//===--- ArgumentExplosionTransform.cpp -----------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2018 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
//
//===----------------------------------------------------------------------===//
///
/// \file
///
/// This file contains an implementation of the partial dead argument
/// elimination optimization. We do this to attempt to remove non-trivial
/// arguments of callees to eliminate lifetime constraints of a large argument
/// on values in the caller.
///
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "fso-argument-explosion-transform"
#include "FunctionSignatureOpts.h"
#include "llvm/Support/CommandLine.h"

using namespace swift;

static llvm::cl::opt<bool> FSODisableArgExplosion(
    "sil-fso-disable-arg-explosion",
    llvm::cl::desc("Do not perform argument explosion during FSO. Intended "
                   "only for testing purposes"));

//===----------------------------------------------------------------------===//
//                                  Utility
//===----------------------------------------------------------------------===//

/// Whether the known-to-date upper bound on the live leaf count is high enough
/// so that argument explosion is possible.
static bool
mayExplodeGivenLiveLeafCountUpperBound(unsigned knownLiveLeafCountUpperBound) {
  return knownLiveLeafCountUpperBound > 0;
}

static unsigned maxExplosionSizeWhenSpecializationWillIntroduceThunk(
    bool willSpecializationIntroduceThunk) {
  // 3 is the heuristic max explosion size for a single argument when the
  // specializing the function will introduce a thunk.  If specializing the
  // function may not introduce a thunk, then we rely on the maximum size
  // imposed by shouldExpand.
  return willSpecializationIntroduceThunk ? 3 : UINT_MAX;
}

static bool shouldExplode(unsigned knownLiveLeafCountUpperBound,
                          bool hasKnownDeadLeaves,
                          bool hasKnownDeadNontrivialLeaves,
                          bool willSpecializationIntroduceThunk) {
  unsigned maxExplosionSize =
      maxExplosionSizeWhenSpecializationWillIntroduceThunk(
          /*willSpecializationIntroduceThunk=*/
          willSpecializationIntroduceThunk);
  bool isLiveLeafCountInExplodableRange =
      mayExplodeGivenLiveLeafCountUpperBound(knownLiveLeafCountUpperBound) &&
      (knownLiveLeafCountUpperBound <= maxExplosionSize);
  bool hasKnownDeadRelevantLeaves = willSpecializationIntroduceThunk
                                        ? hasKnownDeadNontrivialLeaves
                                        : hasKnownDeadLeaves;
  return isLiveLeafCountInExplodableRange && hasKnownDeadRelevantLeaves;
}

