summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/Basic/CodeGenOptions.def4
-rw-r--r--clang/include/clang/Driver/Options.td5
-rw-r--r--clang/include/clang/Driver/SanitizerArgs.h1
-rw-r--r--clang/lib/CodeGen/BackendUtil.cpp30
-rw-r--r--clang/lib/Driver/SanitizerArgs.cpp2
-rw-r--r--clang/lib/Driver/ToolChains/Clang.cpp11
-rw-r--r--clang/lib/Frontend/CompilerInvocation.cpp1
-rw-r--r--clang/test/CodeGen/thinlto-distributed-cfi-devirt.ll2
-rw-r--r--clang/test/CodeGen/thinlto-distributed-cfi.ll2
-rw-r--r--clang/test/CodeGenCXX/no-lto-unit.cpp2
-rw-r--r--clang/test/CodeGenCXX/type-metadata-thinlto.cpp4
-rw-r--r--clang/test/Driver/split-lto-unit.c10
12 files changed, 61 insertions, 13 deletions
diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def
index 952aa588b60..ed2387b9a2e 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -116,6 +116,10 @@ CODEGENOPT(PrepareForThinLTO , 1, 0) ///< Set when -flto=thin is enabled on the
///< 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 traditional whole program
+ /// devirtualization that require whole
+ /// program IR support.
CODEGENOPT(IncrementalLinkerCompatible, 1, 0) ///< Emit an object file which can
///< be used with an incremental
///< linker.
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index bb4436a6382..72ded521bde 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -1776,6 +1776,11 @@ def fwhole_program_vtables : Flag<["-"], "fwhole-program-vtables">, Group<f_Grou
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">;
diff --git a/clang/include/clang/Driver/SanitizerArgs.h b/clang/include/clang/Driver/SanitizerArgs.h
index 02338c22165..e590a49deea 100644
--- a/clang/include/clang/Driver/SanitizerArgs.h
+++ b/clang/include/clang/Driver/SanitizerArgs.h
@@ -81,6 +81,7 @@ class SanitizerArgs {
bool requiresPIE() const;
bool needsUnwindTables() const;
+ bool needsLTO() const;
bool linkCXXRuntimes() const { return LinkCXXRuntimes; }
bool hasCrossDsoCfi() const { return CfiCrossDso; }
bool hasAnySanitizer() const { return !Sanitizers.empty(); }
diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index 1311af91686..3e0651978b4 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -814,6 +814,8 @@ void EmitAssemblyHelper::EmitAssembly(BackendAction Action,
if (!ThinLinkOS)
return;
}
+ TheModule->addModuleFlag(Module::Error, "EnableSplitLTOUnit",
+ CodeGenOpts.EnableSplitLTOUnit);
PerModulePasses.add(createWriteThinLTOBitcodePass(
*OS, ThinLinkOS ? &ThinLinkOS->os() : nullptr));
} else {
@@ -824,12 +826,15 @@ void EmitAssemblyHelper::EmitAssembly(BackendAction Action,
!CodeGenOpts.DisableLLVMPasses &&
llvm::Triple(TheModule->getTargetTriple()).getVendor() !=
llvm::Triple::Apple);
- if (EmitLTOSummary && !TheModule->getModuleFlag("ThinLTO"))
- TheModule->addModuleFlag(Module::Error, "ThinLTO", uint32_t(0));
+ if (EmitLTOSummary) {
+ if (!TheModule->getModuleFlag("ThinLTO"))
+ TheModule->addModuleFlag(Module::Error, "ThinLTO", uint32_t(0));
+ TheModule->addModuleFlag(Module::Error, "EnableSplitLTOUnit",
+ CodeGenOpts.EnableSplitLTOUnit);
+ }
- PerModulePasses.add(
- createBitcodeWriterPass(*OS, CodeGenOpts.EmitLLVMUseLists,
- EmitLTOSummary));
+ PerModulePasses.add(createBitcodeWriterPass(
+ *OS, CodeGenOpts.EmitLLVMUseLists, EmitLTOSummary));
}
break;
@@ -1054,6 +1059,8 @@ void EmitAssemblyHelper::EmitAssemblyWithNewPassManager(
if (!ThinLinkOS)
return;
}
+ TheModule->addModuleFlag(Module::Error, "EnableSplitLTOUnit",
+ CodeGenOpts.EnableSplitLTOUnit);
MPM.addPass(ThinLTOBitcodeWriterPass(*OS, ThinLinkOS ? &ThinLinkOS->os()
: nullptr));
} else {
@@ -1064,11 +1071,14 @@ void EmitAssemblyHelper::EmitAssemblyWithNewPassManager(
!CodeGenOpts.DisableLLVMPasses &&
llvm::Triple(TheModule->getTargetTriple()).getVendor() !=
llvm::Triple::Apple);
- if (EmitLTOSummary && !TheModule->getModuleFlag("ThinLTO"))
- TheModule->addModuleFlag(Module::Error, "ThinLTO", uint32_t(0));
-
- MPM.addPass(BitcodeWriterPass(*OS, CodeGenOpts.EmitLLVMUseLists,
- EmitLTOSummary));
+ if (EmitLTOSummary) {
+ if (!TheModule->getModuleFlag("ThinLTO"))
+ TheModule->addModuleFlag(Module::Error, "ThinLTO", uint32_t(0));
+ TheModule->addModuleFlag(Module::Error, "EnableSplitLTOUnit",
+ CodeGenOpts.EnableSplitLTOUnit);
+ }
+ MPM.addPass(
+ BitcodeWriterPass(*OS, CodeGenOpts.EmitLLVMUseLists, EmitLTOSummary));
}
break;
diff --git a/clang/lib/Driver/SanitizerArgs.cpp b/clang/lib/Driver/SanitizerArgs.cpp
index 6667cbb347c..1a46073aaa3 100644
--- a/clang/lib/Driver/SanitizerArgs.cpp
+++ b/clang/lib/Driver/SanitizerArgs.cpp
@@ -207,6 +207,8 @@ bool SanitizerArgs::needsUnwindTables() const {
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
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index eb88a71e492..4b999925273 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -5226,6 +5226,17 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-fwhole-program-vtables");
}
+ bool RequiresSplitLTOUnit = WholeProgramVTables || Sanitize.needsLTO();
+ bool SplitLTOUnit =
+ Args.hasFlag(options::OPT_fsplit_lto_unit,
+ options::OPT_fno_split_lto_unit, RequiresSplitLTOUnit);
+ if (RequiresSplitLTOUnit && !SplitLTOUnit)
+ D.Diag(diag::err_drv_argument_not_allowed_with)
+ << "-fno-split-lto-unit"
+ << (WholeProgramVTables ? "-fwhole-program-vtables" : "-fsanitize=cfi");
+ if (SplitLTOUnit)
+ CmdArgs.push_back("-fsplit-lto-unit");
+
if (Arg *A = Args.getLastArg(options::OPT_fexperimental_isel,
options::OPT_fno_experimental_isel)) {
CmdArgs.push_back("-mllvm");
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 1e857355b33..3e6528c2598 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -907,6 +907,7 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
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)
diff --git a/clang/test/CodeGen/thinlto-distributed-cfi-devirt.ll b/clang/test/CodeGen/thinlto-distributed-cfi-devirt.ll
index fbcaa773ba0..2ecf149b061 100644
--- a/clang/test/CodeGen/thinlto-distributed-cfi-devirt.ll
+++ b/clang/test/CodeGen/thinlto-distributed-cfi-devirt.ll
@@ -4,7 +4,7 @@
; It additionally enables -fwhole-program-vtables to get more information in
; TYPE_IDs of GLOBALVAL_SUMMARY_BLOCK.
-; RUN: opt -thinlto-bc -o %t.o %s
+; RUN: opt -thinlto-bc -thinlto-split-lto-unit -o %t.o %s
; FIXME: Fix machine verifier issues and remove -verify-machineinstrs=0. PR39436.
; RUN: llvm-lto2 run -thinlto-distributed-indexes %t.o \
diff --git a/clang/test/CodeGen/thinlto-distributed-cfi.ll b/clang/test/CodeGen/thinlto-distributed-cfi.ll
index 055b5971eb2..b2ede5395d1 100644
--- a/clang/test/CodeGen/thinlto-distributed-cfi.ll
+++ b/clang/test/CodeGen/thinlto-distributed-cfi.ll
@@ -2,7 +2,7 @@
; Backend test for distribute ThinLTO with CFI.
-; RUN: opt -thinlto-bc -o %t.o %s
+; RUN: opt -thinlto-bc -thinlto-split-lto-unit -o %t.o %s
; RUN: llvm-lto2 run -thinlto-distributed-indexes %t.o \
; RUN: -o %t2.index \
diff --git a/clang/test/CodeGenCXX/no-lto-unit.cpp b/clang/test/CodeGenCXX/no-lto-unit.cpp
index 24b8fd01546..3797f0742ef 100644
--- a/clang/test/CodeGenCXX/no-lto-unit.cpp
+++ b/clang/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 {
diff --git a/clang/test/CodeGenCXX/type-metadata-thinlto.cpp b/clang/test/CodeGenCXX/type-metadata-thinlto.cpp
index 2a586fc4c37..8bf39f129c4 100644
--- a/clang/test/CodeGenCXX/type-metadata-thinlto.cpp
+++ b/clang/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: %clang_cc1 -flto=thin -flto-unit -fsplit-lto-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=8/>
// CHECK: @_ZTV1A = linkonce_odr
class A {
diff --git a/clang/test/Driver/split-lto-unit.c b/clang/test/Driver/split-lto-unit.c
new file mode 100644
index 00000000000..fab5790c26b
--- /dev/null
+++ b/clang/test/Driver/split-lto-unit.c
@@ -0,0 +1,10 @@
+// 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=ERROR1 %s
+// RUN: %clang -target x86_64-unknown-linux -### %s -flto=thin -fno-split-lto-unit -fsanitize=cfi 2>&1 | FileCheck --check-prefix=ERROR2 %s
+
+// UNIT: "-fsplit-lto-unit"
+// NOUNIT-NOT: "-fsplit-lto-unit"
+// ERROR1: error: invalid argument '-fno-split-lto-unit' not allowed with '-fwhole-program-vtables'
+// ERROR2: error: invalid argument '-fno-split-lto-unit' not allowed with '-fsanitize=cfi'
OpenPOWER on IntegriCloud