AArch64InstrInfo.cpp revision e54360be01d1eaccd5ef27f510634927aaa887a4
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 "AArch64.h" 15#include "AArch64InstrInfo.h" 16#include "AArch64MachineFunctionInfo.h" 17#include "AArch64TargetMachine.h" 18#include "MCTargetDesc/AArch64MCTargetDesc.h" 19#include "Utils/AArch64BaseInfo.h" 20#include "llvm/CodeGen/MachineConstantPool.h" 21#include "llvm/CodeGen/MachineDominators.h" 22#include "llvm/CodeGen/MachineFrameInfo.h" 23#include "llvm/CodeGen/MachineFunctionPass.h" 24#include "llvm/CodeGen/MachineInstrBuilder.h" 25#include "llvm/CodeGen/MachineRegisterInfo.h" 26#include "llvm/IR/Function.h" 27#include "llvm/Support/ErrorHandling.h" 28#include "llvm/Support/TargetRegistry.h" 29 30#include <algorithm> 31 32#define GET_INSTRINFO_CTOR 33#include "AArch64GenInstrInfo.inc" 34 35using namespace llvm; 36 37AArch64InstrInfo::AArch64InstrInfo(const AArch64Subtarget &STI) 38 : AArch64GenInstrInfo(AArch64::ADJCALLSTACKDOWN, AArch64::ADJCALLSTACKUP), 39 Subtarget(STI) {} 40 41void AArch64InstrInfo::copyPhysReg(MachineBasicBlock &MBB, 42 MachineBasicBlock::iterator I, DebugLoc DL, 43 unsigned DestReg, unsigned SrcReg, 44 bool KillSrc) const { 45 unsigned Opc = 0; 46 unsigned ZeroReg = 0; 47 if (DestReg == AArch64::XSP || SrcReg == AArch64::XSP) { 48 // E.g. ADD xDst, xsp, #0 (, lsl #0) 49 BuildMI(MBB, I, DL, get(AArch64::ADDxxi_lsl0_s), DestReg) 50 .addReg(SrcReg) 51 .addImm(0); 52 return; 53 } else if (DestReg == AArch64::WSP || SrcReg == AArch64::WSP) { 54 // E.g. ADD wDST, wsp, #0 (, lsl #0) 55 BuildMI(MBB, I, DL, get(AArch64::ADDwwi_lsl0_s), DestReg) 56 .addReg(SrcReg) 57 .addImm(0); 58 return; 59 } else if (DestReg == AArch64::NZCV) { 60 assert(AArch64::GPR64RegClass.contains(SrcReg)); 61 // E.g. MSR NZCV, xDST 62 BuildMI(MBB, I, DL, get(AArch64::MSRix)) 63 .addImm(A64SysReg::NZCV) 64 .addReg(SrcReg); 65 } else if (SrcReg == AArch64::NZCV) { 66 assert(AArch64::GPR64RegClass.contains(DestReg)); 67 // E.g. MRS xDST, NZCV 68 BuildMI(MBB, I, DL, get(AArch64::MRSxi), DestReg) 69 .addImm(A64SysReg::NZCV); 70 } else if (AArch64::GPR64RegClass.contains(DestReg)) { 71 if(AArch64::GPR64RegClass.contains(SrcReg)){ 72 Opc = AArch64::ORRxxx_lsl; 73 ZeroReg = AArch64::XZR; 74 } else{ 75 assert(AArch64::FPR64RegClass.contains(SrcReg)); 76 BuildMI(MBB, I, DL, get(AArch64::FMOVxd), DestReg) 77 .addReg(SrcReg); 78 return; 79 } 80 } else if (AArch64::GPR32RegClass.contains(DestReg)) { 81 if(AArch64::GPR32RegClass.contains(SrcReg)){ 82 Opc = AArch64::ORRwww_lsl; 83 ZeroReg = AArch64::WZR; 84 } else{ 85 assert(AArch64::FPR32RegClass.contains(SrcReg)); 86 BuildMI(MBB, I, DL, get(AArch64::FMOVws), DestReg) 87 .addReg(SrcReg); 88 return; 89 } 90 } else if (AArch64::FPR32RegClass.contains(DestReg)) { 91 if(AArch64::FPR32RegClass.contains(SrcReg)){ 92 BuildMI(MBB, I, DL, get(AArch64::FMOVss), DestReg) 93 .addReg(SrcReg); 94 return; 95 } 96 else { 97 assert(AArch64::GPR32RegClass.contains(SrcReg)); 98 BuildMI(MBB, I, DL, get(AArch64::FMOVsw), DestReg) 99 .addReg(SrcReg); 100 return; 101 } 102 } else if (AArch64::FPR64RegClass.contains(DestReg)) { 103 if(AArch64::FPR64RegClass.contains(SrcReg)){ 104 BuildMI(MBB, I, DL, get(AArch64::FMOVdd), DestReg) 105 .addReg(SrcReg); 106 return; 107 } 108 else { 109 assert(AArch64::GPR64RegClass.contains(SrcReg)); 110 BuildMI(MBB, I, DL, get(AArch64::FMOVdx), DestReg) 111 .addReg(SrcReg); 112 return; 113 } 114 } else if (AArch64::FPR128RegClass.contains(DestReg)) { 115 assert(AArch64::FPR128RegClass.contains(SrcReg)); 116 117 // FIXME: there's no good way to do this, at least without NEON: 118 // + There's no single move instruction for q-registers 119 // + We can't create a spill slot and use normal STR/LDR because stack 120 // allocation has already happened 121 // + We can't go via X-registers with FMOV because register allocation has 122 // already happened. 123 // This may not be efficient, but at least it works. 124 BuildMI(MBB, I, DL, get(AArch64::LSFP128_PreInd_STR), AArch64::XSP) 125 .addReg(SrcReg) 126 .addReg(AArch64::XSP) 127 .addImm(0x1ff & -16); 128 129 BuildMI(MBB, I, DL, get(AArch64::LSFP128_PostInd_LDR), DestReg) 130 .addReg(AArch64::XSP, RegState::Define) 131 .addReg(AArch64::XSP) 132 .addImm(16); 133 return; 134 } else { 135 llvm_unreachable("Unknown register class in copyPhysReg"); 136 } 137 138 // E.g. ORR xDst, xzr, xSrc, lsl #0 139 BuildMI(MBB, I, DL, get(Opc), DestReg) 140 .addReg(ZeroReg) 141 .addReg(SrcReg) 142 .addImm(0); 143} 144 145/// Does the Opcode represent a conditional branch that we can remove and re-add 146/// at the end of a basic block? 147static bool isCondBranch(unsigned Opc) { 148 return Opc == AArch64::Bcc || Opc == AArch64::CBZw || Opc == AArch64::CBZx || 149 Opc == AArch64::CBNZw || Opc == AArch64::CBNZx || 150 Opc == AArch64::TBZwii || Opc == AArch64::TBZxii || 151 Opc == AArch64::TBNZwii || Opc == AArch64::TBNZxii; 152} 153 154/// Takes apart a given conditional branch MachineInstr (see isCondBranch), 155/// setting TBB to the destination basic block and populating the Cond vector 156/// with data necessary to recreate the conditional branch at a later 157/// date. First element will be the opcode, and subsequent ones define the 158/// conditions being branched on in an instruction-specific manner. 159static void classifyCondBranch(MachineInstr *I, MachineBasicBlock *&TBB, 160 SmallVectorImpl<MachineOperand> &Cond) { 161 switch(I->getOpcode()) { 162 case AArch64::Bcc: 163 case AArch64::CBZw: 164 case AArch64::CBZx: 165 case AArch64::CBNZw: 166 case AArch64::CBNZx: 167 // These instructions just have one predicate operand in position 0 (either 168 // a condition code or a register being compared). 169 Cond.push_back(MachineOperand::CreateImm(I->getOpcode())); 170 Cond.push_back(I->getOperand(0)); 171 TBB = I->getOperand(1).getMBB(); 172 return; 173 case AArch64::TBZwii: 174 case AArch64::TBZxii: 175 case AArch64::TBNZwii: 176 case AArch64::TBNZxii: 177 // These have two predicate operands: a register and a bit position. 178 Cond.push_back(MachineOperand::CreateImm(I->getOpcode())); 179 Cond.push_back(I->getOperand(0)); 180 Cond.push_back(I->getOperand(1)); 181 TBB = I->getOperand(2).getMBB(); 182 return; 183 default: 184 llvm_unreachable("Unknown conditional branch to classify"); 185 } 186} 187 188 189bool 190AArch64InstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB, 191 MachineBasicBlock *&FBB, 192 SmallVectorImpl<MachineOperand> &Cond, 193 bool AllowModify) const { 194 // If the block has no terminators, it just falls into the block after it. 195 MachineBasicBlock::iterator I = MBB.end(); 196 if (I == MBB.begin()) 197 return false; 198 --I; 199 while (I->isDebugValue()) { 200 if (I == MBB.begin()) 201 return false; 202 --I; 203 } 204 if (!isUnpredicatedTerminator(I)) 205 return false; 206 207 // Get the last instruction in the block. 208 MachineInstr *LastInst = I; 209 210 // If there is only one terminator instruction, process it. 211 unsigned LastOpc = LastInst->getOpcode(); 212 if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) { 213 if (LastOpc == AArch64::Bimm) { 214 TBB = LastInst->getOperand(0).getMBB(); 215 return false; 216 } 217 if (isCondBranch(LastOpc)) { 218 classifyCondBranch(LastInst, TBB, Cond); 219 return false; 220 } 221 return true; // Can't handle indirect branch. 222 } 223 224 // Get the instruction before it if it is a terminator. 225 MachineInstr *SecondLastInst = I; 226 unsigned SecondLastOpc = SecondLastInst->getOpcode(); 227 228 // If AllowModify is true and the block ends with two or more unconditional 229 // branches, delete all but the first unconditional branch. 230 if (AllowModify && LastOpc == AArch64::Bimm) { 231 while (SecondLastOpc == AArch64::Bimm) { 232 LastInst->eraseFromParent(); 233 LastInst = SecondLastInst; 234 LastOpc = LastInst->getOpcode(); 235 if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) { 236 // Return now the only terminator is an unconditional branch. 237 TBB = LastInst->getOperand(0).getMBB(); 238 return false; 239 } else { 240 SecondLastInst = I; 241 SecondLastOpc = SecondLastInst->getOpcode(); 242 } 243 } 244 } 245 246 // If there are three terminators, we don't know what sort of block this is. 247 if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(--I)) 248 return true; 249 250 // If the block ends with a B and a Bcc, handle it. 251 if (LastOpc == AArch64::Bimm) { 252 if (SecondLastOpc == AArch64::Bcc) { 253 TBB = SecondLastInst->getOperand(1).getMBB(); 254 Cond.push_back(MachineOperand::CreateImm(AArch64::Bcc)); 255 Cond.push_back(SecondLastInst->getOperand(0)); 256 FBB = LastInst->getOperand(0).getMBB(); 257 return false; 258 } else if (isCondBranch(SecondLastOpc)) { 259 classifyCondBranch(SecondLastInst, TBB, Cond); 260 FBB = LastInst->getOperand(0).getMBB(); 261 return false; 262 } 263 } 264 265 // If the block ends with two unconditional branches, handle it. The second 266 // one is not executed, so remove it. 267 if (SecondLastOpc == AArch64::Bimm && LastOpc == AArch64::Bimm) { 268 TBB = SecondLastInst->getOperand(0).getMBB(); 269 I = LastInst; 270 if (AllowModify) 271 I->eraseFromParent(); 272 return false; 273 } 274 275 // Otherwise, can't handle this. 276 return true; 277} 278 279bool AArch64InstrInfo::ReverseBranchCondition( 280 SmallVectorImpl<MachineOperand> &Cond) const { 281 switch (Cond[0].getImm()) { 282 case AArch64::Bcc: { 283 A64CC::CondCodes CC = static_cast<A64CC::CondCodes>(Cond[1].getImm()); 284 CC = A64InvertCondCode(CC); 285 Cond[1].setImm(CC); 286 return false; 287 } 288 case AArch64::CBZw: 289 Cond[0].setImm(AArch64::CBNZw); 290 return false; 291 case AArch64::CBZx: 292 Cond[0].setImm(AArch64::CBNZx); 293 return false; 294 case AArch64::CBNZw: 295 Cond[0].setImm(AArch64::CBZw); 296 return false; 297 case AArch64::CBNZx: 298 Cond[0].setImm(AArch64::CBZx); 299 return false; 300 case AArch64::TBZwii: 301 Cond[0].setImm(AArch64::TBNZwii); 302 return false; 303 case AArch64::TBZxii: 304 Cond[0].setImm(AArch64::TBNZxii); 305 return false; 306 case AArch64::TBNZwii: 307 Cond[0].setImm(AArch64::TBZwii); 308 return false; 309 case AArch64::TBNZxii: 310 Cond[0].setImm(AArch64::TBZxii); 311 return false; 312 default: 313 llvm_unreachable("Unknown branch type"); 314 } 315} 316 317 318unsigned 319AArch64InstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, 320 MachineBasicBlock *FBB, 321 const SmallVectorImpl<MachineOperand> &Cond, 322 DebugLoc DL) const { 323 if (FBB == 0 && Cond.empty()) { 324 BuildMI(&MBB, DL, get(AArch64::Bimm)).addMBB(TBB); 325 return 1; 326 } else if (FBB == 0) { 327 MachineInstrBuilder MIB = BuildMI(&MBB, DL, get(Cond[0].getImm())); 328 for (int i = 1, e = Cond.size(); i != e; ++i) 329 MIB.addOperand(Cond[i]); 330 MIB.addMBB(TBB); 331 return 1; 332 } 333 334 MachineInstrBuilder MIB = BuildMI(&MBB, DL, get(Cond[0].getImm())); 335 for (int i = 1, e = Cond.size(); i != e; ++i) 336 MIB.addOperand(Cond[i]); 337 MIB.addMBB(TBB); 338 339 BuildMI(&MBB, DL, get(AArch64::Bimm)).addMBB(FBB); 340 return 2; 341} 342 343unsigned AArch64InstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { 344 MachineBasicBlock::iterator I = MBB.end(); 345 if (I == MBB.begin()) return 0; 346 --I; 347 while (I->isDebugValue()) { 348 if (I == MBB.begin()) 349 return 0; 350 --I; 351 } 352 if (I->getOpcode() != AArch64::Bimm && !isCondBranch(I->getOpcode())) 353 return 0; 354 355 // Remove the branch. 356 I->eraseFromParent(); 357 358 I = MBB.end(); 359 360 if (I == MBB.begin()) return 1; 361 --I; 362 if (!isCondBranch(I->getOpcode())) 363 return 1; 364 365 // Remove the branch. 366 I->eraseFromParent(); 367 return 2; 368} 369 370bool 371AArch64InstrInfo::expandPostRAPseudo(MachineBasicBlock::iterator MBBI) const { 372 MachineInstr &MI = *MBBI; 373 MachineBasicBlock &MBB = *MI.getParent(); 374 375 unsigned Opcode = MI.getOpcode(); 376 switch (Opcode) { 377 case AArch64::TLSDESC_BLRx: { 378 MachineInstr *NewMI = 379 BuildMI(MBB, MBBI, MI.getDebugLoc(), get(AArch64::TLSDESCCALL)) 380 .addOperand(MI.getOperand(1)); 381 MI.setDesc(get(AArch64::BLRx)); 382 383 llvm::finalizeBundle(MBB, NewMI, *++MBBI); 384 return true; 385 } 386 default: 387 return false; 388 } 389 390 return false; 391} 392 393void 394AArch64InstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, 395 MachineBasicBlock::iterator MBBI, 396 unsigned SrcReg, bool isKill, 397 int FrameIdx, 398 const TargetRegisterClass *RC, 399 const TargetRegisterInfo *TRI) const { 400 DebugLoc DL = MBB.findDebugLoc(MBBI); 401 MachineFunction &MF = *MBB.getParent(); 402 MachineFrameInfo &MFI = *MF.getFrameInfo(); 403 unsigned Align = MFI.getObjectAlignment(FrameIdx); 404 405 MachineMemOperand *MMO 406 = MF.getMachineMemOperand(MachinePointerInfo::getFixedStack(FrameIdx), 407 MachineMemOperand::MOStore, 408 MFI.getObjectSize(FrameIdx), 409 Align); 410 411 unsigned StoreOp = 0; 412 if (RC->hasType(MVT::i64) || RC->hasType(MVT::i32)) { 413 switch(RC->getSize()) { 414 case 4: StoreOp = AArch64::LS32_STR; break; 415 case 8: StoreOp = AArch64::LS64_STR; break; 416 default: 417 llvm_unreachable("Unknown size for regclass"); 418 } 419 } else { 420 assert((RC->hasType(MVT::f32) || RC->hasType(MVT::f64) || 421 RC->hasType(MVT::f128)) 422 && "Expected integer or floating type for store"); 423 switch (RC->getSize()) { 424 case 4: StoreOp = AArch64::LSFP32_STR; break; 425 case 8: StoreOp = AArch64::LSFP64_STR; break; 426 case 16: StoreOp = AArch64::LSFP128_STR; break; 427 default: 428 llvm_unreachable("Unknown size for regclass"); 429 } 430 } 431 432 MachineInstrBuilder NewMI = BuildMI(MBB, MBBI, DL, get(StoreOp)); 433 NewMI.addReg(SrcReg, getKillRegState(isKill)) 434 .addFrameIndex(FrameIdx) 435 .addImm(0) 436 .addMemOperand(MMO); 437 438} 439 440void 441AArch64InstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, 442 MachineBasicBlock::iterator MBBI, 443 unsigned DestReg, int FrameIdx, 444 const TargetRegisterClass *RC, 445 const TargetRegisterInfo *TRI) const { 446 DebugLoc DL = MBB.findDebugLoc(MBBI); 447 MachineFunction &MF = *MBB.getParent(); 448 MachineFrameInfo &MFI = *MF.getFrameInfo(); 449 unsigned Align = MFI.getObjectAlignment(FrameIdx); 450 451 MachineMemOperand *MMO 452 = MF.getMachineMemOperand(MachinePointerInfo::getFixedStack(FrameIdx), 453 MachineMemOperand::MOLoad, 454 MFI.getObjectSize(FrameIdx), 455 Align); 456 457 unsigned LoadOp = 0; 458 if (RC->hasType(MVT::i64) || RC->hasType(MVT::i32)) { 459 switch(RC->getSize()) { 460 case 4: LoadOp = AArch64::LS32_LDR; break; 461 case 8: LoadOp = AArch64::LS64_LDR; break; 462 default: 463 llvm_unreachable("Unknown size for regclass"); 464 } 465 } else { 466 assert((RC->hasType(MVT::f32) || RC->hasType(MVT::f64) 467 || RC->hasType(MVT::f128)) 468 && "Expected integer or floating type for store"); 469 switch (RC->getSize()) { 470 case 4: LoadOp = AArch64::LSFP32_LDR; break; 471 case 8: LoadOp = AArch64::LSFP64_LDR; break; 472 case 16: LoadOp = AArch64::LSFP128_LDR; break; 473 default: 474 llvm_unreachable("Unknown size for regclass"); 475 } 476 } 477 478 MachineInstrBuilder NewMI = BuildMI(MBB, MBBI, DL, get(LoadOp), DestReg); 479 NewMI.addFrameIndex(FrameIdx) 480 .addImm(0) 481 .addMemOperand(MMO); 482} 483 484unsigned AArch64InstrInfo::estimateRSStackLimit(MachineFunction &MF) const { 485 unsigned Limit = (1 << 16) - 1; 486 for (MachineFunction::iterator BB = MF.begin(),E = MF.end(); BB != E; ++BB) { 487 for (MachineBasicBlock::iterator I = BB->begin(), E = BB->end(); 488 I != E; ++I) { 489 for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) { 490 if (!I->getOperand(i).isFI()) continue; 491 492 // When using ADDxxi_lsl0_s to get the address of a stack object, 0xfff 493 // is the largest offset guaranteed to fit in the immediate offset. 494 if (I->getOpcode() == AArch64::ADDxxi_lsl0_s) { 495 Limit = std::min(Limit, 0xfffu); 496 break; 497 } 498 499 int AccessScale, MinOffset, MaxOffset; 500 getAddressConstraints(*I, AccessScale, MinOffset, MaxOffset); 501 Limit = std::min(Limit, static_cast<unsigned>(MaxOffset)); 502 503 break; // At most one FI per instruction 504 } 505 } 506 } 507 508 return Limit; 509} 510void AArch64InstrInfo::getAddressConstraints(const MachineInstr &MI, 511 int &AccessScale, int &MinOffset, 512 int &MaxOffset) const { 513 switch (MI.getOpcode()) { 514 default: llvm_unreachable("Unkown load/store kind"); 515 case TargetOpcode::DBG_VALUE: 516 AccessScale = 1; 517 MinOffset = INT_MIN; 518 MaxOffset = INT_MAX; 519 return; 520 case AArch64::LS8_LDR: case AArch64::LS8_STR: 521 case AArch64::LSFP8_LDR: case AArch64::LSFP8_STR: 522 case AArch64::LDRSBw: 523 case AArch64::LDRSBx: 524 AccessScale = 1; 525 MinOffset = 0; 526 MaxOffset = 0xfff; 527 return; 528 case AArch64::LS16_LDR: case AArch64::LS16_STR: 529 case AArch64::LSFP16_LDR: case AArch64::LSFP16_STR: 530 case AArch64::LDRSHw: 531 case AArch64::LDRSHx: 532 AccessScale = 2; 533 MinOffset = 0; 534 MaxOffset = 0xfff * AccessScale; 535 return; 536 case AArch64::LS32_LDR: case AArch64::LS32_STR: 537 case AArch64::LSFP32_LDR: case AArch64::LSFP32_STR: 538 case AArch64::LDRSWx: 539 case AArch64::LDPSWx: 540 AccessScale = 4; 541 MinOffset = 0; 542 MaxOffset = 0xfff * AccessScale; 543 return; 544 case AArch64::LS64_LDR: case AArch64::LS64_STR: 545 case AArch64::LSFP64_LDR: case AArch64::LSFP64_STR: 546 case AArch64::PRFM: 547 AccessScale = 8; 548 MinOffset = 0; 549 MaxOffset = 0xfff * AccessScale; 550 return; 551 case AArch64::LSFP128_LDR: case AArch64::LSFP128_STR: 552 AccessScale = 16; 553 MinOffset = 0; 554 MaxOffset = 0xfff * AccessScale; 555 return; 556 case AArch64::LSPair32_LDR: case AArch64::LSPair32_STR: 557 case AArch64::LSFPPair32_LDR: case AArch64::LSFPPair32_STR: 558 AccessScale = 4; 559 MinOffset = -0x40 * AccessScale; 560 MaxOffset = 0x3f * AccessScale; 561 return; 562 case AArch64::LSPair64_LDR: case AArch64::LSPair64_STR: 563 case AArch64::LSFPPair64_LDR: case AArch64::LSFPPair64_STR: 564 AccessScale = 8; 565 MinOffset = -0x40 * AccessScale; 566 MaxOffset = 0x3f * AccessScale; 567 return; 568 case AArch64::LSFPPair128_LDR: case AArch64::LSFPPair128_STR: 569 AccessScale = 16; 570 MinOffset = -0x40 * AccessScale; 571 MaxOffset = 0x3f * AccessScale; 572 return; 573 } 574} 575 576unsigned AArch64InstrInfo::getInstSizeInBytes(const MachineInstr &MI) const { 577 const MCInstrDesc &MCID = MI.getDesc(); 578 const MachineBasicBlock &MBB = *MI.getParent(); 579 const MachineFunction &MF = *MBB.getParent(); 580 const MCAsmInfo &MAI = *MF.getTarget().getMCAsmInfo(); 581 582 if (MCID.getSize()) 583 return MCID.getSize(); 584 585 if (MI.getOpcode() == AArch64::INLINEASM) 586 return getInlineAsmLength(MI.getOperand(0).getSymbolName(), MAI); 587 588 if (MI.isLabel()) 589 return 0; 590 591 switch (MI.getOpcode()) { 592 case TargetOpcode::BUNDLE: 593 return getInstBundleLength(MI); 594 case TargetOpcode::IMPLICIT_DEF: 595 case TargetOpcode::KILL: 596 case TargetOpcode::PROLOG_LABEL: 597 case TargetOpcode::EH_LABEL: 598 case TargetOpcode::DBG_VALUE: 599 return 0; 600 case AArch64::TLSDESCCALL: 601 return 0; 602 default: 603 llvm_unreachable("Unknown instruction class"); 604 } 605} 606 607unsigned AArch64InstrInfo::getInstBundleLength(const MachineInstr &MI) const { 608 unsigned Size = 0; 609 MachineBasicBlock::const_instr_iterator I = MI; 610 MachineBasicBlock::const_instr_iterator E = MI.getParent()->instr_end(); 611 while (++I != E && I->isInsideBundle()) { 612 assert(!I->isBundle() && "No nested bundle!"); 613 Size += getInstSizeInBytes(*I); 614 } 615 return Size; 616} 617 618bool llvm::rewriteA64FrameIndex(MachineInstr &MI, unsigned FrameRegIdx, 619 unsigned FrameReg, int &Offset, 620 const AArch64InstrInfo &TII) { 621 MachineBasicBlock &MBB = *MI.getParent(); 622 MachineFunction &MF = *MBB.getParent(); 623 MachineFrameInfo &MFI = *MF.getFrameInfo(); 624 625 MFI.getObjectOffset(FrameRegIdx); 626 llvm_unreachable("Unimplemented rewriteFrameIndex"); 627} 628 629void llvm::emitRegUpdate(MachineBasicBlock &MBB, 630 MachineBasicBlock::iterator MBBI, 631 DebugLoc dl, const TargetInstrInfo &TII, 632 unsigned DstReg, unsigned SrcReg, unsigned ScratchReg, 633 int64_t NumBytes, MachineInstr::MIFlag MIFlags) { 634 if (NumBytes == 0 && DstReg == SrcReg) 635 return; 636 else if (abs64(NumBytes) & ~0xffffff) { 637 // Generically, we have to materialize the offset into a temporary register 638 // and subtract it. There are a couple of ways this could be done, for now 639 // we'll use a movz/movk or movn/movk sequence. 640 uint64_t Bits = static_cast<uint64_t>(abs64(NumBytes)); 641 BuildMI(MBB, MBBI, dl, TII.get(AArch64::MOVZxii), ScratchReg) 642 .addImm(0xffff & Bits).addImm(0) 643 .setMIFlags(MIFlags); 644 645 Bits >>= 16; 646 if (Bits & 0xffff) { 647 BuildMI(MBB, MBBI, dl, TII.get(AArch64::MOVKxii), ScratchReg) 648 .addReg(ScratchReg) 649 .addImm(0xffff & Bits).addImm(1) 650 .setMIFlags(MIFlags); 651 } 652 653 Bits >>= 16; 654 if (Bits & 0xffff) { 655 BuildMI(MBB, MBBI, dl, TII.get(AArch64::MOVKxii), ScratchReg) 656 .addReg(ScratchReg) 657 .addImm(0xffff & Bits).addImm(2) 658 .setMIFlags(MIFlags); 659 } 660 661 Bits >>= 16; 662 if (Bits & 0xffff) { 663 BuildMI(MBB, MBBI, dl, TII.get(AArch64::MOVKxii), ScratchReg) 664 .addReg(ScratchReg) 665 .addImm(0xffff & Bits).addImm(3) 666 .setMIFlags(MIFlags); 667 } 668 669 // ADD DST, SRC, xTMP (, lsl #0) 670 unsigned AddOp = NumBytes > 0 ? AArch64::ADDxxx_uxtx : AArch64::SUBxxx_uxtx; 671 BuildMI(MBB, MBBI, dl, TII.get(AddOp), DstReg) 672 .addReg(SrcReg, RegState::Kill) 673 .addReg(ScratchReg, RegState::Kill) 674 .addImm(0) 675 .setMIFlag(MIFlags); 676 return; 677 } 678 679 // Now we know that the adjustment can be done in at most two add/sub 680 // (immediate) instructions, which is always more efficient than a 681 // literal-pool load, or even a hypothetical movz/movk/add sequence 682 683 // Decide whether we're doing addition or subtraction 684 unsigned LowOp, HighOp; 685 if (NumBytes >= 0) { 686 LowOp = AArch64::ADDxxi_lsl0_s; 687 HighOp = AArch64::ADDxxi_lsl12_s; 688 } else { 689 LowOp = AArch64::SUBxxi_lsl0_s; 690 HighOp = AArch64::SUBxxi_lsl12_s; 691 NumBytes = abs64(NumBytes); 692 } 693 694 // If we're here, at the very least a move needs to be produced, which just 695 // happens to be materializable by an ADD. 696 if ((NumBytes & 0xfff) || NumBytes == 0) { 697 BuildMI(MBB, MBBI, dl, TII.get(LowOp), DstReg) 698 .addReg(SrcReg, RegState::Kill) 699 .addImm(NumBytes & 0xfff) 700 .setMIFlag(MIFlags); 701 702 // Next update should use the register we've just defined. 703 SrcReg = DstReg; 704 } 705 706 if (NumBytes & 0xfff000) { 707 BuildMI(MBB, MBBI, dl, TII.get(HighOp), DstReg) 708 .addReg(SrcReg, RegState::Kill) 709 .addImm(NumBytes >> 12) 710 .setMIFlag(MIFlags); 711 } 712} 713 714void llvm::emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, 715 DebugLoc dl, const TargetInstrInfo &TII, 716 unsigned ScratchReg, int64_t NumBytes, 717 MachineInstr::MIFlag MIFlags) { 718 emitRegUpdate(MBB, MI, dl, TII, AArch64::XSP, AArch64::XSP, AArch64::X16, 719 NumBytes, MIFlags); 720} 721 722 723namespace { 724 struct LDTLSCleanup : public MachineFunctionPass { 725 static char ID; 726 LDTLSCleanup() : MachineFunctionPass(ID) {} 727 728 virtual bool runOnMachineFunction(MachineFunction &MF) { 729 AArch64MachineFunctionInfo* MFI 730 = MF.getInfo<AArch64MachineFunctionInfo>(); 731 if (MFI->getNumLocalDynamicTLSAccesses() < 2) { 732 // No point folding accesses if there isn't at least two. 733 return false; 734 } 735 736 MachineDominatorTree *DT = &getAnalysis<MachineDominatorTree>(); 737 return VisitNode(DT->getRootNode(), 0); 738 } 739 740 // Visit the dominator subtree rooted at Node in pre-order. 741 // If TLSBaseAddrReg is non-null, then use that to replace any 742 // TLS_base_addr instructions. Otherwise, create the register 743 // when the first such instruction is seen, and then use it 744 // as we encounter more instructions. 745 bool VisitNode(MachineDomTreeNode *Node, unsigned TLSBaseAddrReg) { 746 MachineBasicBlock *BB = Node->getBlock(); 747 bool Changed = false; 748 749 // Traverse the current block. 750 for (MachineBasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; 751 ++I) { 752 switch (I->getOpcode()) { 753 case AArch64::TLSDESC_BLRx: 754 // Make sure it's a local dynamic access. 755 if (!I->getOperand(1).isSymbol() || 756 strcmp(I->getOperand(1).getSymbolName(), "_TLS_MODULE_BASE_")) 757 break; 758 759 if (TLSBaseAddrReg) 760 I = ReplaceTLSBaseAddrCall(I, TLSBaseAddrReg); 761 else 762 I = SetRegister(I, &TLSBaseAddrReg); 763 Changed = true; 764 break; 765 default: 766 break; 767 } 768 } 769 770 // Visit the children of this block in the dominator tree. 771 for (MachineDomTreeNode::iterator I = Node->begin(), E = Node->end(); 772 I != E; ++I) { 773 Changed |= VisitNode(*I, TLSBaseAddrReg); 774 } 775 776 return Changed; 777 } 778 779 // Replace the TLS_base_addr instruction I with a copy from 780 // TLSBaseAddrReg, returning the new instruction. 781 MachineInstr *ReplaceTLSBaseAddrCall(MachineInstr *I, 782 unsigned TLSBaseAddrReg) { 783 MachineFunction *MF = I->getParent()->getParent(); 784 const AArch64TargetMachine *TM = 785 static_cast<const AArch64TargetMachine *>(&MF->getTarget()); 786 const AArch64InstrInfo *TII = TM->getInstrInfo(); 787 788 // Insert a Copy from TLSBaseAddrReg to x0, which is where the rest of the 789 // code sequence assumes the address will be. 790 MachineInstr *Copy = BuildMI(*I->getParent(), I, I->getDebugLoc(), 791 TII->get(TargetOpcode::COPY), 792 AArch64::X0) 793 .addReg(TLSBaseAddrReg); 794 795 // Erase the TLS_base_addr instruction. 796 I->eraseFromParent(); 797 798 return Copy; 799 } 800 801 // Create a virtal register in *TLSBaseAddrReg, and populate it by 802 // inserting a copy instruction after I. Returns the new instruction. 803 MachineInstr *SetRegister(MachineInstr *I, unsigned *TLSBaseAddrReg) { 804 MachineFunction *MF = I->getParent()->getParent(); 805 const AArch64TargetMachine *TM = 806 static_cast<const AArch64TargetMachine *>(&MF->getTarget()); 807 const AArch64InstrInfo *TII = TM->getInstrInfo(); 808 809 // Create a virtual register for the TLS base address. 810 MachineRegisterInfo &RegInfo = MF->getRegInfo(); 811 *TLSBaseAddrReg = RegInfo.createVirtualRegister(&AArch64::GPR64RegClass); 812 813 // Insert a copy from X0 to TLSBaseAddrReg for later. 814 MachineInstr *Next = I->getNextNode(); 815 MachineInstr *Copy = BuildMI(*I->getParent(), Next, I->getDebugLoc(), 816 TII->get(TargetOpcode::COPY), 817 *TLSBaseAddrReg) 818 .addReg(AArch64::X0); 819 820 return Copy; 821 } 822 823 virtual const char *getPassName() const { 824 return "Local Dynamic TLS Access Clean-up"; 825 } 826 827 virtual void getAnalysisUsage(AnalysisUsage &AU) const { 828 AU.setPreservesCFG(); 829 AU.addRequired<MachineDominatorTree>(); 830 MachineFunctionPass::getAnalysisUsage(AU); 831 } 832 }; 833} 834 835char LDTLSCleanup::ID = 0; 836FunctionPass* 837llvm::createAArch64CleanupLocalDynamicTLSPass() { return new LDTLSCleanup(); } 838