-
Notifications
You must be signed in to change notification settings - Fork 14.9k
[clang] Add clang::nooutline Attribute #163666
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
base: users/lenary/llvm-nooutline-enum-attr
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -2355,6 +2355,13 @@ def NoInline : DeclOrStmtAttr { | |||||
let SimpleHandler = 1; | ||||||
} | ||||||
|
||||||
def NoOutline : DeclOrStmtAttr { | ||||||
let Spellings = [Clang<"nooutline">]; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
perhaps? Makes it... somewhat consistent with the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wrote a longer comment about this, see above. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see, thanks. Hmm... my mental parse is still not really picking up the actual meaning of what this is (and as I'm the second one to mention that, perhaps something we should care about?). The rest don't have that parse problem for me. While I appreciate the symmetry, at the same time readability should, IMO trump it. |
||||||
let Subjects = SubjectList<[Function], ErrorDiag>; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Your examples all use prototyped functions, is there a reason this cant be used on a no-prototype function? If so, this should reflect that (alternatively, write a codegen test to show its lack of importance). |
||||||
let Documentation = [NoOutlineDocs]; | ||||||
let SimpleHandler = 1; | ||||||
} | ||||||
|
||||||
def NoMips16 : InheritableAttr, TargetSpecificAttr<TargetMips32> { | ||||||
let Spellings = [GCC<"nomips16">]; | ||||||
let Subjects = SubjectList<[Function], ErrorDiag>; | ||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -862,6 +862,36 @@ with ``__noinline__`` defined as a macro as ``__attribute__((noinline))``. | |
}]; | ||
} | ||
|
||
def NoOutlineDocs : Documentation { | ||
let Category = DocCatFunction; | ||
let Content = [{ | ||
This function attribute suppresses outlining from the annotated function. | ||
|
||
Outlining is the process where common parts of separate functions are extracted | ||
into a separate function (or assembly snippet), and calls to that function or | ||
snippet are inserted in the original functions. In this way, it can be seen as | ||
the opposite of inlining. It can help to reduce code size. | ||
|
||
.. code-block:: c | ||
|
||
[[clang::nooutline]] int x1(int y) { | ||
int z = COMPLEX_MACRO(y); // Not outlined | ||
return z + const1; | ||
} | ||
|
||
int x2(int y) { | ||
int z = COMPLEX_MACRO(y); // May be outlined | ||
return z * const2; | ||
} | ||
|
||
int x3(int y) { | ||
int z = COMPLEX_MACRO(y); // May be outlined | ||
reutrn z / const3; | ||
} | ||
|
||
}]; | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you explain why one would not want this to happen? Perhaps a quick example? And can you show a psuedo-code version of x2/x3 (though I'd probably suggest only a single-one of those examples, they aren't unique enough to have 2) as to what it might look like as an 'outlined' version? |
||
|
||
def MustTailDocs : Documentation { | ||
let Category = DocCatStmt; | ||
let Content = [{ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --check-attributes --version 6 | ||
// RUN: %clang_cc1 -emit-llvm %s -triple x86_64-unknown-linux-gnu -o - | FileCheck %s --check-prefix=C | ||
// RUN: %clang_cc1 -emit-llvm -x c++ %s -triple x86_64-unknown-linux-gnu -o - | FileCheck %s --check-prefix=CXX | ||
|
||
// C: Function Attrs: noinline nooutline nounwind optnone | ||
// C-LABEL: define dso_local i32 @t1( | ||
// C-SAME: i32 noundef [[X:%.*]]) #[[ATTR0:[0-9]+]] { | ||
// C-NEXT: [[ENTRY:.*:]] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The body in these tests are probably not worth it since all we care about are the FunctionAttrs line and the one with the declaration. The rest seems fragile for no value. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree with the fragility aspect, is there a better way to automatically test these or should I just write the checks by hand? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These are short/easy enough I'd suggest just writing them by hand (or just deleting everything in the body of the function manually). |
||
// C-NEXT: [[X_ADDR:%.*]] = alloca i32, align 4 | ||
// C-NEXT: store i32 [[X]], ptr [[X_ADDR]], align 4 | ||
// C-NEXT: [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4 | ||
// C-NEXT: ret i32 [[TMP0]] | ||
// | ||
// CXX: Function Attrs: mustprogress noinline nooutline nounwind optnone | ||
// CXX-LABEL: define dso_local noundef i32 @_Z2t1i( | ||
// CXX-SAME: i32 noundef [[X:%.*]]) #[[ATTR0:[0-9]+]] { | ||
// CXX-NEXT: [[ENTRY:.*:]] | ||
// CXX-NEXT: [[X_ADDR:%.*]] = alloca i32, align 4 | ||
// CXX-NEXT: store i32 [[X]], ptr [[X_ADDR]], align 4 | ||
// CXX-NEXT: [[TMP0:%.*]] = load i32, ptr [[X_ADDR]], align 4 | ||
// CXX-NEXT: ret i32 [[TMP0]] | ||
// | ||
[[clang::nooutline]] int t1(int x) { | ||
return x; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
// RUN: %clang_cc1 %s -verify -fsyntax-only | ||
|
||
[[clang::nooutline]] int a; // expected-error {{'clang::nooutline' attribute only applies to functions}} | ||
|
||
[[clang::nooutline]] void t1(void); | ||
|
||
[[clang::nooutline(2)]] void t2(void); // expected-error {{'clang::nooutline' attribute takes no arguments}} |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,7 @@ | ||||||
// RUN: %clang_cc1 -verify -fsyntax-only %s -Wno-c++17-extensions | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
I don’t think we need to pass |
||||||
|
||||||
[[clang::nooutline]] int a; // expected-error {{'clang::nooutline' attribute only applies to functions}} | ||||||
|
||||||
[[clang::nooutline]] void t1(void); | ||||||
|
||||||
[[clang::nooutline(2)]] void t2(void); // expected-error {{'clang::nooutline' attribute takes no arguments}} |
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.
There is a dedicated section called ‘Attribute Changes in Clang’ below