//===- DIExpressionOptimizer.cpp - Constant folding of DIExpressions ------===//
//
// 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 implements functions to constant fold DIExpressions. Which were
// declared in DIExpressionOptimizer.h
//
//===----------------------------------------------------------------------===//

#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/IR/DebugInfoMetadata.h"

using namespace llvm;

/// Returns true if the Op is a DW_OP_constu.
static std::optional<uint64_t> isConstantVal(DIExpression::ExprOperand Op) {
  if (auto Constant = dyn_cast<DIExpression::ConstuOp>(Op))
    return Constant.getValue();
  return std::nullopt;
}

/// Returns true if an operation and operand result in a No Op.
static bool isNeutralElement(uint64_t Op, uint64_t Val) {
  switch (Op) {
  case dwarf::DW_OP_plus:
  case dwarf::DW_OP_minus:
  case dwarf::DW_OP_shl:
  case dwarf::DW_OP_shr:
    return Val == 0;
  case dwarf::DW_OP_mul:
  case dwarf::DW_OP_div:
    return Val == 1;
  default:
    return false;
  }
}

/// Try to fold \p Const1 and \p Const2 by applying \p Operator and returning
/// the result, if there is an overflow, return a std::nullopt.
static std::optional<uint64_t>
foldOperationIfPossible(uint64_t Const1, uint64_t Const2,
                        dwarf::LocationAtom Operator) {

  bool ResultOverflowed;
  switch (Operator) {
  case dwarf::DW_OP_plus: {
    auto Result = SaturatingAdd(Const1, Const2, &ResultOverflowed);
    if (ResultOverflowed)
      return std::nullopt;
    return Result;
  }
  case dwarf::DW_OP_minus: {
    if (Const1 < Const2)
      return std::nullopt;
    return Const1 - Const2;
  }
  case dwarf::DW_OP_shl: {
    if (Const2 >= std::numeric_limits<uint64_t>::digits ||
        static_cast<uint64_t>(countl_zero(Const1)) < Const2)
      return std::nullopt;
    return Const1 << Const2;
  }
  case dwarf::DW_OP_shr: {
    if (Const2 >= std::numeric_limits<uint64_t>::digits ||
        static_cast<uint64_t>(countr_zero(Const1)) < Const2)
      return std::nullopt;
    return Const1 >> Const2;
  }
  case dwarf::DW_OP_mul: {
    auto Result = SaturatingMultiply(Const1, Const2, &ResultOverflowed);
    if (ResultOverflowed)
      return std::nullopt;
    return Result;
  }
  case dwarf::DW_OP_div: {
    if (Const2)
      return Const1 / Const2;
    return std::nullopt;
  }
  default:
    return std::nullopt;
  }
}

/// Returns true if the two operations \p Operator1 and \p Operator2 are
/// commutative and can be folded.
static bool operationsAreFoldableAndCommutative(dwarf::LocationAtom Operator1,
                                                dwarf::LocationAtom Operator2) {
  return Operator1 == Operator2 &&
         (Operator1 == dwarf::DW_OP_plus || Operator1 == dwarf::DW_OP_mul);
}

/// Consume one operator and its operand(s).
static void consumeOneOperator(DIExpressionCursor &Cursor, uint64_t &Loc,
                               const DIExpression::ExprOperand &Op) {
  Cursor.consume(1);
  Loc = Loc + Op.getSize();
}

/// Reset the Cursor to the beginning of the WorkingOps.
void startFromBeginning(uint64_t &Loc, DIExpressionCursor &Cursor,
                        ArrayRef<uint64_t> WorkingOps) {
  Cursor.assignNewExpr(WorkingOps);
  Loc = 0;
}

