Work in progress. Finding some cse now.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@97635 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Evan Cheng 2010-03-03 02:48:20 +00:00
parent 99fe641325
commit 6ba9554988

View File

@ -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::ProcessBlock(MachineDomTreeNode *Node) {
ScopedHashTableScope<MachineInstr*, unsigned> VNTS(VNT);
MachineBasicBlock *MBB = Node->getBlock();
for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end(); I != E;
++I) {
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);
}
// 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());
}