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)) 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) && MI.killsRegister(I1UseReg, TRI))) 364 return false; 365 366 // Check for an exact kill (registers match). 367 if (I1UseReg && MI.killsRegister(I1UseReg)) { 368 assert(!KillingInstr && "Should only see one killing instruction"); 369 KilledOperand = I1UseReg; 370 KillingInstr = &MI; 371 } 372 } 373 if (KillingInstr) { 374 removeKillInfo(*KillingInstr, KilledOperand); 375 // Update I1 to set the kill flag. This flag will later be picked up by 376 // the new COMBINE instruction. 377 bool Added = I1.addRegisterKilled(KilledOperand, TRI); 378 (void)Added; // suppress compiler warning 379 assert(Added && "Must successfully update kill flag"); 380 } 381 DoInsertAtI1 = false; 382 } 383 384 return true; 385 } 386 387 /// findPotentialNewifiableTFRs - Finds tranfers that feed stores that could be 388 /// newified. (A use of a 64 bit register define can not be newified) 389 void 390 HexagonCopyToCombine::findPotentialNewifiableTFRs(MachineBasicBlock &BB) { 391 DenseMap<unsigned, MachineInstr *> LastDef; 392 for (MachineInstr &MI : BB) { 393 if (MI.isDebugInstr()) 394 continue; 395 396 // Mark TFRs that feed a potential new value store as such. 397 if (TII->mayBeNewStore(MI)) { 398 // Look for uses of TFR instructions. 399 for (const MachineOperand &Op : MI.operands()) { 400 // Skip over anything except register uses. 401 if (!Op.isReg() || !Op.isUse() || !Op.getReg()) 402 continue; 403 404 // Look for the defining instruction. 405 Register Reg = Op.getReg(); 406 MachineInstr *DefInst = LastDef[Reg]; 407 if (!DefInst) 408 continue; 409 if (!isCombinableInstType(*DefInst, TII, ShouldCombineAggressively)) 410 continue; 411 412 // Only close newifiable stores should influence the decision. 413 // Ignore the debug instructions in between. 414 MachineBasicBlock::iterator It(DefInst); 415 unsigned NumInstsToDef = 0; 416 while (&*It != &MI) { 417 if (!It->isDebugInstr()) 418 ++NumInstsToDef; 419 ++It; 420 } 421 422 if (NumInstsToDef > MaxNumOfInstsBetweenNewValueStoreAndTFR) 423 continue; 424 425 PotentiallyNewifiableTFR.insert(DefInst); 426 } 427 // Skip to next instruction. 428 continue; 429 } 430 431 // Put instructions that last defined integer or double registers into the 432 // map. 433 for (MachineOperand &Op : MI.operands()) { 434 if (Op.isReg()) { 435 if (!Op.isDef() || !Op.getReg()) 436 continue; 437 Register Reg = Op.getReg(); 438 if (Hexagon::DoubleRegsRegClass.contains(Reg)) { 439 for (MCPhysReg SubReg : TRI->subregs(Reg)) 440 LastDef[SubReg] = &MI; 441 } else if (Hexagon::IntRegsRegClass.contains(Reg)) 442 LastDef[Reg] = &MI; 443 } else if (Op.isRegMask()) { 444 for (unsigned Reg : Hexagon::IntRegsRegClass) 445 if (Op.clobbersPhysReg(Reg)) 446 LastDef[Reg] = &MI; 447 } 448 } 449 } 450 } 451 452 bool HexagonCopyToCombine::runOnMachineFunction(MachineFunction &MF) { 453 if (skipFunction(MF.getFunction())) 454 return false; 455 456 if (IsCombinesDisabled) return false; 457 458 bool HasChanged = false; 459 460 // Get target info. 461 ST = &MF.getSubtarget<HexagonSubtarget>(); 462 TRI = ST->getRegisterInfo(); 463 TII = ST->getInstrInfo(); 464 465 const Function &F = MF.getFunction(); 466 bool OptForSize = F.hasFnAttribute(Attribute::OptimizeForSize); 467 468 // Combine aggressively (for code size) 469 ShouldCombineAggressively = 470 MF.getTarget().getOptLevel() <= CodeGenOpt::Default; 471 472 // Disable CONST64 for tiny core since it takes a LD resource. 473 if (!OptForSize && ST->isTinyCore()) 474 IsConst64Disabled = true; 475 476 // Traverse basic blocks. 477 for (MachineBasicBlock &MBB : MF) { 478 PotentiallyNewifiableTFR.clear(); 479 findPotentialNewifiableTFRs(MBB); 480 481 // Traverse instructions in basic block. 482 for (MachineBasicBlock::iterator MI = MBB.begin(), End = MBB.end(); 483 MI != End;) { 484 MachineInstr &I1 = *MI++; 485 486 if (I1.isDebugInstr()) 487 continue; 488 489 // Don't combine a TFR whose user could be newified (instructions that 490 // define double registers can not be newified - Programmer's Ref Manual 491 // 5.4.2 New-value stores). 492 if (ShouldCombineAggressively && PotentiallyNewifiableTFR.count(&I1)) 493 continue; 494 495 // Ignore instructions that are not combinable. 496 if (!isCombinableInstType(I1, TII, ShouldCombineAggressively)) 497 continue; 498 499 // Find a second instruction that can be merged into a combine 500 // instruction. In addition, also find all the debug instructions that 501 // need to be moved along with it. 502 bool DoInsertAtI1 = false; 503 DbgMItoMove.clear(); 504 MachineInstr *I2 = findPairable(I1, DoInsertAtI1, OptForSize); 505 if (I2) { 506 HasChanged = true; 507 combine(I1, *I2, MI, DoInsertAtI1, OptForSize); 508 } 509 } 510 } 511 512 return HasChanged; 513 } 514 515 /// findPairable - Returns an instruction that can be merged with \p I1 into a 516 /// COMBINE instruction or 0 if no such instruction can be found. Returns true 517 /// in \p DoInsertAtI1 if the combine must be inserted at instruction \p I1 518 /// false if the combine must be inserted at the returned instruction. 519 MachineInstr *HexagonCopyToCombine::findPairable(MachineInstr &I1, 520 bool &DoInsertAtI1, 521 bool AllowC64) { 522 MachineBasicBlock::iterator I2 = std::next(MachineBasicBlock::iterator(I1)); 523 while (I2 != I1.getParent()->end() && I2->isDebugInstr()) 524 ++I2; 525 526 Register I1DestReg = I1.getOperand(0).getReg(); 527 528 for (MachineBasicBlock::iterator End = I1.getParent()->end(); I2 != End; 529 ++I2) { 530 // Bail out early if we see a second definition of I1DestReg. 531 if (I2->modifiesRegister(I1DestReg, TRI)) 532 break; 533 534 // Ignore non-combinable instructions. 535 if (!isCombinableInstType(*I2, TII, ShouldCombineAggressively)) 536 continue; 537 538 // Don't combine a TFR whose user could be newified. 539 if (ShouldCombineAggressively && PotentiallyNewifiableTFR.count(&*I2)) 540 continue; 541 542 Register I2DestReg = I2->getOperand(0).getReg(); 543 544 // Check that registers are adjacent and that the first destination register 545 // is even. 546 bool IsI1LowReg = (I2DestReg - I1DestReg) == 1; 547 bool IsI2LowReg = (I1DestReg - I2DestReg) == 1; 548 unsigned FirstRegIndex = IsI1LowReg ? I1DestReg : I2DestReg; 549 if ((!IsI1LowReg && !IsI2LowReg) || !isEvenReg(FirstRegIndex)) 550 continue; 551 552 // Check that the two instructions are combinable. 553 // The order matters because in a A2_tfrsi we might can encode a int8 as 554 // the hi reg operand but only a uint6 as the low reg operand. 555 if ((IsI2LowReg && !areCombinableOperations(TRI, I1, *I2, AllowC64)) || 556 (IsI1LowReg && !areCombinableOperations(TRI, *I2, I1, AllowC64))) 557 break; 558 559 if (isSafeToMoveTogether(I1, *I2, I1DestReg, I2DestReg, DoInsertAtI1)) 560 return &*I2; 561 562 // Not safe. Stop searching. 563 break; 564 } 565 return nullptr; 566 } 567 568 void HexagonCopyToCombine::combine(MachineInstr &I1, MachineInstr &I2, 569 MachineBasicBlock::iterator &MI, 570 bool DoInsertAtI1, bool OptForSize) { 571 // We are going to delete I2. If MI points to I2 advance it to the next 572 // instruction. 573 if (MI == I2.getIterator()) 574 ++MI; 575 576 // Figure out whether I1 or I2 goes into the lowreg part. 577 Register I1DestReg = I1.getOperand(0).getReg(); 578 Register I2DestReg = I2.getOperand(0).getReg(); 579 bool IsI1Loreg = (I2DestReg - I1DestReg) == 1; 580 unsigned LoRegDef = IsI1Loreg ? I1DestReg : I2DestReg; 581 unsigned SubLo; 582 583 const TargetRegisterClass *SuperRC = nullptr; 584 if (Hexagon::IntRegsRegClass.contains(LoRegDef)) { 585 SuperRC = &Hexagon::DoubleRegsRegClass; 586 SubLo = Hexagon::isub_lo; 587 } else if (Hexagon::HvxVRRegClass.contains(LoRegDef)) { 588 assert(ST->useHVXOps()); 589 SuperRC = &Hexagon::HvxWRRegClass; 590 SubLo = Hexagon::vsub_lo; 591 } else 592 llvm_unreachable("Unexpected register class"); 593 594 // Get the double word register. 595 unsigned DoubleRegDest = TRI->getMatchingSuperReg(LoRegDef, SubLo, SuperRC); 596 assert(DoubleRegDest != 0 && "Expect a valid register"); 597 598 // Setup source operands. 599 MachineOperand &LoOperand = IsI1Loreg ? I1.getOperand(1) : I2.getOperand(1); 600 MachineOperand &HiOperand = IsI1Loreg ? I2.getOperand(1) : I1.getOperand(1); 601 602 // Figure out which source is a register and which a constant. 603 bool IsHiReg = HiOperand.isReg(); 604 bool IsLoReg = LoOperand.isReg(); 605 606 // There is a combine of two constant extended values into CONST64. 607 bool IsC64 = OptForSize && LoOperand.isImm() && HiOperand.isImm() && 608 isGreaterThanNBitTFRI<16>(I1) && isGreaterThanNBitTFRI<16>(I2); 609 610 MachineBasicBlock::iterator InsertPt(DoInsertAtI1 ? I1 : I2); 611 // Emit combine. 612 if (IsHiReg && IsLoReg) 613 emitCombineRR(InsertPt, DoubleRegDest, HiOperand, LoOperand); 614 else if (IsHiReg) 615 emitCombineRI(InsertPt, DoubleRegDest, HiOperand, LoOperand); 616 else if (IsLoReg) 617 emitCombineIR(InsertPt, DoubleRegDest, HiOperand, LoOperand); 618 else if (IsC64 && !IsConst64Disabled) 619 emitConst64(InsertPt, DoubleRegDest, HiOperand, LoOperand); 620 else 621 emitCombineII(InsertPt, DoubleRegDest, HiOperand, LoOperand); 622 623 // Move debug instructions along with I1 if it's being 624 // moved towards I2. 625 if (!DoInsertAtI1 && DbgMItoMove.size() != 0) { 626 // Insert debug instructions at the new location before I2. 627 MachineBasicBlock *BB = InsertPt->getParent(); 628 for (auto *NewMI : DbgMItoMove) { 629 // If iterator MI is pointing to DEBUG_VAL, make sure 630 // MI now points to next relevant instruction. 631 if (NewMI == MI) 632 ++MI; 633 BB->splice(InsertPt, BB, NewMI); 634 } 635 } 636 637 I1.eraseFromParent(); 638 I2.eraseFromParent(); 639 } 640 641 void HexagonCopyToCombine::emitConst64(MachineBasicBlock::iterator &InsertPt, 642 unsigned DoubleDestReg, 643 MachineOperand &HiOperand, 644 MachineOperand &LoOperand) { 645 LLVM_DEBUG(dbgs() << "Found a CONST64\n"); 646 647 DebugLoc DL = InsertPt->getDebugLoc(); 648 MachineBasicBlock *BB = InsertPt->getParent(); 649 assert(LoOperand.isImm() && HiOperand.isImm() && 650 "Both operands must be immediate"); 651 652 int64_t V = HiOperand.getImm(); 653 V = (V << 32) | (0x0ffffffffLL & LoOperand.getImm()); 654 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::CONST64), DoubleDestReg) 655 .addImm(V); 656 } 657 658 void HexagonCopyToCombine::emitCombineII(MachineBasicBlock::iterator &InsertPt, 659 unsigned DoubleDestReg, 660 MachineOperand &HiOperand, 661 MachineOperand &LoOperand) { 662 DebugLoc DL = InsertPt->getDebugLoc(); 663 MachineBasicBlock *BB = InsertPt->getParent(); 664 665 // Handle globals. 666 if (HiOperand.isGlobal()) { 667 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg) 668 .addGlobalAddress(HiOperand.getGlobal(), HiOperand.getOffset(), 669 HiOperand.getTargetFlags()) 670 .addImm(LoOperand.getImm()); 671 return; 672 } 673 if (LoOperand.isGlobal()) { 674 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg) 675 .addImm(HiOperand.getImm()) 676 .addGlobalAddress(LoOperand.getGlobal(), LoOperand.getOffset(), 677 LoOperand.getTargetFlags()); 678 return; 679 } 680 681 // Handle block addresses. 682 if (HiOperand.isBlockAddress()) { 683 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg) 684 .addBlockAddress(HiOperand.getBlockAddress(), HiOperand.getOffset(), 685 HiOperand.getTargetFlags()) 686 .addImm(LoOperand.getImm()); 687 return; 688 } 689 if (LoOperand.isBlockAddress()) { 690 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg) 691 .addImm(HiOperand.getImm()) 692 .addBlockAddress(LoOperand.getBlockAddress(), LoOperand.getOffset(), 693 LoOperand.getTargetFlags()); 694 return; 695 } 696 697 // Handle jump tables. 698 if (HiOperand.isJTI()) { 699 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg) 700 .addJumpTableIndex(HiOperand.getIndex(), HiOperand.getTargetFlags()) 701 .addImm(LoOperand.getImm()); 702 return; 703 } 704 if (LoOperand.isJTI()) { 705 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg) 706 .addImm(HiOperand.getImm()) 707 .addJumpTableIndex(LoOperand.getIndex(), LoOperand.getTargetFlags()); 708 return; 709 } 710 711 // Handle constant pools. 712 if (HiOperand.isCPI()) { 713 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg) 714 .addConstantPoolIndex(HiOperand.getIndex(), HiOperand.getOffset(), 715 HiOperand.getTargetFlags()) 716 .addImm(LoOperand.getImm()); 717 return; 718 } 719 if (LoOperand.isCPI()) { 720 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg) 721 .addImm(HiOperand.getImm()) 722 .addConstantPoolIndex(LoOperand.getIndex(), LoOperand.getOffset(), 723 LoOperand.getTargetFlags()); 724 return; 725 } 726 727 // First preference should be given to Hexagon::A2_combineii instruction 728 // as it can include U6 (in Hexagon::A4_combineii) as well. 729 // In this instruction, HiOperand is const extended, if required. 730 if (isInt<8>(LoOperand.getImm())) { 731 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg) 732 .addImm(HiOperand.getImm()) 733 .addImm(LoOperand.getImm()); 734 return; 735 } 736 737 // In this instruction, LoOperand is const extended, if required. 738 if (isInt<8>(HiOperand.getImm())) { 739 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineii), DoubleDestReg) 740 .addImm(HiOperand.getImm()) 741 .addImm(LoOperand.getImm()); 742 return; 743 } 744 745 // Insert new combine instruction. 746 // DoubleRegDest = combine #HiImm, #LoImm 747 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A2_combineii), DoubleDestReg) 748 .addImm(HiOperand.getImm()) 749 .addImm(LoOperand.getImm()); 750 } 751 752 void HexagonCopyToCombine::emitCombineIR(MachineBasicBlock::iterator &InsertPt, 753 unsigned DoubleDestReg, 754 MachineOperand &HiOperand, 755 MachineOperand &LoOperand) { 756 Register LoReg = LoOperand.getReg(); 757 unsigned LoRegKillFlag = getKillRegState(LoOperand.isKill()); 758 759 DebugLoc DL = InsertPt->getDebugLoc(); 760 MachineBasicBlock *BB = InsertPt->getParent(); 761 762 // Handle globals. 763 if (HiOperand.isGlobal()) { 764 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineir), DoubleDestReg) 765 .addGlobalAddress(HiOperand.getGlobal(), HiOperand.getOffset(), 766 HiOperand.getTargetFlags()) 767 .addReg(LoReg, LoRegKillFlag); 768 return; 769 } 770 // Handle block addresses. 771 if (HiOperand.isBlockAddress()) { 772 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineir), DoubleDestReg) 773 .addBlockAddress(HiOperand.getBlockAddress(), HiOperand.getOffset(), 774 HiOperand.getTargetFlags()) 775 .addReg(LoReg, LoRegKillFlag); 776 return; 777 } 778 // Handle jump tables. 779 if (HiOperand.isJTI()) { 780 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineir), DoubleDestReg) 781 .addJumpTableIndex(HiOperand.getIndex(), HiOperand.getTargetFlags()) 782 .addReg(LoReg, LoRegKillFlag); 783 return; 784 } 785 // Handle constant pools. 786 if (HiOperand.isCPI()) { 787 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineir), DoubleDestReg) 788 .addConstantPoolIndex(HiOperand.getIndex(), HiOperand.getOffset(), 789 HiOperand.getTargetFlags()) 790 .addReg(LoReg, LoRegKillFlag); 791 return; 792 } 793 // Insert new combine instruction. 794 // DoubleRegDest = combine #HiImm, LoReg 795 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineir), DoubleDestReg) 796 .addImm(HiOperand.getImm()) 797 .addReg(LoReg, LoRegKillFlag); 798 } 799 800 void HexagonCopyToCombine::emitCombineRI(MachineBasicBlock::iterator &InsertPt, 801 unsigned DoubleDestReg, 802 MachineOperand &HiOperand, 803 MachineOperand &LoOperand) { 804 unsigned HiRegKillFlag = getKillRegState(HiOperand.isKill()); 805 Register HiReg = HiOperand.getReg(); 806 807 DebugLoc DL = InsertPt->getDebugLoc(); 808 MachineBasicBlock *BB = InsertPt->getParent(); 809 810 // Handle global. 811 if (LoOperand.isGlobal()) { 812 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineri), DoubleDestReg) 813 .addReg(HiReg, HiRegKillFlag) 814 .addGlobalAddress(LoOperand.getGlobal(), LoOperand.getOffset(), 815 LoOperand.getTargetFlags()); 816 return; 817 } 818 // Handle block addresses. 819 if (LoOperand.isBlockAddress()) { 820 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineri), DoubleDestReg) 821 .addReg(HiReg, HiRegKillFlag) 822 .addBlockAddress(LoOperand.getBlockAddress(), LoOperand.getOffset(), 823 LoOperand.getTargetFlags()); 824 return; 825 } 826 // Handle jump tables. 827 if (LoOperand.isJTI()) { 828 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineri), DoubleDestReg) 829 .addReg(HiOperand.getReg(), HiRegKillFlag) 830 .addJumpTableIndex(LoOperand.getIndex(), LoOperand.getTargetFlags()); 831 return; 832 } 833 // Handle constant pools. 834 if (LoOperand.isCPI()) { 835 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineri), DoubleDestReg) 836 .addReg(HiOperand.getReg(), HiRegKillFlag) 837 .addConstantPoolIndex(LoOperand.getIndex(), LoOperand.getOffset(), 838 LoOperand.getTargetFlags()); 839 return; 840 } 841 842 // Insert new combine instruction. 843 // DoubleRegDest = combine HiReg, #LoImm 844 BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::A4_combineri), DoubleDestReg) 845 .addReg(HiReg, HiRegKillFlag) 846 .addImm(LoOperand.getImm()); 847 } 848 849 void HexagonCopyToCombine::emitCombineRR(MachineBasicBlock::iterator &InsertPt, 850 unsigned DoubleDestReg, 851 MachineOperand &HiOperand, 852 MachineOperand &LoOperand) { 853 unsigned LoRegKillFlag = getKillRegState(LoOperand.isKill()); 854 unsigned HiRegKillFlag = getKillRegState(HiOperand.isKill()); 855 Register LoReg = LoOperand.getReg(); 856 Register HiReg = HiOperand.getReg(); 857 858 DebugLoc DL = InsertPt->getDebugLoc(); 859 MachineBasicBlock *BB = InsertPt->getParent(); 860 861 // Insert new combine instruction. 862 // DoubleRegDest = combine HiReg, LoReg 863 unsigned NewOpc; 864 if (Hexagon::DoubleRegsRegClass.contains(DoubleDestReg)) { 865 NewOpc = Hexagon::A2_combinew; 866 } else if (Hexagon::HvxWRRegClass.contains(DoubleDestReg)) { 867 assert(ST->useHVXOps()); 868 NewOpc = Hexagon::V6_vcombine; 869 } else 870 llvm_unreachable("Unexpected register"); 871 872 BuildMI(*BB, InsertPt, DL, TII->get(NewOpc), DoubleDestReg) 873 .addReg(HiReg, HiRegKillFlag) 874 .addReg(LoReg, LoRegKillFlag); 875 } 876 877 FunctionPass *llvm::createHexagonCopyToCombine() { 878 return new HexagonCopyToCombine(); 879 } 880