/// This function will canonicalize:
/// 1. DW_OP_plus_uconst to DW_OP_constu <const-val> DW_OP_plus
/// 2. DW_OP_lit<n> to DW_OP_constu <n>
static SmallVector<uint64_t>
canonicalizeDwarfOperations(ArrayRef<uint64_t> WorkingOps) {
  DIExpressionCursor Cursor(WorkingOps);
  uint64_t Loc = 0;
  SmallVector<uint64_t> ResultOps;
  while (Loc < WorkingOps.size()) {
    auto Op = Cursor.peek();
    /// Expression has no operations, break.
    if (!Op)
      break;
    auto OpRaw = Op->getOp();

    if (DIExpression::isLitOp(OpRaw)) {
      ResultOps.push_back(dwarf::DW_OP_constu);
      ResultOps.push_back(OpRaw - dwarf::DW_OP_lit0);
      consumeOneOperator(Cursor, Loc, *Cursor.peek());
      continue;
    }
    if (auto PlusUconst = dyn_cast<DIExpression::PlusUconstOp>(*Op)) {
      ResultOps.push_back(dwarf::DW_OP_constu);
      ResultOps.push_back(PlusUconst.getOffset());
      ResultOps.push_back(dwarf::DW_OP_plus);
      consumeOneOperator(Cursor, Loc, *Cursor.peek());
      continue;
    }
    uint64_t PrevLoc = Loc;
    consumeOneOperator(Cursor, Loc, *Cursor.peek());
    ResultOps.append(WorkingOps.begin() + PrevLoc, WorkingOps.begin() + Loc);
  }
  return ResultOps;
}

/// This function will convert:
/// 1. DW_OP_constu <const-val> DW_OP_plus to DW_OP_plus_uconst
/// 2. DW_OP_constu, 0 to DW_OP_lit0
static SmallVector<uint64_t>
optimizeDwarfOperations(ArrayRef<uint64_t> WorkingOps) {
  DIExpressionCursor Cursor(WorkingOps);
  uint64_t Loc = 0;
  SmallVector<uint64_t> ResultOps;
  while (Loc < WorkingOps.size()) {
    auto Op1 = Cursor.peek();
    /// Expression has no operations, exit.
    if (!Op1)
      break;

    auto Constant = dyn_cast<DIExpression::ConstuOp>(*Op1);
    if (Constant && Constant.getValue() == 0) {
      ResultOps.push_back(dwarf::DW_OP_lit0);
      consumeOneOperator(Cursor, Loc, *Cursor.peek());
      continue;
    }

    auto Op2 = Cursor.peekNext();
    /// Expression has no more operations, copy into ResultOps and exit.
    if (!Op2) {
      uint64_t PrevLoc = Loc;
      consumeOneOperator(Cursor, Loc, *Cursor.peek());
      ResultOps.append(WorkingOps.begin() + PrevLoc, WorkingOps.begin() + Loc);
      break;
    }
    auto Op2Raw = Op2->getOp();

    if (Constant && Op2Raw == dwarf::DW_OP_plus) {
      ResultOps.push_back(dwarf::DW_OP_plus_uconst);
      ResultOps.push_back(Constant.getValue());
      consumeOneOperator(Cursor, Loc, *Cursor.peek());
      consumeOneOperator(Cursor, Loc, *Cursor.peek());
      continue;
    }
    uint64_t PrevLoc = Loc;
    consumeOneOperator(Cursor, Loc, *Cursor.peek());
    ResultOps.append(WorkingOps.begin() + PrevLoc, WorkingOps.begin() + Loc);
  }
  return ResultOps;
}

/// {DW_OP_constu, 0, DW_OP_[plus, minus, shl, shr]} -> {}
/// {DW_OP_constu, 1, DW_OP_[mul, div]} -> {}
static bool tryFoldNoOpMath(uint64_t Const1,
                            ArrayRef<DIExpression::ExprOperand> Ops,
                            uint64_t &Loc, DIExpressionCursor &Cursor,
                            SmallVectorImpl<uint64_t> &WorkingOps) {

  if (isNeutralElement(Ops[1].getOp(), Const1)) {
    WorkingOps.erase(WorkingOps.begin() + Loc, WorkingOps.begin() + Loc + 3);
    startFromBeginning(Loc, Cursor, WorkingOps);
    return true;
  }
  return false;
}

