//===--- SemanticARCOpts.cpp ----------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "sil-semantic-arc-opts"
#include "swift/SIL/OwnershipChecker.h"
#include "swift/SIL/SILArgument.h"
#include "swift/SIL/SILInstruction.h"
#include "swift/SIL/TransitivelyUnreachableBlocks.h"
#include "swift/SILOptimizer/Analysis/PostOrderAnalysis.h"
#include "swift/SILOptimizer/PassManager/Passes.h"
#include "swift/SILOptimizer/PassManager/Transforms.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"

using namespace swift;

STATISTIC(NumEliminatedInsts, "number of removed instructions");

static bool optimizeGuaranteedArgument(SILArgument *Arg,
                                       OwnershipChecker &Checker) {
  bool MadeChange = false;

  // Gather all copy_value users of Arg.
  llvm::SmallVector<CopyValueInst *, 4> Worklist;
  for (auto *Op : Arg->getUses()) {
    if (auto *CVI = dyn_cast<CopyValueInst>(Op->getUser())) {
      Worklist.push_back(CVI);
    }
  }

  // Then until we run out of copies...
  while (!Worklist.empty()) {
    auto *CVI = Worklist.pop_back_val();

    // Quickly see if copy has only one use and that use is a destroy_value. In
    // such a case, we can always eliminate both the copy and the destroy.
    if (auto *Op = CVI->getSingleUse()) {
      if (auto *DVI = dyn_cast<DestroyValueInst>(Op->getUser())) {
        DVI->eraseFromParent();
        CVI->eraseFromParent();
        NumEliminatedInsts += 2;
        continue;
      }
    }

    // Ok, now run the checker on the copy value. If it fails, then we just
    // continue.
    if (!Checker.checkValue(CVI))
      continue;

    // Otherwise, lets do a quick check on what the checker thinks the lifetime
    // ending and non-lifetime ending users. To be conservative, we bail unless
    // each lifetime ending use is a destroy_value and if each non-lifetime
    // ending use is one of the following instructions:
    //
    // 1. copy_value.
    // 2. begin_borrow.
    // 3. end_borrow.
    if (!all_of(Checker.LifetimeEndingUsers, [](SILInstruction *I) -> bool {
          return isa<DestroyValueInst>(I);
        }))
      continue;

    // Extra copy values that we should visit recursively.
    llvm::SmallVector<CopyValueInst *, 8> NewCopyInsts;
    llvm::SmallVector<SILInstruction *, 8> NewBorrowInsts;
    if (!all_of(Checker.RegularUsers, [&](SILInstruction *I) -> bool {
          if (auto *CVI = dyn_cast<CopyValueInst>(I)) {
            NewCopyInsts.push_back(CVI);
            return true;
          }

          if (!isa<BeginBorrowInst>(I) && !isa<EndBorrowInst>(I))
            return false;

          NewBorrowInsts.push_back(I);
          return true;
        }))
      continue;

    // Ok! we can remove the copy_value, destroy_values!
    MadeChange = true;
    CVI->replaceAllUsesWith(CVI->getOperand());
    CVI->eraseFromParent();
    ++NumEliminatedInsts;

    while (!Checker.LifetimeEndingUsers.empty()) {
      Checker.LifetimeEndingUsers.pop_back_val()->eraseFromParent();
      ++NumEliminatedInsts;
    }

    // Then add the copy_values that were users of our original copy value to
    // the worklist.
    while (!NewCopyInsts.empty()) {
      Worklist.push_back(NewCopyInsts.pop_back_val());
    }

    // Then remove any begin/end borrow that we found. These are unneeded since
    // the lifetime guarantee from the argument exists above and beyond said
    // scope.
    while (!NewBorrowInsts.empty()) {
      SILInstruction *I = NewBorrowInsts.pop_back_val();
      if (auto *BBI = dyn_cast<BeginBorrowInst>(I)) {
        // Any copy_value that is used by the begin borrow is added to the
        // worklist.
        for (auto *BBIUse : BBI->getUses()) {
          if (auto *BBIUseCopyValue =
                  dyn_cast<CopyValueInst>(BBIUse->getUser())) {
            Worklist.push_back(BBIUseCopyValue);
          }
        }
        BBI->replaceAllUsesWith(BBI->getOperand());
        BBI->eraseFromParent();
        ++NumEliminatedInsts;
        continue;
      }

      // This is not necessary, but it does add a check.
      auto *EBI = cast<EndBorrowInst>(I);
      EBI->eraseFromParent();
      ++NumEliminatedInsts;
    }
  }

  return MadeChange;
}

//===----------------------------------------------------------------------===//
//                            Top Level Entrypoint
//===----------------------------------------------------------------------===//

namespace {

struct SemanticARCOpts : SILFunctionTransform {
  void run() override {
    bool MadeChange = false;
    SILFunction *F = getFunction();

    auto *PO = PM->getAnalysis<PostOrderAnalysis>()->get(F);
    TransitivelyUnreachableBlocksInfo TUB(*PO);
    OwnershipChecker Checker{F->getModule(), TUB, {}, {}, {}};

    // First as a special case, handle guaranteed SIL function arguments.
    //
    // The reason that this is special is that we do not need to consider the
    // end of the borrow scope since the end of the function is the end of the
    // borrow scope.
    for (auto *Arg : F->getArguments()) {
      if (Arg->getOwnershipKind() != ValueOwnershipKind::Guaranteed)
        continue;
      MadeChange |= optimizeGuaranteedArgument(Arg, Checker);
    }

    if (MadeChange) {
      invalidateAnalysis(SILAnalysis::InvalidationKind::Instructions);
    }
  }

  StringRef getName() override { return "Semantic ARC Opts"; }
};

} // end anonymous namespace

SILTransform *swift::createSemanticARCOpts() { return new SemanticARCOpts(); }
