mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-05 12:31:33 +00:00
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:
parent
99fe641325
commit
6ba9554988
@ -17,6 +17,8 @@
|
|||||||
#include "llvm/CodeGen/Passes.h"
|
#include "llvm/CodeGen/Passes.h"
|
||||||
#include "llvm/CodeGen/MachineDominators.h"
|
#include "llvm/CodeGen/MachineDominators.h"
|
||||||
#include "llvm/CodeGen/MachineInstr.h"
|
#include "llvm/CodeGen/MachineInstr.h"
|
||||||
|
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||||
|
#include "llvm/Target/TargetInstrInfo.h"
|
||||||
#include "llvm/ADT/ScopedHashTable.h"
|
#include "llvm/ADT/ScopedHashTable.h"
|
||||||
#include "llvm/ADT/Statistic.h"
|
#include "llvm/ADT/Statistic.h"
|
||||||
#include "llvm/Support/Debug.h"
|
#include "llvm/Support/Debug.h"
|
||||||
@ -41,6 +43,8 @@ namespace llvm {
|
|||||||
switch (MO.getType()) {
|
switch (MO.getType()) {
|
||||||
default: break;
|
default: break;
|
||||||
case MachineOperand::MO_Register:
|
case MachineOperand::MO_Register:
|
||||||
|
if (MO.isDef() && TargetRegisterInfo::isVirtualRegister(MO.getReg()))
|
||||||
|
continue; // Skip virtual register defs.
|
||||||
Key |= MO.getReg();
|
Key |= MO.getReg();
|
||||||
break;
|
break;
|
||||||
case MachineOperand::MO_Immediate:
|
case MachineOperand::MO_Immediate:
|
||||||
@ -76,18 +80,24 @@ namespace llvm {
|
|||||||
|
|
||||||
static bool isEqual(const MachineInstr* const &LHS,
|
static bool isEqual(const MachineInstr* const &LHS,
|
||||||
const MachineInstr* const &RHS) {
|
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
|
} // end llvm namespace
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
class MachineCSE : public MachineFunctionPass {
|
class MachineCSE : public MachineFunctionPass {
|
||||||
ScopedHashTable<MachineInstr*, unsigned> VNT;
|
const TargetInstrInfo *TII;
|
||||||
|
MachineRegisterInfo *MRI;
|
||||||
MachineDominatorTree *DT;
|
MachineDominatorTree *DT;
|
||||||
|
ScopedHashTable<MachineInstr*, unsigned> VNT;
|
||||||
|
unsigned CurrVN;
|
||||||
public:
|
public:
|
||||||
static char ID; // Pass identification
|
static char ID; // Pass identification
|
||||||
MachineCSE() : MachineFunctionPass(&ID) {}
|
MachineCSE() : MachineFunctionPass(&ID), CurrVN(0) {}
|
||||||
|
|
||||||
virtual bool runOnMachineFunction(MachineFunction &MF);
|
virtual bool runOnMachineFunction(MachineFunction &MF);
|
||||||
|
|
||||||
@ -99,6 +109,7 @@ namespace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool PerformTrivialCoalescing(MachineInstr *MI, MachineBasicBlock *MBB);
|
||||||
bool ProcessBlock(MachineDomTreeNode *Node);
|
bool ProcessBlock(MachineDomTreeNode *Node);
|
||||||
};
|
};
|
||||||
} // end anonymous namespace
|
} // end anonymous namespace
|
||||||
@ -109,16 +120,89 @@ X("machine-cse", "Machine Common Subexpression Elimination");
|
|||||||
|
|
||||||
FunctionPass *llvm::createMachineCSEPass() { return new MachineCSE(); }
|
FunctionPass *llvm::createMachineCSEPass() { return new MachineCSE(); }
|
||||||
|
|
||||||
bool MachineCSE::ProcessBlock(MachineDomTreeNode *Node) {
|
bool MachineCSE::PerformTrivialCoalescing(MachineInstr *MI,
|
||||||
ScopedHashTableScope<MachineInstr*, unsigned> VNTS(VNT);
|
MachineBasicBlock *MBB) {
|
||||||
MachineBasicBlock *MBB = Node->getBlock();
|
bool Changed = false;
|
||||||
for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end(); I != E;
|
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
|
||||||
++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;
|
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) {
|
bool MachineCSE::runOnMachineFunction(MachineFunction &MF) {
|
||||||
|
TII = MF.getTarget().getInstrInfo();
|
||||||
|
MRI = &MF.getRegInfo();
|
||||||
DT = &getAnalysis<MachineDominatorTree>();
|
DT = &getAnalysis<MachineDominatorTree>();
|
||||||
return ProcessBlock(DT->getRootNode());
|
return ProcessBlock(DT->getRootNode());
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user