Skip to content

[IRGen] Introduce OptimizedIRRequest #32914

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Jul 16, 2020
56 changes: 45 additions & 11 deletions include/swift/AST/IRGenRequests.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,13 @@
#include "swift/AST/SimpleRequest.h"
#include "swift/Basic/PrimarySpecificPaths.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/Target/TargetMachine.h"

namespace swift {
class SourceFile;
class IRGenOptions;
class SILModule;
class SILOptions;
struct TBDGenOptions;

namespace irgen {
Expand All @@ -39,6 +41,7 @@ namespace llvm {
class GlobalVariable;
class LLVMContext;
class Module;
class TargetMachine;

namespace orc {
class ThreadSafeModule;
Expand All @@ -58,8 +61,9 @@ class GeneratedModule final {
private:
std::unique_ptr<llvm::LLVMContext> Context;
std::unique_ptr<llvm::Module> Module;
std::unique_ptr<llvm::TargetMachine> Target;

GeneratedModule() : Context(nullptr), Module(nullptr) {}
GeneratedModule() : Context(nullptr), Module(nullptr), Target(nullptr) {}

GeneratedModule(GeneratedModule const &) = delete;
GeneratedModule &operator=(GeneratedModule const &) = delete;
Expand All @@ -70,10 +74,13 @@ class GeneratedModule final {
/// The given pointers must not be null. If a null \c GeneratedModule is
/// needed, use \c GeneratedModule::null() instead.
explicit GeneratedModule(std::unique_ptr<llvm::LLVMContext> &&Context,
std::unique_ptr<llvm::Module> &&Module)
: Context(std::move(Context)), Module(std::move(Module)) {
std::unique_ptr<llvm::Module> &&Module,
std::unique_ptr<llvm::TargetMachine> &&Target)
: Context(std::move(Context)), Module(std::move(Module)),
Target(std::move(Target)) {
assert(getModule() && "Use GeneratedModule::null() instead");
assert(getContext() && "Use GeneratedModule::null() instead");
assert(getTargetMachine() && "Use GeneratedModule::null() instead");
}

GeneratedModule(GeneratedModule &&) = default;
Expand All @@ -97,6 +104,9 @@ class GeneratedModule final {
const llvm::LLVMContext *getContext() const { return Context.get(); }
llvm::LLVMContext *getContext() { return Context.get(); }

const llvm::TargetMachine *getTargetMachine() const { return Target.get(); }
llvm::TargetMachine *getTargetMachine() { return Target.get(); }

public:
/// Release ownership of the context and module to the caller, consuming
/// this value in the process.
Expand All @@ -114,12 +124,15 @@ class GeneratedModule final {
};

struct IRGenDescriptor {
llvm::PointerUnion<ModuleDecl *, SourceFile *> Ctx;
llvm::PointerUnion<FileUnit *, ModuleDecl *> Ctx;

const IRGenOptions &Opts;
const TBDGenOptions &TBDOpts;
const SILOptions &SILOpts;

Lowering::TypeConverter &Conv;
SILModule *SILMod;

StringRef ModuleName;
const PrimarySpecificPaths &PSPs;
StringRef PrivateDiscriminator;
Expand All @@ -142,14 +155,17 @@ struct IRGenDescriptor {

public:
static IRGenDescriptor
forFile(SourceFile &SF, const IRGenOptions &Opts,
const TBDGenOptions &TBDOpts, std::unique_ptr<SILModule> &&SILMod,
forFile(FileUnit *file, const IRGenOptions &Opts,
const TBDGenOptions &TBDOpts, const SILOptions &SILOpts,
Lowering::TypeConverter &Conv, std::unique_ptr<SILModule> &&SILMod,
StringRef ModuleName, const PrimarySpecificPaths &PSPs,
StringRef PrivateDiscriminator,
llvm::GlobalVariable **outModuleHash) {
return IRGenDescriptor{&SF,
llvm::GlobalVariable **outModuleHash = nullptr) {
return IRGenDescriptor{file,
Opts,
TBDOpts,
SILOpts,
Conv,
SILMod.release(),
ModuleName,
PSPs,
Expand All @@ -160,14 +176,17 @@ struct IRGenDescriptor {

static IRGenDescriptor
forWholeModule(ModuleDecl *M, const IRGenOptions &Opts,
const TBDGenOptions &TBDOpts,
const TBDGenOptions &TBDOpts, const SILOptions &SILOpts,
Lowering::TypeConverter &Conv,
std::unique_ptr<SILModule> &&SILMod, StringRef ModuleName,
const PrimarySpecificPaths &PSPs,
ArrayRef<std::string> parallelOutputFilenames,
llvm::GlobalVariable **outModuleHash) {
ArrayRef<std::string> parallelOutputFilenames = {},
llvm::GlobalVariable **outModuleHash = nullptr) {
return IRGenDescriptor{M,
Opts,
TBDOpts,
SILOpts,
Conv,
SILMod.release(),
ModuleName,
PSPs,
Expand Down Expand Up @@ -217,6 +236,21 @@ void simple_display(llvm::raw_ostream &out, const IRGenDescriptor &d);

SourceLoc extractNearestSourceLoc(const IRGenDescriptor &desc);

/// Returns the optimized IR for a given file or module. Note this runs the
/// entire compiler pipeline and ignores the passed SILModule.
class OptimizedIRRequest
: public SimpleRequest<OptimizedIRRequest, GeneratedModule(IRGenDescriptor),
RequestFlags::Uncached> {
public:
using SimpleRequest::SimpleRequest;

private:
friend SimpleRequest;

// Evaluation.
GeneratedModule evaluate(Evaluator &evaluator, IRGenDescriptor desc) const;
};

/// The zone number for IRGen.
#define SWIFT_TYPEID_ZONE IRGen
#define SWIFT_TYPEID_HEADER "swift/AST/IRGenTypeIDZone.def"
Expand Down
3 changes: 3 additions & 0 deletions include/swift/AST/IRGenTypeIDZone.def
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,6 @@
SWIFT_REQUEST(IRGen, IRGenRequest,
GeneratedModule(IRGenDescriptor),
Uncached, NoLocationInfo)
SWIFT_REQUEST(IRGen, OptimizedIRRequest,
GeneratedModule(IRGenDescriptor),
Uncached, NoLocationInfo)
23 changes: 14 additions & 9 deletions include/swift/Subsystems.h
Original file line number Diff line number Diff line change
Expand Up @@ -204,9 +204,8 @@ namespace swift {
std::string>
getIRTargetOptions(const IRGenOptions &Opts, ASTContext &Ctx);

/// Turn the given Swift module into either LLVM IR or native code
/// and return the generated LLVM IR module.
/// If you set an outModuleHash, then you need to call performLLVM.
/// Turn the given Swift module into LLVM IR and return the generated module.
/// To compile and output the generated code, call \c performLLVM.
GeneratedModule
performIRGeneration(ModuleDecl *M, const IRGenOptions &Opts,
const TBDGenOptions &TBDOpts,
Expand All @@ -215,11 +214,10 @@ namespace swift {
ArrayRef<std::string> parallelOutputFilenames,
llvm::GlobalVariable **outModuleHash = nullptr);

/// Turn the given Swift module into either LLVM IR or native code
/// and return the generated LLVM IR module.
/// If you set an outModuleHash, then you need to call performLLVM.
/// Turn the given Swift file into LLVM IR and return the generated module.
/// To compile and output the generated code, call \c performLLVM.
GeneratedModule
performIRGeneration(SourceFile &SF, const IRGenOptions &Opts,
performIRGeneration(FileUnit *file, const IRGenOptions &Opts,
const TBDGenOptions &TBDOpts,
std::unique_ptr<SILModule> SILMod,
StringRef ModuleName, const PrimarySpecificPaths &PSPs,
Expand All @@ -232,6 +230,15 @@ namespace swift {
void performLLVMOptimizations(const IRGenOptions &Opts, llvm::Module *Module,
llvm::TargetMachine *TargetMachine);

/// Compiles and writes the given LLVM module into an output stream in the
/// format specified in the \c IRGenOptions.
bool compileAndWriteLLVM(llvm::Module *module,
llvm::TargetMachine *targetMachine,
const IRGenOptions &opts,
UnifiedStatsReporter *stats, DiagnosticEngine &diags,
llvm::raw_pwrite_stream &out,
llvm::sys::Mutex *diagMutex = nullptr);

/// Wrap a serialized module inside a swift AST section in an object file.
void createSwiftModuleObjectFile(SILModule &SILMod, StringRef Buffer,
StringRef OutputPath);
Expand All @@ -251,15 +258,13 @@ namespace swift {
/// was already compiled, may be null if not desired.
/// \param Module LLVM module to code gen, required.
/// \param TargetMachine target of code gen, required.
/// \param effectiveLanguageVersion version of the language, effectively.
/// \param OutputFilename Filename for output.
bool performLLVM(const IRGenOptions &Opts,
DiagnosticEngine &Diags,
llvm::sys::Mutex *DiagMutex,
llvm::GlobalVariable *HashGlobal,
llvm::Module *Module,
llvm::TargetMachine *TargetMachine,
const version::Version &effectiveLanguageVersion,
StringRef OutputFilename,
UnifiedStatsReporter *Stats);

Expand Down
2 changes: 1 addition & 1 deletion lib/Basic/Version.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,7 @@ std::string getSwiftFullVersion(Version effectiveVersion) {
OS << "-dev";
#endif

if (!(effectiveVersion == Version::getCurrentLanguageVersion())) {
if (effectiveVersion != Version::getCurrentLanguageVersion()) {
OS << " effective-" << effectiveVersion;
}

Expand Down
8 changes: 3 additions & 5 deletions lib/FrontendTool/FrontendTool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1508,7 +1508,7 @@ generateIR(const IRGenOptions &IRGenOpts, const TBDGenOptions &TBDOpts,
llvm::GlobalVariable *&HashGlobal,
ArrayRef<std::string> parallelOutputFilenames) {
if (auto *SF = MSF.dyn_cast<SourceFile *>()) {
return performIRGeneration(*SF, IRGenOpts, TBDOpts,
return performIRGeneration(SF, IRGenOpts, TBDOpts,
std::move(SM), OutputFilename, PSPs,
SF->getPrivateDiscriminator().str(),
&HashGlobal);
Expand Down Expand Up @@ -1648,16 +1648,14 @@ static bool generateCode(CompilerInstance &Instance, StringRef OutputFilename,
const auto &opts = Instance.getInvocation().getIRGenOptions();
std::unique_ptr<llvm::TargetMachine> TargetMachine =
createTargetMachine(opts, Instance.getASTContext());
version::Version EffectiveLanguageVersion =
Instance.getASTContext().LangOpts.EffectiveLanguageVersion;

// Free up some compiler resources now that we have an IRModule.
freeASTContextIfPossible(Instance);

// Now that we have a single IR Module, hand it over to performLLVM.
return performLLVM(opts, Instance.getDiags(), nullptr, HashGlobal, IRModule,
TargetMachine.get(), EffectiveLanguageVersion,
OutputFilename, Instance.getStatsReporter());
TargetMachine.get(), OutputFilename,
Instance.getStatsReporter());
}

static bool performCompileStepsPostSILGen(CompilerInstance &Instance,
Expand Down
Loading