mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
113 lines
4.0 KiB
C++
113 lines
4.0 KiB
C++
//===--- FunctionSignatureOptUtils.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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "swift/SIL/SILBasicBlock.h"
|
|
#include "swift/SIL/SILFunction.h"
|
|
#include "swift/SIL/SILInstruction.h"
|
|
#include "swift/SIL/SILModule.h"
|
|
#include "swift/SIL/SILValue.h"
|
|
#include "swift/SIL/DebugUtils.h"
|
|
#include "swift/SILOptimizer/Utils/FunctionSignatureOptUtils.h"
|
|
#include "swift/SILOptimizer/Utils/Local.h"
|
|
#include "llvm/Support/CommandLine.h"
|
|
|
|
using namespace swift;
|
|
|
|
/// Set to true to enable the support for partial specialization.
|
|
llvm::cl::opt<bool> FSOEnableGenerics(
|
|
"sil-fso-enable-generics", llvm::cl::init(true),
|
|
llvm::cl::desc("Support function signature optimization "
|
|
"of generic functions"));
|
|
|
|
bool swift::hasNonTrivialNonDebugUse(SILArgument *Arg) {
|
|
llvm::SmallVector<SILInstruction *, 8> Worklist;
|
|
llvm::SmallPtrSet<SILInstruction *, 8> SeenInsts;
|
|
|
|
for (Operand *I : getNonDebugUses(SILValue(Arg)))
|
|
Worklist.push_back(I->getUser());
|
|
|
|
while (!Worklist.empty()) {
|
|
SILInstruction *U = Worklist.pop_back_val();
|
|
if (!SeenInsts.insert(U).second)
|
|
continue;
|
|
|
|
// If U is a terminator inst, return false.
|
|
if (isa<TermInst>(U))
|
|
return true;
|
|
|
|
// If U has side effects...
|
|
if (U->mayHaveSideEffects())
|
|
return true;
|
|
|
|
// Otherwise add all non-debug uses of I to the worklist.
|
|
for (Operand *I : getNonDebugUses(SILValue(U)))
|
|
Worklist.push_back(I->getUser());
|
|
}
|
|
return false;
|
|
}
|
|
|
|
static bool isSpecializableRepresentation(SILFunctionTypeRepresentation Rep,
|
|
bool OptForPartialApply) {
|
|
switch (Rep) {
|
|
case SILFunctionTypeRepresentation::Method:
|
|
case SILFunctionTypeRepresentation::Closure:
|
|
case SILFunctionTypeRepresentation::Thin:
|
|
case SILFunctionTypeRepresentation::Thick:
|
|
case SILFunctionTypeRepresentation::CFunctionPointer:
|
|
return true;
|
|
case SILFunctionTypeRepresentation::WitnessMethod:
|
|
return OptForPartialApply;
|
|
case SILFunctionTypeRepresentation::ObjCMethod:
|
|
case SILFunctionTypeRepresentation::Block:
|
|
return false;
|
|
}
|
|
|
|
llvm_unreachable("Unhandled SILFunctionTypeRepresentation in switch.");
|
|
}
|
|
|
|
/// Returns true if F is a function which the pass know show to specialize
|
|
/// function signatures for.
|
|
bool swift::canSpecializeFunction(SILFunction *F,
|
|
const CallerAnalysis::FunctionInfo *FuncInfo,
|
|
bool OptForPartialApply) {
|
|
// Do not specialize the signature of SILFunctions that are external
|
|
// declarations since there is no body to optimize.
|
|
if (F->isExternalDeclaration())
|
|
return false;
|
|
|
|
// For now ignore functions with indirect results.
|
|
if (F->getConventions().hasIndirectSILResults())
|
|
return false;
|
|
|
|
// Do not specialize the signature of always inline functions. We
|
|
// will just inline them and specialize each one of the individual
|
|
// functions that these sorts of functions are inlined into.
|
|
// It is OK to specialize always inline functions if they are
|
|
// used by partial_apply instructions.
|
|
assert(!OptForPartialApply || FuncInfo);
|
|
if (F->getInlineStrategy() == Inline_t::AlwaysInline &&
|
|
(!OptForPartialApply || !FuncInfo->getMinPartialAppliedArgs()))
|
|
return false;
|
|
|
|
// For now ignore generic functions to keep things simple...
|
|
if (!FSOEnableGenerics && F->getLoweredFunctionType()->isPolymorphic())
|
|
return false;
|
|
|
|
// Make sure F has a linkage that we can optimize.
|
|
if (!isSpecializableRepresentation(F->getRepresentation(),
|
|
OptForPartialApply))
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|