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) {
67de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (skipFunction(*F.getFunction()))
68de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return false;
69de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
70ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  TII = static_cast<const SystemZInstrInfo *>(F.getSubtarget().getInstrInfo());
71ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  MF = &F;
72ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
73ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  SystemZMachineFunctionInfo* MFI = F.getInfo<SystemZMachineFunctionInfo>();
74ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (MFI->getNumLocalDynamicTLSAccesses() < 2) {
75ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // No point folding accesses if there isn't at least two.
76ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return false;
77ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
78ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
79ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  MachineDominatorTree *DT = &getAnalysis<MachineDominatorTree>();
80ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  return VisitNode(DT->getRootNode(), 0);
81ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
82ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
83ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// Visit the dominator subtree rooted at Node in pre-order.
84ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// If TLSBaseAddrReg is non-null, then use that to replace any
85ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// TLS_LDCALL instructions. Otherwise, create the register
86ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// when the first such instruction is seen, and then use it
87ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// as we encounter more instructions.
88ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesbool SystemZLDCleanup::VisitNode(MachineDomTreeNode *Node,
89ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                 unsigned TLSBaseAddrReg) {
90ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  MachineBasicBlock *BB = Node->getBlock();
91ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  bool Changed = false;
92ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
93ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // Traverse the current block.
94ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  for (auto I = BB->begin(), E = BB->end(); I != E; ++I) {
95ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    switch (I->getOpcode()) {
96ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      case SystemZ::TLS_LDCALL:
97ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        if (TLSBaseAddrReg)
98de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          I = ReplaceTLSCall(&*I, TLSBaseAddrReg);
99ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        else
100de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          I = SetRegister(&*I, &TLSBaseAddrReg);
101ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        Changed = true;
102ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        break;
103ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      default:
104ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        break;
105ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }
106ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
107ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
108ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // Visit the children of this block in the dominator tree.
109ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  for (auto I = Node->begin(), E = Node->end(); I != E; ++I)
110ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    Changed |= VisitNode(*I, TLSBaseAddrReg);
111ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
112ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  return Changed;
113ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
114ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
115ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// Replace the TLS_LDCALL instruction I with a copy from TLSBaseAddrReg,
116ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// returning the new instruction.
117ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesMachineInstr *SystemZLDCleanup::ReplaceTLSCall(MachineInstr *I,
118ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                               unsigned TLSBaseAddrReg) {
119ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // Insert a Copy from TLSBaseAddrReg to R2.
120ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  MachineInstr *Copy = BuildMI(*I->getParent(), I, I->getDebugLoc(),
121ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                               TII->get(TargetOpcode::COPY), SystemZ::R2D)
122ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                               .addReg(TLSBaseAddrReg);
123ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
124ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // Erase the TLS_LDCALL instruction.
125ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  I->eraseFromParent();
126ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
127ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  return Copy;
128ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
129ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
130ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// Create a virtal register in *TLSBaseAddrReg, and populate it by
131ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// inserting a copy instruction after I. Returns the new instruction.
132ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesMachineInstr *SystemZLDCleanup::SetRegister(MachineInstr *I,
133ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                            unsigned *TLSBaseAddrReg) {
134ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // Create a virtual register for the TLS base address.
135ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  MachineRegisterInfo &RegInfo = MF->getRegInfo();
136ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  *TLSBaseAddrReg = RegInfo.createVirtualRegister(&SystemZ::GR64BitRegClass);
137ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
138ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // Insert a copy from R2 to TLSBaseAddrReg.
139ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  MachineInstr *Next = I->getNextNode();
140ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  MachineInstr *Copy = BuildMI(*I->getParent(), Next, I->getDebugLoc(),
141ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                               TII->get(TargetOpcode::COPY), *TLSBaseAddrReg)
142ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                               .addReg(SystemZ::R2D);
143ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
144ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  return Copy;
145ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
146ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
147