//===--- Condition.cpp - Implements the SILGen Condition class ------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#include "Condition.h"
#include "Initialization.h"
#include "ManagedValue.h"
#include "RValue.h"
#include "swift/SIL/SILArgument.h"
#include "swift/SIL/SILFunction.h"
using namespace swift;
using namespace Lowering;

void Condition::enterTrue(SILGenFunction &SGF) {
  assert(TrueBB && "Cannot call enterTrue without a True block!");
  
  // TrueBB has already been inserted somewhere unless there's a
  // continuation block.
  if (!ContBB) return;
  
  SGF.B.emitBlock(TrueBB);
}

/// Extract the last SILLocation used in BB.
static SILLocation getContinuationLoc(SILBasicBlock &BB, SILLocation Fallback) {
  for (auto I = BB.rbegin(); I != BB.rend(); ++I)
    if (auto L = I->getLoc())
      return L;
  return Fallback;
}
void Condition::exitTrue(SILGenFunction &SGF, ArrayRef<SILValue> Args) {
  // If there's no continuation block, it's because the condition was
  // folded to true.  In that case, we just continue emitting code as
  // if we were still in the true case, and we're unreachable iff the
  // end of the true case is unreachable.  In other words, there's
  // nothing to do.
  if (!ContBB) {
    assert(!FalseBB && "no continuation");
    return;
  }
  
  // If there is a continuation block, we should branch to it if the
  // current point is reachable.
  if (!SGF.B.hasValidInsertionPoint()) {
    // If there is no false code, the continuation block has a use
    // because the main condition jumps directly to it.
    assert(ContBB->pred_empty() || !FalseBB);
    return;
  }
  
  // Otherwise, resume into the continuation block.  This branch might
  // be folded by exitFalse if it turns out that that point is
  // unreachable.
  SGF.B.createBranch(getContinuationLoc(*SGF.B.getInsertionBB(), Loc),
                     ContBB, Args);
  
  // Coming out of exitTrue, we can be in one of three states:
  //   - a valid non-terminal IP, but only if there is no continuation
  //     block, which is only possible if there is no false block;
  //   - a valid terminal IP, if the end of the true block was reachable; or
  //   - a cleared IP, if the end of the true block was not reachable.
}

void Condition::enterFalse(SILGenFunction &SGF) {
  assert(FalseBB && "entering the false branch when it was not valid");
  
  // FalseBB has already been inserted somewhere unless there's a
  // continuation block.
  if (!ContBB) return;
  
  // It's possible to have no insertion point here if the end of the
  // true case was unreachable.
  SGF.B.emitBlock(FalseBB);
}

void Condition::exitFalse(SILGenFunction &SGF, ArrayRef<SILValue> Args) {
  // If there's no continuation block, it's because the condition was
  // folded to false.  In that case, we just continue emitting code as
  // if we were still in the false case, and we're unreachable iff the
  // end of the false case is unreachable.  In other words, there's
  // nothing to do.
  if (!ContBB) return;
  
  if (ContBB->pred_empty()) {
    // If the true case didn't need the continuation block, then
    // we don't either, regardless of whether the current location
    // is reachable.  Just keep inserting / being unreachable
    // right where we are.
  } else if (!SGF.B.hasValidInsertionPoint()) {
    // If the true case did need the continuation block, but the false
    // case doesn't, just merge the continuation block back into its
    // single predecessor and move the IP there.
    //
    // Note that doing this tends to strand the false code after
    // everything else in the function, so maybe it's not a great idea.
    auto PI = ContBB->pred_begin();
    SILBasicBlock *ContPred = *PI;

    // Verify there was only a single predecessor to ContBB.
    ++PI;
    assert(PI == ContBB->pred_end() && "Only expect one branch to the ContBB");
    
    // Insert before the uncond branch and zap it.
    auto *Br = cast<BranchInst>(ContPred->getTerminator());
    SGF.B.setInsertionPoint(Br->getParent());

    Br->eraseFromParent();
    assert(ContBB->pred_empty() &&
           "Zapping the branch should make ContBB dead");
  } else {
    // Otherwise, branch to the continuation block and start inserting there.
    SGF.B.createBranch(getContinuationLoc(*SGF.B.getInsertionBB(), Loc),
                       ContBB, Args);
  }
}

