//===- MemoryModelRelaxationAnnotations.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
//
//===----------------------------------------------------------------------===//

#include "llvm/IR/MemoryModelRelaxationAnnotations.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Metadata.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"

using namespace llvm;

//===- MMRAMetadata -------------------------------------------------------===//

MMRAMetadata::MMRAMetadata(const Instruction &I)
    : MMRAMetadata(I.getMetadata(LLVMContext::MD_mmra)) {}

MMRAMetadata::MMRAMetadata(MDNode *MD) {
  if (!MD)
    return;

  // TODO: Split this into a "tryParse" function that can return an err.
  // CTor can use the tryParse & just fatal on err.

  MDTuple *Tuple = dyn_cast<MDTuple>(MD);
  assert(Tuple && "Invalid MMRA structure");

  const auto HandleTagMD = [this](MDNode *TagMD) {
    Tags.insert({cast<MDString>(TagMD->getOperand(0))->getString(),
                 cast<MDString>(TagMD->getOperand(1))->getString()});
  };

  if (isTagMD(Tuple)) {
    HandleTagMD(Tuple);
    return;
  }

  for (const MDOperand &Op : Tuple->operands()) {
    MDNode *MDOp = cast<MDNode>(Op.get());
    assert(isTagMD(MDOp));
    HandleTagMD(MDOp);
  }
}

bool MMRAMetadata::isTagMD(const Metadata *MD) {
  if (auto *Tuple = dyn_cast<MDTuple>(MD)) {
    return Tuple->getNumOperands() == 2 &&
           isa<MDString>(Tuple->getOperand(0)) &&
           isa<MDString>(Tuple->getOperand(1));
  }
  return false;
}

MDTuple *MMRAMetadata::getTagMD(LLVMContext &Ctx, StringRef Prefix,
                                StringRef Suffix) {
  return MDTuple::get(Ctx,
                      {MDString::get(Ctx, Prefix), MDString::get(Ctx, Suffix)});
}

MDTuple *MMRAMetadata::getMD(LLVMContext &Ctx,
                             ArrayRef<MMRAMetadata::TagT> Tags) {
  if (Tags.empty())
    return nullptr;

  if (Tags.size() == 1)
    return getTagMD(Ctx, Tags.front());

  SmallVector<Metadata *> MMRAs;
  for (const auto &Tag : Tags)
    MMRAs.push_back(getTagMD(Ctx, Tag));
  return MDTuple::get(Ctx, MMRAs);
}

MDNode *MMRAMetadata::combine(LLVMContext &Ctx, const MMRAMetadata &A,
                              const MMRAMetadata &B) {
  // Let A and B be two tags set, and U be the prefix-wise union of A and B.
  // For every unique tag prefix P present in A or B:
  // * If either A or B has no tags with prefix P, no tags with prefix
  //   P are added to U.
  // * If both A and B have at least one tag with prefix P, all tags with prefix
  //   P from both sets are added to U.

  SmallVector<Metadata *> Result;

  for (const auto &[P, S] : A) {
    if (B.hasTagWithPrefix(P))
      Result.push_back(getTagMD(Ctx, P, S));
  }
  for (const auto &[P, S] : B) {
    if (A.hasTagWithPrefix(P))
      Result.push_back(getTagMD(Ctx, P, S));
  }

  return MDTuple::get(Ctx, Result);
}

bool MMRAMetadata::hasTag(StringRef Prefix, StringRef Suffix) const {
  return Tags.count({Prefix, Suffix});
}

bool MMRAMetadata::isCompatibleWith(const MMRAMetadata &Other) const {
  // Two sets of tags are compatible iff, for every unique tag prefix P
  // present in at least one set:
  //   - the other set contains no tag with prefix P, or
  //   - at least one tag with prefix P is common to both sets.

  StringMap<bool> PrefixStatuses;
  for (const auto &[P, S] : Tags)
    PrefixStatuses[P] |= (Other.hasTag(P, S) || !Other.hasTagWithPrefix(P));
  for (const auto &[P, S] : Other)
    PrefixStatuses[P] |= (hasTag(P, S) || !hasTagWithPrefix(P));

  for (auto &[Prefix, Status] : PrefixStatuses) {
    if (!Status)
      return false;
  }

  return true;
}

bool MMRAMetadata::hasTagWithPrefix(StringRef Prefix) const {
  for (const auto &[P, S] : Tags)
    if (P == Prefix)
      return true;
  return false;
}

MMRAMetadata::const_iterator MMRAMetadata::begin() const {
  return Tags.begin();
}

MMRAMetadata::const_iterator MMRAMetadata::end() const { return Tags.end(); }

bool MMRAMetadata::empty() const { return Tags.empty(); }

unsigned MMRAMetadata::size() const { return Tags.size(); }

void MMRAMetadata::print(raw_ostream &OS) const {
  bool IsFirst = true;
  // TODO: use map_iter + join
  for (const auto &[P, S] : Tags) {
    if (IsFirst)
      IsFirst = false;
    else
      OS << ", ";
    OS << P << ":" << S;
  }
}

LLVM_DUMP_METHOD
void MMRAMetadata::dump() const { print(dbgs()); }

//===- Helpers ------------------------------------------------------------===//

static bool isReadWriteMemCall(const Instruction &I) {
  if (const auto *C = dyn_cast<CallBase>(&I))
    return C->mayReadOrWriteMemory() ||
           !C->getMemoryEffects().doesNotAccessMemory();
  return false;
}

bool llvm::canInstructionHaveMMRAs(const Instruction &I) {
  return isa<LoadInst>(I) || isa<StoreInst>(I) || isa<AtomicCmpXchgInst>(I) ||
         isa<AtomicRMWInst>(I) || isa<FenceInst>(I) || isReadWriteMemCall(I);
}
