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