1//===-- HexagonExpandPredSpillCode.cpp - Expand Predicate Spill Code ------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// The Hexagon processor has no instructions that load or store predicate 10// registers directly. So, when these registers must be spilled a general 11// purpose register must be found and the value copied to/from it from/to 12// the predicate register. This code currently does not use the register 13// scavenger mechanism available in the allocator. There are two registers 14// reserved to allow spilling/restoring predicate registers. One is used to 15// hold the predicate value. The other is used when stack frame offsets are 16// too large. 17// 18//===----------------------------------------------------------------------===// 19 20#include "Hexagon.h" 21#include "HexagonMachineFunctionInfo.h" 22#include "HexagonSubtarget.h" 23#include "HexagonTargetMachine.h" 24#include "llvm/ADT/Statistic.h" 25#include "llvm/CodeGen/LatencyPriorityQueue.h" 26#include "llvm/CodeGen/MachineDominators.h" 27#include "llvm/CodeGen/MachineFunctionPass.h" 28#include "llvm/CodeGen/MachineInstrBuilder.h" 29#include "llvm/CodeGen/MachineLoopInfo.h" 30#include "llvm/CodeGen/MachineRegisterInfo.h" 31#include "llvm/CodeGen/Passes.h" 32#include "llvm/CodeGen/ScheduleHazardRecognizer.h" 33#include "llvm/CodeGen/SchedulerRegistry.h" 34#include "llvm/Support/Compiler.h" 35#include "llvm/Support/Debug.h" 36#include "llvm/Support/MathExtras.h" 37#include "llvm/Target/TargetInstrInfo.h" 38#include "llvm/Target/TargetMachine.h" 39#include "llvm/Target/TargetRegisterInfo.h" 40 41using namespace llvm; 42 43 44namespace llvm { 45 void initializeHexagonExpandPredSpillCodePass(PassRegistry&); 46} 47 48 49namespace { 50 51class HexagonExpandPredSpillCode : public MachineFunctionPass { 52 const HexagonTargetMachine& QTM; 53 const HexagonSubtarget &QST; 54 55 public: 56 static char ID; 57 HexagonExpandPredSpillCode(const HexagonTargetMachine& TM) : 58 MachineFunctionPass(ID), QTM(TM), QST(*TM.getSubtargetImpl()) { 59 PassRegistry &Registry = *PassRegistry::getPassRegistry(); 60 initializeHexagonExpandPredSpillCodePass(Registry); 61 } 62 63 const char *getPassName() const { 64 return "Hexagon Expand Predicate Spill Code"; 65 } 66 bool runOnMachineFunction(MachineFunction &Fn); 67}; 68 69 70char HexagonExpandPredSpillCode::ID = 0; 71 72 73bool HexagonExpandPredSpillCode::runOnMachineFunction(MachineFunction &Fn) { 74 75 const HexagonInstrInfo *TII = QTM.getInstrInfo(); 76 77 // Loop over all of the basic blocks. 78 for (MachineFunction::iterator MBBb = Fn.begin(), MBBe = Fn.end(); 79 MBBb != MBBe; ++MBBb) { 80 MachineBasicBlock* MBB = MBBb; 81 // Traverse the basic block. 82 for (MachineBasicBlock::iterator MII = MBB->begin(); MII != MBB->end(); 83 ++MII) { 84 MachineInstr *MI = MII; 85 int Opc = MI->getOpcode(); 86 if (Opc == Hexagon::STriw_pred) { 87 // STriw_pred [R30], ofst, SrcReg; 88 unsigned FP = MI->getOperand(0).getReg(); 89 assert(FP == QTM.getRegisterInfo()->getFrameRegister() && 90 "Not a Frame Pointer, Nor a Spill Slot"); 91 assert(MI->getOperand(1).isImm() && "Not an offset"); 92 int Offset = MI->getOperand(1).getImm(); 93 int SrcReg = MI->getOperand(2).getReg(); 94 assert(Hexagon::PredRegsRegClass.contains(SrcReg) && 95 "Not a predicate register"); 96 if (!TII->isValidOffset(Hexagon::STriw_indexed, Offset)) { 97 if (!TII->isValidOffset(Hexagon::ADD_ri, Offset)) { 98 BuildMI(*MBB, MII, MI->getDebugLoc(), 99 TII->get(Hexagon::CONST32_Int_Real), 100 HEXAGON_RESERVED_REG_1).addImm(Offset); 101 BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::ADD_rr), 102 HEXAGON_RESERVED_REG_1) 103 .addReg(FP).addReg(HEXAGON_RESERVED_REG_1); 104 BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::TFR_RsPd), 105 HEXAGON_RESERVED_REG_2).addReg(SrcReg); 106 BuildMI(*MBB, MII, MI->getDebugLoc(), 107 TII->get(Hexagon::STriw_indexed)) 108 .addReg(HEXAGON_RESERVED_REG_1) 109 .addImm(0).addReg(HEXAGON_RESERVED_REG_2); 110 } else { 111 BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::ADD_ri), 112 HEXAGON_RESERVED_REG_1).addReg(FP).addImm(Offset); 113 BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::TFR_RsPd), 114 HEXAGON_RESERVED_REG_2).addReg(SrcReg); 115 BuildMI(*MBB, MII, MI->getDebugLoc(), 116 TII->get(Hexagon::STriw_indexed)) 117 .addReg(HEXAGON_RESERVED_REG_1) 118 .addImm(0) 119 .addReg(HEXAGON_RESERVED_REG_2); 120 } 121 } else { 122 BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::TFR_RsPd), 123 HEXAGON_RESERVED_REG_2).addReg(SrcReg); 124 BuildMI(*MBB, MII, MI->getDebugLoc(), 125 TII->get(Hexagon::STriw_indexed)). 126 addReg(FP).addImm(Offset).addReg(HEXAGON_RESERVED_REG_2); 127 } 128 MII = MBB->erase(MI); 129 --MII; 130 } else if (Opc == Hexagon::LDriw_pred) { 131 // DstReg = LDriw_pred [R30], ofst. 132 int DstReg = MI->getOperand(0).getReg(); 133 assert(Hexagon::PredRegsRegClass.contains(DstReg) && 134 "Not a predicate register"); 135 unsigned FP = MI->getOperand(1).getReg(); 136 assert(FP == QTM.getRegisterInfo()->getFrameRegister() && 137 "Not a Frame Pointer, Nor a Spill Slot"); 138 assert(MI->getOperand(2).isImm() && "Not an offset"); 139 int Offset = MI->getOperand(2).getImm(); 140 if (!TII->isValidOffset(Hexagon::LDriw, Offset)) { 141 if (!TII->isValidOffset(Hexagon::ADD_ri, Offset)) { 142 BuildMI(*MBB, MII, MI->getDebugLoc(), 143 TII->get(Hexagon::CONST32_Int_Real), 144 HEXAGON_RESERVED_REG_1).addImm(Offset); 145 BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::ADD_rr), 146 HEXAGON_RESERVED_REG_1) 147 .addReg(FP) 148 .addReg(HEXAGON_RESERVED_REG_1); 149 BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::LDriw), 150 HEXAGON_RESERVED_REG_2) 151 .addReg(HEXAGON_RESERVED_REG_1) 152 .addImm(0); 153 BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::TFR_PdRs), 154 DstReg).addReg(HEXAGON_RESERVED_REG_2); 155 } else { 156 BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::ADD_ri), 157 HEXAGON_RESERVED_REG_1).addReg(FP).addImm(Offset); 158 BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::LDriw), 159 HEXAGON_RESERVED_REG_2) 160 .addReg(HEXAGON_RESERVED_REG_1) 161 .addImm(0); 162 BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::TFR_PdRs), 163 DstReg).addReg(HEXAGON_RESERVED_REG_2); 164 } 165 } else { 166 BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::LDriw), 167 HEXAGON_RESERVED_REG_2).addReg(FP).addImm(Offset); 168 BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::TFR_PdRs), 169 DstReg).addReg(HEXAGON_RESERVED_REG_2); 170 } 171 MII = MBB->erase(MI); 172 --MII; 173 } 174 } 175 } 176 177 return true; 178} 179 180} 181 182//===----------------------------------------------------------------------===// 183// Public Constructor Functions 184//===----------------------------------------------------------------------===// 185 186static void initializePassOnce(PassRegistry &Registry) { 187 const char *Name = "Hexagon Expand Predicate Spill Code"; 188 PassInfo *PI = new PassInfo(Name, "hexagon-spill-pred", 189 &HexagonExpandPredSpillCode::ID, 190 0, false, false); 191 Registry.registerPass(*PI, true); 192} 193 194void llvm::initializeHexagonExpandPredSpillCodePass(PassRegistry &Registry) { 195 CALL_ONCE_INITIALIZATION(initializePassOnce) 196} 197 198FunctionPass* 199llvm::createHexagonExpandPredSpillCode(const HexagonTargetMachine &TM) { 200 return new HexagonExpandPredSpillCode(TM); 201} 202