//===-- ExpandPostRAPseudos.cpp - Pseudo instruction expansion pass -------===//
//
// 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 file defines a pass that expands COPY and SUBREG_TO_REG pseudo
// instructions after register allocation.
//
//===----------------------------------------------------------------------===//

#include "llvm/CodeGen/ExpandPostRAPseudos.h"
#include "llvm/CodeGen/MachineDominators.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
#include "llvm/CodeGen/TargetRegisterInfo.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/InitializePasses.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"

using namespace llvm;

#define DEBUG_TYPE "post-ra-pseudos"

namespace {
struct ExpandPostRA {
  bool run(MachineFunction &);

private:
  const TargetRegisterInfo *TRI = nullptr;
  const TargetInstrInfo *TII = nullptr;

  bool LowerSubregToReg(MachineInstr *MI);
};

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

  void getAnalysisUsage(AnalysisUsage &AU) const override {
    AU.setPreservesCFG();
    MachineFunctionPass::getAnalysisUsage(AU);
  }

  /// runOnMachineFunction - pass entry point
  bool runOnMachineFunction(MachineFunction &) override;
};
} // end anonymous namespace

PreservedAnalyses
ExpandPostRAPseudosPass::run(MachineFunction &MF,
                             MachineFunctionAnalysisManager &MFAM) {
  if (!ExpandPostRA().run(MF))
    return PreservedAnalyses::all();

  return getMachineFunctionPassPreservedAnalyses().preserveSet<CFGAnalyses>();
}

char ExpandPostRALegacy::ID = 0;
char &llvm::ExpandPostRAPseudosID = ExpandPostRALegacy::ID;

INITIALIZE_PASS(ExpandPostRALegacy, DEBUG_TYPE,
                "Post-RA pseudo instruction expansion pass", false, false)

bool ExpandPostRA::LowerSubregToReg(MachineInstr *MI) {
  MachineBasicBlock *MBB = MI->getParent();
  assert(MI->getOperand(0).isReg() && MI->getOperand(0).isDef() &&
         MI->getOperand(1).isReg() && MI->getOperand(1).isUse() &&
         MI->getOperand(2).isImm() && "Invalid subreg_to_reg");

  Register DstReg = MI->getOperand(0).getReg();
  Register InsReg = MI->getOperand(1).getReg();
  assert(!MI->getOperand(1).getSubReg() && "SubIdx on physreg?");
  unsigned SubIdx = MI->getOperand(2).getImm();

  assert(SubIdx != 0 && "Invalid index for insert_subreg");
  Register DstSubReg = TRI->getSubReg(DstReg, SubIdx);

  assert(DstReg.isPhysical() &&
         "Insert destination must be in a physical register");
  assert(InsReg.isPhysical() &&
         "Inserted value must be in a physical register");

  LLVM_DEBUG(dbgs() << "subreg: CONVERTING: " << *MI);

  if (MI->allDefsAreDead() || DstSubReg == InsReg) {
    // No need to insert an identity copy instruction.
    // Watch out for case like this:
    // %rax = SUBREG_TO_REG killed %eax, 3
    // We must leave %rax live.
    MI->setDesc(TII->get(TargetOpcode::KILL));
    MI->removeOperand(2); // SubIdx
    LLVM_DEBUG(dbgs() << "subreg: replaced by: " << *MI);
    return true;
  }

  TII->copyPhysReg(*MBB, MI, MI->getDebugLoc(), DstSubReg, InsReg,
                   MI->getOperand(1).isKill());

  // Implicitly define DstReg for subsequent uses.
  MachineBasicBlock::iterator CopyMI = MI;
  --CopyMI;
  CopyMI->addRegisterDefined(DstReg);
  LLVM_DEBUG(dbgs() << "subreg: " << *CopyMI);

  MBB->erase(MI);
  return true;
}

bool ExpandPostRALegacy::runOnMachineFunction(MachineFunction &MF) {
  return ExpandPostRA().run(MF);
}

/// runOnMachineFunction - Reduce subregister inserts and extracts to register
/// copies.
///
bool ExpandPostRA::run(MachineFunction &MF) {
  LLVM_DEBUG(dbgs() << "Machine Function\n"
                    << "********** EXPANDING POST-RA PSEUDO INSTRS **********\n"
                    << "********** Function: " << MF.getName() << '\n');
  TRI = MF.getSubtarget().getRegisterInfo();
  TII = MF.getSubtarget().getInstrInfo();

  bool MadeChange = false;

  for (MachineBasicBlock &MBB : MF) {
    for (MachineInstr &MI : llvm::make_early_inc_range(MBB)) {
      // Only expand pseudos.
      if (!MI.isPseudo())
        continue;

      // Give targets a chance to expand even standard pseudos.
      if (TII->expandPostRAPseudo(MI)) {
        MadeChange = true;
        continue;
      }

      // Expand standard pseudos.
      switch (MI.getOpcode()) {
      case TargetOpcode::SUBREG_TO_REG:
        MadeChange |= LowerSubregToReg(&MI);
        break;
      case TargetOpcode::COPY:
        TII->lowerCopy(&MI);
        MadeChange = true;
        break;
      case TargetOpcode::DBG_VALUE:
        continue;
      case TargetOpcode::INSERT_SUBREG:
      case TargetOpcode::EXTRACT_SUBREG:
        llvm_unreachable("Sub-register pseudos should have been eliminated.");
      }
    }
  }

  return MadeChange;
}
