Skip to content

Commit 574b0f2

Browse files
committedMar 1, 2016
Introduce -fembed-bitcode driver option
Summary: This is the clang driver part of the change to embedded bitcode. This includes: 1. -fembed-bitcode option which breaks down the compilation into two stages. The first stage emits optimized bitcode and the second stage compiles bitcode into object file. 2. -fembed-bitcode-marker option which doesn't really break down to two stages to speedup the compilation flow. 3. pass the correct linker flag to darwin linker if tool chains supports embedded bitcode. Reviewers: rsmith, thakis Subscribers: thakis, cfe-commits Differential Revision: http://reviews.llvm.org/D17390 llvm-svn: 262282
1 parent da8cf8a commit 574b0f2

File tree

9 files changed

+126
-11
lines changed

9 files changed

+126
-11
lines changed
 

Diff for: ‎clang/include/clang/Basic/DiagnosticDriverKinds.td

+3-1
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,9 @@ def err_drv_omp_host_ir_file_not_found : Error<
134134
"The provided host compiler IR file '%0' is required to generate code for OpenMP target regions but cannot be found.">;
135135
def err_drv_omp_host_target_not_supported : Error<
136136
"The target '%0' is not a supported OpenMP host target.">;
137-
137+
def err_drv_bitcode_unsupported_on_toolchain : Error<
138+
"-fembed-bitcode is not supported on versions of iOS prior to 6.0">;
139+
138140
def warn_O4_is_O3 : Warning<"-O4 is equivalent to -O3">, InGroup<Deprecated>;
139141
def warn_drv_lto_libpath : Warning<"libLTO.dylib relative to clang installed dir not found; using 'ld' default search path instead">,
140142
InGroup<LibLTO>;

Diff for: ‎clang/include/clang/Driver/Driver.h

+9
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,12 @@ class Driver {
8383
SaveTempsObj
8484
} SaveTemps;
8585

86+
enum BitcodeEmbedMode {
87+
EmbedNone,
88+
EmbedMarker,
89+
EmbedBitcode
90+
} BitcodeEmbed;
91+
8692
/// LTO mode selected via -f(no-)?lto(=.*)? options.
8793
LTOKind LTOMode;
8894

@@ -262,6 +268,9 @@ class Driver {
262268
bool isSaveTempsEnabled() const { return SaveTemps != SaveTempsNone; }
263269
bool isSaveTempsObj() const { return SaveTemps == SaveTempsObj; }
264270

271+
bool embedBitcodeEnabled() const { return BitcodeEmbed == EmbedBitcode; }
272+
bool embedBitcodeMarkerOnly() const { return BitcodeEmbed == EmbedMarker; }
273+
265274
/// @}
266275
/// @name Primary Functionality
267276
/// @{

Diff for: ‎clang/include/clang/Driver/Options.td

+6
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,12 @@ def fno_autolink : Flag <["-"], "fno-autolink">, Group<f_Group>,
437437
Flags<[DriverOption, CC1Option]>,
438438
HelpText<"Disable generation of linker directives for automatic library linking">;
439439

440+
def fembed_bitcode : Flag<["-"], "fembed-bitcode">, Group<f_Group>,
441+
Flags<[CC1Option, CC1AsOption]>,
442+
HelpText<"Embed LLVM IR bitcode as data">;
443+
def fembed_bitcode_marker : Flag<["-"], "fembed-bitcode-marker">,
444+
Group<f_Group>, Flags<[CC1Option]>,
445+
HelpText<"Embed placeholder LLVM IR data as a marker">;
440446
def fgnu_inline_asm : Flag<["-"], "fgnu-inline-asm">, Group<f_Group>, Flags<[DriverOption]>;
441447
def fno_gnu_inline_asm : Flag<["-"], "fno-gnu-inline-asm">, Group<f_Group>,
442448
Flags<[DriverOption, CC1Option]>,

Diff for: ‎clang/include/clang/Driver/ToolChain.h

+5
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,11 @@ class ToolChain {
319319
return false;
320320
}
321321

322+
/// SupportsEmbeddedBitcode - Does this tool chain support embedded bitcode.
323+
virtual bool SupportsEmbeddedBitcode() const {
324+
return false;
325+
}
326+
322327
/// getThreadModel() - Which thread model does this target use?
323328
virtual std::string getThreadModel() const { return "posix"; }
324329

Diff for: ‎clang/lib/Driver/Driver.cpp

+36-10
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ Driver::Driver(StringRef ClangExecutable, StringRef DefaultTargetTriple,
5050
DiagnosticsEngine &Diags,
5151
IntrusiveRefCntPtr<vfs::FileSystem> VFS)
5252
: Opts(createDriverOptTable()), Diags(Diags), VFS(VFS), Mode(GCCMode),
53-
SaveTemps(SaveTempsNone), LTOMode(LTOK_None),
53+
SaveTemps(SaveTempsNone), BitcodeEmbed(EmbedNone), LTOMode(LTOK_None),
5454
ClangExecutable(ClangExecutable),
5555
SysRoot(DEFAULT_SYSROOT), UseStdLib(true),
5656
DefaultTargetTriple(DefaultTargetTriple),
@@ -479,6 +479,19 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) {
479479
.Default(SaveTempsCwd);
480480
}
481481

