1 //===------- HexagonCopyToCombine.cpp - Hexagon Copy-To-Combine Pass ------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // This pass replaces transfer instructions by combine instructions. 9 // We walk along a basic block and look for two combinable instructions and try 10 // to move them together. If we can move them next to each other we do so and 11 // replace them with a combine instruction. 12 //===----------------------------------------------------------------------===// 13 14 #include "HexagonInstrInfo.h" 15 #include "HexagonSubtarget.h" 16 #include "llvm/ADT/DenseMap.h" 17 #include "llvm/ADT/DenseSet.h" 18 #include "llvm/CodeGen/MachineBasicBlock.h" 19 #include "llvm/CodeGen/MachineFunction.h" 20 #include "llvm/CodeGen/MachineFunctionPass.h" 21 #include "llvm/CodeGen/MachineInstr.h" 22 #include "llvm/CodeGen/MachineInstrBuilder.h" 23 #include "llvm/CodeGen/Passes.h" 24 #include "llvm/CodeGen/TargetRegisterInfo.h" 25 #include "llvm/Pass.h" 26 #include "llvm/Support/CodeGen.h" 27 #include "llvm/Support/CommandLine.h" 28 #include "llvm/Support/Debug.h" 29 #include "llvm/Support/raw_ostream.h" 30 #include "llvm/Target/TargetMachine.h" 31 32 using namespace llvm; 33 34 #define DEBUG_TYPE "hexagon-copy-combine" 35 36 static cl::opt<bool> 37 IsCombinesDisabled("disable-merge-into-combines", cl::Hidden, 38 39 cl::desc("Disable merging into combines")); 40 static cl::opt<bool> 41 IsConst64Disabled("disable-const64", cl::Hidden, 42 43 cl::desc("Disable generation of const64")); 44 static 45 cl::opt<unsigned> 46 MaxNumOfInstsBetweenNewValueStoreAndTFR("max-num-inst-between-tfr-and-nv-store", 47 cl::Hidden, cl::init(4), 48 cl::desc("Maximum distance between a tfr feeding a store we " 49 "consider the store still to be newifiable")); 50 51 namespace llvm { 52 FunctionPass *createHexagonCopyToCombine(); 53 void initializeHexagonCopyToCombinePass(PassRegistry&); 54 } 55 56 57 namespace { 58 59 class HexagonCopyToCombine : public MachineFunctionPass { 60 const HexagonInstrInfo *TII; 61 const TargetRegisterInfo *TRI; 62 const HexagonSubtarget *ST; 63 bool ShouldCombineAggressively; 64 65 DenseSet<MachineInstr *> PotentiallyNewifiableTFR; 66 SmallVector<MachineInstr *, 8> DbgMItoMove; 67 68 public: 69 static char ID; 70 71 HexagonCopyToCombine() : MachineFunctionPass(ID) {} 72 73 void getAnalysisUsage(AnalysisUsage &AU) const override { 74 MachineFunctionPass::getAnalysisUsage(AU); 75 } 76 77 StringRef getPassName() const override { 78 return "Hexagon Copy-To-Combine Pass"; 79 } 80 81 bool runOnMachineFunction(MachineFunction &Fn) override; 82 83 MachineFunctionProperties getRequiredProperties() const override { 84 return MachineFunctionProperties().set( 85 MachineFunctionProperties::Property::NoVRegs); 86 } 87 88 private: 89 MachineInstr *findPairable(MachineInstr &I1, bool &DoInsertAtI1, 90 bool AllowC64); 91 92 void findPotentialNewifiableTFRs(MachineBasicBlock &); 93 94 void combine(MachineInstr &I1, MachineInstr &I2, 95 MachineBasicBlock::iterator &MI, bool DoInsertAtI1, 96 bool OptForSize); 97 98 bool isSafeToMoveTogether(MachineInstr &I1, MachineInstr &I2, 99 unsigned I1DestReg, unsigned I2DestReg, 100 bool &DoInsertAtI1); 101 102 void emitCombineRR(MachineBasicBlock::iterator &Before, unsigned DestReg, 103 MachineOperand &HiOperand, MachineOperand &LoOperand); 104 105 void emitCombineRI(MachineBasicBlock::iterator &Before, unsigned DestReg, 106 MachineOperand &HiOperand, MachineOperand &LoOperand); 107 108 void emitCombineIR(MachineBasicBlock::iterator &Before, unsigned DestReg, 109 MachineOperand &HiOperand, MachineOperand &LoOperand); 110 111 void emitCombineII(MachineBasicBlock::iterator &Before, unsigned DestReg, 112 MachineOperand &HiOperand, MachineOperand &LoOperand); 113 114 void emitConst64(MachineBasicBlock::iterator &Before, unsigned DestReg, 115 MachineOperand &HiOperand, MachineOperand &LoOperand); 116 }; 117 118 } // End anonymous namespace. 119 120 char HexagonCopyToCombine::ID = 0; 121 122 INITIALIZE_PASS(HexagonCopyToCombine, "hexagon-copy-combine", 123 "Hexagon Copy-To-Combine Pass", false, false) 124 125 static bool isCombinableInstType(MachineInstr &MI, const HexagonInstrInfo *TII, 126 bool ShouldCombineAggressively) { 127 switch (MI.getOpcode()) { 128 case Hexagon::A2_tfr: { 129 // A COPY instruction can be combined if its arguments are IntRegs (32bit). 130 const MachineOperand &Op0 = MI.getOperand(0); 131 const MachineOperand &Op1 = MI.getOperand(1); 132 assert(Op0.isReg() && Op1.isReg()); 133 134 Register DestReg = Op0.getReg(); 135 Register SrcReg = Op1.getReg(); 136 return Hexagon::IntRegsRegClass.contains(DestReg) && 137 Hexagon::IntRegsRegClass.contains(SrcReg); 138 } 139 140 case Hexagon::A2_tfrsi: { 141 // A transfer-immediate can be combined if its argument is a signed 8bit 142 // value. 143 const MachineOperand &Op0 = MI.getOperand(0); 144 const MachineOperand &Op1 = MI.getOperand(1); 145 assert(Op0.isReg()); 146 147 Register DestReg = Op0.getReg(); 148 // Ensure that TargetFlags are MO_NO_FLAG for a global. This is a 149 // workaround for an ABI bug that prevents GOT relocations on combine 150 // instructions 151 if (!Op1.isImm() && Op1.getTargetFlags() != HexagonII::MO_NO_FLAG) 152 return false; 153 154 // Only combine constant extended A2_tfrsi if we are in aggressive mode. 155 bool NotExt = Op1.isImm() && isInt<8>(Op1.getImm()); 156 return Hexagon::IntRegsRegClass.contains(DestReg) && 157 (ShouldCombineAggressively || NotExt); 158 } 159 160 case Hexagon::V6_vassign: 161 return true; 162 163 default: 164 break; 165 } 166 167 return false; 168 } 169 170 template <unsigned N> static bool isGreaterThanNBitTFRI(const MachineInstr &I) { 171 if (I.getOpcode() == Hexagon::TFRI64_V4 || 172 I.getOpcode() == Hexagon::A2_tfrsi) { 173 const MachineOperand &Op = I.getOperand(1); 174 return !Op.isImm() || !isInt<N>(Op.getImm()); 175 } 176 return false; 177 } 178 179 /// areCombinableOperations - Returns true if the two instruction can be merge 180 /// into a combine (ignoring register constraints). 181 static bool areCombinableOperations(const TargetRegisterInfo *TRI, 182 MachineInstr &HighRegInst, 183 MachineInstr &LowRegInst, bool AllowC64) { 184 unsigned HiOpc = HighRegInst.getOpcode(); 185 unsigned LoOpc = LowRegInst.getOpcode(); 186 187 auto verifyOpc = [](unsigned Opc) -> void { 188 switch (Opc) { 189 case Hexagon::A2_tfr: 190 case Hexagon::A2_tfrsi: 191 case Hexagon::V6_vassign: 192 break; 193 default: 194 llvm_unreachable("Unexpected opcode"); 195 } 196 }; 197 verifyOpc(HiOpc); 198 verifyOpc(LoOpc); 199 200 if (HiOpc == Hexagon::V6_vassign || LoOpc == Hexagon::V6_vassign) 201 return HiOpc == LoOpc; 202 203 if (!AllowC64) { 204 // There is no combine of two constant extended values. 205 if (isGreaterThanNBitTFRI<8>(HighRegInst) && 206 isGreaterThanNBitTFRI<6>(LowRegInst)) 207 return false; 208 } 209 210 // There is a combine of two constant extended values into CONST64, 211 // provided both constants are true immediates. 212 if (isGreaterThanNBitTFRI<16>(HighRegInst) && 213 isGreaterThanNBitTFRI<16>(LowRegInst) && !IsConst64Disabled) 214 return (HighRegInst.getOperand(1).isImm() && 215 LowRegInst.getOperand(1).isImm()); 216 217 // There is no combine of two constant extended values, unless handled above 218 // Make both 8-bit size checks to allow both combine (#,##) and combine(##,#) 219 if (isGreaterThanNBitTFRI<8>(HighRegInst) && 220 isGreaterThanNBitTFRI<8>(LowRegInst)) 221 return false; 222 223 return true; 224 } 225 226 static bool isEvenReg(unsigned Reg) { 227 assert(Register::isPhysicalRegister(Reg)); 228 if (Hexagon::IntRegsRegClass.contains(Reg)) 229 return (Reg - Hexagon::R0) % 2 == 0; 230 if (Hexagon::HvxVRRegClass.contains(Reg)) 231 return (Reg - Hexagon::V0) % 2 == 0; 232 llvm_unreachable("Invalid register"); 233 } 234 235 static void removeKillInfo(MachineInstr &MI, unsigned RegNotKilled) { 236 for (MachineOperand &Op : MI.operands()) 237 if (Op.isReg() && Op.getReg() == RegNotKilled && Op.isKill()) 238 Op.setIsKill(false); 239 } 240 241 /// Returns true if it is unsafe to move a copy instruction from \p UseReg to 242 /// \p DestReg over the instruction \p MI. 243 static bool isUnsafeToMoveAcross(MachineInstr &MI, unsigned UseReg, 244 unsigned DestReg, 245 const TargetRegisterInfo *TRI) { 246 return (UseReg && (MI.modifiesRegister(UseReg, TRI))) || 247 MI.modifiesRegister(DestReg, TRI) || MI.readsRegister(DestReg, TRI) || 248 MI.hasUnmodeledSideEffects() || MI.isInlineAsm() || 249 MI.isMetaInstruction(); 250 } 251 252 static Register UseReg(const MachineOperand& MO) { 253 return MO.isReg() ? MO.getReg() : Register(); 254 } 255 256 /// isSafeToMoveTogether - Returns true if it is safe to move I1 next to I2 such 257 /// that the two instructions can be paired in a combine. 258 bool HexagonCopyToCombine::isSafeToMoveTogether(MachineInstr &I1, 259 MachineInstr &I2, 260 unsigned I1DestReg, 261 unsigned I2DestReg, 262 bool &DoInsertAtI1) { 263 Register I2UseReg = UseReg(I2.getOperand(1)); 264 265 // It is not safe to move I1 and I2 into one combine if I2 has a true 266 // dependence on I1. 267 if (I2UseReg && I1.modifiesRegister(I2UseReg, TRI)) 268 return false; 269 270 bool isSafe = true; 271 272 // First try to move I2 towards I1. 273 { 274 // A reverse_iterator instantiated like below starts before I2, and I1 275 // respectively. 276 // Look at instructions I in between I2 and (excluding) I1. 277 MachineBasicBlock::reverse_iterator I = ++I2.getIterator().getReverse(); 278 MachineBasicBlock::reverse_iterator End = I1.getIterator().getReverse(); 279 // At 03 we got better results (dhrystone!) by being more conservative. 280 if (!ShouldCombineAggressively) 281 End = ++I1.getIterator().getReverse(); 282 // If I2 kills its operand and we move I2 over an instruction that also 283 // uses I2's use reg we need to modify that (first) instruction to now kill 284 // this reg. 285 unsigned KilledOperand = 0; 286 if (I2.killsRegister(I2UseReg, /*TRI=*/nullptr)) 287 KilledOperand = I2UseReg; 288 MachineInstr *KillingInstr = nullptr; 289 290 for (; I != End; ++I) { 291 // If the intervening instruction I: 292 // * modifies I2's use reg 293 // * modifies I2's def reg 294 // * reads I2's def reg 295 // * or has unmodelled side effects 296 // we can't move I2 across it. 297 if (I->isDebugInstr()) 298 continue; 299 300 if (isUnsafeToMoveAcross(*I, I2UseReg, I2DestReg, TRI)) { 301 isSafe = false; 302 break; 303 } 304 305 // Update first use of the killed operand. 306 if (!KillingInstr && KilledOperand && 307 I->readsRegister(KilledOperand, TRI)) 308 KillingInstr = &*I; 309 } 310 if (isSafe) { 311 // Update the intermediate instruction to with the kill flag. 312 if (KillingInstr) { 313 bool Added = KillingInstr->addRegisterKilled(KilledOperand, TRI, true); 314 (void)Added; // suppress compiler warning 315 assert(Added && "Must successfully update kill flag"); 316 removeKillInfo(I2, KilledOperand); 317 } 318 DoInsertAtI1 = true; 319 return true; 320 } 321 } 322 323 // Try to move I1 towards I2. 324 { 325 // Look at instructions I in between I1 and (excluding) I2. 326 MachineBasicBlock::iterator I(I1), End(I2); 327 // At O3 we got better results (dhrystone) by being more conservative here. 328 if (!ShouldCombineAggressively) 329 End = std::next(MachineBasicBlock::iterator(I2)); 330 Register I1UseReg = UseReg(I1.getOperand(1)); 331 // Track killed operands. If we move across an instruction that kills our 332 // operand, we need to update the kill information on the moved I1. It kills 333 // the operand now. 334 MachineInstr *KillingInstr = nullptr; 335 unsigned KilledOperand = 0; 336 337 while(++I != End) { 338 MachineInstr &MI = *I; 339 // If the intervening instruction MI: 340 // * modifies I1's use reg 341 // * modifies I1's def reg 342 // * reads I1's def reg 343 // * or has unmodelled side effects 344 // We introduce this special case because llvm has no api to remove a 345 // kill flag for a register (a removeRegisterKilled() analogous to 346 // addRegisterKilled) that handles aliased register correctly. 347 // * or has a killed aliased register use of I1's use reg 348 // %d4 = A2_tfrpi 16 349 // %r6 = A2_tfr %r9 350 // %r8 = KILL %r8, implicit killed %d4 351 // If we want to move R6 = across the KILL instruction we would have 352 // to remove the implicit killed %d4 operand. For now, we are 353 // conservative and disallow the move. 354 // we can't move I1 across it. 355 if (MI.isDebugInstr()) { 356 if (MI.readsRegister(I1DestReg, TRI)) // Move this instruction after I2. 357 DbgMItoMove.push_back(&MI); 358 continue; 359 } 360 361 if (isUnsafeToMoveAcross(MI, I1UseReg, I1DestReg, TRI) || 362 // Check for an aliased register kill. Bail out if we see one. 363 (!MI.killsRegister(I1UseReg, /*TRI=*/nullptr) && 364 MI.killsRegister(I1UseReg, TRI))) 365 return false; 366 367 // Check for an exact kill (registers match). 368 if (I1UseReg && MI.killsRegister(I1UseReg, /*TRI=*/nullptr)) { 369 assert(!KillingInstr && "Should only see one killing instruction"); 370 KilledOperand = I1UseReg; 371 KillingInstr = &MI; 372 } 373 } 374 if (KillingInstr) { 375 removeKillInfo(*KillingInstr, KilledOperand); 376 // Update I1 to set the kill flag. This flag will later be picked up by 377 // the new COMBINE instruction. 378 bool Added = I1.addRegisterKilled(KilledOperand, TRI); 379 (void)Added; // suppress compiler warning 380 assert(Added && "Must successfully update kill flag"); 381 } 382 DoInsertAtI1 = false; 383 } 384 385 return true; 386 } 387 388 /// findPotentialNewifiableTFRs - Finds tranfers that feed stores that could be 389 /// newified. (A use of a 64 bit register define can not be newified) 390 void 391 HexagonCopyToCombine::findPotentialNewifiableTFRs(MachineBasicBlock &BB) { 392 DenseMap<unsigned, MachineInstr *> LastDef; 393 for (MachineInstr &MI : BB) { 394 if (MI.isDebugInstr()) 395 continue; 396 397 // Mark TFRs that feed a potential new value store as such. 398 if (TII->mayBeNewStore(MI)) { 399 // Look for uses of TFR instructions. 400 for (const MachineOperand &Op : MI.operands()) { 401 // Skip over anything except register uses. 402 if (!Op.isReg() || !Op.isUse() || !Op.getReg()) 403 continue; 404 405 // Look for the defining instruction. 406 Register Reg = Op.getReg(); 407 MachineInstr *DefInst = LastDef[Reg]; 408 if (!DefInst) 409 continue; 410 if (!isCombinableInstType(*DefInst, TII, ShouldCombineAggressively)) 411 continue; 412 413 // Only close newifiable stores should influence the decision. 414 // Ignore the debug instructions in between. 415 MachineBasicBlock::iterator It(DefInst); 416 unsigned NumInstsToDef = 0; 417 while (&*It != &MI) { 418 if (!It->isDebugInstr()) 419 ++NumInstsToDef; 420 ++It; 421 } 422 423 if (NumInstsToDef > MaxNumOfInstsBetweenNewValueStoreAndTFR) 424 continue; 425 426 PotentiallyNewifiableTFR.insert(DefInst); 427 } 428 // Skip to next instruction. 429 continue; 430 } 431 432 // Put instructions that last defined integer or double registers into the 433 // map. 434 for (MachineOperand &Op : MI.operands()) { 435 if (Op.isReg()) { 436 if (!Op.isDef() || !Op.getReg()) 437 continue; 438 Register Reg = Op.getReg(); 439 if (Hexagon::DoubleRegsRegClass.contains(Reg)) { 440 for (MCPhysReg SubReg : TRI->subregs(Reg)) 441 LastDef[SubReg] = &MI; 442 } else if (Hexagon::IntRegsRegClass.contains(Reg)) 443 LastDef[Reg] = &MI; 444 } else if (Op.isRegMask()) { 445 for (unsigned Reg : Hexagon::IntRegsRegClass) 446 if (Op.clobbersPhysReg(Reg)) 447 LastDef[Reg] = &MI; 448 } 449 } 450 } 451 } 452 453 bool HexagonCopyToCombine::runOnMachineFunction(MachineFunction &MF) { 454 if (skipFunction(MF.getFunction())) 455 return false; 456 457 if (IsCombinesDisabled) return false; 458 459 bool HasChanged = false; 460 461 // Get target info. 462 ST = &MF.getSubtarget<HexagonSubtarget>(); 463 TRI = ST->getRegisterInfo(); 464 TII = ST->getInstrInfo(); 465 466 const Function &F = MF.getFunction(); 467 bool OptForSize = F.hasFnAttribute(Attribute::OptimizeForSize); 468 469 // Combine aggressively (for code size) 470 ShouldCombineAggressively = 471 MF.getTarget().getOptLevel() <= CodeGenOptLevel::Default; 472 473 // Disable CONST64 for tiny core since it takes a LD resource. 474 if (!OptForSize && ST->isTinyCore()) 475 IsConst64Disabled = true; 476 477 // Traverse basic blocks. 478 for (MachineBasicBlock &MBB : MF) { 479 PotentiallyNewifiableTFR.clear(); 480 findPotentialNewifiableTFRs(MBB); 481 482 // Traverse instructions in basic block. 483 for (MachineBasicBlock::iterator MI = MBB.begin(), End = MBB.end(); 484 MI != End;) { 485 MachineInstr &I1 = *MI++; 486 487 if (I1.isDebugInstr()) 488 continue; 489 490 // Don't combine a TFR whose user could be newified (instructions that 491 // define double registers can not be newified - Programmer's Ref Manual 492 // 5.4.2 New-value stores). 493 if (ShouldCombineAggressively && PotentiallyNewifiableTFR.count(&I1)) 494 continue; 495 496 // Ignore instructions that are not combinable. 497 if (!isCombinableInstType(I1, TII, ShouldCombineAggressively)) 498 continue; 499 500 // Find a second instruction that can be merged into a combine 501 // instruction. In addition, also find all the debug instructions that 502 // need to be moved along with it. 503 bool DoInsertAtI1 = false; 504 DbgMItoMove.clear(); 505 MachineInstr *I2 = findPairable(I1, DoInsertAtI1, OptForSize); 506 if (I2) { 507 HasChanged = true; 508 combine(I1, *I2, MI, DoInsertAtI1, OptForSize); 509 } 510 } 511 } 512 513 return HasChanged; 514 } 515 516 /// findPairable - Returns an instruction that can be merged with \p I1 into a 517 /// COMBINE instruction or 0 if no such instruction can be found. Returns true 518 /// in \p DoInsertAtI1 if the combine must be inserted at instruction \p I1 519 /// false if the combine must be inserted at the returned instruction. 520 MachineInstr *HexagonCopyToCombine::findPairable(MachineInstr &I1, 521 bool &DoInsertAtI1, 522 bool AllowC64) { 523 MachineBasicBlock::iterator I2 = std::next(MachineBasicBlock::iterator(I1)); 524 while (I2 != I1.getParent()->end() && I2->isDebugInstr()) 525 ++I2; 526 527 Register I1DestReg = I1.getOperand(0).getReg(); 528 529 for (MachineBasicBlock::iterator End = I1.getParent()->end(); I2 != End; 530 ++I2) { 531 // Bail out early if we see a second definition of I1DestReg. 532 if (I2->modifiesRegister(I1DestReg, TRI)) 533 break; 534 535 // Ignore non-combinable instructions. 536 if (!isCombinableInstType(*I2, TII, ShouldCombineAggressively)) 537 continue; 538 539 // Don't combine a TFR whose user could be newified. 540 if (ShouldCombineAggressively && PotentiallyNewifiableTFR.count(&*I2)) 541 continue; 542 543 Register I2DestReg = I2->getOperand(0).getReg(); 544 545 // Check that registers are adjacent and that the first destination register 546 // is even. 547 bool IsI1LowReg = (I2DestReg - I1DestReg) == 1; 548 bool IsI2LowReg = (I1DestReg - I2DestReg) == 1; 549 unsigned FirstRegIndex = IsI1LowReg ? I1DestReg : I2DestReg; 550 if ((!IsI1LowReg && !IsI2LowReg) || !isEvenReg(FirstRegIndex)) 551 continue; 552 553 // Check that the two instructions are combinable. 554 // The order matters because in a A2_tfrsi we might can encode a int8 as 555 // the hi reg operand but only a uint6 as the low reg operand. 556 if ((IsI2LowReg && !areCombinableOperations(TRI, I1, *I2, AllowC64)) || 557 (IsI1LowReg && !areCombinableOperations(TRI, *I2, I1, AllowC64))) 558 break; 559 560 if (isSafeToMoveTogether(I1, *I2, I1DestReg, I2DestReg, DoInsertAtI1)) 561 return &*I2; 562 563 // Not safe. Stop searching. 564 break; 565 } 566 return nullptr; 567 } 568 569 void HexagonCopyToCombine::combine(MachineInstr &I1, MachineInstr &I2, 570 MachineBasicBlock::iterator &MI, 571 bool DoInsertAtI1, bool OptForSize) { 572 // We are going to delete I2. If MI points to I2 advance it to the next 573 // instruction. 574 if (MI == I2.getIterator()) 575 ++MI; 576 577 // Figure out whether I1 or I2 goes into the lowreg part. 578 Register I1DestReg = I1.getOperand(0).getReg(); 579 Register I2DestReg = I2.getOperand(0).getReg(); 580 bool IsI1Loreg = (I2DestReg - I1DestReg) == 1; 581 unsigned LoRegDef = IsI1Loreg ? I1DestReg : I2DestReg; 582 unsigned SubLo; 583 584 const TargetRegisterClass *SuperRC = nullptr; 585 if (Hexagon::IntRegsRegClass.contains(LoRegDef)) { 586 SuperRC = &Hexagon::DoubleRegsRegClass; 587 SubLo = Hexagon::isub_lo; 588 } else if (Hexagon::HvxVRRegClass.contains(LoRegDef)) { 589 assert(ST->useHVXOps()); 590 SuperRC = &Hexagon::HvxWRRegClass; 591 SubLo = Hexagon::vsub_lo; 592 } else 593 llvm_unreachable("Unexpected register class"); 594 595 // Get the double word register. 596 unsigned DoubleRegDest = TRI->getMatchingSuperReg(LoRegDef, SubLo, SuperRC); 597 assert(DoubleRegDest != 0 && "Expect a valid register"); 598 599 // Setup source operands. 600 MachineOperand &LoOperand = IsI1Loreg ? I1.getOperand(1) : I2.getOperand(1); 601 MachineOperand &HiOperand = IsI1Loreg ? I2.getOperand(1) : I1.getOperand(1); 602 603 // Figure out which source is a register and which a constant. 604 bool IsHiReg = HiOperand.isReg(); 605 bool IsLoReg = LoOperand.isReg(); 606 607 // There is a combine of two constant extended values into CONST64. 608 bool IsC64 = OptForSize && LoOperand.isImm() && HiOperand.isImm() && 609 isGreaterThanNBitTFRI<16>(I1) && isGreaterThanNBitTFRI<16>(I2); 610 611 MachineBasicBlock::iterator InsertPt(DoInsertAtI1 ? I1 : I2); 612 // Emit combine. 613 if (IsHiReg && IsLoReg) 614 emitCombineRR(InsertPt, DoubleRegDest, HiOperand, LoOperand); 615 else if (IsHiReg) 616 emitCombineRI(InsertPt, DoubleRegDest, HiOperand, LoOperand); 617 else if (IsLoReg) 618 emitCombineIR(InsertPt, DoubleRegDest, HiOperand, LoOperand); 619 else if (IsC64 && !IsConst64Disabled) 620 emitConst64(InsertPt, DoubleRegDest, HiOperand, LoOperand); 621 else 622 emitCombineII(InsertPt, DoubleRegDest, HiOperand, LoOperand); 623 624 // Move debug instructions along with I1 if it's being 625 // moved towards I2. 626 if (!DoInsertAtI1 && DbgMItoMove.size() != 0) { 627 // Insert debug instructions at the new location before I2. 628 MachineBasicBlock *BB = InsertPt->getParent(); 629 for (auto *NewMI : DbgMItoMove) { 630 // If iterator MI is pointing to DEBUG_VAL, make sure 631 // MI now points to next relevant instruction. 632 if (NewMI == MI) 633 ++MI; 634 BB->splice(InsertPt, BB, NewMI); 635 } 636 } 637 638 I1.eraseFromParent(); 639 I2.eraseFromParent(); 640 } 641 642 void HexagonCopyToCombine::emitConst64(MachineBasicBlock::iterator &InsertPt, 643 unsigned DoubleDestReg, 644 MachineOperand &HiOperand, 645 MachineOperand &LoOperand) { 646 LLVM_DEBUG(dbgs() << "Found a CONST64\n"); 647 648 DebugLoc DL = InsertPt->getDebugLoc(); 649 MachineBasicBlock *BB = InsertPt->getParent(); 650 assert(LoOperand.isImm() && HiOperand.isImm() && 651 "Both operands must be immediate"); 652 653 int64_t V = HiOperand.getImm(); 654 V = (V << 32) | (0x0ffffffffLL & LoOperand.getImm()); 655 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::CONST64), DoubleDestReg) 656 .addImm(V); 657 } 658 659 void HexagonCopyToCombine::emitCombineII(MachineBasicBlock::iterator &InsertPt, 660 unsigned DoubleDestReg, 661 MachineOperand &HiOperand, 662 MachineOperand &LoOperand) { 663 DebugLoc DL = InsertPt->getDebugLoc(); 664 MachineBasicBlock *BB = InsertPt->getParent(); 665 666 // Handle globals. 667 if (HiOperand.isGlobal()) { 668 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg) 669 .addGlobalAddress(HiOperand.getGlobal(), HiOperand.getOffset(), 670 HiOperand.getTargetFlags()) 671 .addImm(LoOperand.getImm()); 672 return; 673 } 674 if (LoOperand.isGlobal()) { 675 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg) 676 .addImm(HiOperand.getImm()) 677 .addGlobalAddress(LoOperand.getGlobal(), LoOperand.getOffset(), 678 LoOperand.getTargetFlags()); 679 return; 680 } 681 682 // Handle block addresses. 683 if (HiOperand.isBlockAddress()) { 684 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg) 685 .addBlockAddress(HiOperand.getBlockAddress(), HiOperand.getOffset(), 686 HiOperand.getTargetFlags()) 687 .addImm(LoOperand.getImm()); 688 return; 689 } 690 if (LoOperand.isBlockAddress()) { 691 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg) 692 .addImm(HiOperand.getImm()) 693 .addBlockAddress(LoOperand.getBlockAddress(), LoOperand.getOffset(), 694 LoOperand.getTargetFlags()); 695 return; 696 } 697 698 // Handle jump tables. 699 if (HiOperand.isJTI()) { 700 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg) 701 .addJumpTableIndex(HiOperand.getIndex(), HiOperand.getTargetFlags()) 702 .addImm(LoOperand.getImm()); 703 return; 704 } 705 if (LoOperand.isJTI()) { 706 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg) 707 .addImm(HiOperand.getImm()) 708 .addJumpTableIndex(LoOperand.getIndex(), LoOperand.getTargetFlags()); 709 return; 710 } 711 712 // Handle constant pools. 713 if (HiOperand.isCPI()) { 714 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg) 715 .addConstantPoolIndex(HiOperand.getIndex(), HiOperand.getOffset(), 716 HiOperand.getTargetFlags()) 717 .addImm(LoOperand.getImm()); 718 return; 719 } 720 if (LoOperand.isCPI()) { 721 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg) 722 .addImm(HiOperand.getImm()) 723 .addConstantPoolIndex(LoOperand.getIndex(), LoOperand.getOffset(), 724 LoOperand.getTargetFlags()); 725 return; 726 } 727 728 // First preference should be given to Hexagon::A2_combineii instruction 729 // as it can include U6 (in Hexagon::A4_combineii) as well. 730 // In this instruction, HiOperand is const extended, if required. 731 if (isInt<8>(LoOperand.getImm())) { 732 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg) 733 .addImm(HiOperand.getImm()) 734 .addImm(LoOperand.getImm()); 735 return; 736 } 737 738 // In this instruction, LoOperand is const extended, if required. 739 if (isInt<8>(HiOperand.getImm())) { 740 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg) 741 .addImm(HiOperand.getImm()) 742 .addImm(LoOperand.getImm()); 743 return; 744 } 745 746 // Insert new combine instruction. 747 // DoubleRegDest = combine #HiImm, #LoImm 748 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg) 749 .addImm(HiOperand.getImm()) 750 .addImm(LoOperand.getImm()); 751 } 752 753 void HexagonCopyToCombine::emitCombineIR(MachineBasicBlock::iterator &InsertPt, 754 unsigned DoubleDestReg, 755 MachineOperand &HiOperand, 756 MachineOperand &LoOperand) { 757 Register LoReg = LoOperand.getReg(); 758 unsigned LoRegKillFlag = getKillRegState(LoOperand.isKill()); 759 760 DebugLoc DL = InsertPt->getDebugLoc(); 761 MachineBasicBlock *BB = InsertPt->getParent(); 762 763 // Handle globals. 764 if (HiOperand.isGlobal()) { 765 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineir), DoubleDestReg) 766 .addGlobalAddress(HiOperand.getGlobal(), HiOperand.getOffset(), 767 HiOperand.getTargetFlags()) 768 .addReg(LoReg, LoRegKillFlag); 769 return; 770 } 771 // Handle block addresses. 772 if (HiOperand.isBlockAddress()) { 773 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineir), DoubleDestReg) 774 .addBlockAddress(HiOperand.getBlockAddress(), HiOperand.getOffset(), 775 HiOperand.getTargetFlags()) 776 .addReg(LoReg, LoRegKillFlag); 777 return; 778 } 779 // Handle jump tables. 780 if (HiOperand.isJTI()) { 781 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineir), DoubleDestReg) 782 .addJumpTableIndex(HiOperand.getIndex(), HiOperand.getTargetFlags()) 783 .addReg(LoReg, LoRegKillFlag); 784 return; 785 } 786 // Handle constant pools. 787 if (HiOperand.isCPI()) { 788 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineir), DoubleDestReg) 789 .addConstantPoolIndex(HiOperand.getIndex(), HiOperand.getOffset(), 790 HiOperand.getTargetFlags()) 791 .addReg(LoReg, LoRegKillFlag); 792 return; 793 } 794 // Insert new combine instruction. 795 // DoubleRegDest = combine #HiImm, LoReg 796 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineir), DoubleDestReg) 797 .addImm(HiOperand.getImm()) 798 .addReg(LoReg, LoRegKillFlag); 799 } 800 801 void HexagonCopyToCombine::emitCombineRI(MachineBasicBlock::iterator &InsertPt, 802 unsigned DoubleDestReg, 803 MachineOperand &HiOperand, 804 MachineOperand &LoOperand) { 805 unsigned HiRegKillFlag = getKillRegState(HiOperand.isKill()); 806 Register HiReg = HiOperand.getReg(); 807 808 DebugLoc DL = InsertPt->getDebugLoc(); 809 MachineBasicBlock *BB = InsertPt->getParent(); 810 811 // Handle global. 812 if (LoOperand.isGlobal()) { 813 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineri), DoubleDestReg) 814 .addReg(HiReg, HiRegKillFlag) 815 .addGlobalAddress(LoOperand.getGlobal(), LoOperand.getOffset(), 816 LoOperand.getTargetFlags()); 817 return; 818 } 819 // Handle block addresses. 820 if (LoOperand.isBlockAddress()) { 821 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineri), DoubleDestReg) 822 .addReg(HiReg, HiRegKillFlag) 823 .addBlockAddress(LoOperand.getBlockAddress(), LoOperand.getOffset(), 824 LoOperand.getTargetFlags()); 825 return; 826 } 827 // Handle jump tables. 828 if (LoOperand.isJTI()) { 829 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineri), DoubleDestReg) 830 .addReg(HiOperand.getReg(), HiRegKillFlag) 831 .addJumpTableIndex(LoOperand.getIndex(), LoOperand.getTargetFlags()); 832 return; 833 } 834 // Handle constant pools. 835 if (LoOperand.isCPI()) { 836 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineri), DoubleDestReg) 837 .addReg(HiOperand.getReg(), HiRegKillFlag) 838 .addConstantPoolIndex(LoOperand.getIndex(), LoOperand.getOffset(), 839 LoOperand.getTargetFlags()); 840 return; 841 } 842 843 // Insert new combine instruction. 844 // DoubleRegDest = combine HiReg, #LoImm 845 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineri), DoubleDestReg) 846 .addReg(HiReg, HiRegKillFlag) 847 .addImm(LoOperand.getImm()); 848 } 849 850 void HexagonCopyToCombine::emitCombineRR(MachineBasicBlock::iterator &InsertPt, 851 unsigned DoubleDestReg, 852 MachineOperand &HiOperand, 853 MachineOperand &LoOperand) { 854 unsigned LoRegKillFlag = getKillRegState(LoOperand.isKill()); 855 unsigned HiRegKillFlag = getKillRegState(HiOperand.isKill()); 856 Register LoReg = LoOperand.getReg(); 857 Register HiReg = HiOperand.getReg(); 858 859 DebugLoc DL = InsertPt->getDebugLoc(); 860 MachineBasicBlock *BB = InsertPt->getParent(); 861 862 // Insert new combine instruction. 863 // DoubleRegDest = combine HiReg, LoReg 864 unsigned NewOpc; 865 if (Hexagon::DoubleRegsRegClass.contains(DoubleDestReg)) { 866 NewOpc = Hexagon::A2_combinew; 867 } else if (Hexagon::HvxWRRegClass.contains(DoubleDestReg)) { 868 assert(ST->useHVXOps()); 869 NewOpc = Hexagon::V6_vcombine; 870 } else 871 llvm_unreachable("Unexpected register"); 872 873 BuildMI(*BB, InsertPt, DL, TII->get(NewOpc), DoubleDestReg) 874 .addReg(HiReg, HiRegKillFlag) 875 .addReg(LoReg, LoRegKillFlag); 876 } 877 878 FunctionPass *llvm::createHexagonCopyToCombine() { 879 return new HexagonCopyToCombine(); 880 } 881