mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[deserialization] Deserialize transparent functions lazily iff they will be used in mandatory inlining.
Swift SVN r14490
This commit is contained in:
@@ -58,6 +58,9 @@ public:
|
|||||||
|
|
||||||
/// Stop optimizing after the Nth pass. For debugging purposes.
|
/// Stop optimizing after the Nth pass. For debugging purposes.
|
||||||
unsigned NumOptPassesToRun = UINT_MAX;
|
unsigned NumOptPassesToRun = UINT_MAX;
|
||||||
|
|
||||||
|
/// Are we debugging sil serialization.
|
||||||
|
bool DebugSerialization = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace swift
|
} // end namespace swift
|
||||||
|
|||||||
@@ -128,6 +128,10 @@ def sil_print_all : Flag<["-"], "sil-print-all">,
|
|||||||
def sil_time_transforms : Flag<["-"], "sil-time-transforms">,
|
def sil_time_transforms : Flag<["-"], "sil-time-transforms">,
|
||||||
HelpText<"Time each SIL transform invocation">;
|
HelpText<"Time each SIL transform invocation">;
|
||||||
|
|
||||||
|
def sil_debug_serialization : Flag<["-"], "sil-debug-serialization">,
|
||||||
|
HelpText<"Only run mandatory inlining and do not allow inlining to eliminate "
|
||||||
|
"dead functions. (for debugging only)">;
|
||||||
|
|
||||||
def use_malloc : Flag<["-"], "use-malloc">,
|
def use_malloc : Flag<["-"], "use-malloc">,
|
||||||
HelpText<"Allocate internal data structures using malloc "
|
HelpText<"Allocate internal data structures using malloc "
|
||||||
"(for memory debugging)">;
|
"(for memory debugging)">;
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
#include "swift/AST/ASTContext.h"
|
#include "swift/AST/ASTContext.h"
|
||||||
#include "swift/AST/Builtins.h"
|
#include "swift/AST/Builtins.h"
|
||||||
#include "swift/AST/Module.h"
|
#include "swift/AST/Module.h"
|
||||||
|
#include "swift/AST/SILOptions.h"
|
||||||
#include "swift/Basic/LangOptions.h"
|
#include "swift/Basic/LangOptions.h"
|
||||||
#include "swift/Basic/Range.h"
|
#include "swift/Basic/Range.h"
|
||||||
#include "swift/SIL/SILDeclRef.h"
|
#include "swift/SIL/SILDeclRef.h"
|
||||||
@@ -76,6 +77,7 @@ public:
|
|||||||
using GlobalListType = llvm::ilist<SILGlobalVariable>;
|
using GlobalListType = llvm::ilist<SILGlobalVariable>;
|
||||||
using VTableListType = llvm::ilist<SILVTable>;
|
using VTableListType = llvm::ilist<SILVTable>;
|
||||||
using WitnessTableListType = llvm::ilist<SILWitnessTable>;
|
using WitnessTableListType = llvm::ilist<SILWitnessTable>;
|
||||||
|
using LinkingMode = SILOptions::LinkingMode;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class SILBasicBlock;
|
friend class SILBasicBlock;
|
||||||
@@ -317,6 +319,13 @@ public:
|
|||||||
return FunctionTable.lookup(name);
|
return FunctionTable.lookup(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Attempt to link the SILFunction. Returns true if linking succeeded, false
|
||||||
|
/// otherwise.
|
||||||
|
///
|
||||||
|
/// \return false if the linking failed.
|
||||||
|
bool linkFunction(SILFunction *Fun,
|
||||||
|
LinkingMode LinkAll=LinkingMode::LinkNormal);
|
||||||
|
|
||||||
/// \brief Return the declaration of a utility function that can,
|
/// \brief Return the declaration of a utility function that can,
|
||||||
/// but needn't, be shared between modules.
|
/// but needn't, be shared between modules.
|
||||||
SILFunction *getOrCreateSharedFunction(SILLocation loc,
|
SILFunction *getOrCreateSharedFunction(SILLocation loc,
|
||||||
|
|||||||
@@ -17,8 +17,9 @@
|
|||||||
#ifndef SWIFT_SILPASSES_PASSES_H
|
#ifndef SWIFT_SILPASSES_PASSES_H
|
||||||
#define SWIFT_SILPASSES_PASSES_H
|
#define SWIFT_SILPASSES_PASSES_H
|
||||||
|
|
||||||
|
#include "swift/SIL/SILModule.h"
|
||||||
|
|
||||||
namespace swift {
|
namespace swift {
|
||||||
class SILModule;
|
|
||||||
class SILOptions;
|
class SILOptions;
|
||||||
class SILTransform;
|
class SILTransform;
|
||||||
|
|
||||||
@@ -51,7 +52,8 @@ namespace swift {
|
|||||||
SILTransform *createPredictableMemoryOptimizations();
|
SILTransform *createPredictableMemoryOptimizations();
|
||||||
SILTransform *createConstantPropagation();
|
SILTransform *createConstantPropagation();
|
||||||
SILTransform *createDCE();
|
SILTransform *createDCE();
|
||||||
SILTransform *createMandatoryInlining();
|
SILTransform *createMandatoryInlining(SILModule::LinkingMode Mode,
|
||||||
|
bool ShouldCleanup=true);
|
||||||
SILTransform *createSILCleanup();
|
SILTransform *createSILCleanup();
|
||||||
SILTransform *createEmitDFDiagnostics();
|
SILTransform *createEmitDFDiagnostics();
|
||||||
|
|
||||||
|
|||||||
@@ -647,6 +647,7 @@ static bool ParseSILArgs(SILOptions &Opts, ArgList &Args,
|
|||||||
Opts.VerifyAll = Args.hasArg(OPT_sil_verify_all);
|
Opts.VerifyAll = Args.hasArg(OPT_sil_verify_all);
|
||||||
Opts.PrintAll = Args.hasArg(OPT_sil_print_all);
|
Opts.PrintAll = Args.hasArg(OPT_sil_print_all);
|
||||||
Opts.TimeTransforms = Args.hasArg(OPT_sil_time_transforms);
|
Opts.TimeTransforms = Args.hasArg(OPT_sil_time_transforms);
|
||||||
|
Opts.DebugSerialization = Args.hasArg(OPT_sil_debug_serialization);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,8 +16,12 @@
|
|||||||
#include "swift/SIL/SILValue.h"
|
#include "swift/SIL/SILValue.h"
|
||||||
#include "llvm/ADT/FoldingSet.h"
|
#include "llvm/ADT/FoldingSet.h"
|
||||||
#include "llvm/ADT/StringSwitch.h"
|
#include "llvm/ADT/StringSwitch.h"
|
||||||
|
#include "llvm/ADT/Statistic.h"
|
||||||
|
#include "llvm/Support/Debug.h"
|
||||||
using namespace swift;
|
using namespace swift;
|
||||||
|
|
||||||
|
STATISTIC(NumFuncLinked, "Number of SIL functions linked");
|
||||||
|
|
||||||
namespace swift {
|
namespace swift {
|
||||||
/// SILTypeList - The uniqued backing store for the SILValue type list. This
|
/// SILTypeList - The uniqued backing store for the SILValue type list. This
|
||||||
/// is only exposed out of SILValue as an ArrayRef of types, so it should
|
/// is only exposed out of SILValue as an ArrayRef of types, so it should
|
||||||
@@ -243,3 +247,82 @@ const BuiltinInfo &SILModule::getBuiltinInfo(Identifier ID) {
|
|||||||
|
|
||||||
return Info;
|
return Info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SILModule::linkFunction(SILFunction *Fun, SILModule::LinkingMode Mode) {
|
||||||
|
// If we are not linking anything bail.
|
||||||
|
if (Mode == LinkingMode::LinkNone)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
bool LinkAll = Mode == LinkingMode::LinkAll;
|
||||||
|
// First attempt to link in Fun. If we fail, bail.
|
||||||
|
auto NewFn = SILLoader->lookupSILFunction(Fun);
|
||||||
|
if (!NewFn)
|
||||||
|
return false;
|
||||||
|
++NumFuncLinked;
|
||||||
|
|
||||||
|
// Ok, we succeeded in linking in Fun. Transitively link in the functions that
|
||||||
|
// Fun references.
|
||||||
|
SmallVector<SILFunction *, 128> Worklist;
|
||||||
|
Worklist.push_back(NewFn);
|
||||||
|
while (!Worklist.empty()) {
|
||||||
|
auto Fn = Worklist.pop_back_val();
|
||||||
|
|
||||||
|
for (auto &BB : *Fn)
|
||||||
|
for (auto I = BB.begin(), E = BB.end(); I != E; I++) {
|
||||||
|
SILFunction *CalleeFunction = nullptr;
|
||||||
|
bool TryLinking = false;
|
||||||
|
if (ApplyInst *AI = dyn_cast<ApplyInst>(I)) {
|
||||||
|
SILValue Callee = AI->getCallee();
|
||||||
|
// Handles FunctionRefInst only.
|
||||||
|
if (FunctionRefInst *FRI = dyn_cast<FunctionRefInst>(Callee.getDef())) {
|
||||||
|
CalleeFunction = FRI->getReferencedFunction();
|
||||||
|
// When EnableLinkAll is true, we always link the Callee.
|
||||||
|
TryLinking = LinkAll || AI->isTransparent() ||
|
||||||
|
CalleeFunction->getLinkage() == SILLinkage::Shared;
|
||||||
|
}
|
||||||
|
} else if (PartialApplyInst *PAI = dyn_cast<PartialApplyInst>(I)) {
|
||||||
|
SILValue Callee = PAI->getCallee();
|
||||||
|
// Handles FunctionRefInst only.
|
||||||
|
if (FunctionRefInst *FRI = dyn_cast<FunctionRefInst>(Callee.getDef())) {
|
||||||
|
CalleeFunction = FRI->getReferencedFunction();
|
||||||
|
// When EnableLinkAll is true, we always link the Callee.
|
||||||
|
TryLinking = LinkAll || CalleeFunction->isTransparent() ||
|
||||||
|
CalleeFunction->getLinkage() == SILLinkage::Shared;
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else if (FunctionRefInst *FRI = dyn_cast<FunctionRefInst>(I)) {
|
||||||
|
// When EnableLinkAll is true, we link the function referenced by
|
||||||
|
// FunctionRefInst.
|
||||||
|
CalleeFunction = LinkAll ? FRI->getReferencedFunction() :
|
||||||
|
nullptr;
|
||||||
|
TryLinking = LinkAll;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!CalleeFunction)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// The ExternalSource may wish to rewrite non-empty bodies.
|
||||||
|
if (ExternalSource)
|
||||||
|
if (auto NewFn = ExternalSource->lookupSILFunction(CalleeFunction)) {
|
||||||
|
Worklist.push_back(NewFn);
|
||||||
|
++NumFuncLinked;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
CalleeFunction->setBare(IsBare);
|
||||||
|
|
||||||
|
if (CalleeFunction->empty())
|
||||||
|
// Try to find the definition in a serialized module when callee is
|
||||||
|
// currently empty.
|
||||||
|
if (TryLinking)
|
||||||
|
if (auto NewFn = SILLoader->lookupSILFunction(CalleeFunction)) {
|
||||||
|
Worklist.push_back(NewFn);
|
||||||
|
++NumFuncLinked;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|||||||
@@ -201,7 +201,8 @@ cleanupCalleeValue(SILValue CalleeValue, ArrayRef<SILValue> CaptureArgs,
|
|||||||
static SILFunction *
|
static SILFunction *
|
||||||
getCalleeFunction(ApplyInst* AI, bool &IsThick,
|
getCalleeFunction(ApplyInst* AI, bool &IsThick,
|
||||||
SmallVectorImpl<SILValue>& CaptureArgs,
|
SmallVectorImpl<SILValue>& CaptureArgs,
|
||||||
SmallVectorImpl<SILValue>& FullArgs) {
|
SmallVectorImpl<SILValue>& FullArgs,
|
||||||
|
SILModule::LinkingMode Mode) {
|
||||||
if (!AI->isTransparent())
|
if (!AI->isTransparent())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
@@ -278,10 +279,17 @@ getCalleeFunction(ApplyInst* AI, bool &IsThick,
|
|||||||
assert(CalleeValue.getResultNumber() == 0);
|
assert(CalleeValue.getResultNumber() == 0);
|
||||||
|
|
||||||
SILFunction *CalleeFunction = FRI->getReferencedFunction();
|
SILFunction *CalleeFunction = FRI->getReferencedFunction();
|
||||||
if (!CalleeFunction || CalleeFunction->empty() ||
|
|
||||||
|
if (!CalleeFunction ||
|
||||||
(CalleeFunction->getAbstractCC() != AbstractCC::Freestanding &&
|
(CalleeFunction->getAbstractCC() != AbstractCC::Freestanding &&
|
||||||
CalleeFunction->getAbstractCC() != AbstractCC::Method))
|
CalleeFunction->getAbstractCC() != AbstractCC::Method))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
|
// If CalleeFunction is a declaration, see if we can load it. If we fail to
|
||||||
|
// load it, bail.
|
||||||
|
if (CalleeFunction->empty() && !AI->getModule().linkFunction(CalleeFunction,
|
||||||
|
Mode))
|
||||||
|
return nullptr;
|
||||||
return CalleeFunction;
|
return CalleeFunction;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -301,6 +309,7 @@ getCalleeFunction(ApplyInst* AI, bool &IsThick,
|
|||||||
/// \returns true if successful, false if failed due to circular inlining.
|
/// \returns true if successful, false if failed due to circular inlining.
|
||||||
static bool
|
static bool
|
||||||
runOnFunctionRecursively(SILFunction *F, ApplyInst* AI,
|
runOnFunctionRecursively(SILFunction *F, ApplyInst* AI,
|
||||||
|
SILModule::LinkingMode Mode,
|
||||||
DenseFunctionSet &FullyInlinedSet,
|
DenseFunctionSet &FullyInlinedSet,
|
||||||
ImmutableFunctionSet::Factory &SetFactory,
|
ImmutableFunctionSet::Factory &SetFactory,
|
||||||
ImmutableFunctionSet CurrentInliningSet) {
|
ImmutableFunctionSet CurrentInliningSet) {
|
||||||
@@ -318,7 +327,7 @@ runOnFunctionRecursively(SILFunction *F, ApplyInst* AI,
|
|||||||
diag::circular_transparent);
|
diag::circular_transparent);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add to the current inlining set (immutably, so we only affect the set
|
// Add to the current inlining set (immutably, so we only affect the set
|
||||||
// during this call and recursive subcalls).
|
// during this call and recursive subcalls).
|
||||||
CurrentInliningSet = SetFactory.add(CurrentInliningSet, F);
|
CurrentInliningSet = SetFactory.add(CurrentInliningSet, F);
|
||||||
@@ -339,15 +348,17 @@ runOnFunctionRecursively(SILFunction *F, ApplyInst* AI,
|
|||||||
SILValue CalleeValue = InnerAI->getCallee();
|
SILValue CalleeValue = InnerAI->getCallee();
|
||||||
bool IsThick;
|
bool IsThick;
|
||||||
SILFunction *CalleeFunction = getCalleeFunction(InnerAI, IsThick,
|
SILFunction *CalleeFunction = getCalleeFunction(InnerAI, IsThick,
|
||||||
CaptureArgs, FullArgs);
|
CaptureArgs, FullArgs,
|
||||||
|
Mode);
|
||||||
if (!CalleeFunction) {
|
if (!CalleeFunction) {
|
||||||
++I;
|
++I;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Then recursively process it first before trying to inline it.
|
// Then recursively process it first before trying to inline it.
|
||||||
if (!runOnFunctionRecursively(CalleeFunction, InnerAI, FullyInlinedSet,
|
if (!runOnFunctionRecursively(CalleeFunction, InnerAI, Mode,
|
||||||
SetFactory, CurrentInliningSet)) {
|
FullyInlinedSet, SetFactory,
|
||||||
|
CurrentInliningSet)) {
|
||||||
// If we failed due to circular inlining, then emit some notes to
|
// If we failed due to circular inlining, then emit some notes to
|
||||||
// trace back the failure if we have more information.
|
// trace back the failure if we have more information.
|
||||||
// FIXME: possibly it could be worth recovering and attempting other
|
// FIXME: possibly it could be worth recovering and attempting other
|
||||||
@@ -363,7 +374,7 @@ runOnFunctionRecursively(SILFunction *F, ApplyInst* AI,
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto *ApplyBlock = InnerAI->getParent();
|
auto *ApplyBlock = InnerAI->getParent();
|
||||||
|
|
||||||
// Inline function at I, which also changes I to refer to the first
|
// Inline function at I, which also changes I to refer to the first
|
||||||
// instruction inlined in the case that it succeeds. We purposely
|
// instruction inlined in the case that it succeeds. We purposely
|
||||||
// process the inlined body after inlining, because the inlining may
|
// process the inlined body after inlining, because the inlining may
|
||||||
@@ -420,52 +431,60 @@ runOnFunctionRecursively(SILFunction *F, ApplyInst* AI,
|
|||||||
// Top Level Driver
|
// Top Level Driver
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
static void performSILMandatoryInlining(SILModule *M) {
|
|
||||||
DenseFunctionSet FullyInlinedSet;
|
|
||||||
ImmutableFunctionSet::Factory SetFactory;
|
|
||||||
for (auto &F : *M)
|
|
||||||
runOnFunctionRecursively(&F, nullptr, FullyInlinedSet, SetFactory,
|
|
||||||
SetFactory.getEmptySet());
|
|
||||||
|
|
||||||
// Now that we've inlined some functions, clean up. If there are any
|
|
||||||
// transparent functions that are deserialized from another module that are
|
|
||||||
// now unused, just remove them from the module.
|
|
||||||
//
|
|
||||||
// We do this with a simple linear scan, because transparent functions that
|
|
||||||
// reference each other have already been flattened.
|
|
||||||
for (auto FI = M->begin(), E = M->end(); FI != E; ) {
|
|
||||||
SILFunction &F = *FI++;
|
|
||||||
|
|
||||||
if (F.getRefCount() != 0) continue;
|
|
||||||
|
|
||||||
// We can always remove transparent functions. We can also remove functions
|
|
||||||
// that came from closures.
|
|
||||||
if (!F.isTransparent() &&
|
|
||||||
(!F.hasLocation() || !F.getLocation().isASTNode<Expr>() ||
|
|
||||||
!F.getLocation().isASTNode<AbstractClosureExpr>()))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// We discard functions that don't have external linkage, e.g. deserialized
|
|
||||||
// functions, internal functions, and thunks. Being marked transparent
|
|
||||||
// controls this.
|
|
||||||
if (isPossiblyUsedExternally(F.getLinkage())) continue;
|
|
||||||
|
|
||||||
// Okay, just erase the function from the module.
|
|
||||||
M->getFunctionList().erase(&F);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class MandatoryInlining : public SILModuleTransform {
|
class MandatoryInlining : public SILModuleTransform {
|
||||||
|
SILModule::LinkingMode Mode;
|
||||||
|
bool ShouldCleanup;
|
||||||
|
public:
|
||||||
|
MandatoryInlining(SILModule::LinkingMode M, bool C) : SILModuleTransform(),
|
||||||
|
Mode(M),
|
||||||
|
ShouldCleanup(C) {}
|
||||||
|
private:
|
||||||
/// The entry point to the transformation.
|
/// The entry point to the transformation.
|
||||||
void run() {
|
void run() {
|
||||||
performSILMandatoryInlining(getModule());
|
SILModule *M = getModule();
|
||||||
|
DenseFunctionSet FullyInlinedSet;
|
||||||
|
ImmutableFunctionSet::Factory SetFactory;
|
||||||
|
for (auto &F : *M)
|
||||||
|
runOnFunctionRecursively(&F, nullptr, Mode, FullyInlinedSet, SetFactory,
|
||||||
|
SetFactory.getEmptySet());
|
||||||
|
|
||||||
|
if (!ShouldCleanup)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Now that we've inlined some functions, clean up. If there are any
|
||||||
|
// transparent functions that are deserialized from another module that are
|
||||||
|
// now unused, just remove them from the module.
|
||||||
|
//
|
||||||
|
// We do this with a simple linear scan, because transparent functions that
|
||||||
|
// reference each other have already been flattened.
|
||||||
|
for (auto FI = M->begin(), E = M->end(); FI != E; ) {
|
||||||
|
SILFunction &F = *FI++;
|
||||||
|
|
||||||
|
if (F.getRefCount() != 0) continue;
|
||||||
|
|
||||||
|
// We can always remove transparent functions. We can also remove functions
|
||||||
|
// that came from closures.
|
||||||
|
if (!F.isTransparent() &&
|
||||||
|
(!F.hasLocation() || !F.getLocation().isASTNode<Expr>() ||
|
||||||
|
!F.getLocation().isASTNode<AbstractClosureExpr>()))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// We discard functions that don't have external linkage, e.g. deserialized
|
||||||
|
// functions, internal functions, and thunks. Being marked transparent
|
||||||
|
// controls this.
|
||||||
|
if (isPossiblyUsedExternally(F.getLinkage())) continue;
|
||||||
|
|
||||||
|
// Okay, just erase the function from the module.
|
||||||
|
M->getFunctionList().erase(&F);
|
||||||
|
}
|
||||||
|
|
||||||
invalidateAnalysis(SILAnalysis::InvalidationKind::All);
|
invalidateAnalysis(SILAnalysis::InvalidationKind::All);
|
||||||
}
|
}
|
||||||
|
|
||||||
StringRef getName() override { return "Mandatory Inlining"; }
|
StringRef getName() override { return "Mandatory Inlining"; }
|
||||||
};
|
};
|
||||||
|
|
||||||
SILTransform *swift::createMandatoryInlining() {
|
SILTransform *swift::createMandatoryInlining(SILModule::LinkingMode Mode,
|
||||||
return new MandatoryInlining();
|
bool ShouldCleanup) {
|
||||||
|
return new MandatoryInlining(Mode, ShouldCleanup);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,7 +47,18 @@ bool swift::runSILDiagnosticPasses(SILModule &Module,
|
|||||||
PM.registerAnalysis(createCallGraphAnalysis(&Module));
|
PM.registerAnalysis(createCallGraphAnalysis(&Module));
|
||||||
PM.registerAnalysis(createAliasAnalysis(&Module));
|
PM.registerAnalysis(createAliasAnalysis(&Module));
|
||||||
PM.registerAnalysis(createDominanceAnalysis(&Module));
|
PM.registerAnalysis(createDominanceAnalysis(&Module));
|
||||||
PM.add(createMandatoryInlining());
|
|
||||||
|
// If we are asked do debug serialization, instead of running all diagnostic
|
||||||
|
// passes, just run mandatory inlining with dead transparent function cleanup
|
||||||
|
// disabled.
|
||||||
|
PM.add(createMandatoryInlining(Options.LinkMode,
|
||||||
|
!Options.DebugSerialization/*ShouldCleanup*/));
|
||||||
|
if (Options.DebugSerialization) {
|
||||||
|
PM.run();
|
||||||
|
return Ctx.hadError();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise run the rest of diagnostics.
|
||||||
PM.add(createCapturePromotion());
|
PM.add(createCapturePromotion());
|
||||||
PM.add(createAllocBoxToStack());
|
PM.add(createAllocBoxToStack());
|
||||||
PM.add(createInOutDeshadowing());
|
PM.add(createInOutDeshadowing());
|
||||||
|
|||||||
@@ -141,10 +141,6 @@ static bool performCompile(CompilerInstance &Instance,
|
|||||||
SM = performSILGeneration(*PrimarySourceFile);
|
SM = performSILGeneration(*PrimarySourceFile);
|
||||||
else
|
else
|
||||||
SM = performSILGeneration(Instance.getMainModule());
|
SM = performSILGeneration(Instance.getMainModule());
|
||||||
|
|
||||||
// Link in transparent functions.
|
|
||||||
if (Invocation.getSILOptions().LinkMode > SILOptions::LinkNone)
|
|
||||||
performSILLinking(SM.get(), false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// We've been told to emit SIL after SILGen, so write it now.
|
// We've been told to emit SIL after SILGen, so write it now.
|
||||||
|
|||||||
@@ -323,7 +323,7 @@ int main(int argc, char **argv) {
|
|||||||
PM.add(createInOutDeshadowing());
|
PM.add(createInOutDeshadowing());
|
||||||
break;
|
break;
|
||||||
case PassKind::MandatoryInlining:
|
case PassKind::MandatoryInlining:
|
||||||
PM.add(createMandatoryInlining());
|
PM.add(createMandatoryInlining(SILOpts.LinkMode));
|
||||||
break;
|
break;
|
||||||
case PassKind::PredictableMemoryOpt:
|
case PassKind::PredictableMemoryOpt:
|
||||||
PM.add(createPredictableMemoryOptimizations());
|
PM.add(createPredictableMemoryOptimizations());
|
||||||
|
|||||||
Reference in New Issue
Block a user