/// Return true if it's both legal and a good idea to explode this argument.
///
/// Our main interest here is to expose more opportunities for ARC. This means
/// that we are not interested in exploding (and partially DCEing) structs in
/// the following cases:
///
/// 1. Completely dead arguments. This is handled by dead argument elimination.
///
/// 2. Structs with many live leaf nodes. Our heuristic is to explode if there
///    are only 1-3 live leaf nodes for specializations and 1-6 live leaf nodes
///    (in fact, the number specified in shouldExpand). Otherwise again we run
///    into register pressure/spilling issues.
///    TODO: Improve the 1-3 heuristic by having FSO consider the total
///          resultant argument count.  Currently, there is no consideration of
///          that, meaning we could end up with argument exploding even in the
///          case of long argument lists where it isn't beneficial.
///
/// Perform argument exploding if one of the following sets of conditions hold:
///
/// 1. a. The live leaf count is less than or equal to 3.
///    b. There is a dead non-trivial leaf.
/// 2. a. The live leaf count is less than or equal to 6.
///    b. There is a dead trivial leaf.
///    c. Specializing the function will not result in a thunk.
static bool
shouldExplode(FunctionSignatureTransformDescriptor &transformDesc,
              ArgumentDescriptor &argDesc,
              ConsumedArgToEpilogueReleaseMatcher &epilogueReleaseMatcher) {
  // The method is structured as follows:
  //
  // First, do some basic checks and exit early.
  // Then in three steps of increasing complexity, calculate data which could
  // permit the heuristic to decide to explode the argument.  These steps
  // provide information of increasing expense and fidelity.  Checking whether
  // the heuristic allows explosion after each step unnecessary work to be
  // avoided.
  //
  // In a bit more detail:
  //
  // 1) Do some basic checks and exit early, returning false.
  //    - that we can optimize the argument at all
  //    - that the argument has more than a single leaf node
  //    - that the module permits the type to be expanded
  // 2) Gather some basic leaf counts.
  //    - calculate the unmodified (unmodified that is by the results of the
  //      owned-to-guaranteed transformation) live leaf count
  //    - calculate the total list of leaf types to obtain the total leaf count
  // 3) Check whether the heuristic allows the argument to be exploded using
  //    only potentially-trivial leaf counts.  At this point it is certainly not
  //    known that there are dead non-trivial leaves, so exiting early here
  //    is only possible if specializing the function will not result in a
  //    thunk.
  // 4) Gather the counts of non-trivial leaves.
  //    - calculate the count of total non-trivial leaves by filtering the total
  //      list of leaf types from step 2) according to whether leaf is trivial
  //    - calculate an upper bound (upper bound because it doesn't consider the
  //      results of the owned-to-guaranteed transformation) on the count of
  //      live non-trivial leaves
  // 5) Check whether the heuristic allows the argument to be exploded using the
  //    upper bound on live non-trivial leaves.
  // 6) Dial in the upper bounds calculated in steps 2) and 4) by compensating
  //    for the effects of the owned-to-guaranteed transformation.
  // 7) Check whether the heuristic allows the argument to be exploded using the
  //    actual count of live leaves, both trivial and non-trivial.

  // No passes can optimize this argument, so just bail.
  if (!argDesc.canOptimizeLiveArg()) {
    LLVM_DEBUG(llvm::dbgs()
               << "The argument is of a type that cannot be exploded.");
    return false;
  }

  // If the argument is a singleton, it will not be exploded.
  //
  // Explosion makes sense only if some but not all of the leaves are live.
  //
  // Note that ProjectionTree::isSingleton returns true for enums since they are
  // sums and not products and so only have a single top-level node.
  if (argDesc.ProjTree.isSingleton()) {
    LLVM_DEBUG(llvm::dbgs() << "The argument's type is a singleton.");
    return false;
  }

  auto *argument = argDesc.Arg;
  auto &module = argument->getModule();
  auto type = argument->getType().getObjectType();

  // If the global type expansion heuristic does not allow the type to be
  // expanded, it will not be exploded.
  if (!shouldExpand(module, type)) {
    LLVM_DEBUG(llvm::dbgs()
               << "The argument is of a type which should not be expanded.");
    return false;
  }

  bool willSpecializationIntroduceThunk =
      transformDesc.willSpecializationIntroduceThunk();

  unsigned const liveLeafCountUpperBound = argDesc.ProjTree.getLiveLeafCount();

  // If we know already that we may not explode given the upper bound we have
  // established on the live leaf count, exit early.
  //
  // If the argument is completely dead, it will not be exploded.
  //
  // Explosion makes sense only if some but not all of the leaves are live.  The
  // dead argument transformation will try to eliminate the argument.
  if (!mayExplodeGivenLiveLeafCountUpperBound(liveLeafCountUpperBound)) {
    LLVM_DEBUG(llvm::dbgs() << "The argument has no live leaves.");
    return false;
  }

  // To determine whether some but not all of the leaves are used, the total
  // leaf count must be retrieved.
  llvm::SmallVector<SILType, 32> allLeaves;
  argDesc.ProjTree.getAllLeafTypes(allLeaves);
  unsigned const leafCount = allLeaves.size();

  assert(
      liveLeafCountUpperBound <= leafCount &&
      "There should be no more *live* leaves than there are *total* leaves.");

  if (shouldExplode(
          /*knownLifeLeafCount=*/liveLeafCountUpperBound,
          /*hasKnownDeadLeaves=*/liveLeafCountUpperBound < leafCount,
          /*hasKnownDeadNontrivialLeaves=*/false,
          /*willSpecializationIntroduceThunk=*/
          willSpecializationIntroduceThunk)) {
    LLVM_DEBUG(
        llvm::dbgs()
        << "Without considering the liveness of non-trivial leaves, it has "
           "already been determined that there are already fewer ("
        << liveLeafCountUpperBound
        << ") live leaves of the relevant sort (trivial) than total leaves ("
        << leafCount << ") and no more total live leaves ("
        << liveLeafCountUpperBound << ") than the heuristic permits ("
        << maxExplosionSizeWhenSpecializationWillIntroduceThunk(
               /*willSpecializationIntroduceThunk=*/
               willSpecializationIntroduceThunk)
        << ").  Exploding.");
    return true;
  }

  auto *function = argument->getFunction();
  unsigned const nontrivialLeafCount = llvm::count_if(
      allLeaves, [&](SILType type) { return !type.isTrivial(*function); });

  llvm::SmallVector<const ProjectionTreeNode *, 32> liveLeaves;
  argDesc.ProjTree.getLiveLeafNodes(liveLeaves);
  // NOTE: The value obtained here is an upper bound because the
  //       owned-to-guaranteed transformation may eliminate some live
  //       non-trivial leaves, leaving the count lower.
  unsigned const liveNontrivialLeafCountUpperBound =
      llvm::count_if(liveLeaves, [&](const ProjectionTreeNode *leaf) {
        return !leaf->getType().isTrivial(*function);
      });

  assert(liveNontrivialLeafCountUpperBound <= nontrivialLeafCount &&
         "There should be no more *live* non-trivial leaves than there are "
         "*total* non-trivial leaves.");
  assert(nontrivialLeafCount <= leafCount &&
         "There should be no more *non-trivial* leaves than there are *total* "
         "leaves.");

  // If it is known without taking the owned-to-guaranteed transformation into
  // account both that exploding will reduce ARC traffic (because an upper bound
  // for the number of live non-trivial leaves is less than the non-trivial
  // leaf count) and also that the explosion will fit within the heuristic upper
  // bound (because an upper bound for the total live leaf count falls within
  // the limit imposed by the heuristic), then explode now.
  bool shouldExplodeGivenUpperBounds = shouldExplode(
      /*knownLiveLeafCount=*/liveLeafCountUpperBound,
      /*hasKnownDeadLeaves=*/liveLeafCountUpperBound < leafCount,
      /*hasKnownDeadNontrivialLeaves=*/liveNontrivialLeafCountUpperBound <
          nontrivialLeafCount,
      /*willSpecializationIntroduceThunk=*/willSpecializationIntroduceThunk);
  if (shouldExplodeGivenUpperBounds) {
    LLVM_DEBUG(
        llvm::dbgs()
        << "Without considering the expected results of the "
           "owned-to-guaranteed transformation, there are already fewer ("
        << liveNontrivialLeafCountUpperBound
        << ") live non-trivial leaves than total leaves ("
        << nontrivialLeafCount << ") and no more total live leaves ("
        << liveLeafCountUpperBound << ") than the heuristic permits ("
        << maxExplosionSizeWhenSpecializationWillIntroduceThunk(
               /*willSpecializationIntroduceThunk=*/
               willSpecializationIntroduceThunk)
        << ").  Exploding.");
    return true;
  }

  unsigned liveLeafCount = liveLeafCountUpperBound;
  unsigned liveNontrivialLeafCount = liveNontrivialLeafCountUpperBound;

  // The upper bounds that have been established for the live leaf counts are
  // too high to permit us to explode.  That could be because it hasn't been
  // established that any leaves are dead or alternatively that it hasn't been
  // established that there are fewer total live leaves than the limit imposed
  // by the heuristic.  In either case, if some live leaves are eliminated, the
  // number of live leaves may decrease such that exploding will be possible.
  // The results of the owned-to-guaranteed transformation are predicated.  If
  // it is predicted that a leaf will be dead after the owned-to-guaranteed
  // transformation, then the leaf count is decreased.
  //
  // The owned-to-guaranteed will only be applied to the argumehnt if its
  // convention is Direct_Owned.  Additionally, it only applies to non-trivial
  // leaves, which it may kill, so if it is already known that there are no live
  // non-trivial leaves, owned-to-guaranteed will not eliminate anything.
  if (argDesc.hasConvention(SILArgumentConvention::Direct_Owned) &&
      liveNontrivialLeafCountUpperBound > 0) {
    if (auto maybeReleases =
            epilogueReleaseMatcher.getPartiallyPostDomReleaseSet(argument)) {
      auto releases = maybeReleases.getValue();
      llvm::SmallPtrSet<SILInstruction *, 8> users;
      users.insert(std::begin(releases), std::end(releases));

      for (auto *leaf : liveLeaves) {
        if (llvm::all_of(leaf->getNonProjUsers(), [&](Operand *operand) {
              return users.count(operand->getUser());
            })) {
          // Every non-projection user of the leaf is an epilogue release.  The
          // owned-to-guaranteed transformation will eliminate this usage.  With
          // the expectation of that usage being eliminated, stop considering
          // this leaf to be live for the purposes of deciding whether the
          // argument should be exploded.
          --liveLeafCount;
          --liveNontrivialLeafCount;
        }
      }
    }
  }

  return shouldExplode(
      /*knownLifeLeafCount=*/liveLeafCount,
      /*hasKnownDeadLeaves=*/liveLeafCount < leafCount,
      /*hasKnownDeadNontrivialLeaves=*/liveNontrivialLeafCount <
          nontrivialLeafCount,
      /*willSpecializationIntroduceThunk=*/willSpecializationIntroduceThunk);
}

