public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH][6/n] Alias housekeeping
@ 2011-04-28  9:55 Richard Guenther
  0 siblings, 0 replies; 2+ messages in thread
From: Richard Guenther @ 2011-04-28  9:55 UTC (permalink / raw)
  To: gcc-patches


This changes PTA graph dumps to DOT format and dumps before
and after solving.  It also moves succ graph building after
freeing substitution info, reducing peak memory usage slightly.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.

Richard.

2011-04-28  Richard Guenther  <rguenther@suse.de>

	* tree-ssa-structalias.c (dump_constraint): Don't end the line.
	(debug_constraint): Do it here.
	(dump_constraints): And here.
	(rewrite_constraints): And here.
	(dump_constraint_edge): Remove.
	(dump_constraint_graph): Rewrite to produce DOT output.
	(solve_constraints): Build succ graph as late as possible.
	Dump constraint graphs before and after solving.

Index: gcc/tree-ssa-structalias.c
===================================================================
*** gcc/tree-ssa-structalias.c.orig	2011-02-02 16:17:27.000000000 +0100
--- gcc/tree-ssa-structalias.c	2011-02-02 16:33:10.000000000 +0100
*************** dump_constraint (FILE *file, constraint_
*** 707,713 ****
      fprintf (file, " + UNKNOWN");
    else if (c->rhs.offset != 0)
      fprintf (file, " + " HOST_WIDE_INT_PRINT_DEC, c->rhs.offset);
-   fprintf (file, "\n");
  }
  
  
--- 707,712 ----
*************** DEBUG_FUNCTION void
*** 723,728 ****
--- 722,728 ----
  debug_constraint (constraint_t c)
  {
    dump_constraint (stderr, c);
+   fprintf (stderr, "\n");
  }
  
  /* Print out all constraints to FILE */
*************** dump_constraints (FILE *file, int from)
*** 733,739 ****
    int i;
    constraint_t c;
    for (i = from; VEC_iterate (constraint_t, constraints, i, c); i++)
!     dump_constraint (file, c);
  }
  
  /* Print out all constraints to stderr.  */
--- 733,743 ----
    int i;
    constraint_t c;
    for (i = from; VEC_iterate (constraint_t, constraints, i, c); i++)
!     if (c)
!       {
! 	dump_constraint (file, c);
! 	fprintf (file, "\n");
!       }
  }
  
  /* Print out all constraints to stderr.  */
*************** debug_constraints (void)
*** 744,829 ****
    dump_constraints (stderr, 0);
  }
  
- /* Print out to FILE the edge in the constraint graph that is created by
-    constraint c. The edge may have a label, depending on the type of
-    constraint that it represents. If complex1, e.g: a = *b, then the label
-    is "=*", if complex2, e.g: *a = b, then the label is "*=", if
-    complex with an offset, e.g: a = b + 8, then the label is "+".
-    Otherwise the edge has no label.  */
- 
- static void
- dump_constraint_edge (FILE *file, constraint_t c)
- {
-   if (c->rhs.type != ADDRESSOF)
-     {
-       const char *src = get_varinfo (c->rhs.var)->name;
-       const char *dst = get_varinfo (c->lhs.var)->name;
-       fprintf (file, "  \"%s\" -> \"%s\" ", src, dst);
-       /* Due to preprocessing of constraints, instructions like *a = *b are
-          illegal; thus, we do not have to handle such cases.  */
-       if (c->lhs.type == DEREF)
-         fprintf (file, " [ label=\"*=\" ] ;\n");
-       else if (c->rhs.type == DEREF)
-         fprintf (file, " [ label=\"=*\" ] ;\n");
-       else
-         {
-           /* We must check the case where the constraint is an offset.
-              In this case, it is treated as a complex constraint.  */
-           if (c->rhs.offset != c->lhs.offset)
-             fprintf (file, " [ label=\"+\" ] ;\n");
-           else
-             fprintf (file, " ;\n");
-         }
-     }
- }
- 
  /* Print the constraint graph in dot format.  */
  
  static void
  dump_constraint_graph (FILE *file)
  {
!   unsigned int i=0, size;
!   constraint_t c;
  
    /* Only print the graph if it has already been initialized:  */
    if (!graph)
      return;
  
-   /* Print the constraints used to produce the constraint graph. The
-      constraints will be printed as comments in the dot file:  */
-   fprintf (file, "\n\n/* Constraints used in the constraint graph:\n");
-   dump_constraints (file, 0);
-   fprintf (file, "*/\n");
- 
    /* Prints the header of the dot file:  */
-   fprintf (file, "\n\n// The constraint graph in dot format:\n");
    fprintf (file, "strict digraph {\n");
    fprintf (file, "  node [\n    shape = box\n  ]\n");
    fprintf (file, "  edge [\n    fontsize = \"12\"\n  ]\n");
!   fprintf (file, "\n  // List of nodes in the constraint graph:\n");
  
!   /* The next lines print the nodes in the graph. In order to get the
!      number of nodes in the graph, we must choose the minimum between the
!      vector VEC (varinfo_t, varmap) and graph->size. If the graph has not
!      yet been initialized, then graph->size == 0, otherwise we must only
!      read nodes that have an entry in VEC (varinfo_t, varmap).  */
!   size = VEC_length (varinfo_t, varmap);
!   size = size < graph->size ? size : graph->size;
!   for (i = 0; i < size; i++)
      {
!       const char *name = get_varinfo (graph->rep[i])->name;
!       fprintf (file, "  \"%s\" ;\n", name);
      }
  
!   /* Go over the list of constraints printing the edges in the constraint
!      graph.  */
!   fprintf (file, "\n  // The constraint edges:\n");
!   FOR_EACH_VEC_ELT (constraint_t, constraints, i, c)
!     if (c)
!       dump_constraint_edge (file, c);
  
!   /* Prints the tail of the dot file. By now, only the closing bracket.  */
!   fprintf (file, "}\n\n\n");
  }
  
  /* Print out the constraint graph to stderr.  */
