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 * dd-mmm-95 - Original Version 00042 * 00043 * Description: contains routines to maintain 00044 * 00045 * a) a block stack for control flow and parallel regions 00046 * b) special WN_Blocks used for pragmas, entry preamble 00047 * loops etc. These are filled in at odd times, then 00048 * added to the main WN_tree when convenient. 00049 * 00050 * ==================================================================== 00051 * ==================================================================== 00052 */ 00053 00054 static char *source_file = __FILE__; 00055 00056 /* sgi includes */ 00057 00058 #include "defs.h" 00059 #include "glob.h" 00060 #include "symtab.h" 00061 #include "errors.h" 00062 #include "wn.h" 00063 #include "wn_util.h" 00064 #include "ir_reader.h" 00065 00066 /* conversion includes */ 00067 00068 #include "cwh_defines.h" 00069 #include "cwh_stmt.h" 00070 #include "cwh_directive.h" 00071 #include "cwh_block.h" 00072 #include "cwh_block.i" 00073 00074 /*============================================== 00075 * 00076 * cwh_block_push_block 00077 * 00078 * push the current block onto the block stack. 00079 * 00080 *=============================================== 00081 */ 00082 extern void 00083 cwh_block_push_block(WN *deferred, WN *append, BOOL is_top_pdo) 00084 { 00085 cwh_block_bump(); 00086 00087 block_stack[block_stack_top].wn = cwh_block_current_inline(); 00088 block_stack[block_stack_top].u.block.deferred = deferred; 00089 block_stack[block_stack_top].u.block.append = append; 00090 00091 if (parallel_do_count) { 00092 block_stack[block_stack_top].is_parallel_do = TRUE; 00093 parallel_do_count--; 00094 00095 } else { 00096 block_stack[block_stack_top].is_parallel_do = FALSE; 00097 } 00098 00099 block_stack[block_stack_top].is_top_pdo = is_top_pdo; 00100 } 00101 00102 /*============================================== 00103 * 00104 * cwh_block_pop_block 00105 * 00106 * pop the region/do/block on top of the block stack 00107 * 00108 * Appends any deferred statements to the current block. 00109 * Makes TOS current block, and appends any thing 00110 * that's on the append list. 00111 * 00112 *=============================================== 00113 */ 00114 extern void 00115 cwh_block_pop_block(void) 00116 { 00117 WN *block, *append; 00118 BOOL is_parallel_do, is_top_pdo; 00119 00120 DevAssert((block_stack_top >= 0),("block stack underflow")); 00121 00122 block = block_stack[block_stack_top].wn; 00123 is_parallel_do = block_stack[block_stack_top].is_parallel_do; 00124 is_top_pdo = block_stack[block_stack_top].is_top_pdo; 00125 00126 DevAssert((WN_opcode(block)!=OPC_REGION),("stack mismatch, expected BLOCK")); 00127 00128 if (block_stack[block_stack_top].u.block.deferred) { 00129 cwh_block_append(block_stack[block_stack_top].u.block.deferred); 00130 } 00131 00132 append = block_stack[block_stack_top].u.block.append; 00133 cwh_block_set_current(block); 00134 --block_stack_top; 00135 00136 if (append) 00137 cwh_block_append(append); 00138 00139 /* is implicit end of parallel loop region ? */ 00140 /* don't do this for outer-most loop of PDO */ 00141 /* because the endpdo will pop off the region */ 00142 00143 if (is_parallel_do && !is_top_pdo) 00144 cwh_block_pop_region(); 00145 } 00146 00147 /*============================================== 00148 * 00149 * cwh_block_pop_region 00150 * 00151 * pop the MP region on top of the block stack. 00152 * 00153 *=============================================== 00154 */ 00155 extern WN * 00156 cwh_block_pop_region(void) 00157 { 00158 WN *region, *block; 00159 DevAssert((block_stack_top >= 0),("region stack underflow")); 00160 00161 region = block_stack[block_stack_top].wn; 00162 block = block_stack[block_stack_top].u.region_parent; 00163 00164 DevAssert((WN_opcode(region)==OPC_REGION),("stack mismatch, expected REGION")); 00165 00166 --block_stack_top; 00167 00168 /* the current block is now set to the parent block of the region */ 00169 00170 cwh_block_set_current(block); 00171 return region; 00172 } 00173 00174 /*============================================== 00175 * 00176 * cwh_block_set_region 00177 * 00178 * set the current block to the nearest enclosing 00179 * region's pragma block. 00180 * 00181 * Return the current block mostly, but 00182 * oometimes we want to check the block stack 00183 * but don't mind if there isn't an enclosing 00184 * region. If so, then return NULL. 00185 * 00186 *=============================================== 00187 */ 00188 extern WN * 00189 cwh_block_set_region_pragmas(BOOL assert) 00190 { 00191 int i; 00192 WN *wn; 00193 for (i=block_stack_top; i>=0; i--) { 00194 wn = block_stack[i].wn; 00195 if (WN_operator(wn)==OPR_REGION) { 00196 return (cwh_block_exchange_current(WN_region_pragmas(wn))); 00197 } 00198 } 00199 00200 if (assert) { 00201 DevAssert((0),("no enclosing region")); 00202 return cwh_block_current_inline() ; 00203 } 00204 return NULL; 00205 } 00206 00207 /*============================================== 00208 * 00209 * cwh_block_add_to_enclosing_regions 00210 * 00211 * add the given pragma to pragma blocks 00212 * of all regions on the block stack. 00213 * 00214 *=============================================== 00215 */ 00216 extern void 00217 cwh_block_add_to_enclosing_regions(WN_PRAGMA_ID id, ST * st) 00218 { 00219 int i; 00220 00221 WN_VECTOR regions ; 00222 00223 DevAssert((id == WN_PRAGMA_LOCAL), ("only local required just now")); 00224 00225 for (i = block_stack_top; i>=0 ; i--) { 00226 WN * wn = block_stack[i].wn; 00227 00228 if (WN_operator(wn)==OPR_REGION) { 00229 if (WN_region_kind(wn) == REGION_KIND_MP) 00230 regions.insert(regions.end(),wn); 00231 } 00232 } 00233 00234 Add_Pragma_To_MP_Regions (®ions, 00235 id, 00236 st, 00237 0, 00238 0, 00239 FALSE); 00240 } 00241 00242 /*============================================== 00243 * 00244 * cwh_block_push_region 00245 * 00246 * push the MP region on top of the block stack. 00247 * 00248 *=============================================== 00249 */ 00250 extern void 00251 cwh_block_push_region(WN *region) 00252 { 00253 DevAssert((WN_opcode(region)==OPC_REGION),(" not region")) ; 00254 00255 cwh_block_bump(); 00256 00257 block_stack[block_stack_top].wn = region; 00258 block_stack[block_stack_top].u.region_parent = cwh_block_current_inline(); 00259 } 00260 00261 /*============================================== 00262 * 00263 * cwh_block_dump() 00264 * 00265 * dumps the block stack to stdout 00266 * 00267 *=============================================== 00268 */ 00269 extern void 00270 cwh_block_dump(void) 00271 { 00272 WN * wn ; 00273 int i ; 00274 00275 printf ("\n Block Stack --- \n\n"); 00276 00277 for (i = block_stack_top ; i >= 0 ; i-- ) { 00278 00279 wn = block_stack[i].wn ; 00280 00281 dump_wn(wn); 00282 00283 if (WN_opcode(wn) == OPC_REGION) { 00284 00285 printf (" parent %x \n", 00286 block_stack[i].u.region_parent); 00287 00288 } else { 00289 00290 printf (" deferred %x, append %x, pdo %d, top pdo %d \n", 00291 block_stack[i].u.block.deferred, 00292 block_stack[i].u.block.append, 00293 block_stack[i].is_parallel_do, 00294 block_stack[i].is_top_pdo); 00295 } 00296 } 00297 } 00298 00299 /*============================================== 00300 * 00301 * cwh_block_bump 00302 * 00303 * bump the block stack along 00304 * 00305 * Allocate in chunks of 20 00306 * 00307 *=============================================== 00308 */ 00309 static void 00310 cwh_block_bump(void) 00311 { 00312 ++block_stack_top; 00313 00314 if (block_stack_size == 0) { 00315 00316 block_stack = (block_stack_t *) malloc(BLOCK_CHUNK_SIZE * sizeof(block_stack_t)); 00317 block_stack_size = BLOCK_CHUNK_SIZE; 00318 00319 } else if (block_stack_top >= block_stack_size) { 00320 00321 block_stack_size += BLOCK_CHUNK_SIZE; 00322 block_stack = (block_stack_t *) realloc(block_stack, block_stack_size * sizeof(block_stack_t)); 00323 } 00324 } 00325 00326 /*============================================== 00327 * 00328 * cwh_block_current 00329 * 00330 * get the current block 00331 * 00332 *=============================================== 00333 */ 00334 extern WN * 00335 cwh_block_current(void) 00336 { 00337 return WN_block; 00338 } 00339 00340 /*=============================================== 00341 * 00342 * cwh_block_set_current 00343 * 00344 * Set current block, ie: default location to add 00345 * statements,to blk 00346 * 00347 *=============================================== 00348 */ 00349 extern void 00350 cwh_block_set_current(WN * blk ) 00351 { 00352 WN_block = blk; 00353 } 00354 /*=============================================== 00355 * 00356 * cwh_block_new_and_current 00357 * 00358 * Create a new block and set it up as the 00359 * current block. Return the block that was 00360 * current; 00361 * 00362 *=============================================== 00363 */ 00364 extern WN * 00365 cwh_block_new_and_current(void) 00366 { 00367 WN * wn ; 00368 00369 wn = cwh_block_current_inline(); 00370 cwh_block_set_current(WN_CreateBlock()) ; 00371 00372 return (wn); 00373 } 00374 00375 extern WN * 00376 cwh_block_new_and_decl(void) 00377 { 00378 WN * wn ; 00379 00380 wn = cwh_block_decl(); 00381 cwh_block_set_current(WN_CreateBlock()) ; 00382 00383 return (wn); 00384 } 00385 00386 00387 /*=============================================== 00388 * 00389 * cwh_block_exchange_current 00390 * 00391 * Set current block to blk and return the old value 00392 * 00393 *=============================================== 00394 */ 00395 extern WN * 00396 cwh_block_exchange_current(WN * blk ) 00397 { 00398 WN * rtrn = cwh_block_current_inline(); 00399 cwh_block_set_current(blk); 00400 return rtrn; 00401 } 00402 00403 /*=============================================== 00404 * 00405 * cwh_block_append 00406 * 00407 * Append the WN argument to the current block node, 00408 * by default, or anoth block if given 00409 * 00410 *=============================================== 00411 */ 00412 extern void 00413 cwh_block_append(WN *wn) 00414 { 00415 cwh_block_append_given_block(wn,cwh_block_current_inline()); 00416 } 00417 00418 /*=============================================== 00419 * 00420 * cwh_block_append_given_block 00421 * 00422 * Append the WN argument to the given block node, 00423 * 00424 *=============================================== 00425 */ 00426 extern void 00427 cwh_block_append_given_block(WN *wn, WN* block) 00428 { 00429 if (WN_opcode(wn) != OPC_BLOCK) { 00430 if (cwh_block_add_debug_line) 00431 WN_Set_Linenum (wn, USRCPOS_srcpos(current_srcpos) ); 00432 else 00433 WN_Set_Linenum (wn, 0); 00434 } 00435 00436 WN_INSERT_BlockLast(block,wn) ; 00437 } 00438 00439 /*=============================================== 00440 * 00441 * cwh_block_insert_after 00442 * 00443 * Insert a node after a given node within the current block. 00444 * 00445 *=============================================== 00446 */ 00447 extern void 00448 cwh_block_insert_after(WN *wn, WN*in) 00449 { 00450 00451 if (cwh_block_add_debug_line) 00452 WN_Set_Linenum (in, USRCPOS_srcpos(current_srcpos) ); 00453 else 00454 WN_Set_Linenum (in, 0); 00455 00456 00457 WN_INSERT_BlockAfter(cwh_block_current_inline(), wn, in); 00458 } 00459 00460 00461 /*=============================================== 00462 * 00463 * cwh_block_append_given_id 00464 * 00465 * Append the WN to the block given. If the block 00466 * is NULL, it's created. Several such blocks 00467 * are available either for declarations just 00468 * before or after the preamble, or to defer 00469 * statements after a block. 00470 * 00471 *=============================================== 00472 */ 00473 extern void 00474 cwh_block_append_given_id(WN* wn, enum block_id id, BOOL first) 00475 { 00476 WN ** block ; 00477 00478 block = cwh_block_find_address(id) ; 00479 00480 if (!(*block)) 00481 *block = WN_CreateBlock(); 00482 00483 00484 if (first) 00485 WN_INSERT_BlockFirst(*block,wn); 00486 else 00487 WN_INSERT_BlockLast(*block,wn); 00488 } 00489 00490 /*=============================================== 00491 * 00492 * cwh_block_append_given 00493 * 00494 * Append given block to the current block. 00495 * Clears the block pointer associated with flag 00496 * 00497 *=============================================== 00498 */ 00499 extern void 00500 cwh_block_append_given(enum block_id id) 00501 { 00502 WN ** block ; 00503 00504 block = cwh_block_find_address(id) ; 00505 00506 if (*block != NULL) { 00507 cwh_block_append(*block); 00508 *block = NULL; 00509 } 00510 } 00511 00512 /*=============================================== 00513 * 00514 * cwh_block_find_address 00515 * 00516 * Get the address of the pointer to the WN_block 00517 * given the ID. 00518 * 00519 *=============================================== 00520 */ 00521 static WN ** 00522 cwh_block_find_address(enum block_id id) 00523 { 00524 WN ** block ; 00525 00526 switch (id) { 00527 case Defer_Block: 00528 block = &WN_defer_block; 00529 break; 00530 00531 case Preamble_Block: 00532 block = &WN_copyin_block; 00533 break; 00534 00535 case First_Block: 00536 block = &WN_decl_block; 00537 break; 00538 00539 case Top_of_Loop_Block: 00540 block = &WN_top_of_loop_block; 00541 break; 00542 00543 default: 00544 DevAssert((0),("odd block")); 00545 } 00546 return block; 00547 } 00548 00549 /*=============================================== 00550 * 00551 * cwh_block_init 00552 * 00553 * Initalize block varbls. 00554 * 00555 *=============================================== 00556 */ 00557 extern void 00558 cwh_block_init_pu() 00559 { 00560 WN_defer_block = NULL; 00561 WN_decl_block = NULL; 00562 WN_copyin_block = NULL; 00563 WN_top_of_loop_block = NULL; 00564 cwh_block_add_debug_line = FALSE; 00565 00566 } 00567 00568 /*=============================================== 00569 * 00570 * cwh_block_toggle_debug 00571 * 00572 * toggle the debug flag which puts out WN src lines. 00573 * returns old setting. 00574 * 00575 *=============================================== 00576 */ 00577 extern BOOL 00578 cwh_block_toggle_debug(BOOL debug) 00579 { 00580 BOOL old = cwh_block_add_debug_line; 00581 cwh_block_add_debug_line = debug; 00582 return old; 00583 }