diff options
author | Segher Boessenkool <segher@kernel.crashing.org> | 2018-12-06 18:56:58 +0100 |
---|---|---|
committer | Segher Boessenkool <segher@gcc.gnu.org> | 2018-12-06 18:56:58 +0100 |
commit | 5b76e75f760f3e4787851366359d5d50f989877c (patch) | |
tree | ae4aaa5970fcde870ee822e0cab27211b682ea3e /gcc/c | |
parent | 30bd42b979140de02d343bb1014e9aece2e683c1 (diff) | |
download | gcc-5b76e75f760f3e4787851366359d5d50f989877c.zip gcc-5b76e75f760f3e4787851366359d5d50f989877c.tar.gz gcc-5b76e75f760f3e4787851366359d5d50f989877c.tar.bz2 |
asm inline
The Linux kernel people want a feature that makes GCC pretend some
inline assembler code is tiny (while it would think it is huge), so
that such code will be inlined essentially always instead of
essentially never.
This patch lets you say "asm inline" instead of just "asm", with the
result that that inline assembler is always counted as minimum cost
for inlining. It implements this for C and C++, making "inline"
another asm-qualifier (supplementing "volatile" and "goto").
* doc/extend.texi (Using Assembly Language with C): Document asm inline.
(Size of an asm): Fix typo. Document asm inline.
* gimple-pretty-print.c (dump_gimple_asm): Handle asm inline.
* gimple.h (enum gf_mask): Add GF_ASM_INLINE.
(gimple_asm_set_volatile): Fix typo.
(gimple_asm_inline_p): New.
(gimple_asm_set_inline): New.
* gimplify.c (gimplify_asm_expr): Propagate the asm inline flag from
tree to gimple.
* ipa-icf-gimple.c (func_checker::compare_gimple_asm): Compare the
gimple_asm_inline_p flag, too.
* tree-core.h (tree_base): Document that protected_flag is ASM_INLINE_P
in an ASM_EXPR.
* tree-inline.c (estimate_num_insns): If gimple_asm_inline_p return
a minimum size for an asm.
* tree.h (ASM_INLINE_P): New.
gcc/c/
* c-parser.c (c_parser_asm_statement): Detect the inline keyword
after asm. Pass a flag for it to build_asm_expr.
* c-tree.h (build_asm_expr): Update declaration.
* c-typeck.c (build_asm_stmt): Add is_inline parameter. Use it to
set ASM_INLINE_P.
gcc/cp/
* cp-tree.h (finish_asm_stmt): Update declaration.
* parser.c (cp_parser_asm_definition): Detect the inline keyword
after asm. Pass a flag for it to finish_asm_stmt.
* pt.c (tsubst_expr): Pass the ASM_INLINE_P flag to finish_asm_stmt.
* semantics.c (finish_asm_stmt): Add inline_p parameter. Use it to
set ASM_INLINE_P.
gcc/testsuite/
* c-c++-common/torture/asm-inline.c: New testcase.
* gcc.dg/asm-qual-2.c: Test asm inline, too.
From-SVN: r266860
Diffstat (limited to 'gcc/c')
-rw-r--r-- | gcc/c/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/c/c-parser.c | 21 | ||||
-rw-r--r-- | gcc/c/c-tree.h | 3 | ||||
-rw-r--r-- | gcc/c/c-typeck.c | 7 |
4 files changed, 32 insertions, 7 deletions
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index c54223d..69d4929 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,5 +1,13 @@ 2018-12-06 Segher Boessenkool <segher@kernel.crashing.org> + * c-parser.c (c_parser_asm_statement): Detect the inline keyword + after asm. Pass a flag for it to build_asm_expr. + * c-tree.h (build_asm_expr): Update declaration. + * c-typeck.c (build_asm_stmt): Add is_inline parameter. Use it to + set ASM_INLINE_P. + +2018-12-06 Segher Boessenkool <segher@kernel.crashing.org> + PR inline-asm/55681 * c-parser.c (c_parser_asm_statement): Update grammar. Allow any combination of volatile and goto, in any order, without repetitions. diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index a4a8745..3a7fcdc 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -6329,11 +6329,12 @@ c_parser_for_statement (c_parser *parser, bool ivdep, unsigned short unroll, } /* Parse an asm statement, a GNU extension. This is a full-blown asm - statement with inputs, outputs, clobbers, and volatile and goto tag - allowed. + statement with inputs, outputs, clobbers, and volatile, inline, and goto + tags allowed. asm-qualifier: volatile + inline goto asm-qualifier-list: @@ -6360,7 +6361,7 @@ static tree c_parser_asm_statement (c_parser *parser) { tree quals, str, outputs, inputs, clobbers, labels, ret; - bool simple, is_volatile, is_goto; + bool simple, is_volatile, is_inline, is_goto; location_t asm_loc = c_parser_peek_token (parser)->location; int section, nsections; @@ -6369,6 +6370,7 @@ c_parser_asm_statement (c_parser *parser) quals = NULL_TREE; is_volatile = false; + is_inline = false; is_goto = false; for (bool done = false; !done; ) switch (c_parser_peek_token (parser)->keyword) @@ -6383,6 +6385,16 @@ c_parser_asm_statement (c_parser *parser) else done = true; break; + case RID_INLINE: + if (!is_inline) + { + is_inline = true; + quals = c_parser_peek_token (parser)->value; + c_parser_consume_token (parser); + } + else + done = true; + break; case RID_GOTO: if (!is_goto) { @@ -6471,7 +6483,8 @@ c_parser_asm_statement (c_parser *parser) c_parser_skip_to_end_of_block_or_statement (parser); ret = build_asm_stmt (quals, build_asm_expr (asm_loc, str, outputs, inputs, - clobbers, labels, simple)); + clobbers, labels, simple, + is_inline)); error: parser->lex_untranslated_string = false; diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h index 5ed2f48..f08a8fc 100644 --- a/gcc/c/c-tree.h +++ b/gcc/c/c-tree.h @@ -677,7 +677,8 @@ extern tree build_compound_literal (location_t, tree, tree, bool, extern void check_compound_literal_type (location_t, struct c_type_name *); extern tree c_start_case (location_t, location_t, tree, bool); extern void c_finish_case (tree, tree); -extern tree build_asm_expr (location_t, tree, tree, tree, tree, tree, bool); +extern tree build_asm_expr (location_t, tree, tree, tree, tree, tree, bool, + bool); extern tree build_asm_stmt (tree, tree); extern int c_types_compatible_p (tree, tree); extern tree c_begin_compound_stmt (bool); diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index 8fbecfc..1a89727 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -10327,10 +10327,12 @@ build_asm_stmt (tree cv_qualifier, tree args) some INPUTS, and some CLOBBERS. The latter three may be NULL. SIMPLE indicates whether there was anything at all after the string in the asm expression -- asm("blah") and asm("blah" : ) - are subtly different. We use a ASM_EXPR node to represent this. */ + are subtly different. We use a ASM_EXPR node to represent this. + LOC is the location of the asm, and IS_INLINE says whether this + is asm inline. */ tree build_asm_expr (location_t loc, tree string, tree outputs, tree inputs, - tree clobbers, tree labels, bool simple) + tree clobbers, tree labels, bool simple, bool is_inline) { tree tail; tree args; @@ -10448,6 +10450,7 @@ build_asm_expr (location_t loc, tree string, tree outputs, tree inputs, as volatile. */ ASM_INPUT_P (args) = simple; ASM_VOLATILE_P (args) = (noutputs == 0); + ASM_INLINE_P (args) = is_inline; return args; } |