tree-ssa-pre.c (create_component_ref_by_pieces_1): Move call handling ...
authorRichard Biener <rguenther@suse.de>
Mon, 5 Oct 2015 11:13:14 +0000 (11:13 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Mon, 5 Oct 2015 11:13:14 +0000 (11:13 +0000)
2015-10-05  Richard Biener  <rguenther@suse.de>

* tree-ssa-pre.c (create_component_ref_by_pieces_1): Move
call handling ...
(create_expression_by_pieces): ... here and build GIMPLE
calls directly.  Use gimple_build API and avoid force_gimple_operand.
(insert_into_preds_of_block): Simplify.
(do_regular_insertion): Add comment.

From-SVN: r228471

gcc/ChangeLog
gcc/tree-ssa-pre.c

index 0d740a24901d1a3ef9b182735bb0052e6d693073..4b9ed52e95afdf00d5db75715bcee77a4cab3dda 100644 (file)
@@ -1,3 +1,12 @@
+2015-10-05  Richard Biener  <rguenther@suse.de>
+
+       * tree-ssa-pre.c (create_component_ref_by_pieces_1): Move
+       call handling ...
+       (create_expression_by_pieces): ... here and build GIMPLE
+       calls directly.  Use gimple_build API and avoid force_gimple_operand.
+       (insert_into_preds_of_block): Simplify.
+       (do_regular_insertion): Add comment.
+
 2015-10-04  Jason Merrill  <jason@redhat.com>
 
        * builtins.def (BUILT_IN_ABORT): Add transaction_pure attribute.
index f8feaa19c16ba9414951a408e57b4a67b099b5b1..fb9ed02ec87184413d9cac334c08f7b64f510b15 100644 (file)
@@ -2474,42 +2474,7 @@ create_component_ref_by_pieces_1 (basic_block block, vn_reference_t ref,
   switch (currop->opcode)
     {
     case CALL_EXPR:
-      {
-       tree folded, sc = NULL_TREE;
-       unsigned int nargs = 0;
-       tree fn, *args;
-       if (TREE_CODE (currop->op0) == FUNCTION_DECL)
-         fn = currop->op0;
-       else
-         fn = find_or_generate_expression (block, currop->op0, stmts);
-       if (!fn)
-         return NULL_TREE;
-       if (currop->op1)
-         {
-           sc = find_or_generate_expression (block, currop->op1, stmts);
-           if (!sc)
-             return NULL_TREE;
-         }
-       args = XNEWVEC (tree, ref->operands.length () - 1);
-       while (*operand < ref->operands.length ())
-         {
-           args[nargs] = create_component_ref_by_pieces_1 (block, ref,
-                                                           operand, stmts);
-           if (!args[nargs])
-             return NULL_TREE;
-           nargs++;
-         }
-       folded = build_call_array (currop->type,
-                                  (TREE_CODE (fn) == FUNCTION_DECL
-                                   ? build_fold_addr_expr (fn) : fn),
-                                  nargs, args);
-       if (currop->with_bounds)
-         CALL_WITH_BOUNDS_P (folded) = true;
-       free (args);
-       if (sc)
-         CALL_EXPR_STATIC_CHAIN (folded) = sc;
-       return folded;
-      }
+      gcc_unreachable ();
 
     case MEM_REF:
       {
@@ -2798,21 +2763,75 @@ create_expression_by_pieces (basic_block block, pre_expr expr,
 
   switch (expr->kind)
     {
-      /* We may hit the NAME/CONSTANT case if we have to convert types
-        that value numbering saw through.  */
+    /* We may hit the NAME/CONSTANT case if we have to convert types
+       that value numbering saw through.  */
     case NAME:
       folded = PRE_EXPR_NAME (expr);
+      if (useless_type_conversion_p (exprtype, TREE_TYPE (folded)))
+       return folded;
       break;
     case CONSTANT:
-      folded = PRE_EXPR_CONSTANT (expr);
-      break;
-    case REFERENCE:
-      {
-       vn_reference_t ref = PRE_EXPR_REFERENCE (expr);
-       folded = create_component_ref_by_pieces (block, ref, stmts);
-       if (!folded)
-         return NULL_TREE;
+      { 
+       folded = PRE_EXPR_CONSTANT (expr);
+       tree tem = fold_convert (exprtype, folded);
+       if (is_gimple_min_invariant (tem))
+         return tem;
+       break;
       }
+    case REFERENCE:
+      if (PRE_EXPR_REFERENCE (expr)->operands[0].opcode == CALL_EXPR)
+       {
+         vn_reference_t ref = PRE_EXPR_REFERENCE (expr);
+         unsigned int operand = 1;
+         vn_reference_op_t currop = &ref->operands[0];
+         tree sc = NULL_TREE;
+         tree fn;
+         if (TREE_CODE (currop->op0) == FUNCTION_DECL)
+           fn = currop->op0;
+         else
+           fn = find_or_generate_expression (block, currop->op0, stmts);
+         if (!fn)
+           return NULL_TREE;
+         if (currop->op1)
+           {
+             sc = find_or_generate_expression (block, currop->op1, stmts);
+             if (!sc)
+               return NULL_TREE;
+           }
+         auto_vec<tree> args (ref->operands.length () - 1);
+         while (operand < ref->operands.length ())
+           {
+             tree arg = create_component_ref_by_pieces_1 (block, ref,
+                                                          &operand, stmts);
+             if (!arg)
+               return NULL_TREE;
+             args.quick_push (arg);
+           }
+         gcall *call
+           = gimple_build_call_vec ((TREE_CODE (fn) == FUNCTION_DECL
+                                     ? build_fold_addr_expr (fn) : fn), args);
+         gimple_call_set_with_bounds (call, currop->with_bounds);
+         if (sc)
+           gimple_call_set_chain (call, sc);
+         tree forcedname = make_ssa_name (currop->type);
+         gimple_call_set_lhs (call, forcedname);
+         gimple_set_vuse (call, BB_LIVE_VOP_ON_EXIT (block));
+         gimple_seq_add_stmt_without_update (&forced_stmts, call);
+         folded = forcedname;
+       }
+      else
+       {
+         folded = create_component_ref_by_pieces (block,
+                                                  PRE_EXPR_REFERENCE (expr),
+                                                  stmts);
+         if (!folded)
+           return NULL_TREE;
+         name = make_temp_ssa_name (exprtype, NULL, "pretmp");
+         newstmt = gimple_build_assign (name, folded);
+         gimple_seq_add_stmt_without_update (&forced_stmts, newstmt);
+         gimple_set_vuse (newstmt, BB_LIVE_VOP_ON_EXIT (block));
+         folded = name;
+       }
       break;
     case NARY:
       {
@@ -2845,22 +2864,26 @@ create_expression_by_pieces (basic_block block, pre_expr expr,
            for (i = 0; i < nary->length; ++i)
              CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE, genop[i]);
            folded = build_constructor (nary->type, elts);
+           name = make_temp_ssa_name (exprtype, NULL, "pretmp");
+           newstmt = gimple_build_assign (name, folded);
+           gimple_seq_add_stmt_without_update (&forced_stmts, newstmt);
+           folded = name;
          }
        else
          {
            switch (nary->length)
              {
              case 1:
-               folded = fold_build1 (nary->opcode, nary->type,
-                                     genop[0]);
+               folded = gimple_build (&forced_stmts, nary->opcode, nary->type,
+                                      genop[0]);
                break;
              case 2:
-               folded = fold_build2 (nary->opcode, nary->type,
-                                     genop[0], genop[1]);
+               folded = gimple_build (&forced_stmts, nary->opcode, nary->type,
+                                      genop[0], genop[1]);
                break;
              case 3:
-               folded = fold_build3 (nary->opcode, nary->type,
-                                     genop[0], genop[1], genop[2]);
+               folded = gimple_build (&forced_stmts, nary->opcode, nary->type,
+                                      genop[0], genop[1], genop[2]);
                break;
              default:
                gcc_unreachable ();
@@ -2872,17 +2895,15 @@ create_expression_by_pieces (basic_block block, pre_expr expr,
       gcc_unreachable ();
     }
 
-  if (!useless_type_conversion_p (exprtype, TREE_TYPE (folded)))
-    folded = fold_convert (exprtype, folded);
+  folded = gimple_convert (&forced_stmts, exprtype, folded);
+
+  /* If everything simplified to an exisiting SSA name or constant just
+     return that.  */
+  if (gimple_seq_empty_p (forced_stmts)
+      || is_gimple_min_invariant (folded))
+    return folded;
 
-  /* Force the generated expression to be a sequence of GIMPLE
-     statements.
-     We have to call unshare_expr because force_gimple_operand may
-     modify the tree we pass to it.  */
-  gimple_seq tem = NULL;
-  folded = force_gimple_operand (unshare_expr (folded), &tem,
-                                false, NULL);
-  gimple_seq_add_seq_without_update (&forced_stmts, tem);
+  gcc_assert (TREE_CODE (folded) == SSA_NAME);
 
   /* If we have any intermediate expressions to the value sets, add them
      to the value sets and chain them in the instruction stream.  */
@@ -2895,9 +2916,8 @@ create_expression_by_pieces (basic_block block, pre_expr expr,
          tree forcedname = gimple_get_lhs (stmt);
          pre_expr nameexpr;
 
-         if (TREE_CODE (forcedname) == SSA_NAME)
+         if (forcedname != folded)
            {
-             bitmap_set_bit (inserted_exprs, SSA_NAME_VERSION (forcedname));
              VN_INFO_GET (forcedname)->valnum = forcedname;
              VN_INFO (forcedname)->value_id = get_next_value_id ();
              nameexpr = get_or_alloc_expr_for_name (forcedname);
@@ -2906,20 +2926,13 @@ create_expression_by_pieces (basic_block block, pre_expr expr,
              bitmap_value_replace_in_set (AVAIL_OUT (block), nameexpr);
            }
 
-         gimple_set_vuse (stmt, BB_LIVE_VOP_ON_EXIT (block));
-         gimple_set_modified (stmt, true);
+         bitmap_set_bit (inserted_exprs, SSA_NAME_VERSION (forcedname));
+         gimple_set_plf (stmt, NECESSARY, false);
        }
       gimple_seq_add_seq (stmts, forced_stmts);
     }
 
-  name = make_temp_ssa_name (exprtype, NULL, "pretmp");
-  newstmt = gimple_build_assign (name, folded);
-  gimple_set_vuse (newstmt, BB_LIVE_VOP_ON_EXIT (block));
-  gimple_set_modified (newstmt, true);
-  gimple_set_plf (newstmt, NECESSARY, false);
-
-  gimple_seq_add_stmt (stmts, newstmt);
-  bitmap_set_bit (inserted_exprs, SSA_NAME_VERSION (name));
+  name = folded;
 
   /* Fold the last statement.  */
   gsi = gsi_last (*stmts);
@@ -2947,7 +2960,7 @@ create_expression_by_pieces (basic_block block, pre_expr expr,
   if (dump_file && (dump_flags & TDF_DETAILS))
     {
       fprintf (dump_file, "Inserted ");
-      print_gimple_stmt (dump_file, newstmt, 0, 0);
+      print_gimple_stmt (dump_file, gsi_stmt (gsi_last (*stmts)), 0, 0);
       fprintf (dump_file, " in predecessor %d (%04d)\n",
               block->index, value_id);
     }
@@ -3004,106 +3017,25 @@ insert_into_preds_of_block (basic_block block, unsigned int exprnum,
       tree builtexpr;
       bprime = pred->src;
       eprime = avail[pred->dest_idx];
-
-      if (eprime->kind != NAME && eprime->kind != CONSTANT)
+      builtexpr = create_expression_by_pieces (bprime, eprime,
+                                              &stmts, type);
+      gcc_assert (!(pred->flags & EDGE_ABNORMAL));
+      if (!gimple_seq_empty_p (stmts))
        {
-         builtexpr = create_expression_by_pieces (bprime, eprime,
-                                                  &stmts, type);
-         gcc_assert (!(pred->flags & EDGE_ABNORMAL));
          gsi_insert_seq_on_edge (pred, stmts);
-         if (!builtexpr)
-           {
-             /* We cannot insert a PHI node if we failed to insert
-                on one edge.  */
-             nophi = true;
-             continue;
-           }
-         avail[pred->dest_idx] = get_or_alloc_expr_for_name (builtexpr);
          insertions = true;
        }
-      else if (eprime->kind == CONSTANT)
-       {
-         /* Constants may not have the right type, fold_convert
-            should give us back a constant with the right type.  */
-         tree constant = PRE_EXPR_CONSTANT (eprime);
-         if (!useless_type_conversion_p (type, TREE_TYPE (constant)))
-           {
-             tree builtexpr = fold_convert (type, constant);
-             if (!is_gimple_min_invariant (builtexpr))
-               {
-                 tree forcedexpr = force_gimple_operand (builtexpr,
-                                                         &stmts, true,
-                                                         NULL);
-                 if (!is_gimple_min_invariant (forcedexpr))
-                   {
-                     if (forcedexpr != builtexpr)
-                       {
-                         VN_INFO_GET (forcedexpr)->valnum = PRE_EXPR_CONSTANT (eprime);
-                         VN_INFO (forcedexpr)->value_id = get_expr_value_id (eprime);
-                       }
-                     if (stmts)
-                       {
-                         gimple_stmt_iterator gsi;
-                         gsi = gsi_start (stmts);
-                         for (; !gsi_end_p (gsi); gsi_next (&gsi))
-                           {
-                             gimple *stmt = gsi_stmt (gsi);
-                             tree lhs = gimple_get_lhs (stmt);
-                             if (TREE_CODE (lhs) == SSA_NAME)
-                               bitmap_set_bit (inserted_exprs,
-                                               SSA_NAME_VERSION (lhs));
-                             gimple_set_plf (stmt, NECESSARY, false);
-                           }
-                         gsi_insert_seq_on_edge (pred, stmts);
-                       }
-                     avail[pred->dest_idx]
-                       = get_or_alloc_expr_for_name (forcedexpr);
-                   }
-               }
-             else
-               avail[pred->dest_idx]
-                   = get_or_alloc_expr_for_constant (builtexpr);
-           }
-       }
-      else if (eprime->kind == NAME)
+      if (!builtexpr)
        {
-         /* We may have to do a conversion because our value
-            numbering can look through types in certain cases, but
-            our IL requires all operands of a phi node have the same
-            type.  */
-         tree name = PRE_EXPR_NAME (eprime);
-         if (!useless_type_conversion_p (type, TREE_TYPE (name)))
-           {
-             tree builtexpr;
-             tree forcedexpr;
-             builtexpr = fold_convert (type, name);
-             forcedexpr = force_gimple_operand (builtexpr,
-                                                &stmts, true,
-                                                NULL);
-
-             if (forcedexpr != name)
-               {
-                 VN_INFO_GET (forcedexpr)->valnum = VN_INFO (name)->valnum;
-                 VN_INFO (forcedexpr)->value_id = VN_INFO (name)->value_id;
-               }
-
-             if (stmts)
-               {
-                 gimple_stmt_iterator gsi;
-                 gsi = gsi_start (stmts);
-                 for (; !gsi_end_p (gsi); gsi_next (&gsi))
-                   {
-                     gimple *stmt = gsi_stmt (gsi);
-                     tree lhs = gimple_get_lhs (stmt);
-                     if (TREE_CODE (lhs) == SSA_NAME)
-                       bitmap_set_bit (inserted_exprs, SSA_NAME_VERSION (lhs));
-                     gimple_set_plf (stmt, NECESSARY, false);
-                   }
-                 gsi_insert_seq_on_edge (pred, stmts);
-               }
-             avail[pred->dest_idx] = get_or_alloc_expr_for_name (forcedexpr);
-           }
+         /* We cannot insert a PHI node if we failed to insert
+            on one edge.  */
+         nophi = true;
+         continue;
        }
+      if (is_gimple_min_invariant (builtexpr))
+       avail[pred->dest_idx] = get_or_alloc_expr_for_constant (builtexpr);
+      else
+       avail[pred->dest_idx] = get_or_alloc_expr_for_name (builtexpr);
     }
   /* If we didn't want a phi node, and we made insertions, we still have
      inserted new stuff, and thus return true.  If we didn't want a phi node,
@@ -3267,6 +3199,7 @@ do_regular_insertion (basic_block block, basic_block dom)
                 and so not come across fake pred edges.  */
              gcc_assert (!(pred->flags & EDGE_FAKE));
              bprime = pred->src;
+             /* We are looking at ANTIC_OUT of bprime.  */
              eprime = phi_translate (expr, ANTIC_IN (block), NULL,
                                      bprime, block);