summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/CodeGen/FastISel.h7
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/FastISel.cpp15
2 files changed, 18 insertions, 4 deletions
diff --git a/llvm/include/llvm/CodeGen/FastISel.h b/llvm/include/llvm/CodeGen/FastISel.h
index 32d6bb03ec1..c233cd48f44 100644
--- a/llvm/include/llvm/CodeGen/FastISel.h
+++ b/llvm/include/llvm/CodeGen/FastISel.h
@@ -226,6 +226,10 @@ protected:
/// makes sense (for example, on function calls)
MachineInstr *EmitStartPt;
+ /// Last local value flush point. On a subsequent flush, no local value will
+ /// sink past this point.
+ MachineBasicBlock::iterator LastFlushPoint;
+
public:
virtual ~FastISel();
@@ -569,7 +573,8 @@ private:
MachineInstr *FirstTerminator = nullptr;
unsigned FirstTerminatorOrder = std::numeric_limits<unsigned>::max();
- void initialize(MachineBasicBlock *MBB);
+ void initialize(MachineBasicBlock *MBB,
+ MachineBasicBlock::iterator LastFlushPoint);
};
/// Sinks the local value materialization instruction LocalMI to its first use
diff --git a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
index 84196062491..23a7798f867 100644
--- a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
@@ -215,6 +215,7 @@ void FastISel::flushLocalValueMap() {
LastLocalValue = EmitStartPt;
recomputeInsertPt();
SavedInsertPt = FuncInfo.InsertPt;
+ LastFlushPoint = FuncInfo.InsertPt;
}
static bool isRegUsedByPhiNodes(unsigned DefReg,
@@ -228,7 +229,8 @@ static bool isRegUsedByPhiNodes(unsigned DefReg,
/// Build a map of instruction orders. Return the first terminator and its
/// order. Consider EH_LABEL instructions to be terminators as well, since local
/// values for phis after invokes must be materialized before the call.
-void FastISel::InstOrderMap::initialize(MachineBasicBlock *MBB) {
+void FastISel::InstOrderMap::initialize(
+ MachineBasicBlock *MBB, MachineBasicBlock::iterator LastFlushPoint) {
unsigned Order = 0;
for (MachineInstr &I : *MBB) {
if (!FirstTerminator &&
@@ -237,6 +239,10 @@ void FastISel::InstOrderMap::initialize(MachineBasicBlock *MBB) {
FirstTerminatorOrder = Order;
}
Orders[&I] = Order++;
+
+ // We don't need to order instructions past the last flush point.
+ if (I.getIterator() == LastFlushPoint)
+ break;
}
}
@@ -266,13 +272,16 @@ void FastISel::sinkLocalValueMaterialization(MachineInstr &LocalMI,
// Number the instructions if we haven't yet so we can efficiently find the
// earliest use.
if (OrderMap.Orders.empty())
- OrderMap.initialize(FuncInfo.MBB);
+ OrderMap.initialize(FuncInfo.MBB, LastFlushPoint);
// Find the first user in the BB.
MachineInstr *FirstUser = nullptr;
unsigned FirstOrder = std::numeric_limits<unsigned>::max();
for (MachineInstr &UseInst : MRI.use_nodbg_instructions(DefReg)) {
- unsigned UseOrder = OrderMap.Orders[&UseInst];
+ auto I = OrderMap.Orders.find(&UseInst);
+ assert(I != OrderMap.Orders.end() &&
+ "local value used by instruction outside local region");
+ unsigned UseOrder = I->second;
if (UseOrder < FirstOrder) {
FirstOrder = UseOrder;
FirstUser = &UseInst;
OpenPOWER on IntegriCloud