#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/ADT/DepthFirstIterator.h"
+#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Config/alloca.h"
#include <algorithm>
bool LiveVariables::KillsRegister(MachineInstr *MI, unsigned Reg) const {
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
MachineOperand &MO = MI->getOperand(i);
- if (MO.isReg() && MO.isKill()) {
+ if (MO.isRegister() && MO.isKill()) {
if ((MO.getReg() == Reg) ||
(MRegisterInfo::isPhysicalRegister(MO.getReg()) &&
MRegisterInfo::isPhysicalRegister(Reg) &&
bool LiveVariables::RegisterDefIsDead(MachineInstr *MI, unsigned Reg) const {
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
MachineOperand &MO = MI->getOperand(i);
- if (MO.isReg() && MO.isDead()) {
+ if (MO.isRegister() && MO.isDead()) {
if ((MO.getReg() == Reg) ||
(MRegisterInfo::isPhysicalRegister(MO.getReg()) &&
MRegisterInfo::isPhysicalRegister(Reg) &&
bool LiveVariables::ModifiesRegister(MachineInstr *MI, unsigned Reg) const {
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
MachineOperand &MO = MI->getOperand(i);
- if (MO.isReg() && MO.isDef() && MO.getReg() == Reg)
+ if (MO.isRegister() && MO.isDef() && MO.getReg() == Reg)
return true;
}
return false;
}
void LiveVariables::MarkVirtRegAliveInBlock(VarInfo &VRInfo,
- MachineBasicBlock *MBB) {
+ MachineBasicBlock *MBB,
+ std::vector<MachineBasicBlock*> &WorkList) {
unsigned BBNum = MBB->getNumber();
// Check to see if this basic block is one of the killing blocks. If so,
// Mark the variable known alive in this bb
VRInfo.AliveBlocks[BBNum] = true;
- for (MachineBasicBlock::const_pred_iterator PI = MBB->pred_begin(),
- E = MBB->pred_end(); PI != E; ++PI)
- MarkVirtRegAliveInBlock(VRInfo, *PI);
+ for (MachineBasicBlock::const_pred_reverse_iterator PI = MBB->pred_rbegin(),
+ E = MBB->pred_rend(); PI != E; ++PI)
+ WorkList.push_back(*PI);
+}
+
+void LiveVariables::MarkVirtRegAliveInBlock(VarInfo &VRInfo,
+ MachineBasicBlock *MBB) {
+ std::vector<MachineBasicBlock*> WorkList;
+ MarkVirtRegAliveInBlock(VRInfo, MBB, WorkList);
+ while (!WorkList.empty()) {
+ MachineBasicBlock *Pred = WorkList.back();
+ WorkList.pop_back();
+ MarkVirtRegAliveInBlock(VRInfo, Pred, WorkList);
+ }
}
+
void LiveVariables::HandleVirtRegUse(VarInfo &VRInfo, MachineBasicBlock *MBB,
MachineInstr *MI) {
assert(VRInfo.DefInst && "Register use before def!");
bool Found = false;
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
MachineOperand &MO = MI->getOperand(i);
- if (MO.isReg() && MO.isUse()) {
+ if (MO.isRegister() && MO.isUse()) {
unsigned Reg = MO.getReg();
if (!Reg)
continue;
bool Found = false;
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
MachineOperand &MO = MI->getOperand(i);
- if (MO.isReg() && MO.isDef()) {
+ if (MO.isRegister() && MO.isDef()) {
unsigned Reg = MO.getReg();
if (!Reg)
continue;
}
void LiveVariables::HandlePhysRegUse(unsigned Reg, MachineInstr *MI) {
- // There is a now a proper use, forget about the last partial use.
- PhysRegPartUse[Reg] = NULL;
-
// Turn previous partial def's into read/mod/write.
for (unsigned i = 0, e = PhysRegPartDef[Reg].size(); i != e; ++i) {
MachineInstr *Def = PhysRegPartDef[Reg][i];
// A: EAX = ...
// B: = AX
// Add implicit def to A.
- if (PhysRegInfo[Reg] && !PhysRegUsed[Reg]) {
+ if (PhysRegInfo[Reg] && PhysRegInfo[Reg] != PhysRegPartUse[Reg] &&
+ !PhysRegUsed[Reg]) {
MachineInstr *Def = PhysRegInfo[Reg];
if (!Def->findRegisterDefOperand(Reg))
Def->addRegOperand(Reg, true/*IsDef*/,true/*IsImp*/);
}
+ // There is a now a proper use, forget about the last partial use.
+ PhysRegPartUse[Reg] = NULL;
PhysRegInfo[Reg] = MI;
PhysRegUsed[Reg] = true;
PhysRegUsed[SubReg] = true;
}
- // Remember the partial uses.
for (const unsigned *SuperRegs = RegInfo->getSuperRegisters(Reg);
- unsigned SuperReg = *SuperRegs; ++SuperRegs)
- PhysRegPartUse[SuperReg] = MI;
+ unsigned SuperReg = *SuperRegs; ++SuperRegs) {
+ // Remember the partial use of this superreg if it was previously defined.
+ bool HasPrevDef = PhysRegInfo[SuperReg] != NULL;
+ if (!HasPrevDef) {
+ for (const unsigned *SSRegs = RegInfo->getSuperRegisters(SuperReg);
+ unsigned SSReg = *SSRegs; ++SSRegs) {
+ if (PhysRegInfo[SSReg] != NULL) {
+ HasPrevDef = true;
+ break;
+ }
+ }
+ }
+ if (HasPrevDef) {
+ PhysRegInfo[SuperReg] = MI;
+ PhysRegPartUse[SuperReg] = MI;
+ }
+ }
+}
+
+bool LiveVariables::HandlePhysRegKill(unsigned Reg, MachineInstr *RefMI,
+ SmallSet<unsigned, 4> &SubKills) {
+ for (const unsigned *SubRegs = RegInfo->getImmediateSubRegisters(Reg);
+ unsigned SubReg = *SubRegs; ++SubRegs) {
+ MachineInstr *LastRef = PhysRegInfo[SubReg];
+ if (LastRef != RefMI ||
+ !HandlePhysRegKill(SubReg, RefMI, SubKills))
+ SubKills.insert(SubReg);
+ }
+
+ if (*RegInfo->getImmediateSubRegisters(Reg) == 0) {
+ // No sub-registers, just check if reg is killed by RefMI.
+ if (PhysRegInfo[Reg] == RefMI)
+ return true;
+ } else if (SubKills.empty())
+ // None of the sub-registers are killed elsewhere...
+ return true;
+ return false;
+}
+
+void LiveVariables::addRegisterKills(unsigned Reg, MachineInstr *MI,
+ SmallSet<unsigned, 4> &SubKills) {
+ if (SubKills.count(Reg) == 0)
+ addRegisterKilled(Reg, MI, true);
+ else {
+ for (const unsigned *SubRegs = RegInfo->getImmediateSubRegisters(Reg);
+ unsigned SubReg = *SubRegs; ++SubRegs)
+ addRegisterKills(SubReg, MI, SubKills);
+ }
+}
+
+bool LiveVariables::HandlePhysRegKill(unsigned Reg, MachineInstr *RefMI) {
+ SmallSet<unsigned, 4> SubKills;
+ if (HandlePhysRegKill(Reg, RefMI, SubKills)) {
+ addRegisterKilled(Reg, RefMI, true);
+ return true;
+ } else {
+ // Some sub-registers are killed by another MI.
+ for (const unsigned *SubRegs = RegInfo->getImmediateSubRegisters(Reg);
+ unsigned SubReg = *SubRegs; ++SubRegs)
+ addRegisterKills(SubReg, RefMI, SubKills);
+ return false;
+ }
}
void LiveVariables::HandlePhysRegDef(unsigned Reg, MachineInstr *MI) {
// Does this kill a previous version of this register?
if (MachineInstr *LastRef = PhysRegInfo[Reg]) {
- if (PhysRegUsed[Reg])
- addRegisterKilled(Reg, LastRef);
- else if (PhysRegPartUse[Reg])
- // Add implicit use / kill to last use of a sub-register.
+ if (PhysRegUsed[Reg]) {
+ if (!HandlePhysRegKill(Reg, LastRef)) {
+ if (PhysRegPartUse[Reg])
+ addRegisterKilled(Reg, PhysRegPartUse[Reg], true);
+ }
+ } else if (PhysRegPartUse[Reg])
+ // Add implicit use / kill to last partial use.
addRegisterKilled(Reg, PhysRegPartUse[Reg], true);
else
addRegisterDead(Reg, LastRef);
}
- PhysRegInfo[Reg] = MI;
- PhysRegUsed[Reg] = false;
- PhysRegPartUse[Reg] = NULL;
for (const unsigned *SubRegs = RegInfo->getSubRegisters(Reg);
unsigned SubReg = *SubRegs; ++SubRegs) {
if (MachineInstr *LastRef = PhysRegInfo[SubReg]) {
- if (PhysRegUsed[SubReg])
- addRegisterKilled(SubReg, LastRef);
- else if (PhysRegPartUse[SubReg])
+ if (PhysRegUsed[SubReg]) {
+ if (!HandlePhysRegKill(SubReg, LastRef)) {
+ if (PhysRegPartUse[SubReg])
+ addRegisterKilled(SubReg, PhysRegPartUse[SubReg], true);
+ }
+ } else if (PhysRegPartUse[SubReg])
// Add implicit use / kill to last use of a sub-register.
addRegisterKilled(SubReg, PhysRegPartUse[SubReg], true);
- else
+ else if (LastRef != MI)
+ // This must be a def of the subreg on the same MI.
addRegisterDead(SubReg, LastRef);
}
- PhysRegInfo[SubReg] = MI;
- PhysRegUsed[SubReg] = false;
}
- if (MI)
+ if (MI) {
for (const unsigned *SuperRegs = RegInfo->getSuperRegisters(Reg);
unsigned SuperReg = *SuperRegs; ++SuperRegs) {
- if (PhysRegInfo[SuperReg]) {
+ if (PhysRegInfo[SuperReg] && PhysRegInfo[SuperReg] != MI) {
// The larger register is previously defined. Now a smaller part is
// being re-defined. Treat it as read/mod/write.
// EAX =
MI->addRegOperand(SuperReg, true/*IsDef*/,true/*IsImp*/);
PhysRegInfo[SuperReg] = MI;
PhysRegUsed[SuperReg] = false;
+ PhysRegPartUse[SuperReg] = NULL;
} else {
// Remember this partial def.
PhysRegPartDef[SuperReg].push_back(MI);
}
+ }
+
+ PhysRegInfo[Reg] = MI;
+ PhysRegUsed[Reg] = false;
+ PhysRegPartDef[Reg].clear();
+ PhysRegPartUse[Reg] = NULL;
+ for (const unsigned *SubRegs = RegInfo->getSubRegisters(Reg);
+ unsigned SubReg = *SubRegs; ++SubRegs) {
+ PhysRegInfo[SubReg] = MI;
+ PhysRegUsed[SubReg] = false;
+ PhysRegPartDef[SubReg].clear();
+ PhysRegPartUse[SubReg] = NULL;
+ }
}
}
// nodes, which are treated as a special case).
//
MachineBasicBlock *Entry = MF->begin();
- std::set<MachineBasicBlock*> Visited;
- for (df_ext_iterator<MachineBasicBlock*> DFI = df_ext_begin(Entry, Visited),
- E = df_ext_end(Entry, Visited); DFI != E; ++DFI) {
+ SmallPtrSet<MachineBasicBlock*,16> Visited;
+ for (df_ext_iterator<MachineBasicBlock*, SmallPtrSet<MachineBasicBlock*,16> >
+ DFI = df_ext_begin(Entry, Visited), E = df_ext_end(Entry, Visited);
+ DFI != E; ++DFI) {
MachineBasicBlock *MBB = *DFI;
// Mark live-in registers as live-in.
// Clear some states between BB's. These are purely local information.
for (unsigned i = 0; i != NumRegs; ++i)
PhysRegPartDef[i].clear();
+ std::fill(PhysRegInfo, PhysRegInfo + NumRegs, (MachineInstr*)0);
+ std::fill(PhysRegUsed, PhysRegUsed + NumRegs, false);
std::fill(PhysRegPartUse, PhysRegPartUse + NumRegs, (MachineInstr*)0);
}
if (VI.DefInst == OldMI)
VI.DefInst = NewMI;
}
- if (MO.isUse()) {
- if (MO.isKill()) {
- MO.unsetIsKill();
- addVirtualRegisterKilled(Reg, NewMI);
- }
- // If this is a kill of the value, update the VI kills list.
- if (VI.removeKill(OldMI))
- VI.Kills.push_back(NewMI); // Yes, there was a kill of it
+ if (MO.isKill()) {
+ MO.unsetIsKill();
+ addVirtualRegisterKilled(Reg, NewMI);
}
+ // If this is a kill of the value, update the VI kills list.
+ if (VI.removeKill(OldMI))
+ VI.Kills.push_back(NewMI); // Yes, there was a kill of it
}
}
}
void LiveVariables::removeVirtualRegistersKilled(MachineInstr *MI) {
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
MachineOperand &MO = MI->getOperand(i);
- if (MO.isReg() && MO.isKill()) {
+ if (MO.isRegister() && MO.isKill()) {
MO.unsetIsKill();
unsigned Reg = MO.getReg();
if (MRegisterInfo::isVirtualRegister(Reg)) {
void LiveVariables::removeVirtualRegistersDead(MachineInstr *MI) {
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
MachineOperand &MO = MI->getOperand(i);
- if (MO.isReg() && MO.isDead()) {
+ if (MO.isRegister() && MO.isDead()) {
MO.unsetIsDead();
unsigned Reg = MO.getReg();
if (MRegisterInfo::isVirtualRegister(Reg)) {