public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* [gimplefe] hacking pass manager
@ 2016-06-18  6:32 Prasad Ghangal
  2016-06-29 16:20 ` Prathamesh Kulkarni
  0 siblings, 1 reply; 29+ messages in thread
From: Prasad Ghangal @ 2016-06-18  6:32 UTC (permalink / raw)
  To: Richard Biener, David Malcolm, gcc Mailing List

[-- Attachment #1: Type: text/plain, Size: 682 bytes --]

Hi,

I tried hacking pass manager to execute only given passes. For this I
am adding new member as opt_pass *custom_pass_list to the function
structure to store passes need to execute and providing the
custom_pass_list to execute_pass_list() function instead of all passes

for test case like-

int a;
void __GIMPLE (execute ("tree-ccp1", "tree-fre1")) foo()
{
bb_1:
  a = 1 + a;
}

it will execute only given passes i.e. ccp1 and fre1 pass on the function

and for test case like -

int a;
void __GIMPLE (startwith ("tree-ccp1")) foo()
{
bb_1:
  a = 1 + a;
}

it will act as a entry point to the pipeline and will execute passes
starting from given pass.



Thanks,
Prasad Ghangal

[-- Attachment #2: test.diff --]
[-- Type: text/plain, Size: 16930 bytes --]

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-decl.c b/gcc/c/c-decl.c
index d79802e..d498f19 100644
--- a/gcc/c/c-decl.c
+++ b/gcc/c/c-decl.c
@@ -9154,6 +9154,7 @@ finish_function (void)
   invoke_plugin_callbacks (PLUGIN_FINISH_PARSE_FUNCTION, current_function_decl);
   current_function_decl = NULL;
 }
+
 \f
 /* Check the declarations given in a for-loop for satisfying the C99
    constraints.  If exactly one such decl is found, return it.  LOC is
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index bca8653..2d83281 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -58,6 +58,14 @@ 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"
+#include "tree-pretty-print.h"
+#include "tree.h"
+#include "basic-block.h"
+#include "gimple.h"
+#include "gimple-pretty-print.h"
+#include "tree-ssa.h"
+#include "pass_manager.h"
 
 /* We need to walk over decls with incomplete struct/union/enum types
    after parsing the whole translation unit.
@@ -1396,6 +1404,13 @@ 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 *);
+static void c_parser_gimple_basic_block (c_parser *, gimple_seq *);
+static void c_parser_gimple_expression (c_parser *, gimple_seq *);
+static void c_parser_pass_list (c_parser *, opt_pass **);
+static opt_pass *c_parser_pass_list_params (c_parser *, opt_pass **);
 
 /* Parse a translation unit (C90 6.7, C99 6.9).
 
@@ -1638,6 +1653,8 @@ 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;
+  opt_pass *pass = NULL;
 
   if (static_assert_ok
       && c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
@@ -1687,6 +1704,20 @@ 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);
+	  c_parser_pass_list (parser, &pass);
+	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 
+				     "expected %<)%>");
+	}
+    }
+
   finish_declspecs (specs);
   bool auto_type_p = specs->typespec_word == cts_auto_type;
   if (c_parser_next_token_is (parser, CPP_SEMICOLON))
@@ -2093,6 +2124,10 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
 	c_parser_declaration_or_fndef (parser, false, false, false,
 				       true, false, NULL, vNULL);
       store_parm_decls ();
+
+      if (pass)
+	cfun->custom_pass_list = pass;
+
       if (omp_declare_simd_clauses.exists ()
 	  || !vec_safe_is_empty (parser->cilk_simd_fn_tokens))
 	c_finish_omp_declare_simd (parser, current_function_decl, NULL_TREE,
@@ -2102,6 +2137,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);
+	  cgraph_node::finalize_function (current_function_decl, false);
+	  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 +18114,288 @@ 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)
+{
+  debug_generic_expr (current_function_decl);
+  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);
+
+  greturn *r = gimple_build_return (NULL);
+  gimple_seq_add_stmt (&seq, r);
+
+  DECL_INITIAL (current_function_decl) = make_node (BLOCK);
+  BLOCK_SUPERCONTEXT (DECL_INITIAL (current_function_decl)) = current_function_decl;
+
+  tree block = DECL_INITIAL (current_function_decl);
+  BLOCK_SUBBLOCKS (block) = NULL_TREE;
+  BLOCK_CHAIN (block) = NULL_TREE;
+  TREE_ASM_WRITTEN (block) = 1;
+
+  gimple_set_body (current_function_decl, seq);
+  cfun->curr_properties = PROP_gimple_any;
+
+  debug_gimple_seq (seq);
+  init_tree_ssa (cfun);
+  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_NAME) 
+	  && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
+	{
+	  c_parser_gimple_basic_block (parser, seq);
+	}
+      else 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_parser_gimple_expression (parser, seq);
+	      c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
+	      break;
+	    }
+	}
+      parser->error = false;
+    }
+  c_parser_consume_token (parser);
+
+  out:
+  return;
+}
+
+/* Parse a gimple expression */
+
+static void
+c_parser_gimple_expression (c_parser *parser, gimple_seq *seq)
+{
+  c_expr lhs, rhs;
+  enum tree_code subcode;
+  lhs = c_parser_unary_expression (parser);
+  if (c_parser_next_token_is (parser, CPP_EQ))
+    c_parser_consume_token (parser);
+  if (!(c_parser_next_token_is (parser, CPP_NAME) 
+	      || c_parser_next_token_is (parser, CPP_NUMBER)))
+    {
+      c_parser_error (parser, "expected expression");
+      return;
+    }
+  switch (c_parser_peek_2nd_token (parser)->type)
+    {
+    case CPP_PLUS:
+      subcode = PLUS_EXPR;
+      break;
+    case CPP_MINUS:
+      subcode = MINUS_EXPR;
+      break;
+    case CPP_MULT:
+      subcode = MULT_EXPR;
+      break;
+    case CPP_DIV:
+      subcode = RDIV_EXPR;
+      break;
+    case CPP_SEMICOLON:
+    default:
+      gimple_seq_add_stmt (seq, gimple_build_assign (lhs.value, 
+						     c_parser_unary_expression (parser).value));
+      return;
+    }
+/*  if (!(c_parser_next_token_is (parser, CPP_NAME) 
+	      || c_parser_next_token_is (parser, CPP_NUMBER)))
+    {
+      c_parser_error (parser, "invalid gimple expression");
+      return;
+    }*/
+  rhs = c_parser_binary_expression (parser, NULL, NULL);
+  gimple_seq_add_stmt (seq, gimple_build_assign (lhs.value, subcode, 
+						 TREE_OPERAND(rhs.value, 0), TREE_OPERAND(rhs.value, 1)));
+  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;
+    }
+}
+
+/* Parse gimple basic block */
+
+static void 
+c_parser_gimple_basic_block (c_parser *parser, gimple_seq *seq)
+{
+  tree bb;
+  tree name = c_parser_peek_token (parser)->value;
+  location_t loc1 = c_parser_peek_token (parser)->location;
+  gcc_assert (c_parser_next_token_is (parser, CPP_NAME));
+  c_parser_consume_token (parser);
+  gcc_assert (c_parser_next_token_is (parser, CPP_COLON));
+  c_parser_consume_token (parser);
+  bb = build_decl (loc1, LABEL_DECL, name, void_type_node);
+  DECL_CONTEXT (bb) = current_function_decl;
+  gimple_seq_add_stmt (seq, gimple_build_label (bb));
+  return;
+}
+
+/* Parse gimple pass list */
+
+static void 
+c_parser_pass_list (c_parser *parser, opt_pass **pass)
+{
+  opt_pass *pass_start;
+  if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
+    {
+      return;
+    }
+
+  if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
+    {
+      return;
+    }
+
+  if (c_parser_next_token_is (parser, CPP_NAME))
+    {
+      const char *op = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
+      c_parser_consume_token (parser);
+      if (!strcmp (op, "execute"))
+	{
+	  pass_start = c_parser_pass_list_params (parser, pass);
+	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 
+				     "expected %<)%>");
+	  (*pass)->next = NULL;
+	  *pass = pass_start;
+	}
+      else if (!strcmp (op, "startwith"))
+	{
+	  *pass = c_parser_pass_list_params (parser, pass);
+	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 
+				     "expected %<)%>");
+	}
+      else
+	{
+	  c_parser_error (parser, "invalid operation");
+	  return;
+	}
+    }
+  else if (c_parser_next_token_is (parser, CPP_EOF))
+    {
+      c_parser_error (parser, "expected parameters");
+      return;
+    }
+
+  return;
+}
+
+static opt_pass *
+c_parser_pass_list_params (c_parser *parser, opt_pass **pass)
+{
+  opt_pass *pass_start, *new_pass;
+  if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
+    {
+      return NULL;
+    }
+
+  if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
+    {
+      return NULL;
+    }
+
+  while (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN))
+    {
+      if (c_parser_next_token_is (parser, CPP_EOF))
+	{
+	  c_parser_error (parser, "expected pass names");
+	  return NULL;
+	}
+
+      if (c_parser_next_token_is (parser, CPP_STRING))
+	{
+	  const char *name = TREE_STRING_POINTER(c_parser_peek_token (parser)->value);
+	  c_parser_consume_token (parser);
+	  new_pass = g->get_passes ()->get_pass_by_name (name);
+
+	  if (!new_pass)
+	    {
+	      c_parser_error (parser, "invalid pass name");
+	      return NULL;
+	    }
+	  if (*pass)
+	    {
+	      (*pass)->next = new_pass;
+	      (*pass) = (*pass)->next;
+	    }
+	  else
+	    {
+	      *pass = new_pass;
+	      pass_start = *pass;
+	    }
+	}
+      else if (c_parser_next_token_is (parser, CPP_COMMA))
+	c_parser_consume_token (parser);
+      else
+	{
+	  c_parser_error (parser, "expected pass names");
+	  return NULL;
+	}
+    }
+  return pass_start;
+}
+
 #include "gt-c-c-parser.h"
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 4bfcad7..7effd71 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -1980,7 +1980,10 @@ cgraph_node::expand (void)
   /* Signal the start of passes.  */
   invoke_plugin_callbacks (PLUGIN_ALL_PASSES_START, NULL);
 
-  execute_pass_list (cfun, g->get_passes ()->all_passes);
+  if (flag_gimple && cfun->custom_pass_list)
+    execute_pass_list (cfun, cfun->custom_pass_list);
+  else
+    execute_pass_list (cfun, g->get_passes ()->all_passes);
 
   /* Signal the end of passes.  */
   invoke_plugin_callbacks (PLUGIN_ALL_PASSES_END, NULL);
@@ -2033,7 +2036,10 @@ cgraph_node::expand (void)
   timevar_pop (TV_REST_OF_COMPILATION);
 
   /* Make sure that BE didn't give up on compiling.  */
-  gcc_assert (TREE_ASM_WRITTEN (decl));
+
+  if (!(flag_gimple && cfun->custom_pass_list))	/* FIXME : for gimplefe custom_pass_list */
+    gcc_assert (TREE_ASM_WRITTEN (decl));
+  
   if (cfun)
     pop_cfun ();
 
diff --git a/gcc/coretypes.h b/gcc/coretypes.h
index b3a91a6..491573e 100644
--- a/gcc/coretypes.h
+++ b/gcc/coretypes.h
@@ -85,6 +85,7 @@ typedef const union tree_node *const_tree;
 struct gimple;
 typedef gimple *gimple_seq;
 struct gimple_stmt_iterator;
+class opt_pass;
 
 /* Forward decls for leaf gimple subclasses (for individual gimple codes).
    Keep this in the same order as the corresponding codes in gimple.def.  */
@@ -399,6 +400,8 @@ typedef unsigned char uchar;
 #include "input.h"
 #include "is-a.h"
 #include "memory-block.h"
+#include "pass_manager.h"
+#include "tree-pass.h"
 #endif /* GENERATOR_FILE && !USED_FOR_TARGET */
 
 #endif /* coretypes.h */
diff --git a/gcc/function.h b/gcc/function.h
index 501ef68..f84b97b 100644
--- a/gcc/function.h
+++ b/gcc/function.h
@@ -228,6 +228,9 @@ struct GTY(()) function {
   /* GIMPLE body for this function.  */
   gimple_seq gimple_body;
 
+  /* GIMPLEFE Passes */
+  opt_pass *custom_pass_list = NULL;
+
   /* SSA and dataflow information.  */
   struct gimple_df *gimple_df;
 
diff --git a/gcc/gimple-expr.c b/gcc/gimple-expr.c
index ed012cc..1b2310f 100644
--- a/gcc/gimple-expr.c
+++ b/gcc/gimple-expr.c
@@ -726,6 +726,9 @@ is_gimple_ip_invariant (const_tree t)
 bool
 is_gimple_reg (tree t)
 {
+  if (flag_gimple)  /* FIXME : For GIMPLE FE gimple expr*/
+    return true;
+
   if (virtual_operand_p (t))
     return false;
 
diff --git a/gcc/gimple-low.c b/gcc/gimple-low.c
index 9ea17af..e56e81c 100644
--- a/gcc/gimple-low.c
+++ b/gcc/gimple-low.c
@@ -90,8 +90,10 @@ lower_function_body (void)
 
   /* The gimplifier should've left a body of exactly one statement,
      namely a GIMPLE_BIND.  */
-  gcc_assert (gimple_seq_first (body) == gimple_seq_last (body)
-	      && gimple_code (gimple_seq_first_stmt (body)) == GIMPLE_BIND);
+  /* FIXME : to parse gimple body without gimple bind */
+  if (! (gimple_seq_first (body) == gimple_seq_last (body)
+      && gimple_code (gimple_seq_first_stmt (body)) == GIMPLE_BIND))
+    return 0;
 
   memset (&data, 0, sizeof (data));
   data.block = DECL_INITIAL (current_function_decl);
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.  */
diff --git a/gcc/passes.c b/gcc/passes.c
index 0565cfa..117a25a 100644
--- a/gcc/passes.c
+++ b/gcc/passes.c
@@ -2294,6 +2294,7 @@ execute_one_pass (opt_pass *pass)
     gcc_assert (cfun && current_function_decl);
 
   current_pass = pass;
+  debug_pass ();
 
   /* Check whether gate check should be avoided.
      User controls the value of the gate through the parameter "gate_status". */

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [gimplefe] hacking pass manager
  2016-06-18  6:32 [gimplefe] hacking pass manager Prasad Ghangal
@ 2016-06-29 16:20 ` Prathamesh Kulkarni
  2016-06-29 16:45   ` Richard Biener
  0 siblings, 1 reply; 29+ messages in thread
From: Prathamesh Kulkarni @ 2016-06-29 16:20 UTC (permalink / raw)
  To: Prasad Ghangal; +Cc: Richard Biener, David Malcolm, gcc Mailing List

On 18 June 2016 at 12:02, Prasad Ghangal <prasad.ghangal@gmail.com> wrote:
> Hi,
>
> I tried hacking pass manager to execute only given passes. For this I
> am adding new member as opt_pass *custom_pass_list to the function
> structure to store passes need to execute and providing the
> custom_pass_list to execute_pass_list() function instead of all passes
>
> for test case like-
>
> int a;
> void __GIMPLE (execute ("tree-ccp1", "tree-fre1")) foo()
> {
> bb_1:
>   a = 1 + a;
> }
>
> it will execute only given passes i.e. ccp1 and fre1 pass on the function
>
> and for test case like -
>
> int a;
> void __GIMPLE (startwith ("tree-ccp1")) foo()
> {
> bb_1:
>   a = 1 + a;
> }
>
> it will act as a entry point to the pipeline and will execute passes
> starting from given pass.
Bike-shedding:
Would it make sense to have syntax for defining pass ranges to execute ?
for instance:
void __GIMPLE(execute (pass_start : pass_end))
which would execute all the passes within range [pass_start, pass_end],
which would be convenient if the range is large.

Thanks,
Prathamesh
>
>
>
> Thanks,
> Prasad Ghangal

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [gimplefe] hacking pass manager
  2016-06-29 16:20 ` Prathamesh Kulkarni
@ 2016-06-29 16:45   ` Richard Biener
  2016-06-29 19:14     ` Prasad Ghangal
  0 siblings, 1 reply; 29+ messages in thread
From: Richard Biener @ 2016-06-29 16:45 UTC (permalink / raw)
  To: Prathamesh Kulkarni, Prasad Ghangal; +Cc: David Malcolm, gcc Mailing List

On June 29, 2016 6:20:29 PM GMT+02:00, Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org> wrote:
>On 18 June 2016 at 12:02, Prasad Ghangal <prasad.ghangal@gmail.com>
>wrote:
>> Hi,
>>
>> I tried hacking pass manager to execute only given passes. For this I
>> am adding new member as opt_pass *custom_pass_list to the function
>> structure to store passes need to execute and providing the
>> custom_pass_list to execute_pass_list() function instead of all
>passes
>>
>> for test case like-
>>
>> int a;
>> void __GIMPLE (execute ("tree-ccp1", "tree-fre1")) foo()
>> {
>> bb_1:
>>   a = 1 + a;
>> }
>>
>> it will execute only given passes i.e. ccp1 and fre1 pass on the
>function
>>
>> and for test case like -
>>
>> int a;
>> void __GIMPLE (startwith ("tree-ccp1")) foo()
>> {
>> bb_1:
>>   a = 1 + a;
>> }
>>
>> it will act as a entry point to the pipeline and will execute passes
>> starting from given pass.
>Bike-shedding:
>Would it make sense to have syntax for defining pass ranges to execute
>?
>for instance:
>void __GIMPLE(execute (pass_start : pass_end))
>which would execute all the passes within range [pass_start, pass_end],
>which would be convenient if the range is large.

But it would rely on a particular pass pipeline, f.e. pass-start appearing before pass-end.

Currently control doesn't work 100% as it only replaces all_optimizations but not lowering passes or early opts, nor IPA opts.

Richard.

>Thanks,
>Prathamesh
>>
>>
>>
>> Thanks,
>> Prasad Ghangal


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [gimplefe] hacking pass manager
  2016-06-29 16:45   ` Richard Biener
@ 2016-06-29 19:14     ` Prasad Ghangal
  2016-06-30 11:41       ` Richard Biener
  0 siblings, 1 reply; 29+ messages in thread
From: Prasad Ghangal @ 2016-06-29 19:14 UTC (permalink / raw)
  To: Richard Biener; +Cc: Prathamesh Kulkarni, David Malcolm, gcc Mailing List

On 29 June 2016 at 22:15, Richard Biener <richard.guenther@gmail.com> wrote:
> On June 29, 2016 6:20:29 PM GMT+02:00, Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org> wrote:
>>On 18 June 2016 at 12:02, Prasad Ghangal <prasad.ghangal@gmail.com>
>>wrote:
>>> Hi,
>>>
>>> I tried hacking pass manager to execute only given passes. For this I
>>> am adding new member as opt_pass *custom_pass_list to the function
>>> structure to store passes need to execute and providing the
>>> custom_pass_list to execute_pass_list() function instead of all
>>passes
>>>
>>> for test case like-
>>>
>>> int a;
>>> void __GIMPLE (execute ("tree-ccp1", "tree-fre1")) foo()
>>> {
>>> bb_1:
>>>   a = 1 + a;
>>> }
>>>
>>> it will execute only given passes i.e. ccp1 and fre1 pass on the
>>function
>>>
>>> and for test case like -
>>>
>>> int a;
>>> void __GIMPLE (startwith ("tree-ccp1")) foo()
>>> {
>>> bb_1:
>>>   a = 1 + a;
>>> }
>>>
>>> it will act as a entry point to the pipeline and will execute passes
>>> starting from given pass.
>>Bike-shedding:
>>Would it make sense to have syntax for defining pass ranges to execute
>>?
>>for instance:
>>void __GIMPLE(execute (pass_start : pass_end))
>>which would execute all the passes within range [pass_start, pass_end],
>>which would be convenient if the range is large.
>
> But it would rely on a particular pass pipeline, f.e. pass-start appearing before pass-end.
>
> Currently control doesn't work 100% as it only replaces all_optimizations but not lowering passes or early opts, nor IPA opts.
>

Each pass needs GIMPLE in some specific form. So I am letting lowering
and early opt passes to execute. I think we have to execute some
passes (like cfg) anyway to represent GIMPLE into proper form

> Richard.
>
>>Thanks,
>>Prathamesh
>>>
>>>
>>>
>>> Thanks,
>>> Prasad Ghangal
>
>

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [gimplefe] hacking pass manager
  2016-06-29 19:14     ` Prasad Ghangal
@ 2016-06-30 11:41       ` Richard Biener
  2016-07-01 12:30         ` Prathamesh Kulkarni
  2016-07-06  7:51         ` Prasad Ghangal
  0 siblings, 2 replies; 29+ messages in thread
From: Richard Biener @ 2016-06-30 11:41 UTC (permalink / raw)
  To: Prasad Ghangal; +Cc: Prathamesh Kulkarni, David Malcolm, gcc Mailing List

On Wed, Jun 29, 2016 at 9:13 PM, Prasad Ghangal
<prasad.ghangal@gmail.com> wrote:
> On 29 June 2016 at 22:15, Richard Biener <richard.guenther@gmail.com> wrote:
>> On June 29, 2016 6:20:29 PM GMT+02:00, Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org> wrote:
>>>On 18 June 2016 at 12:02, Prasad Ghangal <prasad.ghangal@gmail.com>
>>>wrote:
>>>> Hi,
>>>>
>>>> I tried hacking pass manager to execute only given passes. For this I
>>>> am adding new member as opt_pass *custom_pass_list to the function
>>>> structure to store passes need to execute and providing the
>>>> custom_pass_list to execute_pass_list() function instead of all
>>>passes
>>>>
>>>> for test case like-
>>>>
>>>> int a;
>>>> void __GIMPLE (execute ("tree-ccp1", "tree-fre1")) foo()
>>>> {
>>>> bb_1:
>>>>   a = 1 + a;
>>>> }
>>>>
>>>> it will execute only given passes i.e. ccp1 and fre1 pass on the
>>>function
>>>>
>>>> and for test case like -
>>>>
>>>> int a;
>>>> void __GIMPLE (startwith ("tree-ccp1")) foo()
>>>> {
>>>> bb_1:
>>>>   a = 1 + a;
>>>> }
>>>>
>>>> it will act as a entry point to the pipeline and will execute passes
>>>> starting from given pass.
>>>Bike-shedding:
>>>Would it make sense to have syntax for defining pass ranges to execute
>>>?
>>>for instance:
>>>void __GIMPLE(execute (pass_start : pass_end))
>>>which would execute all the passes within range [pass_start, pass_end],
>>>which would be convenient if the range is large.
>>
>> But it would rely on a particular pass pipeline, f.e. pass-start appearing before pass-end.
>>
>> Currently control doesn't work 100% as it only replaces all_optimizations but not lowering passes or early opts, nor IPA opts.
>>
>
> Each pass needs GIMPLE in some specific form. So I am letting lowering
> and early opt passes to execute. I think we have to execute some
> passes (like cfg) anyway to represent GIMPLE into proper form

Yes, that's true.  Note that early opt passes only optimize but we need
pass_build_ssa_passes at least (for into-SSA).  For proper unit-testing
of GIMPLE passes we do need to guard off early opts somehow
(I guess a simple if (flag_gimple && cfun->custom_pass_list) would do
that).

Then there is of course the question about IPA passes which I think is
somewhat harder (one could always disable all IPA passes manually
via flags of course or finally have a global -fipa/no-ipa like most
other compilers).

Richard.

>> Richard.
>>
>>>Thanks,
>>>Prathamesh
>>>>
>>>>
>>>>
>>>> Thanks,
>>>> Prasad Ghangal
>>
>>

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [gimplefe] hacking pass manager
  2016-06-30 11:41       ` Richard Biener
@ 2016-07-01 12:30         ` Prathamesh Kulkarni
  2016-07-06  7:51         ` Prasad Ghangal
  1 sibling, 0 replies; 29+ messages in thread
From: Prathamesh Kulkarni @ 2016-07-01 12:30 UTC (permalink / raw)
  To: Richard Biener; +Cc: Prasad Ghangal, David Malcolm, gcc Mailing List

On 30 June 2016 at 17:10, Richard Biener <richard.guenther@gmail.com> wrote:
> On Wed, Jun 29, 2016 at 9:13 PM, Prasad Ghangal
> <prasad.ghangal@gmail.com> wrote:
>> On 29 June 2016 at 22:15, Richard Biener <richard.guenther@gmail.com> wrote:
>>> On June 29, 2016 6:20:29 PM GMT+02:00, Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org> wrote:
>>>>On 18 June 2016 at 12:02, Prasad Ghangal <prasad.ghangal@gmail.com>
>>>>wrote:
>>>>> Hi,
>>>>>
>>>>> I tried hacking pass manager to execute only given passes. For this I
>>>>> am adding new member as opt_pass *custom_pass_list to the function
>>>>> structure to store passes need to execute and providing the
>>>>> custom_pass_list to execute_pass_list() function instead of all
>>>>passes
>>>>>
>>>>> for test case like-
>>>>>
>>>>> int a;
>>>>> void __GIMPLE (execute ("tree-ccp1", "tree-fre1")) foo()
>>>>> {
>>>>> bb_1:
>>>>>   a = 1 + a;
>>>>> }
>>>>>
>>>>> it will execute only given passes i.e. ccp1 and fre1 pass on the
>>>>function
>>>>>
>>>>> and for test case like -
>>>>>
>>>>> int a;
>>>>> void __GIMPLE (startwith ("tree-ccp1")) foo()
>>>>> {
>>>>> bb_1:
>>>>>   a = 1 + a;
>>>>> }
>>>>>
>>>>> it will act as a entry point to the pipeline and will execute passes
>>>>> starting from given pass.
>>>>Bike-shedding:
>>>>Would it make sense to have syntax for defining pass ranges to execute
>>>>?
>>>>for instance:
>>>>void __GIMPLE(execute (pass_start : pass_end))
>>>>which would execute all the passes within range [pass_start, pass_end],
>>>>which would be convenient if the range is large.
>>>
>>> But it would rely on a particular pass pipeline, f.e. pass-start appearing before pass-end.
>>>
>>> Currently control doesn't work 100% as it only replaces all_optimizations but not lowering passes or early opts, nor IPA opts.
>>>
>>
>> Each pass needs GIMPLE in some specific form. So I am letting lowering
>> and early opt passes to execute. I think we have to execute some
>> passes (like cfg) anyway to represent GIMPLE into proper form
>
> Yes, that's true.  Note that early opt passes only optimize but we need
> pass_build_ssa_passes at least (for into-SSA).  For proper unit-testing
> of GIMPLE passes we do need to guard off early opts somehow
> (I guess a simple if (flag_gimple && cfun->custom_pass_list) would do
> that).
>
> Then there is of course the question about IPA passes which I think is
> somewhat harder (one could always disable all IPA passes manually
> via flags of course or finally have a global -fipa/no-ipa like most
> other compilers).
For ordering of ipa passes, we could perhaps pass them via command line:
sth like -fipa-opts-order=cp,icf
which will only run ipa-cp and ipa-icf, but it admittedly looks quite ugly :/

Alternatively a more general approach would be to define pass ordering
in separate file (which could perhaps take the format of passes.def)
and that could be passed to the the compiler via command-line, say
-fpass-list=<file>
and then the compiler would parse the file and set up the pass lists
accordingly.
Not sure if this is a good solution either.

Thanks,
Prathamesh
>
> Richard.
>
>>> Richard.
>>>
>>>>Thanks,
>>>>Prathamesh
>>>>>
>>>>>
>>>>>
>>>>> Thanks,
>>>>> Prasad Ghangal
>>>
>>>

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [gimplefe] hacking pass manager
  2016-06-30 11:41       ` Richard Biener
  2016-07-01 12:30         ` Prathamesh Kulkarni
@ 2016-07-06  7:51         ` Prasad Ghangal
  2016-07-06  8:55           ` Richard Biener
  1 sibling, 1 reply; 29+ messages in thread
From: Prasad Ghangal @ 2016-07-06  7:51 UTC (permalink / raw)
  To: Richard Biener; +Cc: Prathamesh Kulkarni, David Malcolm, gcc Mailing List

On 30 June 2016 at 17:10, Richard Biener <richard.guenther@gmail.com> wrote:
> On Wed, Jun 29, 2016 at 9:13 PM, Prasad Ghangal
> <prasad.ghangal@gmail.com> wrote:
>> On 29 June 2016 at 22:15, Richard Biener <richard.guenther@gmail.com> wrote:
>>> On June 29, 2016 6:20:29 PM GMT+02:00, Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org> wrote:
>>>>On 18 June 2016 at 12:02, Prasad Ghangal <prasad.ghangal@gmail.com>
>>>>wrote:
>>>>> Hi,
>>>>>
>>>>> I tried hacking pass manager to execute only given passes. For this I
>>>>> am adding new member as opt_pass *custom_pass_list to the function
>>>>> structure to store passes need to execute and providing the
>>>>> custom_pass_list to execute_pass_list() function instead of all
>>>>passes
>>>>>
>>>>> for test case like-
>>>>>
>>>>> int a;
>>>>> void __GIMPLE (execute ("tree-ccp1", "tree-fre1")) foo()
>>>>> {
>>>>> bb_1:
>>>>>   a = 1 + a;
>>>>> }
>>>>>
>>>>> it will execute only given passes i.e. ccp1 and fre1 pass on the
>>>>function
>>>>>
>>>>> and for test case like -
>>>>>
>>>>> int a;
>>>>> void __GIMPLE (startwith ("tree-ccp1")) foo()
>>>>> {
>>>>> bb_1:
>>>>>   a = 1 + a;
>>>>> }
>>>>>
>>>>> it will act as a entry point to the pipeline and will execute passes
>>>>> starting from given pass.
>>>>Bike-shedding:
>>>>Would it make sense to have syntax for defining pass ranges to execute
>>>>?
>>>>for instance:
>>>>void __GIMPLE(execute (pass_start : pass_end))
>>>>which would execute all the passes within range [pass_start, pass_end],
>>>>which would be convenient if the range is large.
>>>
>>> But it would rely on a particular pass pipeline, f.e. pass-start appearing before pass-end.
>>>
>>> Currently control doesn't work 100% as it only replaces all_optimizations but not lowering passes or early opts, nor IPA opts.
>>>
>>
>> Each pass needs GIMPLE in some specific form. So I am letting lowering
>> and early opt passes to execute. I think we have to execute some
>> passes (like cfg) anyway to represent GIMPLE into proper form
>
> Yes, that's true.  Note that early opt passes only optimize but we need
> pass_build_ssa_passes at least (for into-SSA).  For proper unit-testing
> of GIMPLE passes we do need to guard off early opts somehow
> (I guess a simple if (flag_gimple && cfun->custom_pass_list) would do
> that).
>
> Then there is of course the question about IPA passes which I think is
> somewhat harder (one could always disable all IPA passes manually
> via flags of course or finally have a global -fipa/no-ipa like most
> other compilers).
>
Can we iterate through all ipa passes and do -fdisable-ipa-pass or
-fenable-ipa-pass equivalent for each?

Thanks,
Prasad

> Richard.
>
>>> Richard.
>>>
>>>>Thanks,
>>>>Prathamesh
>>>>>
>>>>>
>>>>>
>>>>> Thanks,
>>>>> Prasad Ghangal
>>>
>>>

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [gimplefe] hacking pass manager
  2016-07-06  7:51         ` Prasad Ghangal
@ 2016-07-06  8:55           ` Richard Biener
  2016-07-07 19:45             ` Prasad Ghangal
  0 siblings, 1 reply; 29+ messages in thread
From: Richard Biener @ 2016-07-06  8:55 UTC (permalink / raw)
  To: Prasad Ghangal; +Cc: Prathamesh Kulkarni, David Malcolm, gcc Mailing List

On Wed, Jul 6, 2016 at 9:51 AM, Prasad Ghangal <prasad.ghangal@gmail.com> wrote:
> On 30 June 2016 at 17:10, Richard Biener <richard.guenther@gmail.com> wrote:
>> On Wed, Jun 29, 2016 at 9:13 PM, Prasad Ghangal
>> <prasad.ghangal@gmail.com> wrote:
>>> On 29 June 2016 at 22:15, Richard Biener <richard.guenther@gmail.com> wrote:
>>>> On June 29, 2016 6:20:29 PM GMT+02:00, Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org> wrote:
>>>>>On 18 June 2016 at 12:02, Prasad Ghangal <prasad.ghangal@gmail.com>
>>>>>wrote:
>>>>>> Hi,
>>>>>>
>>>>>> I tried hacking pass manager to execute only given passes. For this I
>>>>>> am adding new member as opt_pass *custom_pass_list to the function
>>>>>> structure to store passes need to execute and providing the
>>>>>> custom_pass_list to execute_pass_list() function instead of all
>>>>>passes
>>>>>>
>>>>>> for test case like-
>>>>>>
>>>>>> int a;
>>>>>> void __GIMPLE (execute ("tree-ccp1", "tree-fre1")) foo()
>>>>>> {
>>>>>> bb_1:
>>>>>>   a = 1 + a;
>>>>>> }
>>>>>>
>>>>>> it will execute only given passes i.e. ccp1 and fre1 pass on the
>>>>>function
>>>>>>
>>>>>> and for test case like -
>>>>>>
>>>>>> int a;
>>>>>> void __GIMPLE (startwith ("tree-ccp1")) foo()
>>>>>> {
>>>>>> bb_1:
>>>>>>   a = 1 + a;
>>>>>> }
>>>>>>
>>>>>> it will act as a entry point to the pipeline and will execute passes
>>>>>> starting from given pass.
>>>>>Bike-shedding:
>>>>>Would it make sense to have syntax for defining pass ranges to execute
>>>>>?
>>>>>for instance:
>>>>>void __GIMPLE(execute (pass_start : pass_end))
>>>>>which would execute all the passes within range [pass_start, pass_end],
>>>>>which would be convenient if the range is large.
>>>>
>>>> But it would rely on a particular pass pipeline, f.e. pass-start appearing before pass-end.
>>>>
>>>> Currently control doesn't work 100% as it only replaces all_optimizations but not lowering passes or early opts, nor IPA opts.
>>>>
>>>
>>> Each pass needs GIMPLE in some specific form. So I am letting lowering
>>> and early opt passes to execute. I think we have to execute some
>>> passes (like cfg) anyway to represent GIMPLE into proper form
>>
>> Yes, that's true.  Note that early opt passes only optimize but we need
>> pass_build_ssa_passes at least (for into-SSA).  For proper unit-testing
>> of GIMPLE passes we do need to guard off early opts somehow
>> (I guess a simple if (flag_gimple && cfun->custom_pass_list) would do
>> that).
>>
>> Then there is of course the question about IPA passes which I think is
>> somewhat harder (one could always disable all IPA passes manually
>> via flags of course or finally have a global -fipa/no-ipa like most
>> other compilers).
>>
> Can we iterate through all ipa passes and do -fdisable-ipa-pass or
> -fenable-ipa-pass equivalent for each?

We could do that, yes.  But let's postpone this issue.  I think that
startwith is going to be most useful and rather than constructing
a pass list for it "native" support for it in the pass manager is
likely to produce better results (add a 'startwith' member alongside
the pass list member and if it is set the pass manager skips all
passes that do not match 'startwith' and once it reaches it it clears
the field).

In the future I hope we can get away from a static pass list and more
towards rule-driven pass execution (we have all those PROP_* stuff
already but it isn't really used for example).  But well, that would be
a separate GSoC project ;)

IMHO startwith will provide everything needed for unit-testing.  We can
add a flag on whether further passes should be executed or not and
even a pass list like execute ("ccp1", "fre") can be implemented by
startwith ccp1 and then from there executing the rest of the passes in the
list and stopping at the end.

As said, unit-testing should exercise a single pass if we can control
its input.

Thanks,
Richard.

> Thanks,
> Prasad
>
>> Richard.
>>
>>>> Richard.
>>>>
>>>>>Thanks,
>>>>>Prathamesh
>>>>>>
>>>>>>
>>>>>>
>>>>>> Thanks,
>>>>>> Prasad Ghangal
>>>>
>>>>

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [gimplefe] hacking pass manager
  2016-07-06  8:55           ` Richard Biener
@ 2016-07-07 19:45             ` Prasad Ghangal
  2016-07-08  7:43               ` Richard Biener
  0 siblings, 1 reply; 29+ messages in thread
From: Prasad Ghangal @ 2016-07-07 19:45 UTC (permalink / raw)
  To: Richard Biener; +Cc: Prathamesh Kulkarni, David Malcolm, gcc Mailing List

[-- Attachment #1: Type: text/plain, Size: 4431 bytes --]

On 6 July 2016 at 14:24, Richard Biener <richard.guenther@gmail.com> wrote:
> On Wed, Jul 6, 2016 at 9:51 AM, Prasad Ghangal <prasad.ghangal@gmail.com> wrote:
>> On 30 June 2016 at 17:10, Richard Biener <richard.guenther@gmail.com> wrote:
>>> On Wed, Jun 29, 2016 at 9:13 PM, Prasad Ghangal
>>> <prasad.ghangal@gmail.com> wrote:
>>>> On 29 June 2016 at 22:15, Richard Biener <richard.guenther@gmail.com> wrote:
>>>>> On June 29, 2016 6:20:29 PM GMT+02:00, Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org> wrote:
>>>>>>On 18 June 2016 at 12:02, Prasad Ghangal <prasad.ghangal@gmail.com>
>>>>>>wrote:
>>>>>>> Hi,
>>>>>>>
>>>>>>> I tried hacking pass manager to execute only given passes. For this I
>>>>>>> am adding new member as opt_pass *custom_pass_list to the function
>>>>>>> structure to store passes need to execute and providing the
>>>>>>> custom_pass_list to execute_pass_list() function instead of all
>>>>>>passes
>>>>>>>
>>>>>>> for test case like-
>>>>>>>
>>>>>>> int a;
>>>>>>> void __GIMPLE (execute ("tree-ccp1", "tree-fre1")) foo()
>>>>>>> {
>>>>>>> bb_1:
>>>>>>>   a = 1 + a;
>>>>>>> }
>>>>>>>
>>>>>>> it will execute only given passes i.e. ccp1 and fre1 pass on the
>>>>>>function
>>>>>>>
>>>>>>> and for test case like -
>>>>>>>
>>>>>>> int a;
>>>>>>> void __GIMPLE (startwith ("tree-ccp1")) foo()
>>>>>>> {
>>>>>>> bb_1:
>>>>>>>   a = 1 + a;
>>>>>>> }
>>>>>>>
>>>>>>> it will act as a entry point to the pipeline and will execute passes
>>>>>>> starting from given pass.
>>>>>>Bike-shedding:
>>>>>>Would it make sense to have syntax for defining pass ranges to execute
>>>>>>?
>>>>>>for instance:
>>>>>>void __GIMPLE(execute (pass_start : pass_end))
>>>>>>which would execute all the passes within range [pass_start, pass_end],
>>>>>>which would be convenient if the range is large.
>>>>>
>>>>> But it would rely on a particular pass pipeline, f.e. pass-start appearing before pass-end.
>>>>>
>>>>> Currently control doesn't work 100% as it only replaces all_optimizations but not lowering passes or early opts, nor IPA opts.
>>>>>
>>>>
>>>> Each pass needs GIMPLE in some specific form. So I am letting lowering
>>>> and early opt passes to execute. I think we have to execute some
>>>> passes (like cfg) anyway to represent GIMPLE into proper form
>>>
>>> Yes, that's true.  Note that early opt passes only optimize but we need
>>> pass_build_ssa_passes at least (for into-SSA).  For proper unit-testing
>>> of GIMPLE passes we do need to guard off early opts somehow
>>> (I guess a simple if (flag_gimple && cfun->custom_pass_list) would do
>>> that).
>>>
>>> Then there is of course the question about IPA passes which I think is
>>> somewhat harder (one could always disable all IPA passes manually
>>> via flags of course or finally have a global -fipa/no-ipa like most
>>> other compilers).
>>>
>> Can we iterate through all ipa passes and do -fdisable-ipa-pass or
>> -fenable-ipa-pass equivalent for each?
>
> We could do that, yes.  But let's postpone this issue.  I think that
> startwith is going to be most useful and rather than constructing
> a pass list for it "native" support for it in the pass manager is
> likely to produce better results (add a 'startwith' member alongside
> the pass list member and if it is set the pass manager skips all
> passes that do not match 'startwith' and once it reaches it it clears
> the field).
>
> In the future I hope we can get away from a static pass list and more
> towards rule-driven pass execution (we have all those PROP_* stuff
> already but it isn't really used for example).  But well, that would be
> a separate GSoC project ;)
>
> IMHO startwith will provide everything needed for unit-testing.  We can
> add a flag on whether further passes should be executed or not and
> even a pass list like execute ("ccp1", "fre") can be implemented by
> startwith ccp1 and then from there executing the rest of the passes in the
> list and stopping at the end.
>
> As said, unit-testing should exercise a single pass if we can control
> its input.
>
In this patch I am skipping execution of passes until pass_startwith
is found. Unlike previous build, now pass manager executes all passes
in pipeline starting from pass_startwith instead of just sub passes.

> Thanks,
> Richard.
>
>> Thanks,
>> Prasad
>>
>>> Richard.
>>>
>>>>> Richard.
>>>>>
>>>>>>Thanks,
>>>>>>Prathamesh
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> Thanks,
>>>>>>> Prasad Ghangal
>>>>>
>>>>>

[-- Attachment #2: pass_man.diff --]
[-- Type: text/plain, Size: 6970 bytes --]

diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index 00e0bc5..d7ffdce 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -1413,7 +1413,7 @@ static c_expr c_parser_gimple_unary_expression (c_parser *);
 static struct c_expr c_parser_gimple_postfix_expression (c_parser *);
 static struct c_expr c_parser_gimple_postfix_expression_after_primary (c_parser *,
 								       struct c_expr);
-static void c_parser_gimple_pass_list (c_parser *, opt_pass **);
+static void c_parser_gimple_pass_list (c_parser *, opt_pass **, bool *);
 static opt_pass *c_parser_gimple_pass_list_params (c_parser *, opt_pass **);
 static void c_parser_gimple_declaration (c_parser *);
 static void c_parser_gimple_goto_stmt (location_t, tree, gimple_seq *);
@@ -1666,6 +1666,7 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
   location_t here = c_parser_peek_token (parser)->location;
   bool gimple_body_p = false;
   opt_pass *pass = NULL;
+  bool startwith_p;
 
   if (static_assert_ok
       && c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
@@ -1722,8 +1723,9 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
       if (kw_token->keyword == RID_GIMPLE)
 	{
 	  gimple_body_p = true;
+	  startwith_p = false;
 	  c_parser_consume_token (parser);
-	  c_parser_gimple_pass_list (parser, &pass);
+	  c_parser_gimple_pass_list (parser, &pass, &startwith_p);
 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 
 				     "expected %<)%>");
 	}
@@ -2137,7 +2139,10 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
       store_parm_decls ();
 
       if (pass)
-	cfun->custom_pass_list = pass;
+	{
+	  cfun->pass_startwith = pass;
+	  cfun->startwith = startwith_p;
+	}
 
       if (omp_declare_simd_clauses.exists ()
 	  || !vec_safe_is_empty (parser->cilk_simd_fn_tokens))
@@ -18797,9 +18802,8 @@ c_parser_gimple_label (c_parser *parser, gimple_seq *seq)
 /* Parse gimple pass list */
 
 static void 
-c_parser_gimple_pass_list (c_parser *parser, opt_pass **pass)
+c_parser_gimple_pass_list (c_parser *parser, opt_pass **pass, bool *startwith_p)
 {
-  opt_pass *pass_start;
   if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
     {
       return;
@@ -18814,17 +18818,11 @@ c_parser_gimple_pass_list (c_parser *parser, opt_pass **pass)
     {
       const char *op = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
       c_parser_consume_token (parser);
-      if (!strcmp (op, "execute"))
-	{
-	  pass_start = c_parser_gimple_pass_list_params (parser, pass);
-	  if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
-	    return;
-	  (*pass)->next = NULL;
-	  *pass = pass_start;
-	}
-      else if (!strcmp (op, "startwith"))
+      if (!strcmp (op, "startwith"))
 	{
 	  *pass = c_parser_gimple_pass_list_params (parser, pass);
+	  (*pass)->next = NULL;
+	  *startwith_p = true;
 	  if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
 	    return;
 	}
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 7effd71..2bb112e 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -1980,10 +1980,7 @@ cgraph_node::expand (void)
   /* Signal the start of passes.  */
   invoke_plugin_callbacks (PLUGIN_ALL_PASSES_START, NULL);
 
-  if (flag_gimple && cfun->custom_pass_list)
-    execute_pass_list (cfun, cfun->custom_pass_list);
-  else
-    execute_pass_list (cfun, g->get_passes ()->all_passes);
+  execute_pass_list (cfun, g->get_passes ()->all_passes, true);
 
   /* Signal the end of passes.  */
   invoke_plugin_callbacks (PLUGIN_ALL_PASSES_END, NULL);
@@ -2037,7 +2034,7 @@ cgraph_node::expand (void)
 
   /* Make sure that BE didn't give up on compiling.  */
 
-  if (!(flag_gimple && cfun->custom_pass_list))	/* FIXME : for gimplefe custom_pass_list */
+  if (!(flag_gimple && cfun->pass_startwith))	/* FIXME : for gimplefe custom_pass_list */
     gcc_assert (TREE_ASM_WRITTEN (decl));
   
   if (cfun)
diff --git a/gcc/function.h b/gcc/function.h
index f84b97b..0adbd68 100644
--- a/gcc/function.h
+++ b/gcc/function.h
@@ -228,8 +228,11 @@ struct GTY(()) function {
   /* GIMPLE body for this function.  */
   gimple_seq gimple_body;
 
-  /* GIMPLEFE Passes */
-  opt_pass *custom_pass_list = NULL;
+  /* GIMPLEFE pass to start with */
+  opt_pass *pass_startwith = NULL;
+
+  /* Startwith flag */
+  bool startwith;
 
   /* SSA and dataflow information.  */
   struct gimple_df *gimple_df;
diff --git a/gcc/passes.c b/gcc/passes.c
index c84b4b1..c4588bb 100644
--- a/gcc/passes.c
+++ b/gcc/passes.c
@@ -114,7 +114,7 @@ pass_manager::execute_early_local_passes ()
   execute_pass_list (cfun, pass_build_ssa_passes_1->sub);
   if (flag_check_pointer_bounds)
     execute_pass_list (cfun, pass_chkp_instrumentation_passes_1->sub);
-  if (flag_gimple && cfun->custom_pass_list)
+  if (!flag_gimple && !cfun->pass_startwith)
     execute_pass_list (cfun, pass_local_optimization_passes_1->sub);
 }
 
@@ -2281,8 +2281,18 @@ override_gate_status (opt_pass *pass, tree func, bool gate_status)
 /* Execute PASS. */
 
 bool
-execute_one_pass (opt_pass *pass)
+execute_one_pass (opt_pass *pass, bool startwith_p)
 {
+  /* For skipping passes until startwith pass */
+  if (startwith_p && cfun->startwith)
+    {
+      if (pass->name == cfun->pass_startwith->name
+	  || pass->name == "*clean_state")
+	cfun->startwith = false;
+      else
+	return true;
+    }
+
   unsigned int todo_after = 0;
 
   bool gate_status;
@@ -2419,7 +2429,7 @@ execute_one_pass (opt_pass *pass)
 }
 
 static void
-execute_pass_list_1 (opt_pass *pass)
+execute_pass_list_1 (opt_pass *pass, bool startwith_p)
 {
   do
     {
@@ -2428,18 +2438,18 @@ execute_pass_list_1 (opt_pass *pass)
 
       if (cfun == NULL)
 	return;
-      if (execute_one_pass (pass) && pass->sub)
-        execute_pass_list_1 (pass->sub);
+      if (execute_one_pass (pass, startwith_p) && pass->sub)
+	execute_pass_list_1 (pass->sub, startwith_p);
       pass = pass->next;
     }
   while (pass);
 }
 
 void
-execute_pass_list (function *fn, opt_pass *pass)
+execute_pass_list (function *fn, opt_pass *pass, bool startwith_p)
 {
   gcc_assert (fn == cfun);
-  execute_pass_list_1 (pass);
+  execute_pass_list_1 (pass, startwith_p);
   if (cfun && fn->cfg)
     {
       free_dominance_info (CDI_DOMINATORS);
diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h
index 36299a6..1c68485 100644
--- a/gcc/tree-pass.h
+++ b/gcc/tree-pass.h
@@ -615,8 +615,8 @@ extern gimple_opt_pass *make_pass_lower_vaarg (gcc::context *ctxt);
 /* Current optimization pass.  */
 extern opt_pass *current_pass;
 
-extern bool execute_one_pass (opt_pass *);
-extern void execute_pass_list (function *, opt_pass *);
+extern bool execute_one_pass (opt_pass *, bool startwith_p = false);
+extern void execute_pass_list (function *, opt_pass *, bool startwith_p	= false);
 extern void execute_ipa_pass_list (opt_pass *);
 extern void execute_ipa_summary_passes (ipa_opt_pass_d *);
 extern void execute_all_ipa_transforms (void);

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [gimplefe] hacking pass manager
  2016-07-07 19:45             ` Prasad Ghangal
@ 2016-07-08  7:43               ` Richard Biener
  2016-07-10 16:13                 ` Prasad Ghangal
  0 siblings, 1 reply; 29+ messages in thread
From: Richard Biener @ 2016-07-08  7:43 UTC (permalink / raw)
  To: Prasad Ghangal; +Cc: Prathamesh Kulkarni, David Malcolm, gcc Mailing List

On Thu, Jul 7, 2016 at 9:45 PM, Prasad Ghangal <prasad.ghangal@gmail.com> wrote:
> On 6 July 2016 at 14:24, Richard Biener <richard.guenther@gmail.com> wrote:
>> On Wed, Jul 6, 2016 at 9:51 AM, Prasad Ghangal <prasad.ghangal@gmail.com> wrote:
>>> On 30 June 2016 at 17:10, Richard Biener <richard.guenther@gmail.com> wrote:
>>>> On Wed, Jun 29, 2016 at 9:13 PM, Prasad Ghangal
>>>> <prasad.ghangal@gmail.com> wrote:
>>>>> On 29 June 2016 at 22:15, Richard Biener <richard.guenther@gmail.com> wrote:
>>>>>> On June 29, 2016 6:20:29 PM GMT+02:00, Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org> wrote:
>>>>>>>On 18 June 2016 at 12:02, Prasad Ghangal <prasad.ghangal@gmail.com>
>>>>>>>wrote:
>>>>>>>> Hi,
>>>>>>>>
>>>>>>>> I tried hacking pass manager to execute only given passes. For this I
>>>>>>>> am adding new member as opt_pass *custom_pass_list to the function
>>>>>>>> structure to store passes need to execute and providing the
>>>>>>>> custom_pass_list to execute_pass_list() function instead of all
>>>>>>>passes
>>>>>>>>
>>>>>>>> for test case like-
>>>>>>>>
>>>>>>>> int a;
>>>>>>>> void __GIMPLE (execute ("tree-ccp1", "tree-fre1")) foo()
>>>>>>>> {
>>>>>>>> bb_1:
>>>>>>>>   a = 1 + a;
>>>>>>>> }
>>>>>>>>
>>>>>>>> it will execute only given passes i.e. ccp1 and fre1 pass on the
>>>>>>>function
>>>>>>>>
>>>>>>>> and for test case like -
>>>>>>>>
>>>>>>>> int a;
>>>>>>>> void __GIMPLE (startwith ("tree-ccp1")) foo()
>>>>>>>> {
>>>>>>>> bb_1:
>>>>>>>>   a = 1 + a;
>>>>>>>> }
>>>>>>>>
>>>>>>>> it will act as a entry point to the pipeline and will execute passes
>>>>>>>> starting from given pass.
>>>>>>>Bike-shedding:
>>>>>>>Would it make sense to have syntax for defining pass ranges to execute
>>>>>>>?
>>>>>>>for instance:
>>>>>>>void __GIMPLE(execute (pass_start : pass_end))
>>>>>>>which would execute all the passes within range [pass_start, pass_end],
>>>>>>>which would be convenient if the range is large.
>>>>>>
>>>>>> But it would rely on a particular pass pipeline, f.e. pass-start appearing before pass-end.
>>>>>>
>>>>>> Currently control doesn't work 100% as it only replaces all_optimizations but not lowering passes or early opts, nor IPA opts.
>>>>>>
>>>>>
>>>>> Each pass needs GIMPLE in some specific form. So I am letting lowering
>>>>> and early opt passes to execute. I think we have to execute some
>>>>> passes (like cfg) anyway to represent GIMPLE into proper form
>>>>
>>>> Yes, that's true.  Note that early opt passes only optimize but we need
>>>> pass_build_ssa_passes at least (for into-SSA).  For proper unit-testing
>>>> of GIMPLE passes we do need to guard off early opts somehow
>>>> (I guess a simple if (flag_gimple && cfun->custom_pass_list) would do
>>>> that).
>>>>
>>>> Then there is of course the question about IPA passes which I think is
>>>> somewhat harder (one could always disable all IPA passes manually
>>>> via flags of course or finally have a global -fipa/no-ipa like most
>>>> other compilers).
>>>>
>>> Can we iterate through all ipa passes and do -fdisable-ipa-pass or
>>> -fenable-ipa-pass equivalent for each?
>>
>> We could do that, yes.  But let's postpone this issue.  I think that
>> startwith is going to be most useful and rather than constructing
>> a pass list for it "native" support for it in the pass manager is
>> likely to produce better results (add a 'startwith' member alongside
>> the pass list member and if it is set the pass manager skips all
>> passes that do not match 'startwith' and once it reaches it it clears
>> the field).
>>
>> In the future I hope we can get away from a static pass list and more
>> towards rule-driven pass execution (we have all those PROP_* stuff
>> already but it isn't really used for example).  But well, that would be
>> a separate GSoC project ;)
>>
>> IMHO startwith will provide everything needed for unit-testing.  We can
>> add a flag on whether further passes should be executed or not and
>> even a pass list like execute ("ccp1", "fre") can be implemented by
>> startwith ccp1 and then from there executing the rest of the passes in the
>> list and stopping at the end.
>>
>> As said, unit-testing should exercise a single pass if we can control
>> its input.
>>
> In this patch I am skipping execution of passes until pass_startwith
> is found. Unlike previous build, now pass manager executes all passes
> in pipeline starting from pass_startwith instead of just sub passes.

That looks good.  I wonder if

+  if (startwith_p && cfun->startwith)
+    {
+      if (pass->name == cfun->pass_startwith->name
+         || pass->name == "*clean_state")

need better be strcmp ()s though.  Also the early optimization pipeline
should be executed with startwith support as well.

Richard.

>> Thanks,
>> Richard.
>>
>>> Thanks,
>>> Prasad
>>>
>>>> Richard.
>>>>
>>>>>> Richard.
>>>>>>
>>>>>>>Thanks,
>>>>>>>Prathamesh
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> Thanks,
>>>>>>>> Prasad Ghangal
>>>>>>
>>>>>>

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [gimplefe] hacking pass manager
  2016-07-08  7:43               ` Richard Biener
@ 2016-07-10 16:13                 ` Prasad Ghangal
  2016-07-15 10:43                   ` Richard Biener
  0 siblings, 1 reply; 29+ messages in thread
From: Prasad Ghangal @ 2016-07-10 16:13 UTC (permalink / raw)
  To: Richard Biener; +Cc: Prathamesh Kulkarni, David Malcolm, gcc Mailing List

[-- Attachment #1: Type: text/plain, Size: 5434 bytes --]

On 8 July 2016 at 13:13, Richard Biener <richard.guenther@gmail.com> wrote:
> On Thu, Jul 7, 2016 at 9:45 PM, Prasad Ghangal <prasad.ghangal@gmail.com> wrote:
>> On 6 July 2016 at 14:24, Richard Biener <richard.guenther@gmail.com> wrote:
>>> On Wed, Jul 6, 2016 at 9:51 AM, Prasad Ghangal <prasad.ghangal@gmail.com> wrote:
>>>> On 30 June 2016 at 17:10, Richard Biener <richard.guenther@gmail.com> wrote:
>>>>> On Wed, Jun 29, 2016 at 9:13 PM, Prasad Ghangal
>>>>> <prasad.ghangal@gmail.com> wrote:
>>>>>> On 29 June 2016 at 22:15, Richard Biener <richard.guenther@gmail.com> wrote:
>>>>>>> On June 29, 2016 6:20:29 PM GMT+02:00, Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org> wrote:
>>>>>>>>On 18 June 2016 at 12:02, Prasad Ghangal <prasad.ghangal@gmail.com>
>>>>>>>>wrote:
>>>>>>>>> Hi,
>>>>>>>>>
>>>>>>>>> I tried hacking pass manager to execute only given passes. For this I
>>>>>>>>> am adding new member as opt_pass *custom_pass_list to the function
>>>>>>>>> structure to store passes need to execute and providing the
>>>>>>>>> custom_pass_list to execute_pass_list() function instead of all
>>>>>>>>passes
>>>>>>>>>
>>>>>>>>> for test case like-
>>>>>>>>>
>>>>>>>>> int a;
>>>>>>>>> void __GIMPLE (execute ("tree-ccp1", "tree-fre1")) foo()
>>>>>>>>> {
>>>>>>>>> bb_1:
>>>>>>>>>   a = 1 + a;
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>> it will execute only given passes i.e. ccp1 and fre1 pass on the
>>>>>>>>function
>>>>>>>>>
>>>>>>>>> and for test case like -
>>>>>>>>>
>>>>>>>>> int a;
>>>>>>>>> void __GIMPLE (startwith ("tree-ccp1")) foo()
>>>>>>>>> {
>>>>>>>>> bb_1:
>>>>>>>>>   a = 1 + a;
>>>>>>>>> }
>>>>>>>>>
>>>>>>>>> it will act as a entry point to the pipeline and will execute passes
>>>>>>>>> starting from given pass.
>>>>>>>>Bike-shedding:
>>>>>>>>Would it make sense to have syntax for defining pass ranges to execute
>>>>>>>>?
>>>>>>>>for instance:
>>>>>>>>void __GIMPLE(execute (pass_start : pass_end))
>>>>>>>>which would execute all the passes within range [pass_start, pass_end],
>>>>>>>>which would be convenient if the range is large.
>>>>>>>
>>>>>>> But it would rely on a particular pass pipeline, f.e. pass-start appearing before pass-end.
>>>>>>>
>>>>>>> Currently control doesn't work 100% as it only replaces all_optimizations but not lowering passes or early opts, nor IPA opts.
>>>>>>>
>>>>>>
>>>>>> Each pass needs GIMPLE in some specific form. So I am letting lowering
>>>>>> and early opt passes to execute. I think we have to execute some
>>>>>> passes (like cfg) anyway to represent GIMPLE into proper form
>>>>>
>>>>> Yes, that's true.  Note that early opt passes only optimize but we need
>>>>> pass_build_ssa_passes at least (for into-SSA).  For proper unit-testing
>>>>> of GIMPLE passes we do need to guard off early opts somehow
>>>>> (I guess a simple if (flag_gimple && cfun->custom_pass_list) would do
>>>>> that).
>>>>>
>>>>> Then there is of course the question about IPA passes which I think is
>>>>> somewhat harder (one could always disable all IPA passes manually
>>>>> via flags of course or finally have a global -fipa/no-ipa like most
>>>>> other compilers).
>>>>>
>>>> Can we iterate through all ipa passes and do -fdisable-ipa-pass or
>>>> -fenable-ipa-pass equivalent for each?
>>>
>>> We could do that, yes.  But let's postpone this issue.  I think that
>>> startwith is going to be most useful and rather than constructing
>>> a pass list for it "native" support for it in the pass manager is
>>> likely to produce better results (add a 'startwith' member alongside
>>> the pass list member and if it is set the pass manager skips all
>>> passes that do not match 'startwith' and once it reaches it it clears
>>> the field).
>>>
>>> In the future I hope we can get away from a static pass list and more
>>> towards rule-driven pass execution (we have all those PROP_* stuff
>>> already but it isn't really used for example).  But well, that would be
>>> a separate GSoC project ;)
>>>
>>> IMHO startwith will provide everything needed for unit-testing.  We can
>>> add a flag on whether further passes should be executed or not and
>>> even a pass list like execute ("ccp1", "fre") can be implemented by
>>> startwith ccp1 and then from there executing the rest of the passes in the
>>> list and stopping at the end.
>>>
>>> As said, unit-testing should exercise a single pass if we can control
>>> its input.
>>>
>> In this patch I am skipping execution of passes until pass_startwith
>> is found. Unlike previous build, now pass manager executes all passes
>> in pipeline starting from pass_startwith instead of just sub passes.
>
> That looks good.  I wonder if
>
> +  if (startwith_p && cfun->startwith)
> +    {
> +      if (pass->name == cfun->pass_startwith->name
> +         || pass->name == "*clean_state")
>
> need better be strcmp ()s though.  Also the early optimization pipeline
> should be executed with startwith support as well.
>

This patch adds startwith support for early opt passes. But for
starting from some passes (like asan0, optimized) in all_passes
pipeline, it falils at verify_curr_properties in execute_one_pass ().
I wonder if we need to update properties after skipping each pass

Thanks,
Prasad

> Richard.
>
>>> Thanks,
>>> Richard.
>>>
>>>> Thanks,
>>>> Prasad
>>>>
>>>>> Richard.
>>>>>
>>>>>>> Richard.
>>>>>>>
>>>>>>>>Thanks,
>>>>>>>>Prathamesh
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Thanks,
>>>>>>>>> Prasad Ghangal
>>>>>>>
>>>>>>>

[-- Attachment #2: pass_man.diff --]
[-- Type: text/plain, Size: 5482 bytes --]

diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index d7ffdce..1a55b9a 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -18821,7 +18821,8 @@ c_parser_gimple_pass_list (c_parser *parser, opt_pass **pass, bool *startwith_p)
       if (!strcmp (op, "startwith"))
 	{
 	  *pass = c_parser_gimple_pass_list_params (parser, pass);
-	  (*pass)->next = NULL;
+	  if (!(*pass))
+	    return;
 	  *startwith_p = true;
 	  if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
 	    return;
@@ -18874,6 +18875,7 @@ c_parser_gimple_pass_list_params (c_parser *parser, opt_pass **pass)
 	  if (!new_pass)
 	    {
 	      error_at (c_parser_peek_token (parser)->location, "invalid pass name");
+	      parser->error = true;
 	      c_parser_consume_token (parser);
 	      return NULL;
 	    }
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 2bb112e..1df4950 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -1942,6 +1942,7 @@ cgraph_node::assemble_thunks_and_aliases (void)
 void
 cgraph_node::expand (void)
 {
+  bool startwith_p = true;
   location_t saved_loc;
 
   /* We ought to not compile any inline clones.  */
@@ -1980,7 +1981,7 @@ cgraph_node::expand (void)
   /* Signal the start of passes.  */
   invoke_plugin_callbacks (PLUGIN_ALL_PASSES_START, NULL);
 
-  execute_pass_list (cfun, g->get_passes ()->all_passes, true);
+  execute_pass_list (cfun, g->get_passes ()->all_passes, &startwith_p);
 
   /* Signal the end of passes.  */
   invoke_plugin_callbacks (PLUGIN_ALL_PASSES_END, NULL);
diff --git a/gcc/passes.c b/gcc/passes.c
index c4588bb..c7c7191 100644
--- a/gcc/passes.c
+++ b/gcc/passes.c
@@ -114,8 +114,7 @@ pass_manager::execute_early_local_passes ()
   execute_pass_list (cfun, pass_build_ssa_passes_1->sub);
   if (flag_check_pointer_bounds)
     execute_pass_list (cfun, pass_chkp_instrumentation_passes_1->sub);
-  if (!flag_gimple && !cfun->pass_startwith)
-    execute_pass_list (cfun, pass_local_optimization_passes_1->sub);
+  execute_pass_list (cfun, pass_local_optimization_passes_1->sub);
 }
 
 unsigned int
@@ -1686,12 +1685,13 @@ remove_cgraph_node_from_order (cgraph_node *node, void *data)
    call CALLBACK on the current function.
    This function is global so that plugins can use it.  */
 void
-do_per_function_toporder (void (*callback) (function *, void *data), void *data)
+do_per_function_toporder (void (*callback) (function *, void *data, void *flag), 
+			  void *data, void *flag)
 {
   int i;
 
   if (current_function_decl)
-    callback (cfun, data);
+    callback (cfun, data, flag);
   else
     {
       cgraph_node_hook_list *hook;
@@ -1726,7 +1726,7 @@ do_per_function_toporder (void (*callback) (function *, void *data), void *data)
 	    {
 	      struct function *fn = DECL_STRUCT_FUNCTION (node->decl);
 	      push_cfun (fn);
-	      callback (fn, data);
+	      callback (fn, data, flag);
 	      pop_cfun ();
 	    }
 	}
@@ -2284,10 +2284,10 @@ bool
 execute_one_pass (opt_pass *pass, bool startwith_p)
 {
   /* For skipping passes until startwith pass */
-  if (startwith_p && cfun->startwith)
+  if (cfun && startwith_p && cfun->startwith)
     {
-      if (pass->name == cfun->pass_startwith->name
-	  || pass->name == "*clean_state")
+      if (!strcmp (pass->name, cfun->pass_startwith->name)
+	  || !strcmp (pass->name, "*clean_state"))
 	cfun->startwith = false;
       else
 	return true;
@@ -2446,10 +2446,15 @@ execute_pass_list_1 (opt_pass *pass, bool startwith_p)
 }
 
 void
-execute_pass_list (function *fn, opt_pass *pass, bool startwith_p)
+execute_pass_list (function *fn, opt_pass *pass, bool *startwith_p)
 {
   gcc_assert (fn == cfun);
-  execute_pass_list_1 (pass, startwith_p);
+
+  if (startwith_p)
+    execute_pass_list_1 (pass, *startwith_p);
+  else
+    execute_pass_list_1 (pass, false);
+
   if (cfun && fn->cfg)
     {
       free_dominance_info (CDI_DOMINATORS);
@@ -2779,19 +2784,22 @@ ipa_read_optimization_summaries (void)
 void
 execute_ipa_pass_list (opt_pass *pass)
 {
+  bool startwith_p = false;
   do
     {
       gcc_assert (!current_function_decl);
       gcc_assert (!cfun);
       gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS);
-      if (execute_one_pass (pass) && pass->sub)
+      if (!strcmp (pass->name, "opt_local_passes"))
+	startwith_p = true;
+      if (execute_one_pass (pass, startwith_p) && pass->sub)
 	{
 	  if (pass->sub->type == GIMPLE_PASS)
 	    {
 	      invoke_plugin_callbacks (PLUGIN_EARLY_GIMPLE_PASSES_START, NULL);
-	      do_per_function_toporder ((void (*)(function *, void *))
+	      do_per_function_toporder ((void (*)(function *, void *, void *))
 					  execute_pass_list,
-					pass->sub);
+					pass->sub, &startwith_p);      
 	      invoke_plugin_callbacks (PLUGIN_EARLY_GIMPLE_PASSES_END, NULL);
 	    }
 	  else if (pass->sub->type == SIMPLE_IPA_PASS
diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h
index 1c68485..df97f45 100644
--- a/gcc/tree-pass.h
+++ b/gcc/tree-pass.h
@@ -616,7 +616,7 @@ extern gimple_opt_pass *make_pass_lower_vaarg (gcc::context *ctxt);
 extern opt_pass *current_pass;
 
 extern bool execute_one_pass (opt_pass *, bool startwith_p = false);
-extern void execute_pass_list (function *, opt_pass *, bool startwith_p	= false);
+extern void execute_pass_list (function *, opt_pass *, bool *startwith_p = NULL);
 extern void execute_ipa_pass_list (opt_pass *);
 extern void execute_ipa_summary_passes (ipa_opt_pass_d *);
 extern void execute_all_ipa_transforms (void);

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [gimplefe] hacking pass manager
  2016-07-10 16:13                 ` Prasad Ghangal
@ 2016-07-15 10:43                   ` Richard Biener
  2016-07-18 18:28                     ` Prasad Ghangal
  0 siblings, 1 reply; 29+ messages in thread
From: Richard Biener @ 2016-07-15 10:43 UTC (permalink / raw)
  To: Prasad Ghangal; +Cc: Prathamesh Kulkarni, David Malcolm, gcc Mailing List

On Sun, Jul 10, 2016 at 6:13 PM, Prasad Ghangal
<prasad.ghangal@gmail.com> wrote:
> On 8 July 2016 at 13:13, Richard Biener <richard.guenther@gmail.com> wrote:
>> On Thu, Jul 7, 2016 at 9:45 PM, Prasad Ghangal <prasad.ghangal@gmail.com> wrote:
>>> On 6 July 2016 at 14:24, Richard Biener <richard.guenther@gmail.com> wrote:
>>>> On Wed, Jul 6, 2016 at 9:51 AM, Prasad Ghangal <prasad.ghangal@gmail.com> wrote:
>>>>> On 30 June 2016 at 17:10, Richard Biener <richard.guenther@gmail.com> wrote:
>>>>>> On Wed, Jun 29, 2016 at 9:13 PM, Prasad Ghangal
>>>>>> <prasad.ghangal@gmail.com> wrote:
>>>>>>> On 29 June 2016 at 22:15, Richard Biener <richard.guenther@gmail.com> wrote:
>>>>>>>> On June 29, 2016 6:20:29 PM GMT+02:00, Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org> wrote:
>>>>>>>>>On 18 June 2016 at 12:02, Prasad Ghangal <prasad.ghangal@gmail.com>
>>>>>>>>>wrote:
>>>>>>>>>> Hi,
>>>>>>>>>>
>>>>>>>>>> I tried hacking pass manager to execute only given passes. For this I
>>>>>>>>>> am adding new member as opt_pass *custom_pass_list to the function
>>>>>>>>>> structure to store passes need to execute and providing the
>>>>>>>>>> custom_pass_list to execute_pass_list() function instead of all
>>>>>>>>>passes
>>>>>>>>>>
>>>>>>>>>> for test case like-
>>>>>>>>>>
>>>>>>>>>> int a;
>>>>>>>>>> void __GIMPLE (execute ("tree-ccp1", "tree-fre1")) foo()
>>>>>>>>>> {
>>>>>>>>>> bb_1:
>>>>>>>>>>   a = 1 + a;
>>>>>>>>>> }
>>>>>>>>>>
>>>>>>>>>> it will execute only given passes i.e. ccp1 and fre1 pass on the
>>>>>>>>>function
>>>>>>>>>>
>>>>>>>>>> and for test case like -
>>>>>>>>>>
>>>>>>>>>> int a;
>>>>>>>>>> void __GIMPLE (startwith ("tree-ccp1")) foo()
>>>>>>>>>> {
>>>>>>>>>> bb_1:
>>>>>>>>>>   a = 1 + a;
>>>>>>>>>> }
>>>>>>>>>>
>>>>>>>>>> it will act as a entry point to the pipeline and will execute passes
>>>>>>>>>> starting from given pass.
>>>>>>>>>Bike-shedding:
>>>>>>>>>Would it make sense to have syntax for defining pass ranges to execute
>>>>>>>>>?
>>>>>>>>>for instance:
>>>>>>>>>void __GIMPLE(execute (pass_start : pass_end))
>>>>>>>>>which would execute all the passes within range [pass_start, pass_end],
>>>>>>>>>which would be convenient if the range is large.
>>>>>>>>
>>>>>>>> But it would rely on a particular pass pipeline, f.e. pass-start appearing before pass-end.
>>>>>>>>
>>>>>>>> Currently control doesn't work 100% as it only replaces all_optimizations but not lowering passes or early opts, nor IPA opts.
>>>>>>>>
>>>>>>>
>>>>>>> Each pass needs GIMPLE in some specific form. So I am letting lowering
>>>>>>> and early opt passes to execute. I think we have to execute some
>>>>>>> passes (like cfg) anyway to represent GIMPLE into proper form
>>>>>>
>>>>>> Yes, that's true.  Note that early opt passes only optimize but we need
>>>>>> pass_build_ssa_passes at least (for into-SSA).  For proper unit-testing
>>>>>> of GIMPLE passes we do need to guard off early opts somehow
>>>>>> (I guess a simple if (flag_gimple && cfun->custom_pass_list) would do
>>>>>> that).
>>>>>>
>>>>>> Then there is of course the question about IPA passes which I think is
>>>>>> somewhat harder (one could always disable all IPA passes manually
>>>>>> via flags of course or finally have a global -fipa/no-ipa like most
>>>>>> other compilers).
>>>>>>
>>>>> Can we iterate through all ipa passes and do -fdisable-ipa-pass or
>>>>> -fenable-ipa-pass equivalent for each?
>>>>
>>>> We could do that, yes.  But let's postpone this issue.  I think that
>>>> startwith is going to be most useful and rather than constructing
>>>> a pass list for it "native" support for it in the pass manager is
>>>> likely to produce better results (add a 'startwith' member alongside
>>>> the pass list member and if it is set the pass manager skips all
>>>> passes that do not match 'startwith' and once it reaches it it clears
>>>> the field).
>>>>
>>>> In the future I hope we can get away from a static pass list and more
>>>> towards rule-driven pass execution (we have all those PROP_* stuff
>>>> already but it isn't really used for example).  But well, that would be
>>>> a separate GSoC project ;)
>>>>
>>>> IMHO startwith will provide everything needed for unit-testing.  We can
>>>> add a flag on whether further passes should be executed or not and
>>>> even a pass list like execute ("ccp1", "fre") can be implemented by
>>>> startwith ccp1 and then from there executing the rest of the passes in the
>>>> list and stopping at the end.
>>>>
>>>> As said, unit-testing should exercise a single pass if we can control
>>>> its input.
>>>>
>>> In this patch I am skipping execution of passes until pass_startwith
>>> is found. Unlike previous build, now pass manager executes all passes
>>> in pipeline starting from pass_startwith instead of just sub passes.
>>
>> That looks good.  I wonder if
>>
>> +  if (startwith_p && cfun->startwith)
>> +    {
>> +      if (pass->name == cfun->pass_startwith->name
>> +         || pass->name == "*clean_state")
>>
>> need better be strcmp ()s though.  Also the early optimization pipeline
>> should be executed with startwith support as well.
>>
>
> This patch adds startwith support for early opt passes. But for
> starting from some passes (like asan0, optimized) in all_passes
> pipeline, it falils at verify_curr_properties in execute_one_pass ().
> I wonder if we need to update properties after skipping each pass

Yeah, it's not possible to start at arbitrary points with skipping passes
that provide a required property.  I suspect it's good enough that we'll
ICE if that happens.

I see you are working on the dump-file side a bit now.  What is still
missing after you got support for PHIs is parsing of SSA names.
Without this unit-testing will be difficult at best.

I think what we need to do is simplify the job of the parser and
make the syntax we use to print SSA names a bit different.
So rather than printing VAR_VERSION we need to choose a
letter that is not part of a valid identifier before VERSION,
like a dot '.'.  Thus we'd have i.1 instead of i_1 and we'd have
.2 instead of _2 for an anonymous SSA name.  The advantage
for non-anonymous names is that we can properly re-use the
C frontends decl handling for declaring and looking up 'i'.
The disadvantage is that for anonymous SSA names this isn't
so easy which means we could choose to not support those
for the moment and require fake decls for them.  In fact
into-SSA will do the correct thing if we just treat them as decls,
thus continue to dump them as _VERSION.

Another issue would be to preserve SSA name VERSIONS
(the decl idea for anon ones doesn't work) or basic-block
numbering/ordering (requires direct CFG construction).  Both
are out-of-scope for the GSoC project I think.

Richard.

> Thanks,
> Prasad
>
>> Richard.
>>
>>>> Thanks,
>>>> Richard.
>>>>
>>>>> Thanks,
>>>>> Prasad
>>>>>
>>>>>> Richard.
>>>>>>
>>>>>>>> Richard.
>>>>>>>>
>>>>>>>>>Thanks,
>>>>>>>>>Prathamesh
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> Thanks,
>>>>>>>>>> Prasad Ghangal
>>>>>>>>
>>>>>>>>

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [gimplefe] hacking pass manager
  2016-07-15 10:43                   ` Richard Biener
@ 2016-07-18 18:28                     ` Prasad Ghangal
  2016-07-18 18:55                       ` Richard Biener
  0 siblings, 1 reply; 29+ messages in thread
From: Prasad Ghangal @ 2016-07-18 18:28 UTC (permalink / raw)
  To: Richard Biener; +Cc: Prathamesh Kulkarni, David Malcolm, gcc Mailing List

On 15 July 2016 at 16:13, Richard Biener <richard.guenther@gmail.com> wrote:
> On Sun, Jul 10, 2016 at 6:13 PM, Prasad Ghangal
> <prasad.ghangal@gmail.com> wrote:
>> On 8 July 2016 at 13:13, Richard Biener <richard.guenther@gmail.com> wrote:
>>> On Thu, Jul 7, 2016 at 9:45 PM, Prasad Ghangal <prasad.ghangal@gmail.com> wrote:
>>>> On 6 July 2016 at 14:24, Richard Biener <richard.guenther@gmail.com> wrote:
>>>>> On Wed, Jul 6, 2016 at 9:51 AM, Prasad Ghangal <prasad.ghangal@gmail.com> wrote:
>>>>>> On 30 June 2016 at 17:10, Richard Biener <richard.guenther@gmail.com> wrote:
>>>>>>> On Wed, Jun 29, 2016 at 9:13 PM, Prasad Ghangal
>>>>>>> <prasad.ghangal@gmail.com> wrote:
>>>>>>>> On 29 June 2016 at 22:15, Richard Biener <richard.guenther@gmail.com> wrote:
>>>>>>>>> On June 29, 2016 6:20:29 PM GMT+02:00, Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org> wrote:
>>>>>>>>>>On 18 June 2016 at 12:02, Prasad Ghangal <prasad.ghangal@gmail.com>
>>>>>>>>>>wrote:
>>>>>>>>>>> Hi,
>>>>>>>>>>>
>>>>>>>>>>> I tried hacking pass manager to execute only given passes. For this I
>>>>>>>>>>> am adding new member as opt_pass *custom_pass_list to the function
>>>>>>>>>>> structure to store passes need to execute and providing the
>>>>>>>>>>> custom_pass_list to execute_pass_list() function instead of all
>>>>>>>>>>passes
>>>>>>>>>>>
>>>>>>>>>>> for test case like-
>>>>>>>>>>>
>>>>>>>>>>> int a;
>>>>>>>>>>> void __GIMPLE (execute ("tree-ccp1", "tree-fre1")) foo()
>>>>>>>>>>> {
>>>>>>>>>>> bb_1:
>>>>>>>>>>>   a = 1 + a;
>>>>>>>>>>> }
>>>>>>>>>>>
>>>>>>>>>>> it will execute only given passes i.e. ccp1 and fre1 pass on the
>>>>>>>>>>function
>>>>>>>>>>>
>>>>>>>>>>> and for test case like -
>>>>>>>>>>>
>>>>>>>>>>> int a;
>>>>>>>>>>> void __GIMPLE (startwith ("tree-ccp1")) foo()
>>>>>>>>>>> {
>>>>>>>>>>> bb_1:
>>>>>>>>>>>   a = 1 + a;
>>>>>>>>>>> }
>>>>>>>>>>>
>>>>>>>>>>> it will act as a entry point to the pipeline and will execute passes
>>>>>>>>>>> starting from given pass.
>>>>>>>>>>Bike-shedding:
>>>>>>>>>>Would it make sense to have syntax for defining pass ranges to execute
>>>>>>>>>>?
>>>>>>>>>>for instance:
>>>>>>>>>>void __GIMPLE(execute (pass_start : pass_end))
>>>>>>>>>>which would execute all the passes within range [pass_start, pass_end],
>>>>>>>>>>which would be convenient if the range is large.
>>>>>>>>>
>>>>>>>>> But it would rely on a particular pass pipeline, f.e. pass-start appearing before pass-end.
>>>>>>>>>
>>>>>>>>> Currently control doesn't work 100% as it only replaces all_optimizations but not lowering passes or early opts, nor IPA opts.
>>>>>>>>>
>>>>>>>>
>>>>>>>> Each pass needs GIMPLE in some specific form. So I am letting lowering
>>>>>>>> and early opt passes to execute. I think we have to execute some
>>>>>>>> passes (like cfg) anyway to represent GIMPLE into proper form
>>>>>>>
>>>>>>> Yes, that's true.  Note that early opt passes only optimize but we need
>>>>>>> pass_build_ssa_passes at least (for into-SSA).  For proper unit-testing
>>>>>>> of GIMPLE passes we do need to guard off early opts somehow
>>>>>>> (I guess a simple if (flag_gimple && cfun->custom_pass_list) would do
>>>>>>> that).
>>>>>>>
>>>>>>> Then there is of course the question about IPA passes which I think is
>>>>>>> somewhat harder (one could always disable all IPA passes manually
>>>>>>> via flags of course or finally have a global -fipa/no-ipa like most
>>>>>>> other compilers).
>>>>>>>
>>>>>> Can we iterate through all ipa passes and do -fdisable-ipa-pass or
>>>>>> -fenable-ipa-pass equivalent for each?
>>>>>
>>>>> We could do that, yes.  But let's postpone this issue.  I think that
>>>>> startwith is going to be most useful and rather than constructing
>>>>> a pass list for it "native" support for it in the pass manager is
>>>>> likely to produce better results (add a 'startwith' member alongside
>>>>> the pass list member and if it is set the pass manager skips all
>>>>> passes that do not match 'startwith' and once it reaches it it clears
>>>>> the field).
>>>>>
>>>>> In the future I hope we can get away from a static pass list and more
>>>>> towards rule-driven pass execution (we have all those PROP_* stuff
>>>>> already but it isn't really used for example).  But well, that would be
>>>>> a separate GSoC project ;)
>>>>>
>>>>> IMHO startwith will provide everything needed for unit-testing.  We can
>>>>> add a flag on whether further passes should be executed or not and
>>>>> even a pass list like execute ("ccp1", "fre") can be implemented by
>>>>> startwith ccp1 and then from there executing the rest of the passes in the
>>>>> list and stopping at the end.
>>>>>
>>>>> As said, unit-testing should exercise a single pass if we can control
>>>>> its input.
>>>>>
>>>> In this patch I am skipping execution of passes until pass_startwith
>>>> is found. Unlike previous build, now pass manager executes all passes
>>>> in pipeline starting from pass_startwith instead of just sub passes.
>>>
>>> That looks good.  I wonder if
>>>
>>> +  if (startwith_p && cfun->startwith)
>>> +    {
>>> +      if (pass->name == cfun->pass_startwith->name
>>> +         || pass->name == "*clean_state")
>>>
>>> need better be strcmp ()s though.  Also the early optimization pipeline
>>> should be executed with startwith support as well.
>>>
>>
>> This patch adds startwith support for early opt passes. But for
>> starting from some passes (like asan0, optimized) in all_passes
>> pipeline, it falils at verify_curr_properties in execute_one_pass ().
>> I wonder if we need to update properties after skipping each pass
>
> Yeah, it's not possible to start at arbitrary points with skipping passes
> that provide a required property.  I suspect it's good enough that we'll
> ICE if that happens.
>
> I see you are working on the dump-file side a bit now.  What is still
> missing after you got support for PHIs is parsing of SSA names.
> Without this unit-testing will be difficult at best.
>
> I think what we need to do is simplify the job of the parser and
> make the syntax we use to print SSA names a bit different.
> So rather than printing VAR_VERSION we need to choose a
> letter that is not part of a valid identifier before VERSION,
> like a dot '.'.  Thus we'd have i.1 instead of i_1 and we'd have
> .2 instead of _2 for an anonymous SSA name.  The advantage
> for non-anonymous names is that we can properly re-use the
> C frontends decl handling for declaring and looking up 'i'.
> The disadvantage is that for anonymous SSA names this isn't
> so easy which means we could choose to not support those
> for the moment and require fake decls for them.  In fact
> into-SSA will do the correct thing if we just treat them as decls,
> thus continue to dump them as _VERSION.
>

I am little confused here about parsing 'i.1' because lexer drops DOT
token for syntax like NAME.NUMBER . Hence instead of 'i.1' parser
receives 'i1'

> Another issue would be to preserve SSA name VERSIONS
> (the decl idea for anon ones doesn't work) or basic-block
> numbering/ordering (requires direct CFG construction).  Both
> are out-of-scope for the GSoC project I think.
>
> Richard.
>
>> Thanks,
>> Prasad
>>
>>> Richard.
>>>
>>>>> Thanks,
>>>>> Richard.
>>>>>
>>>>>> Thanks,
>>>>>> Prasad
>>>>>>
>>>>>>> Richard.
>>>>>>>
>>>>>>>>> Richard.
>>>>>>>>>
>>>>>>>>>>Thanks,
>>>>>>>>>>Prathamesh
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> Thanks,
>>>>>>>>>>> Prasad Ghangal
>>>>>>>>>
>>>>>>>>>

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [gimplefe] hacking pass manager
  2016-07-18 18:28                     ` Prasad Ghangal
@ 2016-07-18 18:55                       ` Richard Biener
  2016-07-18 19:22                         ` Prasad Ghangal
  0 siblings, 1 reply; 29+ messages in thread
From: Richard Biener @ 2016-07-18 18:55 UTC (permalink / raw)
  To: Prasad Ghangal; +Cc: Prathamesh Kulkarni, David Malcolm, gcc Mailing List

On July 18, 2016 8:28:15 PM GMT+02:00, Prasad Ghangal <prasad.ghangal@gmail.com> wrote:
>On 15 July 2016 at 16:13, Richard Biener <richard.guenther@gmail.com>
>wrote:
>> On Sun, Jul 10, 2016 at 6:13 PM, Prasad Ghangal
>> <prasad.ghangal@gmail.com> wrote:
>>> On 8 July 2016 at 13:13, Richard Biener <richard.guenther@gmail.com>
>wrote:
>>>> On Thu, Jul 7, 2016 at 9:45 PM, Prasad Ghangal
><prasad.ghangal@gmail.com> wrote:
>>>>> On 6 July 2016 at 14:24, Richard Biener
><richard.guenther@gmail.com> wrote:
>>>>>> On Wed, Jul 6, 2016 at 9:51 AM, Prasad Ghangal
><prasad.ghangal@gmail.com> wrote:
>>>>>>> On 30 June 2016 at 17:10, Richard Biener
><richard.guenther@gmail.com> wrote:
>>>>>>>> On Wed, Jun 29, 2016 at 9:13 PM, Prasad Ghangal
>>>>>>>> <prasad.ghangal@gmail.com> wrote:
>>>>>>>>> On 29 June 2016 at 22:15, Richard Biener
><richard.guenther@gmail.com> wrote:
>>>>>>>>>> On June 29, 2016 6:20:29 PM GMT+02:00, Prathamesh Kulkarni
><prathamesh.kulkarni@linaro.org> wrote:
>>>>>>>>>>>On 18 June 2016 at 12:02, Prasad Ghangal
><prasad.ghangal@gmail.com>
>>>>>>>>>>>wrote:
>>>>>>>>>>>> Hi,
>>>>>>>>>>>>
>>>>>>>>>>>> I tried hacking pass manager to execute only given passes.
>For this I
>>>>>>>>>>>> am adding new member as opt_pass *custom_pass_list to the
>function
>>>>>>>>>>>> structure to store passes need to execute and providing the
>>>>>>>>>>>> custom_pass_list to execute_pass_list() function instead of
>all
>>>>>>>>>>>passes
>>>>>>>>>>>>
>>>>>>>>>>>> for test case like-
>>>>>>>>>>>>
>>>>>>>>>>>> int a;
>>>>>>>>>>>> void __GIMPLE (execute ("tree-ccp1", "tree-fre1")) foo()
>>>>>>>>>>>> {
>>>>>>>>>>>> bb_1:
>>>>>>>>>>>>   a = 1 + a;
>>>>>>>>>>>> }
>>>>>>>>>>>>
>>>>>>>>>>>> it will execute only given passes i.e. ccp1 and fre1 pass
>on the
>>>>>>>>>>>function
>>>>>>>>>>>>
>>>>>>>>>>>> and for test case like -
>>>>>>>>>>>>
>>>>>>>>>>>> int a;
>>>>>>>>>>>> void __GIMPLE (startwith ("tree-ccp1")) foo()
>>>>>>>>>>>> {
>>>>>>>>>>>> bb_1:
>>>>>>>>>>>>   a = 1 + a;
>>>>>>>>>>>> }
>>>>>>>>>>>>
>>>>>>>>>>>> it will act as a entry point to the pipeline and will
>execute passes
>>>>>>>>>>>> starting from given pass.
>>>>>>>>>>>Bike-shedding:
>>>>>>>>>>>Would it make sense to have syntax for defining pass ranges
>to execute
>>>>>>>>>>>?
>>>>>>>>>>>for instance:
>>>>>>>>>>>void __GIMPLE(execute (pass_start : pass_end))
>>>>>>>>>>>which would execute all the passes within range [pass_start,
>pass_end],
>>>>>>>>>>>which would be convenient if the range is large.
>>>>>>>>>>
>>>>>>>>>> But it would rely on a particular pass pipeline, f.e.
>pass-start appearing before pass-end.
>>>>>>>>>>
>>>>>>>>>> Currently control doesn't work 100% as it only replaces
>all_optimizations but not lowering passes or early opts, nor IPA opts.
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Each pass needs GIMPLE in some specific form. So I am letting
>lowering
>>>>>>>>> and early opt passes to execute. I think we have to execute
>some
>>>>>>>>> passes (like cfg) anyway to represent GIMPLE into proper form
>>>>>>>>
>>>>>>>> Yes, that's true.  Note that early opt passes only optimize but
>we need
>>>>>>>> pass_build_ssa_passes at least (for into-SSA).  For proper
>unit-testing
>>>>>>>> of GIMPLE passes we do need to guard off early opts somehow
>>>>>>>> (I guess a simple if (flag_gimple && cfun->custom_pass_list)
>would do
>>>>>>>> that).
>>>>>>>>
>>>>>>>> Then there is of course the question about IPA passes which I
>think is
>>>>>>>> somewhat harder (one could always disable all IPA passes
>manually
>>>>>>>> via flags of course or finally have a global -fipa/no-ipa like
>most
>>>>>>>> other compilers).
>>>>>>>>
>>>>>>> Can we iterate through all ipa passes and do -fdisable-ipa-pass
>or
>>>>>>> -fenable-ipa-pass equivalent for each?
>>>>>>
>>>>>> We could do that, yes.  But let's postpone this issue.  I think
>that
>>>>>> startwith is going to be most useful and rather than constructing
>>>>>> a pass list for it "native" support for it in the pass manager is
>>>>>> likely to produce better results (add a 'startwith' member
>alongside
>>>>>> the pass list member and if it is set the pass manager skips all
>>>>>> passes that do not match 'startwith' and once it reaches it it
>clears
>>>>>> the field).
>>>>>>
>>>>>> In the future I hope we can get away from a static pass list and
>more
>>>>>> towards rule-driven pass execution (we have all those PROP_*
>stuff
>>>>>> already but it isn't really used for example).  But well, that
>would be
>>>>>> a separate GSoC project ;)
>>>>>>
>>>>>> IMHO startwith will provide everything needed for unit-testing. 
>We can
>>>>>> add a flag on whether further passes should be executed or not
>and
>>>>>> even a pass list like execute ("ccp1", "fre") can be implemented
>by
>>>>>> startwith ccp1 and then from there executing the rest of the
>passes in the
>>>>>> list and stopping at the end.
>>>>>>
>>>>>> As said, unit-testing should exercise a single pass if we can
>control
>>>>>> its input.
>>>>>>
>>>>> In this patch I am skipping execution of passes until
>pass_startwith
>>>>> is found. Unlike previous build, now pass manager executes all
>passes
>>>>> in pipeline starting from pass_startwith instead of just sub
>passes.
>>>>
>>>> That looks good.  I wonder if
>>>>
>>>> +  if (startwith_p && cfun->startwith)
>>>> +    {
>>>> +      if (pass->name == cfun->pass_startwith->name
>>>> +         || pass->name == "*clean_state")
>>>>
>>>> need better be strcmp ()s though.  Also the early optimization
>pipeline
>>>> should be executed with startwith support as well.
>>>>
>>>
>>> This patch adds startwith support for early opt passes. But for
>>> starting from some passes (like asan0, optimized) in all_passes
>>> pipeline, it falils at verify_curr_properties in execute_one_pass
>().
>>> I wonder if we need to update properties after skipping each pass
>>
>> Yeah, it's not possible to start at arbitrary points with skipping
>passes
>> that provide a required property.  I suspect it's good enough that
>we'll
>> ICE if that happens.
>>
>> I see you are working on the dump-file side a bit now.  What is still
>> missing after you got support for PHIs is parsing of SSA names.
>> Without this unit-testing will be difficult at best.
>>
>> I think what we need to do is simplify the job of the parser and
>> make the syntax we use to print SSA names a bit different.
>> So rather than printing VAR_VERSION we need to choose a
>> letter that is not part of a valid identifier before VERSION,
>> like a dot '.'.  Thus we'd have i.1 instead of i_1 and we'd have
>> .2 instead of _2 for an anonymous SSA name.  The advantage
>> for non-anonymous names is that we can properly re-use the
>> C frontends decl handling for declaring and looking up 'i'.
>> The disadvantage is that for anonymous SSA names this isn't
>> so easy which means we could choose to not support those
>> for the moment and require fake decls for them.  In fact
>> into-SSA will do the correct thing if we just treat them as decls,
>> thus continue to dump them as _VERSION.
>>
>
>I am little confused here about parsing 'i.1' because lexer drops DOT
>token for syntax like NAME.NUMBER . Hence instead of 'i.1' parser
>receives 'i1'

Are you sure? You should get three tokens, one for 'i', one for the dot and
One for '1'.  You'd lookup the first via the C frontend symbol table only.

Richard.

>> Another issue would be to preserve SSA name VERSIONS
>> (the decl idea for anon ones doesn't work) or basic-block
>> numbering/ordering (requires direct CFG construction).  Both
>> are out-of-scope for the GSoC project I think.
>>
>> Richard.
>>
>>> Thanks,
>>> Prasad
>>>
>>>> Richard.
>>>>
>>>>>> Thanks,
>>>>>> Richard.
>>>>>>
>>>>>>> Thanks,
>>>>>>> Prasad
>>>>>>>
>>>>>>>> Richard.
>>>>>>>>
>>>>>>>>>> Richard.
>>>>>>>>>>
>>>>>>>>>>>Thanks,
>>>>>>>>>>>Prathamesh
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> Thanks,
>>>>>>>>>>>> Prasad Ghangal
>>>>>>>>>>
>>>>>>>>>>


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [gimplefe] hacking pass manager
  2016-07-18 18:55                       ` Richard Biener
@ 2016-07-18 19:22                         ` Prasad Ghangal
  2016-07-18 21:06                           ` David Malcolm
  0 siblings, 1 reply; 29+ messages in thread
From: Prasad Ghangal @ 2016-07-18 19:22 UTC (permalink / raw)
  To: Richard Biener; +Cc: Prathamesh Kulkarni, David Malcolm, gcc Mailing List

On 19 July 2016 at 00:25, Richard Biener <richard.guenther@gmail.com> wrote:
> On July 18, 2016 8:28:15 PM GMT+02:00, Prasad Ghangal <prasad.ghangal@gmail.com> wrote:
>>On 15 July 2016 at 16:13, Richard Biener <richard.guenther@gmail.com>
>>wrote:
>>> On Sun, Jul 10, 2016 at 6:13 PM, Prasad Ghangal
>>> <prasad.ghangal@gmail.com> wrote:
>>>> On 8 July 2016 at 13:13, Richard Biener <richard.guenther@gmail.com>
>>wrote:
>>>>> On Thu, Jul 7, 2016 at 9:45 PM, Prasad Ghangal
>><prasad.ghangal@gmail.com> wrote:
>>>>>> On 6 July 2016 at 14:24, Richard Biener
>><richard.guenther@gmail.com> wrote:
>>>>>>> On Wed, Jul 6, 2016 at 9:51 AM, Prasad Ghangal
>><prasad.ghangal@gmail.com> wrote:
>>>>>>>> On 30 June 2016 at 17:10, Richard Biener
>><richard.guenther@gmail.com> wrote:
>>>>>>>>> On Wed, Jun 29, 2016 at 9:13 PM, Prasad Ghangal
>>>>>>>>> <prasad.ghangal@gmail.com> wrote:
>>>>>>>>>> On 29 June 2016 at 22:15, Richard Biener
>><richard.guenther@gmail.com> wrote:
>>>>>>>>>>> On June 29, 2016 6:20:29 PM GMT+02:00, Prathamesh Kulkarni
>><prathamesh.kulkarni@linaro.org> wrote:
>>>>>>>>>>>>On 18 June 2016 at 12:02, Prasad Ghangal
>><prasad.ghangal@gmail.com>
>>>>>>>>>>>>wrote:
>>>>>>>>>>>>> Hi,
>>>>>>>>>>>>>
>>>>>>>>>>>>> I tried hacking pass manager to execute only given passes.
>>For this I
>>>>>>>>>>>>> am adding new member as opt_pass *custom_pass_list to the
>>function
>>>>>>>>>>>>> structure to store passes need to execute and providing the
>>>>>>>>>>>>> custom_pass_list to execute_pass_list() function instead of
>>all
>>>>>>>>>>>>passes
>>>>>>>>>>>>>
>>>>>>>>>>>>> for test case like-
>>>>>>>>>>>>>
>>>>>>>>>>>>> int a;
>>>>>>>>>>>>> void __GIMPLE (execute ("tree-ccp1", "tree-fre1")) foo()
>>>>>>>>>>>>> {
>>>>>>>>>>>>> bb_1:
>>>>>>>>>>>>>   a = 1 + a;
>>>>>>>>>>>>> }
>>>>>>>>>>>>>
>>>>>>>>>>>>> it will execute only given passes i.e. ccp1 and fre1 pass
>>on the
>>>>>>>>>>>>function
>>>>>>>>>>>>>
>>>>>>>>>>>>> and for test case like -
>>>>>>>>>>>>>
>>>>>>>>>>>>> int a;
>>>>>>>>>>>>> void __GIMPLE (startwith ("tree-ccp1")) foo()
>>>>>>>>>>>>> {
>>>>>>>>>>>>> bb_1:
>>>>>>>>>>>>>   a = 1 + a;
>>>>>>>>>>>>> }
>>>>>>>>>>>>>
>>>>>>>>>>>>> it will act as a entry point to the pipeline and will
>>execute passes
>>>>>>>>>>>>> starting from given pass.
>>>>>>>>>>>>Bike-shedding:
>>>>>>>>>>>>Would it make sense to have syntax for defining pass ranges
>>to execute
>>>>>>>>>>>>?
>>>>>>>>>>>>for instance:
>>>>>>>>>>>>void __GIMPLE(execute (pass_start : pass_end))
>>>>>>>>>>>>which would execute all the passes within range [pass_start,
>>pass_end],
>>>>>>>>>>>>which would be convenient if the range is large.
>>>>>>>>>>>
>>>>>>>>>>> But it would rely on a particular pass pipeline, f.e.
>>pass-start appearing before pass-end.
>>>>>>>>>>>
>>>>>>>>>>> Currently control doesn't work 100% as it only replaces
>>all_optimizations but not lowering passes or early opts, nor IPA opts.
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> Each pass needs GIMPLE in some specific form. So I am letting
>>lowering
>>>>>>>>>> and early opt passes to execute. I think we have to execute
>>some
>>>>>>>>>> passes (like cfg) anyway to represent GIMPLE into proper form
>>>>>>>>>
>>>>>>>>> Yes, that's true.  Note that early opt passes only optimize but
>>we need
>>>>>>>>> pass_build_ssa_passes at least (for into-SSA).  For proper
>>unit-testing
>>>>>>>>> of GIMPLE passes we do need to guard off early opts somehow
>>>>>>>>> (I guess a simple if (flag_gimple && cfun->custom_pass_list)
>>would do
>>>>>>>>> that).
>>>>>>>>>
>>>>>>>>> Then there is of course the question about IPA passes which I
>>think is
>>>>>>>>> somewhat harder (one could always disable all IPA passes
>>manually
>>>>>>>>> via flags of course or finally have a global -fipa/no-ipa like
>>most
>>>>>>>>> other compilers).
>>>>>>>>>
>>>>>>>> Can we iterate through all ipa passes and do -fdisable-ipa-pass
>>or
>>>>>>>> -fenable-ipa-pass equivalent for each?
>>>>>>>
>>>>>>> We could do that, yes.  But let's postpone this issue.  I think
>>that
>>>>>>> startwith is going to be most useful and rather than constructing
>>>>>>> a pass list for it "native" support for it in the pass manager is
>>>>>>> likely to produce better results (add a 'startwith' member
>>alongside
>>>>>>> the pass list member and if it is set the pass manager skips all
>>>>>>> passes that do not match 'startwith' and once it reaches it it
>>clears
>>>>>>> the field).
>>>>>>>
>>>>>>> In the future I hope we can get away from a static pass list and
>>more
>>>>>>> towards rule-driven pass execution (we have all those PROP_*
>>stuff
>>>>>>> already but it isn't really used for example).  But well, that
>>would be
>>>>>>> a separate GSoC project ;)
>>>>>>>
>>>>>>> IMHO startwith will provide everything needed for unit-testing.
>>We can
>>>>>>> add a flag on whether further passes should be executed or not
>>and
>>>>>>> even a pass list like execute ("ccp1", "fre") can be implemented
>>by
>>>>>>> startwith ccp1 and then from there executing the rest of the
>>passes in the
>>>>>>> list and stopping at the end.
>>>>>>>
>>>>>>> As said, unit-testing should exercise a single pass if we can
>>control
>>>>>>> its input.
>>>>>>>
>>>>>> In this patch I am skipping execution of passes until
>>pass_startwith
>>>>>> is found. Unlike previous build, now pass manager executes all
>>passes
>>>>>> in pipeline starting from pass_startwith instead of just sub
>>passes.
>>>>>
>>>>> That looks good.  I wonder if
>>>>>
>>>>> +  if (startwith_p && cfun->startwith)
>>>>> +    {
>>>>> +      if (pass->name == cfun->pass_startwith->name
>>>>> +         || pass->name == "*clean_state")
>>>>>
>>>>> need better be strcmp ()s though.  Also the early optimization
>>pipeline
>>>>> should be executed with startwith support as well.
>>>>>
>>>>
>>>> This patch adds startwith support for early opt passes. But for
>>>> starting from some passes (like asan0, optimized) in all_passes
>>>> pipeline, it falils at verify_curr_properties in execute_one_pass
>>().
>>>> I wonder if we need to update properties after skipping each pass
>>>
>>> Yeah, it's not possible to start at arbitrary points with skipping
>>passes
>>> that provide a required property.  I suspect it's good enough that
>>we'll
>>> ICE if that happens.
>>>
>>> I see you are working on the dump-file side a bit now.  What is still
>>> missing after you got support for PHIs is parsing of SSA names.
>>> Without this unit-testing will be difficult at best.
>>>
>>> I think what we need to do is simplify the job of the parser and
>>> make the syntax we use to print SSA names a bit different.
>>> So rather than printing VAR_VERSION we need to choose a
>>> letter that is not part of a valid identifier before VERSION,
>>> like a dot '.'.  Thus we'd have i.1 instead of i_1 and we'd have
>>> .2 instead of _2 for an anonymous SSA name.  The advantage
>>> for non-anonymous names is that we can properly re-use the
>>> C frontends decl handling for declaring and looking up 'i'.
>>> The disadvantage is that for anonymous SSA names this isn't
>>> so easy which means we could choose to not support those
>>> for the moment and require fake decls for them.  In fact
>>> into-SSA will do the correct thing if we just treat them as decls,
>>> thus continue to dump them as _VERSION.
>>>
>>
>>I am little confused here about parsing 'i.1' because lexer drops DOT
>>token for syntax like NAME.NUMBER . Hence instead of 'i.1' parser
>>receives 'i1'
>
> Are you sure? You should get three tokens, one for 'i', one for the dot and
> One for '1'.  You'd lookup the first via the C frontend symbol table only.
>

Yes, I was also expecting that. For syntax like 'a.b' (ie name.name)
it gives proper 3 tokens but for syntax like 'a.1' it produces only 2.

This is what I observed while debugging "int a.1;"

(gdb) print *c_parser_peek_nth_token (parser, 1)
$3 = {type = CPP_KEYWORD, id_kind = C_ID_NONE, keyword = RID_INT,
  pragma_kind = PRAGMA_NONE, location = 242114, value = 0x7ffff65c82d0}
(gdb) print *c_parser_peek_nth_token (parser, 2)
$4 = {type = CPP_NAME, id_kind = C_ID_ID, keyword = RID_MAX,
  pragma_kind = PRAGMA_NONE, location = 242240, value = 0x7ffff66d0b90}
(gdb) print *c_parser_peek_nth_token (parser, 3)
$5 = {type = CPP_NUMBER, id_kind = C_ID_NONE, keyword = RID_MAX,
  pragma_kind = PRAGMA_NONE, location = 242273, value = 0x7ffff66e0030}


Thanks,
Prasad

> Richard.
>
>>> Another issue would be to preserve SSA name VERSIONS
>>> (the decl idea for anon ones doesn't work) or basic-block
>>> numbering/ordering (requires direct CFG construction).  Both
>>> are out-of-scope for the GSoC project I think.
>>>
>>> Richard.
>>>
>>>> Thanks,
>>>> Prasad
>>>>
>>>>> Richard.
>>>>>
>>>>>>> Thanks,
>>>>>>> Richard.
>>>>>>>
>>>>>>>> Thanks,
>>>>>>>> Prasad
>>>>>>>>
>>>>>>>>> Richard.
>>>>>>>>>
>>>>>>>>>>> Richard.
>>>>>>>>>>>
>>>>>>>>>>>>Thanks,
>>>>>>>>>>>>Prathamesh
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> Thanks,
>>>>>>>>>>>>> Prasad Ghangal
>>>>>>>>>>>
>>>>>>>>>>>
>
>

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [gimplefe] hacking pass manager
  2016-07-18 19:22                         ` Prasad Ghangal
@ 2016-07-18 21:06                           ` David Malcolm
  2016-07-19  5:35                             ` Richard Biener
  0 siblings, 1 reply; 29+ messages in thread
From: David Malcolm @ 2016-07-18 21:06 UTC (permalink / raw)
  To: Prasad Ghangal, Richard Biener; +Cc: Prathamesh Kulkarni, gcc Mailing List

On Tue, 2016-07-19 at 00:52 +0530, Prasad Ghangal wrote:
> On 19 July 2016 at 00:25, Richard Biener <richard.guenther@gmail.com>
> wrote:
> > On July 18, 2016 8:28:15 PM GMT+02:00, Prasad Ghangal <
> > prasad.ghangal@gmail.com> wrote:
> > > On 15 July 2016 at 16:13, Richard Biener <
> > > richard.guenther@gmail.com>
> > > wrote:
> > > > On Sun, Jul 10, 2016 at 6:13 PM, Prasad Ghangal
> > > > <prasad.ghangal@gmail.com> wrote:
> > > > > On 8 July 2016 at 13:13, Richard Biener <
> > > > > richard.guenther@gmail.com>
> > > wrote:
> > > > > > On Thu, Jul 7, 2016 at 9:45 PM, Prasad Ghangal
> > > <prasad.ghangal@gmail.com> wrote:
> > > > > > > On 6 July 2016 at 14:24, Richard Biener
> > > <richard.guenther@gmail.com> wrote:
> > > > > > > > On Wed, Jul 6, 2016 at 9:51 AM, Prasad Ghangal
> > > <prasad.ghangal@gmail.com> wrote:
> > > > > > > > > On 30 June 2016 at 17:10, Richard Biener
> > > <richard.guenther@gmail.com> wrote:
> > > > > > > > > > On Wed, Jun 29, 2016 at 9:13 PM, Prasad Ghangal
> > > > > > > > > > <prasad.ghangal@gmail.com> wrote:
> > > > > > > > > > > On 29 June 2016 at 22:15, Richard Biener
> > > <richard.guenther@gmail.com> wrote:
> > > > > > > > > > > > On June 29, 2016 6:20:29 PM GMT+02:00,
> > > > > > > > > > > > Prathamesh Kulkarni
> > > <prathamesh.kulkarni@linaro.org> wrote:
> > > > > > > > > > > > > On 18 June 2016 at 12:02, Prasad Ghangal
> > > <prasad.ghangal@gmail.com>
> > > > > > > > > > > > > wrote:
> > > > > > > > > > > > > > Hi,
> > > > > > > > > > > > > > 
> > > > > > > > > > > > > > I tried hacking pass manager to execute
> > > > > > > > > > > > > > only given passes.
> > > For this I
> > > > > > > > > > > > > > am adding new member as opt_pass
> > > > > > > > > > > > > > *custom_pass_list to the
> > > function
> > > > > > > > > > > > > > structure to store passes need to execute
> > > > > > > > > > > > > > and providing the
> > > > > > > > > > > > > > custom_pass_list to execute_pass_list()
> > > > > > > > > > > > > > function instead of
> > > all
> > > > > > > > > > > > > passes
> > > > > > > > > > > > > > 
> > > > > > > > > > > > > > for test case like-
> > > > > > > > > > > > > > 
> > > > > > > > > > > > > > int a;
> > > > > > > > > > > > > > void __GIMPLE (execute ("tree-ccp1", "tree
> > > > > > > > > > > > > > -fre1")) foo()
> > > > > > > > > > > > > > {
> > > > > > > > > > > > > > bb_1:
> > > > > > > > > > > > > >   a = 1 + a;
> > > > > > > > > > > > > > }
> > > > > > > > > > > > > > 
> > > > > > > > > > > > > > it will execute only given passes i.e. ccp1
> > > > > > > > > > > > > > and fre1 pass
> > > on the
> > > > > > > > > > > > > function
> > > > > > > > > > > > > > 
> > > > > > > > > > > > > > and for test case like -
> > > > > > > > > > > > > > 
> > > > > > > > > > > > > > int a;
> > > > > > > > > > > > > > void __GIMPLE (startwith ("tree-ccp1"))
> > > > > > > > > > > > > > foo()
> > > > > > > > > > > > > > {
> > > > > > > > > > > > > > bb_1:
> > > > > > > > > > > > > >   a = 1 + a;
> > > > > > > > > > > > > > }
> > > > > > > > > > > > > > 
> > > > > > > > > > > > > > it will act as a entry point to the
> > > > > > > > > > > > > > pipeline and will
> > > execute passes
> > > > > > > > > > > > > > starting from given pass.
> > > > > > > > > > > > > Bike-shedding:
> > > > > > > > > > > > > Would it make sense to have syntax for
> > > > > > > > > > > > > defining pass ranges
> > > to execute
> > > > > > > > > > > > > ?
> > > > > > > > > > > > > for instance:
> > > > > > > > > > > > > void __GIMPLE(execute (pass_start :
> > > > > > > > > > > > > pass_end))
> > > > > > > > > > > > > which would execute all the passes within
> > > > > > > > > > > > > range [pass_start,
> > > pass_end],
> > > > > > > > > > > > > which would be convenient if the range is
> > > > > > > > > > > > > large.
> > > > > > > > > > > > 
> > > > > > > > > > > > But it would rely on a particular pass
> > > > > > > > > > > > pipeline, f.e.
> > > pass-start appearing before pass-end.
> > > > > > > > > > > > 
> > > > > > > > > > > > Currently control doesn't work 100% as it only
> > > > > > > > > > > > replaces
> > > all_optimizations but not lowering passes or early opts, nor IPA
> > > opts.
> > > > > > > > > > > > 
> > > > > > > > > > > 
> > > > > > > > > > > Each pass needs GIMPLE in some specific form. So
> > > > > > > > > > > I am letting
> > > lowering
> > > > > > > > > > > and early opt passes to execute. I think we have
> > > > > > > > > > > to execute
> > > some
> > > > > > > > > > > passes (like cfg) anyway to represent GIMPLE into
> > > > > > > > > > > proper form
> > > > > > > > > > 
> > > > > > > > > > Yes, that's true.  Note that early opt passes only
> > > > > > > > > > optimize but
> > > we need
> > > > > > > > > > pass_build_ssa_passes at least (for into-SSA).  For
> > > > > > > > > > proper
> > > unit-testing
> > > > > > > > > > of GIMPLE passes we do need to guard off early opts
> > > > > > > > > > somehow
> > > > > > > > > > (I guess a simple if (flag_gimple && cfun
> > > > > > > > > > ->custom_pass_list)
> > > would do
> > > > > > > > > > that).
> > > > > > > > > > 
> > > > > > > > > > Then there is of course the question about IPA
> > > > > > > > > > passes which I
> > > think is
> > > > > > > > > > somewhat harder (one could always disable all IPA
> > > > > > > > > > passes
> > > manually
> > > > > > > > > > via flags of course or finally have a global 
> > > > > > > > > > -fipa/no-ipa like
> > > most
> > > > > > > > > > other compilers).
> > > > > > > > > > 
> > > > > > > > > Can we iterate through all ipa passes and do 
> > > > > > > > > -fdisable-ipa-pass
> > > or
> > > > > > > > > -fenable-ipa-pass equivalent for each?
> > > > > > > > 
> > > > > > > > We could do that, yes.  But let's postpone this issue. 
> > > > > > > >  I think
> > > that
> > > > > > > > startwith is going to be most useful and rather than
> > > > > > > > constructing
> > > > > > > > a pass list for it "native" support for it in the pass
> > > > > > > > manager is
> > > > > > > > likely to produce better results (add a 'startwith'
> > > > > > > > member
> > > alongside
> > > > > > > > the pass list member and if it is set the pass manager
> > > > > > > > skips all
> > > > > > > > passes that do not match 'startwith' and once it
> > > > > > > > reaches it it
> > > clears
> > > > > > > > the field).
> > > > > > > > 
> > > > > > > > In the future I hope we can get away from a static pass
> > > > > > > > list and
> > > more
> > > > > > > > towards rule-driven pass execution (we have all those
> > > > > > > > PROP_*
> > > stuff
> > > > > > > > already but it isn't really used for example).  But
> > > > > > > > well, that
> > > would be
> > > > > > > > a separate GSoC project ;)
> > > > > > > > 
> > > > > > > > IMHO startwith will provide everything needed for unit
> > > > > > > > -testing.
> > > We can
> > > > > > > > add a flag on whether further passes should be executed
> > > > > > > > or not
> > > and
> > > > > > > > even a pass list like execute ("ccp1", "fre") can be
> > > > > > > > implemented
> > > by
> > > > > > > > startwith ccp1 and then from there executing the rest
> > > > > > > > of the
> > > passes in the
> > > > > > > > list and stopping at the end.
> > > > > > > > 
> > > > > > > > As said, unit-testing should exercise a single pass if
> > > > > > > > we can
> > > control
> > > > > > > > its input.
> > > > > > > > 
> > > > > > > In this patch I am skipping execution of passes until
> > > pass_startwith
> > > > > > > is found. Unlike previous build, now pass manager
> > > > > > > executes all
> > > passes
> > > > > > > in pipeline starting from pass_startwith instead of just
> > > > > > > sub
> > > passes.
> > > > > > 
> > > > > > That looks good.  I wonder if
> > > > > > 
> > > > > > +  if (startwith_p && cfun->startwith)
> > > > > > +    {
> > > > > > +      if (pass->name == cfun->pass_startwith->name
> > > > > > +         || pass->name == "*clean_state")
> > > > > > 
> > > > > > need better be strcmp ()s though.  Also the early
> > > > > > optimization
> > > pipeline
> > > > > > should be executed with startwith support as well.
> > > > > > 
> > > > > 
> > > > > This patch adds startwith support for early opt passes. But
> > > > > for
> > > > > starting from some passes (like asan0, optimized) in
> > > > > all_passes
> > > > > pipeline, it falils at verify_curr_properties in
> > > > > execute_one_pass
> > > ().
> > > > > I wonder if we need to update properties after skipping each
> > > > > pass
> > > > 
> > > > Yeah, it's not possible to start at arbitrary points with
> > > > skipping
> > > passes
> > > > that provide a required property.  I suspect it's good enough
> > > > that
> > > we'll
> > > > ICE if that happens.
> > > > 
> > > > I see you are working on the dump-file side a bit now.  What is
> > > > still
> > > > missing after you got support for PHIs is parsing of SSA names.
> > > > Without this unit-testing will be difficult at best.
> > > > 
> > > > I think what we need to do is simplify the job of the parser
> > > > and
> > > > make the syntax we use to print SSA names a bit different.
> > > > So rather than printing VAR_VERSION we need to choose a
> > > > letter that is not part of a valid identifier before VERSION,
> > > > like a dot '.'.  Thus we'd have i.1 instead of i_1 and we'd
> > > > have
> > > > .2 instead of _2 for an anonymous SSA name.  The advantage
> > > > for non-anonymous names is that we can properly re-use the
> > > > C frontends decl handling for declaring and looking up 'i'.
> > > > The disadvantage is that for anonymous SSA names this isn't
> > > > so easy which means we could choose to not support those
> > > > for the moment and require fake decls for them.  In fact
> > > > into-SSA will do the correct thing if we just treat them as
> > > > decls,
> > > > thus continue to dump them as _VERSION.
> > > > 
> > > 
> > > I am little confused here about parsing 'i.1' because lexer drops
> > > DOT
> > > token for syntax like NAME.NUMBER . Hence instead of 'i.1' parser
> > > receives 'i1'
> > 
> > Are you sure? You should get three tokens, one for 'i', one for the
> > dot and
> > One for '1'.  You'd lookup the first via the C frontend symbol
> > table only.
> > 
> 
> Yes, I was also expecting that. For syntax like 'a.b' (ie name.name)
> it gives proper 3 tokens but for syntax like 'a.1' it produces only
> 2.
> 
> This is what I observed while debugging "int a.1;"
> 
> (gdb) print *c_parser_peek_nth_token (parser, 1)
> $3 = {type = CPP_KEYWORD, id_kind = C_ID_NONE, keyword = RID_INT,
>   pragma_kind = PRAGMA_NONE, location = 242114, value =
> 0x7ffff65c82d0}
> (gdb) print *c_parser_peek_nth_token (parser, 2)
> $4 = {type = CPP_NAME, id_kind = C_ID_ID, keyword = RID_MAX,
>   pragma_kind = PRAGMA_NONE, location = 242240, value =
> 0x7ffff66d0b90}
> (gdb) print *c_parser_peek_nth_token (parser, 3)
> $5 = {type = CPP_NUMBER, id_kind = C_ID_NONE, keyword = RID_MAX,
>   pragma_kind = PRAGMA_NONE, location = 242273, value =
> 0x7ffff66e0030}

What is the number?  I'm wondering if it's somehow been lexed as a
decimal ".1" i.e. if the "." is somehow being treated as part of the
CPP_NUMBER.

FWIW, I find hacking in calls to "inform" very useful for seeing what
each token is (assuming that caret printing isn't disabled).

  (gdb) call inform ($3->location, "")
  (gdb) call inform ($4->location, "")
  (gdb) call inform ($5
->location, "")

etc

BTW, does it have to be '.' as the SSA_NAME separator?  Could it be a different character e.g. '@' or something else that's non-legal in C?

Dave

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [gimplefe] hacking pass manager
  2016-07-18 21:06                           ` David Malcolm
@ 2016-07-19  5:35                             ` Richard Biener
  2016-07-19 20:09                               ` Prasad Ghangal
  0 siblings, 1 reply; 29+ messages in thread
From: Richard Biener @ 2016-07-19  5:35 UTC (permalink / raw)
  To: David Malcolm, Prasad Ghangal; +Cc: Prathamesh Kulkarni, gcc Mailing List

On July 18, 2016 11:05:58 PM GMT+02:00, David Malcolm <dmalcolm@redhat.com> wrote:
>On Tue, 2016-07-19 at 00:52 +0530, Prasad Ghangal wrote:
>> On 19 July 2016 at 00:25, Richard Biener <richard.guenther@gmail.com>
>> wrote:
>> > On July 18, 2016 8:28:15 PM GMT+02:00, Prasad Ghangal <
>> > prasad.ghangal@gmail.com> wrote:
>> > > On 15 July 2016 at 16:13, Richard Biener <
>> > > richard.guenther@gmail.com>
>> > > wrote:
>> > > > On Sun, Jul 10, 2016 at 6:13 PM, Prasad Ghangal
>> > > > <prasad.ghangal@gmail.com> wrote:
>> > > > > On 8 July 2016 at 13:13, Richard Biener <
>> > > > > richard.guenther@gmail.com>
>> > > wrote:
>> > > > > > On Thu, Jul 7, 2016 at 9:45 PM, Prasad Ghangal
>> > > <prasad.ghangal@gmail.com> wrote:
>> > > > > > > On 6 July 2016 at 14:24, Richard Biener
>> > > <richard.guenther@gmail.com> wrote:
>> > > > > > > > On Wed, Jul 6, 2016 at 9:51 AM, Prasad Ghangal
>> > > <prasad.ghangal@gmail.com> wrote:
>> > > > > > > > > On 30 June 2016 at 17:10, Richard Biener
>> > > <richard.guenther@gmail.com> wrote:
>> > > > > > > > > > On Wed, Jun 29, 2016 at 9:13 PM, Prasad Ghangal
>> > > > > > > > > > <prasad.ghangal@gmail.com> wrote:
>> > > > > > > > > > > On 29 June 2016 at 22:15, Richard Biener
>> > > <richard.guenther@gmail.com> wrote:
>> > > > > > > > > > > > On June 29, 2016 6:20:29 PM GMT+02:00,
>> > > > > > > > > > > > Prathamesh Kulkarni
>> > > <prathamesh.kulkarni@linaro.org> wrote:
>> > > > > > > > > > > > > On 18 June 2016 at 12:02, Prasad Ghangal
>> > > <prasad.ghangal@gmail.com>
>> > > > > > > > > > > > > wrote:
>> > > > > > > > > > > > > > Hi,
>> > > > > > > > > > > > > > 
>> > > > > > > > > > > > > > I tried hacking pass manager to execute
>> > > > > > > > > > > > > > only given passes.
>> > > For this I
>> > > > > > > > > > > > > > am adding new member as opt_pass
>> > > > > > > > > > > > > > *custom_pass_list to the
>> > > function
>> > > > > > > > > > > > > > structure to store passes need to execute
>> > > > > > > > > > > > > > and providing the
>> > > > > > > > > > > > > > custom_pass_list to execute_pass_list()
>> > > > > > > > > > > > > > function instead of
>> > > all
>> > > > > > > > > > > > > passes
>> > > > > > > > > > > > > > 
>> > > > > > > > > > > > > > for test case like-
>> > > > > > > > > > > > > > 
>> > > > > > > > > > > > > > int a;
>> > > > > > > > > > > > > > void __GIMPLE (execute ("tree-ccp1", "tree
>> > > > > > > > > > > > > > -fre1")) foo()
>> > > > > > > > > > > > > > {
>> > > > > > > > > > > > > > bb_1:
>> > > > > > > > > > > > > >   a = 1 + a;
>> > > > > > > > > > > > > > }
>> > > > > > > > > > > > > > 
>> > > > > > > > > > > > > > it will execute only given passes i.e. ccp1
>> > > > > > > > > > > > > > and fre1 pass
>> > > on the
>> > > > > > > > > > > > > function
>> > > > > > > > > > > > > > 
>> > > > > > > > > > > > > > and for test case like -
>> > > > > > > > > > > > > > 
>> > > > > > > > > > > > > > int a;
>> > > > > > > > > > > > > > void __GIMPLE (startwith ("tree-ccp1"))
>> > > > > > > > > > > > > > foo()
>> > > > > > > > > > > > > > {
>> > > > > > > > > > > > > > bb_1:
>> > > > > > > > > > > > > >   a = 1 + a;
>> > > > > > > > > > > > > > }
>> > > > > > > > > > > > > > 
>> > > > > > > > > > > > > > it will act as a entry point to the
>> > > > > > > > > > > > > > pipeline and will
>> > > execute passes
>> > > > > > > > > > > > > > starting from given pass.
>> > > > > > > > > > > > > Bike-shedding:
>> > > > > > > > > > > > > Would it make sense to have syntax for
>> > > > > > > > > > > > > defining pass ranges
>> > > to execute
>> > > > > > > > > > > > > ?
>> > > > > > > > > > > > > for instance:
>> > > > > > > > > > > > > void __GIMPLE(execute (pass_start :
>> > > > > > > > > > > > > pass_end))
>> > > > > > > > > > > > > which would execute all the passes within
>> > > > > > > > > > > > > range [pass_start,
>> > > pass_end],
>> > > > > > > > > > > > > which would be convenient if the range is
>> > > > > > > > > > > > > large.
>> > > > > > > > > > > > 
>> > > > > > > > > > > > But it would rely on a particular pass
>> > > > > > > > > > > > pipeline, f.e.
>> > > pass-start appearing before pass-end.
>> > > > > > > > > > > > 
>> > > > > > > > > > > > Currently control doesn't work 100% as it only
>> > > > > > > > > > > > replaces
>> > > all_optimizations but not lowering passes or early opts, nor IPA
>> > > opts.
>> > > > > > > > > > > > 
>> > > > > > > > > > > 
>> > > > > > > > > > > Each pass needs GIMPLE in some specific form. So
>> > > > > > > > > > > I am letting
>> > > lowering
>> > > > > > > > > > > and early opt passes to execute. I think we have
>> > > > > > > > > > > to execute
>> > > some
>> > > > > > > > > > > passes (like cfg) anyway to represent GIMPLE into
>> > > > > > > > > > > proper form
>> > > > > > > > > > 
>> > > > > > > > > > Yes, that's true.  Note that early opt passes only
>> > > > > > > > > > optimize but
>> > > we need
>> > > > > > > > > > pass_build_ssa_passes at least (for into-SSA).  For
>> > > > > > > > > > proper
>> > > unit-testing
>> > > > > > > > > > of GIMPLE passes we do need to guard off early opts
>> > > > > > > > > > somehow
>> > > > > > > > > > (I guess a simple if (flag_gimple && cfun
>> > > > > > > > > > ->custom_pass_list)
>> > > would do
>> > > > > > > > > > that).
>> > > > > > > > > > 
>> > > > > > > > > > Then there is of course the question about IPA
>> > > > > > > > > > passes which I
>> > > think is
>> > > > > > > > > > somewhat harder (one could always disable all IPA
>> > > > > > > > > > passes
>> > > manually
>> > > > > > > > > > via flags of course or finally have a global 
>> > > > > > > > > > -fipa/no-ipa like
>> > > most
>> > > > > > > > > > other compilers).
>> > > > > > > > > > 
>> > > > > > > > > Can we iterate through all ipa passes and do 
>> > > > > > > > > -fdisable-ipa-pass
>> > > or
>> > > > > > > > > -fenable-ipa-pass equivalent for each?
>> > > > > > > > 
>> > > > > > > > We could do that, yes.  But let's postpone this issue. 
>> > > > > > > >  I think
>> > > that
>> > > > > > > > startwith is going to be most useful and rather than
>> > > > > > > > constructing
>> > > > > > > > a pass list for it "native" support for it in the pass
>> > > > > > > > manager is
>> > > > > > > > likely to produce better results (add a 'startwith'
>> > > > > > > > member
>> > > alongside
>> > > > > > > > the pass list member and if it is set the pass manager
>> > > > > > > > skips all
>> > > > > > > > passes that do not match 'startwith' and once it
>> > > > > > > > reaches it it
>> > > clears
>> > > > > > > > the field).
>> > > > > > > > 
>> > > > > > > > In the future I hope we can get away from a static pass
>> > > > > > > > list and
>> > > more
>> > > > > > > > towards rule-driven pass execution (we have all those
>> > > > > > > > PROP_*
>> > > stuff
>> > > > > > > > already but it isn't really used for example).  But
>> > > > > > > > well, that
>> > > would be
>> > > > > > > > a separate GSoC project ;)
>> > > > > > > > 
>> > > > > > > > IMHO startwith will provide everything needed for unit
>> > > > > > > > -testing.
>> > > We can
>> > > > > > > > add a flag on whether further passes should be executed
>> > > > > > > > or not
>> > > and
>> > > > > > > > even a pass list like execute ("ccp1", "fre") can be
>> > > > > > > > implemented
>> > > by
>> > > > > > > > startwith ccp1 and then from there executing the rest
>> > > > > > > > of the
>> > > passes in the
>> > > > > > > > list and stopping at the end.
>> > > > > > > > 
>> > > > > > > > As said, unit-testing should exercise a single pass if
>> > > > > > > > we can
>> > > control
>> > > > > > > > its input.
>> > > > > > > > 
>> > > > > > > In this patch I am skipping execution of passes until
>> > > pass_startwith
>> > > > > > > is found. Unlike previous build, now pass manager
>> > > > > > > executes all
>> > > passes
>> > > > > > > in pipeline starting from pass_startwith instead of just
>> > > > > > > sub
>> > > passes.
>> > > > > > 
>> > > > > > That looks good.  I wonder if
>> > > > > > 
>> > > > > > +  if (startwith_p && cfun->startwith)
>> > > > > > +    {
>> > > > > > +      if (pass->name == cfun->pass_startwith->name
>> > > > > > +         || pass->name == "*clean_state")
>> > > > > > 
>> > > > > > need better be strcmp ()s though.  Also the early
>> > > > > > optimization
>> > > pipeline
>> > > > > > should be executed with startwith support as well.
>> > > > > > 
>> > > > > 
>> > > > > This patch adds startwith support for early opt passes. But
>> > > > > for
>> > > > > starting from some passes (like asan0, optimized) in
>> > > > > all_passes
>> > > > > pipeline, it falils at verify_curr_properties in
>> > > > > execute_one_pass
>> > > ().
>> > > > > I wonder if we need to update properties after skipping each
>> > > > > pass
>> > > > 
>> > > > Yeah, it's not possible to start at arbitrary points with
>> > > > skipping
>> > > passes
>> > > > that provide a required property.  I suspect it's good enough
>> > > > that
>> > > we'll
>> > > > ICE if that happens.
>> > > > 
>> > > > I see you are working on the dump-file side a bit now.  What is
>> > > > still
>> > > > missing after you got support for PHIs is parsing of SSA names.
>> > > > Without this unit-testing will be difficult at best.
>> > > > 
>> > > > I think what we need to do is simplify the job of the parser
>> > > > and
>> > > > make the syntax we use to print SSA names a bit different.
>> > > > So rather than printing VAR_VERSION we need to choose a
>> > > > letter that is not part of a valid identifier before VERSION,
>> > > > like a dot '.'.  Thus we'd have i.1 instead of i_1 and we'd
>> > > > have
>> > > > .2 instead of _2 for an anonymous SSA name.  The advantage
>> > > > for non-anonymous names is that we can properly re-use the
>> > > > C frontends decl handling for declaring and looking up 'i'.
>> > > > The disadvantage is that for anonymous SSA names this isn't
>> > > > so easy which means we could choose to not support those
>> > > > for the moment and require fake decls for them.  In fact
>> > > > into-SSA will do the correct thing if we just treat them as
>> > > > decls,
>> > > > thus continue to dump them as _VERSION.
>> > > > 
>> > > 
>> > > I am little confused here about parsing 'i.1' because lexer drops
>> > > DOT
>> > > token for syntax like NAME.NUMBER . Hence instead of 'i.1' parser
>> > > receives 'i1'
>> > 
>> > Are you sure? You should get three tokens, one for 'i', one for the
>> > dot and
>> > One for '1'.  You'd lookup the first via the C frontend symbol
>> > table only.
>> > 
>> 
>> Yes, I was also expecting that. For syntax like 'a.b' (ie name.name)
>> it gives proper 3 tokens but for syntax like 'a.1' it produces only
>> 2.
>> 
>> This is what I observed while debugging "int a.1;"
>> 
>> (gdb) print *c_parser_peek_nth_token (parser, 1)
>> $3 = {type = CPP_KEYWORD, id_kind = C_ID_NONE, keyword = RID_INT,
>>   pragma_kind = PRAGMA_NONE, location = 242114, value =
>> 0x7ffff65c82d0}
>> (gdb) print *c_parser_peek_nth_token (parser, 2)
>> $4 = {type = CPP_NAME, id_kind = C_ID_ID, keyword = RID_MAX,
>>   pragma_kind = PRAGMA_NONE, location = 242240, value =
>> 0x7ffff66d0b90}
>> (gdb) print *c_parser_peek_nth_token (parser, 3)
>> $5 = {type = CPP_NUMBER, id_kind = C_ID_NONE, keyword = RID_MAX,
>>   pragma_kind = PRAGMA_NONE, location = 242273, value =
>> 0x7ffff66e0030}
>
>What is the number?  I'm wondering if it's somehow been lexed as a
>decimal ".1" i.e. if the "." is somehow being treated as part of the
>CPP_NUMBER.

Ah, possible...

>FWIW, I find hacking in calls to "inform" very useful for seeing what
>each token is (assuming that caret printing isn't disabled).
>
>  (gdb) call inform ($3->location, "")
>  (gdb) call inform ($4->location, "")
>  (gdb) call inform ($5
>->location, "")
>
>etc
>
>BTW, does it have to be '.' as the SSA_NAME separator?  Could it be a
>different character e.g. '@' or something else that's non-legal in C?

It doesn't have to be '.', but sth visually not too disturbing would be nice.  If we don't go with '.' We can as well try to parse the SSA version from i_1, leaving the ambiguity with it being a valid C identifier.

Richard.

>Dave


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [gimplefe] hacking pass manager
  2016-07-19  5:35                             ` Richard Biener
@ 2016-07-19 20:09                               ` Prasad Ghangal
  2016-07-20 10:35                                 ` Richard Biener
  0 siblings, 1 reply; 29+ messages in thread
From: Prasad Ghangal @ 2016-07-19 20:09 UTC (permalink / raw)
  To: Richard Biener; +Cc: David Malcolm, Prathamesh Kulkarni, gcc Mailing List

On 19 July 2016 at 11:04, Richard Biener <richard.guenther@gmail.com> wrote:
> On July 18, 2016 11:05:58 PM GMT+02:00, David Malcolm <dmalcolm@redhat.com> wrote:
>>On Tue, 2016-07-19 at 00:52 +0530, Prasad Ghangal wrote:
>>> On 19 July 2016 at 00:25, Richard Biener <richard.guenther@gmail.com>
>>> wrote:
>>> > On July 18, 2016 8:28:15 PM GMT+02:00, Prasad Ghangal <
>>> > prasad.ghangal@gmail.com> wrote:
>>> > > On 15 July 2016 at 16:13, Richard Biener <
>>> > > richard.guenther@gmail.com>
>>> > > wrote:
>>> > > > On Sun, Jul 10, 2016 at 6:13 PM, Prasad Ghangal
>>> > > > <prasad.ghangal@gmail.com> wrote:
>>> > > > > On 8 July 2016 at 13:13, Richard Biener <
>>> > > > > richard.guenther@gmail.com>
>>> > > wrote:
>>> > > > > > On Thu, Jul 7, 2016 at 9:45 PM, Prasad Ghangal
>>> > > <prasad.ghangal@gmail.com> wrote:
>>> > > > > > > On 6 July 2016 at 14:24, Richard Biener
>>> > > <richard.guenther@gmail.com> wrote:
>>> > > > > > > > On Wed, Jul 6, 2016 at 9:51 AM, Prasad Ghangal
>>> > > <prasad.ghangal@gmail.com> wrote:
>>> > > > > > > > > On 30 June 2016 at 17:10, Richard Biener
>>> > > <richard.guenther@gmail.com> wrote:
>>> > > > > > > > > > On Wed, Jun 29, 2016 at 9:13 PM, Prasad Ghangal
>>> > > > > > > > > > <prasad.ghangal@gmail.com> wrote:
>>> > > > > > > > > > > On 29 June 2016 at 22:15, Richard Biener
>>> > > <richard.guenther@gmail.com> wrote:
>>> > > > > > > > > > > > On June 29, 2016 6:20:29 PM GMT+02:00,
>>> > > > > > > > > > > > Prathamesh Kulkarni
>>> > > <prathamesh.kulkarni@linaro.org> wrote:
>>> > > > > > > > > > > > > On 18 June 2016 at 12:02, Prasad Ghangal
>>> > > <prasad.ghangal@gmail.com>
>>> > > > > > > > > > > > > wrote:
>>> > > > > > > > > > > > > > Hi,
>>> > > > > > > > > > > > > >
>>> > > > > > > > > > > > > > I tried hacking pass manager to execute
>>> > > > > > > > > > > > > > only given passes.
>>> > > For this I
>>> > > > > > > > > > > > > > am adding new member as opt_pass
>>> > > > > > > > > > > > > > *custom_pass_list to the
>>> > > function
>>> > > > > > > > > > > > > > structure to store passes need to execute
>>> > > > > > > > > > > > > > and providing the
>>> > > > > > > > > > > > > > custom_pass_list to execute_pass_list()
>>> > > > > > > > > > > > > > function instead of
>>> > > all
>>> > > > > > > > > > > > > passes
>>> > > > > > > > > > > > > >
>>> > > > > > > > > > > > > > for test case like-
>>> > > > > > > > > > > > > >
>>> > > > > > > > > > > > > > int a;
>>> > > > > > > > > > > > > > void __GIMPLE (execute ("tree-ccp1", "tree
>>> > > > > > > > > > > > > > -fre1")) foo()
>>> > > > > > > > > > > > > > {
>>> > > > > > > > > > > > > > bb_1:
>>> > > > > > > > > > > > > >   a = 1 + a;
>>> > > > > > > > > > > > > > }
>>> > > > > > > > > > > > > >
>>> > > > > > > > > > > > > > it will execute only given passes i.e. ccp1
>>> > > > > > > > > > > > > > and fre1 pass
>>> > > on the
>>> > > > > > > > > > > > > function
>>> > > > > > > > > > > > > >
>>> > > > > > > > > > > > > > and for test case like -
>>> > > > > > > > > > > > > >
>>> > > > > > > > > > > > > > int a;
>>> > > > > > > > > > > > > > void __GIMPLE (startwith ("tree-ccp1"))
>>> > > > > > > > > > > > > > foo()
>>> > > > > > > > > > > > > > {
>>> > > > > > > > > > > > > > bb_1:
>>> > > > > > > > > > > > > >   a = 1 + a;
>>> > > > > > > > > > > > > > }
>>> > > > > > > > > > > > > >
>>> > > > > > > > > > > > > > it will act as a entry point to the
>>> > > > > > > > > > > > > > pipeline and will
>>> > > execute passes
>>> > > > > > > > > > > > > > starting from given pass.
>>> > > > > > > > > > > > > Bike-shedding:
>>> > > > > > > > > > > > > Would it make sense to have syntax for
>>> > > > > > > > > > > > > defining pass ranges
>>> > > to execute
>>> > > > > > > > > > > > > ?
>>> > > > > > > > > > > > > for instance:
>>> > > > > > > > > > > > > void __GIMPLE(execute (pass_start :
>>> > > > > > > > > > > > > pass_end))
>>> > > > > > > > > > > > > which would execute all the passes within
>>> > > > > > > > > > > > > range [pass_start,
>>> > > pass_end],
>>> > > > > > > > > > > > > which would be convenient if the range is
>>> > > > > > > > > > > > > large.
>>> > > > > > > > > > > >
>>> > > > > > > > > > > > But it would rely on a particular pass
>>> > > > > > > > > > > > pipeline, f.e.
>>> > > pass-start appearing before pass-end.
>>> > > > > > > > > > > >
>>> > > > > > > > > > > > Currently control doesn't work 100% as it only
>>> > > > > > > > > > > > replaces
>>> > > all_optimizations but not lowering passes or early opts, nor IPA
>>> > > opts.
>>> > > > > > > > > > > >
>>> > > > > > > > > > >
>>> > > > > > > > > > > Each pass needs GIMPLE in some specific form. So
>>> > > > > > > > > > > I am letting
>>> > > lowering
>>> > > > > > > > > > > and early opt passes to execute. I think we have
>>> > > > > > > > > > > to execute
>>> > > some
>>> > > > > > > > > > > passes (like cfg) anyway to represent GIMPLE into
>>> > > > > > > > > > > proper form
>>> > > > > > > > > >
>>> > > > > > > > > > Yes, that's true.  Note that early opt passes only
>>> > > > > > > > > > optimize but
>>> > > we need
>>> > > > > > > > > > pass_build_ssa_passes at least (for into-SSA).  For
>>> > > > > > > > > > proper
>>> > > unit-testing
>>> > > > > > > > > > of GIMPLE passes we do need to guard off early opts
>>> > > > > > > > > > somehow
>>> > > > > > > > > > (I guess a simple if (flag_gimple && cfun
>>> > > > > > > > > > ->custom_pass_list)
>>> > > would do
>>> > > > > > > > > > that).
>>> > > > > > > > > >
>>> > > > > > > > > > Then there is of course the question about IPA
>>> > > > > > > > > > passes which I
>>> > > think is
>>> > > > > > > > > > somewhat harder (one could always disable all IPA
>>> > > > > > > > > > passes
>>> > > manually
>>> > > > > > > > > > via flags of course or finally have a global
>>> > > > > > > > > > -fipa/no-ipa like
>>> > > most
>>> > > > > > > > > > other compilers).
>>> > > > > > > > > >
>>> > > > > > > > > Can we iterate through all ipa passes and do
>>> > > > > > > > > -fdisable-ipa-pass
>>> > > or
>>> > > > > > > > > -fenable-ipa-pass equivalent for each?
>>> > > > > > > >
>>> > > > > > > > We could do that, yes.  But let's postpone this issue.
>>> > > > > > > >  I think
>>> > > that
>>> > > > > > > > startwith is going to be most useful and rather than
>>> > > > > > > > constructing
>>> > > > > > > > a pass list for it "native" support for it in the pass
>>> > > > > > > > manager is
>>> > > > > > > > likely to produce better results (add a 'startwith'
>>> > > > > > > > member
>>> > > alongside
>>> > > > > > > > the pass list member and if it is set the pass manager
>>> > > > > > > > skips all
>>> > > > > > > > passes that do not match 'startwith' and once it
>>> > > > > > > > reaches it it
>>> > > clears
>>> > > > > > > > the field).
>>> > > > > > > >
>>> > > > > > > > In the future I hope we can get away from a static pass
>>> > > > > > > > list and
>>> > > more
>>> > > > > > > > towards rule-driven pass execution (we have all those
>>> > > > > > > > PROP_*
>>> > > stuff
>>> > > > > > > > already but it isn't really used for example).  But
>>> > > > > > > > well, that
>>> > > would be
>>> > > > > > > > a separate GSoC project ;)
>>> > > > > > > >
>>> > > > > > > > IMHO startwith will provide everything needed for unit
>>> > > > > > > > -testing.
>>> > > We can
>>> > > > > > > > add a flag on whether further passes should be executed
>>> > > > > > > > or not
>>> > > and
>>> > > > > > > > even a pass list like execute ("ccp1", "fre") can be
>>> > > > > > > > implemented
>>> > > by
>>> > > > > > > > startwith ccp1 and then from there executing the rest
>>> > > > > > > > of the
>>> > > passes in the
>>> > > > > > > > list and stopping at the end.
>>> > > > > > > >
>>> > > > > > > > As said, unit-testing should exercise a single pass if
>>> > > > > > > > we can
>>> > > control
>>> > > > > > > > its input.
>>> > > > > > > >
>>> > > > > > > In this patch I am skipping execution of passes until
>>> > > pass_startwith
>>> > > > > > > is found. Unlike previous build, now pass manager
>>> > > > > > > executes all
>>> > > passes
>>> > > > > > > in pipeline starting from pass_startwith instead of just
>>> > > > > > > sub
>>> > > passes.
>>> > > > > >
>>> > > > > > That looks good.  I wonder if
>>> > > > > >
>>> > > > > > +  if (startwith_p && cfun->startwith)
>>> > > > > > +    {
>>> > > > > > +      if (pass->name == cfun->pass_startwith->name
>>> > > > > > +         || pass->name == "*clean_state")
>>> > > > > >
>>> > > > > > need better be strcmp ()s though.  Also the early
>>> > > > > > optimization
>>> > > pipeline
>>> > > > > > should be executed with startwith support as well.
>>> > > > > >
>>> > > > >
>>> > > > > This patch adds startwith support for early opt passes. But
>>> > > > > for
>>> > > > > starting from some passes (like asan0, optimized) in
>>> > > > > all_passes
>>> > > > > pipeline, it falils at verify_curr_properties in
>>> > > > > execute_one_pass
>>> > > ().
>>> > > > > I wonder if we need to update properties after skipping each
>>> > > > > pass
>>> > > >
>>> > > > Yeah, it's not possible to start at arbitrary points with
>>> > > > skipping
>>> > > passes
>>> > > > that provide a required property.  I suspect it's good enough
>>> > > > that
>>> > > we'll
>>> > > > ICE if that happens.
>>> > > >
>>> > > > I see you are working on the dump-file side a bit now.  What is
>>> > > > still
>>> > > > missing after you got support for PHIs is parsing of SSA names.
>>> > > > Without this unit-testing will be difficult at best.
>>> > > >
>>> > > > I think what we need to do is simplify the job of the parser
>>> > > > and
>>> > > > make the syntax we use to print SSA names a bit different.
>>> > > > So rather than printing VAR_VERSION we need to choose a
>>> > > > letter that is not part of a valid identifier before VERSION,
>>> > > > like a dot '.'.  Thus we'd have i.1 instead of i_1 and we'd
>>> > > > have
>>> > > > .2 instead of _2 for an anonymous SSA name.  The advantage
>>> > > > for non-anonymous names is that we can properly re-use the
>>> > > > C frontends decl handling for declaring and looking up 'i'.
>>> > > > The disadvantage is that for anonymous SSA names this isn't
>>> > > > so easy which means we could choose to not support those
>>> > > > for the moment and require fake decls for them.  In fact
>>> > > > into-SSA will do the correct thing if we just treat them as
>>> > > > decls,
>>> > > > thus continue to dump them as _VERSION.
>>> > > >
>>> > >
>>> > > I am little confused here about parsing 'i.1' because lexer drops
>>> > > DOT
>>> > > token for syntax like NAME.NUMBER . Hence instead of 'i.1' parser
>>> > > receives 'i1'
>>> >
>>> > Are you sure? You should get three tokens, one for 'i', one for the
>>> > dot and
>>> > One for '1'.  You'd lookup the first via the C frontend symbol
>>> > table only.
>>> >
>>>
>>> Yes, I was also expecting that. For syntax like 'a.b' (ie name.name)
>>> it gives proper 3 tokens but for syntax like 'a.1' it produces only
>>> 2.
>>>
>>> This is what I observed while debugging "int a.1;"
>>>
>>> (gdb) print *c_parser_peek_nth_token (parser, 1)
>>> $3 = {type = CPP_KEYWORD, id_kind = C_ID_NONE, keyword = RID_INT,
>>>   pragma_kind = PRAGMA_NONE, location = 242114, value =
>>> 0x7ffff65c82d0}
>>> (gdb) print *c_parser_peek_nth_token (parser, 2)
>>> $4 = {type = CPP_NAME, id_kind = C_ID_ID, keyword = RID_MAX,
>>>   pragma_kind = PRAGMA_NONE, location = 242240, value =
>>> 0x7ffff66d0b90}
>>> (gdb) print *c_parser_peek_nth_token (parser, 3)
>>> $5 = {type = CPP_NUMBER, id_kind = C_ID_NONE, keyword = RID_MAX,
>>>   pragma_kind = PRAGMA_NONE, location = 242273, value =
>>> 0x7ffff66e0030}
>>
>>What is the number?  I'm wondering if it's somehow been lexed as a
>>decimal ".1" i.e. if the "." is somehow being treated as part of the
>>CPP_NUMBER.
>

Yes, the token '.1' is treated as CPP_NUMBER

> Ah, possible...
>
>>FWIW, I find hacking in calls to "inform" very useful for seeing what
>>each token is (assuming that caret printing isn't disabled).
>>
>>  (gdb) call inform ($3->location, "")
>>  (gdb) call inform ($4->location, "")
>>  (gdb) call inform ($5
>>->location, "")
>>
>>etc
>>
>>BTW, does it have to be '.' as the SSA_NAME separator?  Could it be a
>>different character e.g. '@' or something else that's non-legal in C?
>
> It doesn't have to be '.', but sth visually not too disturbing would be nice.  If we don't go with '.' We can as well try to parse the SSA version from i_1, leaving the ambiguity with it being a valid C identifier.
>

As special characters are not valid in C, I am using 'a..1' as syntax
for ssa name. For parsing I am using
+      lhs.value = make_ssa_name_fn (cfun,
+                                   lookup_name (c_parser_peek_token
(parser)->value),
+                                   NULL);
Now for passing ssa name into __PHI, how can we lookup for particular ssa name.
Or is there other better method to do it?

> Richard.
>
>>Dave
>
>

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [gimplefe] hacking pass manager
  2016-07-19 20:09                               ` Prasad Ghangal
@ 2016-07-20 10:35                                 ` Richard Biener
  2016-07-20 11:46                                   ` Prathamesh Kulkarni
  0 siblings, 1 reply; 29+ messages in thread
From: Richard Biener @ 2016-07-20 10:35 UTC (permalink / raw)
  To: Prasad Ghangal; +Cc: David Malcolm, Prathamesh Kulkarni, gcc Mailing List

On Tue, Jul 19, 2016 at 10:09 PM, Prasad Ghangal
<prasad.ghangal@gmail.com> wrote:
> On 19 July 2016 at 11:04, Richard Biener <richard.guenther@gmail.com> wrote:
>> On July 18, 2016 11:05:58 PM GMT+02:00, David Malcolm <dmalcolm@redhat.com> wrote:
>>>On Tue, 2016-07-19 at 00:52 +0530, Prasad Ghangal wrote:
>>>> On 19 July 2016 at 00:25, Richard Biener <richard.guenther@gmail.com>
>>>> wrote:
>>>> > On July 18, 2016 8:28:15 PM GMT+02:00, Prasad Ghangal <
>>>> > prasad.ghangal@gmail.com> wrote:
>>>> > > On 15 July 2016 at 16:13, Richard Biener <
>>>> > > richard.guenther@gmail.com>
>>>> > > wrote:
>>>> > > > On Sun, Jul 10, 2016 at 6:13 PM, Prasad Ghangal
>>>> > > > <prasad.ghangal@gmail.com> wrote:
>>>> > > > > On 8 July 2016 at 13:13, Richard Biener <
>>>> > > > > richard.guenther@gmail.com>
>>>> > > wrote:
>>>> > > > > > On Thu, Jul 7, 2016 at 9:45 PM, Prasad Ghangal
>>>> > > <prasad.ghangal@gmail.com> wrote:
>>>> > > > > > > On 6 July 2016 at 14:24, Richard Biener
>>>> > > <richard.guenther@gmail.com> wrote:
>>>> > > > > > > > On Wed, Jul 6, 2016 at 9:51 AM, Prasad Ghangal
>>>> > > <prasad.ghangal@gmail.com> wrote:
>>>> > > > > > > > > On 30 June 2016 at 17:10, Richard Biener
>>>> > > <richard.guenther@gmail.com> wrote:
>>>> > > > > > > > > > On Wed, Jun 29, 2016 at 9:13 PM, Prasad Ghangal
>>>> > > > > > > > > > <prasad.ghangal@gmail.com> wrote:
>>>> > > > > > > > > > > On 29 June 2016 at 22:15, Richard Biener
>>>> > > <richard.guenther@gmail.com> wrote:
>>>> > > > > > > > > > > > On June 29, 2016 6:20:29 PM GMT+02:00,
>>>> > > > > > > > > > > > Prathamesh Kulkarni
>>>> > > <prathamesh.kulkarni@linaro.org> wrote:
>>>> > > > > > > > > > > > > On 18 June 2016 at 12:02, Prasad Ghangal
>>>> > > <prasad.ghangal@gmail.com>
>>>> > > > > > > > > > > > > wrote:
>>>> > > > > > > > > > > > > > Hi,
>>>> > > > > > > > > > > > > >
>>>> > > > > > > > > > > > > > I tried hacking pass manager to execute
>>>> > > > > > > > > > > > > > only given passes.
>>>> > > For this I
>>>> > > > > > > > > > > > > > am adding new member as opt_pass
>>>> > > > > > > > > > > > > > *custom_pass_list to the
>>>> > > function
>>>> > > > > > > > > > > > > > structure to store passes need to execute
>>>> > > > > > > > > > > > > > and providing the
>>>> > > > > > > > > > > > > > custom_pass_list to execute_pass_list()
>>>> > > > > > > > > > > > > > function instead of
>>>> > > all
>>>> > > > > > > > > > > > > passes
>>>> > > > > > > > > > > > > >
>>>> > > > > > > > > > > > > > for test case like-
>>>> > > > > > > > > > > > > >
>>>> > > > > > > > > > > > > > int a;
>>>> > > > > > > > > > > > > > void __GIMPLE (execute ("tree-ccp1", "tree
>>>> > > > > > > > > > > > > > -fre1")) foo()
>>>> > > > > > > > > > > > > > {
>>>> > > > > > > > > > > > > > bb_1:
>>>> > > > > > > > > > > > > >   a = 1 + a;
>>>> > > > > > > > > > > > > > }
>>>> > > > > > > > > > > > > >
>>>> > > > > > > > > > > > > > it will execute only given passes i.e. ccp1
>>>> > > > > > > > > > > > > > and fre1 pass
>>>> > > on the
>>>> > > > > > > > > > > > > function
>>>> > > > > > > > > > > > > >
>>>> > > > > > > > > > > > > > and for test case like -
>>>> > > > > > > > > > > > > >
>>>> > > > > > > > > > > > > > int a;
>>>> > > > > > > > > > > > > > void __GIMPLE (startwith ("tree-ccp1"))
>>>> > > > > > > > > > > > > > foo()
>>>> > > > > > > > > > > > > > {
>>>> > > > > > > > > > > > > > bb_1:
>>>> > > > > > > > > > > > > >   a = 1 + a;
>>>> > > > > > > > > > > > > > }
>>>> > > > > > > > > > > > > >
>>>> > > > > > > > > > > > > > it will act as a entry point to the
>>>> > > > > > > > > > > > > > pipeline and will
>>>> > > execute passes
>>>> > > > > > > > > > > > > > starting from given pass.
>>>> > > > > > > > > > > > > Bike-shedding:
>>>> > > > > > > > > > > > > Would it make sense to have syntax for
>>>> > > > > > > > > > > > > defining pass ranges
>>>> > > to execute
>>>> > > > > > > > > > > > > ?
>>>> > > > > > > > > > > > > for instance:
>>>> > > > > > > > > > > > > void __GIMPLE(execute (pass_start :
>>>> > > > > > > > > > > > > pass_end))
>>>> > > > > > > > > > > > > which would execute all the passes within
>>>> > > > > > > > > > > > > range [pass_start,
>>>> > > pass_end],
>>>> > > > > > > > > > > > > which would be convenient if the range is
>>>> > > > > > > > > > > > > large.
>>>> > > > > > > > > > > >
>>>> > > > > > > > > > > > But it would rely on a particular pass
>>>> > > > > > > > > > > > pipeline, f.e.
>>>> > > pass-start appearing before pass-end.
>>>> > > > > > > > > > > >
>>>> > > > > > > > > > > > Currently control doesn't work 100% as it only
>>>> > > > > > > > > > > > replaces
>>>> > > all_optimizations but not lowering passes or early opts, nor IPA
>>>> > > opts.
>>>> > > > > > > > > > > >
>>>> > > > > > > > > > >
>>>> > > > > > > > > > > Each pass needs GIMPLE in some specific form. So
>>>> > > > > > > > > > > I am letting
>>>> > > lowering
>>>> > > > > > > > > > > and early opt passes to execute. I think we have
>>>> > > > > > > > > > > to execute
>>>> > > some
>>>> > > > > > > > > > > passes (like cfg) anyway to represent GIMPLE into
>>>> > > > > > > > > > > proper form
>>>> > > > > > > > > >
>>>> > > > > > > > > > Yes, that's true.  Note that early opt passes only
>>>> > > > > > > > > > optimize but
>>>> > > we need
>>>> > > > > > > > > > pass_build_ssa_passes at least (for into-SSA).  For
>>>> > > > > > > > > > proper
>>>> > > unit-testing
>>>> > > > > > > > > > of GIMPLE passes we do need to guard off early opts
>>>> > > > > > > > > > somehow
>>>> > > > > > > > > > (I guess a simple if (flag_gimple && cfun
>>>> > > > > > > > > > ->custom_pass_list)
>>>> > > would do
>>>> > > > > > > > > > that).
>>>> > > > > > > > > >
>>>> > > > > > > > > > Then there is of course the question about IPA
>>>> > > > > > > > > > passes which I
>>>> > > think is
>>>> > > > > > > > > > somewhat harder (one could always disable all IPA
>>>> > > > > > > > > > passes
>>>> > > manually
>>>> > > > > > > > > > via flags of course or finally have a global
>>>> > > > > > > > > > -fipa/no-ipa like
>>>> > > most
>>>> > > > > > > > > > other compilers).
>>>> > > > > > > > > >
>>>> > > > > > > > > Can we iterate through all ipa passes and do
>>>> > > > > > > > > -fdisable-ipa-pass
>>>> > > or
>>>> > > > > > > > > -fenable-ipa-pass equivalent for each?
>>>> > > > > > > >
>>>> > > > > > > > We could do that, yes.  But let's postpone this issue.
>>>> > > > > > > >  I think
>>>> > > that
>>>> > > > > > > > startwith is going to be most useful and rather than
>>>> > > > > > > > constructing
>>>> > > > > > > > a pass list for it "native" support for it in the pass
>>>> > > > > > > > manager is
>>>> > > > > > > > likely to produce better results (add a 'startwith'
>>>> > > > > > > > member
>>>> > > alongside
>>>> > > > > > > > the pass list member and if it is set the pass manager
>>>> > > > > > > > skips all
>>>> > > > > > > > passes that do not match 'startwith' and once it
>>>> > > > > > > > reaches it it
>>>> > > clears
>>>> > > > > > > > the field).
>>>> > > > > > > >
>>>> > > > > > > > In the future I hope we can get away from a static pass
>>>> > > > > > > > list and
>>>> > > more
>>>> > > > > > > > towards rule-driven pass execution (we have all those
>>>> > > > > > > > PROP_*
>>>> > > stuff
>>>> > > > > > > > already but it isn't really used for example).  But
>>>> > > > > > > > well, that
>>>> > > would be
>>>> > > > > > > > a separate GSoC project ;)
>>>> > > > > > > >
>>>> > > > > > > > IMHO startwith will provide everything needed for unit
>>>> > > > > > > > -testing.
>>>> > > We can
>>>> > > > > > > > add a flag on whether further passes should be executed
>>>> > > > > > > > or not
>>>> > > and
>>>> > > > > > > > even a pass list like execute ("ccp1", "fre") can be
>>>> > > > > > > > implemented
>>>> > > by
>>>> > > > > > > > startwith ccp1 and then from there executing the rest
>>>> > > > > > > > of the
>>>> > > passes in the
>>>> > > > > > > > list and stopping at the end.
>>>> > > > > > > >
>>>> > > > > > > > As said, unit-testing should exercise a single pass if
>>>> > > > > > > > we can
>>>> > > control
>>>> > > > > > > > its input.
>>>> > > > > > > >
>>>> > > > > > > In this patch I am skipping execution of passes until
>>>> > > pass_startwith
>>>> > > > > > > is found. Unlike previous build, now pass manager
>>>> > > > > > > executes all
>>>> > > passes
>>>> > > > > > > in pipeline starting from pass_startwith instead of just
>>>> > > > > > > sub
>>>> > > passes.
>>>> > > > > >
>>>> > > > > > That looks good.  I wonder if
>>>> > > > > >
>>>> > > > > > +  if (startwith_p && cfun->startwith)
>>>> > > > > > +    {
>>>> > > > > > +      if (pass->name == cfun->pass_startwith->name
>>>> > > > > > +         || pass->name == "*clean_state")
>>>> > > > > >
>>>> > > > > > need better be strcmp ()s though.  Also the early
>>>> > > > > > optimization
>>>> > > pipeline
>>>> > > > > > should be executed with startwith support as well.
>>>> > > > > >
>>>> > > > >
>>>> > > > > This patch adds startwith support for early opt passes. But
>>>> > > > > for
>>>> > > > > starting from some passes (like asan0, optimized) in
>>>> > > > > all_passes
>>>> > > > > pipeline, it falils at verify_curr_properties in
>>>> > > > > execute_one_pass
>>>> > > ().
>>>> > > > > I wonder if we need to update properties after skipping each
>>>> > > > > pass
>>>> > > >
>>>> > > > Yeah, it's not possible to start at arbitrary points with
>>>> > > > skipping
>>>> > > passes
>>>> > > > that provide a required property.  I suspect it's good enough
>>>> > > > that
>>>> > > we'll
>>>> > > > ICE if that happens.
>>>> > > >
>>>> > > > I see you are working on the dump-file side a bit now.  What is
>>>> > > > still
>>>> > > > missing after you got support for PHIs is parsing of SSA names.
>>>> > > > Without this unit-testing will be difficult at best.
>>>> > > >
>>>> > > > I think what we need to do is simplify the job of the parser
>>>> > > > and
>>>> > > > make the syntax we use to print SSA names a bit different.
>>>> > > > So rather than printing VAR_VERSION we need to choose a
>>>> > > > letter that is not part of a valid identifier before VERSION,
>>>> > > > like a dot '.'.  Thus we'd have i.1 instead of i_1 and we'd
>>>> > > > have
>>>> > > > .2 instead of _2 for an anonymous SSA name.  The advantage
>>>> > > > for non-anonymous names is that we can properly re-use the
>>>> > > > C frontends decl handling for declaring and looking up 'i'.
>>>> > > > The disadvantage is that for anonymous SSA names this isn't
>>>> > > > so easy which means we could choose to not support those
>>>> > > > for the moment and require fake decls for them.  In fact
>>>> > > > into-SSA will do the correct thing if we just treat them as
>>>> > > > decls,
>>>> > > > thus continue to dump them as _VERSION.
>>>> > > >
>>>> > >
>>>> > > I am little confused here about parsing 'i.1' because lexer drops
>>>> > > DOT
>>>> > > token for syntax like NAME.NUMBER . Hence instead of 'i.1' parser
>>>> > > receives 'i1'
>>>> >
>>>> > Are you sure? You should get three tokens, one for 'i', one for the
>>>> > dot and
>>>> > One for '1'.  You'd lookup the first via the C frontend symbol
>>>> > table only.
>>>> >
>>>>
>>>> Yes, I was also expecting that. For syntax like 'a.b' (ie name.name)
>>>> it gives proper 3 tokens but for syntax like 'a.1' it produces only
>>>> 2.
>>>>
>>>> This is what I observed while debugging "int a.1;"
>>>>
>>>> (gdb) print *c_parser_peek_nth_token (parser, 1)
>>>> $3 = {type = CPP_KEYWORD, id_kind = C_ID_NONE, keyword = RID_INT,
>>>>   pragma_kind = PRAGMA_NONE, location = 242114, value =
>>>> 0x7ffff65c82d0}
>>>> (gdb) print *c_parser_peek_nth_token (parser, 2)
>>>> $4 = {type = CPP_NAME, id_kind = C_ID_ID, keyword = RID_MAX,
>>>>   pragma_kind = PRAGMA_NONE, location = 242240, value =
>>>> 0x7ffff66d0b90}
>>>> (gdb) print *c_parser_peek_nth_token (parser, 3)
>>>> $5 = {type = CPP_NUMBER, id_kind = C_ID_NONE, keyword = RID_MAX,
>>>>   pragma_kind = PRAGMA_NONE, location = 242273, value =
>>>> 0x7ffff66e0030}
>>>
>>>What is the number?  I'm wondering if it's somehow been lexed as a
>>>decimal ".1" i.e. if the "." is somehow being treated as part of the
>>>CPP_NUMBER.
>>
>
> Yes, the token '.1' is treated as CPP_NUMBER
>
>> Ah, possible...
>>
>>>FWIW, I find hacking in calls to "inform" very useful for seeing what
>>>each token is (assuming that caret printing isn't disabled).
>>>
>>>  (gdb) call inform ($3->location, "")
>>>  (gdb) call inform ($4->location, "")
>>>  (gdb) call inform ($5
>>>->location, "")
>>>
>>>etc
>>>
>>>BTW, does it have to be '.' as the SSA_NAME separator?  Could it be a
>>>different character e.g. '@' or something else that's non-legal in C?
>>
>> It doesn't have to be '.', but sth visually not too disturbing would be nice.  If we don't go with '.' We can as well try to parse the SSA version from i_1, leaving the ambiguity with it being a valid C identifier.
>>
>
> As special characters are not valid in C, I am using 'a..1' as syntax
> for ssa name. For parsing I am using
> +      lhs.value = make_ssa_name_fn (cfun,
> +                                   lookup_name (c_parser_peek_token
> (parser)->value),
> +                                   NULL);
> Now for passing ssa name into __PHI, how can we lookup for particular ssa name.
> Or is there other better method to do it?

Note that with this you need to preserve SSA versions as used in the source
(the 1 in a..1).  If you can do that (see below) the way to lookup an SSA name
is simply calling 'ssa_name (version)' with version being an integer with the
version number.

make_ssa_name will simply allocate the next available SSA version so
you'll need to add an interface that allows you allocation of a specific
SSA version.  Like with sth similar to

Index: gcc/tree-ssanames.c
===================================================================
--- gcc/tree-ssanames.c (revision 238512)
+++ gcc/tree-ssanames.c (working copy)
@@ -255,7 +255,7 @@
    used without a preceding definition).  */

 tree
-make_ssa_name_fn (struct function *fn, tree var, gimple *stmt)
+make_ssa_name_fn (struct function *fn, tree var, gimple *stmt, int version)
 {
   tree t;
   use_operand_p imm;
@@ -265,8 +265,17 @@
              || TREE_CODE (var) == RESULT_DECL
              || (TYPE_P (var) && is_gimple_reg_type (var)));

+  if (version != 0)
+    {
+      t = make_node (SSA_NAME);
+      SSA_NAME_VERSION (t) = version;
+      vec_safe_grow_cleared (SSANAMES (fn), version + 1);
+      gcc_assert ((*SSANAMES (fn))[version] == NULL);
+      (*SSANAMES (fn))[version] = t;
+      ssa_name_nodes_created++;
+    }
   /* If our free list has an element, then use it.  */
-  if (!vec_safe_is_empty (FREE_SSANAMES (fn)))
+  else if (!vec_safe_is_empty (FREE_SSANAMES (fn)))
     {
       t = FREE_SSANAMES (fn)->pop ();
       ssa_name_nodes_reused++;
Index: gcc/tree-ssanames.h
===================================================================
--- gcc/tree-ssanames.h (revision 237253)
+++ gcc/tree-ssanames.h (working copy)
@@ -79,7 +79,7 @@
 extern void init_ssanames (struct function *, int);
 extern void fini_ssanames (struct function *);
 extern void ssanames_print_statistics (void);
-extern tree make_ssa_name_fn (struct function *, tree, gimple *);
+extern tree make_ssa_name_fn (struct function *, tree, gimple *, int);
 extern void release_ssa_name_fn (struct function *, tree);
 extern bool get_ptr_info_alignment (struct ptr_info_def *, unsigned int *,
                                    unsigned int *);

where you can then do sth like

  ssaname = ssa_name (version);
  if (!ssaname)
    ssaname = make_ssa_name_fn (cfun, lookup_name (...), NULL, version);

to either lookup an existing or allocate a new SSA name of the desired version.

Just for some bike-shedding, I don't like using '..' too much ;)

Richard.

>
>> Richard.
>>
>>>Dave
>>
>>

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [gimplefe] hacking pass manager
  2016-07-20 10:35                                 ` Richard Biener
@ 2016-07-20 11:46                                   ` Prathamesh Kulkarni
  2016-07-20 12:58                                     ` Richard Biener
  0 siblings, 1 reply; 29+ messages in thread
From: Prathamesh Kulkarni @ 2016-07-20 11:46 UTC (permalink / raw)
  To: Richard Biener; +Cc: Prasad Ghangal, David Malcolm, gcc Mailing List

On 20 July 2016 at 11:34, Richard Biener <richard.guenther@gmail.com> wrote:
> On Tue, Jul 19, 2016 at 10:09 PM, Prasad Ghangal
> <prasad.ghangal@gmail.com> wrote:
>> On 19 July 2016 at 11:04, Richard Biener <richard.guenther@gmail.com> wrote:
>>> On July 18, 2016 11:05:58 PM GMT+02:00, David Malcolm <dmalcolm@redhat.com> wrote:
>>>>On Tue, 2016-07-19 at 00:52 +0530, Prasad Ghangal wrote:
>>>>> On 19 July 2016 at 00:25, Richard Biener <richard.guenther@gmail.com>
>>>>> wrote:
>>>>> > On July 18, 2016 8:28:15 PM GMT+02:00, Prasad Ghangal <
>>>>> > prasad.ghangal@gmail.com> wrote:
>>>>> > > On 15 July 2016 at 16:13, Richard Biener <
>>>>> > > richard.guenther@gmail.com>
>>>>> > > wrote:
>>>>> > > > On Sun, Jul 10, 2016 at 6:13 PM, Prasad Ghangal
>>>>> > > > <prasad.ghangal@gmail.com> wrote:
>>>>> > > > > On 8 July 2016 at 13:13, Richard Biener <
>>>>> > > > > richard.guenther@gmail.com>
>>>>> > > wrote:
>>>>> > > > > > On Thu, Jul 7, 2016 at 9:45 PM, Prasad Ghangal
>>>>> > > <prasad.ghangal@gmail.com> wrote:
>>>>> > > > > > > On 6 July 2016 at 14:24, Richard Biener
>>>>> > > <richard.guenther@gmail.com> wrote:
>>>>> > > > > > > > On Wed, Jul 6, 2016 at 9:51 AM, Prasad Ghangal
>>>>> > > <prasad.ghangal@gmail.com> wrote:
>>>>> > > > > > > > > On 30 June 2016 at 17:10, Richard Biener
>>>>> > > <richard.guenther@gmail.com> wrote:
>>>>> > > > > > > > > > On Wed, Jun 29, 2016 at 9:13 PM, Prasad Ghangal
>>>>> > > > > > > > > > <prasad.ghangal@gmail.com> wrote:
>>>>> > > > > > > > > > > On 29 June 2016 at 22:15, Richard Biener
>>>>> > > <richard.guenther@gmail.com> wrote:
>>>>> > > > > > > > > > > > On June 29, 2016 6:20:29 PM GMT+02:00,
>>>>> > > > > > > > > > > > Prathamesh Kulkarni
>>>>> > > <prathamesh.kulkarni@linaro.org> wrote:
>>>>> > > > > > > > > > > > > On 18 June 2016 at 12:02, Prasad Ghangal
>>>>> > > <prasad.ghangal@gmail.com>
>>>>> > > > > > > > > > > > > wrote:
>>>>> > > > > > > > > > > > > > Hi,
>>>>> > > > > > > > > > > > > >
>>>>> > > > > > > > > > > > > > I tried hacking pass manager to execute
>>>>> > > > > > > > > > > > > > only given passes.
>>>>> > > For this I
>>>>> > > > > > > > > > > > > > am adding new member as opt_pass
>>>>> > > > > > > > > > > > > > *custom_pass_list to the
>>>>> > > function
>>>>> > > > > > > > > > > > > > structure to store passes need to execute
>>>>> > > > > > > > > > > > > > and providing the
>>>>> > > > > > > > > > > > > > custom_pass_list to execute_pass_list()
>>>>> > > > > > > > > > > > > > function instead of
>>>>> > > all
>>>>> > > > > > > > > > > > > passes
>>>>> > > > > > > > > > > > > >
>>>>> > > > > > > > > > > > > > for test case like-
>>>>> > > > > > > > > > > > > >
>>>>> > > > > > > > > > > > > > int a;
>>>>> > > > > > > > > > > > > > void __GIMPLE (execute ("tree-ccp1", "tree
>>>>> > > > > > > > > > > > > > -fre1")) foo()
>>>>> > > > > > > > > > > > > > {
>>>>> > > > > > > > > > > > > > bb_1:
>>>>> > > > > > > > > > > > > >   a = 1 + a;
>>>>> > > > > > > > > > > > > > }
>>>>> > > > > > > > > > > > > >
>>>>> > > > > > > > > > > > > > it will execute only given passes i.e. ccp1
>>>>> > > > > > > > > > > > > > and fre1 pass
>>>>> > > on the
>>>>> > > > > > > > > > > > > function
>>>>> > > > > > > > > > > > > >
>>>>> > > > > > > > > > > > > > and for test case like -
>>>>> > > > > > > > > > > > > >
>>>>> > > > > > > > > > > > > > int a;
>>>>> > > > > > > > > > > > > > void __GIMPLE (startwith ("tree-ccp1"))
>>>>> > > > > > > > > > > > > > foo()
>>>>> > > > > > > > > > > > > > {
>>>>> > > > > > > > > > > > > > bb_1:
>>>>> > > > > > > > > > > > > >   a = 1 + a;
>>>>> > > > > > > > > > > > > > }
>>>>> > > > > > > > > > > > > >
>>>>> > > > > > > > > > > > > > it will act as a entry point to the
>>>>> > > > > > > > > > > > > > pipeline and will
>>>>> > > execute passes
>>>>> > > > > > > > > > > > > > starting from given pass.
>>>>> > > > > > > > > > > > > Bike-shedding:
>>>>> > > > > > > > > > > > > Would it make sense to have syntax for
>>>>> > > > > > > > > > > > > defining pass ranges
>>>>> > > to execute
>>>>> > > > > > > > > > > > > ?
>>>>> > > > > > > > > > > > > for instance:
>>>>> > > > > > > > > > > > > void __GIMPLE(execute (pass_start :
>>>>> > > > > > > > > > > > > pass_end))
>>>>> > > > > > > > > > > > > which would execute all the passes within
>>>>> > > > > > > > > > > > > range [pass_start,
>>>>> > > pass_end],
>>>>> > > > > > > > > > > > > which would be convenient if the range is
>>>>> > > > > > > > > > > > > large.
>>>>> > > > > > > > > > > >
>>>>> > > > > > > > > > > > But it would rely on a particular pass
>>>>> > > > > > > > > > > > pipeline, f.e.
>>>>> > > pass-start appearing before pass-end.
>>>>> > > > > > > > > > > >
>>>>> > > > > > > > > > > > Currently control doesn't work 100% as it only
>>>>> > > > > > > > > > > > replaces
>>>>> > > all_optimizations but not lowering passes or early opts, nor IPA
>>>>> > > opts.
>>>>> > > > > > > > > > > >
>>>>> > > > > > > > > > >
>>>>> > > > > > > > > > > Each pass needs GIMPLE in some specific form. So
>>>>> > > > > > > > > > > I am letting
>>>>> > > lowering
>>>>> > > > > > > > > > > and early opt passes to execute. I think we have
>>>>> > > > > > > > > > > to execute
>>>>> > > some
>>>>> > > > > > > > > > > passes (like cfg) anyway to represent GIMPLE into
>>>>> > > > > > > > > > > proper form
>>>>> > > > > > > > > >
>>>>> > > > > > > > > > Yes, that's true.  Note that early opt passes only
>>>>> > > > > > > > > > optimize but
>>>>> > > we need
>>>>> > > > > > > > > > pass_build_ssa_passes at least (for into-SSA).  For
>>>>> > > > > > > > > > proper
>>>>> > > unit-testing
>>>>> > > > > > > > > > of GIMPLE passes we do need to guard off early opts
>>>>> > > > > > > > > > somehow
>>>>> > > > > > > > > > (I guess a simple if (flag_gimple && cfun
>>>>> > > > > > > > > > ->custom_pass_list)
>>>>> > > would do
>>>>> > > > > > > > > > that).
>>>>> > > > > > > > > >
>>>>> > > > > > > > > > Then there is of course the question about IPA
>>>>> > > > > > > > > > passes which I
>>>>> > > think is
>>>>> > > > > > > > > > somewhat harder (one could always disable all IPA
>>>>> > > > > > > > > > passes
>>>>> > > manually
>>>>> > > > > > > > > > via flags of course or finally have a global
>>>>> > > > > > > > > > -fipa/no-ipa like
>>>>> > > most
>>>>> > > > > > > > > > other compilers).
>>>>> > > > > > > > > >
>>>>> > > > > > > > > Can we iterate through all ipa passes and do
>>>>> > > > > > > > > -fdisable-ipa-pass
>>>>> > > or
>>>>> > > > > > > > > -fenable-ipa-pass equivalent for each?
>>>>> > > > > > > >
>>>>> > > > > > > > We could do that, yes.  But let's postpone this issue.
>>>>> > > > > > > >  I think
>>>>> > > that
>>>>> > > > > > > > startwith is going to be most useful and rather than
>>>>> > > > > > > > constructing
>>>>> > > > > > > > a pass list for it "native" support for it in the pass
>>>>> > > > > > > > manager is
>>>>> > > > > > > > likely to produce better results (add a 'startwith'
>>>>> > > > > > > > member
>>>>> > > alongside
>>>>> > > > > > > > the pass list member and if it is set the pass manager
>>>>> > > > > > > > skips all
>>>>> > > > > > > > passes that do not match 'startwith' and once it
>>>>> > > > > > > > reaches it it
>>>>> > > clears
>>>>> > > > > > > > the field).
>>>>> > > > > > > >
>>>>> > > > > > > > In the future I hope we can get away from a static pass
>>>>> > > > > > > > list and
>>>>> > > more
>>>>> > > > > > > > towards rule-driven pass execution (we have all those
>>>>> > > > > > > > PROP_*
>>>>> > > stuff
>>>>> > > > > > > > already but it isn't really used for example).  But
>>>>> > > > > > > > well, that
>>>>> > > would be
>>>>> > > > > > > > a separate GSoC project ;)
>>>>> > > > > > > >
>>>>> > > > > > > > IMHO startwith will provide everything needed for unit
>>>>> > > > > > > > -testing.
>>>>> > > We can
>>>>> > > > > > > > add a flag on whether further passes should be executed
>>>>> > > > > > > > or not
>>>>> > > and
>>>>> > > > > > > > even a pass list like execute ("ccp1", "fre") can be
>>>>> > > > > > > > implemented
>>>>> > > by
>>>>> > > > > > > > startwith ccp1 and then from there executing the rest
>>>>> > > > > > > > of the
>>>>> > > passes in the
>>>>> > > > > > > > list and stopping at the end.
>>>>> > > > > > > >
>>>>> > > > > > > > As said, unit-testing should exercise a single pass if
>>>>> > > > > > > > we can
>>>>> > > control
>>>>> > > > > > > > its input.
>>>>> > > > > > > >
>>>>> > > > > > > In this patch I am skipping execution of passes until
>>>>> > > pass_startwith
>>>>> > > > > > > is found. Unlike previous build, now pass manager
>>>>> > > > > > > executes all
>>>>> > > passes
>>>>> > > > > > > in pipeline starting from pass_startwith instead of just
>>>>> > > > > > > sub
>>>>> > > passes.
>>>>> > > > > >
>>>>> > > > > > That looks good.  I wonder if
>>>>> > > > > >
>>>>> > > > > > +  if (startwith_p && cfun->startwith)
>>>>> > > > > > +    {
>>>>> > > > > > +      if (pass->name == cfun->pass_startwith->name
>>>>> > > > > > +         || pass->name == "*clean_state")
>>>>> > > > > >
>>>>> > > > > > need better be strcmp ()s though.  Also the early
>>>>> > > > > > optimization
>>>>> > > pipeline
>>>>> > > > > > should be executed with startwith support as well.
>>>>> > > > > >
>>>>> > > > >
>>>>> > > > > This patch adds startwith support for early opt passes. But
>>>>> > > > > for
>>>>> > > > > starting from some passes (like asan0, optimized) in
>>>>> > > > > all_passes
>>>>> > > > > pipeline, it falils at verify_curr_properties in
>>>>> > > > > execute_one_pass
>>>>> > > ().
>>>>> > > > > I wonder if we need to update properties after skipping each
>>>>> > > > > pass
>>>>> > > >
>>>>> > > > Yeah, it's not possible to start at arbitrary points with
>>>>> > > > skipping
>>>>> > > passes
>>>>> > > > that provide a required property.  I suspect it's good enough
>>>>> > > > that
>>>>> > > we'll
>>>>> > > > ICE if that happens.
>>>>> > > >
>>>>> > > > I see you are working on the dump-file side a bit now.  What is
>>>>> > > > still
>>>>> > > > missing after you got support for PHIs is parsing of SSA names.
>>>>> > > > Without this unit-testing will be difficult at best.
>>>>> > > >
>>>>> > > > I think what we need to do is simplify the job of the parser
>>>>> > > > and
>>>>> > > > make the syntax we use to print SSA names a bit different.
>>>>> > > > So rather than printing VAR_VERSION we need to choose a
>>>>> > > > letter that is not part of a valid identifier before VERSION,
>>>>> > > > like a dot '.'.  Thus we'd have i.1 instead of i_1 and we'd
>>>>> > > > have
>>>>> > > > .2 instead of _2 for an anonymous SSA name.  The advantage
>>>>> > > > for non-anonymous names is that we can properly re-use the
>>>>> > > > C frontends decl handling for declaring and looking up 'i'.
>>>>> > > > The disadvantage is that for anonymous SSA names this isn't
>>>>> > > > so easy which means we could choose to not support those
>>>>> > > > for the moment and require fake decls for them.  In fact
>>>>> > > > into-SSA will do the correct thing if we just treat them as
>>>>> > > > decls,
>>>>> > > > thus continue to dump them as _VERSION.
>>>>> > > >
>>>>> > >
>>>>> > > I am little confused here about parsing 'i.1' because lexer drops
>>>>> > > DOT
>>>>> > > token for syntax like NAME.NUMBER . Hence instead of 'i.1' parser
>>>>> > > receives 'i1'
>>>>> >
>>>>> > Are you sure? You should get three tokens, one for 'i', one for the
>>>>> > dot and
>>>>> > One for '1'.  You'd lookup the first via the C frontend symbol
>>>>> > table only.
>>>>> >
>>>>>
>>>>> Yes, I was also expecting that. For syntax like 'a.b' (ie name.name)
>>>>> it gives proper 3 tokens but for syntax like 'a.1' it produces only
>>>>> 2.
>>>>>
>>>>> This is what I observed while debugging "int a.1;"
>>>>>
>>>>> (gdb) print *c_parser_peek_nth_token (parser, 1)
>>>>> $3 = {type = CPP_KEYWORD, id_kind = C_ID_NONE, keyword = RID_INT,
>>>>>   pragma_kind = PRAGMA_NONE, location = 242114, value =
>>>>> 0x7ffff65c82d0}
>>>>> (gdb) print *c_parser_peek_nth_token (parser, 2)
>>>>> $4 = {type = CPP_NAME, id_kind = C_ID_ID, keyword = RID_MAX,
>>>>>   pragma_kind = PRAGMA_NONE, location = 242240, value =
>>>>> 0x7ffff66d0b90}
>>>>> (gdb) print *c_parser_peek_nth_token (parser, 3)
>>>>> $5 = {type = CPP_NUMBER, id_kind = C_ID_NONE, keyword = RID_MAX,
>>>>>   pragma_kind = PRAGMA_NONE, location = 242273, value =
>>>>> 0x7ffff66e0030}
>>>>
>>>>What is the number?  I'm wondering if it's somehow been lexed as a
>>>>decimal ".1" i.e. if the "." is somehow being treated as part of the
>>>>CPP_NUMBER.
>>>
>>
>> Yes, the token '.1' is treated as CPP_NUMBER
>>
>>> Ah, possible...
>>>
>>>>FWIW, I find hacking in calls to "inform" very useful for seeing what
>>>>each token is (assuming that caret printing isn't disabled).
>>>>
>>>>  (gdb) call inform ($3->location, "")
>>>>  (gdb) call inform ($4->location, "")
>>>>  (gdb) call inform ($5
>>>>->location, "")
>>>>
>>>>etc
>>>>
>>>>BTW, does it have to be '.' as the SSA_NAME separator?  Could it be a
>>>>different character e.g. '@' or something else that's non-legal in C?
>>>
>>> It doesn't have to be '.', but sth visually not too disturbing would be nice.  If we don't go with '.' We can as well try to parse the SSA version from i_1, leaving the ambiguity with it being a valid C identifier.
>>>
>>
>> As special characters are not valid in C, I am using 'a..1' as syntax
>> for ssa name. For parsing I am using
>> +      lhs.value = make_ssa_name_fn (cfun,
>> +                                   lookup_name (c_parser_peek_token
>> (parser)->value),
>> +                                   NULL);
>> Now for passing ssa name into __PHI, how can we lookup for particular ssa name.
>> Or is there other better method to do it?
>
> Note that with this you need to preserve SSA versions as used in the source
> (the 1 in a..1).  If you can do that (see below) the way to lookup an SSA name
> is simply calling 'ssa_name (version)' with version being an integer with the
> version number.
>
> make_ssa_name will simply allocate the next available SSA version so
> you'll need to add an interface that allows you allocation of a specific
> SSA version.  Like with sth similar to
>
> Index: gcc/tree-ssanames.c
> ===================================================================
> --- gcc/tree-ssanames.c (revision 238512)
> +++ gcc/tree-ssanames.c (working copy)
> @@ -255,7 +255,7 @@
>     used without a preceding definition).  */
>
>  tree
> -make_ssa_name_fn (struct function *fn, tree var, gimple *stmt)
> +make_ssa_name_fn (struct function *fn, tree var, gimple *stmt, int version)
>  {
>    tree t;
>    use_operand_p imm;
> @@ -265,8 +265,17 @@
>               || TREE_CODE (var) == RESULT_DECL
>               || (TYPE_P (var) && is_gimple_reg_type (var)));
>
> +  if (version != 0)
> +    {
> +      t = make_node (SSA_NAME);
> +      SSA_NAME_VERSION (t) = version;
> +      vec_safe_grow_cleared (SSANAMES (fn), version + 1);
> +      gcc_assert ((*SSANAMES (fn))[version] == NULL);
> +      (*SSANAMES (fn))[version] = t;
> +      ssa_name_nodes_created++;
> +    }
>    /* If our free list has an element, then use it.  */
> -  if (!vec_safe_is_empty (FREE_SSANAMES (fn)))
> +  else if (!vec_safe_is_empty (FREE_SSANAMES (fn)))
>      {
>        t = FREE_SSANAMES (fn)->pop ();
>        ssa_name_nodes_reused++;
> Index: gcc/tree-ssanames.h
> ===================================================================
> --- gcc/tree-ssanames.h (revision 237253)
> +++ gcc/tree-ssanames.h (working copy)
> @@ -79,7 +79,7 @@
>  extern void init_ssanames (struct function *, int);
>  extern void fini_ssanames (struct function *);
>  extern void ssanames_print_statistics (void);
> -extern tree make_ssa_name_fn (struct function *, tree, gimple *);
> +extern tree make_ssa_name_fn (struct function *, tree, gimple *, int);
>  extern void release_ssa_name_fn (struct function *, tree);
>  extern bool get_ptr_info_alignment (struct ptr_info_def *, unsigned int *,
>                                     unsigned int *);
>
> where you can then do sth like
>
>   ssaname = ssa_name (version);
>   if (!ssaname)
>     ssaname = make_ssa_name_fn (cfun, lookup_name (...), NULL, version);
>
> to either lookup an existing or allocate a new SSA name of the desired version.
>
> Just for some bike-shedding, I don't like using '..' too much ;)
Would it be a good idea to modify libcpp's lexer to recognize
identifier.number as a single token if -fgimple is enabled ?

Thanks,
Prathamesh
>
> Richard.
>
>>
>>> Richard.
>>>
>>>>Dave
>>>
>>>

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [gimplefe] hacking pass manager
  2016-07-20 11:46                                   ` Prathamesh Kulkarni
@ 2016-07-20 12:58                                     ` Richard Biener
  2016-07-26 18:50                                       ` Prasad Ghangal
  0 siblings, 1 reply; 29+ messages in thread
From: Richard Biener @ 2016-07-20 12:58 UTC (permalink / raw)
  To: Prathamesh Kulkarni; +Cc: Prasad Ghangal, David Malcolm, gcc Mailing List

On Wed, Jul 20, 2016 at 1:46 PM, Prathamesh Kulkarni
<prathamesh.kulkarni@linaro.org> wrote:
> On 20 July 2016 at 11:34, Richard Biener <richard.guenther@gmail.com> wrote:
>> On Tue, Jul 19, 2016 at 10:09 PM, Prasad Ghangal
>> <prasad.ghangal@gmail.com> wrote:
>>> On 19 July 2016 at 11:04, Richard Biener <richard.guenther@gmail.com> wrote:
>>>> On July 18, 2016 11:05:58 PM GMT+02:00, David Malcolm <dmalcolm@redhat.com> wrote:
>>>>>On Tue, 2016-07-19 at 00:52 +0530, Prasad Ghangal wrote:
>>>>>> On 19 July 2016 at 00:25, Richard Biener <richard.guenther@gmail.com>
>>>>>> wrote:
>>>>>> > On July 18, 2016 8:28:15 PM GMT+02:00, Prasad Ghangal <
>>>>>> > prasad.ghangal@gmail.com> wrote:
>>>>>> > > On 15 July 2016 at 16:13, Richard Biener <
>>>>>> > > richard.guenther@gmail.com>
>>>>>> > > wrote:
>>>>>> > > > On Sun, Jul 10, 2016 at 6:13 PM, Prasad Ghangal
>>>>>> > > > <prasad.ghangal@gmail.com> wrote:
>>>>>> > > > > On 8 July 2016 at 13:13, Richard Biener <
>>>>>> > > > > richard.guenther@gmail.com>
>>>>>> > > wrote:
>>>>>> > > > > > On Thu, Jul 7, 2016 at 9:45 PM, Prasad Ghangal
>>>>>> > > <prasad.ghangal@gmail.com> wrote:
>>>>>> > > > > > > On 6 July 2016 at 14:24, Richard Biener
>>>>>> > > <richard.guenther@gmail.com> wrote:
>>>>>> > > > > > > > On Wed, Jul 6, 2016 at 9:51 AM, Prasad Ghangal
>>>>>> > > <prasad.ghangal@gmail.com> wrote:
>>>>>> > > > > > > > > On 30 June 2016 at 17:10, Richard Biener
>>>>>> > > <richard.guenther@gmail.com> wrote:
>>>>>> > > > > > > > > > On Wed, Jun 29, 2016 at 9:13 PM, Prasad Ghangal
>>>>>> > > > > > > > > > <prasad.ghangal@gmail.com> wrote:
>>>>>> > > > > > > > > > > On 29 June 2016 at 22:15, Richard Biener
>>>>>> > > <richard.guenther@gmail.com> wrote:
>>>>>> > > > > > > > > > > > On June 29, 2016 6:20:29 PM GMT+02:00,
>>>>>> > > > > > > > > > > > Prathamesh Kulkarni
>>>>>> > > <prathamesh.kulkarni@linaro.org> wrote:
>>>>>> > > > > > > > > > > > > On 18 June 2016 at 12:02, Prasad Ghangal
>>>>>> > > <prasad.ghangal@gmail.com>
>>>>>> > > > > > > > > > > > > wrote:
>>>>>> > > > > > > > > > > > > > Hi,
>>>>>> > > > > > > > > > > > > >
>>>>>> > > > > > > > > > > > > > I tried hacking pass manager to execute
>>>>>> > > > > > > > > > > > > > only given passes.
>>>>>> > > For this I
>>>>>> > > > > > > > > > > > > > am adding new member as opt_pass
>>>>>> > > > > > > > > > > > > > *custom_pass_list to the
>>>>>> > > function
>>>>>> > > > > > > > > > > > > > structure to store passes need to execute
>>>>>> > > > > > > > > > > > > > and providing the
>>>>>> > > > > > > > > > > > > > custom_pass_list to execute_pass_list()
>>>>>> > > > > > > > > > > > > > function instead of
>>>>>> > > all
>>>>>> > > > > > > > > > > > > passes
>>>>>> > > > > > > > > > > > > >
>>>>>> > > > > > > > > > > > > > for test case like-
>>>>>> > > > > > > > > > > > > >
>>>>>> > > > > > > > > > > > > > int a;
>>>>>> > > > > > > > > > > > > > void __GIMPLE (execute ("tree-ccp1", "tree
>>>>>> > > > > > > > > > > > > > -fre1")) foo()
>>>>>> > > > > > > > > > > > > > {
>>>>>> > > > > > > > > > > > > > bb_1:
>>>>>> > > > > > > > > > > > > >   a = 1 + a;
>>>>>> > > > > > > > > > > > > > }
>>>>>> > > > > > > > > > > > > >
>>>>>> > > > > > > > > > > > > > it will execute only given passes i.e. ccp1
>>>>>> > > > > > > > > > > > > > and fre1 pass
>>>>>> > > on the
>>>>>> > > > > > > > > > > > > function
>>>>>> > > > > > > > > > > > > >
>>>>>> > > > > > > > > > > > > > and for test case like -
>>>>>> > > > > > > > > > > > > >
>>>>>> > > > > > > > > > > > > > int a;
>>>>>> > > > > > > > > > > > > > void __GIMPLE (startwith ("tree-ccp1"))
>>>>>> > > > > > > > > > > > > > foo()
>>>>>> > > > > > > > > > > > > > {
>>>>>> > > > > > > > > > > > > > bb_1:
>>>>>> > > > > > > > > > > > > >   a = 1 + a;
>>>>>> > > > > > > > > > > > > > }
>>>>>> > > > > > > > > > > > > >
>>>>>> > > > > > > > > > > > > > it will act as a entry point to the
>>>>>> > > > > > > > > > > > > > pipeline and will
>>>>>> > > execute passes
>>>>>> > > > > > > > > > > > > > starting from given pass.
>>>>>> > > > > > > > > > > > > Bike-shedding:
>>>>>> > > > > > > > > > > > > Would it make sense to have syntax for
>>>>>> > > > > > > > > > > > > defining pass ranges
>>>>>> > > to execute
>>>>>> > > > > > > > > > > > > ?
>>>>>> > > > > > > > > > > > > for instance:
>>>>>> > > > > > > > > > > > > void __GIMPLE(execute (pass_start :
>>>>>> > > > > > > > > > > > > pass_end))
>>>>>> > > > > > > > > > > > > which would execute all the passes within
>>>>>> > > > > > > > > > > > > range [pass_start,
>>>>>> > > pass_end],
>>>>>> > > > > > > > > > > > > which would be convenient if the range is
>>>>>> > > > > > > > > > > > > large.
>>>>>> > > > > > > > > > > >
>>>>>> > > > > > > > > > > > But it would rely on a particular pass
>>>>>> > > > > > > > > > > > pipeline, f.e.
>>>>>> > > pass-start appearing before pass-end.
>>>>>> > > > > > > > > > > >
>>>>>> > > > > > > > > > > > Currently control doesn't work 100% as it only
>>>>>> > > > > > > > > > > > replaces
>>>>>> > > all_optimizations but not lowering passes or early opts, nor IPA
>>>>>> > > opts.
>>>>>> > > > > > > > > > > >
>>>>>> > > > > > > > > > >
>>>>>> > > > > > > > > > > Each pass needs GIMPLE in some specific form. So
>>>>>> > > > > > > > > > > I am letting
>>>>>> > > lowering
>>>>>> > > > > > > > > > > and early opt passes to execute. I think we have
>>>>>> > > > > > > > > > > to execute
>>>>>> > > some
>>>>>> > > > > > > > > > > passes (like cfg) anyway to represent GIMPLE into
>>>>>> > > > > > > > > > > proper form
>>>>>> > > > > > > > > >
>>>>>> > > > > > > > > > Yes, that's true.  Note that early opt passes only
>>>>>> > > > > > > > > > optimize but
>>>>>> > > we need
>>>>>> > > > > > > > > > pass_build_ssa_passes at least (for into-SSA).  For
>>>>>> > > > > > > > > > proper
>>>>>> > > unit-testing
>>>>>> > > > > > > > > > of GIMPLE passes we do need to guard off early opts
>>>>>> > > > > > > > > > somehow
>>>>>> > > > > > > > > > (I guess a simple if (flag_gimple && cfun
>>>>>> > > > > > > > > > ->custom_pass_list)
>>>>>> > > would do
>>>>>> > > > > > > > > > that).
>>>>>> > > > > > > > > >
>>>>>> > > > > > > > > > Then there is of course the question about IPA
>>>>>> > > > > > > > > > passes which I
>>>>>> > > think is
>>>>>> > > > > > > > > > somewhat harder (one could always disable all IPA
>>>>>> > > > > > > > > > passes
>>>>>> > > manually
>>>>>> > > > > > > > > > via flags of course or finally have a global
>>>>>> > > > > > > > > > -fipa/no-ipa like
>>>>>> > > most
>>>>>> > > > > > > > > > other compilers).
>>>>>> > > > > > > > > >
>>>>>> > > > > > > > > Can we iterate through all ipa passes and do
>>>>>> > > > > > > > > -fdisable-ipa-pass
>>>>>> > > or
>>>>>> > > > > > > > > -fenable-ipa-pass equivalent for each?
>>>>>> > > > > > > >
>>>>>> > > > > > > > We could do that, yes.  But let's postpone this issue.
>>>>>> > > > > > > >  I think
>>>>>> > > that
>>>>>> > > > > > > > startwith is going to be most useful and rather than
>>>>>> > > > > > > > constructing
>>>>>> > > > > > > > a pass list for it "native" support for it in the pass
>>>>>> > > > > > > > manager is
>>>>>> > > > > > > > likely to produce better results (add a 'startwith'
>>>>>> > > > > > > > member
>>>>>> > > alongside
>>>>>> > > > > > > > the pass list member and if it is set the pass manager
>>>>>> > > > > > > > skips all
>>>>>> > > > > > > > passes that do not match 'startwith' and once it
>>>>>> > > > > > > > reaches it it
>>>>>> > > clears
>>>>>> > > > > > > > the field).
>>>>>> > > > > > > >
>>>>>> > > > > > > > In the future I hope we can get away from a static pass
>>>>>> > > > > > > > list and
>>>>>> > > more
>>>>>> > > > > > > > towards rule-driven pass execution (we have all those
>>>>>> > > > > > > > PROP_*
>>>>>> > > stuff
>>>>>> > > > > > > > already but it isn't really used for example).  But
>>>>>> > > > > > > > well, that
>>>>>> > > would be
>>>>>> > > > > > > > a separate GSoC project ;)
>>>>>> > > > > > > >
>>>>>> > > > > > > > IMHO startwith will provide everything needed for unit
>>>>>> > > > > > > > -testing.
>>>>>> > > We can
>>>>>> > > > > > > > add a flag on whether further passes should be executed
>>>>>> > > > > > > > or not
>>>>>> > > and
>>>>>> > > > > > > > even a pass list like execute ("ccp1", "fre") can be
>>>>>> > > > > > > > implemented
>>>>>> > > by
>>>>>> > > > > > > > startwith ccp1 and then from there executing the rest
>>>>>> > > > > > > > of the
>>>>>> > > passes in the
>>>>>> > > > > > > > list and stopping at the end.
>>>>>> > > > > > > >
>>>>>> > > > > > > > As said, unit-testing should exercise a single pass if
>>>>>> > > > > > > > we can
>>>>>> > > control
>>>>>> > > > > > > > its input.
>>>>>> > > > > > > >
>>>>>> > > > > > > In this patch I am skipping execution of passes until
>>>>>> > > pass_startwith
>>>>>> > > > > > > is found. Unlike previous build, now pass manager
>>>>>> > > > > > > executes all
>>>>>> > > passes
>>>>>> > > > > > > in pipeline starting from pass_startwith instead of just
>>>>>> > > > > > > sub
>>>>>> > > passes.
>>>>>> > > > > >
>>>>>> > > > > > That looks good.  I wonder if
>>>>>> > > > > >
>>>>>> > > > > > +  if (startwith_p && cfun->startwith)
>>>>>> > > > > > +    {
>>>>>> > > > > > +      if (pass->name == cfun->pass_startwith->name
>>>>>> > > > > > +         || pass->name == "*clean_state")
>>>>>> > > > > >
>>>>>> > > > > > need better be strcmp ()s though.  Also the early
>>>>>> > > > > > optimization
>>>>>> > > pipeline
>>>>>> > > > > > should be executed with startwith support as well.
>>>>>> > > > > >
>>>>>> > > > >
>>>>>> > > > > This patch adds startwith support for early opt passes. But
>>>>>> > > > > for
>>>>>> > > > > starting from some passes (like asan0, optimized) in
>>>>>> > > > > all_passes
>>>>>> > > > > pipeline, it falils at verify_curr_properties in
>>>>>> > > > > execute_one_pass
>>>>>> > > ().
>>>>>> > > > > I wonder if we need to update properties after skipping each
>>>>>> > > > > pass
>>>>>> > > >
>>>>>> > > > Yeah, it's not possible to start at arbitrary points with
>>>>>> > > > skipping
>>>>>> > > passes
>>>>>> > > > that provide a required property.  I suspect it's good enough
>>>>>> > > > that
>>>>>> > > we'll
>>>>>> > > > ICE if that happens.
>>>>>> > > >
>>>>>> > > > I see you are working on the dump-file side a bit now.  What is
>>>>>> > > > still
>>>>>> > > > missing after you got support for PHIs is parsing of SSA names.
>>>>>> > > > Without this unit-testing will be difficult at best.
>>>>>> > > >
>>>>>> > > > I think what we need to do is simplify the job of the parser
>>>>>> > > > and
>>>>>> > > > make the syntax we use to print SSA names a bit different.
>>>>>> > > > So rather than printing VAR_VERSION we need to choose a
>>>>>> > > > letter that is not part of a valid identifier before VERSION,
>>>>>> > > > like a dot '.'.  Thus we'd have i.1 instead of i_1 and we'd
>>>>>> > > > have
>>>>>> > > > .2 instead of _2 for an anonymous SSA name.  The advantage
>>>>>> > > > for non-anonymous names is that we can properly re-use the
>>>>>> > > > C frontends decl handling for declaring and looking up 'i'.
>>>>>> > > > The disadvantage is that for anonymous SSA names this isn't
>>>>>> > > > so easy which means we could choose to not support those
>>>>>> > > > for the moment and require fake decls for them.  In fact
>>>>>> > > > into-SSA will do the correct thing if we just treat them as
>>>>>> > > > decls,
>>>>>> > > > thus continue to dump them as _VERSION.
>>>>>> > > >
>>>>>> > >
>>>>>> > > I am little confused here about parsing 'i.1' because lexer drops
>>>>>> > > DOT
>>>>>> > > token for syntax like NAME.NUMBER . Hence instead of 'i.1' parser
>>>>>> > > receives 'i1'
>>>>>> >
>>>>>> > Are you sure? You should get three tokens, one for 'i', one for the
>>>>>> > dot and
>>>>>> > One for '1'.  You'd lookup the first via the C frontend symbol
>>>>>> > table only.
>>>>>> >
>>>>>>
>>>>>> Yes, I was also expecting that. For syntax like 'a.b' (ie name.name)
>>>>>> it gives proper 3 tokens but for syntax like 'a.1' it produces only
>>>>>> 2.
>>>>>>
>>>>>> This is what I observed while debugging "int a.1;"
>>>>>>
>>>>>> (gdb) print *c_parser_peek_nth_token (parser, 1)
>>>>>> $3 = {type = CPP_KEYWORD, id_kind = C_ID_NONE, keyword = RID_INT,
>>>>>>   pragma_kind = PRAGMA_NONE, location = 242114, value =
>>>>>> 0x7ffff65c82d0}
>>>>>> (gdb) print *c_parser_peek_nth_token (parser, 2)
>>>>>> $4 = {type = CPP_NAME, id_kind = C_ID_ID, keyword = RID_MAX,
>>>>>>   pragma_kind = PRAGMA_NONE, location = 242240, value =
>>>>>> 0x7ffff66d0b90}
>>>>>> (gdb) print *c_parser_peek_nth_token (parser, 3)
>>>>>> $5 = {type = CPP_NUMBER, id_kind = C_ID_NONE, keyword = RID_MAX,
>>>>>>   pragma_kind = PRAGMA_NONE, location = 242273, value =
>>>>>> 0x7ffff66e0030}
>>>>>
>>>>>What is the number?  I'm wondering if it's somehow been lexed as a
>>>>>decimal ".1" i.e. if the "." is somehow being treated as part of the
>>>>>CPP_NUMBER.
>>>>
>>>
>>> Yes, the token '.1' is treated as CPP_NUMBER
>>>
>>>> Ah, possible...
>>>>
>>>>>FWIW, I find hacking in calls to "inform" very useful for seeing what
>>>>>each token is (assuming that caret printing isn't disabled).
>>>>>
>>>>>  (gdb) call inform ($3->location, "")
>>>>>  (gdb) call inform ($4->location, "")
>>>>>  (gdb) call inform ($5
>>>>>->location, "")
>>>>>
>>>>>etc
>>>>>
>>>>>BTW, does it have to be '.' as the SSA_NAME separator?  Could it be a
>>>>>different character e.g. '@' or something else that's non-legal in C?
>>>>
>>>> It doesn't have to be '.', but sth visually not too disturbing would be nice.  If we don't go with '.' We can as well try to parse the SSA version from i_1, leaving the ambiguity with it being a valid C identifier.
>>>>
>>>
>>> As special characters are not valid in C, I am using 'a..1' as syntax
>>> for ssa name. For parsing I am using
>>> +      lhs.value = make_ssa_name_fn (cfun,
>>> +                                   lookup_name (c_parser_peek_token
>>> (parser)->value),
>>> +                                   NULL);
>>> Now for passing ssa name into __PHI, how can we lookup for particular ssa name.
>>> Or is there other better method to do it?
>>
>> Note that with this you need to preserve SSA versions as used in the source
>> (the 1 in a..1).  If you can do that (see below) the way to lookup an SSA name
>> is simply calling 'ssa_name (version)' with version being an integer with the
>> version number.
>>
>> make_ssa_name will simply allocate the next available SSA version so
>> you'll need to add an interface that allows you allocation of a specific
>> SSA version.  Like with sth similar to
>>
>> Index: gcc/tree-ssanames.c
>> ===================================================================
>> --- gcc/tree-ssanames.c (revision 238512)
>> +++ gcc/tree-ssanames.c (working copy)
>> @@ -255,7 +255,7 @@
>>     used without a preceding definition).  */
>>
>>  tree
>> -make_ssa_name_fn (struct function *fn, tree var, gimple *stmt)
>> +make_ssa_name_fn (struct function *fn, tree var, gimple *stmt, int version)
>>  {
>>    tree t;
>>    use_operand_p imm;
>> @@ -265,8 +265,17 @@
>>               || TREE_CODE (var) == RESULT_DECL
>>               || (TYPE_P (var) && is_gimple_reg_type (var)));
>>
>> +  if (version != 0)
>> +    {
>> +      t = make_node (SSA_NAME);
>> +      SSA_NAME_VERSION (t) = version;
>> +      vec_safe_grow_cleared (SSANAMES (fn), version + 1);
>> +      gcc_assert ((*SSANAMES (fn))[version] == NULL);
>> +      (*SSANAMES (fn))[version] = t;
>> +      ssa_name_nodes_created++;
>> +    }
>>    /* If our free list has an element, then use it.  */
>> -  if (!vec_safe_is_empty (FREE_SSANAMES (fn)))
>> +  else if (!vec_safe_is_empty (FREE_SSANAMES (fn)))
>>      {
>>        t = FREE_SSANAMES (fn)->pop ();
>>        ssa_name_nodes_reused++;
>> Index: gcc/tree-ssanames.h
>> ===================================================================
>> --- gcc/tree-ssanames.h (revision 237253)
>> +++ gcc/tree-ssanames.h (working copy)
>> @@ -79,7 +79,7 @@
>>  extern void init_ssanames (struct function *, int);
>>  extern void fini_ssanames (struct function *);
>>  extern void ssanames_print_statistics (void);
>> -extern tree make_ssa_name_fn (struct function *, tree, gimple *);
>> +extern tree make_ssa_name_fn (struct function *, tree, gimple *, int);
>>  extern void release_ssa_name_fn (struct function *, tree);
>>  extern bool get_ptr_info_alignment (struct ptr_info_def *, unsigned int *,
>>                                     unsigned int *);
>>
>> where you can then do sth like
>>
>>   ssaname = ssa_name (version);
>>   if (!ssaname)
>>     ssaname = make_ssa_name_fn (cfun, lookup_name (...), NULL, version);
>>
>> to either lookup an existing or allocate a new SSA name of the desired version.
>>
>> Just for some bike-shedding, I don't like using '..' too much ;)
> Would it be a good idea to modify libcpp's lexer to recognize
> identifier.number as a single token if -fgimple is enabled ?

I don't think so.  As said, we can retain the i_2 syntax as well where you then
get a single token and to decide whether it is a SSA name do a lookup for
'i' first and if that succeeds, interpret _2 as a version suffix,
otherwise use it
as full variable name.  Re-constructing the 1 from .1 or 17 from .17 CPP_NUMBER
is possible as well of course.

Richard.

> Thanks,
> Prathamesh
>>
>> Richard.
>>
>>>
>>>> Richard.
>>>>
>>>>>Dave
>>>>
>>>>

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [gimplefe] hacking pass manager
  2016-07-20 12:58                                     ` Richard Biener
@ 2016-07-26 18:50                                       ` Prasad Ghangal
  2016-07-26 21:39                                         ` Prathamesh Kulkarni
  0 siblings, 1 reply; 29+ messages in thread
From: Prasad Ghangal @ 2016-07-26 18:50 UTC (permalink / raw)
  To: Richard Biener; +Cc: Prathamesh Kulkarni, David Malcolm, gcc Mailing List

[-- Attachment #1: Type: text/plain, Size: 18602 bytes --]

On 20 July 2016 at 18:28, Richard Biener <richard.guenther@gmail.com> wrote:
> On Wed, Jul 20, 2016 at 1:46 PM, Prathamesh Kulkarni
> <prathamesh.kulkarni@linaro.org> wrote:
>> On 20 July 2016 at 11:34, Richard Biener <richard.guenther@gmail.com> wrote:
>>> On Tue, Jul 19, 2016 at 10:09 PM, Prasad Ghangal
>>> <prasad.ghangal@gmail.com> wrote:
>>>> On 19 July 2016 at 11:04, Richard Biener <richard.guenther@gmail.com> wrote:
>>>>> On July 18, 2016 11:05:58 PM GMT+02:00, David Malcolm <dmalcolm@redhat.com> wrote:
>>>>>>On Tue, 2016-07-19 at 00:52 +0530, Prasad Ghangal wrote:
>>>>>>> On 19 July 2016 at 00:25, Richard Biener <richard.guenther@gmail.com>
>>>>>>> wrote:
>>>>>>> > On July 18, 2016 8:28:15 PM GMT+02:00, Prasad Ghangal <
>>>>>>> > prasad.ghangal@gmail.com> wrote:
>>>>>>> > > On 15 July 2016 at 16:13, Richard Biener <
>>>>>>> > > richard.guenther@gmail.com>
>>>>>>> > > wrote:
>>>>>>> > > > On Sun, Jul 10, 2016 at 6:13 PM, Prasad Ghangal
>>>>>>> > > > <prasad.ghangal@gmail.com> wrote:
>>>>>>> > > > > On 8 July 2016 at 13:13, Richard Biener <
>>>>>>> > > > > richard.guenther@gmail.com>
>>>>>>> > > wrote:
>>>>>>> > > > > > On Thu, Jul 7, 2016 at 9:45 PM, Prasad Ghangal
>>>>>>> > > <prasad.ghangal@gmail.com> wrote:
>>>>>>> > > > > > > On 6 July 2016 at 14:24, Richard Biener
>>>>>>> > > <richard.guenther@gmail.com> wrote:
>>>>>>> > > > > > > > On Wed, Jul 6, 2016 at 9:51 AM, Prasad Ghangal
>>>>>>> > > <prasad.ghangal@gmail.com> wrote:
>>>>>>> > > > > > > > > On 30 June 2016 at 17:10, Richard Biener
>>>>>>> > > <richard.guenther@gmail.com> wrote:
>>>>>>> > > > > > > > > > On Wed, Jun 29, 2016 at 9:13 PM, Prasad Ghangal
>>>>>>> > > > > > > > > > <prasad.ghangal@gmail.com> wrote:
>>>>>>> > > > > > > > > > > On 29 June 2016 at 22:15, Richard Biener
>>>>>>> > > <richard.guenther@gmail.com> wrote:
>>>>>>> > > > > > > > > > > > On June 29, 2016 6:20:29 PM GMT+02:00,
>>>>>>> > > > > > > > > > > > Prathamesh Kulkarni
>>>>>>> > > <prathamesh.kulkarni@linaro.org> wrote:
>>>>>>> > > > > > > > > > > > > On 18 June 2016 at 12:02, Prasad Ghangal
>>>>>>> > > <prasad.ghangal@gmail.com>
>>>>>>> > > > > > > > > > > > > wrote:
>>>>>>> > > > > > > > > > > > > > Hi,
>>>>>>> > > > > > > > > > > > > >
>>>>>>> > > > > > > > > > > > > > I tried hacking pass manager to execute
>>>>>>> > > > > > > > > > > > > > only given passes.
>>>>>>> > > For this I
>>>>>>> > > > > > > > > > > > > > am adding new member as opt_pass
>>>>>>> > > > > > > > > > > > > > *custom_pass_list to the
>>>>>>> > > function
>>>>>>> > > > > > > > > > > > > > structure to store passes need to execute
>>>>>>> > > > > > > > > > > > > > and providing the
>>>>>>> > > > > > > > > > > > > > custom_pass_list to execute_pass_list()
>>>>>>> > > > > > > > > > > > > > function instead of
>>>>>>> > > all
>>>>>>> > > > > > > > > > > > > passes
>>>>>>> > > > > > > > > > > > > >
>>>>>>> > > > > > > > > > > > > > for test case like-
>>>>>>> > > > > > > > > > > > > >
>>>>>>> > > > > > > > > > > > > > int a;
>>>>>>> > > > > > > > > > > > > > void __GIMPLE (execute ("tree-ccp1", "tree
>>>>>>> > > > > > > > > > > > > > -fre1")) foo()
>>>>>>> > > > > > > > > > > > > > {
>>>>>>> > > > > > > > > > > > > > bb_1:
>>>>>>> > > > > > > > > > > > > >   a = 1 + a;
>>>>>>> > > > > > > > > > > > > > }
>>>>>>> > > > > > > > > > > > > >
>>>>>>> > > > > > > > > > > > > > it will execute only given passes i.e. ccp1
>>>>>>> > > > > > > > > > > > > > and fre1 pass
>>>>>>> > > on the
>>>>>>> > > > > > > > > > > > > function
>>>>>>> > > > > > > > > > > > > >
>>>>>>> > > > > > > > > > > > > > and for test case like -
>>>>>>> > > > > > > > > > > > > >
>>>>>>> > > > > > > > > > > > > > int a;
>>>>>>> > > > > > > > > > > > > > void __GIMPLE (startwith ("tree-ccp1"))
>>>>>>> > > > > > > > > > > > > > foo()
>>>>>>> > > > > > > > > > > > > > {
>>>>>>> > > > > > > > > > > > > > bb_1:
>>>>>>> > > > > > > > > > > > > >   a = 1 + a;
>>>>>>> > > > > > > > > > > > > > }
>>>>>>> > > > > > > > > > > > > >
>>>>>>> > > > > > > > > > > > > > it will act as a entry point to the
>>>>>>> > > > > > > > > > > > > > pipeline and will
>>>>>>> > > execute passes
>>>>>>> > > > > > > > > > > > > > starting from given pass.
>>>>>>> > > > > > > > > > > > > Bike-shedding:
>>>>>>> > > > > > > > > > > > > Would it make sense to have syntax for
>>>>>>> > > > > > > > > > > > > defining pass ranges
>>>>>>> > > to execute
>>>>>>> > > > > > > > > > > > > ?
>>>>>>> > > > > > > > > > > > > for instance:
>>>>>>> > > > > > > > > > > > > void __GIMPLE(execute (pass_start :
>>>>>>> > > > > > > > > > > > > pass_end))
>>>>>>> > > > > > > > > > > > > which would execute all the passes within
>>>>>>> > > > > > > > > > > > > range [pass_start,
>>>>>>> > > pass_end],
>>>>>>> > > > > > > > > > > > > which would be convenient if the range is
>>>>>>> > > > > > > > > > > > > large.
>>>>>>> > > > > > > > > > > >
>>>>>>> > > > > > > > > > > > But it would rely on a particular pass
>>>>>>> > > > > > > > > > > > pipeline, f.e.
>>>>>>> > > pass-start appearing before pass-end.
>>>>>>> > > > > > > > > > > >
>>>>>>> > > > > > > > > > > > Currently control doesn't work 100% as it only
>>>>>>> > > > > > > > > > > > replaces
>>>>>>> > > all_optimizations but not lowering passes or early opts, nor IPA
>>>>>>> > > opts.
>>>>>>> > > > > > > > > > > >
>>>>>>> > > > > > > > > > >
>>>>>>> > > > > > > > > > > Each pass needs GIMPLE in some specific form. So
>>>>>>> > > > > > > > > > > I am letting
>>>>>>> > > lowering
>>>>>>> > > > > > > > > > > and early opt passes to execute. I think we have
>>>>>>> > > > > > > > > > > to execute
>>>>>>> > > some
>>>>>>> > > > > > > > > > > passes (like cfg) anyway to represent GIMPLE into
>>>>>>> > > > > > > > > > > proper form
>>>>>>> > > > > > > > > >
>>>>>>> > > > > > > > > > Yes, that's true.  Note that early opt passes only
>>>>>>> > > > > > > > > > optimize but
>>>>>>> > > we need
>>>>>>> > > > > > > > > > pass_build_ssa_passes at least (for into-SSA).  For
>>>>>>> > > > > > > > > > proper
>>>>>>> > > unit-testing
>>>>>>> > > > > > > > > > of GIMPLE passes we do need to guard off early opts
>>>>>>> > > > > > > > > > somehow
>>>>>>> > > > > > > > > > (I guess a simple if (flag_gimple && cfun
>>>>>>> > > > > > > > > > ->custom_pass_list)
>>>>>>> > > would do
>>>>>>> > > > > > > > > > that).
>>>>>>> > > > > > > > > >
>>>>>>> > > > > > > > > > Then there is of course the question about IPA
>>>>>>> > > > > > > > > > passes which I
>>>>>>> > > think is
>>>>>>> > > > > > > > > > somewhat harder (one could always disable all IPA
>>>>>>> > > > > > > > > > passes
>>>>>>> > > manually
>>>>>>> > > > > > > > > > via flags of course or finally have a global
>>>>>>> > > > > > > > > > -fipa/no-ipa like
>>>>>>> > > most
>>>>>>> > > > > > > > > > other compilers).
>>>>>>> > > > > > > > > >
>>>>>>> > > > > > > > > Can we iterate through all ipa passes and do
>>>>>>> > > > > > > > > -fdisable-ipa-pass
>>>>>>> > > or
>>>>>>> > > > > > > > > -fenable-ipa-pass equivalent for each?
>>>>>>> > > > > > > >
>>>>>>> > > > > > > > We could do that, yes.  But let's postpone this issue.
>>>>>>> > > > > > > >  I think
>>>>>>> > > that
>>>>>>> > > > > > > > startwith is going to be most useful and rather than
>>>>>>> > > > > > > > constructing
>>>>>>> > > > > > > > a pass list for it "native" support for it in the pass
>>>>>>> > > > > > > > manager is
>>>>>>> > > > > > > > likely to produce better results (add a 'startwith'
>>>>>>> > > > > > > > member
>>>>>>> > > alongside
>>>>>>> > > > > > > > the pass list member and if it is set the pass manager
>>>>>>> > > > > > > > skips all
>>>>>>> > > > > > > > passes that do not match 'startwith' and once it
>>>>>>> > > > > > > > reaches it it
>>>>>>> > > clears
>>>>>>> > > > > > > > the field).
>>>>>>> > > > > > > >
>>>>>>> > > > > > > > In the future I hope we can get away from a static pass
>>>>>>> > > > > > > > list and
>>>>>>> > > more
>>>>>>> > > > > > > > towards rule-driven pass execution (we have all those
>>>>>>> > > > > > > > PROP_*
>>>>>>> > > stuff
>>>>>>> > > > > > > > already but it isn't really used for example).  But
>>>>>>> > > > > > > > well, that
>>>>>>> > > would be
>>>>>>> > > > > > > > a separate GSoC project ;)
>>>>>>> > > > > > > >
>>>>>>> > > > > > > > IMHO startwith will provide everything needed for unit
>>>>>>> > > > > > > > -testing.
>>>>>>> > > We can
>>>>>>> > > > > > > > add a flag on whether further passes should be executed
>>>>>>> > > > > > > > or not
>>>>>>> > > and
>>>>>>> > > > > > > > even a pass list like execute ("ccp1", "fre") can be
>>>>>>> > > > > > > > implemented
>>>>>>> > > by
>>>>>>> > > > > > > > startwith ccp1 and then from there executing the rest
>>>>>>> > > > > > > > of the
>>>>>>> > > passes in the
>>>>>>> > > > > > > > list and stopping at the end.
>>>>>>> > > > > > > >
>>>>>>> > > > > > > > As said, unit-testing should exercise a single pass if
>>>>>>> > > > > > > > we can
>>>>>>> > > control
>>>>>>> > > > > > > > its input.
>>>>>>> > > > > > > >
>>>>>>> > > > > > > In this patch I am skipping execution of passes until
>>>>>>> > > pass_startwith
>>>>>>> > > > > > > is found. Unlike previous build, now pass manager
>>>>>>> > > > > > > executes all
>>>>>>> > > passes
>>>>>>> > > > > > > in pipeline starting from pass_startwith instead of just
>>>>>>> > > > > > > sub
>>>>>>> > > passes.
>>>>>>> > > > > >
>>>>>>> > > > > > That looks good.  I wonder if
>>>>>>> > > > > >
>>>>>>> > > > > > +  if (startwith_p && cfun->startwith)
>>>>>>> > > > > > +    {
>>>>>>> > > > > > +      if (pass->name == cfun->pass_startwith->name
>>>>>>> > > > > > +         || pass->name == "*clean_state")
>>>>>>> > > > > >
>>>>>>> > > > > > need better be strcmp ()s though.  Also the early
>>>>>>> > > > > > optimization
>>>>>>> > > pipeline
>>>>>>> > > > > > should be executed with startwith support as well.
>>>>>>> > > > > >
>>>>>>> > > > >
>>>>>>> > > > > This patch adds startwith support for early opt passes. But
>>>>>>> > > > > for
>>>>>>> > > > > starting from some passes (like asan0, optimized) in
>>>>>>> > > > > all_passes
>>>>>>> > > > > pipeline, it falils at verify_curr_properties in
>>>>>>> > > > > execute_one_pass
>>>>>>> > > ().
>>>>>>> > > > > I wonder if we need to update properties after skipping each
>>>>>>> > > > > pass
>>>>>>> > > >
>>>>>>> > > > Yeah, it's not possible to start at arbitrary points with
>>>>>>> > > > skipping
>>>>>>> > > passes
>>>>>>> > > > that provide a required property.  I suspect it's good enough
>>>>>>> > > > that
>>>>>>> > > we'll
>>>>>>> > > > ICE if that happens.
>>>>>>> > > >
>>>>>>> > > > I see you are working on the dump-file side a bit now.  What is
>>>>>>> > > > still
>>>>>>> > > > missing after you got support for PHIs is parsing of SSA names.
>>>>>>> > > > Without this unit-testing will be difficult at best.
>>>>>>> > > >
>>>>>>> > > > I think what we need to do is simplify the job of the parser
>>>>>>> > > > and
>>>>>>> > > > make the syntax we use to print SSA names a bit different.
>>>>>>> > > > So rather than printing VAR_VERSION we need to choose a
>>>>>>> > > > letter that is not part of a valid identifier before VERSION,
>>>>>>> > > > like a dot '.'.  Thus we'd have i.1 instead of i_1 and we'd
>>>>>>> > > > have
>>>>>>> > > > .2 instead of _2 for an anonymous SSA name.  The advantage
>>>>>>> > > > for non-anonymous names is that we can properly re-use the
>>>>>>> > > > C frontends decl handling for declaring and looking up 'i'.
>>>>>>> > > > The disadvantage is that for anonymous SSA names this isn't
>>>>>>> > > > so easy which means we could choose to not support those
>>>>>>> > > > for the moment and require fake decls for them.  In fact
>>>>>>> > > > into-SSA will do the correct thing if we just treat them as
>>>>>>> > > > decls,
>>>>>>> > > > thus continue to dump them as _VERSION.
>>>>>>> > > >
>>>>>>> > >
>>>>>>> > > I am little confused here about parsing 'i.1' because lexer drops
>>>>>>> > > DOT
>>>>>>> > > token for syntax like NAME.NUMBER . Hence instead of 'i.1' parser
>>>>>>> > > receives 'i1'
>>>>>>> >
>>>>>>> > Are you sure? You should get three tokens, one for 'i', one for the
>>>>>>> > dot and
>>>>>>> > One for '1'.  You'd lookup the first via the C frontend symbol
>>>>>>> > table only.
>>>>>>> >
>>>>>>>
>>>>>>> Yes, I was also expecting that. For syntax like 'a.b' (ie name.name)
>>>>>>> it gives proper 3 tokens but for syntax like 'a.1' it produces only
>>>>>>> 2.
>>>>>>>
>>>>>>> This is what I observed while debugging "int a.1;"
>>>>>>>
>>>>>>> (gdb) print *c_parser_peek_nth_token (parser, 1)
>>>>>>> $3 = {type = CPP_KEYWORD, id_kind = C_ID_NONE, keyword = RID_INT,
>>>>>>>   pragma_kind = PRAGMA_NONE, location = 242114, value =
>>>>>>> 0x7ffff65c82d0}
>>>>>>> (gdb) print *c_parser_peek_nth_token (parser, 2)
>>>>>>> $4 = {type = CPP_NAME, id_kind = C_ID_ID, keyword = RID_MAX,
>>>>>>>   pragma_kind = PRAGMA_NONE, location = 242240, value =
>>>>>>> 0x7ffff66d0b90}
>>>>>>> (gdb) print *c_parser_peek_nth_token (parser, 3)
>>>>>>> $5 = {type = CPP_NUMBER, id_kind = C_ID_NONE, keyword = RID_MAX,
>>>>>>>   pragma_kind = PRAGMA_NONE, location = 242273, value =
>>>>>>> 0x7ffff66e0030}
>>>>>>
>>>>>>What is the number?  I'm wondering if it's somehow been lexed as a
>>>>>>decimal ".1" i.e. if the "." is somehow being treated as part of the
>>>>>>CPP_NUMBER.
>>>>>
>>>>
>>>> Yes, the token '.1' is treated as CPP_NUMBER
>>>>
>>>>> Ah, possible...
>>>>>
>>>>>>FWIW, I find hacking in calls to "inform" very useful for seeing what
>>>>>>each token is (assuming that caret printing isn't disabled).
>>>>>>
>>>>>>  (gdb) call inform ($3->location, "")
>>>>>>  (gdb) call inform ($4->location, "")
>>>>>>  (gdb) call inform ($5
>>>>>>->location, "")
>>>>>>
>>>>>>etc
>>>>>>
>>>>>>BTW, does it have to be '.' as the SSA_NAME separator?  Could it be a
>>>>>>different character e.g. '@' or something else that's non-legal in C?
>>>>>
>>>>> It doesn't have to be '.', but sth visually not too disturbing would be nice.  If we don't go with '.' We can as well try to parse the SSA version from i_1, leaving the ambiguity with it being a valid C identifier.
>>>>>
>>>>
>>>> As special characters are not valid in C, I am using 'a..1' as syntax
>>>> for ssa name. For parsing I am using
>>>> +      lhs.value = make_ssa_name_fn (cfun,
>>>> +                                   lookup_name (c_parser_peek_token
>>>> (parser)->value),
>>>> +                                   NULL);
>>>> Now for passing ssa name into __PHI, how can we lookup for particular ssa name.
>>>> Or is there other better method to do it?
>>>
>>> Note that with this you need to preserve SSA versions as used in the source
>>> (the 1 in a..1).  If you can do that (see below) the way to lookup an SSA name
>>> is simply calling 'ssa_name (version)' with version being an integer with the
>>> version number.
>>>
>>> make_ssa_name will simply allocate the next available SSA version so
>>> you'll need to add an interface that allows you allocation of a specific
>>> SSA version.  Like with sth similar to
>>>
>>> Index: gcc/tree-ssanames.c
>>> ===================================================================
>>> --- gcc/tree-ssanames.c (revision 238512)
>>> +++ gcc/tree-ssanames.c (working copy)
>>> @@ -255,7 +255,7 @@
>>>     used without a preceding definition).  */
>>>
>>>  tree
>>> -make_ssa_name_fn (struct function *fn, tree var, gimple *stmt)
>>> +make_ssa_name_fn (struct function *fn, tree var, gimple *stmt, int version)
>>>  {
>>>    tree t;
>>>    use_operand_p imm;
>>> @@ -265,8 +265,17 @@
>>>               || TREE_CODE (var) == RESULT_DECL
>>>               || (TYPE_P (var) && is_gimple_reg_type (var)));
>>>
>>> +  if (version != 0)
>>> +    {
>>> +      t = make_node (SSA_NAME);
>>> +      SSA_NAME_VERSION (t) = version;
>>> +      vec_safe_grow_cleared (SSANAMES (fn), version + 1);
>>> +      gcc_assert ((*SSANAMES (fn))[version] == NULL);
>>> +      (*SSANAMES (fn))[version] = t;
>>> +      ssa_name_nodes_created++;
>>> +    }
>>>    /* If our free list has an element, then use it.  */
>>> -  if (!vec_safe_is_empty (FREE_SSANAMES (fn)))
>>> +  else if (!vec_safe_is_empty (FREE_SSANAMES (fn)))
>>>      {
>>>        t = FREE_SSANAMES (fn)->pop ();
>>>        ssa_name_nodes_reused++;
>>> Index: gcc/tree-ssanames.h
>>> ===================================================================
>>> --- gcc/tree-ssanames.h (revision 237253)
>>> +++ gcc/tree-ssanames.h (working copy)
>>> @@ -79,7 +79,7 @@
>>>  extern void init_ssanames (struct function *, int);
>>>  extern void fini_ssanames (struct function *);
>>>  extern void ssanames_print_statistics (void);
>>> -extern tree make_ssa_name_fn (struct function *, tree, gimple *);
>>> +extern tree make_ssa_name_fn (struct function *, tree, gimple *, int);
>>>  extern void release_ssa_name_fn (struct function *, tree);
>>>  extern bool get_ptr_info_alignment (struct ptr_info_def *, unsigned int *,
>>>                                     unsigned int *);
>>>
>>> where you can then do sth like
>>>
>>>   ssaname = ssa_name (version);
>>>   if (!ssaname)
>>>     ssaname = make_ssa_name_fn (cfun, lookup_name (...), NULL, version);
>>>
>>> to either lookup an existing or allocate a new SSA name of the desired version.
>>>
>>> Just for some bike-shedding, I don't like using '..' too much ;)
>> Would it be a good idea to modify libcpp's lexer to recognize
>> identifier.number as a single token if -fgimple is enabled ?
>
> I don't think so.  As said, we can retain the i_2 syntax as well where you then
> get a single token and to decide whether it is a SSA name do a lookup for
> 'i' first and if that succeeds, interpret _2 as a version suffix,
> otherwise use it
> as full variable name.  Re-constructing the 1 from .1 or 17 from .17 CPP_NUMBER
> is possible as well of course.
>

Sorry for the late response. I was little busy due to some family problem.

In this patch, I am parsing ssa names as described above. But the
problem is non ssa variable also gets renamed

for testcase :

void __GIMPLE () foo()
{
  int a;
bb_2:
  if (a > 4)
    goto bb_3;
  else
    goto bb_4;
bb_3:
  a_1 = 55;
  goto bb_5;

bb_4:
  a_2 = 99;

bb_5:
  a_3 = __PHI (bb_3: a_1, bb_4: a_2);
  a_4 = a_3 + 3;
  return;
}

I am getting ssa dump as:

/* Function foo (foo, funcdef_no=0, decl_uid=1744, cgraph_uid=0,
symbol_order=0)*/

void
foo ()
{
bb_2:
  if (a_5 > 4)
    goto bb_3;
  else
    goto bb_4;

bb_3:
  a_1 = 55;
  goto bb_5;

bb_4:
  a_2 = 99;

  a_3 = __PHI (bb_3: a_1, bb_4: a_2)
bb_5:
  a_4 = a_3 + 3;
  return;

}

> Richard.
>
>> Thanks,
>> Prathamesh
>>>
>>> Richard.
>>>
>>>>
>>>>> Richard.
>>>>>
>>>>>>Dave
>>>>>
>>>>>

[-- Attachment #2: ssa.patch --]
[-- Type: text/x-diff, Size: 8943 bytes --]

diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index 1a55b9a..17c1eb5 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -66,6 +66,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "gimple-pretty-print.h"
 #include "tree-ssa.h"
 #include "pass_manager.h"
+#include "tree-ssanames.h"
+#include "gimple-ssa.h"
 
 /* We need to walk over decls with incomplete struct/union/enum types
    after parsing the whole translation unit.
@@ -1666,7 +1668,7 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
   location_t here = c_parser_peek_token (parser)->location;
   bool gimple_body_p = false;
   opt_pass *pass = NULL;
-  bool startwith_p;
+  bool startwith_p = false;
 
   if (static_assert_ok
       && c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
@@ -1723,7 +1725,6 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
       if (kw_token->keyword == RID_GIMPLE)
 	{
 	  gimple_body_p = true;
-	  startwith_p = false;
 	  c_parser_consume_token (parser);
 	  c_parser_gimple_pass_list (parser, &pass, &startwith_p);
 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 
@@ -18145,7 +18146,7 @@ c_parser_parse_gimple_body (c_parser *parser)
   location_t loc1 = c_parser_peek_token (parser)->location;
   seq = NULL;
   body = NULL;
-  
+  init_tree_ssa (cfun);
   return_p = c_parser_gimple_compound_statement (parser, &seq);
 
   if (!return_p)
@@ -18173,7 +18174,6 @@ c_parser_parse_gimple_body (c_parser *parser)
   cfun->curr_properties = PROP_gimple_any;
   if (flag_gdebug)
     debug_gimple_seq (seq);
-  init_tree_ssa (cfun);
   return;
 }
 
@@ -18361,7 +18361,7 @@ c_parser_gimple_expression (c_parser *parser, gimple_seq *seq)
 
       gcall *call_stmt;
       /* Gimplify internal functions. */
-      tree arg;
+      tree arg = NULL_TREE;
       vec<tree> vargs = vNULL;
 
       if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
@@ -18386,7 +18386,29 @@ c_parser_gimple_expression (c_parser *parser, gimple_seq *seq)
 	    }
 	  else
 	    {
-	      arg = c_parser_gimple_unary_expression (parser).value;
+	      /* Parse ssa names */
+	      tree id;
+	      char *var_name, *var_version, *token;
+	      const char *ssa_token = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
+	      token = new char [strlen (ssa_token)];
+	      strcpy (token, ssa_token);
+	      var_name = strtok (token, "_");
+	      id = get_identifier (var_name);
+	      if (lookup_name (id))
+		{
+		  unsigned int version;
+		  var_version = strtok (NULL, "_");
+		  version = atoi (var_version);
+		  if (var_version && version)
+		    {
+		      arg = NULL_TREE;
+		      if (version < num_ssa_names)
+			arg = ssa_name (version);
+		      if (!arg)
+			arg = make_ssa_name_fn (cfun, lookup_name (id), gimple_build_nop (), version);
+		      c_parser_consume_token (parser);
+		    }
+		}
 	      vargs.safe_push (arg);
 	    }
 	}
@@ -18481,7 +18503,7 @@ c_parser_gimple_binary_expression (c_parser *parser, enum tree_code *subcode)
     sp--;								      \
   } while (0)
   stack[0].loc = c_parser_peek_token (parser)->location;
-  stack[0].expr = c_parser_cast_expression (parser, NULL);
+  stack[0].expr = c_parser_gimple_unary_expression (parser);
   stack[0].prec = PREC_NONE;
   sp = 0;
   enum c_parser_prec oprec;
@@ -18601,7 +18623,7 @@ c_parser_gimple_binary_expression (c_parser *parser, enum tree_code *subcode)
     }
   sp++;
   stack[sp].loc = binary_loc;
-  stack[sp].expr = c_parser_cast_expression (parser, NULL);
+  stack[sp].expr = c_parser_gimple_unary_expression (parser);
   stack[sp].prec = oprec;
   stack[sp].op = *subcode;
 out:
@@ -18618,6 +18640,34 @@ static c_expr
 c_parser_gimple_unary_expression (c_parser *parser)
 {
   struct c_expr ret, op;
+  /* Parse ssa names */
+  if (TREE_CODE (c_parser_peek_token (parser)->value) == IDENTIFIER_NODE
+      && !lookup_name (c_parser_peek_token (parser)->value))
+    {
+      tree id;
+      char *var_name, *var_version, *token;
+      const char *ssa_token = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
+      token = new char [strlen (ssa_token)];
+      strcpy (token, ssa_token);
+      var_name = strtok (token, "_");
+      id = get_identifier (var_name);
+      if (lookup_name (id))
+	{
+	  var_version = strtok (NULL, "_");
+	  unsigned int version;
+	  version = atoi (var_version);
+	  if (var_version && version)
+	    {
+	      ret.value = NULL_TREE;
+	      if (version < num_ssa_names)
+		ret.value = ssa_name (version);
+	      if (!ret.value)
+		ret.value = make_ssa_name_fn (cfun, lookup_name (id), gimple_build_nop (), version);
+	      c_parser_consume_token (parser);
+	    }
+	}
+      return ret;
+    }
   location_t op_loc = c_parser_peek_token (parser)->location;
   location_t exp_loc;
   location_t finish;
@@ -18868,7 +18918,7 @@ c_parser_gimple_pass_list_params (c_parser *parser, opt_pass **pass)
 
       if (c_parser_next_token_is (parser, CPP_STRING))
 	{
-	  const char *name = TREE_STRING_POINTER(c_parser_peek_token (parser)->value);
+	  const char *name = TREE_STRING_POINTER (c_parser_peek_token (parser)->value);
 	  c_parser_consume_token (parser);
 	  new_pass = g->get_passes ()->get_pass_by_name (name);
 
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index 8842cec..288e983 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -347,6 +347,7 @@ replace_loop_annotate (void)
 }
 
 /* Lower internal PHI function from GIMPLE FE */
+
 static void 
 lower_phi_internal_fn ()
 {
@@ -356,8 +357,8 @@ lower_phi_internal_fn ()
   gphi *phi_node;
   gimple *stmt;
   int len, capacity;
-  /* After edge creation, handle __PHI function from GIMPLE FE */
 
+  /* After edge creation, handle __PHI function from GIMPLE FE */
   FOR_EACH_BB_FN (bb, cfun)
     {
       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
@@ -368,12 +369,10 @@ lower_phi_internal_fn ()
 
 	  if (gimple_call_internal_p (stmt) && gimple_call_internal_fn (stmt) == IFN_PHI)
 	    {
-	     gsi_remove (&gsi, true);
+	      gsi_remove (&gsi, true);
 	      int i;
 	      lhs = gimple_call_lhs (stmt);
-	      
 	      phi_node = create_phi_node (lhs, bb);
-	      
 	      for (i = 0; i < gimple_call_num_args (stmt); ++i)
 		{
 		  tree arg = gimple_call_arg (stmt, i);
@@ -7625,7 +7624,7 @@ dump_function_to_file (tree fndecl, FILE *file, int flags)
 	for (ix = 1; ix < num_ssa_names; ++ix)
 	  {
 	    tree name = ssa_name (ix);
-	    if (!virtual_operand_p (name))
+	    if (name && !SSA_NAME_VAR (name))
 	      {
 		fprintf (file, "  ");
 		print_generic_expr (file, TREE_TYPE (name), flags);
diff --git a/gcc/tree-into-ssa.c b/gcc/tree-into-ssa.c
index 71150ac..b183b05 100644
--- a/gcc/tree-into-ssa.c
+++ b/gcc/tree-into-ssa.c
@@ -1386,7 +1386,8 @@ rewrite_add_phi_arguments (basic_block bb)
 	  /* If we have pre-existing PHI its args may be different 
 	     vars than existing vars */
 	  argvar = gimple_phi_arg_def (phi, e->dest_idx);
-	  gcc_assert (!argvar || TREE_CODE (argvar) != SSA_NAME);
+	  if (TREE_CODE (argvar) == SSA_NAME)
+	    continue;
 	  if (!argvar)
 	    argvar = SSA_NAME_VAR (res);
 	  currdef = get_reaching_def (argvar);
diff --git a/gcc/tree-ssanames.c b/gcc/tree-ssanames.c
index 91a8f97..c85eda2 100644
--- a/gcc/tree-ssanames.c
+++ b/gcc/tree-ssanames.c
@@ -255,7 +255,7 @@ flush_ssaname_freelist (void)
    used without a preceding definition).  */
 
 tree
-make_ssa_name_fn (struct function *fn, tree var, gimple *stmt)
+make_ssa_name_fn (struct function *fn, tree var, gimple *stmt, int version)
 {
   tree t;
   use_operand_p imm;
@@ -265,8 +265,17 @@ make_ssa_name_fn (struct function *fn, tree var, gimple *stmt)
 	      || TREE_CODE (var) == RESULT_DECL
 	      || (TYPE_P (var) && is_gimple_reg_type (var)));
 
+  if (version != 0)
+    {
+      t = make_node (SSA_NAME);
+      SSA_NAME_VERSION (t) = version;
+      vec_safe_grow_cleared (SSANAMES (fn), version + 1);
+      gcc_assert ((*SSANAMES (fn))[version] == NULL);
+      (*SSANAMES (fn))[version] = t;
+      ssa_name_nodes_created++;
+    }
   /* If our free list has an element, then use it.  */
-  if (!vec_safe_is_empty (FREE_SSANAMES (fn)))
+  else if (!vec_safe_is_empty (FREE_SSANAMES (fn)))
     {
       t = FREE_SSANAMES (fn)->pop ();
       ssa_name_nodes_reused++;
diff --git a/gcc/tree-ssanames.h b/gcc/tree-ssanames.h
index c81b1a1..0034ae0 100644
--- a/gcc/tree-ssanames.h
+++ b/gcc/tree-ssanames.h
@@ -79,7 +79,7 @@ extern bool ssa_name_has_boolean_range (tree);
 extern void init_ssanames (struct function *, int);
 extern void fini_ssanames (struct function *);
 extern void ssanames_print_statistics (void);
-extern tree make_ssa_name_fn (struct function *, tree, gimple *);
+extern tree make_ssa_name_fn (struct function *, tree, gimple *, int version = 0);
 extern void release_ssa_name_fn (struct function *, tree);
 extern bool get_ptr_info_alignment (struct ptr_info_def *, unsigned int *,
 				    unsigned int *);

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [gimplefe] hacking pass manager
  2016-07-26 18:50                                       ` Prasad Ghangal
@ 2016-07-26 21:39                                         ` Prathamesh Kulkarni
  2016-07-27  8:53                                           ` Richard Biener
  0 siblings, 1 reply; 29+ messages in thread
From: Prathamesh Kulkarni @ 2016-07-26 21:39 UTC (permalink / raw)
  To: Prasad Ghangal; +Cc: Richard Biener, David Malcolm, gcc Mailing List

On 27 July 2016 at 00:20, Prasad Ghangal <prasad.ghangal@gmail.com> wrote:
> On 20 July 2016 at 18:28, Richard Biener <richard.guenther@gmail.com> wrote:
>> On Wed, Jul 20, 2016 at 1:46 PM, Prathamesh Kulkarni
>> <prathamesh.kulkarni@linaro.org> wrote:
>>> On 20 July 2016 at 11:34, Richard Biener <richard.guenther@gmail.com> wrote:
>>>> On Tue, Jul 19, 2016 at 10:09 PM, Prasad Ghangal
>>>> <prasad.ghangal@gmail.com> wrote:
>>>>> On 19 July 2016 at 11:04, Richard Biener <richard.guenther@gmail.com> wrote:
>>>>>> On July 18, 2016 11:05:58 PM GMT+02:00, David Malcolm <dmalcolm@redhat.com> wrote:
>>>>>>>On Tue, 2016-07-19 at 00:52 +0530, Prasad Ghangal wrote:
>>>>>>>> On 19 July 2016 at 00:25, Richard Biener <richard.guenther@gmail.com>
>>>>>>>> wrote:
>>>>>>>> > On July 18, 2016 8:28:15 PM GMT+02:00, Prasad Ghangal <
>>>>>>>> > prasad.ghangal@gmail.com> wrote:
>>>>>>>> > > On 15 July 2016 at 16:13, Richard Biener <
>>>>>>>> > > richard.guenther@gmail.com>
>>>>>>>> > > wrote:
>>>>>>>> > > > On Sun, Jul 10, 2016 at 6:13 PM, Prasad Ghangal
>>>>>>>> > > > <prasad.ghangal@gmail.com> wrote:
>>>>>>>> > > > > On 8 July 2016 at 13:13, Richard Biener <
>>>>>>>> > > > > richard.guenther@gmail.com>
>>>>>>>> > > wrote:
>>>>>>>> > > > > > On Thu, Jul 7, 2016 at 9:45 PM, Prasad Ghangal
>>>>>>>> > > <prasad.ghangal@gmail.com> wrote:
>>>>>>>> > > > > > > On 6 July 2016 at 14:24, Richard Biener
>>>>>>>> > > <richard.guenther@gmail.com> wrote:
>>>>>>>> > > > > > > > On Wed, Jul 6, 2016 at 9:51 AM, Prasad Ghangal
>>>>>>>> > > <prasad.ghangal@gmail.com> wrote:
>>>>>>>> > > > > > > > > On 30 June 2016 at 17:10, Richard Biener
>>>>>>>> > > <richard.guenther@gmail.com> wrote:
>>>>>>>> > > > > > > > > > On Wed, Jun 29, 2016 at 9:13 PM, Prasad Ghangal
>>>>>>>> > > > > > > > > > <prasad.ghangal@gmail.com> wrote:
>>>>>>>> > > > > > > > > > > On 29 June 2016 at 22:15, Richard Biener
>>>>>>>> > > <richard.guenther@gmail.com> wrote:
>>>>>>>> > > > > > > > > > > > On June 29, 2016 6:20:29 PM GMT+02:00,
>>>>>>>> > > > > > > > > > > > Prathamesh Kulkarni
>>>>>>>> > > <prathamesh.kulkarni@linaro.org> wrote:
>>>>>>>> > > > > > > > > > > > > On 18 June 2016 at 12:02, Prasad Ghangal
>>>>>>>> > > <prasad.ghangal@gmail.com>
>>>>>>>> > > > > > > > > > > > > wrote:
>>>>>>>> > > > > > > > > > > > > > Hi,
>>>>>>>> > > > > > > > > > > > > >
>>>>>>>> > > > > > > > > > > > > > I tried hacking pass manager to execute
>>>>>>>> > > > > > > > > > > > > > only given passes.
>>>>>>>> > > For this I
>>>>>>>> > > > > > > > > > > > > > am adding new member as opt_pass
>>>>>>>> > > > > > > > > > > > > > *custom_pass_list to the
>>>>>>>> > > function
>>>>>>>> > > > > > > > > > > > > > structure to store passes need to execute
>>>>>>>> > > > > > > > > > > > > > and providing the
>>>>>>>> > > > > > > > > > > > > > custom_pass_list to execute_pass_list()
>>>>>>>> > > > > > > > > > > > > > function instead of
>>>>>>>> > > all
>>>>>>>> > > > > > > > > > > > > passes
>>>>>>>> > > > > > > > > > > > > >
>>>>>>>> > > > > > > > > > > > > > for test case like-
>>>>>>>> > > > > > > > > > > > > >
>>>>>>>> > > > > > > > > > > > > > int a;
>>>>>>>> > > > > > > > > > > > > > void __GIMPLE (execute ("tree-ccp1", "tree
>>>>>>>> > > > > > > > > > > > > > -fre1")) foo()
>>>>>>>> > > > > > > > > > > > > > {
>>>>>>>> > > > > > > > > > > > > > bb_1:
>>>>>>>> > > > > > > > > > > > > >   a = 1 + a;
>>>>>>>> > > > > > > > > > > > > > }
>>>>>>>> > > > > > > > > > > > > >
>>>>>>>> > > > > > > > > > > > > > it will execute only given passes i.e. ccp1
>>>>>>>> > > > > > > > > > > > > > and fre1 pass
>>>>>>>> > > on the
>>>>>>>> > > > > > > > > > > > > function
>>>>>>>> > > > > > > > > > > > > >
>>>>>>>> > > > > > > > > > > > > > and for test case like -
>>>>>>>> > > > > > > > > > > > > >
>>>>>>>> > > > > > > > > > > > > > int a;
>>>>>>>> > > > > > > > > > > > > > void __GIMPLE (startwith ("tree-ccp1"))
>>>>>>>> > > > > > > > > > > > > > foo()
>>>>>>>> > > > > > > > > > > > > > {
>>>>>>>> > > > > > > > > > > > > > bb_1:
>>>>>>>> > > > > > > > > > > > > >   a = 1 + a;
>>>>>>>> > > > > > > > > > > > > > }
>>>>>>>> > > > > > > > > > > > > >
>>>>>>>> > > > > > > > > > > > > > it will act as a entry point to the
>>>>>>>> > > > > > > > > > > > > > pipeline and will
>>>>>>>> > > execute passes
>>>>>>>> > > > > > > > > > > > > > starting from given pass.
>>>>>>>> > > > > > > > > > > > > Bike-shedding:
>>>>>>>> > > > > > > > > > > > > Would it make sense to have syntax for
>>>>>>>> > > > > > > > > > > > > defining pass ranges
>>>>>>>> > > to execute
>>>>>>>> > > > > > > > > > > > > ?
>>>>>>>> > > > > > > > > > > > > for instance:
>>>>>>>> > > > > > > > > > > > > void __GIMPLE(execute (pass_start :
>>>>>>>> > > > > > > > > > > > > pass_end))
>>>>>>>> > > > > > > > > > > > > which would execute all the passes within
>>>>>>>> > > > > > > > > > > > > range [pass_start,
>>>>>>>> > > pass_end],
>>>>>>>> > > > > > > > > > > > > which would be convenient if the range is
>>>>>>>> > > > > > > > > > > > > large.
>>>>>>>> > > > > > > > > > > >
>>>>>>>> > > > > > > > > > > > But it would rely on a particular pass
>>>>>>>> > > > > > > > > > > > pipeline, f.e.
>>>>>>>> > > pass-start appearing before pass-end.
>>>>>>>> > > > > > > > > > > >
>>>>>>>> > > > > > > > > > > > Currently control doesn't work 100% as it only
>>>>>>>> > > > > > > > > > > > replaces
>>>>>>>> > > all_optimizations but not lowering passes or early opts, nor IPA
>>>>>>>> > > opts.
>>>>>>>> > > > > > > > > > > >
>>>>>>>> > > > > > > > > > >
>>>>>>>> > > > > > > > > > > Each pass needs GIMPLE in some specific form. So
>>>>>>>> > > > > > > > > > > I am letting
>>>>>>>> > > lowering
>>>>>>>> > > > > > > > > > > and early opt passes to execute. I think we have
>>>>>>>> > > > > > > > > > > to execute
>>>>>>>> > > some
>>>>>>>> > > > > > > > > > > passes (like cfg) anyway to represent GIMPLE into
>>>>>>>> > > > > > > > > > > proper form
>>>>>>>> > > > > > > > > >
>>>>>>>> > > > > > > > > > Yes, that's true.  Note that early opt passes only
>>>>>>>> > > > > > > > > > optimize but
>>>>>>>> > > we need
>>>>>>>> > > > > > > > > > pass_build_ssa_passes at least (for into-SSA).  For
>>>>>>>> > > > > > > > > > proper
>>>>>>>> > > unit-testing
>>>>>>>> > > > > > > > > > of GIMPLE passes we do need to guard off early opts
>>>>>>>> > > > > > > > > > somehow
>>>>>>>> > > > > > > > > > (I guess a simple if (flag_gimple && cfun
>>>>>>>> > > > > > > > > > ->custom_pass_list)
>>>>>>>> > > would do
>>>>>>>> > > > > > > > > > that).
>>>>>>>> > > > > > > > > >
>>>>>>>> > > > > > > > > > Then there is of course the question about IPA
>>>>>>>> > > > > > > > > > passes which I
>>>>>>>> > > think is
>>>>>>>> > > > > > > > > > somewhat harder (one could always disable all IPA
>>>>>>>> > > > > > > > > > passes
>>>>>>>> > > manually
>>>>>>>> > > > > > > > > > via flags of course or finally have a global
>>>>>>>> > > > > > > > > > -fipa/no-ipa like
>>>>>>>> > > most
>>>>>>>> > > > > > > > > > other compilers).
>>>>>>>> > > > > > > > > >
>>>>>>>> > > > > > > > > Can we iterate through all ipa passes and do
>>>>>>>> > > > > > > > > -fdisable-ipa-pass
>>>>>>>> > > or
>>>>>>>> > > > > > > > > -fenable-ipa-pass equivalent for each?
>>>>>>>> > > > > > > >
>>>>>>>> > > > > > > > We could do that, yes.  But let's postpone this issue.
>>>>>>>> > > > > > > >  I think
>>>>>>>> > > that
>>>>>>>> > > > > > > > startwith is going to be most useful and rather than
>>>>>>>> > > > > > > > constructing
>>>>>>>> > > > > > > > a pass list for it "native" support for it in the pass
>>>>>>>> > > > > > > > manager is
>>>>>>>> > > > > > > > likely to produce better results (add a 'startwith'
>>>>>>>> > > > > > > > member
>>>>>>>> > > alongside
>>>>>>>> > > > > > > > the pass list member and if it is set the pass manager
>>>>>>>> > > > > > > > skips all
>>>>>>>> > > > > > > > passes that do not match 'startwith' and once it
>>>>>>>> > > > > > > > reaches it it
>>>>>>>> > > clears
>>>>>>>> > > > > > > > the field).
>>>>>>>> > > > > > > >
>>>>>>>> > > > > > > > In the future I hope we can get away from a static pass
>>>>>>>> > > > > > > > list and
>>>>>>>> > > more
>>>>>>>> > > > > > > > towards rule-driven pass execution (we have all those
>>>>>>>> > > > > > > > PROP_*
>>>>>>>> > > stuff
>>>>>>>> > > > > > > > already but it isn't really used for example).  But
>>>>>>>> > > > > > > > well, that
>>>>>>>> > > would be
>>>>>>>> > > > > > > > a separate GSoC project ;)
>>>>>>>> > > > > > > >
>>>>>>>> > > > > > > > IMHO startwith will provide everything needed for unit
>>>>>>>> > > > > > > > -testing.
>>>>>>>> > > We can
>>>>>>>> > > > > > > > add a flag on whether further passes should be executed
>>>>>>>> > > > > > > > or not
>>>>>>>> > > and
>>>>>>>> > > > > > > > even a pass list like execute ("ccp1", "fre") can be
>>>>>>>> > > > > > > > implemented
>>>>>>>> > > by
>>>>>>>> > > > > > > > startwith ccp1 and then from there executing the rest
>>>>>>>> > > > > > > > of the
>>>>>>>> > > passes in the
>>>>>>>> > > > > > > > list and stopping at the end.
>>>>>>>> > > > > > > >
>>>>>>>> > > > > > > > As said, unit-testing should exercise a single pass if
>>>>>>>> > > > > > > > we can
>>>>>>>> > > control
>>>>>>>> > > > > > > > its input.
>>>>>>>> > > > > > > >
>>>>>>>> > > > > > > In this patch I am skipping execution of passes until
>>>>>>>> > > pass_startwith
>>>>>>>> > > > > > > is found. Unlike previous build, now pass manager
>>>>>>>> > > > > > > executes all
>>>>>>>> > > passes
>>>>>>>> > > > > > > in pipeline starting from pass_startwith instead of just
>>>>>>>> > > > > > > sub
>>>>>>>> > > passes.
>>>>>>>> > > > > >
>>>>>>>> > > > > > That looks good.  I wonder if
>>>>>>>> > > > > >
>>>>>>>> > > > > > +  if (startwith_p && cfun->startwith)
>>>>>>>> > > > > > +    {
>>>>>>>> > > > > > +      if (pass->name == cfun->pass_startwith->name
>>>>>>>> > > > > > +         || pass->name == "*clean_state")
>>>>>>>> > > > > >
>>>>>>>> > > > > > need better be strcmp ()s though.  Also the early
>>>>>>>> > > > > > optimization
>>>>>>>> > > pipeline
>>>>>>>> > > > > > should be executed with startwith support as well.
>>>>>>>> > > > > >
>>>>>>>> > > > >
>>>>>>>> > > > > This patch adds startwith support for early opt passes. But
>>>>>>>> > > > > for
>>>>>>>> > > > > starting from some passes (like asan0, optimized) in
>>>>>>>> > > > > all_passes
>>>>>>>> > > > > pipeline, it falils at verify_curr_properties in
>>>>>>>> > > > > execute_one_pass
>>>>>>>> > > ().
>>>>>>>> > > > > I wonder if we need to update properties after skipping each
>>>>>>>> > > > > pass
>>>>>>>> > > >
>>>>>>>> > > > Yeah, it's not possible to start at arbitrary points with
>>>>>>>> > > > skipping
>>>>>>>> > > passes
>>>>>>>> > > > that provide a required property.  I suspect it's good enough
>>>>>>>> > > > that
>>>>>>>> > > we'll
>>>>>>>> > > > ICE if that happens.
>>>>>>>> > > >
>>>>>>>> > > > I see you are working on the dump-file side a bit now.  What is
>>>>>>>> > > > still
>>>>>>>> > > > missing after you got support for PHIs is parsing of SSA names.
>>>>>>>> > > > Without this unit-testing will be difficult at best.
>>>>>>>> > > >
>>>>>>>> > > > I think what we need to do is simplify the job of the parser
>>>>>>>> > > > and
>>>>>>>> > > > make the syntax we use to print SSA names a bit different.
>>>>>>>> > > > So rather than printing VAR_VERSION we need to choose a
>>>>>>>> > > > letter that is not part of a valid identifier before VERSION,
>>>>>>>> > > > like a dot '.'.  Thus we'd have i.1 instead of i_1 and we'd
>>>>>>>> > > > have
>>>>>>>> > > > .2 instead of _2 for an anonymous SSA name.  The advantage
>>>>>>>> > > > for non-anonymous names is that we can properly re-use the
>>>>>>>> > > > C frontends decl handling for declaring and looking up 'i'.
>>>>>>>> > > > The disadvantage is that for anonymous SSA names this isn't
>>>>>>>> > > > so easy which means we could choose to not support those
>>>>>>>> > > > for the moment and require fake decls for them.  In fact
>>>>>>>> > > > into-SSA will do the correct thing if we just treat them as
>>>>>>>> > > > decls,
>>>>>>>> > > > thus continue to dump them as _VERSION.
>>>>>>>> > > >
>>>>>>>> > >
>>>>>>>> > > I am little confused here about parsing 'i.1' because lexer drops
>>>>>>>> > > DOT
>>>>>>>> > > token for syntax like NAME.NUMBER . Hence instead of 'i.1' parser
>>>>>>>> > > receives 'i1'
>>>>>>>> >
>>>>>>>> > Are you sure? You should get three tokens, one for 'i', one for the
>>>>>>>> > dot and
>>>>>>>> > One for '1'.  You'd lookup the first via the C frontend symbol
>>>>>>>> > table only.
>>>>>>>> >
>>>>>>>>
>>>>>>>> Yes, I was also expecting that. For syntax like 'a.b' (ie name.name)
>>>>>>>> it gives proper 3 tokens but for syntax like 'a.1' it produces only
>>>>>>>> 2.
>>>>>>>>
>>>>>>>> This is what I observed while debugging "int a.1;"
>>>>>>>>
>>>>>>>> (gdb) print *c_parser_peek_nth_token (parser, 1)
>>>>>>>> $3 = {type = CPP_KEYWORD, id_kind = C_ID_NONE, keyword = RID_INT,
>>>>>>>>   pragma_kind = PRAGMA_NONE, location = 242114, value =
>>>>>>>> 0x7ffff65c82d0}
>>>>>>>> (gdb) print *c_parser_peek_nth_token (parser, 2)
>>>>>>>> $4 = {type = CPP_NAME, id_kind = C_ID_ID, keyword = RID_MAX,
>>>>>>>>   pragma_kind = PRAGMA_NONE, location = 242240, value =
>>>>>>>> 0x7ffff66d0b90}
>>>>>>>> (gdb) print *c_parser_peek_nth_token (parser, 3)
>>>>>>>> $5 = {type = CPP_NUMBER, id_kind = C_ID_NONE, keyword = RID_MAX,
>>>>>>>>   pragma_kind = PRAGMA_NONE, location = 242273, value =
>>>>>>>> 0x7ffff66e0030}
>>>>>>>
>>>>>>>What is the number?  I'm wondering if it's somehow been lexed as a
>>>>>>>decimal ".1" i.e. if the "." is somehow being treated as part of the
>>>>>>>CPP_NUMBER.
>>>>>>
>>>>>
>>>>> Yes, the token '.1' is treated as CPP_NUMBER
>>>>>
>>>>>> Ah, possible...
>>>>>>
>>>>>>>FWIW, I find hacking in calls to "inform" very useful for seeing what
>>>>>>>each token is (assuming that caret printing isn't disabled).
>>>>>>>
>>>>>>>  (gdb) call inform ($3->location, "")
>>>>>>>  (gdb) call inform ($4->location, "")
>>>>>>>  (gdb) call inform ($5
>>>>>>>->location, "")
>>>>>>>
>>>>>>>etc
>>>>>>>
>>>>>>>BTW, does it have to be '.' as the SSA_NAME separator?  Could it be a
>>>>>>>different character e.g. '@' or something else that's non-legal in C?
>>>>>>
>>>>>> It doesn't have to be '.', but sth visually not too disturbing would be nice.  If we don't go with '.' We can as well try to parse the SSA version from i_1, leaving the ambiguity with it being a valid C identifier.
>>>>>>
>>>>>
>>>>> As special characters are not valid in C, I am using 'a..1' as syntax
>>>>> for ssa name. For parsing I am using
>>>>> +      lhs.value = make_ssa_name_fn (cfun,
>>>>> +                                   lookup_name (c_parser_peek_token
>>>>> (parser)->value),
>>>>> +                                   NULL);
>>>>> Now for passing ssa name into __PHI, how can we lookup for particular ssa name.
>>>>> Or is there other better method to do it?
>>>>
>>>> Note that with this you need to preserve SSA versions as used in the source
>>>> (the 1 in a..1).  If you can do that (see below) the way to lookup an SSA name
>>>> is simply calling 'ssa_name (version)' with version being an integer with the
>>>> version number.
>>>>
>>>> make_ssa_name will simply allocate the next available SSA version so
>>>> you'll need to add an interface that allows you allocation of a specific
>>>> SSA version.  Like with sth similar to
>>>>
>>>> Index: gcc/tree-ssanames.c
>>>> ===================================================================
>>>> --- gcc/tree-ssanames.c (revision 238512)
>>>> +++ gcc/tree-ssanames.c (working copy)
>>>> @@ -255,7 +255,7 @@
>>>>     used without a preceding definition).  */
>>>>
>>>>  tree
>>>> -make_ssa_name_fn (struct function *fn, tree var, gimple *stmt)
>>>> +make_ssa_name_fn (struct function *fn, tree var, gimple *stmt, int version)
>>>>  {
>>>>    tree t;
>>>>    use_operand_p imm;
>>>> @@ -265,8 +265,17 @@
>>>>               || TREE_CODE (var) == RESULT_DECL
>>>>               || (TYPE_P (var) && is_gimple_reg_type (var)));
>>>>
>>>> +  if (version != 0)
>>>> +    {
>>>> +      t = make_node (SSA_NAME);
>>>> +      SSA_NAME_VERSION (t) = version;
>>>> +      vec_safe_grow_cleared (SSANAMES (fn), version + 1);
>>>> +      gcc_assert ((*SSANAMES (fn))[version] == NULL);
>>>> +      (*SSANAMES (fn))[version] = t;
>>>> +      ssa_name_nodes_created++;
>>>> +    }
>>>>    /* If our free list has an element, then use it.  */
>>>> -  if (!vec_safe_is_empty (FREE_SSANAMES (fn)))
>>>> +  else if (!vec_safe_is_empty (FREE_SSANAMES (fn)))
>>>>      {
>>>>        t = FREE_SSANAMES (fn)->pop ();
>>>>        ssa_name_nodes_reused++;
>>>> Index: gcc/tree-ssanames.h
>>>> ===================================================================
>>>> --- gcc/tree-ssanames.h (revision 237253)
>>>> +++ gcc/tree-ssanames.h (working copy)
>>>> @@ -79,7 +79,7 @@
>>>>  extern void init_ssanames (struct function *, int);
>>>>  extern void fini_ssanames (struct function *);
>>>>  extern void ssanames_print_statistics (void);
>>>> -extern tree make_ssa_name_fn (struct function *, tree, gimple *);
>>>> +extern tree make_ssa_name_fn (struct function *, tree, gimple *, int);
>>>>  extern void release_ssa_name_fn (struct function *, tree);
>>>>  extern bool get_ptr_info_alignment (struct ptr_info_def *, unsigned int *,
>>>>                                     unsigned int *);
>>>>
>>>> where you can then do sth like
>>>>
>>>>   ssaname = ssa_name (version);
>>>>   if (!ssaname)
>>>>     ssaname = make_ssa_name_fn (cfun, lookup_name (...), NULL, version);
>>>>
>>>> to either lookup an existing or allocate a new SSA name of the desired version.
>>>>
>>>> Just for some bike-shedding, I don't like using '..' too much ;)
>>> Would it be a good idea to modify libcpp's lexer to recognize
>>> identifier.number as a single token if -fgimple is enabled ?
>>
>> I don't think so.  As said, we can retain the i_2 syntax as well where you then
>> get a single token and to decide whether it is a SSA name do a lookup for
>> 'i' first and if that succeeds, interpret _2 as a version suffix,
>> otherwise use it
>> as full variable name.  Re-constructing the 1 from .1 or 17 from .17 CPP_NUMBER
>> is possible as well of course.
>>
>
> Sorry for the late response. I was little busy due to some family problem.
>
> In this patch, I am parsing ssa names as described above. But the
> problem is non ssa variable also gets renamed
I assume you're referring to renaming of a to a_5 here ?
I suppose that's expected since 'a' is gimple reg, ssa pass will
create ssa name for it.
Maybe emit "parse error" if local var is not in "ssa syntax", that is,
it doesn't
have _version suffixed ? But emitting an error for this case looks
artificial to me.

Thanks,
Prathamesh
>
> for testcase :
>
> void __GIMPLE () foo()
> {
>   int a;
> bb_2:
>   if (a > 4)
>     goto bb_3;
>   else
>     goto bb_4;
> bb_3:
>   a_1 = 55;
>   goto bb_5;
>
> bb_4:
>   a_2 = 99;
>
> bb_5:
>   a_3 = __PHI (bb_3: a_1, bb_4: a_2);
>   a_4 = a_3 + 3;
>   return;
> }
>
> I am getting ssa dump as:
>
> /* Function foo (foo, funcdef_no=0, decl_uid=1744, cgraph_uid=0,
> symbol_order=0)*/
>
> void
> foo ()
> {
> bb_2:
>   if (a_5 > 4)
>     goto bb_3;
>   else
>     goto bb_4;
>
> bb_3:
>   a_1 = 55;
>   goto bb_5;
>
> bb_4:
>   a_2 = 99;
>
>   a_3 = __PHI (bb_3: a_1, bb_4: a_2)
> bb_5:
>   a_4 = a_3 + 3;
>   return;
>
> }
>
>> Richard.
>>
>>> Thanks,
>>> Prathamesh
>>>>
>>>> Richard.
>>>>
>>>>>
>>>>>> Richard.
>>>>>>
>>>>>>>Dave
>>>>>>
>>>>>>

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [gimplefe] hacking pass manager
  2016-07-26 21:39                                         ` Prathamesh Kulkarni
@ 2016-07-27  8:53                                           ` Richard Biener
  2016-07-28 18:31                                             ` Prasad Ghangal
  0 siblings, 1 reply; 29+ messages in thread
From: Richard Biener @ 2016-07-27  8:53 UTC (permalink / raw)
  To: Prathamesh Kulkarni; +Cc: Prasad Ghangal, David Malcolm, gcc Mailing List

On Tue, Jul 26, 2016 at 11:38 PM, Prathamesh Kulkarni
<prathamesh.kulkarni@linaro.org> wrote:
> On 27 July 2016 at 00:20, Prasad Ghangal <prasad.ghangal@gmail.com> wrote:
>> On 20 July 2016 at 18:28, Richard Biener <richard.guenther@gmail.com> wrote:
>>> On Wed, Jul 20, 2016 at 1:46 PM, Prathamesh Kulkarni
>>> <prathamesh.kulkarni@linaro.org> wrote:
>>>> On 20 July 2016 at 11:34, Richard Biener <richard.guenther@gmail.com> wrote:
>>>>> On Tue, Jul 19, 2016 at 10:09 PM, Prasad Ghangal
>>>>> <prasad.ghangal@gmail.com> wrote:
>>>>>> On 19 July 2016 at 11:04, Richard Biener <richard.guenther@gmail.com> wrote:
>>>>>>> On July 18, 2016 11:05:58 PM GMT+02:00, David Malcolm <dmalcolm@redhat.com> wrote:
>>>>>>>>On Tue, 2016-07-19 at 00:52 +0530, Prasad Ghangal wrote:
>>>>>>>>> On 19 July 2016 at 00:25, Richard Biener <richard.guenther@gmail.com>
>>>>>>>>> wrote:
>>>>>>>>> > On July 18, 2016 8:28:15 PM GMT+02:00, Prasad Ghangal <
>>>>>>>>> > prasad.ghangal@gmail.com> wrote:
>>>>>>>>> > > On 15 July 2016 at 16:13, Richard Biener <
>>>>>>>>> > > richard.guenther@gmail.com>
>>>>>>>>> > > wrote:
>>>>>>>>> > > > On Sun, Jul 10, 2016 at 6:13 PM, Prasad Ghangal
>>>>>>>>> > > > <prasad.ghangal@gmail.com> wrote:
>>>>>>>>> > > > > On 8 July 2016 at 13:13, Richard Biener <
>>>>>>>>> > > > > richard.guenther@gmail.com>
>>>>>>>>> > > wrote:
>>>>>>>>> > > > > > On Thu, Jul 7, 2016 at 9:45 PM, Prasad Ghangal
>>>>>>>>> > > <prasad.ghangal@gmail.com> wrote:
>>>>>>>>> > > > > > > On 6 July 2016 at 14:24, Richard Biener
>>>>>>>>> > > <richard.guenther@gmail.com> wrote:
>>>>>>>>> > > > > > > > On Wed, Jul 6, 2016 at 9:51 AM, Prasad Ghangal
>>>>>>>>> > > <prasad.ghangal@gmail.com> wrote:
>>>>>>>>> > > > > > > > > On 30 June 2016 at 17:10, Richard Biener
>>>>>>>>> > > <richard.guenther@gmail.com> wrote:
>>>>>>>>> > > > > > > > > > On Wed, Jun 29, 2016 at 9:13 PM, Prasad Ghangal
>>>>>>>>> > > > > > > > > > <prasad.ghangal@gmail.com> wrote:
>>>>>>>>> > > > > > > > > > > On 29 June 2016 at 22:15, Richard Biener
>>>>>>>>> > > <richard.guenther@gmail.com> wrote:
>>>>>>>>> > > > > > > > > > > > On June 29, 2016 6:20:29 PM GMT+02:00,
>>>>>>>>> > > > > > > > > > > > Prathamesh Kulkarni
>>>>>>>>> > > <prathamesh.kulkarni@linaro.org> wrote:
>>>>>>>>> > > > > > > > > > > > > On 18 June 2016 at 12:02, Prasad Ghangal
>>>>>>>>> > > <prasad.ghangal@gmail.com>
>>>>>>>>> > > > > > > > > > > > > wrote:
>>>>>>>>> > > > > > > > > > > > > > Hi,
>>>>>>>>> > > > > > > > > > > > > >
>>>>>>>>> > > > > > > > > > > > > > I tried hacking pass manager to execute
>>>>>>>>> > > > > > > > > > > > > > only given passes.
>>>>>>>>> > > For this I
>>>>>>>>> > > > > > > > > > > > > > am adding new member as opt_pass
>>>>>>>>> > > > > > > > > > > > > > *custom_pass_list to the
>>>>>>>>> > > function
>>>>>>>>> > > > > > > > > > > > > > structure to store passes need to execute
>>>>>>>>> > > > > > > > > > > > > > and providing the
>>>>>>>>> > > > > > > > > > > > > > custom_pass_list to execute_pass_list()
>>>>>>>>> > > > > > > > > > > > > > function instead of
>>>>>>>>> > > all
>>>>>>>>> > > > > > > > > > > > > passes
>>>>>>>>> > > > > > > > > > > > > >
>>>>>>>>> > > > > > > > > > > > > > for test case like-
>>>>>>>>> > > > > > > > > > > > > >
>>>>>>>>> > > > > > > > > > > > > > int a;
>>>>>>>>> > > > > > > > > > > > > > void __GIMPLE (execute ("tree-ccp1", "tree
>>>>>>>>> > > > > > > > > > > > > > -fre1")) foo()
>>>>>>>>> > > > > > > > > > > > > > {
>>>>>>>>> > > > > > > > > > > > > > bb_1:
>>>>>>>>> > > > > > > > > > > > > >   a = 1 + a;
>>>>>>>>> > > > > > > > > > > > > > }
>>>>>>>>> > > > > > > > > > > > > >
>>>>>>>>> > > > > > > > > > > > > > it will execute only given passes i.e. ccp1
>>>>>>>>> > > > > > > > > > > > > > and fre1 pass
>>>>>>>>> > > on the
>>>>>>>>> > > > > > > > > > > > > function
>>>>>>>>> > > > > > > > > > > > > >
>>>>>>>>> > > > > > > > > > > > > > and for test case like -
>>>>>>>>> > > > > > > > > > > > > >
>>>>>>>>> > > > > > > > > > > > > > int a;
>>>>>>>>> > > > > > > > > > > > > > void __GIMPLE (startwith ("tree-ccp1"))
>>>>>>>>> > > > > > > > > > > > > > foo()
>>>>>>>>> > > > > > > > > > > > > > {
>>>>>>>>> > > > > > > > > > > > > > bb_1:
>>>>>>>>> > > > > > > > > > > > > >   a = 1 + a;
>>>>>>>>> > > > > > > > > > > > > > }
>>>>>>>>> > > > > > > > > > > > > >
>>>>>>>>> > > > > > > > > > > > > > it will act as a entry point to the
>>>>>>>>> > > > > > > > > > > > > > pipeline and will
>>>>>>>>> > > execute passes
>>>>>>>>> > > > > > > > > > > > > > starting from given pass.
>>>>>>>>> > > > > > > > > > > > > Bike-shedding:
>>>>>>>>> > > > > > > > > > > > > Would it make sense to have syntax for
>>>>>>>>> > > > > > > > > > > > > defining pass ranges
>>>>>>>>> > > to execute
>>>>>>>>> > > > > > > > > > > > > ?
>>>>>>>>> > > > > > > > > > > > > for instance:
>>>>>>>>> > > > > > > > > > > > > void __GIMPLE(execute (pass_start :
>>>>>>>>> > > > > > > > > > > > > pass_end))
>>>>>>>>> > > > > > > > > > > > > which would execute all the passes within
>>>>>>>>> > > > > > > > > > > > > range [pass_start,
>>>>>>>>> > > pass_end],
>>>>>>>>> > > > > > > > > > > > > which would be convenient if the range is
>>>>>>>>> > > > > > > > > > > > > large.
>>>>>>>>> > > > > > > > > > > >
>>>>>>>>> > > > > > > > > > > > But it would rely on a particular pass
>>>>>>>>> > > > > > > > > > > > pipeline, f.e.
>>>>>>>>> > > pass-start appearing before pass-end.
>>>>>>>>> > > > > > > > > > > >
>>>>>>>>> > > > > > > > > > > > Currently control doesn't work 100% as it only
>>>>>>>>> > > > > > > > > > > > replaces
>>>>>>>>> > > all_optimizations but not lowering passes or early opts, nor IPA
>>>>>>>>> > > opts.
>>>>>>>>> > > > > > > > > > > >
>>>>>>>>> > > > > > > > > > >
>>>>>>>>> > > > > > > > > > > Each pass needs GIMPLE in some specific form. So
>>>>>>>>> > > > > > > > > > > I am letting
>>>>>>>>> > > lowering
>>>>>>>>> > > > > > > > > > > and early opt passes to execute. I think we have
>>>>>>>>> > > > > > > > > > > to execute
>>>>>>>>> > > some
>>>>>>>>> > > > > > > > > > > passes (like cfg) anyway to represent GIMPLE into
>>>>>>>>> > > > > > > > > > > proper form
>>>>>>>>> > > > > > > > > >
>>>>>>>>> > > > > > > > > > Yes, that's true.  Note that early opt passes only
>>>>>>>>> > > > > > > > > > optimize but
>>>>>>>>> > > we need
>>>>>>>>> > > > > > > > > > pass_build_ssa_passes at least (for into-SSA).  For
>>>>>>>>> > > > > > > > > > proper
>>>>>>>>> > > unit-testing
>>>>>>>>> > > > > > > > > > of GIMPLE passes we do need to guard off early opts
>>>>>>>>> > > > > > > > > > somehow
>>>>>>>>> > > > > > > > > > (I guess a simple if (flag_gimple && cfun
>>>>>>>>> > > > > > > > > > ->custom_pass_list)
>>>>>>>>> > > would do
>>>>>>>>> > > > > > > > > > that).
>>>>>>>>> > > > > > > > > >
>>>>>>>>> > > > > > > > > > Then there is of course the question about IPA
>>>>>>>>> > > > > > > > > > passes which I
>>>>>>>>> > > think is
>>>>>>>>> > > > > > > > > > somewhat harder (one could always disable all IPA
>>>>>>>>> > > > > > > > > > passes
>>>>>>>>> > > manually
>>>>>>>>> > > > > > > > > > via flags of course or finally have a global
>>>>>>>>> > > > > > > > > > -fipa/no-ipa like
>>>>>>>>> > > most
>>>>>>>>> > > > > > > > > > other compilers).
>>>>>>>>> > > > > > > > > >
>>>>>>>>> > > > > > > > > Can we iterate through all ipa passes and do
>>>>>>>>> > > > > > > > > -fdisable-ipa-pass
>>>>>>>>> > > or
>>>>>>>>> > > > > > > > > -fenable-ipa-pass equivalent for each?
>>>>>>>>> > > > > > > >
>>>>>>>>> > > > > > > > We could do that, yes.  But let's postpone this issue.
>>>>>>>>> > > > > > > >  I think
>>>>>>>>> > > that
>>>>>>>>> > > > > > > > startwith is going to be most useful and rather than
>>>>>>>>> > > > > > > > constructing
>>>>>>>>> > > > > > > > a pass list for it "native" support for it in the pass
>>>>>>>>> > > > > > > > manager is
>>>>>>>>> > > > > > > > likely to produce better results (add a 'startwith'
>>>>>>>>> > > > > > > > member
>>>>>>>>> > > alongside
>>>>>>>>> > > > > > > > the pass list member and if it is set the pass manager
>>>>>>>>> > > > > > > > skips all
>>>>>>>>> > > > > > > > passes that do not match 'startwith' and once it
>>>>>>>>> > > > > > > > reaches it it
>>>>>>>>> > > clears
>>>>>>>>> > > > > > > > the field).
>>>>>>>>> > > > > > > >
>>>>>>>>> > > > > > > > In the future I hope we can get away from a static pass
>>>>>>>>> > > > > > > > list and
>>>>>>>>> > > more
>>>>>>>>> > > > > > > > towards rule-driven pass execution (we have all those
>>>>>>>>> > > > > > > > PROP_*
>>>>>>>>> > > stuff
>>>>>>>>> > > > > > > > already but it isn't really used for example).  But
>>>>>>>>> > > > > > > > well, that
>>>>>>>>> > > would be
>>>>>>>>> > > > > > > > a separate GSoC project ;)
>>>>>>>>> > > > > > > >
>>>>>>>>> > > > > > > > IMHO startwith will provide everything needed for unit
>>>>>>>>> > > > > > > > -testing.
>>>>>>>>> > > We can
>>>>>>>>> > > > > > > > add a flag on whether further passes should be executed
>>>>>>>>> > > > > > > > or not
>>>>>>>>> > > and
>>>>>>>>> > > > > > > > even a pass list like execute ("ccp1", "fre") can be
>>>>>>>>> > > > > > > > implemented
>>>>>>>>> > > by
>>>>>>>>> > > > > > > > startwith ccp1 and then from there executing the rest
>>>>>>>>> > > > > > > > of the
>>>>>>>>> > > passes in the
>>>>>>>>> > > > > > > > list and stopping at the end.
>>>>>>>>> > > > > > > >
>>>>>>>>> > > > > > > > As said, unit-testing should exercise a single pass if
>>>>>>>>> > > > > > > > we can
>>>>>>>>> > > control
>>>>>>>>> > > > > > > > its input.
>>>>>>>>> > > > > > > >
>>>>>>>>> > > > > > > In this patch I am skipping execution of passes until
>>>>>>>>> > > pass_startwith
>>>>>>>>> > > > > > > is found. Unlike previous build, now pass manager
>>>>>>>>> > > > > > > executes all
>>>>>>>>> > > passes
>>>>>>>>> > > > > > > in pipeline starting from pass_startwith instead of just
>>>>>>>>> > > > > > > sub
>>>>>>>>> > > passes.
>>>>>>>>> > > > > >
>>>>>>>>> > > > > > That looks good.  I wonder if
>>>>>>>>> > > > > >
>>>>>>>>> > > > > > +  if (startwith_p && cfun->startwith)
>>>>>>>>> > > > > > +    {
>>>>>>>>> > > > > > +      if (pass->name == cfun->pass_startwith->name
>>>>>>>>> > > > > > +         || pass->name == "*clean_state")
>>>>>>>>> > > > > >
>>>>>>>>> > > > > > need better be strcmp ()s though.  Also the early
>>>>>>>>> > > > > > optimization
>>>>>>>>> > > pipeline
>>>>>>>>> > > > > > should be executed with startwith support as well.
>>>>>>>>> > > > > >
>>>>>>>>> > > > >
>>>>>>>>> > > > > This patch adds startwith support for early opt passes. But
>>>>>>>>> > > > > for
>>>>>>>>> > > > > starting from some passes (like asan0, optimized) in
>>>>>>>>> > > > > all_passes
>>>>>>>>> > > > > pipeline, it falils at verify_curr_properties in
>>>>>>>>> > > > > execute_one_pass
>>>>>>>>> > > ().
>>>>>>>>> > > > > I wonder if we need to update properties after skipping each
>>>>>>>>> > > > > pass
>>>>>>>>> > > >
>>>>>>>>> > > > Yeah, it's not possible to start at arbitrary points with
>>>>>>>>> > > > skipping
>>>>>>>>> > > passes
>>>>>>>>> > > > that provide a required property.  I suspect it's good enough
>>>>>>>>> > > > that
>>>>>>>>> > > we'll
>>>>>>>>> > > > ICE if that happens.
>>>>>>>>> > > >
>>>>>>>>> > > > I see you are working on the dump-file side a bit now.  What is
>>>>>>>>> > > > still
>>>>>>>>> > > > missing after you got support for PHIs is parsing of SSA names.
>>>>>>>>> > > > Without this unit-testing will be difficult at best.
>>>>>>>>> > > >
>>>>>>>>> > > > I think what we need to do is simplify the job of the parser
>>>>>>>>> > > > and
>>>>>>>>> > > > make the syntax we use to print SSA names a bit different.
>>>>>>>>> > > > So rather than printing VAR_VERSION we need to choose a
>>>>>>>>> > > > letter that is not part of a valid identifier before VERSION,
>>>>>>>>> > > > like a dot '.'.  Thus we'd have i.1 instead of i_1 and we'd
>>>>>>>>> > > > have
>>>>>>>>> > > > .2 instead of _2 for an anonymous SSA name.  The advantage
>>>>>>>>> > > > for non-anonymous names is that we can properly re-use the
>>>>>>>>> > > > C frontends decl handling for declaring and looking up 'i'.
>>>>>>>>> > > > The disadvantage is that for anonymous SSA names this isn't
>>>>>>>>> > > > so easy which means we could choose to not support those
>>>>>>>>> > > > for the moment and require fake decls for them.  In fact
>>>>>>>>> > > > into-SSA will do the correct thing if we just treat them as
>>>>>>>>> > > > decls,
>>>>>>>>> > > > thus continue to dump them as _VERSION.
>>>>>>>>> > > >
>>>>>>>>> > >
>>>>>>>>> > > I am little confused here about parsing 'i.1' because lexer drops
>>>>>>>>> > > DOT
>>>>>>>>> > > token for syntax like NAME.NUMBER . Hence instead of 'i.1' parser
>>>>>>>>> > > receives 'i1'
>>>>>>>>> >
>>>>>>>>> > Are you sure? You should get three tokens, one for 'i', one for the
>>>>>>>>> > dot and
>>>>>>>>> > One for '1'.  You'd lookup the first via the C frontend symbol
>>>>>>>>> > table only.
>>>>>>>>> >
>>>>>>>>>
>>>>>>>>> Yes, I was also expecting that. For syntax like 'a.b' (ie name.name)
>>>>>>>>> it gives proper 3 tokens but for syntax like 'a.1' it produces only
>>>>>>>>> 2.
>>>>>>>>>
>>>>>>>>> This is what I observed while debugging "int a.1;"
>>>>>>>>>
>>>>>>>>> (gdb) print *c_parser_peek_nth_token (parser, 1)
>>>>>>>>> $3 = {type = CPP_KEYWORD, id_kind = C_ID_NONE, keyword = RID_INT,
>>>>>>>>>   pragma_kind = PRAGMA_NONE, location = 242114, value =
>>>>>>>>> 0x7ffff65c82d0}
>>>>>>>>> (gdb) print *c_parser_peek_nth_token (parser, 2)
>>>>>>>>> $4 = {type = CPP_NAME, id_kind = C_ID_ID, keyword = RID_MAX,
>>>>>>>>>   pragma_kind = PRAGMA_NONE, location = 242240, value =
>>>>>>>>> 0x7ffff66d0b90}
>>>>>>>>> (gdb) print *c_parser_peek_nth_token (parser, 3)
>>>>>>>>> $5 = {type = CPP_NUMBER, id_kind = C_ID_NONE, keyword = RID_MAX,
>>>>>>>>>   pragma_kind = PRAGMA_NONE, location = 242273, value =
>>>>>>>>> 0x7ffff66e0030}
>>>>>>>>
>>>>>>>>What is the number?  I'm wondering if it's somehow been lexed as a
>>>>>>>>decimal ".1" i.e. if the "." is somehow being treated as part of the
>>>>>>>>CPP_NUMBER.
>>>>>>>
>>>>>>
>>>>>> Yes, the token '.1' is treated as CPP_NUMBER
>>>>>>
>>>>>>> Ah, possible...
>>>>>>>
>>>>>>>>FWIW, I find hacking in calls to "inform" very useful for seeing what
>>>>>>>>each token is (assuming that caret printing isn't disabled).
>>>>>>>>
>>>>>>>>  (gdb) call inform ($3->location, "")
>>>>>>>>  (gdb) call inform ($4->location, "")
>>>>>>>>  (gdb) call inform ($5
>>>>>>>>->location, "")
>>>>>>>>
>>>>>>>>etc
>>>>>>>>
>>>>>>>>BTW, does it have to be '.' as the SSA_NAME separator?  Could it be a
>>>>>>>>different character e.g. '@' or something else that's non-legal in C?
>>>>>>>
>>>>>>> It doesn't have to be '.', but sth visually not too disturbing would be nice.  If we don't go with '.' We can as well try to parse the SSA version from i_1, leaving the ambiguity with it being a valid C identifier.
>>>>>>>
>>>>>>
>>>>>> As special characters are not valid in C, I am using 'a..1' as syntax
>>>>>> for ssa name. For parsing I am using
>>>>>> +      lhs.value = make_ssa_name_fn (cfun,
>>>>>> +                                   lookup_name (c_parser_peek_token
>>>>>> (parser)->value),
>>>>>> +                                   NULL);
>>>>>> Now for passing ssa name into __PHI, how can we lookup for particular ssa name.
>>>>>> Or is there other better method to do it?
>>>>>
>>>>> Note that with this you need to preserve SSA versions as used in the source
>>>>> (the 1 in a..1).  If you can do that (see below) the way to lookup an SSA name
>>>>> is simply calling 'ssa_name (version)' with version being an integer with the
>>>>> version number.
>>>>>
>>>>> make_ssa_name will simply allocate the next available SSA version so
>>>>> you'll need to add an interface that allows you allocation of a specific
>>>>> SSA version.  Like with sth similar to
>>>>>
>>>>> Index: gcc/tree-ssanames.c
>>>>> ===================================================================
>>>>> --- gcc/tree-ssanames.c (revision 238512)
>>>>> +++ gcc/tree-ssanames.c (working copy)
>>>>> @@ -255,7 +255,7 @@
>>>>>     used without a preceding definition).  */
>>>>>
>>>>>  tree
>>>>> -make_ssa_name_fn (struct function *fn, tree var, gimple *stmt)
>>>>> +make_ssa_name_fn (struct function *fn, tree var, gimple *stmt, int version)
>>>>>  {
>>>>>    tree t;
>>>>>    use_operand_p imm;
>>>>> @@ -265,8 +265,17 @@
>>>>>               || TREE_CODE (var) == RESULT_DECL
>>>>>               || (TYPE_P (var) && is_gimple_reg_type (var)));
>>>>>
>>>>> +  if (version != 0)
>>>>> +    {
>>>>> +      t = make_node (SSA_NAME);
>>>>> +      SSA_NAME_VERSION (t) = version;
>>>>> +      vec_safe_grow_cleared (SSANAMES (fn), version + 1);
>>>>> +      gcc_assert ((*SSANAMES (fn))[version] == NULL);
>>>>> +      (*SSANAMES (fn))[version] = t;
>>>>> +      ssa_name_nodes_created++;
>>>>> +    }
>>>>>    /* If our free list has an element, then use it.  */
>>>>> -  if (!vec_safe_is_empty (FREE_SSANAMES (fn)))
>>>>> +  else if (!vec_safe_is_empty (FREE_SSANAMES (fn)))
>>>>>      {
>>>>>        t = FREE_SSANAMES (fn)->pop ();
>>>>>        ssa_name_nodes_reused++;
>>>>> Index: gcc/tree-ssanames.h
>>>>> ===================================================================
>>>>> --- gcc/tree-ssanames.h (revision 237253)
>>>>> +++ gcc/tree-ssanames.h (working copy)
>>>>> @@ -79,7 +79,7 @@
>>>>>  extern void init_ssanames (struct function *, int);
>>>>>  extern void fini_ssanames (struct function *);
>>>>>  extern void ssanames_print_statistics (void);
>>>>> -extern tree make_ssa_name_fn (struct function *, tree, gimple *);
>>>>> +extern tree make_ssa_name_fn (struct function *, tree, gimple *, int);
>>>>>  extern void release_ssa_name_fn (struct function *, tree);
>>>>>  extern bool get_ptr_info_alignment (struct ptr_info_def *, unsigned int *,
>>>>>                                     unsigned int *);
>>>>>
>>>>> where you can then do sth like
>>>>>
>>>>>   ssaname = ssa_name (version);
>>>>>   if (!ssaname)
>>>>>     ssaname = make_ssa_name_fn (cfun, lookup_name (...), NULL, version);
>>>>>
>>>>> to either lookup an existing or allocate a new SSA name of the desired version.
>>>>>
>>>>> Just for some bike-shedding, I don't like using '..' too much ;)
>>>> Would it be a good idea to modify libcpp's lexer to recognize
>>>> identifier.number as a single token if -fgimple is enabled ?
>>>
>>> I don't think so.  As said, we can retain the i_2 syntax as well where you then
>>> get a single token and to decide whether it is a SSA name do a lookup for
>>> 'i' first and if that succeeds, interpret _2 as a version suffix,
>>> otherwise use it
>>> as full variable name.  Re-constructing the 1 from .1 or 17 from .17 CPP_NUMBER
>>> is possible as well of course.
>>>
>>
>> Sorry for the late response. I was little busy due to some family problem.
>>
>> In this patch, I am parsing ssa names as described above. But the
>> problem is non ssa variable also gets renamed
> I assume you're referring to renaming of a to a_5 here ?
> I suppose that's expected since 'a' is gimple reg, ssa pass will
> create ssa name for it.
> Maybe emit "parse error" if local var is not in "ssa syntax", that is,
> it doesn't
> have _version suffixed ? But emitting an error for this case looks
> artificial to me.

Yes, I think the result is as expected.  If we want to constrain the
input to the
GIMPLE parser then we somehow have to tell it what kind of GIMPLE we are
presenting it (SSA or non-SSA gimple), but for the moment what you have
and show with the testcase looks good to me.

The parsing doesn't handle

void __GIMPLE () foo ()
{
  int a_3;
  a_3_1 = 0;
}

correctly as it looks for the first '_' rather than the last.  I'd have used
sth like

  char *p = strrchr (ssa_token, '_');
  if (p)
    {
      var_name = new char [p - ssa_token + 1];
      memcpy (var_name, ssa_token, p - ssa_token);
      var_name[p - ssa_token] = '\0';
      ...
      version = atoi (p);

in the patch you have two copies of the SSA name parsing code - you want to
split that out into a function.

There is one other feature missing for SSA name parsing (forget to mention that)
which is parsing of default def SSA names.  Those are for example used for
parameters and currently dumped like

foo (int i)
{
  int D.1759;
  int _2;

  <bb 2>:
  _2 = i_1(D) + 1;
  return _2;
}

for int foo (int i) { return i + 1; }.  Here 'i_1(D)' is the
default-def of 'i' which
in case of a parameter is the value at function start and in case of a
non-parameter
is simply "undefined".  '(D)' is again somewhat awkward to parse but I guess we
can cope with that ;)  A default-def needs to be registered like

  arg = make_ssa_name_fn (cfun, lookup_name (id), ...);
  set_ssa_default_def (cfun, lookup_name (id), arg);

"undefined" SSA names appear often in PHIs (and of course for parameters).

Thanks,
Richard.

> Thanks,
> Prathamesh
>>
>> for testcase :
>>
>> void __GIMPLE () foo()
>> {
>>   int a;
>> bb_2:
>>   if (a > 4)
>>     goto bb_3;
>>   else
>>     goto bb_4;
>> bb_3:
>>   a_1 = 55;
>>   goto bb_5;
>>
>> bb_4:
>>   a_2 = 99;
>>
>> bb_5:
>>   a_3 = __PHI (bb_3: a_1, bb_4: a_2);
>>   a_4 = a_3 + 3;
>>   return;
>> }
>>
>> I am getting ssa dump as:
>>
>> /* Function foo (foo, funcdef_no=0, decl_uid=1744, cgraph_uid=0,
>> symbol_order=0)*/
>>
>> void
>> foo ()
>> {
>> bb_2:
>>   if (a_5 > 4)
>>     goto bb_3;
>>   else
>>     goto bb_4;
>>
>> bb_3:
>>   a_1 = 55;
>>   goto bb_5;
>>
>> bb_4:
>>   a_2 = 99;
>>
>>   a_3 = __PHI (bb_3: a_1, bb_4: a_2)
>> bb_5:
>>   a_4 = a_3 + 3;
>>   return;
>>
>> }
>>
>>> Richard.
>>>
>>>> Thanks,
>>>> Prathamesh
>>>>>
>>>>> Richard.
>>>>>
>>>>>>
>>>>>>> Richard.
>>>>>>>
>>>>>>>>Dave
>>>>>>>
>>>>>>>

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [gimplefe] hacking pass manager
  2016-07-27  8:53                                           ` Richard Biener
@ 2016-07-28 18:31                                             ` Prasad Ghangal
  2016-07-29  1:26                                               ` Prathamesh Kulkarni
  0 siblings, 1 reply; 29+ messages in thread
From: Prasad Ghangal @ 2016-07-28 18:31 UTC (permalink / raw)
  To: Richard Biener; +Cc: Prathamesh Kulkarni, David Malcolm, gcc Mailing List

[-- Attachment #1: Type: text/plain, Size: 22401 bytes --]

On 27 July 2016 at 14:22, Richard Biener <richard.guenther@gmail.com> wrote:
> On Tue, Jul 26, 2016 at 11:38 PM, Prathamesh Kulkarni
> <prathamesh.kulkarni@linaro.org> wrote:
>> On 27 July 2016 at 00:20, Prasad Ghangal <prasad.ghangal@gmail.com> wrote:
>>> On 20 July 2016 at 18:28, Richard Biener <richard.guenther@gmail.com> wrote:
>>>> On Wed, Jul 20, 2016 at 1:46 PM, Prathamesh Kulkarni
>>>> <prathamesh.kulkarni@linaro.org> wrote:
>>>>> On 20 July 2016 at 11:34, Richard Biener <richard.guenther@gmail.com> wrote:
>>>>>> On Tue, Jul 19, 2016 at 10:09 PM, Prasad Ghangal
>>>>>> <prasad.ghangal@gmail.com> wrote:
>>>>>>> On 19 July 2016 at 11:04, Richard Biener <richard.guenther@gmail.com> wrote:
>>>>>>>> On July 18, 2016 11:05:58 PM GMT+02:00, David Malcolm <dmalcolm@redhat.com> wrote:
>>>>>>>>>On Tue, 2016-07-19 at 00:52 +0530, Prasad Ghangal wrote:
>>>>>>>>>> On 19 July 2016 at 00:25, Richard Biener <richard.guenther@gmail.com>
>>>>>>>>>> wrote:
>>>>>>>>>> > On July 18, 2016 8:28:15 PM GMT+02:00, Prasad Ghangal <
>>>>>>>>>> > prasad.ghangal@gmail.com> wrote:
>>>>>>>>>> > > On 15 July 2016 at 16:13, Richard Biener <
>>>>>>>>>> > > richard.guenther@gmail.com>
>>>>>>>>>> > > wrote:
>>>>>>>>>> > > > On Sun, Jul 10, 2016 at 6:13 PM, Prasad Ghangal
>>>>>>>>>> > > > <prasad.ghangal@gmail.com> wrote:
>>>>>>>>>> > > > > On 8 July 2016 at 13:13, Richard Biener <
>>>>>>>>>> > > > > richard.guenther@gmail.com>
>>>>>>>>>> > > wrote:
>>>>>>>>>> > > > > > On Thu, Jul 7, 2016 at 9:45 PM, Prasad Ghangal
>>>>>>>>>> > > <prasad.ghangal@gmail.com> wrote:
>>>>>>>>>> > > > > > > On 6 July 2016 at 14:24, Richard Biener
>>>>>>>>>> > > <richard.guenther@gmail.com> wrote:
>>>>>>>>>> > > > > > > > On Wed, Jul 6, 2016 at 9:51 AM, Prasad Ghangal
>>>>>>>>>> > > <prasad.ghangal@gmail.com> wrote:
>>>>>>>>>> > > > > > > > > On 30 June 2016 at 17:10, Richard Biener
>>>>>>>>>> > > <richard.guenther@gmail.com> wrote:
>>>>>>>>>> > > > > > > > > > On Wed, Jun 29, 2016 at 9:13 PM, Prasad Ghangal
>>>>>>>>>> > > > > > > > > > <prasad.ghangal@gmail.com> wrote:
>>>>>>>>>> > > > > > > > > > > On 29 June 2016 at 22:15, Richard Biener
>>>>>>>>>> > > <richard.guenther@gmail.com> wrote:
>>>>>>>>>> > > > > > > > > > > > On June 29, 2016 6:20:29 PM GMT+02:00,
>>>>>>>>>> > > > > > > > > > > > Prathamesh Kulkarni
>>>>>>>>>> > > <prathamesh.kulkarni@linaro.org> wrote:
>>>>>>>>>> > > > > > > > > > > > > On 18 June 2016 at 12:02, Prasad Ghangal
>>>>>>>>>> > > <prasad.ghangal@gmail.com>
>>>>>>>>>> > > > > > > > > > > > > wrote:
>>>>>>>>>> > > > > > > > > > > > > > Hi,
>>>>>>>>>> > > > > > > > > > > > > >
>>>>>>>>>> > > > > > > > > > > > > > I tried hacking pass manager to execute
>>>>>>>>>> > > > > > > > > > > > > > only given passes.
>>>>>>>>>> > > For this I
>>>>>>>>>> > > > > > > > > > > > > > am adding new member as opt_pass
>>>>>>>>>> > > > > > > > > > > > > > *custom_pass_list to the
>>>>>>>>>> > > function
>>>>>>>>>> > > > > > > > > > > > > > structure to store passes need to execute
>>>>>>>>>> > > > > > > > > > > > > > and providing the
>>>>>>>>>> > > > > > > > > > > > > > custom_pass_list to execute_pass_list()
>>>>>>>>>> > > > > > > > > > > > > > function instead of
>>>>>>>>>> > > all
>>>>>>>>>> > > > > > > > > > > > > passes
>>>>>>>>>> > > > > > > > > > > > > >
>>>>>>>>>> > > > > > > > > > > > > > for test case like-
>>>>>>>>>> > > > > > > > > > > > > >
>>>>>>>>>> > > > > > > > > > > > > > int a;
>>>>>>>>>> > > > > > > > > > > > > > void __GIMPLE (execute ("tree-ccp1", "tree
>>>>>>>>>> > > > > > > > > > > > > > -fre1")) foo()
>>>>>>>>>> > > > > > > > > > > > > > {
>>>>>>>>>> > > > > > > > > > > > > > bb_1:
>>>>>>>>>> > > > > > > > > > > > > >   a = 1 + a;
>>>>>>>>>> > > > > > > > > > > > > > }
>>>>>>>>>> > > > > > > > > > > > > >
>>>>>>>>>> > > > > > > > > > > > > > it will execute only given passes i.e. ccp1
>>>>>>>>>> > > > > > > > > > > > > > and fre1 pass
>>>>>>>>>> > > on the
>>>>>>>>>> > > > > > > > > > > > > function
>>>>>>>>>> > > > > > > > > > > > > >
>>>>>>>>>> > > > > > > > > > > > > > and for test case like -
>>>>>>>>>> > > > > > > > > > > > > >
>>>>>>>>>> > > > > > > > > > > > > > int a;
>>>>>>>>>> > > > > > > > > > > > > > void __GIMPLE (startwith ("tree-ccp1"))
>>>>>>>>>> > > > > > > > > > > > > > foo()
>>>>>>>>>> > > > > > > > > > > > > > {
>>>>>>>>>> > > > > > > > > > > > > > bb_1:
>>>>>>>>>> > > > > > > > > > > > > >   a = 1 + a;
>>>>>>>>>> > > > > > > > > > > > > > }
>>>>>>>>>> > > > > > > > > > > > > >
>>>>>>>>>> > > > > > > > > > > > > > it will act as a entry point to the
>>>>>>>>>> > > > > > > > > > > > > > pipeline and will
>>>>>>>>>> > > execute passes
>>>>>>>>>> > > > > > > > > > > > > > starting from given pass.
>>>>>>>>>> > > > > > > > > > > > > Bike-shedding:
>>>>>>>>>> > > > > > > > > > > > > Would it make sense to have syntax for
>>>>>>>>>> > > > > > > > > > > > > defining pass ranges
>>>>>>>>>> > > to execute
>>>>>>>>>> > > > > > > > > > > > > ?
>>>>>>>>>> > > > > > > > > > > > > for instance:
>>>>>>>>>> > > > > > > > > > > > > void __GIMPLE(execute (pass_start :
>>>>>>>>>> > > > > > > > > > > > > pass_end))
>>>>>>>>>> > > > > > > > > > > > > which would execute all the passes within
>>>>>>>>>> > > > > > > > > > > > > range [pass_start,
>>>>>>>>>> > > pass_end],
>>>>>>>>>> > > > > > > > > > > > > which would be convenient if the range is
>>>>>>>>>> > > > > > > > > > > > > large.
>>>>>>>>>> > > > > > > > > > > >
>>>>>>>>>> > > > > > > > > > > > But it would rely on a particular pass
>>>>>>>>>> > > > > > > > > > > > pipeline, f.e.
>>>>>>>>>> > > pass-start appearing before pass-end.
>>>>>>>>>> > > > > > > > > > > >
>>>>>>>>>> > > > > > > > > > > > Currently control doesn't work 100% as it only
>>>>>>>>>> > > > > > > > > > > > replaces
>>>>>>>>>> > > all_optimizations but not lowering passes or early opts, nor IPA
>>>>>>>>>> > > opts.
>>>>>>>>>> > > > > > > > > > > >
>>>>>>>>>> > > > > > > > > > >
>>>>>>>>>> > > > > > > > > > > Each pass needs GIMPLE in some specific form. So
>>>>>>>>>> > > > > > > > > > > I am letting
>>>>>>>>>> > > lowering
>>>>>>>>>> > > > > > > > > > > and early opt passes to execute. I think we have
>>>>>>>>>> > > > > > > > > > > to execute
>>>>>>>>>> > > some
>>>>>>>>>> > > > > > > > > > > passes (like cfg) anyway to represent GIMPLE into
>>>>>>>>>> > > > > > > > > > > proper form
>>>>>>>>>> > > > > > > > > >
>>>>>>>>>> > > > > > > > > > Yes, that's true.  Note that early opt passes only
>>>>>>>>>> > > > > > > > > > optimize but
>>>>>>>>>> > > we need
>>>>>>>>>> > > > > > > > > > pass_build_ssa_passes at least (for into-SSA).  For
>>>>>>>>>> > > > > > > > > > proper
>>>>>>>>>> > > unit-testing
>>>>>>>>>> > > > > > > > > > of GIMPLE passes we do need to guard off early opts
>>>>>>>>>> > > > > > > > > > somehow
>>>>>>>>>> > > > > > > > > > (I guess a simple if (flag_gimple && cfun
>>>>>>>>>> > > > > > > > > > ->custom_pass_list)
>>>>>>>>>> > > would do
>>>>>>>>>> > > > > > > > > > that).
>>>>>>>>>> > > > > > > > > >
>>>>>>>>>> > > > > > > > > > Then there is of course the question about IPA
>>>>>>>>>> > > > > > > > > > passes which I
>>>>>>>>>> > > think is
>>>>>>>>>> > > > > > > > > > somewhat harder (one could always disable all IPA
>>>>>>>>>> > > > > > > > > > passes
>>>>>>>>>> > > manually
>>>>>>>>>> > > > > > > > > > via flags of course or finally have a global
>>>>>>>>>> > > > > > > > > > -fipa/no-ipa like
>>>>>>>>>> > > most
>>>>>>>>>> > > > > > > > > > other compilers).
>>>>>>>>>> > > > > > > > > >
>>>>>>>>>> > > > > > > > > Can we iterate through all ipa passes and do
>>>>>>>>>> > > > > > > > > -fdisable-ipa-pass
>>>>>>>>>> > > or
>>>>>>>>>> > > > > > > > > -fenable-ipa-pass equivalent for each?
>>>>>>>>>> > > > > > > >
>>>>>>>>>> > > > > > > > We could do that, yes.  But let's postpone this issue.
>>>>>>>>>> > > > > > > >  I think
>>>>>>>>>> > > that
>>>>>>>>>> > > > > > > > startwith is going to be most useful and rather than
>>>>>>>>>> > > > > > > > constructing
>>>>>>>>>> > > > > > > > a pass list for it "native" support for it in the pass
>>>>>>>>>> > > > > > > > manager is
>>>>>>>>>> > > > > > > > likely to produce better results (add a 'startwith'
>>>>>>>>>> > > > > > > > member
>>>>>>>>>> > > alongside
>>>>>>>>>> > > > > > > > the pass list member and if it is set the pass manager
>>>>>>>>>> > > > > > > > skips all
>>>>>>>>>> > > > > > > > passes that do not match 'startwith' and once it
>>>>>>>>>> > > > > > > > reaches it it
>>>>>>>>>> > > clears
>>>>>>>>>> > > > > > > > the field).
>>>>>>>>>> > > > > > > >
>>>>>>>>>> > > > > > > > In the future I hope we can get away from a static pass
>>>>>>>>>> > > > > > > > list and
>>>>>>>>>> > > more
>>>>>>>>>> > > > > > > > towards rule-driven pass execution (we have all those
>>>>>>>>>> > > > > > > > PROP_*
>>>>>>>>>> > > stuff
>>>>>>>>>> > > > > > > > already but it isn't really used for example).  But
>>>>>>>>>> > > > > > > > well, that
>>>>>>>>>> > > would be
>>>>>>>>>> > > > > > > > a separate GSoC project ;)
>>>>>>>>>> > > > > > > >
>>>>>>>>>> > > > > > > > IMHO startwith will provide everything needed for unit
>>>>>>>>>> > > > > > > > -testing.
>>>>>>>>>> > > We can
>>>>>>>>>> > > > > > > > add a flag on whether further passes should be executed
>>>>>>>>>> > > > > > > > or not
>>>>>>>>>> > > and
>>>>>>>>>> > > > > > > > even a pass list like execute ("ccp1", "fre") can be
>>>>>>>>>> > > > > > > > implemented
>>>>>>>>>> > > by
>>>>>>>>>> > > > > > > > startwith ccp1 and then from there executing the rest
>>>>>>>>>> > > > > > > > of the
>>>>>>>>>> > > passes in the
>>>>>>>>>> > > > > > > > list and stopping at the end.
>>>>>>>>>> > > > > > > >
>>>>>>>>>> > > > > > > > As said, unit-testing should exercise a single pass if
>>>>>>>>>> > > > > > > > we can
>>>>>>>>>> > > control
>>>>>>>>>> > > > > > > > its input.
>>>>>>>>>> > > > > > > >
>>>>>>>>>> > > > > > > In this patch I am skipping execution of passes until
>>>>>>>>>> > > pass_startwith
>>>>>>>>>> > > > > > > is found. Unlike previous build, now pass manager
>>>>>>>>>> > > > > > > executes all
>>>>>>>>>> > > passes
>>>>>>>>>> > > > > > > in pipeline starting from pass_startwith instead of just
>>>>>>>>>> > > > > > > sub
>>>>>>>>>> > > passes.
>>>>>>>>>> > > > > >
>>>>>>>>>> > > > > > That looks good.  I wonder if
>>>>>>>>>> > > > > >
>>>>>>>>>> > > > > > +  if (startwith_p && cfun->startwith)
>>>>>>>>>> > > > > > +    {
>>>>>>>>>> > > > > > +      if (pass->name == cfun->pass_startwith->name
>>>>>>>>>> > > > > > +         || pass->name == "*clean_state")
>>>>>>>>>> > > > > >
>>>>>>>>>> > > > > > need better be strcmp ()s though.  Also the early
>>>>>>>>>> > > > > > optimization
>>>>>>>>>> > > pipeline
>>>>>>>>>> > > > > > should be executed with startwith support as well.
>>>>>>>>>> > > > > >
>>>>>>>>>> > > > >
>>>>>>>>>> > > > > This patch adds startwith support for early opt passes. But
>>>>>>>>>> > > > > for
>>>>>>>>>> > > > > starting from some passes (like asan0, optimized) in
>>>>>>>>>> > > > > all_passes
>>>>>>>>>> > > > > pipeline, it falils at verify_curr_properties in
>>>>>>>>>> > > > > execute_one_pass
>>>>>>>>>> > > ().
>>>>>>>>>> > > > > I wonder if we need to update properties after skipping each
>>>>>>>>>> > > > > pass
>>>>>>>>>> > > >
>>>>>>>>>> > > > Yeah, it's not possible to start at arbitrary points with
>>>>>>>>>> > > > skipping
>>>>>>>>>> > > passes
>>>>>>>>>> > > > that provide a required property.  I suspect it's good enough
>>>>>>>>>> > > > that
>>>>>>>>>> > > we'll
>>>>>>>>>> > > > ICE if that happens.
>>>>>>>>>> > > >
>>>>>>>>>> > > > I see you are working on the dump-file side a bit now.  What is
>>>>>>>>>> > > > still
>>>>>>>>>> > > > missing after you got support for PHIs is parsing of SSA names.
>>>>>>>>>> > > > Without this unit-testing will be difficult at best.
>>>>>>>>>> > > >
>>>>>>>>>> > > > I think what we need to do is simplify the job of the parser
>>>>>>>>>> > > > and
>>>>>>>>>> > > > make the syntax we use to print SSA names a bit different.
>>>>>>>>>> > > > So rather than printing VAR_VERSION we need to choose a
>>>>>>>>>> > > > letter that is not part of a valid identifier before VERSION,
>>>>>>>>>> > > > like a dot '.'.  Thus we'd have i.1 instead of i_1 and we'd
>>>>>>>>>> > > > have
>>>>>>>>>> > > > .2 instead of _2 for an anonymous SSA name.  The advantage
>>>>>>>>>> > > > for non-anonymous names is that we can properly re-use the
>>>>>>>>>> > > > C frontends decl handling for declaring and looking up 'i'.
>>>>>>>>>> > > > The disadvantage is that for anonymous SSA names this isn't
>>>>>>>>>> > > > so easy which means we could choose to not support those
>>>>>>>>>> > > > for the moment and require fake decls for them.  In fact
>>>>>>>>>> > > > into-SSA will do the correct thing if we just treat them as
>>>>>>>>>> > > > decls,
>>>>>>>>>> > > > thus continue to dump them as _VERSION.
>>>>>>>>>> > > >
>>>>>>>>>> > >
>>>>>>>>>> > > I am little confused here about parsing 'i.1' because lexer drops
>>>>>>>>>> > > DOT
>>>>>>>>>> > > token for syntax like NAME.NUMBER . Hence instead of 'i.1' parser
>>>>>>>>>> > > receives 'i1'
>>>>>>>>>> >
>>>>>>>>>> > Are you sure? You should get three tokens, one for 'i', one for the
>>>>>>>>>> > dot and
>>>>>>>>>> > One for '1'.  You'd lookup the first via the C frontend symbol
>>>>>>>>>> > table only.
>>>>>>>>>> >
>>>>>>>>>>
>>>>>>>>>> Yes, I was also expecting that. For syntax like 'a.b' (ie name.name)
>>>>>>>>>> it gives proper 3 tokens but for syntax like 'a.1' it produces only
>>>>>>>>>> 2.
>>>>>>>>>>
>>>>>>>>>> This is what I observed while debugging "int a.1;"
>>>>>>>>>>
>>>>>>>>>> (gdb) print *c_parser_peek_nth_token (parser, 1)
>>>>>>>>>> $3 = {type = CPP_KEYWORD, id_kind = C_ID_NONE, keyword = RID_INT,
>>>>>>>>>>   pragma_kind = PRAGMA_NONE, location = 242114, value =
>>>>>>>>>> 0x7ffff65c82d0}
>>>>>>>>>> (gdb) print *c_parser_peek_nth_token (parser, 2)
>>>>>>>>>> $4 = {type = CPP_NAME, id_kind = C_ID_ID, keyword = RID_MAX,
>>>>>>>>>>   pragma_kind = PRAGMA_NONE, location = 242240, value =
>>>>>>>>>> 0x7ffff66d0b90}
>>>>>>>>>> (gdb) print *c_parser_peek_nth_token (parser, 3)
>>>>>>>>>> $5 = {type = CPP_NUMBER, id_kind = C_ID_NONE, keyword = RID_MAX,
>>>>>>>>>>   pragma_kind = PRAGMA_NONE, location = 242273, value =
>>>>>>>>>> 0x7ffff66e0030}
>>>>>>>>>
>>>>>>>>>What is the number?  I'm wondering if it's somehow been lexed as a
>>>>>>>>>decimal ".1" i.e. if the "." is somehow being treated as part of the
>>>>>>>>>CPP_NUMBER.
>>>>>>>>
>>>>>>>
>>>>>>> Yes, the token '.1' is treated as CPP_NUMBER
>>>>>>>
>>>>>>>> Ah, possible...
>>>>>>>>
>>>>>>>>>FWIW, I find hacking in calls to "inform" very useful for seeing what
>>>>>>>>>each token is (assuming that caret printing isn't disabled).
>>>>>>>>>
>>>>>>>>>  (gdb) call inform ($3->location, "")
>>>>>>>>>  (gdb) call inform ($4->location, "")
>>>>>>>>>  (gdb) call inform ($5
>>>>>>>>>->location, "")
>>>>>>>>>
>>>>>>>>>etc
>>>>>>>>>
>>>>>>>>>BTW, does it have to be '.' as the SSA_NAME separator?  Could it be a
>>>>>>>>>different character e.g. '@' or something else that's non-legal in C?
>>>>>>>>
>>>>>>>> It doesn't have to be '.', but sth visually not too disturbing would be nice.  If we don't go with '.' We can as well try to parse the SSA version from i_1, leaving the ambiguity with it being a valid C identifier.
>>>>>>>>
>>>>>>>
>>>>>>> As special characters are not valid in C, I am using 'a..1' as syntax
>>>>>>> for ssa name. For parsing I am using
>>>>>>> +      lhs.value = make_ssa_name_fn (cfun,
>>>>>>> +                                   lookup_name (c_parser_peek_token
>>>>>>> (parser)->value),
>>>>>>> +                                   NULL);
>>>>>>> Now for passing ssa name into __PHI, how can we lookup for particular ssa name.
>>>>>>> Or is there other better method to do it?
>>>>>>
>>>>>> Note that with this you need to preserve SSA versions as used in the source
>>>>>> (the 1 in a..1).  If you can do that (see below) the way to lookup an SSA name
>>>>>> is simply calling 'ssa_name (version)' with version being an integer with the
>>>>>> version number.
>>>>>>
>>>>>> make_ssa_name will simply allocate the next available SSA version so
>>>>>> you'll need to add an interface that allows you allocation of a specific
>>>>>> SSA version.  Like with sth similar to
>>>>>>
>>>>>> Index: gcc/tree-ssanames.c
>>>>>> ===================================================================
>>>>>> --- gcc/tree-ssanames.c (revision 238512)
>>>>>> +++ gcc/tree-ssanames.c (working copy)
>>>>>> @@ -255,7 +255,7 @@
>>>>>>     used without a preceding definition).  */
>>>>>>
>>>>>>  tree
>>>>>> -make_ssa_name_fn (struct function *fn, tree var, gimple *stmt)
>>>>>> +make_ssa_name_fn (struct function *fn, tree var, gimple *stmt, int version)
>>>>>>  {
>>>>>>    tree t;
>>>>>>    use_operand_p imm;
>>>>>> @@ -265,8 +265,17 @@
>>>>>>               || TREE_CODE (var) == RESULT_DECL
>>>>>>               || (TYPE_P (var) && is_gimple_reg_type (var)));
>>>>>>
>>>>>> +  if (version != 0)
>>>>>> +    {
>>>>>> +      t = make_node (SSA_NAME);
>>>>>> +      SSA_NAME_VERSION (t) = version;
>>>>>> +      vec_safe_grow_cleared (SSANAMES (fn), version + 1);
>>>>>> +      gcc_assert ((*SSANAMES (fn))[version] == NULL);
>>>>>> +      (*SSANAMES (fn))[version] = t;
>>>>>> +      ssa_name_nodes_created++;
>>>>>> +    }
>>>>>>    /* If our free list has an element, then use it.  */
>>>>>> -  if (!vec_safe_is_empty (FREE_SSANAMES (fn)))
>>>>>> +  else if (!vec_safe_is_empty (FREE_SSANAMES (fn)))
>>>>>>      {
>>>>>>        t = FREE_SSANAMES (fn)->pop ();
>>>>>>        ssa_name_nodes_reused++;
>>>>>> Index: gcc/tree-ssanames.h
>>>>>> ===================================================================
>>>>>> --- gcc/tree-ssanames.h (revision 237253)
>>>>>> +++ gcc/tree-ssanames.h (working copy)
>>>>>> @@ -79,7 +79,7 @@
>>>>>>  extern void init_ssanames (struct function *, int);
>>>>>>  extern void fini_ssanames (struct function *);
>>>>>>  extern void ssanames_print_statistics (void);
>>>>>> -extern tree make_ssa_name_fn (struct function *, tree, gimple *);
>>>>>> +extern tree make_ssa_name_fn (struct function *, tree, gimple *, int);
>>>>>>  extern void release_ssa_name_fn (struct function *, tree);
>>>>>>  extern bool get_ptr_info_alignment (struct ptr_info_def *, unsigned int *,
>>>>>>                                     unsigned int *);
>>>>>>
>>>>>> where you can then do sth like
>>>>>>
>>>>>>   ssaname = ssa_name (version);
>>>>>>   if (!ssaname)
>>>>>>     ssaname = make_ssa_name_fn (cfun, lookup_name (...), NULL, version);
>>>>>>
>>>>>> to either lookup an existing or allocate a new SSA name of the desired version.
>>>>>>
>>>>>> Just for some bike-shedding, I don't like using '..' too much ;)
>>>>> Would it be a good idea to modify libcpp's lexer to recognize
>>>>> identifier.number as a single token if -fgimple is enabled ?
>>>>
>>>> I don't think so.  As said, we can retain the i_2 syntax as well where you then
>>>> get a single token and to decide whether it is a SSA name do a lookup for
>>>> 'i' first and if that succeeds, interpret _2 as a version suffix,
>>>> otherwise use it
>>>> as full variable name.  Re-constructing the 1 from .1 or 17 from .17 CPP_NUMBER
>>>> is possible as well of course.
>>>>
>>>
>>> Sorry for the late response. I was little busy due to some family problem.
>>>
>>> In this patch, I am parsing ssa names as described above. But the
>>> problem is non ssa variable also gets renamed
>> I assume you're referring to renaming of a to a_5 here ?
>> I suppose that's expected since 'a' is gimple reg, ssa pass will
>> create ssa name for it.
>> Maybe emit "parse error" if local var is not in "ssa syntax", that is,
>> it doesn't
>> have _version suffixed ? But emitting an error for this case looks
>> artificial to me.
>
> Yes, I think the result is as expected.  If we want to constrain the
> input to the
> GIMPLE parser then we somehow have to tell it what kind of GIMPLE we are
> presenting it (SSA or non-SSA gimple), but for the moment what you have
> and show with the testcase looks good to me.
>
> The parsing doesn't handle
>
> void __GIMPLE () foo ()
> {
>   int a_3;
>   a_3_1 = 0;
> }
>
> correctly as it looks for the first '_' rather than the last.  I'd have used
> sth like
>
>   char *p = strrchr (ssa_token, '_');
>   if (p)
>     {
>       var_name = new char [p - ssa_token + 1];
>       memcpy (var_name, ssa_token, p - ssa_token);
>       var_name[p - ssa_token] = '\0';
>       ...
>       version = atoi (p);
>
> in the patch you have two copies of the SSA name parsing code - you want to
> split that out into a function.
>
> There is one other feature missing for SSA name parsing (forget to mention that)
> which is parsing of default def SSA names.  Those are for example used for
> parameters and currently dumped like
>
> foo (int i)
> {
>   int D.1759;
>   int _2;
>
>   <bb 2>:
>   _2 = i_1(D) + 1;
>   return _2;
> }
>
> for int foo (int i) { return i + 1; }.  Here 'i_1(D)' is the
> default-def of 'i' which
> in case of a parameter is the value at function start and in case of a
> non-parameter
> is simply "undefined".  '(D)' is again somewhat awkward to parse but I guess we
> can cope with that ;)  A default-def needs to be registered like
>
>   arg = make_ssa_name_fn (cfun, lookup_name (id), ...);
>   set_ssa_default_def (cfun, lookup_name (id), arg);
>
> "undefined" SSA names appear often in PHIs (and of course for parameters).
>

This updated patch tries to parse default def ssa names

Thanks,
Prasad

> Thanks,
> Richard.
>
>> Thanks,
>> Prathamesh
>>>
>>> for testcase :
>>>
>>> void __GIMPLE () foo()
>>> {
>>>   int a;
>>> bb_2:
>>>   if (a > 4)
>>>     goto bb_3;
>>>   else
>>>     goto bb_4;
>>> bb_3:
>>>   a_1 = 55;
>>>   goto bb_5;
>>>
>>> bb_4:
>>>   a_2 = 99;
>>>
>>> bb_5:
>>>   a_3 = __PHI (bb_3: a_1, bb_4: a_2);
>>>   a_4 = a_3 + 3;
>>>   return;
>>> }
>>>
>>> I am getting ssa dump as:
>>>
>>> /* Function foo (foo, funcdef_no=0, decl_uid=1744, cgraph_uid=0,
>>> symbol_order=0)*/
>>>
>>> void
>>> foo ()
>>> {
>>> bb_2:
>>>   if (a_5 > 4)
>>>     goto bb_3;
>>>   else
>>>     goto bb_4;
>>>
>>> bb_3:
>>>   a_1 = 55;
>>>   goto bb_5;
>>>
>>> bb_4:
>>>   a_2 = 99;
>>>
>>>   a_3 = __PHI (bb_3: a_1, bb_4: a_2)
>>> bb_5:
>>>   a_4 = a_3 + 3;
>>>   return;
>>>
>>> }
>>>
>>>> Richard.
>>>>
>>>>> Thanks,
>>>>> Prathamesh
>>>>>>
>>>>>> Richard.
>>>>>>
>>>>>>>
>>>>>>>> Richard.
>>>>>>>>
>>>>>>>>>Dave
>>>>>>>>
>>>>>>>>

[-- Attachment #2: ssa.patch --]
[-- Type: text/x-diff, Size: 10406 bytes --]

diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index 1a55b9a..1d2fc2d 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -66,6 +66,9 @@ along with GCC; see the file COPYING3.  If not see
 #include "gimple-pretty-print.h"
 #include "tree-ssa.h"
 #include "pass_manager.h"
+#include "tree-ssanames.h"
+#include "gimple-ssa.h"
+#include "tree-dfa.h"
 
 /* We need to walk over decls with incomplete struct/union/enum types
    after parsing the whole translation unit.
@@ -1421,7 +1424,7 @@ static void c_parser_gimple_if_stmt (c_parser *, gimple_seq *);
 static void c_parser_gimple_switch_stmt (c_parser *, gimple_seq *);
 static void c_parser_gimple_return_stmt (c_parser *, gimple_seq *);
 static void c_finish_gimple_return (location_t, tree);
-
+static c_expr c_parser_parse_ssa_names (c_parser *);
 
 /* Parse a translation unit (C90 6.7, C99 6.9).
 
@@ -1666,7 +1669,7 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
   location_t here = c_parser_peek_token (parser)->location;
   bool gimple_body_p = false;
   opt_pass *pass = NULL;
-  bool startwith_p;
+  bool startwith_p = false;
 
   if (static_assert_ok
       && c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
@@ -1723,7 +1726,6 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
       if (kw_token->keyword == RID_GIMPLE)
 	{
 	  gimple_body_p = true;
-	  startwith_p = false;
 	  c_parser_consume_token (parser);
 	  c_parser_gimple_pass_list (parser, &pass, &startwith_p);
 	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 
@@ -18145,7 +18147,7 @@ c_parser_parse_gimple_body (c_parser *parser)
   location_t loc1 = c_parser_peek_token (parser)->location;
   seq = NULL;
   body = NULL;
-  
+  init_tree_ssa (cfun);
   return_p = c_parser_gimple_compound_statement (parser, &seq);
 
   if (!return_p)
@@ -18173,7 +18175,6 @@ c_parser_parse_gimple_body (c_parser *parser)
   cfun->curr_properties = PROP_gimple_any;
   if (flag_gdebug)
     debug_gimple_seq (seq);
-  init_tree_ssa (cfun);
   return;
 }
 
@@ -18361,7 +18362,7 @@ c_parser_gimple_expression (c_parser *parser, gimple_seq *seq)
 
       gcall *call_stmt;
       /* Gimplify internal functions. */
-      tree arg;
+      tree arg = NULL_TREE;
       vec<tree> vargs = vNULL;
 
       if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
@@ -18386,7 +18387,7 @@ c_parser_gimple_expression (c_parser *parser, gimple_seq *seq)
 	    }
 	  else
 	    {
-	      arg = c_parser_gimple_unary_expression (parser).value;
+	      arg = c_parser_parse_ssa_names (parser).value;
 	      vargs.safe_push (arg);
 	    }
 	}
@@ -18481,7 +18482,7 @@ c_parser_gimple_binary_expression (c_parser *parser, enum tree_code *subcode)
     sp--;								      \
   } while (0)
   stack[0].loc = c_parser_peek_token (parser)->location;
-  stack[0].expr = c_parser_cast_expression (parser, NULL);
+  stack[0].expr = c_parser_gimple_unary_expression (parser);
   stack[0].prec = PREC_NONE;
   sp = 0;
   enum c_parser_prec oprec;
@@ -18601,7 +18602,7 @@ c_parser_gimple_binary_expression (c_parser *parser, enum tree_code *subcode)
     }
   sp++;
   stack[sp].loc = binary_loc;
-  stack[sp].expr = c_parser_cast_expression (parser, NULL);
+  stack[sp].expr = c_parser_gimple_unary_expression (parser);
   stack[sp].prec = oprec;
   stack[sp].op = *subcode;
 out:
@@ -18618,6 +18619,10 @@ static c_expr
 c_parser_gimple_unary_expression (c_parser *parser)
 {
   struct c_expr ret, op;
+  if (TREE_CODE (c_parser_peek_token (parser)->value) == IDENTIFIER_NODE
+      && !lookup_name (c_parser_peek_token (parser)->value))
+    return c_parser_parse_ssa_names (parser);
+
   location_t op_loc = c_parser_peek_token (parser)->location;
   location_t exp_loc;
   location_t finish;
@@ -18676,6 +18681,56 @@ c_parser_gimple_unary_expression (c_parser *parser)
     }
 }
 
+/* Parse ssa names */
+
+static c_expr
+c_parser_parse_ssa_names (c_parser *parser)
+{
+  tree id = NULL_TREE;
+  c_expr ret;
+  char *var_name, *var_version, *token;
+  ret.original_code = ERROR_MARK;
+  ret.original_type = NULL;
+  const char *ssa_token = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
+  token = new char [strlen (ssa_token)];
+  strcpy (token, ssa_token);
+  var_version = strrchr (token, '_');
+  if (var_version)
+    {
+      var_name = new char[var_version - token + 1];
+      memcpy (var_name, token, var_version - token);
+      var_name[var_version - token] = '\0';
+      id = get_identifier (var_name);
+      if (lookup_name (id))
+	{
+	  var_version++;
+	  unsigned int version;
+	  version = atoi (var_version);
+	  if (var_version && version)
+	    {
+	      ret.value = NULL_TREE;
+	      if (version < num_ssa_names)
+		ret.value = ssa_name (version);
+	      if (!ret.value)
+		ret.value = make_ssa_name_fn (cfun, lookup_name (id), gimple_build_nop (), version);
+	      c_parser_consume_token (parser);
+	    }
+	}
+    }
+  if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
+    {
+      c_parser_consume_token (parser);
+      if (!strcmp ("D",IDENTIFIER_POINTER (c_parser_peek_token (parser)->value)))
+	{
+	  set_ssa_default_def (cfun, lookup_name (id), ret.value);
+	  c_parser_consume_token (parser);
+	}
+      if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
+	return ret;
+    }
+  return ret;
+}
+
 /*Parser gimple postfix expression*/
 
 static struct c_expr 
@@ -18868,7 +18923,7 @@ c_parser_gimple_pass_list_params (c_parser *parser, opt_pass **pass)
 
       if (c_parser_next_token_is (parser, CPP_STRING))
 	{
-	  const char *name = TREE_STRING_POINTER(c_parser_peek_token (parser)->value);
+	  const char *name = TREE_STRING_POINTER (c_parser_peek_token (parser)->value);
 	  c_parser_consume_token (parser);
 	  new_pass = g->get_passes ()->get_pass_by_name (name);
 
@@ -19205,7 +19260,7 @@ c_finish_gimple_return (location_t loc, tree retval)
 		  "declared here");
 	}
     }
-  else if (TREE_CODE (valtype) != TREE_CODE (retval))
+  else if (TREE_CODE (valtype) != TREE_CODE (TREE_TYPE (retval)))
     {
       error_at
 	(xloc, "invalid conversion in return statement");
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index 8842cec..288e983 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -347,6 +347,7 @@ replace_loop_annotate (void)
 }
 
 /* Lower internal PHI function from GIMPLE FE */
+
 static void 
 lower_phi_internal_fn ()
 {
@@ -356,8 +357,8 @@ lower_phi_internal_fn ()
   gphi *phi_node;
   gimple *stmt;
   int len, capacity;
-  /* After edge creation, handle __PHI function from GIMPLE FE */
 
+  /* After edge creation, handle __PHI function from GIMPLE FE */
   FOR_EACH_BB_FN (bb, cfun)
     {
       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
@@ -368,12 +369,10 @@ lower_phi_internal_fn ()
 
 	  if (gimple_call_internal_p (stmt) && gimple_call_internal_fn (stmt) == IFN_PHI)
 	    {
-	     gsi_remove (&gsi, true);
+	      gsi_remove (&gsi, true);
 	      int i;
 	      lhs = gimple_call_lhs (stmt);
-	      
 	      phi_node = create_phi_node (lhs, bb);
-	      
 	      for (i = 0; i < gimple_call_num_args (stmt); ++i)
 		{
 		  tree arg = gimple_call_arg (stmt, i);
@@ -7625,7 +7624,7 @@ dump_function_to_file (tree fndecl, FILE *file, int flags)
 	for (ix = 1; ix < num_ssa_names; ++ix)
 	  {
 	    tree name = ssa_name (ix);
-	    if (!virtual_operand_p (name))
+	    if (name && !SSA_NAME_VAR (name))
 	      {
 		fprintf (file, "  ");
 		print_generic_expr (file, TREE_TYPE (name), flags);
diff --git a/gcc/tree-into-ssa.c b/gcc/tree-into-ssa.c
index 71150ac..46c47d4 100644
--- a/gcc/tree-into-ssa.c
+++ b/gcc/tree-into-ssa.c
@@ -1386,7 +1386,8 @@ rewrite_add_phi_arguments (basic_block bb)
 	  /* If we have pre-existing PHI its args may be different 
 	     vars than existing vars */
 	  argvar = gimple_phi_arg_def (phi, e->dest_idx);
-	  gcc_assert (!argvar || TREE_CODE (argvar) != SSA_NAME);
+	  if (argvar && TREE_CODE (argvar) == SSA_NAME)
+	    continue;
 	  if (!argvar)
 	    argvar = SSA_NAME_VAR (res);
 	  currdef = get_reaching_def (argvar);
diff --git a/gcc/tree-pretty-print.c b/gcc/tree-pretty-print.c
index 0760587..03ade22 100644
--- a/gcc/tree-pretty-print.c
+++ b/gcc/tree-pretty-print.c
@@ -2704,6 +2704,10 @@ dump_generic_node (pretty_printer *pp, tree node, int spc, int flags,
 	}
       pp_underscore (pp);
       pp_decimal_int (pp, SSA_NAME_VERSION (node));
+      if (SSA_NAME_IS_DEFAULT_DEF (node))
+	pp_string (pp, "(D)");
+      if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (node))
+	pp_string (pp, "(ab)");
       break;
 
     case WITH_SIZE_EXPR:
diff --git a/gcc/tree-ssanames.c b/gcc/tree-ssanames.c
index 91a8f97..3017b51 100644
--- a/gcc/tree-ssanames.c
+++ b/gcc/tree-ssanames.c
@@ -255,7 +255,7 @@ flush_ssaname_freelist (void)
    used without a preceding definition).  */
 
 tree
-make_ssa_name_fn (struct function *fn, tree var, gimple *stmt)
+make_ssa_name_fn (struct function *fn, tree var, gimple *stmt, unsigned int version)
 {
   tree t;
   use_operand_p imm;
@@ -265,8 +265,18 @@ make_ssa_name_fn (struct function *fn, tree var, gimple *stmt)
 	      || TREE_CODE (var) == RESULT_DECL
 	      || (TYPE_P (var) && is_gimple_reg_type (var)));
 
+  if (version != 0)
+    {
+      t = make_node (SSA_NAME);
+      SSA_NAME_VERSION (t) = version;
+      if (version >= SSANAMES (fn)->length ())
+	vec_safe_grow_cleared (SSANAMES (fn), version + 1);
+      gcc_assert ((*SSANAMES (fn))[version] == NULL);
+      (*SSANAMES (fn))[version] = t;
+      ssa_name_nodes_created++;
+    }
   /* If our free list has an element, then use it.  */
-  if (!vec_safe_is_empty (FREE_SSANAMES (fn)))
+  else if (!vec_safe_is_empty (FREE_SSANAMES (fn)))
     {
       t = FREE_SSANAMES (fn)->pop ();
       ssa_name_nodes_reused++;
diff --git a/gcc/tree-ssanames.h b/gcc/tree-ssanames.h
index c81b1a1..228f021 100644
--- a/gcc/tree-ssanames.h
+++ b/gcc/tree-ssanames.h
@@ -79,7 +79,7 @@ extern bool ssa_name_has_boolean_range (tree);
 extern void init_ssanames (struct function *, int);
 extern void fini_ssanames (struct function *);
 extern void ssanames_print_statistics (void);
-extern tree make_ssa_name_fn (struct function *, tree, gimple *);
+extern tree make_ssa_name_fn (struct function *, tree, gimple *, unsigned int version = 0);
 extern void release_ssa_name_fn (struct function *, tree);
 extern bool get_ptr_info_alignment (struct ptr_info_def *, unsigned int *,
 				    unsigned int *);

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [gimplefe] hacking pass manager
  2016-07-28 18:31                                             ` Prasad Ghangal
@ 2016-07-29  1:26                                               ` Prathamesh Kulkarni
  2016-07-29  7:03                                                 ` Prasad Ghangal
  0 siblings, 1 reply; 29+ messages in thread
From: Prathamesh Kulkarni @ 2016-07-29  1:26 UTC (permalink / raw)
  To: Prasad Ghangal; +Cc: Richard Biener, David Malcolm, gcc Mailing List

On 29 July 2016 at 00:01, Prasad Ghangal <prasad.ghangal@gmail.com> wrote:
> On 27 July 2016 at 14:22, Richard Biener <richard.guenther@gmail.com> wrote:
>> On Tue, Jul 26, 2016 at 11:38 PM, Prathamesh Kulkarni
>> <prathamesh.kulkarni@linaro.org> wrote:
>>> On 27 July 2016 at 00:20, Prasad Ghangal <prasad.ghangal@gmail.com> wrote:
>>>> On 20 July 2016 at 18:28, Richard Biener <richard.guenther@gmail.com> wrote:
>>>>> On Wed, Jul 20, 2016 at 1:46 PM, Prathamesh Kulkarni
>>>>> <prathamesh.kulkarni@linaro.org> wrote:
>>>>>> On 20 July 2016 at 11:34, Richard Biener <richard.guenther@gmail.com> wrote:
>>>>>>> On Tue, Jul 19, 2016 at 10:09 PM, Prasad Ghangal
>>>>>>> <prasad.ghangal@gmail.com> wrote:
>>>>>>>> On 19 July 2016 at 11:04, Richard Biener <richard.guenther@gmail.com> wrote:
>>>>>>>>> On July 18, 2016 11:05:58 PM GMT+02:00, David Malcolm <dmalcolm@redhat.com> wrote:
>>>>>>>>>>On Tue, 2016-07-19 at 00:52 +0530, Prasad Ghangal wrote:
>>>>>>>>>>> On 19 July 2016 at 00:25, Richard Biener <richard.guenther@gmail.com>
>>>>>>>>>>> wrote:
>>>>>>>>>>> > On July 18, 2016 8:28:15 PM GMT+02:00, Prasad Ghangal <
>>>>>>>>>>> > prasad.ghangal@gmail.com> wrote:
>>>>>>>>>>> > > On 15 July 2016 at 16:13, Richard Biener <
>>>>>>>>>>> > > richard.guenther@gmail.com>
>>>>>>>>>>> > > wrote:
>>>>>>>>>>> > > > On Sun, Jul 10, 2016 at 6:13 PM, Prasad Ghangal
>>>>>>>>>>> > > > <prasad.ghangal@gmail.com> wrote:
>>>>>>>>>>> > > > > On 8 July 2016 at 13:13, Richard Biener <
>>>>>>>>>>> > > > > richard.guenther@gmail.com>
>>>>>>>>>>> > > wrote:
>>>>>>>>>>> > > > > > On Thu, Jul 7, 2016 at 9:45 PM, Prasad Ghangal
>>>>>>>>>>> > > <prasad.ghangal@gmail.com> wrote:
>>>>>>>>>>> > > > > > > On 6 July 2016 at 14:24, Richard Biener
>>>>>>>>>>> > > <richard.guenther@gmail.com> wrote:
>>>>>>>>>>> > > > > > > > On Wed, Jul 6, 2016 at 9:51 AM, Prasad Ghangal
>>>>>>>>>>> > > <prasad.ghangal@gmail.com> wrote:
>>>>>>>>>>> > > > > > > > > On 30 June 2016 at 17:10, Richard Biener
>>>>>>>>>>> > > <richard.guenther@gmail.com> wrote:
>>>>>>>>>>> > > > > > > > > > On Wed, Jun 29, 2016 at 9:13 PM, Prasad Ghangal
>>>>>>>>>>> > > > > > > > > > <prasad.ghangal@gmail.com> wrote:
>>>>>>>>>>> > > > > > > > > > > On 29 June 2016 at 22:15, Richard Biener
>>>>>>>>>>> > > <richard.guenther@gmail.com> wrote:
>>>>>>>>>>> > > > > > > > > > > > On June 29, 2016 6:20:29 PM GMT+02:00,
>>>>>>>>>>> > > > > > > > > > > > Prathamesh Kulkarni
>>>>>>>>>>> > > <prathamesh.kulkarni@linaro.org> wrote:
>>>>>>>>>>> > > > > > > > > > > > > On 18 June 2016 at 12:02, Prasad Ghangal
>>>>>>>>>>> > > <prasad.ghangal@gmail.com>
>>>>>>>>>>> > > > > > > > > > > > > wrote:
>>>>>>>>>>> > > > > > > > > > > > > > Hi,
>>>>>>>>>>> > > > > > > > > > > > > >
>>>>>>>>>>> > > > > > > > > > > > > > I tried hacking pass manager to execute
>>>>>>>>>>> > > > > > > > > > > > > > only given passes.
>>>>>>>>>>> > > For this I
>>>>>>>>>>> > > > > > > > > > > > > > am adding new member as opt_pass
>>>>>>>>>>> > > > > > > > > > > > > > *custom_pass_list to the
>>>>>>>>>>> > > function
>>>>>>>>>>> > > > > > > > > > > > > > structure to store passes need to execute
>>>>>>>>>>> > > > > > > > > > > > > > and providing the
>>>>>>>>>>> > > > > > > > > > > > > > custom_pass_list to execute_pass_list()
>>>>>>>>>>> > > > > > > > > > > > > > function instead of
>>>>>>>>>>> > > all
>>>>>>>>>>> > > > > > > > > > > > > passes
>>>>>>>>>>> > > > > > > > > > > > > >
>>>>>>>>>>> > > > > > > > > > > > > > for test case like-
>>>>>>>>>>> > > > > > > > > > > > > >
>>>>>>>>>>> > > > > > > > > > > > > > int a;
>>>>>>>>>>> > > > > > > > > > > > > > void __GIMPLE (execute ("tree-ccp1", "tree
>>>>>>>>>>> > > > > > > > > > > > > > -fre1")) foo()
>>>>>>>>>>> > > > > > > > > > > > > > {
>>>>>>>>>>> > > > > > > > > > > > > > bb_1:
>>>>>>>>>>> > > > > > > > > > > > > >   a = 1 + a;
>>>>>>>>>>> > > > > > > > > > > > > > }
>>>>>>>>>>> > > > > > > > > > > > > >
>>>>>>>>>>> > > > > > > > > > > > > > it will execute only given passes i.e. ccp1
>>>>>>>>>>> > > > > > > > > > > > > > and fre1 pass
>>>>>>>>>>> > > on the
>>>>>>>>>>> > > > > > > > > > > > > function
>>>>>>>>>>> > > > > > > > > > > > > >
>>>>>>>>>>> > > > > > > > > > > > > > and for test case like -
>>>>>>>>>>> > > > > > > > > > > > > >
>>>>>>>>>>> > > > > > > > > > > > > > int a;
>>>>>>>>>>> > > > > > > > > > > > > > void __GIMPLE (startwith ("tree-ccp1"))
>>>>>>>>>>> > > > > > > > > > > > > > foo()
>>>>>>>>>>> > > > > > > > > > > > > > {
>>>>>>>>>>> > > > > > > > > > > > > > bb_1:
>>>>>>>>>>> > > > > > > > > > > > > >   a = 1 + a;
>>>>>>>>>>> > > > > > > > > > > > > > }
>>>>>>>>>>> > > > > > > > > > > > > >
>>>>>>>>>>> > > > > > > > > > > > > > it will act as a entry point to the
>>>>>>>>>>> > > > > > > > > > > > > > pipeline and will
>>>>>>>>>>> > > execute passes
>>>>>>>>>>> > > > > > > > > > > > > > starting from given pass.
>>>>>>>>>>> > > > > > > > > > > > > Bike-shedding:
>>>>>>>>>>> > > > > > > > > > > > > Would it make sense to have syntax for
>>>>>>>>>>> > > > > > > > > > > > > defining pass ranges
>>>>>>>>>>> > > to execute
>>>>>>>>>>> > > > > > > > > > > > > ?
>>>>>>>>>>> > > > > > > > > > > > > for instance:
>>>>>>>>>>> > > > > > > > > > > > > void __GIMPLE(execute (pass_start :
>>>>>>>>>>> > > > > > > > > > > > > pass_end))
>>>>>>>>>>> > > > > > > > > > > > > which would execute all the passes within
>>>>>>>>>>> > > > > > > > > > > > > range [pass_start,
>>>>>>>>>>> > > pass_end],
>>>>>>>>>>> > > > > > > > > > > > > which would be convenient if the range is
>>>>>>>>>>> > > > > > > > > > > > > large.
>>>>>>>>>>> > > > > > > > > > > >
>>>>>>>>>>> > > > > > > > > > > > But it would rely on a particular pass
>>>>>>>>>>> > > > > > > > > > > > pipeline, f.e.
>>>>>>>>>>> > > pass-start appearing before pass-end.
>>>>>>>>>>> > > > > > > > > > > >
>>>>>>>>>>> > > > > > > > > > > > Currently control doesn't work 100% as it only
>>>>>>>>>>> > > > > > > > > > > > replaces
>>>>>>>>>>> > > all_optimizations but not lowering passes or early opts, nor IPA
>>>>>>>>>>> > > opts.
>>>>>>>>>>> > > > > > > > > > > >
>>>>>>>>>>> > > > > > > > > > >
>>>>>>>>>>> > > > > > > > > > > Each pass needs GIMPLE in some specific form. So
>>>>>>>>>>> > > > > > > > > > > I am letting
>>>>>>>>>>> > > lowering
>>>>>>>>>>> > > > > > > > > > > and early opt passes to execute. I think we have
>>>>>>>>>>> > > > > > > > > > > to execute
>>>>>>>>>>> > > some
>>>>>>>>>>> > > > > > > > > > > passes (like cfg) anyway to represent GIMPLE into
>>>>>>>>>>> > > > > > > > > > > proper form
>>>>>>>>>>> > > > > > > > > >
>>>>>>>>>>> > > > > > > > > > Yes, that's true.  Note that early opt passes only
>>>>>>>>>>> > > > > > > > > > optimize but
>>>>>>>>>>> > > we need
>>>>>>>>>>> > > > > > > > > > pass_build_ssa_passes at least (for into-SSA).  For
>>>>>>>>>>> > > > > > > > > > proper
>>>>>>>>>>> > > unit-testing
>>>>>>>>>>> > > > > > > > > > of GIMPLE passes we do need to guard off early opts
>>>>>>>>>>> > > > > > > > > > somehow
>>>>>>>>>>> > > > > > > > > > (I guess a simple if (flag_gimple && cfun
>>>>>>>>>>> > > > > > > > > > ->custom_pass_list)
>>>>>>>>>>> > > would do
>>>>>>>>>>> > > > > > > > > > that).
>>>>>>>>>>> > > > > > > > > >
>>>>>>>>>>> > > > > > > > > > Then there is of course the question about IPA
>>>>>>>>>>> > > > > > > > > > passes which I
>>>>>>>>>>> > > think is
>>>>>>>>>>> > > > > > > > > > somewhat harder (one could always disable all IPA
>>>>>>>>>>> > > > > > > > > > passes
>>>>>>>>>>> > > manually
>>>>>>>>>>> > > > > > > > > > via flags of course or finally have a global
>>>>>>>>>>> > > > > > > > > > -fipa/no-ipa like
>>>>>>>>>>> > > most
>>>>>>>>>>> > > > > > > > > > other compilers).
>>>>>>>>>>> > > > > > > > > >
>>>>>>>>>>> > > > > > > > > Can we iterate through all ipa passes and do
>>>>>>>>>>> > > > > > > > > -fdisable-ipa-pass
>>>>>>>>>>> > > or
>>>>>>>>>>> > > > > > > > > -fenable-ipa-pass equivalent for each?
>>>>>>>>>>> > > > > > > >
>>>>>>>>>>> > > > > > > > We could do that, yes.  But let's postpone this issue.
>>>>>>>>>>> > > > > > > >  I think
>>>>>>>>>>> > > that
>>>>>>>>>>> > > > > > > > startwith is going to be most useful and rather than
>>>>>>>>>>> > > > > > > > constructing
>>>>>>>>>>> > > > > > > > a pass list for it "native" support for it in the pass
>>>>>>>>>>> > > > > > > > manager is
>>>>>>>>>>> > > > > > > > likely to produce better results (add a 'startwith'
>>>>>>>>>>> > > > > > > > member
>>>>>>>>>>> > > alongside
>>>>>>>>>>> > > > > > > > the pass list member and if it is set the pass manager
>>>>>>>>>>> > > > > > > > skips all
>>>>>>>>>>> > > > > > > > passes that do not match 'startwith' and once it
>>>>>>>>>>> > > > > > > > reaches it it
>>>>>>>>>>> > > clears
>>>>>>>>>>> > > > > > > > the field).
>>>>>>>>>>> > > > > > > >
>>>>>>>>>>> > > > > > > > In the future I hope we can get away from a static pass
>>>>>>>>>>> > > > > > > > list and
>>>>>>>>>>> > > more
>>>>>>>>>>> > > > > > > > towards rule-driven pass execution (we have all those
>>>>>>>>>>> > > > > > > > PROP_*
>>>>>>>>>>> > > stuff
>>>>>>>>>>> > > > > > > > already but it isn't really used for example).  But
>>>>>>>>>>> > > > > > > > well, that
>>>>>>>>>>> > > would be
>>>>>>>>>>> > > > > > > > a separate GSoC project ;)
>>>>>>>>>>> > > > > > > >
>>>>>>>>>>> > > > > > > > IMHO startwith will provide everything needed for unit
>>>>>>>>>>> > > > > > > > -testing.
>>>>>>>>>>> > > We can
>>>>>>>>>>> > > > > > > > add a flag on whether further passes should be executed
>>>>>>>>>>> > > > > > > > or not
>>>>>>>>>>> > > and
>>>>>>>>>>> > > > > > > > even a pass list like execute ("ccp1", "fre") can be
>>>>>>>>>>> > > > > > > > implemented
>>>>>>>>>>> > > by
>>>>>>>>>>> > > > > > > > startwith ccp1 and then from there executing the rest
>>>>>>>>>>> > > > > > > > of the
>>>>>>>>>>> > > passes in the
>>>>>>>>>>> > > > > > > > list and stopping at the end.
>>>>>>>>>>> > > > > > > >
>>>>>>>>>>> > > > > > > > As said, unit-testing should exercise a single pass if
>>>>>>>>>>> > > > > > > > we can
>>>>>>>>>>> > > control
>>>>>>>>>>> > > > > > > > its input.
>>>>>>>>>>> > > > > > > >
>>>>>>>>>>> > > > > > > In this patch I am skipping execution of passes until
>>>>>>>>>>> > > pass_startwith
>>>>>>>>>>> > > > > > > is found. Unlike previous build, now pass manager
>>>>>>>>>>> > > > > > > executes all
>>>>>>>>>>> > > passes
>>>>>>>>>>> > > > > > > in pipeline starting from pass_startwith instead of just
>>>>>>>>>>> > > > > > > sub
>>>>>>>>>>> > > passes.
>>>>>>>>>>> > > > > >
>>>>>>>>>>> > > > > > That looks good.  I wonder if
>>>>>>>>>>> > > > > >
>>>>>>>>>>> > > > > > +  if (startwith_p && cfun->startwith)
>>>>>>>>>>> > > > > > +    {
>>>>>>>>>>> > > > > > +      if (pass->name == cfun->pass_startwith->name
>>>>>>>>>>> > > > > > +         || pass->name == "*clean_state")
>>>>>>>>>>> > > > > >
>>>>>>>>>>> > > > > > need better be strcmp ()s though.  Also the early
>>>>>>>>>>> > > > > > optimization
>>>>>>>>>>> > > pipeline
>>>>>>>>>>> > > > > > should be executed with startwith support as well.
>>>>>>>>>>> > > > > >
>>>>>>>>>>> > > > >
>>>>>>>>>>> > > > > This patch adds startwith support for early opt passes. But
>>>>>>>>>>> > > > > for
>>>>>>>>>>> > > > > starting from some passes (like asan0, optimized) in
>>>>>>>>>>> > > > > all_passes
>>>>>>>>>>> > > > > pipeline, it falils at verify_curr_properties in
>>>>>>>>>>> > > > > execute_one_pass
>>>>>>>>>>> > > ().
>>>>>>>>>>> > > > > I wonder if we need to update properties after skipping each
>>>>>>>>>>> > > > > pass
>>>>>>>>>>> > > >
>>>>>>>>>>> > > > Yeah, it's not possible to start at arbitrary points with
>>>>>>>>>>> > > > skipping
>>>>>>>>>>> > > passes
>>>>>>>>>>> > > > that provide a required property.  I suspect it's good enough
>>>>>>>>>>> > > > that
>>>>>>>>>>> > > we'll
>>>>>>>>>>> > > > ICE if that happens.
>>>>>>>>>>> > > >
>>>>>>>>>>> > > > I see you are working on the dump-file side a bit now.  What is
>>>>>>>>>>> > > > still
>>>>>>>>>>> > > > missing after you got support for PHIs is parsing of SSA names.
>>>>>>>>>>> > > > Without this unit-testing will be difficult at best.
>>>>>>>>>>> > > >
>>>>>>>>>>> > > > I think what we need to do is simplify the job of the parser
>>>>>>>>>>> > > > and
>>>>>>>>>>> > > > make the syntax we use to print SSA names a bit different.
>>>>>>>>>>> > > > So rather than printing VAR_VERSION we need to choose a
>>>>>>>>>>> > > > letter that is not part of a valid identifier before VERSION,
>>>>>>>>>>> > > > like a dot '.'.  Thus we'd have i.1 instead of i_1 and we'd
>>>>>>>>>>> > > > have
>>>>>>>>>>> > > > .2 instead of _2 for an anonymous SSA name.  The advantage
>>>>>>>>>>> > > > for non-anonymous names is that we can properly re-use the
>>>>>>>>>>> > > > C frontends decl handling for declaring and looking up 'i'.
>>>>>>>>>>> > > > The disadvantage is that for anonymous SSA names this isn't
>>>>>>>>>>> > > > so easy which means we could choose to not support those
>>>>>>>>>>> > > > for the moment and require fake decls for them.  In fact
>>>>>>>>>>> > > > into-SSA will do the correct thing if we just treat them as
>>>>>>>>>>> > > > decls,
>>>>>>>>>>> > > > thus continue to dump them as _VERSION.
>>>>>>>>>>> > > >
>>>>>>>>>>> > >
>>>>>>>>>>> > > I am little confused here about parsing 'i.1' because lexer drops
>>>>>>>>>>> > > DOT
>>>>>>>>>>> > > token for syntax like NAME.NUMBER . Hence instead of 'i.1' parser
>>>>>>>>>>> > > receives 'i1'
>>>>>>>>>>> >
>>>>>>>>>>> > Are you sure? You should get three tokens, one for 'i', one for the
>>>>>>>>>>> > dot and
>>>>>>>>>>> > One for '1'.  You'd lookup the first via the C frontend symbol
>>>>>>>>>>> > table only.
>>>>>>>>>>> >
>>>>>>>>>>>
>>>>>>>>>>> Yes, I was also expecting that. For syntax like 'a.b' (ie name.name)
>>>>>>>>>>> it gives proper 3 tokens but for syntax like 'a.1' it produces only
>>>>>>>>>>> 2.
>>>>>>>>>>>
>>>>>>>>>>> This is what I observed while debugging "int a.1;"
>>>>>>>>>>>
>>>>>>>>>>> (gdb) print *c_parser_peek_nth_token (parser, 1)
>>>>>>>>>>> $3 = {type = CPP_KEYWORD, id_kind = C_ID_NONE, keyword = RID_INT,
>>>>>>>>>>>   pragma_kind = PRAGMA_NONE, location = 242114, value =
>>>>>>>>>>> 0x7ffff65c82d0}
>>>>>>>>>>> (gdb) print *c_parser_peek_nth_token (parser, 2)
>>>>>>>>>>> $4 = {type = CPP_NAME, id_kind = C_ID_ID, keyword = RID_MAX,
>>>>>>>>>>>   pragma_kind = PRAGMA_NONE, location = 242240, value =
>>>>>>>>>>> 0x7ffff66d0b90}
>>>>>>>>>>> (gdb) print *c_parser_peek_nth_token (parser, 3)
>>>>>>>>>>> $5 = {type = CPP_NUMBER, id_kind = C_ID_NONE, keyword = RID_MAX,
>>>>>>>>>>>   pragma_kind = PRAGMA_NONE, location = 242273, value =
>>>>>>>>>>> 0x7ffff66e0030}
>>>>>>>>>>
>>>>>>>>>>What is the number?  I'm wondering if it's somehow been lexed as a
>>>>>>>>>>decimal ".1" i.e. if the "." is somehow being treated as part of the
>>>>>>>>>>CPP_NUMBER.
>>>>>>>>>
>>>>>>>>
>>>>>>>> Yes, the token '.1' is treated as CPP_NUMBER
>>>>>>>>
>>>>>>>>> Ah, possible...
>>>>>>>>>
>>>>>>>>>>FWIW, I find hacking in calls to "inform" very useful for seeing what
>>>>>>>>>>each token is (assuming that caret printing isn't disabled).
>>>>>>>>>>
>>>>>>>>>>  (gdb) call inform ($3->location, "")
>>>>>>>>>>  (gdb) call inform ($4->location, "")
>>>>>>>>>>  (gdb) call inform ($5
>>>>>>>>>>->location, "")
>>>>>>>>>>
>>>>>>>>>>etc
>>>>>>>>>>
>>>>>>>>>>BTW, does it have to be '.' as the SSA_NAME separator?  Could it be a
>>>>>>>>>>different character e.g. '@' or something else that's non-legal in C?
>>>>>>>>>
>>>>>>>>> It doesn't have to be '.', but sth visually not too disturbing would be nice.  If we don't go with '.' We can as well try to parse the SSA version from i_1, leaving the ambiguity with it being a valid C identifier.
>>>>>>>>>
>>>>>>>>
>>>>>>>> As special characters are not valid in C, I am using 'a..1' as syntax
>>>>>>>> for ssa name. For parsing I am using
>>>>>>>> +      lhs.value = make_ssa_name_fn (cfun,
>>>>>>>> +                                   lookup_name (c_parser_peek_token
>>>>>>>> (parser)->value),
>>>>>>>> +                                   NULL);
>>>>>>>> Now for passing ssa name into __PHI, how can we lookup for particular ssa name.
>>>>>>>> Or is there other better method to do it?
>>>>>>>
>>>>>>> Note that with this you need to preserve SSA versions as used in the source
>>>>>>> (the 1 in a..1).  If you can do that (see below) the way to lookup an SSA name
>>>>>>> is simply calling 'ssa_name (version)' with version being an integer with the
>>>>>>> version number.
>>>>>>>
>>>>>>> make_ssa_name will simply allocate the next available SSA version so
>>>>>>> you'll need to add an interface that allows you allocation of a specific
>>>>>>> SSA version.  Like with sth similar to
>>>>>>>
>>>>>>> Index: gcc/tree-ssanames.c
>>>>>>> ===================================================================
>>>>>>> --- gcc/tree-ssanames.c (revision 238512)
>>>>>>> +++ gcc/tree-ssanames.c (working copy)
>>>>>>> @@ -255,7 +255,7 @@
>>>>>>>     used without a preceding definition).  */
>>>>>>>
>>>>>>>  tree
>>>>>>> -make_ssa_name_fn (struct function *fn, tree var, gimple *stmt)
>>>>>>> +make_ssa_name_fn (struct function *fn, tree var, gimple *stmt, int version)
>>>>>>>  {
>>>>>>>    tree t;
>>>>>>>    use_operand_p imm;
>>>>>>> @@ -265,8 +265,17 @@
>>>>>>>               || TREE_CODE (var) == RESULT_DECL
>>>>>>>               || (TYPE_P (var) && is_gimple_reg_type (var)));
>>>>>>>
>>>>>>> +  if (version != 0)
>>>>>>> +    {
>>>>>>> +      t = make_node (SSA_NAME);
>>>>>>> +      SSA_NAME_VERSION (t) = version;
>>>>>>> +      vec_safe_grow_cleared (SSANAMES (fn), version + 1);
>>>>>>> +      gcc_assert ((*SSANAMES (fn))[version] == NULL);
>>>>>>> +      (*SSANAMES (fn))[version] = t;
>>>>>>> +      ssa_name_nodes_created++;
>>>>>>> +    }
>>>>>>>    /* If our free list has an element, then use it.  */
>>>>>>> -  if (!vec_safe_is_empty (FREE_SSANAMES (fn)))
>>>>>>> +  else if (!vec_safe_is_empty (FREE_SSANAMES (fn)))
>>>>>>>      {
>>>>>>>        t = FREE_SSANAMES (fn)->pop ();
>>>>>>>        ssa_name_nodes_reused++;
>>>>>>> Index: gcc/tree-ssanames.h
>>>>>>> ===================================================================
>>>>>>> --- gcc/tree-ssanames.h (revision 237253)
>>>>>>> +++ gcc/tree-ssanames.h (working copy)
>>>>>>> @@ -79,7 +79,7 @@
>>>>>>>  extern void init_ssanames (struct function *, int);
>>>>>>>  extern void fini_ssanames (struct function *);
>>>>>>>  extern void ssanames_print_statistics (void);
>>>>>>> -extern tree make_ssa_name_fn (struct function *, tree, gimple *);
>>>>>>> +extern tree make_ssa_name_fn (struct function *, tree, gimple *, int);
>>>>>>>  extern void release_ssa_name_fn (struct function *, tree);
>>>>>>>  extern bool get_ptr_info_alignment (struct ptr_info_def *, unsigned int *,
>>>>>>>                                     unsigned int *);
>>>>>>>
>>>>>>> where you can then do sth like
>>>>>>>
>>>>>>>   ssaname = ssa_name (version);
>>>>>>>   if (!ssaname)
>>>>>>>     ssaname = make_ssa_name_fn (cfun, lookup_name (...), NULL, version);
>>>>>>>
>>>>>>> to either lookup an existing or allocate a new SSA name of the desired version.
>>>>>>>
>>>>>>> Just for some bike-shedding, I don't like using '..' too much ;)
>>>>>> Would it be a good idea to modify libcpp's lexer to recognize
>>>>>> identifier.number as a single token if -fgimple is enabled ?
>>>>>
>>>>> I don't think so.  As said, we can retain the i_2 syntax as well where you then
>>>>> get a single token and to decide whether it is a SSA name do a lookup for
>>>>> 'i' first and if that succeeds, interpret _2 as a version suffix,
>>>>> otherwise use it
>>>>> as full variable name.  Re-constructing the 1 from .1 or 17 from .17 CPP_NUMBER
>>>>> is possible as well of course.
>>>>>
>>>>
>>>> Sorry for the late response. I was little busy due to some family problem.
>>>>
>>>> In this patch, I am parsing ssa names as described above. But the
>>>> problem is non ssa variable also gets renamed
>>> I assume you're referring to renaming of a to a_5 here ?
>>> I suppose that's expected since 'a' is gimple reg, ssa pass will
>>> create ssa name for it.
>>> Maybe emit "parse error" if local var is not in "ssa syntax", that is,
>>> it doesn't
>>> have _version suffixed ? But emitting an error for this case looks
>>> artificial to me.
>>
>> Yes, I think the result is as expected.  If we want to constrain the
>> input to the
>> GIMPLE parser then we somehow have to tell it what kind of GIMPLE we are
>> presenting it (SSA or non-SSA gimple), but for the moment what you have
>> and show with the testcase looks good to me.
>>
>> The parsing doesn't handle
>>
>> void __GIMPLE () foo ()
>> {
>>   int a_3;
>>   a_3_1 = 0;
>> }
>>
>> correctly as it looks for the first '_' rather than the last.  I'd have used
>> sth like
>>
>>   char *p = strrchr (ssa_token, '_');
>>   if (p)
>>     {
>>       var_name = new char [p - ssa_token + 1];
>>       memcpy (var_name, ssa_token, p - ssa_token);
>>       var_name[p - ssa_token] = '\0';
>>       ...
>>       version = atoi (p);
>>
>> in the patch you have two copies of the SSA name parsing code - you want to
>> split that out into a function.
>>
>> There is one other feature missing for SSA name parsing (forget to mention that)
>> which is parsing of default def SSA names.  Those are for example used for
>> parameters and currently dumped like
>>
>> foo (int i)
>> {
>>   int D.1759;
>>   int _2;
>>
>>   <bb 2>:
>>   _2 = i_1(D) + 1;
>>   return _2;
>> }
>>
>> for int foo (int i) { return i + 1; }.  Here 'i_1(D)' is the
>> default-def of 'i' which
>> in case of a parameter is the value at function start and in case of a
>> non-parameter
>> is simply "undefined".  '(D)' is again somewhat awkward to parse but I guess we
>> can cope with that ;)  A default-def needs to be registered like
>>
>>   arg = make_ssa_name_fn (cfun, lookup_name (id), ...);
>>   set_ssa_default_def (cfun, lookup_name (id), arg);
>>
>> "undefined" SSA names appear often in PHIs (and of course for parameters).
>>
>
> This updated patch tries to parse default def ssa names
Um does this emit error for cases like a_1() and a_(D) ?
From the code it appears to me that parsing 'D' is made optional, so
id_version() would be accepted.
Perhaps have an else for the if (!strcmp("D", ...) that emits parse error ?

Btw for the following case:
int a;
int a_1;
int x = a_1 + 1;
What does a_1 refer to in "int x = a_1 + 1" ? the ssa-version of 'a'
or the variable 'a_1' ?
I think from the code it would refer to ssa-version of a ? However the
reference looks
ambiguous to me (since we also allow variables in non-ssa form).

Thanks,
Prathamesh
>
> Thanks,
> Prasad
>
>> Thanks,
>> Richard.
>>
>>> Thanks,
>>> Prathamesh
>>>>
>>>> for testcase :
>>>>
>>>> void __GIMPLE () foo()
>>>> {
>>>>   int a;
>>>> bb_2:
>>>>   if (a > 4)
>>>>     goto bb_3;
>>>>   else
>>>>     goto bb_4;
>>>> bb_3:
>>>>   a_1 = 55;
>>>>   goto bb_5;
>>>>
>>>> bb_4:
>>>>   a_2 = 99;
>>>>
>>>> bb_5:
>>>>   a_3 = __PHI (bb_3: a_1, bb_4: a_2);
>>>>   a_4 = a_3 + 3;
>>>>   return;
>>>> }
>>>>
>>>> I am getting ssa dump as:
>>>>
>>>> /* Function foo (foo, funcdef_no=0, decl_uid=1744, cgraph_uid=0,
>>>> symbol_order=0)*/
>>>>
>>>> void
>>>> foo ()
>>>> {
>>>> bb_2:
>>>>   if (a_5 > 4)
>>>>     goto bb_3;
>>>>   else
>>>>     goto bb_4;
>>>>
>>>> bb_3:
>>>>   a_1 = 55;
>>>>   goto bb_5;
>>>>
>>>> bb_4:
>>>>   a_2 = 99;
>>>>
>>>>   a_3 = __PHI (bb_3: a_1, bb_4: a_2)
>>>> bb_5:
>>>>   a_4 = a_3 + 3;
>>>>   return;
>>>>
>>>> }
>>>>
>>>>> Richard.
>>>>>
>>>>>> Thanks,
>>>>>> Prathamesh
>>>>>>>
>>>>>>> Richard.
>>>>>>>
>>>>>>>>
>>>>>>>>> Richard.
>>>>>>>>>
>>>>>>>>>>Dave
>>>>>>>>>
>>>>>>>>>

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [gimplefe] hacking pass manager
  2016-07-29  1:26                                               ` Prathamesh Kulkarni
@ 2016-07-29  7:03                                                 ` Prasad Ghangal
  2016-07-29  7:25                                                   ` Richard Biener
  0 siblings, 1 reply; 29+ messages in thread
From: Prasad Ghangal @ 2016-07-29  7:03 UTC (permalink / raw)
  To: Prathamesh Kulkarni; +Cc: Richard Biener, David Malcolm, gcc Mailing List

Thanks,
Prasad


On 29 July 2016 at 06:56, Prathamesh Kulkarni
<prathamesh.kulkarni@linaro.org> wrote:
> On 29 July 2016 at 00:01, Prasad Ghangal <prasad.ghangal@gmail.com> wrote:
>> On 27 July 2016 at 14:22, Richard Biener <richard.guenther@gmail.com> wrote:
>>> On Tue, Jul 26, 2016 at 11:38 PM, Prathamesh Kulkarni
>>> <prathamesh.kulkarni@linaro.org> wrote:
>>>> On 27 July 2016 at 00:20, Prasad Ghangal <prasad.ghangal@gmail.com> wrote:
>>>>> On 20 July 2016 at 18:28, Richard Biener <richard.guenther@gmail.com> wrote:
>>>>>> On Wed, Jul 20, 2016 at 1:46 PM, Prathamesh Kulkarni
>>>>>> <prathamesh.kulkarni@linaro.org> wrote:
>>>>>>> On 20 July 2016 at 11:34, Richard Biener <richard.guenther@gmail.com> wrote:
>>>>>>>> On Tue, Jul 19, 2016 at 10:09 PM, Prasad Ghangal
>>>>>>>> <prasad.ghangal@gmail.com> wrote:
>>>>>>>>> On 19 July 2016 at 11:04, Richard Biener <richard.guenther@gmail.com> wrote:
>>>>>>>>>> On July 18, 2016 11:05:58 PM GMT+02:00, David Malcolm <dmalcolm@redhat.com> wrote:
>>>>>>>>>>>On Tue, 2016-07-19 at 00:52 +0530, Prasad Ghangal wrote:
>>>>>>>>>>>> On 19 July 2016 at 00:25, Richard Biener <richard.guenther@gmail.com>
>>>>>>>>>>>> wrote:
>>>>>>>>>>>> > On July 18, 2016 8:28:15 PM GMT+02:00, Prasad Ghangal <
>>>>>>>>>>>> > prasad.ghangal@gmail.com> wrote:
>>>>>>>>>>>> > > On 15 July 2016 at 16:13, Richard Biener <
>>>>>>>>>>>> > > richard.guenther@gmail.com>
>>>>>>>>>>>> > > wrote:
>>>>>>>>>>>> > > > On Sun, Jul 10, 2016 at 6:13 PM, Prasad Ghangal
>>>>>>>>>>>> > > > <prasad.ghangal@gmail.com> wrote:
>>>>>>>>>>>> > > > > On 8 July 2016 at 13:13, Richard Biener <
>>>>>>>>>>>> > > > > richard.guenther@gmail.com>
>>>>>>>>>>>> > > wrote:
>>>>>>>>>>>> > > > > > On Thu, Jul 7, 2016 at 9:45 PM, Prasad Ghangal
>>>>>>>>>>>> > > <prasad.ghangal@gmail.com> wrote:
>>>>>>>>>>>> > > > > > > On 6 July 2016 at 14:24, Richard Biener
>>>>>>>>>>>> > > <richard.guenther@gmail.com> wrote:
>>>>>>>>>>>> > > > > > > > On Wed, Jul 6, 2016 at 9:51 AM, Prasad Ghangal
>>>>>>>>>>>> > > <prasad.ghangal@gmail.com> wrote:
>>>>>>>>>>>> > > > > > > > > On 30 June 2016 at 17:10, Richard Biener
>>>>>>>>>>>> > > <richard.guenther@gmail.com> wrote:
>>>>>>>>>>>> > > > > > > > > > On Wed, Jun 29, 2016 at 9:13 PM, Prasad Ghangal
>>>>>>>>>>>> > > > > > > > > > <prasad.ghangal@gmail.com> wrote:
>>>>>>>>>>>> > > > > > > > > > > On 29 June 2016 at 22:15, Richard Biener
>>>>>>>>>>>> > > <richard.guenther@gmail.com> wrote:
>>>>>>>>>>>> > > > > > > > > > > > On June 29, 2016 6:20:29 PM GMT+02:00,
>>>>>>>>>>>> > > > > > > > > > > > Prathamesh Kulkarni
>>>>>>>>>>>> > > <prathamesh.kulkarni@linaro.org> wrote:
>>>>>>>>>>>> > > > > > > > > > > > > On 18 June 2016 at 12:02, Prasad Ghangal
>>>>>>>>>>>> > > <prasad.ghangal@gmail.com>
>>>>>>>>>>>> > > > > > > > > > > > > wrote:
>>>>>>>>>>>> > > > > > > > > > > > > > Hi,
>>>>>>>>>>>> > > > > > > > > > > > > >
>>>>>>>>>>>> > > > > > > > > > > > > > I tried hacking pass manager to execute
>>>>>>>>>>>> > > > > > > > > > > > > > only given passes.
>>>>>>>>>>>> > > For this I
>>>>>>>>>>>> > > > > > > > > > > > > > am adding new member as opt_pass
>>>>>>>>>>>> > > > > > > > > > > > > > *custom_pass_list to the
>>>>>>>>>>>> > > function
>>>>>>>>>>>> > > > > > > > > > > > > > structure to store passes need to execute
>>>>>>>>>>>> > > > > > > > > > > > > > and providing the
>>>>>>>>>>>> > > > > > > > > > > > > > custom_pass_list to execute_pass_list()
>>>>>>>>>>>> > > > > > > > > > > > > > function instead of
>>>>>>>>>>>> > > all
>>>>>>>>>>>> > > > > > > > > > > > > passes
>>>>>>>>>>>> > > > > > > > > > > > > >
>>>>>>>>>>>> > > > > > > > > > > > > > for test case like-
>>>>>>>>>>>> > > > > > > > > > > > > >
>>>>>>>>>>>> > > > > > > > > > > > > > int a;
>>>>>>>>>>>> > > > > > > > > > > > > > void __GIMPLE (execute ("tree-ccp1", "tree
>>>>>>>>>>>> > > > > > > > > > > > > > -fre1")) foo()
>>>>>>>>>>>> > > > > > > > > > > > > > {
>>>>>>>>>>>> > > > > > > > > > > > > > bb_1:
>>>>>>>>>>>> > > > > > > > > > > > > >   a = 1 + a;
>>>>>>>>>>>> > > > > > > > > > > > > > }
>>>>>>>>>>>> > > > > > > > > > > > > >
>>>>>>>>>>>> > > > > > > > > > > > > > it will execute only given passes i.e. ccp1
>>>>>>>>>>>> > > > > > > > > > > > > > and fre1 pass
>>>>>>>>>>>> > > on the
>>>>>>>>>>>> > > > > > > > > > > > > function
>>>>>>>>>>>> > > > > > > > > > > > > >
>>>>>>>>>>>> > > > > > > > > > > > > > and for test case like -
>>>>>>>>>>>> > > > > > > > > > > > > >
>>>>>>>>>>>> > > > > > > > > > > > > > int a;
>>>>>>>>>>>> > > > > > > > > > > > > > void __GIMPLE (startwith ("tree-ccp1"))
>>>>>>>>>>>> > > > > > > > > > > > > > foo()
>>>>>>>>>>>> > > > > > > > > > > > > > {
>>>>>>>>>>>> > > > > > > > > > > > > > bb_1:
>>>>>>>>>>>> > > > > > > > > > > > > >   a = 1 + a;
>>>>>>>>>>>> > > > > > > > > > > > > > }
>>>>>>>>>>>> > > > > > > > > > > > > >
>>>>>>>>>>>> > > > > > > > > > > > > > it will act as a entry point to the
>>>>>>>>>>>> > > > > > > > > > > > > > pipeline and will
>>>>>>>>>>>> > > execute passes
>>>>>>>>>>>> > > > > > > > > > > > > > starting from given pass.
>>>>>>>>>>>> > > > > > > > > > > > > Bike-shedding:
>>>>>>>>>>>> > > > > > > > > > > > > Would it make sense to have syntax for
>>>>>>>>>>>> > > > > > > > > > > > > defining pass ranges
>>>>>>>>>>>> > > to execute
>>>>>>>>>>>> > > > > > > > > > > > > ?
>>>>>>>>>>>> > > > > > > > > > > > > for instance:
>>>>>>>>>>>> > > > > > > > > > > > > void __GIMPLE(execute (pass_start :
>>>>>>>>>>>> > > > > > > > > > > > > pass_end))
>>>>>>>>>>>> > > > > > > > > > > > > which would execute all the passes within
>>>>>>>>>>>> > > > > > > > > > > > > range [pass_start,
>>>>>>>>>>>> > > pass_end],
>>>>>>>>>>>> > > > > > > > > > > > > which would be convenient if the range is
>>>>>>>>>>>> > > > > > > > > > > > > large.
>>>>>>>>>>>> > > > > > > > > > > >
>>>>>>>>>>>> > > > > > > > > > > > But it would rely on a particular pass
>>>>>>>>>>>> > > > > > > > > > > > pipeline, f.e.
>>>>>>>>>>>> > > pass-start appearing before pass-end.
>>>>>>>>>>>> > > > > > > > > > > >
>>>>>>>>>>>> > > > > > > > > > > > Currently control doesn't work 100% as it only
>>>>>>>>>>>> > > > > > > > > > > > replaces
>>>>>>>>>>>> > > all_optimizations but not lowering passes or early opts, nor IPA
>>>>>>>>>>>> > > opts.
>>>>>>>>>>>> > > > > > > > > > > >
>>>>>>>>>>>> > > > > > > > > > >
>>>>>>>>>>>> > > > > > > > > > > Each pass needs GIMPLE in some specific form. So
>>>>>>>>>>>> > > > > > > > > > > I am letting
>>>>>>>>>>>> > > lowering
>>>>>>>>>>>> > > > > > > > > > > and early opt passes to execute. I think we have
>>>>>>>>>>>> > > > > > > > > > > to execute
>>>>>>>>>>>> > > some
>>>>>>>>>>>> > > > > > > > > > > passes (like cfg) anyway to represent GIMPLE into
>>>>>>>>>>>> > > > > > > > > > > proper form
>>>>>>>>>>>> > > > > > > > > >
>>>>>>>>>>>> > > > > > > > > > Yes, that's true.  Note that early opt passes only
>>>>>>>>>>>> > > > > > > > > > optimize but
>>>>>>>>>>>> > > we need
>>>>>>>>>>>> > > > > > > > > > pass_build_ssa_passes at least (for into-SSA).  For
>>>>>>>>>>>> > > > > > > > > > proper
>>>>>>>>>>>> > > unit-testing
>>>>>>>>>>>> > > > > > > > > > of GIMPLE passes we do need to guard off early opts
>>>>>>>>>>>> > > > > > > > > > somehow
>>>>>>>>>>>> > > > > > > > > > (I guess a simple if (flag_gimple && cfun
>>>>>>>>>>>> > > > > > > > > > ->custom_pass_list)
>>>>>>>>>>>> > > would do
>>>>>>>>>>>> > > > > > > > > > that).
>>>>>>>>>>>> > > > > > > > > >
>>>>>>>>>>>> > > > > > > > > > Then there is of course the question about IPA
>>>>>>>>>>>> > > > > > > > > > passes which I
>>>>>>>>>>>> > > think is
>>>>>>>>>>>> > > > > > > > > > somewhat harder (one could always disable all IPA
>>>>>>>>>>>> > > > > > > > > > passes
>>>>>>>>>>>> > > manually
>>>>>>>>>>>> > > > > > > > > > via flags of course or finally have a global
>>>>>>>>>>>> > > > > > > > > > -fipa/no-ipa like
>>>>>>>>>>>> > > most
>>>>>>>>>>>> > > > > > > > > > other compilers).
>>>>>>>>>>>> > > > > > > > > >
>>>>>>>>>>>> > > > > > > > > Can we iterate through all ipa passes and do
>>>>>>>>>>>> > > > > > > > > -fdisable-ipa-pass
>>>>>>>>>>>> > > or
>>>>>>>>>>>> > > > > > > > > -fenable-ipa-pass equivalent for each?
>>>>>>>>>>>> > > > > > > >
>>>>>>>>>>>> > > > > > > > We could do that, yes.  But let's postpone this issue.
>>>>>>>>>>>> > > > > > > >  I think
>>>>>>>>>>>> > > that
>>>>>>>>>>>> > > > > > > > startwith is going to be most useful and rather than
>>>>>>>>>>>> > > > > > > > constructing
>>>>>>>>>>>> > > > > > > > a pass list for it "native" support for it in the pass
>>>>>>>>>>>> > > > > > > > manager is
>>>>>>>>>>>> > > > > > > > likely to produce better results (add a 'startwith'
>>>>>>>>>>>> > > > > > > > member
>>>>>>>>>>>> > > alongside
>>>>>>>>>>>> > > > > > > > the pass list member and if it is set the pass manager
>>>>>>>>>>>> > > > > > > > skips all
>>>>>>>>>>>> > > > > > > > passes that do not match 'startwith' and once it
>>>>>>>>>>>> > > > > > > > reaches it it
>>>>>>>>>>>> > > clears
>>>>>>>>>>>> > > > > > > > the field).
>>>>>>>>>>>> > > > > > > >
>>>>>>>>>>>> > > > > > > > In the future I hope we can get away from a static pass
>>>>>>>>>>>> > > > > > > > list and
>>>>>>>>>>>> > > more
>>>>>>>>>>>> > > > > > > > towards rule-driven pass execution (we have all those
>>>>>>>>>>>> > > > > > > > PROP_*
>>>>>>>>>>>> > > stuff
>>>>>>>>>>>> > > > > > > > already but it isn't really used for example).  But
>>>>>>>>>>>> > > > > > > > well, that
>>>>>>>>>>>> > > would be
>>>>>>>>>>>> > > > > > > > a separate GSoC project ;)
>>>>>>>>>>>> > > > > > > >
>>>>>>>>>>>> > > > > > > > IMHO startwith will provide everything needed for unit
>>>>>>>>>>>> > > > > > > > -testing.
>>>>>>>>>>>> > > We can
>>>>>>>>>>>> > > > > > > > add a flag on whether further passes should be executed
>>>>>>>>>>>> > > > > > > > or not
>>>>>>>>>>>> > > and
>>>>>>>>>>>> > > > > > > > even a pass list like execute ("ccp1", "fre") can be
>>>>>>>>>>>> > > > > > > > implemented
>>>>>>>>>>>> > > by
>>>>>>>>>>>> > > > > > > > startwith ccp1 and then from there executing the rest
>>>>>>>>>>>> > > > > > > > of the
>>>>>>>>>>>> > > passes in the
>>>>>>>>>>>> > > > > > > > list and stopping at the end.
>>>>>>>>>>>> > > > > > > >
>>>>>>>>>>>> > > > > > > > As said, unit-testing should exercise a single pass if
>>>>>>>>>>>> > > > > > > > we can
>>>>>>>>>>>> > > control
>>>>>>>>>>>> > > > > > > > its input.
>>>>>>>>>>>> > > > > > > >
>>>>>>>>>>>> > > > > > > In this patch I am skipping execution of passes until
>>>>>>>>>>>> > > pass_startwith
>>>>>>>>>>>> > > > > > > is found. Unlike previous build, now pass manager
>>>>>>>>>>>> > > > > > > executes all
>>>>>>>>>>>> > > passes
>>>>>>>>>>>> > > > > > > in pipeline starting from pass_startwith instead of just
>>>>>>>>>>>> > > > > > > sub
>>>>>>>>>>>> > > passes.
>>>>>>>>>>>> > > > > >
>>>>>>>>>>>> > > > > > That looks good.  I wonder if
>>>>>>>>>>>> > > > > >
>>>>>>>>>>>> > > > > > +  if (startwith_p && cfun->startwith)
>>>>>>>>>>>> > > > > > +    {
>>>>>>>>>>>> > > > > > +      if (pass->name == cfun->pass_startwith->name
>>>>>>>>>>>> > > > > > +         || pass->name == "*clean_state")
>>>>>>>>>>>> > > > > >
>>>>>>>>>>>> > > > > > need better be strcmp ()s though.  Also the early
>>>>>>>>>>>> > > > > > optimization
>>>>>>>>>>>> > > pipeline
>>>>>>>>>>>> > > > > > should be executed with startwith support as well.
>>>>>>>>>>>> > > > > >
>>>>>>>>>>>> > > > >
>>>>>>>>>>>> > > > > This patch adds startwith support for early opt passes. But
>>>>>>>>>>>> > > > > for
>>>>>>>>>>>> > > > > starting from some passes (like asan0, optimized) in
>>>>>>>>>>>> > > > > all_passes
>>>>>>>>>>>> > > > > pipeline, it falils at verify_curr_properties in
>>>>>>>>>>>> > > > > execute_one_pass
>>>>>>>>>>>> > > ().
>>>>>>>>>>>> > > > > I wonder if we need to update properties after skipping each
>>>>>>>>>>>> > > > > pass
>>>>>>>>>>>> > > >
>>>>>>>>>>>> > > > Yeah, it's not possible to start at arbitrary points with
>>>>>>>>>>>> > > > skipping
>>>>>>>>>>>> > > passes
>>>>>>>>>>>> > > > that provide a required property.  I suspect it's good enough
>>>>>>>>>>>> > > > that
>>>>>>>>>>>> > > we'll
>>>>>>>>>>>> > > > ICE if that happens.
>>>>>>>>>>>> > > >
>>>>>>>>>>>> > > > I see you are working on the dump-file side a bit now.  What is
>>>>>>>>>>>> > > > still
>>>>>>>>>>>> > > > missing after you got support for PHIs is parsing of SSA names.
>>>>>>>>>>>> > > > Without this unit-testing will be difficult at best.
>>>>>>>>>>>> > > >
>>>>>>>>>>>> > > > I think what we need to do is simplify the job of the parser
>>>>>>>>>>>> > > > and
>>>>>>>>>>>> > > > make the syntax we use to print SSA names a bit different.
>>>>>>>>>>>> > > > So rather than printing VAR_VERSION we need to choose a
>>>>>>>>>>>> > > > letter that is not part of a valid identifier before VERSION,
>>>>>>>>>>>> > > > like a dot '.'.  Thus we'd have i.1 instead of i_1 and we'd
>>>>>>>>>>>> > > > have
>>>>>>>>>>>> > > > .2 instead of _2 for an anonymous SSA name.  The advantage
>>>>>>>>>>>> > > > for non-anonymous names is that we can properly re-use the
>>>>>>>>>>>> > > > C frontends decl handling for declaring and looking up 'i'.
>>>>>>>>>>>> > > > The disadvantage is that for anonymous SSA names this isn't
>>>>>>>>>>>> > > > so easy which means we could choose to not support those
>>>>>>>>>>>> > > > for the moment and require fake decls for them.  In fact
>>>>>>>>>>>> > > > into-SSA will do the correct thing if we just treat them as
>>>>>>>>>>>> > > > decls,
>>>>>>>>>>>> > > > thus continue to dump them as _VERSION.
>>>>>>>>>>>> > > >
>>>>>>>>>>>> > >
>>>>>>>>>>>> > > I am little confused here about parsing 'i.1' because lexer drops
>>>>>>>>>>>> > > DOT
>>>>>>>>>>>> > > token for syntax like NAME.NUMBER . Hence instead of 'i.1' parser
>>>>>>>>>>>> > > receives 'i1'
>>>>>>>>>>>> >
>>>>>>>>>>>> > Are you sure? You should get three tokens, one for 'i', one for the
>>>>>>>>>>>> > dot and
>>>>>>>>>>>> > One for '1'.  You'd lookup the first via the C frontend symbol
>>>>>>>>>>>> > table only.
>>>>>>>>>>>> >
>>>>>>>>>>>>
>>>>>>>>>>>> Yes, I was also expecting that. For syntax like 'a.b' (ie name.name)
>>>>>>>>>>>> it gives proper 3 tokens but for syntax like 'a.1' it produces only
>>>>>>>>>>>> 2.
>>>>>>>>>>>>
>>>>>>>>>>>> This is what I observed while debugging "int a.1;"
>>>>>>>>>>>>
>>>>>>>>>>>> (gdb) print *c_parser_peek_nth_token (parser, 1)
>>>>>>>>>>>> $3 = {type = CPP_KEYWORD, id_kind = C_ID_NONE, keyword = RID_INT,
>>>>>>>>>>>>   pragma_kind = PRAGMA_NONE, location = 242114, value =
>>>>>>>>>>>> 0x7ffff65c82d0}
>>>>>>>>>>>> (gdb) print *c_parser_peek_nth_token (parser, 2)
>>>>>>>>>>>> $4 = {type = CPP_NAME, id_kind = C_ID_ID, keyword = RID_MAX,
>>>>>>>>>>>>   pragma_kind = PRAGMA_NONE, location = 242240, value =
>>>>>>>>>>>> 0x7ffff66d0b90}
>>>>>>>>>>>> (gdb) print *c_parser_peek_nth_token (parser, 3)
>>>>>>>>>>>> $5 = {type = CPP_NUMBER, id_kind = C_ID_NONE, keyword = RID_MAX,
>>>>>>>>>>>>   pragma_kind = PRAGMA_NONE, location = 242273, value =
>>>>>>>>>>>> 0x7ffff66e0030}
>>>>>>>>>>>
>>>>>>>>>>>What is the number?  I'm wondering if it's somehow been lexed as a
>>>>>>>>>>>decimal ".1" i.e. if the "." is somehow being treated as part of the
>>>>>>>>>>>CPP_NUMBER.
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Yes, the token '.1' is treated as CPP_NUMBER
>>>>>>>>>
>>>>>>>>>> Ah, possible...
>>>>>>>>>>
>>>>>>>>>>>FWIW, I find hacking in calls to "inform" very useful for seeing what
>>>>>>>>>>>each token is (assuming that caret printing isn't disabled).
>>>>>>>>>>>
>>>>>>>>>>>  (gdb) call inform ($3->location, "")
>>>>>>>>>>>  (gdb) call inform ($4->location, "")
>>>>>>>>>>>  (gdb) call inform ($5
>>>>>>>>>>>->location, "")
>>>>>>>>>>>
>>>>>>>>>>>etc
>>>>>>>>>>>
>>>>>>>>>>>BTW, does it have to be '.' as the SSA_NAME separator?  Could it be a
>>>>>>>>>>>different character e.g. '@' or something else that's non-legal in C?
>>>>>>>>>>
>>>>>>>>>> It doesn't have to be '.', but sth visually not too disturbing would be nice.  If we don't go with '.' We can as well try to parse the SSA version from i_1, leaving the ambiguity with it being a valid C identifier.
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>> As special characters are not valid in C, I am using 'a..1' as syntax
>>>>>>>>> for ssa name. For parsing I am using
>>>>>>>>> +      lhs.value = make_ssa_name_fn (cfun,
>>>>>>>>> +                                   lookup_name (c_parser_peek_token
>>>>>>>>> (parser)->value),
>>>>>>>>> +                                   NULL);
>>>>>>>>> Now for passing ssa name into __PHI, how can we lookup for particular ssa name.
>>>>>>>>> Or is there other better method to do it?
>>>>>>>>
>>>>>>>> Note that with this you need to preserve SSA versions as used in the source
>>>>>>>> (the 1 in a..1).  If you can do that (see below) the way to lookup an SSA name
>>>>>>>> is simply calling 'ssa_name (version)' with version being an integer with the
>>>>>>>> version number.
>>>>>>>>
>>>>>>>> make_ssa_name will simply allocate the next available SSA version so
>>>>>>>> you'll need to add an interface that allows you allocation of a specific
>>>>>>>> SSA version.  Like with sth similar to
>>>>>>>>
>>>>>>>> Index: gcc/tree-ssanames.c
>>>>>>>> ===================================================================
>>>>>>>> --- gcc/tree-ssanames.c (revision 238512)
>>>>>>>> +++ gcc/tree-ssanames.c (working copy)
>>>>>>>> @@ -255,7 +255,7 @@
>>>>>>>>     used without a preceding definition).  */
>>>>>>>>
>>>>>>>>  tree
>>>>>>>> -make_ssa_name_fn (struct function *fn, tree var, gimple *stmt)
>>>>>>>> +make_ssa_name_fn (struct function *fn, tree var, gimple *stmt, int version)
>>>>>>>>  {
>>>>>>>>    tree t;
>>>>>>>>    use_operand_p imm;
>>>>>>>> @@ -265,8 +265,17 @@
>>>>>>>>               || TREE_CODE (var) == RESULT_DECL
>>>>>>>>               || (TYPE_P (var) && is_gimple_reg_type (var)));
>>>>>>>>
>>>>>>>> +  if (version != 0)
>>>>>>>> +    {
>>>>>>>> +      t = make_node (SSA_NAME);
>>>>>>>> +      SSA_NAME_VERSION (t) = version;
>>>>>>>> +      vec_safe_grow_cleared (SSANAMES (fn), version + 1);
>>>>>>>> +      gcc_assert ((*SSANAMES (fn))[version] == NULL);
>>>>>>>> +      (*SSANAMES (fn))[version] = t;
>>>>>>>> +      ssa_name_nodes_created++;
>>>>>>>> +    }
>>>>>>>>    /* If our free list has an element, then use it.  */
>>>>>>>> -  if (!vec_safe_is_empty (FREE_SSANAMES (fn)))
>>>>>>>> +  else if (!vec_safe_is_empty (FREE_SSANAMES (fn)))
>>>>>>>>      {
>>>>>>>>        t = FREE_SSANAMES (fn)->pop ();
>>>>>>>>        ssa_name_nodes_reused++;
>>>>>>>> Index: gcc/tree-ssanames.h
>>>>>>>> ===================================================================
>>>>>>>> --- gcc/tree-ssanames.h (revision 237253)
>>>>>>>> +++ gcc/tree-ssanames.h (working copy)
>>>>>>>> @@ -79,7 +79,7 @@
>>>>>>>>  extern void init_ssanames (struct function *, int);
>>>>>>>>  extern void fini_ssanames (struct function *);
>>>>>>>>  extern void ssanames_print_statistics (void);
>>>>>>>> -extern tree make_ssa_name_fn (struct function *, tree, gimple *);
>>>>>>>> +extern tree make_ssa_name_fn (struct function *, tree, gimple *, int);
>>>>>>>>  extern void release_ssa_name_fn (struct function *, tree);
>>>>>>>>  extern bool get_ptr_info_alignment (struct ptr_info_def *, unsigned int *,
>>>>>>>>                                     unsigned int *);
>>>>>>>>
>>>>>>>> where you can then do sth like
>>>>>>>>
>>>>>>>>   ssaname = ssa_name (version);
>>>>>>>>   if (!ssaname)
>>>>>>>>     ssaname = make_ssa_name_fn (cfun, lookup_name (...), NULL, version);
>>>>>>>>
>>>>>>>> to either lookup an existing or allocate a new SSA name of the desired version.
>>>>>>>>
>>>>>>>> Just for some bike-shedding, I don't like using '..' too much ;)
>>>>>>> Would it be a good idea to modify libcpp's lexer to recognize
>>>>>>> identifier.number as a single token if -fgimple is enabled ?
>>>>>>
>>>>>> I don't think so.  As said, we can retain the i_2 syntax as well where you then
>>>>>> get a single token and to decide whether it is a SSA name do a lookup for
>>>>>> 'i' first and if that succeeds, interpret _2 as a version suffix,
>>>>>> otherwise use it
>>>>>> as full variable name.  Re-constructing the 1 from .1 or 17 from .17 CPP_NUMBER
>>>>>> is possible as well of course.
>>>>>>
>>>>>
>>>>> Sorry for the late response. I was little busy due to some family problem.
>>>>>
>>>>> In this patch, I am parsing ssa names as described above. But the
>>>>> problem is non ssa variable also gets renamed
>>>> I assume you're referring to renaming of a to a_5 here ?
>>>> I suppose that's expected since 'a' is gimple reg, ssa pass will
>>>> create ssa name for it.
>>>> Maybe emit "parse error" if local var is not in "ssa syntax", that is,
>>>> it doesn't
>>>> have _version suffixed ? But emitting an error for this case looks
>>>> artificial to me.
>>>
>>> Yes, I think the result is as expected.  If we want to constrain the
>>> input to the
>>> GIMPLE parser then we somehow have to tell it what kind of GIMPLE we are
>>> presenting it (SSA or non-SSA gimple), but for the moment what you have
>>> and show with the testcase looks good to me.
>>>
>>> The parsing doesn't handle
>>>
>>> void __GIMPLE () foo ()
>>> {
>>>   int a_3;
>>>   a_3_1 = 0;
>>> }
>>>
>>> correctly as it looks for the first '_' rather than the last.  I'd have used
>>> sth like
>>>
>>>   char *p = strrchr (ssa_token, '_');
>>>   if (p)
>>>     {
>>>       var_name = new char [p - ssa_token + 1];
>>>       memcpy (var_name, ssa_token, p - ssa_token);
>>>       var_name[p - ssa_token] = '\0';
>>>       ...
>>>       version = atoi (p);
>>>
>>> in the patch you have two copies of the SSA name parsing code - you want to
>>> split that out into a function.
>>>
>>> There is one other feature missing for SSA name parsing (forget to mention that)
>>> which is parsing of default def SSA names.  Those are for example used for
>>> parameters and currently dumped like
>>>
>>> foo (int i)
>>> {
>>>   int D.1759;
>>>   int _2;
>>>
>>>   <bb 2>:
>>>   _2 = i_1(D) + 1;
>>>   return _2;
>>> }
>>>
>>> for int foo (int i) { return i + 1; }.  Here 'i_1(D)' is the
>>> default-def of 'i' which
>>> in case of a parameter is the value at function start and in case of a
>>> non-parameter
>>> is simply "undefined".  '(D)' is again somewhat awkward to parse but I guess we
>>> can cope with that ;)  A default-def needs to be registered like
>>>
>>>   arg = make_ssa_name_fn (cfun, lookup_name (id), ...);
>>>   set_ssa_default_def (cfun, lookup_name (id), arg);
>>>
>>> "undefined" SSA names appear often in PHIs (and of course for parameters).
>>>
>>
>> This updated patch tries to parse default def ssa names
> Um does this emit error for cases like a_1() and a_(D) ?
> From the code it appears to me that parsing 'D' is made optional, so
> id_version() would be accepted.
> Perhaps have an else for the if (!strcmp("D", ...) that emits parse error ?
>
Right. Currently it gives ICE but we can handle it with better way.

> Btw for the following case:
> int a;
> int a_1;
> int x = a_1 + 1;
> What does a_1 refer to in "int x = a_1 + 1" ? the ssa-version of 'a'
> or the variable 'a_1' ?
> I think from the code it would refer to ssa-version of a ? However the
> reference looks
> ambiguous to me (since we also allow variables in non-ssa form).
>
we are guarding it with condition
if (TREE_CODE (c_parser_peek_token (parser)->value) == IDENTIFIER_NODE
        && !lookup_name (c_parser_peek_token (parser)->value))
so that shouldn't happen.


Thanks,
Prasad

> Thanks,
> Prathamesh
>>
>> Thanks,
>> Prasad
>>
>>> Thanks,
>>> Richard.
>>>
>>>> Thanks,
>>>> Prathamesh
>>>>>
>>>>> for testcase :
>>>>>
>>>>> void __GIMPLE () foo()
>>>>> {
>>>>>   int a;
>>>>> bb_2:
>>>>>   if (a > 4)
>>>>>     goto bb_3;
>>>>>   else
>>>>>     goto bb_4;
>>>>> bb_3:
>>>>>   a_1 = 55;
>>>>>   goto bb_5;
>>>>>
>>>>> bb_4:
>>>>>   a_2 = 99;
>>>>>
>>>>> bb_5:
>>>>>   a_3 = __PHI (bb_3: a_1, bb_4: a_2);
>>>>>   a_4 = a_3 + 3;
>>>>>   return;
>>>>> }
>>>>>
>>>>> I am getting ssa dump as:
>>>>>
>>>>> /* Function foo (foo, funcdef_no=0, decl_uid=1744, cgraph_uid=0,
>>>>> symbol_order=0)*/
>>>>>
>>>>> void
>>>>> foo ()
>>>>> {
>>>>> bb_2:
>>>>>   if (a_5 > 4)
>>>>>     goto bb_3;
>>>>>   else
>>>>>     goto bb_4;
>>>>>
>>>>> bb_3:
>>>>>   a_1 = 55;
>>>>>   goto bb_5;
>>>>>
>>>>> bb_4:
>>>>>   a_2 = 99;
>>>>>
>>>>>   a_3 = __PHI (bb_3: a_1, bb_4: a_2)
>>>>> bb_5:
>>>>>   a_4 = a_3 + 3;
>>>>>   return;
>>>>>
>>>>> }
>>>>>
>>>>>> Richard.
>>>>>>
>>>>>>> Thanks,
>>>>>>> Prathamesh
>>>>>>>>
>>>>>>>> Richard.
>>>>>>>>
>>>>>>>>>
>>>>>>>>>> Richard.
>>>>>>>>>>
>>>>>>>>>>>Dave
>>>>>>>>>>
>>>>>>>>>>

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [gimplefe] hacking pass manager
  2016-07-29  7:03                                                 ` Prasad Ghangal
@ 2016-07-29  7:25                                                   ` Richard Biener
  2016-07-29 10:13                                                     ` Prasad Ghangal
  0 siblings, 1 reply; 29+ messages in thread
From: Richard Biener @ 2016-07-29  7:25 UTC (permalink / raw)
  To: Prasad Ghangal; +Cc: Prathamesh Kulkarni, David Malcolm, gcc Mailing List

On Fri, Jul 29, 2016 at 9:03 AM, Prasad Ghangal
<prasad.ghangal@gmail.com> wrote:
> Thanks,
> Prasad
>
>
> On 29 July 2016 at 06:56, Prathamesh Kulkarni
> <prathamesh.kulkarni@linaro.org> wrote:
>> On 29 July 2016 at 00:01, Prasad Ghangal <prasad.ghangal@gmail.com> wrote:
>>> On 27 July 2016 at 14:22, Richard Biener <richard.guenther@gmail.com> wrote:
>>>> On Tue, Jul 26, 2016 at 11:38 PM, Prathamesh Kulkarni
>>>> <prathamesh.kulkarni@linaro.org> wrote:
>>>>> On 27 July 2016 at 00:20, Prasad Ghangal <prasad.ghangal@gmail.com> wrote:
>>>> There is one other feature missing for SSA name parsing (forget to mention that)
>>>> which is parsing of default def SSA names.  Those are for example used for
>>>> parameters and currently dumped like
>>>>
>>>> foo (int i)
>>>> {
>>>>   int D.1759;
>>>>   int _2;
>>>>
>>>>   <bb 2>:
>>>>   _2 = i_1(D) + 1;
>>>>   return _2;
>>>> }
>>>>
>>>> for int foo (int i) { return i + 1; }.  Here 'i_1(D)' is the
>>>> default-def of 'i' which
>>>> in case of a parameter is the value at function start and in case of a
>>>> non-parameter
>>>> is simply "undefined".  '(D)' is again somewhat awkward to parse but I guess we
>>>> can cope with that ;)  A default-def needs to be registered like
>>>>
>>>>   arg = make_ssa_name_fn (cfun, lookup_name (id), ...);
>>>>   set_ssa_default_def (cfun, lookup_name (id), arg);
>>>>
>>>> "undefined" SSA names appear often in PHIs (and of course for parameters).
>>>>
>>>
>>> This updated patch tries to parse default def ssa names
>> Um does this emit error for cases like a_1() and a_(D) ?
>> From the code it appears to me that parsing 'D' is made optional, so
>> id_version() would be accepted.
>> Perhaps have an else for the if (!strcmp("D", ...) that emits parse error ?
>>
> Right. Currently it gives ICE but we can handle it with better way.
>
>> Btw for the following case:
>> int a;
>> int a_1;
>> int x = a_1 + 1;
>> What does a_1 refer to in "int x = a_1 + 1" ? the ssa-version of 'a'
>> or the variable 'a_1' ?
>> I think from the code it would refer to ssa-version of a ? However the
>> reference looks
>> ambiguous to me (since we also allow variables in non-ssa form).
>>
> we are guarding it with condition
> if (TREE_CODE (c_parser_peek_token (parser)->value) == IDENTIFIER_NODE
>         && !lookup_name (c_parser_peek_token (parser)->value))
> so that shouldn't happen.

Note that the example is indeed ambiguous.  As said previously rejecting all
invalid source shouldn't be necessarily scope of the GSoC project.  In this
particular case the issue is from using _ as the separator for the SSA name
version - the source simply has to cope with that (or we need to choose sth
else).  Similar issue is that a_1(D) can also parse as a function call in C.

Btw, I'd like to see some testcases for the SSA name parsing in the testsuite.

Thanks,
Richard.

>
> Thanks,
> Prasad
>
>> Thanks,
>> Prathamesh
>>>
>>> Thanks,
>>> Prasad
>>>
>>>> Thanks,
>>>> Richard.
>>>>
>>>>> Thanks,
>>>>> Prathamesh
>>>>>>
>>>>>> for testcase :
>>>>>>
>>>>>> void __GIMPLE () foo()
>>>>>> {
>>>>>>   int a;
>>>>>> bb_2:
>>>>>>   if (a > 4)
>>>>>>     goto bb_3;
>>>>>>   else
>>>>>>     goto bb_4;
>>>>>> bb_3:
>>>>>>   a_1 = 55;
>>>>>>   goto bb_5;
>>>>>>
>>>>>> bb_4:
>>>>>>   a_2 = 99;
>>>>>>
>>>>>> bb_5:
>>>>>>   a_3 = __PHI (bb_3: a_1, bb_4: a_2);
>>>>>>   a_4 = a_3 + 3;
>>>>>>   return;
>>>>>> }
>>>>>>
>>>>>> I am getting ssa dump as:
>>>>>>
>>>>>> /* Function foo (foo, funcdef_no=0, decl_uid=1744, cgraph_uid=0,
>>>>>> symbol_order=0)*/
>>>>>>
>>>>>> void
>>>>>> foo ()
>>>>>> {
>>>>>> bb_2:
>>>>>>   if (a_5 > 4)
>>>>>>     goto bb_3;
>>>>>>   else
>>>>>>     goto bb_4;
>>>>>>
>>>>>> bb_3:
>>>>>>   a_1 = 55;
>>>>>>   goto bb_5;
>>>>>>
>>>>>> bb_4:
>>>>>>   a_2 = 99;
>>>>>>
>>>>>>   a_3 = __PHI (bb_3: a_1, bb_4: a_2)
>>>>>> bb_5:
>>>>>>   a_4 = a_3 + 3;
>>>>>>   return;
>>>>>>
>>>>>> }
>>>>>>
>>>>>>> Richard.
>>>>>>>
>>>>>>>> Thanks,
>>>>>>>> Prathamesh
>>>>>>>>>
>>>>>>>>> Richard.
>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>> Richard.
>>>>>>>>>>>
>>>>>>>>>>>>Dave
>>>>>>>>>>>
>>>>>>>>>>>

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [gimplefe] hacking pass manager
  2016-07-29  7:25                                                   ` Richard Biener
@ 2016-07-29 10:13                                                     ` Prasad Ghangal
  0 siblings, 0 replies; 29+ messages in thread
From: Prasad Ghangal @ 2016-07-29 10:13 UTC (permalink / raw)
  To: Richard Biener; +Cc: Prathamesh Kulkarni, David Malcolm, gcc Mailing List

Thanks,
Prasad


On 29 July 2016 at 12:55, Richard Biener <richard.guenther@gmail.com> wrote:
> On Fri, Jul 29, 2016 at 9:03 AM, Prasad Ghangal
> <prasad.ghangal@gmail.com> wrote:
>> Thanks,
>> Prasad
>>
>>
>> On 29 July 2016 at 06:56, Prathamesh Kulkarni
>> <prathamesh.kulkarni@linaro.org> wrote:
>>> On 29 July 2016 at 00:01, Prasad Ghangal <prasad.ghangal@gmail.com> wrote:
>>>> On 27 July 2016 at 14:22, Richard Biener <richard.guenther@gmail.com> wrote:
>>>>> On Tue, Jul 26, 2016 at 11:38 PM, Prathamesh Kulkarni
>>>>> <prathamesh.kulkarni@linaro.org> wrote:
>>>>>> On 27 July 2016 at 00:20, Prasad Ghangal <prasad.ghangal@gmail.com> wrote:
>>>>> There is one other feature missing for SSA name parsing (forget to mention that)
>>>>> which is parsing of default def SSA names.  Those are for example used for
>>>>> parameters and currently dumped like
>>>>>
>>>>> foo (int i)
>>>>> {
>>>>>   int D.1759;
>>>>>   int _2;
>>>>>
>>>>>   <bb 2>:
>>>>>   _2 = i_1(D) + 1;
>>>>>   return _2;
>>>>> }
>>>>>
>>>>> for int foo (int i) { return i + 1; }.  Here 'i_1(D)' is the
>>>>> default-def of 'i' which
>>>>> in case of a parameter is the value at function start and in case of a
>>>>> non-parameter
>>>>> is simply "undefined".  '(D)' is again somewhat awkward to parse but I guess we
>>>>> can cope with that ;)  A default-def needs to be registered like
>>>>>
>>>>>   arg = make_ssa_name_fn (cfun, lookup_name (id), ...);
>>>>>   set_ssa_default_def (cfun, lookup_name (id), arg);
>>>>>
>>>>> "undefined" SSA names appear often in PHIs (and of course for parameters).
>>>>>
>>>>
>>>> This updated patch tries to parse default def ssa names
>>> Um does this emit error for cases like a_1() and a_(D) ?
>>> From the code it appears to me that parsing 'D' is made optional, so
>>> id_version() would be accepted.
>>> Perhaps have an else for the if (!strcmp("D", ...) that emits parse error ?
>>>
>> Right. Currently it gives ICE but we can handle it with better way.
>>
>>> Btw for the following case:
>>> int a;
>>> int a_1;
>>> int x = a_1 + 1;
>>> What does a_1 refer to in "int x = a_1 + 1" ? the ssa-version of 'a'
>>> or the variable 'a_1' ?
>>> I think from the code it would refer to ssa-version of a ? However the
>>> reference looks
>>> ambiguous to me (since we also allow variables in non-ssa form).
>>>
>> we are guarding it with condition
>> if (TREE_CODE (c_parser_peek_token (parser)->value) == IDENTIFIER_NODE
>>         && !lookup_name (c_parser_peek_token (parser)->value))
>> so that shouldn't happen.
>
> Note that the example is indeed ambiguous.  As said previously rejecting all
> invalid source shouldn't be necessarily scope of the GSoC project.  In this
> particular case the issue is from using _ as the separator for the SSA name
> version - the source simply has to cope with that (or we need to choose sth
> else).  Similar issue is that a_1(D) can also parse as a function call in C.
>
> Btw, I'd like to see some testcases for the SSA name parsing in the testsuite.
>
I have added testcases for __PHI and ssa names

Thanks,
Prasad

> Thanks,
> Richard.
>
>>
>> Thanks,
>> Prasad
>>
>>> Thanks,
>>> Prathamesh
>>>>
>>>> Thanks,
>>>> Prasad
>>>>
>>>>> Thanks,
>>>>> Richard.
>>>>>
>>>>>> Thanks,
>>>>>> Prathamesh
>>>>>>>
>>>>>>> for testcase :
>>>>>>>
>>>>>>> void __GIMPLE () foo()
>>>>>>> {
>>>>>>>   int a;
>>>>>>> bb_2:
>>>>>>>   if (a > 4)
>>>>>>>     goto bb_3;
>>>>>>>   else
>>>>>>>     goto bb_4;
>>>>>>> bb_3:
>>>>>>>   a_1 = 55;
>>>>>>>   goto bb_5;
>>>>>>>
>>>>>>> bb_4:
>>>>>>>   a_2 = 99;
>>>>>>>
>>>>>>> bb_5:
>>>>>>>   a_3 = __PHI (bb_3: a_1, bb_4: a_2);
>>>>>>>   a_4 = a_3 + 3;
>>>>>>>   return;
>>>>>>> }
>>>>>>>
>>>>>>> I am getting ssa dump as:
>>>>>>>
>>>>>>> /* Function foo (foo, funcdef_no=0, decl_uid=1744, cgraph_uid=0,
>>>>>>> symbol_order=0)*/
>>>>>>>
>>>>>>> void
>>>>>>> foo ()
>>>>>>> {
>>>>>>> bb_2:
>>>>>>>   if (a_5 > 4)
>>>>>>>     goto bb_3;
>>>>>>>   else
>>>>>>>     goto bb_4;
>>>>>>>
>>>>>>> bb_3:
>>>>>>>   a_1 = 55;
>>>>>>>   goto bb_5;
>>>>>>>
>>>>>>> bb_4:
>>>>>>>   a_2 = 99;
>>>>>>>
>>>>>>>   a_3 = __PHI (bb_3: a_1, bb_4: a_2)
>>>>>>> bb_5:
>>>>>>>   a_4 = a_3 + 3;
>>>>>>>   return;
>>>>>>>
>>>>>>> }
>>>>>>>
>>>>>>>> Richard.
>>>>>>>>
>>>>>>>>> Thanks,
>>>>>>>>> Prathamesh
>>>>>>>>>>
>>>>>>>>>> Richard.
>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>> Richard.
>>>>>>>>>>>>
>>>>>>>>>>>>>Dave
>>>>>>>>>>>>
>>>>>>>>>>>>

^ permalink raw reply	[flat|nested] 29+ messages in thread

end of thread, other threads:[~2016-07-29 10:13 UTC | newest]

Thread overview: 29+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-06-18  6:32 [gimplefe] hacking pass manager Prasad Ghangal
2016-06-29 16:20 ` Prathamesh Kulkarni
2016-06-29 16:45   ` Richard Biener
2016-06-29 19:14     ` Prasad Ghangal
2016-06-30 11:41       ` Richard Biener
2016-07-01 12:30         ` Prathamesh Kulkarni
2016-07-06  7:51         ` Prasad Ghangal
2016-07-06  8:55           ` Richard Biener
2016-07-07 19:45             ` Prasad Ghangal
2016-07-08  7:43               ` Richard Biener
2016-07-10 16:13                 ` Prasad Ghangal
2016-07-15 10:43                   ` Richard Biener
2016-07-18 18:28                     ` Prasad Ghangal
2016-07-18 18:55                       ` Richard Biener
2016-07-18 19:22                         ` Prasad Ghangal
2016-07-18 21:06                           ` David Malcolm
2016-07-19  5:35                             ` Richard Biener
2016-07-19 20:09                               ` Prasad Ghangal
2016-07-20 10:35                                 ` Richard Biener
2016-07-20 11:46                                   ` Prathamesh Kulkarni
2016-07-20 12:58                                     ` Richard Biener
2016-07-26 18:50                                       ` Prasad Ghangal
2016-07-26 21:39                                         ` Prathamesh Kulkarni
2016-07-27  8:53                                           ` Richard Biener
2016-07-28 18:31                                             ` Prasad Ghangal
2016-07-29  1:26                                               ` Prathamesh Kulkarni
2016-07-29  7:03                                                 ` Prasad Ghangal
2016-07-29  7:25                                                   ` Richard Biener
2016-07-29 10:13                                                     ` Prasad Ghangal

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).