//===---------- PPCTLSDynamicCall.cpp - TLS Dynamic Call Fixup ------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This pass expands ADDItls{ld,gd}LADDR[32] machine instructions into
// separate ADDItls[gd]L[32] and GETtlsADDR[32] instructions, both of
// which define GPR3.  A copy is added from GPR3 to the target virtual
// register of the original instruction.  The GETtlsADDR[32] is really
// a call instruction, so its target register is constrained to be GPR3.
// This is not true of ADDItls[gd]L[32], but there is a legacy linker
// optimization bug that requires the target register of the addi of
// a local- or general-dynamic TLS access sequence to be GPR3.
//
// This is done in a late pass so that TLS variable accesses can be
// fully commoned by MachineCSE.
//
//===----------------------------------------------------------------------===//

#include "PPC.h"
#include "PPCInstrInfo.h"
#include "PPCTargetMachine.h"
#include "llvm/CodeGen/LiveIntervals.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"

using namespace llvm;

#define DEBUG_TYPE "ppc-tls-dynamic-call"

namespace {
  struct PPCTLSDynamicCall : public MachineFunctionPass {
    static char ID;
    PPCTLSDynamicCall() : MachineFunctionPass(ID) {}

    const PPCInstrInfo *TII;

protected:
    bool processBlock(MachineBasicBlock &MBB) {
      bool Changed = false;
      bool NeedFence = true;
      const PPCSubtarget &Subtarget =
          MBB.getParent()->getSubtarget<PPCSubtarget>();
      bool Is64Bit = Subtarget.isPPC64();
      bool IsAIX = Subtarget.isAIXABI();
      bool IsLargeModel =
          Subtarget.getTargetMachine().getCodeModel() == CodeModel::Large;
      bool IsPCREL = false;
      MachineFunction *MF = MBB.getParent();
      MachineRegisterInfo &RegInfo = MF->getRegInfo();

      for (MachineBasicBlock::iterator I = MBB.begin(), IE = MBB.end();
           I != IE;) {
        MachineInstr &MI = *I;
        IsPCREL = isPCREL(MI);
        // There are a number of slight differences in code generation
        // when we call .__get_tpointer (32-bit AIX TLS).
        bool IsTLSTPRelMI = MI.getOpcode() == PPC::GETtlsTpointer32AIX;
        bool IsTLSLDAIXMI = (MI.getOpcode() == PPC::TLSLDAIX8 ||
                             MI.getOpcode() == PPC::TLSLDAIX);

        if (MI.getOpcode() != PPC::ADDItlsgdLADDR &&
            MI.getOpcode() != PPC::ADDItlsldLADDR &&
            MI.getOpcode() != PPC::ADDItlsgdLADDR32 &&
            MI.getOpcode() != PPC::ADDItlsldLADDR32 &&
            MI.getOpcode() != PPC::TLSGDAIX &&
            MI.getOpcode() != PPC::TLSGDAIX8 && !IsTLSTPRelMI && !IsPCREL &&
            !IsTLSLDAIXMI) {
          // Although we create ADJCALLSTACKDOWN and ADJCALLSTACKUP
          // as scheduling fences, we skip creating fences if we already
          // have existing ADJCALLSTACKDOWN/UP to avoid nesting,
          // which causes verification error with -verify-machineinstrs.
          if (MI.getOpcode() == PPC::ADJCALLSTACKDOWN)
            NeedFence = false;
          else if (MI.getOpcode() == PPC::ADJCALLSTACKUP)
            NeedFence = true;

          ++I;
          continue;
        }

        LLVM_DEBUG(dbgs() << "TLS Dynamic Call Fixup:\n    " << MI);

        Register OutReg = MI.getOperand(0).getReg();
        Register InReg = PPC::NoRegister;
        Register GPR3 = Is64Bit ? PPC::X3 : PPC::R3;
        Register GPR4 = Is64Bit ? PPC::X4 : PPC::R4;
        if (!IsPCREL && !IsTLSTPRelMI)
          InReg = MI.getOperand(1).getReg();
        DebugLoc DL = MI.getDebugLoc();

        unsigned Opc1, Opc2;
        switch (MI.getOpcode()) {
        default:
          llvm_unreachable("Opcode inconsistency error");
        case PPC::ADDItlsgdLADDR:
          Opc1 = PPC::ADDItlsgdL;
          Opc2 = PPC::GETtlsADDR;
          break;
        case PPC::ADDItlsldLADDR:
          Opc1 = PPC::ADDItlsldL;
          Opc2 = PPC::GETtlsldADDR;
          break;
        case PPC::ADDItlsgdLADDR32:
          Opc1 = PPC::ADDItlsgdL32;
          Opc2 = PPC::GETtlsADDR32;
          break;
        case PPC::ADDItlsldLADDR32:
          Opc1 = PPC::ADDItlsldL32;
          Opc2 = PPC::GETtlsldADDR32;
          break;
        case PPC::TLSLDAIX:
          // TLSLDAIX is expanded to one copy and GET_TLS_MOD, so we only set
          // Opc2 here.
          Opc2 = PPC::GETtlsMOD32AIX;
          break;
        case PPC::TLSLDAIX8:
          // TLSLDAIX8 is expanded to one copy and GET_TLS_MOD, so we only set
          // Opc2 here.
          Opc2 = PPC::GETtlsMOD64AIX;
          break;
        case PPC::TLSGDAIX8:
          // TLSGDAIX8 is expanded to two copies and GET_TLS_ADDR, so we only
          // set Opc2 here.
          Opc2 = PPC::GETtlsADDR64AIX;
          break;
        case PPC::TLSGDAIX:
          // TLSGDAIX is expanded to two copies and GET_TLS_ADDR, so we only
          // set Opc2 here.
          Opc2 = PPC::GETtlsADDR32AIX;
          break;
        case PPC::GETtlsTpointer32AIX:
          // GETtlsTpointer32AIX is expanded to a call to GET_TPOINTER on AIX
          // 32-bit mode within PPCAsmPrinter. This instruction does not need
          // to change, so Opc2 is set to the same instruction opcode.
          Opc2 = PPC::GETtlsTpointer32AIX;
          break;
        case PPC::PADDI8pc:
          assert(IsPCREL && "Expecting General/Local Dynamic PCRel");
          Opc1 = PPC::PADDI8pc;
          Opc2 = MI.getOperand(2).getTargetFlags() ==
                         PPCII::MO_GOT_TLSGD_PCREL_FLAG
                     ? PPC::GETtlsADDRPCREL
                     : PPC::GETtlsldADDRPCREL;
        }

        // We create ADJCALLSTACKUP and ADJCALLSTACKDOWN around _tls_get_addr
        // as scheduling fence to avoid it is scheduled before
        // mflr in the prologue and the address in LR is clobbered (PR25839).
        // We don't really need to save data to the stack - the clobbered
        // registers are already saved when the SDNode (e.g. PPCaddiTlsgdLAddr)
        // gets translated to the pseudo instruction (e.g. ADDItlsgdLADDR).
        if (NeedFence) {
          MBB.getParent()->getFrameInfo().setAdjustsStack(true);
          BuildMI(MBB, I, DL, TII->get(PPC::ADJCALLSTACKDOWN)).addImm(0)
                                                              .addImm(0);
        }

        if (IsAIX) {
          if (IsTLSLDAIXMI) {
            // The relative order between the node that loads the variable
            // offset from the TOC, and the .__tls_get_mod node is being tuned
            // here. It is better to put the variable offset TOC load after the
            // call, since this node can use clobbers r4/r5.
            // Search for the pattern of the two nodes that load from the TOC
            // (either for the variable offset or for the module handle), and
            // then move the variable offset TOC load right before the node that
            // uses the OutReg of the .__tls_get_mod node.
            unsigned LDTocOp =
                Is64Bit ? (IsLargeModel ? PPC::LDtocL : PPC::LDtoc)
                        : (IsLargeModel ? PPC::LWZtocL : PPC::LWZtoc);
            if (!RegInfo.use_empty(OutReg)) {
              std::set<MachineInstr *> Uses;
              // Collect all instructions that use the OutReg.
              for (MachineOperand &MO : RegInfo.use_operands(OutReg))
                Uses.insert(MO.getParent());
              // Find the first user (e.g.: lwax/stfdx) of the OutReg within the
              // current BB.
              MachineBasicBlock::iterator UseIter = MBB.begin();
              for (MachineBasicBlock::iterator IE = MBB.end(); UseIter != IE;
                   ++UseIter)
                if (Uses.count(&*UseIter))
                  break;

              // Additional handling is required when UserIter (the first user
              // of OutReg) is pointing to a valid node that loads from the TOC.
              // Check the pattern and do the movement if the pattern matches.
              if (UseIter != MBB.end()) {
                // Collect all associated nodes that load from the TOC. Use
                // hasOneDef() to guard against unexpected scenarios.
                std::set<MachineInstr *> LoadFromTocs;
                for (MachineOperand &MO : UseIter->operands())
                  if (MO.isReg() && MO.isUse()) {
                    Register MOReg = MO.getReg();
                    if (RegInfo.hasOneDef(MOReg)) {
                      MachineInstr *Temp =
                          RegInfo.getOneDef(MOReg)->getParent();
                      // For the current TLSLDAIX node, get the corresponding
                      // node that loads from the TOC for the InReg. Otherwise,
                      // Temp probably pointed to the variable offset TOC load
                      // we would like to move.
                      if (Temp == &MI && RegInfo.hasOneDef(InReg))
                        Temp = RegInfo.getOneDef(InReg)->getParent();
                      if (Temp->getOpcode() == LDTocOp)
                        LoadFromTocs.insert(Temp);
                    } else {
                      // FIXME: analyze this scenario if there is one.
                      LoadFromTocs.clear();
                      break;
                    }
                  }

                // Check the two nodes that loaded from the TOC: one should be
                // "_$TLSML", and the other will be moved before the node that
                // uses the OutReg of the .__tls_get_mod node.
                if (LoadFromTocs.size() == 2) {
                  MachineBasicBlock::iterator TLSMLIter = MBB.end();
                  MachineBasicBlock::iterator OffsetIter = MBB.end();
                  // Make sure the two nodes that loaded from the TOC are within
                  // the current BB, and that one of them is from the "_$TLSML"
                  // pseudo symbol, while the other is from the variable.
                  for (MachineBasicBlock::iterator I = MBB.begin(),
                                                   IE = MBB.end();
                       I != IE; ++I)
                    if (LoadFromTocs.count(&*I)) {
                      MachineOperand MO = I->getOperand(1);
                      if (MO.isGlobal() && MO.getGlobal()->hasName() &&
                          MO.getGlobal()->getName() == "_$TLSML")
                        TLSMLIter = I;
                      else
                        OffsetIter = I;
                    }
                  // Perform the movement when the desired scenario has been
                  // identified, which should be when both of the iterators are
                  // valid.
                  if (TLSMLIter != MBB.end() && OffsetIter != MBB.end())
                    OffsetIter->moveBefore(&*UseIter);
                }
              }
            }
            // The module-handle is copied into r3. The copy is followed by
            // GETtlsMOD32AIX/GETtlsMOD64AIX.
            BuildMI(MBB, I, DL, TII->get(TargetOpcode::COPY), GPR3)
                .addReg(InReg);
            // The call to .__tls_get_mod.
            BuildMI(MBB, I, DL, TII->get(Opc2), GPR3).addReg(GPR3);
          } else if (!IsTLSTPRelMI) {
            // The variable offset and region handle (for TLSGD) are copied in
            // r4 and r3. The copies are followed by
            // GETtlsADDR32AIX/GETtlsADDR64AIX.
            BuildMI(MBB, I, DL, TII->get(TargetOpcode::COPY), GPR4)
                .addReg(MI.getOperand(1).getReg());
            BuildMI(MBB, I, DL, TII->get(TargetOpcode::COPY), GPR3)
                .addReg(MI.getOperand(2).getReg());
            BuildMI(MBB, I, DL, TII->get(Opc2), GPR3).addReg(GPR3).addReg(GPR4);
          } else
            // The opcode of GETtlsTpointer32AIX does not change, because later
            // this instruction will be expanded into a call to .__get_tpointer,
            // which will return the thread pointer into r3.
            BuildMI(MBB, I, DL, TII->get(Opc2), GPR3);
        } else {
          MachineInstr *Addi;
          if (IsPCREL) {
            Addi = BuildMI(MBB, I, DL, TII->get(Opc1), GPR3).addImm(0);
          } else {
            // Expand into two ops built prior to the existing instruction.
            assert(InReg != PPC::NoRegister && "Operand must be a register");
            Addi = BuildMI(MBB, I, DL, TII->get(Opc1), GPR3).addReg(InReg);
          }

          Addi->addOperand(MI.getOperand(2));

          MachineInstr *Call =
              (BuildMI(MBB, I, DL, TII->get(Opc2), GPR3).addReg(GPR3));
          if (IsPCREL)
            Call->addOperand(MI.getOperand(2));
          else
            Call->addOperand(MI.getOperand(3));
        }
        if (NeedFence)
          BuildMI(MBB, I, DL, TII->get(PPC::ADJCALLSTACKUP)).addImm(0).addImm(0);

        BuildMI(MBB, I, DL, TII->get(TargetOpcode::COPY), OutReg)
          .addReg(GPR3);

        // Move past the original instruction and remove it.
        ++I;
        MI.removeFromParent();

        Changed = true;
      }

      return Changed;
    }

public:
  bool isPCREL(const MachineInstr &MI) {
    return (MI.getOpcode() == PPC::PADDI8pc) &&
           (MI.getOperand(2).getTargetFlags() ==
                PPCII::MO_GOT_TLSGD_PCREL_FLAG ||
            MI.getOperand(2).getTargetFlags() ==
                PPCII::MO_GOT_TLSLD_PCREL_FLAG);
  }

