Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
ir.c
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 static char USMID[] = "\n@(#)5.0_pl/sources/ir.c        5.6     10/05/99 14:45:20\n";
00038 
00039 # include <stdarg.h>
00040 
00041 # include "defines.h"           /* Machine dependent ifdefs */
00042 
00043 # include "host.m"              /* Host machine dependent macros.*/
00044 # include "host.h"              /* Host machine dependent header.*/
00045 # include "target.m"            /* Target machine dependent macros.*/
00046 # include "target.h"            /* Target machine dependent header.*/
00047 
00048 # include "globals.m"
00049 # include "tokens.m"
00050 # include "sytb.m"
00051 # include "s_globals.m"
00052 # include "debug.m"
00053 
00054 # include "globals.h"
00055 # include "tokens.h"
00056 # include "sytb.h"
00057 # include "s_globals.h"
00058 
00059 
00060 /*****************************************************************\
00061 |* function prototypes of static functions declared in this file *|
00062 \*****************************************************************/
00063 
00064 static boolean  compare_il(int, int, int, int);
00065 static boolean  compare_ir(int, int);
00066 static boolean  il_is_symbolic_constant(int);
00067 static boolean  ir_is_symbolic_constant(int);
00068 
00069 static  int     label_copy_al_idx = NULL_IDX;
00070 static  boolean gen_lbl_copy = FALSE;
00071 
00072 
00073 /******************************************************************************\
00074 |*                                                                            *|
00075 |* Description:                                                               *|
00076 |*      Generate a new Statement Header (SH) either before or after the       *|
00077 |*      current SH.                                                           *|
00078 |*                                                                            *|
00079 |* Input parameters:                                                          *|
00080 |*      NONE                                                                  *|
00081 |*                                                                            *|
00082 |* Output parameters:                                                         *|
00083 |*      NONE                                                                  *|
00084 |*                                                                            *|
00085 |* Returns:                                                                   *|
00086 |*      NOTHING                                                               *|
00087 |*                                                                            *|
00088 \******************************************************************************/
00089 
00090 void gen_sh(sh_position_type    position,
00091             stmt_type_type      stmt_type,
00092             int                 line_num,
00093             int                 col_num,
00094             boolean             err_flag,
00095             boolean             labeled,
00096             boolean             compiler_gen)
00097 
00098 {
00099    int          next_idx;
00100    int          prev_idx;
00101    int          sh_idx;
00102 
00103 
00104    TRACE (Func_Entry, "gen_sh", NULL);
00105 
00106 # ifdef _DEBUG
00107    if (defer_stmt_expansion) {
00108       PRINTMSG(line_num, 626, Internal, col_num,
00109                "no defer_stmt_expansion", "gen_sh");
00110    }
00111 
00112    if (curr_stmt_sh_idx == NULL_IDX) {
00113       PRINTMSG(line_num, 626, Internal, col_num,
00114                "valid curr_stmt_sh_idx", "gen_sh");
00115    }
00116 # endif
00117 
00118    sh_idx                  = ntr_sh_tbl();
00119    SH_STMT_TYPE(sh_idx)    = stmt_type;
00120    SH_GLB_LINE(sh_idx)     = line_num;
00121    SH_ERR_FLG(sh_idx)      = err_flag;
00122    SH_COL_NUM(sh_idx)      = col_num;
00123    SH_LABELED(sh_idx)      = labeled;
00124    SH_COMPILER_GEN(sh_idx) = compiler_gen;
00125    
00126    if (stmt_type == Construct_Def) {
00127       SH_P2_SKIP_ME(sh_idx) = TRUE;
00128    }
00129 
00130    if (position == Before) {
00131       SH_NEXT_IDX(sh_idx) = curr_stmt_sh_idx;
00132 
00133       if (curr_stmt_sh_idx == SCP_FIRST_SH_IDX(curr_scp_idx)) {           
00134          SCP_FIRST_SH_IDX(curr_scp_idx) = sh_idx; 
00135       }
00136       else {
00137          prev_idx = SH_PREV_IDX(curr_stmt_sh_idx);
00138 
00139          if (prev_idx != NULL_IDX) { 
00140             SH_PREV_IDX(sh_idx)         = prev_idx;
00141             SH_NEXT_IDX(prev_idx)       = sh_idx;
00142          }
00143       }
00144 
00145       SH_PREV_IDX(curr_stmt_sh_idx) = sh_idx;
00146    }
00147    else {
00148       SH_PREV_IDX(sh_idx)       = curr_stmt_sh_idx;
00149       next_idx                  = SH_NEXT_IDX(curr_stmt_sh_idx);
00150  
00151       if (next_idx != NULL_IDX) {
00152          SH_NEXT_IDX(sh_idx)    = next_idx;
00153          SH_PREV_IDX(next_idx)  = sh_idx;
00154       }
00155 
00156       SH_NEXT_IDX(curr_stmt_sh_idx)    = sh_idx;
00157       curr_stmt_sh_idx                 = sh_idx;
00158    }
00159 
00160    TRACE (Func_Exit, "gen_sh", NULL);
00161 
00162    return;
00163 
00164 }  /* gen_sh */
00165 
00166 /******************************************************************************\
00167 |*                                                                            *|
00168 |* Description:                                                               *|
00169 |*      Generate a new Statement Header (SH) either before or after the       *|
00170 |*      current SH.                                                           *|
00171 |*                                                                            *|
00172 |* Input parameters:                                                          *|
00173 |*      NONE                                                                  *|
00174 |*                                                                            *|
00175 |* Output parameters:                                                         *|
00176 |*      NONE                                                                  *|
00177 |*                                                                            *|
00178 |* Returns:                                                                   *|
00179 |*      NOTHING                                                               *|
00180 |*                                                                            *|
00181 \******************************************************************************/
00182 
00183 void gen_gl_sh(sh_position_type    position,
00184             stmt_type_type      stmt_type,
00185             int                 line_num,
00186             int                 col_num,
00187             boolean             err_flag,
00188             boolean             labeled,
00189             boolean             compiler_gen)
00190 
00191 {
00192    int          next_idx;
00193    int          prev_idx;
00194    int          sh_idx;
00195 
00196 
00197    TRACE (Func_Entry, "gen_gl_sh", NULL);
00198 
00199    sh_idx                  = ntr_gl_sh_tbl();
00200    GL_SH_STMT_TYPE(sh_idx)    = stmt_type;
00201    GL_SH_GLB_LINE(sh_idx)     = line_num;
00202    GL_SH_ERR_FLG(sh_idx)      = err_flag;
00203    GL_SH_COL_NUM(sh_idx)      = col_num;
00204    GL_SH_LABELED(sh_idx)      = labeled;
00205    GL_SH_COMPILER_GEN(sh_idx) = compiler_gen;
00206 
00207    if (stmt_type == Construct_Def) {
00208       GL_SH_P2_SKIP_ME(sh_idx) = TRUE;
00209    }
00210 
00211    if (curr_gl_stmt_sh_idx == NULL_IDX) {
00212 
00213       if (global_stmt_sh_idx == NULL_IDX) {
00214          global_stmt_sh_idx = sh_idx;
00215       }
00216       curr_gl_stmt_sh_idx = sh_idx;
00217    }
00218    else if (position == Before) {
00219 
00220       GL_SH_NEXT_IDX(sh_idx) = curr_gl_stmt_sh_idx;
00221 
00222       if (curr_gl_stmt_sh_idx == global_stmt_sh_idx) {
00223          global_stmt_sh_idx = sh_idx;
00224       }
00225       else {
00226          prev_idx = GL_SH_PREV_IDX(curr_gl_stmt_sh_idx);
00227 
00228          if (prev_idx != NULL_IDX) {
00229             GL_SH_PREV_IDX(sh_idx)         = prev_idx;
00230             GL_SH_NEXT_IDX(prev_idx)       = sh_idx;
00231          }
00232       }
00233 
00234       GL_SH_PREV_IDX(curr_gl_stmt_sh_idx) = sh_idx;
00235    }
00236    else {
00237       GL_SH_PREV_IDX(sh_idx)    = curr_gl_stmt_sh_idx;
00238       next_idx                  = GL_SH_NEXT_IDX(curr_gl_stmt_sh_idx);
00239 
00240       if (next_idx != NULL_IDX) {
00241          GL_SH_NEXT_IDX(sh_idx)    = next_idx;
00242          GL_SH_PREV_IDX(next_idx)  = sh_idx;
00243       }
00244 
00245       GL_SH_NEXT_IDX(curr_gl_stmt_sh_idx) = sh_idx;
00246       curr_gl_stmt_sh_idx                 = sh_idx;
00247    }
00248 
00249    TRACE (Func_Exit, "gen_gl_sh", NULL);
00250 
00251    return;
00252 
00253 }  /* gen_gl_sh */
00254 
00255 /******************************************************************************\
00256 |*                                                                            *|
00257 |* Description:                                                               *|
00258 |*      compare_ir takes 2 seperate ir streams and compares them.  If the     *|
00259 |*      operators, types and operands are the same, the ir streams are the    *|
00260 |*      same.  Different ir/il indexes are okay.  If the underlying ir is     *|
00261 |*      is the same, then the ir is the same.                                 *|
00262 |*                                                                            *|
00263 |* Input parameters:                                                          *|
00264 |*      ir_idx1  -> Index to start of ir stream 1.                            *|
00265 |*      ir_idx2  -> Index to start of ir stream 2.                            *|
00266 |*                                                                            *|
00267 |* Output parameters:                                                         *|
00268 |*      NONE                                                                  *|
00269 |*                                                                            *|
00270 |* Returns:                                                                   *|
00271 |*      TRUE if the streams are exact matches, False otherwise.               *|
00272 |*      NOTE:  The line and column numbers do not have to match.              *|
00273 |*                                                                            *|
00274 \******************************************************************************/
00275 static boolean  compare_ir(int  ir_idx1,
00276                            int  ir_idx2)
00277 {
00278    boolean      matched;
00279    int          type1;
00280    int          type2;
00281 
00282    TRACE (Func_Entry, "compare_ir", NULL);
00283 
00284 
00285    /* BHJ - Try to optimize by using words, masks, and shifts rather than     */
00286    /*       field accesses.                                                   */
00287 
00288 
00289    type1 = IR_TYPE_IDX(ir_idx1);
00290    type2 = IR_TYPE_IDX(ir_idx2);
00291 
00292    if (IR_OPR(ir_idx1) == IR_OPR(ir_idx2) && type1 == type2 &&
00293        IR_FLD_L(ir_idx1) == IR_FLD_L(ir_idx2) &&
00294        IR_FLD_R(ir_idx1) == IR_FLD_R(ir_idx2)) {
00295 
00296       /* Operators, types, and fld types of both ir streams match.          */
00297       /* The indexes will match if they are both attribute or constant      */
00298       /* entries.  If they are IR or IL entries the indexes cannot match.   */
00299       /* Call appropriate compare routines to check.                        */
00300       /* Do the left side first, then the right side first.                 */
00301 
00302       if (IR_IDX_L(ir_idx1) == IR_IDX_L(ir_idx2)) {
00303          matched = TRUE;
00304       }
00305       else if (IR_FLD_L(ir_idx1) == IR_Tbl_Idx) { 
00306          matched = compare_ir(IR_IDX_L(ir_idx1), IR_IDX_L(ir_idx2));
00307       }
00308       else if (IR_FLD_L(ir_idx1) == IL_Tbl_Idx) {
00309          matched = compare_il(IR_IDX_L(ir_idx1), IR_IDX_L(ir_idx2),
00310                               IR_LIST_CNT_L(ir_idx1), IR_LIST_CNT_L(ir_idx2));
00311       }
00312       else {
00313          matched = FALSE;
00314       }
00315 
00316       if (matched) {  /* Try right side. */
00317 
00318          if (IR_IDX_R(ir_idx1) == IR_IDX_R(ir_idx2)) {
00319             matched = TRUE;
00320          }
00321          else if (IR_FLD_R(ir_idx1) == IR_Tbl_Idx) {
00322             matched = compare_ir(IR_IDX_R(ir_idx1), IR_IDX_R(ir_idx2));
00323          }
00324          else if (IR_FLD_R(ir_idx1) == IL_Tbl_Idx) {
00325             matched = compare_il(IR_IDX_R(ir_idx1), IR_IDX_R(ir_idx2),
00326                                  IR_LIST_CNT_R(ir_idx1),IR_LIST_CNT_R(ir_idx2));
00327          }
00328          else {
00329             matched = FALSE;
00330          }
00331       }
00332    }
00333    else {
00334       matched = FALSE;
00335    }
00336 
00337    TRACE (Func_Exit, "compare_ir", NULL);
00338 
00339    return(matched);
00340 
00341 }  /* compare_ir */
00342 
00343 /******************************************************************************\
00344 |*                                                                            *|
00345 |* Description:                                                               *|
00346 |*      compare_il takes 2 seperate il streams and compares them.  If the     *|
00347 |*      list items are the same then the lists are the same.  Different       *|
00348 |*      ir/il indexes are the same, as long as the underlying lists or ir     *|
00349 |*      streams are the same.                                                 *|
00350 |*                                                                            *|
00351 |* Input parameters:                                                          *|
00352 |*      il_idx1  -> Index to start of ir stream 1.                            *|
00353 |*      il_idx2  -> Index to start of ir stream 2.                            *|
00354 |*      list_cnt1-> # of items in list 1.                                     *|
00355 |*      list_cnt2-> # of items in list 2.                                     *|
00356 |*                                                                            *|
00357 |* Output parameters:                                                         *|
00358 |*      NONE                                                                  *|
00359 |*                                                                            *|
00360 |* Returns:                                                                   *|
00361 |*      TRUE if the streams are exact matches, False otherwise.               *|
00362 |*      NOTE:  The line and column numbers do not have to match.              *|
00363 |*                                                                            *|
00364 \******************************************************************************/
00365 static boolean  compare_il(int  il_idx1,
00366                            int  il_idx2,
00367                            int  list_cnt1,
00368                            int  list_cnt2)
00369 {
00370    boolean      matched;
00371 
00372 
00373    TRACE (Func_Entry, "compare_il", NULL);
00374 
00375    if (list_cnt1 != list_cnt2) {
00376       matched = FALSE;
00377    }
00378    else {
00379 
00380       do {
00381          if (IL_FLD(il_idx1) == IL_FLD(il_idx2)) {
00382 
00383             /* These fields are the same.  Now check indexes.  If the list  */
00384             /* item is ir or another list, the indexes will be different,   */
00385             /* so call the appropriate compare routines.                    */
00386 
00387             if (IL_IDX(il_idx1) == IL_IDX(il_idx2)) {
00388                matched = TRUE;
00389             }
00390             else if (IL_FLD(il_idx1) == IR_Tbl_Idx) { 
00391                matched = compare_ir(IL_IDX(il_idx1), IL_IDX(il_idx2));
00392             }
00393             else if (IL_FLD(il_idx1) == IL_Tbl_Idx) {
00394                matched = compare_il(IL_IDX(il_idx1), IL_IDX(il_idx2),
00395                                     IL_LIST_CNT(il_idx1), IL_LIST_CNT(il_idx2));
00396             }
00397             else {
00398                matched = FALSE;
00399             }
00400          }
00401          else {
00402             matched = FALSE;
00403          }
00404 
00405          il_idx1 = IL_NEXT_LIST_IDX(il_idx1);
00406          il_idx2 = IL_NEXT_LIST_IDX(il_idx2);
00407 
00408          /* List counts are the same, so only have to check for one to go NULL*/
00409          /* If one goes NULL before the other, the compiler is messed up.     */
00410 
00411       }  while (matched && il_idx1 != NULL_IDX);
00412    }
00413 
00414    TRACE (Func_Exit, "compare_il", NULL);
00415 
00416    return(matched);
00417 
00418 }  /* compare_il */
00419 
00420 /******************************************************************************\
00421 |*                                                                            *|
00422 |* Description:                                                               *|
00423 |*      free_ir_stream returns ir to the free list.                           *|
00424 |*                                                                            *|
00425 |* Input parameters:                                                          *|
00426 |*      ir_idx -> Start of ir stream to clear.                                *|
00427 |*                                                                            *|
00428 |* Output parameters:                                                         *|
00429 |*      NONE                                                                  *|
00430 |*                                                                            *|
00431 |* Returns:                                                                   *|
00432 |*      NONE                                                                  *|
00433 |*                                                                            *|
00434 \******************************************************************************/
00435 void    free_ir_stream(int      ir_idx)
00436 {
00437    TRACE (Func_Entry, "free_ir_stream", NULL);
00438 
00439    if (IR_FLD_L(ir_idx) == IR_Tbl_Idx) {
00440       free_ir_stream(IR_IDX_L(ir_idx));
00441    }
00442    else if (IR_FLD_L(ir_idx) == IL_Tbl_Idx) {
00443       free_ir_list(IR_IDX_L(ir_idx));
00444    }
00445    
00446    if (IR_FLD_R(ir_idx) == IR_Tbl_Idx) {
00447       free_ir_stream(IR_IDX_R(ir_idx));
00448    }
00449    else if (IR_FLD_R(ir_idx) == IL_Tbl_Idx) {
00450       free_ir_list(IR_IDX_R(ir_idx));
00451    }
00452 
00453    FREE_IR_NODE(ir_idx);
00454 
00455    TRACE (Func_Exit, "free_ir_stream", NULL);
00456 
00457    return;
00458 
00459 }  /* free_ir_stream */
00460 
00461 /******************************************************************************\
00462 |*                                                                            *|
00463 |* Description:                                                               *|
00464 |*      free_ir_list returns il to the free list.                             *|
00465 |*                                                                            *|
00466 |* Input parameters:                                                          *|
00467 |*      il_idx   -> Start of ir stream to clear.                              *|
00468 |*                                                                            *|
00469 |* Output parameters:                                                         *|
00470 |*      NONE                                                                  *|
00471 |*                                                                            *|
00472 |* Returns:                                                                   *|
00473 |*      NONE                                                                  *|
00474 |*                                                                            *|
00475 \******************************************************************************/
00476 void    free_ir_list(int        il_idx)
00477 {
00478    int          next_il;
00479 
00480 
00481    TRACE (Func_Entry, "free_ir_list", NULL);
00482 
00483    while (il_idx != NULL_IDX) {
00484 
00485       if (IL_FLD(il_idx) == IR_Tbl_Idx) {
00486          free_ir_stream(IL_IDX(il_idx));
00487       }
00488       else if (IL_FLD(il_idx) == IL_Tbl_Idx) {
00489          free_ir_list(IL_IDX(il_idx));
00490       }
00491 
00492       next_il = IL_NEXT_LIST_IDX(il_idx);
00493       FREE_IR_LIST_NODE(il_idx);
00494       il_idx = next_il;
00495    }
00496 
00497    TRACE (Func_Exit, "free_ir_list", NULL);
00498 
00499    return;
00500 
00501 }  /* free_ir_list */
00502 
00503 /******************************************************************************\
00504 |*                                                                            *|
00505 |* Description:                                                               *|
00506 |*      Create new ir, sh or il entries that are a copy of the input entry.   *|
00507 |*                                                                            *|
00508 |* Input parameters:                                                          *|
00509 |*      idx     table idx of entry to be copied.                              *|
00510 |*      fld     fld type of idx.                                              *|
00511 |*                                                                            *|
00512 |* Output parameters:                                                         *|
00513 |*      NONE                                                                  *|
00514 |*                                                                            *|
00515 |* Returns:                                                                   *|
00516 |*      idx of new entry, same fld type as the input idx.                     *|
00517 |*                                                                            *|
00518 \******************************************************************************/
00519 
00520 void copy_subtree(opnd_type     *old_opnd,
00521                   opnd_type     *new_opnd)
00522 
00523 {
00524    int          idx;
00525    int          list_idx;
00526    int          list2_idx;
00527    int          new_root = NULL_IDX;
00528    opnd_type    opnd_o;
00529    opnd_type    opnd_n;
00530 
00531 
00532    TRACE (Func_Entry, "copy_subtree", NULL);
00533 
00534    COPY_OPND((*new_opnd), (*old_opnd));
00535    idx = OPND_IDX((*old_opnd));
00536 
00537    if (idx) {
00538 
00539       switch(OPND_FLD((*old_opnd))) {
00540 
00541          case NO_Tbl_Idx   :
00542             break;
00543 
00544          case IR_Tbl_Idx :
00545             
00546             if (IR_OPR(idx) == Stmt_Expansion_Opr) {
00547                /* just copy the left opnd */
00548 
00549                COPY_OPND(opnd_o, IR_OPND_L(idx));
00550                copy_subtree(&opnd_o, &opnd_n);
00551                COPY_OPND((*new_opnd), opnd_n);
00552             }
00553             else {
00554                NTR_IR_TBL(new_root);
00555 
00556                COPY_TBL_NTRY(ir_tbl, new_root, idx);
00557                OPND_IDX((*new_opnd)) = new_root;
00558 
00559                COPY_OPND(opnd_o, IR_OPND_L(idx));
00560                copy_subtree(&opnd_o, &opnd_n);
00561                COPY_OPND(IR_OPND_L(new_root), opnd_n);
00562 
00563                COPY_OPND(opnd_o, IR_OPND_R(idx));
00564                copy_subtree(&opnd_o, &opnd_n);
00565                COPY_OPND(IR_OPND_R(new_root), opnd_n);
00566             }
00567             break;
00568 
00569          case AT_Tbl_Idx :
00570 
00571             if (gen_lbl_copy &&
00572                 AT_OBJ_CLASS(idx) == Label &&
00573                 ATL_CLASS(idx) == Lbl_Internal) {
00574 
00575                if (ATL_NEW_LBL_IDX(idx) == NULL_IDX) {
00576                   /* gen a new label */
00577                   ATL_NEW_LBL_IDX(idx) = gen_internal_lbl(AT_DEF_LINE(idx));
00578 
00579                   NTR_ATTR_LIST_TBL(list_idx);
00580                   AL_ATTR_IDX(list_idx) = idx;
00581 
00582                   AL_NEXT_IDX(list_idx) = label_copy_al_idx;
00583 
00584                   label_copy_al_idx = list_idx;
00585                }
00586 
00587                OPND_IDX((*new_opnd)) = ATL_NEW_LBL_IDX(idx);
00588             }
00589             break;
00590 
00591          case CN_Tbl_Idx :
00592             break;
00593 
00594          case SH_Tbl_Idx :
00595 
00596             new_root    = ntr_sh_tbl();
00597 
00598             COPY_TBL_NTRY(sh_tbl, new_root, idx);
00599 
00600             OPND_FLD(opnd_o) = IR_Tbl_Idx;
00601             OPND_IDX(opnd_o) = SH_IR_IDX(idx);
00602             copy_subtree(&opnd_o, &opnd_n);
00603             SH_IR_IDX(new_root) = OPND_IDX(opnd_n);
00604             OPND_IDX((*new_opnd)) = new_root;
00605             break;
00606 
00607          case IL_Tbl_Idx :
00608 
00609             NTR_IR_LIST_TBL(new_root);
00610 
00611             COPY_TBL_NTRY(ir_list_tbl, new_root, idx);
00612             OPND_IDX((*new_opnd)) = new_root;
00613 
00614             COPY_OPND(opnd_o, IL_OPND(idx));
00615             copy_subtree(&opnd_o, &opnd_n);
00616             COPY_OPND(IL_OPND(new_root), opnd_n);
00617 
00618             list2_idx        = new_root;
00619 
00620             idx              = IL_NEXT_LIST_IDX(idx);
00621 
00622             while (idx != NULL_IDX) {
00623                NTR_IR_LIST_TBL(list_idx);
00624 
00625                COPY_TBL_NTRY(ir_list_tbl, list_idx, idx);
00626 
00627                if (! IL_ARG_DESC_VARIANT(idx)) {
00628                   IL_PREV_LIST_IDX(list_idx)  = list2_idx;
00629                }
00630 
00631                IL_NEXT_LIST_IDX(list2_idx) = list_idx;
00632                list2_idx                   = list_idx;
00633 
00634                COPY_OPND(opnd_o, IL_OPND(idx));
00635                copy_subtree(&opnd_o, &opnd_n);
00636                COPY_OPND(IL_OPND(list_idx), opnd_n);
00637 
00638                idx              = IL_NEXT_LIST_IDX(idx);
00639             }
00640             break;
00641       }
00642    }
00643 
00644    TRACE (Func_Exit, "copy_subtree", NULL);
00645 
00646    return;
00647 
00648 }  /* copy_subtree */
00649 
00650 /******************************************************************************\
00651 |*                                                                            *|
00652 |* Description:                                                               *|
00653 |*      Create new ir, sh or il entries that are a copy of the input entry.   *|
00654 |*                                                                            *|
00655 |* Input parameters:                                                          *|
00656 |*      idx     table idx of entry to be copied.                              *|
00657 |*      fld     fld type of idx.                                              *|
00658 |*                                                                            *|
00659 |* Output parameters:                                                         *|
00660 |*      NONE                                                                  *|
00661 |*                                                                            *|
00662 |* Returns:                                                                   *|
00663 |*      idx of new entry, same fld type as the input idx.                     *|
00664 |*                                                                            *|
00665 \******************************************************************************/
00666 
00667 int copy_to_gl_subtree(int      idx,
00668                  fld_type fld)
00669 
00670 {
00671    int          new_idx;
00672    int          list_idx;
00673    int          list2_idx;
00674    int          name_idx;
00675    int          new_root = NULL_IDX;
00676 
00677 
00678    TRACE (Func_Entry, "copy_to_gl_subtree", NULL);
00679 
00680    if (idx != NULL_IDX) {
00681 
00682       switch(fld) {
00683 
00684          case NO_Tbl_Idx   :
00685             break;
00686 
00687          case IR_Tbl_Idx :
00688 
00689             NTR_GL_IR_TBL(new_root);
00690 
00691             COPY_GL_TBL_NTRY(global_ir_tbl, ir_tbl, new_root, idx);
00692 
00693             new_idx = copy_to_gl_subtree(IR_IDX_L(idx), IR_FLD_L(idx));
00694             GL_IR_IDX_L(new_root) = new_idx;
00695 
00696             new_idx = copy_to_gl_subtree(IR_IDX_R(idx), IR_FLD_R(idx));
00697             GL_IR_IDX_R(new_root) = new_idx;
00698 
00699             break;
00700 
00701          case AT_Tbl_Idx :
00702 
00703             if (srch_global_name_tbl(AT_OBJ_NAME_PTR(idx),
00704                             AT_NAME_LEN(idx),
00705                             &name_idx)) {
00706             }
00707             else {
00708                ntr_global_name_tbl(idx, NULL_IDX, name_idx);
00709             }
00710 
00711             new_root = GN_ATTR_IDX(name_idx);
00712             break;
00713 
00714          case CN_Tbl_Idx :
00715 
00716             /* Until we have a global constant table, I'm using this big */
00717             /* KLUDGE. This assumes that any constant will be integer and*/
00718             /* will fit in 24 bits.                                      */
00719 
00720 # ifdef _DEBUG
00721             if (TYP_TYPE(CN_TYPE_IDX(idx)) != Integer) {
00722                PRINTMSG(stmt_start_line, 626, Internal, stmt_start_col,
00723                         "Integer constant", "copy_to_gl_subtree");
00724             }
00725 # endif
00726 
00727             new_root = CN_INT_TO_C(idx);  /* KAY - BRIANJ */
00728             break;
00729 
00730          case SH_Tbl_Idx :
00731 
00732             new_root    = ntr_gl_sh_tbl();
00733 
00734             COPY_GL_TBL_NTRY(global_sh_tbl, sh_tbl, new_root, idx);
00735 
00736             new_idx = copy_to_gl_subtree(SH_IR_IDX(idx), IR_Tbl_Idx);
00737             GL_SH_IR_IDX(new_root) = new_idx;
00738             break;
00739 
00740          case IL_Tbl_Idx :
00741 
00742             NTR_GL_IR_LIST_TBL(new_root);
00743 
00744             COPY_GL_TBL_NTRY(global_ir_list_tbl, ir_list_tbl, new_root, idx);
00745 
00746             new_idx = copy_to_gl_subtree(IL_IDX(idx), IL_FLD(idx));
00747             GL_IL_IDX(new_root) = new_idx;
00748             list2_idx        = new_root;
00749 
00750             idx              = IL_NEXT_LIST_IDX(idx);
00751 
00752             while (idx != NULL_IDX) {
00753                NTR_GL_IR_LIST_TBL(list_idx);
00754 
00755                COPY_GL_TBL_NTRY(global_ir_list_tbl, ir_list_tbl, list_idx, idx);
00756 
00757                if (! IL_ARG_DESC_VARIANT(idx)) {
00758                   GL_IL_PREV_LIST_IDX(list_idx)  = list2_idx;
00759                }
00760 
00761                GL_IL_NEXT_LIST_IDX(list2_idx) = list_idx;
00762                list2_idx                   = list_idx;
00763 
00764                new_idx = copy_to_gl_subtree(IL_IDX(idx), IL_FLD(idx));
00765                GL_IL_IDX(list_idx) = new_idx;
00766                idx              = IL_NEXT_LIST_IDX(idx);
00767             }
00768             break;
00769       }
00770    }
00771 
00772    TRACE (Func_Exit, "copy_to_gl_subtree", NULL);
00773 
00774    return(new_root);
00775 
00776 }  /* copy_to_gl_subtree */
00777 
00778 /******************************************************************************\
00779 |*                                                                            *|
00780 |* Description:                                                               *|
00781 |*      Create new ir, sh or il entries that are a copy of the input entry.   *|
00782 |*                                                                            *|
00783 |* Input parameters:                                                          *|
00784 |*      idx     table idx of entry to be copied.                              *|
00785 |*      fld     fld type of idx.                                              *|
00786 |*                                                                            *|
00787 |* Output parameters:                                                         *|
00788 |*      NONE                                                                  *|
00789 |*                                                                            *|
00790 |* Returns:                                                                   *|
00791 |*      idx of new entry, same fld type as the input idx.                     *|
00792 |*                                                                            *|
00793 \******************************************************************************/
00794 
00795 int copy_from_gl_subtree(int      idx,
00796                  fld_type fld)
00797 
00798 {
00799    int          new_idx;
00800    int          list_idx;
00801    int          list2_idx;
00802    int          name_idx;
00803    int          new_root = NULL_IDX;
00804    long_type    the_constant;
00805 
00806 
00807    TRACE (Func_Entry, "copy_from_gl_subtree", NULL);
00808 
00809    if (idx != NULL_IDX) {
00810 
00811       switch(fld) {
00812 
00813          case NO_Tbl_Idx   :
00814             break;
00815 
00816          case IR_Tbl_Idx :
00817 
00818             NTR_IR_TBL(new_root);
00819 
00820             COPY_GL_TBL_NTRY(ir_tbl, global_ir_tbl, new_root, idx);
00821 
00822             new_idx = copy_from_gl_subtree(GL_IR_IDX_L(idx), GL_IR_FLD_L(idx));
00823             IR_IDX_L(new_root) = new_idx;
00824 
00825             new_idx = copy_from_gl_subtree(GL_IR_IDX_R(idx), GL_IR_FLD_R(idx));
00826             IR_IDX_R(new_root) = new_idx;
00827 
00828             break;
00829 
00830          case AT_Tbl_Idx :
00831 
00832             new_root = srch_sym_tbl(GA_OBJ_NAME_PTR(idx),
00833                                     GA_NAME_LEN(idx),
00834                                     &name_idx);
00835 
00836             /* it had better be there */
00837             break;
00838 
00839          case CN_Tbl_Idx :
00840 
00841             /* Until we have a global constant table, I'm using this big */
00842             /* KLUDGE. This assumes that any constant will be integer and*/
00843             /* will fit in 24 bits.                                      */
00844 
00845             /* BRIANJ */
00846 
00847             the_constant = idx;
00848             new_root = ntr_const_tbl(CG_INTEGER_DEFAULT_TYPE,
00849                                      FALSE,
00850                                     &the_constant);
00851 
00852             break;
00853 
00854          case SH_Tbl_Idx :
00855 
00856             new_root    = ntr_sh_tbl();
00857 
00858             COPY_GL_TBL_NTRY(sh_tbl, global_sh_tbl, new_root, idx);
00859 
00860             new_idx = copy_from_gl_subtree(GL_SH_IR_IDX(idx), IR_Tbl_Idx);
00861             SH_IR_IDX(new_root) = new_idx;
00862 
00863             SH_COMPILER_GEN(new_root) = TRUE;
00864             break;
00865 
00866          case IL_Tbl_Idx :
00867 
00868             NTR_IR_LIST_TBL(new_root);
00869 
00870             COPY_GL_TBL_NTRY(ir_list_tbl, global_ir_list_tbl, new_root, idx);
00871 
00872             new_idx = copy_from_gl_subtree(GL_IL_IDX(idx), GL_IL_FLD(idx));
00873             IL_IDX(new_root) = new_idx;
00874             list2_idx        = new_root;
00875 
00876             idx              = GL_IL_NEXT_LIST_IDX(idx);
00877 
00878             while (idx != NULL_IDX) {
00879                NTR_IR_LIST_TBL(list_idx);
00880 
00881                COPY_GL_TBL_NTRY(ir_list_tbl, global_ir_list_tbl, list_idx, idx);
00882 
00883                if (! GL_IL_ARG_DESC_VARIANT(idx)) {
00884                   IL_PREV_LIST_IDX(list_idx)  = list2_idx;
00885                }
00886 
00887                IL_NEXT_LIST_IDX(list2_idx) = list_idx;
00888                list2_idx                   = list_idx;
00889 
00890                new_idx = copy_from_gl_subtree(GL_IL_IDX(idx), GL_IL_FLD(idx));
00891                IL_IDX(list_idx) = new_idx;
00892                idx              = GL_IL_NEXT_LIST_IDX(idx);
00893             }
00894             break;
00895       }
00896    }
00897 
00898    TRACE (Func_Exit, "copy_from_gl_subtree", NULL);
00899 
00900    return(new_root);
00901 
00902 }  /* copy_from_gl_subtree */
00903 
00904 /******************************************************************************\
00905 |*                                                                            *|
00906 |* Description:                                                               *|
00907 |*      Insert a stmt header chain at the current scps main entry and then    *|
00908 |*      copy it at every other entry.                                         *|
00909 |*      It puts the original chain after the main entry.                      *|
00910 |*                                                                            *|
00911 |* Input parameters:                                                          *|
00912 |*      head_idx, tail_idx - indexes of beginning and end of chain.           *|
00913 |*                                                                            *|
00914 |* Output parameters:                                                         *|
00915 |*      NONE                                                                  *|
00916 |*                                                                            *|
00917 |* Returns:                                                                   *|
00918 |*      NOTHING                                                               *|
00919 |*                                                                            *|
00920 \******************************************************************************/
00921 
00922 void insert_sh_chain_after_entries(int  head_idx,
00923                                    int  tail_idx)
00924 
00925 {
00926    int          entry_idx;
00927    int          entry_sh_idx;
00928    int          idx;
00929    int          next_sh_idx;
00930    int          new_end_sh_idx;
00931    int          new_start_sh_idx;
00932 
00933 
00934    TRACE (Func_Entry, "insert_sh_chain_after_entries", NULL);
00935 
00936    SH_NEXT_IDX(tail_idx) = SH_NEXT_IDX(SCP_FIRST_SH_IDX(curr_scp_idx));
00937    SH_PREV_IDX(head_idx) = SCP_FIRST_SH_IDX(curr_scp_idx);
00938    SH_NEXT_IDX(SCP_FIRST_SH_IDX(curr_scp_idx)) = head_idx;
00939    SH_PREV_IDX(SH_NEXT_IDX(tail_idx))          = tail_idx;
00940 
00941    idx    = SCP_ENTRY_IDX(curr_scp_idx);
00942 
00943    while (idx != NULL_IDX) {
00944       /* copy sh chain after each entry opr */
00945 
00946       entry_idx = AL_ATTR_IDX(idx);
00947 
00948       entry_sh_idx           = ATP_FIRST_SH_IDX(entry_idx);
00949       next_sh_idx            = SH_NEXT_IDX(entry_sh_idx);
00950 
00951       copy_entry_exit_sh_list(head_idx,
00952                               tail_idx,
00953                              &new_start_sh_idx,
00954                              &new_end_sh_idx);
00955 
00956       SH_NEXT_IDX(entry_sh_idx)     = new_start_sh_idx;
00957       SH_PREV_IDX(new_start_sh_idx) = entry_sh_idx;
00958 
00959       SH_PREV_IDX(next_sh_idx) = new_end_sh_idx;
00960       SH_NEXT_IDX(new_end_sh_idx) = next_sh_idx;
00961 
00962       idx = AL_NEXT_IDX(idx);
00963    }
00964 
00965 
00966    TRACE (Func_Exit, "insert_sh_chain_after_entries", NULL);
00967 
00968    return;
00969 
00970 }  /* insert_sh_chain_after_entries */
00971 
00972 /******************************************************************************\
00973 |*                                                                            *|
00974 |* Description:                                                               *|
00975 |*      inserts an sh chain Before or After curr_stmt_sh_idx.                 *|
00976 |*                                                                            *|
00977 |* Input parameters:                                                          *|
00978 |*      NONE                                                                  *|
00979 |*                                                                            *|
00980 |* Output parameters:                                                         *|
00981 |*      NONE                                                                  *|
00982 |*                                                                            *|
00983 |* Returns:                                                                   *|
00984 |*      NOTHING                                                               *|
00985 |*                                                                            *|
00986 \******************************************************************************/
00987 
00988 void insert_sh_chain(int                start_idx,
00989                      int                end_idx,
00990                      sh_position_type   position)
00991 
00992 {
00993 
00994 
00995    TRACE (Func_Entry, "insert_sh_chain", NULL);
00996 
00997    if (position == Before) {
00998       if (SH_PREV_IDX(curr_stmt_sh_idx) != NULL_IDX) {
00999          SH_NEXT_IDX(SH_PREV_IDX(curr_stmt_sh_idx)) = start_idx;
01000       }
01001       SH_PREV_IDX(start_idx) = SH_PREV_IDX(curr_stmt_sh_idx);
01002 
01003       SH_PREV_IDX(curr_stmt_sh_idx) = end_idx;
01004       SH_NEXT_IDX(end_idx)          = curr_stmt_sh_idx;
01005    }
01006    else {
01007       SH_PREV_IDX(start_idx) = curr_stmt_sh_idx;
01008       SH_NEXT_IDX(end_idx) = SH_NEXT_IDX(curr_stmt_sh_idx);
01009       if (SH_NEXT_IDX(curr_stmt_sh_idx) != NULL_IDX) {
01010          SH_PREV_IDX(SH_NEXT_IDX(curr_stmt_sh_idx)) = end_idx;
01011       }
01012       SH_NEXT_IDX(curr_stmt_sh_idx) = start_idx;
01013    }
01014 
01015    TRACE (Func_Exit, "insert_sh_chain", NULL);
01016 
01017    return;
01018 
01019 }  /* insert_sh_chain */
01020 
01021 /******************************************************************************\
01022 |*                                                                            *|
01023 |* Description:                                                               *|
01024 |*      compare_opnds is the driver for compare_il and compare_ir.  It takes  *|
01025 |*      as input 2 operands.  First the fields are checked.  If they are      *|
01026 |*      different, FALSE is returned.  If they are the same, then if they     *|
01027 |*      are IR entries, compare_ir is called.  If they are list entries,      *|
01028 |*      compare_il is called.  Otherwise, if the indexes are the same,        *|
01029 |*      TRUE is returned.                                                     *|
01030 |*                                                                            *|
01031 |* Input parameters:                                                          *|
01032 |*      opnd1  -> Ptr to first operand to compare.                            *|
01033 |*      opnd2  -> Ptr to second operand to compare.                           *|
01034 |*                                                                            *|
01035 |* Output parameters:                                                         *|
01036 |*      NONE                                                                  *|
01037 |*                                                                            *|
01038 |* Returns:                                                                   *|
01039 |*      TRUE if the operands are the same.                                    *|
01040 |*                                                                            *|
01041 \******************************************************************************/
01042 boolean compare_opnds(opnd_type         *opnd1,
01043                       opnd_type         *opnd2)
01044 {
01045    boolean      matched;
01046 
01047    TRACE (Func_Entry, "compare_opnds", NULL);
01048 
01049    if (OPND_FLD((*opnd1)) != OPND_FLD((*opnd2))) {
01050       matched = FALSE;
01051    }
01052    else {
01053 
01054       switch (OPND_FLD((*opnd1))) {
01055 
01056          case IR_Tbl_Idx:
01057             matched = compare_ir(OPND_IDX((*opnd1)), OPND_IDX((*opnd2)));
01058             break;
01059 
01060          case IL_Tbl_Idx:
01061             matched = compare_il(OPND_IDX((*opnd1)),
01062                                  OPND_IDX((*opnd2)),
01063                                  OPND_LIST_CNT((*opnd1)),
01064                                  OPND_LIST_CNT((*opnd2)));
01065             break;
01066 
01067          default:
01068             matched = OPND_IDX((*opnd1)) == OPND_IDX((*opnd2));
01069             break;
01070       }
01071    }
01072 
01073    TRACE (Func_Exit, "compare_opnds", NULL);
01074 
01075    return(matched);
01076 
01077 }  /* compare_opnds */
01078 
01079 /******************************************************************************\
01080 |*                                                                            *|
01081 |* Description:                                                               *|
01082 |*      This routine inserts an sh chain before the curr_stmt_sh_idx.         *|
01083 |*      It searches from the input sh idx to find the beginning and end       *|
01084 |*      of the chain.                                                         *|
01085 |*                                                                            *|
01086 |* Input parameters:                                                          *|
01087 |*      sh_idx - idx of some sh node within the chain.                        *|
01088 |*                                                                            *|
01089 |* Output parameters:                                                         *|
01090 |*      NONE                                                                  *|
01091 |*                                                                            *|
01092 |* Returns:                                                                   *|
01093 |*      NOTHING                                                               *|
01094 |*                                                                            *|
01095 \******************************************************************************/
01096 
01097 void insert_sh_chain_before(int         sh_idx)
01098 
01099 {
01100    int          start_idx;
01101    int          end_idx;
01102 
01103    TRACE (Func_Entry, "insert_sh_chain_before", NULL);
01104 
01105    start_idx = sh_idx;
01106    while (SH_PREV_IDX(start_idx)) {
01107       start_idx = SH_PREV_IDX(start_idx);
01108    }
01109 
01110    end_idx = sh_idx;
01111    while (SH_NEXT_IDX(end_idx)) {
01112       end_idx = SH_NEXT_IDX(end_idx);
01113    }
01114 
01115    insert_sh_chain(start_idx, end_idx, Before);
01116 
01117    TRACE (Func_Exit, "insert_sh_chain_before", NULL);
01118 
01119    return;
01120 
01121 }  /* insert_sh_chain_before */
01122 
01123 /******************************************************************************\
01124 |*                                                                            *|
01125 |* Description:                                                               *|
01126 |*      Go through an ir stream, looking for the specified attr.              *|
01127 |*                                                                            *|
01128 |* Input parameters:                                                          *|
01129 |*      attr_idx        - attr_idx to search for.                             *|
01130 |*      ir_idx          - ir to search.                                       *|
01131 |*                                                                            *|
01132 |* Output parameters:                                                         *|
01133 |*      *opnd           - Place to copy ir information to, when it's found.   *|
01134 |*                                                                            *|
01135 |* Returns:                                                                   *|
01136 |*      TRUE if attr is found, else FALSE                                     *|
01137 |*                                                                            *|
01138 \******************************************************************************/
01139 
01140 boolean find_attr_in_ir(int              attr_idx,
01141                         int              ir_idx,
01142                         opnd_type       *opnd)
01143 {
01144 
01145    TRACE (Func_Entry, "find_attr_in_ir", NULL);
01146 
01147    switch (IR_FLD_L(ir_idx)) {
01148    case AT_Tbl_Idx:
01149 
01150       if (IR_IDX_L(ir_idx) == attr_idx) {
01151          COPY_OPND((*opnd), IR_OPND_L(ir_idx));
01152          return(TRUE);
01153       }
01154       break;
01155 
01156    case IR_Tbl_Idx:
01157 
01158       if (find_attr_in_ir(attr_idx, IR_IDX_L(ir_idx), opnd)) {
01159          return(TRUE);
01160       }
01161       break;
01162 
01163    case IL_Tbl_Idx:
01164 
01165       if (find_attr_in_il(attr_idx, IR_IDX_L(ir_idx), opnd)) {
01166          return(TRUE);
01167       }
01168       break;
01169 
01170    case CN_Tbl_Idx:
01171    case NO_Tbl_Idx:
01172    case SH_Tbl_Idx:
01173       break;
01174    }
01175 
01176    switch (IR_FLD_R(ir_idx)) {
01177    case AT_Tbl_Idx:
01178 
01179       if (IR_IDX_R(ir_idx) == attr_idx) {
01180          COPY_OPND((*opnd), IR_OPND_R(ir_idx));
01181          return(TRUE);
01182       }
01183       break;
01184 
01185    case IR_Tbl_Idx:
01186 
01187       if (find_attr_in_ir(attr_idx, IR_IDX_R(ir_idx), opnd)) {
01188          return(TRUE);
01189       }
01190       break;
01191 
01192    case IL_Tbl_Idx:
01193 
01194       if (find_attr_in_il(attr_idx, IR_IDX_R(ir_idx), opnd)) {
01195          return(TRUE);
01196       }
01197       break;
01198 
01199    case CN_Tbl_Idx:
01200    case NO_Tbl_Idx:
01201    case SH_Tbl_Idx:
01202       break;
01203    }
01204 
01205    TRACE (Func_Exit, "find_attr_in_ir", NULL);
01206 
01207    return(FALSE);
01208 
01209 }  /* find_attr_in_ir */
01210 
01211 /******************************************************************************\
01212 |*                                                                            *|
01213 |* Description:                                                               *|
01214 |*      Go through an il, looking for the specified attr.                     *|
01215 |*                                                                            *|
01216 |* Input parameters:                                                          *|
01217 |*      attr_idx        - attr_idx to search for.                             *|
01218 |*      il_idx          - il to search.                                       *|
01219 |*                                                                            *|
01220 |* Output parameters:                                                         *|
01221 |*      *opnd           - Place to copy il information to, when it's found.   *|
01222 |*                                                                            *|
01223 |* Returns:                                                                   *|
01224 |*      TRUE if attr is found, else FALSE                                     *|
01225 |*                                                                            *|
01226 \******************************************************************************/
01227 
01228 boolean find_attr_in_il(int              attr_idx,
01229                         int              il_idx,
01230                         opnd_type       *opnd)
01231 {
01232 
01233    TRACE (Func_Entry, "find_attr_in_il", NULL);
01234 
01235    while (il_idx != NULL_IDX) {
01236 
01237       switch (IL_FLD(il_idx)) {
01238 
01239       case AT_Tbl_Idx:
01240 
01241          if (IL_IDX(il_idx) == attr_idx) {
01242             COPY_OPND((*opnd), IL_OPND(il_idx));
01243             return(TRUE);
01244          }
01245          break;
01246 
01247       case IR_Tbl_Idx:
01248 
01249          if (find_attr_in_ir(attr_idx, IL_IDX(il_idx), opnd)) {
01250             return(TRUE);
01251          }
01252          break;
01253 
01254       case IL_Tbl_Idx:
01255 
01256          if (find_attr_in_il(attr_idx, IL_IDX(il_idx), opnd)) {
01257             return(TRUE);
01258          }
01259          break;
01260 
01261       case CN_Tbl_Idx:
01262       case NO_Tbl_Idx:
01263       case SH_Tbl_Idx:
01264          break;
01265       }
01266 
01267       il_idx = IL_NEXT_LIST_IDX(il_idx);
01268    }
01269 
01270    TRACE (Func_Exit, "find_attr_in_il", NULL);
01271 
01272    return(FALSE);
01273 
01274 }  /* find_attr_in_il */
01275 
01276 /******************************************************************************\
01277 |*                                                                            *|
01278 |* Description:                                                               *|
01279 |*      expr_is_symbolic_constant checks the expression and returns TRUE      *|
01280 |*      if this expression meets the criteria for a symbolic constant.        *|
01281 |*      If this expression is a symbolic constant, the operators are changed. *|
01282 |*      A correct expression contains only plus, minus, multiply, divide,     *|
01283 |*      unary plus and unary minus.                                           *|
01284 |*                                                                            *|
01285 |*      Assumption:  This is an integer expression.                           *|
01286 |*                                                                            *|
01287 |* Input parameters:                                                          *|
01288 |*      *opnd - A ptr to the expression to check.                             *|
01289 |*                                                                            *|
01290 |* Output parameters:                                                         *|
01291 |*      *opnd - Will contain an expression with correct symbolic constant     *|
01292 |*              operators.                                                    *|
01293 |*                                                                            *|
01294 |* Returns:                                                                   *|
01295 |*      TRUE if this is a symbolic constant, else FALSE.                      *|
01296 |*                                                                            *|
01297 \******************************************************************************/
01298 boolean expr_is_symbolic_constant(opnd_type     *opnd)
01299 
01300 {
01301    int          idx;
01302    opnd_type    loc_opnd;
01303    opnd_type    new_opnd;
01304    boolean      symbolic;
01305 
01306 
01307    TRACE (Func_Entry, "expr_is_symbolic_constant", NULL);
01308 
01309    switch (OPND_FLD((*opnd))) {
01310    case CN_Tbl_Idx:
01311       symbolic  = TRUE;
01312       break;
01313 
01314    case IL_Tbl_Idx:
01315       COPY_OPND(loc_opnd, (*opnd));
01316       copy_subtree(&loc_opnd, &new_opnd);
01317       idx = OPND_IDX(new_opnd);
01318       symbolic  = il_is_symbolic_constant(idx);
01319 
01320       if (symbolic) {
01321          OPND_IDX((*opnd)) = idx;
01322       }
01323       else {
01324          free_ir_list(idx);
01325       }
01326       break;
01327 
01328    case IR_Tbl_Idx:
01329       COPY_OPND(loc_opnd, (*opnd));
01330       copy_subtree(&loc_opnd, &new_opnd);
01331       idx = OPND_IDX(new_opnd);
01332       symbolic  = ir_is_symbolic_constant(idx);
01333 
01334       if (symbolic) {
01335          OPND_IDX((*opnd)) = idx;
01336       }
01337       else {
01338          free_ir_stream(idx);
01339       }
01340       break;
01341 
01342    case AT_Tbl_Idx:
01343       symbolic = (AT_OBJ_CLASS(OPND_IDX((*opnd))) == Data_Obj &&
01344                   (ATD_SYMBOLIC_CONSTANT(OPND_IDX((*opnd))) ||
01345                   (ATD_CLASS(OPND_IDX((*opnd))) == Constant &&
01346                    ATD_FLD(OPND_IDX((*opnd))) == CN_Tbl_Idx)));
01347       break;
01348 
01349    case SH_Tbl_Idx:
01350       symbolic  = FALSE;
01351       break;
01352 
01353    default:
01354       symbolic  = FALSE;
01355       break;
01356    }
01357 
01358    TRACE (Func_Exit, "expr_is_symbolic_constant", NULL);
01359 
01360    return(symbolic);
01361 
01362 }  /* expr_is_symbolic_constant */
01363 
01364 /******************************************************************************\
01365 |*                                                                            *|
01366 |* Description:                                                               *|
01367 |*      Go through an ir stream, checking to see if it is a symbolic constant *|
01368 |*                                                                            *|
01369 |* Input parameters:                                                          *|
01370 |*      ir_idx          - ir to search.                                       *|
01371 |*                                                                            *|
01372 |* Output parameters:                                                         *|
01373 |*      NONE                                                                  *|
01374 |*                                                                            *|
01375 |* Returns:                                                                   *|
01376 |*      TRUE if ir stream is a symbolic constant.  FALSE otherwise.           *|
01377 |*                                                                            *|
01378 \******************************************************************************/
01379 static  boolean ir_is_symbolic_constant(int              ir_idx)
01380 
01381 {
01382    boolean      symbolic;
01383 
01384 
01385    TRACE (Func_Entry, "ir_is_symbolic_constant", NULL);
01386 
01387    switch (IR_OPR(ir_idx)) {
01388    case Mult_Opr:
01389       IR_OPR(ir_idx)    = Symbolic_Mult_Opr;
01390       break;
01391 
01392    case Div_Opr:
01393       IR_OPR(ir_idx)    = Symbolic_Div_Opr;
01394       break;
01395 
01396    case Uplus_Opr:
01397       IR_OPR(ir_idx)    = Symbolic_Uplus_Opr;
01398       break;
01399 
01400    case Uminus_Opr:
01401       IR_OPR(ir_idx)    = Symbolic_Uminus_Opr;
01402       break;
01403 
01404    case Plus_Opr:
01405       IR_OPR(ir_idx)    = Symbolic_Plus_Opr;
01406       break;
01407 
01408    case Minus_Opr:
01409       IR_OPR(ir_idx)    = Symbolic_Minus_Opr;
01410       break;
01411 
01412    default:
01413       symbolic = FALSE;
01414       goto EXIT;
01415    }
01416 
01417    switch (IR_FLD_L(ir_idx)) {
01418    case AT_Tbl_Idx:
01419       symbolic = (AT_OBJ_CLASS(IR_IDX_L(ir_idx)) == Data_Obj &&
01420                   (ATD_SYMBOLIC_CONSTANT(IR_IDX_L(ir_idx)) ||
01421                   (ATD_CLASS(IR_IDX_L(ir_idx)) == Constant &&
01422                    ATD_FLD(IR_IDX_L(ir_idx)) == CN_Tbl_Idx)));
01423       break;
01424 
01425    case IR_Tbl_Idx:
01426       symbolic = ir_is_symbolic_constant(IR_IDX_L(ir_idx));
01427       break;
01428 
01429    case IL_Tbl_Idx:
01430       symbolic = il_is_symbolic_constant(IR_IDX_L(ir_idx));
01431       break;
01432 
01433    case CN_Tbl_Idx:
01434    case NO_Tbl_Idx:
01435       symbolic  = TRUE;
01436       break;
01437 
01438    case SH_Tbl_Idx:
01439    default:
01440       symbolic  = FALSE;
01441       break;
01442    }
01443 
01444    if (symbolic) {
01445 
01446       switch (IR_FLD_R(ir_idx)) {
01447       case AT_Tbl_Idx:
01448          symbolic = (AT_OBJ_CLASS(IR_IDX_R(ir_idx)) == Data_Obj &&
01449                      (ATD_SYMBOLIC_CONSTANT(IR_IDX_R(ir_idx)) ||
01450                      (ATD_CLASS(IR_IDX_R(ir_idx)) == Constant &&
01451                       ATD_FLD(IR_IDX_R(ir_idx)) == CN_Tbl_Idx)));
01452          break;
01453 
01454       case IR_Tbl_Idx:
01455          symbolic = ir_is_symbolic_constant(IR_IDX_R(ir_idx));
01456          break;
01457 
01458       case IL_Tbl_Idx:
01459          symbolic = il_is_symbolic_constant(IR_IDX_R(ir_idx));
01460          break;
01461 
01462       case CN_Tbl_Idx:
01463       case NO_Tbl_Idx:
01464          symbolic = TRUE;
01465          break;
01466 
01467       case SH_Tbl_Idx:
01468       default:
01469          symbolic = FALSE;
01470          break;
01471       }
01472    }
01473 
01474    EXIT:
01475 
01476    TRACE (Func_Exit, "ir_is_symbolic_constant", NULL);
01477 
01478    return(symbolic);
01479 
01480 }  /* ir_is_symbolic_constant */
01481 
01482 /******************************************************************************\
01483 |*                                                                            *|
01484 |* Description:                                                               *|
01485 |*      Go through an il stream, checking to see if it is a symbolic constant *|
01486 |*                                                                            *|
01487 |* Input parameters:                                                          *|
01488 |*      il_idx          - il to search.                                       *|
01489 |*                                                                            *|
01490 |* Output parameters:                                                         *|
01491 |*      NONE                                                                  *|
01492 |*                                                                            *|
01493 |* Returns:                                                                   *|
01494 |*      TRUE if il stream is a symbolic constant.  FALSE otherwise.           *|
01495 |*                                                                            *|
01496 \******************************************************************************/
01497 static  boolean il_is_symbolic_constant(int      il_idx)
01498 {
01499    boolean      symbolic        = TRUE;
01500 
01501 
01502    TRACE (Func_Entry, "il_is_symbolic_constant", NULL);
01503 
01504    while (symbolic == TRUE && il_idx != NULL_IDX) {
01505 
01506       switch (IL_FLD(il_idx)) {
01507 
01508       case AT_Tbl_Idx:
01509          symbolic = (AT_OBJ_CLASS(IL_IDX(il_idx)) == Data_Obj &&
01510                      (ATD_SYMBOLIC_CONSTANT(IL_IDX(il_idx)) ||
01511                      (ATD_CLASS(IL_IDX(il_idx)) == Constant &&
01512                       ATD_FLD(IL_IDX(il_idx)) == CN_Tbl_Idx)));
01513          break;
01514 
01515       case IR_Tbl_Idx:
01516          symbolic = ir_is_symbolic_constant(IL_IDX(il_idx));
01517          break;
01518 
01519       case IL_Tbl_Idx:
01520          symbolic = il_is_symbolic_constant(IL_IDX(il_idx));
01521          break;
01522 
01523       case CN_Tbl_Idx:
01524       case NO_Tbl_Idx:
01525          symbolic = TRUE;
01526          break;
01527 
01528       case SH_Tbl_Idx:
01529       default:
01530          symbolic = FALSE;
01531          break;
01532       }
01533 
01534       il_idx = IL_NEXT_LIST_IDX(il_idx);
01535    }
01536 
01537    TRACE (Func_Exit, "il_is_symbolic_constant", NULL);
01538 
01539    return(symbolic);
01540 
01541 }  /* il_is_symbolic_constant */
01542 
01543 /******************************************************************************\
01544 |*                                                                            *|
01545 |* Description:                                                               *|
01546 |*      This routine copies a linked list of statements and replaces any      *|
01547 |*      internal label with a new internal label.                             *|
01548 |*                                                                            *|
01549 |* Input parameters:                                                          *|
01550 |*      NONE                                                                  *|
01551 |*                                                                            *|
01552 |* Output parameters:                                                         *|
01553 |*      NONE                                                                  *|
01554 |*                                                                            *|
01555 |* Returns:                                                                   *|
01556 |*      NOTHING                                                               *|
01557 |*                                                                            *|
01558 \******************************************************************************/
01559 
01560 void copy_entry_exit_sh_list(int        start_sh_idx,
01561                              int        end_sh_idx,
01562                              int        *new_start_sh_idx,
01563                              int        *new_end_sh_idx)
01564 
01565 {
01566    int          al_idx;
01567    int          new_sh_idx;
01568    opnd_type    opnd_o;
01569    opnd_type    opnd_n;
01570    int          sh_idx;
01571 
01572    TRACE (Func_Entry, "copy_entry_exit_sh_list", NULL);
01573 
01574    sh_idx = start_sh_idx;
01575    *new_start_sh_idx = NULL_IDX;
01576    label_copy_al_idx = NULL_IDX;
01577    gen_lbl_copy = TRUE;
01578 
01579    while (sh_idx != SH_NEXT_IDX(end_sh_idx)) {
01580 
01581       /* do not copy init statements. These are possibly */
01582       /* generated for runtime argument checking.        */
01583 
01584       if (IR_OPR(SH_IR_IDX(sh_idx)) != Init_Opr &&
01585           IR_OPR(SH_IR_IDX(sh_idx)) != Init_Reloc_Opr) {
01586 
01587          OPND_FLD(opnd_o) = SH_Tbl_Idx;
01588          OPND_IDX(opnd_o) = sh_idx;
01589          copy_subtree(&opnd_o, &opnd_n);
01590          new_sh_idx = OPND_IDX(opnd_n);
01591 
01592          if (*new_start_sh_idx == NULL_IDX) {
01593             *new_start_sh_idx = new_sh_idx;
01594             SH_PREV_IDX((*new_start_sh_idx)) = NULL_IDX;
01595             SH_NEXT_IDX((*new_start_sh_idx)) = NULL_IDX;
01596             *new_end_sh_idx = new_sh_idx;
01597          }
01598          else {
01599             SH_NEXT_IDX((*new_end_sh_idx)) = new_sh_idx;
01600             SH_PREV_IDX(new_sh_idx) = *new_end_sh_idx;
01601             SH_NEXT_IDX(new_sh_idx) = NULL_IDX;
01602             *new_end_sh_idx = new_sh_idx;
01603          }
01604       }
01605 
01606       sh_idx = SH_NEXT_IDX(sh_idx);
01607    }
01608 
01609    gen_lbl_copy = FALSE;
01610    al_idx       = label_copy_al_idx;
01611 
01612    while (al_idx != NULL_IDX) {
01613       ATL_NEW_LBL_IDX(AL_ATTR_IDX(al_idx))      = NULL_IDX;
01614       al_idx                                    = AL_NEXT_IDX(al_idx);
01615    }
01616 
01617    free_attr_list(label_copy_al_idx);
01618 
01619    label_copy_al_idx = NULL_IDX;
01620 
01621    TRACE (Func_Exit, "copy_entry_exit_sh_list", NULL);
01622 
01623    return;
01624 
01625 }  /* copy_entry_exit_sh_list */
01626 
01627 /******************************************************************************\
01628 |*                                                                            *|
01629 |* Description:                                                               *|
01630 |*      Generate an Stmt_Expansion_Opr. They use this form ...                *|
01631 |*                                                                            *|
01632 |*                  (Stmt_Expansion_Opr)                                      *|
01633 |*                 /                    \                                     *|
01634 |*           result temp                 |-> Before list, start (SH_Tbl_Idx)  *|
01635 |*              opnd                     |                                    *|
01636 |*                                       |-> Before list, end (SH_Tbl_Idx)    *|
01637 |*                                       |                                    *|
01638 |*                                       |-> After list, start (SH_Tbl_Idx)   *|
01639 |*                                       |                                    *|
01640 |*                                       |-> After list, end (SH_Tbl_Idx)     *|
01641 |*                                                                            *|
01642 |* Input parameters:                                                          *|
01643 |*      NONE                                                                  *|
01644 |*                                                                            *|
01645 |* Output parameters:                                                         *|
01646 |*      NONE                                                                  *|
01647 |*                                                                            *|
01648 |* Returns:                                                                   *|
01649 |*      NOTHING                                                               *|
01650 |*                                                                            *|
01651 \******************************************************************************/
01652 
01653 int     gen_stmt_expansion_opr(int      line,
01654                                int      col)
01655 
01656 {
01657    int          ir_idx;
01658    int          list_idx;
01659 
01660    TRACE (Func_Entry, "gen_stmt_expansion_opr", NULL);
01661 
01662    NTR_IR_TBL(ir_idx);
01663    IR_OPR(ir_idx) = Stmt_Expansion_Opr;
01664    IR_TYPE_IDX(ir_idx) = TYPELESS_DEFAULT_TYPE;
01665    IR_LINE_NUM(ir_idx) = line;
01666    IR_COL_NUM(ir_idx) = col;
01667 
01668    NTR_IR_LIST_TBL(list_idx);
01669    IL_FLD(list_idx) = SH_Tbl_Idx;
01670    IL_LINE_NUM(list_idx) = line;
01671    IL_COL_NUM(list_idx) = col;
01672    IR_FLD_R(ir_idx) = IL_Tbl_Idx;
01673    IR_IDX_R(ir_idx) = list_idx;
01674    IR_LIST_CNT_R(ir_idx) = 4;
01675 
01676    NTR_IR_LIST_TBL(IL_NEXT_LIST_IDX(list_idx));
01677    IL_PREV_LIST_IDX(IL_NEXT_LIST_IDX(list_idx)) = list_idx;
01678    list_idx = IL_NEXT_LIST_IDX(list_idx);
01679    IL_FLD(list_idx) = SH_Tbl_Idx;
01680    IL_LINE_NUM(list_idx) = line;
01681    IL_COL_NUM(list_idx) = col;
01682 
01683    NTR_IR_LIST_TBL(IL_NEXT_LIST_IDX(list_idx));
01684    IL_PREV_LIST_IDX(IL_NEXT_LIST_IDX(list_idx)) = list_idx;
01685    list_idx = IL_NEXT_LIST_IDX(list_idx);
01686    IL_FLD(list_idx) = SH_Tbl_Idx;
01687    IL_LINE_NUM(list_idx) = line;
01688    IL_COL_NUM(list_idx) = col;
01689 
01690    NTR_IR_LIST_TBL(IL_NEXT_LIST_IDX(list_idx));
01691    IL_PREV_LIST_IDX(IL_NEXT_LIST_IDX(list_idx)) = list_idx;
01692    list_idx = IL_NEXT_LIST_IDX(list_idx);
01693    IL_FLD(list_idx) = SH_Tbl_Idx;
01694    IL_LINE_NUM(list_idx) = line;
01695    IL_COL_NUM(list_idx) = col;
01696 
01697    if (defer_stmt_expansion) {
01698       number_of_functions++;
01699    }
01700 
01701    TRACE (Func_Exit, "gen_stmt_expansion_opr", NULL);
01702 
01703    return(ir_idx);
01704 
01705 }  /* gen_stmt_expansion_opr */
01706 
01707 /******************************************************************************\
01708 |*                                                                            *|
01709 |* Description:                                                               *|
01710 |*      <description>                                                         *|
01711 |*                                                                            *|
01712 |* Input parameters:                                                          *|
01713 |*      NONE                                                                  *|
01714 |*                                                                            *|
01715 |* Output parameters:                                                         *|
01716 |*      NONE                                                                  *|
01717 |*                                                                            *|
01718 |* Returns:                                                                   *|
01719 |*      NOTHING                                                               *|
01720 |*                                                                            *|
01721 \******************************************************************************/
01722 
01723 void free_stmt_expansion_opr(int        ir_idx)
01724 
01725 {
01726    int          free_list;
01727    int          list_idx;
01728 
01729    TRACE (Func_Entry, "free_stmt_expansion_opr", NULL);
01730 
01731    list_idx = IR_IDX_R(ir_idx);
01732    while (list_idx) {
01733       free_list = list_idx;
01734 
01735       list_idx = IL_NEXT_LIST_IDX(list_idx);
01736       FREE_IR_LIST_NODE(free_list);
01737    }
01738 
01739    FREE_IR_NODE(ir_idx);
01740 
01741    TRACE (Func_Exit, "free_stmt_expansion_opr", NULL);
01742 
01743    return;
01744 
01745 }  /* free_stmt_expansion_opr */
01746 
01747 /******************************************************************************\
01748 |*                                                                            *|
01749 |* Description:                                                               *|
01750 |*      <description>                                                         *|
01751 |*                                                                            *|
01752 |* Input parameters:                                                          *|
01753 |*      NONE                                                                  *|
01754 |*                                                                            *|
01755 |* Output parameters:                                                         *|
01756 |*      NONE                                                                  *|
01757 |*                                                                            *|
01758 |* Returns:                                                                   *|
01759 |*      NOTHING                                                               *|
01760 |*                                                                            *|
01761 \******************************************************************************/
01762 
01763 int     gen_ir(fld_type         l_fld,
01764                int              l_idx,
01765                operator_type    opr,
01766                int              type_idx,
01767                int              line,
01768                int              col,
01769                fld_type         r_fld,
01770                int              r_idx)
01771 
01772 {
01773 
01774    int          cnt;
01775    int          ir_idx;
01776    int          list_idx;
01777    int          rank_l = 0;
01778    int          rank_r = 0;
01779 
01780    TRACE (Func_Entry, "gen_ir", NULL);
01781 
01782 # ifdef _DEBUG
01783    if (opr == Subscript_Opr ||
01784        opr == Whole_Subscript_Opr ||
01785        opr == Section_Subscript_Opr ||
01786        opr == Substring_Opr ||
01787        opr == Whole_Substring_Opr ||
01788        opr == Struct_Opr) {
01789 
01790       PRINTMSG(line, 626, Internal, col,
01791                "no reference operator",
01792                "gen_ir");
01793    }
01794 
01795    if ((opr == Loc_Opr || opr == Aloc_Opr) &&
01796        (l_fld == CN_Tbl_Idx ||
01797         l_fld == SB_Tbl_Idx ||
01798         l_fld == IL_Tbl_Idx ||
01799         l_fld == SH_Tbl_Idx ||
01800         (l_fld == IR_Tbl_Idx &&
01801          IR_OPR(l_idx) != Struct_Opr &&
01802          IR_OPR(l_idx) != Dv_Deref_Opr &&
01803          IR_OPR(l_idx) != Subscript_Opr &&
01804          IR_OPR(l_idx) != Whole_Subscript_Opr &&
01805          IR_OPR(l_idx) != Section_Subscript_Opr &&
01806          IR_OPR(l_idx) != Substring_Opr &&
01807          IR_OPR(l_idx) != Whole_Substring_Opr))) {
01808 
01809       PRINTMSG(line, 626, Internal, col,
01810                "valid LOC opr",
01811                "gen_ir");
01812    }
01813         
01814 # endif
01815 
01816    NTR_IR_TBL(ir_idx);
01817    IR_TYPE_IDX(ir_idx)   = type_idx;
01818    IR_OPR(ir_idx)        = opr;
01819    IR_LINE_NUM(ir_idx)   = line;
01820    IR_COL_NUM(ir_idx)    = col;
01821 
01822    if (l_fld != NO_Tbl_Idx) {
01823       IR_LINE_NUM_L(ir_idx) = line;
01824       IR_COL_NUM_L(ir_idx)  = col;
01825       IR_FLD_L(ir_idx)      = l_fld;
01826       IR_IDX_L(ir_idx)      = l_idx;
01827 
01828       if (l_fld == IR_Tbl_Idx) {
01829          rank_l = IR_RANK(l_idx);
01830       }
01831       else if (l_fld == IL_Tbl_Idx) {
01832          list_idx = l_idx;
01833          cnt = 0;
01834          while (list_idx) {
01835 
01836             if (IL_FLD(list_idx) == IR_Tbl_Idx &&
01837                 IR_RANK(IL_IDX(list_idx)) > rank_l) {
01838                rank_l = IR_RANK(IL_IDX(list_idx));
01839             }
01840             cnt++;
01841             list_idx = IL_NEXT_LIST_IDX(list_idx);
01842          }
01843          IR_LIST_CNT_L(ir_idx) = cnt;
01844       }
01845    }
01846 
01847    if (r_fld != NO_Tbl_Idx) {
01848       IR_LINE_NUM_R(ir_idx) = line;
01849       IR_COL_NUM_R(ir_idx)  = col;
01850       IR_FLD_R(ir_idx)      = r_fld;
01851       IR_IDX_R(ir_idx)      = r_idx;
01852 
01853       if (r_fld == IR_Tbl_Idx) {
01854          rank_r = IR_RANK(r_idx);
01855       }
01856       else if (r_fld == IL_Tbl_Idx) {
01857          list_idx = r_idx;
01858          cnt = 0;
01859          while (list_idx) {
01860 
01861             if (IL_FLD(list_idx) == IR_Tbl_Idx &&
01862                 IR_RANK(IL_IDX(list_idx)) > rank_r) {
01863                rank_r = IR_RANK(IL_IDX(list_idx));
01864             }
01865             cnt++;
01866             list_idx = IL_NEXT_LIST_IDX(list_idx);
01867          }
01868          IR_LIST_CNT_R(ir_idx) = cnt;
01869       }
01870    }
01871 
01872    IR_RANK(ir_idx) = (rank_l > rank_r ? rank_l : rank_r);
01873 
01874    IR_ARRAY_SYNTAX(ir_idx) = (IR_RANK(ir_idx) ? TRUE : FALSE);
01875 
01876    TRACE (Func_Exit, "gen_ir", NULL);
01877 
01878    return(ir_idx);
01879 
01880 }  /* gen_ir */
01881 
01882 /******************************************************************************\
01883 |*                                                                            *|
01884 |* Description:                                                               *|
01885 |*      <description>                                                         *|
01886 |*                                                                            *|
01887 |* Input parameters:                                                          *|
01888 |*      NONE                                                                  *|
01889 |*                                                                            *|
01890 |* Output parameters:                                                         *|
01891 |*      NONE                                                                  *|
01892 |*                                                                            *|
01893 |* Returns:                                                                   *|
01894 |*      NOTHING                                                               *|
01895 |*                                                                            *|
01896 \******************************************************************************/
01897 
01898 void gen_opnd(opnd_type *opnd, int idx, fld_type fld, int line, int col)
01899 
01900 {
01901 
01902    TRACE (Func_Entry, "gen_opnd", NULL);
01903 
01904    *opnd = null_opnd;
01905 
01906    OPND_FLD((*opnd)) = fld;
01907    OPND_IDX((*opnd)) = idx;
01908    if (fld == IL_Tbl_Idx) {
01909       OPND_LIST_CNT((*opnd)) = line;
01910    }
01911    else if (fld == AT_Tbl_Idx || fld == CN_Tbl_Idx) {
01912       OPND_LINE_NUM((*opnd)) = line;
01913       OPND_COL_NUM((*opnd)) = col;
01914    }
01915 
01916    TRACE (Func_Exit, "gen_opnd", NULL);
01917 
01918    return;
01919 
01920 }  /* gen_opnd */
01921 
01922 /******************************************************************************\
01923 |*                                                                            *|
01924 |* Description:                                                               *|
01925 |*      <description>                                                         *|
01926 |*                                                                            *|
01927 |* Input parameters:                                                          *|
01928 |*      NONE                                                                  *|
01929 |*                                                                            *|
01930 |* Output parameters:                                                         *|
01931 |*      NONE                                                                  *|
01932 |*                                                                            *|
01933 |* Returns:                                                                   *|
01934 |*      NOTHING                                                               *|
01935 |*                                                                            *|
01936 \******************************************************************************/
01937 
01938 void stmt_expansion_control_start(void)
01939 
01940 {
01941    int  col;
01942    int  line;
01943    int  save_curr_stmt_sh_idx;
01944 
01945    TRACE (Func_Entry, "stmt_expansion_control_start", NULL);
01946    if (defer_stmt_expansion) {
01947       PUSH_CURR_STMT;
01948       save_curr_stmt_sh_idx = curr_stmt_sh_idx;
01949       curr_stmt_sh_idx = ntr_sh_tbl();
01950       PUSH_CURR_STMT;
01951       line = SH_GLB_LINE(save_curr_stmt_sh_idx);
01952       col = SH_COL_NUM(save_curr_stmt_sh_idx);
01953       SH_ERR_FLG(curr_stmt_sh_idx) = SH_ERR_FLG(save_curr_stmt_sh_idx);
01954       SH_COL_NUM(curr_stmt_sh_idx) = col;
01955       SH_GLB_LINE(curr_stmt_sh_idx) = line;
01956       SH_STMT_TYPE(curr_stmt_sh_idx) = SH_STMT_TYPE(save_curr_stmt_sh_idx);
01957 
01958       /* place two empty stmts around the current one. */
01959       /* This is because some stmts generators expect to alway */
01960       /* have a 'NEXT' stmt */
01961 
01962       defer_stmt_expansion = FALSE;
01963       gen_sh(Before, Null_Stmt, line, col, FALSE, FALSE, TRUE);
01964       gen_sh(After, Null_Stmt, line, col, FALSE, FALSE, TRUE);
01965       curr_stmt_sh_idx = SH_PREV_IDX(curr_stmt_sh_idx);
01966       defer_stmt_expansion = TRUE;
01967    }
01968 
01969    TRACE (Func_Exit, "stmt_expansion_control_start", NULL);
01970 
01971    return;
01972 
01973 }  /* stmt_expansion_control_start */
01974 
01975 /******************************************************************************\
01976 |*                                                                            *|
01977 |* Description:                                                               *|
01978 |*      <description>                                                         *|
01979 |*                                                                            *|
01980 |* Input parameters:                                                          *|
01981 |*      NONE                                                                  *|
01982 |*                                                                            *|
01983 |* Output parameters:                                                         *|
01984 |*      NONE                                                                  *|
01985 |*                                                                            *|
01986 |* Returns:                                                                   *|
01987 |*      NOTHING                                                               *|
01988 |*                                                                            *|
01989 \******************************************************************************/
01990 
01991 void stmt_expansion_control_end(opnd_type *opnd)
01992 
01993 {
01994    int          col;
01995    int          line;
01996    int          next_idx;
01997    int          prev_idx;
01998    int          sh_idx;
01999    int          stmt_expansion_idx;
02000 
02001    TRACE (Func_Entry, "stmt_expansion_control_end", NULL);
02002 
02003    if (defer_stmt_expansion) {
02004       POP_CURR_STMT;
02005 
02006       /* remove the bounding empty stmts. */
02007 
02008       next_idx = NULL_IDX;
02009       prev_idx = NULL_IDX;
02010 
02011       sh_idx = SH_PREV_IDX(curr_stmt_sh_idx);
02012 
02013       while(SH_PREV_IDX(sh_idx)) {
02014          prev_idx = sh_idx;
02015          sh_idx = SH_PREV_IDX(sh_idx);
02016       }
02017 
02018 # ifdef _DEBUG
02019       if (SH_STMT_TYPE(sh_idx) != Null_Stmt) {
02020          PRINTMSG(stmt_start_line, 626, Internal, stmt_start_col,
02021                   "valid stmt_expansion_control", 
02022                   "stmt_expansion_control_end");
02023       }
02024 # endif
02025 
02026       FREE_SH_NODE(sh_idx);
02027 
02028       sh_idx = SH_NEXT_IDX(curr_stmt_sh_idx);
02029 
02030       while(SH_NEXT_IDX(sh_idx)) {
02031          next_idx = sh_idx;
02032          sh_idx = SH_NEXT_IDX(sh_idx);
02033       }
02034 
02035 # ifdef _DEBUG
02036       if (SH_STMT_TYPE(sh_idx) != Null_Stmt) {
02037          PRINTMSG(stmt_start_line, 626, Internal, stmt_start_col,
02038                   "valid stmt_expansion_control", 
02039                   "stmt_expansion_control_end");
02040       }
02041 # endif
02042 
02043       FREE_SH_NODE(sh_idx);
02044 
02045       if (prev_idx || next_idx) {
02046          find_opnd_line_and_column(opnd, &line, &col);
02047          stmt_expansion_idx = 
02048                  gen_stmt_expansion_opr(line, col);
02049          if (prev_idx) {
02050             STMT_EXPAND_BEFORE_END_SH(stmt_expansion_idx) =
02051                                        SH_PREV_IDX(curr_stmt_sh_idx);
02052             STMT_EXPAND_BEFORE_START_SH(stmt_expansion_idx) = prev_idx;
02053             SH_PREV_IDX(prev_idx) = NULL_IDX;
02054             SH_NEXT_IDX(STMT_EXPAND_BEFORE_END_SH(stmt_expansion_idx)) = 
02055                                                                 NULL_IDX;
02056          }
02057          if (next_idx) {
02058            STMT_EXPAND_AFTER_START_SH(stmt_expansion_idx) =
02059                                             SH_NEXT_IDX(curr_stmt_sh_idx);
02060             STMT_EXPAND_AFTER_END_SH(stmt_expansion_idx) = next_idx;
02061             SH_NEXT_IDX(next_idx) = NULL_IDX;
02062             SH_PREV_IDX(STMT_EXPAND_AFTER_START_SH(stmt_expansion_idx)) = 
02063                                                            NULL_IDX;
02064          }
02065          COPY_OPND(IR_OPND_L(stmt_expansion_idx), (*opnd));
02066          OPND_FLD((*opnd)) = IR_Tbl_Idx;
02067          OPND_IDX((*opnd)) = stmt_expansion_idx;
02068       }
02069       FREE_SH_NODE(curr_stmt_sh_idx);
02070       POP_CURR_STMT;
02071    }
02072 
02073    TRACE (Func_Exit, "stmt_expansion_control_end", NULL);
02074 
02075    return;
02076 
02077 }  /* stmt_expansion_control_end */
02078 
02079 /******************************************************************************\
02080 |*                                                                            *|
02081 |* Description:                                                               *|
02082 |*      <description>                                                         *|
02083 |*                                                                            *|
02084 |* Input parameters:                                                          *|
02085 |*      NONE                                                                  *|
02086 |*                                                                            *|
02087 |* Output parameters:                                                         *|
02088 |*      NONE                                                                  *|
02089 |*                                                                            *|
02090 |* Returns:                                                                   *|
02091 |*      NOTHING                                                               *|
02092 |*                                                                            *|
02093 \******************************************************************************/
02094 
02095 void remove_sh(int      sh_idx)
02096 
02097 {
02098 
02099 
02100    TRACE (Func_Entry, "remove_sh", NULL);
02101 
02102    if (SH_NEXT_IDX(sh_idx)) {
02103       SH_PREV_IDX(SH_NEXT_IDX(sh_idx)) = SH_PREV_IDX(sh_idx);
02104    }
02105 
02106    if (SH_PREV_IDX(sh_idx)) {
02107       SH_NEXT_IDX(SH_PREV_IDX(sh_idx)) = SH_NEXT_IDX(sh_idx);
02108    }
02109 
02110    TRACE (Func_Exit, "remove_sh", NULL);
02111 
02112    return;
02113 
02114 }  /* remove_sh */
02115 
02116 /******************************************************************************\
02117 |*                                                                            *|
02118 |* Description:                                                               *|
02119 |*      generate a list. The varargs to this routine are 'count' number of    *|
02120 |*      pairs of fld, idx.                                                    *|
02121 |*                                                                            *|
02122 |* Input parameters:                                                          *|
02123 |*      count           - number of fld/idx pairs. (number of list items)     *|
02124 |*      arg_desc        - TRUE is this is IL_ARG_DESC_VARIANT il.             *|
02125 |*      line            - line.                                               *|
02126 |*      col             - col.                                                *|
02127 |*      ...             - list item operands. (fld/idx pairs)                 *|
02128 |*                                                                            *|
02129 |* Output parameters:                                                         *|
02130 |*      NONE                                                                  *|
02131 |*                                                                            *|
02132 |* Returns:                                                                   *|
02133 |*      The idx of the first list item.                                       *|
02134 |*                                                                            *|
02135 \******************************************************************************/
02136 
02137 int gen_il(int          count, 
02138            boolean      arg_desc,
02139            int          line, 
02140            int          col, 
02141            ...)
02142 
02143 {
02144 # define MAX_LIST_ARGS  40
02145 
02146    va_list      arg_ptr;
02147    int          i;
02148    int          k;
02149    int          list_idx;
02150    int          list_idx2;
02151    int          start_idx = NULL_IDX;
02152    int          fld[MAX_LIST_ARGS];
02153    int          idx[MAX_LIST_ARGS];
02154 
02155    TRACE (Func_Entry, "gen_il", NULL);
02156 
02157    if (count <= 0) {
02158       goto EXIT;
02159    }
02160 
02161 # ifdef _DEBUG
02162    if (count > MAX_LIST_ARGS) {
02163       PRINTMSG(line, 626, Internal, col,
02164                "count <= MAX_LIST_ARGS", 
02165                "gen_il");
02166    }
02167 # endif
02168 
02169    va_start (arg_ptr, col);
02170 
02171    for (i = 0; i < count; i++) {
02172       fld[i] = va_arg(arg_ptr, long);
02173       idx[i] = va_arg(arg_ptr, long);
02174    }
02175 
02176    va_end(arg_ptr);
02177 
02178    NTR_IR_LIST_TBL(list_idx);
02179    start_idx = list_idx;
02180 
02181    if (arg_desc) {
02182       IL_ARG_DESC_VARIANT(list_idx) = TRUE;
02183    }
02184 
02185    IL_FLD(list_idx) = (fld_type) fld[0];
02186    IL_IDX(list_idx) = idx[0];
02187 
02188    if (IL_FLD(list_idx) == IL_Tbl_Idx) {
02189       k = 0;
02190       list_idx2 = IL_IDX(list_idx);
02191       while(list_idx2) {
02192          k++;
02193          list_idx2 = IL_NEXT_LIST_IDX(list_idx2);
02194       }
02195 
02196       IL_LIST_CNT(list_idx) = k;
02197    }
02198    else if (IL_FLD(list_idx) != IR_Tbl_Idx) {
02199       IL_LINE_NUM(list_idx) = line;
02200       IL_COL_NUM(list_idx) = col;
02201    }
02202 
02203    for (i = 1; i < count; i++) {
02204 
02205       NTR_IR_LIST_TBL(IL_NEXT_LIST_IDX(list_idx));
02206 
02207       if (arg_desc) {
02208          IL_ARG_DESC_VARIANT(IL_NEXT_LIST_IDX(list_idx)) = TRUE;
02209       }
02210       else {
02211          IL_PREV_LIST_IDX(IL_NEXT_LIST_IDX(list_idx)) = list_idx;
02212       }
02213       list_idx = IL_NEXT_LIST_IDX(list_idx);
02214 
02215       IL_FLD(list_idx) = (fld_type) fld[i];
02216       IL_IDX(list_idx) = idx[i];
02217 
02218       if (IL_FLD(list_idx) == IL_Tbl_Idx) {
02219          k = 0;
02220          list_idx2 = IL_IDX(list_idx);
02221          while(list_idx2) {
02222             k++;
02223             list_idx2 = IL_NEXT_LIST_IDX(list_idx2);
02224          }
02225 
02226          IL_LIST_CNT(list_idx) = k;
02227       }
02228       else if (IL_FLD(list_idx) != IR_Tbl_Idx) {
02229          IL_LINE_NUM(list_idx) = line;
02230          IL_COL_NUM(list_idx) = col;
02231       }
02232    }
02233 
02234 EXIT:
02235 
02236    TRACE (Func_Exit, "gen_il", NULL);
02237 
02238    return(start_idx);
02239 
02240 }  /* gen_il */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines