X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FSelectionDAG%2FSelectionDAGISel.cpp;h=4b88f7884f5d8287e2c303520b1d92835395c8e6;hb=5bab78527a946632cd9614daa0b9a82ee7b5e1cc;hp=60b5290607a5ef5971c9a10aed8819e3d188839f;hpb=87b51bc2b0e9bced27d6fd95573a3f21691a261c;p=oota-llvm.git diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 60b5290607a..4b88f7884f5 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -2,8 +2,8 @@ // // The LLVM Compiler Infrastructure // -// This file was developed by the LLVM research group and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // @@ -26,14 +26,15 @@ #include "llvm/Intrinsics.h" #include "llvm/IntrinsicInst.h" #include "llvm/ParameterAttributes.h" -#include "llvm/CodeGen/MachineModuleInfo.h" +#include "llvm/CodeGen/Collector.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineFrameInfo.h" -#include "llvm/CodeGen/MachineJumpTableInfo.h" #include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineJumpTableInfo.h" +#include "llvm/CodeGen/MachineModuleInfo.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/SchedulerRegistry.h" #include "llvm/CodeGen/SelectionDAG.h" -#include "llvm/CodeGen/SSARegMap.h" #include "llvm/Target/MRegisterInfo.h" #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetFrameInfo.h" @@ -56,7 +57,7 @@ ViewSchedDAGs("view-sched-dags", cl::Hidden, cl::desc("Pop up a window to show sched dags as they are processed")); static cl::opt ViewSUnitDAGs("view-sunit-dags", cl::Hidden, - cl::desc("Pop up a window to show SUnit dags after they are processed")); + cl::desc("Pop up a window to show SUnit dags after they are processed")); #else static const bool ViewISelDAGs = 0, ViewSchedDAGs = 0, ViewSUnitDAGs = 0; #endif @@ -78,7 +79,8 @@ namespace { RegisterPassParser > ISHeuristic("pre-RA-sched", cl::init(&createDefaultScheduler), - cl::desc("Instruction schedulers available (before register allocation):")); + cl::desc("Instruction schedulers available (before register" + " allocation):")); static RegisterScheduler defaultListDAGScheduler("default", " Best scheduler for the target", @@ -166,7 +168,7 @@ namespace llvm { TargetLowering &TLI; Function &Fn; MachineFunction &MF; - SSARegMap *RegMap; + MachineRegisterInfo &RegInfo; FunctionLoweringInfo(TargetLowering &TLI, Function &Fn,MachineFunction &MF); @@ -189,7 +191,7 @@ namespace llvm { #endif unsigned MakeReg(MVT::ValueType VT) { - return RegMap->createVirtualRegister(TLI.getRegClassFor(VT)); + return RegInfo.createVirtualRegister(TLI.getRegClassFor(VT)); } /// isExportedInst - Return true if the specified value is an instruction @@ -244,7 +246,7 @@ static bool isOnlyUsedInEntryBlock(Argument *A) { FunctionLoweringInfo::FunctionLoweringInfo(TargetLowering &tli, Function &fn, MachineFunction &mf) - : TLI(tli), Fn(fn), MF(mf), RegMap(MF.getSSARegMap()) { + : TLI(tli), Fn(fn), MF(mf), RegInfo(MF.getRegInfo()) { // Create a vreg for each argument register that is not dead and is used // outside of the entry block for the function. @@ -261,7 +263,7 @@ FunctionLoweringInfo::FunctionLoweringInfo(TargetLowering &tli, if (AllocaInst *AI = dyn_cast(I)) if (ConstantInt *CUI = dyn_cast(AI->getArraySize())) { const Type *Ty = AI->getAllocatedType(); - uint64_t TySize = TLI.getTargetData()->getTypeSize(Ty); + uint64_t TySize = TLI.getTargetData()->getABITypeSize(Ty); unsigned Align = std::max((unsigned)TLI.getTargetData()->getPrefTypeAlignment(Ty), AI->getAlignment()); @@ -426,12 +428,16 @@ public: /// FuncInfo - Information about the function as a whole. /// FunctionLoweringInfo &FuncInfo; + + /// GCI - Garbage collection metadata for the function. + CollectorMetadata *GCI; SelectionDAGLowering(SelectionDAG &dag, TargetLowering &tli, AliasAnalysis &aa, - FunctionLoweringInfo &funcinfo) + FunctionLoweringInfo &funcinfo, + CollectorMetadata *gci) : TLI(tli), DAG(dag), TD(DAG.getTarget().getTargetData()), AA(aa), - FuncInfo(funcinfo) { + FuncInfo(funcinfo), GCI(gci) { } /// getRoot - Return the current virtual root of the Selection DAG. @@ -478,10 +484,6 @@ public: const Value *SV, SDOperand Root, bool isVolatile, unsigned Alignment); - SDOperand getIntPtrConstant(uint64_t Val) { - return DAG.getConstant(Val, TLI.getPointerTy()); - } - SDOperand getValue(const Value *V); void setValue(const Value *V, SDOperand NewN) { @@ -499,11 +501,9 @@ public: 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, + void LowerCallTo(CallSite CS, SDOperand Callee, bool IsTailCall, MachineBasicBlock *LandingPad = NULL); - + // Terminator instructions. void visitRet(ReturnInst &I); void visitBr(BranchInst &I); @@ -597,7 +597,7 @@ public: void visitStore(StoreInst &I); void visitPHI(PHINode &I) { } // PHI nodes are handled specially. void visitCall(CallInst &I); - void visitInlineAsm(CallInst &I); + void visitInlineAsm(CallSite CS); const char *visitIntrinsicCall(CallInst &I, unsigned Intrinsic); void visitTargetIntrinsic(CallInst &I, unsigned Intrinsic); @@ -648,7 +648,15 @@ static SDOperand getCopyFromParts(SelectionDAG &DAG, if (MVT::isVector(PartVT)) { assert(MVT::isVector(ValueVT) && "Unknown vector conversion!"); - return DAG.getNode(ISD::BIT_CONVERT, PartVT, Val); + return DAG.getNode(ISD::BIT_CONVERT, ValueVT, Val); + } + + if (MVT::isVector(ValueVT)) { + assert(NumParts == 1 && + MVT::getVectorElementType(ValueVT) == PartVT && + MVT::getVectorNumElements(ValueVT) == 1 && + "Only trivial scalar-to-vector conversions should get here!"); + return DAG.getNode(ISD::BUILD_VECTOR, ValueVT, Val); } if (MVT::isInteger(PartVT) && @@ -666,12 +674,10 @@ static SDOperand getCopyFromParts(SelectionDAG &DAG, } } - if (MVT::isFloatingPoint(PartVT) && - MVT::isFloatingPoint(ValueVT)) - return DAG.getNode(ISD::FP_ROUND, ValueVT, Val); + if (MVT::isFloatingPoint(PartVT) && MVT::isFloatingPoint(ValueVT)) + return DAG.getNode(ISD::FP_ROUND, ValueVT, Val, DAG.getIntPtrConstant(0)); - if (MVT::getSizeInBits(PartVT) == - MVT::getSizeInBits(ValueVT)) + if (MVT::getSizeInBits(PartVT) == MVT::getSizeInBits(ValueVT)) return DAG.getNode(ISD::BIT_CONVERT, ValueVT, Val); assert(0 && "Unknown mismatch!"); @@ -746,6 +752,13 @@ static void getCopyToParts(SelectionDAG &DAG, assert(MVT::isVector(ValueVT) && "Not a vector-vector cast?"); Val = DAG.getNode(ISD::BIT_CONVERT, PartVT, Val); + } else if (MVT::isVector(ValueVT)) { + assert(NumParts == 1 && + MVT::getVectorElementType(ValueVT) == PartVT && + MVT::getVectorNumElements(ValueVT) == 1 && + "Only trivial vector-to-scalar conversions should get here!"); + Val = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, PartVT, Val, + DAG.getConstant(0, PtrVT)); } else if (MVT::isInteger(PartVT) && MVT::isInteger(ValueVT)) { if (PartVT < ValueVT) Val = DAG.getNode(ISD::TRUNCATE, PartVT, Val); @@ -919,12 +932,11 @@ void SelectionDAGLowering::visitRet(ReturnInst &I) { TmpVT = TLI.getTypeToTransformTo(MVT::i32); else TmpVT = MVT::i32; - const FunctionType *FTy = I.getParent()->getParent()->getFunctionType(); - const ParamAttrsList *Attrs = FTy->getParamAttrs(); + const Function *F = I.getParent()->getParent(); ISD::NodeType ExtendKind = ISD::ANY_EXTEND; - if (Attrs && Attrs->paramHasAttr(0, ParamAttr::SExt)) + if (F->paramHasAttr(0, ParamAttr::SExt)) ExtendKind = ISD::SIGN_EXTEND; - if (Attrs && Attrs->paramHasAttr(0, ParamAttr::ZExt)) + if (F->paramHasAttr(0, ParamAttr::ZExt)) ExtendKind = ISD::ZERO_EXTEND; RetOp = DAG.getNode(ExtendKind, TmpVT, RetOp); NewValues.push_back(RetOp); @@ -1152,7 +1164,6 @@ void SelectionDAGLowering::visitBr(BranchInst &I) { // Update machine-CFG edges. CurMBB->addSuccessor(Succ0MBB); - return; } @@ -1435,11 +1446,10 @@ void SelectionDAGLowering::visitInvoke(InvokeInst &I) { MachineBasicBlock *Return = FuncInfo.MBBMap[I.getSuccessor(0)]; MachineBasicBlock *LandingPad = FuncInfo.MBBMap[I.getSuccessor(1)]; - LowerCallTo(I, I.getCalledValue()->getType(), - I.getCallingConv(), - false, - getValue(I.getOperand(0)), - 3, LandingPad); + if (isa(I.getCalledValue())) + visitInlineAsm(&I); + else + LowerCallTo(&I, getValue(I.getOperand(0)), false, LandingPad); // If the value of the invoke is used outside of its defining block, make it // available as a virtual register. @@ -1900,7 +1910,7 @@ unsigned SelectionDAGLowering::Clusterify(CaseVector& Cases, SI.getSuccessorValue(i), SMBB)); } - sort(Cases.begin(), Cases.end(), CaseCmp()); + std::sort(Cases.begin(), Cases.end(), CaseCmp()); // Merge case into clusters if (Cases.size()>=2) @@ -2004,8 +2014,7 @@ void SelectionDAGLowering::visitSub(User &I) { const Type *ElTy = DestTy->getElementType(); if (ElTy->isFloatingPoint()) { unsigned VL = DestTy->getNumElements(); - std::vector NZ(VL, ConstantFP::get(ElTy, - ElTy==Type::FloatTy ? APFloat(-0.0f) : APFloat(-0.0))); + std::vector NZ(VL, ConstantFP::getNegativeZero(ElTy)); Constant *CNZ = ConstantVector::get(&NZ[0], NZ.size()); if (CV == CNZ) { SDOperand Op2 = getValue(I.getOperand(1)); @@ -2017,7 +2026,7 @@ void SelectionDAGLowering::visitSub(User &I) { } if (Ty->isFloatingPoint()) { if (ConstantFP *CFP = dyn_cast(I.getOperand(0))) - if (CFP->isExactlyValue(-0.0)) { + if (CFP->isExactlyValue(ConstantFP::getNegativeZero(Ty)->getValueAPF())) { SDOperand Op2 = getValue(I.getOperand(1)); setValue(&I, DAG.getNode(ISD::FNEG, Op2.getValueType(), Op2)); return; @@ -2149,7 +2158,7 @@ void SelectionDAGLowering::visitFPTrunc(User &I) { // FPTrunc is never a no-op cast, no need to check SDOperand N = getValue(I.getOperand(0)); MVT::ValueType DestVT = TLI.getValueType(I.getType()); - setValue(&I, DAG.getNode(ISD::FP_ROUND, DestVT, N)); + setValue(&I, DAG.getNode(ISD::FP_ROUND, DestVT, N, DAG.getIntPtrConstant(0))); } void SelectionDAGLowering::visitFPExt(User &I){ @@ -2270,7 +2279,7 @@ void SelectionDAGLowering::visitGetElementPtr(User &I) { // N = N + Offset uint64_t Offset = TD->getStructLayout(StTy)->getElementOffset(Field); N = DAG.getNode(ISD::ADD, N.getValueType(), N, - getIntPtrConstant(Offset)); + DAG.getIntPtrConstant(Offset)); } Ty = StTy->getElementType(Field); } else { @@ -2280,13 +2289,14 @@ void SelectionDAGLowering::visitGetElementPtr(User &I) { if (ConstantInt *CI = dyn_cast(Idx)) { if (CI->getZExtValue() == 0) continue; uint64_t Offs = - TD->getTypeSize(Ty)*cast(CI)->getSExtValue(); - N = DAG.getNode(ISD::ADD, N.getValueType(), N, getIntPtrConstant(Offs)); + TD->getABITypeSize(Ty)*cast(CI)->getSExtValue(); + N = DAG.getNode(ISD::ADD, N.getValueType(), N, + DAG.getIntPtrConstant(Offs)); continue; } // N = N + Idx * ElementSize; - uint64_t ElementSize = TD->getTypeSize(Ty); + uint64_t ElementSize = TD->getABITypeSize(Ty); SDOperand IdxN = getValue(Idx); // If the index is smaller or larger than intptr_t, truncate or extend @@ -2306,7 +2316,7 @@ void SelectionDAGLowering::visitGetElementPtr(User &I) { continue; } - SDOperand Scale = getIntPtrConstant(ElementSize); + SDOperand Scale = DAG.getIntPtrConstant(ElementSize); IdxN = DAG.getNode(ISD::MUL, N.getValueType(), IdxN, Scale); N = DAG.getNode(ISD::ADD, N.getValueType(), N, IdxN); } @@ -2321,7 +2331,7 @@ void SelectionDAGLowering::visitAlloca(AllocaInst &I) { return; // getValue will auto-populate this. const Type *Ty = I.getAllocatedType(); - uint64_t TySize = TLI.getTargetData()->getTypeSize(Ty); + uint64_t TySize = TLI.getTargetData()->getABITypeSize(Ty); unsigned Align = std::max((unsigned)TLI.getTargetData()->getPrefTypeAlignment(Ty), I.getAlignment()); @@ -2334,7 +2344,7 @@ void SelectionDAGLowering::visitAlloca(AllocaInst &I) { AllocSize = DAG.getNode(ISD::ZERO_EXTEND, IntPtr, AllocSize); AllocSize = DAG.getNode(ISD::MUL, IntPtr, AllocSize, - getIntPtrConstant(TySize)); + DAG.getIntPtrConstant(TySize)); // Handle alignment. If the requested alignment is less than or equal to // the stack alignment, ignore it. If the size is greater than or equal to @@ -2347,12 +2357,12 @@ void SelectionDAGLowering::visitAlloca(AllocaInst &I) { // Round the size of the allocation up to the stack alignment size // by add SA-1 to the size. AllocSize = DAG.getNode(ISD::ADD, AllocSize.getValueType(), AllocSize, - getIntPtrConstant(StackAlign-1)); + DAG.getIntPtrConstant(StackAlign-1)); // Mask out the low bits for alignment purposes. AllocSize = DAG.getNode(ISD::AND, AllocSize.getValueType(), AllocSize, - getIntPtrConstant(~(uint64_t)(StackAlign-1))); + DAG.getIntPtrConstant(~(uint64_t)(StackAlign-1))); - SDOperand Ops[] = { getRoot(), AllocSize, getIntPtrConstant(Align) }; + SDOperand Ops[] = { getRoot(), AllocSize, DAG.getIntPtrConstant(Align) }; const MVT::ValueType *VTs = DAG.getNodeValueTypes(AllocSize.getValueType(), MVT::Other); SDOperand DSA = DAG.getNode(ISD::DYNAMIC_STACKALLOC, VTs, 2, Ops, 3); @@ -2404,31 +2414,13 @@ void SelectionDAGLowering::visitStore(StoreInst &I) { I.isVolatile(), I.getAlignment())); } -/// IntrinsicCannotAccessMemory - Return true if the specified intrinsic cannot -/// access memory and has no other side effects at all. -static bool IntrinsicCannotAccessMemory(unsigned IntrinsicID) { -#define GET_NO_MEMORY_INTRINSICS -#include "llvm/Intrinsics.gen" -#undef GET_NO_MEMORY_INTRINSICS - return false; -} - -// IntrinsicOnlyReadsMemory - Return true if the specified intrinsic doesn't -// have any side-effects or if it only reads memory. -static bool IntrinsicOnlyReadsMemory(unsigned IntrinsicID) { -#define GET_SIDE_EFFECT_INFO -#include "llvm/Intrinsics.gen" -#undef GET_SIDE_EFFECT_INFO - return false; -} - /// visitTargetIntrinsic - Lower a call of a target intrinsic to an INTRINSIC /// node. void SelectionDAGLowering::visitTargetIntrinsic(CallInst &I, unsigned Intrinsic) { - bool HasChain = !IntrinsicCannotAccessMemory(Intrinsic); - bool OnlyLoad = HasChain && IntrinsicOnlyReadsMemory(Intrinsic); - + bool HasChain = !I.doesNotAccessMemory(); + bool OnlyLoad = HasChain && I.onlyReadsMemory(); + // Build the operand list. SmallVector Ops; if (HasChain) { // If this intrinsic has side-effects, chainify it. @@ -2797,19 +2789,33 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) { return 0; } - case Intrinsic::sqrt_f32: - case Intrinsic::sqrt_f64: + case Intrinsic::sqrt: setValue(&I, DAG.getNode(ISD::FSQRT, getValue(I.getOperand(1)).getValueType(), getValue(I.getOperand(1)))); return 0; - case Intrinsic::powi_f32: - case Intrinsic::powi_f64: + case Intrinsic::powi: setValue(&I, DAG.getNode(ISD::FPOWI, getValue(I.getOperand(1)).getValueType(), getValue(I.getOperand(1)), getValue(I.getOperand(2)))); return 0; + case Intrinsic::sin: + setValue(&I, DAG.getNode(ISD::FSIN, + getValue(I.getOperand(1)).getValueType(), + getValue(I.getOperand(1)))); + return 0; + case Intrinsic::cos: + setValue(&I, DAG.getNode(ISD::FCOS, + getValue(I.getOperand(1)).getValueType(), + getValue(I.getOperand(1)))); + return 0; + case Intrinsic::pow: + setValue(&I, DAG.getNode(ISD::FPOW, + getValue(I.getOperand(1)).getValueType(), + getValue(I.getOperand(1)), + getValue(I.getOperand(2)))); + return 0; case Intrinsic::pcmarker: { SDOperand Tmp = getValue(I.getOperand(1)); DAG.setRoot(DAG.getNode(ISD::PCMARKER, MVT::Other, getRoot(), Tmp)); @@ -2881,12 +2887,6 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) { // Discard annotate attributes return 0; - case Intrinsic::adjust_trampoline: { - SDOperand Arg = getValue(I.getOperand(1)); - setValue(&I, DAG.getNode(ISD::ADJUST_TRAMP, TLI.getPointerTy(), Arg)); - return 0; - } - case Intrinsic::init_trampoline: { const Function *F = cast(IntrinsicInst::StripPointerCasts(I.getOperand(2))); @@ -2899,68 +2899,99 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) { Ops[4] = DAG.getSrcValue(I.getOperand(1)); Ops[5] = DAG.getSrcValue(F); - DAG.setRoot(DAG.getNode(ISD::TRAMPOLINE, MVT::Other, Ops, 6)); + SDOperand Tmp = DAG.getNode(ISD::TRAMPOLINE, + DAG.getNodeValueTypes(TLI.getPointerTy(), + MVT::Other), 2, + Ops, 6); + + setValue(&I, Tmp); + DAG.setRoot(Tmp.getValue(1)); + return 0; + } + + case Intrinsic::gcroot: + if (GCI) { + Value *Alloca = I.getOperand(1); + Constant *TypeMap = cast(I.getOperand(2)); + + FrameIndexSDNode *FI = cast(getValue(Alloca).Val); + GCI->addStackRoot(FI->getIndex(), TypeMap); + } + return 0; + + case Intrinsic::gcread: + case Intrinsic::gcwrite: + assert(0 && "Collector failed to lower gcread/gcwrite intrinsics!"); + return 0; + + case Intrinsic::flt_rounds: { + setValue(&I, DAG.getNode(ISD::FLT_ROUNDS, MVT::i32)); + return 0; + } + + case Intrinsic::trap: { + DAG.setRoot(DAG.getNode(ISD::TRAP, MVT::Other, getRoot())); return 0; } } } -void SelectionDAGLowering::LowerCallTo(Instruction &I, - const Type *CalledValueTy, - unsigned CallingConv, +void SelectionDAGLowering::LowerCallTo(CallSite CS, SDOperand Callee, bool IsTailCall, - SDOperand Callee, unsigned OpIdx, MachineBasicBlock *LandingPad) { - const PointerType *PT = cast(CalledValueTy); + const PointerType *PT = cast(CS.getCalledValue()->getType()); const FunctionType *FTy = cast(PT->getElementType()); - const ParamAttrsList *Attrs = FTy->getParamAttrs(); MachineModuleInfo *MMI = DAG.getMachineModuleInfo(); unsigned BeginLabel = 0, EndLabel = 0; - + 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(); - - unsigned attrInd = i - OpIdx + 1; - Entry.isSExt = Attrs && Attrs->paramHasAttr(attrInd, ParamAttr::SExt); - Entry.isZExt = Attrs && Attrs->paramHasAttr(attrInd, ParamAttr::ZExt); - Entry.isInReg = Attrs && Attrs->paramHasAttr(attrInd, ParamAttr::InReg); - Entry.isSRet = Attrs && Attrs->paramHasAttr(attrInd, ParamAttr::StructRet); - Entry.isNest = Attrs && Attrs->paramHasAttr(attrInd, ParamAttr::Nest); - Entry.isByVal = Attrs && Attrs->paramHasAttr(attrInd, ParamAttr::ByVal); + Args.reserve(CS.arg_size()); + for (CallSite::arg_iterator i = CS.arg_begin(), e = CS.arg_end(); + i != e; ++i) { + SDOperand ArgNode = getValue(*i); + Entry.Node = ArgNode; Entry.Ty = (*i)->getType(); + + unsigned attrInd = i - CS.arg_begin() + 1; + Entry.isSExt = CS.paramHasAttr(attrInd, ParamAttr::SExt); + Entry.isZExt = CS.paramHasAttr(attrInd, ParamAttr::ZExt); + Entry.isInReg = CS.paramHasAttr(attrInd, ParamAttr::InReg); + Entry.isSRet = CS.paramHasAttr(attrInd, ParamAttr::StructRet); + Entry.isNest = CS.paramHasAttr(attrInd, ParamAttr::Nest); + Entry.isByVal = CS.paramHasAttr(attrInd, ParamAttr::ByVal); Args.push_back(Entry); } - if (ExceptionHandling && MMI && LandingPad) { + bool MarkTryRange = LandingPad || + // C++ requires special handling of 'nounwind' calls. + (CS.doesNotThrow()); + + if (MarkTryRange && ExceptionHandling && MMI) { // 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. BeginLabel = MMI->NextLabelID(); DAG.setRoot(DAG.getNode(ISD::LABEL, MVT::Other, getRoot(), DAG.getConstant(BeginLabel, MVT::i32))); } - + std::pair Result = - TLI.LowerCallTo(getRoot(), I.getType(), - Attrs && Attrs->paramHasAttr(0, ParamAttr::SExt), - FTy->isVarArg(), CallingConv, IsTailCall, + TLI.LowerCallTo(getRoot(), CS.getType(), + CS.paramHasAttr(0, ParamAttr::SExt), + FTy->isVarArg(), CS.getCallingConv(), IsTailCall, Callee, Args, DAG); - if (I.getType() != Type::VoidTy) - setValue(&I, Result.first); + if (CS.getType() != Type::VoidTy) + setValue(CS.getInstruction(), Result.first); DAG.setRoot(Result.second); - if (ExceptionHandling && MMI && LandingPad) { + if (MarkTryRange && ExceptionHandling && MMI) { // Insert a label at the end of the invoke call to mark the try range. This // can be used to detect deletion of the invoke via the MachineModuleInfo. EndLabel = MMI->NextLabelID(); DAG.setRoot(DAG.getNode(ISD::LABEL, MVT::Other, getRoot(), DAG.getConstant(EndLabel, MVT::i32))); - // Inform MachineModuleInfo of range. + // Inform MachineModuleInfo of range. MMI->addInvoke(LandingPad, BeginLabel, EndLabel); } } @@ -2997,7 +3028,8 @@ void SelectionDAGLowering::visitCall(CallInst &I) { } } else if (NameStr[0] == 'f' && ((NameLen == 4 && !strcmp(NameStr, "fabs")) || - (NameLen == 5 && !strcmp(NameStr, "fabsf")))) { + (NameLen == 5 && !strcmp(NameStr, "fabsf")) || + (NameLen == 5 && !strcmp(NameStr, "fabsl")))) { if (I.getNumOperands() == 2 && // Basic sanity checks. I.getOperand(1)->getType()->isFloatingPoint() && I.getType() == I.getOperand(1)->getType()) { @@ -3007,7 +3039,8 @@ void SelectionDAGLowering::visitCall(CallInst &I) { } } else if (NameStr[0] == 's' && ((NameLen == 3 && !strcmp(NameStr, "sin")) || - (NameLen == 4 && !strcmp(NameStr, "sinf")))) { + (NameLen == 4 && !strcmp(NameStr, "sinf")) || + (NameLen == 4 && !strcmp(NameStr, "sinl")))) { if (I.getNumOperands() == 2 && // Basic sanity checks. I.getOperand(1)->getType()->isFloatingPoint() && I.getType() == I.getOperand(1)->getType()) { @@ -3017,7 +3050,8 @@ void SelectionDAGLowering::visitCall(CallInst &I) { } } else if (NameStr[0] == 'c' && ((NameLen == 3 && !strcmp(NameStr, "cos")) || - (NameLen == 4 && !strcmp(NameStr, "cosf")))) { + (NameLen == 4 && !strcmp(NameStr, "cosf")) || + (NameLen == 4 && !strcmp(NameStr, "cosl")))) { if (I.getNumOperands() == 2 && // Basic sanity checks. I.getOperand(1)->getType()->isFloatingPoint() && I.getType() == I.getOperand(1)->getType()) { @@ -3028,7 +3062,7 @@ void SelectionDAGLowering::visitCall(CallInst &I) { } } } else if (isa(I.getOperand(0))) { - visitInlineAsm(I); + visitInlineAsm(&I); return; } @@ -3038,11 +3072,7 @@ void SelectionDAGLowering::visitCall(CallInst &I) { else Callee = DAG.getExternalSymbol(RenameFn, TLI.getPointerTy()); - LowerCallTo(I, I.getCalledValue()->getType(), - I.getCallingConv(), - I.isTailCall(), - Callee, - 1); + LowerCallTo(&I, Callee, I.isTailCall()); } @@ -3340,9 +3370,9 @@ GetRegistersForValue(AsmOperandInfo &OpInfo, bool HasEarlyClobber, ValueVT = RegVT; // Create the appropriate number of virtual registers. - SSARegMap *RegMap = MF.getSSARegMap(); + MachineRegisterInfo &RegInfo = MF.getRegInfo(); for (; NumRegs; --NumRegs) - Regs.push_back(RegMap->createVirtualRegister(PhysReg.second)); + Regs.push_back(RegInfo.createVirtualRegister(PhysReg.second)); OpInfo.AssignedRegs = RegsForValue(Regs, RegVT, ValueVT); OpInfo.MarkAllocatedRegs(isOutReg, isInReg, OutputRegs, InputRegs); @@ -3409,8 +3439,8 @@ GetRegistersForValue(AsmOperandInfo &OpInfo, bool HasEarlyClobber, /// visitInlineAsm - Handle a call to an InlineAsm object. /// -void SelectionDAGLowering::visitInlineAsm(CallInst &I) { - InlineAsm *IA = cast(I.getOperand(0)); +void SelectionDAGLowering::visitInlineAsm(CallSite CS) { + InlineAsm *IA = cast(CS.getCalledValue()); /// ConstraintOperands - Information about all of the constraints. std::vector ConstraintOperands; @@ -3430,7 +3460,7 @@ void SelectionDAGLowering::visitInlineAsm(CallInst &I) { // registers, because it will not know to avoid the earlyclobbered output reg. bool SawEarlyClobber = false; - unsigned OpNo = 1; // OpNo - The operand of the CallInst. + unsigned ArgNo = 0; // ArgNo - The argument of the CallInst. for (unsigned i = 0, e = ConstraintInfos.size(); i != e; ++i) { ConstraintOperands.push_back(AsmOperandInfo(ConstraintInfos[i])); AsmOperandInfo &OpInfo = ConstraintOperands.back(); @@ -3443,14 +3473,14 @@ void SelectionDAGLowering::visitInlineAsm(CallInst &I) { if (!OpInfo.isIndirect) { // The return value of the call is this value. As such, there is no // corresponding argument. - assert(I.getType() != Type::VoidTy && "Bad inline asm!"); - OpVT = TLI.getValueType(I.getType()); + assert(CS.getType() != Type::VoidTy && "Bad inline asm!"); + OpVT = TLI.getValueType(CS.getType()); } else { - OpInfo.CallOperandVal = I.getOperand(OpNo++); + OpInfo.CallOperandVal = CS.getArgument(ArgNo++); } break; case InlineAsm::isInput: - OpInfo.CallOperandVal = I.getOperand(OpNo++); + OpInfo.CallOperandVal = CS.getArgument(ArgNo++); break; case InlineAsm::isClobber: // Nothing to do. @@ -3458,31 +3488,37 @@ void SelectionDAGLowering::visitInlineAsm(CallInst &I) { } // If this is an input or an indirect output, process the call argument. + // BasicBlocks are labels, currently appearing only in asm's. if (OpInfo.CallOperandVal) { - OpInfo.CallOperand = getValue(OpInfo.CallOperandVal); - const Type *OpTy = OpInfo.CallOperandVal->getType(); - // If this is an indirect operand, the operand is a pointer to the - // accessed type. - if (OpInfo.isIndirect) - OpTy = cast(OpTy)->getElementType(); - - // If OpTy is not a first-class value, it may be a struct/union that we - // can tile with integers. - if (!OpTy->isFirstClassType() && OpTy->isSized()) { - unsigned BitSize = TD->getTypeSizeInBits(OpTy); - switch (BitSize) { - default: break; - case 1: - case 8: - case 16: - case 32: - case 64: - OpTy = IntegerType::get(BitSize); - break; + if (isa(OpInfo.CallOperandVal)) + OpInfo.CallOperand = + DAG.getBasicBlock(FuncInfo.MBBMap[cast(OpInfo.CallOperandVal)]); + else { + OpInfo.CallOperand = getValue(OpInfo.CallOperandVal); + const Type *OpTy = OpInfo.CallOperandVal->getType(); + // If this is an indirect operand, the operand is a pointer to the + // accessed type. + if (OpInfo.isIndirect) + OpTy = cast(OpTy)->getElementType(); + + // If OpTy is not a first-class value, it may be a struct/union that we + // can tile with integers. + if (!OpTy->isFirstClassType() && OpTy->isSized()) { + unsigned BitSize = TD->getTypeSizeInBits(OpTy); + switch (BitSize) { + default: break; + case 1: + case 8: + case 16: + case 32: + case 64: + OpTy = IntegerType::get(BitSize); + break; + } } + + OpVT = TLI.getValueType(OpTy, true); } - - OpVT = TLI.getValueType(OpTy, true); } OpInfo.ConstraintVT = OpVT; @@ -3515,7 +3551,7 @@ void SelectionDAGLowering::visitInlineAsm(CallInst &I) { // Otherwise, create a stack slot and emit a store to it before the // asm. const Type *Ty = OpVal->getType(); - uint64_t TySize = TLI.getTargetData()->getTypeSize(Ty); + uint64_t TySize = TLI.getTargetData()->getABITypeSize(Ty); unsigned Align = TLI.getTargetData()->getPrefTypeAlignment(Ty); MachineFunction &MF = DAG.getMachineFunction(); int SSFI = MF.getFrameInfo()->CreateStackObject(TySize, Align); @@ -3595,7 +3631,7 @@ void SelectionDAGLowering::visitInlineAsm(CallInst &I) { // This is the result value of the call. assert(RetValRegs.Regs.empty() && "Cannot have multiple output constraints yet!"); - assert(I.getType() != Type::VoidTy && "Bad inline asm!"); + assert(CS.getType() != Type::VoidTy && "Bad inline asm!"); RetValRegs = OpInfo.AssignedRegs; } else { IndirectStoresToEmit.push_back(std::make_pair(OpInfo.AssignedRegs, @@ -3729,13 +3765,13 @@ void SelectionDAGLowering::visitInlineAsm(CallInst &I) { // width/num elts. Make sure to convert it to the right type with // bit_convert. if (MVT::isVector(Val.getValueType())) { - const VectorType *VTy = cast(I.getType()); + const VectorType *VTy = cast(CS.getType()); MVT::ValueType DesiredVT = TLI.getValueType(VTy); Val = DAG.getNode(ISD::BIT_CONVERT, DesiredVT, Val); } - setValue(&I, Val); + setValue(CS.getInstruction(), Val); } std::vector > StoresToEmit; @@ -3773,9 +3809,9 @@ void SelectionDAGLowering::visitMalloc(MallocInst &I) { Src = DAG.getNode(ISD::ZERO_EXTEND, IntPtr, Src); // Scale the source by the type size. - uint64_t ElementSize = TD->getTypeSize(I.getType()->getElementType()); + uint64_t ElementSize = TD->getABITypeSize(I.getType()->getElementType()); Src = DAG.getNode(ISD::MUL, Src.getValueType(), - Src, getIntPtrConstant(ElementSize)); + Src, DAG.getIntPtrConstant(ElementSize)); TargetLowering::ArgListTy Args; TargetLowering::ArgListEntry Entry; @@ -3852,8 +3888,6 @@ void SelectionDAGLowering::visitVACopy(CallInst &I) { /// integrated into SDISel. std::vector 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 Ops; Ops.push_back(DAG.getRoot()); @@ -3872,25 +3906,24 @@ TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) { // FIXME: Distinguish between a formal with no [sz]ext attribute from one // that is zero extended! - if (Attrs && Attrs->paramHasAttr(j, ParamAttr::ZExt)) + if (F.paramHasAttr(j, ParamAttr::ZExt)) Flags &= ~(ISD::ParamFlags::SExt); - if (Attrs && Attrs->paramHasAttr(j, ParamAttr::SExt)) + if (F.paramHasAttr(j, ParamAttr::SExt)) Flags |= ISD::ParamFlags::SExt; - if (Attrs && Attrs->paramHasAttr(j, ParamAttr::InReg)) + if (F.paramHasAttr(j, ParamAttr::InReg)) Flags |= ISD::ParamFlags::InReg; - if (Attrs && Attrs->paramHasAttr(j, ParamAttr::StructRet)) + if (F.paramHasAttr(j, ParamAttr::StructRet)) Flags |= ISD::ParamFlags::StructReturn; - if (Attrs && Attrs->paramHasAttr(j, ParamAttr::ByVal)) { + if (F.paramHasAttr(j, ParamAttr::ByVal)) { Flags |= ISD::ParamFlags::ByVal; const PointerType *Ty = cast(I->getType()); - const StructType *STy = cast(Ty->getElementType()); - unsigned StructAlign = - Log2_32(getTargetData()->getCallFrameTypeAlignment(STy)); - unsigned StructSize = getTargetData()->getTypeSize(STy); - Flags |= (StructAlign << ISD::ParamFlags::ByValAlignOffs); - Flags |= (StructSize << ISD::ParamFlags::ByValSizeOffs); + const Type *ElementTy = Ty->getElementType(); + unsigned FrameAlign = Log2_32(getByValTypeAlignment(ElementTy)); + unsigned FrameSize = getTargetData()->getABITypeSize(ElementTy); + Flags |= (FrameAlign << ISD::ParamFlags::ByValAlignOffs); + Flags |= (FrameSize << ISD::ParamFlags::ByValSizeOffs); } - if (Attrs && Attrs->paramHasAttr(j, ParamAttr::Nest)) + if (F.paramHasAttr(j, ParamAttr::Nest)) Flags |= ISD::ParamFlags::Nest; Flags |= (OriginalAlignment << ISD::ParamFlags::OrigAlignmentOffs); @@ -3947,16 +3980,16 @@ TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) { case Promote: { SDOperand Op(Result, i++); if (MVT::isInteger(VT)) { - if (Attrs && Attrs->paramHasAttr(Idx, ParamAttr::SExt)) + if (F.paramHasAttr(Idx, ParamAttr::SExt)) Op = DAG.getNode(ISD::AssertSext, Op.getValueType(), Op, DAG.getValueType(VT)); - else if (Attrs && Attrs->paramHasAttr(Idx, ParamAttr::ZExt)) + else if (F.paramHasAttr(Idx, ParamAttr::ZExt)) 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?"); - Op = DAG.getNode(ISD::FP_ROUND, VT, Op); + Op = DAG.getNode(ISD::FP_ROUND, VT, Op, DAG.getIntPtrConstant(1)); } Ops.push_back(Op); break; @@ -4013,12 +4046,11 @@ TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy, if (Args[i].isByVal) { Flags |= ISD::ParamFlags::ByVal; const PointerType *Ty = cast(Args[i].Ty); - const StructType *STy = cast(Ty->getElementType()); - unsigned StructAlign = - Log2_32(getTargetData()->getCallFrameTypeAlignment(STy)); - unsigned StructSize = getTargetData()->getTypeSize(STy); - Flags |= (StructAlign << ISD::ParamFlags::ByValAlignOffs); - Flags |= (StructSize << ISD::ParamFlags::ByValSizeOffs); + const Type *ElementTy = Ty->getElementType(); + unsigned FrameAlign = Log2_32(getByValTypeAlignment(ElementTy)); + unsigned FrameSize = getTargetData()->getABITypeSize(ElementTy); + Flags |= (FrameAlign << ISD::ParamFlags::ByValAlignOffs); + Flags |= (FrameSize << ISD::ParamFlags::ByValSizeOffs); } if (Args[i].isNest) Flags |= ISD::ParamFlags::Nest; @@ -4304,13 +4336,13 @@ void SelectionDAGLowering::visitMemIntrinsic(CallInst &I, unsigned Op) { I.getOperand(1), DstOff); } else { Value = DAG.getLoad(VT, getRoot(), - getMemBasePlusOffset(Op2, SrcOff, DAG, TLI), - I.getOperand(2), SrcOff); + getMemBasePlusOffset(Op2, SrcOff, DAG, TLI), + I.getOperand(2), SrcOff, false, Align); Chain = Value.getValue(1); Store = DAG.getStore(Chain, Value, getMemBasePlusOffset(Op1, DstOff, DAG, TLI), - I.getOperand(1), DstOff); + I.getOperand(1), DstOff, false, Align); } OutChains.push_back(Store); SrcOff += VTSize; @@ -4328,7 +4360,22 @@ void SelectionDAGLowering::visitMemIntrinsic(CallInst &I, unsigned Op) { } } - DAG.setRoot(DAG.getNode(Op, MVT::Other, getRoot(), Op1, Op2, Op3, Op4)); + SDOperand AlwaysInline = DAG.getConstant(0, MVT::i1); + SDOperand Node; + switch(Op) { + default: + assert(0 && "Unknown Op"); + case ISD::MEMCPY: + Node = DAG.getMemcpy(getRoot(), Op1, Op2, Op3, Op4, AlwaysInline); + break; + case ISD::MEMMOVE: + Node = DAG.getMemmove(getRoot(), Op1, Op2, Op3, Op4, AlwaysInline); + break; + case ISD::MEMSET: + Node = DAG.getMemset(getRoot(), Op1, Op2, Op3, Op4, AlwaysInline); + break; + } + DAG.setRoot(Node); } //===----------------------------------------------------------------------===// @@ -4336,11 +4383,12 @@ void SelectionDAGLowering::visitMemIntrinsic(CallInst &I, unsigned Op) { //===----------------------------------------------------------------------===// unsigned SelectionDAGISel::MakeReg(MVT::ValueType VT) { - return RegMap->createVirtualRegister(TLI.getRegClassFor(VT)); + return RegInfo->createVirtualRegister(TLI.getRegClassFor(VT)); } void SelectionDAGISel::getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired(); + AU.addRequired(); AU.setPreservesAll(); } @@ -4351,7 +4399,11 @@ bool SelectionDAGISel::runOnFunction(Function &Fn) { AA = &getAnalysis(); MachineFunction &MF = MachineFunction::construct(&Fn, TLI.getTargetMachine()); - RegMap = MF.getSSARegMap(); + if (MF.getFunction()->hasCollector()) + GCI = &getAnalysis().get(*MF.getFunction()); + else + GCI = 0; + RegInfo = &MF.getRegInfo(); DOUT << "\n\n\n=== " << Fn.getName() << "\n"; FunctionLoweringInfo FuncInfo(TLI, Fn, MF); @@ -4368,9 +4420,9 @@ bool SelectionDAGISel::runOnFunction(Function &Fn) { // 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) + if (!RegInfo->livein_empty()) + for (MachineRegisterInfo::livein_iterator I = RegInfo->livein_begin(), + E = RegInfo->livein_end(); I != E; ++I) BB->addLiveIn(I->first); #ifndef NDEBUG @@ -4432,22 +4484,63 @@ LowerArguments(BasicBlock *LLVMBB, SelectionDAGLowering &SDL, static void copyCatchInfo(BasicBlock *SrcBB, BasicBlock *DestBB, MachineModuleInfo *MMI, FunctionLoweringInfo &FLI) { - assert(!FLI.MBBMap[SrcBB]->isLandingPad() && - "Copying catch info out of a landing pad!"); for (BasicBlock::iterator I = SrcBB->begin(), E = --SrcBB->end(); I != E; ++I) if (isSelector(I)) { // Apply the catch info to DestBB. addCatchInfo(cast(*I), MMI, FLI.MBBMap[DestBB]); #ifndef NDEBUG - FLI.CatchInfoFound.insert(I); + if (!FLI.MBBMap[SrcBB]->isLandingPad()) + FLI.CatchInfoFound.insert(I); #endif } } +/// CheckDAGForTailCallsAndFixThem - This Function looks for CALL nodes in the +/// DAG and fixes their tailcall attribute operand. +static void CheckDAGForTailCallsAndFixThem(SelectionDAG &DAG, + TargetLowering& TLI) { + SDNode * Ret = NULL; + SDOperand Terminator = DAG.getRoot(); + + // Find RET node. + if (Terminator.getOpcode() == ISD::RET) { + Ret = Terminator.Val; + } + + // Fix tail call attribute of CALL nodes. + for (SelectionDAG::allnodes_iterator BE = DAG.allnodes_begin(), + BI = prior(DAG.allnodes_end()); BI != BE; --BI) { + if (BI->getOpcode() == ISD::CALL) { + SDOperand OpRet(Ret, 0); + SDOperand OpCall(static_cast(BI), 0); + bool isMarkedTailCall = + cast(OpCall.getOperand(3))->getValue() != 0; + // If CALL node has tail call attribute set to true and the call is not + // eligible (no RET or the target rejects) the attribute is fixed to + // false. The TargetLowering::IsEligibleForTailCallOptimization function + // must correctly identify tail call optimizable calls. + if (isMarkedTailCall && + (Ret==NULL || + !TLI.IsEligibleForTailCallOptimization(OpCall, OpRet, DAG))) { + SmallVector Ops; + unsigned idx=0; + for(SDNode::op_iterator I =OpCall.Val->op_begin(), + E=OpCall.Val->op_end(); I!=E; I++, idx++) { + if (idx!=3) + Ops.push_back(*I); + else + Ops.push_back(DAG.getConstant(false, TLI.getPointerTy())); + } + DAG.UpdateNodeOperands(OpCall, Ops.begin(), Ops.size()); + } + } + } +} + void SelectionDAGISel::BuildSelectionDAG(SelectionDAG &DAG, BasicBlock *LLVMBB, std::vector > &PHINodesToUpdate, FunctionLoweringInfo &FuncInfo) { - SelectionDAGLowering SDL(DAG, TLI, *AA, FuncInfo); + SelectionDAGLowering SDL(DAG, TLI, *AA, FuncInfo, GCI); std::vector UnorderedChains; @@ -4621,17 +4714,30 @@ void SelectionDAGISel::BuildSelectionDAG(SelectionDAG &DAG, BasicBlock *LLVMBB, // Make sure the root of the DAG is up-to-date. DAG.setRoot(SDL.getRoot()); + + // Check whether calls in this block are real tail calls. Fix up CALL nodes + // with correct tailcall attribute so that the target can rely on the tailcall + // attribute indicating whether the call is really eligible for tail call + // optimization. + CheckDAGForTailCallsAndFixThem(DAG, TLI); } void SelectionDAGISel::CodeGenAndEmitDAG(SelectionDAG &DAG) { + DOUT << "Lowered selection DAG:\n"; + DEBUG(DAG.dump()); + // Run the DAG combiner in pre-legalize mode. DAG.Combine(false, *AA); - DOUT << "Lowered selection DAG:\n"; + DOUT << "Optimized lowered selection DAG:\n"; DEBUG(DAG.dump()); // Second step, hack on the DAG until it only uses operations and types that // the target supports. +#if 0 // Enable this some day. + DAG.LegalizeTypes(); + // Someday even later, enable a dag combine pass here. +#endif DAG.Legalize(); DOUT << "Legalized selection DAG:\n"; @@ -4640,6 +4746,9 @@ void SelectionDAGISel::CodeGenAndEmitDAG(SelectionDAG &DAG) { // Run the DAG combiner in post-legalize mode. DAG.Combine(true, *AA); + DOUT << "Optimized legalized selection DAG:\n"; + DEBUG(DAG.dump()); + if (ViewISelDAGs) DAG.viewGraph(); // Third, instruction select all of the operations to machine code, adding the @@ -4678,8 +4787,9 @@ void SelectionDAGISel::SelectBasicBlock(BasicBlock *LLVMBB, MachineFunction &MF, MachineInstr *PHI = PHINodesToUpdate[i].first; assert(PHI->getOpcode() == TargetInstrInfo::PHI && "This is not a machine PHI node that we are updating!"); - PHI->addRegOperand(PHINodesToUpdate[i].second, false); - PHI->addMachineBasicBlockOperand(BB); + PHI->addOperand(MachineOperand::CreateReg(PHINodesToUpdate[i].second, + false)); + PHI->addOperand(MachineOperand::CreateMBB(BB)); } return; } @@ -4689,7 +4799,7 @@ void SelectionDAGISel::SelectBasicBlock(BasicBlock *LLVMBB, MachineFunction &MF, if (!BitTestCases[i].Emitted) { SelectionDAG HSDAG(TLI, MF, getAnalysisToUpdate()); CurDAG = &HSDAG; - SelectionDAGLowering HSDL(HSDAG, TLI, *AA, FuncInfo); + SelectionDAGLowering HSDL(HSDAG, TLI, *AA, FuncInfo, GCI); // Set the current basic block to the mbb we wish to insert the code into BB = BitTestCases[i].Parent; HSDL.setCurrentBasicBlock(BB); @@ -4702,7 +4812,7 @@ void SelectionDAGISel::SelectBasicBlock(BasicBlock *LLVMBB, MachineFunction &MF, for (unsigned j = 0, ej = BitTestCases[i].Cases.size(); j != ej; ++j) { SelectionDAG BSDAG(TLI, MF, getAnalysisToUpdate()); CurDAG = &BSDAG; - SelectionDAGLowering BSDL(BSDAG, TLI, *AA, FuncInfo); + SelectionDAGLowering BSDL(BSDAG, TLI, *AA, FuncInfo, GCI); // Set the current basic block to the mbb we wish to insert the code into BB = BitTestCases[i].Cases[j].ThisBB; BSDL.setCurrentBasicBlock(BB); @@ -4730,18 +4840,22 @@ void SelectionDAGISel::SelectBasicBlock(BasicBlock *LLVMBB, MachineFunction &MF, // 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->addRegOperand(PHINodesToUpdate[pi].second, false); - PHI->addMachineBasicBlockOperand(BitTestCases[i].Cases.back().ThisBB); + PHI->addOperand(MachineOperand::CreateReg(PHINodesToUpdate[pi].second, + false)); + PHI->addOperand(MachineOperand::CreateMBB(BitTestCases[i].Parent)); + PHI->addOperand(MachineOperand::CreateReg(PHINodesToUpdate[pi].second, + false)); + PHI->addOperand(MachineOperand::CreateMBB(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); + PHI->addOperand(MachineOperand::CreateReg(PHINodesToUpdate[pi].second, + false)); + PHI->addOperand(MachineOperand::CreateMBB(cBB)); } } } @@ -4755,7 +4869,7 @@ void SelectionDAGISel::SelectBasicBlock(BasicBlock *LLVMBB, MachineFunction &MF, if (!JTCases[i].first.Emitted) { SelectionDAG HSDAG(TLI, MF, getAnalysisToUpdate()); CurDAG = &HSDAG; - SelectionDAGLowering HSDL(HSDAG, TLI, *AA, FuncInfo); + SelectionDAGLowering HSDL(HSDAG, TLI, *AA, FuncInfo, GCI); // Set the current basic block to the mbb we wish to insert the code into BB = JTCases[i].first.HeaderBB; HSDL.setCurrentBasicBlock(BB); @@ -4767,7 +4881,7 @@ void SelectionDAGISel::SelectBasicBlock(BasicBlock *LLVMBB, MachineFunction &MF, SelectionDAG JSDAG(TLI, MF, getAnalysisToUpdate()); CurDAG = &JSDAG; - SelectionDAGLowering JSDL(JSDAG, TLI, *AA, FuncInfo); + SelectionDAGLowering JSDL(JSDAG, TLI, *AA, FuncInfo, GCI); // Set the current basic block to the mbb we wish to insert the code into BB = JTCases[i].second.MBB; JSDL.setCurrentBasicBlock(BB); @@ -4784,13 +4898,15 @@ void SelectionDAGISel::SelectBasicBlock(BasicBlock *LLVMBB, MachineFunction &MF, "This is not a machine PHI node that we are updating!"); // "default" BB. We can go there only from header BB. if (PHIBB == JTCases[i].second.Default) { - PHI->addRegOperand(PHINodesToUpdate[pi].second, false); - PHI->addMachineBasicBlockOperand(JTCases[i].first.HeaderBB); + PHI->addOperand(MachineOperand::CreateReg(PHINodesToUpdate[pi].second, + false)); + PHI->addOperand(MachineOperand::CreateMBB(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); + PHI->addOperand(MachineOperand::CreateReg(PHINodesToUpdate[pi].second, + false)); + PHI->addOperand(MachineOperand::CreateMBB(BB)); } } } @@ -4802,8 +4918,9 @@ void SelectionDAGISel::SelectBasicBlock(BasicBlock *LLVMBB, MachineFunction &MF, assert(PHI->getOpcode() == TargetInstrInfo::PHI && "This is not a machine PHI node that we are updating!"); if (BB->isSuccessor(PHI->getParent())) { - PHI->addRegOperand(PHINodesToUpdate[i].second, false); - PHI->addMachineBasicBlockOperand(BB); + PHI->addOperand(MachineOperand::CreateReg(PHINodesToUpdate[i].second, + false)); + PHI->addOperand(MachineOperand::CreateMBB(BB)); } } @@ -4812,7 +4929,7 @@ void SelectionDAGISel::SelectBasicBlock(BasicBlock *LLVMBB, MachineFunction &MF, for (unsigned i = 0, e = SwitchCases.size(); i != e; ++i) { SelectionDAG SDAG(TLI, MF, getAnalysisToUpdate()); CurDAG = &SDAG; - SelectionDAGLowering SDL(SDAG, TLI, *AA, FuncInfo); + SelectionDAGLowering SDL(SDAG, TLI, *AA, FuncInfo, GCI); // Set the current basic block to the mbb we wish to insert the code into BB = SwitchCases[i].ThisBB; @@ -4834,8 +4951,9 @@ void SelectionDAGISel::SelectBasicBlock(BasicBlock *LLVMBB, MachineFunction &MF, for (unsigned pn = 0; ; ++pn) { assert(pn != PHINodesToUpdate.size() && "Didn't find PHI entry!"); if (PHINodesToUpdate[pn].first == Phi) { - Phi->addRegOperand(PHINodesToUpdate[pn].second, false); - Phi->addMachineBasicBlockOperand(SwitchCases[i].ThisBB); + Phi->addOperand(MachineOperand::CreateReg(PHINodesToUpdate[pn]. + second, false)); + Phi->addOperand(MachineOperand::CreateMBB(SwitchCases[i].ThisBB)); break; } }