Home | History | Annotate | Download | only in SystemZ
      1 //===-- SystemZLDCleanup.cpp - Clean up local-dynamic TLS accesses --------===//
      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 pass combines multiple accesses to local-dynamic TLS variables so that
     11 // the TLS base address for the module is only fetched once per execution path
     12 // through the function.
     13 //
     14 //===----------------------------------------------------------------------===//
     15 
     16 #include "SystemZTargetMachine.h"
     17 #include "SystemZMachineFunctionInfo.h"
     18 #include "llvm/CodeGen/MachineDominators.h"
     19 #include "llvm/CodeGen/MachineFunctionPass.h"
     20 #include "llvm/CodeGen/MachineInstrBuilder.h"
     21 #include "llvm/CodeGen/MachineRegisterInfo.h"
     22 #include "llvm/Target/TargetInstrInfo.h"
     23 #include "llvm/Target/TargetMachine.h"
     24 #include "llvm/Target/TargetRegisterInfo.h"
     25 
     26 using namespace llvm;
     27 
     28 namespace {
     29 
     30 class SystemZLDCleanup : public MachineFunctionPass {
     31 public:
     32   static char ID;
     33   SystemZLDCleanup(const SystemZTargetMachine &tm)
     34     : MachineFunctionPass(ID), TII(nullptr), MF(nullptr) {}
     35 
     36   const char *getPassName() const override {
     37     return "SystemZ Local Dynamic TLS Access Clean-up";
     38   }
     39 
     40   bool runOnMachineFunction(MachineFunction &MF) override;
     41   void getAnalysisUsage(AnalysisUsage &AU) const override;
     42 
     43 private:
     44   bool VisitNode(MachineDomTreeNode *Node, unsigned TLSBaseAddrReg);
     45   MachineInstr *ReplaceTLSCall(MachineInstr *I, unsigned TLSBaseAddrReg);
     46   MachineInstr *SetRegister(MachineInstr *I, unsigned *TLSBaseAddrReg);
     47 
     48   const SystemZInstrInfo *TII;
     49   MachineFunction *MF;
     50 };
     51 
     52 char SystemZLDCleanup::ID = 0;
     53 
     54 } // end anonymous namespace
     55 
     56 FunctionPass *llvm::createSystemZLDCleanupPass(SystemZTargetMachine &TM) {
     57   return new SystemZLDCleanup(TM);
     58 }
     59 
     60 void SystemZLDCleanup::getAnalysisUsage(AnalysisUsage &AU) const {
     61   AU.setPreservesCFG();
     62   AU.addRequired<MachineDominatorTree>();
     63   MachineFunctionPass::getAnalysisUsage(AU);
     64 }
     65 
     66 bool SystemZLDCleanup::runOnMachineFunction(MachineFunction &F) {
     67   TII = static_cast<const SystemZInstrInfo *>(F.getSubtarget().getInstrInfo());
     68   MF = &F;
     69 
     70   SystemZMachineFunctionInfo* MFI = F.getInfo<SystemZMachineFunctionInfo>();
     71   if (MFI->getNumLocalDynamicTLSAccesses() < 2) {
     72     // No point folding accesses if there isn't at least two.
     73     return false;
     74   }
     75 
     76   MachineDominatorTree *DT = &getAnalysis<MachineDominatorTree>();
     77   return VisitNode(DT->getRootNode(), 0);
     78 }
     79 
     80 // Visit the dominator subtree rooted at Node in pre-order.
     81 // If TLSBaseAddrReg is non-null, then use that to replace any
     82 // TLS_LDCALL instructions. Otherwise, create the register
     83 // when the first such instruction is seen, and then use it
     84 // as we encounter more instructions.
     85 bool SystemZLDCleanup::VisitNode(MachineDomTreeNode *Node,
     86                                  unsigned TLSBaseAddrReg) {
     87   MachineBasicBlock *BB = Node->getBlock();
     88   bool Changed = false;
     89 
     90   // Traverse the current block.
     91   for (auto I = BB->begin(), E = BB->end(); I != E; ++I) {
     92     switch (I->getOpcode()) {
     93       case SystemZ::TLS_LDCALL:
     94         if (TLSBaseAddrReg)
     95           I = ReplaceTLSCall(I, TLSBaseAddrReg);
     96         else
     97           I = SetRegister(I, &TLSBaseAddrReg);
     98         Changed = true;
     99         break;
    100       default:
    101         break;
    102     }
    103   }
    104 
    105   // Visit the children of this block in the dominator tree.
    106   for (auto I = Node->begin(), E = Node->end(); I != E; ++I)
    107     Changed |= VisitNode(*I, TLSBaseAddrReg);
    108 
    109   return Changed;
    110 }
    111 
    112 // Replace the TLS_LDCALL instruction I with a copy from TLSBaseAddrReg,
    113 // returning the new instruction.
    114 MachineInstr *SystemZLDCleanup::ReplaceTLSCall(MachineInstr *I,
    115                                                unsigned TLSBaseAddrReg) {
    116   // Insert a Copy from TLSBaseAddrReg to R2.
    117   MachineInstr *Copy = BuildMI(*I->getParent(), I, I->getDebugLoc(),
    118                                TII->get(TargetOpcode::COPY), SystemZ::R2D)
    119                                .addReg(TLSBaseAddrReg);
    120 
    121   // Erase the TLS_LDCALL instruction.
    122   I->eraseFromParent();
    123 
    124   return Copy;
    125 }
    126 
    127 // Create a virtal register in *TLSBaseAddrReg, and populate it by
    128 // inserting a copy instruction after I. Returns the new instruction.
    129 MachineInstr *SystemZLDCleanup::SetRegister(MachineInstr *I,
    130                                             unsigned *TLSBaseAddrReg) {
    131   // Create a virtual register for the TLS base address.
    132   MachineRegisterInfo &RegInfo = MF->getRegInfo();
    133   *TLSBaseAddrReg = RegInfo.createVirtualRegister(&SystemZ::GR64BitRegClass);
    134 
    135   // Insert a copy from R2 to TLSBaseAddrReg.
    136   MachineInstr *Next = I->getNextNode();
    137   MachineInstr *Copy = BuildMI(*I->getParent(), Next, I->getDebugLoc(),
    138                                TII->get(TargetOpcode::COPY), *TLSBaseAddrReg)
    139                                .addReg(SystemZ::R2D);
    140 
    141   return Copy;
    142 }
    143 
    144