//===----------------------------------------------------------------------===//
//                          Top Level Implementation
//===----------------------------------------------------------------------===//

bool FunctionSignatureTransform::ArgumentExplosionAnalyzeParameters() {
  // If we are not supposed to perform argument explosion, bail.
  if (FSODisableArgExplosion)
    return false;

  SILFunction *F = TransformDescriptor.OriginalFunction;
  // Did we decide we should optimize any parameter?
  bool SignatureOptimize = false;
  auto Args = F->begin()->getFunctionArguments();
  ConsumedArgToEpilogueReleaseMatcher ArgToReturnReleaseMap(
      RCIA->get(F), F, {SILArgumentConvention::Direct_Owned});

  // Analyze the argument information.
  for (unsigned i : indices(Args)) {
    ArgumentDescriptor &A = TransformDescriptor.ArgumentDescList[i];
    // If the argument is dead, there is no point in trying to explode it. The
    // dead argument pass will get it.
    if (A.IsEntirelyDead) {
      continue;
    }

    // Do not optimize argument.
    if (!A.canOptimizeLiveArg()) {
      continue;
    }

    // Explosion of generic parameters is not supported yet.
    if (A.Arg->getType().hasArchetype())
      continue;

    A.ProjTree.computeUsesAndLiveness(A.Arg);
    A.Explode = shouldExplode(TransformDescriptor, A, ArgToReturnReleaseMap);

    // Modified self argument.
    if (A.Explode && Args[i]->isSelf()) {
      TransformDescriptor.shouldModifySelfArgument = true;
    }

    SignatureOptimize |= A.Explode;
  }
  return SignatureOptimize;
}

