tejohnson updated this revision to Diff 174329.
tejohnson added a comment.
- As discussed off-patch, will use a new, separate option to control this
splitting, here I am using -f[no]split-lto-unit.
- Switch the default of splitting lto units to off by default, unless
compiled with CFI or -fwhole-program-vtables.
- I'll update the patch title and summary once we converge on flag/behavior.
Repository:
rC Clang
https://reviews.llvm.org/D53891
Files:
include/clang/Driver/Options.td
include/clang/Driver/SanitizerArgs.h
include/clang/Frontend/CodeGenOptions.def
lib/CodeGen/BackendUtil.cpp
lib/Driver/SanitizerArgs.cpp
lib/Driver/ToolChains/Clang.cpp
lib/Frontend/CompilerInvocation.cpp
test/CodeGenCXX/no-lto-unit.cpp
test/CodeGenCXX/type-metadata-thinlto.cpp
test/Driver/split-lto-unit.c
Index: test/Driver/split-lto-unit.c
===================================================================
--- /dev/null
+++ test/Driver/split-lto-unit.c
@@ -0,0 +1,8 @@
+// RUN: %clang -target x86_64-unknown-linux -### %s -flto=thin 2>&1 | FileCheck --check-prefix=NOUNIT %s
+// RUN: %clang -target x86_64-unknown-linux -### %s -flto=thin -fsplit-lto-unit 2>&1 | FileCheck --check-prefix=UNIT %s
+// RUN: %clang -target x86_64-unknown-linux -### %s -flto=thin -fno-split-lto-unit 2>&1 | FileCheck --check-prefix=NOUNIT %s
+// RUN: %clang -target x86_64-unknown-linux -### %s -flto=thin -fno-split-lto-unit -fwhole-program-vtables 2>&1 | FileCheck --check-prefix=UNIT %s
+// RUN: %clang -target x86_64-unknown-linux -### %s -flto=thin -fno-split-lto-unit -fsanitize=cfi 2>&1 | FileCheck --check-prefix=UNIT %s
+
+// UNIT: "-fsplit-lto-unit"
+// NOUNIT-NOT: "-fsplit-lto-unit"
Index: test/CodeGenCXX/type-metadata-thinlto.cpp
===================================================================
--- test/CodeGenCXX/type-metadata-thinlto.cpp
+++ test/CodeGenCXX/type-metadata-thinlto.cpp
@@ -1,5 +1,7 @@
// RUN: %clang_cc1 -flto=thin -flto-unit -triple x86_64-unknown-linux -fvisibility hidden -emit-llvm-bc -o %t %s
// RUN: llvm-modextract -o - -n 1 %t | llvm-dis | FileCheck %s
+// RUN: llvm-modextract -b -o - -n 1 %t | llvm-bcanalyzer -dump | FileCheck %s --check-prefix=LTOUNIT
+// LTOUNIT: <FLAGS op0=4/>
// CHECK: @_ZTV1A = linkonce_odr
class A {
Index: test/CodeGenCXX/no-lto-unit.cpp
===================================================================
--- test/CodeGenCXX/no-lto-unit.cpp
+++ test/CodeGenCXX/no-lto-unit.cpp
@@ -2,6 +2,8 @@
// RUN: llvm-dis -o - %t | FileCheck %s
// RUN: %clang_cc1 -flto=thin -flto-unit -fno-lto-unit -triple x86_64-unknown-linux -fvisibility hidden -emit-llvm-bc -o %t %s
// RUN: llvm-dis -o - %t | FileCheck %s
+// RUN: llvm-bcanalyzer -dump %t | FileCheck %s --check-prefix=NOLTOUNIT
+// NOLTOUNIT: <FLAGS op0=0/>
// CHECK-NOT: !type
class A {
Index: lib/Frontend/CompilerInvocation.cpp
===================================================================
--- lib/Frontend/CompilerInvocation.cpp
+++ lib/Frontend/CompilerInvocation.cpp
@@ -793,6 +793,7 @@
Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << S;
}
Opts.LTOUnit = Args.hasFlag(OPT_flto_unit, OPT_fno_lto_unit, false);
+ Opts.EnableSplitLTOUnit = Args.hasArg(OPT_fsplit_lto_unit);
if (Arg *A = Args.getLastArg(OPT_fthinlto_index_EQ)) {
if (IK.getLanguage() != InputKind::LLVM_IR)
Diags.Report(diag::err_drv_argument_only_allowed_with)
Index: lib/Driver/ToolChains/Clang.cpp
===================================================================
--- lib/Driver/ToolChains/Clang.cpp
+++ lib/Driver/ToolChains/Clang.cpp
@@ -5108,6 +5108,12 @@
CmdArgs.push_back("-fwhole-program-vtables");
}
+ bool EnableSplitLTOUnit = Args.hasFlag(
+ options::OPT_fsplit_lto_unit, options::OPT_fno_split_lto_unit, false);
+ if (EnableSplitLTOUnit || WholeProgramVTables || Sanitize.needsLTO()) {
+ CmdArgs.push_back("-fsplit-lto-unit");
+ }
+
if (Arg *A = Args.getLastArg(options::OPT_fexperimental_isel,
options::OPT_fno_experimental_isel)) {
CmdArgs.push_back("-mllvm");
Index: lib/Driver/SanitizerArgs.cpp
===================================================================
--- lib/Driver/SanitizerArgs.cpp
+++ lib/Driver/SanitizerArgs.cpp
@@ -207,6 +207,8 @@
return Sanitizers.Mask & NeedsUnwindTables;
}
+bool SanitizerArgs::needsLTO() const { return Sanitizers.Mask & NeedsLTO; }
+
SanitizerArgs::SanitizerArgs(const ToolChain &TC,
const llvm::opt::ArgList &Args) {
SanitizerMask AllRemove = 0; // During the loop below, the accumulated set of
Index: lib/CodeGen/BackendUtil.cpp
===================================================================
--- lib/CodeGen/BackendUtil.cpp
+++ lib/CodeGen/BackendUtil.cpp
@@ -808,7 +808,8 @@
return;
}
PerModulePasses.add(createWriteThinLTOBitcodePass(
- *OS, ThinLinkOS ? &ThinLinkOS->os() : nullptr));
+ *OS, ThinLinkOS ? &ThinLinkOS->os() : nullptr,
+ CodeGenOpts.EnableSplitLTOUnit));
} else {
// Emit a module summary by default for Regular LTO except for ld64
// targets
@@ -820,9 +821,9 @@
if (EmitLTOSummary && !TheModule->getModuleFlag("ThinLTO"))
TheModule->addModuleFlag(Module::Error, "ThinLTO", uint32_t(0));
- PerModulePasses.add(
- createBitcodeWriterPass(*OS, CodeGenOpts.EmitLLVMUseLists,
- EmitLTOSummary));
+ PerModulePasses.add(createBitcodeWriterPass(
+ *OS, CodeGenOpts.EmitLLVMUseLists, EmitLTOSummary,
+ /*EmitModuleHash=*/false, CodeGenOpts.EnableSplitLTOUnit));
}
break;
@@ -1043,8 +1044,9 @@
if (!ThinLinkOS)
return;
}
- MPM.addPass(ThinLTOBitcodeWriterPass(*OS, ThinLinkOS ? &ThinLinkOS->os()
- : nullptr));
+ MPM.addPass(ThinLTOBitcodeWriterPass(
+ *OS, ThinLinkOS ? &ThinLinkOS->os() : nullptr,
+ CodeGenOpts.EnableSplitLTOUnit));
} else {
// Emit a module summary by default for Regular LTO except for ld64
// targets
@@ -1057,7 +1059,8 @@
TheModule->addModuleFlag(Module::Error, "ThinLTO", uint32_t(0));
MPM.addPass(BitcodeWriterPass(*OS, CodeGenOpts.EmitLLVMUseLists,
- EmitLTOSummary));
+ EmitLTOSummary, /*EmitModuleHash=*/false,
+ CodeGenOpts.EnableSplitLTOUnit));
}
break;
Index: include/clang/Frontend/CodeGenOptions.def
===================================================================
--- include/clang/Frontend/CodeGenOptions.def
+++ include/clang/Frontend/CodeGenOptions.def
@@ -116,6 +116,10 @@
///< compile step.
CODEGENOPT(LTOUnit, 1, 0) ///< Emit IR to support LTO unit features (CFI, whole
///< program vtable opt).
+CODEGENOPT(EnableSplitLTOUnit, 1, 0) ///< Enable LTO unit splitting to support
+ /// CFI and tranditional whole program
+ /// devirtulization that require whole
+ /// program IR support.
CODEGENOPT(IncrementalLinkerCompatible, 1, 0) ///< Emit an object file which can
///< be used with an incremental
///< linker.
Index: include/clang/Driver/SanitizerArgs.h
===================================================================
--- include/clang/Driver/SanitizerArgs.h
+++ include/clang/Driver/SanitizerArgs.h
@@ -79,6 +79,7 @@
bool requiresPIE() const;
bool needsUnwindTables() const;
+ bool needsLTO() const;
bool linkCXXRuntimes() const { return LinkCXXRuntimes; }
bool hasCrossDsoCfi() const { return CfiCrossDso; }
void addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
Index: include/clang/Driver/Options.td
===================================================================
--- include/clang/Driver/Options.td
+++ include/clang/Driver/Options.td
@@ -1733,6 +1733,11 @@
HelpText<"Enables whole-program vtable optimization. Requires -flto">;
def fno_whole_program_vtables : Flag<["-"], "fno-whole-program-vtables">, Group<f_Group>,
Flags<[CoreOption]>;
+def fsplit_lto_unit : Flag<["-"], "fsplit-lto-unit">, Group<f_Group>,
+ Flags<[CoreOption, CC1Option]>,
+ HelpText<"Enables splitting of the LTO unit.">;
+def fno_split_lto_unit : Flag<["-"], "fno-split-lto-unit">, Group<f_Group>,
+ Flags<[CoreOption]>;
def fforce_emit_vtables : Flag<["-"], "fforce-emit-vtables">, Group<f_Group>,
Flags<[CC1Option]>,
HelpText<"Emits more virtual tables to improve devirtualization">;
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits