[LLVMdev] Register scavenger and SP/FP adjustments
Krzysztof Parzyszek
kparzysz at codeaurora.org
Wed Sep 25 08:57:31 PDT 2013
Hi All,
I'm dealing with a problem where the spill/restore instructions inserted
during scavenging span an adjustment of the SP/FP register. The result
is that despite the base register (SP/FP) being changed between the
spill and the restore, both store and load use the same immediate offset.
I see code in the PEI (replaceFrameIndices) that is supposed to track
the SP/FP adjustment:
----------------------------------------
void PEI::replaceFrameIndices(MachineBasicBlock *BB,
MachineFunction &Fn, int &SPAdj) {
const TargetMachine &TM = Fn.getTarget();
assert(TM.getRegisterInfo() &&
"TM::getRegisterInfo() must be implemented!");
const TargetInstrInfo &TII = *Fn.getTarget().getInstrInfo();
const TargetRegisterInfo &TRI = *TM.getRegisterInfo();
const TargetFrameLowering *TFI = TM.getFrameLowering();
bool StackGrowsDown =
TFI->getStackGrowthDirection() ==
TargetFrameLowering::StackGrowsDown;
int FrameSetupOpcode = TII.getCallFrameSetupOpcode();
int FrameDestroyOpcode = TII.getCallFrameDestroyOpcode();
if (RS && !FrameIndexVirtualScavenging) RS->enterBasicBlock(BB);
for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ) {
if (I->getOpcode() == FrameSetupOpcode ||
I->getOpcode() == FrameDestroyOpcode) {
// Remember how much SP has been adjusted to create the call
// frame.
int Size = I->getOperand(0).getImm();
if ((!StackGrowsDown && I->getOpcode() == FrameSetupOpcode) ||
(StackGrowsDown && I->getOpcode() == FrameDestroyOpcode))
Size = -Size;
SPAdj += Size;
[...]
----------------------------------------
The problem is that it expects frame-setup and frame-destroy opcodes,
but at the time it runs (after emitPrologue/emitEpilogue) the frame
setup and teardown will be expanded into instruction sequences that can
be different for each target, let alone having the immediate value in
the 0-th operand.
As I see, this code won't work, although I'm not sure what was the
original idea behind it. Should this code run before the target
specific generation of prolog/epilog? Even then, there won't need to be
ADJCALLSTACKUP/DOWN instructions (if it's a leaf function). If it runs
where it should, should it instead use some target-specific hook that
identifies the actual stack adjustment amount?
-Krzysztof
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation
More information about the llvm-dev
mailing list