Skip to content

[passmanager] Change the optimizer to use SILOptFunctionBuilder. #18517

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions include/swift/SILOptimizer/PassManager/Transforms.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ namespace swift {
/// Inject the pass manager running this pass.
void injectPassManager(SILPassManager *PMM) { PM = PMM; }

SILPassManager *getPassManager() const { return PM; }

irgen::IRGenModule *getIRGenModule() {
auto *Mod = PM->getIRGenModule();
assert(Mod && "Expecting a valid module");
Expand Down
14 changes: 10 additions & 4 deletions include/swift/SILOptimizer/Utils/CastOptimizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,12 @@

namespace swift {

class SILOptFunctionBuilder;

/// \brief This is a helper class used to optimize casts.
class CastOptimizer {
SILOptFunctionBuilder &FunctionBuilder;

// Callback to be called when uses of an instruction should be replaced.
std::function<void(SingleValueInstruction *I, ValueBase *V)>
ReplaceInstUsesAction;
Expand Down Expand Up @@ -64,12 +68,13 @@ class CastOptimizer {
SILInstruction *TrapInst);

public:
CastOptimizer(std::function<void(SingleValueInstruction *I, ValueBase *V)>
CastOptimizer(SILOptFunctionBuilder &FunctionBuilder,
std::function<void(SingleValueInstruction *I, ValueBase *V)>
ReplaceInstUsesAction,
std::function<void(SILInstruction *)> EraseAction,
std::function<void()> WillSucceedAction,
std::function<void()> WillFailAction = []() {})
: ReplaceInstUsesAction(ReplaceInstUsesAction),
: FunctionBuilder(FunctionBuilder), ReplaceInstUsesAction(ReplaceInstUsesAction),
EraseInstAction(EraseAction), WillSucceedAction(WillSucceedAction),
WillFailAction(WillFailAction) {}

Expand All @@ -78,11 +83,12 @@ class CastOptimizer {
// couldn't use the single constructor version which has three default
// arguments. It seems the number of the default argument with lambda is
// limited.
CastOptimizer(std::function<void(SingleValueInstruction *I, ValueBase *V)>
CastOptimizer(SILOptFunctionBuilder &FunctionBuilder,
std::function<void(SingleValueInstruction *I, ValueBase *V)>
ReplaceInstUsesAction,
std::function<void(SILInstruction *)> EraseAction =
[](SILInstruction *) {})
: CastOptimizer(ReplaceInstUsesAction, EraseAction, []() {}, []() {}) {}
: CastOptimizer(FunctionBuilder, ReplaceInstUsesAction, EraseAction, []() {}, []() {}) {}

/// Simplify checked_cast_br. It may change the control flow.
SILInstruction *simplifyCheckedCastBranchInst(CheckedCastBranchInst *Inst);
Expand Down
10 changes: 8 additions & 2 deletions include/swift/SILOptimizer/Utils/ConstantFolding.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@

namespace swift {

class SILOptFunctionBuilder;

/// Evaluates the constant result of a binary bit-operation.
///
/// The \p ID must be the ID of a binary bit-operation builtin.
Expand Down Expand Up @@ -54,6 +56,8 @@ APInt constantFoldCast(APInt val, const BuiltinInfo &BI);
/// A utility class to do constant folding.
class ConstantFolder {
private:
SILOptFunctionBuilder &FuncBuilder;

/// The worklist of the constants that could be folded into their users.
llvm::SetVector<SILInstruction *> WorkList;

Expand All @@ -75,10 +79,12 @@ class ConstantFolder {
/// \param EnableDiagnostics Print diagnostics as part of mandatory constant
/// propagation.
/// \param Callback Called for each constant folded instruction.
ConstantFolder(unsigned AssertConfiguration,
ConstantFolder(SILOptFunctionBuilder &FuncBuilder,
unsigned AssertConfiguration,
bool EnableDiagnostics = false,
std::function<void (SILInstruction *)> Callback =
[](SILInstruction *){}) :
[](SILInstruction *){}) :
FuncBuilder(FuncBuilder),
AssertConfiguration(AssertConfiguration),
EnableDiagnostics(EnableDiagnostics),
Callback(Callback) { }
Expand Down
13 changes: 8 additions & 5 deletions include/swift/SILOptimizer/Utils/GenericCloner.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,28 +40,30 @@ class GenericCloner : public TypeSubstCloner<GenericCloner> {
public:
friend class SILCloner<GenericCloner>;

GenericCloner(SILFunction *F,
GenericCloner(SILOptFunctionBuilder &FuncBuilder,
SILFunction *F,
IsSerialized_t Serialized,
const ReabstractionInfo &ReInfo,
SubstitutionMap ParamSubs,
StringRef NewName,
CloneCollector::CallbackType Callback)
: TypeSubstCloner(*initCloned(F, Serialized, ReInfo, NewName), *F,
: TypeSubstCloner(*initCloned(FuncBuilder, F, Serialized, ReInfo, NewName), *F,
ParamSubs), ReInfo(ReInfo), Callback(Callback) {
assert(F->getDebugScope()->Parent != getCloned()->getDebugScope()->Parent);
}
/// Clone and remap the types in \p F according to the substitution
/// list in \p Subs. Parameters are re-abstracted (changed from indirect to
/// direct) according to \p ReInfo.
static SILFunction *
cloneFunction(SILFunction *F,
cloneFunction(SILOptFunctionBuilder &FuncBuilder,
SILFunction *F,
IsSerialized_t Serialized,
const ReabstractionInfo &ReInfo,
SubstitutionMap ParamSubs,
StringRef NewName,
CloneCollector::CallbackType Callback =nullptr) {
// Clone and specialize the function.
GenericCloner SC(F, Serialized, ReInfo, ParamSubs,
GenericCloner SC(FuncBuilder, F, Serialized, ReInfo, ParamSubs,
NewName, Callback);
SC.populateCloned();
SC.cleanUp(SC.getCloned());
Expand All @@ -84,7 +86,8 @@ class GenericCloner : public TypeSubstCloner<GenericCloner> {
}

private:
static SILFunction *initCloned(SILFunction *Orig,
static SILFunction *initCloned(SILOptFunctionBuilder &FuncBuilder,
SILFunction *Orig,
IsSerialized_t Serialized,
const ReabstractionInfo &ReInfo,
StringRef NewName);
Expand Down
6 changes: 5 additions & 1 deletion include/swift/SILOptimizer/Utils/Generics.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
namespace swift {

class FunctionSignaturePartialSpecializer;
class SILOptFunctionBuilder;

namespace OptRemark {
class Emitter;
Expand All @@ -41,6 +42,7 @@ class Emitter;
///
/// This is the top-level entry point for specializing an existing call site.
void trySpecializeApplyOfGeneric(
SILOptFunctionBuilder &FunctionBuilder,
ApplySite Apply, DeadInstructionSet &DeadApplies,
llvm::SmallVectorImpl<SILFunction *> &NewFunctions,
OptRemark::Emitter &ORE);
Expand Down Expand Up @@ -257,6 +259,7 @@ class ReabstractionInfo {
/// Helper class for specializing a generic function given a list of
/// substitutions.
class GenericFuncSpecializer {
SILOptFunctionBuilder &FuncBuilder;
SILModule &M;
SILFunction *GenericFunc;
SubstitutionMap ParamSubs;
Expand All @@ -267,7 +270,8 @@ class GenericFuncSpecializer {
std::string ClonedName;

public:
GenericFuncSpecializer(SILFunction *GenericFunc,
GenericFuncSpecializer(SILOptFunctionBuilder &FuncBuilder,
SILFunction *GenericFunc,
SubstitutionMap ParamSubs,
IsSerialized_t Serialized,
const ReabstractionInfo &ReInfo);
Expand Down
45 changes: 45 additions & 0 deletions include/swift/SILOptimizer/Utils/SILOptFunctionBuilder.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
//===--- SILOptFunctionBuilder.h --------------------------------*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//

#ifndef SWIFT_SILOPTIMIZER_UTILS_SILOPTFUNCTIONBUILDER_H
#define SWIFT_SILOPTIMIZER_UTILS_SILOPTFUNCTIONBUILDER_H

#include "swift/SIL/SILFunctionBuilder.h"
#include "swift/SILOptimizer/PassManager/PassManager.h"

namespace swift {

class SILOptFunctionBuilder {
SILFunctionBuilder builder;

public:
SILOptFunctionBuilder(SILPassManager &passManager)
: builder(*passManager.getModule()) {}

template <class... ArgTys>
SILFunction *getOrCreateSharedFunction(ArgTys &&... args) {
return builder.getOrCreateSharedFunction(std::forward<ArgTys>(args)...);
}

template <class... ArgTys>
SILFunction *getOrCreateFunction(ArgTys &&... args) {
return builder.getOrCreateFunction(std::forward<ArgTys>(args)...);
}

template <class... ArgTys> SILFunction *createFunction(ArgTys &&... args) {
return builder.createFunction(std::forward<ArgTys>(args)...);
}
};

} // namespace swift

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
#include "swift/SIL/DebugUtils.h"
#include "swift/SIL/SILCloner.h"
#include "swift/SIL/SILFunction.h"
#include "swift/SIL/SILFunctionBuilder.h"
#include "swift/SILOptimizer/Utils/SILOptFunctionBuilder.h"
#include "swift/SIL/SILValue.h"
#include "swift/SILOptimizer/Analysis/ARCAnalysis.h"
#include "swift/SILOptimizer/Analysis/CallerAnalysis.h"
Expand Down Expand Up @@ -495,8 +495,7 @@ void FunctionSignatureTransform::createFunctionSignatureOptimizedFunction() {
// The specialized function is an internal detail, so we need to disconnect it
// from a parent class, if one exists, thus the override of the
// classSubclassScope.
SILFunctionBuilder builder(M);
TransformDescriptor.OptimizedFunction = builder.createFunction(
TransformDescriptor.OptimizedFunction = FunctionBuilder.createFunction(
linkage, Name, NewFTy, NewFGenericEnv, F->getLocation(), F->isBare(),
F->isTransparent(), F->isSerialized(), F->getEntryCount(), F->isThunk(),
/*classSubclassScope=*/SubclassScope::NotApplicable,
Expand Down Expand Up @@ -795,8 +794,9 @@ class FunctionSignatureOpts : public SILFunctionTransform {
ResultDescList.emplace_back(IR);
}

SILOptFunctionBuilder FuncBuilder(*getPassManager());
// Owned to guaranteed optimization.
FunctionSignatureTransform FST(F, RCIA, EA, Mangler, AIM,
FunctionSignatureTransform FST(FuncBuilder, F, RCIA, EA, Mangler, AIM,
ArgumentDescList, ResultDescList);

bool Changed = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "swift/SILOptimizer/Analysis/RCIdentityAnalysis.h"
#include "swift/SILOptimizer/PassManager/PassManager.h"
#include "swift/SILOptimizer/Utils/Local.h"
#include "swift/SILOptimizer/Utils/SILOptFunctionBuilder.h"
#include "swift/SILOptimizer/Utils/SpecializationMangler.h"
#include "llvm/ADT/DenseMap.h"

Expand Down Expand Up @@ -216,6 +217,8 @@ struct FunctionSignatureTransformDescriptor {
};

class FunctionSignatureTransform {
SILOptFunctionBuilder &FunctionBuilder;

/// A struct that contains all data that we use during our
/// transformation. This is an initial step towards splitting this struct into
/// multiple "transforms" that can be tested independently of each other.
Expand Down Expand Up @@ -284,12 +287,14 @@ class FunctionSignatureTransform {
public:
/// Constructor.
FunctionSignatureTransform(
SILOptFunctionBuilder &FunctionBuilder,
SILFunction *F, RCIdentityAnalysis *RCIA, EpilogueARCAnalysis *EA,
Mangle::FunctionSignatureSpecializationMangler &Mangler,
llvm::SmallDenseMap<int, int> &AIM,
llvm::SmallVector<ArgumentDescriptor, 4> &ADL,
llvm::SmallVector<ResultDescriptor, 4> &RDL)
: TransformDescriptor{F, nullptr, AIM, false, ADL, RDL}, RCIA(RCIA),
: FunctionBuilder(FunctionBuilder),
TransformDescriptor{F, nullptr, AIM, false, ADL, RDL}, RCIA(RCIA),
EA(EA) {}

/// Return the optimized function.
Expand Down
33 changes: 20 additions & 13 deletions lib/SILOptimizer/IPO/CapturePromotion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
#define DEBUG_TYPE "sil-capture-promotion"
#include "swift/AST/GenericEnvironment.h"
#include "swift/SIL/SILCloner.h"
#include "swift/SIL/SILFunctionBuilder.h"
#include "swift/SILOptimizer/Utils/SILOptFunctionBuilder.h"
#include "swift/SIL/TypeSubstCloner.h"
#include "swift/SILOptimizer/PassManager/Passes.h"
#include "swift/SILOptimizer/PassManager/Transforms.h"
Expand Down Expand Up @@ -197,7 +197,8 @@ class ClosureCloner : public SILClonerWithScopes<ClosureCloner> {
friend class SILInstructionVisitor<ClosureCloner>;
friend class SILCloner<ClosureCloner>;

ClosureCloner(SILFunction *Orig, IsSerialized_t Serialized,
ClosureCloner(SILOptFunctionBuilder &FuncBuilder,
SILFunction *Orig, IsSerialized_t Serialized,
StringRef ClonedName,
IndicesSet &PromotableIndices);

Expand All @@ -206,7 +207,8 @@ class ClosureCloner : public SILClonerWithScopes<ClosureCloner> {
SILFunction *getCloned() { return &getBuilder().getFunction(); }

private:
static SILFunction *initCloned(SILFunction *Orig, IsSerialized_t Serialized,
static SILFunction *initCloned(SILOptFunctionBuilder &FuncBuilder,
SILFunction *Orig, IsSerialized_t Serialized,
StringRef ClonedName,
IndicesSet &PromotableIndices);

Expand Down Expand Up @@ -306,11 +308,12 @@ ReachabilityInfo::isReachable(SILBasicBlock *From, SILBasicBlock *To) {
return FromSet.test(FI->second);
}

ClosureCloner::ClosureCloner(SILFunction *Orig, IsSerialized_t Serialized,
ClosureCloner::ClosureCloner(SILOptFunctionBuilder &FuncBuilder,
SILFunction *Orig, IsSerialized_t Serialized,
StringRef ClonedName,
IndicesSet &PromotableIndices)
: SILClonerWithScopes<ClosureCloner>(
*initCloned(Orig, Serialized, ClonedName, PromotableIndices)),
*initCloned(FuncBuilder, Orig, Serialized, ClonedName, PromotableIndices)),
Orig(Orig), PromotableIndices(PromotableIndices) {
assert(Orig->getDebugScope()->Parent != getCloned()->getDebugScope()->Parent);
}
Expand Down Expand Up @@ -403,7 +406,8 @@ static std::string getSpecializedName(SILFunction *F,
/// *NOTE* PromotableIndices only contains the container value of the box, not
/// the address value.
SILFunction*
ClosureCloner::initCloned(SILFunction *Orig, IsSerialized_t Serialized,
ClosureCloner::initCloned(SILOptFunctionBuilder &FunctionBuilder,
SILFunction *Orig, IsSerialized_t Serialized,
StringRef ClonedName,
IndicesSet &PromotableIndices) {
SILModule &M = Orig->getModule();
Expand All @@ -428,8 +432,7 @@ ClosureCloner::initCloned(SILFunction *Orig, IsSerialized_t Serialized,
&& "SILFunction missing DebugScope");
assert(!Orig->isGlobalInit() && "Global initializer cannot be cloned");

SILFunctionBuilder builder(M);
auto *Fn = builder.createFunction(
auto *Fn = FunctionBuilder.createFunction(
Orig->getLinkage(), ClonedName, ClonedTy, Orig->getGenericEnvironment(),
Orig->getLocation(), Orig->isBare(), IsNotTransparent, Serialized,
Orig->getEntryCount(), Orig->isThunk(), Orig->getClassSubclassScope(),
Expand Down Expand Up @@ -1130,7 +1133,8 @@ examineAllocBoxInst(AllocBoxInst *ABI, ReachabilityInfo &RI,
}

static SILFunction *
constructClonedFunction(PartialApplyInst *PAI, FunctionRefInst *FRI,
constructClonedFunction(SILOptFunctionBuilder &FuncBuilder,
PartialApplyInst *PAI, FunctionRefInst *FRI,
IndicesSet &PromotableIndices) {
SILFunction *F = PAI->getFunction();

Expand All @@ -1150,7 +1154,7 @@ constructClonedFunction(PartialApplyInst *PAI, FunctionRefInst *FRI,
}

// Otherwise, create a new clone.
ClosureCloner cloner(Orig, Serialized, ClonedName, PromotableIndices);
ClosureCloner cloner(FuncBuilder, Orig, Serialized, ClonedName, PromotableIndices);
cloner.populateCloned();
return cloner.getCloned();
}
Expand Down Expand Up @@ -1203,14 +1207,15 @@ static SILValue getOrCreateProjectBoxHelper(SILValue PartialOperand) {
/// necessary. Also, if the closure is cloned, the cloned function is added to
/// the worklist.
static SILFunction *
processPartialApplyInst(PartialApplyInst *PAI, IndicesSet &PromotableIndices,
processPartialApplyInst(SILOptFunctionBuilder &FuncBuilder,
PartialApplyInst *PAI, IndicesSet &PromotableIndices,
SmallVectorImpl<SILFunction*> &Worklist) {
SILModule &M = PAI->getModule();

auto *FRI = dyn_cast<FunctionRefInst>(PAI->getCallee());

// Clone the closure with the given promoted captures.
SILFunction *ClonedFn = constructClonedFunction(PAI, FRI, PromotableIndices);
SILFunction *ClonedFn = constructClonedFunction(FuncBuilder, PAI, FRI, PromotableIndices);
Worklist.push_back(ClonedFn);

// Initialize a SILBuilder and create a function_ref referencing the cloned
Expand Down Expand Up @@ -1338,9 +1343,11 @@ void CapturePromotionPass::processFunction(SILFunction *F,

// Do the actual promotions; all promotions on a single partial_apply are
// handled together.
SILOptFunctionBuilder FuncBuilder(*getPassManager());
for (auto &IndicesPair : IndicesMap) {
PartialApplyInst *PAI = IndicesPair.first;
SILFunction *ClonedFn = processPartialApplyInst(PAI, IndicesPair.second,
SILFunction *ClonedFn = processPartialApplyInst(FuncBuilder,
PAI, IndicesPair.second,
Worklist);
notifyAddFunction(ClonedFn);
}
Expand Down
Loading