diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2019-01-19 10:01:25 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2019-01-19 10:01:25 +0000 | 
| commit | d8e91e46262bc44006913e6796843909f1ac7bcd (patch) | |
| tree | 7d0c143d9b38190e0fa0180805389da22cd834c5 /lib/Target/PowerPC/PPCFrameLowering.cpp | |
| parent | b7eb8e35e481a74962664b63dfb09483b200209a (diff) | |
Notes
Diffstat (limited to 'lib/Target/PowerPC/PPCFrameLowering.cpp')
| -rw-r--r-- | lib/Target/PowerPC/PPCFrameLowering.cpp | 139 | 
1 files changed, 116 insertions, 23 deletions
diff --git a/lib/Target/PowerPC/PPCFrameLowering.cpp b/lib/Target/PowerPC/PPCFrameLowering.cpp index 84dacf396462..8263954994d2 100644 --- a/lib/Target/PowerPC/PPCFrameLowering.cpp +++ b/lib/Target/PowerPC/PPCFrameLowering.cpp @@ -17,6 +17,7 @@  #include "PPCMachineFunctionInfo.h"  #include "PPCSubtarget.h"  #include "PPCTargetMachine.h" +#include "llvm/ADT/Statistic.h"  #include "llvm/CodeGen/MachineFrameInfo.h"  #include "llvm/CodeGen/MachineFunction.h"  #include "llvm/CodeGen/MachineInstrBuilder.h" @@ -28,6 +29,16 @@  using namespace llvm; +#define DEBUG_TYPE "framelowering" +STATISTIC(NumNoNeedForFrame, "Number of functions without frames"); +STATISTIC(NumPESpillVSR, "Number of spills to vector in prologue"); +STATISTIC(NumPEReloadVSR, "Number of reloads from vector in epilogue"); + +static cl::opt<bool> +EnablePEVectorSpills("ppc-enable-pe-vector-spills", +                     cl::desc("Enable spills in prologue to vector registers."), +                     cl::init(false), cl::Hidden); +  /// VRRegNo - Map from a numbered VR register to its enum value.  ///  static const MCPhysReg VRRegNo[] = { @@ -466,6 +477,7 @@ unsigned PPCFrameLowering::determineFrameLayout(MachineFunction &MF,    // Check whether we can skip adjusting the stack pointer (by using red zone)    if (!DisableRedZone && CanUseRedZone && FitsInRedZone) { +    NumNoNeedForFrame++;      // No need for frame      if (UpdateMF)        MFI.setStackSize(0); @@ -1213,11 +1225,20 @@ void PPCFrameLowering::emitPrologue(MachineFunction &MF,          continue;        } -      int Offset = MFI.getObjectOffset(CSI[I].getFrameIdx()); -      unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset( -          nullptr, MRI->getDwarfRegNum(Reg, true), Offset)); -      BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION)) -          .addCFIIndex(CFIIndex); +      if (CSI[I].isSpilledToReg()) { +        unsigned SpilledReg = CSI[I].getDstReg(); +        unsigned CFIRegister = MF.addFrameInst(MCCFIInstruction::createRegister( +            nullptr, MRI->getDwarfRegNum(Reg, true), +            MRI->getDwarfRegNum(SpilledReg, true))); +        BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION)) +          .addCFIIndex(CFIRegister); +      } else { +        int Offset = MFI.getObjectOffset(CSI[I].getFrameIdx()); +        unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset( +            nullptr, MRI->getDwarfRegNum(Reg, true), Offset)); +        BuildMI(MBB, MBBI, dl, TII.get(TargetOpcode::CFI_INSTRUCTION)) +            .addCFIIndex(CFIIndex); +      }      }    }  } @@ -1822,17 +1843,19 @@ void PPCFrameLowering::processFunctionBeforeFrameFinalized(MachineFunction &MF,      // Move general register save area spill slots down, taking into account      // the size of the Floating-point register save area.      for (unsigned i = 0, e = GPRegs.size(); i != e; ++i) { -      int FI = GPRegs[i].getFrameIdx(); - -      MFI.setObjectOffset(FI, LowerBound + MFI.getObjectOffset(FI)); +      if (!GPRegs[i].isSpilledToReg()) { +        int FI = GPRegs[i].getFrameIdx(); +        MFI.setObjectOffset(FI, LowerBound + MFI.getObjectOffset(FI)); +      }      }      // Move general register save area spill slots down, taking into account      // the size of the Floating-point register save area.      for (unsigned i = 0, e = G8Regs.size(); i != e; ++i) { -      int FI = G8Regs[i].getFrameIdx(); - -      MFI.setObjectOffset(FI, LowerBound + MFI.getObjectOffset(FI)); +      if (!G8Regs[i].isSpilledToReg()) { +        int FI = G8Regs[i].getFrameIdx(); +        MFI.setObjectOffset(FI, LowerBound + MFI.getObjectOffset(FI)); +      }      }      unsigned MinReg = @@ -1947,6 +1970,64 @@ PPCFrameLowering::addScavengingSpillSlot(MachineFunction &MF,    }  } +// This function checks if a callee saved gpr can be spilled to a volatile +// vector register. This occurs for leaf functions when the option +// ppc-enable-pe-vector-spills is enabled. If there are any remaining registers +// which were not spilled to vectors, return false so the target independent +// code can handle them by assigning a FrameIdx to a stack slot. +bool PPCFrameLowering::assignCalleeSavedSpillSlots( +    MachineFunction &MF, const TargetRegisterInfo *TRI, +    std::vector<CalleeSavedInfo> &CSI) const { + +  if (CSI.empty()) +    return true; // Early exit if no callee saved registers are modified! + +  // Early exit if cannot spill gprs to volatile vector registers. +  MachineFrameInfo &MFI = MF.getFrameInfo(); +  if (!EnablePEVectorSpills || MFI.hasCalls() || !Subtarget.hasP9Vector()) +    return false; + +  // Build a BitVector of VSRs that can be used for spilling GPRs. +  BitVector BVAllocatable = TRI->getAllocatableSet(MF); +  BitVector BVCalleeSaved(TRI->getNumRegs()); +  const PPCRegisterInfo *RegInfo = Subtarget.getRegisterInfo(); +  const MCPhysReg *CSRegs = RegInfo->getCalleeSavedRegs(&MF); +  for (unsigned i = 0; CSRegs[i]; ++i) +    BVCalleeSaved.set(CSRegs[i]); + +  for (unsigned Reg : BVAllocatable.set_bits()) { +    // Set to 0 if the register is not a volatile VF/F8 register, or if it is +    // used in the function. +    if (BVCalleeSaved[Reg] || +        (!PPC::F8RCRegClass.contains(Reg) && +         !PPC::VFRCRegClass.contains(Reg)) || +        (MF.getRegInfo().isPhysRegUsed(Reg))) +      BVAllocatable.reset(Reg); +  } + +  bool AllSpilledToReg = true; +  for (auto &CS : CSI) { +    if (BVAllocatable.none()) +      return false; + +    unsigned Reg = CS.getReg(); +    if (!PPC::G8RCRegClass.contains(Reg) && !PPC::GPRCRegClass.contains(Reg)) { +      AllSpilledToReg = false; +      continue; +    } + +    unsigned VolatileVFReg = BVAllocatable.find_first(); +    if (VolatileVFReg < BVAllocatable.size()) { +      CS.setDstReg(VolatileVFReg); +      BVAllocatable.reset(VolatileVFReg); +    } else { +      AllSpilledToReg = false; +    } +  } +  return AllSpilledToReg; +} + +  bool  PPCFrameLowering::spillCalleeSavedRegisters(MachineBasicBlock &MBB,                                       MachineBasicBlock::iterator MI, @@ -2012,12 +2093,18 @@ PPCFrameLowering::spillCalleeSavedRegisters(MachineBasicBlock &MBB,                                           CSI[i].getFrameIdx()));        }      } else { -      const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); -      // Use !IsLiveIn for the kill flag. -      // We do not want to kill registers that are live in this function -      // before their use because they will become undefined registers. -      TII.storeRegToStackSlot(MBB, MI, Reg, !IsLiveIn, -                              CSI[i].getFrameIdx(), RC, TRI); +      if (CSI[i].isSpilledToReg()) { +        NumPESpillVSR++; +        BuildMI(MBB, MI, DL, TII.get(PPC::MTVSRD), CSI[i].getDstReg()) +          .addReg(Reg, getKillRegState(true)); +      } else { +        const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); +        // Use !IsLiveIn for the kill flag. +        // We do not want to kill registers that are live in this function +        // before their use because they will become undefined registers. +        TII.storeRegToStackSlot(MBB, MI, Reg, !IsLiveIn, +                                CSI[i].getFrameIdx(), RC, TRI); +      }      }    }    return true; @@ -2157,13 +2244,19 @@ PPCFrameLowering::restoreCalleeSavedRegisters(MachineBasicBlock &MBB,          CR2Spilled = CR3Spilled = CR4Spilled = false;        } -      // Default behavior for non-CR saves. -      const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); -      TII.loadRegFromStackSlot(MBB, I, Reg, CSI[i].getFrameIdx(), -                               RC, TRI); -      assert(I != MBB.begin() && -             "loadRegFromStackSlot didn't insert any code!"); +      if (CSI[i].isSpilledToReg()) { +        DebugLoc DL; +        NumPEReloadVSR++; +        BuildMI(MBB, I, DL, TII.get(PPC::MFVSRD), Reg) +            .addReg(CSI[i].getDstReg(), getKillRegState(true)); +      } else { +       // Default behavior for non-CR saves. +        const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); +        TII.loadRegFromStackSlot(MBB, I, Reg, CSI[i].getFrameIdx(), RC, TRI); +        assert(I != MBB.begin() && +               "loadRegFromStackSlot didn't insert any code!");        } +    }      // Insert in reverse order.      if (AtStart)  | 
