X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FSelectionDAG%2FSelectionDAGISel.cpp;h=4b88f7884f5d8287e2c303520b1d92835395c8e6;hb=5bab78527a946632cd9614daa0b9a82ee7b5e1cc;hp=4468d16e8c271d5196fccd37a42f318d1683745f;hpb=de09040946b4aa9bdc70057d65f840685ac31fef;p=oota-llvm.git diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 4468d16e8c2..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); @@ -674,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!"); @@ -934,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); @@ -1167,7 +1164,6 @@ void SelectionDAGLowering::visitBr(BranchInst &I) { // Update machine-CFG edges. CurMBB->addSuccessor(Succ0MBB); - return; } @@ -1450,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. @@ -1915,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) @@ -2163,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){ @@ -2284,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 { @@ -2295,7 +2290,8 @@ void SelectionDAGLowering::visitGetElementPtr(User &I) { if (CI->getZExtValue() == 0) continue; uint64_t Offs = TD->getABITypeSize(Ty)*cast(CI)->getSExtValue(); - N = DAG.getNode(ISD::ADD, N.getValueType(), N, getIntPtrConstant(Offs)); + N = DAG.getNode(ISD::ADD, N.getValueType(), N, + DAG.getIntPtrConstant(Offs)); continue; } @@ -2320,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); } @@ -2335,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()); @@ -2348,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 @@ -2361,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); @@ -2418,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. @@ -2930,65 +2908,90 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) { 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); } } @@ -3059,7 +3062,7 @@ void SelectionDAGLowering::visitCall(CallInst &I) { } } } else if (isa(I.getOperand(0))) { - visitInlineAsm(I); + visitInlineAsm(&I); return; } @@ -3069,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()); } @@ -3371,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); @@ -3440,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; @@ -3461,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(); @@ -3474,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. @@ -3489,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; @@ -3546,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); @@ -3626,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, @@ -3760,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; @@ -3804,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; @@ -3883,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()); @@ -3903,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); @@ -3978,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; @@ -4044,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; @@ -4134,14 +4135,6 @@ SDOperand TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { return SDOperand(); } -std::pair -TargetLowering::ExpandOperationResult(SDNode *N, SelectionDAG &DAG) { - assert(0 && "ExpandOperation not implemented for this target!"); - abort(); - return std::pair(); -} - - SDOperand TargetLowering::CustomPromoteOperation(SDOperand Op, SelectionDAG &DAG) { assert(0 && "CustomPromoteOperation not implemented for this target!"); @@ -4302,10 +4295,6 @@ void SelectionDAGLowering::visitMemIntrinsic(CallInst &I, unsigned Op) { break; } case ISD::MEMCPY: { - // FIXME: Disabling memcpy lowering for copying onto the stack. - if (Op1.getOpcode() == ISD::FrameIndex) - break; - if (MeetsMaxMemopRequirement(MemOps, TLI.getMaxStoresPerMemcpy(), Size->getValue(), Align, TLI)) { unsigned NumMemOps = MemOps.size(); @@ -4347,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; @@ -4394,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(); } @@ -4409,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); @@ -4426,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 @@ -4490,14 +4484,13 @@ 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 } } @@ -4547,7 +4540,7 @@ static void CheckDAGForTailCallsAndFixThem(SelectionDAG &DAG, 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; @@ -4794,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; } @@ -4805,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); @@ -4818,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); @@ -4846,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)); } } } @@ -4871,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); @@ -4883,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); @@ -4900,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)); } } } @@ -4918,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)); } } @@ -4928,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; @@ -4950,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; } }