//===------ PollyIRBuilder.cpp --------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// The Polly IRBuilder file contains Polly specific extensions for the IRBuilder
// that are used e.g. to emit the llvm.loop.parallel metadata.
//
//===----------------------------------------------------------------------===//

#include "polly/CodeGen/IRBuilder.h"
#include "polly/ScopInfo.h"
#include "polly/Support/ScopHelper.h"
#include "llvm/IR/Metadata.h"
#include "llvm/Support/Debug.h"

using namespace llvm;
using namespace polly;

/// @brief Get a self referencing id metadata node.
///
/// The MDNode looks like this (if arg0/arg1 are not null):
///
///    '!n = metadata !{metadata !n, arg0, arg1}'
///
/// @return The self referencing id metadata node.
static MDNode *getID(LLVMContext &Ctx, Metadata *arg0 = nullptr,
                     Metadata *arg1 = nullptr) {
  MDNode *ID;
  SmallVector<Metadata *, 3> Args;
  // Use a temporary node to safely create a unique pointer for the first arg.
  auto TempNode = MDNode::getTemporary(Ctx, None);
  // Reserve operand 0 for loop id self reference.
  Args.push_back(TempNode.get());

  if (arg0)
    Args.push_back(arg0);
  if (arg1)
    Args.push_back(arg1);

  ID = MDNode::get(Ctx, Args);
  ID->replaceOperandWith(0, ID);
  return ID;
}

ScopAnnotator::ScopAnnotator() : SE(nullptr), AliasScopeDomain(nullptr) {}

void ScopAnnotator::buildAliasScopes(Scop &S) {
  SE = S.getSE();

  LLVMContext &Ctx = SE->getContext();
  AliasScopeDomain = getID(Ctx, MDString::get(Ctx, "polly.alias.scope.domain"));

  AliasScopeMap.clear();
  OtherAliasScopeListMap.clear();

  SetVector<Value *> BasePtrs;
  for (ScopStmt &Stmt : S)
    for (MemoryAccess *MA : Stmt)
      BasePtrs.insert(MA->getBaseAddr());

  std::string AliasScopeStr = "polly.alias.scope.";
  for (Value *BasePtr : BasePtrs)
    AliasScopeMap[BasePtr] = getID(
        Ctx, AliasScopeDomain,
        MDString::get(Ctx, (AliasScopeStr + BasePtr->getName()).str().c_str()));

  for (Value *BasePtr : BasePtrs) {
    MDNode *AliasScopeList = MDNode::get(Ctx, {});
    for (const auto &AliasScopePair : AliasScopeMap) {
      if (BasePtr == AliasScopePair.first)
        continue;

      Metadata *Args = {AliasScopePair.second};
      AliasScopeList =
          MDNode::concatenate(AliasScopeList, MDNode::get(Ctx, Args));
    }

    OtherAliasScopeListMap[BasePtr] = AliasScopeList;
  }
}

void ScopAnnotator::pushLoop(Loop *L, bool IsParallel) {

  ActiveLoops.push_back(L);
  if (!IsParallel)
    return;

  BasicBlock *Header = L->getHeader();
  MDNode *Id = getID(Header->getContext());
  assert(Id->getOperand(0) == Id && "Expected Id to be a self-reference");
  assert(Id->getNumOperands() == 1 && "Unexpected extra operands in Id");
  MDNode *Ids = ParallelLoops.empty()
                    ? Id
                    : MDNode::concatenate(ParallelLoops.back(), Id);
  ParallelLoops.push_back(Ids);
}

void ScopAnnotator::popLoop(bool IsParallel) {
  ActiveLoops.pop_back();
  if (!IsParallel)
    return;

  assert(!ParallelLoops.empty() && "Expected a parallel loop to pop");
  ParallelLoops.pop_back();
}

void ScopAnnotator::annotateLoopLatch(BranchInst *B, Loop *L,
                                      bool IsParallel) const {
  if (!IsParallel)
    return;

  assert(!ParallelLoops.empty() && "Expected a parallel loop to annotate");
  MDNode *Ids = ParallelLoops.back();
  MDNode *Id = cast<MDNode>(Ids->getOperand(Ids->getNumOperands() - 1));
  B->setMetadata("llvm.loop", Id);
}

void ScopAnnotator::annotate(Instruction *Inst) {
  if (!Inst->mayReadOrWriteMemory())
    return;

  // TODO: Use the ScopArrayInfo once available here.
  if (AliasScopeDomain) {
    Value *BasePtr = nullptr;
    if (isa<StoreInst>(Inst) || isa<LoadInst>(Inst)) {
      const SCEV *PtrSCEV = SE->getSCEV(getPointerOperand(*Inst));
      const SCEV *BaseSCEV = SE->getPointerBase(PtrSCEV);
      if (const SCEVUnknown *SU = dyn_cast<SCEVUnknown>(BaseSCEV))
        BasePtr = SU->getValue();
    }

    if (BasePtr) {
      Inst->setMetadata("alias.scope", AliasScopeMap[BasePtr]);
      Inst->setMetadata("noalias", OtherAliasScopeListMap[BasePtr]);
    }
  }

  if (ParallelLoops.empty())
    return;

  Inst->setMetadata("llvm.mem.parallel_loop_access", ParallelLoops.back());
}
