This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[lto] PATCH: new CALL_EXPR constructors
- From: Sandra Loosemore <sandra at codesourcery dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Sat, 05 Aug 2006 12:37:08 -0400
- Subject: [lto] PATCH: new CALL_EXPR constructors
This is my last set of patches in preparation for changing the low-level
representation of CALL_EXPRs to push the arguments into the expr node itself
instead of pointing to a TREE_LIST. Here, I've "broken" build3 and fold_build3
as constructors for tcc_vl_exp objects, introduced a new set of low-level
constructors for CALL_EXPR-like objects, and propagated the changes around. I
also fixed up a few more places that weren't yet using the new abstract
interface for CALL_EXPRs.
Any comments or complaints before I commit this?
I'm planning to actually hack the representation next, and see what breaks. :-P
-Sandra
2006-08-04 Sandra Loosemore <sandra@codesourcery.com>
* gcc/tree.c (substitute_in_expr, substitute_placeholder_in_expr):
Simplify implementation of tcc_vl_exp case.
(build3_stat, build_nt): Don't allow these to be used for
building CALL_EXPRs and other tcc_vl_exps.
(build_nt_call_list): New function, equivalent to build_nt for
tcc_vl_exps.
(process_call_operands): New function used as a helper by other
new constructors for tcc_vl_exps.
(build_call_list): New constructor for tcc_vl_exps.
(build_call_nary): Likewise.
(build_call_valist): Likewise.
(build_call_array): Likewise.
* gcc/tree.h (build_nt_call_list): Declare new function.
(build_call_list): Likewise.
(build_call_nary): Likewise.
(build_call_valist): Likewise.
(build_call_array): Likewise.
(fold_build_call_list): Likewise.
(fold_build_call_list_initializer): Likewise.
(fold_build_call_expr): Deleted, and replaced with...
(fold_builtin_call_list, fold_builtin_call_valist): Declare.
* gcc/builtins.c (fold_builtin_call_list): Replacement for
fold_build_call_expr. Renamed for consistency with other new
CALL_EXPR constructors, and removed the static_chain argument since
it is never used. Fixed all callers.
(build_call_expr): Split up and move much of the code into...
(fold_builtin_call_valist): New function.
* gcc/fold-const.c (fold): Add clause for tcc_vl_exp specially.
Remove CALL_EXPR handling from ternary operator case.
(fold_build3_stat): Don't allow this to build tcc_vl_exps.
(fold_build_call_list): New function replacing uses of fold_build3
to build CALL_EXPRs.
(fold_build_call_list_initializer): Likewise, replacing uses of
fold_build3_initializer.
* gcc/c-typeck.c (build_function_call): Use fold_build_call_list
and fold_build_call_list_initializer.
* gcc/calls.c (expand_call): Use new CALL_EXPR accessors.
* gcc/tree-ssa-pre.c (expression_node_pool): Delete, since alloc_pool
can't be used to manage pools of variably-sized objects.
(temp_call_expr_chain): Declare.
(temp_copy_call_expr, free_temp_call_expr_chain): New routines for
managing temporary tcc_vl_expr objects created in this pass.
(phi_translate): Rewrite the CALL_EXPR section to be independent
of the storage representation. Use temp_copy_call_expr. Don't
value number the arglist.
(valid_in_set): Clean up CALL_EXPR section a little.
(create_expression_by_pieces): Likewise.
(create_value_expr_from): Use temp_copy_call_expr. Don't value
number the arglist.
(init_pre): Update initialization of temp memory for CALL_EXPRs.
(fini_pre): Update deallocation of temp memory for CALL_EXPRs.
* gcc/java/parse.y (patch_invoke): Use build_call_list/build_call_nary
instead of build3.
(build_method_invocation): Likewise.
(build_new_invocation): Likewise.
(patch_cast): Likewise.
(patch_newarray): Likewise.
(build_assertion): Likewise.
* gcc/java/expr.c (build_java_athrow): Likewise.
(build_java_throw_out_of_bounds_exception): Likewise.
(java_check_reference): Likewise.
(build_java_arraystore_check): Likewise.
(build_anewarray): Likewise.
(expand_java_multinewarray): Likewise.
(build_java_monitor): Likewise.
(java_create_object): Likewise.
(expand_java_NEW): Likewise.
(build_instanceof): Likewise.
(expand_java_CHECKCAST): Likewise.
(build_java_soft_divmod): Likewise.
(build_java_binop): Likewise.
(build_field_ref): Likewise.
(build_class_init): Likewise.
(build_invokeinterface): Likewise.
(expand_invoke): Likewise.
(build_jni_stub): Likewise.
(force_evaluation_order): Use new CALL_EXPR accessors.
* gcc/java/parse.h (BUILD_THROW): Use build_call_nary.
* gcc/java/java-tree.h (BUILD_MONITOR_ENTER, BUILD_MONITOR_EXIT):
Likewise.
* gcc/java/jcf-write.c (generate_bytecode_insns): Use new CALL_EXPR
accessors.
* gcc/cp/call.c (build_call): Use build_call_list instead of build3.
(build_over_call): Likewise.
(build_java_interface_fn_ref): Likewise.
(build_new_method_call): Use build_min_non_dep_call_list.
* gcc/cp/tree.c (build_cplus_new): Use build_call_list.
(build_min_nt, build_min): Can't use these for building tcc_vl_exps.
(build_min_nt_call_list): New function, equivalent to build_min_nt.
(build_min_non_dep_call_list): New function, equivalent to
build_min_non_dep.
* gcc/cp/tree.h (AGGR_INIT_EXPR_SLOT): New.
(build_min_nt_call_list, build_min_non_dep_call_list): Declare.
* gcc/cp/dump.c (cp_dump_tree): Use new AGGR_INIT_EXPR accessors.
* gcc/cp/cp-gimplify.c (cp_gimplify_init_expr): Likewise.
* gcc/cp/cxx-pretty-print.c (pp_cxx_postfix_expression): Likewise.
* gcc/cp/pt.c (tsubst_copy): Use build_nt_call_list.
* gcc/cp/semantics.c (finish_call_expr): Use build_nt_call_list
and build_call_list.
(simplify_aggr_init_expr): Use new AGGR_INIT_EXPR accessors. Use
build_call_list.
* gcc/cp/decl2.c (build_offset_ref_call_from_tree): Use
build_min_nt_call_list and build_in_non_dep_call_list.
* gcc/cp/parser.c (cp_parser_postfix_expression): Use
build_min_nt_call_list.
* gcc/fortran/trans-expr.c (gfc_conv_function_call): Use
build_call_list.
Index: gcc/tree.c
===================================================================
*** gcc/tree.c (revision 115887)
--- gcc/tree.c (working copy)
*************** tree_code_size (enum tree_code code)
*** 355,361 ****
case tcc_comparison: /* a comparison expression */
case tcc_unary: /* a unary arithmetic expression */
case tcc_binary: /* a binary arithmetic expression */
! case tcc_vl_exp: /* FIXME: a function call expression */
return (sizeof (struct tree_exp)
+ (TREE_CODE_LENGTH (code) - 1) * sizeof (tree));
--- 355,361 ----
case tcc_comparison: /* a comparison expression */
case tcc_unary: /* a unary arithmetic expression */
case tcc_binary: /* a binary arithmetic expression */
! case tcc_vl_exp: /* FIXME: a function call expression */
return (sizeof (struct tree_exp)
+ (TREE_CODE_LENGTH (code) - 1) * sizeof (tree));
*************** substitute_in_expr (tree exp, tree f, tr
*** 2448,2478 ****
case tcc_vl_exp:
{
- /* FIXME: use new CALL_EXPR constructor */
- tree fn = SUBSTITUTE_IN_EXPR (CALL_EXPR_FN (exp), f, r);
- tree sc = SUBSTITUTE_IN_EXPR (CALL_EXPR_STATIC_CHAIN (exp), f, r);
tree copy = NULL_TREE;
! int i = 0;
! call_expr_arg_iterator iter;
! tree arg;
!
! FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
{
! tree newarg = SUBSTITUTE_IN_EXPR (arg, f, r);
! if (newarg != arg)
{
! if (!copy)
! copy = build3 (code, TREE_TYPE (exp), fn, sc,
! copy_list (CALL_EXPR_ARGS (exp)));
! CALL_EXPR_ARG (copy, i) = newarg;
}
}
if (copy)
new = fold (copy);
- else if (fn != CALL_EXPR_FN (exp)
- || sc != CALL_EXPR_STATIC_CHAIN (exp))
- new = fold_build3 (code, TREE_TYPE (exp), fn, sc,
- CALL_EXPR_ARGS (exp));
else
return exp;
}
--- 2448,2468 ----
case tcc_vl_exp:
{
tree copy = NULL_TREE;
! int i;
! int n = TREE_OPERAND_LENGTH (exp);
! for (i = 0; i < n; i++)
{
! tree op = TREE_OPERAND (exp, i);
! tree newop = SUBSTITUTE_IN_EXPR (op, f, r);
! if (newop != op)
{
! copy = copy_node (exp);
! TREE_OPERAND (copy, i) = newop;
}
}
if (copy)
new = fold (copy);
else
return exp;
}
*************** substitute_placeholder_in_expr (tree exp
*** 2611,2642 ****
case tcc_vl_exp:
{
- /* FIXME: use new CALL_EXPR constructor */
- tree fn = SUBSTITUTE_PLACEHOLDER_IN_EXPR (CALL_EXPR_FN (exp), obj);
- tree sc = SUBSTITUTE_PLACEHOLDER_IN_EXPR (CALL_EXPR_STATIC_CHAIN (exp),
- obj);
tree copy = NULL_TREE;
! int i = 0;
! call_expr_arg_iterator iter;
! tree arg;
!
! FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
{
! tree newarg = SUBSTITUTE_PLACEHOLDER_IN_EXPR (arg, obj);
! if (newarg != arg)
{
! if (!copy)
! copy = build3 (code, TREE_TYPE (exp), fn, sc,
! copy_list (CALL_EXPR_ARGS (exp)));
! CALL_EXPR_ARG (copy, i) = newarg;
}
}
if (copy)
return fold (copy);
- else if (fn != CALL_EXPR_FN (exp)
- || sc != CALL_EXPR_STATIC_CHAIN (exp))
- return fold_build3 (code, TREE_TYPE (exp), fn, sc,
- CALL_EXPR_ARGS (exp));
else
return exp;
}
--- 2601,2621 ----
case tcc_vl_exp:
{
tree copy = NULL_TREE;
! int i;
! int n = TREE_OPERAND_LENGTH (exp);
! for (i = 0; i < n; i++)
{
! tree op = TREE_OPERAND (exp, i);
! tree newop = SUBSTITUTE_PLACEHOLDER_IN_EXPR (op, obj);
! if (newop != op)
{
! copy = copy_node (exp);
! TREE_OPERAND (copy, i) = newop;
}
}
if (copy)
return fold (copy);
else
return exp;
}
*************** build3_stat (enum tree_code code, tree t
*** 3078,3083 ****
--- 3057,3063 ----
tree t;
gcc_assert (TREE_CODE_LENGTH (code) == 3);
+ gcc_assert (TREE_CODE_CLASS (code) != tcc_vl_exp);
t = make_node_stat (code PASS_MEM_STAT);
TREE_TYPE (t) = tt;
*************** build3_stat (enum tree_code code, tree t
*** 3088,3113 ****
PROCESS_ARG(1);
PROCESS_ARG(2);
- if (code == CALL_EXPR && !side_effects)
- {
- tree node;
- int i;
-
- /* Calls have side-effects, except those to const or
- pure functions. */
- i = call_expr_flags (t);
- if (!(i & (ECF_CONST | ECF_PURE)))
- side_effects = 1;
-
- /* And even those have side-effects if their arguments do. */
- else for (node = arg1; node; node = TREE_CHAIN (node))
- if (TREE_SIDE_EFFECTS (TREE_VALUE (node)))
- {
- side_effects = 1;
- break;
- }
- }
-
TREE_SIDE_EFFECTS (t) = side_effects;
TREE_THIS_VOLATILE (t)
= (TREE_CODE_CLASS (code) == tcc_reference
--- 3068,3073 ----
*************** build_nt (enum tree_code code, ...)
*** 3213,3218 ****
--- 3173,3180 ----
int i;
va_list p;
+ gcc_assert (TREE_CODE_CLASS (code) != tcc_vl_exp);
+
va_start (p, code);
t = make_node (code);
*************** build_nt (enum tree_code code, ...)
*** 3224,3229 ****
--- 3186,3208 ----
va_end (p);
return t;
}
+
+ /* Similar to build_nt, but for creating a CALL_EXPR-like object with
+ ARGLIST passed as a list. */
+
+ tree
+ build_nt_call_list (enum tree_code code, tree fn, tree arglist)
+ {
+ tree t;
+ gcc_assert (TREE_CODE_CLASS (code) == tcc_vl_exp);
+
+ /* FIXME: change this to use the new CALL_EXPR representation. */
+ t = make_node (code);
+ CALL_EXPR_FN (t) = fn;
+ CALL_EXPR_STATIC_CHAIN (t) = NULL_TREE;
+ CALL_EXPR_ARGS (t) = arglist;
+ return t;
+ }
/* Create a DECL_... node of code CODE, name NAME and data type TYPE.
We do NOT enter this node in any sort of symbol table.
*************** build_omp_clause (enum omp_clause_code c
*** 7001,7006 ****
--- 6980,7105 ----
return t;
}
+ /* Set various status flags when building a tcc_vl_exp object T. */
+
+ static void
+ process_call_operands (tree t)
+ {
+ bool side_effects;
+
+ side_effects = TREE_SIDE_EFFECTS (t);
+ if (!side_effects)
+ {
+ int i, n;
+ n = TREE_OPERAND_LENGTH (t);
+ for (i = 0; i < n; i++)
+ {
+ tree op = TREE_OPERAND (t, i);
+ if (op && TREE_SIDE_EFFECTS (op))
+ {
+ side_effects = 1;
+ break;
+ }
+ }
+ }
+ if (TREE_CODE (t) == CALL_EXPR && !side_effects)
+ {
+ int i;
+
+ /* Calls have side-effects, except those to const or
+ pure functions. */
+ i = call_expr_flags (t);
+ if (!(i & (ECF_CONST | ECF_PURE)))
+ side_effects = 1;
+
+ /* FIXME: This goes away after representation change is complete. */
+ /* And even those have side-effects if their arguments do. */
+ else
+ {
+ tree node;
+ call_expr_arg_iterator iter;
+ FOR_EACH_CALL_EXPR_ARG (node, iter, t)
+ if (TREE_SIDE_EFFECTS (node))
+ {
+ side_effects = 1;
+ break;
+ }
+ }
+ }
+ TREE_SIDE_EFFECTS (t) = side_effects;
+ }
+
+ /* Build a CALL_EXPR-like thing of class tcc_vl_exp with code CODE and the
+ indicated RETURN_TYPE and FN and a null static chain slot.
+ ARGLIST is a TREE_LIST of the arguments. */
+
+ tree
+ build_call_list (enum tree_code code, tree return_type, tree fn,
+ tree arglist)
+ {
+ tree t;
+ gcc_assert (TREE_CODE_CLASS (code) == tcc_vl_exp);
+
+ /* FIXME: change this to use the new CALL_EXPR representation. */
+ t = make_node (code);
+ TREE_TYPE (t) = return_type;
+ CALL_EXPR_FN (t) = fn;
+ CALL_EXPR_STATIC_CHAIN (t) = NULL_TREE;
+ CALL_EXPR_ARGS (t) = arglist;
+ process_call_operands (t);
+ return t;
+ }
+
+ /* Build a CALL_EXPR-like thing of class tcc_vl_exp with code CODE and the
+ indicated RETURN_TYPE and FN and a null static chain slot.
+ NARGS is the number of call arguments which are specified as "..."
+ arguments. */
+
+ tree
+ build_call_nary (enum tree_code code, tree return_type, tree fn,
+ int nargs, ...)
+ {
+ tree ret;
+ va_list args;
+ va_start (args, nargs);
+ ret = build_call_valist (code, return_type, fn, nargs, args);
+ va_end (args);
+ return ret;
+ }
+
+ /* Build a CALL_EXPR-like thing of class tcc_vl_exp with code CODE and the
+ indicated RETURN_TYPE and FN and a null static chain slot.
+ NARGS is the number of call arguments which are specified as a
+ va_list ARGS. */
+
+ tree
+ build_call_valist (enum tree_code code, tree return_type, tree fn,
+ int nargs, va_list args)
+ {
+ /* FIXME: change this to use the new CALL_EXPR representation. */
+ tree arglist = NULL_TREE;
+ int i;
+ for (i = 0; i < nargs; i++)
+ arglist = tree_cons (NULL_TREE, va_arg (args, tree), arglist);
+ return build_call_list (code, return_type, fn, nreverse (arglist));
+ }
+
+ /* Build a CALL_EXPR-like thing of class tcc_vl_exp with code CODE and the
+ indicated RETURN_TYPE and FN and a null static chain slot.
+ NARGS is the number of call arguments which are specified as a tree
+ array ARGS. */
+
+ tree
+ build_call_array (enum tree_code code, tree return_type, tree fn,
+ int nargs, tree *args)
+ {
+ /* FIXME: change this to use the new CALL_EXPR representation. */
+ tree arglist = NULL_TREE;
+ int i;
+ for (i = 0; i < nargs; i++)
+ arglist = tree_cons (NULL_TREE, args[i], arglist);
+ return build_call_list (code, return_type, fn, nreverse (arglist));
+ }
/* Returns true if it is possible to prove that the index of
an array access REF (an ARRAY_REF expression) falls into the
Index: gcc/tree.h
===================================================================
*** gcc/tree.h (revision 115887)
--- gcc/tree.h (working copy)
*************** extern tree maybe_get_identifier (const
*** 3530,3535 ****
--- 3530,3536 ----
/* Construct various types of nodes. */
extern tree build_nt (enum tree_code, ...);
+ extern tree build_nt_call_list (enum tree_code, tree, tree);
extern tree build0_stat (enum tree_code, tree MEM_STAT_DECL);
#define build0(c,t) build0_stat (c,t MEM_STAT_INFO)
*************** extern void annotate_with_locus (tree, l
*** 3575,3580 ****
--- 3576,3586 ----
extern tree build_empty_stmt (void);
extern tree build_omp_clause (enum omp_clause_code);
+ extern tree build_call_list (enum tree_code, tree, tree, tree);
+ extern tree build_call_nary (enum tree_code, tree, tree, int, ...);
+ extern tree build_call_valist (enum tree_code, tree, tree, int, va_list);
+ extern tree build_call_array (enum tree_code, tree, tree, int, tree*);
+
/* Construct various nodes representing data types. */
extern tree make_signed_type (int);
*************** extern tree fold_build2_stat (enum tree_
*** 4211,4219 ****
--- 4217,4227 ----
#define fold_build2(c,t1,t2,t3) fold_build2_stat (c, t1, t2, t3 MEM_STAT_INFO)
extern tree fold_build3_stat (enum tree_code, tree, tree, tree, tree MEM_STAT_DECL);
#define fold_build3(c,t1,t2,t3,t4) fold_build3_stat (c, t1, t2, t3, t4 MEM_STAT_INFO)
+ extern tree fold_build_call_list (enum tree_code, tree, tree, tree);
extern tree fold_build1_initializer (enum tree_code, tree, tree);
extern tree fold_build2_initializer (enum tree_code, tree, tree, tree);
extern tree fold_build3_initializer (enum tree_code, tree, tree, tree, tree);
+ extern tree fold_build_call_list_initializer (enum tree_code, tree, tree, tree);
extern tree fold_convert (tree, tree);
extern tree fold_single_bit_test (enum tree_code, tree, tree, tree);
extern tree fold_ignored_result (tree);
*************** extern tree fold_builtin_snprintf_chk (t
*** 4296,4302 ****
extern bool fold_builtin_next_arg (tree, bool);
extern enum built_in_function builtin_mathfn_code (tree);
extern tree build_function_call_expr (tree, tree);
! extern tree fold_build_call_expr (tree, tree, tree, tree);
extern tree build_call_expr (tree, int, ...);
extern tree mathfn_built_in (tree, enum built_in_function fn);
extern tree strip_float_extensions (tree);
--- 4304,4311 ----
extern bool fold_builtin_next_arg (tree, bool);
extern enum built_in_function builtin_mathfn_code (tree);
extern tree build_function_call_expr (tree, tree);
! extern tree fold_builtin_call_list (tree, tree, tree);
! extern tree fold_builtin_call_valist (tree, tree, int, va_list);
extern tree build_call_expr (tree, int, ...);
extern tree mathfn_built_in (tree, enum built_in_function fn);
extern tree strip_float_extensions (tree);
Index: gcc/builtins.c
===================================================================
*** gcc/builtins.c (revision 115887)
--- gcc/builtins.c (working copy)
*************** build_function_call_expr (tree fndecl, t
*** 8919,8936 ****
{
tree fntype = TREE_TYPE (fndecl);
tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
! return fold_build_call_expr (TREE_TYPE (fntype), fn, arglist, NULL_TREE);
}
! /* Construct a function call expression with type TYPE with FN as the
! function expression. ARGLIST is a TREE_LIST of arguments, and
! STATIC_CHAIN is the static chain.
!
! FIXME: This needs to be rewritten when the underlying CALL_EXPR
! representation changes not to use a TREE_LIST to hold the arguments. */
tree
! fold_build_call_expr (tree type, tree fn, tree arglist, tree static_chain)
{
tree ret = NULL_TREE;
if (TREE_CODE (fn) == ADDR_EXPR)
--- 8919,8932 ----
{
tree fntype = TREE_TYPE (fndecl);
tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
! return fold_builtin_call_list (TREE_TYPE (fntype), fn, arglist);
}
! /* Construct a CALL_EXPR with type TYPE with FN as the function expression.
! ARGLIST is a TREE_LIST of arguments. */
tree
! fold_builtin_call_list (tree type, tree fn, tree arglist)
{
tree ret = NULL_TREE;
if (TREE_CODE (fn) == ADDR_EXPR)
*************** fold_build_call_expr (tree type, tree fn
*** 8951,8957 ****
tree tail = arglist;
tree args[MAX_ARGS_TO_FOLD_BUILTIN];
int nargs;
! tree temp;
for (nargs = 0; nargs < MAX_ARGS_TO_FOLD_BUILTIN; nargs++)
{
if (!tail)
--- 8947,8953 ----
tree tail = arglist;
tree args[MAX_ARGS_TO_FOLD_BUILTIN];
int nargs;
! tree exp;
for (nargs = 0; nargs < MAX_ARGS_TO_FOLD_BUILTIN; nargs++)
{
if (!tail)
*************** fold_build_call_expr (tree type, tree fn
*** 8965,9050 ****
if (ret)
return ret;
}
! temp = build3 (CALL_EXPR, type, fn, arglist, static_chain);
! ret = fold_builtin_varargs (fndecl, temp, false);
! return ret ? ret : temp;
}
}
}
! return build3 (CALL_EXPR, type, fn, arglist, static_chain);
}
/* Conveniently construct a function call expression. FNDECL names the
function to be called, N is the number of arguments, and the "..."
! parameters are the argument expressions.
!
! FIXME: This needs to be rewritten when the underlying CALL_EXPR
! representation changes not to use a TREE_LIST to hold the arguments. */
tree
build_call_expr (tree fndecl, int n, ...)
{
va_list ap;
! int i;
! tree arglist = NULL_TREE;
! tree ret = NULL_TREE;
! tree exp;
! tree fntype;
!
! if (TREE_CODE (fndecl) == FUNCTION_DECL
! && DECL_BUILT_IN (fndecl)
! && n <= MAX_ARGS_TO_FOLD_BUILTIN
! && DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_MD)
!
! {
! /* First try the transformations that don't require consing up
! an arglist or exp. */
! tree args[MAX_ARGS_TO_FOLD_BUILTIN];
! va_start (ap, n);
! for (i = 0; i < n; i++)
! args[i] = va_arg (ap, tree);
! va_end (ap);
! ret = fold_builtin_n (fndecl, args, n, false);
! if (ret)
! return ret;
! }
- /* We at least need an arglist.... */
va_start (ap, n);
! for (i = 0; i < n; i++)
! {
! tree arg = va_arg (ap, tree);
! arglist = tree_cons (NULL_TREE, arg, arglist);
! }
va_end (ap);
! arglist = nreverse (arglist);
! if (TREE_CODE (fndecl) == FUNCTION_DECL
! && DECL_BUILT_IN (fndecl)
! && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
! {
! /* FIXME: Don't use a list in this interface. */
! ret = targetm.fold_builtin (fndecl, arglist, false);
! if (ret)
! return ret;
! }
! /* If we got this far, we need to build an exp. */
! fntype = TREE_TYPE (fndecl);
! exp = build3 (CALL_EXPR,
! TREE_TYPE (fntype),
! build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl),
! arglist, NULL_TREE);
! if (TREE_CODE (fndecl) == FUNCTION_DECL
! && DECL_BUILT_IN (fndecl))
{
! ret = fold_builtin_varargs (fndecl, exp, false);
! if (ret)
! return ret;
}
! return exp;
}
/* Construct a new CALL_EXPR using the tail of the argument list of EXP
--- 8961,9052 ----
if (ret)
return ret;
}
! exp = build_call_list (CALL_EXPR, type, fn, arglist);
! ret = fold_builtin_varargs (fndecl, exp, false);
! return ret ? ret : exp;
}
}
}
! return build_call_list (CALL_EXPR, type, fn, arglist);
}
/* Conveniently construct a function call expression. FNDECL names the
function to be called, N is the number of arguments, and the "..."
! parameters are the argument expressions. */
tree
build_call_expr (tree fndecl, int n, ...)
{
va_list ap;
! tree ret;
! tree fntype = TREE_TYPE (fndecl);
! tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
va_start (ap, n);
! ret = fold_builtin_call_valist (TREE_TYPE (fntype), fn, n, ap);
va_end (ap);
! return ret;
! }
! /* Construct a CALL_EXPR with type TYPE with FN as the function expression.
! N arguments are passed in the va_list AP. */
! tree
! fold_builtin_call_valist (tree type,
! tree fn,
! int n,
! va_list ap)
! {
! tree ret = NULL_TREE;
! int i;
! tree exp;
! if (TREE_CODE (fn) == ADDR_EXPR)
{
! tree fndecl = TREE_OPERAND (fn, 0);
! if (TREE_CODE (fndecl) == FUNCTION_DECL
! && DECL_BUILT_IN (fndecl))
! {
! /* FIXME: Don't use a list in this interface. */
! if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
! {
! tree arglist = NULL_TREE;
! va_list ap0;
! va_copy (ap0, ap);
! for (i = 0; i < n; i++)
! {
! tree arg = va_arg (ap0, tree);
! arglist = tree_cons (NULL_TREE, arg, arglist);
! }
! va_end (ap0);
! arglist = nreverse (arglist);
! ret = targetm.fold_builtin (fndecl, arglist, false);
! if (ret)
! return ret;
! }
! else if (n <= MAX_ARGS_TO_FOLD_BUILTIN)
! {
! /* First try the transformations that don't require consing up
! an exp. */
! tree args[MAX_ARGS_TO_FOLD_BUILTIN];
! va_list ap0;
! va_copy (ap0, ap);
! for (i = 0; i < n; i++)
! args[i] = va_arg (ap0, tree);
! va_end (ap0);
! ret = fold_builtin_n (fndecl, args, n, false);
! if (ret)
! return ret;
! }
!
! /* If we got this far, we need to build an exp. */
! exp = build_call_valist (CALL_EXPR, type, fn, n, ap);
! ret = fold_builtin_varargs (fndecl, exp, false);
! return ret ? ret : exp;
! }
}
! return build_call_valist (CALL_EXPR, type, fn, n, ap);
}
/* Construct a new CALL_EXPR using the tail of the argument list of EXP
Index: gcc/fold-const.c
===================================================================
*** gcc/fold-const.c (revision 115887)
--- gcc/fold-const.c (working copy)
*************** fold (tree expr)
*** 11186,11191 ****
--- 11186,11203 ----
if (kind == tcc_constant)
return t;
+ /* CALL_EXPR-like objects with variable numbers of operands are
+ treated specially. */
+ if (kind == tcc_vl_exp)
+ {
+ if (code == CALL_EXPR)
+ {
+ tem = fold_call_expr (expr, false);
+ return tem ? tem : expr;
+ }
+ return expr;
+ }
+
if (IS_EXPR_CODE_CLASS (kind))
{
tree type = TREE_TYPE (t);
*************** fold (tree expr)
*** 11203,11215 ****
tem = fold_binary (code, type, op0, op1);
return tem ? tem : expr;
case 3:
- /* FIXME: CALL_EXPRs won't be ternary expressions any more
- after representation change is implemented. */
- if (code == CALL_EXPR)
- {
- tem = fold_call_expr (expr, false);
- return tem ? tem : expr;
- }
op0 = TREE_OPERAND (t, 0);
op1 = TREE_OPERAND (t, 1);
op2 = TREE_OPERAND (t, 2);
--- 11215,11220 ----
*************** fold_build3_stat (enum tree_code code, t
*** 11566,11581 ****
htab_empty (ht);
#endif
! /* FIXME: This is only temporary, since CALL_EXPRs won't be constructed
! with fold_build3 after representation conversion is complete. */
! if (code != CALL_EXPR)
! {
! tem = fold_ternary (code, type, op0, op1, op2);
! if (!tem)
! tem = build3_stat (code, type, op0, op1, op2 PASS_MEM_STAT);
! }
! else
! tem = fold_build_call_expr (type, op0, op1, op2);
#ifdef ENABLE_FOLD_CHECKING
md5_init_ctx (&ctx);
--- 11571,11580 ----
htab_empty (ht);
#endif
! gcc_assert (TREE_CODE_CLASS (code) != tcc_vl_exp);
! tem = fold_ternary (code, type, op0, op1, op2);
! if (!tem)
! tem = build3_stat (code, type, op0, op1, op2 PASS_MEM_STAT);
#ifdef ENABLE_FOLD_CHECKING
md5_init_ctx (&ctx);
*************** fold_build3_stat (enum tree_code code, t
*** 11605,11610 ****
--- 11604,11666 ----
return tem;
}
+ /* Fold a CALL_EXPR-like expression with code CODE of type TYPE with
+ operands FN and ARGLIST and a null static chain.
+ Return a folded expression if successful. Otherwise, return a tree
+ expression with code CODE of type TYPE from the given operands as
+ constructed by build_call_list. */
+
+ tree
+ fold_build_call_list (enum tree_code code, tree type,
+ tree fn, tree arglist)
+ {
+ tree tem;
+ #ifdef ENABLE_FOLD_CHECKING
+ unsigned char checksum_before_fn[16],
+ checksum_before_arglist[16],
+ checksum_after_fn[16],
+ checksum_after_arglist[16];
+ struct md5_ctx ctx;
+ htab_t ht;
+
+ ht = htab_create (32, htab_hash_pointer, htab_eq_pointer, NULL);
+ md5_init_ctx (&ctx);
+ fold_checksum_tree (fn, &ctx, ht);
+ md5_finish_ctx (&ctx, checksum_before_fn);
+ htab_empty (ht);
+
+ md5_init_ctx (&ctx);
+ fold_checksum_tree (arglist, &ctx, ht);
+ md5_finish_ctx (&ctx, checksum_before_arglist);
+ htab_empty (ht);
+ #endif
+
+ gcc_assert (TREE_CODE_CLASS (code) == tcc_vl_exp);
+ if (code == CALL_EXPR)
+ tem = fold_builtin_call_list (type, fn, arglist);
+ else
+ tem = build_call_list (code, type, fn, arglist);
+
+ #ifdef ENABLE_FOLD_CHECKING
+ md5_init_ctx (&ctx);
+ fold_checksum_tree (fn, &ctx, ht);
+ md5_finish_ctx (&ctx, checksum_after_fn);
+ htab_empty (ht);
+
+ if (memcmp (checksum_before_fn, checksum_after_fn, 16))
+ fold_check_failed (fn, tem);
+
+ md5_init_ctx (&ctx);
+ fold_checksum_tree (arglist, &ctx, ht);
+ md5_finish_ctx (&ctx, checksum_after_arglist);
+ htab_delete (ht);
+
+ if (memcmp (checksum_before_arglist, checksum_after_arglist, 16))
+ fold_check_failed (arglist, tem);
+ #endif
+ return tem;
+ }
+
/* Perform constant folding and related simplification of initializer
expression EXPR. These behave identically to "fold_buildN" but ignore
potential run-time traps and exceptions that fold must preserve. */
*************** fold_build3_initializer (enum tree_code
*** 11662,11667 ****
--- 11718,11736 ----
return result;
}
+ tree
+ fold_build_call_list_initializer (enum tree_code code, tree type,
+ tree fn, tree arglist)
+ {
+ tree result;
+ START_FOLD_INIT;
+
+ result = fold_build_call_list (code, type, fn, arglist);
+
+ END_FOLD_INIT;
+ return result;
+ }
+
#undef START_FOLD_INIT
#undef END_FOLD_INIT
Index: gcc/c-typeck.c
===================================================================
*** gcc/c-typeck.c (revision 115887)
--- gcc/c-typeck.c (working copy)
*************** build_function_call (tree function, tree
*** 2270,2286 ****
if (require_constant_value)
{
! result = fold_build3_initializer (CALL_EXPR, TREE_TYPE (fntype),
! function, coerced_params, NULL_TREE);
!
if (TREE_CONSTANT (result)
&& (name == NULL_TREE
|| strncmp (IDENTIFIER_POINTER (name), "__builtin_", 10) != 0))
pedwarn_init ("initializer element is not constant");
}
else
! result = fold_build3 (CALL_EXPR, TREE_TYPE (fntype),
! function, coerced_params, NULL_TREE);
if (VOID_TYPE_P (TREE_TYPE (result)))
return result;
--- 2268,2285 ----
if (require_constant_value)
{
! result = fold_build_call_list_initializer (CALL_EXPR,
! TREE_TYPE (fntype),
! function,
! coerced_params);
if (TREE_CONSTANT (result)
&& (name == NULL_TREE
|| strncmp (IDENTIFIER_POINTER (name), "__builtin_", 10) != 0))
pedwarn_init ("initializer element is not constant");
}
else
! result = fold_build_call_list (CALL_EXPR, TREE_TYPE (fntype),
! function, coerced_params);
if (VOID_TYPE_P (TREE_TYPE (result)))
return result;
Index: gcc/calls.c
===================================================================
*** gcc/calls.c (revision 115887)
--- gcc/calls.c (working copy)
*************** shift_return_value (enum machine_mode mo
*** 1778,1784 ****
return true;
}
! /* Generate all the code for a function call
and return an rtx for its value.
Store the value in TARGET (specified as an rtx) if convenient.
If the value is stored in TARGET then TARGET is returned.
--- 1778,1784 ----
return true;
}
! /* Generate all the code for a CALL_EXPR exp
and return an rtx for its value.
Store the value in TARGET (specified as an rtx) if convenient.
If the value is stored in TARGET then TARGET is returned.
*************** expand_call (tree exp, rtx target, int i
*** 1791,1797 ****
static int currently_expanding_call = 0;
/* List of actual parameters. */
! tree actparms = TREE_OPERAND (exp, 1);
/* RTX for the function to be called. */
rtx funexp;
/* Sequence of insns to perform a normal "call". */
--- 1791,1798 ----
static int currently_expanding_call = 0;
/* List of actual parameters. */
! /* FIXME: rewrite this so that it doesn't cons up a TREE_LIST. */
! tree actparms = CALL_EXPR_ARGS (exp);
/* RTX for the function to be called. */
rtx funexp;
/* Sequence of insns to perform a normal "call". */
*************** expand_call (tree exp, rtx target, int i
*** 1892,1899 ****
int old_stack_pointer_delta = 0;
rtx call_fusage;
! tree p = TREE_OPERAND (exp, 0);
! tree addr = TREE_OPERAND (exp, 0);
int i;
/* The alignment of the stack, in bits. */
unsigned HOST_WIDE_INT preferred_stack_boundary;
--- 1893,1900 ----
int old_stack_pointer_delta = 0;
rtx call_fusage;
! tree p = CALL_EXPR_FN (exp);
! tree addr = CALL_EXPR_FN (exp);
int i;
/* The alignment of the stack, in bits. */
unsigned HOST_WIDE_INT preferred_stack_boundary;
*************** expand_call (tree exp, rtx target, int i
*** 2542,2549 ****
once we have started filling any specific hard regs. */
precompute_register_parameters (num_actuals, args, ®_parm_seen);
! if (TREE_OPERAND (exp, 2))
! static_chain_value = expand_normal (TREE_OPERAND (exp, 2));
else
static_chain_value = 0;
--- 2543,2550 ----
once we have started filling any specific hard regs. */
precompute_register_parameters (num_actuals, args, ®_parm_seen);
! if (CALL_EXPR_STATIC_CHAIN (exp))
! static_chain_value = expand_normal (CALL_EXPR_STATIC_CHAIN (exp));
else
static_chain_value = 0;
Index: gcc/tree-ssa-pre.c
===================================================================
*** gcc/tree-ssa-pre.c (revision 115887)
--- gcc/tree-ssa-pre.c (working copy)
*************** static alloc_pool binary_node_pool;
*** 326,336 ****
static alloc_pool unary_node_pool;
static alloc_pool reference_node_pool;
static alloc_pool comparison_node_pool;
- static alloc_pool expression_node_pool;
static alloc_pool list_node_pool;
static alloc_pool modify_expr_node_pool;
static bitmap_obstack grand_bitmap_obstack;
/* To avoid adding 300 temporary variables when we only need one, we
only create one temporary variable, on demand, and build ssa names
off that. We do have to change the variable if the types don't
--- 326,343 ----
static alloc_pool unary_node_pool;
static alloc_pool reference_node_pool;
static alloc_pool comparison_node_pool;
static alloc_pool list_node_pool;
static alloc_pool modify_expr_node_pool;
static bitmap_obstack grand_bitmap_obstack;
+ /* We can't use allocation pools to hold temporary CALL_EXPR objects, since
+ they are not of fixed size. Instead, we'll xmalloc them directly, and
+ chain them together through their TREE_CHAIN slots. We don't need to
+ free them individually, just the whole chain of them when we are done. */
+
+ static tree temp_call_expr_chain;
+
+
/* To avoid adding 300 temporary variables when we only need one, we
only create one temporary variable, on demand, and build ssa names
off that. We do have to change the variable if the types don't
*************** pool_copy_list (tree list)
*** 987,992 ****
--- 994,1027 ----
return head;
}
+ /* Make a temporary copy of a CALL_EXPR object NODE. */
+
+ static tree
+ temp_copy_call_expr (tree node)
+ {
+ tree new = (tree) xmalloc (tree_size (node));
+ memcpy (new, node, tree_size (node));
+ TREE_CHAIN (new) = temp_call_expr_chain;
+ temp_call_expr_chain = new;
+ /* FIXME: Remove after CALL_EXPR representation conversion. */
+ CALL_EXPR_ARGS (new) = pool_copy_list (CALL_EXPR_ARGS (node));
+ return new;
+ }
+
+ /* Free all temporary CALL_EXPR objects. */
+ static void
+ free_temp_call_expr_chain (void)
+ {
+ tree node = temp_call_expr_chain;
+ while (node)
+ {
+ tree next = TREE_CHAIN (node);
+ free (node);
+ node = next;
+ }
+ temp_call_expr_chain = NULL_TREE;
+ }
+
/* Translate the vuses in the VUSES vector backwards through phi
nodes, so that they have the value they would have in BLOCK. */
*************** phi_translate (tree expr, value_set_t se
*** 1067,1123 ****
return NULL;
else
{
! tree oldop0 = CALL_EXPR_FN (expr);
! tree oldarglist = CALL_EXPR_ARGS (expr);
! tree oldop2 = CALL_EXPR_STATIC_CHAIN (expr);
! tree newop0;
! tree newarglist;
! tree newop2 = NULL;
! tree oldwalker;
! tree newwalker;
! tree newexpr;
tree vh = get_value_handle (expr);
! bool listchanged = false;
VEC (tree, gc) *vuses = VALUE_HANDLE_VUSES (vh);
VEC (tree, gc) *tvuses;
! /* FIXME: This section of code needs to be completely
! rewritten when the new representation of CALL_EXPRs is
! implemented. */
!
! /* Call expressions are kind of weird because they have an
! argument list. We don't want to value number the list
! as one value number, because that doesn't make much
! sense, and just breaks the support functions we call,
! which expect TREE_OPERAND (call_expr, 2) to be a
! TREE_LIST. */
!
! newop0 = phi_translate (find_leader (set, oldop0),
! set, pred, phiblock);
! if (newop0 == NULL)
return NULL;
! if (oldop2)
{
! newop2 = phi_translate (find_leader (set, oldop2),
! set, pred, phiblock);
! if (newop2 == NULL)
return NULL;
}
! /* phi translate the argument list piece by piece.
!
! We could actually build the list piece by piece here,
! but it's likely to not be worth the memory we will save,
! unless you have millions of call arguments. */
!
! newarglist = pool_copy_list (oldarglist);
! for (oldwalker = oldarglist, newwalker = newarglist;
! oldwalker && newwalker;
! oldwalker = TREE_CHAIN (oldwalker),
! newwalker = TREE_CHAIN (newwalker))
{
!
! tree oldval = TREE_VALUE (oldwalker);
tree newval;
if (oldval)
{
--- 1102,1144 ----
return NULL;
else
{
! tree oldfn = CALL_EXPR_FN (expr);
! tree oldsc = CALL_EXPR_STATIC_CHAIN (expr);
! tree newfn, newsc;
! tree newexpr = NULL_TREE;
tree vh = get_value_handle (expr);
! int i, nargs;
VEC (tree, gc) *vuses = VALUE_HANDLE_VUSES (vh);
VEC (tree, gc) *tvuses;
! newfn = phi_translate (find_leader (set, oldfn),
! set, pred, phiblock);
! if (newfn == NULL)
return NULL;
! if (newfn != oldfn)
{
! newexpr = temp_copy_call_expr (expr);
! CALL_EXPR_FN (newexpr) = get_value_handle (newfn);
! }
! if (oldsc)
! {
! newsc = phi_translate (find_leader (set, oldsc),
! set, pred, phiblock);
! if (newsc == NULL)
return NULL;
+ if (newsc != oldsc)
+ {
+ if (!newexpr)
+ newexpr = temp_copy_call_expr (expr);
+ CALL_EXPR_STATIC_CHAIN (newexpr) = get_value_handle (newsc);
+ }
}
! /* phi translate the argument list piece by piece. */
! nargs = call_expr_nargs (expr);
! for (i = 0; i < nargs; i++)
{
! tree oldval = CALL_EXPR_ARG (expr, i);
tree newval;
if (oldval)
{
*************** phi_translate (tree expr, value_set_t se
*** 1139,1162 ****
return NULL;
if (newval != oldval)
{
! listchanged = true;
! TREE_VALUE (newwalker) = get_value_handle (newval);
}
}
}
! if (listchanged)
! vn_lookup_or_add (newarglist, NULL);
!
tvuses = translate_vuses_through_block (vuses, pred);
! if (listchanged || (newop0 != oldop0) || (oldop2 != newop2)
! || vuses != tvuses)
{
- newexpr = (tree) pool_alloc (expression_node_pool);
- memcpy (newexpr, expr, tree_size (expr));
- CALL_EXPR_FN (newexpr) = newop0 == oldop0 ? oldop0 : get_value_handle (newop0);
- CALL_EXPR_ARGS (newexpr) = listchanged ? newarglist : oldarglist;
- CALL_EXPR_STATIC_CHAIN (newexpr) = newop2 == oldop2 ? oldop2 : get_value_handle (newop2);
create_tree_ann (newexpr);
vn_lookup_or_add_with_vuses (newexpr, tvuses);
expr = newexpr;
--- 1160,1178 ----
return NULL;
if (newval != oldval)
{
! if (!newexpr)
! newexpr = temp_copy_call_expr (expr);
! CALL_EXPR_ARG (newexpr, i) = get_value_handle (newval);
}
}
}
!
tvuses = translate_vuses_through_block (vuses, pred);
+ if (vuses != tvuses && ! newexpr)
+ newexpr = temp_copy_call_expr (expr);
! if (newexpr)
{
create_tree_ann (newexpr);
vn_lookup_or_add_with_vuses (newexpr, tvuses);
expr = newexpr;
*************** valid_in_set (value_set_t set, tree expr
*** 1558,1571 ****
{
if (TREE_CODE (expr) == CALL_EXPR)
{
! tree op0 = CALL_EXPR_FN (expr);
! tree op2 = CALL_EXPR_STATIC_CHAIN (expr);
tree arg;
call_expr_arg_iterator iter;
! /* Check the non-list operands first. */
! if (!set_contains_value (set, op0)
! || (op2 && !set_contains_value (set, op2)))
return false;
FOR_EACH_CALL_EXPR_ARG (arg, iter, expr)
--- 1574,1587 ----
{
if (TREE_CODE (expr) == CALL_EXPR)
{
! tree fn = CALL_EXPR_FN (expr);
! tree sc = CALL_EXPR_STATIC_CHAIN (expr);
tree arg;
call_expr_arg_iterator iter;
! /* Check the non-argument operands first. */
! if (!set_contains_value (set, fn)
! || (sc && !set_contains_value (set, sc)))
return false;
FOR_EACH_CALL_EXPR_ARG (arg, iter, expr)
*************** create_expression_by_pieces (basic_block
*** 2319,2331 ****
case tcc_vl_exp:
{
tree fn, sc;
! tree genfn, gensc;
tree genarglist;
tree arg;
call_expr_arg_iterator iter;
gcc_assert (TREE_CODE (expr) == CALL_EXPR);
- gensc = NULL;
fn = CALL_EXPR_FN (expr);
sc = CALL_EXPR_STATIC_CHAIN (expr);
--- 2335,2346 ----
case tcc_vl_exp:
{
tree fn, sc;
! tree genfn;
tree genarglist;
tree arg;
call_expr_arg_iterator iter;
gcc_assert (TREE_CODE (expr) == CALL_EXPR);
fn = CALL_EXPR_FN (expr);
sc = CALL_EXPR_STATIC_CHAIN (expr);
*************** create_expression_by_pieces (basic_block
*** 2342,2351 ****
}
genarglist = nreverse (genarglist);
! if (sc)
! gensc = find_or_generate_expression (block, sc, stmts);
! folded = fold_build_call_expr (TREE_TYPE (expr),
! genfn, genarglist, gensc);
break;
}
break;
--- 2357,2368 ----
}
genarglist = nreverse (genarglist);
! folded = fold_build_call_list (TREE_CODE (expr),
! TREE_TYPE (expr),
! genfn, genarglist);
! if (sc)
! CALL_EXPR_STATIC_CHAIN (folded) =
! find_or_generate_expression (block, sc, stmts);
break;
}
break;
*************** create_value_expr_from (tree expr, basic
*** 2892,2904 ****
pool = list_node_pool;
}
else
{
! gcc_assert (code == CALL_EXPR);
! pool = expression_node_pool;
}
-
- vexpr = (tree) pool_alloc (pool);
- memcpy (vexpr, expr, tree_size (expr));
/* This case is only for TREE_LIST's that appear as part of
CALL_EXPR's. Anything else is a bug, but we can't easily verify
--- 2909,2923 ----
pool = list_node_pool;
}
else
+ gcc_assert (code == CALL_EXPR);
+
+ if (code == CALL_EXPR)
+ vexpr = temp_copy_call_expr (expr);
+ else
{
! vexpr = (tree) pool_alloc (pool);
! memcpy (vexpr, expr, tree_size (expr));
}
/* This case is only for TREE_LIST's that appear as part of
CALL_EXPR's. Anything else is a bug, but we can't easily verify
*************** create_value_expr_from (tree expr, basic
*** 2907,2913 ****
operands, so you can't access purpose/value/chain through
TREE_OPERAND macros. */
! /* FIXME: This section of code needs to go away somehow when the
low-level representation of CALL_EXPRs is changed not to use
TREE_LISTs. */
--- 2926,2932 ----
operands, so you can't access purpose/value/chain through
TREE_OPERAND macros. */
! /* FIXME: This section of code should go away completely when the
low-level representation of CALL_EXPRs is changed not to use
TREE_LISTs. */
*************** create_value_expr_from (tree expr, basic
*** 2958,2963 ****
--- 2977,2983 ----
op = tempop ? tempop : op;
val = vn_lookup_or_add (op, stmt);
}
+ /* FIXME: Delete this clause when CALL_EXPR representation changes. */
else if (TREE_CODE (op) == TREE_LIST)
{
tree tempop;
*************** create_value_expr_from (tree expr, basic
*** 2966,2972 ****
tempop = create_value_expr_from (op, block, stmt);
op = tempop ? tempop : op;
- vn_lookup_or_add (op, NULL);
/* Unlike everywhere else, we do *not* want to replace the
TREE_LIST itself with a value number, because support
functions we call will blow up. */
--- 2986,2991 ----
*************** init_pre (bool do_fre)
*** 3789,3796 ****
tree_code_size (NEGATE_EXPR), 30);
reference_node_pool = create_alloc_pool ("Reference tree nodes",
tree_code_size (ARRAY_REF), 30);
- expression_node_pool = create_alloc_pool ("Expression tree nodes",
- tree_code_size (CALL_EXPR), 30);
list_node_pool = create_alloc_pool ("List tree nodes",
tree_code_size (TREE_LIST), 30);
comparison_node_pool = create_alloc_pool ("Comparison tree nodes",
--- 3808,3813 ----
*************** init_pre (bool do_fre)
*** 3799,3804 ****
--- 3816,3822 ----
tree_code_size (MODIFY_EXPR),
30);
modify_expr_template = NULL;
+ temp_call_expr_chain = NULL_TREE;
FOR_ALL_BB (bb)
{
*************** fini_pre (bool do_fre)
*** 3823,3828 ****
--- 3841,3847 ----
VEC_free (tree, heap, inserted_exprs);
VEC_free (tree, heap, need_creation);
bitmap_obstack_release (&grand_bitmap_obstack);
+ free_temp_call_expr_chain ();
free_alloc_pool (value_set_pool);
free_alloc_pool (bitmap_set_pool);
free_alloc_pool (value_set_node_pool);
*************** fini_pre (bool do_fre)
*** 3830,3836 ****
free_alloc_pool (reference_node_pool);
free_alloc_pool (unary_node_pool);
free_alloc_pool (list_node_pool);
- free_alloc_pool (expression_node_pool);
free_alloc_pool (comparison_node_pool);
free_alloc_pool (modify_expr_node_pool);
htab_delete (phi_translate_table);
--- 3849,3854 ----
Index: gcc/java/parse.y
===================================================================
*** gcc/java/parse.y (revision 115887)
--- gcc/java/parse.y (working copy)
*************** patch_invoke (tree patch, tree method, t
*** 11103,11111 ****
if (flag_emit_class_files)
{
! tree new_patch = build3 (NEW_CLASS_EXPR,
! build_pointer_type (class),
! func, args, NULL_TREE);
TREE_SIDE_EFFECTS (new_patch) = TREE_SIDE_EFFECTS (patch);
EXPR_WFL_LINECOL (new_patch) = EXPR_WFL_LINECOL (patch);
CALL_USING_SUPER (new_patch) = CALL_USING_SUPER (patch);
--- 11103,11111 ----
if (flag_emit_class_files)
{
! tree new_patch = build_call_list (NEW_CLASS_EXPR,
! build_pointer_type (class),
! func, args);
TREE_SIDE_EFFECTS (new_patch) = TREE_SIDE_EFFECTS (patch);
EXPR_WFL_LINECOL (new_patch) = EXPR_WFL_LINECOL (patch);
CALL_USING_SUPER (new_patch) = CALL_USING_SUPER (patch);
*************** patch_invoke (tree patch, tree method, t
*** 11116,11129 ****
alloc_node =
(class_has_finalize_method (class) ? alloc_object_node
: alloc_no_finalizer_node);
! new = build3 (CALL_EXPR, promote_type (class),
! build_address_of (alloc_node),
! build_tree_list (NULL_TREE, build_class_ref (class)),
! NULL_TREE);
saved_new = save_expr (new);
args = tree_cons (NULL_TREE, saved_new, args);
! new_patch = build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (method)),
! func, args, NULL_TREE);
TREE_SIDE_EFFECTS (new_patch) = TREE_SIDE_EFFECTS (patch);
EXPR_WFL_LINECOL (new_patch) = EXPR_WFL_LINECOL (patch);
CALL_USING_SUPER (new_patch) = CALL_USING_SUPER (patch);
--- 11116,11128 ----
alloc_node =
(class_has_finalize_method (class) ? alloc_object_node
: alloc_no_finalizer_node);
! new = build_call_nary (CALL_EXPR, promote_type (class),
! build_address_of (alloc_node),
! 1, build_class_ref (class));
saved_new = save_expr (new);
args = tree_cons (NULL_TREE, saved_new, args);
! new_patch = build_call_list (CALL_EXPR, TREE_TYPE (TREE_TYPE (method)),
! func, args);
TREE_SIDE_EFFECTS (new_patch) = TREE_SIDE_EFFECTS (patch);
EXPR_WFL_LINECOL (new_patch) = EXPR_WFL_LINECOL (patch);
CALL_USING_SUPER (new_patch) = CALL_USING_SUPER (patch);
*************** patch_invoke (tree patch, tree method, t
*** 11131,11138 ****
}
else
{
! tree new_patch = build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (method)),
! func, args, NULL_TREE);
TREE_SIDE_EFFECTS (new_patch) = TREE_SIDE_EFFECTS (patch);
EXPR_WFL_LINECOL (new_patch) = EXPR_WFL_LINECOL (patch);
CALL_USING_SUPER (new_patch) = CALL_USING_SUPER (patch);
--- 11130,11138 ----
}
else
{
! tree new_patch = build_call_list (CALL_EXPR,
! TREE_TYPE (TREE_TYPE (method)),
! func, args);
TREE_SIDE_EFFECTS (new_patch) = TREE_SIDE_EFFECTS (patch);
EXPR_WFL_LINECOL (new_patch) = EXPR_WFL_LINECOL (patch);
CALL_USING_SUPER (new_patch) = CALL_USING_SUPER (patch);
*************** build_this_super_qualified_invocation (i
*** 12744,12750 ****
static tree
build_method_invocation (tree name, tree args)
{
! tree call = build3 (CALL_EXPR, NULL_TREE, name, args, NULL_TREE);
TREE_SIDE_EFFECTS (call) = 1;
EXPR_WFL_LINECOL (call) = EXPR_WFL_LINECOL (name);
return call;
--- 12744,12750 ----
static tree
build_method_invocation (tree name, tree args)
{
! tree call = build_call_list (CALL_EXPR, NULL_TREE, name, args);
TREE_SIDE_EFFECTS (call) = 1;
EXPR_WFL_LINECOL (call) = EXPR_WFL_LINECOL (name);
return call;
*************** build_method_invocation (tree name, tree
*** 12755,12761 ****
static tree
build_new_invocation (tree name, tree args)
{
! tree call = build3 (NEW_CLASS_EXPR, NULL_TREE, name, args, NULL_TREE);
TREE_SIDE_EFFECTS (call) = 1;
EXPR_WFL_LINECOL (call) = EXPR_WFL_LINECOL (name);
return call;
--- 12755,12762 ----
static tree
build_new_invocation (tree name, tree args)
{
! tree call =
! build_call_list (NEW_CLASS_EXPR, NULL_TREE, name, args);
TREE_SIDE_EFFECTS (call) = 1;
EXPR_WFL_LINECOL (call) = EXPR_WFL_LINECOL (name);
return call;
*************** patch_cast (tree node, tree wfl_op)
*** 14617,14627 ****
}
/* The cast requires a run-time check */
! return build3 (CALL_EXPR, promote_type (cast_type),
! build_address_of (soft_checkcast_node),
! tree_cons (NULL_TREE, build_class_ref (cast_type),
! build_tree_list (NULL_TREE, op)),
! NULL_TREE);
}
/* Any other casts are proven incorrect at compile time */
--- 14618,14626 ----
}
/* The cast requires a run-time check */
! return build_call_nary (CALL_EXPR, promote_type (cast_type),
! build_address_of (soft_checkcast_node),
! 2, build_class_ref (cast_type), op);
}
/* Any other casts are proven incorrect at compile time */
*************** patch_newarray (tree node)
*** 14813,14826 ****
/* Can't reuse what's already written in expr.c because it uses the
JVM stack representation. Provide a build_multianewarray. FIXME */
! return build3 (CALL_EXPR, array_type,
! build_address_of (soft_multianewarray_node),
! tree_cons (NULL_TREE,
! build_class_ref (TREE_TYPE (array_type)),
! tree_cons (NULL_TREE,
! build_int_cst (NULL_TREE, ndims),
! dims)),
! NULL_TREE);
}
/* 10.6 Array initializer. */
--- 14812,14824 ----
/* Can't reuse what's already written in expr.c because it uses the
JVM stack representation. Provide a build_multianewarray. FIXME */
! return build_call_list (CALL_EXPR, array_type,
! build_address_of (soft_multianewarray_node),
! tree_cons (NULL_TREE,
! build_class_ref (TREE_TYPE (array_type)),
! tree_cons (NULL_TREE,
! build_int_cst (NULL_TREE, ndims),
! dims)));
}
/* 10.6 Array initializer. */
*************** build_assertion (
*** 15618,15624 ****
/* Call CLASS.desiredAssertionStatus(). */
id = build_wfl_node (get_identifier ("desiredAssertionStatus"));
! call = build3 (CALL_EXPR, NULL_TREE, id, NULL_TREE, NULL_TREE);
call = make_qualified_primary (classdollar, call, location);
TREE_SIDE_EFFECTS (call) = 1;
--- 15616,15622 ----
/* Call CLASS.desiredAssertionStatus(). */
id = build_wfl_node (get_identifier ("desiredAssertionStatus"));
! call = build_call_nary (CALL_EXPR, NULL_TREE, id, 0);
call = make_qualified_primary (classdollar, call, location);
TREE_SIDE_EFFECTS (call) = 1;
*************** build_assertion (
*** 15638,15653 ****
CLASS_USES_ASSERTIONS (klass) = 1;
}
- if (value != NULL_TREE)
- value = tree_cons (NULL_TREE, value, NULL_TREE);
-
node = build_wfl_node (get_identifier ("java"));
node = make_qualified_name (node, build_wfl_node (get_identifier ("lang")),
location);
node = make_qualified_name (node, build_wfl_node (get_identifier ("AssertionError")),
location);
!
! node = build3 (NEW_CLASS_EXPR, NULL_TREE, node, value, NULL_TREE);
TREE_SIDE_EFFECTS (node) = 1;
/* It is too early to use BUILD_THROW. */
node = build1 (THROW_EXPR, NULL_TREE, node);
--- 15636,15651 ----
CLASS_USES_ASSERTIONS (klass) = 1;
}
node = build_wfl_node (get_identifier ("java"));
node = make_qualified_name (node, build_wfl_node (get_identifier ("lang")),
location);
node = make_qualified_name (node, build_wfl_node (get_identifier ("AssertionError")),
location);
! if (value != NULL_TREE)
! node = build_call_nary (NEW_CLASS_EXPR, NULL_TREE,
! node, 1, value);
! else
! node = build_call_nary (NEW_CLASS_EXPR, NULL_TREE, node, 0);
TREE_SIDE_EFFECTS (node) = 1;
/* It is too early to use BUILD_THROW. */
node = build1 (THROW_EXPR, NULL_TREE, node);
Index: gcc/java/expr.c
===================================================================
*** gcc/java/expr.c (revision 115887)
--- gcc/java/expr.c (working copy)
*************** build_java_athrow (tree node)
*** 712,722 ****
{
tree call;
! call = build3 (CALL_EXPR,
! void_type_node,
! build_address_of (throw_node),
! build_tree_list (NULL_TREE, node),
! NULL_TREE);
TREE_SIDE_EFFECTS (call) = 1;
java_add_stmt (call);
java_stack_pop (stack_pointer);
--- 712,720 ----
{
tree call;
! call = build_call_nary (CALL_EXPR, void_type_node,
! build_address_of (throw_node),
! 1, node);
TREE_SIDE_EFFECTS (call) = 1;
java_add_stmt (call);
java_stack_pop (stack_pointer);
*************** encode_newarray_type (tree type)
*** 795,803 ****
static tree
build_java_throw_out_of_bounds_exception (tree index)
{
! tree node = build3 (CALL_EXPR, int_type_node,
! build_address_of (soft_badarrayindex_node),
! build_tree_list (NULL_TREE, index), NULL_TREE);
TREE_SIDE_EFFECTS (node) = 1; /* Allows expansion within ANDIF */
return (node);
}
--- 793,801 ----
static tree
build_java_throw_out_of_bounds_exception (tree index)
{
! tree node = build_call_nary (CALL_EXPR, int_type_node,
! build_address_of (soft_badarrayindex_node),
! 1, index);
TREE_SIDE_EFFECTS (node) = 1; /* Allows expansion within ANDIF */
return (node);
}
*************** java_check_reference (tree expr, int che
*** 846,854 ****
expr = build3 (COND_EXPR, TREE_TYPE (expr),
build2 (EQ_EXPR, boolean_type_node,
expr, null_pointer_node),
! build3 (CALL_EXPR, void_type_node,
! build_address_of (soft_nullpointer_node),
! NULL_TREE, NULL_TREE),
expr);
}
--- 844,852 ----
expr = build3 (COND_EXPR, TREE_TYPE (expr),
build2 (EQ_EXPR, boolean_type_node,
expr, null_pointer_node),
! build_call_nary (CALL_EXPR, void_type_node,
! build_address_of (soft_nullpointer_node),
! 0),
expr);
}
*************** build_java_arraystore_check (tree array,
*** 991,1001 ****
}
/* Build an invocation of _Jv_CheckArrayStore */
! check = build3 (CALL_EXPR, void_type_node,
! build_address_of (soft_checkarraystore_node),
! tree_cons (NULL_TREE, array,
! build_tree_list (NULL_TREE, object)),
! NULL_TREE);
TREE_SIDE_EFFECTS (check) = 1;
return check;
--- 989,997 ----
}
/* Build an invocation of _Jv_CheckArrayStore */
! check = build_call_nary (CALL_EXPR, void_type_node,
! build_address_of (soft_checkarraystore_node),
! 2, array, object);
TREE_SIDE_EFFECTS (check) = 1;
return check;
*************** build_newarray (int atype_value, tree le
*** 1041,1052 ****
else
type_arg = build_class_ref (prim_type);
! return build3 (CALL_EXPR, promote_type (type),
! build_address_of (soft_newarray_node),
! tree_cons (NULL_TREE,
! type_arg,
! build_tree_list (NULL_TREE, length)),
! NULL_TREE);
}
/* Generates anewarray from a given CLASS_TYPE. Gets from the stack the size
--- 1037,1045 ----
else
type_arg = build_class_ref (prim_type);
! return build_call_nary (CALL_EXPR, promote_type (type),
! build_address_of (soft_newarray_node),
! 2, type_arg, length);
}
/* Generates anewarray from a given CLASS_TYPE. Gets from the stack the size
*************** build_anewarray (tree class_type, tree l
*** 1060,1072 ****
host_integerp (length, 0)
? tree_low_cst (length, 0) : -1);
! return build3 (CALL_EXPR, promote_type (type),
! build_address_of (soft_anewarray_node),
! tree_cons (NULL_TREE, length,
! tree_cons (NULL_TREE, build_class_ref (class_type),
! build_tree_list (NULL_TREE,
! null_pointer_node))),
! NULL_TREE);
}
/* Return a node the evaluates 'new TYPE[LENGTH]'. */
--- 1053,1064 ----
host_integerp (length, 0)
? tree_low_cst (length, 0) : -1);
! return build_call_nary (CALL_EXPR, promote_type (type),
! build_address_of (soft_anewarray_node),
! 3,
! length,
! build_class_ref (class_type),
! null_pointer_node);
}
/* Return a node the evaluates 'new TYPE[LENGTH]'. */
*************** expand_java_multianewarray (tree class_t
*** 1093,1106 ****
for( i = 0; i < ndim; i++ )
args = tree_cons (NULL_TREE, pop_value (int_type_node), args);
! push_value (build3 (CALL_EXPR,
! promote_type (class_type),
! build_address_of (soft_multianewarray_node),
! tree_cons (NULL_TREE, build_class_ref (class_type),
! tree_cons (NULL_TREE,
! build_int_cst (NULL_TREE, ndim),
! args)),
! NULL_TREE));
}
/* ARRAY[INDEX] <- RHS. build_java_check_indexed_type makes sure that
--- 1085,1100 ----
for( i = 0; i < ndim; i++ )
args = tree_cons (NULL_TREE, pop_value (int_type_node), args);
! args = tree_cons (NULL_TREE,
! build_class_ref (class_type),
! tree_cons (NULL_TREE,
! build_int_cst (NULL_TREE, ndim),
! args));
!
! push_value (build_call_list (CALL_EXPR,
! promote_type (class_type),
! build_address_of (soft_multianewarray_node),
! args));
}
/* ARRAY[INDEX] <- RHS. build_java_check_indexed_type makes sure that
*************** expand_java_array_length (void)
*** 1210,1220 ****
static tree
build_java_monitor (tree call, tree object)
{
! return build3 (CALL_EXPR,
! void_type_node,
! build_address_of (call),
! build_tree_list (NULL_TREE, object),
! NULL_TREE);
}
/* Emit code for one of the PUSHC instructions. */
--- 1204,1213 ----
static tree
build_java_monitor (tree call, tree object)
{
! return build_call_nary (CALL_EXPR,
! void_type_node,
! build_address_of (call),
! 1, object);
}
/* Emit code for one of the PUSHC instructions. */
*************** java_create_object (tree type)
*** 1311,1320 ****
? alloc_object_node
: alloc_no_finalizer_node);
! return build3 (CALL_EXPR, promote_type (type),
! build_address_of (alloc_node),
! build_tree_list (NULL_TREE, build_class_ref (type)),
! NULL_TREE);
}
static void
--- 1304,1312 ----
? alloc_object_node
: alloc_no_finalizer_node);
! return build_call_nary (CALL_EXPR, promote_type (type),
! build_address_of (alloc_node),
! 1, build_class_ref (type));
}
static void
*************** expand_java_NEW (tree type)
*** 1327,1336 ****
if (! CLASS_LOADED_P (type))
load_class (type, 1);
safe_layout_class (type);
! push_value (build3 (CALL_EXPR, promote_type (type),
! build_address_of (alloc_node),
! build_tree_list (NULL_TREE, build_class_ref (type)),
! NULL_TREE));
}
/* This returns an expression which will extract the class of an
--- 1319,1327 ----
if (! CLASS_LOADED_P (type))
load_class (type, 1);
safe_layout_class (type);
! push_value (build_call_nary (CALL_EXPR, promote_type (type),
! build_address_of (alloc_node),
! 1, build_class_ref (type)));
}
/* This returns an expression which will extract the class of an
*************** build_instanceof (tree value, tree type)
*** 1409,1420 ****
}
else
{
! expr = build3 (CALL_EXPR, itype,
! build_address_of (soft_instanceof_node),
! tree_cons (NULL_TREE, value,
! build_tree_list (NULL_TREE,
! build_class_ref (type))),
! NULL_TREE);
}
TREE_SIDE_EFFECTS (expr) = TREE_SIDE_EFFECTS (value);
return expr;
--- 1400,1408 ----
}
else
{
! expr = build_call_nary (CALL_EXPR, itype,
! build_address_of (soft_instanceof_node),
! 2, value, build_class_ref (type));
}
TREE_SIDE_EFFECTS (expr) = TREE_SIDE_EFFECTS (value);
return expr;
*************** static void
*** 1432,1442 ****
expand_java_CHECKCAST (tree type)
{
tree value = pop_value (ptr_type_node);
! value = build3 (CALL_EXPR, promote_type (type),
! build_address_of (soft_checkcast_node),
! tree_cons (NULL_TREE, build_class_ref (type),
! build_tree_list (NULL_TREE, value)),
! NULL_TREE);
push_value (value);
}
--- 1420,1428 ----
expand_java_CHECKCAST (tree type)
{
tree value = pop_value (ptr_type_node);
! value = build_call_nary (CALL_EXPR, promote_type (type),
! build_address_of (soft_checkcast_node),
! 2, build_class_ref (type), value);
push_value (value);
}
*************** build_java_soft_divmod (enum tree_code o
*** 1492,1503 ****
}
gcc_assert (call);
! call = build3 (CALL_EXPR, type,
! build_address_of (call),
! tree_cons (NULL_TREE, arg1,
! build_tree_list (NULL_TREE, arg2)),
! NULL_TREE);
!
return call;
}
--- 1478,1486 ----
}
gcc_assert (call);
! call = build_call_nary (CALL_EXPR, type,
! build_address_of (call),
! 2, arg1, arg2);
return call;
}
*************** build_java_binop (enum tree_code op, tre
*** 1560,1570 ****
arg1 = convert (double_type_node, arg1);
arg2 = convert (double_type_node, arg2);
}
! call = build3 (CALL_EXPR, double_type_node,
! build_address_of (soft_fmod_node),
! tree_cons (NULL_TREE, arg1,
! build_tree_list (NULL_TREE, arg2)),
! NULL_TREE);
if (type != double_type_node)
call = convert (type, call);
return call;
--- 1543,1551 ----
arg1 = convert (double_type_node, arg1);
arg2 = convert (double_type_node, arg2);
}
! call = build_call_nary (CALL_EXPR, double_type_node,
! build_address_of (soft_fmod_node),
! 2, arg1, arg2);
if (type != double_type_node)
call = convert (type, call);
return call;
*************** build_field_ref (tree self_value, tree s
*** 1723,1732 ****
= build3 (COND_EXPR, TREE_TYPE (field_offset),
build2 (EQ_EXPR, boolean_type_node,
field_offset, integer_zero_node),
! build3 (CALL_EXPR, void_type_node,
! build_address_of (soft_nosuchfield_node),
! build_tree_list (NULL_TREE, otable_index),
! NULL_TREE),
field_offset);
field_offset = fold (convert (sizetype, field_offset));
--- 1704,1712 ----
= build3 (COND_EXPR, TREE_TYPE (field_offset),
build2 (EQ_EXPR, boolean_type_node,
field_offset, integer_zero_node),
! build_call_nary (CALL_EXPR, void_type_node,
! build_address_of (soft_nosuchfield_node),
! 1, otable_index),
field_offset);
field_offset = fold (convert (sizetype, field_offset));
*************** build_class_init (tree clas, tree expr)
*** 1962,1971 ****
if (always_initialize_class_p)
{
! init = build3 (CALL_EXPR, void_type_node,
! build_address_of (soft_initclass_node),
! build_tree_list (NULL_TREE, build_class_ref (clas)),
! NULL_TREE);
TREE_SIDE_EFFECTS (init) = 1;
}
else
--- 1942,1950 ----
if (always_initialize_class_p)
{
! init = build_call_nary (CALL_EXPR, void_type_node,
! build_address_of (soft_initclass_node),
! 1, build_class_ref (clas));
TREE_SIDE_EFFECTS (init) = 1;
}
else
*************** build_class_init (tree clas, tree expr)
*** 1995,2004 ****
*init_test_decl = decl;
}
! init = build3 (CALL_EXPR, void_type_node,
! build_address_of (soft_initclass_node),
! build_tree_list (NULL_TREE, build_class_ref (clas)),
! NULL_TREE);
TREE_SIDE_EFFECTS (init) = 1;
init = build3 (COND_EXPR, void_type_node,
build2 (EQ_EXPR, boolean_type_node,
--- 1974,1982 ----
*init_test_decl = decl;
}
! init = build_call_nary (CALL_EXPR, void_type_node,
! build_address_of (soft_initclass_node),
! 1, build_class_ref (clas));
TREE_SIDE_EFFECTS (init) = 1;
init = build3 (COND_EXPR, void_type_node,
build2 (EQ_EXPR, boolean_type_node,
*************** static GTY(()) tree class_ident;
*** 2285,2291 ****
tree
build_invokeinterface (tree dtable, tree method)
{
- tree lookup_arg;
tree interface;
tree idx;
--- 2263,2268 ----
*************** build_invokeinterface (tree dtable, tree
*** 2330,2342 ****
interface = build_class_ref (interface);
}
! lookup_arg = tree_cons (NULL_TREE, dtable,
! tree_cons (NULL_TREE, interface,
! build_tree_list (NULL_TREE, idx)));
!
! return build3 (CALL_EXPR, ptr_type_node,
! build_address_of (soft_lookupinterfacemethod_node),
! lookup_arg, NULL_TREE);
}
/* Expand one of the invoke_* opcodes.
--- 2307,2315 ----
interface = build_class_ref (interface);
}
! return build_call_nary (CALL_EXPR, ptr_type_node,
! build_address_of (soft_lookupinterfacemethod_node),
! 3, dtable, interface, idx);
}
/* Expand one of the invoke_* opcodes.
*************** expand_invoke (int opcode, int method_re
*** 2516,2523 ****
else
func = build1 (NOP_EXPR, build_pointer_type (method_type), func);
! call = build3 (CALL_EXPR, TREE_TYPE (method_type),
! func, arg_list, NULL_TREE);
TREE_SIDE_EFFECTS (call) = 1;
call = check_for_builtin (method, call);
--- 2489,2495 ----
else
func = build1 (NOP_EXPR, build_pointer_type (method_type), func);
! call = build_call_list (CALL_EXPR, TREE_TYPE (method_type), func, arg_list);
TREE_SIDE_EFFECTS (call) = 1;
call = check_for_builtin (method, call);
*************** expand_invoke (int opcode, int method_re
*** 2542,2548 ****
tree
build_jni_stub (tree method)
{
! tree jnifunc, call, args, body, lookup_arg, method_sig, arg_types;
tree jni_func_type, tem;
tree env_var, res_var = NULL_TREE, block;
tree method_args, res_type;
--- 2514,2521 ----
tree
build_jni_stub (tree method)
{
! tree jnifunc, call, args, body, method_sig, arg_types;
! tree jniarg0, jniarg1, jniarg2, jniarg3;
tree jni_func_type, tem;
tree env_var, res_var = NULL_TREE, block;
tree method_args, res_type;
*************** build_jni_stub (tree method)
*** 2597,2606 ****
/* Compute the local `env' by calling _Jv_GetJNIEnvNewFrame. */
body = build2 (MODIFY_EXPR, ptr_type_node, env_var,
! build3 (CALL_EXPR, ptr_type_node,
! build_address_of (soft_getjnienvnewframe_node),
! build_tree_list (NULL_TREE, klass),
! NULL_TREE));
CAN_COMPLETE_NORMALLY (body) = 1;
/* All the arguments to this method become arguments to the
--- 2570,2578 ----
/* Compute the local `env' by calling _Jv_GetJNIEnvNewFrame. */
body = build2 (MODIFY_EXPR, ptr_type_node, env_var,
! build_call_nary (CALL_EXPR, ptr_type_node,
! build_address_of (soft_getjnienvnewframe_node),
! 1, klass));
CAN_COMPLETE_NORMALLY (body) = 1;
/* All the arguments to this method become arguments to the
*************** build_jni_stub (tree method)
*** 2639,2656 ****
/* We call _Jv_LookupJNIMethod to find the actual underlying
function pointer. _Jv_LookupJNIMethod will throw the appropriate
exception if this function is not found at runtime. */
- tem = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, args_size));
method_sig = build_java_signature (TREE_TYPE (method));
! lookup_arg = tree_cons (NULL_TREE,
! build_utf8_ref (unmangle_classname
! (IDENTIFIER_POINTER (method_sig),
! IDENTIFIER_LENGTH (method_sig))),
! tem);
! tem = DECL_NAME (method);
! lookup_arg
! = tree_cons (NULL_TREE, klass,
! tree_cons (NULL_TREE, build_utf8_ref (tem), lookup_arg));
!
tem = build_function_type (TREE_TYPE (TREE_TYPE (method)), arg_types);
#ifdef MODIFY_JNI_METHOD_CALL
--- 2611,2624 ----
/* We call _Jv_LookupJNIMethod to find the actual underlying
function pointer. _Jv_LookupJNIMethod will throw the appropriate
exception if this function is not found at runtime. */
method_sig = build_java_signature (TREE_TYPE (method));
! jniarg0 = klass;
! jniarg1 = build_utf8_ref (DECL_NAME (method));
! jniarg2 = build_utf8_ref (unmangle_classname
! (IDENTIFIER_POINTER (method_sig),
! IDENTIFIER_LENGTH (method_sig)));
! jniarg3 = build_int_cst (NULL_TREE, args_size);
!
tem = build_function_type (TREE_TYPE (TREE_TYPE (method)), arg_types);
#ifdef MODIFY_JNI_METHOD_CALL
*************** build_jni_stub (tree method)
*** 2662,2677 ****
jnifunc = build3 (COND_EXPR, ptr_type_node,
meth_var, meth_var,
build2 (MODIFY_EXPR, ptr_type_node, meth_var,
! build3 (CALL_EXPR, ptr_type_node,
! build_address_of
! (soft_lookupjnimethod_node),
! lookup_arg, NULL_TREE)));
/* Now we make the actual JNI call via the resulting function
pointer. */
! call = build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (method)),
! build1 (NOP_EXPR, jni_func_type, jnifunc),
! args, NULL_TREE);
/* If the JNI call returned a result, capture it here. If we had to
unwrap JNI object results, we would do that here. */
--- 2630,2647 ----
jnifunc = build3 (COND_EXPR, ptr_type_node,
meth_var, meth_var,
build2 (MODIFY_EXPR, ptr_type_node, meth_var,
! build_call_nary (CALL_EXPR, ptr_type_node,
! build_address_of
! (soft_lookupjnimethod_node),
! 4,
! jniarg0, jniarg1,
! jniarg2, jniarg3)));
/* Now we make the actual JNI call via the resulting function
pointer. */
! call = build_call_list (CALL_EXPR, TREE_TYPE (TREE_TYPE (method)),
! build1 (NOP_EXPR, jni_func_type, jnifunc),
! args);
/* If the JNI call returned a result, capture it here. If we had to
unwrap JNI object results, we would do that here. */
*************** build_jni_stub (tree method)
*** 2680,2689 ****
/* If the call returns an object, it may return a JNI weak
reference, in which case we must unwrap it. */
if (! JPRIMITIVE_TYPE_P (TREE_TYPE (TREE_TYPE (method))))
! call = build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (method)),
! build_address_of (soft_unwrapjni_node),
! build_tree_list (NULL_TREE, call),
! NULL_TREE);
call = build2 (MODIFY_EXPR, TREE_TYPE (TREE_TYPE (method)),
res_var, call);
}
--- 2650,2658 ----
/* If the call returns an object, it may return a JNI weak
reference, in which case we must unwrap it. */
if (! JPRIMITIVE_TYPE_P (TREE_TYPE (TREE_TYPE (method))))
! call = build_call_nary (CALL_EXPR, TREE_TYPE (TREE_TYPE (method)),
! build_address_of (soft_unwrapjni_node),
! 1, call);
call = build2 (MODIFY_EXPR, TREE_TYPE (TREE_TYPE (method)),
res_var, call);
}
*************** build_jni_stub (tree method)
*** 2695,2704 ****
TREE_SIDE_EFFECTS (body) = 1;
/* Now free the environment we allocated. */
! call = build3 (CALL_EXPR, ptr_type_node,
! build_address_of (soft_jnipopsystemframe_node),
! build_tree_list (NULL_TREE, env_var),
! NULL_TREE);
TREE_SIDE_EFFECTS (call) = 1;
CAN_COMPLETE_NORMALLY (call) = 1;
body = build2 (COMPOUND_EXPR, void_type_node, body, call);
--- 2664,2672 ----
TREE_SIDE_EFFECTS (body) = 1;
/* Now free the environment we allocated. */
! call = build_call_nary (CALL_EXPR, ptr_type_node,
! build_address_of (soft_jnipopsystemframe_node),
! 1, env_var);
TREE_SIDE_EFFECTS (call) = 1;
CAN_COMPLETE_NORMALLY (call) = 1;
body = build2 (COMPOUND_EXPR, void_type_node, body, call);
*************** force_evaluation_order (tree node)
*** 3573,3612 ****
&& TREE_CODE (TREE_OPERAND (node, 0)) == CALL_EXPR
&& TREE_CODE (TREE_OPERAND (node, 1)) == SAVE_EXPR))
{
! tree arg, cmp;
! arg = node;
!
! /* Position arg properly, account for wrapped around ctors. */
if (TREE_CODE (node) == COMPOUND_EXPR)
! arg = TREE_OPERAND (node, 0);
!
! arg = TREE_OPERAND (arg, 1);
!
! /* An empty argument list is ok, just ignore it. */
! if (!arg)
! return node;
! /* Not having a list of arguments here is an error. */
! gcc_assert (TREE_CODE (arg) == TREE_LIST);
/* This reverses the evaluation order. This is a desired effect. */
! for (cmp = NULL_TREE; arg; arg = TREE_CHAIN (arg))
{
/* Promote types smaller than integer. This is required by
some ABIs. */
! tree type = TREE_TYPE (TREE_VALUE (arg));
tree saved;
if (targetm.calls.promote_prototypes (type)
&& INTEGRAL_TYPE_P (type)
&& INT_CST_LT_UNSIGNED (TYPE_SIZE (type),
TYPE_SIZE (integer_type_node)))
! TREE_VALUE (arg) = fold_convert (integer_type_node, TREE_VALUE (arg));
! saved = save_expr (force_evaluation_order (TREE_VALUE (arg)));
cmp = (cmp == NULL_TREE ? saved :
build2 (COMPOUND_EXPR, void_type_node, cmp, saved));
! TREE_VALUE (arg) = saved;
}
if (cmp && TREE_CODE (cmp) == COMPOUND_EXPR)
--- 3541,3576 ----
&& TREE_CODE (TREE_OPERAND (node, 0)) == CALL_EXPR
&& TREE_CODE (TREE_OPERAND (node, 1)) == SAVE_EXPR))
{
! tree call, cmp;
! int i, nargs;
! /* Account for wrapped around ctors. */
if (TREE_CODE (node) == COMPOUND_EXPR)
! call = TREE_OPERAND (node, 0);
! else
! call = node;
! nargs = call_expr_nargs (call);
/* This reverses the evaluation order. This is a desired effect. */
! for (i = 0, cmp = NULL_TREE; i < nargs; i++)
{
+ tree arg = CALL_EXPR_ARG (call, i);
/* Promote types smaller than integer. This is required by
some ABIs. */
! tree type = TREE_TYPE (arg);
tree saved;
if (targetm.calls.promote_prototypes (type)
&& INTEGRAL_TYPE_P (type)
&& INT_CST_LT_UNSIGNED (TYPE_SIZE (type),
TYPE_SIZE (integer_type_node)))
! arg = fold_convert (integer_type_node, arg);
! saved = save_expr (force_evaluation_order (arg));
cmp = (cmp == NULL_TREE ? saved :
build2 (COMPOUND_EXPR, void_type_node, cmp, saved));
!
! CALL_EXPR_ARG (call, i) = saved;
}
if (cmp && TREE_CODE (cmp) == COMPOUND_EXPR)
Index: gcc/java/parse.h
===================================================================
*** gcc/java/parse.h (revision 115887)
--- gcc/java/parse.h (working copy)
*************** typedef struct jdeplist_s jdeplist;
*** 681,689 ****
#define BUILD_THROW(WHERE, WHAT) \
{ \
(WHERE) = \
! build3 (CALL_EXPR, void_type_node, \
! build_address_of (throw_node), \
! build_tree_list (NULL_TREE, (WHAT)), NULL_TREE); \
TREE_SIDE_EFFECTS ((WHERE)) = 1; \
}
--- 681,689 ----
#define BUILD_THROW(WHERE, WHAT) \
{ \
(WHERE) = \
! build_call_nary (CALL_EXPR, void_type_node, \
! build_address_of (throw_node), \
! 1, (WHAT)); \
TREE_SIDE_EFFECTS ((WHERE)) = 1; \
}
Index: gcc/java/java-tree.h
===================================================================
*** gcc/java/java-tree.h (revision 115887)
--- gcc/java/java-tree.h (working copy)
*************** extern tree *type_map;
*** 1813,1832 ****
#define BUILD_MONITOR_ENTER(WHERE, ARG) \
{ \
! (WHERE) = build3 (CALL_EXPR, int_type_node, \
! build_address_of (soft_monitorenter_node), \
! build_tree_list (NULL_TREE, (ARG)), \
! NULL_TREE); \
TREE_SIDE_EFFECTS (WHERE) = 1; \
}
! #define BUILD_MONITOR_EXIT(WHERE, ARG) \
! { \
! (WHERE) = build3 (CALL_EXPR, int_type_node, \
! build_address_of (soft_monitorexit_node), \
! build_tree_list (NULL_TREE, (ARG)), \
! NULL_TREE); \
! TREE_SIDE_EFFECTS (WHERE) = 1; \
}
/* Nonzero if TYPE is an unchecked exception */
--- 1813,1830 ----
#define BUILD_MONITOR_ENTER(WHERE, ARG) \
{ \
! (WHERE) = build_call_nary (CALL_EXPR, int_type_node, \
! build_address_of (soft_monitorenter_node), \
! 1, (ARG)); \
TREE_SIDE_EFFECTS (WHERE) = 1; \
}
! #define BUILD_MONITOR_EXIT(WHERE, ARG) \
! { \
! (WHERE) = build_call_nary (CALL_EXPR, int_type_node, \
! build_address_of (soft_monitorexit_node), \
! 1, (ARG)); \
! TREE_SIDE_EFFECTS (WHERE) = 1; \
}
/* Nonzero if TYPE is an unchecked exception */
Index: gcc/java/jcf-write.c
===================================================================
*** gcc/java/jcf-write.c (revision 115887)
--- gcc/java/jcf-write.c (working copy)
*************** generate_bytecode_insns (tree exp, int t
*** 2528,2543 ****
/* ... fall though ... */
case CALL_EXPR:
{
! tree f = TREE_OPERAND (exp, 0);
! tree x = TREE_OPERAND (exp, 1);
int save_SP = state->code_SP;
int nargs;
if (TREE_CODE (f) == ADDR_EXPR)
f = TREE_OPERAND (f, 0);
if (f == soft_newarray_node)
{
! int type_code = TREE_INT_CST_LOW (TREE_VALUE (x));
! generate_bytecode_insns (TREE_VALUE (TREE_CHAIN (x)),
STACK_TARGET, state);
RESERVE (2);
OP1 (OPCODE_newarray);
--- 2528,2544 ----
/* ... fall though ... */
case CALL_EXPR:
{
! tree f = CALL_EXPR_FN (exp);
int save_SP = state->code_SP;
int nargs;
+ call_expr_arg_iterator iter;
+ tree arg;
if (TREE_CODE (f) == ADDR_EXPR)
f = TREE_OPERAND (f, 0);
if (f == soft_newarray_node)
{
! int type_code = TREE_INT_CST_LOW (CALL_EXPR_ARG0 (exp));
! generate_bytecode_insns (CALL_EXPR_ARG1 (exp),
STACK_TARGET, state);
RESERVE (2);
OP1 (OPCODE_newarray);
*************** generate_bytecode_insns (tree exp, int t
*** 2548,2561 ****
{
int ndims;
int idim;
int index = find_class_constant (&state->cpool,
TREE_TYPE (TREE_TYPE (exp)));
! x = TREE_CHAIN (x); /* Skip class argument. */
! ndims = TREE_INT_CST_LOW (TREE_VALUE (x));
! for (idim = ndims; --idim >= 0; )
{
! x = TREE_CHAIN (x);
! generate_bytecode_insns (TREE_VALUE (x), STACK_TARGET, state);
}
RESERVE (4);
OP1 (OPCODE_multianewarray);
--- 2549,2563 ----
{
int ndims;
int idim;
+ int i;
int index = find_class_constant (&state->cpool,
TREE_TYPE (TREE_TYPE (exp)));
! /* Skip class argument. */
! ndims = TREE_INT_CST_LOW (CALL_EXPR_ARG1 (exp));
! for (i = 2, idim = ndims; --idim >= 0; i++)
{
! arg = CALL_EXPR_ARG (exp, i);
! generate_bytecode_insns (arg, STACK_TARGET, state);
}
RESERVE (4);
OP1 (OPCODE_multianewarray);
*************** generate_bytecode_insns (tree exp, int t
*** 2568,2574 ****
{
tree cl = TYPE_ARRAY_ELEMENT (TREE_TYPE (TREE_TYPE (exp)));
int index = find_class_constant (&state->cpool, TREE_TYPE (cl));
! generate_bytecode_insns (TREE_VALUE (x), STACK_TARGET, state);
RESERVE (3);
OP1 (OPCODE_anewarray);
OP2 (index);
--- 2570,2577 ----
{
tree cl = TYPE_ARRAY_ELEMENT (TREE_TYPE (TREE_TYPE (exp)));
int index = find_class_constant (&state->cpool, TREE_TYPE (cl));
! generate_bytecode_insns (CALL_EXPR_ARG0 (exp),
! STACK_TARGET, state);
RESERVE (3);
OP1 (OPCODE_anewarray);
OP2 (index);
*************** generate_bytecode_insns (tree exp, int t
*** 2584,2599 ****
op = OPCODE_monitorexit;
else
op = OPCODE_athrow;
! generate_bytecode_insns (TREE_VALUE (x), STACK_TARGET, state);
RESERVE (1);
OP1 (op);
NOTE_POP (1);
break;
}
! for ( ; x != NULL_TREE; x = TREE_CHAIN (x))
! {
! generate_bytecode_insns (TREE_VALUE (x), STACK_TARGET, state);
! }
nargs = state->code_SP - save_SP;
state->code_SP = save_SP;
if (f == soft_fmod_node)
--- 2587,2601 ----
op = OPCODE_monitorexit;
else
op = OPCODE_athrow;
! generate_bytecode_insns (CALL_EXPR_ARG0 (exp),
! STACK_TARGET, state);
RESERVE (1);
OP1 (op);
NOTE_POP (1);
break;
}
! FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
! generate_bytecode_insns (arg, STACK_TARGET, state);
nargs = state->code_SP - save_SP;
state->code_SP = save_SP;
if (f == soft_fmod_node)
*************** generate_bytecode_insns (tree exp, int t
*** 2619,2625 ****
&& ! METHOD_PRIVATE (f)
&& DECL_CONTEXT (f) != object_type_node)
{
! tree arg1 = TREE_VALUE (TREE_OPERAND (exp, 1));
context = TREE_TYPE (TREE_TYPE (arg1));
}
--- 2621,2627 ----
&& ! METHOD_PRIVATE (f)
&& DECL_CONTEXT (f) != object_type_node)
{
! tree arg1 = CALL_EXPR_ARG0 (exp);
context = TREE_TYPE (TREE_TYPE (arg1));
}
Index: gcc/cp/call.c
===================================================================
*** gcc/cp/call.c (revision 115887)
--- gcc/cp/call.c (working copy)
*************** build_call (tree function, tree parms)
*** 334,340 ****
TREE_VALUE (tmp), t);
}
! function = build3 (CALL_EXPR, result_type, function, parms, NULL_TREE);
TREE_HAS_CONSTRUCTOR (function) = is_constructor;
TREE_NOTHROW (function) = nothrow;
--- 334,340 ----
TREE_VALUE (tmp), t);
}
! function = build_call_list (CALL_EXPR, result_type, function, parms);
TREE_HAS_CONSTRUCTOR (function) = is_constructor;
TREE_NOTHROW (function) = nothrow;
*************** build_over_call (struct z_candidate *can
*** 4703,4709 ****
tree expr;
tree return_type;
return_type = TREE_TYPE (TREE_TYPE (fn));
! expr = build3 (CALL_EXPR, return_type, fn, args, NULL_TREE);
if (TREE_THIS_VOLATILE (fn) && cfun)
current_function_returns_abnormally = 1;
if (!VOID_TYPE_P (return_type))
--- 4703,4709 ----
tree expr;
tree return_type;
return_type = TREE_TYPE (TREE_TYPE (fn));
! expr = build_call_list (CALL_EXPR, return_type, fn, args);
if (TREE_THIS_VOLATILE (fn) && cfun)
current_function_returns_abnormally = 1;
if (!VOID_TYPE_P (return_type))
*************** build_java_interface_fn_ref (tree fn, tr
*** 5091,5097 ****
lookup_fn = build1 (ADDR_EXPR,
build_pointer_type (TREE_TYPE (java_iface_lookup_fn)),
java_iface_lookup_fn);
! return build3 (CALL_EXPR, ptr_type_node, lookup_fn, lookup_args, NULL_TREE);
}
/* Returns the value to use for the in-charge parameter when making a
--- 5091,5097 ----
lookup_fn = build1 (ADDR_EXPR,
build_pointer_type (TREE_TYPE (java_iface_lookup_fn)),
java_iface_lookup_fn);
! return build_call_list (CALL_EXPR, ptr_type_node, lookup_fn, lookup_args);
}
/* Returns the value to use for the in-charge parameter when making a
*************** build_new_method_call (tree instance, tr
*** 5502,5511 ****
}
if (processing_template_decl && call != error_mark_node)
! call = (build_min_non_dep
(CALL_EXPR, call,
build_min_nt (COMPONENT_REF, orig_instance, orig_fns, NULL_TREE),
! orig_args, NULL_TREE));
/* Free all the conversions we allocated. */
obstack_free (&conversion_obstack, p);
--- 5502,5511 ----
}
if (processing_template_decl && call != error_mark_node)
! call = (build_min_non_dep_call_list
(CALL_EXPR, call,
build_min_nt (COMPONENT_REF, orig_instance, orig_fns, NULL_TREE),
! orig_args));
/* Free all the conversions we allocated. */
obstack_free (&conversion_obstack, p);
Index: gcc/cp/tree.c
===================================================================
*** gcc/cp/tree.c (revision 115887)
--- gcc/cp/tree.c (working copy)
*************** build_cplus_new (tree type, tree init)
*** 304,311 ****
type, don't mess with AGGR_INIT_EXPR. */
if (is_ctor || TREE_ADDRESSABLE (type))
{
! rval = build3 (AGGR_INIT_EXPR, void_type_node, fn,
! CALL_EXPR_ARGS (init), slot);
TREE_SIDE_EFFECTS (rval) = 1;
AGGR_INIT_VIA_CTOR_P (rval) = is_ctor;
}
--- 304,312 ----
type, don't mess with AGGR_INIT_EXPR. */
if (is_ctor || TREE_ADDRESSABLE (type))
{
! rval = build_call_list (AGGR_INIT_EXPR, void_type_node, fn,
! CALL_EXPR_ARGS (init));
! AGGR_INIT_EXPR_SLOT (rval) = slot;
TREE_SIDE_EFFECTS (rval) = 1;
AGGR_INIT_VIA_CTOR_P (rval) = is_ctor;
}
*************** break_out_target_exprs (tree t)
*** 1278,1284 ****
/* Similar to `build_nt', but for template definitions of dependent
expressions */
- /* FIXME: This can't handle the new CALL_EXPR representation. */
tree
build_min_nt (enum tree_code code, ...)
--- 1279,1284 ----
*************** build_min_nt (enum tree_code code, ...)
*** 1288,1293 ****
--- 1288,1295 ----
int i;
va_list p;
+ gcc_assert (TREE_CODE_CLASS (code) != tcc_vl_exp);
+
va_start (p, code);
t = make_node (code);
*************** build_min_nt (enum tree_code code, ...)
*** 1303,1310 ****
return t;
}
/* Similar to `build', but for template definitions. */
- /* FIXME: This can't handle the new CALL_EXPR representation. */
tree
build_min (enum tree_code code, tree tt, ...)
--- 1305,1320 ----
return t;
}
+ /* Similar to `build_nt_call_list', but for template definitions of
+ dependent expressions. */
+ tree
+ build_min_nt_call_list (enum tree_code code, tree fn, tree arglist)
+ {
+ return build_nt_call_list (code, fn, arglist);
+ }
+
+
/* Similar to `build', but for template definitions. */
tree
build_min (enum tree_code code, tree tt, ...)
*************** build_min (enum tree_code code, tree tt,
*** 1314,1319 ****
--- 1324,1331 ----
int i;
va_list p;
+ gcc_assert (TREE_CODE_CLASS (code) != tcc_vl_exp);
+
va_start (p, tt);
t = make_node (code);
*************** build_min (enum tree_code code, tree tt,
*** 1335,1341 ****
/* Similar to `build', but for template definitions of non-dependent
expressions. NON_DEP is the non-dependent expression that has been
built. */
- /* FIXME: This can't handle the new CALL_EXPR representation. */
tree
build_min_non_dep (enum tree_code code, tree non_dep, ...)
--- 1347,1352 ----
*************** build_min_non_dep (enum tree_code code,
*** 1345,1350 ****
--- 1356,1363 ----
int i;
va_list p;
+ gcc_assert (TREE_CODE_CLASS (code) != tcc_vl_exp);
+
va_start (p, non_dep);
t = make_node (code);
*************** build_min_non_dep (enum tree_code code,
*** 1367,1372 ****
--- 1380,1399 ----
return t;
}
+ /* Similar to `build_call_list', but for template definitions of non-dependent
+ expressions. NON_DEP is the non-dependent expression that has been
+ built. */
+
+ tree
+ build_min_non_dep_call_list (enum tree_code code, tree non_dep,
+ tree fn, tree arglist)
+ {
+ tree t = build_nt_call_list (code, fn, arglist);
+ TREE_TYPE (t) = TREE_TYPE (non_dep);
+ TREE_SIDE_EFFECTS (t) = TREE_SIDE_EFFECTS (non_dep);
+ return t;
+ }
+
tree
get_type_decl (tree t)
{
Index: gcc/cp/cp-tree.h
===================================================================
*** gcc/cp/cp-tree.h (revision 115887)
--- gcc/cp/cp-tree.h (working copy)
*************** struct template_info GTY(())
*** 2348,2353 ****
--- 2348,2360 ----
#define AGGR_INIT_VIA_CTOR_P(NODE) \
TREE_LANG_FLAG_0 (AGGR_INIT_EXPR_CHECK (NODE))
+ /* Accessor for the "slot" of an AGGR_INIT_EXPR node. It shares the
+ storage that is used for the static chain field in other tcc_vl_exp
+ nodes. */
+
+ #define AGGR_INIT_EXPR_SLOT(NODE) \
+ CALL_EXPR_STATIC_CHAIN (AGGR_INIT_EXPR_CHECK (NODE))
+
/* The TYPE_MAIN_DECL for a class template type is a TYPE_DECL, not a
TEMPLATE_DECL. This macro determines whether or not a given class
type is really a template type, as opposed to an instantiation or
*************** extern cp_lvalue_kind real_lvalue_p (tr
*** 4341,4347 ****
--- 4348,4357 ----
extern bool builtin_valid_in_constant_expr_p (tree);
extern tree build_min (enum tree_code, tree, ...);
extern tree build_min_nt (enum tree_code, ...);
+ extern tree build_min_nt_call_list (enum tree_code, tree, tree);
extern tree build_min_non_dep (enum tree_code, tree, ...);
+ extern tree build_min_non_dep_call_list (enum tree_code, tree,
+ tree, tree);
extern tree build_cplus_new (tree, tree);
extern tree get_target_expr (tree);
extern tree build_cplus_array_type (tree, tree);
Index: gcc/cp/dump.c
===================================================================
*** gcc/cp/dump.c (revision 115887)
--- gcc/cp/dump.c (working copy)
*************** cp_dump_tree (void* dump_info, tree t)
*** 393,399 ****
tree arg;
call_expr_arg_iterator iter;
dump_int (di, "ctor", AGGR_INIT_VIA_CTOR_P (t));
! dump_child ("fn", TREE_OPERAND (t, 0));
FOR_EACH_CALL_EXPR_ARG (arg, iter, t)
{
char buffer[32];
--- 393,399 ----
tree arg;
call_expr_arg_iterator iter;
dump_int (di, "ctor", AGGR_INIT_VIA_CTOR_P (t));
! dump_child ("fn", CALL_EXPR_FN (t));
FOR_EACH_CALL_EXPR_ARG (arg, iter, t)
{
char buffer[32];
*************** cp_dump_tree (void* dump_info, tree t)
*** 401,407 ****
dump_child (buffer, arg);
i++;
}
! dump_child ("decl", TREE_OPERAND (t, 2));
}
break;
--- 401,407 ----
dump_child (buffer, arg);
i++;
}
! dump_child ("decl", AGGR_INIT_EXPR_SLOT (t));
}
break;
Index: gcc/cp/cp-gimplify.c
===================================================================
*** gcc/cp/cp-gimplify.c (revision 115887)
--- gcc/cp/cp-gimplify.c (working copy)
*************** cp_gimplify_init_expr (tree *expr_p, tre
*** 413,419 ****
if (TREE_CODE (sub) == AGGR_INIT_EXPR)
{
gimplify_expr (&to, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
! CALL_EXPR_STATIC_CHAIN (sub) = to;
*expr_p = from;
/* The initialization is now a side-effect, so the container can
--- 413,419 ----
if (TREE_CODE (sub) == AGGR_INIT_EXPR)
{
gimplify_expr (&to, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
! AGGR_INIT_EXPR_SLOT (sub) = to;
*expr_p = from;
/* The initialization is now a side-effect, so the container can
Index: gcc/cp/cxx-pretty-print.c
===================================================================
*** gcc/cp/cxx-pretty-print.c (revision 115887)
--- gcc/cp/cxx-pretty-print.c (working copy)
*************** pp_cxx_postfix_expression (cxx_pretty_pr
*** 430,436 ****
else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fun))
{
tree object = (code == AGGR_INIT_EXPR && AGGR_INIT_VIA_CTOR_P (t)
! ? CALL_EXPR_STATIC_CHAIN (t)
: CALL_EXPR_ARG0 (t));
while (TREE_CODE (object) == NOP_EXPR)
--- 430,436 ----
else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fun))
{
tree object = (code == AGGR_INIT_EXPR && AGGR_INIT_VIA_CTOR_P (t)
! ? AGGR_INIT_EXPR_SLOT (t)
: CALL_EXPR_ARG0 (t));
while (TREE_CODE (object) == NOP_EXPR)
*************** pp_cxx_postfix_expression (cxx_pretty_pr
*** 472,478 ****
if (code == AGGR_INIT_EXPR && AGGR_INIT_VIA_CTOR_P (t))
{
pp_cxx_separate_with (pp, ',');
! pp_cxx_postfix_expression (pp, CALL_EXPR_STATIC_CHAIN (t));
}
break;
--- 472,478 ----
if (code == AGGR_INIT_EXPR && AGGR_INIT_VIA_CTOR_P (t))
{
pp_cxx_separate_with (pp, ',');
! pp_cxx_postfix_expression (pp, AGGR_INIT_EXPR_SLOT (t));
}
break;
Index: gcc/cp/pt.c
===================================================================
*** gcc/cp/pt.c (revision 115887)
--- gcc/cp/pt.c (working copy)
*************** tsubst_copy (tree t, tree args, tsubst_f
*** 7886,7897 ****
case CALL_EXPR:
/* FIXME: It should be possible to do this without consing up
lists for the arguments. */
! return build_nt (code,
! tsubst_copy (CALL_EXPR_FN (t), args,
! complain, in_decl),
! tsubst_copy (CALL_EXPR_ARGS (t), args, complain,
! in_decl),
! NULL_TREE);
case COND_EXPR:
case MODOP_EXPR:
--- 7886,7896 ----
case CALL_EXPR:
/* FIXME: It should be possible to do this without consing up
lists for the arguments. */
! return build_nt_call_list (CALL_EXPR,
! tsubst_copy (CALL_EXPR_FN (t), args,
! complain, in_decl),
! tsubst_copy (CALL_EXPR_ARGS (t), args,
! complain, in_decl));
case COND_EXPR:
case MODOP_EXPR:
Index: gcc/cp/semantics.c
===================================================================
*** gcc/cp/semantics.c (revision 115887)
--- gcc/cp/semantics.c (working copy)
*************** finish_call_expr (tree fn, tree args, bo
*** 1780,1786 ****
if (type_dependent_expression_p (fn)
|| any_type_dependent_arguments_p (args))
{
! result = build_nt (CALL_EXPR, fn, args, NULL_TREE);
KOENIG_LOOKUP_P (result) = koenig_p;
return result;
}
--- 1780,1786 ----
if (type_dependent_expression_p (fn)
|| any_type_dependent_arguments_p (args))
{
! result = build_nt_call_list (CALL_EXPR, fn, args);
KOENIG_LOOKUP_P (result) = koenig_p;
return result;
}
*************** finish_call_expr (tree fn, tree args, bo
*** 1855,1861 ****
if (processing_template_decl)
{
if (type_dependent_expression_p (object))
! return build_nt (CALL_EXPR, orig_fn, orig_args, NULL_TREE);
object = build_non_dependent_expr (object);
}
--- 1855,1861 ----
if (processing_template_decl)
{
if (type_dependent_expression_p (object))
! return build_nt_call_list (CALL_EXPR, orig_fn, orig_args);
object = build_non_dependent_expr (object);
}
*************** finish_call_expr (tree fn, tree args, bo
*** 1899,1906 ****
if (processing_template_decl)
{
! result = build3 (CALL_EXPR, TREE_TYPE (result), orig_fn,
! orig_args, NULL_TREE);
KOENIG_LOOKUP_P (result) = koenig_p;
}
return result;
--- 1899,1906 ----
if (processing_template_decl)
{
! result = build_call_list (CALL_EXPR, TREE_TYPE (result), orig_fn,
! orig_args);
KOENIG_LOOKUP_P (result) = koenig_p;
}
return result;
*************** simplify_aggr_init_expr (tree *tp)
*** 2903,2912 ****
{
tree aggr_init_expr = *tp;
/* Form an appropriate CALL_EXPR. */
tree fn = CALL_EXPR_FN (aggr_init_expr);
tree args = CALL_EXPR_ARGS (aggr_init_expr);
! tree slot = CALL_EXPR_STATIC_CHAIN (aggr_init_expr);
tree type = TREE_TYPE (slot);
tree call_expr;
--- 2903,2913 ----
{
tree aggr_init_expr = *tp;
+ /* FIXME: don't cons up arglist for CALL_EXPR. */
/* Form an appropriate CALL_EXPR. */
tree fn = CALL_EXPR_FN (aggr_init_expr);
tree args = CALL_EXPR_ARGS (aggr_init_expr);
! tree slot = AGGR_INIT_EXPR_SLOT (aggr_init_expr);
tree type = TREE_TYPE (slot);
tree call_expr;
*************** simplify_aggr_init_expr (tree *tp)
*** 2936,2944 ****
args = tree_cons (NULL_TREE, addr, args);
}
! call_expr = build3 (CALL_EXPR,
! TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))),
! fn, args, NULL_TREE);
if (style == arg)
{
--- 2937,2945 ----
args = tree_cons (NULL_TREE, addr, args);
}
! call_expr = build_call_list (CALL_EXPR,
! TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))),
! fn, args);
if (style == arg)
{
Index: gcc/cp/decl2.c
===================================================================
*** gcc/cp/decl2.c (revision 115887)
--- gcc/cp/decl2.c (working copy)
*************** build_offset_ref_call_from_tree (tree fn
*** 3180,3186 ****
|| TREE_CODE (fn) == MEMBER_REF);
if (type_dependent_expression_p (fn)
|| any_type_dependent_arguments_p (args))
! return build_min_nt (CALL_EXPR, fn, args, NULL_TREE);
/* Transform the arguments and add the implicit "this"
parameter. That must be done before the FN is transformed
--- 3180,3186 ----
|| TREE_CODE (fn) == MEMBER_REF);
if (type_dependent_expression_p (fn)
|| any_type_dependent_arguments_p (args))
! return build_min_nt_call_list (CALL_EXPR, fn, args);
/* Transform the arguments and add the implicit "this"
parameter. That must be done before the FN is transformed
*************** build_offset_ref_call_from_tree (tree fn
*** 3210,3216 ****
expr = build_function_call (fn, args);
if (processing_template_decl && expr != error_mark_node)
! return build_min_non_dep (CALL_EXPR, expr, orig_fn, orig_args, NULL_TREE);
return expr;
}
--- 3210,3216 ----
expr = build_function_call (fn, args);
if (processing_template_decl && expr != error_mark_node)
! return build_min_non_dep_call_list (CALL_EXPR, expr, orig_fn, orig_args);
return expr;
}
Index: gcc/cp/parser.c
===================================================================
*** gcc/cp/parser.c (revision 115887)
--- gcc/cp/parser.c (working copy)
*************** cp_parser_postfix_expression (cp_parser
*** 4263,4270 ****
|| any_type_dependent_arguments_p (args)))
{
postfix_expression
! = build_min_nt (CALL_EXPR, postfix_expression,
! args, NULL_TREE);
break;
}
--- 4263,4270 ----
|| any_type_dependent_arguments_p (args)))
{
postfix_expression
! = build_min_nt_call_list (CALL_EXPR, postfix_expression,
! args);
break;
}
Index: gcc/fortran/trans-expr.c
===================================================================
*** gcc/fortran/trans-expr.c (revision 115887)
--- gcc/fortran/trans-expr.c (working copy)
*************** gfc_conv_function_call (gfc_se * se, gfc
*** 2087,2094 ****
}
fntype = TREE_TYPE (TREE_TYPE (se->expr));
! se->expr = build3 (CALL_EXPR, TREE_TYPE (fntype), se->expr,
! arglist, NULL_TREE);
/* If we have a pointer function, but we don't want a pointer, e.g.
something like
--- 2087,2094 ----
}
fntype = TREE_TYPE (TREE_TYPE (se->expr));
! se->expr = build_call_list (CALL_EXPR, TREE_TYPE (fntype), se->expr,
! arglist);
/* If we have a pointer function, but we don't want a pointer, e.g.
something like