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