paulkirth created this revision. paulkirth added reviewers: phosek, tejohnson, MaskRay, alexander-shaposhnikov. Herald added subscribers: ormris, steven_wu, hiraditya. Herald added a project: All. paulkirth requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
Fat LTO objects contain both LTO compatible IR, as well as generated object code. This allows users to defer the choice of whether to use LTO or not to link-time. This is a feature available in GCC for some time, and makes the existing -ffat-lto-objects flag functional in the same way as GCC's. This patch adds support for that flag in the driver, as well as setting the necessary codegen options for the backend. Largely, this means we select the newly added pass pipeline for generating fat objects. Users are expected to pass -ffat-lto-objects to clang in addition to one of the -flto variants. Without the -flto flag, -ffat-lto-objects has no effect. Original RFC: https://discourse.llvm.org/t/rfc-ffat-lto-objects-support/63977 Depends on D146776 <https://reviews.llvm.org/D146776> Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D146777 Files: clang/include/clang/Basic/CodeGenOptions.def clang/include/clang/Driver/Options.td clang/lib/CodeGen/BackendUtil.cpp clang/lib/Driver/Driver.cpp clang/lib/Driver/ToolChains/Clang.cpp clang/test/CodeGen/embed-lto-fatlto.c clang/test/Driver/clang_f_opts.c clang/test/Driver/fatlto-objects.c
Index: clang/test/Driver/fatlto-objects.c =================================================================== --- /dev/null +++ clang/test/Driver/fatlto-objects.c @@ -0,0 +1,10 @@ +// REQUIRES: x86_64-linux +// RUN: %clang -target x86_64-unknown-linux-gnu -flto -ffat-lto-objects -fintegrated-as -### %s -c 2>&1 | FileCheck %s -check-prefix=CHECK-CC +// CHECK-CC: -cc1 +// CHECK-CC: -emit-obj +// CHECK-CC: -ffat-lto-objects + +// RUN: %clang -target x86_64-unknown-linux-gnu -ffat-lto-objects -fintegrated-as -### %s -c 2>&1 | FileCheck %s -check-prefix=CHECK-CC-NOLTO +// CHECK-CC-NOLTO: -cc1 +// CHECK-CC-NOLTO: -emit-obj +// CHECK-CC-NOLTO-NOT: -ffat-lto-objects Index: clang/test/Driver/clang_f_opts.c =================================================================== --- clang/test/Driver/clang_f_opts.c +++ clang/test/Driver/clang_f_opts.c @@ -421,7 +421,6 @@ // CHECK-WARNING-DAG: optimization flag '-fwhole-program' is not supported // CHECK-WARNING-DAG: optimization flag '-fcaller-saves' is not supported // CHECK-WARNING-DAG: optimization flag '-freorder-blocks' is not supported -// CHECK-WARNING-DAG: optimization flag '-ffat-lto-objects' is not supported // CHECK-WARNING-DAG: optimization flag '-fmerge-constants' is not supported // CHECK-WARNING-DAG: optimization flag '-finline-small-functions' is not supported // CHECK-WARNING-DAG: optimization flag '-ftree-dce' is not supported Index: clang/test/CodeGen/embed-lto-fatlto.c =================================================================== --- /dev/null +++ clang/test/CodeGen/embed-lto-fatlto.c @@ -0,0 +1,9 @@ +// RUN: %clang -cc1 -triple x86_64-unknown-linux-gnu -S -flto=full -ffat-lto-objects -emit-llvm < %s | FileCheck %s +// RUN: %clang -cc1 -triple x86_64-unknown-linux-gnu -S -flto=full -ffat-lto-objects -emit-llvm < %s | FileCheck %s +// +// CHECK: !{{[0-9]+}} = !{i32 1, !"ThinLTO", i32 0} +// CHECK: !{{[0-9]+}} = !{i32 1, !"EnableSplitLTOUnit", i32 1} + +int test(void) { + return 0xabcd; +} Index: clang/lib/Driver/ToolChains/Clang.cpp =================================================================== --- clang/lib/Driver/ToolChains/Clang.cpp +++ clang/lib/Driver/ToolChains/Clang.cpp @@ -7276,6 +7276,14 @@ } } + if (IsUsingLTO && Args.getLastArg(options::OPT_ffat_lto_objects)) { + assert(LTOMode == LTOK_Full || LTOMode == LTOK_Thin); + CmdArgs.push_back(Args.MakeArgString( + Twine("-flto=") + (LTOMode == LTOK_Thin ? "thin" : "full"))); + CmdArgs.push_back("-flto-unit"); + CmdArgs.push_back("-ffat-lto-objects"); + } + if (Args.hasArg(options::OPT_forder_file_instrumentation)) { CmdArgs.push_back("-forder-file-instrumentation"); // Enable order file instrumentation when ThinLTO is not on. When ThinLTO is Index: clang/lib/Driver/Driver.cpp =================================================================== --- clang/lib/Driver/Driver.cpp +++ clang/lib/Driver/Driver.cpp @@ -4641,8 +4641,13 @@ } case phases::Backend: { if (isUsingLTO() && TargetDeviceOffloadKind == Action::OFK_None) { - types::ID Output = - Args.hasArg(options::OPT_S) ? types::TY_LTO_IR : types::TY_LTO_BC; + types::ID Output; + if (Args.hasArg(options::OPT_S)) + Output = types::TY_LTO_IR; + else if (Args.hasArg(options::OPT_ffat_lto_objects)) + Output = types::TY_PP_Asm; + else + Output = types::TY_LTO_BC; return C.MakeAction<BackendJobAction>(Input, Output); } if (isUsingLTO(/* IsOffload */ true) && Index: clang/lib/CodeGen/BackendUtil.cpp =================================================================== --- clang/lib/CodeGen/BackendUtil.cpp +++ clang/lib/CodeGen/BackendUtil.cpp @@ -24,6 +24,7 @@ #include "llvm/Bitcode/BitcodeReader.h" #include "llvm/Bitcode/BitcodeWriter.h" #include "llvm/Bitcode/BitcodeWriterPass.h" +#include "llvm/Bitcode/EmbedBitcodePass.h" #include "llvm/CodeGen/RegAllocRegistry.h" #include "llvm/CodeGen/SchedulerRegistry.h" #include "llvm/CodeGen/TargetSubtargetInfo.h" @@ -973,7 +974,13 @@ MPM.addPass(InstrProfiling(*Options, false)); }); - if (IsThinLTO) { + if (CodeGenOpts.OptimizationLevel == 0) { + MPM = PB.buildO0DefaultPipeline(Level, IsLTO || IsThinLTO); + } else if (CodeGenOpts.FatLTO) { + MPM = PB.buildFatLTODefaultPipeline( + Level, IsThinLTO, CodeGenOpts.EmitLLVMUseLists, + IsThinLTO || shouldEmitRegularLTOSummary()); + } else if (IsThinLTO) { MPM = PB.buildThinLTOPreLinkDefaultPipeline(Level); } else if (IsLTO) { MPM = PB.buildLTOPreLinkDefaultPipeline(Level); @@ -1031,6 +1038,13 @@ } } + if (CodeGenOpts.FatLTO) { + // Set EnableSplitLTOUnit, since the config above won't + if (!TheModule->getModuleFlag("EnableSplitLTOUnit")) + TheModule->addModuleFlag(Module::Error, "EnableSplitLTOUnit", + uint32_t(CodeGenOpts.EnableSplitLTOUnit)); + } + // Now that we have all of the passes ready, run them. { PrettyStackTraceString CrashInfo("Optimizer"); Index: clang/include/clang/Driver/Options.td =================================================================== --- clang/include/clang/Driver/Options.td +++ clang/include/clang/Driver/Options.td @@ -2265,6 +2265,11 @@ Flags<[CoreOption, CC1Option]>, Group<f_Group>, HelpText<"Write minimized bitcode to <file> for the ThinLTO thin link only">, MarshallingInfoString<CodeGenOpts<"ThinLinkBitcodeFile">>; +defm fat_lto_objects : BoolFOption<"fat-lto-objects", + CodeGenOpts<"FatLTO">, DefaultFalse, + PosFlag<SetTrue, [], "Enable fat LTO object support">, + NegFlag<SetFalse, [], "Disable fat LTO object support">, + BothFlags<[CC1Option], "">>; def fmacro_backtrace_limit_EQ : Joined<["-"], "fmacro-backtrace-limit=">, Group<f_Group>, Flags<[NoXarchOption, CoreOption]>; defm merge_all_constants : BoolFOption<"merge-all-constants", @@ -4910,7 +4915,6 @@ defm reorder_blocks : BooleanFFlag<"reorder-blocks">, Group<clang_ignored_gcc_optimization_f_Group>; defm branch_count_reg : BooleanFFlag<"branch-count-reg">, Group<clang_ignored_gcc_optimization_f_Group>; defm default_inline : BooleanFFlag<"default-inline">, Group<clang_ignored_gcc_optimization_f_Group>; -defm fat_lto_objects : BooleanFFlag<"fat-lto-objects">, Group<clang_ignored_gcc_optimization_f_Group>; defm float_store : BooleanFFlag<"float-store">, Group<clang_ignored_gcc_optimization_f_Group>; defm friend_injection : BooleanFFlag<"friend-injection">, Group<clang_ignored_f_Group>; defm function_attribute_list : BooleanFFlag<"function-attribute-list">, Group<clang_ignored_f_Group>; Index: clang/include/clang/Basic/CodeGenOptions.def =================================================================== --- clang/include/clang/Basic/CodeGenOptions.def +++ clang/include/clang/Basic/CodeGenOptions.def @@ -162,6 +162,7 @@ ///< compile step. CODEGENOPT(LTOUnit, 1, 0) ///< Emit IR to support LTO unit features (CFI, whole ///< program vtable opt). +CODEGENOPT(FatLTO, 1, 0) ///< Set when -ffat-lto-objects is enabled. CODEGENOPT(EnableSplitLTOUnit, 1, 0) ///< Enable LTO unit splitting to support /// CFI and traditional whole program /// devirtualization that require whole
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits