Annotation of researchv10dc/cmd/gcc/local-alloc.c, revision 1.1

1.1     ! root        1: ags genflags.o rtl.o $(LIBS)
        !             2: 
        !             3: genflags.o : genflags.c $(RTL_H)
        !             4:        $(CC) $(CFLAGS) -c genflags.c
        !             5: 
        !             6: gencodes : gencodes.o rtl.o $(OBSTACK1)
        !             7:        $(CC) $(CFLAGS) -o gencodes gencodes.o rtl.o $(LIBS)
        !             8: 
        !             9: gencodes.o : gencodes.c $(RTL_H)
        !            10:        $(CC) $(CFLAGS) -c gencodes.c
        !            11: 
        !            12: genemit : genemit.o rtl.o $(OBSTACK1)
        !            13:        $(CC) $(CFLAGS) -o genemit genemit.o rtl.o $(LIBS)
        !            14: 
        !            15: genemit.o : genemit.c $(RTL_H)
        !            16:        $(CC) $(CFLAGS) -c genemit.c
        !            17: 
        !            18: genrecog : genrecog.o rtl.o $(OBSTACK1)
        !            19:        $(CC) $(CFLAGS) -o genrecog genrecog.o rtl.o $(LIBS)
        !            20: 
        !            21: genrecog.o : genrecog.c $(RTL_H)
        !            22:        $(CC) $(CFLAGS) -c genrecog.c
        !            23: 
        !            24: genextract : genextract.o rtl.o $(OBSTACK1)
        !            25:        $(CC) $(CFLAGS) -o genextract genextract.o rtl.o $(LIBS)
        !            26: 
        !            27: genextract.o : genextract.c $(RTL_H)
        !            28:        $(CC) $(CFLAGS) -c genextract.c
        !            29: 
        !            30: genpeep : genpeep.o rtl.o $(OBSTACK1)
        !            31:        $(CC) $(CFLAGS) -o genpeep genpeep.o rtl.o $(LIBS)
        !            32: 
        !            33: genpeep.o : genpeep.c $(RTL_H)
        !            34:        $(CC) $(CFLAGS) -c genpeep.c
        !            35: 
        !            36: genoutput : genoutput.o rtl.o $(OBSTACK1)
        !            37:        $(CC) $(CFLAGS) -o genoutput genoutput.o rtl.o $(LIBS)
        !            38: 
        !            39: genoutput.o : genoutput.c $(RTL_H)
        !            40:        $(CC) $(CFLAGS) -c genoutput.c
        !            41: 
        !            42: # Making the preprocessor
        !            43: cpp: cccp
        !            44:        -rm -f cpp
        !            45:        ln cccp cpp
        !            46: cccp: cccp.o cexp.o version.o $(CLIB)
        !            47:        $(CC) $(CFLAGS) -o cccp cccp.o cexp.o version.o $(CLIB)
        !            48: cexp.o: cexp.c
        !            49: cexp.c: cexp.y
        !            50:        $(BISON) cexp.y
        !            51:        mv cexp.tab.c cexp.c
        !            52: cccp.o: cccp.c
        !            53: 
        !            54: # gnulib is not deleted because deleting it would be inconvenient
        !            55: # for most uses of this target.
        !            56: clean:
        !            57:        -rm -f $(STAGESTUFF) $(STAGE_GCC)
        !            58:        -rm -f *.s *.s[0-9] *.co *.greg *.lreg *.combine *.flow *.cse *.jump *.rtl *.tree *.loop
        !            59:        -rm -f core
        !            60: 
        !            61: # Copy the files into directories where they will be run.
        !            62: install: all
        !            63:        install cc1 $(libdir)/gcc-cc1
        !            64:        install -c -m 755 gnulib $(libdir)/gcc-gnulib
        !            65:        ranlib $(libdir)/gcc-gnulib
        !            66:        install cpp $(libdir)/gcc-cpp
        !            67:        install gcc $(bindir)
        !            68: 
        !            69: # do make -f ../gcc/Makefile maketest DIR=../gcc
        !            70: # in the intended test directory to make it a suitable test directory.
        !            71: maketest:
        !            72:        ln -s $(DIR)/*.[chy] .
        !            73:        ln -s $(DIR)/*.def .
        !            74:        ln -s $(DIR)/*.md .
        !            75:        ln -s $(DIR)/.gdbinit .
        !            76:        -ln -s $(DIR)/bison.simple .
        !            77:        ln -s $(DIR)/gcc .
        !            78:        ln -s $(DIR)/move-if-change .
        !            79:        ln -s $(DIR)/Makefile test-Makefile
        !            80:        -rm tm.h aux-output.c
        !            81:        make -f test-Makefile clean
        !            82: # You must create the necessary links tm.h, md and aux-output.c
        !            83: 
        !            84: # Copy the object files from a particular stage into a subdirectory.
        !            85: stage1: force
        !            86:        -mkdir stage1
        !            87:        mv $(STAGESTUFF) $(STAGE_GCC) stage1
        !            88:        ln gnulib stage1
        !            89: 
        !            90: stage2: force
        !            91:        -mkdir stage2
        !            92:        mv $(STAGESTUFF) $(STAGE_GCC) stage2
        !            93:        ln gnulib stage2
        !            94: 
        !            95: stage3: force
        !            96:        -mkdir stage3
        !            97:        mv $(STAGESTUFF) $(STAGE_GCC) stage3
        !            98:        ln gnulib stage3
        !            99: 
        !           100: .PHONY: stage1 stage2 stage3 #In GNU Make, ignore whether `stage*' exists.
        !           101: force:
        !           102: 
        !           103: TAGS: force
        !           104:        etags *.y *.h *.c
        !           105: .PHONY: TAGS
        !           106:   is a set of consecutive insns.  */
        !           107: 
        !           108: static int *qty_death;
        !           109: 
        !           110: /* Number of words needed to hold the data in quantity Q.
        !           111:    This depends on its machine mode.  It is used for these purposes:
        !           112:    1. If it is 0, the qty is not really in use and is not allocated.
        !           113:    2. It is used in computing the relative importances of qtys,
        !           114:       which determines the order in which we look for regs for them.
        !           115:    3. It is used in rules that prevent tying several registers of
        !           116:       different sizes in a way that is geometrically impossible
        !           117:       (see combine_regs).  */
        !           118: 
        !           119: static int *qty_size;
        !           120: 
        !           121: /* This holds the mode of the registers that are tied to qty Q,
        !           122:    or VOIDmode if registers with differing modes are tied together.  */
        !           123: 
        !           124: static enum machine_mode *qty_mode;
        !           125: 
        !           126: /* Nonzero if any of the regs tied to qty Q lives across a CALL_INSN.  */
        !           127: 
        !           128: static char *qty_crosses_call;
        !           129: 
        !           130: /* Nonzero means don't allocate qty Q if we can't get its preferred class.  */
        !           131: 
        !           132: static char *qty_preferred_or_nothing;
        !           133: 
        !           134: /* reg_qty[n] is the qty number of (REG n),
        !           135:    or -1 if (REG n) is not local to the current basic block,
        !           136:    or -2 if not known yet.  */
        !           137: 
        !           138: static int *reg_qty;
        !           139: 
        !           140: /* The offset (in words) of register N within its quantity.
        !           141:    This can be nonzero if register N is SImode, and has been tied
        !           142:    to a subreg of a DImode register.  */
        !           143: 
        !           144: static int *reg_offset;
        !           145: 
        !           146: /* Vector of substitutions of register numbers,
        !           147:    used to map pseudo regs into hardware regs.
        !           148:    This is set up as a result of register allocation.
        !           149:    Element N is the hard reg assigned to pseudo reg N,
        !           150:    or is -1 if no hard reg was assigned.
        !           151:    If N is a hard reg number, element N is N.  */
        !           152: 
        !           153: short *reg_renumber;
        !           154: 
        !           155: /* Set of hard registers live at the current point in the scan
        !           156:    of the instructions in a basic block.  */
        !           157: 
        !           158: static HARD_REG_SET regs_live;
        !           159: 
        !           160: /* Indexed by insn-number-within-basic-block,
        !           161:    a set or hard registers live *after* that insn.  */
        !           162: 
        !           163: static HARD_REG_SET *regs_live_at;
        !           164: 
        !           165: /* Nonzero if a CALL_INSN has been scanned
        !           166:    but we have not yet seen a reference to the value returned.  */
        !           167: 
        !           168: static int call_seen;
        !           169: 
        !           170: /* Communicate local vars `insn_number' and `b' from `block_alloc' to `reg_is_set'.  */
        !           171: 
        !           172: static int this_insn_number;
        !           173: static int this_block_number;
        !           174: 
        !           175: static void block_alloc ();
        !           176: static int combine_regs ();
        !           177: static void wipe_dead_reg ();
        !           178: static void reg_is_born ();
        !           179: static void reg_is_set ();
        !           180: static void mark_life ();
        !           181: static void post_mark_life ();
        !           182: static int qty_compare ();
        !           183: static int qty_compare_1 ();
        !           184: static int reg_meets_class_p ();
        !           185: static int reg_class_subset_p ();
        !           186: static void update_qty_class ();
        !           187: 
        !           188: /* Allocate a new quantity (new within current basic block)
        !           189:    for register number REGNO which is born in insn number INSN_NUMBER
        !           190:    within the block.  MODE and SIZE are info on reg REGNO.  */
        !           191: 
        !           192: static void
        !           193: alloc_qty (regno, mode, size, insn_number)
        !           194:      int regno;
        !           195:      enum machine_mode mode;
        !           196:      int size, insn_number;
        !           197: {
        !           198:   register int qty = next_qty++;
        !           199:   reg_qty[regno] = qty;
        !           200:   reg_offset[regno] = 0;
        !           201:   qty_size[qty] = size;
        !           202:   qty_mode[qty] = mode;
        !           203:   qty_birth[qty] = insn_number;
        !           204:   qty_crosses_call[qty] = reg_crosses_call[regno];
        !           205:   qty_min_class[qty] = reg_preferred_class (regno);
        !           206:   qty_preferred_or_nothing[qty] = reg_preferred_or_nothing (regno);
        !           207: }
        !           208: 
        !           209: /* Main entry point of this file.  */
        !           210: 
        !           211: void
        !           212: local_alloc ()
        !           213: {
        !           214:   register int b, i;
        !           215: 
        !           216:   /* Allocate vectors of temporary data.
        !           217:      See the declarations of these variables, above,
        !           218:      for what they mean.  */
        !           219: 
        !           220:   qty_phys_reg = (short *) alloca (max_regno * sizeof (short));
        !           221:   qty_phys_sugg = (short *) alloca (max_regno * sizeof (short));
        !           222:   qty_birth = (int *) alloca (max_regno * sizeof (int));
        !           223:   qty_death = (int *) alloca (max_regno * sizeof (int));
        !           224:   qty_size = (int *) alloca (max_regno * sizeof (int));
        !           225:   qty_mode = (enum machine_mode *) alloca (max_regno * sizeof (enum machine_mode));
        !           226:   qty_crosses_call = (char *) alloca (max_regno);
        !           227:   qty_min_class = (enum reg_class *) alloca (max_regno * sizeof (enum reg_class));
        !           228:   qty_preferred_or_nothing = (char *) alloca (max_regno);
        !           229: 
        !           230:   reg_qty = (int *) alloca (max_regno * sizeof (int));
        !           231:   reg_offset = (int *) alloca (max_regno * sizeof (int));
        !           232: 
        !           233:   reg_renumber = (short *) oballoc (max_regno * sizeof (short));
        !           234:   for (i = 0; i < max_regno; i++)
        !           235:     reg_renumber[i] = -1;
        !           236: 
        !           237:   /* Allocate each block's local registers, block by block.  */
        !           238: 
        !           239:   for (b = 0; b < n_basic_blocks; b++)
        !           240:     {
        !           241:       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
        !           242:        {
        !           243:          qty_phys_sugg[i] = -1;
        !           244:          reg_qty[i] = -2;
        !           245:        }
        !           246:       for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
        !           247:        {
        !           248:          qty_phys_sugg[i] = -1;
        !           249:          /* Set reg_qty to -2 for pseudos in this block, -1 for others.  */
        !           250:          if (reg_basic_block[i] == b && reg_n_deaths[i] == 1)
        !           251:            reg_qty[i] = -2;
        !           252:          else
        !           253:            reg_qty[i] = -1;
        !           254:        }
        !           255: 
        !           256:       bzero (reg_offset, max_regno * sizeof (int));
        !           257: 
        !           258:       bzero (qty_birth, max_regno * sizeof (int));
        !           259:       bzero (qty_death, max_regno * sizeof (int));
        !           260:       bzero (qty_size, max_regno * sizeof (int));
        !           261:       bzero (qty_mode, max_regno * sizeof (enum machine_mode));
        !           262:       bzero (qty_min_class, max_regno * sizeof (enum reg_class));
        !           263:       bzero (qty_preferred_or_nothing, max_regno);
        !           264:       bzero (qty_crosses_call, max_regno);
        !           265:       bzero (qty_phys_reg, max_regno * sizeof (short));
        !           266: 
        !           267:       next_qty = FIRST_PSEUDO_REGISTER;
        !           268: 
        !           269:       block_alloc (b);
        !           270:     }
        !           271: }
        !           272: 
        !           273: /* Allocate hard regs to the pseudo regs used only within block number B.
        !           274:    Only the pseudos that die but once can be handled.  */
        !           275: 
        !           276: static void
        !           277: block_alloc (b)
        !           278:      int b;
        !           279: {
        !           280:   register int i, q;
        !           281:   register rtx insn;
        !           282:   int insn_number = 0;
        !           283:   int insn_count = 0;
        !           284:   short *qty_order;
        !           285: 
        !           286:   call_seen = 0;
        !           287: 
        !           288:   /* Count the instructions in the basic block.  */
        !           289: 
        !           290:   insn = basic_block_end[b];
        !           291:   while (1)
        !           292:     {
        !           293:       insn_count++;
        !           294:       if (insn == basic_block_head[b])
        !           295:        break;
        !           296:       insn = PREV_INSN (insn);
        !           297:     }
        !           298: 
        !           299:   /* +1 to leave room for a post_mark_life at the last insn.  */
        !           300:   regs_live_at = (HARD_REG_SET *) alloca ((insn_count + 1)
        !           301:                                          * sizeof (HARD_REG_SET));
        !           302:   bzero (regs_live_at, insn_count * sizeof (HARD_REG_SET));
        !           303: 
        !           304:   /* Initialize table of hardware registers currently live.  */
        !           305: 
        !           306: #ifdef HARD_REG_SET
        !           307:   regs_live = *basic_block_live_at_start[b];
        !           308: #else
        !           309:   COPY_HARD_REG_SET (regs_live, basic_block_live_at_start[b]);
        !           310: #endif
        !           311: 
        !           312:   /* This loop scans the instructions of the basic block
        !           313:      and assigns quantities to registers.
        !           314:      It computes which registers to tie.  */
        !           315: 
        !           316:   insn = basic_block_head[b];
        !           317:   while (1)
        !           318:     {
        !           319:       register rtx body = PATTERN (insn);
        !           320:       insn_number++;
        !           321: 
        !           322:       if (GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN
        !           323:          || GET_CODE (insn) == CALL_INSN)
        !           324:        {
        !           325:          register rtx link;
        !           326:          register int win = 0;
        !           327:          register rtx r0, r1;
        !           328:          int combined_regno = -1;
        !           329: 
        !           330:          /* Is this insn suitable for tying two registers?
        !           331:             If so, try doing that.
        !           332:             Suitable insns are (set reg0 reg1) and
        !           333:             (set reg0 (arithop reg1 ...)).
        !           334:             Subregs in place of regs are also ok.
        !           335:             An insn with parallel sets is ok if the first set is suitable.
        !           336: 
        !           337:             If tying is done, WIN is set nonzero.  */
        !           338: 
        !           339:          if (GET_CODE (body) == SET
        !           340:              && (r0 = SET_DEST (body),
        !           341:                  GET_CODE (r0) == REG || GET_CODE (r0) == SUBREG)
        !           342:              && (r1 = SET_SRC (body),
        !           343:                  GET_CODE (r1) == REG || GET_CODE (r1) == SUBREG))
        !           344:            win = combine_regs (r1, r0, b, insn_number, insn);
        !           345:          else if (GET_CODE (body) == SET
        !           346:                   && (r0 = SET_DEST (body),
        !           347:                       GET_CODE (r0) == REG || GET_CODE (r0) == SUBREG)
        !           348:                   && GET_RTX_FORMAT (GET_CODE (SET_SRC (body)))[0] == 'e'
        !           349:                   && (r1 = XEXP (SET_SRC (body), 0),
        !           350:                       GET_CODE (r1) == REG || GET_CODE (r1) == SUBREG))
        !           351:            win = combine_regs (r1, r0, b, insn_number, insn);
        !           352:          else if (GET_CODE (body) == PARALLEL)
        !           353:            {
        !           354:              rtx set1 = XVECEXP (body, 0, 0);
        !           355:              if (GET_CODE (set1) == SET 
        !           356:                  && (r0 = SET_DEST (set1),
        !           357:                      GET_CODE (r0) == REG || GET_CODE (r0) == SUBREG)
        !           358:                  && GET_RTX_FORMAT (GET_CODE (SET_SRC (set1)))[0] == 'e'
        !           359:                  && (r1 = XEXP (SET_SRC (set1), 0),
        !           360:                      GET_CODE (r1) == REG || GET_CODE (r1) == SUBREG))
        !           361:                win = combine_regs (r1, r0, b, insn_number, insn);
        !           362:            }
        !           363: 
        !           364:          /* If registers were just tied, set COMBINED_REGNO
        !           365:             to the number of the register used in this insn
        !           366:             that was tied to the register set in this insn.
        !           367:             This register's qty should not be "killed".  */
        !           368: 
        !           369:          if (win)
        !           370:            {
        !           371:              while (GET_CODE (r1) == SUBREG)
        !           372:                r1 = SUBREG_REG (r1);
        !           373:              combined_regno = REGNO (r1);
        !           374:            }
        !           375: 
        !           376:          /* Mark the death of everything that dies in this instruction,
        !           377:             except for anything that was just combined or that was
        !           378:             just set in this insn.
        !           379:             They can be found on the REG_NOTES list of the instruction.  */
        !           380:          for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
        !           381:            if (XEXP (link, 0)
        !           382:                && REG_NOTE_KIND (link) == REG_DEAD
        !           383:                && combined_regno != REGNO (XEXP (link, 0)))
        !           384:              {
        !           385:                if (combined_regno >= 0 &&
        !           386:                    reg_qty[combined_regno] == reg_qty[REGNO (XEXP (link, 0))])
        !           387:                  /* Here for the death of the quotient in a divmod insn:
        !           388:                     something that was born and dead in this insn
        !           389:                     but combined with something else that also dies here.
        !           390:                     Mark the qty as dying one instruction later.  */
        !           391:                  wipe_dead_reg (XEXP (link, 0), insn_number,
        !           392:                                 insn_number + 1, b);
        !           393:                else
        !           394:                  wipe_dead_reg (XEXP (link, 0), insn_number, insn_number, b);
        !           395:              }
        !           396:            else if (REG_NOTE_KIND (link) == REG_EQUIV
        !           397:                     && GET_CODE (SET_DEST (body)) == REG
        !           398:                     && general_operand (XEXP (link, 0), VOIDmode)
        !           399:                     /* Don't inhibit allocation of a "constant" register
        !           400:                        that we have already tied to something else!  */
        !           401:                     && combined_regno < 0)
        !           402:              {
        !           403:                /* Also, if this insn introduces a "constant" register,
        !           404:                   that could just be replaced by the value it is given here
        !           405:                   (which can legitimately be an immediate operand),
        !           406:                   tell global-alloc not to allocate it
        !           407:                   unless it is used at least twice more.  */
        !           408:                i = REGNO (SET_DEST (body));
        !           409:                if (reg_n_sets[i] > 1)
        !           410:                  {
        !           411:                    /* Register is set in another place => not really constant.
        !           412:                       cse or flow can cause this to happen.
        !           413:                       Ok, forget we ever thought it was constant.  */
        !           414:                    GET_MODE (link) = VOIDmode;
        !           415:                  }
        !           416:                else if (reg_n_refs[i] <= 2)
        !           417:                  {
        !           418:                    /* For a parameter copy, do let global-alloc
        !           419:                       allocate it; otherwise we would be forced to
        !           420:                       have a frame pointer.  */
        !           421:                    if (! frame_pointer_needed
        !           422:                        && GET_CODE (SET_SRC (PATTERN (insn))) == MEM)
        !           423:                      reg_live_length[i] = -2;
        !           424:                    else
        !           425:                      reg_live_length[i] = -1;
        !           426: 
        !           427:                    /* If value is not constant, we have a parameter
        !           428:                       or a static chain pointer.  Tell local-alloc
        !           429:                       as well not to allocate it.  */
        !           430:                    if (! CONSTANT_P (SET_SRC (PATTERN (insn))))
        !           431:                      {
        !           432:                        reg_basic_block[i] = -2;
        !           433:                        reg_qty[i] = -1;
        !           434:                      }
        !           435:                  }
        !           436:                else
        !           437:                  /* In any case, lower its priority for global-alloc.  */
        !           438:                  reg_live_length[i] *= 2;
        !           439:              }
        !           440: 
        !           441:          /* Allocate qty numbers for all registers local to this block
        !           442:             that are born (set) in this instruction.
        !           443:             A pseudo that already has a qty is not changed.  */
        !           444: 
        !           445:          this_insn_number = insn_number;
        !           446:          this_block_number = b;
        !           447:          note_stores (PATTERN (insn), reg_is_set);
        !           448:        }
        !           449:       if (GET_CODE (insn) == CALL_INSN)
        !           450:        call_seen = 1;
        !           451:       if (insn == basic_block_end[b])
        !           452:        break;
        !           453:       /* We don't need this for the block's first instruction
        !           454:         since no regs we care about are live before that instruction.
        !           455:         Also we do not allocate space in regs_live_at for that instruction. */
        !           456:       IOR_HARD_REG_SET (regs_live_at[insn_number], regs_live);
        !           457:       insn = NEXT_INSN (insn);
        !           458:     }
        !           459: 
        !           460:   /* Now every register that is local to this basic block
        !           461:      has been given a hardware register (its reg_qty is < FIRST_PSEUDO_REGISTER)
        !           462:      or is tied to something not local to this block (reg_qty is -1)
        !           463:      or belongs to a qty with a known birth.  (Verify this now.)
        !           464: 
        !           465:      If a qty's death has not been established, it indicates a dead store.
        !           466:      That is ok if the insn is not entirely dead.
        !           467:      So set the qty'd death to just after its birth.  */
        !           468: 
        !           469:   for (i = FIRST_PSEUDO_REGISTER; i < next_qty; i++)
        !           470:     {
        !           471:       if (qty_birth[i] == 0)
        !           472:        abort ();
        !           473:       if (qty_death[i] == 0)
        !           474:        qty_death[i] = qty_birth[i] + 1;
        !           475:     }
        !           476: 
        !           477:   /* Now order the qtys so we assign them registers
        !           478:      in order of decreasing length of life.  */
        !           479:   qty_order = (short *) alloca (next_qty * sizeof (short));
        !           480:   for (i = FIRST_PSEUDO_REGISTER; i < next_qty; i++)
        !           481:     qty_order[i] = i;
        !           482: 
        !           483: #define EXCHANGE(I1, I2)  \
        !           484:   { i = qty_order[I1]; qty_order[I1] = qty_order[I2]; qty_order[I2] = i; }
        !           485: 
        !           486:   if (next_qty == 2 + FIRST_PSEUDO_REGISTER)
        !           487:     {
        !           488:       if (qty_compare (FIRST_PSEUDO_REGISTER + 1, FIRST_PSEUDO_REGISTER) > 0)
        !           489:        EXCHANGE (FIRST_PSEUDO_REGISTER, FIRST_PSEUDO_REGISTER + 1);
        !           490:     }
        !           491:   else if (next_qty == 3 + FIRST_PSEUDO_REGISTER)
        !           492:     {
        !           493:       if (qty_compare (FIRST_PSEUDO_REGISTER + 1, FIRST_PSEUDO_REGISTER) > 0)
        !           494:        EXCHANGE (FIRST_PSEUDO_REGISTER, FIRST_PSEUDO_REGISTER + 1);
        !           495:       if (qty_compare (FIRST_PSEUDO_REGISTER + 2, FIRST_PSEUDO_REGISTER + 1) > 0)
        !           496:        EXCHANGE (FIRST_PSEUDO_REGISTER + 2, FIRST_PSEUDO_REGISTER + 1);
        !           497:       if (qty_compare (FIRST_PSEUDO_REGISTER + 1, FIRST_PSEUDO_REGISTER) > 0)
        !           498:        EXCHANGE (FIRST_PSEUDO_REGISTER, FIRST_PSEUDO_REGISTER + 1);
        !           499:     }
        !           500:   else if (next_qty > 3 + FIRST_PSEUDO_REGISTER)
        !           501:     qsort (qty_order + FIRST_PSEUDO_REGISTER,
        !           502:           next_qty - FIRST_PSEUDO_REGISTER, sizeof (short), qty_compare_1);
        !           503: 
        !           504:   /* Now for each qty that is not a hardware register,
        !           505:      look for a hardware register to put it in.
        !           506:      First try the register class that is cheapest for this qty,
        !           507:      if there is more than one class.  */
        !           508: 
        !           509:   for (i = FIRST_PSEUDO_REGISTER; i < next_qty; i++)
        !           510:     {
        !           511:       q = qty_order[i];
        !           512:       if (qty_size[q] >= 0)
        !           513:        {
        !           514:          if (N_REG_CLASSES > 1)
        !           515:            {
        !           516:              qty_phys_reg[q] = find_free_reg (qty_crosses_call[q],
        !           517:                                               qty_min_class[q],
        !           518:                                               qty_mode[q], q,
        !           519:                                               qty_birth[q], qty_death[q]);
        !           520:              if (qty_phys_reg[q] >= 0)
        !           521:                continue;
        !           522:            }
        !           523: 
        !           524:          if (!qty_preferred_or_nothing[q])
        !           525:            qty_phys_reg[q] = find_free_reg (qty_crosses_call[q], GENERAL_REGS,
        !           526:                                             qty_mode[q], q,
        !           527:                                             qty_birth[q], qty_death[q]);
        !           528:        }
        !           529:     }
        !           530: 
        !           531:   /* Now propagate the register assignments
        !           532:      to the pseudo regs belonging to the qtys.  */
        !           533: 
        !           534:   for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
        !           535:     if (reg_qty[i] >= 0 && qty_phys_reg[reg_qty[i]] >= 0)
        !           536:       {
        !           537:        reg_renumber[i] = qty_phys_reg[reg_qty[i]] + reg_offset[i];
        !           538:       }
        !           539: }
        !           540: 
        !           541: /* Compare two quantities' priority for getting real registers.
        !           542:    We give quantities with hard-reg suggestions priority over all others.
        !           543:    We give longer-lived quantities higher priority
        !           544:    so that the shorter-lived ones will tend to be in the same places
        !           545:    which gives in general the maximum room for the regs to
        !           546:    be allocated by global-alloc.  */
        !           547: 
        !           548: static int
        !           549: qty_compare (q1, q2)
        !           550:      int q1, q2;
        !           551: {
        !           552:   register int tem = (qty_phys_sugg[q2] >= 0) - (qty_phys_sugg[q1] >= 0);
        !           553:   if (tem != 0) return tem;
        !           554:   return -((qty_death[q1] - qty_birth[q1]) * qty_size[q2]
        !           555:           - (qty_death[q2] - qty_birth[q2]) * qty_size[q1]);
        !           556: }
        !           557: 
        !           558: static int
        !           559: qty_compare_1 (q1, q2)
        !           560:      short *q1, *q2;
        !           561: {
        !           562:   register int tem = (qty_phys_sugg[*q2] >= 0) - (qty_phys_sugg[*q1] >= 0);
        !           563:   if (tem != 0) return tem;
        !           564:   return -((qty_death[*q1] - qty_birth[*q1]) * qty_size[*q2]
        !           565:           - (qty_death[*q2] - qty_birth[*q2]) * qty_size[*q1]);
        !           566: }
        !           567: 
        !           568: /* Attempt to combine the two registers (rtx's) USEDREG and SETREG.
        !           569:    Returns 1 if have done so, or 0 if cannot.
        !           570: 
        !           571:    Combining registers means marking them as having the same quantity
        !           572:    and adjusting the offsets within the quantity if either of
        !           573:    them is a SUBREG).
        !           574: 
        !           575:    We don't actually combine a hard reg with a pseudo; instead
        !           576:    we just record the hard reg as the suggestion for the pseudo's quantity.
        !           577:    If we really combined them, we could lose if the pseudo lives
        !           578:    across an insn that clobbers the hard reg (eg, movstr).
        !           579: 
        !           580:    This refusal to actually tie a hard reg with a pseudo is a recent change
        !           581:    and the code that used to deal with pseudos that have already been
        !           582:    tied to hard regs has not been removed.
        !           583: 
        !           584:    There are elaborate checks for the validity of combining.  */
        !           585: 
        !           586:    
        !           587: static int
        !           588: combine_regs (usedreg, setreg, b, insn_number, insn)
        !           589:      rtx usedreg, setreg;
        !           590:      int b;
        !           591:      int insn_number;
        !           592:      rtx insn;
        !           593: {
        !           594:   register int ureg, sreg;
        !           595:   register int offset = 0;
        !           596:   int usize, ssize;
        !           597:   register int sqty;
        !           598: 
        !           599:   while (GET_CODE (usedreg) == SUBREG)
        !           600:     {
        !           601:       offset += SUBREG_WORD (usedreg);
        !           602:       usedreg = SUBREG_REG (usedreg);
        !           603:     }
        !           604:   if (GET_CODE (usedreg) != REG)
        !           605:     return 0;
        !           606:   ureg = REGNO (usedreg);
        !           607:   usize = REG_SIZE (usedreg);
        !           608: 
        !           609: #if 0
        !           610:   /* Function value register is assigned implicitly by function calls,
        !           611:      but since that is implicit, reg_is_born will not
        !           612:      have been called for it.  Do so now
        !           613:      if this is the first use following a function call.  */
        !           614:   if (FUNCTION_VALUE_REGNO_P (ureg) && call_seen)
        !           615:     {
        !           616:       reg_is_born (usedreg, insn_number, -1);
        !           617:       call_seen = 0;
        !           618:     }
        !           619: #endif
        !           620: 
        !           621:   while (GET_CODE (setreg) == SUBREG)
        !           622:     {
        !           623:       offset -= SUBREG_WORD (setreg);
        !           624:       setreg = SUBREG_REG (setreg);
        !           625:     }
        !           626:   if (GET_CODE (setreg) != REG)
        !           627:     return 0;
        !           628:   sreg = REGNO (setreg);
        !           629:   ssize = REG_SIZE (setreg);
        !           630: 
        !           631:   /* Do not combine registers unless one fits within the other.  */
        !           632:   if (offset > 0 && usize + offset > ssize)
        !           633:     return 0;
        !           634:   if (offset < 0 && usize + offset < ssize)
        !           635:     return 0;
        !           636:   /* Do not combine with a smaller already-assigned object
        !           637:      if that smaller object is already combined with something bigger
        !           638:      or if that smaller object is a hard reg.
        !           639:      In the latter case, we would implicitly be using consecutive
        !           640:      hard regs, and there is no code to keep track of that.
        !           641:      (This is overcautious; we could check that ssize actually
        !           642:      requires more hard regs at this spot.)  */
        !           643:   if (ssize > usize && reg_qty[ureg] >= 0
        !           644:       && (usize < qty_size[reg_qty[ureg]]
        !           645:          || reg_qty[ureg] < FIRST_PSEUDO_REGISTER))
        !           646:     return 0;
        !           647: 
        !           648:   /* Don't do anything with the non-allocatable registers.
        !           649:      Also, don't tie a call-clobberable register
        !           650:      to something that must live across calls.
        !           651:      Also, don't tie a hardware register to anything larger than it.  */
        !           652:   if (ureg < FIRST_PSEUDO_REGISTER)
        !           653:     {
        !           654:       if (fixed_regs[ureg])
        !           655:        return 0;
        !           656:       if (reg_crosses_call[sreg] && call_used_regs[ureg])
        !           657:        return 0;
        !           658:       if (usize < ssize)
        !           659:        return 0;
        !           660:     }
        !           661: 
        !           662:   if (sreg < FIRST_PSEUDO_REGISTER)
        !           663:     {
        !           664:       if (fixed_regs[sreg])
        !           665:        return 0;
        !           666:       if (reg_crosses_call[ureg] && call_used_regs[sreg])
        !           667:        return 0;
        !           668:       if (ssize < usize)
        !           669:        return 0;
        !           670:     }
        !           671: 
        !           672:   /* Don't tie something that crosses calls
        !           673:      to something tied to a call-clobbered hardware register.  */
        !           674:   if (reg_qty[ureg] < FIRST_PSEUDO_REGISTER && reg_qty[ureg] >= 0
        !           675:       && call_used_regs[reg_qty[ureg]]
        !           676:       && reg_crosses_call[sreg])
        !           677:     return 0;
        !           678:   if (reg_qty[sreg] < FIRST_PSEUDO_REGISTER && reg_qty[sreg] >= 0
        !           679:       && call_used_regs[reg_qty[sreg]]
        !           680:       && reg_crosses_call[ureg])
        !           681:     return 0;
        !           682: 
        !           683:   /* Tying something to itself is ok iff no offset involved.  */
        !           684: 
        !           685:   if (ureg == sreg)
        !           686:     return offset == 0;
        !           687: 
        !           688:   /* Don't try to connect two different hardware registers.  */
        !           689: 
        !           690:   if (ureg < FIRST_PSEUDO_REGISTER && sreg < FIRST_PSEUDO_REGISTER)
        !           691:     return 0;
        !           692: 
        !           693:   /* Don't connect two different machine modes if they have different
        !           694:      implications as to which registers may be used.  */
        !           695: 
        !           696:   if (!MODES_TIEABLE_P (GET_MODE (usedreg), GET_MODE (setreg)))
        !           697:     return 0;
        !           698: 
        !           699:   /* Now, if one of UREG and SREG is a hard reg and the other is
        !           700:      a pseudo, record the hard reg as the qty_phys_sugg for the pseudo
        !           701:      instead of tying them.  */
        !           702:   /* Return "failure" so that the lifespan of UREG is terminated here;
        !           703:      that way the two lifespans will be disjoint and nothing will prevent
        !           704:      the pseudo reg from being given this hard reg.  */
        !           705: 
        !           706:   if (ureg < FIRST_PSEUDO_REGISTER)
        !           707:     {
        !           708:       if (reg_qty[sreg] == -2)
        !           709:        reg_is_born (setreg, insn_number, b);
        !           710:       if (reg_qty[ureg] == -2)
        !           711:        reg_is_born (usedreg, insn_number, b);
        !           712:       if (reg_qty[sreg] >= 0)
        !           713:        qty_phys_sugg[reg_qty[sreg]] = ureg;
        !           714:       return 0;
        !           715:     }
        !           716:   if (sreg < FIRST_PSEUDO_REGISTER)
        !           717:     {
        !           718:       if (reg_qty[sreg] == -2)
        !           719:        reg_is_born (setreg, insn_number, b);
        !           720:       if (reg_qty[ureg] == -2)
        !           721:        reg_is_born (usedreg, insn_number, b);
        !           722:       /* If UREG already has a suggested hard reg, don't override it,
        !           723:         since the most likely case is on a risc machine
        !           724:         when a pseudo gets a subroutine result and is then returned by
        !           725:         this function.  In this case, the outgoing register window
        !           726:         is probably a better place to use.  */
        !           727:    0 for the whole things.  */
        !           728: 
        !           729:   fmt = GET_RTX_FORMAT (code);
        !           730:   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
        !           731:     {
        !           732:       register int j;
        !           733:       switch (fmt[i])
        !           734:        {
        !           735:        case 'i':
        !           736:          if (XINT (x, i) != XINT (y, i))
        !           737:            return 0;
        !           738:          break;
        !           739: 
        !           740:        case 's':
        !           741:          if (strcmp (XSTR (x, i), XSTR (y, i)))
        !           742:            return 0;
        !           743:          break;
        !           744: 
        !           745:        case 'e':
        !           746:          if (! rtx_renumbered_equal_p (XEXP (x, i), XEXP (y, i)))
        !           747:            return 0;
        !           748:          break;
        !           749: 
        !           750:        case '0':
        !           751:          break;
        !           752: 
        !           753:        case 'E':
        !           754:          if (XVECLEN (x, i) != XVECLEN (y, i))
        !           755:            return 0;
        !           756:          for (j ill live may already be tied to it.  */
        !           757: 
        !           758:   if (reg_qty[sreg] != -2)
        !           759:     return 0;
        !           760: 
        !           761:   /* Summarize the status of what we know about SREG in SQTY:
        !           762:      >= 0 for a hard reg, -2 for a pseudo local to the basic block,
        !           763:      -1 for a pseudo not local to the basic block.
        !           764:      Note that reg_n_deaths[sreg]==0 for a dead store.  */
        !           765: 
        !           766:   sqty = -2;
        !           767:   if (sreg < FIRST_PSEUDO_REGISTER)
        !           768:     sqty = sreg;
        !           769:   else if (reg_basic_block[sreg] != b || reg_n_deaths[sreg] > 1)
        !           770:     sqty = -1;
        !           771: 
        !           772:   /* For now, since global_alloc has no idea of tying,
        !           773:      there is no use noting those local pseudos that could
        !           774:      profitably be delayed till global_alloc and get tied to global ones.
        !           775:      So right now give up if either SREG or UREG is a pseudo
        !           776:      not local to the block.  */
        !           777: 
        !           778:   if (reg_qty[ureg] == -1 || sqty == -1)
        !           779:     return 0;
        !           780: 
        !           781:   /* If SREG is not local to the basic block, or if it is a hard reg,
        !           782:      then tie UREG (and all others it is tied to) to SREG.
        !           783:      Only if UREG is a pseudo-reg local to this basic block
        !           784:      and not already tied to a hardware register,
        !           785:      and SREG is 1) external to the block or 2) a hardware register.
        !           786:      Also if SREG is a hardware register insist that it be in the class
        !           787:      that UREG and its other tied regs want to be in.  */
        !           788: 
        !           789:   if (sqty != -2 && ureg >= FIRST_PSEUDO_REGISTER
        !           790:       && reg_qty[ureg] >= FIRST_PSEUDO_REGISTER
        !           791: #if 0
        !           792: /* qty_best_class would require info not currently computed until
        !           793:    after this scan is complete.  */
        !           794:       &&
        !           795:       (sqty == -1 ||
        !           796:        TEST_HARD_REG_BIT (reg_class_contents[(int) qty_best_class (reg_qty[ureg])],
        !           797:                          sreg))
        !           798: #else
        !           799:       &&
        !           800:       (sqty == -1 ||
        !           801:        TEST_HARD_REG_BIT (reg_class_contents[(int) reg_preferred_class (ureg)],
        !           802:                          sreg))
        !           803: #endif
        !           804:       )
        !           805:     {
        !           806:       /* We get rid of the quantity that ureg belongs to
        !           807:         and make all regs of that quantity get sqty instead.  */
        !           808:       register int i;
        !           809:       register int v = reg_qty[ureg];
        !           810:       if (sqty == -1) offset = 0;
        !           811:       else
        !           812:        {
        !           813:          reg_is_born (setreg, insn_number, b);
        !           814:          post_mark_life (sqty, qty_mode[sqty], 1, qty_birth[v], insn_number);
        !           815:        }
        !           816: 
        !           817:       qty_birth[sqty] = qty_birth[v];
        !           818:       qty_death[v] = qty_birth[v]; /* So qty V won't occupy any hard reg */
        !           819:       qty_crosses_call[sqty] |= qty_crosses_call[v];
        !           820:       qty_preferred_or_nothing[sqty] = 0;
        !           821:       if (qty_size[v] > qty_size[sqty])
        !           822:        {
        !           823:          qty_size[sqty] = qty_size[v];
        !           824:          qty_mode[sqty] = qty_mode[v];
        !           825:        }
        !           826:       for (i = 0; i < max_regno; i++)
        !           827:        if (reg_qty[i] == v)
        !           828:          {
        !           829:            reg_qty[i] = sqty;
        !           830:            reg_offset[i] -= offset;
        !           831:          }
        !           832:     }
        !           833:   /* Else if we don't already know about SREG, tie it to UREG
        !           834:      if this is the last use of UREG.
        !           835:      If UREG is a hardware register (or tied to one), don't tie
        !           836:      if it is not in the class that SREG wants.
        !           837:      If UREG is not a hardware register, don't tie
        !           838:      if it and SREG want different classes.  */
        !           839:   else if (sqty == -2 && regno_dead_p (ureg, insn)
        !           840:           && (reg_qty[ureg] >= FIRST_PSEUDO_REGISTER
        !           841:               ? reg_meets_class_p (sreg, qty_min_class[reg_qty[ureg]])
        !           842:               : reg_qty[ureg] < 0
        !           843:               ? reg_meets_class_p (sreg, reg_preferred_class (ureg))
        !           844:               : TEST_HARD_REG_BIT (reg_class_contents[(int) reg_preferred_class (sreg)],
        !           845:                                    reg_qty[ureg])))
        !           846:     {
        !           847:       if (reg_qty[ureg] == -2)
        !           848:        reg_is_born (usedreg, insn_number, b);
        !           849:       sqty = reg_qty[sreg] = reg_qty[ureg];
        !           850:       /* If SREG's reg class is smaller, set qty_min_class[SQTY].  */
        !           851:       update_qty_class (sqty, sreg);
        !           852:       reg_offset[sreg] = reg_offset[ureg] + offset;
        !           853:       if (sqty >= 0)
        !           854:        {
        !           855:          qty_crosses_call[sqty] |= reg_crosses_call[sreg];
        !           856:          qty_preferred_or_nothing[sqty] = 0;
        !           857:          if (usize < ssize)
        !           858:            {
        !           859:              register int i;
        !           860:              for (i = 0; i < max_regno; i++)
        !           861:                if (reg_qty[i] == sqty)
        !           862:                  reg_offset[i] -= offset;
        !           863:              qty_size[sqty] = ssize;
        !           864:              qty_mode[sqty] = GET_MODE (setreg);
        !           865:            }
        !           866:        }
        !           867:     }
        !           868:   else
        !           869:     return 0;
        !           870: 
        !           871:   return 1;
        !           872: }
        !           873: 
        !           874: /* Return 1 if the preferred class of REG allows it to be tied
        !           875:    to a quantity or register whose class is CLASS.
        !           876:    True if REG's reg class either contains or is contained in CLASS.  */
        !           877: 
        !           878: static int
        !           879: reg_meets_class_p (reg, class)
        !           880:      int reg;
        !           881:      enum reg_class class;
        !           882: {
        !           883:   register enum reg_class rclass = reg_preferred_class (reg);
        !           884:   return (reg_class_subset_p (rclass, class)
        !           885:          || reg_class_subset_p (class, rclass));
        !           886: }
        !           887: 
        !           888: /* Return nonzero if R2's preferred class is the same as or contains
        !           889:    R1's preferred class.  R1 and R2 are pseudo-register numbers.  */
        !           890: 
        !           891: static int
        !           892: reg_class_subset_p (c1, c2)
        !           893:      register enum reg_class c1;
        !           894:      register enum reg_class c2;
        !           895: {
        !           896:   if (c1 == c2) return 1;
        !           897: 
        !           898:   if (c2 == ALL_REGS)
        !           899:   win:
        !           900:     return 1;
        !           901:   GO_IF_HARD_REG_SUBSET (reg_class_contents[(int)c1],
        !           902:                         reg_class_contents[(int)c2],
        !           903:                         win);
        !           904:   return 0;
        !           905: }
        !           906: 
        !           907: /* Update the class of QTY assuming that REG is being tied to it.  */
        !           908: 
        !           909: static void
        !           910: update_qty_class (qty, reg)
        !           911:      int qty;
        !           912:      int reg;
        !           913: {
        !           914:   enum reg_class rclass = reg_preferred_class (reg);
        !           915:   if (reg_class_subset_p (rclass, qty_min_class[qty]))
        !           916:     qty_min_class[qty] = rclass;
        !           917: }
        !           918: 
        !           919: /* Handle something which alters the value of an rtx REG.
        !           920:    REG is whatever is set or clobbered.  (CLOBBER_FLAG says which.)
        !           921:    If it is not really a register, we do nothing.
        !           922:    THIS_INSN_NUMBER and THIS_BLOCK_NUMBER carry info from `block_alloc'.  */
        !           923: 
        !           924: static void
        !           925: reg_is_set (reg, clobber_flag)
        !           926:      rtx reg;
        !           927:      int clobber_flag;
        !           928: {
        !           929:   register int regno;
        !           930: 
        !           931:   if (reg == 0 || GET_CODE (reg) != REG)
        !           932:     return;
        !           933: 
        !           934:   regno = REGNO (reg);
        !           935: 
        !           936:   if (clobber_flag)
        !           937:     {
        !           938:       if (regno < FIRST_PSEUDO_REGISTER)
        !           939:        {
        !           940:          register int lim = regno + HARD_REGNO_NREGS (regno, GET_MODE (reg));
        !           941:          register int i;
        !           942:          for (i = regno; i < lim; i++)
        !           943:            SET_HARD_REG_BIT (regs_live_at[this_insn_number], i);
        !           944:        }
        !           945:       return;
        !           946:     }
        !           947: 
        !           948:   reg_is_born (reg, this_insn_number, this_block_number);
        !           949: 
        !           950:   /* If a register dies in the same insn that sets it,
        !           951:      say it dies in the following insn instead,
        !           952:      because it will have to be live right after this insn.  */
        !           953:   if (reg_qty[regno] >= 0
        !           954:       && qty_death[reg_qty[regno]] == this_insn_number)
        !           955:     {
        !           956:       /* It is live right after this insn */
        !           957:       post_mark_life (reg_qty[regno], GET_MODE (reg), 1,
        !           958:                      this_insn_number, this_insn_number+1);
        !           959:       /* But dead later.  */
        !           960:       mark_life (reg_qty[regno], GET_MODE (reg), 0);
        !           961:       qty_death[reg_qty[regno]]++;
        !           962:     }
        !           963: }
        !           964: 
        !           965: /* Handle setting a register REG (or otherwise beginning its life).
        !           966:    INSN_NUMBER is the insn at which this is happening, and BLOCKNUM
        !           967:    is the current basic block number.  */
        !           968: 
        !           969: static void
        !           970: reg_is_born (reg, insn_number, blocknum)
        !           971:      rtx reg;
        !           972:      int insn_number;
        !           973:      int blocknum;
        !           974: {
        !           975:   register int regno;
        !           976: 
        !           977:   regno = REGNO (reg);
        !           978:      
        !           979:   if (regno < FIRST_PSEUDO_REGISTER)
        !           980:     {
        !           981:       reg_qty[regno] = regno;
        !           982:       qty_phys_reg[regno] = regno;
        !           983:       qty_mode[regno] = GET_MODE (reg);
        !           984:       mark_life (regno, GET_MODE (reg), 1);
        !           985:     }
        !           986:   else if (reg_qty[regno] >= -1)
        !           987:     ;
        !           988:   else if (reg_basic_block[regno] == blocknum
        !           989:           && reg_n_deaths[regno] == 1)
        !           990:     alloc_qty (regno, GET_MODE (reg), PSEUDO_REGNO_SIZE (regno), insn_number);
        !           991:   else
        !           992:     abort ();
        !           993: /*    reg_qty[regno] = -1;   now done before calling block_alloc.  */
        !           994: }
        !           995: 
        !           996: /* Record the death in insn DEATH_INSN_NUMBER for the register REG.  */
        !           997: 
        !           998: static void
        !           999: wipe_dead_reg (reg, this_insn_number, death_insn_number, blocknum)
        !          1000:      register rtx reg;
        !          1001:      int this_insn_number;
        !          1002:      int death_insn_number;
        !          1003:      int blocknum;
        !          1004: {
        !          1005:   register int regno = REGNO (reg);
        !          1006: 
        !          1007:   /* If a pseudo reg is referred to but was never set,
        !          1008:      we will find here that its qty is -2.
        !          1009:      Since these regs do not conflict with anything,
        !          1010:      mark them as born and dead in the same place.  */
        !          1011:   if (reg_qty[regno] == -2
        !          1012:       && regno >= FIRST_PSEUDO_REGISTER
        !          1013:       && reg_basic_block[regno] == blocknum
        !          1014:       && reg_n_deaths[regno] == 1)
        !          1015:     alloc_qty (regno, GET_MODE (reg), REG_SIZE (reg), this_insn_number);
        !          1016:   /* For a hard reg, make it live so we can record the death.  */
        !          1017:   if (regno < FIRST_PSEUDO_REGISTER
        !          1018:       && reg_qty[regno] < 0)
        !          1019:     reg_is_born (reg, this_insn_number, blocknum);
        !          1020:   if (reg_qty[regno] >= 0)
        !          1021:     {
        !          1022:       qty_death[reg_qty[regno]] = death_insn_number;
        !          1023:       if (reg_qty[regno] < FIRST_PSEUDO_REGISTER)
        !          1024:        {
        !          1025:          mark_life (reg_qty[regno], GET_MODE (reg), 0);
        !          1026:          if (this_insn_number != death_insn_number)
        !          1027:            post_mark_life (reg_qty[regno], GET_MODE (reg), 1,
        !          1028:                            this_insn_number, death_insn_number);
        !          1029:        }
        !          1030:     }
        !          1031: }
        !          1032: 
        !          1033: /* Find a block of SIZE words of hard regs in reg_class CLASS
        !          1034:    that can hold something of machine-mode MODE
        !          1035:      (but actually we test only the first of the block for holding MODE)
        !          1036:    and still free between insn BORN_INSN and insn DEAD_INSN,
        !          1037:    and return the number of the first of them.
        !          1038:    Return -1 if such a block cannot be found.
        !          1039:    If CALL_PRESERVED is nonzero, insist on registers preserved
        !          1040:    over subroutine calls, and return -1 if cannot find such.  */
        !          1041: 
        !          1042: static int
        !          1043: find_free_reg (call_preserved, class, mode, qty, born_insn, dead_insn)
        !          1044:      int call_preserved;
        !          1045:      enum reg_class class;
        !          1046:      enum machine_mode mode;
        !          1047:      int qty;
        !          1048:      int born_insn, dead_insn;
        !          1049: {
        !          1050:   register int i, ins;
        !          1051: #ifdef HARD_REG_SET
        !          1052:   register             /* Declare it register if it's a scalar.  */
        !          1053: #endif
        !          1054:     HARD_REG_SET used;
        !          1055: 
        !          1056:   COPY_HARD_REG_SET (used,
        !          1057:                     call_preserved ? call_used_reg_set : fixed_reg_set);
        !          1058: 
        !          1059:   for (ins = born_insn; ins < dead_insn; ins++)
        !          1060:     IOR_HARD_REG_SET (used, regs_live_at[ins]);
        !          1061: 
        !          1062:   IOR_COMPL_HARD_REG_SET (used, reg_class_contents[(int) class]);
        !          1063: 
        !          1064:   /* If quantity QTY has a suggested physical register,
        !          1065:      try that one first.  */
        !          1066: 
        !          1067:   if (qty_phys_sugg[qty] >= 0)
        !          1068:     {
        !          1069:       i = qty_phys_sugg[qty];
        !          1070:       if (! TEST_HARD_REG_BIT (used, i)
        !          1071:          && HARD_REGNO_MODE_OK (i, mode))
        !          1072:        {
        !          1073:          register int j;
        !          1074:          register int size1 = HARD_REGNO_NREGS (i, mode);
        !          1075:          for (j = 1; j < size1 && ! TEST_HARD_REG_BIT (used, i + j); j++);
        !          1076:          if (j == size1)
        !          1077:            {
        !          1078:              post_mark_life (i, mode, 1, born_insn, dead_insn);
        !          1079:              return i;
        !          1080:            }
        !          1081:        }
        !          1082:     }
        !          1083: 
        !          1084:   /* If that doesn't find one, test each hard reg.  */
        !          1085: 
        !          1086:   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
        !          1087:     if (! TEST_HARD_REG_BIT (used, i)
        !          1088:        && HARD_REGNO_MODE_OK (i, mode))
        !          1089:       {
        !          1090:        register int j;
        !          1091:        register int size1 = HARD_REGNO_NREGS (i, mode);
        !          1092:        for (j = 1; j < size1 && ! TEST_HARD_REG_BIT (used, i + j); j++);
        !          1093:        if (j == size1)
        !          1094:          {
        !          1095:            post_mark_life (i, mode, 1, born_insn, dead_insn);
        !          1096:            return i;
        !          1097:          }
        !          1098:        i += j;                 /* Skip starting points we know will lose */
        !          1099:       }
        !          1100:   return -1;
        !          1101: }
        !          1102: 
        !          1103: static void
        !          1104: mark_life (regno, mode, life)
        !          1105:      register int regno;
        !          1106:      enum machine_mode mode;
        !          1107:      int life;
        !          1108: {
        !          1109:   register int j = HARD_REGNO_NREGS (regno, mode);
        !          1110:   if (life)
        !          1111:     while (--j >= 0)
        !          1112:       SET_HARD_REG_BIT (regs_live, regno + j);
        !          1113:   else
        !          1114:     while (--j >= 0)
        !          1115:       CLEAR_HARD_REG_BIT (regs_live, regno + j);
        !          1116: }
        !          1117: 
        !          1118: static void
        !          1119: post_mark_life (regno, mode, life, birth, death)
        !          1120:      register int regno, life, birth;
        !          1121:      enum machine_mode mode;
        !          1122:      int death;
        !          1123: {
        !          1124:   register int j = HARD_REGNO_NREGS (regno, mode);
        !          1125: #ifdef HARD_REG_SET
        !          1126:   register             /* Declare it register if it's a scalar.  */
        !          1127: #endif
        !          1128:     HARD_REG_SET this_reg;
        !          1129: 
        !          1130:   CLEAR_HARD_REG_SET (this_reg);
        !          1131:   while (--j >= 0)
        !          1132:     SET_HARD_REG_BIT (this_reg, regno + j);
        !          1133: 
        !          1134:   /* If a reg is born and dies in one insn,
        !          1135:      consider it live after that insn.  */
        !          1136: 
        !          1137:   if (birth == death)
        !          1138:     death++;
        !          1139: 
        !          1140:   if (life)
        !          1141:     while (birth < death)
        !          1142:       {
        !          1143:        IOR_HARD_REG_SET (regs_live_at[birth], this_reg);
        !          1144:        birth++;
        !          1145:       }
        !          1146:   else
        !          1147:     while (birth < death)
        !          1148:       {
        !          1149:        AND_COMPL_HARD_REG_SET (regs_live_at[birth], this_reg);
        !          1150:        birth++;
        !          1151:       }
        !          1152: }
        !          1153: 
        !          1154: void
        !          1155: dump_local_alloc (file)
        !          1156:      FILE *file;
        !          1157: {
        !          1158:   register int i;
        !          1159:   for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
        !          1160:     if (reg_renumber[i] != -1)
        !          1161:       fprintf (file, ";; Register %d in %d.\n", i, reg_renumber[i]);
        !          1162: }

unix.superglobalmegacorp.com

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