LCOV - code coverage report
Current view: top level - lib/Target/AArch64 - AArch64CleanupLocalDynamicTLSPass.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 28 46 60.9 %
Date: 2018-10-20 13:21:21 Functions: 8 10 80.0 %
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 "llvm/CodeGen/MachineDominators.h"
      29             : #include "llvm/CodeGen/MachineFunction.h"
      30             : #include "llvm/CodeGen/MachineFunctionPass.h"
      31             : #include "llvm/CodeGen/MachineInstrBuilder.h"
      32             : #include "llvm/CodeGen/MachineRegisterInfo.h"
      33             : using namespace llvm;
      34             : 
      35             : #define TLSCLEANUP_PASS_NAME "AArch64 Local Dynamic TLS Access Clean-up"
      36             : 
      37             : namespace {
      38             : struct LDTLSCleanup : public MachineFunctionPass {
      39             :   static char ID;
      40         823 :   LDTLSCleanup() : MachineFunctionPass(ID) {
      41         823 :     initializeLDTLSCleanupPass(*PassRegistry::getPassRegistry());
      42         823 :   }
      43             : 
      44       11794 :   bool runOnMachineFunction(MachineFunction &MF) override {
      45       11794 :     if (skipFunction(MF.getFunction()))
      46             :       return false;
      47             : 
      48       11789 :     AArch64FunctionInfo *AFI = MF.getInfo<AArch64FunctionInfo>();
      49       11789 :     if (AFI->getNumLocalDynamicTLSAccesses() < 2) {
      50             :       // No point folding accesses if there isn't at least two.
      51             :       return false;
      52             :     }
      53             : 
      54           3 :     MachineDominatorTree *DT = &getAnalysis<MachineDominatorTree>();
      55           3 :     return VisitNode(DT->getRootNode(), 0);
      56             :   }
      57             : 
      58             :   // Visit the dominator subtree rooted at Node in pre-order.
      59             :   // If TLSBaseAddrReg is non-null, then use that to replace any
      60             :   // TLS_base_addr instructions. Otherwise, create the register
      61             :   // when the first such instruction is seen, and then use it
      62             :   // as we encounter more instructions.
      63           3 :   bool VisitNode(MachineDomTreeNode *Node, unsigned TLSBaseAddrReg) {
      64           3 :     MachineBasicBlock *BB = Node->getBlock();
      65             :     bool Changed = false;
      66             : 
      67             :     // Traverse the current block.
      68          45 :     for (MachineBasicBlock::iterator I = BB->begin(), E = BB->end(); I != E;
      69             :          ++I) {
      70          84 :       switch (I->getOpcode()) {
      71             :       case AArch64::TLSDESC_CALLSEQ:
      72             :         // Make sure it's a local dynamic access.
      73          12 :         if (!I->getOperand(0).isSymbol() ||
      74           6 :             strcmp(I->getOperand(0).getSymbolName(), "_TLS_MODULE_BASE_"))
      75             :           break;
      76             : 
      77           6 :         if (TLSBaseAddrReg)
      78           3 :           I = replaceTLSBaseAddrCall(*I, TLSBaseAddrReg);
      79             :         else
      80           3 :           I = setRegister(*I, &TLSBaseAddrReg);
      81             :         Changed = true;
      82             :         break;
      83             :       default:
      84             :         break;
      85             :       }
      86             :     }
      87             : 
      88             :     // Visit the children of this block in the dominator tree.
      89           3 :     for (MachineDomTreeNode *N : *Node) {
      90           0 :       Changed |= VisitNode(N, TLSBaseAddrReg);
      91             :     }
      92             : 
      93           3 :     return Changed;
      94             :   }
      95             : 
      96             :   // Replace the TLS_base_addr instruction I with a copy from
      97             :   // TLSBaseAddrReg, returning the new instruction.
      98           0 :   MachineInstr *replaceTLSBaseAddrCall(MachineInstr &I,
      99             :                                        unsigned TLSBaseAddrReg) {
     100           0 :     MachineFunction *MF = I.getParent()->getParent();
     101           0 :     const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo();
     102             : 
     103             :     // Insert a Copy from TLSBaseAddrReg to x0, which is where the rest of the
     104             :     // code sequence assumes the address will be.
     105           0 :     MachineInstr *Copy = BuildMI(*I.getParent(), I, I.getDebugLoc(),
     106           0 :                                  TII->get(TargetOpcode::COPY), AArch64::X0)
     107           0 :                              .addReg(TLSBaseAddrReg);
     108             : 
     109             :     // Erase the TLS_base_addr instruction.
     110           0 :     I.eraseFromParent();
     111             : 
     112           0 :     return Copy;
     113             :   }
     114             : 
     115             :   // Create a virtual register in *TLSBaseAddrReg, and populate it by
     116             :   // inserting a copy instruction after I. Returns the new instruction.
     117           0 :   MachineInstr *setRegister(MachineInstr &I, unsigned *TLSBaseAddrReg) {
     118           0 :     MachineFunction *MF = I.getParent()->getParent();
     119           0 :     const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo();
     120             : 
     121             :     // Create a virtual register for the TLS base address.
     122           0 :     MachineRegisterInfo &RegInfo = MF->getRegInfo();
     123           0 :     *TLSBaseAddrReg = RegInfo.createVirtualRegister(&AArch64::GPR64RegClass);
     124             : 
     125             :     // Insert a copy from X0 to TLSBaseAddrReg for later.
     126             :     MachineInstr *Copy =
     127           0 :         BuildMI(*I.getParent(), ++I.getIterator(), I.getDebugLoc(),
     128           0 :                 TII->get(TargetOpcode::COPY), *TLSBaseAddrReg)
     129           0 :             .addReg(AArch64::X0);
     130             : 
     131           0 :     return Copy;
     132             :   }
     133             : 
     134          14 :   StringRef getPassName() const override { return TLSCLEANUP_PASS_NAME; }
     135             : 
     136         820 :   void getAnalysisUsage(AnalysisUsage &AU) const override {
     137         820 :     AU.setPreservesCFG();
     138             :     AU.addRequired<MachineDominatorTree>();
     139         820 :     MachineFunctionPass::getAnalysisUsage(AU);
     140         820 :   }
     141             : };
     142             : }
     143             : 
     144      199855 : INITIALIZE_PASS(LDTLSCleanup, "aarch64-local-dynamic-tls-cleanup",
     145             :                 TLSCLEANUP_PASS_NAME, false, false)
     146             : 
     147             : char LDTLSCleanup::ID = 0;
     148         823 : FunctionPass *llvm::createAArch64CleanupLocalDynamicTLSPass() {
     149         823 :   return new LDTLSCleanup();
     150             : }

Generated by: LCOV version 1.13