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