mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-19 04:32:19 +00:00
Properly handle kills of a physical register which has sub-registers that are read by later instructions.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@37739 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
c4f2fe0694
commit
4efe74129f
@ -31,6 +31,7 @@
|
|||||||
|
|
||||||
#include "llvm/CodeGen/MachineFunctionPass.h"
|
#include "llvm/CodeGen/MachineFunctionPass.h"
|
||||||
#include "llvm/ADT/BitVector.h"
|
#include "llvm/ADT/BitVector.h"
|
||||||
|
#include "llvm/ADT/SmallSet.h"
|
||||||
#include "llvm/ADT/SmallVector.h"
|
#include "llvm/ADT/SmallVector.h"
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
@ -163,6 +164,15 @@ private: // Intermediate data structures
|
|||||||
bool addRegisterDead(unsigned IncomingReg, MachineInstr *MI,
|
bool addRegisterDead(unsigned IncomingReg, MachineInstr *MI,
|
||||||
bool AddIfNotFound = false);
|
bool AddIfNotFound = false);
|
||||||
|
|
||||||
|
void addRegisterKills(unsigned Reg, MachineInstr *MI,
|
||||||
|
SmallSet<unsigned, 4> &SubKills);
|
||||||
|
|
||||||
|
/// HandlePhysRegKill - Add kills of Reg and its sub-registers to the
|
||||||
|
/// uses. Pay special attention to the sub-register uses which may come below
|
||||||
|
/// the last use of the whole register.
|
||||||
|
bool HandlePhysRegKill(unsigned Reg, MachineInstr *MI,
|
||||||
|
SmallSet<unsigned, 4> &SubKills);
|
||||||
|
bool HandlePhysRegKill(unsigned Reg, MachineInstr *MI);
|
||||||
void HandlePhysRegUse(unsigned Reg, MachineInstr *MI);
|
void HandlePhysRegUse(unsigned Reg, MachineInstr *MI);
|
||||||
void HandlePhysRegDef(unsigned Reg, MachineInstr *MI);
|
void HandlePhysRegDef(unsigned Reg, MachineInstr *MI);
|
||||||
|
|
||||||
|
@ -286,38 +286,85 @@ void LiveVariables::HandlePhysRegUse(unsigned Reg, MachineInstr *MI) {
|
|||||||
PhysRegPartUse[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)
|
||||||
|
SubKills.insert(SubReg);
|
||||||
|
else if (!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);
|
||||||
|
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) {
|
void LiveVariables::HandlePhysRegDef(unsigned Reg, MachineInstr *MI) {
|
||||||
// Does this kill a previous version of this register?
|
// Does this kill a previous version of this register?
|
||||||
if (MachineInstr *LastRef = PhysRegInfo[Reg]) {
|
if (MachineInstr *LastRef = PhysRegInfo[Reg]) {
|
||||||
if (PhysRegUsed[Reg])
|
if (PhysRegUsed[Reg]) {
|
||||||
addRegisterKilled(Reg, LastRef);
|
if (!HandlePhysRegKill(Reg, LastRef)) {
|
||||||
else if (PhysRegPartUse[Reg])
|
if (PhysRegPartUse[Reg])
|
||||||
|
addRegisterKilled(Reg, PhysRegPartUse[Reg], true);
|
||||||
|
}
|
||||||
|
} else if (PhysRegPartUse[Reg])
|
||||||
// Add implicit use / kill to last use of a sub-register.
|
// Add implicit use / kill to last use of a sub-register.
|
||||||
addRegisterKilled(Reg, PhysRegPartUse[Reg], true);
|
addRegisterKilled(Reg, PhysRegPartUse[Reg], true);
|
||||||
else
|
else
|
||||||
addRegisterDead(Reg, LastRef);
|
addRegisterDead(Reg, LastRef);
|
||||||
}
|
}
|
||||||
PhysRegInfo[Reg] = MI;
|
|
||||||
PhysRegUsed[Reg] = false;
|
|
||||||
PhysRegPartUse[Reg] = NULL;
|
|
||||||
|
|
||||||
for (const unsigned *SubRegs = RegInfo->getSubRegisters(Reg);
|
for (const unsigned *SubRegs = RegInfo->getSubRegisters(Reg);
|
||||||
unsigned SubReg = *SubRegs; ++SubRegs) {
|
unsigned SubReg = *SubRegs; ++SubRegs) {
|
||||||
if (MachineInstr *LastRef = PhysRegInfo[SubReg]) {
|
if (MachineInstr *LastRef = PhysRegInfo[SubReg]) {
|
||||||
if (PhysRegUsed[SubReg])
|
if (PhysRegUsed[SubReg]) {
|
||||||
addRegisterKilled(SubReg, LastRef);
|
if (!HandlePhysRegKill(SubReg, LastRef)) {
|
||||||
else if (PhysRegPartUse[SubReg])
|
if (PhysRegPartUse[SubReg])
|
||||||
|
addRegisterKilled(SubReg, PhysRegPartUse[SubReg], true);
|
||||||
|
}
|
||||||
|
//addRegisterKilled(SubReg, LastRef);
|
||||||
|
} else if (PhysRegPartUse[SubReg])
|
||||||
// Add implicit use / kill to last use of a sub-register.
|
// Add implicit use / kill to last use of a sub-register.
|
||||||
addRegisterKilled(SubReg, PhysRegPartUse[SubReg], true);
|
addRegisterKilled(SubReg, PhysRegPartUse[SubReg], true);
|
||||||
else
|
else
|
||||||
addRegisterDead(SubReg, LastRef);
|
addRegisterDead(SubReg, LastRef);
|
||||||
}
|
}
|
||||||
PhysRegInfo[SubReg] = MI;
|
|
||||||
PhysRegUsed[SubReg] = false;
|
|
||||||
PhysRegPartUse[SubReg] = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MI)
|
if (MI) {
|
||||||
for (const unsigned *SuperRegs = RegInfo->getSuperRegisters(Reg);
|
for (const unsigned *SuperRegs = RegInfo->getSuperRegisters(Reg);
|
||||||
unsigned SuperReg = *SuperRegs; ++SuperRegs) {
|
unsigned SuperReg = *SuperRegs; ++SuperRegs) {
|
||||||
if (PhysRegInfo[SuperReg]) {
|
if (PhysRegInfo[SuperReg]) {
|
||||||
@ -334,6 +381,17 @@ void LiveVariables::HandlePhysRegDef(unsigned Reg, MachineInstr *MI) {
|
|||||||
// Remember this partial def.
|
// Remember this partial def.
|
||||||
PhysRegPartDef[SuperReg].push_back(MI);
|
PhysRegPartDef[SuperReg].push_back(MI);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PhysRegInfo[Reg] = MI;
|
||||||
|
PhysRegUsed[Reg] = false;
|
||||||
|
PhysRegPartUse[Reg] = NULL;
|
||||||
|
for (const unsigned *SubRegs = RegInfo->getSubRegisters(Reg);
|
||||||
|
unsigned SubReg = *SubRegs; ++SubRegs) {
|
||||||
|
PhysRegInfo[SubReg] = MI;
|
||||||
|
PhysRegUsed[SubReg] = false;
|
||||||
|
PhysRegPartUse[SubReg] = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -465,6 +523,8 @@ bool LiveVariables::runOnMachineFunction(MachineFunction &mf) {
|
|||||||
// Clear some states between BB's. These are purely local information.
|
// Clear some states between BB's. These are purely local information.
|
||||||
for (unsigned i = 0; i != NumRegs; ++i)
|
for (unsigned i = 0; i != NumRegs; ++i)
|
||||||
PhysRegPartDef[i].clear();
|
PhysRegPartDef[i].clear();
|
||||||
|
std::fill(PhysRegInfo, PhysRegInfo + NumRegs, (MachineInstr*)0);
|
||||||
|
std::fill(PhysRegUsed, PhysRegUsed + NumRegs, false);
|
||||||
std::fill(PhysRegPartUse, PhysRegPartUse + NumRegs, (MachineInstr*)0);
|
std::fill(PhysRegPartUse, PhysRegPartUse + NumRegs, (MachineInstr*)0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user