LLVM API Documentation

AArch64CleanupLocalDynamicTLSPass.cpp
Go to the documentation of this file.
00001 //===-- AArch64CleanupLocalDynamicTLSPass.cpp ---------------------*- C++ -*-=//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // Local-dynamic access to thread-local variables proceeds in three stages.
00011 //
00012 // 1. The offset of this Module's thread-local area from TPIDR_EL0 is calculated
00013 //    in much the same way as a general-dynamic TLS-descriptor access against
00014 //    the special symbol _TLS_MODULE_BASE.
00015 // 2. The variable's offset from _TLS_MODULE_BASE_ is calculated using
00016 //    instructions with "dtprel" modifiers.
00017 // 3. These two are added, together with TPIDR_EL0, to obtain the variable's
00018 //    true address.
00019 //
00020 // This is only better than general-dynamic access to the variable if two or
00021 // more of the first stage TLS-descriptor calculations can be combined. This
00022 // pass looks through a function and performs such combinations.
00023 //
00024 //===----------------------------------------------------------------------===//
00025 #include "AArch64.h"
00026 #include "AArch64InstrInfo.h"
00027 #include "AArch64MachineFunctionInfo.h"
00028 #include "AArch64TargetMachine.h"
00029 #include "llvm/CodeGen/MachineDominators.h"
00030 #include "llvm/CodeGen/MachineFunction.h"
00031 #include "llvm/CodeGen/MachineFunctionPass.h"
00032 #include "llvm/CodeGen/MachineInstrBuilder.h"
00033 #include "llvm/CodeGen/MachineRegisterInfo.h"
00034 using namespace llvm;
00035 
00036 namespace {
00037 struct LDTLSCleanup : public MachineFunctionPass {
00038   static char ID;
00039   LDTLSCleanup() : MachineFunctionPass(ID) {}
00040 
00041   bool runOnMachineFunction(MachineFunction &MF) override {
00042     AArch64FunctionInfo *AFI = MF.getInfo<AArch64FunctionInfo>();
00043     if (AFI->getNumLocalDynamicTLSAccesses() < 2) {
00044       // No point folding accesses if there isn't at least two.
00045       return false;
00046     }
00047 
00048     MachineDominatorTree *DT = &getAnalysis<MachineDominatorTree>();
00049     return VisitNode(DT->getRootNode(), 0);
00050   }
00051 
00052   // Visit the dominator subtree rooted at Node in pre-order.
00053   // If TLSBaseAddrReg is non-null, then use that to replace any
00054   // TLS_base_addr instructions. Otherwise, create the register
00055   // when the first such instruction is seen, and then use it
00056   // as we encounter more instructions.
00057   bool VisitNode(MachineDomTreeNode *Node, unsigned TLSBaseAddrReg) {
00058     MachineBasicBlock *BB = Node->getBlock();
00059     bool Changed = false;
00060 
00061     // Traverse the current block.
00062     for (MachineBasicBlock::iterator I = BB->begin(), E = BB->end(); I != E;
00063          ++I) {
00064       switch (I->getOpcode()) {
00065       case AArch64::TLSDESC_BLR:
00066         // Make sure it's a local dynamic access.
00067         if (!I->getOperand(1).isSymbol() ||
00068             strcmp(I->getOperand(1).getSymbolName(), "_TLS_MODULE_BASE_"))
00069           break;
00070 
00071         if (TLSBaseAddrReg)
00072           I = replaceTLSBaseAddrCall(I, TLSBaseAddrReg);
00073         else
00074           I = setRegister(I, &TLSBaseAddrReg);
00075         Changed = true;
00076         break;
00077       default:
00078         break;
00079       }
00080     }
00081 
00082     // Visit the children of this block in the dominator tree.
00083     for (MachineDomTreeNode *N : *Node) {
00084       Changed |= VisitNode(N, TLSBaseAddrReg);
00085     }
00086 
00087     return Changed;
00088   }
00089 
00090   // Replace the TLS_base_addr instruction I with a copy from
00091   // TLSBaseAddrReg, returning the new instruction.
00092   MachineInstr *replaceTLSBaseAddrCall(MachineInstr *I,
00093                                        unsigned TLSBaseAddrReg) {
00094     MachineFunction *MF = I->getParent()->getParent();
00095     const AArch64TargetMachine *TM =
00096         static_cast<const AArch64TargetMachine *>(&MF->getTarget());
00097     const AArch64InstrInfo *TII = TM->getSubtargetImpl()->getInstrInfo();
00098 
00099     // Insert a Copy from TLSBaseAddrReg to x0, which is where the rest of the
00100     // code sequence assumes the address will be.
00101     MachineInstr *Copy = BuildMI(*I->getParent(), I, I->getDebugLoc(),
00102                                  TII->get(TargetOpcode::COPY),
00103                                  AArch64::X0).addReg(TLSBaseAddrReg);
00104 
00105     // Erase the TLS_base_addr instruction.
00106     I->eraseFromParent();
00107 
00108     return Copy;
00109   }
00110 
00111   // Create a virtal register in *TLSBaseAddrReg, and populate it by
00112   // inserting a copy instruction after I. Returns the new instruction.
00113   MachineInstr *setRegister(MachineInstr *I, unsigned *TLSBaseAddrReg) {
00114     MachineFunction *MF = I->getParent()->getParent();
00115     const AArch64TargetMachine *TM =
00116         static_cast<const AArch64TargetMachine *>(&MF->getTarget());
00117     const AArch64InstrInfo *TII = TM->getSubtargetImpl()->getInstrInfo();
00118 
00119     // Create a virtual register for the TLS base address.
00120     MachineRegisterInfo &RegInfo = MF->getRegInfo();
00121     *TLSBaseAddrReg = RegInfo.createVirtualRegister(&AArch64::GPR64RegClass);
00122 
00123     // Insert a copy from X0 to TLSBaseAddrReg for later.
00124     MachineInstr *Next = I->getNextNode();
00125     MachineInstr *Copy = BuildMI(*I->getParent(), Next, I->getDebugLoc(),
00126                                  TII->get(TargetOpcode::COPY),
00127                                  *TLSBaseAddrReg).addReg(AArch64::X0);
00128 
00129     return Copy;
00130   }
00131 
00132   const char *getPassName() const override {
00133     return "Local Dynamic TLS Access Clean-up";
00134   }
00135 
00136   void getAnalysisUsage(AnalysisUsage &AU) const override {
00137     AU.setPreservesCFG();
00138     AU.addRequired<MachineDominatorTree>();
00139     MachineFunctionPass::getAnalysisUsage(AU);
00140   }
00141 };
00142 }
00143 
00144 char LDTLSCleanup::ID = 0;
00145 FunctionPass *llvm::createAArch64CleanupLocalDynamicTLSPass() {
00146   return new LDTLSCleanup();
00147 }