diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h index 01aba3f9853..3f13663d51f 100644 --- a/include/llvm/CodeGen/SelectionDAG.h +++ b/include/llvm/CodeGen/SelectionDAG.h @@ -66,7 +66,7 @@ private: /// class SelectionDAG { TargetLowering &TLI; - MachineFunction &MF; + MachineFunction *MF; FunctionLoweringInfo &FLI; MachineModuleInfo *MMI; @@ -103,16 +103,20 @@ class SelectionDAG { void VerifyNode(SDNode *N); public: - SelectionDAG(TargetLowering &tli, MachineFunction &mf, - FunctionLoweringInfo &fli, MachineModuleInfo *mmi); + SelectionDAG(TargetLowering &tli, FunctionLoweringInfo &fli); ~SelectionDAG(); - /// reset - Clear state and free memory necessary to make this + /// init - Prepare this SelectionDAG to process code in the given + /// MachineFunction. + /// + void init(MachineFunction &mf, MachineModuleInfo *mmi); + + /// clear - Clear state and free memory necessary to make this /// SelectionDAG ready to process a new block. /// - void reset(); + void clear(); - MachineFunction &getMachineFunction() const { return MF; } + MachineFunction &getMachineFunction() const { return *MF; } const TargetMachine &getTarget() const; TargetLowering &getTargetLoweringInfo() const { return TLI; } FunctionLoweringInfo &getFunctionLoweringInfo() const { return FLI; } diff --git a/include/llvm/CodeGen/SelectionDAGISel.h b/include/llvm/CodeGen/SelectionDAGISel.h index 64c3b25591a..ee5f88364fc 100644 --- a/include/llvm/CodeGen/SelectionDAGISel.h +++ b/include/llvm/CodeGen/SelectionDAGISel.h @@ -39,7 +39,9 @@ class SelectionDAGISel : public FunctionPass { public: TargetLowering &TLI; MachineRegisterInfo *RegInfo; + FunctionLoweringInfo *FuncInfo; SelectionDAG *CurDAG; + SelectionDAGLowering *SDL; MachineBasicBlock *BB; AliasAnalysis *AA; GCFunctionInfo *GFI; @@ -47,8 +49,8 @@ public: std::vector TopOrder; static char ID; - explicit SelectionDAGISel(TargetLowering &tli, bool fast = false) : - FunctionPass((intptr_t)&ID), TLI(tli), GFI(), Fast(fast), DAGSize(0) {} + explicit SelectionDAGISel(TargetLowering &tli, bool fast = false); + virtual ~SelectionDAGISel(); TargetLowering &getTargetLowering() { return TLI; } @@ -87,80 +89,6 @@ public: /// to use for this target when scheduling the DAG. virtual HazardRecognizer *CreateTargetHazardRecognizer(); - /// CaseBlock - This structure is used to communicate between SDLowering and - /// SDISel for the code generation of additional basic blocks needed by multi- - /// case switch statements. - struct CaseBlock { - CaseBlock(ISD::CondCode cc, Value *cmplhs, Value *cmprhs, Value *cmpmiddle, - MachineBasicBlock *truebb, MachineBasicBlock *falsebb, - MachineBasicBlock *me) - : CC(cc), CmpLHS(cmplhs), CmpMHS(cmpmiddle), CmpRHS(cmprhs), - TrueBB(truebb), FalseBB(falsebb), ThisBB(me) {} - // CC - the condition code to use for the case block's setcc node - ISD::CondCode CC; - // CmpLHS/CmpRHS/CmpMHS - The LHS/MHS/RHS of the comparison to emit. - // Emit by default LHS op RHS. MHS is used for range comparisons: - // If MHS is not null: (LHS <= MHS) and (MHS <= RHS). - Value *CmpLHS, *CmpMHS, *CmpRHS; - // TrueBB/FalseBB - the block to branch to if the setcc is true/false. - MachineBasicBlock *TrueBB, *FalseBB; - // ThisBB - the block into which to emit the code for the setcc and branches - MachineBasicBlock *ThisBB; - }; - struct JumpTable { - JumpTable(unsigned R, unsigned J, MachineBasicBlock *M, - MachineBasicBlock *D): Reg(R), JTI(J), MBB(M), Default(D) {} - - /// Reg - the virtual register containing the index of the jump table entry - //. to jump to. - unsigned Reg; - /// JTI - the JumpTableIndex for this jump table in the function. - unsigned JTI; - /// MBB - the MBB into which to emit the code for the indirect jump. - MachineBasicBlock *MBB; - /// Default - the MBB of the default bb, which is a successor of the range - /// check MBB. This is when updating PHI nodes in successors. - MachineBasicBlock *Default; - }; - struct JumpTableHeader { - JumpTableHeader(uint64_t F, uint64_t L, Value* SV, MachineBasicBlock* H, - bool E = false): - First(F), Last(L), SValue(SV), HeaderBB(H), Emitted(E) {} - uint64_t First; - uint64_t Last; - Value *SValue; - MachineBasicBlock *HeaderBB; - bool Emitted; - }; - typedef std::pair JumpTableBlock; - - struct BitTestCase { - BitTestCase(uint64_t M, MachineBasicBlock* T, MachineBasicBlock* Tr): - Mask(M), ThisBB(T), TargetBB(Tr) { } - uint64_t Mask; - MachineBasicBlock* ThisBB; - MachineBasicBlock* TargetBB; - }; - - typedef SmallVector BitTestInfo; - - struct BitTestBlock { - BitTestBlock(uint64_t F, uint64_t R, Value* SV, - unsigned Rg, bool E, - MachineBasicBlock* P, MachineBasicBlock* D, - const BitTestInfo& C): - First(F), Range(R), SValue(SV), Reg(Rg), Emitted(E), - Parent(P), Default(D), Cases(C) { } - uint64_t First; - uint64_t Range; - Value *SValue; - unsigned Reg; - bool Emitted; - MachineBasicBlock *Parent; - MachineBasicBlock *Default; - BitTestInfo Cases; - }; - protected: /// DAGSize - Size of DAG being instruction selected. /// @@ -177,40 +105,23 @@ protected: int64_t DesiredMaskS) const; private: - void SelectAllBasicBlocks(Function &Fn, MachineFunction &MF, - FunctionLoweringInfo &FuncInfo); - void FinishBasicBlock(FunctionLoweringInfo &FuncInfo, - std::vector > &PHINodesToUpdate); + void SelectAllBasicBlocks(Function &Fn, MachineFunction &MF); + void FinishBasicBlock(); void SelectBasicBlock(BasicBlock *LLVMBB, BasicBlock::iterator Begin, BasicBlock::iterator End, - bool DoArgs, - std::vector > &PHINodesToUpdate, - FunctionLoweringInfo &FuncInfo); + bool DoArgs); void CodeGenAndEmitDAG(); - void LowerArguments(BasicBlock *BB, SelectionDAGLowering &SDL); + void LowerArguments(BasicBlock *BB); void ComputeLiveOutVRegInfo(); - void HandlePHINodesInSuccessorBlocks(BasicBlock *LLVMBB, - FunctionLoweringInfo &FuncInfo, - std::vector > &PHINodesToUpdate, - SelectionDAGLowering &SDL); + void HandlePHINodesInSuccessorBlocks(BasicBlock *LLVMBB); /// Pick a safe ordering for instructions for each target node in the /// graph. ScheduleDAG *Schedule(); - - /// SwitchCases - Vector of CaseBlock structures used to communicate - /// SwitchInst code generation information. - std::vector SwitchCases; - - /// JTCases - Vector of JumpTable structures which holds necessary information - /// for emitting a jump tables during SwitchInst code generation. - std::vector JTCases; - - std::vector BitTestCases; }; } diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 5c996a0b3e6..0bd1a4d2d08 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -765,14 +765,18 @@ unsigned SelectionDAG::getMVTAlignment(MVT VT) const { return TLI.getTargetData()->getABITypeAlignment(Ty); } -SelectionDAG::SelectionDAG(TargetLowering &tli, MachineFunction &mf, - FunctionLoweringInfo &fli, MachineModuleInfo *mmi) - : TLI(tli), MF(mf), FLI(fli), MMI(mmi), - EntryNode(ISD::EntryToken, getVTList(MVT::Other)), +SelectionDAG::SelectionDAG(TargetLowering &tli, FunctionLoweringInfo &fli) + : TLI(tli), FLI(fli), + EntryNode(ISD::EntryToken, getVTList(MVT::Other)), Root(getEntryNode()) { AllNodes.push_back(&EntryNode); } +void SelectionDAG::init(MachineFunction &mf, MachineModuleInfo *mmi) { + MF = &mf; + MMI = mmi; +} + SelectionDAG::~SelectionDAG() { allnodes_clear(); } @@ -789,7 +793,7 @@ void SelectionDAG::allnodes_clear() { } } -void SelectionDAG::reset() { +void SelectionDAG::clear() { allnodes_clear(); OperandAllocator.Reset(); CSEMap.clear(); diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 35f79094eaa..e0ecda4613a 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -313,11 +313,16 @@ namespace llvm { class FunctionLoweringInfo { public: TargetLowering &TLI; - Function &Fn; - MachineFunction &MF; - MachineRegisterInfo &RegInfo; + Function *Fn; + MachineFunction *MF; + MachineRegisterInfo *RegInfo; - FunctionLoweringInfo(TargetLowering &TLI, Function &Fn,MachineFunction &MF); + explicit FunctionLoweringInfo(TargetLowering &TLI); + + /// set - Initialize this FunctionLoweringInfo with the given Function + /// and its associated MachineFunction. + /// + void set(Function &Fn, MachineFunction &MF); /// MBBMap - A mapping from LLVM basic blocks to their machine code entry. DenseMap MBBMap; @@ -338,7 +343,7 @@ namespace llvm { #endif unsigned MakeReg(MVT VT) { - return RegInfo.createVirtualRegister(TLI.getRegClassFor(VT)); + return RegInfo->createVirtualRegister(TLI.getRegClassFor(VT)); } /// isExportedInst - Return true if the specified value is an instruction @@ -364,6 +369,20 @@ namespace llvm { /// LiveOutRegInfo - Information about live out vregs, indexed by their /// register number offset by 'FirstVirtualRegister'. std::vector LiveOutRegInfo; + + /// clear - Clear out all the function-specific state. This returns this + /// FunctionLoweringInfo to an empty state, ready to be used for a + /// different function. + void clear() { + MBBMap.clear(); + ValueMap.clear(); + StaticAllocaMap.clear(); +#ifndef NDEBUG + CatchInfoLost.clear(); + CatchInfoFound.clear(); +#endif + LiveOutRegInfo.clear(); + } }; } @@ -406,13 +425,18 @@ static bool isOnlyUsedInEntryBlock(Argument *A) { return true; } -FunctionLoweringInfo::FunctionLoweringInfo(TargetLowering &tli, - Function &fn, MachineFunction &mf) - : TLI(tli), Fn(fn), MF(mf), RegInfo(MF.getRegInfo()) { +FunctionLoweringInfo::FunctionLoweringInfo(TargetLowering &tli) + : TLI(tli) { +} + +void FunctionLoweringInfo::set(Function &fn, MachineFunction &mf) { + 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. - for (Function::arg_iterator AI = Fn.arg_begin(), E = Fn.arg_end(); + for (Function::arg_iterator AI = Fn->arg_begin(), E = Fn->arg_end(); AI != E; ++AI) if (!isOnlyUsedInEntryBlock(AI)) InitializeRegForValue(AI); @@ -420,7 +444,7 @@ FunctionLoweringInfo::FunctionLoweringInfo(TargetLowering &tli, // Initialize the mapping of values to registers. This is only set up for // instruction values that are used outside of the block that defines // them. - Function::iterator BB = Fn.begin(), EB = Fn.end(); + Function::iterator BB = Fn->begin(), EB = Fn->end(); for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) if (AllocaInst *AI = dyn_cast(I)) if (ConstantInt *CUI = dyn_cast(AI->getArraySize())) { @@ -433,7 +457,7 @@ FunctionLoweringInfo::FunctionLoweringInfo(TargetLowering &tli, TySize *= CUI->getZExtValue(); // Get total allocated size. if (TySize == 0) TySize = 1; // Don't create zero-sized stack objects. StaticAllocaMap[AI] = - MF.getFrameInfo()->CreateStackObject(TySize, Align); + MF->getFrameInfo()->CreateStackObject(TySize, Align); } for (; BB != EB; ++BB) @@ -446,10 +470,10 @@ FunctionLoweringInfo::FunctionLoweringInfo(TargetLowering &tli, // Create an initial MachineBasicBlock for each LLVM BasicBlock in F. This // also creates the initial PHI MachineInstrs, though none of the input // operands are populated. - for (BB = Fn.begin(), EB = Fn.end(); BB != EB; ++BB) { + for (BB = Fn->begin(), EB = Fn->end(); BB != EB; ++BB) { MachineBasicBlock *MBB = mf.CreateMachineBasicBlock(BB); MBBMap[BB] = MBB; - MF.push_back(MBB); + MF->push_back(MBB); // Create Machine PHI nodes for LLVM PHI nodes, lowering them as // appropriate. @@ -499,6 +523,84 @@ unsigned FunctionLoweringInfo::CreateRegForValue(const Value *V) { return FirstReg; } +namespace { + +/// CaseBlock - This structure is used to communicate between SDLowering and +/// SDISel for the code generation of additional basic blocks needed by multi- +/// case switch statements. +struct CaseBlock { + CaseBlock(ISD::CondCode cc, Value *cmplhs, Value *cmprhs, Value *cmpmiddle, + MachineBasicBlock *truebb, MachineBasicBlock *falsebb, + MachineBasicBlock *me) + : CC(cc), CmpLHS(cmplhs), CmpMHS(cmpmiddle), CmpRHS(cmprhs), + TrueBB(truebb), FalseBB(falsebb), ThisBB(me) {} + // CC - the condition code to use for the case block's setcc node + ISD::CondCode CC; + // CmpLHS/CmpRHS/CmpMHS - The LHS/MHS/RHS of the comparison to emit. + // Emit by default LHS op RHS. MHS is used for range comparisons: + // If MHS is not null: (LHS <= MHS) and (MHS <= RHS). + Value *CmpLHS, *CmpMHS, *CmpRHS; + // TrueBB/FalseBB - the block to branch to if the setcc is true/false. + MachineBasicBlock *TrueBB, *FalseBB; + // ThisBB - the block into which to emit the code for the setcc and branches + MachineBasicBlock *ThisBB; +}; +struct JumpTable { + JumpTable(unsigned R, unsigned J, MachineBasicBlock *M, + MachineBasicBlock *D): Reg(R), JTI(J), MBB(M), Default(D) {} + + /// Reg - the virtual register containing the index of the jump table entry + //. to jump to. + unsigned Reg; + /// JTI - the JumpTableIndex for this jump table in the function. + unsigned JTI; + /// MBB - the MBB into which to emit the code for the indirect jump. + MachineBasicBlock *MBB; + /// Default - the MBB of the default bb, which is a successor of the range + /// check MBB. This is when updating PHI nodes in successors. + MachineBasicBlock *Default; +}; +struct JumpTableHeader { + JumpTableHeader(uint64_t F, uint64_t L, Value* SV, MachineBasicBlock* H, + bool E = false): + First(F), Last(L), SValue(SV), HeaderBB(H), Emitted(E) {} + uint64_t First; + uint64_t Last; + Value *SValue; + MachineBasicBlock *HeaderBB; + bool Emitted; +}; +typedef std::pair JumpTableBlock; + +struct BitTestCase { + BitTestCase(uint64_t M, MachineBasicBlock* T, MachineBasicBlock* Tr): + Mask(M), ThisBB(T), TargetBB(Tr) { } + uint64_t Mask; + MachineBasicBlock* ThisBB; + MachineBasicBlock* TargetBB; +}; + +typedef SmallVector BitTestInfo; + +struct BitTestBlock { + BitTestBlock(uint64_t F, uint64_t R, Value* SV, + unsigned Rg, bool E, + MachineBasicBlock* P, MachineBasicBlock* D, + const BitTestInfo& C): + First(F), Range(R), SValue(SV), Reg(Rg), Emitted(E), + Parent(P), Default(D), Cases(C) { } + uint64_t First; + uint64_t Range; + Value *SValue; + unsigned Reg; + bool Emitted; + MachineBasicBlock *Parent; + MachineBasicBlock *Default; + BitTestInfo Cases; +}; + +} // end anonymous namespace + //===----------------------------------------------------------------------===// /// SelectionDAGLowering - This is the common target-independent lowering /// implementation that is parameterized by a TargetLowering object. @@ -521,7 +623,7 @@ class SelectionDAGLowering { /// instruction, but they have no other ordering requirements. We bunch them /// up and the emit a single tokenfactor for them just before terminator /// instructions. - std::vector PendingExports; + SmallVector PendingExports; /// Case - A struct to record the Value for a switch case, and the /// case's target basic block. @@ -599,16 +701,24 @@ public: TargetLowering &TLI; SelectionDAG &DAG; const TargetData *TD; - AliasAnalysis &AA; + AliasAnalysis *AA; /// SwitchCases - Vector of CaseBlock structures used to communicate /// SwitchInst code generation information. - std::vector SwitchCases; + std::vector SwitchCases; /// JTCases - Vector of JumpTable structures used to communicate /// SwitchInst code generation information. - std::vector JTCases; - std::vector BitTestCases; + std::vector JTCases; + /// BitTestCases - Vector of BitTestBlock structures used to communicate + /// SwitchInst code generation information. + std::vector BitTestCases; + std::vector > PHINodesToUpdate; + + // Emit PHI-node-operand constants only once even if used by multiple + // PHI nodes. + DenseMap ConstantsOut; + /// FuncInfo - Information about the function as a whole. /// FunctionLoweringInfo &FuncInfo; @@ -617,11 +727,27 @@ public: GCFunctionInfo *GFI; SelectionDAGLowering(SelectionDAG &dag, TargetLowering &tli, - AliasAnalysis &aa, - FunctionLoweringInfo &funcinfo, - GCFunctionInfo *gfi) - : TLI(tli), DAG(dag), TD(DAG.getTarget().getTargetData()), AA(aa), - FuncInfo(funcinfo), GFI(gfi) { + FunctionLoweringInfo &funcinfo) + : TLI(tli), DAG(dag), FuncInfo(funcinfo) { + } + + void init(GCFunctionInfo *gfi, AliasAnalysis &aa) { + AA = &aa; + GFI = gfi; + TD = DAG.getTarget().getTargetData(); + } + + /// clear - Clear out the curret SelectionDAG and the associated + /// state and prepare this SelectionDAGLowering object to be used + /// for a new block. This doesn't clear out information about + /// additional blocks that are needed to complete switch lowering + /// or PHI node updating; that information is cleared out as it is + /// consumed. + void clear() { + NodeMap.clear(); + PendingLoads.clear(); + PendingExports.clear(); + DAG.clear(); } /// getRoot - Return the current virtual root of the Selection DAG, @@ -741,14 +867,13 @@ public: CaseRecVector& WorkList, Value* SV, MachineBasicBlock* Default); - void visitSwitchCase(SelectionDAGISel::CaseBlock &CB); - void visitBitTestHeader(SelectionDAGISel::BitTestBlock &B); + void visitSwitchCase(CaseBlock &CB); + void visitBitTestHeader(BitTestBlock &B); void visitBitTestCase(MachineBasicBlock* NextMBB, unsigned Reg, - SelectionDAGISel::BitTestCase &B); - void visitJumpTable(SelectionDAGISel::JumpTable &JT); - void visitJumpTableHeader(SelectionDAGISel::JumpTable &JT, - SelectionDAGISel::JumpTableHeader &JTH); + BitTestCase &B); + void visitJumpTable(JumpTable &JT); + void visitJumpTableHeader(JumpTable &JT, JumpTableHeader &JTH); // These all get lowered before this pass. void visitInvoke(InvokeInst &I); @@ -1437,15 +1562,15 @@ void SelectionDAGLowering::FindMergedConditions(Value *Cond, assert(0 && "Unknown compare instruction"); } - SelectionDAGISel::CaseBlock CB(Condition, BOp->getOperand(0), - BOp->getOperand(1), NULL, TBB, FBB, CurBB); + CaseBlock CB(Condition, BOp->getOperand(0), + 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, ConstantInt::getTrue(), - NULL, TBB, FBB, CurBB); + CaseBlock CB(ISD::SETEQ, Cond, ConstantInt::getTrue(), + NULL, TBB, FBB, CurBB); SwitchCases.push_back(CB); return; } @@ -1494,7 +1619,7 @@ void SelectionDAGLowering::FindMergedConditions(Value *Cond, /// If we should emit this as a bunch of and/or'd together conditions, return /// false. static bool -ShouldEmitAsBranches(const std::vector &Cases) { +ShouldEmitAsBranches(const std::vector &Cases) { if (Cases.size() != 2) return true; // If this is two comparisons of the same values or'd or and'd together, they @@ -1583,8 +1708,8 @@ void SelectionDAGLowering::visitBr(BranchInst &I) { } // Create a CaseBlock record representing this branch. - SelectionDAGISel::CaseBlock CB(ISD::SETEQ, CondVal, ConstantInt::getTrue(), - NULL, Succ0MBB, Succ1MBB, CurMBB); + 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); @@ -1592,7 +1717,7 @@ void SelectionDAGLowering::visitBr(BranchInst &I) { /// visitSwitchCase - Emits the necessary code to represent a single node in /// the binary search tree resulting from lowering a switch instruction. -void SelectionDAGLowering::visitSwitchCase(SelectionDAGISel::CaseBlock &CB) { +void SelectionDAGLowering::visitSwitchCase(CaseBlock &CB) { SDValue Cond; SDValue CondLHS = getValue(CB.CmpLHS); @@ -1664,7 +1789,7 @@ void SelectionDAGLowering::visitSwitchCase(SelectionDAGISel::CaseBlock &CB) { } /// visitJumpTable - Emit JumpTable node in the current MBB -void SelectionDAGLowering::visitJumpTable(SelectionDAGISel::JumpTable &JT) { +void SelectionDAGLowering::visitJumpTable(JumpTable &JT) { // Emit the code for the jump table assert(JT.Reg != -1U && "Should lower JT Header first!"); MVT PTy = TLI.getPointerTy(); @@ -1677,8 +1802,8 @@ void SelectionDAGLowering::visitJumpTable(SelectionDAGISel::JumpTable &JT) { /// visitJumpTableHeader - This function emits necessary code to produce index /// in the JumpTable from switch case. -void SelectionDAGLowering::visitJumpTableHeader(SelectionDAGISel::JumpTable &JT, - SelectionDAGISel::JumpTableHeader &JTH) { +void SelectionDAGLowering::visitJumpTableHeader(JumpTable &JT, + 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. @@ -1729,7 +1854,7 @@ void SelectionDAGLowering::visitJumpTableHeader(SelectionDAGISel::JumpTable &JT, /// visitBitTestHeader - This function emits necessary code to produce value /// suitable for "bit tests" -void SelectionDAGLowering::visitBitTestHeader(SelectionDAGISel::BitTestBlock &B) { +void SelectionDAGLowering::visitBitTestHeader(BitTestBlock &B) { // Subtract the minimum value SDValue SwitchOp = getValue(B.SValue); MVT VT = SwitchOp.getValueType(); @@ -1783,7 +1908,7 @@ void SelectionDAGLowering::visitBitTestHeader(SelectionDAGISel::BitTestBlock &B) /// visitBitTestCase - this function produces one "bit test" void SelectionDAGLowering::visitBitTestCase(MachineBasicBlock* NextMBB, unsigned Reg, - SelectionDAGISel::BitTestCase &B) { + BitTestCase &B) { // Emit bit tests and jumps SDValue SwitchVal = DAG.getCopyFromReg(getControlRoot(), Reg, TLI.getPointerTy()); @@ -1911,8 +2036,7 @@ bool SelectionDAGLowering::handleSmallSwitchRange(CaseRec& CR, CC = ISD::SETLE; LHS = I->Low; MHS = SV; RHS = I->High; } - SelectionDAGISel::CaseBlock CB(CC, LHS, RHS, MHS, - I->BB, FallThrough, CurBlock); + CaseBlock CB(CC, LHS, RHS, MHS, I->BB, FallThrough, CurBlock); // If emitting the first comparison, just call visitSwitchCase to emit the // code into the current block. Otherwise, push the CaseBlock onto the @@ -2019,13 +2143,12 @@ bool SelectionDAGLowering::handleJTSwitchCase(CaseRec& CR, // Set the jump table information so that we can codegen it as a second // MachineBasicBlock - SelectionDAGISel::JumpTable JT(-1U, JTI, JumpTableBB, Default); - SelectionDAGISel::JumpTableHeader JTH(First, Last, SV, CR.CaseBB, - (CR.CaseBB == CurMBB)); + JumpTable JT(-1U, JTI, JumpTableBB, Default); + JumpTableHeader JTH(First, Last, SV, CR.CaseBB, (CR.CaseBB == CurMBB)); if (CR.CaseBB == CurMBB) visitJumpTableHeader(JT, JTH); - JTCases.push_back(SelectionDAGISel::JumpTableBlock(JTH, JT)); + JTCases.push_back(JumpTableBlock(JTH, JT)); return true; } @@ -2139,8 +2262,7 @@ bool SelectionDAGLowering::handleBTSplitSwitchCase(CaseRec& CR, // 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); + CaseBlock CB(ISD::SETLT, SV, C, NULL, TrueBB, FalseBB, CR.CaseBB); if (CR.CaseBB == CurMBB) visitSwitchCase(CB); @@ -2241,7 +2363,7 @@ bool SelectionDAGLowering::handleBitTestsSwitchCase(CaseRec& CR, } std::sort(CasesBits.begin(), CasesBits.end(), CaseBitsCmp()); - SelectionDAGISel::BitTestInfo BTC; + BitTestInfo BTC; // Figure out which block is immediately after the current one. MachineFunction::iterator BBI = CR.CaseBB; @@ -2256,14 +2378,14 @@ bool SelectionDAGLowering::handleBitTestsSwitchCase(CaseRec& CR, MachineBasicBlock *CaseBB = CurMF->CreateMachineBasicBlock(LLVMBB); CurMF->insert(BBI, CaseBB); - BTC.push_back(SelectionDAGISel::BitTestCase(CasesBits[i].Mask, - CaseBB, - CasesBits[i].BB)); + BTC.push_back(BitTestCase(CasesBits[i].Mask, + CaseBB, + CasesBits[i].BB)); } - SelectionDAGISel::BitTestBlock BTB(lowBound, range, SV, - -1U, (CR.CaseBB == CurMBB), - CR.CaseBB, Default, BTC); + BitTestBlock BTB(lowBound, range, SV, + -1U, (CR.CaseBB == CurMBB), + CR.CaseBB, Default, BTC); if (CR.CaseBB == CurMBB) visitBitTestHeader(BTB); @@ -2906,7 +3028,7 @@ void SelectionDAGLowering::visitLoad(LoadInst &I) { if (I.isVolatile()) // Serialize volatile loads with other side effects. Root = getRoot(); - else if (AA.pointsToConstantMemory(SV)) { + else if (AA->pointsToConstantMemory(SV)) { // Do not serialize (non-volatile) loads of constant memory with anything. Root = DAG.getEntryNode(); ConstantMemory = true; @@ -3188,7 +3310,7 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) { uint64_t Size = -1ULL; if (ConstantSDNode *C = dyn_cast(Op3)) Size = C->getValue(); - if (AA.alias(I.getOperand(1), Size, I.getOperand(2), Size) == + if (AA->alias(I.getOperand(1), Size, I.getOperand(2), Size) == AliasAnalysis::NoAlias) { DAG.setRoot(DAG.getMemcpy(getRoot(), Op1, Op2, Op3, Align, false, I.getOperand(1), 0, I.getOperand(2), 0)); @@ -4885,6 +5007,22 @@ SDValue TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) { // SelectionDAGISel code //===----------------------------------------------------------------------===// +SelectionDAGISel::SelectionDAGISel(TargetLowering &tli, bool fast) : + FunctionPass((intptr_t)&ID), TLI(tli), + FuncInfo(new FunctionLoweringInfo(TLI)), + CurDAG(new SelectionDAG(TLI, *FuncInfo)), + SDL(new SelectionDAGLowering(*CurDAG, TLI, *FuncInfo)), + GFI(), + Fast(fast), + DAGSize(0) +{} + +SelectionDAGISel::~SelectionDAGISel() { + delete SDL; + delete CurDAG; + delete FuncInfo; +} + unsigned SelectionDAGISel::MakeReg(MVT VT) { return RegInfo->createVirtualRegister(TLI.getRegClassFor(VT)); } @@ -4907,28 +5045,32 @@ bool SelectionDAGISel::runOnFunction(Function &Fn) { RegInfo = &MF.getRegInfo(); DOUT << "\n\n\n=== " << Fn.getName() << "\n"; - FunctionLoweringInfo FuncInfo(TLI, Fn, MF); + FuncInfo->set(Fn, MF); + CurDAG->init(MF, getAnalysisToUpdate()); + SDL->init(GFI, *AA); for (Function::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I) if (InvokeInst *Invoke = dyn_cast(I->getTerminator())) // Mark landing pad. - FuncInfo.MBBMap[Invoke->getSuccessor(1)]->setIsLandingPad(); + FuncInfo->MBBMap[Invoke->getSuccessor(1)]->setIsLandingPad(); - SelectAllBasicBlocks(Fn, MF, FuncInfo); + SelectAllBasicBlocks(Fn, MF); // Add function live-ins to entry block live-in set. BasicBlock *EntryBB = &Fn.getEntryBlock(); - BB = FuncInfo.MBBMap[EntryBB]; + BB = FuncInfo->MBBMap[EntryBB]; 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 - assert(FuncInfo.CatchInfoFound.size() == FuncInfo.CatchInfoLost.size() && + assert(FuncInfo->CatchInfoFound.size() == FuncInfo->CatchInfoLost.size() && "Not all catch info was assigned to a landing pad!"); #endif + FuncInfo->clear(); + return true; } @@ -4946,13 +5088,12 @@ void SelectionDAGLowering::CopyValueToVirtualRegister(Value *V, unsigned Reg) { } void SelectionDAGISel:: -LowerArguments(BasicBlock *LLVMBB, SelectionDAGLowering &SDL) { +LowerArguments(BasicBlock *LLVMBB) { // If this is the entry block, emit arguments. Function &F = *LLVMBB->getParent(); - FunctionLoweringInfo &FuncInfo = SDL.FuncInfo; - SDValue OldRoot = SDL.DAG.getRoot(); + SDValue OldRoot = SDL->DAG.getRoot(); SmallVector Args; - TLI.LowerArguments(F, SDL.DAG, Args); + TLI.LowerArguments(F, SDL->DAG, Args); unsigned a = 0; for (Function::arg_iterator AI = F.arg_begin(), E = F.arg_end(); @@ -4961,12 +5102,12 @@ LowerArguments(BasicBlock *LLVMBB, SelectionDAGLowering &SDL) { ComputeValueVTs(TLI, AI->getType(), ValueVTs); unsigned NumValues = ValueVTs.size(); if (!AI->use_empty()) { - SDL.setValue(AI, SDL.DAG.getMergeValues(&Args[a], NumValues)); + SDL->setValue(AI, SDL->DAG.getMergeValues(&Args[a], NumValues)); // 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. - DenseMap::iterator VMI=FuncInfo.ValueMap.find(AI); - if (VMI != FuncInfo.ValueMap.end()) { - SDL.CopyValueToVirtualRegister(AI, VMI->second); + DenseMap::iterator VMI=FuncInfo->ValueMap.find(AI); + if (VMI != FuncInfo->ValueMap.end()) { + SDL->CopyValueToVirtualRegister(AI, VMI->second); } } a += NumValues; @@ -4974,7 +5115,7 @@ LowerArguments(BasicBlock *LLVMBB, SelectionDAGLowering &SDL) { // Finally, if the target has anything special to do, allow it to do so. // FIXME: this should insert code into the DAG! - EmitFunctionEntryCode(F, SDL.DAG.getMachineFunction()); + EmitFunctionEntryCode(F, SDL->DAG.getMachineFunction()); } static void copyCatchInfo(BasicBlock *SrcBB, BasicBlock *DestBB, @@ -5107,31 +5248,21 @@ static void CheckDAGForTailCallsAndFixThem(SelectionDAG &DAG, /// the end. /// void -SelectionDAGISel::HandlePHINodesInSuccessorBlocks(BasicBlock *LLVMBB, - FunctionLoweringInfo &FuncInfo, - std::vector > &PHINodesToUpdate, - SelectionDAGLowering &SDL) { +SelectionDAGISel::HandlePHINodesInSuccessorBlocks(BasicBlock *LLVMBB) { TerminatorInst *TI = LLVMBB->getTerminator(); - // Emit constants only once even if used by multiple PHI nodes. - std::map ConstantsOut; - - BitVector SuccsHandled; - if (TI->getNumSuccessors()) - SuccsHandled.resize(BB->getParent()->getNumBlockIDs()); - + SmallPtrSet SuccsHandled; + // Check successor nodes' PHI nodes that expect a constant to be available // from this block. for (unsigned succ = 0, e = TI->getNumSuccessors(); succ != e; ++succ) { BasicBlock *SuccBB = TI->getSuccessor(succ); if (!isa(SuccBB->begin())) continue; - MachineBasicBlock *SuccMBB = FuncInfo.MBBMap[SuccBB]; + MachineBasicBlock *SuccMBB = FuncInfo->MBBMap[SuccBB]; // If this terminator has multiple identical successors (common for // switches), only handle each succ once. - unsigned SuccMBBNo = SuccMBB->getNumber(); - if (SuccsHandled[SuccMBBNo]) continue; - SuccsHandled[SuccMBBNo] = true; + if (!SuccsHandled.insert(SuccMBB)) continue; MachineBasicBlock::iterator MBBI = SuccMBB->begin(); PHINode *PN; @@ -5143,25 +5274,25 @@ SelectionDAGISel::HandlePHINodesInSuccessorBlocks(BasicBlock *LLVMBB, (PN = dyn_cast(I)); ++I) { // Ignore dead phi's. if (PN->use_empty()) continue; - + unsigned Reg; Value *PHIOp = PN->getIncomingValueForBlock(LLVMBB); - + if (Constant *C = dyn_cast(PHIOp)) { - unsigned &RegOut = ConstantsOut[C]; + unsigned &RegOut = SDL->ConstantsOut[C]; if (RegOut == 0) { - RegOut = FuncInfo.CreateRegForValue(C); - SDL.CopyValueToVirtualRegister(C, RegOut); + RegOut = FuncInfo->CreateRegForValue(C); + SDL->CopyValueToVirtualRegister(C, RegOut); } Reg = RegOut; } else { - Reg = FuncInfo.ValueMap[PHIOp]; + Reg = FuncInfo->ValueMap[PHIOp]; if (Reg == 0) { assert(isa(PHIOp) && - FuncInfo.StaticAllocaMap.count(cast(PHIOp)) && + FuncInfo->StaticAllocaMap.count(cast(PHIOp)) && "Didn't codegen value into a register!??"); - Reg = FuncInfo.CreateRegForValue(PHIOp); - SDL.CopyValueToVirtualRegister(PHIOp, Reg); + Reg = FuncInfo->CreateRegForValue(PHIOp); + SDL->CopyValueToVirtualRegister(PHIOp, Reg); } } @@ -5173,39 +5304,26 @@ SelectionDAGISel::HandlePHINodesInSuccessorBlocks(BasicBlock *LLVMBB, MVT VT = ValueVTs[vti]; unsigned NumRegisters = TLI.getNumRegisters(VT); for (unsigned i = 0, e = NumRegisters; i != e; ++i) - PHINodesToUpdate.push_back(std::make_pair(MBBI++, Reg+i)); + SDL->PHINodesToUpdate.push_back(std::make_pair(MBBI++, Reg+i)); Reg += NumRegisters; } } } - ConstantsOut.clear(); + SDL->ConstantsOut.clear(); // Lower the terminator after the copies are emitted. - 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; - JTCases.clear(); - JTCases = SDL.JTCases; - BitTestCases.clear(); - BitTestCases = SDL.BitTestCases; + SDL->visit(*LLVMBB->getTerminator()); } void SelectionDAGISel::SelectBasicBlock(BasicBlock *LLVMBB, BasicBlock::iterator Begin, BasicBlock::iterator End, - bool DoArgs, - std::vector > &PHINodesToUpdate, - FunctionLoweringInfo &FuncInfo) { - SelectionDAGLowering SDL(*CurDAG, TLI, *AA, FuncInfo, GFI); - + bool DoArgs) { // Lower any arguments needed in this block if this is the entry block. if (DoArgs) - LowerArguments(LLVMBB, SDL); + LowerArguments(LLVMBB); - SDL.setCurrentBasicBlock(BB); + SDL->setCurrentBasicBlock(BB); MachineModuleInfo *MMI = CurDAG->getMachineModuleInfo(); @@ -5245,30 +5363,30 @@ void SelectionDAGISel::SelectBasicBlock(BasicBlock *LLVMBB, if (I == E) // No catch info found - try to extract some from the successor. - copyCatchInfo(Br->getSuccessor(0), LLVMBB, MMI, FuncInfo); + copyCatchInfo(Br->getSuccessor(0), LLVMBB, MMI, *FuncInfo); } } // Lower all of the non-terminator instructions. for (BasicBlock::iterator I = Begin; I != End; ++I) if (!isa(I)) - SDL.visit(*I); + SDL->visit(*I); // Ensure that all instructions which are used outside of their defining // blocks are available as virtual registers. Invoke is handled elsewhere. for (BasicBlock::iterator I = Begin; I != End; ++I) if (!I->use_empty() && !isa(I) && !isa(I)) { - DenseMap::iterator VMI =FuncInfo.ValueMap.find(I); - if (VMI != FuncInfo.ValueMap.end()) - SDL.CopyValueToVirtualRegister(I, VMI->second); + DenseMap::iterator VMI =FuncInfo->ValueMap.find(I); + if (VMI != FuncInfo->ValueMap.end()) + SDL->CopyValueToVirtualRegister(I, VMI->second); } // Handle PHI nodes in successor blocks. if (Begin != End && End == LLVMBB->end()) - HandlePHINodesInSuccessorBlocks(LLVMBB, FuncInfo, PHINodesToUpdate, SDL); + HandlePHINodesInSuccessorBlocks(LLVMBB); // Make sure the root of the DAG is up-to-date. - CurDAG->setRoot(SDL.getControlRoot()); + CurDAG->setRoot(SDL->getControlRoot()); // 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 @@ -5278,7 +5396,7 @@ void SelectionDAGISel::SelectBasicBlock(BasicBlock *LLVMBB, // Final step, emit the lowered DAG as machine code. CodeGenAndEmitDAG(); - CurDAG->reset(); + SDL->clear(); } void SelectionDAGISel::ComputeLiveOutVRegInfo() { @@ -5457,18 +5575,10 @@ void SelectionDAGISel::CodeGenAndEmitDAG() { DEBUG(BB->dump()); } -void SelectionDAGISel::SelectAllBasicBlocks(Function &Fn, MachineFunction &MF, - FunctionLoweringInfo &FuncInfo) { - // Define the SelectionDAG here so that memory allocation is reused for - // each basic block. - SelectionDAG DAG(TLI, MF, FuncInfo, - getAnalysisToUpdate()); - CurDAG = &DAG; - - std::vector > PHINodesToUpdate; +void SelectionDAGISel::SelectAllBasicBlocks(Function &Fn, MachineFunction &MF) { for (Function::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I) { BasicBlock *LLVMBB = &*I; - BB = FuncInfo.MBBMap[LLVMBB]; + BB = FuncInfo->MBBMap[LLVMBB]; BasicBlock::iterator Begin = LLVMBB->begin(); BasicBlock::iterator End = LLVMBB->end(); @@ -5477,10 +5587,10 @@ void SelectionDAGISel::SelectAllBasicBlocks(Function &Fn, MachineFunction &MF, // Before doing SelectionDAG ISel, see if FastISel has been requested. // FastISel doesn't support EH landing pads, which require special handling. if (EnableFastISel && !BB->isLandingPad()) { - if (FastISel *F = TLI.createFastISel(FuncInfo.MF)) { + if (FastISel *F = TLI.createFastISel(*FuncInfo->MF)) { while (Begin != End) { - Begin = F->SelectInstructions(Begin, End, FuncInfo.ValueMap, - FuncInfo.MBBMap, BB); + Begin = F->SelectInstructions(Begin, End, FuncInfo->ValueMap, + FuncInfo->MBBMap, BB); if (Begin == End) // The "fast" selector selected the entire block, so we're done. @@ -5490,13 +5600,12 @@ void SelectionDAGISel::SelectAllBasicBlocks(Function &Fn, MachineFunction &MF, if (isa(Begin) || isa(Begin) || isa(Begin)) { if (Begin->getType() != Type::VoidTy) { - unsigned &R = FuncInfo.ValueMap[Begin]; + unsigned &R = FuncInfo->ValueMap[Begin]; if (!R) - R = FuncInfo.CreateRegForValue(Begin); + R = FuncInfo->CreateRegForValue(Begin); } - SelectBasicBlock(LLVMBB, Begin, next(Begin), DoArgs, - PHINodesToUpdate, FuncInfo); + SelectBasicBlock(LLVMBB, Begin, next(Begin), DoArgs); ++Begin; DoArgs = false; @@ -5522,18 +5631,14 @@ void SelectionDAGISel::SelectAllBasicBlocks(Function &Fn, MachineFunction &MF, } if (Begin != End || DoArgs) - SelectBasicBlock(LLVMBB, Begin, End, DoArgs, PHINodesToUpdate, FuncInfo); + SelectBasicBlock(LLVMBB, Begin, End, DoArgs); - FinishBasicBlock(FuncInfo, PHINodesToUpdate); - PHINodesToUpdate.clear(); + FinishBasicBlock(); } - - CurDAG = 0; } void -SelectionDAGISel::FinishBasicBlock(FunctionLoweringInfo &FuncInfo, - std::vector > &PHINodesToUpdate) { +SelectionDAGISel::FinishBasicBlock() { // Perform target specific isel post processing. InstructionSelectPostProcessing(); @@ -5542,146 +5647,148 @@ SelectionDAGISel::FinishBasicBlock(FunctionLoweringInfo &FuncInfo, DEBUG(BB->dump()); 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";); + << SDL->PHINodesToUpdate.size() << "\n"; + DEBUG(for (unsigned i = 0, e = SDL->PHINodesToUpdate.size(); i != e; ++i) + DOUT << "Node " << i << " : (" << SDL->PHINodesToUpdate[i].first + << ", " << SDL->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() && JTCases.empty() && BitTestCases.empty()) { - for (unsigned i = 0, e = PHINodesToUpdate.size(); i != e; ++i) { - MachineInstr *PHI = PHINodesToUpdate[i].first; + if (SDL->SwitchCases.empty() && + SDL->JTCases.empty() && + SDL->BitTestCases.empty()) { + for (unsigned i = 0, e = SDL->PHINodesToUpdate.size(); i != e; ++i) { + MachineInstr *PHI = SDL->PHINodesToUpdate[i].first; assert(PHI->getOpcode() == TargetInstrInfo::PHI && "This is not a machine PHI node that we are updating!"); - PHI->addOperand(MachineOperand::CreateReg(PHINodesToUpdate[i].second, + PHI->addOperand(MachineOperand::CreateReg(SDL->PHINodesToUpdate[i].second, false)); PHI->addOperand(MachineOperand::CreateMBB(BB)); } + SDL->PHINodesToUpdate.clear(); return; } - for (unsigned i = 0, e = BitTestCases.size(); i != e; ++i) { + for (unsigned i = 0, e = SDL->BitTestCases.size(); i != e; ++i) { // Lower header first, if it wasn't already lowered - if (!BitTestCases[i].Emitted) { - SelectionDAGLowering HSDL(*CurDAG, TLI, *AA, FuncInfo, GFI); + if (!SDL->BitTestCases[i].Emitted) { // Set the current basic block to the mbb we wish to insert the code into - BB = BitTestCases[i].Parent; - HSDL.setCurrentBasicBlock(BB); + BB = SDL->BitTestCases[i].Parent; + SDL->setCurrentBasicBlock(BB); // Emit the code - HSDL.visitBitTestHeader(BitTestCases[i]); - CurDAG->setRoot(HSDL.getRoot()); + SDL->visitBitTestHeader(SDL->BitTestCases[i]); + CurDAG->setRoot(SDL->getRoot()); CodeGenAndEmitDAG(); - CurDAG->reset(); + SDL->clear(); } - for (unsigned j = 0, ej = BitTestCases[i].Cases.size(); j != ej; ++j) { - SelectionDAGLowering BSDL(*CurDAG, TLI, *AA, FuncInfo, GFI); + for (unsigned j = 0, ej = SDL->BitTestCases[i].Cases.size(); j != ej; ++j) { // Set the current basic block to the mbb we wish to insert the code into - BB = BitTestCases[i].Cases[j].ThisBB; - BSDL.setCurrentBasicBlock(BB); + BB = SDL->BitTestCases[i].Cases[j].ThisBB; + SDL->setCurrentBasicBlock(BB); // Emit the code if (j+1 != ej) - BSDL.visitBitTestCase(BitTestCases[i].Cases[j+1].ThisBB, - BitTestCases[i].Reg, - BitTestCases[i].Cases[j]); + SDL->visitBitTestCase(SDL->BitTestCases[i].Cases[j+1].ThisBB, + SDL->BitTestCases[i].Reg, + SDL->BitTestCases[i].Cases[j]); else - BSDL.visitBitTestCase(BitTestCases[i].Default, - BitTestCases[i].Reg, - BitTestCases[i].Cases[j]); + SDL->visitBitTestCase(SDL->BitTestCases[i].Default, + SDL->BitTestCases[i].Reg, + SDL->BitTestCases[i].Cases[j]); - CurDAG->setRoot(BSDL.getRoot()); + CurDAG->setRoot(SDL->getRoot()); CodeGenAndEmitDAG(); - CurDAG->reset(); + SDL->clear(); } // Update PHI Nodes - for (unsigned pi = 0, pe = PHINodesToUpdate.size(); pi != pe; ++pi) { - MachineInstr *PHI = PHINodesToUpdate[pi].first; + for (unsigned pi = 0, pe = SDL->PHINodesToUpdate.size(); pi != pe; ++pi) { + MachineInstr *PHI = SDL->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->addOperand(MachineOperand::CreateReg(PHINodesToUpdate[pi].second, + if (PHIBB == SDL->BitTestCases[i].Default) { + PHI->addOperand(MachineOperand::CreateReg(SDL->PHINodesToUpdate[pi].second, false)); - PHI->addOperand(MachineOperand::CreateMBB(BitTestCases[i].Parent)); - PHI->addOperand(MachineOperand::CreateReg(PHINodesToUpdate[pi].second, + PHI->addOperand(MachineOperand::CreateMBB(SDL->BitTestCases[i].Parent)); + PHI->addOperand(MachineOperand::CreateReg(SDL->PHINodesToUpdate[pi].second, false)); - PHI->addOperand(MachineOperand::CreateMBB(BitTestCases[i].Cases. + PHI->addOperand(MachineOperand::CreateMBB(SDL->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; + for (unsigned j = 0, ej = SDL->BitTestCases[i].Cases.size(); + j != ej; ++j) { + MachineBasicBlock* cBB = SDL->BitTestCases[i].Cases[j].ThisBB; if (cBB->succ_end() != std::find(cBB->succ_begin(),cBB->succ_end(), PHIBB)) { - PHI->addOperand(MachineOperand::CreateReg(PHINodesToUpdate[pi].second, + PHI->addOperand(MachineOperand::CreateReg(SDL->PHINodesToUpdate[pi].second, false)); PHI->addOperand(MachineOperand::CreateMBB(cBB)); } } } } + SDL->BitTestCases.clear(); // 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 - for (unsigned i = 0, e = JTCases.size(); i != e; ++i) { + for (unsigned i = 0, e = SDL->JTCases.size(); i != e; ++i) { // Lower header first, if it wasn't already lowered - if (!JTCases[i].first.Emitted) { - SelectionDAGLowering HSDL(*CurDAG, TLI, *AA, FuncInfo, GFI); + if (!SDL->JTCases[i].first.Emitted) { // Set the current basic block to the mbb we wish to insert the code into - BB = JTCases[i].first.HeaderBB; - HSDL.setCurrentBasicBlock(BB); + BB = SDL->JTCases[i].first.HeaderBB; + SDL->setCurrentBasicBlock(BB); // Emit the code - HSDL.visitJumpTableHeader(JTCases[i].second, JTCases[i].first); - CurDAG->setRoot(HSDL.getRoot()); + SDL->visitJumpTableHeader(SDL->JTCases[i].second, SDL->JTCases[i].first); + CurDAG->setRoot(SDL->getRoot()); CodeGenAndEmitDAG(); - CurDAG->reset(); + SDL->clear(); } - SelectionDAGLowering JSDL(*CurDAG, TLI, *AA, FuncInfo, GFI); // Set the current basic block to the mbb we wish to insert the code into - BB = JTCases[i].second.MBB; - JSDL.setCurrentBasicBlock(BB); + BB = SDL->JTCases[i].second.MBB; + SDL->setCurrentBasicBlock(BB); // Emit the code - JSDL.visitJumpTable(JTCases[i].second); - CurDAG->setRoot(JSDL.getRoot()); + SDL->visitJumpTable(SDL->JTCases[i].second); + CurDAG->setRoot(SDL->getRoot()); CodeGenAndEmitDAG(); - CurDAG->reset(); + SDL->clear(); // Update PHI Nodes - for (unsigned pi = 0, pe = PHINodesToUpdate.size(); pi != pe; ++pi) { - MachineInstr *PHI = PHINodesToUpdate[pi].first; + for (unsigned pi = 0, pe = SDL->PHINodesToUpdate.size(); pi != pe; ++pi) { + MachineInstr *PHI = SDL->PHINodesToUpdate[pi].first; MachineBasicBlock *PHIBB = PHI->getParent(); assert(PHI->getOpcode() == TargetInstrInfo::PHI && "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->addOperand(MachineOperand::CreateReg(PHINodesToUpdate[pi].second, + if (PHIBB == SDL->JTCases[i].second.Default) { + PHI->addOperand(MachineOperand::CreateReg(SDL->PHINodesToUpdate[pi].second, false)); - PHI->addOperand(MachineOperand::CreateMBB(JTCases[i].first.HeaderBB)); + PHI->addOperand(MachineOperand::CreateMBB(SDL->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->addOperand(MachineOperand::CreateReg(PHINodesToUpdate[pi].second, + PHI->addOperand(MachineOperand::CreateReg(SDL->PHINodesToUpdate[pi].second, false)); PHI->addOperand(MachineOperand::CreateMBB(BB)); } } } + SDL->JTCases.clear(); // If the switch block involved a branch to one of the actual successors, we // need to update PHI nodes in that block. - for (unsigned i = 0, e = PHINodesToUpdate.size(); i != e; ++i) { - MachineInstr *PHI = PHINodesToUpdate[i].first; + for (unsigned i = 0, e = SDL->PHINodesToUpdate.size(); i != e; ++i) { + MachineInstr *PHI = SDL->PHINodesToUpdate[i].first; assert(PHI->getOpcode() == TargetInstrInfo::PHI && "This is not a machine PHI node that we are updating!"); if (BB->isSuccessor(PHI->getParent())) { - PHI->addOperand(MachineOperand::CreateReg(PHINodesToUpdate[i].second, + PHI->addOperand(MachineOperand::CreateReg(SDL->PHINodesToUpdate[i].second, false)); PHI->addOperand(MachineOperand::CreateMBB(BB)); } @@ -5689,48 +5796,50 @@ SelectionDAGISel::FinishBasicBlock(FunctionLoweringInfo &FuncInfo, // If we generated any switch lowering information, build and codegen any // additional DAGs necessary. - for (unsigned i = 0, e = SwitchCases.size(); i != e; ++i) { - SelectionDAGLowering SDL(*CurDAG, TLI, *AA, FuncInfo, GFI); - + for (unsigned i = 0, e = SDL->SwitchCases.size(); i != e; ++i) { // Set the current basic block to the mbb we wish to insert the code into - BB = SwitchCases[i].ThisBB; - SDL.setCurrentBasicBlock(BB); + BB = SDL->SwitchCases[i].ThisBB; + SDL->setCurrentBasicBlock(BB); // Emit the code - SDL.visitSwitchCase(SwitchCases[i]); - CurDAG->setRoot(SDL.getRoot()); + SDL->visitSwitchCase(SDL->SwitchCases[i]); + CurDAG->setRoot(SDL->getRoot()); CodeGenAndEmitDAG(); - CurDAG->reset(); + SDL->clear(); // Handle any PHI nodes in successors of this chunk, as if we were coming // from the original BB before switch expansion. Note that PHI nodes can // occur multiple times in PHINodesToUpdate. We have to be very careful to // handle them the right number of times. - while ((BB = SwitchCases[i].TrueBB)) { // Handle LHS and RHS. + while ((BB = SDL->SwitchCases[i].TrueBB)) { // Handle LHS and RHS. for (MachineBasicBlock::iterator Phi = BB->begin(); Phi != BB->end() && Phi->getOpcode() == TargetInstrInfo::PHI; ++Phi){ // This value for this PHI node is recorded in PHINodesToUpdate, get it. for (unsigned pn = 0; ; ++pn) { - assert(pn != PHINodesToUpdate.size() && "Didn't find PHI entry!"); - if (PHINodesToUpdate[pn].first == Phi) { - Phi->addOperand(MachineOperand::CreateReg(PHINodesToUpdate[pn]. + assert(pn != SDL->PHINodesToUpdate.size() && + "Didn't find PHI entry!"); + if (SDL->PHINodesToUpdate[pn].first == Phi) { + Phi->addOperand(MachineOperand::CreateReg(SDL->PHINodesToUpdate[pn]. second, false)); - Phi->addOperand(MachineOperand::CreateMBB(SwitchCases[i].ThisBB)); + Phi->addOperand(MachineOperand::CreateMBB(SDL->SwitchCases[i].ThisBB)); break; } } } // Don't process RHS if same block as LHS. - if (BB == SwitchCases[i].FalseBB) - SwitchCases[i].FalseBB = 0; + if (BB == SDL->SwitchCases[i].FalseBB) + SDL->SwitchCases[i].FalseBB = 0; // If we haven't handled the RHS, do so now. Otherwise, we're done. - SwitchCases[i].TrueBB = SwitchCases[i].FalseBB; - SwitchCases[i].FalseBB = 0; + SDL->SwitchCases[i].TrueBB = SDL->SwitchCases[i].FalseBB; + SDL->SwitchCases[i].FalseBB = 0; } - assert(SwitchCases[i].TrueBB == 0 && SwitchCases[i].FalseBB == 0); + assert(SDL->SwitchCases[i].TrueBB == 0 && SDL->SwitchCases[i].FalseBB == 0); } + SDL->SwitchCases.clear(); + + SDL->PHINodesToUpdate.clear(); }