-
Notifications
You must be signed in to change notification settings - Fork 12.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[LLVM] Add new attribute has_fake_use for llvm.fake.use-specific logic #109997
Conversation
Following the addition of the llvm.fake.use intrinsic and corresponding MIR instruction, two further changes are planned: to add an -fextend-lifetimes flag to Clang that emits these intrinsics, and to have -Og enable this flag by default. Currently, some logic for handling fake uses is gated by the optdebug attribute, which is intended to be switched on by -fextend-lifetimes (and by extension -Og later on). However, the decision was made that a general `optdebug` attribute should be incompatible with other opt_ attributes (e.g. optsize, optnone), since they all express different intents for how to optimize the program. We would still like to allow -fextend-lifetimes with optsize however (i.e. `-Os -fextend-lifetimes` should be legal), since it may be a useful configuration and there is no technical reason to not allow it. This patch solves this by adding a has_fake_uses function attribute to LLVM, which is added by -fextend-lifetimes and is used for logic that is specific to the fake use intrinsic, without also bundling in other effects of optdebug, which will include limiting or disabling certain optimizations.
@llvm/pr-subscribers-llvm-ir @llvm/pr-subscribers-debuginfo Author: Stephen Tozer (SLTozer) ChangesFollowing the addition of the llvm.fake.use intrinsic and corresponding MIR instruction, two further changes are planned: to add an -fextend-lifetimes flag to Clang that emits these intrinsics, and to have -Og enable this flag by default. Currently, some logic for handling fake uses is gated by the optdebug attribute, which is intended to be switched on by -fextend-lifetimes (and by extension -Og later on). However, the decision was made that a general This patch resolves this by adding a has_fake_uses function attribute to LLVM, which is added by -fextend-lifetimes and is used for logic that is specific to the fake use intrinsic, without also bundling in other effects of optdebug, which will include limiting or disabling certain optimizations. Full diff: https://github.com/llvm/llvm-project/pull/109997.diff 26 Files Affected:
diff --git a/llvm/include/llvm/Bitcode/LLVMBitCodes.h b/llvm/include/llvm/Bitcode/LLVMBitCodes.h
index cbd92fd52fc75a..a49fa0f0698a64 100644
--- a/llvm/include/llvm/Bitcode/LLVMBitCodes.h
+++ b/llvm/include/llvm/Bitcode/LLVMBitCodes.h
@@ -764,6 +764,7 @@ enum AttributeKindCodes {
ATTR_KIND_SANITIZE_REALTIME_UNSAFE = 97,
ATTR_KIND_CORO_ELIDE_SAFE = 98,
ATTR_KIND_NO_EXT = 99,
+ ATTR_KIND_HAS_FAKE_USES = 100,
};
enum ComdatSelectionKindCodes {
diff --git a/llvm/include/llvm/IR/Attributes.td b/llvm/include/llvm/IR/Attributes.td
index 9044d127b47946..28af0e98b2cd20 100644
--- a/llvm/include/llvm/IR/Attributes.td
+++ b/llvm/include/llvm/IR/Attributes.td
@@ -112,6 +112,9 @@ def ElementType : TypeAttr<"elementtype", [ParamAttr]>;
/// symbol.
def FnRetThunkExtern : EnumAttr<"fn_ret_thunk_extern", [FnAttr]>;
+/// Function uses fake use intrinsics to extend variable lifetimes.
+def HasFakeUses : EnumAttr<"has_fake_uses", [FnAttr]>;
+
/// Function has a hybrid patchable thunk.
def HybridPatchable : EnumAttr<"hybrid_patchable", [FnAttr]>;
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index 6f997510b03609..d34c114690dad1 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -2024,6 +2024,8 @@ static Attribute::AttrKind getAttrFromCode(uint64_t Code) {
return Attribute::ElementType;
case bitc::ATTR_KIND_FNRETTHUNK_EXTERN:
return Attribute::FnRetThunkExtern;
+ case bitc::ATTR_KIND_HAS_FAKE_USES:
+ return Attribute::HasFakeUses;
case bitc::ATTR_KIND_INLINE_HINT:
return Attribute::InlineHint;
case bitc::ATTR_KIND_IN_REG:
diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
index d9086bfebbd2a9..e5fedf2aefd6e3 100644
--- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -727,6 +727,8 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) {
return bitc::ATTR_KIND_DISABLE_SANITIZER_INSTRUMENTATION;
case Attribute::FnRetThunkExtern:
return bitc::ATTR_KIND_FNRETTHUNK_EXTERN;
+ case Attribute::HasFakeUses:
+ return bitc::ATTR_KIND_HAS_FAKE_USES;
case Attribute::Hot:
return bitc::ATTR_KIND_HOT;
case Attribute::ElementType:
diff --git a/llvm/lib/CodeGen/RemoveLoadsIntoFakeUses.cpp b/llvm/lib/CodeGen/RemoveLoadsIntoFakeUses.cpp
index 232181a199b8c2..c040a999e60786 100644
--- a/llvm/lib/CodeGen/RemoveLoadsIntoFakeUses.cpp
+++ b/llvm/lib/CodeGen/RemoveLoadsIntoFakeUses.cpp
@@ -74,9 +74,9 @@ INITIALIZE_PASS_END(RemoveLoadsIntoFakeUses, DEBUG_TYPE,
"Remove Loads Into Fake Uses", false, false)
bool RemoveLoadsIntoFakeUses::runOnMachineFunction(MachineFunction &MF) {
- // Only `optdebug` functions should contain FAKE_USEs, so don't try to run
- // this for other functions.
- if (!MF.getFunction().hasFnAttribute(Attribute::OptimizeForDebugging) ||
+ // Only `has_fake_uses` functions should contain FAKE_USEs, so don't try to
+ // run this for other functions.
+ if (!MF.getFunction().hasFnAttribute(Attribute::HasFakeUses) ||
skipFunction(MF.getFunction()))
return false;
diff --git a/llvm/lib/Transforms/Utils/CodeExtractor.cpp b/llvm/lib/Transforms/Utils/CodeExtractor.cpp
index f58448dd9562d5..508dbebd68c015 100644
--- a/llvm/lib/Transforms/Utils/CodeExtractor.cpp
+++ b/llvm/lib/Transforms/Utils/CodeExtractor.cpp
@@ -923,6 +923,7 @@ Function *CodeExtractor::constructFunction(const ValueSet &inputs,
case Attribute::Cold:
case Attribute::DisableSanitizerInstrumentation:
case Attribute::FnRetThunkExtern:
+ case Attribute::HasFakeUses:
case Attribute::Hot:
case Attribute::HybridPatchable:
case Attribute::NoRecurse:
diff --git a/llvm/test/Bitcode/attributes.ll b/llvm/test/Bitcode/attributes.ll
index a66eda19ff5735..e5b0efc489ea67 100644
--- a/llvm/test/Bitcode/attributes.ll
+++ b/llvm/test/Bitcode/attributes.ll
@@ -537,6 +537,11 @@ define void @f91(ptr dead_on_unwind %p) {
ret void
}
+; CHECK: define void @f100() [[HASFAKEUSES:#[0-9]+]]
+define void @f100() has_fake_uses {
+ ret void;
+}
+
; CHECK: define range(i32 -1, 42) i32 @range_attribute(<4 x i32> range(i32 -1, 42) %a)
define range(i32 -1, 42) i32 @range_attribute(<4 x i32> range(i32 -1, 42) %a) {
ret i32 0
@@ -615,4 +620,5 @@ define void @initializes(ptr initializes((-4, 0), (4, 8)) %a) {
; CHECK: attributes [[FNRETTHUNKEXTERN]] = { fn_ret_thunk_extern }
; CHECK: attributes [[SKIPPROFILE]] = { skipprofile }
; CHECK: attributes [[OPTDEBUG]] = { optdebug }
+; CHECK: attributes [[HASFAKEUSES]] = { has_fake_uses }
; CHECK: attributes #[[NOBUILTIN]] = { nobuiltin }
diff --git a/llvm/test/CodeGen/MIR/X86/fake-use-tailcall.mir b/llvm/test/CodeGen/MIR/X86/fake-use-tailcall.mir
index 6c2cb0e55222b2..9576060ade4397 100644
--- a/llvm/test/CodeGen/MIR/X86/fake-use-tailcall.mir
+++ b/llvm/test/CodeGen/MIR/X86/fake-use-tailcall.mir
@@ -35,7 +35,7 @@
# CHECK-NEXT: ret
--- |
- define hidden i32 @foo(i32 %i) local_unnamed_addr optdebug {
+ define hidden i32 @foo(i32 %i) local_unnamed_addr has_fake_uses {
entry:
%cmp = icmp eq i32 %i, 0
br i1 %cmp, label %if.then, label %if.else
diff --git a/llvm/test/CodeGen/X86/fake-use-hpfloat.ll b/llvm/test/CodeGen/X86/fake-use-hpfloat.ll
index fd511a6179acfe..d2548943fc4c8d 100644
--- a/llvm/test/CodeGen/X86/fake-use-hpfloat.ll
+++ b/llvm/test/CodeGen/X86/fake-use-hpfloat.ll
@@ -8,7 +8,7 @@
;
target triple = "x86_64-unknown-unknown"
-define void @_Z6doTestv() local_unnamed_addr optdebug {
+define void @_Z6doTestv() local_unnamed_addr has_fake_uses {
entry:
tail call void (...) @llvm.fake.use(half 0xH0000)
ret void
diff --git a/llvm/test/CodeGen/X86/fake-use-ld.ll b/llvm/test/CodeGen/X86/fake-use-ld.ll
index 86e7235091dd1c..d6ddcb910c53fe 100644
--- a/llvm/test/CodeGen/X86/fake-use-ld.ll
+++ b/llvm/test/CodeGen/X86/fake-use-ld.ll
@@ -10,7 +10,7 @@
; }
; /*******************************************************************/
-define x86_fp80 @actual(x86_fp80 %p1, x86_fp80 %p2, x86_fp80 %p3) optdebug {
+define x86_fp80 @actual(x86_fp80 %p1, x86_fp80 %p2, x86_fp80 %p3) has_fake_uses {
;
; CHECK: actual
;
diff --git a/llvm/test/CodeGen/X86/fake-use-scheduler.mir b/llvm/test/CodeGen/X86/fake-use-scheduler.mir
index 8b82c4ed2485dc..3c3b54eef5ee9a 100644
--- a/llvm/test/CodeGen/X86/fake-use-scheduler.mir
+++ b/llvm/test/CodeGen/X86/fake-use-scheduler.mir
@@ -26,7 +26,7 @@
@glb = common dso_local local_unnamed_addr global [100 x i32] zeroinitializer, align 16
- define dso_local i64 @foo(ptr %p) local_unnamed_addr optdebug {
+ define dso_local i64 @foo(ptr %p) local_unnamed_addr has_fake_uses {
entry:
%0 = load i32, ptr @glb, align 16
store i32 %0, ptr %p, align 4
@@ -43,7 +43,7 @@
ret i64 %add3
}
- define dso_local i64 @bar(ptr %p) local_unnamed_addr optdebug {
+ define dso_local i64 @bar(ptr %p) local_unnamed_addr has_fake_uses {
entry:
%0 = load i32, ptr @glb, align 16
store i32 %0, ptr %p, align 4
diff --git a/llvm/test/CodeGen/X86/fake-use-simple-tail-call.ll b/llvm/test/CodeGen/X86/fake-use-simple-tail-call.ll
index 45a210ef391009..b9c92692585e41 100644
--- a/llvm/test/CodeGen/X86/fake-use-simple-tail-call.ll
+++ b/llvm/test/CodeGen/X86/fake-use-simple-tail-call.ll
@@ -14,7 +14,7 @@
; ModuleID = 'test.cpp'
source_filename = "test.cpp"
-define i32 @_Z4foo1i(i32 %i) local_unnamed_addr optdebug {
+define i32 @_Z4foo1i(i32 %i) local_unnamed_addr has_fake_uses {
entry:
%call = tail call i32 @_Z3bari(i32 %i)
tail call void (...) @llvm.fake.use(i32 %i)
diff --git a/llvm/test/CodeGen/X86/fake-use-suppress-load.ll b/llvm/test/CodeGen/X86/fake-use-suppress-load.ll
index c1b442ebd79ffa..b50b10fdb71d05 100644
--- a/llvm/test/CodeGen/X86/fake-use-suppress-load.ll
+++ b/llvm/test/CodeGen/X86/fake-use-suppress-load.ll
@@ -6,7 +6,7 @@
; CHECK: movq %r{{[a-z]+,}} -{{[0-9]+\(%rsp\)}}
; CHECK-NOT: movq -{{[0-9]+\(%rsp\)}}, %r{{[a-z]+}}
-define dso_local i32 @f(ptr %p) local_unnamed_addr optdebug {
+define dso_local i32 @f(ptr %p) local_unnamed_addr has_fake_uses {
entry:
call void asm sideeffect "", "~{rax},~{rbx},~{rcx},~{rdx},~{rsi},~{rdi},~{rbp},~{r8},~{r9},~{r10},~{r11},~{r12},~{r13},~{r14},~{r15},~{dirflag},~{fpsr},~{flags}"() #1
notail call void (...) @llvm.fake.use(ptr %p)
diff --git a/llvm/test/CodeGen/X86/fake-use-tailcall.ll b/llvm/test/CodeGen/X86/fake-use-tailcall.ll
index 67c28dcf1301c4..f0bbc0fa4734ea 100644
--- a/llvm/test/CodeGen/X86/fake-use-tailcall.ll
+++ b/llvm/test/CodeGen/X86/fake-use-tailcall.ll
@@ -17,7 +17,7 @@
; CHECK: FAKE_USE %0
; CHECK: TCRETURN
-define void @bar(i32 %v) optdebug {
+define void @bar(i32 %v) has_fake_uses {
entry:
%call = tail call i32 @_Z3fooi(i32 %v)
%mul = mul nsw i32 %call, 3
@@ -27,7 +27,7 @@ entry:
ret void
}
-define i32 @baz(i32 %v) optdebug {
+define i32 @baz(i32 %v) has_fake_uses {
entry:
%call = tail call i32 @_Z3fooi(i32 %v)
notail call void (...) @llvm.fake.use(i32 %v)
diff --git a/llvm/test/CodeGen/X86/fake-use-vector.ll b/llvm/test/CodeGen/X86/fake-use-vector.ll
index 4d6ede30827046..9d815eef748804 100644
--- a/llvm/test/CodeGen/X86/fake-use-vector.ll
+++ b/llvm/test/CodeGen/X86/fake-use-vector.ll
@@ -36,4 +36,4 @@ declare <4 x float> @llvm.x86.sse.cvtpi2ps(<4 x float>, <1 x i64>)
; Function Attrs: nounwind
declare void @llvm.fake.use(...)
-attributes #0 = { "target-cpu"="btver2" optdebug }
+attributes #0 = { "target-cpu"="btver2" has_fake_uses }
diff --git a/llvm/test/CodeGen/X86/fake-use-vector2.ll b/llvm/test/CodeGen/X86/fake-use-vector2.ll
index 190197615775a9..868afa4bf897cb 100644
--- a/llvm/test/CodeGen/X86/fake-use-vector2.ll
+++ b/llvm/test/CodeGen/X86/fake-use-vector2.ll
@@ -24,4 +24,4 @@ entry:
declare void @llvm.fake.use(...)
-attributes #0 = { "target-cpu"="btver2" optdebug }
+attributes #0 = { "target-cpu"="btver2" has_fake_uses }
diff --git a/llvm/test/CodeGen/X86/fake-use-zero-length.ll b/llvm/test/CodeGen/X86/fake-use-zero-length.ll
index e3bdd2659dd913..16578327c068aa 100644
--- a/llvm/test/CodeGen/X86/fake-use-zero-length.ll
+++ b/llvm/test/CodeGen/X86/fake-use-zero-length.ll
@@ -17,7 +17,7 @@
source_filename = "test.ll"
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
-define hidden i32 @main([0 x i32] %zero, [1 x i32] %one) local_unnamed_addr optdebug {
+define hidden i32 @main([0 x i32] %zero, [1 x i32] %one) local_unnamed_addr has_fake_uses {
entry:
notail call void (...) @bar([0 x i32] %zero)
notail call void (...) @baz([1 x i32] %one)
diff --git a/llvm/test/DebugInfo/AArch64/fake-use-global-isel.ll b/llvm/test/DebugInfo/AArch64/fake-use-global-isel.ll
index 65a64583096959..bb0b69e9f21073 100644
--- a/llvm/test/DebugInfo/AArch64/fake-use-global-isel.ll
+++ b/llvm/test/DebugInfo/AArch64/fake-use-global-isel.ll
@@ -33,7 +33,7 @@ source_filename = "t2.c"
@glob = common local_unnamed_addr global [10 x i32] zeroinitializer, align 16, !dbg !0
; Function Attrs: nounwind sspstrong uwtable
-define i32 @foo(i32 %b, i32 %i) local_unnamed_addr optdebug !dbg !13 {
+define i32 @foo(i32 %b, i32 %i) local_unnamed_addr has_fake_uses !dbg !13 {
entry:
#dbg_value(i32 %b, !17, !20, !21)
%c = add i32 %b, 42
diff --git a/llvm/test/DebugInfo/X86/fake-use.ll b/llvm/test/DebugInfo/X86/fake-use.ll
index 5ac5104a167118..27c5be16be7a05 100644
--- a/llvm/test/DebugInfo/X86/fake-use.ll
+++ b/llvm/test/DebugInfo/X86/fake-use.ll
@@ -30,7 +30,7 @@ source_filename = "t2.c"
@glob = common local_unnamed_addr global [10 x i32] zeroinitializer, align 16, !dbg !0
; Function Attrs: nounwind sspstrong uwtable
-define i32 @foo(i32 %b, i32 %i) local_unnamed_addr optdebug !dbg !13 {
+define i32 @foo(i32 %b, i32 %i) local_unnamed_addr has_fake_uses !dbg !13 {
entry:
#dbg_value(i32 %b, !17, !20, !21)
%c = add i32 %b, 42
diff --git a/llvm/test/Transforms/CodeGenPrepare/X86/fake-use-phi.ll b/llvm/test/Transforms/CodeGenPrepare/X86/fake-use-phi.ll
index 064d3f29dd9ebb..c8b280e7c3d042 100644
--- a/llvm/test/Transforms/CodeGenPrepare/X86/fake-use-phi.ll
+++ b/llvm/test/Transforms/CodeGenPrepare/X86/fake-use-phi.ll
@@ -25,7 +25,7 @@ source_filename = "test.ll"
declare i32 @foo(ptr nonnull dereferenceable(1)) local_unnamed_addr
declare i32 @bar(ptr nonnull dereferenceable(1)) local_unnamed_addr
-define hidden void @func(ptr nonnull dereferenceable(1) %this) local_unnamed_addr align 2 optdebug {
+define hidden void @func(ptr nonnull dereferenceable(1) %this) local_unnamed_addr align 2 has_fake_uses {
entry:
%b = getelementptr inbounds %class.a, ptr %this, i64 0, i32 0
%0 = load i8, i8* %b, align 1
diff --git a/llvm/test/Transforms/CodeGenPrepare/X86/fake-use-split-ret.ll b/llvm/test/Transforms/CodeGenPrepare/X86/fake-use-split-ret.ll
index b2cf89f6f2dd82..ffa61174c60f09 100644
--- a/llvm/test/Transforms/CodeGenPrepare/X86/fake-use-split-ret.ll
+++ b/llvm/test/Transforms/CodeGenPrepare/X86/fake-use-split-ret.ll
@@ -17,7 +17,7 @@
declare i32 @_Z3bari(i32) local_unnamed_addr
-define i32 @_Z4foo2i(i32 %i) local_unnamed_addr optdebug {
+define i32 @_Z4foo2i(i32 %i) local_unnamed_addr has_fake_uses {
entry:
%dec = add nsw i32 %i, -1
%cmp = icmp slt i32 %i, 2
diff --git a/llvm/test/Transforms/GVN/fake-use-constprop.ll b/llvm/test/Transforms/GVN/fake-use-constprop.ll
index 1466f9f9fca277..9691de90170132 100644
--- a/llvm/test/Transforms/GVN/fake-use-constprop.ll
+++ b/llvm/test/Transforms/GVN/fake-use-constprop.ll
@@ -37,7 +37,7 @@
; CHECK: call {{.+}} @bees(i8 0)
; CHECK: call {{.+}} @llvm.fake.use(i8 %[[CONV_VAR]])
-define i32 @foo(float %f) optdebug {
+define i32 @foo(float %f) has_fake_uses {
%conv = fptosi float %f to i8
%tobool3 = icmp eq i8 %conv, 0
br i1 %tobool3, label %if.end, label %lab
diff --git a/llvm/test/Transforms/SROA/fake-use-sroa.ll b/llvm/test/Transforms/SROA/fake-use-sroa.ll
index 9e92df15487506..9a342ca53719fa 100644
--- a/llvm/test/Transforms/SROA/fake-use-sroa.ll
+++ b/llvm/test/Transforms/SROA/fake-use-sroa.ll
@@ -25,7 +25,7 @@
; CHECK: %[[SLICE2:[^ ]+]] = trunc i64
; CHECK-DAG: call{{.*}} @llvm.fake.use(i32 %[[SLICE1]])
; CHECK-DAG: call{{.*}} @llvm.fake.use(i32 %[[SLICE2]])
-define dso_local void @foo(i64 %S.coerce) optdebug {
+define dso_local void @foo(i64 %S.coerce) has_fake_uses {
entry:
%S = alloca %struct.s, align 4
store i64 %S.coerce, ptr %S, align 4
@@ -40,7 +40,7 @@ entry:
; CHECK: %[[ARRAYSLICE2:[^ ]+]] = load
; CHECK-DAG: call{{.*}} @llvm.fake.use(i32 %[[ARRAYSLICE1]])
; CHECK-DAG: call{{.*}} @llvm.fake.use(i32 %[[ARRAYSLICE2]])
-define dso_local void @bar() optdebug {
+define dso_local void @bar() has_fake_uses {
entry:
%arr = alloca [2 x i32], align 4
call void @llvm.memcpy.p0i8.p0i8.i64(ptr align 4 %arr, ptr align 4 bitcast (ptr @__const.bar.arr to ptr), i64 8, i1 false)
diff --git a/llvm/utils/emacs/llvm-mode.el b/llvm/utils/emacs/llvm-mode.el
index dab37833ff63a9..30b6a8610a3515 100644
--- a/llvm/utils/emacs/llvm-mode.el
+++ b/llvm/utils/emacs/llvm-mode.el
@@ -30,7 +30,7 @@
(list
;; Attributes
`(,(regexp-opt
- '("alwaysinline" "argmemonly" "allocsize" "builtin" "cold" "convergent" "dereferenceable" "dereferenceable_or_null" "hot" "immarg" "inaccessiblememonly"
+ '("alwaysinline" "argmemonly" "allocsize" "builtin" "cold" "convergent" "dereferenceable" "dereferenceable_or_null" "has_fake_uses" "hot" "immarg" "inaccessiblememonly"
"inaccessiblemem_or_argmemonly" "inalloca" "inlinehint" "jumptable" "minsize" "mustprogress" "naked" "nobuiltin" "nonnull" "nocapture"
"nocallback" "nocf_check" "noduplicate" "nofree" "noimplicitfloat" "noinline" "nomerge" "nonlazybind" "noprofile" "noredzone" "noreturn"
"norecurse" "nosync" "noundef" "nounwind" "nosanitize_bounds" "nosanitize_coverage" "null_pointer_is_valid" "optdebug" "optforfuzzing" "optnone" "optsize" "preallocated" "readnone" "readonly" "returned" "returns_twice"
diff --git a/llvm/utils/kate/llvm.xml b/llvm/utils/kate/llvm.xml
index 0e7aec3880e6b4..3cd76a084e48b6 100644
--- a/llvm/utils/kate/llvm.xml
+++ b/llvm/utils/kate/llvm.xml
@@ -87,6 +87,7 @@
<item> dereferenceable_or_null </item>
<item> extern_weak </item>
<item> hhvmcc </item>
+ <item> has_fake_uses </item>
<item> hot </item>
<item> inaccessiblemem_or_argmemonly </item>
<item> inaccessiblememonly </item>
diff --git a/llvm/utils/vim/syntax/llvm.vim b/llvm/utils/vim/syntax/llvm.vim
index fac509c355cb8a..9a89ba32c33760 100644
--- a/llvm/utils/vim/syntax/llvm.vim
+++ b/llvm/utils/vim/syntax/llvm.vim
@@ -94,6 +94,7 @@ syn keyword llvmKeyword
\ from
\ gc
\ global
+ \ has_fake_uses
\ hhvm_ccc
\ hhvmcc
\ hidden
|
@llvm/pr-subscribers-backend-x86 Author: Stephen Tozer (SLTozer) ChangesFollowing the addition of the llvm.fake.use intrinsic and corresponding MIR instruction, two further changes are planned: to add an -fextend-lifetimes flag to Clang that emits these intrinsics, and to have -Og enable this flag by default. Currently, some logic for handling fake uses is gated by the optdebug attribute, which is intended to be switched on by -fextend-lifetimes (and by extension -Og later on). However, the decision was made that a general This patch resolves this by adding a has_fake_uses function attribute to LLVM, which is added by -fextend-lifetimes and is used for logic that is specific to the fake use intrinsic, without also bundling in other effects of optdebug, which will include limiting or disabling certain optimizations. Full diff: https://github.com/llvm/llvm-project/pull/109997.diff 26 Files Affected:
diff --git a/llvm/include/llvm/Bitcode/LLVMBitCodes.h b/llvm/include/llvm/Bitcode/LLVMBitCodes.h
index cbd92fd52fc75a..a49fa0f0698a64 100644
--- a/llvm/include/llvm/Bitcode/LLVMBitCodes.h
+++ b/llvm/include/llvm/Bitcode/LLVMBitCodes.h
@@ -764,6 +764,7 @@ enum AttributeKindCodes {
ATTR_KIND_SANITIZE_REALTIME_UNSAFE = 97,
ATTR_KIND_CORO_ELIDE_SAFE = 98,
ATTR_KIND_NO_EXT = 99,
+ ATTR_KIND_HAS_FAKE_USES = 100,
};
enum ComdatSelectionKindCodes {
diff --git a/llvm/include/llvm/IR/Attributes.td b/llvm/include/llvm/IR/Attributes.td
index 9044d127b47946..28af0e98b2cd20 100644
--- a/llvm/include/llvm/IR/Attributes.td
+++ b/llvm/include/llvm/IR/Attributes.td
@@ -112,6 +112,9 @@ def ElementType : TypeAttr<"elementtype", [ParamAttr]>;
/// symbol.
def FnRetThunkExtern : EnumAttr<"fn_ret_thunk_extern", [FnAttr]>;
+/// Function uses fake use intrinsics to extend variable lifetimes.
+def HasFakeUses : EnumAttr<"has_fake_uses", [FnAttr]>;
+
/// Function has a hybrid patchable thunk.
def HybridPatchable : EnumAttr<"hybrid_patchable", [FnAttr]>;
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index 6f997510b03609..d34c114690dad1 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -2024,6 +2024,8 @@ static Attribute::AttrKind getAttrFromCode(uint64_t Code) {
return Attribute::ElementType;
case bitc::ATTR_KIND_FNRETTHUNK_EXTERN:
return Attribute::FnRetThunkExtern;
+ case bitc::ATTR_KIND_HAS_FAKE_USES:
+ return Attribute::HasFakeUses;
case bitc::ATTR_KIND_INLINE_HINT:
return Attribute::InlineHint;
case bitc::ATTR_KIND_IN_REG:
diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
index d9086bfebbd2a9..e5fedf2aefd6e3 100644
--- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -727,6 +727,8 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) {
return bitc::ATTR_KIND_DISABLE_SANITIZER_INSTRUMENTATION;
case Attribute::FnRetThunkExtern:
return bitc::ATTR_KIND_FNRETTHUNK_EXTERN;
+ case Attribute::HasFakeUses:
+ return bitc::ATTR_KIND_HAS_FAKE_USES;
case Attribute::Hot:
return bitc::ATTR_KIND_HOT;
case Attribute::ElementType:
diff --git a/llvm/lib/CodeGen/RemoveLoadsIntoFakeUses.cpp b/llvm/lib/CodeGen/RemoveLoadsIntoFakeUses.cpp
index 232181a199b8c2..c040a999e60786 100644
--- a/llvm/lib/CodeGen/RemoveLoadsIntoFakeUses.cpp
+++ b/llvm/lib/CodeGen/RemoveLoadsIntoFakeUses.cpp
@@ -74,9 +74,9 @@ INITIALIZE_PASS_END(RemoveLoadsIntoFakeUses, DEBUG_TYPE,
"Remove Loads Into Fake Uses", false, false)
bool RemoveLoadsIntoFakeUses::runOnMachineFunction(MachineFunction &MF) {
- // Only `optdebug` functions should contain FAKE_USEs, so don't try to run
- // this for other functions.
- if (!MF.getFunction().hasFnAttribute(Attribute::OptimizeForDebugging) ||
+ // Only `has_fake_uses` functions should contain FAKE_USEs, so don't try to
+ // run this for other functions.
+ if (!MF.getFunction().hasFnAttribute(Attribute::HasFakeUses) ||
skipFunction(MF.getFunction()))
return false;
diff --git a/llvm/lib/Transforms/Utils/CodeExtractor.cpp b/llvm/lib/Transforms/Utils/CodeExtractor.cpp
index f58448dd9562d5..508dbebd68c015 100644
--- a/llvm/lib/Transforms/Utils/CodeExtractor.cpp
+++ b/llvm/lib/Transforms/Utils/CodeExtractor.cpp
@@ -923,6 +923,7 @@ Function *CodeExtractor::constructFunction(const ValueSet &inputs,
case Attribute::Cold:
case Attribute::DisableSanitizerInstrumentation:
case Attribute::FnRetThunkExtern:
+ case Attribute::HasFakeUses:
case Attribute::Hot:
case Attribute::HybridPatchable:
case Attribute::NoRecurse:
diff --git a/llvm/test/Bitcode/attributes.ll b/llvm/test/Bitcode/attributes.ll
index a66eda19ff5735..e5b0efc489ea67 100644
--- a/llvm/test/Bitcode/attributes.ll
+++ b/llvm/test/Bitcode/attributes.ll
@@ -537,6 +537,11 @@ define void @f91(ptr dead_on_unwind %p) {
ret void
}
+; CHECK: define void @f100() [[HASFAKEUSES:#[0-9]+]]
+define void @f100() has_fake_uses {
+ ret void;
+}
+
; CHECK: define range(i32 -1, 42) i32 @range_attribute(<4 x i32> range(i32 -1, 42) %a)
define range(i32 -1, 42) i32 @range_attribute(<4 x i32> range(i32 -1, 42) %a) {
ret i32 0
@@ -615,4 +620,5 @@ define void @initializes(ptr initializes((-4, 0), (4, 8)) %a) {
; CHECK: attributes [[FNRETTHUNKEXTERN]] = { fn_ret_thunk_extern }
; CHECK: attributes [[SKIPPROFILE]] = { skipprofile }
; CHECK: attributes [[OPTDEBUG]] = { optdebug }
+; CHECK: attributes [[HASFAKEUSES]] = { has_fake_uses }
; CHECK: attributes #[[NOBUILTIN]] = { nobuiltin }
diff --git a/llvm/test/CodeGen/MIR/X86/fake-use-tailcall.mir b/llvm/test/CodeGen/MIR/X86/fake-use-tailcall.mir
index 6c2cb0e55222b2..9576060ade4397 100644
--- a/llvm/test/CodeGen/MIR/X86/fake-use-tailcall.mir
+++ b/llvm/test/CodeGen/MIR/X86/fake-use-tailcall.mir
@@ -35,7 +35,7 @@
# CHECK-NEXT: ret
--- |
- define hidden i32 @foo(i32 %i) local_unnamed_addr optdebug {
+ define hidden i32 @foo(i32 %i) local_unnamed_addr has_fake_uses {
entry:
%cmp = icmp eq i32 %i, 0
br i1 %cmp, label %if.then, label %if.else
diff --git a/llvm/test/CodeGen/X86/fake-use-hpfloat.ll b/llvm/test/CodeGen/X86/fake-use-hpfloat.ll
index fd511a6179acfe..d2548943fc4c8d 100644
--- a/llvm/test/CodeGen/X86/fake-use-hpfloat.ll
+++ b/llvm/test/CodeGen/X86/fake-use-hpfloat.ll
@@ -8,7 +8,7 @@
;
target triple = "x86_64-unknown-unknown"
-define void @_Z6doTestv() local_unnamed_addr optdebug {
+define void @_Z6doTestv() local_unnamed_addr has_fake_uses {
entry:
tail call void (...) @llvm.fake.use(half 0xH0000)
ret void
diff --git a/llvm/test/CodeGen/X86/fake-use-ld.ll b/llvm/test/CodeGen/X86/fake-use-ld.ll
index 86e7235091dd1c..d6ddcb910c53fe 100644
--- a/llvm/test/CodeGen/X86/fake-use-ld.ll
+++ b/llvm/test/CodeGen/X86/fake-use-ld.ll
@@ -10,7 +10,7 @@
; }
; /*******************************************************************/
-define x86_fp80 @actual(x86_fp80 %p1, x86_fp80 %p2, x86_fp80 %p3) optdebug {
+define x86_fp80 @actual(x86_fp80 %p1, x86_fp80 %p2, x86_fp80 %p3) has_fake_uses {
;
; CHECK: actual
;
diff --git a/llvm/test/CodeGen/X86/fake-use-scheduler.mir b/llvm/test/CodeGen/X86/fake-use-scheduler.mir
index 8b82c4ed2485dc..3c3b54eef5ee9a 100644
--- a/llvm/test/CodeGen/X86/fake-use-scheduler.mir
+++ b/llvm/test/CodeGen/X86/fake-use-scheduler.mir
@@ -26,7 +26,7 @@
@glb = common dso_local local_unnamed_addr global [100 x i32] zeroinitializer, align 16
- define dso_local i64 @foo(ptr %p) local_unnamed_addr optdebug {
+ define dso_local i64 @foo(ptr %p) local_unnamed_addr has_fake_uses {
entry:
%0 = load i32, ptr @glb, align 16
store i32 %0, ptr %p, align 4
@@ -43,7 +43,7 @@
ret i64 %add3
}
- define dso_local i64 @bar(ptr %p) local_unnamed_addr optdebug {
+ define dso_local i64 @bar(ptr %p) local_unnamed_addr has_fake_uses {
entry:
%0 = load i32, ptr @glb, align 16
store i32 %0, ptr %p, align 4
diff --git a/llvm/test/CodeGen/X86/fake-use-simple-tail-call.ll b/llvm/test/CodeGen/X86/fake-use-simple-tail-call.ll
index 45a210ef391009..b9c92692585e41 100644
--- a/llvm/test/CodeGen/X86/fake-use-simple-tail-call.ll
+++ b/llvm/test/CodeGen/X86/fake-use-simple-tail-call.ll
@@ -14,7 +14,7 @@
; ModuleID = 'test.cpp'
source_filename = "test.cpp"
-define i32 @_Z4foo1i(i32 %i) local_unnamed_addr optdebug {
+define i32 @_Z4foo1i(i32 %i) local_unnamed_addr has_fake_uses {
entry:
%call = tail call i32 @_Z3bari(i32 %i)
tail call void (...) @llvm.fake.use(i32 %i)
diff --git a/llvm/test/CodeGen/X86/fake-use-suppress-load.ll b/llvm/test/CodeGen/X86/fake-use-suppress-load.ll
index c1b442ebd79ffa..b50b10fdb71d05 100644
--- a/llvm/test/CodeGen/X86/fake-use-suppress-load.ll
+++ b/llvm/test/CodeGen/X86/fake-use-suppress-load.ll
@@ -6,7 +6,7 @@
; CHECK: movq %r{{[a-z]+,}} -{{[0-9]+\(%rsp\)}}
; CHECK-NOT: movq -{{[0-9]+\(%rsp\)}}, %r{{[a-z]+}}
-define dso_local i32 @f(ptr %p) local_unnamed_addr optdebug {
+define dso_local i32 @f(ptr %p) local_unnamed_addr has_fake_uses {
entry:
call void asm sideeffect "", "~{rax},~{rbx},~{rcx},~{rdx},~{rsi},~{rdi},~{rbp},~{r8},~{r9},~{r10},~{r11},~{r12},~{r13},~{r14},~{r15},~{dirflag},~{fpsr},~{flags}"() #1
notail call void (...) @llvm.fake.use(ptr %p)
diff --git a/llvm/test/CodeGen/X86/fake-use-tailcall.ll b/llvm/test/CodeGen/X86/fake-use-tailcall.ll
index 67c28dcf1301c4..f0bbc0fa4734ea 100644
--- a/llvm/test/CodeGen/X86/fake-use-tailcall.ll
+++ b/llvm/test/CodeGen/X86/fake-use-tailcall.ll
@@ -17,7 +17,7 @@
; CHECK: FAKE_USE %0
; CHECK: TCRETURN
-define void @bar(i32 %v) optdebug {
+define void @bar(i32 %v) has_fake_uses {
entry:
%call = tail call i32 @_Z3fooi(i32 %v)
%mul = mul nsw i32 %call, 3
@@ -27,7 +27,7 @@ entry:
ret void
}
-define i32 @baz(i32 %v) optdebug {
+define i32 @baz(i32 %v) has_fake_uses {
entry:
%call = tail call i32 @_Z3fooi(i32 %v)
notail call void (...) @llvm.fake.use(i32 %v)
diff --git a/llvm/test/CodeGen/X86/fake-use-vector.ll b/llvm/test/CodeGen/X86/fake-use-vector.ll
index 4d6ede30827046..9d815eef748804 100644
--- a/llvm/test/CodeGen/X86/fake-use-vector.ll
+++ b/llvm/test/CodeGen/X86/fake-use-vector.ll
@@ -36,4 +36,4 @@ declare <4 x float> @llvm.x86.sse.cvtpi2ps(<4 x float>, <1 x i64>)
; Function Attrs: nounwind
declare void @llvm.fake.use(...)
-attributes #0 = { "target-cpu"="btver2" optdebug }
+attributes #0 = { "target-cpu"="btver2" has_fake_uses }
diff --git a/llvm/test/CodeGen/X86/fake-use-vector2.ll b/llvm/test/CodeGen/X86/fake-use-vector2.ll
index 190197615775a9..868afa4bf897cb 100644
--- a/llvm/test/CodeGen/X86/fake-use-vector2.ll
+++ b/llvm/test/CodeGen/X86/fake-use-vector2.ll
@@ -24,4 +24,4 @@ entry:
declare void @llvm.fake.use(...)
-attributes #0 = { "target-cpu"="btver2" optdebug }
+attributes #0 = { "target-cpu"="btver2" has_fake_uses }
diff --git a/llvm/test/CodeGen/X86/fake-use-zero-length.ll b/llvm/test/CodeGen/X86/fake-use-zero-length.ll
index e3bdd2659dd913..16578327c068aa 100644
--- a/llvm/test/CodeGen/X86/fake-use-zero-length.ll
+++ b/llvm/test/CodeGen/X86/fake-use-zero-length.ll
@@ -17,7 +17,7 @@
source_filename = "test.ll"
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
-define hidden i32 @main([0 x i32] %zero, [1 x i32] %one) local_unnamed_addr optdebug {
+define hidden i32 @main([0 x i32] %zero, [1 x i32] %one) local_unnamed_addr has_fake_uses {
entry:
notail call void (...) @bar([0 x i32] %zero)
notail call void (...) @baz([1 x i32] %one)
diff --git a/llvm/test/DebugInfo/AArch64/fake-use-global-isel.ll b/llvm/test/DebugInfo/AArch64/fake-use-global-isel.ll
index 65a64583096959..bb0b69e9f21073 100644
--- a/llvm/test/DebugInfo/AArch64/fake-use-global-isel.ll
+++ b/llvm/test/DebugInfo/AArch64/fake-use-global-isel.ll
@@ -33,7 +33,7 @@ source_filename = "t2.c"
@glob = common local_unnamed_addr global [10 x i32] zeroinitializer, align 16, !dbg !0
; Function Attrs: nounwind sspstrong uwtable
-define i32 @foo(i32 %b, i32 %i) local_unnamed_addr optdebug !dbg !13 {
+define i32 @foo(i32 %b, i32 %i) local_unnamed_addr has_fake_uses !dbg !13 {
entry:
#dbg_value(i32 %b, !17, !20, !21)
%c = add i32 %b, 42
diff --git a/llvm/test/DebugInfo/X86/fake-use.ll b/llvm/test/DebugInfo/X86/fake-use.ll
index 5ac5104a167118..27c5be16be7a05 100644
--- a/llvm/test/DebugInfo/X86/fake-use.ll
+++ b/llvm/test/DebugInfo/X86/fake-use.ll
@@ -30,7 +30,7 @@ source_filename = "t2.c"
@glob = common local_unnamed_addr global [10 x i32] zeroinitializer, align 16, !dbg !0
; Function Attrs: nounwind sspstrong uwtable
-define i32 @foo(i32 %b, i32 %i) local_unnamed_addr optdebug !dbg !13 {
+define i32 @foo(i32 %b, i32 %i) local_unnamed_addr has_fake_uses !dbg !13 {
entry:
#dbg_value(i32 %b, !17, !20, !21)
%c = add i32 %b, 42
diff --git a/llvm/test/Transforms/CodeGenPrepare/X86/fake-use-phi.ll b/llvm/test/Transforms/CodeGenPrepare/X86/fake-use-phi.ll
index 064d3f29dd9ebb..c8b280e7c3d042 100644
--- a/llvm/test/Transforms/CodeGenPrepare/X86/fake-use-phi.ll
+++ b/llvm/test/Transforms/CodeGenPrepare/X86/fake-use-phi.ll
@@ -25,7 +25,7 @@ source_filename = "test.ll"
declare i32 @foo(ptr nonnull dereferenceable(1)) local_unnamed_addr
declare i32 @bar(ptr nonnull dereferenceable(1)) local_unnamed_addr
-define hidden void @func(ptr nonnull dereferenceable(1) %this) local_unnamed_addr align 2 optdebug {
+define hidden void @func(ptr nonnull dereferenceable(1) %this) local_unnamed_addr align 2 has_fake_uses {
entry:
%b = getelementptr inbounds %class.a, ptr %this, i64 0, i32 0
%0 = load i8, i8* %b, align 1
diff --git a/llvm/test/Transforms/CodeGenPrepare/X86/fake-use-split-ret.ll b/llvm/test/Transforms/CodeGenPrepare/X86/fake-use-split-ret.ll
index b2cf89f6f2dd82..ffa61174c60f09 100644
--- a/llvm/test/Transforms/CodeGenPrepare/X86/fake-use-split-ret.ll
+++ b/llvm/test/Transforms/CodeGenPrepare/X86/fake-use-split-ret.ll
@@ -17,7 +17,7 @@
declare i32 @_Z3bari(i32) local_unnamed_addr
-define i32 @_Z4foo2i(i32 %i) local_unnamed_addr optdebug {
+define i32 @_Z4foo2i(i32 %i) local_unnamed_addr has_fake_uses {
entry:
%dec = add nsw i32 %i, -1
%cmp = icmp slt i32 %i, 2
diff --git a/llvm/test/Transforms/GVN/fake-use-constprop.ll b/llvm/test/Transforms/GVN/fake-use-constprop.ll
index 1466f9f9fca277..9691de90170132 100644
--- a/llvm/test/Transforms/GVN/fake-use-constprop.ll
+++ b/llvm/test/Transforms/GVN/fake-use-constprop.ll
@@ -37,7 +37,7 @@
; CHECK: call {{.+}} @bees(i8 0)
; CHECK: call {{.+}} @llvm.fake.use(i8 %[[CONV_VAR]])
-define i32 @foo(float %f) optdebug {
+define i32 @foo(float %f) has_fake_uses {
%conv = fptosi float %f to i8
%tobool3 = icmp eq i8 %conv, 0
br i1 %tobool3, label %if.end, label %lab
diff --git a/llvm/test/Transforms/SROA/fake-use-sroa.ll b/llvm/test/Transforms/SROA/fake-use-sroa.ll
index 9e92df15487506..9a342ca53719fa 100644
--- a/llvm/test/Transforms/SROA/fake-use-sroa.ll
+++ b/llvm/test/Transforms/SROA/fake-use-sroa.ll
@@ -25,7 +25,7 @@
; CHECK: %[[SLICE2:[^ ]+]] = trunc i64
; CHECK-DAG: call{{.*}} @llvm.fake.use(i32 %[[SLICE1]])
; CHECK-DAG: call{{.*}} @llvm.fake.use(i32 %[[SLICE2]])
-define dso_local void @foo(i64 %S.coerce) optdebug {
+define dso_local void @foo(i64 %S.coerce) has_fake_uses {
entry:
%S = alloca %struct.s, align 4
store i64 %S.coerce, ptr %S, align 4
@@ -40,7 +40,7 @@ entry:
; CHECK: %[[ARRAYSLICE2:[^ ]+]] = load
; CHECK-DAG: call{{.*}} @llvm.fake.use(i32 %[[ARRAYSLICE1]])
; CHECK-DAG: call{{.*}} @llvm.fake.use(i32 %[[ARRAYSLICE2]])
-define dso_local void @bar() optdebug {
+define dso_local void @bar() has_fake_uses {
entry:
%arr = alloca [2 x i32], align 4
call void @llvm.memcpy.p0i8.p0i8.i64(ptr align 4 %arr, ptr align 4 bitcast (ptr @__const.bar.arr to ptr), i64 8, i1 false)
diff --git a/llvm/utils/emacs/llvm-mode.el b/llvm/utils/emacs/llvm-mode.el
index dab37833ff63a9..30b6a8610a3515 100644
--- a/llvm/utils/emacs/llvm-mode.el
+++ b/llvm/utils/emacs/llvm-mode.el
@@ -30,7 +30,7 @@
(list
;; Attributes
`(,(regexp-opt
- '("alwaysinline" "argmemonly" "allocsize" "builtin" "cold" "convergent" "dereferenceable" "dereferenceable_or_null" "hot" "immarg" "inaccessiblememonly"
+ '("alwaysinline" "argmemonly" "allocsize" "builtin" "cold" "convergent" "dereferenceable" "dereferenceable_or_null" "has_fake_uses" "hot" "immarg" "inaccessiblememonly"
"inaccessiblemem_or_argmemonly" "inalloca" "inlinehint" "jumptable" "minsize" "mustprogress" "naked" "nobuiltin" "nonnull" "nocapture"
"nocallback" "nocf_check" "noduplicate" "nofree" "noimplicitfloat" "noinline" "nomerge" "nonlazybind" "noprofile" "noredzone" "noreturn"
"norecurse" "nosync" "noundef" "nounwind" "nosanitize_bounds" "nosanitize_coverage" "null_pointer_is_valid" "optdebug" "optforfuzzing" "optnone" "optsize" "preallocated" "readnone" "readonly" "returned" "returns_twice"
diff --git a/llvm/utils/kate/llvm.xml b/llvm/utils/kate/llvm.xml
index 0e7aec3880e6b4..3cd76a084e48b6 100644
--- a/llvm/utils/kate/llvm.xml
+++ b/llvm/utils/kate/llvm.xml
@@ -87,6 +87,7 @@
<item> dereferenceable_or_null </item>
<item> extern_weak </item>
<item> hhvmcc </item>
+ <item> has_fake_uses </item>
<item> hot </item>
<item> inaccessiblemem_or_argmemonly </item>
<item> inaccessiblememonly </item>
diff --git a/llvm/utils/vim/syntax/llvm.vim b/llvm/utils/vim/syntax/llvm.vim
index fac509c355cb8a..9a89ba32c33760 100644
--- a/llvm/utils/vim/syntax/llvm.vim
+++ b/llvm/utils/vim/syntax/llvm.vim
@@ -94,6 +94,7 @@ syn keyword llvmKeyword
\ from
\ gc
\ global
+ \ has_fake_uses
\ hhvm_ccc
\ hhvmcc
\ hidden
|
@llvm/pr-subscribers-llvm-transforms Author: Stephen Tozer (SLTozer) ChangesFollowing the addition of the llvm.fake.use intrinsic and corresponding MIR instruction, two further changes are planned: to add an -fextend-lifetimes flag to Clang that emits these intrinsics, and to have -Og enable this flag by default. Currently, some logic for handling fake uses is gated by the optdebug attribute, which is intended to be switched on by -fextend-lifetimes (and by extension -Og later on). However, the decision was made that a general This patch resolves this by adding a has_fake_uses function attribute to LLVM, which is added by -fextend-lifetimes and is used for logic that is specific to the fake use intrinsic, without also bundling in other effects of optdebug, which will include limiting or disabling certain optimizations. Full diff: https://github.com/llvm/llvm-project/pull/109997.diff 26 Files Affected:
diff --git a/llvm/include/llvm/Bitcode/LLVMBitCodes.h b/llvm/include/llvm/Bitcode/LLVMBitCodes.h
index cbd92fd52fc75a..a49fa0f0698a64 100644
--- a/llvm/include/llvm/Bitcode/LLVMBitCodes.h
+++ b/llvm/include/llvm/Bitcode/LLVMBitCodes.h
@@ -764,6 +764,7 @@ enum AttributeKindCodes {
ATTR_KIND_SANITIZE_REALTIME_UNSAFE = 97,
ATTR_KIND_CORO_ELIDE_SAFE = 98,
ATTR_KIND_NO_EXT = 99,
+ ATTR_KIND_HAS_FAKE_USES = 100,
};
enum ComdatSelectionKindCodes {
diff --git a/llvm/include/llvm/IR/Attributes.td b/llvm/include/llvm/IR/Attributes.td
index 9044d127b47946..28af0e98b2cd20 100644
--- a/llvm/include/llvm/IR/Attributes.td
+++ b/llvm/include/llvm/IR/Attributes.td
@@ -112,6 +112,9 @@ def ElementType : TypeAttr<"elementtype", [ParamAttr]>;
/// symbol.
def FnRetThunkExtern : EnumAttr<"fn_ret_thunk_extern", [FnAttr]>;
+/// Function uses fake use intrinsics to extend variable lifetimes.
+def HasFakeUses : EnumAttr<"has_fake_uses", [FnAttr]>;
+
/// Function has a hybrid patchable thunk.
def HybridPatchable : EnumAttr<"hybrid_patchable", [FnAttr]>;
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index 6f997510b03609..d34c114690dad1 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -2024,6 +2024,8 @@ static Attribute::AttrKind getAttrFromCode(uint64_t Code) {
return Attribute::ElementType;
case bitc::ATTR_KIND_FNRETTHUNK_EXTERN:
return Attribute::FnRetThunkExtern;
+ case bitc::ATTR_KIND_HAS_FAKE_USES:
+ return Attribute::HasFakeUses;
case bitc::ATTR_KIND_INLINE_HINT:
return Attribute::InlineHint;
case bitc::ATTR_KIND_IN_REG:
diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
index d9086bfebbd2a9..e5fedf2aefd6e3 100644
--- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -727,6 +727,8 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) {
return bitc::ATTR_KIND_DISABLE_SANITIZER_INSTRUMENTATION;
case Attribute::FnRetThunkExtern:
return bitc::ATTR_KIND_FNRETTHUNK_EXTERN;
+ case Attribute::HasFakeUses:
+ return bitc::ATTR_KIND_HAS_FAKE_USES;
case Attribute::Hot:
return bitc::ATTR_KIND_HOT;
case Attribute::ElementType:
diff --git a/llvm/lib/CodeGen/RemoveLoadsIntoFakeUses.cpp b/llvm/lib/CodeGen/RemoveLoadsIntoFakeUses.cpp
index 232181a199b8c2..c040a999e60786 100644
--- a/llvm/lib/CodeGen/RemoveLoadsIntoFakeUses.cpp
+++ b/llvm/lib/CodeGen/RemoveLoadsIntoFakeUses.cpp
@@ -74,9 +74,9 @@ INITIALIZE_PASS_END(RemoveLoadsIntoFakeUses, DEBUG_TYPE,
"Remove Loads Into Fake Uses", false, false)
bool RemoveLoadsIntoFakeUses::runOnMachineFunction(MachineFunction &MF) {
- // Only `optdebug` functions should contain FAKE_USEs, so don't try to run
- // this for other functions.
- if (!MF.getFunction().hasFnAttribute(Attribute::OptimizeForDebugging) ||
+ // Only `has_fake_uses` functions should contain FAKE_USEs, so don't try to
+ // run this for other functions.
+ if (!MF.getFunction().hasFnAttribute(Attribute::HasFakeUses) ||
skipFunction(MF.getFunction()))
return false;
diff --git a/llvm/lib/Transforms/Utils/CodeExtractor.cpp b/llvm/lib/Transforms/Utils/CodeExtractor.cpp
index f58448dd9562d5..508dbebd68c015 100644
--- a/llvm/lib/Transforms/Utils/CodeExtractor.cpp
+++ b/llvm/lib/Transforms/Utils/CodeExtractor.cpp
@@ -923,6 +923,7 @@ Function *CodeExtractor::constructFunction(const ValueSet &inputs,
case Attribute::Cold:
case Attribute::DisableSanitizerInstrumentation:
case Attribute::FnRetThunkExtern:
+ case Attribute::HasFakeUses:
case Attribute::Hot:
case Attribute::HybridPatchable:
case Attribute::NoRecurse:
diff --git a/llvm/test/Bitcode/attributes.ll b/llvm/test/Bitcode/attributes.ll
index a66eda19ff5735..e5b0efc489ea67 100644
--- a/llvm/test/Bitcode/attributes.ll
+++ b/llvm/test/Bitcode/attributes.ll
@@ -537,6 +537,11 @@ define void @f91(ptr dead_on_unwind %p) {
ret void
}
+; CHECK: define void @f100() [[HASFAKEUSES:#[0-9]+]]
+define void @f100() has_fake_uses {
+ ret void;
+}
+
; CHECK: define range(i32 -1, 42) i32 @range_attribute(<4 x i32> range(i32 -1, 42) %a)
define range(i32 -1, 42) i32 @range_attribute(<4 x i32> range(i32 -1, 42) %a) {
ret i32 0
@@ -615,4 +620,5 @@ define void @initializes(ptr initializes((-4, 0), (4, 8)) %a) {
; CHECK: attributes [[FNRETTHUNKEXTERN]] = { fn_ret_thunk_extern }
; CHECK: attributes [[SKIPPROFILE]] = { skipprofile }
; CHECK: attributes [[OPTDEBUG]] = { optdebug }
+; CHECK: attributes [[HASFAKEUSES]] = { has_fake_uses }
; CHECK: attributes #[[NOBUILTIN]] = { nobuiltin }
diff --git a/llvm/test/CodeGen/MIR/X86/fake-use-tailcall.mir b/llvm/test/CodeGen/MIR/X86/fake-use-tailcall.mir
index 6c2cb0e55222b2..9576060ade4397 100644
--- a/llvm/test/CodeGen/MIR/X86/fake-use-tailcall.mir
+++ b/llvm/test/CodeGen/MIR/X86/fake-use-tailcall.mir
@@ -35,7 +35,7 @@
# CHECK-NEXT: ret
--- |
- define hidden i32 @foo(i32 %i) local_unnamed_addr optdebug {
+ define hidden i32 @foo(i32 %i) local_unnamed_addr has_fake_uses {
entry:
%cmp = icmp eq i32 %i, 0
br i1 %cmp, label %if.then, label %if.else
diff --git a/llvm/test/CodeGen/X86/fake-use-hpfloat.ll b/llvm/test/CodeGen/X86/fake-use-hpfloat.ll
index fd511a6179acfe..d2548943fc4c8d 100644
--- a/llvm/test/CodeGen/X86/fake-use-hpfloat.ll
+++ b/llvm/test/CodeGen/X86/fake-use-hpfloat.ll
@@ -8,7 +8,7 @@
;
target triple = "x86_64-unknown-unknown"
-define void @_Z6doTestv() local_unnamed_addr optdebug {
+define void @_Z6doTestv() local_unnamed_addr has_fake_uses {
entry:
tail call void (...) @llvm.fake.use(half 0xH0000)
ret void
diff --git a/llvm/test/CodeGen/X86/fake-use-ld.ll b/llvm/test/CodeGen/X86/fake-use-ld.ll
index 86e7235091dd1c..d6ddcb910c53fe 100644
--- a/llvm/test/CodeGen/X86/fake-use-ld.ll
+++ b/llvm/test/CodeGen/X86/fake-use-ld.ll
@@ -10,7 +10,7 @@
; }
; /*******************************************************************/
-define x86_fp80 @actual(x86_fp80 %p1, x86_fp80 %p2, x86_fp80 %p3) optdebug {
+define x86_fp80 @actual(x86_fp80 %p1, x86_fp80 %p2, x86_fp80 %p3) has_fake_uses {
;
; CHECK: actual
;
diff --git a/llvm/test/CodeGen/X86/fake-use-scheduler.mir b/llvm/test/CodeGen/X86/fake-use-scheduler.mir
index 8b82c4ed2485dc..3c3b54eef5ee9a 100644
--- a/llvm/test/CodeGen/X86/fake-use-scheduler.mir
+++ b/llvm/test/CodeGen/X86/fake-use-scheduler.mir
@@ -26,7 +26,7 @@
@glb = common dso_local local_unnamed_addr global [100 x i32] zeroinitializer, align 16
- define dso_local i64 @foo(ptr %p) local_unnamed_addr optdebug {
+ define dso_local i64 @foo(ptr %p) local_unnamed_addr has_fake_uses {
entry:
%0 = load i32, ptr @glb, align 16
store i32 %0, ptr %p, align 4
@@ -43,7 +43,7 @@
ret i64 %add3
}
- define dso_local i64 @bar(ptr %p) local_unnamed_addr optdebug {
+ define dso_local i64 @bar(ptr %p) local_unnamed_addr has_fake_uses {
entry:
%0 = load i32, ptr @glb, align 16
store i32 %0, ptr %p, align 4
diff --git a/llvm/test/CodeGen/X86/fake-use-simple-tail-call.ll b/llvm/test/CodeGen/X86/fake-use-simple-tail-call.ll
index 45a210ef391009..b9c92692585e41 100644
--- a/llvm/test/CodeGen/X86/fake-use-simple-tail-call.ll
+++ b/llvm/test/CodeGen/X86/fake-use-simple-tail-call.ll
@@ -14,7 +14,7 @@
; ModuleID = 'test.cpp'
source_filename = "test.cpp"
-define i32 @_Z4foo1i(i32 %i) local_unnamed_addr optdebug {
+define i32 @_Z4foo1i(i32 %i) local_unnamed_addr has_fake_uses {
entry:
%call = tail call i32 @_Z3bari(i32 %i)
tail call void (...) @llvm.fake.use(i32 %i)
diff --git a/llvm/test/CodeGen/X86/fake-use-suppress-load.ll b/llvm/test/CodeGen/X86/fake-use-suppress-load.ll
index c1b442ebd79ffa..b50b10fdb71d05 100644
--- a/llvm/test/CodeGen/X86/fake-use-suppress-load.ll
+++ b/llvm/test/CodeGen/X86/fake-use-suppress-load.ll
@@ -6,7 +6,7 @@
; CHECK: movq %r{{[a-z]+,}} -{{[0-9]+\(%rsp\)}}
; CHECK-NOT: movq -{{[0-9]+\(%rsp\)}}, %r{{[a-z]+}}
-define dso_local i32 @f(ptr %p) local_unnamed_addr optdebug {
+define dso_local i32 @f(ptr %p) local_unnamed_addr has_fake_uses {
entry:
call void asm sideeffect "", "~{rax},~{rbx},~{rcx},~{rdx},~{rsi},~{rdi},~{rbp},~{r8},~{r9},~{r10},~{r11},~{r12},~{r13},~{r14},~{r15},~{dirflag},~{fpsr},~{flags}"() #1
notail call void (...) @llvm.fake.use(ptr %p)
diff --git a/llvm/test/CodeGen/X86/fake-use-tailcall.ll b/llvm/test/CodeGen/X86/fake-use-tailcall.ll
index 67c28dcf1301c4..f0bbc0fa4734ea 100644
--- a/llvm/test/CodeGen/X86/fake-use-tailcall.ll
+++ b/llvm/test/CodeGen/X86/fake-use-tailcall.ll
@@ -17,7 +17,7 @@
; CHECK: FAKE_USE %0
; CHECK: TCRETURN
-define void @bar(i32 %v) optdebug {
+define void @bar(i32 %v) has_fake_uses {
entry:
%call = tail call i32 @_Z3fooi(i32 %v)
%mul = mul nsw i32 %call, 3
@@ -27,7 +27,7 @@ entry:
ret void
}
-define i32 @baz(i32 %v) optdebug {
+define i32 @baz(i32 %v) has_fake_uses {
entry:
%call = tail call i32 @_Z3fooi(i32 %v)
notail call void (...) @llvm.fake.use(i32 %v)
diff --git a/llvm/test/CodeGen/X86/fake-use-vector.ll b/llvm/test/CodeGen/X86/fake-use-vector.ll
index 4d6ede30827046..9d815eef748804 100644
--- a/llvm/test/CodeGen/X86/fake-use-vector.ll
+++ b/llvm/test/CodeGen/X86/fake-use-vector.ll
@@ -36,4 +36,4 @@ declare <4 x float> @llvm.x86.sse.cvtpi2ps(<4 x float>, <1 x i64>)
; Function Attrs: nounwind
declare void @llvm.fake.use(...)
-attributes #0 = { "target-cpu"="btver2" optdebug }
+attributes #0 = { "target-cpu"="btver2" has_fake_uses }
diff --git a/llvm/test/CodeGen/X86/fake-use-vector2.ll b/llvm/test/CodeGen/X86/fake-use-vector2.ll
index 190197615775a9..868afa4bf897cb 100644
--- a/llvm/test/CodeGen/X86/fake-use-vector2.ll
+++ b/llvm/test/CodeGen/X86/fake-use-vector2.ll
@@ -24,4 +24,4 @@ entry:
declare void @llvm.fake.use(...)
-attributes #0 = { "target-cpu"="btver2" optdebug }
+attributes #0 = { "target-cpu"="btver2" has_fake_uses }
diff --git a/llvm/test/CodeGen/X86/fake-use-zero-length.ll b/llvm/test/CodeGen/X86/fake-use-zero-length.ll
index e3bdd2659dd913..16578327c068aa 100644
--- a/llvm/test/CodeGen/X86/fake-use-zero-length.ll
+++ b/llvm/test/CodeGen/X86/fake-use-zero-length.ll
@@ -17,7 +17,7 @@
source_filename = "test.ll"
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
-define hidden i32 @main([0 x i32] %zero, [1 x i32] %one) local_unnamed_addr optdebug {
+define hidden i32 @main([0 x i32] %zero, [1 x i32] %one) local_unnamed_addr has_fake_uses {
entry:
notail call void (...) @bar([0 x i32] %zero)
notail call void (...) @baz([1 x i32] %one)
diff --git a/llvm/test/DebugInfo/AArch64/fake-use-global-isel.ll b/llvm/test/DebugInfo/AArch64/fake-use-global-isel.ll
index 65a64583096959..bb0b69e9f21073 100644
--- a/llvm/test/DebugInfo/AArch64/fake-use-global-isel.ll
+++ b/llvm/test/DebugInfo/AArch64/fake-use-global-isel.ll
@@ -33,7 +33,7 @@ source_filename = "t2.c"
@glob = common local_unnamed_addr global [10 x i32] zeroinitializer, align 16, !dbg !0
; Function Attrs: nounwind sspstrong uwtable
-define i32 @foo(i32 %b, i32 %i) local_unnamed_addr optdebug !dbg !13 {
+define i32 @foo(i32 %b, i32 %i) local_unnamed_addr has_fake_uses !dbg !13 {
entry:
#dbg_value(i32 %b, !17, !20, !21)
%c = add i32 %b, 42
diff --git a/llvm/test/DebugInfo/X86/fake-use.ll b/llvm/test/DebugInfo/X86/fake-use.ll
index 5ac5104a167118..27c5be16be7a05 100644
--- a/llvm/test/DebugInfo/X86/fake-use.ll
+++ b/llvm/test/DebugInfo/X86/fake-use.ll
@@ -30,7 +30,7 @@ source_filename = "t2.c"
@glob = common local_unnamed_addr global [10 x i32] zeroinitializer, align 16, !dbg !0
; Function Attrs: nounwind sspstrong uwtable
-define i32 @foo(i32 %b, i32 %i) local_unnamed_addr optdebug !dbg !13 {
+define i32 @foo(i32 %b, i32 %i) local_unnamed_addr has_fake_uses !dbg !13 {
entry:
#dbg_value(i32 %b, !17, !20, !21)
%c = add i32 %b, 42
diff --git a/llvm/test/Transforms/CodeGenPrepare/X86/fake-use-phi.ll b/llvm/test/Transforms/CodeGenPrepare/X86/fake-use-phi.ll
index 064d3f29dd9ebb..c8b280e7c3d042 100644
--- a/llvm/test/Transforms/CodeGenPrepare/X86/fake-use-phi.ll
+++ b/llvm/test/Transforms/CodeGenPrepare/X86/fake-use-phi.ll
@@ -25,7 +25,7 @@ source_filename = "test.ll"
declare i32 @foo(ptr nonnull dereferenceable(1)) local_unnamed_addr
declare i32 @bar(ptr nonnull dereferenceable(1)) local_unnamed_addr
-define hidden void @func(ptr nonnull dereferenceable(1) %this) local_unnamed_addr align 2 optdebug {
+define hidden void @func(ptr nonnull dereferenceable(1) %this) local_unnamed_addr align 2 has_fake_uses {
entry:
%b = getelementptr inbounds %class.a, ptr %this, i64 0, i32 0
%0 = load i8, i8* %b, align 1
diff --git a/llvm/test/Transforms/CodeGenPrepare/X86/fake-use-split-ret.ll b/llvm/test/Transforms/CodeGenPrepare/X86/fake-use-split-ret.ll
index b2cf89f6f2dd82..ffa61174c60f09 100644
--- a/llvm/test/Transforms/CodeGenPrepare/X86/fake-use-split-ret.ll
+++ b/llvm/test/Transforms/CodeGenPrepare/X86/fake-use-split-ret.ll
@@ -17,7 +17,7 @@
declare i32 @_Z3bari(i32) local_unnamed_addr
-define i32 @_Z4foo2i(i32 %i) local_unnamed_addr optdebug {
+define i32 @_Z4foo2i(i32 %i) local_unnamed_addr has_fake_uses {
entry:
%dec = add nsw i32 %i, -1
%cmp = icmp slt i32 %i, 2
diff --git a/llvm/test/Transforms/GVN/fake-use-constprop.ll b/llvm/test/Transforms/GVN/fake-use-constprop.ll
index 1466f9f9fca277..9691de90170132 100644
--- a/llvm/test/Transforms/GVN/fake-use-constprop.ll
+++ b/llvm/test/Transforms/GVN/fake-use-constprop.ll
@@ -37,7 +37,7 @@
; CHECK: call {{.+}} @bees(i8 0)
; CHECK: call {{.+}} @llvm.fake.use(i8 %[[CONV_VAR]])
-define i32 @foo(float %f) optdebug {
+define i32 @foo(float %f) has_fake_uses {
%conv = fptosi float %f to i8
%tobool3 = icmp eq i8 %conv, 0
br i1 %tobool3, label %if.end, label %lab
diff --git a/llvm/test/Transforms/SROA/fake-use-sroa.ll b/llvm/test/Transforms/SROA/fake-use-sroa.ll
index 9e92df15487506..9a342ca53719fa 100644
--- a/llvm/test/Transforms/SROA/fake-use-sroa.ll
+++ b/llvm/test/Transforms/SROA/fake-use-sroa.ll
@@ -25,7 +25,7 @@
; CHECK: %[[SLICE2:[^ ]+]] = trunc i64
; CHECK-DAG: call{{.*}} @llvm.fake.use(i32 %[[SLICE1]])
; CHECK-DAG: call{{.*}} @llvm.fake.use(i32 %[[SLICE2]])
-define dso_local void @foo(i64 %S.coerce) optdebug {
+define dso_local void @foo(i64 %S.coerce) has_fake_uses {
entry:
%S = alloca %struct.s, align 4
store i64 %S.coerce, ptr %S, align 4
@@ -40,7 +40,7 @@ entry:
; CHECK: %[[ARRAYSLICE2:[^ ]+]] = load
; CHECK-DAG: call{{.*}} @llvm.fake.use(i32 %[[ARRAYSLICE1]])
; CHECK-DAG: call{{.*}} @llvm.fake.use(i32 %[[ARRAYSLICE2]])
-define dso_local void @bar() optdebug {
+define dso_local void @bar() has_fake_uses {
entry:
%arr = alloca [2 x i32], align 4
call void @llvm.memcpy.p0i8.p0i8.i64(ptr align 4 %arr, ptr align 4 bitcast (ptr @__const.bar.arr to ptr), i64 8, i1 false)
diff --git a/llvm/utils/emacs/llvm-mode.el b/llvm/utils/emacs/llvm-mode.el
index dab37833ff63a9..30b6a8610a3515 100644
--- a/llvm/utils/emacs/llvm-mode.el
+++ b/llvm/utils/emacs/llvm-mode.el
@@ -30,7 +30,7 @@
(list
;; Attributes
`(,(regexp-opt
- '("alwaysinline" "argmemonly" "allocsize" "builtin" "cold" "convergent" "dereferenceable" "dereferenceable_or_null" "hot" "immarg" "inaccessiblememonly"
+ '("alwaysinline" "argmemonly" "allocsize" "builtin" "cold" "convergent" "dereferenceable" "dereferenceable_or_null" "has_fake_uses" "hot" "immarg" "inaccessiblememonly"
"inaccessiblemem_or_argmemonly" "inalloca" "inlinehint" "jumptable" "minsize" "mustprogress" "naked" "nobuiltin" "nonnull" "nocapture"
"nocallback" "nocf_check" "noduplicate" "nofree" "noimplicitfloat" "noinline" "nomerge" "nonlazybind" "noprofile" "noredzone" "noreturn"
"norecurse" "nosync" "noundef" "nounwind" "nosanitize_bounds" "nosanitize_coverage" "null_pointer_is_valid" "optdebug" "optforfuzzing" "optnone" "optsize" "preallocated" "readnone" "readonly" "returned" "returns_twice"
diff --git a/llvm/utils/kate/llvm.xml b/llvm/utils/kate/llvm.xml
index 0e7aec3880e6b4..3cd76a084e48b6 100644
--- a/llvm/utils/kate/llvm.xml
+++ b/llvm/utils/kate/llvm.xml
@@ -87,6 +87,7 @@
<item> dereferenceable_or_null </item>
<item> extern_weak </item>
<item> hhvmcc </item>
+ <item> has_fake_uses </item>
<item> hot </item>
<item> inaccessiblemem_or_argmemonly </item>
<item> inaccessiblememonly </item>
diff --git a/llvm/utils/vim/syntax/llvm.vim b/llvm/utils/vim/syntax/llvm.vim
index fac509c355cb8a..9a89ba32c33760 100644
--- a/llvm/utils/vim/syntax/llvm.vim
+++ b/llvm/utils/vim/syntax/llvm.vim
@@ -94,6 +94,7 @@ syn keyword llvmKeyword
\ from
\ gc
\ global
+ \ has_fake_uses
\ hhvm_ccc
\ hhvmcc
\ hidden
|
if (!MF.getFunction().hasFnAttribute(Attribute::OptimizeForDebugging) || | ||
// Only `has_fake_uses` functions should contain FAKE_USEs, so don't try to | ||
// run this for other functions. | ||
if (!MF.getFunction().hasFnAttribute(Attribute::HasFakeUses) || |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this the only use of the attribute? If it's just a pure compile time optimization, you can track whether there are FAKE_USEs on the MachineFunction.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's used for this, and for disabling the post-RA machine scheduler. I do agree that if there's a method that doesn't require adding an attribute, that's preferable, but thought that adding a scan to every function to see if a FAKE_USE exists would be worse. Is there a better way to store this information as part of the MachineFunction itself?
Edit: I see similar bools used to cache information like this being directly added to the MachineFunction class, I'll try rewriting the patch to use that method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think just adding a bool to MachineFunction would be fine? It already has a bunch of those.
Closed in favour of #110097, which takes a simpler approach. |
Following the addition of the llvm.fake.use intrinsic and corresponding MIR instruction, two further changes are planned: to add an -fextend-lifetimes flag to Clang that emits these intrinsics, and to have -Og enable this flag by default. Currently, some logic for handling fake uses is gated by the optdebug attribute, which is intended to be switched on by -fextend-lifetimes (and by extension -Og later on). However, the decision was made that a general
optdebug
attribute should be incompatible with other opt_ attributes (e.g. optsize, optnone), since they all express different intents for how to optimize the program. We would still like to allow -fextend-lifetimes with optsize however (i.e.-Os -fextend-lifetimes
should be legal), since it may be a useful configuration and there is no technical reason to not allow it.This patch resolves this by adding a has_fake_uses function attribute to LLVM, which is added by -fextend-lifetimes and is used for logic that is specific to the fake use intrinsic, without also bundling in other effects of optdebug, which will include limiting or disabling certain optimizations.