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