Annotation of GNUtools/cc/cse.c, revision 1.1

1.1     ! root        1: /* Common subexpression elimination for GNU compiler.
        !             2:    Copyright (C) 1987, 1988, 1989, 1992, 1993 Free Software Foundation, Inc.
        !             3: 
        !             4: This file is part of GNU CC.
        !             5: 
        !             6: GNU CC is free software; you can redistribute it and/or modify
        !             7: it under the terms of the GNU General Public License as published by
        !             8: the Free Software Foundation; either version 2, or (at your option)
        !             9: any later version.
        !            10: 
        !            11: GNU CC is distributed in the hope that it will be useful,
        !            12: but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        !            14: GNU General Public License for more details.
        !            15: 
        !            16: You should have received a copy of the GNU General Public License
        !            17: along with GNU CC; see the file COPYING.  If not, write to
        !            18: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
        !            19: 
        !            20: 
        !            21: #include "config.h"
        !            22: /* Must precede rtl.h for FFS.  */
        !            23: #include <stdio.h>
        !            24: 
        !            25: #include "rtl.h"
        !            26: #include "regs.h"
        !            27: #include "hard-reg-set.h"
        !            28: #include "flags.h"
        !            29: #include "real.h"
        !            30: #include "insn-config.h"
        !            31: #include "recog.h"
        !            32: 
        !            33: #include <setjmp.h>
        !            34: 
        !            35: /* The basic idea of common subexpression elimination is to go
        !            36:    through the code, keeping a record of expressions that would
        !            37:    have the same value at the current scan point, and replacing
        !            38:    expressions encountered with the cheapest equivalent expression.
        !            39: 
        !            40:    It is too complicated to keep track of the different possibilities
        !            41:    when control paths merge; so, at each label, we forget all that is
        !            42:    known and start fresh.  This can be described as processing each
        !            43:    basic block separately.  Note, however, that these are not quite
        !            44:    the same as the basic blocks found by a later pass and used for
        !            45:    data flow analysis and register packing.  We do not need to start fresh
        !            46:    after a conditional jump instruction if there is no label there.
        !            47: 
        !            48:    We use two data structures to record the equivalent expressions:
        !            49:    a hash table for most expressions, and several vectors together
        !            50:    with "quantity numbers" to record equivalent (pseudo) registers.
        !            51: 
        !            52:    The use of the special data structure for registers is desirable
        !            53:    because it is faster.  It is possible because registers references
        !            54:    contain a fairly small number, the register number, taken from
        !            55:    a contiguously allocated series, and two register references are
        !            56:    identical if they have the same number.  General expressions
        !            57:    do not have any such thing, so the only way to retrieve the
        !            58:    information recorded on an expression other than a register
        !            59:    is to keep it in a hash table.
        !            60: 
        !            61: Registers and "quantity numbers":
        !            62:    
        !            63:    At the start of each basic block, all of the (hardware and pseudo)
        !            64:    registers used in the function are given distinct quantity
        !            65:    numbers to indicate their contents.  During scan, when the code
        !            66:    copies one register into another, we copy the quantity number.
        !            67:    When a register is loaded in any other way, we allocate a new
        !            68:    quantity number to describe the value generated by this operation.
        !            69:    `reg_qty' records what quantity a register is currently thought
        !            70:    of as containing.
        !            71: 
        !            72:    All real quantity numbers are greater than or equal to `max_reg'.
        !            73:    If register N has not been assigned a quantity, reg_qty[N] will equal N.
        !            74: 
        !            75:    Quantity numbers below `max_reg' do not exist and none of the `qty_...'
        !            76:    variables should be referenced with an index below `max_reg'.
        !            77: 
        !            78:    We also maintain a bidirectional chain of registers for each
        !            79:    quantity number.  `qty_first_reg', `qty_last_reg',
        !            80:    `reg_next_eqv' and `reg_prev_eqv' hold these chains.
        !            81: 
        !            82:    The first register in a chain is the one whose lifespan is least local.
        !            83:    Among equals, it is the one that was seen first.
        !            84:    We replace any equivalent register with that one.
        !            85: 
        !            86:    If two registers have the same quantity number, it must be true that
        !            87:    REG expressions with `qty_mode' must be in the hash table for both
        !            88:    registers and must be in the same class.
        !            89: 
        !            90:    The converse is not true.  Since hard registers may be referenced in
        !            91:    any mode, two REG expressions might be equivalent in the hash table
        !            92:    but not have the same quantity number if the quantity number of one
        !            93:    of the registers is not the same mode as those expressions.
        !            94:    
        !            95: Constants and quantity numbers
        !            96: 
        !            97:    When a quantity has a known constant value, that value is stored
        !            98:    in the appropriate element of qty_const.  This is in addition to
        !            99:    putting the constant in the hash table as is usual for non-regs.
        !           100: 
        !           101:    Whether a reg or a constant is preferred is determined by the configuration
        !           102:    macro CONST_COSTS and will often depend on the constant value.  In any
        !           103:    event, expressions containing constants can be simplified, by fold_rtx.
        !           104: 
        !           105:    When a quantity has a known nearly constant value (such as an address
        !           106:    of a stack slot), that value is stored in the appropriate element
        !           107:    of qty_const.
        !           108: 
        !           109:    Integer constants don't have a machine mode.  However, cse
        !           110:    determines the intended machine mode from the destination
        !           111:    of the instruction that moves the constant.  The machine mode
        !           112:    is recorded in the hash table along with the actual RTL
        !           113:    constant expression so that different modes are kept separate.
        !           114: 
        !           115: Other expressions:
        !           116: 
        !           117:    To record known equivalences among expressions in general
        !           118:    we use a hash table called `table'.  It has a fixed number of buckets
        !           119:    that contain chains of `struct table_elt' elements for expressions.
        !           120:    These chains connect the elements whose expressions have the same
        !           121:    hash codes.
        !           122: 
        !           123:    Other chains through the same elements connect the elements which
        !           124:    currently have equivalent values.
        !           125: 
        !           126:    Register references in an expression are canonicalized before hashing
        !           127:    the expression.  This is done using `reg_qty' and `qty_first_reg'.
        !           128:    The hash code of a register reference is computed using the quantity
        !           129:    number, not the register number.
        !           130: 
        !           131:    When the value of an expression changes, it is necessary to remove from the
        !           132:    hash table not just that expression but all expressions whose values
        !           133:    could be different as a result.
        !           134: 
        !           135:      1. If the value changing is in memory, except in special cases
        !           136:      ANYTHING referring to memory could be changed.  That is because
        !           137:      nobody knows where a pointer does not point.
        !           138:      The function `invalidate_memory' removes what is necessary.
        !           139: 
        !           140:      The special cases are when the address is constant or is
        !           141:      a constant plus a fixed register such as the frame pointer
        !           142:      or a static chain pointer.  When such addresses are stored in,
        !           143:      we can tell exactly which other such addresses must be invalidated
        !           144:      due to overlap.  `invalidate' does this.
        !           145:      All expressions that refer to non-constant
        !           146:      memory addresses are also invalidated.  `invalidate_memory' does this.
        !           147: 
        !           148:      2. If the value changing is a register, all expressions
        !           149:      containing references to that register, and only those,
        !           150:      must be removed.
        !           151: 
        !           152:    Because searching the entire hash table for expressions that contain
        !           153:    a register is very slow, we try to figure out when it isn't necessary.
        !           154:    Precisely, this is necessary only when expressions have been
        !           155:    entered in the hash table using this register, and then the value has
        !           156:    changed, and then another expression wants to be added to refer to
        !           157:    the register's new value.  This sequence of circumstances is rare
        !           158:    within any one basic block.
        !           159: 
        !           160:    The vectors `reg_tick' and `reg_in_table' are used to detect this case.
        !           161:    reg_tick[i] is incremented whenever a value is stored in register i.
        !           162:    reg_in_table[i] holds -1 if no references to register i have been
        !           163:    entered in the table; otherwise, it contains the value reg_tick[i] had
        !           164:    when the references were entered.  If we want to enter a reference
        !           165:    and reg_in_table[i] != reg_tick[i], we must scan and remove old references.
        !           166:    Until we want to enter a new entry, the mere fact that the two vectors
        !           167:    don't match makes the entries be ignored if anyone tries to match them.
        !           168: 
        !           169:    Registers themselves are entered in the hash table as well as in
        !           170:    the equivalent-register chains.  However, the vectors `reg_tick'
        !           171:    and `reg_in_table' do not apply to expressions which are simple
        !           172:    register references.  These expressions are removed from the table
        !           173:    immediately when they become invalid, and this can be done even if
        !           174:    we do not immediately search for all the expressions that refer to
        !           175:    the register.
        !           176: 
        !           177:    A CLOBBER rtx in an instruction invalidates its operand for further
        !           178:    reuse.  A CLOBBER or SET rtx whose operand is a MEM:BLK
        !           179:    invalidates everything that resides in memory.
        !           180: 
        !           181: Related expressions:
        !           182: 
        !           183:    Constant expressions that differ only by an additive integer
        !           184:    are called related.  When a constant expression is put in
        !           185:    the table, the related expression with no constant term
        !           186:    is also entered.  These are made to point at each other
        !           187:    so that it is possible to find out if there exists any
        !           188:    register equivalent to an expression related to a given expression.  */
        !           189:    
        !           190: /* One plus largest register number used in this function.  */
        !           191: 
        !           192: static int max_reg;
        !           193: 
        !           194: /* Length of vectors indexed by quantity number.
        !           195:    We know in advance we will not need a quantity number this big.  */
        !           196: 
        !           197: static int max_qty;
        !           198: 
        !           199: /* Next quantity number to be allocated.
        !           200:    This is 1 + the largest number needed so far.  */
        !           201: 
        !           202: static int next_qty;
        !           203: 
        !           204: /* Indexed by quantity number, gives the first (or last) (pseudo) register 
        !           205:    in the chain of registers that currently contain this quantity.  */
        !           206: 
        !           207: static int *qty_first_reg;
        !           208: static int *qty_last_reg;
        !           209: 
        !           210: /* Index by quantity number, gives the mode of the quantity.  */
        !           211: 
        !           212: static enum machine_mode *qty_mode;
        !           213: 
        !           214: /* Indexed by quantity number, gives the rtx of the constant value of the
        !           215:    quantity, or zero if it does not have a known value.
        !           216:    A sum of the frame pointer (or arg pointer) plus a constant
        !           217:    can also be entered here.  */
        !           218: 
        !           219: static rtx *qty_const;
        !           220: 
        !           221: /* Indexed by qty number, gives the insn that stored the constant value
        !           222:    recorded in `qty_const'.  */
        !           223: 
        !           224: static rtx *qty_const_insn;
        !           225: 
        !           226: /* The next three variables are used to track when a comparison between a
        !           227:    quantity and some constant or register has been passed.  In that case, we
        !           228:    know the results of the comparison in case we see it again.  These variables
        !           229:    record a comparison that is known to be true.  */
        !           230: 
        !           231: /* Indexed by qty number, gives the rtx code of a comparison with a known
        !           232:    result involving this quantity.  If none, it is UNKNOWN.  */
        !           233: static enum rtx_code *qty_comparison_code;
        !           234: 
        !           235: /* Indexed by qty number, gives the constant being compared against in a
        !           236:    comparison of known result.  If no such comparison, it is undefined.
        !           237:    If the comparison is not with a constant, it is zero.  */
        !           238: 
        !           239: static rtx *qty_comparison_const;
        !           240: 
        !           241: /* Indexed by qty number, gives the quantity being compared against in a
        !           242:    comparison of known result.  If no such comparison, if it undefined.
        !           243:    If the comparison is not with a register, it is -1.  */
        !           244: 
        !           245: static int *qty_comparison_qty;
        !           246: 
        !           247: #ifdef HAVE_cc0
        !           248: /* For machines that have a CC0, we do not record its value in the hash
        !           249:    table since its use is guaranteed to be the insn immediately following
        !           250:    its definition and any other insn is presumed to invalidate it.
        !           251: 
        !           252:    Instead, we store below the value last assigned to CC0.  If it should
        !           253:    happen to be a constant, it is stored in preference to the actual
        !           254:    assigned value.  In case it is a constant, we store the mode in which
        !           255:    the constant should be interpreted.  */
        !           256: 
        !           257: static rtx prev_insn_cc0;
        !           258: static enum machine_mode prev_insn_cc0_mode;
        !           259: #endif
        !           260: 
        !           261: /* Previous actual insn.  0 if at first insn of basic block.  */
        !           262: 
        !           263: static rtx prev_insn;
        !           264: 
        !           265: /* Insn being scanned.  */
        !           266: 
        !           267: static rtx this_insn;
        !           268: 
        !           269: /* Index by (pseudo) register number, gives the quantity number
        !           270:    of the register's current contents.  */
        !           271: 
        !           272: static int *reg_qty;
        !           273: 
        !           274: /* Index by (pseudo) register number, gives the number of the next (or
        !           275:    previous) (pseudo) register in the chain of registers sharing the same
        !           276:    value.
        !           277: 
        !           278:    Or -1 if this register is at the end of the chain.
        !           279: 
        !           280:    If reg_qty[N] == N, reg_next_eqv[N] is undefined.  */
        !           281: 
        !           282: static int *reg_next_eqv;
        !           283: static int *reg_prev_eqv;
        !           284: 
        !           285: /* Index by (pseudo) register number, gives the number of times
        !           286:    that register has been altered in the current basic block.  */
        !           287: 
        !           288: static int *reg_tick;
        !           289: 
        !           290: /* Index by (pseudo) register number, gives the reg_tick value at which
        !           291:    rtx's containing this register are valid in the hash table.
        !           292:    If this does not equal the current reg_tick value, such expressions
        !           293:    existing in the hash table are invalid.
        !           294:    If this is -1, no expressions containing this register have been
        !           295:    entered in the table.  */
        !           296: 
        !           297: static int *reg_in_table;
        !           298: 
        !           299: /* A HARD_REG_SET containing all the hard registers for which there is 
        !           300:    currently a REG expression in the hash table.  Note the difference
        !           301:    from the above variables, which indicate if the REG is mentioned in some
        !           302:    expression in the table.  */
        !           303: 
        !           304: static HARD_REG_SET hard_regs_in_table;
        !           305: 
        !           306: /* A HARD_REG_SET containing all the hard registers that are invalidated
        !           307:    by a CALL_INSN.  */
        !           308: 
        !           309: static HARD_REG_SET regs_invalidated_by_call;
        !           310: 
        !           311: /* Two vectors of ints:
        !           312:    one containing max_reg -1's; the other max_reg + 500 (an approximation
        !           313:    for max_qty) elements where element i contains i.
        !           314:    These are used to initialize various other vectors fast.  */
        !           315: 
        !           316: static int *all_minus_one;
        !           317: static int *consec_ints;
        !           318: 
        !           319: /* CUID of insn that starts the basic block currently being cse-processed.  */
        !           320: 
        !           321: static int cse_basic_block_start;
        !           322: 
        !           323: /* CUID of insn that ends the basic block currently being cse-processed.  */
        !           324: 
        !           325: static int cse_basic_block_end;
        !           326: 
        !           327: /* Vector mapping INSN_UIDs to cuids.
        !           328:    The cuids are like uids but increase monotonically always.
        !           329:    We use them to see whether a reg is used outside a given basic block.  */
        !           330: 
        !           331: static int *uid_cuid;
        !           332: 
        !           333: /* Highest UID in UID_CUID.  */
        !           334: static int max_uid;
        !           335: 
        !           336: /* Get the cuid of an insn.  */
        !           337: 
        !           338: #define INSN_CUID(INSN) (uid_cuid[INSN_UID (INSN)])
        !           339: 
        !           340: /* Nonzero if cse has altered conditional jump insns
        !           341:    in such a way that jump optimization should be redone.  */
        !           342: 
        !           343: static int cse_jumps_altered;
        !           344: 
        !           345: /* canon_hash stores 1 in do_not_record
        !           346:    if it notices a reference to CC0, PC, or some other volatile
        !           347:    subexpression.  */
        !           348: 
        !           349: static int do_not_record;
        !           350: 
        !           351: /* canon_hash stores 1 in hash_arg_in_memory
        !           352:    if it notices a reference to memory within the expression being hashed.  */
        !           353: 
        !           354: static int hash_arg_in_memory;
        !           355: 
        !           356: /* canon_hash stores 1 in hash_arg_in_struct
        !           357:    if it notices a reference to memory that's part of a structure.  */
        !           358: 
        !           359: static int hash_arg_in_struct;
        !           360: 
        !           361: /* The hash table contains buckets which are chains of `struct table_elt's,
        !           362:    each recording one expression's information.
        !           363:    That expression is in the `exp' field.
        !           364: 
        !           365:    Those elements with the same hash code are chained in both directions
        !           366:    through the `next_same_hash' and `prev_same_hash' fields.
        !           367: 
        !           368:    Each set of expressions with equivalent values
        !           369:    are on a two-way chain through the `next_same_value'
        !           370:    and `prev_same_value' fields, and all point with
        !           371:    the `first_same_value' field at the first element in
        !           372:    that chain.  The chain is in order of increasing cost.
        !           373:    Each element's cost value is in its `cost' field.
        !           374: 
        !           375:    The `in_memory' field is nonzero for elements that
        !           376:    involve any reference to memory.  These elements are removed
        !           377:    whenever a write is done to an unidentified location in memory.
        !           378:    To be safe, we assume that a memory address is unidentified unless
        !           379:    the address is either a symbol constant or a constant plus
        !           380:    the frame pointer or argument pointer.
        !           381: 
        !           382:    The `in_struct' field is nonzero for elements that
        !           383:    involve any reference to memory inside a structure or array.
        !           384: 
        !           385:    The `related_value' field is used to connect related expressions
        !           386:    (that differ by adding an integer).
        !           387:    The related expressions are chained in a circular fashion.
        !           388:    `related_value' is zero for expressions for which this
        !           389:    chain is not useful.
        !           390: 
        !           391:    The `cost' field stores the cost of this element's expression.
        !           392: 
        !           393:    The `is_const' flag is set if the element is a constant (including
        !           394:    a fixed address).
        !           395: 
        !           396:    The `flag' field is used as a temporary during some search routines.
        !           397: 
        !           398:    The `mode' field is usually the same as GET_MODE (`exp'), but
        !           399:    if `exp' is a CONST_INT and has no machine mode then the `mode'
        !           400:    field is the mode it was being used as.  Each constant is
        !           401:    recorded separately for each mode it is used with.  */
        !           402: 
        !           403: 
        !           404: struct table_elt
        !           405: {
        !           406:   rtx exp;
        !           407:   struct table_elt *next_same_hash;
        !           408:   struct table_elt *prev_same_hash;
        !           409:   struct table_elt *next_same_value;
        !           410:   struct table_elt *prev_same_value;
        !           411:   struct table_elt *first_same_value;
        !           412:   struct table_elt *related_value;
        !           413:   int cost;
        !           414:   enum machine_mode mode;
        !           415:   char in_memory;
        !           416:   char in_struct;
        !           417:   char is_const;
        !           418:   char flag;
        !           419: };
        !           420: 
        !           421: #define HASHBITS 16
        !           422: 
        !           423: /* We don't want a lot of buckets, because we rarely have very many
        !           424:    things stored in the hash table, and a lot of buckets slows
        !           425:    down a lot of loops that happen frequently.  */
        !           426: #define NBUCKETS 31
        !           427: 
        !           428: /* Compute hash code of X in mode M.  Special-case case where X is a pseudo
        !           429:    register (hard registers may require `do_not_record' to be set).  */
        !           430: 
        !           431: #define HASH(X, M)     \
        !           432:  (GET_CODE (X) == REG && REGNO (X) >= FIRST_PSEUDO_REGISTER    \
        !           433:   ? ((((int) REG << 7) + reg_qty[REGNO (X)]) % NBUCKETS)       \
        !           434:   : canon_hash (X, M) % NBUCKETS)
        !           435: 
        !           436: /* Determine whether register number N is considered a fixed register for CSE.
        !           437:    It is desirable to replace other regs with fixed regs, to reduce need for
        !           438:    non-fixed hard regs.
        !           439:    A reg wins if it is either the frame pointer or designated as fixed,
        !           440:    but not if it is an overlapping register.  */
        !           441: #ifdef OVERLAPPING_REGNO_P
        !           442: #define FIXED_REGNO_P(N)  \
        !           443:   (((N) == FRAME_POINTER_REGNUM || (N) == HARD_FRAME_POINTER_REGNUM \
        !           444:     || fixed_regs[N])    \
        !           445:    && ! OVERLAPPING_REGNO_P ((N)))
        !           446: #else
        !           447: #define FIXED_REGNO_P(N)  \
        !           448:   ((N) == FRAME_POINTER_REGNUM || (N) == HARD_FRAME_POINTER_REGNUM \
        !           449:    || fixed_regs[N])
        !           450: #endif
        !           451: 
        !           452: /* Compute cost of X, as stored in the `cost' field of a table_elt.  Fixed
        !           453:    hard registers and pointers into the frame are the cheapest with a cost
        !           454:    of 0.  Next come pseudos with a cost of one and other hard registers with
        !           455:    a cost of 2.  Aside from these special cases, call `rtx_cost'.  */
        !           456: 
        !           457: #define CHEAP_REG(N) \
        !           458:   ((N) == FRAME_POINTER_REGNUM || (N) == HARD_FRAME_POINTER_REGNUM     \
        !           459:    || (N) == STACK_POINTER_REGNUM || (N) == ARG_POINTER_REGNUM         \
        !           460:    || ((N) >= FIRST_VIRTUAL_REGISTER && (N) <= LAST_VIRTUAL_REGISTER)  \
        !           461:    || ((N) < FIRST_PSEUDO_REGISTER                                     \
        !           462:        && FIXED_REGNO_P (N) && REGNO_REG_CLASS (N) != NO_REGS))
        !           463: 
        !           464: #define COST(X)                                                \
        !           465:   (GET_CODE (X) == REG                                 \
        !           466:    ? (CHEAP_REG (REGNO (X)) ? 0                                \
        !           467:       : REGNO (X) >= FIRST_PSEUDO_REGISTER ? 1         \
        !           468:       : 2)                                             \
        !           469:    : rtx_cost (X, SET) * 2)
        !           470: 
        !           471: /* Determine if the quantity number for register X represents a valid index
        !           472:    into the `qty_...' variables.  */
        !           473: 
        !           474: #define REGNO_QTY_VALID_P(N) (reg_qty[N] != (N))
        !           475: 
        !           476: static struct table_elt *table[NBUCKETS];
        !           477: 
        !           478: /* Chain of `struct table_elt's made so far for this function
        !           479:    but currently removed from the table.  */
        !           480: 
        !           481: static struct table_elt *free_element_chain;
        !           482: 
        !           483: /* Number of `struct table_elt' structures made so far for this function.  */
        !           484: 
        !           485: static int n_elements_made;
        !           486: 
        !           487: /* Maximum value `n_elements_made' has had so far in this compilation
        !           488:    for functions previously processed.  */
        !           489: 
        !           490: static int max_elements_made;
        !           491: 
        !           492: /* Surviving equivalence class when two equivalence classes are merged 
        !           493:    by recording the effects of a jump in the last insn.  Zero if the
        !           494:    last insn was not a conditional jump.  */
        !           495: 
        !           496: static struct table_elt *last_jump_equiv_class;
        !           497: 
        !           498: /* Set to the cost of a constant pool reference if one was found for a
        !           499:    symbolic constant.  If this was found, it means we should try to
        !           500:    convert constants into constant pool entries if they don't fit in
        !           501:    the insn.  */
        !           502: 
        !           503: static int constant_pool_entries_cost;
        !           504: 
        !           505: /* Bits describing what kind of values in memory must be invalidated
        !           506:    for a particular instruction.  If all three bits are zero,
        !           507:    no memory refs need to be invalidated.  Each bit is more powerful
        !           508:    than the preceding ones, and if a bit is set then the preceding
        !           509:    bits are also set.
        !           510: 
        !           511:    Here is how the bits are set:
        !           512:    Pushing onto the stack invalidates only the stack pointer,
        !           513:    writing at a fixed address invalidates only variable addresses,
        !           514:    writing in a structure element at variable address
        !           515:      invalidates all but scalar variables,
        !           516:    and writing in anything else at variable address invalidates everything.  */
        !           517: 
        !           518: struct write_data
        !           519: {
        !           520:   int sp : 1;                  /* Invalidate stack pointer. */
        !           521:   int var : 1;                 /* Invalidate variable addresses.  */
        !           522:   int nonscalar : 1;           /* Invalidate all but scalar variables.  */
        !           523:   int all : 1;                 /* Invalidate all memory refs.  */
        !           524: };
        !           525: 
        !           526: /* Define maximum length of a branch path.  */
        !           527: 
        !           528: #define PATHLENGTH     10
        !           529: 
        !           530: /* This data describes a block that will be processed by cse_basic_block.  */
        !           531: 
        !           532: struct cse_basic_block_data {
        !           533:   /* Lowest CUID value of insns in block.  */
        !           534:   int low_cuid;
        !           535:   /* Highest CUID value of insns in block.  */
        !           536:   int high_cuid;
        !           537:   /* Total number of SETs in block.  */
        !           538:   int nsets;
        !           539:   /* Last insn in the block.  */
        !           540:   rtx last;
        !           541:   /* Size of current branch path, if any.  */
        !           542:   int path_size;
        !           543:   /* Current branch path, indicating which branches will be taken.  */
        !           544:   struct branch_path {
        !           545:     /* The branch insn. */
        !           546:     rtx branch;
        !           547:     /* Whether it should be taken or not.  AROUND is the same as taken
        !           548:        except that it is used when the destination label is not preceded
        !           549:        by a BARRIER.  */
        !           550:     enum taken {TAKEN, NOT_TAKEN, AROUND} status;
        !           551:   } path[PATHLENGTH];
        !           552: };
        !           553: 
        !           554: /* Nonzero if X has the form (PLUS frame-pointer integer).  We check for
        !           555:    virtual regs here because the simplify_*_operation routines are called
        !           556:    by integrate.c, which is called before virtual register instantiation.  */
        !           557: 
        !           558: #define FIXED_BASE_PLUS_P(X)                                   \
        !           559:   ((X) == frame_pointer_rtx || (X) == hard_frame_pointer_rtx   \
        !           560:    || (X) == arg_pointer_rtx                                   \
        !           561:    || (X) == virtual_stack_vars_rtx                            \
        !           562:    || (X) == virtual_incoming_args_rtx                         \
        !           563:    || (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 1)) == CONST_INT \
        !           564:        && (XEXP (X, 0) == frame_pointer_rtx                    \
        !           565:           || XEXP (X, 0) == hard_frame_pointer_rtx             \
        !           566:           || XEXP (X, 0) == arg_pointer_rtx                    \
        !           567:           || XEXP (X, 0) == virtual_stack_vars_rtx             \
        !           568:           || XEXP (X, 0) == virtual_incoming_args_rtx)))
        !           569: 
        !           570: /* Similar, but also allows reference to the stack pointer.
        !           571: 
        !           572:    This used to include FIXED_BASE_PLUS_P, however, we can't assume that
        !           573:    arg_pointer_rtx by itself is nonzero, because on at least one machine,
        !           574:    the i960, the arg pointer is zero when it is unused.  */
        !           575: 
        !           576: #define NONZERO_BASE_PLUS_P(X)                                 \
        !           577:   ((X) == frame_pointer_rtx || (X) == hard_frame_pointer_rtx   \
        !           578:    || (X) == virtual_stack_vars_rtx                            \
        !           579:    || (X) == virtual_incoming_args_rtx                         \
        !           580:    || (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 1)) == CONST_INT \
        !           581:        && (XEXP (X, 0) == frame_pointer_rtx                    \
        !           582:           || XEXP (X, 0) == hard_frame_pointer_rtx             \
        !           583:           || XEXP (X, 0) == arg_pointer_rtx                    \
        !           584:           || XEXP (X, 0) == virtual_stack_vars_rtx             \
        !           585:           || XEXP (X, 0) == virtual_incoming_args_rtx))        \
        !           586:    || (X) == stack_pointer_rtx                                 \
        !           587:    || (X) == virtual_stack_dynamic_rtx                         \
        !           588:    || (X) == virtual_outgoing_args_rtx                         \
        !           589:    || (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 1)) == CONST_INT \
        !           590:        && (XEXP (X, 0) == stack_pointer_rtx                    \
        !           591:           || XEXP (X, 0) == virtual_stack_dynamic_rtx          \
        !           592:           || XEXP (X, 0) == virtual_outgoing_args_rtx)))
        !           593: 
        !           594: static void new_basic_block    PROTO((void));
        !           595: static void make_new_qty       PROTO((int));
        !           596: static void make_regs_eqv      PROTO((int, int));
        !           597: static void delete_reg_equiv   PROTO((int));
        !           598: static int mention_regs                PROTO((rtx));
        !           599: static int insert_regs         PROTO((rtx, struct table_elt *, int));
        !           600: static void free_element       PROTO((struct table_elt *));
        !           601: static void remove_from_table  PROTO((struct table_elt *, int));
        !           602: static struct table_elt *get_element PROTO((void));
        !           603: static struct table_elt *lookup        PROTO((rtx, int, enum machine_mode)),
        !           604:        *lookup_for_remove PROTO((rtx, int, enum machine_mode));
        !           605: static rtx lookup_as_function  PROTO((rtx, enum rtx_code));
        !           606: static struct table_elt *insert PROTO((rtx, struct table_elt *, int,
        !           607:                                       enum machine_mode));
        !           608: static void merge_equiv_classes PROTO((struct table_elt *,
        !           609:                                       struct table_elt *));
        !           610: static void invalidate         PROTO((rtx));
        !           611: static void remove_invalid_refs        PROTO((int));
        !           612: static void rehash_using_reg   PROTO((rtx));
        !           613: static void invalidate_memory  PROTO((struct write_data *));
        !           614: static void invalidate_for_call        PROTO((void));
        !           615: static rtx use_related_value   PROTO((rtx, struct table_elt *));
        !           616: static int canon_hash          PROTO((rtx, enum machine_mode));
        !           617: static int safe_hash           PROTO((rtx, enum machine_mode));
        !           618: static int exp_equiv_p         PROTO((rtx, rtx, int, int));
        !           619: static void set_nonvarying_address_components PROTO((rtx, int, rtx *,
        !           620:                                                     HOST_WIDE_INT *,
        !           621:                                                     HOST_WIDE_INT *));
        !           622: static int refers_to_p         PROTO((rtx, rtx));
        !           623: static int refers_to_mem_p     PROTO((rtx, rtx, HOST_WIDE_INT,
        !           624:                                       HOST_WIDE_INT));
        !           625: static int cse_rtx_addr_varies_p PROTO((rtx));
        !           626: static rtx canon_reg           PROTO((rtx, rtx));
        !           627: static void find_best_addr     PROTO((rtx, rtx *));
        !           628: static enum rtx_code find_comparison_args PROTO((enum rtx_code, rtx *, rtx *,
        !           629:                                                 enum machine_mode *,
        !           630:                                                 enum machine_mode *));
        !           631: static rtx cse_gen_binary      PROTO((enum rtx_code, enum machine_mode,
        !           632:                                       rtx, rtx));
        !           633: static rtx simplify_plus_minus PROTO((enum rtx_code, enum machine_mode,
        !           634:                                       rtx, rtx));
        !           635: static rtx fold_rtx            PROTO((rtx, rtx));
        !           636: static rtx equiv_constant      PROTO((rtx));
        !           637: static void record_jump_equiv  PROTO((rtx, int));
        !           638: static void record_jump_cond   PROTO((enum rtx_code, enum machine_mode,
        !           639:                                       rtx, rtx, int));
        !           640: static void cse_insn           PROTO((rtx, int));
        !           641: static void note_mem_written   PROTO((rtx, struct write_data *));
        !           642: static void invalidate_from_clobbers PROTO((struct write_data *, rtx));
        !           643: static rtx cse_process_notes   PROTO((rtx, rtx));
        !           644: static void cse_around_loop    PROTO((rtx));
        !           645: static void invalidate_skipped_set PROTO((rtx, rtx));
        !           646: static void invalidate_skipped_block PROTO((rtx));
        !           647: static void cse_check_loop_start PROTO((rtx, rtx));
        !           648: static void cse_set_around_loop        PROTO((rtx, rtx, rtx));
        !           649: static rtx cse_basic_block     PROTO((rtx, rtx, struct branch_path *, int));
        !           650: static void count_reg_usage    PROTO((rtx, int *, int));
        !           651: 
        !           652: /* Return an estimate of the cost of computing rtx X.
        !           653:    One use is in cse, to decide which expression to keep in the hash table.
        !           654:    Another is in rtl generation, to pick the cheapest way to multiply.
        !           655:    Other uses like the latter are expected in the future.  */
        !           656: 
        !           657: /* Return the right cost to give to an operation
        !           658:    to make the cost of the corresponding register-to-register instruction
        !           659:    N times that of a fast register-to-register instruction.  */
        !           660: 
        !           661: #define COSTS_N_INSNS(N) ((N) * 4 - 2)
        !           662: 
        !           663: int
        !           664: rtx_cost (x, outer_code)
        !           665:      rtx x;
        !           666:      enum rtx_code outer_code;
        !           667: {
        !           668:   register int i, j;
        !           669:   register enum rtx_code code;
        !           670:   register char *fmt;
        !           671:   register int total;
        !           672: 
        !           673:   if (x == 0)
        !           674:     return 0;
        !           675: 
        !           676:   /* Compute the default costs of certain things.
        !           677:      Note that RTX_COSTS can override the defaults.  */
        !           678: 
        !           679:   code = GET_CODE (x);
        !           680:   switch (code)
        !           681:     {
        !           682:     case MULT:
        !           683:       /* Count multiplication by 2**n as a shift,
        !           684:         because if we are considering it, we would output it as a shift.  */
        !           685:       if (GET_CODE (XEXP (x, 1)) == CONST_INT
        !           686:          && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
        !           687:        total = 2;
        !           688:       else
        !           689:        total = COSTS_N_INSNS (5);
        !           690:       break;
        !           691:     case DIV:
        !           692:     case UDIV:
        !           693:     case MOD:
        !           694:     case UMOD:
        !           695:       total = COSTS_N_INSNS (7);
        !           696:       break;
        !           697:     case USE:
        !           698:       /* Used in loop.c and combine.c as a marker.  */
        !           699:       total = 0;
        !           700:       break;
        !           701:     case ASM_OPERANDS:
        !           702:       /* We don't want these to be used in substitutions because
        !           703:         we have no way of validating the resulting insn.  So assign
        !           704:         anything containing an ASM_OPERANDS a very high cost.  */
        !           705:       total = 1000;
        !           706:       break;
        !           707:     default:
        !           708:       total = 2;
        !           709:     }
        !           710: 
        !           711:   switch (code)
        !           712:     {
        !           713:     case REG:
        !           714:       return ! CHEAP_REG (REGNO (x));
        !           715: 
        !           716:     case SUBREG:
        !           717:       /* If we can't tie these modes, make this expensive.  The larger
        !           718:         the mode, the more expensive it is.  */
        !           719:       if (! MODES_TIEABLE_P (GET_MODE (x), GET_MODE (SUBREG_REG (x))))
        !           720:        return COSTS_N_INSNS (2
        !           721:                              + GET_MODE_SIZE (GET_MODE (x)) / UNITS_PER_WORD);
        !           722:       return 2;
        !           723: #ifdef RTX_COSTS
        !           724:       RTX_COSTS (x, code, outer_code);
        !           725: #endif 
        !           726:       CONST_COSTS (x, code, outer_code);
        !           727:     }
        !           728: 
        !           729:   /* Sum the costs of the sub-rtx's, plus cost of this operation,
        !           730:      which is already in total.  */
        !           731: 
        !           732:   fmt = GET_RTX_FORMAT (code);
        !           733:   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
        !           734:     if (fmt[i] == 'e')
        !           735:       total += rtx_cost (XEXP (x, i), code);
        !           736:     else if (fmt[i] == 'E')
        !           737:       for (j = 0; j < XVECLEN (x, i); j++)
        !           738:        total += rtx_cost (XVECEXP (x, i, j), code);
        !           739: 
        !           740:   return total;
        !           741: }
        !           742: 
        !           743: /* Clear the hash table and initialize each register with its own quantity,
        !           744:    for a new basic block.  */
        !           745: 
        !           746: static void
        !           747: new_basic_block ()
        !           748: {
        !           749:   register int i;
        !           750: 
        !           751:   next_qty = max_reg;
        !           752: 
        !           753:   bzero (reg_tick, max_reg * sizeof (int));
        !           754: 
        !           755:   bcopy (all_minus_one, reg_in_table, max_reg * sizeof (int));
        !           756:   bcopy (consec_ints, reg_qty, max_reg * sizeof (int));
        !           757:   CLEAR_HARD_REG_SET (hard_regs_in_table);
        !           758: 
        !           759:   /* The per-quantity values used to be initialized here, but it is
        !           760:      much faster to initialize each as it is made in `make_new_qty'.  */
        !           761: 
        !           762:   for (i = 0; i < NBUCKETS; i++)
        !           763:     {
        !           764:       register struct table_elt *this, *next;
        !           765:       for (this = table[i]; this; this = next)
        !           766:        {
        !           767:          next = this->next_same_hash;
        !           768:          free_element (this);
        !           769:        }
        !           770:     }
        !           771: 
        !           772:   bzero (table, sizeof table);
        !           773: 
        !           774:   prev_insn = 0;
        !           775: 
        !           776: #ifdef HAVE_cc0
        !           777:   prev_insn_cc0 = 0;
        !           778: #endif
        !           779: }
        !           780: 
        !           781: /* Say that register REG contains a quantity not in any register before
        !           782:    and initialize that quantity.  */
        !           783: 
        !           784: static void
        !           785: make_new_qty (reg)
        !           786:      register int reg;
        !           787: {
        !           788:   register int q;
        !           789: 
        !           790:   if (next_qty >= max_qty)
        !           791:     abort ();
        !           792: 
        !           793:   q = reg_qty[reg] = next_qty++;
        !           794:   qty_first_reg[q] = reg;
        !           795:   qty_last_reg[q] = reg;
        !           796:   qty_const[q] = qty_const_insn[q] = 0;
        !           797:   qty_comparison_code[q] = UNKNOWN;
        !           798: 
        !           799:   reg_next_eqv[reg] = reg_prev_eqv[reg] = -1;
        !           800: }
        !           801: 
        !           802: /* Make reg NEW equivalent to reg OLD.
        !           803:    OLD is not changing; NEW is.  */
        !           804: 
        !           805: static void
        !           806: make_regs_eqv (new, old)
        !           807:      register int new, old;
        !           808: {
        !           809:   register int lastr, firstr;
        !           810:   register int q = reg_qty[old];
        !           811: 
        !           812:   /* Nothing should become eqv until it has a "non-invalid" qty number.  */
        !           813:   if (! REGNO_QTY_VALID_P (old))
        !           814:     abort ();
        !           815: 
        !           816:   reg_qty[new] = q;
        !           817:   firstr = qty_first_reg[q];
        !           818:   lastr = qty_last_reg[q];
        !           819: 
        !           820:   /* Prefer fixed hard registers to anything.  Prefer pseudo regs to other
        !           821:      hard regs.  Among pseudos, if NEW will live longer than any other reg
        !           822:      of the same qty, and that is beyond the current basic block,
        !           823:      make it the new canonical replacement for this qty.  */
        !           824:   if (! (firstr < FIRST_PSEUDO_REGISTER && FIXED_REGNO_P (firstr))
        !           825:       /* Certain fixed registers might be of the class NO_REGS.  This means
        !           826:         that not only can they not be allocated by the compiler, but
        !           827:         they cannot be used in substitutions or canonicalizations
        !           828:         either.  */
        !           829:       && (new >= FIRST_PSEUDO_REGISTER || REGNO_REG_CLASS (new) != NO_REGS)
        !           830:       && ((new < FIRST_PSEUDO_REGISTER && FIXED_REGNO_P (new))
        !           831:          || (new >= FIRST_PSEUDO_REGISTER
        !           832:              && (firstr < FIRST_PSEUDO_REGISTER
        !           833:                  || ((uid_cuid[regno_last_uid[new]] > cse_basic_block_end
        !           834:                       || (uid_cuid[regno_first_uid[new]]
        !           835:                           < cse_basic_block_start))
        !           836:                      && (uid_cuid[regno_last_uid[new]]
        !           837:                          > uid_cuid[regno_last_uid[firstr]]))))))
        !           838:     {
        !           839:       reg_prev_eqv[firstr] = new;
        !           840:       reg_next_eqv[new] = firstr;
        !           841:       reg_prev_eqv[new] = -1;
        !           842:       qty_first_reg[q] = new;
        !           843:     }
        !           844:   else
        !           845:     {
        !           846:       /* If NEW is a hard reg (known to be non-fixed), insert at end.
        !           847:         Otherwise, insert before any non-fixed hard regs that are at the
        !           848:         end.  Registers of class NO_REGS cannot be used as an
        !           849:         equivalent for anything.  */
        !           850:       while (lastr < FIRST_PSEUDO_REGISTER && reg_prev_eqv[lastr] >= 0
        !           851:             && (REGNO_REG_CLASS (lastr) == NO_REGS || ! FIXED_REGNO_P (lastr))
        !           852:             && new >= FIRST_PSEUDO_REGISTER)
        !           853:        lastr = reg_prev_eqv[lastr];
        !           854:       reg_next_eqv[new] = reg_next_eqv[lastr];
        !           855:       if (reg_next_eqv[lastr] >= 0)
        !           856:        reg_prev_eqv[reg_next_eqv[lastr]] = new;
        !           857:       else
        !           858:        qty_last_reg[q] = new;
        !           859:       reg_next_eqv[lastr] = new;
        !           860:       reg_prev_eqv[new] = lastr;
        !           861:     }
        !           862: }
        !           863: 
        !           864: /* Remove REG from its equivalence class.  */
        !           865: 
        !           866: static void
        !           867: delete_reg_equiv (reg)
        !           868:      register int reg;
        !           869: {
        !           870:   register int n = reg_next_eqv[reg];
        !           871:   register int p = reg_prev_eqv[reg];
        !           872:   register int q = reg_qty[reg];
        !           873: 
        !           874:   /* If invalid, do nothing.  N and P above are undefined in that case.  */
        !           875:   if (q == reg)
        !           876:     return;
        !           877: 
        !           878:   if (n != -1)
        !           879:     reg_prev_eqv[n] = p;
        !           880:   else
        !           881:     qty_last_reg[q] = p;
        !           882:   if (p != -1)
        !           883:     reg_next_eqv[p] = n;
        !           884:   else
        !           885:     qty_first_reg[q] = n;
        !           886: 
        !           887:   reg_qty[reg] = reg;
        !           888: }
        !           889: 
        !           890: /* Remove any invalid expressions from the hash table
        !           891:    that refer to any of the registers contained in expression X.
        !           892: 
        !           893:    Make sure that newly inserted references to those registers
        !           894:    as subexpressions will be considered valid.
        !           895: 
        !           896:    mention_regs is not called when a register itself
        !           897:    is being stored in the table.
        !           898: 
        !           899:    Return 1 if we have done something that may have changed the hash code
        !           900:    of X.  */
        !           901: 
        !           902: static int
        !           903: mention_regs (x)
        !           904:      rtx x;
        !           905: {
        !           906:   register enum rtx_code code;
        !           907:   register int i, j;
        !           908:   register char *fmt;
        !           909:   register int changed = 0;
        !           910: 
        !           911:   if (x == 0)
        !           912:     return 0;
        !           913: 
        !           914:   code = GET_CODE (x);
        !           915:   if (code == REG)
        !           916:     {
        !           917:       register int regno = REGNO (x);
        !           918:       register int endregno
        !           919:        = regno + (regno >= FIRST_PSEUDO_REGISTER ? 1
        !           920:                   : HARD_REGNO_NREGS (regno, GET_MODE (x)));
        !           921:       int i;
        !           922: 
        !           923:       for (i = regno; i < endregno; i++)
        !           924:        {
        !           925:          if (reg_in_table[i] >= 0 && reg_in_table[i] != reg_tick[i])
        !           926:            remove_invalid_refs (i);
        !           927: 
        !           928:          reg_in_table[i] = reg_tick[i];
        !           929:        }
        !           930: 
        !           931:       return 0;
        !           932:     }
        !           933: 
        !           934:   /* If X is a comparison or a COMPARE and either operand is a register
        !           935:      that does not have a quantity, give it one.  This is so that a later
        !           936:      call to record_jump_equiv won't cause X to be assigned a different
        !           937:      hash code and not found in the table after that call.
        !           938: 
        !           939:      It is not necessary to do this here, since rehash_using_reg can
        !           940:      fix up the table later, but doing this here eliminates the need to
        !           941:      call that expensive function in the most common case where the only
        !           942:      use of the register is in the comparison.  */
        !           943: 
        !           944:   if (code == COMPARE || GET_RTX_CLASS (code) == '<')
        !           945:     {
        !           946:       if (GET_CODE (XEXP (x, 0)) == REG
        !           947:          && ! REGNO_QTY_VALID_P (REGNO (XEXP (x, 0))))
        !           948:        if (insert_regs (XEXP (x, 0), NULL_PTR, 0))
        !           949:          {
        !           950:            rehash_using_reg (XEXP (x, 0));
        !           951:            changed = 1;
        !           952:          }
        !           953: 
        !           954:       if (GET_CODE (XEXP (x, 1)) == REG
        !           955:          && ! REGNO_QTY_VALID_P (REGNO (XEXP (x, 1))))
        !           956:        if (insert_regs (XEXP (x, 1), NULL_PTR, 0))
        !           957:          {
        !           958:            rehash_using_reg (XEXP (x, 1));
        !           959:            changed = 1;
        !           960:          }
        !           961:     }
        !           962: 
        !           963:   fmt = GET_RTX_FORMAT (code);
        !           964:   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
        !           965:     if (fmt[i] == 'e')
        !           966:       changed |= mention_regs (XEXP (x, i));
        !           967:     else if (fmt[i] == 'E')
        !           968:       for (j = 0; j < XVECLEN (x, i); j++)
        !           969:        changed |= mention_regs (XVECEXP (x, i, j));
        !           970: 
        !           971:   return changed;
        !           972: }
        !           973: 
        !           974: /* Update the register quantities for inserting X into the hash table
        !           975:    with a value equivalent to CLASSP.
        !           976:    (If the class does not contain a REG, it is irrelevant.)
        !           977:    If MODIFIED is nonzero, X is a destination; it is being modified.
        !           978:    Note that delete_reg_equiv should be called on a register
        !           979:    before insert_regs is done on that register with MODIFIED != 0.
        !           980: 
        !           981:    Nonzero value means that elements of reg_qty have changed
        !           982:    so X's hash code may be different.  */
        !           983: 
        !           984: static int
        !           985: insert_regs (x, classp, modified)
        !           986:      rtx x;
        !           987:      struct table_elt *classp;
        !           988:      int modified;
        !           989: {
        !           990:   if (GET_CODE (x) == REG)
        !           991:     {
        !           992:       register int regno = REGNO (x);
        !           993: 
        !           994:       /* If REGNO is in the equivalence table already but is of the
        !           995:         wrong mode for that equivalence, don't do anything here.  */
        !           996: 
        !           997:       if (REGNO_QTY_VALID_P (regno)
        !           998:          && qty_mode[reg_qty[regno]] != GET_MODE (x))
        !           999:        return 0;
        !          1000: 
        !          1001:       if (modified || ! REGNO_QTY_VALID_P (regno))
        !          1002:        {
        !          1003:          if (classp)
        !          1004:            for (classp = classp->first_same_value;
        !          1005:                 classp != 0;
        !          1006:                 classp = classp->next_same_value)
        !          1007:              if (GET_CODE (classp->exp) == REG
        !          1008:                  && GET_MODE (classp->exp) == GET_MODE (x))
        !          1009:                {
        !          1010:                  make_regs_eqv (regno, REGNO (classp->exp));
        !          1011:                  return 1;
        !          1012:                }
        !          1013: 
        !          1014:          make_new_qty (regno);
        !          1015:          qty_mode[reg_qty[regno]] = GET_MODE (x);
        !          1016:          return 1;
        !          1017:        }
        !          1018: 
        !          1019:       return 0;
        !          1020:     }
        !          1021: 
        !          1022:   /* If X is a SUBREG, we will likely be inserting the inner register in the
        !          1023:      table.  If that register doesn't have an assigned quantity number at
        !          1024:      this point but does later, the insertion that we will be doing now will
        !          1025:      not be accessible because its hash code will have changed.  So assign
        !          1026:      a quantity number now.  */
        !          1027: 
        !          1028:   else if (GET_CODE (x) == SUBREG && GET_CODE (SUBREG_REG (x)) == REG
        !          1029:           && ! REGNO_QTY_VALID_P (REGNO (SUBREG_REG (x))))
        !          1030:     {
        !          1031:       insert_regs (SUBREG_REG (x), NULL_PTR, 0);
        !          1032:       mention_regs (SUBREG_REG (x));
        !          1033:       return 1;
        !          1034:     }
        !          1035:   else
        !          1036:     return mention_regs (x);
        !          1037: }
        !          1038: 
        !          1039: /* Look in or update the hash table.  */
        !          1040: 
        !          1041: /* Put the element ELT on the list of free elements.  */
        !          1042: 
        !          1043: static void
        !          1044: free_element (elt)
        !          1045:      struct table_elt *elt;
        !          1046: {
        !          1047:   elt->next_same_hash = free_element_chain;
        !          1048:   free_element_chain = elt;
        !          1049: }
        !          1050: 
        !          1051: /* Return an element that is free for use.  */
        !          1052: 
        !          1053: static struct table_elt *
        !          1054: get_element ()
        !          1055: {
        !          1056:   struct table_elt *elt = free_element_chain;
        !          1057:   if (elt)
        !          1058:     {
        !          1059:       free_element_chain = elt->next_same_hash;
        !          1060:       return elt;
        !          1061:     }
        !          1062:   n_elements_made++;
        !          1063:   return (struct table_elt *) oballoc (sizeof (struct table_elt));
        !          1064: }
        !          1065: 
        !          1066: /* Remove table element ELT from use in the table.
        !          1067:    HASH is its hash code, made using the HASH macro.
        !          1068:    It's an argument because often that is known in advance
        !          1069:    and we save much time not recomputing it.  */
        !          1070: 
        !          1071: static void
        !          1072: remove_from_table (elt, hash)
        !          1073:      register struct table_elt *elt;
        !          1074:      int hash;
        !          1075: {
        !          1076:   if (elt == 0)
        !          1077:     return;
        !          1078: 
        !          1079:   /* Mark this element as removed.  See cse_insn.  */
        !          1080:   elt->first_same_value = 0;
        !          1081: 
        !          1082:   /* Remove the table element from its equivalence class.  */
        !          1083:      
        !          1084:   {
        !          1085:     register struct table_elt *prev = elt->prev_same_value;
        !          1086:     register struct table_elt *next = elt->next_same_value;
        !          1087: 
        !          1088:     if (next) next->prev_same_value = prev;
        !          1089: 
        !          1090:     if (prev)
        !          1091:       prev->next_same_value = next;
        !          1092:     else
        !          1093:       {
        !          1094:        register struct table_elt *newfirst = next;
        !          1095:        while (next)
        !          1096:          {
        !          1097:            next->first_same_value = newfirst;
        !          1098:            next = next->next_same_value;
        !          1099:          }
        !          1100:       }
        !          1101:   }
        !          1102: 
        !          1103:   /* Remove the table element from its hash bucket.  */
        !          1104: 
        !          1105:   {
        !          1106:     register struct table_elt *prev = elt->prev_same_hash;
        !          1107:     register struct table_elt *next = elt->next_same_hash;
        !          1108: 
        !          1109:     if (next) next->prev_same_hash = prev;
        !          1110: 
        !          1111:     if (prev)
        !          1112:       prev->next_same_hash = next;
        !          1113:     else if (table[hash] == elt)
        !          1114:       table[hash] = next;
        !          1115:     else
        !          1116:       {
        !          1117:        /* This entry is not in the proper hash bucket.  This can happen
        !          1118:           when two classes were merged by `merge_equiv_classes'.  Search
        !          1119:           for the hash bucket that it heads.  This happens only very
        !          1120:           rarely, so the cost is acceptable.  */
        !          1121:        for (hash = 0; hash < NBUCKETS; hash++)
        !          1122:          if (table[hash] == elt)
        !          1123:            table[hash] = next;
        !          1124:       }
        !          1125:   }
        !          1126: 
        !          1127:   /* Remove the table element from its related-value circular chain.  */
        !          1128: 
        !          1129:   if (elt->related_value != 0 && elt->related_value != elt)
        !          1130:     {
        !          1131:       register struct table_elt *p = elt->related_value;
        !          1132:       while (p->related_value != elt)
        !          1133:        p = p->related_value;
        !          1134:       p->related_value = elt->related_value;
        !          1135:       if (p->related_value == p)
        !          1136:        p->related_value = 0;
        !          1137:     }
        !          1138: 
        !          1139:   free_element (elt);
        !          1140: }
        !          1141: 
        !          1142: /* Look up X in the hash table and return its table element,
        !          1143:    or 0 if X is not in the table.
        !          1144: 
        !          1145:    MODE is the machine-mode of X, or if X is an integer constant
        !          1146:    with VOIDmode then MODE is the mode with which X will be used.
        !          1147: 
        !          1148:    Here we are satisfied to find an expression whose tree structure
        !          1149:    looks like X.  */
        !          1150: 
        !          1151: static struct table_elt *
        !          1152: lookup (x, hash, mode)
        !          1153:      rtx x;
        !          1154:      int hash;
        !          1155:      enum machine_mode mode;
        !          1156: {
        !          1157:   register struct table_elt *p;
        !          1158: 
        !          1159:   for (p = table[hash]; p; p = p->next_same_hash)
        !          1160:     if (mode == p->mode && ((x == p->exp && GET_CODE (x) == REG)
        !          1161:                            || exp_equiv_p (x, p->exp, GET_CODE (x) != REG, 0)))
        !          1162:       return p;
        !          1163: 
        !          1164:   return 0;
        !          1165: }
        !          1166: 
        !          1167: /* Like `lookup' but don't care whether the table element uses invalid regs.
        !          1168:    Also ignore discrepancies in the machine mode of a register.  */
        !          1169: 
        !          1170: static struct table_elt *
        !          1171: lookup_for_remove (x, hash, mode)
        !          1172:      rtx x;
        !          1173:      int hash;
        !          1174:      enum machine_mode mode;
        !          1175: {
        !          1176:   register struct table_elt *p;
        !          1177: 
        !          1178:   if (GET_CODE (x) == REG)
        !          1179:     {
        !          1180:       int regno = REGNO (x);
        !          1181:       /* Don't check the machine mode when comparing registers;
        !          1182:         invalidating (REG:SI 0) also invalidates (REG:DF 0).  */
        !          1183:       for (p = table[hash]; p; p = p->next_same_hash)
        !          1184:        if (GET_CODE (p->exp) == REG
        !          1185:            && REGNO (p->exp) == regno)
        !          1186:          return p;
        !          1187:     }
        !          1188:   else
        !          1189:     {
        !          1190:       for (p = table[hash]; p; p = p->next_same_hash)
        !          1191:        if (mode == p->mode && (x == p->exp || exp_equiv_p (x, p->exp, 0, 0)))
        !          1192:          return p;
        !          1193:     }
        !          1194: 
        !          1195:   return 0;
        !          1196: }
        !          1197: 
        !          1198: /* Look for an expression equivalent to X and with code CODE.
        !          1199:    If one is found, return that expression.  */
        !          1200: 
        !          1201: static rtx
        !          1202: lookup_as_function (x, code)
        !          1203:      rtx x;
        !          1204:      enum rtx_code code;
        !          1205: {
        !          1206:   register struct table_elt *p = lookup (x, safe_hash (x, VOIDmode) % NBUCKETS,
        !          1207:                                         GET_MODE (x));
        !          1208:   if (p == 0)
        !          1209:     return 0;
        !          1210: 
        !          1211:   for (p = p->first_same_value; p; p = p->next_same_value)
        !          1212:     {
        !          1213:       if (GET_CODE (p->exp) == code
        !          1214:          /* Make sure this is a valid entry in the table.  */
        !          1215:          && exp_equiv_p (p->exp, p->exp, 1, 0))
        !          1216:        return p->exp;
        !          1217:     }
        !          1218:   
        !          1219:   return 0;
        !          1220: }
        !          1221: 
        !          1222: /* Insert X in the hash table, assuming HASH is its hash code
        !          1223:    and CLASSP is an element of the class it should go in
        !          1224:    (or 0 if a new class should be made).
        !          1225:    It is inserted at the proper position to keep the class in
        !          1226:    the order cheapest first.
        !          1227: 
        !          1228:    MODE is the machine-mode of X, or if X is an integer constant
        !          1229:    with VOIDmode then MODE is the mode with which X will be used.
        !          1230: 
        !          1231:    For elements of equal cheapness, the most recent one
        !          1232:    goes in front, except that the first element in the list
        !          1233:    remains first unless a cheaper element is added.  The order of
        !          1234:    pseudo-registers does not matter, as canon_reg will be called to
        !          1235:    find the cheapest when a register is retrieved from the table.
        !          1236: 
        !          1237:    The in_memory field in the hash table element is set to 0.
        !          1238:    The caller must set it nonzero if appropriate.
        !          1239: 
        !          1240:    You should call insert_regs (X, CLASSP, MODIFY) before calling here,
        !          1241:    and if insert_regs returns a nonzero value
        !          1242:    you must then recompute its hash code before calling here.
        !          1243: 
        !          1244:    If necessary, update table showing constant values of quantities.  */
        !          1245: 
        !          1246: #define CHEAPER(X,Y)   ((X)->cost < (Y)->cost)
        !          1247: 
        !          1248: static struct table_elt *
        !          1249: insert (x, classp, hash, mode)
        !          1250:      register rtx x;
        !          1251:      register struct table_elt *classp;
        !          1252:      int hash;
        !          1253:      enum machine_mode mode;
        !          1254: {
        !          1255:   register struct table_elt *elt;
        !          1256: 
        !          1257:   /* If X is a register and we haven't made a quantity for it,
        !          1258:      something is wrong.  */
        !          1259:   if (GET_CODE (x) == REG && ! REGNO_QTY_VALID_P (REGNO (x)))
        !          1260:     abort ();
        !          1261: 
        !          1262:   /* If X is a hard register, show it is being put in the table.  */
        !          1263:   if (GET_CODE (x) == REG && REGNO (x) < FIRST_PSEUDO_REGISTER)
        !          1264:     {
        !          1265:       int regno = REGNO (x);
        !          1266:       int endregno = regno + HARD_REGNO_NREGS (regno, GET_MODE (x));
        !          1267:       int i;
        !          1268: 
        !          1269:       for (i = regno; i < endregno; i++)
        !          1270:            SET_HARD_REG_BIT (hard_regs_in_table, i);
        !          1271:     }
        !          1272: 
        !          1273: 
        !          1274:   /* Put an element for X into the right hash bucket.  */
        !          1275: 
        !          1276:   elt = get_element ();
        !          1277:   elt->exp = x;
        !          1278:   elt->cost = COST (x);
        !          1279:   elt->next_same_value = 0;
        !          1280:   elt->prev_same_value = 0;
        !          1281:   elt->next_same_hash = table[hash];
        !          1282:   elt->prev_same_hash = 0;
        !          1283:   elt->related_value = 0;
        !          1284:   elt->in_memory = 0;
        !          1285:   elt->mode = mode;
        !          1286:   elt->is_const = (CONSTANT_P (x)
        !          1287:                   /* GNU C++ takes advantage of this for `this'
        !          1288:                      (and other const values).  */
        !          1289:                   || (RTX_UNCHANGING_P (x)
        !          1290:                       && GET_CODE (x) == REG
        !          1291:                       && REGNO (x) >= FIRST_PSEUDO_REGISTER)
        !          1292:                   || FIXED_BASE_PLUS_P (x));
        !          1293: 
        !          1294:   if (table[hash])
        !          1295:     table[hash]->prev_same_hash = elt;
        !          1296:   table[hash] = elt;
        !          1297: 
        !          1298:   /* Put it into the proper value-class.  */
        !          1299:   if (classp)
        !          1300:     {
        !          1301:       classp = classp->first_same_value;
        !          1302:       if (CHEAPER (elt, classp))
        !          1303:        /* Insert at the head of the class */
        !          1304:        {
        !          1305:          register struct table_elt *p;
        !          1306:          elt->next_same_value = classp;
        !          1307:          classp->prev_same_value = elt;
        !          1308:          elt->first_same_value = elt;
        !          1309: 
        !          1310:          for (p = classp; p; p = p->next_same_value)
        !          1311:            p->first_same_value = elt;
        !          1312:        }
        !          1313:       else
        !          1314:        {
        !          1315:          /* Insert not at head of the class.  */
        !          1316:          /* Put it after the last element cheaper than X.  */
        !          1317:          register struct table_elt *p, *next;
        !          1318:          for (p = classp; (next = p->next_same_value) && CHEAPER (next, elt);
        !          1319:               p = next);
        !          1320:          /* Put it after P and before NEXT.  */
        !          1321:          elt->next_same_value = next;
        !          1322:          if (next)
        !          1323:            next->prev_same_value = elt;
        !          1324:          elt->prev_same_value = p;
        !          1325:          p->next_same_value = elt;
        !          1326:          elt->first_same_value = classp;
        !          1327:        }
        !          1328:     }
        !          1329:   else
        !          1330:     elt->first_same_value = elt;
        !          1331: 
        !          1332:   /* If this is a constant being set equivalent to a register or a register
        !          1333:      being set equivalent to a constant, note the constant equivalence.
        !          1334: 
        !          1335:      If this is a constant, it cannot be equivalent to a different constant,
        !          1336:      and a constant is the only thing that can be cheaper than a register.  So
        !          1337:      we know the register is the head of the class (before the constant was
        !          1338:      inserted).
        !          1339: 
        !          1340:      If this is a register that is not already known equivalent to a
        !          1341:      constant, we must check the entire class.
        !          1342: 
        !          1343:      If this is a register that is already known equivalent to an insn,
        !          1344:      update `qty_const_insn' to show that `this_insn' is the latest
        !          1345:      insn making that quantity equivalent to the constant.  */
        !          1346: 
        !          1347:   if (elt->is_const && classp && GET_CODE (classp->exp) == REG)
        !          1348:     {
        !          1349:       qty_const[reg_qty[REGNO (classp->exp)]]
        !          1350:        = gen_lowpart_if_possible (qty_mode[reg_qty[REGNO (classp->exp)]], x);
        !          1351:       qty_const_insn[reg_qty[REGNO (classp->exp)]] = this_insn;
        !          1352:     }
        !          1353: 
        !          1354:   else if (GET_CODE (x) == REG && classp && ! qty_const[reg_qty[REGNO (x)]])
        !          1355:     {
        !          1356:       register struct table_elt *p;
        !          1357: 
        !          1358:       for (p = classp; p != 0; p = p->next_same_value)
        !          1359:        {
        !          1360:          if (p->is_const)
        !          1361:            {
        !          1362:              qty_const[reg_qty[REGNO (x)]]
        !          1363:                = gen_lowpart_if_possible (GET_MODE (x), p->exp);
        !          1364:              qty_const_insn[reg_qty[REGNO (x)]] = this_insn;
        !          1365:              break;
        !          1366:            }
        !          1367:        }
        !          1368:     }
        !          1369: 
        !          1370:   else if (GET_CODE (x) == REG && qty_const[reg_qty[REGNO (x)]]
        !          1371:           && GET_MODE (x) == qty_mode[reg_qty[REGNO (x)]])
        !          1372:     qty_const_insn[reg_qty[REGNO (x)]] = this_insn;
        !          1373: 
        !          1374:   /* If this is a constant with symbolic value,
        !          1375:      and it has a term with an explicit integer value,
        !          1376:      link it up with related expressions.  */
        !          1377:   if (GET_CODE (x) == CONST)
        !          1378:     {
        !          1379:       rtx subexp = get_related_value (x);
        !          1380:       int subhash;
        !          1381:       struct table_elt *subelt, *subelt_prev;
        !          1382: 
        !          1383:       if (subexp != 0)
        !          1384:        {
        !          1385:          /* Get the integer-free subexpression in the hash table.  */
        !          1386:          subhash = safe_hash (subexp, mode) % NBUCKETS;
        !          1387:          subelt = lookup (subexp, subhash, mode);
        !          1388:          if (subelt == 0)
        !          1389:            subelt = insert (subexp, NULL_PTR, subhash, mode);
        !          1390:          /* Initialize SUBELT's circular chain if it has none.  */
        !          1391:          if (subelt->related_value == 0)
        !          1392:            subelt->related_value = subelt;
        !          1393:          /* Find the element in the circular chain that precedes SUBELT.  */
        !          1394:          subelt_prev = subelt;
        !          1395:          while (subelt_prev->related_value != subelt)
        !          1396:            subelt_prev = subelt_prev->related_value;
        !          1397:          /* Put new ELT into SUBELT's circular chain just before SUBELT.
        !          1398:             This way the element that follows SUBELT is the oldest one.  */
        !          1399:          elt->related_value = subelt_prev->related_value;
        !          1400:          subelt_prev->related_value = elt;
        !          1401:        }
        !          1402:     }
        !          1403: 
        !          1404:   return elt;
        !          1405: }
        !          1406: 
        !          1407: /* Given two equivalence classes, CLASS1 and CLASS2, put all the entries from
        !          1408:    CLASS2 into CLASS1.  This is done when we have reached an insn which makes
        !          1409:    the two classes equivalent.
        !          1410: 
        !          1411:    CLASS1 will be the surviving class; CLASS2 should not be used after this
        !          1412:    call.
        !          1413: 
        !          1414:    Any invalid entries in CLASS2 will not be copied.  */
        !          1415: 
        !          1416: static void
        !          1417: merge_equiv_classes (class1, class2)
        !          1418:      struct table_elt *class1, *class2;
        !          1419: {
        !          1420:   struct table_elt *elt, *next, *new;
        !          1421: 
        !          1422:   /* Ensure we start with the head of the classes.  */
        !          1423:   class1 = class1->first_same_value;
        !          1424:   class2 = class2->first_same_value;
        !          1425: 
        !          1426:   /* If they were already equal, forget it.  */
        !          1427:   if (class1 == class2)
        !          1428:     return;
        !          1429: 
        !          1430:   for (elt = class2; elt; elt = next)
        !          1431:     {
        !          1432:       int hash;
        !          1433:       rtx exp = elt->exp;
        !          1434:       enum machine_mode mode = elt->mode;
        !          1435: 
        !          1436:       next = elt->next_same_value;
        !          1437: 
        !          1438:       /* Remove old entry, make a new one in CLASS1's class.
        !          1439:         Don't do this for invalid entries as we cannot find their
        !          1440:         hash code (it also isn't necessary). */
        !          1441:       if (GET_CODE (exp) == REG || exp_equiv_p (exp, exp, 1, 0))
        !          1442:        {
        !          1443:          hash_arg_in_memory = 0;
        !          1444:          hash_arg_in_struct = 0;
        !          1445:          hash = HASH (exp, mode);
        !          1446:              
        !          1447:          if (GET_CODE (exp) == REG)
        !          1448:            delete_reg_equiv (REGNO (exp));
        !          1449:              
        !          1450:          remove_from_table (elt, hash);
        !          1451: 
        !          1452:          if (insert_regs (exp, class1, 0))
        !          1453:            hash = HASH (exp, mode);
        !          1454:          new = insert (exp, class1, hash, mode);
        !          1455:          new->in_memory = hash_arg_in_memory;
        !          1456:          new->in_struct = hash_arg_in_struct;
        !          1457:        }
        !          1458:     }
        !          1459: }
        !          1460: 
        !          1461: /* Remove from the hash table, or mark as invalid,
        !          1462:    all expressions whose values could be altered by storing in X.
        !          1463:    X is a register, a subreg, or a memory reference with nonvarying address
        !          1464:    (because, when a memory reference with a varying address is stored in,
        !          1465:    all memory references are removed by invalidate_memory
        !          1466:    so specific invalidation is superfluous).
        !          1467: 
        !          1468:    A nonvarying address may be just a register or just
        !          1469:    a symbol reference, or it may be either of those plus
        !          1470:    a numeric offset.  */
        !          1471: 
        !          1472: static void
        !          1473: invalidate (x)
        !          1474:      rtx x;
        !          1475: {
        !          1476:   register int i;
        !          1477:   register struct table_elt *p;
        !          1478:   rtx base;
        !          1479:   HOST_WIDE_INT start, end;
        !          1480: 
        !          1481:   /* If X is a register, dependencies on its contents
        !          1482:      are recorded through the qty number mechanism.
        !          1483:      Just change the qty number of the register,
        !          1484:      mark it as invalid for expressions that refer to it,
        !          1485:      and remove it itself.  */
        !          1486: 
        !          1487:   if (GET_CODE (x) == REG)
        !          1488:     {
        !          1489:       register int regno = REGNO (x);
        !          1490:       register int hash = HASH (x, GET_MODE (x));
        !          1491: 
        !          1492:       /* Remove REGNO from any quantity list it might be on and indicate
        !          1493:         that it's value might have changed.  If it is a pseudo, remove its
        !          1494:         entry from the hash table.
        !          1495: 
        !          1496:         For a hard register, we do the first two actions above for any
        !          1497:         additional hard registers corresponding to X.  Then, if any of these
        !          1498:         registers are in the table, we must remove any REG entries that
        !          1499:         overlap these registers.  */
        !          1500: 
        !          1501:       delete_reg_equiv (regno);
        !          1502:       reg_tick[regno]++;
        !          1503: 
        !          1504:       if (regno >= FIRST_PSEUDO_REGISTER)
        !          1505:        remove_from_table (lookup_for_remove (x, hash, GET_MODE (x)), hash);
        !          1506:       else
        !          1507:        {
        !          1508:          HOST_WIDE_INT in_table
        !          1509:            = TEST_HARD_REG_BIT (hard_regs_in_table, regno);
        !          1510:          int endregno = regno + HARD_REGNO_NREGS (regno, GET_MODE (x));
        !          1511:          int tregno, tendregno;
        !          1512:          register struct table_elt *p, *next;
        !          1513: 
        !          1514:          CLEAR_HARD_REG_BIT (hard_regs_in_table, regno);
        !          1515: 
        !          1516:          for (i = regno + 1; i < endregno; i++)
        !          1517:            {
        !          1518:              in_table |= TEST_HARD_REG_BIT (hard_regs_in_table, i);
        !          1519:              CLEAR_HARD_REG_BIT (hard_regs_in_table, i);
        !          1520:              delete_reg_equiv (i);
        !          1521:              reg_tick[i]++;
        !          1522:            }
        !          1523: 
        !          1524:          if (in_table)
        !          1525:            for (hash = 0; hash < NBUCKETS; hash++)
        !          1526:              for (p = table[hash]; p; p = next)
        !          1527:                {
        !          1528:                  next = p->next_same_hash;
        !          1529: 
        !          1530:                  if (GET_CODE (p->exp) != REG
        !          1531:                      || REGNO (p->exp) >= FIRST_PSEUDO_REGISTER)
        !          1532:                    continue;
        !          1533: 
        !          1534:                  tregno = REGNO (p->exp);
        !          1535:                  tendregno
        !          1536:                    = tregno + HARD_REGNO_NREGS (tregno, GET_MODE (p->exp));
        !          1537:                  if (tendregno > regno && tregno < endregno)
        !          1538:                  remove_from_table (p, hash);
        !          1539:                }
        !          1540:        }
        !          1541: 
        !          1542:       return;
        !          1543:     }
        !          1544: 
        !          1545:   if (GET_CODE (x) == SUBREG)
        !          1546:     {
        !          1547:       if (GET_CODE (SUBREG_REG (x)) != REG)
        !          1548:        abort ();
        !          1549:       invalidate (SUBREG_REG (x));
        !          1550:       return;
        !          1551:     }
        !          1552: 
        !          1553:   /* X is not a register; it must be a memory reference with
        !          1554:      a nonvarying address.  Remove all hash table elements
        !          1555:      that refer to overlapping pieces of memory.  */
        !          1556: 
        !          1557:   if (GET_CODE (x) != MEM)
        !          1558:     abort ();
        !          1559: 
        !          1560:   set_nonvarying_address_components (XEXP (x, 0), GET_MODE_SIZE (GET_MODE (x)),
        !          1561:                                     &base, &start, &end);
        !          1562: 
        !          1563:   for (i = 0; i < NBUCKETS; i++)
        !          1564:     {
        !          1565:       register struct table_elt *next;
        !          1566:       for (p = table[i]; p; p = next)
        !          1567:        {
        !          1568:          next = p->next_same_hash;
        !          1569:          if (refers_to_mem_p (p->exp, base, start, end))
        !          1570:            remove_from_table (p, i);
        !          1571:        }
        !          1572:     }
        !          1573: }
        !          1574: 
        !          1575: /* Remove all expressions that refer to register REGNO,
        !          1576:    since they are already invalid, and we are about to
        !          1577:    mark that register valid again and don't want the old
        !          1578:    expressions to reappear as valid.  */
        !          1579: 
        !          1580: static void
        !          1581: remove_invalid_refs (regno)
        !          1582:      int regno;
        !          1583: {
        !          1584:   register int i;
        !          1585:   register struct table_elt *p, *next;
        !          1586: 
        !          1587:   for (i = 0; i < NBUCKETS; i++)
        !          1588:     for (p = table[i]; p; p = next)
        !          1589:       {
        !          1590:        next = p->next_same_hash;
        !          1591:        if (GET_CODE (p->exp) != REG
        !          1592:            && refers_to_regno_p (regno, regno + 1, p->exp, NULL_PTR))
        !          1593:          remove_from_table (p, i);
        !          1594:       }
        !          1595: }
        !          1596: 
        !          1597: /* Recompute the hash codes of any valid entries in the hash table that
        !          1598:    reference X, if X is a register, or SUBREG_REG (X) if X is a SUBREG.
        !          1599: 
        !          1600:    This is called when we make a jump equivalence.  */
        !          1601: 
        !          1602: static void
        !          1603: rehash_using_reg (x)
        !          1604:      rtx x;
        !          1605: {
        !          1606:   int i;
        !          1607:   struct table_elt *p, *next;
        !          1608:   int hash;
        !          1609: 
        !          1610:   if (GET_CODE (x) == SUBREG)
        !          1611:     x = SUBREG_REG (x);
        !          1612: 
        !          1613:   /* If X is not a register or if the register is known not to be in any
        !          1614:      valid entries in the table, we have no work to do.  */
        !          1615: 
        !          1616:   if (GET_CODE (x) != REG
        !          1617:       || reg_in_table[REGNO (x)] < 0
        !          1618:       || reg_in_table[REGNO (x)] != reg_tick[REGNO (x)])
        !          1619:     return;
        !          1620: 
        !          1621:   /* Scan all hash chains looking for valid entries that mention X.
        !          1622:      If we find one and it is in the wrong hash chain, move it.  We can skip
        !          1623:      objects that are registers, since they are handled specially.  */
        !          1624: 
        !          1625:   for (i = 0; i < NBUCKETS; i++)
        !          1626:     for (p = table[i]; p; p = next)
        !          1627:       {
        !          1628:        next = p->next_same_hash;
        !          1629:        if (GET_CODE (p->exp) != REG && reg_mentioned_p (x, p->exp)
        !          1630:            && exp_equiv_p (p->exp, p->exp, 1, 0)
        !          1631:            && i != (hash = safe_hash (p->exp, p->mode) % NBUCKETS))
        !          1632:          {
        !          1633:            if (p->next_same_hash)
        !          1634:              p->next_same_hash->prev_same_hash = p->prev_same_hash;
        !          1635: 
        !          1636:            if (p->prev_same_hash)
        !          1637:              p->prev_same_hash->next_same_hash = p->next_same_hash;
        !          1638:            else
        !          1639:              table[i] = p->next_same_hash;
        !          1640: 
        !          1641:            p->next_same_hash = table[hash];
        !          1642:            p->prev_same_hash = 0;
        !          1643:            if (table[hash])
        !          1644:              table[hash]->prev_same_hash = p;
        !          1645:            table[hash] = p;
        !          1646:          }
        !          1647:       }
        !          1648: }
        !          1649: 
        !          1650: /* Remove from the hash table all expressions that reference memory,
        !          1651:    or some of them as specified by *WRITES.  */
        !          1652: 
        !          1653: static void
        !          1654: invalidate_memory (writes)
        !          1655:      struct write_data *writes;
        !          1656: {
        !          1657:   register int i;
        !          1658:   register struct table_elt *p, *next;
        !          1659:   int all = writes->all;
        !          1660:   int nonscalar = writes->nonscalar;
        !          1661: 
        !          1662:   for (i = 0; i < NBUCKETS; i++)
        !          1663:     for (p = table[i]; p; p = next)
        !          1664:       {
        !          1665:        next = p->next_same_hash;
        !          1666:        if (p->in_memory
        !          1667:            && (all
        !          1668:                || (nonscalar && p->in_struct)
        !          1669:                || cse_rtx_addr_varies_p (p->exp)))
        !          1670:          remove_from_table (p, i);
        !          1671:       }
        !          1672: }
        !          1673: 
        !          1674: /* Remove from the hash table any expression that is a call-clobbered
        !          1675:    register.  Also update their TICK values.  */
        !          1676: 
        !          1677: static void
        !          1678: invalidate_for_call ()
        !          1679: {
        !          1680:   int regno, endregno;
        !          1681:   int i;
        !          1682:   int hash;
        !          1683:   struct table_elt *p, *next;
        !          1684:   int in_table = 0;
        !          1685: 
        !          1686:   /* Go through all the hard registers.  For each that is clobbered in
        !          1687:      a CALL_INSN, remove the register from quantity chains and update
        !          1688:      reg_tick if defined.  Also see if any of these registers is currently
        !          1689:      in the table.  */
        !          1690: 
        !          1691:   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
        !          1692:     if (TEST_HARD_REG_BIT (regs_invalidated_by_call, regno))
        !          1693:       {
        !          1694:        delete_reg_equiv (regno);
        !          1695:        if (reg_tick[regno] >= 0)
        !          1696:          reg_tick[regno]++;
        !          1697: 
        !          1698:        in_table |= TEST_HARD_REG_BIT (hard_regs_in_table, regno);
        !          1699:       }
        !          1700: 
        !          1701:   /* In the case where we have no call-clobbered hard registers in the
        !          1702:      table, we are done.  Otherwise, scan the table and remove any
        !          1703:      entry that overlaps a call-clobbered register.  */
        !          1704: 
        !          1705:   if (in_table)
        !          1706:     for (hash = 0; hash < NBUCKETS; hash++)
        !          1707:       for (p = table[hash]; p; p = next)
        !          1708:        {
        !          1709:          next = p->next_same_hash;
        !          1710: 
        !          1711:          if (GET_CODE (p->exp) != REG
        !          1712:              || REGNO (p->exp) >= FIRST_PSEUDO_REGISTER)
        !          1713:            continue;
        !          1714: 
        !          1715:          regno = REGNO (p->exp);
        !          1716:          endregno = regno + HARD_REGNO_NREGS (regno, GET_MODE (p->exp));
        !          1717: 
        !          1718:          for (i = regno; i < endregno; i++)
        !          1719:            if (TEST_HARD_REG_BIT (regs_invalidated_by_call, i))
        !          1720:              {
        !          1721:                remove_from_table (p, hash);
        !          1722:                break;
        !          1723:              }
        !          1724:        }
        !          1725: }
        !          1726: 
        !          1727: /* Given an expression X of type CONST,
        !          1728:    and ELT which is its table entry (or 0 if it
        !          1729:    is not in the hash table),
        !          1730:    return an alternate expression for X as a register plus integer.
        !          1731:    If none can be found, return 0.  */
        !          1732: 
        !          1733: static rtx
        !          1734: use_related_value (x, elt)
        !          1735:      rtx x;
        !          1736:      struct table_elt *elt;
        !          1737: {
        !          1738:   register struct table_elt *relt = 0;
        !          1739:   register struct table_elt *p, *q;
        !          1740:   HOST_WIDE_INT offset;
        !          1741: 
        !          1742:   /* First, is there anything related known?
        !          1743:      If we have a table element, we can tell from that.
        !          1744:      Otherwise, must look it up.  */
        !          1745: 
        !          1746:   if (elt != 0 && elt->related_value != 0)
        !          1747:     relt = elt;
        !          1748:   else if (elt == 0 && GET_CODE (x) == CONST)
        !          1749:     {
        !          1750:       rtx subexp = get_related_value (x);
        !          1751:       if (subexp != 0)
        !          1752:        relt = lookup (subexp,
        !          1753:                       safe_hash (subexp, GET_MODE (subexp)) % NBUCKETS,
        !          1754:                       GET_MODE (subexp));
        !          1755:     }
        !          1756: 
        !          1757:   if (relt == 0)
        !          1758:     return 0;
        !          1759: 
        !          1760:   /* Search all related table entries for one that has an
        !          1761:      equivalent register.  */
        !          1762: 
        !          1763:   p = relt;
        !          1764:   while (1)
        !          1765:     {
        !          1766:       /* This loop is strange in that it is executed in two different cases.
        !          1767:         The first is when X is already in the table.  Then it is searching
        !          1768:         the RELATED_VALUE list of X's class (RELT).  The second case is when
        !          1769:         X is not in the table.  Then RELT points to a class for the related
        !          1770:         value.
        !          1771: 
        !          1772:         Ensure that, whatever case we are in, that we ignore classes that have
        !          1773:         the same value as X.  */
        !          1774: 
        !          1775:       if (rtx_equal_p (x, p->exp))
        !          1776:        q = 0;
        !          1777:       else
        !          1778:        for (q = p->first_same_value; q; q = q->next_same_value)
        !          1779:          if (GET_CODE (q->exp) == REG)
        !          1780:            break;
        !          1781: 
        !          1782:       if (q)
        !          1783:        break;
        !          1784: 
        !          1785:       p = p->related_value;
        !          1786: 
        !          1787:       /* We went all the way around, so there is nothing to be found.
        !          1788:         Alternatively, perhaps RELT was in the table for some other reason
        !          1789:         and it has no related values recorded.  */
        !          1790:       if (p == relt || p == 0)
        !          1791:        break;
        !          1792:     }
        !          1793: 
        !          1794:   if (q == 0)
        !          1795:     return 0;
        !          1796: 
        !          1797:   offset = (get_integer_term (x) - get_integer_term (p->exp));
        !          1798:   /* Note: OFFSET may be 0 if P->xexp and X are related by commutativity.  */
        !          1799:   return plus_constant (q->exp, offset);
        !          1800: }
        !          1801: 
        !          1802: /* Hash an rtx.  We are careful to make sure the value is never negative.
        !          1803:    Equivalent registers hash identically.
        !          1804:    MODE is used in hashing for CONST_INTs only;
        !          1805:    otherwise the mode of X is used.
        !          1806: 
        !          1807:    Store 1 in do_not_record if any subexpression is volatile.
        !          1808: 
        !          1809:    Store 1 in hash_arg_in_memory if X contains a MEM rtx
        !          1810:    which does not have the RTX_UNCHANGING_P bit set.
        !          1811:    In this case, also store 1 in hash_arg_in_struct
        !          1812:    if there is a MEM rtx which has the MEM_IN_STRUCT_P bit set.
        !          1813: 
        !          1814:    Note that cse_insn knows that the hash code of a MEM expression
        !          1815:    is just (int) MEM plus the hash code of the address.  */
        !          1816: 
        !          1817: static int
        !          1818: canon_hash (x, mode)
        !          1819:      rtx x;
        !          1820:      enum machine_mode mode;
        !          1821: {
        !          1822:   register int i, j;
        !          1823:   register int hash = 0;
        !          1824:   register enum rtx_code code;
        !          1825:   register char *fmt;
        !          1826: 
        !          1827:   /* repeat is used to turn tail-recursion into iteration.  */
        !          1828:  repeat:
        !          1829:   if (x == 0)
        !          1830:     return hash;
        !          1831: 
        !          1832:   code = GET_CODE (x);
        !          1833:   switch (code)
        !          1834:     {
        !          1835:     case REG:
        !          1836:       {
        !          1837:        register int regno = REGNO (x);
        !          1838: 
        !          1839:        /* On some machines, we can't record any non-fixed hard register,
        !          1840:           because extending its life will cause reload problems.  We
        !          1841:           consider ap, fp, and sp to be fixed for this purpose.
        !          1842:           On all machines, we can't record any global registers. */
        !          1843: 
        !          1844:        if (regno < FIRST_PSEUDO_REGISTER
        !          1845:            && (global_regs[regno]
        !          1846: #ifdef SMALL_REGISTER_CLASSES
        !          1847:                || (! fixed_regs[regno]
        !          1848:                    && regno != FRAME_POINTER_REGNUM
        !          1849:                    && regno != HARD_FRAME_POINTER_REGNUM
        !          1850:                    && regno != ARG_POINTER_REGNUM
        !          1851:                    && regno != STACK_POINTER_REGNUM)
        !          1852: #endif
        !          1853:                ))
        !          1854:          {
        !          1855:            do_not_record = 1;
        !          1856:            return 0;
        !          1857:          }
        !          1858:        return hash + ((int) REG << 7) + reg_qty[regno];
        !          1859:       }
        !          1860: 
        !          1861:     case CONST_INT:
        !          1862:       hash += ((int) mode + ((int) CONST_INT << 7)
        !          1863:               + INTVAL (x) + (INTVAL (x) >> HASHBITS));
        !          1864:       return ((1 << HASHBITS) - 1) & hash;
        !          1865: 
        !          1866:     case CONST_DOUBLE:
        !          1867:       /* This is like the general case, except that it only counts
        !          1868:         the integers representing the constant.  */
        !          1869:       hash += (int) code + (int) GET_MODE (x);
        !          1870:       {
        !          1871:        int i;
        !          1872:        for (i = 2; i < GET_RTX_LENGTH (CONST_DOUBLE); i++)
        !          1873:          {
        !          1874:            int tem = XINT (x, i);
        !          1875:            hash += ((1 << HASHBITS) - 1) & (tem + (tem >> HASHBITS));
        !          1876:          }
        !          1877:       }
        !          1878:       return hash;
        !          1879: 
        !          1880:       /* Assume there is only one rtx object for any given label.  */
        !          1881:     case LABEL_REF:
        !          1882:       /* Use `and' to ensure a positive number.  */
        !          1883:       return (hash + ((HOST_WIDE_INT) LABEL_REF << 7)
        !          1884:              + ((HOST_WIDE_INT) XEXP (x, 0) & ((1 << HASHBITS) - 1)));
        !          1885: 
        !          1886:     case SYMBOL_REF:
        !          1887:       return (hash + ((HOST_WIDE_INT) SYMBOL_REF << 7)
        !          1888:              + ((HOST_WIDE_INT) XEXP (x, 0) & ((1 << HASHBITS) - 1)));
        !          1889: 
        !          1890:     case MEM:
        !          1891:       if (MEM_VOLATILE_P (x))
        !          1892:        {
        !          1893:          do_not_record = 1;
        !          1894:          return 0;
        !          1895:        }
        !          1896:       if (! RTX_UNCHANGING_P (x))
        !          1897:        {
        !          1898:          hash_arg_in_memory = 1;
        !          1899:          if (MEM_IN_STRUCT_P (x)) hash_arg_in_struct = 1;
        !          1900:        }
        !          1901:       /* Now that we have already found this special case,
        !          1902:         might as well speed it up as much as possible.  */
        !          1903:       hash += (int) MEM;
        !          1904:       x = XEXP (x, 0);
        !          1905:       goto repeat;
        !          1906: 
        !          1907:     case PRE_DEC:
        !          1908:     case PRE_INC:
        !          1909:     case POST_DEC:
        !          1910:     case POST_INC:
        !          1911:     case PC:
        !          1912:     case CC0:
        !          1913:     case CALL:
        !          1914:     case UNSPEC_VOLATILE:
        !          1915:       do_not_record = 1;
        !          1916:       return 0;
        !          1917: 
        !          1918:     case ASM_OPERANDS:
        !          1919:       if (MEM_VOLATILE_P (x))
        !          1920:        {
        !          1921:          do_not_record = 1;
        !          1922:          return 0;
        !          1923:        }
        !          1924:     }
        !          1925: 
        !          1926:   i = GET_RTX_LENGTH (code) - 1;
        !          1927:   hash += (int) code + (int) GET_MODE (x);
        !          1928:   fmt = GET_RTX_FORMAT (code);
        !          1929:   for (; i >= 0; i--)
        !          1930:     {
        !          1931:       if (fmt[i] == 'e')
        !          1932:        {
        !          1933:          rtx tem = XEXP (x, i);
        !          1934:          rtx tem1;
        !          1935: 
        !          1936:          /* If the operand is a REG that is equivalent to a constant, hash
        !          1937:             as if we were hashing the constant, since we will be comparing
        !          1938:             that way.  */
        !          1939:          if (tem != 0 && GET_CODE (tem) == REG
        !          1940:              && REGNO_QTY_VALID_P (REGNO (tem))
        !          1941:              && qty_mode[reg_qty[REGNO (tem)]] == GET_MODE (tem)
        !          1942:              && (tem1 = qty_const[reg_qty[REGNO (tem)]]) != 0
        !          1943:              && CONSTANT_P (tem1))
        !          1944:            tem = tem1;
        !          1945: 
        !          1946:          /* If we are about to do the last recursive call
        !          1947:             needed at this level, change it into iteration.
        !          1948:             This function  is called enough to be worth it.  */
        !          1949:          if (i == 0)
        !          1950:            {
        !          1951:              x = tem;
        !          1952:              goto repeat;
        !          1953:            }
        !          1954:          hash += canon_hash (tem, 0);
        !          1955:        }
        !          1956:       else if (fmt[i] == 'E')
        !          1957:        for (j = 0; j < XVECLEN (x, i); j++)
        !          1958:          hash += canon_hash (XVECEXP (x, i, j), 0);
        !          1959:       else if (fmt[i] == 's')
        !          1960:        {
        !          1961:          register char *p = XSTR (x, i);
        !          1962:          if (p)
        !          1963:            while (*p)
        !          1964:              {
        !          1965:                register int tem = *p++;
        !          1966:                hash += ((1 << HASHBITS) - 1) & (tem + (tem >> HASHBITS));
        !          1967:              }
        !          1968:        }
        !          1969:       else if (fmt[i] == 'i')
        !          1970:        {
        !          1971:          register int tem = XINT (x, i);
        !          1972:          hash += ((1 << HASHBITS) - 1) & (tem + (tem >> HASHBITS));
        !          1973:        }
        !          1974:       else
        !          1975:        abort ();
        !          1976:     }
        !          1977:   return hash;
        !          1978: }
        !          1979: 
        !          1980: /* Like canon_hash but with no side effects.  */
        !          1981: 
        !          1982: static int
        !          1983: safe_hash (x, mode)
        !          1984:      rtx x;
        !          1985:      enum machine_mode mode;
        !          1986: {
        !          1987:   int save_do_not_record = do_not_record;
        !          1988:   int save_hash_arg_in_memory = hash_arg_in_memory;
        !          1989:   int save_hash_arg_in_struct = hash_arg_in_struct;
        !          1990:   int hash = canon_hash (x, mode);
        !          1991:   hash_arg_in_memory = save_hash_arg_in_memory;
        !          1992:   hash_arg_in_struct = save_hash_arg_in_struct;
        !          1993:   do_not_record = save_do_not_record;
        !          1994:   return hash;
        !          1995: }
        !          1996: 
        !          1997: /* Return 1 iff X and Y would canonicalize into the same thing,
        !          1998:    without actually constructing the canonicalization of either one.
        !          1999:    If VALIDATE is nonzero,
        !          2000:    we assume X is an expression being processed from the rtl
        !          2001:    and Y was found in the hash table.  We check register refs
        !          2002:    in Y for being marked as valid.
        !          2003: 
        !          2004:    If EQUAL_VALUES is nonzero, we allow a register to match a constant value
        !          2005:    that is known to be in the register.  Ordinarily, we don't allow them
        !          2006:    to match, because letting them match would cause unpredictable results
        !          2007:    in all the places that search a hash table chain for an equivalent
        !          2008:    for a given value.  A possible equivalent that has different structure
        !          2009:    has its hash code computed from different data.  Whether the hash code
        !          2010:    is the same as that of the the given value is pure luck.  */
        !          2011: 
        !          2012: static int
        !          2013: exp_equiv_p (x, y, validate, equal_values)
        !          2014:      rtx x, y;
        !          2015:      int validate;
        !          2016:      int equal_values;
        !          2017: {
        !          2018:   register int i, j;
        !          2019:   register enum rtx_code code;
        !          2020:   register char *fmt;
        !          2021: 
        !          2022:   /* Note: it is incorrect to assume an expression is equivalent to itself
        !          2023:      if VALIDATE is nonzero.  */
        !          2024:   if (x == y && !validate)
        !          2025:     return 1;
        !          2026:   if (x == 0 || y == 0)
        !          2027:     return x == y;
        !          2028: 
        !          2029:   code = GET_CODE (x);
        !          2030:   if (code != GET_CODE (y))
        !          2031:     {
        !          2032:       if (!equal_values)
        !          2033:        return 0;
        !          2034: 
        !          2035:       /* If X is a constant and Y is a register or vice versa, they may be
        !          2036:         equivalent.  We only have to validate if Y is a register.  */
        !          2037:       if (CONSTANT_P (x) && GET_CODE (y) == REG
        !          2038:          && REGNO_QTY_VALID_P (REGNO (y))
        !          2039:          && GET_MODE (y) == qty_mode[reg_qty[REGNO (y)]]
        !          2040:          && rtx_equal_p (x, qty_const[reg_qty[REGNO (y)]])
        !          2041:          && (! validate || reg_in_table[REGNO (y)] == reg_tick[REGNO (y)]))
        !          2042:        return 1;
        !          2043: 
        !          2044:       if (CONSTANT_P (y) && code == REG
        !          2045:          && REGNO_QTY_VALID_P (REGNO (x))
        !          2046:          && GET_MODE (x) == qty_mode[reg_qty[REGNO (x)]]
        !          2047:          && rtx_equal_p (y, qty_const[reg_qty[REGNO (x)]]))
        !          2048:        return 1;
        !          2049: 
        !          2050:       return 0;
        !          2051:     }
        !          2052: 
        !          2053:   /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent.  */
        !          2054:   if (GET_MODE (x) != GET_MODE (y))
        !          2055:     return 0;
        !          2056: 
        !          2057:   switch (code)
        !          2058:     {
        !          2059:     case PC:
        !          2060:     case CC0:
        !          2061:       return x == y;
        !          2062: 
        !          2063:     case CONST_INT:
        !          2064:       return INTVAL (x) == INTVAL (y);
        !          2065: 
        !          2066:     case LABEL_REF:
        !          2067:     case SYMBOL_REF:
        !          2068:       return XEXP (x, 0) == XEXP (y, 0);
        !          2069: 
        !          2070:     case REG:
        !          2071:       {
        !          2072:        int regno = REGNO (y);
        !          2073:        int endregno
        !          2074:          = regno + (regno >= FIRST_PSEUDO_REGISTER ? 1
        !          2075:                     : HARD_REGNO_NREGS (regno, GET_MODE (y)));
        !          2076:        int i;
        !          2077: 
        !          2078:        /* If the quantities are not the same, the expressions are not
        !          2079:           equivalent.  If there are and we are not to validate, they
        !          2080:           are equivalent.  Otherwise, ensure all regs are up-to-date.  */
        !          2081: 
        !          2082:        if (reg_qty[REGNO (x)] != reg_qty[regno])
        !          2083:          return 0;
        !          2084: 
        !          2085:        if (! validate)
        !          2086:          return 1;
        !          2087: 
        !          2088:        for (i = regno; i < endregno; i++)
        !          2089:          if (reg_in_table[i] != reg_tick[i])
        !          2090:            return 0;
        !          2091: 
        !          2092:        return 1;
        !          2093:       }
        !          2094: 
        !          2095:     /*  For commutative operations, check both orders.  */
        !          2096:     case PLUS:
        !          2097:     case MULT:
        !          2098:     case AND:
        !          2099:     case IOR:
        !          2100:     case XOR:
        !          2101:     case NE:
        !          2102:     case EQ:
        !          2103:       return ((exp_equiv_p (XEXP (x, 0), XEXP (y, 0), validate, equal_values)
        !          2104:               && exp_equiv_p (XEXP (x, 1), XEXP (y, 1),
        !          2105:                               validate, equal_values))
        !          2106:              || (exp_equiv_p (XEXP (x, 0), XEXP (y, 1),
        !          2107:                               validate, equal_values)
        !          2108:                  && exp_equiv_p (XEXP (x, 1), XEXP (y, 0),
        !          2109:                                  validate, equal_values)));
        !          2110:     }
        !          2111: 
        !          2112:   /* Compare the elements.  If any pair of corresponding elements
        !          2113:      fail to match, return 0 for the whole things.  */
        !          2114: 
        !          2115:   fmt = GET_RTX_FORMAT (code);
        !          2116:   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
        !          2117:     {
        !          2118:       switch (fmt[i])
        !          2119:        {
        !          2120:        case 'e':
        !          2121:          if (! exp_equiv_p (XEXP (x, i), XEXP (y, i), validate, equal_values))
        !          2122:            return 0;
        !          2123:          break;
        !          2124: 
        !          2125:        case 'E':
        !          2126:          if (XVECLEN (x, i) != XVECLEN (y, i))
        !          2127:            return 0;
        !          2128:          for (j = 0; j < XVECLEN (x, i); j++)
        !          2129:            if (! exp_equiv_p (XVECEXP (x, i, j), XVECEXP (y, i, j),
        !          2130:                               validate, equal_values))
        !          2131:              return 0;
        !          2132:          break;
        !          2133: 
        !          2134:        case 's':
        !          2135:          if (strcmp (XSTR (x, i), XSTR (y, i)))
        !          2136:            return 0;
        !          2137:          break;
        !          2138: 
        !          2139:        case 'i':
        !          2140:          if (XINT (x, i) != XINT (y, i))
        !          2141:            return 0;
        !          2142:          break;
        !          2143: 
        !          2144:        case 'w':
        !          2145:          if (XWINT (x, i) != XWINT (y, i))
        !          2146:            return 0;
        !          2147:        break;
        !          2148: 
        !          2149:        case '0':
        !          2150:          break;
        !          2151: 
        !          2152:        default:
        !          2153:          abort ();
        !          2154:        }
        !          2155:       }
        !          2156: 
        !          2157:   return 1;
        !          2158: }
        !          2159: 
        !          2160: /* Return 1 iff any subexpression of X matches Y.
        !          2161:    Here we do not require that X or Y be valid (for registers referred to)
        !          2162:    for being in the hash table.  */
        !          2163: 
        !          2164: static int
        !          2165: refers_to_p (x, y)
        !          2166:      rtx x, y;
        !          2167: {
        !          2168:   register int i;
        !          2169:   register enum rtx_code code;
        !          2170:   register char *fmt;
        !          2171: 
        !          2172:  repeat:
        !          2173:   if (x == y)
        !          2174:     return 1;
        !          2175:   if (x == 0 || y == 0)
        !          2176:     return 0;
        !          2177: 
        !          2178:   code = GET_CODE (x);
        !          2179:   /* If X as a whole has the same code as Y, they may match.
        !          2180:      If so, return 1.  */
        !          2181:   if (code == GET_CODE (y))
        !          2182:     {
        !          2183:       if (exp_equiv_p (x, y, 0, 1))
        !          2184:        return 1;
        !          2185:     }
        !          2186: 
        !          2187:   /* X does not match, so try its subexpressions.  */
        !          2188: 
        !          2189:   fmt = GET_RTX_FORMAT (code);
        !          2190:   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
        !          2191:     if (fmt[i] == 'e')
        !          2192:       {
        !          2193:        if (i == 0)
        !          2194:          {
        !          2195:            x = XEXP (x, 0);
        !          2196:            goto repeat;
        !          2197:          }
        !          2198:        else
        !          2199:          if (refers_to_p (XEXP (x, i), y))
        !          2200:            return 1;
        !          2201:       }
        !          2202:     else if (fmt[i] == 'E')
        !          2203:       {
        !          2204:        int j;
        !          2205:        for (j = 0; j < XVECLEN (x, i); j++)
        !          2206:          if (refers_to_p (XVECEXP (x, i, j), y))
        !          2207:            return 1;
        !          2208:       }
        !          2209: 
        !          2210:   return 0;
        !          2211: }
        !          2212: 
        !          2213: /* Given ADDR and SIZE (a memory address, and the size of the memory reference),
        !          2214:    set PBASE, PSTART, and PEND which correspond to the base of the address,
        !          2215:    the starting offset, and ending offset respectively.
        !          2216: 
        !          2217:    ADDR is known to be a nonvarying address. 
        !          2218: 
        !          2219:    cse_address_varies_p returns zero for nonvarying addresses.  */
        !          2220: 
        !          2221: static void
        !          2222: set_nonvarying_address_components (addr, size, pbase, pstart, pend)
        !          2223:      rtx addr;
        !          2224:      int size;
        !          2225:      rtx *pbase;
        !          2226:      HOST_WIDE_INT *pstart, *pend;
        !          2227: {
        !          2228:   rtx base;
        !          2229:   int start, end;
        !          2230: 
        !          2231:   base = addr;
        !          2232:   start = 0;
        !          2233:   end = 0;
        !          2234: 
        !          2235:   /* Registers with nonvarying addresses usually have constant equivalents;
        !          2236:      but the frame pointer register is also possible.  */
        !          2237:   if (GET_CODE (base) == REG
        !          2238:       && qty_const != 0
        !          2239:       && REGNO_QTY_VALID_P (REGNO (base))
        !          2240:       && qty_mode[reg_qty[REGNO (base)]] == GET_MODE (base)
        !          2241:       && qty_const[reg_qty[REGNO (base)]] != 0)
        !          2242:     base = qty_const[reg_qty[REGNO (base)]];
        !          2243:   else if (GET_CODE (base) == PLUS
        !          2244:           && GET_CODE (XEXP (base, 1)) == CONST_INT
        !          2245:           && GET_CODE (XEXP (base, 0)) == REG
        !          2246:           && qty_const != 0
        !          2247:           && REGNO_QTY_VALID_P (REGNO (XEXP (base, 0)))
        !          2248:           && (qty_mode[reg_qty[REGNO (XEXP (base, 0))]]
        !          2249:               == GET_MODE (XEXP (base, 0)))
        !          2250:           && qty_const[reg_qty[REGNO (XEXP (base, 0))]])
        !          2251:     {
        !          2252:       start = INTVAL (XEXP (base, 1));
        !          2253:       base = qty_const[reg_qty[REGNO (XEXP (base, 0))]];
        !          2254:     }
        !          2255: 
        !          2256:   /* By definition, operand1 of a LO_SUM is the associated constant
        !          2257:      address.  Use the associated constant address as the base instead.  */
        !          2258:   if (GET_CODE (base) == LO_SUM)
        !          2259:     base = XEXP (base, 1);
        !          2260: 
        !          2261:   /* Strip off CONST.  */
        !          2262:   if (GET_CODE (base) == CONST)
        !          2263:     base = XEXP (base, 0);
        !          2264: 
        !          2265:   if (GET_CODE (base) == PLUS
        !          2266:       && GET_CODE (XEXP (base, 1)) == CONST_INT)
        !          2267:     {
        !          2268:       start += INTVAL (XEXP (base, 1));
        !          2269:       base = XEXP (base, 0);
        !          2270:     }
        !          2271: 
        !          2272:   end = start + size;
        !          2273: 
        !          2274:   /* Set the return values.  */
        !          2275:   *pbase = base;
        !          2276:   *pstart = start;
        !          2277:   *pend = end;
        !          2278: }
        !          2279: 
        !          2280: /* Return 1 iff any subexpression of X refers to memory
        !          2281:    at an address of BASE plus some offset
        !          2282:    such that any of the bytes' offsets fall between START (inclusive)
        !          2283:    and END (exclusive).
        !          2284: 
        !          2285:    The value is undefined if X is a varying address (as determined by
        !          2286:    cse_rtx_addr_varies_p).  This function is not used in such cases.
        !          2287: 
        !          2288:    When used in the cse pass, `qty_const' is nonzero, and it is used
        !          2289:    to treat an address that is a register with a known constant value
        !          2290:    as if it were that constant value.
        !          2291:    In the loop pass, `qty_const' is zero, so this is not done.  */
        !          2292: 
        !          2293: static int
        !          2294: refers_to_mem_p (x, base, start, end)
        !          2295:      rtx x, base;
        !          2296:      HOST_WIDE_INT start, end;
        !          2297: {
        !          2298:   register HOST_WIDE_INT i;
        !          2299:   register enum rtx_code code;
        !          2300:   register char *fmt;
        !          2301: 
        !          2302:   if (GET_CODE (base) == CONST_INT)
        !          2303:     {
        !          2304:       start += INTVAL (base);
        !          2305:       end += INTVAL (base);
        !          2306:       base = const0_rtx;
        !          2307:     }
        !          2308: 
        !          2309:  repeat:
        !          2310:   if (x == 0)
        !          2311:     return 0;
        !          2312: 
        !          2313:   code = GET_CODE (x);
        !          2314:   if (code == MEM)
        !          2315:     {
        !          2316:       register rtx addr = XEXP (x, 0); /* Get the address.  */
        !          2317:       rtx mybase;
        !          2318:       HOST_WIDE_INT mystart, myend;
        !          2319: 
        !          2320:       set_nonvarying_address_components (addr, GET_MODE_SIZE (GET_MODE (x)),
        !          2321:                                         &mybase, &mystart, &myend);
        !          2322: 
        !          2323: 
        !          2324:       /* refers_to_mem_p is never called with varying addresses. 
        !          2325:         If the base addresses are not equal, there is no chance
        !          2326:         of the memory addresses conflicting.  */
        !          2327:       if (! rtx_equal_p (mybase, base))
        !          2328:        return 0;
        !          2329: 
        !          2330:       return myend > start && mystart < end;
        !          2331:     }
        !          2332: 
        !          2333: #ifdef MACHO_PIC
        !          2334:   if (code == PLUS && XEXP (x, 0) == pic_offset_table_rtx)
        !          2335:     {
        !          2336:       x = XEXP (XEXP (XEXP (x, 1), 0), 0);
        !          2337:       goto repeat;
        !          2338:     }
        !          2339: #endif
        !          2340: 
        !          2341:   /* X does not match, so try its subexpressions.  */
        !          2342: 
        !          2343:   fmt = GET_RTX_FORMAT (code);
        !          2344:   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
        !          2345:     if (fmt[i] == 'e')
        !          2346:       {
        !          2347:        if (i == 0)
        !          2348:          {
        !          2349:            x = XEXP (x, 0);
        !          2350:            goto repeat;
        !          2351:          }
        !          2352:        else
        !          2353:          if (refers_to_mem_p (XEXP (x, i), base, start, end))
        !          2354:            return 1;
        !          2355:       }
        !          2356:     else if (fmt[i] == 'E')
        !          2357:       {
        !          2358:        int j;
        !          2359:        for (j = 0; j < XVECLEN (x, i); j++)
        !          2360:          if (refers_to_mem_p (XVECEXP (x, i, j), base, start, end))
        !          2361:            return 1;
        !          2362:       }
        !          2363: 
        !          2364:   return 0;
        !          2365: }
        !          2366: 
        !          2367: /* Nonzero if X refers to memory at a varying address;
        !          2368:    except that a register which has at the moment a known constant value
        !          2369:    isn't considered variable.  */
        !          2370: 
        !          2371: static int
        !          2372: cse_rtx_addr_varies_p (x)
        !          2373:      rtx x;
        !          2374: {
        !          2375:   /* We need not check for X and the equivalence class being of the same
        !          2376:      mode because if X is equivalent to a constant in some mode, it
        !          2377:      doesn't vary in any mode.  */
        !          2378: 
        !          2379:   if (GET_CODE (x) == MEM
        !          2380:       && GET_CODE (XEXP (x, 0)) == REG
        !          2381:       && REGNO_QTY_VALID_P (REGNO (XEXP (x, 0)))
        !          2382:       && GET_MODE (XEXP (x, 0)) == qty_mode[reg_qty[REGNO (XEXP (x, 0))]]
        !          2383:       && qty_const[reg_qty[REGNO (XEXP (x, 0))]] != 0)
        !          2384:     return 0;
        !          2385: 
        !          2386:   if (GET_CODE (x) == MEM
        !          2387:       && GET_CODE (XEXP (x, 0)) == PLUS
        !          2388:       && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
        !          2389:       && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
        !          2390:       && REGNO_QTY_VALID_P (REGNO (XEXP (XEXP (x, 0), 0)))
        !          2391:       && (GET_MODE (XEXP (XEXP (x, 0), 0))
        !          2392:          == qty_mode[reg_qty[REGNO (XEXP (XEXP (x, 0), 0))]])
        !          2393:       && qty_const[reg_qty[REGNO (XEXP (XEXP (x, 0), 0))]])
        !          2394:     return 0;
        !          2395: 
        !          2396:   return rtx_addr_varies_p (x);
        !          2397: }
        !          2398: 
        !          2399: /* Canonicalize an expression:
        !          2400:    replace each register reference inside it
        !          2401:    with the "oldest" equivalent register.
        !          2402: 
        !          2403:    If INSN is non-zero and we are replacing a pseudo with a hard register
        !          2404:    or vice versa, validate_change is used to ensure that INSN remains valid
        !          2405:    after we make our substitution.  The calls are made with IN_GROUP non-zero
        !          2406:    so apply_change_group must be called upon the outermost return from this
        !          2407:    function (unless INSN is zero).  The result of apply_change_group can
        !          2408:    generally be discarded since the changes we are making are optional.  */
        !          2409: 
        !          2410: static rtx
        !          2411: canon_reg (x, insn)
        !          2412:      rtx x;
        !          2413:      rtx insn;
        !          2414: {
        !          2415:   register int i;
        !          2416:   register enum rtx_code code;
        !          2417:   register char *fmt;
        !          2418: 
        !          2419:   if (x == 0)
        !          2420:     return x;
        !          2421: 
        !          2422:   code = GET_CODE (x);
        !          2423:   switch (code)
        !          2424:     {
        !          2425:     case PC:
        !          2426:     case CC0:
        !          2427:     case CONST:
        !          2428:     case CONST_INT:
        !          2429:     case CONST_DOUBLE:
        !          2430:     case SYMBOL_REF:
        !          2431:     case LABEL_REF:
        !          2432:     case ADDR_VEC:
        !          2433:     case ADDR_DIFF_VEC:
        !          2434:       return x;
        !          2435: 
        !          2436:     case REG:
        !          2437:       {
        !          2438:        register int first;
        !          2439: 
        !          2440:        /* Never replace a hard reg, because hard regs can appear
        !          2441:           in more than one machine mode, and we must preserve the mode
        !          2442:           of each occurrence.  Also, some hard regs appear in
        !          2443:           MEMs that are shared and mustn't be altered.  Don't try to
        !          2444:           replace any reg that maps to a reg of class NO_REGS.  */
        !          2445:        if (REGNO (x) < FIRST_PSEUDO_REGISTER
        !          2446:            || ! REGNO_QTY_VALID_P (REGNO (x)))
        !          2447:          return x;
        !          2448: 
        !          2449:        first = qty_first_reg[reg_qty[REGNO (x)]];
        !          2450:        return (first >= FIRST_PSEUDO_REGISTER ? regno_reg_rtx[first]
        !          2451:                : REGNO_REG_CLASS (first) == NO_REGS ? x
        !          2452:                : gen_rtx (REG, qty_mode[reg_qty[REGNO (x)]], first));
        !          2453:       }
        !          2454:     }
        !          2455: 
        !          2456:   fmt = GET_RTX_FORMAT (code);
        !          2457:   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
        !          2458:     {
        !          2459:       register int j;
        !          2460: 
        !          2461:       if (fmt[i] == 'e')
        !          2462:        {
        !          2463:          rtx new = canon_reg (XEXP (x, i), insn);
        !          2464: 
        !          2465:          /* If replacing pseudo with hard reg or vice versa, ensure the
        !          2466:             insn remains valid.  Likewise if the insn has MATCH_DUPs.  */
        !          2467:          if (insn != 0 && new != 0
        !          2468:              && GET_CODE (new) == REG && GET_CODE (XEXP (x, i)) == REG
        !          2469:              && (((REGNO (new) < FIRST_PSEUDO_REGISTER)
        !          2470:                   != (REGNO (XEXP (x, i)) < FIRST_PSEUDO_REGISTER))
        !          2471:                  || insn_n_dups[recog_memoized (insn)] > 0))
        !          2472:            validate_change (insn, &XEXP (x, i), new, 1);
        !          2473:          else
        !          2474:            XEXP (x, i) = new;
        !          2475:        }
        !          2476:       else if (fmt[i] == 'E')
        !          2477:        for (j = 0; j < XVECLEN (x, i); j++)
        !          2478:          XVECEXP (x, i, j) = canon_reg (XVECEXP (x, i, j), insn);
        !          2479:     }
        !          2480: 
        !          2481:   return x;
        !          2482: }
        !          2483: 
        !          2484: /* LOC is a location with INSN that is an operand address (the contents of
        !          2485:    a MEM).  Find the best equivalent address to use that is valid for this
        !          2486:    insn.
        !          2487: 
        !          2488:    On most CISC machines, complicated address modes are costly, and rtx_cost
        !          2489:    is a good approximation for that cost.  However, most RISC machines have
        !          2490:    only a few (usually only one) memory reference formats.  If an address is
        !          2491:    valid at all, it is often just as cheap as any other address.  Hence, for
        !          2492:    RISC machines, we use the configuration macro `ADDRESS_COST' to compare the
        !          2493:    costs of various addresses.  For two addresses of equal cost, choose the one
        !          2494:    with the highest `rtx_cost' value as that has the potential of eliminating
        !          2495:    the most insns.  For equal costs, we choose the first in the equivalence
        !          2496:    class.  Note that we ignore the fact that pseudo registers are cheaper
        !          2497:    than hard registers here because we would also prefer the pseudo registers.
        !          2498:   */
        !          2499: 
        !          2500: static void
        !          2501: find_best_addr (insn, loc)
        !          2502:      rtx insn;
        !          2503:      rtx *loc;
        !          2504: {
        !          2505:   struct table_elt *elt, *p;
        !          2506:   rtx addr = *loc;
        !          2507:   int our_cost;
        !          2508:   int found_better = 1;
        !          2509:   int save_do_not_record = do_not_record;
        !          2510:   int save_hash_arg_in_memory = hash_arg_in_memory;
        !          2511:   int save_hash_arg_in_struct = hash_arg_in_struct;
        !          2512:   int hash_code;
        !          2513:   int addr_volatile;
        !          2514:   int regno;
        !          2515: 
        !          2516:   /* Do not try to replace constant addresses or addresses of local and
        !          2517:      argument slots.  These MEM expressions are made only once and inserted
        !          2518:      in many instructions, as well as being used to control symbol table
        !          2519:      output.  It is not safe to clobber them.
        !          2520: 
        !          2521:      There are some uncommon cases where the address is already in a register
        !          2522:      for some reason, but we cannot take advantage of that because we have
        !          2523:      no easy way to unshare the MEM.  In addition, looking up all stack
        !          2524:      addresses is costly.  */
        !          2525:   if ((GET_CODE (addr) == PLUS
        !          2526:        && GET_CODE (XEXP (addr, 0)) == REG
        !          2527:        && GET_CODE (XEXP (addr, 1)) == CONST_INT
        !          2528:        && (regno = REGNO (XEXP (addr, 0)),
        !          2529:           regno == FRAME_POINTER_REGNUM || regno == HARD_FRAME_POINTER_REGNUM
        !          2530:           || regno == ARG_POINTER_REGNUM))
        !          2531:       || (GET_CODE (addr) == REG
        !          2532:          && (regno = REGNO (addr), regno == FRAME_POINTER_REGNUM
        !          2533:              || regno == HARD_FRAME_POINTER_REGNUM
        !          2534:              || regno == ARG_POINTER_REGNUM))
        !          2535:       || CONSTANT_ADDRESS_P (addr))
        !          2536:     return;
        !          2537: 
        !          2538:   /* If this address is not simply a register, try to fold it.  This will
        !          2539:      sometimes simplify the expression.  Many simplifications
        !          2540:      will not be valid, but some, usually applying the associative rule, will
        !          2541:      be valid and produce better code.  */
        !          2542:   if (GET_CODE (addr) != REG
        !          2543:       && validate_change (insn, loc, fold_rtx (addr, insn), 0))
        !          2544:     addr = *loc;
        !          2545:        
        !          2546:   /* If this address is not in the hash table, we can't look for equivalences
        !          2547:      of the whole address.  Also, ignore if volatile.  */
        !          2548: 
        !          2549:   do_not_record = 0;
        !          2550:   hash_code = HASH (addr, Pmode);
        !          2551:   addr_volatile = do_not_record;
        !          2552:   do_not_record = save_do_not_record;
        !          2553:   hash_arg_in_memory = save_hash_arg_in_memory;
        !          2554:   hash_arg_in_struct = save_hash_arg_in_struct;
        !          2555: 
        !          2556:   if (addr_volatile)
        !          2557:     return;
        !          2558: 
        !          2559:   elt = lookup (addr, hash_code, Pmode);
        !          2560: 
        !          2561: #ifndef ADDRESS_COST
        !          2562:   if (elt)
        !          2563:     {
        !          2564:       our_cost = elt->cost;
        !          2565: 
        !          2566:       /* Find the lowest cost below ours that works.  */
        !          2567:       for (elt = elt->first_same_value; elt; elt = elt->next_same_value)
        !          2568:        if (elt->cost < our_cost
        !          2569:            && (GET_CODE (elt->exp) == REG
        !          2570:                || exp_equiv_p (elt->exp, elt->exp, 1, 0))
        !          2571:            && validate_change (insn, loc,
        !          2572:                                canon_reg (copy_rtx (elt->exp), NULL_RTX), 0))
        !          2573:          return;
        !          2574:     }
        !          2575: #else
        !          2576: 
        !          2577:   if (elt)
        !          2578:     {
        !          2579:       /* We need to find the best (under the criteria documented above) entry
        !          2580:         in the class that is valid.  We use the `flag' field to indicate
        !          2581:         choices that were invalid and iterate until we can't find a better
        !          2582:         one that hasn't already been tried.  */
        !          2583: 
        !          2584:       for (p = elt->first_same_value; p; p = p->next_same_value)
        !          2585:        p->flag = 0;
        !          2586: 
        !          2587:       while (found_better)
        !          2588:        {
        !          2589:          int best_addr_cost = ADDRESS_COST (*loc);
        !          2590:          int best_rtx_cost = (elt->cost + 1) >> 1;
        !          2591:          struct table_elt *best_elt = elt; 
        !          2592: 
        !          2593:          found_better = 0;
        !          2594:          for (p = elt->first_same_value; p; p = p->next_same_value)
        !          2595:            if (! p->flag
        !          2596:                && (GET_CODE (p->exp) == REG
        !          2597:                    || exp_equiv_p (p->exp, p->exp, 1, 0))
        !          2598:                && (ADDRESS_COST (p->exp) < best_addr_cost
        !          2599:                    || (ADDRESS_COST (p->exp) == best_addr_cost
        !          2600:                        && (p->cost + 1) >> 1 > best_rtx_cost)))
        !          2601:              {
        !          2602:                found_better = 1;
        !          2603:                best_addr_cost = ADDRESS_COST (p->exp);
        !          2604:                best_rtx_cost = (p->cost + 1) >> 1;
        !          2605:                best_elt = p;
        !          2606:              }
        !          2607: 
        !          2608:          if (found_better)
        !          2609:            {
        !          2610:              if (validate_change (insn, loc,
        !          2611:                                   canon_reg (copy_rtx (best_elt->exp),
        !          2612:                                              NULL_RTX), 0))
        !          2613:                return;
        !          2614:              else
        !          2615:                best_elt->flag = 1;
        !          2616:            }
        !          2617:        }
        !          2618:     }
        !          2619: 
        !          2620:   /* If the address is a binary operation with the first operand a register
        !          2621:      and the second a constant, do the same as above, but looking for
        !          2622:      equivalences of the register.  Then try to simplify before checking for
        !          2623:      the best address to use.  This catches a few cases:  First is when we
        !          2624:      have REG+const and the register is another REG+const.  We can often merge
        !          2625:      the constants and eliminate one insn and one register.  It may also be
        !          2626:      that a machine has a cheap REG+REG+const.  Finally, this improves the
        !          2627:      code on the Alpha for unaligned byte stores.  */
        !          2628: 
        !          2629:   if (flag_expensive_optimizations
        !          2630:       && (GET_RTX_CLASS (GET_CODE (*loc)) == '2'
        !          2631:          || GET_RTX_CLASS (GET_CODE (*loc)) == 'c')
        !          2632:       && GET_CODE (XEXP (*loc, 0)) == REG
        !          2633:       && GET_CODE (XEXP (*loc, 1)) == CONST_INT)
        !          2634:     {
        !          2635:       rtx c = XEXP (*loc, 1);
        !          2636: 
        !          2637:       do_not_record = 0;
        !          2638:       hash_code = HASH (XEXP (*loc, 0), Pmode);
        !          2639:       do_not_record = save_do_not_record;
        !          2640:       hash_arg_in_memory = save_hash_arg_in_memory;
        !          2641:       hash_arg_in_struct = save_hash_arg_in_struct;
        !          2642: 
        !          2643:       elt = lookup (XEXP (*loc, 0), hash_code, Pmode);
        !          2644:       if (elt == 0)
        !          2645:        return;
        !          2646: 
        !          2647:       /* We need to find the best (under the criteria documented above) entry
        !          2648:         in the class that is valid.  We use the `flag' field to indicate
        !          2649:         choices that were invalid and iterate until we can't find a better
        !          2650:         one that hasn't already been tried.  */
        !          2651: 
        !          2652:       for (p = elt->first_same_value; p; p = p->next_same_value)
        !          2653:        p->flag = 0;
        !          2654: 
        !          2655:       while (found_better)
        !          2656:        {
        !          2657:          int best_addr_cost = ADDRESS_COST (*loc);
        !          2658:          int best_rtx_cost = (COST (*loc) + 1) >> 1;
        !          2659:          struct table_elt *best_elt = elt; 
        !          2660:          rtx best_rtx = *loc;
        !          2661: 
        !          2662:          found_better = 0;
        !          2663:          for (p = elt->first_same_value; p; p = p->next_same_value)
        !          2664:            if (! p->flag
        !          2665:                && (GET_CODE (p->exp) == REG
        !          2666:                    || exp_equiv_p (p->exp, p->exp, 1, 0)))
        !          2667:              {
        !          2668:                rtx new = cse_gen_binary (GET_CODE (*loc), Pmode, p->exp, c);
        !          2669: 
        !          2670:                if ((ADDRESS_COST (new) < best_addr_cost
        !          2671:                    || (ADDRESS_COST (new) == best_addr_cost
        !          2672:                        && (COST (new) + 1) >> 1 > best_rtx_cost)))
        !          2673:                  {
        !          2674:                    found_better = 1;
        !          2675:                    best_addr_cost = ADDRESS_COST (new);
        !          2676:                    best_rtx_cost = (COST (new) + 1) >> 1;
        !          2677:                    best_elt = p;
        !          2678:                    best_rtx = new;
        !          2679:                  }
        !          2680:              }
        !          2681: 
        !          2682:          if (found_better)
        !          2683:            {
        !          2684:              if (validate_change (insn, loc,
        !          2685:                                   canon_reg (copy_rtx (best_rtx),
        !          2686:                                              NULL_RTX), 0))
        !          2687:                return;
        !          2688:              else
        !          2689:                best_elt->flag = 1;
        !          2690:            }
        !          2691:        }
        !          2692:     }
        !          2693: #endif
        !          2694: }
        !          2695: 
        !          2696: /* Given an operation (CODE, *PARG1, *PARG2), where code is a comparison
        !          2697:    operation (EQ, NE, GT, etc.), follow it back through the hash table and
        !          2698:    what values are being compared.
        !          2699: 
        !          2700:    *PARG1 and *PARG2 are updated to contain the rtx representing the values
        !          2701:    actually being compared.  For example, if *PARG1 was (cc0) and *PARG2
        !          2702:    was (const_int 0), *PARG1 and *PARG2 will be set to the objects that were
        !          2703:    compared to produce cc0.
        !          2704: 
        !          2705:    The return value is the comparison operator and is either the code of
        !          2706:    A or the code corresponding to the inverse of the comparison.  */
        !          2707: 
        !          2708: static enum rtx_code
        !          2709: find_comparison_args (code, parg1, parg2, pmode1, pmode2)
        !          2710:      enum rtx_code code;
        !          2711:      rtx *parg1, *parg2;
        !          2712:      enum machine_mode *pmode1, *pmode2;
        !          2713: {
        !          2714:   rtx arg1, arg2;
        !          2715: 
        !          2716:   arg1 = *parg1, arg2 = *parg2;
        !          2717: 
        !          2718:   /* If ARG2 is const0_rtx, see what ARG1 is equivalent to.  */
        !          2719: 
        !          2720:   while (arg2 == CONST0_RTX (GET_MODE (arg1)))
        !          2721:     {
        !          2722:       /* Set non-zero when we find something of interest.  */
        !          2723:       rtx x = 0;
        !          2724:       int reverse_code = 0;
        !          2725:       struct table_elt *p = 0;
        !          2726: 
        !          2727:       /* If arg1 is a COMPARE, extract the comparison arguments from it.
        !          2728:         On machines with CC0, this is the only case that can occur, since
        !          2729:         fold_rtx will return the COMPARE or item being compared with zero
        !          2730:         when given CC0.  */
        !          2731: 
        !          2732:       if (GET_CODE (arg1) == COMPARE && arg2 == const0_rtx)
        !          2733:        x = arg1;
        !          2734: 
        !          2735:       /* If ARG1 is a comparison operator and CODE is testing for
        !          2736:         STORE_FLAG_VALUE, get the inner arguments.  */
        !          2737: 
        !          2738:       else if (GET_RTX_CLASS (GET_CODE (arg1)) == '<')
        !          2739:        {
        !          2740:          if (code == NE
        !          2741:              || (GET_MODE_CLASS (GET_MODE (arg1)) == MODE_INT
        !          2742:                  && code == LT && STORE_FLAG_VALUE == -1)
        !          2743: #ifdef FLOAT_STORE_FLAG_VALUE
        !          2744:              || (GET_MODE_CLASS (GET_MODE (arg1)) == MODE_FLOAT
        !          2745:                  && FLOAT_STORE_FLAG_VALUE < 0)
        !          2746: #endif
        !          2747:              )
        !          2748:            x = arg1;
        !          2749:          else if (code == EQ
        !          2750:                   || (GET_MODE_CLASS (GET_MODE (arg1)) == MODE_INT
        !          2751:                       && code == GE && STORE_FLAG_VALUE == -1)
        !          2752: #ifdef FLOAT_STORE_FLAG_VALUE
        !          2753:                   || (GET_MODE_CLASS (GET_MODE (arg1)) == MODE_FLOAT
        !          2754:                       && FLOAT_STORE_FLAG_VALUE < 0)
        !          2755: #endif
        !          2756:                   )
        !          2757:            x = arg1, reverse_code = 1;
        !          2758:        }
        !          2759: 
        !          2760:       /* ??? We could also check for
        !          2761: 
        !          2762:         (ne (and (eq (...) (const_int 1))) (const_int 0))
        !          2763: 
        !          2764:         and related forms, but let's wait until we see them occurring.  */
        !          2765: 
        !          2766:       if (x == 0)
        !          2767:        /* Look up ARG1 in the hash table and see if it has an equivalence
        !          2768:           that lets us see what is being compared.  */
        !          2769:        p = lookup (arg1, safe_hash (arg1, GET_MODE (arg1)) % NBUCKETS,
        !          2770:                    GET_MODE (arg1));
        !          2771:       if (p) p = p->first_same_value;
        !          2772: 
        !          2773:       for (; p; p = p->next_same_value)
        !          2774:        {
        !          2775:          enum machine_mode inner_mode = GET_MODE (p->exp);
        !          2776: 
        !          2777:          /* If the entry isn't valid, skip it.  */
        !          2778:          if (! exp_equiv_p (p->exp, p->exp, 1, 0))
        !          2779:            continue;
        !          2780: 
        !          2781:          if (GET_CODE (p->exp) == COMPARE
        !          2782:              /* Another possibility is that this machine has a compare insn
        !          2783:                 that includes the comparison code.  In that case, ARG1 would
        !          2784:                 be equivalent to a comparison operation that would set ARG1 to
        !          2785:                 either STORE_FLAG_VALUE or zero.  If this is an NE operation,
        !          2786:                 ORIG_CODE is the actual comparison being done; if it is an EQ,
        !          2787:                 we must reverse ORIG_CODE.  On machine with a negative value
        !          2788:                 for STORE_FLAG_VALUE, also look at LT and GE operations.  */
        !          2789:              || ((code == NE
        !          2790:                   || (code == LT
        !          2791:                       && GET_MODE_CLASS (inner_mode) == MODE_INT
        !          2792:                       && (GET_MODE_BITSIZE (inner_mode)
        !          2793:                           <= HOST_BITS_PER_WIDE_INT)
        !          2794:                       && (STORE_FLAG_VALUE
        !          2795:                           & ((HOST_WIDE_INT) 1
        !          2796:                              << (GET_MODE_BITSIZE (inner_mode) - 1))))
        !          2797: #ifdef FLOAT_STORE_FLAG_VALUE
        !          2798:                   || (code == LT
        !          2799:                       && GET_MODE_CLASS (inner_mode) == MODE_FLOAT
        !          2800:                       && FLOAT_STORE_FLAG_VALUE < 0)
        !          2801: #endif
        !          2802:                   )
        !          2803:                  && GET_RTX_CLASS (GET_CODE (p->exp)) == '<'))
        !          2804:            {
        !          2805:              x = p->exp;
        !          2806:              break;
        !          2807:            }
        !          2808:          else if ((code == EQ
        !          2809:                    || (code == GE
        !          2810:                        && GET_MODE_CLASS (inner_mode) == MODE_INT
        !          2811:                        && (GET_MODE_BITSIZE (inner_mode)
        !          2812:                            <= HOST_BITS_PER_WIDE_INT)
        !          2813:                        && (STORE_FLAG_VALUE
        !          2814:                            & ((HOST_WIDE_INT) 1
        !          2815:                               << (GET_MODE_BITSIZE (inner_mode) - 1))))
        !          2816: #ifdef FLOAT_STORE_FLAG_VALUE
        !          2817:                    || (code == GE
        !          2818:                        && GET_MODE_CLASS (inner_mode) == MODE_FLOAT
        !          2819:                        && FLOAT_STORE_FLAG_VALUE < 0)
        !          2820: #endif
        !          2821:                    )
        !          2822:                   && GET_RTX_CLASS (GET_CODE (p->exp)) == '<')
        !          2823:            {
        !          2824:              reverse_code = 1;
        !          2825:              x = p->exp;
        !          2826:              break;
        !          2827:            }
        !          2828: 
        !          2829:          /* If this is fp + constant, the equivalent is a better operand since
        !          2830:             it may let us predict the value of the comparison.  */
        !          2831:          else if (NONZERO_BASE_PLUS_P (p->exp))
        !          2832:            {
        !          2833:              arg1 = p->exp;
        !          2834:              continue;
        !          2835:            }
        !          2836:        }
        !          2837: 
        !          2838:       /* If we didn't find a useful equivalence for ARG1, we are done.
        !          2839:         Otherwise, set up for the next iteration.  */
        !          2840:       if (x == 0)
        !          2841:        break;
        !          2842: 
        !          2843:       arg1 = XEXP (x, 0),  arg2 = XEXP (x, 1);
        !          2844:       if (GET_RTX_CLASS (GET_CODE (x)) == '<')
        !          2845:        code = GET_CODE (x);
        !          2846: 
        !          2847:       if (reverse_code)
        !          2848:        code = reverse_condition (code);
        !          2849:     }
        !          2850: 
        !          2851:   /* Return our results.  Return the modes from before fold_rtx
        !          2852:      because fold_rtx might produce const_int, and then it's too late.  */
        !          2853:   *pmode1 = GET_MODE (arg1), *pmode2 = GET_MODE (arg2);
        !          2854:   *parg1 = fold_rtx (arg1, 0), *parg2 = fold_rtx (arg2, 0);
        !          2855: 
        !          2856:   return code;
        !          2857: }
        !          2858: 
        !          2859: /* Try to simplify a unary operation CODE whose output mode is to be
        !          2860:    MODE with input operand OP whose mode was originally OP_MODE.
        !          2861:    Return zero if no simplification can be made.  */
        !          2862: 
        !          2863: rtx
        !          2864: simplify_unary_operation (code, mode, op, op_mode)
        !          2865:      enum rtx_code code;
        !          2866:      enum machine_mode mode;
        !          2867:      rtx op;
        !          2868:      enum machine_mode op_mode;
        !          2869: {
        !          2870:   register int width = GET_MODE_BITSIZE (mode);
        !          2871: 
        !          2872:   /* The order of these tests is critical so that, for example, we don't
        !          2873:      check the wrong mode (input vs. output) for a conversion operation,
        !          2874:      such as FIX.  At some point, this should be simplified.  */
        !          2875: 
        !          2876: #if !defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
        !          2877:   if (code == FLOAT && GET_CODE (op) == CONST_INT)
        !          2878:     {
        !          2879:       REAL_VALUE_TYPE d;
        !          2880: 
        !          2881: #ifdef REAL_ARITHMETIC
        !          2882:       REAL_VALUE_FROM_INT (d, INTVAL (op), INTVAL (op) < 0 ? ~0 : 0);
        !          2883: #else
        !          2884:       d = (double) INTVAL (op);
        !          2885: #endif
        !          2886:       return CONST_DOUBLE_FROM_REAL_VALUE (d, mode);
        !          2887:     }
        !          2888:   else if (code == UNSIGNED_FLOAT && GET_CODE (op) == CONST_INT)
        !          2889:     {
        !          2890:       REAL_VALUE_TYPE d;
        !          2891: 
        !          2892: #ifdef REAL_ARITHMETIC
        !          2893:       REAL_VALUE_FROM_INT (d, INTVAL (op), 0);
        !          2894: #else
        !          2895:       d = (double) (unsigned int) INTVAL (op);
        !          2896: #endif
        !          2897:       return CONST_DOUBLE_FROM_REAL_VALUE (d, mode);
        !          2898:     }
        !          2899: 
        !          2900:   else if (code == FLOAT && GET_CODE (op) == CONST_DOUBLE
        !          2901:           && GET_MODE (op) == VOIDmode)
        !          2902:     {
        !          2903:       REAL_VALUE_TYPE d;
        !          2904: 
        !          2905: #ifdef REAL_ARITHMETIC
        !          2906:       REAL_VALUE_FROM_INT (d, CONST_DOUBLE_LOW (op), CONST_DOUBLE_HIGH (op));
        !          2907: #else
        !          2908:       if (CONST_DOUBLE_HIGH (op) < 0)
        !          2909:        {
        !          2910:          d = (double) (~ CONST_DOUBLE_HIGH (op));
        !          2911:          d *= ((double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2))
        !          2912:                * (double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2)));
        !          2913:          d += (double) (unsigned HOST_WIDE_INT) (~ CONST_DOUBLE_LOW (op));
        !          2914:          d = (- d - 1.0);
        !          2915:        }
        !          2916:       else
        !          2917:        {
        !          2918:          d = (double) CONST_DOUBLE_HIGH (op);
        !          2919:          d *= ((double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2))
        !          2920:                * (double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2)));
        !          2921:          d += (double) (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (op);
        !          2922:        }
        !          2923: #endif  /* REAL_ARITHMETIC */
        !          2924:       return CONST_DOUBLE_FROM_REAL_VALUE (d, mode);
        !          2925:     }
        !          2926:   else if (code == UNSIGNED_FLOAT && GET_CODE (op) == CONST_DOUBLE
        !          2927:           && GET_MODE (op) == VOIDmode)
        !          2928:     {
        !          2929:       REAL_VALUE_TYPE d;
        !          2930: 
        !          2931: #ifdef REAL_ARITHMETIC
        !          2932:       REAL_VALUE_FROM_UNSIGNED_INT (d, CONST_DOUBLE_LOW (op),
        !          2933:                                    CONST_DOUBLE_HIGH (op));
        !          2934: #else
        !          2935:       d = (double) CONST_DOUBLE_HIGH (op);
        !          2936:       d *= ((double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2))
        !          2937:            * (double) ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 2)));
        !          2938:       d += (double) (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (op);
        !          2939: #endif  /* REAL_ARITHMETIC */
        !          2940:       return CONST_DOUBLE_FROM_REAL_VALUE (d, mode);
        !          2941:     }
        !          2942: #endif
        !          2943: 
        !          2944:   if (GET_CODE (op) == CONST_INT
        !          2945:       && width <= HOST_BITS_PER_WIDE_INT && width > 0)
        !          2946:     {
        !          2947:       register HOST_WIDE_INT arg0 = INTVAL (op);
        !          2948:       register HOST_WIDE_INT val;
        !          2949: 
        !          2950:       switch (code)
        !          2951:        {
        !          2952:        case NOT:
        !          2953:          val = ~ arg0;
        !          2954:          break;
        !          2955: 
        !          2956:        case NEG:
        !          2957:          val = - arg0;
        !          2958:          break;
        !          2959: 
        !          2960:        case ABS:
        !          2961:          val = (arg0 >= 0 ? arg0 : - arg0);
        !          2962:          break;
        !          2963: 
        !          2964:        case FFS:
        !          2965:          /* Don't use ffs here.  Instead, get low order bit and then its
        !          2966:             number.  If arg0 is zero, this will return 0, as desired.  */
        !          2967:          arg0 &= GET_MODE_MASK (mode);
        !          2968:          val = exact_log2 (arg0 & (- arg0)) + 1;
        !          2969:          break;
        !          2970: 
        !          2971:        case TRUNCATE:
        !          2972:          val = arg0;
        !          2973:          break;
        !          2974: 
        !          2975:        case ZERO_EXTEND:
        !          2976:          if (op_mode == VOIDmode)
        !          2977:            op_mode = mode;
        !          2978:          if (GET_MODE_BITSIZE (op_mode) == HOST_BITS_PER_WIDE_INT)
        !          2979:            {
        !          2980:              /* If we were really extending the mode,
        !          2981:                 we would have to distinguish between zero-extension
        !          2982:                 and sign-extension.  */
        !          2983:              if (width != GET_MODE_BITSIZE (op_mode))
        !          2984:                abort ();
        !          2985:              val = arg0;
        !          2986:            }
        !          2987:          else if (GET_MODE_BITSIZE (op_mode) < HOST_BITS_PER_WIDE_INT)
        !          2988:            val = arg0 & ~((HOST_WIDE_INT) (-1) << GET_MODE_BITSIZE (op_mode));
        !          2989:          else
        !          2990:            return 0;
        !          2991:          break;
        !          2992: 
        !          2993:        case SIGN_EXTEND:
        !          2994:          if (op_mode == VOIDmode)
        !          2995:            op_mode = mode;
        !          2996:          if (GET_MODE_BITSIZE (op_mode) == HOST_BITS_PER_WIDE_INT)
        !          2997:            {
        !          2998:              /* If we were really extending the mode,
        !          2999:                 we would have to distinguish between zero-extension
        !          3000:                 and sign-extension.  */
        !          3001:              if (width != GET_MODE_BITSIZE (op_mode))
        !          3002:                abort ();
        !          3003:              val = arg0;
        !          3004:            }
        !          3005:          else if (GET_MODE_BITSIZE (op_mode) < HOST_BITS_PER_WIDE_INT)
        !          3006:            {
        !          3007:              val
        !          3008:                = arg0 & ~((HOST_WIDE_INT) (-1) << GET_MODE_BITSIZE (op_mode));
        !          3009:              if (val
        !          3010:                  & ((HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (op_mode) - 1)))
        !          3011:                val -= (HOST_WIDE_INT) 1 << GET_MODE_BITSIZE (op_mode);
        !          3012:            }
        !          3013:          else
        !          3014:            return 0;
        !          3015:          break;
        !          3016: 
        !          3017:        case SQRT:
        !          3018:          return 0;
        !          3019: 
        !          3020:        default:
        !          3021:          abort ();
        !          3022:        }
        !          3023: 
        !          3024:       /* Clear the bits that don't belong in our mode,
        !          3025:         unless they and our sign bit are all one.
        !          3026:         So we get either a reasonable negative value or a reasonable
        !          3027:         unsigned value for this mode.  */
        !          3028:       if (width < HOST_BITS_PER_WIDE_INT
        !          3029:          && ((val & ((HOST_WIDE_INT) (-1) << (width - 1)))
        !          3030:              != ((HOST_WIDE_INT) (-1) << (width - 1))))
        !          3031:        val &= (1 << width) - 1;
        !          3032: 
        !          3033:       return GEN_INT (val);
        !          3034:     }
        !          3035: 
        !          3036:   /* We can do some operations on integer CONST_DOUBLEs.  Also allow
        !          3037:      for a DImode operation on a CONST_INT. */
        !          3038:   else if (GET_MODE (op) == VOIDmode
        !          3039:           && (GET_CODE (op) == CONST_DOUBLE || GET_CODE (op) == CONST_INT))
        !          3040:     {
        !          3041:       HOST_WIDE_INT l1, h1, lv, hv;
        !          3042: 
        !          3043:       if (GET_CODE (op) == CONST_DOUBLE)
        !          3044:        l1 = CONST_DOUBLE_LOW (op), h1 = CONST_DOUBLE_HIGH (op);
        !          3045:       else
        !          3046:        l1 = INTVAL (op), h1 = l1 < 0 ? -1 : 0;
        !          3047: 
        !          3048:       switch (code)
        !          3049:        {
        !          3050:        case NOT:
        !          3051:          lv = ~ l1;
        !          3052:          hv = ~ h1;
        !          3053:          break;
        !          3054: 
        !          3055:        case NEG:
        !          3056:          neg_double (l1, h1, &lv, &hv);
        !          3057:          break;
        !          3058: 
        !          3059:        case ABS:
        !          3060:          if (h1 < 0)
        !          3061:            neg_double (l1, h1, &lv, &hv);
        !          3062:          else
        !          3063:            lv = l1, hv = h1;
        !          3064:          break;
        !          3065: 
        !          3066:        case FFS:
        !          3067:          hv = 0;
        !          3068:          if (l1 == 0)
        !          3069:            lv = HOST_BITS_PER_WIDE_INT + exact_log2 (h1 & (-h1)) + 1;
        !          3070:          else
        !          3071:            lv = exact_log2 (l1 & (-l1)) + 1;
        !          3072:          break;
        !          3073: 
        !          3074:        case TRUNCATE:
        !          3075:          if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
        !          3076:            return GEN_INT (l1 & GET_MODE_MASK (mode));
        !          3077:          else
        !          3078:            return 0;
        !          3079:          break;
        !          3080: 
        !          3081:        case ZERO_EXTEND:
        !          3082:          if (op_mode == VOIDmode
        !          3083:              || GET_MODE_BITSIZE (op_mode) > HOST_BITS_PER_WIDE_INT)
        !          3084:            return 0;
        !          3085: 
        !          3086:          hv = 0;
        !          3087:          lv = l1 & GET_MODE_MASK (op_mode);
        !          3088:          break;
        !          3089: 
        !          3090:        case SIGN_EXTEND:
        !          3091:          if (op_mode == VOIDmode
        !          3092:              || GET_MODE_BITSIZE (op_mode) > HOST_BITS_PER_WIDE_INT)
        !          3093:            return 0;
        !          3094:          else
        !          3095:            {
        !          3096:              lv = l1 & GET_MODE_MASK (op_mode);
        !          3097:              if (GET_MODE_BITSIZE (op_mode) < HOST_BITS_PER_WIDE_INT
        !          3098:                  && (lv & ((HOST_WIDE_INT) 1
        !          3099:                            << (GET_MODE_BITSIZE (op_mode) - 1))) != 0)
        !          3100:                lv -= (HOST_WIDE_INT) 1 << GET_MODE_BITSIZE (op_mode);
        !          3101: 
        !          3102:              hv = (lv < 0) ? ~ (HOST_WIDE_INT) 0 : 0;
        !          3103:            }
        !          3104:          break;
        !          3105: 
        !          3106:        case SQRT:
        !          3107:          return 0;
        !          3108: 
        !          3109:        default:
        !          3110:          return 0;
        !          3111:        }
        !          3112: 
        !          3113:       return immed_double_const (lv, hv, mode);
        !          3114:     }
        !          3115: 
        !          3116: #if ! defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
        !          3117:   else if (GET_CODE (op) == CONST_DOUBLE
        !          3118:           && GET_MODE_CLASS (mode) == MODE_FLOAT)
        !          3119:     {
        !          3120:       REAL_VALUE_TYPE d;
        !          3121:       jmp_buf handler;
        !          3122:       rtx x;
        !          3123: 
        !          3124:       if (setjmp (handler))
        !          3125:        /* There used to be a warning here, but that is inadvisable.
        !          3126:           People may want to cause traps, and the natural way
        !          3127:           to do it should not get a warning.  */
        !          3128:        return 0;
        !          3129: 
        !          3130:       set_float_handler (handler);
        !          3131: 
        !          3132:       REAL_VALUE_FROM_CONST_DOUBLE (d, op);
        !          3133: 
        !          3134:       switch (code)
        !          3135:        {
        !          3136:        case NEG:
        !          3137:          d = REAL_VALUE_NEGATE (d);
        !          3138:          break;
        !          3139: 
        !          3140:        case ABS:
        !          3141:          if (REAL_VALUE_NEGATIVE (d))
        !          3142:            d = REAL_VALUE_NEGATE (d);
        !          3143:          break;
        !          3144: 
        !          3145:        case FLOAT_TRUNCATE:
        !          3146:          d = real_value_truncate (mode, d);
        !          3147:          break;
        !          3148: 
        !          3149:        case FLOAT_EXTEND:
        !          3150:          /* All this does is change the mode.  */
        !          3151:          break;
        !          3152: 
        !          3153:        case FIX:
        !          3154:          d = REAL_VALUE_RNDZINT (d);
        !          3155:          break;
        !          3156: 
        !          3157:        case UNSIGNED_FIX:
        !          3158:          d = REAL_VALUE_UNSIGNED_RNDZINT (d);
        !          3159:          break;
        !          3160: 
        !          3161:        case SQRT:
        !          3162:          return 0;
        !          3163: 
        !          3164:        default:
        !          3165:          abort ();
        !          3166:        }
        !          3167: 
        !          3168:       x = immed_real_const_1 (d, mode);
        !          3169:       set_float_handler (NULL_PTR);
        !          3170:       return x;
        !          3171:     }
        !          3172:   else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE_CLASS (mode) == MODE_INT
        !          3173:           && width <= HOST_BITS_PER_WIDE_INT && width > 0)
        !          3174:     {
        !          3175:       REAL_VALUE_TYPE d;
        !          3176:       jmp_buf handler;
        !          3177:       HOST_WIDE_INT val;
        !          3178: 
        !          3179:       if (setjmp (handler))
        !          3180:        return 0;
        !          3181: 
        !          3182:       set_float_handler (handler);
        !          3183: 
        !          3184:       REAL_VALUE_FROM_CONST_DOUBLE (d, op);
        !          3185: 
        !          3186:       switch (code)
        !          3187:        {
        !          3188:        case FIX:
        !          3189:          val = REAL_VALUE_FIX (d);
        !          3190:          break;
        !          3191: 
        !          3192:        case UNSIGNED_FIX:
        !          3193:          val = REAL_VALUE_UNSIGNED_FIX (d);
        !          3194:          break;
        !          3195: 
        !          3196:        default:
        !          3197:          abort ();
        !          3198:        }
        !          3199: 
        !          3200:       set_float_handler (NULL_PTR);
        !          3201: 
        !          3202:       /* Clear the bits that don't belong in our mode,
        !          3203:         unless they and our sign bit are all one.
        !          3204:         So we get either a reasonable negative value or a reasonable
        !          3205:         unsigned value for this mode.  */
        !          3206:       if (width < HOST_BITS_PER_WIDE_INT
        !          3207:          && ((val & ((HOST_WIDE_INT) (-1) << (width - 1)))
        !          3208:              != ((HOST_WIDE_INT) (-1) << (width - 1))))
        !          3209:        val &= ((HOST_WIDE_INT) 1 << width) - 1;
        !          3210: 
        !          3211:       return GEN_INT (val);
        !          3212:     }
        !          3213: #endif
        !          3214:   /* This was formerly used only for non-IEEE float.
        !          3215:      [email protected] says it is safe for IEEE also.  */
        !          3216:   else
        !          3217:     {
        !          3218:       /* There are some simplifications we can do even if the operands
        !          3219:         aren't constant.  */
        !          3220:       switch (code)
        !          3221:        {
        !          3222:        case NEG:
        !          3223:        case NOT:
        !          3224:          /* (not (not X)) == X, similarly for NEG.  */
        !          3225:          if (GET_CODE (op) == code)
        !          3226:            return XEXP (op, 0);
        !          3227:          break;
        !          3228: 
        !          3229:        case SIGN_EXTEND:
        !          3230:          /* (sign_extend (truncate (minus (label_ref L1) (label_ref L2))))
        !          3231:             becomes just the MINUS if its mode is MODE.  This allows
        !          3232:             folding switch statements on machines using casesi (such as
        !          3233:             the Vax).  */
        !          3234:          if (GET_CODE (op) == TRUNCATE
        !          3235:              && GET_MODE (XEXP (op, 0)) == mode
        !          3236:              && GET_CODE (XEXP (op, 0)) == MINUS
        !          3237:              && GET_CODE (XEXP (XEXP (op, 0), 0)) == LABEL_REF
        !          3238:              && GET_CODE (XEXP (XEXP (op, 0), 1)) == LABEL_REF)
        !          3239:            return XEXP (op, 0);
        !          3240:          break;
        !          3241:        }
        !          3242: 
        !          3243:       return 0;
        !          3244:     }
        !          3245: }
        !          3246: 
        !          3247: /* Simplify a binary operation CODE with result mode MODE, operating on OP0
        !          3248:    and OP1.  Return 0 if no simplification is possible.
        !          3249: 
        !          3250:    Don't use this for relational operations such as EQ or LT.
        !          3251:    Use simplify_relational_operation instead.  */
        !          3252: 
        !          3253: rtx
        !          3254: simplify_binary_operation (code, mode, op0, op1)
        !          3255:      enum rtx_code code;
        !          3256:      enum machine_mode mode;
        !          3257:      rtx op0, op1;
        !          3258: {
        !          3259:   register HOST_WIDE_INT arg0, arg1, arg0s, arg1s;
        !          3260:   HOST_WIDE_INT val;
        !          3261:   int width = GET_MODE_BITSIZE (mode);
        !          3262:   rtx tem;
        !          3263: 
        !          3264:   /* Relational operations don't work here.  We must know the mode
        !          3265:      of the operands in order to do the comparison correctly.
        !          3266:      Assuming a full word can give incorrect results.
        !          3267:      Consider comparing 128 with -128 in QImode.  */
        !          3268: 
        !          3269:   if (GET_RTX_CLASS (code) == '<')
        !          3270:     abort ();
        !          3271: 
        !          3272: #if ! defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
        !          3273:   if (GET_MODE_CLASS (mode) == MODE_FLOAT
        !          3274:       && GET_CODE (op0) == CONST_DOUBLE && GET_CODE (op1) == CONST_DOUBLE
        !          3275:       && mode == GET_MODE (op0) && mode == GET_MODE (op1))
        !          3276:     {
        !          3277:       REAL_VALUE_TYPE f0, f1, value;
        !          3278:       jmp_buf handler;
        !          3279: 
        !          3280:       if (setjmp (handler))
        !          3281:        return 0;
        !          3282: 
        !          3283:       set_float_handler (handler);
        !          3284: 
        !          3285:       REAL_VALUE_FROM_CONST_DOUBLE (f0, op0);
        !          3286:       REAL_VALUE_FROM_CONST_DOUBLE (f1, op1);
        !          3287:       f0 = real_value_truncate (mode, f0);
        !          3288:       f1 = real_value_truncate (mode, f1);
        !          3289: 
        !          3290: #ifdef REAL_ARITHMETIC
        !          3291:       REAL_ARITHMETIC (value, rtx_to_tree_code (code), f0, f1);
        !          3292: #else
        !          3293:       switch (code)
        !          3294:        {
        !          3295:        case PLUS:
        !          3296:          value = f0 + f1;
        !          3297:          break;
        !          3298:        case MINUS:
        !          3299:          value = f0 - f1;
        !          3300:          break;
        !          3301:        case MULT:
        !          3302:          value = f0 * f1;
        !          3303:          break;
        !          3304:        case DIV:
        !          3305: #ifndef REAL_INFINITY
        !          3306:          if (f1 == 0)
        !          3307:            return 0;
        !          3308: #endif
        !          3309:          value = f0 / f1;
        !          3310:          break;
        !          3311:        case SMIN:
        !          3312:          value = MIN (f0, f1);
        !          3313:          break;
        !          3314:        case SMAX:
        !          3315:          value = MAX (f0, f1);
        !          3316:          break;
        !          3317:        default:
        !          3318:          abort ();
        !          3319:        }
        !          3320: #endif
        !          3321: 
        !          3322:       set_float_handler (NULL_PTR);
        !          3323:       value = real_value_truncate (mode, value);
        !          3324:       return immed_real_const_1 (value, mode);
        !          3325:     }
        !          3326: #endif  /* not REAL_IS_NOT_DOUBLE, or REAL_ARITHMETIC */
        !          3327: 
        !          3328:   /* We can fold some multi-word operations.  */
        !          3329:   if (GET_MODE_CLASS (mode) == MODE_INT
        !          3330:       && width == HOST_BITS_PER_WIDE_INT * 2
        !          3331:       && (GET_CODE (op0) == CONST_DOUBLE || GET_CODE (op0) == CONST_INT)
        !          3332:       && (GET_CODE (op1) == CONST_DOUBLE || GET_CODE (op1) == CONST_INT))
        !          3333:     {
        !          3334:       HOST_WIDE_INT l1, l2, h1, h2, lv, hv;
        !          3335: 
        !          3336:       if (GET_CODE (op0) == CONST_DOUBLE)
        !          3337:        l1 = CONST_DOUBLE_LOW (op0), h1 = CONST_DOUBLE_HIGH (op0);
        !          3338:       else
        !          3339:        l1 = INTVAL (op0), h1 = l1 < 0 ? -1 : 0;
        !          3340: 
        !          3341:       if (GET_CODE (op1) == CONST_DOUBLE)
        !          3342:        l2 = CONST_DOUBLE_LOW (op1), h2 = CONST_DOUBLE_HIGH (op1);
        !          3343:       else
        !          3344:        l2 = INTVAL (op1), h2 = l2 < 0 ? -1 : 0;
        !          3345: 
        !          3346:       switch (code)
        !          3347:        {
        !          3348:        case MINUS:
        !          3349:          /* A - B == A + (-B).  */
        !          3350:          neg_double (l2, h2, &lv, &hv);
        !          3351:          l2 = lv, h2 = hv;
        !          3352: 
        !          3353:          /* .. fall through ... */
        !          3354: 
        !          3355:        case PLUS:
        !          3356:          add_double (l1, h1, l2, h2, &lv, &hv);
        !          3357:          break;
        !          3358: 
        !          3359:        case MULT:
        !          3360:          mul_double (l1, h1, l2, h2, &lv, &hv);
        !          3361:          break;
        !          3362: 
        !          3363:        case DIV:  case MOD:   case UDIV:  case UMOD:
        !          3364:          /* We'd need to include tree.h to do this and it doesn't seem worth
        !          3365:             it.  */
        !          3366:          return 0;
        !          3367: 
        !          3368:        case AND:
        !          3369:          lv = l1 & l2, hv = h1 & h2;
        !          3370:          break;
        !          3371: 
        !          3372:        case IOR:
        !          3373:          lv = l1 | l2, hv = h1 | h2;
        !          3374:          break;
        !          3375: 
        !          3376:        case XOR:
        !          3377:          lv = l1 ^ l2, hv = h1 ^ h2;
        !          3378:          break;
        !          3379: 
        !          3380:        case SMIN:
        !          3381:          if (h1 < h2
        !          3382:              || (h1 == h2
        !          3383:                  && ((unsigned HOST_WIDE_INT) l1
        !          3384:                      < (unsigned HOST_WIDE_INT) l2)))
        !          3385:            lv = l1, hv = h1;
        !          3386:          else
        !          3387:            lv = l2, hv = h2;
        !          3388:          break;
        !          3389: 
        !          3390:        case SMAX:
        !          3391:          if (h1 > h2
        !          3392:              || (h1 == h2
        !          3393:                  && ((unsigned HOST_WIDE_INT) l1
        !          3394:                      > (unsigned HOST_WIDE_INT) l2)))
        !          3395:            lv = l1, hv = h1;
        !          3396:          else
        !          3397:            lv = l2, hv = h2;
        !          3398:          break;
        !          3399: 
        !          3400:        case UMIN:
        !          3401:          if ((unsigned HOST_WIDE_INT) h1 < (unsigned HOST_WIDE_INT) h2
        !          3402:              || (h1 == h2
        !          3403:                  && ((unsigned HOST_WIDE_INT) l1
        !          3404:                      < (unsigned HOST_WIDE_INT) l2)))
        !          3405:            lv = l1, hv = h1;
        !          3406:          else
        !          3407:            lv = l2, hv = h2;
        !          3408:          break;
        !          3409: 
        !          3410:        case UMAX:
        !          3411:          if ((unsigned HOST_WIDE_INT) h1 > (unsigned HOST_WIDE_INT) h2
        !          3412:              || (h1 == h2
        !          3413:                  && ((unsigned HOST_WIDE_INT) l1
        !          3414:                      > (unsigned HOST_WIDE_INT) l2)))
        !          3415:            lv = l1, hv = h1;
        !          3416:          else
        !          3417:            lv = l2, hv = h2;
        !          3418:          break;
        !          3419: 
        !          3420:        case LSHIFTRT:   case ASHIFTRT:
        !          3421:        case ASHIFT:     case LSHIFT:
        !          3422:        case ROTATE:     case ROTATERT:
        !          3423: #ifdef SHIFT_COUNT_TRUNCATED
        !          3424:          if (SHIFT_COUNT_TRUNCATED)
        !          3425:            l2 &= (GET_MODE_BITSIZE (mode) - 1), h2 = 0;
        !          3426: #endif
        !          3427: 
        !          3428:          if (h2 != 0 || l2 < 0 || l2 >= GET_MODE_BITSIZE (mode))
        !          3429:            return 0;
        !          3430: 
        !          3431:          if (code == LSHIFTRT || code == ASHIFTRT)
        !          3432:            rshift_double (l1, h1, l2, GET_MODE_BITSIZE (mode), &lv, &hv,
        !          3433:                           code == ASHIFTRT);
        !          3434:          else if (code == ASHIFT || code == LSHIFT)
        !          3435:            lshift_double (l1, h1, l2, GET_MODE_BITSIZE (mode), &lv, &hv,
        !          3436:                           code == ASHIFT);
        !          3437:          else if (code == ROTATE)
        !          3438:            lrotate_double (l1, h1, l2, GET_MODE_BITSIZE (mode), &lv, &hv);
        !          3439:          else /* code == ROTATERT */
        !          3440:            rrotate_double (l1, h1, l2, GET_MODE_BITSIZE (mode), &lv, &hv);
        !          3441:          break;
        !          3442: 
        !          3443:        default:
        !          3444:          return 0;
        !          3445:        }
        !          3446: 
        !          3447:       return immed_double_const (lv, hv, mode);
        !          3448:     }
        !          3449: 
        !          3450:   if (GET_CODE (op0) != CONST_INT || GET_CODE (op1) != CONST_INT
        !          3451:       || width > HOST_BITS_PER_WIDE_INT || width == 0)
        !          3452:     {
        !          3453:       /* Even if we can't compute a constant result,
        !          3454:         there are some cases worth simplifying.  */
        !          3455: 
        !          3456:       switch (code)
        !          3457:        {
        !          3458:        case PLUS:
        !          3459:          /* In IEEE floating point, x+0 is not the same as x.  Similarly
        !          3460:             for the other optimizations below.  */
        !          3461:          if (TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
        !          3462:              && FLOAT_MODE_P (mode))
        !          3463:            break;
        !          3464: 
        !          3465:          if (op1 == CONST0_RTX (mode))
        !          3466:            return op0;
        !          3467: 
        !          3468:          /* ((-a) + b) -> (b - a) and similarly for (a + (-b)) */
        !          3469:          if (GET_CODE (op0) == NEG)
        !          3470:            return cse_gen_binary (MINUS, mode, op1, XEXP (op0, 0));
        !          3471:          else if (GET_CODE (op1) == NEG)
        !          3472:            return cse_gen_binary (MINUS, mode, op0, XEXP (op1, 0));
        !          3473: 
        !          3474:          /* Handle both-operands-constant cases.  We can only add
        !          3475:             CONST_INTs to constants since the sum of relocatable symbols
        !          3476:             can't be handled by most assemblers.  Don't add CONST_INT
        !          3477:             to CONST_INT since overflow won't be computed properly if wider
        !          3478:             than HOST_BITS_PER_WIDE_INT.  */
        !          3479: 
        !          3480:          if (CONSTANT_P (op0) && GET_MODE (op0) != VOIDmode
        !          3481:              && GET_CODE (op1) == CONST_INT)
        !          3482:            return plus_constant (op0, INTVAL (op1));
        !          3483:          else if (CONSTANT_P (op1) && GET_MODE (op1) != VOIDmode
        !          3484:                   && GET_CODE (op0) == CONST_INT)
        !          3485:            return plus_constant (op1, INTVAL (op0));
        !          3486: 
        !          3487:          /* If one of the operands is a PLUS or a MINUS, see if we can
        !          3488:             simplify this by the associative law. 
        !          3489:             Don't use the associative law for floating point.
        !          3490:             The inaccuracy makes it nonassociative,
        !          3491:             and subtle programs can break if operations are associated.  */
        !          3492: 
        !          3493:          if (INTEGRAL_MODE_P (mode)
        !          3494:              && (GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS
        !          3495:                  || GET_CODE (op1) == PLUS || GET_CODE (op1) == MINUS)
        !          3496:              && (tem = simplify_plus_minus (code, mode, op0, op1)) != 0)
        !          3497:            return tem;
        !          3498:          break;
        !          3499: 
        !          3500:        case COMPARE:
        !          3501: #ifdef HAVE_cc0
        !          3502:          /* Convert (compare FOO (const_int 0)) to FOO unless we aren't
        !          3503:             using cc0, in which case we want to leave it as a COMPARE
        !          3504:             so we can distinguish it from a register-register-copy.
        !          3505: 
        !          3506:             In IEEE floating point, x-0 is not the same as x.  */
        !          3507: 
        !          3508:          if ((TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
        !          3509:               || ! FLOAT_MODE_P (mode))
        !          3510:              && op1 == CONST0_RTX (mode))
        !          3511:            return op0;
        !          3512: #else
        !          3513:          /* Do nothing here.  */
        !          3514: #endif
        !          3515:          break;
        !          3516:              
        !          3517:        case MINUS:
        !          3518:          /* None of these optimizations can be done for IEEE
        !          3519:             floating point.  */
        !          3520:          if (TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
        !          3521:              && FLOAT_MODE_P (mode))
        !          3522:            break;
        !          3523: 
        !          3524:          /* We can't assume x-x is 0 even with non-IEEE floating point.  */
        !          3525:          if (rtx_equal_p (op0, op1)
        !          3526:              && ! side_effects_p (op0)
        !          3527:              && ! FLOAT_MODE_P (mode))
        !          3528:            return const0_rtx;
        !          3529: 
        !          3530:          /* Change subtraction from zero into negation.  */
        !          3531:          if (op0 == CONST0_RTX (mode))
        !          3532:            return gen_rtx (NEG, mode, op1);
        !          3533: 
        !          3534:          /* (-1 - a) is ~a.  */
        !          3535:          if (op0 == constm1_rtx)
        !          3536:            return gen_rtx (NOT, mode, op1);
        !          3537: 
        !          3538:          /* Subtracting 0 has no effect.  */
        !          3539:          if (op1 == CONST0_RTX (mode))
        !          3540:            return op0;
        !          3541: 
        !          3542:          /* (a - (-b)) -> (a + b).  */
        !          3543:          if (GET_CODE (op1) == NEG)
        !          3544:            return cse_gen_binary (PLUS, mode, op0, XEXP (op1, 0));
        !          3545: 
        !          3546:          /* If one of the operands is a PLUS or a MINUS, see if we can
        !          3547:             simplify this by the associative law. 
        !          3548:             Don't use the associative law for floating point.
        !          3549:             The inaccuracy makes it nonassociative,
        !          3550:             and subtle programs can break if operations are associated.  */
        !          3551: 
        !          3552:          if (INTEGRAL_MODE_P (mode)
        !          3553:              && (GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS
        !          3554:                  || GET_CODE (op1) == PLUS || GET_CODE (op1) == MINUS)
        !          3555:              && (tem = simplify_plus_minus (code, mode, op0, op1)) != 0)
        !          3556:            return tem;
        !          3557: 
        !          3558:          /* Don't let a relocatable value get a negative coeff.  */
        !          3559:          if (GET_CODE (op1) == CONST_INT && GET_MODE (op1) != VOIDmode)
        !          3560:            return plus_constant (op0, - INTVAL (op1));
        !          3561:          break;
        !          3562: 
        !          3563:        case MULT:
        !          3564:          if (op1 == constm1_rtx)
        !          3565:            {
        !          3566:              tem = simplify_unary_operation (NEG, mode, op0, mode);
        !          3567: 
        !          3568:              return tem ? tem : gen_rtx (NEG, mode, op0);
        !          3569:            }
        !          3570: 
        !          3571:          /* In IEEE floating point, x*0 is not always 0.  */
        !          3572:          if ((TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
        !          3573:               && ! FLOAT_MODE_P (mode))
        !          3574:              && op1 == CONST0_RTX (mode)
        !          3575:              && ! side_effects_p (op0))
        !          3576:            return op1;
        !          3577: 
        !          3578:          /* In IEEE floating point, x*1 is not equivalent to x for nans.
        !          3579:             However, ANSI says we can drop signals,
        !          3580:             so we can do this anyway.  */
        !          3581:          if (op1 == CONST1_RTX (mode))
        !          3582:            return op0;
        !          3583: 
        !          3584:          /* Convert multiply by constant power of two into shift.  */
        !          3585:          if (GET_CODE (op1) == CONST_INT
        !          3586:              && (val = exact_log2 (INTVAL (op1))) >= 0)
        !          3587:            return gen_rtx (ASHIFT, mode, op0, GEN_INT (val));
        !          3588: 
        !          3589:          if (GET_CODE (op1) == CONST_DOUBLE
        !          3590:              && GET_MODE_CLASS (GET_MODE (op1)) == MODE_FLOAT)
        !          3591:            {
        !          3592:              REAL_VALUE_TYPE d;
        !          3593:              jmp_buf handler;
        !          3594:              int op1is2, op1ism1;
        !          3595: 
        !          3596:              if (setjmp (handler))
        !          3597:                return 0;
        !          3598: 
        !          3599:              set_float_handler (handler);
        !          3600:              REAL_VALUE_FROM_CONST_DOUBLE (d, op1);
        !          3601:              op1is2 = REAL_VALUES_EQUAL (d, dconst2);
        !          3602:              op1ism1 = REAL_VALUES_EQUAL (d, dconstm1);
        !          3603:              set_float_handler (NULL_PTR);
        !          3604: 
        !          3605:              /* x*2 is x+x and x*(-1) is -x */
        !          3606:              if (op1is2 && GET_MODE (op0) == mode)
        !          3607:                return gen_rtx (PLUS, mode, op0, copy_rtx (op0));
        !          3608: 
        !          3609:              else if (op1ism1 && GET_MODE (op0) == mode)
        !          3610:                return gen_rtx (NEG, mode, op0);
        !          3611:            }
        !          3612:          break;
        !          3613: 
        !          3614:        case IOR:
        !          3615:          if (op1 == const0_rtx)
        !          3616:            return op0;
        !          3617:          if (GET_CODE (op1) == CONST_INT
        !          3618:              && (INTVAL (op1) & GET_MODE_MASK (mode)) == GET_MODE_MASK (mode))
        !          3619:            return op1;
        !          3620:          if (rtx_equal_p (op0, op1) && ! side_effects_p (op0))
        !          3621:            return op0;
        !          3622:          /* A | (~A) -> -1 */
        !          3623:          if (((GET_CODE (op0) == NOT && rtx_equal_p (XEXP (op0, 0), op1))
        !          3624:               || (GET_CODE (op1) == NOT && rtx_equal_p (XEXP (op1, 0), op0)))
        !          3625:              && ! side_effects_p (op0)
        !          3626:              && GET_MODE_CLASS (mode) != MODE_CC)
        !          3627:            return constm1_rtx;
        !          3628:          break;
        !          3629: 
        !          3630:        case XOR:
        !          3631:          if (op1 == const0_rtx)
        !          3632:            return op0;
        !          3633:          if (GET_CODE (op1) == CONST_INT
        !          3634:              && (INTVAL (op1) & GET_MODE_MASK (mode)) == GET_MODE_MASK (mode))
        !          3635:            return gen_rtx (NOT, mode, op0);
        !          3636:          if (op0 == op1 && ! side_effects_p (op0)
        !          3637:              && GET_MODE_CLASS (mode) != MODE_CC)
        !          3638:            return const0_rtx;
        !          3639:          break;
        !          3640: 
        !          3641:        case AND:
        !          3642:          if (op1 == const0_rtx && ! side_effects_p (op0))
        !          3643:            return const0_rtx;
        !          3644:          if (GET_CODE (op1) == CONST_INT
        !          3645:              && (INTVAL (op1) & GET_MODE_MASK (mode)) == GET_MODE_MASK (mode))
        !          3646:            return op0;
        !          3647:          if (op0 == op1 && ! side_effects_p (op0)
        !          3648:              && GET_MODE_CLASS (mode) != MODE_CC)
        !          3649:            return op0;
        !          3650:          /* A & (~A) -> 0 */
        !          3651:          if (((GET_CODE (op0) == NOT && rtx_equal_p (XEXP (op0, 0), op1))
        !          3652:               || (GET_CODE (op1) == NOT && rtx_equal_p (XEXP (op1, 0), op0)))
        !          3653:              && ! side_effects_p (op0)
        !          3654:              && GET_MODE_CLASS (mode) != MODE_CC)
        !          3655:            return const0_rtx;
        !          3656:          break;
        !          3657: 
        !          3658:        case UDIV:
        !          3659:          /* Convert divide by power of two into shift (divide by 1 handled
        !          3660:             below).  */
        !          3661:          if (GET_CODE (op1) == CONST_INT
        !          3662:              && (arg1 = exact_log2 (INTVAL (op1))) > 0)
        !          3663:            return gen_rtx (LSHIFTRT, mode, op0, GEN_INT (arg1));
        !          3664: 
        !          3665:          /* ... fall through ... */
        !          3666: 
        !          3667:        case DIV:
        !          3668:          if (op1 == CONST1_RTX (mode))
        !          3669:            return op0;
        !          3670: 
        !          3671:          /* In IEEE floating point, 0/x is not always 0.  */
        !          3672:          if ((TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
        !          3673:               || ! FLOAT_MODE_P (mode))
        !          3674:              && op0 == CONST0_RTX (mode)
        !          3675:              && ! side_effects_p (op1))
        !          3676:            return op0;
        !          3677: 
        !          3678: #if 0 /* Turned off till an expert says this is a safe thing to do.  */
        !          3679: #if ! defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
        !          3680:          /* Change division by a constant into multiplication.  */
        !          3681:          else if (GET_CODE (op1) == CONST_DOUBLE
        !          3682:                   && GET_MODE_CLASS (GET_MODE (op1)) == MODE_FLOAT
        !          3683:                   && op1 != CONST0_RTX (mode))
        !          3684:            {
        !          3685:              REAL_VALUE_TYPE d;
        !          3686:              REAL_VALUE_FROM_CONST_DOUBLE (d, op1);
        !          3687:              if (REAL_VALUES_EQUAL (d, dconst0))
        !          3688:                abort();
        !          3689: #if defined (REAL_ARITHMETIC)
        !          3690:              REAL_ARITHMETIC (d, (int) RDIV_EXPR, dconst1, d);
        !          3691:              return gen_rtx (MULT, mode, op0, 
        !          3692:                              CONST_DOUBLE_FROM_REAL_VALUE (d, mode));
        !          3693: #else
        !          3694:              return gen_rtx (MULT, mode, op0, 
        !          3695:                              CONST_DOUBLE_FROM_REAL_VALUE (1./d, mode));
        !          3696:            }
        !          3697: #endif
        !          3698: #endif
        !          3699: #endif
        !          3700:          break;
        !          3701: 
        !          3702:        case UMOD:
        !          3703:          /* Handle modulus by power of two (mod with 1 handled below).  */
        !          3704:          if (GET_CODE (op1) == CONST_INT
        !          3705:              && exact_log2 (INTVAL (op1)) > 0)
        !          3706:            return gen_rtx (AND, mode, op0, GEN_INT (INTVAL (op1) - 1));
        !          3707: 
        !          3708:          /* ... fall through ... */
        !          3709: 
        !          3710:        case MOD:
        !          3711:          if ((op0 == const0_rtx || op1 == const1_rtx)
        !          3712:              && ! side_effects_p (op0) && ! side_effects_p (op1))
        !          3713:            return const0_rtx;
        !          3714:          break;
        !          3715: 
        !          3716:        case ROTATERT:
        !          3717:        case ROTATE:
        !          3718:          /* Rotating ~0 always results in ~0.  */
        !          3719:          if (GET_CODE (op0) == CONST_INT && width <= HOST_BITS_PER_WIDE_INT
        !          3720:              && INTVAL (op0) == GET_MODE_MASK (mode)
        !          3721:              && ! side_effects_p (op1))
        !          3722:            return op0;
        !          3723: 
        !          3724:          /* ... fall through ... */
        !          3725: 
        !          3726:        case LSHIFT:
        !          3727:        case ASHIFT:
        !          3728:        case ASHIFTRT:
        !          3729:        case LSHIFTRT:
        !          3730:          if (op1 == const0_rtx)
        !          3731:            return op0;
        !          3732:          if (op0 == const0_rtx && ! side_effects_p (op1))
        !          3733:            return op0;
        !          3734:          break;
        !          3735: 
        !          3736:        case SMIN:
        !          3737:          if (width <= HOST_BITS_PER_WIDE_INT && GET_CODE (op1) == CONST_INT 
        !          3738:              && INTVAL (op1) == (HOST_WIDE_INT) 1 << (width -1)
        !          3739:              && ! side_effects_p (op0))
        !          3740:            return op1;
        !          3741:          else if (rtx_equal_p (op0, op1) && ! side_effects_p (op0))
        !          3742:            return op0;
        !          3743:          break;
        !          3744:           
        !          3745:        case SMAX:
        !          3746:          if (width <= HOST_BITS_PER_WIDE_INT && GET_CODE (op1) == CONST_INT
        !          3747:              && (INTVAL (op1)
        !          3748:                  == (unsigned HOST_WIDE_INT) GET_MODE_MASK (mode) >> 1)
        !          3749:              && ! side_effects_p (op0))
        !          3750:            return op1;
        !          3751:          else if (rtx_equal_p (op0, op1) && ! side_effects_p (op0))
        !          3752:            return op0;
        !          3753:          break;
        !          3754: 
        !          3755:        case UMIN:
        !          3756:          if (op1 == const0_rtx && ! side_effects_p (op0))
        !          3757:            return op1;
        !          3758:          else if (rtx_equal_p (op0, op1) && ! side_effects_p (op0))
        !          3759:            return op0;
        !          3760:          break;
        !          3761:            
        !          3762:        case UMAX:
        !          3763:          if (op1 == constm1_rtx && ! side_effects_p (op0))
        !          3764:            return op1;
        !          3765:          else if (rtx_equal_p (op0, op1) && ! side_effects_p (op0))
        !          3766:            return op0;
        !          3767:          break;
        !          3768: 
        !          3769:        default:
        !          3770:          abort ();
        !          3771:        }
        !          3772:       
        !          3773:       return 0;
        !          3774:     }
        !          3775: 
        !          3776:   /* Get the integer argument values in two forms:
        !          3777:      zero-extended in ARG0, ARG1 and sign-extended in ARG0S, ARG1S.  */
        !          3778: 
        !          3779:   arg0 = INTVAL (op0);
        !          3780:   arg1 = INTVAL (op1);
        !          3781: 
        !          3782:   if (width < HOST_BITS_PER_WIDE_INT)
        !          3783:     {
        !          3784:       arg0 &= ((HOST_WIDE_INT) 1 << width) - 1;
        !          3785:       arg1 &= ((HOST_WIDE_INT) 1 << width) - 1;
        !          3786: 
        !          3787:       arg0s = arg0;
        !          3788:       if (arg0s & ((HOST_WIDE_INT) 1 << (width - 1)))
        !          3789:        arg0s |= ((HOST_WIDE_INT) (-1) << width);
        !          3790: 
        !          3791:       arg1s = arg1;
        !          3792:       if (arg1s & ((HOST_WIDE_INT) 1 << (width - 1)))
        !          3793:        arg1s |= ((HOST_WIDE_INT) (-1) << width);
        !          3794:     }
        !          3795:   else
        !          3796:     {
        !          3797:       arg0s = arg0;
        !          3798:       arg1s = arg1;
        !          3799:     }
        !          3800: 
        !          3801:   /* Compute the value of the arithmetic.  */
        !          3802: 
        !          3803:   switch (code)
        !          3804:     {
        !          3805:     case PLUS:
        !          3806:       val = arg0s + arg1s;
        !          3807:       break;
        !          3808: 
        !          3809:     case MINUS:
        !          3810:       val = arg0s - arg1s;
        !          3811:       break;
        !          3812: 
        !          3813:     case MULT:
        !          3814:       val = arg0s * arg1s;
        !          3815:       break;
        !          3816: 
        !          3817:     case DIV:
        !          3818:       if (arg1s == 0)
        !          3819:        return 0;
        !          3820:       val = arg0s / arg1s;
        !          3821:       break;
        !          3822: 
        !          3823:     case MOD:
        !          3824:       if (arg1s == 0)
        !          3825:        return 0;
        !          3826:       val = arg0s % arg1s;
        !          3827:       break;
        !          3828: 
        !          3829:     case UDIV:
        !          3830:       if (arg1 == 0)
        !          3831:        return 0;
        !          3832:       val = (unsigned HOST_WIDE_INT) arg0 / arg1;
        !          3833:       break;
        !          3834: 
        !          3835:     case UMOD:
        !          3836:       if (arg1 == 0)
        !          3837:        return 0;
        !          3838:       val = (unsigned HOST_WIDE_INT) arg0 % arg1;
        !          3839:       break;
        !          3840: 
        !          3841:     case AND:
        !          3842:       val = arg0 & arg1;
        !          3843:       break;
        !          3844: 
        !          3845:     case IOR:
        !          3846:       val = arg0 | arg1;
        !          3847:       break;
        !          3848: 
        !          3849:     case XOR:
        !          3850:       val = arg0 ^ arg1;
        !          3851:       break;
        !          3852: 
        !          3853:     case LSHIFTRT:
        !          3854:       /* If shift count is undefined, don't fold it; let the machine do
        !          3855:         what it wants.  But truncate it if the machine will do that.  */
        !          3856:       if (arg1 < 0)
        !          3857:        return 0;
        !          3858: 
        !          3859: #ifdef SHIFT_COUNT_TRUNCATED
        !          3860:       if (SHIFT_COUNT_TRUNCATED)
        !          3861:        arg1 &= (BITS_PER_WORD - 1);
        !          3862: #endif
        !          3863: 
        !          3864:       if (arg1 >= width)
        !          3865:        return 0;
        !          3866: 
        !          3867:       val = ((unsigned HOST_WIDE_INT) arg0) >> arg1;
        !          3868:       break;
        !          3869: 
        !          3870:     case ASHIFT:
        !          3871:     case LSHIFT:
        !          3872:       if (arg1 < 0)
        !          3873:        return 0;
        !          3874: 
        !          3875: #ifdef SHIFT_COUNT_TRUNCATED
        !          3876:       if (SHIFT_COUNT_TRUNCATED)
        !          3877:        arg1 &= (BITS_PER_WORD - 1);
        !          3878: #endif
        !          3879: 
        !          3880:       if (arg1 >= width)
        !          3881:        return 0;
        !          3882: 
        !          3883:       val = ((unsigned HOST_WIDE_INT) arg0) << arg1;
        !          3884:       break;
        !          3885: 
        !          3886:     case ASHIFTRT:
        !          3887:       if (arg1 < 0)
        !          3888:        return 0;
        !          3889: 
        !          3890: #ifdef SHIFT_COUNT_TRUNCATED
        !          3891:       if (SHIFT_COUNT_TRUNCATED)
        !          3892:        arg1 &= (BITS_PER_WORD - 1);
        !          3893: #endif
        !          3894: 
        !          3895:       if (arg1 >= width)
        !          3896:        return 0;
        !          3897: 
        !          3898:       val = arg0s >> arg1;
        !          3899: 
        !          3900:       /* Bootstrap compiler may not have sign extended the right shift.
        !          3901:         Manually extend the sign to insure bootstrap cc matches gcc.  */
        !          3902:       if (arg0s < 0 && arg1 > 0)
        !          3903:        val |= ((HOST_WIDE_INT) -1) << (HOST_BITS_PER_WIDE_INT - arg1);
        !          3904: 
        !          3905:       break;
        !          3906: 
        !          3907:     case ROTATERT:
        !          3908:       if (arg1 < 0)
        !          3909:        return 0;
        !          3910: 
        !          3911:       arg1 %= width;
        !          3912:       val = ((((unsigned HOST_WIDE_INT) arg0) << (width - arg1))
        !          3913:             | (((unsigned HOST_WIDE_INT) arg0) >> arg1));
        !          3914:       break;
        !          3915: 
        !          3916:     case ROTATE:
        !          3917:       if (arg1 < 0)
        !          3918:        return 0;
        !          3919: 
        !          3920:       arg1 %= width;
        !          3921:       val = ((((unsigned HOST_WIDE_INT) arg0) << arg1)
        !          3922:             | (((unsigned HOST_WIDE_INT) arg0) >> (width - arg1)));
        !          3923:       break;
        !          3924: 
        !          3925:     case COMPARE:
        !          3926:       /* Do nothing here.  */
        !          3927:       return 0;
        !          3928: 
        !          3929:     case SMIN:
        !          3930:       val = arg0s <= arg1s ? arg0s : arg1s;
        !          3931:       break;
        !          3932: 
        !          3933:     case UMIN:
        !          3934:       val = ((unsigned HOST_WIDE_INT) arg0
        !          3935:             <= (unsigned HOST_WIDE_INT) arg1 ? arg0 : arg1);
        !          3936:       break;
        !          3937: 
        !          3938:     case SMAX:
        !          3939:       val = arg0s > arg1s ? arg0s : arg1s;
        !          3940:       break;
        !          3941: 
        !          3942:     case UMAX:
        !          3943:       val = ((unsigned HOST_WIDE_INT) arg0
        !          3944:             > (unsigned HOST_WIDE_INT) arg1 ? arg0 : arg1);
        !          3945:       break;
        !          3946: 
        !          3947:     default:
        !          3948:       abort ();
        !          3949:     }
        !          3950: 
        !          3951:   /* Clear the bits that don't belong in our mode, unless they and our sign
        !          3952:      bit are all one.  So we get either a reasonable negative value or a
        !          3953:      reasonable unsigned value for this mode.  */
        !          3954:   if (width < HOST_BITS_PER_WIDE_INT
        !          3955:       && ((val & ((HOST_WIDE_INT) (-1) << (width - 1)))
        !          3956:          != ((HOST_WIDE_INT) (-1) << (width - 1))))
        !          3957:     val &= ((HOST_WIDE_INT) 1 << width) - 1;
        !          3958: 
        !          3959:   return GEN_INT (val);
        !          3960: }
        !          3961: 
        !          3962: /* Simplify a PLUS or MINUS, at least one of whose operands may be another
        !          3963:    PLUS or MINUS.
        !          3964: 
        !          3965:    Rather than test for specific case, we do this by a brute-force method
        !          3966:    and do all possible simplifications until no more changes occur.  Then
        !          3967:    we rebuild the operation.  */
        !          3968: 
        !          3969: static rtx
        !          3970: simplify_plus_minus (code, mode, op0, op1)
        !          3971:      enum rtx_code code;
        !          3972:      enum machine_mode mode;
        !          3973:      rtx op0, op1;
        !          3974: {
        !          3975:   rtx ops[8];
        !          3976:   int negs[8];
        !          3977:   rtx result, tem;
        !          3978:   int n_ops = 2, input_ops = 2, input_consts = 0, n_consts = 0;
        !          3979:   int first = 1, negate = 0, changed;
        !          3980:   int i, j;
        !          3981: 
        !          3982:   bzero (ops, sizeof ops);
        !          3983:   
        !          3984:   /* Set up the two operands and then expand them until nothing has been
        !          3985:      changed.  If we run out of room in our array, give up; this should
        !          3986:      almost never happen.  */
        !          3987: 
        !          3988:   ops[0] = op0, ops[1] = op1, negs[0] = 0, negs[1] = (code == MINUS);
        !          3989: 
        !          3990:   changed = 1;
        !          3991:   while (changed)
        !          3992:     {
        !          3993:       changed = 0;
        !          3994: 
        !          3995:       for (i = 0; i < n_ops; i++)
        !          3996:        switch (GET_CODE (ops[i]))
        !          3997:          {
        !          3998:          case PLUS:
        !          3999:          case MINUS:
        !          4000:            if (n_ops == 7)
        !          4001:              return 0;
        !          4002: 
        !          4003:            ops[n_ops] = XEXP (ops[i], 1);
        !          4004:            negs[n_ops++] = GET_CODE (ops[i]) == MINUS ? !negs[i] : negs[i];
        !          4005:            ops[i] = XEXP (ops[i], 0);
        !          4006:            input_ops++;
        !          4007:            changed = 1;
        !          4008:            break;
        !          4009: 
        !          4010:          case NEG:
        !          4011:            ops[i] = XEXP (ops[i], 0);
        !          4012:            negs[i] = ! negs[i];
        !          4013:            changed = 1;
        !          4014:            break;
        !          4015: 
        !          4016:          case CONST:
        !          4017:            ops[i] = XEXP (ops[i], 0);
        !          4018:            input_consts++;
        !          4019:            changed = 1;
        !          4020:            break;
        !          4021: 
        !          4022:          case NOT:
        !          4023:            /* ~a -> (-a - 1) */
        !          4024:            if (n_ops != 7)
        !          4025:              {
        !          4026:                ops[n_ops] = constm1_rtx;
        !          4027:                negs[n_ops++] = negs[i];
        !          4028:                ops[i] = XEXP (ops[i], 0);
        !          4029:                negs[i] = ! negs[i];
        !          4030:                changed = 1;
        !          4031:              }
        !          4032:            break;
        !          4033: 
        !          4034:          case CONST_INT:
        !          4035:            if (negs[i])
        !          4036:              ops[i] = GEN_INT (- INTVAL (ops[i])), negs[i] = 0, changed = 1;
        !          4037:            break;
        !          4038:          }
        !          4039:     }
        !          4040: 
        !          4041:   /* If we only have two operands, we can't do anything.  */
        !          4042:   if (n_ops <= 2)
        !          4043:     return 0;
        !          4044: 
        !          4045:   /* Now simplify each pair of operands until nothing changes.  The first
        !          4046:      time through just simplify constants against each other.  */
        !          4047: 
        !          4048:   changed = 1;
        !          4049:   while (changed)
        !          4050:     {
        !          4051:       changed = first;
        !          4052: 
        !          4053:       for (i = 0; i < n_ops - 1; i++)
        !          4054:        for (j = i + 1; j < n_ops; j++)
        !          4055:          if (ops[i] != 0 && ops[j] != 0
        !          4056:              && (! first || (CONSTANT_P (ops[i]) && CONSTANT_P (ops[j]))))
        !          4057:            {
        !          4058:              rtx lhs = ops[i], rhs = ops[j];
        !          4059:              enum rtx_code ncode = PLUS;
        !          4060: 
        !          4061:              if (negs[i] && ! negs[j])
        !          4062:                lhs = ops[j], rhs = ops[i], ncode = MINUS;
        !          4063:              else if (! negs[i] && negs[j])
        !          4064:                ncode = MINUS;
        !          4065: 
        !          4066:              tem = simplify_binary_operation (ncode, mode, lhs, rhs);
        !          4067:              if (tem)
        !          4068:                {
        !          4069:                  ops[i] = tem, ops[j] = 0;
        !          4070:                  negs[i] = negs[i] && negs[j];
        !          4071:                  if (GET_CODE (tem) == NEG)
        !          4072:                    ops[i] = XEXP (tem, 0), negs[i] = ! negs[i];
        !          4073: 
        !          4074:                  if (GET_CODE (ops[i]) == CONST_INT && negs[i])
        !          4075:                    ops[i] = GEN_INT (- INTVAL (ops[i])), negs[i] = 0;
        !          4076:                  changed = 1;
        !          4077:                }
        !          4078:            }
        !          4079: 
        !          4080:       first = 0;
        !          4081:     }
        !          4082: 
        !          4083:   /* Pack all the operands to the lower-numbered entries and give up if
        !          4084:      we didn't reduce the number of operands we had.  Make sure we
        !          4085:      count a CONST as two operands.  If we have the same number of
        !          4086:      operands, but have made more CONSTs than we had, this is also
        !          4087:      an improvement, so accept it.  */
        !          4088: 
        !          4089:   for (i = 0, j = 0; j < n_ops; j++)
        !          4090:     if (ops[j] != 0)
        !          4091:       {
        !          4092:        ops[i] = ops[j], negs[i++] = negs[j];
        !          4093:        if (GET_CODE (ops[j]) == CONST)
        !          4094:          n_consts++;
        !          4095:       }
        !          4096: 
        !          4097:   if (i + n_consts > input_ops
        !          4098:       || (i + n_consts == input_ops && n_consts <= input_consts))
        !          4099:     return 0;
        !          4100: 
        !          4101:   n_ops = i;
        !          4102: 
        !          4103:   /* If we have a CONST_INT, put it last.  */
        !          4104:   for (i = 0; i < n_ops - 1; i++)
        !          4105:     if (GET_CODE (ops[i]) == CONST_INT)
        !          4106:       {
        !          4107:        tem = ops[n_ops - 1], ops[n_ops - 1] = ops[i] , ops[i] = tem;
        !          4108:        j = negs[n_ops - 1], negs[n_ops - 1] = negs[i], negs[i] = j;
        !          4109:       }
        !          4110: 
        !          4111:   /* Put a non-negated operand first.  If there aren't any, make all
        !          4112:      operands positive and negate the whole thing later.  */
        !          4113:   for (i = 0; i < n_ops && negs[i]; i++)
        !          4114:     ;
        !          4115: 
        !          4116:   if (i == n_ops)
        !          4117:     {
        !          4118:       for (i = 0; i < n_ops; i++)
        !          4119:        negs[i] = 0;
        !          4120:       negate = 1;
        !          4121:     }
        !          4122:   else if (i != 0)
        !          4123:     {
        !          4124:       tem = ops[0], ops[0] = ops[i], ops[i] = tem;
        !          4125:       j = negs[0], negs[0] = negs[i], negs[i] = j;
        !          4126:     }
        !          4127: 
        !          4128:   /* Now make the result by performing the requested operations.  */
        !          4129:   result = ops[0];
        !          4130:   for (i = 1; i < n_ops; i++)
        !          4131:     result = cse_gen_binary (negs[i] ? MINUS : PLUS, mode, result, ops[i]);
        !          4132: 
        !          4133:   return negate ? gen_rtx (NEG, mode, result) : result;
        !          4134: }
        !          4135: 
        !          4136: /* Make a binary operation by properly ordering the operands and 
        !          4137:    seeing if the expression folds.  */
        !          4138: 
        !          4139: static rtx
        !          4140: cse_gen_binary (code, mode, op0, op1)
        !          4141:      enum rtx_code code;
        !          4142:      enum machine_mode mode;
        !          4143:      rtx op0, op1;
        !          4144: {
        !          4145:   rtx tem;
        !          4146: 
        !          4147:   /* Put complex operands first and constants second if commutative.  */
        !          4148:   if (GET_RTX_CLASS (code) == 'c'
        !          4149:       && ((CONSTANT_P (op0) && GET_CODE (op1) != CONST_INT)
        !          4150:          || (GET_RTX_CLASS (GET_CODE (op0)) == 'o'
        !          4151:              && GET_RTX_CLASS (GET_CODE (op1)) != 'o')
        !          4152:          || (GET_CODE (op0) == SUBREG
        !          4153:              && GET_RTX_CLASS (GET_CODE (SUBREG_REG (op0))) == 'o'
        !          4154:              && GET_RTX_CLASS (GET_CODE (op1)) != 'o')))
        !          4155:     tem = op0, op0 = op1, op1 = tem;
        !          4156: 
        !          4157:   /* If this simplifies, do it.  */
        !          4158:   tem = simplify_binary_operation (code, mode, op0, op1);
        !          4159: 
        !          4160:   if (tem)
        !          4161:     return tem;
        !          4162: 
        !          4163:   /* Handle addition and subtraction of CONST_INT specially.  Otherwise,
        !          4164:      just form the operation.  */
        !          4165: 
        !          4166:   if (code == PLUS && GET_CODE (op1) == CONST_INT
        !          4167:       && GET_MODE (op0) != VOIDmode)
        !          4168:     return plus_constant (op0, INTVAL (op1));
        !          4169:   else if (code == MINUS && GET_CODE (op1) == CONST_INT
        !          4170:           && GET_MODE (op0) != VOIDmode)
        !          4171:     return plus_constant (op0, - INTVAL (op1));
        !          4172:   else
        !          4173:     return gen_rtx (code, mode, op0, op1);
        !          4174: }
        !          4175: 
        !          4176: /* Like simplify_binary_operation except used for relational operators.
        !          4177:    MODE is the mode of the operands, not that of the result.  */
        !          4178: 
        !          4179: rtx
        !          4180: simplify_relational_operation (code, mode, op0, op1)
        !          4181:      enum rtx_code code;
        !          4182:      enum machine_mode mode;
        !          4183:      rtx op0, op1;
        !          4184: {
        !          4185:   register HOST_WIDE_INT arg0, arg1, arg0s, arg1s;
        !          4186:   HOST_WIDE_INT val;
        !          4187:   int width = GET_MODE_BITSIZE (mode);
        !          4188: 
        !          4189:   /* If op0 is a compare, extract the comparison arguments from it.  */
        !          4190:   if (GET_CODE (op0) == COMPARE && op1 == const0_rtx)
        !          4191:     op1 = XEXP (op0, 1), op0 = XEXP (op0, 0);
        !          4192: 
        !          4193:   /* What to do with MODE_CC isn't clear yet.
        !          4194:      Let's make sure nothing erroneous is done.  */
        !          4195:   if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC)
        !          4196:     return 0;
        !          4197: 
        !          4198:   /* Unlike the arithmetic operations, we can do the comparison whether
        !          4199:      or not WIDTH is larger than HOST_BITS_PER_WIDE_INT because the
        !          4200:      CONST_INTs are to be understood as being infinite precision as
        !          4201:      is the comparison.  So there is no question of overflow.  */
        !          4202: 
        !          4203:   if (GET_CODE (op0) != CONST_INT || GET_CODE (op1) != CONST_INT || width == 0)
        !          4204:     {
        !          4205:       /* Even if we can't compute a constant result,
        !          4206:         there are some cases worth simplifying.  */
        !          4207: 
        !          4208:       /* For non-IEEE floating-point, if the two operands are equal, we know
        !          4209:         the result.  */
        !          4210:       if (rtx_equal_p (op0, op1)
        !          4211:          && (TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
        !          4212:              || ! FLOAT_MODE_P (GET_MODE (op0))))
        !          4213:        return (code == EQ || code == GE || code == LE || code == LEU
        !          4214:                || code == GEU) ? const_true_rtx : const0_rtx;
        !          4215: 
        !          4216: #if ! defined (REAL_IS_NOT_DOUBLE) || defined (REAL_ARITHMETIC)
        !          4217:       else if (GET_CODE (op0) == CONST_DOUBLE
        !          4218:               && GET_CODE (op1) == CONST_DOUBLE
        !          4219:               && GET_MODE_CLASS (GET_MODE (op0)) == MODE_FLOAT)
        !          4220:        {
        !          4221:          REAL_VALUE_TYPE d0, d1;
        !          4222:          jmp_buf handler;
        !          4223:          int op0lt, op1lt, equal;
        !          4224: 
        !          4225:          if (setjmp (handler))
        !          4226:            return 0;
        !          4227: 
        !          4228:          set_float_handler (handler);
        !          4229:          REAL_VALUE_FROM_CONST_DOUBLE (d0, op0);
        !          4230:          REAL_VALUE_FROM_CONST_DOUBLE (d1, op1);
        !          4231:          equal = REAL_VALUES_EQUAL (d0, d1);
        !          4232:          op0lt = REAL_VALUES_LESS (d0, d1);
        !          4233:          op1lt = REAL_VALUES_LESS (d1, d0);
        !          4234:          set_float_handler (NULL_PTR);
        !          4235: 
        !          4236:          switch (code)
        !          4237:            {
        !          4238:            case EQ:
        !          4239:              return equal ? const_true_rtx : const0_rtx;
        !          4240:            case NE:
        !          4241:              return !equal ? const_true_rtx : const0_rtx;
        !          4242:            case LE:
        !          4243:              return equal || op0lt ? const_true_rtx : const0_rtx;
        !          4244:            case LT:
        !          4245:              return op0lt ? const_true_rtx : const0_rtx;
        !          4246:            case GE:
        !          4247:              return equal || op1lt ? const_true_rtx : const0_rtx;
        !          4248:            case GT:
        !          4249:              return op1lt ? const_true_rtx : const0_rtx;
        !          4250:            }
        !          4251:        }
        !          4252: #endif  /* not REAL_IS_NOT_DOUBLE, or REAL_ARITHMETIC */
        !          4253: 
        !          4254:       else if (GET_MODE_CLASS (mode) == MODE_INT
        !          4255:               && width > HOST_BITS_PER_WIDE_INT
        !          4256:               && (GET_CODE (op0) == CONST_DOUBLE
        !          4257:                   || GET_CODE (op0) == CONST_INT)
        !          4258:               && (GET_CODE (op1) == CONST_DOUBLE
        !          4259:                   || GET_CODE (op1) == CONST_INT))
        !          4260:        {
        !          4261:          HOST_WIDE_INT h0, l0, h1, l1;
        !          4262:          unsigned HOST_WIDE_INT uh0, ul0, uh1, ul1;
        !          4263:          int op0lt, op0ltu, equal;
        !          4264: 
        !          4265:          if (GET_CODE (op0) == CONST_DOUBLE)
        !          4266:            l0 = CONST_DOUBLE_LOW (op0), h0 = CONST_DOUBLE_HIGH (op0);
        !          4267:          else
        !          4268:            l0 = INTVAL (op0), h0 = l0 < 0 ? -1 : 0;
        !          4269:          
        !          4270:          if (GET_CODE (op1) == CONST_DOUBLE)
        !          4271:            l1 = CONST_DOUBLE_LOW (op1), h1 = CONST_DOUBLE_HIGH (op1);
        !          4272:          else
        !          4273:            l1 = INTVAL (op1), h1 = l1 < 0 ? -1 : 0;
        !          4274: 
        !          4275:          uh0 = h0, ul0 = l0, uh1 = h1, ul1 = l1;
        !          4276: 
        !          4277:          equal = (h0 == h1 && l0 == l1);
        !          4278:          op0lt = (h0 < h1 || (h0 == h1 && l0 < l1));
        !          4279:          op0ltu = (uh0 < uh1 || (uh0 == uh1 && ul0 < ul1));
        !          4280: 
        !          4281:          switch (code)
        !          4282:            {
        !          4283:            case EQ:
        !          4284:              return equal ? const_true_rtx : const0_rtx;
        !          4285:            case NE:
        !          4286:              return !equal ? const_true_rtx : const0_rtx;
        !          4287:            case LE:
        !          4288:              return equal || op0lt ? const_true_rtx : const0_rtx;
        !          4289:            case LT:
        !          4290:              return op0lt ? const_true_rtx : const0_rtx;
        !          4291:            case GE:
        !          4292:              return !op0lt ? const_true_rtx : const0_rtx;
        !          4293:            case GT:
        !          4294:              return !equal && !op0lt ? const_true_rtx : const0_rtx;
        !          4295:            case LEU:
        !          4296:              return equal || op0ltu ? const_true_rtx : const0_rtx;
        !          4297:            case LTU:
        !          4298:              return op0ltu ? const_true_rtx : const0_rtx;
        !          4299:            case GEU:
        !          4300:              return !op0ltu ? const_true_rtx : const0_rtx;
        !          4301:            case GTU:
        !          4302:              return !equal && !op0ltu ? const_true_rtx : const0_rtx;
        !          4303:            }
        !          4304:        }
        !          4305: 
        !          4306:       switch (code)
        !          4307:        {
        !          4308:        case EQ:
        !          4309:          {
        !          4310: #if 0
        !          4311:            /* We can't make this assumption due to #pragma weak */
        !          4312:            if (CONSTANT_P (op0) && op1 == const0_rtx)
        !          4313:              return const0_rtx;
        !          4314: #endif
        !          4315:            if (NONZERO_BASE_PLUS_P (op0) && op1 == const0_rtx
        !          4316:                /* On some machines, the ap reg can be 0 sometimes.  */
        !          4317:                && op0 != arg_pointer_rtx)
        !          4318:              return const0_rtx;
        !          4319:            break;
        !          4320:          }
        !          4321: 
        !          4322:        case NE:
        !          4323: #if 0
        !          4324:          /* We can't make this assumption due to #pragma weak */
        !          4325:          if (CONSTANT_P (op0) && op1 == const0_rtx)
        !          4326:            return const_true_rtx;
        !          4327: #endif
        !          4328:          if (NONZERO_BASE_PLUS_P (op0) && op1 == const0_rtx
        !          4329:              /* On some machines, the ap reg can be 0 sometimes.  */
        !          4330:              && op0 != arg_pointer_rtx)
        !          4331:            return const_true_rtx;
        !          4332:          break;
        !          4333: 
        !          4334:        case GEU:
        !          4335:          /* Unsigned values are never negative, but we must be sure we are
        !          4336:             actually comparing a value, not a CC operand.  */
        !          4337:          if (op1 == const0_rtx && INTEGRAL_MODE_P (mode))
        !          4338:            return const_true_rtx;
        !          4339:          break;
        !          4340: 
        !          4341:        case LTU:
        !          4342:          if (op1 == const0_rtx && INTEGRAL_MODE_P (mode))
        !          4343:            return const0_rtx;
        !          4344:          break;
        !          4345: 
        !          4346:        case LEU:
        !          4347:          /* Unsigned values are never greater than the largest
        !          4348:             unsigned value.  */
        !          4349:          if (GET_CODE (op1) == CONST_INT
        !          4350:              && INTVAL (op1) == GET_MODE_MASK (mode)
        !          4351:              && INTEGRAL_MODE_P (mode))
        !          4352:            return const_true_rtx;
        !          4353:          break;
        !          4354: 
        !          4355:        case GTU:
        !          4356:          if (GET_CODE (op1) == CONST_INT
        !          4357:              && INTVAL (op1) == GET_MODE_MASK (mode)
        !          4358:              && INTEGRAL_MODE_P (mode))
        !          4359:            return const0_rtx;
        !          4360:          break;
        !          4361:        }
        !          4362: 
        !          4363:       return 0;
        !          4364:     }
        !          4365: 
        !          4366:   /* Get the integer argument values in two forms:
        !          4367:      zero-extended in ARG0, ARG1 and sign-extended in ARG0S, ARG1S.  */
        !          4368: 
        !          4369:   arg0 = INTVAL (op0);
        !          4370:   arg1 = INTVAL (op1);
        !          4371: 
        !          4372:   if (width < HOST_BITS_PER_WIDE_INT)
        !          4373:     {
        !          4374:       arg0 &= ((HOST_WIDE_INT) 1 << width) - 1;
        !          4375:       arg1 &= ((HOST_WIDE_INT) 1 << width) - 1;
        !          4376: 
        !          4377:       arg0s = arg0;
        !          4378:       if (arg0s & ((HOST_WIDE_INT) 1 << (width - 1)))
        !          4379:        arg0s |= ((HOST_WIDE_INT) (-1) << width);
        !          4380: 
        !          4381:       arg1s = arg1;
        !          4382:       if (arg1s & ((HOST_WIDE_INT) 1 << (width - 1)))
        !          4383:        arg1s |= ((HOST_WIDE_INT) (-1) << width);
        !          4384:     }
        !          4385:   else
        !          4386:     {
        !          4387:       arg0s = arg0;
        !          4388:       arg1s = arg1;
        !          4389:     }
        !          4390: 
        !          4391:   /* Compute the value of the arithmetic.  */
        !          4392: 
        !          4393:   switch (code)
        !          4394:     {
        !          4395:     case NE:
        !          4396:       val = arg0 != arg1 ? STORE_FLAG_VALUE : 0;
        !          4397:       break;
        !          4398: 
        !          4399:     case EQ:
        !          4400:       val = arg0 == arg1 ? STORE_FLAG_VALUE : 0;
        !          4401:       break;
        !          4402: 
        !          4403:     case LE:
        !          4404:       val = arg0s <= arg1s ? STORE_FLAG_VALUE : 0;
        !          4405:       break;
        !          4406: 
        !          4407:     case LT:
        !          4408:       val = arg0s < arg1s ? STORE_FLAG_VALUE : 0;
        !          4409:       break;
        !          4410: 
        !          4411:     case GE:
        !          4412:       val = arg0s >= arg1s ? STORE_FLAG_VALUE : 0;
        !          4413:       break;
        !          4414: 
        !          4415:     case GT:
        !          4416:       val = arg0s > arg1s ? STORE_FLAG_VALUE : 0;
        !          4417:       break;
        !          4418: 
        !          4419:     case LEU:
        !          4420:       val = (((unsigned HOST_WIDE_INT) arg0)
        !          4421:             <= ((unsigned HOST_WIDE_INT) arg1) ? STORE_FLAG_VALUE : 0);
        !          4422:       break;
        !          4423: 
        !          4424:     case LTU:
        !          4425:       val = (((unsigned HOST_WIDE_INT) arg0)
        !          4426:             < ((unsigned HOST_WIDE_INT) arg1) ? STORE_FLAG_VALUE : 0);
        !          4427:       break;
        !          4428: 
        !          4429:     case GEU:
        !          4430:       val = (((unsigned HOST_WIDE_INT) arg0)
        !          4431:             >= ((unsigned HOST_WIDE_INT) arg1) ? STORE_FLAG_VALUE : 0);
        !          4432:       break;
        !          4433: 
        !          4434:     case GTU:
        !          4435:       val = (((unsigned HOST_WIDE_INT) arg0)
        !          4436:             > ((unsigned HOST_WIDE_INT) arg1) ? STORE_FLAG_VALUE : 0);
        !          4437:       break;
        !          4438: 
        !          4439:     default:
        !          4440:       abort ();
        !          4441:     }
        !          4442: 
        !          4443:   /* Clear the bits that don't belong in our mode, unless they and our sign
        !          4444:      bit are all one.  So we get either a reasonable negative value or a
        !          4445:      reasonable unsigned value for this mode.  */
        !          4446:   if (width < HOST_BITS_PER_WIDE_INT
        !          4447:       && ((val & ((HOST_WIDE_INT) (-1) << (width - 1)))
        !          4448:          != ((HOST_WIDE_INT) (-1) << (width - 1))))
        !          4449:     val &= ((HOST_WIDE_INT) 1 << width) - 1;
        !          4450:   
        !          4451:   return GEN_INT (val);
        !          4452: }
        !          4453: 
        !          4454: /* Simplify CODE, an operation with result mode MODE and three operands,
        !          4455:    OP0, OP1, and OP2.  OP0_MODE was the mode of OP0 before it became
        !          4456:    a constant.  Return 0 if no simplifications is possible.  */
        !          4457: 
        !          4458: rtx
        !          4459: simplify_ternary_operation (code, mode, op0_mode, op0, op1, op2)
        !          4460:      enum rtx_code code;
        !          4461:      enum machine_mode mode, op0_mode;
        !          4462:      rtx op0, op1, op2;
        !          4463: {
        !          4464:   int width = GET_MODE_BITSIZE (mode);
        !          4465: 
        !          4466:   /* VOIDmode means "infinite" precision.  */
        !          4467:   if (width == 0)
        !          4468:     width = HOST_BITS_PER_WIDE_INT;
        !          4469: 
        !          4470:   switch (code)
        !          4471:     {
        !          4472:     case SIGN_EXTRACT:
        !          4473:     case ZERO_EXTRACT:
        !          4474:       if (GET_CODE (op0) == CONST_INT
        !          4475:          && GET_CODE (op1) == CONST_INT
        !          4476:          && GET_CODE (op2) == CONST_INT
        !          4477:          && INTVAL (op1) + INTVAL (op2) <= GET_MODE_BITSIZE (op0_mode)
        !          4478:          && width <= HOST_BITS_PER_WIDE_INT)
        !          4479:        {
        !          4480:          /* Extracting a bit-field from a constant */
        !          4481:          HOST_WIDE_INT val = INTVAL (op0);
        !          4482: 
        !          4483: #if BITS_BIG_ENDIAN
        !          4484:          val >>= (GET_MODE_BITSIZE (op0_mode) - INTVAL (op2) - INTVAL (op1));
        !          4485: #else
        !          4486:          val >>= INTVAL (op2);
        !          4487: #endif
        !          4488:          if (HOST_BITS_PER_WIDE_INT != INTVAL (op1))
        !          4489:            {
        !          4490:              /* First zero-extend.  */
        !          4491:              val &= ((HOST_WIDE_INT) 1 << INTVAL (op1)) - 1;
        !          4492:              /* If desired, propagate sign bit.  */
        !          4493:              if (code == SIGN_EXTRACT
        !          4494:                  && (val & ((HOST_WIDE_INT) 1 << (INTVAL (op1) - 1))))
        !          4495:                val |= ~ (((HOST_WIDE_INT) 1 << INTVAL (op1)) - 1);
        !          4496:            }
        !          4497: 
        !          4498:          /* Clear the bits that don't belong in our mode,
        !          4499:             unless they and our sign bit are all one.
        !          4500:             So we get either a reasonable negative value or a reasonable
        !          4501:             unsigned value for this mode.  */
        !          4502:          if (width < HOST_BITS_PER_WIDE_INT
        !          4503:              && ((val & ((HOST_WIDE_INT) (-1) << (width - 1)))
        !          4504:                  != ((HOST_WIDE_INT) (-1) << (width - 1))))
        !          4505:            val &= ((HOST_WIDE_INT) 1 << width) - 1;
        !          4506: 
        !          4507:          return GEN_INT (val);
        !          4508:        }
        !          4509:       break;
        !          4510: 
        !          4511:     case IF_THEN_ELSE:
        !          4512:       if (GET_CODE (op0) == CONST_INT)
        !          4513:        return op0 != const0_rtx ? op1 : op2;
        !          4514:       break;
        !          4515: 
        !          4516:     default:
        !          4517:       abort ();
        !          4518:     }
        !          4519: 
        !          4520:   return 0;
        !          4521: }
        !          4522: 
        !          4523: /* If X is a nontrivial arithmetic operation on an argument
        !          4524:    for which a constant value can be determined, return
        !          4525:    the result of operating on that value, as a constant.
        !          4526:    Otherwise, return X, possibly with one or more operands
        !          4527:    modified by recursive calls to this function.
        !          4528: 
        !          4529:    If X is a register whose contents are known, we do NOT
        !          4530:    return those contents here.  equiv_constant is called to
        !          4531:    perform that task.
        !          4532: 
        !          4533:    INSN is the insn that we may be modifying.  If it is 0, make a copy
        !          4534:    of X before modifying it.  */
        !          4535: 
        !          4536: static rtx
        !          4537: fold_rtx (x, insn)
        !          4538:      rtx x;
        !          4539:      rtx insn;    
        !          4540: {
        !          4541:   register enum rtx_code code;
        !          4542:   register enum machine_mode mode;
        !          4543:   register char *fmt;
        !          4544:   register int i;
        !          4545:   rtx new = 0;
        !          4546:   int copied = 0;
        !          4547:   int must_swap = 0;
        !          4548: 
        !          4549:   /* Folded equivalents of first two operands of X.  */
        !          4550:   rtx folded_arg0;
        !          4551:   rtx folded_arg1;
        !          4552: 
        !          4553:   /* Constant equivalents of first three operands of X;
        !          4554:      0 when no such equivalent is known.  */
        !          4555:   rtx const_arg0;
        !          4556:   rtx const_arg1;
        !          4557:   rtx const_arg2;
        !          4558: 
        !          4559:   /* The mode of the first operand of X.  We need this for sign and zero
        !          4560:      extends.  */
        !          4561:   enum machine_mode mode_arg0;
        !          4562: 
        !          4563:   if (x == 0)
        !          4564:     return x;
        !          4565: 
        !          4566:   mode = GET_MODE (x);
        !          4567:   code = GET_CODE (x);
        !          4568:   switch (code)
        !          4569:     {
        !          4570:     case CONST:
        !          4571:     case CONST_INT:
        !          4572:     case CONST_DOUBLE:
        !          4573:     case SYMBOL_REF:
        !          4574:     case LABEL_REF:
        !          4575:     case REG:
        !          4576:       /* No use simplifying an EXPR_LIST
        !          4577:         since they are used only for lists of args
        !          4578:         in a function call's REG_EQUAL note.  */
        !          4579:     case EXPR_LIST:
        !          4580:       return x;
        !          4581: 
        !          4582: #ifdef HAVE_cc0
        !          4583:     case CC0:
        !          4584:       return prev_insn_cc0;
        !          4585: #endif
        !          4586: 
        !          4587:     case PC:
        !          4588:       /* If the next insn is a CODE_LABEL followed by a jump table,
        !          4589:         PC's value is a LABEL_REF pointing to that label.  That
        !          4590:         lets us fold switch statements on the Vax.  */
        !          4591:       if (insn && GET_CODE (insn) == JUMP_INSN)
        !          4592:        {
        !          4593:          rtx next = next_nonnote_insn (insn);
        !          4594: 
        !          4595:          if (next && GET_CODE (next) == CODE_LABEL
        !          4596:              && NEXT_INSN (next) != 0
        !          4597:              && GET_CODE (NEXT_INSN (next)) == JUMP_INSN
        !          4598:              && (GET_CODE (PATTERN (NEXT_INSN (next))) == ADDR_VEC
        !          4599:                  || GET_CODE (PATTERN (NEXT_INSN (next))) == ADDR_DIFF_VEC))
        !          4600:            return gen_rtx (LABEL_REF, Pmode, next);
        !          4601:        }
        !          4602:       break;
        !          4603: 
        !          4604:     case SUBREG:
        !          4605:       /* See if we previously assigned a constant value to this SUBREG.  */
        !          4606:       if ((new = lookup_as_function (x, CONST_INT)) != 0
        !          4607:          || (new = lookup_as_function (x, CONST_DOUBLE)) != 0)
        !          4608:        return new;
        !          4609: 
        !          4610:       /* If this is a paradoxical SUBREG, we have no idea what value the
        !          4611:         extra bits would have.  However, if the operand is equivalent
        !          4612:         to a SUBREG whose operand is the same as our mode, and all the
        !          4613:         modes are within a word, we can just use the inner operand
        !          4614:         because these SUBREGs just say how to treat the register.
        !          4615: 
        !          4616:         Similarly if we find an integer constant.  */
        !          4617: 
        !          4618:       if (GET_MODE_SIZE (mode) > GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
        !          4619:        {
        !          4620:          enum machine_mode imode = GET_MODE (SUBREG_REG (x));
        !          4621:          struct table_elt *elt;
        !          4622: 
        !          4623:          if (GET_MODE_SIZE (mode) <= UNITS_PER_WORD
        !          4624:              && GET_MODE_SIZE (imode) <= UNITS_PER_WORD
        !          4625:              && (elt = lookup (SUBREG_REG (x), HASH (SUBREG_REG (x), imode),
        !          4626:                                imode)) != 0)
        !          4627:            for (elt = elt->first_same_value;
        !          4628:                 elt; elt = elt->next_same_value)
        !          4629:              {
        !          4630:                if (CONSTANT_P (elt->exp)
        !          4631:                    && GET_MODE (elt->exp) == VOIDmode)
        !          4632:                  return elt->exp;
        !          4633: 
        !          4634:                if (GET_CODE (elt->exp) == SUBREG
        !          4635:                    && GET_MODE (SUBREG_REG (elt->exp)) == mode
        !          4636:                    && exp_equiv_p (elt->exp, elt->exp, 1, 0))
        !          4637:                  return copy_rtx (SUBREG_REG (elt->exp));
        !          4638:            }
        !          4639: 
        !          4640:          return x;
        !          4641:        }
        !          4642: 
        !          4643:       /* Fold SUBREG_REG.  If it changed, see if we can simplify the SUBREG.
        !          4644:         We might be able to if the SUBREG is extracting a single word in an
        !          4645:         integral mode or extracting the low part.  */
        !          4646: 
        !          4647:       folded_arg0 = fold_rtx (SUBREG_REG (x), insn);
        !          4648:       const_arg0 = equiv_constant (folded_arg0);
        !          4649:       if (const_arg0)
        !          4650:        folded_arg0 = const_arg0;
        !          4651: 
        !          4652:       if (folded_arg0 != SUBREG_REG (x))
        !          4653:        {
        !          4654:          new = 0;
        !          4655: 
        !          4656:          if (GET_MODE_CLASS (mode) == MODE_INT
        !          4657:              && GET_MODE_SIZE (mode) == UNITS_PER_WORD
        !          4658:              && GET_MODE (SUBREG_REG (x)) != VOIDmode)
        !          4659:            new = operand_subword (folded_arg0, SUBREG_WORD (x), 0,
        !          4660:                                   GET_MODE (SUBREG_REG (x)));
        !          4661:          if (new == 0 && subreg_lowpart_p (x))
        !          4662:            new = gen_lowpart_if_possible (mode, folded_arg0);
        !          4663:          if (new)
        !          4664:            return new;
        !          4665:        }
        !          4666: 
        !          4667:       /* If this is a narrowing SUBREG and our operand is a REG, see if
        !          4668:         we can find an equivalence for REG that is an arithmetic operation
        !          4669:         in a wider mode where both operands are paradoxical SUBREGs
        !          4670:         from objects of our result mode.  In that case, we couldn't report
        !          4671:         an equivalent value for that operation, since we don't know what the
        !          4672:         extra bits will be.  But we can find an equivalence for this SUBREG
        !          4673:         by folding that operation is the narrow mode.  This allows us to
        !          4674:         fold arithmetic in narrow modes when the machine only supports
        !          4675:         word-sized arithmetic.  
        !          4676: 
        !          4677:         Also look for a case where we have a SUBREG whose operand is the
        !          4678:         same as our result.  If both modes are smaller than a word, we
        !          4679:         are simply interpreting a register in different modes and we
        !          4680:         can use the inner value.  */
        !          4681: 
        !          4682:       if (GET_CODE (folded_arg0) == REG
        !          4683:          && GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (folded_arg0))
        !          4684:          && subreg_lowpart_p (x))
        !          4685:        {
        !          4686:          struct table_elt *elt;
        !          4687: 
        !          4688:          /* We can use HASH here since we know that canon_hash won't be
        !          4689:             called.  */
        !          4690:          elt = lookup (folded_arg0,
        !          4691:                        HASH (folded_arg0, GET_MODE (folded_arg0)),
        !          4692:                        GET_MODE (folded_arg0));
        !          4693: 
        !          4694:          if (elt)
        !          4695:            elt = elt->first_same_value;
        !          4696: 
        !          4697:          for (; elt; elt = elt->next_same_value)
        !          4698:            {
        !          4699:              enum rtx_code eltcode = GET_CODE (elt->exp);
        !          4700: 
        !          4701:              /* Just check for unary and binary operations.  */
        !          4702:              if (GET_RTX_CLASS (GET_CODE (elt->exp)) == '1'
        !          4703:                  && GET_CODE (elt->exp) != SIGN_EXTEND
        !          4704:                  && GET_CODE (elt->exp) != ZERO_EXTEND
        !          4705:                  && GET_CODE (XEXP (elt->exp, 0)) == SUBREG
        !          4706:                  && GET_MODE (SUBREG_REG (XEXP (elt->exp, 0))) == mode)
        !          4707:                {
        !          4708:                  rtx op0 = SUBREG_REG (XEXP (elt->exp, 0));
        !          4709: 
        !          4710:                  if (GET_CODE (op0) != REG && ! CONSTANT_P (op0))
        !          4711:                    op0 = fold_rtx (op0, NULL_RTX);
        !          4712: 
        !          4713:                  op0 = equiv_constant (op0);
        !          4714:                  if (op0)
        !          4715:                    new = simplify_unary_operation (GET_CODE (elt->exp), mode,
        !          4716:                                                    op0, mode);
        !          4717:                }
        !          4718:              else if ((GET_RTX_CLASS (GET_CODE (elt->exp)) == '2'
        !          4719:                        || GET_RTX_CLASS (GET_CODE (elt->exp)) == 'c')
        !          4720:                       && eltcode != DIV && eltcode != MOD
        !          4721:                       && eltcode != UDIV && eltcode != UMOD
        !          4722:                       && eltcode != ASHIFTRT && eltcode != LSHIFTRT
        !          4723:                       && eltcode != ROTATE && eltcode != ROTATERT
        !          4724:                       && ((GET_CODE (XEXP (elt->exp, 0)) == SUBREG
        !          4725:                            && (GET_MODE (SUBREG_REG (XEXP (elt->exp, 0)))
        !          4726:                                == mode))
        !          4727:                           || CONSTANT_P (XEXP (elt->exp, 0)))
        !          4728:                       && ((GET_CODE (XEXP (elt->exp, 1)) == SUBREG
        !          4729:                            && (GET_MODE (SUBREG_REG (XEXP (elt->exp, 1)))
        !          4730:                                == mode))
        !          4731:                           || CONSTANT_P (XEXP (elt->exp, 1))))
        !          4732:                {
        !          4733:                  rtx op0 = gen_lowpart_common (mode, XEXP (elt->exp, 0));
        !          4734:                  rtx op1 = gen_lowpart_common (mode, XEXP (elt->exp, 1));
        !          4735: 
        !          4736:                  if (op0 && GET_CODE (op0) != REG && ! CONSTANT_P (op0))
        !          4737:                    op0 = fold_rtx (op0, NULL_RTX);
        !          4738: 
        !          4739:                  if (op0)
        !          4740:                    op0 = equiv_constant (op0);
        !          4741: 
        !          4742:                  if (op1 && GET_CODE (op1) != REG && ! CONSTANT_P (op1))
        !          4743:                    op1 = fold_rtx (op1, NULL_RTX);
        !          4744: 
        !          4745:                  if (op1)
        !          4746:                    op1 = equiv_constant (op1);
        !          4747: 
        !          4748:                  /* If we are looking for the low SImode part of 
        !          4749:                     (ashift:DI c (const_int 32)), it doesn't work
        !          4750:                     to compute that in SImode, because a 32-bit shift
        !          4751:                     in SImode is unpredictable.  We know the value is 0.  */
        !          4752:                  if (op0 && op1
        !          4753:                      && (GET_CODE (elt->exp) == ASHIFT
        !          4754:                          || GET_CODE (elt->exp) == LSHIFT)
        !          4755:                      && GET_CODE (op1) == CONST_INT
        !          4756:                      && INTVAL (op1) >= GET_MODE_BITSIZE (mode))
        !          4757:                    {
        !          4758:                      if (INTVAL (op1) < GET_MODE_BITSIZE (GET_MODE (elt->exp)))
        !          4759:                        
        !          4760:                        /* If the count fits in the inner mode's width,
        !          4761:                           but exceeds the outer mode's width,
        !          4762:                           the value will get truncated to 0
        !          4763:                           by the subreg.  */
        !          4764:                        new = const0_rtx;
        !          4765:                      else
        !          4766:                        /* If the count exceeds even the inner mode's width,
        !          4767:                           don't fold this expression.  */
        !          4768:                        new = 0;
        !          4769:                    }
        !          4770:                  else if (op0 && op1)
        !          4771:                    new = simplify_binary_operation (GET_CODE (elt->exp), mode,
        !          4772:                                                     op0, op1);
        !          4773:                }
        !          4774: 
        !          4775:              else if (GET_CODE (elt->exp) == SUBREG
        !          4776:                       && GET_MODE (SUBREG_REG (elt->exp)) == mode
        !          4777:                       && (GET_MODE_SIZE (GET_MODE (folded_arg0))
        !          4778:                           <= UNITS_PER_WORD)
        !          4779:                       && exp_equiv_p (elt->exp, elt->exp, 1, 0))
        !          4780:                new = copy_rtx (SUBREG_REG (elt->exp));
        !          4781: 
        !          4782:              if (new)
        !          4783:                return new;
        !          4784:            }
        !          4785:        }
        !          4786: 
        !          4787:       return x;
        !          4788: 
        !          4789:     case NOT:
        !          4790:     case NEG:
        !          4791:       /* If we have (NOT Y), see if Y is known to be (NOT Z).
        !          4792:         If so, (NOT Y) simplifies to Z.  Similarly for NEG.  */
        !          4793:       new = lookup_as_function (XEXP (x, 0), code);
        !          4794:       if (new)
        !          4795:        return fold_rtx (copy_rtx (XEXP (new, 0)), insn);
        !          4796:       break;
        !          4797: 
        !          4798:     case MEM:
        !          4799:       /* If we are not actually processing an insn, don't try to find the
        !          4800:         best address.  Not only don't we care, but we could modify the
        !          4801:         MEM in an invalid way since we have no insn to validate against.  */
        !          4802:       if (insn != 0)
        !          4803:        find_best_addr (insn, &XEXP (x, 0));
        !          4804: 
        !          4805:       {
        !          4806:        /* Even if we don't fold in the insn itself,
        !          4807:           we can safely do so here, in hopes of getting a constant.  */
        !          4808:        rtx addr = fold_rtx (XEXP (x, 0), NULL_RTX);
        !          4809:        rtx base = 0;
        !          4810:        HOST_WIDE_INT offset = 0;
        !          4811: 
        !          4812:        if (GET_CODE (addr) == REG
        !          4813:            && REGNO_QTY_VALID_P (REGNO (addr))
        !          4814:            && GET_MODE (addr) == qty_mode[reg_qty[REGNO (addr)]]
        !          4815:            && qty_const[reg_qty[REGNO (addr)]] != 0)
        !          4816:          addr = qty_const[reg_qty[REGNO (addr)]];
        !          4817: 
        !          4818:        /* If address is constant, split it into a base and integer offset.  */
        !          4819:        if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == LABEL_REF)
        !          4820:          base = addr;
        !          4821:        else if (GET_CODE (addr) == CONST && GET_CODE (XEXP (addr, 0)) == PLUS
        !          4822:                 && GET_CODE (XEXP (XEXP (addr, 0), 1)) == CONST_INT)
        !          4823:          {
        !          4824:            base = XEXP (XEXP (addr, 0), 0);
        !          4825:            offset = INTVAL (XEXP (XEXP (addr, 0), 1));
        !          4826:          }
        !          4827:        else if (GET_CODE (addr) == LO_SUM
        !          4828:                 && GET_CODE (XEXP (addr, 1)) == SYMBOL_REF)
        !          4829:          base = XEXP (addr, 1);
        !          4830: 
        !          4831:        /* If this is a constant pool reference, we can fold it into its
        !          4832:           constant to allow better value tracking.  */
        !          4833:        if (base && GET_CODE (base) == SYMBOL_REF
        !          4834:            && CONSTANT_POOL_ADDRESS_P (base))
        !          4835:          {
        !          4836:            rtx constant = get_pool_constant (base);
        !          4837:            enum machine_mode const_mode = get_pool_mode (base);
        !          4838:            rtx new;
        !          4839: 
        !          4840:            if (CONSTANT_P (constant) && GET_CODE (constant) != CONST_INT)
        !          4841:              constant_pool_entries_cost = COST (constant);
        !          4842: 
        !          4843:            /* If we are loading the full constant, we have an equivalence.  */
        !          4844:            if (offset == 0 && mode == const_mode)
        !          4845:              return constant;
        !          4846: 
        !          4847:            /* If this actually isn't a constant (wierd!), we can't do
        !          4848:               anything.  Otherwise, handle the two most common cases:
        !          4849:               extracting a word from a multi-word constant, and extracting
        !          4850:               the low-order bits.  Other cases don't seem common enough to
        !          4851:               worry about.  */
        !          4852:            if (! CONSTANT_P (constant))
        !          4853:              return x;
        !          4854: 
        !          4855:            if (GET_MODE_CLASS (mode) == MODE_INT
        !          4856:                && GET_MODE_SIZE (mode) == UNITS_PER_WORD
        !          4857:                && offset % UNITS_PER_WORD == 0
        !          4858:                && (new = operand_subword (constant,
        !          4859:                                           offset / UNITS_PER_WORD,
        !          4860:                                           0, const_mode)) != 0)
        !          4861:              return new;
        !          4862: 
        !          4863:            if (((BYTES_BIG_ENDIAN
        !          4864:                  && offset == GET_MODE_SIZE (GET_MODE (constant)) - 1)
        !          4865:                 || (! BYTES_BIG_ENDIAN && offset == 0))
        !          4866:                && (new = gen_lowpart_if_possible (mode, constant)) != 0)
        !          4867:              return new;
        !          4868:          }
        !          4869: 
        !          4870:        /* If this is a reference to a label at a known position in a jump
        !          4871:           table, we also know its value.  */
        !          4872:        if (base && GET_CODE (base) == LABEL_REF)
        !          4873:          {
        !          4874:            rtx label = XEXP (base, 0);
        !          4875:            rtx table_insn = NEXT_INSN (label);
        !          4876:            
        !          4877:            if (table_insn && GET_CODE (table_insn) == JUMP_INSN
        !          4878:                && GET_CODE (PATTERN (table_insn)) == ADDR_VEC)
        !          4879:              {
        !          4880:                rtx table = PATTERN (table_insn);
        !          4881: 
        !          4882:                if (offset >= 0
        !          4883:                    && (offset / GET_MODE_SIZE (GET_MODE (table))
        !          4884:                        < XVECLEN (table, 0)))
        !          4885:                  return XVECEXP (table, 0,
        !          4886:                                  offset / GET_MODE_SIZE (GET_MODE (table)));
        !          4887:              }
        !          4888:            if (table_insn && GET_CODE (table_insn) == JUMP_INSN
        !          4889:                && GET_CODE (PATTERN (table_insn)) == ADDR_DIFF_VEC)
        !          4890:              {
        !          4891:                rtx table = PATTERN (table_insn);
        !          4892: 
        !          4893:                if (offset >= 0
        !          4894:                    && (offset / GET_MODE_SIZE (GET_MODE (table))
        !          4895:                        < XVECLEN (table, 1)))
        !          4896:                  {
        !          4897:                    offset /= GET_MODE_SIZE (GET_MODE (table));
        !          4898:                    new = gen_rtx (MINUS, Pmode, XVECEXP (table, 1, offset),
        !          4899:                                   XEXP (table, 0));
        !          4900: 
        !          4901:                    if (GET_MODE (table) != Pmode)
        !          4902:                      new = gen_rtx (TRUNCATE, GET_MODE (table), new);
        !          4903: 
        !          4904:                    return new;
        !          4905:                  }
        !          4906:              }
        !          4907:          }
        !          4908: 
        !          4909:        return x;
        !          4910:       }
        !          4911:     }
        !          4912: 
        !          4913:   const_arg0 = 0;
        !          4914:   const_arg1 = 0;
        !          4915:   const_arg2 = 0;
        !          4916:   mode_arg0 = VOIDmode;
        !          4917: 
        !          4918:   /* Try folding our operands.
        !          4919:      Then see which ones have constant values known.  */
        !          4920: 
        !          4921:   fmt = GET_RTX_FORMAT (code);
        !          4922:   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
        !          4923:     if (fmt[i] == 'e')
        !          4924:       {
        !          4925:        rtx arg = XEXP (x, i);
        !          4926:        rtx folded_arg = arg, const_arg = 0;
        !          4927:        enum machine_mode mode_arg = GET_MODE (arg);
        !          4928:        rtx cheap_arg, expensive_arg;
        !          4929:        rtx replacements[2];
        !          4930:        int j;
        !          4931: 
        !          4932:        /* Most arguments are cheap, so handle them specially.  */
        !          4933:        switch (GET_CODE (arg))
        !          4934:          {
        !          4935:          case REG:
        !          4936:            /* This is the same as calling equiv_constant; it is duplicated
        !          4937:               here for speed.  */
        !          4938:            if (REGNO_QTY_VALID_P (REGNO (arg))
        !          4939:                && qty_const[reg_qty[REGNO (arg)]] != 0
        !          4940:                && GET_CODE (qty_const[reg_qty[REGNO (arg)]]) != REG
        !          4941:                && GET_CODE (qty_const[reg_qty[REGNO (arg)]]) != PLUS)
        !          4942:              const_arg
        !          4943:                = gen_lowpart_if_possible (GET_MODE (arg),
        !          4944:                                           qty_const[reg_qty[REGNO (arg)]]);
        !          4945:            break;
        !          4946: 
        !          4947:          case CONST:
        !          4948:          case CONST_INT:
        !          4949:          case SYMBOL_REF:
        !          4950:          case LABEL_REF:
        !          4951:          case CONST_DOUBLE:
        !          4952:            const_arg = arg;
        !          4953:            break;
        !          4954: 
        !          4955: #ifdef HAVE_cc0
        !          4956:          case CC0:
        !          4957:            folded_arg = prev_insn_cc0;
        !          4958:            mode_arg = prev_insn_cc0_mode;
        !          4959:            const_arg = equiv_constant (folded_arg);
        !          4960:            break;
        !          4961: #endif
        !          4962: 
        !          4963:          default:
        !          4964:            folded_arg = fold_rtx (arg, insn);
        !          4965:            const_arg = equiv_constant (folded_arg);
        !          4966:          }
        !          4967: 
        !          4968:        /* For the first three operands, see if the operand
        !          4969:           is constant or equivalent to a constant.  */
        !          4970:        switch (i)
        !          4971:          {
        !          4972:          case 0:
        !          4973:            folded_arg0 = folded_arg;
        !          4974:            const_arg0 = const_arg;
        !          4975:            mode_arg0 = mode_arg;
        !          4976:            break;
        !          4977:          case 1:
        !          4978:            folded_arg1 = folded_arg;
        !          4979:            const_arg1 = const_arg;
        !          4980:            break;
        !          4981:          case 2:
        !          4982:            const_arg2 = const_arg;
        !          4983:            break;
        !          4984:          }
        !          4985: 
        !          4986:        /* Pick the least expensive of the folded argument and an
        !          4987:           equivalent constant argument.  */
        !          4988:        if (const_arg == 0 || const_arg == folded_arg
        !          4989:            || COST (const_arg) > COST (folded_arg))
        !          4990:          cheap_arg = folded_arg, expensive_arg = const_arg;
        !          4991:        else
        !          4992:          cheap_arg = const_arg, expensive_arg = folded_arg;
        !          4993: 
        !          4994:        /* Try to replace the operand with the cheapest of the two
        !          4995:           possibilities.  If it doesn't work and this is either of the first
        !          4996:           two operands of a commutative operation, try swapping them.
        !          4997:           If THAT fails, try the more expensive, provided it is cheaper
        !          4998:           than what is already there.  */
        !          4999: 
        !          5000:        if (cheap_arg == XEXP (x, i))
        !          5001:          continue;
        !          5002: 
        !          5003:        if (insn == 0 && ! copied)
        !          5004:          {
        !          5005:            x = copy_rtx (x);
        !          5006:            copied = 1;
        !          5007:          }
        !          5008: 
        !          5009:        replacements[0] = cheap_arg, replacements[1] = expensive_arg;
        !          5010:        for (j = 0;
        !          5011:             j < 2 && replacements[j]
        !          5012:             && COST (replacements[j]) < COST (XEXP (x, i));
        !          5013:             j++)
        !          5014:          {
        !          5015:            if (validate_change (insn, &XEXP (x, i), replacements[j], 0))
        !          5016:              break;
        !          5017: 
        !          5018:            if (code == NE || code == EQ || GET_RTX_CLASS (code) == 'c')
        !          5019:              {
        !          5020:                validate_change (insn, &XEXP (x, i), XEXP (x, 1 - i), 1);
        !          5021:                validate_change (insn, &XEXP (x, 1 - i), replacements[j], 1);
        !          5022: 
        !          5023:                if (apply_change_group ())
        !          5024:                  {
        !          5025:                    /* Swap them back to be invalid so that this loop can
        !          5026:                       continue and flag them to be swapped back later.  */
        !          5027:                    rtx tem;
        !          5028: 
        !          5029:                    tem = XEXP (x, 0); XEXP (x, 0) = XEXP (x, 1);
        !          5030:                                       XEXP (x, 1) = tem;
        !          5031:                    must_swap = 1;
        !          5032:                    break;
        !          5033:                  }
        !          5034:              }
        !          5035:          }
        !          5036:       }
        !          5037: 
        !          5038:     else if (fmt[i] == 'E')
        !          5039:       /* Don't try to fold inside of a vector of expressions.
        !          5040:         Doing nothing is harmless.  */
        !          5041:       ;
        !          5042: 
        !          5043:   /* If a commutative operation, place a constant integer as the second
        !          5044:      operand unless the first operand is also a constant integer.  Otherwise,
        !          5045:      place any constant second unless the first operand is also a constant.  */
        !          5046: 
        !          5047:   if (code == EQ || code == NE || GET_RTX_CLASS (code) == 'c')
        !          5048:     {
        !          5049:       if (must_swap || (const_arg0
        !          5050:                        && (const_arg1 == 0
        !          5051:                            || (GET_CODE (const_arg0) == CONST_INT
        !          5052:                                && GET_CODE (const_arg1) != CONST_INT))))
        !          5053:        {
        !          5054:          register rtx tem = XEXP (x, 0);
        !          5055: 
        !          5056:          if (insn == 0 && ! copied)
        !          5057:            {
        !          5058:              x = copy_rtx (x);
        !          5059:              copied = 1;
        !          5060:            }
        !          5061: 
        !          5062:          validate_change (insn, &XEXP (x, 0), XEXP (x, 1), 1);
        !          5063:          validate_change (insn, &XEXP (x, 1), tem, 1);
        !          5064:          if (apply_change_group ())
        !          5065:            {
        !          5066:              tem = const_arg0, const_arg0 = const_arg1, const_arg1 = tem;
        !          5067:              tem = folded_arg0, folded_arg0 = folded_arg1, folded_arg1 = tem;
        !          5068:            }
        !          5069:        }
        !          5070:     }
        !          5071: 
        !          5072:   /* If X is an arithmetic operation, see if we can simplify it.  */
        !          5073: 
        !          5074:   switch (GET_RTX_CLASS (code))
        !          5075:     {
        !          5076:     case '1':
        !          5077:       /* We can't simplify extension ops unless we know the original mode.  */
        !          5078:       if ((code == ZERO_EXTEND || code == SIGN_EXTEND)
        !          5079:          && mode_arg0 == VOIDmode)
        !          5080:        break;
        !          5081:       new = simplify_unary_operation (code, mode,
        !          5082:                                      const_arg0 ? const_arg0 : folded_arg0,
        !          5083:                                      mode_arg0);
        !          5084:       break;
        !          5085:       
        !          5086:     case '<':
        !          5087:       /* See what items are actually being compared and set FOLDED_ARG[01]
        !          5088:         to those values and CODE to the actual comparison code.  If any are
        !          5089:         constant, set CONST_ARG0 and CONST_ARG1 appropriately.  We needn't
        !          5090:         do anything if both operands are already known to be constant.  */
        !          5091: 
        !          5092:       if (const_arg0 == 0 || const_arg1 == 0)
        !          5093:        {
        !          5094:          struct table_elt *p0, *p1;
        !          5095:          rtx true = const_true_rtx, false = const0_rtx;
        !          5096:          enum machine_mode mode_arg1;
        !          5097: 
        !          5098: #ifdef FLOAT_STORE_FLAG_VALUE
        !          5099:          if (GET_MODE_CLASS (mode) == MODE_FLOAT)
        !          5100:            {
        !          5101:              true = immed_real_const_1 (FLOAT_STORE_FLAG_VALUE, mode);
        !          5102:              false = CONST0_RTX (mode);
        !          5103:            }
        !          5104: #endif
        !          5105: 
        !          5106:          code = find_comparison_args (code, &folded_arg0, &folded_arg1,
        !          5107:                                       &mode_arg0, &mode_arg1);
        !          5108:          const_arg0 = equiv_constant (folded_arg0);
        !          5109:          const_arg1 = equiv_constant (folded_arg1);
        !          5110: 
        !          5111:          /* If the mode is VOIDmode or a MODE_CC mode, we don't know
        !          5112:             what kinds of things are being compared, so we can't do
        !          5113:             anything with this comparison.  */
        !          5114: 
        !          5115:          if (mode_arg0 == VOIDmode || GET_MODE_CLASS (mode_arg0) == MODE_CC)
        !          5116:            break;
        !          5117: 
        !          5118:          /* If we do not now have two constants being compared, see if we
        !          5119:             can nevertheless deduce some things about the comparison.  */
        !          5120:          if (const_arg0 == 0 || const_arg1 == 0)
        !          5121:            {
        !          5122:              /* Is FOLDED_ARG0 frame-pointer plus a constant?  Or non-explicit
        !          5123:                 constant?  These aren't zero, but we don't know their sign. */
        !          5124:              if (const_arg1 == const0_rtx
        !          5125:                  && (NONZERO_BASE_PLUS_P (folded_arg0)
        !          5126: #if 0  /* Sad to say, on sysvr4, #pragma weak can make a symbol address
        !          5127:          come out as 0.  */
        !          5128:                      || GET_CODE (folded_arg0) == SYMBOL_REF
        !          5129: #endif
        !          5130:                      || GET_CODE (folded_arg0) == LABEL_REF
        !          5131:                      || GET_CODE (folded_arg0) == CONST))
        !          5132:                {
        !          5133:                  if (code == EQ)
        !          5134:                    return false;
        !          5135:                  else if (code == NE)
        !          5136:                    return true;
        !          5137:                }
        !          5138: 
        !          5139:              /* See if the two operands are the same.  We don't do this
        !          5140:                 for IEEE floating-point since we can't assume x == x
        !          5141:                 since x might be a NaN.  */
        !          5142: 
        !          5143:              if ((TARGET_FLOAT_FORMAT != IEEE_FLOAT_FORMAT
        !          5144:                   || ! FLOAT_MODE_P (mode_arg0))
        !          5145:                  && (folded_arg0 == folded_arg1
        !          5146:                      || (GET_CODE (folded_arg0) == REG
        !          5147:                          && GET_CODE (folded_arg1) == REG
        !          5148:                          && (reg_qty[REGNO (folded_arg0)]
        !          5149:                              == reg_qty[REGNO (folded_arg1)]))
        !          5150:                      || ((p0 = lookup (folded_arg0,
        !          5151:                                        (safe_hash (folded_arg0, mode_arg0)
        !          5152:                                         % NBUCKETS), mode_arg0))
        !          5153:                          && (p1 = lookup (folded_arg1,
        !          5154:                                           (safe_hash (folded_arg1, mode_arg0)
        !          5155:                                            % NBUCKETS), mode_arg0))
        !          5156:                          && p0->first_same_value == p1->first_same_value)))
        !          5157:                return ((code == EQ || code == LE || code == GE
        !          5158:                         || code == LEU || code == GEU)
        !          5159:                        ? true : false);
        !          5160: 
        !          5161:              /* If FOLDED_ARG0 is a register, see if the comparison we are
        !          5162:                 doing now is either the same as we did before or the reverse
        !          5163:                 (we only check the reverse if not floating-point).  */
        !          5164:              else if (GET_CODE (folded_arg0) == REG)
        !          5165:                {
        !          5166:                  int qty = reg_qty[REGNO (folded_arg0)];
        !          5167: 
        !          5168:                  if (REGNO_QTY_VALID_P (REGNO (folded_arg0))
        !          5169:                      && (comparison_dominates_p (qty_comparison_code[qty], code)
        !          5170:                          || (comparison_dominates_p (qty_comparison_code[qty],
        !          5171:                                                      reverse_condition (code))
        !          5172:                              && ! FLOAT_MODE_P (mode_arg0)))
        !          5173:                      && (rtx_equal_p (qty_comparison_const[qty], folded_arg1)
        !          5174:                          || (const_arg1
        !          5175:                              && rtx_equal_p (qty_comparison_const[qty],
        !          5176:                                              const_arg1))
        !          5177:                          || (GET_CODE (folded_arg1) == REG
        !          5178:                              && (reg_qty[REGNO (folded_arg1)]
        !          5179:                                  == qty_comparison_qty[qty]))))
        !          5180:                    return (comparison_dominates_p (qty_comparison_code[qty],
        !          5181:                                                    code)
        !          5182:                            ? true : false);
        !          5183:                }
        !          5184:            }
        !          5185:        }
        !          5186: 
        !          5187:       /* If we are comparing against zero, see if the first operand is
        !          5188:         equivalent to an IOR with a constant.  If so, we may be able to
        !          5189:         determine the result of this comparison.  */
        !          5190: 
        !          5191:       if (const_arg1 == const0_rtx)
        !          5192:        {
        !          5193:          rtx y = lookup_as_function (folded_arg0, IOR);
        !          5194:          rtx inner_const;
        !          5195: 
        !          5196:          if (y != 0
        !          5197:              && (inner_const = equiv_constant (XEXP (y, 1))) != 0
        !          5198:              && GET_CODE (inner_const) == CONST_INT
        !          5199:              && INTVAL (inner_const) != 0)
        !          5200:            {
        !          5201:              int sign_bitnum = GET_MODE_BITSIZE (mode_arg0) - 1;
        !          5202:              int has_sign = (HOST_BITS_PER_WIDE_INT >= sign_bitnum
        !          5203:                              && (INTVAL (inner_const)
        !          5204:                                  & ((HOST_WIDE_INT) 1 << sign_bitnum)));
        !          5205:              rtx true = const_true_rtx, false = const0_rtx;
        !          5206: 
        !          5207: #ifdef FLOAT_STORE_FLAG_VALUE
        !          5208:              if (GET_MODE_CLASS (mode) == MODE_FLOAT)
        !          5209:                {
        !          5210:                  true = immed_real_const_1 (FLOAT_STORE_FLAG_VALUE, mode);
        !          5211:                  false = CONST0_RTX (mode);
        !          5212:                }
        !          5213: #endif
        !          5214: 
        !          5215:              switch (code)
        !          5216:                {
        !          5217:                case EQ:
        !          5218:                  return false;
        !          5219:                case NE:
        !          5220:                  return true;
        !          5221:                case LT:  case LE:
        !          5222:                  if (has_sign)
        !          5223:                    return true;
        !          5224:                  break;
        !          5225:                case GT:  case GE:
        !          5226:                  if (has_sign)
        !          5227:                    return false;
        !          5228:                  break;
        !          5229:                }
        !          5230:            }
        !          5231:        }
        !          5232: 
        !          5233:       new = simplify_relational_operation (code, mode_arg0,
        !          5234:                                           const_arg0 ? const_arg0 : folded_arg0,
        !          5235:                                           const_arg1 ? const_arg1 : folded_arg1);
        !          5236: #ifdef FLOAT_STORE_FLAG_VALUE
        !          5237:       if (new != 0 && GET_MODE_CLASS (mode) == MODE_FLOAT)
        !          5238:        new = ((new == const0_rtx) ? CONST0_RTX (mode)
        !          5239:               : immed_real_const_1 (FLOAT_STORE_FLAG_VALUE, mode));
        !          5240: #endif
        !          5241:       break;
        !          5242: 
        !          5243:     case '2':
        !          5244:     case 'c':
        !          5245:       switch (code)
        !          5246:        {
        !          5247:        case PLUS:
        !          5248:          /* If the second operand is a LABEL_REF, see if the first is a MINUS
        !          5249:             with that LABEL_REF as its second operand.  If so, the result is
        !          5250:             the first operand of that MINUS.  This handles switches with an
        !          5251:             ADDR_DIFF_VEC table.  */
        !          5252:          if (const_arg1 && GET_CODE (const_arg1) == LABEL_REF)
        !          5253:            {
        !          5254:              rtx y = lookup_as_function (folded_arg0, MINUS);
        !          5255: 
        !          5256:              if (y != 0 && GET_CODE (XEXP (y, 1)) == LABEL_REF
        !          5257:                  && XEXP (XEXP (y, 1), 0) == XEXP (const_arg1, 0))
        !          5258:                return XEXP (y, 0);
        !          5259:            }
        !          5260:          goto from_plus;
        !          5261: 
        !          5262:        case MINUS:
        !          5263:          /* If we have (MINUS Y C), see if Y is known to be (PLUS Z C2).
        !          5264:             If so, produce (PLUS Z C2-C).  */
        !          5265:          if (const_arg1 != 0 && GET_CODE (const_arg1) == CONST_INT)
        !          5266:            {
        !          5267:              rtx y = lookup_as_function (XEXP (x, 0), PLUS);
        !          5268:              if (y && GET_CODE (XEXP (y, 1)) == CONST_INT)
        !          5269:                return fold_rtx (plus_constant (copy_rtx (y),
        !          5270:                                                -INTVAL (const_arg1)),
        !          5271:                                 NULL_RTX);
        !          5272:            }
        !          5273: 
        !          5274:          /* ... fall through ... */
        !          5275: 
        !          5276:        from_plus:
        !          5277:        case SMIN:    case SMAX:      case UMIN:    case UMAX:
        !          5278:        case IOR:     case AND:       case XOR:
        !          5279:        case MULT:    case DIV:       case UDIV:
        !          5280:        case ASHIFT:  case LSHIFTRT:  case ASHIFTRT:
        !          5281:          /* If we have (<op> <reg> <const_int>) for an associative OP and REG
        !          5282:             is known to be of similar form, we may be able to replace the
        !          5283:             operation with a combined operation.  This may eliminate the
        !          5284:             intermediate operation if every use is simplified in this way.
        !          5285:             Note that the similar optimization done by combine.c only works
        !          5286:             if the intermediate operation's result has only one reference.  */
        !          5287: 
        !          5288:          if (GET_CODE (folded_arg0) == REG
        !          5289:              && const_arg1 && GET_CODE (const_arg1) == CONST_INT)
        !          5290:            {
        !          5291:              int is_shift
        !          5292:                = (code == ASHIFT || code == ASHIFTRT || code == LSHIFTRT);
        !          5293:              rtx y = lookup_as_function (folded_arg0, code);
        !          5294:              rtx inner_const;
        !          5295:              enum rtx_code associate_code;
        !          5296:              rtx new_const;
        !          5297: 
        !          5298:              if (y == 0
        !          5299:                  || 0 == (inner_const
        !          5300:                           = equiv_constant (fold_rtx (XEXP (y, 1), 0)))
        !          5301:                  || GET_CODE (inner_const) != CONST_INT
        !          5302:                  /* If we have compiled a statement like
        !          5303:                     "if (x == (x & mask1))", and now are looking at
        !          5304:                     "x & mask2", we will have a case where the first operand
        !          5305:                     of Y is the same as our first operand.  Unless we detect
        !          5306:                     this case, an infinite loop will result.  */
        !          5307:                  || XEXP (y, 0) == folded_arg0)
        !          5308:                break;
        !          5309: 
        !          5310:              /* Don't associate these operations if they are a PLUS with the
        !          5311:                 same constant and it is a power of two.  These might be doable
        !          5312:                 with a pre- or post-increment.  Similarly for two subtracts of
        !          5313:                 identical powers of two with post decrement.  */
        !          5314: 
        !          5315:              if (code == PLUS && INTVAL (const_arg1) == INTVAL (inner_const)
        !          5316:                  && (0
        !          5317: #if defined(HAVE_PRE_INCREMENT) || defined(HAVE_POST_INCREMENT)
        !          5318:                      || exact_log2 (INTVAL (const_arg1)) >= 0
        !          5319: #endif
        !          5320: #if defined(HAVE_PRE_DECREMENT) || defined(HAVE_POST_DECREMENT)
        !          5321:                      || exact_log2 (- INTVAL (const_arg1)) >= 0
        !          5322: #endif
        !          5323:                  ))
        !          5324:                break;
        !          5325: 
        !          5326:              /* Compute the code used to compose the constants.  For example,
        !          5327:                 A/C1/C2 is A/(C1 * C2), so if CODE == DIV, we want MULT.  */
        !          5328: 
        !          5329:              associate_code
        !          5330:                = (code == MULT || code == DIV || code == UDIV ? MULT
        !          5331:                   : is_shift || code == PLUS || code == MINUS ? PLUS : code);
        !          5332: 
        !          5333:              new_const = simplify_binary_operation (associate_code, mode,
        !          5334:                                                     const_arg1, inner_const);
        !          5335: 
        !          5336:              if (new_const == 0)
        !          5337:                break;
        !          5338: 
        !          5339:              /* If we are associating shift operations, don't let this
        !          5340:                 produce a shift of the size of the object or larger.
        !          5341:                 This could occur when we follow a sign-extend by a right
        !          5342:                 shift on a machine that does a sign-extend as a pair
        !          5343:                 of shifts.  */
        !          5344: 
        !          5345:              if (is_shift && GET_CODE (new_const) == CONST_INT
        !          5346:                  && INTVAL (new_const) >= GET_MODE_BITSIZE (mode))
        !          5347:                {
        !          5348:                  /* As an exception, we can turn an ASHIFTRT of this
        !          5349:                     form into a shift of the number of bits - 1.  */
        !          5350:                  if (code == ASHIFTRT)
        !          5351:                    new_const = GEN_INT (GET_MODE_BITSIZE (mode) - 1);
        !          5352:                  else
        !          5353:                    break;
        !          5354:                }
        !          5355: 
        !          5356:              y = copy_rtx (XEXP (y, 0));
        !          5357: 
        !          5358:              /* If Y contains our first operand (the most common way this
        !          5359:                 can happen is if Y is a MEM), we would do into an infinite
        !          5360:                 loop if we tried to fold it.  So don't in that case.  */
        !          5361: 
        !          5362:              if (! reg_mentioned_p (folded_arg0, y))
        !          5363:                y = fold_rtx (y, insn);
        !          5364: 
        !          5365:              return cse_gen_binary (code, mode, y, new_const);
        !          5366:            }
        !          5367:        }
        !          5368: 
        !          5369:       new = simplify_binary_operation (code, mode,
        !          5370:                                       const_arg0 ? const_arg0 : folded_arg0,
        !          5371:                                       const_arg1 ? const_arg1 : folded_arg1);
        !          5372:       break;
        !          5373: 
        !          5374:     case 'o':
        !          5375:       /* (lo_sum (high X) X) is simply X.  */
        !          5376:       if (code == LO_SUM && const_arg0 != 0
        !          5377:          && GET_CODE (const_arg0) == HIGH
        !          5378:          && rtx_equal_p (XEXP (const_arg0, 0), const_arg1))
        !          5379:        return const_arg1;
        !          5380:       break;
        !          5381: 
        !          5382:     case '3':
        !          5383:     case 'b':
        !          5384:       new = simplify_ternary_operation (code, mode, mode_arg0,
        !          5385:                                        const_arg0 ? const_arg0 : folded_arg0,
        !          5386:                                        const_arg1 ? const_arg1 : folded_arg1,
        !          5387:                                        const_arg2 ? const_arg2 : XEXP (x, 2));
        !          5388:       break;
        !          5389:     }
        !          5390: 
        !          5391:   return new ? new : x;
        !          5392: }
        !          5393: 
        !          5394: /* Return a constant value currently equivalent to X.
        !          5395:    Return 0 if we don't know one.  */
        !          5396: 
        !          5397: static rtx
        !          5398: equiv_constant (x)
        !          5399:      rtx x;
        !          5400: {
        !          5401:   if (GET_CODE (x) == REG
        !          5402:       && REGNO_QTY_VALID_P (REGNO (x))
        !          5403:       && qty_const[reg_qty[REGNO (x)]])
        !          5404:     x = gen_lowpart_if_possible (GET_MODE (x), qty_const[reg_qty[REGNO (x)]]);
        !          5405: 
        !          5406:   if (x != 0 && CONSTANT_P (x))
        !          5407:     return x;
        !          5408: 
        !          5409:   /* If X is a MEM, try to fold it outside the context of any insn to see if
        !          5410:      it might be equivalent to a constant.  That handles the case where it
        !          5411:      is a constant-pool reference.  Then try to look it up in the hash table
        !          5412:      in case it is something whose value we have seen before.  */
        !          5413: 
        !          5414:   if (GET_CODE (x) == MEM)
        !          5415:     {
        !          5416:       struct table_elt *elt;
        !          5417: 
        !          5418:       x = fold_rtx (x, NULL_RTX);
        !          5419:       if (CONSTANT_P (x))
        !          5420:        return x;
        !          5421: 
        !          5422:       elt = lookup (x, safe_hash (x, GET_MODE (x)) % NBUCKETS, GET_MODE (x));
        !          5423:       if (elt == 0)
        !          5424:        return 0;
        !          5425: 
        !          5426:       for (elt = elt->first_same_value; elt; elt = elt->next_same_value)
        !          5427:        if (elt->is_const && CONSTANT_P (elt->exp))
        !          5428:          return elt->exp;
        !          5429:     }
        !          5430: 
        !          5431:   return 0;
        !          5432: }
        !          5433: 
        !          5434: /* Assuming that X is an rtx (e.g., MEM, REG or SUBREG) for a fixed-point
        !          5435:    number, return an rtx (MEM, SUBREG, or CONST_INT) that refers to the
        !          5436:    least-significant part of X.
        !          5437:    MODE specifies how big a part of X to return.  
        !          5438: 
        !          5439:    If the requested operation cannot be done, 0 is returned.
        !          5440: 
        !          5441:    This is similar to gen_lowpart in emit-rtl.c.  */
        !          5442: 
        !          5443: rtx
        !          5444: gen_lowpart_if_possible (mode, x)
        !          5445:      enum machine_mode mode;
        !          5446:      register rtx x;
        !          5447: {
        !          5448:   rtx result = gen_lowpart_common (mode, x);
        !          5449: 
        !          5450:   if (result)
        !          5451:     return result;
        !          5452:   else if (GET_CODE (x) == MEM)
        !          5453:     {
        !          5454:       /* This is the only other case we handle.  */
        !          5455:       register int offset = 0;
        !          5456:       rtx new;
        !          5457: 
        !          5458: #if WORDS_BIG_ENDIAN
        !          5459:       offset = (MAX (GET_MODE_SIZE (GET_MODE (x)), UNITS_PER_WORD)
        !          5460:                - MAX (GET_MODE_SIZE (mode), UNITS_PER_WORD));
        !          5461: #endif
        !          5462: #if BYTES_BIG_ENDIAN
        !          5463:       /* Adjust the address so that the address-after-the-data
        !          5464:         is unchanged.  */
        !          5465:       offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (mode))
        !          5466:                 - MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (x))));
        !          5467: #endif
        !          5468:       new = gen_rtx (MEM, mode, plus_constant (XEXP (x, 0), offset));
        !          5469:       if (! memory_address_p (mode, XEXP (new, 0)))
        !          5470:        return 0;
        !          5471:       MEM_VOLATILE_P (new) = MEM_VOLATILE_P (x);
        !          5472:       RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (x);
        !          5473:       MEM_IN_STRUCT_P (new) = MEM_IN_STRUCT_P (x);
        !          5474:       return new;
        !          5475:     }
        !          5476:   else
        !          5477:     return 0;
        !          5478: }
        !          5479: 
        !          5480: /* Given INSN, a jump insn, TAKEN indicates if we are following the "taken"
        !          5481:    branch.  It will be zero if not.
        !          5482: 
        !          5483:    In certain cases, this can cause us to add an equivalence.  For example,
        !          5484:    if we are following the taken case of 
        !          5485:        if (i == 2)
        !          5486:    we can add the fact that `i' and '2' are now equivalent.
        !          5487: 
        !          5488:    In any case, we can record that this comparison was passed.  If the same
        !          5489:    comparison is seen later, we will know its value.  */
        !          5490: 
        !          5491: static void
        !          5492: record_jump_equiv (insn, taken)
        !          5493:      rtx insn;
        !          5494:      int taken;
        !          5495: {
        !          5496:   int cond_known_true;
        !          5497:   rtx op0, op1;
        !          5498:   enum machine_mode mode, mode0, mode1;
        !          5499:   int reversed_nonequality = 0;
        !          5500:   enum rtx_code code;
        !          5501: 
        !          5502:   /* Ensure this is the right kind of insn.  */
        !          5503:   if (! condjump_p (insn) || simplejump_p (insn))
        !          5504:     return;
        !          5505: 
        !          5506:   /* See if this jump condition is known true or false.  */
        !          5507:   if (taken)
        !          5508:     cond_known_true = (XEXP (SET_SRC (PATTERN (insn)), 2) == pc_rtx);
        !          5509:   else
        !          5510:     cond_known_true = (XEXP (SET_SRC (PATTERN (insn)), 1) == pc_rtx);
        !          5511: 
        !          5512:   /* Get the type of comparison being done and the operands being compared.
        !          5513:      If we had to reverse a non-equality condition, record that fact so we
        !          5514:      know that it isn't valid for floating-point.  */
        !          5515:   code = GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 0));
        !          5516:   op0 = fold_rtx (XEXP (XEXP (SET_SRC (PATTERN (insn)), 0), 0), insn);
        !          5517:   op1 = fold_rtx (XEXP (XEXP (SET_SRC (PATTERN (insn)), 0), 1), insn);
        !          5518: 
        !          5519:   code = find_comparison_args (code, &op0, &op1, &mode0, &mode1);
        !          5520:   if (! cond_known_true)
        !          5521:     {
        !          5522:       reversed_nonequality = (code != EQ && code != NE);
        !          5523:       code = reverse_condition (code);
        !          5524:     }
        !          5525: 
        !          5526:   /* The mode is the mode of the non-constant.  */
        !          5527:   mode = mode0;
        !          5528:   if (mode1 != VOIDmode)
        !          5529:     mode = mode1;
        !          5530: 
        !          5531:   record_jump_cond (code, mode, op0, op1, reversed_nonequality);
        !          5532: }
        !          5533: 
        !          5534: /* We know that comparison CODE applied to OP0 and OP1 in MODE is true.
        !          5535:    REVERSED_NONEQUALITY is nonzero if CODE had to be swapped.
        !          5536:    Make any useful entries we can with that information.  Called from
        !          5537:    above function and called recursively.  */
        !          5538: 
        !          5539: static void
        !          5540: record_jump_cond (code, mode, op0, op1, reversed_nonequality)
        !          5541:      enum rtx_code code;
        !          5542:      enum machine_mode mode;
        !          5543:      rtx op0, op1;
        !          5544:      int reversed_nonequality;
        !          5545: {
        !          5546:   int op0_hash_code, op1_hash_code;
        !          5547:   int op0_in_memory, op0_in_struct, op1_in_memory, op1_in_struct;
        !          5548:   struct table_elt *op0_elt, *op1_elt;
        !          5549: 
        !          5550:   /* If OP0 and OP1 are known equal, and either is a paradoxical SUBREG,
        !          5551:      we know that they are also equal in the smaller mode (this is also
        !          5552:      true for all smaller modes whether or not there is a SUBREG, but
        !          5553:      is not worth testing for with no SUBREG.  */
        !          5554: 
        !          5555:   /* Note that GET_MODE (op0) may not equal MODE.  */
        !          5556:   if (code == EQ && GET_CODE (op0) == SUBREG
        !          5557:       && (GET_MODE_SIZE (GET_MODE (op0))
        !          5558:          > GET_MODE_SIZE (GET_MODE (SUBREG_REG (op0)))))
        !          5559:     {
        !          5560:       enum machine_mode inner_mode = GET_MODE (SUBREG_REG (op0));
        !          5561:       rtx tem = gen_lowpart_if_possible (inner_mode, op1);
        !          5562: 
        !          5563:       record_jump_cond (code, mode, SUBREG_REG (op0),
        !          5564:                        tem ? tem : gen_rtx (SUBREG, inner_mode, op1, 0),
        !          5565:                        reversed_nonequality);
        !          5566:     }
        !          5567: 
        !          5568:   if (code == EQ && GET_CODE (op1) == SUBREG
        !          5569:       && (GET_MODE_SIZE (GET_MODE (op1))
        !          5570:          > GET_MODE_SIZE (GET_MODE (SUBREG_REG (op1)))))
        !          5571:     {
        !          5572:       enum machine_mode inner_mode = GET_MODE (SUBREG_REG (op1));
        !          5573:       rtx tem = gen_lowpart_if_possible (inner_mode, op0);
        !          5574: 
        !          5575:       record_jump_cond (code, mode, SUBREG_REG (op1),
        !          5576:                        tem ? tem : gen_rtx (SUBREG, inner_mode, op0, 0),
        !          5577:                        reversed_nonequality);
        !          5578:     }
        !          5579: 
        !          5580:   /* Similarly, if this is an NE comparison, and either is a SUBREG 
        !          5581:      making a smaller mode, we know the whole thing is also NE.  */
        !          5582: 
        !          5583:   /* Note that GET_MODE (op0) may not equal MODE;
        !          5584:      if we test MODE instead, we can get an infinite recursion
        !          5585:      alternating between two modes each wider than MODE.  */
        !          5586: 
        !          5587:   if (code == NE && GET_CODE (op0) == SUBREG
        !          5588:       && subreg_lowpart_p (op0)
        !          5589:       && (GET_MODE_SIZE (GET_MODE (op0))
        !          5590:          < GET_MODE_SIZE (GET_MODE (SUBREG_REG (op0)))))
        !          5591:     {
        !          5592:       enum machine_mode inner_mode = GET_MODE (SUBREG_REG (op0));
        !          5593:       rtx tem = gen_lowpart_if_possible (inner_mode, op1);
        !          5594: 
        !          5595:       record_jump_cond (code, mode, SUBREG_REG (op0),
        !          5596:                        tem ? tem : gen_rtx (SUBREG, inner_mode, op1, 0),
        !          5597:                        reversed_nonequality);
        !          5598:     }
        !          5599: 
        !          5600:   if (code == NE && GET_CODE (op1) == SUBREG
        !          5601:       && subreg_lowpart_p (op1)
        !          5602:       && (GET_MODE_SIZE (GET_MODE (op1))
        !          5603:          < GET_MODE_SIZE (GET_MODE (SUBREG_REG (op1)))))
        !          5604:     {
        !          5605:       enum machine_mode inner_mode = GET_MODE (SUBREG_REG (op1));
        !          5606:       rtx tem = gen_lowpart_if_possible (inner_mode, op0);
        !          5607: 
        !          5608:       record_jump_cond (code, mode, SUBREG_REG (op1),
        !          5609:                        tem ? tem : gen_rtx (SUBREG, inner_mode, op0, 0),
        !          5610:                        reversed_nonequality);
        !          5611:     }
        !          5612: 
        !          5613:   /* Hash both operands.  */
        !          5614: 
        !          5615:   do_not_record = 0;
        !          5616:   hash_arg_in_memory = 0;
        !          5617:   hash_arg_in_struct = 0;
        !          5618:   op0_hash_code = HASH (op0, mode);
        !          5619:   op0_in_memory = hash_arg_in_memory;
        !          5620:   op0_in_struct = hash_arg_in_struct;
        !          5621: 
        !          5622:   if (do_not_record)
        !          5623:     return;
        !          5624: 
        !          5625:   do_not_record = 0;
        !          5626:   hash_arg_in_memory = 0;
        !          5627:   hash_arg_in_struct = 0;
        !          5628:   op1_hash_code = HASH (op1, mode);
        !          5629:   op1_in_memory = hash_arg_in_memory;
        !          5630:   op1_in_struct = hash_arg_in_struct;
        !          5631:   
        !          5632:   if (do_not_record)
        !          5633:     return;
        !          5634: 
        !          5635:   /* Look up both operands.  */
        !          5636:   op0_elt = lookup (op0, op0_hash_code, mode);
        !          5637:   op1_elt = lookup (op1, op1_hash_code, mode);
        !          5638: 
        !          5639:   /* If we aren't setting two things equal all we can do is save this
        !          5640:      comparison.   Similarly if this is floating-point.  In the latter
        !          5641:      case, OP1 might be zero and both -0.0 and 0.0 are equal to it.
        !          5642:      If we record the equality, we might inadvertently delete code
        !          5643:      whose intent was to change -0 to +0.  */
        !          5644: 
        !          5645:   if (code != EQ || FLOAT_MODE_P (GET_MODE (op0)))
        !          5646:     {
        !          5647:       /* If we reversed a floating-point comparison, if OP0 is not a
        !          5648:         register, or if OP1 is neither a register or constant, we can't
        !          5649:         do anything.  */
        !          5650: 
        !          5651:       if (GET_CODE (op1) != REG)
        !          5652:        op1 = equiv_constant (op1);
        !          5653: 
        !          5654:       if ((reversed_nonequality && FLOAT_MODE_P (mode))
        !          5655:          || GET_CODE (op0) != REG || op1 == 0)
        !          5656:        return;
        !          5657: 
        !          5658:       /* Put OP0 in the hash table if it isn't already.  This gives it a
        !          5659:         new quantity number.  */
        !          5660:       if (op0_elt == 0)
        !          5661:        {
        !          5662:          if (insert_regs (op0, NULL_PTR, 0))
        !          5663:            {
        !          5664:              rehash_using_reg (op0);
        !          5665:              op0_hash_code = HASH (op0, mode);
        !          5666: 
        !          5667:              /* If OP0 is contained in OP1, this changes its hash code
        !          5668:                 as well.  Faster to rehash than to check, except
        !          5669:                 for the simple case of a constant.  */
        !          5670:              if (! CONSTANT_P (op1))
        !          5671:                op1_hash_code = HASH (op1,mode);
        !          5672:            }
        !          5673: 
        !          5674:          op0_elt = insert (op0, NULL_PTR, op0_hash_code, mode);
        !          5675:          op0_elt->in_memory = op0_in_memory;
        !          5676:          op0_elt->in_struct = op0_in_struct;
        !          5677:        }
        !          5678: 
        !          5679:       qty_comparison_code[reg_qty[REGNO (op0)]] = code;
        !          5680:       if (GET_CODE (op1) == REG)
        !          5681:        {
        !          5682:          /* Look it up again--in case op0 and op1 are the same.  */
        !          5683:          op1_elt = lookup (op1, op1_hash_code, mode);
        !          5684: 
        !          5685:          /* Put OP1 in the hash table so it gets a new quantity number.  */
        !          5686:          if (op1_elt == 0)
        !          5687:            {
        !          5688:              if (insert_regs (op1, NULL_PTR, 0))
        !          5689:                {
        !          5690:                  rehash_using_reg (op1);
        !          5691:                  op1_hash_code = HASH (op1, mode);
        !          5692:                }
        !          5693: 
        !          5694:              op1_elt = insert (op1, NULL_PTR, op1_hash_code, mode);
        !          5695:              op1_elt->in_memory = op1_in_memory;
        !          5696:              op1_elt->in_struct = op1_in_struct;
        !          5697:            }
        !          5698: 
        !          5699:          qty_comparison_qty[reg_qty[REGNO (op0)]] = reg_qty[REGNO (op1)];
        !          5700:          qty_comparison_const[reg_qty[REGNO (op0)]] = 0;
        !          5701:        }
        !          5702:       else
        !          5703:        {
        !          5704:          qty_comparison_qty[reg_qty[REGNO (op0)]] = -1;
        !          5705:          qty_comparison_const[reg_qty[REGNO (op0)]] = op1;
        !          5706:        }
        !          5707: 
        !          5708:       return;
        !          5709:     }
        !          5710: 
        !          5711:   /* If either side is still missing an equivalence, make it now,
        !          5712:      then merge the equivalences.  */
        !          5713: 
        !          5714:   if (op0_elt == 0)
        !          5715:     {
        !          5716:       if (insert_regs (op0, NULL_PTR, 0))
        !          5717:        {
        !          5718:          rehash_using_reg (op0);
        !          5719:          op0_hash_code = HASH (op0, mode);
        !          5720:        }
        !          5721: 
        !          5722:       op0_elt = insert (op0, NULL_PTR, op0_hash_code, mode);
        !          5723:       op0_elt->in_memory = op0_in_memory;
        !          5724:       op0_elt->in_struct = op0_in_struct;
        !          5725:     }
        !          5726: 
        !          5727:   if (op1_elt == 0)
        !          5728:     {
        !          5729:       if (insert_regs (op1, NULL_PTR, 0))
        !          5730:        {
        !          5731:          rehash_using_reg (op1);
        !          5732:          op1_hash_code = HASH (op1, mode);
        !          5733:        }
        !          5734: 
        !          5735:       op1_elt = insert (op1, NULL_PTR, op1_hash_code, mode);
        !          5736:       op1_elt->in_memory = op1_in_memory;
        !          5737:       op1_elt->in_struct = op1_in_struct;
        !          5738:     }
        !          5739: 
        !          5740:   merge_equiv_classes (op0_elt, op1_elt);
        !          5741:   last_jump_equiv_class = op0_elt;
        !          5742: }
        !          5743: 
        !          5744: /* CSE processing for one instruction.
        !          5745:    First simplify sources and addresses of all assignments
        !          5746:    in the instruction, using previously-computed equivalents values.
        !          5747:    Then install the new sources and destinations in the table
        !          5748:    of available values. 
        !          5749: 
        !          5750:    If IN_LIBCALL_BLOCK is nonzero, don't record any equivalence made in
        !          5751:    the insn.  */
        !          5752: 
        !          5753: /* Data on one SET contained in the instruction.  */
        !          5754: 
        !          5755: struct set
        !          5756: {
        !          5757:   /* The SET rtx itself.  */
        !          5758:   rtx rtl;
        !          5759:   /* The SET_SRC of the rtx (the original value, if it is changing).  */
        !          5760:   rtx src;
        !          5761:   /* The hash-table element for the SET_SRC of the SET.  */
        !          5762:   struct table_elt *src_elt;
        !          5763:   /* Hash code for the SET_SRC.  */
        !          5764:   int src_hash_code;
        !          5765:   /* Hash code for the SET_DEST.  */
        !          5766:   int dest_hash_code;
        !          5767:   /* The SET_DEST, with SUBREG, etc., stripped.  */
        !          5768:   rtx inner_dest;
        !          5769:   /* Place where the pointer to the INNER_DEST was found.  */
        !          5770:   rtx *inner_dest_loc;
        !          5771:   /* Nonzero if the SET_SRC is in memory.  */ 
        !          5772:   char src_in_memory;
        !          5773:   /* Nonzero if the SET_SRC is in a structure.  */ 
        !          5774:   char src_in_struct;
        !          5775:   /* Nonzero if the SET_SRC contains something
        !          5776:      whose value cannot be predicted and understood.  */
        !          5777:   char src_volatile;
        !          5778:   /* Original machine mode, in case it becomes a CONST_INT.  */
        !          5779:   enum machine_mode mode;
        !          5780:   /* A constant equivalent for SET_SRC, if any.  */
        !          5781:   rtx src_const;
        !          5782:   /* Hash code of constant equivalent for SET_SRC.  */
        !          5783:   int src_const_hash_code;
        !          5784:   /* Table entry for constant equivalent for SET_SRC, if any.  */
        !          5785:   struct table_elt *src_const_elt;
        !          5786: };
        !          5787: 
        !          5788: static void
        !          5789: cse_insn (insn, in_libcall_block)
        !          5790:      rtx insn;
        !          5791:      int in_libcall_block;
        !          5792: {
        !          5793:   register rtx x = PATTERN (insn);
        !          5794:   rtx tem;
        !          5795:   register int i;
        !          5796:   register int n_sets = 0;
        !          5797: 
        !          5798:   /* Records what this insn does to set CC0.  */
        !          5799:   rtx this_insn_cc0 = 0;
        !          5800:   enum machine_mode this_insn_cc0_mode;
        !          5801:   struct write_data writes_memory;
        !          5802:   static struct write_data init = {0, 0, 0, 0};
        !          5803: 
        !          5804:   rtx src_eqv = 0;
        !          5805:   struct table_elt *src_eqv_elt = 0;
        !          5806:   int src_eqv_volatile;
        !          5807:   int src_eqv_in_memory;
        !          5808:   int src_eqv_in_struct;
        !          5809:   int src_eqv_hash_code;
        !          5810: 
        !          5811:   struct set *sets;
        !          5812: 
        !          5813:   this_insn = insn;
        !          5814:   writes_memory = init;
        !          5815: 
        !          5816:   /* Find all the SETs and CLOBBERs in this instruction.
        !          5817:      Record all the SETs in the array `set' and count them.
        !          5818:      Also determine whether there is a CLOBBER that invalidates
        !          5819:      all memory references, or all references at varying addresses.  */
        !          5820: 
        !          5821:   if (GET_CODE (x) == SET)
        !          5822:     {
        !          5823:       sets = (struct set *) alloca (sizeof (struct set));
        !          5824:       sets[0].rtl = x;
        !          5825: 
        !          5826:       /* Ignore SETs that are unconditional jumps.
        !          5827:         They never need cse processing, so this does not hurt.
        !          5828:         The reason is not efficiency but rather
        !          5829:         so that we can test at the end for instructions
        !          5830:         that have been simplified to unconditional jumps
        !          5831:         and not be misled by unchanged instructions
        !          5832:         that were unconditional jumps to begin with.  */
        !          5833:       if (SET_DEST (x) == pc_rtx
        !          5834:          && GET_CODE (SET_SRC (x)) == LABEL_REF)
        !          5835:        ;
        !          5836: 
        !          5837:       /* Don't count call-insns, (set (reg 0) (call ...)), as a set.
        !          5838:         The hard function value register is used only once, to copy to
        !          5839:         someplace else, so it isn't worth cse'ing (and on 80386 is unsafe)!
        !          5840:         Ensure we invalidate the destination register.  On the 80386 no
        !          5841:         other code would invalidate it since it is a fixed_reg.
        !          5842:         We need not check the return of apply_change_group; see canon_reg. */
        !          5843: 
        !          5844:       else if (GET_CODE (SET_SRC (x)) == CALL)
        !          5845:        {
        !          5846:          canon_reg (SET_SRC (x), insn);
        !          5847:          apply_change_group ();
        !          5848:          fold_rtx (SET_SRC (x), insn);
        !          5849:          invalidate (SET_DEST (x));
        !          5850:        }
        !          5851:       else
        !          5852:        n_sets = 1;
        !          5853:     }
        !          5854:   else if (GET_CODE (x) == PARALLEL)
        !          5855:     {
        !          5856:       register int lim = XVECLEN (x, 0);
        !          5857: 
        !          5858:       sets = (struct set *) alloca (lim * sizeof (struct set));
        !          5859: 
        !          5860:       /* Find all regs explicitly clobbered in this insn,
        !          5861:         and ensure they are not replaced with any other regs
        !          5862:         elsewhere in this insn.
        !          5863:         When a reg that is clobbered is also used for input,
        !          5864:         we should presume that that is for a reason,
        !          5865:         and we should not substitute some other register
        !          5866:         which is not supposed to be clobbered.
        !          5867:         Therefore, this loop cannot be merged into the one below
        !          5868:         because a CALL may precede a CLOBBER and refer to the
        !          5869:         value clobbered.  We must not let a canonicalization do
        !          5870:         anything in that case.  */
        !          5871:       for (i = 0; i < lim; i++)
        !          5872:        {
        !          5873:          register rtx y = XVECEXP (x, 0, i);
        !          5874:          if (GET_CODE (y) == CLOBBER)
        !          5875:            {
        !          5876:              rtx clobbered = XEXP (y, 0);
        !          5877: 
        !          5878:              if (GET_CODE (clobbered) == REG
        !          5879:                  || GET_CODE (clobbered) == SUBREG)
        !          5880:                invalidate (clobbered);
        !          5881:              else if (GET_CODE (clobbered) == STRICT_LOW_PART
        !          5882:                       || GET_CODE (clobbered) == ZERO_EXTRACT)
        !          5883:                invalidate (XEXP (clobbered, 0));
        !          5884:            }
        !          5885:        }
        !          5886:            
        !          5887:       for (i = 0; i < lim; i++)
        !          5888:        {
        !          5889:          register rtx y = XVECEXP (x, 0, i);
        !          5890:          if (GET_CODE (y) == SET)
        !          5891:            {
        !          5892:              /* As above, we ignore unconditional jumps and call-insns and
        !          5893:                 ignore the result of apply_change_group.  */
        !          5894:              if (GET_CODE (SET_SRC (y)) == CALL)
        !          5895:                {
        !          5896:                  canon_reg (SET_SRC (y), insn);
        !          5897:                  apply_change_group ();
        !          5898:                  fold_rtx (SET_SRC (y), insn);
        !          5899:                  invalidate (SET_DEST (y));
        !          5900:                }
        !          5901:              else if (SET_DEST (y) == pc_rtx
        !          5902:                       && GET_CODE (SET_SRC (y)) == LABEL_REF)
        !          5903:                ;
        !          5904:              else
        !          5905:                sets[n_sets++].rtl = y;
        !          5906:            }
        !          5907:          else if (GET_CODE (y) == CLOBBER)
        !          5908:            {
        !          5909:              /* If we clobber memory, take note of that,
        !          5910:                 and canon the address.
        !          5911:                 This does nothing when a register is clobbered
        !          5912:                 because we have already invalidated the reg.  */
        !          5913:              if (GET_CODE (XEXP (y, 0)) == MEM)
        !          5914:                {
        !          5915:                  canon_reg (XEXP (y, 0), NULL_RTX);
        !          5916:                  note_mem_written (XEXP (y, 0), &writes_memory);
        !          5917:                }
        !          5918:            }
        !          5919:          else if (GET_CODE (y) == USE
        !          5920:                   && ! (GET_CODE (XEXP (y, 0)) == REG
        !          5921:                         && REGNO (XEXP (y, 0)) < FIRST_PSEUDO_REGISTER))
        !          5922:            canon_reg (y, NULL_RTX);
        !          5923:          else if (GET_CODE (y) == CALL)
        !          5924:            {
        !          5925:              /* The result of apply_change_group can be ignored; see
        !          5926:                 canon_reg.  */
        !          5927:              canon_reg (y, insn);
        !          5928:              apply_change_group ();
        !          5929:              fold_rtx (y, insn);
        !          5930:            }
        !          5931:        }
        !          5932:     }
        !          5933:   else if (GET_CODE (x) == CLOBBER)
        !          5934:     {
        !          5935:       if (GET_CODE (XEXP (x, 0)) == MEM)
        !          5936:        {
        !          5937:          canon_reg (XEXP (x, 0), NULL_RTX);
        !          5938:          note_mem_written (XEXP (x, 0), &writes_memory);
        !          5939:        }
        !          5940:     }
        !          5941: 
        !          5942:   /* Canonicalize a USE of a pseudo register or memory location.  */
        !          5943:   else if (GET_CODE (x) == USE
        !          5944:           && ! (GET_CODE (XEXP (x, 0)) == REG
        !          5945:                 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER))
        !          5946:     canon_reg (XEXP (x, 0), NULL_RTX);
        !          5947:   else if (GET_CODE (x) == CALL)
        !          5948:     {
        !          5949:       /* The result of apply_change_group can be ignored; see canon_reg.  */
        !          5950:       canon_reg (x, insn);
        !          5951:       apply_change_group ();
        !          5952:       fold_rtx (x, insn);
        !          5953:     }
        !          5954: 
        !          5955:   if (n_sets == 1 && REG_NOTES (insn) != 0)
        !          5956:     {
        !          5957:       /* Store the equivalent value in SRC_EQV, if different.  */
        !          5958:       rtx tem = find_reg_note (insn, REG_EQUAL, NULL_RTX);
        !          5959: 
        !          5960:       if (tem && ! rtx_equal_p (XEXP (tem, 0), SET_SRC (sets[0].rtl)))
        !          5961:         src_eqv = canon_reg (XEXP (tem, 0), NULL_RTX);
        !          5962:     }
        !          5963: 
        !          5964:   /* Canonicalize sources and addresses of destinations.
        !          5965:      We do this in a separate pass to avoid problems when a MATCH_DUP is
        !          5966:      present in the insn pattern.  In that case, we want to ensure that
        !          5967:      we don't break the duplicate nature of the pattern.  So we will replace
        !          5968:      both operands at the same time.  Otherwise, we would fail to find an
        !          5969:      equivalent substitution in the loop calling validate_change below.
        !          5970: 
        !          5971:      We used to suppress canonicalization of DEST if it appears in SRC,
        !          5972:      but we don't do this any more.  */
        !          5973: 
        !          5974:   for (i = 0; i < n_sets; i++)
        !          5975:     {
        !          5976:       rtx dest = SET_DEST (sets[i].rtl);
        !          5977:       rtx src = SET_SRC (sets[i].rtl);
        !          5978:       rtx new = canon_reg (src, insn);
        !          5979: 
        !          5980:       if ((GET_CODE (new) == REG && GET_CODE (src) == REG
        !          5981:           && ((REGNO (new) < FIRST_PSEUDO_REGISTER)
        !          5982:               != (REGNO (src) < FIRST_PSEUDO_REGISTER)))
        !          5983:          || insn_n_dups[recog_memoized (insn)] > 0)
        !          5984:        validate_change (insn, &SET_SRC (sets[i].rtl), new, 1);
        !          5985:       else
        !          5986:        SET_SRC (sets[i].rtl) = new;
        !          5987: 
        !          5988:       if (GET_CODE (dest) == ZERO_EXTRACT || GET_CODE (dest) == SIGN_EXTRACT)
        !          5989:        {
        !          5990:          validate_change (insn, &XEXP (dest, 1),
        !          5991:                           canon_reg (XEXP (dest, 1), insn), 1);
        !          5992:          validate_change (insn, &XEXP (dest, 2),
        !          5993:                           canon_reg (XEXP (dest, 2), insn), 1);
        !          5994:        }
        !          5995: 
        !          5996:       while (GET_CODE (dest) == SUBREG || GET_CODE (dest) == STRICT_LOW_PART
        !          5997:             || GET_CODE (dest) == ZERO_EXTRACT
        !          5998:             || GET_CODE (dest) == SIGN_EXTRACT)
        !          5999:        dest = XEXP (dest, 0);
        !          6000: 
        !          6001:       if (GET_CODE (dest) == MEM)
        !          6002:        canon_reg (dest, insn);
        !          6003:     }
        !          6004: 
        !          6005:   /* Now that we have done all the replacements, we can apply the change
        !          6006:      group and see if they all work.  Note that this will cause some
        !          6007:      canonicalizations that would have worked individually not to be applied
        !          6008:      because some other canonicalization didn't work, but this should not
        !          6009:      occur often. 
        !          6010: 
        !          6011:      The result of apply_change_group can be ignored; see canon_reg.  */
        !          6012: 
        !          6013:   apply_change_group ();
        !          6014: 
        !          6015:   /* Set sets[i].src_elt to the class each source belongs to.
        !          6016:      Detect assignments from or to volatile things
        !          6017:      and set set[i] to zero so they will be ignored
        !          6018:      in the rest of this function.
        !          6019: 
        !          6020:      Nothing in this loop changes the hash table or the register chains.  */
        !          6021: 
        !          6022:   for (i = 0; i < n_sets; i++)
        !          6023:     {
        !          6024:       register rtx src, dest;
        !          6025:       register rtx src_folded;
        !          6026:       register struct table_elt *elt = 0, *p;
        !          6027:       enum machine_mode mode;
        !          6028:       rtx src_eqv_here;
        !          6029:       rtx src_const = 0;
        !          6030:       rtx src_related = 0;
        !          6031:       struct table_elt *src_const_elt = 0;
        !          6032:       int src_cost = 10000, src_eqv_cost = 10000, src_folded_cost = 10000;
        !          6033:       int src_related_cost = 10000, src_elt_cost = 10000;
        !          6034:       /* Set non-zero if we need to call force_const_mem on with the
        !          6035:         contents of src_folded before using it.  */
        !          6036:       int src_folded_force_flag = 0;
        !          6037: 
        !          6038:       dest = SET_DEST (sets[i].rtl);
        !          6039:       src = SET_SRC (sets[i].rtl);
        !          6040: 
        !          6041:       /* If SRC is a constant that has no machine mode,
        !          6042:         hash it with the destination's machine mode.
        !          6043:         This way we can keep different modes separate.  */
        !          6044: 
        !          6045:       mode = GET_MODE (src) == VOIDmode ? GET_MODE (dest) : GET_MODE (src);
        !          6046:       sets[i].mode = mode;
        !          6047: 
        !          6048:       if (src_eqv)
        !          6049:        {
        !          6050:          enum machine_mode eqvmode = mode;
        !          6051:          if (GET_CODE (dest) == STRICT_LOW_PART)
        !          6052:            eqvmode = GET_MODE (SUBREG_REG (XEXP (dest, 0)));
        !          6053:          do_not_record = 0;
        !          6054:          hash_arg_in_memory = 0;
        !          6055:          hash_arg_in_struct = 0;
        !          6056:          src_eqv = fold_rtx (src_eqv, insn);
        !          6057:          src_eqv_hash_code = HASH (src_eqv, eqvmode);
        !          6058: 
        !          6059:          /* Find the equivalence class for the equivalent expression.  */
        !          6060: 
        !          6061:          if (!do_not_record)
        !          6062:            src_eqv_elt = lookup (src_eqv, src_eqv_hash_code, eqvmode);
        !          6063: 
        !          6064:          src_eqv_volatile = do_not_record;
        !          6065:          src_eqv_in_memory = hash_arg_in_memory;
        !          6066:          src_eqv_in_struct = hash_arg_in_struct;
        !          6067:        }
        !          6068: 
        !          6069:       /* If this is a STRICT_LOW_PART assignment, src_eqv corresponds to the
        !          6070:         value of the INNER register, not the destination.  So it is not
        !          6071:         a legal substitution for the source.  But save it for later.  */
        !          6072:       if (GET_CODE (dest) == STRICT_LOW_PART)
        !          6073:        src_eqv_here = 0;
        !          6074:       else
        !          6075:        src_eqv_here = src_eqv;
        !          6076: 
        !          6077:       /* Simplify and foldable subexpressions in SRC.  Then get the fully-
        !          6078:         simplified result, which may not necessarily be valid.  */
        !          6079:       src_folded = fold_rtx (src, insn);
        !          6080: 
        !          6081:       /* If storing a constant in a bitfield, pre-truncate the constant
        !          6082:         so we will be able to record it later.  */
        !          6083:       if (GET_CODE (SET_DEST (sets[i].rtl)) == ZERO_EXTRACT
        !          6084:          || GET_CODE (SET_DEST (sets[i].rtl)) == SIGN_EXTRACT)
        !          6085:        {
        !          6086:          rtx width = XEXP (SET_DEST (sets[i].rtl), 1);
        !          6087: 
        !          6088:          if (GET_CODE (src) == CONST_INT
        !          6089:              && GET_CODE (width) == CONST_INT
        !          6090:              && INTVAL (width) < HOST_BITS_PER_WIDE_INT
        !          6091:              && (INTVAL (src) & ((HOST_WIDE_INT) (-1) << INTVAL (width))))
        !          6092:            src_folded
        !          6093:              = GEN_INT (INTVAL (src) & (((HOST_WIDE_INT) 1
        !          6094:                                          << INTVAL (width)) - 1));
        !          6095:        }
        !          6096: 
        !          6097:       /* Compute SRC's hash code, and also notice if it
        !          6098:         should not be recorded at all.  In that case,
        !          6099:         prevent any further processing of this assignment.  */
        !          6100:       do_not_record = 0;
        !          6101:       hash_arg_in_memory = 0;
        !          6102:       hash_arg_in_struct = 0;
        !          6103: 
        !          6104:       sets[i].src = src;
        !          6105:       sets[i].src_hash_code = HASH (src, mode);
        !          6106:       sets[i].src_volatile = do_not_record;
        !          6107:       sets[i].src_in_memory = hash_arg_in_memory;
        !          6108:       sets[i].src_in_struct = hash_arg_in_struct;
        !          6109: 
        !          6110: #if 0
        !          6111:       /* It is no longer clear why we used to do this, but it doesn't
        !          6112:         appear to still be needed.  So let's try without it since this
        !          6113:         code hurts cse'ing widened ops.  */
        !          6114:       /* If source is a perverse subreg (such as QI treated as an SI),
        !          6115:         treat it as volatile.  It may do the work of an SI in one context
        !          6116:         where the extra bits are not being used, but cannot replace an SI
        !          6117:         in general.  */
        !          6118:       if (GET_CODE (src) == SUBREG
        !          6119:          && (GET_MODE_SIZE (GET_MODE (src))
        !          6120:              > GET_MODE_SIZE (GET_MODE (SUBREG_REG (src)))))
        !          6121:        sets[i].src_volatile = 1;
        !          6122: #endif
        !          6123: 
        !          6124:       /* Locate all possible equivalent forms for SRC.  Try to replace
        !          6125:          SRC in the insn with each cheaper equivalent.
        !          6126: 
        !          6127:          We have the following types of equivalents: SRC itself, a folded
        !          6128:          version, a value given in a REG_EQUAL note, or a value related
        !          6129:         to a constant.
        !          6130: 
        !          6131:          Each of these equivalents may be part of an additional class
        !          6132:          of equivalents (if more than one is in the table, they must be in
        !          6133:          the same class; we check for this).
        !          6134: 
        !          6135:         If the source is volatile, we don't do any table lookups.
        !          6136: 
        !          6137:          We note any constant equivalent for possible later use in a
        !          6138:          REG_NOTE.  */
        !          6139: 
        !          6140:       if (!sets[i].src_volatile)
        !          6141:        elt = lookup (src, sets[i].src_hash_code, mode);
        !          6142: 
        !          6143:       sets[i].src_elt = elt;
        !          6144: 
        !          6145:       if (elt && src_eqv_here && src_eqv_elt)
        !          6146:         {
        !          6147:           if (elt->first_same_value != src_eqv_elt->first_same_value)
        !          6148:            {
        !          6149:              /* The REG_EQUAL is indicating that two formerly distinct
        !          6150:                 classes are now equivalent.  So merge them.  */
        !          6151:              merge_equiv_classes (elt, src_eqv_elt);
        !          6152:              src_eqv_hash_code = HASH (src_eqv, elt->mode);
        !          6153:              src_eqv_elt = lookup (src_eqv, src_eqv_hash_code, elt->mode);
        !          6154:            }
        !          6155: 
        !          6156:           src_eqv_here = 0;
        !          6157:         }
        !          6158: 
        !          6159:       else if (src_eqv_elt)
        !          6160:         elt = src_eqv_elt;
        !          6161: 
        !          6162:       /* Try to find a constant somewhere and record it in `src_const'.
        !          6163:         Record its table element, if any, in `src_const_elt'.  Look in
        !          6164:         any known equivalences first.  (If the constant is not in the
        !          6165:         table, also set `sets[i].src_const_hash_code').  */
        !          6166:       if (elt)
        !          6167:         for (p = elt->first_same_value; p; p = p->next_same_value)
        !          6168:          if (p->is_const)
        !          6169:            {
        !          6170:              src_const = p->exp;
        !          6171:              src_const_elt = elt;
        !          6172:              break;
        !          6173:            }
        !          6174: 
        !          6175:       if (src_const == 0
        !          6176:          && (CONSTANT_P (src_folded)
        !          6177:              /* Consider (minus (label_ref L1) (label_ref L2)) as 
        !          6178:                 "constant" here so we will record it. This allows us
        !          6179:                 to fold switch statements when an ADDR_DIFF_VEC is used.  */
        !          6180:              || (GET_CODE (src_folded) == MINUS
        !          6181:                  && GET_CODE (XEXP (src_folded, 0)) == LABEL_REF
        !          6182:                  && GET_CODE (XEXP (src_folded, 1)) == LABEL_REF)))
        !          6183:        src_const = src_folded, src_const_elt = elt;
        !          6184:       else if (src_const == 0 && src_eqv_here && CONSTANT_P (src_eqv_here))
        !          6185:        src_const = src_eqv_here, src_const_elt = src_eqv_elt;
        !          6186: 
        !          6187:       /* If we don't know if the constant is in the table, get its
        !          6188:         hash code and look it up.  */
        !          6189:       if (src_const && src_const_elt == 0)
        !          6190:        {
        !          6191:          sets[i].src_const_hash_code = HASH (src_const, mode);
        !          6192:          src_const_elt = lookup (src_const, sets[i].src_const_hash_code,
        !          6193:                                  mode);
        !          6194:        }
        !          6195: 
        !          6196:       sets[i].src_const = src_const;
        !          6197:       sets[i].src_const_elt = src_const_elt;
        !          6198: 
        !          6199:       /* If the constant and our source are both in the table, mark them as
        !          6200:         equivalent.  Otherwise, if a constant is in the table but the source
        !          6201:         isn't, set ELT to it.  */
        !          6202:       if (src_const_elt && elt
        !          6203:          && src_const_elt->first_same_value != elt->first_same_value)
        !          6204:        merge_equiv_classes (elt, src_const_elt);
        !          6205:       else if (src_const_elt && elt == 0)
        !          6206:        elt = src_const_elt;
        !          6207: 
        !          6208:       /* See if there is a register linearly related to a constant
        !          6209:          equivalent of SRC.  */
        !          6210:       if (src_const
        !          6211:          && (GET_CODE (src_const) == CONST
        !          6212:              || (src_const_elt && src_const_elt->related_value != 0)))
        !          6213:         {
        !          6214:           src_related = use_related_value (src_const, src_const_elt);
        !          6215:           if (src_related)
        !          6216:             {
        !          6217:              struct table_elt *src_related_elt
        !          6218:                    = lookup (src_related, HASH (src_related, mode), mode);
        !          6219:              if (src_related_elt && elt)
        !          6220:                {
        !          6221:                  if (elt->first_same_value
        !          6222:                      != src_related_elt->first_same_value)
        !          6223:                    /* This can occur when we previously saw a CONST 
        !          6224:                       involving a SYMBOL_REF and then see the SYMBOL_REF
        !          6225:                       twice.  Merge the involved classes.  */
        !          6226:                    merge_equiv_classes (elt, src_related_elt);
        !          6227: 
        !          6228:                  src_related = 0;
        !          6229:                  src_related_elt = 0;
        !          6230:                }
        !          6231:               else if (src_related_elt && elt == 0)
        !          6232:                elt = src_related_elt;
        !          6233:            }
        !          6234:         }
        !          6235: 
        !          6236:       /* See if we have a CONST_INT that is already in a register in a
        !          6237:         wider mode.  */
        !          6238: 
        !          6239:       if (src_const && src_related == 0 && GET_CODE (src_const) == CONST_INT
        !          6240:          && GET_MODE_CLASS (mode) == MODE_INT
        !          6241:          && GET_MODE_BITSIZE (mode) < BITS_PER_WORD)
        !          6242:        {
        !          6243:          enum machine_mode wider_mode;
        !          6244: 
        !          6245:          for (wider_mode = GET_MODE_WIDER_MODE (mode);
        !          6246:               GET_MODE_BITSIZE (wider_mode) <= BITS_PER_WORD
        !          6247:               && src_related == 0;
        !          6248:               wider_mode = GET_MODE_WIDER_MODE (wider_mode))
        !          6249:            {
        !          6250:              struct table_elt *const_elt
        !          6251:                = lookup (src_const, HASH (src_const, wider_mode), wider_mode);
        !          6252: 
        !          6253:              if (const_elt == 0)
        !          6254:                continue;
        !          6255: 
        !          6256:              for (const_elt = const_elt->first_same_value;
        !          6257:                   const_elt; const_elt = const_elt->next_same_value)
        !          6258:                if (GET_CODE (const_elt->exp) == REG)
        !          6259:                  {
        !          6260:                    src_related = gen_lowpart_if_possible (mode,
        !          6261:                                                           const_elt->exp);
        !          6262:                    break;
        !          6263:                  }
        !          6264:            }
        !          6265:        }
        !          6266: 
        !          6267:       /* Another possibility is that we have an AND with a constant in
        !          6268:         a mode narrower than a word.  If so, it might have been generated
        !          6269:         as part of an "if" which would narrow the AND.  If we already
        !          6270:         have done the AND in a wider mode, we can use a SUBREG of that
        !          6271:         value.  */
        !          6272: 
        !          6273:       if (flag_expensive_optimizations && ! src_related
        !          6274:          && GET_CODE (src) == AND && GET_CODE (XEXP (src, 1)) == CONST_INT
        !          6275:          && GET_MODE_SIZE (mode) < UNITS_PER_WORD)
        !          6276:        {
        !          6277:          enum machine_mode tmode;
        !          6278:          rtx new_and = gen_rtx (AND, VOIDmode, NULL_RTX, XEXP (src, 1));
        !          6279: 
        !          6280:          for (tmode = GET_MODE_WIDER_MODE (mode);
        !          6281:               GET_MODE_SIZE (tmode) <= UNITS_PER_WORD;
        !          6282:               tmode = GET_MODE_WIDER_MODE (tmode))
        !          6283:            {
        !          6284:              rtx inner = gen_lowpart_if_possible (tmode, XEXP (src, 0));
        !          6285:              struct table_elt *larger_elt;
        !          6286: 
        !          6287:              if (inner)
        !          6288:                {
        !          6289:                  PUT_MODE (new_and, tmode);
        !          6290:                  XEXP (new_and, 0) = inner;
        !          6291:                  larger_elt = lookup (new_and, HASH (new_and, tmode), tmode);
        !          6292:                  if (larger_elt == 0)
        !          6293:                    continue;
        !          6294: 
        !          6295:                  for (larger_elt = larger_elt->first_same_value;
        !          6296:                       larger_elt; larger_elt = larger_elt->next_same_value)
        !          6297:                    if (GET_CODE (larger_elt->exp) == REG)
        !          6298:                      {
        !          6299:                        src_related
        !          6300:                          = gen_lowpart_if_possible (mode, larger_elt->exp);
        !          6301:                        break;
        !          6302:                      }
        !          6303: 
        !          6304:                  if (src_related)
        !          6305:                    break;
        !          6306:                }
        !          6307:            }
        !          6308:        }
        !          6309:                  
        !          6310:       if (src == src_folded)
        !          6311:         src_folded = 0;
        !          6312: 
        !          6313:       /* At this point, ELT, if non-zero, points to a class of expressions
        !          6314:          equivalent to the source of this SET and SRC, SRC_EQV, SRC_FOLDED,
        !          6315:         and SRC_RELATED, if non-zero, each contain additional equivalent
        !          6316:         expressions.  Prune these latter expressions by deleting expressions
        !          6317:         already in the equivalence class.
        !          6318: 
        !          6319:         Check for an equivalent identical to the destination.  If found,
        !          6320:         this is the preferred equivalent since it will likely lead to
        !          6321:         elimination of the insn.  Indicate this by placing it in
        !          6322:         `src_related'.  */
        !          6323: 
        !          6324:       if (elt) elt = elt->first_same_value;
        !          6325:       for (p = elt; p; p = p->next_same_value)
        !          6326:         {
        !          6327:          enum rtx_code code = GET_CODE (p->exp);
        !          6328: 
        !          6329:          /* If the expression is not valid, ignore it.  Then we do not
        !          6330:             have to check for validity below.  In most cases, we can use
        !          6331:             `rtx_equal_p', since canonicalization has already been done.  */
        !          6332:          if (code != REG && ! exp_equiv_p (p->exp, p->exp, 1, 0))
        !          6333:            continue;
        !          6334: 
        !          6335:           if (src && GET_CODE (src) == code && rtx_equal_p (src, p->exp))
        !          6336:            src = 0;
        !          6337:           else if (src_folded && GET_CODE (src_folded) == code
        !          6338:                   && rtx_equal_p (src_folded, p->exp))
        !          6339:            src_folded = 0;
        !          6340:           else if (src_eqv_here && GET_CODE (src_eqv_here) == code
        !          6341:                   && rtx_equal_p (src_eqv_here, p->exp))
        !          6342:            src_eqv_here = 0;
        !          6343:           else if (src_related && GET_CODE (src_related) == code
        !          6344:                   && rtx_equal_p (src_related, p->exp))
        !          6345:            src_related = 0;
        !          6346: 
        !          6347:          /* This is the same as the destination of the insns, we want
        !          6348:             to prefer it.  Copy it to src_related.  The code below will
        !          6349:             then give it a negative cost.  */
        !          6350:          if (GET_CODE (dest) == code && rtx_equal_p (p->exp, dest))
        !          6351:            src_related = dest;
        !          6352: 
        !          6353:         }
        !          6354: 
        !          6355:       /* Find the cheapest valid equivalent, trying all the available
        !          6356:          possibilities.  Prefer items not in the hash table to ones
        !          6357:          that are when they are equal cost.  Note that we can never
        !          6358:          worsen an insn as the current contents will also succeed.
        !          6359:         If we find an equivalent identical to the destination, use it as best,
        !          6360:         since this insn will probably be eliminated in that case. */
        !          6361:       if (src)
        !          6362:        {
        !          6363:          if (rtx_equal_p (src, dest))
        !          6364:            src_cost = -1;
        !          6365:          else
        !          6366:            src_cost = COST (src);
        !          6367:        }
        !          6368: 
        !          6369:       if (src_eqv_here)
        !          6370:        {
        !          6371:          if (rtx_equal_p (src_eqv_here, dest))
        !          6372:            src_eqv_cost = -1;
        !          6373:          else
        !          6374:            src_eqv_cost = COST (src_eqv_here);
        !          6375:        }
        !          6376: 
        !          6377:       if (src_folded)
        !          6378:        {
        !          6379:          if (rtx_equal_p (src_folded, dest))
        !          6380:            src_folded_cost = -1;
        !          6381:          else
        !          6382:            src_folded_cost = COST (src_folded);
        !          6383:        }
        !          6384: 
        !          6385:       if (src_related)
        !          6386:        {
        !          6387:          if (rtx_equal_p (src_related, dest))
        !          6388:            src_related_cost = -1;
        !          6389:          else
        !          6390:            src_related_cost = COST (src_related);
        !          6391:        }
        !          6392: 
        !          6393:       /* If this was an indirect jump insn, a known label will really be
        !          6394:         cheaper even though it looks more expensive.  */
        !          6395:       if (dest == pc_rtx && src_const && GET_CODE (src_const) == LABEL_REF)
        !          6396:        src_folded = src_const, src_folded_cost = -1;
        !          6397:          
        !          6398:       /* Terminate loop when replacement made.  This must terminate since
        !          6399:          the current contents will be tested and will always be valid.  */
        !          6400:       while (1)
        !          6401:         {
        !          6402:           rtx trial;
        !          6403: 
        !          6404:           /* Skip invalid entries.  */
        !          6405:           while (elt && GET_CODE (elt->exp) != REG
        !          6406:                 && ! exp_equiv_p (elt->exp, elt->exp, 1, 0))
        !          6407:            elt = elt->next_same_value;      
        !          6408:              
        !          6409:           if (elt) src_elt_cost = elt->cost;
        !          6410: 
        !          6411:           /* Find cheapest and skip it for the next time.   For items
        !          6412:             of equal cost, use this order:
        !          6413:             src_folded, src, src_eqv, src_related and hash table entry.  */
        !          6414:           if (src_folded_cost <= src_cost
        !          6415:              && src_folded_cost <= src_eqv_cost
        !          6416:              && src_folded_cost <= src_related_cost
        !          6417:              && src_folded_cost <= src_elt_cost)
        !          6418:            {
        !          6419:              trial = src_folded, src_folded_cost = 10000;
        !          6420:              if (src_folded_force_flag)
        !          6421:                trial = force_const_mem (mode, trial);
        !          6422:            }
        !          6423:           else if (src_cost <= src_eqv_cost
        !          6424:                   && src_cost <= src_related_cost
        !          6425:                   && src_cost <= src_elt_cost)
        !          6426:            trial = src, src_cost = 10000;
        !          6427:           else if (src_eqv_cost <= src_related_cost
        !          6428:                   && src_eqv_cost <= src_elt_cost)
        !          6429:            trial = copy_rtx (src_eqv_here), src_eqv_cost = 10000;
        !          6430:           else if (src_related_cost <= src_elt_cost)
        !          6431:            trial = copy_rtx (src_related), src_related_cost = 10000;
        !          6432:           else
        !          6433:            {
        !          6434:              trial = copy_rtx (elt->exp);
        !          6435:              elt = elt->next_same_value;
        !          6436:              src_elt_cost = 10000;
        !          6437:            }
        !          6438: 
        !          6439:          /* We don't normally have an insn matching (set (pc) (pc)), so
        !          6440:             check for this separately here.  We will delete such an
        !          6441:             insn below.
        !          6442: 
        !          6443:             Tablejump insns contain a USE of the table, so simply replacing
        !          6444:             the operand with the constant won't match.  This is simply an
        !          6445:             unconditional branch, however, and is therefore valid.  Just
        !          6446:             insert the substitution here and we will delete and re-emit
        !          6447:             the insn later.  */
        !          6448: 
        !          6449:          if (n_sets == 1 && dest == pc_rtx
        !          6450:              && (trial == pc_rtx
        !          6451:                  || (GET_CODE (trial) == LABEL_REF
        !          6452:                      && ! condjump_p (insn))))
        !          6453:            {
        !          6454:              /* If TRIAL is a label in front of a jump table, we are
        !          6455:                 really falling through the switch (this is how casesi
        !          6456:                 insns work), so we must branch around the table.  */
        !          6457:              if (GET_CODE (trial) == CODE_LABEL
        !          6458:                  && NEXT_INSN (trial) != 0
        !          6459:                  && GET_CODE (NEXT_INSN (trial)) == JUMP_INSN
        !          6460:                  && (GET_CODE (PATTERN (NEXT_INSN (trial))) == ADDR_DIFF_VEC
        !          6461:                      || GET_CODE (PATTERN (NEXT_INSN (trial))) == ADDR_VEC))
        !          6462: 
        !          6463:                trial = gen_rtx (LABEL_REF, Pmode, get_label_after (trial));
        !          6464: 
        !          6465:              SET_SRC (sets[i].rtl) = trial;
        !          6466:              break;
        !          6467:            }
        !          6468:           
        !          6469:          /* Look for a substitution that makes a valid insn.  */
        !          6470:           else if (validate_change (insn, &SET_SRC (sets[i].rtl), trial, 0))
        !          6471:            {
        !          6472:              /* The result of apply_change_group can be ignored; see
        !          6473:                 canon_reg.  */
        !          6474: 
        !          6475:              validate_change (insn, &SET_SRC (sets[i].rtl),
        !          6476:                               canon_reg (SET_SRC (sets[i].rtl), insn),
        !          6477:                               1);
        !          6478:              apply_change_group ();
        !          6479:              break;
        !          6480:            }
        !          6481: 
        !          6482:          /* If we previously found constant pool entries for 
        !          6483:             constants and this is a constant, try making a
        !          6484:             pool entry.  Put it in src_folded unless we already have done
        !          6485:             this since that is where it likely came from.  */
        !          6486: 
        !          6487:          else if (constant_pool_entries_cost
        !          6488:                   && CONSTANT_P (trial)
        !          6489:                   && (src_folded == 0 || GET_CODE (src_folded) != MEM)
        !          6490:                   && GET_MODE_CLASS (mode) != MODE_CC)
        !          6491:            {
        !          6492:              src_folded_force_flag = 1;
        !          6493:              src_folded = trial;
        !          6494:              src_folded_cost = constant_pool_entries_cost;
        !          6495:            }
        !          6496:         }
        !          6497: 
        !          6498:       src = SET_SRC (sets[i].rtl);
        !          6499: 
        !          6500:       /* In general, it is good to have a SET with SET_SRC == SET_DEST.
        !          6501:         However, there is an important exception:  If both are registers
        !          6502:         that are not the head of their equivalence class, replace SET_SRC
        !          6503:         with the head of the class.  If we do not do this, we will have
        !          6504:         both registers live over a portion of the basic block.  This way,
        !          6505:         their lifetimes will likely abut instead of overlapping.  */
        !          6506:       if (GET_CODE (dest) == REG
        !          6507:          && REGNO_QTY_VALID_P (REGNO (dest))
        !          6508:          && qty_mode[reg_qty[REGNO (dest)]] == GET_MODE (dest)
        !          6509:          && qty_first_reg[reg_qty[REGNO (dest)]] != REGNO (dest)
        !          6510:          && GET_CODE (src) == REG && REGNO (src) == REGNO (dest)
        !          6511:          /* Don't do this if the original insn had a hard reg as
        !          6512:             SET_SRC.  */
        !          6513:          && (GET_CODE (sets[i].src) != REG
        !          6514:              || REGNO (sets[i].src) >= FIRST_PSEUDO_REGISTER))
        !          6515:        /* We can't call canon_reg here because it won't do anything if
        !          6516:           SRC is a hard register.  */
        !          6517:        {
        !          6518:          int first = qty_first_reg[reg_qty[REGNO (src)]];
        !          6519: 
        !          6520:          src = SET_SRC (sets[i].rtl)
        !          6521:            = first >= FIRST_PSEUDO_REGISTER ? regno_reg_rtx[first]
        !          6522:              : gen_rtx (REG, GET_MODE (src), first);
        !          6523: 
        !          6524:          /* If we had a constant that is cheaper than what we are now
        !          6525:             setting SRC to, use that constant.  We ignored it when we
        !          6526:             thought we could make this into a no-op.  */
        !          6527:          if (src_const && COST (src_const) < COST (src)
        !          6528:              && validate_change (insn, &SET_SRC (sets[i].rtl), src_const, 0))
        !          6529:            src = src_const;
        !          6530:        }
        !          6531: 
        !          6532:       /* If we made a change, recompute SRC values.  */
        !          6533:       if (src != sets[i].src)
        !          6534:         {
        !          6535:           do_not_record = 0;
        !          6536:           hash_arg_in_memory = 0;
        !          6537:           hash_arg_in_struct = 0;
        !          6538:          sets[i].src = src;
        !          6539:           sets[i].src_hash_code = HASH (src, mode);
        !          6540:           sets[i].src_volatile = do_not_record;
        !          6541:           sets[i].src_in_memory = hash_arg_in_memory;
        !          6542:           sets[i].src_in_struct = hash_arg_in_struct;
        !          6543:           sets[i].src_elt = lookup (src, sets[i].src_hash_code, mode);
        !          6544:         }
        !          6545: 
        !          6546:       /* If this is a single SET, we are setting a register, and we have an
        !          6547:         equivalent constant, we want to add a REG_NOTE.   We don't want
        !          6548:         to write a REG_EQUAL note for a constant pseudo since verifying that
        !          6549:         that pseudo hasn't been eliminated is a pain.  Such a note also
        !          6550:         won't help anything.  */
        !          6551:       if (n_sets == 1 && src_const && GET_CODE (dest) == REG
        !          6552:          && GET_CODE (src_const) != REG)
        !          6553:        {
        !          6554:          rtx tem = find_reg_note (insn, REG_EQUAL, NULL_RTX);
        !          6555:          
        !          6556:          /* Record the actual constant value in a REG_EQUAL note, making
        !          6557:             a new one if one does not already exist.  */
        !          6558:          if (tem)
        !          6559:            XEXP (tem, 0) = src_const;
        !          6560:          else
        !          6561:            REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL,
        !          6562:                                        src_const, REG_NOTES (insn));
        !          6563: 
        !          6564:           /* If storing a constant value in a register that
        !          6565:             previously held the constant value 0,
        !          6566:             record this fact with a REG_WAS_0 note on this insn.
        !          6567: 
        !          6568:             Note that the *register* is required to have previously held 0,
        !          6569:             not just any register in the quantity and we must point to the
        !          6570:             insn that set that register to zero.
        !          6571: 
        !          6572:             Rather than track each register individually, we just see if
        !          6573:             the last set for this quantity was for this register.  */
        !          6574: 
        !          6575:          if (REGNO_QTY_VALID_P (REGNO (dest))
        !          6576:              && qty_const[reg_qty[REGNO (dest)]] == const0_rtx)
        !          6577:            {
        !          6578:              /* See if we previously had a REG_WAS_0 note.  */
        !          6579:              rtx note = find_reg_note (insn, REG_WAS_0, NULL_RTX);
        !          6580:              rtx const_insn = qty_const_insn[reg_qty[REGNO (dest)]];
        !          6581: 
        !          6582:              if ((tem = single_set (const_insn)) != 0
        !          6583:                  && rtx_equal_p (SET_DEST (tem), dest))
        !          6584:                {
        !          6585:                  if (note)
        !          6586:                    XEXP (note, 0) = const_insn;
        !          6587:                  else
        !          6588:                    REG_NOTES (insn) = gen_rtx (INSN_LIST, REG_WAS_0,
        !          6589:                                                const_insn, REG_NOTES (insn));
        !          6590:                }
        !          6591:            }
        !          6592:        }
        !          6593: 
        !          6594:       /* Now deal with the destination.  */
        !          6595:       do_not_record = 0;
        !          6596:       sets[i].inner_dest_loc = &SET_DEST (sets[0].rtl);
        !          6597: 
        !          6598:       /* Look within any SIGN_EXTRACT or ZERO_EXTRACT
        !          6599:         to the MEM or REG within it.  */
        !          6600:       while (GET_CODE (dest) == SIGN_EXTRACT
        !          6601:             || GET_CODE (dest) == ZERO_EXTRACT
        !          6602:             || GET_CODE (dest) == SUBREG
        !          6603:             || GET_CODE (dest) == STRICT_LOW_PART)
        !          6604:        {
        !          6605:          sets[i].inner_dest_loc = &XEXP (dest, 0);
        !          6606:          dest = XEXP (dest, 0);
        !          6607:        }
        !          6608: 
        !          6609:       sets[i].inner_dest = dest;
        !          6610: 
        !          6611:       if (GET_CODE (dest) == MEM)
        !          6612:        {
        !          6613:          dest = fold_rtx (dest, insn);
        !          6614: 
        !          6615:          /* Decide whether we invalidate everything in memory,
        !          6616:             or just things at non-fixed places.
        !          6617:             Writing a large aggregate must invalidate everything
        !          6618:             because we don't know how long it is.  */
        !          6619:          note_mem_written (dest, &writes_memory);
        !          6620:        }
        !          6621: 
        !          6622:       /* Compute the hash code of the destination now,
        !          6623:         before the effects of this instruction are recorded,
        !          6624:         since the register values used in the address computation
        !          6625:         are those before this instruction.  */
        !          6626:       sets[i].dest_hash_code = HASH (dest, mode);
        !          6627: 
        !          6628:       /* Don't enter a bit-field in the hash table
        !          6629:         because the value in it after the store
        !          6630:         may not equal what was stored, due to truncation.  */
        !          6631: 
        !          6632:       if (GET_CODE (SET_DEST (sets[i].rtl)) == ZERO_EXTRACT
        !          6633:          || GET_CODE (SET_DEST (sets[i].rtl)) == SIGN_EXTRACT)
        !          6634:        {
        !          6635:          rtx width = XEXP (SET_DEST (sets[i].rtl), 1);
        !          6636: 
        !          6637:          if (src_const != 0 && GET_CODE (src_const) == CONST_INT
        !          6638:              && GET_CODE (width) == CONST_INT
        !          6639:              && INTVAL (width) < HOST_BITS_PER_WIDE_INT
        !          6640:              && ! (INTVAL (src_const)
        !          6641:                    & ((HOST_WIDE_INT) (-1) << INTVAL (width))))
        !          6642:            /* Exception: if the value is constant,
        !          6643:               and it won't be truncated, record it.  */
        !          6644:            ;
        !          6645:          else
        !          6646:            {
        !          6647:              /* This is chosen so that the destination will be invalidated
        !          6648:                 but no new value will be recorded.
        !          6649:                 We must invalidate because sometimes constant
        !          6650:                 values can be recorded for bitfields.  */
        !          6651:              sets[i].src_elt = 0;
        !          6652:              sets[i].src_volatile = 1;
        !          6653:              src_eqv = 0;
        !          6654:              src_eqv_elt = 0;
        !          6655:            }
        !          6656:        }
        !          6657: 
        !          6658:       /* If only one set in a JUMP_INSN and it is now a no-op, we can delete
        !          6659:         the insn.  */
        !          6660:       else if (n_sets == 1 && dest == pc_rtx && src == pc_rtx)
        !          6661:        {
        !          6662:          PUT_CODE (insn, NOTE);
        !          6663:          NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
        !          6664:          NOTE_SOURCE_FILE (insn) = 0;
        !          6665:          cse_jumps_altered = 1;
        !          6666:          /* One less use of the label this insn used to jump to.  */
        !          6667:          --LABEL_NUSES (JUMP_LABEL (insn));
        !          6668:          /* No more processing for this set.  */
        !          6669:          sets[i].rtl = 0;
        !          6670:        }
        !          6671: 
        !          6672:       /* If this SET is now setting PC to a label, we know it used to
        !          6673:         be a conditional or computed branch.  So we see if we can follow
        !          6674:         it.  If it was a computed branch, delete it and re-emit.  */
        !          6675:       else if (dest == pc_rtx && GET_CODE (src) == LABEL_REF)
        !          6676:        {
        !          6677:          rtx p;
        !          6678: 
        !          6679:          /* If this is not in the format for a simple branch and
        !          6680:             we are the only SET in it, re-emit it.  */
        !          6681:          if (! simplejump_p (insn) && n_sets == 1)
        !          6682:            {
        !          6683:              rtx new = emit_jump_insn_before (gen_jump (XEXP (src, 0)), insn);
        !          6684:              JUMP_LABEL (new) = XEXP (src, 0);
        !          6685:              LABEL_NUSES (XEXP (src, 0))++;
        !          6686:              delete_insn (insn);
        !          6687:              insn = new;
        !          6688:            }
        !          6689:          else
        !          6690:            /* Otherwise, force rerecognition, since it probably had
        !          6691:               a different pattern before.
        !          6692:               This shouldn't really be necessary, since whatever
        !          6693:               changed the source value above should have done this.
        !          6694:               Until the right place is found, might as well do this here.  */
        !          6695:            INSN_CODE (insn) = -1;
        !          6696: 
        !          6697:          /* Now that we've converted this jump to an unconditional jump,
        !          6698:             there is dead code after it.  Delete the dead code until we
        !          6699:             reach a BARRIER, the end of the function, or a label.  Do
        !          6700:             not delete NOTEs except for NOTE_INSN_DELETED since later
        !          6701:             phases assume these notes are retained.  */
        !          6702: 
        !          6703:          p = insn;
        !          6704: 
        !          6705:          while (NEXT_INSN (p) != 0
        !          6706:                 && GET_CODE (NEXT_INSN (p)) != BARRIER
        !          6707:                 && GET_CODE (NEXT_INSN (p)) != CODE_LABEL)
        !          6708:            {
        !          6709:              if (GET_CODE (NEXT_INSN (p)) != NOTE
        !          6710:                  || NOTE_LINE_NUMBER (NEXT_INSN (p)) == NOTE_INSN_DELETED)
        !          6711:                delete_insn (NEXT_INSN (p));
        !          6712:              else
        !          6713:                p = NEXT_INSN (p);
        !          6714:            }
        !          6715: 
        !          6716:          /* If we don't have a BARRIER immediately after INSN, put one there.
        !          6717:             Much code assumes that there are no NOTEs between a JUMP_INSN and
        !          6718:             BARRIER.  */
        !          6719: 
        !          6720:          if (NEXT_INSN (insn) == 0
        !          6721:              || GET_CODE (NEXT_INSN (insn)) != BARRIER)
        !          6722:            emit_barrier_after (insn);
        !          6723: 
        !          6724:          /* We might have two BARRIERs separated by notes.  Delete the second
        !          6725:             one if so.  */
        !          6726: 
        !          6727:          if (p != insn && NEXT_INSN (p) != 0
        !          6728:              && GET_CODE (NEXT_INSN (p)) == BARRIER)
        !          6729:            delete_insn (NEXT_INSN (p));
        !          6730: 
        !          6731:          cse_jumps_altered = 1;
        !          6732:          sets[i].rtl = 0;
        !          6733:        }
        !          6734: 
        !          6735:       /* If destination is volatile, invalidate it and then do no further
        !          6736:         processing for this assignment.  */
        !          6737: 
        !          6738:       else if (do_not_record)
        !          6739:        {
        !          6740:          if (GET_CODE (dest) == REG || GET_CODE (dest) == SUBREG
        !          6741:              || GET_CODE (dest) == MEM)
        !          6742:            invalidate (dest);
        !          6743:          else if (GET_CODE (dest) == STRICT_LOW_PART
        !          6744:                   || GET_CODE (dest) == ZERO_EXTRACT)
        !          6745:            invalidate (XEXP (dest, 0));
        !          6746:          sets[i].rtl = 0;
        !          6747:        }
        !          6748: 
        !          6749:       if (sets[i].rtl != 0 && dest != SET_DEST (sets[i].rtl))
        !          6750:        sets[i].dest_hash_code = HASH (SET_DEST (sets[i].rtl), mode);
        !          6751: 
        !          6752: #ifdef HAVE_cc0
        !          6753:       /* If setting CC0, record what it was set to, or a constant, if it
        !          6754:         is equivalent to a constant.  If it is being set to a floating-point
        !          6755:         value, make a COMPARE with the appropriate constant of 0.  If we
        !          6756:         don't do this, later code can interpret this as a test against
        !          6757:         const0_rtx, which can cause problems if we try to put it into an
        !          6758:         insn as a floating-point operand.  */
        !          6759:       if (dest == cc0_rtx)
        !          6760:        {
        !          6761:          this_insn_cc0 = src_const && mode != VOIDmode ? src_const : src;
        !          6762:          this_insn_cc0_mode = mode;
        !          6763:          if (FLOAT_MODE_P (mode))
        !          6764:            this_insn_cc0 = gen_rtx (COMPARE, VOIDmode, this_insn_cc0,
        !          6765:                                     CONST0_RTX (mode));
        !          6766:        }
        !          6767: #endif
        !          6768:     }
        !          6769: 
        !          6770:   /* Now enter all non-volatile source expressions in the hash table
        !          6771:      if they are not already present.
        !          6772:      Record their equivalence classes in src_elt.
        !          6773:      This way we can insert the corresponding destinations into
        !          6774:      the same classes even if the actual sources are no longer in them
        !          6775:      (having been invalidated).  */
        !          6776: 
        !          6777:   if (src_eqv && src_eqv_elt == 0 && sets[0].rtl != 0 && ! src_eqv_volatile
        !          6778:       && ! rtx_equal_p (src_eqv, SET_DEST (sets[0].rtl)))
        !          6779:     {
        !          6780:       register struct table_elt *elt;
        !          6781:       register struct table_elt *classp = sets[0].src_elt;
        !          6782:       rtx dest = SET_DEST (sets[0].rtl);
        !          6783:       enum machine_mode eqvmode = GET_MODE (dest);
        !          6784: 
        !          6785:       if (GET_CODE (dest) == STRICT_LOW_PART)
        !          6786:        {
        !          6787:          eqvmode = GET_MODE (SUBREG_REG (XEXP (dest, 0)));
        !          6788:          classp = 0;
        !          6789:        }
        !          6790:       if (insert_regs (src_eqv, classp, 0))
        !          6791:        src_eqv_hash_code = HASH (src_eqv, eqvmode);
        !          6792:       elt = insert (src_eqv, classp, src_eqv_hash_code, eqvmode);
        !          6793:       elt->in_memory = src_eqv_in_memory;
        !          6794:       elt->in_struct = src_eqv_in_struct;
        !          6795:       src_eqv_elt = elt;
        !          6796: 
        !          6797:       /* Check to see if src_eqv_elt is the same as a set source which
        !          6798:         does not yet have an elt, and if so set the elt of the set source
        !          6799:         to src_eqv_elt.  */
        !          6800:       for (i = 0; i < n_sets; i++)
        !          6801:        if (sets[i].rtl && sets[i].src_elt == 0
        !          6802:            && rtx_equal_p (SET_SRC (sets[i].rtl), src_eqv))
        !          6803:          sets[i].src_elt = src_eqv_elt;
        !          6804:     }
        !          6805: 
        !          6806:   for (i = 0; i < n_sets; i++)
        !          6807:     if (sets[i].rtl && ! sets[i].src_volatile
        !          6808:        && ! rtx_equal_p (SET_SRC (sets[i].rtl), SET_DEST (sets[i].rtl)))
        !          6809:       {
        !          6810:        if (GET_CODE (SET_DEST (sets[i].rtl)) == STRICT_LOW_PART)
        !          6811:          {
        !          6812:            /* REG_EQUAL in setting a STRICT_LOW_PART
        !          6813:               gives an equivalent for the entire destination register,
        !          6814:               not just for the subreg being stored in now.
        !          6815:               This is a more interesting equivalence, so we arrange later
        !          6816:               to treat the entire reg as the destination.  */
        !          6817:            sets[i].src_elt = src_eqv_elt;
        !          6818:            sets[i].src_hash_code = src_eqv_hash_code;
        !          6819:          }
        !          6820:        else
        !          6821:          {
        !          6822:            /* Insert source and constant equivalent into hash table, if not
        !          6823:               already present.  */
        !          6824:            register struct table_elt *classp = src_eqv_elt;
        !          6825:            register rtx src = sets[i].src;
        !          6826:            register rtx dest = SET_DEST (sets[i].rtl);
        !          6827:            enum machine_mode mode
        !          6828:              = GET_MODE (src) == VOIDmode ? GET_MODE (dest) : GET_MODE (src);
        !          6829: 
        !          6830:            if (sets[i].src_elt == 0)
        !          6831:              {
        !          6832:                register struct table_elt *elt;
        !          6833: 
        !          6834:                /* Note that these insert_regs calls cannot remove
        !          6835:                   any of the src_elt's, because they would have failed to
        !          6836:                   match if not still valid.  */
        !          6837:                if (insert_regs (src, classp, 0))
        !          6838:                  sets[i].src_hash_code = HASH (src, mode);
        !          6839:                elt = insert (src, classp, sets[i].src_hash_code, mode);
        !          6840:                elt->in_memory = sets[i].src_in_memory;
        !          6841:                elt->in_struct = sets[i].src_in_struct;
        !          6842:                sets[i].src_elt = classp = elt;
        !          6843:              }
        !          6844: 
        !          6845:            if (sets[i].src_const && sets[i].src_const_elt == 0
        !          6846:                && src != sets[i].src_const
        !          6847:                && ! rtx_equal_p (sets[i].src_const, src))
        !          6848:              sets[i].src_elt = insert (sets[i].src_const, classp,
        !          6849:                                        sets[i].src_const_hash_code, mode);
        !          6850:          }
        !          6851:       }
        !          6852:     else if (sets[i].src_elt == 0)
        !          6853:       /* If we did not insert the source into the hash table (e.g., it was
        !          6854:         volatile), note the equivalence class for the REG_EQUAL value, if any,
        !          6855:         so that the destination goes into that class.  */
        !          6856:       sets[i].src_elt = src_eqv_elt;
        !          6857: 
        !          6858:   invalidate_from_clobbers (&writes_memory, x);
        !          6859: 
        !          6860:   /* Some registers are invalidated by subroutine calls.  Memory is 
        !          6861:      invalidated by non-constant calls.  */
        !          6862: 
        !          6863:   if (GET_CODE (insn) == CALL_INSN)
        !          6864:     {
        !          6865:       static struct write_data everything = {0, 1, 1, 1};
        !          6866: 
        !          6867:       if (! CONST_CALL_P (insn))
        !          6868:        invalidate_memory (&everything);
        !          6869:       invalidate_for_call ();
        !          6870:     }
        !          6871: 
        !          6872:   /* Now invalidate everything set by this instruction.
        !          6873:      If a SUBREG or other funny destination is being set,
        !          6874:      sets[i].rtl is still nonzero, so here we invalidate the reg
        !          6875:      a part of which is being set.  */
        !          6876: 
        !          6877:   for (i = 0; i < n_sets; i++)
        !          6878:     if (sets[i].rtl)
        !          6879:       {
        !          6880:        register rtx dest = sets[i].inner_dest;
        !          6881: 
        !          6882:        /* Needed for registers to remove the register from its
        !          6883:           previous quantity's chain.
        !          6884:           Needed for memory if this is a nonvarying address, unless
        !          6885:           we have just done an invalidate_memory that covers even those.  */
        !          6886:        if (GET_CODE (dest) == REG || GET_CODE (dest) == SUBREG
        !          6887:            || (! writes_memory.all && ! cse_rtx_addr_varies_p (dest)))
        !          6888:          invalidate (dest);
        !          6889:        else if (GET_CODE (dest) == STRICT_LOW_PART
        !          6890:                 || GET_CODE (dest) == ZERO_EXTRACT)
        !          6891:          invalidate (XEXP (dest, 0));
        !          6892:       }
        !          6893: 
        !          6894:   /* Make sure registers mentioned in destinations
        !          6895:      are safe for use in an expression to be inserted.
        !          6896:      This removes from the hash table
        !          6897:      any invalid entry that refers to one of these registers.
        !          6898: 
        !          6899:      We don't care about the return value from mention_regs because
        !          6900:      we are going to hash the SET_DEST values unconditionally.  */
        !          6901: 
        !          6902:   for (i = 0; i < n_sets; i++)
        !          6903:     if (sets[i].rtl && GET_CODE (SET_DEST (sets[i].rtl)) != REG)
        !          6904:       mention_regs (SET_DEST (sets[i].rtl));
        !          6905: 
        !          6906:   /* We may have just removed some of the src_elt's from the hash table.
        !          6907:      So replace each one with the current head of the same class.  */
        !          6908: 
        !          6909:   for (i = 0; i < n_sets; i++)
        !          6910:     if (sets[i].rtl)
        !          6911:       {
        !          6912:        if (sets[i].src_elt && sets[i].src_elt->first_same_value == 0)
        !          6913:          /* If elt was removed, find current head of same class,
        !          6914:             or 0 if nothing remains of that class.  */
        !          6915:          {
        !          6916:            register struct table_elt *elt = sets[i].src_elt;
        !          6917: 
        !          6918:            while (elt && elt->prev_same_value)
        !          6919:              elt = elt->prev_same_value;
        !          6920: 
        !          6921:            while (elt && elt->first_same_value == 0)
        !          6922:              elt = elt->next_same_value;
        !          6923:            sets[i].src_elt = elt ? elt->first_same_value : 0;
        !          6924:          }
        !          6925:       }
        !          6926: 
        !          6927:   /* Now insert the destinations into their equivalence classes.  */
        !          6928: 
        !          6929:   for (i = 0; i < n_sets; i++)
        !          6930:     if (sets[i].rtl)
        !          6931:       {
        !          6932:        register rtx dest = SET_DEST (sets[i].rtl);
        !          6933:        register struct table_elt *elt;
        !          6934: 
        !          6935:        /* Don't record value if we are not supposed to risk allocating
        !          6936:           floating-point values in registers that might be wider than
        !          6937:           memory.  */
        !          6938:        if ((flag_float_store
        !          6939:             && GET_CODE (dest) == MEM
        !          6940:             && FLOAT_MODE_P (GET_MODE (dest)))
        !          6941:            /* Don't record values of destinations set inside a libcall block
        !          6942:               since we might delete the libcall.  Things should have been set
        !          6943:               up so we won't want to reuse such a value, but we play it safe
        !          6944:               here.  */
        !          6945:            || in_libcall_block
        !          6946:            /* If we didn't put a REG_EQUAL value or a source into the hash
        !          6947:               table, there is no point is recording DEST.  */
        !          6948:             || sets[i].src_elt == 0)
        !          6949:          continue;
        !          6950: 
        !          6951:        /* STRICT_LOW_PART isn't part of the value BEING set,
        !          6952:           and neither is the SUBREG inside it.
        !          6953:           Note that in this case SETS[I].SRC_ELT is really SRC_EQV_ELT.  */
        !          6954:        if (GET_CODE (dest) == STRICT_LOW_PART)
        !          6955:          dest = SUBREG_REG (XEXP (dest, 0));
        !          6956: 
        !          6957:        if (GET_CODE (dest) == REG || GET_CODE (dest) == SUBREG)
        !          6958:          /* Registers must also be inserted into chains for quantities.  */
        !          6959:          if (insert_regs (dest, sets[i].src_elt, 1))
        !          6960:            /* If `insert_regs' changes something, the hash code must be
        !          6961:               recalculated.  */
        !          6962:            sets[i].dest_hash_code = HASH (dest, GET_MODE (dest));
        !          6963: 
        !          6964:        elt = insert (dest, sets[i].src_elt,
        !          6965:                      sets[i].dest_hash_code, GET_MODE (dest));
        !          6966:        elt->in_memory = GET_CODE (sets[i].inner_dest) == MEM;
        !          6967:        if (elt->in_memory)
        !          6968:          {
        !          6969:            /* This implicitly assumes a whole struct
        !          6970:               need not have MEM_IN_STRUCT_P.
        !          6971:               But a whole struct is *supposed* to have MEM_IN_STRUCT_P.  */
        !          6972:            elt->in_struct = (MEM_IN_STRUCT_P (sets[i].inner_dest)
        !          6973:                              || sets[i].inner_dest != SET_DEST (sets[i].rtl));
        !          6974:          }
        !          6975: 
        !          6976:        /* If we have (set (subreg:m1 (reg:m2 foo) 0) (bar:m1)), M1 is no
        !          6977:           narrower than M2, and both M1 and M2 are the same number of words,
        !          6978:           we are also doing (set (reg:m2 foo) (subreg:m2 (bar:m1) 0)) so
        !          6979:           make that equivalence as well.
        !          6980: 
        !          6981:           However, BAR may have equivalences for which gen_lowpart_if_possible
        !          6982:           will produce a simpler value than gen_lowpart_if_possible applied to
        !          6983:           BAR (e.g., if BAR was ZERO_EXTENDed from M2), so we will scan all
        !          6984:           BAR's equivalences.  If we don't get a simplified form, make 
        !          6985:           the SUBREG.  It will not be used in an equivalence, but will
        !          6986:           cause two similar assignments to be detected.
        !          6987: 
        !          6988:           Note the loop below will find SUBREG_REG (DEST) since we have
        !          6989:           already entered SRC and DEST of the SET in the table.  */
        !          6990: 
        !          6991:        if (GET_CODE (dest) == SUBREG
        !          6992:            && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest))) / UNITS_PER_WORD
        !          6993:                == GET_MODE_SIZE (GET_MODE (dest)) / UNITS_PER_WORD)
        !          6994:            && (GET_MODE_SIZE (GET_MODE (dest))
        !          6995:                >= GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest))))
        !          6996:            && sets[i].src_elt != 0)
        !          6997:          {
        !          6998:            enum machine_mode new_mode = GET_MODE (SUBREG_REG (dest));
        !          6999:            struct table_elt *elt, *classp = 0;
        !          7000: 
        !          7001:            for (elt = sets[i].src_elt->first_same_value; elt;
        !          7002:                 elt = elt->next_same_value)
        !          7003:              {
        !          7004:                rtx new_src = 0;
        !          7005:                int src_hash;
        !          7006:                struct table_elt *src_elt;
        !          7007: 
        !          7008:                /* Ignore invalid entries.  */
        !          7009:                if (GET_CODE (elt->exp) != REG
        !          7010:                    && ! exp_equiv_p (elt->exp, elt->exp, 1, 0))
        !          7011:                  continue;
        !          7012: 
        !          7013:                new_src = gen_lowpart_if_possible (new_mode, elt->exp);
        !          7014:                if (new_src == 0)
        !          7015:                  new_src = gen_rtx (SUBREG, new_mode, elt->exp, 0);
        !          7016: 
        !          7017:                src_hash = HASH (new_src, new_mode);
        !          7018:                src_elt = lookup (new_src, src_hash, new_mode);
        !          7019: 
        !          7020:                /* Put the new source in the hash table is if isn't
        !          7021:                   already.  */
        !          7022:                if (src_elt == 0)
        !          7023:                  {
        !          7024:                    if (insert_regs (new_src, classp, 0))
        !          7025:                      src_hash = HASH (new_src, new_mode);
        !          7026:                    src_elt = insert (new_src, classp, src_hash, new_mode);
        !          7027:                    src_elt->in_memory = elt->in_memory;
        !          7028:                    src_elt->in_struct = elt->in_struct;
        !          7029:                  }
        !          7030:                else if (classp && classp != src_elt->first_same_value)
        !          7031:                  /* Show that two things that we've seen before are 
        !          7032:                     actually the same.  */
        !          7033:                  merge_equiv_classes (src_elt, classp);
        !          7034: 
        !          7035:                classp = src_elt->first_same_value;
        !          7036:              }
        !          7037:          }
        !          7038:       }
        !          7039: 
        !          7040:   /* Special handling for (set REG0 REG1)
        !          7041:      where REG0 is the "cheapest", cheaper than REG1.
        !          7042:      After cse, REG1 will probably not be used in the sequel, 
        !          7043:      so (if easily done) change this insn to (set REG1 REG0) and
        !          7044:      replace REG1 with REG0 in the previous insn that computed their value.
        !          7045:      Then REG1 will become a dead store and won't cloud the situation
        !          7046:      for later optimizations.
        !          7047: 
        !          7048:      Do not make this change if REG1 is a hard register, because it will
        !          7049:      then be used in the sequel and we may be changing a two-operand insn
        !          7050:      into a three-operand insn.
        !          7051: 
        !          7052:      Also do not do this if we are operating on a copy of INSN.  */
        !          7053: 
        !          7054:   if (n_sets == 1 && sets[0].rtl && GET_CODE (SET_DEST (sets[0].rtl)) == REG
        !          7055:       && PREV_INSN(insn)
        !          7056:       && NEXT_INSN (PREV_INSN (insn)) == insn
        !          7057:       && GET_CODE (SET_SRC (sets[0].rtl)) == REG
        !          7058:       && REGNO (SET_SRC (sets[0].rtl)) >= FIRST_PSEUDO_REGISTER
        !          7059:       && REGNO_QTY_VALID_P (REGNO (SET_SRC (sets[0].rtl)))
        !          7060:       && (qty_first_reg[reg_qty[REGNO (SET_SRC (sets[0].rtl))]]
        !          7061:          == REGNO (SET_DEST (sets[0].rtl))))
        !          7062:     {
        !          7063:       rtx prev = PREV_INSN (insn);
        !          7064:       while (prev && GET_CODE (prev) == NOTE)
        !          7065:        prev = PREV_INSN (prev);
        !          7066: 
        !          7067:       if (prev && GET_CODE (prev) == INSN && GET_CODE (PATTERN (prev)) == SET
        !          7068:          && SET_DEST (PATTERN (prev)) == SET_SRC (sets[0].rtl))
        !          7069:        {
        !          7070:          rtx dest = SET_DEST (sets[0].rtl);
        !          7071:          rtx note = find_reg_note (prev, REG_EQUIV, NULL_RTX);
        !          7072: 
        !          7073:          validate_change (prev, & SET_DEST (PATTERN (prev)), dest, 1);
        !          7074:          validate_change (insn, & SET_DEST (sets[0].rtl),
        !          7075:                           SET_SRC (sets[0].rtl), 1);
        !          7076:          validate_change (insn, & SET_SRC (sets[0].rtl), dest, 1);
        !          7077:          apply_change_group ();
        !          7078: 
        !          7079:          /* If REG1 was equivalent to a constant, REG0 is not.  */
        !          7080:          if (note)
        !          7081:            PUT_REG_NOTE_KIND (note, REG_EQUAL);
        !          7082: 
        !          7083:          /* If there was a REG_WAS_0 note on PREV, remove it.  Move
        !          7084:             any REG_WAS_0 note on INSN to PREV.  */
        !          7085:          note = find_reg_note (prev, REG_WAS_0, NULL_RTX);
        !          7086:          if (note)
        !          7087:            remove_note (prev, note);
        !          7088: 
        !          7089:          note = find_reg_note (insn, REG_WAS_0, NULL_RTX);
        !          7090:          if (note)
        !          7091:            {
        !          7092:              remove_note (insn, note);
        !          7093:              XEXP (note, 1) = REG_NOTES (prev);
        !          7094:              REG_NOTES (prev) = note;
        !          7095:            }
        !          7096:        }
        !          7097:     }
        !          7098: 
        !          7099:   /* If this is a conditional jump insn, record any known equivalences due to
        !          7100:      the condition being tested.  */
        !          7101: 
        !          7102:   last_jump_equiv_class = 0;
        !          7103:   if (GET_CODE (insn) == JUMP_INSN
        !          7104:       && n_sets == 1 && GET_CODE (x) == SET
        !          7105:       && GET_CODE (SET_SRC (x)) == IF_THEN_ELSE)
        !          7106:     record_jump_equiv (insn, 0);
        !          7107: 
        !          7108: #ifdef HAVE_cc0
        !          7109:   /* If the previous insn set CC0 and this insn no longer references CC0,
        !          7110:      delete the previous insn.  Here we use the fact that nothing expects CC0
        !          7111:      to be valid over an insn, which is true until the final pass.  */
        !          7112:   if (prev_insn && GET_CODE (prev_insn) == INSN
        !          7113:       && (tem = single_set (prev_insn)) != 0
        !          7114:       && SET_DEST (tem) == cc0_rtx
        !          7115:       && ! reg_mentioned_p (cc0_rtx, x))
        !          7116:     {
        !          7117:       PUT_CODE (prev_insn, NOTE);
        !          7118:       NOTE_LINE_NUMBER (prev_insn) = NOTE_INSN_DELETED;
        !          7119:       NOTE_SOURCE_FILE (prev_insn) = 0;
        !          7120:     }
        !          7121: 
        !          7122:   prev_insn_cc0 = this_insn_cc0;
        !          7123:   prev_insn_cc0_mode = this_insn_cc0_mode;
        !          7124: #endif
        !          7125: 
        !          7126:   prev_insn = insn;
        !          7127: }
        !          7128: 
        !          7129: /* Store 1 in *WRITES_PTR for those categories of memory ref
        !          7130:    that must be invalidated when the expression WRITTEN is stored in.
        !          7131:    If WRITTEN is null, say everything must be invalidated.  */
        !          7132: 
        !          7133: static void
        !          7134: note_mem_written (written, writes_ptr)
        !          7135:      rtx written;
        !          7136:      struct write_data *writes_ptr;
        !          7137: {
        !          7138:   static struct write_data everything = {0, 1, 1, 1};
        !          7139: 
        !          7140:   if (written == 0)
        !          7141:     *writes_ptr = everything;
        !          7142:   else if (GET_CODE (written) == MEM)
        !          7143:     {
        !          7144:       /* Pushing or popping the stack invalidates just the stack pointer. */
        !          7145:       rtx addr = XEXP (written, 0);
        !          7146:       if ((GET_CODE (addr) == PRE_DEC || GET_CODE (addr) == PRE_INC
        !          7147:           || GET_CODE (addr) == POST_DEC || GET_CODE (addr) == POST_INC)
        !          7148:          && GET_CODE (XEXP (addr, 0)) == REG
        !          7149:          && REGNO (XEXP (addr, 0)) == STACK_POINTER_REGNUM)
        !          7150:        {
        !          7151:          writes_ptr->sp = 1;
        !          7152:          return;
        !          7153:        }
        !          7154:       else if (GET_MODE (written) == BLKmode)
        !          7155:        *writes_ptr = everything;
        !          7156:       /* (mem (scratch)) means clobber everything.  */
        !          7157:       else if (GET_CODE (addr) == SCRATCH)
        !          7158:        *writes_ptr = everything;
        !          7159:       else if (cse_rtx_addr_varies_p (written))
        !          7160:        {
        !          7161:          /* A varying address that is a sum indicates an array element,
        !          7162:             and that's just as good as a structure element
        !          7163:             in implying that we need not invalidate scalar variables.
        !          7164:             However, we must allow QImode aliasing of scalars, because the
        !          7165:             ANSI C standard allows character pointers to alias anything.  */
        !          7166:          if (! ((MEM_IN_STRUCT_P (written)
        !          7167:                  || GET_CODE (XEXP (written, 0)) == PLUS)
        !          7168:                 && GET_MODE (written) != QImode))
        !          7169:            writes_ptr->all = 1;
        !          7170:          writes_ptr->nonscalar = 1;
        !          7171:        }
        !          7172:       writes_ptr->var = 1;
        !          7173:     }
        !          7174: }
        !          7175: 
        !          7176: /* Perform invalidation on the basis of everything about an insn
        !          7177:    except for invalidating the actual places that are SET in it.
        !          7178:    This includes the places CLOBBERed, and anything that might
        !          7179:    alias with something that is SET or CLOBBERed.
        !          7180: 
        !          7181:    W points to the writes_memory for this insn, a struct write_data
        !          7182:    saying which kinds of memory references must be invalidated.
        !          7183:    X is the pattern of the insn.  */
        !          7184: 
        !          7185: static void
        !          7186: invalidate_from_clobbers (w, x)
        !          7187:      struct write_data *w;
        !          7188:      rtx x;
        !          7189: {
        !          7190:   /* If W->var is not set, W specifies no action.
        !          7191:      If W->all is set, this step gets all memory refs
        !          7192:      so they can be ignored in the rest of this function.  */
        !          7193:   if (w->var)
        !          7194:     invalidate_memory (w);
        !          7195: 
        !          7196:   if (w->sp)
        !          7197:     {
        !          7198:       if (reg_tick[STACK_POINTER_REGNUM] >= 0)
        !          7199:        reg_tick[STACK_POINTER_REGNUM]++;
        !          7200: 
        !          7201:       /* This should be *very* rare.  */
        !          7202:       if (TEST_HARD_REG_BIT (hard_regs_in_table, STACK_POINTER_REGNUM))
        !          7203:        invalidate (stack_pointer_rtx);
        !          7204:     }
        !          7205: 
        !          7206:   if (GET_CODE (x) == CLOBBER)
        !          7207:     {
        !          7208:       rtx ref = XEXP (x, 0);
        !          7209:       if (ref)
        !          7210:        {
        !          7211:          if (GET_CODE (ref) == REG || GET_CODE (ref) == SUBREG
        !          7212:              || (GET_CODE (ref) == MEM && ! w->all))
        !          7213:            invalidate (ref);
        !          7214:          else if (GET_CODE (ref) == STRICT_LOW_PART
        !          7215:                   || GET_CODE (ref) == ZERO_EXTRACT)
        !          7216:            invalidate (XEXP (ref, 0));
        !          7217:        }
        !          7218:     }
        !          7219:   else if (GET_CODE (x) == PARALLEL)
        !          7220:     {
        !          7221:       register int i;
        !          7222:       for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
        !          7223:        {
        !          7224:          register rtx y = XVECEXP (x, 0, i);
        !          7225:          if (GET_CODE (y) == CLOBBER)
        !          7226:            {
        !          7227:              rtx ref = XEXP (y, 0);
        !          7228:              if (ref)
        !          7229:                {
        !          7230:                  if (GET_CODE (ref) == REG || GET_CODE (ref) == SUBREG
        !          7231:                      || (GET_CODE (ref) == MEM && !w->all))
        !          7232:                    invalidate (ref);
        !          7233:                  else if (GET_CODE (ref) == STRICT_LOW_PART
        !          7234:                           || GET_CODE (ref) == ZERO_EXTRACT)
        !          7235:                    invalidate (XEXP (ref, 0));
        !          7236:                }
        !          7237:            }
        !          7238:        }
        !          7239:     }
        !          7240: }
        !          7241: 
        !          7242: /* Process X, part of the REG_NOTES of an insn.  Look at any REG_EQUAL notes
        !          7243:    and replace any registers in them with either an equivalent constant
        !          7244:    or the canonical form of the register.  If we are inside an address,
        !          7245:    only do this if the address remains valid.
        !          7246: 
        !          7247:    OBJECT is 0 except when within a MEM in which case it is the MEM.
        !          7248: 
        !          7249:    Return the replacement for X.  */
        !          7250: 
        !          7251: static rtx
        !          7252: cse_process_notes (x, object)
        !          7253:      rtx x;
        !          7254:      rtx object;
        !          7255: {
        !          7256:   enum rtx_code code = GET_CODE (x);
        !          7257:   char *fmt = GET_RTX_FORMAT (code);
        !          7258:   int i;
        !          7259: 
        !          7260:   switch (code)
        !          7261:     {
        !          7262:     case CONST_INT:
        !          7263:     case CONST:
        !          7264:     case SYMBOL_REF:
        !          7265:     case LABEL_REF:
        !          7266:     case CONST_DOUBLE:
        !          7267:     case PC:
        !          7268:     case CC0:
        !          7269:     case LO_SUM:
        !          7270:       return x;
        !          7271: 
        !          7272:     case MEM:
        !          7273:       XEXP (x, 0) = cse_process_notes (XEXP (x, 0), x);
        !          7274:       return x;
        !          7275: 
        !          7276:     case EXPR_LIST:
        !          7277:     case INSN_LIST:
        !          7278:       if (REG_NOTE_KIND (x) == REG_EQUAL)
        !          7279:        XEXP (x, 0) = cse_process_notes (XEXP (x, 0), NULL_RTX);
        !          7280:       if (XEXP (x, 1))
        !          7281:        XEXP (x, 1) = cse_process_notes (XEXP (x, 1), NULL_RTX);
        !          7282:       return x;
        !          7283: 
        !          7284:     case SIGN_EXTEND:
        !          7285:     case ZERO_EXTEND:
        !          7286:       {
        !          7287:        rtx new = cse_process_notes (XEXP (x, 0), object);
        !          7288:        /* We don't substitute VOIDmode constants into these rtx,
        !          7289:           since they would impede folding.  */
        !          7290:        if (GET_MODE (new) != VOIDmode)
        !          7291:          validate_change (object, &XEXP (x, 0), new, 0);
        !          7292:        return x;
        !          7293:       }
        !          7294: 
        !          7295:     case REG:
        !          7296:       i = reg_qty[REGNO (x)];
        !          7297: 
        !          7298:       /* Return a constant or a constant register.  */
        !          7299:       if (REGNO_QTY_VALID_P (REGNO (x))
        !          7300:          && qty_const[i] != 0
        !          7301:          && (CONSTANT_P (qty_const[i])
        !          7302:              || GET_CODE (qty_const[i]) == REG))
        !          7303:        {
        !          7304:          rtx new = gen_lowpart_if_possible (GET_MODE (x), qty_const[i]);
        !          7305:          if (new)
        !          7306:            return new;
        !          7307:        }
        !          7308: 
        !          7309:       /* Otherwise, canonicalize this register.  */
        !          7310:       return canon_reg (x, NULL_RTX);
        !          7311:     }
        !          7312: 
        !          7313:   for (i = 0; i < GET_RTX_LENGTH (code); i++)
        !          7314:     if (fmt[i] == 'e')
        !          7315:       validate_change (object, &XEXP (x, i),
        !          7316:                       cse_process_notes (XEXP (x, i), object), 0);
        !          7317: 
        !          7318:   return x;
        !          7319: }
        !          7320: 
        !          7321: /* Find common subexpressions between the end test of a loop and the beginning
        !          7322:    of the loop.  LOOP_START is the CODE_LABEL at the start of a loop.
        !          7323: 
        !          7324:    Often we have a loop where an expression in the exit test is used
        !          7325:    in the body of the loop.  For example "while (*p) *q++ = *p++;".
        !          7326:    Because of the way we duplicate the loop exit test in front of the loop,
        !          7327:    however, we don't detect that common subexpression.  This will be caught
        !          7328:    when global cse is implemented, but this is a quite common case.
        !          7329: 
        !          7330:    This function handles the most common cases of these common expressions.
        !          7331:    It is called after we have processed the basic block ending with the
        !          7332:    NOTE_INSN_LOOP_END note that ends a loop and the previous JUMP_INSN
        !          7333:    jumps to a label used only once.  */
        !          7334: 
        !          7335: static void
        !          7336: cse_around_loop (loop_start)
        !          7337:      rtx loop_start;
        !          7338: {
        !          7339:   rtx insn;
        !          7340:   int i;
        !          7341:   struct table_elt *p;
        !          7342: 
        !          7343:   /* If the jump at the end of the loop doesn't go to the start, we don't
        !          7344:      do anything.  */
        !          7345:   for (insn = PREV_INSN (loop_start);
        !          7346:        insn && (GET_CODE (insn) == NOTE && NOTE_LINE_NUMBER (insn) >= 0);
        !          7347:        insn = PREV_INSN (insn))
        !          7348:     ;
        !          7349: 
        !          7350:   if (insn == 0
        !          7351:       || GET_CODE (insn) != NOTE
        !          7352:       || NOTE_LINE_NUMBER (insn) != NOTE_INSN_LOOP_BEG)
        !          7353:     return;
        !          7354: 
        !          7355:   /* If the last insn of the loop (the end test) was an NE comparison,
        !          7356:      we will interpret it as an EQ comparison, since we fell through
        !          7357:      the loop.  Any equivalences resulting from that comparison are
        !          7358:      therefore not valid and must be invalidated.  */
        !          7359:   if (last_jump_equiv_class)
        !          7360:     for (p = last_jump_equiv_class->first_same_value; p;
        !          7361:         p = p->next_same_value)
        !          7362:       if (GET_CODE (p->exp) == MEM || GET_CODE (p->exp) == REG
        !          7363:          || GET_CODE (p->exp) == SUBREG)
        !          7364:        invalidate (p->exp);
        !          7365:       else if (GET_CODE (p->exp) == STRICT_LOW_PART
        !          7366:               || GET_CODE (p->exp) == ZERO_EXTRACT)
        !          7367:        invalidate (XEXP (p->exp, 0));
        !          7368: 
        !          7369:   /* Process insns starting after LOOP_START until we hit a CALL_INSN or
        !          7370:      a CODE_LABEL (we could handle a CALL_INSN, but it isn't worth it).
        !          7371: 
        !          7372:      The only thing we do with SET_DEST is invalidate entries, so we
        !          7373:      can safely process each SET in order.  It is slightly less efficient
        !          7374:      to do so, but we only want to handle the most common cases.  */
        !          7375: 
        !          7376:   for (insn = NEXT_INSN (loop_start);
        !          7377:        GET_CODE (insn) != CALL_INSN && GET_CODE (insn) != CODE_LABEL
        !          7378:        && ! (GET_CODE (insn) == NOTE
        !          7379:             && NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END);
        !          7380:        insn = NEXT_INSN (insn))
        !          7381:     {
        !          7382:       if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
        !          7383:          && (GET_CODE (PATTERN (insn)) == SET
        !          7384:              || GET_CODE (PATTERN (insn)) == CLOBBER))
        !          7385:        cse_set_around_loop (PATTERN (insn), insn, loop_start);
        !          7386:       else if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
        !          7387:               && GET_CODE (PATTERN (insn)) == PARALLEL)
        !          7388:        for (i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--)
        !          7389:          if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET
        !          7390:              || GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == CLOBBER)
        !          7391:            cse_set_around_loop (XVECEXP (PATTERN (insn), 0, i), insn,
        !          7392:                                 loop_start);
        !          7393:     }
        !          7394: }
        !          7395: 
        !          7396: /* Variable used for communications between the next two routines.  */
        !          7397: 
        !          7398: static struct write_data skipped_writes_memory;
        !          7399: 
        !          7400: /* Process one SET of an insn that was skipped.  We ignore CLOBBERs
        !          7401:    since they are done elsewhere.  This function is called via note_stores.  */
        !          7402: 
        !          7403: static void
        !          7404: invalidate_skipped_set (dest, set)
        !          7405:      rtx set;
        !          7406:      rtx dest;
        !          7407: {
        !          7408:   if (GET_CODE (set) == CLOBBER
        !          7409: #ifdef HAVE_cc0
        !          7410:       || dest == cc0_rtx
        !          7411: #endif
        !          7412:       || dest == pc_rtx)
        !          7413:     return;
        !          7414: 
        !          7415:   if (GET_CODE (dest) == MEM)
        !          7416:     note_mem_written (dest, &skipped_writes_memory);
        !          7417: 
        !          7418:   /* There are times when an address can appear varying and be a PLUS
        !          7419:      during this scan when it would be a fixed address were we to know
        !          7420:      the proper equivalences.  So promote "nonscalar" to be "all".  */
        !          7421:   if (skipped_writes_memory.nonscalar)
        !          7422:     skipped_writes_memory.all = 1;
        !          7423: 
        !          7424:   if (GET_CODE (dest) == REG || GET_CODE (dest) == SUBREG
        !          7425:       || (! skipped_writes_memory.all && ! cse_rtx_addr_varies_p (dest)))
        !          7426:     invalidate (dest);
        !          7427:   else if (GET_CODE (dest) == STRICT_LOW_PART
        !          7428:           || GET_CODE (dest) == ZERO_EXTRACT)
        !          7429:     invalidate (XEXP (dest, 0));
        !          7430: }
        !          7431: 
        !          7432: /* Invalidate all insns from START up to the end of the function or the
        !          7433:    next label.  This called when we wish to CSE around a block that is
        !          7434:    conditionally executed.  */
        !          7435: 
        !          7436: static void
        !          7437: invalidate_skipped_block (start)
        !          7438:      rtx start;
        !          7439: {
        !          7440:   rtx insn;
        !          7441:   static struct write_data init = {0, 0, 0, 0};
        !          7442:   static struct write_data everything = {0, 1, 1, 1};
        !          7443: 
        !          7444:   for (insn = start; insn && GET_CODE (insn) != CODE_LABEL;
        !          7445:        insn = NEXT_INSN (insn))
        !          7446:     {
        !          7447:       if (GET_RTX_CLASS (GET_CODE (insn)) != 'i')
        !          7448:        continue;
        !          7449: 
        !          7450:       skipped_writes_memory = init;
        !          7451: 
        !          7452:       if (GET_CODE (insn) == CALL_INSN)
        !          7453:        {
        !          7454:          invalidate_for_call ();
        !          7455:          skipped_writes_memory = everything;
        !          7456:        }
        !          7457: 
        !          7458:       note_stores (PATTERN (insn), invalidate_skipped_set);
        !          7459:       invalidate_from_clobbers (&skipped_writes_memory, PATTERN (insn));
        !          7460:     }
        !          7461: }
        !          7462: 
        !          7463: /* Used for communication between the following two routines; contains a
        !          7464:    value to be checked for modification.  */
        !          7465: 
        !          7466: static rtx cse_check_loop_start_value;
        !          7467: 
        !          7468: /* If modifying X will modify the value in CSE_CHECK_LOOP_START_VALUE,
        !          7469:    indicate that fact by setting CSE_CHECK_LOOP_START_VALUE to 0.  */
        !          7470: 
        !          7471: static void
        !          7472: cse_check_loop_start (x, set)
        !          7473:      rtx x;
        !          7474:      rtx set;
        !          7475: {
        !          7476:   if (cse_check_loop_start_value == 0
        !          7477:       || GET_CODE (x) == CC0 || GET_CODE (x) == PC)
        !          7478:     return;
        !          7479: 
        !          7480:   if ((GET_CODE (x) == MEM && GET_CODE (cse_check_loop_start_value) == MEM)
        !          7481:       || reg_overlap_mentioned_p (x, cse_check_loop_start_value))
        !          7482:     cse_check_loop_start_value = 0;
        !          7483: }
        !          7484: 
        !          7485: /* X is a SET or CLOBBER contained in INSN that was found near the start of
        !          7486:    a loop that starts with the label at LOOP_START.
        !          7487: 
        !          7488:    If X is a SET, we see if its SET_SRC is currently in our hash table.
        !          7489:    If so, we see if it has a value equal to some register used only in the
        !          7490:    loop exit code (as marked by jump.c).
        !          7491: 
        !          7492:    If those two conditions are true, we search backwards from the start of
        !          7493:    the loop to see if that same value was loaded into a register that still
        !          7494:    retains its value at the start of the loop.
        !          7495: 
        !          7496:    If so, we insert an insn after the load to copy the destination of that
        !          7497:    load into the equivalent register and (try to) replace our SET_SRC with that
        !          7498:    register.
        !          7499: 
        !          7500:    In any event, we invalidate whatever this SET or CLOBBER modifies.  */
        !          7501: 
        !          7502: static void
        !          7503: cse_set_around_loop (x, insn, loop_start)
        !          7504:      rtx x;
        !          7505:      rtx insn;
        !          7506:      rtx loop_start;
        !          7507: {
        !          7508:   struct table_elt *src_elt;
        !          7509:   static struct write_data init = {0, 0, 0, 0};
        !          7510:   struct write_data writes_memory;
        !          7511: 
        !          7512:   writes_memory = init;
        !          7513: 
        !          7514:   /* If this is a SET, see if we can replace SET_SRC, but ignore SETs that
        !          7515:      are setting PC or CC0 or whose SET_SRC is already a register.  */
        !          7516:   if (GET_CODE (x) == SET
        !          7517:       && GET_CODE (SET_DEST (x)) != PC && GET_CODE (SET_DEST (x)) != CC0
        !          7518:       && GET_CODE (SET_SRC (x)) != REG)
        !          7519:     {
        !          7520:       src_elt = lookup (SET_SRC (x),
        !          7521:                        HASH (SET_SRC (x), GET_MODE (SET_DEST (x))),
        !          7522:                        GET_MODE (SET_DEST (x)));
        !          7523: 
        !          7524:       if (src_elt)
        !          7525:        for (src_elt = src_elt->first_same_value; src_elt;
        !          7526:             src_elt = src_elt->next_same_value)
        !          7527:          if (GET_CODE (src_elt->exp) == REG && REG_LOOP_TEST_P (src_elt->exp)
        !          7528:              && COST (src_elt->exp) < COST (SET_SRC (x)))
        !          7529:            {
        !          7530:              rtx p, set;
        !          7531: 
        !          7532:              /* Look for an insn in front of LOOP_START that sets
        !          7533:                 something in the desired mode to SET_SRC (x) before we hit
        !          7534:                 a label or CALL_INSN.  */
        !          7535: 
        !          7536:              for (p = prev_nonnote_insn (loop_start);
        !          7537:                   p && GET_CODE (p) != CALL_INSN
        !          7538:                   && GET_CODE (p) != CODE_LABEL;
        !          7539:                   p = prev_nonnote_insn  (p))
        !          7540:                if ((set = single_set (p)) != 0
        !          7541:                    && GET_CODE (SET_DEST (set)) == REG
        !          7542:                    && GET_MODE (SET_DEST (set)) == src_elt->mode
        !          7543:                    && rtx_equal_p (SET_SRC (set), SET_SRC (x)))
        !          7544:                  {
        !          7545:                    /* We now have to ensure that nothing between P
        !          7546:                       and LOOP_START modified anything referenced in
        !          7547:                       SET_SRC (x).  We know that nothing within the loop
        !          7548:                       can modify it, or we would have invalidated it in
        !          7549:                       the hash table.  */
        !          7550:                    rtx q;
        !          7551: 
        !          7552:                    cse_check_loop_start_value = SET_SRC (x);
        !          7553:                    for (q = p; q != loop_start; q = NEXT_INSN (q))
        !          7554:                      if (GET_RTX_CLASS (GET_CODE (q)) == 'i')
        !          7555:                        note_stores (PATTERN (q), cse_check_loop_start);
        !          7556: 
        !          7557:                    /* If nothing was changed and we can replace our
        !          7558:                       SET_SRC, add an insn after P to copy its destination
        !          7559:                       to what we will be replacing SET_SRC with.  */
        !          7560:                    if (cse_check_loop_start_value
        !          7561:                        && validate_change (insn, &SET_SRC (x),
        !          7562:                                            src_elt->exp, 0))
        !          7563:                      emit_insn_after (gen_move_insn (src_elt->exp,
        !          7564:                                                      SET_DEST (set)),
        !          7565:                                       p);
        !          7566:                    break;
        !          7567:                  }
        !          7568:            }
        !          7569:     }
        !          7570: 
        !          7571:   /* Now invalidate anything modified by X.  */
        !          7572:   note_mem_written (SET_DEST (x), &writes_memory);
        !          7573: 
        !          7574:   if (writes_memory.var)
        !          7575:     invalidate_memory (&writes_memory);
        !          7576: 
        !          7577:   /* See comment on similar code in cse_insn for explanation of these tests. */
        !          7578:   if (GET_CODE (SET_DEST (x)) == REG || GET_CODE (SET_DEST (x)) == SUBREG
        !          7579:       || (GET_CODE (SET_DEST (x)) == MEM && ! writes_memory.all
        !          7580:          && ! cse_rtx_addr_varies_p (SET_DEST (x))))
        !          7581:     invalidate (SET_DEST (x));
        !          7582:   else if (GET_CODE (SET_DEST (x)) == STRICT_LOW_PART
        !          7583:           || GET_CODE (SET_DEST (x)) == ZERO_EXTRACT)
        !          7584:     invalidate (XEXP (SET_DEST (x), 0));
        !          7585: }
        !          7586: 
        !          7587: /* Find the end of INSN's basic block and return its range,
        !          7588:    the total number of SETs in all the insns of the block, the last insn of the
        !          7589:    block, and the branch path.
        !          7590: 
        !          7591:    The branch path indicates which branches should be followed.  If a non-zero
        !          7592:    path size is specified, the block should be rescanned and a different set
        !          7593:    of branches will be taken.  The branch path is only used if
        !          7594:    FLAG_CSE_FOLLOW_JUMPS or FLAG_CSE_SKIP_BLOCKS is non-zero.
        !          7595: 
        !          7596:    DATA is a pointer to a struct cse_basic_block_data, defined below, that is
        !          7597:    used to describe the block.  It is filled in with the information about
        !          7598:    the current block.  The incoming structure's branch path, if any, is used
        !          7599:    to construct the output branch path.  */
        !          7600: 
        !          7601: void
        !          7602: cse_end_of_basic_block (insn, data, follow_jumps, after_loop, skip_blocks)
        !          7603:      rtx insn;
        !          7604:      struct cse_basic_block_data *data;
        !          7605:      int follow_jumps;
        !          7606:      int after_loop;
        !          7607:      int skip_blocks;
        !          7608: {
        !          7609:   rtx p = insn, q;
        !          7610:   int nsets = 0;
        !          7611:   int low_cuid = INSN_CUID (insn), high_cuid = INSN_CUID (insn);
        !          7612:   rtx next = GET_RTX_CLASS (GET_CODE (insn)) == 'i' ? insn : next_real_insn (insn);
        !          7613:   int path_size = data->path_size;
        !          7614:   int path_entry = 0;
        !          7615:   int i;
        !          7616: 
        !          7617:   /* Update the previous branch path, if any.  If the last branch was
        !          7618:      previously TAKEN, mark it NOT_TAKEN.  If it was previously NOT_TAKEN,
        !          7619:      shorten the path by one and look at the previous branch.  We know that
        !          7620:      at least one branch must have been taken if PATH_SIZE is non-zero.  */
        !          7621:   while (path_size > 0)
        !          7622:     {
        !          7623:       if (data->path[path_size - 1].status != NOT_TAKEN)
        !          7624:        {
        !          7625:          data->path[path_size - 1].status = NOT_TAKEN;
        !          7626:          break;
        !          7627:        }
        !          7628:       else
        !          7629:        path_size--;
        !          7630:     }
        !          7631: 
        !          7632:   /* Scan to end of this basic block.  */
        !          7633:   while (p && GET_CODE (p) != CODE_LABEL)
        !          7634:     {
        !          7635:       /* Don't cse out the end of a loop.  This makes a difference
        !          7636:         only for the unusual loops that always execute at least once;
        !          7637:         all other loops have labels there so we will stop in any case.
        !          7638:         Cse'ing out the end of the loop is dangerous because it
        !          7639:         might cause an invariant expression inside the loop
        !          7640:         to be reused after the end of the loop.  This would make it
        !          7641:         hard to move the expression out of the loop in loop.c,
        !          7642:         especially if it is one of several equivalent expressions
        !          7643:         and loop.c would like to eliminate it.
        !          7644: 
        !          7645:         If we are running after loop.c has finished, we can ignore
        !          7646:         the NOTE_INSN_LOOP_END.  */
        !          7647: 
        !          7648:       if (! after_loop && GET_CODE (p) == NOTE
        !          7649:          && NOTE_LINE_NUMBER (p) == NOTE_INSN_LOOP_END)
        !          7650:        break;
        !          7651: 
        !          7652:       /* Don't cse over a call to setjmp; on some machines (eg vax)
        !          7653:         the regs restored by the longjmp come from
        !          7654:         a later time than the setjmp.  */
        !          7655:       if (GET_CODE (p) == NOTE
        !          7656:          && NOTE_LINE_NUMBER (p) == NOTE_INSN_SETJMP)
        !          7657:        break;
        !          7658: 
        !          7659:       /* A PARALLEL can have lots of SETs in it,
        !          7660:         especially if it is really an ASM_OPERANDS.  */
        !          7661:       if (GET_RTX_CLASS (GET_CODE (p)) == 'i'
        !          7662:          && GET_CODE (PATTERN (p)) == PARALLEL)
        !          7663:        nsets += XVECLEN (PATTERN (p), 0);
        !          7664:       else if (GET_CODE (p) != NOTE)
        !          7665:        nsets += 1;
        !          7666:        
        !          7667:       /* Ignore insns made by CSE; they cannot affect the boundaries of
        !          7668:         the basic block.  */
        !          7669: 
        !          7670:       if (INSN_UID (p) <= max_uid && INSN_CUID (p) > high_cuid)
        !          7671:        high_cuid = INSN_CUID (p);
        !          7672:       if (INSN_UID (p) <= max_uid && INSN_CUID (p) < low_cuid)
        !          7673:        low_cuid = INSN_CUID (p);
        !          7674: 
        !          7675:       /* See if this insn is in our branch path.  If it is and we are to
        !          7676:         take it, do so.  */
        !          7677:       if (path_entry < path_size && data->path[path_entry].branch == p)
        !          7678:        {
        !          7679:          if (data->path[path_entry].status != NOT_TAKEN)
        !          7680:            p = JUMP_LABEL (p);
        !          7681:          
        !          7682:          /* Point to next entry in path, if any.  */
        !          7683:          path_entry++;
        !          7684:        }
        !          7685: 
        !          7686:       /* If this is a conditional jump, we can follow it if -fcse-follow-jumps
        !          7687:         was specified, we haven't reached our maximum path length, there are
        !          7688:         insns following the target of the jump, this is the only use of the
        !          7689:         jump label, and the target label is preceded by a BARRIER.
        !          7690: 
        !          7691:         Alternatively, we can follow the jump if it branches around a
        !          7692:         block of code and there are no other branches into the block.
        !          7693:         In this case invalidate_skipped_block will be called to invalidate any
        !          7694:         registers set in the block when following the jump.  */
        !          7695: 
        !          7696:       else if ((follow_jumps || skip_blocks) && path_size < PATHLENGTH - 1
        !          7697:               && GET_CODE (p) == JUMP_INSN
        !          7698:               && GET_CODE (PATTERN (p)) == SET
        !          7699:               && GET_CODE (SET_SRC (PATTERN (p))) == IF_THEN_ELSE
        !          7700:               && LABEL_NUSES (JUMP_LABEL (p)) == 1
        !          7701:               && NEXT_INSN (JUMP_LABEL (p)) != 0)
        !          7702:        {
        !          7703:          for (q = PREV_INSN (JUMP_LABEL (p)); q; q = PREV_INSN (q))
        !          7704:            if ((GET_CODE (q) != NOTE
        !          7705:                 || NOTE_LINE_NUMBER (q) == NOTE_INSN_LOOP_END
        !          7706:                 || NOTE_LINE_NUMBER (q) == NOTE_INSN_SETJMP)
        !          7707:                && (GET_CODE (q) != CODE_LABEL || LABEL_NUSES (q) != 0))
        !          7708:              break;
        !          7709: 
        !          7710:          /* If we ran into a BARRIER, this code is an extension of the
        !          7711:             basic block when the branch is taken.  */
        !          7712:          if (follow_jumps && q != 0 && GET_CODE (q) == BARRIER)
        !          7713:            {
        !          7714:              /* Don't allow ourself to keep walking around an
        !          7715:                 always-executed loop.  */
        !          7716:              if (next_real_insn (q) == next)
        !          7717:                {
        !          7718:                  p = NEXT_INSN (p);
        !          7719:                  continue;
        !          7720:                }
        !          7721: 
        !          7722:              /* Similarly, don't put a branch in our path more than once.  */
        !          7723:              for (i = 0; i < path_entry; i++)
        !          7724:                if (data->path[i].branch == p)
        !          7725:                  break;
        !          7726: 
        !          7727:              if (i != path_entry)
        !          7728:                break;
        !          7729: 
        !          7730:              data->path[path_entry].branch = p;
        !          7731:              data->path[path_entry++].status = TAKEN;
        !          7732: 
        !          7733:              /* This branch now ends our path.  It was possible that we
        !          7734:                 didn't see this branch the last time around (when the
        !          7735:                 insn in front of the target was a JUMP_INSN that was
        !          7736:                 turned into a no-op).  */
        !          7737:              path_size = path_entry;
        !          7738: 
        !          7739:              p = JUMP_LABEL (p);
        !          7740:              /* Mark block so we won't scan it again later.  */
        !          7741:              PUT_MODE (NEXT_INSN (p), QImode);
        !          7742:            }
        !          7743:          /* Detect a branch around a block of code.  */
        !          7744:          else if (skip_blocks && q != 0 && GET_CODE (q) != CODE_LABEL)
        !          7745:            {
        !          7746:              register rtx tmp;
        !          7747: 
        !          7748:              if (next_real_insn (q) == next)
        !          7749:                {
        !          7750:                  p = NEXT_INSN (p);
        !          7751:                  continue;
        !          7752:                }
        !          7753: 
        !          7754:              for (i = 0; i < path_entry; i++)
        !          7755:                if (data->path[i].branch == p)
        !          7756:                  break;
        !          7757: 
        !          7758:              if (i != path_entry)
        !          7759:                break;
        !          7760: 
        !          7761:              /* This is no_labels_between_p (p, q) with an added check for
        !          7762:                 reaching the end of a function (in case Q precedes P).  */
        !          7763:              for (tmp = NEXT_INSN (p); tmp && tmp != q; tmp = NEXT_INSN (tmp))
        !          7764:                if (GET_CODE (tmp) == CODE_LABEL)
        !          7765:                  break;
        !          7766:              
        !          7767:              if (tmp == q)
        !          7768:                {
        !          7769:                  data->path[path_entry].branch = p;
        !          7770:                  data->path[path_entry++].status = AROUND;
        !          7771: 
        !          7772:                  path_size = path_entry;
        !          7773: 
        !          7774:                  p = JUMP_LABEL (p);
        !          7775:                  /* Mark block so we won't scan it again later.  */
        !          7776:                  PUT_MODE (NEXT_INSN (p), QImode);
        !          7777:                }
        !          7778:            }
        !          7779:        }
        !          7780:       p = NEXT_INSN (p);
        !          7781:     }
        !          7782: 
        !          7783:   data->low_cuid = low_cuid;
        !          7784:   data->high_cuid = high_cuid;
        !          7785:   data->nsets = nsets;
        !          7786:   data->last = p;
        !          7787: 
        !          7788:   /* If all jumps in the path are not taken, set our path length to zero
        !          7789:      so a rescan won't be done.  */
        !          7790:   for (i = path_size - 1; i >= 0; i--)
        !          7791:     if (data->path[i].status != NOT_TAKEN)
        !          7792:       break;
        !          7793: 
        !          7794:   if (i == -1)
        !          7795:     data->path_size = 0;
        !          7796:   else
        !          7797:     data->path_size = path_size;
        !          7798: 
        !          7799:   /* End the current branch path.  */
        !          7800:   data->path[path_size].branch = 0;
        !          7801: }
        !          7802: 
        !          7803: /* Perform cse on the instructions of a function.
        !          7804:    F is the first instruction.
        !          7805:    NREGS is one plus the highest pseudo-reg number used in the instruction.
        !          7806: 
        !          7807:    AFTER_LOOP is 1 if this is the cse call done after loop optimization
        !          7808:    (only if -frerun-cse-after-loop).
        !          7809: 
        !          7810:    Returns 1 if jump_optimize should be redone due to simplifications
        !          7811:    in conditional jump instructions.  */
        !          7812: 
        !          7813: int
        !          7814: cse_main (f, nregs, after_loop, file)
        !          7815:      rtx f;
        !          7816:      int nregs;
        !          7817:      int after_loop;
        !          7818:      FILE *file;
        !          7819: {
        !          7820:   struct cse_basic_block_data val;
        !          7821:   register rtx insn = f;
        !          7822:   register int i;
        !          7823: 
        !          7824:   cse_jumps_altered = 0;
        !          7825:   constant_pool_entries_cost = 0;
        !          7826:   val.path_size = 0;
        !          7827: 
        !          7828:   init_recog ();
        !          7829: 
        !          7830:   max_reg = nregs;
        !          7831: 
        !          7832:   all_minus_one = (int *) alloca (nregs * sizeof (int));
        !          7833:   consec_ints = (int *) alloca (nregs * sizeof (int));
        !          7834: 
        !          7835:   for (i = 0; i < nregs; i++)
        !          7836:     {
        !          7837:       all_minus_one[i] = -1;
        !          7838:       consec_ints[i] = i;
        !          7839:     }
        !          7840: 
        !          7841:   reg_next_eqv = (int *) alloca (nregs * sizeof (int));
        !          7842:   reg_prev_eqv = (int *) alloca (nregs * sizeof (int));
        !          7843:   reg_qty = (int *) alloca (nregs * sizeof (int));
        !          7844:   reg_in_table = (int *) alloca (nregs * sizeof (int));
        !          7845:   reg_tick = (int *) alloca (nregs * sizeof (int));
        !          7846: 
        !          7847:   /* Discard all the free elements of the previous function
        !          7848:      since they are allocated in the temporarily obstack.  */
        !          7849:   bzero (table, sizeof table);
        !          7850:   free_element_chain = 0;
        !          7851:   n_elements_made = 0;
        !          7852: 
        !          7853:   /* Find the largest uid.  */
        !          7854: 
        !          7855:   max_uid = get_max_uid ();
        !          7856:   uid_cuid = (int *) alloca ((max_uid + 1) * sizeof (int));
        !          7857:   bzero (uid_cuid, (max_uid + 1) * sizeof (int));
        !          7858: 
        !          7859:   /* Compute the mapping from uids to cuids.
        !          7860:      CUIDs are numbers assigned to insns, like uids,
        !          7861:      except that cuids increase monotonically through the code.
        !          7862:      Don't assign cuids to line-number NOTEs, so that the distance in cuids
        !          7863:      between two insns is not affected by -g.  */
        !          7864: 
        !          7865:   for (insn = f, i = 0; insn; insn = NEXT_INSN (insn))
        !          7866:     {
        !          7867:       if (GET_CODE (insn) != NOTE
        !          7868:          || NOTE_LINE_NUMBER (insn) < 0)
        !          7869:        INSN_CUID (insn) = ++i;
        !          7870:       else
        !          7871:        /* Give a line number note the same cuid as preceding insn.  */
        !          7872:        INSN_CUID (insn) = i;
        !          7873:     }
        !          7874: 
        !          7875:   /* Initialize which registers are clobbered by calls.  */
        !          7876: 
        !          7877:   CLEAR_HARD_REG_SET (regs_invalidated_by_call);
        !          7878: 
        !          7879:   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
        !          7880:     if ((call_used_regs[i]
        !          7881:         /* Used to check !fixed_regs[i] here, but that isn't safe;
        !          7882:            fixed regs are still call-clobbered, and sched can get
        !          7883:            confused if they can "live across calls".
        !          7884: 
        !          7885:            The frame pointer is always preserved across calls.  The arg
        !          7886:            pointer is if it is fixed.  The stack pointer usually is, unless
        !          7887:            RETURN_POPS_ARGS, in which case an explicit CLOBBER
        !          7888:            will be present.  If we are generating PIC code, the PIC offset
        !          7889:            table register is preserved across calls.  */
        !          7890: 
        !          7891:         && i != STACK_POINTER_REGNUM
        !          7892:         && i != FRAME_POINTER_REGNUM
        !          7893: #if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
        !          7894:         && i != HARD_FRAME_POINTER_REGNUM
        !          7895: #endif
        !          7896: #if ARG_POINTER_REGNUM != FRAME_POINTER_REGNUM
        !          7897:         && ! (i == ARG_POINTER_REGNUM && fixed_regs[i])
        !          7898: #endif
        !          7899: #ifdef PIC_OFFSET_TABLE_REGNUM
        !          7900:         && ! (i == PIC_OFFSET_TABLE_REGNUM && flag_pic)
        !          7901: #endif
        !          7902:         )
        !          7903:        || global_regs[i])
        !          7904:       SET_HARD_REG_BIT (regs_invalidated_by_call, i);
        !          7905: 
        !          7906:   /* Loop over basic blocks.
        !          7907:      Compute the maximum number of qty's needed for each basic block
        !          7908:      (which is 2 for each SET).  */
        !          7909:   insn = f;
        !          7910:   while (insn)
        !          7911:     {
        !          7912:       cse_end_of_basic_block (insn, &val, flag_cse_follow_jumps, after_loop,
        !          7913:                              flag_cse_skip_blocks);
        !          7914: 
        !          7915:       /* If this basic block was already processed or has no sets, skip it.  */
        !          7916:       if (val.nsets == 0 || GET_MODE (insn) == QImode)
        !          7917:        {
        !          7918:          PUT_MODE (insn, VOIDmode);
        !          7919:          insn = (val.last ? NEXT_INSN (val.last) : 0);
        !          7920:          val.path_size = 0;
        !          7921:          continue;
        !          7922:        }
        !          7923: 
        !          7924:       cse_basic_block_start = val.low_cuid;
        !          7925:       cse_basic_block_end = val.high_cuid;
        !          7926:       max_qty = val.nsets * 2;
        !          7927:       
        !          7928:       if (file)
        !          7929:        fprintf (file, ";; Processing block from %d to %d, %d sets.\n",
        !          7930:                 INSN_UID (insn), val.last ? INSN_UID (val.last) : 0,
        !          7931:                 val.nsets);
        !          7932: 
        !          7933:       /* Make MAX_QTY bigger to give us room to optimize
        !          7934:         past the end of this basic block, if that should prove useful.  */
        !          7935:       if (max_qty < 500)
        !          7936:        max_qty = 500;
        !          7937: 
        !          7938:       max_qty += max_reg;
        !          7939: 
        !          7940:       /* If this basic block is being extended by following certain jumps,
        !          7941:          (see `cse_end_of_basic_block'), we reprocess the code from the start.
        !          7942:          Otherwise, we start after this basic block.  */
        !          7943:       if (val.path_size > 0)
        !          7944:         cse_basic_block (insn, val.last, val.path, 0);
        !          7945:       else
        !          7946:        {
        !          7947:          int old_cse_jumps_altered = cse_jumps_altered;
        !          7948:          rtx temp;
        !          7949: 
        !          7950:          /* When cse changes a conditional jump to an unconditional
        !          7951:             jump, we want to reprocess the block, since it will give
        !          7952:             us a new branch path to investigate.  */
        !          7953:          cse_jumps_altered = 0;
        !          7954:          temp = cse_basic_block (insn, val.last, val.path, ! after_loop);
        !          7955:          if (cse_jumps_altered == 0
        !          7956:              || (flag_cse_follow_jumps == 0 && flag_cse_skip_blocks == 0))
        !          7957:            insn = temp;
        !          7958: 
        !          7959:          cse_jumps_altered |= old_cse_jumps_altered;
        !          7960:        }
        !          7961: 
        !          7962: #ifdef USE_C_ALLOCA
        !          7963:       alloca (0);
        !          7964: #endif
        !          7965:     }
        !          7966: 
        !          7967:   /* Tell refers_to_mem_p that qty_const info is not available.  */
        !          7968:   qty_const = 0;
        !          7969: 
        !          7970:   if (max_elements_made < n_elements_made)
        !          7971:     max_elements_made = n_elements_made;
        !          7972: 
        !          7973:   return cse_jumps_altered;
        !          7974: }
        !          7975: 
        !          7976: /* Process a single basic block.  FROM and TO and the limits of the basic
        !          7977:    block.  NEXT_BRANCH points to the branch path when following jumps or
        !          7978:    a null path when not following jumps.
        !          7979: 
        !          7980:    AROUND_LOOP is non-zero if we are to try to cse around to the start of a
        !          7981:    loop.  This is true when we are being called for the last time on a
        !          7982:    block and this CSE pass is before loop.c.  */
        !          7983: 
        !          7984: static rtx
        !          7985: cse_basic_block (from, to, next_branch, around_loop)
        !          7986:      register rtx from, to;
        !          7987:      struct branch_path *next_branch;
        !          7988:      int around_loop;
        !          7989: {
        !          7990:   register rtx insn;
        !          7991:   int to_usage = 0;
        !          7992:   int in_libcall_block = 0;
        !          7993: 
        !          7994:   /* Each of these arrays is undefined before max_reg, so only allocate
        !          7995:      the space actually needed and adjust the start below.  */
        !          7996: 
        !          7997:   qty_first_reg = (int *) alloca ((max_qty - max_reg) * sizeof (int));
        !          7998:   qty_last_reg = (int *) alloca ((max_qty - max_reg) * sizeof (int));
        !          7999:   qty_mode= (enum machine_mode *) alloca ((max_qty - max_reg) * sizeof (enum machine_mode));
        !          8000:   qty_const = (rtx *) alloca ((max_qty - max_reg) * sizeof (rtx));
        !          8001:   qty_const_insn = (rtx *) alloca ((max_qty - max_reg) * sizeof (rtx));
        !          8002:   qty_comparison_code
        !          8003:     = (enum rtx_code *) alloca ((max_qty - max_reg) * sizeof (enum rtx_code));
        !          8004:   qty_comparison_qty = (int *) alloca ((max_qty - max_reg) * sizeof (int));
        !          8005:   qty_comparison_const = (rtx *) alloca ((max_qty - max_reg) * sizeof (rtx));
        !          8006: 
        !          8007:   qty_first_reg -= max_reg;
        !          8008:   qty_last_reg -= max_reg;
        !          8009:   qty_mode -= max_reg;
        !          8010:   qty_const -= max_reg;
        !          8011:   qty_const_insn -= max_reg;
        !          8012:   qty_comparison_code -= max_reg;
        !          8013:   qty_comparison_qty -= max_reg;
        !          8014:   qty_comparison_const -= max_reg;
        !          8015: 
        !          8016:   new_basic_block ();
        !          8017: 
        !          8018:   /* TO might be a label.  If so, protect it from being deleted.  */
        !          8019:   if (to != 0 && GET_CODE (to) == CODE_LABEL)
        !          8020:     ++LABEL_NUSES (to);
        !          8021: 
        !          8022:   for (insn = from; insn != to; insn = NEXT_INSN (insn))
        !          8023:     {
        !          8024:       register enum rtx_code code;
        !          8025: 
        !          8026:       /* See if this is a branch that is part of the path.  If so, and it is
        !          8027:         to be taken, do so.  */
        !          8028:       if (next_branch->branch == insn)
        !          8029:        {
        !          8030:          enum taken status = next_branch++->status;
        !          8031:          if (status != NOT_TAKEN)
        !          8032:            {
        !          8033:              if (status == TAKEN)
        !          8034:                record_jump_equiv (insn, 1);
        !          8035:              else
        !          8036:                invalidate_skipped_block (NEXT_INSN (insn));
        !          8037: 
        !          8038:              /* Set the last insn as the jump insn; it doesn't affect cc0.
        !          8039:                 Then follow this branch.  */
        !          8040: #ifdef HAVE_cc0
        !          8041:              prev_insn_cc0 = 0;
        !          8042: #endif
        !          8043:              prev_insn = insn;
        !          8044:              insn = JUMP_LABEL (insn);
        !          8045:              continue;
        !          8046:            }
        !          8047:        }
        !          8048:         
        !          8049:       code = GET_CODE (insn);
        !          8050:       if (GET_MODE (insn) == QImode)
        !          8051:        PUT_MODE (insn, VOIDmode);
        !          8052: 
        !          8053:       if (GET_RTX_CLASS (code) == 'i')
        !          8054:        {
        !          8055:          /* Process notes first so we have all notes in canonical forms when
        !          8056:             looking for duplicate operations.  */
        !          8057: 
        !          8058:          if (REG_NOTES (insn))
        !          8059:            REG_NOTES (insn) = cse_process_notes (REG_NOTES (insn), NULL_RTX);
        !          8060: 
        !          8061:          /* Track when we are inside in LIBCALL block.  Inside such a block,
        !          8062:             we do not want to record destinations.  The last insn of a
        !          8063:             LIBCALL block is not considered to be part of the block, since
        !          8064:             its destination is the result of the block and hence should be
        !          8065:             recorded.  */
        !          8066: 
        !          8067:          if (find_reg_note (insn, REG_LIBCALL, NULL_RTX))
        !          8068:            in_libcall_block = 1;
        !          8069:          else if (find_reg_note (insn, REG_RETVAL, NULL_RTX))
        !          8070:            in_libcall_block = 0;
        !          8071: 
        !          8072:          cse_insn (insn, in_libcall_block);
        !          8073:        }
        !          8074: 
        !          8075:       /* If INSN is now an unconditional jump, skip to the end of our
        !          8076:         basic block by pretending that we just did the last insn in the
        !          8077:         basic block.  If we are jumping to the end of our block, show
        !          8078:         that we can have one usage of TO.  */
        !          8079: 
        !          8080:       if (simplejump_p (insn))
        !          8081:        {
        !          8082:          if (to == 0)
        !          8083:            return 0;
        !          8084: 
        !          8085:          if (JUMP_LABEL (insn) == to)
        !          8086:            to_usage = 1;
        !          8087: 
        !          8088:          /* Maybe TO was deleted because the jump is unconditional.
        !          8089:             If so, there is nothing left in this basic block.  */
        !          8090:          /* ??? Perhaps it would be smarter to set TO
        !          8091:             to whatever follows this insn, 
        !          8092:             and pretend the basic block had always ended here.  */
        !          8093:          if (INSN_DELETED_P (to))
        !          8094:            break;
        !          8095: 
        !          8096:          insn = PREV_INSN (to);
        !          8097:        }
        !          8098: 
        !          8099:       /* See if it is ok to keep on going past the label
        !          8100:         which used to end our basic block.  Remember that we incremented
        !          8101:         the count of that label, so we decrement it here.  If we made
        !          8102:         a jump unconditional, TO_USAGE will be one; in that case, we don't
        !          8103:         want to count the use in that jump.  */
        !          8104: 
        !          8105:       if (to != 0 && NEXT_INSN (insn) == to
        !          8106:          && GET_CODE (to) == CODE_LABEL && --LABEL_NUSES (to) == to_usage)
        !          8107:        {
        !          8108:          struct cse_basic_block_data val;
        !          8109: 
        !          8110:          insn = NEXT_INSN (to);
        !          8111: 
        !          8112:          if (LABEL_NUSES (to) == 0)
        !          8113:            delete_insn (to);
        !          8114: 
        !          8115:          /* Find the end of the following block.  Note that we won't be
        !          8116:             following branches in this case.  If TO was the last insn
        !          8117:             in the function, we are done.  Similarly, if we deleted the
        !          8118:             insn after TO, it must have been because it was preceded by
        !          8119:             a BARRIER.  In that case, we are done with this block because it
        !          8120:             has no continuation.  */
        !          8121: 
        !          8122:          if (insn == 0 || INSN_DELETED_P (insn))
        !          8123:            return 0;
        !          8124: 
        !          8125:          to_usage = 0;
        !          8126:          val.path_size = 0;
        !          8127:          cse_end_of_basic_block (insn, &val, 0, 0, 0);
        !          8128: 
        !          8129:          /* If the tables we allocated have enough space left
        !          8130:             to handle all the SETs in the next basic block,
        !          8131:             continue through it.  Otherwise, return,
        !          8132:             and that block will be scanned individually.  */
        !          8133:          if (val.nsets * 2 + next_qty > max_qty)
        !          8134:            break;
        !          8135: 
        !          8136:          cse_basic_block_start = val.low_cuid;
        !          8137:          cse_basic_block_end = val.high_cuid;
        !          8138:          to = val.last;
        !          8139: 
        !          8140:          /* Prevent TO from being deleted if it is a label.  */
        !          8141:          if (to != 0 && GET_CODE (to) == CODE_LABEL)
        !          8142:            ++LABEL_NUSES (to);
        !          8143: 
        !          8144:          /* Back up so we process the first insn in the extension.  */
        !          8145:          insn = PREV_INSN (insn);
        !          8146:        }
        !          8147:     }
        !          8148: 
        !          8149:   if (next_qty > max_qty)
        !          8150:     abort ();
        !          8151: 
        !          8152:   /* If we are running before loop.c, we stopped on a NOTE_INSN_LOOP_END, and
        !          8153:      the previous insn is the only insn that branches to the head of a loop,
        !          8154:      we can cse into the loop.  Don't do this if we changed the jump
        !          8155:      structure of a loop unless we aren't going to be following jumps.  */
        !          8156: 
        !          8157:   if ((cse_jumps_altered == 0
        !          8158:        || (flag_cse_follow_jumps == 0 && flag_cse_skip_blocks == 0))
        !          8159:       && around_loop && to != 0
        !          8160:       && GET_CODE (to) == NOTE && NOTE_LINE_NUMBER (to) == NOTE_INSN_LOOP_END
        !          8161:       && GET_CODE (PREV_INSN (to)) == JUMP_INSN
        !          8162:       && JUMP_LABEL (PREV_INSN (to)) != 0
        !          8163:       && LABEL_NUSES (JUMP_LABEL (PREV_INSN (to))) == 1)
        !          8164:     cse_around_loop (JUMP_LABEL (PREV_INSN (to)));
        !          8165: 
        !          8166:   return to ? NEXT_INSN (to) : 0;
        !          8167: }
        !          8168: 
        !          8169: /* Count the number of times registers are used (not set) in X.
        !          8170:    COUNTS is an array in which we accumulate the count, INCR is how much
        !          8171:    we count each register usage.  */
        !          8172: 
        !          8173: static void
        !          8174: count_reg_usage (x, counts, incr)
        !          8175:      rtx x;
        !          8176:      int *counts;
        !          8177:      int incr;
        !          8178: {
        !          8179:   enum rtx_code code = GET_CODE (x);
        !          8180:   char *fmt;
        !          8181:   int i, j;
        !          8182: 
        !          8183:   switch (code)
        !          8184:     {
        !          8185:     case REG:
        !          8186:       counts[REGNO (x)] += incr;
        !          8187:       return;
        !          8188: 
        !          8189:     case PC:
        !          8190:     case CC0:
        !          8191:     case CONST:
        !          8192:     case CONST_INT:
        !          8193:     case CONST_DOUBLE:
        !          8194:     case SYMBOL_REF:
        !          8195:     case LABEL_REF:
        !          8196:     case CLOBBER:
        !          8197:       return;
        !          8198: 
        !          8199:     case SET:
        !          8200:       /* Unless we are setting a REG, count everything in SET_DEST.  */
        !          8201:       if (GET_CODE (SET_DEST (x)) != REG)
        !          8202:        count_reg_usage (SET_DEST (x), counts, incr);
        !          8203:       count_reg_usage (SET_SRC (x), counts, incr);
        !          8204:       return;
        !          8205: 
        !          8206:     case INSN:
        !          8207:     case JUMP_INSN:
        !          8208:     case CALL_INSN:
        !          8209:       count_reg_usage (PATTERN (x), counts, incr);
        !          8210: 
        !          8211:       /* Things used in a REG_EQUAL note aren't dead since loop may try to
        !          8212:         use them.  */
        !          8213: 
        !          8214:       if (REG_NOTES (x))
        !          8215:        count_reg_usage (REG_NOTES (x), counts, incr);
        !          8216:       return;
        !          8217: 
        !          8218:     case EXPR_LIST:
        !          8219:     case INSN_LIST:
        !          8220:       if (REG_NOTE_KIND (x) == REG_EQUAL)
        !          8221:        count_reg_usage (XEXP (x, 0), counts, incr);
        !          8222:       if (XEXP (x, 1))
        !          8223:        count_reg_usage (XEXP (x, 1), counts, incr);
        !          8224:       return;
        !          8225:     }
        !          8226: 
        !          8227:   fmt = GET_RTX_FORMAT (code);
        !          8228:   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
        !          8229:     {
        !          8230:       if (fmt[i] == 'e')
        !          8231:        count_reg_usage (XEXP (x, i), counts, incr);
        !          8232:       else if (fmt[i] == 'E')
        !          8233:        for (j = XVECLEN (x, i) - 1; j >= 0; j--)
        !          8234:          count_reg_usage (XVECEXP (x, i, j), counts, incr);
        !          8235:     }
        !          8236: }
        !          8237: 
        !          8238: /* Scan all the insns and delete any that are dead; i.e., they store a register
        !          8239:    that is never used or they copy a register to itself.
        !          8240: 
        !          8241:    This is used to remove insns made obviously dead by cse.  It improves the
        !          8242:    heuristics in loop since it won't try to move dead invariants out of loops
        !          8243:    or make givs for dead quantities.  The remaining passes of the compilation
        !          8244:    are also sped up.  */
        !          8245: 
        !          8246: void
        !          8247: delete_dead_from_cse (insns, nreg)
        !          8248:      rtx insns;
        !          8249:      int nreg;
        !          8250: {
        !          8251:   int *counts = (int *) alloca (nreg * sizeof (int));
        !          8252:   rtx insn, prev;
        !          8253:   rtx tem;
        !          8254:   int i;
        !          8255:   int in_libcall = 0;
        !          8256: 
        !          8257:   /* First count the number of times each register is used.  */
        !          8258:   bzero (counts, sizeof (int) * nreg);
        !          8259:   for (insn = next_real_insn (insns); insn; insn = next_real_insn (insn))
        !          8260:     count_reg_usage (insn, counts, 1);
        !          8261: 
        !          8262:   /* Go from the last insn to the first and delete insns that only set unused
        !          8263:      registers or copy a register to itself.  As we delete an insn, remove
        !          8264:      usage counts for registers it uses.  */
        !          8265:   for (insn = prev_real_insn (get_last_insn ()); insn; insn = prev)
        !          8266:     {
        !          8267:       int live_insn = 0;
        !          8268: 
        !          8269:       prev = prev_real_insn (insn);
        !          8270: 
        !          8271:       /* Don't delete any insns that are part of a libcall block.
        !          8272:         Flow or loop might get confused if we did that.  Remember
        !          8273:         that we are scanning backwards.  */
        !          8274:       if (find_reg_note (insn, REG_RETVAL, NULL_RTX))
        !          8275:        in_libcall = 1;
        !          8276: 
        !          8277:       if (in_libcall)
        !          8278:        live_insn = 1;
        !          8279:       else if (GET_CODE (PATTERN (insn)) == SET)
        !          8280:        {
        !          8281:          if (GET_CODE (SET_DEST (PATTERN (insn))) == REG
        !          8282:              && SET_DEST (PATTERN (insn)) == SET_SRC (PATTERN (insn)))
        !          8283:            ;
        !          8284: 
        !          8285: #ifdef HAVE_cc0
        !          8286:          else if (GET_CODE (SET_DEST (PATTERN (insn))) == CC0
        !          8287:                   && ! side_effects_p (SET_SRC (PATTERN (insn)))
        !          8288:                   && ((tem = next_nonnote_insn (insn)) == 0
        !          8289:                       || GET_RTX_CLASS (GET_CODE (tem)) != 'i'
        !          8290:                       || ! reg_referenced_p (cc0_rtx, PATTERN (tem))))
        !          8291:            ;
        !          8292: #endif
        !          8293:          else if (GET_CODE (SET_DEST (PATTERN (insn))) != REG
        !          8294:                   || REGNO (SET_DEST (PATTERN (insn))) < FIRST_PSEUDO_REGISTER
        !          8295:                   || counts[REGNO (SET_DEST (PATTERN (insn)))] != 0
        !          8296:                   || side_effects_p (SET_SRC (PATTERN (insn))))
        !          8297:            live_insn = 1;
        !          8298:        }
        !          8299:       else if (GET_CODE (PATTERN (insn)) == PARALLEL)
        !          8300:        for (i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--)
        !          8301:          {
        !          8302:            rtx elt = XVECEXP (PATTERN (insn), 0, i);
        !          8303: 
        !          8304:            if (GET_CODE (elt) == SET)
        !          8305:              {
        !          8306:                if (GET_CODE (SET_DEST (elt)) == REG
        !          8307:                    && SET_DEST (elt) == SET_SRC (elt))
        !          8308:                  ;
        !          8309: 
        !          8310: #ifdef HAVE_cc0
        !          8311:                else if (GET_CODE (SET_DEST (elt)) == CC0
        !          8312:                         && ! side_effects_p (SET_SRC (elt))
        !          8313:                         && ((tem = next_nonnote_insn (insn)) == 0
        !          8314:                             || GET_RTX_CLASS (GET_CODE (tem)) != 'i'
        !          8315:                             || ! reg_referenced_p (cc0_rtx, PATTERN (tem))))
        !          8316:                  ;
        !          8317: #endif
        !          8318:                else if (GET_CODE (SET_DEST (elt)) != REG
        !          8319:                         || REGNO (SET_DEST (elt)) < FIRST_PSEUDO_REGISTER
        !          8320:                         || counts[REGNO (SET_DEST (elt))] != 0
        !          8321:                         || side_effects_p (SET_SRC (elt)))
        !          8322:                  live_insn = 1;
        !          8323:              }
        !          8324:            else if (GET_CODE (elt) != CLOBBER && GET_CODE (elt) != USE)
        !          8325:              live_insn = 1;
        !          8326:          }
        !          8327:       else
        !          8328:        live_insn = 1;
        !          8329: 
        !          8330:       /* If this is a dead insn, delete it and show registers in it aren't
        !          8331:         being used.  */
        !          8332: 
        !          8333:       if (! live_insn)
        !          8334:        {
        !          8335:          count_reg_usage (insn, counts, -1);
        !          8336:          delete_insn (insn);
        !          8337:        }
        !          8338: 
        !          8339:       if (find_reg_note (insn, REG_LIBCALL, NULL_RTX))
        !          8340:        in_libcall = 0;
        !          8341:     }
        !          8342: }

unix.superglobalmegacorp.com

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