Files
swift-mirror/include/swift/SILOptimizer/PassManager/Transforms.h
Andrew Trick 89985ebacd Use the pass's "tag" for command-line options.
A pass has an ID (C++ identifier), Tag (shell identifier),
and Name (human identifier).

Command line options that identify passes should obviously be compatibile with
with the pass' command line identifier. This is also what the user is used to
typing for the -debug-only option.
2017-07-06 14:10:23 -07:00

183 lines
5.6 KiB
C++

//===--- Transforms.h - Swift Transformations ------------------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 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_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; }
irgen::IRGenModule *getIRGenModule() {
auto *Mod = PM->getIRGenModule();
assert(Mod && "Expecting a valid module");
return Mod;
}
/// Get the name of the transform.
llvm::StringRef getName() { return PassKindName(getPassKind()); }
/// Get the transform's (command-line) tag.
llvm::StringRef getTag() { return PassKindTag(getPassKind()); }
/// Get the transform's name as a C++ identifier.
llvm::StringRef getID() { return PassKindID(getPassKind()); }
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 \p F that needs to be
/// processed by the function passes and the analyses.
///
/// If not null, the function \p DerivedFrom is the function from which \p F
/// is derived. This is used to limit the number of new functions which are
/// derived from a common base function, e.g. due to specialization.
/// The number should be small anyway, but bugs in optimizations could cause
/// an infinite loop in the passmanager.
void notifyAddFunction(SILFunction *F, SILFunction *DerivedFrom) {
PM->addFunctionToWorklist(F, DerivedFrom);
PM->notifyAnalysisOfFunction(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 analysis data for the whole module.
void invalidateAll() {
PM->invalidateAllAnalysis();
}
/// Invalidate only the function \p F, using invalidation information \p K.
void invalidateAnalysis(SILFunction *F, SILAnalysis::InvalidationKind K) {
PM->invalidateAnalysis(F, K);
}
/// Invalidate the analysis data for witness- and vtables.
void invalidateFunctionTables() {
PM->invalidateFunctionTables();
}
/// Inform the pass manager of a deleted function.
void notifyDeleteFunction(SILFunction *F) {
PM->notifyDeleteFunction(F);
}
/// Inform the pass manager of an added function.
void notifyAddFunction(SILFunction *F) {
PM->notifyAnalysisOfFunction(F);
}
};
} // end namespace swift
#endif