482+
// Ignore -fembed-bitcode options with LTO
483+
// since the output will be bitcode anyway.
484+
if (!Args.hasFlag(options::OPT_flto, options::OPT_fno_lto, false)) {
485+
if (Args.hasArg(options::OPT_fembed_bitcode))
486+
BitcodeEmbed = EmbedBitcode;
487+
else if (Args.hasArg(options::OPT_fembed_bitcode_marker))
488+
BitcodeEmbed = EmbedMarker;
489+
} else {
490+
// claim the bitcode option under LTO so no warning is issued.
491+
Args.ClaimAllArgs(options::OPT_fembed_bitcode);
492+
Args.ClaimAllArgs(options::OPT_fembed_bitcode_marker);
493+
}
494+
482495
setLTOMode(Args);
483496

484497
std::unique_ptr<llvm::opt::InputArgList> UArgs =
@@ -1723,7 +1736,8 @@ void Driver::BuildJobs(Compilation &C) const {
17231736
// CudaHostAction, updates CollapsedCHA with the pointer to it so the
17241737
// caller can deal with extra handling such action requires.
17251738
static const Tool *selectToolForJob(Compilation &C, bool SaveTemps,
1726-
const ToolChain *TC, const JobAction *JA,
1739+
bool EmbedBitcode, const ToolChain *TC,
1740+
const JobAction *JA,
17271741
const ActionList *&Inputs,
17281742
const CudaHostAction *&CollapsedCHA) {
17291743
const Tool *ToolForJob = nullptr;
@@ -1739,10 +1753,12 @@ static const Tool *selectToolForJob(Compilation &C, bool SaveTemps,
17391753
!C.getArgs().hasArg(options::OPT__SLASH_Fa) &&
17401754
isa<AssembleJobAction>(JA) && Inputs->size() == 1 &&
17411755
isa<BackendJobAction>(*Inputs->begin())) {
1742-
// A BackendJob is always preceded by a CompileJob, and without
1743-
// -save-temps they will always get combined together, so instead of
1744-
// checking the backend tool, check if the tool for the CompileJob
1745-
// has an integrated assembler.
1756+
// A BackendJob is always preceded by a CompileJob, and without -save-temps
1757+
// or -fembed-bitcode, they will always get combined together, so instead of
1758+
// checking the backend tool, check if the tool for the CompileJob has an
1759+
// integrated assembler. For -fembed-bitcode, CompileJob is still used to
1760+
// look up tools for BackendJob, but they need to match before we can split
1761+
// them.
17461762
const ActionList *BackendInputs = &(*Inputs)[0]->getInputs();
17471763
// Compile job may be wrapped in CudaHostAction, extract it if
17481764
// that's the case and update CollapsedCHA if we combine phases.
@@ -1753,6 +1769,14 @@ static const Tool *selectToolForJob(Compilation &C, bool SaveTemps,
17531769
const Tool *Compiler = TC->SelectTool(*CompileJA);
17541770
if (!Compiler)
17551771
return nullptr;
1772+
// When using -fembed-bitcode, it is required to have the same tool (clang)
1773+
// for both CompilerJA and BackendJA. Otherwise, combine two stages.
1774+
if (EmbedBitcode) {
1775+
JobAction *InputJA = cast<JobAction>(*Inputs->begin());
1776+
const Tool *BackendTool = TC->SelectTool(*InputJA);
1777+
if (BackendTool == Compiler)
1778+
CompileJA = InputJA;
1779+
}
17561780
if (Compiler->hasIntegratedAssembler()) {
17571781
Inputs = &CompileJA->getInputs();
17581782
ToolForJob = Compiler;
@@ -1761,8 +1785,8 @@ static const Tool *selectToolForJob(Compilation &C, bool SaveTemps,
17611785
}
17621786

17631787
// A backend job should always be combined with the preceding compile job
1764-
// unless OPT_save_temps is enabled and the compiler is capable of emitting
1765-
// LLVM IR as an intermediate output.
1788+
// unless OPT_save_temps or OPT_fembed_bitcode is enabled and the compiler is
1789+
// capable of emitting LLVM IR as an intermediate output.
17661790
if (isa<BackendJobAction>(JA)) {
17671791
// Check if the compiler supports emitting LLVM IR.
17681792
assert(Inputs->size() == 1);
@@ -1775,7 +1799,8 @@ static const Tool *selectToolForJob(Compilation &C, bool SaveTemps,
17751799
const Tool *Compiler = TC->SelectTool(*CompileJA);
17761800
if (!Compiler)
17771801
return nullptr;
1778-
if (!Compiler->canEmitIR() || !SaveTemps) {
1802+
if (!Compiler->canEmitIR() ||
1803+
(!SaveTemps && !EmbedBitcode)) {
17791804
Inputs = &CompileJA->getInputs();
17801805
ToolForJob = Compiler;
17811806
CollapsedCHA = CHA;
@@ -1889,7 +1914,8 @@ InputInfo Driver::BuildJobsForActionNoCache(
18891914
const JobAction *JA = cast<JobAction>(A);
18901915
const CudaHostAction *CollapsedCHA = nullptr;
18911916
const Tool *T =
1892-
selectToolForJob(C, isSaveTempsEnabled(), TC, JA, Inputs, CollapsedCHA);
1917+
selectToolForJob(C, isSaveTempsEnabled(), embedBitcodeEnabled(), TC, JA,
1918+
Inputs, CollapsedCHA);
18931919
if (!T)
18941920
return InputInfo();
18951921

Diff for: ‎clang/lib/Driver/ToolChains.cpp

+7
Original file line numberDiff line numberDiff line change
@@ -1103,6 +1103,13 @@ bool Darwin::UseSjLjExceptions(const ArgList &Args) const {
11031103
return !Triple.isWatchABI();
11041104
}
11051105

1106+
bool Darwin::SupportsEmbeddedBitcode() const {
1107+
assert(TargetInitialized && "Target not initialized!");
1108+
if (isTargetIPhoneOS() && isIPhoneOSVersionLT(6, 0))
1109+
return false;
1110+
return true;
1111+
}
1112+
11061113
bool MachO::isPICDefault() const { return true; }
11071114

11081115
bool MachO::isPIEDefault() const { return false; }

Diff for: ‎clang/lib/Driver/ToolChains.h

+2
Original file line numberDiff line numberDiff line change
@@ -542,6 +542,8 @@ class LLVM_LIBRARY_VISIBILITY Darwin : public MachO {
542542

543543
bool UseSjLjExceptions(const llvm::opt::ArgList &Args) const override;
544544

545+
bool SupportsEmbeddedBitcode() const override;
546+
545547
SanitizerMask getSupportedSanitizers() const override;
546548
};
547549

Diff for: ‎clang/lib/Driver/Tools.cpp

+20
Original file line numberDiff line numberDiff line change
@@ -3625,6 +3625,17 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
36253625
Args.AddLastArg(CmdArgs, options::OPT_fthinlto_index_EQ);
36263626
}
36273627

3628+
// Embed-bitcode option.
3629+
if (C.getDriver().embedBitcodeEnabled() &&
3630+
(isa<BackendJobAction>(JA) || isa<AssembleJobAction>(JA))) {
3631+
// Add flags implied by -fembed-bitcode.
3632+
CmdArgs.push_back("-fembed-bitcode");
3633+
// Disable all llvm IR level optimizations.
3634+
CmdArgs.push_back("-disable-llvm-optzns");
3635+
}
3636+
if (C.getDriver().embedBitcodeMarkerOnly())
3637+
CmdArgs.push_back("-fembed-bitcode-marker");
3638+
36283639
// We normally speed up the clang process a bit by skipping destructors at
36293640
// exit, but when we're generating diagnostics we can rely on some of the
36303641
// cleanup.
@@ -7262,6 +7273,15 @@ void darwin::Linker::AddLinkArgs(Compilation &C, const ArgList &Args,
72627273
else
72637274
CmdArgs.push_back("-no_pie");
72647275
}
7276+
// for embed-bitcode, use -bitcode_bundle in linker command
7277+
if (C.getDriver().embedBitcodeEnabled() ||
7278+
C.getDriver().embedBitcodeMarkerOnly()) {
7279+
// Check if the toolchain supports bitcode build flow.
7280+
if (MachOTC.SupportsEmbeddedBitcode())
7281+
CmdArgs.push_back("-bitcode_bundle");
7282+
else
7283+
D.Diag(diag::err_drv_bitcode_unsupported_on_toolchain);
7284+
}
72657285

72667286
Args.AddLastArg(CmdArgs, options::OPT_prebind);
72677287
Args.AddLastArg(CmdArgs, options::OPT_noprebind);

Diff for: ‎clang/test/Driver/embed-bitcode.c

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// RUN: %clang -ccc-print-bindings -c %s -fembed-bitcode 2>&1 | FileCheck %s
2+
// CHECK: clang
3+
// CHECK: clang
4+
5+
// RUN: %clang %s -fembed-bitcode 2>&1 -### | FileCheck %s -check-prefix=CHECK-CC
6+
// CHECK-CC: -cc1
7+
// CHECK-CC: -emit-llvm-bc
8+
// CHECK-CC: -cc1
9+
// CHECK-CC: -emit-obj
10+
// CHECK-CC: -fembed-bitcode
11+
// CHECK-CC: ld
12+
// CHECK-CC: -bitcode_bundle
13+
14+
// RUN: %clang %s -save-temps -fembed-bitcode 2>&1 -### | FileCheck %s -check-prefix=CHECK-SAVE-TEMP
15+
// CHECK-SAVE-TEMP: -cc1
16+
// CHECK-SAVE-TEMP: -E
17+
// CHECK-SAVE-TEMP: -cc1
18+
// CHECK-SAVE-TEMP: -emit-llvm-bc
19+
// CHECK-SAVE-TEMP: -cc1
20+
// CHECK-SAVE-TEMP: -S
21+
// CHECK-SAVE-TEMP: -fembed-bitcode
22+
// CHECK-SAVE-TEMP: -cc1as
23+
// CHECK-SAVE-TEMP: ld
24+
// CHECK-SAVE-TEMP: -bitcode_bundle
25+
26+
// RUN: %clang -c %s -flto -fembed-bitcode 2>&1 -### | FileCheck %s -check-prefix=CHECK-LTO
27+
// CHECK-LTO: -cc1
28+
// CHECK-LTO: -emit-llvm-bc
29+
// CHECK-LTO-NOT: warning: argument unused during compilation: '-fembed-bitcode'
30+
// CHECK-LTO-NOT: -cc1
31+
// CHECK-LTO-NOT: -fembed-bitcode
32+
33+
// RUN: %clang -c %s -fembed-bitcode-marker 2>&1 -### | FileCheck %s -check-prefix=CHECK-MARKER
34+
// CHECK-MARKER: -cc1
35+
// CHECK-MARKER: -emit-obj
36+
// CHECK-MARKER: -fembed-bitcode-marker
37+
// CHECK-MARKER-NOT: -cc1
38+

0 commit comments

Comments
 (0)
Please sign in to comment.