17db6918eSUlrich Weigand //===-- SystemZLDCleanup.cpp - Clean up local-dynamic TLS accesses --------===//
27db6918eSUlrich Weigand //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
67db6918eSUlrich Weigand //
77db6918eSUlrich Weigand //===----------------------------------------------------------------------===//
87db6918eSUlrich Weigand //
97db6918eSUlrich Weigand // This pass combines multiple accesses to local-dynamic TLS variables so that
107db6918eSUlrich Weigand // the TLS base address for the module is only fetched once per execution path
117db6918eSUlrich Weigand // through the function.
127db6918eSUlrich Weigand //
137db6918eSUlrich Weigand //===----------------------------------------------------------------------===//
147db6918eSUlrich Weigand
157db6918eSUlrich Weigand #include "SystemZMachineFunctionInfo.h"
166bda14b3SChandler Carruth #include "SystemZTargetMachine.h"
177db6918eSUlrich Weigand #include "llvm/CodeGen/MachineDominators.h"
187db6918eSUlrich Weigand #include "llvm/CodeGen/MachineFunctionPass.h"
197db6918eSUlrich Weigand #include "llvm/CodeGen/MachineInstrBuilder.h"
207db6918eSUlrich Weigand #include "llvm/CodeGen/MachineRegisterInfo.h"
213f833edcSDavid Blaikie #include "llvm/CodeGen/TargetInstrInfo.h"
22b3bde2eaSDavid Blaikie #include "llvm/CodeGen/TargetRegisterInfo.h"
237db6918eSUlrich Weigand #include "llvm/Target/TargetMachine.h"
247db6918eSUlrich Weigand
257db6918eSUlrich Weigand using namespace llvm;
267db6918eSUlrich Weigand
277db6918eSUlrich Weigand namespace {
287db6918eSUlrich Weigand
297db6918eSUlrich Weigand class SystemZLDCleanup : public MachineFunctionPass {
307db6918eSUlrich Weigand public:
317db6918eSUlrich Weigand static char ID;
SystemZLDCleanup()32d5ae039eSKai Nacke SystemZLDCleanup() : MachineFunctionPass(ID), TII(nullptr), MF(nullptr) {
33d5ae039eSKai Nacke initializeSystemZLDCleanupPass(*PassRegistry::getPassRegistry());
347db6918eSUlrich Weigand }
357db6918eSUlrich Weigand
367db6918eSUlrich Weigand bool runOnMachineFunction(MachineFunction &MF) override;
377db6918eSUlrich Weigand void getAnalysisUsage(AnalysisUsage &AU) const override;
387db6918eSUlrich Weigand
397db6918eSUlrich Weigand private:
407db6918eSUlrich Weigand bool VisitNode(MachineDomTreeNode *Node, unsigned TLSBaseAddrReg);
417db6918eSUlrich Weigand MachineInstr *ReplaceTLSCall(MachineInstr *I, unsigned TLSBaseAddrReg);
427db6918eSUlrich Weigand MachineInstr *SetRegister(MachineInstr *I, unsigned *TLSBaseAddrReg);
437db6918eSUlrich Weigand
447db6918eSUlrich Weigand const SystemZInstrInfo *TII;
457db6918eSUlrich Weigand MachineFunction *MF;
467db6918eSUlrich Weigand };
477db6918eSUlrich Weigand
487db6918eSUlrich Weigand char SystemZLDCleanup::ID = 0;
497db6918eSUlrich Weigand
507db6918eSUlrich Weigand } // end anonymous namespace
517db6918eSUlrich Weigand
52d5ae039eSKai Nacke INITIALIZE_PASS(SystemZLDCleanup, "systemz-ld-cleanup",
53d5ae039eSKai Nacke "SystemZ Local Dynamic TLS Access Clean-up", false, false)
54d5ae039eSKai Nacke
createSystemZLDCleanupPass(SystemZTargetMachine & TM)557db6918eSUlrich Weigand FunctionPass *llvm::createSystemZLDCleanupPass(SystemZTargetMachine &TM) {
56d5ae039eSKai Nacke return new SystemZLDCleanup();
577db6918eSUlrich Weigand }
587db6918eSUlrich Weigand
getAnalysisUsage(AnalysisUsage & AU) const597db6918eSUlrich Weigand void SystemZLDCleanup::getAnalysisUsage(AnalysisUsage &AU) const {
607db6918eSUlrich Weigand AU.setPreservesCFG();
617db6918eSUlrich Weigand AU.addRequired<MachineDominatorTree>();
627db6918eSUlrich Weigand MachineFunctionPass::getAnalysisUsage(AU);
637db6918eSUlrich Weigand }
647db6918eSUlrich Weigand
runOnMachineFunction(MachineFunction & F)657db6918eSUlrich Weigand bool SystemZLDCleanup::runOnMachineFunction(MachineFunction &F) {
66f1caa283SMatthias Braun if (skipFunction(F.getFunction()))
67d9974cc9SAndrew Kaylor return false;
68d9974cc9SAndrew Kaylor
69*3432d40cSJonas Paulsson TII = F.getSubtarget<SystemZSubtarget>().getInstrInfo();
707db6918eSUlrich Weigand MF = &F;
717db6918eSUlrich Weigand
727db6918eSUlrich Weigand SystemZMachineFunctionInfo* MFI = F.getInfo<SystemZMachineFunctionInfo>();
737db6918eSUlrich Weigand if (MFI->getNumLocalDynamicTLSAccesses() < 2) {
747db6918eSUlrich Weigand // No point folding accesses if there isn't at least two.
757db6918eSUlrich Weigand return false;
767db6918eSUlrich Weigand }
777db6918eSUlrich Weigand
787db6918eSUlrich Weigand MachineDominatorTree *DT = &getAnalysis<MachineDominatorTree>();
797db6918eSUlrich Weigand return VisitNode(DT->getRootNode(), 0);
807db6918eSUlrich Weigand }
817db6918eSUlrich Weigand
827db6918eSUlrich Weigand // Visit the dominator subtree rooted at Node in pre-order.
837db6918eSUlrich Weigand // If TLSBaseAddrReg is non-null, then use that to replace any
847db6918eSUlrich Weigand // TLS_LDCALL instructions. Otherwise, create the register
857db6918eSUlrich Weigand // when the first such instruction is seen, and then use it
867db6918eSUlrich Weigand // as we encounter more instructions.
VisitNode(MachineDomTreeNode * Node,unsigned TLSBaseAddrReg)877db6918eSUlrich Weigand bool SystemZLDCleanup::VisitNode(MachineDomTreeNode *Node,
887db6918eSUlrich Weigand unsigned TLSBaseAddrReg) {
897db6918eSUlrich Weigand MachineBasicBlock *BB = Node->getBlock();
907db6918eSUlrich Weigand bool Changed = false;
917db6918eSUlrich Weigand
927db6918eSUlrich Weigand // Traverse the current block.
937db6918eSUlrich Weigand for (auto I = BB->begin(), E = BB->end(); I != E; ++I) {
947db6918eSUlrich Weigand switch (I->getOpcode()) {
957db6918eSUlrich Weigand case SystemZ::TLS_LDCALL:
967db6918eSUlrich Weigand if (TLSBaseAddrReg)
974565ec0cSDuncan P. N. Exon Smith I = ReplaceTLSCall(&*I, TLSBaseAddrReg);
987db6918eSUlrich Weigand else
994565ec0cSDuncan P. N. Exon Smith I = SetRegister(&*I, &TLSBaseAddrReg);
1007db6918eSUlrich Weigand Changed = true;
1017db6918eSUlrich Weigand break;
1027db6918eSUlrich Weigand default:
1037db6918eSUlrich Weigand break;
1047db6918eSUlrich Weigand }
1057db6918eSUlrich Weigand }
1067db6918eSUlrich Weigand
1077db6918eSUlrich Weigand // Visit the children of this block in the dominator tree.
1087db6918eSUlrich Weigand for (auto I = Node->begin(), E = Node->end(); I != E; ++I)
1097db6918eSUlrich Weigand Changed |= VisitNode(*I, TLSBaseAddrReg);
1107db6918eSUlrich Weigand
1117db6918eSUlrich Weigand return Changed;
1127db6918eSUlrich Weigand }
1137db6918eSUlrich Weigand
1147db6918eSUlrich Weigand // Replace the TLS_LDCALL instruction I with a copy from TLSBaseAddrReg,
1157db6918eSUlrich Weigand // returning the new instruction.
ReplaceTLSCall(MachineInstr * I,unsigned TLSBaseAddrReg)1167db6918eSUlrich Weigand MachineInstr *SystemZLDCleanup::ReplaceTLSCall(MachineInstr *I,
1177db6918eSUlrich Weigand unsigned TLSBaseAddrReg) {
1187db6918eSUlrich Weigand // Insert a Copy from TLSBaseAddrReg to R2.
1197db6918eSUlrich Weigand MachineInstr *Copy = BuildMI(*I->getParent(), I, I->getDebugLoc(),
1207db6918eSUlrich Weigand TII->get(TargetOpcode::COPY), SystemZ::R2D)
1217db6918eSUlrich Weigand .addReg(TLSBaseAddrReg);
1227db6918eSUlrich Weigand
1237db6918eSUlrich Weigand // Erase the TLS_LDCALL instruction.
1247db6918eSUlrich Weigand I->eraseFromParent();
1257db6918eSUlrich Weigand
1267db6918eSUlrich Weigand return Copy;
1277db6918eSUlrich Weigand }
1287db6918eSUlrich Weigand
129ddb34d84SHiroshi Inoue // Create a virtual register in *TLSBaseAddrReg, and populate it by
1307db6918eSUlrich Weigand // inserting a copy instruction after I. Returns the new instruction.
SetRegister(MachineInstr * I,unsigned * TLSBaseAddrReg)1317db6918eSUlrich Weigand MachineInstr *SystemZLDCleanup::SetRegister(MachineInstr *I,
1327db6918eSUlrich Weigand unsigned *TLSBaseAddrReg) {
1337db6918eSUlrich Weigand // Create a virtual register for the TLS base address.
1347db6918eSUlrich Weigand MachineRegisterInfo &RegInfo = MF->getRegInfo();
1357db6918eSUlrich Weigand *TLSBaseAddrReg = RegInfo.createVirtualRegister(&SystemZ::GR64BitRegClass);
1367db6918eSUlrich Weigand
1377db6918eSUlrich Weigand // Insert a copy from R2 to TLSBaseAddrReg.
1387db6918eSUlrich Weigand MachineInstr *Next = I->getNextNode();
1397db6918eSUlrich Weigand MachineInstr *Copy = BuildMI(*I->getParent(), Next, I->getDebugLoc(),
1407db6918eSUlrich Weigand TII->get(TargetOpcode::COPY), *TLSBaseAddrReg)
1417db6918eSUlrich Weigand .addReg(SystemZ::R2D);
1427db6918eSUlrich Weigand
1437db6918eSUlrich Weigand return Copy;
1447db6918eSUlrich Weigand }
1457db6918eSUlrich Weigand
146