Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 118 additions & 0 deletions include/swift/AST/SILGenRequests.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
//===--- SILGenRequests.h - SILGen Requests ---------------------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2020 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
//
//===----------------------------------------------------------------------===//
//
// This file defines SILGen requests.
//
//===----------------------------------------------------------------------===//

#ifndef SWIFT_SILGEN_REQUESTS_H
#define SWIFT_SILGEN_REQUESTS_H

#include "swift/AST/ASTTypeIDs.h"
#include "swift/AST/SimpleRequest.h"

namespace swift {

class FileUnit;
class LangOptions;
class ModuleDecl;
class SILModule;
class SILOptions;
class SourceFile;

namespace Lowering {
class TypeConverter;
}

/// Report that a request of the given kind is being evaluated, so it
/// can be recorded by the stats reporter.
template<typename Request>
void reportEvaluatedRequest(UnifiedStatsReporter &stats,
const Request &request);

struct SILGenDescriptor {
llvm::PointerUnion<ModuleDecl *, FileUnit *> context;
Lowering::TypeConverter &conv;
const SILOptions &opts;

friend llvm::hash_code hash_value(const SILGenDescriptor &owner) {
return llvm::hash_combine(owner.context, (void *)&owner.conv,
(void *)&owner.opts);
}

friend bool operator==(const SILGenDescriptor &lhs,
const SILGenDescriptor &rhs) {
return lhs.context == rhs.context &&
&lhs.conv == &rhs.conv &&
&lhs.opts == &rhs.opts;
}

friend bool operator!=(const SILGenDescriptor &lhs,
const SILGenDescriptor &rhs) {
return !(lhs == rhs);
}

public:
static SILGenDescriptor forFile(FileUnit &sf, Lowering::TypeConverter &conv,
const SILOptions &opts) {
return SILGenDescriptor{&sf, conv, opts};
}

static SILGenDescriptor forWholeModule(ModuleDecl *mod,
Lowering::TypeConverter &conv,
const SILOptions &opts) {
return SILGenDescriptor{mod, conv, opts};
}
};

class GenerateSILRequest :
public SimpleRequest<GenerateSILRequest,
std::unique_ptr<SILModule>(SILGenDescriptor),
CacheKind::Uncached> {
public:
using SimpleRequest::SimpleRequest;

private:
friend SimpleRequest;

// Evaluation.
llvm::Expected<std::unique_ptr<SILModule>>
evaluate(Evaluator &evaluator, SILGenDescriptor desc) const;

public:
bool isCached() const { return true; }
};

void simple_display(llvm::raw_ostream &out, const SILGenDescriptor &d);

SourceLoc extractNearestSourceLoc(const SILGenDescriptor &desc);

/// The zone number for SILGen.
#define SWIFT_TYPEID_ZONE SILGen
#define SWIFT_TYPEID_HEADER "swift/AST/SILGenTypeIDZone.def"
#include "swift/Basic/DefineTypeIDZone.h"
#undef SWIFT_TYPEID_ZONE
#undef SWIFT_TYPEID_HEADER

// Set up reporting of evaluated requests.
#define SWIFT_REQUEST(Zone, RequestType, Sig, Caching, LocOptions) \
template<> \
inline void reportEvaluatedRequest(UnifiedStatsReporter &stats, \
const RequestType &request) { \
++stats.getFrontendCounters().RequestType; \
}
#include "swift/AST/SILGenTypeIDZone.def"
#undef SWIFT_REQUEST

} // end namespace swift

#endif // SWIFT_SILGEN_REQUESTS_H
19 changes: 19 additions & 0 deletions include/swift/AST/SILGenTypeIDZone.def
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//===--- SILGenTypeIDZone.def -----------------------------------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2020 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
//
//===----------------------------------------------------------------------===//
//
// This definition file describes the requests in SILGen's zone.
//
//===----------------------------------------------------------------------===//

SWIFT_REQUEST(SILGen, GenerateSILRequest,
std::unique_ptr<SILModule>(SILGenDescriptor),
Uncached, NoLocationInfo)
1 change: 1 addition & 0 deletions include/swift/Basic/CTypeIDZone.def
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ SWIFT_TYPEID_NAMED(std::string, String)

