aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/SelectionDAG/FastISel.cpp
diff options
context:
space:
mode:
authorDan Gohman <gohman@apple.com>2010-07-07 19:20:32 +0000
committerDan Gohman <gohman@apple.com>2010-07-07 19:20:32 +0000
commit4df83ed159f21fdf73a57729c3e9d8c9fcd73607 (patch)
treeabee7270365c3f2f5299e810db3d44482dae9504 /lib/CodeGen/SelectionDAG/FastISel.cpp
parentf423a69839c4810b890f8a8b09fb8cfbd6bf0139 (diff)
Implement bottom-up fast-isel. This has the advantage of not requiring
a separate DCE pass over MachineInstrs. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@107804 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/SelectionDAG/FastISel.cpp')
-rw-r--r--lib/CodeGen/SelectionDAG/FastISel.cpp43
1 files changed, 32 insertions, 11 deletions
diff --git a/lib/CodeGen/SelectionDAG/FastISel.cpp b/lib/CodeGen/SelectionDAG/FastISel.cpp
index 2ba8315a7e..5a24512277 100644
--- a/lib/CodeGen/SelectionDAG/FastISel.cpp
+++ b/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<Instruction>(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<Instruction>(V)) {
Reg = createResultReg(TLI.getRegClassFor(VT));
- if (isa<Instruction>(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<Instruction>(V) ||
+ cast<Instruction>(V)->getParent() == LI->getParent() ||
+ (isa<AllocaInst>(V) && FuncInfo.StaticAllocaMap.count(cast<AllocaInst>(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() {}