|
|
1.1 ! root 1: /* Compute register class preferences for pseudo-registers. ! 2: Copyright (C) 1987 Free Software Foundation, Inc. ! 3: ! 4: This file is part of GNU CC. ! 5: ! 6: GNU CC is distributed in the hope that it will be useful, ! 7: but WITHOUT ANY WARRANTY. No author or distributor ! 8: accepts responsibility to anyone for the consequences of using it ! 9: or for whether it serves any particular purpose or works at all, ! 10: unless he says so in writing. Refer to the GNU CC General Public ! 11: License for full details. ! 12: ! 13: Everyone is granted permission to copy, modify and redistribute ! 14: GNU CC, but only under the conditions described in the ! 15: GNU CC General Public License. A copy of this license is ! 16: supposed to have been given to you along with GNU CC so you ! 17: can know your rights and responsibilities. It should be in a ! 18: file named COPYING. Among other things, the copyright notice ! 19: and this notice must be preserved on all copies. */ ! 20: ! 21: ! 22: /* This file contains two passes of the compiler: reg_scan and reg_class. ! 23: It also defines some tables of information about the hardware registers ! 24: and a function init_reg_sets to initialize the tables. */ ! 25: ! 26: #include "config.h" ! 27: #include "rtl.h" ! 28: #include "hard-reg-set.h" ! 29: #include "flags.h" ! 30: #include "basic-block.h" ! 31: #include "regs.h" ! 32: #include "insn-config.h" ! 33: #include "recog.h" ! 34: ! 35: #define max(A,B) ((A) > (B) ? (A) : (B)) ! 36: #define min(A,B) ((A) < (B) ? (A) : (B)) ! 37: ! 38: /* Register tables used by many passes. */ ! 39: ! 40: /* Indexed by hard register number, contains 1 for registers ! 41: that are fixed use (stack pointer, pc, frame pointer, etc.). ! 42: These are the registers that cannot be used to allocate ! 43: a pseudo reg whose life does not cross calls. */ ! 44: ! 45: char fixed_regs[FIRST_PSEUDO_REGISTER]; ! 46: ! 47: /* Same info as a HARD_REG_SET. */ ! 48: ! 49: HARD_REG_SET fixed_reg_set; ! 50: ! 51: /* Data for initializing the above. */ ! 52: ! 53: static char initial_fixed_regs[] = FIXED_REGISTERS; ! 54: ! 55: /* Indexed by hard register number, contains 1 for registers ! 56: that are fixed use or are clobbered by function calls. ! 57: These are the registers that cannot be used to allocate ! 58: a pseudo reg whose life crosses calls. */ ! 59: ! 60: char call_used_regs[FIRST_PSEUDO_REGISTER]; ! 61: ! 62: /* Same info as a HARD_REG_SET. */ ! 63: ! 64: HARD_REG_SET call_used_reg_set; ! 65: ! 66: /* Data for initializing the above. */ ! 67: ! 68: static char initial_call_used_regs[] = CALL_USED_REGISTERS; ! 69: ! 70: /* For each reg class, a HARD_REG_SET saying which registers are in it. */ ! 71: ! 72: HARD_REG_SET reg_class_contents[] = REG_CLASS_CONTENTS; ! 73: ! 74: /* For each reg class, table listing all the containing classes. */ ! 75: ! 76: enum reg_class reg_class_superclasses[N_REG_CLASSES][N_REG_CLASSES]; ! 77: ! 78: /* For each reg class, table listing all the classes contained in it. */ ! 79: ! 80: enum reg_class reg_class_subclasses[N_REG_CLASSES][N_REG_CLASSES]; ! 81: ! 82: /* For each pair of reg classes, ! 83: a largest reg class contained in their union. */ ! 84: ! 85: enum reg_class reg_class_subunion[N_REG_CLASSES][N_REG_CLASSES]; ! 86: ! 87: ! 88: /* Function called only once to initialize the tables above. */ ! 89: ! 90: void ! 91: init_reg_sets () ! 92: { ! 93: register int i, j; ! 94: ! 95: bcopy (initial_fixed_regs, fixed_regs, sizeof fixed_regs); ! 96: bcopy (initial_call_used_regs, call_used_regs, sizeof call_used_regs); ! 97: ! 98: /* This macro allows the fixed or call-used registers ! 99: to depend on target flags. */ ! 100: ! 101: #ifdef CONDITIONAL_REGISTER_USAGE ! 102: CONDITIONAL_REGISTER_USAGE ! 103: #endif ! 104: ! 105: /* Initialize "constant" tables. */ ! 106: ! 107: CLEAR_HARD_REG_SET (fixed_reg_set); ! 108: CLEAR_HARD_REG_SET (call_used_reg_set); ! 109: ! 110: for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) ! 111: { ! 112: if (fixed_regs[i]) ! 113: SET_HARD_REG_BIT (fixed_reg_set, i); ! 114: if (call_used_regs[i]) ! 115: SET_HARD_REG_BIT (call_used_reg_set, i); ! 116: } ! 117: ! 118: /* Initialize the table of subunions. ! 119: reg_class_subunion[I][J] gets the largest-numbered reg-class ! 120: that is contained in the union of classes I and J. */ ! 121: ! 122: for (i = 0; i < N_REG_CLASSES; i++) ! 123: { ! 124: for (j = 0; j < N_REG_CLASSES; j++) ! 125: { ! 126: #ifdef HARD_REG_SET ! 127: register /* Declare it register if it's a scalar. */ ! 128: #endif ! 129: HARD_REG_SET c; ! 130: register int k; ! 131: ! 132: COPY_HARD_REG_SET (c, reg_class_contents[i]); ! 133: IOR_HARD_REG_SET (c, reg_class_contents[j]); ! 134: for (k = 0; k < N_REG_CLASSES; k++) ! 135: { ! 136: GO_IF_HARD_REG_SUBSET (reg_class_contents[k], c, ! 137: subclass1); ! 138: continue; ! 139: ! 140: subclass1: ! 141: reg_class_subunion[i][j] = (enum reg_class) k; ! 142: } ! 143: } ! 144: } ! 145: ! 146: /* Initialize the tables of subclasses and superclasses of each reg class. ! 147: First clear the whole table, then add the elements as they are found. */ ! 148: ! 149: for (i = 0; i < N_REG_CLASSES; i++) ! 150: { ! 151: for (j = 0; j < N_REG_CLASSES; j++) ! 152: { ! 153: reg_class_superclasses[i][j] = LIM_REG_CLASSES; ! 154: reg_class_subclasses[i][j] = LIM_REG_CLASSES; ! 155: } ! 156: } ! 157: ! 158: for (i = 0; i < N_REG_CLASSES; i++) ! 159: { ! 160: if (i == (int) NO_REGS) ! 161: continue; ! 162: ! 163: for (j = i + 1; j < N_REG_CLASSES; j++) ! 164: { ! 165: enum reg_class *p; ! 166: ! 167: GO_IF_HARD_REG_SUBSET (reg_class_contents[i], reg_class_contents[j], ! 168: subclass); ! 169: continue; ! 170: subclass: ! 171: /* Reg class I is a subclass of J. ! 172: Add J to the table of superclasses of I. */ ! 173: p = ®_class_superclasses[i][0]; ! 174: while (*p != LIM_REG_CLASSES) p++; ! 175: *p = (enum reg_class) j; ! 176: /* Add I to the table of superclasses of J. */ ! 177: p = ®_class_subclasses[j][0]; ! 178: while (*p != LIM_REG_CLASSES) p++; ! 179: *p = (enum reg_class) i; ! 180: } ! 181: } ! 182: } ! 183: ! 184: /* Specify the usage characteristics of the register named NAME. ! 185: It should be a fixed register if FIXED and a ! 186: call-used register if CALL_USED. */ ! 187: ! 188: void ! 189: fix_register (name, fixed, call_used) ! 190: char *name; ! 191: int fixed, call_used; ! 192: { ! 193: static char *reg_names[] = REGISTER_NAMES; ! 194: int i; ! 195: ! 196: /* Decode the name and update the primary form of ! 197: the register info. */ ! 198: ! 199: for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) ! 200: if (!strcmp (reg_names[i], name)) ! 201: { ! 202: fixed_regs[i] = fixed; ! 203: call_used_regs[i] = call_used; ! 204: break; ! 205: } ! 206: ! 207: if (i == FIRST_PSEUDO_REGISTER) ! 208: { ! 209: warning ("unknown register name: %s", name); ! 210: return; ! 211: } ! 212: ! 213: /* Reinitialize the HARD_REG_SETs that have the same info. */ ! 214: ! 215: CLEAR_HARD_REG_SET (fixed_reg_set); ! 216: CLEAR_HARD_REG_SET (call_used_reg_set); ! 217: ! 218: for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) ! 219: { ! 220: if (fixed_regs[i]) ! 221: SET_HARD_REG_BIT (fixed_reg_set, i); ! 222: if (call_used_regs[i]) ! 223: SET_HARD_REG_BIT (call_used_reg_set, i); ! 224: } ! 225: } ! 226: ! 227: /* Now the data and code for the `regclass' pass, which happens ! 228: just before local-alloc. */ ! 229: ! 230: /* savings[R].savings[CL] is twice the amount saved by putting register R ! 231: in class CL. This data is used within `regclass' and freed ! 232: when it is finished. */ ! 233: ! 234: struct savings ! 235: { ! 236: short savings[N_REG_CLASSES]; ! 237: short memcost; ! 238: }; ! 239: ! 240: static struct savings *savings; ! 241: ! 242: /* (enum reg_class) prefclass[R] is the preferred class for pseudo number R. ! 243: This is available after `regclass' is run. */ ! 244: ! 245: static char *prefclass; ! 246: ! 247: /* preferred_or_nothing[R] is nonzero if we should put pseudo number R ! 248: in memory if we can't get its perferred class. ! 249: This is available after `regclass' is run. */ ! 250: ! 251: static char *preferred_or_nothing; ! 252: ! 253: void reg_class_record (); ! 254: void record_address_regs (); ! 255: ! 256: ! 257: /* Return the reg_class in which pseudo reg number REGNO is best allocated. ! 258: This function is sometimes called before the info has been computed. ! 259: When that happens, just return GENERAL_REGS, which is innocuous. */ ! 260: ! 261: enum reg_class ! 262: reg_preferred_class (regno) ! 263: int regno; ! 264: { ! 265: if (prefclass == 0) ! 266: return GENERAL_REGS; ! 267: return (enum reg_class) prefclass[regno]; ! 268: } ! 269: ! 270: int ! 271: reg_preferred_or_nothing (regno) ! 272: { ! 273: if (prefclass == 0) ! 274: return 0; ! 275: return preferred_or_nothing[regno]; ! 276: } ! 277: ! 278: /* This prevents dump_flow_info from losing if called ! 279: before regclass is run. */ ! 280: ! 281: int ! 282: regclass_init () ! 283: { ! 284: prefclass = 0; ! 285: } ! 286: ! 287: /* This is a pass of the compiler that scans all instructions ! 288: and calculates the preferred class for each pseudo-register. ! 289: This information can be accessed later by calling `reg_preferred_class'. ! 290: This pass comes just before local register allocation. */ ! 291: ! 292: void ! 293: regclass (f, nregs) ! 294: rtx f; ! 295: int nregs; ! 296: { ! 297: #ifdef REGISTER_CONSTRAINTS ! 298: register rtx insn; ! 299: register int i; ! 300: ! 301: init_recog (); ! 302: ! 303: /* Zero out our accumulation of the cost of each class for each reg. */ ! 304: ! 305: savings = (struct savings *) alloca (nregs * sizeof (struct savings)); ! 306: bzero (savings, nregs * sizeof (struct savings)); ! 307: ! 308: /* Scan the instructions and record each time it would ! 309: save code to put a certain register in a certain class. */ ! 310: ! 311: for (insn = f; insn; insn = NEXT_INSN (insn)) ! 312: if ((GET_CODE (insn) == INSN ! 313: && GET_CODE (PATTERN (insn)) != USE ! 314: && GET_CODE (PATTERN (insn)) != CLOBBER ! 315: && GET_CODE (PATTERN (insn)) != ASM_INPUT) ! 316: || (GET_CODE (insn) == JUMP_INSN ! 317: && GET_CODE (PATTERN (insn)) != ADDR_VEC ! 318: && GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC) ! 319: || GET_CODE (insn) == CALL_INSN) ! 320: { ! 321: if (GET_CODE (insn) == INSN && asm_noperands (PATTERN (insn)) > 0) ! 322: { ! 323: int noperands = asm_noperands (PATTERN (insn)); ! 324: rtx *operands = (rtx *) oballoc (noperands * sizeof (rtx)); ! 325: char **constraints ! 326: = (char **) oballoc (noperands * sizeof (char *)); ! 327: ! 328: decode_asm_operands (PATTERN (insn), operands, 0, constraints, 0); ! 329: ! 330: for (i = noperands - 1; i >= 0; i--) ! 331: reg_class_record (operands[i], ! 332: &constraints[i]); ! 333: ! 334: obfree (operands); ! 335: } ! 336: else ! 337: { ! 338: int insn_code_number = recog_memoized (insn); ! 339: ! 340: insn_extract (insn); ! 341: ! 342: for (i = insn_n_operands[insn_code_number] - 1; i >= 0; i--) ! 343: reg_class_record (recog_operand[i], ! 344: &insn_operand_constraint[insn_code_number][i]); ! 345: ! 346: /* Improve handling of two-address insns such as ! 347: (set X (ashift CONST Y)) where CONST must be made to match X. ! 348: Change it into two insns: (set X CONST) (set X (ashift X Y)). ! 349: If we left this for reloading, it would probably get three insns ! 350: because X and Y might go in the same place. ! 351: This prevents X and Y from receiving the same hard reg. */ ! 352: ! 353: if (optimize ! 354: && insn_n_operands[insn_code_number] >= 3 ! 355: && insn_operand_constraint[insn_code_number][1][0] == '0' ! 356: && insn_operand_constraint[insn_code_number][1][1] == 0 ! 357: && CONSTANT_P (recog_operand[1]) ! 358: && ! rtx_equal_p (recog_operand[0], recog_operand[1]) ! 359: && ! rtx_equal_p (recog_operand[0], recog_operand[2]) ! 360: && GET_CODE (recog_operand[0]) == REG) ! 361: { ! 362: rtx previnsn = prev_real_insn (insn); ! 363: rtx newinsn ! 364: = emit_insn_before (gen_move_insn (recog_operand[0], ! 365: recog_operand[1]), ! 366: insn); ! 367: ! 368: /* If this insn was the start of a basic block, ! 369: include the new insn in that block. */ ! 370: if (previnsn == 0 || GET_CODE (previnsn) == JUMP_INSN) ! 371: { ! 372: int b; ! 373: for (b = 0; b < n_basic_blocks; b++) ! 374: if (insn == basic_block_head[b]) ! 375: basic_block_head[b] = newinsn; ! 376: } ! 377: ! 378: /* This makes one more setting of new insns's destination. */ ! 379: reg_n_sets[REGNO (recog_operand[0])]++; ! 380: ! 381: *recog_operand_loc[1] = recog_operand[0]; ! 382: for (i = insn_n_dups[insn_code_number] - 1; i >= 0; i--) ! 383: if (recog_dup_num[i] == 1) ! 384: *recog_dup_loc[i] = recog_operand[0]; ! 385: ! 386: ! 387: } ! 388: } ! 389: } ! 390: ! 391: /* Now for each register look at how desirable each class is ! 392: and find which class is preferred. Store that in `prefclass[REGNO]'. */ ! 393: ! 394: prefclass = (char *) oballoc (nregs); ! 395: ! 396: preferred_or_nothing = (char *) oballoc (nregs); ! 397: ! 398: for (i = FIRST_PSEUDO_REGISTER; i < nregs; i++) ! 399: { ! 400: register int best_savings = 0; ! 401: enum reg_class best = ALL_REGS; ! 402: ! 403: /* This is an enum reg_class, but we call it an int ! 404: to save lots of casts. */ ! 405: register int class; ! 406: register struct savings *p = &savings[i]; ! 407: ! 408: for (class = (int) ALL_REGS - 1; class > 0; class--) ! 409: { ! 410: if (p->savings[class] > best_savings) ! 411: { ! 412: best_savings = p->savings[class]; ! 413: best = (enum reg_class) class; ! 414: } ! 415: else if (p->savings[class] == best_savings) ! 416: { ! 417: best = reg_class_subunion[(int)best][class]; ! 418: } ! 419: } ! 420: ! 421: #if 0 ! 422: /* Note that best_savings is twice number of places something ! 423: is saved. */ ! 424: if ((best_savings - p->savings[(int) GENERAL_REGS]) * 5 < reg_n_refs[i]) ! 425: prefclass[i] = (char) GENERAL_REGS; ! 426: else ! 427: prefclass[i] = (char) best; ! 428: #else ! 429: prefclass[i] = (char) best; ! 430: #endif ! 431: ! 432: /* reg_n_refs + p->memcost measures the cost of putting in memory. ! 433: If a GENERAL_REG is no better, don't even try for one. */ ! 434: if (reg_n_refs != 0) ! 435: preferred_or_nothing[i] ! 436: = ((best_savings - p->savings[(int) GENERAL_REGS]) / 2 ! 437: >= reg_n_refs[i] + p->memcost); ! 438: } ! 439: #endif /* REGISTER_CONSTRAINTS */ ! 440: } ! 441: ! 442: #ifdef REGISTER_CONSTRAINTS ! 443: ! 444: /* Scan an operand OP to which the constraint *CONSTRAINT_LOC should apply ! 445: and record the preferred register classes from the constraint for OP ! 446: if OP is a register. If OP is a memory reference, record suitable ! 447: preferences for registers used in the address. ! 448: ! 449: We can deduce both the insn code number and which operand in the insn ! 450: this is supposed to be from the position of CONSTRAINT_LOC ! 451: in the table of constraints. */ ! 452: ! 453: void ! 454: reg_class_record (op, constraint_loc) ! 455: rtx op; ! 456: char **constraint_loc; ! 457: { ! 458: char *constraint = *constraint_loc; ! 459: register char *p; ! 460: register enum reg_class class = NO_REGS; ! 461: char *next = 0; ! 462: int insn_code = (constraint_loc - insn_operand_constraint[0]) / MAX_RECOG_OPERANDS; ! 463: int memok = 0; ! 464: int double_cost = 0; ! 465: ! 466: while (1) ! 467: { ! 468: if (GET_CODE (op) == SUBREG) ! 469: op = SUBREG_REG (op); ! 470: else break; ! 471: } ! 472: ! 473: /* Memory reference: scan the address. */ ! 474: ! 475: if (GET_CODE (op) == MEM) ! 476: record_address_regs (XEXP (op, 0), 2, 0); ! 477: ! 478: if (GET_CODE (op) != REG) ! 479: { ! 480: /* If the constraint says the operand is supposed to BE an address, ! 481: scan it as one. */ ! 482: ! 483: if (constraint != 0 && constraint[0] == 'p') ! 484: record_address_regs (op, 2, 0); ! 485: return; ! 486: } ! 487: ! 488: /* Operand is a register: examine the constraint for specified classes. */ ! 489: ! 490: for (p = constraint; *p || next; p++) ! 491: { ! 492: if (*p == 0) ! 493: { ! 494: p = next; ! 495: next = 0; ! 496: } ! 497: switch (*p) ! 498: { ! 499: case '=': ! 500: case '?': ! 501: case '#': ! 502: case '!': ! 503: case '%': ! 504: case 'F': ! 505: case 'G': ! 506: case 'H': ! 507: case 'i': ! 508: case 'n': ! 509: case 's': ! 510: case 'p': ! 511: case ',': ! 512: break; ! 513: ! 514: case '+': ! 515: /* An input-output operand is twice as costly if it loses. */ ! 516: double_cost = 1; ! 517: break; ! 518: ! 519: case 'm': ! 520: case 'o': ! 521: memok = 1; ! 522: break; ! 523: ! 524: /* * means ignore following letter ! 525: when choosing register preferences. */ ! 526: case '*': ! 527: p++; ! 528: break; ! 529: ! 530: case 'g': ! 531: case 'r': ! 532: class ! 533: = reg_class_subunion[(int) class][(int) GENERAL_REGS]; ! 534: break; ! 535: ! 536: case '0': ! 537: case '1': ! 538: case '2': ! 539: case '3': ! 540: case '4': ! 541: /* If constraint says "match another operand", ! 542: use that operand's constraint to choose preferences. */ ! 543: next = insn_operand_constraint[insn_code][*p - '0']; ! 544: break; ! 545: ! 546: default: ! 547: class ! 548: = reg_class_subunion[(int) class][(int) REG_CLASS_FROM_LETTER (*p)]; ! 549: } ! 550: } ! 551: ! 552: { ! 553: register int i; ! 554: register struct savings *pp; ! 555: register enum reg_class class1; ! 556: int cost = 2 * (1 + double_cost); ! 557: pp = &savings[REGNO (op)]; ! 558: ! 559: /* Increment the savings for this reg ! 560: for each class contained in the one the constraint asks for. */ ! 561: ! 562: if (class != NO_REGS && class != ALL_REGS) ! 563: { ! 564: pp->savings[(int) class] += cost; ! 565: for (i = 0; ; i++) ! 566: { ! 567: class1 = reg_class_subclasses[(int)class][i]; ! 568: if (class1 == LIM_REG_CLASSES) ! 569: break; ! 570: pp->savings[(int) class1] += cost; ! 571: } ! 572: } ! 573: ! 574: if (! memok) ! 575: pp->memcost += 1 + 2 * double_cost; ! 576: } ! 577: } ! 578: ! 579: /* Record the pseudo registers we must reload into hard registers ! 580: in a subexpression of a memory address, X. ! 581: BCOST is the cost if X is a register and it fails to be in BASE_REG_CLASS. ! 582: ICOST is the cost if it fails to be in INDEX_REG_CLASS. */ ! 583: ! 584: void ! 585: record_address_regs (x, bcost, icost) ! 586: rtx x; ! 587: int bcost, icost; ! 588: { ! 589: register RTX_CODE code = GET_CODE (x); ! 590: ! 591: switch (code) ! 592: { ! 593: case CONST_INT: ! 594: case CONST: ! 595: case CC0: ! 596: case PC: ! 597: case SYMBOL_REF: ! 598: case LABEL_REF: ! 599: return; ! 600: ! 601: case PLUS: ! 602: /* When we have an address that is a sum, ! 603: we must determine whether registers are "base" or "index" regs. ! 604: If there is a sum of two registers, we must choose one to be ! 605: the "base". Luckily, we can use the REGNO_POINTER_FLAG ! 606: to make a good choice most of the time. */ ! 607: { ! 608: register RTX_CODE code0 = GET_CODE (XEXP (x, 0)); ! 609: register RTX_CODE code1 = GET_CODE (XEXP (x, 1)); ! 610: int icost0 = 0; ! 611: int icost1 = 0; ! 612: int suppress1 = 0; ! 613: int suppress0 = 0; ! 614: ! 615: if (code0 == MULT || code1 == MEM) ! 616: icost0 = 2; ! 617: else if (code1 == MULT || code0 == MEM) ! 618: icost1 = 2; ! 619: else if (code0 == CONST_INT) ! 620: suppress0 = 1; ! 621: else if (code1 == CONST_INT) ! 622: suppress1 = 1; ! 623: else if (code0 == REG && code1 == REG) ! 624: { ! 625: if (REGNO_POINTER_FLAG (REGNO (XEXP (x, 0)))) ! 626: icost1 = 2; ! 627: else if (REGNO_POINTER_FLAG (REGNO (XEXP (x, 1)))) ! 628: icost0 = 2; ! 629: else ! 630: icost0 = icost1 = 1; ! 631: } ! 632: else if (code0 == REG) ! 633: { ! 634: if (code1 == PLUS ! 635: && ! REGNO_POINTER_FLAG (REGNO (XEXP (x, 0)))) ! 636: icost0 = 2; ! 637: else ! 638: REGNO_POINTER_FLAG (REGNO (XEXP (x, 0))) = 1; ! 639: } ! 640: else if (code1 == REG) ! 641: { ! 642: if (code0 == PLUS ! 643: && ! REGNO_POINTER_FLAG (REGNO (XEXP (x, 1)))) ! 644: icost1 = 2; ! 645: else ! 646: REGNO_POINTER_FLAG (REGNO (XEXP (x, 1))) = 1; ! 647: } ! 648: ! 649: /* ICOST0 determines whether we are treating operand 0 ! 650: as a base register or as an index register. ! 651: SUPPRESS0 nonzero means it isn't a register at all. ! 652: ICOST1 and SUPPRESS1 are likewise for operand 1. */ ! 653: ! 654: if (! suppress0) ! 655: record_address_regs (XEXP (x, 0), 2 - icost0, icost0); ! 656: if (! suppress1) ! 657: record_address_regs (XEXP (x, 1), 2 - icost1, icost1); ! 658: } ! 659: break; ! 660: ! 661: case POST_INC: ! 662: case PRE_INC: ! 663: case POST_DEC: ! 664: case PRE_DEC: ! 665: /* Double the importance of a pseudo register that is incremented ! 666: or decremented, since it would take two extra insns ! 667: if it ends up in the wrong place. */ ! 668: record_address_regs (XEXP (x, 0), 2 * bcost, 2 * icost); ! 669: break; ! 670: ! 671: case REG: ! 672: { ! 673: register struct savings *pp; ! 674: register enum reg_class class, class1; ! 675: pp = &savings[REGNO (x)]; ! 676: ! 677: /* We have an address (or part of one) that is just one register. */ ! 678: ! 679: /* Record BCOST worth of savings for classes contained ! 680: in BASE_REG_CLASS. */ ! 681: ! 682: class = BASE_REG_CLASS; ! 683: if (class != NO_REGS && class != ALL_REGS) ! 684: { ! 685: register int i; ! 686: pp->savings[(int) class] += bcost; ! 687: for (i = 0; ; i++) ! 688: { ! 689: class1 = reg_class_subclasses[(int)class][i]; ! 690: if (class1 == LIM_REG_CLASSES) ! 691: break; ! 692: pp->savings[(int) class1] += bcost; ! 693: } ! 694: } ! 695: ! 696: /* Record ICOST worth of savings for classes contained ! 697: in INDEX_REG_CLASS. */ ! 698: ! 699: class = INDEX_REG_CLASS; ! 700: if (icost != 0 && class != NO_REGS && class != ALL_REGS) ! 701: { ! 702: register int i; ! 703: pp->savings[(int) class] += icost; ! 704: for (i = 0; ; i++) ! 705: { ! 706: class1 = reg_class_subclasses[(int)class][i]; ! 707: if (class1 == LIM_REG_CLASSES) ! 708: break; ! 709: pp->savings[(int) class1] += icost; ! 710: } ! 711: } ! 712: } ! 713: break; ! 714: ! 715: default: ! 716: { ! 717: register char *fmt = GET_RTX_FORMAT (code); ! 718: register int i; ! 719: for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) ! 720: if (fmt[i] == 'e') ! 721: record_address_regs (XEXP (x, i), bcost, icost); ! 722: } ! 723: } ! 724: } ! 725: #endif /* REGISTER_CONSTRAINTS */ ! 726: ! 727: /* This is the `regscan' pass of the compiler, run just before cse ! 728: and again just before loop. ! 729: ! 730: It finds the first and last use of each pseudo-register ! 731: and records them in the vectors regno_first_uid, regno_last_uid. ! 732: REPEAT is nonzero the second time this is called. */ ! 733: ! 734: /* Indexed by pseudo register number, gives uid of first insn using the reg ! 735: (as of the time reg_scan is called). */ ! 736: ! 737: short *regno_first_uid; ! 738: ! 739: /* Indexed by pseudo register number, gives uid of last insn using the reg ! 740: (as of the time reg_scan is called). */ ! 741: ! 742: short *regno_last_uid; ! 743: ! 744: void reg_scan_mark_refs (); ! 745: ! 746: void ! 747: reg_scan (f, nregs, repeat) ! 748: rtx f; ! 749: int nregs; ! 750: int repeat; ! 751: { ! 752: register rtx insn; ! 753: ! 754: if (!repeat) ! 755: regno_first_uid = (short *) oballoc (nregs * sizeof (short)); ! 756: bzero (regno_first_uid, nregs * sizeof (short)); ! 757: ! 758: if (!repeat) ! 759: regno_last_uid = (short *) oballoc (nregs * sizeof (short)); ! 760: bzero (regno_last_uid, nregs * sizeof (short)); ! 761: ! 762: for (insn = f; insn; insn = NEXT_INSN (insn)) ! 763: if (GET_CODE (insn) == INSN ! 764: || GET_CODE (insn) == CALL_INSN ! 765: || GET_CODE (insn) == JUMP_INSN) ! 766: reg_scan_mark_refs (PATTERN (insn), INSN_UID (insn)); ! 767: } ! 768: ! 769: void ! 770: reg_scan_mark_refs (x, uid) ! 771: rtx x; ! 772: int uid; ! 773: { ! 774: register RTX_CODE code = GET_CODE (x); ! 775: ! 776: switch (code) ! 777: { ! 778: case CONST_INT: ! 779: case CONST: ! 780: case CONST_DOUBLE: ! 781: case CC0: ! 782: case PC: ! 783: case SYMBOL_REF: ! 784: case LABEL_REF: ! 785: return; ! 786: ! 787: case REG: ! 788: { ! 789: register int regno = REGNO (x); ! 790: ! 791: regno_last_uid[regno] = uid; ! 792: if (regno_first_uid[regno] == 0) ! 793: regno_first_uid[regno] = uid; ! 794: } ! 795: break; ! 796: ! 797: default: ! 798: { ! 799: register char *fmt = GET_RTX_FORMAT (code); ! 800: register int i; ! 801: for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) ! 802: { ! 803: if (fmt[i] == 'e') ! 804: reg_scan_mark_refs (XEXP (x, i), uid); ! 805: else if (fmt[i] == 'E') ! 806: { ! 807: register int j; ! 808: for (j = XVECLEN (x, i) - 1; j >= 0; j--) ! 809: reg_scan_mark_refs (XVECEXP (x, i, j), uid); ! 810: } ! 811: } ! 812: } ! 813: } ! 814: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.