Skip to content

Commit 35bc2f3

Browse files
authored
Merge pull request #31167 from CodaFi/NSStream-beans
Lazily Associate a SILRemarkStreamer with an LLVMContext at IRGen time
2 parents c292b11 + db845eb commit 35bc2f3

File tree

6 files changed

+64
-17
lines changed

6 files changed

+64
-17
lines changed

include/swift/SIL/SILModule.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,7 @@ class SILModule {
523523
swift::SILRemarkStreamer *getSILRemarkStreamer() {
524524
return silRemarkStreamer.get();
525525
}
526+
526527
void installSILRemarkStreamer();
527528

528529
// This is currently limited to VarDecl because the visibility of global

include/swift/SIL/SILRemarkStreamer.h

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,20 @@ namespace swift {
2626

2727
class SILRemarkStreamer {
2828
private:
29-
/// The \c LLVMContext the underlying streamer uses for scratch space.
30-
std::unique_ptr<llvm::LLVMContext> streamerContext;
29+
enum class Owner {
30+
SILModule,
31+
LLVM,
32+
} owner;
33+
34+
/// The underlying LLVM streamer.
35+
///
36+
/// If owned by a SILModule, this will be non-null.
37+
std::unique_ptr<llvm::remarks::RemarkStreamer> streamer;
38+
/// The owning LLVM context.
39+
///
40+
/// If owned by LLVM, this will be non-null.
41+
llvm::LLVMContext *context;
42+
3143
/// The remark output stream used to record SIL remarks to a file.
3244
std::unique_ptr<llvm::raw_fd_ostream> remarkStream;
3345

@@ -53,6 +65,12 @@ class SILRemarkStreamer {
5365

5466
const ASTContext &getASTContext() const { return ctx; }
5567

68+
public:
69+
/// Perform a one-time ownership transfer to associate the underlying
70+
/// \c llvm::remarks::RemarkStreamer with the given \c LLVMContext.
71+
void intoLLVMContext(llvm::LLVMContext &Ctx) &;
72+
73+
public:
5674
/// Emit a remark through the streamer.
5775
template <typename RemarkT>
5876
void emit(const OptRemark::Remark<RemarkT> &remark);

lib/IRGen/IRGen.cpp

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include "swift/LLVMPasses/Passes.h"
3535
#include "swift/LLVMPasses/PassesFwd.h"
3636
#include "swift/SIL/SILModule.h"
37+
#include "swift/SIL/SILRemarkStreamer.h"
3738
#include "swift/SILOptimizer/PassManager/PassManager.h"
3839
#include "swift/SILOptimizer/PassManager/PassPipeline.h"
3940
#include "swift/SILOptimizer/PassManager/Passes.h"
@@ -884,7 +885,7 @@ static void embedBitcode(llvm::Module *M, const IRGenOptions &Opts)
884885
NewUsed->setSection("llvm.metadata");
885886
}
886887

887-
static void initLLVMModule(const IRGenModule &IGM, ModuleDecl &M) {
888+
static void initLLVMModule(const IRGenModule &IGM, SILModule &SIL) {
888889
auto *Module = IGM.getModule();
889890
assert(Module && "Expected llvm:Module for IR generation!");
890891

@@ -902,12 +903,17 @@ static void initLLVMModule(const IRGenModule &IGM, ModuleDecl &M) {
902903

903904
auto *MDNode = IGM.getModule()->getOrInsertNamedMetadata("swift.module.flags");
904905
auto &Context = IGM.getModule()->getContext();
905-
auto *Value = M.isStdlibModule() ? llvm::ConstantInt::getTrue(Context)
906-
: llvm::ConstantInt::getFalse(Context);
906+
auto *Value = SIL.getSwiftModule()->isStdlibModule()
907+
? llvm::ConstantInt::getTrue(Context)
908+
: llvm::ConstantInt::getFalse(Context);
907909
MDNode->addOperand(llvm::MDTuple::get(Context,
908910
{llvm::MDString::get(Context,
909911
"standard-library"),
910912
llvm::ConstantAsMetadata::get(Value)}));
913+
914+
if (auto *streamer = SIL.getSILRemarkStreamer()) {
915+
streamer->intoLLVMContext(Module->getContext());
916+
}
911917
}
912918

913919
std::pair<IRGenerator *, IRGenModule *>
@@ -926,7 +932,7 @@ swift::irgen::createIRGenModule(SILModule *SILMod, StringRef OutputFilename,
926932
*irgen, std::move(targetMachine), nullptr, "", OutputFilename,
927933
MainInputFilenameForDebugInfo, PrivateDiscriminator);
928934

929-
initLLVMModule(*IGM, *SILMod->getSwiftModule());
935+
initLLVMModule(*IGM, *SILMod);
930936

931937
return std::pair<IRGenerator *, IRGenModule *>(irgen, IGM);
932938
}
@@ -969,7 +975,7 @@ performIRGeneration(const IRGenOptions &Opts, ModuleDecl *M,
969975
PSPs.OutputFilename, PSPs.MainInputFilenameForDebugInfo,
970976
PrivateDiscriminator);
971977

972-
initLLVMModule(IGM, *SILMod->getSwiftModule());
978+
initLLVMModule(IGM, *SILMod);
973979

974980
// Run SIL level IRGen preparation passes.
975981
runIRGenPreparePasses(*SILMod, IGM);
@@ -1217,7 +1223,7 @@ static void performParallelIRGeneration(
12171223
nextSF->getPrivateDiscriminator().str());
12181224
IGMcreated = true;
12191225

1220-
initLLVMModule(*IGM, *SILMod->getSwiftModule());
1226+
initLLVMModule(*IGM, *SILMod);
12211227
if (!DidRunSILCodeGenPreparePasses) {
12221228
// Run SIL level IRGen preparation passes on the module the first time
12231229
// around.
@@ -1431,7 +1437,7 @@ swift::createSwiftModuleObjectFile(SILModule &SILMod, StringRef Buffer,
14311437

14321438
IRGenModule IGM(irgen, std::move(targetMachine), nullptr,
14331439
OutputPath, OutputPath, "", "");
1434-
initLLVMModule(IGM, *SILMod.getSwiftModule());
1440+
initLLVMModule(IGM, SILMod);
14351441
auto *Ty = llvm::ArrayType::get(IGM.Int8Ty, Buffer.size());
14361442
auto *Data =
14371443
llvm::ConstantDataArray::getString(IGM.getLLVMContext(),

lib/SIL/Utils/SILRemarkStreamer.cpp

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,35 @@ using namespace swift;
1919
SILRemarkStreamer::SILRemarkStreamer(
2020
std::unique_ptr<llvm::remarks::RemarkStreamer> &&streamer,
2121
std::unique_ptr<llvm::raw_fd_ostream> &&stream, const ASTContext &Ctx)
22-
: streamerContext(std::make_unique<llvm::LLVMContext>()),
23-
remarkStream(std::move(stream)), ctx(Ctx) {
24-
streamerContext->setMainRemarkStreamer(std::move(streamer));
25-
}
22+
: owner(Owner::SILModule), streamer(std::move(streamer)), context(nullptr),
23+
remarkStream(std::move(stream)), ctx(Ctx) { }
2624

2725
llvm::remarks::RemarkStreamer &SILRemarkStreamer::getLLVMStreamer() {
28-
return *streamerContext->getMainRemarkStreamer();
26+
switch (owner) {
27+
case Owner::SILModule:
28+
return *streamer.get();
29+
case Owner::LLVM:
30+
return *context->getMainRemarkStreamer();
31+
}
32+
return *streamer.get();
2933
}
3034

3135
const llvm::remarks::RemarkStreamer &
3236
SILRemarkStreamer::getLLVMStreamer() const {
33-
return *streamerContext->getMainRemarkStreamer();
37+
switch (owner) {
38+
case Owner::SILModule:
39+
return *streamer.get();
40+
case Owner::LLVM:
41+
return *context->getMainRemarkStreamer();
42+
}
43+
return *streamer.get();
44+
}
45+
46+
void SILRemarkStreamer::intoLLVMContext(llvm::LLVMContext &Ctx) & {
47+
assert(owner == Owner::SILModule);
48+
Ctx.setMainRemarkStreamer(std::move(streamer));
49+
context = &Ctx;
50+
owner = Owner::LLVM;
3451
}
3552

3653
std::unique_ptr<SILRemarkStreamer>

test/Driver/opt-record-bitstream.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
// RUN: %empty-directory(%t)
2-
// RUN: %target-swiftc_driver -O -wmo -save-optimization-record=bitstream %s -module-name optrecordmod -o %t/opt-record 2>&1 | %FileCheck -allow-empty %s
2+
// RUN: %target-swift-frontend -c -O -wmo -save-optimization-record=bitstream -save-optimization-record-path %t/optrecordmod.opt.bitstream %s -module-name optrecordmod -o %t/opt-record.o 2>&1 | %FileCheck -allow-empty %s
33
// RUN: llvm-bcanalyzer -dump %t/optrecordmod.opt.bitstream | %FileCheck -check-prefix=BITSTREAM %s
4+
// RUN: otool -l %t/opt-record.o | %FileCheck -check-prefix=OBJ %s
45

56
// REQUIRES: OS=macosx || OS=ios || OS=tvos || OS=watchos
67

8+
// Ensure we emitted the appropriate section
9+
10+
// OBJ: sectname __remarks
11+
712
// CHECK-NOT: remark
813

914
var a: Int = 1

tools/sil-opt/SILOpt.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,7 @@ int main(int argc, char **argv) {
461461
if (CI.getSILModule())
462462
CI.getSILModule()->setSerializeSILAction([]{});
463463

464-
if (RemarksFilename != "") {
464+
if (!RemarksFilename.empty()) {
465465
llvm::Expected<llvm::remarks::Format> formatOrErr =
466466
llvm::remarks::parseFormat(RemarksFormat);
467467
if (llvm::Error E = formatOrErr.takeError()) {

0 commit comments

Comments
 (0)