gcc80: Handle TZ specific "%+" format in strftime.
[dragonfly.git] / contrib / gcc-8.0 / gcc / ipa-param-manipulation.c
1 /* Manipulation of formal and actual parameters of functions and function
2    calls.
3    Copyright (C) 2017-2018 Free Software Foundation, Inc.
4
5 This file is part of GCC.
6
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.
11
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.
16
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/>.  */
20
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"
40
41 /* Return a heap allocated vector containing formal parameters of FNDECL.  */
42
43 vec<tree>
44 ipa_get_vector_of_formal_parms (tree fndecl)
45 {
46   vec<tree> args;
47   int count;
48   tree parm;
49
50   gcc_assert (!flag_wpa);
51   count = 0;
52   for (parm = DECL_ARGUMENTS (fndecl); parm; parm = DECL_CHAIN (parm))
53     count++;
54
55   args.create (count);
56   for (parm = DECL_ARGUMENTS (fndecl); parm; parm = DECL_CHAIN (parm))
57     args.quick_push (parm);
58
59   return args;
60 }
61
62 /* Return a heap allocated vector containing types of formal parameters of
63    function type FNTYPE.  */
64
65 vec<tree>
66 ipa_get_vector_of_formal_parm_types (tree fntype)
67 {
68   vec<tree> types;
69   int count = 0;
70   tree t;
71
72   for (t = TYPE_ARG_TYPES (fntype); t; t = TREE_CHAIN (t))
73     count++;
74
75   types.create (count);
76   for (t = TYPE_ARG_TYPES (fntype); t; t = TREE_CHAIN (t))
77     types.quick_push (TREE_VALUE (t));
78
79   return types;
80 }
81
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.  */
86
87 void
88 ipa_modify_formal_parameters (tree fndecl, ipa_parm_adjustment_vec adjustments)
89 {
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);
93
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)
100     {
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 ());
108     }
109   else
110     {
111       last_parm_void = false;
112       otypes.create (0);
113     }
114
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++)
119     {
120       struct ipa_parm_adjustment *adj;
121       gcc_assert (link);
122
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;
130
131       if (adj->op == IPA_PARM_OP_COPY)
132         {
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);
138         }
139       else if (adj->op != IPA_PARM_OP_REMOVE)
140         {
141           tree new_parm;
142           tree ptype;
143
144           if (adj->by_ref)
145             ptype = build_pointer_type (adj->type);
146           else
147             {
148               ptype = adj->type;
149               if (is_gimple_reg_type (ptype)
150                   && TYPE_MODE (ptype) != BLKmode)
151                 {
152                   unsigned malign = GET_MODE_ALIGNMENT (TYPE_MODE (ptype));
153                   if (TYPE_ALIGN (ptype) != malign)
154                     ptype = build_aligned_type (ptype, malign);
155                 }
156             }
157
158           if (care_for_types)
159             new_arg_types = tree_cons (NULL_TREE, ptype, new_arg_types);
160
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);
171
172           if (adj->op == IPA_PARM_OP_NEW)
173             adj->base = NULL;
174           else
175             adj->base = parm;
176           adj->new_decl = new_parm;
177
178           *link = new_parm;
179           link = &DECL_CHAIN (new_parm);
180         }
181     }
182
183   *link = NULL_TREE;
184
185   tree new_reversed = NULL;
186   if (care_for_types)
187     {
188       new_reversed = nreverse (new_arg_types);
189       if (last_parm_void)
190         {
191           if (new_reversed)
192             TREE_CHAIN (new_arg_types) = void_list_node;
193           else
194             new_reversed = void_list_node;
195         }
196     }
197
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))
207     {
208       new_type = build_distinct_type_copy (orig_type);
209       TYPE_ARG_TYPES (new_type) = new_reversed;
210     }
211   else
212     {
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;
218     }
219
220   /* When signature changes, we need to clear builtin info.  */
221   if (DECL_BUILT_IN (fndecl))
222     {
223       DECL_BUILT_IN_CLASS (fndecl) = NOT_BUILT_IN;
224       DECL_FUNCTION_CODE (fndecl) = (enum built_in_function) 0;
225     }
226
227   TREE_TYPE (fndecl) = new_type;
228   DECL_VIRTUAL_P (fndecl) = 0;
229   DECL_LANG_SPECIFIC (fndecl) = NULL;
230   otypes.release ();
231   oparms.release ();
232 }
233
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.  */
237
238 void
239 ipa_modify_call_arguments (struct cgraph_edge *cs, gcall *stmt,
240                            ipa_parm_adjustment_vec adjustments)
241 {
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;
249
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);
254
255   gsi = gsi_for_stmt (stmt);
256   prev_gsi = gsi;
257   gsi_prev (&prev_gsi);
258   for (i = 0; i < len; i++)
259     {
260       struct ipa_parm_adjustment *adj;
261
262       adj = &adjustments[i];
263
264       if (adj->op == IPA_PARM_OP_COPY)
265         {
266           tree arg = gimple_call_arg (stmt, adj->base_index);
267
268           vargs.quick_push (arg);
269         }
270       else if (adj->op != IPA_PARM_OP_REMOVE)
271         {
272           tree expr, base, off;
273           location_t loc;
274           unsigned int deref_align = 0;
275           bool deref_base = false;
276
277           /* We create a new parameter out of the value of the old one, we can
278              do the following kind of transformations:
279
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).
283
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).
290
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.  */
295
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);
299
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
304             {
305               poly_int64 base_offset;
306               tree prev_base;
307               bool addrof;
308
309               if (TREE_CODE (base) == ADDR_EXPR)
310                 {
311                   base = TREE_OPERAND (base, 0);
312                   addrof = true;
313                 }
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)
320                 {
321                   base = build_fold_addr_expr (prev_base);
322                   off = build_int_cst (adj->alias_ptr_type, byte_offset);
323                 }
324               else if (TREE_CODE (base) == MEM_REF)
325                 {
326                   if (!addrof)
327                     {
328                       deref_base = true;
329                       deref_align = TYPE_ALIGN (TREE_TYPE (base));
330                     }
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);
336                 }
337               else
338                 {
339                   off = build_int_cst (adj->alias_ptr_type,
340                                        base_offset + byte_offset);
341                   base = build_fold_addr_expr (base);
342                 }
343             }
344
345           if (!adj->by_ref)
346             {
347               tree type = adj->type;
348               unsigned int align;
349               unsigned HOST_WIDE_INT misalign;
350
351               if (deref_base)
352                 {
353                   align = deref_align;
354                   misalign = 0;
355                 }
356               else
357                 {
358                   get_pointer_alignment_1 (base, &align, &misalign);
359                   if (TYPE_ALIGN (type) > align)
360                     align = TYPE_ALIGN (type);
361                 }
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)))
377                 {
378                   gimple *tem = gimple_build_assign (NULL_TREE, expr);
379                   if (gimple_in_ssa_p (cfun))
380                     {
381                       gimple_set_vuse (tem, gimple_vuse (stmt));
382                       expr = make_ssa_name (TREE_TYPE (expr), tem);
383                     }
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);
389                 }
390             }
391           else
392             {
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);
398             }
399           vargs.quick_push (expr);
400         }
401       if (adj->op != IPA_PARM_OP_COPY && MAY_HAVE_DEBUG_BIND_STMTS)
402         {
403           unsigned int ix;
404           tree ddecl = NULL_TREE, origin = DECL_ORIGIN (adj->base), arg;
405           gimple *def_temp;
406
407           arg = gimple_call_arg (stmt, adj->base_index);
408           if (!useless_type_conversion_p (TREE_TYPE (origin), TREE_TYPE (arg)))
409             {
410               if (!fold_convertible_p (TREE_TYPE (origin), arg))
411                 continue;
412               arg = fold_convert_loc (gimple_location (stmt),
413                                       TREE_TYPE (origin), arg);
414             }
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)
419               {
420                 ddecl = (**debug_args)[ix + 1];
421                 break;
422               }
423           if (ddecl == NULL)
424             {
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));
429
430               vec_safe_push (*debug_args, origin);
431               vec_safe_push (*debug_args, ddecl);
432             }
433           def_temp = gimple_build_debug_bind (ddecl, unshare_expr (arg), stmt);
434           gsi_insert_before (&gsi, def_temp, GSI_SAME_STMT);
435         }
436     }
437
438   if (dump_file && (dump_flags & TDF_DETAILS))
439     {
440       fprintf (dump_file, "replacing stmt:");
441       print_gimple_stmt (dump_file, gsi_stmt (gsi), 0);
442     }
443
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));
448
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     {
456       gimple_set_vuse (new_stmt, gimple_vuse (stmt));
457       if (gimple_vdef (stmt))
458         {
459           gimple_set_vdef (new_stmt, gimple_vdef (stmt));
460           SSA_NAME_DEF_STMT (gimple_vdef (new_stmt)) = new_stmt;
461         }
462     }
463
464   if (dump_file && (dump_flags & TDF_DETAILS))
465     {
466       fprintf (dump_file, "with stmt:");
467       print_gimple_stmt (dump_file, new_stmt, 0);
468       fprintf (dump_file, "\n");
469     }
470   gsi_replace (&gsi, new_stmt, true);
471   if (cs)
472     cs->set_call_stmt (new_stmt);
473   do
474     {
475       current_node->record_stmt_references (gsi_stmt (gsi));
476       gsi_prev (&gsi);
477     }
478   while (gsi_stmt (gsi) != gsi_stmt (prev_gsi));
479 }
480
481 /* Return true iff BASE_INDEX is in ADJUSTMENTS more than once.  */
482
483 static bool
484 index_in_adjustments_multiple_times_p (int base_index,
485                                        ipa_parm_adjustment_vec adjustments)
486 {
487   int i, len = adjustments.length ();
488   bool one = false;
489
490   for (i = 0; i < len; i++)
491     {
492       struct ipa_parm_adjustment *adj;
493       adj = &adjustments[i];
494
495       if (adj->base_index == base_index)
496         {
497           if (one)
498             return true;
499           else
500             one = true;
501         }
502     }
503   return false;
504 }
505
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.  */
509
510 ipa_parm_adjustment_vec
511 ipa_combine_adjustments (ipa_parm_adjustment_vec inner,
512                          ipa_parm_adjustment_vec outer)
513 {
514   int i, outlen = outer.length ();
515   int inlen = inner.length ();
516   int removals = 0;
517   ipa_parm_adjustment_vec adjustments, tmp;
518
519   tmp.create (inlen);
520   for (i = 0; i < inlen; i++)
521     {
522       struct ipa_parm_adjustment *n;
523       n = &inner[i];
524
525       if (n->op == IPA_PARM_OP_REMOVE)
526         removals++;
527       else
528         {
529           /* FIXME: Handling of new arguments are not implemented yet.  */
530           gcc_assert (n->op != IPA_PARM_OP_NEW);
531           tmp.quick_push (*n);
532         }
533     }
534
535   adjustments.create (outlen + removals);
536   for (i = 0; i < outlen; i++)
537     {
538       struct ipa_parm_adjustment r;
539       struct ipa_parm_adjustment *out = &outer[i];
540       struct ipa_parm_adjustment *in = &tmp[out->base_index];
541
542       memset (&r, 0, sizeof (r));
543       gcc_assert (in->op != IPA_PARM_OP_REMOVE);
544       if (out->op == IPA_PARM_OP_REMOVE)
545         {
546           if (!index_in_adjustments_multiple_times_p (in->base_index, tmp))
547             {
548               r.op = IPA_PARM_OP_REMOVE;
549               adjustments.quick_push (r);
550             }
551           continue;
552         }
553       else
554         {
555           /* FIXME: Handling of new arguments are not implemented yet.  */
556           gcc_assert (out->op != IPA_PARM_OP_NEW);
557         }
558
559       r.base_index = in->base_index;
560       r.type = out->type;
561
562       /* FIXME:  Create nonlocal value too.  */
563
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);
573     }
574
575   for (i = 0; i < inlen; i++)
576     {
577       struct ipa_parm_adjustment *n = &inner[i];
578
579       if (n->op == IPA_PARM_OP_REMOVE)
580         adjustments.quick_push (*n);
581     }
582
583   tmp.release ();
584   return adjustments;
585 }
586
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.  */
591
592 static tree
593 get_ssa_base_param (tree t, bool ignore_default_def)
594 {
595   if (TREE_CODE (t) == SSA_NAME)
596     {
597       if (ignore_default_def || SSA_NAME_IS_DEFAULT_DEF (t))
598         return SSA_NAME_VAR (t);
599       else
600         return NULL_TREE;
601     }
602   return t;
603 }
604
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.
608
609    If IGNORE_DEFAULT_DEF is set, consider SSA_NAMEs which are not a
610    default def, otherwise bail on them.
611
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.  */
615
616 ipa_parm_adjustment *
617 ipa_get_adjustment_candidate (tree **expr, bool *convert,
618                               ipa_parm_adjustment_vec adjustments,
619                               bool ignore_default_def)
620 {
621   if (TREE_CODE (**expr) == BIT_FIELD_REF
622       || TREE_CODE (**expr) == IMAGPART_EXPR
623       || TREE_CODE (**expr) == REALPART_EXPR)
624     {
625       *expr = &TREE_OPERAND (**expr, 0);
626       if (convert)
627         *convert = true;
628     }
629
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;
636
637   if (TREE_CODE (base) == MEM_REF)
638     {
639       offset += mem_ref_offset (base).force_shwi () * BITS_PER_UNIT;
640       base = TREE_OPERAND (base, 0);
641     }
642
643   base = get_ssa_base_param (base, ignore_default_def);
644   if (!base || TREE_CODE (base) != PARM_DECL)
645     return NULL;
646
647   struct ipa_parm_adjustment *cand = NULL;
648   unsigned int len = adjustments.length ();
649   for (unsigned i = 0; i < len; i++)
650     {
651       struct ipa_parm_adjustment *adj = &adjustments[i];
652
653       if (adj->base == base
654           && (known_eq (adj->offset, offset) || adj->op == IPA_PARM_OP_REMOVE))
655         {
656           cand = adj;
657           break;
658         }
659     }
660
661   if (!cand || cand->op == IPA_PARM_OP_COPY || cand->op == IPA_PARM_OP_REMOVE)
662     return NULL;
663   return cand;
664 }
665
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. */
672
673 bool
674 ipa_modify_expr (tree *expr, bool convert,
675                  ipa_parm_adjustment_vec adjustments)
676 {
677   struct ipa_parm_adjustment *cand
678     = ipa_get_adjustment_candidate (&expr, &convert, adjustments, false);
679   if (!cand)
680     return false;
681
682   tree src;
683   if (cand->by_ref)
684     {
685       src = build_simple_mem_ref (cand->new_decl);
686       REF_REVERSE_STORAGE_ORDER (src) = cand->reverse;
687     }
688   else
689     src = cand->new_decl;
690
691   if (dump_file && (dump_flags & TDF_DETAILS))
692     {
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");
698     }
699
700   if (convert && !useless_type_conversion_p (TREE_TYPE (*expr), cand->type))
701     {
702       tree vce = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (*expr), src);
703       *expr = vce;
704     }
705   else
706     *expr = src;
707   return true;
708 }
709
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.  */
712
713 void
714 ipa_dump_param_adjustments (FILE *file, ipa_parm_adjustment_vec adjustments,
715                             tree fndecl)
716 {
717   int i, len = adjustments.length ();
718   bool first = true;
719   vec<tree> parms = ipa_get_vector_of_formal_parms (fndecl);
720
721   fprintf (file, "IPA param adjustments: ");
722   for (i = 0; i < len; i++)
723     {
724       struct ipa_parm_adjustment *adj;
725       adj = &adjustments[i];
726
727       if (!first)
728         fprintf (file, "                 ");
729       else
730         first = false;
731
732       fprintf (file, "%i. base_index: %i - ", i, adj->base_index);
733       print_generic_expr (file, parms[adj->base_index]);
734       if (adj->base)
735         {
736           fprintf (file, ", base: ");
737           print_generic_expr (file, adj->base);
738         }
739       if (adj->new_decl)
740         {
741           fprintf (file, ", new_decl: ");
742           print_generic_expr (file, adj->new_decl);
743         }
744       if (adj->new_ssa_base)
745         {
746           fprintf (file, ", new_ssa_base: ");
747           print_generic_expr (file, adj->new_ssa_base);
748         }
749
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
755         {
756           fprintf (file, ", offset ");
757           print_dec (adj->offset, file);
758         }
759       if (adj->by_ref)
760         fprintf (file, ", by_ref");
761       print_node_brief (file, ", type: ", adj->type, 0);
762       fprintf (file, "\n");
763     }
764   parms.release ();
765 }
766