//===- OrderedBasicBlock.cpp --------------------------------- -*- C++ -*-===//
//
// 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 OrderedBasicBlock class. OrderedBasicBlock
// maintains an interface where clients can query if one instruction comes
// before another in a BasicBlock. Since BasicBlock currently lacks a reliable
// way to query relative position between instructions one can use
// OrderedBasicBlock to do such queries. OrderedBasicBlock is lazily built on a
// source BasicBlock and maintains an internal Instruction -> Position map. A
// OrderedBasicBlock instance should be discarded whenever the source
// BasicBlock changes.
//
// It's currently used by the CaptureTracker in order to find relative
// positions of a pair of instructions inside a BasicBlock.
//
//===----------------------------------------------------------------------===//

#include "llvm/Analysis/OrderedBasicBlock.h"
#include "llvm/IR/Instruction.h"
using namespace llvm;

OrderedBasicBlock::OrderedBasicBlock(const BasicBlock *BasicB)
    : NextInstPos(0), BB(BasicB) {
  LastInstFound = BB->end();
}

/// Given no cached results, find if \p A comes before \p B in \p BB.
/// Cache and number out instruction while walking \p BB.
bool OrderedBasicBlock::comesBefore(const Instruction *A,
                                    const Instruction *B) {
  const Instruction *Inst = nullptr;
  assert(!(LastInstFound == BB->end() && NextInstPos != 0) &&
         "Instruction supposed to be in NumberedInsts");
  assert(A->getParent() == BB && "Instruction supposed to be in the block!");
  assert(B->getParent() == BB && "Instruction supposed to be in the block!");

  // Start the search with the instruction found in the last lookup round.
  auto II = BB->begin();
  auto IE = BB->end();
  if (LastInstFound != IE)
    II = std::next(LastInstFound);

  // Number all instructions up to the point where we find 'A' or 'B'.
  for (; II != IE; ++II) {
    Inst = cast<Instruction>(II);
    NumberedInsts[Inst] = NextInstPos++;
    if (Inst == A || Inst == B)
      break;
  }

  assert(II != IE && "Instruction not found?");
  assert((Inst == A || Inst == B) && "Should find A or B");
  LastInstFound = II;
  return Inst != B;
}

/// Find out whether \p A dominates \p B, meaning whether \p A
/// comes before \p B in \p BB. This is a simplification that considers
/// cached instruction positions and ignores other basic blocks, being
/// only relevant to compare relative instructions positions inside \p BB.
bool OrderedBasicBlock::dominates(const Instruction *A, const Instruction *B) {
  assert(A->getParent() == B->getParent() &&
         "Instructions must be in the same basic block!");
  assert(A->getParent() == BB && "Instructions must be in the tracked block!");

  // First we lookup the instructions. If they don't exist, lookup will give us
  // back ::end(). If they both exist, we compare the numbers. Otherwise, if NA
  // exists and NB doesn't, it means NA must come before NB because we would
  // have numbered NB as well if it didn't. The same is true for NB. If it
  // exists, but NA does not, NA must come after it. If neither exist, we need
  // to number the block and cache the results (by calling comesBefore).
  auto NAI = NumberedInsts.find(A);
  auto NBI = NumberedInsts.find(B);
  if (NAI != NumberedInsts.end() && NBI != NumberedInsts.end())
    return NAI->second < NBI->second;
  if (NAI != NumberedInsts.end())
    return true;
  if (NBI != NumberedInsts.end())
    return false;

  return comesBefore(A, B);
}

void OrderedBasicBlock::eraseInstruction(const Instruction *I) {
  if (LastInstFound != BB->end() && I == &*LastInstFound) {
    if (LastInstFound == BB->begin()) {
      LastInstFound = BB->end();
      NextInstPos = 0;
    } else
      LastInstFound--;
  }

  NumberedInsts.erase(I);
}

void OrderedBasicBlock::replaceInstruction(const Instruction *Old,
                                           const Instruction *New) {
  auto OI = NumberedInsts.find(Old);
  if (OI == NumberedInsts.end())
    return;

  NumberedInsts.insert({New, OI->second});
  if (LastInstFound != BB->end() && Old == &*LastInstFound)
    LastInstFound = New->getIterator();
  NumberedInsts.erase(Old);
}
