diff --git a/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp b/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp --- a/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp +++ b/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp @@ -373,22 +373,32 @@ const MachineFrameInfo &MFI = MF.getFrameInfo(); const std::vector &Info = MFI.getCalleeSavedInfo(); + LLVM_DEBUG(dbgs() << "requiresFrameIndexScavenging for " << MF.getName() + << ".\n"); // If the callee saved info is invalid we have to default to true for safety. - if (!MFI.isCalleeSavedInfoValid()) + if (!MFI.isCalleeSavedInfoValid()) { + LLVM_DEBUG(dbgs() << "TRUE - Invalid callee saved info.\n"); return true; + } // We will require the use of X-Forms because the frame is larger than what // can be represented in signed 16 bits that fit in the immediate of a D-Form. // If we need an X-Form then we need a register to store the address offset. unsigned FrameSize = MFI.getStackSize(); // Signed 16 bits means that the FrameSize cannot be more than 15 bits. - if (FrameSize & ~0x7FFF) + if (FrameSize & ~0x7FFF) { + LLVM_DEBUG(dbgs() << "TRUE - Frame size is too large for D-Form.\n"); return true; + } // The callee saved info is valid so it can be traversed. // Checking for registers that need saving that do not have load or store // forms where the address offset is an immediate. for (unsigned i = 0; i < Info.size(); i++) { + // If the spill is to a register no scavenging is required. + if (Info[i].isSpilledToReg()) + continue; + int FrIdx = Info[i].getFrameIdx(); unsigned Reg = Info[i].getReg(); @@ -397,8 +407,13 @@ if (!MFI.isFixedObjectIndex(FrIdx)) { // This is not a fixed object. If it requires alignment then we may still // need to use the XForm. - if (offsetMinAlignForOpcode(Opcode) > 1) + if (offsetMinAlignForOpcode(Opcode) > 1) { + LLVM_DEBUG(dbgs() << "Memory Operand: " << InstrInfo->getName(Opcode) + << " for register " << printReg(Reg, this) << ".\n"); + LLVM_DEBUG(dbgs() << "TRUE - Not fixed frame object that requires " + << "alignment.\n"); return true; + } } // This is eiher: @@ -407,9 +422,14 @@ // need to consider the alignment here. // 2) A not fixed object but in that case we now know that the min required // alignment is no more than 1 based on the previous check. - if (InstrInfo->isXFormMemOp(Opcode)) + if (InstrInfo->isXFormMemOp(Opcode)) { + LLVM_DEBUG(dbgs() << "Memory Operand: " << InstrInfo->getName(Opcode) + << " for register " << printReg(Reg, this) << ".\n"); + LLVM_DEBUG(dbgs() << "TRUE - Memory operand is X-Form.\n"); return true; + } } + LLVM_DEBUG(dbgs() << "FALSE - Scavenging is not required.\n"); return false; } diff --git a/llvm/test/CodeGen/PowerPC/frame_index_scavenging.mir b/llvm/test/CodeGen/PowerPC/frame_index_scavenging.mir new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/PowerPC/frame_index_scavenging.mir @@ -0,0 +1,143 @@ +# REQUIRES: asserts +# RUN: llc -mtriple=powerpc64le-unknown-linux-gnu -mcpu=pwr8 \ +# RUN: -start-before=prologepilog -debug-only=reginfo --filetype=null \ +# RUN: -verify-machineinstrs %s 2>&1 >/dev/null | FileCheck %s --check-prefix=P8 +# RUN: llc -mtriple=powerpc64le-unknown-linux-gnu -mcpu=pwr9 \ +# RUN: -start-before=prologepilog -debug-only=reginfo --filetype=null \ +# RUN: -verify-machineinstrs %s 2>&1 >/dev/null | FileCheck %s --check-prefix=P9 +# RUN: llc -mtriple=powerpc64le-unknown-linux-gnu -mcpu=pwr9 \ +# RUN: -start-before=prologepilog -debug-only=reginfo \ +# RUN: --filetype=null -ppc-enable-pe-vector-spills \ +# RUN: -verify-machineinstrs %s 2>&1 >/dev/null | FileCheck %s --check-prefix=P9-REGSPILL +# RUN: llc -mtriple=powerpc64le-unknown-linux-gnu -mcpu=pwr10 \ +# RUN: -start-before=prologepilog -debug-only=reginfo --filetype=null \ +# RUN: -verify-machineinstrs %s 2>&1 >/dev/null | FileCheck %s -check-prefix=P10 + +--- +name: SpillGPR +alignment: 16 +tracksRegLiveness: true +liveins: +body: | + bb.0.entry: + $r14 = IMPLICIT_DEF + $r15 = IMPLICIT_DEF + $r16 = IMPLICIT_DEF + $r17 = IMPLICIT_DEF + $lr8 = IMPLICIT_DEF + BLR8 implicit undef $lr8, implicit undef $rm +## TODO: Calling requiresFrameIndexScavenging from PEI::runOnMachineFunction +## always returns TRUE because MFI.isCalleeSavedInfoValid() always +## indicates that the callee saved info is invalid at that point. The +## info becomes valid for later calls. Can we do better? +# P8: requiresFrameIndexScavenging for SpillGPR. +# P8: TRUE - Invalid callee saved info. +# P8: requiresFrameIndexScavenging for SpillGPR. +# P8: FALSE - Scavenging is not required. +# P9: requiresFrameIndexScavenging for SpillGPR. +# P9: TRUE - Invalid callee saved info. +# P9: requiresFrameIndexScavenging for SpillGPR. +# P9: FALSE - Scavenging is not required. +# P9-REGSPILL: requiresFrameIndexScavenging for SpillGPR. +# P9-REGSPILL: TRUE - Invalid callee saved info. +# P9-REGSPILL: requiresFrameIndexScavenging for SpillGPR. +# P9-REGSPILL: FALSE - Scavenging is not required. +# P10: requiresFrameIndexScavenging for SpillGPR. +# P10: TRUE - Invalid callee saved info. +# P10: requiresFrameIndexScavenging for SpillGPR. +# P10: FALSE - Scavenging is not required. +... + +--- +name: SpillFPR +alignment: 16 +tracksRegLiveness: true +liveins: +body: | + bb.0.entry: + $f14 = IMPLICIT_DEF + $f15 = IMPLICIT_DEF + $f16 = IMPLICIT_DEF + $f17 = IMPLICIT_DEF + $lr8 = IMPLICIT_DEF + BLR8 implicit undef $lr8, implicit undef $rm + +# P8: requiresFrameIndexScavenging for SpillFPR. +# P8: TRUE - Invalid callee saved info. +# P8: requiresFrameIndexScavenging for SpillFPR. +# P8: FALSE - Scavenging is not required. +# P9: requiresFrameIndexScavenging for SpillFPR. +# P9: TRUE - Invalid callee saved info. +# P9: requiresFrameIndexScavenging for SpillFPR. +# P9: FALSE - Scavenging is not required. +# P9-REGSPILL: requiresFrameIndexScavenging for SpillFPR. +# P9-REGSPILL: TRUE - Invalid callee saved info. +# P9-REGSPILL: requiresFrameIndexScavenging for SpillFPR. +# P9-REGSPILL: FALSE - Scavenging is not required. +# P10: requiresFrameIndexScavenging for SpillFPR. +# P10: TRUE - Invalid callee saved info. +# P10: requiresFrameIndexScavenging for SpillFPR. +# P10: FALSE - Scavenging is not required. +... + +--- +name: SpillVR +alignment: 16 +tracksRegLiveness: true +liveins: +body: | + bb.0.entry: + $v20 = IMPLICIT_DEF + $v21 = IMPLICIT_DEF + $v22 = IMPLICIT_DEF + $v23 = IMPLICIT_DEF + $lr8 = IMPLICIT_DEF + BLR8 implicit undef $lr8, implicit undef $rm + +# P8: requiresFrameIndexScavenging for SpillVR. +# P8: TRUE - Invalid callee saved info. +# P8: requiresFrameIndexScavenging for SpillVR. +# P8: Memory Operand: STVX for register $v20. +# P8: TRUE - Memory operand is X-Form. +# P9: requiresFrameIndexScavenging for SpillVR. +# P9: TRUE - Invalid callee saved info. +# P9: requiresFrameIndexScavenging for SpillVR. +# P9: Memory Operand: STVX for register $v20. +# P9: TRUE - Memory operand is X-Form. +# P9-REGSPILL: requiresFrameIndexScavenging for SpillVR. +# P9-REGSPILL: TRUE - Invalid callee saved info. +# P9-REGSPILL: requiresFrameIndexScavenging for SpillVR. +# P9-REGSPILL: Memory Operand: STVX for register $v20. +# P9-REGSPILL: TRUE - Memory operand is X-Form. +# P10: requiresFrameIndexScavenging for SpillVR. +# P10: TRUE - Invalid callee saved info. +# P10: requiresFrameIndexScavenging for SpillVR. +# P10: Memory Operand: STVX for register $v20. +# P10: TRUE - Memory operand is X-Form. +... + +--- +name: SpillMixed +alignment: 16 +tracksRegLiveness: true +liveins: +body: | + bb.0.entry: + $r14 = IMPLICIT_DEF + $r15 = IMPLICIT_DEF + $f16 = IMPLICIT_DEF + $f17 = IMPLICIT_DEF + $v20 = IMPLICIT_DEF + $v21 = IMPLICIT_DEF + $lr8 = IMPLICIT_DEF + BLR8 implicit undef $lr8, implicit undef $rm + +# P8: requiresFrameIndexScavenging for SpillMixed. +# P8: TRUE - Invalid callee saved info. +# P9: requiresFrameIndexScavenging for SpillMixed. +# P9: TRUE - Invalid callee saved info. +# P9-REGSPILL: requiresFrameIndexScavenging for SpillMixed. +# P9-REGSPILL: TRUE - Invalid callee saved info. +# P10: requiresFrameIndexScavenging for SpillMixed. +# P10: TRUE - Invalid callee saved info. +...