[llvm] 614de22 - [gcov] Set nounwind and respect module flags metadata "frame-pointer" & "uwtable" for synthesized functions

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 26 13:30:26 PDT 2021


Author: Fangrui Song
Date: 2021-04-26T13:30:21-07:00
New Revision: 614de225c92bc3998a83a274e84dfb94ec8a7840

URL: https://github.com/llvm/llvm-project/commit/614de225c92bc3998a83a274e84dfb94ec8a7840
DIFF: https://github.com/llvm/llvm-project/commit/614de225c92bc3998a83a274e84dfb94ec8a7840.diff

LOG: [gcov] Set nounwind and respect module flags metadata "frame-pointer" & "uwtable" for synthesized functions

This applies the D100251 mechanism to the gcov instrumentation pass.

With this patch, `-fno-omit-frame-pointer` in
`clang -fprofile-arcs -O1 -fno-omit-frame-pointer` will be respected for synthesized
`__llvm_gcov_writeout,__llvm_gcov_reset,__llvm_gcov_init` functions: the frame pointer
will be kept (note: on many targets -O1 eliminates the frame pointer by default).

`clang -fno-exceptions -fno-asynchronous-unwind-tables -g -fprofile-arcs` will
produce .debug_frame instead of .eh_frame.

Fix: https://github.com/ClangBuiltLinux/linux/issues/955

Reviewed By: nickdesaulniers

Differential Revision: https://reviews.llvm.org/D101129

Added: 
    llvm/test/Transforms/GCOVProfiling/module-flags.ll

Modified: 
    llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
    llvm/test/Transforms/GCOVProfiling/function-numbering.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp b/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
index c2a3b91f2a5ac..aae04cb909dc1 100644
--- a/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
+++ b/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp
@@ -125,6 +125,7 @@ class GCOVProfiler {
                    function_ref<BranchProbabilityInfo *(Function &F)> GetBPI,
                    function_ref<const TargetLibraryInfo &(Function &F)> GetTLI);
 
+  Function *createInternalFunction(FunctionType *FTy, StringRef Name);
   void emitGlobalConstructor(
       SmallVectorImpl<std::pair<GlobalVariable *, MDNode *>> &CountersBySP);
 
@@ -1023,22 +1024,28 @@ bool GCOVProfiler::emitProfileNotes(
   return true;
 }
 
+Function *GCOVProfiler::createInternalFunction(FunctionType *FTy,
+                                               StringRef Name) {
+  Function *F = Function::createWithDefaultAttr(
+      FTy, GlobalValue::InternalLinkage, 0, Name, M);
+  F->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
+  F->addFnAttr(Attribute::NoUnwind);
+  if (Options.NoRedZone)
+    F->addFnAttr(Attribute::NoRedZone);
+  return F;
+}
+
 void GCOVProfiler::emitGlobalConstructor(
     SmallVectorImpl<std::pair<GlobalVariable *, MDNode *>> &CountersBySP) {
   Function *WriteoutF = insertCounterWriteout(CountersBySP);
   Function *ResetF = insertReset(CountersBySP);
 
   // Create a small bit of code that registers the "__llvm_gcov_writeout" to
-  // be executed at exit and the "__llvm_gcov_flush" function to be executed
+  // be executed at exit and the "__llvm_gcov_reset" function to be executed
   // when "__gcov_flush" is called.
   FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
-  Function *F = Function::Create(FTy, GlobalValue::InternalLinkage,
-                                 "__llvm_gcov_init", M);
-  F->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
-  F->setLinkage(GlobalValue::InternalLinkage);
+  Function *F = createInternalFunction(FTy, "__llvm_gcov_init");
   F->addFnAttr(Attribute::NoInline);
-  if (Options.NoRedZone)
-    F->addFnAttr(Attribute::NoRedZone);
 
   BasicBlock *BB = BasicBlock::Create(*Ctx, "entry", F);
   IRBuilder<> Builder(BB);
@@ -1113,12 +1120,8 @@ Function *GCOVProfiler::insertCounterWriteout(
   FunctionType *WriteoutFTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
   Function *WriteoutF = M->getFunction("__llvm_gcov_writeout");
   if (!WriteoutF)
-    WriteoutF = Function::Create(WriteoutFTy, GlobalValue::InternalLinkage,
-                                 "__llvm_gcov_writeout", M);
-  WriteoutF->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
+    WriteoutF = createInternalFunction(WriteoutFTy, "__llvm_gcov_writeout");
   WriteoutF->addFnAttr(Attribute::NoInline);
-  if (Options.NoRedZone)
-    WriteoutF->addFnAttr(Attribute::NoRedZone);
 
   BasicBlock *BB = BasicBlock::Create(*Ctx, "entry", WriteoutF);
   IRBuilder<> Builder(BB);
@@ -1363,12 +1366,8 @@ Function *GCOVProfiler::insertReset(
   FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
   Function *ResetF = M->getFunction("__llvm_gcov_reset");
   if (!ResetF)
-    ResetF = Function::Create(FTy, GlobalValue::InternalLinkage,
-                              "__llvm_gcov_reset", M);
-  ResetF->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
+    ResetF = createInternalFunction(FTy, "__llvm_gcov_reset");
   ResetF->addFnAttr(Attribute::NoInline);
-  if (Options.NoRedZone)
-    ResetF->addFnAttr(Attribute::NoRedZone);
 
   BasicBlock *Entry = BasicBlock::Create(*Ctx, "entry", ResetF);
   IRBuilder<> Builder(Entry);

diff  --git a/llvm/test/Transforms/GCOVProfiling/function-numbering.ll b/llvm/test/Transforms/GCOVProfiling/function-numbering.ll
index 59bfb257b12ed..bde2e850ac867 100644
--- a/llvm/test/Transforms/GCOVProfiling/function-numbering.ll
+++ b/llvm/test/Transforms/GCOVProfiling/function-numbering.ll
@@ -20,7 +20,7 @@ target triple = "x86_64-apple-macosx10.10.0"
 ; GCDA-SAME: { i32 0,
 ; GCDA-SAME: { i32 1,
 ;
-; GCDA-LABEL: define internal void @__llvm_gcov_writeout() {{.*}} {
+; GCDA-LABEL: define internal void @__llvm_gcov_writeout() unnamed_addr #[[#ATTR:]] {
 ; GCDA-NEXT:  entry:
 ; GCDA-NEXT:    br label %[[FILE_LOOP_HEADER:.*]]
 ;
@@ -94,6 +94,8 @@ define void @baz() !dbg !8 {
   ret void, !dbg !13
 }
 
+; GCDA: attributes #[[#ATTR]] = { noinline nounwind }
+
 !llvm.gcov = !{!14}
 !llvm.dbg.cu = !{!0}
 !llvm.module.flags = !{!9, !10}

diff  --git a/llvm/test/Transforms/GCOVProfiling/module-flags.ll b/llvm/test/Transforms/GCOVProfiling/module-flags.ll
new file mode 100644
index 0000000000000..8828da877e962
--- /dev/null
+++ b/llvm/test/Transforms/GCOVProfiling/module-flags.ll
@@ -0,0 +1,34 @@
+; RUN: mkdir -p %t && cd %t
+; RUN: opt < %s -S -passes=insert-gcov-profiling | FileCheck %s
+
+target triple = "x86_64-unknown-linux-gnu"
+
+define dso_local void @empty() !dbg !5 {
+entry:
+  ret void, !dbg !8
+}
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!3, !4, !9, !10}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, emissionKind: FullDebug, enums: !2)
+!1 = !DIFile(filename: "a.c", directory: "")
+!2 = !{}
+!3 = !{i32 7, !"Dwarf Version", i32 5}
+!4 = !{i32 2, !"Debug Info Version", i32 3}
+!5 = distinct !DISubprogram(name: "empty", scope: !1, file: !1, line: 1, type: !6, scopeLine: 1, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !2)
+!6 = !DISubroutineType(types: !7)
+!7 = !{null}
+!8 = !DILocation(line: 2, column: 1, scope: !5)
+
+;; Due to -fasynchronous-unwind-tables.
+!9 = !{i32 7, !"uwtable", i32 1}
+
+;; Due to -fno-omit-frame-pointer.
+!10 = !{i32 7, !"frame-pointer", i32 2}
+
+;; Infer uwtable and "frame-pointer" from the module flags.
+; CHECK: define internal void @__llvm_gcov_writeout() unnamed_addr #[[#ATTR:]]
+; CHECK: define internal void @__llvm_gcov_reset() unnamed_addr #[[#ATTR]]
+; CHECK: define internal void @__llvm_gcov_init() unnamed_addr #[[#ATTR]]
+; CHECK: attributes #[[#ATTR]] = { noinline nounwind uwtable "frame-pointer"="all" }


        


More information about the llvm-commits mailing list