// C++ standard library types.
SWIFT_TYPEID_TEMPLATE1_NAMED(std::vector, Vector, typename T, T)
SWIFT_TYPEID_TEMPLATE1_NAMED(std::unique_ptr, UniquePtr, typename T, T)

// LLVM ADT types.
SWIFT_TYPEID_TEMPLATE1_NAMED(llvm::TinyPtrVector, TinyPtrVector, typename T, T)
Expand Down
4 changes: 4 additions & 0 deletions include/swift/Basic/Statistics.def
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,10 @@ FRONTEND_STATISTIC(Sema, NumUnloadedLazyIterableDeclContexts)
#include "swift/IDE/IDERequestIDZone.def"
#undef SWIFT_REQUEST

#define SWIFT_REQUEST(ZONE, NAME, Sig, Caching, LocOptions) FRONTEND_STATISTIC(SILGen, NAME)
#include "swift/AST/SILGenTypeIDZone.def"
#undef SWIFT_REQUEST

/// The next 10 statistics count 5 kinds of SIL entities present
/// after the SILGen and SILOpt phases. The entities are functions,
/// vtables, witness tables, default witness tables and global
Expand Down
1 change: 1 addition & 0 deletions include/swift/Basic/TypeID.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ enum class Zone : uint8_t {
NameLookup = 9,
Parse = 8,
TypeChecker = 10,
SILGen = 12,
// N.B. This is not a formal zone and exists solely to support the unit tests.
ArithmeticEvaluator = 255,
};
Expand Down
6 changes: 6 additions & 0 deletions include/swift/Subsystems.h
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,12 @@ namespace swift {
/// ASTContext.
void registerTypeCheckerRequestFunctions(Evaluator &evaluator);

/// Register SILGen-level request functions with the evaluator.
///
/// Clients that form an ASTContext and will perform any SIL generation
/// should call this functions after forming the ASTContext.
void registerSILGenRequestFunctions(Evaluator &evaluator);

/// Register IDE-level request functions with the evaluator.
///
/// The ASTContext will automatically call these upon construction.
Expand Down
1 change: 1 addition & 0 deletions lib/Frontend/Frontend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ bool CompilerInstance::setUpASTContextIfNeeded() {
Invocation.getSearchPathOptions(), SourceMgr, Diagnostics));
registerParseRequestFunctions(Context->evaluator);
registerTypeCheckerRequestFunctions(Context->evaluator);
registerSILGenRequestFunctions(Context->evaluator);

