===================================================================
@@ -751,10 +751,11 @@ copy_gimple_bind (gimple stmt, copy_body
return new_bind;
}
-/* Return true if DECL is a parameter or a SSA_NAME for a parameter. */
+/* Return true if DECL is a parameter with reference type or a SSA_NAME
+ for a parameter with reference type. */
static bool
-is_parm (tree decl)
+is_ref_parm (tree decl)
{
if (TREE_CODE (decl) == SSA_NAME)
{
@@ -763,7 +764,40 @@ is_parm (tree decl)
return false;
}
- return (TREE_CODE (decl) == PARM_DECL);
+ return (TREE_CODE (decl) == PARM_DECL
+ && TREE_CODE (TREE_TYPE (decl)) == REFERENCE_TYPE);
+}
+
+/* Return true if DECL is based on a parameter with reference type or a
+ SSA_NAME for a parameter with with reference type. */
+
+static bool
+is_based_on_ref_parm (tree decl)
+{
+ HOST_WIDE_INT offset;
+ tree obj, expr;
+ gimple def_stmt;
+
+ /* First the easy case. */
+ if (is_ref_parm (decl))
+ return true;
+
+ /* Then look for an SSA name whose defining statement is of the form:
+
+ D.1718_7 = &parm_2(D)->f1;
+
+ where parm_2 is a parameter with reference type. */
+ if (TREE_CODE (decl) != SSA_NAME)
+ return false;
+ def_stmt = SSA_NAME_DEF_STMT (decl);
+ if (!def_stmt)
+ return false;
+
+ expr = get_ancestor_addr_info (def_stmt, &obj, &offset);
+ if (!expr)
+ return false;
+
+ return is_ref_parm (TREE_OPERAND (expr, 0));
}
/* Remap the GIMPLE operand pointed to by *TP. DATA is really a
@@ -865,12 +899,13 @@ remap_gimple_op_r (tree *tp, int *walk_s
TREE_THIS_VOLATILE (*tp) = TREE_THIS_VOLATILE (old);
TREE_SIDE_EFFECTS (*tp) = TREE_SIDE_EFFECTS (old);
TREE_NO_WARNING (*tp) = TREE_NO_WARNING (old);
- /* We cannot propagate the TREE_THIS_NOTRAP flag if we have
- remapped a parameter as the property might be valid only
- for the parameter itself. */
+ /* We cannot always propagate the TREE_THIS_NOTRAP flag if we have
+ remapped a parameter with reference type as the property may be
+ valid only for the parameter. */
if (TREE_THIS_NOTRAP (old)
- && (!is_parm (TREE_OPERAND (old, 0))
- || (!id->transform_parameter && is_parm (ptr))))
+ && (!is_ref_parm (TREE_OPERAND (old, 0))
+ || !id->transform_parameter
+ || is_based_on_ref_parm (ptr)))
TREE_THIS_NOTRAP (*tp) = 1;
*walk_subtrees = 0;
return NULL;
@@ -1092,12 +1127,13 @@ copy_tree_body_r (tree *tp, int *walk_su
TREE_THIS_VOLATILE (*tp) = TREE_THIS_VOLATILE (old);
TREE_SIDE_EFFECTS (*tp) = TREE_SIDE_EFFECTS (old);
TREE_READONLY (*tp) = TREE_READONLY (old);
- /* We cannot propagate the TREE_THIS_NOTRAP flag if we
- have remapped a parameter as the property might be
- valid only for the parameter itself. */
+ /* We cannot always propagate the TREE_THIS_NOTRAP flag
+ if we have remapped a parameter with reference type as
+ the property may be valid only for the parameter. */
if (TREE_THIS_NOTRAP (old)
- && (!is_parm (TREE_OPERAND (old, 0))
- || (!id->transform_parameter && is_parm (ptr))))
+ && (!is_ref_parm (TREE_OPERAND (old, 0))
+ || !id->transform_parameter
+ || is_based_on_ref_parm (ptr)))
TREE_THIS_NOTRAP (*tp) = 1;
}
}
@@ -1118,12 +1154,13 @@ copy_tree_body_r (tree *tp, int *walk_su
TREE_THIS_VOLATILE (*tp) = TREE_THIS_VOLATILE (old);
TREE_SIDE_EFFECTS (*tp) = TREE_SIDE_EFFECTS (old);
TREE_NO_WARNING (*tp) = TREE_NO_WARNING (old);
- /* We cannot propagate the TREE_THIS_NOTRAP flag if we have
- remapped a parameter as the property might be valid only
- for the parameter itself. */
+ /* We cannot always propagate the TREE_THIS_NOTRAP flag if we have
+ remapped a parameter with reference type as the property may be
+ valid only for the parameter. */
if (TREE_THIS_NOTRAP (old)
- && (!is_parm (TREE_OPERAND (old, 0))
- || (!id->transform_parameter && is_parm (ptr))))
+ && (!is_ref_parm (TREE_OPERAND (old, 0))
+ || !id->transform_parameter
+ || is_based_on_ref_parm (ptr)))
TREE_THIS_NOTRAP (*tp) = 1;
*walk_subtrees = 0;
return NULL;
===================================================================
@@ -693,6 +693,7 @@ tree ipa_value_from_jfunc (struct ipa_no
unsigned int ipcp_transform_function (struct cgraph_node *node);
void ipa_dump_param (FILE *, struct ipa_node_params *info, int i);
+tree get_ancestor_addr_info (gimple, tree *, HOST_WIDE_INT *);
/* From tree-sra.c: */
tree build_ref_for_offset (location_t, tree, HOST_WIDE_INT, tree,
===================================================================
@@ -1078,7 +1078,7 @@ compute_complex_assign_jump_func (struct
handled components and the MEM_REF itself is stored into *OFFSET. The whole
RHS stripped off the ADDR_EXPR is stored into *OBJ_P. */
-static tree
+tree
get_ancestor_addr_info (gimple assign, tree *obj_p, HOST_WIDE_INT *offset)
{
HOST_WIDE_INT size, max_size;