Annotation of researchv10dc/cmd/gcc/regclass.c, revision 1.1

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 = &reg_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 = &reg_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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.