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