From 4eab008b5a300411ba33363d3a5ba68fad0d0712 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Wed, 3 Mar 2010 02:48:20 +0000 Subject: [PATCH] Work in progress. Finding some cse now. llvm-svn: 97635 --- llvm/lib/CodeGen/MachineCSE.cpp | 100 +++++++++++++++++++++++++++++--- 1 file changed, 92 insertions(+), 8 deletions(-) diff --git a/llvm/lib/CodeGen/MachineCSE.cpp b/llvm/lib/CodeGen/MachineCSE.cpp index 6f80741ee2e4..023ace2d219c 100644 --- a/llvm/lib/CodeGen/MachineCSE.cpp +++ b/llvm/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 VNT; + const TargetInstrInfo *TII; + MachineRegisterInfo *MRI; MachineDominatorTree *DT; + ScopedHashTable 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 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 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 &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(); return ProcessBlock(DT->getRootNode()); }