This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [gimplefe] Parsing __GIMPLE function body


Hi,

This patch parses simple assignment statement

int a;
void __GIMPLE foo()
{
  a = 1;
}

but it does not produce gimple dump. In debugging I found that
cfun->gimple_body is not NULL and it contains GIMPLE_ASSIGN statement.
Am I missing something ?



Thanks,
Prasad Ghangal

On 31 May 2016 at 15:57, Richard Biener <richard.guenther@gmail.com> wrote:
> On Mon, May 30, 2016 at 5:15 PM, Prasad Ghangal
> <prasad.ghangal@gmail.com> wrote:
>> Hi,
>>
>> As David suggested in his rtlfe patch,
>> this patch recognizes __GIMPLE keyword and switches to
>> c_parser_parse_gimple_body by providing -fgimple option.
>>
>>
>> diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
>> index 4568cf6..41a8f05 100644
>> --- a/gcc/c-family/c-common.c
>> +++ b/gcc/c-family/c-common.c
>> @@ -511,6 +511,7 @@ const struct c_common_resword c_common_reswords[] =
>>    { "__underlying_type", RID_UNDERLYING_TYPE, D_CXXONLY },
>>    { "__volatile",    RID_VOLATILE,    0 },
>>    { "__volatile__",    RID_VOLATILE,    0 },
>> +  { "__GIMPLE",        RID_GIMPLE,    0 },
>
> I think we need a D_GIMPLE_ONLY flag which disables this reserved word
> when -fgimple is not
> in effect.  That's something to put on a list of TODOs once everything
> else works fine (it's not
> high priority but a requirement to merge to trunk).  For now you can
> at least put D_CONLY there
> (as -fgimple is a C only flag).
>
>>    { "alignas",        RID_ALIGNAS,    D_CXXONLY | D_CXX11 | D_CXXWARN },
>>    { "alignof",        RID_ALIGNOF,    D_CXXONLY | D_CXX11 | D_CXXWARN },
>>    { "asm",        RID_ASM,    D_ASM },
>> diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
>> index 0295532..23a401d 100644
>> --- a/gcc/c-family/c-common.h
>> +++ b/gcc/c-family/c-common.h
>> @@ -104,6 +104,9 @@ enum rid
>>    RID_DFLOAT32, RID_DFLOAT64, RID_DFLOAT128,
>>    RID_FRACT, RID_ACCUM, RID_AUTO_TYPE, RID_BUILTIN_CALL_WITH_STATIC_CHAIN,
>>
>> +  /* "__GIMPLE", for the GIMPLE-parsing extension to the C frontend. */
>> +  RID_GIMPLE,
>> +
>>    /* C11 */
>>    RID_ALIGNAS, RID_GENERIC,
>>
>> diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
>> index 918df16..8ab56af 100644
>> --- a/gcc/c-family/c.opt
>> +++ b/gcc/c-family/c.opt
>> @@ -200,6 +200,10 @@ F
>>  Driver C ObjC C++ ObjC++ Joined Separate MissingArgError(missing path
>> after %qs)
>>  -F <dir>    Add <dir> to the end of the main framework include path.
>>
>> +fgimple
>> +C Var(flag_gimple) Init(0)
>> +Enable parsing GIMPLE
>> +
>>  H
>>  C ObjC C++ ObjC++
>>  Print the name of header files as they are used.
>> diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
>> index 1cf4fb4..c5a4d3f 100644
>> --- a/gcc/c/c-parser.c
>> +++ b/gcc/c/c-parser.c
>> @@ -1396,6 +1396,7 @@ static bool c_parser_cilk_verify_simd (c_parser
>> *, enum pragma_context);
>>  static tree c_parser_array_notation (location_t, c_parser *, tree, tree);
>>  static tree c_parser_cilk_clause_vectorlength (c_parser *, tree, bool);
>>  static void c_parser_cilk_grainsize (c_parser *, bool *);
>> +static void c_parser_parse_gimple_body (c_parser *parser);
>>
>>  /* Parse a translation unit (C90 6.7, C99 6.9).
>>
>> @@ -1638,6 +1639,7 @@ c_parser_declaration_or_fndef (c_parser *parser,
>> bool fndef_ok,
>>    tree all_prefix_attrs;
>>    bool diagnosed_no_specs = false;
>>    location_t here = c_parser_peek_token (parser)->location;
>> +  bool gimple_body_p = false;
>>
>>    if (static_assert_ok
>>        && c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
>> @@ -1687,6 +1689,17 @@ c_parser_declaration_or_fndef (c_parser
>> *parser, bool fndef_ok,
>>        c_parser_skip_to_end_of_block_or_statement (parser);
>>        return;
>>      }
>> +
>> +  if (c_parser_next_token_is (parser, CPP_KEYWORD))
>> +    {
>> +      c_token *kw_token = c_parser_peek_token (parser);
>> +      if (kw_token->keyword == RID_GIMPLE)
>> +    {
>> +      gimple_body_p = true;
>> +      c_parser_consume_token (parser);
>> +    }
>> +    }
>> +
>>    finish_declspecs (specs);
>>    bool auto_type_p = specs->typespec_word == cts_auto_type;
>>    if (c_parser_next_token_is (parser, CPP_SEMICOLON))
>> @@ -2102,6 +2115,14 @@ c_parser_declaration_or_fndef (c_parser
>> *parser, bool fndef_ok,
>>                     oacc_routine_clauses, false, first, true);
>>        DECL_STRUCT_FUNCTION (current_function_decl)->function_start_locus
>>      = c_parser_peek_token (parser)->location;
>> +
>> +      if (gimple_body_p && flag_gimple)
>> +    {
>> +      c_parser_parse_gimple_body (parser);
>> +      finish_function ();
>> +      return;
>> +    }
>> +
>>        fnbody = c_parser_compound_statement (parser);
>>        if (flag_cilkplus && contains_array_notation_expr (fnbody))
>>      fnbody = expand_array_notation_exprs (fnbody);
>> @@ -2123,7 +2144,7 @@ c_parser_declaration_or_fndef (c_parser *parser,
>> bool fndef_ok,
>>        add_stmt (fnbody);
>>        finish_function ();
>>      }
>> -
>> +
>>        timevar_pop (tv);
>>        break;
>>      }
>
> Always avoid stay changes like this.
>
>> @@ -18055,4 +18076,23 @@ c_parser_array_notation (location_t loc,
>> c_parser *parser, tree initial_index,
>>    return value_tree;
>>  }
>>
>> +/* Parse the body of a function declaration marked with "__GIMPLE".  */
>> +
>> +void
>> +c_parser_parse_gimple_body (c_parser *parser)
>> +{
>> +  if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
>> +    return;
>> +
>> +  location_t loc1 = c_parser_peek_token (parser)->location;
>> +  inform (loc1, "start of GIMPLE");
>> +
>> +  while (c_parser_next_token_is_not (parser, CPP_CLOSE_BRACE))
>> +    {
>> +    c_parser_consume_token (parser);
>> +    }
>> +
>> +  c_parser_consume_token (parser);
>> +}
>> +
>>  #include "gt-c-c-parser.h"
>>
>>
>>
>>
>> GIMPLE function body consists of GIMPLE statements. For parsing GIMPLE
>> function body, we need to populate gimple body with gimple statements
>> which will emit GIMPLE as it is.
>>
>> I would like to hear suggestions about how can I emit GIMPLE directly from FE.
>
> You should be able to use gimple_build_* functions declared in gimple.h, for
> example
>
>   stmt = gimple_build_assign (res, PLUS_EXPR, op0, op1);
>
> will build an assignment to res computing op0 + op1.  res, op0 and op1 can be
> most easily parsed using the appropriate C parsing functions for identifiers.
>
> You'll need to queue stmts you built in a gimple_seq and attach that to the
> function via gimple_set_body (fndecl, sequence).
>
> I suggest you try with a "simple" example like
>
> int a;
>
> __GIMPLE void foo (void)
> {
>   a = 1;
> }
>
> going forward with handling a = 1 + 2; and then, sth you'll need very quickly,
> handle local declarations like
>
> int a;
> __GIMPLE int foo (void)
> {
>   int b;
>   b = a;
>   b = b + 1;
>   a = b;
> }
>
> this is sth C code like int foo (void) { a = a + 1; } is gimplified to.
>
> Richard.
>
>>
>>
>> Thanks,
>> Prasad Ghangal
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 4568cf6..f2e62ca 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -511,6 +511,7 @@ const struct c_common_resword c_common_reswords[] =
   { "__underlying_type", RID_UNDERLYING_TYPE, D_CXXONLY },
   { "__volatile",	RID_VOLATILE,	0 },
   { "__volatile__",	RID_VOLATILE,	0 },
