aboutsummaryrefslogtreecommitdiff
path: root/gcc/c
diff options
context:
space:
mode:
authorSegher Boessenkool <segher@kernel.crashing.org>2018-12-06 18:56:58 +0100
committerSegher Boessenkool <segher@gcc.gnu.org>2018-12-06 18:56:58 +0100
commit5b76e75f760f3e4787851366359d5d50f989877c (patch)
treeae4aaa5970fcde870ee822e0cab27211b682ea3e /gcc/c
parent30bd42b979140de02d343bb1014e9aece2e683c1 (diff)
downloadgcc-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/ChangeLog8
-rw-r--r--gcc/c/c-parser.c21
-rw-r--r--gcc/c/c-tree.h3
-rw-r--r--gcc/c/c-typeck.c7
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;
}