Skip to content

Commit 91a5ceb

Browse files
authored
Merge pull request swiftlang#29631 from CodaFi/irgen-bru
IRGen Requests
2 parents 5d37c9b + 52f4aba commit 91a5ceb

File tree

9 files changed

+316
-20
lines changed

9 files changed

+316
-20
lines changed

include/swift/AST/IRGenRequests.h

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
//===--- IRGenRequests.h - IRGen Requests -----------------------*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2020 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
//
13+
// This file defines IRGen requests.
14+
//
15+
//===----------------------------------------------------------------------===//
16+
17+
#ifndef SWIFT_IRGen_REQUESTS_H
18+
#define SWIFT_IRGen_REQUESTS_H
19+
20+
#include "swift/AST/ASTTypeIDs.h"
21+
#include "swift/AST/SimpleRequest.h"
22+
#include "swift/Basic/PrimarySpecificPaths.h"
23+
#include "llvm/ADT/StringSet.h"
24+
25+
namespace swift {
26+
class SourceFile;
27+
class IRGenOptions;
28+
class SILModule;
29+
30+
namespace irgen {
31+
class IRGenModule;
32+
};
33+
34+
}; // namespace swift
35+
36+
namespace llvm {
37+
class GlobalVariable;
38+
class LLVMContext;
39+
class Module;
40+
}; // namespace llvm
41+
42+
namespace swift {
43+
44+
struct IRGenDescriptor {
45+
const IRGenOptions &Opts;
46+
llvm::PointerUnion<ModuleDecl *, SourceFile *> Ctx;
47+
SILModule *SILMod;
48+
StringRef ModuleName;
49+
const PrimarySpecificPaths &PSPs;
50+
StringRef PrivateDiscriminator;
51+
llvm::LLVMContext &LLVMContext;
52+
ArrayRef<std::string> parallelOutputFilenames;
53+
llvm::GlobalVariable **outModuleHash;
54+
llvm::StringSet<> *LinkerDirectives;
55+
56+
friend llvm::hash_code hash_value(const IRGenDescriptor &owner) {
57+
return llvm::hash_combine(owner.Ctx);
58+
}
59+
60+
friend bool operator==(const IRGenDescriptor &lhs,
61+
const IRGenDescriptor &rhs) {
62+
return lhs.Ctx == rhs.Ctx;
63+
}
64+
65+
friend bool operator!=(const IRGenDescriptor &lhs,
66+
const IRGenDescriptor &rhs) {
67+
return !(lhs == rhs);
68+
}
69+
70+
public:
71+
static IRGenDescriptor
72+
forFile(const IRGenOptions &Opts, SourceFile &SF,
73+
std::unique_ptr<SILModule> &&SILMod, StringRef ModuleName,
74+
const PrimarySpecificPaths &PSPs, StringRef PrivateDiscriminator,
75+
llvm::LLVMContext &LLVMContext, llvm::GlobalVariable **outModuleHash,
76+
llvm::StringSet<> *LinkerDirectives) {
77+
return IRGenDescriptor{Opts,
78+
&SF,
79+
SILMod.release(),
80+
ModuleName,
81+
PSPs,
82+
PrivateDiscriminator,
83+
LLVMContext,
84+
{},
85+
outModuleHash,
86+
LinkerDirectives};
87+
}
88+
89+
static IRGenDescriptor
90+
forWholeModule(const IRGenOptions &Opts, swift::ModuleDecl *M,
91+
std::unique_ptr<SILModule> &&SILMod, StringRef ModuleName,
92+
const PrimarySpecificPaths &PSPs,
93+
llvm::LLVMContext &LLVMContext,
94+
ArrayRef<std::string> parallelOutputFilenames,
95+
llvm::GlobalVariable **outModuleHash,
96+
llvm::StringSet<> *LinkerDirectives) {
97+
return IRGenDescriptor{Opts,
98+
M,
99+
SILMod.release(),
100+
ModuleName,
101+
PSPs,
102+
"",
103+
LLVMContext,
104+
parallelOutputFilenames,
105+
outModuleHash,
106+
LinkerDirectives};
107+
}
108+
};
109+
110+
/// Report that a request of the given kind is being evaluated, so it
111+
/// can be recorded by the stats reporter.
112+
template<typename Request>
113+
void reportEvaluatedRequest(UnifiedStatsReporter &stats,
114+
const Request &request);
115+
116+
class IRGenSourceFileRequest
117+
: public SimpleRequest<IRGenSourceFileRequest,
118+
std::unique_ptr<llvm::Module>(IRGenDescriptor),
119+
CacheKind::Uncached> {
120+
public:
121+
using SimpleRequest::SimpleRequest;
122+
123+
private:
124+
friend SimpleRequest;
125+
126+
// Evaluation.
127+
llvm::Expected<std::unique_ptr<llvm::Module>>
128+
evaluate(Evaluator &evaluator, IRGenDescriptor desc) const;
129+
130+
public:
131+
bool isCached() const { return true; }
132+
};
133+
134+
class IRGenWholeModuleRequest
135+
: public SimpleRequest<IRGenWholeModuleRequest,
136+
std::unique_ptr<llvm::Module>(IRGenDescriptor),
137+
CacheKind::Uncached> {
138+
public:
139+
using SimpleRequest::SimpleRequest;
140+
141+
private:
142+
friend SimpleRequest;
143+
144+
// Evaluation.
145+
llvm::Expected<std::unique_ptr<llvm::Module>>
146+
evaluate(Evaluator &evaluator, IRGenDescriptor desc) const;
147+
148+
public:
149+
bool isCached() const { return true; }
150+
};
151+
152+
void simple_display(llvm::raw_ostream &out, const IRGenDescriptor &d);
153+
154+
SourceLoc extractNearestSourceLoc(const IRGenDescriptor &desc);
155+
156+
/// The zone number for IRGen.
157+
#define SWIFT_TYPEID_ZONE IRGen
158+
#define SWIFT_TYPEID_HEADER "swift/AST/IRGenTypeIDZone.def"
159+
#include "swift/Basic/DefineTypeIDZone.h"
160+
#undef SWIFT_TYPEID_ZONE
161+
#undef SWIFT_TYPEID_HEADER
162+
163+
// Set up reporting of evaluated requests.
164+
#define SWIFT_REQUEST(Zone, RequestType, Sig, Caching, LocOptions) \
165+
template<> \
166+
inline void reportEvaluatedRequest(UnifiedStatsReporter &stats, \
167+
const RequestType &request) { \
168+
++stats.getFrontendCounters().RequestType; \
169+
}
170+
#include "swift/AST/IRGenTypeIDZone.def"
171+
#undef SWIFT_REQUEST
172+
173+
} // end namespace swift
174+
175+
#endif // SWIFT_IRGen_REQUESTS_H

