//===--- 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/Analysis/RegionInfo.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<LoopInfoWrapperPass>().getLoopInfo();

  // 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(), &DT, &LI);
  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);
  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(), &DT, &LI);
    // 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;
}
