[Ada] New aspect/pragma No_Caching for analysis of volatile data
[official-gcc.git] / gcc / ipa-param-manipulation.c
blob11908d31a566945f621949ea53f9cd448db63be2
1 /* Manipulation of formal and actual parameters of functions and function
2 calls.
3 Copyright (C) 2017-2019 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 (fndecl_built_in_p (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 = gimple_location (stmt);
300 if (TREE_CODE (base) != ADDR_EXPR
301 && POINTER_TYPE_P (TREE_TYPE (base)))
302 off = build_int_cst (adj->alias_ptr_type, byte_offset);
303 else
305 poly_int64 base_offset;
306 tree prev_base;
307 bool addrof;
309 if (TREE_CODE (base) == ADDR_EXPR)
311 base = TREE_OPERAND (base, 0);
312 addrof = true;
314 else
315 addrof = false;
316 prev_base = base;
317 base = get_addr_base_and_unit_offset (base, &base_offset);
318 /* Aggregate arguments can have non-invariant addresses. */
319 if (!base)
321 base = build_fold_addr_expr (prev_base);
322 off = build_int_cst (adj->alias_ptr_type, byte_offset);
324 else if (TREE_CODE (base) == MEM_REF)
326 if (!addrof)
328 deref_base = true;
329 deref_align = TYPE_ALIGN (TREE_TYPE (base));
331 off = build_int_cst (adj->alias_ptr_type,
332 base_offset + byte_offset);
333 off = int_const_binop (PLUS_EXPR, TREE_OPERAND (base, 1),
334 off);
335 base = TREE_OPERAND (base, 0);
337 else
339 off = build_int_cst (adj->alias_ptr_type,
340 base_offset + byte_offset);
341 base = build_fold_addr_expr (base);
345 if (!adj->by_ref)
347 tree type = adj->type;
348 unsigned int align;
349 unsigned HOST_WIDE_INT misalign;
351 if (deref_base)
353 align = deref_align;
354 misalign = 0;
356 else
358 get_pointer_alignment_1 (base, &align, &misalign);
359 if (TYPE_ALIGN (type) > align)
360 align = TYPE_ALIGN (type);
362 misalign += (offset_int::from (wi::to_wide (off),
363 SIGNED).to_short_addr ()
364 * BITS_PER_UNIT);
365 misalign = misalign & (align - 1);
366 if (misalign != 0)
367 align = least_bit_hwi (misalign);
368 if (align < TYPE_ALIGN (type))
369 type = build_aligned_type (type, align);
370 base = force_gimple_operand_gsi (&gsi, base,
371 true, NULL, true, GSI_SAME_STMT);
372 expr = fold_build2_loc (loc, MEM_REF, type, base, off);
373 REF_REVERSE_STORAGE_ORDER (expr) = adj->reverse;
374 /* If expr is not a valid gimple call argument emit
375 a load into a temporary. */
376 if (is_gimple_reg_type (TREE_TYPE (expr)))
378 gimple *tem = gimple_build_assign (NULL_TREE, expr);
379 if (gimple_in_ssa_p (cfun))
381 gimple_set_vuse (tem, gimple_vuse (stmt));
382 expr = make_ssa_name (TREE_TYPE (expr), tem);
384 else
385 expr = create_tmp_reg (TREE_TYPE (expr));
386 gimple_assign_set_lhs (tem, expr);
387 gimple_set_location (tem, loc);
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))
455 gimple_move_vops (new_stmt, stmt);
457 if (dump_file && (dump_flags & TDF_DETAILS))
459 fprintf (dump_file, "with stmt:");
460 print_gimple_stmt (dump_file, new_stmt, 0);
461 fprintf (dump_file, "\n");
463 gsi_replace (&gsi, new_stmt, true);
464 if (cs)
465 cs->set_call_stmt (new_stmt);
468 current_node->record_stmt_references (gsi_stmt (gsi));
469 gsi_prev (&gsi);
471 while (gsi_stmt (gsi) != gsi_stmt (prev_gsi));
474 /* Return true iff BASE_INDEX is in ADJUSTMENTS more than once. */
476 static bool
477 index_in_adjustments_multiple_times_p (int base_index,
478 ipa_parm_adjustment_vec adjustments)
480 int i, len = adjustments.length ();
481 bool one = false;
483 for (i = 0; i < len; i++)
485 struct ipa_parm_adjustment *adj;
486 adj = &adjustments[i];
488 if (adj->base_index == base_index)
490 if (one)
491 return true;
492 else
493 one = true;
496 return false;
499 /* Return adjustments that should have the same effect on function parameters
500 and call arguments as if they were first changed according to adjustments in
501 INNER and then by adjustments in OUTER. */
503 ipa_parm_adjustment_vec
504 ipa_combine_adjustments (ipa_parm_adjustment_vec inner,
505 ipa_parm_adjustment_vec outer)
507 int i, outlen = outer.length ();
508 int inlen = inner.length ();
509 int removals = 0;
510 ipa_parm_adjustment_vec adjustments, tmp;
512 tmp.create (inlen);
513 for (i = 0; i < inlen; i++)
515 struct ipa_parm_adjustment *n;
516 n = &inner[i];
518 if (n->op == IPA_PARM_OP_REMOVE)
519 removals++;
520 else
522 /* FIXME: Handling of new arguments are not implemented yet. */
523 gcc_assert (n->op != IPA_PARM_OP_NEW);
524 tmp.quick_push (*n);
528 adjustments.create (outlen + removals);
529 for (i = 0; i < outlen; i++)
531 struct ipa_parm_adjustment r;
532 struct ipa_parm_adjustment *out = &outer[i];
533 struct ipa_parm_adjustment *in = &tmp[out->base_index];
535 memset (&r, 0, sizeof (r));
536 gcc_assert (in->op != IPA_PARM_OP_REMOVE);
537 if (out->op == IPA_PARM_OP_REMOVE)
539 if (!index_in_adjustments_multiple_times_p (in->base_index, tmp))
541 r.op = IPA_PARM_OP_REMOVE;
542 adjustments.quick_push (r);
544 continue;
546 else
548 /* FIXME: Handling of new arguments are not implemented yet. */
549 gcc_assert (out->op != IPA_PARM_OP_NEW);
552 r.base_index = in->base_index;
553 r.type = out->type;
555 /* FIXME: Create nonlocal value too. */
557 if (in->op == IPA_PARM_OP_COPY && out->op == IPA_PARM_OP_COPY)
558 r.op = IPA_PARM_OP_COPY;
559 else if (in->op == IPA_PARM_OP_COPY)
560 r.offset = out->offset;
561 else if (out->op == IPA_PARM_OP_COPY)
562 r.offset = in->offset;
563 else
564 r.offset = in->offset + out->offset;
565 adjustments.quick_push (r);
568 for (i = 0; i < inlen; i++)
570 struct ipa_parm_adjustment *n = &inner[i];
572 if (n->op == IPA_PARM_OP_REMOVE)
573 adjustments.quick_push (*n);
576 tmp.release ();
577 return adjustments;
580 /* If T is an SSA_NAME, return NULL if it is not a default def or
581 return its base variable if it is. If IGNORE_DEFAULT_DEF is true,
582 the base variable is always returned, regardless if it is a default
583 def. Return T if it is not an SSA_NAME. */
585 static tree
586 get_ssa_base_param (tree t, bool ignore_default_def)
588 if (TREE_CODE (t) == SSA_NAME)
590 if (ignore_default_def || SSA_NAME_IS_DEFAULT_DEF (t))
591 return SSA_NAME_VAR (t);
592 else
593 return NULL_TREE;
595 return t;
598 /* Given an expression, return an adjustment entry specifying the
599 transformation to be done on EXPR. If no suitable adjustment entry
600 was found, returns NULL.
602 If IGNORE_DEFAULT_DEF is set, consider SSA_NAMEs which are not a
603 default def, otherwise bail on them.
605 If CONVERT is non-NULL, this function will set *CONVERT if the
606 expression provided is a component reference. ADJUSTMENTS is the
607 adjustments vector. */
609 ipa_parm_adjustment *
610 ipa_get_adjustment_candidate (tree **expr, bool *convert,
611 ipa_parm_adjustment_vec adjustments,
612 bool ignore_default_def)
614 if (TREE_CODE (**expr) == BIT_FIELD_REF
615 || TREE_CODE (**expr) == IMAGPART_EXPR
616 || TREE_CODE (**expr) == REALPART_EXPR)
618 *expr = &TREE_OPERAND (**expr, 0);
619 if (convert)
620 *convert = true;
623 poly_int64 offset, size, max_size;
624 bool reverse;
625 tree base
626 = get_ref_base_and_extent (**expr, &offset, &size, &max_size, &reverse);
627 if (!base || !known_size_p (size) || !known_size_p (max_size))
628 return NULL;
630 if (TREE_CODE (base) == MEM_REF)
632 offset += mem_ref_offset (base).force_shwi () * BITS_PER_UNIT;
633 base = TREE_OPERAND (base, 0);
636 base = get_ssa_base_param (base, ignore_default_def);
637 if (!base || TREE_CODE (base) != PARM_DECL)
638 return NULL;
640 struct ipa_parm_adjustment *cand = NULL;
641 unsigned int len = adjustments.length ();
642 for (unsigned i = 0; i < len; i++)
644 struct ipa_parm_adjustment *adj = &adjustments[i];
646 if (adj->base == base
647 && (known_eq (adj->offset, offset) || adj->op == IPA_PARM_OP_REMOVE))
649 cand = adj;
650 break;
654 if (!cand || cand->op == IPA_PARM_OP_COPY || cand->op == IPA_PARM_OP_REMOVE)
655 return NULL;
656 return cand;
659 /* If the expression *EXPR should be replaced by a reduction of a parameter, do
660 so. ADJUSTMENTS is a pointer to a vector of adjustments. CONVERT
661 specifies whether the function should care about type incompatibility the
662 current and new expressions. If it is false, the function will leave
663 incompatibility issues to the caller. Return true iff the expression
664 was modified. */
666 bool
667 ipa_modify_expr (tree *expr, bool convert,
668 ipa_parm_adjustment_vec adjustments)
670 struct ipa_parm_adjustment *cand
671 = ipa_get_adjustment_candidate (&expr, &convert, adjustments, false);
672 if (!cand)
673 return false;
675 tree src;
676 if (cand->by_ref)
678 src = build_simple_mem_ref (cand->new_decl);
679 REF_REVERSE_STORAGE_ORDER (src) = cand->reverse;
681 else
682 src = cand->new_decl;
684 if (dump_file && (dump_flags & TDF_DETAILS))
686 fprintf (dump_file, "About to replace expr ");
687 print_generic_expr (dump_file, *expr);
688 fprintf (dump_file, " with ");
689 print_generic_expr (dump_file, src);
690 fprintf (dump_file, "\n");
693 if (convert && !useless_type_conversion_p (TREE_TYPE (*expr), cand->type))
695 tree vce = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (*expr), src);
696 *expr = vce;
698 else
699 *expr = src;
700 return true;
703 /* Dump the adjustments in the vector ADJUSTMENTS to dump_file in a human
704 friendly way, assuming they are meant to be applied to FNDECL. */
706 void
707 ipa_dump_param_adjustments (FILE *file, ipa_parm_adjustment_vec adjustments,
708 tree fndecl)
710 int i, len = adjustments.length ();
711 bool first = true;
712 vec<tree> parms = ipa_get_vector_of_formal_parms (fndecl);
714 fprintf (file, "IPA param adjustments: ");
715 for (i = 0; i < len; i++)
717 struct ipa_parm_adjustment *adj;
718 adj = &adjustments[i];
720 if (!first)
721 fprintf (file, " ");
722 else
723 first = false;
725 fprintf (file, "%i. base_index: %i - ", i, adj->base_index);
726 print_generic_expr (file, parms[adj->base_index]);
727 if (adj->base)
729 fprintf (file, ", base: ");
730 print_generic_expr (file, adj->base);
732 if (adj->new_decl)
734 fprintf (file, ", new_decl: ");
735 print_generic_expr (file, adj->new_decl);
737 if (adj->new_ssa_base)
739 fprintf (file, ", new_ssa_base: ");
740 print_generic_expr (file, adj->new_ssa_base);
743 if (adj->op == IPA_PARM_OP_COPY)
744 fprintf (file, ", copy_param");
745 else if (adj->op == IPA_PARM_OP_REMOVE)
746 fprintf (file, ", remove_param");
747 else
749 fprintf (file, ", offset ");
750 print_dec (adj->offset, file);
752 if (adj->by_ref)
753 fprintf (file, ", by_ref");
754 print_node_brief (file, ", type: ", adj->type, 0);
755 fprintf (file, "\n");
757 parms.release ();