[llvm-commits] [llvm] r49105 - in /llvm/trunk: include/llvm/CodeGen/LiveVariables.h lib/CodeGen/LiveVariables.cpp
Evan Cheng
evan.cheng at apple.com
Wed Apr 2 11:04:08 PDT 2008
Author: evancheng
Date: Wed Apr 2 13:04:08 2008
New Revision: 49105
URL: http://llvm.org/viewvc/llvm-project?rev=49105&view=rev
Log:
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.
Modified:
llvm/trunk/include/llvm/CodeGen/LiveVariables.h
llvm/trunk/lib/CodeGen/LiveVariables.cpp
Modified: llvm/trunk/include/llvm/CodeGen/LiveVariables.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/LiveVariables.h?rev=49105&r1=49104&r2=49105&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/LiveVariables.h (original)
+++ llvm/trunk/include/llvm/CodeGen/LiveVariables.h Wed Apr 2 13:04:08 2008
@@ -31,11 +31,13 @@
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
namespace llvm {
+class MachineRegisterInfo;
class TargetRegisterInfo;
class LiveVariables : public MachineFunctionPass {
@@ -128,6 +130,8 @@
private: // Intermediate data structures
MachineFunction *MF;
+ MachineRegisterInfo* MRI;
+
const TargetRegisterInfo *TRI;
// PhysRegInfo - Keep track of which instruction was the last def/use of a
@@ -152,6 +156,10 @@
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,
SmallSet<unsigned, 4> &SubKills);
Modified: llvm/trunk/lib/CodeGen/LiveVariables.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveVariables.cpp?rev=49105&r1=49104&r2=49105&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/LiveVariables.cpp (original)
+++ llvm/trunk/lib/CodeGen/LiveVariables.cpp Wed Apr 2 13:04:08 2008
@@ -118,8 +118,7 @@
void LiveVariables::HandleVirtRegUse(unsigned reg, MachineBasicBlock *MBB,
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();
@@ -140,7 +139,7 @@
assert(VRInfo.Kills[i]->getParent() != MBB && "entry should be at end!");
#endif
- assert(MBB != MRI.getVRegDef(reg)->getParent() &&
+ assert(MBB != MRI->getVRegDef(reg)->getParent() &&
"Should have kill for defblock!");
// Add a new kill entry for this basic block. If this virtual register is
@@ -152,7 +151,7 @@
// Update all dominating blocks to mark them as "known live".
for (MachineBasicBlock::const_pred_iterator PI = MBB->pred_begin(),
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
@@ -305,25 +304,63 @@
MachineBasicBlock *MBB) {
if (I == MBB->end())
return false;
- ++I;
- // FIXME: This is slow. We probably need a smarter solution. Possibilities:
- // 1. Scan all instructions once and build def / use information of physical
- // registers. We also need a fast way to compare relative ordering of
- // instructions.
- // 2. Cache information so this function only has to scan instructions that
- // read / def physical instructions.
- for (MachineBasicBlock::iterator E = MBB->end(); I != E; ++I) {
- MachineInstr *MI = I;
- for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
- const MachineOperand &MO = MI->getOperand(i);
- if (!MO.isRegister() || MO.getReg() != Reg)
- continue;
- if (MO.isDef())
- return false;
- return true;
+
+ // First find out if there are any uses / defs below.
+ bool hasDistInfo = true;
+ unsigned CurDist = DistanceMap[I];
+ SmallVector<MachineInstr*, 4> Uses;
+ SmallVector<MachineInstr*, 4> Defs;
+ for (MachineRegisterInfo::reg_iterator RI = MRI->reg_begin(Reg),
+ RE = MRI->reg_end(); RI != RE; ++RI) {
+ MachineOperand &UDO = RI.getOperand();
+ MachineInstr *UDMI = &*RI;
+ if (UDMI->getParent() != MBB)
+ continue;
+ DenseMap<MachineInstr*, unsigned>::iterator DI = DistanceMap.find(UDMI);
+ bool isBelow = false;
+ if (DI == DistanceMap.end()) {
+ // 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) {
@@ -408,8 +445,8 @@
bool LiveVariables::runOnMachineFunction(MachineFunction &mf) {
MF = &mf;
+ MRI = &mf.getRegInfo();
TRI = MF->getTarget().getRegisterInfo();
- MachineRegisterInfo& MRI = mf.getRegInfo();
ReservedRegisters = TRI->getReservedRegs(mf);
@@ -449,9 +486,12 @@
}
// Loop over all of the instructions, processing them.
+ DistanceMap.clear();
+ unsigned Dist = 0;
for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end();
I != E; ++I) {
MachineInstr *MI = I;
+ DistanceMap.insert(std::make_pair(MI, Dist++));
// Process all of the operands of the instruction...
unsigned NumOperandsToProcess = MI->getNumOperands();
@@ -507,7 +547,7 @@
for (SmallVector<unsigned, 4>::iterator I = VarInfoVec.begin(),
E = VarInfoVec.end(); I != E; ++I)
// 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);
}
@@ -549,7 +589,7 @@
for (unsigned i = 0, e1 = VirtRegInfo.size(); i != e1; ++i)
for (unsigned j = 0, e2 = VirtRegInfo[i].Kills.size(); j != e2; ++j)
if (VirtRegInfo[i].Kills[j] ==
- MRI.getVRegDef(i + TargetRegisterInfo::FirstVirtualRegister))
+ MRI->getVRegDef(i + TargetRegisterInfo::FirstVirtualRegister))
VirtRegInfo[i]
.Kills[j]->addRegisterDead(i +
TargetRegisterInfo::FirstVirtualRegister,
More information about the llvm-commits
mailing list