//===--- Utils.cpp - Utility functions for the code generation --*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains utility functions for the code generation.
//
//===----------------------------------------------------------------------===//

#include "polly/CodeGen/Utils.h"
#include "polly/CodeGen/IRBuilder.h"
#include "polly/ScopInfo.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Support/Debug.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"

using namespace llvm;

BasicBlock *polly::executeScopConditionally(Scop &S, Pass *P, Value *RTC) {
  BasicBlock *StartBlock, *SplitBlock, *NewBlock;
  Region &R = S.getRegion();
  PollyIRBuilder Builder(R.getEntry());
  DominatorTree &DT = P->getAnalysis<DominatorTreeWrapperPass>().getDomTree();
  RegionInfo &RI = P->getAnalysis<RegionInfoPass>().getRegionInfo();
  LoopInfo &LI = P->getAnalysis<LoopInfo>();

  // Split the entry edge of the region and generate a new basic block on this
  // edge. This function also updates ScopInfo and RegionInfo.
  NewBlock = SplitEdge(R.getEnteringBlock(), R.getEntry(), P);
  if (DT.dominates(R.getEntry(), NewBlock)) {
    BasicBlock *OldBlock = R.getEntry();
    std::string OldName = OldBlock->getName();

    // Update ScopInfo.
    for (ScopStmt *Stmt : S)
      if (Stmt->getBasicBlock() == OldBlock) {
        Stmt->setBasicBlock(NewBlock);
        break;
      }

    // Update RegionInfo.
    SplitBlock = OldBlock;
    OldBlock->setName("polly.split");
    NewBlock->setName(OldName);
    R.replaceEntryRecursive(NewBlock);
    RI.setRegionFor(NewBlock, &R);
  } else {
    RI.setRegionFor(NewBlock, R.getParent());
    SplitBlock = NewBlock;
  }

  SplitBlock->setName("polly.split_new_and_old");
  Function *F = SplitBlock->getParent();
  StartBlock = BasicBlock::Create(F->getContext(), "polly.start", F);
  SplitBlock->getTerminator()->eraseFromParent();
  Builder.SetInsertPoint(SplitBlock);
  Builder.CreateCondBr(RTC, StartBlock, R.getEntry());
  if (Loop *L = LI.getLoopFor(SplitBlock))
    L->addBasicBlockToLoop(StartBlock, LI.getBase());
  DT.addNewBlock(StartBlock, SplitBlock);
  Builder.SetInsertPoint(StartBlock);

  BasicBlock *MergeBlock;

  if (R.getExit()->getSinglePredecessor())
    // No splitEdge required.  A block with a single predecessor cannot have
    // PHI nodes that would complicate life.
    MergeBlock = R.getExit();
  else {
    MergeBlock = SplitEdge(R.getExitingBlock(), R.getExit(), P);
    // SplitEdge will never split R.getExit(), as R.getExit() has more than
    // one predecessor. Hence, mergeBlock is always a newly generated block.
    R.replaceExitRecursive(MergeBlock);
    RI.setRegionFor(MergeBlock, &R);
  }

  Builder.CreateBr(MergeBlock);
  MergeBlock->setName("polly.merge_new_and_old");

  if (DT.dominates(SplitBlock, MergeBlock))
    DT.changeImmediateDominator(MergeBlock, SplitBlock);
  return StartBlock;
}
