Open64 (mfef90, whirl2f, and IR tools)
TAG: version-openad; SVN changeset: 916
|
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 }