steven_wu created this revision. steven_wu added a subscriber: cfe-commits.
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. http://reviews.llvm.org/D17390 Files: include/clang/Basic/DiagnosticDriverKinds.td include/clang/Driver/Driver.h include/clang/Driver/Options.td include/clang/Driver/ToolChain.h lib/Driver/Driver.cpp lib/Driver/ToolChains.cpp lib/Driver/ToolChains.h lib/Driver/Tools.cpp test/Driver/embed-bitcode.c
Index: test/Driver/embed-bitcode.c =================================================================== --- /dev/null +++ test/Driver/embed-bitcode.c @@ -0,0 +1,26 @@ +// 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 -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 + Index: lib/Driver/Tools.cpp =================================================================== --- lib/Driver/Tools.cpp +++ lib/Driver/Tools.cpp @@ -3620,6 +3620,17 @@ 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. @@ -7176,6 +7187,15 @@ 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); Index: lib/Driver/ToolChains.h =================================================================== --- lib/Driver/ToolChains.h +++ lib/Driver/ToolChains.h @@ -542,6 +542,8 @@ bool UseSjLjExceptions(const llvm::opt::ArgList &Args) const override; + bool SupportsEmbeddedBitcode() const override; + SanitizerMask getSupportedSanitizers() const override; }; Index: lib/Driver/ToolChains.cpp =================================================================== --- lib/Driver/ToolChains.cpp +++ lib/Driver/ToolChains.cpp @@ -1103,6 +1103,13 @@ 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; } Index: lib/Driver/Driver.cpp =================================================================== --- lib/Driver/Driver.cpp +++ lib/Driver/Driver.cpp @@ -50,7 +50,7 @@ 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 @@ .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 @@ // 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; @@ -1743,13 +1757,13 @@ // -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. - const ActionList *BackendInputs = &(*Inputs)[0]->getInputs(); + const ActionList *BackendInputs = + (EmbedBitcode ? Inputs : &(*Inputs)[0]->getInputs()); // Compile job may be wrapped in CudaHostAction, extract it if // that's the case and update CollapsedCHA if we combine phases. CudaHostAction *CHA = dyn_cast<CudaHostAction>(*BackendInputs->begin()); JobAction *CompileJA = - cast<CompileJobAction>(CHA ? *CHA->begin() : *BackendInputs->begin()); - assert(CompileJA && "Backend job is not preceeded by compile job."); + cast<JobAction>(CHA ? *CHA->begin() : *BackendInputs->begin()); const Tool *Compiler = TC->SelectTool(*CompileJA); if (!Compiler) return nullptr; @@ -1775,7 +1789,8 @@ 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 +1904,8 @@ 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(); Index: include/clang/Driver/ToolChain.h =================================================================== --- include/clang/Driver/ToolChain.h +++ include/clang/Driver/ToolChain.h @@ -319,6 +319,11 @@ 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"; } Index: include/clang/Driver/Options.td =================================================================== --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -437,6 +437,12 @@ 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]>, Index: include/clang/Driver/Driver.h =================================================================== --- include/clang/Driver/Driver.h +++ include/clang/Driver/Driver.h @@ -83,6 +83,12 @@ SaveTempsObj } SaveTemps; + enum BitcodeEmbedMode { + EmbedNone, + EmbedMarker, + EmbedBitcode + } BitcodeEmbed; + /// LTO mode selected via -f(no-)?lto(=.*)? options. LTOKind LTOMode; @@ -262,6 +268,9 @@ 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 /// @{ Index: include/clang/Basic/DiagnosticDriverKinds.td =================================================================== --- include/clang/Basic/DiagnosticDriverKinds.td +++ include/clang/Basic/DiagnosticDriverKinds.td @@ -134,7 +134,9 @@ "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>;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits