mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 18:54:02 +01:00
[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
This commit is contained in:
parent
c4d20372c0
commit
4cb0dafe51
@ -125,6 +125,7 @@ private:
|
||||
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);
|
||||
|
@ -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}
|
||||
|
34
test/Transforms/GCOVProfiling/module-flags.ll
Normal file
34
test/Transforms/GCOVProfiling/module-flags.ll
Normal file
@ -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" }
|
Loading…
Reference in New Issue
Block a user