Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
data_layout.cxx
Go to the documentation of this file.
00001 /*
00002 
00003   Copyright (C) 2000, 2001 Silicon Graphics, Inc.  All Rights Reserved.
00004 
00005   This program is free software; you can redistribute it and/or modify it
00006   under the terms of version 2 of the GNU General Public License as
00007   published by the Free Software Foundation.
00008 
00009   This program is distributed in the hope that it would be useful, but
00010   WITHOUT ANY WARRANTY; without even the implied warranty of
00011   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
00012 
00013   Further, this software is distributed without any warranty that it is
00014   free of the rightful claim of any third person regarding infringement 
00015   or the like.  Any license provided herein, whether implied or 
00016   otherwise, applies only to this software file.  Patent licenses, if 
00017   any, provided herein do not apply to combinations of this program with 
00018   other software, or any other product whatsoever.  
00019 
00020   You should have received a copy of the GNU General Public License along
00021   with this program; if not, write the Free Software Foundation, Inc., 59
00022   Temple Place - Suite 330, Boston MA 02111-1307, USA.
00023 
00024   Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
00025   Mountain View, CA 94043, or:
00026 
00027   http://www.sgi.com
00028 
00029   For further information regarding this notice, see:
00030 
00031   http://oss.sgi.com/projects/GenInfo/NoticeExplan
00032 
00033 */
00034 
00035 
00036 /* ====================================================================
00037  * ====================================================================
00038  *
00039  *
00040  * Revision history:
00041  *  11-Nov-94 - Original Version
00042  *
00043  * Description:
00044  *
00045  * General support for data layout functionality in the back end.
00046  *
00047  * ====================================================================
00048  * ====================================================================
00049  */
00050 #ifdef USE_PCH
00051 #include "be_com_pch.h"
00052 #endif /* USE_PCH */
00053 #pragma hdrstop
00054 #include <cmplrs/rcodes.h>
00055 #include <sys/resource.h>
00056 
00057 #ifndef _USE_STL_EXT
00058 #include <list>
00059 #else
00060 #include <slist>
00061 #endif
00062 
00063 using namespace std;
00064 
00065 #include "defs.h"
00066 #include "erglob.h"
00067 #include "erbe.h"
00068 #include "config.h"
00069 #include "tracing.h"
00070 #include "strtab.h"
00071 #include "stab.h"
00072 #include "const.h"
00073 #include "glob.h"
00074 #include "mtypes.h"
00075 #include "targ_const.h"
00076 #include "targ_sim.h"
00077 #include "ttype.h"
00078 #include "irbdata.h"
00079 #include "util.h"
00080 #include "stblock.h"
00081 #include "data_layout.h"
00082 #include "wintrinsic.h"
00083 #include "sections.h"
00084 #include "betarget.h"
00085 #include "intrn_info.h"
00086 
00087 extern void Early_Terminate (INT status);
00088 
00089 #define ST_force_gprel(s)       ST_gprel(s)
00090 
00091 ST *SP_Sym;
00092 ST *FP_Sym;
00093 ST *Local_Spill_Sym;
00094 INT32 Current_PU_Actual_Size;
00095 STACK_MODEL Current_PU_Stack_Model = SMODEL_UNDEF;
00096 
00097 #define ST_NAME(st)     (ST_class(st) == CLASS_CONST ? \
00098         Targ_Print(NULL,STC_val(st)) : ST_name(st) )
00099 
00100 static BOOL Frame_Has_Calls;    // whether stack frame has calls
00101 
00102 /* ====================================================================
00103  * "Stack Frame" segments:
00104  *
00105  * The following enumerate sub-segments of a stack frame, which are
00106  * used for stack frame reorganization.
00107  * ====================================================================
00108  */
00109 
00110 typedef enum {
00111   SFSEG_UNKNOWN,        /* Unknown/undefined */
00112   SFSEG_ACTUAL,         /* Actual arguments */
00113   SFSEG_FTEMP,          /* Fixed temporaries (altentry formals) */
00114   SFSEG_FORMAL,         /* Formal argument save area */
00115   SFSEG_UPFORMAL        /* Up-level Formal argument save area */
00116                         /* (e.g. stack vars get put in caller's frame) */
00117   // note that we could define a separate callee-upformal area for
00118   // targets that can store to the uplevel area, but then it is hard
00119   // to optimize away that space when it is not used; so instead we
00120   // do the stack_offset_adjustment trick.
00121 } SF_SEGMENT;
00122 
00123 #define SFSEG_FIRST     SFSEG_ACTUAL
00124 #define SFSEG_LAST      SFSEG_UPFORMAL
00125 
00126 typedef struct {
00127   SF_SEGMENT    seg;    /* Which segment */
00128   ST           *block;  /* Which ST block */
00129   mINT64        maxsize;/* Maximum allocated size */
00130   char         *name;   /* For tracing */
00131 } SF_SEG_DESC;
00132 
00133 #define SFSEG_seg(s)    ((s)->seg)
00134 #define SFSEG_block(s)  ((s)->block)
00135 #define SFSEG_maxsize(s) ((s)->maxsize)
00136 #define SFSEG_name(s)   ((s)->name)
00137 
00138 /* Note:  This code requires the following machine parameters
00139  *
00140  *   Max_Small_Frame_Offset : Maximum simple addressing offset
00141  *      (defined in betarget)
00142  *   DEFAULT_LARGE_OBJECT_BYTES How big is a large object?
00143  *   DEFAULT_TEMP_SPACE_BYTES   How much space to allocate for temps?
00144  */
00145 
00146 #define DEFAULT_LARGE_OBJECT_BYTES      64
00147 
00148 #define DEFAULT_TEMP_SPACE_BYTES 4096
00149 #define MAX_SFSEG_BYTES         0x7FFFFFFFFFFFFFFFLL
00150 
00151 #define MAX_LARGE_FRAME_OFFSET  0x7FFFFFFFFFFFFFFFLL    // 64bits on all targs
00152 #define MAX_FRAME_OFFSET        \
00153         (Current_PU_Stack_Model == SMODEL_SMALL ? \
00154         Max_Small_Frame_Offset : MAX_LARGE_FRAME_OFFSET)
00155 
00156 typedef enum _align {
00157   _BYTE_ALIGN = 1,
00158   _CARD_ALIGN = 2,
00159   _WORD_ALIGN = 4,
00160   _DWORD_ALIGN = 8,
00161   _QUAD_ALIGN = 16
00162 } ALIGN;  
00163 
00164 static STACK_DIR stack_direction;
00165 
00166 #ifndef DEFAULT_STACK_ALIGNMENT
00167 #define DEFAULT_STACK_ALIGNMENT _QUAD_ALIGN
00168 #endif
00169 static INT16 stack_align = DEFAULT_STACK_ALIGNMENT;
00170 
00171 
00172 /* Define the segment descriptors we need: */
00173 static SF_SEG_DESC SF_Seg_Descriptors [SFSEG_LAST+1] = {
00174   { SFSEG_UNKNOWN, NULL, MAX_SFSEG_BYTES, "Unknown" },
00175   { SFSEG_ACTUAL,  NULL, MAX_SFSEG_BYTES, "Actual_Arg" },
00176   { SFSEG_FTEMP,   NULL, MAX_SFSEG_BYTES, "Fixed_Temp" },
00177   { SFSEG_FORMAL,  NULL, MAX_SFSEG_BYTES, "Formal_Arg" },
00178   { SFSEG_UPFORMAL,  NULL, MAX_SFSEG_BYTES, "UpFormal_Arg" }
00179 };
00180 #define SF_Seg_Desc(n)  (&SF_Seg_Descriptors[n])
00181 
00182 #define SF_Block(n)     (SFSEG_block(SF_Seg_Desc(n)))
00183 #define SF_Maxsize(n)   (SFSEG_maxsize(SF_Seg_Desc(n)))
00184 #define SF_Name(n)      (SFSEG_name(SF_Seg_Desc(n)))
00185 
00186 /* How big is a large object?  If we end up with too many small
00187  * objects, we may want to change this value and try again, so we
00188  * use this variable below instead of the #defined default:
00189  */
00190 static INT32 Large_Object_Bytes;
00191 
00192 static BOOL Trace_Frame = FALSE;
00193 
00194 /* ====================================================================
00195  *
00196  * Static/Global Object Layout Related Data Structures
00197  *
00198  * ====================================================================
00199  */
00200 
00201 #define Is_root_base(st) (ST_class(st) == CLASS_BLOCK && STB_root_base(st))
00202 #define Has_No_Base_Block(st) (ST_base(st) == st)
00203 #define Is_Allocatable(st)      (!Has_Base_Block(st) && !Is_root_base(st))
00204 #define Is_Allocatable_Root_Block(st) \
00205  (ST_class(st) == CLASS_BLOCK && !Is_root_base(st) && Has_No_Base_Block(st))
00206 
00207 
00208 /* --------------------------------------------------------------------
00209  * Forward references
00210  * --------------------------------------------------------------------
00211  */
00212 static SECTION_IDX Shorten_Section (ST *, SECTION_IDX);
00213 static void Allocate_Object_To_Section (ST *, SECTION_IDX, UINT);
00214 static void Allocate_Label (ST *lab);
00215 
00216 
00217 BOOL
00218 Is_Allocated (ST *st)
00219 {
00220   ST *base;
00221   INT64 ofst;
00222   Base_Symbol_And_Offset(st, &base, &ofst);
00223   // formals may be allocated to block, but not root_block
00224   if (ST_sclass(st) == SCLASS_FORMAL && ST_class(base) == CLASS_BLOCK) 
00225         return TRUE;
00226   return ((base != st && Is_root_base(base)) || Is_root_base(st));
00227 }
00228 
00229 
00230 
00231 
00232 
00233 #define ROUNDUP(val,align)      ( (-(INT64)align) & (INT64)(val+align-1) )
00234 #define ROUNDDOWN(val,align)    ( (-(INT64)align) & (INT64)(val)         )
00235 #define IS_POW2(num)            ( (~((num)-1) & (num) ) == (num) )
00236 
00237 
00238 /* ====================================================================
00239  *
00240  * ST_on_stack
00241  *
00242  * Returns TRUE if the object is on the Stack.
00243  *
00244  * ====================================================================
00245  */
00246 
00247 BOOL ST_on_stack(ST *sym)
00248 {
00249   if (ST_sclass(sym) == SCLASS_AUTO)
00250         return TRUE;
00251   else if (ST_sclass(sym) == SCLASS_FORMAL)
00252         return TRUE;
00253   else if (sym == SP_Sym || sym == FP_Sym)
00254         return TRUE;
00255   else {
00256         ST *base = Base_Symbol(sym);
00257         if (base == SP_Sym || base == FP_Sym)
00258                 return TRUE;
00259         else
00260                 return FALSE;
00261   }
00262 }
00263 
00264 
00265 
00266 
00267 /* ====================================================================
00268  *
00269  * ST_pu_defined
00270  *
00271  * Returns TRUE if the object is defined in this PU.
00272  *
00273  * ====================================================================
00274  */
00275 
00276 BOOL ST_pu_defined(ST *sym)
00277 {
00278   if ((ST_class(sym) == CLASS_VAR)      ||
00279       (ST_class(sym) == CLASS_CONST))
00280   {
00281     switch(ST_sclass(sym))
00282     {
00283     case SCLASS_AUTO:
00284     case SCLASS_PSTATIC:
00285     case SCLASS_FSTATIC:
00286     case SCLASS_DGLOBAL:
00287     case SCLASS_FORMAL:
00288       return TRUE;
00289     default:
00290       return FALSE;
00291     }
00292   }
00293   return FALSE;
00294 
00295 }
00296 
00297 
00298 // TODO: for efficiency should probably hash this info,
00299 // but for now just do a linear search.
00300 // there shouldn't be very many of these nodes....
00301 typedef struct {
00302   const ST        *sym;
00303         ST        *base;
00304         PREG_NUM   preg;
00305           // This is ST_level(sym).  We store it because when
00306           // Init_ST_formal_info_for_PU() is called for any parent PU after
00307           // the first, the sym field is invalid (its Scope_Table has been
00308           // deallocated).
00309         SYMTAB_IDX level;
00310 } formal_info;
00311 static formal_info *formal_info_array;
00312 static INT max_formal_info_index = 0;
00313 
00314 static void
00315 Realloc_ST_formal_info (INT min_needed)
00316 {
00317         if (min_needed >= max_formal_info_index) {
00318                 // realloc space
00319                 formal_info_array = TYPE_MEM_POOL_REALLOC_N (
00320                         formal_info, &MEM_src_pool, 
00321                         formal_info_array,
00322                         max_formal_info_index,
00323                         min_needed + 8);
00324                 max_formal_info_index = min_needed + 8;
00325         }
00326 }
00327 
00328 // clear out the formal_info_array.
00329 // num_formals may be lower than real number, in case of altentries.
00330 static void
00331 Init_ST_formal_info_for_PU (INT num_formals)
00332 {
00333         if (formal_info_array == NULL) {
00334                 max_formal_info_index = MAX(8,num_formals);
00335                 formal_info_array = (formal_info*) Src_Alloc (
00336                         sizeof(formal_info) * max_formal_info_index);
00337         }
00338         else {
00339                 // clear out the values
00340                 // but don't clear if value is for a uplevel symbol
00341                 // that is still visible.
00342                 INT num_uplevel_entries = 0;
00343                 for (INT i = 0; i < max_formal_info_index; i++) {
00344                         if (formal_info_array[i].sym != NULL) {
00345                                 if (formal_info_array[i].level >=
00346                                     CURRENT_SYMTAB) {
00347                                         formal_info_array[i].sym = NULL;
00348                                         formal_info_array[i].base = NULL;
00349                                         formal_info_array[i].preg = 0;
00350                                         formal_info_array[i].level =
00351                                                 SYMTAB_IDX_ZERO;
00352                                 } else {
00353                                         num_uplevel_entries++;
00354                                 }
00355                         }
00356                 }
00357                 Realloc_ST_formal_info (num_formals + num_uplevel_entries);
00358         }
00359 
00360 #ifdef Is_True_On
00361         // verify formal_info_array invariant: no NULL sym may precede a
00362         // a non-NULL one
00363         Is_True(max_formal_info_index > 0, ("no elements allocated"));
00364         const ST *last = formal_info_array[0].sym;
00365         for (INT i = 0; i < max_formal_info_index; i++) {
00366                 Is_True(last != NULL || last == formal_info_array[i].sym,
00367                         ("NULL sym precedes non-NULL sym"));
00368                 last = formal_info_array[i].sym;
00369         }
00370 #endif
00371 }
00372 
00373 // Look for a formal-ref-base corresponding to the sym.
00374 ST *
00375 Get_ST_formal_ref_base (const ST *sym)
00376 {
00377   if (ST_sclass(sym) != SCLASS_FORMAL_REF)
00378     return NULL;
00379   INT i;
00380   for (i = 0; i < max_formal_info_index; i++) {
00381         if (formal_info_array[i].sym == sym)
00382                 return formal_info_array[i].base;
00383         else if (formal_info_array[i].sym == NULL)
00384                 break;
00385   }
00386   return NULL;
00387 }
00388 
00389 void
00390 Set_ST_formal_ref_base (const ST *sym, ST *base)
00391 {
00392   INT i;
00393   for (i = 0; i < max_formal_info_index; i++) {
00394         if (formal_info_array[i].sym == NULL) {
00395                 formal_info_array[i].sym = sym;
00396                 formal_info_array[i].base = base;
00397                 formal_info_array[i].level = ST_level(sym);
00398                 return;
00399         }
00400   }
00401   Realloc_ST_formal_info (max_formal_info_index);
00402   formal_info_array[i].sym = sym;
00403   formal_info_array[i].base = base;
00404   formal_info_array[i].level = ST_level(sym);
00405 }
00406 
00407 // return 0 if no formal-preg-num
00408 PREG_NUM
00409 Get_ST_formal_preg_num (const ST *base)
00410 {
00411   INT i;
00412   for (i = 0; i < max_formal_info_index; i++) {
00413         if (formal_info_array[i].base == base)
00414                 return formal_info_array[i].preg;
00415         else if (formal_info_array[i].sym == NULL)
00416                 break;
00417   }
00418   return (PREG_NUM) 0;
00419 }
00420 
00421 void
00422 Set_ST_formal_preg_num (const ST *base, PREG_NUM p)
00423 {
00424   INT i;
00425   for (i = 0; i < max_formal_info_index; i++) {
00426         if (formal_info_array[i].base == base) {
00427                 formal_info_array[i].preg = p;
00428                 return;
00429         }
00430   }
00431   Is_True(FALSE, ("Set_ST_formal_preg_num didn't find base"));
00432 }
00433 
00434 static ST *Formal_Sym(ST *sym, BOOL onstack)
00435 {
00436   ST            *base;
00437 
00438   if (ST_sclass(sym) != SCLASS_FORMAL_REF)
00439     return sym;
00440   
00441   if (Is_Allocated(sym))
00442   {
00443     return sym;
00444   }
00445   if (base = Get_ST_formal_ref_base(sym))
00446   {
00447     return base;
00448   }
00449 
00450   base =                Copy_ST(sym);
00451   Set_ST_name(base, Save_Str2(ST_name(base), ".base"));
00452   Set_ST_type(base, Make_Pointer_Type(ST_type(sym)) );
00453   Set_ST_sclass (base, SCLASS_FORMAL);
00454   Set_ST_formal_ref_base(sym, base);
00455  /*
00456   *  sym may need to be promoted, but the base is pointer type
00457   */
00458   Clear_ST_promote_parm(base);  
00459 
00460  /*
00461   *  cannot put uplevel formal in a register
00462   *  unfortunately , the nested_ref is set while lowering MP regions (ie. later)
00463   */
00464   /* Don't put things on the stack because of debug level 3 (PV 642999) */
00465   onstack |=    (Debug_Level > 0 && Debug_Level != 3)   ||
00466                 ST_has_nested_ref(sym)          ||
00467                 ST_declared_static(sym)         ||
00468                 PU_has_mp(Get_Current_PU());
00469 
00470   if (onstack == FALSE)
00471   {
00472     Set_ST_formal_preg_num(base, Create_Preg(TY_mtype(ST_type(base)), ST_name(base)));
00473   }
00474 
00475   if ( Trace_Frame )
00476   {
00477     fprintf(TFile, "SCLASS_FORMAL (%s, base %s, onstack= %d, preg= %d) allocated\n",
00478             ST_name(sym), ST_name(base), onstack, Get_ST_formal_preg_num(base));
00479   }
00480 
00481   return base;
00482 }
00483 
00484 
00485 
00486 /* ====================================================================
00487  *
00488  * Stack_Alignment
00489  *
00490  * Return the alignment requirement for the object on the stack frame.
00491  *
00492  * ====================================================================
00493  */
00494 
00495 INT32
00496 Stack_Alignment ( void )
00497 {
00498   return stack_align;
00499 }
00500 
00501 
00502 STACK_DIR Stack_Direction(void)
00503 {
00504   return stack_direction;
00505 }
00506 
00507 static STACK_DIR
00508 Get_Direction (ST *blk)
00509 {
00510   if (STB_decrement(blk)) return DECREMENT;
00511   else return INCREMENT;
00512 }
00513 
00514 static void
00515 Set_Direction (STACK_DIR dir, ST *blk)
00516 {
00517   if (dir == DECREMENT) Set_STB_decrement(blk);
00518   else Reset_STB_decrement(blk);
00519 }
00520 
00521 static ST*
00522 Create_Local_Block( STACK_DIR dir, STR_IDX name )
00523 {
00524   ST *new_blk = New_ST_Block(name, FALSE, SCLASS_UNKNOWN, stack_align, 0);
00525   Set_Direction(dir, new_blk);
00526   Enter_ST(new_blk);
00527   return new_blk;
00528 }
00529 
00530 static ST *
00531 Create_Base_Reg (char *name, STACK_DIR dir)
00532 {
00533   ST *new_blk = Create_Local_Block(dir, Save_Str(name));
00534   Set_STB_root_base(new_blk);
00535   Set_STB_is_basereg(new_blk);
00536   return new_blk;
00537 }
00538 
00539 
00540 /*
00541  * Temporarily set offset of blk, but don't change base because blk is
00542  * not finished yet.  This allows us to find the correct offset of 
00543  * objects that are in the blk, even while the block is growing.
00544  * Later call Allocate_Space to reset the offset and change the base.
00545  *
00546  * Note that this assumes that the previous blocks under base are fixed;
00547  * This only works for the first "unfixed" block.
00548  */
00549 static void
00550 Assign_Offset (ST *blk, ST *base, INT32 lpad, INT32 rpad)
00551 {
00552   UINT align = Adjusted_Alignment(blk);
00553   Set_ST_ofst(blk, ROUNDUP(STB_size(base) + lpad, align));
00554   if (STB_decrement(base)) {
00555     /* point to start of object */
00556     Set_ST_ofst(blk, 
00557         -(INT64) ROUNDUP(ST_ofst(blk) + ST_size(blk) + rpad, align));
00558   }
00559 }
00560 
00561 /* ====================================================================
00562  *
00563  * Allocate_Space
00564  *
00565  * Compute the new ST_ofst for blk according to the block size of
00566  * base, the pad, the direction.  The CROSS-ENDIAN issue should be
00567  * handled in this routine, when the roundup is performed.
00568  *
00569  * ====================================================================
00570  */
00571 static void
00572 Allocate_Space(ST *base, ST *blk, INT32 lpad, INT32 rpad, INT64 maxsize)
00573 {
00574   UINT align = Adjusted_Alignment(blk);
00575   INT64 old_offset;
00576   INT64 size = ST_size(blk);
00577 
00578   Set_STB_align(base, MAX(STB_align(base), align));
00579   if (!STB_decrement(base)) {
00580     old_offset = STB_size(base);
00581     Set_ST_ofst(blk, ROUNDUP(old_offset + lpad, align));
00582     Set_STB_size(base, ROUNDUP(ST_ofst(blk) + size + rpad, align));
00583   }
00584   else {
00585     old_offset = STB_size(base);
00586     /* align object end */
00587     Set_ST_ofst(blk, ROUNDUP(old_offset + lpad, align));        
00588     Set_ST_ofst(blk,
00589         -(INT64) ROUNDUP(ST_ofst(blk) + size + rpad, align)); /* start */
00590     Set_STB_size(base, -ST_ofst(blk));
00591   }
00592   if ((base == SP_Sym && Frame_Has_Calls) || base == FP_Sym) {
00593         // on stack
00594         // All stack offsets are adjusted a certain amount,
00595         // such that we can use part of the space from the callers frame.
00596         // If based on FP then is always offset even if leaf
00597         // cause are using space in callers frame.
00598         Set_ST_ofst(blk, ST_ofst(blk) + Stack_Offset_Adjustment);
00599   }
00600   if ( Trace_Frame ) {
00601     if (ST_class(blk) == CLASS_CONST)
00602         fprintf ( TFile, "Allocate <constant: %s>", Targ_Print(NULL,STC_val(blk)));
00603     else
00604         fprintf ( TFile, "Allocate %s", ST_name(blk));
00605     fprintf (TFile, " to %s: offset = %lld, size = %lld\n",
00606         ST_name(base), ST_ofst(blk), size);
00607   }
00608   if (STB_size(base) > maxsize
00609         && Is_Local_Symbol(base)                        // on stack
00610         && maxsize == Max_Small_Frame_Offset 
00611         && Current_PU_Stack_Model == SMODEL_SMALL)
00612   {
00613         DevWarn("overflowed small stack frame; will try recompiling with -TENV:large_stack");
00614         Early_Terminate(RC_OVERFLOW_ERROR);
00615   }
00616   Is_True( old_offset <= STB_size(base) && STB_size(base) <= maxsize,
00617         ("Block size overflowed"));
00618 }
00619 
00620 
00621 /* ====================================================================
00622  *
00623  * ST_Block_Merge
00624  *
00625  * Merge second ST entry into the first ST entry's container block,
00626  * if these two ST entries belong to the same storage class.  It
00627  * creates a new container block for the first ST if there isn't one
00628  * yet. After setting the base, it performs data layout by assigning
00629  * the offset in the second block with proper alignment, additional
00630  * padding as passed in parameter, "pad",  and check if the current
00631  * block exceeds the limit, "maxsize", for this block.
00632  *
00633  * ====================================================================
00634  */
00635 
00636 static ST*
00637 ST_Block_Merge (ST *block, ST *sym, INT32 lpad, INT32 rpad, INT64 maxsize)
00638 {
00639   ST *base;
00640 
00641   Is_True(ST_class(block) == CLASS_BLOCK, ("block-merge not given a block"));
00642   Set_ST_base(sym, block);
00643   base = ST_base(sym);
00644   Allocate_Space(base, sym, lpad, rpad, maxsize);
00645 
00646   /* inherit the init attributes from the individual blocks */
00647   if (ST_is_initialized(sym) && !STB_section(block))
00648     Set_ST_is_initialized(block);
00649 
00650   return base;
00651 }
00652 
00653 
00654 static void
00655 Initialize_Frame_Segment (SF_SEGMENT seg, ST_SCLASS sclass, STACK_DIR dir)
00656 {
00657   if (SF_Block(seg) == NULL)
00658   {
00659         SF_Block(seg) = Create_Local_Block(dir, 
00660                 Save_Str2 (SF_Name(seg),"_StkSeg"));
00661         Set_ST_sclass (SF_Block(seg), sclass);
00662   }
00663 }
00664 
00665 static void
00666 Assign_Object_To_Frame_Segment ( ST *sym, SF_SEGMENT seg, INT64 offset)
00667 {
00668         if (Trace_Frame) {
00669                 fprintf ( TFile, 
00670                         "Assigning symbol %s to segment %s at offset %lld\n",
00671                         ST_name(sym), SF_Name(seg), offset);
00672         }
00673         Initialize_Frame_Segment (seg, ST_sclass(sym), INCREMENT);
00674         Set_ST_base(sym, SF_Block(seg));
00675         Set_ST_ofst(sym, offset);
00676 }
00677 
00678 /* ====================================================================
00679  *
00680  * Add_Object_To_Frame_Segment
00681  *
00682  * Add the given object to the given stack segment.
00683  *
00684  * ====================================================================
00685  */
00686 
00687 static void
00688 Add_Object_To_Frame_Segment ( ST *sym, SF_SEGMENT seg, BOOL allocate )
00689 {
00690   if ( Trace_Frame && !allocate )
00691   {
00692     fprintf ( TFile, "Adding symbol to %s segment -- %s \n",
00693               SF_Name(seg), ST_name(sym)? ST_name(sym) : "<null>");
00694   }
00695 
00696   Initialize_Frame_Segment (seg, ST_sclass(sym), INCREMENT);
00697 
00698   if (SF_Block(seg) == sym)
00699   {
00700    /*
00701     *  StkSeg will be in list of local symbols, don't merge with self
00702     */
00703     return;
00704   }
00705 
00706   if (allocate)
00707   {
00708     INT64 size;
00709     INT32 lpad, rpad;
00710     lpad = rpad = 0;
00711 
00712     switch (seg)
00713     {
00714     case SFSEG_ACTUAL:
00715     case SFSEG_UPFORMAL:
00716     case SFSEG_FORMAL:
00717       size = ST_size(sym);
00718 
00719       // struct params are left-justified.
00720       if (TY_kind(ST_type(sym)) == KIND_STRUCT)
00721       {
00722         rpad = ROUNDUP(size, MTYPE_RegisterSize(Spill_Int_Mtype)) - size;
00723       }
00724       else
00725       {
00726        /*
00727         * for parameters, we want to right-justify the objects;
00728         * so add in a pad amount to do the right-justifying.
00729         * container is the register size
00730         * Except float parms are left-justified!
00731         */
00732         if (size < MTYPE_RegisterSize(Spill_Int_Mtype)) {
00733           if (Target_Byte_Sex == LITTLE_ENDIAN ||
00734               MTYPE_is_float(TY_mtype(ST_type(sym)))) {
00735                 rpad = MTYPE_RegisterSize(Spill_Int_Mtype) - size;
00736           }
00737           else
00738                 lpad = MTYPE_RegisterSize(Spill_Int_Mtype) - size;
00739         }
00740       }
00741       break;
00742     }
00743     ST_Block_Merge (SF_Block(seg), sym, lpad, rpad, SF_Maxsize(seg));
00744 
00745     if (seg == SFSEG_FORMAL)
00746     {
00747       ST *formal = SF_Block(seg);
00748 
00749      /* formal overlaps both formal and upformal area,
00750       * so reset the blksizes of the segments.
00751       */
00752       if (STB_size(formal) > Formal_Save_Area_Size)
00753       {
00754         ST *upformal = SF_Block(SFSEG_UPFORMAL);
00755 
00756         if (Trace_Frame)
00757           fprintf(TFile, "<lay> split formal between segs\n");
00758 
00759         Initialize_Frame_Segment (SFSEG_UPFORMAL, ST_sclass(sym), INCREMENT);
00760         Set_STB_size(upformal, 
00761             STB_size(upformal) + STB_size(formal) - Formal_Save_Area_Size);
00762         Set_STB_size(formal, Formal_Save_Area_Size);
00763       }
00764     }
00765   }
00766   else
00767   {
00768     Set_ST_base(sym, SF_Block(seg));
00769   }
00770 }
00771 
00772 
00773 // Map PU idx to arg-area-size.
00774 // The arg-area-size is stored for efficiency, 
00775 // to avoid recomputing at each call.
00776 static UINT32 *arg_area_size_array;
00777 static INT max_arg_area_size_index = 0;
00778 
00779 // initialize and possibly realloc the arg-area-size array.
00780 static void
00781 Init_PU_arg_area_size_array (void)
00782 {
00783         INT num_pus = TY_Table_Size();
00784         if (arg_area_size_array == NULL) {
00785                 max_arg_area_size_index = num_pus;
00786                 arg_area_size_array = (UINT32*) Src_Alloc (
00787                         sizeof(UINT32) * (max_arg_area_size_index+1));
00788         }
00789         else if (num_pus >= max_arg_area_size_index) {
00790                 // realloc space
00791                 num_pus = MAX(num_pus, 2 * max_arg_area_size_index);
00792                 arg_area_size_array = TYPE_MEM_POOL_REALLOC_N (
00793                         UINT32, &MEM_src_pool, 
00794                         arg_area_size_array,
00795                         max_arg_area_size_index,
00796                         num_pus);
00797                 max_arg_area_size_index = num_pus;
00798         }
00799 }
00800 
00801 // Look for the arg-area-size corresponding to the pu.
00802 UINT32
00803 Get_PU_arg_area_size (TY_IDX pu)
00804 {
00805   Is_True(TY_kind(pu) == KIND_FUNCTION, ("Get_PU_arg_area_size of non-pu"));
00806   INT index = TY_id(pu);
00807   if (index >= max_arg_area_size_index) {
00808         // overflowed
00809         Init_PU_arg_area_size_array ();
00810   }
00811   Is_True(index < max_arg_area_size_index, ("Get_PU_arg_area_size still overflows?"));
00812   return arg_area_size_array[index];
00813 }
00814 
00815 void
00816 Set_PU_arg_area_size (TY_IDX pu, UINT32 size)
00817 {
00818   Is_True(TY_kind(pu) == KIND_FUNCTION, ("Set_PU_arg_area_size of non-pu"));
00819   INT index = TY_id(pu);
00820   if (index >= max_arg_area_size_index) {
00821         // overflowed
00822         Init_PU_arg_area_size_array ();
00823   }
00824   Is_True(index < max_arg_area_size_index, ("Set_PU_arg_area_size still overflows?"));
00825   arg_area_size_array[index] = size;
00826 }
00827 
00828 // return ST for __return_address if one exists
00829 
00830 struct is_return_address
00831 {
00832     BOOL operator () (UINT32, const ST *st) const {
00833         return (strcmp (ST_name (st), "__return_address") == 0);
00834     }
00835 }; 
00836 
00837 ST *
00838 Find_Special_Return_Address_Symbol (void)
00839 {
00840     ST_IDX st_idx = For_all_until (St_Table, CURRENT_SYMTAB,
00841                                    is_return_address ());
00842 
00843     if (st_idx == 0)
00844         return NULL;
00845     else
00846         return ST_ptr(st_idx);
00847 
00848 } // Find_Special_Return_Address_Symbol
00849 
00850 
00851 /* ====================================================================
00852  *
00853  * Get_Section_ST
00854  * 
00855  * Given a section kind, it finds its block symbol in Sections table.
00856  * It creates a new block symbol if the block symbol doesn't exist.
00857  *
00858  * ====================================================================
00859  */
00860 static ST*
00861 Get_Section_ST(SECTION_IDX sec, UINT align, ST_SCLASS sclass)
00862 {
00863   if (SEC_block(sec) == NULL) {
00864     ST *new_blk = New_ST_Block (Save_Str(SEC_name(sec)), 
00865         TRUE/*is_global*/, sclass, align, 0);
00866     Set_STB_section_idx(new_blk, sec);
00867     SEC_block(sec) = new_blk;
00868     Set_STB_section(new_blk);
00869     Set_STB_root_base(new_blk);
00870     if (SEC_is_gprel(sec)) {
00871         Set_STB_is_basereg(new_blk);
00872         Set_ST_gprel(new_blk);
00873     }
00874     if (SEC_is_merge(sec)) 
00875         Set_STB_merge(new_blk);
00876     if (SEC_is_exec(sec))
00877         Set_STB_exec(new_blk);
00878     if (SEC_is_nobits(sec)) 
00879         Set_STB_nobits(new_blk);
00880     Enter_ST(new_blk);
00881   }
00882   return SEC_block(sec);
00883 }
00884 
00885 // Either reuse or create a section block st that has same properties
00886 // as "sec" and "sclass" parameters, but with specified "name".
00887 // Need to possibly reuse for constructor/destructor case.
00888 static ST *
00889 Get_Section_ST_With_Given_Name (SECTION_IDX sec, ST_SCLASS sclass, STR_IDX name)
00890 {
00891         ST *newblk = NULL;
00892         ST *st;
00893         INT i;
00894         FOREACH_SYMBOL (GLOBAL_SYMTAB,st,i) {
00895                 if (ST_class(st) != CLASS_BLOCK) continue;
00896                 if (STB_section(st) && ST_name_idx(st) == name)
00897                 {
00898                         if (STB_section_idx(st) != sec) {
00899                                 ErrMsg (EC_LAY_section_name, ST_name(st), SEC_name(STB_section_idx(st)), SEC_name(sec));
00900                         }
00901                         newblk = st;
00902                         break;
00903                 }
00904         }
00905         if (newblk == NULL) {
00906                 ST *blk = Get_Section_ST(sec, 0, sclass);
00907                 newblk = Copy_ST_Block(blk);
00908                 Set_ST_name_idx(newblk, name);
00909         }
00910         return newblk;
00911 }
00912 
00913 static void
00914 Assign_ST_To_Named_Section (ST *st, STR_IDX name)
00915 {
00916         ST *newblk;
00917         if (ST_is_not_used(st))
00918                 return;
00919         if (ST_class(st) == CLASS_FUNC) {
00920                 if (ST_sclass(st) == SCLASS_EXTERN) {
00921                         // can just ignore section attribute on extern func
00922                         return;
00923                 }
00924                 // first assign to text like usual,
00925                 // then copy and change the name.
00926                 newblk = Get_Section_ST_With_Given_Name (_SEC_TEXT, 
00927                         ST_sclass(st), name);
00928                 Set_ST_base(st, newblk);
00929         }
00930         else if (ST_class(st) == CLASS_VAR) {
00931                 // assign object to section, 
00932                 // copy section block and rename,
00933                 // allocate object to new section block.
00934                 SECTION_IDX  sec;
00935                 switch (ST_sclass(st)) {
00936                 case SCLASS_DGLOBAL:
00937                 case SCLASS_FSTATIC:
00938                 case SCLASS_PSTATIC:
00939                         // must be initialized
00940                         if (ST_is_constant(st)) sec = _SEC_RDATA;
00941                         else sec = _SEC_DATA;
00942                         break;
00943                 case SCLASS_UGLOBAL:
00944                         sec = _SEC_BSS;
00945                         break;
00946                 default:
00947                         FmtAssert(FALSE,
00948                             ("unexpected sclass %d for section attribute on %s", 
00949                             ST_sclass(st), ST_name(st)));
00950                 }
00951                 newblk = Get_Section_ST_With_Given_Name (sec, 
00952                         SCLASS_UNKNOWN, name);
00953                 Set_ST_base(st, newblk);
00954                 // if object was supposed to go into bss,
00955                 // but was assigned to initialized data section,
00956                 // then change the symbol to be initialized to 0.
00957                 if (sec == _SEC_BSS && STB_section_idx(newblk) != _SEC_BSS) {
00958                         DevWarn("change bss symbol to be initialized to 0");
00959                         Set_ST_sclass(st, SCLASS_DGLOBAL);
00960                         Set_ST_is_initialized(st);
00961                         INITO_IDX ino = New_INITO(st);
00962                         INITV_IDX inv = New_INITV();
00963                         INITV_Init_Pad (inv, ST_size(st));
00964                         Set_INITO_val(ino, inv);
00965                 }
00966                 ST_Block_Merge (newblk, st, 0, 0, SEC_max_sec_size(sec));
00967         }
00968         else
00969                 FmtAssert(FALSE, ("unexpected section attribute"));
00970 }
00971 
00972 struct Assign_Section_Names 
00973 {
00974     inline void operator() (UINT32, ST_ATTR *st_attr) const {
00975         ST *st;
00976         STR_IDX name;
00977         if (ST_ATTR_kind (*st_attr) != ST_ATTR_SECTION_NAME)
00978             return;
00979         st = ST_ptr(ST_ATTR_st_idx(*st_attr));
00980         name = ST_ATTR_section_name(*st_attr);
00981         Assign_ST_To_Named_Section (st, name);
00982     }
00983 };
00984 
00985 // return section name for corresponding ST via st_attr table
00986 struct find_st_attr_secname {
00987         ST_IDX st;
00988         find_st_attr_secname (const ST *s) : st (ST_st_idx (s)) {}
00989 
00990         BOOL operator () (UINT, const ST_ATTR *st_attr) const {
00991             return (ST_ATTR_kind (*st_attr) == ST_ATTR_SECTION_NAME &&
00992                     ST_ATTR_st_idx (*st_attr) == st);
00993         }
00994 };
00995 
00996 STR_IDX
00997 Find_Section_Name_For_ST (const ST *st)
00998 {
00999     ST_IDX idx = ST_st_idx (st);
01000     ST_ATTR_IDX d;
01001 
01002     d = For_all_until (St_Attr_Table, ST_IDX_level (idx),
01003                           find_st_attr_secname(st));
01004     FmtAssert(d != 0, ("didn't find section name for ST %s", ST_name(st)));
01005     return ST_ATTR_section_name(St_Attr_Table(ST_IDX_level (idx), d));
01006 }
01007 
01008 
01009 /*
01010  * In -64 there are two areas for the parameters:
01011  * 1) any stack area needed for the overflow of parameters
01012  * is put above the FP, in the caller.
01013  * 2) for varargs we store all registers immediately after the FP in the callee.
01014  * We can also use the same space for homing the formals in -O0.
01015  * When RVI is done (-O2) we won't see the store into this space.
01016  * Also can check the st flag to see if the variable was used before allocating.
01017  * TODO:  don't allocate space if -O2.
01018  * In -32 there is only the arg build-area in the caller.
01019  * Calc_Actual_Area is used for area 1;
01020  * Min_Formal_Area_Bytes is used for area 2.
01021  * Calc_Actual_Area calculates the area, but does not allocate it.
01022  * Use Allocate_Formal_Offsets routine to allocate.
01023  */
01024 
01025 static INT32
01026 Calc_Actual_Area ( TY_IDX pu_type, WN *pu_tree )
01027 {
01028   INT size;
01029   PLOC ploc;
01030   // size = (pu_type != NULL ? Get_PU_arg_area_size(pu_type) : 0);
01031   size = 0; // The above method fails because PU typoes may be incomplete or shared
01032   if (size == 0) {
01033         INT i;
01034         INT num_parms;
01035         INT regsize = MTYPE_RegisterSize(Spill_Int_Mtype);
01036         INTRINSIC       id;
01037 
01038         switch (WN_operator(pu_tree)) {
01039         case OPR_PICCALL:
01040         case OPR_ICALL:
01041         case OPR_CALL:
01042                 num_parms = WN_num_actuals(pu_tree);
01043                 ploc = Setup_Output_Parameter_Locations(pu_type);
01044                 for (i = 0; i < num_parms; i++) {
01045                         ploc = Get_Output_Parameter_Location (TY_Of_Parameter(WN_actual(pu_tree,i)));
01046                 }
01047                 size = PLOC_total_size(ploc);
01048                 break;
01049         case OPR_INTRINSIC_OP:
01050         case OPR_INTRINSIC_CALL:
01051                 id = (INTRINSIC) WN_intrinsic(pu_tree);
01052 
01053                 switch(id) {
01054                 case INTRN_CONCATEXPR:
01055                         size = 5 * regsize;
01056                         break;
01057                 default:
01058                         num_parms = WN_num_actuals(pu_tree);
01059                        /*
01060                         *  CQ return via hidden argument
01061                         *  Assumption:  CQ Intrinsics always have CQ parameter
01062                         *  after the hidden argument, so pad the space.
01063                         */
01064                         if (MTYPE_id(WN_rtype(pu_tree)) == MTYPE_CQ)
01065                                 size = ROUNDUP(regsize, MTYPE_align_best(MTYPE_CQ));
01066                         if (INTRN_by_value(id) == TRUE)
01067                         {       
01068                                 for(i= 0; i<num_parms; i++) {
01069                                         size += ROUNDUP(TY_size(TY_Of_Parameter(WN_actual(pu_tree,i))), regsize);
01070                                 }
01071                         }
01072                         else    /* by reference */
01073                         {
01074                                 size += num_parms * regsize;
01075                         }
01076                         break;
01077                 }
01078                 break;
01079         default:
01080                 FmtAssert(FALSE, ("Calc_Actual_Area: unexpected opcode"));
01081         }
01082         /* if not varargs and have prototype, then store size in TY;
01083          * else will have to recalculate it each time. */
01084         /* Note:  the TY_parms may be incomplete due to implicit arguments */
01085         if (pu_type != (TY_IDX) NULL && TY_has_prototype (pu_type) &&
01086             !TY_is_varargs (pu_type)) {
01087                 Set_PU_arg_area_size(pu_type, size);
01088         }
01089   }
01090   size -= Formal_Save_Area_Size;
01091   if (size < 0) 
01092     size = 0;
01093   else if (Trace_Frame)
01094         fprintf(TFile, "<lay> actual_arg_area = %d\n", size);
01095 
01096   return size;
01097 }
01098 
01099 /*
01100  * Verify that stack space needed for actuals doesn't overflow
01101  * what we initially reserved.
01102  */
01103 extern void
01104 Check_Actual_Stack_Size (WN *call_tree)
01105 {
01106   INT32 actual_size;
01107   switch (WN_operator(call_tree)) {
01108   case OPR_CALL:
01109   case OPR_PICCALL:
01110     actual_size = Calc_Actual_Area ( ST_pu_type(WN_st(call_tree)), call_tree);
01111     break;
01112   case OPR_ICALL:
01113     actual_size = Calc_Actual_Area ( WN_ty(call_tree), call_tree);
01114     break;
01115   default:
01116     FmtAssert(FALSE, ("unexpected opcode in Check_Actual_Stack_Size"));
01117   }
01118   FmtAssert(actual_size <= Current_PU_Actual_Size,
01119         ("size of actual area increased from %d to %d",
01120         Current_PU_Actual_Size, actual_size));
01121 }
01122 
01123 /* ====================================================================
01124  *
01125  * Max_Arg_Area_Bytes
01126  *
01127  * This functions finds the largest amount of stack space is required
01128  * for passing parameter to all functions within this PU.  It goes
01129  * through the WHIRL tree to find all function calls in this PU.
01130  * For each call, use PLOCs to calculate the number of bytes required
01131  * for that call.
01132  *
01133  * ====================================================================
01134  */
01135 static INT32
01136 Max_Arg_Area_Bytes(WN *node)
01137 {
01138   OPCODE opcode;
01139   INT32 maxsize = 0;
01140 
01141   opcode = WN_opcode (node);
01142 
01143   switch (OPCODE_operator(opcode)) {
01144   case OPR_CALL:
01145   case OPR_PICCALL:
01146     maxsize = Calc_Actual_Area ( ST_pu_type (WN_st (node)), node);
01147     Frame_Has_Calls = TRUE;
01148     break;
01149   case OPR_ICALL:
01150     maxsize = Calc_Actual_Area ( WN_ty(node), node );
01151     Frame_Has_Calls = TRUE;
01152     break;
01153   case OPR_INTRINSIC_OP:
01154   case OPR_INTRINSIC_CALL:
01155     maxsize = Calc_Actual_Area ( (TY_IDX) NULL, node );
01156     Frame_Has_Calls = TRUE;
01157     break;
01158 #ifdef TARG_IA32
01159   case OPR_IO:
01160     maxsize = 16;
01161     break;
01162 #endif
01163   }
01164 
01165   if (opcode == OPC_BLOCK) {
01166     WN *wn;
01167     for ( wn = WN_first(node); wn != NULL; wn = WN_next(wn) ) {
01168       INT32 wn_size;
01169       if (((WN_opcode(wn) == OPC_PRAGMA) || (WN_opcode(wn) == OPC_XPRAGMA)) &&
01170           (WN_pragma(wn) == WN_PRAGMA_COPYIN)) {
01171         INT32 copyincount = 3;
01172         WN *next;
01173         while ((next = WN_next(wn)) &&
01174                ((WN_opcode(next) == OPC_PRAGMA) ||
01175                 (WN_opcode(next) == OPC_XPRAGMA)) &&
01176                (WN_pragma(next) == WN_PRAGMA_COPYIN)) {
01177           copyincount += 2;
01178           wn = next;
01179         }
01180         wn_size = copyincount * MTYPE_RegisterSize(Spill_Int_Mtype);
01181         maxsize = MAX(maxsize, wn_size);
01182         Frame_Has_Calls = TRUE;
01183       } else {
01184         wn_size = Max_Arg_Area_Bytes (wn);
01185         maxsize = MAX(maxsize, wn_size);
01186       }
01187     }
01188   }
01189   else if (!OPCODE_is_leaf(opcode)) {
01190     INT i;
01191 
01192     for (i = 0; i < WN_kid_count(node); i++) {
01193       if (WN_kid(node, i) != NULL) {
01194         INT32 wn_size = Max_Arg_Area_Bytes (WN_kid(node, i));
01195         maxsize = MAX(maxsize, wn_size);
01196       }
01197     }
01198   }
01199 
01200   return maxsize;
01201 }
01202 
01203 /* ====================================================================
01204  *
01205  * Reset_UPFORMAL_Segment(ST *s)
01206  *
01207  * Reset the UPFORMAL areas offset and size back to zero
01208  * This is to simulate the UPFORMAL offset to create an ST * to
01209  * store to s during ALTENTRY formals
01210  *
01211  * ====================================================================
01212  */
01213 void
01214 Reset_UPFORMAL_Segment(void)
01215 {
01216   ST *block;
01217 
01218   if (block = SF_Block(SFSEG_UPFORMAL))
01219   {
01220     Set_ST_ofst(block, 0);
01221     Set_STB_size(block, 0);
01222   }
01223   else
01224   {
01225     Initialize_Frame_Segment (SFSEG_UPFORMAL, SCLASS_AUTO, INCREMENT);
01226   }
01227 }
01228 
01229 /*
01230  *  Allocate each formal parameter on the stack,
01231  * 
01232  */
01233 static void
01234 Allocate_Entry_Formal(ST *formal, BOOL on_stack, BOOL in_formal_reg)
01235 {
01236   if (Has_No_Base_Block(formal))
01237   {
01238    /*
01239     *  Formals that are vms static have entry points that use this address.
01240     *  Master kludge around this by allocating this variable to a static.
01241     */
01242     if (PU_has_altentry(Get_Current_PU()) && ST_declared_static(formal))
01243     {
01244         SECTION_IDX sec;
01245         // formal will not be on stack
01246         Set_ST_sclass(formal, SCLASS_PSTATIC);
01247         Clear_ST_is_value_parm(formal);
01248         sec = Shorten_Section(formal, _SEC_BSS);
01249         Allocate_Object_To_Section(formal, sec, Adjusted_Alignment(formal));
01250     }
01251     else if (in_formal_reg)
01252     {
01253       /* parameter is in register, so put in FORMAL area */
01254       Add_Object_To_Frame_Segment ( formal, SFSEG_FORMAL, TRUE );
01255     }
01256     else if (on_stack)
01257     {
01258       /* parameter is on stack, so put in either UPFORMAL or FTEMP area */
01259       if (PU_has_altentry(Get_Current_PU())) {
01260         Add_Object_To_Frame_Segment ( formal, SFSEG_FTEMP, TRUE );
01261       }
01262       else {
01263         Add_Object_To_Frame_Segment ( formal, SFSEG_UPFORMAL, TRUE );
01264       }
01265     }
01266     else 
01267     {
01268         // formal not in usual parameter reg and not on stack
01269         // (e.g. passing addr in return reg), so store in FTEMP.
01270         Add_Object_To_Frame_Segment ( formal, SFSEG_FTEMP, TRUE );
01271     }
01272   }
01273 }
01274 
01275 
01276 
01277 
01278 /* ====================================================================
01279  *
01280  * ST *formal_sym_type(WN *formal)
01281  *
01282  *  create a "base" ST for the formal ref that represents the
01283  *  address of the formal
01284  *
01285  * ====================================================================
01286  */
01287 static TY_IDX Formal_ST_type(ST *sym)
01288 {
01289   TY_IDX type= ST_type(sym);
01290 
01291   if (ST_sclass(sym) == SCLASS_FORMAL_REF)
01292   {
01293     return Make_Pointer_Type(type);
01294   }
01295   return type;
01296 }
01297 
01298 /* indexed list of vararg symbols */
01299 # if MAX_NUMBER_OF_REGISTER_PARAMETERS > 0
01300     ST *vararg_symbols[MAX_NUMBER_OF_REGISTER_PARAMETERS];      
01301 # else
01302     // zero length arrays not allowed.
01303 #   define vararg_symbols ((ST * *)0)  // Not accessed
01304 # endif
01305 
01306 /* this is just so we don't have symbols dangling around in next PU */
01307 static void
01308 Clear_Vararg_Symbols (void)
01309 {
01310         INT i;
01311         for (i = 0; i < MAX_NUMBER_OF_REGISTER_PARAMETERS; i++) {
01312                 vararg_symbols[i] = NULL;
01313         }
01314 }
01315 
01316 /* get vararg symbol that corresponds to ploc value */
01317 extern ST*
01318 Get_Vararg_Symbol (PLOC ploc)
01319 {
01320         Is_True(PLOC_reg(ploc) < 
01321                 First_Int_Preg_Param_Offset+MAX_NUMBER_OF_REGISTER_PARAMETERS,
01322                 ("Get_Vararg_Symbol:  ploc %d out of range", PLOC_reg(ploc)));
01323         return vararg_symbols[PLOC_reg(ploc)-First_Int_Preg_Param_Offset];
01324 }
01325 
01326 /*
01327  * Search for all formals, including alt-entry formals,
01328  * and allocate them.  This way regions can always access the formals.
01329  */
01330 static void
01331 Allocate_All_Formals (WN *pu)
01332 {
01333   INT i;
01334   PLOC ploc;
01335   ST *sym;
01336   BOOL varargs;
01337   TY_IDX pu_type = ST_pu_type (WN_st (pu));
01338 
01339   Init_ST_formal_info_for_PU (WN_num_formals(pu));
01340   varargs = TY_is_varargs (pu_type);
01341   ploc = Setup_Input_Parameter_Locations(pu_type);
01342 
01343  /*
01344   *  for varargs functions do not put the scalar formal base in a preg
01345   */
01346   for (i = 0; i < WN_num_formals(pu); i++)
01347   {
01348     sym = WN_st(WN_formal(pu, i));
01349  
01350     ploc = Get_Input_Parameter_Location( Formal_ST_type(sym));
01351 
01352     sym =  Formal_Sym(sym, PLOC_on_stack(ploc) || varargs);
01353 
01354     Allocate_Entry_Formal (sym, PLOC_on_stack(ploc), Is_Formal_Preg(PLOC_reg(ploc)));
01355   }
01356 
01357   if ( PU_has_altentry(Get_Current_PU()))
01358   {
01359     WN *tree;
01360 
01361     for ( tree = WN_first(WN_func_body(pu)); tree != NULL; tree = WN_next(tree))
01362     {
01363       if (WN_opcode(tree) == OPC_ALTENTRY)
01364       {
01365         Reset_UPFORMAL_Segment();
01366         ploc = Setup_Input_Parameter_Locations(ST_pu_type(WN_st(tree)));
01367         for (i = 0; i < WN_kid_count(tree); i++)
01368         {
01369           sym = WN_st(WN_formal(tree, i));
01370 
01371           ploc = Get_Input_Parameter_Location ( Formal_ST_type(sym));
01372 
01373           sym =  Formal_Sym(sym, PLOC_on_stack(ploc) || varargs);
01374 
01375           Allocate_Entry_Formal (sym, TRUE, Is_Formal_Preg(PLOC_reg(ploc)));
01376         }
01377       }
01378     }
01379   }
01380 
01381   if (varargs) {
01382         /*
01383          *  For varargs, the func-entry just has the list of fixed
01384          *  parameters, so also have to allocate the vararg registers.
01385          *  The lowerer needs to find these symbols, so put them in list
01386          *  that get_vararg_symbol can use.
01387          */
01388 
01389         ST *last_fixed_symbol = sym;
01390         PLOC last_fixed_ploc = ploc;
01391         /* vararg registers must be integer registers */
01392         TY_IDX vararg_type = Copy_TY(ST_type(Int_Preg));
01393         /* set flag for alias analyzer */
01394         Set_TY_no_ansi_alias (vararg_type);
01395 
01396         if (PLOC_is_nonempty(ploc) && !PLOC_on_stack(ploc)) {
01397                 /* don't do if already reached stack params */
01398                 ploc = Get_Vararg_Input_Parameter_Location (ploc);
01399         }
01400 
01401         while (!PLOC_on_stack(ploc)) {
01402                 /*
01403                  *  create a temporary for the vararg formal
01404                  */
01405                 sym = Gen_Temp_Symbol (vararg_type, "vararg");
01406                 Set_ST_sclass (sym, SCLASS_FORMAL);
01407                 Set_ST_is_value_parm( sym);
01408                 Set_ST_addr_saved(sym);
01409                 vararg_symbols[PLOC_reg(ploc)-First_Int_Preg_Param_Offset] = sym;
01410                 Allocate_Entry_Formal(sym, PLOC_on_stack(ploc), Is_Formal_Preg(PLOC_reg(ploc)));
01411                 /*
01412                  * The optimizer sees these varargs references as *ap+n,
01413                  * i.e. as an offset past the last fixed arg, so to help
01414                  * aliasing work properly we set the base of these symbols
01415                  * to the last fixed symbol rather than to the formal_stkseg.
01416                  */
01417                 Set_ST_base(sym, last_fixed_symbol);
01418                 Set_ST_ofst(sym, PLOC_offset(ploc) - PLOC_offset(last_fixed_ploc));
01419 
01420                 ploc = Get_Vararg_Input_Parameter_Location (ploc);
01421         }
01422   }
01423 }
01424 
01425 /* For stack parameters in altentry functions, 
01426  * we need an ST that corresponds to the upformal (fp+0,fp+8,etc) area.
01427  * In this case we copy the formal from the upformal to the ltemp area,
01428  * because the upformal area will not be the same for all entries.
01429  * The lowerer will generate the whirl to copy from upformal to ltemp.
01430  * We use the ploc offset so not dependent on calling this in order
01431  * (with formal-ref, we process these params in separate passes).
01432  * Note that the upformal area doesn't need to be allocated, just assigned.
01433  */
01434 extern ST*
01435 Get_Altentry_UpFormal_Symbol (ST *formal, PLOC ploc) 
01436 {
01437   ST* upformal = Copy_ST(formal);
01438   Set_ST_name(upformal, Save_Str2(ST_name(upformal), ".upformal."));
01439   Set_ST_sclass(upformal, SCLASS_FORMAL);       // this is a stack location
01440   Clear_ST_gprel(upformal);
01441 
01442   INT offset = PLOC_offset(ploc) - Formal_Save_Area_Size;
01443   if (PUSH_FRAME_POINTER_ON_STACK) {
01444     offset += MTYPE_byte_size(Pointer_Mtype);
01445   }
01446   if (PUSH_RETURN_ADDRESS_ON_STACK) {
01447     offset += MTYPE_byte_size(Pointer_Mtype);
01448   }
01449 
01450   Assign_Object_To_Frame_Segment (upformal, SFSEG_UPFORMAL, offset);
01451   return upformal;
01452 }
01453 
01454 /* Calculate size needed for formals and upformals */
01455 /* TODO:  account for FTEMP area needed for alt-entry */
01456 static void 
01457 Calc_Formal_Area (WN *pu_tree, INT32 *formal_size, INT32 *upformal_size)
01458 {
01459   INT maxsize;
01460   ST *st = WN_st (pu_tree);
01461   TY_IDX pu_ty = ST_pu_type (st);
01462   FmtAssert(WN_opcode(pu_tree) == OPC_FUNC_ENTRY, ("not a func-entry"));
01463 
01464   if (TY_is_varargs (pu_ty)) {
01465         *formal_size = Formal_Save_Area_Size;
01466         *upformal_size = 0;
01467         /* don't set PU_arg_area_size, cause changes with each call */
01468         return;
01469   } 
01470   else if (Get_PU_arg_area_size(pu_ty) > 0) {
01471         ;       /* size is known */
01472   } 
01473   else {
01474         PLOC ploc;
01475         INT i;
01476         ploc = Setup_Input_Parameter_Locations(pu_ty);
01477         for (i = 0; i < WN_num_formals(pu_tree); i++) {
01478                 ploc = Get_Input_Parameter_Location (TY_Of_Parameter(WN_formal(pu_tree,i)));
01479         }
01480         Set_PU_arg_area_size(pu_ty, PLOC_total_size(ploc));
01481   }
01482   maxsize = Get_PU_arg_area_size(pu_ty);
01483   if ( PU_has_altentry(Get_Current_PU())) {
01484         /* need to reserve upformal space for maximum of alt-entries */
01485         /* Note that formal space may be smaller than save-area-size
01486          * yet still have upformal space, because altentry formals are put
01487          * in ftemp area. */
01488         WN *tree = WN_first(WN_func_body(pu_tree));
01489         for (; tree != NULL; tree = WN_next(tree)) {
01490             if (WN_opcode(tree) == OPC_ALTENTRY) {
01491                 PLOC ploc;
01492                 INT i;
01493                 ploc = Setup_Input_Parameter_Locations(ST_pu_type(WN_st(tree)));
01494                 for (i = 0; i < WN_kid_count(tree); i++) {
01495                         ploc = Get_Input_Parameter_Location (TY_Of_Parameter(WN_formal(tree,i)));
01496                 }
01497                 maxsize = MAX(maxsize, PLOC_total_size(ploc));
01498             }
01499         }
01500   }
01501   /* formal area cannot be larger than save-area size */
01502   *formal_size = MIN (Get_PU_arg_area_size(pu_ty), Formal_Save_Area_Size);
01503   /* upformal size is 0 or size > save-area size */
01504   *upformal_size = MAX (maxsize - Formal_Save_Area_Size, 0);
01505 }
01506 
01507 /* estimate stack space needed for local variables */
01508 
01509 static inline INT64
01510 Calc_Local_Area (void)
01511 {
01512     INT64 local_size = 0;
01513     ST_ITER first = Scope_tab[CURRENT_SYMTAB].st_tab->begin ();
01514     const ST_ITER last = Scope_tab[CURRENT_SYMTAB].st_tab->end ();
01515 
01516     while (++first != last) {
01517         ST &st = *first;
01518         switch (ST_sclass (st)) {
01519 
01520         case SCLASS_AUTO:
01521             /* ignore symbols that already been merged into a block;
01522              * only count the root block. */
01523             if (ST_base_idx (st) != ST_st_idx (st))
01524                 break;
01525             if (Trace_Frame)
01526                 fprintf (TFile, "local %s has size %lld\n", ST_name(&st),
01527                          ST_size(&st)); 
01528             local_size += ST_size(&st);
01529             break;
01530             
01531         case SCLASS_DGLOBAL:
01532         case SCLASS_COMMON:
01533             /*  the compiler has promised the Adjusted_Alignment to earlier phases
01534              */
01535             if (ST_type (st) != 0) {
01536                 Set_ST_type (st, Make_Align_Type (ST_type (st),
01537                                                   Adjusted_Alignment (&st)));
01538             }
01539             break;
01540         }
01541     }
01542 
01543     return local_size;
01544 }
01545 
01546 
01547 
01548 /*
01549  *  Clear the segment descriptors: 
01550  */
01551 static void 
01552 Init_Segment_Descriptors(void)
01553 {
01554   SF_SEGMENT s;
01555 
01556   for (s = (SF_SEGMENT) (SFSEG_UNKNOWN+1); s <= SFSEG_LAST; s = (SF_SEGMENT) (s + 1) )
01557   {
01558    /* use positive direction by default,
01559     * change later when decide stack model. 
01560     */
01561     SF_Block(s) = Create_Local_Block(INCREMENT,
01562                                      Save_Str2 (SF_Name(s),"_StkSeg"));
01563     SF_Maxsize(s) = MAX_SFSEG_BYTES;
01564   }
01565   // mark formal block as unused until someone references it
01566   Set_ST_is_not_used(SF_Block(SFSEG_FORMAL));
01567 }
01568 
01569 /* get segment size from either the block size or maxsize */
01570 #define SEG_SIZE(s)     \
01571         (SF_Block(s) ? \
01572          STB_size(SF_Block(s)) : \
01573         ((SF_Maxsize(s) == MAX_SFSEG_BYTES) ? 0 : SF_Maxsize(s) ) )
01574 
01575 
01576 static void
01577 Init_Formal_Segments (INT32 formal_size, INT32 upformal_size)
01578 {
01579   SF_Maxsize ( SFSEG_UPFORMAL ) = ROUNDUP(upformal_size, stack_align);
01580   SF_Maxsize ( SFSEG_FORMAL ) = ROUNDUP(formal_size, stack_align);
01581 }
01582 
01583 /* ====================================================================
01584  *
01585  * Init_Frame_For_PU
01586  *
01587  * Initialize the SF segments for a new PU.
01588  *
01589  * ====================================================================
01590  */
01591 
01592 static void
01593 Init_Frame_For_PU (INT32 actual_size)
01594 {
01595   /* Alloca depends on the actual_size that we first guessed,
01596    * because the alloca reserves actual_size bytes below it and
01597    * then points above the actual_area.
01598    * So never change actual_size, even if turns out to be smaller.
01599    */
01600   SF_Maxsize ( SFSEG_ACTUAL ) = ROUNDUP(actual_size, stack_align);
01601 
01602   /* temps can use max frame size minus the fixed space required for
01603    * formals and actuals. */
01604   SF_Maxsize ( SFSEG_FTEMP ) = 
01605         MAX_FRAME_OFFSET - SEG_SIZE(SFSEG_FORMAL) - SEG_SIZE(SFSEG_ACTUAL);
01606 
01607   /* Initialize the size of a large object.  Note that if we can
01608    * determine in advance the size of the frame per the FE, and it is
01609    * small, we should use infinity instead of the default:
01610    */
01611   Large_Object_Bytes = DEFAULT_LARGE_OBJECT_BYTES;
01612 }
01613 
01614 /* ====================================================================
01615  *
01616  * Bind_Stack_Frame
01617  *
01618  * It binds the stack segments according to the stack model.
01619  *
01620  * ====================================================================
01621  */
01622 
01623 static void
01624 Bind_Stack_Frame ( ST *SP_baseST, ST *FP_baseST )
01625 {
01626   Set_Direction (Get_Direction(SP_baseST), SF_Block(SFSEG_ACTUAL));
01627   Set_Direction (Get_Direction(SP_baseST), SF_Block(SFSEG_UPFORMAL));
01628   /* within formal seg, object grow upward, toward FP */
01629   Set_Direction (Get_Direction(SP_baseST), SF_Block(SFSEG_FORMAL));
01630 
01631   switch (Current_PU_Stack_Model) {
01632   case SMODEL_SMALL:
01633   case SMODEL_LARGE:
01634     Set_Direction (Get_Direction(SP_baseST), SF_Block(SFSEG_FTEMP));
01635     break;
01636   case SMODEL_DYNAMIC:
01637     Set_Direction (Get_Direction(FP_baseST), SF_Block(SFSEG_FTEMP));
01638     break;
01639   default:
01640     FmtAssert ( TRUE,
01641                ("UNDEFINED Stack Model in Bind_Stack_Frame" ));
01642   }
01643 }
01644 
01645 #define MERGE_SEGMENT(base, seg, mxfrm) \
01646   ST_Block_Merge (base, SF_Block(seg), 0, 0, mxfrm)
01647 
01648 /* ====================================================================
01649  *
01650  * Merge_Fixed_Stack_Frame
01651  *
01652  * At this point all but the TEMP segment are allocated, so merge the
01653  * other segments so that the offsets are exact.
01654  *
01655  * ====================================================================
01656  */
01657 static void
01658 Merge_Fixed_Stack_Frame(ST *SP_baseST, ST *FP_baseST)
01659 {
01660   INT32 orig_formal_size;
01661   FmtAssert(SP_baseST != NULL && FP_baseST != NULL,
01662             ("Initialize_Stack_Frame: Invalid parameters"));
01663 
01664   Set_STB_size(SP_baseST,0);
01665   Set_STB_size(FP_baseST,0);
01666 
01667   /* the actual area doesn't have allocated objects, just a size */
01668   Set_STB_size(SF_Block(SFSEG_ACTUAL), SF_Maxsize(SFSEG_ACTUAL));
01669   /* varargs formals are not allocated yet, so temporarily fake size
01670    * and then reset it. */
01671   BOOL pu_is_varargs = TY_is_varargs (ST_pu_type (Get_Current_PU_ST()));
01672   if (pu_is_varargs) {
01673         orig_formal_size = STB_size(SF_Block(SFSEG_FORMAL));
01674         Set_STB_size(SF_Block(SFSEG_FORMAL), SF_Maxsize(SFSEG_FORMAL));
01675   }
01676 
01677   switch ( Current_PU_Stack_Model) {
01678   case SMODEL_SMALL:
01679     MERGE_SEGMENT(SP_baseST, SFSEG_ACTUAL, Max_Small_Frame_Offset);
01680     /* only altentries may use the temp area, so merge it now */
01681     MERGE_SEGMENT(SP_baseST, SFSEG_FTEMP, Max_Small_Frame_Offset);
01682 
01683     // don't know offset of formals and upformals,
01684     // so leave alone until finalized.
01685     break;
01686 
01687   case SMODEL_LARGE:
01688     MERGE_SEGMENT(SP_baseST, SFSEG_ACTUAL, MAX_LARGE_FRAME_OFFSET);
01689     MERGE_SEGMENT(SP_baseST, SFSEG_FTEMP, MAX_LARGE_FRAME_OFFSET);
01690     Set_ST_base(SF_Block(SFSEG_UPFORMAL), FP_baseST);
01691     Set_ST_ofst (SF_Block(SFSEG_UPFORMAL), Stack_Offset_Adjustment);
01692     MERGE_SEGMENT(FP_baseST, SFSEG_FORMAL, MAX_LARGE_FRAME_OFFSET);
01693     break;
01694 
01695   case SMODEL_DYNAMIC:
01696     MERGE_SEGMENT(SP_baseST, SFSEG_ACTUAL, MAX_LARGE_FRAME_OFFSET);
01697     Set_ST_base(SF_Block(SFSEG_UPFORMAL), FP_baseST);
01698     Set_ST_ofst (SF_Block(SFSEG_UPFORMAL), Stack_Offset_Adjustment);
01699 
01700     MERGE_SEGMENT(FP_baseST, SFSEG_FORMAL, MAX_LARGE_FRAME_OFFSET);
01701     MERGE_SEGMENT(FP_baseST, SFSEG_FTEMP, MAX_LARGE_FRAME_OFFSET);
01702     break;
01703 
01704   default:
01705     FmtAssert ( TRUE,
01706                ("UNDEFINED Stack Model in Initialize_Stack_Frame" ));
01707   }
01708   if (pu_is_varargs) {
01709         /* reset size */
01710         Set_STB_size(SF_Block(SFSEG_FORMAL), orig_formal_size);
01711   }
01712 }
01713 
01714 static STACK_MODEL
01715 Choose_Stack_Model (INT64 frame_size)
01716 {
01717   if (PU_has_alloca(Get_Current_PU())) {
01718     return SMODEL_DYNAMIC;
01719   } 
01720   else if (PU_has_nested(Get_Current_PU())) {
01721     return SMODEL_DYNAMIC;
01722   } 
01723   else if (Force_Large_Stack_Model) {
01724     return SMODEL_LARGE;
01725   }
01726   else if (frame_size < Max_Small_Frame_Offset) {
01727     return SMODEL_SMALL;
01728   } 
01729   else if (frame_size < MAX_LARGE_FRAME_OFFSET) {
01730     return SMODEL_LARGE;
01731   } 
01732   else {
01733     FmtAssert ( FALSE, ("64-bit stack frame NYI"));
01734     return SMODEL_UNDEF;
01735   }
01736 }
01737 
01738 /* create and allocate special space for a spill offset that is guaranteed 
01739  * to be within 16-bits of the SP or FP. */
01740 static void
01741 Allocate_Local_Spill_Sym (void)
01742 {
01743   if (Current_PU_Stack_Model == SMODEL_SMALL) {
01744         /* not needed if frame is small anyways */
01745         Local_Spill_Sym = NULL;
01746   }
01747   else {
01748         Local_Spill_Sym = Gen_Temp_Symbol (Spill_Int_Type, "reserved_spill");
01749         Allocate_Temp_To_Memory (Local_Spill_Sym);
01750   }
01751 }
01752 
01753 extern void
01754 Initialize_Stack_Frame (WN *PU_tree)
01755 {
01756   INT32 actual_size;
01757   INT32 formal_size;
01758   INT32 upformal_size;
01759   INT64 frame_size = 0;
01760 
01761   Set_Error_Phase("Data Layout");
01762   Trace_Frame = Get_Trace(TP_DATALAYOUT, 1);
01763   FmtAssert(WN_opcode(PU_tree) == OPC_FUNC_ENTRY,
01764             ("Determine_Stack_Model: The PU_tree node does not point to a OPC_FUNC_ENTRY"));
01765 
01766   if (ST_asm_function_st(*WN_st(PU_tree))) {
01767     // Do nothing for functions that merely wrap up file-scope
01768     // assembly code.
01769     return;
01770   }
01771 
01772   if (Trace_Frame)
01773         fprintf(TFile, "<lay> Determine_Stack_Model for %s\n", 
01774                 ST_name(WN_st(PU_tree)));
01775 
01776   if (PU_has_return_address(Get_Current_PU()) 
01777         && MTYPE_byte_size(Pointer_Mtype) < MTYPE_byte_size(Spill_Int_Mtype) )
01778   {
01779         /* In n32 the __return_address is only 4 bytes (pointer),
01780          * but need to force allocation of 8 bytes, with return_address
01781          * pointing to last 4 bytes, so can do ld/sd
01782          * and make kernel and dbx happy. */
01783         // set base of __return_address to 8-byte dummy symbol,
01784         // offset at 4 of the base.
01785         ST *ra_sym = Find_Special_Return_Address_Symbol();
01786         ST *st_base = New_ST ();
01787         ST_Init (st_base, Save_Str("return_address_base"), 
01788                 ST_class(ra_sym), ST_sclass(ra_sym), ST_export(ra_sym), 
01789                 MTYPE_To_TY(Spill_Int_Mtype) );
01790         Set_ST_base (ra_sym, st_base);
01791         Set_ST_ofst (ra_sym, MTYPE_byte_size(Spill_Int_Mtype) - MTYPE_byte_size(Pointer_Mtype));
01792   }
01793 
01794   Init_Segment_Descriptors();
01795   Init_PU_arg_area_size_array();
01796 
01797   Calc_Formal_Area (PU_tree, &formal_size, &upformal_size);
01798   /* also can be ftemp size, but probably small */
01799 
01800   Frame_Has_Calls = FALSE;
01801   actual_size = Max_Arg_Area_Bytes(PU_tree);
01802   // mp_io and alloca rely on the actual size being register-sized aligned
01803   actual_size = ROUNDUP(actual_size, MTYPE_byte_size(Spill_Int_Mtype));
01804   Current_PU_Actual_Size = actual_size;
01805 
01806   frame_size = Calc_Local_Area ();
01807 
01808   if (PUSH_FRAME_POINTER_ON_STACK) {
01809     // Reserve the space on stack for the old frame pointer (ia32)
01810     ST* old_fp = New_ST ();
01811     ST_Init (old_fp, 
01812              Save_Str("old_frame_pointer"),
01813              CLASS_VAR,
01814              SCLASS_AUTO,
01815              EXPORT_LOCAL,
01816              MTYPE_To_TY(Pointer_Mtype));
01817     Add_Object_To_Frame_Segment (old_fp, SFSEG_UPFORMAL, TRUE);
01818     upformal_size += MTYPE_byte_size(Pointer_Mtype);
01819   }
01820 
01821   if (PUSH_RETURN_ADDRESS_ON_STACK) {
01822     // Reserve the space on stack for the return address (ia32)
01823     ST* ra_st = New_ST ();
01824     ST_Init (ra_st, 
01825              Save_Str("return_address"),
01826              CLASS_VAR,
01827              SCLASS_AUTO,
01828              EXPORT_LOCAL,
01829              MTYPE_To_TY(Pointer_Mtype));
01830     Add_Object_To_Frame_Segment (ra_st, SFSEG_UPFORMAL, TRUE);
01831     upformal_size += MTYPE_byte_size(Pointer_Mtype);
01832   }
01833 
01834   if (Trace_Frame) {
01835         fprintf(TFile, "<lay> locals' size = %lld\n", frame_size);
01836         fprintf(TFile, "<lay> upformal size = %d, formal size = %d\n", 
01837                 upformal_size, formal_size);
01838         fprintf(TFile, "<lay> actual size = %d\n", actual_size);
01839   }
01840   frame_size += formal_size + actual_size;
01841 
01842   /* add the 4K area for temporaries */
01843   frame_size += DEFAULT_TEMP_SPACE_BYTES;
01844 
01845   /* add upformal_size in case upformal is so large it needs
01846    * to be accessed via $fp. */
01847   frame_size += upformal_size;
01848 
01849   Current_PU_Stack_Model = Choose_Stack_Model(frame_size);
01850   if (Trace_Frame) {
01851         fprintf(TFile, "<lay> guess frame_size = %lld\n", frame_size);
01852         fprintf(TFile, "<lay> stack model = %d\n", Current_PU_Stack_Model);
01853   }
01854 
01855   /* stack grows down; sp objects grow up from sp; fp objects down from fp */
01856   stack_direction = DECREMENT;
01857   SP_Sym = Create_Base_Reg (".SP", INCREMENT);
01858   FP_Sym = Create_Base_Reg (".FP", DECREMENT);
01859 
01860   /* make sure all formals are allocated before we split into regions */
01861   Allocate_All_Formals (PU_tree);
01862   Init_Formal_Segments (formal_size, upformal_size);
01863 }
01864 
01865 // this is called after lowering, when have more accurate view of code.
01866 extern void
01867 Calculate_Stack_Frame_Sizes (WN *PU_tree)
01868 {
01869   if (ST_asm_function_st(*Get_Current_PU_ST())) {
01870     // Do nothing for functions that merely wrap up file-scope
01871     // assembly code.
01872     return;
01873   }
01874 
01875   INT32 actual_size;
01876   // calculate size of actual area.
01877   actual_size = Max_Arg_Area_Bytes(PU_tree);
01878   // mp_io and alloca rely on the actual size being register-sized aligned
01879   actual_size = ROUNDUP(actual_size, MTYPE_byte_size(Spill_Int_Mtype));
01880   if (Trace_Frame && actual_size != Current_PU_Actual_Size) {
01881         fprintf(TFile, "actual_size was %d, now is %d\n",
01882                 Current_PU_Actual_Size, actual_size);
01883   }
01884   // only change size if increased
01885   // (with regions it may decrease if we don't see whole PU).
01886   Current_PU_Actual_Size = MAX(Current_PU_Actual_Size, actual_size);
01887 
01888   Init_Frame_For_PU (Current_PU_Actual_Size);
01889   Bind_Stack_Frame (SP_Sym, FP_Sym);
01890   /* merge fixed part of frame */
01891   Merge_Fixed_Stack_Frame (SP_Sym, FP_Sym);
01892 
01893   Allocate_Local_Spill_Sym ();  /* for later scheduler use */
01894 }
01895 
01896 /* ====================================================================
01897  *
01898  * Process_Stack_Variable
01899  *
01900  * Given a variable allocated to the stack, select the appropriate stack
01901  * frame segment for it, and deal with it.
01902  *
01903  * This routine is used for variables only!
01904  *
01905  * ====================================================================
01906  */
01907 
01908 static void
01909 Process_Stack_Variable ( ST *st )
01910 {
01911    ST_SCLASS    sc;
01912    UINT64       size;
01913    BOOL         is_root_block = Is_Allocatable_Root_Block(st);
01914    ST           *base;
01915 
01916    if (! is_root_block && ST_class(st) == CLASS_BLOCK) return;
01917 
01918    sc = ST_sclass(st);
01919    Is_True ( (sc == SCLASS_AUTO),
01920            ("Process_Stack_Variable: Invalid SCLASS %d\n",ST_sclass(st)) );
01921 
01922    size = (is_root_block) ? STB_size(st) : TY_size(ST_type(st));
01923 
01924    /* attach large objects to FP (if exists), else attach to SP */
01925    if (Current_PU_Stack_Model == SMODEL_SMALL || 
01926         (Current_PU_Stack_Model == SMODEL_LARGE && size < Large_Object_Bytes))
01927         base = SP_Sym;
01928    else
01929         base = FP_Sym;
01930    ST_Block_Merge (base, st, 0, 0, MAX_FRAME_OFFSET);
01931 }
01932 
01933 static void
01934 Trace_Stack_Segments( char *msg, ST *SP_baseST, ST *FP_baseST )
01935 {
01936   SF_SEGMENT s;
01937 
01938   fprintf(TFile, "Stack Segment after \"%s\"\n", msg);
01939   fprintf(TFile, "SegName \toffset\tbase\tblksize\talign\tmaxsize\n");
01940 
01941   /* Clear the segment descriptors: */
01942   for ( s = SFSEG_FIRST; s <= SFSEG_LAST; s = (SF_SEGMENT) (s + 1) ) {
01943     ST          *block;
01944     INT64       size, offset;
01945     INT         align;
01946     char        *basename;
01947 
01948     block = SF_Block(s);
01949     basename = block ? ST_name(ST_base(block)) : (char *)"<none>";
01950     size = block? STB_size(block): 0;
01951     align = block? STB_align(block): 0;
01952     offset = block? ST_ofst(block): 0;
01953     fprintf(TFile, "%s \t%lld\t%s\t%lld\t%d\t%lld\n",
01954             SF_Name(s), offset, basename, size, align, SF_Maxsize(s));
01955   }
01956   if (SP_baseST != NULL)
01957         fprintf(TFile, "%s \t\t%lld\t\t%lld\t%d\n",
01958                 ST_name(SP_baseST), ST_ofst(SP_baseST),
01959                 STB_size(SP_baseST), STB_align(SP_baseST));
01960   if (FP_baseST != NULL)
01961         fprintf(TFile, "%s \t\t%lld\t\t%lld\t%d\n",
01962                 ST_name(FP_baseST), ST_ofst(FP_baseST), 
01963                 STB_size(FP_baseST), STB_align(FP_baseST));
01964 }
01965 
01966 #ifdef PV394813
01967 /* go thru all initv and make sure their STs are allocated */
01968 static void
01969 Allocate_All_INITV (INITV *inv1)
01970 {
01971         INITV *inv;
01972         if (inv1 == NULL) return;
01973         FOREACH_INITV(inv1, inv) {
01974                 if ( INITV_kind(inv) == INITVKIND_SYMOFF) {
01975                         /* may have BASED base, but not allocated */
01976                         Allocate_Object(INITV_st(inv));
01977                 }
01978                 else if (INITV_kind(inv) == INITVKIND_BLOCK) {
01979                         /* recurse on nested block */
01980                         Allocate_All_INITV (INITV_blk(inv));
01981                 }
01982         }
01983 }
01984 #endif
01985 
01986 
01987 /* ====================================================================
01988  *
01989  * Finalize_Stack_Frame
01990  *
01991  * This be called immediately prior to emission to finalize offsets for use
01992  * in instructions.
01993  *
01994  * ====================================================================
01995  */
01996 struct finalize_inito
01997 {
01998     void operator() (UINT32, const INITO* inito) const {
01999         ST* st = INITO_st (*inito);
02000         if (Has_No_Base_Block(st))
02001             Allocate_Object(st);
02002 #ifdef PV394813
02003         Allocate_All_INITV (INITO_val(*inito));
02004 #endif
02005     }
02006 };
02007     
02008 INT64 Finalize_Stack_Frame (void)
02009 {
02010   INT64 Frame_Size;
02011   ST *st;
02012   INT i;
02013 
02014   Set_Error_Phase("Data Layout");
02015   Clear_Vararg_Symbols();
02016 
02017   For_all (Inito_Table, CURRENT_SYMTAB, finalize_inito());
02018 
02019   /* if nested pu, then may not see reference in this pu, 
02020    * but still need to allocate for nested pu's. */
02021   if (PU_has_nested(Get_Current_PU())) {
02022     FOREACH_SYMBOL (CURRENT_SYMTAB, st, i) {
02023       if (ST_class(st) == CLASS_VAR && ST_has_nested_ref(st)) {
02024         Allocate_Object(st);
02025       }
02026     }
02027   }
02028 
02029   switch ( Current_PU_Stack_Model ) {
02030   case SMODEL_SMALL:
02031     // if formals are unused (and no upformals), 
02032     // then don't add formals to frame.
02033     if (SEG_SIZE(SFSEG_UPFORMAL) == 0 
02034         && ST_is_not_used(SF_Block(SFSEG_FORMAL)) )
02035     {
02036         if (Trace_Frame) fprintf(TFile, "<lay> formals not used\n");
02037     }
02038     else {
02039         MERGE_SEGMENT(SP_Sym, SFSEG_FORMAL, Max_Small_Frame_Offset);
02040     }
02041     Frame_Size = STB_size(SP_Sym);
02042     Set_ST_base(SF_Block(SFSEG_UPFORMAL), SP_Sym);
02043     Assign_Offset(SF_Block(SFSEG_UPFORMAL), SP_Sym, 
02044         (Frame_Has_Calls ? Stack_Offset_Adjustment : 0), 0);
02045     break;
02046 
02047   case SMODEL_LARGE:
02048     Frame_Size = STB_size(SP_Sym) + STB_size(FP_Sym);
02049     break;
02050 
02051   case SMODEL_DYNAMIC:
02052     Frame_Size = STB_size(SP_Sym) + STB_size(FP_Sym);
02053     break;
02054 
02055   default:
02056     FmtAssert ( TRUE,
02057                ("UNDEFINED Stack Model in Finalize_Stack_Frame" ));
02058   }
02059 
02060   Frame_Size = ROUNDUP(Frame_Size, stack_align);
02061 
02062   // the stack-frame-adjustment represents N bytes of free space
02063   // that is in the callers frame, and thus does not need to be
02064   // included in the new callee frame size if this is a leaf
02065   // (so don't need to reserve space for subsequent frames).
02066   if (!Frame_Has_Calls) {
02067         Frame_Size = MAX(0, Frame_Size - Stack_Offset_Adjustment);
02068   }
02069 
02070   if ( Trace_Frame ) {
02071     Trace_Stack_Segments ( "Finalize_Stack_Frame", SP_Sym, FP_Sym);
02072     fprintf(TFile, "<lay> final frame_size = %lld\n", Frame_Size);
02073   }
02074   if (Current_PU_Stack_Model == SMODEL_SMALL 
02075         && ((Frame_Size + STB_size(SF_Block(SFSEG_UPFORMAL))) 
02076                 > Max_Small_Frame_Offset))
02077   {
02078         DevWarn("upformals overflowed small stack frame; will try recompiling with -TENV:large_stack");
02079         Early_Terminate(RC_OVERFLOW_ERROR);
02080   }
02081   if (Current_PU_Stack_Model == SMODEL_LARGE && Frame_Size < Max_Small_Frame_Offset)
02082         if (Trace_Frame) fprintf(TFile, "<lay> stack-model underflowed\n");
02083 
02084   {     
02085         /* check that stacksize does not exceed system max */
02086 #if (defined(__sgi) || defined(__sun) \
02087      || (defined(__linux__) && defined(__ia64__)))
02088         struct rlimit64 rlp;
02089         getrlimit64 (RLIMIT_STACK, &rlp);
02090 #else
02091         struct rlimit rlp;
02092         getrlimit(RLIMIT_STACK, &rlp);
02093 #endif
02094         
02095         if (Frame_Size > rlp.rlim_cur)
02096                 ErrMsg (EC_LAY_stack_limit, Frame_Size, (INT64) rlp.rlim_cur);
02097   }
02098   return Frame_Size;
02099 }
02100 
02101 
02102 /* ====================================================================
02103  *
02104  * Allocate_Temp_To_Memory
02105  *
02106  * At the beginning if back end process for a module, the 
02107  *
02108  * ====================================================================
02109  */
02110 void
02111 Allocate_Temp_To_Memory ( ST *st )
02112 {
02113   Is_True(ST_sclass(st) == SCLASS_AUTO, ("Allocate_Temp_To_Memory expect stack var"));
02114   Set_ST_is_temp_var(st);
02115   Process_Stack_Variable ( st );
02116 }
02117 
02118 
02119 /* ====================================================================
02120  *
02121  * STATIC/GLOBAL OBJECT LAYOUT RELATED FUNCTIONS
02122  *
02123  * ====================================================================
02124  */
02125 
02126 static BOOL
02127 Is_String_Literal (ST *st)
02128 {
02129         if (ST_class(st) == CLASS_CONST && TCON_ty(STC_val(st)) == MTYPE_STR) {
02130                 return TRUE;
02131         }
02132         /* sometimes strings are in const array vars */
02133         else if (ST_class(st) == CLASS_VAR && ST_is_const_var(st)
02134                 && ST_is_initialized(st) 
02135                 && TY_kind(ST_type(st)) == KIND_ARRAY
02136                 && TY_mtype(TY_AR_etype(ST_type(st))) == MTYPE_U1 )
02137         {
02138                 return TRUE;
02139         }
02140         return FALSE;
02141 }
02142 
02143 /* ====================================================================
02144  *
02145  * Shorten_Section
02146  *
02147  * Given the section, is there a "Short" section and can we put
02148  * this object into it?  Return the section we should put this
02149  * object into. We also try to figure out if the object can be put
02150  * into a merged section. 
02151  *
02152  * ====================================================================
02153  */
02154 static SECTION_IDX
02155 Shorten_Section ( ST *st, SECTION_IDX sec )
02156 {
02157    INT64   size;
02158    SECTION_IDX newsec;
02159    BOOL     is_root_block = Is_Allocatable_Root_Block(st);
02160 
02161    if (! is_root_block && ST_class(st) == CLASS_BLOCK) return sec;
02162 
02163    /* For PIC code, we can only put local or hidden objects into GP
02164       relative sections.  (unless is gprel)
02165    */
02166    if ((Gen_PIC_Shared || Gen_PIC_Call_Shared) && ST_is_preemptible(st)
02167         && ! (ST_class(st) == CLASS_VAR && ST_force_gprel(st)) )
02168    {
02169       return sec;
02170    }
02171 
02172    newsec = Corresponding_Short_Section (sec);
02173    if (newsec == sec) return sec;       // won't be shortened
02174 
02175    size = ST_size(st);
02176    /* size = 0 implies that we don't really know the size. e.g. int a[]; */
02177    if (size == 0) return sec;
02178 
02179    if (ST_class(st) == CLASS_VAR && ST_not_gprel(st)) 
02180         return sec;     /* user says not gp-relative */
02181 
02182    if (size > Max_Sdata_Elt_Size) { 
02183         /* Object size is greater than the -G number.
02184          * Unless user or previous phase has specified it to be GPREL,
02185          * it can't be GP relative. */
02186         if (ST_class(st) != CLASS_VAR)
02187                 return sec;
02188         /* else is CLASS_VAR */
02189         else if (!ST_gprel(st) && !ST_force_gprel(st))
02190                 return sec;
02191    }
02192 
02193    if (Strings_Not_Gprelative && Is_String_Literal(st)) {
02194         /* don't put strings in a gp-relative section */
02195         return sec;
02196    }
02197 
02198    if ((ST_class(st) == CLASS_VAR || ST_class(st) == CLASS_CONST) && !ST_gprel(st)) 
02199    {
02200         /* Gspace specifies total amount of space we can use for things other
02201          * than what ipa already allocated as gprel. */
02202         /* need to adjust size by possible alignment padding */
02203         size = MAX(size, Adjusted_Alignment(st));
02204         if (size <= Gspace_Available) {
02205                 Gspace_Available -= size;
02206 #if 0
02207                 if (Trace_Frame) fprintf(TFile, "<lay> use Gspace for %s (size %d, align %d)\n", ST_NAME(st), TY_size(ST_type(st)), Adjusted_Alignment(st));
02208 #endif
02209         }
02210         else {
02211                 if (Trace_Frame) fprintf(TFile, "<lay> not enough Gspace, so didn't assign %s to gprel section\n", ST_NAME(st));
02212                 return sec;
02213         }
02214    }
02215 #if 0
02216 else {
02217 if (Trace_Frame) fprintf(TFile, "<lay> didn't check Gspace for %s\n", ST_NAME(st));
02218 }
02219 #endif
02220 
02221    if (sec == _SEC_RDATA && ST_class(st) == CLASS_CONST) {
02222      /* by default put all short .rodata items into .srdata, unless 
02223         we can put it into an appropriate merge section.
02224       */
02225        TCON tcon = STC_val(st);
02226        switch (TCON_ty (tcon)) {
02227        case MTYPE_F4:
02228        case MTYPE_I4:
02229        case MTYPE_U4:
02230          newsec = _SEC_LIT4;
02231          break;
02232        case MTYPE_F8:
02233        case MTYPE_I8:
02234        case MTYPE_U8:
02235          newsec = _SEC_LIT8;
02236          break;
02237        case MTYPE_FQ:
02238          newsec = _SEC_LIT16;
02239          break;
02240        }
02241    }
02242    Set_ST_gprel(st);
02243    return newsec;
02244 }
02245 
02246 
02247 
02248 /* ====================================================================
02249  *
02250  * Allocate object to a section
02251  * 
02252  * Assign an object to a section and then immediately allocate
02253  * space for it.   
02254  *
02255  * ST_ofst is set to the offset from ST_base.
02256  * ST_base is set to the base_sym of the section or altbase.
02257  *
02258  * Remember: "align" is minimum alignment expressed in bytes.
02259  *
02260  * ====================================================================
02261  */
02262 static void
02263 Allocate_Object_To_Section (ST *st, SECTION_IDX sec, UINT align)
02264 {
02265   ST *block;
02266   INT64 max_size;
02267 
02268   /* Everything ok? */
02269      Is_True( IS_POW2(align), ("Alignment %d must be power of 2",align));
02270 
02271   block = Get_Section_ST (sec, align, SCLASS_UNKNOWN /* cause varies */);
02272   max_size = SEC_max_sec_size(sec);
02273   ST_Block_Merge (block, st, 0, 0, max_size);
02274 }
02275 
02276 
02277 /* ====================================================================
02278  *
02279  * Assign object to section
02280  * 
02281  * This is the routine that assigns an object to a section.
02282  *
02283  * No space allocation is done.
02284  *
02285  * "align" is the minimum alignment expressed in bytes.
02286  *
02287  * ====================================================================
02288  */
02289 static void
02290 Assign_Object_To_Section( ST *st, SECTION_IDX sec, UINT align)
02291 {
02292   ST *block;
02293 
02294   /* Everything ok? */
02295      Is_True( IS_POW2(align), ("Alignment %d must be power of 2",align));
02296 
02297   block = Get_Section_ST(sec, align, ST_sclass (st));
02298   if ( Trace_Frame ) {
02299     fprintf ( TFile, "Assigning symbol %s to %s section \n",
02300              ST_name(st) ? ST_name(st) : "<null>", ST_name(block) );
02301   } 
02302   Set_ST_base(st, block);
02303 }
02304 
02305 static void
02306 Allocate_Label (ST *lab)
02307 {
02308   FmtAssert(ST_sclass(lab) == SCLASS_TEXT, ("non-text label?"));
02309   /* this is a reference only, no storage need be allocated */
02310   Assign_Object_To_Section ( lab, _SEC_TEXT, 0 );
02311 }
02312 
02313 
02314 /* ====================================================================
02315  *
02316  * Allocate_Object
02317  *
02318  * Given a symbol table element (representing a data object) with valid
02319  * storage class and unassigned section (SEC_UNKNOWN), chose the appropriate
02320  * section, assign the ST to that section, and allocate storage.
02321  *
02322  * In general, if you have decided which section to allocate this in,
02323  * then call Allocate_Object_To_Section; if you don't know and are
02324  * willing to let this decide, then call Allocate_Object.
02325  *
02326  * ====================================================================
02327  */
02328 
02329 extern void
02330 Allocate_Object ( ST *st )
02331 {
02332   SECTION_IDX  sec;
02333   ST *base_st = st;
02334 
02335   if ( ST_sclass(st) == SCLASS_FORMAL ) {
02336     /* mark that formal-stack-arg-area is needed */
02337     Clear_ST_is_not_used(SF_Block(SFSEG_FORMAL));
02338   }
02339 
02340   if (Is_Allocated(st)) return;
02341   if (ST_is_not_used(st)) return;
02342 
02343   if (ST_has_named_section(st)) {
02344         STR_IDX name = Find_Section_Name_For_ST (st);
02345         Assign_ST_To_Named_Section (st, name);
02346         return;
02347   }
02348   if (Has_Base_Block(st)) {
02349         base_st = Base_Symbol(st);      /* allocate the base, not the leaf */
02350   }
02351 
02352   if (ST_sclass(st) != ST_sclass(base_st))
02353     DevWarn("st sclass %d different from base sclass %d", 
02354             ST_sclass(st), ST_sclass(base_st));
02355 
02356   switch ( ST_sclass(base_st) ) {
02357   case SCLASS_UNKNOWN :
02358     break;
02359   case SCLASS_AUTO:
02360     Process_Stack_Variable(base_st);
02361     break;
02362   case SCLASS_FORMAL:
02363   case SCLASS_FORMAL_REF:
02364     /*
02365      * should have already processed formals and formal_refs: 
02366      */
02367     break;
02368   case SCLASS_PSTATIC :
02369   case SCLASS_FSTATIC :
02370     if (ST_is_thread_private(st)) {
02371       if (ST_is_initialized(st) && !ST_init_value_zero (st))
02372         sec = _SEC_LDATA;
02373       else
02374         sec = _SEC_LBSS;
02375     }
02376     else if (ST_is_initialized(st) && !ST_init_value_zero (st))
02377         sec = (ST_is_constant(st) ? _SEC_RDATA : _SEC_DATA);
02378     else
02379         sec = _SEC_BSS;
02380     sec = Shorten_Section ( st, sec );
02381     Allocate_Object_To_Section ( base_st, sec, Adjusted_Alignment (base_st) );
02382     break;
02383   case SCLASS_REG:
02384         break;
02385   case SCLASS_CPLINIT:
02386         sec = _SEC_CPLINIT;
02387         Allocate_Object_To_Section ( base_st, sec, Adjusted_Alignment(base_st));
02388         break;
02389   case SCLASS_EH_REGION:
02390         sec = _SEC_EH_REGION;
02391         Allocate_Object_To_Section ( base_st, sec, Adjusted_Alignment(base_st));
02392         break;
02393   case SCLASS_EH_REGION_SUPP:
02394         sec = _SEC_EH_REGION_SUPP;
02395         Allocate_Object_To_Section ( base_st, sec, Adjusted_Alignment(base_st));
02396         break;
02397   case SCLASS_DISTR_ARRAY:
02398         sec = _SEC_DISTR_ARRAY;
02399         Allocate_Object_To_Section ( base_st, sec, Adjusted_Alignment(base_st));
02400         break;
02401   case SCLASS_THREAD_PRIVATE_FUNCS:
02402         sec = _SEC_THREAD_PRIVATE_FUNCS;
02403         Allocate_Object_To_Section ( base_st, sec, Adjusted_Alignment(base_st));
02404         break;
02405   case SCLASS_COMMON:
02406    /*  The compiler has promised the Adjusted_Alignment to earlier phases, so
02407     *  we must change the alignment somewhere (here is good)
02408     *
02409     *  This may break compatibility with other compilers (ie. another compiler
02410     *  initializes data at a non Adjusted_Alignment().
02411     */
02412     if (ST_type(st) != (TY_IDX) NULL)
02413     {
02414       TY_IDX type = ST_type(st);
02415 
02416       Set_ST_type(st, 
02417         Make_Align_Type(type, Adjusted_Alignment(st)) );
02418     } /* fall thru */
02419   case SCLASS_EXTERN:
02420     /* if possible, mark the symbol as gp-relative. No need to do anything
02421      * else.  But if IPA has been run, don't want to mark these symbols
02422      * as gprel, because have to trust IPA's choosing of gprel symbols.
02423      */
02424     if ( ! FILE_INFO_ipa (File_info) && !ST_is_weak_symbol(st)) {
02425         sec = Shorten_Section ( st, _SEC_DATA );
02426         if (sec != _SEC_DATA) Set_ST_gprel (st);
02427     }
02428     break;
02429   case SCLASS_UGLOBAL :
02430     if (ST_is_thread_private(st)) {
02431       sec = _SEC_LBSS;
02432     } 
02433     else sec = _SEC_BSS;
02434     sec = Shorten_Section ( st, sec );
02435     Allocate_Object_To_Section ( base_st, sec, Adjusted_Alignment(base_st));
02436     break;
02437   case SCLASS_DGLOBAL :
02438     if (ST_is_thread_private(st)) sec = _SEC_LDATA;
02439     else if (ST_is_constant(st)) sec = _SEC_RDATA;
02440     else sec = _SEC_DATA;
02441     sec = Shorten_Section ( st, sec );
02442     Allocate_Object_To_Section ( base_st, sec, Adjusted_Alignment(base_st));
02443     break;
02444   case SCLASS_TEXT :
02445     /* this is a reference only, no storage need be allocated */
02446     /* Text can't be shortened */
02447     sec = _SEC_TEXT;
02448     Assign_Object_To_Section ( base_st, sec, 0 );
02449     break;
02450   default:
02451     Is_True ( (FALSE)
02452              , ("Allocate_Object: Invalid SCLASS %d",ST_sclass(st)) );
02453     break;
02454   } /* switch */
02455 
02456 }
02457 
02458 
02459 
02460 /* ====================================================================
02461  *
02462  * Allocate_File_Statics
02463  *
02464  * It goes throught the global symbols and call Allocate_Object for
02465  * them. 
02466  *
02467  * ====================================================================
02468  */
02469 extern void 
02470 Allocate_File_Statics (void)
02471 {
02472   ST *st;
02473   INT i;
02474   Trace_Frame = Get_Trace(TP_DATALAYOUT, 1);
02475 
02476   // first look in global st-attr table for section assignments
02477   if ( ST_ATTR_Table_Size (GLOBAL_SYMTAB)) {
02478     For_all (St_Attr_Table, GLOBAL_SYMTAB,
02479         Assign_Section_Names());
02480   }
02481 
02482   // gnu assembler complains about multiple commons with same name in a file.
02483   // So search for commons with same name and merge them together.
02484 
02485 #ifndef _USE_STL_EXT
02486   list<ST*> common_list;
02487   list<ST*>::iterator cit;
02488 #else
02489   slist<ST*> common_list;
02490   slist<ST*>::iterator cit;
02491 #endif
02492 
02493   FOREACH_SYMBOL (GLOBAL_SYMTAB,st,i) {
02494         if (ST_sclass(st) != SCLASS_COMMON) continue;
02495         if (Has_Base_Block(st)) continue;       // only merge root commons
02496         // search for it in list; if found, merge, if not, add.
02497         for (cit = common_list.begin(); cit != common_list.end(); ++cit)
02498         {
02499                 if (ST_name_idx(*cit) == ST_name_idx(st)
02500                     && ST_export(*cit) == ST_export(st)) 
02501                 {
02502                         // rather than create new symbol, instead
02503                         // just base one symbol on larger one.
02504                         // St_Block_Union(*cit, st);
02505                         if (TY_size(ST_type(st)) > TY_size(ST_type(*cit))) {
02506                                 Set_ST_base(*cit, st);
02507 DevWarn("found commons with same name %s; merge together %d->%d", ST_name(st), ST_index(*cit), ST_index(st));
02508                                 // replace symbol in list with the
02509                                 // larger symbol.
02510                                 *cit = st;
02511                         }
02512                         else {
02513                                 Set_ST_base(st, *cit);
02514 DevWarn("found commons with same name %s; merge together %d->%d", ST_name(st), ST_index(st), ST_index(*cit));
02515                         }
02516                         break;
02517                 }
02518         }
02519         if (cit == common_list.end()) {
02520                 common_list.push_front(st);
02521         }
02522   }
02523 
02524   FOREACH_SYMBOL (GLOBAL_SYMTAB,st,i) {
02525       if (ST_sclass(st) == SCLASS_REG) continue;        // pregs
02526 
02527       // will allocate constants as seen, unless IPA
02528       if (ST_class(st) == CLASS_CONST && !Emit_Global_Data) continue;
02529 
02530       /* if reshaped, lno will take care of allocation.
02531        * if fill/align, then be will take care of allocation.
02532        */
02533       if (ST_class(st) == CLASS_VAR &&
02534           (ST_is_reshaped(st) || ST_is_fill_align(st))) 
02535         continue;
02536       Allocate_Object(st);
02537   }
02538 }
02539 
02540 
02541 /* This checks for "small" offsets (< 16 bits) from sp/gp/fp */
02542 BOOL
02543 Uses_Small_Offset (ST *st, WN_OFFSET wn_ofst)
02544 {
02545         switch(ST_sclass(st)) {
02546 
02547         case SCLASS_AUTO:
02548                 switch (Current_PU_Stack_Model) {
02549                 case SMODEL_SMALL:
02550                         return TRUE;
02551                 case SMODEL_LARGE:
02552                         /* assume that only large objects
02553                          * will end up far away.
02554                          * could be wrong if lots of small objects. */
02555                         return (ST_size(st) < Large_Object_Bytes);
02556                 case SMODEL_DYNAMIC:
02557                         /* don't know order with alloca frames
02558                          * so worse case assumption: */
02559                         return FALSE;
02560                 }
02561 
02562         case SCLASS_FORMAL:
02563                 return (Current_PU_Stack_Model != SMODEL_DYNAMIC);
02564         default:
02565                 switch (ST_class(st)) {
02566                 case CLASS_VAR:
02567                 case CLASS_BLOCK:
02568                         return ST_gprel(st);
02569                 case CLASS_CONST:
02570                         /* assume that const will be in gp-relative section.
02571                          * actually may not be, but this is a safe guess. */
02572                         return TRUE;
02573                 }
02574                 return FALSE;
02575         }
02576 }
02577 
02578 // Pad global arrays whose size is too close to a multiple of the
02579 // cache size
02580 
02581 static ST*
02582 Create_Global_Array_ST (TYPE_ID emtype, INT num, char *name) 
02583 {
02584 
02585     TY_IDX arr_ty = Make_Array_Type (emtype, 1, num);
02586     ST* st = New_ST ();
02587     ST_Init (st, Save_Str(name), CLASS_VAR, SCLASS_UGLOBAL, EXPORT_LOCAL, arr_ty);
02588     Set_ST_pt_to_unique_mem (st);
02589     return st;
02590 } // Create_Global_Array_ST
02591 
02592 
02593 // make sure size is greater than 10% more than 1600 or 256K
02594 
02595 
02596 struct pad_global_arrays
02597 {
02598     inline void operator() (UINT32, ST* st) const {
02599         if ((ST_sclass(st) == SCLASS_UGLOBAL) && (ST_class(st) == CLASS_VAR)) {
02600           const TY_IDX ty = ST_type(st);
02601 
02602           if (!ST_is_not_used(st) &&
02603             (TY_size (ty) > 0) &&
02604             !ST_is_fill_align(st) &&
02605             !ST_has_nested_ref(st) &&
02606             (TY_kind(ty) == KIND_ARRAY) &&
02607             (!ST_is_reshaped(st))) {
02608 
02609             INT size = TY_size (ty);
02610             INT set_size = 256*1024;
02611             INT mod = size % set_size;
02612             INT pad_size=0;
02613             if ((size > 0.9*set_size) && (mod < set_size/20)) {
02614                 pad_size = set_size/20 - mod;
02615             } else if ((size > 0.9*set_size) &&
02616                        ((set_size - mod) < set_size/20)) {
02617                 pad_size = set_size/20 + (set_size - mod);
02618             }
02619             size += pad_size;
02620             set_size = 16*1024;
02621             mod = size % set_size;
02622             if ((size > 0.9*set_size) && (mod < set_size/20)) {
02623                 pad_size += set_size/20 - mod;
02624             } else if ((size > 0.9*set_size) &&
02625                        ((set_size - mod) < set_size/20)) {
02626                 pad_size += set_size/20 + (set_size - mod);
02627             }
02628             size += pad_size;
02629             if (pad_size) {
02630                 static INT count;
02631                 char name[64];
02632                 sprintf (name, "global_pad_%d", count);
02633                 count++;
02634                 ST *pad_symbol = Create_Global_Array_ST (MTYPE_I1,size,name); 
02635                 St_Block_Union(st,pad_symbol);
02636             }
02637           }
02638         }
02639     }
02640 }; // pad_global_arrays
02641 
02642 extern void
02643 Pad_Global_Arrays()
02644 {
02645     For_all (St_Table, GLOBAL_SYMTAB, pad_global_arrays ());
02646 }
02647 
02648 
02649 extern INT
02650 Stack_Offset_Adjustment_For_PU (void)
02651 {
02652   if (Frame_Has_Calls) 
02653         return Stack_Offset_Adjustment;
02654   else
02655         return 0;
02656 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines