aarch64 - Set the mode for the unspec in speculation_tracker insn.
[platform/upstream/linaro-gcc.git] / gcc / ree.c
1 /* Redundant Extension Elimination pass for the GNU compiler.
2    Copyright (C) 2010-2016 Free Software Foundation, Inc.
3    Contributed by Ilya Enkovich (ilya.enkovich@intel.com)
4
5    Based on the Redundant Zero-extension elimination pass contributed by
6    Sriraman Tallam (tmsriram@google.com) and Silvius Rus (rus@google.com).
7
8 This file is part of GCC.
9
10 GCC is free software; you can redistribute it and/or modify it under
11 the terms of the GNU General Public License as published by the Free
12 Software Foundation; either version 3, or (at your option) any later
13 version.
14
15 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
16 WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with GCC; see the file COPYING3.  If not see
22 <http://www.gnu.org/licenses/>.  */
23
24
25 /* Problem Description :
26    --------------------
27    This pass is intended to remove redundant extension instructions.
28    Such instructions appear for different reasons.  We expect some of
29    them due to implicit zero-extension in 64-bit registers after writing
30    to their lower 32-bit half (e.g. for the x86-64 architecture).
31    Another possible reason is a type cast which follows a load (for
32    instance a register restore) and which can be combined into a single
33    instruction, and for which earlier local passes, e.g. the combiner,
34    weren't able to optimize.
35
36    How does this pass work  ?
37    --------------------------
38
39    This pass is run after register allocation.  Hence, all registers that
40    this pass deals with are hard registers.  This pass first looks for an
41    extension instruction that could possibly be redundant.  Such extension
42    instructions show up in RTL with the pattern  :
43    (set (reg:<SWI248> x) (any_extend:<SWI248> (reg:<SWI124> x))),
44    where x can be any hard register.
45    Now, this pass tries to eliminate this instruction by merging the
46    extension with the definitions of register x.  For instance, if
47    one of the definitions of register x was  :
48    (set (reg:SI x) (plus:SI (reg:SI z1) (reg:SI z2))),
49    followed by extension  :
50    (set (reg:DI x) (zero_extend:DI (reg:SI x)))
51    then the combination converts this into :
52    (set (reg:DI x) (zero_extend:DI (plus:SI (reg:SI z1) (reg:SI z2)))).
53    If all the merged definitions are recognizable assembly instructions,
54    the extension is effectively eliminated.
55
56    For example, for the x86-64 architecture, implicit zero-extensions
57    are captured with appropriate patterns in the i386.md file.  Hence,
58    these merged definition can be matched to a single assembly instruction.
59    The original extension instruction is then deleted if all the
60    definitions can be merged.
61
62    However, there are cases where the definition instruction cannot be
63    merged with an extension.  Examples are CALL instructions.  In such
64    cases, the original extension is not redundant and this pass does
65    not delete it.
66
67    Handling conditional moves :
68    ----------------------------
69
70    Architectures like x86-64 support conditional moves whose semantics for
71    extension differ from the other instructions.  For instance, the
72    instruction *cmov ebx, eax*
73    zero-extends eax onto rax only when the move from ebx to eax happens.
74    Otherwise, eax may not be zero-extended.  Consider conditional moves as
75    RTL instructions of the form
76    (set (reg:SI x) (if_then_else (cond) (reg:SI y) (reg:SI z))).
77    This pass tries to merge an extension with a conditional move by
78    actually merging the definitions of y and z with an extension and then
79    converting the conditional move into :
80    (set (reg:DI x) (if_then_else (cond) (reg:DI y) (reg:DI z))).
81    Since registers y and z are extended, register x will also be extended
82    after the conditional move.  Note that this step has to be done
83    transitively since the definition of a conditional copy can be
84    another conditional copy.
85
86    Motivating Example I :
87    ---------------------
88    For this program :
89    **********************************************
90    bad_code.c
91
92    int mask[1000];
93
94    int foo(unsigned x)
95    {
96      if (x < 10)
97        x = x * 45;
98      else
99        x = x * 78;
100      return mask[x];
101    }
102    **********************************************
103
104    $ gcc -O2 bad_code.c
105      ........
106      400315:       b8 4e 00 00 00          mov    $0x4e,%eax
107      40031a:       0f af f8                imul   %eax,%edi
108      40031d:       89 ff                   mov    %edi,%edi - useless extension
109      40031f:       8b 04 bd 60 19 40 00    mov    0x401960(,%rdi,4),%eax
110      400326:       c3                      retq
111      ......
112      400330:       ba 2d 00 00 00          mov    $0x2d,%edx
113      400335:       0f af fa                imul   %edx,%edi
114      400338:       89 ff                   mov    %edi,%edi - useless extension
115      40033a:       8b 04 bd 60 19 40 00    mov    0x401960(,%rdi,4),%eax
116      400341:       c3                      retq
117
118    $ gcc -O2 -free bad_code.c
119      ......
120      400315:       6b ff 4e                imul   $0x4e,%edi,%edi
121      400318:       8b 04 bd 40 19 40 00    mov    0x401940(,%rdi,4),%eax
122      40031f:       c3                      retq
123      400320:       6b ff 2d                imul   $0x2d,%edi,%edi
124      400323:       8b 04 bd 40 19 40 00    mov    0x401940(,%rdi,4),%eax
125      40032a:       c3                      retq
126
127    Motivating Example II :
128    ---------------------
129
130    Here is an example with a conditional move.
131
132    For this program :
133    **********************************************
134
135    unsigned long long foo(unsigned x , unsigned y)
136    {
137      unsigned z;
138      if (x > 100)
139        z = x + y;
140      else
141        z = x - y;
142      return (unsigned long long)(z);
143    }
144
145    $ gcc -O2 bad_code.c
146      ............
147      400360:       8d 14 3e                lea    (%rsi,%rdi,1),%edx
148      400363:       89 f8                   mov    %edi,%eax
149      400365:       29 f0                   sub    %esi,%eax
150      400367:       83 ff 65                cmp    $0x65,%edi
151      40036a:       0f 43 c2                cmovae %edx,%eax
152      40036d:       89 c0                   mov    %eax,%eax - useless extension
153      40036f:       c3                      retq
154
155    $ gcc -O2 -free bad_code.c
156      .............
157      400360:       89 fa                   mov    %edi,%edx
158      400362:       8d 04 3e                lea    (%rsi,%rdi,1),%eax
159      400365:       29 f2                   sub    %esi,%edx
160      400367:       83 ff 65                cmp    $0x65,%edi
161      40036a:       89 d6                   mov    %edx,%esi
162      40036c:       48 0f 42 c6             cmovb  %rsi,%rax
163      400370:       c3                      retq
164
165   Motivating Example III :
166   ---------------------
167
168   Here is an example with a type cast.
169
170   For this program :
171   **********************************************
172
173   void test(int size, unsigned char *in, unsigned char *out)
174   {
175     int i;
176     unsigned char xr, xg, xy=0;
177
178     for (i = 0; i < size; i++) {
179       xr = *in++;
180       xg = *in++;
181       xy = (unsigned char) ((19595*xr + 38470*xg) >> 16);
182       *out++ = xy;
183     }
184   }
185
186   $ gcc -O2 bad_code.c
187     ............
188     10:   0f b6 0e                movzbl (%rsi),%ecx
189     13:   0f b6 46 01             movzbl 0x1(%rsi),%eax
190     17:   48 83 c6 02             add    $0x2,%rsi
191     1b:   0f b6 c9                movzbl %cl,%ecx - useless extension
192     1e:   0f b6 c0                movzbl %al,%eax - useless extension
193     21:   69 c9 8b 4c 00 00       imul   $0x4c8b,%ecx,%ecx
194     27:   69 c0 46 96 00 00       imul   $0x9646,%eax,%eax
195
196    $ gcc -O2 -free bad_code.c
197      .............
198     10:   0f b6 0e                movzbl (%rsi),%ecx
199     13:   0f b6 46 01             movzbl 0x1(%rsi),%eax
200     17:   48 83 c6 02             add    $0x2,%rsi
201     1b:   69 c9 8b 4c 00 00       imul   $0x4c8b,%ecx,%ecx
202     21:   69 c0 46 96 00 00       imul   $0x9646,%eax,%eax
203
204    Usefulness :
205    ----------
206
207    The original redundant zero-extension elimination pass reported reduction
208    of the dynamic instruction count of a compression benchmark by 2.8% and
209    improvement of its run time by about 1%.
210
211    The additional performance gain with the enhanced pass is mostly expected
212    on in-order architectures where redundancy cannot be compensated by out of
213    order execution.  Measurements showed up to 10% performance gain (reduced
214    run time) on EEMBC 2.0 benchmarks on Atom processor with geomean performance
215    gain 1%.  */
216
217
218 #include "config.h"
219 #include "system.h"
220 #include "coretypes.h"
221 #include "backend.h"
222 #include "target.h"
223 #include "rtl.h"
224 #include "tree.h"
225 #include "df.h"
226 #include "tm_p.h"
227 #include "optabs.h"
228 #include "emit-rtl.h"
229 #include "recog.h"
230 #include "cfgrtl.h"
231 #include "expr.h"
232 #include "tree-pass.h"
233
234 /* This structure represents a candidate for elimination.  */
235
236 struct ext_cand
237 {
238   /* The expression.  */
239   const_rtx expr;
240
241   /* The kind of extension.  */
242   enum rtx_code code;
243
244   /* The destination mode.  */
245   machine_mode mode;
246
247   /* The instruction where it lives.  */
248   rtx_insn *insn;
249 };
250
251
252 static int max_insn_uid;
253
254 /* Update or remove REG_EQUAL or REG_EQUIV notes for INSN.  */
255
256 static bool
257 update_reg_equal_equiv_notes (rtx_insn *insn, machine_mode new_mode,
258                               machine_mode old_mode, enum rtx_code code)
259 {
260   rtx *loc = &REG_NOTES (insn);
261   while (*loc)
262     {
263       enum reg_note kind = REG_NOTE_KIND (*loc);
264       if (kind == REG_EQUAL || kind == REG_EQUIV)
265         {
266           rtx orig_src = XEXP (*loc, 0);
267           /* Update equivalency constants.  Recall that RTL constants are
268              sign-extended.  */
269           if (GET_CODE (orig_src) == CONST_INT
270               && HOST_BITS_PER_WIDE_INT >= GET_MODE_BITSIZE (new_mode))
271             {
272               if (INTVAL (orig_src) >= 0 || code == SIGN_EXTEND)
273                 /* Nothing needed.  */;
274               else
275                 {
276                   /* Zero-extend the negative constant by masking out the
277                      bits outside the source mode.  */
278                   rtx new_const_int
279                     = gen_int_mode (INTVAL (orig_src)
280                                     & GET_MODE_MASK (old_mode),
281                                     new_mode);
282                   if (!validate_change (insn, &XEXP (*loc, 0),
283                                         new_const_int, true))
284                     return false;
285                 }
286               loc = &XEXP (*loc, 1);
287             }
288           /* Drop all other notes, they assume a wrong mode.  */
289           else if (!validate_change (insn, loc, XEXP (*loc, 1), true))
290             return false;
291         }
292       else
293         loc = &XEXP (*loc, 1);
294     }
295   return true;
296 }
297
298 /* Given a insn (CURR_INSN), an extension candidate for removal (CAND)
299    and a pointer to the SET rtx (ORIG_SET) that needs to be modified,
300    this code modifies the SET rtx to a new SET rtx that extends the
301    right hand expression into a register on the left hand side.  Note
302    that multiple assumptions are made about the nature of the set that
303    needs to be true for this to work and is called from merge_def_and_ext.
304
305    Original :
306    (set (reg a) (expression))
307
308    Transform :
309    (set (reg a) (any_extend (expression)))
310
311    Special Cases :
312    If the expression is a constant or another extension, then directly
313    assign it to the register.  */
314
315 static bool
316 combine_set_extension (ext_cand *cand, rtx_insn *curr_insn, rtx *orig_set)
317 {
318   rtx orig_src = SET_SRC (*orig_set);
319   machine_mode orig_mode = GET_MODE (SET_DEST (*orig_set));
320   rtx new_set;
321   rtx cand_pat = PATTERN (cand->insn);
322
323   /* If the extension's source/destination registers are not the same
324      then we need to change the original load to reference the destination
325      of the extension.  Then we need to emit a copy from that destination
326      to the original destination of the load.  */
327   rtx new_reg;
328   bool copy_needed
329     = (REGNO (SET_DEST (cand_pat)) != REGNO (XEXP (SET_SRC (cand_pat), 0)));
330   if (copy_needed)
331     new_reg = gen_rtx_REG (cand->mode, REGNO (SET_DEST (cand_pat)));
332   else
333     new_reg = gen_rtx_REG (cand->mode, REGNO (SET_DEST (*orig_set)));
334
335   /* Merge constants by directly moving the constant into the register under
336      some conditions.  Recall that RTL constants are sign-extended.  */
337   if (GET_CODE (orig_src) == CONST_INT
338       && HOST_BITS_PER_WIDE_INT >= GET_MODE_BITSIZE (cand->mode))
339     {
340       if (INTVAL (orig_src) >= 0 || cand->code == SIGN_EXTEND)
341         new_set = gen_rtx_SET (new_reg, orig_src);
342       else
343         {
344           /* Zero-extend the negative constant by masking out the bits outside
345              the source mode.  */
346           rtx new_const_int
347             = gen_int_mode (INTVAL (orig_src) & GET_MODE_MASK (orig_mode),
348                             GET_MODE (new_reg));
349           new_set = gen_rtx_SET (new_reg, new_const_int);
350         }
351     }
352   else if (GET_MODE (orig_src) == VOIDmode)
353     {
354       /* This is mostly due to a call insn that should not be optimized.  */
355       return false;
356     }
357   else if (GET_CODE (orig_src) == cand->code)
358     {
359       /* Here is a sequence of two extensions.  Try to merge them.  */
360       rtx temp_extension
361         = gen_rtx_fmt_e (cand->code, cand->mode, XEXP (orig_src, 0));
362       rtx simplified_temp_extension = simplify_rtx (temp_extension);
363       if (simplified_temp_extension)
364         temp_extension = simplified_temp_extension;
365       new_set = gen_rtx_SET (new_reg, temp_extension);
366     }
367   else if (GET_CODE (orig_src) == IF_THEN_ELSE)
368     {
369       /* Only IF_THEN_ELSE of phi-type copies are combined.  Otherwise,
370          in general, IF_THEN_ELSE should not be combined.  */
371       return false;
372     }
373   else
374     {
375       /* This is the normal case.  */
376       rtx temp_extension
377         = gen_rtx_fmt_e (cand->code, cand->mode, orig_src);
378       rtx simplified_temp_extension = simplify_rtx (temp_extension);
379       if (simplified_temp_extension)
380         temp_extension = simplified_temp_extension;
381       new_set = gen_rtx_SET (new_reg, temp_extension);
382     }
383
384   /* This change is a part of a group of changes.  Hence,
385      validate_change will not try to commit the change.  */
386   if (validate_change (curr_insn, orig_set, new_set, true)
387       && update_reg_equal_equiv_notes (curr_insn, cand->mode, orig_mode,
388                                        cand->code))
389     {
390       if (dump_file)
391         {
392           fprintf (dump_file,
393                    "Tentatively merged extension with definition %s:\n",
394                    (copy_needed) ? "(copy needed)" : "");
395           print_rtl_single (dump_file, curr_insn);
396         }
397       return true;
398     }
399
400   return false;
401 }
402
403 /* Treat if_then_else insns, where the operands of both branches
404    are registers, as copies.  For instance,
405    Original :
406    (set (reg:SI a) (if_then_else (cond) (reg:SI b) (reg:SI c)))
407    Transformed :
408    (set (reg:DI a) (if_then_else (cond) (reg:DI b) (reg:DI c)))
409    DEF_INSN is the if_then_else insn.  */
410
411 static bool
412 transform_ifelse (ext_cand *cand, rtx_insn *def_insn)
413 {
414   rtx set_insn = PATTERN (def_insn);
415   rtx srcreg, dstreg, srcreg2;
416   rtx map_srcreg, map_dstreg, map_srcreg2;
417   rtx ifexpr;
418   rtx cond;
419   rtx new_set;
420
421   gcc_assert (GET_CODE (set_insn) == SET);
422
423   cond = XEXP (SET_SRC (set_insn), 0);
424   dstreg = SET_DEST (set_insn);
425   srcreg = XEXP (SET_SRC (set_insn), 1);
426   srcreg2 = XEXP (SET_SRC (set_insn), 2);
427   /* If the conditional move already has the right or wider mode,
428      there is nothing to do.  */
429   if (GET_MODE_SIZE (GET_MODE (dstreg)) >= GET_MODE_SIZE (cand->mode))
430     return true;
431
432   map_srcreg = gen_rtx_REG (cand->mode, REGNO (srcreg));
433   map_srcreg2 = gen_rtx_REG (cand->mode, REGNO (srcreg2));
434   map_dstreg = gen_rtx_REG (cand->mode, REGNO (dstreg));
435   ifexpr = gen_rtx_IF_THEN_ELSE (cand->mode, cond, map_srcreg, map_srcreg2);
436   new_set = gen_rtx_SET (map_dstreg, ifexpr);
437
438   if (validate_change (def_insn, &PATTERN (def_insn), new_set, true)
439       && update_reg_equal_equiv_notes (def_insn, cand->mode, GET_MODE (dstreg),
440                                        cand->code))
441     {
442       if (dump_file)
443         {
444           fprintf (dump_file,
445                    "Mode of conditional move instruction extended:\n");
446           print_rtl_single (dump_file, def_insn);
447         }
448       return true;
449     }
450
451   return false;
452 }
453
454 /* Get all the reaching definitions of an instruction.  The definitions are
455    desired for REG used in INSN.  Return the definition list or NULL if a
456    definition is missing.  If DEST is non-NULL, additionally push the INSN
457    of the definitions onto DEST.  */
458
459 static struct df_link *
460 get_defs (rtx_insn *insn, rtx reg, vec<rtx_insn *> *dest)
461 {
462   df_ref use;
463   struct df_link *ref_chain, *ref_link;
464
465   FOR_EACH_INSN_USE (use, insn)
466     {
467       if (GET_CODE (DF_REF_REG (use)) == SUBREG)
468         return NULL;
469       if (REGNO (DF_REF_REG (use)) == REGNO (reg))
470         break;
471     }
472
473   gcc_assert (use != NULL);
474
475   ref_chain = DF_REF_CHAIN (use);
476
477   for (ref_link = ref_chain; ref_link; ref_link = ref_link->next)
478     {
479       /* Problem getting some definition for this instruction.  */
480       if (ref_link->ref == NULL)
481         return NULL;
482       if (DF_REF_INSN_INFO (ref_link->ref) == NULL)
483         return NULL;
484       /* As global regs are assumed to be defined at each function call
485          dataflow can report a call_insn as being a definition of REG.
486          But we can't do anything with that in this pass so proceed only
487          if the instruction really sets REG in a way that can be deduced
488          from the RTL structure.  */
489       if (global_regs[REGNO (reg)]
490           && !set_of (reg, DF_REF_INSN (ref_link->ref)))
491         return NULL;
492     }
493
494   if (dest)
495     for (ref_link = ref_chain; ref_link; ref_link = ref_link->next)
496       dest->safe_push (DF_REF_INSN (ref_link->ref));
497
498   return ref_chain;
499 }
500
501 /* Return true if INSN is
502      (SET (reg REGNO (def_reg)) (if_then_else (cond) (REG x1) (REG x2)))
503    and store x1 and x2 in REG_1 and REG_2.  */
504
505 static bool
506 is_cond_copy_insn (rtx_insn *insn, rtx *reg1, rtx *reg2)
507 {
508   rtx expr = single_set (insn);
509
510   if (expr != NULL_RTX
511       && GET_CODE (expr) == SET
512       && GET_CODE (SET_DEST (expr)) == REG
513       && GET_CODE (SET_SRC (expr))  == IF_THEN_ELSE
514       && GET_CODE (XEXP (SET_SRC (expr), 1)) == REG
515       && GET_CODE (XEXP (SET_SRC (expr), 2)) == REG)
516     {
517       *reg1 = XEXP (SET_SRC (expr), 1);
518       *reg2 = XEXP (SET_SRC (expr), 2);
519       return true;
520     }
521
522   return false;
523 }
524
525 enum ext_modified_kind
526 {
527   /* The insn hasn't been modified by ree pass yet.  */
528   EXT_MODIFIED_NONE,
529   /* Changed into zero extension.  */
530   EXT_MODIFIED_ZEXT,
531   /* Changed into sign extension.  */
532   EXT_MODIFIED_SEXT
533 };
534
535 struct ATTRIBUTE_PACKED ext_modified
536 {
537   /* Mode from which ree has zero or sign extended the destination.  */
538   ENUM_BITFIELD(machine_mode) mode : 8;
539
540   /* Kind of modification of the insn.  */
541   ENUM_BITFIELD(ext_modified_kind) kind : 2;
542
543   unsigned int do_not_reextend : 1;
544
545   /* True if the insn is scheduled to be deleted.  */
546   unsigned int deleted : 1;
547 };
548
549 /* Vectors used by combine_reaching_defs and its helpers.  */
550 struct ext_state
551 {
552   /* In order to avoid constant alloc/free, we keep these
553      4 vectors live through the entire find_and_remove_re and just
554      truncate them each time.  */
555   vec<rtx_insn *> defs_list;
556   vec<rtx_insn *> copies_list;
557   vec<rtx_insn *> modified_list;
558   vec<rtx_insn *> work_list;
559
560   /* For instructions that have been successfully modified, this is
561      the original mode from which the insn is extending and
562      kind of extension.  */
563   struct ext_modified *modified;
564 };
565
566 /* Reaching Definitions of the extended register could be conditional copies
567    or regular definitions.  This function separates the two types into two
568    lists, STATE->DEFS_LIST and STATE->COPIES_LIST.  This is necessary because,
569    if a reaching definition is a conditional copy, merging the extension with
570    this definition is wrong.  Conditional copies are merged by transitively
571    merging their definitions.  The defs_list is populated with all the reaching
572    definitions of the extension instruction (EXTEND_INSN) which must be merged
573    with an extension.  The copies_list contains all the conditional moves that
574    will later be extended into a wider mode conditional move if all the merges
575    are successful.  The function returns false upon failure, true upon
576    success.  */
577
578 static bool
579 make_defs_and_copies_lists (rtx_insn *extend_insn, const_rtx set_pat,
580                             ext_state *state)
581 {
582   rtx src_reg = XEXP (SET_SRC (set_pat), 0);
583   bool *is_insn_visited;
584   bool ret = true;
585
586   state->work_list.truncate (0);
587
588   /* Initialize the work list.  */
589   if (!get_defs (extend_insn, src_reg, &state->work_list))
590     return false;
591
592   is_insn_visited = XCNEWVEC (bool, max_insn_uid);
593
594   /* Perform transitive closure for conditional copies.  */
595   while (!state->work_list.is_empty ())
596     {
597       rtx_insn *def_insn = state->work_list.pop ();
598       rtx reg1, reg2;
599
600       gcc_assert (INSN_UID (def_insn) < max_insn_uid);
601
602       if (is_insn_visited[INSN_UID (def_insn)])
603         continue;
604       is_insn_visited[INSN_UID (def_insn)] = true;
605
606       if (is_cond_copy_insn (def_insn, &reg1, &reg2))
607         {
608           /* Push it onto the copy list first.  */
609           state->copies_list.safe_push (def_insn);
610
611           /* Now perform the transitive closure.  */
612           if (!get_defs (def_insn, reg1, &state->work_list)
613               || !get_defs (def_insn, reg2, &state->work_list))
614             {
615               ret = false;
616               break;
617             }
618         }
619       else
620         state->defs_list.safe_push (def_insn);
621     }
622
623   XDELETEVEC (is_insn_visited);
624
625   return ret;
626 }
627
628 /* If DEF_INSN has single SET expression, possibly buried inside
629    a PARALLEL, return the address of the SET expression, else
630    return NULL.  This is similar to single_set, except that
631    single_set allows multiple SETs when all but one is dead.  */
632 static rtx *
633 get_sub_rtx (rtx_insn *def_insn)
634 {
635   enum rtx_code code = GET_CODE (PATTERN (def_insn));
636   rtx *sub_rtx = NULL;
637
638   if (code == PARALLEL)
639     {
640       for (int i = 0; i < XVECLEN (PATTERN (def_insn), 0); i++)
641         {
642           rtx s_expr = XVECEXP (PATTERN (def_insn), 0, i);
643           if (GET_CODE (s_expr) != SET)
644             continue;
645
646           if (sub_rtx == NULL)
647             sub_rtx = &XVECEXP (PATTERN (def_insn), 0, i);
648           else
649             {
650               /* PARALLEL with multiple SETs.  */
651               return NULL;
652             }
653         }
654     }
655   else if (code == SET)
656     sub_rtx = &PATTERN (def_insn);
657   else
658     {
659       /* It is not a PARALLEL or a SET, what could it be ? */
660       return NULL;
661     }
662
663   gcc_assert (sub_rtx != NULL);
664   return sub_rtx;
665 }
666
667 /* Merge the DEF_INSN with an extension.  Calls combine_set_extension
668    on the SET pattern.  */
669
670 static bool
671 merge_def_and_ext (ext_cand *cand, rtx_insn *def_insn, ext_state *state)
672 {
673   machine_mode ext_src_mode;
674   rtx *sub_rtx;
675
676   ext_src_mode = GET_MODE (XEXP (SET_SRC (cand->expr), 0));
677   sub_rtx = get_sub_rtx (def_insn);
678
679   if (sub_rtx == NULL)
680     return false;
681
682   if (REG_P (SET_DEST (*sub_rtx))
683       && (GET_MODE (SET_DEST (*sub_rtx)) == ext_src_mode
684           || ((state->modified[INSN_UID (def_insn)].kind
685                == (cand->code == ZERO_EXTEND
686                    ? EXT_MODIFIED_ZEXT : EXT_MODIFIED_SEXT))
687               && state->modified[INSN_UID (def_insn)].mode
688                  == ext_src_mode)))
689     {
690       if (GET_MODE_SIZE (GET_MODE (SET_DEST (*sub_rtx)))
691           >= GET_MODE_SIZE (cand->mode))
692         return true;
693       /* If def_insn is already scheduled to be deleted, don't attempt
694          to modify it.  */
695       if (state->modified[INSN_UID (def_insn)].deleted)
696         return false;
697       if (combine_set_extension (cand, def_insn, sub_rtx))
698         {
699           if (state->modified[INSN_UID (def_insn)].kind == EXT_MODIFIED_NONE)
700             state->modified[INSN_UID (def_insn)].mode = ext_src_mode;
701           return true;
702         }
703     }
704
705   return false;
706 }
707
708 /* Given SRC, which should be one or more extensions of a REG, strip
709    away the extensions and return the REG.  */
710
711 static inline rtx
712 get_extended_src_reg (rtx src)
713 {
714   while (GET_CODE (src) == SIGN_EXTEND || GET_CODE (src) == ZERO_EXTEND)
715     src = XEXP (src, 0);
716   gcc_assert (REG_P (src));
717   return src;
718 }
719
720 /* This function goes through all reaching defs of the source
721    of the candidate for elimination (CAND) and tries to combine
722    the extension with the definition instruction.  The changes
723    are made as a group so that even if one definition cannot be
724    merged, all reaching definitions end up not being merged.
725    When a conditional copy is encountered, merging is attempted
726    transitively on its definitions.  It returns true upon success
727    and false upon failure.  */
728
729 static bool
730 combine_reaching_defs (ext_cand *cand, const_rtx set_pat, ext_state *state)
731 {
732   rtx_insn *def_insn;
733   bool merge_successful = true;
734   int i;
735   int defs_ix;
736   bool outcome;
737
738   state->defs_list.truncate (0);
739   state->copies_list.truncate (0);
740
741   outcome = make_defs_and_copies_lists (cand->insn, set_pat, state);
742
743   if (!outcome)
744     return false;
745
746   /* If the destination operand of the extension is a different
747      register than the source operand, then additional restrictions
748      are needed.  Note we have to handle cases where we have nested
749      extensions in the source operand.  */
750   bool copy_needed
751     = (REGNO (SET_DEST (PATTERN (cand->insn)))
752        != REGNO (get_extended_src_reg (SET_SRC (PATTERN (cand->insn)))));
753   if (copy_needed)
754     {
755       /* Considering transformation of
756          (set (reg1) (expression))
757          ...
758          (set (reg2) (any_extend (reg1)))
759
760          into
761
762          (set (reg2) (any_extend (expression)))
763          (set (reg1) (reg2))
764          ...  */
765
766       /* In theory we could handle more than one reaching def, it
767          just makes the code to update the insn stream more complex.  */
768       if (state->defs_list.length () != 1)
769         return false;
770
771       /* We don't have the structure described above if there are
772          conditional moves in between the def and the candidate,
773          and we will not handle them correctly.  See PR68194.  */
774       if (state->copies_list.length () > 0)
775         return false;
776
777       /* We require the candidate not already be modified.  It may,
778          for example have been changed from a (sign_extend (reg))
779          into (zero_extend (sign_extend (reg))).
780
781          Handling that case shouldn't be terribly difficult, but the code
782          here and the code to emit copies would need auditing.  Until
783          we see a need, this is the safe thing to do.  */
784       if (state->modified[INSN_UID (cand->insn)].kind != EXT_MODIFIED_NONE)
785         return false;
786
787       machine_mode dst_mode = GET_MODE (SET_DEST (PATTERN (cand->insn)));
788       rtx src_reg = get_extended_src_reg (SET_SRC (PATTERN (cand->insn)));
789
790       /* Ensure the number of hard registers of the copy match.  */
791       if (HARD_REGNO_NREGS (REGNO (src_reg), dst_mode)
792           != HARD_REGNO_NREGS (REGNO (src_reg), GET_MODE (src_reg)))
793         return false;
794
795       /* There's only one reaching def.  */
796       rtx_insn *def_insn = state->defs_list[0];
797
798       /* The defining statement must not have been modified either.  */
799       if (state->modified[INSN_UID (def_insn)].kind != EXT_MODIFIED_NONE)
800         return false;
801
802       /* The defining statement and candidate insn must be in the same block.
803          This is merely to keep the test for safety and updating the insn
804          stream simple.  Also ensure that within the block the candidate
805          follows the defining insn.  */
806       basic_block bb = BLOCK_FOR_INSN (cand->insn);
807       if (bb != BLOCK_FOR_INSN (def_insn)
808           || DF_INSN_LUID (def_insn) > DF_INSN_LUID (cand->insn))
809         return false;
810
811       /* If there is an overlap between the destination of DEF_INSN and
812          CAND->insn, then this transformation is not safe.  Note we have
813          to test in the widened mode.  */
814       rtx *dest_sub_rtx = get_sub_rtx (def_insn);
815       if (dest_sub_rtx == NULL
816           || !REG_P (SET_DEST (*dest_sub_rtx)))
817         return false;
818
819       rtx tmp_reg = gen_rtx_REG (GET_MODE (SET_DEST (PATTERN (cand->insn))),
820                                  REGNO (SET_DEST (*dest_sub_rtx)));
821       if (reg_overlap_mentioned_p (tmp_reg, SET_DEST (PATTERN (cand->insn))))
822         return false;
823
824       /* The destination register of the extension insn must not be
825          used or set between the def_insn and cand->insn exclusive.  */
826       if (reg_used_between_p (SET_DEST (PATTERN (cand->insn)),
827                               def_insn, cand->insn)
828           || reg_set_between_p (SET_DEST (PATTERN (cand->insn)),
829                                 def_insn, cand->insn))
830         return false;
831
832       /* We must be able to copy between the two registers.   Generate,
833          recognize and verify constraints of the copy.  Also fail if this
834          generated more than one insn.
835
836          This generates garbage since we throw away the insn when we're
837          done, only to recreate it later if this test was successful. 
838
839          Make sure to get the mode from the extension (cand->insn).  This
840          is different than in the code to emit the copy as we have not
841          modified the defining insn yet.  */
842       start_sequence ();
843       rtx pat = PATTERN (cand->insn);
844       rtx new_dst = gen_rtx_REG (GET_MODE (SET_DEST (pat)),
845                                  REGNO (get_extended_src_reg (SET_SRC (pat))));
846       rtx new_src = gen_rtx_REG (GET_MODE (SET_DEST (pat)),
847                                  REGNO (SET_DEST (pat)));
848       emit_move_insn (new_dst, new_src);
849
850       rtx_insn *insn = get_insns();
851       end_sequence ();
852       if (NEXT_INSN (insn))
853         return false;
854       if (recog_memoized (insn) == -1)
855         return false;
856       extract_insn (insn);
857       if (!constrain_operands (1, get_preferred_alternatives (insn, bb)))
858         return false;
859     }
860
861
862   /* If cand->insn has been already modified, update cand->mode to a wider
863      mode if possible, or punt.  */
864   if (state->modified[INSN_UID (cand->insn)].kind != EXT_MODIFIED_NONE)
865     {
866       machine_mode mode;
867       rtx set;
868
869       if (state->modified[INSN_UID (cand->insn)].kind
870           != (cand->code == ZERO_EXTEND
871               ? EXT_MODIFIED_ZEXT : EXT_MODIFIED_SEXT)
872           || state->modified[INSN_UID (cand->insn)].mode != cand->mode
873           || (set = single_set (cand->insn)) == NULL_RTX)
874         return false;
875       mode = GET_MODE (SET_DEST (set));
876       gcc_assert (GET_MODE_SIZE (mode) >= GET_MODE_SIZE (cand->mode));
877       cand->mode = mode;
878     }
879
880   merge_successful = true;
881
882   /* Go through the defs vector and try to merge all the definitions
883      in this vector.  */
884   state->modified_list.truncate (0);
885   FOR_EACH_VEC_ELT (state->defs_list, defs_ix, def_insn)
886     {
887       if (merge_def_and_ext (cand, def_insn, state))
888         state->modified_list.safe_push (def_insn);
889       else
890         {
891           merge_successful = false;
892           break;
893         }
894     }
895
896   /* Now go through the conditional copies vector and try to merge all
897      the copies in this vector.  */
898   if (merge_successful)
899     {
900       FOR_EACH_VEC_ELT (state->copies_list, i, def_insn)
901         {
902           if (transform_ifelse (cand, def_insn))
903             state->modified_list.safe_push (def_insn);
904           else
905             {
906               merge_successful = false;
907               break;
908             }
909         }
910     }
911
912   if (merge_successful)
913     {
914       /* Commit the changes here if possible
915          FIXME: It's an all-or-nothing scenario.  Even if only one definition
916          cannot be merged, we entirely give up.  In the future, we should allow
917          extensions to be partially eliminated along those paths where the
918          definitions could be merged.  */
919       if (apply_change_group ())
920         {
921           if (dump_file)
922             fprintf (dump_file, "All merges were successful.\n");
923
924           FOR_EACH_VEC_ELT (state->modified_list, i, def_insn)
925             {
926               ext_modified *modified = &state->modified[INSN_UID (def_insn)];
927               if (modified->kind == EXT_MODIFIED_NONE)
928                 modified->kind = (cand->code == ZERO_EXTEND ? EXT_MODIFIED_ZEXT
929                                                             : EXT_MODIFIED_SEXT);
930
931               if (copy_needed)
932                 modified->do_not_reextend = 1;
933             }
934           return true;
935         }
936       else
937         {
938           /* Changes need not be cancelled explicitly as apply_change_group
939              does it.  Print list of definitions in the dump_file for debug
940              purposes.  This extension cannot be deleted.  */
941           if (dump_file)
942             {
943               fprintf (dump_file,
944                        "Merge cancelled, non-mergeable definitions:\n");
945               FOR_EACH_VEC_ELT (state->modified_list, i, def_insn)
946                 print_rtl_single (dump_file, def_insn);
947             }
948         }
949     }
950   else
951     {
952       /* Cancel any changes that have been made so far.  */
953       cancel_changes (0);
954     }
955
956   return false;
957 }
958
959 /* Add an extension pattern that could be eliminated.  */
960
961 static void
962 add_removable_extension (const_rtx expr, rtx_insn *insn,
963                          vec<ext_cand> *insn_list,
964                          unsigned *def_map,
965                          bitmap init_regs)
966 {
967   enum rtx_code code;
968   machine_mode mode;
969   unsigned int idx;
970   rtx src, dest;
971
972   /* We are looking for SET (REG N) (ANY_EXTEND (REG N)).  */
973   if (GET_CODE (expr) != SET)
974     return;
975
976   src = SET_SRC (expr);
977   code = GET_CODE (src);
978   dest = SET_DEST (expr);
979   mode = GET_MODE (dest);
980
981   if (REG_P (dest)
982       && (code == SIGN_EXTEND || code == ZERO_EXTEND)
983       && REG_P (XEXP (src, 0)))
984     {
985       rtx reg = XEXP (src, 0);
986       struct df_link *defs, *def;
987       ext_cand *cand;
988
989       /* Zero-extension of an undefined value is partly defined (it's
990          completely undefined for sign-extension, though).  So if there exists
991          a path from the entry to this zero-extension that leaves this register
992          uninitialized, removing the extension could change the behavior of
993          correct programs.  So first, check it is not the case.  */
994       if (code == ZERO_EXTEND && !bitmap_bit_p (init_regs, REGNO (reg)))
995         {
996           if (dump_file)
997             {
998               fprintf (dump_file, "Cannot eliminate extension:\n");
999               print_rtl_single (dump_file, insn);
1000               fprintf (dump_file, " because it can operate on uninitialized"
1001                                   " data\n");
1002             }
1003           return;
1004         }
1005
1006       /* Second, make sure we can get all the reaching definitions.  */
1007       defs = get_defs (insn, reg, NULL);
1008       if (!defs)
1009         {
1010           if (dump_file)
1011             {
1012               fprintf (dump_file, "Cannot eliminate extension:\n");
1013               print_rtl_single (dump_file, insn);
1014               fprintf (dump_file, " because of missing definition(s)\n");
1015             }
1016           return;
1017         }
1018
1019       /* Third, make sure the reaching definitions don't feed another and
1020          different extension.  FIXME: this obviously can be improved.  */
1021       for (def = defs; def; def = def->next)
1022         if ((idx = def_map[INSN_UID (DF_REF_INSN (def->ref))])
1023             && idx != -1U
1024             && (cand = &(*insn_list)[idx - 1])
1025             && cand->code != code)
1026           {
1027             if (dump_file)
1028               {
1029                 fprintf (dump_file, "Cannot eliminate extension:\n");
1030                 print_rtl_single (dump_file, insn);
1031                 fprintf (dump_file, " because of other extension\n");
1032               }
1033             return;
1034           }
1035         /* For vector mode extensions, ensure that all uses of the
1036            XEXP (src, 0) register are in insn or debug insns, as unlike
1037            integral extensions lowpart subreg of the sign/zero extended
1038            register are not equal to the original register, so we have
1039            to change all uses or none and the current code isn't able
1040            to change them all at once in one transaction.  */
1041         else if (VECTOR_MODE_P (GET_MODE (XEXP (src, 0))))
1042           {
1043             if (idx == 0)
1044               {
1045                 struct df_link *ref_chain, *ref_link;
1046
1047                 ref_chain = DF_REF_CHAIN (def->ref);
1048                 for (ref_link = ref_chain; ref_link; ref_link = ref_link->next)
1049                   {
1050                     if (ref_link->ref == NULL
1051                         || DF_REF_INSN_INFO (ref_link->ref) == NULL)
1052                       {
1053                         idx = -1U;
1054                         break;
1055                       }
1056                     rtx_insn *use_insn = DF_REF_INSN (ref_link->ref);
1057                     if (use_insn != insn && !DEBUG_INSN_P (use_insn))
1058                       {
1059                         idx = -1U;
1060                         break;
1061                       }
1062                   }
1063                 if (idx == -1U)
1064                   def_map[INSN_UID (DF_REF_INSN (def->ref))] = idx;
1065               }
1066             if (idx == -1U)
1067               {
1068                 if (dump_file)
1069                   {
1070                     fprintf (dump_file, "Cannot eliminate extension:\n");
1071                     print_rtl_single (dump_file, insn);
1072                     fprintf (dump_file,
1073                              " because some vector uses aren't extension\n");
1074                   }
1075                 return;
1076               }
1077           }
1078
1079       /* Fourth, if the extended version occupies more registers than the
1080          original and the source of the extension is the same hard register
1081          as the destination of the extension, then we can not eliminate
1082          the extension without deep analysis, so just punt.
1083
1084          We allow this when the registers are different because the
1085          code in combine_reaching_defs will handle that case correctly.  */
1086       if ((HARD_REGNO_NREGS (REGNO (dest), mode)
1087            != HARD_REGNO_NREGS (REGNO (reg), GET_MODE (reg)))
1088           && reg_overlap_mentioned_p (dest, reg))
1089         return;
1090
1091       /* Then add the candidate to the list and insert the reaching definitions
1092          into the definition map.  */
1093       ext_cand e = {expr, code, mode, insn};
1094       insn_list->safe_push (e);
1095       idx = insn_list->length ();
1096
1097       for (def = defs; def; def = def->next)
1098         def_map[INSN_UID (DF_REF_INSN (def->ref))] = idx;
1099     }
1100 }
1101
1102 /* Traverse the instruction stream looking for extensions and return the
1103    list of candidates.  */
1104
1105 static vec<ext_cand>
1106 find_removable_extensions (void)
1107 {
1108   vec<ext_cand> insn_list = vNULL;
1109   basic_block bb;
1110   rtx_insn *insn;
1111   rtx set;
1112   unsigned *def_map = XCNEWVEC (unsigned, max_insn_uid);
1113   bitmap_head init, kill, gen, tmp;
1114
1115   bitmap_initialize (&init, NULL);
1116   bitmap_initialize (&kill, NULL);
1117   bitmap_initialize (&gen, NULL);
1118   bitmap_initialize (&tmp, NULL);
1119
1120   FOR_EACH_BB_FN (bb, cfun)
1121     {
1122       bitmap_copy (&init, DF_MIR_IN (bb));
1123       bitmap_clear (&kill);
1124       bitmap_clear (&gen);
1125
1126       FOR_BB_INSNS (bb, insn)
1127         {
1128           if (NONDEBUG_INSN_P (insn))
1129             {
1130               set = single_set (insn);
1131               if (set != NULL_RTX)
1132                 add_removable_extension (set, insn, &insn_list, def_map,
1133                                          &init);
1134               df_mir_simulate_one_insn (bb, insn, &kill, &gen);
1135               bitmap_ior_and_compl (&tmp, &gen, &init, &kill);
1136               bitmap_copy (&init, &tmp);
1137             }
1138         }
1139     }
1140
1141   XDELETEVEC (def_map);
1142
1143   return insn_list;
1144 }
1145
1146 /* This is the main function that checks the insn stream for redundant
1147    extensions and tries to remove them if possible.  */
1148
1149 static void
1150 find_and_remove_re (void)
1151 {
1152   ext_cand *curr_cand;
1153   rtx_insn *curr_insn = NULL;
1154   int num_re_opportunities = 0, num_realized = 0, i;
1155   vec<ext_cand> reinsn_list;
1156   auto_vec<rtx_insn *> reinsn_del_list;
1157   auto_vec<rtx_insn *> reinsn_copy_list;
1158   ext_state state;
1159
1160   /* Construct DU chain to get all reaching definitions of each
1161      extension instruction.  */
1162   df_set_flags (DF_RD_PRUNE_DEAD_DEFS);
1163   df_chain_add_problem (DF_UD_CHAIN + DF_DU_CHAIN);
1164   df_mir_add_problem ();
1165   df_analyze ();
1166   df_set_flags (DF_DEFER_INSN_RESCAN);
1167
1168   max_insn_uid = get_max_uid ();
1169   reinsn_list = find_removable_extensions ();
1170   state.defs_list.create (0);
1171   state.copies_list.create (0);
1172   state.modified_list.create (0);
1173   state.work_list.create (0);
1174   if (reinsn_list.is_empty ())
1175     state.modified = NULL;
1176   else
1177     state.modified = XCNEWVEC (struct ext_modified, max_insn_uid);
1178
1179   FOR_EACH_VEC_ELT (reinsn_list, i, curr_cand)
1180     {
1181       num_re_opportunities++;
1182
1183       /* Try to combine the extension with the definition.  */
1184       if (dump_file)
1185         {
1186           fprintf (dump_file, "Trying to eliminate extension:\n");
1187           print_rtl_single (dump_file, curr_cand->insn);
1188         }
1189
1190       if (combine_reaching_defs (curr_cand, curr_cand->expr, &state))
1191         {
1192           if (dump_file)
1193             fprintf (dump_file, "Eliminated the extension.\n");
1194           num_realized++;
1195           /* If the RHS of the current candidate is not (extend (reg)), then
1196              we do not allow the optimization of extensions where
1197              the source and destination registers do not match.  Thus
1198              checking REG_P here is correct.  */
1199           if (REG_P (XEXP (SET_SRC (PATTERN (curr_cand->insn)), 0))
1200               && (REGNO (SET_DEST (PATTERN (curr_cand->insn)))
1201                   != REGNO (XEXP (SET_SRC (PATTERN (curr_cand->insn)), 0))))
1202             {
1203               reinsn_copy_list.safe_push (curr_cand->insn);
1204               reinsn_copy_list.safe_push (state.defs_list[0]);
1205             }
1206           reinsn_del_list.safe_push (curr_cand->insn);
1207           state.modified[INSN_UID (curr_cand->insn)].deleted = 1;
1208         }
1209     }
1210
1211   /* The copy list contains pairs of insns which describe copies we
1212      need to insert into the INSN stream.
1213
1214      The first insn in each pair is the extension insn, from which
1215      we derive the source and destination of the copy.
1216
1217      The second insn in each pair is the memory reference where the
1218      extension will ultimately happen.  We emit the new copy
1219      immediately after this insn.
1220
1221      It may first appear that the arguments for the copy are reversed.
1222      Remember that the memory reference will be changed to refer to the
1223      destination of the extention.  So we're actually emitting a copy
1224      from the new destination to the old destination.  */
1225   for (unsigned int i = 0; i < reinsn_copy_list.length (); i += 2)
1226     {
1227       rtx_insn *curr_insn = reinsn_copy_list[i];
1228       rtx_insn *def_insn = reinsn_copy_list[i + 1];
1229
1230       /* Use the mode of the destination of the defining insn
1231          for the mode of the copy.  This is necessary if the
1232          defining insn was used to eliminate a second extension
1233          that was wider than the first.  */
1234       rtx sub_rtx = *get_sub_rtx (def_insn);
1235       rtx pat = PATTERN (curr_insn);
1236       rtx new_dst = gen_rtx_REG (GET_MODE (SET_DEST (sub_rtx)),
1237                                  REGNO (XEXP (SET_SRC (pat), 0)));
1238       rtx new_src = gen_rtx_REG (GET_MODE (SET_DEST (sub_rtx)),
1239                                  REGNO (SET_DEST (pat)));
1240       rtx set = gen_rtx_SET (new_dst, new_src);
1241       emit_insn_after (set, def_insn);
1242     }
1243
1244   /* Delete all useless extensions here in one sweep.  */
1245   FOR_EACH_VEC_ELT (reinsn_del_list, i, curr_insn)
1246     delete_insn (curr_insn);
1247
1248   reinsn_list.release ();
1249   state.defs_list.release ();
1250   state.copies_list.release ();
1251   state.modified_list.release ();
1252   state.work_list.release ();
1253   XDELETEVEC (state.modified);
1254
1255   if (dump_file && num_re_opportunities > 0)
1256     fprintf (dump_file, "Elimination opportunities = %d realized = %d\n",
1257              num_re_opportunities, num_realized);
1258 }
1259
1260 /* Find and remove redundant extensions.  */
1261
1262 static unsigned int
1263 rest_of_handle_ree (void)
1264 {
1265   timevar_push (TV_REE);
1266   find_and_remove_re ();
1267   timevar_pop (TV_REE);
1268   return 0;
1269 }
1270
1271 namespace {
1272
1273 const pass_data pass_data_ree =
1274 {
1275   RTL_PASS, /* type */
1276   "ree", /* name */
1277   OPTGROUP_NONE, /* optinfo_flags */
1278   TV_REE, /* tv_id */
1279   0, /* properties_required */
1280   0, /* properties_provided */
1281   0, /* properties_destroyed */
1282   0, /* todo_flags_start */
1283   TODO_df_finish, /* todo_flags_finish */
1284 };
1285
1286 class pass_ree : public rtl_opt_pass
1287 {
1288 public:
1289   pass_ree (gcc::context *ctxt)
1290     : rtl_opt_pass (pass_data_ree, ctxt)
1291   {}
1292
1293   /* opt_pass methods: */
1294   virtual bool gate (function *) { return (optimize > 0 && flag_ree); }
1295   virtual unsigned int execute (function *) { return rest_of_handle_ree (); }
1296
1297 }; // class pass_ree
1298
1299 } // anon namespace
1300
1301 rtl_opt_pass *
1302 make_pass_ree (gcc::context *ctxt)
1303 {
1304   return new pass_ree (ctxt);
1305 }