mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-21 10:36:49 +00:00
Introduce -funique-source-file-names flag.
The purpose of this flag is to allow the compiler to assume that each object file passed to the linker has been compiled using a unique source file name. This is useful for reducing link times when doing ThinLTO in combination with whole-program devirtualization or CFI, as it allows modules without exported symbols to be built with ThinLTO. Reviewers: vitalybuka, teresajohnson Reviewed By: teresajohnson Pull Request: https://github.com/llvm/llvm-project/pull/135728
This commit is contained in:
parent
3f58ff20fe
commit
a5aa0c46c3
clang
docs
include/clang
lib
test
llvm
@ -42,6 +42,11 @@ default visibility setting is ``-fvisibility=default``, which would disable
|
||||
CFI checks for classes without visibility attributes. Most users will want
|
||||
to specify ``-fvisibility=hidden``, which enables CFI checks for such classes.
|
||||
|
||||
When using ``-fsanitize=cfi*`` with ``-flto=thin``, it is recommended
|
||||
to reduce link times by passing `-funique-source-file-names
|
||||
<UsersManual.html#cmdoption-f-no-unique-source-file-names>`_, provided
|
||||
that your program is compatible with it.
|
||||
|
||||
Experimental support for :ref:`cross-DSO control flow integrity
|
||||
<cfi-cross-dso>` exists that does not require classes to have hidden LTO
|
||||
visibility. This cross-DSO support has unstable ABI at this time.
|
||||
|
@ -2297,6 +2297,16 @@ are listed below.
|
||||
pure ThinLTO, as all split regular LTO modules are merged and LTO linked
|
||||
with regular LTO.
|
||||
|
||||
.. option:: -f[no-]unique-source-file-names
|
||||
|
||||
When enabled, allows the compiler to assume that each object file
|
||||
passed to the linker has been compiled using a unique source file
|
||||
name. This is useful for reducing link times when doing ThinLTO
|
||||
in combination with whole-program devirtualization or CFI.
|
||||
|
||||
A misuse of this flag will generally result in a duplicate symbol
|
||||
error at link time.
|
||||
|
||||
.. option:: -fforce-emit-vtables
|
||||
|
||||
In order to improve devirtualization, forces emitting of vtables even in
|
||||
|
@ -278,6 +278,8 @@ CODEGENOPT(SanitizeCfiICallNormalizeIntegers, 1, 0) ///< Normalize integer types
|
||||
///< CFI icall function signatures
|
||||
CODEGENOPT(SanitizeCfiCanonicalJumpTables, 1, 0) ///< Make jump table symbols canonical
|
||||
///< instead of creating a local jump table.
|
||||
CODEGENOPT(UniqueSourceFileNames, 1, 0) ///< Allow the compiler to assume that TUs
|
||||
///< have unique source file names at link time
|
||||
CODEGENOPT(SanitizeKcfiArity, 1, 0) ///< Embed arity in KCFI patchable function prefix
|
||||
CODEGENOPT(SanitizeCoverageType, 2, 0) ///< Type of sanitizer coverage
|
||||
///< instrumentation.
|
||||
|
@ -4140,6 +4140,13 @@ def ftrigraphs : Flag<["-"], "ftrigraphs">, Group<f_Group>,
|
||||
def fno_trigraphs : Flag<["-"], "fno-trigraphs">, Group<f_Group>,
|
||||
HelpText<"Do not process trigraph sequences">,
|
||||
Visibility<[ClangOption, CC1Option]>;
|
||||
defm unique_source_file_names: BoolOption<"f", "unique-source-file-names",
|
||||
CodeGenOpts<"UniqueSourceFileNames">, DefaultFalse,
|
||||
PosFlag<SetTrue, [], [CC1Option], "Allow">,
|
||||
NegFlag<SetFalse, [], [], "Do not allow">,
|
||||
BothFlags<[], [ClangOption], " the compiler to assume that each translation unit has a unique "
|
||||
"source file name at link time">>,
|
||||
Group<f_clang_Group>;
|
||||
def funsigned_bitfields : Flag<["-"], "funsigned-bitfields">, Group<f_Group>;
|
||||
def funsigned_char : Flag<["-"], "funsigned-char">, Group<f_Group>;
|
||||
def fno_unsigned_char : Flag<["-"], "fno-unsigned-char">;
|
||||
|
@ -1144,6 +1144,10 @@ void CodeGenModule::Release() {
|
||||
1);
|
||||
}
|
||||
|
||||
if (CodeGenOpts.UniqueSourceFileNames) {
|
||||
getModule().addModuleFlag(llvm::Module::Max, "Unique Source File Names", 1);
|
||||
}
|
||||
|
||||
if (LangOpts.Sanitize.has(SanitizerKind::KCFI)) {
|
||||
getModule().addModuleFlag(llvm::Module::Override, "kcfi", 1);
|
||||
// KCFI assumes patchable-function-prefix is the same for all indirectly
|
||||
|
@ -7744,6 +7744,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
|
||||
Args.addOptInFlag(CmdArgs, options::OPT_fexperimental_late_parse_attributes,
|
||||
options::OPT_fno_experimental_late_parse_attributes);
|
||||
|
||||
Args.addOptInFlag(CmdArgs, options::OPT_funique_source_file_names,
|
||||
options::OPT_fno_unique_source_file_names);
|
||||
|
||||
// Setup statistics file output.
|
||||
SmallString<128> StatsFile = getStatsFileName(Args, Output, Input, D);
|
||||
if (!StatsFile.empty()) {
|
||||
|
2
clang/test/CodeGen/unique-source-file-names.c
Normal file
2
clang/test/CodeGen/unique-source-file-names.c
Normal file
@ -0,0 +1,2 @@
|
||||
// RUN: %clang_cc1 -funique-source-file-names -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s
|
||||
// CHECK: !{i32 7, !"Unique Source File Names", i32 1}
|
5
clang/test/Driver/unique-source-file-names.c
Normal file
5
clang/test/Driver/unique-source-file-names.c
Normal file
@ -0,0 +1,5 @@
|
||||
// RUN: %clang -funique-source-file-names -### %s 2> %t
|
||||
// RUN: FileCheck < %t %s
|
||||
|
||||
// CHECK: "-cc1"
|
||||
// CHECK: "-funique-source-file-names"
|
@ -345,27 +345,25 @@ void llvm::filterDeadComdatFunctions(
|
||||
|
||||
std::string llvm::getUniqueModuleId(Module *M) {
|
||||
MD5 Md5;
|
||||
bool ExportsSymbols = false;
|
||||
auto AddGlobal = [&](GlobalValue &GV) {
|
||||
if (GV.isDeclaration() || GV.getName().starts_with("llvm.") ||
|
||||
!GV.hasExternalLinkage() || GV.hasComdat())
|
||||
return;
|
||||
ExportsSymbols = true;
|
||||
Md5.update(GV.getName());
|
||||
Md5.update(ArrayRef<uint8_t>{0});
|
||||
};
|
||||
|
||||
for (auto &F : *M)
|
||||
AddGlobal(F);
|
||||
for (auto &GV : M->globals())
|
||||
AddGlobal(GV);
|
||||
for (auto &GA : M->aliases())
|
||||
AddGlobal(GA);
|
||||
for (auto &IF : M->ifuncs())
|
||||
AddGlobal(IF);
|
||||
auto *UniqueSourceFileNames = mdconst::extract_or_null<ConstantInt>(
|
||||
M->getModuleFlag("Unique Source File Names"));
|
||||
if (UniqueSourceFileNames && UniqueSourceFileNames->getZExtValue()) {
|
||||
Md5.update(M->getSourceFileName());
|
||||
} else {
|
||||
bool ExportsSymbols = false;
|
||||
for (auto &GV : M->global_values()) {
|
||||
if (GV.isDeclaration() || GV.getName().starts_with("llvm.") ||
|
||||
!GV.hasExternalLinkage() || GV.hasComdat())
|
||||
continue;
|
||||
ExportsSymbols = true;
|
||||
Md5.update(GV.getName());
|
||||
Md5.update(ArrayRef<uint8_t>{0});
|
||||
}
|
||||
|
||||
if (!ExportsSymbols)
|
||||
return "";
|
||||
if (!ExportsSymbols)
|
||||
return "";
|
||||
}
|
||||
|
||||
MD5::MD5Result R;
|
||||
Md5.final(R);
|
||||
|
@ -0,0 +1,22 @@
|
||||
; RUN: opt -thinlto-bc -thin-link-bitcode-file=%t2 -thinlto-split-lto-unit -o %t %s
|
||||
; RUN: llvm-modextract -b -n 1 -o %t1 %t
|
||||
; RUN: llvm-dis -o - %t1 | FileCheck %s
|
||||
|
||||
source_filename = "unique-source-file-names.c"
|
||||
|
||||
@llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr @f, ptr null }]
|
||||
|
||||
; CHECK: @g.45934e8a5251fb7adbecfff71a4e70ed =
|
||||
@g = internal global i8 42, !type !0
|
||||
|
||||
declare void @sink(ptr)
|
||||
|
||||
define internal void @f() {
|
||||
call void @sink(ptr @g)
|
||||
ret void
|
||||
}
|
||||
|
||||
!0 = !{i32 0, !"typeid"}
|
||||
|
||||
!llvm.module.flags = !{!1}
|
||||
!1 = !{i32 1, !"Unique Source File Names", i32 1}
|
Loading…
x
Reference in New Issue
Block a user