Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
cwh_block.cxx
Go to the documentation of this file.
00001 /*
00002 
00003   Copyright (C) 2000, 2001 Silicon Graphics, Inc.  All Rights Reserved.
00004 
00005   This program is free software; you can redistribute it and/or modify it
00006   under the terms of version 2 of the GNU General Public License as
00007   published by the Free Software Foundation.
00008 
00009   This program is distributed in the hope that it would be useful, but
00010   WITHOUT ANY WARRANTY; without even the implied warranty of
00011   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
00012 
00013   Further, this software is distributed without any warranty that it is
00014   free of the rightful claim of any third person regarding infringement 
00015   or the like.  Any license provided herein, whether implied or 
00016   otherwise, applies only to this software file.  Patent licenses, if 
00017   any, provided herein do not apply to combinations of this program with 
00018   other software, or any other product whatsoever.  
00019 
00020   You should have received a copy of the GNU General Public License along
00021   with this program; if not, write the Free Software Foundation, Inc., 59
00022   Temple Place - Suite 330, Boston MA 02111-1307, USA.
00023 
00024   Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
00025   Mountain View, CA 94043, or:
00026 
00027   http://www.sgi.com
00028 
00029   For further information regarding this notice, see:
00030 
00031   http://oss.sgi.com/projects/GenInfo/NoticeExplan
00032 
00033 */
00034 
00035 
00036 /* ====================================================================
00037  * ====================================================================
00038  *
00039  *
00040  * Revision history:
00041  *  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 (&regions, 
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines