зеркало из https://github.com/microsoft/clang-1.git
Fix PR9614 for functions with the always_inline attribute. Try to keep
the common case (-O0, no always_inline) fast. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@143222 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
6d09f01af7
Коммит
cc4889f72e
|
@ -901,18 +901,15 @@ bool
|
|||
CodeGenModule::shouldEmitFunction(const FunctionDecl *F) {
|
||||
if (getFunctionLinkage(F) != llvm::Function::AvailableExternallyLinkage)
|
||||
return true;
|
||||
if (F->hasAttr<AlwaysInlineAttr>())
|
||||
return true;
|
||||
if (CodeGenOpts.OptimizationLevel == 0)
|
||||
if (CodeGenOpts.OptimizationLevel == 0 &&
|
||||
!F->hasAttr<AlwaysInlineAttr>())
|
||||
return false;
|
||||
// PR9614. Avoid cases where the source code is lying to us. An available
|
||||
// externally function should have an equivalent function somewhere else,
|
||||
// but a function that calls itself is clearly not equivalent to the real
|
||||
// implementation.
|
||||
// This happens in glibc's btowc and in some configure checks.
|
||||
if (isTriviallyRecursiveViaAsm(F))
|
||||
return false;
|
||||
return true;
|
||||
return !isTriviallyRecursiveViaAsm(F);
|
||||
}
|
||||
|
||||
void CodeGenModule::EmitGlobalDefinition(GlobalDecl GD) {
|
||||
|
|
|
@ -1,15 +1,23 @@
|
|||
// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s
|
||||
|
||||
extern int foo_alias (void) __asm ("foo");
|
||||
inline int foo (void) {
|
||||
extern void foo_alias (void) __asm ("foo");
|
||||
inline void foo (void) {
|
||||
return foo_alias ();
|
||||
}
|
||||
int f(void) {
|
||||
return foo();
|
||||
extern void bar_alias (void) __asm ("bar");
|
||||
inline __attribute__ ((__always_inline__)) void bar (void) {
|
||||
return bar_alias ();
|
||||
}
|
||||
void f(void) {
|
||||
foo();
|
||||
bar();
|
||||
}
|
||||
|
||||
// CHECK-NOT: define
|
||||
// CHECK: define i32 @f()
|
||||
// CHECK: call i32 @foo()
|
||||
// CHECK-NEXT: ret i32
|
||||
// CHECK-NOT: define
|
||||
// CHECK: define void @f()
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK-NEXT: call void @foo()
|
||||
// CHECK-NEXT: call void @bar()
|
||||
// CHECK-NEXT: ret void
|
||||
|
||||
// CHECK: declare void @foo()
|
||||
// CHECK: declare void @bar()
|
||||
|
|
Загрузка…
Ссылка в новой задаче