    bool runOnMachineFunction(MachineFunction &MF) override {
      TII = MF.getSubtarget<PPCSubtarget>().getInstrInfo();

      bool Changed = false;

      for (MachineBasicBlock &B : llvm::make_early_inc_range(MF))
        if (processBlock(B))
          Changed = true;

      return Changed;
    }

    void getAnalysisUsage(AnalysisUsage &AU) const override {
      AU.addRequired<LiveIntervalsWrapperPass>();
      AU.addRequired<SlotIndexesWrapperPass>();
      MachineFunctionPass::getAnalysisUsage(AU);
    }
  };
}

INITIALIZE_PASS_BEGIN(PPCTLSDynamicCall, DEBUG_TYPE,
                      "PowerPC TLS Dynamic Call Fixup", false, false)
INITIALIZE_PASS_DEPENDENCY(LiveIntervalsWrapperPass)
INITIALIZE_PASS_DEPENDENCY(SlotIndexesWrapperPass)
INITIALIZE_PASS_END(PPCTLSDynamicCall, DEBUG_TYPE,
                    "PowerPC TLS Dynamic Call Fixup", false, false)

char PPCTLSDynamicCall::ID = 0;
FunctionPass*
llvm::createPPCTLSDynamicCallPass() { return new PPCTLSDynamicCall(); }
