void LiveVariables::VarInfo::dump() const {
cerr << " Alive in blocks: ";
- for (int i = AliveBlocks.find_first(); i != -1; i = AliveBlocks.find_next(i))
- cerr << i << ", ";
- cerr << " Used in blocks: ";
- for (int i = UsedBlocks.find_first(); i != -1; i = UsedBlocks.find_next(i))
- cerr << i << ", ";
+ for (SparseBitVector<>::iterator I = AliveBlocks.begin(),
+ E = AliveBlocks.end(); I != E; ++I)
+ cerr << *I << ", ";
cerr << "\n Killed by:";
if (Kills.empty())
cerr << " No instructions.\n";
else
VirtRegInfo.resize(2*VirtRegInfo.size());
}
- VarInfo &VI = VirtRegInfo[RegIdx];
- VI.AliveBlocks.resize(MF->getNumBlockIDs());
- VI.UsedBlocks.resize(MF->getNumBlockIDs());
- return VI;
+ return VirtRegInfo[RegIdx];
}
void LiveVariables::MarkVirtRegAliveInBlock(VarInfo& VRInfo,
if (MBB == DefBlock) return; // Terminate recursion
- if (VRInfo.AliveBlocks[BBNum])
+ if (VRInfo.AliveBlocks.test(BBNum))
return; // We already know the block is live
// Mark the variable known alive in this bb
- VRInfo.AliveBlocks[BBNum] = true;
+ VRInfo.AliveBlocks.set(BBNum);
for (MachineBasicBlock::const_pred_reverse_iterator PI = MBB->pred_rbegin(),
E = MBB->pred_rend(); PI != E; ++PI)
unsigned BBNum = MBB->getNumber();
VarInfo& VRInfo = getVarInfo(reg);
- VRInfo.UsedBlocks[BBNum] = true;
VRInfo.NumUses++;
// Check to see if this basic block is already a kill block.
// Add a new kill entry for this basic block. If this virtual register is
// already marked as alive in this basic block, that means it is alive in at
// least one of the successor blocks, it's not a kill.
- if (!VRInfo.AliveBlocks[BBNum])
+ if (!VRInfo.AliveBlocks.test(BBNum))
VRInfo.Kills.push_back(MI);
// Update all dominating blocks to mark them as "known live".
void LiveVariables::HandleVirtRegDef(unsigned Reg, MachineInstr *MI) {
VarInfo &VRInfo = getVarInfo(Reg);
- if (VRInfo.AliveBlocks.none())
+ if (VRInfo.AliveBlocks.empty())
// If vr is not alive in any block, then defaults to dead.
VRInfo.Kills.push_back(MI);
}
}
}
- // There was an earlier def of a super-register. Add implicit def to that MI.
- //
- // A: EAX = ...
- // B: ... = AX
- //
- // Add implicit def to A if there isn't a use of AX (or EAX) before B.
- if (!PhysRegUse[Reg]) {
- MachineInstr *Def = PhysRegDef[Reg];
- if (Def && !Def->modifiesRegister(Reg))
- Def->addOperand(MachineOperand::CreateReg(Reg,
- true /*IsDef*/,
- true /*IsImp*/));
- }
-
// Remember this use.
PhysRegUse[Reg] = MI;
for (const unsigned *SubRegs = TRI->getSubRegisters(Reg);
return true;
}
-bool LiveVariables::HandlePhysRegKill(unsigned Reg) {
+bool LiveVariables::HandlePhysRegKill(unsigned Reg, MachineInstr *MI) {
if (!PhysRegUse[Reg] && !PhysRegDef[Reg])
return false;
}
}
}
- if (LastRefOrPartRef == PhysRegDef[Reg])
- // Not used at all.
+
+ if (LastRefOrPartRef == PhysRegDef[Reg] && LastRefOrPartRef != MI)
+ // If the last reference is the last def, then it's not used at all.
+ // That is, unless we are currently processing the last reference itself.
LastRefOrPartRef->addRegisterDead(Reg, TRI, true);
- /* Partial uses. Mark register def dead and add implicit def of
- sub-registers which are used.
- FIXME: LiveIntervalAnalysis can't handle this yet!
- EAX<dead> = op AL<imp-def>
- That is, EAX def is dead but AL def extends pass it.
- Enable this after live interval analysis is fixed to improve codegen!
+ // Partial uses. Mark register def dead and add implicit def of
+ // sub-registers which are used.
+ // EAX<dead> = op AL<imp-def>
+ // That is, EAX def is dead but AL def extends pass it.
+ // Enable this after live interval analysis is fixed to improve codegen!
else if (!PhysRegUse[Reg]) {
PhysRegDef[Reg]->addRegisterDead(Reg, TRI, true);
for (const unsigned *SubRegs = TRI->getSubRegisters(Reg);
unsigned SubReg = *SubRegs; ++SubRegs) {
if (PartUses.count(SubReg)) {
- PhysRegDef[Reg]->addOperand(MachineOperand::CreateReg(SubReg,
- true, true));
+ bool NeedDef = true;
+ if (PhysRegDef[Reg] == PhysRegDef[SubReg]) {
+ MachineOperand *MO = PhysRegDef[Reg]->findRegisterDefOperand(SubReg);
+ if (MO) {
+ NeedDef = false;
+ assert(!MO->isDead());
+ }
+ }
+ if (NeedDef)
+ PhysRegDef[Reg]->addOperand(MachineOperand::CreateReg(SubReg,
+ true, true));
LastRefOrPartRef->addRegisterKilled(SubReg, TRI, true);
for (const unsigned *SS = TRI->getSubRegisters(SubReg); *SS; ++SS)
PartUses.erase(*SS);
}
}
- } */
+ }
else
LastRefOrPartRef->addRegisterKilled(Reg, TRI, true);
return true;
// Start from the largest piece, find the last time any part of the register
// is referenced.
- if (!HandlePhysRegKill(Reg)) {
+ if (!HandlePhysRegKill(Reg, MI)) {
// Only some of the sub-registers are used.
for (const unsigned *SubRegs = TRI->getSubRegisters(Reg);
unsigned SubReg = *SubRegs; ++SubRegs) {
if (!Live.count(SubReg))
// Skip if this sub-register isn't defined.
continue;
- if (HandlePhysRegKill(SubReg)) {
+ if (HandlePhysRegKill(SubReg, MI)) {
Live.erase(SubReg);
for (const unsigned *SS = TRI->getSubRegisters(SubReg); *SS; ++SS)
Live.erase(*SS);
}
} else {
// Otherwise, the super register is killed.
- if (HandlePhysRegKill(SuperReg)) {
+ if (HandlePhysRegKill(SuperReg, MI)) {
PhysRegDef[SuperReg] = NULL;
PhysRegUse[SuperReg] = NULL;
for (const unsigned *SS = TRI->getSubRegisters(SuperReg); *SS; ++SS) {
SmallVector<unsigned, 4> DefRegs;
for (unsigned i = 0; i != NumOperandsToProcess; ++i) {
const MachineOperand &MO = MI->getOperand(i);
- if (MO.isReg() && MO.getReg()) {
- unsigned MOReg = MO.getReg();
- if (MO.isUse())
- UseRegs.push_back(MOReg);
- if (MO.isDef())
- DefRegs.push_back(MOReg);
- }
+ if (!MO.isReg() || MO.getReg() == 0)
+ continue;
+ unsigned MOReg = MO.getReg();
+ if (MO.isUse())
+ UseRegs.push_back(MOReg);
+ if (MO.isDef())
+ DefRegs.push_back(MOReg);
}
// Process all uses.