Files
swift-mirror/include/swift/SILOptimizer/PassManager/Transforms.h
Mark Lacey beb0f7dc2f Update pass manager execution strategy for function passes.
Allow function passes to:

1. Add new functions, to be optimized before continuing with the current
   function.
2. Restart the pipeline on the current function after the current pass
   completes.

This makes it possible to fully optimize callees that are the result of
specialization prior to generating interprocedural information or making
inlining choices about these callees.

It also allows us to solve a phase-ordering issue we have with generic
specialization, devirtualization, and inlining, by rescheduling the
current function after changes happen in one of these passes as opposed
to running all of these as part of the inlining pass as happens today.

Currently this is NFC since we have no passes that use this
functionality.
2016-02-01 16:47:26 -08:00

152 lines
4.4 KiB
C++

//===--- Transforms.h - Swift Transformations ------------------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 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
//
//===----------------------------------------------------------------------===//
#ifndef SWIFT_SILOPTIMIZER_PASSMANAGER_TRANSFORMS_H
#define SWIFT_SILOPTIMIZER_PASSMANAGER_TRANSFORMS_H
#include "swift/SIL/Notifications.h"
#include "swift/SILOptimizer/PassManager/PassManager.h"
namespace swift {
class SILModule;
class SILFunction;
class PrettyStackTraceSILFunctionTransform;
/// The base class for all SIL-level transformations.
class SILTransform : public DeleteNotificationHandler {
public:
/// The kind of transformation passes we use.
enum class TransformKind {
Function,
Module,
};
/// Stores the kind of derived class.
const TransformKind Kind;
protected:
// The pass manager that runs this pass.
SILPassManager* PM;
// The pass kind (used by the pass manager).
PassKind passKind = PassKind::invalidPassKind;
public:
/// C'tor. \p K indicates the kind of derived class.
SILTransform(SILTransform::TransformKind K) : Kind(K), PM(0) {}
/// D'tor.
virtual ~SILTransform() = default;
/// Returns the kind of derived class.
TransformKind getKind() const { return Kind; }
/// Returns the pass kind.
PassKind getPassKind() const {
assert(passKind != PassKind::invalidPassKind);
return passKind;
}
/// Sets the pass kind. This should only be done in the add-functions of
/// the pass manager.
void setPassKind(PassKind newPassKind) {
assert(passKind == PassKind::invalidPassKind);
passKind = newPassKind;
}
/// Inject the pass manager running this pass.
void injectPassManager(SILPassManager *PMM) { PM = PMM; }
/// Get the name of the transform.
virtual llvm::StringRef getName() = 0;
protected:
/// \brief Searches for an analysis of type T in the list of registered
/// analysis. If the analysis is not found, the program terminates.
template<typename T>
T* getAnalysis() { return PM->getAnalysis<T>(); }
const SILOptions &getOptions() { return PM->getOptions(); }
};
/// A transformation that operates on functions.
class SILFunctionTransform : public SILTransform {
friend class PrettyStackTraceSILFunctionTransform;
SILFunction *F;
public:
/// C'tor.
SILFunctionTransform() : SILTransform(TransformKind::Function), F(0) {}
/// The entry point to the transformation.
virtual void run() = 0;
static bool classof(const SILTransform *S) {
return S->getKind() == TransformKind::Function;
}
void injectFunction(SILFunction *Func) { F = Func; }
/// \brief Notify the pass manager of a function that needs to be
/// processed by the function passes.
void notifyPassManagerOfFunction(SILFunction *F) {
PM->addFunctionToWorklist(F);
}
/// \brief Reoptimize the current function by restarting the pass
/// pipeline on it.
void restartPassPipeline() { PM->restartWithCurrentFunction(this); }
protected:
SILFunction *getFunction() { return F; }
void invalidateAnalysis(SILAnalysis::InvalidationKind K) {
PM->invalidateAnalysis(F, K);
}
};
/// A transformation that operates on modules.
class SILModuleTransform : public SILTransform {
SILModule *M;
public:
/// C'tor.
SILModuleTransform() : SILTransform(TransformKind::Module), M(0) {}
/// The entry point to the transformation.
virtual void run() = 0;
static bool classof(const SILTransform *S) {
return S->getKind() == TransformKind::Module;
}
void injectModule(SILModule *Mod) { M = Mod; }
SILModule *getModule() { return M; }
/// Invalidate all of functions in the module, using invalidation
/// information \p K.
void invalidateAnalysis(SILAnalysis::InvalidationKind K) {
PM->invalidateAnalysis(K);
}
/// Invalidate only the function \p F, using invalidation information \p K.
void invalidateAnalysis(SILFunction *F, SILAnalysis::InvalidationKind K) {
PM->invalidateAnalysis(F, K);
}
};
} // end namespace swift
#endif