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 "llvm/ADT/Statistic.h" 24#include "llvm/CodeGen/LatencyPriorityQueue.h" 25#include "llvm/CodeGen/MachineDominators.h" 26#include "llvm/CodeGen/MachineFunctionPass.h" 27#include "llvm/CodeGen/MachineInstrBuilder.h" 28#include "llvm/CodeGen/MachineLoopInfo.h" 29#include "llvm/CodeGen/MachineRegisterInfo.h" 30#include "llvm/CodeGen/Passes.h" 31#include "llvm/CodeGen/ScheduleHazardRecognizer.h" 32#include "llvm/CodeGen/SchedulerRegistry.h" 33#include "llvm/Support/Compiler.h" 34#include "llvm/Support/Debug.h" 35#include "llvm/Support/MathExtras.h" 36#include "llvm/Target/TargetInstrInfo.h" 37#include "llvm/Target/TargetMachine.h" 38#include "llvm/Target/TargetRegisterInfo.h" 39 40using namespace llvm; 41 42 43namespace llvm { 44 void initializeHexagonExpandPredSpillCodePass(PassRegistry&); 45} 46 47 48namespace { 49 50class HexagonExpandPredSpillCode : public MachineFunctionPass { 51 public: 52 static char ID; 53 HexagonExpandPredSpillCode() : MachineFunctionPass(ID) { 54 PassRegistry &Registry = *PassRegistry::getPassRegistry(); 55 initializeHexagonExpandPredSpillCodePass(Registry); 56 } 57 58 const char *getPassName() const override { 59 return "Hexagon Expand Predicate Spill Code"; 60 } 61 bool runOnMachineFunction(MachineFunction &Fn) override; 62}; 63 64 65char HexagonExpandPredSpillCode::ID = 0; 66 67 68bool HexagonExpandPredSpillCode::runOnMachineFunction(MachineFunction &Fn) { 69 70 const HexagonSubtarget &QST = Fn.getSubtarget<HexagonSubtarget>(); 71 const HexagonInstrInfo *TII = QST.getInstrInfo(); 72 73 // Loop over all of the basic blocks. 74 for (MachineFunction::iterator MBBb = Fn.begin(), MBBe = Fn.end(); 75 MBBb != MBBe; ++MBBb) { 76 MachineBasicBlock* MBB = MBBb; 77 // Traverse the basic block. 78 for (MachineBasicBlock::iterator MII = MBB->begin(); MII != MBB->end(); 79 ++MII) { 80 MachineInstr *MI = MII; 81 int Opc = MI->getOpcode(); 82 if (Opc == Hexagon::S2_storerb_pci_pseudo || 83 Opc == Hexagon::S2_storerh_pci_pseudo || 84 Opc == Hexagon::S2_storeri_pci_pseudo || 85 Opc == Hexagon::S2_storerd_pci_pseudo || 86 Opc == Hexagon::S2_storerf_pci_pseudo) { 87 unsigned Opcode; 88 if (Opc == Hexagon::S2_storerd_pci_pseudo) 89 Opcode = Hexagon::S2_storerd_pci; 90 else if (Opc == Hexagon::S2_storeri_pci_pseudo) 91 Opcode = Hexagon::S2_storeri_pci; 92 else if (Opc == Hexagon::S2_storerh_pci_pseudo) 93 Opcode = Hexagon::S2_storerh_pci; 94 else if (Opc == Hexagon::S2_storerf_pci_pseudo) 95 Opcode = Hexagon::S2_storerf_pci; 96 else if (Opc == Hexagon::S2_storerb_pci_pseudo) 97 Opcode = Hexagon::S2_storerb_pci; 98 else 99 llvm_unreachable("wrong Opc"); 100 MachineOperand &Op0 = MI->getOperand(0); 101 MachineOperand &Op1 = MI->getOperand(1); 102 MachineOperand &Op2 = MI->getOperand(2); 103 MachineOperand &Op3 = MI->getOperand(3); // Modifier value. 104 MachineOperand &Op4 = MI->getOperand(4); 105 // Emit a "C6 = Rn, C6 is the control register for M0". 106 BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::A2_tfrrcr), 107 Hexagon::C6)->addOperand(Op3); 108 // Replace the pseude circ_ldd by the real circ_ldd. 109 MachineInstr *NewMI = BuildMI(*MBB, MII, MI->getDebugLoc(), 110 TII->get(Opcode)); 111 NewMI->addOperand(Op0); 112 NewMI->addOperand(Op1); 113 NewMI->addOperand(Op4); 114 NewMI->addOperand(MachineOperand::CreateReg(Hexagon::M0, 115 false, /*isDef*/ 116 false, /*isImpl*/ 117 true /*isKill*/)); 118 NewMI->addOperand(Op2); 119 MII = MBB->erase(MI); 120 --MII; 121 } else if (Opc == Hexagon::L2_loadrd_pci_pseudo || 122 Opc == Hexagon::L2_loadri_pci_pseudo || 123 Opc == Hexagon::L2_loadrh_pci_pseudo || 124 Opc == Hexagon::L2_loadruh_pci_pseudo|| 125 Opc == Hexagon::L2_loadrb_pci_pseudo || 126 Opc == Hexagon::L2_loadrub_pci_pseudo) { 127 unsigned Opcode; 128 if (Opc == Hexagon::L2_loadrd_pci_pseudo) 129 Opcode = Hexagon::L2_loadrd_pci; 130 else if (Opc == Hexagon::L2_loadri_pci_pseudo) 131 Opcode = Hexagon::L2_loadri_pci; 132 else if (Opc == Hexagon::L2_loadrh_pci_pseudo) 133 Opcode = Hexagon::L2_loadrh_pci; 134 else if (Opc == Hexagon::L2_loadruh_pci_pseudo) 135 Opcode = Hexagon::L2_loadruh_pci; 136 else if (Opc == Hexagon::L2_loadrb_pci_pseudo) 137 Opcode = Hexagon::L2_loadrb_pci; 138 else if (Opc == Hexagon::L2_loadrub_pci_pseudo) 139 Opcode = Hexagon::L2_loadrub_pci; 140 else 141 llvm_unreachable("wrong Opc"); 142 143 MachineOperand &Op0 = MI->getOperand(0); 144 MachineOperand &Op1 = MI->getOperand(1); 145 MachineOperand &Op2 = MI->getOperand(2); 146 MachineOperand &Op4 = MI->getOperand(4); // Modifier value. 147 MachineOperand &Op5 = MI->getOperand(5); 148 // Emit a "C6 = Rn, C6 is the control register for M0". 149 BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::A2_tfrrcr), 150 Hexagon::C6)->addOperand(Op4); 151 // Replace the pseude circ_ldd by the real circ_ldd. 152 MachineInstr *NewMI = BuildMI(*MBB, MII, MI->getDebugLoc(), 153 TII->get(Opcode)); 154 NewMI->addOperand(Op1); 155 NewMI->addOperand(Op0); 156 NewMI->addOperand(Op2); 157 NewMI->addOperand(Op5); 158 NewMI->addOperand(MachineOperand::CreateReg(Hexagon::M0, 159 false, /*isDef*/ 160 false, /*isImpl*/ 161 true /*isKill*/)); 162 MII = MBB->erase(MI); 163 --MII; 164 } else if (Opc == Hexagon::L2_loadrd_pbr_pseudo || 165 Opc == Hexagon::L2_loadri_pbr_pseudo || 166 Opc == Hexagon::L2_loadrh_pbr_pseudo || 167 Opc == Hexagon::L2_loadruh_pbr_pseudo|| 168 Opc == Hexagon::L2_loadrb_pbr_pseudo || 169 Opc == Hexagon::L2_loadrub_pbr_pseudo) { 170 unsigned Opcode; 171 if (Opc == Hexagon::L2_loadrd_pbr_pseudo) 172 Opcode = Hexagon::L2_loadrd_pbr; 173 else if (Opc == Hexagon::L2_loadri_pbr_pseudo) 174 Opcode = Hexagon::L2_loadri_pbr; 175 else if (Opc == Hexagon::L2_loadrh_pbr_pseudo) 176 Opcode = Hexagon::L2_loadrh_pbr; 177 else if (Opc == Hexagon::L2_loadruh_pbr_pseudo) 178 Opcode = Hexagon::L2_loadruh_pbr; 179 else if (Opc == Hexagon::L2_loadrb_pbr_pseudo) 180 Opcode = Hexagon::L2_loadrb_pbr; 181 else if (Opc == Hexagon::L2_loadrub_pbr_pseudo) 182 Opcode = Hexagon::L2_loadrub_pbr; 183 else 184 llvm_unreachable("wrong Opc"); 185 MachineOperand &Op0 = MI->getOperand(0); 186 MachineOperand &Op1 = MI->getOperand(1); 187 MachineOperand &Op2 = MI->getOperand(2); 188 MachineOperand &Op4 = MI->getOperand(4); // Modifier value. 189 // Emit a "C6 = Rn, C6 is the control register for M0". 190 BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::A2_tfrrcr), 191 Hexagon::C6)->addOperand(Op4); 192 // Replace the pseudo brev_ldd by the real brev_ldd. 193 MachineInstr *NewMI = BuildMI(*MBB, MII, MI->getDebugLoc(), 194 TII->get(Opcode)); 195 NewMI->addOperand(Op1); 196 NewMI->addOperand(Op0); 197 NewMI->addOperand(Op2); 198 NewMI->addOperand(MachineOperand::CreateReg(Hexagon::M0, 199 false, /*isDef*/ 200 false, /*isImpl*/ 201 true /*isKill*/)); 202 MII = MBB->erase(MI); 203 --MII; 204 } else if (Opc == Hexagon::S2_storerd_pbr_pseudo || 205 Opc == Hexagon::S2_storeri_pbr_pseudo || 206 Opc == Hexagon::S2_storerh_pbr_pseudo || 207 Opc == Hexagon::S2_storerb_pbr_pseudo || 208 Opc == Hexagon::S2_storerf_pbr_pseudo) { 209 unsigned Opcode; 210 if (Opc == Hexagon::S2_storerd_pbr_pseudo) 211 Opcode = Hexagon::S2_storerd_pbr; 212 else if (Opc == Hexagon::S2_storeri_pbr_pseudo) 213 Opcode = Hexagon::S2_storeri_pbr; 214 else if (Opc == Hexagon::S2_storerh_pbr_pseudo) 215 Opcode = Hexagon::S2_storerh_pbr; 216 else if (Opc == Hexagon::S2_storerf_pbr_pseudo) 217 Opcode = Hexagon::S2_storerf_pbr; 218 else if (Opc == Hexagon::S2_storerb_pbr_pseudo) 219 Opcode = Hexagon::S2_storerb_pbr; 220 else 221 llvm_unreachable("wrong Opc"); 222 MachineOperand &Op0 = MI->getOperand(0); 223 MachineOperand &Op1 = MI->getOperand(1); 224 MachineOperand &Op2 = MI->getOperand(2); 225 MachineOperand &Op3 = MI->getOperand(3); // Modifier value. 226 // Emit a "C6 = Rn, C6 is the control register for M0". 227 BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::A2_tfrrcr), 228 Hexagon::C6)->addOperand(Op3); 229 // Replace the pseudo brev_ldd by the real brev_ldd. 230 MachineInstr *NewMI = BuildMI(*MBB, MII, MI->getDebugLoc(), 231 TII->get(Opcode)); 232 NewMI->addOperand(Op0); 233 NewMI->addOperand(Op1); 234 NewMI->addOperand(MachineOperand::CreateReg(Hexagon::M0, 235 false, /*isDef*/ 236 false, /*isImpl*/ 237 true /*isKill*/)); 238 NewMI->addOperand(Op2); 239 MII = MBB->erase(MI); 240 --MII; 241 } else if (Opc == Hexagon::STriw_pred) { 242 // STriw_pred [R30], ofst, SrcReg; 243 unsigned FP = MI->getOperand(0).getReg(); 244 assert(FP == QST.getRegisterInfo()->getFrameRegister() && 245 "Not a Frame Pointer, Nor a Spill Slot"); 246 assert(MI->getOperand(1).isImm() && "Not an offset"); 247 int Offset = MI->getOperand(1).getImm(); 248 int SrcReg = MI->getOperand(2).getReg(); 249 assert(Hexagon::PredRegsRegClass.contains(SrcReg) && 250 "Not a predicate register"); 251 if (!TII->isValidOffset(Hexagon::S2_storeri_io, Offset)) { 252 if (!TII->isValidOffset(Hexagon::A2_addi, Offset)) { 253 BuildMI(*MBB, MII, MI->getDebugLoc(), 254 TII->get(Hexagon::CONST32_Int_Real), 255 HEXAGON_RESERVED_REG_1).addImm(Offset); 256 BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::A2_add), 257 HEXAGON_RESERVED_REG_1) 258 .addReg(FP).addReg(HEXAGON_RESERVED_REG_1); 259 BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::C2_tfrpr), 260 HEXAGON_RESERVED_REG_2).addReg(SrcReg); 261 BuildMI(*MBB, MII, MI->getDebugLoc(), 262 TII->get(Hexagon::S2_storeri_io)) 263 .addReg(HEXAGON_RESERVED_REG_1) 264 .addImm(0).addReg(HEXAGON_RESERVED_REG_2); 265 } else { 266 BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::A2_addi), 267 HEXAGON_RESERVED_REG_1).addReg(FP).addImm(Offset); 268 BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::C2_tfrpr), 269 HEXAGON_RESERVED_REG_2).addReg(SrcReg); 270 BuildMI(*MBB, MII, MI->getDebugLoc(), 271 TII->get(Hexagon::S2_storeri_io)) 272 .addReg(HEXAGON_RESERVED_REG_1) 273 .addImm(0) 274 .addReg(HEXAGON_RESERVED_REG_2); 275 } 276 } else { 277 BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::C2_tfrpr), 278 HEXAGON_RESERVED_REG_2).addReg(SrcReg); 279 BuildMI(*MBB, MII, MI->getDebugLoc(), 280 TII->get(Hexagon::S2_storeri_io)). 281 addReg(FP).addImm(Offset).addReg(HEXAGON_RESERVED_REG_2); 282 } 283 MII = MBB->erase(MI); 284 --MII; 285 } else if (Opc == Hexagon::LDriw_pred) { 286 // DstReg = LDriw_pred [R30], ofst. 287 int DstReg = MI->getOperand(0).getReg(); 288 assert(Hexagon::PredRegsRegClass.contains(DstReg) && 289 "Not a predicate register"); 290 unsigned FP = MI->getOperand(1).getReg(); 291 assert(FP == QST.getRegisterInfo()->getFrameRegister() && 292 "Not a Frame Pointer, Nor a Spill Slot"); 293 assert(MI->getOperand(2).isImm() && "Not an offset"); 294 int Offset = MI->getOperand(2).getImm(); 295 if (!TII->isValidOffset(Hexagon::L2_loadri_io, Offset)) { 296 if (!TII->isValidOffset(Hexagon::A2_addi, Offset)) { 297 BuildMI(*MBB, MII, MI->getDebugLoc(), 298 TII->get(Hexagon::CONST32_Int_Real), 299 HEXAGON_RESERVED_REG_1).addImm(Offset); 300 BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::A2_add), 301 HEXAGON_RESERVED_REG_1) 302 .addReg(FP) 303 .addReg(HEXAGON_RESERVED_REG_1); 304 BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::L2_loadri_io), 305 HEXAGON_RESERVED_REG_2) 306 .addReg(HEXAGON_RESERVED_REG_1) 307 .addImm(0); 308 BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::C2_tfrrp), 309 DstReg).addReg(HEXAGON_RESERVED_REG_2); 310 } else { 311 BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::A2_addi), 312 HEXAGON_RESERVED_REG_1).addReg(FP).addImm(Offset); 313 BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::L2_loadri_io), 314 HEXAGON_RESERVED_REG_2) 315 .addReg(HEXAGON_RESERVED_REG_1) 316 .addImm(0); 317 BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::C2_tfrrp), 318 DstReg).addReg(HEXAGON_RESERVED_REG_2); 319 } 320 } else { 321 BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::L2_loadri_io), 322 HEXAGON_RESERVED_REG_2).addReg(FP).addImm(Offset); 323 BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::C2_tfrrp), 324 DstReg).addReg(HEXAGON_RESERVED_REG_2); 325 } 326 MII = MBB->erase(MI); 327 --MII; 328 } 329 } 330 } 331 332 return true; 333} 334 335} 336 337//===----------------------------------------------------------------------===// 338// Public Constructor Functions 339//===----------------------------------------------------------------------===// 340 341static void initializePassOnce(PassRegistry &Registry) { 342 const char *Name = "Hexagon Expand Predicate Spill Code"; 343 PassInfo *PI = new PassInfo(Name, "hexagon-spill-pred", 344 &HexagonExpandPredSpillCode::ID, 345 nullptr, false, false); 346 Registry.registerPass(*PI, true); 347} 348 349void llvm::initializeHexagonExpandPredSpillCodePass(PassRegistry &Registry) { 350 CALL_ONCE_INITIALIZATION(initializePassOnce) 351} 352 353FunctionPass* 354llvm::createHexagonExpandPredSpillCode() { 355 return new HexagonExpandPredSpillCode(); 356} 357