I don't understand the following code snippet in LiveIntervalAnalysis.cpp.
Why changing the type of the opreand from a virtual register to a
machine register? The register number (reg) is still a virtual
register index (>1024).
bool LiveIntervals::runOnMachineFunction(MachineFunction &fn) {
// perform a final pass over the instructions and compute spill
// weights, coalesce virtual registers and remove identity moves
...
for (unsigned i = 0; i < mii->getNumOperands(); ++i) {
const MachineOperand& mop = mii->getOperand(i);
if (mop.isRegister() && mop.getReg() &&
MRegisterInfo::isVirtualRegister(mop.getReg())) {
// replace register with representative register
unsigned reg = rep(mop.getReg());
mii->SetMachineOperandReg(i, reg);
LiveInterval &RegInt = getInterval(reg);
RegInt.weight +=
(mop.isUse() + mop.isDef()) * pow(10.0F, (int)loopDepth);
After joining intervals some moves are unecessary. If for example this
instruction was in the code:
mov %reg1024, %reg1045
and intervals for reg1024 and reg1045 were joined, only one register
needs to be present in the pre register-allocation machine code. So all
references to reg1024 and reg1045 are replaced with a reference to their
representative register (found using a union find algorithm). Note that
the representative register could be a real register if we ever joined
an interval of a real register with one of a virtual register (and this
real register will be the representative register of the set of
intervals joined together).
I don't understand the following code snippet in LiveIntervalAnalysis.cpp.
Why changing the type of the opreand from a virtual register to a
machine register? The register number (reg) is still a virtual
register index (>1024).
This code isn't actually replacing the virtual register with a physreg. As you noticed, it replaces it with a different virtual register. As part of coallescing, the code uses union-find to find a single representative register for all merged live ranges. This code just makes sure that all of the merged live ranges are rewritten to use a single virtual register (the representative).
After this is done, the "spiller" (in CodeGen/VirtRegMap.*) rewrites to virtual registers to use physregs and/or spilled values.
-Chris
bool LiveIntervals::runOnMachineFunction(MachineFunction &fn) {
// perform a final pass over the instructions and compute spill
// weights, coalesce virtual registers and remove identity moves
...
for (unsigned i = 0; i < mii->getNumOperands(); ++i) {
const MachineOperand& mop = mii->getOperand(i);
if (mop.isRegister() && mop.getReg() &&
MRegisterInfo::isVirtualRegister(mop.getReg())) {
// replace register with representative register
unsigned reg = rep(mop.getReg());
mii->SetMachineOperandReg(i, reg);
LiveInterval &RegInt = getInterval(reg);
RegInt.weight +=
(mop.isUse() + mop.isDef()) * pow(10.0F, (int)loopDepth);
-Chris
Then why changing its optype?
It makes the assertion fails:
MachineOperand& MO = inst.getOperand(n);
if (MRegisterInfo::isVirtualRegister(MO.getReg())) {
assert(MachineOperand::MO_VirtualRegister == MO.getType());
...
}
Is that alright?
Some of my code using MachineOperand::getType() instead of
MRegisterInfo::is{Physical,Virtual}Register() to check the register
type.
I understand the representative register could be a physical (real)
register if one of the coallescing register is a physical register.
But the code _uncondtionally_ changes MachineOperand::optype to
MO_MachineRegister, why?
(Same question as my previous post)
This code isn't actually replacing the virtual register with a physreg.
Then why changing its optype?
It makes the assertion fails:
MachineOperand& MO = inst.getOperand(n);
if (MRegisterInfo::isVirtualRegister(MO.getReg())) {
assert(MachineOperand::MO_VirtualRegister == MO.getType());
...
}
Is that alright?
No, that's not right. There is no distinction between MO_VirtualRegister and MO_PhysicalRegister in the target independent backend. This is due to difference between how the SparcV9 backend (which uses this distinction) and the target-indep backend work. If you use: MO.isRegister(), it accepts both MO_MachineRegister and MO_VirtualRegister. In the target-indep backend, there is no distinction: the distinction is based on the value of the register itself.
Some of my code using MachineOperand::getType() instead of
MRegisterInfo::is{Physical,Virtual}Register() to check the register
type.
If you use MO.isRegister() things should work.
-Chris
See above. There is no distinction, and some of these changes are required by the SparcV9 backend. This kind of stuff will be cleaned up over time.
-Chris