aboutsummaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/MachineLICM.cpp
diff options
context:
space:
mode:
authorDevang Patel <dpatel@apple.com>2011-10-10 19:09:20 +0000
committerDevang Patel <dpatel@apple.com>2011-10-10 19:09:20 +0000
commit9ac743a4ee61cb845bbe22a2f6898f38c2adafce (patch)
treec64733717dd89e7c30b5110cd18a084bc3726c04 /lib/CodeGen/MachineLICM.cpp
parent5a57168a55f23cff1f0d1c7ba4183b4182665e46 (diff)
downloadexternal_llvm-9ac743a4ee61cb845bbe22a2f6898f38c2adafce.zip
external_llvm-9ac743a4ee61cb845bbe22a2f6898f38c2adafce.tar.gz
external_llvm-9ac743a4ee61cb845bbe22a2f6898f38c2adafce.tar.bz2
Add dominance check for the instruction being hoisted.
For example, MachineLICM should not hoist a load that is not guaranteed to be executed. Radar 10254254. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@141569 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/MachineLICM.cpp')
-rw-r--r--lib/CodeGen/MachineLICM.cpp30
1 files changed, 30 insertions, 0 deletions
diff --git a/lib/CodeGen/MachineLICM.cpp b/lib/CodeGen/MachineLICM.cpp
index d310f25..f8cbe41 100644
--- a/lib/CodeGen/MachineLICM.cpp
+++ b/lib/CodeGen/MachineLICM.cpp
@@ -168,6 +168,11 @@ namespace {
///
bool IsLoopInvariantInst(MachineInstr &I);
+ /// IsGuaranteedToExecute - check to make sure that the MI dominates
+ /// all of the exit blocks. If it doesn't, then there is a path out of the
+ /// loop which does not execute this instruction, so we can't hoist it.
+ bool IsGuaranteedToExecute(MachineInstr *MI);
+
/// HasAnyPHIUse - Return true if the specified register is used by any
/// phi node.
bool HasAnyPHIUse(unsigned Reg) const;
@@ -1129,6 +1134,29 @@ bool MachineLICM::EliminateCSE(MachineInstr *MI,
return false;
}
+/// IsGuaranteedToExecute - check to make sure that the instruction dominates
+/// all of the exit blocks. If it doesn't, then there is a path out of the loop
+/// which does not execute this instruction, so we can't hoist it.
+bool MachineLICM::IsGuaranteedToExecute(MachineInstr *MI) {
+ // If the instruction is in the header block for the loop (which is very
+ // common), it is always guaranteed to dominate the exit blocks. Since this
+ // is a common case, and can save some work, check it now.
+ if (MI->getParent() == CurLoop->getHeader())
+ return true;
+
+ // Get the exit blocks for the current loop.
+ SmallVector<MachineBasicBlock*, 8> ExitBlocks;
+ CurLoop->getExitingBlocks(ExitBlocks);
+
+ // Verify that the block dominates each of the exit blocks of the loop.
+ for (unsigned i = 0, e = ExitBlocks.size(); i != e; ++i)
+ if (ExitBlocks[i] != CurLoop->getHeader() &&
+ !DT->dominates(MI->getParent(), ExitBlocks[i]))
+ return false;
+
+ return true;
+}
+
/// Hoist - When an instruction is found to use only loop invariant operands
/// that are safe to hoist, this instruction is called to do the dirty work.
///
@@ -1139,6 +1167,8 @@ bool MachineLICM::Hoist(MachineInstr *MI, MachineBasicBlock *Preheader) {
MI = ExtractHoistableLoad(MI);
if (!MI) return false;
}
+ if (!IsGuaranteedToExecute(MI))
+ return false;
// Now move the instructions to the predecessor, inserting it before any
// terminator instructions.