summaryrefslogtreecommitdiff
path: root/lib/CodeGen/MachineCSE.cpp
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2010-03-03 02:48:20 +0000
committerEvan Cheng <evan.cheng@apple.com>2010-03-03 02:48:20 +0000
commit6ba9554988f2efe13c6556c6149aea4846cf415d (patch)
tree9f9964e1433d23f3d9981d245760d162584c8d31 /lib/CodeGen/MachineCSE.cpp
parent99fe6413252b0b434d03536739840cd40421bf1a (diff)
downloadllvm-6ba9554988f2efe13c6556c6149aea4846cf415d.tar.gz
llvm-6ba9554988f2efe13c6556c6149aea4846cf415d.tar.bz2
llvm-6ba9554988f2efe13c6556c6149aea4846cf415d.tar.xz
Work in progress. Finding some cse now.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@97635 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/MachineCSE.cpp')
-rw-r--r--lib/CodeGen/MachineCSE.cpp92
1 files changed, 88 insertions, 4 deletions
diff --git a/lib/CodeGen/MachineCSE.cpp b/lib/CodeGen/MachineCSE.cpp
index 6f80741ee2..023ace2d21 100644
--- a/lib/CodeGen/MachineCSE.cpp
+++ b/lib/CodeGen/MachineCSE.cpp
@@ -17,6 +17,8 @@
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/MachineDominators.h"
#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/ADT/ScopedHashTable.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Support/Debug.h"
@@ -41,6 +43,8 @@ namespace llvm {
switch (MO.getType()) {
default: break;
case MachineOperand::MO_Register:
+ if (MO.isDef() && TargetRegisterInfo::isVirtualRegister(MO.getReg()))
+ continue; // Skip virtual register defs.
Key |= MO.getReg();
break;
case MachineOperand::MO_Immediate:
@@ -76,18 +80,24 @@ namespace llvm {
static bool isEqual(const MachineInstr* const &LHS,
const MachineInstr* const &RHS) {
- return LHS->isIdenticalTo(RHS);
+ if (RHS == getEmptyKey() || RHS == getTombstoneKey() ||
+ LHS == getEmptyKey() || LHS == getTombstoneKey())
+ return LHS == RHS;
+ return LHS->isIdenticalTo(RHS, MachineInstr::IgnoreVRegDefs);
}
};
} // end llvm namespace
namespace {
class MachineCSE : public MachineFunctionPass {
- ScopedHashTable<MachineInstr*, unsigned> VNT;
+ const TargetInstrInfo *TII;
+ MachineRegisterInfo *MRI;
MachineDominatorTree *DT;
+ ScopedHashTable<MachineInstr*, unsigned> VNT;
+ unsigned CurrVN;
public:
static char ID; // Pass identification
- MachineCSE() : MachineFunctionPass(&ID) {}
+ MachineCSE() : MachineFunctionPass(&ID), CurrVN(0) {}
virtual bool runOnMachineFunction(MachineFunction &MF);
@@ -99,6 +109,7 @@ namespace {
}
private:
+ bool PerformTrivialCoalescing(MachineInstr *MI, MachineBasicBlock *MBB);
bool ProcessBlock(MachineDomTreeNode *Node);
};
} // end anonymous namespace
@@ -109,16 +120,89 @@ X("machine-cse", "Machine Common Subexpression Elimination");
FunctionPass *llvm::createMachineCSEPass() { return new MachineCSE(); }
+bool MachineCSE::PerformTrivialCoalescing(MachineInstr *MI,
+ MachineBasicBlock *MBB) {
+ bool Changed = false;
+ for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
+ MachineOperand &MO = MI->getOperand(i);
+ if (MO.isReg() && MO.isUse()) {
+ unsigned Reg = MO.getReg();
+ if (!Reg || TargetRegisterInfo::isPhysicalRegister(Reg))
+ continue;
+ MachineInstr *DefMI = MRI->getVRegDef(Reg);
+ if (DefMI->getParent() == MBB) {
+ unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx;
+ if (TII->isMoveInstr(*DefMI, SrcReg, DstReg, SrcSubIdx, DstSubIdx) &&
+ TargetRegisterInfo::isVirtualRegister(SrcReg) &&
+ !SrcSubIdx && !DstSubIdx) {
+ MO.setReg(SrcReg);
+ Changed = true;
+ }
+ }
+ }
+ }
+
+ return Changed;
+}
+
+static bool hasLivePhysRegDefUse(MachineInstr *MI) {
+ for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
+ MachineOperand &MO = MI->getOperand(i);
+ if (!MO.isReg())
+ continue;
+ unsigned Reg = MO.getReg();
+ if (!Reg)
+ continue;
+ if (TargetRegisterInfo::isPhysicalRegister(Reg) &&
+ !(MO.isDef() && MO.isDead()))
+ return true;
+ }
+ return false;
+}
+
bool MachineCSE::ProcessBlock(MachineDomTreeNode *Node) {
+ bool Changed = false;
+
ScopedHashTableScope<MachineInstr*, unsigned> VNTS(VNT);
MachineBasicBlock *MBB = Node->getBlock();
for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end(); I != E;
++I) {
+ MachineInstr *MI = &*I;
+ bool SawStore = false;
+ if (!MI->isSafeToMove(TII, 0, SawStore))
+ continue;
+ // Ignore copies or instructions that read / write physical registers
+ // (except for dead defs of physical registers).
+ unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx;
+ if (TII->isMoveInstr(*MI, SrcReg, DstReg, SrcSubIdx, DstSubIdx))
+ continue;
+ if (hasLivePhysRegDefUse(MI))
+ continue;
+
+ bool FoundCSE = VNT.count(MI);
+ if (!FoundCSE) {
+ // Look for trivial copy coalescing opportunities.
+ if (PerformTrivialCoalescing(MI, MBB))
+ FoundCSE = VNT.count(MI);
+ }
+
+ if (FoundCSE)
+ DEBUG(dbgs() << "Found a common subexpression: " << *MI);
+ else
+ VNT.insert(MI, ++CurrVN);
}
- return false;
+
+ // Recursively call ProcessBlock with childred.
+ const std::vector<MachineDomTreeNode*> &Children = Node->getChildren();
+ for (unsigned i = 0, e = Children.size(); i != e; ++i)
+ Changed |= ProcessBlock(Children[i]);
+
+ return Changed;
}
bool MachineCSE::runOnMachineFunction(MachineFunction &MF) {
+ TII = MF.getTarget().getInstrInfo();
+ MRI = &MF.getRegInfo();
DT = &getAnalysis<MachineDominatorTree>();
return ProcessBlock(DT->getRootNode());
}