+2010-07-13 Nathan Froyd <froydnj@codesourcery.com>
+
+ * tree.h (build_function_call_expr): Delete.
+ (build_call_expr_loc_array): New function.
+ (build_call_expr_loc_vec): New function.
+ * tree-flow.h (struct omp_region): Change type of ws_args field
+ to a VEC.
+ * builtins.c (build_function_call_expr): Delete.
+ (build_call_expr_loc_array): New function.
+ (build_call_expr_loc): Call it. Use XALLOCAVEC.
+ (build_call_expr): Likewise.
+ (build_call_expr_loc_vec): New function.
+ * cgraphunit.c (build_cdtor): Call build_call_expr instead of
+ build_function_call_expr.
+ * expr.c (emutls_var_address): Likewise.
+ * varasm.c (emutls_common_1): Likewise.
+ * omp-low.c (expand_omp_atomic_mutex): Likewise.
+ (expand_omp_taskreg): Adjust for new type of region->ws_args.
+ (get_ws_args_for): Return a VEC instead of a tree.
+ (expand_parallel_call): Call build_call_expr_loc_vec instead of
+ build_function_call_expr.
+ * stor-layout.c (self_referential_size): Likewise.
+
2010-07-13 Jakub Jelinek <jakub@redhat.com>
PR testsuite/44701
}
/* Conveniently construct a function call expression. FNDECL names the
- function to be called and ARGLIST is a TREE_LIST of arguments. */
+ function to be called and N arguments are passed in the array
+ ARGARRAY. */
tree
-build_function_call_expr (location_t loc, tree fndecl, tree arglist)
+build_call_expr_loc_array (location_t loc, tree fndecl, int n, tree *argarray)
{
tree fntype = TREE_TYPE (fndecl);
tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
- int n = list_length (arglist);
- tree *argarray = (tree *) alloca (n * sizeof (tree));
- int i;
-
- for (i = 0; i < n; i++, arglist = TREE_CHAIN (arglist))
- argarray[i] = TREE_VALUE (arglist);
+
return fold_builtin_call_array (loc, TREE_TYPE (fntype), fn, n, argarray);
}
+/* Conveniently construct a function call expression. FNDECL names the
+ function to be called and the arguments are passed in the vector
+ VEC. */
+
+tree
+build_call_expr_loc_vec (location_t loc, tree fndecl, VEC(tree,gc) *vec)
+{
+ return build_call_expr_loc_array (loc, fndecl, VEC_length (tree, vec),
+ VEC_address (tree, vec));
+}
+
+
/* 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. */
build_call_expr_loc (location_t loc, tree fndecl, int n, ...)
{
va_list ap;
- tree fntype = TREE_TYPE (fndecl);
- tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
- tree *argarray = (tree *) alloca (n * sizeof (tree));
+ tree *argarray = XALLOCAVEC (tree, n);
int i;
va_start (ap, n);
for (i = 0; i < n; i++)
argarray[i] = va_arg (ap, tree);
va_end (ap);
- return fold_builtin_call_array (loc, TREE_TYPE (fntype), fn, n, argarray);
+ return build_call_expr_loc_array (loc, fndecl, n, argarray);
}
/* Like build_call_expr_loc (UNKNOWN_LOCATION, ...). Duplicated because
build_call_expr (tree fndecl, int n, ...)
{
va_list ap;
- tree fntype = TREE_TYPE (fndecl);
- tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
- tree *argarray = (tree *) alloca (n * sizeof (tree));
+ tree *argarray = XALLOCAVEC (tree, n);
int i;
va_start (ap, n);
for (i = 0; i < n; i++)
argarray[i] = va_arg (ap, tree);
va_end (ap);
- return fold_builtin_call_array (UNKNOWN_LOCATION, TREE_TYPE (fntype),
- fn, n, argarray);
+ return build_call_expr_loc_array (UNKNOWN_LOCATION, fndecl, n, argarray);
}
/* Construct a CALL_EXPR with type TYPE with FN as the function expression.
do
{
priority_type p;
+ tree call;
fn = cdtors[i];
p = ctor_p ? DECL_INIT_PRIORITY (fn) : DECL_FINI_PRIORITY (fn);
if (!body)
priority = p;
else if (p != priority)
break;
- append_to_statement_list (build_function_call_expr (UNKNOWN_LOCATION,
- fn, 0),
- &body);
+ call = build_call_expr (fn, 0);
+ append_to_statement_list (call, &body);
++i;
}
while (i < len);
tree emuvar = emutls_decl (var);
tree fn = built_in_decls [BUILT_IN_EMUTLS_GET_ADDRESS];
tree arg = build_fold_addr_expr_with_type (emuvar, ptr_type_node);
- tree arglist = build_tree_list (NULL_TREE, arg);
- tree call = build_function_call_expr (UNKNOWN_LOCATION, fn, arglist);
+ tree call = build_call_expr (fn, 1, arg);
return fold_convert (build_pointer_type (TREE_TYPE (var)), call);
}
\f
+2010-07-13 Nathan Froyd <froydnj@codesourcery.com>
+
+ * trans-decl.c (build_entry_thunks): Call build_call_expr_loc_vec
+ instead of build_function_call_expr.
+ * trans-intrinsic.c (gfc_conv_intrinsic_sr_kind): Likewise.
+
2010-07-13 Tobias Burnus <burnus@net-b.de>
Daniel Franke <franke.daniel@gmail.com>
gfc_symbol *thunk_sym;
stmtblock_t body;
tree thunk_fndecl;
- tree args;
- tree string_args;
tree tmp;
locus old_loc;
gfc_get_backend_locus (&old_loc);
for (el = ns->entries; el; el = el->next)
{
+ VEC(tree,gc) *args = NULL;
+ VEC(tree,gc) *string_args = NULL;
+
thunk_sym = el->sym;
build_function_decl (thunk_sym);
/* Pass extra parameter identifying this entry point. */
tmp = build_int_cst (gfc_array_index_type, el->id);
- args = tree_cons (NULL_TREE, tmp, NULL_TREE);
- string_args = NULL_TREE;
+ VEC_safe_push (tree, gc, args, tmp);
if (thunk_sym->attr.function)
{
if (gfc_return_by_reference (ns->proc_name))
{
tree ref = DECL_ARGUMENTS (current_function_decl);
- args = tree_cons (NULL_TREE, ref, args);
+ VEC_safe_push (tree, gc, args, ref);
if (ns->proc_name->ts.type == BT_CHARACTER)
- args = tree_cons (NULL_TREE, TREE_CHAIN (ref),
- args);
+ VEC_safe_push (tree, gc, args, TREE_CHAIN (ref));
}
}
{
/* Pass the argument. */
DECL_ARTIFICIAL (thunk_formal->sym->backend_decl) = 1;
- args = tree_cons (NULL_TREE, thunk_formal->sym->backend_decl,
- args);
+ VEC_safe_push (tree, gc, args, thunk_formal->sym->backend_decl);
if (formal->sym->ts.type == BT_CHARACTER)
{
tmp = thunk_formal->sym->ts.u.cl->backend_decl;
- string_args = tree_cons (NULL_TREE, tmp, string_args);
+ VEC_safe_push (tree, gc, string_args, tmp);
}
}
else
{
/* Pass NULL for a missing argument. */
- args = tree_cons (NULL_TREE, null_pointer_node, args);
+ VEC_safe_push (tree, gc, args, null_pointer_node);
if (formal->sym->ts.type == BT_CHARACTER)
{
tmp = build_int_cst (gfc_charlen_type_node, 0);
- string_args = tree_cons (NULL_TREE, tmp, string_args);
+ VEC_safe_push (tree, gc, string_args, tmp);
}
}
}
/* Call the master function. */
- args = nreverse (args);
- args = chainon (args, nreverse (string_args));
+ VEC_safe_splice (tree, gc, args, string_args);
tmp = ns->proc_name->backend_decl;
- tmp = build_function_call_expr (input_location, tmp, args);
+ tmp = build_call_expr_loc_vec (input_location, tmp, args);
if (ns->proc_name->attr.mixed_entry_master)
{
tree union_decl, field;
gfc_conv_intrinsic_sr_kind (gfc_se *se, gfc_expr *expr)
{
gfc_actual_arglist *actual;
- tree args, type;
+ tree type;
gfc_se argse;
+ VEC(tree,gc) *args = NULL;
- args = NULL_TREE;
for (actual = expr->value.function.actual; actual; actual = actual->next)
{
gfc_init_se (&argse, se);
gfc_add_block_to_block (&se->pre, &argse.pre);
gfc_add_block_to_block (&se->post, &argse.post);
- args = gfc_chainon_list (args, argse.expr);
+ VEC_safe_push (tree, gc, args, argse.expr);
}
/* Convert it to the required type. */
type = gfc_typenode_for_spec (&expr->ts);
- se->expr = build_function_call_expr (input_location,
- gfor_fndecl_sr_kind, args);
+ se->expr = build_call_expr_loc_vec (input_location,
+ gfor_fndecl_sr_kind, args);
se->expr = fold_convert (type, se->expr);
}
parallel+workshare call. WS_STMT is the workshare directive being
expanded. */
-static tree
+static VEC(tree,gc) *
get_ws_args_for (gimple ws_stmt)
{
tree t;
location_t loc = gimple_location (ws_stmt);
+ VEC(tree,gc) *ws_args;
if (gimple_code (ws_stmt) == GIMPLE_OMP_FOR)
{
struct omp_for_data fd;
- tree ws_args;
extract_omp_for_data (ws_stmt, &fd, NULL);
- ws_args = NULL_TREE;
- if (fd.chunk_size)
- {
- t = fold_convert_loc (loc, long_integer_type_node, fd.chunk_size);
- ws_args = tree_cons (NULL, t, ws_args);
- }
+ ws_args = VEC_alloc (tree, gc, 3 + (fd.chunk_size != 0));
- t = fold_convert_loc (loc, long_integer_type_node, fd.loop.step);
- ws_args = tree_cons (NULL, t, ws_args);
+ t = fold_convert_loc (loc, long_integer_type_node, fd.loop.n1);
+ VEC_quick_push (tree, ws_args, t);
t = fold_convert_loc (loc, long_integer_type_node, fd.loop.n2);
- ws_args = tree_cons (NULL, t, ws_args);
+ VEC_quick_push (tree, ws_args, t);
- t = fold_convert_loc (loc, long_integer_type_node, fd.loop.n1);
- ws_args = tree_cons (NULL, t, ws_args);
+ t = fold_convert_loc (loc, long_integer_type_node, fd.loop.step);
+ VEC_quick_push (tree, ws_args, t);
+
+ if (fd.chunk_size)
+ {
+ t = fold_convert_loc (loc, long_integer_type_node, fd.chunk_size);
+ VEC_quick_push (tree, ws_args, t);
+ }
return ws_args;
}
the exit of the sections region. */
basic_block bb = single_succ (gimple_bb (ws_stmt));
t = build_int_cst (unsigned_type_node, EDGE_COUNT (bb->succs) - 1);
- t = tree_cons (NULL, t, NULL);
- return t;
+ ws_args = VEC_alloc (tree, gc, 1);
+ VEC_quick_push (tree, ws_args, t);
+ return ws_args;
}
gcc_unreachable ();
static void
expand_parallel_call (struct omp_region *region, basic_block bb,
- gimple entry_stmt, tree ws_args)
+ gimple entry_stmt, VEC(tree,gc) *ws_args)
{
tree t, t1, t2, val, cond, c, clauses;
gimple_stmt_iterator gsi;
gimple stmt;
int start_ix;
location_t clause_loc;
+ VEC(tree,gc) *args;
clauses = gimple_omp_parallel_clauses (entry_stmt);
t1 = build_fold_addr_expr (t);
t2 = build_fold_addr_expr (gimple_omp_parallel_child_fn (entry_stmt));
- if (ws_args)
- {
- tree args = tree_cons (NULL, t2,
- tree_cons (NULL, t1,
- tree_cons (NULL, val, ws_args)));
- t = build_function_call_expr (UNKNOWN_LOCATION,
- built_in_decls[start_ix], args);
- }
- else
- t = build_call_expr (built_in_decls[start_ix], 3, t2, t1, val);
+ args = VEC_alloc (tree, gc, 3 + VEC_length (tree, ws_args));
+ VEC_quick_push (tree, args, t2);
+ VEC_quick_push (tree, args, t1);
+ VEC_quick_push (tree, args, val);
+ VEC_splice (tree, args, ws_args);
+
+ t = build_call_expr_loc_vec (UNKNOWN_LOCATION,
+ built_in_decls[start_ix], args);
force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
false, GSI_CONTINUE_LINKING);
{
basic_block entry_bb, exit_bb, new_bb;
struct function *child_cfun;
- tree child_fn, block, t, ws_args;
+ tree child_fn, block, t;
tree save_current;
gimple_stmt_iterator gsi;
gimple entry_stmt, stmt;
edge e;
+ VEC(tree,gc) *ws_args;
entry_stmt = last_stmt (region->entry);
child_fn = gimple_omp_taskreg_child_fn (entry_stmt);
if (is_combined_parallel (region))
ws_args = region->ws_args;
else
- ws_args = NULL_TREE;
+ ws_args = NULL;
if (child_cfun->cfg)
{
gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ATOMIC_LOAD);
t = built_in_decls[BUILT_IN_GOMP_ATOMIC_START];
- t = build_function_call_expr (UNKNOWN_LOCATION, t, 0);
+ t = build_call_expr (t, 0);
force_gimple_operand_gsi (&si, t, true, NULL_TREE, true, GSI_SAME_STMT);
stmt = gimple_build_assign (loaded_val, build_simple_mem_ref (addr));
gsi_insert_before (&si, stmt, GSI_SAME_STMT);
t = built_in_decls[BUILT_IN_GOMP_ATOMIC_END];
- t = build_function_call_expr (UNKNOWN_LOCATION, t, 0);
+ t = build_call_expr (t, 0);
force_gimple_operand_gsi (&si, t, true, NULL_TREE, true, GSI_SAME_STMT);
gsi_remove (&si, true);
{
static unsigned HOST_WIDE_INT fnno = 0;
VEC (tree, heap) *self_refs = NULL;
- tree param_type_list = NULL, param_decl_list = NULL, arg_list = NULL;
+ tree param_type_list = NULL, param_decl_list = NULL;
tree t, ref, return_type, fntype, fnname, fndecl;
unsigned int i;
char buf[128];
+ VEC(tree,gc) *args = NULL;
/* Do not factor out simple operations. */
t = skip_simple_arithmetic (size);
/* Build the parameter and argument lists in parallel; also
substitute the former for the latter in the expression. */
+ args = VEC_alloc (tree, gc, VEC_length (tree, self_refs));
for (i = 0; VEC_iterate (tree, self_refs, i, ref); i++)
{
tree subst, param_name, param_type, param_decl;
param_type_list = tree_cons (NULL_TREE, param_type, param_type_list);
param_decl_list = chainon (param_decl, param_decl_list);
- arg_list = tree_cons (NULL_TREE, ref, arg_list);
+ VEC_quick_push (tree, args, ref);
}
VEC_free (tree, heap, self_refs);
/* The 3 lists have been created in reverse order. */
param_type_list = nreverse (param_type_list);
param_decl_list = nreverse (param_decl_list);
- arg_list = nreverse (arg_list);
/* Build the function type. */
return_type = TREE_TYPE (size);
VEC_safe_push (tree, gc, size_functions, fndecl);
/* Replace the original expression with a call to the size function. */
- return build_function_call_expr (UNKNOWN_LOCATION, fndecl, arg_list);
+ return build_call_expr_loc_vec (input_location, fndecl, args);
}
/* Take, queue and compile all the size functions. It is essential that
/* If this is a combined parallel+workshare region, this is a list
of additional arguments needed by the combined parallel+workshare
library call. */
- tree ws_args;
+ VEC(tree,gc) *ws_args;
/* The code for the omp directive of this region. */
enum gimple_code type;
extern tree fold_builtin_snprintf_chk (location_t, tree, tree, enum built_in_function);
extern bool fold_builtin_next_arg (tree, bool);
extern enum built_in_function builtin_mathfn_code (const_tree);
-extern tree build_function_call_expr (location_t, tree, tree);
extern tree fold_builtin_call_array (location_t, tree, tree, int, tree *);
+extern tree build_call_expr_loc_array (location_t, tree, int, tree *);
+extern tree build_call_expr_loc_vec (location_t, tree, VEC(tree,gc) *);
extern tree build_call_expr_loc (location_t, tree, int, ...);
extern tree build_call_expr (tree, int, ...);
extern tree mathfn_built_in (tree, enum built_in_function fn);
emutls_common_1 (void **loc, void *xstmts)
{
struct tree_map *h = *(struct tree_map **) loc;
- tree args, x, *pstmts = (tree *) xstmts;
+ tree x, *pstmts = (tree *) xstmts;
tree word_type_node;
if (! DECL_COMMON (h->base.from)
do this and there is an initializer, -fanchor_section loses,
because it would be too late to ensure the template is
output. */
- x = null_pointer_node;
- args = tree_cons (NULL, x, NULL);
- x = build_int_cst (word_type_node, DECL_ALIGN_UNIT (h->base.from));
- args = tree_cons (NULL, x, args);
- x = fold_convert (word_type_node, DECL_SIZE_UNIT (h->base.from));
- args = tree_cons (NULL, x, args);
- x = build_fold_addr_expr (h->to);
- args = tree_cons (NULL, x, args);
-
x = built_in_decls[BUILT_IN_EMUTLS_REGISTER_COMMON];
- x = build_function_call_expr (UNKNOWN_LOCATION, x, args);
+ x = build_call_expr (x, 4,
+ build_fold_addr_expr (h->to),
+ fold_convert (word_type_node,
+ DECL_SIZE_UNIT (h->base.from)),
+ build_int_cst (word_type_node,
+ DECL_ALIGN_UNIT (h->base.from)),
+ null_pointer_node);
append_to_statement_list (x, pstmts);
return 1;