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