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
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103 static const char *source_file = __FILE__;
00104
00105
00106
00107
00108 #include "defs.h"
00109 #include "glob.h"
00110 #include "stab.h"
00111 #include "strtab.h"
00112 #include "errors.h"
00113 #include "targ_const.h"
00114 #include "config_targ.h"
00115 #include "config_debug.h"
00116 #include "const.h"
00117 #include "pu_info.h"
00118 #include "wn.h"
00119 #include "wn_util.h"
00120 #include "f90_utils.h"
00121 #include "targ_sim.h"
00122 #ifdef KEY
00123 #include "../../../clibinc/cray/io_byteswap.h"
00124 #endif
00125
00126
00127
00128 #include "i_cvrt.h"
00129
00130
00131
00132 #include "cwh_defines.h"
00133 #include "cwh_addr.h"
00134 #include "cwh_block.h"
00135 #include "cwh_expr.h"
00136 #include "cwh_stk.h"
00137 #include "cwh_types.h"
00138 #include "cwh_preg.h"
00139 #include "cwh_stab.h"
00140 #include "cwh_auxst.h"
00141 #include "cwh_intrin.h"
00142 #include "cwh_stmt.h"
00143 #include "cwh_dst.h"
00144 #include "cwh_directive.h"
00145 #include "cwh_preg.h"
00146 #include "sgi_cmd_line.h"
00147
00148 #include "cwh_stmt.i"
00149
00150 #include <libgen.h>
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165 extern void
00166 fei_stmt(INT32 lineno,
00167 INT32 stmt_character_flag )
00168 {
00169
00170 if (lineno) {
00171
00172 cwh_stmt_init_srcpos(lineno);
00173
00174
00175
00176 cwh_block_append_given(Defer_Block);
00177 }
00178 }
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191 extern void
00192 fei_user_code_start(void)
00193 {
00194 still_in_preamble = FALSE;
00195 cwh_block_append_given(Preamble_Block);
00196 cwh_stmt_add_pragma(WN_PRAGMA_PREAMBLE_END);
00197 cwh_block_append_given(First_Block);
00198 (void) cwh_block_toggle_debug(TRUE) ;
00199
00200 cwh_stk_verify_empty();
00201 }
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214 extern void
00215 fei_object_ref (INTPTR sym_idx,
00216 INT32 whole_array,
00217 INT32 whole_substring )
00218 {
00219 STB_pkt *p ;
00220
00221 p = cast_to_STB(sym_idx);
00222 DevAssert((p->form == is_ST),("Odd object ref"));
00223
00224 ST * st = cast_to_ST(p->item);
00225 DevAssert((st),("null st"));
00226
00227 if (whole_array) {
00228 cwh_stk_push(st,ST_item_whole_array) ;
00229 } else {
00230 cwh_stk_push(st,ST_item) ;
00231 }
00232 }
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243 extern void
00244 fei_seg_ref (INTPTR sym_idx )
00245 {
00246 STB_pkt *p ;
00247
00248 p = cast_to_STB(sym_idx);
00249 DevAssert((p->form == is_ST),("Odd seg ref"));
00250
00251 ST * st = cast_to_ST(p->item);
00252 DevAssert((st),("null st"));
00253
00254 cwh_stk_push(st,ST_item) ;
00255 }
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266 void
00267 fei_namelist_ref (INTPTR sym_idx )
00268 {
00269 fei_object_ref(sym_idx, 0, 0);
00270 }
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283 extern void
00284 fei_member_ref (INTPTR sym_idx )
00285 {
00286
00287 cwh_stk_push(cast_to_void(sym_idx),FLD_item) ;
00288 }
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311 extern INTPTR
00312 fei_constant ( TYPE type,
00313 INT32 Class,
00314 char *start,
00315 INT64 bitsize )
00316
00317 {
00318 WN * wn ;
00319 WN * wc ;
00320 TY_IDX ty ;
00321 INTPTR cn ;
00322 ST *st;
00323 #ifdef KEY
00324 STB_pkt *p = 0;
00325 #else
00326 STB_pkt *p ;
00327 #endif
00328
00329 switch ((CONSTANT_CLASS)Class) {
00330 case Arith_Const:
00331
00332 cn = fei_arith_con(type,(SLONG *)start) ;
00333 p = cast_to_STB(cn);
00334
00335 if (p->form == is_WN)
00336 wn = cast_to_WN(p->item);
00337 else
00338 wn = cwh_stab_const(cast_to_ST(p->item));
00339
00340 wc = WN_COPY_Tree(wn);
00341 wn = WN_COPY_Tree(wn);
00342 ty = cast_to_TY(t_TY(type));
00343 cwh_stk_push_typed(cast_to_void(wn),WN_item,ty) ;
00344 p = cwh_stab_packet_typed(wc,is_WN,ty);
00345
00346 break;
00347
00348 case Pattern_Const:
00349
00350 cn = fei_pattern_con(type,start,bitsize);
00351
00352 if (type.basic_type == Char_Fortran) {
00353
00354 st = (ST *) cast_to_void(cn);
00355 wn = WN_CreateIntconst (OPC_U4INTCONST,TY_size(ST_type(st)));
00356 cwh_stk_push_STR(wn,st,ST_type(st),ST_item);
00357 p = cwh_stab_packet(cast_to_void(cn),is_SCONST);
00358
00359 } else {
00360 cwh_stk_push(cast_to_void(cn),PCONST_item);
00361 p = cwh_stab_packet(cast_to_void(cn),is_PCONST);
00362 }
00363
00364 break;
00365
00366 default:
00367 DevAssert((0), ("Unimplemented constant"));
00368 break ;
00369 }
00370
00371 return(cast_to_long(p));
00372 }
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384 extern void
00385 fei_push_arith_con ( INTPTR cdx )
00386 {
00387 WN * wn ;
00388 TY_IDX ty ;
00389 STB_pkt *p;
00390
00391 p = cast_to_STB(cdx);
00392 wn = WN_COPY_Tree((WN *) p->item);
00393 ty = p->ty;
00394
00395 if (ty != 0)
00396 cwh_stk_push_typed(cast_to_void(wn),WN_item,ty) ;
00397 else
00398 cwh_stk_push(cast_to_void(wn),WN_item) ;
00399 }
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411 extern void
00412 fei_push_pattern_con ( INTPTR cdx )
00413 {
00414 ST *st;
00415 TY_IDX ty;
00416 WN *wn;
00417 STB_pkt *p;
00418
00419 p = cast_to_STB(cdx);
00420
00421
00422 st = (ST *) p->item;
00423
00424 if (p->form == is_SCONST) {
00425 ty = ST_type(st);
00426 wn = WN_CreateIntconst (OPC_U4INTCONST,TY_size(ty));
00427 cwh_stk_push_STR(wn,st,ty,ST_item);
00428
00429 } else {
00430 cwh_stk_push(st,PCONST_item);
00431 }
00432 }
00433 #ifdef KEY
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444 extern void
00445 fei_array_element_by_value() {
00446 TY_IDX save_type = cwh_stk_get_TY();
00447 enum item_class save_class = cwh_stk_get_class();
00448 WN *wn = cwh_stk_pop_WN();
00449
00450 if (wn != NULL && cwh_addr_is_array(wn)) {
00451 wn = cwh_addr_load_WN(wn, 0, save_type);
00452 }
00453 cwh_stk_push_typed(wn, save_class, save_type);
00454 }
00455 #endif
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478 extern void
00479 fei_store ( TYPE result_type )
00480 {
00481 WN * rhs ;
00482 WN * wn ;
00483 ST * st ;
00484 ST * rhs_st;
00485 TY_IDX ty;
00486 TY_IDX ts;
00487
00488 FLD_det det ;
00489
00490 if (cwh_stk_get_class() == STR_item) {
00491
00492 cwh_stmt_character_store(result_type);
00493
00494 } else if (cwh_stk_get_class() == PCONST_item) {
00495
00496 rhs_st = cwh_stk_pop_PCONST();
00497 ty = ST_type(rhs_st);
00498 rhs = cwh_addr_address_ST(rhs_st,0);
00499 rhs = cwh_addr_mload(rhs,0,ty,NULL);
00500 wn = cwh_expr_address(f_NONE);
00501 wn = cwh_addr_mstore(wn,0,ty,rhs) ;
00502 cwh_block_append(wn) ;
00503
00504 } else {
00505
00506 rhs = cwh_expr_operand(NULL);
00507
00508 if (rhs == NULL) {
00509 cwh_stk_pop_whatever() ;
00510 return ;
00511 }
00512
00513 switch(cwh_stk_get_class()) {
00514 case WN_item:
00515 case WN_item_whole_array:
00516 ts = cwh_stk_get_TY();
00517 wn = cwh_expr_address(f_NONE);
00518 wn = F90_Wrap_ARREXP(wn) ;
00519 cwh_addr_store_WN(wn,0,ts,rhs);
00520 break ;
00521
00522 case DEREF_item:
00523 ts = cwh_stk_get_TY();
00524 if (ts) {
00525
00526 ts = TY_pointed(FLD_type(TY_fld(Ty_Table[ts])));
00527 }
00528 wn = cwh_expr_address(f_NONE);
00529 wn = F90_Wrap_ARREXP(wn) ;
00530 cwh_addr_store_WN(wn,0,ts,rhs);
00531 break ;
00532
00533 case ST_item:
00534 case ST_item_whole_array:
00535 st = cwh_stk_pop_ST();
00536 cwh_addr_store_ST(st,0,0,rhs);
00537 break ;
00538
00539 case FLD_item:
00540 det = cwh_addr_offset();
00541
00542 if (cwh_stk_get_class() == ST_item ||
00543 cwh_stk_get_class() == ST_item_whole_array) {
00544
00545 st = cwh_stk_pop_ST();
00546 cwh_addr_store_ST(st,det.off,det.type,rhs);
00547
00548 } else {
00549
00550 wn = cwh_stk_pop_WHIRL();
00551 wn = cwh_expr_bincalc(OPR_ADD,wn,WN_Intconst(Pointer_Mtype,det.off));
00552 wn = F90_Wrap_ARREXP(wn);
00553 cwh_addr_store_WN(wn,0,det.type,rhs);
00554 }
00555 break;
00556
00557 default:
00558 DevAssert((0),("odd store LHS"));
00559 }
00560 }
00561 }
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580 extern void
00581 fei_non_conform_store( TYPE result_type )
00582 {
00583 WN *wd ;
00584 WN *wdl ;
00585 TY_IDX td ;
00586 TY_IDX ts1 ;
00587 TY_IDX ts2 ;
00588
00589 WN *wt ;
00590 WN *wtl ;
00591 TY_IDX tt ;
00592
00593 FLD_HANDLE f1 ;
00594 FLD_HANDLE f2 ;
00595 FLD_det d1 ;
00596 FLD_det d2 ;
00597
00598 switch(cwh_stk_get_class()) {
00599 case STR_item:
00600 cwh_stk_pop_STR();
00601 wtl = cwh_stk_pop_WN();
00602 ts1 = cwh_stk_get_TY();
00603 wt = cwh_stk_pop_WN();
00604 wt = cwh_expr_extract_arrayexp(wt,DELETE_ARRAYEXP_WN);
00605
00606 cwh_stk_pop_STR();
00607 wdl = cwh_stk_pop_WN();
00608 ts2 = cwh_stk_get_TY();
00609 wd = cwh_stk_pop_WN();
00610 wd = cwh_expr_extract_arrayexp(wd,DELETE_ARRAYEXP_WN);
00611
00612 cwh_addr_nonc_util(&wt,&wd);
00613
00614 cwh_stk_push_STR(wdl,wd,ts2,WN_item);
00615 cwh_stk_push_STR(wtl,wt,ts1,WN_item);
00616 break;
00617
00618 default:
00619
00620 if (cwh_stk_get_class() == FLD_item) {
00621 d1 = cwh_addr_offset();
00622 f1 = cwh_types_fld_dummy(d1.off,d1.type);
00623 }
00624 tt = cwh_stk_get_TY();
00625 wt = cwh_stk_pop_WHIRL();
00626
00627 if (!tt) {
00628 tt = cwh_types_WN_TY(wt,FALSE);
00629 }
00630
00631 wt = cwh_expr_extract_arrayexp(wt,DELETE_ARRAYEXP_WN);
00632
00633 if (cwh_stk_get_class() == FLD_item) {
00634 d2 = cwh_addr_offset();
00635 f2 = cwh_types_fld_dummy(d2.off,d2.type);
00636 }
00637 td = cwh_stk_get_TY();
00638 wd = cwh_stk_pop_WHIRL();
00639
00640 if (!td) {
00641 td = cwh_types_WN_TY(wd,FALSE);
00642 }
00643
00644 wd = cwh_expr_extract_arrayexp(wd,DELETE_ARRAYEXP_WN);
00645
00646 cwh_addr_nonc_util(&wt,&wd);
00647
00648 cwh_stk_push_typed(wd,WN_item,td);
00649 if (!f2.Is_Null ())
00650 cwh_stk_push((void *)(INTPTR)f2.Idx (),FLD_item);
00651
00652 cwh_stk_push_typed(wt,WN_item,tt);
00653 if (!f1.Is_Null ())
00654 cwh_stk_push((void *)(INTPTR)f1.Idx(),FLD_item);
00655
00656 }
00657
00658 fei_store(result_type);
00659 }
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676 static void
00677 cwh_stmt_character_store(TYPE result_type)
00678 {
00679 WN * src;
00680
00681 if (cwh_stk_is_byte_STR(0) &&
00682 cwh_stk_is_byte_STR(1)) {
00683
00684 cwh_stk_pop_STR();
00685 cwh_stk_pop_whatever();
00686 src = cwh_expr_operand(NULL);
00687 src = cwh_expr_dispose_of_char(src);
00688
00689 cwh_stk_pop_STR();
00690 cwh_stk_pop_whatever();
00691
00692 cwh_stk_push(src,WN_item);
00693 fei_store(result_type);
00694
00695 } else {
00696 cwh_stmt_character_icall(INTRN_CASSIGNSTMT);
00697 }
00698 }
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709 extern void
00710 fei_function_ref(INTPTR id)
00711 {
00712 STB_pkt *p;
00713
00714 p = cast_to_STB(id) ;
00715
00716 DevAssert((p->form == is_ST),("Fn ST missing"));
00717 DevAssert((p->item != NULL),("NULL fn imp"));
00718
00719 cwh_stk_push(cast_to_ST(p->item), ST_item);
00720 }
00721
00722 #ifdef KEY
00723
00724
00725
00726
00727 TY_IDX array_of_struct_by_value(TY_IDX t) {
00728 if (TY_kind(t) == KIND_ARRAY) {
00729 t = cwh_types_scalar_TY(t);
00730 if (STRUCT_BY_VALUE(t)) {
00731 return t;
00732 }
00733 }
00734 return (TY_IDX) -1;
00735 }
00736 #endif
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772 #include "ir_reader.h"
00773 extern WN *
00774 cwh_stmt_call_helper(INT32 num_args, TY_IDX ty, INT32 inline_state, INT64 flags)
00775 {
00776 WN * wc ;
00777 WN * call_wn ;
00778 WN * wn ;
00779 WN * wa ;
00780 WN * wt ;
00781 WN ** args;
00782 ST * st ;
00783 ST * rt ;
00784 TY_IDX ta ;
00785 TY_IDX ts ;
00786 TY_IDX tr ;
00787 INT32 nargs;
00788 INT32 clen ;
00789 INT32 i,k ;
00790 WN * block;
00791
00792 TYPE_ID rbtype1;
00793 TYPE_ID rbtype2;
00794 OPCODE opc;
00795
00796 BOOL forward_barrier = FALSE;
00797 BOOL backward_barrier = FALSE;
00798 WN * barrier_wn;
00799 #ifdef KEY
00800
00801
00802
00803 WN *case4_array_temp = 0;
00804 TY_IDX case4_base_type = (TY_IDX) -1;
00805 #endif
00806
00807
00808
00809 nargs = num_args + cwh_stk_count_STRs(num_args) ;
00810 clen = nargs ;
00811 rt = NULL;
00812
00813 args = (WN **) malloc(nargs*sizeof(WN *));
00814
00815 for (k = num_args -1 ; k >= 0 ; k --) {
00816
00817 switch(cwh_stk_get_class()) {
00818 case STR_item:
00819 cwh_stk_pop_STR();
00820 wa = cwh_stk_pop_WN();
00821 wc = WN_COPY_Tree(wa);
00822 args[--clen] = cwh_intrin_wrap_value_parm(wa);
00823 wa = cwh_stk_pop_ADDR();
00824 args[k] = cwh_intrin_wrap_char_parm(wa,wc);
00825 break ;
00826
00827 case ADDR_item:
00828 ta = cwh_stk_get_TY();
00829 wa = cwh_stk_pop_ADDR();
00830 args[k] = cwh_intrin_wrap_ref_parm(wa,ta);
00831 break;
00832
00833 case WN_item:
00834 case WN_item_whole_array:
00835 wa = cwh_stk_pop_WN();
00836 wa = cwh_intrin_wrap_value_parm(wa);
00837
00838 args[k] = wa;
00839 break ;
00840
00841 case FLD_item:
00842 case ST_item:
00843 case ST_item_whole_array:
00844 wa = cwh_expr_operand(NULL);
00845 wa = cwh_intrin_wrap_value_parm(wa);
00846 args[k] = wa;
00847 break ;
00848
00849 case DEREF_item:
00850 wa = cwh_stk_pop_DEREF();
00851 wa = cwh_intrin_wrap_value_parm(wa);
00852 args[k] = wa;
00853 break;
00854
00855 default:
00856 DevAssert((0),("Odd call actual")) ;
00857 }
00858 }
00859
00860
00861
00862
00863
00864
00865
00866
00867 st = cwh_stk_pop_ST();
00868 ts = ty ;
00869 tr = ty ;
00870
00871 if (ST_class(st) != CLASS_FUNC) {
00872
00873
00874 DevAssert((TY_kind(ST_type(st)) == KIND_POINTER &&
00875 TY_kind(TY_pointed(ST_type(st))) == KIND_FUNCTION),
00876 ("Odd ST"));
00877
00878 tr = TY_ret_type(TY_pointed(ST_type(st)));
00879 }
00880
00881 if (ST_auxst_has_rslt_tmp(st) || cwh_types_is_character(tr)) {
00882
00883 tr = cwh_types_WN_TY(args[0],FALSE);
00884
00885 if (cwh_types_is_character(tr)) {
00886
00887 wt = args[clen];
00888
00889 for (k = clen ; k > 1 ; k--)
00890 args[k] = args[k-1];
00891
00892 args[1] = wt;
00893
00894 } else if (STRUCT_BY_VALUE(tr)) {
00895
00896 DevAssert((WNOPR(args[0]) == OPR_PARM),("Odd result"));
00897 wt = WN_kid(args[0],0);
00898
00899 DevAssert((wt != NULL),("struct w/o temp"));
00900 DevAssert((WNOPR(wt) == OPR_LDA),("struct w/o ADDR_item"));
00901
00902 rt = WN_st(wt);
00903 ts = tr ;
00904
00905 nargs --;
00906
00907 for (i=0; i < nargs; i++)
00908 args[i] = args[i+1];
00909
00910 }
00911 #ifdef KEY
00912 else if ((ST_auxst_is_elemental(st)) && (TY_mtype(tr) != MTYPE_V)) {
00913 case4_base_type = array_of_struct_by_value(tr);
00914 if (case4_base_type != (TY_IDX) -1) {
00915 DevAssert((WNOPR(args[0]) == OPR_PARM),("Odd result"));
00916 case4_array_temp = WN_kid(args[0],0);
00917 wt = WN_kid(case4_array_temp,0);
00918
00919 DevAssert((wt != NULL),("struct w/o temp"));
00920 DevAssert((WNOPR(wt) == OPR_LDA),("struct w/o ADDR_item"));
00921
00922 rt = WN_st(wt);
00923 ts = case4_base_type ;
00924
00925 nargs --;
00926
00927 for (i=0; i < nargs; i++)
00928 args[i] = args[i+1];
00929 }
00930 }
00931 #endif
00932 }
00933
00934
00935
00936
00937 if (WHIRL_Return_Info_On) {
00938
00939 RETURN_INFO return_info = Get_Return_Info (ts, Use_Simulated);
00940
00941 if (RETURN_INFO_count(return_info) <= 2 ||
00942 WHIRL_Return_Val_On) {
00943
00944 rbtype1 = RETURN_INFO_mtype (return_info, 0);
00945 rbtype2 = RETURN_INFO_mtype (return_info, 1);
00946 }
00947
00948 else
00949 Fail_FmtAssertion ("cwh_stmt_call_helper: more than 2 return registers");
00950 }
00951
00952 else
00953 Get_Return_Mtypes(ts, Use_Simulated, &rbtype1,&rbtype2);
00954
00955
00956 if (ST_sclass(st) != SCLASS_FORMAL) {
00957
00958 opc = OPCODE_make_op(OPR_CALL,TY_mtype(ts),MTYPE_V);
00959 wn = WN_Create(opc,nargs);
00960 WN_st_idx(wn) = ST_st_idx(st);
00961
00962
00963
00964
00965 if (cwh_stmt_sgi_mp_flag) {
00966 if (rbtype1==MTYPE_V && ST_name(st) &&
00967 ST_name(st)[0]=='m' && ST_name(st)[1]=='p') {
00968 if (!strcmp(&(ST_name(st)[2]),"_setlock_")) {
00969 backward_barrier = TRUE;
00970 } else if (!strcmp(&(ST_name(st)[2]),"_unsetlock_")) {
00971 forward_barrier = TRUE;
00972 } else if (!strcmp(&(ST_name(st)[2]),"_barrier_")) {
00973 forward_barrier = TRUE;
00974 backward_barrier = TRUE;
00975 }
00976 }
00977 }
00978
00979 } else {
00980
00981 opc = OPCODE_make_op (OPR_ICALL,TY_mtype(ts),MTYPE_V);
00982 wn = WN_Create(opc,nargs+1);
00983 WN_set_ty(wn,TY_pointed(ST_type(st)));
00984 WN_kid(wn,nargs) = cwh_addr_load_ST(st,0,ST_type(st));
00985 }
00986
00987 if (forward_barrier) {
00988 barrier_wn=WN_CreateBarrier ( TRUE, 0 );
00989 cwh_block_append(barrier_wn);
00990 }
00991
00992
00993 WN_Set_Call_Default_Flags(wn);
00994 WN_Set_Call_Fortran_Pointer_Rule(wn);
00995
00996 if (FE_Call_Never_Return &&
00997 test_flag(flags, FEI_CALL_DOES_NOT_RETURN)) {
00998 WN_Set_Call_Never_Return(wn);
00999 }
01000
01001 if (inline_state == 1) {
01002
01003 WN_Set_Call_Inline(wn);
01004 fe_invoke_inliner = TRUE;
01005 } else if (inline_state == 2) {
01006
01007 WN_Set_Call_Dont_Inline(wn);
01008 }
01009
01010 call_wn = wn;
01011
01012 for (i=0; i < nargs; i++) {
01013 WN_kid(wn,i) = args[i];
01014 }
01015
01016 free(args);
01017
01018
01019
01020
01021
01022
01023
01024
01025 if ((ST_auxst_is_elemental(st)) && (TY_mtype(ts) != MTYPE_V)) {
01026
01027
01028
01029 block = cwh_block_new_and_current();
01030 cwh_block_append(wn);
01031 block = cwh_block_exchange_current(block);
01032
01033 #ifdef KEY
01034
01035
01036 WN *stmt_return_block = cwh_block_new_and_current();
01037 if (case4_base_type != ((TY_IDX) -1)) {
01038 wn = cwh_stmt_return_scalar(rt,NULL,case4_base_type,FALSE);
01039 } else {
01040 wn = cwh_stmt_return_scalar(rt,NULL,ts,FALSE);
01041 }
01042 stmt_return_block = cwh_block_exchange_current(stmt_return_block);
01043 opc = cwh_make_typed_opcode(OPR_COMMA,rbtype1,MTYPE_V);
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083 if (NULL == wn) {
01084 WN *store = WN_first(stmt_return_block);
01085 WN *load = WN_kid0(store);
01086 wn = WN_CreateComma(opc,block,load);
01087 if (case4_array_temp) {
01088 cwh_stk_push_typed(case4_array_temp,WN_item,tr);
01089 cwh_stk_push_typed(wn,WN_item,tr);
01090 TYPE pdg_type_void = fei_descriptor(0, Basic, 0, V_oid, 0, 0);
01091 fei_store(pdg_type_void);
01092 }
01093 else {
01094 WN_kid0(store) = wn;
01095 cwh_block_append(store);
01096 }
01097 }
01098 else {
01099 wn = WN_CreateComma(opc,block,wn);
01100 cwh_stk_push_typed(wn,WN_item,ty);
01101 }
01102 #else
01103 wn = cwh_stmt_return_scalar(rt,NULL,ts,FALSE);
01104 opc = cwh_make_typed_opcode(OPR_COMMA,rbtype1,MTYPE_V);
01105 wn = WN_CreateComma(opc,block,wn);
01106 cwh_stk_push_typed(wn,WN_item,ty);
01107 #endif
01108
01109 } else {
01110
01111
01112
01113 if (ST_auxst_is_elemental(st)) {
01114
01115 for (k = 0; k < nargs; k ++) {
01116 WN_kid0(WN_kid(wn,k)) = F90_Wrap_ARREXP(WN_kid0(WN_kid(wn,k)));
01117 }
01118 }
01119 cwh_block_append(wn);
01120
01121
01122
01123
01124
01125
01126 if (TY_mtype(ts) != MTYPE_V) {
01127
01128 wn = cwh_stmt_return_scalar(rt,NULL,ts,FALSE);
01129
01130 if (wn != NULL)
01131 cwh_stk_push(wn,WN_item);
01132 }
01133 }
01134
01135 if (backward_barrier) {
01136 barrier_wn=WN_CreateBarrier ( FALSE, 0 );
01137 cwh_block_append(barrier_wn);
01138 }
01139
01140 return (call_wn);
01141 }
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161 extern void
01162 fei_call(INT32 num_args,
01163 TYPE result_type,
01164 INT32 call_type,
01165 INT32 alt_return_flag,
01166 INT32 inline_setting,
01167 INT64 flags)
01168
01169 {
01170 TY_IDX ty;
01171 ty = cast_to_TY(t_TY(result_type));
01172 (void) cwh_stmt_call_helper(num_args,ty,inline_setting,flags);
01173 }
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192 extern void
01193 fei_arg_addr(TYPE type)
01194 {
01195 WN * wn ;
01196 WN * wa ;
01197 TY_IDX ty ;
01198 TY_IDX ts ;
01199 FLD_HANDLE fld;
01200 FLD_det det;
01201
01202 switch(cwh_stk_get_class()) {
01203 case STR_item:
01204 cwh_stk_pop_STR();
01205 wn = cwh_stk_pop_WN();
01206 ts = cwh_stk_get_TY();
01207 wa = cwh_expr_address(f_T_PASSED);
01208 cwh_stk_push_STR(wn,wa,ts,ADDR_item);
01209 break;
01210
01211 case FLD_item:
01212 det = cwh_addr_offset();
01213 fld = cwh_types_fld_dummy(det.off,det.type);
01214 cwh_stk_push((void *)(INTPTR)fld.Idx (),FLD_item);
01215 wa = cwh_expr_address(f_T_PASSED);
01216 cwh_stk_push_typed(wa,ADDR_item, cwh_types_make_pointer_type(det.type, FALSE));
01217 break;
01218
01219 case WN_item_whole_array:
01220 wa = cwh_expr_address(f_T_PASSED);
01221 DevAssert ((WNOPR(wa) == OPR_ARRAY), ("Whole array isnt an ARRAY"));
01222 wa = WN_kid0(wa);
01223 ty = cwh_types_WN_TY(wa,FALSE);
01224 ty = cwh_types_make_pointer_type(ty, FALSE);
01225 cwh_stk_push_typed(wa,ADDR_item,ty);
01226 break;
01227
01228 default:
01229 wa = cwh_expr_address(f_T_PASSED);
01230 if (WNOPR(wa) == OPR_ARRAY) {
01231 ty = cwh_types_WN_TY(wa,FALSE);
01232 ty = cwh_types_array_TY(ty);
01233 ty = cwh_types_scalar_TY(ty);
01234 ty = cwh_types_make_pointer_type(ty, FALSE);
01235 cwh_stk_push_typed(wa,ADDR_item,ty);
01236
01237 } else
01238 cwh_stk_push(wa,ADDR_item);
01239 break;
01240 }
01241 }
01242
01243
01244
01245
01246
01247
01248
01249
01250
01251
01252
01253
01254
01255 void
01256 fei_fcd(TYPE result_type)
01257 {
01258 #ifdef KEY
01259 WN *wn = 0;
01260 #else
01261 WN *wn ;
01262 #endif
01263 WN *ad ;
01264 WN *ln ;
01265 TY_IDX ts ;
01266
01267 ts = cwh_stk_get_TY();
01268 ad = cwh_stk_pop_WHIRL();
01269 ln = cwh_stk_pop_WHIRL();
01270
01271 if (WNOPR(ad) == OPR_INTCONST) {
01272
01273 wn = WN_Intconst(Pointer_Mtype,WN_const_val(ad));
01274
01275 WN_DELETE_Tree(ad);
01276 ad = wn;
01277
01278 }
01279 if (ts == 0)
01280 ts = cwh_types_WN_TY(wn,FALSE);
01281
01282 cwh_stk_push_STR(ln,ad,ts,ADDR_item);
01283
01284 }
01285
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295 extern void
01296 fei_addr_con(TYPE type)
01297 {
01298 WN * wn;
01299 WN * wt;
01300 ST * st;
01301 TY_IDX ty;
01302
01303 TCON tc ;
01304 TYPE_ID bt ;
01305
01306
01307 switch (cwh_stk_get_class()) {
01308 case STR_item:
01309 cwh_stk_pop_STR();
01310 wn = cwh_stk_pop_WN();
01311 ty = cwh_stk_get_TY();
01312 wt = cwh_expr_address(f_T_PASSED);
01313 cwh_stk_push_STR(wn,wt,ty,ADDR_item);
01314 break;
01315
01316 default:
01317 ty = cwh_stk_get_TY();
01318 wn = cwh_stk_pop_WN();
01319
01320 if (WNOPR(wn) == OPR_INTCONST) {
01321
01322 if (ty == 0) {
01323 bt = WNRTY(wn);
01324 } else {
01325 bt = TY_mtype(ty);
01326 }
01327 tc = Host_To_Targ (bt,WN_const_val(wn));
01328 st = New_Const_Sym(Enter_tcon (tc), Be_Type_Tbl(bt));
01329
01330 } else
01331 st = WN_st(wn);
01332
01333 wt = cwh_addr_address_ST(st,0);
01334 cwh_stk_push(wt,ADDR_item);
01335 }
01336 }
01337
01338
01339
01340
01341
01342
01343
01344
01345
01346
01347 extern void
01348 fei_entry_pt(INTPTR idx)
01349 {
01350 ST *st ;
01351 ST **ap ;
01352 WN *wn ;
01353 STB_pkt *p ;
01354
01355 INT16 nkids,i ;
01356
01357 p = cast_to_STB(idx);
01358 st = cast_to_ST(p->item);
01359
01360 nkids = cwh_auxst_num_dummies(st);
01361 ap = cwh_auxst_arglist(st);
01362
01363 wn = WN_Create (OPC_ALTENTRY, nkids);
01364 WN_st_idx(wn) = ST_st_idx(st);
01365
01366 for (i = 0 ; i < nkids ; i ++)
01367 WN_kid(wn,i) = WN_CreateIdname ( 0, *ap++);
01368
01369 cwh_block_append(wn) ;
01370 (void) cwh_block_toggle_debug(FALSE) ;
01371 }
01372
01373
01374
01375
01376
01377
01378
01379
01380
01381 extern void
01382 fei_goto(INTPTR lbl_idx)
01383 {
01384 LABEL_IDX lb ;
01385
01386 lb = cast_to_LB(lbl_idx);
01387 cwh_stmt_goto(lb);
01388 }
01389
01390
01391
01392
01393
01394
01395
01396
01397
01398
01399
01400
01401
01402
01403
01404
01405
01406
01407 extern void
01408 fei_arith_goto(INTPTR eq_lbl,
01409 INTPTR gt_lbl,
01410 INTPTR lt_lbl )
01411 {
01412 WN *expr;
01413 WN *val1, *val2;
01414 WN *wn;
01415 LABEL_IDX lb ;
01416 TY_IDX ty;
01417 OPCODE opc;
01418 OPERATOR opr;
01419 INTPTR true_lbl;
01420 INTPTR false_lbl;
01421
01422
01423 if (lt_lbl == eq_lbl && gt_lbl == eq_lbl) {
01424
01425
01426
01427 cwh_stmt_goto(cast_to_LB(eq_lbl));
01428 expr = cwh_expr_operand(NULL);
01429
01430 } else {
01431
01432 expr = cwh_expr_operand(NULL);
01433 ty = Be_Type_Tbl(WN_rtype(expr));
01434
01435 if ( WN_operator(expr) == OPR_SUB ) {
01436 val1 = WN_kid0(expr);
01437 val2 = WN_kid1(expr);
01438 } else {
01439 val1 = expr;
01440 if (MTYPE_is_integral(TY_mtype(ty))) {
01441 opc = cwh_make_typed_opcode(OPR_INTCONST, TY_mtype(ty), MTYPE_V);
01442 val2 = WN_CreateIntconst ( opc, 0 );
01443 } else {
01444 val2 = Make_Zerocon ( TY_mtype(ty) );
01445 }
01446 }
01447
01448 if (eq_lbl != lt_lbl &&
01449 eq_lbl != gt_lbl &&
01450 lt_lbl != gt_lbl ) {
01451
01452
01453
01454 lb = cast_to_LB(lt_lbl);
01455
01456 wn = cwh_stmt_truebr(WN_COPY_Tree(val1), WN_COPY_Tree(val2), ty, OPR_LT,lb);
01457 cwh_block_append(wn);
01458
01459 lb = cast_to_LB(gt_lbl);
01460 wn = cwh_stmt_truebr(WN_COPY_Tree(val1), WN_COPY_Tree(val2), ty, OPR_GT,lb);
01461 cwh_block_append(wn);
01462 cwh_stmt_goto(cast_to_LB(eq_lbl));
01463
01464
01465 } else {
01466
01467
01468
01469 if (eq_lbl == lt_lbl) {
01470 opr = OPR_LE;
01471 true_lbl = eq_lbl;
01472 false_lbl = gt_lbl;
01473
01474 } else if (eq_lbl == gt_lbl) {
01475 opr = OPR_GE;
01476 true_lbl = eq_lbl;
01477 false_lbl = lt_lbl;
01478
01479 } else {
01480 opr = OPR_NE;
01481 true_lbl = gt_lbl;
01482 false_lbl = eq_lbl;
01483 }
01484
01485 lb = cast_to_LB(true_lbl);
01486 wn = cwh_stmt_truebr(WN_COPY_Tree(val1), WN_COPY_Tree(val2), ty, opr,lb);
01487 cwh_block_append(wn);
01488 cwh_stmt_goto(cast_to_LB(false_lbl));
01489 }
01490 }
01491 }
01492
01493
01494
01495
01496
01497
01498
01499
01500
01501 extern void
01502 fei_label_ref(INTPTR lbl_idx)
01503 {
01504 LABEL_IDX lb;
01505 lb = cast_to_LB(lbl_idx);
01506 cwh_stk_push(cast_to_void((INTPTR)lb),LB_item);
01507 }
01508
01509
01510
01511
01512
01513
01514
01515
01516
01517
01518
01519
01520
01521
01522
01523
01524
01525
01526 extern void
01527 fei_label_addr(INTPTR lbl_idx)
01528 {
01529 WN *wn;
01530 INT32 *assign_id;
01531
01532 assign_id = cwh_auxst_assign_id(CURRENT_SYMTAB, LABEL_IDX_index((LABEL_IDX)lbl_idx));
01533
01534 if (*assign_id == -1)
01535 *assign_id = cwh_assign_label_id++;
01536
01537 wn = WN_CreateIntconst (OPC_I4INTCONST, *assign_id);
01538 cwh_stk_push(wn, WN_item);
01539 }
01540
01541
01542
01543
01544
01545
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555
01556
01557 static void
01558 cwh_stmt_computed_goto(INT32 num_labels)
01559 {
01560 LABEL_IDX *label_list;
01561 LABEL_IDX default_label_num = 0;
01562 WN *parent_block;
01563 WN *wn;
01564 WN *default_label;
01565 WN *expr;
01566 OPERATOR opr;
01567 LABEL_IDX lb;
01568 LABEL_IDX last_label=0;
01569 INT32 sequences=0;
01570 INT32 count;
01571 INT32 i;
01572
01573 label_list = (LABEL_IDX *) malloc(num_labels*sizeof(LABEL_IDX));
01574
01575 for(i=num_labels-1; i>=0; i--) {
01576 label_list[i] = cwh_stk_pop_LB();
01577 if (label_list[i] != last_label) {
01578 sequences++;
01579 last_label = label_list[i];
01580 }
01581 }
01582
01583 expr = cwh_expr_operand(NULL);
01584
01585 if (num_labels == 1) {
01586
01587 cwh_stmt_append_truebr(WN_COPY_Tree(expr),1, OPR_EQ, label_list[0]);
01588
01589 } else if ( sequences == 1 && num_labels >= 2) {
01590
01591 (void) New_LABEL (CURRENT_SYMTAB, default_label_num);
01592
01593 cwh_stmt_append_truebr(WN_COPY_Tree(expr),1, OPR_LT,default_label_num);
01594 cwh_stmt_append_truebr(WN_COPY_Tree(expr),num_labels, OPR_LE,label_list[0]);
01595
01596 } else if ( num_labels <= COMPGOTO_IF_ELSE) {
01597
01598 for(i=0; i<num_labels; i++) {
01599 cwh_stmt_append_truebr(WN_COPY_Tree(expr),i+1,OPR_EQ,label_list[i]);
01600 }
01601
01602 } else if (sequences <= COMPGOTO_IF_ELSE) {
01603
01604 (void) New_LABEL (CURRENT_SYMTAB, default_label_num);
01605 cwh_stmt_append_truebr(WN_COPY_Tree(expr),1,OPR_LT,default_label_num);
01606
01607 last_label = label_list[0];
01608 count = 0;
01609
01610 for(i=0; i<num_labels; i++) {
01611 if (label_list[i] == last_label) {
01612 count++;
01613 } else {
01614 lb = last_label;
01615 if (count == 1)
01616 opr = OPR_EQ;
01617 else
01618 opr = OPR_LE;
01619 cwh_stmt_append_truebr(WN_COPY_Tree(expr),i,opr,lb);
01620 count = 1;
01621 last_label = label_list[i];
01622 }
01623 }
01624
01625 if (count == 1)
01626 opr = OPR_EQ;
01627 else
01628 opr = OPR_LE;
01629
01630 cwh_stmt_append_truebr(WN_COPY_Tree(expr),num_labels,opr,last_label);
01631
01632 } else {
01633
01634 parent_block = cwh_block_new_and_current();
01635 (void) New_LABEL (CURRENT_SYMTAB, default_label_num);
01636 cwh_stmt_goto(default_label_num);
01637
01638 for(i=0; i<num_labels; i++) {
01639 cwh_stmt_goto(label_list[i]);
01640 }
01641
01642 default_label = WN_CreateGoto (default_label_num);
01643 wn = WN_CreateCompgoto (num_labels+1, expr, cwh_block_current(), default_label, 0);
01644 cwh_block_set_current(parent_block);
01645 cwh_block_append(wn);
01646
01647 }
01648
01649 if (default_label_num) {
01650 wn = WN_CreateLabel(default_label_num, 0,NULL);
01651 cwh_block_append(wn);
01652 }
01653 }
01654
01655
01656
01657
01658
01659
01660
01661
01662
01663
01664
01665
01666
01667
01668
01669
01670
01671 static void
01672 cwh_stmt_assigned_goto(INT32 num_labels)
01673 {
01674 INT32 i;
01675 LABEL_IDX default_label_num = 0;
01676 WN *expr;
01677 WN *parent_block;
01678 WN *wn;
01679 WN *default_label;
01680 LABEL_IDX lb;
01681 LABEL_IDX *cwh_assign_label_array=NULL;
01682
01683 cwh_assign_label_array = (LABEL_IDX *) malloc (sizeof(LABEL_IDX *) * num_labels);
01684
01685 for(i=0; i<num_labels; i++)
01686 cwh_assign_label_array[i] = cwh_stk_pop_LB();
01687
01688 expr = cwh_expr_operand(NULL);
01689
01690 if (num_labels <= COMPGOTO_IF_ELSE) {
01691
01692 for(i=0; i<num_labels; i++ ) {
01693 lb = cwh_assign_label_array [i];
01694 cwh_stmt_append_truebr(WN_COPY_Tree(expr),i,OPR_EQ,lb);
01695 }
01696
01697 } else {
01698
01699 parent_block = cwh_block_new_and_current();
01700 (void) New_LABEL (CURRENT_SYMTAB, default_label_num);
01701 default_label = WN_CreateGoto (default_label_num);
01702
01703 for(i=0; i<num_labels; i++ ) {
01704 cwh_stmt_goto(cwh_assign_label_array [i]);
01705 }
01706
01707 wn = WN_CreateCompgoto (num_labels, expr, cwh_block_current(), default_label, 0);
01708 cwh_block_set_current(parent_block);
01709 cwh_block_append(wn);
01710 wn = WN_CreateLabel(default_label_num, 0,NULL);
01711 cwh_block_append(wn);
01712 }
01713 }
01714
01715
01716
01717
01718
01719
01720
01721
01722
01723
01724
01725
01726 static WN *
01727 cwh_stmt_truebr(WN *expr, WN *val, TY_IDX ty, OPERATOR opr, INT32 label_no)
01728 {
01729 WN * wn;
01730 WN * test;
01731
01732 OPCODE opc;
01733
01734 opc = cwh_make_typed_opcode(opr, MTYPE_I4, Mtype_comparison(TY_mtype(ty)));
01735 test = WN_CreateExp2 ( opc, expr, val);
01736 wn = WN_CreateTruebr (label_no, test );
01737
01738 return wn;
01739 }
01740
01741
01742
01743
01744
01745
01746
01747
01748
01749
01750
01751 static void
01752 cwh_stmt_append_truebr(WN *expr, INT64 con, OPERATOR opr, INT32 label_no)
01753 {
01754 WN * wn;
01755 WN * val;
01756 TY_IDX ty;
01757 OPCODE opc;
01758
01759 ty = Be_Type_Tbl(WN_rtype(expr));
01760 opc = cwh_make_typed_opcode(OPR_INTCONST, TY_mtype(ty), MTYPE_V);
01761
01762 val = WN_CreateIntconst (opc,con);
01763 wn = cwh_stmt_truebr(expr,val,ty,opr,label_no) ;
01764 cwh_block_append(wn);
01765 }
01766
01767
01768
01769
01770
01771
01772
01773
01774
01775
01776
01777 static WN *
01778 cwh_stmt_falsebr(WN *expr, WN *val, TY_IDX ty, OPERATOR opr, INT32 label_no)
01779 {
01780 WN * wn;
01781 WN * test;
01782
01783 OPCODE opc;
01784
01785 opc = cwh_make_typed_opcode(opr, MTYPE_I4, Mtype_comparison(TY_mtype(ty)));
01786 test = WN_CreateExp2 ( opc, expr, val);
01787 wn = WN_CreateFalsebr (label_no, test );
01788
01789 return wn;
01790 }
01791
01792
01793
01794
01795
01796
01797
01798
01799
01800
01801 static void
01802 cwh_stmt_goto(LABEL_IDX label)
01803 {
01804 WN * wn;
01805 wn = WN_CreateGoto(label);
01806 cwh_block_append(wn) ;
01807 }
01808
01809
01810
01811
01812
01813
01814
01815
01816
01817
01818
01819
01820 extern void
01821 fei_indirect_goto(INT32 num_labels,
01822 INT32 assign_goto_flag )
01823 {
01824
01825 if (assign_goto_flag == 0)
01826 cwh_stmt_computed_goto(num_labels);
01827 else
01828 cwh_stmt_assigned_goto(num_labels);
01829 }
01830
01831
01832
01833
01834
01835
01836
01837
01838
01839
01840
01841
01842
01843
01844
01845
01846
01847
01848
01849
01850
01851
01852
01853
01854
01855
01856
01857 static void
01858 cwh_stmt_select_char(INT32 num_cases,
01859 INTPTR default_label_idx )
01860 {
01861 WN *wn1;
01862 W_node expr[2];
01863 WN *default_label;
01864 WN *last_node;
01865 LABEL_IDX lb;
01866
01867 cwh_expr_str_operand(expr);
01868
01869 if (num_cases > 0) {
01870
01871 last_node = WN_last(cwh_block_current());
01872
01873 lb = cast_to_LB(default_label_idx);
01874 default_label = WN_CreateGoto (lb);
01875
01876
01877
01878 wn1 = WN_CreateIntconst(OPC_I4INTCONST, num_cases);
01879 cwh_stk_push(wn1, WN_item);
01880 cwh_stk_push(default_label, WN_item);
01881 cwh_stk_push_STR(W_wn(expr[0]), W_wn(expr[1]),W_ty(expr[1]), WN_item);
01882 cwh_stk_push(last_node, WN_item);
01883
01884 } else {
01885
01886 WN_DELETE_Tree(W_wn(expr[0]));
01887 WN_DELETE_Tree(W_wn(expr[1]));
01888
01889 }
01890 }
01891
01892
01893
01894
01895
01896
01897
01898
01899
01900
01901
01902
01903
01904
01905
01906
01907
01908
01909
01910
01911
01912
01913
01914
01915
01916
01917
01918
01919
01920
01921
01922
01923
01924
01925
01926
01927
01928
01929
01930
01931 static void
01932 cwh_stmt_select_case_char(INT32 low_value_pres,
01933 INT32 high_value_pres,
01934 INT32 case_follows)
01935 {
01936 W_node val[2];
01937 W_node high_val[2];
01938 W_node expr[2];
01939
01940 WN *copy[2];
01941 #ifdef KEY
01942 copy[0] = copy[1] = 0;
01943 #endif
01944 WN *wn1;
01945
01946 WN *last_node;
01947 WN *default_label;
01948 LABEL_IDX label;
01949 INT32 remaining_cases;
01950 LABEL_IDX new_label_num=0;
01951 OPERATOR opr;
01952
01953 if (low_value_pres && high_value_pres)
01954 cwh_expr_str_operand(high_val);
01955
01956 cwh_expr_str_operand(val);
01957 label = cwh_stk_pop_LB();
01958 last_node = cwh_expr_operand(NULL);
01959 cwh_expr_str_operand(expr);
01960 default_label = cwh_expr_operand(NULL);
01961 remaining_cases = WN_const_val(cwh_expr_operand(NULL));
01962 (void) New_LABEL (CURRENT_SYMTAB, new_label_num);
01963
01964 if (remaining_cases > 0) {
01965 copy[0] = WN_COPY_Tree(W_wn(expr[0]));
01966 copy[1] = WN_COPY_Tree(W_wn(expr[1]));
01967 }
01968
01969 if (low_value_pres && high_value_pres) {
01970
01971 WN *cpy[2];
01972
01973 cpy[0] = WN_COPY_Tree(W_wn(expr[0]));
01974 cpy[1] = WN_COPY_Tree(W_wn(expr[1]));
01975
01976 last_node = cwh_stmt_str_falsebr_util(OPR_GE,
01977 expr,
01978 val,
01979 new_label_num,
01980 last_node);
01981
01982 W_wn(expr[0]) = cpy[0];
01983 W_wn(expr[1]) = cpy[1];
01984
01985 last_node = cwh_stmt_str_falsebr_util(OPR_LE,
01986 expr,
01987 high_val,
01988 new_label_num,
01989 last_node);
01990 } else {
01991
01992 if (low_value_pres)
01993 opr = OPR_GE;
01994 else if (high_value_pres)
01995 opr = OPR_LE;
01996 else
01997 opr = OPR_EQ;
01998
01999 last_node = cwh_stmt_str_falsebr_util(opr,
02000 expr,
02001 val,
02002 new_label_num,
02003 last_node);
02004 }
02005
02006 wn1 = WN_CreateGoto(label);
02007 cwh_block_insert_after(last_node, wn1);
02008 last_node = wn1;
02009
02010 wn1 = WN_CreateLabel(new_label_num, 0,NULL);
02011 cwh_block_insert_after(last_node, wn1);
02012 last_node = wn1;
02013
02014 remaining_cases = remaining_cases - 1;
02015
02016 if (remaining_cases != 0) {
02017
02018 wn1 = WN_CreateIntconst(OPC_I4INTCONST, remaining_cases);
02019 cwh_stk_push(wn1, WN_item);
02020 cwh_stk_push(default_label, WN_item);
02021 cwh_stk_push_STR(copy[0], copy[1],W_ty(expr[1]),WN_item);
02022 cwh_stk_push(last_node, WN_item);
02023
02024 if (case_follows)
02025 cwh_stk_push(cast_to_void((INTPTR)label), LB_item);
02026
02027 } else {
02028
02029 cwh_block_insert_after(last_node, default_label);
02030 }
02031 }
02032
02033
02034
02035
02036
02037
02038
02039
02040
02041
02042
02043
02044
02045
02046 static WN *
02047 cwh_stmt_str_falsebr_util(OPERATOR opr,
02048 W_node expr[2],
02049 W_node val[2],
02050 INT32 label,
02051 WN *last_node)
02052 {
02053 WN * test;
02054 WN * wn1 ;
02055
02056 cwh_stk_push_STR(W_wn(expr[0]),W_wn(expr[1]),W_ty(expr[1]),WN_item);
02057 cwh_stk_push_STR(W_wn(val[0]), W_wn(val[1]), W_ty(val[1]), WN_item);
02058
02059 cwh_expr_compare(opr,W_ty(expr[0]));
02060
02061 test = cwh_expr_operand(NULL);
02062 wn1 = WN_CreateFalsebr(label, test);
02063 cwh_block_insert_after(last_node, wn1);
02064
02065 return wn1 ;
02066 }
02067
02068
02069
02070
02071
02072
02073
02074
02075
02076
02077
02078
02079
02080
02081
02082
02083
02084
02085
02086
02087
02088
02089
02090
02091
02092
02093
02094
02095
02096
02097
02098 void
02099 fei_new_select(INT32 num_cases,
02100 #ifdef KEY
02101 INTPTR last_label_idx,
02102 #endif
02103 INTPTR default_label_idx )
02104 {
02105 WN *parent_block;
02106 WN *wn;
02107 WN *wn1;
02108 WN *expr;
02109 WN *default_label;
02110 WN *last_node;
02111 LABEL_IDX lb;
02112 ST *tmp_st;
02113 TY_IDX ty;
02114
02115 if (cwh_stk_get_class() == STR_item) {
02116
02117 cwh_stmt_select_char(num_cases, default_label_idx);
02118
02119 } else {
02120
02121 expr = cwh_expr_operand(NULL);
02122
02123 if ( num_cases > 0) {
02124
02125 ty = Be_Type_Tbl(WN_rtype(expr));
02126 tmp_st = cwh_stab_temp_ST(ty, "select_expr");
02127 cwh_addr_store_ST(tmp_st, 0, ty, WN_COPY_Tree(expr));
02128 expr = cwh_addr_load_ST(tmp_st, 0, 0);
02129 last_node = WN_last(cwh_block_current());
02130
02131
02132
02133 parent_block = cwh_block_new_and_current();
02134
02135 lb = cast_to_LB(default_label_idx);
02136 default_label = WN_CreateGoto (lb);
02137 wn = WN_CreateSwitch (num_cases, expr, cwh_block_current(), default_label, 0);
02138
02139
02140
02141
02142 wn1 = WN_CreateIntconst(OPC_I4INTCONST, num_cases);
02143 cwh_stk_push(wn1, WN_item);
02144 cwh_stk_push(cwh_block_current(), WN_item);
02145 cwh_stk_push(expr, WN_item);
02146 cwh_stk_push(last_node, WN_item);
02147
02148
02149
02150 cwh_block_set_current(parent_block);
02151 cwh_block_append(wn);
02152 #ifdef KEY
02153 LABEL_IDX last_lb = cast_to_LB(last_label_idx);
02154 WN_last_label(wn) = last_lb;
02155 #endif
02156
02157 } else {
02158
02159 WN_DELETE_Tree(expr);
02160 }
02161 }
02162 }
02163
02164
02165
02166
02167
02168
02169
02170
02171
02172
02173
02174
02175
02176
02177
02178
02179
02180
02181
02182
02183
02184
02185
02186
02187
02188
02189
02190
02191
02192
02193
02194
02195
02196
02197
02198
02199
02200
02201
02202
02203
02204
02205
02206 void
02207 fei_new_select_case(INT64 low_value_pres,
02208 INT64 high_value_pres,
02209 INT32 case_follows)
02210 {
02211 WN *o_val;
02212 #ifdef KEY
02213 WN *high_val = 0;
02214 #else
02215 WN *high_val;
02216 #endif
02217 WN *casegoto_block;
02218 WN *wn;
02219 WN *wn1;
02220 WN *expr;
02221 WN *last_node;
02222 LABEL_IDX label;
02223 TY_IDX ty;
02224 INT32 remaining_cases;
02225 LABEL_IDX new_label_num=0;
02226
02227 if (cwh_stk_get_class() == STR_item) {
02228
02229 cwh_stmt_select_case_char(low_value_pres, high_value_pres,
02230 case_follows);
02231
02232 } else {
02233
02234 if (low_value_pres && high_value_pres)
02235 high_val = cwh_expr_operand(NULL);
02236
02237 o_val = cwh_expr_operand(NULL);
02238 label = cwh_stk_pop_LB();
02239
02240 last_node = cwh_expr_operand(NULL);
02241 expr = cwh_expr_operand(NULL);
02242 casegoto_block = cwh_expr_operand(NULL);
02243 remaining_cases = WN_const_val(cwh_expr_operand(NULL));
02244
02245 if (low_value_pres || high_value_pres) {
02246
02247 ty = Be_Type_Tbl(WN_rtype(expr));
02248 (void) New_LABEL (CURRENT_SYMTAB, new_label_num);
02249
02250 if (low_value_pres && high_value_pres) {
02251
02252 wn1 = cwh_stmt_falsebr(WN_COPY_Tree(expr),
02253 WN_COPY_Tree(o_val),
02254 ty,
02255 OPR_GE,
02256 new_label_num);
02257
02258 cwh_block_insert_after(last_node, wn1);
02259 last_node = wn1;
02260
02261 wn1 = cwh_stmt_falsebr(WN_COPY_Tree(expr),
02262 WN_COPY_Tree(high_val),
02263 ty,
02264 OPR_LE,
02265 new_label_num);
02266
02267 } else {
02268
02269 OPERATOR opr = OPR_LE;
02270
02271 if (low_value_pres)
02272 opr = OPR_GE;
02273
02274 wn1 = cwh_stmt_falsebr(WN_COPY_Tree(expr),
02275 WN_COPY_Tree(o_val),
02276 ty,
02277 opr,
02278 new_label_num);
02279
02280 }
02281
02282 cwh_block_insert_after(last_node, wn1);
02283 last_node = wn1;
02284
02285 wn1 = cwh_addr_stid (WN_st(expr), 0, ty, WN_COPY_Tree(o_val));
02286 cwh_block_insert_after(last_node, wn1);
02287 last_node = wn1;
02288
02289 wn1 = WN_CreateLabel(new_label_num, 0,NULL);
02290 cwh_block_insert_after(last_node, wn1);
02291 last_node = wn1;
02292
02293 }
02294 wn = WN_CreateCasegoto(WN_const_val(o_val),label);
02295
02296 cwh_block_append_given_block(wn,casegoto_block);
02297
02298 remaining_cases = remaining_cases - 1;
02299
02300 if (remaining_cases != 0) {
02301
02302 wn1 = WN_CreateIntconst(OPC_I4INTCONST, remaining_cases);
02303 cwh_stk_push(wn1, WN_item);
02304 cwh_stk_push(casegoto_block, WN_item);
02305 cwh_stk_push(expr, WN_item);
02306 cwh_stk_push(last_node, WN_item);
02307 if (case_follows)
02308 cwh_stk_push(cast_to_void((INTPTR)label), LB_item);
02309 }
02310
02311 }
02312 }
02313
02314
02315
02316
02317
02318
02319
02320
02321
02322
02323
02324
02325
02326 void fei_label_def_named(INTPTR lbl_idx,
02327 INT64 label_flag_word,
02328 INT32 lineno,
02329 INT32 sup_cnt,
02330 INT32 keepme,
02331 INT32 storage_seg,
02332 INT32 safevl,
02333 INT32 unroll_cnt,
02334 char *mark_name,
02335 INT32 pipe_cnt,
02336 INT32 last_argument,
02337 INT32 unused1,
02338 INT32 unused2,
02339 INT32 unused3)
02340 {
02341 WN * wn ;
02342 LABEL_IDX lb ;
02343 WN * expr;
02344
02345
02346 if (!test_flag(label_flag_word, FEI_LABEL_DEF_NAMED_NOT_REFERENCED)) {
02347 lb = cast_to_LB(lbl_idx);
02348 wn = WN_CreateLabel(lb,0,NULL);
02349
02350 if (test_flag(label_flag_word, FEI_LABEL_DEF_NAMED_CASE))
02351 cwh_stk_push(cast_to_void((INTPTR)lb), LB_item);
02352
02353 cwh_block_append(wn) ;
02354 }
02355
02356 #ifdef _SGI_DIRS
02357
02358
02359
02360 if (test_flag(label_flag_word, FEI_LABEL_DEF_NAMED_MAXCPUS)) {
02361
02362 expr = cwh_expr_operand(NULL);
02363 cwh_stmt_add_xpragma(WN_PRAGMA_CRI_MAXCPUS,FALSE,expr);
02364
02365 }
02366 if (test_flag(label_flag_word, FEI_LABEL_DEF_NAMED_SUPPRESS)) {
02367 cwh_directive_barrier_insert(NULL,sup_cnt);
02368 }
02369
02370 if (test_flag(label_flag_word, FEI_LABEL_DEF_NAMED_LOOPCHK)) {
02371 if (test_flag(label_flag_word, FEI_LABEL_DEF_NAMED_PERMUTATION)) {
02372
02373
02374 cwh_stmt_add_pragma(WN_PRAGMA_KAP_ASSERT_PERMUTATION);
02375 }
02376 if (test_flag(label_flag_word, FEI_LABEL_DEF_NAMED_IVDEP)) {
02377 cwh_stmt_add_pragma(WN_PRAGMA_IVDEP);
02378 }
02379 if (test_flag(label_flag_word, FEI_LABEL_DEF_NAMED_NOREDUCE)) {
02380 cwh_stmt_add_pragma(WN_PRAGMA_NORECURRENCE);
02381 }
02382 if (test_flag(label_flag_word, FEI_LABEL_DEF_NAMED_SHORTLOOP)) {
02383 cwh_stmt_add_pragma(WN_PRAGMA_CRI_SHORTLOOP,FALSE, NULL,64);
02384 }
02385 if (test_flag(label_flag_word, FEI_LABEL_DEF_NAMED_DO_BL)) {
02386 cwh_stmt_add_pragma(WN_PRAGMA_CRI_BL,FALSE, NULL,1);
02387 }
02388 if (test_flag(label_flag_word, FEI_LABEL_DEF_NAMED_CONCCALLS)) {
02389 cwh_stmt_add_pragma(WN_PRAGMA_KAP_ASSERT_CONCURRENT_CALL);
02390 }
02391 if (test_flag(label_flag_word, FEI_LABEL_DEF_NAMED_NEXTSCALAR)) {
02392 cwh_stmt_add_pragma(WN_PRAGMA_NEXT_SCALAR);
02393 }
02394 if (test_flag(label_flag_word, FEI_LABEL_DEF_NAMED_SHORTLOOP128)) {
02395 cwh_stmt_add_pragma(WN_PRAGMA_CRI_SHORTLOOP,FALSE, NULL,128);
02396 }
02397 if (test_flag(label_flag_word, FEI_LABEL_DEF_NAMED_SELECT_TASK)) {
02398 cwh_stmt_add_pragma(WN_PRAGMA_CRI_PREFERTASK);
02399 }
02400 if (test_flag(label_flag_word, FEI_LABEL_DEF_NAMED_NOTASK)) {
02401 cwh_stmt_add_pragma(WN_PRAGMA_KAP_ASSERT_DO,FALSE, NULL,ASSERT_DO_SERIAL);
02402 }
02403 if (test_flag(label_flag_word, FEI_LABEL_DEF_NAMED_UNROLL)) {
02404
02405 if (unroll_cnt != 0) {
02406 cwh_stmt_add_pragma(WN_PRAGMA_UNROLL,FALSE, NULL,unroll_cnt,-1);
02407 }
02408 }
02409 if (test_flag(label_flag_word, FEI_LABEL_DEF_NAMED_FISSIONABLE)) {
02410 cwh_stmt_add_pragma(WN_PRAGMA_FISSIONABLE);
02411 }
02412 if (test_flag(label_flag_word, FEI_LABEL_DEF_NAMED_FUSABLE)) {
02413 cwh_stmt_add_pragma(WN_PRAGMA_FUSEABLE);
02414 }
02415 if (test_flag(label_flag_word, FEI_LABEL_DEF_NAMED_NOFISSION)) {
02416 cwh_stmt_add_pragma(WN_PRAGMA_NO_FISSION);
02417 }
02418 if (test_flag(label_flag_word, FEI_LABEL_DEF_NAMED_NOFUSION)) {
02419 cwh_stmt_add_pragma(WN_PRAGMA_NO_FUSION);
02420 }
02421 if (test_flag(label_flag_word, FEI_LABEL_DEF_NAMED_NOINTERCHANGE)) {
02422 cwh_stmt_add_pragma(WN_PRAGMA_NO_INTERCHANGE);
02423 }
02424 if (test_flag(label_flag_word, FEI_LABEL_DEF_NAMED_NOBLOCKING)) {
02425 cwh_stmt_add_pragma(WN_PRAGMA_NO_BLOCKING);
02426 }
02427 if (test_flag(label_flag_word, FEI_LABEL_DEF_NAMED_AGGRESSIVEINNERLOOPFISSION)) {
02428 cwh_stmt_add_pragma(WN_PRAGMA_AGGRESSIVE_INNER_LOOP_FISSION);
02429 }
02430 }
02431 #endif
02432 }
02433
02434
02435
02436
02437
02438
02439
02440
02441
02442
02443 extern void
02444 fei_brtrue(INTPTR lbl_idx)
02445 {
02446 WN *wn;
02447 WN *wc;
02448 LABEL_IDX lb ;
02449
02450 lb = cast_to_LB(lbl_idx);
02451 wc = cwh_expr_operand(NULL);
02452 wn = WN_CreateTruebr(lb,wc);
02453 cwh_block_append(wn) ;
02454 }
02455
02456
02457
02458
02459
02460
02461
02462
02463
02464
02465
02466
02467
02468
02469
02470
02471
02472
02473
02474
02475 extern void
02476 fei_where(INT32 defined_asg,
02477 INT32 inline_state)
02478 {
02479 WN *msk ;
02480 WN *wn ;
02481 WN *wl ;
02482 TYPE dummy_type;
02483 #ifdef KEY
02484 memset(&dummy_type, 0, sizeof(dummy_type));
02485 #endif
02486 INT64 flags = 0;
02487
02488 msk = cwh_expr_operand(NULL);
02489 msk = F90_Wrap_ARREXP(msk);
02490
02491 wl = cwh_block_new_and_current();
02492
02493 wn = WN_Create(OPC_WHERE,3);
02494 WN_kid0(wn) = msk ;
02495 WN_kid1(wn) = cwh_block_current();
02496
02497 if (defined_asg) {
02498 dummy_type = fei_descriptor(0,
02499 Basic,
02500 0,
02501 V_oid,
02502 0,
02503 0);
02504 fei_call(2, dummy_type, By_Value_Call, FALSE, inline_state, flags);
02505 }
02506 else {
02507 fei_store(dummy_type);
02508 }
02509
02510 (void) cwh_block_new_and_current();
02511
02512 WN_kid2(wn) = cwh_block_current();
02513
02514 cwh_block_set_current(wl);
02515 cwh_block_append(wn);
02516
02517 }
02518
02519
02520
02521
02522
02523
02524
02525
02526
02527
02528
02529
02530 extern void
02531 fei_stop( void )
02532 {
02533 WN *wa;
02534 WN *wc;
02535 WN *wn;
02536 #ifdef KEY
02537 WN *stop_code = 0;
02538 WN *stop_code_len = 0;
02539 #else
02540 WN *stop_code;
02541 WN *stop_code_len;
02542 #endif
02543
02544 if (cwh_stk_get_class() == STR_item) {
02545 cwh_stk_pop_STR();
02546 wa = cwh_stk_pop_WN();
02547 wc = WN_COPY_Tree(wa);
02548 stop_code_len = cwh_intrin_wrap_value_parm(wa);
02549 wa = cwh_stk_pop_ADDR();
02550 stop_code = cwh_intrin_wrap_char_parm(wa,wc);
02551 }
02552 else {
02553 DevAssert((0),("expected character stop code"));
02554 }
02555
02556 wn = WN_Create ( OPC_VINTRINSIC_CALL, 2);
02557 WN_Set_Call_Default_Flags(wn);
02558
02559 if (FE_Call_Never_Return)
02560 WN_Set_Call_Never_Return (wn);
02561
02562 WN_kid0(wn) = stop_code;
02563 WN_kid1(wn) = stop_code_len;
02564
02565 WN_intrinsic(wn) = INTRN_STOP_F90;
02566
02567 cwh_block_append(wn);
02568 }
02569
02570
02571
02572
02573
02574
02575
02576
02577
02578
02579
02580
02581
02582
02583
02584
02585
02586
02587
02588
02589
02590
02591
02592
02593
02594
02595
02596
02597
02598
02599
02600
02601
02602
02603
02604 extern void
02605 fei_return(INT return_kind, TYPE dummy)
02606 {
02607 WN * wn;
02608 WN * ret_wn = NULL;
02609 ST * st;
02610 ST * rt;
02611 TY_IDX ty;
02612
02613 TYPE_ID bt;
02614
02615 BOOL done_int;
02616 BOOL done_float;
02617
02618 DevAssert(((return_kind >= 1) && (return_kind <= 3)),
02619 (" odd return kind "));
02620
02621 if (( return_kind == 1 ) ||
02622 ( return_kind == 3 )) {
02623
02624 switch (cwh_stk_get_class()) {
02625 case ST_item:
02626 case ST_item_whole_array:
02627 st = cwh_stk_pop_ST();
02628 ty = ST_type(st);
02629
02630 if ( WHIRL_Return_Val_On ) {
02631
02632 if((ST_sclass(st) == SCLASS_FORMAL) &&
02633 (TY_kind(ty) == KIND_POINTER))
02634 ty = TY_pointed(ty);
02635
02636 if ((TY_kind(ty) == KIND_SCALAR ||
02637 TY_kind(ty) == KIND_STRUCT) &&
02638 (! ST_auxst_is_rslt_tmp(st)) &&
02639 (! cwh_types_is_character(ty))) {
02640
02641 ret_wn = cwh_stmt_return_scalar(st,NULL,ST_type(st),TRUE);
02642 }
02643 else {
02644
02645 ret_wn = WN_CreateReturn();
02646 }
02647 }
02648 else {
02649
02650 if (!IS_ALTENTRY_TEMP(st)) {
02651
02652 if((ST_sclass(st) == SCLASS_FORMAL) &&
02653 (TY_kind(ty) == KIND_POINTER))
02654 ty = TY_pointed(ty);
02655
02656 if ((TY_kind(ty) == KIND_SCALAR) &&
02657 (! ST_auxst_is_rslt_tmp(st)) &&
02658 (! cwh_types_is_character(ty))) {
02659
02660 ret_wn = cwh_stmt_return_scalar(st,NULL,ST_type(st),TRUE);
02661
02662 } else if (STRUCT_BY_VALUE(ty)) {
02663 (void) cwh_stmt_return_scalar(st,NULL,ST_type(st),TRUE);
02664
02665 } else {
02666
02667 ret_wn = WN_CreateReturn();
02668 }
02669
02670 } else {
02671
02672 done_int = FALSE;
02673 done_float = FALSE;
02674
02675
02676 ITEM *re = NULL;
02677 while ((re = cwh_auxst_next_element(ST_base(st),re,l_RETURN_TEMPS)) != NULL ) {
02678 rt = I_element(re);
02679 bt = TY_mtype(ST_type(rt));
02680
02681 if (MTYPE_is_float(bt)) {
02682 if (! done_float) {
02683 done_float = TRUE;
02684 cwh_stmt_return_altentry(rt);
02685 }
02686 } else if (! done_int) {
02687 done_int = TRUE;
02688 cwh_stmt_return_altentry(rt);
02689 }
02690 }
02691 }
02692 }
02693 break;
02694
02695
02696 case WN_item:
02697 case WN_item_whole_array:
02698 case DEREF_item:
02699 wn = cwh_expr_operand(NULL);
02700 ty = Be_Type_Tbl(WNRTY(wn));
02701 ret_wn = cwh_stmt_return_scalar(NULL,wn,ty,TRUE);
02702 break;
02703
02704
02705 case FLD_item:
02706 ty = cwh_stk_get_FLD_TY();
02707 wn = cwh_expr_operand(NULL);
02708 ret_wn = cwh_stmt_return_scalar(NULL,wn,ty,TRUE);
02709 break;
02710
02711 default:
02712 DevAssert((0),("Odd return"));
02713
02714 }
02715
02716 if ( WHIRL_Return_Val_On ) {
02717 if (ret_wn != NULL) {
02718 cwh_block_append(ret_wn);
02719 }
02720 }
02721 else {
02722 wn = WN_CreateReturn();
02723 cwh_block_append(wn) ;
02724 }
02725 }
02726 else {
02727
02728 wn = WN_CreateReturn();
02729 cwh_block_append(wn) ;
02730 }
02731 }
02732
02733
02734
02735
02736
02737
02738
02739
02740
02741
02742
02743
02744
02745
02746
02747
02748
02749
02750
02751
02752
02753
02754
02755
02756
02757
02758 extern WN *
02759 cwh_stmt_return_scalar(ST *st, WN * rv, TY_IDX rty, BOOL callee_return)
02760 {
02761 TYPE_ID rbtype1;
02762 TYPE_ID rbtype2;
02763 PREG_NUM rreg1;
02764 PREG_NUM rreg2;
02765
02766
02767 #ifdef KEY
02768 WN * wn = 0;
02769 #else
02770 WN * wn ;
02771 #endif
02772 WN * wn2 ;
02773 ST * pr1 ;
02774 ST * pr2 ;
02775 OFFSET_64 off;
02776
02777 if (WHIRL_Return_Info_On) {
02778
02779 RETURN_INFO return_info = Get_Return_Info (rty, Use_Simulated);
02780
02781 if (RETURN_INFO_count(return_info) <= 2 ||
02782 WHIRL_Return_Val_On) {
02783
02784 rbtype1 = RETURN_INFO_mtype (return_info, 0);
02785 rbtype2 = RETURN_INFO_mtype (return_info, 1);
02786 rreg1 = RETURN_INFO_preg (return_info, 0);
02787 rreg2 = RETURN_INFO_preg (return_info, 1);
02788 }
02789
02790 else
02791 Fail_FmtAssertion ("cwh_stmt_return_scalar: more than 2 return registers");
02792 }
02793
02794 else {
02795 Get_Return_Mtypes(rty, Use_Simulated, &rbtype1, &rbtype2);
02796 Get_Return_Pregs(rbtype1, rbtype2, &rreg1, &rreg2);
02797 }
02798
02799 pr1 = MTYPE_To_PREG(rbtype1);
02800 pr2 = MTYPE_To_PREG(rbtype2);
02801
02802 if (callee_return) {
02803
02804 if ( WHIRL_Return_Val_On ) {
02805 if (st == NULL) {
02806 wn = WN_CreateReturn_Val (OPR_RETURN_VAL, TY_mtype (rty), MTYPE_V, rv);
02807 Set_PU_has_very_high_whirl (Get_Current_PU ());
02808 }
02809 else {
02810
02811 # if (defined(linux) || defined(BUILD_OS_DARWIN))
02812 wn2 = cwh_addr_load_ST(st,0,0);
02813 wn = WN_CreateReturn_Val (OPR_RETURN_VAL, TY_mtype (rty), MTYPE_V, wn2);
02814 # else
02815 if (IS_ALTENTRY_TEMP(st)) {
02816 wn2 = cwh_addr_ldid(ST_base(st),0,ST_type(ST_base(st)));
02817 wn = WN_CreateReturn_Val (OPR_RETURN_VAL, TY_mtype (ST_type(ST_base(st))), MTYPE_V, wn2);
02818 } else {
02819 wn2 = cwh_addr_load_ST(st,0,NULL);
02820 wn = WN_CreateReturn_Val (OPR_RETURN_VAL, TY_mtype (rty), MTYPE_V, wn2);
02821 }
02822 # endif
02823
02824 Set_PU_has_very_high_whirl (Get_Current_PU ());
02825 }
02826 }
02827 else {
02828 if (st == NULL)
02829 cwh_addr_store_ST(pr1,rreg1,rty,rv);
02830
02831 else {
02832
02833 if (TY_kind(ST_type(st)) == KIND_STRUCT) {
02834
02835 wn = cwh_addr_mk_ldid(st,0,rbtype1,rty);
02836 cwh_addr_store_ST(pr1,rreg1,Be_Type_Tbl(rbtype1),wn);
02837
02838 if (rreg2 !=0) {
02839
02840 off = PREG2_OFFSET(pr1,pr2);
02841 wn = cwh_addr_mk_ldid(st,off,rbtype2,rty);
02842 cwh_addr_store_ST(pr2,rreg2,Be_Type_Tbl(rbtype2),wn);
02843 }
02844
02845 } else if (IS_ALTENTRY_TEMP(st)) {
02846
02847 wn = cwh_addr_ldid(ST_base(st),0,rty);
02848 cwh_addr_store_ST(pr1,rreg1,rty,wn);
02849
02850 } else {
02851
02852 wn = cwh_addr_load_ST(st,0,0);
02853 cwh_addr_store_ST(pr1,rreg1,rty,wn);
02854 }
02855 }
02856 }
02857 } else {
02858
02859 if ( WHIRL_Return_Val_On ) {
02860 wn = cwh_addr_mk_ldid(Return_Val_Preg,-1, TY_mtype (rty), rty);
02861
02862
02863 if (STRUCT_BY_VALUE(rty)) {
02864
02865
02866
02867 cwh_addr_store_ST(st,0,rty,wn);
02868 wn = NULL;
02869 }
02870 }
02871 else {
02872
02873
02874
02875 wn = cwh_addr_load_ST(pr1,rreg1,Be_Type_Tbl(rbtype1));
02876
02877 }
02878 }
02879
02880 return wn;
02881 }
02882
02883
02884
02885
02886
02887
02888
02889
02890
02891
02892 static void
02893 cwh_stmt_return_altentry(ST *st)
02894 {
02895 TYPE_ID rbtype1;
02896 TYPE_ID rbtype2;
02897 TYPE_ID bt;
02898
02899 PREG_NUM rreg1;
02900 PREG_NUM rreg2;
02901
02902 WN * wn;
02903 WN * wn2;
02904 ST * pr;
02905 TY_IDX rty;
02906 ST ** p;
02907 BOOL same;
02908
02909
02910 same = ST_auxst_altentry_shareTY(ST_base(st));
02911 rty = cwh_stab_altentry_TY(st,same);
02912
02913 if (TY_mtype(rty) == MTYPE_CQ) {
02914
02915 p = cwh_auxst_arglist(Procedure_ST) ;
02916 wn = cwh_addr_load_ST(st,0,0);
02917
02918 if ( WHIRL_Return_Val_On ) {
02919 wn2 = WN_CreateReturn_Val (OPR_RETURN_VAL, TY_mtype (rty), MTYPE_V, wn);
02920 cwh_block_append(wn2);
02921 Set_PU_has_very_high_whirl (Get_Current_PU ());
02922 }
02923 else {
02924 cwh_addr_store_ST(p[0],0,0,wn);
02925 }
02926
02927 } else {
02928
02929 if ( WHIRL_Return_Val_On ) {
02930
02931 wn = cwh_addr_ldid(ST_base(st),0,rty);
02932
02933 wn2 = WN_CreateReturn_Val (OPR_RETURN_VAL, TY_mtype (rty), MTYPE_V, wn);
02934 cwh_block_append(wn2);
02935 Set_PU_has_very_high_whirl (Get_Current_PU ());
02936 }
02937 else {
02938 if (WHIRL_Return_Info_On) {
02939
02940 RETURN_INFO return_info = Get_Return_Info (rty, Use_Simulated);
02941
02942 if (RETURN_INFO_count(return_info) <= 2) {
02943
02944 rbtype1 = RETURN_INFO_mtype (return_info, 0);
02945 rbtype2 = RETURN_INFO_mtype (return_info, 1);
02946 rreg1 = RETURN_INFO_preg (return_info, 0);
02947 rreg2 = RETURN_INFO_preg (return_info, 1);
02948 }
02949
02950 else
02951 Fail_FmtAssertion ("cwh_stmt_alt_entry: more than 2 return registers");
02952 }
02953
02954 else {
02955 Get_Return_Mtypes(rty, Use_Simulated, &rbtype1, &rbtype2);
02956 Get_Return_Pregs(rbtype1, rbtype2, &rreg1, &rreg2);
02957 }
02958
02959 pr = MTYPE_To_PREG(rbtype1);
02960
02961 wn = cwh_addr_ldid(ST_base(st),0,rty);
02962 bt = TY_mtype(rty);
02963
02964 if (MTYPE_is_float(bt) && !same) {
02965
02966 if (bt == MTYPE_C4) {
02967 wn = WN_CreateStid (OPC_C4STID, 32, Float32_Preg,rty,wn);
02968 cwh_block_append(wn);
02969 } else if (TY_size(rty) <= TY_size(Be_Type_Tbl(MTYPE_F8)))
02970 cwh_addr_store_ST(pr,rreg1,rty,wn);
02971 else {
02972 wn = WN_CreateStid (OPC_FQSTID, 32, Float64_Preg, rty, wn );
02973 cwh_block_append(wn);
02974 }
02975
02976 } else
02977 cwh_addr_store_ST(pr,rreg1,rty,wn);
02978 }
02979 }
02980 }
02981
02982
02983
02984
02985
02986
02987
02988
02989
02990
02991
02992
02993
02994
02995
02996
02997
02998 extern void
02999 fei_concat(INT32 numops)
03000 {
03001 INT32 i,nm,k,sc;
03002 WN ** sz ;
03003 WN ** wn ;
03004 WN * rsz;
03005 WN * wt ;
03006 WN * ae ;
03007 TY_IDX ty ;
03008 BOOL *va ;
03009 WN *wr;
03010
03011 ae = NULL ;
03012 sc = numops + 1 ;
03013 nm = 2 * sc ;
03014 sz = (WN **) malloc(nm * sizeof(WN *)) ;
03015 wn = (WN **) malloc(nm * sizeof(WN *)) ;
03016 va = (BOOL *) malloc(nm * sizeof(BOOL)) ;
03017 rsz = WN_Zerocon(cwh_bound_int_typeid);
03018
03019 for (i = sc ; i >= 2 ; i--) {
03020 k = i + numops ;
03021 cwh_stk_pop_STR();
03022 wn[k] = cwh_stk_pop_WN();
03023 wn[i] = F90_Wrap_ARREXP(cwh_expr_address(f_T_PASSED));
03024 if (WNOPR(wn[i]) == OPR_ARRAYEXP)
03025 ae = wn[i] ;
03026 sz[k] = NULL;
03027 sz[i] = WN_COPY_Tree(wn[k]) ;
03028 va[k] = TRUE;
03029 va[i] = FALSE;
03030 rsz = cwh_expr_bincalc(OPR_ADD,rsz,WN_COPY_Tree(wn[k]));
03031 }
03032
03033
03034
03035
03036 ty = cwh_types_mk_character_TY(WN_COPY_Tree(rsz),NULL,TRUE);
03037
03038 if (ae != NULL) {
03039 ty = cwh_types_array_temp_TY(ae,ty) ;
03040 wt = cwh_expr_temp(ty,WN_COPY_Tree(rsz),f_T_PASSED);
03041 wt = cwh_addr_temp_section(wt,ty);
03042 wr = WN_COPY_Tree(wt);
03043 wt = F90_Wrap_ARREXP(wt);
03044 } else {
03045 wt = cwh_expr_temp(ty,WN_COPY_Tree(rsz),f_T_PASSED);
03046 wr = WN_COPY_Tree(wt) ;
03047 }
03048
03049 wn[0] = wt;
03050 wn[1] = WN_COPY_Tree(rsz) ;
03051 sz[0] = WN_COPY_Tree(rsz) ;
03052 sz[1] = NULL ;
03053 va[0] = FALSE;
03054 va[1] = TRUE ;
03055
03056 cwh_intrin_call(INTRN_CONCATEXPR,nm,wn,sz,va,MTYPE_V);
03057
03058 cwh_stk_push_STR(rsz,wr,ty,WN_item);
03059
03060 free(sz);
03061 free(wn);
03062 free(va);
03063 }
03064
03065
03066
03067
03068
03069
03070
03071
03072
03073
03074
03075
03076
03077
03078
03079 extern void
03080 cwh_stmt_character_icall(INTRINSIC intrinsic)
03081 {
03082 WN * ar[4];
03083 WN * sz[4];
03084 BOOL va[4];
03085
03086 cwh_stk_pop_STR();
03087 ar[3] = cwh_expr_operand(NULL);
03088 ar[1] = cwh_expr_address(f_NONE);
03089 ar[1] = F90_Wrap_ARREXP(ar[1]);
03090
03091 sz[3] = NULL;
03092 sz[1] = WN_COPY_Tree(ar[3]);
03093 va[3] = TRUE;
03094 va[1] = FALSE;
03095
03096 cwh_stk_pop_STR();
03097 ar[2] = cwh_expr_operand(NULL);
03098 ar[0] = cwh_expr_address(f_NONE);
03099 ar[0] = F90_Wrap_ARREXP(ar[0]);
03100
03101 sz[2] = NULL;
03102 sz[0] = WN_COPY_Tree(ar[2]);
03103 va[2] = TRUE;
03104 va[0] = FALSE;
03105
03106 #ifdef KEY
03107 WN *wn = cwh_intrin_call(intrinsic,4,ar,sz,va,MTYPE_V);
03108 WN_Set_Linenum(wn, USRCPOS_srcpos(current_srcpos));
03109 #else
03110 cwh_intrin_call(intrinsic,4,ar,sz,va,MTYPE_V);
03111 #endif
03112 }
03113
03114
03115
03116
03117
03118
03119
03120
03121
03122
03123
03124
03125
03126 extern BOOL
03127 cwh_stmt_add_to_preamble(WN *wn,enum site block)
03128 {
03129 BOOL res = FALSE;
03130
03131 if (block == block_ca)
03132 if (WN_pragma_ca != NULL) {
03133 WN_INSERT_BlockFirst (WN_pragma_ca,wn);
03134 res = TRUE;
03135 }
03136
03137 if (block == block_pu)
03138 if (WN_pragma_pu != NULL) {
03139 WN_INSERT_BlockFirst (WN_pragma_pu,wn);
03140 res = TRUE;
03141 }
03142
03143 return res;
03144 }
03145
03146
03147
03148
03149
03150
03151
03152
03153
03154
03155 extern void
03156 cwh_stmt_add_pragma(WN_PRAGMA_ID wn_pragma_id,
03157 BOOL is_omp,
03158 ST *st,
03159 INT32 arg1,
03160 INT32 arg2)
03161 {
03162 WN *wn;
03163 wn = WN_CreatePragma(wn_pragma_id, st, arg1, arg2);
03164 if (is_omp)
03165 WN_set_pragma_omp(wn);
03166 cwh_block_append(wn);
03167 }
03168
03169 #ifdef KEY
03170
03171
03172
03173
03174
03175
03176
03177
03178
03179 extern void
03180 cwh_stmt_add_options_pragma(ST *st)
03181 {
03182
03183
03184 WN *wn = WN_CreatePragma(WN_PRAGMA_OPTIONS, st, 0, 0);
03185 cwh_stmt_add_to_preamble(wn,block_pu);
03186 }
03187 #endif
03188
03189
03190
03191
03192
03193
03194
03195
03196
03197
03198
03199 extern void
03200 cwh_stmt_add_xpragma(WN_PRAGMA_ID wn_pragma_id,
03201 BOOL is_omp,
03202 WN * expr)
03203 {
03204 WN *wn;
03205 wn = WN_CreateXpragma(wn_pragma_id, (ST_IDX) NULL, 1);
03206 WN_kid0(wn) = expr;
03207 if (is_omp)
03208 WN_set_pragma_omp(wn);
03209 cwh_block_append(wn);
03210 }
03211
03212
03213
03214
03215
03216
03217
03218
03219
03220 void
03221 fei_enddo(void)
03222 {
03223 WN *wn;
03224
03225 if (FE_Endloop_Marker) {
03226 wn = WN_CreateComment("ENDLOOP");
03227 cwh_block_append(wn);
03228 cwh_auxst_clear(WN_st(wn));
03229 }
03230
03231 cwh_block_pop_block();
03232 }
03233
03234
03235
03236
03237
03238
03239
03240
03241
03242
03243
03244 void
03245 fei_dowhile(void)
03246 {
03247 WN *expr,*block,*w;
03248
03249 expr = cwh_expr_operand(NULL);
03250 block = WN_CreateBlock();
03251 WN_Set_Linenum (block, USRCPOS_srcpos(current_srcpos));
03252 w = WN_CreateWhileDo(expr,block);
03253 cwh_block_append(w);
03254
03255
03256
03257 cwh_block_push_block(NULL,NULL,FALSE);
03258 cwh_block_set_current(block);
03259 }
03260
03261
03262
03263
03264
03265
03266
03267
03268
03269
03270
03271
03272
03273
03274
03275
03276
03277
03278
03279
03280
03281
03282 void
03283 fei_doloop(INT32 line)
03284 {
03285 WN *lb;
03286 WN *ub,*ubcomp;
03287 WN *stride,*stride_in_loop;
03288 #ifdef KEY
03289 ST *lcv = 0;
03290 #else
03291 ST *lcv;
03292 #endif
03293 WN *index_id;
03294 WN *stmts;
03295 WN *start;
03296 WN *end;
03297 WN *step;
03298 WN *wlcv = NULL;
03299 #ifdef KEY
03300 TY_IDX ty = 0;
03301 #else
03302 TY_IDX ty;
03303 #endif
03304
03305 USRCPOS pos;
03306 INT32 local_line_num;
03307 mUINT16 local_file_num;
03308
03309 TYPE_ID doloop_ty,lcv_t;
03310 BOOL canonicalize;
03311 PREG_NUM loop_preg;
03312 WN *temp, *count;
03313 WN *deferred_update=NULL;
03314 WN *calcu=NULL;
03315
03316 WN *doloop;
03317 WN *body;
03318
03319
03320
03321
03322
03323
03324
03325
03326
03327
03328 BOOL is_top_pdo=FALSE;
03329 BOOL is_innermost=FALSE;
03330
03331
03332 if ((nested_do_descriptor.type == WN_PRAGMA_PDO_BEGIN ||
03333 nested_do_descriptor.type == WN_PRAGMA_PARALLEL_DO) &&
03334 nested_do_descriptor.explicit_end &&
03335 nested_do_descriptor.current==0 &&
03336 nested_do_descriptor.depth!=0) {
03337 is_top_pdo=TRUE;
03338 }
03339
03340
03341 if (nested_do_descriptor.depth!=0) {
03342
03343
03344
03345 if (nested_do_descriptor.current>0) {
03346
03347 body=cwh_mp_region(nested_do_descriptor.type,0,0,0,0,0,0);
03348 cwh_block_set_current(body);
03349 }
03350
03351 nested_do_descriptor.current++;
03352
03353 if (nested_do_descriptor.current >= nested_do_descriptor.depth) {
03354
03355 nested_do_descriptor.depth = 0;
03356 nested_do_descriptor.current = 0;
03357 is_innermost=TRUE;
03358 }
03359 }
03360
03361
03362 canonicalize = FALSE;
03363
03364 stride = cwh_expr_operand(NULL);
03365 ub = cwh_expr_operand(NULL);
03366 lb = cwh_expr_operand(NULL);
03367
03368
03369
03370 if (cwh_stk_get_class() == ST_item || cwh_stk_get_class() == ST_item_whole_array) {
03371
03372 lcv = cwh_stk_pop_ST();
03373 if (ST_sclass(lcv) == SCLASS_FORMAL) {
03374 lcv_t = TY_mtype(TY_pointed(ST_type(lcv)));
03375 canonicalize = TRUE;
03376 } else {
03377 lcv_t = TY_mtype(ST_type(lcv));
03378 }
03379
03380 } else {
03381 wlcv = cwh_stk_pop_WHIRL();
03382 ty = cwh_types_WN_TY(wlcv,FALSE);
03383 lcv_t = TY_mtype(cwh_types_scalar_TY(ty));
03384 canonicalize = TRUE;
03385 }
03386
03387
03388
03389
03390 lb = cwh_convert_to_ty(lb,lcv_t);
03391 ub = cwh_convert_to_ty(ub,lcv_t);
03392 stride = cwh_convert_to_ty(stride,lcv_t);
03393
03394 if (lcv_t != MTYPE_I4 && lcv_t != MTYPE_I8) {
03395 canonicalize = TRUE;
03396 doloop_ty = cwh_doloop_typeid;
03397 } else {
03398 doloop_ty = lcv_t;
03399 }
03400
03401 if (WNOPR(stride) != OPR_INTCONST) {
03402 canonicalize = TRUE;
03403 }
03404 if (WNOPR(stride) != OPR_INTCONST && WNOPR(stride) != OPR_CONST) {
03405 stride_in_loop = cwh_preg_temp_save("doloop_stride",stride);
03406 } else {
03407 stride_in_loop = WN_COPY_Tree(stride);
03408 }
03409
03410 if (WNOPR(ub) != OPR_INTCONST && WNOPR(ub) != OPR_CONST) {
03411 ubcomp = cwh_preg_temp_save("doloop_ub",ub);
03412 } else {
03413 ubcomp = WN_COPY_Tree(ub);
03414 }
03415
03416
03417
03418
03419 if (parallel_do_count) {
03420
03421 if (! ((WNOPR(lb) == OPR_INTCONST) ||
03422 (WNOPR(lb) == OPR_LDID && ST_class(WN_st(lb)) == CLASS_PREG))) {
03423 lb = cwh_preg_temp_save("doloop_lb",lb);
03424 }
03425 }
03426
03427 if (canonicalize) {
03428
03429
03430
03431 WN *wc ;
03432
03433 if (wlcv == NULL) {
03434 cwh_addr_store_ST(lcv,0,0,WN_COPY_Tree(lb));
03435 wc = cwh_addr_load_ST(lcv,0,0) ;
03436
03437 } else {
03438 cwh_addr_store_WN(wlcv,0,0,WN_COPY_Tree(lb));
03439 wc = cwh_addr_load_WN(wlcv,0,0) ;
03440 }
03441
03442
03443 #ifdef KEY // Bug 4660, 8272
03444 temp = cwh_addr_extent(WN_COPY_Tree(lb),ub,stride_in_loop);
03445 #else
03446 temp = cwh_addr_extent(wc,ub,stride);
03447 #endif
03448 count = cwh_convert_to_ty(temp,doloop_ty);
03449
03450 if (WNOPR(count) != OPR_INTCONST) {
03451 count = cwh_preg_temp_save("doloop_count",count);
03452 }
03453 loop_preg = Create_Preg(doloop_ty,Index_To_Str(Save_Str("doloop_var")));
03454 index_id = WN_CreateIdname(loop_preg,MTYPE_To_PREG(doloop_ty));
03455
03456 start = WN_StidPreg(doloop_ty,loop_preg,WN_Intconst(doloop_ty,0));
03457 end = WN_CreateExp2(OPCODE_make_op(OPR_LT,MTYPE_I4,doloop_ty),
03458 WN_LdidPreg(doloop_ty,loop_preg),
03459 count);
03460 step = cwh_expr_bincalc(OPR_ADD,WN_LdidPreg(doloop_ty,loop_preg),
03461 WN_Intconst(doloop_ty,1));
03462 step = WN_StidPreg(doloop_ty,loop_preg,step);
03463
03464 if (parallel_do_count) {
03465 calcu = cwh_expr_bincalc(OPR_ADD,WN_COPY_Tree(lb),
03466 cwh_expr_bincalc(OPR_MPY, WN_LdidPreg(doloop_ty,loop_preg), stride_in_loop));
03467 if (wlcv)
03468 calcu = cwh_addr_istore(wlcv,0,ty,calcu);
03469 else
03470 calcu = cwh_addr_stid(lcv,0,Be_Type_Tbl(lcv_t),calcu);
03471
03472 } else {
03473
03474 deferred_update = cwh_expr_bincalc(OPR_ADD,WN_COPY_Tree(wc),stride_in_loop);
03475 if (wlcv)
03476 deferred_update = cwh_addr_istore(wlcv,0,ty,deferred_update);
03477 else
03478 deferred_update = cwh_addr_stid(lcv,0,Be_Type_Tbl(lcv_t),deferred_update);
03479 }
03480
03481 WN_DELETE_Tree(ubcomp);
03482
03483 } else {
03484
03485 OPERATOR op;
03486
03487 index_id = WN_CreateIdname(0,lcv);
03488 start = WN_Stid(lcv_t, 0, lcv, Be_Type_Tbl(lcv_t), lb);
03489
03490
03491
03492 if (WN_const_val(stride) > 0)
03493 op = OPR_LE;
03494 else
03495 op = OPR_GE;
03496
03497 end = WN_CreateExp2(OPCODE_make_op(op,MTYPE_I4,Mtype_comparison(lcv_t)),
03498 WN_Ldid(lcv_t,0,lcv,ST_type(lcv)),
03499 ubcomp);
03500 step = cwh_expr_bincalc(OPR_ADD,WN_Ldid(lcv_t,0,lcv,ST_type(lcv)),
03501 stride_in_loop);
03502 step = WN_Stid(lcv_t, 0, lcv, ST_type(lcv), step);
03503 deferred_update = NULL;
03504 }
03505
03506 stmts = WN_CreateBlock();
03507 WN_Set_Linenum (start, USRCPOS_srcpos(current_srcpos) );
03508
03509
03510 if (line > 0) {
03511 USRCPOS_clear(pos);
03512 USRCPOS_filenum(pos) = USRCPOS_filenum(current_srcpos);
03513 USRCPOS_linenum(pos) = global_to_local_line_number(line);
03514 WN_Set_Linenum (step, USRCPOS_srcpos(pos));
03515 }
03516 else {
03517 WN_Set_Linenum (step, USRCPOS_srcpos(current_srcpos));
03518 }
03519
03520 WN_Set_Linenum (stmts, USRCPOS_srcpos(current_srcpos) );
03521
03522 doloop = WN_CreateDO(index_id, start, end, step, stmts, NULL);
03523
03524 cwh_directive_insert_do_loop_directives();
03525 cwh_block_append(doloop);
03526
03527
03528
03529 cwh_block_push_block(deferred_update,calcu,is_top_pdo);
03530 cwh_block_set_current(stmts);
03531
03532
03533
03534 if (is_innermost)
03535 cwh_block_append_given(Top_of_Loop_Block);
03536
03537
03538
03539 if (calcu) {
03540 cwh_block_append(WN_COPY_Tree(calcu));
03541 }
03542 return;
03543 }
03544
03545
03546
03547
03548
03549
03550
03551
03552
03553
03554 void
03555 fei_doforever(void)
03556 {
03557
03558 cwh_block_push_block(NULL,NULL,FALSE);
03559 }
03560
03561
03562
03563
03564
03565
03566
03567
03568 void
03569 fei_if(void)
03570 {
03571 WN *test;
03572 WN *if_then;
03573 WN *if_else;
03574 WN *if_cnstrct;
03575
03576 test = cwh_expr_operand(NULL);
03577
03578 if_then = WN_CreateBlock();
03579 if_else = WN_CreateBlock();
03580 WN_Set_Linenum (if_else, USRCPOS_srcpos(current_srcpos) );
03581 WN_Set_Linenum (if_then, USRCPOS_srcpos(current_srcpos) );
03582
03583 if_cnstrct = WN_CreateIf(test, if_then, if_else);
03584
03585 cwh_block_append(if_cnstrct);
03586
03587
03588 cwh_block_push_block(NULL,NULL,FALSE);
03589
03590 cwh_block_set_current(if_then);
03591
03592
03593 cwh_stk_push(if_cnstrct, WN_item);
03594
03595 return;
03596 }
03597
03598
03599
03600
03601
03602
03603
03604
03605 void
03606 fei_else(void)
03607 {
03608 WN *if_else;
03609 WN *if_cnstrct;
03610
03611
03612 if_cnstrct = cwh_stk_pop_WN();
03613
03614
03615 if_else = WN_kid2(if_cnstrct);
03616
03617 cwh_block_set_current(if_else);
03618
03619
03620 cwh_stk_push(if_cnstrct, WN_item);
03621
03622 return;
03623 }
03624
03625
03626
03627
03628
03629
03630
03631
03632
03633 void
03634 fei_endif(void)
03635 {
03636 WN *if_cnstrct;
03637
03638 if_cnstrct = cwh_stk_pop_WN();
03639
03640 cwh_block_pop_block();
03641 return;
03642 }
03643
03644 static ST *allocate_routine_st = NULL;
03645
03646
03647
03648
03649
03650
03651
03652
03653
03654
03655
03656
03657
03658 static void
03659 cwh_inline_allocate(WN **dopes, TY_IDX *types, INT num_dopes, WN *stat)
03660 {
03661 INT idope,i;
03662 INT rank;
03663 WN *dope_addr;
03664 TY_IDX ty;
03665 TY_IDX el_ty;
03666 FLD_HANDLE fl;
03667 INT64 esize;
03668 INT64 flag_val;
03669 WN *size;
03670 WN *size2;
03671 WN *assoc;
03672 WN *flags;
03673 BOOL is_f90_pointer;
03674 WN *args[5];
03675 WN *iop;
03676 PREG_NUM size_preg;
03677 PREG_NUM addr_preg;
03678 TY_IDX addr_ty;
03679
03680
03681 if (WNOPR(stat) != OPR_INTCONST) {
03682 cwh_addr_store_WN(WN_COPY_Tree(stat),0,0,WN_Zerocon(MTYPE_I4));
03683 }
03684
03685 if (!allocate_routine_st) {
03686 allocate_routine_st = cwh_intrin_make_intrinsic_symbol("_F90_ALLOCATE_B",Pointer_Mtype);
03687 }
03688
03689
03690 for (idope=0; idope < num_dopes; idope++) {
03691 dope_addr = dopes[idope];
03692
03693 size_preg = Create_Preg(cwh_bound_int_typeid,Index_To_Str(Save_Str("size_preg")));
03694
03695
03696 ty = types[idope];
03697 if (TY_kind(ty) == KIND_POINTER) ty = TY_pointed(ty);
03698
03699
03700 TY & tt = Ty_Table[ty];
03701 is_f90_pointer = TY_is_f90_pointer(tt);
03702
03703
03704 rank = cwh_types_dope_rank(ty);
03705
03706 fl = TY_fld(tt);
03707 addr_ty = FLD_type(fl);
03708 ty = TY_pointed(addr_ty);
03709
03710 addr_preg = Create_Preg(Pointer_Mtype,Index_To_Str(Save_Str("alloc_addr")));
03711
03712 if (rank > 0) {
03713 el_ty = TY_AR_etype(ty);
03714 } else {
03715 el_ty = ty;
03716 }
03717
03718 esize = TY_size(el_ty);
03719 if (esize != 0) {
03720 size = WN_Intconst(cwh_bound_int_typeid,esize);
03721 } else {
03722
03723
03724 cwh_stk_push(WN_COPY_Tree(dope_addr),WN_item);
03725 #ifdef KEY
03726 fei_get_dv_hdr_fld(DV_EL_LEN_IDX);
03727 #else
03728 fei_get_dv_hdr_fld(2);
03729 #endif
03730 size = cwh_expr_operand(NULL);
03731 }
03732
03733 size2 = WN_Int_Type_Conversion(size,MTYPE_I8);
03734
03735 for (i = 0; i < rank; i++) {
03736 cwh_stk_push(WN_COPY_Tree(dope_addr),WN_item);
03737 fei_get_dv_extent(i+1,0);
03738 size2 = cwh_expr_bincalc(OPR_MPY,cwh_expr_operand(NULL),size2);
03739 }
03740 size2 = WN_StidPreg(cwh_bound_int_typeid,size_preg,size2);
03741 cwh_block_append(size2);
03742
03743
03744
03745 flag_val = 0;
03746 if (DEBUG_Trap_Uv) {
03747 flag_val |= 4;
03748 }
03749 if (is_f90_pointer) {
03750 cwh_stk_push(WN_COPY_Tree(dope_addr),WN_item);
03751 cwh_stk_push(WN_Intconst(MTYPE_I4,1),WN_item);
03752 #ifdef KEY
03753 fei_set_dv_hdr_fld(DV_PTR_ALLOC_IDX);
03754 #else
03755 fei_set_dv_hdr_fld(4);
03756 #endif
03757 flag_val |= 1;
03758 }
03759 flags = WN_Intconst(MTYPE_I4,flag_val);
03760
03761
03762
03763 cwh_stk_push(WN_COPY_Tree(dope_addr),WN_item);
03764 #ifdef KEY
03765 fei_get_dv_hdr_fld(DV_ASSOC_IDX);
03766 #else
03767 fei_get_dv_hdr_fld(3);
03768 #endif
03769 assoc = cwh_intrin_wrap_value_parm(cwh_expr_operand(NULL));
03770
03771
03772 args[0] = cwh_intrin_wrap_value_parm(WN_LdidPreg(cwh_bound_int_typeid,size_preg));
03773 args[1] = assoc;
03774 args[2] = cwh_intrin_wrap_value_parm(flags);
03775
03776 if (WNOPR(stat) == OPR_INTCONST) {
03777 args[3] = cwh_intrin_wrap_value_parm(WN_COPY_Tree(stat));
03778 } else {
03779 args[3] = cwh_intrin_wrap_ref_parm(WN_COPY_Tree(stat),0);
03780 }
03781
03782
03783 cwh_stk_push(WN_COPY_Tree(dope_addr),WN_item);
03784 #ifdef KEY
03785 fei_get_dv_hdr_fld(DV_BASE_IDX);
03786 #else
03787 fei_get_dv_hdr_fld(1);
03788 #endif
03789 args[4] = cwh_intrin_wrap_value_parm(cwh_expr_operand(NULL));
03790
03791 iop = WN_Create(opc_call,5);
03792
03793 for (i=0; i < 5; i++) {
03794 WN_kid(iop,i) = args[i];
03795 }
03796
03797
03798 WN_st_idx(iop) = ST_st_idx(allocate_routine_st);
03799 WN_Set_Call_Does_Mem_Alloc(iop);
03800 WN_Set_Call_Non_Data_Mod(iop);
03801 WN_Set_Call_Parm_Mod(iop);
03802 WN_Set_Call_Parm_Ref(iop);
03803 cwh_block_append(iop);
03804 iop = cwh_stmt_return_scalar(NULL, NULL, Be_Type_Tbl(Pointer_Mtype), FALSE);
03805 iop = WN_StidPreg(Pointer_Mtype,addr_preg,iop);
03806 cwh_block_append(iop);
03807
03808
03809
03810 cwh_stk_push_typed(WN_COPY_Tree(dope_addr),WN_item, types[idope]);
03811 cwh_stk_push(WN_LdidPreg(Pointer_Mtype,addr_preg),WN_item);
03812 #ifdef KEY
03813 fei_set_dv_hdr_fld(DV_BASE_IDX);
03814 #else
03815 fei_set_dv_hdr_fld(1);
03816 #endif
03817
03818
03819 cwh_stk_push_typed(WN_COPY_Tree(dope_addr),WN_item, types[idope]);
03820 cwh_stk_push(WN_LdidPreg(Pointer_Mtype,addr_preg),WN_item);
03821 #ifdef KEY
03822 fei_set_dv_hdr_fld(DV_ORIG_BASE_IDX);
03823 #else
03824 fei_set_dv_hdr_fld(9);
03825 #endif
03826
03827
03828 cwh_stk_push(WN_COPY_Tree(dope_addr),WN_item);
03829 size = cwh_expr_bincalc(OPR_SHL,WN_LdidPreg(cwh_bound_int_typeid,size_preg),
03830 WN_Intconst(MTYPE_I4,3));
03831 cwh_stk_push(size,WN_item);
03832 #ifdef KEY
03833 fei_set_dv_hdr_fld(DV_ORIG_SIZE_IDX);
03834 #else
03835 fei_set_dv_hdr_fld(10);
03836 #endif
03837
03838
03839 cwh_stk_push(WN_COPY_Tree(dope_addr),WN_item);
03840 assoc = WN_LdidPreg(Pointer_Mtype,addr_preg);
03841 assoc = WN_CreateExp2(OPCODE_make_op(OPR_GT,MTYPE_I4,Pointer_Mtype),
03842 assoc,
03843 WN_Zerocon(Pointer_Mtype));
03844 cwh_stk_push(assoc,WN_item);
03845 #ifdef KEY
03846 fei_set_dv_hdr_fld(DV_ASSOC_IDX);
03847 #else
03848 fei_set_dv_hdr_fld(3);
03849 #endif
03850 }
03851 }
03852
03853
03854
03855
03856
03857
03858
03859
03860
03861
03862
03863
03864
03865
03866
03867
03868
03869
03870
03871
03872 extern void
03873 fei_allocate(INT32 count)
03874 {
03875
03876 INT num_dopes,i,num_args;
03877 BOOL use_stat;
03878 WN **dopes;
03879 TY_IDX *types;
03880 WN *dope;
03881 WN *wn;
03882 WN *stat,*ver;
03883 ST *routine;
03884 TY_IDX temp_ty;
03885 TY_IDX pty;
03886 ST *temp_st;
03887 INT64 vernum;
03888 WN *call;
03889 char temp_str[40];
03890 static INT32 temp_name_idx = 0;
03891
03892 num_dopes = count - 3;
03893 dopes = (WN **) malloc(num_dopes*sizeof(WN *));
03894 types = (TY_IDX *) malloc(num_dopes*sizeof(TY_IDX ));
03895 for (i=0; i < num_dopes; i++) {
03896 types[i] = cwh_stk_get_TY();
03897 dopes[i] = cwh_expr_operand(NULL);
03898 if (!types[i]) {
03899
03900 types[i] = cwh_types_WN_TY(dopes[i],TRUE);
03901 }
03902 }
03903 stat = cwh_expr_operand(NULL);
03904 ver = cwh_expr_operand(NULL);
03905 routine = cwh_stk_pop_ST();
03906
03907 if (!strcmp(ST_name(routine),"_DEALLOC")) {
03908 use_stat = FALSE;
03909 num_args = num_dopes+1;
03910 } else if (!strcmp(ST_name(routine),"_ALLOCATE")) {
03911 cwh_inline_allocate(dopes,types,num_dopes,stat);
03912 free(dopes);
03913 free(types);
03914 return;
03915 } else {
03916 use_stat = TRUE;
03917 num_args = num_dopes+2;
03918 }
03919
03920
03921 call = WN_Create(OPC_VCALL,num_args);
03922 WN_st_idx(call) = ST_st_idx(routine);
03923 WN_Set_Call_Parm_Ref(call);
03924 WN_Set_Call_Parm_Mod(call);
03925 WN_Set_Call_Does_Mem_Free(call);
03926
03927
03928 sprintf(temp_str, "%s%d", ".alloctemp.", temp_name_idx);
03929 temp_ty = cwh_types_array_util(1,Be_Type_Tbl(Pointer_Mtype),Pointer_Size,
03930 Pointer_Size*num_dopes+8,temp_str,TRUE);
03931
03932 ARB_HANDLE arb = TY_arb(temp_ty);
03933 Set_ARB_ubnd_val(arb, num_dopes + (8/Pointer_Size));
03934 Set_ARB_stride_val(arb, Pointer_Size);
03935
03936 sprintf(temp_str, "%s%d", ".alloc", temp_name_idx++);
03937 temp_st = cwh_stab_address_temp_ST(temp_str,temp_ty,FALSE);
03938 Set_ST_base(temp_st, temp_st);
03939 cwh_expr_set_flags(temp_st, f_T_PASSED);
03940
03941 WN_kid0(call) = cwh_intrin_wrap_ref_parm(cwh_addr_address_ST(temp_st, 0),0);
03942
03943
03944 if (use_stat) {
03945 if (WNOPR(stat) == OPR_INTCONST) {
03946
03947 WN_set_opcode(stat,OPCODE_make_op(OPR_INTCONST,Pointer_Mtype,MTYPE_V));
03948 stat = cwh_intrin_wrap_value_parm(stat);
03949 } else {
03950 stat = cwh_intrin_wrap_ref_parm(stat,0);
03951 }
03952 WN_kid1(call) = stat;
03953 }
03954
03955 pty = Be_Type_Tbl(Pointer_Mtype);
03956
03957 DevAssert((WN_opcode(ver) == OPC_I8INTCONST),("Expected I8INTCONST for allocate version."));
03958 if (Pointer_Size == 4) {
03959 # if defined(linux) || defined(BUILD_OS_DARWIN)
03960 vernum = WN_const_val(ver) & (0xffffffff);
03961 cwh_block_append(cwh_addr_stid(temp_st,0,pty,
03962 WN_Intconst(Pointer_Mtype,vernum)));
03963 vernum = WN_const_val(ver) >> 32;
03964 cwh_block_append(cwh_addr_stid(temp_st,4,pty,
03965 WN_Intconst(Pointer_Mtype,vernum)));
03966 # else
03967 vernum = WN_const_val(ver) >> 32;
03968 cwh_block_append(cwh_addr_stid(temp_st,0,pty,
03969 WN_Intconst(Pointer_Mtype,vernum)));
03970 vernum = WN_const_val(ver) & (0xffffffff);
03971 cwh_block_append(cwh_addr_stid(temp_st,4,pty,
03972 WN_Intconst(Pointer_Mtype,vernum)));
03973 # endif
03974 WN_DELETE_Tree(ver);
03975 } else {
03976 cwh_block_append(cwh_addr_stid(temp_st,0,pty, ver));
03977 }
03978
03979 for (i=0; i < num_dopes; i++) {
03980 dope = dopes[i];
03981 wn = cwh_addr_stid(temp_st, 8 + Pointer_Size*i,pty,WN_COPY_Tree(dope));
03982 cwh_block_append(wn);
03983 dope = cwh_intrin_wrap_ref_parm(dope,0);
03984 WN_Set_Parm_Dummy(dope);
03985 if (use_stat) {
03986 WN_kid(call,i+2) = dope;
03987 } else {
03988 WN_kid(call,i+1) = dope;
03989 }
03990 }
03991
03992
03993
03994 cwh_block_append(call);
03995 free (dopes);
03996 free (types);
03997 }
03998
03999
04000
04001
04002
04003
04004
04005
04006
04007
04008
04009
04010
04011 extern void
04012 cwh_stmt_init_file(BOOL sgi_mp)
04013 {
04014 cwh_stmt_sgi_mp_flag = sgi_mp ;
04015 cwh_addr_init_target() ;
04016 }
04017
04018
04019
04020
04021
04022
04023
04024
04025
04026
04027 static void
04028 cwh_stmt_add_parallel_pragmas(void)
04029 {
04030 WN *prag;
04031
04032 if (global_chunk_pragma_set) {
04033 prag = WN_CreateXpragma(WN_PRAGMA_CHUNKSIZE, (ST_IDX) 0, 1);
04034 WN_kid0(prag) = WN_Intconst(MTYPE_I4,global_chunk_pragma_value);
04035 cwh_stmt_add_to_preamble(prag,block_pu);
04036 }
04037
04038 if (global_schedtype_pragma_set) {
04039 prag = WN_CreatePragma(WN_PRAGMA_MPSCHEDTYPE, (ST_IDX) NULL, global_schedtype_pragma_val,4);
04040 cwh_stmt_add_to_preamble(prag,block_pu);
04041 }
04042 }
04043
04044 #ifdef KEY
04045
04046
04047
04048
04049 static void
04050 export_i4_sym(const char *symname, int value) {
04051 TY_IDX int_ty_idx = MTYPE_To_TY(MTYPE_I4);
04052 ST *st = New_ST(GLOBAL_SYMTAB);
04053 cwh_auxst_clear(st);
04054 ST_Init(st, Save_Str(symname), CLASS_VAR, SCLASS_DGLOBAL, EXPORT_PREEMPTIBLE,
04055 int_ty_idx);
04056 Set_ST_is_initialized(st);
04057 INITO_IDX inito = New_INITO(st);
04058 INITV_IDX inv = New_INITV();
04059 INITV_Init_Integer(inv, MTYPE_I4, value, 1);
04060 Set_INITO_val(inito, inv);
04061 }
04062 #endif
04063
04064
04065
04066
04067
04068
04069
04070
04071
04072
04073
04074 extern void
04075 cwh_stmt_init_pu(ST * st, INT32 lineno)
04076 {
04077 INT16 nkids,i ;
04078 ST **ap ;
04079
04080 cwh_stmt_init_srcpos(lineno);
04081 (void) cwh_block_toggle_debug(FALSE);
04082
04083 nkids = cwh_auxst_num_dummies(st);
04084 ap = cwh_auxst_arglist(st);
04085
04086 (void) cwh_block_new_and_current() ;
04087
04088 WN_tree = WN_CreateEntry (nkids,st,cwh_block_current(), NULL,NULL );
04089
04090 WN_pragma_pu = WN_kid(WN_tree,nkids);
04091 WN_pragma_ca = WN_kid(WN_tree,nkids+1);
04092
04093 for (i = 0 ; i < nkids ; i ++)
04094 WN_kid(WN_tree,i) = WN_CreateIdname ( 0, *ap++);
04095
04096 WN_Set_Linenum (WN_tree, USRCPOS_srcpos(current_srcpos) );
04097 WN_Set_Linenum (cwh_block_current(), USRCPOS_srcpos(current_srcpos));
04098
04099 cwh_stmt_add_parallel_pragmas();
04100 #ifdef KEY
04101 char *compiler_bin = getenv("COMPILER_BIN");
04102 if (strcmp(ST_name(st), "MAIN__") == 0 &&
04103 compiler_bin != NULL) {
04104 size_t str_len = strlen(compiler_bin) + 1;
04105
04106
04107 char *psc_str = (char *) malloc(str_len*sizeof(char));
04108 strcpy(psc_str, compiler_bin);
04109
04110 TY_IDX str_ty_idx;
04111 TY &str_ty = New_TY(str_ty_idx);
04112 TY_Init(str_ty, str_len, KIND_ARRAY, MTYPE_M, 0);
04113 Set_TY_etype(str_ty, MTYPE_To_TY(MTYPE_I1));
04114 Set_TY_align(str_ty_idx, TY_align(TY_etype(str_ty)));
04115 ARB_HANDLE arb = New_ARB ();
04116 ARB_Init (arb, 0, 0, 0);
04117 Set_TY_arb (str_ty, arb);
04118 Set_ARB_first_dimen (arb);
04119 Set_ARB_last_dimen (arb);
04120 Set_ARB_dimension (arb, 1);
04121 Set_ARB_const_stride(arb);
04122 Set_ARB_stride_val(arb, 1);
04123 Set_ARB_const_lbnd (arb);
04124 Set_ARB_lbnd_val (arb, 0);
04125 Set_ARB_const_ubnd (arb);
04126 Set_ARB_ubnd_val (arb, str_len);
04127 ST *str_st = New_ST(GLOBAL_SYMTAB);
04128
04129 cwh_auxst_clear(str_st);
04130 ST_Init(str_st, Save_Str("__pathscale_compiler"), CLASS_VAR, SCLASS_DGLOBAL,
04131 EXPORT_PREEMPTIBLE, str_ty_idx);
04132 Set_ST_is_initialized(str_st);
04133 INITO_IDX inito = New_INITO(str_st);
04134 INITV_IDX inv = New_INITV();
04135 INITV_Init_String(inv, psc_str, str_len);
04136 Set_INITO_val(inito, inv);
04137 #ifdef KEY
04138
04139
04140
04141
04142 if (IO_DEFAULT != io_byteswap) {
04143 export_i4_sym("__io_byteswap_value", io_byteswap);
04144 }
04145 #endif
04146 #ifdef KEY
04147 # ifdef TARG_X8664
04148
04149
04150
04151
04152
04153 if (!(Target_SSE2 || Target_SSE3)) {
04154 export_i4_sym("__SSE2_off", 1);
04155 }
04156 # endif
04157 #endif
04158 }
04159 #endif
04160 }
04161
04162
04163
04164
04165
04166
04167
04168
04169
04170
04171
04172
04173 extern WN *
04174 cwh_stmt_end_pu(void)
04175 {
04176
04177 WN_pragma_pu = NULL;
04178 WN_pragma_ca = NULL;
04179
04180 return(WN_tree) ;
04181 }
04182
04183
04184
04185
04186
04187
04188
04189
04190 extern void
04191 cwh_stmt_postprocess_pu(void)
04192 {
04193
04194 if (DEBUG_Conform_Check) {
04195 cwh_stmt_conformance_checks(WN_tree);
04196 }
04197
04198
04199
04200
04201 return;
04202 }
04203
04204
04205
04206
04207
04208
04209
04210
04211
04212
04213
04214
04215
04216
04217
04218
04219
04220
04221
04222
04223 static void
04224 cwh_stmt_init_srcpos(INT32 lineno)
04225 {
04226 char *file_name;
04227 INT32 local_line_num;
04228 mUINT16 local_file_num;
04229
04230 static char *last_file_name = NULL;
04231 static PU *last_pu = NULL;
04232
04233 if (lineno != 0) {
04234
04235 file_name = global_to_local_file(lineno);
04236 local_line_num = global_to_local_line_number(lineno);
04237
04238 if ((last_file_name != file_name) ||
04239 (local_line_num > USRCPOS_linenum(current_srcpos)) ||
04240 (last_pu != &(Get_Current_PU()))) {
04241
04242 local_file_num = USRCPOS_filenum(current_srcpos) ;
04243
04244 USRCPOS_clear(current_srcpos);
04245
04246 if (last_file_name != file_name)
04247 USRCPOS_filenum(current_srcpos) = cwh_dst_enter_path(file_name);
04248 else
04249 USRCPOS_filenum(current_srcpos) = local_file_num ;
04250
04251 USRCPOS_linenum(current_srcpos) = local_line_num;
04252 Set_Error_Source (file_name );
04253 Set_Error_Line(local_line_num);
04254 }
04255 last_file_name = file_name ;
04256 last_pu = &(Get_Current_PU());
04257 }
04258 }
04259
04260
04261
04262
04263
04264
04265
04266
04267
04268
04269
04270
04271
04272
04273
04274
04275
04276
04277
04278 static void
04279 cwh_stmt_insert_conformance_check(WN **s1, WN **s2, INT ndims1, INT ndims2, INT first_axis,
04280 WN *stmt, WN *block)
04281 {
04282 INT i;
04283 WN *eq, *t1,*t2, *gt0, *temp;
04284 BOOL not_all_const = FALSE;
04285 BOOL need_gt0_check;
04286 WN *args[5];
04287 WN *call;
04288 WN *if_stmt,*ifthenblock;
04289 char * proc_name;
04290 #ifdef KEY
04291 PREG_NUM r1,r2;
04292 PREG_NUM rgt0 = 0;
04293 #else
04294 PREG_NUM r1,r2,rgt0;
04295 #endif
04296 INT64 lineno;
04297
04298
04299 if (ndims1 == 0 || ndims2 == 0) return;
04300 Is_True(ndims1==ndims2,("conformance check rank mismatch."));
04301
04302
04303 gt0 = WN_Intconst(MTYPE_I4,1);
04304 for (i=0; i < ndims1; i++) {
04305 t1 = cwh_convert_to_ty(WN_COPY_Tree(s1[i]),MTYPE_I8);
04306 t2 = cwh_convert_to_ty(WN_COPY_Tree(s2[i]),MTYPE_I8);
04307 gt0 = WN_LAND(gt0,WN_LIOR(WN_GT(MTYPE_I8,t1,WN_Zerocon(MTYPE_I8)),
04308 WN_GT(MTYPE_I8,t2,WN_Zerocon(MTYPE_I8))));
04309 }
04310
04311 need_gt0_check = TRUE;
04312 if (WN_operator(gt0) == OPR_INTCONST) {
04313 if (WN_const_val(gt0) == 0) {
04314
04315 WN_DELETE_Tree(gt0);
04316 return;
04317 } else {
04318 WN_DELETE_Tree(gt0);
04319 need_gt0_check = FALSE;
04320 }
04321 }
04322
04323 if (need_gt0_check) {
04324 rgt0 = Create_Preg(MTYPE_I4,Index_To_Str(Save_Str("ccgt0")));
04325 WN_INSERT_BlockBefore(block,stmt,WN_StidPreg(MTYPE_I4,rgt0,gt0));
04326 }
04327
04328 for (i=0; i < ndims1; i++) {
04329 t1 = cwh_convert_to_ty(WN_COPY_Tree(s1[i]),MTYPE_I8);
04330 t2 = cwh_convert_to_ty(WN_COPY_Tree(s2[i]),MTYPE_I8);
04331 eq = WN_EQ(MTYPE_I8,WN_COPY_Tree(t1),WN_COPY_Tree(t2));
04332
04333 if (WN_operator(eq) != OPR_INTCONST ||
04334 WN_const_val(eq) == 0) {
04335
04336
04337 lineno = WN_Get_Linenum(stmt);
04338 proc_name = cwh_dst_filename_from_filenum(SRCPOS_filenum(lineno));
04339
04340 args[0] = cwh_intrin_wrap_value_parm(WN_LdaString(proc_name, 0, strlen(proc_name)));
04341 args[1] = cwh_intrin_wrap_value_parm(WN_Intconst(MTYPE_I4, SRCPOS_linenum(lineno)));
04342 if (first_axis != 0) {
04343 args[2] = cwh_intrin_wrap_value_parm(WN_Intconst(MTYPE_I4,ndims1-1-i+first_axis));
04344 } else {
04345 args[2] = cwh_intrin_wrap_value_parm(WN_Intconst(MTYPE_I4,0));
04346 }
04347
04348
04349 r1 = Create_Preg(MTYPE_I8,Index_To_Str(Save_Str("cc1")));
04350 r2 = Create_Preg(MTYPE_I8,Index_To_Str(Save_Str("cc2")));
04351 WN_INSERT_BlockBefore(block,stmt,WN_StidPreg(MTYPE_I8,r1,t1));
04352 WN_INSERT_BlockBefore(block,stmt,WN_StidPreg(MTYPE_I8,r2,t2));
04353 args[3] = cwh_intrin_wrap_value_parm(WN_LdidPreg(MTYPE_I8,r1));
04354 args[4] = cwh_intrin_wrap_value_parm(WN_LdidPreg(MTYPE_I8,r2));
04355 call = WN_Create_Intrinsic(OPR_INTRINSIC_CALL, MTYPE_V, MTYPE_V,
04356 INTRN_F90CONFORM_CHECK, 5, args);
04357 ifthenblock = WN_CreateBlock();
04358 WN_INSERT_BlockFirst(ifthenblock,call);
04359 if_stmt = WN_NE(MTYPE_I8,WN_LdidPreg(MTYPE_I8,r1),WN_LdidPreg(MTYPE_I8,r2));
04360 if (need_gt0_check) {
04361 if_stmt = WN_LAND(WN_LdidPreg(MTYPE_I4,rgt0),if_stmt);
04362 }
04363 if_stmt = WN_CreateIf(if_stmt,ifthenblock,WN_CreateBlock());
04364 WN_INSERT_BlockBefore(block,stmt,if_stmt);
04365 } else {
04366 WN_DELETE_Tree(t1);
04367 WN_DELETE_Tree(t2);
04368 }
04369 WN_DELETE_Tree(eq);
04370 }
04371 }
04372
04373
04374
04375
04376
04377
04378
04379
04380
04381
04382
04383
04384
04385
04386
04387 #define MAX_KIDS 6
04388
04389 static void
04390 cwh_stmt_conformance_checks_walk (WN *tree, WN *stmt, WN *block, WN ** sizes, INT * ndim)
04391 {
04392 OPERATOR op;
04393 WN *node, *nextnode;
04394
04395 WN *ksizes[MAX_KIDS][MAX_ARY_DIMS];
04396 INT kndims[MAX_KIDS];
04397 INT i,j,numkids,i_save,numargs;
04398 INT dim;
04399
04400 op = WN_operator(tree);
04401 numkids = WN_kid_count(tree);
04402 if (ndim) *ndim = 0;
04403
04404 if (op == OPR_BLOCK) {
04405 node = WN_first(tree);
04406 while (node) {
04407 nextnode = WN_next(node);
04408 cwh_stmt_conformance_checks_walk (node, NULL, tree, NULL, NULL);
04409 node = nextnode;
04410 }
04411
04412 } else if (op == OPR_WHERE) {
04413
04414 DevAssert((numkids == 3),("Expected WHERE to have three kids."));
04415
04416
04417 cwh_stmt_conformance_checks_walk (WN_kid(tree,0), tree, block, NULL, NULL);
04418
04419
04420 DevAssert((WN_operator(WN_kid(tree,1)) == OPR_BLOCK),("Expected WHERE to have BLOCK kid 1"));
04421
04422 node = WN_first(WN_kid(tree,1));
04423 while (node) {
04424 nextnode = WN_next(node);
04425
04426 cwh_stmt_conformance_checks_walk (node, tree, block, NULL, NULL);
04427 node = nextnode;
04428 }
04429
04430
04431
04432 DevAssert((WN_operator(WN_kid(tree,2)) == OPR_BLOCK),("Expected WHERE to have BLOCK kid 2"));
04433
04434 node = WN_first(WN_kid(tree,2));
04435 while (node) {
04436 nextnode = WN_next(node);
04437
04438 cwh_stmt_conformance_checks_walk (node, tree, block, NULL, NULL);
04439 node = nextnode;
04440 }
04441
04442 } else if (op == OPR_ISTORE || op == OPR_MSTORE) {
04443 cwh_stmt_conformance_checks_walk (WN_kid(tree,0), (stmt?stmt:tree), block, ksizes[0], &kndims[0]);
04444 cwh_stmt_conformance_checks_walk (WN_kid(tree,1), (stmt?stmt:tree), block, ksizes[1], &kndims[1]);
04445 cwh_stmt_insert_conformance_check(ksizes[0],ksizes[1],kndims[0],kndims[1],1,(stmt?stmt:tree),block);
04446 if (sizes) {
04447 *ndim = kndims[0];
04448 for (i=0; i < kndims[0]; i++) {
04449 sizes[i] = ksizes[0][i];
04450 }
04451 } else {
04452 for (i=0; i < kndims[0]; i++) {
04453 WN_DELETE_Tree(ksizes[0][i]);
04454 }
04455 }
04456 for (i=0; i < kndims[1]; i++) {
04457 WN_DELETE_Tree(ksizes[1][i]);
04458 }
04459
04460 } else if (op == OPR_INTRINSIC_CALL && WN_intrinsic(tree) == INTRN_CASSIGNSTMT) {
04461
04462 cwh_stmt_conformance_checks_walk (WN_kid(tree,0), (stmt?stmt:tree), block, ksizes[0], &kndims[0]);
04463 cwh_stmt_conformance_checks_walk (WN_kid(tree,1), (stmt?stmt:tree), block, ksizes[1], &kndims[1]);
04464 cwh_stmt_conformance_checks_walk (WN_kid(tree,2), (stmt?stmt:tree), block, NULL, NULL);
04465 cwh_stmt_conformance_checks_walk (WN_kid(tree,3), (stmt?stmt:tree), block, NULL, NULL);
04466 cwh_stmt_insert_conformance_check(ksizes[0],ksizes[1],kndims[0],kndims[1],1,(stmt?stmt:tree),block);
04467 if (sizes) {
04468 *ndim = kndims[0];
04469 for (i=0; i < kndims[0]; i++) {
04470 sizes[i] = ksizes[0][i];
04471 }
04472 } else {
04473 for (i=0; i < kndims[0]; i++) {
04474 WN_DELETE_Tree(ksizes[0][i]);
04475 }
04476 }
04477 for (i=0; i < kndims[1]; i++) {
04478 WN_DELETE_Tree(ksizes[1][i]);
04479 }
04480
04481 } else if (op == OPR_INTRINSIC_CALL && WN_intrinsic(tree) == INTRN_CONCATEXPR) {
04482
04483 cwh_stmt_conformance_checks_walk (WN_kid(tree,0), (stmt?stmt:tree), block, ksizes[0], &kndims[0]);
04484 cwh_stmt_conformance_checks_walk (WN_kid(tree,1), (stmt?stmt:tree), block, NULL, NULL);
04485
04486 numargs = (numkids - 2)/2;
04487 for (i=0; i < numargs; i++) {
04488 cwh_stmt_conformance_checks_walk (WN_kid(tree,i+2), (stmt?stmt:tree), block, ksizes[1], &kndims[1]);
04489 cwh_stmt_conformance_checks_walk (WN_kid(tree,i+2+numargs), (stmt?stmt:tree), block, NULL, NULL);
04490 cwh_stmt_insert_conformance_check(ksizes[0],ksizes[1],kndims[0],kndims[1],1,(stmt?stmt:tree),block);
04491 for (j=0; j < kndims[1]; j++) {
04492 WN_DELETE_Tree(ksizes[1][j]);
04493 }
04494 }
04495
04496 if (sizes) {
04497 *ndim = kndims[0];
04498 for (i=0; i < kndims[0]; i++) {
04499 sizes[i] = ksizes[0][i];
04500 }
04501 } else {
04502 for (i=0; i < kndims[0]; i++) {
04503 WN_DELETE_Tree(ksizes[0][i]);
04504 }
04505 }
04506
04507 } else if (OPERATOR_is_stmt(op) || OPERATOR_is_scf(op)) {
04508 for (i=0; i < numkids; i++) {
04509 cwh_stmt_conformance_checks_walk (WN_kid(tree,i), (stmt?stmt:tree), block, NULL, NULL);
04510 }
04511
04512 } else {
04513
04514 switch (op) {
04515 case OPR_ARRAYEXP:
04516 case OPR_ARRSECTION:
04517 case OPR_ARRAY:
04518 case OPR_TRIPLET:
04519 for (i=0; i < numkids; i++) {
04520 cwh_stmt_conformance_checks_walk (WN_kid(tree,i), stmt, block, NULL, NULL);
04521 }
04522 if (sizes) {
04523 F90_Size_Walk(tree,ndim,sizes);
04524 }
04525 break;
04526
04527 default:
04528
04529 if (op == OPR_INTRINSIC_OP && F90_Is_Transformational(WN_intrinsic(tree))) {
04530
04531 switch (WN_intrinsic(tree)) {
04532
04533 default:
04534 case INTRN_SPREAD:
04535 case INTRN_TRANSPOSE:
04536 case INTRN_ALL:
04537 case INTRN_ANY:
04538 case INTRN_COUNT:
04539 case INTRN_RESHAPE:
04540 for (i=0; i < numkids; i++) {
04541 cwh_stmt_conformance_checks_walk (WN_kid(tree,0), stmt, block, NULL, NULL);
04542 }
04543 if (sizes) {
04544 F90_Size_Walk(tree,ndim,sizes);
04545 }
04546 break;
04547
04548 case INTRN_MATMUL:
04549 case INTRN_DOT_PRODUCT:
04550 cwh_stmt_conformance_checks_walk (WN_kid(tree,0), stmt, block, ksizes[0], &kndims[0]);
04551 cwh_stmt_conformance_checks_walk (WN_kid(tree,1), stmt, block, ksizes[1], &kndims[1]);
04552 if (kndims[0] == 2 && kndims[1] == 2) {
04553 cwh_stmt_insert_conformance_check(&ksizes[0][0],&ksizes[1][1],1,1,0,stmt,block);
04554 WN_DELETE_Tree(ksizes[0][0]);
04555 WN_DELETE_Tree(ksizes[1][1]);
04556 if (sizes) {
04557 sizes[1] = ksizes[0][1];
04558 sizes[0] = ksizes[1][0];
04559 *ndim = 2;
04560 }
04561 } else if (kndims[0] == 2 && kndims[1] == 1) {
04562 cwh_stmt_insert_conformance_check(&ksizes[0][0],&ksizes[1][0],1,1,0,stmt,block);
04563 WN_DELETE_Tree(ksizes[0][0]);
04564 WN_DELETE_Tree(ksizes[1][0]);
04565 if (sizes) {
04566 sizes[0] = ksizes[0][1];
04567 *ndim = 1;
04568 }
04569 } else if (kndims[0] == 1 && kndims[1] == 2) {
04570 cwh_stmt_insert_conformance_check(&ksizes[0][0],&ksizes[1][1],1,1,0,stmt,block);
04571 WN_DELETE_Tree(ksizes[0][0]);
04572 WN_DELETE_Tree(ksizes[1][1]);
04573 if (sizes) {
04574 sizes[0] = ksizes[1][0];
04575 *ndim = 1;
04576 }
04577 } else {
04578
04579 cwh_stmt_insert_conformance_check(&ksizes[0][0],&ksizes[1][0],1,1,1,stmt,block);
04580 WN_DELETE_Tree(ksizes[0][0]);
04581 WN_DELETE_Tree(ksizes[1][0]);
04582 }
04583 break;
04584
04585 case INTRN_PRODUCT:
04586 case INTRN_SUM:
04587 case INTRN_MAXVAL:
04588 case INTRN_MINVAL:
04589 case INTRN_MAXLOC:
04590 case INTRN_MINLOC:
04591 cwh_stmt_conformance_checks_walk (WN_kid(tree,0), stmt, block, ksizes[0], &kndims[0]);
04592 cwh_stmt_conformance_checks_walk (WN_kid(tree,2), stmt, block, ksizes[1], &kndims[1]);
04593 cwh_stmt_insert_conformance_check(ksizes[0],ksizes[1],kndims[0],kndims[1],1,stmt,block);
04594 for (i=0; i < kndims[0]; i++) {
04595 WN_DELETE_Tree(ksizes[0][i]);
04596 }
04597 for (i=0; i < kndims[1]; i++) {
04598 WN_DELETE_Tree(ksizes[1][i]);
04599 }
04600 if (sizes) {
04601 F90_Size_Walk(tree,ndim,sizes);
04602 }
04603 break;
04604
04605 case INTRN_CSHIFT:
04606 cwh_stmt_conformance_checks_walk (WN_kid(tree,0), stmt, block, ksizes[0], &kndims[0]);
04607 cwh_stmt_conformance_checks_walk (WN_kid(tree,1), stmt, block, ksizes[1], &kndims[1]);
04608 dim = F90_Get_Dim(WN_kid(tree,2))-1;
04609
04610
04611 if (dim >= 0) {
04612 for (i=0,j=0; i < kndims[0]; i++) {
04613 if (i != kndims[0]-1-dim) {
04614 ksizes[2][j] = ksizes[0][i];
04615 ++j;
04616 }
04617 }
04618 kndims[2] = kndims[0] - 1;
04619 cwh_stmt_insert_conformance_check(ksizes[2],ksizes[1],kndims[2],kndims[1],0,stmt,block);
04620 }
04621 if (sizes) {
04622 *ndim = kndims[0];
04623 for (i=0; i < kndims[0]; i++) {
04624 sizes[i] = ksizes[0][i];
04625 }
04626 } else {
04627 for (i=0; i < kndims[0]; i++) {
04628 WN_DELETE_Tree(ksizes[0][i]);
04629 }
04630 }
04631 for (i=0; i < kndims[1]; i++) {
04632 WN_DELETE_Tree(ksizes[1][i]);
04633 }
04634 break;
04635
04636 case INTRN_EOSHIFT:
04637 cwh_stmt_conformance_checks_walk (WN_kid(tree,0), stmt, block, ksizes[0], &kndims[0]);
04638 cwh_stmt_conformance_checks_walk (WN_kid(tree,1), stmt, block, ksizes[1], &kndims[1]);
04639 cwh_stmt_conformance_checks_walk (WN_kid(tree,2), stmt, block, ksizes[2], &kndims[2]);
04640 dim = F90_Get_Dim(WN_kid(tree,3))-1;
04641
04642
04643 if (dim >= 0) {
04644 for (i=0,j=0; i < kndims[0]; i++) {
04645 if (i != kndims[0]-1-dim) {
04646 ksizes[3][j] = ksizes[0][i];
04647 ++j;
04648 }
04649 }
04650 kndims[3] = kndims[0] - 1;
04651 cwh_stmt_insert_conformance_check(ksizes[3],ksizes[1],kndims[3],kndims[1],0,stmt,block);
04652 cwh_stmt_insert_conformance_check(ksizes[3],ksizes[2],kndims[3],kndims[2],0,stmt,block);
04653 }
04654 if (sizes) {
04655 *ndim = kndims[0];
04656 for (i=0; i < kndims[0]; i++) {
04657 sizes[i] = ksizes[0][i];
04658 }
04659 } else {
04660 for (i=0; i < kndims[0]; i++) {
04661 WN_DELETE_Tree(ksizes[0][i]);
04662 }
04663 }
04664 for (i=0; i < kndims[1]; i++) {
04665 WN_DELETE_Tree(ksizes[1][i]);
04666 }
04667 for (i=0; i < kndims[2]; i++) {
04668 WN_DELETE_Tree(ksizes[2][i]);
04669 }
04670 break;
04671
04672 case INTRN_PACK:
04673 cwh_stmt_conformance_checks_walk (WN_kid(tree,0), stmt, block, ksizes[0], &kndims[0]);
04674 cwh_stmt_conformance_checks_walk (WN_kid(tree,1), stmt, block, ksizes[1], &kndims[1]);
04675 cwh_stmt_conformance_checks_walk (WN_kid(tree,2), stmt, block, sizes, ndim);
04676 cwh_stmt_insert_conformance_check(ksizes[0],ksizes[1],kndims[0],kndims[1],1,stmt,block);
04677 for (i=0; i < kndims[0]; i++) {
04678 WN_DELETE_Tree(ksizes[0][i]);
04679 }
04680 for (i=0; i < kndims[1]; i++) {
04681 WN_DELETE_Tree(ksizes[1][i]);
04682 }
04683 break;
04684
04685 case INTRN_UNPACK:
04686 cwh_stmt_conformance_checks_walk (WN_kid(tree,0), stmt, block, NULL, NULL);
04687 cwh_stmt_conformance_checks_walk (WN_kid(tree,1), stmt, block, ksizes[0], &kndims[0]);
04688 cwh_stmt_conformance_checks_walk (WN_kid(tree,2), stmt, block, ksizes[1], &kndims[1]);
04689 cwh_stmt_insert_conformance_check(ksizes[0],ksizes[1],kndims[0],kndims[1],1,stmt,block);
04690
04691 if (sizes) {
04692 *ndim = kndims[0];
04693 for (i=0; i < kndims[0]; i++) {
04694 sizes[i] = ksizes[0][i];
04695 }
04696 } else {
04697 for (i=0; i < kndims[0]; i++) {
04698 WN_DELETE_Tree(ksizes[0][i]);
04699 }
04700 }
04701 for (i=0; i < kndims[1]; i++) {
04702 WN_DELETE_Tree(ksizes[1][i]);
04703 }
04704 break;
04705
04706 }
04707
04708 break;
04709 }
04710
04711 if (numkids == 0) {
04712 break;
04713 }
04714 if (numkids == 1) {
04715 cwh_stmt_conformance_checks_walk (WN_kid(tree,0), stmt, block, sizes, ndim);
04716 break;
04717 }
04718
04719
04720 if (numkids > MAX_KIDS) break;
04721 for (i=0; i < numkids; i++) {
04722 cwh_stmt_conformance_checks_walk (WN_kid(tree,i), stmt, block,
04723 ksizes[i], &kndims[i]);
04724 }
04725 for (i=0; i < numkids; i++) {
04726 for (j = i+1; j < numkids; j++) {
04727 cwh_stmt_insert_conformance_check(ksizes[i],ksizes[j],kndims[i],kndims[j],1,stmt,block);
04728 }
04729 }
04730
04731
04732 i_save = -1;
04733 if (sizes) {
04734 for (i=0; i < numkids; i++) {
04735 if (kndims[i] > *ndim) {
04736 i_save = i;
04737 *ndim = kndims[i];
04738 for (j = 0; j < kndims[i]; j++) {
04739 sizes[j] = ksizes[i][j];
04740 }
04741 }
04742 }
04743 }
04744
04745
04746 for (i=0; i < numkids; i++) {
04747 if (i_save != i) {
04748 for (j = 0; j < kndims[i]; j++) {
04749 WN_DELETE_Tree(ksizes[i][j]);
04750 }
04751 }
04752 }
04753 break;
04754 }
04755 }
04756 return;
04757 }
04758
04759
04760
04761
04762
04763
04764
04765
04766
04767
04768
04769 static void
04770 cwh_stmt_conformance_checks(WN *tree)
04771 {
04772 cwh_stmt_conformance_checks_walk(tree,NULL,NULL,NULL,NULL);
04773 }