Clarification about callee saved regs and MachineRegisterInfo::isPhyRegUsed

Hi,

I am confused about the call to isPhyRegUsed in calculateCalleeSavedRegisters:

if (Fn.getRegInfo().isPhysRegUsed(Reg)) {
// If the reg is modified, save it!
CSI.push_back(CalleeSavedInfo(Reg));
}

It seems that isPhyRegUsed returns true if the register is read or written in the function.

If this is right, why do we save a register if it is only read in the function ?? I would have expected that calculateCalleeSavedRegisters use another function which would return true only when the register is written, something like “isPhyRegWritten”.

You may ask why a function would only read a callee saved register ?? The case I have in mind is the link register, like LR in ARM: a typical return instruction is BX LR. BX instruction only reads LR, no need to push/pop LR just because a function ends by BX LR…

The ARM backend don’t have this problem because it use a BX_RET instruction, which is just a BX which implicitly use LR as operand. Seems like a workaround solution…

Context of this question: I am trying to learn how backends work, for doing so I started to write a backend for ARM Cortex M0, starting from the mblaze as base. I am aware that the ARM backend already support Cortex M0, this is just a learning exercise, I may turn it into a tutorial if I am confident enough with the result. I am trying to do it in the most straightforward way and avoid quick and dirty workarounds…

best regards,

Sebastien

I am confused about the call to isPhyRegUsed in calculateCalleeSavedRegisters:

if (Fn.getRegInfo().isPhysRegUsed(Reg)) {
// If the reg is modified, save it!
CSI.push_back(CalleeSavedInfo(Reg));
}

It seems that isPhyRegUsed returns true if the register is read or written in the function.

If this is right, why do we save a register if it is only read in the function ?? I would have expected that calculateCalleeSavedRegisters use another function which would return true only when the register is written, something like “isPhyRegWritten”.

Hi Sebastien,

I don’t think there is a good reason it works that way. The distinction hasn’t been important yet, I’d guess.

The ARM backend don’t have this problem because it use a BX_RET instruction, which is just a BX which implicitly use LR as operand. Seems like a workaround solution…

Some CodeGen passes treat return instructions specially. That is why there is a BX_RET instruction. Look for isReturn().

/jakob