--- 748,824 ----
    dump_constraints (stderr, 0);
  }
  
  /* Print the constraint graph in dot format.  */
  
  static void
  dump_constraint_graph (FILE *file)
  {
!   unsigned int i;
  
    /* Only print the graph if it has already been initialized:  */
    if (!graph)
      return;
  
    /* Prints the header of the dot file:  */
    fprintf (file, "strict digraph {\n");
    fprintf (file, "  node [\n    shape = box\n  ]\n");
    fprintf (file, "  edge [\n    fontsize = \"12\"\n  ]\n");
!   fprintf (file, "\n  // List of nodes and complex constraints in "
! 	   "the constraint graph:\n");
  
!   /* The next lines print the nodes in the graph together with the
!      complex constraints attached to them.  */
!   for (i = 0; i < graph->size; i++)
      {
!       if (find (i) != i)
! 	continue;
!       if (i < FIRST_REF_NODE)
! 	fprintf (file, "\"%s\"", get_varinfo (i)->name);
!       else
! 	fprintf (file, "\"*%s\"", get_varinfo (i - FIRST_REF_NODE)->name);
!       if (graph->complex[i])
! 	{
! 	  unsigned j;
! 	  constraint_t c;
! 	  fprintf (file, " [label=\"\\N\\n");
! 	  for (j = 0; VEC_iterate (constraint_t, graph->complex[i], j, c); ++j)
! 	    {
! 	      dump_constraint (file, c);
! 	      fprintf (file, "\\l");
! 	    }
! 	  fprintf (file, "\"]");
! 	}
!       fprintf (file, ";\n");
      }
  
!   /* Go over the edges.  */
!   fprintf (file, "\n  // Edges in the constraint graph:\n");
!   for (i = 0; i < graph->size; i++)
!     {
!       unsigned j;
!       bitmap_iterator bi;
!       if (find (i) != i)
! 	continue;
!       EXECUTE_IF_IN_NONNULL_BITMAP (graph->succs[i], 0, j, bi)
! 	{
! 	  unsigned to = find (j);
! 	  if (i == to)
! 	    continue;
! 	  if (i < FIRST_REF_NODE)
! 	    fprintf (file, "\"%s\"", get_varinfo (i)->name);
! 	  else
! 	    fprintf (file, "\"*%s\"", get_varinfo (i - FIRST_REF_NODE)->name);
! 	  fprintf (file, " -> ");
! 	  if (to < FIRST_REF_NODE)
! 	    fprintf (file, "\"%s\"", get_varinfo (to)->name);
! 	  else
! 	    fprintf (file, "\"*%s\"", get_varinfo (to - FIRST_REF_NODE)->name);
! 	  fprintf (file, ";\n");
! 	}
!     }
  
!   /* Prints the tail of the dot file.  */
!   fprintf (file, "}\n");
  }
  
  /* Print out the constraint graph to stderr.  */
*************** rewrite_constraints (constraint_graph_t
*** 2507,2512 ****
--- 2495,2501 ----
  		       "ignoring constraint:",
  		       get_varinfo (lhs.var)->name);
  	      dump_constraint (dump_file, c);
+ 	      fprintf (dump_file, "\n");
  	    }
  	  VEC_replace (constraint_t, constraints, i, NULL);
  	  continue;
*************** rewrite_constraints (constraint_graph_t
*** 2521,2526 ****
--- 2510,2516 ----
  		       "ignoring constraint:",
  		       get_varinfo (rhs.var)->name);
  	      dump_constraint (dump_file, c);
