diff options
author | Devang Patel <dpatel@apple.com> | 2011-10-10 19:09:20 +0000 |
---|---|---|
committer | Devang Patel <dpatel@apple.com> | 2011-10-10 19:09:20 +0000 |
commit | 9ac743a4ee61cb845bbe22a2f6898f38c2adafce (patch) | |
tree | c64733717dd89e7c30b5110cd18a084bc3726c04 /lib/CodeGen/MachineLICM.cpp | |
parent | 5a57168a55f23cff1f0d1c7ba4183b4182665e46 (diff) | |
download | external_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.cpp | 30 |
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. |