diff options
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/include/clang/Basic/DiagnosticDriverKinds.td | 4 | ||||
| -rw-r--r-- | clang/include/clang/Driver/Driver.h | 9 | ||||
| -rw-r--r-- | clang/include/clang/Driver/Options.td | 6 | ||||
| -rw-r--r-- | clang/include/clang/Driver/ToolChain.h | 5 | ||||
| -rw-r--r-- | clang/lib/Driver/Driver.cpp | 46 | ||||
| -rw-r--r-- | clang/lib/Driver/ToolChains.cpp | 7 | ||||
| -rw-r--r-- | clang/lib/Driver/ToolChains.h | 2 | ||||
| -rw-r--r-- | clang/lib/Driver/Tools.cpp | 20 | ||||
| -rw-r--r-- | clang/test/Driver/embed-bitcode.c | 38 |
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 + |

