From 40e9e0826be8e7a80a5d0e3362311bc5c7d14e3d Mon Sep 17 00:00:00 2001 From: Kai Luo Date: Fri, 3 Jul 2020 03:30:38 +0000 Subject: [PATCH] [PowerPC][NFC] Refactor lowerDynamicAlloc When performing dynamic stack allocation, calculation of frame pointer and actual negsize can be separated. This patch refactors `lowerDynamicAlloc` in preparation of supporting `-fstack-clash-protection` which also has to calculate actual frame pointer and negsize. Differential Revision: https://reviews.llvm.org/D81354 --- llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp | 117 ++++++++++++-------- llvm/lib/Target/PowerPC/PPCRegisterInfo.h | 3 + 2 files changed, 76 insertions(+), 44 deletions(-) diff --git a/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp b/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp index 2b1ea8c2ec40..2dfadd85f2d4 100644 --- a/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp +++ b/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp @@ -480,6 +480,62 @@ void PPCRegisterInfo::lowerDynamicAlloc(MachineBasicBlock::iterator II) const { // Get the maximum call stack size. unsigned maxCallFrameSize = MFI.getMaxCallFrameSize(); + Align MaxAlign = MFI.getMaxAlign(); + assert(isAligned(MaxAlign, maxCallFrameSize) && + "Maximum call-frame size not sufficiently aligned"); + + const TargetRegisterClass *G8RC = &PPC::G8RCRegClass; + const TargetRegisterClass *GPRC = &PPC::GPRCRegClass; + Register Reg = MF.getRegInfo().createVirtualRegister(LP64 ? G8RC : GPRC); + bool KillNegSizeReg = MI.getOperand(1).isKill(); + Register NegSizeReg = MI.getOperand(1).getReg(); + + prepareDynamicAlloca(II, NegSizeReg, KillNegSizeReg, Reg); + // Grow the stack and update the stack pointer link, then determine the + // address of new allocated space. + if (LP64) { + BuildMI(MBB, II, dl, TII.get(PPC::STDUX), PPC::X1) + .addReg(Reg, RegState::Kill) + .addReg(PPC::X1) + .addReg(NegSizeReg, getKillRegState(KillNegSizeReg)); + BuildMI(MBB, II, dl, TII.get(PPC::ADDI8), MI.getOperand(0).getReg()) + .addReg(PPC::X1) + .addImm(maxCallFrameSize); + } else { + BuildMI(MBB, II, dl, TII.get(PPC::STWUX), PPC::R1) + .addReg(Reg, RegState::Kill) + .addReg(PPC::R1) + .addReg(NegSizeReg, getKillRegState(KillNegSizeReg)); + BuildMI(MBB, II, dl, TII.get(PPC::ADDI), MI.getOperand(0).getReg()) + .addReg(PPC::R1) + .addImm(maxCallFrameSize); + } + + // Discard the DYNALLOC instruction. + MBB.erase(II); +} + +/// To accomplish dynamic stack allocation, we have to calculate exact size +/// subtracted from the stack pointer according alignment information and get +/// previous frame pointer. +void PPCRegisterInfo::prepareDynamicAlloca(MachineBasicBlock::iterator II, + Register &NegSizeReg, + bool &KillNegSizeReg, + Register &FramePointer) const { + // Get the instruction. + MachineInstr &MI = *II; + // Get the instruction's basic block. + MachineBasicBlock &MBB = *MI.getParent(); + // Get the basic block's function. + MachineFunction &MF = *MBB.getParent(); + // Get the frame info. + MachineFrameInfo &MFI = MF.getFrameInfo(); + const PPCSubtarget &Subtarget = MF.getSubtarget(); + // Get the instruction info. + const TargetInstrInfo &TII = *Subtarget.getInstrInfo(); + // Determine whether 64-bit pointers are used. + bool LP64 = TM.isPPC64(); + DebugLoc dl = MI.getDebugLoc(); // Get the total frame size. unsigned FrameSize = MFI.getStackSize(); @@ -487,8 +543,6 @@ void PPCRegisterInfo::lowerDynamicAlloc(MachineBasicBlock::iterator II) const { const PPCFrameLowering *TFI = getFrameLowering(MF); Align TargetAlign = TFI->getStackAlign(); Align MaxAlign = MFI.getMaxAlign(); - assert(isAligned(MaxAlign, maxCallFrameSize) && - "Maximum call-frame size not sufficiently aligned"); // Determine the previous frame's address. If FrameSize can't be // represented as 16 bits or we need special alignment, then we load the @@ -498,32 +552,26 @@ void PPCRegisterInfo::lowerDynamicAlloc(MachineBasicBlock::iterator II) const { // Fortunately, a frame greater than 32K is rare. const TargetRegisterClass *G8RC = &PPC::G8RCRegClass; const TargetRegisterClass *GPRC = &PPC::GPRCRegClass; - Register Reg = MF.getRegInfo().createVirtualRegister(LP64 ? G8RC : GPRC); if (MaxAlign < TargetAlign && isInt<16>(FrameSize)) { if (LP64) - BuildMI(MBB, II, dl, TII.get(PPC::ADDI8), Reg) - .addReg(PPC::X31) - .addImm(FrameSize); + BuildMI(MBB, II, dl, TII.get(PPC::ADDI8), FramePointer) + .addReg(PPC::X31) + .addImm(FrameSize); else - BuildMI(MBB, II, dl, TII.get(PPC::ADDI), Reg) - .addReg(PPC::R31) - .addImm(FrameSize); + BuildMI(MBB, II, dl, TII.get(PPC::ADDI), FramePointer) + .addReg(PPC::R31) + .addImm(FrameSize); } else if (LP64) { - BuildMI(MBB, II, dl, TII.get(PPC::LD), Reg) - .addImm(0) - .addReg(PPC::X1); + BuildMI(MBB, II, dl, TII.get(PPC::LD), FramePointer) + .addImm(0) + .addReg(PPC::X1); } else { - BuildMI(MBB, II, dl, TII.get(PPC::LWZ), Reg) - .addImm(0) - .addReg(PPC::R1); + BuildMI(MBB, II, dl, TII.get(PPC::LWZ), FramePointer) + .addImm(0) + .addReg(PPC::R1); } - - bool KillNegSizeReg = MI.getOperand(1).isKill(); - Register NegSizeReg = MI.getOperand(1).getReg(); - - // Grow the stack and update the stack pointer link, then determine the - // address of new allocated space. + // Determine the actual NegSizeReg according to alignment info. if (LP64) { if (MaxAlign > TargetAlign) { unsigned UnalNegSizeReg = NegSizeReg; @@ -537,18 +585,10 @@ void PPCRegisterInfo::lowerDynamicAlloc(MachineBasicBlock::iterator II) const { unsigned NegSizeReg1 = NegSizeReg; NegSizeReg = MF.getRegInfo().createVirtualRegister(G8RC); BuildMI(MBB, II, dl, TII.get(PPC::AND8), NegSizeReg) - .addReg(UnalNegSizeReg, getKillRegState(KillNegSizeReg)) - .addReg(NegSizeReg1, RegState::Kill); + .addReg(UnalNegSizeReg, getKillRegState(KillNegSizeReg)) + .addReg(NegSizeReg1, RegState::Kill); KillNegSizeReg = true; } - - BuildMI(MBB, II, dl, TII.get(PPC::STDUX), PPC::X1) - .addReg(Reg, RegState::Kill) - .addReg(PPC::X1) - .addReg(NegSizeReg, getKillRegState(KillNegSizeReg)); - BuildMI(MBB, II, dl, TII.get(PPC::ADDI8), MI.getOperand(0).getReg()) - .addReg(PPC::X1) - .addImm(maxCallFrameSize); } else { if (MaxAlign > TargetAlign) { unsigned UnalNegSizeReg = NegSizeReg; @@ -562,22 +602,11 @@ void PPCRegisterInfo::lowerDynamicAlloc(MachineBasicBlock::iterator II) const { unsigned NegSizeReg1 = NegSizeReg; NegSizeReg = MF.getRegInfo().createVirtualRegister(GPRC); BuildMI(MBB, II, dl, TII.get(PPC::AND), NegSizeReg) - .addReg(UnalNegSizeReg, getKillRegState(KillNegSizeReg)) - .addReg(NegSizeReg1, RegState::Kill); + .addReg(UnalNegSizeReg, getKillRegState(KillNegSizeReg)) + .addReg(NegSizeReg1, RegState::Kill); KillNegSizeReg = true; } - - BuildMI(MBB, II, dl, TII.get(PPC::STWUX), PPC::R1) - .addReg(Reg, RegState::Kill) - .addReg(PPC::R1) - .addReg(NegSizeReg, getKillRegState(KillNegSizeReg)); - BuildMI(MBB, II, dl, TII.get(PPC::ADDI), MI.getOperand(0).getReg()) - .addReg(PPC::R1) - .addImm(maxCallFrameSize); } - - // Discard the DYNALLOC instruction. - MBB.erase(II); } void PPCRegisterInfo::lowerDynamicAreaOffset( diff --git a/llvm/lib/Target/PowerPC/PPCRegisterInfo.h b/llvm/lib/Target/PowerPC/PPCRegisterInfo.h index 46aaa8b4e153..884c7f09d498 100644 --- a/llvm/lib/Target/PowerPC/PPCRegisterInfo.h +++ b/llvm/lib/Target/PowerPC/PPCRegisterInfo.h @@ -107,6 +107,9 @@ public: void lowerDynamicAlloc(MachineBasicBlock::iterator II) const; void lowerDynamicAreaOffset(MachineBasicBlock::iterator II) const; + void prepareDynamicAlloca(MachineBasicBlock::iterator II, + Register &NegSizeReg, bool &KillNegSizeReg, + Register &FramePointer) const; void lowerCRSpilling(MachineBasicBlock::iterator II, unsigned FrameIndex) const; void lowerCRRestore(MachineBasicBlock::iterator II,