//===-- WebAssemblyDebugFixup.cpp - Debug 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
//
//===----------------------------------------------------------------------===//
///
/// \file
/// Several prior passes may "stackify" registers, here we ensure any references
/// in such registers in debug_value instructions become stack relative also.
/// This is done in a separate pass such that not all previous passes need to
/// track stack depth when values get stackified.
///
//===----------------------------------------------------------------------===//

#include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
#include "WebAssembly.h"
#include "WebAssemblyMachineFunctionInfo.h"
#include "WebAssemblySubtarget.h"
#include "WebAssemblyUtilities.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;

#define DEBUG_TYPE "wasm-debug-fixup"

namespace {
class WebAssemblyDebugFixup final : public MachineFunctionPass {
  StringRef getPassName() const override { return "WebAssembly Debug Fixup"; }

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

  bool runOnMachineFunction(MachineFunction &MF) override;

public:
  static char ID; // Pass identification, replacement for typeid
  WebAssemblyDebugFixup() : MachineFunctionPass(ID) {}
};
} // end anonymous namespace

char WebAssemblyDebugFixup::ID = 0;
INITIALIZE_PASS(
    WebAssemblyDebugFixup, DEBUG_TYPE,
    "Ensures debug_value's that have been stackified become stack relative",
    false, false)

FunctionPass *llvm::createWebAssemblyDebugFixup() {
  return new WebAssemblyDebugFixup();
}

// At this very end of the compilation pipeline, if any DBG_VALUEs with
// registers remain, it means they are dangling info which we failed to update
// when their corresponding def instruction was transformed/moved/splitted etc.
// Because Wasm cannot access values in LLVM virtual registers in the debugger,
// these dangling DBG_VALUEs in effect kill the effect of any previous DBG_VALUE
// associated with the variable, which will appear as "optimized out".
static void setDanglingDebugValuesUndef(MachineBasicBlock &MBB,
                                        const TargetInstrInfo *TII) {
  for (auto &MI : llvm::make_early_inc_range(MBB)) {
    if (MI.isDebugValue() && MI.getDebugOperand(0).isReg() &&
        !MI.isUndefDebugValue()) {
      LLVM_DEBUG(dbgs() << "Warning: dangling DBG_VALUE set to undef: " << MI
                        << "\n");
      MI.setDebugValueUndef();
    }
  }
}

bool WebAssemblyDebugFixup::runOnMachineFunction(MachineFunction &MF) {
  LLVM_DEBUG(dbgs() << "********** Debug Fixup **********\n"
                       "********** Function: "
                    << MF.getName() << '\n');

  WebAssemblyFunctionInfo &MFI = *MF.getInfo<WebAssemblyFunctionInfo>();
  const auto *TII = MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();

  struct StackElem {
    unsigned Reg;
    MachineInstr *DebugValue;
  };
  std::vector<StackElem> Stack;
  for (MachineBasicBlock &MBB : MF) {
    // We may insert into this list.
    for (auto MII = MBB.begin(); MII != MBB.end(); ++MII) {
      MachineInstr &MI = *MII;
      if (MI.isDebugValue()) {
        auto &MO = MI.getOperand(0);
        // Also check if not a $noreg: likely a DBG_VALUE we just inserted.
        if (MO.isReg() && MO.getReg().isValid() &&
            MFI.isVRegStackified(MO.getReg())) {
          // Found a DBG_VALUE with a stackified register we will
          // change into a stack operand.
          // Search for register rather than assume it is on top (which it
          // typically is if it appears right after the def), since
          // DBG_VALUE's may shift under some circumstances.
          for (auto &Elem : reverse(Stack)) {
            if (MO.getReg() == Elem.Reg) {
              auto Depth = static_cast<unsigned>(&Elem - &Stack[0]);
              LLVM_DEBUG(dbgs() << "Debug Value VReg " << printReg(MO.getReg())
                                << " -> Stack Relative " << Depth << "\n");
              MO.ChangeToTargetIndex(WebAssembly::TI_OPERAND_STACK, Depth);
              // Save the DBG_VALUE instruction that defined this stackified
              // variable since later we need it to construct another one on
              // pop.
              Elem.DebugValue = &MI;
              break;
            }
          }
          // If the Reg was not found, we have a DBG_VALUE outside of its
          // def-use range, and we leave it unmodified as reg, which means
          // it will be culled later.
        }
      } else {
        // Track stack depth.
        for (MachineOperand &MO : reverse(MI.explicit_uses())) {
          if (MO.isReg() && MFI.isVRegStackified(MO.getReg())) {
            auto Prev = Stack.back();
            Stack.pop_back();
            assert(Prev.Reg == MO.getReg() &&
                   "WebAssemblyDebugFixup: Pop: Register not matched!");
            // We should not put a DBG_VALUE after a terminator; debug ranges
            // are terminated at the end of a BB anyway.
            if (Prev.DebugValue && !MI.isTerminator()) {
              // This stackified reg is a variable that started life at
              // Prev.DebugValue, so now that we're popping it we must insert
              // a $noreg DBG_VALUE for the variable to end it, right after
              // the current instruction.
              BuildMI(*Prev.DebugValue->getParent(), std::next(MII),
                      Prev.DebugValue->getDebugLoc(),
                      TII->get(WebAssembly::DBG_VALUE), false, Register(),
                      Prev.DebugValue->getOperand(2).getMetadata(),
                      Prev.DebugValue->getOperand(3).getMetadata());
            }
          }
        }
        for (MachineOperand &MO : MI.defs()) {
          if (MO.isReg() && MFI.isVRegStackified(MO.getReg())) {
            Stack.push_back({MO.getReg(), nullptr});
          }
        }
      }
    }
    assert(Stack.empty() &&
           "WebAssemblyDebugFixup: Stack not empty at end of basic block!");

    setDanglingDebugValuesUndef(MBB, TII);
  }

  return true;
}