+ 	      fprintf (dump_file, "\n");
  	    }
  	  VEC_replace (constraint_t, constraints, i, NULL);
  	  continue;
*************** solve_constraints (void)
*** 6474,6486 ****
      fprintf (dump_file, "Rewriting constraints and unifying "
  	     "variables\n");
    rewrite_constraints (graph, si);
- 
-   build_succ_graph ();
    free_var_substitution_info (si);
  
!   if (dump_file && (dump_flags & TDF_GRAPH))
!     dump_constraint_graph (dump_file);
  
    move_complex_constraints (graph);
  
    if (dump_file)
--- 6467,6477 ----
      fprintf (dump_file, "Rewriting constraints and unifying "
  	     "variables\n");
    rewrite_constraints (graph, si);
    free_var_substitution_info (si);
  
!   build_succ_graph ();
  
+   /* Attach complex constraints to graph nodes.  */
    move_complex_constraints (graph);
  
    if (dump_file)
*************** solve_constraints (void)
*** 6496,6506 ****
--- 6487,6513 ----
       point. */
    remove_preds_and_fake_succs (graph);
  
+   if (dump_file && (dump_flags & TDF_GRAPH))
+     {
+       fprintf (dump_file, "\n\n// The constraint graph before solve-graph "
+ 	       "in dot format:\n");
+       dump_constraint_graph (dump_file);
+       fprintf (dump_file, "\n\n");
+     }
+ 
    if (dump_file)
      fprintf (dump_file, "Solving graph\n");
  
    solve_graph (graph);
  
+   if (dump_file && (dump_flags & TDF_GRAPH))
+     {
+       fprintf (dump_file, "\n\n// The constraint graph after solve-graph "
+ 	       "in dot format:\n");
+       dump_constraint_graph (dump_file);
+       fprintf (dump_file, "\n\n");
+     }
+ 
    if (dump_file)
      dump_sa_points_to_info (dump_file);
  }

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

* [PATCH][6/n] Alias housekeeping
@ 2011-04-29 13:01 Richard Guenther
  0 siblings, 0 replies; 2+ messages in thread
From: Richard Guenther @ 2011-04-29 13:01 UTC (permalink / raw)
  To: gcc-patches


This makes PTA handle OBJ_TYPE_REF (not sure why I thought we need
to give up).

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.

Richard.

2011-04-29  Richard Guenther  <rguenther@suse.de>

	* tree-ssa-structalias.c (get_fi_for_callee): Restructure.
	Handle OBJ_TYPE_REF.
	(find_func_aliases_for_call): Use it more consistently.

