diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h index a19765a644c..01aba3f9853 100644 --- a/include/llvm/CodeGen/SelectionDAG.h +++ b/include/llvm/CodeGen/SelectionDAG.h @@ -36,13 +36,6 @@ class MachineFunction; class MachineConstantPoolValue; class FunctionLoweringInfo; -/// NodeAllocatorType - The AllocatorType for allocating SDNodes. We use -/// pool allocation with recycling. -/// -typedef RecyclingAllocator::Alignment> - NodeAllocatorType; - template<> class ilist_traits : public ilist_default_traits { mutable SDNode Sentinel; public: @@ -77,21 +70,31 @@ class SelectionDAG { FunctionLoweringInfo &FLI; MachineModuleInfo *MMI; - /// Root - The root of the entire DAG. EntryNode - The starting token. - SDValue Root, EntryNode; + /// EntryNode - The starting token. + SDNode EntryNode; + + /// Root - The root of the entire DAG. + SDValue Root; /// AllNodes - A linked list of nodes in the current DAG. ilist AllNodes; - /// NodeAllocator - Pool allocation for nodes. The allocator isn't - /// allocated inside this class because we want to reuse a single - /// recycler across multiple SelectionDAG runs. - NodeAllocatorType &NodeAllocator; + /// NodeAllocatorType - The AllocatorType for allocating SDNodes. We use + /// pool allocation with recycling. + typedef RecyclingAllocator::Alignment> + NodeAllocatorType; + + /// NodeAllocator - Pool allocation for nodes. + NodeAllocatorType NodeAllocator; /// CSEMap - This structure is used to memoize nodes, automatically performing /// CSE with existing nodes with a duplicate is requested. FoldingSet CSEMap; + /// OperandAllocator - Pool allocation for machine-opcode SDNode operands. + BumpPtrAllocator OperandAllocator; + /// Allocator - Pool allocation for misc. objects that are created once per /// SelectionDAG. BumpPtrAllocator Allocator; @@ -101,10 +104,14 @@ class SelectionDAG { public: SelectionDAG(TargetLowering &tli, MachineFunction &mf, - FunctionLoweringInfo &fli, MachineModuleInfo *mmi, - NodeAllocatorType &nodeallocator); + FunctionLoweringInfo &fli, MachineModuleInfo *mmi); ~SelectionDAG(); + /// reset - Clear state and free memory necessary to make this + /// SelectionDAG ready to process a new block. + /// + void reset(); + MachineFunction &getMachineFunction() const { return MF; } const TargetMachine &getTarget() const; TargetLowering &getTargetLoweringInfo() const { return TLI; } @@ -152,7 +159,9 @@ public: /// getEntryNode - Return the token chain corresponding to the entry of the /// function. - const SDValue &getEntryNode() const { return EntryNode; } + SDValue getEntryNode() const { + return SDValue(const_cast(&EntryNode), 0); + } /// setRoot - Set the current root tag of the SelectionDAG. /// @@ -721,6 +730,8 @@ private: void DeleteNodeNotInCSEMaps(SDNode *N); unsigned getMVTAlignment(MVT MemoryVT) const; + + void allnodes_clear(); // List of non-single value types. std::vector VTList; diff --git a/include/llvm/CodeGen/SelectionDAGISel.h b/include/llvm/CodeGen/SelectionDAGISel.h index 951efe1975f..64c3b25591a 100644 --- a/include/llvm/CodeGen/SelectionDAGISel.h +++ b/include/llvm/CodeGen/SelectionDAGISel.h @@ -15,6 +15,7 @@ #ifndef LLVM_CODEGEN_SELECTIONDAG_ISEL_H #define LLVM_CODEGEN_SELECTIONDAG_ISEL_H +#include "llvm/BasicBlock.h" #include "llvm/Pass.h" #include "llvm/Constant.h" #include "llvm/CodeGen/SelectionDAG.h" @@ -58,7 +59,7 @@ public: unsigned MakeReg(MVT VT); virtual void EmitFunctionEntryCode(Function &Fn, MachineFunction &MF) {} - virtual void InstructionSelect(SelectionDAG &SD) = 0; + virtual void InstructionSelect() = 0; virtual void InstructionSelectPostProcessing() {} void SelectRootInit() { @@ -72,8 +73,7 @@ public: /// OutOps vector. virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode, - std::vector &OutOps, - SelectionDAG &DAG) { + std::vector &OutOps) { return true; } @@ -168,8 +168,7 @@ protected: /// SelectInlineAsmMemoryOperands - Calls to this are automatically generated /// by tblgen. Others should not call it. - void SelectInlineAsmMemoryOperands(std::vector &Ops, - SelectionDAG &DAG); + void SelectInlineAsmMemoryOperands(std::vector &Ops); // Calls to these predicates are generated by tblgen. bool CheckAndMask(SDValue LHS, ConstantSDNode *RHS, @@ -180,26 +179,28 @@ protected: private: void SelectAllBasicBlocks(Function &Fn, MachineFunction &MF, FunctionLoweringInfo &FuncInfo); - void SelectBasicBlock(BasicBlock *BB, MachineFunction &MF, - FunctionLoweringInfo &FuncInfo, - std::vector > &PHINodesToUpdate, - NodeAllocatorType &NodeAllocator); - void FinishBasicBlock(BasicBlock *BB, MachineFunction &MF, - FunctionLoweringInfo &FuncInfo, - std::vector > &PHINodesToUpdate, - NodeAllocatorType &NodeAllocator); + void FinishBasicBlock(FunctionLoweringInfo &FuncInfo, + std::vector > &PHINodesToUpdate); - void BuildSelectionDAG(SelectionDAG &DAG, BasicBlock *LLVMBB, + void SelectBasicBlock(BasicBlock *LLVMBB, + BasicBlock::iterator Begin, + BasicBlock::iterator End, + bool DoArgs, std::vector > &PHINodesToUpdate, - FunctionLoweringInfo &FuncInfo); - void CodeGenAndEmitDAG(SelectionDAG &DAG); + FunctionLoweringInfo &FuncInfo); + void CodeGenAndEmitDAG(); void LowerArguments(BasicBlock *BB, SelectionDAGLowering &SDL); - void ComputeLiveOutVRegInfo(SelectionDAG &DAG); + void ComputeLiveOutVRegInfo(); + + void HandlePHINodesInSuccessorBlocks(BasicBlock *LLVMBB, + FunctionLoweringInfo &FuncInfo, + std::vector > &PHINodesToUpdate, + SelectionDAGLowering &SDL); /// Pick a safe ordering for instructions for each target node in the /// graph. - ScheduleDAG *Schedule(SelectionDAG &DAG); + ScheduleDAG *Schedule(); /// SwitchCases - Vector of CaseBlock structures used to communicate /// SwitchInst code generation information. diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 3e3890142f5..9275a21f9fb 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -547,11 +547,8 @@ void SelectionDAG::DeleteNodeNotInCSEMaps(SDNode *N) { // Drop all of the operands and decrement used nodes use counts. for (SDNode::op_iterator I = N->op_begin(), E = N->op_end(); I != E; ++I) I->getVal()->removeUser(std::distance(N->op_begin(), I), N); - if (N->OperandsNeedDelete) { + if (N->OperandsNeedDelete) delete[] N->OperandList; - } - N->OperandList = 0; - N->NumOperands = 0; AllNodes.remove(N); } @@ -563,6 +560,9 @@ void SelectionDAG::DeleteNodeNotInCSEMaps(SDNode *N) { void SelectionDAG::RemoveNodeFromCSEMaps(SDNode *N) { bool Erased = false; switch (N->getOpcode()) { + case ISD::EntryToken: + assert(0 && "EntryToken should not be in CSEMaps!"); + return; case ISD::HANDLENODE: return; // noop. case ISD::CONDCODE: assert(CondCodeNodes[cast(N)->get()] && @@ -764,24 +764,44 @@ unsigned SelectionDAG::getMVTAlignment(MVT VT) const { } SelectionDAG::SelectionDAG(TargetLowering &tli, MachineFunction &mf, - FunctionLoweringInfo &fli, MachineModuleInfo *mmi, - NodeAllocatorType &nodeallocator) - : TLI(tli), MF(mf), FLI(fli), MMI(mmi), NodeAllocator(nodeallocator) { - EntryNode = Root = getNode(ISD::EntryToken, MVT::Other); + FunctionLoweringInfo &fli, MachineModuleInfo *mmi) + : TLI(tli), MF(mf), FLI(fli), MMI(mmi), + EntryNode(ISD::EntryToken, getVTList(MVT::Other)), + Root(getEntryNode()) { + AllNodes.push_back(&EntryNode); } SelectionDAG::~SelectionDAG() { + allnodes_clear(); +} + +void SelectionDAG::allnodes_clear() { while (!AllNodes.empty()) { SDNode *N = AllNodes.remove(AllNodes.begin()); N->SetNextInBucket(0); - if (N->OperandsNeedDelete) { + if (N->OperandsNeedDelete) delete [] N->OperandList; - } - N->OperandList = 0; - N->NumOperands = 0; } } +void SelectionDAG::reset() { + allnodes_clear(); + OperandAllocator.Reset(); + CSEMap.clear(); + + ExtendedValueTypeNodes.clear(); + ExternalSymbols.clear(); + TargetExternalSymbols.clear(); + std::fill(CondCodeNodes.begin(), CondCodeNodes.end(), + static_cast(0)); + std::fill(ValueTypeNodes.begin(), ValueTypeNodes.end(), + static_cast(0)); + + EntryNode.Uses = 0; + AllNodes.push_back(&EntryNode); + Root = getEntryNode(); +} + SDValue SelectionDAG::getZeroExtendInReg(SDValue Op, MVT VT) { if (Op.getValueType() == VT) return Op; APInt Imm = APInt::getLowBitsSet(Op.getValueSizeInBits(), @@ -3988,9 +4008,9 @@ SDNode *SelectionDAG::MorphNodeTo(SDNode *N, unsigned Opc, delete[] N->OperandList; if (N->isMachineOpcode()) { // We're creating a final node that will live unmorphed for the - // remainder of this SelectionDAG's duration, so we can allocate the - // operands directly out of the pool with no recycling metadata. - N->OperandList = Allocator.Allocate(NumOps); + // remainder of the current SelectionDAG iteration, so we can allocate + // the operands directly out of a pool with no recycling metadata. + N->OperandList = OperandAllocator.Allocate(NumOps); N->OperandsNeedDelete = false; } else { N->OperandList = new SDUse[NumOps]; diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 147f45c8b53..e789c4e41c1 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -394,6 +394,11 @@ static bool isUsedOutsideOfDefiningBlock(Instruction *I) { /// entry block, return true. This includes arguments used by switches, since /// the switch may expand into multiple basic blocks. static bool isOnlyUsedInEntryBlock(Argument *A) { + // With FastISel active, we may be splitting blocks, so force creation + // of virtual registers for all non-dead arguments. + if (EnableFastISel) + return A->use_empty(); + BasicBlock *Entry = A->getParent()->begin(); for (Value::use_iterator UI = A->use_begin(), E = A->use_end(); UI != E; ++UI) if (cast(*UI)->getParent() != Entry || isa(*UI)) @@ -5094,119 +5099,18 @@ static void CheckDAGForTailCallsAndFixThem(SelectionDAG &DAG, } } -void SelectionDAGISel::BuildSelectionDAG(SelectionDAG &DAG, BasicBlock *LLVMBB, - std::vector > &PHINodesToUpdate, - FunctionLoweringInfo &FuncInfo) { - SelectionDAGLowering SDL(DAG, TLI, *AA, FuncInfo, GFI); - BB = FuncInfo.MBBMap[LLVMBB]; - - // Before doing SelectionDAG ISel, see if FastISel has been requested. - // FastISel doesn't currently support entry blocks, because that - // requires special handling for arguments. And it doesn't support EH - // landing pads, which also require special handling. - // For now, also exclude blocks with terminators that aren't - // unconditional branches. - BasicBlock::iterator Begin = LLVMBB->begin(); - if (EnableFastISel && - LLVMBB != &LLVMBB->getParent()->getEntryBlock() && - !BB->isLandingPad() && - isa(LLVMBB->getTerminator()) && - cast(LLVMBB->getTerminator())->isUnconditional()) { - if (FastISel *F = TLI.createFastISel(FuncInfo.MF)) { - Begin = F->SelectInstructions(Begin, LLVMBB->end(), - FuncInfo.ValueMap, FuncInfo.MBBMap, BB); - - // Clean up the FastISel object. TODO: Reorganize what data is - // stored in the FastISel class itself and what is merely passed - // to the SelectInstructions method, and then move the creation - // and deletion of the FastISel object up so that it is only - // done once per MachineFunction. - delete F; - - if (Begin == LLVMBB->end()) - // The "fast" selector selected the entire block, so we're done. - return; - - if (!DisableFastISelAbort) { - // The "fast" selector couldn't handle something and bailed. - // For the purpose of debugging, just abort. -#ifndef NDEBUG - Begin->dump(); -#endif - assert(0 && "FastISel didn't select the entire block"); - abort(); - } - } - } - - // Lower any arguments needed in this block if this is the entry block. - if (LLVMBB == &LLVMBB->getParent()->getEntryBlock()) - LowerArguments(LLVMBB, SDL); - - SDL.setCurrentBasicBlock(BB); - - MachineModuleInfo *MMI = DAG.getMachineModuleInfo(); - - if (MMI && BB->isLandingPad()) { - // Add a label to mark the beginning of the landing pad. Deletion of the - // landing pad can thus be detected via the MachineModuleInfo. - unsigned LabelID = MMI->addLandingPad(BB); - DAG.setRoot(DAG.getLabel(ISD::EH_LABEL, DAG.getEntryNode(), LabelID)); - - // Mark exception register as live in. - unsigned Reg = TLI.getExceptionAddressRegister(); - if (Reg) BB->addLiveIn(Reg); - - // Mark exception selector register as live in. - Reg = TLI.getExceptionSelectorRegister(); - if (Reg) BB->addLiveIn(Reg); - - // FIXME: Hack around an exception handling flaw (PR1508): the personality - // function and list of typeids logically belong to the invoke (or, if you - // like, the basic block containing the invoke), and need to be associated - // with it in the dwarf exception handling tables. Currently however the - // information is provided by an intrinsic (eh.selector) that can be moved - // to unexpected places by the optimizers: if the unwind edge is critical, - // then breaking it can result in the intrinsics being in the successor of - // the landing pad, not the landing pad itself. This results in exceptions - // not being caught because no typeids are associated with the invoke. - // This may not be the only way things can go wrong, but it is the only way - // we try to work around for the moment. - BranchInst *Br = dyn_cast(LLVMBB->getTerminator()); - - if (Br && Br->isUnconditional()) { // Critical edge? - BasicBlock::iterator I, E; - for (I = LLVMBB->begin(), E = --LLVMBB->end(); I != E; ++I) - if (isSelector(I)) - break; - - if (I == E) - // No catch info found - try to extract some from the successor. - copyCatchInfo(Br->getSuccessor(0), LLVMBB, MMI, FuncInfo); - } - } - - // Lower all of the non-terminator instructions. - for (BasicBlock::iterator I = Begin, E = --LLVMBB->end(); - I != E; ++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, E = LLVMBB->end(); I != E;++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); - } - - // Handle PHI nodes in successor blocks. Emit code into the SelectionDAG to - // ensure constants are generated when needed. Remember the virtual registers - // that need to be added to the Machine PHI nodes as input. We cannot just - // directly add them, because expansion might result in multiple MBB's for one - // BB. As such, the start of the BB might correspond to a different MBB than - // the end. - // +/// Handle PHI nodes in successor blocks. Emit code into the SelectionDAG to +/// ensure constants are generated when needed. Remember the virtual registers +/// that need to be added to the Machine PHI nodes as input. We cannot just +/// directly add them, because expansion might result in multiple MBB's for one +/// BB. As such, the start of the BB might correspond to a different MBB than +/// the end. +/// +void +SelectionDAGISel::HandlePHINodesInSuccessorBlocks(BasicBlock *LLVMBB, + FunctionLoweringInfo &FuncInfo, + std::vector > &PHINodesToUpdate, + SelectionDAGLowering &SDL) { TerminatorInst *TI = LLVMBB->getTerminator(); // Emit constants only once even if used by multiple PHI nodes. @@ -5287,22 +5191,101 @@ void SelectionDAGISel::BuildSelectionDAG(SelectionDAG &DAG, BasicBlock *LLVMBB, JTCases = SDL.JTCases; BitTestCases.clear(); BitTestCases = SDL.BitTestCases; +} + +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); + + // Lower any arguments needed in this block if this is the entry block. + if (DoArgs) + LowerArguments(LLVMBB, SDL); + + SDL.setCurrentBasicBlock(BB); + + MachineModuleInfo *MMI = CurDAG->getMachineModuleInfo(); + + if (MMI && BB->isLandingPad()) { + // Add a label to mark the beginning of the landing pad. Deletion of the + // landing pad can thus be detected via the MachineModuleInfo. + unsigned LabelID = MMI->addLandingPad(BB); + CurDAG->setRoot(CurDAG->getLabel(ISD::EH_LABEL, + CurDAG->getEntryNode(), LabelID)); + + // Mark exception register as live in. + unsigned Reg = TLI.getExceptionAddressRegister(); + if (Reg) BB->addLiveIn(Reg); + + // Mark exception selector register as live in. + Reg = TLI.getExceptionSelectorRegister(); + if (Reg) BB->addLiveIn(Reg); + + // FIXME: Hack around an exception handling flaw (PR1508): the personality + // function and list of typeids logically belong to the invoke (or, if you + // like, the basic block containing the invoke), and need to be associated + // with it in the dwarf exception handling tables. Currently however the + // information is provided by an intrinsic (eh.selector) that can be moved + // to unexpected places by the optimizers: if the unwind edge is critical, + // then breaking it can result in the intrinsics being in the successor of + // the landing pad, not the landing pad itself. This results in exceptions + // not being caught because no typeids are associated with the invoke. + // This may not be the only way things can go wrong, but it is the only way + // we try to work around for the moment. + BranchInst *Br = dyn_cast(LLVMBB->getTerminator()); + + if (Br && Br->isUnconditional()) { // Critical edge? + BasicBlock::iterator I, E; + for (I = LLVMBB->begin(), E = --LLVMBB->end(); I != E; ++I) + if (isSelector(I)) + break; + + if (I == E) + // No catch info found - try to extract some from the successor. + 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); + + // 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); + } + + // Handle PHI nodes in successor blocks. + if (Begin != End && End == LLVMBB->end()) + HandlePHINodesInSuccessorBlocks(LLVMBB, FuncInfo, PHINodesToUpdate, SDL); // Make sure the root of the DAG is up-to-date. - DAG.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 // attribute indicating whether the call is really eligible for tail call // optimization. - CheckDAGForTailCallsAndFixThem(DAG, TLI); + CheckDAGForTailCallsAndFixThem(*CurDAG, TLI); + + // Final step, emit the lowered DAG as machine code. + CodeGenAndEmitDAG(); + CurDAG->reset(); } -void SelectionDAGISel::ComputeLiveOutVRegInfo(SelectionDAG &DAG) { +void SelectionDAGISel::ComputeLiveOutVRegInfo() { SmallPtrSet VisitedNodes; SmallVector Worklist; - Worklist.push_back(DAG.getRoot().Val); + Worklist.push_back(CurDAG->getRoot().Val); APInt Mask; APInt KnownZero; @@ -5335,14 +5318,14 @@ void SelectionDAGISel::ComputeLiveOutVRegInfo(SelectionDAG &DAG) { if (!SrcVT.isInteger() || SrcVT.isVector()) continue; - unsigned NumSignBits = DAG.ComputeNumSignBits(Src); + unsigned NumSignBits = CurDAG->ComputeNumSignBits(Src); Mask = APInt::getAllOnesValue(SrcVT.getSizeInBits()); - DAG.ComputeMaskedBits(Src, Mask, KnownZero, KnownOne); + CurDAG->ComputeMaskedBits(Src, Mask, KnownZero, KnownOne); // Only install this information if it tells us something. if (NumSignBits != 1 || KnownZero != 0 || KnownOne != 0) { DestReg -= TargetRegisterInfo::FirstVirtualRegister; - FunctionLoweringInfo &FLI = DAG.getFunctionLoweringInfo(); + FunctionLoweringInfo &FLI = CurDAG->getFunctionLoweringInfo(); if (DestReg >= FLI.LiveOutRegInfo.size()) FLI.LiveOutRegInfo.resize(DestReg+1); FunctionLoweringInfo::LiveOutInfo &LOI = FLI.LiveOutRegInfo[DestReg]; @@ -5353,102 +5336,102 @@ void SelectionDAGISel::ComputeLiveOutVRegInfo(SelectionDAG &DAG) { } } -void SelectionDAGISel::CodeGenAndEmitDAG(SelectionDAG &DAG) { +void SelectionDAGISel::CodeGenAndEmitDAG() { std::string GroupName; if (TimePassesIsEnabled) GroupName = "Instruction Selection and Scheduling"; std::string BlockName; if (ViewDAGCombine1 || ViewLegalizeTypesDAGs || ViewLegalizeDAGs || ViewDAGCombine2 || ViewISelDAGs || ViewSchedDAGs || ViewSUnitDAGs) - BlockName = DAG.getMachineFunction().getFunction()->getName() + ':' + + BlockName = CurDAG->getMachineFunction().getFunction()->getName() + ':' + BB->getBasicBlock()->getName(); DOUT << "Initial selection DAG:\n"; - DEBUG(DAG.dump()); + DEBUG(CurDAG->dump()); - if (ViewDAGCombine1) DAG.viewGraph("dag-combine1 input for " + BlockName); + if (ViewDAGCombine1) CurDAG->viewGraph("dag-combine1 input for " + BlockName); // Run the DAG combiner in pre-legalize mode. if (TimePassesIsEnabled) { NamedRegionTimer T("DAG Combining 1", GroupName); - DAG.Combine(false, *AA, Fast); + CurDAG->Combine(false, *AA, Fast); } else { - DAG.Combine(false, *AA, Fast); + CurDAG->Combine(false, *AA, Fast); } DOUT << "Optimized lowered selection DAG:\n"; - DEBUG(DAG.dump()); + DEBUG(CurDAG->dump()); // Second step, hack on the DAG until it only uses operations and types that // the target supports. if (EnableLegalizeTypes) {// Enable this some day. - if (ViewLegalizeTypesDAGs) DAG.viewGraph("legalize-types input for " + - BlockName); + if (ViewLegalizeTypesDAGs) CurDAG->viewGraph("legalize-types input for " + + BlockName); if (TimePassesIsEnabled) { NamedRegionTimer T("Type Legalization", GroupName); - DAG.LegalizeTypes(); + CurDAG->LegalizeTypes(); } else { - DAG.LegalizeTypes(); + CurDAG->LegalizeTypes(); } DOUT << "Type-legalized selection DAG:\n"; - DEBUG(DAG.dump()); + DEBUG(CurDAG->dump()); // TODO: enable a dag combine pass here. } - if (ViewLegalizeDAGs) DAG.viewGraph("legalize input for " + BlockName); + if (ViewLegalizeDAGs) CurDAG->viewGraph("legalize input for " + BlockName); if (TimePassesIsEnabled) { NamedRegionTimer T("DAG Legalization", GroupName); - DAG.Legalize(); + CurDAG->Legalize(); } else { - DAG.Legalize(); + CurDAG->Legalize(); } DOUT << "Legalized selection DAG:\n"; - DEBUG(DAG.dump()); + DEBUG(CurDAG->dump()); - if (ViewDAGCombine2) DAG.viewGraph("dag-combine2 input for " + BlockName); + if (ViewDAGCombine2) CurDAG->viewGraph("dag-combine2 input for " + BlockName); // Run the DAG combiner in post-legalize mode. if (TimePassesIsEnabled) { NamedRegionTimer T("DAG Combining 2", GroupName); - DAG.Combine(true, *AA, Fast); + CurDAG->Combine(true, *AA, Fast); } else { - DAG.Combine(true, *AA, Fast); + CurDAG->Combine(true, *AA, Fast); } DOUT << "Optimized legalized selection DAG:\n"; - DEBUG(DAG.dump()); + DEBUG(CurDAG->dump()); - if (ViewISelDAGs) DAG.viewGraph("isel input for " + BlockName); + if (ViewISelDAGs) CurDAG->viewGraph("isel input for " + BlockName); if (!Fast && EnableValueProp) - ComputeLiveOutVRegInfo(DAG); + ComputeLiveOutVRegInfo(); // Third, instruction select all of the operations to machine code, adding the // code to the MachineBasicBlock. if (TimePassesIsEnabled) { NamedRegionTimer T("Instruction Selection", GroupName); - InstructionSelect(DAG); + InstructionSelect(); } else { - InstructionSelect(DAG); + InstructionSelect(); } DOUT << "Selected selection DAG:\n"; - DEBUG(DAG.dump()); + DEBUG(CurDAG->dump()); - if (ViewSchedDAGs) DAG.viewGraph("scheduler input for " + BlockName); + if (ViewSchedDAGs) CurDAG->viewGraph("scheduler input for " + BlockName); // Schedule machine code. ScheduleDAG *Scheduler; if (TimePassesIsEnabled) { NamedRegionTimer T("Instruction Scheduling", GroupName); - Scheduler = Schedule(DAG); + Scheduler = Schedule(); } else { - Scheduler = Schedule(DAG); + Scheduler = Schedule(); } if (ViewSUnitDAGs) Scheduler->viewGraph(); @@ -5470,57 +5453,94 @@ void SelectionDAGISel::CodeGenAndEmitDAG(SelectionDAG &DAG) { delete Scheduler; } - // Perform target specific isel post processing. - if (TimePassesIsEnabled) { - NamedRegionTimer T("Instruction Selection Post Processing", GroupName); - InstructionSelectPostProcessing(); - } else { - InstructionSelectPostProcessing(); - } - DOUT << "Selected machine code:\n"; DEBUG(BB->dump()); } void SelectionDAGISel::SelectAllBasicBlocks(Function &Fn, MachineFunction &MF, FunctionLoweringInfo &FuncInfo) { - // Define NodeAllocator here so that memory allocation is reused for + // Define the SelectionDAG here so that memory allocation is reused for // each basic block. - NodeAllocatorType NodeAllocator; + SelectionDAG DAG(TLI, MF, FuncInfo, + getAnalysisToUpdate()); + CurDAG = &DAG; std::vector > PHINodesToUpdate; for (Function::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I) { BasicBlock *LLVMBB = &*I; + BB = FuncInfo.MBBMap[LLVMBB]; + + BasicBlock::iterator Begin = LLVMBB->begin(); + BasicBlock::iterator End = LLVMBB->end(); + bool DoArgs = LLVMBB == &Fn.getEntryBlock(); + + // 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)) { + while (Begin != End) { + Begin = F->SelectInstructions(Begin, End, FuncInfo.ValueMap, + FuncInfo.MBBMap, BB); + + if (Begin == End) + // The "fast" selector selected the entire block, so we're done. + break; + + // Handle certain instructions as single-LLVM-Instruction blocks. + if (isa(Begin) || isa(Begin) || + isa(Begin)) { + if (Begin->getType() != Type::VoidTy) { + unsigned &R = FuncInfo.ValueMap[Begin]; + if (!R) + R = FuncInfo.CreateRegForValue(Begin); + } + + SelectBasicBlock(LLVMBB, Begin, next(Begin), DoArgs, + PHINodesToUpdate, FuncInfo); + + ++Begin; + DoArgs = false; + continue; + } + + if (!DisableFastISelAbort && + // For now, don't abort on non-conditional-branch terminators. + (!isa(Begin) || + (isa(Begin) && + cast(Begin)->isUnconditional()))) { + // The "fast" selector couldn't handle something and bailed. + // For the purpose of debugging, just abort. +#ifndef NDEBUG + Begin->dump(); +#endif + assert(0 && "FastISel didn't select the entire block"); + } + break; + } + delete F; + } + } + + if (Begin != End || DoArgs) + SelectBasicBlock(LLVMBB, Begin, End, DoArgs, PHINodesToUpdate, FuncInfo); + + FinishBasicBlock(FuncInfo, PHINodesToUpdate); PHINodesToUpdate.clear(); - - SelectBasicBlock(LLVMBB, MF, FuncInfo, PHINodesToUpdate, NodeAllocator); - FinishBasicBlock(LLVMBB, MF, FuncInfo, PHINodesToUpdate, NodeAllocator); } + + CurDAG = 0; } void -SelectionDAGISel::SelectBasicBlock(BasicBlock *LLVMBB, MachineFunction &MF, - FunctionLoweringInfo &FuncInfo, - std::vector > &PHINodesToUpdate, - NodeAllocatorType &NodeAllocator) { - SelectionDAG DAG(TLI, MF, FuncInfo, - getAnalysisToUpdate(), - NodeAllocator); - CurDAG = &DAG; +SelectionDAGISel::FinishBasicBlock(FunctionLoweringInfo &FuncInfo, + std::vector > &PHINodesToUpdate) { + + // Perform target specific isel post processing. + InstructionSelectPostProcessing(); - // First step, lower LLVM code to some DAG. This DAG may use operations and - // types that are not supported by the target. - BuildSelectionDAG(DAG, LLVMBB, PHINodesToUpdate, FuncInfo); + DOUT << "Target-post-processed machine code:\n"; + DEBUG(BB->dump()); - // Second step, emit the lowered DAG as machine code. - CodeGenAndEmitDAG(DAG); -} - -void -SelectionDAGISel::FinishBasicBlock(BasicBlock *LLVMBB, MachineFunction &MF, - FunctionLoweringInfo &FuncInfo, - std::vector > &PHINodesToUpdate, - NodeAllocatorType &NodeAllocator) { DOUT << "Total amount of phi nodes to update: " << PHINodesToUpdate.size() << "\n"; DEBUG(for (unsigned i = 0, e = PHINodesToUpdate.size(); i != e; ++i) @@ -5544,26 +5564,19 @@ SelectionDAGISel::FinishBasicBlock(BasicBlock *LLVMBB, MachineFunction &MF, for (unsigned i = 0, e = BitTestCases.size(); i != e; ++i) { // Lower header first, if it wasn't already lowered if (!BitTestCases[i].Emitted) { - SelectionDAG HSDAG(TLI, MF, FuncInfo, - getAnalysisToUpdate(), - NodeAllocator); - CurDAG = &HSDAG; - SelectionDAGLowering HSDL(HSDAG, TLI, *AA, FuncInfo, GFI); + SelectionDAGLowering HSDL(*CurDAG, TLI, *AA, FuncInfo, GFI); // Set the current basic block to the mbb we wish to insert the code into BB = BitTestCases[i].Parent; HSDL.setCurrentBasicBlock(BB); // Emit the code HSDL.visitBitTestHeader(BitTestCases[i]); - HSDAG.setRoot(HSDL.getRoot()); - CodeGenAndEmitDAG(HSDAG); + CurDAG->setRoot(HSDL.getRoot()); + CodeGenAndEmitDAG(); + CurDAG->reset(); } for (unsigned j = 0, ej = BitTestCases[i].Cases.size(); j != ej; ++j) { - SelectionDAG BSDAG(TLI, MF, FuncInfo, - getAnalysisToUpdate(), - NodeAllocator); - CurDAG = &BSDAG; - SelectionDAGLowering BSDL(BSDAG, TLI, *AA, FuncInfo, GFI); + SelectionDAGLowering BSDL(*CurDAG, TLI, *AA, FuncInfo, GFI); // Set the current basic block to the mbb we wish to insert the code into BB = BitTestCases[i].Cases[j].ThisBB; BSDL.setCurrentBasicBlock(BB); @@ -5578,8 +5591,9 @@ SelectionDAGISel::FinishBasicBlock(BasicBlock *LLVMBB, MachineFunction &MF, BitTestCases[i].Cases[j]); - BSDAG.setRoot(BSDL.getRoot()); - CodeGenAndEmitDAG(BSDAG); + CurDAG->setRoot(BSDL.getRoot()); + CodeGenAndEmitDAG(); + CurDAG->reset(); } // Update PHI Nodes @@ -5618,32 +5632,26 @@ SelectionDAGISel::FinishBasicBlock(BasicBlock *LLVMBB, MachineFunction &MF, for (unsigned i = 0, e = JTCases.size(); i != e; ++i) { // Lower header first, if it wasn't already lowered if (!JTCases[i].first.Emitted) { - SelectionDAG HSDAG(TLI, MF, FuncInfo, - getAnalysisToUpdate(), - NodeAllocator); - CurDAG = &HSDAG; - SelectionDAGLowering HSDL(HSDAG, TLI, *AA, FuncInfo, GFI); + SelectionDAGLowering HSDL(*CurDAG, TLI, *AA, FuncInfo, GFI); // Set the current basic block to the mbb we wish to insert the code into BB = JTCases[i].first.HeaderBB; HSDL.setCurrentBasicBlock(BB); // Emit the code HSDL.visitJumpTableHeader(JTCases[i].second, JTCases[i].first); - HSDAG.setRoot(HSDL.getRoot()); - CodeGenAndEmitDAG(HSDAG); + CurDAG->setRoot(HSDL.getRoot()); + CodeGenAndEmitDAG(); + CurDAG->reset(); } - SelectionDAG JSDAG(TLI, MF, FuncInfo, - getAnalysisToUpdate(), - NodeAllocator); - CurDAG = &JSDAG; - SelectionDAGLowering JSDL(JSDAG, TLI, *AA, FuncInfo, GFI); + 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); // Emit the code JSDL.visitJumpTable(JTCases[i].second); - JSDAG.setRoot(JSDL.getRoot()); - CodeGenAndEmitDAG(JSDAG); + CurDAG->setRoot(JSDL.getRoot()); + CodeGenAndEmitDAG(); + CurDAG->reset(); // Update PHI Nodes for (unsigned pi = 0, pe = PHINodesToUpdate.size(); pi != pe; ++pi) { @@ -5682,11 +5690,7 @@ SelectionDAGISel::FinishBasicBlock(BasicBlock *LLVMBB, MachineFunction &MF, // If we generated any switch lowering information, build and codegen any // additional DAGs necessary. for (unsigned i = 0, e = SwitchCases.size(); i != e; ++i) { - SelectionDAG SDAG(TLI, MF, FuncInfo, - getAnalysisToUpdate(), - NodeAllocator); - CurDAG = &SDAG; - SelectionDAGLowering SDL(SDAG, TLI, *AA, FuncInfo, GFI); + SelectionDAGLowering SDL(*CurDAG, TLI, *AA, FuncInfo, GFI); // Set the current basic block to the mbb we wish to insert the code into BB = SwitchCases[i].ThisBB; @@ -5694,8 +5698,9 @@ SelectionDAGISel::FinishBasicBlock(BasicBlock *LLVMBB, MachineFunction &MF, // Emit the code SDL.visitSwitchCase(SwitchCases[i]); - SDAG.setRoot(SDL.getRoot()); - CodeGenAndEmitDAG(SDAG); + CurDAG->setRoot(SDL.getRoot()); + CodeGenAndEmitDAG(); + CurDAG->reset(); // 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 @@ -5732,7 +5737,7 @@ SelectionDAGISel::FinishBasicBlock(BasicBlock *LLVMBB, MachineFunction &MF, /// Schedule - Pick a safe ordering for instructions for each /// target node in the graph. /// -ScheduleDAG *SelectionDAGISel::Schedule(SelectionDAG &DAG) { +ScheduleDAG *SelectionDAGISel::Schedule() { RegisterScheduler::FunctionPassCtor Ctor = RegisterScheduler::getDefault(); if (!Ctor) { @@ -5740,7 +5745,7 @@ ScheduleDAG *SelectionDAGISel::Schedule(SelectionDAG &DAG) { RegisterScheduler::setDefault(Ctor); } - ScheduleDAG *Scheduler = Ctor(this, &DAG, BB, Fast); + ScheduleDAG *Scheduler = Ctor(this, CurDAG, BB, Fast); Scheduler->Run(); return Scheduler; @@ -5823,7 +5828,7 @@ bool SelectionDAGISel::CheckOrMask(SDValue LHS, ConstantSDNode *RHS, /// SelectInlineAsmMemoryOperands - Calls to this are automatically generated /// by tblgen. Others should not call it. void SelectionDAGISel:: -SelectInlineAsmMemoryOperands(std::vector &Ops, SelectionDAG &DAG) { +SelectInlineAsmMemoryOperands(std::vector &Ops) { std::vector InOps; std::swap(InOps, Ops); @@ -5844,15 +5849,15 @@ SelectInlineAsmMemoryOperands(std::vector &Ops, SelectionDAG &DAG) { assert((Flags >> 3) == 1 && "Memory operand with multiple values?"); // Otherwise, this is a memory operand. Ask the target to select it. std::vector SelOps; - if (SelectInlineAsmMemoryOperand(InOps[i+1], 'm', SelOps, DAG)) { + if (SelectInlineAsmMemoryOperand(InOps[i+1], 'm', SelOps)) { cerr << "Could not match memory address. Inline asm failure!\n"; exit(1); } // Add this to the output node. - MVT IntPtrTy = DAG.getTargetLoweringInfo().getPointerTy(); - Ops.push_back(DAG.getTargetConstant(4/*MEM*/ | (SelOps.size() << 3), - IntPtrTy)); + MVT IntPtrTy = CurDAG->getTargetLoweringInfo().getPointerTy(); + Ops.push_back(CurDAG->getTargetConstant(4/*MEM*/ | (SelOps.size() << 3), + IntPtrTy)); Ops.insert(Ops.end(), SelOps.begin(), SelOps.end()); i += 2; } diff --git a/lib/Target/ARM/ARMISelDAGToDAG.cpp b/lib/Target/ARM/ARMISelDAGToDAG.cpp index ad1f63d642f..d26a5fbd34d 100644 --- a/lib/Target/ARM/ARMISelDAGToDAG.cpp +++ b/lib/Target/ARM/ARMISelDAGToDAG.cpp @@ -54,7 +54,7 @@ public: } SDNode *Select(SDValue Op); - virtual void InstructionSelect(SelectionDAG &DAG); + virtual void InstructionSelect(); bool SelectAddrMode2(SDValue Op, SDValue N, SDValue &Base, SDValue &Offset, SDValue &Opc); bool SelectAddrMode2Offset(SDValue Op, SDValue N, @@ -91,11 +91,11 @@ public: }; } -void ARMDAGToDAGISel::InstructionSelect(SelectionDAG &DAG) { +void ARMDAGToDAGISel::InstructionSelect() { DEBUG(BB->dump()); SelectRoot(); - DAG.RemoveDeadNodes(); + CurDAG->RemoveDeadNodes(); } bool ARMDAGToDAGISel::SelectAddrMode2(SDValue Op, SDValue N, diff --git a/lib/Target/Alpha/AlphaISelDAGToDAG.cpp b/lib/Target/Alpha/AlphaISelDAGToDAG.cpp index 0ff735d28eb..ce6afc3b81b 100644 --- a/lib/Target/Alpha/AlphaISelDAGToDAG.cpp +++ b/lib/Target/Alpha/AlphaISelDAGToDAG.cpp @@ -163,7 +163,7 @@ namespace { /// InstructionSelect - This callback is invoked by /// SelectionDAGISel when it has created a SelectionDAG for us to codegen. - virtual void InstructionSelect(SelectionDAG &DAG); + virtual void InstructionSelect(); virtual const char *getPassName() const { return "Alpha DAG->DAG Pattern Instruction Selection"; @@ -173,8 +173,7 @@ namespace { /// inline asm expressions. virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode, - std::vector &OutOps, - SelectionDAG &DAG) { + std::vector &OutOps) { SDValue Op0; switch (ConstraintCode) { default: return true; @@ -232,12 +231,12 @@ SDValue AlphaDAGToDAGISel::getGlobalRetAddr() { /// InstructionSelect - This callback is invoked by /// SelectionDAGISel when it has created a SelectionDAG for us to codegen. -void AlphaDAGToDAGISel::InstructionSelect(SelectionDAG &DAG) { +void AlphaDAGToDAGISel::InstructionSelect() { DEBUG(BB->dump()); // Select target instructions for the DAG. SelectRoot(); - DAG.RemoveDeadNodes(); + CurDAG->RemoveDeadNodes(); } // Select - Convert the specified operand from a target-independent to a diff --git a/lib/Target/CellSPU/SPUISelDAGToDAG.cpp b/lib/Target/CellSPU/SPUISelDAGToDAG.cpp index c8d04b46cb5..c2a3e3a8df5 100644 --- a/lib/Target/CellSPU/SPUISelDAGToDAG.cpp +++ b/lib/Target/CellSPU/SPUISelDAGToDAG.cpp @@ -285,8 +285,7 @@ public: /// inline asm expressions. virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode, - std::vector &OutOps, - SelectionDAG &DAG) { + std::vector &OutOps) { SDValue Op0, Op1; switch (ConstraintCode) { default: return true; @@ -319,7 +318,7 @@ public: /// InstructionSelect - This callback is invoked by /// SelectionDAGISel when it has created a SelectionDAG for us to codegen. - virtual void InstructionSelect(SelectionDAG &DAG); + virtual void InstructionSelect(); virtual const char *getPassName() const { return "Cell SPU DAG->DAG Pattern Instruction Selection"; @@ -342,13 +341,13 @@ public: /// InstructionSelect - This callback is invoked by /// SelectionDAGISel when it has created a SelectionDAG for us to codegen. void -SPUDAGToDAGISel::InstructionSelect(SelectionDAG &DAG) +SPUDAGToDAGISel::InstructionSelect() { DEBUG(BB->dump()); // Select target instructions for the DAG. SelectRoot(); - DAG.RemoveDeadNodes(); + CurDAG->RemoveDeadNodes(); } /*! diff --git a/lib/Target/IA64/IA64ISelDAGToDAG.cpp b/lib/Target/IA64/IA64ISelDAGToDAG.cpp index 8173e96ccbf..aa1f6bb0156 100644 --- a/lib/Target/IA64/IA64ISelDAGToDAG.cpp +++ b/lib/Target/IA64/IA64ISelDAGToDAG.cpp @@ -80,7 +80,7 @@ namespace { /// InstructionSelect - This callback is invoked by /// SelectionDAGISel when it has created a SelectionDAG for us to codegen. - virtual void InstructionSelect(SelectionDAG &DAG); + virtual void InstructionSelect(); virtual const char *getPassName() const { return "IA64 (Itanium) DAG->DAG Instruction Selector"; @@ -96,12 +96,12 @@ private: /// InstructionSelect - This callback is invoked by /// SelectionDAGISel when it has created a SelectionDAG for us to codegen. -void IA64DAGToDAGISel::InstructionSelect(SelectionDAG &DAG) { +void IA64DAGToDAGISel::InstructionSelect() { DEBUG(BB->dump()); // Select target instructions for the DAG. SelectRoot(); - DAG.RemoveDeadNodes(); + CurDAG->RemoveDeadNodes(); } SDNode *IA64DAGToDAGISel::SelectDIV(SDValue Op) { diff --git a/lib/Target/Mips/MipsISelDAGToDAG.cpp b/lib/Target/Mips/MipsISelDAGToDAG.cpp index 94fdb3526db..1e07a8f53da 100644 --- a/lib/Target/Mips/MipsISelDAGToDAG.cpp +++ b/lib/Target/Mips/MipsISelDAGToDAG.cpp @@ -66,7 +66,7 @@ public: TM(tm), MipsLowering(*TM.getTargetLowering()), Subtarget(tm.getSubtarget()) {} - virtual void InstructionSelect(SelectionDAG &SD); + virtual void InstructionSelect(); // Pass Name virtual const char *getPassName() const { @@ -103,7 +103,7 @@ private: /// InstructionSelect - This callback is invoked by /// SelectionDAGISel when it has created a SelectionDAG for us to codegen. void MipsDAGToDAGISel:: -InstructionSelect(SelectionDAG &SD) +InstructionSelect() { DEBUG(BB->dump()); // Codegen the basic block. @@ -119,7 +119,7 @@ InstructionSelect(SelectionDAG &SD) DOUT << "===== Instruction selection ends:\n"; #endif - SD.RemoveDeadNodes(); + CurDAG->RemoveDeadNodes(); } /// getGlobalBaseReg - Output the instructions required to put the diff --git a/lib/Target/PIC16/PIC16ISelDAGToDAG.cpp b/lib/Target/PIC16/PIC16ISelDAGToDAG.cpp index f1eaa39155d..a9c1d096137 100644 --- a/lib/Target/PIC16/PIC16ISelDAGToDAG.cpp +++ b/lib/Target/PIC16/PIC16ISelDAGToDAG.cpp @@ -60,7 +60,7 @@ public: SelectionDAGISel(PIC16Lowering), TM(tm), PIC16Lowering(*TM.getTargetLowering()) {} - virtual void InstructionSelect(SelectionDAG &SD); + virtual void InstructionSelect(); // Pass Name virtual const char *getPassName() const { @@ -98,7 +98,7 @@ private: /// InstructionSelect - This callback is invoked by /// SelectionDAGISel when it has created a SelectionDAG for us to codegen. -void PIC16DAGToDAGISel::InstructionSelect(SelectionDAG &SD) +void PIC16DAGToDAGISel::InstructionSelect() { DEBUG(BB->dump()); // Codegen the basic block. @@ -113,7 +113,7 @@ void PIC16DAGToDAGISel::InstructionSelect(SelectionDAG &SD) DOUT << "===== Instruction selection ends:\n"; - SD.RemoveDeadNodes(); + CurDAG->RemoveDeadNodes(); } diff --git a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp index c6479554346..e655e06e7a8 100644 --- a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp +++ b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp @@ -144,8 +144,7 @@ namespace { /// inline asm expressions. virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode, - std::vector &OutOps, - SelectionDAG &DAG) { + std::vector &OutOps) { SDValue Op0, Op1; switch (ConstraintCode) { default: return true; @@ -175,7 +174,7 @@ namespace { /// InstructionSelect - This callback is invoked by /// SelectionDAGISel when it has created a SelectionDAG for us to codegen. - virtual void InstructionSelect(SelectionDAG &DAG); + virtual void InstructionSelect(); void InsertVRSaveCode(Function &Fn); @@ -203,12 +202,12 @@ private: /// InstructionSelect - This callback is invoked by /// SelectionDAGISel when it has created a SelectionDAG for us to codegen. -void PPCDAGToDAGISel::InstructionSelect(SelectionDAG &DAG) { +void PPCDAGToDAGISel::InstructionSelect() { DEBUG(BB->dump()); // Select target instructions for the DAG. SelectRoot(); - DAG.RemoveDeadNodes(); + CurDAG->RemoveDeadNodes(); } /// InsertVRSaveCode - Once the entire function has been instruction selected, diff --git a/lib/Target/Sparc/SparcISelDAGToDAG.cpp b/lib/Target/Sparc/SparcISelDAGToDAG.cpp index f62387307d1..64e9bcec6a1 100644 --- a/lib/Target/Sparc/SparcISelDAGToDAG.cpp +++ b/lib/Target/Sparc/SparcISelDAGToDAG.cpp @@ -49,7 +49,7 @@ public: /// InstructionSelect - This callback is invoked by /// SelectionDAGISel when it has created a SelectionDAG for us to codegen. - virtual void InstructionSelect(SelectionDAG &DAG); + virtual void InstructionSelect(); virtual const char *getPassName() const { return "SPARC DAG->DAG Pattern Instruction Selection"; @@ -62,12 +62,12 @@ public: /// InstructionSelect - This callback is invoked by /// SelectionDAGISel when it has created a SelectionDAG for us to codegen. -void SparcDAGToDAGISel::InstructionSelect(SelectionDAG &DAG) { +void SparcDAGToDAGISel::InstructionSelect() { DEBUG(BB->dump()); // Select target instructions for the DAG. SelectRoot(); - DAG.RemoveDeadNodes(); + CurDAG->RemoveDeadNodes(); } bool SparcDAGToDAGISel::SelectADDRri(SDValue Op, SDValue Addr, diff --git a/lib/Target/X86/X86ISelDAGToDAG.cpp b/lib/Target/X86/X86ISelDAGToDAG.cpp index 21837d53d43..29986e50d6d 100644 --- a/lib/Target/X86/X86ISelDAGToDAG.cpp +++ b/lib/Target/X86/X86ISelDAGToDAG.cpp @@ -147,7 +147,7 @@ namespace { /// InstructionSelect - This callback is invoked by /// SelectionDAGISel when it has created a SelectionDAG for us to codegen. - virtual void InstructionSelect(SelectionDAG &DAG); + virtual void InstructionSelect(); /// InstructionSelectPostProcessing - Post processing of selected and /// scheduled basic blocks. @@ -178,15 +178,14 @@ namespace { bool TryFoldLoad(SDValue P, SDValue N, SDValue &Base, SDValue &Scale, SDValue &Index, SDValue &Disp); - void PreprocessForRMW(SelectionDAG &DAG); - void PreprocessForFPConvert(SelectionDAG &DAG); + void PreprocessForRMW(); + void PreprocessForFPConvert(); /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for /// inline asm expressions. virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode, - std::vector &OutOps, - SelectionDAG &DAG); + std::vector &OutOps); void EmitSpecialCodeForMain(MachineBasicBlock *BB, MachineFrameInfo *MFI); @@ -372,7 +371,7 @@ bool X86DAGToDAGISel::CanBeFoldedBy(SDNode *N, SDNode *U, SDNode *Root) const { /// MoveBelowTokenFactor - Replace TokenFactor operand with load's chain operand /// and move load below the TokenFactor. Replace store's chain operand with /// load's chain result. -static void MoveBelowTokenFactor(SelectionDAG &DAG, SDValue Load, +static void MoveBelowTokenFactor(SelectionDAG *CurDAG, SDValue Load, SDValue Store, SDValue TF) { std::vector Ops; for (unsigned i = 0, e = TF.Val->getNumOperands(); i != e; ++i) @@ -380,10 +379,10 @@ static void MoveBelowTokenFactor(SelectionDAG &DAG, SDValue Load, Ops.push_back(Load.Val->getOperand(0)); else Ops.push_back(TF.Val->getOperand(i)); - DAG.UpdateNodeOperands(TF, &Ops[0], Ops.size()); - DAG.UpdateNodeOperands(Load, TF, Load.getOperand(1), Load.getOperand(2)); - DAG.UpdateNodeOperands(Store, Load.getValue(1), Store.getOperand(1), - Store.getOperand(2), Store.getOperand(3)); + CurDAG->UpdateNodeOperands(TF, &Ops[0], Ops.size()); + CurDAG->UpdateNodeOperands(Load, TF, Load.getOperand(1), Load.getOperand(2)); + CurDAG->UpdateNodeOperands(Store, Load.getValue(1), Store.getOperand(1), + Store.getOperand(2), Store.getOperand(3)); } /// isRMWLoad - Return true if N is a load that's part of RMW sub-DAG. @@ -452,9 +451,9 @@ static bool isRMWLoad(SDValue N, SDValue Chain, SDValue Address, /// \ / /// \ / /// [Store] -void X86DAGToDAGISel::PreprocessForRMW(SelectionDAG &DAG) { - for (SelectionDAG::allnodes_iterator I = DAG.allnodes_begin(), - E = DAG.allnodes_end(); I != E; ++I) { +void X86DAGToDAGISel::PreprocessForRMW() { + for (SelectionDAG::allnodes_iterator I = CurDAG->allnodes_begin(), + E = CurDAG->allnodes_end(); I != E; ++I) { if (!ISD::isNON_TRUNCStore(I)) continue; SDValue Chain = I->getOperand(0); @@ -504,7 +503,7 @@ void X86DAGToDAGISel::PreprocessForRMW(SelectionDAG &DAG) { } if (RModW) { - MoveBelowTokenFactor(DAG, Load, SDValue(I, 0), Chain); + MoveBelowTokenFactor(CurDAG, Load, SDValue(I, 0), Chain); ++NumLoadMoved; } } @@ -519,9 +518,9 @@ void X86DAGToDAGISel::PreprocessForRMW(SelectionDAG &DAG) { /// hack on these between the call expansion and the node legalization. As such /// this pass basically does "really late" legalization of these inline with the /// X86 isel pass. -void X86DAGToDAGISel::PreprocessForFPConvert(SelectionDAG &DAG) { - for (SelectionDAG::allnodes_iterator I = DAG.allnodes_begin(), - E = DAG.allnodes_end(); I != E; ) { +void X86DAGToDAGISel::PreprocessForFPConvert() { + for (SelectionDAG::allnodes_iterator I = CurDAG->allnodes_begin(), + E = CurDAG->allnodes_end(); I != E; ) { SDNode *N = I++; // Preincrement iterator to avoid invalidation issues. if (N->getOpcode() != ISD::FP_ROUND && N->getOpcode() != ISD::FP_EXTEND) continue; @@ -553,39 +552,40 @@ void X86DAGToDAGISel::PreprocessForFPConvert(SelectionDAG &DAG) { else MemVT = SrcIsSSE ? SrcVT : DstVT; - SDValue MemTmp = DAG.CreateStackTemporary(MemVT); + SDValue MemTmp = CurDAG->CreateStackTemporary(MemVT); // FIXME: optimize the case where the src/dest is a load or store? - SDValue Store = DAG.getTruncStore(DAG.getEntryNode(), N->getOperand(0), - MemTmp, NULL, 0, MemVT); - SDValue Result = DAG.getExtLoad(ISD::EXTLOAD, DstVT, Store, MemTmp, - NULL, 0, MemVT); + SDValue Store = CurDAG->getTruncStore(CurDAG->getEntryNode(), + N->getOperand(0), + MemTmp, NULL, 0, MemVT); + SDValue Result = CurDAG->getExtLoad(ISD::EXTLOAD, DstVT, Store, MemTmp, + NULL, 0, MemVT); // We're about to replace all uses of the FP_ROUND/FP_EXTEND with the // extload we created. This will cause general havok on the dag because // anything below the conversion could be folded into other existing nodes. // To avoid invalidating 'I', back it up to the convert node. --I; - DAG.ReplaceAllUsesOfValueWith(SDValue(N, 0), Result); + CurDAG->ReplaceAllUsesOfValueWith(SDValue(N, 0), Result); // Now that we did that, the node is dead. Increment the iterator to the // next node to process, then delete N. ++I; - DAG.DeleteNode(N); + CurDAG->DeleteNode(N); } } /// InstructionSelectBasicBlock - This callback is invoked by SelectionDAGISel /// when it has created a SelectionDAG for us to codegen. -void X86DAGToDAGISel::InstructionSelect(SelectionDAG &DAG) { +void X86DAGToDAGISel::InstructionSelect() { CurBB = BB; // BB can change as result of isel. DEBUG(BB->dump()); if (!Fast) - PreprocessForRMW(DAG); + PreprocessForRMW(); // FIXME: This should only happen when not -fast. - PreprocessForFPConvert(DAG); + PreprocessForFPConvert(); // Codegen the basic block. #ifndef NDEBUG @@ -597,7 +597,7 @@ void X86DAGToDAGISel::InstructionSelect(SelectionDAG &DAG) { DOUT << "===== Instruction selection ends:\n"; #endif - DAG.RemoveDeadNodes(); + CurDAG->RemoveDeadNodes(); } void X86DAGToDAGISel::InstructionSelectPostProcessing() { @@ -1599,7 +1599,7 @@ SDNode *X86DAGToDAGISel::Select(SDValue N) { bool X86DAGToDAGISel:: SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode, - std::vector &OutOps, SelectionDAG &DAG){ + std::vector &OutOps) { SDValue Op0, Op1, Op2, Op3; switch (ConstraintCode) { case 'o': // offsetable ?? diff --git a/utils/TableGen/DAGISelEmitter.cpp b/utils/TableGen/DAGISelEmitter.cpp index cf4d20f9c67..b7778918d0d 100644 --- a/utils/TableGen/DAGISelEmitter.cpp +++ b/utils/TableGen/DAGISelEmitter.cpp @@ -1864,7 +1864,7 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) { // Emit boilerplate. OS << "SDNode *Select_INLINEASM(SDValue N) {\n" << " std::vector Ops(N.Val->op_begin(), N.Val->op_end());\n" - << " SelectInlineAsmMemoryOperands(Ops, *CurDAG);\n\n" + << " SelectInlineAsmMemoryOperands(Ops);\n\n" << " // Ensure that the asm operands are themselves selected.\n" << " for (unsigned j = 0, e = Ops.size(); j != e; ++j)\n"