From b72304415dc50cc1f7afa0ab1e342e56d3ac1f15 Mon Sep 17 00:00:00 2001 From: Michael Gottesman Date: Sun, 5 Aug 2018 17:51:51 -0700 Subject: [PATCH] [passmanager] Change the optimizer to use SILOptFunctionBuilder. I am going to add the code in a bit that does the notifications. I tried to pass down the builder instead of the pass manager. I also tried not to change the formatting. rdar://42301529 --- .../SILOptimizer/PassManager/Transforms.h | 2 + .../swift/SILOptimizer/Utils/CastOptimizer.h | 14 ++++-- .../SILOptimizer/Utils/ConstantFolding.h | 10 ++++- .../swift/SILOptimizer/Utils/GenericCloner.h | 13 +++--- include/swift/SILOptimizer/Utils/Generics.h | 6 ++- .../Utils/SILOptFunctionBuilder.h | 45 +++++++++++++++++++ .../FunctionSignatureOpts.cpp | 8 ++-- .../FunctionSignatureOpts.h | 7 ++- lib/SILOptimizer/IPO/CapturePromotion.cpp | 33 ++++++++------ lib/SILOptimizer/IPO/CapturePropagation.cpp | 18 ++++---- lib/SILOptimizer/IPO/ClosureSpecializer.cpp | 24 +++++----- lib/SILOptimizer/IPO/EagerSpecializer.cpp | 13 ++++-- lib/SILOptimizer/IPO/GlobalOpt.cpp | 35 +++++++++------ .../Mandatory/ConstantPropagation.cpp | 6 ++- lib/SILOptimizer/SILCombiner/SILCombine.cpp | 4 +- lib/SILOptimizer/SILCombiner/SILCombiner.h | 6 ++- .../Transforms/AllocBoxToStack.cpp | 33 ++++++++------ .../Transforms/GenericSpecializer.cpp | 5 ++- .../Transforms/ObjectOutliner.cpp | 14 +++--- lib/SILOptimizer/Transforms/Outliner.cpp | 35 +++++++++------ lib/SILOptimizer/Transforms/SimplifyCFG.cpp | 13 ++++-- .../UtilityPasses/BugReducerTester.cpp | 6 +-- lib/SILOptimizer/Utils/CastOptimizer.cpp | 8 ++-- lib/SILOptimizer/Utils/ConstantFolding.cpp | 3 +- lib/SILOptimizer/Utils/GenericCloner.cpp | 8 ++-- lib/SILOptimizer/Utils/Generics.cpp | 30 +++++++------ 26 files changed, 264 insertions(+), 135 deletions(-) create mode 100644 include/swift/SILOptimizer/Utils/SILOptFunctionBuilder.h diff --git a/include/swift/SILOptimizer/PassManager/Transforms.h b/include/swift/SILOptimizer/PassManager/Transforms.h index c92fde435d780..b52358ed9c6be 100644 --- a/include/swift/SILOptimizer/PassManager/Transforms.h +++ b/include/swift/SILOptimizer/PassManager/Transforms.h @@ -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"); diff --git a/include/swift/SILOptimizer/Utils/CastOptimizer.h b/include/swift/SILOptimizer/Utils/CastOptimizer.h index a4e0dabd386e7..49f73711ba4a0 100644 --- a/include/swift/SILOptimizer/Utils/CastOptimizer.h +++ b/include/swift/SILOptimizer/Utils/CastOptimizer.h @@ -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 ReplaceInstUsesAction; @@ -64,12 +68,13 @@ class CastOptimizer { SILInstruction *TrapInst); public: - CastOptimizer(std::function + CastOptimizer(SILOptFunctionBuilder &FunctionBuilder, + std::function ReplaceInstUsesAction, std::function EraseAction, std::function WillSucceedAction, std::function WillFailAction = []() {}) - : ReplaceInstUsesAction(ReplaceInstUsesAction), + : FunctionBuilder(FunctionBuilder), ReplaceInstUsesAction(ReplaceInstUsesAction), EraseInstAction(EraseAction), WillSucceedAction(WillSucceedAction), WillFailAction(WillFailAction) {} @@ -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 + CastOptimizer(SILOptFunctionBuilder &FunctionBuilder, + std::function ReplaceInstUsesAction, std::function EraseAction = [](SILInstruction *) {}) - : CastOptimizer(ReplaceInstUsesAction, EraseAction, []() {}, []() {}) {} + : CastOptimizer(FunctionBuilder, ReplaceInstUsesAction, EraseAction, []() {}, []() {}) {} /// Simplify checked_cast_br. It may change the control flow. SILInstruction *simplifyCheckedCastBranchInst(CheckedCastBranchInst *Inst); diff --git a/include/swift/SILOptimizer/Utils/ConstantFolding.h b/include/swift/SILOptimizer/Utils/ConstantFolding.h index b47fa10910cda..144f25e31a007 100644 --- a/include/swift/SILOptimizer/Utils/ConstantFolding.h +++ b/include/swift/SILOptimizer/Utils/ConstantFolding.h @@ -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. @@ -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 WorkList; @@ -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 Callback = - [](SILInstruction *){}) : + [](SILInstruction *){}) : + FuncBuilder(FuncBuilder), AssertConfiguration(AssertConfiguration), EnableDiagnostics(EnableDiagnostics), Callback(Callback) { } diff --git a/include/swift/SILOptimizer/Utils/GenericCloner.h b/include/swift/SILOptimizer/Utils/GenericCloner.h index d81463a645501..53995238ec4ad 100644 --- a/include/swift/SILOptimizer/Utils/GenericCloner.h +++ b/include/swift/SILOptimizer/Utils/GenericCloner.h @@ -40,13 +40,14 @@ class GenericCloner : public TypeSubstCloner { public: friend class SILCloner; - 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); } @@ -54,14 +55,15 @@ class GenericCloner : public TypeSubstCloner { /// 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()); @@ -84,7 +86,8 @@ class GenericCloner : public TypeSubstCloner { } private: - static SILFunction *initCloned(SILFunction *Orig, + static SILFunction *initCloned(SILOptFunctionBuilder &FuncBuilder, + SILFunction *Orig, IsSerialized_t Serialized, const ReabstractionInfo &ReInfo, StringRef NewName); diff --git a/include/swift/SILOptimizer/Utils/Generics.h b/include/swift/SILOptimizer/Utils/Generics.h index 02d5f30879135..7cfadd89469bc 100644 --- a/include/swift/SILOptimizer/Utils/Generics.h +++ b/include/swift/SILOptimizer/Utils/Generics.h @@ -28,6 +28,7 @@ namespace swift { class FunctionSignaturePartialSpecializer; +class SILOptFunctionBuilder; namespace OptRemark { class Emitter; @@ -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 &NewFunctions, OptRemark::Emitter &ORE); @@ -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; @@ -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); diff --git a/include/swift/SILOptimizer/Utils/SILOptFunctionBuilder.h b/include/swift/SILOptimizer/Utils/SILOptFunctionBuilder.h new file mode 100644 index 0000000000000..56a4bc8745520 --- /dev/null +++ b/include/swift/SILOptimizer/Utils/SILOptFunctionBuilder.h @@ -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 + SILFunction *getOrCreateSharedFunction(ArgTys &&... args) { + return builder.getOrCreateSharedFunction(std::forward(args)...); + } + + template + SILFunction *getOrCreateFunction(ArgTys &&... args) { + return builder.getOrCreateFunction(std::forward(args)...); + } + + template SILFunction *createFunction(ArgTys &&... args) { + return builder.createFunction(std::forward(args)...); + } +}; + +} // namespace swift + +#endif diff --git a/lib/SILOptimizer/FunctionSignatureTransforms/FunctionSignatureOpts.cpp b/lib/SILOptimizer/FunctionSignatureTransforms/FunctionSignatureOpts.cpp index 935a01d5dd38d..32e060490a31d 100644 --- a/lib/SILOptimizer/FunctionSignatureTransforms/FunctionSignatureOpts.cpp +++ b/lib/SILOptimizer/FunctionSignatureTransforms/FunctionSignatureOpts.cpp @@ -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" @@ -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, @@ -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; diff --git a/lib/SILOptimizer/FunctionSignatureTransforms/FunctionSignatureOpts.h b/lib/SILOptimizer/FunctionSignatureTransforms/FunctionSignatureOpts.h index fb618a0f1d528..fef93779651f0 100644 --- a/lib/SILOptimizer/FunctionSignatureTransforms/FunctionSignatureOpts.h +++ b/lib/SILOptimizer/FunctionSignatureTransforms/FunctionSignatureOpts.h @@ -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" @@ -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. @@ -284,12 +287,14 @@ class FunctionSignatureTransform { public: /// Constructor. FunctionSignatureTransform( + SILOptFunctionBuilder &FunctionBuilder, SILFunction *F, RCIdentityAnalysis *RCIA, EpilogueARCAnalysis *EA, Mangle::FunctionSignatureSpecializationMangler &Mangler, llvm::SmallDenseMap &AIM, llvm::SmallVector &ADL, llvm::SmallVector &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. diff --git a/lib/SILOptimizer/IPO/CapturePromotion.cpp b/lib/SILOptimizer/IPO/CapturePromotion.cpp index 5803fade3a4b6..85cabb038a6a1 100644 --- a/lib/SILOptimizer/IPO/CapturePromotion.cpp +++ b/lib/SILOptimizer/IPO/CapturePromotion.cpp @@ -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" @@ -197,7 +197,8 @@ class ClosureCloner : public SILClonerWithScopes { friend class SILInstructionVisitor; friend class SILCloner; - ClosureCloner(SILFunction *Orig, IsSerialized_t Serialized, + ClosureCloner(SILOptFunctionBuilder &FuncBuilder, + SILFunction *Orig, IsSerialized_t Serialized, StringRef ClonedName, IndicesSet &PromotableIndices); @@ -206,7 +207,8 @@ class ClosureCloner : public SILClonerWithScopes { 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); @@ -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( - *initCloned(Orig, Serialized, ClonedName, PromotableIndices)), + *initCloned(FuncBuilder, Orig, Serialized, ClonedName, PromotableIndices)), Orig(Orig), PromotableIndices(PromotableIndices) { assert(Orig->getDebugScope()->Parent != getCloned()->getDebugScope()->Parent); } @@ -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(); @@ -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(), @@ -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(); @@ -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(); } @@ -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 &Worklist) { SILModule &M = PAI->getModule(); auto *FRI = dyn_cast(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 @@ -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); } diff --git a/lib/SILOptimizer/IPO/CapturePropagation.cpp b/lib/SILOptimizer/IPO/CapturePropagation.cpp index 734d361d176ad..5a3dfda59dbbf 100644 --- a/lib/SILOptimizer/IPO/CapturePropagation.cpp +++ b/lib/SILOptimizer/IPO/CapturePropagation.cpp @@ -14,7 +14,7 @@ #include "swift/AST/GenericEnvironment.h" #include "swift/Demangling/Demangle.h" #include "swift/SIL/SILCloner.h" -#include "swift/SIL/SILFunctionBuilder.h" +#include "swift/SILOptimizer/Utils/SILOptFunctionBuilder.h" #include "swift/SIL/SILInstruction.h" #include "swift/SIL/TypeSubstCloner.h" #include "swift/SILOptimizer/Analysis/ColdBlockInfo.h" @@ -257,8 +257,8 @@ SILFunction *CapturePropagation::specializeConstClosure(PartialApplyInst *PAI, GenericEnvironment *GenericEnv = nullptr; if (NewFTy->getGenericSignature()) GenericEnv = OrigF->getGenericEnvironment(); - SILFunctionBuilder builder(OrigF->getModule()); - SILFunction *NewF = builder.createFunction( + SILOptFunctionBuilder FuncBuilder(*getPassManager()); + SILFunction *NewF = FuncBuilder.createFunction( SILLinkage::Shared, Name, NewFTy, GenericEnv, OrigF->getLocation(), OrigF->isBare(), OrigF->isTransparent(), Serialized, OrigF->getEntryCount(), OrigF->isThunk(), OrigF->getClassSubclassScope(), @@ -336,6 +336,7 @@ static bool onlyContainsReturnOrThrowOfArg(SILBasicBlock *BB) { /// GenericSpecialized contains a tuple: /// (new specialized function, old function) static SILFunction *getSpecializedWithDeadParams( + SILOptFunctionBuilder &FuncBuilder, PartialApplyInst *PAI, SILFunction *Orig, int numDeadParams, std::pair &GenericSpecialized) { SILBasicBlock &EntryBB = *Orig->begin(); @@ -418,10 +419,10 @@ static SILFunction *getSpecializedWithDeadParams( ReabstractionInfo ReInfo(ApplySite(), Specialized, PAI->getSubstitutionMap(), /* ConvertIndirectToDirect */ false); - GenericFuncSpecializer FuncSpecializer( - Specialized, - ReInfo.getClonerParamSubstitutionMap(), - Specialized->isSerialized(), ReInfo); + GenericFuncSpecializer FuncSpecializer(FuncBuilder, + Specialized, + ReInfo.getClonerParamSubstitutionMap(), + Specialized->isSerialized(), ReInfo); SILFunction *GenericSpecializedFunc = FuncSpecializer.trySpecialization(); if (!GenericSpecializedFunc) @@ -451,7 +452,8 @@ bool CapturePropagation::optimizePartialApply(PartialApplyInst *PAI) { // First possibility: Is it a partial_apply where all partially applied // arguments are dead? std::pair GenericSpecialized; - if (auto *NewFunc = getSpecializedWithDeadParams( + SILOptFunctionBuilder FuncBuilder(*PM); + if (auto *NewFunc = getSpecializedWithDeadParams(FuncBuilder, PAI, SubstF, PAI->getNumArguments(), GenericSpecialized)) { rewritePartialApply(PAI, NewFunc); if (GenericSpecialized.first) { diff --git a/lib/SILOptimizer/IPO/ClosureSpecializer.cpp b/lib/SILOptimizer/IPO/ClosureSpecializer.cpp index 677ea99b22fb8..15d52af0fbce3 100644 --- a/lib/SILOptimizer/IPO/ClosureSpecializer.cpp +++ b/lib/SILOptimizer/IPO/ClosureSpecializer.cpp @@ -60,7 +60,7 @@ #include "swift/SIL/InstructionUtils.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/SILInstruction.h" #include "swift/SIL/SILModule.h" #include "swift/SILOptimizer/Analysis/BasicCalleeAnalysis.h" @@ -118,9 +118,10 @@ class ClosureSpecCloner : public SILClonerWithScopes { friend class SILInstructionVisitor; friend class SILCloner; - ClosureSpecCloner(const CallSiteDescriptor &CallSiteDesc, + ClosureSpecCloner(SILOptFunctionBuilder &FunctionBuilder, + const CallSiteDescriptor &CallSiteDesc, StringRef ClonedName) - : SuperTy(*initCloned(CallSiteDesc, ClonedName)), + : SuperTy(*initCloned(FunctionBuilder, CallSiteDesc, ClonedName)), CallSiteDesc(CallSiteDesc) {} void populateCloned(); @@ -131,16 +132,18 @@ class ClosureSpecCloner : public SILClonerWithScopes { SmallVectorImpl &NeedsRelease); SILFunction *getCloned() { return &getBuilder().getFunction(); } - static SILFunction *cloneFunction(const CallSiteDescriptor &CallSiteDesc, + static SILFunction *cloneFunction(SILOptFunctionBuilder &FunctionBuilder, + const CallSiteDescriptor &CallSiteDesc, StringRef NewName) { - ClosureSpecCloner C(CallSiteDesc, NewName); + ClosureSpecCloner C(FunctionBuilder, CallSiteDesc, NewName); C.populateCloned(); ++NumClosureSpecialized; return C.getCloned(); }; private: - static SILFunction *initCloned(const CallSiteDescriptor &CallSiteDesc, + static SILFunction *initCloned(SILOptFunctionBuilder &FunctionBuilder, + const CallSiteDescriptor &CallSiteDesc, StringRef ClonedName); const CallSiteDescriptor &CallSiteDesc; }; @@ -563,7 +566,8 @@ static bool isSupportedClosure(const SILInstruction *Closure) { /// signature. /// \arg ClonedName The name of the cloned function that we will create. SILFunction * -ClosureSpecCloner::initCloned(const CallSiteDescriptor &CallSiteDesc, +ClosureSpecCloner::initCloned(SILOptFunctionBuilder &FunctionBuilder, + const CallSiteDescriptor &CallSiteDesc, StringRef ClonedName) { SILFunction *ClosureUser = CallSiteDesc.getApplyCallee(); @@ -631,8 +635,7 @@ ClosureSpecCloner::initCloned(const CallSiteDescriptor &CallSiteDesc, // We make this function bare so we don't have to worry about decls in the // SILArgument. - SILFunctionBuilder builder(M); - auto *Fn = builder.createFunction( + auto *Fn = FunctionBuilder.createFunction( // It's important to use a shared linkage for the specialized function // and not the original linkage. // Otherwise the new function could have an external linkage (in case the @@ -1140,6 +1143,7 @@ bool SILClosureSpecializerTransform::specialize(SILFunction *Caller, invalidateAnalysis(SILAnalysis::InvalidationKind::Branches); } + SILOptFunctionBuilder FuncBuilder(*getPassManager()); bool Changed = false; for (auto *CInfo : ClosureCandidates) { for (auto &CSDesc : CInfo->CallSites) { @@ -1159,7 +1163,7 @@ bool SILClosureSpecializerTransform::specialize(SILFunction *Caller, // If not, create a specialized version of ApplyCallee calling the closure // directly. if (!NewF) { - NewF = ClosureSpecCloner::cloneFunction(CSDesc, NewFName); + NewF = ClosureSpecCloner::cloneFunction(FuncBuilder, CSDesc, NewFName); notifyAddFunction(NewF, CSDesc.getApplyCallee()); } diff --git a/lib/SILOptimizer/IPO/EagerSpecializer.cpp b/lib/SILOptimizer/IPO/EagerSpecializer.cpp index f1377bea70988..344a34d7c5b41 100644 --- a/lib/SILOptimizer/IPO/EagerSpecializer.cpp +++ b/lib/SILOptimizer/IPO/EagerSpecializer.cpp @@ -31,6 +31,7 @@ #include "swift/AST/Type.h" #include "swift/SIL/SILFunction.h" #include "swift/SILOptimizer/PassManager/Transforms.h" +#include "swift/SILOptimizer/Utils/SILOptFunctionBuilder.h" #include "swift/SILOptimizer/Utils/Generics.h" #include "llvm/Support/Debug.h" @@ -701,7 +702,8 @@ class EagerSpecializerTransform : public SILModuleTransform { } // end anonymous namespace /// Specializes a generic function for a concrete type list. -static SILFunction *eagerSpecialize(SILFunction *GenericFunc, +static SILFunction *eagerSpecialize(SILOptFunctionBuilder &FuncBuilder, + SILFunction *GenericFunc, const SILSpecializeAttr &SA, const ReabstractionInfo &ReInfo) { LLVM_DEBUG(dbgs() << "Specializing " << GenericFunc->getName() << "\n"); @@ -720,8 +722,9 @@ static SILFunction *eagerSpecialize(SILFunction *GenericFunc, Serialized = IsSerializable; GenericFuncSpecializer - FuncSpecializer(GenericFunc, ReInfo.getClonerParamSubstitutionMap(), - Serialized, ReInfo); + FuncSpecializer(FuncBuilder, GenericFunc, + ReInfo.getClonerParamSubstitutionMap(), + Serialized, ReInfo); SILFunction *NewFunc = FuncSpecializer.trySpecialization(); if (!NewFunc) @@ -734,6 +737,8 @@ void EagerSpecializerTransform::run() { if (!EagerSpecializeFlag) return; + SILOptFunctionBuilder FuncBuilder(*getPassManager()); + // Process functions in any order. for (auto &F : *getModule()) { if (!F.shouldOptimize()) { @@ -758,7 +763,7 @@ void EagerSpecializerTransform::run() { for (auto *SA : F.getSpecializeAttrs()) { auto AttrRequirements = SA->getRequirements(); ReInfoVec.emplace_back(&F, AttrRequirements); - auto *NewFunc = eagerSpecialize(&F, *SA, ReInfoVec.back()); + auto *NewFunc = eagerSpecialize(FuncBuilder, &F, *SA, ReInfoVec.back()); notifyAddFunction(NewFunc); SpecializedFuncs.push_back(NewFunc); diff --git a/lib/SILOptimizer/IPO/GlobalOpt.cpp b/lib/SILOptimizer/IPO/GlobalOpt.cpp index 79c14ff00a257..5c9a7d30226fc 100644 --- a/lib/SILOptimizer/IPO/GlobalOpt.cpp +++ b/lib/SILOptimizer/IPO/GlobalOpt.cpp @@ -17,7 +17,7 @@ #include "swift/Demangling/ManglingMacros.h" #include "swift/SIL/CFG.h" #include "swift/SIL/DebugUtils.h" -#include "swift/SIL/SILFunctionBuilder.h" +#include "swift/SILOptimizer/Utils/SILOptFunctionBuilder.h" #include "swift/SIL/SILGlobalVariable.h" #include "swift/SIL/SILInstruction.h" #include "swift/SILOptimizer/Analysis/ColdBlockInfo.h" @@ -50,6 +50,7 @@ namespace { /// - When the addressor is local to the module, be sure it is inlined to allow /// constant propagation in case of statically initialized "lets". class SILGlobalOpt { + SILOptFunctionBuilder &FunctionBuilder; SILModule *Module; DominanceAnalysis *DA; bool HasChanged = false; @@ -95,8 +96,8 @@ class SILGlobalOpt { /// function. llvm::DenseMap InitializerCount; public: - SILGlobalOpt(SILModule *M, DominanceAnalysis *DA) - : Module(M), DA(DA) {} + SILGlobalOpt(SILOptFunctionBuilder &FunctionBuilder, SILModule *M, DominanceAnalysis *DA) + : FunctionBuilder(FunctionBuilder), Module(M), DA(DA) {} bool run(); @@ -242,7 +243,8 @@ static std::string mangleGetter(VarDecl *varDecl) { return Mangler.mangleGlobalGetterEntity(varDecl); } -static SILFunction *getGlobalGetterFunction(SILModule &M, +static SILFunction *getGlobalGetterFunction(SILOptFunctionBuilder &FunctionBuilder, + SILModule &M, SILLocation loc, VarDecl *varDecl) { auto getterName = mangleGetter(varDecl); @@ -271,14 +273,15 @@ static SILFunction *getGlobalGetterFunction(SILModule &M, ParameterConvention::Direct_Unowned, /*params*/ {}, /*yields*/ {}, Results, None, M.getASTContext()); - SILFunctionBuilder builder(M); - return builder.getOrCreateFunction(loc, getterName, Linkage, LoweredType, - IsBare, IsNotTransparent, Serialized); + return FunctionBuilder.getOrCreateFunction(loc, getterName, Linkage, + LoweredType, IsBare, + IsNotTransparent, Serialized); } /// Generate getter from the initialization code whose result is stored by a /// given store instruction. -static SILFunction *genGetterFromInit(StoreInst *Store, +static SILFunction *genGetterFromInit(SILOptFunctionBuilder &FunctionBuilder, + StoreInst *Store, SILGlobalVariable *SILG) { auto *varDecl = SILG->getDecl(); @@ -296,7 +299,8 @@ static SILFunction *genGetterFromInit(StoreInst *Store, // Produce a correct order of instructions. std::reverse(Insts.begin(), Insts.end()); - auto *GetterF = getGlobalGetterFunction(Store->getModule(), + auto *GetterF = getGlobalGetterFunction(FunctionBuilder, + Store->getModule(), Store->getLoc(), varDecl); @@ -535,10 +539,12 @@ void SILGlobalOpt::placeInitializers(SILFunction *InitF, } /// Create a getter function from the initializer function. -static SILFunction *genGetterFromInit(SILFunction *InitF, VarDecl *varDecl) { +static SILFunction *genGetterFromInit(SILOptFunctionBuilder &FunctionBuilder, + SILFunction *InitF, VarDecl *varDecl) { // Generate a getter from the global init function without side-effects. - auto *GetterF = getGlobalGetterFunction(InitF->getModule(), + auto *GetterF = getGlobalGetterFunction(FunctionBuilder, + InitF->getModule(), InitF->getLocation(), varDecl); if (!InitF->hasQualifiedOwnership()) @@ -655,7 +661,7 @@ replaceLoadsByKnownValue(BuiltinInst *CallToOnce, SILFunction *AddrF, } // Generate a getter from InitF which returns the value of the global. - auto *GetterF = genGetterFromInit(InitF, SILG->getDecl()); + auto *GetterF = genGetterFromInit(FunctionBuilder, InitF, SILG->getDecl()); // Replace all calls of an addressor by calls of a getter . for (int i = 0, e = Calls.size(); i < e; ++i) { @@ -862,7 +868,7 @@ void SILGlobalOpt::optimizeGlobalAccess(SILGlobalVariable *SILG, return; // Generate a getter only if there are any loads from this variable. - SILFunction *GetterF = genGetterFromInit(SI, SILG); + SILFunction *GetterF = genGetterFromInit(FunctionBuilder, SI, SILG); if (!GetterF) return; @@ -939,7 +945,8 @@ namespace { class SILGlobalOptPass : public SILModuleTransform { void run() override { auto *DA = PM->getAnalysis(); - if (SILGlobalOpt(getModule(), DA).run()) { + SILOptFunctionBuilder FunctionBuilder(*getPassManager()); + if (SILGlobalOpt(FunctionBuilder, getModule(), DA).run()) { invalidateAll(); } } diff --git a/lib/SILOptimizer/Mandatory/ConstantPropagation.cpp b/lib/SILOptimizer/Mandatory/ConstantPropagation.cpp index f879aa38297e5..46a7459e4923d 100644 --- a/lib/SILOptimizer/Mandatory/ConstantPropagation.cpp +++ b/lib/SILOptimizer/Mandatory/ConstantPropagation.cpp @@ -12,6 +12,7 @@ #define DEBUG_TYPE "constant-propagation" #include "swift/SILOptimizer/PassManager/Transforms.h" +#include "swift/SILOptimizer/Utils/SILOptFunctionBuilder.h" #include "swift/SILOptimizer/Utils/ConstantFolding.h" using namespace swift; @@ -32,8 +33,9 @@ class ConstantPropagation : public SILFunctionTransform { private: /// The entry point to the transformation. void run() override { - - ConstantFolder Folder(getOptions().AssertConfig, EnableDiagnostics); + SILOptFunctionBuilder FuncBuilder(*getPassManager()); + ConstantFolder Folder(FuncBuilder, getOptions().AssertConfig, + EnableDiagnostics); Folder.initializeWorklist(*getFunction()); auto Invalidation = Folder.processWorkList(); diff --git a/lib/SILOptimizer/SILCombiner/SILCombine.cpp b/lib/SILOptimizer/SILCombiner/SILCombine.cpp index 0f4e965c545fc..530d3eb89c796 100644 --- a/lib/SILOptimizer/SILCombiner/SILCombine.cpp +++ b/lib/SILOptimizer/SILCombiner/SILCombine.cpp @@ -27,6 +27,7 @@ #include "swift/SILOptimizer/Analysis/AliasAnalysis.h" #include "swift/SILOptimizer/Analysis/SimplifyInstruction.h" #include "swift/SILOptimizer/PassManager/Transforms.h" +#include "swift/SILOptimizer/Utils/SILOptFunctionBuilder.h" #include "swift/SILOptimizer/Utils/Local.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" @@ -347,10 +348,11 @@ class SILCombine : public SILFunctionTransform { auto *AA = PM->getAnalysis(); auto *DA = PM->getAnalysis(); + SILOptFunctionBuilder FuncBuilder(*getPassManager()); // Create a SILBuilder with a tracking list for newly added // instructions, which we will periodically move to our worklist. SILBuilder B(*getFunction(), &TrackingList); - SILCombiner Combiner(B, AA, DA, getOptions().RemoveRuntimeAsserts); + SILCombiner Combiner(FuncBuilder, B, AA, DA, getOptions().RemoveRuntimeAsserts); bool Changed = Combiner.runOnFunction(*getFunction()); assert(TrackingList.empty() && "TrackingList should be fully processed by SILCombiner"); diff --git a/lib/SILOptimizer/SILCombiner/SILCombiner.h b/lib/SILOptimizer/SILCombiner/SILCombiner.h index b2cae236af470..b2bae8472af3f 100644 --- a/lib/SILOptimizer/SILCombiner/SILCombiner.h +++ b/lib/SILOptimizer/SILCombiner/SILCombiner.h @@ -137,11 +137,13 @@ class SILCombiner : CastOptimizer CastOpt; public: - SILCombiner(SILBuilder &B, AliasAnalysis *AA, DominanceAnalysis *DA, + SILCombiner(SILOptFunctionBuilder &FuncBuilder, + SILBuilder &B, AliasAnalysis *AA, DominanceAnalysis *DA, bool removeCondFails) : AA(AA), DA(DA), Worklist(), MadeChange(false), RemoveCondFails(removeCondFails), Iteration(0), Builder(B), - CastOpt(/* ReplaceInstUsesAction */ + CastOpt(FuncBuilder, + /* ReplaceInstUsesAction */ [&](SingleValueInstruction *I, ValueBase *V) { replaceInstUsesWith(*I, V); }, diff --git a/lib/SILOptimizer/Transforms/AllocBoxToStack.cpp b/lib/SILOptimizer/Transforms/AllocBoxToStack.cpp index ac340fc4f3459..2530b774d143e 100644 --- a/lib/SILOptimizer/Transforms/AllocBoxToStack.cpp +++ b/lib/SILOptimizer/Transforms/AllocBoxToStack.cpp @@ -15,7 +15,7 @@ #include "swift/SIL/SILArgument.h" #include "swift/SIL/SILBuilder.h" #include "swift/SIL/SILCloner.h" -#include "swift/SIL/SILFunctionBuilder.h" +#include "swift/SILOptimizer/Utils/SILOptFunctionBuilder.h" #include "swift/SILOptimizer/PassManager/Passes.h" #include "swift/SILOptimizer/PassManager/Transforms.h" #include "swift/SILOptimizer/Utils/Local.h" @@ -504,7 +504,7 @@ class PromotedParamCloner : public SILClonerWithScopes { friend class SILInstructionVisitor; friend class SILCloner; - PromotedParamCloner(SILFunction *Orig, IsSerialized_t Serialized, + PromotedParamCloner(SILOptFunctionBuilder &FuncBuilder, SILFunction *Orig, IsSerialized_t Serialized, ArgIndexList &PromotedArgIndices, llvm::StringRef ClonedName); @@ -513,7 +513,8 @@ class PromotedParamCloner : public SILClonerWithScopes { SILFunction *getCloned() { return &getBuilder().getFunction(); } private: - static SILFunction *initCloned(SILFunction *Orig, IsSerialized_t Serialized, + static SILFunction *initCloned(SILOptFunctionBuilder &FuncBuilder, + SILFunction *Orig, IsSerialized_t Serialized, ArgIndexList &PromotedArgIndices, llvm::StringRef ClonedName); @@ -532,12 +533,14 @@ class PromotedParamCloner : public SILClonerWithScopes { }; } // end anonymous namespace -PromotedParamCloner::PromotedParamCloner(SILFunction *Orig, +PromotedParamCloner::PromotedParamCloner(SILOptFunctionBuilder &FuncBuilder, + SILFunction *Orig, IsSerialized_t Serialized, ArgIndexList &PromotedArgIndices, llvm::StringRef ClonedName) : SILClonerWithScopes( - *initCloned(Orig, Serialized, PromotedArgIndices, ClonedName)), + *initCloned(FuncBuilder, Orig, Serialized, PromotedArgIndices, + ClonedName)), Orig(Orig), PromotedArgIndices(PromotedArgIndices) { assert(Orig->getDebugScope()->getParentFunction() != getCloned()->getDebugScope()->getParentFunction()); @@ -556,10 +559,10 @@ static std::string getClonedName(SILFunction *F, IsSerialized_t Serialized, /// \brief Create the function corresponding to the clone of the /// original closure with the signature modified to reflect promoted /// parameters (which are specified by PromotedArgIndices). -SILFunction *PromotedParamCloner::initCloned(SILFunction *Orig, - IsSerialized_t Serialized, - ArgIndexList &PromotedArgIndices, - llvm::StringRef ClonedName) { +SILFunction *PromotedParamCloner:: +initCloned(SILOptFunctionBuilder &FuncBuilder, SILFunction *Orig, + IsSerialized_t Serialized, ArgIndexList &PromotedArgIndices, + llvm::StringRef ClonedName) { SILModule &M = Orig->getModule(); SmallVector ClonedInterfaceArgTys; @@ -601,8 +604,7 @@ SILFunction *PromotedParamCloner::initCloned(SILFunction *Orig, assert((Orig->isTransparent() || Orig->isBare() || Orig->getDebugScope()) && "SILFunction missing DebugScope"); assert(!Orig->isGlobalInit() && "Global initializer cannot be cloned"); - SILFunctionBuilder builder(M); - auto *Fn = builder.createFunction( + auto *Fn = FuncBuilder.createFunction( SILLinkage::Shared, ClonedName, ClonedTy, Orig->getGenericEnvironment(), Orig->getLocation(), Orig->isBare(), IsNotTransparent, Serialized, Orig->getEntryCount(), Orig->isThunk(), Orig->getClassSubclassScope(), @@ -735,7 +737,8 @@ void PromotedParamCloner::visitProjectBoxInst(ProjectBoxInst *Inst) { /// indices. We expect these parameters to be replaced by stack address /// references. static PartialApplyInst * -specializePartialApply(PartialApplyInst *PartialApply, +specializePartialApply(SILOptFunctionBuilder &FuncBuilder, + PartialApplyInst *PartialApply, ArgIndexList &PromotedCalleeArgIndices, AllocBoxToStackState &pass) { auto *FRI = cast(PartialApply->getCallee()); @@ -758,7 +761,8 @@ specializePartialApply(PartialApplyInst *PartialApply, ClonedFn = PrevFn; } else { // Clone the function the existing partial_apply references. - PromotedParamCloner Cloner(F, Serialized, PromotedCalleeArgIndices, + PromotedParamCloner Cloner(FuncBuilder, F, Serialized, + PromotedCalleeArgIndices, ClonedName); Cloner.populateCloned(); ClonedFn = Cloner.getCloned(); @@ -839,6 +843,7 @@ static void rewritePartialApplies(AllocBoxToStackState &pass) { // Clone the referenced function of each partial_apply, removing the // operands that we will not need, and remove the existing // partial_apply. + SILOptFunctionBuilder FuncBuilder(*pass.T->getPassManager()); for (auto &It : IndexMap) { auto *PartialApply = It.first; auto &Indices = It.second; @@ -848,7 +853,7 @@ static void rewritePartialApplies(AllocBoxToStackState &pass) { Indices.erase(std::unique(Indices.begin(), Indices.end()), Indices.end()); PartialApplyInst *Replacement = - specializePartialApply(PartialApply, Indices, pass); + specializePartialApply(FuncBuilder, PartialApply, Indices, pass); PartialApply->replaceAllUsesWith(Replacement); auto *FRI = cast(PartialApply->getCallee()); diff --git a/lib/SILOptimizer/Transforms/GenericSpecializer.cpp b/lib/SILOptimizer/Transforms/GenericSpecializer.cpp index 9247c6d723ab8..6ef97e197713a 100644 --- a/lib/SILOptimizer/Transforms/GenericSpecializer.cpp +++ b/lib/SILOptimizer/Transforms/GenericSpecializer.cpp @@ -23,6 +23,7 @@ #include "swift/SILOptimizer/Utils/Generics.h" #include "swift/SILOptimizer/Utils/Local.h" #include "swift/SILOptimizer/PassManager/Transforms.h" +#include "swift/SILOptimizer/Utils/SILOptFunctionBuilder.h" #include "llvm/ADT/SmallVector.h" using namespace swift; @@ -48,6 +49,7 @@ class GenericSpecializer : public SILFunctionTransform { } // end anonymous namespace bool GenericSpecializer::specializeAppliesInFunction(SILFunction &F) { + SILOptFunctionBuilder FunctionBuilder(*getPassManager()); DeadInstructionSet DeadApplies; llvm::SmallSetVector Applies; OptRemark::Emitter ORE(DEBUG_TYPE, F.getModule()); @@ -101,7 +103,8 @@ bool GenericSpecializer::specializeAppliesInFunction(SILFunction &F) { // We have a call that can potentially be specialized, so // attempt to do so. llvm::SmallVector NewFunctions; - trySpecializeApplyOfGeneric(Apply, DeadApplies, NewFunctions, ORE); + trySpecializeApplyOfGeneric(FunctionBuilder, Apply, DeadApplies, + NewFunctions, ORE); // Remove all the now-dead applies. We must do this immediately // rather than defer it in order to avoid problems with cloning diff --git a/lib/SILOptimizer/Transforms/ObjectOutliner.cpp b/lib/SILOptimizer/Transforms/ObjectOutliner.cpp index b90c956295a28..998bfe41f8157 100644 --- a/lib/SILOptimizer/Transforms/ObjectOutliner.cpp +++ b/lib/SILOptimizer/Transforms/ObjectOutliner.cpp @@ -14,7 +14,7 @@ #include "swift/AST/ASTMangler.h" #include "swift/SIL/DebugUtils.h" #include "swift/SIL/SILBuilder.h" -#include "swift/SIL/SILFunctionBuilder.h" +#include "swift/SILOptimizer/Utils/SILOptFunctionBuilder.h" #include "swift/SILOptimizer/PassManager/Transforms.h" #include "swift/SILOptimizer/Utils/Local.h" #include "llvm/Support/Debug.h" @@ -23,6 +23,7 @@ using namespace swift; namespace { class ObjectOutliner { + SILOptFunctionBuilder &FunctionBuilder; NominalTypeDecl *ArrayDecl = nullptr; int GlobIdx = 0; @@ -46,7 +47,9 @@ class ObjectOutliner { void replaceFindStringCall(ApplyInst *FindStringCall); public: - ObjectOutliner(NominalTypeDecl *ArrayDecl) : ArrayDecl(ArrayDecl) { } + ObjectOutliner(SILOptFunctionBuilder &FunctionBuilder, + NominalTypeDecl *ArrayDecl) + : FunctionBuilder(FunctionBuilder), ArrayDecl(ArrayDecl) { } bool run(SILFunction *F); }; @@ -432,8 +435,7 @@ void ObjectOutliner::replaceFindStringCall(ApplyInst *FindStringCall) { return; SILDeclRef declRef(FD, SILDeclRef::Kind::Func); - SILFunctionBuilder builder(*Module); - SILFunction *replacementFunc = builder.getOrCreateFunction( + SILFunction *replacementFunc = FunctionBuilder.getOrCreateFunction( FindStringCall->getLoc(), declRef, NotForDefinition); SILFunctionType *FTy = replacementFunc->getLoweredFunctionType(); @@ -489,7 +491,9 @@ class ObjectOutlinerPass : public SILFunctionTransform { void run() override { SILFunction *F = getFunction(); - ObjectOutliner Outliner(F->getModule().getASTContext().getArrayDecl()); + SILOptFunctionBuilder FuncBuilder(*getPassManager()); + ObjectOutliner Outliner(FuncBuilder, + F->getModule().getASTContext().getArrayDecl()); if (Outliner.run(F)) { invalidateAnalysis(SILAnalysis::InvalidationKind::Instructions); } diff --git a/lib/SILOptimizer/Transforms/Outliner.cpp b/lib/SILOptimizer/Transforms/Outliner.cpp index a6264223c283f..87c0850fabb2e 100644 --- a/lib/SILOptimizer/Transforms/Outliner.cpp +++ b/lib/SILOptimizer/Transforms/Outliner.cpp @@ -23,7 +23,7 @@ #include "swift/SIL/SILArgument.h" #include "swift/SIL/SILBuilder.h" #include "swift/SIL/SILFunction.h" -#include "swift/SIL/SILFunctionBuilder.h" +#include "swift/SILOptimizer/Utils/SILOptFunctionBuilder.h" #include "swift/SIL/SILInstruction.h" #include "swift/SIL/SILModule.h" #include "swift/SILOptimizer/PassManager/Passes.h" @@ -103,8 +103,13 @@ std::string OutlinerMangler::mangle() { } namespace { + class OutlinePattern { +protected: + SILOptFunctionBuilder &FuncBuilder; + public: + OutlinePattern(SILOptFunctionBuilder &FuncBuilder) : FuncBuilder(FuncBuilder) {} /// Match the instruction sequence. virtual bool matchInstSequence(SILBasicBlock::iterator I) = 0; @@ -229,7 +234,7 @@ class BridgedProperty : public OutlinePattern { std::pair outline(SILModule &M) override; - BridgedProperty() { + BridgedProperty(SILOptFunctionBuilder &FuncBuilder) : OutlinePattern(FuncBuilder) { clearState(); } @@ -309,8 +314,7 @@ BridgedProperty::outline(SILModule &M) { std::string name = getOutlinedFunctionName(); - SILFunctionBuilder builder(M); - auto *Fun = builder.getOrCreateFunction( + auto *Fun = FuncBuilder.getOrCreateFunction( ObjCMethod->getLoc(), name, SILLinkage::Shared, FunctionType, IsNotBare, IsNotTransparent, IsSerializable); bool NeedsDefinition = Fun->empty(); @@ -891,6 +895,8 @@ class ObjCMethodCall : public OutlinePattern { std::pair outline(SILModule &M) override; + ObjCMethodCall(SILOptFunctionBuilder &FuncBuilder) + : OutlinePattern(FuncBuilder) {} ~ObjCMethodCall(); private: @@ -918,8 +924,7 @@ ObjCMethodCall::outline(SILModule &M) { auto FunctionType = getOutlinedFunctionType(M); std::string name = getOutlinedFunctionName(); - SILFunctionBuilder builder(M); - auto *Fun = builder.getOrCreateFunction( + auto *Fun = FuncBuilder.getOrCreateFunction( ObjCMethod->getLoc(), name, SILLinkage::Shared, FunctionType, IsNotBare, IsNotTransparent, IsSerializable); bool NeedsDefinition = Fun->empty(); @@ -1155,7 +1160,9 @@ class OutlinePatterns { return nullptr; } - OutlinePatterns() {} + OutlinePatterns(SILOptFunctionBuilder &FuncBuilder) + : BridgedPropertyPattern(FuncBuilder), + ObjCMethodCallPattern(FuncBuilder) {} ~OutlinePatterns() {} OutlinePatterns(const OutlinePatterns&) = delete; @@ -1166,11 +1173,11 @@ class OutlinePatterns { /// Perform outlining on the function and return any newly created outlined /// functions. -bool tryOutline(SILFunction *Fun, +bool tryOutline(SILOptFunctionBuilder &FuncBuilder, SILFunction *Fun, SmallVectorImpl &FunctionsAdded) { SmallPtrSet Visited; SmallVector Worklist; - OutlinePatterns patterns; + OutlinePatterns patterns(FuncBuilder); // Traverse the function. Worklist.push_back(&*Fun->begin()); @@ -1204,9 +1211,9 @@ bool tryOutline(SILFunction *Fun, } namespace { + class Outliner : public SILFunctionTransform { public: - Outliner() { } void run() override { @@ -1222,8 +1229,9 @@ class Outliner : public SILFunctionTransform { Fun->dump(); } + SILOptFunctionBuilder FuncBuilder(*getPassManager()); SmallVector FunctionsAdded; - bool Changed = tryOutline(Fun, FunctionsAdded); + bool Changed = tryOutline(FuncBuilder, Fun, FunctionsAdded); if (!FunctionsAdded.empty()) { // Notify the pass manager of any new functions we outlined. @@ -1232,11 +1240,12 @@ class Outliner : public SILFunctionTransform { } } - if (Changed) { + if (Changed) { invalidateAnalysis(SILAnalysis::InvalidationKind::Everything); - } + } } }; + } //end anonymous namespace. SILTransform *swift::createOutliner() { diff --git a/lib/SILOptimizer/Transforms/SimplifyCFG.cpp b/lib/SILOptimizer/Transforms/SimplifyCFG.cpp index 7b290557de15c..c30aa3776e026 100644 --- a/lib/SILOptimizer/Transforms/SimplifyCFG.cpp +++ b/lib/SILOptimizer/Transforms/SimplifyCFG.cpp @@ -26,6 +26,7 @@ #include "swift/SILOptimizer/PassManager/Transforms.h" #include "swift/SILOptimizer/Utils/CFG.h" #include "swift/SILOptimizer/Utils/CastOptimizer.h" +#include "swift/SILOptimizer/Utils/SILOptFunctionBuilder.h" #include "swift/SILOptimizer/Utils/Local.h" #include "swift/SILOptimizer/Utils/ConstantFolding.h" #include "swift/SILOptimizer/Utils/SILInliner.h" @@ -59,6 +60,7 @@ static unsigned MaxIterationsOfDominatorBasedSimplify = 10; namespace { class SimplifyCFG { + SILOptFunctionBuilder FuncBuilder; SILFunction &Fn; SILPassManager *PM; @@ -91,8 +93,8 @@ namespace { public: SimplifyCFG(SILFunction &Fn, SILPassManager *PM, bool Verify, bool EnableJumpThread) - : Fn(Fn), PM(PM), - ConstFolder(PM->getOptions().AssertConfig, + : FuncBuilder(*PM), Fn(Fn), PM(PM), + ConstFolder(FuncBuilder, PM->getOptions().AssertConfig, /* EnableDiagnostics */false, [&](SILInstruction *I) { constFoldingCallback(I); }), ShouldVerify(Verify), EnableJumpThread(EnableJumpThread) {} @@ -1917,7 +1919,8 @@ bool SimplifyCFG::simplifyCheckedCastBranchBlock(CheckedCastBranchInst *CCBI) { auto ThisBB = CCBI->getParent(); bool MadeChange = false; - CastOptimizer CastOpt([&MadeChange](SILInstruction *I, + CastOptimizer CastOpt(FuncBuilder, + [&MadeChange](SILInstruction *I, ValueBase *V) { /* ReplaceInstUsesAction */ MadeChange = true; }, @@ -1946,6 +1949,7 @@ bool SimplifyCFG::simplifyCheckedCastValueBranchBlock( bool MadeChange = false; CastOptimizer CastOpt( + FuncBuilder, [&MadeChange](SILInstruction *I, ValueBase *V) { /* ReplaceInstUsesAction */ MadeChange = true; @@ -1975,7 +1979,8 @@ simplifyCheckedCastAddrBranchBlock(CheckedCastAddrBranchInst *CCABI) { auto ThisBB = CCABI->getParent(); bool MadeChange = false; - CastOptimizer CastOpt([&MadeChange](SILInstruction *I, ValueBase *V) { + CastOptimizer CastOpt(FuncBuilder, + [&MadeChange](SILInstruction *I, ValueBase *V) { MadeChange = true; }, /* ReplaceInstUsesAction */ [&MadeChange](SILInstruction *I) { /* EraseInstAction */ diff --git a/lib/SILOptimizer/UtilityPasses/BugReducerTester.cpp b/lib/SILOptimizer/UtilityPasses/BugReducerTester.cpp index cbaa9daf2d471..4f4133c7c7a6d 100644 --- a/lib/SILOptimizer/UtilityPasses/BugReducerTester.cpp +++ b/lib/SILOptimizer/UtilityPasses/BugReducerTester.cpp @@ -19,7 +19,7 @@ #include "swift/SIL/SILBuilder.h" #include "swift/SIL/SILFunction.h" -#include "swift/SIL/SILFunctionBuilder.h" +#include "swift/SILOptimizer/Utils/SILOptFunctionBuilder.h" #include "swift/SIL/SILInstruction.h" #include "swift/SIL/SILLocation.h" #include "swift/SIL/SILUndef.h" @@ -89,8 +89,8 @@ class BugReducerTester : public SILFunctionTransform { ArrayRef(), ArrayRef(), ResultInfoArray, None, getFunction()->getModule().getASTContext()); - SILFunctionBuilder builder(getFunction()->getModule()); - SILFunction *F = builder.getOrCreateSharedFunction( + SILOptFunctionBuilder FunctionBuilder(*getPassManager()); + SILFunction *F = FunctionBuilder.getOrCreateSharedFunction( RegularLocation::getAutoGeneratedLocation(), RuntimeCrasherFunctionName, FuncType, IsBare, IsNotTransparent, IsSerialized, ProfileCounter(), IsNotThunk); diff --git a/lib/SILOptimizer/Utils/CastOptimizer.cpp b/lib/SILOptimizer/Utils/CastOptimizer.cpp index 53e2247fb95c4..85b3c6cc0a605 100644 --- a/lib/SILOptimizer/Utils/CastOptimizer.cpp +++ b/lib/SILOptimizer/Utils/CastOptimizer.cpp @@ -26,7 +26,7 @@ #include "swift/SIL/InstructionUtils.h" #include "swift/SIL/SILArgument.h" #include "swift/SIL/SILBuilder.h" -#include "swift/SIL/SILFunctionBuilder.h" +#include "swift/SILOptimizer/Utils/SILOptFunctionBuilder.h" #include "swift/SIL/SILModule.h" #include "swift/SIL/SILUndef.h" #include "swift/SIL/TypeLowering.h" @@ -90,8 +90,7 @@ SILInstruction *CastOptimizer::optimizeBridgedObjCToSwiftCast( SILDeclRef FuncDeclRef(BridgeFuncDecl, SILDeclRef::Kind::Func); // Lookup a function from the stdlib. - SILFunctionBuilder builder(M); - SILFunction *BridgedFunc = builder.getOrCreateFunction( + SILFunction *BridgedFunc = FunctionBuilder.getOrCreateFunction( Loc, FuncDeclRef, ForDefinition_t::NotForDefinition); if (!BridgedFunc) @@ -388,8 +387,7 @@ SILInstruction *CastOptimizer::optimizeBridgedSwiftToObjCCast( auto *resultDecl = Results.front(); auto MemberDeclRef = SILDeclRef(resultDecl); - SILFunctionBuilder builder(M); - auto *BridgedFunc = builder.getOrCreateFunction( + auto *BridgedFunc = FunctionBuilder.getOrCreateFunction( Loc, MemberDeclRef, ForDefinition_t::NotForDefinition); // Implementation of _bridgeToObjectiveC could not be found. diff --git a/lib/SILOptimizer/Utils/ConstantFolding.cpp b/lib/SILOptimizer/Utils/ConstantFolding.cpp index 7b6c34510be97..296eef85ff415 100644 --- a/lib/SILOptimizer/Utils/ConstantFolding.cpp +++ b/lib/SILOptimizer/Utils/ConstantFolding.cpp @@ -1471,9 +1471,8 @@ ConstantFolder::processWorkList() { // This is used to avoid duplicate error reporting in case we reach the same // instruction from different entry points in the WorkList. llvm::DenseSet ErrorSet; - llvm::SetVector FoldedUsers; - CastOptimizer CastOpt( + CastOptimizer CastOpt(FuncBuilder, [&](SingleValueInstruction *I, ValueBase *V) { /* ReplaceInstUsesAction */ InvalidateInstructions = true; diff --git a/lib/SILOptimizer/Utils/GenericCloner.cpp b/lib/SILOptimizer/Utils/GenericCloner.cpp index 08a0f2b3ff9cb..b6d6fe48aed20 100644 --- a/lib/SILOptimizer/Utils/GenericCloner.cpp +++ b/lib/SILOptimizer/Utils/GenericCloner.cpp @@ -15,7 +15,7 @@ #include "swift/AST/Type.h" #include "swift/SIL/SILBasicBlock.h" #include "swift/SIL/SILFunction.h" -#include "swift/SIL/SILFunctionBuilder.h" +#include "swift/SILOptimizer/Utils/SILOptFunctionBuilder.h" #include "swift/SIL/SILInstruction.h" #include "swift/SIL/SILModule.h" #include "swift/SIL/SILValue.h" @@ -26,7 +26,8 @@ using namespace swift; /// Create a new empty function with the correct arguments and a unique name. -SILFunction *GenericCloner::initCloned(SILFunction *Orig, +SILFunction *GenericCloner::initCloned(SILOptFunctionBuilder &FunctionBuilder, + SILFunction *Orig, IsSerialized_t Serialized, const ReabstractionInfo &ReInfo, StringRef NewName) { @@ -39,8 +40,7 @@ SILFunction *GenericCloner::initCloned(SILFunction *Orig, assert(!Orig->isGlobalInit() && "Global initializer cannot be cloned"); // Create a new empty function. - SILFunctionBuilder builder(Orig->getModule()); - SILFunction *NewF = builder.createFunction( + SILFunction *NewF = FunctionBuilder.createFunction( getSpecializedLinkage(Orig, Orig->getLinkage()), NewName, ReInfo.getSpecializedType(), ReInfo.getSpecializedGenericEnvironment(), Orig->getLocation(), Orig->isBare(), Orig->isTransparent(), Serialized, diff --git a/lib/SILOptimizer/Utils/Generics.cpp b/lib/SILOptimizer/Utils/Generics.cpp index 395eb5bcf6297..3c63feb69434e 100644 --- a/lib/SILOptimizer/Utils/Generics.cpp +++ b/lib/SILOptimizer/Utils/Generics.cpp @@ -20,7 +20,7 @@ #include "swift/SIL/DebugUtils.h" #include "swift/SIL/InstructionUtils.h" #include "swift/SIL/OptimizationRemark.h" -#include "swift/SIL/SILFunctionBuilder.h" +#include "swift/SILOptimizer/Utils/SILOptFunctionBuilder.h" #include "swift/SILOptimizer/Utils/GenericCloner.h" #include "swift/SILOptimizer/Utils/SpecializationMangler.h" #include "swift/Strings.h" @@ -1779,11 +1779,11 @@ ReabstractionInfo::ReabstractionInfo(SILFunction *Callee, // GenericFuncSpecializer // ============================================================================= -GenericFuncSpecializer::GenericFuncSpecializer(SILFunction *GenericFunc, - SubstitutionMap ParamSubs, - IsSerialized_t Serialized, - const ReabstractionInfo &ReInfo) - : M(GenericFunc->getModule()), +GenericFuncSpecializer::GenericFuncSpecializer( + SILOptFunctionBuilder &FuncBuilder, SILFunction *GenericFunc, + SubstitutionMap ParamSubs, IsSerialized_t Serialized, + const ReabstractionInfo &ReInfo) + : FuncBuilder(FuncBuilder), M(GenericFunc->getModule()), GenericFunc(GenericFunc), ParamSubs(ParamSubs), Serialized(Serialized), @@ -1848,7 +1848,7 @@ SILFunction *GenericFuncSpecializer::tryCreateSpecialization() { // Create a new function. SILFunction *SpecializedF = GenericCloner::cloneFunction( - GenericFunc, Serialized, ReInfo, + FuncBuilder, GenericFunc, Serialized, ReInfo, // Use these substitutions inside the new specialized function being // created. ReInfo.getClonerParamSubstitutionMap(), @@ -2034,7 +2034,9 @@ replaceWithSpecializedFunction(ApplySite AI, SILFunction *NewF, } namespace { + class ReabstractionThunkGenerator { + SILOptFunctionBuilder &FunctionBuilder; SILFunction *OrigF; SILModule &M; SILFunction *SpecializedFunc; @@ -2047,10 +2049,11 @@ class ReabstractionThunkGenerator { SmallVector Arguments; public: - ReabstractionThunkGenerator(const ReabstractionInfo &ReInfo, + ReabstractionThunkGenerator(SILOptFunctionBuilder &FunctionBuilder, + const ReabstractionInfo &ReInfo, PartialApplyInst *OrigPAI, SILFunction *SpecializedFunc) - : OrigF(OrigPAI->getCalleeFunction()), M(OrigF->getModule()), + : FunctionBuilder(FunctionBuilder), OrigF(OrigPAI->getCalleeFunction()), M(OrigF->getModule()), SpecializedFunc(SpecializedFunc), ReInfo(ReInfo), OrigPAI(OrigPAI), Loc(RegularLocation::getAutoGeneratedLocation()) { if (OrigF->isSerialized() && OrigPAI->getFunction()->isSerialized()) @@ -2082,8 +2085,7 @@ class ReabstractionThunkGenerator { } // anonymous namespace SILFunction *ReabstractionThunkGenerator::createThunk() { - SILFunctionBuilder builder(M); - SILFunction *Thunk = builder.getOrCreateSharedFunction( + SILFunction *Thunk = FunctionBuilder.getOrCreateSharedFunction( Loc, ThunkName, ReInfo.getSubstitutedType(), IsBare, IsTransparent, Serialized, ProfileCounter(), IsThunk); // Re-use an existing thunk. @@ -2249,6 +2251,7 @@ SILArgument *ReabstractionThunkGenerator::convertReabstractionThunkArguments( } void swift::trySpecializeApplyOfGeneric( + SILOptFunctionBuilder &FuncBuilder, ApplySite Apply, DeadInstructionSet &DeadApplies, llvm::SmallVectorImpl &NewFunctions, OptRemark::Emitter &ORE) { @@ -2329,7 +2332,8 @@ void swift::trySpecializeApplyOfGeneric( } } - GenericFuncSpecializer FuncSpecializer(RefF, Apply.getSubstitutionMap(), + GenericFuncSpecializer FuncSpecializer(FuncBuilder, + RefF, Apply.getSubstitutionMap(), Serialized, ReInfo); SILFunction *SpecializedF = FuncSpecializer.lookupSpecialization(); if (SpecializedF) { @@ -2373,7 +2377,7 @@ void swift::trySpecializeApplyOfGeneric( auto *PAI = cast(Apply.getInstruction()); SILBuilderWithScope Builder(PAI); SILFunction *Thunk = - ReabstractionThunkGenerator(ReInfo, PAI, SpecializedF).createThunk(); + ReabstractionThunkGenerator(FuncBuilder, ReInfo, PAI, SpecializedF).createThunk(); NewFunctions.push_back(Thunk); auto *FRI = Builder.createFunctionRef(PAI->getLoc(), Thunk); SmallVector Arguments;