mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-10-20 09:24:58 +00:00
Now that I am told MachineRegisterInfo also tracks physical register uses / defs, I can do away with the horribleness I introduced a while back. It's impossible to detect if there is any use of a physical register below an instruction (and before any def of the register) with some cheap book keeping.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@49105 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
1088317675
commit
ea1d9cdc4e
@ -31,11 +31,13 @@
|
|||||||
|
|
||||||
#include "llvm/CodeGen/MachineFunctionPass.h"
|
#include "llvm/CodeGen/MachineFunctionPass.h"
|
||||||
#include "llvm/ADT/BitVector.h"
|
#include "llvm/ADT/BitVector.h"
|
||||||
|
#include "llvm/ADT/DenseMap.h"
|
||||||
#include "llvm/ADT/SmallSet.h"
|
#include "llvm/ADT/SmallSet.h"
|
||||||
#include "llvm/ADT/SmallVector.h"
|
#include "llvm/ADT/SmallVector.h"
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
|
class MachineRegisterInfo;
|
||||||
class TargetRegisterInfo;
|
class TargetRegisterInfo;
|
||||||
|
|
||||||
class LiveVariables : public MachineFunctionPass {
|
class LiveVariables : public MachineFunctionPass {
|
||||||
@ -128,6 +130,8 @@ private:
|
|||||||
private: // Intermediate data structures
|
private: // Intermediate data structures
|
||||||
MachineFunction *MF;
|
MachineFunction *MF;
|
||||||
|
|
||||||
|
MachineRegisterInfo* MRI;
|
||||||
|
|
||||||
const TargetRegisterInfo *TRI;
|
const TargetRegisterInfo *TRI;
|
||||||
|
|
||||||
// PhysRegInfo - Keep track of which instruction was the last def/use of a
|
// PhysRegInfo - Keep track of which instruction was the last def/use of a
|
||||||
@ -152,6 +156,10 @@ private: // Intermediate data structures
|
|||||||
|
|
||||||
SmallVector<unsigned, 4> *PHIVarInfo;
|
SmallVector<unsigned, 4> *PHIVarInfo;
|
||||||
|
|
||||||
|
// DistanceMap - Keep track the distance of a MI from the start of the
|
||||||
|
// current basic block.
|
||||||
|
DenseMap<MachineInstr*, unsigned> DistanceMap;
|
||||||
|
|
||||||
void addRegisterKills(unsigned Reg, MachineInstr *MI,
|
void addRegisterKills(unsigned Reg, MachineInstr *MI,
|
||||||
SmallSet<unsigned, 4> &SubKills);
|
SmallSet<unsigned, 4> &SubKills);
|
||||||
|
|
||||||
|
@ -118,8 +118,7 @@ void LiveVariables::MarkVirtRegAliveInBlock(VarInfo &VRInfo,
|
|||||||
|
|
||||||
void LiveVariables::HandleVirtRegUse(unsigned reg, MachineBasicBlock *MBB,
|
void LiveVariables::HandleVirtRegUse(unsigned reg, MachineBasicBlock *MBB,
|
||||||
MachineInstr *MI) {
|
MachineInstr *MI) {
|
||||||
const MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo();
|
assert(MRI->getVRegDef(reg) && "Register use before def!");
|
||||||
assert(MRI.getVRegDef(reg) && "Register use before def!");
|
|
||||||
|
|
||||||
unsigned BBNum = MBB->getNumber();
|
unsigned BBNum = MBB->getNumber();
|
||||||
|
|
||||||
@ -140,7 +139,7 @@ void LiveVariables::HandleVirtRegUse(unsigned reg, MachineBasicBlock *MBB,
|
|||||||
assert(VRInfo.Kills[i]->getParent() != MBB && "entry should be at end!");
|
assert(VRInfo.Kills[i]->getParent() != MBB && "entry should be at end!");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
assert(MBB != MRI.getVRegDef(reg)->getParent() &&
|
assert(MBB != MRI->getVRegDef(reg)->getParent() &&
|
||||||
"Should have kill for defblock!");
|
"Should have kill for defblock!");
|
||||||
|
|
||||||
// Add a new kill entry for this basic block. If this virtual register is
|
// Add a new kill entry for this basic block. If this virtual register is
|
||||||
@ -152,7 +151,7 @@ void LiveVariables::HandleVirtRegUse(unsigned reg, MachineBasicBlock *MBB,
|
|||||||
// Update all dominating blocks to mark them as "known live".
|
// Update all dominating blocks to mark them as "known live".
|
||||||
for (MachineBasicBlock::const_pred_iterator PI = MBB->pred_begin(),
|
for (MachineBasicBlock::const_pred_iterator PI = MBB->pred_begin(),
|
||||||
E = MBB->pred_end(); PI != E; ++PI)
|
E = MBB->pred_end(); PI != E; ++PI)
|
||||||
MarkVirtRegAliveInBlock(VRInfo, MRI.getVRegDef(reg)->getParent(), *PI);
|
MarkVirtRegAliveInBlock(VRInfo, MRI->getVRegDef(reg)->getParent(), *PI);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// HandlePhysRegUse - Turn previous partial def's into read/mod/writes. Add
|
/// HandlePhysRegUse - Turn previous partial def's into read/mod/writes. Add
|
||||||
@ -305,25 +304,63 @@ bool LiveVariables::hasRegisterUseBelow(unsigned Reg,
|
|||||||
MachineBasicBlock *MBB) {
|
MachineBasicBlock *MBB) {
|
||||||
if (I == MBB->end())
|
if (I == MBB->end())
|
||||||
return false;
|
return false;
|
||||||
++I;
|
|
||||||
// FIXME: This is slow. We probably need a smarter solution. Possibilities:
|
// First find out if there are any uses / defs below.
|
||||||
// 1. Scan all instructions once and build def / use information of physical
|
bool hasDistInfo = true;
|
||||||
// registers. We also need a fast way to compare relative ordering of
|
unsigned CurDist = DistanceMap[I];
|
||||||
// instructions.
|
SmallVector<MachineInstr*, 4> Uses;
|
||||||
// 2. Cache information so this function only has to scan instructions that
|
SmallVector<MachineInstr*, 4> Defs;
|
||||||
// read / def physical instructions.
|
for (MachineRegisterInfo::reg_iterator RI = MRI->reg_begin(Reg),
|
||||||
for (MachineBasicBlock::iterator E = MBB->end(); I != E; ++I) {
|
RE = MRI->reg_end(); RI != RE; ++RI) {
|
||||||
MachineInstr *MI = I;
|
MachineOperand &UDO = RI.getOperand();
|
||||||
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
|
MachineInstr *UDMI = &*RI;
|
||||||
const MachineOperand &MO = MI->getOperand(i);
|
if (UDMI->getParent() != MBB)
|
||||||
if (!MO.isRegister() || MO.getReg() != Reg)
|
continue;
|
||||||
continue;
|
DenseMap<MachineInstr*, unsigned>::iterator DI = DistanceMap.find(UDMI);
|
||||||
if (MO.isDef())
|
bool isBelow = false;
|
||||||
return false;
|
if (DI == DistanceMap.end()) {
|
||||||
return true;
|
// Must be below if it hasn't been assigned a distance yet.
|
||||||
|
isBelow = true;
|
||||||
|
hasDistInfo = false;
|
||||||
|
} else if (DI->second > CurDist)
|
||||||
|
isBelow = true;
|
||||||
|
if (isBelow) {
|
||||||
|
if (UDO.isUse())
|
||||||
|
Uses.push_back(UDMI);
|
||||||
|
if (UDO.isDef())
|
||||||
|
Defs.push_back(UDMI);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
|
if (Uses.empty())
|
||||||
|
// No uses below.
|
||||||
|
return false;
|
||||||
|
else if (!Uses.empty() && Defs.empty())
|
||||||
|
// There are uses below but no defs below.
|
||||||
|
return true;
|
||||||
|
// There are both uses and defs below. We need to know which comes first.
|
||||||
|
if (!hasDistInfo) {
|
||||||
|
// Complete DistanceMap for this MBB. This information is computed only
|
||||||
|
// once per MBB.
|
||||||
|
++I;
|
||||||
|
++CurDist;
|
||||||
|
for (MachineBasicBlock::iterator E = MBB->end(); I != E; ++I, ++CurDist)
|
||||||
|
DistanceMap.insert(std::make_pair(I, CurDist));
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned EarliestUse = CurDist;
|
||||||
|
for (unsigned i = 0, e = Uses.size(); i != e; ++i) {
|
||||||
|
unsigned Dist = DistanceMap[Uses[i]];
|
||||||
|
if (Dist < EarliestUse)
|
||||||
|
EarliestUse = Dist;
|
||||||
|
}
|
||||||
|
for (unsigned i = 0, e = Defs.size(); i != e; ++i) {
|
||||||
|
unsigned Dist = DistanceMap[Defs[i]];
|
||||||
|
if (Dist < EarliestUse)
|
||||||
|
// The register is defined before its first use below.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LiveVariables::HandlePhysRegDef(unsigned Reg, MachineInstr *MI) {
|
void LiveVariables::HandlePhysRegDef(unsigned Reg, MachineInstr *MI) {
|
||||||
@ -408,8 +445,8 @@ void LiveVariables::HandlePhysRegDef(unsigned Reg, MachineInstr *MI) {
|
|||||||
|
|
||||||
bool LiveVariables::runOnMachineFunction(MachineFunction &mf) {
|
bool LiveVariables::runOnMachineFunction(MachineFunction &mf) {
|
||||||
MF = &mf;
|
MF = &mf;
|
||||||
|
MRI = &mf.getRegInfo();
|
||||||
TRI = MF->getTarget().getRegisterInfo();
|
TRI = MF->getTarget().getRegisterInfo();
|
||||||
MachineRegisterInfo& MRI = mf.getRegInfo();
|
|
||||||
|
|
||||||
ReservedRegisters = TRI->getReservedRegs(mf);
|
ReservedRegisters = TRI->getReservedRegs(mf);
|
||||||
|
|
||||||
@ -449,9 +486,12 @@ bool LiveVariables::runOnMachineFunction(MachineFunction &mf) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Loop over all of the instructions, processing them.
|
// Loop over all of the instructions, processing them.
|
||||||
|
DistanceMap.clear();
|
||||||
|
unsigned Dist = 0;
|
||||||
for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end();
|
for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end();
|
||||||
I != E; ++I) {
|
I != E; ++I) {
|
||||||
MachineInstr *MI = I;
|
MachineInstr *MI = I;
|
||||||
|
DistanceMap.insert(std::make_pair(MI, Dist++));
|
||||||
|
|
||||||
// Process all of the operands of the instruction...
|
// Process all of the operands of the instruction...
|
||||||
unsigned NumOperandsToProcess = MI->getNumOperands();
|
unsigned NumOperandsToProcess = MI->getNumOperands();
|
||||||
@ -507,7 +547,7 @@ bool LiveVariables::runOnMachineFunction(MachineFunction &mf) {
|
|||||||
for (SmallVector<unsigned, 4>::iterator I = VarInfoVec.begin(),
|
for (SmallVector<unsigned, 4>::iterator I = VarInfoVec.begin(),
|
||||||
E = VarInfoVec.end(); I != E; ++I)
|
E = VarInfoVec.end(); I != E; ++I)
|
||||||
// Mark it alive only in the block we are representing.
|
// Mark it alive only in the block we are representing.
|
||||||
MarkVirtRegAliveInBlock(getVarInfo(*I), MRI.getVRegDef(*I)->getParent(),
|
MarkVirtRegAliveInBlock(getVarInfo(*I),MRI->getVRegDef(*I)->getParent(),
|
||||||
MBB);
|
MBB);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -549,7 +589,7 @@ bool LiveVariables::runOnMachineFunction(MachineFunction &mf) {
|
|||||||
for (unsigned i = 0, e1 = VirtRegInfo.size(); i != e1; ++i)
|
for (unsigned i = 0, e1 = VirtRegInfo.size(); i != e1; ++i)
|
||||||
for (unsigned j = 0, e2 = VirtRegInfo[i].Kills.size(); j != e2; ++j)
|
for (unsigned j = 0, e2 = VirtRegInfo[i].Kills.size(); j != e2; ++j)
|
||||||
if (VirtRegInfo[i].Kills[j] ==
|
if (VirtRegInfo[i].Kills[j] ==
|
||||||
MRI.getVRegDef(i + TargetRegisterInfo::FirstVirtualRegister))
|
MRI->getVRegDef(i + TargetRegisterInfo::FirstVirtualRegister))
|
||||||
VirtRegInfo[i]
|
VirtRegInfo[i]
|
||||||
.Kills[j]->addRegisterDead(i +
|
.Kills[j]->addRegisterDead(i +
|
||||||
TargetRegisterInfo::FirstVirtualRegister,
|
TargetRegisterInfo::FirstVirtualRegister,
|
||||||
|
Loading…
Reference in New Issue
Block a user