Skip to content

Commit 6613157

Browse files
committed
Debug Info: This patch implements the "emit modules when compiling -g"
proposal. When compiling with debug info, build a swiftmodule that contains all the type decls referenced by DWARF and emit it into a special __apple_swiftast section in the .o file. Swift SVN r7398
1 parent c79bb32 commit 6613157

File tree

11 files changed

+461
-8
lines changed

11 files changed

+461
-8
lines changed

include/swift/Subsystems.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,11 @@ namespace swift {
182182
void serialize(const TranslationUnit *TU, const char *outputPath,
183183
ArrayRef<unsigned> inputFileBufferIDs = {});
184184

185+
/// Serializes a translation unit to a stream.
186+
void serializeToStream(const TranslationUnit *TU, llvm::raw_ostream &out,
187+
ArrayRef<unsigned> inputFileBufferIDs = {});
188+
189+
185190
/// Turn the given translation unit into either LLVM IR or native code.
186191
///
187192
/// \param SILMod A SIL module to translate to LLVM IR. If null, IRGen works

lib/IRGen/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,7 @@ add_swift_library(swiftIRGen
2323
IRGenSIL.cpp
2424
Linking.cpp
2525
OptimizeARC.cpp
26+
SwiftASTStreamerPass.cpp
27+
SwiftTargetMachine.cpp
2628
StructLayout.cpp
2729
DEPENDS swiftAST)

lib/IRGen/IRGen.cpp

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
//
1515
//===----------------------------------------------------------------------===//
1616

17+
#include "SwiftTargetMachine.h"
1718
#include "swift/Subsystems.h"
1819
#include "swift/IRGen/Options.h"
1920
#include "swift/AST/AST.h"
@@ -103,7 +104,7 @@ void swift::performIRGeneration(Options &Opts, llvm::Module *Module,
103104
// TargetOpts.NoFramePointerElimNonLeaf = true;
104105

105106
// Create a target machine.
106-
TargetMachine *TargetMachine
107+
llvm::TargetMachine *TargetMachine
107108
= Target->createTargetMachine(Opts.Triple, /*cpu*/ "generic",
108109
/*features*/ "",
109110
TargetOpts, Reloc::Default,
@@ -300,13 +301,23 @@ void swift::performIRGeneration(Options &Opts, llvm::Module *Module,
300301
break;
301302
case OutputKind::NativeAssembly:
302303
case OutputKind::ObjectFile: {
303-
TargetMachine::CodeGenFileType FileType;
304+
llvm::TargetMachine::CodeGenFileType FileType;
304305
FileType = (Opts.OutputKind == OutputKind::NativeAssembly
305-
? TargetMachine::CGFT_AssemblyFile
306-
: TargetMachine::CGFT_ObjectFile);
307-
308-
if (TargetMachine->addPassesToEmitFile(EmitPasses, FormattedOS,
309-
FileType, !Opts.Verify)) {
306+
? llvm::TargetMachine::CGFT_AssemblyFile
307+
: llvm::TargetMachine::CGFT_ObjectFile);
308+
309+
bool fail;
310+
if (Opts.DebugInfo) {
311+
// Use our own wrapper for TargetMachine which schedules a
312+
// SwiftASTStreamerPass to be run after the code generation.
313+
swift::irgen::TargetMachine
314+
PatchedTargetMachine(TargetMachine, TU, IGM.DebugInfo);
315+
fail = PatchedTargetMachine.
316+
addPassesToEmitFile(EmitPasses, FormattedOS, FileType, !Opts.Verify);
317+
} else
318+
fail = TargetMachine->addPassesToEmitFile(EmitPasses, FormattedOS,
319+
FileType, !Opts.Verify);
320+
if (fail) {
310321
TU->Ctx.Diags.diagnose(SourceLoc(), diag::error_codegen_init_fail);
311322
return;
312323
}

lib/IRGen/IRGenDebugInfo.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ IRGenDebugInfo::IRGenDebugInfo(const Options &Opts,
100100
LastFn(nullptr), LastLoc({}), LastScope(nullptr) {
101101
assert(Opts.DebugInfo);
102102
StringRef Dir, Filename;
103-
StringRef MainFilename = Opts.MainInputFilename;
103+
MainFilename = Opts.MainInputFilename;
104104
if (MainFilename.empty()) {
105105
Filename = "<unknown>";
106106
Dir = getCurrentDirname();

lib/IRGen/IRGenDebugInfo.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ class IRGenDebugInfo {
8484
SILBasicBlock::const_bbarg_iterator LastArg, LastEnd;
8585
unsigned LastArgNo;
8686

87+
StringRef MainFilename;
8788
StringRef CWDName; /// The current working directory.
8889
llvm::BumpPtrAllocator DebugInfoNames;
8990
llvm::DICompileUnit TheCU;
@@ -175,6 +176,8 @@ class IRGenDebugInfo {
175176
DebugTypeInfo DebugType,
176177
SILLocation Loc);
177178

179+
StringRef getMainFilename() const { return MainFilename; }
180+
178181
private:
179182
llvm::DIType createType(DebugTypeInfo DbgTy, llvm::DIDescriptor Scope,
180183
llvm::DIFile File);

lib/IRGen/SwiftASTStreamerPass.cpp

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
//===--- SwiftASTStreamerPass.cpp - DWARF SwiftAST Streamer ---------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See http://swift.org/LICENSE.txt for license information
9+
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
//
13+
// This file implements the SwiftASTStreamerPass class.
14+
//
15+
//===----------------------------------------------------------------------===//
16+
17+
#include "SwiftASTStreamerPass.h"
18+
#include "IRGenDebugInfo.h"
19+
#include "swift/Subsystems.h"
20+
#include "llvm/MC/MCContext.h"
21+
#include "llvm/MC/MCSectionMachO.h"
22+
#include "llvm/MC/MCStreamer.h"
23+
24+
namespace swift {
25+
namespace irgen {
26+
27+
char SwiftASTStreamerPass::ID = 0;
28+
29+
bool SwiftASTStreamerPass::runOnModule(llvm::Module &M) {
30+
if (!DebugInfo)
31+
return false;
32+
33+
// FIXME (LLVM-Swift-branch). This shouldn't be hardcoded for Mach-O.
34+
auto SwiftASTSection = Context.
35+
getMachOSection("__DWARF", "__apple_swiftast",
36+
llvm::MCSectionMachO::S_ATTR_DEBUG,
37+
llvm::SectionKind::getMetadata());
38+
39+
AsmStreamer.SwitchSection(SwiftASTSection);
40+
std::string Buf;
41+
llvm::raw_string_ostream out(Buf);
42+
serializeToStream(TU, out);
43+
44+
StringRef ModuleID = DebugInfo->getMainFilename();
45+
AsmStreamer.EmitIntValue(ModuleID.size(), 8);
46+
AsmStreamer.EmitBytes(ModuleID);
47+
48+
// FIXME: There is a potential problem with using
49+
// MCStreamer::EmitBytes() for this, because (in the assembler
50+
// output) it will result in a .asciz directive, but the data
51+
// stream _will_ contain NUL characters.
52+
AsmStreamer.EmitIntValue(Buf.size(), 8);
53+
AsmStreamer.EmitBytes(Buf);
54+
return false;
55+
}
56+
57+
} // namespace irgen
58+
} // namespace swift

lib/IRGen/SwiftASTStreamerPass.h

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
//===--- SwiftASTStreamerPass.h - DWARF SwiftAST Streamer -------*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See http://swift.org/LICENSE.txt for license information
9+
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
//
13+
// This file implements the SwiftASTStreamerPass class.
14+
//
15+
//===----------------------------------------------------------------------===//
16+
17+
#ifndef SWIFT_IRGEN_SWIFTASTSTREAMERPASS
18+
#define SWIFT_IRGEN_SWIFTASTSTREAMERPASS
19+
20+
#include "llvm/Pass.h"
21+
22+
namespace llvm {
23+
class MCStreamer;
24+
class MCContext;
25+
}
26+
27+
namespace swift {
28+
29+
class TranslationUnit;
30+
31+
namespace irgen {
32+
class IRGenDebugInfo;
33+
34+
/// This pass builds a swiftmodule that contains all the decls
35+
/// referenced by DWARF and emit it into a special __apple_swiftast
36+
/// section in the .o file.
37+
class SwiftASTStreamerPass : public llvm::ModulePass {
38+
static char ID;
39+
llvm::MCStreamer &AsmStreamer;
40+
llvm::MCContext &Context;
41+
TranslationUnit *TU;
42+
IRGenDebugInfo *DebugInfo;
43+
public:
44+
SwiftASTStreamerPass(llvm::MCStreamer &S, llvm::MCContext &C,
45+
TranslationUnit *TU,
46+
IRGenDebugInfo *DI)
47+
: ModulePass(ID), AsmStreamer(S), Context(C), TU(TU), DebugInfo(DI) {}
48+
virtual const char *getPassName() const { return "SwiftASTStreamerPass"; }
49+
virtual bool runOnModule(llvm::Module &M);
50+
};
51+
52+
} // namespace irgen
53+
} // namespace swift
54+
55+
#endif

0 commit comments

Comments
 (0)