//
// The LLVM Compiler Infrastructure
//
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
cerr << " Alive in blocks: ";
for (unsigned i = 0, e = AliveBlocks.size(); i != e; ++i)
if (AliveBlocks[i]) cerr << i << ", ";
+ cerr << " Used in blocks: ";
+ for (unsigned i = 0, e = UsedBlocks.size(); i != e; ++i)
+ if (UsedBlocks[i]) cerr << i << ", ";
cerr << "\n Killed by:";
if (Kills.empty())
cerr << " No instructions.\n";
}
VarInfo &VI = VirtRegInfo[RegIdx];
VI.AliveBlocks.resize(MF->getNumBlockIDs());
+ VI.UsedBlocks.resize(MF->getNumBlockIDs());
return VI;
}
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;
MachineInstr *MI) {
assert(VRInfo.DefInst && "Register use before def!");
+ unsigned BBNum = MBB->getNumber();
+
+ VRInfo.UsedBlocks[BBNum] = true;
VRInfo.NumUses++;
// Check to see if this basic block is already a kill 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 block, it's not
// a kill.
- if (!VRInfo.AliveBlocks[MBB->getNumber()])
+ if (!VRInfo.AliveBlocks[BBNum])
VRInfo.Kills.push_back(MI);
// Update all dominating blocks to mark them known live.
}
bool LiveVariables::addRegisterKilled(unsigned IncomingReg, MachineInstr *MI,
+ const MRegisterInfo *RegInfo,
bool AddIfNotFound) {
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;
RegInfo->isSuperRegister(IncomingReg, Reg) &&
MO.isKill())
// A super-register kill already exists.
- return true;
+ Found = true;
}
}
}
bool LiveVariables::addRegisterDead(unsigned IncomingReg, MachineInstr *MI,
+ const MRegisterInfo *RegInfo,
bool AddIfNotFound) {
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;
for (const unsigned *SubRegs = RegInfo->getImmediateSubRegisters(Reg);
unsigned SubReg = *SubRegs; ++SubRegs) {
MachineInstr *LastRef = PhysRegInfo[SubReg];
- if (LastRef != RefMI)
- SubKills.insert(SubReg);
- else if (!HandlePhysRegKill(SubReg, RefMI, SubKills))
+ if (LastRef != RefMI ||
+ !HandlePhysRegKill(SubReg, RefMI, SubKills))
SubKills.insert(SubReg);
}
void LiveVariables::addRegisterKills(unsigned Reg, MachineInstr *MI,
SmallSet<unsigned, 4> &SubKills) {
if (SubKills.count(Reg) == 0)
- addRegisterKilled(Reg, MI, true);
+ addRegisterKilled(Reg, MI, RegInfo, true);
else {
for (const unsigned *SubRegs = RegInfo->getImmediateSubRegisters(Reg);
unsigned SubReg = *SubRegs; ++SubRegs)
bool LiveVariables::HandlePhysRegKill(unsigned Reg, MachineInstr *RefMI) {
SmallSet<unsigned, 4> SubKills;
if (HandlePhysRegKill(Reg, RefMI, SubKills)) {
- addRegisterKilled(Reg, RefMI);
+ addRegisterKilled(Reg, RefMI, RegInfo, true);
return true;
} else {
// Some sub-registers are killed by another MI.
if (PhysRegUsed[Reg]) {
if (!HandlePhysRegKill(Reg, LastRef)) {
if (PhysRegPartUse[Reg])
- addRegisterKilled(Reg, PhysRegPartUse[Reg], true);
+ addRegisterKilled(Reg, PhysRegPartUse[Reg], RegInfo, true);
}
} else if (PhysRegPartUse[Reg])
// Add implicit use / kill to last partial use.
- addRegisterKilled(Reg, PhysRegPartUse[Reg], true);
- else
- addRegisterDead(Reg, LastRef);
+ addRegisterKilled(Reg, PhysRegPartUse[Reg], RegInfo, true);
+ else if (LastRef != MI)
+ // Defined, but not used. However, watch out for cases where a super-reg
+ // is also defined on the same MI.
+ addRegisterDead(Reg, LastRef, RegInfo);
}
for (const unsigned *SubRegs = RegInfo->getSubRegisters(Reg);
if (PhysRegUsed[SubReg]) {
if (!HandlePhysRegKill(SubReg, LastRef)) {
if (PhysRegPartUse[SubReg])
- addRegisterKilled(SubReg, PhysRegPartUse[SubReg], true);
+ addRegisterKilled(SubReg, PhysRegPartUse[SubReg], RegInfo, true);
}
} else if (PhysRegPartUse[SubReg])
// Add implicit use / kill to last use of a sub-register.
- addRegisterKilled(SubReg, PhysRegPartUse[SubReg], true);
- else
- addRegisterDead(SubReg, LastRef);
+ addRegisterKilled(SubReg, PhysRegPartUse[SubReg], RegInfo, true);
+ else if (LastRef != MI)
+ // This must be a def of the subreg on the same MI.
+ addRegisterDead(SubReg, LastRef, RegInfo);
}
}
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 =
for (unsigned j = 0, e2 = VirtRegInfo[i].Kills.size(); j != e2; ++j) {
if (VirtRegInfo[i].Kills[j] == VirtRegInfo[i].DefInst)
addRegisterDead(i + MRegisterInfo::FirstVirtualRegister,
- VirtRegInfo[i].Kills[j]);
+ VirtRegInfo[i].Kills[j], RegInfo);
else
addRegisterKilled(i + MRegisterInfo::FirstVirtualRegister,
- VirtRegInfo[i].Kills[j]);
+ VirtRegInfo[i].Kills[j], RegInfo);
}
// Check to make sure there are no unreachable blocks in the MC CFG for the
}
}
+/// transferKillDeadInfo - Similar to instructionChanged except it does not
+/// update live variables internal data structures.
+void LiveVariables::transferKillDeadInfo(MachineInstr *OldMI,
+ MachineInstr *NewMI,
+ const MRegisterInfo *RegInfo) {
+ // If the instruction defines any virtual registers, update the VarInfo,
+ // kill and dead information for the instruction.
+ for (unsigned i = 0, e = OldMI->getNumOperands(); i != e; ++i) {
+ MachineOperand &MO = OldMI->getOperand(i);
+ if (MO.isRegister() && MO.getReg() &&
+ MRegisterInfo::isVirtualRegister(MO.getReg())) {
+ unsigned Reg = MO.getReg();
+ if (MO.isDef()) {
+ if (MO.isDead()) {
+ MO.unsetIsDead();
+ addRegisterDead(Reg, NewMI, RegInfo);
+ }
+ }
+ if (MO.isKill()) {
+ MO.unsetIsKill();
+ addRegisterKilled(Reg, NewMI, RegInfo);
+ }
+ }
+ }
+}
+
+
/// removeVirtualRegistersKilled - Remove all killed info for the specified
/// instruction.
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)) {