SILBasicBlock *Condition::complete(SILGenFunction &SGF) {
  // If there is no continuation block, it's because we
  // constant-folded the branch.  The case-exit will have left us in a
  // normal insertion state (i.e. not a post-terminator IP) with
  // nothing to clean up after.
  if (!ContBB) {
    return SGF.B.getInsertionBB();
  }
  
  // Kill the continuation block if it's not being used.  Case-exits
  // only leave themselves post-terminator if they use the
  // continuation block, so we're in an acceptable insertion state.
  if (ContBB->pred_empty() && ContBB->args_empty()) {
    SGF.eraseBasicBlock(ContBB);
    return SGF.B.hasValidInsertionPoint() ? SGF.B.getInsertionBB() : nullptr;
  }
  
  // Okay, we need to insert the continuation block.
  SGF.B.emitBlock(ContBB);
  return ContBB;
}

ConditionalValue::ConditionalValue(SILGenFunction &SGF, SGFContext C,
                                   SILLocation loc,
                                   const TypeLowering &valueTL)
  : SGF(SGF), tl(valueTL), contBB(SGF.createBasicBlock()), loc(loc)
{
  if (tl.isAddressOnly()) {
    // If the result type is address-only, get a result buffer for it.
    result = SGF.getBufferForExprResult(loc, tl.getLoweredType(), C);
  } else {
    // Otherwise, add a BB arg to the continuation block to receive loadable
    // result.
    result = contBB->createPHIArgument(tl.getLoweredType(),
                                       ValueOwnershipKind::Owned);
  }
}

SGFContext ConditionalValue::enterBranch(SILBasicBlock *bb) {
  if (bb) {
    assert(!SGF.B.hasValidInsertionPoint() && "already in a branch");
    SGF.B.emitBlock(bb);
  }
  
  assert(!scope.hasValue() && "already have a scope");
  // Start a scope for the current branch.
  scope.emplace(SGF.Cleanups, CleanupLocation::get(loc));

  // Code emitted in the branch can emit into our buffer for address-only
  // conditionals.
  if (tl.isAddressOnly()) {
    assert(!currentInitialization && "already have an initialization?!");
    currentInitialization = SGF.useBufferAsTemporary(result, tl);
    return SGFContext(currentInitialization.get());
  }

  /// TODO: We might be able to coordinate AllowPlusZero across conditionals
  /// if all branches of the conditional can actually produce a +0 result.
  return SGFContext();
}

void ConditionalValue::exitBranch(RValue &&condResult) {
  assert(scope.hasValue() && "no current scope?!");
  if (tl.isAddressOnly()) {
    // Transfer the result into our buffer if it wasn't emitted in-place
    // already.
    assert(currentInitialization && "no current initialization?!");
    std::move(condResult).forwardInto(SGF, loc,
                                      currentInitialization.release());
    scope.reset();
    SGF.B.createBranch(loc, contBB);
  } else {
    SILValue resultVal = std::move(condResult).forwardAsSingleValue(SGF, loc);
    // Branch with the result as a BB argument.
    scope.reset();
    SGF.B.createBranch(loc, contBB, resultVal);
  }
}

ManagedValue ConditionalValue::complete() {
  assert(!SGF.B.hasValidInsertionPoint() && "still in a branch");
  assert(!scope && "still in a branch scope");
  assert(!currentInitialization && "still in a branch initialization");
  SGF.B.emitBlock(contBB);
  return SGF.emitManagedRValueWithCleanup(result);
}
