SystemZLDCleanup.cpp revision 287506
120253Sjoerg//===-- SystemZLDCleanup.cpp - Clean up local-dynamic TLS accesses --------===// 220302Sjoerg// 320302Sjoerg// The LLVM Compiler Infrastructure 420253Sjoerg// 520253Sjoerg// This file is distributed under the University of Illinois Open Source 620253Sjoerg// License. See LICENSE.TXT for details. 720253Sjoerg// 820253Sjoerg//===----------------------------------------------------------------------===// 920302Sjoerg// 1020253Sjoerg// This pass combines multiple accesses to local-dynamic TLS variables so that 1120253Sjoerg// the TLS base address for the module is only fetched once per execution path 1220253Sjoerg// through the function. 1320253Sjoerg// 1420302Sjoerg//===----------------------------------------------------------------------===// 1520253Sjoerg 1620253Sjoerg#include "SystemZTargetMachine.h" 1720302Sjoerg#include "SystemZMachineFunctionInfo.h" 1820253Sjoerg#include "llvm/CodeGen/MachineDominators.h" 1920253Sjoerg#include "llvm/CodeGen/MachineFunctionPass.h" 2020253Sjoerg#include "llvm/CodeGen/MachineInstrBuilder.h" 2120253Sjoerg#include "llvm/CodeGen/MachineRegisterInfo.h" 2220253Sjoerg#include "llvm/Target/TargetInstrInfo.h" 2320253Sjoerg#include "llvm/Target/TargetMachine.h" 2420253Sjoerg#include "llvm/Target/TargetRegisterInfo.h" 2520253Sjoerg 2620302Sjoergusing namespace llvm; 2720253Sjoerg 2820253Sjoergnamespace { 2920253Sjoerg 3020253Sjoergclass SystemZLDCleanup : public MachineFunctionPass { 3120253Sjoergpublic: 3220253Sjoerg static char ID; 3320253Sjoerg SystemZLDCleanup(const SystemZTargetMachine &tm) 3420253Sjoerg : MachineFunctionPass(ID), TII(nullptr), MF(nullptr) {} 3520253Sjoerg 3620253Sjoerg const char *getPassName() const override { 3720253Sjoerg return "SystemZ Local Dynamic TLS Access Clean-up"; 3820253Sjoerg } 3920253Sjoerg 4020253Sjoerg bool runOnMachineFunction(MachineFunction &MF) override; 4120253Sjoerg void getAnalysisUsage(AnalysisUsage &AU) const override; 4220253Sjoerg 4320253Sjoergprivate: 4420253Sjoerg bool VisitNode(MachineDomTreeNode *Node, unsigned TLSBaseAddrReg); 4520253Sjoerg MachineInstr *ReplaceTLSCall(MachineInstr *I, unsigned TLSBaseAddrReg); 4620253Sjoerg MachineInstr *SetRegister(MachineInstr *I, unsigned *TLSBaseAddrReg); 4720253Sjoerg 4820253Sjoerg const SystemZInstrInfo *TII; 4920253Sjoerg MachineFunction *MF; 5020253Sjoerg}; 5120253Sjoerg 5220253Sjoergchar SystemZLDCleanup::ID = 0; 5320253Sjoerg 5420253Sjoerg} // end anonymous namespace 5520253Sjoerg 5620253SjoergFunctionPass *llvm::createSystemZLDCleanupPass(SystemZTargetMachine &TM) { 5720253Sjoerg return new SystemZLDCleanup(TM); 5820253Sjoerg} 5920253Sjoerg 6020253Sjoergvoid SystemZLDCleanup::getAnalysisUsage(AnalysisUsage &AU) const { 6120253Sjoerg AU.setPreservesCFG(); 6220253Sjoerg AU.addRequired<MachineDominatorTree>(); 6320253Sjoerg MachineFunctionPass::getAnalysisUsage(AU); 6420253Sjoerg} 6520253Sjoerg 6620253Sjoergbool SystemZLDCleanup::runOnMachineFunction(MachineFunction &F) { 6720253Sjoerg TII = static_cast<const SystemZInstrInfo *>(F.getSubtarget().getInstrInfo()); 6820253Sjoerg MF = &F; 6920253Sjoerg 7020253Sjoerg SystemZMachineFunctionInfo* MFI = F.getInfo<SystemZMachineFunctionInfo>(); 7120253Sjoerg if (MFI->getNumLocalDynamicTLSAccesses() < 2) { 7220253Sjoerg // No point folding accesses if there isn't at least two. 7320253Sjoerg return false; 7420253Sjoerg } 7520253Sjoerg 7620253Sjoerg MachineDominatorTree *DT = &getAnalysis<MachineDominatorTree>(); 7720253Sjoerg return VisitNode(DT->getRootNode(), 0); 7820253Sjoerg} 7920253Sjoerg 8020253Sjoerg// Visit the dominator subtree rooted at Node in pre-order. 8120253Sjoerg// If TLSBaseAddrReg is non-null, then use that to replace any 8220253Sjoerg// TLS_LDCALL instructions. Otherwise, create the register 8320253Sjoerg// when the first such instruction is seen, and then use it 8420253Sjoerg// as we encounter more instructions. 8520253Sjoergbool SystemZLDCleanup::VisitNode(MachineDomTreeNode *Node, 8620253Sjoerg unsigned TLSBaseAddrReg) { 8720253Sjoerg MachineBasicBlock *BB = Node->getBlock(); 8820253Sjoerg bool Changed = false; 8920253Sjoerg 9020253Sjoerg // Traverse the current block. 9120253Sjoerg for (auto I = BB->begin(), E = BB->end(); I != E; ++I) { 9220253Sjoerg switch (I->getOpcode()) { 9320253Sjoerg case SystemZ::TLS_LDCALL: 9420253Sjoerg if (TLSBaseAddrReg) 9520253Sjoerg I = ReplaceTLSCall(I, TLSBaseAddrReg); 9620253Sjoerg else 9720253Sjoerg I = SetRegister(I, &TLSBaseAddrReg); 9820253Sjoerg Changed = true; 9920253Sjoerg break; 10020253Sjoerg default: 10120253Sjoerg break; 10220253Sjoerg } 10320253Sjoerg } 10420253Sjoerg 10520253Sjoerg // 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. 114MachineInstr *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. 129MachineInstr *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