2017-12-05 Richard Biener <rguenther@suse.de>
[official-gcc.git] / gcc / ipa-param-manipulation.c
blobbedd201f6dd1e9f1a9d7be4680847a76cf5b6420
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 gcc_checking_assert (adj->offset % BITS_PER_UNIT == 0);
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,
304 adj->offset / BITS_PER_UNIT);
305 else
307 HOST_WIDE_INT base_offset;
308 tree prev_base;
309 bool addrof;
311 if (TREE_CODE (base) == ADDR_EXPR)
313 base = TREE_OPERAND (base, 0);
314 addrof = true;
316 else
317 addrof = false;
318 prev_base = base;
319 base = get_addr_base_and_unit_offset (base, &base_offset);
320 /* Aggregate arguments can have non-invariant addresses. */
321 if (!base)
323 base = build_fold_addr_expr (prev_base);
324 off = build_int_cst (adj->alias_ptr_type,
325 adj->offset / BITS_PER_UNIT);
327 else if (TREE_CODE (base) == MEM_REF)
329 if (!addrof)
331 deref_base = true;
332 deref_align = TYPE_ALIGN (TREE_TYPE (base));
334 off = build_int_cst (adj->alias_ptr_type,
335 base_offset
336 + adj->offset / BITS_PER_UNIT);
337 off = int_const_binop (PLUS_EXPR, TREE_OPERAND (base, 1),
338 off);
339 base = TREE_OPERAND (base, 0);
341 else
343 off = build_int_cst (adj->alias_ptr_type,
344 base_offset
345 + adj->offset / BITS_PER_UNIT);
346 base = build_fold_addr_expr (base);
350 if (!adj->by_ref)
352 tree type = adj->type;
353 unsigned int align;
354 unsigned HOST_WIDE_INT misalign;
356 if (deref_base)
358 align = deref_align;
359 misalign = 0;
361 else
363 get_pointer_alignment_1 (base, &align, &misalign);
364 if (TYPE_ALIGN (type) > align)
365 align = TYPE_ALIGN (type);
367 misalign += (offset_int::from (wi::to_wide (off),
368 SIGNED).to_short_addr ()
369 * BITS_PER_UNIT);
370 misalign = misalign & (align - 1);
371 if (misalign != 0)
372 align = least_bit_hwi (misalign);
373 if (align < TYPE_ALIGN (type))
374 type = build_aligned_type (type, align);
375 base = force_gimple_operand_gsi (&gsi, base,
376 true, NULL, true, GSI_SAME_STMT);
377 expr = fold_build2_loc (loc, MEM_REF, type, base, off);
378 REF_REVERSE_STORAGE_ORDER (expr) = adj->reverse;
379 /* If expr is not a valid gimple call argument emit
380 a load into a temporary. */
381 if (is_gimple_reg_type (TREE_TYPE (expr)))
383 gimple *tem = gimple_build_assign (NULL_TREE, expr);
384 if (gimple_in_ssa_p (cfun))
386 gimple_set_vuse (tem, gimple_vuse (stmt));
387 expr = make_ssa_name (TREE_TYPE (expr), tem);
389 else
390 expr = create_tmp_reg (TREE_TYPE (expr));
391 gimple_assign_set_lhs (tem, expr);
392 gsi_insert_before (&gsi, tem, GSI_SAME_STMT);
395 else
397 expr = fold_build2_loc (loc, MEM_REF, adj->type, base, off);
398 REF_REVERSE_STORAGE_ORDER (expr) = adj->reverse;
399 expr = build_fold_addr_expr (expr);
400 expr = force_gimple_operand_gsi (&gsi, expr,
401 true, NULL, true, GSI_SAME_STMT);
403 vargs.quick_push (expr);
405 if (adj->op != IPA_PARM_OP_COPY && MAY_HAVE_DEBUG_STMTS)
407 unsigned int ix;
408 tree ddecl = NULL_TREE, origin = DECL_ORIGIN (adj->base), arg;
409 gimple *def_temp;
411 arg = gimple_call_arg (stmt, adj->base_index);
412 if (!useless_type_conversion_p (TREE_TYPE (origin), TREE_TYPE (arg)))
414 if (!fold_convertible_p (TREE_TYPE (origin), arg))
415 continue;
416 arg = fold_convert_loc (gimple_location (stmt),
417 TREE_TYPE (origin), arg);
419 if (debug_args == NULL)
420 debug_args = decl_debug_args_insert (callee_decl);
421 for (ix = 0; vec_safe_iterate (*debug_args, ix, &ddecl); ix += 2)
422 if (ddecl == origin)
424 ddecl = (**debug_args)[ix + 1];
425 break;
427 if (ddecl == NULL)
429 ddecl = make_node (DEBUG_EXPR_DECL);
430 DECL_ARTIFICIAL (ddecl) = 1;
431 TREE_TYPE (ddecl) = TREE_TYPE (origin);
432 SET_DECL_MODE (ddecl, DECL_MODE (origin));
434 vec_safe_push (*debug_args, origin);
435 vec_safe_push (*debug_args, ddecl);
437 def_temp = gimple_build_debug_bind (ddecl, unshare_expr (arg), stmt);
438 gsi_insert_before (&gsi, def_temp, GSI_SAME_STMT);
442 if (dump_file && (dump_flags & TDF_DETAILS))
444 fprintf (dump_file, "replacing stmt:");
445 print_gimple_stmt (dump_file, gsi_stmt (gsi), 0);
448 new_stmt = gimple_build_call_vec (callee_decl, vargs);
449 vargs.release ();
450 if (gimple_call_lhs (stmt))
451 gimple_call_set_lhs (new_stmt, gimple_call_lhs (stmt));
453 gimple_set_block (new_stmt, gimple_block (stmt));
454 if (gimple_has_location (stmt))
455 gimple_set_location (new_stmt, gimple_location (stmt));
456 gimple_call_set_chain (new_stmt, gimple_call_chain (stmt));
457 gimple_call_copy_flags (new_stmt, stmt);
458 if (gimple_in_ssa_p (cfun))
460 gimple_set_vuse (new_stmt, gimple_vuse (stmt));
461 if (gimple_vdef (stmt))
463 gimple_set_vdef (new_stmt, gimple_vdef (stmt));
464 SSA_NAME_DEF_STMT (gimple_vdef (new_stmt)) = new_stmt;
468 if (dump_file && (dump_flags & TDF_DETAILS))
470 fprintf (dump_file, "with stmt:");
471 print_gimple_stmt (dump_file, new_stmt, 0);
472 fprintf (dump_file, "\n");
474 gsi_replace (&gsi, new_stmt, true);
475 if (cs)
476 cs->set_call_stmt (new_stmt);
479 current_node->record_stmt_references (gsi_stmt (gsi));
480 gsi_prev (&gsi);
482 while (gsi_stmt (gsi) != gsi_stmt (prev_gsi));
485 /* Return true iff BASE_INDEX is in ADJUSTMENTS more than once. */
487 static bool
488 index_in_adjustments_multiple_times_p (int base_index,
489 ipa_parm_adjustment_vec adjustments)
491 int i, len = adjustments.length ();
492 bool one = false;
494 for (i = 0; i < len; i++)
496 struct ipa_parm_adjustment *adj;
497 adj = &adjustments[i];
499 if (adj->base_index == base_index)
501 if (one)
502 return true;
503 else
504 one = true;
507 return false;
510 /* Return adjustments that should have the same effect on function parameters
511 and call arguments as if they were first changed according to adjustments in
512 INNER and then by adjustments in OUTER. */
514 ipa_parm_adjustment_vec
515 ipa_combine_adjustments (ipa_parm_adjustment_vec inner,
516 ipa_parm_adjustment_vec outer)
518 int i, outlen = outer.length ();
519 int inlen = inner.length ();
520 int removals = 0;
521 ipa_parm_adjustment_vec adjustments, tmp;
523 tmp.create (inlen);
524 for (i = 0; i < inlen; i++)
526 struct ipa_parm_adjustment *n;
527 n = &inner[i];
529 if (n->op == IPA_PARM_OP_REMOVE)
530 removals++;
531 else
533 /* FIXME: Handling of new arguments are not implemented yet. */
534 gcc_assert (n->op != IPA_PARM_OP_NEW);
535 tmp.quick_push (*n);
539 adjustments.create (outlen + removals);
540 for (i = 0; i < outlen; i++)
542 struct ipa_parm_adjustment r;
543 struct ipa_parm_adjustment *out = &outer[i];
544 struct ipa_parm_adjustment *in = &tmp[out->base_index];
546 memset (&r, 0, sizeof (r));
547 gcc_assert (in->op != IPA_PARM_OP_REMOVE);
548 if (out->op == IPA_PARM_OP_REMOVE)
550 if (!index_in_adjustments_multiple_times_p (in->base_index, tmp))
552 r.op = IPA_PARM_OP_REMOVE;
553 adjustments.quick_push (r);
555 continue;
557 else
559 /* FIXME: Handling of new arguments are not implemented yet. */
560 gcc_assert (out->op != IPA_PARM_OP_NEW);
563 r.base_index = in->base_index;
564 r.type = out->type;
566 /* FIXME: Create nonlocal value too. */
568 if (in->op == IPA_PARM_OP_COPY && out->op == IPA_PARM_OP_COPY)
569 r.op = IPA_PARM_OP_COPY;
570 else if (in->op == IPA_PARM_OP_COPY)
571 r.offset = out->offset;
572 else if (out->op == IPA_PARM_OP_COPY)
573 r.offset = in->offset;
574 else
575 r.offset = in->offset + out->offset;
576 adjustments.quick_push (r);
579 for (i = 0; i < inlen; i++)
581 struct ipa_parm_adjustment *n = &inner[i];
583 if (n->op == IPA_PARM_OP_REMOVE)
584 adjustments.quick_push (*n);
587 tmp.release ();
588 return adjustments;
591 /* If T is an SSA_NAME, return NULL if it is not a default def or
592 return its base variable if it is. If IGNORE_DEFAULT_DEF is true,
593 the base variable is always returned, regardless if it is a default
594 def. Return T if it is not an SSA_NAME. */
596 static tree
597 get_ssa_base_param (tree t, bool ignore_default_def)
599 if (TREE_CODE (t) == SSA_NAME)
601 if (ignore_default_def || SSA_NAME_IS_DEFAULT_DEF (t))
602 return SSA_NAME_VAR (t);
603 else
604 return NULL_TREE;
606 return t;
609 /* Given an expression, return an adjustment entry specifying the
610 transformation to be done on EXPR. If no suitable adjustment entry
611 was found, returns NULL.
613 If IGNORE_DEFAULT_DEF is set, consider SSA_NAMEs which are not a
614 default def, otherwise bail on them.
616 If CONVERT is non-NULL, this function will set *CONVERT if the
617 expression provided is a component reference. ADJUSTMENTS is the
618 adjustments vector. */
620 ipa_parm_adjustment *
621 ipa_get_adjustment_candidate (tree **expr, bool *convert,
622 ipa_parm_adjustment_vec adjustments,
623 bool ignore_default_def)
625 if (TREE_CODE (**expr) == BIT_FIELD_REF
626 || TREE_CODE (**expr) == IMAGPART_EXPR
627 || TREE_CODE (**expr) == REALPART_EXPR)
629 *expr = &TREE_OPERAND (**expr, 0);
630 if (convert)
631 *convert = true;
634 HOST_WIDE_INT offset, size, max_size;
635 bool reverse;
636 tree base
637 = get_ref_base_and_extent (**expr, &offset, &size, &max_size, &reverse);
638 if (!base || size == -1 || max_size == -1)
639 return NULL;
641 if (TREE_CODE (base) == MEM_REF)
643 offset += mem_ref_offset (base).to_short_addr () * BITS_PER_UNIT;
644 base = TREE_OPERAND (base, 0);
647 base = get_ssa_base_param (base, ignore_default_def);
648 if (!base || TREE_CODE (base) != PARM_DECL)
649 return NULL;
651 struct ipa_parm_adjustment *cand = NULL;
652 unsigned int len = adjustments.length ();
653 for (unsigned i = 0; i < len; i++)
655 struct ipa_parm_adjustment *adj = &adjustments[i];
657 if (adj->base == base
658 && (adj->offset == offset || adj->op == IPA_PARM_OP_REMOVE))
660 cand = adj;
661 break;
665 if (!cand || cand->op == IPA_PARM_OP_COPY || cand->op == IPA_PARM_OP_REMOVE)
666 return NULL;
667 return cand;
670 /* If the expression *EXPR should be replaced by a reduction of a parameter, do
671 so. ADJUSTMENTS is a pointer to a vector of adjustments. CONVERT
672 specifies whether the function should care about type incompatibility the
673 current and new expressions. If it is false, the function will leave
674 incompatibility issues to the caller. Return true iff the expression
675 was modified. */
677 bool
678 ipa_modify_expr (tree *expr, bool convert,
679 ipa_parm_adjustment_vec adjustments)
681 struct ipa_parm_adjustment *cand
682 = ipa_get_adjustment_candidate (&expr, &convert, adjustments, false);
683 if (!cand)
684 return false;
686 tree src;
687 if (cand->by_ref)
689 src = build_simple_mem_ref (cand->new_decl);
690 REF_REVERSE_STORAGE_ORDER (src) = cand->reverse;
692 else
693 src = cand->new_decl;
695 if (dump_file && (dump_flags & TDF_DETAILS))
697 fprintf (dump_file, "About to replace expr ");
698 print_generic_expr (dump_file, *expr);
699 fprintf (dump_file, " with ");
700 print_generic_expr (dump_file, src);
701 fprintf (dump_file, "\n");
704 if (convert && !useless_type_conversion_p (TREE_TYPE (*expr), cand->type))
706 tree vce = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (*expr), src);
707 *expr = vce;
709 else
710 *expr = src;
711 return true;
714 /* Dump the adjustments in the vector ADJUSTMENTS to dump_file in a human
715 friendly way, assuming they are meant to be applied to FNDECL. */
717 void
718 ipa_dump_param_adjustments (FILE *file, ipa_parm_adjustment_vec adjustments,
719 tree fndecl)
721 int i, len = adjustments.length ();
722 bool first = true;
723 vec<tree> parms = ipa_get_vector_of_formal_parms (fndecl);
725 fprintf (file, "IPA param adjustments: ");
726 for (i = 0; i < len; i++)
728 struct ipa_parm_adjustment *adj;
729 adj = &adjustments[i];
731 if (!first)
732 fprintf (file, " ");
733 else
734 first = false;
736 fprintf (file, "%i. base_index: %i - ", i, adj->base_index);
737 print_generic_expr (file, parms[adj->base_index]);
738 if (adj->base)
740 fprintf (file, ", base: ");
741 print_generic_expr (file, adj->base);
743 if (adj->new_decl)
745 fprintf (file, ", new_decl: ");
746 print_generic_expr (file, adj->new_decl);
748 if (adj->new_ssa_base)
750 fprintf (file, ", new_ssa_base: ");
751 print_generic_expr (file, adj->new_ssa_base);
754 if (adj->op == IPA_PARM_OP_COPY)
755 fprintf (file, ", copy_param");
756 else if (adj->op == IPA_PARM_OP_REMOVE)
757 fprintf (file, ", remove_param");
758 else
759 fprintf (file, ", offset %li", (long) adj->offset);
760 if (adj->by_ref)
761 fprintf (file, ", by_ref");
762 print_node_brief (file, ", type: ", adj->type, 0);
763 fprintf (file, "\n");
765 parms.release ();