aboutsummaryrefslogtreecommitdiff
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/Basic/CodeGenOptions.def1
-rw-r--r--clang/include/clang/Driver/Options.td5
-rw-r--r--clang/lib/CodeGen/BackendUtil.cpp13
-rw-r--r--clang/lib/Driver/ToolChains/Clang.cpp31
-rw-r--r--clang/lib/Driver/ToolChains/PS4CPU.cpp7
-rw-r--r--clang/lib/Frontend/CompilerInvocation.cpp2
-rw-r--r--clang/test/CodeGen/asan-unified-lto.ll18
-rw-r--r--clang/test/CodeGen/emit-summary-index.c6
-rw-r--r--clang/test/CodeGen/unified-lto-pipeline.c17
-rw-r--r--clang/test/CodeGenCXX/unified-cfi-lto.cpp22
-rw-r--r--clang/test/Driver/unified-lto.c12
-rw-r--r--clang/test/Driver/whole-program-vtables.c4
12 files changed, 128 insertions, 10 deletions
diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def
index 5b18f45..a03447c 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -168,6 +168,7 @@ CODEGENOPT(EnableSplitLTOUnit, 1, 0) ///< Enable LTO unit splitting to support
/// CFI and traditional whole program
/// devirtualization that require whole
/// program IR support.
+CODEGENOPT(UnifiedLTO, 1, 0) ///< Use the unified LTO pipeline.
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 c5230d1..aacdf09 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -2341,6 +2341,11 @@ def flto_EQ_auto : Flag<["-"], "flto=auto">, Group<f_Group>,
Alias<flto_EQ>, AliasArgs<["full"]>, HelpText<"Enable LTO in 'full' mode">;
def flto : Flag<["-"], "flto">, Flags<[CoreOption, CC1Option, FC1Option, FlangOption]>, Group<f_Group>,
Alias<flto_EQ>, AliasArgs<["full"]>, HelpText<"Enable LTO in 'full' mode">;
+defm unified_lto : BoolFOption<"unified-lto",
+ CodeGenOpts<"UnifiedLTO">, DefaultFalse,
+ PosFlag<SetTrue, [], "Use the unified LTO pipeline">,
+ NegFlag<SetFalse, [], "Use distinct LTO pipelines">,
+ BothFlags<[CC1Option], "">>;
def fno_lto : Flag<["-"], "fno-lto">, Flags<[CoreOption, CC1Option]>, Group<f_Group>,
HelpText<"Disable LTO mode (default)">;
def foffload_lto_EQ : Joined<["-"], "foffload-lto=">, Flags<[CoreOption]>, Group<f_Group>,
diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index 06af080..1b0c249 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -831,6 +831,7 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
// Only enable CGProfilePass when using integrated assembler, since
// non-integrated assemblers don't recognize .cgprofile section.
PTO.CallGraphProfile = !CodeGenOpts.DisableIntegratedAS;
+ PTO.UnifiedLTO = CodeGenOpts.UnifiedLTO;
LoopAnalysisManager LAM;
FunctionAnalysisManager FAM;
@@ -1010,7 +1011,7 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
});
}
- if (IsThinLTO) {
+ if (IsThinLTO || (IsLTO && CodeGenOpts.UnifiedLTO)) {
MPM = PB.buildThinLTOPreLinkDefaultPipeline(Level);
} else if (IsLTO) {
MPM = PB.buildLTOPreLinkDefaultPipeline(Level);
@@ -1036,8 +1037,10 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
if (!ThinLinkOS)
return;
}
- MPM.addPass(ThinLTOBitcodeWriterPass(*OS, ThinLinkOS ? &ThinLinkOS->os()
- : nullptr));
+ if (CodeGenOpts.UnifiedLTO)
+ TheModule->addModuleFlag(Module::Error, "UnifiedLTO", uint32_t(1));
+ MPM.addPass(ThinLTOBitcodeWriterPass(
+ *OS, ThinLinkOS ? &ThinLinkOS->os() : nullptr));
} else {
MPM.addPass(PrintModulePass(*OS, "", CodeGenOpts.EmitLLVMUseLists,
/*EmitLTOSummary=*/true));
@@ -1048,11 +1051,13 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
// targets
bool EmitLTOSummary = shouldEmitRegularLTOSummary();
if (EmitLTOSummary) {
- if (!TheModule->getModuleFlag("ThinLTO"))
+ if (!TheModule->getModuleFlag("ThinLTO") && !CodeGenOpts.UnifiedLTO)
TheModule->addModuleFlag(Module::Error, "ThinLTO", uint32_t(0));
if (!TheModule->getModuleFlag("EnableSplitLTOUnit"))
TheModule->addModuleFlag(Module::Error, "EnableSplitLTOUnit",
uint32_t(1));
+ if (CodeGenOpts.UnifiedLTO)
+ TheModule->addModuleFlag(Module::Error, "UnifiedLTO", uint32_t(1));
}
if (Action == Backend_EmitBC)
MPM.addPass(BitcodeWriterPass(*OS, CodeGenOpts.EmitLLVMUseLists,
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 5c7e248..890b99d 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -4776,6 +4776,14 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// Select the appropriate action.
RewriteKind rewriteKind = RK_None;
+ bool UnifiedLTO = false;
+ if (IsUsingLTO) {
+ UnifiedLTO = Args.hasFlag(options::OPT_funified_lto,
+ options::OPT_fno_unified_lto, false);
+ if (UnifiedLTO)
+ CmdArgs.push_back("-funified-lto");
+ }
+
// If CollectArgsForIntegratedAssembler() isn't called below, claim the args
// it claims when not running an assembler. Otherwise, clang would emit
// "argument unused" warnings for assembler flags when e.g. adding "-E" to
@@ -4920,7 +4928,11 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
assert(LTOMode == LTOK_Full || LTOMode == LTOK_Thin);
CmdArgs.push_back(Args.MakeArgString(
Twine("-flto=") + (LTOMode == LTOK_Thin ? "thin" : "full")));
- CmdArgs.push_back("-flto-unit");
+ // PS4 uses the legacy LTO API, which does not support some of the
+ // features enabled by -flto-unit.
+ if ((RawTriple.getOS() != llvm::Triple::PS4) ||
+ (D.getLTOMode() == LTOK_Full) || !UnifiedLTO)
+ CmdArgs.push_back("-flto-unit");
}
}
}
@@ -7309,17 +7321,24 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
}
if (WholeProgramVTables) {
- // Propagate -fwhole-program-vtables if this is an LTO compile.
- if (IsUsingLTO)
- CmdArgs.push_back("-fwhole-program-vtables");
+ // PS4 uses the legacy LTO API, which does not support this feature in
+ // ThinLTO mode.
+ bool IsPS4 = getToolChain().getTriple().isPS4();
+
// Check if we passed LTO options but they were suppressed because this is a
// device offloading action, or we passed device offload LTO options which
// were suppressed because this is not the device offload action.
+ // Check if we are using PS4 in regular LTO mode.
// Otherwise, issue an error.
- else if (!D.isUsingLTO(!IsDeviceOffloadAction))
+ if ((!IsUsingLTO && !D.isUsingLTO(!IsDeviceOffloadAction)) ||
+ (IsPS4 && !UnifiedLTO && (D.getLTOMode() != LTOK_Full)))
D.Diag(diag::err_drv_argument_only_allowed_with)
<< "-fwhole-program-vtables"
- << "-flto";
+ << ((IsPS4 && !UnifiedLTO) ? "-flto=full" : "-flto");
+
+ // Propagate -fwhole-program-vtables if this is an LTO compile.
+ if (IsUsingLTO)
+ CmdArgs.push_back("-fwhole-program-vtables");
}
bool DefaultsSplitLTOUnit =
diff --git a/clang/lib/Driver/ToolChains/PS4CPU.cpp b/clang/lib/Driver/ToolChains/PS4CPU.cpp
index 2a35fdf..37006dc 100644
--- a/clang/lib/Driver/ToolChains/PS4CPU.cpp
+++ b/clang/lib/Driver/ToolChains/PS4CPU.cpp
@@ -204,6 +204,13 @@ void tools::PScpu::Linker::ConstructJob(Compilation &C, const JobAction &JA,
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs))
TC.addSanitizerArgs(Args, CmdArgs, "-l", "");
+ if (D.isUsingLTO() && Args.hasArg(options::OPT_funified_lto)) {
+ if (D.getLTOMode() == LTOK_Thin)
+ CmdArgs.push_back("--lto=thin");
+ else if (D.getLTOMode() == LTOK_Full)
+ CmdArgs.push_back("--lto=full");
+ }
+
Args.AddAllArgs(CmdArgs, options::OPT_L);
Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
Args.AddAllArgs(CmdArgs, options::OPT_s);
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 5360bbe..1fba91b 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -1767,6 +1767,8 @@ bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args,
Opts.PrepareForThinLTO = true;
else if (S != "full")
Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << S;
+ if (Args.hasArg(OPT_funified_lto))
+ Opts.PrepareForThinLTO = true;
}
if (Arg *A = Args.getLastArg(OPT_fthinlto_index_EQ)) {
if (IK.getLanguage() != Language::LLVM_IR)
diff --git a/clang/test/CodeGen/asan-unified-lto.ll b/clang/test/CodeGen/asan-unified-lto.ll
new file mode 100644
index 0000000..7b790d4
--- /dev/null
+++ b/clang/test/CodeGen/asan-unified-lto.ll
@@ -0,0 +1,18 @@
+; Verify that in the cases of explict distinct LTO piplines,
+; explicit unified LTO pipelines, and the default LTO pipeline,
+; there is no crash and the anonoymous global is named
+; as expected.
+
+; RUN: %clang_cc1 -emit-llvm-bc -O1 -flto -fsanitize=address -o - -x ir < %s | llvm-dis -o - | FileCheck %s
+; RUN: %clang_cc1 -emit-llvm-bc -O1 -flto -funified-lto -fsanitize=address -o - -x ir < %s | llvm-dis -o - | FileCheck %s
+; CHECK: @anon.3ee0898e5200a57350fed5485ae5d237
+
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-pc-linux-gnu"
+
+@.str = private unnamed_addr constant [5 x i8] c"none\00", align 1
+
+define ptr @f() {
+ %ptr = getelementptr inbounds [5 x i8], ptr @.str, i32 0, i32 0
+ ret ptr %ptr
+}
diff --git a/clang/test/CodeGen/emit-summary-index.c b/clang/test/CodeGen/emit-summary-index.c
index c407934..4a18831 100644
--- a/clang/test/CodeGen/emit-summary-index.c
+++ b/clang/test/CodeGen/emit-summary-index.c
@@ -14,4 +14,10 @@
// RUN: %clang_cc1 -flto -triple x86_64-pc-linux-gnu -emit-llvm-bc -disable-llvm-passes < %s -o %t.bc
// RUN: %clang_cc1 -flto -triple x86_64-pc-linux-gnu -emit-llvm-bc -x ir < %t.bc | llvm-bcanalyzer -dump | FileCheck --check-prefix=LTOINDEX %s
+/// Check that emitting bitcode works for Unified LTO, when either LTO mode is specified
+// RUN: %clang_cc1 -flto=thin -funified-lto -emit-llvm-bc < %s | llvm-bcanalyzer -dump | FileCheck --check-prefix=UNITHIN %s
+// RUN: %clang_cc1 -flto -funified-lto -emit-llvm-bc < %s | llvm-bcanalyzer -dump | FileCheck --check-prefix=UNITHIN %s
+
+// UNITHIN: <GLOBALVAL_SUMMARY_BLOCK
+
int main(void) {}
diff --git a/clang/test/CodeGen/unified-lto-pipeline.c b/clang/test/CodeGen/unified-lto-pipeline.c
new file mode 100644
index 0000000..88bdfa6
--- /dev/null
+++ b/clang/test/CodeGen/unified-lto-pipeline.c
@@ -0,0 +1,17 @@
+// RUN: %clang --target=x86_64-unknown-unknown-linux -Xclang -fdebug-pass-manager -flto=thin -funified-lto -O2 -c %s -o %t.0 2>&1 | FileCheck --check-prefix=THIN %s
+// RUN: mv %t.0 %t.1
+// RUN: %clang --target=x86_64-unknown-unknown-linux -Xclang -fdebug-pass-manager -flto=full -funified-lto -O2 -c %s -o %t.0 2>&1 | FileCheck --check-prefix=THIN %s
+// RUN: %clang --target=x86_64-unknown-unknown-linux -Xclang -fdebug-pass-manager -flto=thin -O2 -c %s -o %t.2 2>&1 | FileCheck --check-prefix=THIN %s
+// RUN: mv %t.2 %t.3
+// RUN: %clang --target=x86_64-unknown-unknown-linux -Xclang -fdebug-pass-manager -flto=full -O2 -c %s -o %t.2 2>&1 | FileCheck --check-prefix=FULL %s
+// RUN: cmp %t.0 %t.1
+// THIN: ThinLTOBitcodeWriterPass
+// FULL-NOT: ThinLTOBitcodeWriterPass
+
+int foo() {
+ return 2 + 2;
+}
+
+int bar() {
+ return foo() + 1;
+}
diff --git a/clang/test/CodeGenCXX/unified-cfi-lto.cpp b/clang/test/CodeGenCXX/unified-cfi-lto.cpp
new file mode 100644
index 0000000..cc3f594
--- /dev/null
+++ b/clang/test/CodeGenCXX/unified-cfi-lto.cpp
@@ -0,0 +1,22 @@
+// Ensure that the frontend adds the proper metadata when CFI is
+// enabled.
+// RUN: %clang --target=x86_64-scei-ps4 -funified-lto -flto -fsanitize=cfi -fvisibility=hidden -c %s -o %t.o
+// RUN: llvm-dis %t.o -o %t1
+// RUN: FileCheck <%t1.0 %s
+
+typedef int (*FuncPtr)();
+
+int a() { return 1; }
+int b() { return 2; }
+int c() { return 3; }
+
+FuncPtr func[3] = {a,b,c};
+
+int
+main(int argc, char *argv[]) {
+ // CHECK: call i1 @llvm.type.test
+ return func[argc]();
+ // CHECK-LABEL: trap
+}
+
+// CHECK: typeTests:
diff --git a/clang/test/Driver/unified-lto.c b/clang/test/Driver/unified-lto.c
new file mode 100644
index 0000000..e16affe
--- /dev/null
+++ b/clang/test/Driver/unified-lto.c
@@ -0,0 +1,12 @@
+// RUN: %clang --target=x86_64-unknown-linux -### %s -flto=full -funified-lto 2>&1 | FileCheck --check-prefix=UNIT %s
+// RUN: %clang --target=x86_64-unknown-linux -### %s -flto=thin -funified-lto 2>&1 | FileCheck --check-prefix=UNIT %s
+// RUN: %clang --target=x86_64-scei-ps4 -### %s -flto=full -funified-lto 2>&1 | FileCheck --check-prefix=UNIT %s
+// RUN: %clang --target=x86_64-scei-ps4 -### %s -flto=thin -funified-lto 2>&1 | FileCheck --check-prefix=NOUNIT %s
+
+// UNIT: "-flto-unit"
+// NOUNIT-NOT: "-flto-unit"
+
+// RUN: %clang --target=x86_64-sie-prospero -### %s -funified-lto 2>&1 | FileCheck --check-prefix=NOUNILTO %s
+// NOUNILTO: clang: warning: argument unused during compilation: '-funified-lto'
+// NOUNILTO: "-cc1"
+// NOUNILTO-NOT: "-funified-lto
diff --git a/clang/test/Driver/whole-program-vtables.c b/clang/test/Driver/whole-program-vtables.c
index de0c606..19986ec 100644
--- a/clang/test/Driver/whole-program-vtables.c
+++ b/clang/test/Driver/whole-program-vtables.c
@@ -6,6 +6,10 @@
// RUN: %clang_cl --target=x86_64-pc-win32 -fwhole-program-vtables -flto -### -- %s 2>&1 | FileCheck --check-prefix=LTO %s
// LTO: "-fwhole-program-vtables"
+/// -funified-lto does not imply -flto, so we still get an error that fwhole-program-vtables has no effect without -flto
+// RUN: %clang --target=x86_64-pc-linux-gnu -fwhole-program-vtables -funified-lto -### %s 2>&1 | FileCheck --check-prefix=NO-LTO %s
+// RUN: %clang --target=x86_64-pc-linux-gnu -fwhole-program-vtables -fno-unified-lto -### %s 2>&1 | FileCheck --check-prefix=NO-LTO %s
+
// RUN: %clang -target x86_64-unknown-linux -fwhole-program-vtables -fno-whole-program-vtables -flto -### %s 2>&1 | FileCheck --check-prefix=LTO-DISABLE %s
// RUN: %clang_cl --target=x86_64-pc-win32 -fwhole-program-vtables -fno-whole-program-vtables -flto -### -- %s 2>&1 | FileCheck --check-prefix=LTO-DISABLE %s
// LTO-DISABLE-NOT: "-fwhole-program-vtables"