/// {DW_OP_constu, Const1, DW_OP_constu, Const2, DW_OP_[plus,
/// minus, mul, div, shl, shr] -> {DW_OP_constu, Const1 [+, -, *, /, <<, >>]
/// Const2}
static bool tryFoldConstants(uint64_t Const1,
                             ArrayRef<DIExpression::ExprOperand> Ops,
                             uint64_t &Loc, DIExpressionCursor &Cursor,
                             SmallVectorImpl<uint64_t> &WorkingOps) {

  auto Const2 = isConstantVal(Ops[1]);
  if (!Const2)
    return false;

  auto Result = foldOperationIfPossible(
      Const1, *Const2, static_cast<dwarf::LocationAtom>(Ops[2].getOp()));
  if (!Result) {
    consumeOneOperator(Cursor, Loc, Ops[0]);
    return true;
  }
  WorkingOps.erase(WorkingOps.begin() + Loc + 2, WorkingOps.begin() + Loc + 5);
  WorkingOps[Loc] = dwarf::DW_OP_constu;
  WorkingOps[Loc + 1] = *Result;
  startFromBeginning(Loc, Cursor, WorkingOps);
  return true;
}

/// {DW_OP_constu, Const1, DW_OP_[plus, mul], DW_OP_constu, Const2,
/// DW_OP_[plus, mul]} -> {DW_OP_constu, Const1 [+, *] Const2, DW_OP_[plus,
/// mul]}
static bool tryFoldCommutativeMath(uint64_t Const1,
                                   ArrayRef<DIExpression::ExprOperand> Ops,
                                   uint64_t &Loc, DIExpressionCursor &Cursor,
                                   SmallVectorImpl<uint64_t> &WorkingOps) {

  auto Const2 = isConstantVal(Ops[2]);
  auto Operand1 = static_cast<dwarf::LocationAtom>(Ops[1].getOp());
  auto Operand2 = static_cast<dwarf::LocationAtom>(Ops[3].getOp());

  if (!Const2 || !operationsAreFoldableAndCommutative(Operand1, Operand2))
    return false;

  auto Result = foldOperationIfPossible(Const1, *Const2, Operand1);
  if (!Result) {
    consumeOneOperator(Cursor, Loc, Ops[0]);
    return true;
  }
  WorkingOps.erase(WorkingOps.begin() + Loc + 3, WorkingOps.begin() + Loc + 6);
  WorkingOps[Loc] = dwarf::DW_OP_constu;
  WorkingOps[Loc + 1] = *Result;
  startFromBeginning(Loc, Cursor, WorkingOps);
  return true;
}

/// {DW_OP_constu, Const1, DW_OP_[plus, mul], DW_OP_LLVM_arg, Arg1,
/// DW_OP_[plus, mul], DW_OP_constu, Const2, DW_OP_[plus, mul]} ->
/// {DW_OP_constu, Const1 [+, *] Const2, DW_OP_[plus, mul], DW_OP_LLVM_arg,
/// Arg1, DW_OP_[plus, mul]}
static bool tryFoldCommutativeMathWithArgInBetween(
    uint64_t Const1, ArrayRef<DIExpression::ExprOperand> Ops, uint64_t &Loc,
    DIExpressionCursor &Cursor, SmallVectorImpl<uint64_t> &WorkingOps) {

  auto Const2 = isConstantVal(Ops[4]);
  auto Operand1 = static_cast<dwarf::LocationAtom>(Ops[1].getOp());
  auto Operand2 = static_cast<dwarf::LocationAtom>(Ops[3].getOp());
  auto Operand3 = static_cast<dwarf::LocationAtom>(Ops[5].getOp());

  if (!Const2 || Ops[2].getOp() != dwarf::DW_OP_LLVM_arg ||
      !operationsAreFoldableAndCommutative(Operand1, Operand2) ||
      !operationsAreFoldableAndCommutative(Operand2, Operand3))
    return false;

  auto Result = foldOperationIfPossible(Const1, *Const2, Operand1);
  if (!Result) {
    consumeOneOperator(Cursor, Loc, Ops[0]);
    return true;
  }
  WorkingOps.erase(WorkingOps.begin() + Loc + 6, WorkingOps.begin() + Loc + 9);
  WorkingOps[Loc] = dwarf::DW_OP_constu;
  WorkingOps[Loc + 1] = *Result;
  startFromBeginning(Loc, Cursor, WorkingOps);
  return true;
}

