summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/Basic/DiagnosticDriverKinds.td4
-rw-r--r--clang/include/clang/Driver/Driver.h9
-rw-r--r--clang/include/clang/Driver/Options.td6
-rw-r--r--clang/include/clang/Driver/ToolChain.h5
-rw-r--r--clang/lib/Driver/Driver.cpp46
-rw-r--r--clang/lib/Driver/ToolChains.cpp7
-rw-r--r--clang/lib/Driver/ToolChains.h2
-rw-r--r--clang/lib/Driver/Tools.cpp20
-rw-r--r--clang/test/Driver/embed-bitcode.c38
9 files changed, 126 insertions, 11 deletions
diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index 4b232006660..c6e6eaf47cc 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -134,7 +134,9 @@ def err_drv_omp_host_ir_file_not_found : Error<
"The provided host compiler IR file '%0' is required to generate code for OpenMP target regions but cannot be found.">;
def err_drv_omp_host_target_not_supported : Error<
"The target '%0' is not a supported OpenMP host target.">;
-
+def err_drv_bitcode_unsupported_on_toolchain : Error<
+ "-fembed-bitcode is not supported on versions of iOS prior to 6.0">;
+
def warn_O4_is_O3 : Warning<"-O4 is equivalent to -O3">, InGroup<Deprecated>;
def warn_drv_lto_libpath : Warning<"libLTO.dylib relative to clang installed dir not found; using 'ld' default search path instead">,
InGroup<LibLTO>;
diff --git a/clang/include/clang/Driver/Driver.h b/clang/include/clang/Driver/Driver.h
index b6580456f41..ccf23e04696 100644
--- a/clang/include/clang/Driver/Driver.h
+++ b/clang/include/clang/Driver/Driver.h
@@ -83,6 +83,12 @@ class Driver {
SaveTempsObj
} SaveTemps;
+ enum BitcodeEmbedMode {
+ EmbedNone,
+ EmbedMarker,
+ EmbedBitcode
+ } BitcodeEmbed;
+
/// LTO mode selected via -f(no-)?lto(=.*)? options.
LTOKind LTOMode;
@@ -262,6 +268,9 @@ public:
bool isSaveTempsEnabled() const { return SaveTemps != SaveTempsNone; }
bool isSaveTempsObj() const { return SaveTemps == SaveTempsObj; }
+ bool embedBitcodeEnabled() const { return BitcodeEmbed == EmbedBitcode; }
+ bool embedBitcodeMarkerOnly() const { return BitcodeEmbed == EmbedMarker; }
+
/// @}
/// @name Primary Functionality
/// @{
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 8a22abcfdca..e05808eb513 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -437,6 +437,12 @@ def fno_autolink : Flag <["-"], "fno-autolink">, Group<f_Group>,
Flags<[DriverOption, CC1Option]>,
HelpText<"Disable generation of linker directives for automatic library linking">;
+def fembed_bitcode : Flag<["-"], "fembed-bitcode">, Group<f_Group>,
+ Flags<[CC1Option, CC1AsOption]>,
+ HelpText<"Embed LLVM IR bitcode as data">;
+def fembed_bitcode_marker : Flag<["-"], "fembed-bitcode-marker">,
+ Group<f_Group>, Flags<[CC1Option]>,
+ HelpText<"Embed placeholder LLVM IR data as a marker">;
def fgnu_inline_asm : Flag<["-"], "fgnu-inline-asm">, Group<f_Group>, Flags<[DriverOption]>;
def fno_gnu_inline_asm : Flag<["-"], "fno-gnu-inline-asm">, Group<f_Group>,
Flags<[DriverOption, CC1Option]>,
diff --git a/clang/include/clang/Driver/ToolChain.h b/clang/include/clang/Driver/ToolChain.h
index da0c40e8ad6..e093f633167 100644
--- a/clang/include/clang/Driver/ToolChain.h
+++ b/clang/include/clang/Driver/ToolChain.h
@@ -319,6 +319,11 @@ public:
return false;
}
+ /// SupportsEmbeddedBitcode - Does this tool chain support embedded bitcode.
+ virtual bool SupportsEmbeddedBitcode() const {
+ return false;
+ }
+
/// getThreadModel() - Which thread model does this target use?
virtual std::string getThreadModel() const { return "posix"; }
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 6a85dabdeb6..eaf29de2aaf 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -50,7 +50,7 @@ Driver::Driver(StringRef ClangExecutable, StringRef DefaultTargetTriple,
DiagnosticsEngine &Diags,
IntrusiveRefCntPtr<vfs::FileSystem> VFS)
: Opts(createDriverOptTable()), Diags(Diags), VFS(VFS), Mode(GCCMode),
- SaveTemps(SaveTempsNone), LTOMode(LTOK_None),
+ SaveTemps(SaveTempsNone), BitcodeEmbed(EmbedNone), LTOMode(LTOK_None),
ClangExecutable(ClangExecutable),
SysRoot(DEFAULT_SYSROOT), UseStdLib(true),
DefaultTargetTriple(DefaultTargetTriple),
@@ -479,6 +479,19 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) {
.Default(SaveTempsCwd);
}
+ // Ignore -fembed-bitcode options with LTO
+ // since the output will be bitcode anyway.
+ if (!Args.hasFlag(options::OPT_flto, options::OPT_fno_lto, false)) {
+ if (Args.hasArg(options::OPT_fembed_bitcode))
+ BitcodeEmbed = EmbedBitcode;
+ else if (Args.hasArg(options::OPT_fembed_bitcode_marker))
+ BitcodeEmbed = EmbedMarker;
+ } else {
+ // claim the bitcode option under LTO so no warning is issued.
+ Args.ClaimAllArgs(options::OPT_fembed_bitcode);
+ Args.ClaimAllArgs(options::OPT_fembed_bitcode_marker);
+ }
+
setLTOMode(Args);
std::unique_ptr<llvm::opt::InputArgList> UArgs =
@@ -1723,7 +1736,8 @@ void Driver::BuildJobs(Compilation &C) const {
// CudaHostAction, updates CollapsedCHA with the pointer to it so the
// caller can deal with extra handling such action requires.
static const Tool *selectToolForJob(Compilation &C, bool SaveTemps,
- const ToolChain *TC, const JobAction *JA,
+ bool EmbedBitcode, const ToolChain *TC,
+ const JobAction *JA,
const ActionList *&Inputs,
const CudaHostAction *&CollapsedCHA) {
const Tool *ToolForJob = nullptr;
@@ -1739,10 +1753,12 @@ static const Tool *selectToolForJob(Compilation &C, bool SaveTemps,
!C.getArgs().hasArg(options::OPT__SLASH_Fa) &&
isa<AssembleJobAction>(JA) && Inputs->size() == 1 &&
isa<BackendJobAction>(*Inputs->begin())) {
- // A BackendJob is always preceded by a CompileJob, and without
- // -save-temps they will always get combined together, so instead of
- // checking the backend tool, check if the tool for the CompileJob
- // has an integrated assembler.
+ // A BackendJob is always preceded by a CompileJob, and without -save-temps
+ // or -fembed-bitcode, they will always get combined together, so instead of
+ // checking the backend tool, check if the tool for the CompileJob has an
+ // integrated assembler. For -fembed-bitcode, CompileJob is still used to
+ // look up tools for BackendJob, but they need to match before we can split
+ // them.
const ActionList *BackendInputs = &(*Inputs)[0]->getInputs();
// Compile job may be wrapped in CudaHostAction, extract it if
// that's the case and update CollapsedCHA if we combine phases.
@@ -1753,6 +1769,14 @@ static const Tool *selectToolForJob(Compilation &C, bool SaveTemps,
const Tool *Compiler = TC->SelectTool(*CompileJA);
if (!Compiler)
return nullptr;
+ // When using -fembed-bitcode, it is required to have the same tool (clang)
+ // for both CompilerJA and BackendJA. Otherwise, combine two stages.
+ if (EmbedBitcode) {
+ JobAction *InputJA = cast<JobAction>(*Inputs->begin());
+ const Tool *BackendTool = TC->SelectTool(*InputJA);
+ if (BackendTool == Compiler)
+ CompileJA = InputJA;
+ }
if (Compiler->hasIntegratedAssembler()) {
Inputs = &CompileJA->getInputs();
ToolForJob = Compiler;
@@ -1761,8 +1785,8 @@ static const Tool *selectToolForJob(Compilation &C, bool SaveTemps,
}
// A backend job should always be combined with the preceding compile job
- // unless OPT_save_temps is enabled and the compiler is capable of emitting
- // LLVM IR as an intermediate output.
+ // unless OPT_save_temps or OPT_fembed_bitcode is enabled and the compiler is
+ // capable of emitting LLVM IR as an intermediate output.
if (isa<BackendJobAction>(JA)) {
// Check if the compiler supports emitting LLVM IR.
assert(Inputs->size() == 1);
@@ -1775,7 +1799,8 @@ static const Tool *selectToolForJob(Compilation &C, bool SaveTemps,
const Tool *Compiler = TC->SelectTool(*CompileJA);
if (!Compiler)
return nullptr;
- if (!Compiler->canEmitIR() || !SaveTemps) {
+ if (!Compiler->canEmitIR() ||
+ (!SaveTemps && !EmbedBitcode)) {
Inputs = &CompileJA->getInputs();
ToolForJob = Compiler;
CollapsedCHA = CHA;
@@ -1889,7 +1914,8 @@ InputInfo Driver::BuildJobsForActionNoCache(
const JobAction *JA = cast<JobAction>(A);
const CudaHostAction *CollapsedCHA = nullptr;
const Tool *T =
- selectToolForJob(C, isSaveTempsEnabled(), TC, JA, Inputs, CollapsedCHA);
+ selectToolForJob(C, isSaveTempsEnabled(), embedBitcodeEnabled(), TC, JA,
+ Inputs, CollapsedCHA);
if (!T)
return InputInfo();
diff --git a/clang/lib/Driver/ToolChains.cpp b/clang/lib/Driver/ToolChains.cpp
index a0fad02b6c6..6cc512b6a16 100644
--- a/clang/lib/Driver/ToolChains.cpp
+++ b/clang/lib/Driver/ToolChains.cpp
@@ -1103,6 +1103,13 @@ bool Darwin::UseSjLjExceptions(const ArgList &Args) const {
return !Triple.isWatchABI();
}
+bool Darwin::SupportsEmbeddedBitcode() const {
+ assert(TargetInitialized && "Target not initialized!");
+ if (isTargetIPhoneOS() && isIPhoneOSVersionLT(6, 0))
+ return false;
+ return true;
+}
+
bool MachO::isPICDefault() const { return true; }
bool MachO::isPIEDefault() const { return false; }
diff --git a/clang/lib/Driver/ToolChains.h b/clang/lib/Driver/ToolChains.h
index b956ac94052..aab4d337683 100644
--- a/clang/lib/Driver/ToolChains.h
+++ b/clang/lib/Driver/ToolChains.h
@@ -542,6 +542,8 @@ public:
bool UseSjLjExceptions(const llvm::opt::ArgList &Args) const override;
+ bool SupportsEmbeddedBitcode() const override;
+
SanitizerMask getSupportedSanitizers() const override;
};
diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp
index e5dbe9bae0c..a0fceb9672a 100644
--- a/clang/lib/Driver/Tools.cpp
+++ b/clang/lib/Driver/Tools.cpp
@@ -3625,6 +3625,17 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
Args.AddLastArg(CmdArgs, options::OPT_fthinlto_index_EQ);
}
+ // Embed-bitcode option.
+ if (C.getDriver().embedBitcodeEnabled() &&
+ (isa<BackendJobAction>(JA) || isa<AssembleJobAction>(JA))) {
+ // Add flags implied by -fembed-bitcode.
+ CmdArgs.push_back("-fembed-bitcode");
+ // Disable all llvm IR level optimizations.
+ CmdArgs.push_back("-disable-llvm-optzns");
+ }
+ if (C.getDriver().embedBitcodeMarkerOnly())
+ CmdArgs.push_back("-fembed-bitcode-marker");
+
// We normally speed up the clang process a bit by skipping destructors at
// exit, but when we're generating diagnostics we can rely on some of the
// cleanup.
@@ -7262,6 +7273,15 @@ void darwin::Linker::AddLinkArgs(Compilation &C, const ArgList &Args,
else
CmdArgs.push_back("-no_pie");
}
+ // for embed-bitcode, use -bitcode_bundle in linker command
+ if (C.getDriver().embedBitcodeEnabled() ||
+ C.getDriver().embedBitcodeMarkerOnly()) {
+ // Check if the toolchain supports bitcode build flow.
+ if (MachOTC.SupportsEmbeddedBitcode())
+ CmdArgs.push_back("-bitcode_bundle");
+ else
+ D.Diag(diag::err_drv_bitcode_unsupported_on_toolchain);
+ }
Args.AddLastArg(CmdArgs, options::OPT_prebind);
Args.AddLastArg(CmdArgs, options::OPT_noprebind);
diff --git a/clang/test/Driver/embed-bitcode.c b/clang/test/Driver/embed-bitcode.c
new file mode 100644
index 00000000000..6ac0d5478c5
--- /dev/null
+++ b/clang/test/Driver/embed-bitcode.c
@@ -0,0 +1,38 @@
+// RUN: %clang -ccc-print-bindings -c %s -fembed-bitcode 2>&1 | FileCheck %s
+// CHECK: clang
+// CHECK: clang
+
+// RUN: %clang %s -fembed-bitcode 2>&1 -### | FileCheck %s -check-prefix=CHECK-CC
+// CHECK-CC: -cc1
+// CHECK-CC: -emit-llvm-bc
+// CHECK-CC: -cc1
+// CHECK-CC: -emit-obj
+// CHECK-CC: -fembed-bitcode
+// CHECK-CC: ld
+// CHECK-CC: -bitcode_bundle
+
+// RUN: %clang %s -save-temps -fembed-bitcode 2>&1 -### | FileCheck %s -check-prefix=CHECK-SAVE-TEMP
+// CHECK-SAVE-TEMP: -cc1
+// CHECK-SAVE-TEMP: -E
+// CHECK-SAVE-TEMP: -cc1
+// CHECK-SAVE-TEMP: -emit-llvm-bc
+// CHECK-SAVE-TEMP: -cc1
+// CHECK-SAVE-TEMP: -S
+// CHECK-SAVE-TEMP: -fembed-bitcode
+// CHECK-SAVE-TEMP: -cc1as
+// CHECK-SAVE-TEMP: ld
+// CHECK-SAVE-TEMP: -bitcode_bundle
+
+// RUN: %clang -c %s -flto -fembed-bitcode 2>&1 -### | FileCheck %s -check-prefix=CHECK-LTO
+// CHECK-LTO: -cc1
+// CHECK-LTO: -emit-llvm-bc
+// CHECK-LTO-NOT: warning: argument unused during compilation: '-fembed-bitcode'
+// CHECK-LTO-NOT: -cc1
+// CHECK-LTO-NOT: -fembed-bitcode
+
+// RUN: %clang -c %s -fembed-bitcode-marker 2>&1 -### | FileCheck %s -check-prefix=CHECK-MARKER
+// CHECK-MARKER: -cc1
+// CHECK-MARKER: -emit-obj
+// CHECK-MARKER: -fembed-bitcode-marker
+// CHECK-MARKER-NOT: -cc1
+
OpenPOWER on IntegriCloud