//===- bolt/Passes/CMOVConversion.cpp ------------------------------------===//
//
// 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 the CMOV conversion pass.
//
//===----------------------------------------------------------------------===//

#include "bolt/Passes/CMOVConversion.h"
#include "bolt/Core/BinaryBasicBlock.h"
#include "bolt/Core/BinaryContext.h"
#include "bolt/Utils/CommandLineOpts.h"
#include "llvm/ADT/PostOrderIterator.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"

#define DEBUG_TYPE "cmov"

using namespace llvm;

namespace opts {

extern cl::OptionCategory BoltOptCategory;

static cl::opt<int> BiasThreshold(
    "cmov-conversion-bias-threshold",
    cl::desc("minimum condition bias (pct) to perform a CMOV conversion, "
             "-1 to not account bias"),
    cl::ReallyHidden, cl::init(1), cl::cat(BoltOptCategory));

static cl::opt<int> MispredictionThreshold(
    "cmov-conversion-misprediction-threshold",
    cl::desc("minimum misprediction rate (pct) to perform a CMOV conversion, "
             "-1 to not account misprediction rate"),
    cl::ReallyHidden, cl::init(5), cl::cat(BoltOptCategory));

static cl::opt<bool> ConvertStackMemOperand(
    "cmov-conversion-convert-stack-mem-operand",
    cl::desc("convert moves with stack memory operand (potentially unsafe)"),
    cl::ReallyHidden, cl::init(false), cl::cat(BoltOptCategory));

static cl::opt<bool> ConvertBasePtrStackMemOperand(
    "cmov-conversion-convert-rbp-stack-mem-operand",
    cl::desc("convert moves with rbp stack memory operand (unsafe, must be off "
             "for binaries compiled with -fomit-frame-pointer)"),
    cl::ReallyHidden, cl::init(false), cl::cat(BoltOptCategory));

} // namespace opts