// Migrator, indexing and typo correction need some IDE requests.
// The integrated REPL needs IDE requests for completion.
Expand Down
1 change: 1 addition & 0 deletions lib/IDE/CompletionInstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ bool CompletionInstance::performCachedOperaitonIfPossible(
ASTContext::get(langOpts, typeckOpts, searchPathOpts, tmpSM, tmpDiags));
registerIDERequestFunctions(Ctx->evaluator);
registerTypeCheckerRequestFunctions(Ctx->evaluator);
registerSILGenRequestFunctions(Ctx->evaluator);
ModuleDecl *M = ModuleDecl::create(Identifier(), *Ctx);
PersistentParserState newState;
SourceFile *newSF =
Expand Down
1 change: 1 addition & 0 deletions lib/SILGen/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ add_swift_host_library(swiftSILGen STATIC
SILGenPattern.cpp
SILGenPoly.cpp
SILGenProlog.cpp
SILGenRequests.cpp
SILGenStmt.cpp
SILGenThunk.cpp
SILGenType.cpp)
Expand Down
19 changes: 17 additions & 2 deletions lib/SILGen/SILGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "SILGenFunctionBuilder.h"
#include "Scope.h"
#include "swift/AST/DiagnosticsSIL.h"
#include "swift/AST/Evaluator.h"
#include "swift/AST/GenericEnvironment.h"
#include "swift/AST/Initializer.h"
#include "swift/AST/NameLookup.h"
Expand All @@ -34,6 +35,7 @@
#include "swift/SIL/SILArgument.h"
#include "swift/SIL/SILDebugScope.h"
#include "swift/SIL/SILProfiler.h"
#include "swift/AST/SILGenRequests.h"
#include "swift/Serialization/SerializedModuleLoader.h"
#include "swift/Serialization/SerializedSILLoader.h"
#include "swift/Strings.h"
Expand Down Expand Up @@ -1752,11 +1754,24 @@ SILModule::constructSIL(ModuleDecl *mod, TypeConverter &tc,
std::unique_ptr<SILModule>
swift::performSILGeneration(ModuleDecl *mod, Lowering::TypeConverter &tc,
const SILOptions &options) {
return SILModule::constructSIL(mod, tc, options, nullptr);
auto desc = SILGenDescriptor::forWholeModule(mod, tc, options);
return llvm::cantFail(mod->getASTContext().evaluator(GenerateSILRequest{desc}));
}

std::unique_ptr<SILModule>
swift::performSILGeneration(FileUnit &sf, Lowering::TypeConverter &tc,
const SILOptions &options) {
return SILModule::constructSIL(sf.getParentModule(), tc, options, &sf);
auto desc = SILGenDescriptor::forFile(sf, tc, options);
return llvm::cantFail(sf.getASTContext().evaluator(GenerateSILRequest{desc}));
}

llvm::Expected<std::unique_ptr<SILModule>>
GenerateSILRequest::evaluate(Evaluator &evaluator, SILGenDescriptor sgd) const {
if (auto *MD = sgd.context.dyn_cast<ModuleDecl *>()) {
return SILModule::constructSIL(MD, sgd.conv, sgd.opts, nullptr);
} else {
auto *SF = sgd.context.get<FileUnit *>();
return SILModule::constructSIL(SF->getParentModule(),
sgd.conv, sgd.opts, SF);
}
}
72 changes: 72 additions & 0 deletions lib/SILGen/SILGenRequests.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
//===--- SILGenRequests.cpp - Requests for SIL Generation ----------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2020 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
//
//===----------------------------------------------------------------------===//

#include "swift/AST/SILGenRequests.h"
#include "swift/AST/ASTContext.h"
#include "swift/AST/Module.h"
#include "swift/AST/FileUnit.h"
#include "swift/AST/SourceFile.h"
#include "swift/SIL/SILModule.h"
#include "swift/Subsystems.h"

using namespace swift;

namespace swift {
// Implement the SILGen type zone (zone 12).
#define SWIFT_TYPEID_ZONE SILGen
#define SWIFT_TYPEID_HEADER "swift/AST/SILGenTypeIDZone.def"
#include "swift/Basic/ImplementTypeIDZone.h"
#undef SWIFT_TYPEID_ZONE
#undef SWIFT_TYPEID_HEADER
} // end namespace swift

void swift::simple_display(llvm::raw_ostream &out,
const SILGenDescriptor &desc) {
auto *MD = desc.context.dyn_cast<ModuleDecl *>();
auto *unit = desc.context.dyn_cast<FileUnit *>();
if (MD) {
out << "SIL Generation for module " << MD->getName();
} else {
assert(unit);
out << "SIL Generation for file ";
switch (unit->getKind()) {
case FileUnitKind::Source:
out << '\"' << cast<SourceFile>(unit)->getFilename() << '\"';
break;
case FileUnitKind::Builtin:
out << "(Builtin)";
break;
case FileUnitKind::DWARFModule:
case FileUnitKind::ClangModule:
case FileUnitKind::SerializedAST:
out << '\"' << cast<LoadedFile>(unit)->getFilename() << '\"';
break;
}
}
}

SourceLoc swift::extractNearestSourceLoc(const SILGenDescriptor &desc) {
return SourceLoc();
}

// Define request evaluation functions for each of the SILGen requests.
static AbstractRequestFunction *silGenRequestFunctions[] = {
#define SWIFT_REQUEST(Zone, Name, Sig, Caching, LocOptions) \
reinterpret_cast<AbstractRequestFunction *>(&Name::evaluateRequest),
#include "swift/AST/SILGenTypeIDZone.def"
#undef SWIFT_REQUEST
};

void swift::registerSILGenRequestFunctions(Evaluator &evaluator) {
evaluator.registerRequestFunctions(Zone::SILGen,
silGenRequestFunctions);
}