tree-ssa-reassoc.c (reassociate_expr): Allow scaler floating point types when flag_un...
[platform/upstream/gcc.git] / gcc / tree-ssa-structalias.c
index cb45a8c..2a10a8d 100644 (file)
@@ -897,6 +897,7 @@ merge_graph_nodes (constraint_graph_t graph, unsigned int to,
       add_graph_edge (graph, newe);
       olde.src = from;
       olde.dest = c->dest;
+      olde.weights = NULL;
       temp = get_graph_weights (graph, olde);
       weights = get_graph_weights (graph, newe);
       bitmap_ior_into (weights, temp);
@@ -917,6 +918,7 @@ merge_graph_nodes (constraint_graph_t graph, unsigned int to,
       add_graph_edge (graph, newe);
       olde.src = c->dest;
       olde.dest = from;
+      olde.weights = NULL;
       temp = get_graph_weights (graph, olde);
       weights = get_graph_weights (graph, newe);
       bitmap_ior_into (weights, temp);
@@ -942,6 +944,7 @@ int_add_graph_edge (constraint_graph_t graph, unsigned int to,
       struct constraint_edge edge;
       edge.src = to;
       edge.dest = from;
+      edge.weights = NULL;
       r = add_graph_edge (graph, edge);
       r |= !bitmap_bit_p (get_graph_weights (graph, edge), weight);
       bitmap_set_bit (get_graph_weights (graph, edge), weight);
@@ -1113,6 +1116,7 @@ collapse_nodes (constraint_graph_t graph, unsigned int to, unsigned int from)
   merge_graph_nodes (graph, to, from);
   edge.src = to;
   edge.dest = to;
+  edge.weights = NULL;
   if (valid_graph_edge (graph, edge))
     {
       bitmap weights = get_graph_weights (graph, edge);
@@ -1216,6 +1220,7 @@ process_unification_queue (constraint_graph_t graph, struct scc_info *si,
          bitmap_clear (tmp);
          edge.src = n;
          edge.dest = n;
+         edge.weights = NULL;
          if (valid_graph_edge (graph, edge))
            {
              bitmap weights = get_graph_weights (graph, edge);
@@ -2550,7 +2555,7 @@ update_alias_info (tree stmt, struct alias_info *ai)
       tree op, var;
       var_ann_t v_ann;
       struct ptr_info_def *pi;
-      bool is_store;
+      bool is_store, is_potential_deref;
       unsigned num_uses, num_derefs;
 
       op = USE_FROM_PTR (use_p);
@@ -2607,7 +2612,42 @@ update_alias_info (tree stmt, struct alias_info *ai)
         is an escape point, whether OP escapes.  */
       count_uses_and_derefs (op, stmt, &num_uses, &num_derefs, &is_store);
 
-      if (num_derefs > 0)
+      /* Handle a corner case involving address expressions of the
+        form '&PTR->FLD'.  The problem with these expressions is that
+        they do not represent a dereference of PTR.  However, if some
+        other transformation propagates them into an INDIRECT_REF
+        expression, we end up with '*(&PTR->FLD)' which is folded
+        into 'PTR->FLD'.
+
+        So, if the original code had no other dereferences of PTR,
+        the aliaser will not create memory tags for it, and when
+        &PTR->FLD gets propagated to INDIRECT_REF expressions, the
+        memory operations will receive no V_MAY_DEF/VUSE operands.
+
+        One solution would be to have count_uses_and_derefs consider
+        &PTR->FLD a dereference of PTR.  But that is wrong, since it
+        is not really a dereference but an offset calculation.
+
+        What we do here is to recognize these special ADDR_EXPR
+        nodes.  Since these expressions are never GIMPLE values (they
+        are not GIMPLE invariants), they can only appear on the RHS
+        of an assignment and their base address is always an
+        INDIRECT_REF expression.  */
+      is_potential_deref = false;
+      if (TREE_CODE (stmt) == MODIFY_EXPR
+         && TREE_CODE (TREE_OPERAND (stmt, 1)) == ADDR_EXPR
+         && !is_gimple_val (TREE_OPERAND (stmt, 1)))
+       {
+         /* If the RHS if of the form &PTR->FLD and PTR == OP, then
+            this represents a potential dereference of PTR.  */
+         tree rhs = TREE_OPERAND (stmt, 1);
+         tree base = get_base_address (TREE_OPERAND (rhs, 0));
+         if (TREE_CODE (base) == INDIRECT_REF
+             && TREE_OPERAND (base, 0) == op)
+           is_potential_deref = true;
+       }
+
+      if (num_derefs > 0 || is_potential_deref)
        {
          /* Mark OP as dereferenced.  In a subsequent pass,
             dereferenced pointers that point to a set of
@@ -3494,7 +3534,8 @@ init_base_vars (void)
 /* Return true if we actually need to solve the constraint graph in order to
    get our points-to sets.  This is false when, for example, no addresses are
    taken other than special vars, or all points-to sets with members already
-   contain the anything variable.  */
+   contain the anything variable and there are no predecessors for other
+   sets.  */
 
 static bool
 need_to_solve (void)
@@ -3516,6 +3557,9 @@ need_to_solve (void)
          && !bitmap_empty_p (v->solution) 
          && !bitmap_bit_p (v->solution, anything_id))
        found_non_anything = true;
+      else if (bitmap_empty_p (v->solution)
+              && VEC_length (constraint_edge_t, graph->preds[v->id]) != 0)
+       found_non_anything = true;
 
       if (found_address_taken && found_non_anything)
        return true;