namespace llvm {
namespace bolt {

// Return true if the CFG conforms to the following subgraph:
// Predecessor
//   /     \
//  |     RHS
//   \     /
//     LHS
// Caller guarantees that LHS and RHS share the same predecessor.
bool isIfThenSubgraph(const BinaryBasicBlock &LHS,
                      const BinaryBasicBlock &RHS) {
  if (LHS.pred_size() != 2 || RHS.pred_size() != 1)
    return false;

  // Sanity check
  BinaryBasicBlock *Predecessor = *RHS.pred_begin();
  assert(Predecessor && LHS.isPredecessor(Predecessor) && "invalid subgraph");
  (void)Predecessor;

  if (!LHS.isPredecessor(&RHS))
    return false;
  if (RHS.succ_size() != 1)
    return false;
  return true;
}

bool matchCFGSubgraph(BinaryBasicBlock &BB, BinaryBasicBlock *&ConditionalSucc,
                      BinaryBasicBlock *&UnconditionalSucc,
                      bool &IsConditionalTaken) {
  BinaryBasicBlock *TakenSucc = BB.getConditionalSuccessor(true);
  BinaryBasicBlock *FallthroughSucc = BB.getConditionalSuccessor(false);
  bool IsIfThenTaken = isIfThenSubgraph(*FallthroughSucc, *TakenSucc);
  bool IsIfThenFallthrough = isIfThenSubgraph(*TakenSucc, *FallthroughSucc);
  if (!IsIfThenFallthrough && !IsIfThenTaken)
    return false;
  assert((!IsIfThenFallthrough || !IsIfThenTaken) && "Invalid subgraph");

  // Output parameters
  ConditionalSucc = IsIfThenTaken ? TakenSucc : FallthroughSucc;
  UnconditionalSucc = IsIfThenTaken ? FallthroughSucc : TakenSucc;
  IsConditionalTaken = IsIfThenTaken;
  return true;
}

// Return true if basic block instructions can be converted into cmov(s).
bool canConvertInstructions(const BinaryContext &BC, const BinaryBasicBlock &BB,
                            unsigned CC) {
  if (BB.empty())
    return false;
  const MCInst *LastInst = BB.getLastNonPseudoInstr();
  // Only pseudo instructions, can't be converted into CMOV
  if (LastInst == nullptr)
    return false;
  for (const MCInst &Inst : BB) {
    if (BC.MIB->isPseudo(Inst))
      continue;
    // Unconditional branch as a last instruction is OK
    if (&Inst == LastInst && BC.MIB->isUnconditionalBranch(Inst))
      continue;
    MCInst Cmov(Inst);
    // GPR move is OK
    if (!BC.MIB->convertMoveToConditionalMove(
            Cmov, CC, opts::ConvertStackMemOperand,
            opts::ConvertBasePtrStackMemOperand)) {
      LLVM_DEBUG({
        dbgs() << BB.getName() << ": can't convert instruction ";
        BC.printInstruction(dbgs(), Cmov);
      });
      return false;
    }
  }
  return true;
}

void convertMoves(const BinaryContext &BC, BinaryBasicBlock &BB, unsigned CC) {
  for (auto II = BB.begin(), IE = BB.end(); II != IE; ++II) {
    if (BC.MIB->isPseudo(*II))
      continue;
    if (BC.MIB->isUnconditionalBranch(*II)) {
      // XXX: this invalidates II but we return immediately
      BB.eraseInstruction(II);
      return;
    }
    bool Result = BC.MIB->convertMoveToConditionalMove(
        *II, CC, opts::ConvertStackMemOperand,
        opts::ConvertBasePtrStackMemOperand);
    assert(Result && "unexpected instruction");
    (void)Result;
  }
}

// Returns misprediction rate if the profile data is available, -1 otherwise.
std::pair<int, uint64_t>
calculateMispredictionRate(const BinaryBasicBlock &BB) {
  uint64_t TotalExecCount = 0;
  uint64_t TotalMispredictionCount = 0;
  for (auto BI : BB.branch_info()) {
    TotalExecCount += BI.Count;
    if (BI.MispredictedCount != BinaryBasicBlock::COUNT_INFERRED)
      TotalMispredictionCount += BI.MispredictedCount;
  }
  if (!TotalExecCount)
    return {-1, TotalMispredictionCount};
  return {100.0f * TotalMispredictionCount / TotalExecCount,
          TotalMispredictionCount};
}

// Returns conditional succ bias if the profile is available, -1 otherwise.
int calculateConditionBias(const BinaryBasicBlock &BB,
                           const BinaryBasicBlock &ConditionalSucc) {
  if (auto BranchStats = BB.getBranchStats(&ConditionalSucc))
    return BranchStats->first;
  return -1;
}

void CMOVConversion::Stats::dumpTo(raw_ostream &OS) {
  OS << "converted static " << StaticPerformed << "/" << StaticPossible
     << formatv(" ({0:P}) ", getStaticRatio())
     << "hammock(s) into CMOV sequences, with dynamic execution count "
     << DynamicPerformed << "/" << DynamicPossible
     << formatv(" ({0:P}), ", getDynamicRatio()) << "saving " << RemovedMP
     << "/" << PossibleMP << formatv(" ({0:P}) ", getMPRatio())
     << "mispredictions\n";
}

void CMOVConversion::runOnFunction(BinaryFunction &Function) {
  BinaryContext &BC = Function.getBinaryContext();
  bool Modified = false;
  // Function-local stats
  Stats Local;
  // Traverse blocks in RPO, merging block with a converted cmov with its
  // successor.
  for (BinaryBasicBlock *BB : post_order(&Function)) {
    uint64_t BBExecCount = BB->getKnownExecutionCount();
    if (BB->empty() ||          // The block must have instructions
        BBExecCount == 0 ||     // must be hot
        BB->succ_size() != 2 || // with two successors
        BB->hasJumpTable())     // no jump table
      continue;

    assert(BB->isValid() && "traversal internal error");

    // Check branch instruction
    auto BranchInstrIter = BB->getLastNonPseudo();
    if (BranchInstrIter == BB->rend() ||
        !BC.MIB->isConditionalBranch(*BranchInstrIter))
      continue;

    // Check successors
    BinaryBasicBlock *ConditionalSucc, *UnconditionalSucc;
    bool IsConditionalTaken;
    if (!matchCFGSubgraph(*BB, ConditionalSucc, UnconditionalSucc,
                          IsConditionalTaken)) {
      LLVM_DEBUG(dbgs() << BB->getName() << ": couldn't match hammock\n");
      continue;
    }

    unsigned CC = BC.MIB->getCondCode(*BranchInstrIter);
    if (!IsConditionalTaken)
      CC = BC.MIB->getInvertedCondCode(CC);
    // Check contents of the conditional block
    if (!canConvertInstructions(BC, *ConditionalSucc, CC))
      continue;

    int ConditionBias = calculateConditionBias(*BB, *ConditionalSucc);
    int MispredictionRate = 0;
    uint64_t MispredictionCount = 0;
    std::tie(MispredictionRate, MispredictionCount) =
        calculateMispredictionRate(*BB);

    Local.StaticPossible++;
    Local.DynamicPossible += BBExecCount;
    Local.PossibleMP += MispredictionCount;

    // If the conditional successor is never executed, don't convert it
    if (ConditionBias < opts::BiasThreshold) {
      LLVM_DEBUG(dbgs() << BB->getName() << "->" << ConditionalSucc->getName()
                        << " bias = " << ConditionBias
                        << ", less than threshold " << opts::BiasThreshold
                        << '\n');
      continue;
    }

    // Check the misprediction rate of a branch
    if (MispredictionRate < opts::MispredictionThreshold) {
      LLVM_DEBUG(dbgs() << BB->getName() << " misprediction rate = "
                        << MispredictionRate << ", less than threshold "
                        << opts::MispredictionThreshold << '\n');
      continue;
    }

    // remove conditional branch
    BB->eraseInstruction(std::prev(BranchInstrIter.base()));
    BB->removeAllSuccessors();
    // Convert instructions from the conditional successor into cmov's in BB.
    convertMoves(BC, *ConditionalSucc, CC);
    BB->addInstructions(ConditionalSucc->begin(), ConditionalSucc->end());
    ConditionalSucc->markValid(false);

    // RPO traversal guarantees that the successor is visited and merged if
    // necessary. Merge the unconditional successor into the current block.
    BB->addInstructions(UnconditionalSucc->begin(), UnconditionalSucc->end());
    UnconditionalSucc->moveAllSuccessorsTo(BB);
    UnconditionalSucc->markValid(false);
    Local.StaticPerformed++;
    Local.DynamicPerformed += BBExecCount;
    Local.RemovedMP += MispredictionCount;
    Modified = true;
  }
  if (Modified)
    Function.eraseInvalidBBs();
  if (opts::Verbosity > 1) {
    BC.outs() << "BOLT-INFO: CMOVConversion: " << Function << ", ";
    Local.dumpTo(BC.outs());
  }
  Global = Global + Local;
}

Error CMOVConversion::runOnFunctions(BinaryContext &BC) {
  for (auto &It : BC.getBinaryFunctions()) {
    BinaryFunction &Function = It.second;
    if (!shouldOptimize(Function))
      continue;
    runOnFunction(Function);
  }

  BC.outs() << "BOLT-INFO: CMOVConversion total: ";
  Global.dumpTo(BC.outs());
  return Error::success();
}

} // end namespace bolt
} // end namespace llvm
