mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 11:42:57 +01:00
Correctly compute live variable information for physical registers
when an implicitely defined register is later used by an alias. For example: call foo %reg1024 = mov %AL The call implicitely defines EAX but only AL is used. Before this fix no information was available on AL. Now EAX and all its aliases except AL get defined and die at the call instruction whereas AL lives to be killed by the assignment. llvm-svn: 10813
This commit is contained in:
parent
807e401607
commit
1a7b3c80d7
@ -261,6 +261,8 @@ void LiveIntervals::handleRegisterDef(MachineBasicBlock* mbb,
|
||||
if (reg < MRegisterInfo::FirstVirtualRegister) {
|
||||
if (allocatableRegisters_[reg]) {
|
||||
handlePhysicalRegisterDef(mbb, mi, reg);
|
||||
for (const unsigned* as = mri_->getAliasSet(reg); *as; ++as)
|
||||
handlePhysicalRegisterDef(mbb, mi, *as);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -300,10 +302,8 @@ void LiveIntervals::computeIntervals()
|
||||
instr->print(std::cerr, *tm_););
|
||||
|
||||
// handle implicit defs
|
||||
for (const unsigned* id = tid.ImplicitDefs; *id; ++id) {
|
||||
unsigned physReg = *id;
|
||||
handlePhysicalRegisterDef(mbb, mi, physReg);
|
||||
}
|
||||
for (const unsigned* id = tid.ImplicitDefs; *id; ++id)
|
||||
handleRegisterDef(mbb, mi, *id);
|
||||
|
||||
// handle explicit defs
|
||||
for (int i = instr->getNumOperands() - 1; i >= 0; --i) {
|
||||
@ -312,14 +312,9 @@ void LiveIntervals::computeIntervals()
|
||||
if (!mop.isRegister())
|
||||
continue;
|
||||
|
||||
unsigned reg = mop.getAllocatedRegNum();
|
||||
// handle defs - build intervals
|
||||
if (mop.isDef()) {
|
||||
if (reg < MRegisterInfo::FirstVirtualRegister)
|
||||
handlePhysicalRegisterDef(mbb, mi, reg);
|
||||
else
|
||||
handleVirtualRegisterDef(mbb, mi, reg);
|
||||
}
|
||||
if (mop.isDef())
|
||||
handleRegisterDef(mbb, mi, mop.getAllocatedRegNum());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -117,14 +117,6 @@ void LiveVariables::HandlePhysRegUse(unsigned Reg, MachineInstr *MI) {
|
||||
if (PhysRegInfo[Reg]) {
|
||||
PhysRegInfo[Reg] = MI;
|
||||
PhysRegUsed[Reg] = true;
|
||||
} else {
|
||||
for (const unsigned *AliasSet = RegInfo->getAliasSet(Reg);
|
||||
*AliasSet; ++AliasSet) {
|
||||
if (MachineInstr *LastUse = PhysRegInfo[*AliasSet]) {
|
||||
PhysRegInfo[*AliasSet] = MI;
|
||||
PhysRegUsed[*AliasSet] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -135,20 +127,21 @@ void LiveVariables::HandlePhysRegDef(unsigned Reg, MachineInstr *MI) {
|
||||
RegistersKilled.insert(std::make_pair(LastUse, Reg));
|
||||
else
|
||||
RegistersDead.insert(std::make_pair(LastUse, Reg));
|
||||
} else {
|
||||
for (const unsigned *AliasSet = RegInfo->getAliasSet(Reg);
|
||||
*AliasSet; ++AliasSet) {
|
||||
if (MachineInstr *LastUse = PhysRegInfo[*AliasSet]) {
|
||||
if (PhysRegUsed[*AliasSet])
|
||||
RegistersKilled.insert(std::make_pair(LastUse, *AliasSet));
|
||||
else
|
||||
RegistersDead.insert(std::make_pair(LastUse, *AliasSet));
|
||||
PhysRegInfo[*AliasSet] = 0; // Kill the aliased register
|
||||
}
|
||||
}
|
||||
}
|
||||
PhysRegInfo[Reg] = MI;
|
||||
PhysRegUsed[Reg] = false;
|
||||
|
||||
for (const unsigned *AliasSet = RegInfo->getAliasSet(Reg);
|
||||
*AliasSet; ++AliasSet) {
|
||||
if (MachineInstr *LastUse = PhysRegInfo[*AliasSet]) {
|
||||
if (PhysRegUsed[*AliasSet])
|
||||
RegistersKilled.insert(std::make_pair(LastUse, *AliasSet));
|
||||
else
|
||||
RegistersDead.insert(std::make_pair(LastUse, *AliasSet));
|
||||
}
|
||||
PhysRegInfo[*AliasSet] = MI;
|
||||
PhysRegUsed[*AliasSet] = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool LiveVariables::runOnMachineFunction(MachineFunction &MF) {
|
||||
|
@ -232,9 +232,8 @@ void RA::removePhysReg(unsigned PhysReg) {
|
||||
|
||||
std::vector<unsigned>::iterator It =
|
||||
std::find(PhysRegsUseOrder.begin(), PhysRegsUseOrder.end(), PhysReg);
|
||||
assert(It != PhysRegsUseOrder.end() &&
|
||||
"Spilled a physical register, but it was not in use list!");
|
||||
PhysRegsUseOrder.erase(It);
|
||||
if (It != PhysRegsUseOrder.end())
|
||||
PhysRegsUseOrder.erase(It);
|
||||
}
|
||||
|
||||
|
||||
@ -550,6 +549,11 @@ void RA::AllocateBasicBlock(MachineBasicBlock &MBB) {
|
||||
spillPhysReg(MBB, I, Reg, true); // Spill any existing value in the reg
|
||||
PhysRegsUsed[Reg] = 0; // It is free and reserved now
|
||||
PhysRegsUseOrder.push_back(Reg);
|
||||
for (const unsigned *AliasSet = RegInfo->getAliasSet(Reg);
|
||||
*AliasSet; ++AliasSet) {
|
||||
PhysRegsUseOrder.push_back(*AliasSet);
|
||||
PhysRegsUsed[*AliasSet] = 0; // It is free and reserved now
|
||||
}
|
||||
}
|
||||
|
||||
// Loop over the implicit defs, spilling them as well.
|
||||
@ -559,6 +563,11 @@ void RA::AllocateBasicBlock(MachineBasicBlock &MBB) {
|
||||
spillPhysReg(MBB, I, Reg);
|
||||
PhysRegsUseOrder.push_back(Reg);
|
||||
PhysRegsUsed[Reg] = 0; // It is free and reserved now
|
||||
for (const unsigned *AliasSet = RegInfo->getAliasSet(Reg);
|
||||
*AliasSet; ++AliasSet) {
|
||||
PhysRegsUseOrder.push_back(*AliasSet);
|
||||
PhysRegsUsed[*AliasSet] = 0; // It is free and reserved now
|
||||
}
|
||||
}
|
||||
|
||||
// Okay, we have allocated all of the source operands and spilled any values
|
||||
|
Loading…
Reference in New Issue
Block a user