void FunctionSignatureTransform::ArgumentExplosionFinalizeOptimizedFunction() {
  SILFunction *NewF = TransformDescriptor.OptimizedFunction.get();
  SILBasicBlock *BB = &*NewF->begin();
  SILBuilder Builder(BB->begin());
  Builder.setCurrentDebugScope(BB->getParent()->getDebugScope());
  unsigned TotalArgIndex = 0;
  for (ArgumentDescriptor &AD : TransformDescriptor.ArgumentDescList) {
    // If this argument descriptor was dead and we removed it, just skip it. Do
    // not increment the argument index.
    if (AD.WasErased) {
      continue;
    }

    // Simply continue if do not explode.
    if (!AD.Explode) {
      TransformDescriptor.AIM[TotalArgIndex] = AD.Index;
      ++TotalArgIndex;
      continue;
    }

    assert(!AD.IsEntirelyDead &&
           "Should never see completely dead values here");

    // OK, we need to explode this argument.
    unsigned ArgOffset = ++TotalArgIndex;
    unsigned OldArgIndex = ArgOffset - 1;
    llvm::SmallVector<SILValue, 8> LeafValues;

    // We do this in the same order as leaf types since ProjTree expects that
    // the order of leaf values matches the order of leaf types.
    llvm::SmallVector<const ProjectionTreeNode *, 8> LeafNodes;
    AD.ProjTree.getLiveLeafNodes(LeafNodes);

    for (auto *Node : LeafNodes) {
      auto OwnershipKind = *AD.getTransformedOwnershipKind(Node->getType());
      LeafValues.push_back(
          BB->insertFunctionArgument(ArgOffset, Node->getType(), OwnershipKind,
                                     BB->getArgument(OldArgIndex)->getDecl()));
      TransformDescriptor.AIM[TotalArgIndex - 1] = AD.Index;
      ++ArgOffset;
      ++TotalArgIndex;
    }

    // Then go through the projection tree constructing aggregates and replacing
    // uses.
    AD.ProjTree.replaceValueUsesWithLeafUses(
        Builder, BB->getParent()->getLocation(), LeafValues);

    // We ignored debugvalue uses when we constructed the new arguments, in
    // order to preserve as much information as possible, we construct a new
    // value for OrigArg from the leaf values and use that in place of the
    // OrigArg.
    SILValue NewOrigArgValue = AD.ProjTree.computeExplodedArgumentValue(
        Builder, BB->getParent()->getLocation(), LeafValues);

    // Replace all uses of the original arg with the new value.
    SILArgument *OrigArg = BB->getArgument(OldArgIndex);
    OrigArg->replaceAllUsesWith(NewOrigArgValue);

    // Now erase the old argument since it does not have any uses. We also
    // decrement ArgOffset since we have one less argument now.
    BB->eraseArgument(OldArgIndex);
    --TotalArgIndex;
  }
}
