FastISel: avoid function calls between the materialization of the constant and its use.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@137993 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/SelectionDAG/FastISel.cpp b/lib/CodeGen/SelectionDAG/FastISel.cpp
index f720322..226edc6 100644
--- a/lib/CodeGen/SelectionDAG/FastISel.cpp
+++ b/lib/CodeGen/SelectionDAG/FastISel.cpp
@@ -66,17 +66,22 @@
void FastISel::startNewBlock() {
LocalValueMap.clear();
- // Start out as null, meaining no local-value instructions have
- // been emitted.
- LastLocalValue = 0;
+ EmitStartPt = 0;
- // Advance the last local value past any EH_LABEL instructions.
+ // Advance the emit start point past any EH_LABEL instructions.
MachineBasicBlock::iterator
I = FuncInfo.MBB->begin(), E = FuncInfo.MBB->end();
while (I != E && I->getOpcode() == TargetOpcode::EH_LABEL) {
- LastLocalValue = I;
+ EmitStartPt = I;
++I;
}
+ LastLocalValue = EmitStartPt;
+}
+
+void FastISel::flushLocalValueMap() {
+ LocalValueMap.clear();
+ LastLocalValue = EmitStartPt;
+ recomputeInsertPt();
}
bool FastISel::hasTrivialKill(const Value *V) const {
@@ -645,6 +650,16 @@
}
}
+ // Usually, it does not make sense to initialize a value,
+ // make an unrelated function call and use the value, because
+ // it tends to be spilled on the stack. So, we move the pointer
+ // to the last local value to the beginning of the block, so that
+ // all the values which have already been materialized,
+ // appear after the call. It also makes sense to skip intrinsics
+ // since they tend to be inlined.
+ if (!isa<IntrinsicInst>(F))
+ flushLocalValueMap();
+
// An arbitrary call. Bail.
return false;
}