LCOV - code coverage report
Current view: top level - lib/Target/AArch64 - AArch64CleanupLocalDynamicTLSPass.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 49 50 98.0 %
Date: 2017-09-14 15:23:50 Functions: 11 12 91.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===-- AArch64CleanupLocalDynamicTLSPass.cpp ---------------------*- C++ -*-=//
       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             : // Local-dynamic access to thread-local variables proceeds in three stages.
      11             : //
      12             : // 1. The offset of this Module's thread-local area from TPIDR_EL0 is calculated
      13             : //    in much the same way as a general-dynamic TLS-descriptor access against
      14             : //    the special symbol _TLS_MODULE_BASE.
      15             : // 2. The variable's offset from _TLS_MODULE_BASE_ is calculated using
      16             : //    instructions with "dtprel" modifiers.
      17             : // 3. These two are added, together with TPIDR_EL0, to obtain the variable's
      18             : //    true address.
      19             : //
      20             : // This is only better than general-dynamic access to the variable if two or
      21             : // more of the first stage TLS-descriptor calculations can be combined. This
      22             : // pass looks through a function and performs such combinations.
      23             : //
      24             : //===----------------------------------------------------------------------===//
      25             : #include "AArch64.h"
      26             : #include "AArch64InstrInfo.h"
      27             : #include "AArch64MachineFunctionInfo.h"
      28             : #include "AArch64TargetMachine.h"
      29             : #include "llvm/CodeGen/MachineDominators.h"
      30             : #include "llvm/CodeGen/MachineFunction.h"
      31             : #include "llvm/CodeGen/MachineFunctionPass.h"
      32             : #include "llvm/CodeGen/MachineInstrBuilder.h"
      33             : #include "llvm/CodeGen/MachineRegisterInfo.h"
      34             : using namespace llvm;
      35             : 
      36             : #define TLSCLEANUP_PASS_NAME "AArch64 Local Dynamic TLS Access Clean-up"
      37             : 
      38             : namespace {
      39         646 : struct LDTLSCleanup : public MachineFunctionPass {
      40             :   static char ID;
      41         650 :   LDTLSCleanup() : MachineFunctionPass(ID) {
      42         650 :     initializeLDTLSCleanupPass(*PassRegistry::getPassRegistry());
      43         650 :   }
      44             : 
      45        8835 :   bool runOnMachineFunction(MachineFunction &MF) override {
      46        8835 :     if (skipFunction(*MF.getFunction()))
      47             :       return false;
      48             : 
      49        8835 :     AArch64FunctionInfo *AFI = MF.getInfo<AArch64FunctionInfo>();
      50        8835 :     if (AFI->getNumLocalDynamicTLSAccesses() < 2) {
      51             :       // No point folding accesses if there isn't at least two.
      52             :       return false;
      53             :     }
      54             : 
      55           2 :     MachineDominatorTree *DT = &getAnalysis<MachineDominatorTree>();
      56           2 :     return VisitNode(DT->getRootNode(), 0);
      57             :   }
      58             : 
      59             :   // Visit the dominator subtree rooted at Node in pre-order.
      60             :   // If TLSBaseAddrReg is non-null, then use that to replace any
      61             :   // TLS_base_addr instructions. Otherwise, create the register
      62             :   // when the first such instruction is seen, and then use it
      63             :   // as we encounter more instructions.
      64           2 :   bool VisitNode(MachineDomTreeNode *Node, unsigned TLSBaseAddrReg) {
      65           2 :     MachineBasicBlock *BB = Node->getBlock();
      66           2 :     bool Changed = false;
      67             : 
      68             :     // Traverse the current block.
      69          34 :     for (MachineBasicBlock::iterator I = BB->begin(), E = BB->end(); I != E;
      70             :          ++I) {
      71          56 :       switch (I->getOpcode()) {
      72           4 :       case AArch64::TLSDESC_CALLSEQ:
      73             :         // Make sure it's a local dynamic access.
      74          12 :         if (!I->getOperand(0).isSymbol() ||
      75           4 :             strcmp(I->getOperand(0).getSymbolName(), "_TLS_MODULE_BASE_"))
      76             :           break;
      77             : 
      78           4 :         if (TLSBaseAddrReg)
      79           6 :           I = replaceTLSBaseAddrCall(*I, TLSBaseAddrReg);
      80             :         else
      81           4 :           I = setRegister(*I, &TLSBaseAddrReg);
      82             :         Changed = true;
      83             :         break;
      84             :       default:
      85             :         break;
      86             :       }
      87             :     }
      88             : 
      89             :     // Visit the children of this block in the dominator tree.
      90           8 :     for (MachineDomTreeNode *N : *Node) {
      91           0 :       Changed |= VisitNode(N, TLSBaseAddrReg);
      92             :     }
      93             : 
      94           2 :     return Changed;
      95             :   }
      96             : 
      97             :   // Replace the TLS_base_addr instruction I with a copy from
      98             :   // TLSBaseAddrReg, returning the new instruction.
      99           2 :   MachineInstr *replaceTLSBaseAddrCall(MachineInstr &I,
     100             :                                        unsigned TLSBaseAddrReg) {
     101           2 :     MachineFunction *MF = I.getParent()->getParent();
     102           2 :     const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo();
     103             : 
     104             :     // Insert a Copy from TLSBaseAddrReg to x0, which is where the rest of the
     105             :     // code sequence assumes the address will be.
     106           4 :     MachineInstr *Copy = BuildMI(*I.getParent(), I, I.getDebugLoc(),
     107           6 :                                  TII->get(TargetOpcode::COPY), AArch64::X0)
     108           2 :                              .addReg(TLSBaseAddrReg);
     109             : 
     110             :     // Erase the TLS_base_addr instruction.
     111           2 :     I.eraseFromParent();
     112             : 
     113           2 :     return Copy;
     114             :   }
     115             : 
     116             :   // Create a virtual register in *TLSBaseAddrReg, and populate it by
     117             :   // inserting a copy instruction after I. Returns the new instruction.
     118           2 :   MachineInstr *setRegister(MachineInstr &I, unsigned *TLSBaseAddrReg) {
     119           2 :     MachineFunction *MF = I.getParent()->getParent();
     120           2 :     const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo();
     121             : 
     122             :     // Create a virtual register for the TLS base address.
     123           2 :     MachineRegisterInfo &RegInfo = MF->getRegInfo();
     124           2 :     *TLSBaseAddrReg = RegInfo.createVirtualRegister(&AArch64::GPR64RegClass);
     125             : 
     126             :     // Insert a copy from X0 to TLSBaseAddrReg for later.
     127             :     MachineInstr *Copy =
     128           8 :         BuildMI(*I.getParent(), ++I.getIterator(), I.getDebugLoc(),
     129           6 :                 TII->get(TargetOpcode::COPY), *TLSBaseAddrReg)
     130           2 :             .addReg(AArch64::X0);
     131             : 
     132           2 :     return Copy;
     133             :   }
     134             : 
     135           4 :   StringRef getPassName() const override { return TLSCLEANUP_PASS_NAME; }
     136             : 
     137         649 :   void getAnalysisUsage(AnalysisUsage &AU) const override {
     138         649 :     AU.setPreservesCFG();
     139         649 :     AU.addRequired<MachineDominatorTree>();
     140         649 :     MachineFunctionPass::getAnalysisUsage(AU);
     141         649 :   }
     142             : };
     143             : }
     144             : 
     145      314503 : INITIALIZE_PASS(LDTLSCleanup, "aarch64-local-dynamic-tls-cleanup",
     146             :                 TLSCLEANUP_PASS_NAME, false, false)
     147             : 
     148             : char LDTLSCleanup::ID = 0;
     149         650 : FunctionPass *llvm::createAArch64CleanupLocalDynamicTLSPass() {
     150         650 :   return new LDTLSCleanup();
     151             : }

Generated by: LCOV version 1.13