Index: gcc/tree-ssa-structalias.c
===================================================================
*** gcc/tree-ssa-structalias.c	(revision 173067)
--- gcc/tree-ssa-structalias.c	(working copy)
*************** handle_pure_call (gimple stmt, VEC(ce_s,
*** 3925,3959 ****
  static varinfo_t
  get_fi_for_callee (gimple call)
  {
!   tree decl;
  
!   gcc_assert (!gimple_call_internal_p (call));
  
    /* If we can directly resolve the function being called, do so.
       Otherwise, it must be some sort of indirect expression that
       we should still be able to handle.  */
!   decl = gimple_call_fndecl (call);
    if (decl)
      return get_vi_for_tree (decl);
  
!   decl = gimple_call_fn (call);
!   /* The function can be either an SSA name pointer or,
!      worse, an OBJ_TYPE_REF.  In this case we have no
       clue and should be getting ANYFN (well, ANYTHING for now).  */
!   if (TREE_CODE (decl) == SSA_NAME)
!     {
!       if (TREE_CODE (decl) == SSA_NAME
! 	  && (TREE_CODE (SSA_NAME_VAR (decl)) == PARM_DECL
! 	      || TREE_CODE (SSA_NAME_VAR (decl)) == RESULT_DECL)
! 	  && SSA_NAME_IS_DEFAULT_DEF (decl))
! 	decl = SSA_NAME_VAR (decl);
!       return get_vi_for_tree (decl);
!     }
!   else if (TREE_CODE (decl) == INTEGER_CST
! 	   || TREE_CODE (decl) == OBJ_TYPE_REF)
      return get_varinfo (anything_id);
!   else
!     gcc_unreachable ();
  }
  
  /* Create constraints for the builtin call T.  Return true if the call
--- 3925,3953 ----
  static varinfo_t
  get_fi_for_callee (gimple call)
  {
!   tree decl, fn = gimple_call_fn (call);
  
!   if (fn && TREE_CODE (fn) == OBJ_TYPE_REF)
!     fn = OBJ_TYPE_REF_EXPR (fn);
  
    /* If we can directly resolve the function being called, do so.
       Otherwise, it must be some sort of indirect expression that
       we should still be able to handle.  */
!   decl = gimple_call_addr_fndecl (fn);
    if (decl)
      return get_vi_for_tree (decl);
  
!   /* If the function is anything other than a SSA name pointer we have no
       clue and should be getting ANYFN (well, ANYTHING for now).  */
!   if (!fn || TREE_CODE (fn) != SSA_NAME)
      return get_varinfo (anything_id);
! 
!   if ((TREE_CODE (SSA_NAME_VAR (fn)) == PARM_DECL
!        || TREE_CODE (SSA_NAME_VAR (fn)) == RESULT_DECL)
!       && SSA_NAME_IS_DEFAULT_DEF (fn))
!     fn = SSA_NAME_VAR (fn);
! 
!   return get_vi_for_tree (fn);
  }
  
  /* Create constraints for the builtin call T.  Return true if the call
*************** find_func_aliases_for_call (gimple t)
*** 4199,4209 ****
        && find_func_aliases_for_builtin_call (t))
      return;
  
    if (!in_ipa_mode
!       || gimple_call_internal_p (t)
!       || (fndecl
! 	  && (!(fi = lookup_vi_for_tree (fndecl))
! 	      || !fi->is_fn_info)))
      {
        VEC(ce_s, heap) *rhsc = NULL;
        int flags = gimple_call_flags (t);
--- 4193,4201 ----
        && find_func_aliases_for_builtin_call (t))
      return;
  
+   fi = get_fi_for_callee (t);
    if (!in_ipa_mode
!       || (fndecl && !fi->is_fn_info))
      {
        VEC(ce_s, heap) *rhsc = NULL;
        int flags = gimple_call_flags (t);
*************** find_func_aliases_for_call (gimple t)
*** 4231,4238 ****
        tree lhsop;
        unsigned j;
  
-       fi = get_fi_for_callee (t);
- 
        /* Assign all the passed arguments to the appropriate incoming
  	 parameters of the function.  */
        for (j = 0; j < gimple_call_num_args (t); j++)
--- 4223,4228 ----
*************** find_func_aliases_for_call (gimple t)
*** 4271,4277 ****
  	      VEC_free(ce_s, heap, tem);
  	    }
  	  FOR_EACH_VEC_ELT (ce_s, lhsc, j, lhsp)
! 	      process_constraint (new_constraint (*lhsp, rhs));
  	}
  
        /* If we pass the result decl by reference, honor that.  */
--- 4261,4267 ----
  	      VEC_free(ce_s, heap, tem);
  	    }
  	  FOR_EACH_VEC_ELT (ce_s, lhsc, j, lhsp)
! 	    process_constraint (new_constraint (*lhsp, rhs));
  	}
  
        /* If we pass the result decl by reference, honor that.  */
*************** find_func_aliases_for_call (gimple t)
*** 4286,4292 ****
  	  get_constraint_for_address_of (lhsop, &rhsc);
  	  lhs = get_function_part_constraint (fi, fi_result);
  	  FOR_EACH_VEC_ELT (ce_s, rhsc, j, rhsp)
! 	      process_constraint (new_constraint (lhs, *rhsp));
  	  VEC_free (ce_s, heap, rhsc);
  	}
  
--- 4276,4282 ----
  	  get_constraint_for_address_of (lhsop, &rhsc);
  	  lhs = get_function_part_constraint (fi, fi_result);
  	  FOR_EACH_VEC_ELT (ce_s, rhsc, j, rhsp)
! 	    process_constraint (new_constraint (lhs, *rhsp));
  	  VEC_free (ce_s, heap, rhsc);
  	}
  
*************** find_func_aliases_for_call (gimple t)
*** 4299,4305 ****
  	  get_constraint_for (gimple_call_chain (t), &rhsc);
  	  lhs = get_function_part_constraint (fi, fi_static_chain);
  	  FOR_EACH_VEC_ELT (ce_s, rhsc, j, rhsp)
! 	      process_constraint (new_constraint (lhs, *rhsp));
  	}
      }
  }
--- 4289,4295 ----
  	  get_constraint_for (gimple_call_chain (t), &rhsc);
  	  lhs = get_function_part_constraint (fi, fi_static_chain);
  	  FOR_EACH_VEC_ELT (ce_s, rhsc, j, rhsp)
! 	    process_constraint (new_constraint (lhs, *rhsp));
  	}
      }
  }

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

end of thread, other threads:[~2011-04-29 10:58 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-04-28  9:55 [PATCH][6/n] Alias housekeeping Richard Guenther
2011-04-29 13:01 Richard Guenther

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).