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