00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "defs.h"
00031 #include "glob.h"
00032 #include "config.h"
00033 #include "wn.h"
00034 #include "wn_util.h"
00035
00036 #include "srcpos.h"
00037
00038 extern "C"{
00039 #include "gspin-wgen-interface.h"
00040 }
00041 #include "wgen_expr.h"
00042 #include "wgen_misc.h"
00043 #include "wgen_dst.h"
00044 #include "wgen_stmt.h"
00045 #include "wgen_spin_symbol.h"
00046 #include "omp_types.h"
00047 #include "omp_directive.h"
00048 #include "wgen_omp_directives.h"
00049 #include "wgen_omp_check_stack.h"
00050
00051 #include <stdio.h>
00052 #include "errors.h"
00053 #include "const.h"
00054
00055 extern std::vector<WN *> doloop_side_effects;
00056
00058
00059 #if 0
00060
00061
00062 void
00063 print_tree (FILE *file, gs_t node)
00064 {
00065 print_node_brief (file, "", node, 0);
00066
00067 fprintf (file, "\n");
00068 }
00069
00070
00071 void
00072 print_node_brief (FILE *file, const char *prefix, gs_t node, int indent)
00073 {
00074 char class1;
00075
00076 if (node == 0)
00077 return;
00078
00079 class1 = gs_tree_code_class (gs_tree_code (node));
00080
00081
00082
00083 if (indent > 0)
00084 fprintf (file, " ");
00085 fprintf (file, "%s <%s ", prefix, tree_code_name[(int) gs_tree_code (node)]);
00086 fprintf (file, HOST_PTR_PRINTF, (char *) node);
00087
00088 if (class1 == 'd')
00089 {
00090 if (gs_decl_name (node))
00091 fprintf (file, " %s", gs_identifier_pointer (gs_decl_name (node)));
00092 }
00093 else if (class1 == 't')
00094 {
00095 if (gs_type_name (node))
00096 {
00097 if (gs_tree_code (gs_type_name (node)) == GS_IDENTIFIER_NODE)
00098 fprintf (file, " %s", gs_identifier_pointer (gs_type_name (node)));
00099 else if (gs_tree_code (gs_type_name (node)) == GS_TYPE_DECL
00100 && gs_decl_name (gs_type_name (node)))
00101 fprintf (file, " %s",
00102 gs_identifier_pointer (gs_decl_name (gs_type_name (node))));
00103 }
00104 }
00105 if (gs_tree_code (node) == GS_IDENTIFIER_NODE)
00106 fprintf (file, " %s", gs_identifier_pointer (node));
00107
00108 fprintf (file, ">");
00109
00110 if (gs_tree_code (node) == GS_TREE_LIST)
00111 {
00112 print_node_brief (file, "purpose", gs_tree_purpose (node), indent + 4);
00113 print_node_brief (file, "value", gs_tree_value (node), indent + 4);
00114 print_node_brief (file, "chain", gs_tree_chain (node), indent + 4);
00115 }
00116 }
00117
00119
00120 void
00121 check_parallel_directive( struct parallel_clause_list * clause_list )
00122 {
00123 struct parallel_clause_list *cl = NULL;
00124 int count_if = 0, count_num_threads = 0, count_default = 0;
00125
00126 for (cl = clause_list; cl != NULL; cl = cl->next)
00127 {
00128 if ( cl->type == p_if ) count_if++;
00129 if ( cl->type == p_num_threads ) count_num_threads++;
00130 if ( cl->type == p_default ) count_default++;
00131 }
00132
00133 if ( count_if > 1 || count_num_threads > 1 || count_default > 1)
00134 {
00135 if ( count_if > 1)
00136 {
00137 printf ("Too many IF clausees.\n");
00138 }
00139 if ( count_num_threads > 1)
00140 {
00141 printf ("Too many NUM_THREADS clausees.\n");
00142 }
00143 if ( count_default > 1)
00144 {
00145 printf ("Too many DEFAULT clausees.\n");
00146 }
00147
00148 SRCPOS srcpos = Get_Srcpos();
00149 Fail_FmtAssertion ("Invalid syntax in the #PRAGMA OMP PARALLEL directive at line: %d, file number: %d.!\n",
00150 SRCPOS_linenum(srcpos), SRCPOS_filenum(srcpos));
00151 }
00152 }
00153 #endif
00154
00155
00156
00157 void
00158 expand_start_parallel_or_combined_parallel (gs_t stmt)
00159 {
00160 gs_t stmts = gs_omp_parallel_body(stmt);
00161
00162
00163
00164
00165
00166
00167 if (!lang_cplus &&
00168 gs_omp_parallel_combined(stmt) &&
00169
00170 gs_tree_code(stmts) == GS_BIND_EXPR)
00171 {
00172 gs_t body = gs_bind_expr_body(stmts);
00173
00174 if (gs_tree_code(body) == GS_OMP_FOR)
00175 {
00176 expand_start_parallel_for (stmt);
00177 return;
00178 }
00179 else if (gs_tree_code(body) == GS_OMP_SECTIONS)
00180 {
00181 expand_start_parallel_sections (stmt);
00182 return;
00183 }
00184 }
00185
00186 expand_start_parallel (stmt);
00187 }
00188
00189 void
00190 expand_start_parallel (gs_t stmt)
00191 {
00192 WGEN_expand_start_parallel (stmt);
00193 WGEN_Expand_Stmt (gs_omp_parallel_body(stmt));
00194 #if 0
00195
00196 WN *wn = WGEN_Stmt_Top ();
00197 WGEN_check_parallel (wn);
00198 #endif
00199 expand_end_parallel ();
00200
00201 }
00202
00203 void
00204 expand_end_parallel ()
00205 {
00206 WGEN_expand_end_parallel ();
00207 }
00208
00209
00210 #if 0
00212
00213 void
00214 check_for_directive(struct for_clause_list * clause_list )
00215 {
00216 struct for_clause_list *cl = NULL;
00217 int count_schedule = 0, count_ordered = 0, count_nowait = 0;
00218
00219 for (cl = clause_list; cl != NULL; cl = cl->next)
00220 {
00221 if ( cl->type == f_schedule_1 || cl->type == f_schedule_2 ) count_schedule++;
00222 if ( cl->type == f_ordered ) count_ordered++;
00223 if ( cl->type == f_nowait ) count_nowait++;
00224 }
00225
00226 if ( count_schedule > 1 || count_ordered > 1 || count_nowait > 1)
00227 {
00228 if ( count_schedule > 1)
00229 {
00230 printf ("Too many SCHEDULE clausees.\n");
00231 }
00232 if ( count_ordered > 1)
00233 {
00234 printf ("Too many ORDERED clausees.\n");
00235 }
00236 if ( count_nowait > 1)
00237 {
00238 printf ("Too many NOWAIT clausees.\n");
00239 }
00240
00241
00242 SRCPOS srcpos = Get_Srcpos();
00243 Fail_FmtAssertion ("Invalid syntax in the #PRAGMA OMP FOR directive at line: %d, file number: %d.!\n",
00244 SRCPOS_linenum(srcpos), SRCPOS_filenum(srcpos));
00245 }
00246 }
00247
00248 #endif
00249
00250 extern void WGEN_Expand_DO (gs_t);
00251
00252 void
00253 expand_start_for (gs_t stmt)
00254 {
00255 WGEN_expand_start_for (stmt);
00256 WGEN_Expand_DO (stmt);
00257 expand_end_for ();
00258 }
00259
00260 void
00261 expand_end_for (void)
00262 {
00263 WGEN_expand_end_for ();
00264 }
00265
00266
00267 #if 0
00269
00270
00271 void
00272 check_sections_directive( struct sections_clause_list * clause_list )
00273 {
00274 struct sections_clause_list *cl = NULL;
00275 int count_nowait = 0;
00276
00277 for (cl = clause_list; cl != NULL; cl = cl->next)
00278 {
00279 if ( cl->type == sections_nowait ) count_nowait++;
00280 }
00281
00282 if ( count_nowait > 1)
00283 {
00284 printf ("Too many NOWAIT clausees.\n");
00285
00286 SRCPOS srcpos = Get_Srcpos();
00287 Fail_FmtAssertion ("Invalid syntax in the #PRAGMA OMP SECTIONS directive at line: %d, file number: %d.!\n",
00288 SRCPOS_linenum(srcpos), SRCPOS_filenum(srcpos));
00289 }
00290 }
00291
00292 #endif
00293
00294 void
00295 expand_start_sections (gs_t stmt)
00296 {
00297 WGEN_expand_start_sections (stmt);
00298 WGEN_Expand_Stmt (gs_omp_sections_body(stmt));
00299 expand_end_sections ();
00300 }
00301
00302 void
00303 expand_end_sections (void)
00304 {
00305 WGEN_expand_end_sections ();
00306 }
00307
00308
00310
00311
00312 void expand_start_section (gs_t stmt)
00313 {
00314 Is_True (gs_tree_code(stmt) == GS_OMP_SECTION,
00315 ("expand_start_section: invalid statement type"));
00316 WGEN_expand_start_section ();
00317 WGEN_Expand_Stmt (gs_omp_section_body(stmt));
00318 expand_end_section ();
00319 }
00320
00321 void expand_end_section (void)
00322 {
00323 WGEN_expand_end_section ();
00324 }
00325
00327
00328
00329 #if 0
00330 void
00331 check_single_directive( struct single_clause_list * clause_list )
00332 {
00333 struct single_clause_list *cl = NULL;
00334 int count_copyprivate = 0, count_nowait = 0;
00335
00336 for (cl = clause_list; cl != NULL; cl = cl->next)
00337 {
00338 if ( cl->type == single_copyprivate ) count_copyprivate++;
00339 if ( cl->type == single_nowait ) count_nowait++;
00340 }
00341
00342 if ( count_nowait > 1 || (count_copyprivate != 0 && count_nowait != 0) )
00343 {
00344 if ( count_copyprivate != 0 && count_nowait != 0 )
00345 {
00346 printf ("The copyprivate clause must not be used with the nowait clause.\n");
00347 }
00348 if ( count_nowait > 1)
00349 {
00350 printf ("Too many NOWAIT clausees.\n");
00351 }
00352
00353 SRCPOS srcpos = Get_Srcpos();
00354 Fail_FmtAssertion ("Invalid syntax in the #PRAGMA OMP SINGLE directive at line: %d, file number: %d.!\n",
00355 SRCPOS_linenum(srcpos), SRCPOS_filenum(srcpos));
00356 }
00357 }
00358
00359 #endif
00360
00361 void
00362 expand_start_single (gs_t stmt)
00363 {
00364 WGEN_expand_start_single (stmt);
00365 WGEN_Expand_Stmt (gs_omp_single_body(stmt));
00366 expand_end_single ();
00367 }
00368
00369 void expand_end_single( )
00370 {
00371 WGEN_expand_end_single ();
00372 }
00373
00374 #if 0
00375
00377
00378
00379 void
00380 check_parallel_for_directive( struct parallel_for_clause_list * clause_list )
00381 {
00382 struct parallel_for_clause_list *cl = NULL;
00383 int count_if = 0, count_num_threads = 0, count_default = 0;
00384 int count_schedule = 0, count_ordered = 0;
00385
00386 for (cl = clause_list; cl != NULL; cl = cl->next)
00387 {
00388 if ( cl->type == p_for_if ) count_if++;
00389 if ( cl->type == p_for_num_threads ) count_num_threads++;
00390 if ( cl->type == p_for_default ) count_default++;
00391 if ( cl->type == p_for_schedule_1 || cl->type == p_for_schedule_2 ) count_schedule++;
00392 if ( cl->type == p_for_ordered ) count_ordered++;
00393 }
00394
00395 if ( count_if > 1 || count_num_threads > 1 || count_default >1
00396 ||count_schedule > 1 || count_ordered > 1 )
00397 {
00398 if ( count_if > 1)
00399 {
00400 printf ("Too many IF clausees.\n");
00401 }
00402 if ( count_num_threads > 1)
00403 {
00404 printf ("Too many NUM_THREADS clausees.\n");
00405 }
00406 if ( count_default > 1)
00407 {
00408 printf ("Too many DEFAULT clausees.\n");
00409 }
00410 if ( count_schedule > 1)
00411 {
00412 printf ("Too many SCHEDULE clausees.\n");
00413 }
00414 if ( count_ordered > 1)
00415 {
00416 printf ("Too many ORDERED clausees.\n");
00417 }
00418
00419 SRCPOS srcpos = Get_Srcpos();
00420 Fail_FmtAssertion ("Invalid syntax in the #PRAGMA OMP PARALLEL FOR directive at line: %d, file number: %d.!\n",
00421 SRCPOS_linenum(srcpos), SRCPOS_filenum(srcpos));
00422 }
00423
00424 }
00425
00426 #endif
00427
00428
00429 void
00430 expand_start_parallel_for (gs_t stmt)
00431 {
00432 WGEN_expand_start_parallel_for (stmt);
00433 WGEN_Expand_DO (gs_bind_expr_body(gs_omp_parallel_body(stmt)));
00434 expand_end_parallel_for ();
00435 }
00436
00437 void
00438 expand_end_parallel_for (void)
00439 {
00440 WGEN_expand_end_parallel_for ();
00441 }
00442
00443
00444 #if 0
00446
00447 void
00448 check_parallel_sections_directive( struct parallel_sections_clause_list * clause_list )
00449 {
00450 struct parallel_sections_clause_list *cl = NULL;
00451 int count_if = 0, count_num_threads = 0, count_default = 0;
00452
00453 for (cl = clause_list; cl != NULL; cl = cl->next)
00454 {
00455 if ( cl->type == p_sections_if ) count_if++;
00456 if ( cl->type == p_sections_num_threads ) count_num_threads++;
00457 if ( cl->type == p_sections_default ) count_default++;
00458 }
00459
00460 if ( count_if > 1 || count_num_threads > 1 || count_default > 1 )
00461 {
00462 if ( count_if > 1)
00463 {
00464 printf ("Too many IF clausees.\n");
00465 }
00466 if ( count_num_threads > 1)
00467 {
00468 printf ("Too many NUM_THREADS clausees.\n");
00469 }
00470 if ( count_default > 1)
00471 {
00472 printf ("Too many DEFAULT clausees.\n");
00473 }
00474
00475 SRCPOS srcpos = Get_Srcpos();
00476 Fail_FmtAssertion ("Invalid syntax in the #PRAGMA OMP PARALLEL SECTIONS directive at line: %d, file number: %d.!\n",
00477 SRCPOS_linenum(srcpos), SRCPOS_filenum(srcpos));
00478 }
00479
00480 }
00481
00482 #endif
00483
00484 void
00485 expand_start_parallel_sections(gs_t stmt)
00486 {
00487 WGEN_expand_start_parallel_sections (stmt);
00488 WGEN_Expand_Stmt (gs_omp_sections_body(
00489 gs_bind_expr_body(
00490 gs_omp_parallel_body(stmt))));
00491 expand_end_parallel_sections ();
00492 }
00493
00494 void
00495 expand_end_parallel_sections(void)
00496 {
00497 WGEN_expand_end_parallel_sections ();
00498 }
00499
00501
00502
00503 void expand_start_master (gs_t stmt)
00504 {
00505 WGEN_expand_start_master ();
00506 WGEN_Expand_Stmt (gs_omp_master_body(stmt));
00507 expand_end_master ();
00508 }
00509
00510 void expand_end_master (void)
00511 {
00512 WGEN_expand_end_master ();
00513 }
00514
00516
00517
00518 void expand_start_critical( gs_t stmt )
00519 {
00520 char *critical_name = NULL;
00521 ST *st = NULL;
00522 TCON tcon;
00523 TY_IDX ty;
00524
00525 gs_t region_phrase = gs_omp_critical_name(stmt);
00526 if (region_phrase)
00527 {
00528 critical_name = gs_identifier_pointer (region_phrase);
00529 tcon = Host_To_Targ_String (MTYPE_STRING, critical_name,
00530 strlen(critical_name));
00531 st = Gen_String_Sym (&tcon, MTYPE_To_TY(MTYPE_STRING), FALSE);
00532 }
00533 if (Trace_Omp)
00534 printf("critical name is %s \n",critical_name);
00535 WGEN_expand_start_critical (st, critical_name);
00536 WGEN_Expand_Stmt (gs_omp_critical_body(stmt));
00537 expand_end_critical ();
00538 }
00539
00540 void expand_end_critical (void)
00541 {
00542 WGEN_expand_end_critical ( );
00543 }
00544
00545
00546 #if 0
00548
00549
00550 void check_atomic_expression ( gs_t atomic_expression )
00551 {
00552 bool valid_for_expr = true;
00553 enum gs_code_t code, code1;
00554
00555 code = gs_tree_code (atomic_expression);
00556
00557 if (code != GS_MODIFY_EXPR && code != GS_PREDECREMENT_EXPR &&
00558 code != GS_PREINCREMENT_EXPR && code != GS_POSTDECREMENT_EXPR &&
00559 code != GS_POSTINCREMENT_EXPR)
00560 {
00561 printf (" No such increment operation is permitted.\n");
00562 valid_for_expr = false;
00563 }
00564 else {
00565 code1 = gs_tree_code (gs_tree_operand (atomic_expression, 1));
00566 if (code1 == GS_NOP_EXPR)
00567 code1 = gs_tree_code (gs_tree_operand (gs_tree_operand (atomic_expression, 1), 0));
00568 if (code == GS_MODIFY_EXPR && code1 != GS_PLUS_EXPR &&
00569 code1 != GS_MINUS_EXPR && code1 != GS_MULT_EXPR &&
00570 code1 != GS_RDIV_EXPR && code1 != GS_BIT_AND_EXPR &&
00571 code1 != GS_BIT_XOR_EXPR && code1 != GS_BIT_IOR_EXPR &&
00572 code1 != GS_LSHIFT_EXPR && code1 != GS_RSHIFT_EXPR &&
00573 code1 != GS_TRUNC_DIV_EXPR)
00574 {
00575 printf (" No such modifying operation is supported.\n");
00576 valid_for_expr = false;
00577 }
00578 }
00579
00580 if ( !valid_for_expr)
00581 {
00582 SRCPOS srcpos = Get_Srcpos();
00583 Fail_FmtAssertion ("Invalid atomic_expression in an ATOMIC directive! at line: %d, file number: %d.!\n",
00584 SRCPOS_linenum(srcpos), SRCPOS_filenum(srcpos));
00585 }
00586 }
00587
00588 #endif
00589
00590 void expand_start_atomic (gs_t stmt)
00591 {
00592 WGEN_expand_start_atomic ();
00593 WN * rhs_wn = WGEN_Expand_Expr (gs_tree_operand(stmt,1));
00594 gs_t lhs = gs_tree_operand(stmt,0);
00595 WGEN_Lhs_Of_Modify_Expr (GS_MODIFY_EXPR, lhs, NULL,
00596 0, 0, 0, 0, 0, rhs_wn, 0, 0, 0);
00597 expand_end_atomic ();
00598 }
00599
00600 void expand_end_atomic (void)
00601 {
00602 WGEN_expand_end_atomic ();
00603 }
00604
00606
00607
00608 void expand_start_ordered(gs_t stmt)
00609 {
00610 WGEN_expand_start_ordered ();
00611 WGEN_Expand_Stmt (gs_omp_ordered_body(stmt));
00612 expand_end_ordered ();
00613 }
00614
00615 void expand_end_ordered (void)
00616 {
00617 WGEN_expand_end_ordered ();
00618 }
00619
00620 #if 0
00621
00623
00624
00625 void expand_barrier ()
00626 {
00627 WGEN_expand_barrier ();
00628 }
00629
00630
00632
00633
00634 void expand_flush ( gs_t flush_variables)
00635 {
00636 register gs_t t = NULL;
00637 WN_list *flush_wn_list = NULL;
00638 WN_list *wnlist = NULL;
00639
00640 for (t = flush_variables; t; t = gs_tree_chain (t))
00641 {
00642 WN *wn = WGEN_Expand_Expr(gs_tree_value(t));
00643 wnlist = (struct WN_list *) malloc(sizeof(struct WN_list));
00644 wnlist->wn = WN_CopyNode (wn) ;
00645 wnlist->next = flush_wn_list;
00646 flush_wn_list = wnlist;
00647 }
00648
00649 WGEN_expand_flush (flush_wn_list);
00650
00651 }
00652
00653
00655
00656 int check_do_loop_for(gs_t init_expr, gs_t logical_expr, gs_t incr_expr)
00657 {
00658
00659 bool valid_for_expr = true;
00660 enum gs_code_t code, code1;
00661
00662 WN *index, *start, *end, *step;
00663
00664 WN *wn_tmp, * lcv , * incv;
00665
00666 TYPE_ID lcv_t;
00667
00668 code = gs_tree_code (init_expr);
00669
00670 if (code != MODIFY_EXPR)
00671 {
00672 valid_for_expr = false;
00673 }
00674 else
00675 {
00676 lcv = WGEN_Expand_Expr (gs_tree_operand (init_expr, 0));
00677 lcv_t = TY_mtype(ST_type(WN_st(lcv)));
00678
00679 if (lcv_t != MTYPE_I4 && lcv_t != MTYPE_I8 && lcv_t != MTYPE_I2
00680 && lcv_t != MTYPE_I1)
00681 {
00682 valid_for_expr = false;
00683 }
00684 }
00685
00686 code = gs_tree_code (logical_expr);
00687
00688 if (valid_for_expr && (code != LT_EXPR) && (code != LE_EXPR) && (code != GT_EXPR) && (code != GE_EXPR))
00689 {
00690 valid_for_expr = false;
00691 }
00692
00693
00694 code = gs_tree_code (incr_expr);
00695
00696 if (valid_for_expr && (code != MODIFY_EXPR) && (code != PREDECREMENT_EXPR) && (code != PREINCREMENT_EXPR)
00697 && (code != POSTDECREMENT_EXPR) && (code != POSTINCREMENT_EXPR))
00698 {
00699 valid_for_expr = false;
00700 }
00701 else {
00702 incv = WGEN_Expand_Expr (gs_tree_operand (incr_expr, 0));
00703 if (WN_st_idx(lcv)!=WN_st_idx(incv))
00704 {
00705 valid_for_expr = false;
00706 }
00707 else
00708 {
00709 code1 = gs_tree_code (gs_tree_operand (incr_expr, 1));
00710 if ((code == MODIFY_EXPR) && (code1 != PLUS_EXPR) && (code1 != MINUS_EXPR))
00711 {
00712 valid_for_expr = false;
00713 }
00714
00715 }
00716 }
00717
00718 if (valid_for_expr)
00719 {
00720 return true;
00721 }
00722 else
00723 {
00724 return false;
00725 }
00726
00727
00728 }
00729 #endif
00730
00731 extern OPERATOR Operator_From_Tree_node (gs_code_t);
00732 extern bool Has_Subsumed_Cvtl (OPERATOR);
00733
00734 void expand_start_do_loop (gs_t init_expr, gs_t logical_expr, gs_t incr_expr)
00735 {
00736 bool valid_for_expr = true;
00737 gs_code_t code, code1;
00738 gs_t temp;
00739
00740 WN *index, *start, *end, *step;
00741
00742 WN *wn_tmp, * lcv , * incv;
00743 WN *wn,*wn1;
00744 WN *tdecl;
00745 ST *tst;
00746 ST_IDX stlcv;
00747
00748 TYPE_ID lcv_t;
00749
00750 FmtAssert (doloop_side_effects.empty(),
00751 ("Expected DO-loop side-effects to be empty."));
00752 code = gs_tree_code (init_expr);
00753
00754 if (code != GS_MODIFY_EXPR && code != GS_VAR_DECL)
00755 {
00756 printf ("Invalid init_expr in a FOR statement! \n");
00757 valid_for_expr = false;
00758 WGEN_Stmt_Push (WN_CreateBlock (), wgen_stmk_comma, Get_Srcpos());
00759 }
00760 else
00761 {
00762 if(code == GS_VAR_DECL)
00763 {
00764 tst = DECL_ST(init_expr);
00765 index = WN_CreateIdname(0,tst);
00766 WGEN_Stmt_Push (WN_CreateBlock (), wgen_stmk_comma, Get_Srcpos());
00767
00768 wn1 = WGEN_Expand_Expr (gs_decl_initial(init_expr));
00769 wn_tmp = WGEN_Lhs_Of_Modify_Expr(GS_MODIFY_EXPR, init_expr, NULL, FALSE,
00770 0, 0, 0, FALSE, wn1, 0, FALSE, FALSE);
00771 wn_tmp = WGEN_Stmt_Pop (wgen_stmk_comma);
00772 start = WN_COPY_Tree( WN_first( wn_tmp ));
00773 WN_DELETE_Tree( wn_tmp );
00774 }
00775 else
00776 {
00777 lcv = WGEN_Expand_Expr (gs_tree_operand (init_expr, 0));
00778 lcv_t = TY_mtype(ST_type(WN_st(lcv)));
00779
00780 if (lcv_t != MTYPE_I4 && lcv_t != MTYPE_I8 &&
00781 lcv_t != MTYPE_I2 && lcv_t != MTYPE_I1)
00782 {
00783 printf ("Invalid induction variable type in init_expr in a FOR statement! \n");
00784 valid_for_expr = false;
00785 }
00786 else
00787 {
00788 index = WN_CreateIdname(0,WN_st_idx(lcv));
00789 if (lang_cplus)
00790 {
00791 WN * rhs = WGEN_Expand_Expr(gs_tree_operand(init_expr, 1));
00792 if (WN_has_side_effects(rhs))
00793 {
00794 TY_IDX ty_idx = MTYPE_TO_TY_array[WN_rtype(rhs)];
00795 ST * st = Gen_Temp_Symbol (ty_idx, "__doloop_init");
00796
00797 WGEN_add_pragma_to_enclosing_regions (WN_PRAGMA_LOCAL, st, TRUE);
00798 WN * stid = WN_Stid (TY_mtype(ty_idx), 0, st, ty_idx, rhs);
00799
00800
00801 doloop_side_effects.push_back (stid);
00802 rhs = WN_Ldid (TY_mtype(ty_idx), 0, st, ty_idx);
00803 }
00804 WGEN_Stmt_Push (WN_CreateBlock (), wgen_stmk_comma, Get_Srcpos());
00805 WGEN_Lhs_Of_Modify_Expr(code, gs_tree_operand (init_expr, 0), NULL, FALSE,
00806 0, 0, 0, FALSE, rhs, 0, FALSE, FALSE);
00807 wn_tmp = WGEN_Stmt_Pop (wgen_stmk_comma);
00808
00809 start = WN_COPY_Tree (WN_first (wn_tmp));
00810 WN_DELETE_Tree (wn_tmp);
00811 }
00812 else
00813 {
00814 WGEN_Stmt_Push (WN_CreateBlock (), wgen_stmk_comma, Get_Srcpos());
00815 wn_tmp = WGEN_Expand_Expr (init_expr);
00816 wn_tmp = WGEN_Stmt_Pop (wgen_stmk_comma);
00817 start = WN_COPY_Tree( WN_first( wn_tmp ));
00818 WN_DELETE_Tree( wn_tmp );
00819 }
00820 }
00821 }
00822 }
00823 code = gs_tree_code (logical_expr);
00824 if (valid_for_expr && (code != GS_LT_EXPR) && (code != GS_LE_EXPR) && (code != GS_GT_EXPR) && (code != GS_GE_EXPR))
00825 {
00826 printf ("Invalid logical_expr in a FOR statement! \
00827 The logical operators can only be <=, <, > or >= \n");
00828 valid_for_expr = false;
00829 }
00830 else
00831 {
00832 if (lang_cplus)
00833 {
00834
00835 WN * var = WGEN_Expand_Expr(gs_tree_operand(logical_expr, 0));
00836
00837 WN * ub = WGEN_Expand_Expr(gs_tree_operand(logical_expr, 1));
00838
00839
00840 TY_IDX ty_idx = Get_TY (gs_tree_type(logical_expr));
00841 TYPE_ID mtyp = TY_mtype(ty_idx);
00842 TY_IDX ty_idx0 = Get_TY(gs_tree_type(gs_tree_operand(logical_expr, 0)));
00843 TYPE_ID mtyp0 = TY_mtype(ty_idx0);
00844 TY_IDX ty_idx1 = Get_TY(gs_tree_type(gs_tree_operand(logical_expr, 1)));
00845 TYPE_ID mtyp1 = TY_mtype(ty_idx1);
00846
00847 if (MTYPE_size_min(mtyp1) > MTYPE_size_min(mtyp0) &&
00848 ! Has_Subsumed_Cvtl(WN_operator(var)))
00849 var = WN_CreateCvtl(OPR_CVTL, Widen_Mtype(mtyp0), MTYPE_V,
00850 MTYPE_size_min(mtyp0), var);
00851 if (MTYPE_size_min(mtyp0) > MTYPE_size_min(mtyp1) &&
00852 ! Has_Subsumed_Cvtl(WN_operator(ub)))
00853 ub = WN_CreateCvtl(OPR_CVTL, Widen_Mtype(mtyp1), MTYPE_V,
00854 MTYPE_size_min(mtyp1), ub);
00855
00856 if (WN_has_side_effects(ub))
00857 {
00858 TY_IDX ty_idx = MTYPE_TO_TY_array[WN_rtype(ub)];
00859 ST * st = Gen_Temp_Symbol (ty_idx, "__doloop_ub");
00860
00861 WGEN_add_pragma_to_enclosing_regions (WN_PRAGMA_LOCAL, st, TRUE);
00862 WN * stid = WN_Stid (TY_mtype(ty_idx), 0, st, ty_idx, ub);
00863
00864
00865 doloop_side_effects.push_back (stid);
00866 ub = WN_Ldid (TY_mtype(ty_idx), 0, st, ty_idx);
00867 }
00868 end = WN_CreateExp2(Operator_From_Tree_node(code),
00869 Widen_Mtype(mtyp), Widen_Mtype(mtyp0),
00870 var, ub);
00871 }
00872 else
00873 end = WGEN_Expand_Expr (logical_expr);
00874 }
00875
00876 code = gs_tree_code (incr_expr);
00877
00878 if (valid_for_expr && (code != GS_MODIFY_EXPR) && (code != GS_PREDECREMENT_EXPR) && (code != GS_PREINCREMENT_EXPR)
00879 && (code != GS_POSTDECREMENT_EXPR) && (code != GS_POSTINCREMENT_EXPR))
00880 {
00881 printf ("Invalid incr_expr in a FOR statement! \n");
00882 valid_for_expr = false;
00883 }
00884 else
00885 {
00886 incv = WGEN_Expand_Expr (gs_tree_operand (incr_expr, 0));
00887 if (gs_tree_code(init_expr) == GS_VAR_DECL)
00888 stlcv = ST_st_idx(tst);
00889 else
00890 stlcv = WN_st_idx(lcv);
00891 if (stlcv!=WN_st_idx(incv))
00892 {
00893 printf ("Invalid incr_expr in a FOR statement! \
00894 No induction variable to be modified.\n");
00895 valid_for_expr = false;
00896 }
00897 else
00898 {
00899 code1 = gs_tree_code (gs_tree_operand (incr_expr, 1));
00900 if ((code == GS_MODIFY_EXPR) && (code1 != GS_PLUS_EXPR) && (code1 != GS_MINUS_EXPR))
00901 {
00902 printf ("Invalid incr_expr in a FOR statement! \
00903 No such increment operation is permitted.\n");
00904 valid_for_expr = false;
00905 }
00906 else
00907 {
00908 WGEN_Stmt_Push (WN_CreateBlock (), wgen_stmk_comma, Get_Srcpos());
00909 WGEN_Expand_Expr (incr_expr, FALSE);
00910 wn_tmp = WGEN_Stmt_Pop (wgen_stmk_comma);
00911 step = WN_COPY_Tree( WN_first( wn_tmp ));
00912 WN_DELETE_Tree( wn_tmp );
00913
00914 }
00915 }
00916 }
00917 if (valid_for_expr)
00918 {
00919 WGEN_expand_start_do_loop (index, start, end, step);
00920 }
00921 else
00922 {
00923 SRCPOS srcpos = Get_Srcpos();
00924 Fail_FmtAssertion ("Invalid syntax in the FOR statement at line: %d, file number: %d.!\n",
00925 SRCPOS_linenum(srcpos), SRCPOS_filenum(srcpos));
00926 }
00927 }
00928
00929 void expand_end_do_loop (void)
00930 {
00931 WGEN_expand_end_do_loop();
00932 }