Skip to content

Commit

Permalink
Merge pull request swiftlang#18517 from gottesmm/pr-69d1270fb634f67df…
Browse files Browse the repository at this point in the history
…bb02afed012bb5cada0dcc1

[passmanager] Change the optimizer to use SILOptFunctionBuilder.
  • Loading branch information
gottesmm authored Aug 6, 2018
2 parents 1623f42 + b723044 commit b8cb40b
Show file tree
Hide file tree
Showing 26 changed files with 264 additions and 135 deletions.
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

0 comments on commit b8cb40b

Please sign in to comment.