brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.8 KiB · a81cfeb Raw
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