poly_int: MEM_REF offsets
[official-gcc.git] / gcc / ipa-param-manipulation.c
blobefa1ea27c669c3e65c83ef9b72a5eb23c99c086a
1 /* Manipulation of formal and actual parameters of functions and function
2 calls.
3 Copyright (C) 2017 Free Software Foundation, Inc.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "backend.h"
25 #include "rtl.h"
26 #include "tree.h"
27 #include "gimple.h"
28 #include "ssa.h"
29 #include "cgraph.h"
30 #include "fold-const.h"
31 #include "stor-layout.h"
32 #include "gimplify.h"
33 #include "gimple-iterator.h"
34 #include "gimplify-me.h"
35 #include "tree-dfa.h"
36 #include "ipa-param-manipulation.h"
37 #include "print-tree.h"
38 #include "gimple-pretty-print.h"
39 #include "builtins.h"
41 /* Return a heap allocated vector containing formal parameters of FNDECL. */
43 vec<tree>
44 ipa_get_vector_of_formal_parms (tree fndecl)
46 vec<tree> args;
47 int count;
48 tree parm;
50 gcc_assert (!flag_wpa);
51 count = 0;
52 for (parm = DECL_ARGUMENTS (fndecl); parm; parm = DECL_CHAIN (parm))
53 count++;
55 args.create (count);
56 for (parm = DECL_ARGUMENTS (fndecl); parm; parm = DECL_CHAIN (parm))
57 args.quick_push (parm);
59 return args;
62 /* Return a heap allocated vector containing types of formal parameters of
63 function type FNTYPE. */
65 vec<tree>
66 ipa_get_vector_of_formal_parm_types (tree fntype)
68 vec<tree> types;
69 int count = 0;
70 tree t;
72 for (t = TYPE_ARG_TYPES (fntype); t; t = TREE_CHAIN (t))
73 count++;
75 types.create (count);
76 for (t = TYPE_ARG_TYPES (fntype); t; t = TREE_CHAIN (t))
77 types.quick_push (TREE_VALUE (t));
79 return types;
82 /* Modify the function declaration FNDECL and its type according to the plan in
83 ADJUSTMENTS. It also sets base fields of individual adjustments structures
84 to reflect the actual parameters being modified which are determined by the
85 base_index field. */
87 void
88 ipa_modify_formal_parameters (tree fndecl, ipa_parm_adjustment_vec adjustments)
90 vec<tree> oparms = ipa_get_vector_of_formal_parms (fndecl);
91 tree orig_type = TREE_TYPE (fndecl);
92 tree old_arg_types = TYPE_ARG_TYPES (orig_type);
94 /* The following test is an ugly hack, some functions simply don't have any
95 arguments in their type. This is probably a bug but well... */
96 bool care_for_types = (old_arg_types != NULL_TREE);
97 bool last_parm_void;
98 vec<tree> otypes;
99 if (care_for_types)
101 last_parm_void = (TREE_VALUE (tree_last (old_arg_types))
102 == void_type_node);
103 otypes = ipa_get_vector_of_formal_parm_types (orig_type);
104 if (last_parm_void)
105 gcc_assert (oparms.length () + 1 == otypes.length ());
106 else
107 gcc_assert (oparms.length () == otypes.length ());
109 else
111 last_parm_void = false;
112 otypes.create (0);
115 int len = adjustments.length ();
116 tree *link = &DECL_ARGUMENTS (fndecl);
117 tree new_arg_types = NULL;
118 for (int i = 0; i < len; i++)
120 struct ipa_parm_adjustment *adj;
121 gcc_assert (link);
123 adj = &adjustments[i];
124 tree parm;
125 if (adj->op == IPA_PARM_OP_NEW)
126 parm = NULL;
127 else
128 parm = oparms[adj->base_index];
129 adj->base = parm;
131 if (adj->op == IPA_PARM_OP_COPY)
133 if (care_for_types)
134 new_arg_types = tree_cons (NULL_TREE, otypes[adj->base_index],
135 new_arg_types);
136 *link = parm;
137 link = &DECL_CHAIN (parm);
139 else if (adj->op != IPA_PARM_OP_REMOVE)
141 tree new_parm;
142 tree ptype;
144 if (adj->by_ref)
145 ptype = build_pointer_type (adj->type);
146 else
148 ptype = adj->type;
149 if (is_gimple_reg_type (ptype)
150 && TYPE_MODE (ptype) != BLKmode)
152 unsigned malign = GET_MODE_ALIGNMENT (TYPE_MODE (ptype));
153 if (TYPE_ALIGN (ptype) != malign)
154 ptype = build_aligned_type (ptype, malign);
158 if (care_for_types)
159 new_arg_types = tree_cons (NULL_TREE, ptype, new_arg_types);
161 new_parm = build_decl (UNKNOWN_LOCATION, PARM_DECL, NULL_TREE,
162 ptype);
163 const char *prefix = adj->arg_prefix ? adj->arg_prefix : "SYNTH";
164 DECL_NAME (new_parm) = create_tmp_var_name (prefix);
165 DECL_ARTIFICIAL (new_parm) = 1;
166 DECL_ARG_TYPE (new_parm) = ptype;
167 DECL_CONTEXT (new_parm) = fndecl;
168 TREE_USED (new_parm) = 1;
169 DECL_IGNORED_P (new_parm) = 1;
170 layout_decl (new_parm, 0);
172 if (adj->op == IPA_PARM_OP_NEW)
173 adj->base = NULL;
174 else
175 adj->base = parm;
176 adj->new_decl = new_parm;
178 *link = new_parm;
179 link = &DECL_CHAIN (new_parm);
183 *link = NULL_TREE;
185 tree new_reversed = NULL;
186 if (care_for_types)
188 new_reversed = nreverse (new_arg_types);
189 if (last_parm_void)
191 if (new_reversed)
192 TREE_CHAIN (new_arg_types) = void_list_node;
193 else
194 new_reversed = void_list_node;
198 /* Use copy_node to preserve as much as possible from original type
199 (debug info, attribute lists etc.)
200 Exception is METHOD_TYPEs must have THIS argument.
201 When we are asked to remove it, we need to build new FUNCTION_TYPE
202 instead. */
203 tree new_type = NULL;
204 if (TREE_CODE (orig_type) != METHOD_TYPE
205 || (adjustments[0].op == IPA_PARM_OP_COPY
206 && adjustments[0].base_index == 0))
208 new_type = build_distinct_type_copy (orig_type);
209 TYPE_ARG_TYPES (new_type) = new_reversed;
211 else
213 new_type
214 = build_distinct_type_copy (build_function_type (TREE_TYPE (orig_type),
215 new_reversed));
216 TYPE_CONTEXT (new_type) = TYPE_CONTEXT (orig_type);
217 DECL_VINDEX (fndecl) = NULL_TREE;
220 /* When signature changes, we need to clear builtin info. */
221 if (DECL_BUILT_IN (fndecl))
223 DECL_BUILT_IN_CLASS (fndecl) = NOT_BUILT_IN;
224 DECL_FUNCTION_CODE (fndecl) = (enum built_in_function) 0;
227 TREE_TYPE (fndecl) = new_type;
228 DECL_VIRTUAL_P (fndecl) = 0;
229 DECL_LANG_SPECIFIC (fndecl) = NULL;
230 otypes.release ();
231 oparms.release ();
234 /* Modify actual arguments of a function call CS as indicated in ADJUSTMENTS.
235 If this is a directly recursive call, CS must be NULL. Otherwise it must
236 contain the corresponding call graph edge. */
238 void
239 ipa_modify_call_arguments (struct cgraph_edge *cs, gcall *stmt,
240 ipa_parm_adjustment_vec adjustments)
242 struct cgraph_node *current_node = cgraph_node::get (current_function_decl);
243 vec<tree> vargs;
244 vec<tree, va_gc> **debug_args = NULL;
245 gcall *new_stmt;
246 gimple_stmt_iterator gsi, prev_gsi;
247 tree callee_decl;
248 int i, len;
250 len = adjustments.length ();
251 vargs.create (len);
252 callee_decl = !cs ? gimple_call_fndecl (stmt) : cs->callee->decl;
253 current_node->remove_stmt_references (stmt);
255 gsi = gsi_for_stmt (stmt);
256 prev_gsi = gsi;
257 gsi_prev (&prev_gsi);
258 for (i = 0; i < len; i++)
260 struct ipa_parm_adjustment *adj;
262 adj = &adjustments[i];
264 if (adj->op == IPA_PARM_OP_COPY)
266 tree arg = gimple_call_arg (stmt, adj->base_index);
268 vargs.quick_push (arg);
270 else if (adj->op != IPA_PARM_OP_REMOVE)
272 tree expr, base, off;
273 location_t loc;
274 unsigned int deref_align = 0;
275 bool deref_base = false;
277 /* We create a new parameter out of the value of the old one, we can
278 do the following kind of transformations:
280 - A scalar passed by reference is converted to a scalar passed by
281 value. (adj->by_ref is false and the type of the original
282 actual argument is a pointer to a scalar).
284 - A part of an aggregate is passed instead of the whole aggregate.
285 The part can be passed either by value or by reference, this is
286 determined by value of adj->by_ref. Moreover, the code below
287 handles both situations when the original aggregate is passed by
288 value (its type is not a pointer) and when it is passed by
289 reference (it is a pointer to an aggregate).
291 When the new argument is passed by reference (adj->by_ref is true)
292 it must be a part of an aggregate and therefore we form it by
293 simply taking the address of a reference inside the original
294 aggregate. */
296 poly_int64 byte_offset = exact_div (adj->offset, BITS_PER_UNIT);
297 base = gimple_call_arg (stmt, adj->base_index);
298 loc = DECL_P (base) ? DECL_SOURCE_LOCATION (base)
299 : EXPR_LOCATION (base);
301 if (TREE_CODE (base) != ADDR_EXPR
302 && POINTER_TYPE_P (TREE_TYPE (base)))
303 off = build_int_cst (adj->alias_ptr_type, byte_offset);
304 else
306 poly_int64 base_offset;
307 tree prev_base;
308 bool addrof;
310 if (TREE_CODE (base) == ADDR_EXPR)
312 base = TREE_OPERAND (base, 0);
313 addrof = true;
315 else
316 addrof = false;
317 prev_base = base;
318 base = get_addr_base_and_unit_offset (base, &base_offset);
319 /* Aggregate arguments can have non-invariant addresses. */
320 if (!base)
322 base = build_fold_addr_expr (prev_base);
323 off = build_int_cst (adj->alias_ptr_type, byte_offset);
325 else if (TREE_CODE (base) == MEM_REF)
327 if (!addrof)
329 deref_base = true;
330 deref_align = TYPE_ALIGN (TREE_TYPE (base));
332 off = build_int_cst (adj->alias_ptr_type,
333 base_offset + byte_offset);
334 off = int_const_binop (PLUS_EXPR, TREE_OPERAND (base, 1),
335 off);
336 base = TREE_OPERAND (base, 0);
338 else
340 off = build_int_cst (adj->alias_ptr_type,
341 base_offset + byte_offset);
342 base = build_fold_addr_expr (base);
346 if (!adj->by_ref)
348 tree type = adj->type;
349 unsigned int align;
350 unsigned HOST_WIDE_INT misalign;
352 if (deref_base)
354 align = deref_align;
355 misalign = 0;
357 else
359 get_pointer_alignment_1 (base, &align, &misalign);
360 if (TYPE_ALIGN (type) > align)
361 align = TYPE_ALIGN (type);
363 misalign += (offset_int::from (wi::to_wide (off),
364 SIGNED).to_short_addr ()
365 * BITS_PER_UNIT);
366 misalign = misalign & (align - 1);
367 if (misalign != 0)
368 align = least_bit_hwi (misalign);
369 if (align < TYPE_ALIGN (type))
370 type = build_aligned_type (type, align);
371 base = force_gimple_operand_gsi (&gsi, base,
372 true, NULL, true, GSI_SAME_STMT);
373 expr = fold_build2_loc (loc, MEM_REF, type, base, off);
374 REF_REVERSE_STORAGE_ORDER (expr) = adj->reverse;
375 /* If expr is not a valid gimple call argument emit
376 a load into a temporary. */
377 if (is_gimple_reg_type (TREE_TYPE (expr)))
379 gimple *tem = gimple_build_assign (NULL_TREE, expr);
380 if (gimple_in_ssa_p (cfun))
382 gimple_set_vuse (tem, gimple_vuse (stmt));
383 expr = make_ssa_name (TREE_TYPE (expr), tem);
385 else
386 expr = create_tmp_reg (TREE_TYPE (expr));
387 gimple_assign_set_lhs (tem, expr);
388 gsi_insert_before (&gsi, tem, GSI_SAME_STMT);
391 else
393 expr = fold_build2_loc (loc, MEM_REF, adj->type, base, off);
394 REF_REVERSE_STORAGE_ORDER (expr) = adj->reverse;
395 expr = build_fold_addr_expr (expr);
396 expr = force_gimple_operand_gsi (&gsi, expr,
397 true, NULL, true, GSI_SAME_STMT);
399 vargs.quick_push (expr);
401 if (adj->op != IPA_PARM_OP_COPY && MAY_HAVE_DEBUG_BIND_STMTS)
403 unsigned int ix;
404 tree ddecl = NULL_TREE, origin = DECL_ORIGIN (adj->base), arg;
405 gimple *def_temp;
407 arg = gimple_call_arg (stmt, adj->base_index);
408 if (!useless_type_conversion_p (TREE_TYPE (origin), TREE_TYPE (arg)))
410 if (!fold_convertible_p (TREE_TYPE (origin), arg))
411 continue;
412 arg = fold_convert_loc (gimple_location (stmt),
413 TREE_TYPE (origin), arg);
415 if (debug_args == NULL)
416 debug_args = decl_debug_args_insert (callee_decl);
417 for (ix = 0; vec_safe_iterate (*debug_args, ix, &ddecl); ix += 2)
418 if (ddecl == origin)
420 ddecl = (**debug_args)[ix + 1];
421 break;
423 if (ddecl == NULL)
425 ddecl = make_node (DEBUG_EXPR_DECL);
426 DECL_ARTIFICIAL (ddecl) = 1;
427 TREE_TYPE (ddecl) = TREE_TYPE (origin);
428 SET_DECL_MODE (ddecl, DECL_MODE (origin));
430 vec_safe_push (*debug_args, origin);
431 vec_safe_push (*debug_args, ddecl);
433 def_temp = gimple_build_debug_bind (ddecl, unshare_expr (arg), stmt);
434 gsi_insert_before (&gsi, def_temp, GSI_SAME_STMT);
438 if (dump_file && (dump_flags & TDF_DETAILS))
440 fprintf (dump_file, "replacing stmt:");
441 print_gimple_stmt (dump_file, gsi_stmt (gsi), 0);
444 new_stmt = gimple_build_call_vec (callee_decl, vargs);
445 vargs.release ();
446 if (gimple_call_lhs (stmt))
447 gimple_call_set_lhs (new_stmt, gimple_call_lhs (stmt));
449 gimple_set_block (new_stmt, gimple_block (stmt));
450 if (gimple_has_location (stmt))
451 gimple_set_location (new_stmt, gimple_location (stmt));
452 gimple_call_set_chain (new_stmt, gimple_call_chain (stmt));
453 gimple_call_copy_flags (new_stmt, stmt);
454 if (gimple_in_ssa_p (cfun))
456 gimple_set_vuse (new_stmt, gimple_vuse (stmt));
457 if (gimple_vdef (stmt))
459 gimple_set_vdef (new_stmt, gimple_vdef (stmt));
460 SSA_NAME_DEF_STMT (gimple_vdef (new_stmt)) = new_stmt;
464 if (dump_file && (dump_flags & TDF_DETAILS))
466 fprintf (dump_file, "with stmt:");
467 print_gimple_stmt (dump_file, new_stmt, 0);
468 fprintf (dump_file, "\n");
470 gsi_replace (&gsi, new_stmt, true);
471 if (cs)
472 cs->set_call_stmt (new_stmt);
475 current_node->record_stmt_references (gsi_stmt (gsi));
476 gsi_prev (&gsi);
478 while (gsi_stmt (gsi) != gsi_stmt (prev_gsi));
481 /* Return true iff BASE_INDEX is in ADJUSTMENTS more than once. */
483 static bool
484 index_in_adjustments_multiple_times_p (int base_index,
485 ipa_parm_adjustment_vec adjustments)
487 int i, len = adjustments.length ();
488 bool one = false;
490 for (i = 0; i < len; i++)
492 struct ipa_parm_adjustment *adj;
493 adj = &adjustments[i];
495 if (adj->base_index == base_index)
497 if (one)
498 return true;
499 else
500 one = true;
503 return false;
506 /* Return adjustments that should have the same effect on function parameters
507 and call arguments as if they were first changed according to adjustments in
508 INNER and then by adjustments in OUTER. */
510 ipa_parm_adjustment_vec
511 ipa_combine_adjustments (ipa_parm_adjustment_vec inner,
512 ipa_parm_adjustment_vec outer)
514 int i, outlen = outer.length ();
515 int inlen = inner.length ();
516 int removals = 0;
517 ipa_parm_adjustment_vec adjustments, tmp;
519 tmp.create (inlen);
520 for (i = 0; i < inlen; i++)
522 struct ipa_parm_adjustment *n;
523 n = &inner[i];
525 if (n->op == IPA_PARM_OP_REMOVE)
526 removals++;
527 else
529 /* FIXME: Handling of new arguments are not implemented yet. */
530 gcc_assert (n->op != IPA_PARM_OP_NEW);
531 tmp.quick_push (*n);
535 adjustments.create (outlen + removals);
536 for (i = 0; i < outlen; i++)
538 struct ipa_parm_adjustment r;
539 struct ipa_parm_adjustment *out = &outer[i];
540 struct ipa_parm_adjustment *in = &tmp[out->base_index];
542 memset (&r, 0, sizeof (r));
543 gcc_assert (in->op != IPA_PARM_OP_REMOVE);
544 if (out->op == IPA_PARM_OP_REMOVE)
546 if (!index_in_adjustments_multiple_times_p (in->base_index, tmp))
548 r.op = IPA_PARM_OP_REMOVE;
549 adjustments.quick_push (r);
551 continue;
553 else
555 /* FIXME: Handling of new arguments are not implemented yet. */
556 gcc_assert (out->op != IPA_PARM_OP_NEW);
559 r.base_index = in->base_index;
560 r.type = out->type;
562 /* FIXME: Create nonlocal value too. */
564 if (in->op == IPA_PARM_OP_COPY && out->op == IPA_PARM_OP_COPY)
565 r.op = IPA_PARM_OP_COPY;
566 else if (in->op == IPA_PARM_OP_COPY)
567 r.offset = out->offset;
568 else if (out->op == IPA_PARM_OP_COPY)
569 r.offset = in->offset;
570 else
571 r.offset = in->offset + out->offset;
572 adjustments.quick_push (r);
575 for (i = 0; i < inlen; i++)
577 struct ipa_parm_adjustment *n = &inner[i];
579 if (n->op == IPA_PARM_OP_REMOVE)
580 adjustments.quick_push (*n);
583 tmp.release ();
584 return adjustments;
587 /* If T is an SSA_NAME, return NULL if it is not a default def or
588 return its base variable if it is. If IGNORE_DEFAULT_DEF is true,
589 the base variable is always returned, regardless if it is a default
590 def. Return T if it is not an SSA_NAME. */
592 static tree
593 get_ssa_base_param (tree t, bool ignore_default_def)
595 if (TREE_CODE (t) == SSA_NAME)
597 if (ignore_default_def || SSA_NAME_IS_DEFAULT_DEF (t))
598 return SSA_NAME_VAR (t);
599 else
600 return NULL_TREE;
602 return t;
605 /* Given an expression, return an adjustment entry specifying the
606 transformation to be done on EXPR. If no suitable adjustment entry
607 was found, returns NULL.
609 If IGNORE_DEFAULT_DEF is set, consider SSA_NAMEs which are not a
610 default def, otherwise bail on them.
612 If CONVERT is non-NULL, this function will set *CONVERT if the
613 expression provided is a component reference. ADJUSTMENTS is the
614 adjustments vector. */
616 ipa_parm_adjustment *
617 ipa_get_adjustment_candidate (tree **expr, bool *convert,
618 ipa_parm_adjustment_vec adjustments,
619 bool ignore_default_def)
621 if (TREE_CODE (**expr) == BIT_FIELD_REF
622 || TREE_CODE (**expr) == IMAGPART_EXPR
623 || TREE_CODE (**expr) == REALPART_EXPR)
625 *expr = &TREE_OPERAND (**expr, 0);
626 if (convert)
627 *convert = true;
630 poly_int64 offset, size, max_size;
631 bool reverse;
632 tree base
633 = get_ref_base_and_extent (**expr, &offset, &size, &max_size, &reverse);
634 if (!base || !known_size_p (size) || !known_size_p (max_size))
635 return NULL;
637 if (TREE_CODE (base) == MEM_REF)
639 offset += mem_ref_offset (base).force_shwi () * BITS_PER_UNIT;
640 base = TREE_OPERAND (base, 0);
643 base = get_ssa_base_param (base, ignore_default_def);
644 if (!base || TREE_CODE (base) != PARM_DECL)
645 return NULL;
647 struct ipa_parm_adjustment *cand = NULL;
648 unsigned int len = adjustments.length ();
649 for (unsigned i = 0; i < len; i++)
651 struct ipa_parm_adjustment *adj = &adjustments[i];
653 if (adj->base == base
654 && (known_eq (adj->offset, offset) || adj->op == IPA_PARM_OP_REMOVE))
656 cand = adj;
657 break;
661 if (!cand || cand->op == IPA_PARM_OP_COPY || cand->op == IPA_PARM_OP_REMOVE)
662 return NULL;
663 return cand;
666 /* If the expression *EXPR should be replaced by a reduction of a parameter, do
667 so. ADJUSTMENTS is a pointer to a vector of adjustments. CONVERT
668 specifies whether the function should care about type incompatibility the
669 current and new expressions. If it is false, the function will leave
670 incompatibility issues to the caller. Return true iff the expression
671 was modified. */
673 bool
674 ipa_modify_expr (tree *expr, bool convert,
675 ipa_parm_adjustment_vec adjustments)
677 struct ipa_parm_adjustment *cand
678 = ipa_get_adjustment_candidate (&expr, &convert, adjustments, false);
679 if (!cand)
680 return false;
682 tree src;
683 if (cand->by_ref)
685 src = build_simple_mem_ref (cand->new_decl);
686 REF_REVERSE_STORAGE_ORDER (src) = cand->reverse;
688 else
689 src = cand->new_decl;
691 if (dump_file && (dump_flags & TDF_DETAILS))
693 fprintf (dump_file, "About to replace expr ");
694 print_generic_expr (dump_file, *expr);
695 fprintf (dump_file, " with ");
696 print_generic_expr (dump_file, src);
697 fprintf (dump_file, "\n");
700 if (convert && !useless_type_conversion_p (TREE_TYPE (*expr), cand->type))
702 tree vce = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (*expr), src);
703 *expr = vce;
705 else
706 *expr = src;
707 return true;
710 /* Dump the adjustments in the vector ADJUSTMENTS to dump_file in a human
711 friendly way, assuming they are meant to be applied to FNDECL. */
713 void
714 ipa_dump_param_adjustments (FILE *file, ipa_parm_adjustment_vec adjustments,
715 tree fndecl)
717 int i, len = adjustments.length ();
718 bool first = true;
719 vec<tree> parms = ipa_get_vector_of_formal_parms (fndecl);
721 fprintf (file, "IPA param adjustments: ");
722 for (i = 0; i < len; i++)
724 struct ipa_parm_adjustment *adj;
725 adj = &adjustments[i];
727 if (!first)
728 fprintf (file, " ");
729 else
730 first = false;
732 fprintf (file, "%i. base_index: %i - ", i, adj->base_index);
733 print_generic_expr (file, parms[adj->base_index]);
734 if (adj->base)
736 fprintf (file, ", base: ");
737 print_generic_expr (file, adj->base);
739 if (adj->new_decl)
741 fprintf (file, ", new_decl: ");
742 print_generic_expr (file, adj->new_decl);
744 if (adj->new_ssa_base)
746 fprintf (file, ", new_ssa_base: ");
747 print_generic_expr (file, adj->new_ssa_base);
750 if (adj->op == IPA_PARM_OP_COPY)
751 fprintf (file, ", copy_param");
752 else if (adj->op == IPA_PARM_OP_REMOVE)
753 fprintf (file, ", remove_param");
754 else
756 fprintf (file, ", offset ");
757 print_dec (adj->offset, file);
759 if (adj->by_ref)
760 fprintf (file, ", by_ref");
761 print_node_brief (file, ", type: ", adj->type, 0);
762 fprintf (file, "\n");
764 parms.release ();