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