//===---------- PPCTLSDynamicCall.cpp - TLS Dynamic Call Fixup ------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// 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 "PPCInstrInfo.h"
#include "PPC.h"
#include "PPCInstrBuilder.h"
#include "PPCTargetMachine.h"
#include "llvm/CodeGen/LiveIntervalAnalysis.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 llvm {
  void initializePPCTLSDynamicCallPass(PassRegistry&);
}

namespace {
  struct PPCTLSDynamicCall : public MachineFunctionPass {
    static char ID;
    PPCTLSDynamicCall() : MachineFunctionPass(ID) {
      initializePPCTLSDynamicCallPass(*PassRegistry::getPassRegistry());
    }

    const PPCInstrInfo *TII;
    LiveIntervals *LIS;

protected:
    bool processBlock(MachineBasicBlock &MBB) {
      bool Changed = false;
      bool Is64Bit = MBB.getParent()->getSubtarget<PPCSubtarget>().isPPC64();

      for (MachineBasicBlock::iterator I = MBB.begin(), IE = MBB.end();
           I != IE;) {
        MachineInstr *MI = I;

        if (MI->getOpcode() != PPC::ADDItlsgdLADDR &&
            MI->getOpcode() != PPC::ADDItlsldLADDR &&
            MI->getOpcode() != PPC::ADDItlsgdLADDR32 &&
            MI->getOpcode() != PPC::ADDItlsldLADDR32) {
          ++I;
          continue;
        }

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

        unsigned OutReg = MI->getOperand(0).getReg();
        unsigned InReg  = MI->getOperand(1).getReg();
        DebugLoc DL = MI->getDebugLoc();
        unsigned GPR3 = Is64Bit ? PPC::X3 : PPC::R3;
        unsigned Opc1, Opc2;
        SmallVector<unsigned, 4> OrigRegs;
        OrigRegs.push_back(OutReg);
        OrigRegs.push_back(InReg);
        OrigRegs.push_back(GPR3);

        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;
        }

        // 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).
        BuildMI(MBB, I, DL, TII->get(PPC::ADJCALLSTACKDOWN)).addImm(0);

        // Expand into two ops built prior to the existing instruction.
        MachineInstr *Addi = BuildMI(MBB, I, DL, TII->get(Opc1), GPR3)
          .addReg(InReg);
        Addi->addOperand(MI->getOperand(2));

        // The ADDItls* instruction is the first instruction in the
        // repair range.
        MachineBasicBlock::iterator First = I;
        --First;

        MachineInstr *Call = (BuildMI(MBB, I, DL, TII->get(Opc2), GPR3)
                              .addReg(GPR3));
        Call->addOperand(MI->getOperand(3));

        BuildMI(MBB, I, DL, TII->get(PPC::ADJCALLSTACKUP)).addImm(0).addImm(0);

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

        // The COPY is the last instruction in the repair range.
        MachineBasicBlock::iterator Last = I;
        --Last;

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

        // Repair the live intervals.
        LIS->repairIntervalsInRange(&MBB, First, Last, OrigRegs);
        Changed = true;
      }

      return Changed;
    }

public:
    bool runOnMachineFunction(MachineFunction &MF) override {
      TII = MF.getSubtarget<PPCSubtarget>().getInstrInfo();
      LIS = &getAnalysis<LiveIntervals>();

      bool Changed = false;

      for (MachineFunction::iterator I = MF.begin(); I != MF.end();) {
        MachineBasicBlock &B = *I++;
        if (processBlock(B))
          Changed = true;
      }

      return Changed;
    }

    void getAnalysisUsage(AnalysisUsage &AU) const override {
      AU.addRequired<LiveIntervals>();
      AU.addPreserved<LiveIntervals>();
      AU.addRequired<SlotIndexes>();
      AU.addPreserved<SlotIndexes>();
      MachineFunctionPass::getAnalysisUsage(AU);
    }
  };
}

INITIALIZE_PASS_BEGIN(PPCTLSDynamicCall, DEBUG_TYPE,
                      "PowerPC TLS Dynamic Call Fixup", false, false)
INITIALIZE_PASS_DEPENDENCY(LiveIntervals)
INITIALIZE_PASS_DEPENDENCY(SlotIndexes)
INITIALIZE_PASS_END(PPCTLSDynamicCall, DEBUG_TYPE,
                    "PowerPC TLS Dynamic Call Fixup", false, false)

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