+  { "__GIMPLE",		RID_GIMPLE,	D_CONLY },
   { "alignas",		RID_ALIGNAS,	D_CXXONLY | D_CXX11 | D_CXXWARN },
   { "alignof",		RID_ALIGNOF,	D_CXXONLY | D_CXX11 | D_CXXWARN },
   { "asm",		RID_ASM,	D_ASM },
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index 0295532..23a401d 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -104,6 +104,9 @@ enum rid
   RID_DFLOAT32, RID_DFLOAT64, RID_DFLOAT128,
   RID_FRACT, RID_ACCUM, RID_AUTO_TYPE, RID_BUILTIN_CALL_WITH_STATIC_CHAIN,
 
+  /* "__GIMPLE", for the GIMPLE-parsing extension to the C frontend. */
+  RID_GIMPLE,
+
   /* C11 */
   RID_ALIGNAS, RID_GENERIC,
 
diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index 918df16..8ab56af 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -200,6 +200,10 @@ F
 Driver C ObjC C++ ObjC++ Joined Separate MissingArgError(missing path after %qs)
 -F <dir>	Add <dir> to the end of the main framework include path.
 
+fgimple
+C Var(flag_gimple) Init(0)
+Enable parsing GIMPLE
+
 H
 C ObjC C++ ObjC++
 Print the name of header files as they are used.
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index bca8653..f2f5b5a 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -58,6 +58,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "c-family/c-indentation.h"
 #include "gimple-expr.h"
 #include "context.h"
