1 //===- AArch64InstrInfo.cpp - AArch64 Instruction Information -------------===// 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 // 10 // This file contains the AArch64 implementation of the TargetInstrInfo class. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "AArch64InstrInfo.h" 15 #include "AArch64MachineFunctionInfo.h" 16 #include "AArch64Subtarget.h" 17 #include "MCTargetDesc/AArch64AddressingModes.h" 18 #include "Utils/AArch64BaseInfo.h" 19 #include "llvm/ADT/ArrayRef.h" 20 #include "llvm/ADT/STLExtras.h" 21 #include "llvm/ADT/SmallVector.h" 22 #include "llvm/CodeGen/LiveRegUnits.h" 23 #include "llvm/CodeGen/MachineBasicBlock.h" 24 #include "llvm/CodeGen/MachineFrameInfo.h" 25 #include "llvm/CodeGen/MachineFunction.h" 26 #include "llvm/CodeGen/MachineInstr.h" 27 #include "llvm/CodeGen/MachineInstrBuilder.h" 28 #include "llvm/CodeGen/MachineMemOperand.h" 29 #include "llvm/CodeGen/MachineOperand.h" 30 #include "llvm/CodeGen/MachineRegisterInfo.h" 31 #include "llvm/CodeGen/MachineModuleInfo.h" 32 #include "llvm/CodeGen/StackMaps.h" 33 #include "llvm/CodeGen/TargetRegisterInfo.h" 34 #include "llvm/CodeGen/TargetSubtargetInfo.h" 35 #include "llvm/IR/DebugLoc.h" 36 #include "llvm/IR/GlobalValue.h" 37 #include "llvm/MC/MCInst.h" 38 #include "llvm/MC/MCInstrDesc.h" 39 #include "llvm/Support/Casting.h" 40 #include "llvm/Support/CodeGen.h" 41 #include "llvm/Support/CommandLine.h" 42 #include "llvm/Support/Compiler.h" 43 #include "llvm/Support/ErrorHandling.h" 44 #include "llvm/Support/MathExtras.h" 45 #include "llvm/Target/TargetMachine.h" 46 #include "llvm/Target/TargetOptions.h" 47 #include <cassert> 48 #include <cstdint> 49 #include <iterator> 50 #include <utility> 51 52 using namespace llvm; 53 54 #define GET_INSTRINFO_CTOR_DTOR 55 #include "AArch64GenInstrInfo.inc" 56 57 static cl::opt<unsigned> TBZDisplacementBits( 58 "aarch64-tbz-offset-bits", cl::Hidden, cl::init(14), 59 cl::desc("Restrict range of TB[N]Z instructions (DEBUG)")); 60 61 static cl::opt<unsigned> CBZDisplacementBits( 62 "aarch64-cbz-offset-bits", cl::Hidden, cl::init(19), 63 cl::desc("Restrict range of CB[N]Z instructions (DEBUG)")); 64 65 static cl::opt<unsigned> 66 BCCDisplacementBits("aarch64-bcc-offset-bits", cl::Hidden, cl::init(19), 67 cl::desc("Restrict range of Bcc instructions (DEBUG)")); 68 69 AArch64InstrInfo::AArch64InstrInfo(const AArch64Subtarget &STI) 70 : AArch64GenInstrInfo(AArch64::ADJCALLSTACKDOWN, AArch64::ADJCALLSTACKUP), 71 RI(STI.getTargetTriple()), Subtarget(STI) {} 72 73 /// GetInstSize - Return the number of bytes of code the specified 74 /// instruction may be. This returns the maximum number of bytes. 75 unsigned AArch64InstrInfo::getInstSizeInBytes(const MachineInstr &MI) const { 76 const MachineBasicBlock &MBB = *MI.getParent(); 77 const MachineFunction *MF = MBB.getParent(); 78 const MCAsmInfo *MAI = MF->getTarget().getMCAsmInfo(); 79 80 if (MI.getOpcode() == AArch64::INLINEASM) 81 return getInlineAsmLength(MI.getOperand(0).getSymbolName(), *MAI); 82 83 // FIXME: We currently only handle pseudoinstructions that don't get expanded 84 // before the assembly printer. 85 unsigned NumBytes = 0; 86 const MCInstrDesc &Desc = MI.getDesc(); 87 switch (Desc.getOpcode()) { 88 default: 89 // Anything not explicitly designated otherwise is a normal 4-byte insn. 90 NumBytes = 4; 91 break; 92 case TargetOpcode::DBG_VALUE: 93 case TargetOpcode::EH_LABEL: 94 case TargetOpcode::IMPLICIT_DEF: 95 case TargetOpcode::KILL: 96 NumBytes = 0; 97 break; 98 case TargetOpcode::STACKMAP: 99 // The upper bound for a stackmap intrinsic is the full length of its shadow 100 NumBytes = StackMapOpers(&MI).getNumPatchBytes(); 101 assert(NumBytes % 4 == 0 && "Invalid number of NOP bytes requested!"); 102 break; 103 case TargetOpcode::PATCHPOINT: 104 // The size of the patchpoint intrinsic is the number of bytes requested 105 NumBytes = PatchPointOpers(&MI).getNumPatchBytes(); 106 assert(NumBytes % 4 == 0 && "Invalid number of NOP bytes requested!"); 107 break; 108 case AArch64::TLSDESC_CALLSEQ: 109 // This gets lowered to an instruction sequence which takes 16 bytes 110 NumBytes = 16; 111 break; 112 } 113 114 return NumBytes; 115 } 116 117 static void parseCondBranch(MachineInstr *LastInst, MachineBasicBlock *&Target, 118 SmallVectorImpl<MachineOperand> &Cond) { 119 // Block ends with fall-through condbranch. 120 switch (LastInst->getOpcode()) { 121 default: 122 llvm_unreachable("Unknown branch instruction?"); 123 case AArch64::Bcc: 124 Target = LastInst->getOperand(1).getMBB(); 125 Cond.push_back(LastInst->getOperand(0)); 126 break; 127 case AArch64::CBZW: 128 case AArch64::CBZX: 129 case AArch64::CBNZW: 130 case AArch64::CBNZX: 131 Target = LastInst->getOperand(1).getMBB(); 132 Cond.push_back(MachineOperand::CreateImm(-1)); 133 Cond.push_back(MachineOperand::CreateImm(LastInst->getOpcode())); 134 Cond.push_back(LastInst->getOperand(0)); 135 break; 136 case AArch64::TBZW: 137 case AArch64::TBZX: 138 case AArch64::TBNZW: 139 case AArch64::TBNZX: 140 Target = LastInst->getOperand(2).getMBB(); 141 Cond.push_back(MachineOperand::CreateImm(-1)); 142 Cond.push_back(MachineOperand::CreateImm(LastInst->getOpcode())); 143 Cond.push_back(LastInst->getOperand(0)); 144 Cond.push_back(LastInst->getOperand(1)); 145 } 146 } 147 148 static unsigned getBranchDisplacementBits(unsigned Opc) { 149 switch (Opc) { 150 default: 151 llvm_unreachable("unexpected opcode!"); 152 case AArch64::B: 153 return 64; 154 case AArch64::TBNZW: 155 case AArch64::TBZW: 156 case AArch64::TBNZX: 157 case AArch64::TBZX: 158 return TBZDisplacementBits; 159 case AArch64::CBNZW: 160 case AArch64::CBZW: 161 case AArch64::CBNZX: 162 case AArch64::CBZX: 163 return CBZDisplacementBits; 164 case AArch64::Bcc: 165 return BCCDisplacementBits; 166 } 167 } 168 169 bool AArch64InstrInfo::isBranchOffsetInRange(unsigned BranchOp, 170 int64_t BrOffset) const { 171 unsigned Bits = getBranchDisplacementBits(BranchOp); 172 assert(Bits >= 3 && "max branch displacement must be enough to jump" 173 "over conditional branch expansion"); 174 return isIntN(Bits, BrOffset / 4); 175 } 176 177 MachineBasicBlock * 178 AArch64InstrInfo::getBranchDestBlock(const MachineInstr &MI) const { 179 switch (MI.getOpcode()) { 180 default: 181 llvm_unreachable("unexpected opcode!"); 182 case AArch64::B: 183 return MI.getOperand(0).getMBB(); 184 case AArch64::TBZW: 185 case AArch64::TBNZW: 186 case AArch64::TBZX: 187 case AArch64::TBNZX: 188 return MI.getOperand(2).getMBB(); 189 case AArch64::CBZW: 190 case AArch64::CBNZW: 191 case AArch64::CBZX: 192 case AArch64::CBNZX: 193 case AArch64::Bcc: 194 return MI.getOperand(1).getMBB(); 195 } 196 } 197 198 // Branch analysis. 199 bool AArch64InstrInfo::analyzeBranch(MachineBasicBlock &MBB, 200 MachineBasicBlock *&TBB, 201 MachineBasicBlock *&FBB, 202 SmallVectorImpl<MachineOperand> &Cond, 203 bool AllowModify) const { 204 // If the block has no terminators, it just falls into the block after it. 205 MachineBasicBlock::iterator I = MBB.getLastNonDebugInstr(); 206 if (I == MBB.end()) 207 return false; 208 209 if (!isUnpredicatedTerminator(*I)) 210 return false; 211 212 // Get the last instruction in the block. 213 MachineInstr *LastInst = &*I; 214 215 // If there is only one terminator instruction, process it. 216 unsigned LastOpc = LastInst->getOpcode(); 217 if (I == MBB.begin() || !isUnpredicatedTerminator(*--I)) { 218 if (isUncondBranchOpcode(LastOpc)) { 219 TBB = LastInst->getOperand(0).getMBB(); 220 return false; 221 } 222 if (isCondBranchOpcode(LastOpc)) { 223 // Block ends with fall-through condbranch. 224 parseCondBranch(LastInst, TBB, Cond); 225 return false; 226 } 227 return true; // Can't handle indirect branch. 228 } 229 230 // Get the instruction before it if it is a terminator. 231 MachineInstr *SecondLastInst = &*I; 232 unsigned SecondLastOpc = SecondLastInst->getOpcode(); 233 234 // If AllowModify is true and the block ends with two or more unconditional 235 // branches, delete all but the first unconditional branch. 236 if (AllowModify && isUncondBranchOpcode(LastOpc)) { 237 while (isUncondBranchOpcode(SecondLastOpc)) { 238 LastInst->eraseFromParent(); 239 LastInst = SecondLastInst; 240 LastOpc = LastInst->getOpcode(); 241 if (I == MBB.begin() || !isUnpredicatedTerminator(*--I)) { 242 // Return now the only terminator is an unconditional branch. 243 TBB = LastInst->getOperand(0).getMBB(); 244 return false; 245 } else { 246 SecondLastInst = &*I; 247 SecondLastOpc = SecondLastInst->getOpcode(); 248 } 249 } 250 } 251 252 // If there are three terminators, we don't know what sort of block this is. 253 if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(*--I)) 254 return true; 255 256 // If the block ends with a B and a Bcc, handle it. 257 if (isCondBranchOpcode(SecondLastOpc) && isUncondBranchOpcode(LastOpc)) { 258 parseCondBranch(SecondLastInst, TBB, Cond); 259 FBB = LastInst->getOperand(0).getMBB(); 260 return false; 261 } 262 263 // If the block ends with two unconditional branches, handle it. The second 264 // one is not executed, so remove it. 265 if (isUncondBranchOpcode(SecondLastOpc) && isUncondBranchOpcode(LastOpc)) { 266 TBB = SecondLastInst->getOperand(0).getMBB(); 267 I = LastInst; 268 if (AllowModify) 269 I->eraseFromParent(); 270 return false; 271 } 272 273 // ...likewise if it ends with an indirect branch followed by an unconditional 274 // branch. 275 if (isIndirectBranchOpcode(SecondLastOpc) && isUncondBranchOpcode(LastOpc)) { 276 I = LastInst; 277 if (AllowModify) 278 I->eraseFromParent(); 279 return true; 280 } 281 282 // Otherwise, can't handle this. 283 return true; 284 } 285 286 bool AArch64InstrInfo::reverseBranchCondition( 287 SmallVectorImpl<MachineOperand> &Cond) const { 288 if (Cond[0].getImm() != -1) { 289 // Regular Bcc 290 AArch64CC::CondCode CC = (AArch64CC::CondCode)(int)Cond[0].getImm(); 291 Cond[0].setImm(AArch64CC::getInvertedCondCode(CC)); 292 } else { 293 // Folded compare-and-branch 294 switch (Cond[1].getImm()) { 295 default: 296 llvm_unreachable("Unknown conditional branch!"); 297 case AArch64::CBZW: 298 Cond[1].setImm(AArch64::CBNZW); 299 break; 300 case AArch64::CBNZW: 301 Cond[1].setImm(AArch64::CBZW); 302 break; 303 case AArch64::CBZX: 304 Cond[1].setImm(AArch64::CBNZX); 305 break; 306 case AArch64::CBNZX: 307 Cond[1].setImm(AArch64::CBZX); 308 break; 309 case AArch64::TBZW: 310 Cond[1].setImm(AArch64::TBNZW); 311 break; 312 case AArch64::TBNZW: 313 Cond[1].setImm(AArch64::TBZW); 314 break; 315 case AArch64::TBZX: 316 Cond[1].setImm(AArch64::TBNZX); 317 break; 318 case AArch64::TBNZX: 319 Cond[1].setImm(AArch64::TBZX); 320 break; 321 } 322 } 323 324 return false; 325 } 326 327 unsigned AArch64InstrInfo::removeBranch(MachineBasicBlock &MBB, 328 int *BytesRemoved) const { 329 MachineBasicBlock::iterator I = MBB.getLastNonDebugInstr(); 330 if (I == MBB.end()) 331 return 0; 332 333 if (!isUncondBranchOpcode(I->getOpcode()) && 334 !isCondBranchOpcode(I->getOpcode())) 335 return 0; 336 337 // Remove the branch. 338 I->eraseFromParent(); 339 340 I = MBB.end(); 341 342 if (I == MBB.begin()) { 343 if (BytesRemoved) 344 *BytesRemoved = 4; 345 return 1; 346 } 347 --I; 348 if (!isCondBranchOpcode(I->getOpcode())) { 349 if (BytesRemoved) 350 *BytesRemoved = 4; 351 return 1; 352 } 353 354 // Remove the branch. 355 I->eraseFromParent(); 356 if (BytesRemoved) 357 *BytesRemoved = 8; 358 359 return 2; 360 } 361 362 void AArch64InstrInfo::instantiateCondBranch( 363 MachineBasicBlock &MBB, const DebugLoc &DL, MachineBasicBlock *TBB, 364 ArrayRef<MachineOperand> Cond) const { 365 if (Cond[0].getImm() != -1) { 366 // Regular Bcc 367 BuildMI(&MBB, DL, get(AArch64::Bcc)).addImm(Cond[0].getImm()).addMBB(TBB); 368 } else { 369 // Folded compare-and-branch 370 // Note that we use addOperand instead of addReg to keep the flags. 371 const MachineInstrBuilder MIB = 372 BuildMI(&MBB, DL, get(Cond[1].getImm())).add(Cond[2]); 373 if (Cond.size() > 3) 374 MIB.addImm(Cond[3].getImm()); 375 MIB.addMBB(TBB); 376 } 377 } 378 379 unsigned AArch64InstrInfo::insertBranch( 380 MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, 381 ArrayRef<MachineOperand> Cond, const DebugLoc &DL, int *BytesAdded) const { 382 // Shouldn't be a fall through. 383 assert(TBB && "insertBranch must not be told to insert a fallthrough"); 384 385 if (!FBB) { 386 if (Cond.empty()) // Unconditional branch? 387 BuildMI(&MBB, DL, get(AArch64::B)).addMBB(TBB); 388 else 389 instantiateCondBranch(MBB, DL, TBB, Cond); 390 391 if (BytesAdded) 392 *BytesAdded = 4; 393 394 return 1; 395 } 396 397 // Two-way conditional branch. 398 instantiateCondBranch(MBB, DL, TBB, Cond); 399 BuildMI(&MBB, DL, get(AArch64::B)).addMBB(FBB); 400 401 if (BytesAdded) 402 *BytesAdded = 8; 403 404 return 2; 405 } 406 407 // Find the original register that VReg is copied from. 408 static unsigned removeCopies(const MachineRegisterInfo &MRI, unsigned VReg) { 409 while (TargetRegisterInfo::isVirtualRegister(VReg)) { 410 const MachineInstr *DefMI = MRI.getVRegDef(VReg); 411 if (!DefMI->isFullCopy()) 412 return VReg; 413 VReg = DefMI->getOperand(1).getReg(); 414 } 415 return VReg; 416 } 417 418 // Determine if VReg is defined by an instruction that can be folded into a 419 // csel instruction. If so, return the folded opcode, and the replacement 420 // register. 421 static unsigned canFoldIntoCSel(const MachineRegisterInfo &MRI, unsigned VReg, 422 unsigned *NewVReg = nullptr) { 423 VReg = removeCopies(MRI, VReg); 424 if (!TargetRegisterInfo::isVirtualRegister(VReg)) 425 return 0; 426 427 bool Is64Bit = AArch64::GPR64allRegClass.hasSubClassEq(MRI.getRegClass(VReg)); 428 const MachineInstr *DefMI = MRI.getVRegDef(VReg); 429 unsigned Opc = 0; 430 unsigned SrcOpNum = 0; 431 switch (DefMI->getOpcode()) { 432 case AArch64::ADDSXri: 433 case AArch64::ADDSWri: 434 // if NZCV is used, do not fold. 435 if (DefMI->findRegisterDefOperandIdx(AArch64::NZCV, true) == -1) 436 return 0; 437 // fall-through to ADDXri and ADDWri. 438 LLVM_FALLTHROUGH; 439 case AArch64::ADDXri: 440 case AArch64::ADDWri: 441 // add x, 1 -> csinc. 442 if (!DefMI->getOperand(2).isImm() || DefMI->getOperand(2).getImm() != 1 || 443 DefMI->getOperand(3).getImm() != 0) 444 return 0; 445 SrcOpNum = 1; 446 Opc = Is64Bit ? AArch64::CSINCXr : AArch64::CSINCWr; 447 break; 448 449 case AArch64::ORNXrr: 450 case AArch64::ORNWrr: { 451 // not x -> csinv, represented as orn dst, xzr, src. 452 unsigned ZReg = removeCopies(MRI, DefMI->getOperand(1).getReg()); 453 if (ZReg != AArch64::XZR && ZReg != AArch64::WZR) 454 return 0; 455 SrcOpNum = 2; 456 Opc = Is64Bit ? AArch64::CSINVXr : AArch64::CSINVWr; 457 break; 458 } 459 460 case AArch64::SUBSXrr: 461 case AArch64::SUBSWrr: 462 // if NZCV is used, do not fold. 463 if (DefMI->findRegisterDefOperandIdx(AArch64::NZCV, true) == -1) 464 return 0; 465 // fall-through to SUBXrr and SUBWrr. 466 LLVM_FALLTHROUGH; 467 case AArch64::SUBXrr: 468 case AArch64::SUBWrr: { 469 // neg x -> csneg, represented as sub dst, xzr, src. 470 unsigned ZReg = removeCopies(MRI, DefMI->getOperand(1).getReg()); 471 if (ZReg != AArch64::XZR && ZReg != AArch64::WZR) 472 return 0; 473 SrcOpNum = 2; 474 Opc = Is64Bit ? AArch64::CSNEGXr : AArch64::CSNEGWr; 475 break; 476 } 477 default: 478 return 0; 479 } 480 assert(Opc && SrcOpNum && "Missing parameters"); 481 482 if (NewVReg) 483 *NewVReg = DefMI->getOperand(SrcOpNum).getReg(); 484 return Opc; 485 } 486 487 bool AArch64InstrInfo::canInsertSelect(const MachineBasicBlock &MBB, 488 ArrayRef<MachineOperand> Cond, 489 unsigned TrueReg, unsigned FalseReg, 490 int &CondCycles, int &TrueCycles, 491 int &FalseCycles) const { 492 // Check register classes. 493 const MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo(); 494 const TargetRegisterClass *RC = 495 RI.getCommonSubClass(MRI.getRegClass(TrueReg), MRI.getRegClass(FalseReg)); 496 if (!RC) 497 return false; 498 499 // Expanding cbz/tbz requires an extra cycle of latency on the condition. 500 unsigned ExtraCondLat = Cond.size() != 1; 501 502 // GPRs are handled by csel. 503 // FIXME: Fold in x+1, -x, and ~x when applicable. 504 if (AArch64::GPR64allRegClass.hasSubClassEq(RC) || 505 AArch64::GPR32allRegClass.hasSubClassEq(RC)) { 506 // Single-cycle csel, csinc, csinv, and csneg. 507 CondCycles = 1 + ExtraCondLat; 508 TrueCycles = FalseCycles = 1; 509 if (canFoldIntoCSel(MRI, TrueReg)) 510 TrueCycles = 0; 511 else if (canFoldIntoCSel(MRI, FalseReg)) 512 FalseCycles = 0; 513 return true; 514 } 515 516 // Scalar floating point is handled by fcsel. 517 // FIXME: Form fabs, fmin, and fmax when applicable. 518 if (AArch64::FPR64RegClass.hasSubClassEq(RC) || 519 AArch64::FPR32RegClass.hasSubClassEq(RC)) { 520 CondCycles = 5 + ExtraCondLat; 521 TrueCycles = FalseCycles = 2; 522 return true; 523 } 524 525 // Can't do vectors. 526 return false; 527 } 528 529 void AArch64InstrInfo::insertSelect(MachineBasicBlock &MBB, 530 MachineBasicBlock::iterator I, 531 const DebugLoc &DL, unsigned DstReg, 532 ArrayRef<MachineOperand> Cond, 533 unsigned TrueReg, unsigned FalseReg) const { 534 MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo(); 535 536 // Parse the condition code, see parseCondBranch() above. 537 AArch64CC::CondCode CC; 538 switch (Cond.size()) { 539 default: 540 llvm_unreachable("Unknown condition opcode in Cond"); 541 case 1: // b.cc 542 CC = AArch64CC::CondCode(Cond[0].getImm()); 543 break; 544 case 3: { // cbz/cbnz 545 // We must insert a compare against 0. 546 bool Is64Bit; 547 switch (Cond[1].getImm()) { 548 default: 549 llvm_unreachable("Unknown branch opcode in Cond"); 550 case AArch64::CBZW: 551 Is64Bit = false; 552 CC = AArch64CC::EQ; 553 break; 554 case AArch64::CBZX: 555 Is64Bit = true; 556 CC = AArch64CC::EQ; 557 break; 558 case AArch64::CBNZW: 559 Is64Bit = false; 560 CC = AArch64CC::NE; 561 break; 562 case AArch64::CBNZX: 563 Is64Bit = true; 564 CC = AArch64CC::NE; 565 break; 566 } 567 unsigned SrcReg = Cond[2].getReg(); 568 if (Is64Bit) { 569 // cmp reg, #0 is actually subs xzr, reg, #0. 570 MRI.constrainRegClass(SrcReg, &AArch64::GPR64spRegClass); 571 BuildMI(MBB, I, DL, get(AArch64::SUBSXri), AArch64::XZR) 572 .addReg(SrcReg) 573 .addImm(0) 574 .addImm(0); 575 } else { 576 MRI.constrainRegClass(SrcReg, &AArch64::GPR32spRegClass); 577 BuildMI(MBB, I, DL, get(AArch64::SUBSWri), AArch64::WZR) 578 .addReg(SrcReg) 579 .addImm(0) 580 .addImm(0); 581 } 582 break; 583 } 584 case 4: { // tbz/tbnz 585 // We must insert a tst instruction. 586 switch (Cond[1].getImm()) { 587 default: 588 llvm_unreachable("Unknown branch opcode in Cond"); 589 case AArch64::TBZW: 590 case AArch64::TBZX: 591 CC = AArch64CC::EQ; 592 break; 593 case AArch64::TBNZW: 594 case AArch64::TBNZX: 595 CC = AArch64CC::NE; 596 break; 597 } 598 // cmp reg, #foo is actually ands xzr, reg, #1<<foo. 599 if (Cond[1].getImm() == AArch64::TBZW || Cond[1].getImm() == AArch64::TBNZW) 600 BuildMI(MBB, I, DL, get(AArch64::ANDSWri), AArch64::WZR) 601 .addReg(Cond[2].getReg()) 602 .addImm( 603 AArch64_AM::encodeLogicalImmediate(1ull << Cond[3].getImm(), 32)); 604 else 605 BuildMI(MBB, I, DL, get(AArch64::ANDSXri), AArch64::XZR) 606 .addReg(Cond[2].getReg()) 607 .addImm( 608 AArch64_AM::encodeLogicalImmediate(1ull << Cond[3].getImm(), 64)); 609 break; 610 } 611 } 612 613 unsigned Opc = 0; 614 const TargetRegisterClass *RC = nullptr; 615 bool TryFold = false; 616 if (MRI.constrainRegClass(DstReg, &AArch64::GPR64RegClass)) { 617 RC = &AArch64::GPR64RegClass; 618 Opc = AArch64::CSELXr; 619 TryFold = true; 620 } else if (MRI.constrainRegClass(DstReg, &AArch64::GPR32RegClass)) { 621 RC = &AArch64::GPR32RegClass; 622 Opc = AArch64::CSELWr; 623 TryFold = true; 624 } else if (MRI.constrainRegClass(DstReg, &AArch64::FPR64RegClass)) { 625 RC = &AArch64::FPR64RegClass; 626 Opc = AArch64::FCSELDrrr; 627 } else if (MRI.constrainRegClass(DstReg, &AArch64::FPR32RegClass)) { 628 RC = &AArch64::FPR32RegClass; 629 Opc = AArch64::FCSELSrrr; 630 } 631 assert(RC && "Unsupported regclass"); 632 633 // Try folding simple instructions into the csel. 634 if (TryFold) { 635 unsigned NewVReg = 0; 636 unsigned FoldedOpc = canFoldIntoCSel(MRI, TrueReg, &NewVReg); 637 if (FoldedOpc) { 638 // The folded opcodes csinc, csinc and csneg apply the operation to 639 // FalseReg, so we need to invert the condition. 640 CC = AArch64CC::getInvertedCondCode(CC); 641 TrueReg = FalseReg; 642 } else 643 FoldedOpc = canFoldIntoCSel(MRI, FalseReg, &NewVReg); 644 645 // Fold the operation. Leave any dead instructions for DCE to clean up. 646 if (FoldedOpc) { 647 FalseReg = NewVReg; 648 Opc = FoldedOpc; 649 // The extends the live range of NewVReg. 650 MRI.clearKillFlags(NewVReg); 651 } 652 } 653 654 // Pull all virtual register into the appropriate class. 655 MRI.constrainRegClass(TrueReg, RC); 656 MRI.constrainRegClass(FalseReg, RC); 657 658 // Insert the csel. 659 BuildMI(MBB, I, DL, get(Opc), DstReg) 660 .addReg(TrueReg) 661 .addReg(FalseReg) 662 .addImm(CC); 663 } 664 665 /// Returns true if a MOVi32imm or MOVi64imm can be expanded to an ORRxx. 666 static bool canBeExpandedToORR(const MachineInstr &MI, unsigned BitSize) { 667 uint64_t Imm = MI.getOperand(1).getImm(); 668 uint64_t UImm = Imm << (64 - BitSize) >> (64 - BitSize); 669 uint64_t Encoding; 670 return AArch64_AM::processLogicalImmediate(UImm, BitSize, Encoding); 671 } 672 673 // FIXME: this implementation should be micro-architecture dependent, so a 674 // micro-architecture target hook should be introduced here in future. 675 bool AArch64InstrInfo::isAsCheapAsAMove(const MachineInstr &MI) const { 676 if (!Subtarget.hasCustomCheapAsMoveHandling()) 677 return MI.isAsCheapAsAMove(); 678 679 if (Subtarget.hasExynosCheapAsMoveHandling()) { 680 if (isExynosResetFast(MI) || isExynosShiftLeftFast(MI)) 681 return true; 682 else 683 return MI.isAsCheapAsAMove(); 684 } 685 686 switch (MI.getOpcode()) { 687 default: 688 return false; 689 690 // add/sub on register without shift 691 case AArch64::ADDWri: 692 case AArch64::ADDXri: 693 case AArch64::SUBWri: 694 case AArch64::SUBXri: 695 return (MI.getOperand(3).getImm() == 0); 696 697 // logical ops on immediate 698 case AArch64::ANDWri: 699 case AArch64::ANDXri: 700 case AArch64::EORWri: 701 case AArch64::EORXri: 702 case AArch64::ORRWri: 703 case AArch64::ORRXri: 704 return true; 705 706 // logical ops on register without shift 707 case AArch64::ANDWrr: 708 case AArch64::ANDXrr: 709 case AArch64::BICWrr: 710 case AArch64::BICXrr: 711 case AArch64::EONWrr: 712 case AArch64::EONXrr: 713 case AArch64::EORWrr: 714 case AArch64::EORXrr: 715 case AArch64::ORNWrr: 716 case AArch64::ORNXrr: 717 case AArch64::ORRWrr: 718 case AArch64::ORRXrr: 719 return true; 720 721 // If MOVi32imm or MOVi64imm can be expanded into ORRWri or 722 // ORRXri, it is as cheap as MOV 723 case AArch64::MOVi32imm: 724 return canBeExpandedToORR(MI, 32); 725 case AArch64::MOVi64imm: 726 return canBeExpandedToORR(MI, 64); 727 728 // It is cheap to zero out registers if the subtarget has ZeroCycleZeroing 729 // feature. 730 case AArch64::FMOVH0: 731 case AArch64::FMOVS0: 732 case AArch64::FMOVD0: 733 return Subtarget.hasZeroCycleZeroing(); 734 case TargetOpcode::COPY: 735 return (Subtarget.hasZeroCycleZeroing() && 736 (MI.getOperand(1).getReg() == AArch64::WZR || 737 MI.getOperand(1).getReg() == AArch64::XZR)); 738 } 739 740 llvm_unreachable("Unknown opcode to check as cheap as a move!"); 741 } 742 743 bool AArch64InstrInfo::isExynosResetFast(const MachineInstr &MI) const { 744 switch (MI.getOpcode()) { 745 default: 746 return false; 747 748 case AArch64::ADR: 749 case AArch64::ADRP: 750 751 case AArch64::MOVNWi: 752 case AArch64::MOVNXi: 753 case AArch64::MOVZWi: 754 case AArch64::MOVZXi: 755 return true; 756 757 case AArch64::MOVID: 758 case AArch64::MOVIv2d_ns: 759 case AArch64::MOVIv8b_ns: 760 case AArch64::MOVIv16b_ns: 761 return (MI.getOperand(1).getImm() == 0); 762 763 case AArch64::MOVIv2i32: 764 case AArch64::MOVIv4i32: 765 case AArch64::MOVIv4i16: 766 case AArch64::MOVIv8i16: 767 return (MI.getOperand(1).getImm() == 0 && 768 MI.getOperand(2).getImm() == 0); 769 } 770 } 771 772 bool AArch64InstrInfo::isExynosShiftLeftFast(const MachineInstr &MI) const { 773 unsigned Imm, Shift; 774 AArch64_AM::ShiftExtendType Ext; 775 776 switch (MI.getOpcode()) { 777 default: 778 return false; 779 780 // WriteI 781 case AArch64::ADDSWri: 782 case AArch64::ADDSXri: 783 case AArch64::ADDWri: 784 case AArch64::ADDXri: 785 case AArch64::SUBSWri: 786 case AArch64::SUBSXri: 787 case AArch64::SUBWri: 788 case AArch64::SUBXri: 789 return true; 790 791 // WriteISReg 792 case AArch64::ADDSWrs: 793 case AArch64::ADDSXrs: 794 case AArch64::ADDWrs: 795 case AArch64::ADDXrs: 796 case AArch64::ANDSWrs: 797 case AArch64::ANDSXrs: 798 case AArch64::ANDWrs: 799 case AArch64::ANDXrs: 800 case AArch64::BICSWrs: 801 case AArch64::BICSXrs: 802 case AArch64::BICWrs: 803 case AArch64::BICXrs: 804 case AArch64::EONWrs: 805 case AArch64::EONXrs: 806 case AArch64::EORWrs: 807 case AArch64::EORXrs: 808 case AArch64::ORNWrs: 809 case AArch64::ORNXrs: 810 case AArch64::ORRWrs: 811 case AArch64::ORRXrs: 812 case AArch64::SUBSWrs: 813 case AArch64::SUBSXrs: 814 case AArch64::SUBWrs: 815 case AArch64::SUBXrs: 816 Imm = MI.getOperand(3).getImm(); 817 Shift = AArch64_AM::getShiftValue(Imm); 818 Ext = AArch64_AM::getShiftType(Imm); 819 return (Shift == 0 || (Shift <= 3 && Ext == AArch64_AM::LSL)); 820 821 // WriteIEReg 822 case AArch64::ADDSWrx: 823 case AArch64::ADDSXrx: 824 case AArch64::ADDSXrx64: 825 case AArch64::ADDWrx: 826 case AArch64::ADDXrx: 827 case AArch64::ADDXrx64: 828 case AArch64::SUBSWrx: 829 case AArch64::SUBSXrx: 830 case AArch64::SUBSXrx64: 831 case AArch64::SUBWrx: 832 case AArch64::SUBXrx: 833 case AArch64::SUBXrx64: 834 Imm = MI.getOperand(3).getImm(); 835 Shift = AArch64_AM::getArithShiftValue(Imm); 836 Ext = AArch64_AM::getArithExtendType(Imm); 837 return (Shift == 0 || (Shift <= 3 && Ext == AArch64_AM::UXTX)); 838 839 case AArch64::PRFMroW: 840 case AArch64::PRFMroX: 841 842 // WriteLDIdx 843 case AArch64::LDRBBroW: 844 case AArch64::LDRBBroX: 845 case AArch64::LDRHHroW: 846 case AArch64::LDRHHroX: 847 case AArch64::LDRSBWroW: 848 case AArch64::LDRSBWroX: 849 case AArch64::LDRSBXroW: 850 case AArch64::LDRSBXroX: 851 case AArch64::LDRSHWroW: 852 case AArch64::LDRSHWroX: 853 case AArch64::LDRSHXroW: 854 case AArch64::LDRSHXroX: 855 case AArch64::LDRSWroW: 856 case AArch64::LDRSWroX: 857 case AArch64::LDRWroW: 858 case AArch64::LDRWroX: 859 case AArch64::LDRXroW: 860 case AArch64::LDRXroX: 861 862 case AArch64::LDRBroW: 863 case AArch64::LDRBroX: 864 case AArch64::LDRDroW: 865 case AArch64::LDRDroX: 866 case AArch64::LDRHroW: 867 case AArch64::LDRHroX: 868 case AArch64::LDRSroW: 869 case AArch64::LDRSroX: 870 871 // WriteSTIdx 872 case AArch64::STRBBroW: 873 case AArch64::STRBBroX: 874 case AArch64::STRHHroW: 875 case AArch64::STRHHroX: 876 case AArch64::STRWroW: 877 case AArch64::STRWroX: 878 case AArch64::STRXroW: 879 case AArch64::STRXroX: 880 881 case AArch64::STRBroW: 882 case AArch64::STRBroX: 883 case AArch64::STRDroW: 884 case AArch64::STRDroX: 885 case AArch64::STRHroW: 886 case AArch64::STRHroX: 887 case AArch64::STRSroW: 888 case AArch64::STRSroX: 889 Imm = MI.getOperand(3).getImm(); 890 Ext = AArch64_AM::getMemExtendType(Imm); 891 return (Ext == AArch64_AM::SXTX || Ext == AArch64_AM::UXTX); 892 } 893 } 894 895 bool AArch64InstrInfo::isFalkorShiftExtFast(const MachineInstr &MI) const { 896 switch (MI.getOpcode()) { 897 default: 898 return false; 899 900 case AArch64::ADDWrs: 901 case AArch64::ADDXrs: 902 case AArch64::ADDSWrs: 903 case AArch64::ADDSXrs: { 904 unsigned Imm = MI.getOperand(3).getImm(); 905 unsigned ShiftVal = AArch64_AM::getShiftValue(Imm); 906 if (ShiftVal == 0) 907 return true; 908 return AArch64_AM::getShiftType(Imm) == AArch64_AM::LSL && ShiftVal <= 5; 909 } 910 911 case AArch64::ADDWrx: 912 case AArch64::ADDXrx: 913 case AArch64::ADDXrx64: 914 case AArch64::ADDSWrx: 915 case AArch64::ADDSXrx: 916 case AArch64::ADDSXrx64: { 917 unsigned Imm = MI.getOperand(3).getImm(); 918 switch (AArch64_AM::getArithExtendType(Imm)) { 919 default: 920 return false; 921 case AArch64_AM::UXTB: 922 case AArch64_AM::UXTH: 923 case AArch64_AM::UXTW: 924 case AArch64_AM::UXTX: 925 return AArch64_AM::getArithShiftValue(Imm) <= 4; 926 } 927 } 928 929 case AArch64::SUBWrs: 930 case AArch64::SUBSWrs: { 931 unsigned Imm = MI.getOperand(3).getImm(); 932 unsigned ShiftVal = AArch64_AM::getShiftValue(Imm); 933 return ShiftVal == 0 || 934 (AArch64_AM::getShiftType(Imm) == AArch64_AM::ASR && ShiftVal == 31); 935 } 936 937 case AArch64::SUBXrs: 938 case AArch64::SUBSXrs: { 939 unsigned Imm = MI.getOperand(3).getImm(); 940 unsigned ShiftVal = AArch64_AM::getShiftValue(Imm); 941 return ShiftVal == 0 || 942 (AArch64_AM::getShiftType(Imm) == AArch64_AM::ASR && ShiftVal == 63); 943 } 944 945 case AArch64::SUBWrx: 946 case AArch64::SUBXrx: 947 case AArch64::SUBXrx64: 948 case AArch64::SUBSWrx: 949 case AArch64::SUBSXrx: 950 case AArch64::SUBSXrx64: { 951 unsigned Imm = MI.getOperand(3).getImm(); 952 switch (AArch64_AM::getArithExtendType(Imm)) { 953 default: 954 return false; 955 case AArch64_AM::UXTB: 956 case AArch64_AM::UXTH: 957 case AArch64_AM::UXTW: 958 case AArch64_AM::UXTX: 959 return AArch64_AM::getArithShiftValue(Imm) == 0; 960 } 961 } 962 963 case AArch64::LDRBBroW: 964 case AArch64::LDRBBroX: 965 case AArch64::LDRBroW: 966 case AArch64::LDRBroX: 967 case AArch64::LDRDroW: 968 case AArch64::LDRDroX: 969 case AArch64::LDRHHroW: 970 case AArch64::LDRHHroX: 971 case AArch64::LDRHroW: 972 case AArch64::LDRHroX: 973 case AArch64::LDRQroW: 974 case AArch64::LDRQroX: 975 case AArch64::LDRSBWroW: 976 case AArch64::LDRSBWroX: 977 case AArch64::LDRSBXroW: 978 case AArch64::LDRSBXroX: 979 case AArch64::LDRSHWroW: 980 case AArch64::LDRSHWroX: 981 case AArch64::LDRSHXroW: 982 case AArch64::LDRSHXroX: 983 case AArch64::LDRSWroW: 984 case AArch64::LDRSWroX: 985 case AArch64::LDRSroW: 986 case AArch64::LDRSroX: 987 case AArch64::LDRWroW: 988 case AArch64::LDRWroX: 989 case AArch64::LDRXroW: 990 case AArch64::LDRXroX: 991 case AArch64::PRFMroW: 992 case AArch64::PRFMroX: 993 case AArch64::STRBBroW: 994 case AArch64::STRBBroX: 995 case AArch64::STRBroW: 996 case AArch64::STRBroX: 997 case AArch64::STRDroW: 998 case AArch64::STRDroX: 999 case AArch64::STRHHroW: 1000 case AArch64::STRHHroX: 1001 case AArch64::STRHroW: 1002 case AArch64::STRHroX: 1003 case AArch64::STRQroW: 1004 case AArch64::STRQroX: 1005 case AArch64::STRSroW: 1006 case AArch64::STRSroX: 1007 case AArch64::STRWroW: 1008 case AArch64::STRWroX: 1009 case AArch64::STRXroW: 1010 case AArch64::STRXroX: { 1011 unsigned IsSigned = MI.getOperand(3).getImm(); 1012 return !IsSigned; 1013 } 1014 } 1015 } 1016 1017 bool AArch64InstrInfo::isCoalescableExtInstr(const MachineInstr &MI, 1018 unsigned &SrcReg, unsigned &DstReg, 1019 unsigned &SubIdx) const { 1020 switch (MI.getOpcode()) { 1021 default: 1022 return false; 1023 case AArch64::SBFMXri: // aka sxtw 1024 case AArch64::UBFMXri: // aka uxtw 1025 // Check for the 32 -> 64 bit extension case, these instructions can do 1026 // much more. 1027 if (MI.getOperand(2).getImm() != 0 || MI.getOperand(3).getImm() != 31) 1028 return false; 1029 // This is a signed or unsigned 32 -> 64 bit extension. 1030 SrcReg = MI.getOperand(1).getReg(); 1031 DstReg = MI.getOperand(0).getReg(); 1032 SubIdx = AArch64::sub_32; 1033 return true; 1034 } 1035 } 1036 1037 bool AArch64InstrInfo::areMemAccessesTriviallyDisjoint( 1038 MachineInstr &MIa, MachineInstr &MIb, AliasAnalysis *AA) const { 1039 const TargetRegisterInfo *TRI = &getRegisterInfo(); 1040 unsigned BaseRegA = 0, BaseRegB = 0; 1041 int64_t OffsetA = 0, OffsetB = 0; 1042 unsigned WidthA = 0, WidthB = 0; 1043 1044 assert(MIa.mayLoadOrStore() && "MIa must be a load or store."); 1045 assert(MIb.mayLoadOrStore() && "MIb must be a load or store."); 1046 1047 if (MIa.hasUnmodeledSideEffects() || MIb.hasUnmodeledSideEffects() || 1048 MIa.hasOrderedMemoryRef() || MIb.hasOrderedMemoryRef()) 1049 return false; 1050 1051 // Retrieve the base register, offset from the base register and width. Width 1052 // is the size of memory that is being loaded/stored (e.g. 1, 2, 4, 8). If 1053 // base registers are identical, and the offset of a lower memory access + 1054 // the width doesn't overlap the offset of a higher memory access, 1055 // then the memory accesses are different. 1056 if (getMemOpBaseRegImmOfsWidth(MIa, BaseRegA, OffsetA, WidthA, TRI) && 1057 getMemOpBaseRegImmOfsWidth(MIb, BaseRegB, OffsetB, WidthB, TRI)) { 1058 if (BaseRegA == BaseRegB) { 1059 int LowOffset = OffsetA < OffsetB ? OffsetA : OffsetB; 1060 int HighOffset = OffsetA < OffsetB ? OffsetB : OffsetA; 1061 int LowWidth = (LowOffset == OffsetA) ? WidthA : WidthB; 1062 if (LowOffset + LowWidth <= HighOffset) 1063 return true; 1064 } 1065 } 1066 return false; 1067 } 1068 1069 /// analyzeCompare - For a comparison instruction, return the source registers 1070 /// in SrcReg and SrcReg2, and the value it compares against in CmpValue. 1071 /// Return true if the comparison instruction can be analyzed. 1072 bool AArch64InstrInfo::analyzeCompare(const MachineInstr &MI, unsigned &SrcReg, 1073 unsigned &SrcReg2, int &CmpMask, 1074 int &CmpValue) const { 1075 // The first operand can be a frame index where we'd normally expect a 1076 // register. 1077 assert(MI.getNumOperands() >= 2 && "All AArch64 cmps should have 2 operands"); 1078 if (!MI.getOperand(1).isReg()) 1079 return false; 1080 1081 switch (MI.getOpcode()) { 1082 default: 1083 break; 1084 case AArch64::SUBSWrr: 1085 case AArch64::SUBSWrs: 1086 case AArch64::SUBSWrx: 1087 case AArch64::SUBSXrr: 1088 case AArch64::SUBSXrs: 1089 case AArch64::SUBSXrx: 1090 case AArch64::ADDSWrr: 1091 case AArch64::ADDSWrs: 1092 case AArch64::ADDSWrx: 1093 case AArch64::ADDSXrr: 1094 case AArch64::ADDSXrs: 1095 case AArch64::ADDSXrx: 1096 // Replace SUBSWrr with SUBWrr if NZCV is not used. 1097 SrcReg = MI.getOperand(1).getReg(); 1098 SrcReg2 = MI.getOperand(2).getReg(); 1099 CmpMask = ~0; 1100 CmpValue = 0; 1101 return true; 1102 case AArch64::SUBSWri: 1103 case AArch64::ADDSWri: 1104 case AArch64::SUBSXri: 1105 case AArch64::ADDSXri: 1106 SrcReg = MI.getOperand(1).getReg(); 1107 SrcReg2 = 0; 1108 CmpMask = ~0; 1109 // FIXME: In order to convert CmpValue to 0 or 1 1110 CmpValue = MI.getOperand(2).getImm() != 0; 1111 return true; 1112 case AArch64::ANDSWri: 1113 case AArch64::ANDSXri: 1114 // ANDS does not use the same encoding scheme as the others xxxS 1115 // instructions. 1116 SrcReg = MI.getOperand(1).getReg(); 1117 SrcReg2 = 0; 1118 CmpMask = ~0; 1119 // FIXME:The return val type of decodeLogicalImmediate is uint64_t, 1120 // while the type of CmpValue is int. When converting uint64_t to int, 1121 // the high 32 bits of uint64_t will be lost. 1122 // In fact it causes a bug in spec2006-483.xalancbmk 1123 // CmpValue is only used to compare with zero in OptimizeCompareInstr 1124 CmpValue = AArch64_AM::decodeLogicalImmediate( 1125 MI.getOperand(2).getImm(), 1126 MI.getOpcode() == AArch64::ANDSWri ? 32 : 64) != 0; 1127 return true; 1128 } 1129 1130 return false; 1131 } 1132 1133 static bool UpdateOperandRegClass(MachineInstr &Instr) { 1134 MachineBasicBlock *MBB = Instr.getParent(); 1135 assert(MBB && "Can't get MachineBasicBlock here"); 1136 MachineFunction *MF = MBB->getParent(); 1137 assert(MF && "Can't get MachineFunction here"); 1138 const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo(); 1139 const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo(); 1140 MachineRegisterInfo *MRI = &MF->getRegInfo(); 1141 1142 for (unsigned OpIdx = 0, EndIdx = Instr.getNumOperands(); OpIdx < EndIdx; 1143 ++OpIdx) { 1144 MachineOperand &MO = Instr.getOperand(OpIdx); 1145 const TargetRegisterClass *OpRegCstraints = 1146 Instr.getRegClassConstraint(OpIdx, TII, TRI); 1147 1148 // If there's no constraint, there's nothing to do. 1149 if (!OpRegCstraints) 1150 continue; 1151 // If the operand is a frame index, there's nothing to do here. 1152 // A frame index operand will resolve correctly during PEI. 1153 if (MO.isFI()) 1154 continue; 1155 1156 assert(MO.isReg() && 1157 "Operand has register constraints without being a register!"); 1158 1159 unsigned Reg = MO.getReg(); 1160 if (TargetRegisterInfo::isPhysicalRegister(Reg)) { 1161 if (!OpRegCstraints->contains(Reg)) 1162 return false; 1163 } else if (!OpRegCstraints->hasSubClassEq(MRI->getRegClass(Reg)) && 1164 !MRI->constrainRegClass(Reg, OpRegCstraints)) 1165 return false; 1166 } 1167 1168 return true; 1169 } 1170 1171 /// \brief Return the opcode that does not set flags when possible - otherwise 1172 /// return the original opcode. The caller is responsible to do the actual 1173 /// substitution and legality checking. 1174 static unsigned convertToNonFlagSettingOpc(const MachineInstr &MI) { 1175 // Don't convert all compare instructions, because for some the zero register 1176 // encoding becomes the sp register. 1177 bool MIDefinesZeroReg = false; 1178 if (MI.definesRegister(AArch64::WZR) || MI.definesRegister(AArch64::XZR)) 1179 MIDefinesZeroReg = true; 1180 1181 switch (MI.getOpcode()) { 1182 default: 1183 return MI.getOpcode(); 1184 case AArch64::ADDSWrr: 1185 return AArch64::ADDWrr; 1186 case AArch64::ADDSWri: 1187 return MIDefinesZeroReg ? AArch64::ADDSWri : AArch64::ADDWri; 1188 case AArch64::ADDSWrs: 1189 return MIDefinesZeroReg ? AArch64::ADDSWrs : AArch64::ADDWrs; 1190 case AArch64::ADDSWrx: 1191 return AArch64::ADDWrx; 1192 case AArch64::ADDSXrr: 1193 return AArch64::ADDXrr; 1194 case AArch64::ADDSXri: 1195 return MIDefinesZeroReg ? AArch64::ADDSXri : AArch64::ADDXri; 1196 case AArch64::ADDSXrs: 1197 return MIDefinesZeroReg ? AArch64::ADDSXrs : AArch64::ADDXrs; 1198 case AArch64::ADDSXrx: 1199 return AArch64::ADDXrx; 1200 case AArch64::SUBSWrr: 1201 return AArch64::SUBWrr; 1202 case AArch64::SUBSWri: 1203 return MIDefinesZeroReg ? AArch64::SUBSWri : AArch64::SUBWri; 1204 case AArch64::SUBSWrs: 1205 return MIDefinesZeroReg ? AArch64::SUBSWrs : AArch64::SUBWrs; 1206 case AArch64::SUBSWrx: 1207 return AArch64::SUBWrx; 1208 case AArch64::SUBSXrr: 1209 return AArch64::SUBXrr; 1210 case AArch64::SUBSXri: 1211 return MIDefinesZeroReg ? AArch64::SUBSXri : AArch64::SUBXri; 1212 case AArch64::SUBSXrs: 1213 return MIDefinesZeroReg ? AArch64::SUBSXrs : AArch64::SUBXrs; 1214 case AArch64::SUBSXrx: 1215 return AArch64::SUBXrx; 1216 } 1217 } 1218 1219 enum AccessKind { AK_Write = 0x01, AK_Read = 0x10, AK_All = 0x11 }; 1220 1221 /// True when condition flags are accessed (either by writing or reading) 1222 /// on the instruction trace starting at From and ending at To. 1223 /// 1224 /// Note: If From and To are from different blocks it's assumed CC are accessed 1225 /// on the path. 1226 static bool areCFlagsAccessedBetweenInstrs( 1227 MachineBasicBlock::iterator From, MachineBasicBlock::iterator To, 1228 const TargetRegisterInfo *TRI, const AccessKind AccessToCheck = AK_All) { 1229 // Early exit if To is at the beginning of the BB. 1230 if (To == To->getParent()->begin()) 1231 return true; 1232 1233 // Check whether the instructions are in the same basic block 1234 // If not, assume the condition flags might get modified somewhere. 1235 if (To->getParent() != From->getParent()) 1236 return true; 1237 1238 // From must be above To. 1239 assert(std::find_if(++To.getReverse(), To->getParent()->rend(), 1240 [From](MachineInstr &MI) { 1241 return MI.getIterator() == From; 1242 }) != To->getParent()->rend()); 1243 1244 // We iterate backward starting \p To until we hit \p From. 1245 for (--To; To != From; --To) { 1246 const MachineInstr &Instr = *To; 1247 1248 if (((AccessToCheck & AK_Write) && 1249 Instr.modifiesRegister(AArch64::NZCV, TRI)) || 1250 ((AccessToCheck & AK_Read) && Instr.readsRegister(AArch64::NZCV, TRI))) 1251 return true; 1252 } 1253 return false; 1254 } 1255 1256 /// Try to optimize a compare instruction. A compare instruction is an 1257 /// instruction which produces AArch64::NZCV. It can be truly compare 1258 /// instruction 1259 /// when there are no uses of its destination register. 1260 /// 1261 /// The following steps are tried in order: 1262 /// 1. Convert CmpInstr into an unconditional version. 1263 /// 2. Remove CmpInstr if above there is an instruction producing a needed 1264 /// condition code or an instruction which can be converted into such an 1265 /// instruction. 1266 /// Only comparison with zero is supported. 1267 bool AArch64InstrInfo::optimizeCompareInstr( 1268 MachineInstr &CmpInstr, unsigned SrcReg, unsigned SrcReg2, int CmpMask, 1269 int CmpValue, const MachineRegisterInfo *MRI) const { 1270 assert(CmpInstr.getParent()); 1271 assert(MRI); 1272 1273 // Replace SUBSWrr with SUBWrr if NZCV is not used. 1274 int DeadNZCVIdx = CmpInstr.findRegisterDefOperandIdx(AArch64::NZCV, true); 1275 if (DeadNZCVIdx != -1) { 1276 if (CmpInstr.definesRegister(AArch64::WZR) || 1277 CmpInstr.definesRegister(AArch64::XZR)) { 1278 CmpInstr.eraseFromParent(); 1279 return true; 1280 } 1281 unsigned Opc = CmpInstr.getOpcode(); 1282 unsigned NewOpc = convertToNonFlagSettingOpc(CmpInstr); 1283 if (NewOpc == Opc) 1284 return false; 1285 const MCInstrDesc &MCID = get(NewOpc); 1286 CmpInstr.setDesc(MCID); 1287 CmpInstr.RemoveOperand(DeadNZCVIdx); 1288 bool succeeded = UpdateOperandRegClass(CmpInstr); 1289 (void)succeeded; 1290 assert(succeeded && "Some operands reg class are incompatible!"); 1291 return true; 1292 } 1293 1294 // Continue only if we have a "ri" where immediate is zero. 1295 // FIXME:CmpValue has already been converted to 0 or 1 in analyzeCompare 1296 // function. 1297 assert((CmpValue == 0 || CmpValue == 1) && "CmpValue must be 0 or 1!"); 1298 if (CmpValue != 0 || SrcReg2 != 0) 1299 return false; 1300 1301 // CmpInstr is a Compare instruction if destination register is not used. 1302 if (!MRI->use_nodbg_empty(CmpInstr.getOperand(0).getReg())) 1303 return false; 1304 1305 return substituteCmpToZero(CmpInstr, SrcReg, MRI); 1306 } 1307 1308 /// Get opcode of S version of Instr. 1309 /// If Instr is S version its opcode is returned. 1310 /// AArch64::INSTRUCTION_LIST_END is returned if Instr does not have S version 1311 /// or we are not interested in it. 1312 static unsigned sForm(MachineInstr &Instr) { 1313 switch (Instr.getOpcode()) { 1314 default: 1315 return AArch64::INSTRUCTION_LIST_END; 1316 1317 case AArch64::ADDSWrr: 1318 case AArch64::ADDSWri: 1319 case AArch64::ADDSXrr: 1320 case AArch64::ADDSXri: 1321 case AArch64::SUBSWrr: 1322 case AArch64::SUBSWri: 1323 case AArch64::SUBSXrr: 1324 case AArch64::SUBSXri: 1325 return Instr.getOpcode(); 1326 1327 case AArch64::ADDWrr: 1328 return AArch64::ADDSWrr; 1329 case AArch64::ADDWri: 1330 return AArch64::ADDSWri; 1331 case AArch64::ADDXrr: 1332 return AArch64::ADDSXrr; 1333 case AArch64::ADDXri: 1334 return AArch64::ADDSXri; 1335 case AArch64::ADCWr: 1336 return AArch64::ADCSWr; 1337 case AArch64::ADCXr: 1338 return AArch64::ADCSXr; 1339 case AArch64::SUBWrr: 1340 return AArch64::SUBSWrr; 1341 case AArch64::SUBWri: 1342 return AArch64::SUBSWri; 1343 case AArch64::SUBXrr: 1344 return AArch64::SUBSXrr; 1345 case AArch64::SUBXri: 1346 return AArch64::SUBSXri; 1347 case AArch64::SBCWr: 1348 return AArch64::SBCSWr; 1349 case AArch64::SBCXr: 1350 return AArch64::SBCSXr; 1351 case AArch64::ANDWri: 1352 return AArch64::ANDSWri; 1353 case AArch64::ANDXri: 1354 return AArch64::ANDSXri; 1355 } 1356 } 1357 1358 /// Check if AArch64::NZCV should be alive in successors of MBB. 1359 static bool areCFlagsAliveInSuccessors(MachineBasicBlock *MBB) { 1360 for (auto *BB : MBB->successors()) 1361 if (BB->isLiveIn(AArch64::NZCV)) 1362 return true; 1363 return false; 1364 } 1365 1366 namespace { 1367 1368 struct UsedNZCV { 1369 bool N = false; 1370 bool Z = false; 1371 bool C = false; 1372 bool V = false; 1373 1374 UsedNZCV() = default; 1375 1376 UsedNZCV &operator|=(const UsedNZCV &UsedFlags) { 1377 this->N |= UsedFlags.N; 1378 this->Z |= UsedFlags.Z; 1379 this->C |= UsedFlags.C; 1380 this->V |= UsedFlags.V; 1381 return *this; 1382 } 1383 }; 1384 1385 } // end anonymous namespace 1386 1387 /// Find a condition code used by the instruction. 1388 /// Returns AArch64CC::Invalid if either the instruction does not use condition 1389 /// codes or we don't optimize CmpInstr in the presence of such instructions. 1390 static AArch64CC::CondCode findCondCodeUsedByInstr(const MachineInstr &Instr) { 1391 switch (Instr.getOpcode()) { 1392 default: 1393 return AArch64CC::Invalid; 1394 1395 case AArch64::Bcc: { 1396 int Idx = Instr.findRegisterUseOperandIdx(AArch64::NZCV); 1397 assert(Idx >= 2); 1398 return static_cast<AArch64CC::CondCode>(Instr.getOperand(Idx - 2).getImm()); 1399 } 1400 1401 case AArch64::CSINVWr: 1402 case AArch64::CSINVXr: 1403 case AArch64::CSINCWr: 1404 case AArch64::CSINCXr: 1405 case AArch64::CSELWr: 1406 case AArch64::CSELXr: 1407 case AArch64::CSNEGWr: 1408 case AArch64::CSNEGXr: 1409 case AArch64::FCSELSrrr: 1410 case AArch64::FCSELDrrr: { 1411 int Idx = Instr.findRegisterUseOperandIdx(AArch64::NZCV); 1412 assert(Idx >= 1); 1413 return static_cast<AArch64CC::CondCode>(Instr.getOperand(Idx - 1).getImm()); 1414 } 1415 } 1416 } 1417 1418 static UsedNZCV getUsedNZCV(AArch64CC::CondCode CC) { 1419 assert(CC != AArch64CC::Invalid); 1420 UsedNZCV UsedFlags; 1421 switch (CC) { 1422 default: 1423 break; 1424 1425 case AArch64CC::EQ: // Z set 1426 case AArch64CC::NE: // Z clear 1427 UsedFlags.Z = true; 1428 break; 1429 1430 case AArch64CC::HI: // Z clear and C set 1431 case AArch64CC::LS: // Z set or C clear 1432 UsedFlags.Z = true; 1433 LLVM_FALLTHROUGH; 1434 case AArch64CC::HS: // C set 1435 case AArch64CC::LO: // C clear 1436 UsedFlags.C = true; 1437 break; 1438 1439 case AArch64CC::MI: // N set 1440 case AArch64CC::PL: // N clear 1441 UsedFlags.N = true; 1442 break; 1443 1444 case AArch64CC::VS: // V set 1445 case AArch64CC::VC: // V clear 1446 UsedFlags.V = true; 1447 break; 1448 1449 case AArch64CC::GT: // Z clear, N and V the same 1450 case AArch64CC::LE: // Z set, N and V differ 1451 UsedFlags.Z = true; 1452 LLVM_FALLTHROUGH; 1453 case AArch64CC::GE: // N and V the same 1454 case AArch64CC::LT: // N and V differ 1455 UsedFlags.N = true; 1456 UsedFlags.V = true; 1457 break; 1458 } 1459 return UsedFlags; 1460 } 1461 1462 static bool isADDSRegImm(unsigned Opcode) { 1463 return Opcode == AArch64::ADDSWri || Opcode == AArch64::ADDSXri; 1464 } 1465 1466 static bool isSUBSRegImm(unsigned Opcode) { 1467 return Opcode == AArch64::SUBSWri || Opcode == AArch64::SUBSXri; 1468 } 1469 1470 /// Check if CmpInstr can be substituted by MI. 1471 /// 1472 /// CmpInstr can be substituted: 1473 /// - CmpInstr is either 'ADDS %vreg, 0' or 'SUBS %vreg, 0' 1474 /// - and, MI and CmpInstr are from the same MachineBB 1475 /// - and, condition flags are not alive in successors of the CmpInstr parent 1476 /// - and, if MI opcode is the S form there must be no defs of flags between 1477 /// MI and CmpInstr 1478 /// or if MI opcode is not the S form there must be neither defs of flags 1479 /// nor uses of flags between MI and CmpInstr. 1480 /// - and C/V flags are not used after CmpInstr 1481 static bool canInstrSubstituteCmpInstr(MachineInstr *MI, MachineInstr *CmpInstr, 1482 const TargetRegisterInfo *TRI) { 1483 assert(MI); 1484 assert(sForm(*MI) != AArch64::INSTRUCTION_LIST_END); 1485 assert(CmpInstr); 1486 1487 const unsigned CmpOpcode = CmpInstr->getOpcode(); 1488 if (!isADDSRegImm(CmpOpcode) && !isSUBSRegImm(CmpOpcode)) 1489 return false; 1490 1491 if (MI->getParent() != CmpInstr->getParent()) 1492 return false; 1493 1494 if (areCFlagsAliveInSuccessors(CmpInstr->getParent())) 1495 return false; 1496 1497 AccessKind AccessToCheck = AK_Write; 1498 if (sForm(*MI) != MI->getOpcode()) 1499 AccessToCheck = AK_All; 1500 if (areCFlagsAccessedBetweenInstrs(MI, CmpInstr, TRI, AccessToCheck)) 1501 return false; 1502 1503 UsedNZCV NZCVUsedAfterCmp; 1504 for (auto I = std::next(CmpInstr->getIterator()), 1505 E = CmpInstr->getParent()->instr_end(); 1506 I != E; ++I) { 1507 const MachineInstr &Instr = *I; 1508 if (Instr.readsRegister(AArch64::NZCV, TRI)) { 1509 AArch64CC::CondCode CC = findCondCodeUsedByInstr(Instr); 1510 if (CC == AArch64CC::Invalid) // Unsupported conditional instruction 1511 return false; 1512 NZCVUsedAfterCmp |= getUsedNZCV(CC); 1513 } 1514 1515 if (Instr.modifiesRegister(AArch64::NZCV, TRI)) 1516 break; 1517 } 1518 1519 return !NZCVUsedAfterCmp.C && !NZCVUsedAfterCmp.V; 1520 } 1521 1522 /// Substitute an instruction comparing to zero with another instruction 1523 /// which produces needed condition flags. 1524 /// 1525 /// Return true on success. 1526 bool AArch64InstrInfo::substituteCmpToZero( 1527 MachineInstr &CmpInstr, unsigned SrcReg, 1528 const MachineRegisterInfo *MRI) const { 1529 assert(MRI); 1530 // Get the unique definition of SrcReg. 1531 MachineInstr *MI = MRI->getUniqueVRegDef(SrcReg); 1532 if (!MI) 1533 return false; 1534 1535 const TargetRegisterInfo *TRI = &getRegisterInfo(); 1536 1537 unsigned NewOpc = sForm(*MI); 1538 if (NewOpc == AArch64::INSTRUCTION_LIST_END) 1539 return false; 1540 1541 if (!canInstrSubstituteCmpInstr(MI, &CmpInstr, TRI)) 1542 return false; 1543 1544 // Update the instruction to set NZCV. 1545 MI->setDesc(get(NewOpc)); 1546 CmpInstr.eraseFromParent(); 1547 bool succeeded = UpdateOperandRegClass(*MI); 1548 (void)succeeded; 1549 assert(succeeded && "Some operands reg class are incompatible!"); 1550 MI->addRegisterDefined(AArch64::NZCV, TRI); 1551 return true; 1552 } 1553 1554 bool AArch64InstrInfo::expandPostRAPseudo(MachineInstr &MI) const { 1555 if (MI.getOpcode() != TargetOpcode::LOAD_STACK_GUARD) 1556 return false; 1557 1558 MachineBasicBlock &MBB = *MI.getParent(); 1559 DebugLoc DL = MI.getDebugLoc(); 1560 unsigned Reg = MI.getOperand(0).getReg(); 1561 const GlobalValue *GV = 1562 cast<GlobalValue>((*MI.memoperands_begin())->getValue()); 1563 const TargetMachine &TM = MBB.getParent()->getTarget(); 1564 unsigned char OpFlags = Subtarget.ClassifyGlobalReference(GV, TM); 1565 const unsigned char MO_NC = AArch64II::MO_NC; 1566 1567 if ((OpFlags & AArch64II::MO_GOT) != 0) { 1568 BuildMI(MBB, MI, DL, get(AArch64::LOADgot), Reg) 1569 .addGlobalAddress(GV, 0, AArch64II::MO_GOT); 1570 BuildMI(MBB, MI, DL, get(AArch64::LDRXui), Reg) 1571 .addReg(Reg, RegState::Kill) 1572 .addImm(0) 1573 .addMemOperand(*MI.memoperands_begin()); 1574 } else if (TM.getCodeModel() == CodeModel::Large) { 1575 BuildMI(MBB, MI, DL, get(AArch64::MOVZXi), Reg) 1576 .addGlobalAddress(GV, 0, AArch64II::MO_G0 | MO_NC) 1577 .addImm(0); 1578 BuildMI(MBB, MI, DL, get(AArch64::MOVKXi), Reg) 1579 .addReg(Reg, RegState::Kill) 1580 .addGlobalAddress(GV, 0, AArch64II::MO_G1 | MO_NC) 1581 .addImm(16); 1582 BuildMI(MBB, MI, DL, get(AArch64::MOVKXi), Reg) 1583 .addReg(Reg, RegState::Kill) 1584 .addGlobalAddress(GV, 0, AArch64II::MO_G2 | MO_NC) 1585 .addImm(32); 1586 BuildMI(MBB, MI, DL, get(AArch64::MOVKXi), Reg) 1587 .addReg(Reg, RegState::Kill) 1588 .addGlobalAddress(GV, 0, AArch64II::MO_G3) 1589 .addImm(48); 1590 BuildMI(MBB, MI, DL, get(AArch64::LDRXui), Reg) 1591 .addReg(Reg, RegState::Kill) 1592 .addImm(0) 1593 .addMemOperand(*MI.memoperands_begin()); 1594 } else { 1595 BuildMI(MBB, MI, DL, get(AArch64::ADRP), Reg) 1596 .addGlobalAddress(GV, 0, OpFlags | AArch64II::MO_PAGE); 1597 unsigned char LoFlags = OpFlags | AArch64II::MO_PAGEOFF | MO_NC; 1598 BuildMI(MBB, MI, DL, get(AArch64::LDRXui), Reg) 1599 .addReg(Reg, RegState::Kill) 1600 .addGlobalAddress(GV, 0, LoFlags) 1601 .addMemOperand(*MI.memoperands_begin()); 1602 } 1603 1604 MBB.erase(MI); 1605 1606 return true; 1607 } 1608 1609 /// Return true if this is this instruction has a non-zero immediate 1610 bool AArch64InstrInfo::hasShiftedReg(const MachineInstr &MI) { 1611 switch (MI.getOpcode()) { 1612 default: 1613 break; 1614 case AArch64::ADDSWrs: 1615 case AArch64::ADDSXrs: 1616 case AArch64::ADDWrs: 1617 case AArch64::ADDXrs: 1618 case AArch64::ANDSWrs: 1619 case AArch64::ANDSXrs: 1620 case AArch64::ANDWrs: 1621 case AArch64::ANDXrs: 1622 case AArch64::BICSWrs: 1623 case AArch64::BICSXrs: 1624 case AArch64::BICWrs: 1625 case AArch64::BICXrs: 1626 case AArch64::EONWrs: 1627 case AArch64::EONXrs: 1628 case AArch64::EORWrs: 1629 case AArch64::EORXrs: 1630 case AArch64::ORNWrs: 1631 case AArch64::ORNXrs: 1632 case AArch64::ORRWrs: 1633 case AArch64::ORRXrs: 1634 case AArch64::SUBSWrs: 1635 case AArch64::SUBSXrs: 1636 case AArch64::SUBWrs: 1637 case AArch64::SUBXrs: 1638 if (MI.getOperand(3).isImm()) { 1639 unsigned val = MI.getOperand(3).getImm(); 1640 return (val != 0); 1641 } 1642 break; 1643 } 1644 return false; 1645 } 1646 1647 /// Return true if this is this instruction has a non-zero immediate 1648 bool AArch64InstrInfo::hasExtendedReg(const MachineInstr &MI) { 1649 switch (MI.getOpcode()) { 1650 default: 1651 break; 1652 case AArch64::ADDSWrx: 1653 case AArch64::ADDSXrx: 1654 case AArch64::ADDSXrx64: 1655 case AArch64::ADDWrx: 1656 case AArch64::ADDXrx: 1657 case AArch64::ADDXrx64: 1658 case AArch64::SUBSWrx: 1659 case AArch64::SUBSXrx: 1660 case AArch64::SUBSXrx64: 1661 case AArch64::SUBWrx: 1662 case AArch64::SUBXrx: 1663 case AArch64::SUBXrx64: 1664 if (MI.getOperand(3).isImm()) { 1665 unsigned val = MI.getOperand(3).getImm(); 1666 return (val != 0); 1667 } 1668 break; 1669 } 1670 1671 return false; 1672 } 1673 1674 // Return true if this instruction simply sets its single destination register 1675 // to zero. This is equivalent to a register rename of the zero-register. 1676 bool AArch64InstrInfo::isGPRZero(const MachineInstr &MI) { 1677 switch (MI.getOpcode()) { 1678 default: 1679 break; 1680 case AArch64::MOVZWi: 1681 case AArch64::MOVZXi: // movz Rd, #0 (LSL #0) 1682 if (MI.getOperand(1).isImm() && MI.getOperand(1).getImm() == 0) { 1683 assert(MI.getDesc().getNumOperands() == 3 && 1684 MI.getOperand(2).getImm() == 0 && "invalid MOVZi operands"); 1685 return true; 1686 } 1687 break; 1688 case AArch64::ANDWri: // and Rd, Rzr, #imm 1689 return MI.getOperand(1).getReg() == AArch64::WZR; 1690 case AArch64::ANDXri: 1691 return MI.getOperand(1).getReg() == AArch64::XZR; 1692 case TargetOpcode::COPY: 1693 return MI.getOperand(1).getReg() == AArch64::WZR; 1694 } 1695 return false; 1696 } 1697 1698 // Return true if this instruction simply renames a general register without 1699 // modifying bits. 1700 bool AArch64InstrInfo::isGPRCopy(const MachineInstr &MI) { 1701 switch (MI.getOpcode()) { 1702 default: 1703 break; 1704 case TargetOpcode::COPY: { 1705 // GPR32 copies will by lowered to ORRXrs 1706 unsigned DstReg = MI.getOperand(0).getReg(); 1707 return (AArch64::GPR32RegClass.contains(DstReg) || 1708 AArch64::GPR64RegClass.contains(DstReg)); 1709 } 1710 case AArch64::ORRXrs: // orr Xd, Xzr, Xm (LSL #0) 1711 if (MI.getOperand(1).getReg() == AArch64::XZR) { 1712 assert(MI.getDesc().getNumOperands() == 4 && 1713 MI.getOperand(3).getImm() == 0 && "invalid ORRrs operands"); 1714 return true; 1715 } 1716 break; 1717 case AArch64::ADDXri: // add Xd, Xn, #0 (LSL #0) 1718 if (MI.getOperand(2).getImm() == 0) { 1719 assert(MI.getDesc().getNumOperands() == 4 && 1720 MI.getOperand(3).getImm() == 0 && "invalid ADDXri operands"); 1721 return true; 1722 } 1723 break; 1724 } 1725 return false; 1726 } 1727 1728 // Return true if this instruction simply renames a general register without 1729 // modifying bits. 1730 bool AArch64InstrInfo::isFPRCopy(const MachineInstr &MI) { 1731 switch (MI.getOpcode()) { 1732 default: 1733 break; 1734 case TargetOpcode::COPY: { 1735 // FPR64 copies will by lowered to ORR.16b 1736 unsigned DstReg = MI.getOperand(0).getReg(); 1737 return (AArch64::FPR64RegClass.contains(DstReg) || 1738 AArch64::FPR128RegClass.contains(DstReg)); 1739 } 1740 case AArch64::ORRv16i8: 1741 if (MI.getOperand(1).getReg() == MI.getOperand(2).getReg()) { 1742 assert(MI.getDesc().getNumOperands() == 3 && MI.getOperand(0).isReg() && 1743 "invalid ORRv16i8 operands"); 1744 return true; 1745 } 1746 break; 1747 } 1748 return false; 1749 } 1750 1751 unsigned AArch64InstrInfo::isLoadFromStackSlot(const MachineInstr &MI, 1752 int &FrameIndex) const { 1753 switch (MI.getOpcode()) { 1754 default: 1755 break; 1756 case AArch64::LDRWui: 1757 case AArch64::LDRXui: 1758 case AArch64::LDRBui: 1759 case AArch64::LDRHui: 1760 case AArch64::LDRSui: 1761 case AArch64::LDRDui: 1762 case AArch64::LDRQui: 1763 if (MI.getOperand(0).getSubReg() == 0 && MI.getOperand(1).isFI() && 1764 MI.getOperand(2).isImm() && MI.getOperand(2).getImm() == 0) { 1765 FrameIndex = MI.getOperand(1).getIndex(); 1766 return MI.getOperand(0).getReg(); 1767 } 1768 break; 1769 } 1770 1771 return 0; 1772 } 1773 1774 unsigned AArch64InstrInfo::isStoreToStackSlot(const MachineInstr &MI, 1775 int &FrameIndex) const { 1776 switch (MI.getOpcode()) { 1777 default: 1778 break; 1779 case AArch64::STRWui: 1780 case AArch64::STRXui: 1781 case AArch64::STRBui: 1782 case AArch64::STRHui: 1783 case AArch64::STRSui: 1784 case AArch64::STRDui: 1785 case AArch64::STRQui: 1786 if (MI.getOperand(0).getSubReg() == 0 && MI.getOperand(1).isFI() && 1787 MI.getOperand(2).isImm() && MI.getOperand(2).getImm() == 0) { 1788 FrameIndex = MI.getOperand(1).getIndex(); 1789 return MI.getOperand(0).getReg(); 1790 } 1791 break; 1792 } 1793 return 0; 1794 } 1795 1796 /// Return true if this is load/store scales or extends its register offset. 1797 /// This refers to scaling a dynamic index as opposed to scaled immediates. 1798 /// MI should be a memory op that allows scaled addressing. 1799 bool AArch64InstrInfo::isScaledAddr(const MachineInstr &MI) { 1800 switch (MI.getOpcode()) { 1801 default: 1802 break; 1803 case AArch64::LDRBBroW: 1804 case AArch64::LDRBroW: 1805 case AArch64::LDRDroW: 1806 case AArch64::LDRHHroW: 1807 case AArch64::LDRHroW: 1808 case AArch64::LDRQroW: 1809 case AArch64::LDRSBWroW: 1810 case AArch64::LDRSBXroW: 1811 case AArch64::LDRSHWroW: 1812 case AArch64::LDRSHXroW: 1813 case AArch64::LDRSWroW: 1814 case AArch64::LDRSroW: 1815 case AArch64::LDRWroW: 1816 case AArch64::LDRXroW: 1817 case AArch64::STRBBroW: 1818 case AArch64::STRBroW: 1819 case AArch64::STRDroW: 1820 case AArch64::STRHHroW: 1821 case AArch64::STRHroW: 1822 case AArch64::STRQroW: 1823 case AArch64::STRSroW: 1824 case AArch64::STRWroW: 1825 case AArch64::STRXroW: 1826 case AArch64::LDRBBroX: 1827 case AArch64::LDRBroX: 1828 case AArch64::LDRDroX: 1829 case AArch64::LDRHHroX: 1830 case AArch64::LDRHroX: 1831 case AArch64::LDRQroX: 1832 case AArch64::LDRSBWroX: 1833 case AArch64::LDRSBXroX: 1834 case AArch64::LDRSHWroX: 1835 case AArch64::LDRSHXroX: 1836 case AArch64::LDRSWroX: 1837 case AArch64::LDRSroX: 1838 case AArch64::LDRWroX: 1839 case AArch64::LDRXroX: 1840 case AArch64::STRBBroX: 1841 case AArch64::STRBroX: 1842 case AArch64::STRDroX: 1843 case AArch64::STRHHroX: 1844 case AArch64::STRHroX: 1845 case AArch64::STRQroX: 1846 case AArch64::STRSroX: 1847 case AArch64::STRWroX: 1848 case AArch64::STRXroX: 1849 1850 unsigned Val = MI.getOperand(3).getImm(); 1851 AArch64_AM::ShiftExtendType ExtType = AArch64_AM::getMemExtendType(Val); 1852 return (ExtType != AArch64_AM::UXTX) || AArch64_AM::getMemDoShift(Val); 1853 } 1854 return false; 1855 } 1856 1857 /// Check all MachineMemOperands for a hint to suppress pairing. 1858 bool AArch64InstrInfo::isLdStPairSuppressed(const MachineInstr &MI) { 1859 return llvm::any_of(MI.memoperands(), [](MachineMemOperand *MMO) { 1860 return MMO->getFlags() & MOSuppressPair; 1861 }); 1862 } 1863 1864 /// Set a flag on the first MachineMemOperand to suppress pairing. 1865 void AArch64InstrInfo::suppressLdStPair(MachineInstr &MI) { 1866 if (MI.memoperands_empty()) 1867 return; 1868 (*MI.memoperands_begin())->setFlags(MOSuppressPair); 1869 } 1870 1871 /// Check all MachineMemOperands for a hint that the load/store is strided. 1872 bool AArch64InstrInfo::isStridedAccess(const MachineInstr &MI) { 1873 return llvm::any_of(MI.memoperands(), [](MachineMemOperand *MMO) { 1874 return MMO->getFlags() & MOStridedAccess; 1875 }); 1876 } 1877 1878 bool AArch64InstrInfo::isUnscaledLdSt(unsigned Opc) { 1879 switch (Opc) { 1880 default: 1881 return false; 1882 case AArch64::STURSi: 1883 case AArch64::STURDi: 1884 case AArch64::STURQi: 1885 case AArch64::STURBBi: 1886 case AArch64::STURHHi: 1887 case AArch64::STURWi: 1888 case AArch64::STURXi: 1889 case AArch64::LDURSi: 1890 case AArch64::LDURDi: 1891 case AArch64::LDURQi: 1892 case AArch64::LDURWi: 1893 case AArch64::LDURXi: 1894 case AArch64::LDURSWi: 1895 case AArch64::LDURHHi: 1896 case AArch64::LDURBBi: 1897 case AArch64::LDURSBWi: 1898 case AArch64::LDURSHWi: 1899 return true; 1900 } 1901 } 1902 1903 bool AArch64InstrInfo::isPairableLdStInst(const MachineInstr &MI) { 1904 switch (MI.getOpcode()) { 1905 default: 1906 return false; 1907 // Scaled instructions. 1908 case AArch64::STRSui: 1909 case AArch64::STRDui: 1910 case AArch64::STRQui: 1911 case AArch64::STRXui: 1912 case AArch64::STRWui: 1913 case AArch64::LDRSui: 1914 case AArch64::LDRDui: 1915 case AArch64::LDRQui: 1916 case AArch64::LDRXui: 1917 case AArch64::LDRWui: 1918 case AArch64::LDRSWui: 1919 // Unscaled instructions. 1920 case AArch64::STURSi: 1921 case AArch64::STURDi: 1922 case AArch64::STURQi: 1923 case AArch64::STURWi: 1924 case AArch64::STURXi: 1925 case AArch64::LDURSi: 1926 case AArch64::LDURDi: 1927 case AArch64::LDURQi: 1928 case AArch64::LDURWi: 1929 case AArch64::LDURXi: 1930 case AArch64::LDURSWi: 1931 return true; 1932 } 1933 } 1934 1935 unsigned AArch64InstrInfo::convertToFlagSettingOpc(unsigned Opc, 1936 bool &Is64Bit) { 1937 switch (Opc) { 1938 default: 1939 llvm_unreachable("Opcode has no flag setting equivalent!"); 1940 // 32-bit cases: 1941 case AArch64::ADDWri: 1942 Is64Bit = false; 1943 return AArch64::ADDSWri; 1944 case AArch64::ADDWrr: 1945 Is64Bit = false; 1946 return AArch64::ADDSWrr; 1947 case AArch64::ADDWrs: 1948 Is64Bit = false; 1949 return AArch64::ADDSWrs; 1950 case AArch64::ADDWrx: 1951 Is64Bit = false; 1952 return AArch64::ADDSWrx; 1953 case AArch64::ANDWri: 1954 Is64Bit = false; 1955 return AArch64::ANDSWri; 1956 case AArch64::ANDWrr: 1957 Is64Bit = false; 1958 return AArch64::ANDSWrr; 1959 case AArch64::ANDWrs: 1960 Is64Bit = false; 1961 return AArch64::ANDSWrs; 1962 case AArch64::BICWrr: 1963 Is64Bit = false; 1964 return AArch64::BICSWrr; 1965 case AArch64::BICWrs: 1966 Is64Bit = false; 1967 return AArch64::BICSWrs; 1968 case AArch64::SUBWri: 1969 Is64Bit = false; 1970 return AArch64::SUBSWri; 1971 case AArch64::SUBWrr: 1972 Is64Bit = false; 1973 return AArch64::SUBSWrr; 1974 case AArch64::SUBWrs: 1975 Is64Bit = false; 1976 return AArch64::SUBSWrs; 1977 case AArch64::SUBWrx: 1978 Is64Bit = false; 1979 return AArch64::SUBSWrx; 1980 // 64-bit cases: 1981 case AArch64::ADDXri: 1982 Is64Bit = true; 1983 return AArch64::ADDSXri; 1984 case AArch64::ADDXrr: 1985 Is64Bit = true; 1986 return AArch64::ADDSXrr; 1987 case AArch64::ADDXrs: 1988 Is64Bit = true; 1989 return AArch64::ADDSXrs; 1990 case AArch64::ADDXrx: 1991 Is64Bit = true; 1992 return AArch64::ADDSXrx; 1993 case AArch64::ANDXri: 1994 Is64Bit = true; 1995 return AArch64::ANDSXri; 1996 case AArch64::ANDXrr: 1997 Is64Bit = true; 1998 return AArch64::ANDSXrr; 1999 case AArch64::ANDXrs: 2000 Is64Bit = true; 2001 return AArch64::ANDSXrs; 2002 case AArch64::BICXrr: 2003 Is64Bit = true; 2004 return AArch64::BICSXrr; 2005 case AArch64::BICXrs: 2006 Is64Bit = true; 2007 return AArch64::BICSXrs; 2008 case AArch64::SUBXri: 2009 Is64Bit = true; 2010 return AArch64::SUBSXri; 2011 case AArch64::SUBXrr: 2012 Is64Bit = true; 2013 return AArch64::SUBSXrr; 2014 case AArch64::SUBXrs: 2015 Is64Bit = true; 2016 return AArch64::SUBSXrs; 2017 case AArch64::SUBXrx: 2018 Is64Bit = true; 2019 return AArch64::SUBSXrx; 2020 } 2021 } 2022 2023 // Is this a candidate for ld/st merging or pairing? For example, we don't 2024 // touch volatiles or load/stores that have a hint to avoid pair formation. 2025 bool AArch64InstrInfo::isCandidateToMergeOrPair(MachineInstr &MI) const { 2026 // If this is a volatile load/store, don't mess with it. 2027 if (MI.hasOrderedMemoryRef()) 2028 return false; 2029 2030 // Make sure this is a reg+imm (as opposed to an address reloc). 2031 assert(MI.getOperand(1).isReg() && "Expected a reg operand."); 2032 if (!MI.getOperand(2).isImm()) 2033 return false; 2034 2035 // Can't merge/pair if the instruction modifies the base register. 2036 // e.g., ldr x0, [x0] 2037 unsigned BaseReg = MI.getOperand(1).getReg(); 2038 const TargetRegisterInfo *TRI = &getRegisterInfo(); 2039 if (MI.modifiesRegister(BaseReg, TRI)) 2040 return false; 2041 2042 // Check if this load/store has a hint to avoid pair formation. 2043 // MachineMemOperands hints are set by the AArch64StorePairSuppress pass. 2044 if (isLdStPairSuppressed(MI)) 2045 return false; 2046 2047 // On some CPUs quad load/store pairs are slower than two single load/stores. 2048 if (Subtarget.isPaired128Slow()) { 2049 switch (MI.getOpcode()) { 2050 default: 2051 break; 2052 case AArch64::LDURQi: 2053 case AArch64::STURQi: 2054 case AArch64::LDRQui: 2055 case AArch64::STRQui: 2056 return false; 2057 } 2058 } 2059 2060 return true; 2061 } 2062 2063 bool AArch64InstrInfo::getMemOpBaseRegImmOfs( 2064 MachineInstr &LdSt, unsigned &BaseReg, int64_t &Offset, 2065 const TargetRegisterInfo *TRI) const { 2066 unsigned Width; 2067 return getMemOpBaseRegImmOfsWidth(LdSt, BaseReg, Offset, Width, TRI); 2068 } 2069 2070 bool AArch64InstrInfo::getMemOpBaseRegImmOfsWidth( 2071 MachineInstr &LdSt, unsigned &BaseReg, int64_t &Offset, unsigned &Width, 2072 const TargetRegisterInfo *TRI) const { 2073 assert(LdSt.mayLoadOrStore() && "Expected a memory operation."); 2074 // Handle only loads/stores with base register followed by immediate offset. 2075 if (LdSt.getNumExplicitOperands() == 3) { 2076 // Non-paired instruction (e.g., ldr x1, [x0, #8]). 2077 if (!LdSt.getOperand(1).isReg() || !LdSt.getOperand(2).isImm()) 2078 return false; 2079 } else if (LdSt.getNumExplicitOperands() == 4) { 2080 // Paired instruction (e.g., ldp x1, x2, [x0, #8]). 2081 if (!LdSt.getOperand(1).isReg() || !LdSt.getOperand(2).isReg() || 2082 !LdSt.getOperand(3).isImm()) 2083 return false; 2084 } else 2085 return false; 2086 2087 // Get the scaling factor for the instruction and set the width for the 2088 // instruction. 2089 unsigned Scale = 0; 2090 int64_t Dummy1, Dummy2; 2091 2092 // If this returns false, then it's an instruction we don't want to handle. 2093 if (!getMemOpInfo(LdSt.getOpcode(), Scale, Width, Dummy1, Dummy2)) 2094 return false; 2095 2096 // Compute the offset. Offset is calculated as the immediate operand 2097 // multiplied by the scaling factor. Unscaled instructions have scaling factor 2098 // set to 1. 2099 if (LdSt.getNumExplicitOperands() == 3) { 2100 BaseReg = LdSt.getOperand(1).getReg(); 2101 Offset = LdSt.getOperand(2).getImm() * Scale; 2102 } else { 2103 assert(LdSt.getNumExplicitOperands() == 4 && "invalid number of operands"); 2104 BaseReg = LdSt.getOperand(2).getReg(); 2105 Offset = LdSt.getOperand(3).getImm() * Scale; 2106 } 2107 return true; 2108 } 2109 2110 MachineOperand & 2111 AArch64InstrInfo::getMemOpBaseRegImmOfsOffsetOperand(MachineInstr &LdSt) const { 2112 assert(LdSt.mayLoadOrStore() && "Expected a memory operation."); 2113 MachineOperand &OfsOp = LdSt.getOperand(LdSt.getNumExplicitOperands() - 1); 2114 assert(OfsOp.isImm() && "Offset operand wasn't immediate."); 2115 return OfsOp; 2116 } 2117 2118 bool AArch64InstrInfo::getMemOpInfo(unsigned Opcode, unsigned &Scale, 2119 unsigned &Width, int64_t &MinOffset, 2120 int64_t &MaxOffset) const { 2121 switch (Opcode) { 2122 // Not a memory operation or something we want to handle. 2123 default: 2124 Scale = Width = 0; 2125 MinOffset = MaxOffset = 0; 2126 return false; 2127 case AArch64::STRWpost: 2128 case AArch64::LDRWpost: 2129 Width = 32; 2130 Scale = 4; 2131 MinOffset = -256; 2132 MaxOffset = 255; 2133 break; 2134 case AArch64::LDURQi: 2135 case AArch64::STURQi: 2136 Width = 16; 2137 Scale = 1; 2138 MinOffset = -256; 2139 MaxOffset = 255; 2140 break; 2141 case AArch64::LDURXi: 2142 case AArch64::LDURDi: 2143 case AArch64::STURXi: 2144 case AArch64::STURDi: 2145 Width = 8; 2146 Scale = 1; 2147 MinOffset = -256; 2148 MaxOffset = 255; 2149 break; 2150 case AArch64::LDURWi: 2151 case AArch64::LDURSi: 2152 case AArch64::LDURSWi: 2153 case AArch64::STURWi: 2154 case AArch64::STURSi: 2155 Width = 4; 2156 Scale = 1; 2157 MinOffset = -256; 2158 MaxOffset = 255; 2159 break; 2160 case AArch64::LDURHi: 2161 case AArch64::LDURHHi: 2162 case AArch64::LDURSHXi: 2163 case AArch64::LDURSHWi: 2164 case AArch64::STURHi: 2165 case AArch64::STURHHi: 2166 Width = 2; 2167 Scale = 1; 2168 MinOffset = -256; 2169 MaxOffset = 255; 2170 break; 2171 case AArch64::LDURBi: 2172 case AArch64::LDURBBi: 2173 case AArch64::LDURSBXi: 2174 case AArch64::LDURSBWi: 2175 case AArch64::STURBi: 2176 case AArch64::STURBBi: 2177 Width = 1; 2178 Scale = 1; 2179 MinOffset = -256; 2180 MaxOffset = 255; 2181 break; 2182 case AArch64::LDPQi: 2183 case AArch64::LDNPQi: 2184 case AArch64::STPQi: 2185 case AArch64::STNPQi: 2186 Scale = 16; 2187 Width = 32; 2188 MinOffset = -64; 2189 MaxOffset = 63; 2190 break; 2191 case AArch64::LDRQui: 2192 case AArch64::STRQui: 2193 Scale = Width = 16; 2194 MinOffset = 0; 2195 MaxOffset = 4095; 2196 break; 2197 case AArch64::LDPXi: 2198 case AArch64::LDPDi: 2199 case AArch64::LDNPXi: 2200 case AArch64::LDNPDi: 2201 case AArch64::STPXi: 2202 case AArch64::STPDi: 2203 case AArch64::STNPXi: 2204 case AArch64::STNPDi: 2205 Scale = 8; 2206 Width = 16; 2207 MinOffset = -64; 2208 MaxOffset = 63; 2209 break; 2210 case AArch64::LDRXui: 2211 case AArch64::LDRDui: 2212 case AArch64::STRXui: 2213 case AArch64::STRDui: 2214 Scale = Width = 8; 2215 MinOffset = 0; 2216 MaxOffset = 4095; 2217 break; 2218 case AArch64::LDPWi: 2219 case AArch64::LDPSi: 2220 case AArch64::LDNPWi: 2221 case AArch64::LDNPSi: 2222 case AArch64::STPWi: 2223 case AArch64::STPSi: 2224 case AArch64::STNPWi: 2225 case AArch64::STNPSi: 2226 Scale = 4; 2227 Width = 8; 2228 MinOffset = -64; 2229 MaxOffset = 63; 2230 break; 2231 case AArch64::LDRWui: 2232 case AArch64::LDRSui: 2233 case AArch64::LDRSWui: 2234 case AArch64::STRWui: 2235 case AArch64::STRSui: 2236 Scale = Width = 4; 2237 MinOffset = 0; 2238 MaxOffset = 4095; 2239 break; 2240 case AArch64::LDRHui: 2241 case AArch64::LDRHHui: 2242 case AArch64::STRHui: 2243 case AArch64::STRHHui: 2244 Scale = Width = 2; 2245 MinOffset = 0; 2246 MaxOffset = 4095; 2247 break; 2248 case AArch64::LDRBui: 2249 case AArch64::LDRBBui: 2250 case AArch64::STRBui: 2251 case AArch64::STRBBui: 2252 Scale = Width = 1; 2253 MinOffset = 0; 2254 MaxOffset = 4095; 2255 break; 2256 } 2257 2258 return true; 2259 } 2260 2261 // Scale the unscaled offsets. Returns false if the unscaled offset can't be 2262 // scaled. 2263 static bool scaleOffset(unsigned Opc, int64_t &Offset) { 2264 unsigned OffsetStride = 1; 2265 switch (Opc) { 2266 default: 2267 return false; 2268 case AArch64::LDURQi: 2269 case AArch64::STURQi: 2270 OffsetStride = 16; 2271 break; 2272 case AArch64::LDURXi: 2273 case AArch64::LDURDi: 2274 case AArch64::STURXi: 2275 case AArch64::STURDi: 2276 OffsetStride = 8; 2277 break; 2278 case AArch64::LDURWi: 2279 case AArch64::LDURSi: 2280 case AArch64::LDURSWi: 2281 case AArch64::STURWi: 2282 case AArch64::STURSi: 2283 OffsetStride = 4; 2284 break; 2285 } 2286 // If the byte-offset isn't a multiple of the stride, we can't scale this 2287 // offset. 2288 if (Offset % OffsetStride != 0) 2289 return false; 2290 2291 // Convert the byte-offset used by unscaled into an "element" offset used 2292 // by the scaled pair load/store instructions. 2293 Offset /= OffsetStride; 2294 return true; 2295 } 2296 2297 static bool canPairLdStOpc(unsigned FirstOpc, unsigned SecondOpc) { 2298 if (FirstOpc == SecondOpc) 2299 return true; 2300 // We can also pair sign-ext and zero-ext instructions. 2301 switch (FirstOpc) { 2302 default: 2303 return false; 2304 case AArch64::LDRWui: 2305 case AArch64::LDURWi: 2306 return SecondOpc == AArch64::LDRSWui || SecondOpc == AArch64::LDURSWi; 2307 case AArch64::LDRSWui: 2308 case AArch64::LDURSWi: 2309 return SecondOpc == AArch64::LDRWui || SecondOpc == AArch64::LDURWi; 2310 } 2311 // These instructions can't be paired based on their opcodes. 2312 return false; 2313 } 2314 2315 /// Detect opportunities for ldp/stp formation. 2316 /// 2317 /// Only called for LdSt for which getMemOpBaseRegImmOfs returns true. 2318 bool AArch64InstrInfo::shouldClusterMemOps(MachineInstr &FirstLdSt, 2319 unsigned BaseReg1, 2320 MachineInstr &SecondLdSt, 2321 unsigned BaseReg2, 2322 unsigned NumLoads) const { 2323 if (BaseReg1 != BaseReg2) 2324 return false; 2325 2326 // Only cluster up to a single pair. 2327 if (NumLoads > 1) 2328 return false; 2329 2330 if (!isPairableLdStInst(FirstLdSt) || !isPairableLdStInst(SecondLdSt)) 2331 return false; 2332 2333 // Can we pair these instructions based on their opcodes? 2334 unsigned FirstOpc = FirstLdSt.getOpcode(); 2335 unsigned SecondOpc = SecondLdSt.getOpcode(); 2336 if (!canPairLdStOpc(FirstOpc, SecondOpc)) 2337 return false; 2338 2339 // Can't merge volatiles or load/stores that have a hint to avoid pair 2340 // formation, for example. 2341 if (!isCandidateToMergeOrPair(FirstLdSt) || 2342 !isCandidateToMergeOrPair(SecondLdSt)) 2343 return false; 2344 2345 // isCandidateToMergeOrPair guarantees that operand 2 is an immediate. 2346 int64_t Offset1 = FirstLdSt.getOperand(2).getImm(); 2347 if (isUnscaledLdSt(FirstOpc) && !scaleOffset(FirstOpc, Offset1)) 2348 return false; 2349 2350 int64_t Offset2 = SecondLdSt.getOperand(2).getImm(); 2351 if (isUnscaledLdSt(SecondOpc) && !scaleOffset(SecondOpc, Offset2)) 2352 return false; 2353 2354 // Pairwise instructions have a 7-bit signed offset field. 2355 if (Offset1 > 63 || Offset1 < -64) 2356 return false; 2357 2358 // The caller should already have ordered First/SecondLdSt by offset. 2359 assert(Offset1 <= Offset2 && "Caller should have ordered offsets."); 2360 return Offset1 + 1 == Offset2; 2361 } 2362 2363 static const MachineInstrBuilder &AddSubReg(const MachineInstrBuilder &MIB, 2364 unsigned Reg, unsigned SubIdx, 2365 unsigned State, 2366 const TargetRegisterInfo *TRI) { 2367 if (!SubIdx) 2368 return MIB.addReg(Reg, State); 2369 2370 if (TargetRegisterInfo::isPhysicalRegister(Reg)) 2371 return MIB.addReg(TRI->getSubReg(Reg, SubIdx), State); 2372 return MIB.addReg(Reg, State, SubIdx); 2373 } 2374 2375 static bool forwardCopyWillClobberTuple(unsigned DestReg, unsigned SrcReg, 2376 unsigned NumRegs) { 2377 // We really want the positive remainder mod 32 here, that happens to be 2378 // easily obtainable with a mask. 2379 return ((DestReg - SrcReg) & 0x1f) < NumRegs; 2380 } 2381 2382 void AArch64InstrInfo::copyPhysRegTuple(MachineBasicBlock &MBB, 2383 MachineBasicBlock::iterator I, 2384 const DebugLoc &DL, unsigned DestReg, 2385 unsigned SrcReg, bool KillSrc, 2386 unsigned Opcode, 2387 ArrayRef<unsigned> Indices) const { 2388 assert(Subtarget.hasNEON() && "Unexpected register copy without NEON"); 2389 const TargetRegisterInfo *TRI = &getRegisterInfo(); 2390 uint16_t DestEncoding = TRI->getEncodingValue(DestReg); 2391 uint16_t SrcEncoding = TRI->getEncodingValue(SrcReg); 2392 unsigned NumRegs = Indices.size(); 2393 2394 int SubReg = 0, End = NumRegs, Incr = 1; 2395 if (forwardCopyWillClobberTuple(DestEncoding, SrcEncoding, NumRegs)) { 2396 SubReg = NumRegs - 1; 2397 End = -1; 2398 Incr = -1; 2399 } 2400 2401 for (; SubReg != End; SubReg += Incr) { 2402 const MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(Opcode)); 2403 AddSubReg(MIB, DestReg, Indices[SubReg], RegState::Define, TRI); 2404 AddSubReg(MIB, SrcReg, Indices[SubReg], 0, TRI); 2405 AddSubReg(MIB, SrcReg, Indices[SubReg], getKillRegState(KillSrc), TRI); 2406 } 2407 } 2408 2409 void AArch64InstrInfo::copyPhysReg(MachineBasicBlock &MBB, 2410 MachineBasicBlock::iterator I, 2411 const DebugLoc &DL, unsigned DestReg, 2412 unsigned SrcReg, bool KillSrc) const { 2413 if (AArch64::GPR32spRegClass.contains(DestReg) && 2414 (AArch64::GPR32spRegClass.contains(SrcReg) || SrcReg == AArch64::WZR)) { 2415 const TargetRegisterInfo *TRI = &getRegisterInfo(); 2416 2417 if (DestReg == AArch64::WSP || SrcReg == AArch64::WSP) { 2418 // If either operand is WSP, expand to ADD #0. 2419 if (Subtarget.hasZeroCycleRegMove()) { 2420 // Cyclone recognizes "ADD Xd, Xn, #0" as a zero-cycle register move. 2421 unsigned DestRegX = TRI->getMatchingSuperReg(DestReg, AArch64::sub_32, 2422 &AArch64::GPR64spRegClass); 2423 unsigned SrcRegX = TRI->getMatchingSuperReg(SrcReg, AArch64::sub_32, 2424 &AArch64::GPR64spRegClass); 2425 // This instruction is reading and writing X registers. This may upset 2426 // the register scavenger and machine verifier, so we need to indicate 2427 // that we are reading an undefined value from SrcRegX, but a proper 2428 // value from SrcReg. 2429 BuildMI(MBB, I, DL, get(AArch64::ADDXri), DestRegX) 2430 .addReg(SrcRegX, RegState::Undef) 2431 .addImm(0) 2432 .addImm(AArch64_AM::getShifterImm(AArch64_AM::LSL, 0)) 2433 .addReg(SrcReg, RegState::Implicit | getKillRegState(KillSrc)); 2434 } else { 2435 BuildMI(MBB, I, DL, get(AArch64::ADDWri), DestReg) 2436 .addReg(SrcReg, getKillRegState(KillSrc)) 2437 .addImm(0) 2438 .addImm(AArch64_AM::getShifterImm(AArch64_AM::LSL, 0)); 2439 } 2440 } else if (SrcReg == AArch64::WZR && Subtarget.hasZeroCycleZeroing()) { 2441 BuildMI(MBB, I, DL, get(AArch64::MOVZWi), DestReg) 2442 .addImm(0) 2443 .addImm(AArch64_AM::getShifterImm(AArch64_AM::LSL, 0)); 2444 } else { 2445 if (Subtarget.hasZeroCycleRegMove()) { 2446 // Cyclone recognizes "ORR Xd, XZR, Xm" as a zero-cycle register move. 2447 unsigned DestRegX = TRI->getMatchingSuperReg(DestReg, AArch64::sub_32, 2448 &AArch64::GPR64spRegClass); 2449 unsigned SrcRegX = TRI->getMatchingSuperReg(SrcReg, AArch64::sub_32, 2450 &AArch64::GPR64spRegClass); 2451 // This instruction is reading and writing X registers. This may upset 2452 // the register scavenger and machine verifier, so we need to indicate 2453 // that we are reading an undefined value from SrcRegX, but a proper 2454 // value from SrcReg. 2455 BuildMI(MBB, I, DL, get(AArch64::ORRXrr), DestRegX) 2456 .addReg(AArch64::XZR) 2457 .addReg(SrcRegX, RegState::Undef) 2458 .addReg(SrcReg, RegState::Implicit | getKillRegState(KillSrc)); 2459 } else { 2460 // Otherwise, expand to ORR WZR. 2461 BuildMI(MBB, I, DL, get(AArch64::ORRWrr), DestReg) 2462 .addReg(AArch64::WZR) 2463 .addReg(SrcReg, getKillRegState(KillSrc)); 2464 } 2465 } 2466 return; 2467 } 2468 2469 if (AArch64::GPR64spRegClass.contains(DestReg) && 2470 (AArch64::GPR64spRegClass.contains(SrcReg) || SrcReg == AArch64::XZR)) { 2471 if (DestReg == AArch64::SP || SrcReg == AArch64::SP) { 2472 // If either operand is SP, expand to ADD #0. 2473 BuildMI(MBB, I, DL, get(AArch64::ADDXri), DestReg) 2474 .addReg(SrcReg, getKillRegState(KillSrc)) 2475 .addImm(0) 2476 .addImm(AArch64_AM::getShifterImm(AArch64_AM::LSL, 0)); 2477 } else if (SrcReg == AArch64::XZR && Subtarget.hasZeroCycleZeroing()) { 2478 BuildMI(MBB, I, DL, get(AArch64::MOVZXi), DestReg) 2479 .addImm(0) 2480 .addImm(AArch64_AM::getShifterImm(AArch64_AM::LSL, 0)); 2481 } else { 2482 // Otherwise, expand to ORR XZR. 2483 BuildMI(MBB, I, DL, get(AArch64::ORRXrr), DestReg) 2484 .addReg(AArch64::XZR) 2485 .addReg(SrcReg, getKillRegState(KillSrc)); 2486 } 2487 return; 2488 } 2489 2490 // Copy a DDDD register quad by copying the individual sub-registers. 2491 if (AArch64::DDDDRegClass.contains(DestReg) && 2492 AArch64::DDDDRegClass.contains(SrcReg)) { 2493 static const unsigned Indices[] = {AArch64::dsub0, AArch64::dsub1, 2494 AArch64::dsub2, AArch64::dsub3}; 2495 copyPhysRegTuple(MBB, I, DL, DestReg, SrcReg, KillSrc, AArch64::ORRv8i8, 2496 Indices); 2497 return; 2498 } 2499 2500 // Copy a DDD register triple by copying the individual sub-registers. 2501 if (AArch64::DDDRegClass.contains(DestReg) && 2502 AArch64::DDDRegClass.contains(SrcReg)) { 2503 static const unsigned Indices[] = {AArch64::dsub0, AArch64::dsub1, 2504 AArch64::dsub2}; 2505 copyPhysRegTuple(MBB, I, DL, DestReg, SrcReg, KillSrc, AArch64::ORRv8i8, 2506 Indices); 2507 return; 2508 } 2509 2510 // Copy a DD register pair by copying the individual sub-registers. 2511 if (AArch64::DDRegClass.contains(DestReg) && 2512 AArch64::DDRegClass.contains(SrcReg)) { 2513 static const unsigned Indices[] = {AArch64::dsub0, AArch64::dsub1}; 2514 copyPhysRegTuple(MBB, I, DL, DestReg, SrcReg, KillSrc, AArch64::ORRv8i8, 2515 Indices); 2516 return; 2517 } 2518 2519 // Copy a QQQQ register quad by copying the individual sub-registers. 2520 if (AArch64::QQQQRegClass.contains(DestReg) && 2521 AArch64::QQQQRegClass.contains(SrcReg)) { 2522 static const unsigned Indices[] = {AArch64::qsub0, AArch64::qsub1, 2523 AArch64::qsub2, AArch64::qsub3}; 2524 copyPhysRegTuple(MBB, I, DL, DestReg, SrcReg, KillSrc, AArch64::ORRv16i8, 2525 Indices); 2526 return; 2527 } 2528 2529 // Copy a QQQ register triple by copying the individual sub-registers. 2530 if (AArch64::QQQRegClass.contains(DestReg) && 2531 AArch64::QQQRegClass.contains(SrcReg)) { 2532 static const unsigned Indices[] = {AArch64::qsub0, AArch64::qsub1, 2533 AArch64::qsub2}; 2534 copyPhysRegTuple(MBB, I, DL, DestReg, SrcReg, KillSrc, AArch64::ORRv16i8, 2535 Indices); 2536 return; 2537 } 2538 2539 // Copy a QQ register pair by copying the individual sub-registers. 2540 if (AArch64::QQRegClass.contains(DestReg) && 2541 AArch64::QQRegClass.contains(SrcReg)) { 2542 static const unsigned Indices[] = {AArch64::qsub0, AArch64::qsub1}; 2543 copyPhysRegTuple(MBB, I, DL, DestReg, SrcReg, KillSrc, AArch64::ORRv16i8, 2544 Indices); 2545 return; 2546 } 2547 2548 if (AArch64::FPR128RegClass.contains(DestReg) && 2549 AArch64::FPR128RegClass.contains(SrcReg)) { 2550 if (Subtarget.hasNEON()) { 2551 BuildMI(MBB, I, DL, get(AArch64::ORRv16i8), DestReg) 2552 .addReg(SrcReg) 2553 .addReg(SrcReg, getKillRegState(KillSrc)); 2554 } else { 2555 BuildMI(MBB, I, DL, get(AArch64::STRQpre)) 2556 .addReg(AArch64::SP, RegState::Define) 2557 .addReg(SrcReg, getKillRegState(KillSrc)) 2558 .addReg(AArch64::SP) 2559 .addImm(-16); 2560 BuildMI(MBB, I, DL, get(AArch64::LDRQpre)) 2561 .addReg(AArch64::SP, RegState::Define) 2562 .addReg(DestReg, RegState::Define) 2563 .addReg(AArch64::SP) 2564 .addImm(16); 2565 } 2566 return; 2567 } 2568 2569 if (AArch64::FPR64RegClass.contains(DestReg) && 2570 AArch64::FPR64RegClass.contains(SrcReg)) { 2571 if (Subtarget.hasNEON()) { 2572 DestReg = RI.getMatchingSuperReg(DestReg, AArch64::dsub, 2573 &AArch64::FPR128RegClass); 2574 SrcReg = RI.getMatchingSuperReg(SrcReg, AArch64::dsub, 2575 &AArch64::FPR128RegClass); 2576 BuildMI(MBB, I, DL, get(AArch64::ORRv16i8), DestReg) 2577 .addReg(SrcReg) 2578 .addReg(SrcReg, getKillRegState(KillSrc)); 2579 } else { 2580 BuildMI(MBB, I, DL, get(AArch64::FMOVDr), DestReg) 2581 .addReg(SrcReg, getKillRegState(KillSrc)); 2582 } 2583 return; 2584 } 2585 2586 if (AArch64::FPR32RegClass.contains(DestReg) && 2587 AArch64::FPR32RegClass.contains(SrcReg)) { 2588 if (Subtarget.hasNEON()) { 2589 DestReg = RI.getMatchingSuperReg(DestReg, AArch64::ssub, 2590 &AArch64::FPR128RegClass); 2591 SrcReg = RI.getMatchingSuperReg(SrcReg, AArch64::ssub, 2592 &AArch64::FPR128RegClass); 2593 BuildMI(MBB, I, DL, get(AArch64::ORRv16i8), DestReg) 2594 .addReg(SrcReg) 2595 .addReg(SrcReg, getKillRegState(KillSrc)); 2596 } else { 2597 BuildMI(MBB, I, DL, get(AArch64::FMOVSr), DestReg) 2598 .addReg(SrcReg, getKillRegState(KillSrc)); 2599 } 2600 return; 2601 } 2602 2603 if (AArch64::FPR16RegClass.contains(DestReg) && 2604 AArch64::FPR16RegClass.contains(SrcReg)) { 2605 if (Subtarget.hasNEON()) { 2606 DestReg = RI.getMatchingSuperReg(DestReg, AArch64::hsub, 2607 &AArch64::FPR128RegClass); 2608 SrcReg = RI.getMatchingSuperReg(SrcReg, AArch64::hsub, 2609 &AArch64::FPR128RegClass); 2610 BuildMI(MBB, I, DL, get(AArch64::ORRv16i8), DestReg) 2611 .addReg(SrcReg) 2612 .addReg(SrcReg, getKillRegState(KillSrc)); 2613 } else { 2614 DestReg = RI.getMatchingSuperReg(DestReg, AArch64::hsub, 2615 &AArch64::FPR32RegClass); 2616 SrcReg = RI.getMatchingSuperReg(SrcReg, AArch64::hsub, 2617 &AArch64::FPR32RegClass); 2618 BuildMI(MBB, I, DL, get(AArch64::FMOVSr), DestReg) 2619 .addReg(SrcReg, getKillRegState(KillSrc)); 2620 } 2621 return; 2622 } 2623 2624 if (AArch64::FPR8RegClass.contains(DestReg) && 2625 AArch64::FPR8RegClass.contains(SrcReg)) { 2626 if (Subtarget.hasNEON()) { 2627 DestReg = RI.getMatchingSuperReg(DestReg, AArch64::bsub, 2628 &AArch64::FPR128RegClass); 2629 SrcReg = RI.getMatchingSuperReg(SrcReg, AArch64::bsub, 2630 &AArch64::FPR128RegClass); 2631 BuildMI(MBB, I, DL, get(AArch64::ORRv16i8), DestReg) 2632 .addReg(SrcReg) 2633 .addReg(SrcReg, getKillRegState(KillSrc)); 2634 } else { 2635 DestReg = RI.getMatchingSuperReg(DestReg, AArch64::bsub, 2636 &AArch64::FPR32RegClass); 2637 SrcReg = RI.getMatchingSuperReg(SrcReg, AArch64::bsub, 2638 &AArch64::FPR32RegClass); 2639 BuildMI(MBB, I, DL, get(AArch64::FMOVSr), DestReg) 2640 .addReg(SrcReg, getKillRegState(KillSrc)); 2641 } 2642 return; 2643 } 2644 2645 // Copies between GPR64 and FPR64. 2646 if (AArch64::FPR64RegClass.contains(DestReg) && 2647 AArch64::GPR64RegClass.contains(SrcReg)) { 2648 BuildMI(MBB, I, DL, get(AArch64::FMOVXDr), DestReg) 2649 .addReg(SrcReg, getKillRegState(KillSrc)); 2650 return; 2651 } 2652 if (AArch64::GPR64RegClass.contains(DestReg) && 2653 AArch64::FPR64RegClass.contains(SrcReg)) { 2654 BuildMI(MBB, I, DL, get(AArch64::FMOVDXr), DestReg) 2655 .addReg(SrcReg, getKillRegState(KillSrc)); 2656 return; 2657 } 2658 // Copies between GPR32 and FPR32. 2659 if (AArch64::FPR32RegClass.contains(DestReg) && 2660 AArch64::GPR32RegClass.contains(SrcReg)) { 2661 BuildMI(MBB, I, DL, get(AArch64::FMOVWSr), DestReg) 2662 .addReg(SrcReg, getKillRegState(KillSrc)); 2663 return; 2664 } 2665 if (AArch64::GPR32RegClass.contains(DestReg) && 2666 AArch64::FPR32RegClass.contains(SrcReg)) { 2667 BuildMI(MBB, I, DL, get(AArch64::FMOVSWr), DestReg) 2668 .addReg(SrcReg, getKillRegState(KillSrc)); 2669 return; 2670 } 2671 2672 if (DestReg == AArch64::NZCV) { 2673 assert(AArch64::GPR64RegClass.contains(SrcReg) && "Invalid NZCV copy"); 2674 BuildMI(MBB, I, DL, get(AArch64::MSR)) 2675 .addImm(AArch64SysReg::NZCV) 2676 .addReg(SrcReg, getKillRegState(KillSrc)) 2677 .addReg(AArch64::NZCV, RegState::Implicit | RegState::Define); 2678 return; 2679 } 2680 2681 if (SrcReg == AArch64::NZCV) { 2682 assert(AArch64::GPR64RegClass.contains(DestReg) && "Invalid NZCV copy"); 2683 BuildMI(MBB, I, DL, get(AArch64::MRS), DestReg) 2684 .addImm(AArch64SysReg::NZCV) 2685 .addReg(AArch64::NZCV, RegState::Implicit | getKillRegState(KillSrc)); 2686 return; 2687 } 2688 2689 llvm_unreachable("unimplemented reg-to-reg copy"); 2690 } 2691 2692 void AArch64InstrInfo::storeRegToStackSlot( 2693 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned SrcReg, 2694 bool isKill, int FI, const TargetRegisterClass *RC, 2695 const TargetRegisterInfo *TRI) const { 2696 DebugLoc DL; 2697 if (MBBI != MBB.end()) 2698 DL = MBBI->getDebugLoc(); 2699 MachineFunction &MF = *MBB.getParent(); 2700 MachineFrameInfo &MFI = MF.getFrameInfo(); 2701 unsigned Align = MFI.getObjectAlignment(FI); 2702 2703 MachinePointerInfo PtrInfo = MachinePointerInfo::getFixedStack(MF, FI); 2704 MachineMemOperand *MMO = MF.getMachineMemOperand( 2705 PtrInfo, MachineMemOperand::MOStore, MFI.getObjectSize(FI), Align); 2706 unsigned Opc = 0; 2707 bool Offset = true; 2708 switch (TRI->getSpillSize(*RC)) { 2709 case 1: 2710 if (AArch64::FPR8RegClass.hasSubClassEq(RC)) 2711 Opc = AArch64::STRBui; 2712 break; 2713 case 2: 2714 if (AArch64::FPR16RegClass.hasSubClassEq(RC)) 2715 Opc = AArch64::STRHui; 2716 break; 2717 case 4: 2718 if (AArch64::GPR32allRegClass.hasSubClassEq(RC)) { 2719 Opc = AArch64::STRWui; 2720 if (TargetRegisterInfo::isVirtualRegister(SrcReg)) 2721 MF.getRegInfo().constrainRegClass(SrcReg, &AArch64::GPR32RegClass); 2722 else 2723 assert(SrcReg != AArch64::WSP); 2724 } else if (AArch64::FPR32RegClass.hasSubClassEq(RC)) 2725 Opc = AArch64::STRSui; 2726 break; 2727 case 8: 2728 if (AArch64::GPR64allRegClass.hasSubClassEq(RC)) { 2729 Opc = AArch64::STRXui; 2730 if (TargetRegisterInfo::isVirtualRegister(SrcReg)) 2731 MF.getRegInfo().constrainRegClass(SrcReg, &AArch64::GPR64RegClass); 2732 else 2733 assert(SrcReg != AArch64::SP); 2734 } else if (AArch64::FPR64RegClass.hasSubClassEq(RC)) 2735 Opc = AArch64::STRDui; 2736 break; 2737 case 16: 2738 if (AArch64::FPR128RegClass.hasSubClassEq(RC)) 2739 Opc = AArch64::STRQui; 2740 else if (AArch64::DDRegClass.hasSubClassEq(RC)) { 2741 assert(Subtarget.hasNEON() && "Unexpected register store without NEON"); 2742 Opc = AArch64::ST1Twov1d; 2743 Offset = false; 2744 } else if (AArch64::XSeqPairsClassRegClass.hasSubClassEq(RC)) { 2745 BuildMI(MBB, MBBI, DL, get(AArch64::STPXi)) 2746 .addReg(TRI->getSubReg(SrcReg, AArch64::sube64), 2747 getKillRegState(isKill)) 2748 .addReg(TRI->getSubReg(SrcReg, AArch64::subo64), 2749 getKillRegState(isKill)) 2750 .addFrameIndex(FI) 2751 .addImm(0) 2752 .addMemOperand(MMO); 2753 return; 2754 } 2755 break; 2756 case 24: 2757 if (AArch64::DDDRegClass.hasSubClassEq(RC)) { 2758 assert(Subtarget.hasNEON() && "Unexpected register store without NEON"); 2759 Opc = AArch64::ST1Threev1d; 2760 Offset = false; 2761 } 2762 break; 2763 case 32: 2764 if (AArch64::DDDDRegClass.hasSubClassEq(RC)) { 2765 assert(Subtarget.hasNEON() && "Unexpected register store without NEON"); 2766 Opc = AArch64::ST1Fourv1d; 2767 Offset = false; 2768 } else if (AArch64::QQRegClass.hasSubClassEq(RC)) { 2769 assert(Subtarget.hasNEON() && "Unexpected register store without NEON"); 2770 Opc = AArch64::ST1Twov2d; 2771 Offset = false; 2772 } 2773 break; 2774 case 48: 2775 if (AArch64::QQQRegClass.hasSubClassEq(RC)) { 2776 assert(Subtarget.hasNEON() && "Unexpected register store without NEON"); 2777 Opc = AArch64::ST1Threev2d; 2778 Offset = false; 2779 } 2780 break; 2781 case 64: 2782 if (AArch64::QQQQRegClass.hasSubClassEq(RC)) { 2783 assert(Subtarget.hasNEON() && "Unexpected register store without NEON"); 2784 Opc = AArch64::ST1Fourv2d; 2785 Offset = false; 2786 } 2787 break; 2788 } 2789 assert(Opc && "Unknown register class"); 2790 2791 const MachineInstrBuilder MI = BuildMI(MBB, MBBI, DL, get(Opc)) 2792 .addReg(SrcReg, getKillRegState(isKill)) 2793 .addFrameIndex(FI); 2794 2795 if (Offset) 2796 MI.addImm(0); 2797 MI.addMemOperand(MMO); 2798 } 2799 2800 void AArch64InstrInfo::loadRegFromStackSlot( 2801 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned DestReg, 2802 int FI, const TargetRegisterClass *RC, 2803 const TargetRegisterInfo *TRI) const { 2804 DebugLoc DL; 2805 if (MBBI != MBB.end()) 2806 DL = MBBI->getDebugLoc(); 2807 MachineFunction &MF = *MBB.getParent(); 2808 MachineFrameInfo &MFI = MF.getFrameInfo(); 2809 unsigned Align = MFI.getObjectAlignment(FI); 2810 MachinePointerInfo PtrInfo = MachinePointerInfo::getFixedStack(MF, FI); 2811 MachineMemOperand *MMO = MF.getMachineMemOperand( 2812 PtrInfo, MachineMemOperand::MOLoad, MFI.getObjectSize(FI), Align); 2813 2814 unsigned Opc = 0; 2815 bool Offset = true; 2816 switch (TRI->getSpillSize(*RC)) { 2817 case 1: 2818 if (AArch64::FPR8RegClass.hasSubClassEq(RC)) 2819 Opc = AArch64::LDRBui; 2820 break; 2821 case 2: 2822 if (AArch64::FPR16RegClass.hasSubClassEq(RC)) 2823 Opc = AArch64::LDRHui; 2824 break; 2825 case 4: 2826 if (AArch64::GPR32allRegClass.hasSubClassEq(RC)) { 2827 Opc = AArch64::LDRWui; 2828 if (TargetRegisterInfo::isVirtualRegister(DestReg)) 2829 MF.getRegInfo().constrainRegClass(DestReg, &AArch64::GPR32RegClass); 2830 else 2831 assert(DestReg != AArch64::WSP); 2832 } else if (AArch64::FPR32RegClass.hasSubClassEq(RC)) 2833 Opc = AArch64::LDRSui; 2834 break; 2835 case 8: 2836 if (AArch64::GPR64allRegClass.hasSubClassEq(RC)) { 2837 Opc = AArch64::LDRXui; 2838 if (TargetRegisterInfo::isVirtualRegister(DestReg)) 2839 MF.getRegInfo().constrainRegClass(DestReg, &AArch64::GPR64RegClass); 2840 else 2841 assert(DestReg != AArch64::SP); 2842 } else if (AArch64::FPR64RegClass.hasSubClassEq(RC)) 2843 Opc = AArch64::LDRDui; 2844 break; 2845 case 16: 2846 if (AArch64::FPR128RegClass.hasSubClassEq(RC)) 2847 Opc = AArch64::LDRQui; 2848 else if (AArch64::DDRegClass.hasSubClassEq(RC)) { 2849 assert(Subtarget.hasNEON() && "Unexpected register load without NEON"); 2850 Opc = AArch64::LD1Twov1d; 2851 Offset = false; 2852 } else if (AArch64::XSeqPairsClassRegClass.hasSubClassEq(RC)) { 2853 BuildMI(MBB, MBBI, DL, get(AArch64::LDPXi)) 2854 .addReg(TRI->getSubReg(DestReg, AArch64::sube64), 2855 getDefRegState(true)) 2856 .addReg(TRI->getSubReg(DestReg, AArch64::subo64), 2857 getDefRegState(true)) 2858 .addFrameIndex(FI) 2859 .addImm(0) 2860 .addMemOperand(MMO); 2861 return; 2862 } 2863 break; 2864 case 24: 2865 if (AArch64::DDDRegClass.hasSubClassEq(RC)) { 2866 assert(Subtarget.hasNEON() && "Unexpected register load without NEON"); 2867 Opc = AArch64::LD1Threev1d; 2868 Offset = false; 2869 } 2870 break; 2871 case 32: 2872 if (AArch64::DDDDRegClass.hasSubClassEq(RC)) { 2873 assert(Subtarget.hasNEON() && "Unexpected register load without NEON"); 2874 Opc = AArch64::LD1Fourv1d; 2875 Offset = false; 2876 } else if (AArch64::QQRegClass.hasSubClassEq(RC)) { 2877 assert(Subtarget.hasNEON() && "Unexpected register load without NEON"); 2878 Opc = AArch64::LD1Twov2d; 2879 Offset = false; 2880 } 2881 break; 2882 case 48: 2883 if (AArch64::QQQRegClass.hasSubClassEq(RC)) { 2884 assert(Subtarget.hasNEON() && "Unexpected register load without NEON"); 2885 Opc = AArch64::LD1Threev2d; 2886 Offset = false; 2887 } 2888 break; 2889 case 64: 2890 if (AArch64::QQQQRegClass.hasSubClassEq(RC)) { 2891 assert(Subtarget.hasNEON() && "Unexpected register load without NEON"); 2892 Opc = AArch64::LD1Fourv2d; 2893 Offset = false; 2894 } 2895 break; 2896 } 2897 assert(Opc && "Unknown register class"); 2898 2899 const MachineInstrBuilder MI = BuildMI(MBB, MBBI, DL, get(Opc)) 2900 .addReg(DestReg, getDefRegState(true)) 2901 .addFrameIndex(FI); 2902 if (Offset) 2903 MI.addImm(0); 2904 MI.addMemOperand(MMO); 2905 } 2906 2907 void llvm::emitFrameOffset(MachineBasicBlock &MBB, 2908 MachineBasicBlock::iterator MBBI, const DebugLoc &DL, 2909 unsigned DestReg, unsigned SrcReg, int Offset, 2910 const TargetInstrInfo *TII, 2911 MachineInstr::MIFlag Flag, bool SetNZCV) { 2912 if (DestReg == SrcReg && Offset == 0) 2913 return; 2914 2915 assert((DestReg != AArch64::SP || Offset % 16 == 0) && 2916 "SP increment/decrement not 16-byte aligned"); 2917 2918 bool isSub = Offset < 0; 2919 if (isSub) 2920 Offset = -Offset; 2921 2922 // FIXME: If the offset won't fit in 24-bits, compute the offset into a 2923 // scratch register. If DestReg is a virtual register, use it as the 2924 // scratch register; otherwise, create a new virtual register (to be 2925 // replaced by the scavenger at the end of PEI). That case can be optimized 2926 // slightly if DestReg is SP which is always 16-byte aligned, so the scratch 2927 // register can be loaded with offset%8 and the add/sub can use an extending 2928 // instruction with LSL#3. 2929 // Currently the function handles any offsets but generates a poor sequence 2930 // of code. 2931 // assert(Offset < (1 << 24) && "unimplemented reg plus immediate"); 2932 2933 unsigned Opc; 2934 if (SetNZCV) 2935 Opc = isSub ? AArch64::SUBSXri : AArch64::ADDSXri; 2936 else 2937 Opc = isSub ? AArch64::SUBXri : AArch64::ADDXri; 2938 const unsigned MaxEncoding = 0xfff; 2939 const unsigned ShiftSize = 12; 2940 const unsigned MaxEncodableValue = MaxEncoding << ShiftSize; 2941 while (((unsigned)Offset) >= (1 << ShiftSize)) { 2942 unsigned ThisVal; 2943 if (((unsigned)Offset) > MaxEncodableValue) { 2944 ThisVal = MaxEncodableValue; 2945 } else { 2946 ThisVal = Offset & MaxEncodableValue; 2947 } 2948 assert((ThisVal >> ShiftSize) <= MaxEncoding && 2949 "Encoding cannot handle value that big"); 2950 BuildMI(MBB, MBBI, DL, TII->get(Opc), DestReg) 2951 .addReg(SrcReg) 2952 .addImm(ThisVal >> ShiftSize) 2953 .addImm(AArch64_AM::getShifterImm(AArch64_AM::LSL, ShiftSize)) 2954 .setMIFlag(Flag); 2955 2956 SrcReg = DestReg; 2957 Offset -= ThisVal; 2958 if (Offset == 0) 2959 return; 2960 } 2961 BuildMI(MBB, MBBI, DL, TII->get(Opc), DestReg) 2962 .addReg(SrcReg) 2963 .addImm(Offset) 2964 .addImm(AArch64_AM::getShifterImm(AArch64_AM::LSL, 0)) 2965 .setMIFlag(Flag); 2966 } 2967 2968 MachineInstr *AArch64InstrInfo::foldMemoryOperandImpl( 2969 MachineFunction &MF, MachineInstr &MI, ArrayRef<unsigned> Ops, 2970 MachineBasicBlock::iterator InsertPt, int FrameIndex, 2971 LiveIntervals *LIS) const { 2972 // This is a bit of a hack. Consider this instruction: 2973 // 2974 // %0 = COPY %sp; GPR64all:%0 2975 // 2976 // We explicitly chose GPR64all for the virtual register so such a copy might 2977 // be eliminated by RegisterCoalescer. However, that may not be possible, and 2978 // %0 may even spill. We can't spill %sp, and since it is in the GPR64all 2979 // register class, TargetInstrInfo::foldMemoryOperand() is going to try. 2980 // 2981 // To prevent that, we are going to constrain the %0 register class here. 2982 // 2983 // <rdar://problem/11522048> 2984 // 2985 if (MI.isFullCopy()) { 2986 unsigned DstReg = MI.getOperand(0).getReg(); 2987 unsigned SrcReg = MI.getOperand(1).getReg(); 2988 if (SrcReg == AArch64::SP && 2989 TargetRegisterInfo::isVirtualRegister(DstReg)) { 2990 MF.getRegInfo().constrainRegClass(DstReg, &AArch64::GPR64RegClass); 2991 return nullptr; 2992 } 2993 if (DstReg == AArch64::SP && 2994 TargetRegisterInfo::isVirtualRegister(SrcReg)) { 2995 MF.getRegInfo().constrainRegClass(SrcReg, &AArch64::GPR64RegClass); 2996 return nullptr; 2997 } 2998 } 2999 3000 // Handle the case where a copy is being spilled or filled but the source 3001 // and destination register class don't match. For example: 3002 // 3003 // %0 = COPY %xzr; GPR64common:%0 3004 // 3005 // In this case we can still safely fold away the COPY and generate the 3006 // following spill code: 3007 // 3008 // STRXui %xzr, %stack.0 3009 // 3010 // This also eliminates spilled cross register class COPYs (e.g. between x and 3011 // d regs) of the same size. For example: 3012 // 3013 // %0 = COPY %1; GPR64:%0, FPR64:%1 3014 // 3015 // will be filled as 3016 // 3017 // LDRDui %0, fi<#0> 3018 // 3019 // instead of 3020 // 3021 // LDRXui %Temp, fi<#0> 3022 // %0 = FMOV %Temp 3023 // 3024 if (MI.isCopy() && Ops.size() == 1 && 3025 // Make sure we're only folding the explicit COPY defs/uses. 3026 (Ops[0] == 0 || Ops[0] == 1)) { 3027 bool IsSpill = Ops[0] == 0; 3028 bool IsFill = !IsSpill; 3029 const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo(); 3030 const MachineRegisterInfo &MRI = MF.getRegInfo(); 3031 MachineBasicBlock &MBB = *MI.getParent(); 3032 const MachineOperand &DstMO = MI.getOperand(0); 3033 const MachineOperand &SrcMO = MI.getOperand(1); 3034 unsigned DstReg = DstMO.getReg(); 3035 unsigned SrcReg = SrcMO.getReg(); 3036 // This is slightly expensive to compute for physical regs since 3037 // getMinimalPhysRegClass is slow. 3038 auto getRegClass = [&](unsigned Reg) { 3039 return TargetRegisterInfo::isVirtualRegister(Reg) 3040 ? MRI.getRegClass(Reg) 3041 : TRI.getMinimalPhysRegClass(Reg); 3042 }; 3043 3044 if (DstMO.getSubReg() == 0 && SrcMO.getSubReg() == 0) { 3045 assert(TRI.getRegSizeInBits(*getRegClass(DstReg)) == 3046 TRI.getRegSizeInBits(*getRegClass(SrcReg)) && 3047 "Mismatched register size in non subreg COPY"); 3048 if (IsSpill) 3049 storeRegToStackSlot(MBB, InsertPt, SrcReg, SrcMO.isKill(), FrameIndex, 3050 getRegClass(SrcReg), &TRI); 3051 else 3052 loadRegFromStackSlot(MBB, InsertPt, DstReg, FrameIndex, 3053 getRegClass(DstReg), &TRI); 3054 return &*--InsertPt; 3055 } 3056 3057 // Handle cases like spilling def of: 3058 // 3059 // %0:sub_32<def,read-undef> = COPY %wzr; GPR64common:%0 3060 // 3061 // where the physical register source can be widened and stored to the full 3062 // virtual reg destination stack slot, in this case producing: 3063 // 3064 // STRXui %xzr, %stack.0 3065 // 3066 if (IsSpill && DstMO.isUndef() && 3067 TargetRegisterInfo::isPhysicalRegister(SrcReg)) { 3068 assert(SrcMO.getSubReg() == 0 && 3069 "Unexpected subreg on physical register"); 3070 const TargetRegisterClass *SpillRC; 3071 unsigned SpillSubreg; 3072 switch (DstMO.getSubReg()) { 3073 default: 3074 SpillRC = nullptr; 3075 break; 3076 case AArch64::sub_32: 3077 case AArch64::ssub: 3078 if (AArch64::GPR32RegClass.contains(SrcReg)) { 3079 SpillRC = &AArch64::GPR64RegClass; 3080 SpillSubreg = AArch64::sub_32; 3081 } else if (AArch64::FPR32RegClass.contains(SrcReg)) { 3082 SpillRC = &AArch64::FPR64RegClass; 3083 SpillSubreg = AArch64::ssub; 3084 } else 3085 SpillRC = nullptr; 3086 break; 3087 case AArch64::dsub: 3088 if (AArch64::FPR64RegClass.contains(SrcReg)) { 3089 SpillRC = &AArch64::FPR128RegClass; 3090 SpillSubreg = AArch64::dsub; 3091 } else 3092 SpillRC = nullptr; 3093 break; 3094 } 3095 3096 if (SpillRC) 3097 if (unsigned WidenedSrcReg = 3098 TRI.getMatchingSuperReg(SrcReg, SpillSubreg, SpillRC)) { 3099 storeRegToStackSlot(MBB, InsertPt, WidenedSrcReg, SrcMO.isKill(), 3100 FrameIndex, SpillRC, &TRI); 3101 return &*--InsertPt; 3102 } 3103 } 3104 3105 // Handle cases like filling use of: 3106 // 3107 // %0:sub_32<def,read-undef> = COPY %1; GPR64:%0, GPR32:%1 3108 // 3109 // where we can load the full virtual reg source stack slot, into the subreg 3110 // destination, in this case producing: 3111 // 3112 // LDRWui %0:sub_32<def,read-undef>, %stack.0 3113 // 3114 if (IsFill && SrcMO.getSubReg() == 0 && DstMO.isUndef()) { 3115 const TargetRegisterClass *FillRC; 3116 switch (DstMO.getSubReg()) { 3117 default: 3118 FillRC = nullptr; 3119 break; 3120 case AArch64::sub_32: 3121 FillRC = &AArch64::GPR32RegClass; 3122 break; 3123 case AArch64::ssub: 3124 FillRC = &AArch64::FPR32RegClass; 3125 break; 3126 case AArch64::dsub: 3127 FillRC = &AArch64::FPR64RegClass; 3128 break; 3129 } 3130 3131 if (FillRC) { 3132 assert(TRI.getRegSizeInBits(*getRegClass(SrcReg)) == 3133 TRI.getRegSizeInBits(*FillRC) && 3134 "Mismatched regclass size on folded subreg COPY"); 3135 loadRegFromStackSlot(MBB, InsertPt, DstReg, FrameIndex, FillRC, &TRI); 3136 MachineInstr &LoadMI = *--InsertPt; 3137 MachineOperand &LoadDst = LoadMI.getOperand(0); 3138 assert(LoadDst.getSubReg() == 0 && "unexpected subreg on fill load"); 3139 LoadDst.setSubReg(DstMO.getSubReg()); 3140 LoadDst.setIsUndef(); 3141 return &LoadMI; 3142 } 3143 } 3144 } 3145 3146 // Cannot fold. 3147 return nullptr; 3148 } 3149 3150 int llvm::isAArch64FrameOffsetLegal(const MachineInstr &MI, int &Offset, 3151 bool *OutUseUnscaledOp, 3152 unsigned *OutUnscaledOp, 3153 int *EmittableOffset) { 3154 int Scale = 1; 3155 bool IsSigned = false; 3156 // The ImmIdx should be changed case by case if it is not 2. 3157 unsigned ImmIdx = 2; 3158 unsigned UnscaledOp = 0; 3159 // Set output values in case of early exit. 3160 if (EmittableOffset) 3161 *EmittableOffset = 0; 3162 if (OutUseUnscaledOp) 3163 *OutUseUnscaledOp = false; 3164 if (OutUnscaledOp) 3165 *OutUnscaledOp = 0; 3166 switch (MI.getOpcode()) { 3167 default: 3168 llvm_unreachable("unhandled opcode in rewriteAArch64FrameIndex"); 3169 // Vector spills/fills can't take an immediate offset. 3170 case AArch64::LD1Twov2d: 3171 case AArch64::LD1Threev2d: 3172 case AArch64::LD1Fourv2d: 3173 case AArch64::LD1Twov1d: 3174 case AArch64::LD1Threev1d: 3175 case AArch64::LD1Fourv1d: 3176 case AArch64::ST1Twov2d: 3177 case AArch64::ST1Threev2d: 3178 case AArch64::ST1Fourv2d: 3179 case AArch64::ST1Twov1d: 3180 case AArch64::ST1Threev1d: 3181 case AArch64::ST1Fourv1d: 3182 return AArch64FrameOffsetCannotUpdate; 3183 case AArch64::PRFMui: 3184 Scale = 8; 3185 UnscaledOp = AArch64::PRFUMi; 3186 break; 3187 case AArch64::LDRXui: 3188 Scale = 8; 3189 UnscaledOp = AArch64::LDURXi; 3190 break; 3191 case AArch64::LDRWui: 3192 Scale = 4; 3193 UnscaledOp = AArch64::LDURWi; 3194 break; 3195 case AArch64::LDRBui: 3196 Scale = 1; 3197 UnscaledOp = AArch64::LDURBi; 3198 break; 3199 case AArch64::LDRHui: 3200 Scale = 2; 3201 UnscaledOp = AArch64::LDURHi; 3202 break; 3203 case AArch64::LDRSui: 3204 Scale = 4; 3205 UnscaledOp = AArch64::LDURSi; 3206 break; 3207 case AArch64::LDRDui: 3208 Scale = 8; 3209 UnscaledOp = AArch64::LDURDi; 3210 break; 3211 case AArch64::LDRQui: 3212 Scale = 16; 3213 UnscaledOp = AArch64::LDURQi; 3214 break; 3215 case AArch64::LDRBBui: 3216 Scale = 1; 3217 UnscaledOp = AArch64::LDURBBi; 3218 break; 3219 case AArch64::LDRHHui: 3220 Scale = 2; 3221 UnscaledOp = AArch64::LDURHHi; 3222 break; 3223 case AArch64::LDRSBXui: 3224 Scale = 1; 3225 UnscaledOp = AArch64::LDURSBXi; 3226 break; 3227 case AArch64::LDRSBWui: 3228 Scale = 1; 3229 UnscaledOp = AArch64::LDURSBWi; 3230 break; 3231 case AArch64::LDRSHXui: 3232 Scale = 2; 3233 UnscaledOp = AArch64::LDURSHXi; 3234 break; 3235 case AArch64::LDRSHWui: 3236 Scale = 2; 3237 UnscaledOp = AArch64::LDURSHWi; 3238 break; 3239 case AArch64::LDRSWui: 3240 Scale = 4; 3241 UnscaledOp = AArch64::LDURSWi; 3242 break; 3243 3244 case AArch64::STRXui: 3245 Scale = 8; 3246 UnscaledOp = AArch64::STURXi; 3247 break; 3248 case AArch64::STRWui: 3249 Scale = 4; 3250 UnscaledOp = AArch64::STURWi; 3251 break; 3252 case AArch64::STRBui: 3253 Scale = 1; 3254 UnscaledOp = AArch64::STURBi; 3255 break; 3256 case AArch64::STRHui: 3257 Scale = 2; 3258 UnscaledOp = AArch64::STURHi; 3259 break; 3260 case AArch64::STRSui: 3261 Scale = 4; 3262 UnscaledOp = AArch64::STURSi; 3263 break; 3264 case AArch64::STRDui: 3265 Scale = 8; 3266 UnscaledOp = AArch64::STURDi; 3267 break; 3268 case AArch64::STRQui: 3269 Scale = 16; 3270 UnscaledOp = AArch64::STURQi; 3271 break; 3272 case AArch64::STRBBui: 3273 Scale = 1; 3274 UnscaledOp = AArch64::STURBBi; 3275 break; 3276 case AArch64::STRHHui: 3277 Scale = 2; 3278 UnscaledOp = AArch64::STURHHi; 3279 break; 3280 3281 case AArch64::LDPXi: 3282 case AArch64::LDPDi: 3283 case AArch64::STPXi: 3284 case AArch64::STPDi: 3285 case AArch64::LDNPXi: 3286 case AArch64::LDNPDi: 3287 case AArch64::STNPXi: 3288 case AArch64::STNPDi: 3289 ImmIdx = 3; 3290 IsSigned = true; 3291 Scale = 8; 3292 break; 3293 case AArch64::LDPQi: 3294 case AArch64::STPQi: 3295 case AArch64::LDNPQi: 3296 case AArch64::STNPQi: 3297 ImmIdx = 3; 3298 IsSigned = true; 3299 Scale = 16; 3300 break; 3301 case AArch64::LDPWi: 3302 case AArch64::LDPSi: 3303 case AArch64::STPWi: 3304 case AArch64::STPSi: 3305 case AArch64::LDNPWi: 3306 case AArch64::LDNPSi: 3307 case AArch64::STNPWi: 3308 case AArch64::STNPSi: 3309 ImmIdx = 3; 3310 IsSigned = true; 3311 Scale = 4; 3312 break; 3313 3314 case AArch64::LDURXi: 3315 case AArch64::LDURWi: 3316 case AArch64::LDURBi: 3317 case AArch64::LDURHi: 3318 case AArch64::LDURSi: 3319 case AArch64::LDURDi: 3320 case AArch64::LDURQi: 3321 case AArch64::LDURHHi: 3322 case AArch64::LDURBBi: 3323 case AArch64::LDURSBXi: 3324 case AArch64::LDURSBWi: 3325 case AArch64::LDURSHXi: 3326 case AArch64::LDURSHWi: 3327 case AArch64::LDURSWi: 3328 case AArch64::STURXi: 3329 case AArch64::STURWi: 3330 case AArch64::STURBi: 3331 case AArch64::STURHi: 3332 case AArch64::STURSi: 3333 case AArch64::STURDi: 3334 case AArch64::STURQi: 3335 case AArch64::STURBBi: 3336 case AArch64::STURHHi: 3337 Scale = 1; 3338 break; 3339 } 3340 3341 Offset += MI.getOperand(ImmIdx).getImm() * Scale; 3342 3343 bool useUnscaledOp = false; 3344 // If the offset doesn't match the scale, we rewrite the instruction to 3345 // use the unscaled instruction instead. Likewise, if we have a negative 3346 // offset (and have an unscaled op to use). 3347 if ((Offset & (Scale - 1)) != 0 || (Offset < 0 && UnscaledOp != 0)) 3348 useUnscaledOp = true; 3349 3350 // Use an unscaled addressing mode if the instruction has a negative offset 3351 // (or if the instruction is already using an unscaled addressing mode). 3352 unsigned MaskBits; 3353 if (IsSigned) { 3354 // ldp/stp instructions. 3355 MaskBits = 7; 3356 Offset /= Scale; 3357 } else if (UnscaledOp == 0 || useUnscaledOp) { 3358 MaskBits = 9; 3359 IsSigned = true; 3360 Scale = 1; 3361 } else { 3362 MaskBits = 12; 3363 IsSigned = false; 3364 Offset /= Scale; 3365 } 3366 3367 // Attempt to fold address computation. 3368 int MaxOff = (1 << (MaskBits - IsSigned)) - 1; 3369 int MinOff = (IsSigned ? (-MaxOff - 1) : 0); 3370 if (Offset >= MinOff && Offset <= MaxOff) { 3371 if (EmittableOffset) 3372 *EmittableOffset = Offset; 3373 Offset = 0; 3374 } else { 3375 int NewOff = Offset < 0 ? MinOff : MaxOff; 3376 if (EmittableOffset) 3377 *EmittableOffset = NewOff; 3378 Offset = (Offset - NewOff) * Scale; 3379 } 3380 if (OutUseUnscaledOp) 3381 *OutUseUnscaledOp = useUnscaledOp; 3382 if (OutUnscaledOp) 3383 *OutUnscaledOp = UnscaledOp; 3384 return AArch64FrameOffsetCanUpdate | 3385 (Offset == 0 ? AArch64FrameOffsetIsLegal : 0); 3386 } 3387 3388 bool llvm::rewriteAArch64FrameIndex(MachineInstr &MI, unsigned FrameRegIdx, 3389 unsigned FrameReg, int &Offset, 3390 const AArch64InstrInfo *TII) { 3391 unsigned Opcode = MI.getOpcode(); 3392 unsigned ImmIdx = FrameRegIdx + 1; 3393 3394 if (Opcode == AArch64::ADDSXri || Opcode == AArch64::ADDXri) { 3395 Offset += MI.getOperand(ImmIdx).getImm(); 3396 emitFrameOffset(*MI.getParent(), MI, MI.getDebugLoc(), 3397 MI.getOperand(0).getReg(), FrameReg, Offset, TII, 3398 MachineInstr::NoFlags, (Opcode == AArch64::ADDSXri)); 3399 MI.eraseFromParent(); 3400 Offset = 0; 3401 return true; 3402 } 3403 3404 int NewOffset; 3405 unsigned UnscaledOp; 3406 bool UseUnscaledOp; 3407 int Status = isAArch64FrameOffsetLegal(MI, Offset, &UseUnscaledOp, 3408 &UnscaledOp, &NewOffset); 3409 if (Status & AArch64FrameOffsetCanUpdate) { 3410 if (Status & AArch64FrameOffsetIsLegal) 3411 // Replace the FrameIndex with FrameReg. 3412 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false); 3413 if (UseUnscaledOp) 3414 MI.setDesc(TII->get(UnscaledOp)); 3415 3416 MI.getOperand(ImmIdx).ChangeToImmediate(NewOffset); 3417 return Offset == 0; 3418 } 3419 3420 return false; 3421 } 3422 3423 void AArch64InstrInfo::getNoop(MCInst &NopInst) const { 3424 NopInst.setOpcode(AArch64::HINT); 3425 NopInst.addOperand(MCOperand::createImm(0)); 3426 } 3427 3428 // AArch64 supports MachineCombiner. 3429 bool AArch64InstrInfo::useMachineCombiner() const { return true; } 3430 3431 // True when Opc sets flag 3432 static bool isCombineInstrSettingFlag(unsigned Opc) { 3433 switch (Opc) { 3434 case AArch64::ADDSWrr: 3435 case AArch64::ADDSWri: 3436 case AArch64::ADDSXrr: 3437 case AArch64::ADDSXri: 3438 case AArch64::SUBSWrr: 3439 case AArch64::SUBSXrr: 3440 // Note: MSUB Wd,Wn,Wm,Wi -> Wd = Wi - WnxWm, not Wd=WnxWm - Wi. 3441 case AArch64::SUBSWri: 3442 case AArch64::SUBSXri: 3443 return true; 3444 default: 3445 break; 3446 } 3447 return false; 3448 } 3449 3450 // 32b Opcodes that can be combined with a MUL 3451 static bool isCombineInstrCandidate32(unsigned Opc) { 3452 switch (Opc) { 3453 case AArch64::ADDWrr: 3454 case AArch64::ADDWri: 3455 case AArch64::SUBWrr: 3456 case AArch64::ADDSWrr: 3457 case AArch64::ADDSWri: 3458 case AArch64::SUBSWrr: 3459 // Note: MSUB Wd,Wn,Wm,Wi -> Wd = Wi - WnxWm, not Wd=WnxWm - Wi. 3460 case AArch64::SUBWri: 3461 case AArch64::SUBSWri: 3462 return true; 3463 default: 3464 break; 3465 } 3466 return false; 3467 } 3468 3469 // 64b Opcodes that can be combined with a MUL 3470 static bool isCombineInstrCandidate64(unsigned Opc) { 3471 switch (Opc) { 3472 case AArch64::ADDXrr: 3473 case AArch64::ADDXri: 3474 case AArch64::SUBXrr: 3475 case AArch64::ADDSXrr: 3476 case AArch64::ADDSXri: 3477 case AArch64::SUBSXrr: 3478 // Note: MSUB Wd,Wn,Wm,Wi -> Wd = Wi - WnxWm, not Wd=WnxWm - Wi. 3479 case AArch64::SUBXri: 3480 case AArch64::SUBSXri: 3481 return true; 3482 default: 3483 break; 3484 } 3485 return false; 3486 } 3487 3488 // FP Opcodes that can be combined with a FMUL 3489 static bool isCombineInstrCandidateFP(const MachineInstr &Inst) { 3490 switch (Inst.getOpcode()) { 3491 default: 3492 break; 3493 case AArch64::FADDSrr: 3494 case AArch64::FADDDrr: 3495 case AArch64::FADDv2f32: 3496 case AArch64::FADDv2f64: 3497 case AArch64::FADDv4f32: 3498 case AArch64::FSUBSrr: 3499 case AArch64::FSUBDrr: 3500 case AArch64::FSUBv2f32: 3501 case AArch64::FSUBv2f64: 3502 case AArch64::FSUBv4f32: 3503 TargetOptions Options = Inst.getParent()->getParent()->getTarget().Options; 3504 return (Options.UnsafeFPMath || 3505 Options.AllowFPOpFusion == FPOpFusion::Fast); 3506 } 3507 return false; 3508 } 3509 3510 // Opcodes that can be combined with a MUL 3511 static bool isCombineInstrCandidate(unsigned Opc) { 3512 return (isCombineInstrCandidate32(Opc) || isCombineInstrCandidate64(Opc)); 3513 } 3514 3515 // 3516 // Utility routine that checks if \param MO is defined by an 3517 // \param CombineOpc instruction in the basic block \param MBB 3518 static bool canCombine(MachineBasicBlock &MBB, MachineOperand &MO, 3519 unsigned CombineOpc, unsigned ZeroReg = 0, 3520 bool CheckZeroReg = false) { 3521 MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo(); 3522 MachineInstr *MI = nullptr; 3523 3524 if (MO.isReg() && TargetRegisterInfo::isVirtualRegister(MO.getReg())) 3525 MI = MRI.getUniqueVRegDef(MO.getReg()); 3526 // And it needs to be in the trace (otherwise, it won't have a depth). 3527 if (!MI || MI->getParent() != &MBB || (unsigned)MI->getOpcode() != CombineOpc) 3528 return false; 3529 // Must only used by the user we combine with. 3530 if (!MRI.hasOneNonDBGUse(MI->getOperand(0).getReg())) 3531 return false; 3532 3533 if (CheckZeroReg) { 3534 assert(MI->getNumOperands() >= 4 && MI->getOperand(0).isReg() && 3535 MI->getOperand(1).isReg() && MI->getOperand(2).isReg() && 3536 MI->getOperand(3).isReg() && "MAdd/MSub must have a least 4 regs"); 3537 // The third input reg must be zero. 3538 if (MI->getOperand(3).getReg() != ZeroReg) 3539 return false; 3540 } 3541 3542 return true; 3543 } 3544 3545 // 3546 // Is \param MO defined by an integer multiply and can be combined? 3547 static bool canCombineWithMUL(MachineBasicBlock &MBB, MachineOperand &MO, 3548 unsigned MulOpc, unsigned ZeroReg) { 3549 return canCombine(MBB, MO, MulOpc, ZeroReg, true); 3550 } 3551 3552 // 3553 // Is \param MO defined by a floating-point multiply and can be combined? 3554 static bool canCombineWithFMUL(MachineBasicBlock &MBB, MachineOperand &MO, 3555 unsigned MulOpc) { 3556 return canCombine(MBB, MO, MulOpc); 3557 } 3558 3559 // TODO: There are many more machine instruction opcodes to match: 3560 // 1. Other data types (integer, vectors) 3561 // 2. Other math / logic operations (xor, or) 3562 // 3. Other forms of the same operation (intrinsics and other variants) 3563 bool AArch64InstrInfo::isAssociativeAndCommutative( 3564 const MachineInstr &Inst) const { 3565 switch (Inst.getOpcode()) { 3566 case AArch64::FADDDrr: 3567 case AArch64::FADDSrr: 3568 case AArch64::FADDv2f32: 3569 case AArch64::FADDv2f64: 3570 case AArch64::FADDv4f32: 3571 case AArch64::FMULDrr: 3572 case AArch64::FMULSrr: 3573 case AArch64::FMULX32: 3574 case AArch64::FMULX64: 3575 case AArch64::FMULXv2f32: 3576 case AArch64::FMULXv2f64: 3577 case AArch64::FMULXv4f32: 3578 case AArch64::FMULv2f32: 3579 case AArch64::FMULv2f64: 3580 case AArch64::FMULv4f32: 3581 return Inst.getParent()->getParent()->getTarget().Options.UnsafeFPMath; 3582 default: 3583 return false; 3584 } 3585 } 3586 3587 /// Find instructions that can be turned into madd. 3588 static bool getMaddPatterns(MachineInstr &Root, 3589 SmallVectorImpl<MachineCombinerPattern> &Patterns) { 3590 unsigned Opc = Root.getOpcode(); 3591 MachineBasicBlock &MBB = *Root.getParent(); 3592 bool Found = false; 3593 3594 if (!isCombineInstrCandidate(Opc)) 3595 return false; 3596 if (isCombineInstrSettingFlag(Opc)) { 3597 int Cmp_NZCV = Root.findRegisterDefOperandIdx(AArch64::NZCV, true); 3598 // When NZCV is live bail out. 3599 if (Cmp_NZCV == -1) 3600 return false; 3601 unsigned NewOpc = convertToNonFlagSettingOpc(Root); 3602 // When opcode can't change bail out. 3603 // CHECKME: do we miss any cases for opcode conversion? 3604 if (NewOpc == Opc) 3605 return false; 3606 Opc = NewOpc; 3607 } 3608 3609 switch (Opc) { 3610 default: 3611 break; 3612 case AArch64::ADDWrr: 3613 assert(Root.getOperand(1).isReg() && Root.getOperand(2).isReg() && 3614 "ADDWrr does not have register operands"); 3615 if (canCombineWithMUL(MBB, Root.getOperand(1), AArch64::MADDWrrr, 3616 AArch64::WZR)) { 3617 Patterns.push_back(MachineCombinerPattern::MULADDW_OP1); 3618 Found = true; 3619 } 3620 if (canCombineWithMUL(MBB, Root.getOperand(2), AArch64::MADDWrrr, 3621 AArch64::WZR)) { 3622 Patterns.push_back(MachineCombinerPattern::MULADDW_OP2); 3623 Found = true; 3624 } 3625 break; 3626 case AArch64::ADDXrr: 3627 if (canCombineWithMUL(MBB, Root.getOperand(1), AArch64::MADDXrrr, 3628 AArch64::XZR)) { 3629 Patterns.push_back(MachineCombinerPattern::MULADDX_OP1); 3630 Found = true; 3631 } 3632 if (canCombineWithMUL(MBB, Root.getOperand(2), AArch64::MADDXrrr, 3633 AArch64::XZR)) { 3634 Patterns.push_back(MachineCombinerPattern::MULADDX_OP2); 3635 Found = true; 3636 } 3637 break; 3638 case AArch64::SUBWrr: 3639 if (canCombineWithMUL(MBB, Root.getOperand(1), AArch64::MADDWrrr, 3640 AArch64::WZR)) { 3641 Patterns.push_back(MachineCombinerPattern::MULSUBW_OP1); 3642 Found = true; 3643 } 3644 if (canCombineWithMUL(MBB, Root.getOperand(2), AArch64::MADDWrrr, 3645 AArch64::WZR)) { 3646 Patterns.push_back(MachineCombinerPattern::MULSUBW_OP2); 3647 Found = true; 3648 } 3649 break; 3650 case AArch64::SUBXrr: 3651 if (canCombineWithMUL(MBB, Root.getOperand(1), AArch64::MADDXrrr, 3652 AArch64::XZR)) { 3653 Patterns.push_back(MachineCombinerPattern::MULSUBX_OP1); 3654 Found = true; 3655 } 3656 if (canCombineWithMUL(MBB, Root.getOperand(2), AArch64::MADDXrrr, 3657 AArch64::XZR)) { 3658 Patterns.push_back(MachineCombinerPattern::MULSUBX_OP2); 3659 Found = true; 3660 } 3661 break; 3662 case AArch64::ADDWri: 3663 if (canCombineWithMUL(MBB, Root.getOperand(1), AArch64::MADDWrrr, 3664 AArch64::WZR)) { 3665 Patterns.push_back(MachineCombinerPattern::MULADDWI_OP1); 3666 Found = true; 3667 } 3668 break; 3669 case AArch64::ADDXri: 3670 if (canCombineWithMUL(MBB, Root.getOperand(1), AArch64::MADDXrrr, 3671 AArch64::XZR)) { 3672 Patterns.push_back(MachineCombinerPattern::MULADDXI_OP1); 3673 Found = true; 3674 } 3675 break; 3676 case AArch64::SUBWri: 3677 if (canCombineWithMUL(MBB, Root.getOperand(1), AArch64::MADDWrrr, 3678 AArch64::WZR)) { 3679 Patterns.push_back(MachineCombinerPattern::MULSUBWI_OP1); 3680 Found = true; 3681 } 3682 break; 3683 case AArch64::SUBXri: 3684 if (canCombineWithMUL(MBB, Root.getOperand(1), AArch64::MADDXrrr, 3685 AArch64::XZR)) { 3686 Patterns.push_back(MachineCombinerPattern::MULSUBXI_OP1); 3687 Found = true; 3688 } 3689 break; 3690 } 3691 return Found; 3692 } 3693 /// Floating-Point Support 3694 3695 /// Find instructions that can be turned into madd. 3696 static bool getFMAPatterns(MachineInstr &Root, 3697 SmallVectorImpl<MachineCombinerPattern> &Patterns) { 3698 3699 if (!isCombineInstrCandidateFP(Root)) 3700 return false; 3701 3702 MachineBasicBlock &MBB = *Root.getParent(); 3703 bool Found = false; 3704 3705 switch (Root.getOpcode()) { 3706 default: 3707 assert(false && "Unsupported FP instruction in combiner\n"); 3708 break; 3709 case AArch64::FADDSrr: 3710 assert(Root.getOperand(1).isReg() && Root.getOperand(2).isReg() && 3711 "FADDWrr does not have register operands"); 3712 if (canCombineWithFMUL(MBB, Root.getOperand(1), AArch64::FMULSrr)) { 3713 Patterns.push_back(MachineCombinerPattern::FMULADDS_OP1); 3714 Found = true; 3715 } else if (canCombineWithFMUL(MBB, Root.getOperand(1), 3716 AArch64::FMULv1i32_indexed)) { 3717 Patterns.push_back(MachineCombinerPattern::FMLAv1i32_indexed_OP1); 3718 Found = true; 3719 } 3720 if (canCombineWithFMUL(MBB, Root.getOperand(2), AArch64::FMULSrr)) { 3721 Patterns.push_back(MachineCombinerPattern::FMULADDS_OP2); 3722 Found = true; 3723 } else if (canCombineWithFMUL(MBB, Root.getOperand(2), 3724 AArch64::FMULv1i32_indexed)) { 3725 Patterns.push_back(MachineCombinerPattern::FMLAv1i32_indexed_OP2); 3726 Found = true; 3727 } 3728 break; 3729 case AArch64::FADDDrr: 3730 if (canCombineWithFMUL(MBB, Root.getOperand(1), AArch64::FMULDrr)) { 3731 Patterns.push_back(MachineCombinerPattern::FMULADDD_OP1); 3732 Found = true; 3733 } else if (canCombineWithFMUL(MBB, Root.getOperand(1), 3734 AArch64::FMULv1i64_indexed)) { 3735 Patterns.push_back(MachineCombinerPattern::FMLAv1i64_indexed_OP1); 3736 Found = true; 3737 } 3738 if (canCombineWithFMUL(MBB, Root.getOperand(2), AArch64::FMULDrr)) { 3739 Patterns.push_back(MachineCombinerPattern::FMULADDD_OP2); 3740 Found = true; 3741 } else if (canCombineWithFMUL(MBB, Root.getOperand(2), 3742 AArch64::FMULv1i64_indexed)) { 3743 Patterns.push_back(MachineCombinerPattern::FMLAv1i64_indexed_OP2); 3744 Found = true; 3745 } 3746 break; 3747 case AArch64::FADDv2f32: 3748 if (canCombineWithFMUL(MBB, Root.getOperand(1), 3749 AArch64::FMULv2i32_indexed)) { 3750 Patterns.push_back(MachineCombinerPattern::FMLAv2i32_indexed_OP1); 3751 Found = true; 3752 } else if (canCombineWithFMUL(MBB, Root.getOperand(1), 3753 AArch64::FMULv2f32)) { 3754 Patterns.push_back(MachineCombinerPattern::FMLAv2f32_OP1); 3755 Found = true; 3756 } 3757 if (canCombineWithFMUL(MBB, Root.getOperand(2), 3758 AArch64::FMULv2i32_indexed)) { 3759 Patterns.push_back(MachineCombinerPattern::FMLAv2i32_indexed_OP2); 3760 Found = true; 3761 } else if (canCombineWithFMUL(MBB, Root.getOperand(2), 3762 AArch64::FMULv2f32)) { 3763 Patterns.push_back(MachineCombinerPattern::FMLAv2f32_OP2); 3764 Found = true; 3765 } 3766 break; 3767 case AArch64::FADDv2f64: 3768 if (canCombineWithFMUL(MBB, Root.getOperand(1), 3769 AArch64::FMULv2i64_indexed)) { 3770 Patterns.push_back(MachineCombinerPattern::FMLAv2i64_indexed_OP1); 3771 Found = true; 3772 } else if (canCombineWithFMUL(MBB, Root.getOperand(1), 3773 AArch64::FMULv2f64)) { 3774 Patterns.push_back(MachineCombinerPattern::FMLAv2f64_OP1); 3775 Found = true; 3776 } 3777 if (canCombineWithFMUL(MBB, Root.getOperand(2), 3778 AArch64::FMULv2i64_indexed)) { 3779 Patterns.push_back(MachineCombinerPattern::FMLAv2i64_indexed_OP2); 3780 Found = true; 3781 } else if (canCombineWithFMUL(MBB, Root.getOperand(2), 3782 AArch64::FMULv2f64)) { 3783 Patterns.push_back(MachineCombinerPattern::FMLAv2f64_OP2); 3784 Found = true; 3785 } 3786 break; 3787 case AArch64::FADDv4f32: 3788 if (canCombineWithFMUL(MBB, Root.getOperand(1), 3789 AArch64::FMULv4i32_indexed)) { 3790 Patterns.push_back(MachineCombinerPattern::FMLAv4i32_indexed_OP1); 3791 Found = true; 3792 } else if (canCombineWithFMUL(MBB, Root.getOperand(1), 3793 AArch64::FMULv4f32)) { 3794 Patterns.push_back(MachineCombinerPattern::FMLAv4f32_OP1); 3795 Found = true; 3796 } 3797 if (canCombineWithFMUL(MBB, Root.getOperand(2), 3798 AArch64::FMULv4i32_indexed)) { 3799 Patterns.push_back(MachineCombinerPattern::FMLAv4i32_indexed_OP2); 3800 Found = true; 3801 } else if (canCombineWithFMUL(MBB, Root.getOperand(2), 3802 AArch64::FMULv4f32)) { 3803 Patterns.push_back(MachineCombinerPattern::FMLAv4f32_OP2); 3804 Found = true; 3805 } 3806 break; 3807 3808 case AArch64::FSUBSrr: 3809 if (canCombineWithFMUL(MBB, Root.getOperand(1), AArch64::FMULSrr)) { 3810 Patterns.push_back(MachineCombinerPattern::FMULSUBS_OP1); 3811 Found = true; 3812 } 3813 if (canCombineWithFMUL(MBB, Root.getOperand(2), AArch64::FMULSrr)) { 3814 Patterns.push_back(MachineCombinerPattern::FMULSUBS_OP2); 3815 Found = true; 3816 } else if (canCombineWithFMUL(MBB, Root.getOperand(2), 3817 AArch64::FMULv1i32_indexed)) { 3818 Patterns.push_back(MachineCombinerPattern::FMLSv1i32_indexed_OP2); 3819 Found = true; 3820 } 3821 if (canCombineWithFMUL(MBB, Root.getOperand(1), AArch64::FNMULSrr)) { 3822 Patterns.push_back(MachineCombinerPattern::FNMULSUBS_OP1); 3823 Found = true; 3824 } 3825 break; 3826 case AArch64::FSUBDrr: 3827 if (canCombineWithFMUL(MBB, Root.getOperand(1), AArch64::FMULDrr)) { 3828 Patterns.push_back(MachineCombinerPattern::FMULSUBD_OP1); 3829 Found = true; 3830 } 3831 if (canCombineWithFMUL(MBB, Root.getOperand(2), AArch64::FMULDrr)) { 3832 Patterns.push_back(MachineCombinerPattern::FMULSUBD_OP2); 3833 Found = true; 3834 } else if (canCombineWithFMUL(MBB, Root.getOperand(2), 3835 AArch64::FMULv1i64_indexed)) { 3836 Patterns.push_back(MachineCombinerPattern::FMLSv1i64_indexed_OP2); 3837 Found = true; 3838 } 3839 if (canCombineWithFMUL(MBB, Root.getOperand(1), AArch64::FNMULDrr)) { 3840 Patterns.push_back(MachineCombinerPattern::FNMULSUBD_OP1); 3841 Found = true; 3842 } 3843 break; 3844 case AArch64::FSUBv2f32: 3845 if (canCombineWithFMUL(MBB, Root.getOperand(2), 3846 AArch64::FMULv2i32_indexed)) { 3847 Patterns.push_back(MachineCombinerPattern::FMLSv2i32_indexed_OP2); 3848 Found = true; 3849 } else if (canCombineWithFMUL(MBB, Root.getOperand(2), 3850 AArch64::FMULv2f32)) { 3851 Patterns.push_back(MachineCombinerPattern::FMLSv2f32_OP2); 3852 Found = true; 3853 } 3854 if (canCombineWithFMUL(MBB, Root.getOperand(1), 3855 AArch64::FMULv2i32_indexed)) { 3856 Patterns.push_back(MachineCombinerPattern::FMLSv2i32_indexed_OP1); 3857 Found = true; 3858 } else if (canCombineWithFMUL(MBB, Root.getOperand(1), 3859 AArch64::FMULv2f32)) { 3860 Patterns.push_back(MachineCombinerPattern::FMLSv2f32_OP1); 3861 Found = true; 3862 } 3863 break; 3864 case AArch64::FSUBv2f64: 3865 if (canCombineWithFMUL(MBB, Root.getOperand(2), 3866 AArch64::FMULv2i64_indexed)) { 3867 Patterns.push_back(MachineCombinerPattern::FMLSv2i64_indexed_OP2); 3868 Found = true; 3869 } else if (canCombineWithFMUL(MBB, Root.getOperand(2), 3870 AArch64::FMULv2f64)) { 3871 Patterns.push_back(MachineCombinerPattern::FMLSv2f64_OP2); 3872 Found = true; 3873 } 3874 if (canCombineWithFMUL(MBB, Root.getOperand(1), 3875 AArch64::FMULv2i64_indexed)) { 3876 Patterns.push_back(MachineCombinerPattern::FMLSv2i64_indexed_OP1); 3877 Found = true; 3878 } else if (canCombineWithFMUL(MBB, Root.getOperand(1), 3879 AArch64::FMULv2f64)) { 3880 Patterns.push_back(MachineCombinerPattern::FMLSv2f64_OP1); 3881 Found = true; 3882 } 3883 break; 3884 case AArch64::FSUBv4f32: 3885 if (canCombineWithFMUL(MBB, Root.getOperand(2), 3886 AArch64::FMULv4i32_indexed)) { 3887 Patterns.push_back(MachineCombinerPattern::FMLSv4i32_indexed_OP2); 3888 Found = true; 3889 } else if (canCombineWithFMUL(MBB, Root.getOperand(2), 3890 AArch64::FMULv4f32)) { 3891 Patterns.push_back(MachineCombinerPattern::FMLSv4f32_OP2); 3892 Found = true; 3893 } 3894 if (canCombineWithFMUL(MBB, Root.getOperand(1), 3895 AArch64::FMULv4i32_indexed)) { 3896 Patterns.push_back(MachineCombinerPattern::FMLSv4i32_indexed_OP1); 3897 Found = true; 3898 } else if (canCombineWithFMUL(MBB, Root.getOperand(1), 3899 AArch64::FMULv4f32)) { 3900 Patterns.push_back(MachineCombinerPattern::FMLSv4f32_OP1); 3901 Found = true; 3902 } 3903 break; 3904 } 3905 return Found; 3906 } 3907 3908 /// Return true when a code sequence can improve throughput. It 3909 /// should be called only for instructions in loops. 3910 /// \param Pattern - combiner pattern 3911 bool AArch64InstrInfo::isThroughputPattern( 3912 MachineCombinerPattern Pattern) const { 3913 switch (Pattern) { 3914 default: 3915 break; 3916 case MachineCombinerPattern::FMULADDS_OP1: 3917 case MachineCombinerPattern::FMULADDS_OP2: 3918 case MachineCombinerPattern::FMULSUBS_OP1: 3919 case MachineCombinerPattern::FMULSUBS_OP2: 3920 case MachineCombinerPattern::FMULADDD_OP1: 3921 case MachineCombinerPattern::FMULADDD_OP2: 3922 case MachineCombinerPattern::FMULSUBD_OP1: 3923 case MachineCombinerPattern::FMULSUBD_OP2: 3924 case MachineCombinerPattern::FNMULSUBS_OP1: 3925 case MachineCombinerPattern::FNMULSUBD_OP1: 3926 case MachineCombinerPattern::FMLAv1i32_indexed_OP1: 3927 case MachineCombinerPattern::FMLAv1i32_indexed_OP2: 3928 case MachineCombinerPattern::FMLAv1i64_indexed_OP1: 3929 case MachineCombinerPattern::FMLAv1i64_indexed_OP2: 3930 case MachineCombinerPattern::FMLAv2f32_OP2: 3931 case MachineCombinerPattern::FMLAv2f32_OP1: 3932 case MachineCombinerPattern::FMLAv2f64_OP1: 3933 case MachineCombinerPattern::FMLAv2f64_OP2: 3934 case MachineCombinerPattern::FMLAv2i32_indexed_OP1: 3935 case MachineCombinerPattern::FMLAv2i32_indexed_OP2: 3936 case MachineCombinerPattern::FMLAv2i64_indexed_OP1: 3937 case MachineCombinerPattern::FMLAv2i64_indexed_OP2: 3938 case MachineCombinerPattern::FMLAv4f32_OP1: 3939 case MachineCombinerPattern::FMLAv4f32_OP2: 3940 case MachineCombinerPattern::FMLAv4i32_indexed_OP1: 3941 case MachineCombinerPattern::FMLAv4i32_indexed_OP2: 3942 case MachineCombinerPattern::FMLSv1i32_indexed_OP2: 3943 case MachineCombinerPattern::FMLSv1i64_indexed_OP2: 3944 case MachineCombinerPattern::FMLSv2i32_indexed_OP2: 3945 case MachineCombinerPattern::FMLSv2i64_indexed_OP2: 3946 case MachineCombinerPattern::FMLSv2f32_OP2: 3947 case MachineCombinerPattern::FMLSv2f64_OP2: 3948 case MachineCombinerPattern::FMLSv4i32_indexed_OP2: 3949 case MachineCombinerPattern::FMLSv4f32_OP2: 3950 return true; 3951 } // end switch (Pattern) 3952 return false; 3953 } 3954 /// Return true when there is potentially a faster code sequence for an 3955 /// instruction chain ending in \p Root. All potential patterns are listed in 3956 /// the \p Pattern vector. Pattern should be sorted in priority order since the 3957 /// pattern evaluator stops checking as soon as it finds a faster sequence. 3958 3959 bool AArch64InstrInfo::getMachineCombinerPatterns( 3960 MachineInstr &Root, 3961 SmallVectorImpl<MachineCombinerPattern> &Patterns) const { 3962 // Integer patterns 3963 if (getMaddPatterns(Root, Patterns)) 3964 return true; 3965 // Floating point patterns 3966 if (getFMAPatterns(Root, Patterns)) 3967 return true; 3968 3969 return TargetInstrInfo::getMachineCombinerPatterns(Root, Patterns); 3970 } 3971 3972 enum class FMAInstKind { Default, Indexed, Accumulator }; 3973 /// genFusedMultiply - Generate fused multiply instructions. 3974 /// This function supports both integer and floating point instructions. 3975 /// A typical example: 3976 /// F|MUL I=A,B,0 3977 /// F|ADD R,I,C 3978 /// ==> F|MADD R,A,B,C 3979 /// \param MF Containing MachineFunction 3980 /// \param MRI Register information 3981 /// \param TII Target information 3982 /// \param Root is the F|ADD instruction 3983 /// \param [out] InsInstrs is a vector of machine instructions and will 3984 /// contain the generated madd instruction 3985 /// \param IdxMulOpd is index of operand in Root that is the result of 3986 /// the F|MUL. In the example above IdxMulOpd is 1. 3987 /// \param MaddOpc the opcode fo the f|madd instruction 3988 /// \param RC Register class of operands 3989 /// \param kind of fma instruction (addressing mode) to be generated 3990 /// \param ReplacedAddend is the result register from the instruction 3991 /// replacing the non-combined operand, if any. 3992 static MachineInstr * 3993 genFusedMultiply(MachineFunction &MF, MachineRegisterInfo &MRI, 3994 const TargetInstrInfo *TII, MachineInstr &Root, 3995 SmallVectorImpl<MachineInstr *> &InsInstrs, unsigned IdxMulOpd, 3996 unsigned MaddOpc, const TargetRegisterClass *RC, 3997 FMAInstKind kind = FMAInstKind::Default, 3998 const unsigned *ReplacedAddend = nullptr) { 3999 assert(IdxMulOpd == 1 || IdxMulOpd == 2); 4000 4001 unsigned IdxOtherOpd = IdxMulOpd == 1 ? 2 : 1; 4002 MachineInstr *MUL = MRI.getUniqueVRegDef(Root.getOperand(IdxMulOpd).getReg()); 4003 unsigned ResultReg = Root.getOperand(0).getReg(); 4004 unsigned SrcReg0 = MUL->getOperand(1).getReg(); 4005 bool Src0IsKill = MUL->getOperand(1).isKill(); 4006 unsigned SrcReg1 = MUL->getOperand(2).getReg(); 4007 bool Src1IsKill = MUL->getOperand(2).isKill(); 4008 4009 unsigned SrcReg2; 4010 bool Src2IsKill; 4011 if (ReplacedAddend) { 4012 // If we just generated a new addend, we must be it's only use. 4013 SrcReg2 = *ReplacedAddend; 4014 Src2IsKill = true; 4015 } else { 4016 SrcReg2 = Root.getOperand(IdxOtherOpd).getReg(); 4017 Src2IsKill = Root.getOperand(IdxOtherOpd).isKill(); 4018 } 4019 4020 if (TargetRegisterInfo::isVirtualRegister(ResultReg)) 4021 MRI.constrainRegClass(ResultReg, RC); 4022 if (TargetRegisterInfo::isVirtualRegister(SrcReg0)) 4023 MRI.constrainRegClass(SrcReg0, RC); 4024 if (TargetRegisterInfo::isVirtualRegister(SrcReg1)) 4025 MRI.constrainRegClass(SrcReg1, RC); 4026 if (TargetRegisterInfo::isVirtualRegister(SrcReg2)) 4027 MRI.constrainRegClass(SrcReg2, RC); 4028 4029 MachineInstrBuilder MIB; 4030 if (kind == FMAInstKind::Default) 4031 MIB = BuildMI(MF, Root.getDebugLoc(), TII->get(MaddOpc), ResultReg) 4032 .addReg(SrcReg0, getKillRegState(Src0IsKill)) 4033 .addReg(SrcReg1, getKillRegState(Src1IsKill)) 4034 .addReg(SrcReg2, getKillRegState(Src2IsKill)); 4035 else if (kind == FMAInstKind::Indexed) 4036 MIB = BuildMI(MF, Root.getDebugLoc(), TII->get(MaddOpc), ResultReg) 4037 .addReg(SrcReg2, getKillRegState(Src2IsKill)) 4038 .addReg(SrcReg0, getKillRegState(Src0IsKill)) 4039 .addReg(SrcReg1, getKillRegState(Src1IsKill)) 4040 .addImm(MUL->getOperand(3).getImm()); 4041 else if (kind == FMAInstKind::Accumulator) 4042 MIB = BuildMI(MF, Root.getDebugLoc(), TII->get(MaddOpc), ResultReg) 4043 .addReg(SrcReg2, getKillRegState(Src2IsKill)) 4044 .addReg(SrcReg0, getKillRegState(Src0IsKill)) 4045 .addReg(SrcReg1, getKillRegState(Src1IsKill)); 4046 else 4047 assert(false && "Invalid FMA instruction kind \n"); 4048 // Insert the MADD (MADD, FMA, FMS, FMLA, FMSL) 4049 InsInstrs.push_back(MIB); 4050 return MUL; 4051 } 4052 4053 /// genMaddR - Generate madd instruction and combine mul and add using 4054 /// an extra virtual register 4055 /// Example - an ADD intermediate needs to be stored in a register: 4056 /// MUL I=A,B,0 4057 /// ADD R,I,Imm 4058 /// ==> ORR V, ZR, Imm 4059 /// ==> MADD R,A,B,V 4060 /// \param MF Containing MachineFunction 4061 /// \param MRI Register information 4062 /// \param TII Target information 4063 /// \param Root is the ADD instruction 4064 /// \param [out] InsInstrs is a vector of machine instructions and will 4065 /// contain the generated madd instruction 4066 /// \param IdxMulOpd is index of operand in Root that is the result of 4067 /// the MUL. In the example above IdxMulOpd is 1. 4068 /// \param MaddOpc the opcode fo the madd instruction 4069 /// \param VR is a virtual register that holds the value of an ADD operand 4070 /// (V in the example above). 4071 /// \param RC Register class of operands 4072 static MachineInstr *genMaddR(MachineFunction &MF, MachineRegisterInfo &MRI, 4073 const TargetInstrInfo *TII, MachineInstr &Root, 4074 SmallVectorImpl<MachineInstr *> &InsInstrs, 4075 unsigned IdxMulOpd, unsigned MaddOpc, unsigned VR, 4076 const TargetRegisterClass *RC) { 4077 assert(IdxMulOpd == 1 || IdxMulOpd == 2); 4078 4079 MachineInstr *MUL = MRI.getUniqueVRegDef(Root.getOperand(IdxMulOpd).getReg()); 4080 unsigned ResultReg = Root.getOperand(0).getReg(); 4081 unsigned SrcReg0 = MUL->getOperand(1).getReg(); 4082 bool Src0IsKill = MUL->getOperand(1).isKill(); 4083 unsigned SrcReg1 = MUL->getOperand(2).getReg(); 4084 bool Src1IsKill = MUL->getOperand(2).isKill(); 4085 4086 if (TargetRegisterInfo::isVirtualRegister(ResultReg)) 4087 MRI.constrainRegClass(ResultReg, RC); 4088 if (TargetRegisterInfo::isVirtualRegister(SrcReg0)) 4089 MRI.constrainRegClass(SrcReg0, RC); 4090 if (TargetRegisterInfo::isVirtualRegister(SrcReg1)) 4091 MRI.constrainRegClass(SrcReg1, RC); 4092 if (TargetRegisterInfo::isVirtualRegister(VR)) 4093 MRI.constrainRegClass(VR, RC); 4094 4095 MachineInstrBuilder MIB = 4096 BuildMI(MF, Root.getDebugLoc(), TII->get(MaddOpc), ResultReg) 4097 .addReg(SrcReg0, getKillRegState(Src0IsKill)) 4098 .addReg(SrcReg1, getKillRegState(Src1IsKill)) 4099 .addReg(VR); 4100 // Insert the MADD 4101 InsInstrs.push_back(MIB); 4102 return MUL; 4103 } 4104 4105 /// When getMachineCombinerPatterns() finds potential patterns, 4106 /// this function generates the instructions that could replace the 4107 /// original code sequence 4108 void AArch64InstrInfo::genAlternativeCodeSequence( 4109 MachineInstr &Root, MachineCombinerPattern Pattern, 4110 SmallVectorImpl<MachineInstr *> &InsInstrs, 4111 SmallVectorImpl<MachineInstr *> &DelInstrs, 4112 DenseMap<unsigned, unsigned> &InstrIdxForVirtReg) const { 4113 MachineBasicBlock &MBB = *Root.getParent(); 4114 MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo(); 4115 MachineFunction &MF = *MBB.getParent(); 4116 const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo(); 4117 4118 MachineInstr *MUL; 4119 const TargetRegisterClass *RC; 4120 unsigned Opc; 4121 switch (Pattern) { 4122 default: 4123 // Reassociate instructions. 4124 TargetInstrInfo::genAlternativeCodeSequence(Root, Pattern, InsInstrs, 4125 DelInstrs, InstrIdxForVirtReg); 4126 return; 4127 case MachineCombinerPattern::MULADDW_OP1: 4128 case MachineCombinerPattern::MULADDX_OP1: 4129 // MUL I=A,B,0 4130 // ADD R,I,C 4131 // ==> MADD R,A,B,C 4132 // --- Create(MADD); 4133 if (Pattern == MachineCombinerPattern::MULADDW_OP1) { 4134 Opc = AArch64::MADDWrrr; 4135 RC = &AArch64::GPR32RegClass; 4136 } else { 4137 Opc = AArch64::MADDXrrr; 4138 RC = &AArch64::GPR64RegClass; 4139 } 4140 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC); 4141 break; 4142 case MachineCombinerPattern::MULADDW_OP2: 4143 case MachineCombinerPattern::MULADDX_OP2: 4144 // MUL I=A,B,0 4145 // ADD R,C,I 4146 // ==> MADD R,A,B,C 4147 // --- Create(MADD); 4148 if (Pattern == MachineCombinerPattern::MULADDW_OP2) { 4149 Opc = AArch64::MADDWrrr; 4150 RC = &AArch64::GPR32RegClass; 4151 } else { 4152 Opc = AArch64::MADDXrrr; 4153 RC = &AArch64::GPR64RegClass; 4154 } 4155 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC); 4156 break; 4157 case MachineCombinerPattern::MULADDWI_OP1: 4158 case MachineCombinerPattern::MULADDXI_OP1: { 4159 // MUL I=A,B,0 4160 // ADD R,I,Imm 4161 // ==> ORR V, ZR, Imm 4162 // ==> MADD R,A,B,V 4163 // --- Create(MADD); 4164 const TargetRegisterClass *OrrRC; 4165 unsigned BitSize, OrrOpc, ZeroReg; 4166 if (Pattern == MachineCombinerPattern::MULADDWI_OP1) { 4167 OrrOpc = AArch64::ORRWri; 4168 OrrRC = &AArch64::GPR32spRegClass; 4169 BitSize = 32; 4170 ZeroReg = AArch64::WZR; 4171 Opc = AArch64::MADDWrrr; 4172 RC = &AArch64::GPR32RegClass; 4173 } else { 4174 OrrOpc = AArch64::ORRXri; 4175 OrrRC = &AArch64::GPR64spRegClass; 4176 BitSize = 64; 4177 ZeroReg = AArch64::XZR; 4178 Opc = AArch64::MADDXrrr; 4179 RC = &AArch64::GPR64RegClass; 4180 } 4181 unsigned NewVR = MRI.createVirtualRegister(OrrRC); 4182 uint64_t Imm = Root.getOperand(2).getImm(); 4183 4184 if (Root.getOperand(3).isImm()) { 4185 unsigned Val = Root.getOperand(3).getImm(); 4186 Imm = Imm << Val; 4187 } 4188 uint64_t UImm = SignExtend64(Imm, BitSize); 4189 uint64_t Encoding; 4190 if (AArch64_AM::processLogicalImmediate(UImm, BitSize, Encoding)) { 4191 MachineInstrBuilder MIB1 = 4192 BuildMI(MF, Root.getDebugLoc(), TII->get(OrrOpc), NewVR) 4193 .addReg(ZeroReg) 4194 .addImm(Encoding); 4195 InsInstrs.push_back(MIB1); 4196 InstrIdxForVirtReg.insert(std::make_pair(NewVR, 0)); 4197 MUL = genMaddR(MF, MRI, TII, Root, InsInstrs, 1, Opc, NewVR, RC); 4198 } 4199 break; 4200 } 4201 case MachineCombinerPattern::MULSUBW_OP1: 4202 case MachineCombinerPattern::MULSUBX_OP1: { 4203 // MUL I=A,B,0 4204 // SUB R,I, C 4205 // ==> SUB V, 0, C 4206 // ==> MADD R,A,B,V // = -C + A*B 4207 // --- Create(MADD); 4208 const TargetRegisterClass *SubRC; 4209 unsigned SubOpc, ZeroReg; 4210 if (Pattern == MachineCombinerPattern::MULSUBW_OP1) { 4211 SubOpc = AArch64::SUBWrr; 4212 SubRC = &AArch64::GPR32spRegClass; 4213 ZeroReg = AArch64::WZR; 4214 Opc = AArch64::MADDWrrr; 4215 RC = &AArch64::GPR32RegClass; 4216 } else { 4217 SubOpc = AArch64::SUBXrr; 4218 SubRC = &AArch64::GPR64spRegClass; 4219 ZeroReg = AArch64::XZR; 4220 Opc = AArch64::MADDXrrr; 4221 RC = &AArch64::GPR64RegClass; 4222 } 4223 unsigned NewVR = MRI.createVirtualRegister(SubRC); 4224 // SUB NewVR, 0, C 4225 MachineInstrBuilder MIB1 = 4226 BuildMI(MF, Root.getDebugLoc(), TII->get(SubOpc), NewVR) 4227 .addReg(ZeroReg) 4228 .add(Root.getOperand(2)); 4229 InsInstrs.push_back(MIB1); 4230 InstrIdxForVirtReg.insert(std::make_pair(NewVR, 0)); 4231 MUL = genMaddR(MF, MRI, TII, Root, InsInstrs, 1, Opc, NewVR, RC); 4232 break; 4233 } 4234 case MachineCombinerPattern::MULSUBW_OP2: 4235 case MachineCombinerPattern::MULSUBX_OP2: 4236 // MUL I=A,B,0 4237 // SUB R,C,I 4238 // ==> MSUB R,A,B,C (computes C - A*B) 4239 // --- Create(MSUB); 4240 if (Pattern == MachineCombinerPattern::MULSUBW_OP2) { 4241 Opc = AArch64::MSUBWrrr; 4242 RC = &AArch64::GPR32RegClass; 4243 } else { 4244 Opc = AArch64::MSUBXrrr; 4245 RC = &AArch64::GPR64RegClass; 4246 } 4247 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC); 4248 break; 4249 case MachineCombinerPattern::MULSUBWI_OP1: 4250 case MachineCombinerPattern::MULSUBXI_OP1: { 4251 // MUL I=A,B,0 4252 // SUB R,I, Imm 4253 // ==> ORR V, ZR, -Imm 4254 // ==> MADD R,A,B,V // = -Imm + A*B 4255 // --- Create(MADD); 4256 const TargetRegisterClass *OrrRC; 4257 unsigned BitSize, OrrOpc, ZeroReg; 4258 if (Pattern == MachineCombinerPattern::MULSUBWI_OP1) { 4259 OrrOpc = AArch64::ORRWri; 4260 OrrRC = &AArch64::GPR32spRegClass; 4261 BitSize = 32; 4262 ZeroReg = AArch64::WZR; 4263 Opc = AArch64::MADDWrrr; 4264 RC = &AArch64::GPR32RegClass; 4265 } else { 4266 OrrOpc = AArch64::ORRXri; 4267 OrrRC = &AArch64::GPR64spRegClass; 4268 BitSize = 64; 4269 ZeroReg = AArch64::XZR; 4270 Opc = AArch64::MADDXrrr; 4271 RC = &AArch64::GPR64RegClass; 4272 } 4273 unsigned NewVR = MRI.createVirtualRegister(OrrRC); 4274 uint64_t Imm = Root.getOperand(2).getImm(); 4275 if (Root.getOperand(3).isImm()) { 4276 unsigned Val = Root.getOperand(3).getImm(); 4277 Imm = Imm << Val; 4278 } 4279 uint64_t UImm = SignExtend64(-Imm, BitSize); 4280 uint64_t Encoding; 4281 if (AArch64_AM::processLogicalImmediate(UImm, BitSize, Encoding)) { 4282 MachineInstrBuilder MIB1 = 4283 BuildMI(MF, Root.getDebugLoc(), TII->get(OrrOpc), NewVR) 4284 .addReg(ZeroReg) 4285 .addImm(Encoding); 4286 InsInstrs.push_back(MIB1); 4287 InstrIdxForVirtReg.insert(std::make_pair(NewVR, 0)); 4288 MUL = genMaddR(MF, MRI, TII, Root, InsInstrs, 1, Opc, NewVR, RC); 4289 } 4290 break; 4291 } 4292 // Floating Point Support 4293 case MachineCombinerPattern::FMULADDS_OP1: 4294 case MachineCombinerPattern::FMULADDD_OP1: 4295 // MUL I=A,B,0 4296 // ADD R,I,C 4297 // ==> MADD R,A,B,C 4298 // --- Create(MADD); 4299 if (Pattern == MachineCombinerPattern::FMULADDS_OP1) { 4300 Opc = AArch64::FMADDSrrr; 4301 RC = &AArch64::FPR32RegClass; 4302 } else { 4303 Opc = AArch64::FMADDDrrr; 4304 RC = &AArch64::FPR64RegClass; 4305 } 4306 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC); 4307 break; 4308 case MachineCombinerPattern::FMULADDS_OP2: 4309 case MachineCombinerPattern::FMULADDD_OP2: 4310 // FMUL I=A,B,0 4311 // FADD R,C,I 4312 // ==> FMADD R,A,B,C 4313 // --- Create(FMADD); 4314 if (Pattern == MachineCombinerPattern::FMULADDS_OP2) { 4315 Opc = AArch64::FMADDSrrr; 4316 RC = &AArch64::FPR32RegClass; 4317 } else { 4318 Opc = AArch64::FMADDDrrr; 4319 RC = &AArch64::FPR64RegClass; 4320 } 4321 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC); 4322 break; 4323 4324 case MachineCombinerPattern::FMLAv1i32_indexed_OP1: 4325 Opc = AArch64::FMLAv1i32_indexed; 4326 RC = &AArch64::FPR32RegClass; 4327 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC, 4328 FMAInstKind::Indexed); 4329 break; 4330 case MachineCombinerPattern::FMLAv1i32_indexed_OP2: 4331 Opc = AArch64::FMLAv1i32_indexed; 4332 RC = &AArch64::FPR32RegClass; 4333 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC, 4334 FMAInstKind::Indexed); 4335 break; 4336 4337 case MachineCombinerPattern::FMLAv1i64_indexed_OP1: 4338 Opc = AArch64::FMLAv1i64_indexed; 4339 RC = &AArch64::FPR64RegClass; 4340 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC, 4341 FMAInstKind::Indexed); 4342 break; 4343 case MachineCombinerPattern::FMLAv1i64_indexed_OP2: 4344 Opc = AArch64::FMLAv1i64_indexed; 4345 RC = &AArch64::FPR64RegClass; 4346 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC, 4347 FMAInstKind::Indexed); 4348 break; 4349 4350 case MachineCombinerPattern::FMLAv2i32_indexed_OP1: 4351 case MachineCombinerPattern::FMLAv2f32_OP1: 4352 RC = &AArch64::FPR64RegClass; 4353 if (Pattern == MachineCombinerPattern::FMLAv2i32_indexed_OP1) { 4354 Opc = AArch64::FMLAv2i32_indexed; 4355 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC, 4356 FMAInstKind::Indexed); 4357 } else { 4358 Opc = AArch64::FMLAv2f32; 4359 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC, 4360 FMAInstKind::Accumulator); 4361 } 4362 break; 4363 case MachineCombinerPattern::FMLAv2i32_indexed_OP2: 4364 case MachineCombinerPattern::FMLAv2f32_OP2: 4365 RC = &AArch64::FPR64RegClass; 4366 if (Pattern == MachineCombinerPattern::FMLAv2i32_indexed_OP2) { 4367 Opc = AArch64::FMLAv2i32_indexed; 4368 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC, 4369 FMAInstKind::Indexed); 4370 } else { 4371 Opc = AArch64::FMLAv2f32; 4372 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC, 4373 FMAInstKind::Accumulator); 4374 } 4375 break; 4376 4377 case MachineCombinerPattern::FMLAv2i64_indexed_OP1: 4378 case MachineCombinerPattern::FMLAv2f64_OP1: 4379 RC = &AArch64::FPR128RegClass; 4380 if (Pattern == MachineCombinerPattern::FMLAv2i64_indexed_OP1) { 4381 Opc = AArch64::FMLAv2i64_indexed; 4382 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC, 4383 FMAInstKind::Indexed); 4384 } else { 4385 Opc = AArch64::FMLAv2f64; 4386 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC, 4387 FMAInstKind::Accumulator); 4388 } 4389 break; 4390 case MachineCombinerPattern::FMLAv2i64_indexed_OP2: 4391 case MachineCombinerPattern::FMLAv2f64_OP2: 4392 RC = &AArch64::FPR128RegClass; 4393 if (Pattern == MachineCombinerPattern::FMLAv2i64_indexed_OP2) { 4394 Opc = AArch64::FMLAv2i64_indexed; 4395 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC, 4396 FMAInstKind::Indexed); 4397 } else { 4398 Opc = AArch64::FMLAv2f64; 4399 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC, 4400 FMAInstKind::Accumulator); 4401 } 4402 break; 4403 4404 case MachineCombinerPattern::FMLAv4i32_indexed_OP1: 4405 case MachineCombinerPattern::FMLAv4f32_OP1: 4406 RC = &AArch64::FPR128RegClass; 4407 if (Pattern == MachineCombinerPattern::FMLAv4i32_indexed_OP1) { 4408 Opc = AArch64::FMLAv4i32_indexed; 4409 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC, 4410 FMAInstKind::Indexed); 4411 } else { 4412 Opc = AArch64::FMLAv4f32; 4413 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC, 4414 FMAInstKind::Accumulator); 4415 } 4416 break; 4417 4418 case MachineCombinerPattern::FMLAv4i32_indexed_OP2: 4419 case MachineCombinerPattern::FMLAv4f32_OP2: 4420 RC = &AArch64::FPR128RegClass; 4421 if (Pattern == MachineCombinerPattern::FMLAv4i32_indexed_OP2) { 4422 Opc = AArch64::FMLAv4i32_indexed; 4423 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC, 4424 FMAInstKind::Indexed); 4425 } else { 4426 Opc = AArch64::FMLAv4f32; 4427 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC, 4428 FMAInstKind::Accumulator); 4429 } 4430 break; 4431 4432 case MachineCombinerPattern::FMULSUBS_OP1: 4433 case MachineCombinerPattern::FMULSUBD_OP1: { 4434 // FMUL I=A,B,0 4435 // FSUB R,I,C 4436 // ==> FNMSUB R,A,B,C // = -C + A*B 4437 // --- Create(FNMSUB); 4438 if (Pattern == MachineCombinerPattern::FMULSUBS_OP1) { 4439 Opc = AArch64::FNMSUBSrrr; 4440 RC = &AArch64::FPR32RegClass; 4441 } else { 4442 Opc = AArch64::FNMSUBDrrr; 4443 RC = &AArch64::FPR64RegClass; 4444 } 4445 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC); 4446 break; 4447 } 4448 4449 case MachineCombinerPattern::FNMULSUBS_OP1: 4450 case MachineCombinerPattern::FNMULSUBD_OP1: { 4451 // FNMUL I=A,B,0 4452 // FSUB R,I,C 4453 // ==> FNMADD R,A,B,C // = -A*B - C 4454 // --- Create(FNMADD); 4455 if (Pattern == MachineCombinerPattern::FNMULSUBS_OP1) { 4456 Opc = AArch64::FNMADDSrrr; 4457 RC = &AArch64::FPR32RegClass; 4458 } else { 4459 Opc = AArch64::FNMADDDrrr; 4460 RC = &AArch64::FPR64RegClass; 4461 } 4462 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC); 4463 break; 4464 } 4465 4466 case MachineCombinerPattern::FMULSUBS_OP2: 4467 case MachineCombinerPattern::FMULSUBD_OP2: { 4468 // FMUL I=A,B,0 4469 // FSUB R,C,I 4470 // ==> FMSUB R,A,B,C (computes C - A*B) 4471 // --- Create(FMSUB); 4472 if (Pattern == MachineCombinerPattern::FMULSUBS_OP2) { 4473 Opc = AArch64::FMSUBSrrr; 4474 RC = &AArch64::FPR32RegClass; 4475 } else { 4476 Opc = AArch64::FMSUBDrrr; 4477 RC = &AArch64::FPR64RegClass; 4478 } 4479 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC); 4480 break; 4481 } 4482 4483 case MachineCombinerPattern::FMLSv1i32_indexed_OP2: 4484 Opc = AArch64::FMLSv1i32_indexed; 4485 RC = &AArch64::FPR32RegClass; 4486 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC, 4487 FMAInstKind::Indexed); 4488 break; 4489 4490 case MachineCombinerPattern::FMLSv1i64_indexed_OP2: 4491 Opc = AArch64::FMLSv1i64_indexed; 4492 RC = &AArch64::FPR64RegClass; 4493 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC, 4494 FMAInstKind::Indexed); 4495 break; 4496 4497 case MachineCombinerPattern::FMLSv2f32_OP2: 4498 case MachineCombinerPattern::FMLSv2i32_indexed_OP2: 4499 RC = &AArch64::FPR64RegClass; 4500 if (Pattern == MachineCombinerPattern::FMLSv2i32_indexed_OP2) { 4501 Opc = AArch64::FMLSv2i32_indexed; 4502 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC, 4503 FMAInstKind::Indexed); 4504 } else { 4505 Opc = AArch64::FMLSv2f32; 4506 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC, 4507 FMAInstKind::Accumulator); 4508 } 4509 break; 4510 4511 case MachineCombinerPattern::FMLSv2f64_OP2: 4512 case MachineCombinerPattern::FMLSv2i64_indexed_OP2: 4513 RC = &AArch64::FPR128RegClass; 4514 if (Pattern == MachineCombinerPattern::FMLSv2i64_indexed_OP2) { 4515 Opc = AArch64::FMLSv2i64_indexed; 4516 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC, 4517 FMAInstKind::Indexed); 4518 } else { 4519 Opc = AArch64::FMLSv2f64; 4520 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC, 4521 FMAInstKind::Accumulator); 4522 } 4523 break; 4524 4525 case MachineCombinerPattern::FMLSv4f32_OP2: 4526 case MachineCombinerPattern::FMLSv4i32_indexed_OP2: 4527 RC = &AArch64::FPR128RegClass; 4528 if (Pattern == MachineCombinerPattern::FMLSv4i32_indexed_OP2) { 4529 Opc = AArch64::FMLSv4i32_indexed; 4530 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC, 4531 FMAInstKind::Indexed); 4532 } else { 4533 Opc = AArch64::FMLSv4f32; 4534 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC, 4535 FMAInstKind::Accumulator); 4536 } 4537 break; 4538 case MachineCombinerPattern::FMLSv2f32_OP1: 4539 case MachineCombinerPattern::FMLSv2i32_indexed_OP1: { 4540 RC = &AArch64::FPR64RegClass; 4541 unsigned NewVR = MRI.createVirtualRegister(RC); 4542 MachineInstrBuilder MIB1 = 4543 BuildMI(MF, Root.getDebugLoc(), TII->get(AArch64::FNEGv2f32), NewVR) 4544 .add(Root.getOperand(2)); 4545 InsInstrs.push_back(MIB1); 4546 InstrIdxForVirtReg.insert(std::make_pair(NewVR, 0)); 4547 if (Pattern == MachineCombinerPattern::FMLSv2i32_indexed_OP1) { 4548 Opc = AArch64::FMLAv2i32_indexed; 4549 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC, 4550 FMAInstKind::Indexed, &NewVR); 4551 } else { 4552 Opc = AArch64::FMLAv2f32; 4553 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC, 4554 FMAInstKind::Accumulator, &NewVR); 4555 } 4556 break; 4557 } 4558 case MachineCombinerPattern::FMLSv4f32_OP1: 4559 case MachineCombinerPattern::FMLSv4i32_indexed_OP1: { 4560 RC = &AArch64::FPR128RegClass; 4561 unsigned NewVR = MRI.createVirtualRegister(RC); 4562 MachineInstrBuilder MIB1 = 4563 BuildMI(MF, Root.getDebugLoc(), TII->get(AArch64::FNEGv4f32), NewVR) 4564 .add(Root.getOperand(2)); 4565 InsInstrs.push_back(MIB1); 4566 InstrIdxForVirtReg.insert(std::make_pair(NewVR, 0)); 4567 if (Pattern == MachineCombinerPattern::FMLSv4i32_indexed_OP1) { 4568 Opc = AArch64::FMLAv4i32_indexed; 4569 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC, 4570 FMAInstKind::Indexed, &NewVR); 4571 } else { 4572 Opc = AArch64::FMLAv4f32; 4573 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC, 4574 FMAInstKind::Accumulator, &NewVR); 4575 } 4576 break; 4577 } 4578 case MachineCombinerPattern::FMLSv2f64_OP1: 4579 case MachineCombinerPattern::FMLSv2i64_indexed_OP1: { 4580 RC = &AArch64::FPR128RegClass; 4581 unsigned NewVR = MRI.createVirtualRegister(RC); 4582 MachineInstrBuilder MIB1 = 4583 BuildMI(MF, Root.getDebugLoc(), TII->get(AArch64::FNEGv2f64), NewVR) 4584 .add(Root.getOperand(2)); 4585 InsInstrs.push_back(MIB1); 4586 InstrIdxForVirtReg.insert(std::make_pair(NewVR, 0)); 4587 if (Pattern == MachineCombinerPattern::FMLSv2i64_indexed_OP1) { 4588 Opc = AArch64::FMLAv2i64_indexed; 4589 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC, 4590 FMAInstKind::Indexed, &NewVR); 4591 } else { 4592 Opc = AArch64::FMLAv2f64; 4593 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC, 4594 FMAInstKind::Accumulator, &NewVR); 4595 } 4596 break; 4597 } 4598 } // end switch (Pattern) 4599 // Record MUL and ADD/SUB for deletion 4600 DelInstrs.push_back(MUL); 4601 DelInstrs.push_back(&Root); 4602 } 4603 4604 /// \brief Replace csincr-branch sequence by simple conditional branch 4605 /// 4606 /// Examples: 4607 /// 1. \code 4608 /// csinc w9, wzr, wzr, <condition code> 4609 /// tbnz w9, #0, 0x44 4610 /// \endcode 4611 /// to 4612 /// \code 4613 /// b.<inverted condition code> 4614 /// \endcode 4615 /// 4616 /// 2. \code 4617 /// csinc w9, wzr, wzr, <condition code> 4618 /// tbz w9, #0, 0x44 4619 /// \endcode 4620 /// to 4621 /// \code 4622 /// b.<condition code> 4623 /// \endcode 4624 /// 4625 /// Replace compare and branch sequence by TBZ/TBNZ instruction when the 4626 /// compare's constant operand is power of 2. 4627 /// 4628 /// Examples: 4629 /// \code 4630 /// and w8, w8, #0x400 4631 /// cbnz w8, L1 4632 /// \endcode 4633 /// to 4634 /// \code 4635 /// tbnz w8, #10, L1 4636 /// \endcode 4637 /// 4638 /// \param MI Conditional Branch 4639 /// \return True when the simple conditional branch is generated 4640 /// 4641 bool AArch64InstrInfo::optimizeCondBranch(MachineInstr &MI) const { 4642 bool IsNegativeBranch = false; 4643 bool IsTestAndBranch = false; 4644 unsigned TargetBBInMI = 0; 4645 switch (MI.getOpcode()) { 4646 default: 4647 llvm_unreachable("Unknown branch instruction?"); 4648 case AArch64::Bcc: 4649 return false; 4650 case AArch64::CBZW: 4651 case AArch64::CBZX: 4652 TargetBBInMI = 1; 4653 break; 4654 case AArch64::CBNZW: 4655 case AArch64::CBNZX: 4656 TargetBBInMI = 1; 4657 IsNegativeBranch = true; 4658 break; 4659 case AArch64::TBZW: 4660 case AArch64::TBZX: 4661 TargetBBInMI = 2; 4662 IsTestAndBranch = true; 4663 break; 4664 case AArch64::TBNZW: 4665 case AArch64::TBNZX: 4666 TargetBBInMI = 2; 4667 IsNegativeBranch = true; 4668 IsTestAndBranch = true; 4669 break; 4670 } 4671 // So we increment a zero register and test for bits other 4672 // than bit 0? Conservatively bail out in case the verifier 4673 // missed this case. 4674 if (IsTestAndBranch && MI.getOperand(1).getImm()) 4675 return false; 4676 4677 // Find Definition. 4678 assert(MI.getParent() && "Incomplete machine instruciton\n"); 4679 MachineBasicBlock *MBB = MI.getParent(); 4680 MachineFunction *MF = MBB->getParent(); 4681 MachineRegisterInfo *MRI = &MF->getRegInfo(); 4682 unsigned VReg = MI.getOperand(0).getReg(); 4683 if (!TargetRegisterInfo::isVirtualRegister(VReg)) 4684 return false; 4685 4686 MachineInstr *DefMI = MRI->getVRegDef(VReg); 4687 4688 // Look through COPY instructions to find definition. 4689 while (DefMI->isCopy()) { 4690 unsigned CopyVReg = DefMI->getOperand(1).getReg(); 4691 if (!MRI->hasOneNonDBGUse(CopyVReg)) 4692 return false; 4693 if (!MRI->hasOneDef(CopyVReg)) 4694 return false; 4695 DefMI = MRI->getVRegDef(CopyVReg); 4696 } 4697 4698 switch (DefMI->getOpcode()) { 4699 default: 4700 return false; 4701 // Fold AND into a TBZ/TBNZ if constant operand is power of 2. 4702 case AArch64::ANDWri: 4703 case AArch64::ANDXri: { 4704 if (IsTestAndBranch) 4705 return false; 4706 if (DefMI->getParent() != MBB) 4707 return false; 4708 if (!MRI->hasOneNonDBGUse(VReg)) 4709 return false; 4710 4711 bool Is32Bit = (DefMI->getOpcode() == AArch64::ANDWri); 4712 uint64_t Mask = AArch64_AM::decodeLogicalImmediate( 4713 DefMI->getOperand(2).getImm(), Is32Bit ? 32 : 64); 4714 if (!isPowerOf2_64(Mask)) 4715 return false; 4716 4717 MachineOperand &MO = DefMI->getOperand(1); 4718 unsigned NewReg = MO.getReg(); 4719 if (!TargetRegisterInfo::isVirtualRegister(NewReg)) 4720 return false; 4721 4722 assert(!MRI->def_empty(NewReg) && "Register must be defined."); 4723 4724 MachineBasicBlock &RefToMBB = *MBB; 4725 MachineBasicBlock *TBB = MI.getOperand(1).getMBB(); 4726 DebugLoc DL = MI.getDebugLoc(); 4727 unsigned Imm = Log2_64(Mask); 4728 unsigned Opc = (Imm < 32) 4729 ? (IsNegativeBranch ? AArch64::TBNZW : AArch64::TBZW) 4730 : (IsNegativeBranch ? AArch64::TBNZX : AArch64::TBZX); 4731 MachineInstr *NewMI = BuildMI(RefToMBB, MI, DL, get(Opc)) 4732 .addReg(NewReg) 4733 .addImm(Imm) 4734 .addMBB(TBB); 4735 // Register lives on to the CBZ now. 4736 MO.setIsKill(false); 4737 4738 // For immediate smaller than 32, we need to use the 32-bit 4739 // variant (W) in all cases. Indeed the 64-bit variant does not 4740 // allow to encode them. 4741 // Therefore, if the input register is 64-bit, we need to take the 4742 // 32-bit sub-part. 4743 if (!Is32Bit && Imm < 32) 4744 NewMI->getOperand(0).setSubReg(AArch64::sub_32); 4745 MI.eraseFromParent(); 4746 return true; 4747 } 4748 // Look for CSINC 4749 case AArch64::CSINCWr: 4750 case AArch64::CSINCXr: { 4751 if (!(DefMI->getOperand(1).getReg() == AArch64::WZR && 4752 DefMI->getOperand(2).getReg() == AArch64::WZR) && 4753 !(DefMI->getOperand(1).getReg() == AArch64::XZR && 4754 DefMI->getOperand(2).getReg() == AArch64::XZR)) 4755 return false; 4756 4757 if (DefMI->findRegisterDefOperandIdx(AArch64::NZCV, true) != -1) 4758 return false; 4759 4760 AArch64CC::CondCode CC = (AArch64CC::CondCode)DefMI->getOperand(3).getImm(); 4761 // Convert only when the condition code is not modified between 4762 // the CSINC and the branch. The CC may be used by other 4763 // instructions in between. 4764 if (areCFlagsAccessedBetweenInstrs(DefMI, MI, &getRegisterInfo(), AK_Write)) 4765 return false; 4766 MachineBasicBlock &RefToMBB = *MBB; 4767 MachineBasicBlock *TBB = MI.getOperand(TargetBBInMI).getMBB(); 4768 DebugLoc DL = MI.getDebugLoc(); 4769 if (IsNegativeBranch) 4770 CC = AArch64CC::getInvertedCondCode(CC); 4771 BuildMI(RefToMBB, MI, DL, get(AArch64::Bcc)).addImm(CC).addMBB(TBB); 4772 MI.eraseFromParent(); 4773 return true; 4774 } 4775 } 4776 } 4777 4778 std::pair<unsigned, unsigned> 4779 AArch64InstrInfo::decomposeMachineOperandsTargetFlags(unsigned TF) const { 4780 const unsigned Mask = AArch64II::MO_FRAGMENT; 4781 return std::make_pair(TF & Mask, TF & ~Mask); 4782 } 4783 4784 ArrayRef<std::pair<unsigned, const char *>> 4785 AArch64InstrInfo::getSerializableDirectMachineOperandTargetFlags() const { 4786 using namespace AArch64II; 4787 4788 static const std::pair<unsigned, const char *> TargetFlags[] = { 4789 {MO_PAGE, "aarch64-page"}, {MO_PAGEOFF, "aarch64-pageoff"}, 4790 {MO_G3, "aarch64-g3"}, {MO_G2, "aarch64-g2"}, 4791 {MO_G1, "aarch64-g1"}, {MO_G0, "aarch64-g0"}, 4792 {MO_HI12, "aarch64-hi12"}}; 4793 return makeArrayRef(TargetFlags); 4794 } 4795 4796 ArrayRef<std::pair<unsigned, const char *>> 4797 AArch64InstrInfo::getSerializableBitmaskMachineOperandTargetFlags() const { 4798 using namespace AArch64II; 4799 4800 static const std::pair<unsigned, const char *> TargetFlags[] = { 4801 {MO_GOT, "aarch64-got"}, {MO_NC, "aarch64-nc"}, {MO_TLS, "aarch64-tls"}}; 4802 return makeArrayRef(TargetFlags); 4803 } 4804 4805 ArrayRef<std::pair<MachineMemOperand::Flags, const char *>> 4806 AArch64InstrInfo::getSerializableMachineMemOperandTargetFlags() const { 4807 static const std::pair<MachineMemOperand::Flags, const char *> TargetFlags[] = 4808 {{MOSuppressPair, "aarch64-suppress-pair"}, 4809 {MOStridedAccess, "aarch64-strided-access"}}; 4810 return makeArrayRef(TargetFlags); 4811 } 4812 4813 /// Constants defining how certain sequences should be outlined. 4814 /// This encompasses how an outlined function should be called, and what kind of 4815 /// frame should be emitted for that outlined function. 4816 /// 4817 /// \p MachineOutlinerDefault implies that the function should be called with 4818 /// a save and restore of LR to the stack. 4819 /// 4820 /// That is, 4821 /// 4822 /// I1 Save LR OUTLINED_FUNCTION: 4823 /// I2 --> BL OUTLINED_FUNCTION I1 4824 /// I3 Restore LR I2 4825 /// I3 4826 /// RET 4827 /// 4828 /// * Call construction overhead: 3 (save + BL + restore) 4829 /// * Frame construction overhead: 1 (ret) 4830 /// * Requires stack fixups? Yes 4831 /// 4832 /// \p MachineOutlinerTailCall implies that the function is being created from 4833 /// a sequence of instructions ending in a return. 4834 /// 4835 /// That is, 4836 /// 4837 /// I1 OUTLINED_FUNCTION: 4838 /// I2 --> B OUTLINED_FUNCTION I1 4839 /// RET I2 4840 /// RET 4841 /// 4842 /// * Call construction overhead: 1 (B) 4843 /// * Frame construction overhead: 0 (Return included in sequence) 4844 /// * Requires stack fixups? No 4845 /// 4846 /// \p MachineOutlinerNoLRSave implies that the function should be called using 4847 /// a BL instruction, but doesn't require LR to be saved and restored. This 4848 /// happens when LR is known to be dead. 4849 /// 4850 /// That is, 4851 /// 4852 /// I1 OUTLINED_FUNCTION: 4853 /// I2 --> BL OUTLINED_FUNCTION I1 4854 /// I3 I2 4855 /// I3 4856 /// RET 4857 /// 4858 /// * Call construction overhead: 1 (BL) 4859 /// * Frame construction overhead: 1 (RET) 4860 /// * Requires stack fixups? No 4861 /// 4862 enum MachineOutlinerClass { 4863 MachineOutlinerDefault, /// Emit a save, restore, call, and return. 4864 MachineOutlinerTailCall, /// Only emit a branch. 4865 MachineOutlinerNoLRSave /// Emit a call and return. 4866 }; 4867 4868 enum MachineOutlinerMBBFlags { 4869 LRUnavailableSomewhere = 0x2, 4870 HasCalls = 0x4 4871 }; 4872 4873 bool AArch64InstrInfo::canOutlineWithoutLRSave( 4874 MachineBasicBlock::iterator &CallInsertionPt) const { 4875 // Was LR saved in the function containing this basic block? 4876 MachineBasicBlock &MBB = *(CallInsertionPt->getParent()); 4877 LiveRegUnits LRU(getRegisterInfo()); 4878 LRU.addLiveOuts(MBB); 4879 4880 // Get liveness information from the end of the block to the end of the 4881 // prospective outlined region. 4882 std::for_each(MBB.rbegin(), 4883 (MachineBasicBlock::reverse_iterator)CallInsertionPt, 4884 [&LRU](MachineInstr &MI) { LRU.stepBackward(MI); }); 4885 4886 // If the link register is available at this point, then we can safely outline 4887 // the region without saving/restoring LR. Otherwise, we must emit a save and 4888 // restore. 4889 return LRU.available(AArch64::LR); 4890 } 4891 4892 AArch64GenInstrInfo::MachineOutlinerInfo 4893 AArch64InstrInfo::getOutlininingCandidateInfo( 4894 std::vector< 4895 std::pair<MachineBasicBlock::iterator, MachineBasicBlock::iterator>> 4896 &RepeatedSequenceLocs) const { 4897 4898 unsigned CallID = MachineOutlinerDefault; 4899 unsigned FrameID = MachineOutlinerDefault; 4900 unsigned NumInstrsForCall = 3; 4901 unsigned NumInstrsToCreateFrame = 1; 4902 4903 auto DoesntNeedLRSave = 4904 [this](std::pair<MachineBasicBlock::iterator, MachineBasicBlock::iterator> 4905 &I) { return canOutlineWithoutLRSave(I.second); }; 4906 4907 // If the last instruction in any candidate is a terminator, then we should 4908 // tail call all of the candidates. 4909 if (RepeatedSequenceLocs[0].second->isTerminator()) { 4910 CallID = MachineOutlinerTailCall; 4911 FrameID = MachineOutlinerTailCall; 4912 NumInstrsForCall = 1; 4913 NumInstrsToCreateFrame = 0; 4914 } 4915 4916 else if (std::all_of(RepeatedSequenceLocs.begin(), RepeatedSequenceLocs.end(), 4917 DoesntNeedLRSave)) { 4918 CallID = MachineOutlinerNoLRSave; 4919 FrameID = MachineOutlinerNoLRSave; 4920 NumInstrsForCall = 1; 4921 NumInstrsToCreateFrame = 1; 4922 } 4923 4924 // Check if the range contains a call. These require a save + restore of the 4925 // link register. 4926 if (std::any_of(RepeatedSequenceLocs[0].first, RepeatedSequenceLocs[0].second, 4927 [](const MachineInstr &MI) { return MI.isCall(); })) 4928 NumInstrsToCreateFrame += 2; // Save + restore the link register. 4929 4930 // Handle the last instruction separately. If this is a tail call, then the 4931 // last instruction is a call. We don't want to save + restore in this case. 4932 // However, it could be possible that the last instruction is a call without 4933 // it being valid to tail call this sequence. We should consider this as well. 4934 else if (RepeatedSequenceLocs[0].second->isCall() && 4935 FrameID != MachineOutlinerTailCall) 4936 NumInstrsToCreateFrame += 2; 4937 4938 return MachineOutlinerInfo(NumInstrsForCall, NumInstrsToCreateFrame, CallID, 4939 FrameID); 4940 } 4941 4942 bool AArch64InstrInfo::isFunctionSafeToOutlineFrom( 4943 MachineFunction &MF, bool OutlineFromLinkOnceODRs) const { 4944 const Function &F = MF.getFunction(); 4945 4946 // If F uses a redzone, then don't outline from it because it might mess up 4947 // the stack. 4948 if (!F.hasFnAttribute(Attribute::NoRedZone)) 4949 return false; 4950 4951 // Can F be deduplicated by the linker? If it can, don't outline from it. 4952 if (!OutlineFromLinkOnceODRs && F.hasLinkOnceODRLinkage()) 4953 return false; 4954 4955 return true; 4956 } 4957 4958 unsigned 4959 AArch64InstrInfo::getMachineOutlinerMBBFlags(MachineBasicBlock &MBB) const { 4960 unsigned Flags = 0x0; 4961 // Check if there's a call inside this MachineBasicBlock. If there is, then 4962 // set a flag. 4963 if (std::any_of(MBB.begin(), MBB.end(), 4964 [](MachineInstr &MI) { return MI.isCall(); })) 4965 Flags |= MachineOutlinerMBBFlags::HasCalls; 4966 4967 // Check if LR is available through all of the MBB. If it's not, then set 4968 // a flag. 4969 LiveRegUnits LRU(getRegisterInfo()); 4970 LRU.addLiveOuts(MBB); 4971 4972 std::for_each(MBB.rbegin(), 4973 MBB.rend(), 4974 [&LRU](MachineInstr &MI) { LRU.accumulate(MI); }); 4975 4976 if (!LRU.available(AArch64::LR)) 4977 Flags |= MachineOutlinerMBBFlags::LRUnavailableSomewhere; 4978 4979 return Flags; 4980 } 4981 4982 AArch64GenInstrInfo::MachineOutlinerInstrType 4983 AArch64InstrInfo::getOutliningType(MachineBasicBlock::iterator &MIT, 4984 unsigned Flags) const { 4985 MachineInstr &MI = *MIT; 4986 MachineBasicBlock *MBB = MI.getParent(); 4987 MachineFunction *MF = MBB->getParent(); 4988 AArch64FunctionInfo *FuncInfo = MF->getInfo<AArch64FunctionInfo>(); 4989 4990 // Don't outline LOHs. 4991 if (FuncInfo->getLOHRelated().count(&MI)) 4992 return MachineOutlinerInstrType::Illegal; 4993 4994 // Don't allow debug values to impact outlining type. 4995 if (MI.isDebugValue() || MI.isIndirectDebugValue()) 4996 return MachineOutlinerInstrType::Invisible; 4997 4998 // Is this a terminator for a basic block? 4999 if (MI.isTerminator()) { 5000 5001 // Is this the end of a function? 5002 if (MI.getParent()->succ_empty()) 5003 return MachineOutlinerInstrType::Legal; 5004 5005 // It's not, so don't outline it. 5006 return MachineOutlinerInstrType::Illegal; 5007 } 5008 5009 // Special cases for instructions that can always be outlined, but will fail 5010 // the later tests. e.g, ADRPs, which are PC-relative use LR, but can always 5011 // be outlined because they don't require a *specific* value to be in LR. 5012 if (MI.getOpcode() == AArch64::ADRP) 5013 return MachineOutlinerInstrType::Legal; 5014 5015 // Outline calls without stack parameters or aggregate parameters. 5016 if (MI.isCall()) { 5017 const Module *M = MF->getFunction().getParent(); 5018 assert(M && "No module?"); 5019 5020 // Get the function associated with the call. Look at each operand and find 5021 // the one that represents the callee and get its name. 5022 Function *Callee = nullptr; 5023 for (const MachineOperand &MOP : MI.operands()) { 5024 if (MOP.isSymbol()) { 5025 Callee = M->getFunction(MOP.getSymbolName()); 5026 break; 5027 } 5028 5029 else if (MOP.isGlobal()) { 5030 Callee = M->getFunction(MOP.getGlobal()->getGlobalIdentifier()); 5031 break; 5032 } 5033 } 5034 5035 // Only handle functions that we have information about. 5036 if (!Callee) 5037 return MachineOutlinerInstrType::Illegal; 5038 5039 // We have a function we have information about. Check it if it's something 5040 // can safely outline. 5041 5042 // If the callee is vararg, it passes parameters on the stack. Don't touch 5043 // it. 5044 // FIXME: Functions like printf are very common and we should be able to 5045 // outline them. 5046 if (Callee->isVarArg()) 5047 return MachineOutlinerInstrType::Illegal; 5048 5049 // Check if any of the arguments are a pointer to a struct. We don't want 5050 // to outline these since they might be loaded in two instructions. 5051 for (Argument &Arg : Callee->args()) { 5052 if (Arg.getType()->isPointerTy() && 5053 Arg.getType()->getPointerElementType()->isAggregateType()) 5054 return MachineOutlinerInstrType::Illegal; 5055 } 5056 5057 // If the thing we're calling doesn't access memory at all, then we're good 5058 // to go. 5059 if (Callee->doesNotAccessMemory()) 5060 return MachineOutlinerInstrType::Legal; 5061 5062 5063 // It accesses memory. Get the machine function for the callee to see if 5064 // it's safe to outline. 5065 MachineFunction *CalleeMF = MF->getMMI().getMachineFunction(*Callee); 5066 5067 // We don't know what's going on with the callee at all. Don't touch it. 5068 if (!CalleeMF) 5069 return MachineOutlinerInstrType::Illegal; 5070 5071 // Does it pass anything on the stack? If it does, don't outline it. 5072 if (CalleeMF->getInfo<AArch64FunctionInfo>()->getBytesInStackArgArea() != 0) 5073 return MachineOutlinerInstrType::Illegal; 5074 5075 // It doesn't, so it's safe to outline and we're done. 5076 return MachineOutlinerInstrType::Legal; 5077 } 5078 5079 // Don't outline positions. 5080 if (MI.isPosition()) 5081 return MachineOutlinerInstrType::Illegal; 5082 5083 // Don't touch the link register or W30. 5084 if (MI.readsRegister(AArch64::W30, &getRegisterInfo()) || 5085 MI.modifiesRegister(AArch64::W30, &getRegisterInfo())) 5086 return MachineOutlinerInstrType::Illegal; 5087 5088 // Make sure none of the operands are un-outlinable. 5089 for (const MachineOperand &MOP : MI.operands()) { 5090 if (MOP.isCPI() || MOP.isJTI() || MOP.isCFIIndex() || MOP.isFI() || 5091 MOP.isTargetIndex()) 5092 return MachineOutlinerInstrType::Illegal; 5093 5094 // Don't outline anything that uses the link register. 5095 if (MOP.isReg() && getRegisterInfo().regsOverlap(MOP.getReg(), AArch64::LR)) 5096 return MachineOutlinerInstrType::Illegal; 5097 } 5098 5099 // Does this use the stack? 5100 if (MI.modifiesRegister(AArch64::SP, &RI) || 5101 MI.readsRegister(AArch64::SP, &RI)) { 5102 // True if there is no chance that any outlined candidate from this range 5103 // could require stack fixups. That is, both 5104 // * LR is available in the range (No save/restore around call) 5105 // * The range doesn't include calls (No save/restore in outlined frame) 5106 // are true. 5107 bool MightNeedStackFixUp = 5108 (Flags & (MachineOutlinerMBBFlags::LRUnavailableSomewhere | 5109 MachineOutlinerMBBFlags::HasCalls)); 5110 5111 // If this instruction is in a range where it *never* needs to be fixed 5112 // up, then we can *always* outline it. This is true even if it's not 5113 // possible to fix that instruction up. 5114 // 5115 // Why? Consider two equivalent instructions I1, I2 where both I1 and I2 5116 // use SP. Suppose that I1 sits within a range that definitely doesn't 5117 // need stack fixups, while I2 sits in a range that does. 5118 // 5119 // First, I1 can be outlined as long as we *never* fix up the stack in 5120 // any sequence containing it. I1 is already a safe instruction in the 5121 // original program, so as long as we don't modify it we're good to go. 5122 // So this leaves us with showing that outlining I2 won't break our 5123 // program. 5124 // 5125 // Suppose I1 and I2 belong to equivalent candidate sequences. When we 5126 // look at I2, we need to see if it can be fixed up. Suppose I2, (and 5127 // thus I1) cannot be fixed up. Then I2 will be assigned an unique 5128 // integer label; thus, I2 cannot belong to any candidate sequence (a 5129 // contradiction). Suppose I2 can be fixed up. Then I1 can be fixed up 5130 // as well, so we're good. Thus, I1 is always safe to outline. 5131 // 5132 // This gives us two things: first off, it buys us some more instructions 5133 // for our search space by deeming stack instructions illegal only when 5134 // they can't be fixed up AND we might have to fix them up. Second off, 5135 // This allows us to catch tricky instructions like, say, 5136 // %xi = ADDXri %sp, n, 0. We can't safely outline these since they might 5137 // be paired with later SUBXris, which might *not* end up being outlined. 5138 // If we mess with the stack to save something, then an ADDXri messes with 5139 // it *after*, then we aren't going to restore the right something from 5140 // the stack if we don't outline the corresponding SUBXri first. ADDXris and 5141 // SUBXris are extremely common in prologue/epilogue code, so supporting 5142 // them in the outliner can be a pretty big win! 5143 if (!MightNeedStackFixUp) 5144 return MachineOutlinerInstrType::Legal; 5145 5146 // At this point, we have a stack instruction that we might need to fix 5147 // up. We'll handle it if it's a load or store. 5148 if (MI.mayLoadOrStore()) { 5149 unsigned Base; // Filled with the base regiser of MI. 5150 int64_t Offset; // Filled with the offset of MI. 5151 unsigned DummyWidth; 5152 5153 // Does it allow us to offset the base register and is the base SP? 5154 if (!getMemOpBaseRegImmOfsWidth(MI, Base, Offset, DummyWidth, &RI) || 5155 Base != AArch64::SP) 5156 return MachineOutlinerInstrType::Illegal; 5157 5158 // Find the minimum/maximum offset for this instruction and check if 5159 // fixing it up would be in range. 5160 int64_t MinOffset, MaxOffset; // Unscaled offsets for the instruction. 5161 unsigned Scale; // The scale to multiply the offsets by. 5162 getMemOpInfo(MI.getOpcode(), Scale, DummyWidth, MinOffset, MaxOffset); 5163 5164 // TODO: We should really test what happens if an instruction overflows. 5165 // This is tricky to test with IR tests, but when the outliner is moved 5166 // to a MIR test, it really ought to be checked. 5167 Offset += 16; // Update the offset to what it would be if we outlined. 5168 if (Offset < MinOffset * Scale || Offset > MaxOffset * Scale) 5169 return MachineOutlinerInstrType::Illegal; 5170 5171 // It's in range, so we can outline it. 5172 return MachineOutlinerInstrType::Legal; 5173 } 5174 5175 // We can't fix it up, so don't outline it. 5176 return MachineOutlinerInstrType::Illegal; 5177 } 5178 5179 return MachineOutlinerInstrType::Legal; 5180 } 5181 5182 void AArch64InstrInfo::fixupPostOutline(MachineBasicBlock &MBB) const { 5183 for (MachineInstr &MI : MBB) { 5184 unsigned Base, Width; 5185 int64_t Offset; 5186 5187 // Is this a load or store with an immediate offset with SP as the base? 5188 if (!MI.mayLoadOrStore() || 5189 !getMemOpBaseRegImmOfsWidth(MI, Base, Offset, Width, &RI) || 5190 Base != AArch64::SP) 5191 continue; 5192 5193 // It is, so we have to fix it up. 5194 unsigned Scale; 5195 int64_t Dummy1, Dummy2; 5196 5197 MachineOperand &StackOffsetOperand = getMemOpBaseRegImmOfsOffsetOperand(MI); 5198 assert(StackOffsetOperand.isImm() && "Stack offset wasn't immediate!"); 5199 getMemOpInfo(MI.getOpcode(), Scale, Width, Dummy1, Dummy2); 5200 assert(Scale != 0 && "Unexpected opcode!"); 5201 5202 // We've pushed the return address to the stack, so add 16 to the offset. 5203 // This is safe, since we already checked if it would overflow when we 5204 // checked if this instruction was legal to outline. 5205 int64_t NewImm = (Offset + 16) / Scale; 5206 StackOffsetOperand.setImm(NewImm); 5207 } 5208 } 5209 5210 void AArch64InstrInfo::insertOutlinerEpilogue( 5211 MachineBasicBlock &MBB, MachineFunction &MF, 5212 const MachineOutlinerInfo &MInfo) const { 5213 5214 // Is there a call in the outlined range? 5215 if (std::any_of(MBB.instr_begin(), MBB.instr_end(), 5216 [](MachineInstr &MI) { return MI.isCall(); })) { 5217 // Fix up the instructions in the range, since we're going to modify the 5218 // stack. 5219 fixupPostOutline(MBB); 5220 5221 // LR has to be a live in so that we can save it. 5222 MBB.addLiveIn(AArch64::LR); 5223 5224 MachineBasicBlock::iterator It = MBB.begin(); 5225 MachineBasicBlock::iterator Et = MBB.end(); 5226 5227 if (MInfo.FrameConstructionID == MachineOutlinerTailCall) 5228 Et = std::prev(MBB.end()); 5229 5230 // Insert a save before the outlined region 5231 MachineInstr *STRXpre = BuildMI(MF, DebugLoc(), get(AArch64::STRXpre)) 5232 .addReg(AArch64::SP, RegState::Define) 5233 .addReg(AArch64::LR) 5234 .addReg(AArch64::SP) 5235 .addImm(-16); 5236 It = MBB.insert(It, STRXpre); 5237 5238 // Insert a restore before the terminator for the function. 5239 MachineInstr *LDRXpost = BuildMI(MF, DebugLoc(), get(AArch64::LDRXpost)) 5240 .addReg(AArch64::SP, RegState::Define) 5241 .addReg(AArch64::LR, RegState::Define) 5242 .addReg(AArch64::SP) 5243 .addImm(16); 5244 Et = MBB.insert(Et, LDRXpost); 5245 } 5246 5247 // If this is a tail call outlined function, then there's already a return. 5248 if (MInfo.FrameConstructionID == MachineOutlinerTailCall) 5249 return; 5250 5251 // It's not a tail call, so we have to insert the return ourselves. 5252 MachineInstr *ret = BuildMI(MF, DebugLoc(), get(AArch64::RET)) 5253 .addReg(AArch64::LR, RegState::Undef); 5254 MBB.insert(MBB.end(), ret); 5255 5256 // Did we have to modify the stack by saving the link register? 5257 if (MInfo.FrameConstructionID == MachineOutlinerNoLRSave) 5258 return; 5259 5260 // We modified the stack. 5261 // Walk over the basic block and fix up all the stack accesses. 5262 fixupPostOutline(MBB); 5263 } 5264 5265 void AArch64InstrInfo::insertOutlinerPrologue( 5266 MachineBasicBlock &MBB, MachineFunction &MF, 5267 const MachineOutlinerInfo &MInfo) const {} 5268 5269 MachineBasicBlock::iterator AArch64InstrInfo::insertOutlinedCall( 5270 Module &M, MachineBasicBlock &MBB, MachineBasicBlock::iterator &It, 5271 MachineFunction &MF, const MachineOutlinerInfo &MInfo) const { 5272 5273 // Are we tail calling? 5274 if (MInfo.CallConstructionID == MachineOutlinerTailCall) { 5275 // If yes, then we can just branch to the label. 5276 It = MBB.insert(It, BuildMI(MF, DebugLoc(), get(AArch64::B)) 5277 .addGlobalAddress(M.getNamedValue(MF.getName()))); 5278 return It; 5279 } 5280 5281 // Are we saving the link register? 5282 if (MInfo.CallConstructionID == MachineOutlinerNoLRSave) { 5283 // No, so just insert the call. 5284 It = MBB.insert(It, BuildMI(MF, DebugLoc(), get(AArch64::BL)) 5285 .addGlobalAddress(M.getNamedValue(MF.getName()))); 5286 return It; 5287 } 5288 5289 // We have a default call. Save the link register. 5290 MachineInstr *STRXpre = BuildMI(MF, DebugLoc(), get(AArch64::STRXpre)) 5291 .addReg(AArch64::SP, RegState::Define) 5292 .addReg(AArch64::LR) 5293 .addReg(AArch64::SP) 5294 .addImm(-16); 5295 It = MBB.insert(It, STRXpre); 5296 It++; 5297 5298 // Insert the call. 5299 It = MBB.insert(It, BuildMI(MF, DebugLoc(), get(AArch64::BL)) 5300 .addGlobalAddress(M.getNamedValue(MF.getName()))); 5301 5302 It++; 5303 5304 // Restore the link register. 5305 MachineInstr *LDRXpost = BuildMI(MF, DebugLoc(), get(AArch64::LDRXpost)) 5306 .addReg(AArch64::SP, RegState::Define) 5307 .addReg(AArch64::LR, RegState::Define) 5308 .addReg(AArch64::SP) 5309 .addImm(16); 5310 It = MBB.insert(It, LDRXpost); 5311 5312 return It; 5313 } 5314