diff options
author | Chris Lattner <sabre@nondot.org> | 2009-04-10 16:38:36 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2009-04-10 16:38:36 +0000 |
commit | 296185c264a47cadd52c8d3290a54837cc32cbe5 (patch) | |
tree | bfd39852fe00a67b06c4b7945a1c68953a23b7aa /lib/CodeGen/MachineSink.cpp | |
parent | 0355862f712ce23ebb82e9e9378e92ef3b34027b (diff) |
fix two problems with machine sinking:
1. Sinking would crash when the first instruction of a block was
sunk due to iterator problems.
2. Instructions could be sunk to their current block, causing an
infinite loop.
This fixes PR3968
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@68787 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/MachineSink.cpp')
-rw-r--r-- | lib/CodeGen/MachineSink.cpp | 38 |
1 files changed, 26 insertions, 12 deletions
diff --git a/lib/CodeGen/MachineSink.cpp b/lib/CodeGen/MachineSink.cpp index 468bd01548..0e18fa742f 100644 --- a/lib/CodeGen/MachineSink.cpp +++ b/lib/CodeGen/MachineSink.cpp @@ -111,20 +111,29 @@ bool MachineSinking::runOnMachineFunction(MachineFunction &MF) { } bool MachineSinking::ProcessBlock(MachineBasicBlock &MBB) { - bool MadeChange = false; - // Can't sink anything out of a block that has less than two successors. - if (MBB.succ_size() <= 1) return false; - + if (MBB.succ_size() <= 1 || MBB.empty()) return false; + + bool MadeChange = false; + // Walk the basic block bottom-up. Remember if we saw a store. - bool SawStore = false; - for (MachineBasicBlock::iterator I = MBB.end(); I != MBB.begin(); ){ - MachineBasicBlock::iterator LastIt = I; - if (SinkInstruction(--I, SawStore)) { - I = LastIt; - ++NumSunk; - } - } + MachineBasicBlock::iterator I = MBB.end(); + --I; + bool ProcessedBegin, SawStore = false; + do { + MachineInstr *MI = I; // The instruction to sink. + + // Predecrement I (if it's not begin) so that it isn't invalidated by + // sinking. + ProcessedBegin = I == MBB.begin(); + if (!ProcessedBegin) + --I; + + if (SinkInstruction(MI, SawStore)) + ++NumSunk, MadeChange = true; + + // If we just processed the first instruction in the block, we're done. + } while (!ProcessedBegin); return MadeChange; } @@ -218,6 +227,11 @@ bool MachineSinking::SinkInstruction(MachineInstr *MI, bool &SawStore) { if (SuccToSinkTo->isLandingPad()) return false; + // If is not possible to sink an instruction into its own block. This can + // happen with loops. + if (MI->getParent() == SuccToSinkTo) + return false; + DEBUG(cerr << "Sink instr " << *MI); DEBUG(cerr << "to block " << *SuccToSinkTo); |