Reorganize the lifetimes of the major objects SelectionDAGISel

works with.

SelectionDAG, FunctionLoweringInfo, and SelectionDAGLowering
objects now get created once per SelectionDAGISel instance, and
can be reused across blocks and across functions. Previously,
they were created and destroyed each time they were needed.

This reorganization simplifies the handling of PHI nodes, and
also SwitchCases, JumpTables, and BitTestBlocks. This
simplification has the side effect of fixing a bug in FastISel
where successor PHI nodes weren't being updated correctly.

This is also a step towards making the transition from FastISel
into and out of SelectionDAG faster, and also making
plain SelectionDAG faster on code with lots of little blocks.

llvm-svn: 55450
This commit is contained in:
Dan Gohman 2008-08-27 23:52:12 +00:00
parent 3a01c1eb8e
commit e1a9a780a5
4 changed files with 364 additions and 336 deletions

View File

@ -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; }

View File

@ -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<SDNode*> 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<JumpTableHeader, JumpTable> 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<BitTestCase, 3> 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<std::pair<MachineInstr*, unsigned> > &PHINodesToUpdate);
void SelectAllBasicBlocks(Function &Fn, MachineFunction &MF);
void FinishBasicBlock();
void SelectBasicBlock(BasicBlock *LLVMBB,
BasicBlock::iterator Begin,
BasicBlock::iterator End,
bool DoArgs,
std::vector<std::pair<MachineInstr*, unsigned> > &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<std::pair<MachineInstr*, unsigned> > &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<CaseBlock> SwitchCases;
/// JTCases - Vector of JumpTable structures which holds necessary information
/// for emitting a jump tables during SwitchInst code generation.
std::vector<JumpTableBlock> JTCases;
std::vector<BitTestBlock> BitTestCases;
};
}

View File

@ -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();

File diff suppressed because it is too large Load Diff