[llvm] [clang] [clang-tools-extra] Dont alter cold function alignment unless using Os (PR #72387)

via cfe-commits cfe-commits at lists.llvm.org
Wed Nov 15 05:47:20 PST 2023


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Phil Camp (FlameTop)

<details>
<summary>Changes</summary>

This PR alters the behaviour of function alignment for functions marked as 'cold'. Currently functions marked with a ‘cold’ attribute are also set as optimize by size. Optimize by size alters the function alignment from default. This interferes with code replacement features on our targets. This PR allows cold functions to maintain their default alignment except when optimize by size is explicitly used.

---
Full diff: https://github.com/llvm/llvm-project/pull/72387.diff


5 Files Affected:

- (modified) clang/lib/CodeGen/CodeGenModule.cpp (+3) 
- (added) clang/test/CodeGen/cold-align.cpp (+32) 
- (modified) llvm/include/llvm/IR/Attributes.td (+1) 
- (modified) llvm/lib/CodeGen/MachineFunction.cpp (+2-1) 
- (added) llvm/test/CodeGen/X86/cold-align.ll (+52) 


``````````diff
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index f1b900be74b2cdf..450729937740934 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -2410,6 +2410,9 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,
       if (!ShouldAddOptNone)
         B.addAttribute(llvm::Attribute::OptimizeForSize);
       B.addAttribute(llvm::Attribute::Cold);
+      // dont alter alignment if not optimizing for size
+      if (!CodeGenOpts.OptimizeSize)
+        B.addAttribute("keepalign", "true");
     }
     if (D->hasAttr<HotAttr>())
       B.addAttribute(llvm::Attribute::Hot);
diff --git a/clang/test/CodeGen/cold-align.cpp b/clang/test/CodeGen/cold-align.cpp
new file mode 100644
index 000000000000000..93564d181d65d96
--- /dev/null
+++ b/clang/test/CodeGen/cold-align.cpp
@@ -0,0 +1,32 @@
+// Dont alter function alignment if marked cold
+//
+// Cold attribute marks functions as also optimize for size. This normally collapses the
+// default function alignment. This can interfere with edit&continue effectiveness.
+//
+// RUN:     %clang -O2 -S -emit-llvm %s -o - | FileCheck %s -check-prefixes TWO
+// RUN:     %clang -Os -S -emit-llvm %s -o - | FileCheck %s -check-prefixes SIZE
+
+class Dismissed
+{
+public:
+  __attribute__((cold)) void Chilly();
+                        void Temparate();
+  __attribute__((hot))  void Sizzle();
+};
+void Dismissed::Chilly(){};
+void Dismissed::Temparate(){};
+void Dismissed::Sizzle(){};
+
+// TWO: attributes #0 = {
+// TWO: "keepalign"="true"
+// TWO: attributes #1 = {
+// TWO-NOT: "keepalign"="true"
+// TWO: attributes #2 = {
+// TWO-NOT: "keepalign"="true"
+
+// SIZE: attributes #0 = {
+// SIZE-NOT: "keepalign"="true"
+// SIZE: attributes #1 = {
+// SIZE-NOT: "keepalign"="true"
+// SIZE: attributes #2 = {
+// SIZE-NOT: "keepalign"="true"
\ No newline at end of file
diff --git a/llvm/include/llvm/IR/Attributes.td b/llvm/include/llvm/IR/Attributes.td
index fc38e68ad273b6b..30844f566786c37 100644
--- a/llvm/include/llvm/IR/Attributes.td
+++ b/llvm/include/llvm/IR/Attributes.td
@@ -332,6 +332,7 @@ def NoJumpTables : StrBoolAttr<"no-jump-tables">;
 def NoInlineLineTables : StrBoolAttr<"no-inline-line-tables">;
 def ProfileSampleAccurate : StrBoolAttr<"profile-sample-accurate">;
 def UseSampleProfile : StrBoolAttr<"use-sample-profile">;
+def KeepAlign: StrBoolAttr<"keepalign">;
 
 def DenormalFPMath : ComplexStrAttr<"denormal-fp-math", [FnAttr]>;
 def DenormalFPMathF32 : ComplexStrAttr<"denormal-fp-math-f32", [FnAttr]>;
