public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* [gsoc 2014] moving fold-const patterns to gimple
@ 2014-03-02 20:13 Prathamesh Kulkarni
  2014-03-03 10:02 ` Richard Biener
  0 siblings, 1 reply; 22+ messages in thread
From: Prathamesh Kulkarni @ 2014-03-02 20:13 UTC (permalink / raw)
  To: gcc, ktietz70

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

Hi, I am an undergraduate student at University of Pune, India, and would
like to work on moving folding patterns from fold-const.c to gimple.

If I understand correctly, constant folding is done on GENERIC (by
routines in fold-const.c), and then GENERIC is lowered to GIMPLE. The
purpose of this project,
is to have constant folding to be performed on GIMPLE instead (in
gimple-fold.c?)

I have a few elementary questions to ask:

a) A contrived example:
Consider a C expression, a = ~0 (assume a is int)
In GENERIC, this would roughly be represented as:
modify_expr<var_decl "a", <bit_not_expr<integer_cst 0>>>
this gets folded to:
modify_expr<var_decl "a", integer_cst -1>
and the corresponding gimple tuple generated is (-fdump-tree-gimple-raw):
gimple_assign <integer_cst, x, -1, NULL, NULL>

So, instead of folding performed on GENERIC, it should be
done on GIMPLE.
So a tuple like the following should be generated by gimplification:
<bit_not_expr, a, 0, NULL, NULL>
and folded to (by call to fold_stmt):
<integer_cst, a, -1, NUL, NULL>
Is this the expected behavior ?

I have attached a rough/incomplete patch (only stage1 compiled cc1), that
does the following foldings on bit_not_expr:
a) ~ INTEGER_CST => folded
b) ~~x => x
c) ~(-x) => x - 1
(For the moment, I put case BIT_NOT_EXPR: return NULL_TREE
in fold_unary_loc to avoid folding in GENERIC on bit_not_expr)

Is the patch going in the correct direction ? Or have I completely missed
the point here ? I would be grateful to receive suggestions, and start working
on a fair patch.

On the following test-case:
int main()
{
  int a, b, c;
  a = ~~~~b;
  c = ~-a;
  return 0;
}

The following GIMPLE is generated:
main ()
gimple_bind <
  int D.1748;
  int D.1749;
  int D.1750;
  int D.1751;
  int D.1752;
  int a;
  int b;
  int c;

  gimple_assign <var_decl, D.1749, b, NULL, NULL>
  gimple_assign <var_decl, a, D.1749, NULL, NULL>
  gimple_assign <plus_expr, c, a, -1, NULL>
  gimple_assign <integer_cst, D.1752, 0, NULL, NULL>
  gimple_return <D.1752>
>

The patch generates two tuples for a = ~~~~b,
where only one is needed, and extra temporaries, which
are not removed after the folding. How should I go about
removing that (should I worry about that since subsequent passes,
shall remove those ?)

b) Some front-ends, C, for example, requires constant folding in certain places,
like case statement. If constant folding is completely moved off to gimple,
how shall this be handled ? Shall we gimplify the expression immediately if
it's required to be evaluated ?

Thanks and Regards,
Prathamesh

[-- Attachment #2: bit_not_expr.patch --]
[-- Type: text/x-patch, Size: 2757 bytes --]

Index: gcc/fold-const.c
===================================================================
--- gcc/fold-const.c	(revision 208111)
+++ gcc/fold-const.c	(working copy)
@@ -8313,6 +8313,7 @@ fold_unary_loc (location_t loc, enum tre
       return NULL_TREE;
 
     case BIT_NOT_EXPR:
+      return NULL_TREE;
       if (TREE_CODE (arg0) == INTEGER_CST)
         return fold_not_const (arg0, type);
       else if (TREE_CODE (arg0) == BIT_NOT_EXPR)
Index: gcc/gimple-fold.c
===================================================================
--- gcc/gimple-fold.c	(revision 208111)
+++ gcc/gimple-fold.c	(working copy)
@@ -352,6 +352,68 @@ maybe_fold_reference (tree expr, bool is
   return NULL_TREE;
 }
 
+static tree
+fold_not_const (const_tree arg0, tree type)
+{
+  double_int val;
+
+  gcc_assert (TREE_CODE (arg0) == INTEGER_CST);
+
+  val = ~tree_to_double_int (arg0);
+  return force_fit_type_double (type, val, 0, TREE_OVERFLOW (arg0));
+}
+
+static tree
+fold_gimple_bit_not_expr (gimple_stmt_iterator *si)
+{
+  gimple stmt = gsi_stmt (*si);
+  tree rhs = gimple_assign_rhs1 (stmt);
+  tree result = NULL_TREE; 
+  enum tree_code code = TREE_CODE (rhs);
+  tree type = gimple_expr_type (stmt);
+  gimple_stmt_iterator temp_iter;
+
+  if (code == INTEGER_CST)
+    return fold_not_const (rhs, type); 
+  
+  temp_iter = *si;
+  gsi_prev (&temp_iter);
+  gimple prev = gsi_stmt (temp_iter);
+  
+  if (prev)
+    {
+      if (gimple_code (prev) != GIMPLE_ASSIGN)
+	return NULL_TREE;
+
+      switch (gimple_assign_rhs_code (prev))
+	{
+	  case BIT_NOT_EXPR:  // x = ~~y => x = y
+	    if (gimple_assign_lhs (prev) == rhs)
+	      {
+		result = gimple_assign_rhs1 (prev);
+		gsi_remove (&temp_iter, true);
+		return result;
+	      }
+	    return NULL_TREE;
+	
+	  case NEGATE_EXPR:  // x = ~-y => x = y - 1
+	    if (INTEGRAL_TYPE_P (type))
+	      {
+		result = fold_build2 (MINUS_EXPR, type, 
+				      fold_convert (type, gimple_assign_rhs1 (prev)),
+				      build_int_cst (type, 1));
+		gsi_remove (&temp_iter, true);
+		return result;
+	      }
+	    return NULL_TREE;
+
+	  default:
+	    return NULL_TREE;
+	}
+    }
+  
+  return NULL_TREE; 
+}
 
 /* Attempt to fold an assignment statement pointed-to by SI.  Returns a
    replacement rhs for the statement or NULL_TREE if no simplification
@@ -458,8 +520,10 @@ fold_gimple_assign (gimple_stmt_iterator
     case GIMPLE_UNARY_RHS:
       {
 	tree rhs = gimple_assign_rhs1 (stmt);
-
-	result = fold_unary_loc (loc, subcode, gimple_expr_type (stmt), rhs);
+	if (subcode == BIT_NOT_EXPR)
+	  result = fold_gimple_bit_not_expr (si);
+	else
+	  result = fold_unary_loc (loc, subcode, gimple_expr_type (stmt), rhs);
 	if (result)
 	  {
 	    /* If the operation was a conversion do _not_ mark a

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

end of thread, other threads:[~2014-03-21  9:49 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-03-02 20:13 [gsoc 2014] moving fold-const patterns to gimple Prathamesh Kulkarni
2014-03-03 10:02 ` Richard Biener
2014-03-06 12:11   ` Prathamesh Kulkarni
2014-03-06 12:43     ` Richard Biener
2014-03-06 18:17       ` Prathamesh Kulkarni
2014-03-07  9:08         ` Richard Biener
2014-03-10 18:29           ` Prathamesh Kulkarni
2014-03-11 11:20             ` Richard Biener
2014-03-13 11:14               ` Richard Biener
2014-03-14 15:31                 ` Prathamesh Kulkarni
2014-03-14 15:35                   ` Prathamesh Kulkarni
2014-03-14 15:55                   ` Marc Glisse
2014-03-14 16:37                     ` Prathamesh Kulkarni
2014-03-14 17:54                       ` Marc Glisse
2014-03-14 17:16                   ` Richard Biener
2014-03-16 12:21                     ` Prathamesh Kulkarni
2014-03-17  8:52                       ` Richard Biener
2014-03-18  8:13                         ` Prathamesh Kulkarni
2014-03-19  0:27                           ` Maxim Kuvyrkov
     [not found]                         ` <CAJXstsD0Y=vBxw9QveOU3O3jhQgbYkxj_iyfje=AFypHEmK9gA@mail.gmail.com>
2014-03-19  9:43                           ` Richard Biener
2014-03-20 20:52                             ` Prathamesh Kulkarni
2014-03-21  9:49                               ` Richard Biener

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