//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "isel"
+#include "llvm/ADT/BitVector.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/CodeGen/SelectionDAGISel.h"
#include "llvm/CodeGen/ScheduleDAG.h"
-#include "llvm/CallingConv.h"
#include "llvm/Constants.h"
+#include "llvm/CallingConv.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Function.h"
#include "llvm/GlobalVariable.h"
#include "llvm/Instructions.h"
#include "llvm/Intrinsics.h"
#include "llvm/IntrinsicInst.h"
-#include "llvm/CodeGen/MachineDebugInfo.h"
+#include "llvm/ParameterAttributes.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
#include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/CodeGen/SSARegMap.h"
#include "llvm/Target/MRegisterInfo.h"
-#include "llvm/Target/TargetAsmInfo.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetFrameInfo.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetLowering.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
-#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Compiler.h"
static const bool ViewISelDAGs = 0, ViewSchedDAGs = 0;
#endif
-
//===---------------------------------------------------------------------===//
///
/// RegisterScheduler class - Track the registration of instruction schedulers.
/// ValueMap - Since we emit code for the function a basic block at a time,
/// we must remember which virtual registers hold the values for
/// cross-basic-block values.
- std::map<const Value*, unsigned> ValueMap;
+ DenseMap<const Value*, unsigned> ValueMap;
/// StaticAllocaMap - Keep track of frame indices for fixed sized allocas in
/// the entry block. This allows the allocas to be efficiently referenced
const Type *Ty = AI->getAllocatedType();
uint64_t TySize = TLI.getTargetData()->getTypeSize(Ty);
unsigned Align =
- std::max((unsigned)TLI.getTargetData()->getTypeAlignment(Ty),
+ std::max((unsigned)TLI.getTargetData()->getPrefTypeAlignment(Ty),
AI->getAlignment());
- // If the alignment of the value is smaller than the size of the
- // value, and if the size of the value is particularly small
- // (<= 8 bytes), round up to the size of the value for potentially
- // better performance.
- //
- // FIXME: This could be made better with a preferred alignment hook in
- // TargetData. It serves primarily to 8-byte align doubles for X86.
- if (Align < TySize && TySize <= 8) Align = TySize;
TySize *= CUI->getZExtValue(); // Get total allocated size.
if (TySize == 0) TySize = 1; // Don't create zero-sized stack objects.
StaticAllocaMap[AI] =
else {
MVT::ValueType VT1,VT2;
NumElements =
- TLI.getPackedTypeBreakdown(cast<PackedType>(PN->getType()),
+ TLI.getVectorTypeBreakdown(cast<VectorType>(PN->getType()),
VT1, VT2);
}
unsigned PHIReg = ValueMap[PN];
// a <2 x int64> -> 4 x i32 registers.
unsigned NumVectorRegs = 1;
- // If this is a packed type, figure out what type it will decompose into
+ // If this is a vector type, figure out what type it will decompose into
// and how many of the elements it will use.
if (VT == MVT::Vector) {
- const PackedType *PTy = cast<PackedType>(V->getType());
+ const VectorType *PTy = cast<VectorType>(V->getType());
unsigned NumElts = PTy->getNumElements();
MVT::ValueType EltTy = TLI.getValueType(PTy->getElementType());
// If this value is represented with multiple target registers, make sure
// to create enough consecutive registers of the right (smaller) type.
- unsigned NT = VT-1; // Find the type to use.
- while (TLI.getNumElements((MVT::ValueType)NT) != 1)
- --NT;
-
- unsigned R = MakeReg((MVT::ValueType)NT);
+ VT = TLI.getTypeToExpandTo(VT);
+ unsigned R = MakeReg(VT);
for (unsigned i = 1; i != NV*NumVectorRegs; ++i)
- MakeReg((MVT::ValueType)NT);
+ MakeReg(VT);
return R;
}
class SelectionDAGLowering {
MachineBasicBlock *CurMBB;
- std::map<const Value*, SDOperand> NodeMap;
+ DenseMap<const Value*, SDOperand> NodeMap;
/// PendingLoads - Loads are not emitted to the program immediately. We bunch
/// them up and then emit token factor nodes when possible. This allows us to
/// analysis.
std::vector<SDOperand> PendingLoads;
- /// Case - A pair of values to record the Value for a switch case, and the
- /// case's target basic block.
- typedef std::pair<Constant*, MachineBasicBlock*> Case;
- typedef std::vector<Case>::iterator CaseItr;
- typedef std::pair<CaseItr, CaseItr> CaseRange;
+ /// Case - A struct to record the Value for a switch case, and the
+ /// case's target basic block.
+ struct Case {
+ Constant* Low;
+ Constant* High;
+ MachineBasicBlock* BB;
+
+ Case() : Low(0), High(0), BB(0) { }
+ Case(Constant* low, Constant* high, MachineBasicBlock* bb) :
+ Low(low), High(high), BB(bb) { }
+ uint64_t size() const {
+ uint64_t rHigh = cast<ConstantInt>(High)->getSExtValue();
+ uint64_t rLow = cast<ConstantInt>(Low)->getSExtValue();
+ return (rHigh - rLow + 1ULL);
+ }
+ };
+
+ struct CaseBits {
+ uint64_t Mask;
+ MachineBasicBlock* BB;
+ unsigned Bits;
+
+ CaseBits(uint64_t mask, MachineBasicBlock* bb, unsigned bits):
+ Mask(mask), BB(bb), Bits(bits) { }
+ };
+
+ typedef std::vector<Case> CaseVector;
+ typedef std::vector<CaseBits> CaseBitsVector;
+ typedef CaseVector::iterator CaseItr;
+ typedef std::pair<CaseItr, CaseItr> CaseRange;
/// CaseRec - A struct with ctor used in lowering switches to a binary tree
/// of conditional branches.
/// processed at this point in the binary search tree.
CaseRange Range;
};
-
- /// The comparison function for sorting Case values.
+
+ typedef std::vector<CaseRec> CaseRecVector;
+
+ /// The comparison function for sorting the switch case values in the vector.
+ /// WARNING: Case ranges should be disjoint!
struct CaseCmp {
bool operator () (const Case& C1, const Case& C2) {
- if (const ConstantInt* I1 = dyn_cast<const ConstantInt>(C1.first))
- if (I1->getType()->isUnsigned())
- return I1->getZExtValue() <
- cast<const ConstantInt>(C2.first)->getZExtValue();
-
- return cast<const ConstantInt>(C1.first)->getSExtValue() <
- cast<const ConstantInt>(C2.first)->getSExtValue();
+ assert(isa<ConstantInt>(C1.Low) && isa<ConstantInt>(C2.High));
+ const ConstantInt* CI1 = cast<const ConstantInt>(C1.Low);
+ const ConstantInt* CI2 = cast<const ConstantInt>(C2.High);
+ return CI1->getValue().slt(CI2->getValue());
+ }
+ };
+
+ struct CaseBitsCmp {
+ bool operator () (const CaseBits& C1, const CaseBits& C2) {
+ return C1.Bits > C2.Bits;
}
};
+
+ unsigned Clusterify(CaseVector& Cases, const SwitchInst &SI);
public:
// TLI - This is information that describes the available target features we
/// SwitchCases - Vector of CaseBlock structures used to communicate
/// SwitchInst code generation information.
std::vector<SelectionDAGISel::CaseBlock> SwitchCases;
- SelectionDAGISel::JumpTable JT;
+ /// JTCases - Vector of JumpTable structures used to communicate
+ /// SwitchInst code generation information.
+ std::vector<SelectionDAGISel::JumpTableBlock> JTCases;
+ std::vector<SelectionDAGISel::BitTestBlock> BitTestCases;
/// FuncInfo - Information about the function as a whole.
///
SelectionDAGLowering(SelectionDAG &dag, TargetLowering &tli,
FunctionLoweringInfo &funcinfo)
: TLI(tli), DAG(dag), TD(DAG.getTarget().getTargetData()),
- JT(0,0,0,0), FuncInfo(funcinfo) {
+ FuncInfo(funcinfo) {
}
/// getRoot - Return the current virtual root of the Selection DAG.
SDOperand getValue(const Value *V);
- const SDOperand &setValue(const Value *V, SDOperand NewN) {
+ void setValue(const Value *V, SDOperand NewN) {
SDOperand &N = NodeMap[V];
assert(N.Val == 0 && "Already set a value for this node!");
- return N = NewN;
+ N = NewN;
}
RegsForValue GetRegistersForValue(const std::string &ConstrCode,
unsigned Opc);
bool isExportableFromCurrentBlock(Value *V, const BasicBlock *FromBB);
void ExportFromCurrentBlock(Value *V);
-
+ void LowerCallTo(Instruction &I,
+ const Type *CalledValueTy, unsigned CallingConv,
+ bool IsTailCall, SDOperand Callee, unsigned OpIdx);
+
// Terminator instructions.
void visitRet(ReturnInst &I);
void visitBr(BranchInst &I);
void visitSwitch(SwitchInst &I);
void visitUnreachable(UnreachableInst &I) { /* noop */ }
- // Helper for visitSwitch
+ // Helpers for visitSwitch
+ bool handleSmallSwitchRange(CaseRec& CR,
+ CaseRecVector& WorkList,
+ Value* SV,
+ MachineBasicBlock* Default);
+ bool handleJTSwitchCase(CaseRec& CR,
+ CaseRecVector& WorkList,
+ Value* SV,
+ MachineBasicBlock* Default);
+ bool handleBTSplitSwitchCase(CaseRec& CR,
+ CaseRecVector& WorkList,
+ Value* SV,
+ MachineBasicBlock* Default);
+ bool handleBitTestsSwitchCase(CaseRec& CR,
+ CaseRecVector& WorkList,
+ Value* SV,
+ MachineBasicBlock* Default);
void visitSwitchCase(SelectionDAGISel::CaseBlock &CB);
+ void visitBitTestHeader(SelectionDAGISel::BitTestBlock &B);
+ void visitBitTestCase(MachineBasicBlock* NextMBB,
+ unsigned Reg,
+ SelectionDAGISel::BitTestCase &B);
void visitJumpTable(SelectionDAGISel::JumpTable &JT);
+ void visitJumpTableHeader(SelectionDAGISel::JumpTable &JT,
+ SelectionDAGISel::JumpTableHeader &JTH);
// These all get lowered before this pass.
- void visitInvoke(InvokeInst &I) { assert(0 && "TODO"); }
- void visitUnwind(UnwindInst &I) { assert(0 && "TODO"); }
+ void visitInvoke(InvokeInst &I);
+ void visitInvoke(InvokeInst &I, bool AsTerminator);
+ void visitUnwind(UnwindInst &I);
- void visitIntBinary(User &I, unsigned IntOp, unsigned VecOp);
- void visitFPBinary(User &I, unsigned FPOp, unsigned VecOp);
+ void visitScalarBinary(User &I, unsigned OpCode);
+ void visitVectorBinary(User &I, unsigned OpCode);
+ void visitEitherBinary(User &I, unsigned ScalarOp, unsigned VectorOp);
void visitShift(User &I, unsigned Opcode);
void visitAdd(User &I) {
- if (I.getType()->isFloatingPoint())
- visitFPBinary(I, ISD::FADD, ISD::VADD);
+ if (isa<VectorType>(I.getType()))
+ visitVectorBinary(I, ISD::VADD);
+ else if (I.getType()->isFloatingPoint())
+ visitScalarBinary(I, ISD::FADD);
else
- visitIntBinary(I, ISD::ADD, ISD::VADD);
+ visitScalarBinary(I, ISD::ADD);
}
void visitSub(User &I);
void visitMul(User &I) {
- if (I.getType()->isFloatingPoint())
- visitFPBinary(I, ISD::FMUL, ISD::VMUL);
+ if (isa<VectorType>(I.getType()))
+ visitVectorBinary(I, ISD::VMUL);
+ else if (I.getType()->isFloatingPoint())
+ visitScalarBinary(I, ISD::FMUL);
else
- visitIntBinary(I, ISD::MUL, ISD::VMUL);
+ visitScalarBinary(I, ISD::MUL);
}
- void visitURem(User &I) { visitIntBinary(I, ISD::UREM, 0); }
- void visitSRem(User &I) { visitIntBinary(I, ISD::SREM, 0); }
- void visitFRem(User &I) { visitFPBinary (I, ISD::FREM, 0); }
- void visitUDiv(User &I) { visitIntBinary(I, ISD::UDIV, ISD::VUDIV); }
- void visitSDiv(User &I) { visitIntBinary(I, ISD::SDIV, ISD::VSDIV); }
- void visitFDiv(User &I) { visitFPBinary (I, ISD::FDIV, ISD::VSDIV); }
- void visitAnd(User &I) { visitIntBinary(I, ISD::AND, ISD::VAND); }
- void visitOr (User &I) { visitIntBinary(I, ISD::OR, ISD::VOR); }
- void visitXor(User &I) { visitIntBinary(I, ISD::XOR, ISD::VXOR); }
- void visitShl(User &I) { visitShift(I, ISD::SHL); }
+ void visitURem(User &I) { visitScalarBinary(I, ISD::UREM); }
+ void visitSRem(User &I) { visitScalarBinary(I, ISD::SREM); }
+ void visitFRem(User &I) { visitScalarBinary(I, ISD::FREM); }
+ void visitUDiv(User &I) { visitEitherBinary(I, ISD::UDIV, ISD::VUDIV); }
+ void visitSDiv(User &I) { visitEitherBinary(I, ISD::SDIV, ISD::VSDIV); }
+ void visitFDiv(User &I) { visitEitherBinary(I, ISD::FDIV, ISD::VSDIV); }
+ void visitAnd (User &I) { visitEitherBinary(I, ISD::AND, ISD::VAND ); }
+ void visitOr (User &I) { visitEitherBinary(I, ISD::OR, ISD::VOR ); }
+ void visitXor (User &I) { visitEitherBinary(I, ISD::XOR, ISD::VXOR ); }
+ void visitShl (User &I) { visitShift(I, ISD::SHL); }
void visitLShr(User &I) { visitShift(I, ISD::SRL); }
void visitAShr(User &I) { visitShift(I, ISD::SRA); }
void visitICmp(User &I);
void visitFCmp(User &I);
- void visitSetCC(User &I, ISD::CondCode SignedOpc, ISD::CondCode UnsignedOpc,
- ISD::CondCode FPOpc);
- void visitSetEQ(User &I) { visitSetCC(I, ISD::SETEQ, ISD::SETEQ,
- ISD::SETOEQ); }
- void visitSetNE(User &I) { visitSetCC(I, ISD::SETNE, ISD::SETNE,
- ISD::SETUNE); }
- void visitSetLE(User &I) { visitSetCC(I, ISD::SETLE, ISD::SETULE,
- ISD::SETOLE); }
- void visitSetGE(User &I) { visitSetCC(I, ISD::SETGE, ISD::SETUGE,
- ISD::SETOGE); }
- void visitSetLT(User &I) { visitSetCC(I, ISD::SETLT, ISD::SETULT,
- ISD::SETOLT); }
- void visitSetGT(User &I) { visitSetCC(I, ISD::SETGT, ISD::SETUGT,
- ISD::SETOGT); }
// Visit the conversion instructions
void visitTrunc(User &I);
void visitZExt(User &I);
void visitVAArg(VAArgInst &I);
void visitVAEnd(CallInst &I);
void visitVACopy(CallInst &I);
- void visitFrameReturnAddress(CallInst &I, bool isFrameAddress);
void visitMemIntrinsic(CallInst &I, unsigned Op);
if (Constant *C = const_cast<Constant*>(dyn_cast<Constant>(V))) {
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
visit(CE->getOpcode(), *CE);
- assert(N.Val && "visit didn't populate the ValueMap!");
- return N;
+ SDOperand N1 = NodeMap[V];
+ assert(N1.Val && "visit didn't populate the ValueMap!");
+ return N1;
} else if (GlobalValue *GV = dyn_cast<GlobalValue>(C)) {
return N = DAG.getGlobalAddress(GV, VT);
} else if (isa<ConstantPointerNull>(C)) {
return N = DAG.getConstant(0, TLI.getPointerTy());
} else if (isa<UndefValue>(C)) {
- if (!isa<PackedType>(VTy))
+ if (!isa<VectorType>(VTy))
return N = DAG.getNode(ISD::UNDEF, VT);
// Create a VBUILD_VECTOR of undef nodes.
- const PackedType *PTy = cast<PackedType>(VTy);
+ const VectorType *PTy = cast<VectorType>(VTy);
unsigned NumElements = PTy->getNumElements();
MVT::ValueType PVT = TLI.getValueType(PTy->getElementType());
&Ops[0], Ops.size());
} else if (ConstantFP *CFP = dyn_cast<ConstantFP>(C)) {
return N = DAG.getConstantFP(CFP->getValue(), VT);
- } else if (const PackedType *PTy = dyn_cast<PackedType>(VTy)) {
+ } else if (const VectorType *PTy = dyn_cast<VectorType>(VTy)) {
unsigned NumElements = PTy->getNumElements();
MVT::ValueType PVT = TLI.getValueType(PTy->getElementType());
// Constant or ConstantFP node onto the ops list for each element of
// the packed constant.
SmallVector<SDOperand, 8> Ops;
- if (ConstantPacked *CP = dyn_cast<ConstantPacked>(C)) {
+ if (ConstantVector *CP = dyn_cast<ConstantVector>(C)) {
for (unsigned i = 0; i != NumElements; ++i)
Ops.push_back(getValue(CP->getOperand(i)));
} else {
// Create a VBUILD_VECTOR node with generic Vector type.
Ops.push_back(DAG.getConstant(NumElements, MVT::i32));
Ops.push_back(DAG.getValueType(PVT));
- return N = DAG.getNode(ISD::VBUILD_VECTOR,MVT::Vector,&Ops[0],Ops.size());
+ return NodeMap[V] = DAG.getNode(ISD::VBUILD_VECTOR, MVT::Vector, &Ops[0],
+ Ops.size());
} else {
// Canonicalize all constant ints to be unsigned.
- return N = DAG.getConstant(cast<ConstantIntegral>(C)->getZExtValue(),VT);
+ return N = DAG.getConstant(cast<ConstantInt>(C)->getZExtValue(),VT);
}
}
return DAG.getFrameIndex(SI->second, TLI.getPointerTy());
}
- std::map<const Value*, unsigned>::const_iterator VMI =
- FuncInfo.ValueMap.find(V);
- assert(VMI != FuncInfo.ValueMap.end() && "Value not in map!");
-
- unsigned InReg = VMI->second;
+ unsigned InReg = FuncInfo.ValueMap[V];
+ assert(InReg && "Value not in map!");
// If this type is not legal, make it so now.
if (VT != MVT::Vector) {
- MVT::ValueType DestVT = TLI.getTypeToTransformTo(VT);
-
- N = DAG.getCopyFromReg(DAG.getEntryNode(), InReg, DestVT);
- if (DestVT < VT) {
+ if (TLI.getTypeAction(VT) == TargetLowering::Expand) {
// Source must be expanded. This input value is actually coming from the
- // register pair VMI->second and VMI->second+1.
- N = DAG.getNode(ISD::BUILD_PAIR, VT, N,
- DAG.getCopyFromReg(DAG.getEntryNode(), InReg+1, DestVT));
- } else if (DestVT > VT) { // Promotion case
- if (MVT::isFloatingPoint(VT))
- N = DAG.getNode(ISD::FP_ROUND, VT, N);
- else
- N = DAG.getNode(ISD::TRUNCATE, VT, N);
+ // register pair InReg and InReg+1.
+ MVT::ValueType DestVT = TLI.getTypeToExpandTo(VT);
+ unsigned NumVals = TLI.getNumElements(VT);
+ N = DAG.getCopyFromReg(DAG.getEntryNode(), InReg, DestVT);
+ if (NumVals == 1)
+ N = DAG.getNode(ISD::BIT_CONVERT, VT, N);
+ else {
+ assert(NumVals == 2 && "1 to 4 (and more) expansion not implemented!");
+ N = DAG.getNode(ISD::BUILD_PAIR, VT, N,
+ DAG.getCopyFromReg(DAG.getEntryNode(), InReg+1, DestVT));
+ }
+ } else {
+ MVT::ValueType DestVT = TLI.getTypeToTransformTo(VT);
+ N = DAG.getCopyFromReg(DAG.getEntryNode(), InReg, DestVT);
+ if (TLI.getTypeAction(VT) == TargetLowering::Promote) // Promotion case
+ N = MVT::isFloatingPoint(VT)
+ ? DAG.getNode(ISD::FP_ROUND, VT, N)
+ : DAG.getNode(ISD::TRUNCATE, VT, N);
}
} else {
// Otherwise, if this is a vector, make it available as a generic vector
// here.
MVT::ValueType PTyElementVT, PTyLegalElementVT;
- const PackedType *PTy = cast<PackedType>(VTy);
- unsigned NE = TLI.getPackedTypeBreakdown(PTy, PTyElementVT,
+ const VectorType *PTy = cast<VectorType>(VTy);
+ unsigned NE = TLI.getVectorTypeBreakdown(PTy, PTyElementVT,
PTyLegalElementVT);
// Build a VBUILD_VECTOR with the input registers.
NewValues.push_back(getRoot());
for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) {
SDOperand RetOp = getValue(I.getOperand(i));
- bool isSigned = I.getOperand(i)->getType()->isSigned();
// If this is an integer return value, we need to promote it ourselves to
// the full width of a register, since LegalizeOp will use ANY_EXTEND rather
TmpVT = TLI.getTypeToTransformTo(MVT::i32);
else
TmpVT = MVT::i32;
-
- if (isSigned)
- RetOp = DAG.getNode(ISD::SIGN_EXTEND, TmpVT, RetOp);
- else
- RetOp = DAG.getNode(ISD::ZERO_EXTEND, TmpVT, RetOp);
+ const FunctionType *FTy = I.getParent()->getParent()->getFunctionType();
+ const ParamAttrsList *Attrs = FTy->getParamAttrs();
+ ISD::NodeType ExtendKind = ISD::ANY_EXTEND;
+ if (Attrs && Attrs->paramHasAttr(0, SExtAttribute))
+ ExtendKind = ISD::SIGN_EXTEND;
+ if (Attrs && Attrs->paramHasAttr(0, ZExtAttribute))
+ ExtendKind = ISD::ZERO_EXTEND;
+ RetOp = DAG.getNode(ExtendKind, TmpVT, RetOp);
}
NewValues.push_back(RetOp);
- NewValues.push_back(DAG.getConstant(isSigned, MVT::i32));
+ NewValues.push_back(DAG.getConstant(false, MVT::i32));
}
DAG.setRoot(DAG.getNode(ISD::RET, MVT::Other,
&NewValues[0], NewValues.size()));
MachineBasicBlock *CurBB,
unsigned Opc) {
// If this node is not part of the or/and tree, emit it as a branch.
- BinaryOperator *BOp = dyn_cast<BinaryOperator>(Cond);
+ Instruction *BOp = dyn_cast<Instruction>(Cond);
- if (!BOp || (unsigned)BOp->getOpcode() != Opc || !BOp->hasOneUse() ||
+ if (!BOp || !(isa<BinaryOperator>(BOp) || isa<CmpInst>(BOp)) ||
+ (unsigned)BOp->getOpcode() != Opc || !BOp->hasOneUse() ||
BOp->getParent() != CurBB->getBasicBlock() ||
!InBlock(BOp->getOperand(0), CurBB->getBasicBlock()) ||
!InBlock(BOp->getOperand(1), CurBB->getBasicBlock())) {
const BasicBlock *BB = CurBB->getBasicBlock();
- if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(Cond))
- if ((II->getIntrinsicID() == Intrinsic::isunordered_f32 ||
- II->getIntrinsicID() == Intrinsic::isunordered_f64) &&
- // The operands of the setcc have to be in this block. We don't know
- // how to export them from some other block. If this is the first
- // block of the sequence, no exporting is needed.
- (CurBB == CurMBB ||
- (isExportableFromCurrentBlock(II->getOperand(1), BB) &&
- isExportableFromCurrentBlock(II->getOperand(2), BB)))) {
- SelectionDAGISel::CaseBlock CB(ISD::SETUO, II->getOperand(1),
- II->getOperand(2), TBB, FBB, CurBB);
- SwitchCases.push_back(CB);
- return;
- }
-
-
- // If the leaf of the tree is a setcond inst, merge the condition into the
- // caseblock.
- if (BOp && isa<SetCondInst>(BOp) &&
- // The operands of the setcc have to be in this block. We don't know
+ // If the leaf of the tree is a comparison, merge the condition into
+ // the caseblock.
+ if ((isa<ICmpInst>(Cond) || isa<FCmpInst>(Cond)) &&
+ // The operands of the cmp have to be in this block. We don't know
// how to export them from some other block. If this is the first block
// of the sequence, no exporting is needed.
(CurBB == CurMBB ||
(isExportableFromCurrentBlock(BOp->getOperand(0), BB) &&
isExportableFromCurrentBlock(BOp->getOperand(1), BB)))) {
- ISD::CondCode SignCond, UnsCond, FPCond, Condition;
- switch (BOp->getOpcode()) {
- default: assert(0 && "Unknown setcc opcode!");
- case Instruction::SetEQ:
- SignCond = ISD::SETEQ;
- UnsCond = ISD::SETEQ;
- FPCond = ISD::SETOEQ;
- break;
- case Instruction::SetNE:
- SignCond = ISD::SETNE;
- UnsCond = ISD::SETNE;
- FPCond = ISD::SETUNE;
- break;
- case Instruction::SetLE:
- SignCond = ISD::SETLE;
- UnsCond = ISD::SETULE;
- FPCond = ISD::SETOLE;
- break;
- case Instruction::SetGE:
- SignCond = ISD::SETGE;
- UnsCond = ISD::SETUGE;
- FPCond = ISD::SETOGE;
- break;
- case Instruction::SetLT:
- SignCond = ISD::SETLT;
- UnsCond = ISD::SETULT;
- FPCond = ISD::SETOLT;
- break;
- case Instruction::SetGT:
- SignCond = ISD::SETGT;
- UnsCond = ISD::SETUGT;
- FPCond = ISD::SETOGT;
- break;
+ BOp = cast<Instruction>(Cond);
+ ISD::CondCode Condition;
+ if (ICmpInst *IC = dyn_cast<ICmpInst>(Cond)) {
+ switch (IC->getPredicate()) {
+ default: assert(0 && "Unknown icmp predicate opcode!");
+ case ICmpInst::ICMP_EQ: Condition = ISD::SETEQ; break;
+ case ICmpInst::ICMP_NE: Condition = ISD::SETNE; break;
+ case ICmpInst::ICMP_SLE: Condition = ISD::SETLE; break;
+ case ICmpInst::ICMP_ULE: Condition = ISD::SETULE; break;
+ case ICmpInst::ICMP_SGE: Condition = ISD::SETGE; break;
+ case ICmpInst::ICMP_UGE: Condition = ISD::SETUGE; break;
+ case ICmpInst::ICMP_SLT: Condition = ISD::SETLT; break;
+ case ICmpInst::ICMP_ULT: Condition = ISD::SETULT; break;
+ case ICmpInst::ICMP_SGT: Condition = ISD::SETGT; break;
+ case ICmpInst::ICMP_UGT: Condition = ISD::SETUGT; break;
+ }
+ } else if (FCmpInst *FC = dyn_cast<FCmpInst>(Cond)) {
+ ISD::CondCode FPC, FOC;
+ switch (FC->getPredicate()) {
+ default: assert(0 && "Unknown fcmp predicate opcode!");
+ case FCmpInst::FCMP_FALSE: FOC = FPC = ISD::SETFALSE; break;
+ case FCmpInst::FCMP_OEQ: FOC = ISD::SETEQ; FPC = ISD::SETOEQ; break;
+ case FCmpInst::FCMP_OGT: FOC = ISD::SETGT; FPC = ISD::SETOGT; break;
+ case FCmpInst::FCMP_OGE: FOC = ISD::SETGE; FPC = ISD::SETOGE; break;
+ case FCmpInst::FCMP_OLT: FOC = ISD::SETLT; FPC = ISD::SETOLT; break;
+ case FCmpInst::FCMP_OLE: FOC = ISD::SETLE; FPC = ISD::SETOLE; break;
+ case FCmpInst::FCMP_ONE: FOC = ISD::SETNE; FPC = ISD::SETONE; break;
+ case FCmpInst::FCMP_ORD: FOC = ISD::SETEQ; FPC = ISD::SETO; break;
+ case FCmpInst::FCMP_UNO: FOC = ISD::SETNE; FPC = ISD::SETUO; break;
+ case FCmpInst::FCMP_UEQ: FOC = ISD::SETEQ; FPC = ISD::SETUEQ; break;
+ case FCmpInst::FCMP_UGT: FOC = ISD::SETGT; FPC = ISD::SETUGT; break;
+ case FCmpInst::FCMP_UGE: FOC = ISD::SETGE; FPC = ISD::SETUGE; break;
+ case FCmpInst::FCMP_ULT: FOC = ISD::SETLT; FPC = ISD::SETULT; break;
+ case FCmpInst::FCMP_ULE: FOC = ISD::SETLE; FPC = ISD::SETULE; break;
+ case FCmpInst::FCMP_UNE: FOC = ISD::SETNE; FPC = ISD::SETUNE; break;
+ case FCmpInst::FCMP_TRUE: FOC = FPC = ISD::SETTRUE; break;
+ }
+ if (FiniteOnlyFPMath())
+ Condition = FOC;
+ else
+ Condition = FPC;
+ } else {
+ Condition = ISD::SETEQ; // silence warning.
+ assert(0 && "Unknown compare instruction");
}
- const Type *OpType = BOp->getOperand(0)->getType();
- if (const PackedType *PTy = dyn_cast<PackedType>(OpType))
- OpType = PTy->getElementType();
-
- if (!FiniteOnlyFPMath() && OpType->isFloatingPoint())
- Condition = FPCond;
- else if (OpType->isUnsigned())
- Condition = UnsCond;
- else
- Condition = SignCond;
-
SelectionDAGISel::CaseBlock CB(Condition, BOp->getOperand(0),
- BOp->getOperand(1), TBB, FBB, CurBB);
+ BOp->getOperand(1), NULL, TBB, FBB, CurBB);
SwitchCases.push_back(CB);
return;
}
// Create a CaseBlock record representing this branch.
- SelectionDAGISel::CaseBlock CB(ISD::SETEQ, Cond, ConstantBool::getTrue(),
- TBB, FBB, CurBB);
+ SelectionDAGISel::CaseBlock CB(ISD::SETEQ, Cond, ConstantInt::getTrue(),
+ NULL, TBB, FBB, CurBB);
SwitchCases.push_back(CB);
return;
}
}
// Create a CaseBlock record representing this branch.
- SelectionDAGISel::CaseBlock CB(ISD::SETEQ, CondVal, ConstantBool::getTrue(),
- Succ0MBB, Succ1MBB, CurMBB);
+ SelectionDAGISel::CaseBlock CB(ISD::SETEQ, CondVal, ConstantInt::getTrue(),
+ NULL, Succ0MBB, Succ1MBB, CurMBB);
// Use visitSwitchCase to actually insert the fast branch sequence for this
// cond branch.
visitSwitchCase(CB);
SDOperand Cond;
SDOperand CondLHS = getValue(CB.CmpLHS);
- // Build the setcc now, fold "(X == true)" to X and "(X == false)" to !X to
- // handle common cases produced by branch lowering.
- if (CB.CmpRHS == ConstantBool::getTrue() && CB.CC == ISD::SETEQ)
- Cond = CondLHS;
- else if (CB.CmpRHS == ConstantBool::getFalse() && CB.CC == ISD::SETEQ) {
- SDOperand True = DAG.getConstant(1, CondLHS.getValueType());
- Cond = DAG.getNode(ISD::XOR, CondLHS.getValueType(), CondLHS, True);
- } else
- Cond = DAG.getSetCC(MVT::i1, CondLHS, getValue(CB.CmpRHS), CB.CC);
+ // Build the setcc now.
+ if (CB.CmpMHS == NULL) {
+ // Fold "(X == true)" to X and "(X == false)" to !X to
+ // handle common cases produced by branch lowering.
+ if (CB.CmpRHS == ConstantInt::getTrue() && CB.CC == ISD::SETEQ)
+ Cond = CondLHS;
+ else if (CB.CmpRHS == ConstantInt::getFalse() && CB.CC == ISD::SETEQ) {
+ SDOperand True = DAG.getConstant(1, CondLHS.getValueType());
+ Cond = DAG.getNode(ISD::XOR, CondLHS.getValueType(), CondLHS, True);
+ } else
+ Cond = DAG.getSetCC(MVT::i1, CondLHS, getValue(CB.CmpRHS), CB.CC);
+ } else {
+ assert(CB.CC == ISD::SETLE && "Can handle only LE ranges now");
+
+ uint64_t Low = cast<ConstantInt>(CB.CmpLHS)->getSExtValue();
+ uint64_t High = cast<ConstantInt>(CB.CmpRHS)->getSExtValue();
+
+ SDOperand CmpOp = getValue(CB.CmpMHS);
+ MVT::ValueType VT = CmpOp.getValueType();
+
+ if (cast<ConstantInt>(CB.CmpLHS)->isMinValue(true)) {
+ Cond = DAG.getSetCC(MVT::i1, CmpOp, DAG.getConstant(High, VT), ISD::SETLE);
+ } else {
+ SDOperand SUB = DAG.getNode(ISD::SUB, VT, CmpOp, DAG.getConstant(Low, VT));
+ Cond = DAG.getSetCC(MVT::i1, SUB,
+ DAG.getConstant(High-Low, VT), ISD::SETULE);
+ }
+
+ }
// Set NextBlock to be the MBB immediately after the current one, if any.
// This is used to avoid emitting unnecessary branches to the next block.
CurMBB->addSuccessor(CB.FalseBB);
}
+/// visitJumpTable - Emit JumpTable node in the current MBB
void SelectionDAGLowering::visitJumpTable(SelectionDAGISel::JumpTable &JT) {
// Emit the code for the jump table
+ assert(JT.Reg != -1UL && "Should lower JT Header first!");
MVT::ValueType PTy = TLI.getPointerTy();
SDOperand Index = DAG.getCopyFromReg(getRoot(), JT.Reg, PTy);
SDOperand Table = DAG.getJumpTable(JT.JTI, PTy);
return;
}
-void SelectionDAGLowering::visitSwitch(SwitchInst &I) {
- // Figure out which block is immediately after the current one.
+/// visitJumpTableHeader - This function emits necessary code to produce index
+/// in the JumpTable from switch case.
+void SelectionDAGLowering::visitJumpTableHeader(SelectionDAGISel::JumpTable &JT,
+ SelectionDAGISel::JumpTableHeader &JTH) {
+ // Subtract the lowest switch case value from the value being switched on
+ // and conditional branch to default mbb if the result is greater than the
+ // difference between smallest and largest cases.
+ SDOperand SwitchOp = getValue(JTH.SValue);
+ MVT::ValueType VT = SwitchOp.getValueType();
+ SDOperand SUB = DAG.getNode(ISD::SUB, VT, SwitchOp,
+ DAG.getConstant(JTH.First, VT));
+
+ // The SDNode we just created, which holds the value being switched on
+ // minus the the smallest case value, needs to be copied to a virtual
+ // register so it can be used as an index into the jump table in a
+ // subsequent basic block. This value may be smaller or larger than the
+ // target's pointer type, and therefore require extension or truncating.
+ if (VT > TLI.getPointerTy())
+ SwitchOp = DAG.getNode(ISD::TRUNCATE, TLI.getPointerTy(), SUB);
+ else
+ SwitchOp = DAG.getNode(ISD::ZERO_EXTEND, TLI.getPointerTy(), SUB);
+
+ unsigned JumpTableReg = FuncInfo.MakeReg(TLI.getPointerTy());
+ SDOperand CopyTo = DAG.getCopyToReg(getRoot(), JumpTableReg, SwitchOp);
+ JT.Reg = JumpTableReg;
+
+ // Emit the range check for the jump table, and branch to the default
+ // block for the switch statement if the value being switched on exceeds
+ // the largest case in the switch.
+ SDOperand CMP = DAG.getSetCC(TLI.getSetCCResultTy(), SUB,
+ DAG.getConstant(JTH.Last-JTH.First,VT),
+ ISD::SETUGT);
+
+ // Set NextBlock to be the MBB immediately after the current one, if any.
+ // This is used to avoid emitting unnecessary branches to the next block.
MachineBasicBlock *NextBlock = 0;
MachineFunction::iterator BBI = CurMBB;
+ if (++BBI != CurMBB->getParent()->end())
+ NextBlock = BBI;
+
+ SDOperand BrCond = DAG.getNode(ISD::BRCOND, MVT::Other, CopyTo, CMP,
+ DAG.getBasicBlock(JT.Default));
+
+ if (JT.MBB == NextBlock)
+ DAG.setRoot(BrCond);
+ else
+ DAG.setRoot(DAG.getNode(ISD::BR, MVT::Other, BrCond,
+ DAG.getBasicBlock(JT.MBB)));
+
+ return;
+}
+
+/// visitBitTestHeader - This function emits necessary code to produce value
+/// suitable for "bit tests"
+void SelectionDAGLowering::visitBitTestHeader(SelectionDAGISel::BitTestBlock &B) {
+ // Subtract the minimum value
+ SDOperand SwitchOp = getValue(B.SValue);
+ MVT::ValueType VT = SwitchOp.getValueType();
+ SDOperand SUB = DAG.getNode(ISD::SUB, VT, SwitchOp,
+ DAG.getConstant(B.First, VT));
+
+ // Check range
+ SDOperand RangeCmp = DAG.getSetCC(TLI.getSetCCResultTy(), SUB,
+ DAG.getConstant(B.Range, VT),
+ ISD::SETUGT);
+
+ SDOperand ShiftOp;
+ if (VT > TLI.getShiftAmountTy())
+ ShiftOp = DAG.getNode(ISD::TRUNCATE, TLI.getShiftAmountTy(), SUB);
+ else
+ ShiftOp = DAG.getNode(ISD::ZERO_EXTEND, TLI.getShiftAmountTy(), SUB);
+
+ // Make desired shift
+ SDOperand SwitchVal = DAG.getNode(ISD::SHL, TLI.getPointerTy(),
+ DAG.getConstant(1, TLI.getPointerTy()),
+ ShiftOp);
+
+ unsigned SwitchReg = FuncInfo.MakeReg(TLI.getPointerTy());
+ SDOperand CopyTo = DAG.getCopyToReg(getRoot(), SwitchReg, SwitchVal);
+ B.Reg = SwitchReg;
+
+ SDOperand BrRange = DAG.getNode(ISD::BRCOND, MVT::Other, CopyTo, RangeCmp,
+ DAG.getBasicBlock(B.Default));
+ // Set NextBlock to be the MBB immediately after the current one, if any.
+ // This is used to avoid emitting unnecessary branches to the next block.
+ MachineBasicBlock *NextBlock = 0;
+ MachineFunction::iterator BBI = CurMBB;
if (++BBI != CurMBB->getParent()->end())
NextBlock = BBI;
-
- MachineBasicBlock *Default = FuncInfo.MBBMap[I.getDefaultDest()];
- // If there is only the default destination, branch to it if it is not the
- // next basic block. Otherwise, just fall through.
- if (I.getNumOperands() == 2) {
- // Update machine-CFG edges.
+ MachineBasicBlock* MBB = B.Cases[0].ThisBB;
+ if (MBB == NextBlock)
+ DAG.setRoot(BrRange);
+ else
+ DAG.setRoot(DAG.getNode(ISD::BR, MVT::Other, CopyTo,
+ DAG.getBasicBlock(MBB)));
- // If this is not a fall-through branch, emit the branch.
- if (Default != NextBlock)
- DAG.setRoot(DAG.getNode(ISD::BR, MVT::Other, getRoot(),
- DAG.getBasicBlock(Default)));
+ CurMBB->addSuccessor(B.Default);
+ CurMBB->addSuccessor(MBB);
- CurMBB->addSuccessor(Default);
- return;
- }
+ return;
+}
+
+/// visitBitTestCase - this function produces one "bit test"
+void SelectionDAGLowering::visitBitTestCase(MachineBasicBlock* NextMBB,
+ unsigned Reg,
+ SelectionDAGISel::BitTestCase &B) {
+ // Emit bit tests and jumps
+ SDOperand SwitchVal = DAG.getCopyFromReg(getRoot(), Reg, TLI.getPointerTy());
- // If there are any non-default case statements, create a vector of Cases
- // representing each one, and sort the vector so that we can efficiently
- // create a binary search tree from them.
- std::vector<Case> Cases;
+ SDOperand AndOp = DAG.getNode(ISD::AND, TLI.getPointerTy(),
+ SwitchVal,
+ DAG.getConstant(B.Mask,
+ TLI.getPointerTy()));
+ SDOperand AndCmp = DAG.getSetCC(TLI.getSetCCResultTy(), AndOp,
+ DAG.getConstant(0, TLI.getPointerTy()),
+ ISD::SETNE);
+ SDOperand BrAnd = DAG.getNode(ISD::BRCOND, MVT::Other, getRoot(),
+ AndCmp, DAG.getBasicBlock(B.TargetBB));
- for (unsigned i = 1; i < I.getNumSuccessors(); ++i) {
- MachineBasicBlock *SMBB = FuncInfo.MBBMap[I.getSuccessor(i)];
- Cases.push_back(Case(I.getSuccessorValue(i), SMBB));
- }
+ // Set NextBlock to be the MBB immediately after the current one, if any.
+ // This is used to avoid emitting unnecessary branches to the next block.
+ MachineBasicBlock *NextBlock = 0;
+ MachineFunction::iterator BBI = CurMBB;
+ if (++BBI != CurMBB->getParent()->end())
+ NextBlock = BBI;
+
+ if (NextMBB == NextBlock)
+ DAG.setRoot(BrAnd);
+ else
+ DAG.setRoot(DAG.getNode(ISD::BR, MVT::Other, BrAnd,
+ DAG.getBasicBlock(NextMBB)));
+
+ CurMBB->addSuccessor(B.TargetBB);
+ CurMBB->addSuccessor(NextMBB);
- std::sort(Cases.begin(), Cases.end(), CaseCmp());
+ return;
+}
+
+void SelectionDAGLowering::visitInvoke(InvokeInst &I) {
+ assert(0 && "Should never be visited directly");
+}
+void SelectionDAGLowering::visitInvoke(InvokeInst &I, bool AsTerminator) {
+ // Retrieve successors.
+ MachineBasicBlock *Return = FuncInfo.MBBMap[I.getSuccessor(0)];
+ MachineBasicBlock *LandingPad = FuncInfo.MBBMap[I.getSuccessor(1)];
- // Get the Value to be switched on and default basic blocks, which will be
- // inserted into CaseBlock records, representing basic blocks in the binary
- // search tree.
- Value *SV = I.getOperand(0);
+ if (!AsTerminator) {
+ // Mark landing pad so that it doesn't get deleted in branch folding.
+ LandingPad->setIsLandingPad();
+
+ // Insert a label before the invoke call to mark the try range.
+ // This can be used to detect deletion of the invoke via the
+ // MachineModuleInfo.
+ MachineModuleInfo *MMI = DAG.getMachineModuleInfo();
+ unsigned BeginLabel = MMI->NextLabelID();
+ DAG.setRoot(DAG.getNode(ISD::LABEL, MVT::Other, getRoot(),
+ DAG.getConstant(BeginLabel, MVT::i32)));
+
+ LowerCallTo(I, I.getCalledValue()->getType(),
+ I.getCallingConv(),
+ false,
+ getValue(I.getOperand(0)),
+ 3);
+
+ // Insert a label before the invoke call to mark the try range.
+ // This can be used to detect deletion of the invoke via the
+ // MachineModuleInfo.
+ unsigned EndLabel = MMI->NextLabelID();
+ DAG.setRoot(DAG.getNode(ISD::LABEL, MVT::Other, getRoot(),
+ DAG.getConstant(EndLabel, MVT::i32)));
+
+ // Inform MachineModuleInfo of range.
+ MMI->addInvoke(LandingPad, BeginLabel, EndLabel);
+
+ // Update successor info
+ CurMBB->addSuccessor(Return);
+ CurMBB->addSuccessor(LandingPad);
+ } else {
+ // Drop into normal successor.
+ DAG.setRoot(DAG.getNode(ISD::BR, MVT::Other, getRoot(),
+ DAG.getBasicBlock(Return)));
+ }
+}
- // Get the MachineFunction which holds the current MBB. This is used during
- // emission of jump tables, and when inserting any additional MBBs necessary
- // to represent the switch.
- MachineFunction *CurMF = CurMBB->getParent();
- const BasicBlock *LLVMBB = CurMBB->getBasicBlock();
+void SelectionDAGLowering::visitUnwind(UnwindInst &I) {
+}
+
+/// handleSmallSwitchCaseRange - Emit a series of specific tests (suitable for
+/// small case ranges).
+bool SelectionDAGLowering::handleSmallSwitchRange(CaseRec& CR,
+ CaseRecVector& WorkList,
+ Value* SV,
+ MachineBasicBlock* Default) {
+ Case& BackCase = *(CR.Range.second-1);
- // If the switch has few cases (two or less) emit a series of specific
- // tests.
- if (Cases.size() < 3) {
- // TODO: If any two of the cases has the same destination, and if one value
- // is the same as the other, but has one bit unset that the other has set,
- // use bit manipulation to do two compares at once. For example:
- // "if (X == 6 || X == 4)" -> "if ((X|2) == 6)"
+ // Size is the number of Cases represented by this range.
+ unsigned Size = CR.Range.second - CR.Range.first;
+ if (Size > 3)
+ return false;
+
+ // Get the MachineFunction which holds the current MBB. This is used when
+ // inserting any additional MBBs necessary to represent the switch.
+ MachineFunction *CurMF = CurMBB->getParent();
+
+ // Figure out which block is immediately after the current one.
+ MachineBasicBlock *NextBlock = 0;
+ MachineFunction::iterator BBI = CR.CaseBB;
+
+ if (++BBI != CurMBB->getParent()->end())
+ NextBlock = BBI;
+
+ // TODO: If any two of the cases has the same destination, and if one value
+ // is the same as the other, but has one bit unset that the other has set,
+ // use bit manipulation to do two compares at once. For example:
+ // "if (X == 6 || X == 4)" -> "if ((X|2) == 6)"
- // Rearrange the case blocks so that the last one falls through if possible.
- if (NextBlock && Default != NextBlock && Cases.back().second != NextBlock) {
- // The last case block won't fall through into 'NextBlock' if we emit the
- // branches in this order. See if rearranging a case value would help.
- for (unsigned i = 0, e = Cases.size()-1; i != e; ++i) {
- if (Cases[i].second == NextBlock) {
- std::swap(Cases[i], Cases.back());
- break;
- }
+ // Rearrange the case blocks so that the last one falls through if possible.
+ if (NextBlock && Default != NextBlock && BackCase.BB != NextBlock) {
+ // The last case block won't fall through into 'NextBlock' if we emit the
+ // branches in this order. See if rearranging a case value would help.
+ for (CaseItr I = CR.Range.first, E = CR.Range.second-1; I != E; ++I) {
+ if (I->BB == NextBlock) {
+ std::swap(*I, BackCase);
+ break;
}
}
+ }
+
+ // Create a CaseBlock record representing a conditional branch to
+ // the Case's target mbb if the value being switched on SV is equal
+ // to C.
+ MachineBasicBlock *CurBlock = CR.CaseBB;
+ for (CaseItr I = CR.Range.first, E = CR.Range.second; I != E; ++I) {
+ MachineBasicBlock *FallThrough;
+ if (I != E-1) {
+ FallThrough = new MachineBasicBlock(CurBlock->getBasicBlock());
+ CurMF->getBasicBlockList().insert(BBI, FallThrough);
+ } else {
+ // If the last case doesn't match, go to the default block.
+ FallThrough = Default;
+ }
+
+ Value *RHS, *LHS, *MHS;
+ ISD::CondCode CC;
+ if (I->High == I->Low) {
+ // This is just small small case range :) containing exactly 1 case
+ CC = ISD::SETEQ;
+ LHS = SV; RHS = I->High; MHS = NULL;
+ } else {
+ CC = ISD::SETLE;
+ LHS = I->Low; MHS = SV; RHS = I->High;
+ }
+ SelectionDAGISel::CaseBlock CB(CC, LHS, RHS, MHS,
+ I->BB, FallThrough, CurBlock);
- // Create a CaseBlock record representing a conditional branch to
- // the Case's target mbb if the value being switched on SV is equal
- // to C.
- MachineBasicBlock *CurBlock = CurMBB;
- for (unsigned i = 0, e = Cases.size(); i != e; ++i) {
- MachineBasicBlock *FallThrough;
- if (i != e-1) {
- FallThrough = new MachineBasicBlock(CurMBB->getBasicBlock());
- CurMF->getBasicBlockList().insert(BBI, FallThrough);
- } else {
- // If the last case doesn't match, go to the default block.
- FallThrough = Default;
- }
-
- SelectionDAGISel::CaseBlock CB(ISD::SETEQ, SV, Cases[i].first,
- Cases[i].second, FallThrough, CurBlock);
+ // If emitting the first comparison, just call visitSwitchCase to emit the
+ // code into the current block. Otherwise, push the CaseBlock onto the
+ // vector to be later processed by SDISel, and insert the node's MBB
+ // before the next MBB.
+ if (CurBlock == CurMBB)
+ visitSwitchCase(CB);
+ else
+ SwitchCases.push_back(CB);
- // If emitting the first comparison, just call visitSwitchCase to emit the
- // code into the current block. Otherwise, push the CaseBlock onto the
- // vector to be later processed by SDISel, and insert the node's MBB
- // before the next MBB.
- if (CurBlock == CurMBB)
- visitSwitchCase(CB);
- else
- SwitchCases.push_back(CB);
-
- CurBlock = FallThrough;
- }
- return;
+ CurBlock = FallThrough;
}
- // If the switch has more than 5 blocks, and at least 31.25% dense, and the
- // target supports indirect branches, then emit a jump table rather than
- // lowering the switch to a binary tree of conditional branches.
- if ((TLI.isOperationLegal(ISD::BR_JT, MVT::Other) ||
- TLI.isOperationLegal(ISD::BRIND, MVT::Other)) &&
- Cases.size() > 5) {
- uint64_t First =cast<ConstantIntegral>(Cases.front().first)->getZExtValue();
- uint64_t Last = cast<ConstantIntegral>(Cases.back().first)->getZExtValue();
- double Density = (double)Cases.size() / (double)((Last - First) + 1ULL);
+ return true;
+}
+
+/// handleJTSwitchCase - Emit jumptable for current switch case range
+bool SelectionDAGLowering::handleJTSwitchCase(CaseRec& CR,
+ CaseRecVector& WorkList,
+ Value* SV,
+ MachineBasicBlock* Default) {
+ Case& FrontCase = *CR.Range.first;
+ Case& BackCase = *(CR.Range.second-1);
+
+ int64_t First = cast<ConstantInt>(FrontCase.Low)->getSExtValue();
+ int64_t Last = cast<ConstantInt>(BackCase.High)->getSExtValue();
+
+ uint64_t TSize = 0;
+ for (CaseItr I = CR.Range.first, E = CR.Range.second;
+ I!=E; ++I)
+ TSize += I->size();
+
+ if ((!TLI.isOperationLegal(ISD::BR_JT, MVT::Other) &&
+ !TLI.isOperationLegal(ISD::BRIND, MVT::Other)) ||
+ TSize <= 3)
+ return false;
+
+ double Density = (double)TSize / (double)((Last - First) + 1ULL);
+ if (Density < 0.4)
+ return false;
+
+ DOUT << "Lowering jump table\n"
+ << "First entry: " << First << ". Last entry: " << Last << "\n"
+ << "Size: " << TSize << ". Density: " << Density << "\n\n";
+
+ // Get the MachineFunction which holds the current MBB. This is used when
+ // inserting any additional MBBs necessary to represent the switch.
+ MachineFunction *CurMF = CurMBB->getParent();
+
+ // Figure out which block is immediately after the current one.
+ MachineBasicBlock *NextBlock = 0;
+ MachineFunction::iterator BBI = CR.CaseBB;
+
+ if (++BBI != CurMBB->getParent()->end())
+ NextBlock = BBI;
+
+ const BasicBlock *LLVMBB = CR.CaseBB->getBasicBlock();
+
+ // Create a new basic block to hold the code for loading the address
+ // of the jump table, and jumping to it. Update successor information;
+ // we will either branch to the default case for the switch, or the jump
+ // table.
+ MachineBasicBlock *JumpTableBB = new MachineBasicBlock(LLVMBB);
+ CurMF->getBasicBlockList().insert(BBI, JumpTableBB);
+ CR.CaseBB->addSuccessor(Default);
+ CR.CaseBB->addSuccessor(JumpTableBB);
+
+ // Build a vector of destination BBs, corresponding to each target
+ // of the jump table. If the value of the jump table slot corresponds to
+ // a case statement, push the case's BB onto the vector, otherwise, push
+ // the default BB.
+ std::vector<MachineBasicBlock*> DestBBs;
+ int64_t TEI = First;
+ for (CaseItr I = CR.Range.first, E = CR.Range.second; I != E; ++TEI) {
+ int64_t Low = cast<ConstantInt>(I->Low)->getSExtValue();
+ int64_t High = cast<ConstantInt>(I->High)->getSExtValue();
- if (Density >= 0.3125) {
- // Create a new basic block to hold the code for loading the address
- // of the jump table, and jumping to it. Update successor information;
- // we will either branch to the default case for the switch, or the jump
- // table.
- MachineBasicBlock *JumpTableBB = new MachineBasicBlock(LLVMBB);
- CurMF->getBasicBlockList().insert(BBI, JumpTableBB);
- CurMBB->addSuccessor(Default);
- CurMBB->addSuccessor(JumpTableBB);
+ if ((Low <= TEI) && (TEI <= High)) {
+ DestBBs.push_back(I->BB);
+ if (TEI==High)
+ ++I;
+ } else {
+ DestBBs.push_back(Default);
+ }
+ }
+
+ // Update successor info. Add one edge to each unique successor.
+ BitVector SuccsHandled(CR.CaseBB->getParent()->getNumBlockIDs());
+ for (std::vector<MachineBasicBlock*>::iterator I = DestBBs.begin(),
+ E = DestBBs.end(); I != E; ++I) {
+ if (!SuccsHandled[(*I)->getNumber()]) {
+ SuccsHandled[(*I)->getNumber()] = true;
+ JumpTableBB->addSuccessor(*I);
+ }
+ }
- // Subtract the lowest switch case value from the value being switched on
- // and conditional branch to default mbb if the result is greater than the
- // difference between smallest and largest cases.
- SDOperand SwitchOp = getValue(SV);
- MVT::ValueType VT = SwitchOp.getValueType();
- SDOperand SUB = DAG.getNode(ISD::SUB, VT, SwitchOp,
- DAG.getConstant(First, VT));
-
- // The SDNode we just created, which holds the value being switched on
- // minus the the smallest case value, needs to be copied to a virtual
- // register so it can be used as an index into the jump table in a
- // subsequent basic block. This value may be smaller or larger than the
- // target's pointer type, and therefore require extension or truncating.
- if (VT > TLI.getPointerTy())
- SwitchOp = DAG.getNode(ISD::TRUNCATE, TLI.getPointerTy(), SUB);
- else
- SwitchOp = DAG.getNode(ISD::ZERO_EXTEND, TLI.getPointerTy(), SUB);
+ // Create a jump table index for this jump table, or return an existing
+ // one.
+ unsigned JTI = CurMF->getJumpTableInfo()->getJumpTableIndex(DestBBs);
+
+ // Set the jump table information so that we can codegen it as a second
+ // MachineBasicBlock
+ SelectionDAGISel::JumpTable JT(-1UL, JTI, JumpTableBB, Default);
+ SelectionDAGISel::JumpTableHeader JTH(First, Last, SV, CR.CaseBB,
+ (CR.CaseBB == CurMBB));
+ if (CR.CaseBB == CurMBB)
+ visitJumpTableHeader(JT, JTH);
+
+ JTCases.push_back(SelectionDAGISel::JumpTableBlock(JTH, JT));
- unsigned JumpTableReg = FuncInfo.MakeReg(TLI.getPointerTy());
- SDOperand CopyTo = DAG.getCopyToReg(getRoot(), JumpTableReg, SwitchOp);
-
- // Emit the range check for the jump table, and branch to the default
- // block for the switch statement if the value being switched on exceeds
- // the largest case in the switch.
- SDOperand CMP = DAG.getSetCC(TLI.getSetCCResultTy(), SUB,
- DAG.getConstant(Last-First,VT), ISD::SETUGT);
- DAG.setRoot(DAG.getNode(ISD::BRCOND, MVT::Other, CopyTo, CMP,
- DAG.getBasicBlock(Default)));
+ return true;
+}
- // Build a vector of destination BBs, corresponding to each target
- // of the jump table. If the value of the jump table slot corresponds to
- // a case statement, push the case's BB onto the vector, otherwise, push
- // the default BB.
- std::vector<MachineBasicBlock*> DestBBs;
- uint64_t TEI = First;
- for (CaseItr ii = Cases.begin(), ee = Cases.end(); ii != ee; ++TEI)
- if (cast<ConstantIntegral>(ii->first)->getZExtValue() == TEI) {
- DestBBs.push_back(ii->second);
- ++ii;
- } else {
- DestBBs.push_back(Default);
- }
-
- // Update successor info. Add one edge to each unique successor.
- // Vector bool would be better, but vector<bool> is really slow.
- std::vector<unsigned char> SuccsHandled;
- SuccsHandled.resize(CurMBB->getParent()->getNumBlockIDs());
-
- for (std::vector<MachineBasicBlock*>::iterator I = DestBBs.begin(),
- E = DestBBs.end(); I != E; ++I) {
- if (!SuccsHandled[(*I)->getNumber()]) {
- SuccsHandled[(*I)->getNumber()] = true;
- JumpTableBB->addSuccessor(*I);
- }
- }
-
- // Create a jump table index for this jump table, or return an existing
- // one.
- unsigned JTI = CurMF->getJumpTableInfo()->getJumpTableIndex(DestBBs);
-
- // Set the jump table information so that we can codegen it as a second
- // MachineBasicBlock
- JT.Reg = JumpTableReg;
- JT.JTI = JTI;
- JT.MBB = JumpTableBB;
- JT.Default = Default;
- return;
+/// handleBTSplitSwitchCase - emit comparison and split binary search tree into
+/// 2 subtrees.
+bool SelectionDAGLowering::handleBTSplitSwitchCase(CaseRec& CR,
+ CaseRecVector& WorkList,
+ Value* SV,
+ MachineBasicBlock* Default) {
+ // Get the MachineFunction which holds the current MBB. This is used when
+ // inserting any additional MBBs necessary to represent the switch.
+ MachineFunction *CurMF = CurMBB->getParent();
+
+ // Figure out which block is immediately after the current one.
+ MachineBasicBlock *NextBlock = 0;
+ MachineFunction::iterator BBI = CR.CaseBB;
+
+ if (++BBI != CurMBB->getParent()->end())
+ NextBlock = BBI;
+
+ Case& FrontCase = *CR.Range.first;
+ Case& BackCase = *(CR.Range.second-1);
+ const BasicBlock *LLVMBB = CR.CaseBB->getBasicBlock();
+
+ // Size is the number of Cases represented by this range.
+ unsigned Size = CR.Range.second - CR.Range.first;
+
+ int64_t First = cast<ConstantInt>(FrontCase.Low)->getSExtValue();
+ int64_t Last = cast<ConstantInt>(BackCase.High)->getSExtValue();
+ double FMetric = 0;
+ CaseItr Pivot = CR.Range.first + Size/2;
+
+ // Select optimal pivot, maximizing sum density of LHS and RHS. This will
+ // (heuristically) allow us to emit JumpTable's later.
+ uint64_t TSize = 0;
+ for (CaseItr I = CR.Range.first, E = CR.Range.second;
+ I!=E; ++I)
+ TSize += I->size();
+
+ uint64_t LSize = FrontCase.size();
+ uint64_t RSize = TSize-LSize;
+ DOUT << "Selecting best pivot: \n"
+ << "First: " << First << ", Last: " << Last <<"\n"
+ << "LSize: " << LSize << ", RSize: " << RSize << "\n";
+ for (CaseItr I = CR.Range.first, J=I+1, E = CR.Range.second;
+ J!=E; ++I, ++J) {
+ int64_t LEnd = cast<ConstantInt>(I->High)->getSExtValue();
+ int64_t RBegin = cast<ConstantInt>(J->Low)->getSExtValue();
+ assert((RBegin-LEnd>=1) && "Invalid case distance");
+ double LDensity = (double)LSize / (double)((LEnd - First) + 1ULL);
+ double RDensity = (double)RSize / (double)((Last - RBegin) + 1ULL);
+ double Metric = Log2_64(RBegin-LEnd)*(LDensity+RDensity);
+ // Should always split in some non-trivial place
+ DOUT <<"=>Step\n"
+ << "LEnd: " << LEnd << ", RBegin: " << RBegin << "\n"
+ << "LDensity: " << LDensity << ", RDensity: " << RDensity << "\n"
+ << "Metric: " << Metric << "\n";
+ if (FMetric < Metric) {
+ Pivot = J;
+ FMetric = Metric;
+ DOUT << "Current metric set to: " << FMetric << "\n";
}
+
+ LSize += J->size();
+ RSize -= J->size();
}
+ // If our case is dense we *really* should handle it earlier!
+ assert((FMetric > 0) && "Should handle dense range earlier!");
- // Push the initial CaseRec onto the worklist
- std::vector<CaseRec> CaseVec;
- CaseVec.push_back(CaseRec(CurMBB,0,0,CaseRange(Cases.begin(),Cases.end())));
+ CaseRange LHSR(CR.Range.first, Pivot);
+ CaseRange RHSR(Pivot, CR.Range.second);
+ Constant *C = Pivot->Low;
+ MachineBasicBlock *FalseBB = 0, *TrueBB = 0;
+
+ // We know that we branch to the LHS if the Value being switched on is
+ // less than the Pivot value, C. We use this to optimize our binary
+ // tree a bit, by recognizing that if SV is greater than or equal to the
+ // LHS's Case Value, and that Case Value is exactly one less than the
+ // Pivot's Value, then we can branch directly to the LHS's Target,
+ // rather than creating a leaf node for it.
+ if ((LHSR.second - LHSR.first) == 1 &&
+ LHSR.first->High == CR.GE &&
+ cast<ConstantInt>(C)->getSExtValue() ==
+ (cast<ConstantInt>(CR.GE)->getSExtValue() + 1LL)) {
+ TrueBB = LHSR.first->BB;
+ } else {
+ TrueBB = new MachineBasicBlock(LLVMBB);
+ CurMF->getBasicBlockList().insert(BBI, TrueBB);
+ WorkList.push_back(CaseRec(TrueBB, C, CR.GE, LHSR));
+ }
- while (!CaseVec.empty()) {
- // Grab a record representing a case range to process off the worklist
- CaseRec CR = CaseVec.back();
- CaseVec.pop_back();
+ // Similar to the optimization above, if the Value being switched on is
+ // known to be less than the Constant CR.LT, and the current Case Value
+ // is CR.LT - 1, then we can branch directly to the target block for
+ // the current Case Value, rather than emitting a RHS leaf node for it.
+ if ((RHSR.second - RHSR.first) == 1 && CR.LT &&
+ cast<ConstantInt>(RHSR.first->Low)->getSExtValue() ==
+ (cast<ConstantInt>(CR.LT)->getSExtValue() - 1LL)) {
+ FalseBB = RHSR.first->BB;
+ } else {
+ FalseBB = new MachineBasicBlock(LLVMBB);
+ CurMF->getBasicBlockList().insert(BBI, FalseBB);
+ WorkList.push_back(CaseRec(FalseBB,CR.LT,C,RHSR));
+ }
+
+ // Create a CaseBlock record representing a conditional branch to
+ // the LHS node if the value being switched on SV is less than C.
+ // Otherwise, branch to LHS.
+ SelectionDAGISel::CaseBlock CB(ISD::SETLT, SV, C, NULL,
+ TrueBB, FalseBB, CR.CaseBB);
+
+ if (CR.CaseBB == CurMBB)
+ visitSwitchCase(CB);
+ else
+ SwitchCases.push_back(CB);
+
+ return true;
+}
+
+/// handleBitTestsSwitchCase - if current case range has few destination and
+/// range span less, than machine word bitwidth, encode case range into series
+/// of masks and emit bit tests with these masks.
+bool SelectionDAGLowering::handleBitTestsSwitchCase(CaseRec& CR,
+ CaseRecVector& WorkList,
+ Value* SV,
+ MachineBasicBlock* Default) {
+ unsigned IntPtrBits = getSizeInBits(TLI.getPointerTy());
+
+ Case& FrontCase = *CR.Range.first;
+ Case& BackCase = *(CR.Range.second-1);
+
+ // Get the MachineFunction which holds the current MBB. This is used when
+ // inserting any additional MBBs necessary to represent the switch.
+ MachineFunction *CurMF = CurMBB->getParent();
+
+ unsigned numCmps = 0;
+ for (CaseItr I = CR.Range.first, E = CR.Range.second;
+ I!=E; ++I) {
+ // Single case counts one, case range - two.
+ if (I->Low == I->High)
+ numCmps +=1;
+ else
+ numCmps +=2;
+ }
- // Size is the number of Cases represented by this range. If Size is 1,
- // then we are processing a leaf of the binary search tree. Otherwise,
- // we need to pick a pivot, and push left and right ranges onto the
- // worklist.
- unsigned Size = CR.Range.second - CR.Range.first;
+ // Count unique destinations
+ SmallSet<MachineBasicBlock*, 4> Dests;
+ for (CaseItr I = CR.Range.first, E = CR.Range.second; I!=E; ++I) {
+ Dests.insert(I->BB);
+ if (Dests.size() > 3)
+ // Don't bother the code below, if there are too much unique destinations
+ return false;
+ }
+ DOUT << "Total number of unique destinations: " << Dests.size() << "\n"
+ << "Total number of comparisons: " << numCmps << "\n";
+
+ // Compute span of values.
+ Constant* minValue = FrontCase.Low;
+ Constant* maxValue = BackCase.High;
+ uint64_t range = cast<ConstantInt>(maxValue)->getSExtValue() -
+ cast<ConstantInt>(minValue)->getSExtValue();
+ DOUT << "Compare range: " << range << "\n"
+ << "Low bound: " << cast<ConstantInt>(minValue)->getSExtValue() << "\n"
+ << "High bound: " << cast<ConstantInt>(maxValue)->getSExtValue() << "\n";
+
+ if (range>IntPtrBits ||
+ (!(Dests.size() == 1 && numCmps >= 3) &&
+ !(Dests.size() == 2 && numCmps >= 5) &&
+ !(Dests.size() >= 3 && numCmps >= 6)))
+ return false;
+
+ DOUT << "Emitting bit tests\n";
+ int64_t lowBound = 0;
- if (Size == 1) {
- // Create a CaseBlock record representing a conditional branch to
- // the Case's target mbb if the value being switched on SV is equal
- // to C. Otherwise, branch to default.
- Constant *C = CR.Range.first->first;
- MachineBasicBlock *Target = CR.Range.first->second;
- SelectionDAGISel::CaseBlock CB(ISD::SETEQ, SV, C, Target, Default,
- CR.CaseBB);
-
- // If the MBB representing the leaf node is the current MBB, then just
- // call visitSwitchCase to emit the code into the current block.
- // Otherwise, push the CaseBlock onto the vector to be later processed
- // by SDISel, and insert the node's MBB before the next MBB.
- if (CR.CaseBB == CurMBB)
- visitSwitchCase(CB);
- else
- SwitchCases.push_back(CB);
- } else {
- // split case range at pivot
- CaseItr Pivot = CR.Range.first + (Size / 2);
- CaseRange LHSR(CR.Range.first, Pivot);
- CaseRange RHSR(Pivot, CR.Range.second);
- Constant *C = Pivot->first;
- MachineBasicBlock *FalseBB = 0, *TrueBB = 0;
-
- // We know that we branch to the LHS if the Value being switched on is
- // less than the Pivot value, C. We use this to optimize our binary
- // tree a bit, by recognizing that if SV is greater than or equal to the
- // LHS's Case Value, and that Case Value is exactly one less than the
- // Pivot's Value, then we can branch directly to the LHS's Target,
- // rather than creating a leaf node for it.
- if ((LHSR.second - LHSR.first) == 1 &&
- LHSR.first->first == CR.GE &&
- cast<ConstantIntegral>(C)->getZExtValue() ==
- (cast<ConstantIntegral>(CR.GE)->getZExtValue() + 1ULL)) {
- TrueBB = LHSR.first->second;
- } else {
- TrueBB = new MachineBasicBlock(LLVMBB);
- CurMF->getBasicBlockList().insert(BBI, TrueBB);
- CaseVec.push_back(CaseRec(TrueBB, C, CR.GE, LHSR));
- }
+ // Optimize the case where all the case values fit in a
+ // word without having to subtract minValue. In this case,
+ // we can optimize away the subtraction.
+ if (cast<ConstantInt>(minValue)->getSExtValue() >= 0 &&
+ cast<ConstantInt>(maxValue)->getSExtValue() <= IntPtrBits) {
+ range = cast<ConstantInt>(maxValue)->getSExtValue();
+ } else {
+ lowBound = cast<ConstantInt>(minValue)->getSExtValue();
+ }
+
+ CaseBitsVector CasesBits;
+ unsigned i, count = 0;
+
+ for (CaseItr I = CR.Range.first, E = CR.Range.second; I!=E; ++I) {
+ MachineBasicBlock* Dest = I->BB;
+ for (i = 0; i < count; ++i)
+ if (Dest == CasesBits[i].BB)
+ break;
+
+ if (i == count) {
+ assert((count < 3) && "Too much destinations to test!");
+ CasesBits.push_back(CaseBits(0, Dest, 0));
+ count++;
+ }
+
+ uint64_t lo = cast<ConstantInt>(I->Low)->getSExtValue() - lowBound;
+ uint64_t hi = cast<ConstantInt>(I->High)->getSExtValue() - lowBound;
+
+ for (uint64_t j = lo; j <= hi; j++) {
+ CasesBits[i].Mask |= 1 << j;
+ CasesBits[i].Bits++;
+ }
+
+ }
+ std::sort(CasesBits.begin(), CasesBits.end(), CaseBitsCmp());
+
+ SelectionDAGISel::BitTestInfo BTC;
- // Similar to the optimization above, if the Value being switched on is
- // known to be less than the Constant CR.LT, and the current Case Value
- // is CR.LT - 1, then we can branch directly to the target block for
- // the current Case Value, rather than emitting a RHS leaf node for it.
- if ((RHSR.second - RHSR.first) == 1 && CR.LT &&
- cast<ConstantIntegral>(RHSR.first->first)->getZExtValue() ==
- (cast<ConstantIntegral>(CR.LT)->getZExtValue() - 1ULL)) {
- FalseBB = RHSR.first->second;
+ // Figure out which block is immediately after the current one.
+ MachineFunction::iterator BBI = CR.CaseBB;
+ ++BBI;
+
+ const BasicBlock *LLVMBB = CR.CaseBB->getBasicBlock();
+
+ DOUT << "Cases:\n";
+ for (unsigned i = 0, e = CasesBits.size(); i!=e; ++i) {
+ DOUT << "Mask: " << CasesBits[i].Mask << ", Bits: " << CasesBits[i].Bits
+ << ", BB: " << CasesBits[i].BB << "\n";
+
+ MachineBasicBlock *CaseBB = new MachineBasicBlock(LLVMBB);
+ CurMF->getBasicBlockList().insert(BBI, CaseBB);
+ BTC.push_back(SelectionDAGISel::BitTestCase(CasesBits[i].Mask,
+ CaseBB,
+ CasesBits[i].BB));
+ }
+
+ SelectionDAGISel::BitTestBlock BTB(lowBound, range, SV,
+ -1U, (CR.CaseBB == CurMBB),
+ CR.CaseBB, Default, BTC);
+
+ if (CR.CaseBB == CurMBB)
+ visitBitTestHeader(BTB);
+
+ BitTestCases.push_back(BTB);
+
+ return true;
+}
+
+
+// Clusterify - Transform simple list of Cases into list of CaseRange's
+unsigned SelectionDAGLowering::Clusterify(CaseVector& Cases,
+ const SwitchInst& SI) {
+ unsigned numCmps = 0;
+
+ // Start with "simple" cases
+ for (unsigned i = 1; i < SI.getNumSuccessors(); ++i) {
+ MachineBasicBlock *SMBB = FuncInfo.MBBMap[SI.getSuccessor(i)];
+ Cases.push_back(Case(SI.getSuccessorValue(i),
+ SI.getSuccessorValue(i),
+ SMBB));
+ }
+ sort(Cases.begin(), Cases.end(), CaseCmp());
+
+ // Merge case into clusters
+ if (Cases.size()>=2)
+ for (CaseItr I=Cases.begin(), J=++(Cases.begin()), E=Cases.end(); J!=E; ) {
+ int64_t nextValue = cast<ConstantInt>(J->Low)->getSExtValue();
+ int64_t currentValue = cast<ConstantInt>(I->High)->getSExtValue();
+ MachineBasicBlock* nextBB = J->BB;
+ MachineBasicBlock* currentBB = I->BB;
+
+ // If the two neighboring cases go to the same destination, merge them
+ // into a single case.
+ if ((nextValue-currentValue==1) && (currentBB == nextBB)) {
+ I->High = J->High;
+ J = Cases.erase(J);
} else {
- FalseBB = new MachineBasicBlock(LLVMBB);
- CurMF->getBasicBlockList().insert(BBI, FalseBB);
- CaseVec.push_back(CaseRec(FalseBB,CR.LT,C,RHSR));
+ I = J++;
}
+ }
- // Create a CaseBlock record representing a conditional branch to
- // the LHS node if the value being switched on SV is less than C.
- // Otherwise, branch to LHS.
- ISD::CondCode CC = C->getType()->isSigned() ? ISD::SETLT : ISD::SETULT;
- SelectionDAGISel::CaseBlock CB(CC, SV, C, TrueBB, FalseBB, CR.CaseBB);
+ for (CaseItr I=Cases.begin(), E=Cases.end(); I!=E; ++I, ++numCmps) {
+ if (I->Low != I->High)
+ // A range counts double, since it requires two compares.
+ ++numCmps;
+ }
- if (CR.CaseBB == CurMBB)
- visitSwitchCase(CB);
- else
- SwitchCases.push_back(CB);
- }
+ return numCmps;
+}
+
+void SelectionDAGLowering::visitSwitch(SwitchInst &SI) {
+ // Figure out which block is immediately after the current one.
+ MachineBasicBlock *NextBlock = 0;
+ MachineFunction::iterator BBI = CurMBB;
+
+ MachineBasicBlock *Default = FuncInfo.MBBMap[SI.getDefaultDest()];
+
+ // If there is only the default destination, branch to it if it is not the
+ // next basic block. Otherwise, just fall through.
+ if (SI.getNumOperands() == 2) {
+ // Update machine-CFG edges.
+
+ // If this is not a fall-through branch, emit the branch.
+ if (Default != NextBlock)
+ DAG.setRoot(DAG.getNode(ISD::BR, MVT::Other, getRoot(),
+ DAG.getBasicBlock(Default)));
+
+ CurMBB->addSuccessor(Default);
+ return;
+ }
+
+ // If there are any non-default case statements, create a vector of Cases
+ // representing each one, and sort the vector so that we can efficiently
+ // create a binary search tree from them.
+ CaseVector Cases;
+ unsigned numCmps = Clusterify(Cases, SI);
+ DOUT << "Clusterify finished. Total clusters: " << Cases.size()
+ << ". Total compares: " << numCmps << "\n";
+
+ // Get the Value to be switched on and default basic blocks, which will be
+ // inserted into CaseBlock records, representing basic blocks in the binary
+ // search tree.
+ Value *SV = SI.getOperand(0);
+
+ // Push the initial CaseRec onto the worklist
+ CaseRecVector WorkList;
+ WorkList.push_back(CaseRec(CurMBB,0,0,CaseRange(Cases.begin(),Cases.end())));
+
+ while (!WorkList.empty()) {
+ // Grab a record representing a case range to process off the worklist
+ CaseRec CR = WorkList.back();
+ WorkList.pop_back();
+
+ if (handleBitTestsSwitchCase(CR, WorkList, SV, Default))
+ continue;
+
+ // If the range has few cases (two or less) emit a series of specific
+ // tests.
+ if (handleSmallSwitchRange(CR, WorkList, SV, Default))
+ continue;
+
+ // If the switch has more than 5 blocks, and at least 40% dense, and the
+ // target supports indirect branches, then emit a jump table rather than
+ // lowering the switch to a binary tree of conditional branches.
+ if (handleJTSwitchCase(CR, WorkList, SV, Default))
+ continue;
+
+ // Emit binary tree. We need to pick a pivot, and push left and right ranges
+ // onto the worklist. Leafs are handled via handleSmallSwitchRange() call.
+ handleBTSplitSwitchCase(CR, WorkList, SV, Default);
}
}
+
void SelectionDAGLowering::visitSub(User &I) {
// -0.0 - X --> fneg
- if (I.getType()->isFloatingPoint()) {
+ const Type *Ty = I.getType();
+ if (isa<VectorType>(Ty)) {
+ visitVectorBinary(I, ISD::VSUB);
+ } else if (Ty->isFloatingPoint()) {
if (ConstantFP *CFP = dyn_cast<ConstantFP>(I.getOperand(0)))
if (CFP->isExactlyValue(-0.0)) {
SDOperand Op2 = getValue(I.getOperand(1));
setValue(&I, DAG.getNode(ISD::FNEG, Op2.getValueType(), Op2));
return;
}
- visitFPBinary(I, ISD::FSUB, ISD::VSUB);
+ visitScalarBinary(I, ISD::FSUB);
} else
- visitIntBinary(I, ISD::SUB, ISD::VSUB);
+ visitScalarBinary(I, ISD::SUB);
}
-void
-SelectionDAGLowering::visitIntBinary(User &I, unsigned IntOp, unsigned VecOp) {
- const Type *Ty = I.getType();
+void SelectionDAGLowering::visitScalarBinary(User &I, unsigned OpCode) {
SDOperand Op1 = getValue(I.getOperand(0));
SDOperand Op2 = getValue(I.getOperand(1));
-
- if (const PackedType *PTy = dyn_cast<PackedType>(Ty)) {
- SDOperand Num = DAG.getConstant(PTy->getNumElements(), MVT::i32);
- SDOperand Typ = DAG.getValueType(TLI.getValueType(PTy->getElementType()));
- setValue(&I, DAG.getNode(VecOp, MVT::Vector, Op1, Op2, Num, Typ));
- } else {
- setValue(&I, DAG.getNode(IntOp, Op1.getValueType(), Op1, Op2));
- }
+
+ setValue(&I, DAG.getNode(OpCode, Op1.getValueType(), Op1, Op2));
}
-void
-SelectionDAGLowering::visitFPBinary(User &I, unsigned FPOp, unsigned VecOp) {
- const Type *Ty = I.getType();
- SDOperand Op1 = getValue(I.getOperand(0));
- SDOperand Op2 = getValue(I.getOperand(1));
+void
+SelectionDAGLowering::visitVectorBinary(User &I, unsigned OpCode) {
+ assert(isa<VectorType>(I.getType()));
+ const VectorType *Ty = cast<VectorType>(I.getType());
+ SDOperand Typ = DAG.getValueType(TLI.getValueType(Ty->getElementType()));
+
+ setValue(&I, DAG.getNode(OpCode, MVT::Vector,
+ getValue(I.getOperand(0)),
+ getValue(I.getOperand(1)),
+ DAG.getConstant(Ty->getNumElements(), MVT::i32),
+ Typ));
+}
- if (const PackedType *PTy = dyn_cast<PackedType>(Ty)) {
- SDOperand Num = DAG.getConstant(PTy->getNumElements(), MVT::i32);
- SDOperand Typ = DAG.getValueType(TLI.getValueType(PTy->getElementType()));
- setValue(&I, DAG.getNode(VecOp, MVT::Vector, Op1, Op2, Num, Typ));
- } else {
- setValue(&I, DAG.getNode(FPOp, Op1.getValueType(), Op1, Op2));
- }
+void SelectionDAGLowering::visitEitherBinary(User &I, unsigned ScalarOp,
+ unsigned VectorOp) {
+ if (isa<VectorType>(I.getType()))
+ visitVectorBinary(I, VectorOp);
+ else
+ visitScalarBinary(I, ScalarOp);
}
void SelectionDAGLowering::visitShift(User &I, unsigned Opcode) {
SDOperand Op1 = getValue(I.getOperand(0));
SDOperand Op2 = getValue(I.getOperand(1));
- Op2 = DAG.getNode(ISD::ANY_EXTEND, TLI.getShiftAmountTy(), Op2);
+ if (TLI.getShiftAmountTy() < Op2.getValueType())
+ Op2 = DAG.getNode(ISD::TRUNCATE, TLI.getShiftAmountTy(), Op2);
+ else if (TLI.getShiftAmountTy() > Op2.getValueType())
+ Op2 = DAG.getNode(ISD::ANY_EXTEND, TLI.getShiftAmountTy(), Op2);
setValue(&I, DAG.getNode(Opcode, Op1.getValueType(), Op1, Op2));
}
void SelectionDAGLowering::visitICmp(User &I) {
- ICmpInst *IC = cast<ICmpInst>(&I);
- SDOperand Op1 = getValue(IC->getOperand(0));
- SDOperand Op2 = getValue(IC->getOperand(1));
+ ICmpInst::Predicate predicate = ICmpInst::BAD_ICMP_PREDICATE;
+ if (ICmpInst *IC = dyn_cast<ICmpInst>(&I))
+ predicate = IC->getPredicate();
+ else if (ConstantExpr *IC = dyn_cast<ConstantExpr>(&I))
+ predicate = ICmpInst::Predicate(IC->getPredicate());
+ SDOperand Op1 = getValue(I.getOperand(0));
+ SDOperand Op2 = getValue(I.getOperand(1));
ISD::CondCode Opcode;
- switch (IC->getPredicate()) {
+ switch (predicate) {
case ICmpInst::ICMP_EQ : Opcode = ISD::SETEQ; break;
case ICmpInst::ICMP_NE : Opcode = ISD::SETNE; break;
case ICmpInst::ICMP_UGT : Opcode = ISD::SETUGT; break;
}
void SelectionDAGLowering::visitFCmp(User &I) {
- FCmpInst *FC = cast<FCmpInst>(&I);
- SDOperand Op1 = getValue(FC->getOperand(0));
- SDOperand Op2 = getValue(FC->getOperand(1));
- ISD::CondCode Opcode;
- switch (FC->getPredicate()) {
- case FCmpInst::FCMP_FALSE : Opcode = ISD::SETFALSE;
- case FCmpInst::FCMP_OEQ : Opcode = ISD::SETOEQ;
- case FCmpInst::FCMP_OGT : Opcode = ISD::SETOGT;
- case FCmpInst::FCMP_OGE : Opcode = ISD::SETOGE;
- case FCmpInst::FCMP_OLT : Opcode = ISD::SETOLT;
- case FCmpInst::FCMP_OLE : Opcode = ISD::SETOLE;
- case FCmpInst::FCMP_ONE : Opcode = ISD::SETONE;
- case FCmpInst::FCMP_ORD : Opcode = ISD::SETO;
- case FCmpInst::FCMP_UNO : Opcode = ISD::SETUO;
- case FCmpInst::FCMP_UEQ : Opcode = ISD::SETUEQ;
- case FCmpInst::FCMP_UGT : Opcode = ISD::SETUGT;
- case FCmpInst::FCMP_UGE : Opcode = ISD::SETUGE;
- case FCmpInst::FCMP_ULT : Opcode = ISD::SETULT;
- case FCmpInst::FCMP_ULE : Opcode = ISD::SETULE;
- case FCmpInst::FCMP_UNE : Opcode = ISD::SETUNE;
- case FCmpInst::FCMP_TRUE : Opcode = ISD::SETTRUE;
+ FCmpInst::Predicate predicate = FCmpInst::BAD_FCMP_PREDICATE;
+ if (FCmpInst *FC = dyn_cast<FCmpInst>(&I))
+ predicate = FC->getPredicate();
+ else if (ConstantExpr *FC = dyn_cast<ConstantExpr>(&I))
+ predicate = FCmpInst::Predicate(FC->getPredicate());
+ SDOperand Op1 = getValue(I.getOperand(0));
+ SDOperand Op2 = getValue(I.getOperand(1));
+ ISD::CondCode Condition, FOC, FPC;
+ switch (predicate) {
+ case FCmpInst::FCMP_FALSE: FOC = FPC = ISD::SETFALSE; break;
+ case FCmpInst::FCMP_OEQ: FOC = ISD::SETEQ; FPC = ISD::SETOEQ; break;
+ case FCmpInst::FCMP_OGT: FOC = ISD::SETGT; FPC = ISD::SETOGT; break;
+ case FCmpInst::FCMP_OGE: FOC = ISD::SETGE; FPC = ISD::SETOGE; break;
+ case FCmpInst::FCMP_OLT: FOC = ISD::SETLT; FPC = ISD::SETOLT; break;
+ case FCmpInst::FCMP_OLE: FOC = ISD::SETLE; FPC = ISD::SETOLE; break;
+ case FCmpInst::FCMP_ONE: FOC = ISD::SETNE; FPC = ISD::SETONE; break;
+ case FCmpInst::FCMP_ORD: FOC = ISD::SETEQ; FPC = ISD::SETO; break;
+ case FCmpInst::FCMP_UNO: FOC = ISD::SETNE; FPC = ISD::SETUO; break;
+ case FCmpInst::FCMP_UEQ: FOC = ISD::SETEQ; FPC = ISD::SETUEQ; break;
+ case FCmpInst::FCMP_UGT: FOC = ISD::SETGT; FPC = ISD::SETUGT; break;
+ case FCmpInst::FCMP_UGE: FOC = ISD::SETGE; FPC = ISD::SETUGE; break;
+ case FCmpInst::FCMP_ULT: FOC = ISD::SETLT; FPC = ISD::SETULT; break;
+ case FCmpInst::FCMP_ULE: FOC = ISD::SETLE; FPC = ISD::SETULE; break;
+ case FCmpInst::FCMP_UNE: FOC = ISD::SETNE; FPC = ISD::SETUNE; break;
+ case FCmpInst::FCMP_TRUE: FOC = FPC = ISD::SETTRUE; break;
default:
assert(!"Invalid FCmp predicate value");
- Opcode = ISD::SETFALSE;
+ FOC = FPC = ISD::SETFALSE;
break;
}
- setValue(&I, DAG.getSetCC(MVT::i1, Op1, Op2, Opcode));
-}
-
-void SelectionDAGLowering::visitSetCC(User &I,ISD::CondCode SignedOpcode,
- ISD::CondCode UnsignedOpcode,
- ISD::CondCode FPOpcode) {
- SDOperand Op1 = getValue(I.getOperand(0));
- SDOperand Op2 = getValue(I.getOperand(1));
- ISD::CondCode Opcode = SignedOpcode;
- if (!FiniteOnlyFPMath() && I.getOperand(0)->getType()->isFloatingPoint())
- Opcode = FPOpcode;
- else if (I.getOperand(0)->getType()->isUnsigned())
- Opcode = UnsignedOpcode;
- setValue(&I, DAG.getSetCC(MVT::i1, Op1, Op2, Opcode));
+ if (FiniteOnlyFPMath())
+ Condition = FOC;
+ else
+ Condition = FPC;
+ setValue(&I, DAG.getSetCC(MVT::i1, Op1, Op2, Condition));
}
void SelectionDAGLowering::visitSelect(User &I) {
SDOperand Cond = getValue(I.getOperand(0));
SDOperand TrueVal = getValue(I.getOperand(1));
SDOperand FalseVal = getValue(I.getOperand(2));
- if (!isa<PackedType>(I.getType())) {
+ if (!isa<VectorType>(I.getType())) {
setValue(&I, DAG.getNode(ISD::SELECT, TrueVal.getValueType(), Cond,
TrueVal, FalseVal));
} else {
if (DestVT == MVT::Vector) {
// This is a cast to a vector from something else.
// Get information about the output vector.
- const PackedType *DestTy = cast<PackedType>(I.getType());
+ const VectorType *DestTy = cast<VectorType>(I.getType());
MVT::ValueType EltVT = TLI.getValueType(DestTy->getElementType());
setValue(&I, DAG.getNode(ISD::VBIT_CONVERT, DestVT, N,
DAG.getConstant(DestTy->getNumElements(),MVT::i32),
unsigned Field = cast<ConstantInt>(Idx)->getZExtValue();
if (Field) {
// N = N + Offset
- uint64_t Offset = TD->getStructLayout(StTy)->MemberOffsets[Field];
+ uint64_t Offset = TD->getStructLayout(StTy)->getElementOffset(Field);
N = DAG.getNode(ISD::ADD, N.getValueType(), N,
getIntPtrConstant(Offset));
}
// If this is a constant subscript, handle it quickly.
if (ConstantInt *CI = dyn_cast<ConstantInt>(Idx)) {
if (CI->getZExtValue() == 0) continue;
- uint64_t Offs;
- if (CI->getType()->isSigned())
- Offs = (int64_t)
+ uint64_t Offs =
TD->getTypeSize(Ty)*cast<ConstantInt>(CI)->getSExtValue();
- else
- Offs =
- TD->getTypeSize(Ty)*cast<ConstantInt>(CI)->getZExtValue();
N = DAG.getNode(ISD::ADD, N.getValueType(), N, getIntPtrConstant(Offs));
continue;
}
// If the index is smaller or larger than intptr_t, truncate or extend
// it.
if (IdxN.getValueType() < N.getValueType()) {
- if (Idx->getType()->isSigned())
- IdxN = DAG.getNode(ISD::SIGN_EXTEND, N.getValueType(), IdxN);
- else
- IdxN = DAG.getNode(ISD::ZERO_EXTEND, N.getValueType(), IdxN);
+ IdxN = DAG.getNode(ISD::SIGN_EXTEND, N.getValueType(), IdxN);
} else if (IdxN.getValueType() > N.getValueType())
IdxN = DAG.getNode(ISD::TRUNCATE, N.getValueType(), IdxN);
const Type *Ty = I.getAllocatedType();
uint64_t TySize = TLI.getTargetData()->getTypeSize(Ty);
- unsigned Align = std::max((unsigned)TLI.getTargetData()->getTypeAlignment(Ty),
- I.getAlignment());
+ unsigned Align =
+ std::max((unsigned)TLI.getTargetData()->getPrefTypeAlignment(Ty),
+ I.getAlignment());
SDOperand AllocSize = getValue(I.getArraySize());
MVT::ValueType IntPtr = TLI.getPointerTy();
const MVT::ValueType *VTs = DAG.getNodeValueTypes(AllocSize.getValueType(),
MVT::Other);
SDOperand DSA = DAG.getNode(ISD::DYNAMIC_STACKALLOC, VTs, 2, Ops, 3);
- DAG.setRoot(setValue(&I, DSA).getValue(1));
+ setValue(&I, DSA);
+ DAG.setRoot(DSA.getValue(1));
// Inform the Frame Information that we have just allocated a variable-sized
// object.
const Value *SV, SDOperand Root,
bool isVolatile) {
SDOperand L;
- if (const PackedType *PTy = dyn_cast<PackedType>(Ty)) {
+ if (const VectorType *PTy = dyn_cast<VectorType>(Ty)) {
MVT::ValueType PVT = TLI.getValueType(PTy->getElementType());
L = DAG.getVecLoad(PTy->getNumElements(), PVT, Root, Ptr,
DAG.getSrcValue(SV));
} else {
- L = DAG.getLoad(TLI.getValueType(Ty), Root, Ptr, SV, isVolatile);
+ L = DAG.getLoad(TLI.getValueType(Ty), Root, Ptr, SV, 0, isVolatile);
}
if (isVolatile)
Value *SrcV = I.getOperand(0);
SDOperand Src = getValue(SrcV);
SDOperand Ptr = getValue(I.getOperand(1));
- DAG.setRoot(DAG.getStore(getRoot(), Src, Ptr, I.getOperand(1),
+ DAG.setRoot(DAG.getStore(getRoot(), Src, Ptr, I.getOperand(1), 0,
I.isVolatile()));
}
for (unsigned i = 1, e = I.getNumOperands(); i != e; ++i) {
SDOperand Op = getValue(I.getOperand(i));
- // If this is a vector type, force it to the right packed type.
+ // If this is a vector type, force it to the right vector type.
if (Op.getValueType() == MVT::Vector) {
- const PackedType *OpTy = cast<PackedType>(I.getOperand(i)->getType());
+ const VectorType *OpTy = cast<VectorType>(I.getOperand(i)->getType());
MVT::ValueType EltVT = TLI.getValueType(OpTy->getElementType());
MVT::ValueType VVT = MVT::getVectorType(EltVT, OpTy->getNumElements());
if (I.getType() != Type::VoidTy) {
MVT::ValueType VT = TLI.getValueType(I.getType());
if (VT == MVT::Vector) {
- const PackedType *DestTy = cast<PackedType>(I.getType());
+ const VectorType *DestTy = cast<VectorType>(I.getType());
MVT::ValueType EltVT = TLI.getValueType(DestTy->getElementType());
VT = MVT::getVectorType(EltVT, DestTy->getNumElements());
DAG.setRoot(Chain);
}
if (I.getType() != Type::VoidTy) {
- if (const PackedType *PTy = dyn_cast<PackedType>(I.getType())) {
+ if (const VectorType *PTy = dyn_cast<VectorType>(I.getType())) {
MVT::ValueType EVT = TLI.getValueType(PTy->getElementType());
Result = DAG.getNode(ISD::VBIT_CONVERT, MVT::Vector, Result,
DAG.getConstant(PTy->getNumElements(), MVT::i32),
case Intrinsic::vastart: visitVAStart(I); return 0;
case Intrinsic::vaend: visitVAEnd(I); return 0;
case Intrinsic::vacopy: visitVACopy(I); return 0;
- case Intrinsic::returnaddress: visitFrameReturnAddress(I, false); return 0;
- case Intrinsic::frameaddress: visitFrameReturnAddress(I, true); return 0;
+ case Intrinsic::returnaddress:
+ setValue(&I, DAG.getNode(ISD::RETURNADDR, TLI.getPointerTy(),
+ getValue(I.getOperand(1))));
+ return 0;
+ case Intrinsic::frameaddress:
+ setValue(&I, DAG.getNode(ISD::FRAMEADDR, TLI.getPointerTy(),
+ getValue(I.getOperand(1))));
+ return 0;
case Intrinsic::setjmp:
return "_setjmp"+!TLI.usesUnderscoreSetJmp();
break;
return 0;
case Intrinsic::dbg_stoppoint: {
- MachineDebugInfo *DebugInfo = DAG.getMachineDebugInfo();
+ MachineModuleInfo *MMI = DAG.getMachineModuleInfo();
DbgStopPointInst &SPI = cast<DbgStopPointInst>(I);
- if (DebugInfo && SPI.getContext() && DebugInfo->Verify(SPI.getContext())) {
+ if (MMI && SPI.getContext() && MMI->Verify(SPI.getContext())) {
SDOperand Ops[5];
Ops[0] = getRoot();
Ops[1] = getValue(SPI.getLineValue());
Ops[2] = getValue(SPI.getColumnValue());
- DebugInfoDesc *DD = DebugInfo->getDescFor(SPI.getContext());
+ DebugInfoDesc *DD = MMI->getDescFor(SPI.getContext());
assert(DD && "Not a debug information descriptor");
CompileUnitDesc *CompileUnit = cast<CompileUnitDesc>(DD);
return 0;
}
case Intrinsic::dbg_region_start: {
- MachineDebugInfo *DebugInfo = DAG.getMachineDebugInfo();
+ MachineModuleInfo *MMI = DAG.getMachineModuleInfo();
DbgRegionStartInst &RSI = cast<DbgRegionStartInst>(I);
- if (DebugInfo && RSI.getContext() && DebugInfo->Verify(RSI.getContext())) {
- unsigned LabelID = DebugInfo->RecordRegionStart(RSI.getContext());
- DAG.setRoot(DAG.getNode(ISD::DEBUG_LABEL, MVT::Other, getRoot(),
+ if (MMI && RSI.getContext() && MMI->Verify(RSI.getContext())) {
+ unsigned LabelID = MMI->RecordRegionStart(RSI.getContext());
+ DAG.setRoot(DAG.getNode(ISD::LABEL, MVT::Other, getRoot(),
DAG.getConstant(LabelID, MVT::i32)));
}
return 0;
}
case Intrinsic::dbg_region_end: {
- MachineDebugInfo *DebugInfo = DAG.getMachineDebugInfo();
+ MachineModuleInfo *MMI = DAG.getMachineModuleInfo();
DbgRegionEndInst &REI = cast<DbgRegionEndInst>(I);
- if (DebugInfo && REI.getContext() && DebugInfo->Verify(REI.getContext())) {
- unsigned LabelID = DebugInfo->RecordRegionEnd(REI.getContext());
- DAG.setRoot(DAG.getNode(ISD::DEBUG_LABEL, MVT::Other,
+ if (MMI && REI.getContext() && MMI->Verify(REI.getContext())) {
+ unsigned LabelID = MMI->RecordRegionEnd(REI.getContext());
+ DAG.setRoot(DAG.getNode(ISD::LABEL, MVT::Other,
getRoot(), DAG.getConstant(LabelID, MVT::i32)));
}
return 0;
}
case Intrinsic::dbg_func_start: {
- MachineDebugInfo *DebugInfo = DAG.getMachineDebugInfo();
+ MachineModuleInfo *MMI = DAG.getMachineModuleInfo();
DbgFuncStartInst &FSI = cast<DbgFuncStartInst>(I);
- if (DebugInfo && FSI.getSubprogram() &&
- DebugInfo->Verify(FSI.getSubprogram())) {
- unsigned LabelID = DebugInfo->RecordRegionStart(FSI.getSubprogram());
- DAG.setRoot(DAG.getNode(ISD::DEBUG_LABEL, MVT::Other,
+ if (MMI && FSI.getSubprogram() &&
+ MMI->Verify(FSI.getSubprogram())) {
+ unsigned LabelID = MMI->RecordRegionStart(FSI.getSubprogram());
+ DAG.setRoot(DAG.getNode(ISD::LABEL, MVT::Other,
getRoot(), DAG.getConstant(LabelID, MVT::i32)));
}
-
+
+ return 0;
+ }
+ case Intrinsic::dbg_declare: {
+ MachineModuleInfo *MMI = DAG.getMachineModuleInfo();
+ DbgDeclareInst &DI = cast<DbgDeclareInst>(I);
+ if (MMI && DI.getVariable() && MMI->Verify(DI.getVariable())) {
+ SDOperand AddressOp = getValue(DI.getAddress());
+ if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(AddressOp))
+ MMI->RecordVariable(DI.getVariable(), FI->getIndex());
+ }
+
+ return 0;
+ }
+
+ case Intrinsic::eh_exception: {
+ MachineModuleInfo *MMI = DAG.getMachineModuleInfo();
+
+ if (MMI) {
+ // Add a label to mark the beginning of the landing pad. Deletion of the
+ // landing pad can thus be detected via the MachineModuleInfo.
+ unsigned LabelID = MMI->addLandingPad(CurMBB);
+ DAG.setRoot(DAG.getNode(ISD::LABEL, MVT::Other, DAG.getEntryNode(),
+ DAG.getConstant(LabelID, MVT::i32)));
+
+ // Mark exception register as live in.
+ unsigned Reg = TLI.getExceptionAddressRegister();
+ if (Reg) CurMBB->addLiveIn(Reg);
+
+ // Insert the EXCEPTIONADDR instruction.
+ SDVTList VTs = DAG.getVTList(TLI.getPointerTy(), MVT::Other);
+ SDOperand Ops[1];
+ Ops[0] = DAG.getRoot();
+ SDOperand Op = DAG.getNode(ISD::EXCEPTIONADDR, VTs, Ops, 1);
+ setValue(&I, Op);
+ DAG.setRoot(Op.getValue(1));
+ } else {
+ setValue(&I, DAG.getConstant(0, TLI.getPointerTy()));
+ }
return 0;
}
- case Intrinsic::dbg_declare: {
- MachineDebugInfo *DebugInfo = DAG.getMachineDebugInfo();
- DbgDeclareInst &DI = cast<DbgDeclareInst>(I);
- if (DebugInfo && DI.getVariable() && DebugInfo->Verify(DI.getVariable())) {
- SDOperand AddressOp = getValue(DI.getAddress());
- if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(AddressOp))
- DebugInfo->RecordVariable(DI.getVariable(), FI->getIndex());
- }
+ case Intrinsic::eh_selector:
+ case Intrinsic::eh_filter:{
+ MachineModuleInfo *MMI = DAG.getMachineModuleInfo();
+
+ if (MMI) {
+ // Inform the MachineModuleInfo of the personality for this landing pad.
+ ConstantExpr *CE = dyn_cast<ConstantExpr>(I.getOperand(2));
+ assert(CE && CE->getOpcode() == Instruction::BitCast &&
+ isa<Function>(CE->getOperand(0)) &&
+ "Personality should be a function");
+ MMI->addPersonality(CurMBB, cast<Function>(CE->getOperand(0)));
+ if (Intrinsic == Intrinsic::eh_filter)
+ MMI->setIsFilterLandingPad(CurMBB);
+
+ // Gather all the type infos for this landing pad and pass them along to
+ // MachineModuleInfo.
+ std::vector<GlobalVariable *> TyInfo;
+ for (unsigned i = 3, N = I.getNumOperands(); i < N; ++i) {
+ ConstantExpr *CE = dyn_cast<ConstantExpr>(I.getOperand(i));
+ if (CE && CE->getOpcode() == Instruction::BitCast &&
+ isa<GlobalVariable>(CE->getOperand(0))) {
+ TyInfo.push_back(cast<GlobalVariable>(CE->getOperand(0)));
+ } else {
+ ConstantInt *CI = dyn_cast<ConstantInt>(I.getOperand(i));
+ assert(CI && CI->getZExtValue() == 0 &&
+ "TypeInfo must be a global variable typeinfo or NULL");
+ TyInfo.push_back(NULL);
+ }
+ }
+ MMI->addCatchTypeInfo(CurMBB, TyInfo);
+
+ // Mark exception selector register as live in.
+ unsigned Reg = TLI.getExceptionSelectorRegister();
+ if (Reg) CurMBB->addLiveIn(Reg);
+
+ // Insert the EHSELECTION instruction.
+ SDVTList VTs = DAG.getVTList(MVT::i32, MVT::Other);
+ SDOperand Ops[2];
+ Ops[0] = getValue(I.getOperand(1));
+ Ops[1] = getRoot();
+ SDOperand Op = DAG.getNode(ISD::EHSELECTION, VTs, Ops, 2);
+ setValue(&I, Op);
+ DAG.setRoot(Op.getValue(1));
+ } else {
+ setValue(&I, DAG.getConstant(0, MVT::i32));
+ }
+
return 0;
}
+
+ case Intrinsic::eh_typeid_for: {
+ MachineModuleInfo *MMI = DAG.getMachineModuleInfo();
- case Intrinsic::isunordered_f32:
- case Intrinsic::isunordered_f64:
- setValue(&I, DAG.getSetCC(MVT::i1,getValue(I.getOperand(1)),
- getValue(I.getOperand(2)), ISD::SETUO));
+ if (MMI) {
+ // Find the type id for the given typeinfo.
+ GlobalVariable *GV = NULL;
+ ConstantExpr *CE = dyn_cast<ConstantExpr>(I.getOperand(1));
+ if (CE && CE->getOpcode() == Instruction::BitCast &&
+ isa<GlobalVariable>(CE->getOperand(0))) {
+ GV = cast<GlobalVariable>(CE->getOperand(0));
+ } else {
+ ConstantInt *CI = dyn_cast<ConstantInt>(I.getOperand(1));
+ assert(CI && CI->getZExtValue() == 0 &&
+ "TypeInfo must be a global variable typeinfo or NULL");
+ GV = NULL;
+ }
+
+ unsigned TypeID = MMI->getTypeIDFor(GV);
+ setValue(&I, DAG.getConstant(TypeID, MVT::i32));
+ } else {
+ setValue(&I, DAG.getConstant(0, MVT::i32));
+ }
+
return 0;
-
+ }
+
case Intrinsic::sqrt_f32:
case Intrinsic::sqrt_f64:
setValue(&I, DAG.getNode(ISD::FSQRT,
DAG.setRoot(Tmp.getValue(1));
return 0;
}
- case Intrinsic::bswap_i16:
- case Intrinsic::bswap_i32:
- case Intrinsic::bswap_i64:
+ case Intrinsic::part_select: {
+ // Currently not implemented: just abort
+ assert(0 && "bit_part_select intrinsic not implemented");
+ abort();
+ }
+ case Intrinsic::bswap:
setValue(&I, DAG.getNode(ISD::BSWAP,
getValue(I.getOperand(1)).getValueType(),
getValue(I.getOperand(1))));
return 0;
- case Intrinsic::cttz_i8:
- case Intrinsic::cttz_i16:
- case Intrinsic::cttz_i32:
- case Intrinsic::cttz_i64:
- setValue(&I, DAG.getNode(ISD::CTTZ,
- getValue(I.getOperand(1)).getValueType(),
- getValue(I.getOperand(1))));
+ case Intrinsic::cttz: {
+ SDOperand Arg = getValue(I.getOperand(1));
+ MVT::ValueType Ty = Arg.getValueType();
+ SDOperand result = DAG.getNode(ISD::CTTZ, Ty, Arg);
+ if (Ty < MVT::i32)
+ result = DAG.getNode(ISD::ZERO_EXTEND, MVT::i32, result);
+ else if (Ty > MVT::i32)
+ result = DAG.getNode(ISD::TRUNCATE, MVT::i32, result);
+ setValue(&I, result);
return 0;
- case Intrinsic::ctlz_i8:
- case Intrinsic::ctlz_i16:
- case Intrinsic::ctlz_i32:
- case Intrinsic::ctlz_i64:
- setValue(&I, DAG.getNode(ISD::CTLZ,
- getValue(I.getOperand(1)).getValueType(),
- getValue(I.getOperand(1))));
+ }
+ case Intrinsic::ctlz: {
+ SDOperand Arg = getValue(I.getOperand(1));
+ MVT::ValueType Ty = Arg.getValueType();
+ SDOperand result = DAG.getNode(ISD::CTLZ, Ty, Arg);
+ if (Ty < MVT::i32)
+ result = DAG.getNode(ISD::ZERO_EXTEND, MVT::i32, result);
+ else if (Ty > MVT::i32)
+ result = DAG.getNode(ISD::TRUNCATE, MVT::i32, result);
+ setValue(&I, result);
return 0;
- case Intrinsic::ctpop_i8:
- case Intrinsic::ctpop_i16:
- case Intrinsic::ctpop_i32:
- case Intrinsic::ctpop_i64:
- setValue(&I, DAG.getNode(ISD::CTPOP,
- getValue(I.getOperand(1)).getValueType(),
- getValue(I.getOperand(1))));
+ }
+ case Intrinsic::ctpop: {
+ SDOperand Arg = getValue(I.getOperand(1));
+ MVT::ValueType Ty = Arg.getValueType();
+ SDOperand result = DAG.getNode(ISD::CTPOP, Ty, Arg);
+ if (Ty < MVT::i32)
+ result = DAG.getNode(ISD::ZERO_EXTEND, MVT::i32, result);
+ else if (Ty > MVT::i32)
+ result = DAG.getNode(ISD::TRUNCATE, MVT::i32, result);
+ setValue(&I, result);
return 0;
+ }
case Intrinsic::stacksave: {
SDOperand Op = getRoot();
SDOperand Tmp = DAG.getNode(ISD::STACKSAVE,
}
+void SelectionDAGLowering::LowerCallTo(Instruction &I,
+ const Type *CalledValueTy,
+ unsigned CallingConv,
+ bool IsTailCall,
+ SDOperand Callee, unsigned OpIdx) {
+ const PointerType *PT = cast<PointerType>(CalledValueTy);
+ const FunctionType *FTy = cast<FunctionType>(PT->getElementType());
+ const ParamAttrsList *Attrs = FTy->getParamAttrs();
+
+ TargetLowering::ArgListTy Args;
+ TargetLowering::ArgListEntry Entry;
+ Args.reserve(I.getNumOperands());
+ for (unsigned i = OpIdx, e = I.getNumOperands(); i != e; ++i) {
+ Value *Arg = I.getOperand(i);
+ SDOperand ArgNode = getValue(Arg);
+ Entry.Node = ArgNode; Entry.Ty = Arg->getType();
+ Entry.isSExt = Attrs && Attrs->paramHasAttr(i, SExtAttribute);
+ Entry.isZExt = Attrs && Attrs->paramHasAttr(i, ZExtAttribute);
+ Entry.isInReg = Attrs && Attrs->paramHasAttr(i, InRegAttribute);
+ Entry.isSRet = Attrs && Attrs->paramHasAttr(i, StructRetAttribute);
+ Args.push_back(Entry);
+ }
+
+ std::pair<SDOperand,SDOperand> Result =
+ TLI.LowerCallTo(getRoot(), I.getType(),
+ Attrs && Attrs->paramHasAttr(0, SExtAttribute),
+ FTy->isVarArg(), CallingConv, IsTailCall,
+ Callee, Args, DAG);
+ if (I.getType() != Type::VoidTy)
+ setValue(&I, Result.first);
+ DAG.setRoot(Result.second);
+}
+
+
void SelectionDAGLowering::visitCall(CallInst &I) {
const char *RenameFn = 0;
if (Function *F = I.getCalledFunction()) {
- if (F->isExternal())
+ if (F->isDeclaration())
if (unsigned IID = F->getIntrinsicID()) {
RenameFn = visitIntrinsicCall(I, IID);
if (!RenameFn)
Callee = getValue(I.getOperand(0));
else
Callee = DAG.getExternalSymbol(RenameFn, TLI.getPointerTy());
- std::vector<std::pair<SDOperand, const Type*> > Args;
- Args.reserve(I.getNumOperands());
- for (unsigned i = 1, e = I.getNumOperands(); i != e; ++i) {
- Value *Arg = I.getOperand(i);
- SDOperand ArgNode = getValue(Arg);
- Args.push_back(std::make_pair(ArgNode, Arg->getType()));
- }
-
- const PointerType *PT = cast<PointerType>(I.getCalledValue()->getType());
- const FunctionType *FTy = cast<FunctionType>(PT->getElementType());
-
- std::pair<SDOperand,SDOperand> Result =
- TLI.LowerCallTo(getRoot(), I.getType(), FTy->isVarArg(), I.getCallingConv(),
- I.isTailCall(), Callee, Args, DAG);
- if (I.getType() != Type::VoidTy)
- setValue(&I, Result.first);
- DAG.setRoot(Result.second);
+
+ LowerCallTo(I, I.getCalledValue()->getType(),
+ I.getCallingConv(),
+ I.isTailCall(),
+ Callee,
+ 1);
}
+
SDOperand RegsForValue::getCopyFromRegs(SelectionDAG &DAG,
SDOperand &Chain, SDOperand &Flag)const{
SDOperand Val = DAG.getCopyFromReg(Chain, Regs[0], RegVT, Flag);
if (RegVT == ValueVT)
return Val;
+ if (MVT::isVector(RegVT)) {
+ assert(ValueVT == MVT::Vector && "Unknown vector conversion!");
+ return DAG.getNode(ISD::VBIT_CONVERT, MVT::Vector, Val,
+ DAG.getConstant(MVT::getVectorNumElements(RegVT),
+ MVT::i32),
+ DAG.getValueType(MVT::getVectorBaseType(RegVT)));
+ }
+
if (MVT::isInteger(RegVT)) {
if (ValueVT < RegVT)
return DAG.getNode(ISD::TRUNCATE, ValueVT, Val);
else
return DAG.getNode(ISD::ANY_EXTEND, ValueVT, Val);
- } else {
- return DAG.getNode(ISD::FP_ROUND, ValueVT, Val);
}
+
+ assert(MVT::isFloatingPoint(RegVT) && MVT::isFloatingPoint(ValueVT));
+ return DAG.getNode(ISD::FP_ROUND, ValueVT, Val);
}
/// getCopyToRegs - Emit a series of CopyToReg nodes that copies the
// If there is a single register and the types differ, this must be
// a promotion.
if (RegVT != ValueVT) {
- if (MVT::isInteger(RegVT)) {
+ if (MVT::isVector(RegVT)) {
+ assert(Val.getValueType() == MVT::Vector &&"Not a vector-vector cast?");
+ Val = DAG.getNode(ISD::VBIT_CONVERT, RegVT, Val);
+ } else if (MVT::isInteger(RegVT) && MVT::isInteger(Val.getValueType())) {
if (RegVT < ValueVT)
Val = DAG.getNode(ISD::TRUNCATE, RegVT, Val);
else
Val = DAG.getNode(ISD::ANY_EXTEND, RegVT, Val);
- } else
+ } else if (MVT::isFloatingPoint(RegVT) &&
+ MVT::isFloatingPoint(Val.getValueType())) {
Val = DAG.getNode(ISD::FP_EXTEND, RegVT, Val);
+ } else if (MVT::getSizeInBits(RegVT) ==
+ MVT::getSizeInBits(Val.getValueType())) {
+ Val = DAG.getNode(ISD::BIT_CONVERT, RegVT, Val);
+ } else {
+ assert(0 && "Unknown mismatch!");
+ }
}
Chain = DAG.getCopyToReg(Chain, Regs[0], Val, Flag);
Flag = Chain.getValue(1);
/// values added into it.
void RegsForValue::AddInlineAsmOperands(unsigned Code, SelectionDAG &DAG,
std::vector<SDOperand> &Ops) const {
- Ops.push_back(DAG.getConstant(Code | (Regs.size() << 3), MVT::i32));
+ MVT::ValueType IntPtrTy = DAG.getTargetLoweringInfo().getPointerTy();
+ Ops.push_back(DAG.getTargetConstant(Code | (Regs.size() << 3), IntPtrTy));
for (unsigned i = 0, e = Regs.size(); i != e; ++i)
Ops.push_back(DAG.getRegister(Regs[i], RegVT));
}
// Okay, this register is good, we can use it.
++NumAllocated;
- // If we allocated enough consecutive
+ // If we allocated enough consecutive registers, succeed.
if (NumAllocated == NumRegs) {
unsigned RegStart = (i-NumAllocated)+1;
unsigned RegEnd = i+1;
return RegsForValue();
}
+/// getConstraintGenerality - Return an integer indicating how general CT is.
+static unsigned getConstraintGenerality(TargetLowering::ConstraintType CT) {
+ switch (CT) {
+ default: assert(0 && "Unknown constraint type!");
+ case TargetLowering::C_Other:
+ case TargetLowering::C_Unknown:
+ return 0;
+ case TargetLowering::C_Register:
+ return 1;
+ case TargetLowering::C_RegisterClass:
+ return 2;
+ case TargetLowering::C_Memory:
+ return 3;
+ }
+}
+
+static std::string GetMostGeneralConstraint(std::vector<std::string> &C,
+ const TargetLowering &TLI) {
+ assert(!C.empty() && "Must have at least one constraint");
+ if (C.size() == 1) return C[0];
+
+ std::string *Current = &C[0];
+ // If we have multiple constraints, try to pick the most general one ahead
+ // of time. This isn't a wonderful solution, but handles common cases.
+ TargetLowering::ConstraintType Flavor = TLI.getConstraintType(Current[0]);
+ for (unsigned j = 1, e = C.size(); j != e; ++j) {
+ TargetLowering::ConstraintType ThisFlavor = TLI.getConstraintType(C[j]);
+ if (getConstraintGenerality(ThisFlavor) >
+ getConstraintGenerality(Flavor)) {
+ // This constraint letter is more general than the previous one,
+ // use it.
+ Flavor = ThisFlavor;
+ Current = &C[j];
+ }
+ }
+ return *Current;
+}
+
/// visitInlineAsm - Handle a call to an InlineAsm object.
///
std::set<unsigned> OutputRegs, InputRegs;
unsigned OpNum = 1;
for (unsigned i = 0, e = Constraints.size(); i != e; ++i) {
- assert(Constraints[i].Codes.size() == 1 && "Only handles one code so far!");
- std::string &ConstraintCode = Constraints[i].Codes[0];
+ std::string ConstraintCode =
+ GetMostGeneralConstraint(Constraints[i].Codes, TLI);
MVT::ValueType OpVT;
OpNum = 1;
for (unsigned i = 0, e = Constraints.size(); i != e; ++i) {
- assert(Constraints[i].Codes.size() == 1 && "Only handles one code so far!");
- std::string &ConstraintCode = Constraints[i].Codes[0];
+ std::string ConstraintCode =
+ GetMostGeneralConstraint(Constraints[i].Codes, TLI);
switch (Constraints[i].Type) {
case InlineAsm::isOutput: {
TargetLowering::ConstraintType CTy = TargetLowering::C_RegisterClass;
if (ConstraintCode.size() == 1) // not a physreg name.
- CTy = TLI.getConstraintType(ConstraintCode[0]);
+ CTy = TLI.getConstraintType(ConstraintCode);
if (CTy == TargetLowering::C_Memory) {
// Memory output.
unsigned NumOps =
cast<ConstantSDNode>(AsmNodeOperands[CurOp])->getValue();
- assert((NumOps & 7) == 2 /*REGDEF*/ &&
- "Skipped past definitions?");
+ if ((NumOps & 7) == 2 /*REGDEF*/) {
+ // Add NumOps>>3 registers to MatchedRegs.
+ RegsForValue MatchedRegs;
+ MatchedRegs.ValueVT = InOperandVal.getValueType();
+ MatchedRegs.RegVT = AsmNodeOperands[CurOp+1].getValueType();
+ for (unsigned i = 0, e = NumOps>>3; i != e; ++i) {
+ unsigned Reg =
+ cast<RegisterSDNode>(AsmNodeOperands[++CurOp])->getReg();
+ MatchedRegs.Regs.push_back(Reg);
+ }
- // Add NumOps>>3 registers to MatchedRegs.
- RegsForValue MatchedRegs;
- MatchedRegs.ValueVT = InOperandVal.getValueType();
- MatchedRegs.RegVT = AsmNodeOperands[CurOp+1].getValueType();
- for (unsigned i = 0, e = NumOps>>3; i != e; ++i) {
- unsigned Reg=cast<RegisterSDNode>(AsmNodeOperands[++CurOp])->getReg();
- MatchedRegs.Regs.push_back(Reg);
+ // Use the produced MatchedRegs object to
+ MatchedRegs.getCopyToRegs(InOperandVal, DAG, Chain, Flag,
+ TLI.getPointerTy());
+ MatchedRegs.AddInlineAsmOperands(1 /*REGUSE*/, DAG, AsmNodeOperands);
+ break;
+ } else {
+ assert((NumOps & 7) == 4/*MEM*/ && "Unknown matching constraint!");
+ assert(0 && "matching constraints for memory operands unimp");
}
-
- // Use the produced MatchedRegs object to
- MatchedRegs.getCopyToRegs(InOperandVal, DAG, Chain, Flag,
- TLI.getPointerTy());
- MatchedRegs.AddInlineAsmOperands(1 /*REGUSE*/, DAG, AsmNodeOperands);
- break;
}
TargetLowering::ConstraintType CTy = TargetLowering::C_RegisterClass;
if (ConstraintCode.size() == 1) // not a physreg name.
- CTy = TLI.getConstraintType(ConstraintCode[0]);
+ CTy = TLI.getConstraintType(ConstraintCode);
if (CTy == TargetLowering::C_Other) {
InOperandVal = TLI.isOperandValidForConstraint(InOperandVal,
} else if (CTy == TargetLowering::C_Memory) {
// Memory input.
- // Check that the operand isn't a float.
- if (!MVT::isInteger(InOperandVal.getValueType()))
- assert(0 && "MATCH FAIL!");
+ // If the operand is a float, spill to a constant pool entry to get its
+ // address.
+ if (ConstantFP *Val = dyn_cast<ConstantFP>(I.getOperand(OpNum-1)))
+ InOperandVal = DAG.getConstantPool(Val, TLI.getPointerTy());
+
+ if (!MVT::isInteger(InOperandVal.getValueType())) {
+ cerr << "Match failed, cannot handle this yet!\n";
+ InOperandVal.Val->dump();
+ exit(1);
+ }
// Extend/truncate to the right pointer type if needed.
MVT::ValueType PtrType = TLI.getPointerTy();
Src = DAG.getNode(ISD::MUL, Src.getValueType(),
Src, getIntPtrConstant(ElementSize));
- std::vector<std::pair<SDOperand, const Type*> > Args;
- Args.push_back(std::make_pair(Src, TLI.getTargetData()->getIntPtrType()));
+ TargetLowering::ArgListTy Args;
+ TargetLowering::ArgListEntry Entry;
+ Entry.Node = Src;
+ Entry.Ty = TLI.getTargetData()->getIntPtrType();
+ Args.push_back(Entry);
std::pair<SDOperand,SDOperand> Result =
- TLI.LowerCallTo(getRoot(), I.getType(), false, CallingConv::C, true,
+ TLI.LowerCallTo(getRoot(), I.getType(), false, false, CallingConv::C, true,
DAG.getExternalSymbol("malloc", IntPtr),
Args, DAG);
setValue(&I, Result.first); // Pointers always fit in registers
}
void SelectionDAGLowering::visitFree(FreeInst &I) {
- std::vector<std::pair<SDOperand, const Type*> > Args;
- Args.push_back(std::make_pair(getValue(I.getOperand(0)),
- TLI.getTargetData()->getIntPtrType()));
+ TargetLowering::ArgListTy Args;
+ TargetLowering::ArgListEntry Entry;
+ Entry.Node = getValue(I.getOperand(0));
+ Entry.Ty = TLI.getTargetData()->getIntPtrType();
+ Args.push_back(Entry);
MVT::ValueType IntPtr = TLI.getPointerTy();
std::pair<SDOperand,SDOperand> Result =
- TLI.LowerCallTo(getRoot(), Type::VoidTy, false, CallingConv::C, true,
+ TLI.LowerCallTo(getRoot(), Type::VoidTy, false, false, CallingConv::C, true,
DAG.getExternalSymbol("free", IntPtr), Args, DAG);
DAG.setRoot(Result.second);
}
/// integrated into SDISel.
std::vector<SDOperand>
TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
+ const FunctionType *FTy = F.getFunctionType();
+ const ParamAttrsList *Attrs = FTy->getParamAttrs();
// Add CC# and isVararg as operands to the FORMAL_ARGUMENTS node.
std::vector<SDOperand> Ops;
Ops.push_back(DAG.getRoot());
// Add one result value for each formal argument.
std::vector<MVT::ValueType> RetVals;
- for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I) {
+ unsigned j = 1;
+ for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end();
+ I != E; ++I, ++j) {
MVT::ValueType VT = getValueType(I->getType());
+ unsigned Flags = ISD::ParamFlags::NoFlagSet;
+ unsigned OriginalAlignment =
+ getTargetData()->getABITypeAlignment(I->getType());
+
+ // FIXME: Distinguish between a formal with no [sz]ext attribute from one
+ // that is zero extended!
+ if (Attrs && Attrs->paramHasAttr(j, ZExtAttribute))
+ Flags &= ~(ISD::ParamFlags::SExt);
+ if (Attrs && Attrs->paramHasAttr(j, SExtAttribute))
+ Flags |= ISD::ParamFlags::SExt;
+ if (Attrs && Attrs->paramHasAttr(j, InRegAttribute))
+ Flags |= ISD::ParamFlags::InReg;
+ if (Attrs && Attrs->paramHasAttr(j, StructRetAttribute))
+ Flags |= ISD::ParamFlags::StructReturn;
+ Flags |= (OriginalAlignment << ISD::ParamFlags::OrigAlignmentOffs);
switch (getTypeAction(VT)) {
default: assert(0 && "Unknown type action!");
case Legal:
RetVals.push_back(VT);
+ Ops.push_back(DAG.getConstant(Flags, MVT::i32));
break;
case Promote:
RetVals.push_back(getTypeToTransformTo(VT));
+ Ops.push_back(DAG.getConstant(Flags, MVT::i32));
break;
case Expand:
if (VT != MVT::Vector) {
// If this is a large integer, it needs to be broken up into small
// integers. Figure out what the destination type is and how many small
// integers it turns into.
- MVT::ValueType NVT = VT;
- unsigned NumVals = 1;
- while (getTypeAction(NVT) == Expand) {
- NVT = getTypeToTransformTo(NVT);
- NumVals *= MVT::getSizeInBits(VT)/MVT::getSizeInBits(NVT);
- }
- for (unsigned i = 0; i != NumVals; ++i)
+ MVT::ValueType NVT = getTypeToExpandTo(VT);
+ unsigned NumVals = getNumElements(VT);
+ for (unsigned i = 0; i != NumVals; ++i) {
RetVals.push_back(NVT);
+ // if it isn't first piece, alignment must be 1
+ if (i > 0)
+ Flags = (Flags & (~ISD::ParamFlags::OrigAlignment)) |
+ (1 << ISD::ParamFlags::OrigAlignmentOffs);
+ Ops.push_back(DAG.getConstant(Flags, MVT::i32));
+ }
} else {
// Otherwise, this is a vector type. We only support legal vectors
// right now.
- unsigned NumElems = cast<PackedType>(I->getType())->getNumElements();
- const Type *EltTy = cast<PackedType>(I->getType())->getElementType();
+ unsigned NumElems = cast<VectorType>(I->getType())->getNumElements();
+ const Type *EltTy = cast<VectorType>(I->getType())->getElementType();
// Figure out if there is a Packed type corresponding to this Vector
- // type. If so, convert to the packed type.
+ // type. If so, convert to the vector type.
MVT::ValueType TVT = MVT::getVectorType(getValueType(EltTy), NumElems);
if (TVT != MVT::Other && isTypeLegal(TVT)) {
RetVals.push_back(TVT);
+ Ops.push_back(DAG.getConstant(Flags, MVT::i32));
} else {
assert(0 && "Don't support illegal by-val vector arguments yet!");
}
// Set up the return result vector.
Ops.clear();
unsigned i = 0;
- for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I) {
+ unsigned Idx = 1;
+ for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E;
+ ++I, ++Idx) {
MVT::ValueType VT = getValueType(I->getType());
switch (getTypeAction(VT)) {
case Promote: {
SDOperand Op(Result, i++);
if (MVT::isInteger(VT)) {
- unsigned AssertOp = I->getType()->isSigned() ? ISD::AssertSext
- : ISD::AssertZext;
- Op = DAG.getNode(AssertOp, Op.getValueType(), Op, DAG.getValueType(VT));
+ if (Attrs && Attrs->paramHasAttr(Idx, SExtAttribute))
+ Op = DAG.getNode(ISD::AssertSext, Op.getValueType(), Op,
+ DAG.getValueType(VT));
+ else if (Attrs && Attrs->paramHasAttr(Idx, ZExtAttribute))
+ Op = DAG.getNode(ISD::AssertZext, Op.getValueType(), Op,
+ DAG.getValueType(VT));
Op = DAG.getNode(ISD::TRUNCATE, VT, Op);
} else {
assert(MVT::isFloatingPoint(VT) && "Not int or FP?");
} else {
// Otherwise, this is a vector type. We only support legal vectors
// right now.
- const PackedType *PTy = cast<PackedType>(I->getType());
+ const VectorType *PTy = cast<VectorType>(I->getType());
unsigned NumElems = PTy->getNumElements();
const Type *EltTy = PTy->getElementType();
// Figure out if there is a Packed type corresponding to this Vector
- // type. If so, convert to the packed type.
+ // type. If so, convert to the vector type.
MVT::ValueType TVT = MVT::getVectorType(getValueType(EltTy), NumElems);
if (TVT != MVT::Other && isTypeLegal(TVT)) {
SDOperand N = SDOperand(Result, i++);
/// ExpandScalarCallArgs - Recursively expand call argument node by
/// bit_converting it or extract a pair of elements from the larger node.
static void ExpandScalarCallArgs(MVT::ValueType VT, SDOperand Arg,
- bool isSigned,
+ unsigned Flags,
SmallVector<SDOperand, 32> &Ops,
SelectionDAG &DAG,
- TargetLowering &TLI) {
+ TargetLowering &TLI,
+ bool isFirst = true) {
+
if (TLI.getTypeAction(VT) != TargetLowering::Expand) {
+ // if it isn't first piece, alignment must be 1
+ if (!isFirst)
+ Flags = (Flags & (~ISD::ParamFlags::OrigAlignment)) |
+ (1 << ISD::ParamFlags::OrigAlignmentOffs);
Ops.push_back(Arg);
- Ops.push_back(DAG.getConstant(isSigned, MVT::i32));
+ Ops.push_back(DAG.getConstant(Flags, MVT::i32));
return;
}
unsigned NumVals = MVT::getSizeInBits(VT) / MVT::getSizeInBits(EVT);
if (NumVals == 1) {
Arg = DAG.getNode(ISD::BIT_CONVERT, EVT, Arg);
- ExpandScalarCallArgs(EVT, Arg, isSigned, Ops, DAG, TLI);
+ ExpandScalarCallArgs(EVT, Arg, Flags, Ops, DAG, TLI, isFirst);
} else if (NumVals == 2) {
SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, EVT, Arg,
DAG.getConstant(0, TLI.getPointerTy()));
DAG.getConstant(1, TLI.getPointerTy()));
if (!TLI.isLittleEndian())
std::swap(Lo, Hi);
- ExpandScalarCallArgs(EVT, Lo, isSigned, Ops, DAG, TLI);
- ExpandScalarCallArgs(EVT, Hi, isSigned, Ops, DAG, TLI);
+ ExpandScalarCallArgs(EVT, Lo, Flags, Ops, DAG, TLI, isFirst);
+ ExpandScalarCallArgs(EVT, Hi, Flags, Ops, DAG, TLI, false);
} else {
// Value scalarized into many values. Unimp for now.
assert(0 && "Cannot expand i64 -> i16 yet!");
/// lowered by the target to something concrete. FIXME: When all targets are
/// migrated to using ISD::CALL, this hook should be integrated into SDISel.
std::pair<SDOperand, SDOperand>
-TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy, bool isVarArg,
+TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
+ bool RetTyIsSigned, bool isVarArg,
unsigned CallingConv, bool isTailCall,
SDOperand Callee,
ArgListTy &Args, SelectionDAG &DAG) {
// Handle all of the outgoing arguments.
for (unsigned i = 0, e = Args.size(); i != e; ++i) {
- MVT::ValueType VT = getValueType(Args[i].second);
- SDOperand Op = Args[i].first;
- bool isSigned = Args[i].second->isSigned();
+ MVT::ValueType VT = getValueType(Args[i].Ty);
+ SDOperand Op = Args[i].Node;
+ unsigned Flags = ISD::ParamFlags::NoFlagSet;
+ unsigned OriginalAlignment =
+ getTargetData()->getABITypeAlignment(Args[i].Ty);
+
+ if (Args[i].isSExt)
+ Flags |= ISD::ParamFlags::SExt;
+ if (Args[i].isZExt)
+ Flags |= ISD::ParamFlags::ZExt;
+ if (Args[i].isInReg)
+ Flags |= ISD::ParamFlags::InReg;
+ if (Args[i].isSRet)
+ Flags |= ISD::ParamFlags::StructReturn;
+ Flags |= OriginalAlignment << ISD::ParamFlags::OrigAlignmentOffs;
+
switch (getTypeAction(VT)) {
default: assert(0 && "Unknown type action!");
- case Legal:
+ case Legal:
Ops.push_back(Op);
- Ops.push_back(DAG.getConstant(isSigned, MVT::i32));
+ Ops.push_back(DAG.getConstant(Flags, MVT::i32));
break;
case Promote:
if (MVT::isInteger(VT)) {
- unsigned ExtOp = isSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND;
+ unsigned ExtOp;
+ if (Args[i].isSExt)
+ ExtOp = ISD::SIGN_EXTEND;
+ else if (Args[i].isZExt)
+ ExtOp = ISD::ZERO_EXTEND;
+ else
+ ExtOp = ISD::ANY_EXTEND;
Op = DAG.getNode(ExtOp, getTypeToTransformTo(VT), Op);
} else {
assert(MVT::isFloatingPoint(VT) && "Not int or FP?");
Op = DAG.getNode(ISD::FP_EXTEND, getTypeToTransformTo(VT), Op);
}
Ops.push_back(Op);
- Ops.push_back(DAG.getConstant(isSigned, MVT::i32));
+ Ops.push_back(DAG.getConstant(Flags, MVT::i32));
break;
case Expand:
if (VT != MVT::Vector) {
// If this is a large integer, it needs to be broken down into small
// integers. Figure out what the source elt type is and how many small
// integers it is.
- ExpandScalarCallArgs(VT, Op, isSigned, Ops, DAG, *this);
+ ExpandScalarCallArgs(VT, Op, Flags, Ops, DAG, *this);
} else {
// Otherwise, this is a vector type. We only support legal vectors
// right now.
- const PackedType *PTy = cast<PackedType>(Args[i].second);
+ const VectorType *PTy = cast<VectorType>(Args[i].Ty);
unsigned NumElems = PTy->getNumElements();
const Type *EltTy = PTy->getElementType();
// Figure out if there is a Packed type corresponding to this Vector
- // type. If so, convert to the packed type.
+ // type. If so, convert to the vector type.
MVT::ValueType TVT = MVT::getVectorType(getValueType(EltTy), NumElems);
if (TVT != MVT::Other && isTypeLegal(TVT)) {
- // Insert a VBIT_CONVERT of the MVT::Vector type to the packed type.
+ // Insert a VBIT_CONVERT of the MVT::Vector type to the vector type.
Op = DAG.getNode(ISD::VBIT_CONVERT, TVT, Op);
Ops.push_back(Op);
- Ops.push_back(DAG.getConstant(isSigned, MVT::i32));
+ Ops.push_back(DAG.getConstant(Flags, MVT::i32));
} else {
assert(0 && "Don't support illegal by-val vector call args yet!");
abort();
// If this is a large integer, it needs to be reassembled from small
// integers. Figure out what the source elt type is and how many small
// integers it is.
- MVT::ValueType NVT = VT;
- unsigned NumVals = 1;
- while (getTypeAction(NVT) == Expand) {
- NVT = getTypeToTransformTo(NVT);
- NumVals *= MVT::getSizeInBits(VT)/MVT::getSizeInBits(NVT);
- }
+ MVT::ValueType NVT = getTypeToExpandTo(VT);
+ unsigned NumVals = getNumElements(VT);
for (unsigned i = 0; i != NumVals; ++i)
RetTys.push_back(NVT);
} else {
// Otherwise, this is a vector type. We only support legal vectors
// right now.
- const PackedType *PTy = cast<PackedType>(RetTy);
+ const VectorType *PTy = cast<VectorType>(RetTy);
unsigned NumElems = PTy->getNumElements();
const Type *EltTy = PTy->getElementType();
// Figure out if there is a Packed type corresponding to this Vector
- // type. If so, convert to the packed type.
+ // type. If so, convert to the vector type.
MVT::ValueType TVT = MVT::getVectorType(getValueType(EltTy), NumElems);
if (TVT != MVT::Other && isTypeLegal(TVT)) {
RetTys.push_back(TVT);
// If this value was promoted, truncate it down.
if (ResVal.getValueType() != VT) {
if (VT == MVT::Vector) {
- // Insert a VBITCONVERT to convert from the packed result type to the
+ // Insert a VBIT_CONVERT to convert from the packed result type to the
// MVT::Vector type.
- unsigned NumElems = cast<PackedType>(RetTy)->getNumElements();
- const Type *EltTy = cast<PackedType>(RetTy)->getElementType();
+ unsigned NumElems = cast<VectorType>(RetTy)->getNumElements();
+ const Type *EltTy = cast<VectorType>(RetTy)->getElementType();
// Figure out if there is a Packed type corresponding to this Vector
- // type. If so, convert to the packed type.
- MVT::ValueType TVT = MVT::getVectorType(getValueType(EltTy), NumElems);
+ // type. If so, convert to the vector type.
+ MVT::ValueType TVT = MVT::getVectorType(getValueType(EltTy),NumElems);
if (TVT != MVT::Other && isTypeLegal(TVT)) {
// Insert a VBIT_CONVERT of the FORMAL_ARGUMENTS to a
// "N x PTyElementVT" MVT::Vector type.
abort();
}
} else if (MVT::isInteger(VT)) {
- unsigned AssertOp = RetTy->isSigned() ?
- ISD::AssertSext : ISD::AssertZext;
+ unsigned AssertOp = ISD::AssertSext;
+ if (!RetTyIsSigned)
+ AssertOp = ISD::AssertZext;
ResVal = DAG.getNode(AssertOp, ResVal.getValueType(), ResVal,
DAG.getValueType(VT));
ResVal = DAG.getNode(ISD::TRUNCATE, VT, ResVal);
return std::make_pair(ResVal, Res.getValue(Res.Val->getNumValues()-1));
}
-
-
-// It is always conservatively correct for llvm.returnaddress and
-// llvm.frameaddress to return 0.
-//
-// FIXME: Change this to insert a FRAMEADDR/RETURNADDR node, and have that be
-// expanded to 0 if the target wants.
-std::pair<SDOperand, SDOperand>
-TargetLowering::LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain,
- unsigned Depth, SelectionDAG &DAG) {
- return std::make_pair(DAG.getConstant(0, getPointerTy()), Chain);
-}
-
SDOperand TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
assert(0 && "LowerOperation not implemented for this target!");
abort();
return SDOperand();
}
-void SelectionDAGLowering::visitFrameReturnAddress(CallInst &I, bool isFrame) {
- unsigned Depth = (unsigned)cast<ConstantInt>(I.getOperand(1))->getZExtValue();
- std::pair<SDOperand,SDOperand> Result =
- TLI.LowerFrameReturnAddress(isFrame, getRoot(), Depth, DAG);
- setValue(&I, Result.first);
- DAG.setRoot(Result.second);
-}
-
/// getMemsetValue - Vectorized representation of the memset value
/// operand.
static SDOperand getMemsetValue(SDOperand Value, MVT::ValueType VT,
}
void SelectionDAGISel::getAnalysisUsage(AnalysisUsage &AU) const {
- // FIXME: we only modify the CFG to split critical edges. This
- // updates dom and loop info.
AU.addRequired<AliasAnalysis>();
+ AU.setPreservesAll();
}
-/// OptimizeNoopCopyExpression - We have determined that the specified cast
-/// instruction is a noop copy (e.g. it's casting from one pointer type to
-/// another, int->uint, or int->sbyte on PPC.
-///
-/// Return true if any changes are made.
-static bool OptimizeNoopCopyExpression(CastInst *CI) {
- BasicBlock *DefBB = CI->getParent();
-
- /// InsertedCasts - Only insert a cast in each block once.
- std::map<BasicBlock*, CastInst*> InsertedCasts;
-
- bool MadeChange = false;
- for (Value::use_iterator UI = CI->use_begin(), E = CI->use_end();
- UI != E; ) {
- Use &TheUse = UI.getUse();
- Instruction *User = cast<Instruction>(*UI);
-
- // Figure out which BB this cast is used in. For PHI's this is the
- // appropriate predecessor block.
- BasicBlock *UserBB = User->getParent();
- if (PHINode *PN = dyn_cast<PHINode>(User)) {
- unsigned OpVal = UI.getOperandNo()/2;
- UserBB = PN->getIncomingBlock(OpVal);
- }
-
- // Preincrement use iterator so we don't invalidate it.
- ++UI;
-
- // If this user is in the same block as the cast, don't change the cast.
- if (UserBB == DefBB) continue;
-
- // If we have already inserted a cast into this block, use it.
- CastInst *&InsertedCast = InsertedCasts[UserBB];
-
- if (!InsertedCast) {
- BasicBlock::iterator InsertPt = UserBB->begin();
- while (isa<PHINode>(InsertPt)) ++InsertPt;
-
- InsertedCast =
- CastInst::createInferredCast(CI->getOperand(0), CI->getType(), "",
- InsertPt);
- MadeChange = true;
- }
-
- // Replace a use of the cast with a use of the new casat.
- TheUse = InsertedCast;
- }
-
- // If we removed all uses, nuke the cast.
- if (CI->use_empty())
- CI->eraseFromParent();
-
- return MadeChange;
-}
-
-/// InsertGEPComputeCode - Insert code into BB to compute Ptr+PtrOffset,
-/// casting to the type of GEPI.
-static Instruction *InsertGEPComputeCode(Instruction *&V, BasicBlock *BB,
- Instruction *GEPI, Value *Ptr,
- Value *PtrOffset) {
- if (V) return V; // Already computed.
-
- // Figure out the insertion point
- BasicBlock::iterator InsertPt;
- if (BB == GEPI->getParent()) {
- // If GEP is already inserted into BB, insert right after the GEP.
- InsertPt = GEPI;
- ++InsertPt;
- } else {
- // Otherwise, insert at the top of BB, after any PHI nodes
- InsertPt = BB->begin();
- while (isa<PHINode>(InsertPt)) ++InsertPt;
- }
-
- // If Ptr is itself a cast, but in some other BB, emit a copy of the cast into
- // BB so that there is only one value live across basic blocks (the cast
- // operand).
- if (CastInst *CI = dyn_cast<CastInst>(Ptr))
- if (CI->getParent() != BB && isa<PointerType>(CI->getOperand(0)->getType()))
- Ptr = CastInst::createInferredCast(CI->getOperand(0), CI->getType(), "",
- InsertPt);
-
- // Add the offset, cast it to the right type.
- Ptr = BinaryOperator::createAdd(Ptr, PtrOffset, "", InsertPt);
- // Ptr is an integer type, GEPI is pointer type ==> IntToPtr
- return V = CastInst::create(Instruction::IntToPtr, Ptr, GEPI->getType(),
- "", InsertPt);
-}
-
-/// ReplaceUsesOfGEPInst - Replace all uses of RepPtr with inserted code to
-/// compute its value. The RepPtr value can be computed with Ptr+PtrOffset. One
-/// trivial way of doing this would be to evaluate Ptr+PtrOffset in RepPtr's
-/// block, then ReplaceAllUsesWith'ing everything. However, we would prefer to
-/// sink PtrOffset into user blocks where doing so will likely allow us to fold
-/// the constant add into a load or store instruction. Additionally, if a user
-/// is a pointer-pointer cast, we look through it to find its users.
-static void ReplaceUsesOfGEPInst(Instruction *RepPtr, Value *Ptr,
- Constant *PtrOffset, BasicBlock *DefBB,
- GetElementPtrInst *GEPI,
- std::map<BasicBlock*,Instruction*> &InsertedExprs) {
- while (!RepPtr->use_empty()) {
- Instruction *User = cast<Instruction>(RepPtr->use_back());
-
- // If the user is a Pointer-Pointer cast, recurse. Only BitCast can be
- // used for a Pointer-Pointer cast.
- if (isa<BitCastInst>(User)) {
- ReplaceUsesOfGEPInst(User, Ptr, PtrOffset, DefBB, GEPI, InsertedExprs);
-
- // Drop the use of RepPtr. The cast is dead. Don't delete it now, else we
- // could invalidate an iterator.
- User->setOperand(0, UndefValue::get(RepPtr->getType()));
- continue;
- }
-
- // If this is a load of the pointer, or a store through the pointer, emit
- // the increment into the load/store block.
- Instruction *NewVal;
- if (isa<LoadInst>(User) ||
- (isa<StoreInst>(User) && User->getOperand(0) != RepPtr)) {
- NewVal = InsertGEPComputeCode(InsertedExprs[User->getParent()],
- User->getParent(), GEPI,
- Ptr, PtrOffset);
- } else {
- // If this use is not foldable into the addressing mode, use a version
- // emitted in the GEP block.
- NewVal = InsertGEPComputeCode(InsertedExprs[DefBB], DefBB, GEPI,
- Ptr, PtrOffset);
- }
-
- if (GEPI->getType() != RepPtr->getType()) {
- BasicBlock::iterator IP = NewVal;
- ++IP;
- // NewVal must be a GEP which must be pointer type, so BitCast
- NewVal = new BitCastInst(NewVal, RepPtr->getType(), "", IP);
- }
- User->replaceUsesOfWith(RepPtr, NewVal);
- }
-}
-
-
-/// OptimizeGEPExpression - Since we are doing basic-block-at-a-time instruction
-/// selection, we want to be a bit careful about some things. In particular, if
-/// we have a GEP instruction that is used in a different block than it is
-/// defined, the addressing expression of the GEP cannot be folded into loads or
-/// stores that use it. In this case, decompose the GEP and move constant
-/// indices into blocks that use it.
-static bool OptimizeGEPExpression(GetElementPtrInst *GEPI,
- const TargetData *TD) {
- // If this GEP is only used inside the block it is defined in, there is no
- // need to rewrite it.
- bool isUsedOutsideDefBB = false;
- BasicBlock *DefBB = GEPI->getParent();
- for (Value::use_iterator UI = GEPI->use_begin(), E = GEPI->use_end();
- UI != E; ++UI) {
- if (cast<Instruction>(*UI)->getParent() != DefBB) {
- isUsedOutsideDefBB = true;
- break;
- }
- }
- if (!isUsedOutsideDefBB) return false;
-
- // If this GEP has no non-zero constant indices, there is nothing we can do,
- // ignore it.
- bool hasConstantIndex = false;
- bool hasVariableIndex = false;
- for (GetElementPtrInst::op_iterator OI = GEPI->op_begin()+1,
- E = GEPI->op_end(); OI != E; ++OI) {
- if (ConstantInt *CI = dyn_cast<ConstantInt>(*OI)) {
- if (CI->getZExtValue()) {
- hasConstantIndex = true;
- break;
- }
- } else {
- hasVariableIndex = true;
- }
- }
-
- // If this is a "GEP X, 0, 0, 0", turn this into a cast.
- if (!hasConstantIndex && !hasVariableIndex) {
- /// The GEP operand must be a pointer, so must its result -> BitCast
- Value *NC = new BitCastInst(GEPI->getOperand(0), GEPI->getType(),
- GEPI->getName(), GEPI);
- GEPI->replaceAllUsesWith(NC);
- GEPI->eraseFromParent();
- return true;
- }
-
- // If this is a GEP &Alloca, 0, 0, forward subst the frame index into uses.
- if (!hasConstantIndex && !isa<AllocaInst>(GEPI->getOperand(0)))
- return false;
-
- // Otherwise, decompose the GEP instruction into multiplies and adds. Sum the
- // constant offset (which we now know is non-zero) and deal with it later.
- uint64_t ConstantOffset = 0;
- const Type *UIntPtrTy = TD->getIntPtrType();
- Value *Ptr = new PtrToIntInst(GEPI->getOperand(0), UIntPtrTy, "", GEPI);
- const Type *Ty = GEPI->getOperand(0)->getType();
-
- for (GetElementPtrInst::op_iterator OI = GEPI->op_begin()+1,
- E = GEPI->op_end(); OI != E; ++OI) {
- Value *Idx = *OI;
- if (const StructType *StTy = dyn_cast<StructType>(Ty)) {
- unsigned Field = cast<ConstantInt>(Idx)->getZExtValue();
- if (Field)
- ConstantOffset += TD->getStructLayout(StTy)->MemberOffsets[Field];
- Ty = StTy->getElementType(Field);
- } else {
- Ty = cast<SequentialType>(Ty)->getElementType();
-
- // Handle constant subscripts.
- if (ConstantInt *CI = dyn_cast<ConstantInt>(Idx)) {
- if (CI->getZExtValue() == 0) continue;
- if (CI->getType()->isSigned())
- ConstantOffset += (int64_t)TD->getTypeSize(Ty)*CI->getSExtValue();
- else
- ConstantOffset += TD->getTypeSize(Ty)*CI->getZExtValue();
- continue;
- }
-
- // Ptr = Ptr + Idx * ElementSize;
-
- // Cast Idx to UIntPtrTy if needed.
- Idx = CastInst::createInferredCast(Idx, UIntPtrTy, "", GEPI);
-
- uint64_t ElementSize = TD->getTypeSize(Ty);
- // Mask off bits that should not be set.
- ElementSize &= ~0ULL >> (64-UIntPtrTy->getPrimitiveSizeInBits());
- Constant *SizeCst = ConstantInt::get(UIntPtrTy, ElementSize);
-
- // Multiply by the element size and add to the base.
- Idx = BinaryOperator::createMul(Idx, SizeCst, "", GEPI);
- Ptr = BinaryOperator::createAdd(Ptr, Idx, "", GEPI);
- }
- }
-
- // Make sure that the offset fits in uintptr_t.
- ConstantOffset &= ~0ULL >> (64-UIntPtrTy->getPrimitiveSizeInBits());
- Constant *PtrOffset = ConstantInt::get(UIntPtrTy, ConstantOffset);
-
- // Okay, we have now emitted all of the variable index parts to the BB that
- // the GEP is defined in. Loop over all of the using instructions, inserting
- // an "add Ptr, ConstantOffset" into each block that uses it and update the
- // instruction to use the newly computed value, making GEPI dead. When the
- // user is a load or store instruction address, we emit the add into the user
- // block, otherwise we use a canonical version right next to the gep (these
- // won't be foldable as addresses, so we might as well share the computation).
-
- std::map<BasicBlock*,Instruction*> InsertedExprs;
- ReplaceUsesOfGEPInst(GEPI, Ptr, PtrOffset, DefBB, GEPI, InsertedExprs);
-
- // Finally, the GEP is dead, remove it.
- GEPI->eraseFromParent();
-
- return true;
-}
-
-
-/// SplitEdgeNicely - Split the critical edge from TI to it's specified
-/// successor if it will improve codegen. We only do this if the successor has
-/// phi nodes (otherwise critical edges are ok). If there is already another
-/// predecessor of the succ that is empty (and thus has no phi nodes), use it
-/// instead of introducing a new block.
-static void SplitEdgeNicely(TerminatorInst *TI, unsigned SuccNum, Pass *P) {
- BasicBlock *TIBB = TI->getParent();
- BasicBlock *Dest = TI->getSuccessor(SuccNum);
- assert(isa<PHINode>(Dest->begin()) &&
- "This should only be called if Dest has a PHI!");
-
- /// TIPHIValues - This array is lazily computed to determine the values of
- /// PHIs in Dest that TI would provide.
- std::vector<Value*> TIPHIValues;
-
- // Check to see if Dest has any blocks that can be used as a split edge for
- // this terminator.
- for (pred_iterator PI = pred_begin(Dest), E = pred_end(Dest); PI != E; ++PI) {
- BasicBlock *Pred = *PI;
- // To be usable, the pred has to end with an uncond branch to the dest.
- BranchInst *PredBr = dyn_cast<BranchInst>(Pred->getTerminator());
- if (!PredBr || !PredBr->isUnconditional() ||
- // Must be empty other than the branch.
- &Pred->front() != PredBr)
- continue;
-
- // Finally, since we know that Dest has phi nodes in it, we have to make
- // sure that jumping to Pred will have the same affect as going to Dest in
- // terms of PHI values.
- PHINode *PN;
- unsigned PHINo = 0;
- bool FoundMatch = true;
- for (BasicBlock::iterator I = Dest->begin();
- (PN = dyn_cast<PHINode>(I)); ++I, ++PHINo) {
- if (PHINo == TIPHIValues.size())
- TIPHIValues.push_back(PN->getIncomingValueForBlock(TIBB));
-
- // If the PHI entry doesn't work, we can't use this pred.
- if (TIPHIValues[PHINo] != PN->getIncomingValueForBlock(Pred)) {
- FoundMatch = false;
- break;
- }
- }
-
- // If we found a workable predecessor, change TI to branch to Succ.
- if (FoundMatch) {
- Dest->removePredecessor(TIBB);
- TI->setSuccessor(SuccNum, Pred);
- return;
- }
- }
-
- SplitCriticalEdge(TI, SuccNum, P, true);
-}
-
bool SelectionDAGISel::runOnFunction(Function &Fn) {
MachineFunction &MF = MachineFunction::construct(&Fn, TLI.getTargetMachine());
RegMap = MF.getSSARegMap();
DOUT << "\n\n\n=== " << Fn.getName() << "\n";
- // First, split all critical edges.
- //
- // In this pass we also look for GEP and cast instructions that are used
- // across basic blocks and rewrite them to improve basic-block-at-a-time
- // selection.
- //
- bool MadeChange = true;
- while (MadeChange) {
- MadeChange = false;
- for (Function::iterator BB = Fn.begin(), E = Fn.end(); BB != E; ++BB) {
- // Split all critical edges where the dest block has a PHI.
- TerminatorInst *BBTI = BB->getTerminator();
- if (BBTI->getNumSuccessors() > 1) {
- for (unsigned i = 0, e = BBTI->getNumSuccessors(); i != e; ++i)
- if (isa<PHINode>(BBTI->getSuccessor(i)->begin()) &&
- isCriticalEdge(BBTI, i, true))
- SplitEdgeNicely(BBTI, i, this);
- }
-
-
- for (BasicBlock::iterator BBI = BB->begin(), E = BB->end(); BBI != E; ) {
- Instruction *I = BBI++;
-
- if (CallInst *CI = dyn_cast<CallInst>(I)) {
- // If we found an inline asm expession, and if the target knows how to
- // lower it to normal LLVM code, do so now.
- if (isa<InlineAsm>(CI->getCalledValue()))
- if (const TargetAsmInfo *TAI =
- TLI.getTargetMachine().getTargetAsmInfo()) {
- if (TAI->ExpandInlineAsm(CI))
- BBI = BB->begin();
- }
- } else if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(I)) {
- MadeChange |= OptimizeGEPExpression(GEPI, TLI.getTargetData());
- } else if (CastInst *CI = dyn_cast<CastInst>(I)) {
- // If the source of the cast is a constant, then this should have
- // already been constant folded. The only reason NOT to constant fold
- // it is if something (e.g. LSR) was careful to place the constant
- // evaluation in a block other than then one that uses it (e.g. to hoist
- // the address of globals out of a loop). If this is the case, we don't
- // want to forward-subst the cast.
- if (isa<Constant>(CI->getOperand(0)))
- continue;
-
- // If this is a noop copy, sink it into user blocks to reduce the number
- // of virtual registers that must be created and coallesced.
- MVT::ValueType SrcVT = TLI.getValueType(CI->getOperand(0)->getType());
- MVT::ValueType DstVT = TLI.getValueType(CI->getType());
-
- // This is an fp<->int conversion?
- if (MVT::isInteger(SrcVT) != MVT::isInteger(DstVT))
- continue;
-
- // If this is an extension, it will be a zero or sign extension, which
- // isn't a noop.
- if (SrcVT < DstVT) continue;
-
- // If these values will be promoted, find out what they will be promoted
- // to. This helps us consider truncates on PPC as noop copies when they
- // are.
- if (TLI.getTypeAction(SrcVT) == TargetLowering::Promote)
- SrcVT = TLI.getTypeToTransformTo(SrcVT);
- if (TLI.getTypeAction(DstVT) == TargetLowering::Promote)
- DstVT = TLI.getTypeToTransformTo(DstVT);
-
- // If, after promotion, these are the same types, this is a noop copy.
- if (SrcVT == DstVT)
- MadeChange |= OptimizeNoopCopyExpression(CI);
- }
- }
- }
- }
-
FunctionLoweringInfo FuncInfo(TLI, Fn, MF);
for (Function::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I)
SelectBasicBlock(I, MF, FuncInfo);
+ // Add function live-ins to entry block live-in set.
+ BasicBlock *EntryBB = &Fn.getEntryBlock();
+ BB = FuncInfo.MBBMap[EntryBB];
+ if (!MF.livein_empty())
+ for (MachineFunction::livein_iterator I = MF.livein_begin(),
+ E = MF.livein_end(); I != E; ++I)
+ BB->addLiveIn(I->first);
+
return true;
}
} else if (SrcVT == MVT::Vector) {
// Handle copies from generic vectors to registers.
MVT::ValueType PTyElementVT, PTyLegalElementVT;
- unsigned NE = TLI.getPackedTypeBreakdown(cast<PackedType>(V->getType()),
+ unsigned NE = TLI.getVectorTypeBreakdown(cast<VectorType>(V->getType()),
PTyElementVT, PTyLegalElementVT);
// Insert a VBIT_CONVERT of the input vector to a "N x PTyElementVT"
}
return DAG.getNode(ISD::TokenFactor, MVT::Other,
&OutChains[0], OutChains.size());
- } else if (SrcVT < DestVT) {
+ } else if (TLI.getTypeAction(SrcVT) == TargetLowering::Promote) {
// The src value is promoted to the register.
if (MVT::isFloatingPoint(SrcVT))
Op = DAG.getNode(ISD::FP_EXTEND, DestVT, Op);
Op = DAG.getNode(ISD::ANY_EXTEND, DestVT, Op);
return DAG.getCopyToReg(getRoot(), Reg, Op);
} else {
+ DestVT = TLI.getTypeToExpandTo(SrcVT);
+ unsigned NumVals = TLI.getNumElements(SrcVT);
+ if (NumVals == 1)
+ return DAG.getCopyToReg(getRoot(), Reg,
+ DAG.getNode(ISD::BIT_CONVERT, DestVT, Op));
+ assert(NumVals == 2 && "1 to 4 (and more) expansion not implemented!");
// The src value is expanded into multiple registers.
SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, DestVT,
Op, DAG.getConstant(0, TLI.getPointerTy()));
}
void SelectionDAGISel::
-LowerArguments(BasicBlock *BB, SelectionDAGLowering &SDL,
+LowerArguments(BasicBlock *LLVMBB, SelectionDAGLowering &SDL,
std::vector<SDOperand> &UnorderedChains) {
// If this is the entry block, emit arguments.
- Function &F = *BB->getParent();
+ Function &F = *LLVMBB->getParent();
FunctionLoweringInfo &FuncInfo = SDL.FuncInfo;
SDOperand OldRoot = SDL.DAG.getRoot();
std::vector<SDOperand> Args = TLI.LowerArguments(F, SDL.DAG);
// If this argument is live outside of the entry block, insert a copy from
// whereever we got it to the vreg that other BB's will reference it as.
- if (FuncInfo.ValueMap.count(AI)) {
- SDOperand Copy =
- SDL.CopyValueToVirtualRegister(AI, FuncInfo.ValueMap[AI]);
+ DenseMap<const Value*, unsigned>::iterator VMI=FuncInfo.ValueMap.find(AI);
+ if (VMI != FuncInfo.ValueMap.end()) {
+ SDOperand Copy = SDL.CopyValueToVirtualRegister(AI, VMI->second);
UnorderedChains.push_back(Copy);
}
}
std::vector<SDOperand> UnorderedChains;
// Lower any arguments needed in this block if this is the entry block.
- if (LLVMBB == &LLVMBB->getParent()->front())
+ if (LLVMBB == &LLVMBB->getParent()->getEntryBlock())
LowerArguments(LLVMBB, SDL, UnorderedChains);
BB = FuncInfo.MBBMap[LLVMBB];
for (BasicBlock::iterator I = LLVMBB->begin(), E = --LLVMBB->end();
I != E; ++I)
SDL.visit(*I);
+
+ // Lower call part of invoke.
+ InvokeInst *Invoke = dyn_cast<InvokeInst>(LLVMBB->getTerminator());
+ if (Invoke) SDL.visitInvoke(*Invoke, false);
// Ensure that all instructions which are used outside of their defining
// blocks are available as virtual registers.
for (BasicBlock::iterator I = LLVMBB->begin(), E = LLVMBB->end(); I != E;++I)
if (!I->use_empty() && !isa<PHINode>(I)) {
- std::map<const Value*, unsigned>::iterator VMI =FuncInfo.ValueMap.find(I);
+ DenseMap<const Value*, unsigned>::iterator VMI =FuncInfo.ValueMap.find(I);
if (VMI != FuncInfo.ValueMap.end())
UnorderedChains.push_back(
SDL.CopyValueToVirtualRegister(I, VMI->second));
else {
MVT::ValueType VT1,VT2;
NumElements =
- TLI.getPackedTypeBreakdown(cast<PackedType>(PN->getType()),
+ TLI.getVectorTypeBreakdown(cast<VectorType>(PN->getType()),
VT1, VT2);
}
for (unsigned i = 0, e = NumElements; i != e; ++i)
}
// Lower the terminator after the copies are emitted.
- SDL.visit(*LLVMBB->getTerminator());
+ if (Invoke) {
+ // Just the branch part of invoke.
+ SDL.visitInvoke(*Invoke, true);
+ } else {
+ SDL.visit(*LLVMBB->getTerminator());
+ }
// Copy over any CaseBlock records that may now exist due to SwitchInst
// lowering, as well as any jump table information.
SwitchCases.clear();
SwitchCases = SDL.SwitchCases;
- JT = SDL.JT;
-
+ JTCases.clear();
+ JTCases = SDL.JTCases;
+ BitTestCases.clear();
+ BitTestCases = SDL.BitTestCases;
+
// Make sure the root of the DAG is up-to-date.
DAG.setRoot(SDL.getRoot());
}
FunctionLoweringInfo &FuncInfo) {
std::vector<std::pair<MachineInstr*, unsigned> > PHINodesToUpdate;
{
- SelectionDAG DAG(TLI, MF, getAnalysisToUpdate<MachineDebugInfo>());
+ SelectionDAG DAG(TLI, MF, getAnalysisToUpdate<MachineModuleInfo>());
CurDAG = &DAG;
// First step, lower LLVM code to some DAG. This DAG may use operations and
// Second step, emit the lowered DAG as machine code.
CodeGenAndEmitDAG(DAG);
}
+
+ DOUT << "Total amount of phi nodes to update: "
+ << PHINodesToUpdate.size() << "\n";
+ DEBUG(for (unsigned i = 0, e = PHINodesToUpdate.size(); i != e; ++i)
+ DOUT << "Node " << i << " : (" << PHINodesToUpdate[i].first
+ << ", " << PHINodesToUpdate[i].second << ")\n";);
// Next, now that we know what the last MBB the LLVM BB expanded is, update
// PHI nodes in successors.
- if (SwitchCases.empty() && JT.Reg == 0) {
+ if (SwitchCases.empty() && JTCases.empty() && BitTestCases.empty()) {
for (unsigned i = 0, e = PHINodesToUpdate.size(); i != e; ++i) {
MachineInstr *PHI = PHINodesToUpdate[i].first;
assert(PHI->getOpcode() == TargetInstrInfo::PHI &&
}
return;
}
-
+
+ for (unsigned i = 0, e = BitTestCases.size(); i != e; ++i) {
+ // Lower header first, if it wasn't already lowered
+ if (!BitTestCases[i].Emitted) {
+ SelectionDAG HSDAG(TLI, MF, getAnalysisToUpdate<MachineModuleInfo>());
+ CurDAG = &HSDAG;
+ SelectionDAGLowering HSDL(HSDAG, TLI, FuncInfo);
+ // Set the current basic block to the mbb we wish to insert the code into
+ BB = BitTestCases[i].Parent;
+ HSDL.setCurrentBasicBlock(BB);
+ // Emit the code
+ HSDL.visitBitTestHeader(BitTestCases[i]);
+ HSDAG.setRoot(HSDL.getRoot());
+ CodeGenAndEmitDAG(HSDAG);
+ }
+
+ for (unsigned j = 0, ej = BitTestCases[i].Cases.size(); j != ej; ++j) {
+ SelectionDAG BSDAG(TLI, MF, getAnalysisToUpdate<MachineModuleInfo>());
+ CurDAG = &BSDAG;
+ SelectionDAGLowering BSDL(BSDAG, TLI, FuncInfo);
+ // Set the current basic block to the mbb we wish to insert the code into
+ BB = BitTestCases[i].Cases[j].ThisBB;
+ BSDL.setCurrentBasicBlock(BB);
+ // Emit the code
+ if (j+1 != ej)
+ BSDL.visitBitTestCase(BitTestCases[i].Cases[j+1].ThisBB,
+ BitTestCases[i].Reg,
+ BitTestCases[i].Cases[j]);
+ else
+ BSDL.visitBitTestCase(BitTestCases[i].Default,
+ BitTestCases[i].Reg,
+ BitTestCases[i].Cases[j]);
+
+
+ BSDAG.setRoot(BSDL.getRoot());
+ CodeGenAndEmitDAG(BSDAG);
+ }
+
+ // Update PHI Nodes
+ for (unsigned pi = 0, pe = PHINodesToUpdate.size(); pi != pe; ++pi) {
+ MachineInstr *PHI = PHINodesToUpdate[pi].first;
+ MachineBasicBlock *PHIBB = PHI->getParent();
+ assert(PHI->getOpcode() == TargetInstrInfo::PHI &&
+ "This is not a machine PHI node that we are updating!");
+ // This is "default" BB. We have two jumps to it. From "header" BB and
+ // from last "case" BB.
+ if (PHIBB == BitTestCases[i].Default) {
+ PHI->addRegOperand(PHINodesToUpdate[pi].second, false);
+ PHI->addMachineBasicBlockOperand(BitTestCases[i].Parent);
+ PHI->addMachineBasicBlockOperand(BitTestCases[i].Cases.back().ThisBB);
+ }
+ // One of "cases" BB.
+ for (unsigned j = 0, ej = BitTestCases[i].Cases.size(); j != ej; ++j) {
+ MachineBasicBlock* cBB = BitTestCases[i].Cases[j].ThisBB;
+ if (cBB->succ_end() !=
+ std::find(cBB->succ_begin(),cBB->succ_end(), PHIBB)) {
+ PHI->addRegOperand(PHINodesToUpdate[pi].second, false);
+ PHI->addMachineBasicBlockOperand(cBB);
+ }
+ }
+ }
+ }
+
// If the JumpTable record is filled in, then we need to emit a jump table.
// Updating the PHI nodes is tricky in this case, since we need to determine
// whether the PHI is a successor of the range check MBB or the jump table MBB
- if (JT.Reg) {
- assert(SwitchCases.empty() && "Cannot have jump table and lowered switch");
- SelectionDAG SDAG(TLI, MF, getAnalysisToUpdate<MachineDebugInfo>());
- CurDAG = &SDAG;
- SelectionDAGLowering SDL(SDAG, TLI, FuncInfo);
- MachineBasicBlock *RangeBB = BB;
+ for (unsigned i = 0, e = JTCases.size(); i != e; ++i) {
+ // Lower header first, if it wasn't already lowered
+ if (!JTCases[i].first.Emitted) {
+ SelectionDAG HSDAG(TLI, MF, getAnalysisToUpdate<MachineModuleInfo>());
+ CurDAG = &HSDAG;
+ SelectionDAGLowering HSDL(HSDAG, TLI, FuncInfo);
+ // Set the current basic block to the mbb we wish to insert the code into
+ BB = JTCases[i].first.HeaderBB;
+ HSDL.setCurrentBasicBlock(BB);
+ // Emit the code
+ HSDL.visitJumpTableHeader(JTCases[i].second, JTCases[i].first);
+ HSDAG.setRoot(HSDL.getRoot());
+ CodeGenAndEmitDAG(HSDAG);
+ }
+
+ SelectionDAG JSDAG(TLI, MF, getAnalysisToUpdate<MachineModuleInfo>());
+ CurDAG = &JSDAG;
+ SelectionDAGLowering JSDL(JSDAG, TLI, FuncInfo);
// Set the current basic block to the mbb we wish to insert the code into
- BB = JT.MBB;
- SDL.setCurrentBasicBlock(BB);
+ BB = JTCases[i].second.MBB;
+ JSDL.setCurrentBasicBlock(BB);
// Emit the code
- SDL.visitJumpTable(JT);
- SDAG.setRoot(SDL.getRoot());
- CodeGenAndEmitDAG(SDAG);
+ JSDL.visitJumpTable(JTCases[i].second);
+ JSDAG.setRoot(JSDL.getRoot());
+ CodeGenAndEmitDAG(JSDAG);
+
// Update PHI Nodes
for (unsigned pi = 0, pe = PHINodesToUpdate.size(); pi != pe; ++pi) {
MachineInstr *PHI = PHINodesToUpdate[pi].first;
MachineBasicBlock *PHIBB = PHI->getParent();
assert(PHI->getOpcode() == TargetInstrInfo::PHI &&
"This is not a machine PHI node that we are updating!");
- if (PHIBB == JT.Default) {
+ // "default" BB. We can go there only from header BB.
+ if (PHIBB == JTCases[i].second.Default) {
PHI->addRegOperand(PHINodesToUpdate[pi].second, false);
- PHI->addMachineBasicBlockOperand(RangeBB);
+ PHI->addMachineBasicBlockOperand(JTCases[i].first.HeaderBB);
}
+ // JT BB. Just iterate over successors here
if (BB->succ_end() != std::find(BB->succ_begin(),BB->succ_end(), PHIBB)) {
PHI->addRegOperand(PHINodesToUpdate[pi].second, false);
PHI->addMachineBasicBlockOperand(BB);
}
}
- return;
}
// If the switch block involved a branch to one of the actual successors, we
// If we generated any switch lowering information, build and codegen any
// additional DAGs necessary.
for (unsigned i = 0, e = SwitchCases.size(); i != e; ++i) {
- SelectionDAG SDAG(TLI, MF, getAnalysisToUpdate<MachineDebugInfo>());
+ SelectionDAG SDAG(TLI, MF, getAnalysisToUpdate<MachineModuleInfo>());
CurDAG = &SDAG;
SelectionDAGLowering SDL(SDAG, TLI, FuncInfo);
}
// Add this to the output node.
- Ops.push_back(DAG.getConstant(4/*MEM*/ | (SelOps.size() << 3), MVT::i32));
+ MVT::ValueType IntPtrTy = DAG.getTargetLoweringInfo().getPointerTy();
+ Ops.push_back(DAG.getTargetConstant(4/*MEM*/ | (SelOps.size() << 3),
+ IntPtrTy));
Ops.insert(Ops.end(), SelOps.begin(), SelOps.end());
i += 2;
}