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