include/swift/AST/IRGenTypeIDZone.def

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//===--- IRGenTypeIDZone.def ------------------------------------*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2020 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
//
13+
// This definition file describes the requests in IRGen's zone.
14+
//
15+
//===----------------------------------------------------------------------===//
16+
17+
SWIFT_REQUEST(IRGen, IRGenSourceFileRequest,
18+
std::unique_ptr<llvm::Module>(IRGenDescriptor),
19+
Uncached, NoLocationInfo)
20+
SWIFT_REQUEST(IRGen, IRGenWholeModuleRequest,
21+
std::unique_ptr<llvm::Module>(IRGenDescriptor),
22+
Uncached, NoLocationInfo)
23+

include/swift/Basic/Statistics.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,10 @@ FRONTEND_STATISTIC(SILModule, NumSILOptWitnessTables)
290290
FRONTEND_STATISTIC(SILModule, NumSILOptDefaultWitnessTables)
291291
FRONTEND_STATISTIC(SILModule, NumSILOptGlobalVariables)
292292

293+
#define SWIFT_REQUEST(ZONE, NAME, Sig, Caching, LocOptions) FRONTEND_STATISTIC(IRGen, NAME)
294+
#include "swift/AST/IRGenTypeIDZone.def"
295+
#undef SWIFT_REQUEST
296+
293297
/// The next 10 statistics count kinds of LLVM entities produced
294298
/// during the IRGen phase: globals, functions, aliases, ifuncs,
295299
/// named metadata, value and comdat symbols, basic blocks,

