summaryrefslogtreecommitdiff
path: root/lib/CodeGen/MachineSink.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2008-01-12 00:17:41 +0000
committerChris Lattner <sabre@nondot.org>2008-01-12 00:17:41 +0000
commitaad193a7e9f8eb4b558e16c2b54c31dee54f5f1e (patch)
tree43cd1895ed39971de4484c5b5b913474c55180d9 /lib/CodeGen/MachineSink.cpp
parent2769f6fc59cb3bae445e9eff3b5275336665fb9b (diff)
downloadllvm-aad193a7e9f8eb4b558e16c2b54c31dee54f5f1e.tar.gz
llvm-aad193a7e9f8eb4b558e16c2b54c31dee54f5f1e.tar.bz2
llvm-aad193a7e9f8eb4b558e16c2b54c31dee54f5f1e.tar.xz
implement support for sinking a load out the bottom of a block that
has no stores between the load and the end of block. This works great and sinks hundreds of stores, but we can't turn it on because machineinstrs don't have volatility information and we don't want to sink volatile stores :( git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@45894 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/MachineSink.cpp')
-rw-r--r--lib/CodeGen/MachineSink.cpp39
1 files changed, 23 insertions, 16 deletions
diff --git a/lib/CodeGen/MachineSink.cpp b/lib/CodeGen/MachineSink.cpp
index dc3e364e8a..29b0b3f774 100644
--- a/lib/CodeGen/MachineSink.cpp
+++ b/lib/CodeGen/MachineSink.cpp
@@ -47,7 +47,7 @@ namespace {
}
private:
bool ProcessBlock(MachineBasicBlock &MBB);
- bool SinkInstruction(MachineInstr *MI);
+ bool SinkInstruction(MachineInstr *MI, bool &SawStore);
bool AllUsesDominatedByBlock(unsigned Reg, MachineBasicBlock *MBB) const;
};
@@ -115,10 +115,11 @@ bool MachineSinking::ProcessBlock(MachineBasicBlock &MBB) {
// Can't sink anything out of a block that has less than two successors.
if (MBB.succ_size() <= 1) return false;
- // Walk the basic block bottom-up
+ // 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)) {
+ if (SinkInstruction(--I, SawStore)) {
I = LastIt;
++NumSunk;
}
@@ -129,24 +130,30 @@ bool MachineSinking::ProcessBlock(MachineBasicBlock &MBB) {
/// SinkInstruction - Determine whether it is safe to sink the specified machine
/// instruction out of its current block into a successor.
-bool MachineSinking::SinkInstruction(MachineInstr *MI) {
+bool MachineSinking::SinkInstruction(MachineInstr *MI, bool &SawStore) {
const TargetInstrDesc &TID = MI->getDesc();
// Ignore stuff that we obviously can't sink.
- if (TID.mayStore() || TID.isCall() || TID.isReturn() || TID.isBranch() ||
- TID.hasUnmodeledSideEffects())
+ if (TID.mayStore() || TID.isCall()) {
+ SawStore = true;
+ return false;
+ }
+ if (TID.isReturn() || TID.isBranch() || TID.hasUnmodeledSideEffects())
return false;
- if (TID.mayLoad()) {
- // Okay, this instruction does a load. As a refinement, allow the target
- // to decide whether the loaded value is actually a constant. If so, we
- // can actually use it as a load.
- if (!TII->isInvariantLoad(MI)) {
- // FIXME: we should be able to sink loads with no other side effects if
- // there is nothing that can change memory from here until the end of
- // block. This is a trivial form of alias analysis.
- return false;
- }
+ // See if this instruction does a load. If so, we have to guarantee that the
+ // loaded value doesn't change between the load and the end of block. The
+ // check for isInvariantLoad gives the targe the chance to classify the load
+ // as always returning a constant, e.g. a constant pool load.
+ if (TID.mayLoad() && !TII->isInvariantLoad(MI)) {
+ // Otherwise, this is a real load. If there is a store between the load and
+ // end of block, we can't sink the load.
+ //
+ // FIXME: we can't do this transformation until we know that the load is
+ // not volatile, and machineinstrs don't keep this info. :(
+ //
+ //if (SawStore)
+ return false;
}
// FIXME: This should include support for sinking instructions within the