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