include/swift/Basic/TypeID.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ enum class Zone : uint8_t {
4040
SILGen = 12,
4141
SILOptimizer = 13,
4242
TBDGen = 14,
43+
IRGen = 20,
44+
4345
// N.B. This is not a formal zone and exists solely to support the unit tests.
4446
ArithmeticEvaluator = 255,
4547
};

include/swift/Subsystems.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,12 @@ namespace swift {
373373
/// should call this functions after forming the ASTContext.
374374
void registerTBDGenRequestFunctions(Evaluator &evaluator);
375375

376+
/// Register IRGen-level request functions with the evaluator.
377+
///
378+
/// Clients that form an ASTContext and will perform any IR generation
379+
/// should call this functions after forming the ASTContext.
380+
void registerIRGenRequestFunctions(Evaluator &evaluator);
381+
376382
/// Register IDE-level request functions with the evaluator.
377383
///
378384
/// The ASTContext will automatically call these upon construction.

lib/Frontend/Frontend.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,8 @@ bool CompilerInstance::setUpASTContextIfNeeded() {
223223
registerSILGenRequestFunctions(Context->evaluator);
224224
registerSILOptimizerRequestFunctions(Context->evaluator);
225225
registerTBDGenRequestFunctions(Context->evaluator);
226-
226+
registerIRGenRequestFunctions(Context->evaluator);
227+
227228
// Migrator, indexing and typo correction need some IDE requests.
228229
// The integrated REPL needs IDE requests for completion.
229230
if (Invocation.getMigratorOptions().shouldRunMigrator() ||

lib/IRGen/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ add_swift_host_library(swiftIRGen STATIC
4242
IRGenMangler.cpp
4343
IRGenModule.cpp
4444
IRGenSILPasses.cpp
45+
IRGenRequests.cpp
4546
IRGenSIL.cpp
4647
Linking.cpp
4748
LoadableByAddress.cpp

lib/IRGen/IRGen.cpp

Lines changed: 42 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "IRGenModule.h"
1919
#include "swift/AST/DiagnosticsIRGen.h"
2020
#include "swift/AST/IRGenOptions.h"
21+
#include "swift/AST/IRGenRequests.h"
2122
#include "swift/AST/LinkLibrary.h"
2223
#include "swift/AST/ProtocolConformance.h"
2324
#include "swift/Basic/Defer.h"
@@ -968,7 +969,7 @@ performIRGeneration(const IRGenOptions &Opts, ModuleDecl *M,
968969

969970
// Run SIL level IRGen preparation passes.
970971
runIRGenPreparePasses(*SILMod, IGM);
971-
972+
972973
{
973974
FrontendStatsTracer tracer(Ctx.Stats, "IRGen");
974975

@@ -1353,25 +1354,36 @@ static void performParallelIRGeneration(
13531354
}
13541355

13551356
std::unique_ptr<llvm::Module> swift::performIRGeneration(
1356-
const IRGenOptions &Opts, swift::ModuleDecl *M, std::unique_ptr<SILModule> SILMod,
1357-
StringRef ModuleName, const PrimarySpecificPaths &PSPs,
1358-
llvm::LLVMContext &LLVMContext,
1357+
const IRGenOptions &Opts, swift::ModuleDecl *M,
1358+
std::unique_ptr<SILModule> SILMod, StringRef ModuleName,
1359+
const PrimarySpecificPaths &PSPs, llvm::LLVMContext &LLVMContext,
13591360
ArrayRef<std::string> parallelOutputFilenames,
1360-
llvm::GlobalVariable **outModuleHash,
1361-
llvm::StringSet<> *LinkerDirectives) {
1362-
if (SILMod->getOptions().shouldPerformIRGenerationInParallel() &&
1363-
!parallelOutputFilenames.empty()) {
1364-
auto NumThreads = SILMod->getOptions().NumThreads;
1365-
::performParallelIRGeneration(Opts, M, std::move(SILMod), ModuleName,
1366-
NumThreads, parallelOutputFilenames,
1367-
LinkerDirectives);
1361+
llvm::GlobalVariable **outModuleHash, llvm::StringSet<> *LinkerDirectives) {
1362+
auto desc = IRGenDescriptor::forWholeModule(
1363+
Opts, M, std::move(SILMod), ModuleName, PSPs, LLVMContext,
1364+
parallelOutputFilenames, outModuleHash, LinkerDirectives);
1365+
return llvm::cantFail(
1366+
M->getASTContext().evaluator(IRGenWholeModuleRequest{desc}));
1367+
}
1368+
1369+
llvm::Expected<std::unique_ptr<llvm::Module>>
1370+
IRGenWholeModuleRequest::evaluate(Evaluator &evaluator,
1371+
IRGenDescriptor desc) const {
1372+
auto *M = desc.Ctx.get<ModuleDecl *>();
1373+
if (desc.SILMod->getOptions().shouldPerformIRGenerationInParallel() &&
1374+
!desc.parallelOutputFilenames.empty()) {
1375+
const auto NumThreads = desc.SILMod->getOptions().NumThreads;
1376+
::performParallelIRGeneration(
1377+
desc.Opts, M, std::unique_ptr<SILModule>(desc.SILMod), desc.ModuleName,
1378+
NumThreads, desc.parallelOutputFilenames, desc.LinkerDirectives);
13681379
// TODO: Parallel LLVM compilation cannot be used if a (single) module is
13691380
// needed as return value.
13701381
return nullptr;
13711382
}
1372-
return ::performIRGeneration(Opts, M, std::move(SILMod), ModuleName, PSPs,
1373-
"", LLVMContext, nullptr,
1374-
outModuleHash, LinkerDirectives);
1383+
return ::performIRGeneration(
1384+
desc.Opts, M, std::unique_ptr<SILModule>(desc.SILMod), desc.ModuleName,
1385+
desc.PSPs, "", desc.LLVMContext, nullptr, desc.outModuleHash,
1386+
desc.LinkerDirectives);
13751387
}
13761388

13771389
std::unique_ptr<llvm::Module> swift::
@@ -1382,10 +1394,21 @@ performIRGeneration(const IRGenOptions &Opts, SourceFile &SF,
13821394
llvm::LLVMContext &LLVMContext,
13831395
llvm::GlobalVariable **outModuleHash,
13841396
llvm::StringSet<> *LinkerDirectives) {
1385-
return ::performIRGeneration(Opts, SF.getParentModule(), std::move(SILMod),
1386-
ModuleName, PSPs, PrivateDiscriminator,
1387-
LLVMContext, &SF,
1388-
outModuleHash, LinkerDirectives);
1397+
auto desc = IRGenDescriptor::forFile(Opts, SF, std::move(SILMod), ModuleName,
1398+
PSPs, PrivateDiscriminator, LLVMContext,
1399+
outModuleHash, LinkerDirectives);
1400+
return llvm::cantFail(
1401+
SF.getASTContext().evaluator(IRGenSourceFileRequest{desc}));
1402+
}
1403+
1404+
llvm::Expected<std::unique_ptr<llvm::Module>>
1405+
IRGenSourceFileRequest::evaluate(Evaluator &evaluator,
1406+
IRGenDescriptor desc) const {
1407+
auto *SF = desc.Ctx.get<SourceFile *>();
1408+
return ::performIRGeneration(
1409+
desc.Opts, SF->getParentModule(), std::unique_ptr<SILModule>(desc.SILMod),
1410+
desc.ModuleName, desc.PSPs, desc.PrivateDiscriminator, desc.LLVMContext,
1411+
SF, desc.outModuleHash, desc.LinkerDirectives);
13891412
}
13901413

13911414
void

0 commit comments

Comments
 (0)