+#include "tree-pass.h"
 
 /* We need to walk over decls with incomplete struct/union/enum types
    after parsing the whole translation unit.
@@ -1396,6 +1397,11 @@ static bool c_parser_cilk_verify_simd (c_parser *, enum pragma_context);
 static tree c_parser_array_notation (location_t, c_parser *, tree, tree);
 static tree c_parser_cilk_clause_vectorlength (c_parser *, tree, bool);
 static void c_parser_cilk_grainsize (c_parser *, bool *);
+static void c_parser_parse_gimple_body (c_parser *);
+static void c_parser_gimple_compound_statement (c_parser *, gimple_seq *);
+static void c_finish_gimple_expr_stmt (tree, gimple_seq *);
+extern gimple *gimple_build_assign (tree, tree CXX_MEM_STAT_INFO);
+extern void gimple_seq_add_stmt (gimple_seq *, gimple *);
 
 /* Parse a translation unit (C90 6.7, C99 6.9).
 
@@ -1638,6 +1644,7 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
   tree all_prefix_attrs;
   bool diagnosed_no_specs = false;
   location_t here = c_parser_peek_token (parser)->location;
+  bool gimple_body_p = false;
 
   if (static_assert_ok
       && c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
@@ -1687,6 +1694,17 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
       c_parser_skip_to_end_of_block_or_statement (parser);
       return;
     }
+
+  if (c_parser_next_token_is (parser, CPP_KEYWORD))
+    {
+      c_token *kw_token = c_parser_peek_token (parser);
+      if (kw_token->keyword == RID_GIMPLE)
+	{
+	  gimple_body_p = true;
+	  c_parser_consume_token (parser);
+	}
+    }
+
   finish_declspecs (specs);
   bool auto_type_p = specs->typespec_word == cts_auto_type;
   if (c_parser_next_token_is (parser, CPP_SEMICOLON))
@@ -2102,6 +2120,15 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
 			       oacc_routine_clauses, false, first, true);
       DECL_STRUCT_FUNCTION (current_function_decl)->function_start_locus
 	= c_parser_peek_token (parser)->location;
+      
+      if (gimple_body_p && flag_gimple)
+	{
+	  c_parser_parse_gimple_body (parser);
+	  finish_function ();
+	  timevar_pop (tv);
+	  return;
+	}
+
       fnbody = c_parser_compound_statement (parser);
       if (flag_cilkplus && contains_array_notation_expr (fnbody))
 	fnbody = expand_array_notation_exprs (fnbody);
@@ -18070,4 +18097,97 @@ c_parser_array_notation (location_t loc, c_parser *parser, tree initial_index,
   return value_tree;
 }
 
+/* Parse the body of a function declaration marked with "__GIMPLE".  */
+
+void 
+c_parser_parse_gimple_body (c_parser *parser)
+{
+  gimple_seq seq;
+  location_t loc1 = c_parser_peek_token (parser)->location;
+  inform (loc1, "start of GIMPLE");
+  seq = NULL;
+  c_parser_gimple_compound_statement (parser, &seq);
+  gimple_set_body (current_function_decl, seq);
+  cfun->curr_properties = PROP_gimple_any;
+  return;
+}
+
+/* Parser a compound statement in gimple function body */
+
+static void
+c_parser_gimple_compound_statement (c_parser *parser, gimple_seq *seq)
+{
+  location_t brace_loc;
+  brace_loc = c_parser_peek_token (parser)->location;
+  if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
+    {
+      return;
+    }
+  if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
+    {
+      c_parser_consume_token (parser);
+      goto out;
+    }
+
+  /* We must now have at least one statement, label or declaration.  */
+  
+  if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
+    {
+      c_parser_error (parser, "expected declaration or statement");
+      c_parser_consume_token (parser);
+      goto out;
+    }
+  while (c_parser_next_token_is_not (parser, CPP_CLOSE_BRACE))
+    {
+      if (c_parser_next_token_is (parser, CPP_EOF))
+	{
+	  c_parser_error (parser, "expected declaration or statement");
+	  goto out;
+	}
+      else
+	{
+	  switch (c_parser_peek_token (parser)->type)
+	    {
+	    case CPP_KEYWORD:
+	      switch (c_parser_peek_token (parser)->keyword)
+		{
+		default:
+		  goto expr_stmt;
+		}
+	      break;
+	    case CPP_SEMICOLON:
+	      c_parser_consume_token (parser);
+	      break;
+	    default:
+	    expr_stmt:
+	      c_finish_gimple_expr_stmt (c_parser_expression_conv (parser).value, seq);
+	      c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
+	      break;
+	    }
+	}
+      parser->error = false;
+    }
+  c_parser_consume_token (parser);
+
+  out:
+  return;
+}
+
+/* Emit an expression as a statement. */
+
+static void
+c_finish_gimple_expr_stmt (tree expr, gimple_seq *seq)
+{
+  tree lhs, rhs;
+  gimple *stmt;
+  if (expr)
+    {
+      lhs = TREE_OPERAND (expr, 0);
+      rhs = TREE_OPERAND (expr, 1);
+      stmt = gimple_build_assign (lhs, rhs);
+      gimple_seq_add_stmt (seq, stmt);
+      return;
+    }
+}
+
 #include "gt-c-c-parser.h"
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 8316bb8..dd6b04e 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -11678,7 +11678,10 @@ gimplify_function_tree (tree fndecl)
       && !needs_to_live_in_memory (ret))
     DECL_GIMPLE_REG_P (ret) = 1;
 
-  bind = gimplify_body (fndecl, true);
+  if (!cfun->gimple_body)
+    bind = gimplify_body (fndecl, true);
+  else
+    bind = NULL;
 
   /* The tree body of the function is no longer needed, replace it
      with the new GIMPLE body.  */

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]