[llvm-commits] [llvm] r97706 - /llvm/trunk/lib/CodeGen/MachineCSE.cpp
Evan Cheng
evan.cheng at apple.com
Wed Mar 3 17:33:56 PST 2010
Author: evancheng
Date: Wed Mar 3 19:33:55 2010
New Revision: 97706
URL: http://llvm.org/viewvc/llvm-project?rev=97706&view=rev
Log:
Look ahead a bit to determine if a physical register def that is not marked dead is really alive. This is necessary to catch a lot of common cse opportunities for targets like x86.
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=97706&r1=97705&r2=97706&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MachineCSE.cpp (original)
+++ llvm/trunk/lib/CodeGen/MachineCSE.cpp Wed Mar 3 19:33:55 2010
@@ -31,6 +31,7 @@
namespace {
class MachineCSE : public MachineFunctionPass {
const TargetInstrInfo *TII;
+ const TargetRegisterInfo *TRI;
MachineRegisterInfo *MRI;
MachineDominatorTree *DT;
public:
@@ -51,6 +52,10 @@
ScopedHashTable<MachineInstr*, unsigned, MachineInstrExpressionTrait> VNT;
SmallVector<MachineInstr*, 64> Exps;
+ bool hasLivePhysRegDefUse(MachineInstr *MI, MachineBasicBlock *MBB);
+ bool isPhysDefTriviallyDead(unsigned Reg,
+ MachineBasicBlock::const_iterator I,
+ MachineBasicBlock::const_iterator E);
bool PerformTrivialCoalescing(MachineInstr *MI, MachineBasicBlock *MBB);
bool ProcessBlock(MachineDomTreeNode *Node);
};
@@ -93,7 +98,39 @@
return Changed;
}
-static bool hasLivePhysRegDefUse(MachineInstr *MI) {
+bool MachineCSE::isPhysDefTriviallyDead(unsigned Reg,
+ MachineBasicBlock::const_iterator I,
+ MachineBasicBlock::const_iterator E) {
+ unsigned LookAheadLeft = 5;
+ while (LookAheadLeft--) {
+ if (I == E)
+ // Reached end of block, register is obviously dead.
+ return true;
+
+ if (I->isDebugValue())
+ continue;
+ bool SeenDef = false;
+ for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {
+ const MachineOperand &MO = I->getOperand(i);
+ if (!MO.isReg() || !MO.getReg())
+ continue;
+ if (!TRI->regsOverlap(MO.getReg(), Reg))
+ continue;
+ if (MO.isUse())
+ return false;
+ SeenDef = true;
+ }
+ if (SeenDef)
+ // See a def of Reg (or an alias) before encountering any use, it's
+ // trivially dead.
+ return true;
+ ++I;
+ }
+ return false;
+}
+
+bool MachineCSE::hasLivePhysRegDefUse(MachineInstr *MI, MachineBasicBlock *MBB){
+ unsigned PhysDef = 0;
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
MachineOperand &MO = MI->getOperand(i);
if (!MO.isReg())
@@ -101,10 +138,26 @@
unsigned Reg = MO.getReg();
if (!Reg)
continue;
- // FIXME: This is obviously overly conservative. On x86 lots of instructions
- // will def EFLAGS and they are not marked dead at this point.
- if (TargetRegisterInfo::isPhysicalRegister(Reg) &&
- !(MO.isDef() && MO.isDead()))
+ if (TargetRegisterInfo::isPhysicalRegister(Reg)) {
+ if (MO.isUse())
+ // Can't touch anything to read a physical register.
+ return true;
+ if (MO.isDead())
+ // If the def is dead, it's ok.
+ continue;
+ // Ok, this is a physical register def that's not marked "dead". That's
+ // common since this pass is run before livevariables. We can scan
+ // forward a few instructions and check if it is obviously dead.
+ if (PhysDef)
+ // Multiple physical register defs. These are rare, forget about it.
+ return true;
+ PhysDef = Reg;
+ }
+ }
+
+ if (PhysDef) {
+ MachineBasicBlock::iterator I = MI; I = llvm::next(I);
+ if (!isPhysDefTriviallyDead(PhysDef, I, MBB->end()))
return true;
}
return false;
@@ -135,10 +188,11 @@
if (PerformTrivialCoalescing(MI, MBB))
FoundCSE = VNT.count(MI);
}
+ // FIXME: commute commutable instructions?
// If the instruction defines a physical register and the value *may* be
// used, then it's not safe to replace it with a common subexpression.
- if (FoundCSE && hasLivePhysRegDefUse(MI))
+ if (FoundCSE && hasLivePhysRegDefUse(MI, MBB))
FoundCSE = false;
if (!FoundCSE) {
@@ -180,6 +234,7 @@
bool MachineCSE::runOnMachineFunction(MachineFunction &MF) {
TII = MF.getTarget().getInstrInfo();
+ TRI = MF.getTarget().getRegisterInfo();
MRI = &MF.getRegInfo();
DT = &getAnalysis<MachineDominatorTree>();
return ProcessBlock(DT->getRootNode());
More information about the llvm-commits
mailing list