144 lines · cpp
1//===-- SystemZLDCleanup.cpp - Clean up local-dynamic TLS accesses --------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This pass combines multiple accesses to local-dynamic TLS variables so that10// the TLS base address for the module is only fetched once per execution path11// through the function.12//13//===----------------------------------------------------------------------===//14 15#include "SystemZMachineFunctionInfo.h"16#include "SystemZTargetMachine.h"17#include "llvm/CodeGen/MachineDominators.h"18#include "llvm/CodeGen/MachineFunctionPass.h"19#include "llvm/CodeGen/MachineInstrBuilder.h"20#include "llvm/CodeGen/MachineRegisterInfo.h"21#include "llvm/CodeGen/TargetInstrInfo.h"22#include "llvm/CodeGen/TargetRegisterInfo.h"23 24using namespace llvm;25 26namespace {27 28class SystemZLDCleanup : public MachineFunctionPass {29public:30 static char ID;31 SystemZLDCleanup() : MachineFunctionPass(ID), TII(nullptr), MF(nullptr) {}32 33 bool runOnMachineFunction(MachineFunction &MF) override;34 void getAnalysisUsage(AnalysisUsage &AU) const override;35 36private:37 bool VisitNode(MachineDomTreeNode *Node, unsigned TLSBaseAddrReg);38 MachineInstr *ReplaceTLSCall(MachineInstr *I, unsigned TLSBaseAddrReg);39 MachineInstr *SetRegister(MachineInstr *I, unsigned *TLSBaseAddrReg);40 41 const SystemZInstrInfo *TII;42 MachineFunction *MF;43};44 45char SystemZLDCleanup::ID = 0;46 47} // end anonymous namespace48 49INITIALIZE_PASS(SystemZLDCleanup, "systemz-ld-cleanup",50 "SystemZ Local Dynamic TLS Access Clean-up", false, false)51 52FunctionPass *llvm::createSystemZLDCleanupPass(SystemZTargetMachine &TM) {53 return new SystemZLDCleanup();54}55 56void SystemZLDCleanup::getAnalysisUsage(AnalysisUsage &AU) const {57 AU.setPreservesCFG();58 AU.addRequired<MachineDominatorTreeWrapperPass>();59 MachineFunctionPass::getAnalysisUsage(AU);60}61 62bool SystemZLDCleanup::runOnMachineFunction(MachineFunction &F) {63 if (skipFunction(F.getFunction()))64 return false;65 66 TII = F.getSubtarget<SystemZSubtarget>().getInstrInfo();67 MF = &F;68 69 SystemZMachineFunctionInfo* MFI = F.getInfo<SystemZMachineFunctionInfo>();70 if (MFI->getNumLocalDynamicTLSAccesses() < 2) {71 // No point folding accesses if there isn't at least two.72 return false;73 }74 75 MachineDominatorTree *DT =76 &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();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 any82// TLS_LDCALL instructions. Otherwise, create the register83// when the first such instruction is seen, and then use it84// as we encounter more instructions.85bool 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 else97 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 &N : *Node)107 Changed |= VisitNode(N, 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 virtual register in *TLSBaseAddrReg, and populate it by128// 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