From e7ccc51cc171269984c0339ce3f7ee042247dc82 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 7 Jul 2010 19:20:32 +0000 Subject: Implement bottom-up fast-isel. This has the advantage of not requiring a separate DCE pass over MachineInstrs. llvm-svn: 107804 --- llvm/lib/CodeGen/SelectionDAG/FastISel.cpp | 43 ++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 11 deletions(-) (limited to 'llvm/lib/CodeGen/SelectionDAG/FastISel.cpp') diff --git a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp index 2ba8315a7e6..5a245122775 100644 --- a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp @@ -57,6 +57,17 @@ #include "llvm/Support/ErrorHandling.h" using namespace llvm; +/// startNewBlock - Set the current block to which generated machine +/// instructions will be appended, and clear the local CSE map. +/// +void FastISel::startNewBlock() { + LocalValueMap.clear(); + + // Start out as end(), meaining no local-value instructions have + // been emitted. + LastLocalValue = FuncInfo.MBB->end(); +} + bool FastISel::hasTrivialKill(const Value *V) const { // Don't consider constants or arguments to have trivial kills. const Instruction *I = dyn_cast(V); @@ -109,12 +120,9 @@ unsigned FastISel::getRegForValue(const Value *V) { // In bottom-up mode, just create the virtual register which will be used // to hold the value. It will be materialized later. - if (IsBottomUp) { + if (isa(V)) { Reg = createResultReg(TLI.getRegClassFor(VT)); - if (isa(V)) - FuncInfo.ValueMap[V] = Reg; - else - LocalValueMap[V] = Reg; + FuncInfo.ValueMap[V] = Reg; return Reg; } @@ -180,8 +188,10 @@ unsigned FastISel::materializeRegForValue(const Value *V, MVT VT) { // Don't cache constant materializations in the general ValueMap. // To do so would require tracking what uses they dominate. - if (Reg != 0) + if (Reg != 0) { LocalValueMap[V] = Reg; + LastLocalValue = MRI.getVRegDef(Reg); + } return Reg; } @@ -210,12 +220,20 @@ unsigned FastISel::UpdateValueMap(const Value *I, unsigned Reg) { unsigned &AssignedReg = FuncInfo.ValueMap[I]; if (AssignedReg == 0) + // Use the new register. AssignedReg = Reg; else if (Reg != AssignedReg) { - const TargetRegisterClass *RegClass = MRI.getRegClass(Reg); - TII.copyRegToReg(*FuncInfo.MBB, FuncInfo.InsertPt, AssignedReg, - Reg, RegClass, RegClass, DL); + // We already have a register for this value. Replace uses of + // the existing register with uses of the new one. + MRI.replaceRegWith(AssignedReg, Reg); + // Replace uses of the existing register in PHINodesToUpdate too. + for (unsigned i = 0, e = FuncInfo.PHINodesToUpdate.size(); i != e; ++i) + if (FuncInfo.PHINodesToUpdate[i].second == AssignedReg) + FuncInfo.PHINodesToUpdate[i].second = Reg; + // And update the ValueMap. + AssignedReg = Reg; } + return AssignedReg; } @@ -736,11 +754,15 @@ FastISel::SelectLoad(const User *I) { BasicBlock::iterator ScanFrom = LI; if (const Value *V = FindAvailableLoadedValue(LI->getPointerOperand(), LI->getParent(), ScanFrom)) { + if (!isa(V) || + cast(V)->getParent() == LI->getParent() || + (isa(V) && FuncInfo.StaticAllocaMap.count(cast(V)))) { unsigned ResultReg = getRegForValue(V); if (ResultReg != 0) { UpdateValueMap(I, ResultReg); return true; } + } } } @@ -871,8 +893,7 @@ FastISel::FastISel(FunctionLoweringInfo &funcInfo) TD(*TM.getTargetData()), TII(*TM.getInstrInfo()), TLI(*TM.getTargetLowering()), - TRI(*TM.getRegisterInfo()), - IsBottomUp(false) { + TRI(*TM.getRegisterInfo()) { } FastISel::~FastISel() {} -- cgit v1.2.3