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