Annotation of gcc/integrate.c, revision 1.1.1.3

1.1       root        1: /* Procedure integration for GNU CC.
                      2:    Copyright (C) 1988, 1991 Free Software Foundation, Inc.
                      3:    Contributed by Michael Tiemann ([email protected])
                      4: 
                      5: This file is part of GNU CC.
                      6: 
                      7: GNU CC is free software; you can redistribute it and/or modify
                      8: it under the terms of the GNU General Public License as published by
                      9: the Free Software Foundation; either version 2, or (at your option)
                     10: any later version.
                     11: 
                     12: GNU CC is distributed in the hope that it will be useful,
                     13: but WITHOUT ANY WARRANTY; without even the implied warranty of
                     14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     15: GNU General Public License for more details.
                     16: 
                     17: You should have received a copy of the GNU General Public License
                     18: along with GNU CC; see the file COPYING.  If not, write to
                     19: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
                     20: 
                     21: 
                     22: #include <stdio.h>
                     23: 
                     24: #include "config.h"
                     25: #include "rtl.h"
                     26: #include "tree.h"
                     27: #include "flags.h"
                     28: #include "insn-config.h"
                     29: #include "insn-flags.h"
                     30: #include "expr.h"
                     31: #include "output.h"
                     32: #include "integrate.h"
                     33: #include "real.h"
                     34: #include "function.h"
                     35: 
                     36: #include "obstack.h"
                     37: #define        obstack_chunk_alloc     xmalloc
                     38: #define        obstack_chunk_free      free
                     39: extern int xmalloc ();
                     40: extern void free ();
                     41: 
                     42: extern struct obstack *function_maybepermanent_obstack;
                     43: 
                     44: extern tree pushdecl ();
                     45: extern tree poplevel ();
                     46: 
                     47: /* Similar, but round to the next highest integer that meets the
                     48:    alignment.  */
                     49: #define CEIL_ROUND(VALUE,ALIGN)        (((VALUE) + (ALIGN) - 1) & ~((ALIGN)- 1))
                     50: 
                     51: /* Default max number of insns a function can have and still be inline.
                     52:    This is overridden on RISC machines.  */
                     53: #ifndef INTEGRATE_THRESHOLD
                     54: #define INTEGRATE_THRESHOLD(DECL) \
                     55:   (8 * (8 + list_length (DECL_ARGUMENTS (DECL))))
                     56: #endif
                     57: 
                     58: /* Save any constant pool constants in an insn.  */
                     59: static void save_constants ();
                     60: 
                     61: /* Note when parameter registers are the destination of a SET.  */
                     62: static void note_modified_parmregs ();
                     63: 
                     64: /* Copy an rtx for save_for_inline_copying.  */
                     65: static rtx copy_for_inline ();
                     66: 
                     67: /* Make copies of MEMs in DECL_RTLs.  */
                     68: static void copy_decl_rtls ();
                     69: 
                     70: static tree copy_decl_tree ();
                     71: 
                     72: /* Return the constant equivalent of a given rtx, or 0 if none.  */
                     73: static rtx const_equiv ();
                     74: 
                     75: static void integrate_parm_decls ();
                     76: static void integrate_decl_tree ();
                     77: 
                     78: static void subst_constants ();
                     79: static rtx fold_out_const_cc0 ();
                     80: 
                     81: /* Zero if the current function (whose FUNCTION_DECL is FNDECL)
                     82:    is safe and reasonable to integrate into other functions.
                     83:    Nonzero means value is a warning message with a single %s
                     84:    for the function's name.  */
                     85: 
                     86: char *
                     87: function_cannot_inline_p (fndecl)
                     88:      register tree fndecl;
                     89: {
                     90:   register rtx insn;
                     91:   tree last = tree_last (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
                     92:   int max_insns = INTEGRATE_THRESHOLD (fndecl);
                     93:   register int ninsns = 0;
                     94:   register tree parms;
                     95: 
                     96:   /* No inlines with varargs.  `grokdeclarator' gives a warning
                     97:      message about that if `inline' is specified.  This code
                     98:      it put in to catch the volunteers.  */
                     99:   if ((last && TREE_VALUE (last) != void_type_node)
                    100:       || (DECL_ARGUMENTS (fndecl) && DECL_NAME (DECL_ARGUMENTS (fndecl))
                    101:          && ! strcmp (IDENTIFIER_POINTER (DECL_NAME (DECL_ARGUMENTS (fndecl))),
                    102:                       "__builtin_va_alist")))
                    103:     return "varargs function cannot be inline";
                    104: 
                    105:   if (current_function_calls_alloca)
                    106:     return "function using alloca cannot be inline";
                    107: 
                    108:   if (current_function_contains_functions)
                    109:     return "function with nested functions cannot be inline";
                    110: 
                    111:   /* This restriction may be eliminated sometime soon.  But for now, don't
                    112:      worry about remapping the static chain.  */
                    113:   if (current_function_needs_context)
                    114:     return "nested function cannot be inline";
                    115: 
                    116:   /* If its not even close, don't even look.  */
                    117:   if (!TREE_INLINE (fndecl) && get_max_uid () > 3 * max_insns)
                    118:     return "function too large to be inline";
                    119: 
                    120: #if 0
                    121:   /* Large stacks are OK now that inlined functions can share them.  */
                    122:   /* Don't inline functions with large stack usage,
                    123:      since they can make other recursive functions burn up stack.  */
                    124:   if (!TREE_INLINE (fndecl) && get_frame_size () > 100)
                    125:     return "function stack frame for inlining";
                    126: #endif
                    127: 
                    128: #if 0
                    129:   /* Don't inline functions which do not specify a function prototype and
                    130:      have BLKmode argument or take the address of a parameter.  */
                    131:   for (parms = DECL_ARGUMENTS (fndecl); parms; parms = TREE_CHAIN (parms))
                    132:     {
                    133:       if (TYPE_MODE (TREE_TYPE (parms)) == BLKmode)
                    134:        TREE_ADDRESSABLE (parms) = 1;
                    135:       if (last == NULL_TREE && TREE_ADDRESSABLE (parms))
                    136:        return "no prototype, and parameter address used; cannot be inline";
                    137:     }
                    138: #endif
                    139: 
                    140:   /* We can't inline functions that return structures
                    141:      the old-fashioned PCC way, copying into a static block.  */
                    142:   if (current_function_returns_pcc_struct)
                    143:     return "inline functions not supported for this return value type";
                    144: 
                    145:   /* We can't inline functions that return structures of varying size.  */
                    146:   if (int_size_in_bytes (TREE_TYPE (TREE_TYPE (fndecl))) < 0)
                    147:     return "function with varying-size return value cannot be inline";
                    148: 
                    149:   /* Cannot inline a function with a varying size argument.  */
                    150:   for (parms = DECL_ARGUMENTS (fndecl); parms; parms = TREE_CHAIN (parms))
                    151:     if (int_size_in_bytes (TREE_TYPE (parms)) < 0)
                    152:       return "function with varying-size parameter cannot be inline";
                    153: 
                    154:   if (!TREE_INLINE (fndecl) && get_max_uid () > max_insns)
                    155:     {
                    156:       for (ninsns = 0, insn = get_first_nonparm_insn (); insn && ninsns < max_insns;
                    157:           insn = NEXT_INSN (insn))
                    158:        {
                    159:          if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
                    160:            ninsns++;
                    161:        }
                    162: 
                    163:       if (ninsns >= max_insns)
                    164:        return "function too large to be inline";
                    165:     }
                    166: 
1.1.1.2   root      167:   /* We cannot inline this function if forced_labels is non-zero.  This
                    168:      implies that a label in this function was used as an initializer.
                    169:      Because labels can not be duplicated, all labels in the function
                    170:      will be renamed when it is inlined.  However, there is no way to find
                    171:      and fix all variables initialized with addresses of labels in this
                    172:      function, hence inlining is impossible.  */
                    173: 
                    174:   if (forced_labels)
                    175:     return "function with label addresses used in initializers cannot inline";
                    176: 
1.1       root      177:   return 0;
                    178: }
                    179: 
                    180: /* Variables used within save_for_inline.  */
                    181: 
                    182: /* Mapping from old pseudo-register to new pseudo-registers.
                    183:    The first element of this map is reg_map[FIRST_PSEUDO_REGISTER].
                    184:    It is allocated in `save_for_inline' and `expand_inline_function',
                    185:    and deallocated on exit from each of those routines.  */
                    186: static rtx *reg_map;
                    187: 
                    188: /* Mapping from old code-labels to new code-labels.
                    189:    The first element of this map is label_map[min_labelno].
                    190:    It is allocated in `save_for_inline' and `expand_inline_function',
                    191:    and deallocated on exit from each of those routines.  */
                    192: static rtx *label_map;
                    193: 
                    194: /* Mapping from old insn uid's to copied insns.
                    195:    It is allocated in `save_for_inline' and `expand_inline_function',
                    196:    and deallocated on exit from each of those routines.  */
                    197: static rtx *insn_map;
                    198: 
                    199: /* Map pseudo reg number into the PARM_DECL for the parm living in the reg.
                    200:    Zero for a reg that isn't a parm's home.
                    201:    Only reg numbers less than max_parm_reg are mapped here.  */
                    202: static tree *parmdecl_map;
                    203: 
                    204: /* Keep track of first pseudo-register beyond those that are parms.  */
                    205: static int max_parm_reg;
                    206: 
                    207: /* When an insn is being copied by copy_for_inline,
                    208:    this is nonzero if we have copied an ASM_OPERANDS.
                    209:    In that case, it is the original input-operand vector.  */
                    210: static rtvec orig_asm_operands_vector;
                    211: 
                    212: /* When an insn is being copied by copy_for_inline,
                    213:    this is nonzero if we have copied an ASM_OPERANDS.
                    214:    In that case, it is the copied input-operand vector.  */
                    215: static rtvec copy_asm_operands_vector;
                    216: 
                    217: /* Likewise, this is the copied constraints vector.  */
                    218: static rtvec copy_asm_constraints_vector;
                    219: 
                    220: /* In save_for_inline, nonzero if past the parm-initialization insns.  */
                    221: static int in_nonparm_insns;
                    222: 
                    223: /* Subroutine for `save_for_inline{copying,nocopy}'.  Performs initialization
                    224:    needed to save FNDECL's insns and info for future inline expansion.  */
                    225:    
                    226: static rtx
                    227: initialize_for_inline (fndecl, min_labelno, max_labelno, max_reg, copy)
                    228:      tree fndecl;
                    229:      int min_labelno;
                    230:      int max_labelno;
                    231:      int max_reg;
                    232:      int copy;
                    233: {
                    234:   int function_flags, i;
                    235:   rtvec arg_vector;
                    236:   tree parms;
                    237: 
                    238:   /* Compute the values of any flags we must restore when inlining this.  */
                    239: 
                    240:   function_flags
                    241:     = (current_function_calls_alloca * FUNCTION_FLAGS_CALLS_ALLOCA
                    242:        + current_function_calls_setjmp * FUNCTION_FLAGS_CALLS_SETJMP
                    243:        + current_function_calls_longjmp * FUNCTION_FLAGS_CALLS_LONGJMP
                    244:        + current_function_returns_struct * FUNCTION_FLAGS_RETURNS_STRUCT
                    245:        + current_function_returns_pcc_struct * FUNCTION_FLAGS_RETURNS_PCC_STRUCT
                    246:        + current_function_needs_context * FUNCTION_FLAGS_NEEDS_CONTEXT
                    247:        + current_function_has_nonlocal_label * FUNCTION_FLAGS_HAS_NONLOCAL_LABEL
                    248:        + current_function_returns_pointer * FUNCTION_FLAGS_RETURNS_POINTER
                    249:        + current_function_uses_const_pool * FUNCTION_FLAGS_USES_CONST_POOL
                    250:        + current_function_uses_pic_offset_table * FUNCTION_FLAGS_USES_PIC_OFFSET_TABLE);
                    251: 
                    252:   /* Clear out PARMDECL_MAP.  It was allocated in the caller's frame.  */
                    253:   bzero (parmdecl_map, max_parm_reg * sizeof (tree));
                    254:   arg_vector = rtvec_alloc (list_length (DECL_ARGUMENTS (fndecl)));
                    255: 
                    256:   for (parms = DECL_ARGUMENTS (fndecl), i = 0;
                    257:        parms;
                    258:        parms = TREE_CHAIN (parms), i++)
                    259:     {
                    260:       rtx p = DECL_RTL (parms);
                    261: 
                    262:       if (GET_CODE (p) == MEM && copy)
1.1.1.2   root      263:        {
                    264:          /* Copy the rtl so that modifications of the addresses
                    265:             later in compilation won't affect this arg_vector.
                    266:             Virtual register instantiation can screw the address
                    267:             of the rtl.  */
                    268:          rtx new = copy_rtx (p);
                    269: 
                    270:          /* Don't leave the old copy anywhere in this decl.  */
1.1.1.3 ! root      271:          if (DECL_RTL (parms) == DECL_INCOMING_RTL (parms)
        !           272:              || (GET_CODE (DECL_RTL (parms)) == MEM
        !           273:                  && GET_CODE (DECL_INCOMING_RTL (parms)) == MEM
        !           274:                  && (XEXP (DECL_RTL (parms), 0)
        !           275:                      == XEXP (DECL_INCOMING_RTL (parms), 0))))
1.1.1.2   root      276:            DECL_INCOMING_RTL (parms) = new;
                    277:          DECL_RTL (parms) = new;
                    278:        }
1.1       root      279: 
                    280:       RTVEC_ELT (arg_vector, i) = p;
                    281: 
                    282:       if (GET_CODE (p) == REG)
                    283:        parmdecl_map[REGNO (p)] = parms;
1.1.1.3 ! root      284:       /* This flag is cleared later
        !           285:         if the function ever modifies the value of the parm.  */
1.1       root      286:       TREE_READONLY (parms) = 1;
                    287:     }
                    288: 
                    289:   /* Assume we start out in the insns that set up the parameters.  */
                    290:   in_nonparm_insns = 0;
                    291: 
                    292:   /* The list of DECL_SAVED_INSNS, starts off with a header which
                    293:      contains the following information:
                    294: 
                    295:      the first insn of the function (not including the insns that copy
                    296:      parameters into registers).
                    297:      the first parameter insn of the function,
                    298:      the first label used by that function,
                    299:      the last label used by that function,
                    300:      the highest register number used for parameters,
                    301:      the total number of registers used,
                    302:      the size of the incoming stack area for parameters,
                    303:      the number of bytes popped on return,
                    304:      the stack slot list,
                    305:      some flags that are used to restore compiler globals,
                    306:      the value of current_function_outgoing_args_size,
                    307:      the original argument vector,
                    308:      and the original DECL_INITIAL.  */
                    309: 
                    310:   return gen_inline_header_rtx (NULL, NULL, min_labelno, max_labelno,
                    311:                                max_parm_reg, max_reg,
                    312:                                current_function_args_size,
                    313:                                current_function_pops_args,
                    314:                                stack_slot_list, function_flags,
                    315:                                current_function_outgoing_args_size,
                    316:                                arg_vector, (rtx) DECL_INITIAL (fndecl));
                    317: }
                    318: 
                    319: /* Subroutine for `save_for_inline{copying,nocopy}'.  Finishes up the
                    320:    things that must be done to make FNDECL expandable as an inline function.
                    321:    HEAD contains the chain of insns to which FNDECL will expand.  */
                    322:    
                    323: static void
                    324: finish_inline (fndecl, head)
                    325:      tree fndecl;
                    326:      rtx head;
                    327: {
                    328:   NEXT_INSN (head) = get_first_nonparm_insn ();
                    329:   FIRST_PARM_INSN (head) = get_insns ();
                    330:   DECL_SAVED_INSNS (fndecl) = head;
                    331:   DECL_FRAME_SIZE (fndecl) = get_frame_size ();
                    332:   TREE_INLINE (fndecl) = 1;
                    333: }
                    334: 
                    335: /* Make the insns and PARM_DECLs of the current function permanent
                    336:    and record other information in DECL_SAVED_INSNS to allow inlining
                    337:    of this function in subsequent calls.
                    338: 
                    339:    This function is called when we are going to immediately compile
                    340:    the insns for FNDECL.  The insns in maybepermanent_obstack cannot be
                    341:    modified by the compilation process, so we copy all of them to
                    342:    new storage and consider the new insns to be the insn chain to be
                    343:    compiled.  */
                    344: 
                    345: void
                    346: save_for_inline_copying (fndecl)
                    347:      tree fndecl;
                    348: {
                    349:   rtx first_insn, last_insn, insn;
                    350:   rtx head, copy;
                    351:   int max_labelno, min_labelno, i, len;
                    352:   int max_reg;
                    353:   int max_uid;
                    354:   rtx first_nonparm_insn;
                    355: 
                    356:   /* Make and emit a return-label if we have not already done so. 
                    357:      Do this before recording the bounds on label numbers. */
                    358: 
                    359:   if (return_label == 0)
                    360:     {
                    361:       return_label = gen_label_rtx ();
                    362:       emit_label (return_label);
                    363:     }
                    364: 
                    365:   /* Get some bounds on the labels and registers used.  */
                    366: 
                    367:   max_labelno = max_label_num ();
                    368:   min_labelno = get_first_label_num ();
                    369:   max_reg = max_reg_num ();
                    370: 
                    371:   /* Set up PARMDECL_MAP which maps pseudo-reg number to its PARM_DECL.
                    372:      Later we set TREE_READONLY to 0 if the parm is modified inside the fn.
                    373:      Also set up ARG_VECTOR, which holds the unmodified DECL_RTX values
                    374:      for the parms, prior to elimination of virtual registers.
                    375:      These values are needed for substituting parms properly.  */
                    376: 
                    377:   max_parm_reg = max_parm_reg_num ();
                    378:   parmdecl_map = (tree *) alloca (max_parm_reg * sizeof (tree));
                    379: 
                    380:   head = initialize_for_inline (fndecl, min_labelno, max_labelno, max_reg, 1);
                    381: 
                    382:   if (current_function_uses_const_pool)
                    383:     {
                    384:       /* Replace any constant pool references with the actual constant.  We
                    385:         will put the constants back in the copy made below.  */
                    386:       for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
                    387:        if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
                    388:          {
                    389:            save_constants (&PATTERN (insn));
                    390:            if (REG_NOTES (insn))
                    391:              save_constants (&REG_NOTES (insn));
                    392:          }
                    393: 
                    394:       /* Clear out the constant pool so that we can recreate it with the
                    395:         copied constants below.  */
                    396:       init_const_rtx_hash_table ();
                    397:       clear_const_double_mem ();
                    398:     }
                    399: 
                    400:   max_uid = INSN_UID (head);
                    401: 
                    402:   /* We have now allocated all that needs to be allocated permanently
                    403:      on the rtx obstack.  Set our high-water mark, so that we
                    404:      can free the rest of this when the time comes.  */
                    405: 
                    406:   preserve_data ();
                    407: 
                    408:   /* Copy the chain insns of this function.
                    409:      Install the copied chain as the insns of this function,
                    410:      for continued compilation;
                    411:      the original chain is recorded as the DECL_SAVED_INSNS
                    412:      for inlining future calls.  */
                    413: 
                    414:   /* If there are insns that copy parms from the stack into pseudo registers,
                    415:      those insns are not copied.  `expand_inline_function' must
                    416:      emit the correct code to handle such things.  */
                    417: 
                    418:   insn = get_insns ();
                    419:   if (GET_CODE (insn) != NOTE)
                    420:     abort ();
                    421:   first_insn = rtx_alloc (NOTE);
                    422:   NOTE_SOURCE_FILE (first_insn) = NOTE_SOURCE_FILE (insn);
                    423:   NOTE_LINE_NUMBER (first_insn) = NOTE_LINE_NUMBER (insn);
                    424:   INSN_UID (first_insn) = INSN_UID (insn);
                    425:   PREV_INSN (first_insn) = NULL;
                    426:   NEXT_INSN (first_insn) = NULL;
                    427:   last_insn = first_insn;
                    428: 
                    429:   /* Each pseudo-reg in the old insn chain must have a unique rtx in the copy.
                    430:      Make these new rtx's now, and install them in regno_reg_rtx, so they
                    431:      will be the official pseudo-reg rtx's for the rest of compilation.  */
                    432: 
                    433:   reg_map = (rtx *) alloca ((max_reg + 1) * sizeof (rtx));
                    434: 
                    435:   len = sizeof (struct rtx_def) + (GET_RTX_LENGTH (REG) - 1) * sizeof (rtunion);
                    436:   for (i = max_reg - 1; i > LAST_VIRTUAL_REGISTER; i--)
                    437:     reg_map[i] = (rtx)obstack_copy (function_maybepermanent_obstack,
                    438:                                    regno_reg_rtx[i], len);
                    439: 
                    440:   bcopy (reg_map + LAST_VIRTUAL_REGISTER + 1,
                    441:         regno_reg_rtx + LAST_VIRTUAL_REGISTER + 1,
                    442:         (max_reg - (LAST_VIRTUAL_REGISTER + 1)) * sizeof (rtx));
                    443: 
                    444:   /* Likewise each label rtx must have a unique rtx as its copy.  */
                    445: 
                    446:   label_map = (rtx *)alloca ((max_labelno - min_labelno) * sizeof (rtx));
                    447:   label_map -= min_labelno;
                    448: 
                    449:   for (i = min_labelno; i < max_labelno; i++)
                    450:     label_map[i] = gen_label_rtx ();
                    451: 
                    452:   /* Record the mapping of old insns to copied insns.  */
                    453: 
                    454:   insn_map = (rtx *) alloca (max_uid * sizeof (rtx));
                    455:   bzero (insn_map, max_uid * sizeof (rtx));
                    456: 
                    457:   /* Get the insn which signals the end of parameter setup code.  */
                    458:   first_nonparm_insn = get_first_nonparm_insn ();
                    459: 
                    460:   /* Copy any entries in regno_reg_rtx or DECL_RTLs that reference MEM
                    461:      (the former occurs when a variable has its address taken)
                    462:      since these may be shared and can be changed by virtual
                    463:      register instantiation.  DECL_RTL values for our arguments
                    464:      have already been copied by initialize_for_inline.  */
                    465:   for (i = LAST_VIRTUAL_REGISTER + 1; i < max_reg; i++)
                    466:     if (GET_CODE (regno_reg_rtx[i]) == MEM)
                    467:       XEXP (regno_reg_rtx[i], 0)
                    468:        = copy_for_inline (XEXP (regno_reg_rtx[i], 0));
                    469: 
                    470:   /* Copy the tree of subblocks of the function, and the decls in them.
                    471:      We will use the copy for compiling this function, then restore the original
                    472:      subblocks and decls for use when inlining this function.
                    473: 
                    474:      Several parts of the compiler modify BLOCK trees.  In particular,
                    475:      instantiate_virtual_regs will instantiate any virtual regs
                    476:      mentioned in the DECL_RTLs of the decls, and loop
                    477:      unrolling will replicate any BLOCK trees inside an unrolled loop.
                    478: 
                    479:      The modified subblocks or DECL_RTLs would be incorrect for the original rtl
                    480:      which we will use for inlining.  The rtl might even contain pseudoregs
                    481:      whose space has been freed.  */
                    482: 
                    483:   DECL_INITIAL (fndecl) = copy_decl_tree (DECL_INITIAL (fndecl));
                    484: 
                    485:   /* Now copy each DECL_RTL which is a MEM,
                    486:      so it is safe to modify their addresses.  */
                    487:   copy_decl_rtls (DECL_INITIAL (fndecl));
                    488: 
                    489:   /* Now copy the chain of insns.  Do this twice.  The first copy the insn
                    490:      itself and its body.  The second time copy of REG_NOTES.  This is because
                    491:      a REG_NOTE may have a forward pointer to another insn.  */
                    492: 
                    493:   for (insn = NEXT_INSN (insn); insn; insn = NEXT_INSN (insn))
                    494:     {
                    495:       orig_asm_operands_vector = 0;
                    496: 
                    497:       if (insn == first_nonparm_insn)
                    498:        in_nonparm_insns = 1;
                    499: 
                    500:       switch (GET_CODE (insn))
                    501:        {
                    502:        case NOTE:
                    503:          /* No need to keep these.  */
                    504:          if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED)
                    505:            continue;
                    506: 
                    507:          copy = rtx_alloc (NOTE);
                    508:          NOTE_SOURCE_FILE (copy) = NOTE_SOURCE_FILE (insn);
                    509:          NOTE_LINE_NUMBER (copy) = NOTE_LINE_NUMBER (insn);
                    510:          break;
                    511: 
                    512:        case INSN:
                    513:        case CALL_INSN:
                    514:        case JUMP_INSN:
                    515:          copy = rtx_alloc (GET_CODE (insn));
                    516:          PATTERN (copy) = copy_for_inline (PATTERN (insn));
                    517:          INSN_CODE (copy) = -1;
                    518:          LOG_LINKS (copy) = NULL;
                    519:          RTX_INTEGRATED_P (copy) = RTX_INTEGRATED_P (insn);
                    520:          break;
                    521: 
                    522:        case CODE_LABEL:
                    523:          copy = label_map[CODE_LABEL_NUMBER (insn)];
1.1.1.2   root      524:          LABEL_NAME (copy) = LABEL_NAME (insn);
1.1       root      525:          break;
                    526: 
                    527:        case BARRIER:
                    528:          copy = rtx_alloc (BARRIER);
                    529:          break;
                    530: 
                    531:        default:
                    532:          abort ();
                    533:        }
                    534:       INSN_UID (copy) = INSN_UID (insn);
                    535:       insn_map[INSN_UID (insn)] = copy;
                    536:       NEXT_INSN (last_insn) = copy;
                    537:       PREV_INSN (copy) = last_insn;
                    538:       last_insn = copy;
                    539:     }
                    540: 
                    541:   /* Now copy the REG_NOTES.  */
                    542:   for (insn = NEXT_INSN (get_insns ()); insn; insn = NEXT_INSN (insn))
                    543:     if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
                    544:        && insn_map[INSN_UID(insn)])
                    545:       REG_NOTES (insn_map[INSN_UID (insn)])
                    546:        = copy_for_inline (REG_NOTES (insn));
                    547: 
                    548:   NEXT_INSN (last_insn) = NULL;
                    549: 
                    550:   finish_inline (fndecl, head);
                    551: 
                    552:   set_new_first_and_last_insn (first_insn, last_insn);
                    553: }
                    554: 
                    555: /* Make a copy of the entire tree of blocks BLOCK, and return it.  */
                    556: 
                    557: static tree
                    558: copy_decl_tree (block)
                    559:      tree block;
                    560: {
                    561:   tree t, vars, subblocks;
                    562: 
                    563:   vars = copy_list (BLOCK_VARS (block));
                    564:   subblocks = 0;
                    565: 
                    566:   /* Process all subblocks.  */
                    567:   for (t = BLOCK_SUBBLOCKS (block); t; t = TREE_CHAIN (t))
                    568:     {
                    569:       tree copy = copy_decl_tree (t);
                    570:       TREE_CHAIN (copy) = subblocks;
                    571:       subblocks = copy;
                    572:     }
                    573: 
                    574:   t = copy_node (block);
                    575:   BLOCK_VARS (t) = vars;
                    576:   BLOCK_SUBBLOCKS (t) = nreverse (subblocks);
                    577:   return t;
                    578: }
                    579: 
                    580: /* Copy DECL_RTLs in all decls in the given BLOCK node.  */
                    581: 
                    582: static void
                    583: copy_decl_rtls (block)
                    584:      tree block;
                    585: {
                    586:   tree t;
                    587: 
                    588:   for (t = BLOCK_VARS (block); t; t = TREE_CHAIN (t))
                    589:     if (DECL_RTL (t) && GET_CODE (DECL_RTL (t)) == MEM)
                    590:       DECL_RTL (t) = copy_for_inline (DECL_RTL (t));
                    591: 
                    592:   /* Process all subblocks.  */
                    593:   for (t = BLOCK_SUBBLOCKS (block); t; t = TREE_CHAIN (t))
                    594:     copy_decl_rtls (t);
                    595: }
                    596: 
                    597: /* Make the insns and PARM_DECLs of the current function permanent
                    598:    and record other information in DECL_SAVED_INSNS to allow inlining
                    599:    of this function in subsequent calls.
                    600: 
                    601:    This routine need not copy any insns because we are not going
                    602:    to immediately compile the insns in the insn chain.  There
                    603:    are two cases when we would compile the insns for FNDECL:
                    604:    (1) when FNDECL is expanded inline, and (2) when FNDECL needs to
                    605:    be output at the end of other compilation, because somebody took
                    606:    its address.  In the first case, the insns of FNDECL are copied
                    607:    as it is expanded inline, so FNDECL's saved insns are not
                    608:    modified.  In the second case, FNDECL is used for the last time,
                    609:    so modifying the rtl is not a problem.
                    610: 
                    611:    ??? Actually, we do not verify that FNDECL is not inline expanded
                    612:    by other functions which must also be written down at the end
                    613:    of compilation.  We could set flag_no_inline to nonzero when
                    614:    the time comes to write down such functions.  */
                    615: 
                    616: void
                    617: save_for_inline_nocopy (fndecl)
                    618:      tree fndecl;
                    619: {
                    620:   rtx insn;
                    621:   rtx head, copy;
                    622:   tree parms;
                    623:   int max_labelno, min_labelno, i, len;
                    624:   int max_reg;
                    625:   int max_uid;
                    626:   rtx first_nonparm_insn;
                    627:   int function_flags;
                    628: 
                    629:   /* Set up PARMDECL_MAP which maps pseudo-reg number to its PARM_DECL.
                    630:      Later we set TREE_READONLY to 0 if the parm is modified inside the fn.
                    631:      Also set up ARG_VECTOR, which holds the unmodified DECL_RTX values
                    632:      for the parms, prior to elimination of virtual registers.
                    633:      These values are needed for substituting parms properly.  */
                    634: 
                    635:   max_parm_reg = max_parm_reg_num ();
                    636:   parmdecl_map = (tree *) alloca (max_parm_reg * sizeof (tree));
                    637: 
                    638:   /* Make and emit a return-label if we have not already done so.  */
                    639: 
                    640:   if (return_label == 0)
                    641:     {
                    642:       return_label = gen_label_rtx ();
                    643:       emit_label (return_label);
                    644:     }
                    645: 
                    646:   head = initialize_for_inline (fndecl, get_first_label_num (),
                    647:                                max_label_num (), max_reg_num (), 0);
                    648: 
                    649:   /* If there are insns that copy parms from the stack into pseudo registers,
                    650:      those insns are not copied.  `expand_inline_function' must
                    651:      emit the correct code to handle such things.  */
                    652: 
                    653:   insn = get_insns ();
                    654:   if (GET_CODE (insn) != NOTE)
                    655:     abort ();
                    656: 
                    657:   /* Get the insn which signals the end of parameter setup code.  */
                    658:   first_nonparm_insn = get_first_nonparm_insn ();
                    659: 
                    660:   /* Now just scan the chain of insns to see what happens to our
                    661:      PARM_DECLs.  If a PARM_DECL is used but never modified, we
                    662:      can substitute its rtl directly when expanding inline (and
                    663:      perform constant folding when its incoming value is constant).
                    664:      Otherwise, we have to copy its value into a new register and track
                    665:      the new register's life.  */
                    666: 
                    667:   for (insn = NEXT_INSN (insn); insn; insn = NEXT_INSN (insn))
                    668:     {
                    669:       if (insn == first_nonparm_insn)
                    670:        in_nonparm_insns = 1;
                    671: 
                    672:       if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
                    673:        {
                    674:          if (current_function_uses_const_pool)
                    675:            {
                    676:              /* Replace any constant pool references with the actual constant.
                    677:                 We will put the constant back if we need to write the
                    678:                 function out after all.  */
                    679:              save_constants (&PATTERN (insn));
                    680:              if (REG_NOTES (insn))
                    681:                save_constants (&REG_NOTES (insn));
                    682:            }
                    683: 
                    684:          /* Record what interesting things happen to our parameters.  */
                    685:          note_stores (PATTERN (insn), note_modified_parmregs);
                    686:        }
                    687:     }
                    688: 
                    689:   /* We have now allocated all that needs to be allocated permanently
                    690:      on the rtx obstack.  Set our high-water mark, so that we
                    691:      can free the rest of this when the time comes.  */
                    692: 
                    693:   preserve_data ();
                    694: 
                    695:   finish_inline (fndecl, head);
                    696: }
                    697: 
                    698: /* Given PX, a pointer into an insn, search for references to the constant
                    699:    pool.  Replace each with a CONST that has the mode of the original
                    700:    constant, contains the constant, and has RTX_INTEGRATED_P set.
                    701:    Similarly, constant pool addresses not enclosed in a MEM are replaced
                    702:    with an ADDRESS rtx which also gives the constant, mode, and has
                    703:    RTX_INTEGRATED_P set.  */
                    704: 
                    705: static void
                    706: save_constants (px)
                    707:      rtx *px;
                    708: {
                    709:   rtx x;
                    710:   int i, j;
                    711: 
                    712:  again:
                    713:   x = *px;
                    714: 
                    715:   /* If this is a CONST_DOUBLE, don't try to fix things up in 
                    716:      CONST_DOUBLE_MEM, because this is an infinite recursion.  */
                    717:   if (GET_CODE (x) == CONST_DOUBLE)
                    718:     return;
                    719:   else if (GET_CODE (x) == MEM && GET_CODE (XEXP (x, 0)) == SYMBOL_REF
                    720:           && CONSTANT_POOL_ADDRESS_P (XEXP (x,0)))
                    721:     {
                    722:       enum machine_mode const_mode = get_pool_mode (XEXP (x, 0));
                    723:       rtx new = gen_rtx (CONST, const_mode, get_pool_constant (XEXP (x, 0)));
                    724:       RTX_INTEGRATED_P (new) = 1;
                    725: 
                    726:       /* If the MEM was in a different mode than the constant (perhaps we
                    727:         were only looking at the low-order part), surround it with a 
                    728:         SUBREG so we can save both modes.  */
                    729: 
                    730:       if (GET_MODE (x) != const_mode)
                    731:        {
                    732:          new = gen_rtx (SUBREG, GET_MODE (x), new, 0);
                    733:          RTX_INTEGRATED_P (new) = 1;
                    734:        }
                    735: 
                    736:       *px = new;
                    737:       save_constants (&XEXP (*px, 0));
                    738:     }
                    739:   else if (GET_CODE (x) == SYMBOL_REF
                    740:           && CONSTANT_POOL_ADDRESS_P (x))
                    741:     {
                    742:       *px = gen_rtx (ADDRESS, get_pool_mode (x), get_pool_constant (x));
                    743:       save_constants (&XEXP (*px, 0));
                    744:       RTX_INTEGRATED_P (*px) = 1;
                    745:     }
                    746: 
                    747:   else
                    748:     {
                    749:       char *fmt = GET_RTX_FORMAT (GET_CODE (x));
                    750:       int len = GET_RTX_LENGTH (GET_CODE (x));
                    751: 
                    752:       for (i = len-1; i >= 0; i--)
                    753:        {
                    754:          switch (fmt[i])
                    755:            {
                    756:            case 'E':
                    757:              for (j = 0; j < XVECLEN (x, i); j++)
                    758:                save_constants (&XVECEXP (x, i, j));
                    759:              break;
                    760: 
                    761:            case 'e':
                    762:              if (XEXP (x, i) == 0)
                    763:                continue;
                    764:              if (i == 0)
                    765:                {
                    766:                  /* Hack tail-recursion here.  */
                    767:                  px = &XEXP (x, 0);
                    768:                  goto again;
                    769:                }
                    770:              save_constants (&XEXP (x, i));
                    771:              break;
                    772:            }
                    773:        }
                    774:     }
                    775: }
                    776: 
                    777: /* Note whether a parameter is modified or not.  */
                    778: 
                    779: static void
                    780: note_modified_parmregs (reg, x)
                    781:      rtx reg;
                    782:      rtx x;
                    783: {
                    784:   if (GET_CODE (reg) == REG && in_nonparm_insns
                    785:       && REGNO (reg) < max_parm_reg
                    786:       && REGNO (reg) >= FIRST_PSEUDO_REGISTER
                    787:       && parmdecl_map[REGNO (reg)] != 0)
                    788:     TREE_READONLY (parmdecl_map[REGNO (reg)]) = 0;
                    789: }
                    790: 
                    791: /* Copy the rtx ORIG recursively, replacing pseudo-regs and labels
                    792:    according to `reg_map' and `label_map'.  The original rtl insns
                    793:    will be saved for inlining; this is used to make a copy
                    794:    which is used to finish compiling the inline function itself.
                    795: 
                    796:    If we find a "saved" constant pool entry, one which was replaced with
                    797:    the value of the constant, convert it back to a constant pool entry.
                    798:    Since the pool wasn't touched, this should simply restore the old
                    799:    address.
                    800: 
                    801:    All other kinds of rtx are copied except those that can never be
                    802:    changed during compilation.  */
                    803: 
                    804: static rtx
                    805: copy_for_inline (orig)
                    806:      rtx orig;
                    807: {
                    808:   register rtx x = orig;
                    809:   register int i;
                    810:   register enum rtx_code code;
                    811:   register char *format_ptr;
                    812: 
                    813:   if (x == 0)
                    814:     return x;
                    815: 
                    816:   code = GET_CODE (x);
                    817: 
                    818:   /* These types may be freely shared.  */
                    819: 
                    820:   switch (code)
                    821:     {
                    822:     case QUEUED:
                    823:     case CONST_INT:
                    824:     case SYMBOL_REF:
                    825:     case PC:
                    826:     case CC0:
                    827:       return x;
                    828: 
                    829:     case CONST_DOUBLE:
                    830:       /* We have to make a new CONST_DOUBLE to ensure that we account for
                    831:         it correctly.  Using the old CONST_DOUBLE_MEM data is wrong.  */
                    832:       if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
                    833:        {
                    834:          REAL_VALUE_TYPE d;
                    835: 
                    836:          REAL_VALUE_FROM_CONST_DOUBLE (d, x);
                    837:          return immed_real_const_1 (d, GET_MODE (x));
                    838:        }
                    839:       else
                    840:        return immed_double_const (CONST_DOUBLE_LOW (x), CONST_DOUBLE_HIGH (x),
                    841:                                   VOIDmode);
                    842: 
                    843:     case CONST:
                    844:       /* Get constant pool entry for constant in the pool.  */
                    845:       if (RTX_INTEGRATED_P (x))
                    846:        return validize_mem (force_const_mem (GET_MODE (x),
                    847:                                              copy_for_inline (XEXP (x, 0))));
                    848:       break;
                    849: 
                    850:     case SUBREG:
                    851:       /* Get constant pool entry, but access in different mode.  */
                    852:       if (RTX_INTEGRATED_P (x))
                    853:        {
                    854:          rtx new
                    855:            = force_const_mem (GET_MODE (SUBREG_REG (x)),
                    856:                               copy_for_inline (XEXP (SUBREG_REG (x), 0)));
                    857: 
                    858:          PUT_MODE (new, GET_MODE (x));
                    859:          return validize_mem (new);
                    860:        }
                    861:       break;
                    862: 
                    863:     case ADDRESS:
                    864:       /* If not special for constant pool error.  Else get constant pool
                    865:         address.  */
                    866:       if (! RTX_INTEGRATED_P (x))
                    867:        abort ();
                    868: 
                    869:       return XEXP (force_const_mem (GET_MODE (x),
                    870:                                    copy_for_inline (XEXP (x, 0))), 0);
                    871: 
                    872:     case ASM_OPERANDS:
                    873:       /* If a single asm insn contains multiple output operands
                    874:         then it contains multiple ASM_OPERANDS rtx's that share operand 3.
                    875:         We must make sure that the copied insn continues to share it.  */
                    876:       if (orig_asm_operands_vector == XVEC (orig, 3))
                    877:        {
                    878:          x = rtx_alloc (ASM_OPERANDS);
                    879:          XSTR (x, 0) = XSTR (orig, 0);
                    880:          XSTR (x, 1) = XSTR (orig, 1);
                    881:          XINT (x, 2) = XINT (orig, 2);
                    882:          XVEC (x, 3) = copy_asm_operands_vector;
                    883:          XVEC (x, 4) = copy_asm_constraints_vector;
                    884:          XSTR (x, 5) = XSTR (orig, 5);
                    885:          XINT (x, 6) = XINT (orig, 6);
                    886:          return x;
                    887:        }
                    888:       break;
                    889: 
                    890:     case MEM:
                    891:       /* A MEM is usually allowed to be shared if its address is constant
                    892:         or is a constant plus one of the special registers.
                    893: 
                    894:         We do not allow sharing of addresses that are either a special
                    895:         register or the sum of a constant and a special register because
                    896:         it is possible for unshare_all_rtl to copy the address, into memory
                    897:         that won't be saved.  Although the MEM can safely be shared, and
                    898:         won't be copied there, the address itself cannot be shared, and may
                    899:         need to be copied. 
                    900: 
                    901:         There are also two exceptions with constants: The first is if the
                    902:         constant is a LABEL_REF or the sum of the LABEL_REF
                    903:         and an integer.  This case can happen if we have an inline
                    904:         function that supplies a constant operand to the call of another
                    905:         inline function that uses it in a switch statement.  In this case,
                    906:         we will be replacing the LABEL_REF, so we have to replace this MEM
                    907:         as well.
                    908: 
                    909:         The second case is if we have a (const (plus (address ..) ...)).
                    910:         In that case we need to put back the address of the constant pool
                    911:         entry.  */
                    912: 
                    913:       if (CONSTANT_ADDRESS_P (XEXP (x, 0))
                    914:          && GET_CODE (XEXP (x, 0)) != LABEL_REF
                    915:          && ! (GET_CODE (XEXP (x, 0)) == CONST
                    916:                && (GET_CODE (XEXP (XEXP (x, 0), 0)) == PLUS
                    917:                    && ((GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 0))
                    918:                        == LABEL_REF)
                    919:                        || (GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 0))
                    920:                            == ADDRESS)))))
                    921:        return x;
                    922:       break;
                    923: 
                    924:     case LABEL_REF:
                    925:       {
                    926:        /* Must point to the new insn.  */
                    927:        return gen_rtx (LABEL_REF, GET_MODE (orig),
                    928:                        label_map[CODE_LABEL_NUMBER (XEXP (orig, 0))]);
                    929:       }
                    930: 
                    931:     case REG:
                    932:       if (REGNO (x) > LAST_VIRTUAL_REGISTER)
                    933:        return reg_map [REGNO (x)];
                    934:       else
                    935:        return x;
                    936: 
                    937:     case SET:
                    938:       /* If a parm that gets modified lives in a pseudo-reg,
                    939:         clear its TREE_READONLY to prevent certain optimizations.  */
                    940:       {
                    941:        rtx dest = SET_DEST (x);
                    942: 
                    943:        while (GET_CODE (dest) == STRICT_LOW_PART
                    944:               || GET_CODE (dest) == ZERO_EXTRACT
                    945:               || GET_CODE (dest) == SUBREG)
                    946:          dest = XEXP (dest, 0);
                    947: 
                    948:        if (GET_CODE (dest) == REG
                    949:            && REGNO (dest) < max_parm_reg
                    950:            && REGNO (dest) >= FIRST_PSEUDO_REGISTER
                    951:            && parmdecl_map[REGNO (dest)] != 0
                    952:            /* The insn to load an arg pseudo from a stack slot
                    953:               does not count as modifying it.  */
                    954:            && in_nonparm_insns)
                    955:          TREE_READONLY (parmdecl_map[REGNO (dest)]) = 0;
                    956:       }
                    957:       break;
                    958: 
                    959: #if 0 /* This is a good idea, but here is the wrong place for it.  */
                    960:       /* Arrange that CONST_INTs always appear as the second operand
                    961:         if they appear, and that `frame_pointer_rtx' or `arg_pointer_rtx'
                    962:         always appear as the first.  */
                    963:     case PLUS:
                    964:       if (GET_CODE (XEXP (x, 0)) == CONST_INT
                    965:          || (XEXP (x, 1) == frame_pointer_rtx
                    966:              || (ARG_POINTER_REGNUM != FRAME_POINTER_REGNUM
                    967:                  && XEXP (x, 1) == arg_pointer_rtx)))
                    968:        {
                    969:          rtx t = XEXP (x, 0);
                    970:          XEXP (x, 0) = XEXP (x, 1);
                    971:          XEXP (x, 1) = t;
                    972:        }
                    973:       break;
                    974: #endif
                    975:     }
                    976: 
                    977:   /* Replace this rtx with a copy of itself.  */
                    978: 
                    979:   x = rtx_alloc (code);
                    980:   bcopy (orig, x, (sizeof (*x) - sizeof (x->fld)
                    981:                   + sizeof (x->fld[0]) * GET_RTX_LENGTH (code)));
                    982: 
                    983:   /* Now scan the subexpressions recursively.
                    984:      We can store any replaced subexpressions directly into X
                    985:      since we know X is not shared!  Any vectors in X
                    986:      must be copied if X was copied.  */
                    987: 
                    988:   format_ptr = GET_RTX_FORMAT (code);
                    989: 
                    990:   for (i = 0; i < GET_RTX_LENGTH (code); i++)
                    991:     {
                    992:       switch (*format_ptr++)
                    993:        {
                    994:        case 'e':
                    995:          XEXP (x, i) = copy_for_inline (XEXP (x, i));
                    996:          break;
                    997: 
                    998:        case 'u':
                    999:          /* Change any references to old-insns to point to the
                   1000:             corresponding copied insns.  */
                   1001:          XEXP (x, i) = insn_map[INSN_UID (XEXP (x, i))];
                   1002:          break;
                   1003: 
                   1004:        case 'E':
                   1005:          if (XVEC (x, i) != NULL && XVECLEN (x, i) != 0)
                   1006:            {
                   1007:              register int j;
                   1008: 
                   1009:              XVEC (x, i) = gen_rtvec_v (XVECLEN (x, i), &XVECEXP (x, i, 0));
                   1010:              for (j = 0; j < XVECLEN (x, i); j++)
                   1011:                XVECEXP (x, i, j)
                   1012:                  = copy_for_inline (XVECEXP (x, i, j));
                   1013:            }
                   1014:          break;
                   1015:        }
                   1016:     }
                   1017: 
                   1018:   if (code == ASM_OPERANDS && orig_asm_operands_vector == 0)
                   1019:     {
                   1020:       orig_asm_operands_vector = XVEC (orig, 3);
                   1021:       copy_asm_operands_vector = XVEC (x, 3);
                   1022:       copy_asm_constraints_vector = XVEC (x, 4);
                   1023:     }
                   1024: 
                   1025:   return x;
                   1026: }
                   1027: 
                   1028: /* Unfortunately, we need a global copy of const_equiv map for communication
                   1029:    with a function called from note_stores.  Be *very* careful that this
                   1030:    is used properly in the presence of recursion.  */
                   1031: 
                   1032: rtx *global_const_equiv_map;
                   1033: 
                   1034: #define FIXED_BASE_PLUS_P(X) \
                   1035:   (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 1)) == CONST_INT \
                   1036:    && GET_CODE (XEXP (X, 0)) == REG                            \
                   1037:    && REGNO (XEXP (X, 0)) >= FIRST_VIRTUAL_REGISTER            \
                   1038:    && REGNO (XEXP (X, 0)) < LAST_VIRTUAL_REGISTER)
                   1039: 
                   1040: /* Integrate the procedure defined by FNDECL.  Note that this function
                   1041:    may wind up calling itself.  Since the static variables are not
                   1042:    reentrant, we do not assign them until after the possibility
1.1.1.3 ! root     1043:    of recursion is eliminated.
1.1       root     1044: 
                   1045:    If IGNORE is nonzero, do not produce a value.
                   1046:    Otherwise store the value in TARGET if it is nonzero and that is convenient.
                   1047: 
                   1048:    Value is:
                   1049:    (rtx)-1 if we could not substitute the function
                   1050:    0 if we substituted it and it does not produce a value
                   1051:    else an rtx for where the value is stored.  */
                   1052: 
                   1053: rtx
                   1054: expand_inline_function (fndecl, parms, target, ignore, type, structure_value_addr)
                   1055:      tree fndecl, parms;
                   1056:      rtx target;
                   1057:      int ignore;
                   1058:      tree type;
                   1059:      rtx structure_value_addr;
                   1060: {
                   1061:   tree formal, actual;
                   1062:   rtx header = DECL_SAVED_INSNS (fndecl);
                   1063:   rtx insns = FIRST_FUNCTION_INSN (header);
                   1064:   rtx parm_insns = FIRST_PARM_INSN (header);
                   1065:   tree *arg_trees;
                   1066:   rtx *arg_vals;
                   1067:   rtx insn;
                   1068:   int max_regno;
                   1069:   register int i;
                   1070:   int min_labelno = FIRST_LABELNO (header);
                   1071:   int max_labelno = LAST_LABELNO (header);
                   1072:   int nargs;
                   1073:   rtx local_return_label = 0;
                   1074:   rtx loc;
                   1075:   rtx temp;
                   1076:   struct inline_remap *map;
                   1077:   rtx cc0_insn = 0;
                   1078:   rtvec arg_vector = ORIGINAL_ARG_VECTOR (header);
                   1079: 
                   1080:   /* Allow for equivalences of the pseudos we make for virtual fp and ap.  */
                   1081:   max_regno = MAX_REGNUM (header) + 3;
                   1082:   if (max_regno < FIRST_PSEUDO_REGISTER)
                   1083:     abort ();
                   1084: 
                   1085:   nargs = list_length (DECL_ARGUMENTS (fndecl));
                   1086: 
                   1087:   /* We expect PARMS to have the right length; don't crash if not.  */
                   1088:   if (list_length (parms) != nargs)
                   1089:     return (rtx)-1;
                   1090:   /* Also check that the parms type match.  Since the appropriate
                   1091:      conversions or default promotions have already been applied,
                   1092:      the machine modes should match exactly.  */
                   1093:   for (formal = DECL_ARGUMENTS (fndecl),
                   1094:        actual = parms;
                   1095:        formal;
                   1096:        formal = TREE_CHAIN (formal),
                   1097:        actual = TREE_CHAIN (actual))
                   1098:     {
                   1099:       tree arg = TREE_VALUE (actual);
                   1100:       enum machine_mode mode = TYPE_MODE (DECL_ARG_TYPE (formal));
                   1101:       if (mode != TYPE_MODE (TREE_TYPE (arg)))
                   1102:        return (rtx)-1;
                   1103:       /* If they are block mode, the types should match exactly.
                   1104:          They don't match exactly if TREE_TYPE (FORMAL) == ERROR_MARK_NODE,
                   1105:         which could happen if the parameter has incomplete type.  */
                   1106:       if (mode == BLKmode && TREE_TYPE (arg) != TREE_TYPE (formal))
                   1107:        return (rtx)-1;
                   1108:     }
                   1109: 
                   1110:   /* Make a binding contour to keep inline cleanups called at
                   1111:      outer function-scope level from looking like they are shadowing
                   1112:      parameter declarations.  */
                   1113:   pushlevel (0);
                   1114: 
                   1115:   /* Make a fresh binding contour that we can easily remove.  */
                   1116:   pushlevel (0);
                   1117:   expand_start_bindings (0);
                   1118:   if (GET_CODE (parm_insns) == NOTE
                   1119:       && NOTE_LINE_NUMBER (parm_insns) > 0)
                   1120:     emit_note (NOTE_SOURCE_FILE (parm_insns), NOTE_LINE_NUMBER (parm_insns));
                   1121: 
                   1122:   /* Expand the function arguments.  Do this first so that any
                   1123:      new registers get created before we allocate the maps.  */
                   1124: 
                   1125:   arg_vals = (rtx *) alloca (nargs * sizeof (rtx));
                   1126:   arg_trees = (tree *) alloca (nargs * sizeof (tree));
                   1127: 
                   1128:   for (formal = DECL_ARGUMENTS (fndecl), actual = parms, i = 0;
                   1129:        formal;
                   1130:        formal = TREE_CHAIN (formal), actual = TREE_CHAIN (actual), i++)
                   1131:     {
                   1132:       /* Actual parameter, converted to the type of the argument within the
                   1133:         function.  */
                   1134:       tree arg = convert (TREE_TYPE (formal), TREE_VALUE (actual));
                   1135:       /* Mode of the variable used within the function.  */
                   1136:       enum machine_mode mode = TYPE_MODE (TREE_TYPE (formal));
                   1137:       /* Where parameter is located in the function.  */
                   1138:       rtx copy;
                   1139: 
                   1140:       emit_note (DECL_SOURCE_FILE (formal), DECL_SOURCE_LINE (formal));
                   1141: 
                   1142:       arg_trees[i] = arg;
                   1143:       loc = RTVEC_ELT (arg_vector, i);
                   1144: 
                   1145:       /* If this is an object passed by invisible reference, we copy the
                   1146:         object into a stack slot and save its address.  If this will go
                   1147:         into memory, we do nothing now.  Otherwise, we just expand the
                   1148:         argument.  */
                   1149:       if (GET_CODE (loc) == MEM && GET_CODE (XEXP (loc, 0)) == REG
                   1150:          && REGNO (XEXP (loc, 0)) > LAST_VIRTUAL_REGISTER)
                   1151:        {
                   1152:          enum machine_mode mode = TYPE_MODE (TREE_TYPE (arg));
                   1153:          rtx stack_slot = assign_stack_temp (mode, int_size_in_bytes (TREE_TYPE (arg)), 1);
                   1154: 
                   1155:          store_expr (arg, stack_slot, 0);
                   1156: 
                   1157:          arg_vals[i] = XEXP (stack_slot, 0);
                   1158:        }
                   1159:       else if (GET_CODE (loc) != MEM)
                   1160:        arg_vals[i] = expand_expr (arg, 0, mode, EXPAND_SUM);
                   1161:       else
                   1162:        arg_vals[i] = 0;
                   1163: 
                   1164:       if (arg_vals[i] != 0
                   1165:          && (! TREE_READONLY (formal)
                   1166:              /* If the parameter is not read-only, copy our argument through
                   1167:                 a register.  Also, we cannot use ARG_VALS[I] if it overlaps
                   1168:                 TARGET in any way.  In the inline function, they will likely
                   1169:                 be two different pseudos, and `safe_from_p' will make all
                   1170:                 sorts of smart assumptions about their not conflicting.
                   1171:                 But if ARG_VALS[I] overlaps TARGET, these assumptions are
                   1172:                 wrong, so put ARG_VALS[I] into a fresh register.  */
                   1173:              || (target != 0
                   1174:                  && (GET_CODE (arg_vals[i]) == REG
                   1175:                      || GET_CODE (arg_vals[i]) == SUBREG
                   1176:                      || GET_CODE (arg_vals[i]) == MEM)
                   1177:                  && reg_overlap_mentioned_p (arg_vals[i], target))))
                   1178:        arg_vals[i] = copy_to_mode_reg (mode, arg_vals[i]);
                   1179:     }
                   1180:        
                   1181:   /* Allocate the structures we use to remap things.  */
                   1182: 
                   1183:   map = (struct inline_remap *) alloca (sizeof (struct inline_remap));
                   1184:   map->fndecl = fndecl;
                   1185: 
                   1186:   map->reg_map = (rtx *) alloca (max_regno * sizeof (rtx));
                   1187:   bzero (map->reg_map, max_regno * sizeof (rtx));
                   1188: 
                   1189:   map->label_map = (rtx *)alloca ((max_labelno - min_labelno) * sizeof (rtx));
                   1190:   map->label_map -= min_labelno;
                   1191: 
                   1192:   map->insn_map = (rtx *) alloca (INSN_UID (header) * sizeof (rtx));
                   1193:   bzero (map->insn_map, INSN_UID (header) * sizeof (rtx));
                   1194:   map->min_insnno = 0;
                   1195:   map->max_insnno = INSN_UID (header);
                   1196: 
                   1197:   /* const_equiv_map maps pseudos in our routine to constants, so it needs to
                   1198:      be large enough for all our pseudos.  This is the number we are currently
                   1199:      using plus the number in the called routine, plus 15 for each arg,
                   1200:      five to compute the virtual frame pointer, and five for the return value.
                   1201:      This should be enough for most cases.  We do not reference entries
                   1202:      outside the range of the map.
                   1203: 
                   1204:      ??? These numbers are quite arbitrary and were obtained by
                   1205:      experimentation.  At some point, we should try to allocate the
                   1206:      table after all the parameters are set up so we an more accurately
                   1207:      estimate the number of pseudos we will need.  */
                   1208: 
                   1209:   map->const_equiv_map_size
                   1210:     = max_reg_num () + (max_regno - FIRST_PSEUDO_REGISTER) + 15 * nargs + 10;
                   1211: 
                   1212:   map->const_equiv_map
                   1213:     = (rtx *)alloca (map->const_equiv_map_size * sizeof (rtx));
                   1214:   bzero (map->const_equiv_map, map->const_equiv_map_size * sizeof (rtx));
                   1215: 
                   1216:   map->const_age_map
                   1217:     = (unsigned *)alloca (map->const_equiv_map_size * sizeof (unsigned));
                   1218:   bzero (map->const_age_map, map->const_equiv_map_size * sizeof (unsigned));
                   1219:   map->const_age = 0;
                   1220: 
                   1221:   /* Record the current insn in case we have to set up pointers to frame
                   1222:      and argument memory blocks.  */
                   1223:   map->insns_at_start = get_last_insn ();
                   1224: 
                   1225:   /* Update the outgoing argument size to allow for those in the inlined
                   1226:      function.  */
                   1227:   if (OUTGOING_ARGS_SIZE (header) > current_function_outgoing_args_size)
                   1228:     current_function_outgoing_args_size = OUTGOING_ARGS_SIZE (header);
                   1229: 
                   1230:   /* If the inline function needs to make PIC references, that means
                   1231:      that this function's PIC offset table must be used.  */
                   1232:   if (FUNCTION_FLAGS (header) & FUNCTION_FLAGS_USES_PIC_OFFSET_TABLE)
                   1233:     current_function_uses_pic_offset_table = 1;
                   1234: 
                   1235:   /* Process each argument.  For each, set up things so that the function's
                   1236:      reference to the argument will refer to the argument being passed.
                   1237:      We only replace REG with REG here.  Any simplifications are done
                   1238:      via const_equiv_map.
                   1239: 
                   1240:      We make two passes:  In the first, we deal with parameters that will
                   1241:      be placed into registers, since we need to ensure that the allocated
                   1242:      register number fits in const_equiv_map.  Then we store all non-register
                   1243:      parameters into their memory location.  */
                   1244: 
                   1245:   for (i = 0; i < nargs; i++)
                   1246:     {
                   1247:       rtx copy = arg_vals[i];
                   1248: 
                   1249:       loc = RTVEC_ELT (arg_vector, i);
                   1250: 
                   1251:       /* There are three cases, each handled separately.  */
                   1252:       if (GET_CODE (loc) == MEM && GET_CODE (XEXP (loc, 0)) == REG
                   1253:          && REGNO (XEXP (loc, 0)) > LAST_VIRTUAL_REGISTER)
                   1254:        {
                   1255:          /* This must be an object passed by invisible reference (it could
                   1256:             also be a variable-sized object, but we forbid inlining functions
                   1257:             with variable-sized arguments).  COPY is the address of the
                   1258:             actual value (this computation will cause it to be copied).  We
                   1259:             map that address for the register, noting the actual address as
                   1260:             an equivalent in case it can be substituted into the insns.  */
                   1261: 
                   1262:          if (GET_CODE (copy) != REG)
                   1263:            {
                   1264:              temp = copy_addr_to_reg (copy);
                   1265:              if (CONSTANT_P (copy) || FIXED_BASE_PLUS_P (copy))
                   1266:                {
                   1267:                  map->const_equiv_map[REGNO (temp)] = copy;
                   1268:                  map->const_age_map[REGNO (temp)] = CONST_AGE_PARM;
                   1269:                }
                   1270:              copy = temp;
                   1271:            }
                   1272:          map->reg_map[REGNO (XEXP (loc, 0))] = copy;
                   1273:        }
                   1274:       else if (GET_CODE (loc) == MEM)
                   1275:        {
                   1276:          /* This is the case of a parameter that lives in memory.
                   1277:             It will live in the block we allocate in the called routine's
                   1278:             frame that simulates the incoming argument area.  Do nothing
                   1279:             now; we will call store_expr later.  */
                   1280:          ;
                   1281:        }
                   1282:       else if (GET_CODE (loc) == REG)
                   1283:        {
                   1284:          /* This is the good case where the parameter is in a register.
                   1285:             If it is read-only and our argument is a constant, set up the
                   1286:             constant equivalence.  */
                   1287:          if (GET_CODE (copy) != REG && GET_CODE (copy) != SUBREG)
                   1288:            {
                   1289:              temp = copy_to_mode_reg (GET_MODE (loc), copy);
                   1290:              if (CONSTANT_P (copy) || FIXED_BASE_PLUS_P (copy))
                   1291:                {
                   1292:                  map->const_equiv_map[REGNO (temp)] = copy;
                   1293:                  map->const_age_map[REGNO (temp)] = CONST_AGE_PARM;
                   1294:                }
                   1295:              copy = temp;
                   1296:            }
                   1297:          map->reg_map[REGNO (loc)] = copy;
                   1298:        }
                   1299:       else
                   1300:        abort ();
                   1301: 
                   1302:       /* Free any temporaries we made setting up this parameter.  */
                   1303:       free_temp_slots ();
                   1304:     }
                   1305: 
                   1306:   /* Now do the parameters that will be placed in memory.  */
                   1307: 
                   1308:   for (formal = DECL_ARGUMENTS (fndecl), i = 0;
                   1309:        formal; formal = TREE_CHAIN (formal), i++)
                   1310:     {
                   1311:       rtx copy = arg_vals[i];
                   1312: 
                   1313:       loc = RTVEC_ELT (arg_vector, i);
                   1314: 
                   1315:       if (GET_CODE (loc) == MEM
                   1316:          /* Exclude case handled above.  */
                   1317:          && ! (GET_CODE (XEXP (loc, 0)) == REG
                   1318:                && REGNO (XEXP (loc, 0)) > LAST_VIRTUAL_REGISTER))
                   1319:        {
                   1320:          emit_note (DECL_SOURCE_FILE (formal), DECL_SOURCE_LINE (formal));
                   1321: 
                   1322:          /* Compute the address in the area we reserved and store the
                   1323:             value there.  */
                   1324:          temp = copy_rtx_and_substitute (loc, map);
                   1325:          subst_constants (&temp, 0, map);
                   1326:          apply_change_group ();
                   1327:          if (! memory_address_p (GET_MODE (temp), XEXP (temp, 0)))
                   1328:            temp = change_address (temp, VOIDmode, XEXP (temp, 0));
                   1329:          store_expr (arg_trees[i], temp, 0);
                   1330: 
                   1331:          /* Free any temporaries we made setting up this parameter.  */
                   1332:          free_temp_slots ();
                   1333:        }
                   1334:     }
                   1335: 
                   1336:   /* Deal with the places that the function puts its result.
                   1337:      We are driven by what is placed into DECL_RESULT.
                   1338: 
                   1339:      Initially, we assume that we don't have anything special handling for
                   1340:      REG_FUNCTION_RETURN_VALUE_P.  */
                   1341: 
                   1342:   map->inline_target = 0;
                   1343:   loc = DECL_RTL (DECL_RESULT (fndecl));
                   1344:   if (TYPE_MODE (type) == VOIDmode)
                   1345:     /* There is no return value to worry about.  */
                   1346:     ;
                   1347:   else if (GET_CODE (loc) == MEM)
                   1348:     {
                   1349:       if (! structure_value_addr || ! aggregate_value_p (DECL_RESULT (fndecl)))
                   1350:        abort ();
                   1351:   
                   1352:       /* Pass the function the address in which to return a structure value.
                   1353:         Note that a constructor can cause someone to call us with
                   1354:         STRUCTURE_VALUE_ADDR, but the initialization takes place
                   1355:         via the first parameter, rather than the struct return address.
                   1356: 
                   1357:         We have two cases:  If the address is a simple register indirect,
                   1358:         use the mapping mechanism to point that register to our structure
                   1359:         return address.  Otherwise, store the structure return value into
                   1360:         the place that it will be referenced from.  */
                   1361: 
                   1362:       if (GET_CODE (XEXP (loc, 0)) == REG)
                   1363:        {
                   1364:          temp = force_reg (Pmode, structure_value_addr);
                   1365:          map->reg_map[REGNO (XEXP (loc, 0))] = temp;
                   1366:          if (CONSTANT_P (structure_value_addr)
                   1367:              || (GET_CODE (structure_value_addr) == PLUS
                   1368:                  && XEXP (structure_value_addr, 0) == virtual_stack_vars_rtx
                   1369:                  && GET_CODE (XEXP (structure_value_addr, 1)) == CONST_INT))
                   1370:            {
                   1371:              map->const_equiv_map[REGNO (temp)] = structure_value_addr;
                   1372:              map->const_age_map[REGNO (temp)] = CONST_AGE_PARM;
                   1373:            }
                   1374:        }
                   1375:       else
                   1376:        {
                   1377:          temp = copy_rtx_and_substitute (loc, map);
                   1378:          subst_constants (&temp, 0, map);
                   1379:          apply_change_group ();
                   1380:          emit_move_insn (temp, structure_value_addr);
                   1381:        }
                   1382:     }
                   1383:   else if (ignore)
                   1384:     /* We will ignore the result value, so don't look at its structure.
                   1385:        Note that preparations for an aggregate return value
                   1386:        do need to be made (above) even if it will be ignored.  */
                   1387:     ;
                   1388:   else if (GET_CODE (loc) == REG)
                   1389:     {
                   1390:       /* The function returns an object in a register and we use the return
                   1391:         value.  Set up our target for remapping.  */
                   1392: 
                   1393:       /* Machine mode function was declared to return.   */
                   1394:       enum machine_mode departing_mode = TYPE_MODE (type);
                   1395:       /* (Possibly wider) machine mode it actually computes
                   1396:         (for the sake of callers that fail to declare it right).  */
                   1397:       enum machine_mode arriving_mode
                   1398:        = TYPE_MODE (TREE_TYPE (DECL_RESULT (fndecl)));
                   1399:       rtx reg_to_map;
                   1400: 
                   1401:       /* Don't use MEMs as direct targets because on some machines
                   1402:         substituting a MEM for a REG makes invalid insns.
                   1403:         Let the combiner substitute the MEM if that is valid.  */
                   1404:       if (target == 0 || GET_CODE (target) != REG
                   1405:          || GET_MODE (target) != departing_mode)
                   1406:        target = gen_reg_rtx (departing_mode);
                   1407: 
                   1408:       /* If function's value was promoted before return,
                   1409:         avoid machine mode mismatch when we substitute INLINE_TARGET.
                   1410:         But TARGET is what we will return to the caller.  */
                   1411:       if (arriving_mode != departing_mode)
                   1412:        reg_to_map = gen_rtx (SUBREG, arriving_mode, target, 0);
                   1413:       else
                   1414:        reg_to_map = target;
                   1415: 
                   1416:       /* Usually, the result value is the machine's return register.
                   1417:         Sometimes it may be a pseudo. Handle both cases.  */
                   1418:       if (REG_FUNCTION_VALUE_P (loc))
                   1419:        map->inline_target = reg_to_map;
                   1420:       else
                   1421:        map->reg_map[REGNO (loc)] = reg_to_map;
                   1422:     }
                   1423: 
                   1424:   /* Make new label equivalences for the labels in the called function.  */
                   1425:   for (i = min_labelno; i < max_labelno; i++)
                   1426:     map->label_map[i] = gen_label_rtx ();
                   1427: 
                   1428:   /* Perform postincrements before actually calling the function.  */
                   1429:   emit_queue ();
                   1430: 
                   1431:   /* Clean up stack so that variables might have smaller offsets.  */
                   1432:   do_pending_stack_adjust ();
                   1433: 
                   1434:   /* Save a copy of the location of const_equiv_map for mark_stores, called
                   1435:      via note_stores.  */
                   1436:   global_const_equiv_map = map->const_equiv_map;
                   1437: 
                   1438:   /* Now copy the insns one by one.  Do this in two passes, first the insns and
                   1439:      then their REG_NOTES, just like save_for_inline.  */
                   1440: 
                   1441:   /* This loop is very similar to the loop in copy_loop_body in unroll.c.  */
                   1442: 
                   1443:   for (insn = insns; insn; insn = NEXT_INSN (insn))
                   1444:     {
                   1445:       rtx copy, pattern;
                   1446: 
                   1447:       map->orig_asm_operands_vector = 0;
                   1448: 
                   1449:       switch (GET_CODE (insn))
                   1450:        {
                   1451:        case INSN:
                   1452:          pattern = PATTERN (insn);
                   1453:          copy = 0;
                   1454:          if (GET_CODE (pattern) == USE
                   1455:              && GET_CODE (XEXP (pattern, 0)) == REG
                   1456:              && REG_FUNCTION_VALUE_P (XEXP (pattern, 0)))
                   1457:            /* The (USE (REG n)) at return from the function should
                   1458:               be ignored since we are changing (REG n) into
                   1459:               inline_target.  */
                   1460:            break;
                   1461: 
                   1462:          /* Ignore setting a function value that we don't want to use.  */
                   1463:          if (map->inline_target == 0
                   1464:              && GET_CODE (pattern) == SET
                   1465:              && GET_CODE (SET_DEST (pattern)) == REG
                   1466:              && REG_FUNCTION_VALUE_P (SET_DEST (pattern)))
1.1.1.3 ! root     1467:            {
        !          1468:              if (volatile_refs_p (SET_SRC (pattern)))
        !          1469:                {
        !          1470:                  /* If we must not delete the source,
        !          1471:                     load it into a new temporary.  */
        !          1472:                  copy = emit_insn (copy_rtx_and_substitute (pattern, map));
        !          1473:                  SET_DEST (PATTERN (copy)) 
        !          1474:                    = gen_reg_rtx (GET_MODE (SET_DEST (PATTERN (copy))));
        !          1475:                }
        !          1476:              else
        !          1477:                break;
        !          1478:            }
        !          1479:          else
        !          1480:            copy = emit_insn (copy_rtx_and_substitute (pattern, map));
1.1       root     1481:          /* REG_NOTES will be copied later.  */
                   1482: 
                   1483: #ifdef HAVE_cc0
                   1484:          /* If this insn is setting CC0, it may need to look at
                   1485:             the insn that uses CC0 to see what type of insn it is.
                   1486:             In that case, the call to recog via validate_change will
                   1487:             fail.  So don't substitute constants here.  Instead,
                   1488:             do it when we emit the following insn.
                   1489: 
                   1490:             For example, see the pyr.md file.  That machine has signed and
                   1491:             unsigned compares.  The compare patterns must check the
                   1492:             following branch insn to see which what kind of compare to
                   1493:             emit.
                   1494: 
                   1495:             If the previous insn set CC0, substitute constants on it as
                   1496:             well.  */
                   1497:          if (sets_cc0_p (PATTERN (copy)) != 0)
                   1498:            cc0_insn = copy;
                   1499:          else
                   1500:            {
                   1501:              if (cc0_insn)
                   1502:                try_constants (cc0_insn, map);
                   1503:              cc0_insn = 0;
                   1504:              try_constants (copy, map);
                   1505:            }
                   1506: #else
                   1507:          try_constants (copy, map);
                   1508: #endif
                   1509:          break;
                   1510: 
                   1511:        case JUMP_INSN:
                   1512:          if (GET_CODE (PATTERN (insn)) == RETURN)
                   1513:            {
                   1514:              if (local_return_label == 0)
                   1515:                local_return_label = gen_label_rtx ();
                   1516:              pattern = gen_jump (local_return_label);
                   1517:            }
                   1518:          else
                   1519:            pattern = copy_rtx_and_substitute (PATTERN (insn), map);
                   1520: 
                   1521:          copy = emit_jump_insn (pattern);
                   1522: 
                   1523: #ifdef HAVE_cc0
                   1524:          if (cc0_insn)
                   1525:            try_constants (cc0_insn, map);
                   1526:          cc0_insn = 0;
                   1527: #endif
                   1528:          try_constants (copy, map);
                   1529: 
                   1530:          /* If this used to be a conditional jump insn but whose branch
                   1531:             direction is now know, we must do something special.  */
                   1532:          if (condjump_p (insn) && ! simplejump_p (insn) && map->last_pc_value)
                   1533:            {
                   1534: #ifdef HAVE_cc0
                   1535:              /* The previous insn set cc0 for us.  So delete it.  */
                   1536:              delete_insn (PREV_INSN (copy));
                   1537: #endif
                   1538: 
                   1539:              /* If this is now a no-op, delete it.  */
                   1540:              if (map->last_pc_value == pc_rtx)
                   1541:                {
                   1542:                  delete_insn (copy);
                   1543:                  copy = 0;
                   1544:                }
                   1545:              else
                   1546:                /* Otherwise, this is unconditional jump so we must put a
                   1547:                   BARRIER after it.  We could do some dead code elimination
                   1548:                   here, but jump.c will do it just as well.  */
                   1549:                emit_barrier ();
                   1550:            }
                   1551:          break;
                   1552: 
                   1553:        case CALL_INSN:
                   1554:          pattern = copy_rtx_and_substitute (PATTERN (insn), map);
                   1555:          copy = emit_call_insn (pattern);
                   1556: 
                   1557: #ifdef HAVE_cc0
                   1558:          if (cc0_insn)
                   1559:            try_constants (cc0_insn, map);
                   1560:          cc0_insn = 0;
                   1561: #endif
                   1562:          try_constants (copy, map);
                   1563: 
                   1564:          /* Be lazy and assume CALL_INSNs clobber all hard registers.  */
                   1565:          for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
                   1566:            map->const_equiv_map[i] = 0;
                   1567:          break;
                   1568: 
                   1569:        case CODE_LABEL:
                   1570:          copy = emit_label (map->label_map[CODE_LABEL_NUMBER (insn)]);
1.1.1.3 ! root     1571:          LABEL_NAME (copy) = LABEL_NAME (insn);
1.1       root     1572:          map->const_age++;
                   1573:          break;
                   1574: 
                   1575:        case BARRIER:
                   1576:          copy = emit_barrier ();
                   1577:          break;
                   1578: 
                   1579:        case NOTE:
                   1580:          /* It is important to discard function-end and function-beg notes,
                   1581:             so we have only one of each in the current function.
                   1582:             Also, NOTE_INSN_DELETED notes aren't useful (save_for_inline
                   1583:             deleted these in the copy used for continuing compilation,
                   1584:             not the copy used for inlining).  */
                   1585:          if (NOTE_LINE_NUMBER (insn) != NOTE_INSN_FUNCTION_END
                   1586:              && NOTE_LINE_NUMBER (insn) != NOTE_INSN_FUNCTION_BEG
                   1587:              && NOTE_LINE_NUMBER (insn) != NOTE_INSN_DELETED)
                   1588:            copy = emit_note (NOTE_SOURCE_FILE (insn), NOTE_LINE_NUMBER (insn));
                   1589:          else
                   1590:            copy = 0;
                   1591:          break;
                   1592: 
                   1593:        default:
                   1594:          abort ();
                   1595:          break;
                   1596:        }
                   1597: 
                   1598:       if (copy)
                   1599:        RTX_INTEGRATED_P (copy) = 1;
                   1600: 
                   1601:       map->insn_map[INSN_UID (insn)] = copy;
                   1602:     }
                   1603: 
                   1604:   /* Now copy the REG_NOTES.  */
                   1605:   for (insn = insns; insn; insn = NEXT_INSN (insn))
                   1606:     if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
                   1607:        && map->insn_map[INSN_UID (insn)])
                   1608:       REG_NOTES (map->insn_map[INSN_UID (insn)])
                   1609:        = copy_rtx_and_substitute (REG_NOTES (insn), map);
                   1610: 
                   1611:   if (local_return_label)
                   1612:     emit_label (local_return_label);
                   1613: 
                   1614:   /* Make copies of the decls of the symbols in the inline function, so that
                   1615:      the copies of the variables get declared in the current function.  Set
                   1616:      up things so that lookup_static_chain knows that to interpret registers
                   1617:      in SAVE_EXPRs for TYPE_SIZEs as local.  */
                   1618: 
                   1619:   inline_function_decl = fndecl;
                   1620:   integrate_decl_tree ((tree) ORIGINAL_DECL_INITIAL (header), 0, map, 0);
                   1621:   integrate_parm_decls (DECL_ARGUMENTS (fndecl), map, arg_vector);
                   1622:   inline_function_decl = 0;
                   1623: 
                   1624:   /* End the scope containing the copied formal parameter variables.  */
                   1625: 
                   1626:   expand_end_bindings (getdecls (), 1, 1);
                   1627:   poplevel (1, 1, 0);
                   1628:   poplevel (0, 0, 0);
                   1629:   emit_line_note (input_filename, lineno);
                   1630: 
                   1631:   if (structure_value_addr)
                   1632:     return gen_rtx (MEM, TYPE_MODE (type),
                   1633:                    memory_address (TYPE_MODE (type), structure_value_addr));
                   1634:   return target;
                   1635: }
                   1636: 
                   1637: /* Given a chain of PARM_DECLs, ARGS, copy each decl into a VAR_DECL,
                   1638:    push all of those decls and give each one the corresponding home.  */
                   1639: 
                   1640: static void
                   1641: integrate_parm_decls (args, map, arg_vector)
                   1642:      tree args;
                   1643:      struct inline_remap *map;
                   1644:      rtvec arg_vector;
                   1645: {
                   1646:   register tree tail;
                   1647:   register int i;
                   1648: 
                   1649:   for (tail = args, i = 0; tail; tail = TREE_CHAIN (tail), i++)
                   1650:     {
                   1651:       register tree decl = build_decl (VAR_DECL, DECL_NAME (tail),
                   1652:                                       TREE_TYPE (tail));
                   1653:       rtx new_decl_rtl
                   1654:        = copy_rtx_and_substitute (RTVEC_ELT (arg_vector, i), map);
                   1655: 
                   1656:       /* These args would always appear unused, if not for this.  */
                   1657:       TREE_USED (decl) = 1;
                   1658:       /* Prevent warning for shadowing with these.  */
                   1659:       DECL_FROM_INLINE (decl) = 1;
                   1660:       pushdecl (decl);
                   1661:       /* Fully instantiate the address with the equivalent form so that the
                   1662:         debugging information contains the actual register, instead of the
                   1663:         virtual register.   Do this by not passing an insn to
                   1664:         subst_constants.  */
                   1665:       subst_constants (&new_decl_rtl, 0, map);
                   1666:       apply_change_group ();
                   1667:       DECL_RTL (decl) = new_decl_rtl;
                   1668:     }
                   1669: }
                   1670: 
                   1671: /* Given a BLOCK node LET, push decls and levels so as to construct in the
                   1672:    current function a tree of contexts isomorphic to the one that is given.
                   1673: 
                   1674:    LEVEL indicates how far down into the BLOCK tree is the node we are
                   1675:    currently traversing.  It is always zero for the initial call.
                   1676: 
                   1677:    MAP, if nonzero, is a pointer to a inline_remap map which indicates how
                   1678:    registers used in the DECL_RTL field should be remapped.  If it is zero,
                   1679:    no mapping is necessary.
                   1680: 
                   1681:    FUNCTIONBODY indicates whether the top level block tree corresponds to
                   1682:    a function body.  This is identical in meaning to the functionbody
                   1683:    argument of poplevel.  */
                   1684: 
                   1685: static void
                   1686: integrate_decl_tree (let, level, map, functionbody)
                   1687:      tree let;
                   1688:      int level;
                   1689:      struct inline_remap *map;
                   1690:      int functionbody;
                   1691: {
                   1692:   tree t, node;
                   1693: 
                   1694:   pushlevel (0);
                   1695:   
                   1696:   for (t = BLOCK_VARS (let); t; t = TREE_CHAIN (t))
                   1697:     {
                   1698:       tree d = build_decl (TREE_CODE (t), DECL_NAME (t), TREE_TYPE (t));
                   1699:       DECL_SOURCE_LINE (d) = DECL_SOURCE_LINE (t);
                   1700:       DECL_SOURCE_FILE (d) = DECL_SOURCE_FILE (t);
                   1701:       if (! functionbody && DECL_RTL (t) != 0)
                   1702:        {
                   1703:          DECL_RTL (d) = copy_rtx_and_substitute (DECL_RTL (t), map);
                   1704:          /* Fully instantiate the address with the equivalent form so that the
                   1705:             debugging information contains the actual register, instead of the
                   1706:             virtual register.   Do this by not passing an insn to
                   1707:             subst_constants.  */
                   1708:          subst_constants (&DECL_RTL (d), 0, map);
                   1709:          apply_change_group ();
                   1710:        }
                   1711:       else if (DECL_RTL (t))
                   1712:        DECL_RTL (d) = copy_rtx (DECL_RTL (t));
                   1713:       TREE_EXTERNAL (d) = TREE_EXTERNAL (t);
                   1714:       TREE_STATIC (d) = TREE_STATIC (t);
                   1715:       TREE_PUBLIC (d) = TREE_PUBLIC (t);
                   1716:       TREE_CONSTANT (d) = TREE_CONSTANT (t);
                   1717:       TREE_ADDRESSABLE (d) = TREE_ADDRESSABLE (t);
                   1718:       TREE_READONLY (d) = TREE_READONLY (t);
                   1719:       TREE_SIDE_EFFECTS (d) = TREE_SIDE_EFFECTS (t);
                   1720:       /* These args would always appear unused, if not for this.  */
                   1721:       TREE_USED (d) = 1;
                   1722:       /* Prevent warning for shadowing with these.  */
                   1723:       DECL_FROM_INLINE (d) = 1;
                   1724:       pushdecl (d);
                   1725:     }
                   1726: 
                   1727:   for (t = BLOCK_SUBBLOCKS (let); t; t = TREE_CHAIN (t))
                   1728:     integrate_decl_tree (t, level + 1, map, functionbody);
                   1729: 
                   1730:   node = poplevel (level > 0, 0, level == 0 && functionbody);
                   1731:   if (node)
                   1732:     TREE_USED (node) = TREE_USED (let);
                   1733: }
                   1734: 
                   1735: /* Create a new copy of an rtx.
                   1736:    Recursively copies the operands of the rtx,
                   1737:    except for those few rtx codes that are sharable.
                   1738: 
                   1739:    We always return an rtx that is similar to that incoming rtx, with the
                   1740:    exception of possibly changing a REG to a SUBREG or vice versa.  No
                   1741:    rtl is ever emitted.
                   1742: 
                   1743:    Handle constants that need to be placed in the constant pool by
                   1744:    calling `force_const_mem'.  */
                   1745: 
                   1746: rtx
                   1747: copy_rtx_and_substitute (orig, map)
                   1748:      register rtx orig;
                   1749:      struct inline_remap *map;
                   1750: {
                   1751:   register rtx copy, temp;
                   1752:   register int i, j;
                   1753:   register RTX_CODE code;
                   1754:   register enum machine_mode mode;
                   1755:   register char *format_ptr;
                   1756:   int regno;
                   1757: 
                   1758:   if (orig == 0)
                   1759:     return 0;
                   1760: 
                   1761:   code = GET_CODE (orig);
                   1762:   mode = GET_MODE (orig);
                   1763: 
                   1764:   switch (code)
                   1765:     {
                   1766:     case REG:
                   1767:       /* If the stack pointer register shows up, it must be part of
                   1768:         stack-adjustments (*not* because we eliminated the frame pointer!).
                   1769:         Small hard registers are returned as-is.  Pseudo-registers
                   1770:         go through their `reg_map'.  */
                   1771:       regno = REGNO (orig);
                   1772:       if (regno <= LAST_VIRTUAL_REGISTER)
                   1773:        {
                   1774:          /* Some hard registers are also mapped,
                   1775:             but others are not translated.  */
                   1776:          if (map->reg_map[regno] != 0)
                   1777:            return map->reg_map[regno];
                   1778: 
                   1779:          /* If this is the virtual frame pointer, make space in current
                   1780:             function's stack frame for the stack frame of the inline function.
                   1781: 
                   1782:             Copy the address of this area into a pseudo.  Map
                   1783:             virtual_stack_vars_rtx to this pseudo and set up a constant
                   1784:             equivalence for it to be the address.  This will substitute the
                   1785:             address into insns where it can be substituted and use the new
                   1786:             pseudo where it can't.  */
                   1787:          if (regno == VIRTUAL_STACK_VARS_REGNUM)
                   1788:            {
                   1789:              rtx loc, seq;
                   1790:              int size = DECL_FRAME_SIZE (map->fndecl);
                   1791:              int rounded;
                   1792: 
                   1793:              start_sequence ();
                   1794:              loc = assign_stack_temp (BLKmode, size, 1);
                   1795:              loc = XEXP (loc, 0);
                   1796: #ifdef FRAME_GROWS_DOWNWARD
                   1797:              /* In this case, virtual_stack_vars_rtx points to one byte
                   1798:                 higher than the top of the frame area.  So compute the offset
                   1799:                 to one byte higher than our substitute frame.
                   1800:                 Keep the fake frame pointer aligned like a real one.  */
                   1801:              rounded = CEIL_ROUND (size, BIGGEST_ALIGNMENT / BITS_PER_UNIT);
                   1802:              loc = plus_constant (loc, rounded);
                   1803: #endif
1.1.1.2   root     1804:              map->reg_map[regno] = temp = force_operand (loc, 0);
                   1805:              map->const_equiv_map[REGNO (temp)] = loc;
                   1806:              map->const_age_map[REGNO (temp)] = CONST_AGE_PARM;
1.1       root     1807: 
                   1808:              seq = gen_sequence ();
                   1809:              end_sequence ();
                   1810:              emit_insn_after (seq, map->insns_at_start);
1.1.1.2   root     1811:              return temp;
1.1       root     1812:            }
                   1813:          else if (regno == VIRTUAL_INCOMING_ARGS_REGNUM)
                   1814:            {
                   1815:              /* Do the same for a block to contain any arguments referenced
                   1816:                 in memory. */
                   1817:              rtx loc, seq;
                   1818:              int size = FUNCTION_ARGS_SIZE (DECL_SAVED_INSNS (map->fndecl));
                   1819: 
                   1820:              start_sequence ();
                   1821:              loc = assign_stack_temp (BLKmode, size, 1);
                   1822:              loc = XEXP (loc, 0);
1.1.1.2   root     1823:              map->reg_map[regno] = temp = force_operand (loc, 0);
                   1824:              map->const_equiv_map[REGNO (temp)] = loc;
                   1825:              map->const_age_map[REGNO (temp)] = CONST_AGE_PARM;
1.1       root     1826: 
                   1827:              seq = gen_sequence ();
                   1828:              end_sequence ();
                   1829:              emit_insn_after (seq, map->insns_at_start);
1.1.1.2   root     1830:              return temp;
1.1       root     1831:            }
                   1832:          else if (REG_FUNCTION_VALUE_P (orig))
                   1833:            {
                   1834:              /* This is a reference to the function return value.  If
                   1835:                 the function doesn't have a return value, error.  If the
                   1836:                 mode doesn't agree, make a SUBREG.  */
                   1837:              if (map->inline_target == 0)
                   1838:                /* Must be unrolling loops or replicating code if we
                   1839:                   reach here, so return the register unchanged.  */
                   1840:                return orig;
                   1841:              else if (mode != GET_MODE (map->inline_target))
                   1842:                return gen_rtx (SUBREG, mode, map->inline_target, 0);
                   1843:              else
                   1844:                return map->inline_target;
                   1845:            }
                   1846:          return orig;
                   1847:        }
                   1848:       if (map->reg_map[regno] == NULL)
                   1849:        {
                   1850:          map->reg_map[regno] = gen_reg_rtx (mode);
                   1851:          REG_USERVAR_P (map->reg_map[regno]) = REG_USERVAR_P (orig);
                   1852:          REG_LOOP_TEST_P (map->reg_map[regno]) = REG_LOOP_TEST_P (orig);
                   1853:          RTX_UNCHANGING_P (map->reg_map[regno]) = RTX_UNCHANGING_P (orig);
                   1854:          /* A reg with REG_FUNCTION_VALUE_P true will never reach here.  */
                   1855:        }
                   1856:       return map->reg_map[regno];
                   1857: 
                   1858:     case SUBREG:
                   1859:       copy = copy_rtx_and_substitute (SUBREG_REG (orig), map);
                   1860:       /* SUBREG is ordinary, but don't make nested SUBREGs.  */
                   1861:       if (GET_CODE (copy) == SUBREG)
                   1862:        return gen_rtx (SUBREG, GET_MODE (orig), SUBREG_REG (copy),
                   1863:                        SUBREG_WORD (orig) + SUBREG_WORD (copy));
                   1864:       else
                   1865:        return gen_rtx (SUBREG, GET_MODE (orig), copy,
                   1866:                        SUBREG_WORD (orig));
                   1867: 
                   1868:     case USE:
                   1869:     case CLOBBER:
                   1870:       /* USE and CLOBBER are ordinary, but we convert (use (subreg foo))
                   1871:         to (use foo).  */
                   1872:       copy = copy_rtx_and_substitute (XEXP (orig, 0), map);
                   1873:       if (GET_CODE (copy) == SUBREG)
                   1874:        copy = SUBREG_REG (copy);
                   1875:       return gen_rtx (code, VOIDmode, copy);
                   1876: 
                   1877:     case CODE_LABEL:
                   1878:       LABEL_PRESERVE_P (map->label_map[CODE_LABEL_NUMBER (orig)])
                   1879:        = LABEL_PRESERVE_P (orig);
                   1880:       return map->label_map[CODE_LABEL_NUMBER (orig)];
                   1881: 
                   1882:     case LABEL_REF:
                   1883:       copy = rtx_alloc (LABEL_REF);
                   1884:       PUT_MODE (copy, mode);
                   1885:       XEXP (copy, 0) = map->label_map[CODE_LABEL_NUMBER (XEXP (orig, 0))];
                   1886:       LABEL_OUTSIDE_LOOP_P (copy) = LABEL_OUTSIDE_LOOP_P (orig);
                   1887:       return copy;
                   1888: 
                   1889:     case PC:
                   1890:     case CC0:
                   1891:     case CONST_INT:
1.1.1.3 ! root     1892:       return orig;
        !          1893: 
1.1       root     1894:     case SYMBOL_REF:
1.1.1.3 ! root     1895:       /* Symbols which represent the address of a label stored in the constant
        !          1896:         pool must be modified to point to a constant pool entry for the
        !          1897:         remapped label.  Otherwise, symbols are returned unchanged.  */
        !          1898:       if (CONSTANT_POOL_ADDRESS_P (orig))
        !          1899:        {
        !          1900:          rtx constant = get_pool_constant (orig);
        !          1901:          if (GET_CODE (constant) == LABEL_REF)
        !          1902:            {
        !          1903:              copy = rtx_alloc (LABEL_REF);
        !          1904:              PUT_MODE (copy, mode);
        !          1905:              XEXP (copy, 0)
        !          1906:                = map->label_map[CODE_LABEL_NUMBER (XEXP (constant, 0))];
        !          1907:              LABEL_OUTSIDE_LOOP_P (copy) = LABEL_OUTSIDE_LOOP_P (orig);
        !          1908:              copy = force_const_mem (Pmode, copy);
        !          1909:              return XEXP (copy, 0);
        !          1910:            }
        !          1911:        }
1.1       root     1912:       return orig;
                   1913: 
                   1914:     case CONST_DOUBLE:
                   1915:       /* We have to make a new copy of this CONST_DOUBLE because don't want
                   1916:         to use the old value of CONST_DOUBLE_MEM.  Also, this may be a
                   1917:         duplicate of a CONST_DOUBLE we have already seen.  */
                   1918:       if (GET_MODE_CLASS (GET_MODE (orig)) == MODE_FLOAT)
                   1919:        {
                   1920:          REAL_VALUE_TYPE d;
                   1921: 
                   1922:          REAL_VALUE_FROM_CONST_DOUBLE (d, orig);
                   1923:          return immed_real_const_1 (d, GET_MODE (orig));
                   1924:        }
                   1925:       else
                   1926:        return immed_double_const (CONST_DOUBLE_LOW (orig),
                   1927:                                   CONST_DOUBLE_HIGH (orig), VOIDmode);
                   1928: 
                   1929:     case CONST:
                   1930:       /* Make new constant pool entry for a constant
                   1931:         that was in the pool of the inline function.  */
                   1932:       if (RTX_INTEGRATED_P (orig))
                   1933:        {
                   1934:          /* If this was an address of a constant pool entry that itself
                   1935:             had to be placed in the constant pool, it might not be a
                   1936:             valid address.  So the recursive call below might turn it
                   1937:             into a register.  In that case, it isn't a constant any
                   1938:             more, so return it.  This has the potential of changing a
                   1939:             MEM into a REG, but we'll assume that it safe.  */
                   1940:          temp = copy_rtx_and_substitute (XEXP (orig, 0), map);
                   1941:          if (! CONSTANT_P (temp))
                   1942:            return temp;
                   1943:          return validize_mem (force_const_mem (GET_MODE (orig), temp));
                   1944:        }
                   1945:       break;
                   1946: 
                   1947:     case ADDRESS:
                   1948:       /* If from constant pool address, make new constant pool entry and
                   1949:         return its address.  */
                   1950:       if (! RTX_INTEGRATED_P (orig))
                   1951:        abort ();
                   1952: 
                   1953:       temp = force_const_mem (GET_MODE (orig),
                   1954:                              copy_rtx_and_substitute (XEXP (orig, 0), map));
                   1955: 
                   1956: #if 0
                   1957:       /* Legitimizing the address here is incorrect.
                   1958: 
                   1959:         The only ADDRESS rtx's that can reach here are ones created by
                   1960:         save_constants.  Hence the operand of the ADDRESS is always legal
                   1961:         in this position of the instruction, since the original rtx without
                   1962:         the ADDRESS was legal.
                   1963: 
                   1964:         The reason we don't legitimize the address here is that on the
                   1965:         Sparc, the caller may have a (high ...) surrounding this ADDRESS.
                   1966:         This code forces the operand of the address to a register, which
                   1967:         fails because we can not take the HIGH part of a register.
                   1968: 
                   1969:         Also, change_address may create new registers.  These registers
                   1970:         will not have valid reg_map entries.  This can cause try_constants()
                   1971:         to fail because assumes that all registers in the rtx have valid
                   1972:         reg_map entries, and it may end up replacing one of these new
                   1973:         registers with junk. */
                   1974: 
                   1975:       if (! memory_address_p (GET_MODE (temp), XEXP (temp, 0)))
                   1976:        temp = change_address (temp, GET_MODE (temp), XEXP (temp, 0));
                   1977: #endif
                   1978: 
                   1979:       return XEXP (temp, 0);
                   1980: 
                   1981:     case ASM_OPERANDS:
                   1982:       /* If a single asm insn contains multiple output operands
                   1983:         then it contains multiple ASM_OPERANDS rtx's that share operand 3.
                   1984:         We must make sure that the copied insn continues to share it.  */
                   1985:       if (map->orig_asm_operands_vector == XVEC (orig, 3))
                   1986:        {
                   1987:          copy = rtx_alloc (ASM_OPERANDS);
                   1988:          XSTR (copy, 0) = XSTR (orig, 0);
                   1989:          XSTR (copy, 1) = XSTR (orig, 1);
                   1990:          XINT (copy, 2) = XINT (orig, 2);
                   1991:          XVEC (copy, 3) = map->copy_asm_operands_vector;
                   1992:          XVEC (copy, 4) = map->copy_asm_constraints_vector;
                   1993:          XSTR (copy, 5) = XSTR (orig, 5);
                   1994:          XINT (copy, 6) = XINT (orig, 6);
                   1995:          return copy;
                   1996:        }
                   1997:       break;
                   1998: 
                   1999:     case CALL:
                   2000:       /* This is given special treatment because the first
                   2001:         operand of a CALL is a (MEM ...) which may get
                   2002:         forced into a register for cse.  This is undesirable
                   2003:         if function-address cse isn't wanted or if we won't do cse.  */
                   2004: #ifndef NO_FUNCTION_CSE
                   2005:       if (! (optimize && ! flag_no_function_cse))
                   2006: #endif
                   2007:        return gen_rtx (CALL, GET_MODE (orig),
                   2008:                        gen_rtx (MEM, GET_MODE (XEXP (orig, 0)),
                   2009:                                 copy_rtx_and_substitute (XEXP (XEXP (orig, 0), 0), map)),
                   2010:                        copy_rtx_and_substitute (XEXP (orig, 1), map));
                   2011:       break;
                   2012: 
                   2013: #if 0
                   2014:       /* Must be ifdefed out for loop unrolling to work.  */
                   2015:     case RETURN:
                   2016:       abort ();
                   2017: #endif
                   2018: 
                   2019:     case SET:
                   2020:       /* If this is setting fp or ap, it means that we have a nonlocal goto.
                   2021:         Don't alter that.
                   2022:         If the nonlocal goto is into the current function,
                   2023:         this will result in unnecessarily bad code, but should work.  */
                   2024:       if (SET_DEST (orig) == virtual_stack_vars_rtx
                   2025:          || SET_DEST (orig) == virtual_incoming_args_rtx)
                   2026:        return gen_rtx (SET, VOIDmode, SET_DEST (orig),
                   2027:                        copy_rtx_and_substitute (SET_SRC (orig), map));
                   2028:       break;
                   2029: 
                   2030:     case MEM:
                   2031:       copy = rtx_alloc (MEM);
                   2032:       PUT_MODE (copy, mode);
                   2033:       XEXP (copy, 0) = copy_rtx_and_substitute (XEXP (orig, 0), map);
                   2034:       MEM_IN_STRUCT_P (copy) = MEM_IN_STRUCT_P (orig);
                   2035:       MEM_VOLATILE_P (copy) = MEM_VOLATILE_P (orig);
                   2036:       RTX_UNCHANGING_P (copy) = RTX_UNCHANGING_P (orig);
                   2037:       return copy;
                   2038:     }
                   2039: 
                   2040:   copy = rtx_alloc (code);
                   2041:   PUT_MODE (copy, mode);
                   2042:   copy->in_struct = orig->in_struct;
                   2043:   copy->volatil = orig->volatil;
                   2044:   copy->unchanging = orig->unchanging;
                   2045: 
                   2046:   format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
                   2047: 
                   2048:   for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
                   2049:     {
                   2050:       switch (*format_ptr++)
                   2051:        {
                   2052:        case '0':
                   2053:          break;
                   2054: 
                   2055:        case 'e':
                   2056:          XEXP (copy, i) = copy_rtx_and_substitute (XEXP (orig, i), map);
                   2057:          break;
                   2058: 
                   2059:        case 'u':
                   2060:          /* Change any references to old-insns to point to the
                   2061:             corresponding copied insns.  */
                   2062:          XEXP (copy, i) = map->insn_map[INSN_UID (XEXP (orig, i))];
                   2063:          break;
                   2064: 
                   2065:        case 'E':
                   2066:          XVEC (copy, i) = XVEC (orig, i);
                   2067:          if (XVEC (orig, i) != NULL && XVECLEN (orig, i) != 0)
                   2068:            {
                   2069:              XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
                   2070:              for (j = 0; j < XVECLEN (copy, i); j++)
                   2071:                XVECEXP (copy, i, j)
                   2072:                  = copy_rtx_and_substitute (XVECEXP (orig, i, j), map);
                   2073:            }
                   2074:          break;
                   2075: 
                   2076:        case 'i':
                   2077:          XINT (copy, i) = XINT (orig, i);
                   2078:          break;
                   2079: 
                   2080:        case 's':
                   2081:          XSTR (copy, i) = XSTR (orig, i);
                   2082:          break;
                   2083: 
                   2084:        default:
                   2085:          abort ();
                   2086:        }
                   2087:     }
                   2088: 
                   2089:   if (code == ASM_OPERANDS && map->orig_asm_operands_vector == 0)
                   2090:     {
                   2091:       map->orig_asm_operands_vector = XVEC (orig, 3);
                   2092:       map->copy_asm_operands_vector = XVEC (copy, 3);
                   2093:       map->copy_asm_constraints_vector = XVEC (copy, 4);
                   2094:     }
                   2095: 
                   2096:   return copy;
                   2097: }
                   2098: 
                   2099: /* Substitute known constant values into INSN, if that is valid.  */
                   2100: 
                   2101: void
                   2102: try_constants (insn, map)
                   2103:      rtx insn;
                   2104:      struct inline_remap *map;
                   2105: {
                   2106:   int i;
                   2107: 
                   2108:   map->num_sets = 0;
                   2109:   subst_constants (&PATTERN (insn), insn, map);
                   2110: 
                   2111:   /* Apply the changes if they are valid; otherwise discard them.  */
                   2112:   apply_change_group ();
                   2113: 
                   2114:   /* Show we don't know the value of anything stored or clobbered.  */
                   2115:   note_stores (PATTERN (insn), mark_stores);
                   2116:   map->last_pc_value = 0;
                   2117: #ifdef HAVE_cc0
                   2118:   map->last_cc0_value = 0;
                   2119: #endif
                   2120: 
                   2121:   /* Set up any constant equivalences made in this insn.  */
                   2122:   for (i = 0; i < map->num_sets; i++)
                   2123:     {
                   2124:       if (GET_CODE (map->equiv_sets[i].dest) == REG)
                   2125:        {
                   2126:          int regno = REGNO (map->equiv_sets[i].dest);
                   2127: 
                   2128:          if (map->const_equiv_map[regno] == 0
                   2129:              /* Following clause is a hack to make case work where GNU C++
                   2130:                 reassigns a variable to make cse work right.  */
                   2131:              || ! rtx_equal_p (map->const_equiv_map[regno],
                   2132:                                map->equiv_sets[i].equiv))
                   2133:            {
                   2134:              map->const_equiv_map[regno] = map->equiv_sets[i].equiv;
                   2135:              map->const_age_map[regno] = map->const_age;
                   2136:            }
                   2137:        }
                   2138:       else if (map->equiv_sets[i].dest == pc_rtx)
                   2139:        map->last_pc_value = map->equiv_sets[i].equiv;
                   2140: #ifdef HAVE_cc0
                   2141:       else if (map->equiv_sets[i].dest == cc0_rtx)
                   2142:        map->last_cc0_value = map->equiv_sets[i].equiv;
                   2143: #endif
                   2144:     }
                   2145: }
                   2146: 
                   2147: /* Substitute known constants for pseudo regs in the contents of LOC,
                   2148:    which are part of INSN.
1.1.1.2   root     2149:    If INSN is zero, the substitution should always be done (this is used to
1.1       root     2150:    update DECL_RTL).
                   2151:    These changes are taken out by try_constants if the result is not valid.
                   2152: 
                   2153:    Note that we are more concerned with determining when the result of a SET
                   2154:    is a constant, for further propagation, than actually inserting constants
                   2155:    into insns; cse will do the latter task better.
                   2156: 
                   2157:    This function is also used to adjust address of items previously addressed
                   2158:    via the virtual stack variable or virtual incoming arguments registers.  */
                   2159: 
                   2160: static void
                   2161: subst_constants (loc, insn, map)
                   2162:      rtx *loc;
                   2163:      rtx insn;
                   2164:      struct inline_remap *map;
                   2165: {
                   2166:   rtx x = *loc;
                   2167:   register int i;
                   2168:   register enum rtx_code code;
                   2169:   register char *format_ptr;
                   2170:   int num_changes = num_validated_changes ();
                   2171:   rtx new = 0;
                   2172:   enum machine_mode op0_mode;
                   2173: 
                   2174:   code = GET_CODE (x);
                   2175: 
                   2176:   switch (code)
                   2177:     {
                   2178:     case PC:
                   2179:     case CONST_INT:
                   2180:     case CONST_DOUBLE:
                   2181:     case SYMBOL_REF:
                   2182:     case CONST:
                   2183:     case LABEL_REF:
                   2184:     case ADDRESS:
                   2185:       return;
                   2186: 
                   2187: #ifdef HAVE_cc0
                   2188:     case CC0:
                   2189:       validate_change (insn, loc, map->last_cc0_value, 1);
                   2190:       return;
                   2191: #endif
                   2192: 
                   2193:     case USE:
                   2194:     case CLOBBER:
                   2195:       /* The only thing we can do with a USE or CLOBBER is possibly do
                   2196:         some substitutions in a MEM within it.  */
                   2197:       if (GET_CODE (XEXP (x, 0)) == MEM)
                   2198:        subst_constants (&XEXP (XEXP (x, 0), 0), insn, map);
                   2199:       return;
                   2200: 
                   2201:     case REG:
                   2202:       /* Substitute for parms and known constants.  Don't replace
                   2203:         hard regs used as user variables with constants.  */
                   2204:       {
                   2205:        int regno = REGNO (x);
                   2206: 
                   2207:        if (! (regno < FIRST_PSEUDO_REGISTER && REG_USERVAR_P (x))
                   2208:            && regno < map->const_equiv_map_size
                   2209:            && map->const_equiv_map[regno] != 0
                   2210:            && map->const_age_map[regno] >= map->const_age)
                   2211:          validate_change (insn, loc, map->const_equiv_map[regno], 1);
                   2212:        return;
                   2213:       }
                   2214: 
                   2215:     case SUBREG:
                   2216:       /* SUBREG is ordinary, but don't make nested SUBREGs and try to simplify
                   2217:         constants.  */
                   2218:       {
                   2219:        rtx inner = SUBREG_REG (x);
                   2220:        rtx new = 0;
                   2221: 
                   2222:        /* We can't call subst_constants on &SUBREG_REG (x) because any
                   2223:           constant or SUBREG wouldn't be valid inside our SUBEG.  Instead,
                   2224:           see what is inside, try to form the new SUBREG and see if that is
                   2225:           valid.  We handle two cases: extracting a full word in an 
                   2226:           integral mode and extracting the low part.  */
                   2227:        subst_constants (&inner, 0, map);
                   2228: 
                   2229:        if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT
                   2230:            && GET_MODE_SIZE (GET_MODE (x)) == UNITS_PER_WORD
                   2231:            && GET_MODE (SUBREG_REG (x)) != VOIDmode)
                   2232:          new = operand_subword (inner, SUBREG_WORD (x), 0,
                   2233:                                 GET_MODE (SUBREG_REG (x)));
                   2234: 
                   2235:        if (new == 0 && subreg_lowpart_p (x))
                   2236:          new = gen_lowpart_common (GET_MODE (x), inner);
                   2237: 
                   2238:        if (new)
                   2239:          validate_change (insn, loc, new, 1);
                   2240: 
                   2241:        return;
                   2242:       }
                   2243: 
                   2244:     case MEM:
                   2245:       subst_constants (&XEXP (x, 0), insn, map);
                   2246: 
                   2247:       /* If a memory address got spoiled, change it back.  */
                   2248:       if (insn != 0 && num_validated_changes () != num_changes
                   2249:          && !memory_address_p (GET_MODE (x), XEXP (x, 0)))
                   2250:        cancel_changes (num_changes);
                   2251:       return;
                   2252: 
                   2253:     case SET:
                   2254:       {
                   2255:        /* Substitute constants in our source, and in any arguments to a
                   2256:           complex (e..g, ZERO_EXTRACT) destination, but not in the destination
                   2257:           itself.  */
                   2258:        rtx *dest_loc = &SET_DEST (x);
                   2259:        rtx dest = *dest_loc;
                   2260:        rtx src, tem;
                   2261: 
                   2262:        subst_constants (&SET_SRC (x), insn, map);
                   2263:        src = SET_SRC (x);
                   2264: 
                   2265:        while (GET_CODE (*dest_loc) == ZERO_EXTRACT
                   2266:               || GET_CODE (*dest_loc) == SIGN_EXTRACT
                   2267:               || GET_CODE (*dest_loc) == SUBREG
                   2268:               || GET_CODE (*dest_loc) == STRICT_LOW_PART)
                   2269:          {
                   2270:            if (GET_CODE (*dest_loc) == ZERO_EXTRACT)
                   2271:              {
                   2272:                subst_constants (&XEXP (*dest_loc, 1), insn, map);
                   2273:                subst_constants (&XEXP (*dest_loc, 2), insn, map);
                   2274:              }
                   2275:            dest_loc = &XEXP (*dest_loc, 0);
                   2276:          }
                   2277: 
                   2278:        /* Check for the case of DEST a SUBREG, both it and the underlying
                   2279:           register are less than one word, and the SUBREG has the wider mode.
                   2280:           In the case, we are really setting the underlying register to the
                   2281:           source converted to the mode of DEST.  So indicate that.  */
                   2282:        if (GET_CODE (dest) == SUBREG
                   2283:            && GET_MODE_SIZE (GET_MODE (dest)) <= UNITS_PER_WORD
                   2284:            && GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest))) <= UNITS_PER_WORD
                   2285:            && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest)))
                   2286:                      <= GET_MODE_SIZE (GET_MODE (dest)))
                   2287:            && (tem = gen_lowpart_if_possible (GET_MODE (dest), src)))
                   2288:          src = tem, dest = SUBREG_REG (dest);
                   2289: 
                   2290:        /* If storing a recognizable value save it for later recording.  */
                   2291:        if ((map->num_sets < MAX_RECOG_OPERANDS)
                   2292:            && (CONSTANT_P (src)
                   2293:                || (GET_CODE (src) == PLUS
                   2294:                    && GET_CODE (XEXP (src, 0)) == REG
                   2295:                    && REGNO (XEXP (src, 0)) >= FIRST_VIRTUAL_REGISTER
                   2296:                    && REGNO (XEXP (src, 0)) <= LAST_VIRTUAL_REGISTER
                   2297:                    && CONSTANT_P (XEXP (src, 1)))
                   2298:                || GET_CODE (src) == COMPARE
                   2299: #ifdef HAVE_cc0
                   2300:                || dest == cc0_rtx
                   2301: #endif
                   2302:                || (dest == pc_rtx
                   2303:                    && (src == pc_rtx || GET_CODE (src) == RETURN
                   2304:                        || GET_CODE (src) == LABEL_REF))))
                   2305:          {
                   2306:            /* Normally, this copy won't do anything.  But, if SRC is a COMPARE
                   2307:               it will cause us to save the COMPARE with any constants
                   2308:               substituted, which is what we want for later.  */
                   2309:            map->equiv_sets[map->num_sets].equiv = copy_rtx (src);
                   2310:            map->equiv_sets[map->num_sets++].dest = dest;
                   2311:          }
                   2312: 
                   2313:        return;
                   2314:       }
                   2315:     }
                   2316: 
                   2317:   format_ptr = GET_RTX_FORMAT (code);
                   2318:   
                   2319:   /* If the first operand is an expression, save its mode for later.  */
                   2320:   if (*format_ptr == 'e')
                   2321:     op0_mode = GET_MODE (XEXP (x, 0));
                   2322: 
                   2323:   for (i = 0; i < GET_RTX_LENGTH (code); i++)
                   2324:     {
                   2325:       switch (*format_ptr++)
                   2326:        {
                   2327:        case '0':
                   2328:          break;
                   2329: 
                   2330:        case 'e':
                   2331:          if (XEXP (x, i))
                   2332:            subst_constants (&XEXP (x, i), insn, map);
                   2333:          break;
                   2334: 
                   2335:        case 'u':
                   2336:        case 'i':
                   2337:        case 's':
                   2338:          break;
                   2339: 
                   2340:        case 'E':
                   2341:          if (XVEC (x, i) != NULL && XVECLEN (x, i) != 0)
                   2342:            {
                   2343:              int j;
                   2344:              for (j = 0; j < XVECLEN (x, i); j++)
                   2345:                subst_constants (&XVECEXP (x, i, j), insn, map);
                   2346:            }
                   2347:          break;
                   2348: 
                   2349:        default:
                   2350:          abort ();
                   2351:        }
                   2352:     }
                   2353: 
                   2354:   /* If this is a commutative operation, move a constant to the second
                   2355:      operand unless the second operand is already a CONST_INT.  */
                   2356:   if ((GET_RTX_CLASS (code) == 'c' || code == NE || code == EQ)
                   2357:       && CONSTANT_P (XEXP (x, 0)) && GET_CODE (XEXP (x, 1)) != CONST_INT)
                   2358:     {
                   2359:       rtx tem = XEXP (x, 0);
                   2360:       validate_change (insn, &XEXP (x, 0), XEXP (x, 1), 1);
                   2361:       validate_change (insn, &XEXP (x, 1), tem, 1);
                   2362:     }
                   2363: 
                   2364:   /* Simplify the expression in case we put in some constants.  */
                   2365:   switch (GET_RTX_CLASS (code))
                   2366:     {
                   2367:     case '1':
                   2368:       new = simplify_unary_operation (code, GET_MODE (x),
                   2369:                                      XEXP (x, 0), op0_mode);
                   2370:       break;
                   2371: 
                   2372:     case '<':
                   2373:       {
                   2374:        enum machine_mode op_mode = GET_MODE (XEXP (x, 0));
                   2375:        if (op_mode == VOIDmode)
                   2376:          op_mode = GET_MODE (XEXP (x, 1));
                   2377:        new = simplify_relational_operation (code, op_mode,
                   2378:                                             XEXP (x, 0), XEXP (x, 1));
                   2379:        break;
                   2380:       }
                   2381: 
                   2382:     case '2':
                   2383:     case 'c':
                   2384:       new = simplify_binary_operation (code, GET_MODE (x),
                   2385:                                       XEXP (x, 0), XEXP (x, 1));
                   2386:       break;
                   2387: 
                   2388:     case 'b':
                   2389:     case '3':
                   2390:       new = simplify_ternary_operation (code, GET_MODE (x), op0_mode,
                   2391:                                        XEXP (x, 0), XEXP (x, 1), XEXP (x, 2));
                   2392:       break;
                   2393:     }
                   2394: 
                   2395:   if (new)
                   2396:     validate_change (insn, loc, new, 1);
                   2397: }
                   2398: 
                   2399: /* Show that register modified no longer contain known constants.  We are
                   2400:    called from note_stores with parts of the new insn.  */
                   2401: 
                   2402: void
                   2403: mark_stores (dest, x)
                   2404:      rtx dest;
                   2405:      rtx x;
                   2406: {
                   2407:   if (GET_CODE (dest) == SUBREG)
                   2408:     dest = SUBREG_REG (dest);
                   2409: 
                   2410:   if (GET_CODE (dest) == REG)
                   2411:     global_const_equiv_map[REGNO (dest)] = 0;
                   2412: }
                   2413: 
                   2414: /* If any CONST expressions with RTX_INTEGRATED_P are present in the rtx
                   2415:    pointed to by PX, they represent constants in the constant pool.
                   2416:    Replace these with a new memory reference obtained from force_const_mem.
                   2417:    Similarly, ADDRESS expressions with RTX_INTEGRATED_P represent the
                   2418:    address of a constant pool entry.  Replace them with the address of
                   2419:    a new constant pool entry obtained from force_const_mem.  */
                   2420: 
                   2421: static void
                   2422: restore_constants (px)
                   2423:      rtx *px;
                   2424: {
                   2425:   rtx x = *px;
                   2426:   int i, j;
                   2427:   char *fmt;
                   2428: 
                   2429:   if (x == 0)
                   2430:     return;
                   2431: 
                   2432:   if (GET_CODE (x) == CONST_DOUBLE)
                   2433:     {
                   2434:       /* We have to make a new CONST_DOUBLE to ensure that we account for
                   2435:         it correctly.  Using the old CONST_DOUBLE_MEM data is wrong.  */
                   2436:       if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
                   2437:        {
                   2438:          REAL_VALUE_TYPE d;
                   2439: 
                   2440:          REAL_VALUE_FROM_CONST_DOUBLE (d, x);
                   2441:          *px = immed_real_const_1 (d, GET_MODE (x));
                   2442:        }
                   2443:       else
                   2444:        *px = immed_double_const (CONST_DOUBLE_LOW (x), CONST_DOUBLE_HIGH (x),
                   2445:                                  VOIDmode);
                   2446:     }
                   2447: 
                   2448:   else if (RTX_INTEGRATED_P (x) && GET_CODE (x) == CONST)
                   2449:     {
                   2450:       restore_constants (&XEXP (x, 0));
                   2451:       *px = validize_mem (force_const_mem (GET_MODE (x), XEXP (x, 0)));
                   2452:     }
                   2453:   else if (RTX_INTEGRATED_P (x) && GET_CODE (x) == SUBREG)
                   2454:     {
                   2455:       /* This must be (subreg/i:M1 (const/i:M2 ...) 0).  */
                   2456:       rtx new = XEXP (SUBREG_REG (x), 0);
                   2457: 
                   2458:       restore_constants (&new);
                   2459:       new = force_const_mem (GET_MODE (SUBREG_REG (x)), new);
                   2460:       PUT_MODE (new, GET_MODE (x));
                   2461:       *px = validize_mem (new);
                   2462:     }
                   2463:   else if (RTX_INTEGRATED_P (x) && GET_CODE (x) == ADDRESS)
                   2464:     {
                   2465:       restore_constants (&XEXP (x, 0));
                   2466:       *px = XEXP (force_const_mem (GET_MODE (x), XEXP (x, 0)), 0);
                   2467:     }
                   2468:   else
                   2469:     {
                   2470:       fmt = GET_RTX_FORMAT (GET_CODE (x));
                   2471:       for (i = 0; i < GET_RTX_LENGTH (GET_CODE (x)); i++)
                   2472:        {
                   2473:          switch (*fmt++)
                   2474:            {
                   2475:            case 'E':
                   2476:              for (j = 0; j < XVECLEN (x, i); j++)
                   2477:                restore_constants (&XVECEXP (x, i, j));
                   2478:              break;
                   2479: 
                   2480:            case 'e':
                   2481:              restore_constants (&XEXP (x, i));
                   2482:              break;
                   2483:            }
                   2484:        }
                   2485:     }
                   2486: }
                   2487: 
                   2488: /* Output the assembly language code for the function FNDECL
                   2489:    from its DECL_SAVED_INSNS.  Used for inline functions that are output
                   2490:    at end of compilation instead of where they came in the source.  */
                   2491: 
                   2492: void
                   2493: output_inline_function (fndecl)
                   2494:      tree fndecl;
                   2495: {
                   2496:   rtx head = DECL_SAVED_INSNS (fndecl);
                   2497:   rtx last;
                   2498: 
                   2499:   temporary_allocation ();
                   2500: 
                   2501:   current_function_decl = fndecl;
                   2502: 
                   2503:   /* This call is only used to initialize global variables.  */
                   2504:   init_function_start (fndecl, "lossage", 1);
                   2505: 
                   2506:   /* Redo parameter determinations in case the FUNCTION_...
                   2507:      macros took machine-specific actions that need to be redone.  */
                   2508:   assign_parms (fndecl, 1);
                   2509: 
                   2510:   /* Set stack frame size.  */
                   2511:   assign_stack_local (BLKmode, DECL_FRAME_SIZE (fndecl), 0);
                   2512: 
                   2513:   restore_reg_data (FIRST_PARM_INSN (head));
                   2514: 
                   2515:   stack_slot_list = STACK_SLOT_LIST (head);
                   2516: 
                   2517:   if (FUNCTION_FLAGS (head) & FUNCTION_FLAGS_CALLS_ALLOCA)
                   2518:     current_function_calls_alloca = 1;
                   2519: 
                   2520:   if (FUNCTION_FLAGS (head) & FUNCTION_FLAGS_CALLS_SETJMP)
                   2521:     current_function_calls_setjmp = 1;
                   2522: 
                   2523:   if (FUNCTION_FLAGS (head) & FUNCTION_FLAGS_CALLS_LONGJMP)
                   2524:     current_function_calls_longjmp = 1;
                   2525: 
                   2526:   if (FUNCTION_FLAGS (head) & FUNCTION_FLAGS_RETURNS_STRUCT)
                   2527:     current_function_returns_struct = 1;
                   2528: 
                   2529:   if (FUNCTION_FLAGS (head) & FUNCTION_FLAGS_RETURNS_PCC_STRUCT)
                   2530:     current_function_returns_pcc_struct = 1;
                   2531: 
                   2532:   if (FUNCTION_FLAGS (head) & FUNCTION_FLAGS_NEEDS_CONTEXT)
                   2533:     current_function_needs_context = 1;
                   2534: 
                   2535:   if (FUNCTION_FLAGS (head) & FUNCTION_FLAGS_HAS_NONLOCAL_LABEL)
                   2536:     current_function_has_nonlocal_label = 1;
                   2537: 
                   2538:   if (FUNCTION_FLAGS (head) & FUNCTION_FLAGS_RETURNS_POINTER)
                   2539:     current_function_returns_pointer = 1;
                   2540: 
                   2541:   if (FUNCTION_FLAGS (head) & FUNCTION_FLAGS_USES_CONST_POOL)
                   2542:     current_function_uses_const_pool = 1;
                   2543: 
                   2544:   if (FUNCTION_FLAGS (head) & FUNCTION_FLAGS_USES_PIC_OFFSET_TABLE)
                   2545:     current_function_uses_pic_offset_table = 1;
                   2546: 
                   2547:   current_function_outgoing_args_size = OUTGOING_ARGS_SIZE (head);
                   2548:   current_function_pops_args = POPS_ARGS (head);
                   2549: 
                   2550:   /* There is no need to output a return label again.  */
                   2551:   return_label = 0;
                   2552: 
                   2553:   expand_function_end (DECL_SOURCE_FILE (fndecl), DECL_SOURCE_LINE (fndecl));
                   2554: 
                   2555:   /* Find last insn and rebuild the constant pool.  */
                   2556:   for (last = FIRST_PARM_INSN (head);
                   2557:        NEXT_INSN (last); last = NEXT_INSN (last))
                   2558:     {
                   2559:       if (GET_RTX_CLASS (GET_CODE (last)) == 'i')
                   2560:        {
                   2561:          restore_constants (&PATTERN (last));
                   2562:          restore_constants (&REG_NOTES (last));
                   2563:        }
                   2564:     }
                   2565: 
                   2566:   set_new_first_and_last_insn (FIRST_PARM_INSN (head), last);
                   2567:   set_new_first_and_last_label_num (FIRST_LABELNO (head), LAST_LABELNO (head));
                   2568: 
                   2569:   /* Compile this function all the way down to assembly code.  */
                   2570:   rest_of_compilation (fndecl);
                   2571: 
                   2572:   current_function_decl = 0;
                   2573: 
                   2574:   permanent_allocation ();
                   2575: }

unix.superglobalmegacorp.com

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