DIExpression *DIExpression::foldConstantMath() {

  SmallVector<uint64_t, 8> WorkingOps(Elements.begin(), Elements.end());
  uint64_t Loc = 0;
  SmallVector<uint64_t> ResultOps = canonicalizeDwarfOperations(WorkingOps);
  DIExpressionCursor Cursor(ResultOps);
  SmallVector<DIExpression::ExprOperand, 8> Ops;

  // Iterate over all Operations in a DIExpression to match the smallest pattern
  // that can be folded.
  while (Loc < ResultOps.size()) {
    Ops.clear();

    auto Op = Cursor.peek();
    // Expression has no operations, exit.
    if (!Op)
      break;

    auto Const1 = isConstantVal(*Op);

    if (!Const1) {
      // Early exit, all of the following patterns start with a constant value.
      consumeOneOperator(Cursor, Loc, *Op);
      continue;
    }

    Ops.push_back(*Op);

    Op = Cursor.peekNext();
    // All following patterns require at least 2 Operations, exit.
    if (!Op)
      break;

    Ops.push_back(*Op);

    // Try to fold a constant no-op, such as {+ 0}
    if (tryFoldNoOpMath(*Const1, Ops, Loc, Cursor, ResultOps))
      continue;

    Op = Cursor.peekNextN(2);
    // Op[1] could still match a pattern, skip iteration.
    if (!Op) {
      consumeOneOperator(Cursor, Loc, Ops[0]);
      continue;
    }

    Ops.push_back(*Op);

    // Try to fold a pattern of two constants such as {C1 + C2}.
    if (tryFoldConstants(*Const1, Ops, Loc, Cursor, ResultOps))
      continue;

    Op = Cursor.peekNextN(3);
    // Op[1] and Op[2] could still match a pattern, skip iteration.
    if (!Op) {
      consumeOneOperator(Cursor, Loc, Ops[0]);
      continue;
    }

    Ops.push_back(*Op);

    // Try to fold commutative constant math, such as {C1 + C2 +}.
    if (tryFoldCommutativeMath(*Const1, Ops, Loc, Cursor, ResultOps))
      continue;

    Op = Cursor.peekNextN(4);
    if (!Op) {
      consumeOneOperator(Cursor, Loc, Ops[0]);
      continue;
    }

    Ops.push_back(*Op);
    Op = Cursor.peekNextN(5);
    if (!Op) {
      consumeOneOperator(Cursor, Loc, Ops[0]);
      continue;
    }

    Ops.push_back(*Op);

    // Try to fold commutative constant math with an LLVM_Arg in between, such
    // as {C1 + Arg + C2 +}.
    if (tryFoldCommutativeMathWithArgInBetween(*Const1, Ops, Loc, Cursor,
                                               ResultOps))
      continue;

    consumeOneOperator(Cursor, Loc, Ops[0]);
  }
  ResultOps = optimizeDwarfOperations(ResultOps);
  auto *Result = DIExpression::get(getContext(), ResultOps);
  assert(Result->isValid() && "concatenated expression is not valid");
  return Result;
}
