HexagonExpandPredSpillCode.cpp revision 280031
1239310Sdim//===-- HexagonExpandPredSpillCode.cpp - Expand Predicate Spill Code ------===// 2239310Sdim// 3239310Sdim// The LLVM Compiler Infrastructure 4239310Sdim// 5239310Sdim// This file is distributed under the University of Illinois Open Source 6239310Sdim// License. See LICENSE.TXT for details. 7239310Sdim// 8239310Sdim//===----------------------------------------------------------------------===// 9239310Sdim// The Hexagon processor has no instructions that load or store predicate 10239310Sdim// registers directly. So, when these registers must be spilled a general 11239310Sdim// purpose register must be found and the value copied to/from it from/to 12239310Sdim// the predicate register. This code currently does not use the register 13239310Sdim// scavenger mechanism available in the allocator. There are two registers 14239310Sdim// reserved to allow spilling/restoring predicate registers. One is used to 15249423Sdim// hold the predicate value. The other is used when stack frame offsets are 16239310Sdim// too large. 17249423Sdim// 18249423Sdim//===----------------------------------------------------------------------===// 19280031Sdim 20288943Sdim#include "Hexagon.h" 21239310Sdim#include "HexagonMachineFunctionInfo.h" 22239310Sdim#include "HexagonSubtarget.h" 23239310Sdim#include "HexagonTargetMachine.h" 24239310Sdim#include "llvm/ADT/Statistic.h" 25239310Sdim#include "llvm/CodeGen/LatencyPriorityQueue.h" 26249423Sdim#include "llvm/CodeGen/MachineDominators.h" 27276479Sdim#include "llvm/CodeGen/MachineFunctionPass.h" 28288943Sdim#include "llvm/CodeGen/MachineInstrBuilder.h" 29276479Sdim#include "llvm/CodeGen/MachineLoopInfo.h" 30239310Sdim#include "llvm/CodeGen/MachineRegisterInfo.h" 31239310Sdim#include "llvm/CodeGen/Passes.h" 32239310Sdim#include "llvm/CodeGen/ScheduleHazardRecognizer.h" 33239310Sdim#include "llvm/CodeGen/SchedulerRegistry.h" 34249423Sdim#include "llvm/Support/Compiler.h" 35249423Sdim#include "llvm/Support/Debug.h" 36249423Sdim#include "llvm/Support/MathExtras.h" 37239310Sdim#include "llvm/Target/TargetInstrInfo.h" 38239310Sdim#include "llvm/Target/TargetMachine.h" 39239310Sdim#include "llvm/Target/TargetRegisterInfo.h" 40239310Sdim 41239310Sdimusing namespace llvm; 42239310Sdim 43239310Sdim 44239310Sdimnamespace llvm { 45239310Sdim void initializeHexagonExpandPredSpillCodePass(PassRegistry&); 46239310Sdim} 47239310Sdim 48239310Sdim 49239310Sdimnamespace { 50249423Sdim 51249423Sdimclass HexagonExpandPredSpillCode : public MachineFunctionPass { 52251662Sdim const HexagonTargetMachine& QTM; 53288943Sdim const HexagonSubtarget &QST; 54276479Sdim 55276479Sdim public: 56296417Sdim static char ID; 57288943Sdim HexagonExpandPredSpillCode(const HexagonTargetMachine& TM) : 58288943Sdim MachineFunctionPass(ID), QTM(TM), QST(*TM.getSubtargetImpl()) { 59249423Sdim PassRegistry &Registry = *PassRegistry::getPassRegistry(); 60239310Sdim initializeHexagonExpandPredSpillCodePass(Registry); 61239310Sdim } 62239310Sdim 63239310Sdim const char *getPassName() const override { 64239310Sdim return "Hexagon Expand Predicate Spill Code"; 65239310Sdim } 66249423Sdim bool runOnMachineFunction(MachineFunction &Fn) override; 67249423Sdim}; 68296417Sdim 69296417Sdim 70296417Sdimchar HexagonExpandPredSpillCode::ID = 0; 71296417Sdim 72296417Sdim 73296417Sdimbool HexagonExpandPredSpillCode::runOnMachineFunction(MachineFunction &Fn) { 74296417Sdim 75296417Sdim const HexagonInstrInfo *TII = QTM.getSubtargetImpl()->getInstrInfo(); 76296417Sdim 77239310Sdim // Loop over all of the basic blocks. 78239310Sdim for (MachineFunction::iterator MBBb = Fn.begin(), MBBe = Fn.end(); 79288943Sdim MBBb != MBBe; ++MBBb) { 80288943Sdim MachineBasicBlock* MBB = MBBb; 81288943Sdim // Traverse the basic block. 82288943Sdim for (MachineBasicBlock::iterator MII = MBB->begin(); MII != MBB->end(); 83288943Sdim ++MII) { 84288943Sdim MachineInstr *MI = MII; 85288943Sdim int Opc = MI->getOpcode(); 86288943Sdim if (Opc == Hexagon::STriw_pred) { 87288943Sdim // STriw_pred [R30], ofst, SrcReg; 88288943Sdim unsigned FP = MI->getOperand(0).getReg(); 89288943Sdim assert( 90288943Sdim FP == 91276479Sdim QTM.getSubtargetImpl()->getRegisterInfo()->getFrameRegister() && 92276479Sdim "Not a Frame Pointer, Nor a Spill Slot"); 93276479Sdim assert(MI->getOperand(1).isImm() && "Not an offset"); 94276479Sdim int Offset = MI->getOperand(1).getImm(); 95288943Sdim int SrcReg = MI->getOperand(2).getReg(); 96288943Sdim assert(Hexagon::PredRegsRegClass.contains(SrcReg) && 97288943Sdim "Not a predicate register"); 98288943Sdim if (!TII->isValidOffset(Hexagon::S2_storeri_io, Offset)) { 99288943Sdim if (!TII->isValidOffset(Hexagon::ADD_ri, Offset)) { 100288943Sdim BuildMI(*MBB, MII, MI->getDebugLoc(), 101288943Sdim TII->get(Hexagon::CONST32_Int_Real), 102288943Sdim HEXAGON_RESERVED_REG_1).addImm(Offset); 103261991Sdim BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::A2_add), 104261991Sdim HEXAGON_RESERVED_REG_1) 105239310Sdim .addReg(FP).addReg(HEXAGON_RESERVED_REG_1); 106280031Sdim BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::C2_tfrpr), 107280031Sdim HEXAGON_RESERVED_REG_2).addReg(SrcReg); 108239310Sdim BuildMI(*MBB, MII, MI->getDebugLoc(), 109239310Sdim TII->get(Hexagon::S2_storeri_io)) 110288943Sdim .addReg(HEXAGON_RESERVED_REG_1) 111288943Sdim .addImm(0).addReg(HEXAGON_RESERVED_REG_2); 112288943Sdim } else { 113288943Sdim BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::ADD_ri), 114288943Sdim HEXAGON_RESERVED_REG_1).addReg(FP).addImm(Offset); 115249423Sdim BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::C2_tfrpr), 116239310Sdim HEXAGON_RESERVED_REG_2).addReg(SrcReg); 117239310Sdim BuildMI(*MBB, MII, MI->getDebugLoc(), 118239310Sdim TII->get(Hexagon::S2_storeri_io)) 119288943Sdim .addReg(HEXAGON_RESERVED_REG_1) 120288943Sdim .addImm(0) 121288943Sdim .addReg(HEXAGON_RESERVED_REG_2); 122288943Sdim } 123288943Sdim } else { 124249423Sdim BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::C2_tfrpr), 125239310Sdim HEXAGON_RESERVED_REG_2).addReg(SrcReg); 126261991Sdim BuildMI(*MBB, MII, MI->getDebugLoc(), 127239310Sdim TII->get(Hexagon::S2_storeri_io)). 128239310Sdim addReg(FP).addImm(Offset).addReg(HEXAGON_RESERVED_REG_2); 129239310Sdim } 130249423Sdim MII = MBB->erase(MI); 131239310Sdim --MII; 132239310Sdim } else if (Opc == Hexagon::LDriw_pred) { 133239310Sdim // DstReg = LDriw_pred [R30], ofst. 134239310Sdim int DstReg = MI->getOperand(0).getReg(); 135239310Sdim assert(Hexagon::PredRegsRegClass.contains(DstReg) && 136276479Sdim "Not a predicate register"); 137276479Sdim unsigned FP = MI->getOperand(1).getReg(); 138280031Sdim assert( 139276479Sdim FP == 140261991Sdim QTM.getSubtargetImpl()->getRegisterInfo()->getFrameRegister() && 141276479Sdim "Not a Frame Pointer, Nor a Spill Slot"); 142276479Sdim assert(MI->getOperand(2).isImm() && "Not an offset"); 143276479Sdim int Offset = MI->getOperand(2).getImm(); 144296417Sdim if (!TII->isValidOffset(Hexagon::L2_loadri_io, Offset)) { 145296417Sdim if (!TII->isValidOffset(Hexagon::ADD_ri, Offset)) { 146296417Sdim BuildMI(*MBB, MII, MI->getDebugLoc(), 147296417Sdim TII->get(Hexagon::CONST32_Int_Real), 148239310Sdim HEXAGON_RESERVED_REG_1).addImm(Offset); 149261991Sdim BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::A2_add), 150239310Sdim HEXAGON_RESERVED_REG_1) 151239310Sdim .addReg(FP) 152239310Sdim .addReg(HEXAGON_RESERVED_REG_1); 153239310Sdim BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::L2_loadri_io), 154239310Sdim HEXAGON_RESERVED_REG_2) 155239310Sdim .addReg(HEXAGON_RESERVED_REG_1) 156288943Sdim .addImm(0); 157296417Sdim BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::C2_tfrrp), 158288943Sdim DstReg).addReg(HEXAGON_RESERVED_REG_2); 159288943Sdim } else { 160280031Sdim BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::ADD_ri), 161280031Sdim HEXAGON_RESERVED_REG_1).addReg(FP).addImm(Offset); 162296417Sdim BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::L2_loadri_io), 163296417Sdim HEXAGON_RESERVED_REG_2) 164296417Sdim .addReg(HEXAGON_RESERVED_REG_1) 165296417Sdim .addImm(0); 166296417Sdim BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::C2_tfrrp), 167296417Sdim DstReg).addReg(HEXAGON_RESERVED_REG_2); 168296417Sdim } 169251662Sdim } else { 170261991Sdim BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::L2_loadri_io), 171261991Sdim HEXAGON_RESERVED_REG_2).addReg(FP).addImm(Offset); 172261991Sdim BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::C2_tfrrp), 173261991Sdim DstReg).addReg(HEXAGON_RESERVED_REG_2); 174261991Sdim } 175261991Sdim MII = MBB->erase(MI); 176261991Sdim --MII; 177261991Sdim } 178261991Sdim } 179296417Sdim } 180276479Sdim 181276479Sdim return true; 182251662Sdim} 183296417Sdim 184296417Sdim} 185288943Sdim 186288943Sdim//===----------------------------------------------------------------------===// 187288943Sdim// Public Constructor Functions 188288943Sdim//===----------------------------------------------------------------------===// 189288943Sdim 190276479Sdimstatic void initializePassOnce(PassRegistry &Registry) { 191288943Sdim const char *Name = "Hexagon Expand Predicate Spill Code"; 192288943Sdim PassInfo *PI = new PassInfo(Name, "hexagon-spill-pred", 193288943Sdim &HexagonExpandPredSpillCode::ID, 194288943Sdim nullptr, false, false); 195296417Sdim Registry.registerPass(*PI, true); 196296417Sdim} 197276479Sdim 198296417Sdimvoid llvm::initializeHexagonExpandPredSpillCodePass(PassRegistry &Registry) { 199288943Sdim CALL_ONCE_INITIALIZATION(initializePassOnce) 200288943Sdim} 201288943Sdim 202288943SdimFunctionPass* 203288943Sdimllvm::createHexagonExpandPredSpillCode(const HexagonTargetMachine &TM) { 204288943Sdim return new HexagonExpandPredSpillCode(TM); 205296417Sdim} 206288943Sdim