diff --git a/llvm/lib/CodeGen/MachineFunction.cpp b/llvm/lib/CodeGen/MachineFunction.cpp
index 07eb0ba7f45c2e3..ab5392a05fc019b 100644
--- a/llvm/lib/CodeGen/MachineFunction.cpp
+++ b/llvm/lib/CodeGen/MachineFunction.cpp
@@ -214,7 +214,8 @@ void MachineFunction::init() {
 
   // FIXME: Shouldn't use pref alignment if explicit alignment is set on F.
   // FIXME: Use Function::hasOptSize().
-  if (!F.hasFnAttribute(Attribute::OptimizeForSize))
+  if ((!F.hasFnAttribute(Attribute::OptimizeForSize)) ||
+     (F.getFnAttribute("keepalign").getValueAsBool()))
     Alignment = std::max(Alignment,
                          STI->getTargetLowering()->getPrefFunctionAlignment());
 
diff --git a/llvm/test/CodeGen/X86/cold-align.ll b/llvm/test/CodeGen/X86/cold-align.ll
new file mode 100644
index 000000000000000..ab1f393dfa561ab
--- /dev/null
+++ b/llvm/test/CodeGen/X86/cold-align.ll
@@ -0,0 +1,52 @@
+;  Dont alter function alignment if marked cold
+;
+;  Cold attribute marks functions as also optimize for size. This normally collapses the
+;  default function alignment. This can interfere with edit&continue effectiveness.
+;
+;
+;  RUN:     llc -O2 <%s | FileCheck %s -check-prefixes TWO
+;
+;  TWO: .globl _ZN9Dismissed6ChillyEv
+;  TWO-NEXT: .p2align 4, 0x90
+;  TWO: .globl _ZN9Dismissed9TemparateEv
+;  TWO-NEXT: .p2align 4, 0x90
+;  TWO: .globl _ZN9Dismissed6SizzleEv
+;  TWO-NEXT: .p2align 4, 0x90
+
+; ModuleID = 'cold-align.cpp'
+source_filename = "cold-align.cpp"
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-sie-ps5"
+
+; Function Attrs: cold mustprogress nofree norecurse nosync nounwind optsize sspstrong willreturn memory(none) uwtable
+define hidden void @_ZN9Dismissed6ChillyEv(ptr nocapture noundef nonnull readnone align 1 dereferenceable(1) %this) local_unnamed_addr #0 align 2 {
+entry:
+  ret void
+}
+
+; Function Attrs: mustprogress nofree norecurse nosync nounwind sspstrong willreturn memory(none) uwtable
+define hidden void @_ZN9Dismissed9TemparateEv(ptr nocapture noundef nonnull readnone align 1 dereferenceable(1) %this) local_unnamed_addr #1 align 2 {
+entry:
+  ret void
+}
+
+; Function Attrs: hot mustprogress nofree norecurse nosync nounwind sspstrong willreturn memory(none) uwtable
+define hidden void @_ZN9Dismissed6SizzleEv(ptr nocapture noundef nonnull readnone align 1 dereferenceable(1) %this) local_unnamed_addr #2 align 2 {
+entry:
+  ret void
+}
+
+attributes #0 = { cold mustprogress nofree norecurse nosync nounwind optsize sspstrong willreturn memory(none) uwtable "denormal-fp-math"="preserve-sign,preserve-sign" "frame-pointer"="non-leaf" "keepalign"="true" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="znver2s" "target-features"="+adx,+aes,+avx,+avx2,+bmi,+bmi2,+clflushopt,+clwb,+clzero,+crc32,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+lwp,+lzcnt,+mmx,+movbe,+mwaitx,+pclmul,+popcnt,+prfchw,+rdpid,+rdpru,+rdrnd,+rdseed,+sahf,+sha,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+sse4a,+ssse3,+wbnoinvd,+x87,+xsave,+xsavec,+xsaveopt,+xsaves" }
+attributes #1 = { mustprogress nofree norecurse nosync nounwind sspstrong willreturn memory(none) uwtable "denormal-fp-math"="preserve-sign,preserve-sign" "frame-pointer"="non-leaf" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="znver2s" "target-features"="+adx,+aes,+avx,+avx2,+bmi,+bmi2,+clflushopt,+clwb,+clzero,+crc32,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+lwp,+lzcnt,+mmx,+movbe,+mwaitx,+pclmul,+popcnt,+prfchw,+rdpid,+rdpru,+rdrnd,+rdseed,+sahf,+sha,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+sse4a,+ssse3,+wbnoinvd,+x87,+xsave,+xsavec,+xsaveopt,+xsaves" }
+attributes #2 = { hot mustprogress nofree norecurse nosync nounwind sspstrong willreturn memory(none) uwtable "denormal-fp-math"="preserve-sign,preserve-sign" "frame-pointer"="non-leaf" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="znver2s" "target-features"="+adx,+aes,+avx,+avx2,+bmi,+bmi2,+clflushopt,+clwb,+clzero,+crc32,+cx16,+cx8,+f16c,+fma,+fsgsbase,+fxsr,+lwp,+lzcnt,+mmx,+movbe,+mwaitx,+pclmul,+popcnt,+prfchw,+rdpid,+rdpru,+rdrnd,+rdseed,+sahf,+sha,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+sse4a,+ssse3,+wbnoinvd,+x87,+xsave,+xsavec,+xsaveopt,+xsaves" }
+
+!llvm.module.flags = !{!0, !1, !2, !3, !4, !5}
+!llvm.ident = !{!6}
+
+!0 = !{i32 1, !"wchar_size", i32 2}
+!1 = !{i32 1, !"SIE:STLVersion1", i32 1}
+!2 = !{i32 8, !"PIC Level", i32 2}
+!3 = !{i32 7, !"uwtable", i32 2}
+!4 = !{i32 7, !"frame-pointer", i32 1}
+!5 = !{i32 1, !"MaxTLSAlign", i32 256}
+!6 = !{!"clang version 18.0.0"}

``````````

</details>


https://github.com/llvm/llvm-project/pull/72387


More information about the cfe-commits mailing list