mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
176 lines
5.7 KiB
C++
176 lines
5.7 KiB
C++
//===-------- Passes.cpp - Swift Compiler SIL Pass Entrypoints ------------===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
|
|
// Licensed under Apache License v2.0 with Runtime Library Exception
|
|
//
|
|
// See http://swift.org/LICENSE.txt for license information
|
|
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
///
|
|
/// \file
|
|
/// \brief This file provides implementations of a few helper functions
|
|
/// which provide abstracted entrypoints to the SILPasses stage.
|
|
///
|
|
/// \note The actual SIL passes should be implemented in per-pass source files,
|
|
/// not in this file.
|
|
///
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#define DEBUG_TYPE "sil-optimizer"
|
|
|
|
#include "swift/SILPasses/Passes.h"
|
|
#include "swift/SILPasses/PassManager.h"
|
|
#include "swift/SILPasses/Transforms.h"
|
|
#include "swift/SILAnalysis/Analysis.h"
|
|
#include "swift/AST/ASTContext.h"
|
|
#include "swift/AST/Module.h"
|
|
#include "swift/AST/SILOptions.h"
|
|
#include "swift/SIL/SILModule.h"
|
|
#include "llvm/ADT/Statistic.h"
|
|
#include "llvm/Support/Debug.h"
|
|
|
|
using namespace swift;
|
|
|
|
static void registerAnalysisPasses(SILPassManager &PM, SILModule *Mod) {
|
|
PM.registerAnalysis(createCallGraphAnalysis(Mod));
|
|
PM.registerAnalysis(createAliasAnalysis(Mod));
|
|
PM.registerAnalysis(createDominanceAnalysis(Mod));
|
|
}
|
|
|
|
bool swift::runSILDiagnosticPasses(SILModule &Module,
|
|
const SILOptions &Options) {
|
|
// If we parsed a .sil file that is already in canonical form, don't rerun
|
|
// the diagnostic passes.
|
|
if (Module.getStage() == SILStage::Canonical)
|
|
return false;
|
|
|
|
auto &Ctx = Module.getASTContext();
|
|
|
|
SILPassManager PM(&Module, Options);
|
|
registerAnalysisPasses(PM, &Module);
|
|
// 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());
|
|
if (Options.DebugSerialization) {
|
|
PM.run();
|
|
return Ctx.hadError();
|
|
}
|
|
|
|
// Otherwise run the rest of diagnostics.
|
|
PM.add(createCapturePromotion());
|
|
PM.add(createAllocBoxToStack());
|
|
PM.add(createInOutDeshadowing());
|
|
PM.add(createNoReturnFolding());
|
|
PM.add(createDefiniteInitialization());
|
|
PM.add(createPredictableMemoryOptimizations());
|
|
PM.add(createDiagnosticConstantPropagation());
|
|
PM.add(createDiagnoseUnreachable());
|
|
PM.add(createEmitDFDiagnostics());
|
|
PM.run();
|
|
|
|
// Generate diagnostics.
|
|
Module.setStage(SILStage::Canonical);
|
|
|
|
// If errors were produced during SIL analysis, return true.
|
|
return Ctx.hadError();
|
|
}
|
|
|
|
void ConstructSSAPassManager(SILPassManager &PM, SILModule &Module,
|
|
bool useEarlyInliner) {
|
|
|
|
registerAnalysisPasses(PM, &Module);
|
|
PM.add(createSimplifyCFG());
|
|
PM.add(createAllocBoxToStack());
|
|
PM.add(createLowerAggregate());
|
|
PM.add(createSILCombine());
|
|
PM.add(createSROA());
|
|
PM.add(createMem2Reg());
|
|
|
|
// Perform classsic SSA optimizations.
|
|
PM.add(createPerformanceConstantPropagation());
|
|
PM.add(createDCE());
|
|
PM.add(createCSE());
|
|
PM.add(createSILCombine());
|
|
PM.add(createSimplifyCFG());
|
|
|
|
// Perform retain/release code motion and run the first ARC optimizer.
|
|
PM.add(createLoadStoreOpts());
|
|
PM.add(createCodeMotion());
|
|
PM.add(createEnumSimplification());
|
|
PM.add(createGlobalARCOpts());
|
|
|
|
// Devirtualize.
|
|
PM.add(createDevirtualization());
|
|
PM.add(createGenericSpecializer());
|
|
PM.add(createSILLinker());
|
|
|
|
// Use either the early inliner that does not inline functions with defined
|
|
// semantics or the late performance inliner that inlines everything.
|
|
PM.add(useEarlyInliner ? createEarlyInliner() :createPerfInliner());
|
|
PM.add(createGlobalARCOpts());
|
|
}
|
|
|
|
|
|
void swift::runSILOptimizationPasses(SILModule &Module,
|
|
const SILOptions &Options) {
|
|
if (Options.DebugSerialization) {
|
|
SILPassManager PM(&Module, Options);
|
|
registerAnalysisPasses(PM, &Module);
|
|
PM.add(createSILLinker());
|
|
PM.run();
|
|
return;
|
|
}
|
|
|
|
// Start by specializing generics and by cloning functions from stdlib.
|
|
SILPassManager GenericsPM(&Module, Options);
|
|
registerAnalysisPasses(GenericsPM, &Module);
|
|
GenericsPM.add(createSILLinker());
|
|
GenericsPM.add(createGenericSpecializer());
|
|
GenericsPM.run();
|
|
|
|
// Construct SSA pass manager.
|
|
SILPassManager SSAPM(&Module, Options);
|
|
ConstructSSAPassManager(SSAPM, Module, false);
|
|
|
|
// Run three iteration of the SSA pass mananger.
|
|
SSAPM.runOneIteration();
|
|
SSAPM.runOneIteration();
|
|
SSAPM.runOneIteration();
|
|
|
|
// Perform lowering optimizations.
|
|
SILPassManager LoweringPM(&Module, Options);
|
|
registerAnalysisPasses(LoweringPM, &Module);
|
|
LoweringPM.add(createDeadFunctionElimination());
|
|
LoweringPM.add(createDeadObjectElimination());
|
|
|
|
// Hoist globals out of loops.
|
|
LoweringPM.add(createGlobalOpt());
|
|
|
|
// Insert inline caches for virtual calls.
|
|
LoweringPM.add(createDevirtualization());
|
|
LoweringPM.add(createInlineCaches());
|
|
LoweringPM.run();
|
|
|
|
// Run another iteration of the SSA optimizations to optimize the
|
|
// devirtualized inline caches.
|
|
SSAPM.invalidateAnalysis(SILAnalysis::InvalidationKind::All);
|
|
SSAPM.runOneIteration();
|
|
|
|
// Invalidate the SILLoader and allow it to drop references to SIL functions.
|
|
Module.invalidateSILLoader();
|
|
performSILElimination(&Module);
|
|
|
|
// Gather instruction counts if we are asked to do so.
|
|
if (Options.PrintInstCounts) {
|
|
SILPassManager PrinterPM(&Module, Options);
|
|
PrinterPM.add(createSILInstCount());
|
|
PrinterPM.runOneIteration();
|
|
}
|
|
|
|
DEBUG(Module.verify());
|
|
}
|