This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Repair CONTAINS_PLACEHOLDER_P
- From: Eric Botcazou <ebotcazou at adacore dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Mark Mitchell <mark at codesourcery dot com>
- Date: Sun, 11 Sep 2005 23:19:08 +0200
- Subject: Repair CONTAINS_PLACEHOLDER_P
Hi,
The following testcase ICEs in the gimplifier with GCC 4.x:
procedure p is
type S is (E1, E2);
for S use (E1=>1, E2=>2);
type A is array (S range <>) of Natural;
type R(D : S) is
record
C : A (E1..D);
end record;
begin
null;
end;
The CONTAINS_PLACEHOLDER_P predicate returns false for any CALL_EXPR tree with
GCC 4.x. The story is as follows: contains_placeholder_p in 3.4 reads
case '1':
case '2': case '<':
case 'e':
switch (code)
{
case COMPOUND_EXPR:
/* Ignoring the first operand isn't quite right, but works best. */
return CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 1));
case RTL_EXPR:
case CONSTRUCTOR:
return 0;
case COND_EXPR:
return (CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 0))
|| CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 1))
|| CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 2)));
case SAVE_EXPR:
/* If we already know this doesn't have a placeholder, don't
check again. */
if (SAVE_EXPR_NOPLACEHOLDER (exp) || SAVE_EXPR_RTL (exp) != 0)
return 0;
SAVE_EXPR_NOPLACEHOLDER (exp) = 1;
result = CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 0));
if (result)
SAVE_EXPR_NOPLACEHOLDER (exp) = 0;
return result;
case CALL_EXPR:
return CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 1));
default:
break;
}
switch (TREE_CODE_LENGTH (code))
{
case 1:
return CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 0));
case 2:
return (CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 0))
|| CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 1)));
default:
return 0;
}
Richard removed the CALL_EXPR case as part of:
2004-03-21 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
* alias.c (get_alias_set): Remove handling of PLACEHOLDER_EXPR.
* emit-rtl.c (component_ref_for_mem_expr): Likewise.
(set_mem_attributes_minus_bitpos): Call SUBSTITUTE_PLACEHOLDER_IN_EXPR.
* explow.c (expr_size): Likewise.
* expr.h (placeholder_list, find_placeholder): Deleted.
* expr.c (store_constructor): Likewise.
(get_inner_reference): Likewise. Also don't call find_placeholder.
(placeholder_list, find_placeholder): Deleted.
(is_aligning_offset): Don't handle WITH_RECORD_EXPR, PLACEHOLDER_EXPR.
(expand_expr_real, cases PLACEHOLDER_EXPR, WITH_RECORD_EXPR): Likewise.
(highest_pow2_factor, case WITH_RECORD_EXPR): Remove.
* dojump.c (do_jump, case WITH_RECORD_EXPR): Likewise.
* dwarf2out.c (loc_descriptor_from_tree, case WITH_RECORD_EXPR):
Likewise.
* fold-const.c (invert_truthvalue, case WITH_RECORD_EXPR): Likewise.
(extract_muldiv, case WITH_RECORD_EXPR): Likewise.
* tree.c (expr_align, case WITH_RECORD_EXPR): Likewise.
(contains_placeholder_p): Don't handle WITH_RECORD_EXPR.
Clean up by using first_rtl_op.
(substitute_in_expr): Use SUBSTITUTE_IN_EXPR for recursive call.
(substitute_placeholder_in_expr): New function.
* tree.def (WITH_RECORD_EXPR): Deleted.
* tree.h (SUBSTITUTE_IN_EXPR, SUBSTITUTE_PLACEHOLDER_IN_EXPR): New.
(substitute_placeholder_in_expr): New.
because it was partially redundant with the subsequent "2" case.
Then the big Tree-SSA merge occured 2 months later and the TREE_CODE_LENGTH of
CALL_EXPR was bumped to 3. The patch restores the 3.4 behavior and has been
bootstrapped/regtested on x86_64-suse-linux. Applied to mainline as obvious.
Mark, may I apply it to the 4.0 branch as well?
2005-09-11 Eric Botcazou <ebotcazou@adacore.com>
* tree.c (contains_placeholder_p) <tcc_expression>: Properly
handle CALL_EXPR again.
--
Eric Botcazou
Index: tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.c,v
retrieving revision 1.502
diff -u -p -r1.502 tree.c
--- ../tree.c 7 Sep 2005 12:39:03 -0000 1.502
+++ ../tree.c 11 Sep 2005 09:56:21 -0000
@@ -2058,6 +2058,9 @@ contains_placeholder_p (tree exp)
|| CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 1))
|| CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 2)));
+ case CALL_EXPR:
+ return CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 1));
+
default:
break;
}