Home | History | Annotate | Line # | Download | only in gcc
      1  1.1  mrg /* Discovery of auto-inc and auto-dec instructions.
      2  1.1  mrg    Copyright (C) 2006-2022 Free Software Foundation, Inc.
      3  1.1  mrg    Contributed by Kenneth Zadeck <zadeck (at) naturalbridge.com>
      4  1.1  mrg 
      5  1.1  mrg This file is part of GCC.
      6  1.1  mrg 
      7  1.1  mrg GCC is free software; you can redistribute it and/or modify it under
      8  1.1  mrg the terms of the GNU General Public License as published by the Free
      9  1.1  mrg Software Foundation; either version 3, or (at your option) any later
     10  1.1  mrg version.
     11  1.1  mrg 
     12  1.1  mrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
     13  1.1  mrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
     14  1.1  mrg FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     15  1.1  mrg for more details.
     16  1.1  mrg 
     17  1.1  mrg You should have received a copy of the GNU General Public License
     18  1.1  mrg along with GCC; see the file COPYING3.  If not see
     19  1.1  mrg <http://www.gnu.org/licenses/>.  */
     20  1.1  mrg 
     21  1.1  mrg #include "config.h"
     22  1.1  mrg #include "system.h"
     23  1.1  mrg #include "coretypes.h"
     24  1.1  mrg #include "backend.h"
     25  1.1  mrg #include "target.h"
     26  1.1  mrg #include "rtl.h"
     27  1.1  mrg #include "tree.h"
     28  1.1  mrg #include "predict.h"
     29  1.1  mrg #include "df.h"
     30  1.1  mrg #include "insn-config.h"
     31  1.1  mrg #include "memmodel.h"
     32  1.1  mrg #include "emit-rtl.h"
     33  1.1  mrg #include "recog.h"
     34  1.1  mrg #include "cfgrtl.h"
     35  1.1  mrg #include "expr.h"
     36  1.1  mrg #include "tree-pass.h"
     37  1.1  mrg #include "dbgcnt.h"
     38  1.1  mrg #include "print-rtl.h"
     39  1.1  mrg #include "valtrack.h"
     40  1.1  mrg 
     41  1.1  mrg /* This pass was originally removed from flow.c. However there is
     42  1.1  mrg    almost nothing that remains of that code.
     43  1.1  mrg 
     44  1.1  mrg    There are (4) basic forms that are matched:
     45  1.1  mrg 
     46  1.1  mrg       (1) FORM_PRE_ADD
     47  1.1  mrg            a <- b + c
     48  1.1  mrg            ...
     49  1.1  mrg            *a
     50  1.1  mrg 
     51  1.1  mrg         becomes
     52  1.1  mrg 
     53  1.1  mrg            a <- b
     54  1.1  mrg            ...
     55  1.1  mrg            *(a += c) pre
     56  1.1  mrg 
     57  1.1  mrg         or, alternately,
     58  1.1  mrg 
     59  1.1  mrg            a <- b + c
     60  1.1  mrg            ...
     61  1.1  mrg            *b
     62  1.1  mrg 
     63  1.1  mrg         becomes
     64  1.1  mrg 
     65  1.1  mrg            a <- b
     66  1.1  mrg            ...
     67  1.1  mrg            *(a += c) post
     68  1.1  mrg 
     69  1.1  mrg         This uses a post-add, but it's handled as FORM_PRE_ADD because
     70  1.1  mrg         the "increment" insn appears before the memory access.
     71  1.1  mrg 
     72  1.1  mrg 
     73  1.1  mrg       (2) FORM_PRE_INC
     74  1.1  mrg            a += c
     75  1.1  mrg            ...
     76  1.1  mrg            *a
     77  1.1  mrg 
     78  1.1  mrg         becomes
     79  1.1  mrg 
     80  1.1  mrg            ...
     81  1.1  mrg            *(a += c) pre
     82  1.1  mrg 
     83  1.1  mrg 
     84  1.1  mrg       (3) FORM_POST_ADD
     85  1.1  mrg            *a
     86  1.1  mrg            ...
     87  1.1  mrg            b <- a + c
     88  1.1  mrg 
     89  1.1  mrg 	   (For this case to be true, b must not be assigned or used between
     90  1.1  mrg 	   the *a and the assignment to b.  B must also be a Pmode reg.)
     91  1.1  mrg 
     92  1.1  mrg         becomes
     93  1.1  mrg 
     94  1.1  mrg            b <- a
     95  1.1  mrg            *(b += c) post
     96  1.1  mrg            ...
     97  1.1  mrg 
     98  1.1  mrg 
     99  1.1  mrg       (4) FORM_POST_INC
    100  1.1  mrg            *a
    101  1.1  mrg            ...
    102  1.1  mrg            a <- a + c
    103  1.1  mrg 
    104  1.1  mrg         becomes
    105  1.1  mrg 
    106  1.1  mrg            *(a += c) post
    107  1.1  mrg            ...
    108  1.1  mrg 
    109  1.1  mrg 
    110  1.1  mrg   There are three types of values of c.
    111  1.1  mrg 
    112  1.1  mrg     1) c is a constant equal to the width of the value being accessed by
    113  1.1  mrg        the pointer.  This is useful for machines that have
    114  1.1  mrg        HAVE_PRE_INCREMENT, HAVE_POST_INCREMENT, HAVE_PRE_DECREMENT or
    115  1.1  mrg        HAVE_POST_DECREMENT defined.
    116  1.1  mrg 
    117  1.1  mrg     2) c is a constant not equal to the width of the value being accessed
    118  1.1  mrg        by the pointer.  This is useful for machines that have
    119  1.1  mrg        HAVE_PRE_MODIFY_DISP, HAVE_POST_MODIFY_DISP defined.
    120  1.1  mrg 
    121  1.1  mrg     3) c is a register.  This is useful for machines that have
    122  1.1  mrg        HAVE_PRE_MODIFY_REG,  HAVE_POST_MODIFY_REG
    123  1.1  mrg 
    124  1.1  mrg   The is one special case: if a already had an offset equal to it +-
    125  1.1  mrg   its width and that offset is equal to -c when the increment was
    126  1.1  mrg   before the ref or +c if the increment was after the ref, then if we
    127  1.1  mrg   can do the combination but switch the pre/post bit.  */
    128  1.1  mrg 
    129  1.1  mrg 
    130  1.1  mrg enum form
    131  1.1  mrg {
    132  1.1  mrg   FORM_PRE_ADD,
    133  1.1  mrg   FORM_PRE_INC,
    134  1.1  mrg   FORM_POST_ADD,
    135  1.1  mrg   FORM_POST_INC,
    136  1.1  mrg   FORM_last
    137  1.1  mrg };
    138  1.1  mrg 
    139  1.1  mrg /* The states of the second operands of mem refs and inc insns.  If no
    140  1.1  mrg    second operand of the mem_ref was found, it is assumed to just be
    141  1.1  mrg    ZERO.  SIZE is the size of the mode accessed in the memref.  The
    142  1.1  mrg    ANY is used for constants that are not +-size or 0.  REG is used if
    143  1.1  mrg    the forms are reg1 + reg2.  */
    144  1.1  mrg 
    145  1.1  mrg enum inc_state
    146  1.1  mrg {
    147  1.1  mrg   INC_ZERO,           /* == 0  */
    148  1.1  mrg   INC_NEG_SIZE,       /* == +size  */
    149  1.1  mrg   INC_POS_SIZE,       /* == -size */
    150  1.1  mrg   INC_NEG_ANY,        /* == some -constant  */
    151  1.1  mrg   INC_POS_ANY,        /* == some +constant  */
    152  1.1  mrg   INC_REG,            /* == some register  */
    153  1.1  mrg   INC_last
    154  1.1  mrg };
    155  1.1  mrg 
    156  1.1  mrg /* The eight forms that pre/post inc/dec can take.  */
    157  1.1  mrg enum gen_form
    158  1.1  mrg {
    159  1.1  mrg   NOTHING,
    160  1.1  mrg   SIMPLE_PRE_INC,     /* ++size  */
    161  1.1  mrg   SIMPLE_POST_INC,    /* size++  */
    162  1.1  mrg   SIMPLE_PRE_DEC,     /* --size  */
    163  1.1  mrg   SIMPLE_POST_DEC,    /* size--  */
    164  1.1  mrg   DISP_PRE,           /* ++con   */
    165  1.1  mrg   DISP_POST,          /* con++   */
    166  1.1  mrg   REG_PRE,            /* ++reg   */
    167  1.1  mrg   REG_POST            /* reg++   */
    168  1.1  mrg };
    169  1.1  mrg 
    170  1.1  mrg /* Tmp mem rtx for use in cost modeling.  */
    171  1.1  mrg static rtx mem_tmp;
    172  1.1  mrg 
    173  1.1  mrg static enum inc_state
    174  1.1  mrg set_inc_state (HOST_WIDE_INT val, poly_int64 size)
    175  1.1  mrg {
    176  1.1  mrg   if (val == 0)
    177  1.1  mrg     return INC_ZERO;
    178  1.1  mrg   if (val < 0)
    179  1.1  mrg     return known_eq (val, -size) ? INC_NEG_SIZE : INC_NEG_ANY;
    180  1.1  mrg   else
    181  1.1  mrg     return known_eq (val, size) ? INC_POS_SIZE : INC_POS_ANY;
    182  1.1  mrg }
    183  1.1  mrg 
    184  1.1  mrg /* The DECISION_TABLE that describes what form, if any, the increment
    185  1.1  mrg    or decrement will take. It is a three dimensional table.  The first
    186  1.1  mrg    index is the type of constant or register found as the second
    187  1.1  mrg    operand of the inc insn.  The second index is the type of constant
    188  1.1  mrg    or register found as the second operand of the memory reference (if
    189  1.1  mrg    no second operand exists, 0 is used).  The third index is the form
    190  1.1  mrg    and location (relative to the mem reference) of inc insn.  */
    191  1.1  mrg 
    192  1.1  mrg static bool initialized = false;
    193  1.1  mrg static enum gen_form decision_table[INC_last][INC_last][FORM_last];
    194  1.1  mrg 
    195  1.1  mrg static void
    196  1.1  mrg init_decision_table (void)
    197  1.1  mrg {
    198  1.1  mrg   enum gen_form value;
    199  1.1  mrg 
    200  1.1  mrg   if (HAVE_PRE_INCREMENT || HAVE_PRE_MODIFY_DISP)
    201  1.1  mrg     {
    202  1.1  mrg       /* Prefer the simple form if both are available.  */
    203  1.1  mrg       value = (HAVE_PRE_INCREMENT) ? SIMPLE_PRE_INC : DISP_PRE;
    204  1.1  mrg 
    205  1.1  mrg       decision_table[INC_POS_SIZE][INC_ZERO][FORM_PRE_ADD] = value;
    206  1.1  mrg       decision_table[INC_POS_SIZE][INC_ZERO][FORM_PRE_INC] = value;
    207  1.1  mrg 
    208  1.1  mrg       decision_table[INC_POS_SIZE][INC_POS_SIZE][FORM_POST_ADD] = value;
    209  1.1  mrg       decision_table[INC_POS_SIZE][INC_POS_SIZE][FORM_POST_INC] = value;
    210  1.1  mrg     }
    211  1.1  mrg 
    212  1.1  mrg   if (HAVE_POST_INCREMENT || HAVE_POST_MODIFY_DISP)
    213  1.1  mrg     {
    214  1.1  mrg       /* Prefer the simple form if both are available.  */
    215  1.1  mrg       value = (HAVE_POST_INCREMENT) ? SIMPLE_POST_INC : DISP_POST;
    216  1.1  mrg 
    217  1.1  mrg       decision_table[INC_POS_SIZE][INC_ZERO][FORM_POST_ADD] = value;
    218  1.1  mrg       decision_table[INC_POS_SIZE][INC_ZERO][FORM_POST_INC] = value;
    219  1.1  mrg 
    220  1.1  mrg       decision_table[INC_POS_SIZE][INC_NEG_SIZE][FORM_PRE_ADD] = value;
    221  1.1  mrg       decision_table[INC_POS_SIZE][INC_NEG_SIZE][FORM_PRE_INC] = value;
    222  1.1  mrg     }
    223  1.1  mrg 
    224  1.1  mrg   if (HAVE_PRE_DECREMENT || HAVE_PRE_MODIFY_DISP)
    225  1.1  mrg     {
    226  1.1  mrg       /* Prefer the simple form if both are available.  */
    227  1.1  mrg       value = (HAVE_PRE_DECREMENT) ? SIMPLE_PRE_DEC : DISP_PRE;
    228  1.1  mrg 
    229  1.1  mrg       decision_table[INC_NEG_SIZE][INC_ZERO][FORM_PRE_ADD] = value;
    230  1.1  mrg       decision_table[INC_NEG_SIZE][INC_ZERO][FORM_PRE_INC] = value;
    231  1.1  mrg 
    232  1.1  mrg       decision_table[INC_NEG_SIZE][INC_NEG_SIZE][FORM_POST_ADD] = value;
    233  1.1  mrg       decision_table[INC_NEG_SIZE][INC_NEG_SIZE][FORM_POST_INC] = value;
    234  1.1  mrg     }
    235  1.1  mrg 
    236  1.1  mrg   if (HAVE_POST_DECREMENT || HAVE_POST_MODIFY_DISP)
    237  1.1  mrg     {
    238  1.1  mrg       /* Prefer the simple form if both are available.  */
    239  1.1  mrg       value = (HAVE_POST_DECREMENT) ? SIMPLE_POST_DEC : DISP_POST;
    240  1.1  mrg 
    241  1.1  mrg       decision_table[INC_NEG_SIZE][INC_ZERO][FORM_POST_ADD] = value;
    242  1.1  mrg       decision_table[INC_NEG_SIZE][INC_ZERO][FORM_POST_INC] = value;
    243  1.1  mrg 
    244  1.1  mrg       decision_table[INC_NEG_SIZE][INC_POS_SIZE][FORM_PRE_ADD] = value;
    245  1.1  mrg       decision_table[INC_NEG_SIZE][INC_POS_SIZE][FORM_PRE_INC] = value;
    246  1.1  mrg     }
    247  1.1  mrg 
    248  1.1  mrg   if (HAVE_PRE_MODIFY_DISP)
    249  1.1  mrg     {
    250  1.1  mrg       decision_table[INC_POS_ANY][INC_ZERO][FORM_PRE_ADD] = DISP_PRE;
    251  1.1  mrg       decision_table[INC_POS_ANY][INC_ZERO][FORM_PRE_INC] = DISP_PRE;
    252  1.1  mrg 
    253  1.1  mrg       decision_table[INC_POS_ANY][INC_POS_ANY][FORM_POST_ADD] = DISP_PRE;
    254  1.1  mrg       decision_table[INC_POS_ANY][INC_POS_ANY][FORM_POST_INC] = DISP_PRE;
    255  1.1  mrg 
    256  1.1  mrg       decision_table[INC_NEG_ANY][INC_ZERO][FORM_PRE_ADD] = DISP_PRE;
    257  1.1  mrg       decision_table[INC_NEG_ANY][INC_ZERO][FORM_PRE_INC] = DISP_PRE;
    258  1.1  mrg 
    259  1.1  mrg       decision_table[INC_NEG_ANY][INC_NEG_ANY][FORM_POST_ADD] = DISP_PRE;
    260  1.1  mrg       decision_table[INC_NEG_ANY][INC_NEG_ANY][FORM_POST_INC] = DISP_PRE;
    261  1.1  mrg     }
    262  1.1  mrg 
    263  1.1  mrg   if (HAVE_POST_MODIFY_DISP)
    264  1.1  mrg     {
    265  1.1  mrg       decision_table[INC_POS_ANY][INC_ZERO][FORM_POST_ADD] = DISP_POST;
    266  1.1  mrg       decision_table[INC_POS_ANY][INC_ZERO][FORM_POST_INC] = DISP_POST;
    267  1.1  mrg 
    268  1.1  mrg       decision_table[INC_POS_ANY][INC_NEG_ANY][FORM_PRE_ADD] = DISP_POST;
    269  1.1  mrg       decision_table[INC_POS_ANY][INC_NEG_ANY][FORM_PRE_INC] = DISP_POST;
    270  1.1  mrg 
    271  1.1  mrg       decision_table[INC_NEG_ANY][INC_ZERO][FORM_POST_ADD] = DISP_POST;
    272  1.1  mrg       decision_table[INC_NEG_ANY][INC_ZERO][FORM_POST_INC] = DISP_POST;
    273  1.1  mrg 
    274  1.1  mrg       decision_table[INC_NEG_ANY][INC_POS_ANY][FORM_PRE_ADD] = DISP_POST;
    275  1.1  mrg       decision_table[INC_NEG_ANY][INC_POS_ANY][FORM_PRE_INC] = DISP_POST;
    276  1.1  mrg     }
    277  1.1  mrg 
    278  1.1  mrg   /* This is much simpler than the other cases because we do not look
    279  1.1  mrg      for the reg1-reg2 case.  Note that we do not have a INC_POS_REG
    280  1.1  mrg      and INC_NEG_REG states.  Most of the use of such states would be
    281  1.1  mrg      on a target that had an R1 - R2 update address form.
    282  1.1  mrg 
    283  1.1  mrg      There is the remote possibility that you could also catch a = a +
    284  1.1  mrg      b; *(a - b) as a postdecrement of (a + b).  However, it is
    285  1.1  mrg      unclear if *(a - b) would ever be generated on a machine that did
    286  1.1  mrg      not have that kind of addressing mode.  The IA-64 and RS6000 will
    287  1.1  mrg      not do this, and I cannot speak for any other.  If any
    288  1.1  mrg      architecture does have an a-b update for, these cases should be
    289  1.1  mrg      added.  */
    290  1.1  mrg   if (HAVE_PRE_MODIFY_REG)
    291  1.1  mrg     {
    292  1.1  mrg       decision_table[INC_REG][INC_ZERO][FORM_PRE_ADD] = REG_PRE;
    293  1.1  mrg       decision_table[INC_REG][INC_ZERO][FORM_PRE_INC] = REG_PRE;
    294  1.1  mrg 
    295  1.1  mrg       decision_table[INC_REG][INC_REG][FORM_POST_ADD] = REG_PRE;
    296  1.1  mrg       decision_table[INC_REG][INC_REG][FORM_POST_INC] = REG_PRE;
    297  1.1  mrg     }
    298  1.1  mrg 
    299  1.1  mrg   if (HAVE_POST_MODIFY_REG)
    300  1.1  mrg     {
    301  1.1  mrg       decision_table[INC_REG][INC_ZERO][FORM_POST_ADD] = REG_POST;
    302  1.1  mrg       decision_table[INC_REG][INC_ZERO][FORM_POST_INC] = REG_POST;
    303  1.1  mrg     }
    304  1.1  mrg 
    305  1.1  mrg   initialized = true;
    306  1.1  mrg }
    307  1.1  mrg 
    308  1.1  mrg /* Parsed fields of an inc insn of the form "reg_res = reg0+reg1" or
    309  1.1  mrg    "reg_res = reg0+c".  */
    310  1.1  mrg 
    311  1.1  mrg static struct inc_insn
    312  1.1  mrg {
    313  1.1  mrg   rtx_insn *insn;     /* The insn being parsed.  */
    314  1.1  mrg   rtx pat;            /* The pattern of the insn.  */
    315  1.1  mrg   bool reg1_is_const; /* True if reg1 is const, false if reg1 is a reg.  */
    316  1.1  mrg   enum form form;
    317  1.1  mrg   rtx reg_res;
    318  1.1  mrg   rtx reg0;
    319  1.1  mrg   rtx reg1;
    320  1.1  mrg   enum inc_state reg1_state;/* The form of the const if reg1 is a const.  */
    321  1.1  mrg   HOST_WIDE_INT reg1_val;/* Value if reg1 is const.  */
    322  1.1  mrg } inc_insn;
    323  1.1  mrg 
    324  1.1  mrg 
    325  1.1  mrg /* Dump the parsed inc insn to FILE.  */
    326  1.1  mrg 
    327  1.1  mrg static void
    328  1.1  mrg dump_inc_insn (FILE *file)
    329  1.1  mrg {
    330  1.1  mrg   const char *f = ((inc_insn.form == FORM_PRE_ADD)
    331  1.1  mrg 	      || (inc_insn.form == FORM_PRE_INC)) ? "pre" : "post";
    332  1.1  mrg 
    333  1.1  mrg   dump_insn_slim (file, inc_insn.insn);
    334  1.1  mrg 
    335  1.1  mrg   switch (inc_insn.form)
    336  1.1  mrg     {
    337  1.1  mrg     case FORM_PRE_ADD:
    338  1.1  mrg     case FORM_POST_ADD:
    339  1.1  mrg       if (inc_insn.reg1_is_const)
    340  1.1  mrg 	fprintf (file, "found %s add(%d) r[%d]=r[%d]+%d\n",
    341  1.1  mrg 		 f, INSN_UID (inc_insn.insn),
    342  1.1  mrg 		 REGNO (inc_insn.reg_res),
    343  1.1  mrg 		 REGNO (inc_insn.reg0), (int) inc_insn.reg1_val);
    344  1.1  mrg       else
    345  1.1  mrg 	fprintf (file, "found %s add(%d) r[%d]=r[%d]+r[%d]\n",
    346  1.1  mrg 		 f, INSN_UID (inc_insn.insn),
    347  1.1  mrg 		 REGNO (inc_insn.reg_res),
    348  1.1  mrg 		 REGNO (inc_insn.reg0), REGNO (inc_insn.reg1));
    349  1.1  mrg       break;
    350  1.1  mrg 
    351  1.1  mrg     case FORM_PRE_INC:
    352  1.1  mrg     case FORM_POST_INC:
    353  1.1  mrg       if (inc_insn.reg1_is_const)
    354  1.1  mrg 	fprintf (file, "found %s inc(%d) r[%d]+=%d\n",
    355  1.1  mrg 		 f, INSN_UID (inc_insn.insn),
    356  1.1  mrg 		 REGNO (inc_insn.reg_res), (int) inc_insn.reg1_val);
    357  1.1  mrg       else
    358  1.1  mrg 	fprintf (file, "found %s inc(%d) r[%d]+=r[%d]\n",
    359  1.1  mrg 		 f, INSN_UID (inc_insn.insn),
    360  1.1  mrg 		 REGNO (inc_insn.reg_res), REGNO (inc_insn.reg1));
    361  1.1  mrg       break;
    362  1.1  mrg 
    363  1.1  mrg     default:
    364  1.1  mrg       break;
    365  1.1  mrg     }
    366  1.1  mrg }
    367  1.1  mrg 
    368  1.1  mrg 
    369  1.1  mrg /* Parsed fields of a mem ref of the form "*(reg0+reg1)" or "*(reg0+c)".  */
    370  1.1  mrg 
    371  1.1  mrg static struct mem_insn
    372  1.1  mrg {
    373  1.1  mrg   rtx_insn *insn;     /* The insn being parsed.  */
    374  1.1  mrg   rtx pat;            /* The pattern of the insn.  */
    375  1.1  mrg   rtx *mem_loc;       /* The address of the field that holds the mem */
    376  1.1  mrg                       /* that is to be replaced.  */
    377  1.1  mrg   bool reg1_is_const; /* True if reg1 is const, false if reg1 is a reg.  */
    378  1.1  mrg   rtx reg0;
    379  1.1  mrg   rtx reg1;           /* This is either a reg or a const depending on
    380  1.1  mrg 			 reg1_is_const.  */
    381  1.1  mrg   enum inc_state reg1_state;/* The form of the const if reg1 is a const.  */
    382  1.1  mrg   HOST_WIDE_INT reg1_val;/* Value if reg1 is const.  */
    383  1.1  mrg } mem_insn;
    384  1.1  mrg 
    385  1.1  mrg 
    386  1.1  mrg /* Dump the parsed mem insn to FILE.  */
    387  1.1  mrg 
    388  1.1  mrg static void
    389  1.1  mrg dump_mem_insn (FILE *file)
    390  1.1  mrg {
    391  1.1  mrg   dump_insn_slim (file, mem_insn.insn);
    392  1.1  mrg 
    393  1.1  mrg   if (mem_insn.reg1_is_const)
    394  1.1  mrg     fprintf (file, "found mem(%d) *(r[%d]+%d)\n",
    395  1.1  mrg 	     INSN_UID (mem_insn.insn),
    396  1.1  mrg 	     REGNO (mem_insn.reg0), (int) mem_insn.reg1_val);
    397  1.1  mrg   else
    398  1.1  mrg     fprintf (file, "found mem(%d) *(r[%d]+r[%d])\n",
    399  1.1  mrg 	     INSN_UID (mem_insn.insn),
    400  1.1  mrg 	     REGNO (mem_insn.reg0), REGNO (mem_insn.reg1));
    401  1.1  mrg }
    402  1.1  mrg 
    403  1.1  mrg 
    404  1.1  mrg /* The following three arrays contain pointers to instructions. They
    405  1.1  mrg    are indexed by REGNO.  At any point in the basic block where we are
    406  1.1  mrg    looking these three arrays contain, respectively, the next insn
    407  1.1  mrg    that uses REGNO, the next inc or add insn that uses REGNO and the
    408  1.1  mrg    next insn that sets REGNO.
    409  1.1  mrg 
    410  1.1  mrg    The arrays are not cleared when we move from block to block so
    411  1.1  mrg    whenever an insn is retrieved from these arrays, it's block number
    412  1.1  mrg    must be compared with the current block.
    413  1.1  mrg */
    414  1.1  mrg 
    415  1.1  mrg static rtx_insn **reg_next_debug_use = NULL;
    416  1.1  mrg static rtx_insn **reg_next_use = NULL;
    417  1.1  mrg static rtx_insn **reg_next_inc_use = NULL;
    418  1.1  mrg static rtx_insn **reg_next_def = NULL;
    419  1.1  mrg 
    420  1.1  mrg 
    421  1.1  mrg /* Move dead note that match PATTERN to TO_INSN from FROM_INSN.  We do
    422  1.1  mrg    not really care about moving any other notes from the inc or add
    423  1.1  mrg    insn.  Moving the REG_EQUAL and REG_EQUIV is clearly wrong and it
    424  1.1  mrg    does not appear that there are any other kinds of relevant notes.  */
    425  1.1  mrg 
    426  1.1  mrg static void
    427  1.1  mrg move_dead_notes (rtx_insn *to_insn, rtx_insn *from_insn, rtx pattern)
    428  1.1  mrg {
    429  1.1  mrg   rtx note;
    430  1.1  mrg   rtx next_note;
    431  1.1  mrg   rtx prev_note = NULL;
    432  1.1  mrg 
    433  1.1  mrg   for (note = REG_NOTES (from_insn); note; note = next_note)
    434  1.1  mrg     {
    435  1.1  mrg       next_note = XEXP (note, 1);
    436  1.1  mrg 
    437  1.1  mrg       if ((REG_NOTE_KIND (note) == REG_DEAD)
    438  1.1  mrg 	  && pattern == XEXP (note, 0))
    439  1.1  mrg 	{
    440  1.1  mrg 	  XEXP (note, 1) = REG_NOTES (to_insn);
    441  1.1  mrg 	  REG_NOTES (to_insn) = note;
    442  1.1  mrg 	  if (prev_note)
    443  1.1  mrg 	    XEXP (prev_note, 1) = next_note;
    444  1.1  mrg 	  else
    445  1.1  mrg 	    REG_NOTES (from_insn) = next_note;
    446  1.1  mrg 	}
    447  1.1  mrg       else prev_note = note;
    448  1.1  mrg     }
    449  1.1  mrg }
    450  1.1  mrg 
    451  1.1  mrg /* Change mem_insn.mem_loc so that uses NEW_ADDR which has an
    452  1.1  mrg    increment of INC_REG.  To have reached this point, the change is a
    453  1.1  mrg    legitimate one from a dataflow point of view.  The only questions
    454  1.1  mrg    are is this a valid change to the instruction and is this a
    455  1.1  mrg    profitable change to the instruction.  */
    456  1.1  mrg 
    457  1.1  mrg static bool
    458  1.1  mrg attempt_change (rtx new_addr, rtx inc_reg)
    459  1.1  mrg {
    460  1.1  mrg   /* There are four cases: For the two cases that involve an add
    461  1.1  mrg      instruction, we are going to have to delete the add and insert a
    462  1.1  mrg      mov.  We are going to assume that the mov is free.  This is
    463  1.1  mrg      fairly early in the backend and there are a lot of opportunities
    464  1.1  mrg      for removing that move later.  In particular, there is the case
    465  1.1  mrg      where the move may be dead, this is what dead code elimination
    466  1.1  mrg      passes are for.  The two cases where we have an inc insn will be
    467  1.1  mrg      handled mov free.  */
    468  1.1  mrg 
    469  1.1  mrg   basic_block bb = BLOCK_FOR_INSN (mem_insn.insn);
    470  1.1  mrg   rtx_insn *mov_insn = NULL;
    471  1.1  mrg   int regno;
    472  1.1  mrg   rtx mem = *mem_insn.mem_loc;
    473  1.1  mrg   machine_mode mode = GET_MODE (mem);
    474  1.1  mrg   int align = MEM_ALIGN (mem);
    475  1.1  mrg   rtx new_mem;
    476  1.1  mrg   int old_cost = 0;
    477  1.1  mrg   int new_cost = 0;
    478  1.1  mrg   bool speed = optimize_bb_for_speed_p (bb);
    479  1.1  mrg 
    480  1.1  mrg   PUT_MODE (mem_tmp, mode);
    481  1.1  mrg   XEXP (mem_tmp, 0) = new_addr;
    482  1.1  mrg   set_mem_align (mem_tmp, align);
    483  1.1  mrg 
    484  1.1  mrg   old_cost = (set_src_cost (mem, mode, speed)
    485  1.1  mrg 	      + set_rtx_cost (PATTERN (inc_insn.insn), speed));
    486  1.1  mrg 
    487  1.1  mrg   new_cost = set_src_cost (mem_tmp, mode, speed);
    488  1.1  mrg 
    489  1.1  mrg   /* In the FORM_PRE_ADD and FORM_POST_ADD cases we emit an extra move
    490  1.1  mrg      whose cost we should account for.  */
    491  1.1  mrg   if (inc_insn.form == FORM_PRE_ADD
    492  1.1  mrg       || inc_insn.form == FORM_POST_ADD)
    493  1.1  mrg     {
    494  1.1  mrg       start_sequence ();
    495  1.1  mrg       emit_move_insn (inc_insn.reg_res, inc_insn.reg0);
    496  1.1  mrg       mov_insn = get_insns ();
    497  1.1  mrg       end_sequence ();
    498  1.1  mrg       new_cost += seq_cost (mov_insn, speed);
    499  1.1  mrg     }
    500  1.1  mrg 
    501  1.1  mrg   /* The first item of business is to see if this is profitable.  */
    502  1.1  mrg   if (old_cost < new_cost)
    503  1.1  mrg     {
    504  1.1  mrg       if (dump_file)
    505  1.1  mrg 	fprintf (dump_file, "cost failure old=%d new=%d\n", old_cost, new_cost);
    506  1.1  mrg       return false;
    507  1.1  mrg     }
    508  1.1  mrg 
    509  1.1  mrg   /* Jump through a lot of hoops to keep the attributes up to date.  We
    510  1.1  mrg      do not want to call one of the change address variants that take
    511  1.1  mrg      an offset even though we know the offset in many cases.  These
    512  1.1  mrg      assume you are changing where the address is pointing by the
    513  1.1  mrg      offset.  */
    514  1.1  mrg   new_mem = replace_equiv_address_nv (mem, new_addr);
    515  1.1  mrg   if (! validate_change (mem_insn.insn, mem_insn.mem_loc, new_mem, 0))
    516  1.1  mrg     {
    517  1.1  mrg       if (dump_file)
    518  1.1  mrg 	fprintf (dump_file, "validation failure\n");
    519  1.1  mrg       return false;
    520  1.1  mrg     }
    521  1.1  mrg 
    522  1.1  mrg   /* From here to the end of the function we are committed to the
    523  1.1  mrg      change, i.e. nothing fails.  Generate any necessary movs, move
    524  1.1  mrg      any regnotes, and fix up the reg_next_{use,inc_use,def}.  */
    525  1.1  mrg   switch (inc_insn.form)
    526  1.1  mrg     {
    527  1.1  mrg     case FORM_PRE_ADD:
    528  1.1  mrg       /* Replace the addition with a move.  Do it at the location of
    529  1.1  mrg 	 the addition since the operand of the addition may change
    530  1.1  mrg 	 before the memory reference.  */
    531  1.1  mrg       gcc_assert (mov_insn);
    532  1.1  mrg       emit_insn_before (mov_insn, inc_insn.insn);
    533  1.1  mrg       regno = REGNO (inc_insn.reg0);
    534  1.1  mrg       /* ??? Could REGNO possibly be used in MEM_INSN other than in
    535  1.1  mrg 	 the MEM address, and still die there, so that move_dead_notes
    536  1.1  mrg 	 would incorrectly move the note?  */
    537  1.1  mrg       if (reg_next_use[regno] == mem_insn.insn)
    538  1.1  mrg 	move_dead_notes (mov_insn, mem_insn.insn, inc_insn.reg0);
    539  1.1  mrg       else
    540  1.1  mrg 	move_dead_notes (mov_insn, inc_insn.insn, inc_insn.reg0);
    541  1.1  mrg 
    542  1.1  mrg       regno = REGNO (inc_insn.reg_res);
    543  1.1  mrg       if (reg_next_debug_use && reg_next_debug_use[regno]
    544  1.1  mrg 	  && BLOCK_FOR_INSN (reg_next_debug_use[regno]) == bb)
    545  1.1  mrg 	{
    546  1.1  mrg 	  rtx adjres = gen_rtx_PLUS (GET_MODE (inc_insn.reg_res),
    547  1.1  mrg 				     inc_insn.reg_res, inc_insn.reg1);
    548  1.1  mrg 	  if (dump_file)
    549  1.1  mrg 	    fprintf (dump_file, "adjusting debug insns\n");
    550  1.1  mrg 	  propagate_for_debug (PREV_INSN (reg_next_debug_use[regno]),
    551  1.1  mrg 			       mem_insn.insn,
    552  1.1  mrg 			       inc_insn.reg_res, adjres, bb);
    553  1.1  mrg 	  reg_next_debug_use[regno] = NULL;
    554  1.1  mrg 	}
    555  1.1  mrg       reg_next_def[regno] = mov_insn;
    556  1.1  mrg       reg_next_use[regno] = NULL;
    557  1.1  mrg 
    558  1.1  mrg       regno = REGNO (inc_insn.reg0);
    559  1.1  mrg       if (reg_next_debug_use && reg_next_debug_use[regno]
    560  1.1  mrg 	  && BLOCK_FOR_INSN (reg_next_debug_use[regno]) == bb
    561  1.1  mrg 	  && find_reg_note (mov_insn, REG_DEAD, inc_insn.reg0))
    562  1.1  mrg 	{
    563  1.1  mrg 	  if (dump_file)
    564  1.1  mrg 	    fprintf (dump_file, "remapping debug insns\n");
    565  1.1  mrg 	  propagate_for_debug (PREV_INSN (reg_next_debug_use[regno]),
    566  1.1  mrg 			       mem_insn.insn,
    567  1.1  mrg 			       inc_insn.reg0, inc_insn.reg_res, bb);
    568  1.1  mrg 	  reg_next_debug_use[regno] = NULL;
    569  1.1  mrg 	}
    570  1.1  mrg       reg_next_use[regno] = mov_insn;
    571  1.1  mrg       df_recompute_luids (bb);
    572  1.1  mrg       break;
    573  1.1  mrg 
    574  1.1  mrg     case FORM_POST_INC:
    575  1.1  mrg       regno = REGNO (inc_insn.reg_res);
    576  1.1  mrg       if (reg_next_debug_use && reg_next_debug_use[regno]
    577  1.1  mrg 	  && BLOCK_FOR_INSN (reg_next_debug_use[regno]) == bb)
    578  1.1  mrg 	{
    579  1.1  mrg 	  rtx adjres = gen_rtx_MINUS (GET_MODE (inc_insn.reg_res),
    580  1.1  mrg 				      inc_insn.reg_res, inc_insn.reg1);
    581  1.1  mrg 	  if (dump_file)
    582  1.1  mrg 	    fprintf (dump_file, "adjusting debug insns\n");
    583  1.1  mrg 	  propagate_for_debug (PREV_INSN (reg_next_debug_use[regno]),
    584  1.1  mrg 			       inc_insn.insn,
    585  1.1  mrg 			       inc_insn.reg_res, adjres, bb);
    586  1.1  mrg 	  reg_next_debug_use[regno] = NULL;
    587  1.1  mrg 	}
    588  1.1  mrg       if (reg_next_use[regno] == reg_next_inc_use[regno])
    589  1.1  mrg 	reg_next_inc_use[regno] = NULL;
    590  1.1  mrg 
    591  1.1  mrg       /* Fallthru.  */
    592  1.1  mrg     case FORM_PRE_INC:
    593  1.1  mrg       regno = REGNO (inc_insn.reg_res);
    594  1.1  mrg       /* Despite the fall-through, we won't run this twice: we'll have
    595  1.1  mrg 	 already cleared reg_next_debug_use[regno] before falling
    596  1.1  mrg 	 through.  */
    597  1.1  mrg       if (reg_next_debug_use && reg_next_debug_use[regno]
    598  1.1  mrg 	  && BLOCK_FOR_INSN (reg_next_debug_use[regno]) == bb)
    599  1.1  mrg 	{
    600  1.1  mrg 	  rtx adjres = gen_rtx_PLUS (GET_MODE (inc_insn.reg_res),
    601  1.1  mrg 				     inc_insn.reg_res, inc_insn.reg1);
    602  1.1  mrg 	  if (dump_file)
    603  1.1  mrg 	    fprintf (dump_file, "adjusting debug insns\n");
    604  1.1  mrg 	  propagate_for_debug (PREV_INSN (reg_next_debug_use[regno]),
    605  1.1  mrg 			       mem_insn.insn,
    606  1.1  mrg 			       inc_insn.reg_res, adjres, bb);
    607  1.1  mrg 	  if (DF_INSN_LUID (mem_insn.insn)
    608  1.1  mrg 	      < DF_INSN_LUID (reg_next_debug_use[regno]))
    609  1.1  mrg 	    reg_next_debug_use[regno] = NULL;
    610  1.1  mrg 	}
    611  1.1  mrg       reg_next_def[regno] = mem_insn.insn;
    612  1.1  mrg       reg_next_use[regno] = NULL;
    613  1.1  mrg 
    614  1.1  mrg       break;
    615  1.1  mrg 
    616  1.1  mrg     case FORM_POST_ADD:
    617  1.1  mrg       gcc_assert (mov_insn);
    618  1.1  mrg       emit_insn_before (mov_insn, mem_insn.insn);
    619  1.1  mrg       move_dead_notes (mov_insn, inc_insn.insn, inc_insn.reg0);
    620  1.1  mrg 
    621  1.1  mrg       /* Do not move anything to the mov insn because the instruction
    622  1.1  mrg 	 pointer for the main iteration has not yet hit that.  It is
    623  1.1  mrg 	 still pointing to the mem insn. */
    624  1.1  mrg       regno = REGNO (inc_insn.reg_res);
    625  1.1  mrg       /* The pseudo is now set earlier, so it must have been dead in
    626  1.1  mrg 	 that range, and dead registers cannot be referenced in debug
    627  1.1  mrg 	 insns.  */
    628  1.1  mrg       gcc_assert (!(reg_next_debug_use && reg_next_debug_use[regno]
    629  1.1  mrg 		    && BLOCK_FOR_INSN (reg_next_debug_use[regno]) == bb));
    630  1.1  mrg       reg_next_def[regno] = mem_insn.insn;
    631  1.1  mrg       reg_next_use[regno] = NULL;
    632  1.1  mrg 
    633  1.1  mrg       regno = REGNO (inc_insn.reg0);
    634  1.1  mrg       if (reg_next_debug_use && reg_next_debug_use[regno]
    635  1.1  mrg 	  && BLOCK_FOR_INSN (reg_next_debug_use[regno]) == bb
    636  1.1  mrg 	  && find_reg_note (mov_insn, REG_DEAD, inc_insn.reg0))
    637  1.1  mrg 	{
    638  1.1  mrg 	  if (dump_file)
    639  1.1  mrg 	    fprintf (dump_file, "remapping debug insns\n");
    640  1.1  mrg 	  propagate_for_debug (PREV_INSN (reg_next_debug_use[regno]),
    641  1.1  mrg 			       inc_insn.insn,
    642  1.1  mrg 			       inc_insn.reg0, inc_insn.reg_res, bb);
    643  1.1  mrg 	  reg_next_debug_use[regno] = NULL;
    644  1.1  mrg 	}
    645  1.1  mrg       reg_next_use[regno] = mem_insn.insn;
    646  1.1  mrg       if ((reg_next_use[regno] == reg_next_inc_use[regno])
    647  1.1  mrg 	  || (reg_next_inc_use[regno] == inc_insn.insn))
    648  1.1  mrg 	reg_next_inc_use[regno] = NULL;
    649  1.1  mrg       df_recompute_luids (bb);
    650  1.1  mrg       break;
    651  1.1  mrg 
    652  1.1  mrg     case FORM_last:
    653  1.1  mrg     default:
    654  1.1  mrg       gcc_unreachable ();
    655  1.1  mrg     }
    656  1.1  mrg 
    657  1.1  mrg   if (!inc_insn.reg1_is_const)
    658  1.1  mrg     {
    659  1.1  mrg       regno = REGNO (inc_insn.reg1);
    660  1.1  mrg       reg_next_use[regno] = mem_insn.insn;
    661  1.1  mrg       if ((reg_next_use[regno] == reg_next_inc_use[regno])
    662  1.1  mrg 	  || (reg_next_inc_use[regno] == inc_insn.insn))
    663  1.1  mrg 	reg_next_inc_use[regno] = NULL;
    664  1.1  mrg     }
    665  1.1  mrg 
    666  1.1  mrg   delete_insn (inc_insn.insn);
    667  1.1  mrg 
    668  1.1  mrg   if (dump_file && mov_insn)
    669  1.1  mrg     {
    670  1.1  mrg       fprintf (dump_file, "inserting mov ");
    671  1.1  mrg       dump_insn_slim (dump_file, mov_insn);
    672  1.1  mrg     }
    673  1.1  mrg 
    674  1.1  mrg   /* Record that this insn has an implicit side effect.  */
    675  1.1  mrg   add_reg_note (mem_insn.insn, REG_INC, inc_reg);
    676  1.1  mrg 
    677  1.1  mrg   if (dump_file)
    678  1.1  mrg     {
    679  1.1  mrg       fprintf (dump_file, "****success ");
    680  1.1  mrg       dump_insn_slim (dump_file, mem_insn.insn);
    681  1.1  mrg     }
    682  1.1  mrg 
    683  1.1  mrg   return true;
    684  1.1  mrg }
    685  1.1  mrg 
    686  1.1  mrg 
    687  1.1  mrg /* Try to combine the instruction in INC_INSN with the instruction in
    688  1.1  mrg    MEM_INSN.  First the form is determined using the DECISION_TABLE
    689  1.1  mrg    and the results of parsing the INC_INSN and the MEM_INSN.
    690  1.1  mrg    Assuming the form is ok, a prototype new address is built which is
    691  1.1  mrg    passed to ATTEMPT_CHANGE for final processing.  */
    692  1.1  mrg 
    693  1.1  mrg static bool
    694  1.1  mrg try_merge (void)
    695  1.1  mrg {
    696  1.1  mrg   enum gen_form gen_form;
    697  1.1  mrg   rtx mem = *mem_insn.mem_loc;
    698  1.1  mrg   rtx inc_reg = inc_insn.form == FORM_POST_ADD ?
    699  1.1  mrg     inc_insn.reg_res : mem_insn.reg0;
    700  1.1  mrg 
    701  1.1  mrg   /* The width of the mem being accessed.  */
    702  1.1  mrg   poly_int64 size = GET_MODE_SIZE (GET_MODE (mem));
    703  1.1  mrg   rtx_insn *last_insn = NULL;
    704  1.1  mrg   machine_mode reg_mode = GET_MODE (inc_reg);
    705  1.1  mrg 
    706  1.1  mrg   switch (inc_insn.form)
    707  1.1  mrg     {
    708  1.1  mrg     case FORM_PRE_ADD:
    709  1.1  mrg     case FORM_PRE_INC:
    710  1.1  mrg       last_insn = mem_insn.insn;
    711  1.1  mrg       break;
    712  1.1  mrg     case FORM_POST_INC:
    713  1.1  mrg     case FORM_POST_ADD:
    714  1.1  mrg       last_insn = inc_insn.insn;
    715  1.1  mrg       break;
    716  1.1  mrg     case FORM_last:
    717  1.1  mrg     default:
    718  1.1  mrg       gcc_unreachable ();
    719  1.1  mrg     }
    720  1.1  mrg 
    721  1.1  mrg   /* Cannot handle auto inc of the stack.  */
    722  1.1  mrg   if (inc_reg == stack_pointer_rtx)
    723  1.1  mrg     {
    724  1.1  mrg       if (dump_file)
    725  1.1  mrg 	fprintf (dump_file, "cannot inc stack %d failure\n", REGNO (inc_reg));
    726  1.1  mrg       return false;
    727  1.1  mrg     }
    728  1.1  mrg 
    729  1.1  mrg   /* Look to see if the inc register is dead after the memory
    730  1.1  mrg      reference.  If it is, do not do the combination.  */
    731  1.1  mrg   if (find_regno_note (last_insn, REG_DEAD, REGNO (inc_reg)))
    732  1.1  mrg     {
    733  1.1  mrg       if (dump_file)
    734  1.1  mrg 	fprintf (dump_file, "dead failure %d\n", REGNO (inc_reg));
    735  1.1  mrg       return false;
    736  1.1  mrg     }
    737  1.1  mrg 
    738  1.1  mrg   mem_insn.reg1_state = (mem_insn.reg1_is_const)
    739  1.1  mrg     ? set_inc_state (mem_insn.reg1_val, size) : INC_REG;
    740  1.1  mrg   inc_insn.reg1_state = (inc_insn.reg1_is_const)
    741  1.1  mrg     ? set_inc_state (inc_insn.reg1_val, size) : INC_REG;
    742  1.1  mrg 
    743  1.1  mrg   /* Now get the form that we are generating.  */
    744  1.1  mrg   gen_form = decision_table
    745  1.1  mrg     [inc_insn.reg1_state][mem_insn.reg1_state][inc_insn.form];
    746  1.1  mrg 
    747  1.1  mrg   if (dbg_cnt (auto_inc_dec) == false)
    748  1.1  mrg     return false;
    749  1.1  mrg 
    750  1.1  mrg   switch (gen_form)
    751  1.1  mrg     {
    752  1.1  mrg     default:
    753  1.1  mrg     case NOTHING:
    754  1.1  mrg       return false;
    755  1.1  mrg 
    756  1.1  mrg     case SIMPLE_PRE_INC:     /* ++size  */
    757  1.1  mrg       if (dump_file)
    758  1.1  mrg 	fprintf (dump_file, "trying SIMPLE_PRE_INC\n");
    759  1.1  mrg       return attempt_change (gen_rtx_PRE_INC (reg_mode, inc_reg), inc_reg);
    760  1.1  mrg 
    761  1.1  mrg     case SIMPLE_POST_INC:    /* size++  */
    762  1.1  mrg       if (dump_file)
    763  1.1  mrg 	fprintf (dump_file, "trying SIMPLE_POST_INC\n");
    764  1.1  mrg       return attempt_change (gen_rtx_POST_INC (reg_mode, inc_reg), inc_reg);
    765  1.1  mrg 
    766  1.1  mrg     case SIMPLE_PRE_DEC:     /* --size  */
    767  1.1  mrg       if (dump_file)
    768  1.1  mrg 	fprintf (dump_file, "trying SIMPLE_PRE_DEC\n");
    769  1.1  mrg       return attempt_change (gen_rtx_PRE_DEC (reg_mode, inc_reg), inc_reg);
    770  1.1  mrg 
    771  1.1  mrg     case SIMPLE_POST_DEC:    /* size--  */
    772  1.1  mrg       if (dump_file)
    773  1.1  mrg 	fprintf (dump_file, "trying SIMPLE_POST_DEC\n");
    774  1.1  mrg       return attempt_change (gen_rtx_POST_DEC (reg_mode, inc_reg), inc_reg);
    775  1.1  mrg 
    776  1.1  mrg     case DISP_PRE:           /* ++con   */
    777  1.1  mrg       if (dump_file)
    778  1.1  mrg 	fprintf (dump_file, "trying DISP_PRE\n");
    779  1.1  mrg       return attempt_change (gen_rtx_PRE_MODIFY (reg_mode,
    780  1.1  mrg 						 inc_reg,
    781  1.1  mrg 						 gen_rtx_PLUS (reg_mode,
    782  1.1  mrg 							       inc_reg,
    783  1.1  mrg 							       inc_insn.reg1)),
    784  1.1  mrg 			     inc_reg);
    785  1.1  mrg 
    786  1.1  mrg     case DISP_POST:          /* con++   */
    787  1.1  mrg       if (dump_file)
    788  1.1  mrg 	fprintf (dump_file, "trying POST_DISP\n");
    789  1.1  mrg       return attempt_change (gen_rtx_POST_MODIFY (reg_mode,
    790  1.1  mrg 						  inc_reg,
    791  1.1  mrg 						  gen_rtx_PLUS (reg_mode,
    792  1.1  mrg 								inc_reg,
    793  1.1  mrg 								inc_insn.reg1)),
    794  1.1  mrg 			     inc_reg);
    795  1.1  mrg 
    796  1.1  mrg     case REG_PRE:            /* ++reg   */
    797  1.1  mrg       if (dump_file)
    798  1.1  mrg 	fprintf (dump_file, "trying PRE_REG\n");
    799  1.1  mrg       return attempt_change (gen_rtx_PRE_MODIFY (reg_mode,
    800  1.1  mrg 						 inc_reg,
    801  1.1  mrg 						 gen_rtx_PLUS (reg_mode,
    802  1.1  mrg 							       inc_reg,
    803  1.1  mrg 							       inc_insn.reg1)),
    804  1.1  mrg 			     inc_reg);
    805  1.1  mrg 
    806  1.1  mrg     case REG_POST:            /* reg++   */
    807  1.1  mrg       if (dump_file)
    808  1.1  mrg 	fprintf (dump_file, "trying POST_REG\n");
    809  1.1  mrg       return attempt_change (gen_rtx_POST_MODIFY (reg_mode,
    810  1.1  mrg 						  inc_reg,
    811  1.1  mrg 						  gen_rtx_PLUS (reg_mode,
    812  1.1  mrg 								inc_reg,
    813  1.1  mrg 								inc_insn.reg1)),
    814  1.1  mrg 			     inc_reg);
    815  1.1  mrg     }
    816  1.1  mrg }
    817  1.1  mrg 
    818  1.1  mrg /* Return the next insn that uses (if reg_next_use is passed in
    819  1.1  mrg    NEXT_ARRAY) or defines (if reg_next_def is passed in NEXT_ARRAY)
    820  1.1  mrg    REGNO in BB.  */
    821  1.1  mrg 
    822  1.1  mrg static rtx_insn *
    823  1.1  mrg get_next_ref (int regno, basic_block bb, rtx_insn **next_array)
    824  1.1  mrg {
    825  1.1  mrg   rtx_insn *insn = next_array[regno];
    826  1.1  mrg 
    827  1.1  mrg   /* Lazy about cleaning out the next_arrays.  */
    828  1.1  mrg   if (insn && BLOCK_FOR_INSN (insn) != bb)
    829  1.1  mrg     {
    830  1.1  mrg       next_array[regno] = NULL;
    831  1.1  mrg       insn = NULL;
    832  1.1  mrg     }
    833  1.1  mrg 
    834  1.1  mrg   return insn;
    835  1.1  mrg }
    836  1.1  mrg 
    837  1.1  mrg 
    838  1.1  mrg /* Return true if INSN is of a form "a = b op c" where a and b are
    839  1.1  mrg    regs.  op is + if c is a reg and +|- if c is a const.  Fill in
    840  1.1  mrg    INC_INSN with what is found.
    841  1.1  mrg 
    842  1.1  mrg    This function is called in two contexts, if BEFORE_MEM is true,
    843  1.1  mrg    this is called for each insn in the basic block.  If BEFORE_MEM is
    844  1.1  mrg    false, it is called for the instruction in the block that uses the
    845  1.1  mrg    index register for some memory reference that is currently being
    846  1.1  mrg    processed.  */
    847  1.1  mrg 
    848  1.1  mrg static bool
    849  1.1  mrg parse_add_or_inc (rtx_insn *insn, bool before_mem)
    850  1.1  mrg {
    851  1.1  mrg   rtx pat = single_set (insn);
    852  1.1  mrg   if (!pat)
    853  1.1  mrg     return false;
    854  1.1  mrg 
    855  1.1  mrg   /* Result must be single reg.  */
    856  1.1  mrg   if (!REG_P (SET_DEST (pat)))
    857  1.1  mrg     return false;
    858  1.1  mrg 
    859  1.1  mrg   if ((GET_CODE (SET_SRC (pat)) != PLUS)
    860  1.1  mrg       && (GET_CODE (SET_SRC (pat)) != MINUS))
    861  1.1  mrg     return false;
    862  1.1  mrg 
    863  1.1  mrg   if (!REG_P (XEXP (SET_SRC (pat), 0)))
    864  1.1  mrg     return false;
    865  1.1  mrg 
    866  1.1  mrg   inc_insn.insn = insn;
    867  1.1  mrg   inc_insn.pat = pat;
    868  1.1  mrg   inc_insn.reg_res = SET_DEST (pat);
    869  1.1  mrg   inc_insn.reg0 = XEXP (SET_SRC (pat), 0);
    870  1.1  mrg 
    871  1.1  mrg   /* Block any auto increment of the frame pointer since it expands into
    872  1.1  mrg      an addition and cannot be removed by copy propagation.  */
    873  1.1  mrg   if (inc_insn.reg0 == frame_pointer_rtx)
    874  1.1  mrg     return false;
    875  1.1  mrg 
    876  1.1  mrg   if (rtx_equal_p (inc_insn.reg_res, inc_insn.reg0))
    877  1.1  mrg     inc_insn.form = before_mem ? FORM_PRE_INC : FORM_POST_INC;
    878  1.1  mrg   else
    879  1.1  mrg     inc_insn.form = before_mem ? FORM_PRE_ADD : FORM_POST_ADD;
    880  1.1  mrg 
    881  1.1  mrg   if (CONST_INT_P (XEXP (SET_SRC (pat), 1)))
    882  1.1  mrg     {
    883  1.1  mrg       /* Process a = b + c where c is a const.  */
    884  1.1  mrg       inc_insn.reg1_is_const = true;
    885  1.1  mrg       if (GET_CODE (SET_SRC (pat)) == PLUS)
    886  1.1  mrg 	{
    887  1.1  mrg 	  inc_insn.reg1 = XEXP (SET_SRC (pat), 1);
    888  1.1  mrg 	  inc_insn.reg1_val = INTVAL (inc_insn.reg1);
    889  1.1  mrg 	}
    890  1.1  mrg       else
    891  1.1  mrg 	{
    892  1.1  mrg 	  inc_insn.reg1_val = -INTVAL (XEXP (SET_SRC (pat), 1));
    893  1.1  mrg 	  inc_insn.reg1 = GEN_INT (inc_insn.reg1_val);
    894  1.1  mrg 	}
    895  1.1  mrg       return true;
    896  1.1  mrg     }
    897  1.1  mrg   else if ((HAVE_PRE_MODIFY_REG || HAVE_POST_MODIFY_REG)
    898  1.1  mrg 	   && (REG_P (XEXP (SET_SRC (pat), 1)))
    899  1.1  mrg 	   && GET_CODE (SET_SRC (pat)) == PLUS)
    900  1.1  mrg     {
    901  1.1  mrg       /* Process a = b + c where c is a reg.  */
    902  1.1  mrg       inc_insn.reg1 = XEXP (SET_SRC (pat), 1);
    903  1.1  mrg       inc_insn.reg1_is_const = false;
    904  1.1  mrg 
    905  1.1  mrg       if (inc_insn.form == FORM_PRE_INC
    906  1.1  mrg 	  || inc_insn.form == FORM_POST_INC)
    907  1.1  mrg 	return true;
    908  1.1  mrg       else if (rtx_equal_p (inc_insn.reg_res, inc_insn.reg1))
    909  1.1  mrg 	{
    910  1.1  mrg 	  /* Reverse the two operands and turn *_ADD into *_INC since
    911  1.1  mrg 	     a = c + a.  */
    912  1.1  mrg 	  std::swap (inc_insn.reg0, inc_insn.reg1);
    913  1.1  mrg 	  inc_insn.form = before_mem ? FORM_PRE_INC : FORM_POST_INC;
    914  1.1  mrg 	  return true;
    915  1.1  mrg 	}
    916  1.1  mrg       else
    917  1.1  mrg 	return true;
    918  1.1  mrg     }
    919  1.1  mrg 
    920  1.1  mrg   return false;
    921  1.1  mrg }
    922  1.1  mrg 
    923  1.1  mrg 
    924  1.1  mrg /* A recursive function that checks all of the mem uses in
    925  1.1  mrg    ADDRESS_OF_X to see if any single one of them is compatible with
    926  1.1  mrg    what has been found in inc_insn.  To avoid accidental matches, we
    927  1.1  mrg    will only find MEMs with FINDREG, be it inc_insn.reg_res, be it
    928  1.1  mrg    inc_insn.reg0.
    929  1.1  mrg 
    930  1.1  mrg    -1 is returned for success.  0 is returned if nothing was found and
    931  1.1  mrg    1 is returned for failure. */
    932  1.1  mrg 
    933  1.1  mrg static int
    934  1.1  mrg find_address (rtx *address_of_x, rtx findreg)
    935  1.1  mrg {
    936  1.1  mrg   rtx x = *address_of_x;
    937  1.1  mrg   enum rtx_code code = GET_CODE (x);
    938  1.1  mrg   const char *const fmt = GET_RTX_FORMAT (code);
    939  1.1  mrg   int i;
    940  1.1  mrg   int value = 0;
    941  1.1  mrg   int tem;
    942  1.1  mrg 
    943  1.1  mrg   if (code == MEM && findreg == inc_insn.reg_res
    944  1.1  mrg       && rtx_equal_p (XEXP (x, 0), inc_insn.reg_res))
    945  1.1  mrg     {
    946  1.1  mrg       /* Match with *reg_res.  */
    947  1.1  mrg       mem_insn.mem_loc = address_of_x;
    948  1.1  mrg       mem_insn.reg0 = inc_insn.reg_res;
    949  1.1  mrg       mem_insn.reg1_is_const = true;
    950  1.1  mrg       mem_insn.reg1_val = 0;
    951  1.1  mrg       mem_insn.reg1 = GEN_INT (0);
    952  1.1  mrg       return -1;
    953  1.1  mrg     }
    954  1.1  mrg   if (code == MEM && inc_insn.reg1_is_const && inc_insn.reg0
    955  1.1  mrg       && findreg == inc_insn.reg0
    956  1.1  mrg       && rtx_equal_p (XEXP (x, 0), inc_insn.reg0))
    957  1.1  mrg     {
    958  1.1  mrg       /* Match with *reg0, assumed to be equivalent to
    959  1.1  mrg          *(reg_res - reg1_val); callers must check whether this is the case.  */
    960  1.1  mrg       mem_insn.mem_loc = address_of_x;
    961  1.1  mrg       mem_insn.reg0 = inc_insn.reg_res;
    962  1.1  mrg       mem_insn.reg1_is_const = true;
    963  1.1  mrg       mem_insn.reg1_val = -inc_insn.reg1_val;
    964  1.1  mrg       mem_insn.reg1 = GEN_INT (mem_insn.reg1_val);
    965  1.1  mrg       return -1;
    966  1.1  mrg     }
    967  1.1  mrg   if (code == MEM && findreg == inc_insn.reg_res
    968  1.1  mrg       && GET_CODE (XEXP (x, 0)) == PLUS
    969  1.1  mrg       && rtx_equal_p (XEXP (XEXP (x, 0), 0), inc_insn.reg_res))
    970  1.1  mrg     {
    971  1.1  mrg       rtx b = XEXP (XEXP (x, 0), 1);
    972  1.1  mrg       mem_insn.mem_loc = address_of_x;
    973  1.1  mrg       mem_insn.reg0 = inc_insn.reg_res;
    974  1.1  mrg       mem_insn.reg1 = b;
    975  1.1  mrg       mem_insn.reg1_is_const = inc_insn.reg1_is_const;
    976  1.1  mrg       if (CONST_INT_P (b))
    977  1.1  mrg 	{
    978  1.1  mrg 	  /* Match with *(reg0 + reg1) where reg1 is a const. */
    979  1.1  mrg 	  HOST_WIDE_INT val = INTVAL (b);
    980  1.1  mrg 	  if (inc_insn.reg1_is_const
    981  1.1  mrg 	      && (inc_insn.reg1_val == val || inc_insn.reg1_val == -val))
    982  1.1  mrg 	    {
    983  1.1  mrg 	      mem_insn.reg1_val = val;
    984  1.1  mrg 	      return -1;
    985  1.1  mrg 	    }
    986  1.1  mrg 	}
    987  1.1  mrg       else if (!inc_insn.reg1_is_const
    988  1.1  mrg 	       && rtx_equal_p (inc_insn.reg1, b))
    989  1.1  mrg 	/* Match with *(reg0 + reg1). */
    990  1.1  mrg 	return -1;
    991  1.1  mrg     }
    992  1.1  mrg 
    993  1.1  mrg   if (code == SIGN_EXTRACT || code == ZERO_EXTRACT)
    994  1.1  mrg     {
    995  1.1  mrg       /* If REG occurs inside a MEM used in a bit-field reference,
    996  1.1  mrg 	 that is unacceptable.  */
    997  1.1  mrg       if (find_address (&XEXP (x, 0), findreg))
    998  1.1  mrg 	return 1;
    999  1.1  mrg     }
   1000  1.1  mrg 
   1001  1.1  mrg   if (x == inc_insn.reg_res)
   1002  1.1  mrg     return 1;
   1003  1.1  mrg 
   1004  1.1  mrg   /* Time for some deep diving.  */
   1005  1.1  mrg   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
   1006  1.1  mrg     {
   1007  1.1  mrg       if (fmt[i] == 'e')
   1008  1.1  mrg 	{
   1009  1.1  mrg 	  tem = find_address (&XEXP (x, i), findreg);
   1010  1.1  mrg 	  /* If this is the first use, let it go so the rest of the
   1011  1.1  mrg 	     insn can be checked.  */
   1012  1.1  mrg 	  if (value == 0)
   1013  1.1  mrg 	    value = tem;
   1014  1.1  mrg 	  else if (tem != 0)
   1015  1.1  mrg 	    /* More than one match was found.  */
   1016  1.1  mrg 	    return 1;
   1017  1.1  mrg 	}
   1018  1.1  mrg       else if (fmt[i] == 'E')
   1019  1.1  mrg 	{
   1020  1.1  mrg 	  int j;
   1021  1.1  mrg 	  for (j = XVECLEN (x, i) - 1; j >= 0; j--)
   1022  1.1  mrg 	    {
   1023  1.1  mrg 	      tem = find_address (&XVECEXP (x, i, j), findreg);
   1024  1.1  mrg 	      /* If this is the first use, let it go so the rest of
   1025  1.1  mrg 		 the insn can be checked.  */
   1026  1.1  mrg 	      if (value == 0)
   1027  1.1  mrg 		value = tem;
   1028  1.1  mrg 	      else if (tem != 0)
   1029  1.1  mrg 		/* More than one match was found.  */
   1030  1.1  mrg 		return 1;
   1031  1.1  mrg 	    }
   1032  1.1  mrg 	}
   1033  1.1  mrg     }
   1034  1.1  mrg   return value;
   1035  1.1  mrg }
   1036  1.1  mrg 
   1037  1.1  mrg /* Once a suitable mem reference has been found and the MEM_INSN
   1038  1.1  mrg    structure has been filled in, FIND_INC is called to see if there is
   1039  1.1  mrg    a suitable add or inc insn that follows the mem reference and
   1040  1.1  mrg    determine if it is suitable to merge.
   1041  1.1  mrg 
   1042  1.1  mrg    In the case where the MEM_INSN has two registers in the reference,
   1043  1.1  mrg    this function may be called recursively.  The first time looking
   1044  1.1  mrg    for an add of the first register, and if that fails, looking for an
   1045  1.1  mrg    add of the second register.  The FIRST_TRY parameter is used to
   1046  1.1  mrg    only allow the parameters to be reversed once.  */
   1047  1.1  mrg 
   1048  1.1  mrg static bool
   1049  1.1  mrg find_inc (bool first_try)
   1050  1.1  mrg {
   1051  1.1  mrg   rtx_insn *insn;
   1052  1.1  mrg   basic_block bb = BLOCK_FOR_INSN (mem_insn.insn);
   1053  1.1  mrg   rtx_insn *other_insn;
   1054  1.1  mrg   df_ref def;
   1055  1.1  mrg 
   1056  1.1  mrg   /* Make sure this reg appears only once in this insn.  */
   1057  1.1  mrg   if (count_occurrences (PATTERN (mem_insn.insn), mem_insn.reg0, 1) != 1)
   1058  1.1  mrg     {
   1059  1.1  mrg       if (dump_file)
   1060  1.1  mrg 	fprintf (dump_file, "mem count failure\n");
   1061  1.1  mrg       return false;
   1062  1.1  mrg     }
   1063  1.1  mrg 
   1064  1.1  mrg   if (dump_file)
   1065  1.1  mrg     dump_mem_insn (dump_file);
   1066  1.1  mrg 
   1067  1.1  mrg   /* Find the next use that is an inc.  */
   1068  1.1  mrg   insn = get_next_ref (REGNO (mem_insn.reg0),
   1069  1.1  mrg 		       BLOCK_FOR_INSN (mem_insn.insn),
   1070  1.1  mrg 		       reg_next_inc_use);
   1071  1.1  mrg   if (!insn)
   1072  1.1  mrg     return false;
   1073  1.1  mrg 
   1074  1.1  mrg   /* Even though we know the next use is an add or inc because it came
   1075  1.1  mrg      from the reg_next_inc_use, we must still reparse.  */
   1076  1.1  mrg   if (!parse_add_or_inc (insn, false))
   1077  1.1  mrg     {
   1078  1.1  mrg       /* Next use was not an add.  Look for one extra case. It could be
   1079  1.1  mrg 	 that we have:
   1080  1.1  mrg 
   1081  1.1  mrg 	 *(a + b)
   1082  1.1  mrg 	 ...= a;
   1083  1.1  mrg 	 ...= b + a
   1084  1.1  mrg 
   1085  1.1  mrg 	 if we reverse the operands in the mem ref we would
   1086  1.1  mrg 	 find this.  Only try it once though.  */
   1087  1.1  mrg       if (first_try && !mem_insn.reg1_is_const)
   1088  1.1  mrg 	{
   1089  1.1  mrg 	  std::swap (mem_insn.reg0, mem_insn.reg1);
   1090  1.1  mrg 	  return find_inc (false);
   1091  1.1  mrg 	}
   1092  1.1  mrg       else
   1093  1.1  mrg 	return false;
   1094  1.1  mrg     }
   1095  1.1  mrg 
   1096  1.1  mrg   /* Need to assure that none of the operands of the inc instruction are
   1097  1.1  mrg      assigned to by the mem insn.  */
   1098  1.1  mrg   FOR_EACH_INSN_DEF (def, mem_insn.insn)
   1099  1.1  mrg     {
   1100  1.1  mrg       unsigned int regno = DF_REF_REGNO (def);
   1101  1.1  mrg       if ((regno == REGNO (inc_insn.reg0))
   1102  1.1  mrg 	  || (regno == REGNO (inc_insn.reg_res)))
   1103  1.1  mrg 	{
   1104  1.1  mrg 	  if (dump_file)
   1105  1.1  mrg 	    fprintf (dump_file, "inc conflicts with store failure.\n");
   1106  1.1  mrg 	  return false;
   1107  1.1  mrg 	}
   1108  1.1  mrg       if (!inc_insn.reg1_is_const && (regno == REGNO (inc_insn.reg1)))
   1109  1.1  mrg 	{
   1110  1.1  mrg 	  if (dump_file)
   1111  1.1  mrg 	    fprintf (dump_file, "inc conflicts with store failure.\n");
   1112  1.1  mrg 	  return false;
   1113  1.1  mrg 	}
   1114  1.1  mrg     }
   1115  1.1  mrg 
   1116  1.1  mrg   if (dump_file)
   1117  1.1  mrg     dump_inc_insn (dump_file);
   1118  1.1  mrg 
   1119  1.1  mrg   if (inc_insn.form == FORM_POST_ADD)
   1120  1.1  mrg     {
   1121  1.1  mrg       /* Make sure that there is no insn that assigns to inc_insn.res
   1122  1.1  mrg 	 between the mem_insn and the inc_insn.  */
   1123  1.1  mrg       rtx_insn *other_insn = get_next_ref (REGNO (inc_insn.reg_res),
   1124  1.1  mrg 					   BLOCK_FOR_INSN (mem_insn.insn),
   1125  1.1  mrg 					   reg_next_def);
   1126  1.1  mrg       if (other_insn != inc_insn.insn)
   1127  1.1  mrg 	{
   1128  1.1  mrg 	  if (dump_file)
   1129  1.1  mrg 	    fprintf (dump_file,
   1130  1.1  mrg 		     "result of add is assigned to between mem and inc insns.\n");
   1131  1.1  mrg 	  return false;
   1132  1.1  mrg 	}
   1133  1.1  mrg 
   1134  1.1  mrg       other_insn = get_next_ref (REGNO (inc_insn.reg_res),
   1135  1.1  mrg 				 BLOCK_FOR_INSN (mem_insn.insn),
   1136  1.1  mrg 				 reg_next_use);
   1137  1.1  mrg       if (other_insn
   1138  1.1  mrg 	  && (other_insn != inc_insn.insn)
   1139  1.1  mrg 	  && (DF_INSN_LUID (inc_insn.insn) > DF_INSN_LUID (other_insn)))
   1140  1.1  mrg 	{
   1141  1.1  mrg 	  if (dump_file)
   1142  1.1  mrg 	    fprintf (dump_file,
   1143  1.1  mrg 		     "result of add is used between mem and inc insns.\n");
   1144  1.1  mrg 	  return false;
   1145  1.1  mrg 	}
   1146  1.1  mrg 
   1147  1.1  mrg       /* For the post_add to work, the result_reg of the inc must not be
   1148  1.1  mrg 	 used in the mem insn since this will become the new index
   1149  1.1  mrg 	 register.  */
   1150  1.1  mrg       if (reg_overlap_mentioned_p (inc_insn.reg_res, PATTERN (mem_insn.insn)))
   1151  1.1  mrg 	{
   1152  1.1  mrg 	  if (dump_file)
   1153  1.1  mrg 	    fprintf (dump_file, "base reg replacement failure.\n");
   1154  1.1  mrg 	  return false;
   1155  1.1  mrg 	}
   1156  1.1  mrg     }
   1157  1.1  mrg 
   1158  1.1  mrg   if (mem_insn.reg1_is_const)
   1159  1.1  mrg     {
   1160  1.1  mrg       if (mem_insn.reg1_val == 0)
   1161  1.1  mrg 	{
   1162  1.1  mrg 	  if (!inc_insn.reg1_is_const)
   1163  1.1  mrg 	    {
   1164  1.1  mrg 	      /* The mem looks like *r0 and the rhs of the add has two
   1165  1.1  mrg 		 registers.  */
   1166  1.1  mrg 	      int luid = DF_INSN_LUID (inc_insn.insn);
   1167  1.1  mrg 	      if (inc_insn.form == FORM_POST_ADD)
   1168  1.1  mrg 		{
   1169  1.1  mrg 		  /* The trick is that we are not going to increment r0,
   1170  1.1  mrg 		     we are going to increment the result of the add insn.
   1171  1.1  mrg 		     For this trick to be correct, the result reg of
   1172  1.1  mrg 		     the inc must be a valid addressing reg.  */
   1173  1.1  mrg 		  addr_space_t as = MEM_ADDR_SPACE (*mem_insn.mem_loc);
   1174  1.1  mrg 		  if (GET_MODE (inc_insn.reg_res)
   1175  1.1  mrg 		      != targetm.addr_space.address_mode (as))
   1176  1.1  mrg 		    {
   1177  1.1  mrg 		      if (dump_file)
   1178  1.1  mrg 			fprintf (dump_file, "base reg mode failure.\n");
   1179  1.1  mrg 		      return false;
   1180  1.1  mrg 		    }
   1181  1.1  mrg 
   1182  1.1  mrg 		  /* We also need to make sure that the next use of
   1183  1.1  mrg 		     inc result is after the inc.  */
   1184  1.1  mrg 		  other_insn
   1185  1.1  mrg 		    = get_next_ref (REGNO (inc_insn.reg1), bb, reg_next_use);
   1186  1.1  mrg 		  if (other_insn && luid > DF_INSN_LUID (other_insn))
   1187  1.1  mrg 		    return false;
   1188  1.1  mrg 
   1189  1.1  mrg 		  if (!rtx_equal_p (mem_insn.reg0, inc_insn.reg0))
   1190  1.1  mrg 		    std::swap (inc_insn.reg0, inc_insn.reg1);
   1191  1.1  mrg 		}
   1192  1.1  mrg 
   1193  1.1  mrg 	      other_insn
   1194  1.1  mrg 		= get_next_ref (REGNO (inc_insn.reg1), bb, reg_next_def);
   1195  1.1  mrg 	      if (other_insn && luid > DF_INSN_LUID (other_insn))
   1196  1.1  mrg 		return false;
   1197  1.1  mrg 	    }
   1198  1.1  mrg 	}
   1199  1.1  mrg       /* Both the inc/add and the mem have a constant.  Need to check
   1200  1.1  mrg 	 that the constants are ok. */
   1201  1.1  mrg       else if ((mem_insn.reg1_val != inc_insn.reg1_val)
   1202  1.1  mrg 	       && (mem_insn.reg1_val != -inc_insn.reg1_val))
   1203  1.1  mrg 	return false;
   1204  1.1  mrg     }
   1205  1.1  mrg   else
   1206  1.1  mrg     {
   1207  1.1  mrg       /* The mem insn is of the form *(a + b) where a and b are both
   1208  1.1  mrg 	 regs.  It may be that in order to match the add or inc we
   1209  1.1  mrg 	 need to treat it as if it was *(b + a).  It may also be that
   1210  1.1  mrg 	 the add is of the form a + c where c does not match b and
   1211  1.1  mrg 	 then we just abandon this.  */
   1212  1.1  mrg 
   1213  1.1  mrg       int luid = DF_INSN_LUID (inc_insn.insn);
   1214  1.1  mrg       rtx_insn *other_insn;
   1215  1.1  mrg 
   1216  1.1  mrg       /* Make sure this reg appears only once in this insn.  */
   1217  1.1  mrg       if (count_occurrences (PATTERN (mem_insn.insn), mem_insn.reg1, 1) != 1)
   1218  1.1  mrg 	return false;
   1219  1.1  mrg 
   1220  1.1  mrg       if (inc_insn.form == FORM_POST_ADD)
   1221  1.1  mrg 	{
   1222  1.1  mrg 	  /* For this trick to be correct, the result reg of the inc
   1223  1.1  mrg 	     must be a valid addressing reg.  */
   1224  1.1  mrg 	  addr_space_t as = MEM_ADDR_SPACE (*mem_insn.mem_loc);
   1225  1.1  mrg 	  if (GET_MODE (inc_insn.reg_res)
   1226  1.1  mrg 	      != targetm.addr_space.address_mode (as))
   1227  1.1  mrg 	    {
   1228  1.1  mrg 	      if (dump_file)
   1229  1.1  mrg 		fprintf (dump_file, "base reg mode failure.\n");
   1230  1.1  mrg 	      return false;
   1231  1.1  mrg 	    }
   1232  1.1  mrg 
   1233  1.1  mrg 	  if (rtx_equal_p (mem_insn.reg0, inc_insn.reg0))
   1234  1.1  mrg 	    {
   1235  1.1  mrg 	      if (!rtx_equal_p (mem_insn.reg1, inc_insn.reg1))
   1236  1.1  mrg 		{
   1237  1.1  mrg 		  /* See comment above on find_inc (false) call.  */
   1238  1.1  mrg 		  if (first_try)
   1239  1.1  mrg 		    {
   1240  1.1  mrg 		      std::swap (mem_insn.reg0, mem_insn.reg1);
   1241  1.1  mrg 		      return find_inc (false);
   1242  1.1  mrg 		    }
   1243  1.1  mrg 		  else
   1244  1.1  mrg 		    return false;
   1245  1.1  mrg 		}
   1246  1.1  mrg 
   1247  1.1  mrg 	      /* Need to check that there are no assignments to b
   1248  1.1  mrg 		 before the add insn.  */
   1249  1.1  mrg 	      other_insn
   1250  1.1  mrg 		= get_next_ref (REGNO (inc_insn.reg1), bb, reg_next_def);
   1251  1.1  mrg 	      if (other_insn && luid > DF_INSN_LUID (other_insn))
   1252  1.1  mrg 		return false;
   1253  1.1  mrg 	      /* All ok for the next step.  */
   1254  1.1  mrg 	    }
   1255  1.1  mrg 	  else
   1256  1.1  mrg 	    {
   1257  1.1  mrg 	      /* We know that mem_insn.reg0 must equal inc_insn.reg1
   1258  1.1  mrg 		 or else we would not have found the inc insn.  */
   1259  1.1  mrg 	      std::swap (mem_insn.reg0, mem_insn.reg1);
   1260  1.1  mrg 	      if (!rtx_equal_p (mem_insn.reg0, inc_insn.reg0))
   1261  1.1  mrg 		{
   1262  1.1  mrg 		  /* See comment above on find_inc (false) call.  */
   1263  1.1  mrg 		  if (first_try)
   1264  1.1  mrg 		    return find_inc (false);
   1265  1.1  mrg 		  else
   1266  1.1  mrg 		    return false;
   1267  1.1  mrg 		}
   1268  1.1  mrg 	      /* To have gotten here know that.
   1269  1.1  mrg 	       *(b + a)
   1270  1.1  mrg 
   1271  1.1  mrg 	       ... = (b + a)
   1272  1.1  mrg 
   1273  1.1  mrg 	       We also know that the lhs of the inc is not b or a.  We
   1274  1.1  mrg 	       need to make sure that there are no assignments to b
   1275  1.1  mrg 	       between the mem ref and the inc.  */
   1276  1.1  mrg 
   1277  1.1  mrg 	      other_insn
   1278  1.1  mrg 		= get_next_ref (REGNO (inc_insn.reg0), bb, reg_next_def);
   1279  1.1  mrg 	      if (other_insn && luid > DF_INSN_LUID (other_insn))
   1280  1.1  mrg 		return false;
   1281  1.1  mrg 	    }
   1282  1.1  mrg 
   1283  1.1  mrg 	  /* Need to check that the next use of the add result is later than
   1284  1.1  mrg 	     add insn since this will be the reg incremented.  */
   1285  1.1  mrg 	  other_insn
   1286  1.1  mrg 	    = get_next_ref (REGNO (inc_insn.reg_res), bb, reg_next_use);
   1287  1.1  mrg 	  if (other_insn && luid > DF_INSN_LUID (other_insn))
   1288  1.1  mrg 	    return false;
   1289  1.1  mrg 	}
   1290  1.1  mrg       else /* FORM_POST_INC.  There is less to check here because we
   1291  1.1  mrg 	      know that operands must line up.  */
   1292  1.1  mrg 	{
   1293  1.1  mrg 	  if (!rtx_equal_p (mem_insn.reg1, inc_insn.reg1))
   1294  1.1  mrg 	    /* See comment above on find_inc (false) call.  */
   1295  1.1  mrg 	    {
   1296  1.1  mrg 	      if (first_try)
   1297  1.1  mrg 		{
   1298  1.1  mrg 		  std::swap (mem_insn.reg0, mem_insn.reg1);
   1299  1.1  mrg 		  return find_inc (false);
   1300  1.1  mrg 		}
   1301  1.1  mrg 	      else
   1302  1.1  mrg 		return false;
   1303  1.1  mrg 	    }
   1304  1.1  mrg 
   1305  1.1  mrg 	  /* To have gotten here know that.
   1306  1.1  mrg 	   *(a + b)
   1307  1.1  mrg 
   1308  1.1  mrg 	   ... = (a + b)
   1309  1.1  mrg 
   1310  1.1  mrg 	   We also know that the lhs of the inc is not b.  We need to make
   1311  1.1  mrg 	   sure that there are no assignments to b between the mem ref and
   1312  1.1  mrg 	   the inc.  */
   1313  1.1  mrg 	  other_insn
   1314  1.1  mrg 	    = get_next_ref (REGNO (inc_insn.reg1), bb, reg_next_def);
   1315  1.1  mrg 	  if (other_insn && luid > DF_INSN_LUID (other_insn))
   1316  1.1  mrg 	    return false;
   1317  1.1  mrg 	}
   1318  1.1  mrg     }
   1319  1.1  mrg 
   1320  1.1  mrg   if (inc_insn.form == FORM_POST_INC)
   1321  1.1  mrg     {
   1322  1.1  mrg       other_insn
   1323  1.1  mrg 	= get_next_ref (REGNO (inc_insn.reg0), bb, reg_next_use);
   1324  1.1  mrg       /* When we found inc_insn, we were looking for the
   1325  1.1  mrg 	 next add or inc, not the next insn that used the
   1326  1.1  mrg 	 reg.  Because we are going to increment the reg
   1327  1.1  mrg 	 in this form, we need to make sure that there
   1328  1.1  mrg 	 were no intervening uses of reg.  */
   1329  1.1  mrg       if (inc_insn.insn != other_insn)
   1330  1.1  mrg 	return false;
   1331  1.1  mrg     }
   1332  1.1  mrg 
   1333  1.1  mrg   return try_merge ();
   1334  1.1  mrg }
   1335  1.1  mrg 
   1336  1.1  mrg 
   1337  1.1  mrg /* A recursive function that walks ADDRESS_OF_X to find all of the mem
   1338  1.1  mrg    uses in pat that could be used as an auto inc or dec.  It then
   1339  1.1  mrg    calls FIND_INC for each one.  */
   1340  1.1  mrg 
   1341  1.1  mrg static bool
   1342  1.1  mrg find_mem (rtx *address_of_x)
   1343  1.1  mrg {
   1344  1.1  mrg   rtx x = *address_of_x;
   1345  1.1  mrg   enum rtx_code code = GET_CODE (x);
   1346  1.1  mrg   const char *const fmt = GET_RTX_FORMAT (code);
   1347  1.1  mrg   int i;
   1348  1.1  mrg 
   1349  1.1  mrg   if (code == MEM && REG_P (XEXP (x, 0)))
   1350  1.1  mrg     {
   1351  1.1  mrg       /* Match with *reg0.  */
   1352  1.1  mrg       mem_insn.mem_loc = address_of_x;
   1353  1.1  mrg       mem_insn.reg0 = XEXP (x, 0);
   1354  1.1  mrg       mem_insn.reg1_is_const = true;
   1355  1.1  mrg       mem_insn.reg1_val = 0;
   1356  1.1  mrg       mem_insn.reg1 = GEN_INT (0);
   1357  1.1  mrg       if (find_inc (true))
   1358  1.1  mrg 	return true;
   1359  1.1  mrg     }
   1360  1.1  mrg   if (code == MEM && GET_CODE (XEXP (x, 0)) == PLUS
   1361  1.1  mrg       && REG_P (XEXP (XEXP (x, 0), 0)))
   1362  1.1  mrg     {
   1363  1.1  mrg       rtx reg1 = XEXP (XEXP (x, 0), 1);
   1364  1.1  mrg       mem_insn.mem_loc = address_of_x;
   1365  1.1  mrg       mem_insn.reg0 = XEXP (XEXP (x, 0), 0);
   1366  1.1  mrg       mem_insn.reg1 = reg1;
   1367  1.1  mrg       if (CONST_INT_P (reg1))
   1368  1.1  mrg 	{
   1369  1.1  mrg 	  mem_insn.reg1_is_const = true;
   1370  1.1  mrg 	  /* Match with *(reg0 + c) where c is a const. */
   1371  1.1  mrg 	  mem_insn.reg1_val = INTVAL (reg1);
   1372  1.1  mrg 	  if (find_inc (true))
   1373  1.1  mrg 	    return true;
   1374  1.1  mrg 	}
   1375  1.1  mrg       else if (REG_P (reg1))
   1376  1.1  mrg 	{
   1377  1.1  mrg 	  /* Match with *(reg0 + reg1).  */
   1378  1.1  mrg 	  mem_insn.reg1_is_const = false;
   1379  1.1  mrg 	  if (find_inc (true))
   1380  1.1  mrg 	    return true;
   1381  1.1  mrg 	}
   1382  1.1  mrg     }
   1383  1.1  mrg 
   1384  1.1  mrg   if (code == SIGN_EXTRACT || code == ZERO_EXTRACT)
   1385  1.1  mrg     {
   1386  1.1  mrg       /* If REG occurs inside a MEM used in a bit-field reference,
   1387  1.1  mrg 	 that is unacceptable.  */
   1388  1.1  mrg       return false;
   1389  1.1  mrg     }
   1390  1.1  mrg 
   1391  1.1  mrg   /* Time for some deep diving.  */
   1392  1.1  mrg   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
   1393  1.1  mrg     {
   1394  1.1  mrg       if (fmt[i] == 'e')
   1395  1.1  mrg 	{
   1396  1.1  mrg 	  if (find_mem (&XEXP (x, i)))
   1397  1.1  mrg 	    return true;
   1398  1.1  mrg 	}
   1399  1.1  mrg       else if (fmt[i] == 'E')
   1400  1.1  mrg 	{
   1401  1.1  mrg 	  int j;
   1402  1.1  mrg 	  for (j = XVECLEN (x, i) - 1; j >= 0; j--)
   1403  1.1  mrg 	    if (find_mem (&XVECEXP (x, i, j)))
   1404  1.1  mrg 	      return true;
   1405  1.1  mrg 	}
   1406  1.1  mrg     }
   1407  1.1  mrg   return false;
   1408  1.1  mrg }
   1409  1.1  mrg 
   1410  1.1  mrg 
   1411  1.1  mrg /* Try to combine all incs and decs by constant values with memory
   1412  1.1  mrg    references in BB.  */
   1413  1.1  mrg 
   1414  1.1  mrg static void
   1415  1.1  mrg merge_in_block (int max_reg, basic_block bb)
   1416  1.1  mrg {
   1417  1.1  mrg   rtx_insn *insn;
   1418  1.1  mrg   rtx_insn *curr;
   1419  1.1  mrg   int success_in_block = 0;
   1420  1.1  mrg 
   1421  1.1  mrg   if (dump_file)
   1422  1.1  mrg     fprintf (dump_file, "\n\nstarting bb %d\n", bb->index);
   1423  1.1  mrg 
   1424  1.1  mrg   FOR_BB_INSNS_REVERSE_SAFE (bb, insn, curr)
   1425  1.1  mrg     {
   1426  1.1  mrg       bool insn_is_add_or_inc = true;
   1427  1.1  mrg 
   1428  1.1  mrg       if (!NONDEBUG_INSN_P (insn))
   1429  1.1  mrg 	{
   1430  1.1  mrg 	  if (DEBUG_BIND_INSN_P (insn))
   1431  1.1  mrg 	    {
   1432  1.1  mrg 	      df_insn_info *insn_info = DF_INSN_INFO_GET (insn);
   1433  1.1  mrg 	      df_ref use;
   1434  1.1  mrg 
   1435  1.1  mrg 	      if (dump_file)
   1436  1.1  mrg 		dump_insn_slim (dump_file, insn);
   1437  1.1  mrg 
   1438  1.1  mrg 	      FOR_EACH_INSN_INFO_USE (use, insn_info)
   1439  1.1  mrg 		reg_next_debug_use[DF_REF_REGNO (use)] = insn;
   1440  1.1  mrg 	    }
   1441  1.1  mrg 	  continue;
   1442  1.1  mrg 	}
   1443  1.1  mrg 
   1444  1.1  mrg       /* Reload should handle auto-inc within a jump correctly, while LRA
   1445  1.1  mrg 	 is known to have issues with autoinc.  */
   1446  1.1  mrg       if (JUMP_P (insn) && targetm.lra_p ())
   1447  1.1  mrg 	continue;
   1448  1.1  mrg 
   1449  1.1  mrg       if (dump_file)
   1450  1.1  mrg 	dump_insn_slim (dump_file, insn);
   1451  1.1  mrg 
   1452  1.1  mrg       /* Does this instruction increment or decrement a register?  */
   1453  1.1  mrg       if (parse_add_or_inc (insn, true))
   1454  1.1  mrg 	{
   1455  1.1  mrg 	  int regno = REGNO (inc_insn.reg_res);
   1456  1.1  mrg 	  /* Cannot handle case where there are three separate regs
   1457  1.1  mrg 	     before a mem ref.  Too many moves would be needed to be
   1458  1.1  mrg 	     profitable.  */
   1459  1.1  mrg 	  if ((inc_insn.form == FORM_PRE_INC) || inc_insn.reg1_is_const)
   1460  1.1  mrg 	    {
   1461  1.1  mrg 	      mem_insn.insn = get_next_ref (regno, bb, reg_next_use);
   1462  1.1  mrg 	      if (mem_insn.insn)
   1463  1.1  mrg 		{
   1464  1.1  mrg 		  bool ok = true;
   1465  1.1  mrg 		  if (!inc_insn.reg1_is_const)
   1466  1.1  mrg 		    {
   1467  1.1  mrg 		      /* We are only here if we are going to try a
   1468  1.1  mrg 			 HAVE_*_MODIFY_REG type transformation.  c is a
   1469  1.1  mrg 			 reg and we must sure that the path from the
   1470  1.1  mrg 			 inc_insn to the mem_insn.insn is both def and use
   1471  1.1  mrg 			 clear of c because the inc insn is going to move
   1472  1.1  mrg 			 into the mem_insn.insn.  */
   1473  1.1  mrg 		      int luid = DF_INSN_LUID (mem_insn.insn);
   1474  1.1  mrg 		      rtx_insn *other_insn
   1475  1.1  mrg 			= get_next_ref (REGNO (inc_insn.reg1), bb, reg_next_use);
   1476  1.1  mrg 
   1477  1.1  mrg 		      if (other_insn && luid > DF_INSN_LUID (other_insn))
   1478  1.1  mrg 			ok = false;
   1479  1.1  mrg 
   1480  1.1  mrg 		      other_insn
   1481  1.1  mrg 			= get_next_ref (REGNO (inc_insn.reg1), bb, reg_next_def);
   1482  1.1  mrg 
   1483  1.1  mrg 		      if (other_insn && luid > DF_INSN_LUID (other_insn))
   1484  1.1  mrg 			ok = false;
   1485  1.1  mrg 		    }
   1486  1.1  mrg 
   1487  1.1  mrg 		  if (dump_file)
   1488  1.1  mrg 		    dump_inc_insn (dump_file);
   1489  1.1  mrg 
   1490  1.1  mrg 		  if (ok && find_address (&PATTERN (mem_insn.insn),
   1491  1.1  mrg 					  inc_insn.reg_res) == -1)
   1492  1.1  mrg 		    {
   1493  1.1  mrg 		      if (dump_file)
   1494  1.1  mrg 			dump_mem_insn (dump_file);
   1495  1.1  mrg 		      if (try_merge ())
   1496  1.1  mrg 			{
   1497  1.1  mrg 			  success_in_block++;
   1498  1.1  mrg 			  insn_is_add_or_inc = false;
   1499  1.1  mrg 			}
   1500  1.1  mrg 		    }
   1501  1.1  mrg 		}
   1502  1.1  mrg 
   1503  1.1  mrg 	      if (insn_is_add_or_inc
   1504  1.1  mrg 		  /* find_address will only recognize an address
   1505  1.1  mrg 		     with a reg0 that's not reg_res when
   1506  1.1  mrg 		     reg1_is_const, so cut it off early if we
   1507  1.1  mrg 		     already know it won't match.  */
   1508  1.1  mrg 		  && inc_insn.reg1_is_const
   1509  1.1  mrg 		  && inc_insn.reg0
   1510  1.1  mrg 		  && inc_insn.reg0 != inc_insn.reg_res)
   1511  1.1  mrg 		{
   1512  1.1  mrg 		  /* If we identified an inc_insn that uses two
   1513  1.1  mrg 		     different pseudos, it's of the form
   1514  1.1  mrg 
   1515  1.1  mrg 		     (set reg_res (plus reg0 reg1))
   1516  1.1  mrg 
   1517  1.1  mrg 		     where reg1 is a constant (*).
   1518  1.1  mrg 
   1519  1.1  mrg 		     The next use of reg_res was not identified by
   1520  1.1  mrg 		     find_address as a mem_insn that we could turn
   1521  1.1  mrg 		     into auto-inc, so see if we find a suitable
   1522  1.1  mrg 		     MEM in the next use of reg0, as long as it's
   1523  1.1  mrg 		     before any subsequent use of reg_res:
   1524  1.1  mrg 
   1525  1.1  mrg 		     ... (mem (... reg0 ...)) ...
   1526  1.1  mrg 
   1527  1.1  mrg 		     ... reg_res ...
   1528  1.1  mrg 
   1529  1.1  mrg 		     In this case, we can turn the plus into a
   1530  1.1  mrg 		     copy, and the reg0 in the MEM address into a
   1531  1.1  mrg 		     post_inc of reg_res:
   1532  1.1  mrg 
   1533  1.1  mrg 		     (set reg_res reg0)
   1534  1.1  mrg 
   1535  1.1  mrg 		     ... (mem (... (post_add reg_res reg1) ...)) ...
   1536  1.1  mrg 
   1537  1.1  mrg 		     reg_res will then have the correct value at
   1538  1.1  mrg 		     subsequent uses, and reg0 will remain
   1539  1.1  mrg 		     unchanged.
   1540  1.1  mrg 
   1541  1.1  mrg 		     (*) We could support non-const reg1, but then
   1542  1.1  mrg 		     we'd have to check that reg1 remains
   1543  1.1  mrg 		     unchanged all the way to the modified MEM,
   1544  1.1  mrg 		     and we'd have to extend find_address to
   1545  1.1  mrg 		     represent a non-const negated reg1.  */
   1546  1.1  mrg 		  regno = REGNO (inc_insn.reg0);
   1547  1.1  mrg 		  rtx_insn *reg0_use = get_next_ref (regno, bb,
   1548  1.1  mrg 						     reg_next_use);
   1549  1.1  mrg 
   1550  1.1  mrg 		  /* Give up if the next use of reg0 is after the next
   1551  1.1  mrg 		     use of reg_res (same insn is ok; we might have
   1552  1.1  mrg 		     found a MEM with reg_res before, and that failed,
   1553  1.1  mrg 		     but now we try reg0, which might work), or defs
   1554  1.1  mrg 		     of reg_res (same insn is not ok, we'd introduce
   1555  1.1  mrg 		     another def in the same insn) or reg0.  */
   1556  1.1  mrg 		  if (reg0_use)
   1557  1.1  mrg 		    {
   1558  1.1  mrg 		      int luid = DF_INSN_LUID (reg0_use);
   1559  1.1  mrg 
   1560  1.1  mrg 		      /* It might seem pointless to introduce an
   1561  1.1  mrg 			 auto-inc if there's no subsequent use of
   1562  1.1  mrg 			 reg_res (i.e., mem_insn.insn == NULL), but
   1563  1.1  mrg 			 the next use might be in the next iteration
   1564  1.1  mrg 			 of a loop, and it won't hurt if we make the
   1565  1.1  mrg 			 change even if it's not needed.  */
   1566  1.1  mrg 		      if (mem_insn.insn
   1567  1.1  mrg 			  && luid > DF_INSN_LUID (mem_insn.insn))
   1568  1.1  mrg 			reg0_use = NULL;
   1569  1.1  mrg 
   1570  1.1  mrg 		      rtx_insn *other_insn
   1571  1.1  mrg 			= get_next_ref (REGNO (inc_insn.reg_res), bb,
   1572  1.1  mrg 					reg_next_def);
   1573  1.1  mrg 
   1574  1.1  mrg 		      if (other_insn && luid >= DF_INSN_LUID (other_insn))
   1575  1.1  mrg 			reg0_use = NULL;
   1576  1.1  mrg 
   1577  1.1  mrg 		      other_insn
   1578  1.1  mrg 			= get_next_ref (REGNO (inc_insn.reg0), bb,
   1579  1.1  mrg 					reg_next_def);
   1580  1.1  mrg 
   1581  1.1  mrg 		      if (other_insn && luid > DF_INSN_LUID (other_insn))
   1582  1.1  mrg 			reg0_use = NULL;
   1583  1.1  mrg 		    }
   1584  1.1  mrg 
   1585  1.1  mrg 		  mem_insn.insn = reg0_use;
   1586  1.1  mrg 
   1587  1.1  mrg 		  if (mem_insn.insn
   1588  1.1  mrg 		      && find_address (&PATTERN (mem_insn.insn),
   1589  1.1  mrg 				       inc_insn.reg0) == -1)
   1590  1.1  mrg 		    {
   1591  1.1  mrg 		      if (dump_file)
   1592  1.1  mrg 			dump_mem_insn (dump_file);
   1593  1.1  mrg 		      if (try_merge ())
   1594  1.1  mrg 			{
   1595  1.1  mrg 			  success_in_block++;
   1596  1.1  mrg 			  insn_is_add_or_inc = false;
   1597  1.1  mrg 			}
   1598  1.1  mrg 		    }
   1599  1.1  mrg 		}
   1600  1.1  mrg 	    }
   1601  1.1  mrg 	}
   1602  1.1  mrg       else
   1603  1.1  mrg 	{
   1604  1.1  mrg 	  insn_is_add_or_inc = false;
   1605  1.1  mrg 	  /* We can't use auto inc/dec for bare USEs and CLOBBERs,
   1606  1.1  mrg 	     since they aren't supposed to generate any code.  */
   1607  1.1  mrg 	  rtx_code code = GET_CODE (PATTERN (insn));
   1608  1.1  mrg 	  if (code != USE && code != CLOBBER)
   1609  1.1  mrg 	    {
   1610  1.1  mrg 	      mem_insn.insn = insn;
   1611  1.1  mrg 	      if (find_mem (&PATTERN (insn)))
   1612  1.1  mrg 		success_in_block++;
   1613  1.1  mrg 	    }
   1614  1.1  mrg 	}
   1615  1.1  mrg 
   1616  1.1  mrg       /* If the inc insn was merged with a mem, the inc insn is gone
   1617  1.1  mrg 	 and there is noting to update.  */
   1618  1.1  mrg       if (df_insn_info *insn_info = DF_INSN_INFO_GET (insn))
   1619  1.1  mrg 	{
   1620  1.1  mrg 	  df_ref def, use;
   1621  1.1  mrg 
   1622  1.1  mrg 	  /* Need to update next use.  */
   1623  1.1  mrg 	  FOR_EACH_INSN_INFO_DEF (def, insn_info)
   1624  1.1  mrg 	    {
   1625  1.1  mrg 	      if (reg_next_debug_use)
   1626  1.1  mrg 		reg_next_debug_use[DF_REF_REGNO (def)] = NULL;
   1627  1.1  mrg 	      reg_next_use[DF_REF_REGNO (def)] = NULL;
   1628  1.1  mrg 	      reg_next_inc_use[DF_REF_REGNO (def)] = NULL;
   1629  1.1  mrg 	      reg_next_def[DF_REF_REGNO (def)] = insn;
   1630  1.1  mrg 	    }
   1631  1.1  mrg 
   1632  1.1  mrg 	  FOR_EACH_INSN_INFO_USE (use, insn_info)
   1633  1.1  mrg 	    {
   1634  1.1  mrg 	      if (reg_next_debug_use)
   1635  1.1  mrg 		/* This may seem surprising, but we know we may only
   1636  1.1  mrg 		   modify the value of a REG between an insn and the
   1637  1.1  mrg 		   next nondebug use thereof.  Any debug uses after
   1638  1.1  mrg 		   the next nondebug use can be left alone, the REG
   1639  1.1  mrg 		   will hold the expected value there.  */
   1640  1.1  mrg 		reg_next_debug_use[DF_REF_REGNO (use)] = NULL;
   1641  1.1  mrg 	      reg_next_use[DF_REF_REGNO (use)] = insn;
   1642  1.1  mrg 	      if (insn_is_add_or_inc)
   1643  1.1  mrg 		reg_next_inc_use[DF_REF_REGNO (use)] = insn;
   1644  1.1  mrg 	      else
   1645  1.1  mrg 		reg_next_inc_use[DF_REF_REGNO (use)] = NULL;
   1646  1.1  mrg 	    }
   1647  1.1  mrg 	}
   1648  1.1  mrg       else if (dump_file)
   1649  1.1  mrg 	fprintf (dump_file, "skipping update of deleted insn %d\n",
   1650  1.1  mrg 		 INSN_UID (insn));
   1651  1.1  mrg     }
   1652  1.1  mrg 
   1653  1.1  mrg   /* If we were successful, try again.  There may have been several
   1654  1.1  mrg      opportunities that were interleaved.  This is rare but
   1655  1.1  mrg      gcc.c-torture/compile/pr17273.c actually exhibits this.  */
   1656  1.1  mrg   if (success_in_block)
   1657  1.1  mrg     {
   1658  1.1  mrg       /* In this case, we must clear these vectors since the trick of
   1659  1.1  mrg 	 testing if the stale insn in the block will not work.  */
   1660  1.1  mrg       if (reg_next_debug_use)
   1661  1.1  mrg 	memset (reg_next_debug_use, 0, max_reg * sizeof (rtx));
   1662  1.1  mrg       memset (reg_next_use, 0, max_reg * sizeof (rtx));
   1663  1.1  mrg       memset (reg_next_inc_use, 0, max_reg * sizeof (rtx));
   1664  1.1  mrg       memset (reg_next_def, 0, max_reg * sizeof (rtx));
   1665  1.1  mrg       df_recompute_luids (bb);
   1666  1.1  mrg       merge_in_block (max_reg, bb);
   1667  1.1  mrg     }
   1668  1.1  mrg }
   1669  1.1  mrg 
   1670  1.1  mrg /* Discover auto-inc auto-dec instructions.  */
   1671  1.1  mrg 
   1672  1.1  mrg namespace {
   1673  1.1  mrg 
   1674  1.1  mrg const pass_data pass_data_inc_dec =
   1675  1.1  mrg {
   1676  1.1  mrg   RTL_PASS, /* type */
   1677  1.1  mrg   "auto_inc_dec", /* name */
   1678  1.1  mrg   OPTGROUP_NONE, /* optinfo_flags */
   1679  1.1  mrg   TV_AUTO_INC_DEC, /* tv_id */
   1680  1.1  mrg   0, /* properties_required */
   1681  1.1  mrg   0, /* properties_provided */
   1682  1.1  mrg   0, /* properties_destroyed */
   1683  1.1  mrg   0, /* todo_flags_start */
   1684  1.1  mrg   TODO_df_finish, /* todo_flags_finish */
   1685  1.1  mrg };
   1686  1.1  mrg 
   1687  1.1  mrg class pass_inc_dec : public rtl_opt_pass
   1688  1.1  mrg {
   1689  1.1  mrg public:
   1690  1.1  mrg   pass_inc_dec (gcc::context *ctxt)
   1691  1.1  mrg     : rtl_opt_pass (pass_data_inc_dec, ctxt)
   1692  1.1  mrg   {}
   1693  1.1  mrg 
   1694  1.1  mrg   /* opt_pass methods: */
   1695  1.1  mrg   virtual bool gate (function *)
   1696  1.1  mrg     {
   1697  1.1  mrg       if (!AUTO_INC_DEC)
   1698  1.1  mrg 	return false;
   1699  1.1  mrg 
   1700  1.1  mrg       return (optimize > 0 && flag_auto_inc_dec);
   1701  1.1  mrg     }
   1702  1.1  mrg 
   1703  1.1  mrg 
   1704  1.1  mrg   unsigned int execute (function *);
   1705  1.1  mrg 
   1706  1.1  mrg }; // class pass_inc_dec
   1707  1.1  mrg 
   1708  1.1  mrg unsigned int
   1709  1.1  mrg pass_inc_dec::execute (function *fun ATTRIBUTE_UNUSED)
   1710  1.1  mrg {
   1711  1.1  mrg   if (!AUTO_INC_DEC)
   1712  1.1  mrg     return 0;
   1713  1.1  mrg 
   1714  1.1  mrg   basic_block bb;
   1715  1.1  mrg   int max_reg = max_reg_num ();
   1716  1.1  mrg 
   1717  1.1  mrg   if (!initialized)
   1718  1.1  mrg     init_decision_table ();
   1719  1.1  mrg 
   1720  1.1  mrg   mem_tmp = gen_rtx_MEM (Pmode, NULL_RTX);
   1721  1.1  mrg 
   1722  1.1  mrg   df_note_add_problem ();
   1723  1.1  mrg   df_analyze ();
   1724  1.1  mrg 
   1725  1.1  mrg   if (MAY_HAVE_DEBUG_BIND_INSNS)
   1726  1.1  mrg     reg_next_debug_use = XCNEWVEC (rtx_insn *, max_reg);
   1727  1.1  mrg   else
   1728  1.1  mrg     /* An earlier function may have had debug binds.  */
   1729  1.1  mrg     reg_next_debug_use = NULL;
   1730  1.1  mrg   reg_next_use = XCNEWVEC (rtx_insn *, max_reg);
   1731  1.1  mrg   reg_next_inc_use = XCNEWVEC (rtx_insn *, max_reg);
   1732  1.1  mrg   reg_next_def = XCNEWVEC (rtx_insn *, max_reg);
   1733  1.1  mrg   FOR_EACH_BB_FN (bb, fun)
   1734  1.1  mrg     merge_in_block (max_reg, bb);
   1735  1.1  mrg 
   1736  1.1  mrg   free (reg_next_debug_use);
   1737  1.1  mrg   free (reg_next_use);
   1738  1.1  mrg   free (reg_next_inc_use);
   1739  1.1  mrg   free (reg_next_def);
   1740  1.1  mrg 
   1741  1.1  mrg   mem_tmp = NULL;
   1742  1.1  mrg 
   1743  1.1  mrg   return 0;
   1744  1.1  mrg }
   1745  1.1  mrg 
   1746  1.1  mrg } // anon namespace
   1747  1.1  mrg 
   1748  1.1  mrg rtl_opt_pass *
   1749  1.1  mrg make_pass_inc_dec (gcc::context *ctxt)
   1750  1.1  mrg {
   1751  1.1  mrg   return new pass_inc_dec (ctxt);
   1752  1.1  mrg }
   1753