[llvm-commits] [llvm] r97635 - /llvm/trunk/lib/CodeGen/MachineCSE.cpp
Evan Cheng
evan.cheng at apple.com
Tue Mar 2 18:48:20 PST 2010
Author: evancheng
Date: Tue Mar 2 20:48:20 2010
New Revision: 97635
URL: http://llvm.org/viewvc/llvm-project?rev=97635&view=rev
Log:
Work in progress. Finding some cse now.
Modified:
llvm/trunk/lib/CodeGen/MachineCSE.cpp
Modified: llvm/trunk/lib/CodeGen/MachineCSE.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineCSE.cpp?rev=97635&r1=97634&r2=97635&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MachineCSE.cpp (original)
+++ llvm/trunk/lib/CodeGen/MachineCSE.cpp Tue Mar 2 20:48:20 2010
@@ -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 @@
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 @@
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 @@
}
private:
+ bool PerformTrivialCoalescing(MachineInstr *MI, MachineBasicBlock *MBB);
bool ProcessBlock(MachineDomTreeNode *Node);
};
} // end anonymous namespace
@@ -109,16 +120,89 @@
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());
}
More information about the llvm-commits
mailing list