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 #ifdef USE_PCH
00043 #include "lno_pch.h"
00044 #endif // USE_PCH
00045 #pragma hdrstop
00046
00047 #include "defs.h"
00048 #include "wn.h"
00049 #include "wn_pragmas.h"
00050 #include "cxx_memory.h"
00051 #include "lnopt_main.h"
00052 #include "lwn_util.h"
00053 #include "fission.h"
00054 #include "fusion.h"
00055 #include "errors.h"
00056 #include "erbe.h"
00057 #include "erglob.h"
00058 #include "lnoutils.h"
00059
00060 static MEM_POOL FF_PRAGMA_default_pool;
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076 class FF_PRAGMA_WARNING_INFO {
00077 mUINT64 _entry;
00078 public:
00079 operator UINT64() {return _entry;}
00080 FF_PRAGMA_WARNING_INFO(INT32 line, WN_PRAGMA_ID pragma) :
00081 _entry((UINT64(line) << 32) | UINT64(pragma&0xFFFFFFFF)) {}
00082 INT32 Line() const {return _entry >> 32;}
00083 };
00084 typedef HASH_TABLE<FF_PRAGMA_WARNING_INFO,BOOL> FF_PRAGMA_WARNING_TABLE;
00085
00086 BOOL FF_Pragma_Seen_Before(WN* wn)
00087 {
00088 INT32 line = WN_Get_Linenum(wn);
00089
00090 if (line == 0)
00091 return FALSE;
00092
00093 static FF_PRAGMA_WARNING_TABLE* FF_Pragma_Warning_Table = NULL;
00094 WN_PRAGMA_ID pragma = (WN_PRAGMA_ID)WN_pragma(wn);
00095 FF_PRAGMA_WARNING_INFO info(line, pragma);
00096
00097 if (FF_Pragma_Warning_Table == NULL)
00098 FF_Pragma_Warning_Table =
00099 CXX_NEW(FF_PRAGMA_WARNING_TABLE(71, Malloc_Mem_Pool), Malloc_Mem_Pool);
00100
00101 if (FF_Pragma_Warning_Table->Find(info))
00102 return TRUE;
00103
00104 FF_Pragma_Warning_Table->Enter(info,1);
00105 return FALSE;
00106 }
00107
00108
00109
00110
00111
00112
00113
00114 static void Pragma_Set_No_Interchange(WN* wn_ref)
00115 {
00116 if (WN_opcode(wn_ref) == OPC_DO_LOOP) {
00117 DO_LOOP_INFO* dli = Get_Do_Loop_Info(wn_ref);
00118 dli->Cannot_Interchange = TRUE;
00119 if (dli->Is_Inner)
00120 return;
00121 }
00122 if (WN_opcode(wn_ref) == OPC_BLOCK) {
00123 for (WN* wn = WN_first(wn_ref); wn != NULL; wn = WN_next(wn))
00124 Pragma_Set_No_Interchange(wn);
00125 } else {
00126 for (INT i = 0; i < WN_kid_count(wn_ref); i++)
00127 Pragma_Set_No_Interchange(WN_kid(wn_ref, i));
00128 }
00129 }
00130
00131
00132 static BOOL Find_Preceeding_Pragma(WN* wn, WN_PRAGMA_ID pragma_id) {
00133 WN* prev_pragma=WN_prev(wn);
00134 while (prev_pragma &&
00135 (WN_opcode(prev_pragma)==OPC_PRAGMA ||
00136 WN_opcode(prev_pragma)==OPC_XPRAGMA)) {
00137 if (WN_pragma(prev_pragma)==pragma_id)
00138 return TRUE;
00139 prev_pragma=WN_prev(prev_pragma);
00140 }
00141 return FALSE;
00142 }
00143
00144 static WN* Find_Loop_N_Inside(INT n, WN* wn)
00145 {
00146 INT count=1;
00147 LWN_ITER* itr = LWN_WALK_SCFIter(wn);
00148 for ( ; itr; itr = LWN_WALK_SCFNext(itr)) {
00149 WN* w = itr->wn;
00150 if (WN_opcode(w) == OPC_DO_LOOP && count++ == n) {
00151 LWN_WALK_Abort(itr);
00152 return w;
00153 }
00154 }
00155 return NULL;
00156 }
00157
00158
00159 static void LWN_Process_FF_Pragmas_Walk_r(WN* wn)
00160 {
00161 static BOOL ignoring_interchange = FALSE;
00162 static BOOL ignoring_blockable = FALSE;
00163
00164 OPCODE opc=WN_opcode(wn);
00165
00166 if (opc == OPC_DO_LOOP) {
00167 ignoring_interchange = FALSE;
00168 ignoring_blockable = FALSE;
00169 }
00170
00171 if (opc==OPC_PRAGMA || opc==OPC_XPRAGMA) {
00172 BOOL remove = FALSE;
00173
00174 WN_PRAGMA_ID pragma_id=(WN_PRAGMA_ID)WN_pragma(wn);
00175 INT64 pragma_value=WN_const_val(wn);
00176 INT32 prag_arg1=WN_pragma_arg1(wn);
00177 INT32 prag_arg2=WN_pragma_arg2(wn);
00178 DO_LOOP_INFO* dli;
00179 DO_LOOP_INFO* dli1;
00180
00181 WN* next_non_prag_stid = WN_next(wn);
00182 while (next_non_prag_stid) {
00183 OPCODE op = WN_opcode(next_non_prag_stid);
00184 if (op != OPC_PRAGMA && op != OPC_XPRAGMA &&
00185 OPCODE_operator(op) != OPR_STID)
00186 break;
00187 next_non_prag_stid = WN_next(next_non_prag_stid);
00188 }
00189
00190 switch (pragma_id) {
00191 case WN_PRAGMA_INLINE_BODY_START:
00192 case WN_PRAGMA_INLINE_BODY_END:
00193 remove = TRUE;
00194 break;
00195
00196
00197 case WN_PRAGMA_BLOCKABLE:
00198 case WN_PRAGMA_INTERCHANGE:
00199 remove = TRUE;
00200 if (next_non_prag_stid == NULL ||
00201 WN_opcode(next_non_prag_stid) != OPC_DO_LOOP) {
00202 if (!FF_Pragma_Seen_Before(wn))
00203 ErrMsgSrcpos(EC_LNO_Bad_Pragma_String, WN_Get_Linenum(wn),
00204 WN_pragmas[pragma_id].name,
00205 "not followed by a loop, ignored");
00206 break;
00207 }
00208 {
00209 BOOL ipragma = pragma_id == WN_PRAGMA_INTERCHANGE;
00210 if ((!ignoring_interchange && ipragma) ||
00211 (!ignoring_blockable && !ipragma)) {
00212 INT interchange_vector[LNO_MAX_DO_LOOP_DEPTH];
00213 INT count = 0;
00214 BOOL error = FALSE;
00215
00216 if (ipragma) ignoring_interchange = TRUE;
00217 else ignoring_blockable = TRUE;
00218
00219 for (INT i = 0; i < LNO_MAX_DO_LOOP_DEPTH; i++)
00220 interchange_vector[i] = -1;
00221
00222 WN* p = 0;
00223 for (p = wn;
00224 WN_opcode(p) == OPC_PRAGMA || WN_opcode(p) == OPC_XPRAGMA;
00225 p = WN_next(p)) {
00226 WN_PRAGMA_ID pragma_id = (WN_PRAGMA_ID)WN_pragma(p);
00227
00228 if ((ipragma && (pragma_id == WN_PRAGMA_INTERCHANGE)) ||
00229 (!ipragma && (pragma_id == WN_PRAGMA_BLOCKABLE))) {
00230 WN* sdo = Find_Loop_N_Inside(WN_pragma_arg1(p),
00231 next_non_prag_stid);
00232 if (sdo) {
00233 INT sdo_no = Do_Depth(sdo) - Do_Depth(next_non_prag_stid);
00234 interchange_vector[count++] = sdo_no;
00235 } else {
00236 ErrMsgSrcpos(EC_LNO_Bad_Pragma_String, WN_Get_Linenum(p),
00237 WN_pragmas[pragma_id].name,"loop must follow");
00238 error = TRUE;
00239 break;
00240 }
00241 }
00242 }
00243 if (error == FALSE) {
00244 if (!Is_Permutation_Vector(interchange_vector, count)) {
00245 ErrMsgSrcpos(EC_LNO_Bad_Pragma_String, WN_Get_Linenum(p),
00246 WN_pragmas[pragma_id].name,
00247 "incomplete index specification");
00248 }
00249 else {
00250 dli = Get_Do_Loop_Info(next_non_prag_stid);
00251 if (ipragma) {
00252 dli->Permutation_Spec_Count = count;
00253 dli->Permutation_Spec_Array= CXX_NEW_ARRAY(INT, count,
00254 dli->Pool());
00255 for (INT i = 0; i < count; i++)
00256 dli->Permutation_Spec_Array[i] = interchange_vector[i];
00257 }
00258 else
00259 dli->Blockable_Specification = count;
00260 }
00261 }
00262 }
00263 }
00264 break;
00265
00266 case WN_PRAGMA_NO_INTERCHANGE:
00267 remove = TRUE;
00268 if (next_non_prag_stid == NULL ||
00269 WN_opcode(next_non_prag_stid) != OPC_DO_LOOP) {
00270 if (!FF_Pragma_Seen_Before(wn))
00271 ErrMsgSrcpos(EC_LNO_Bad_Pragma_String, WN_Get_Linenum(wn),
00272 WN_pragmas[pragma_id].name,
00273 "not followed by a loop, ignored");
00274 break;
00275 }
00276 Pragma_Set_No_Interchange(next_non_prag_stid);
00277 break;
00278
00279 case WN_PRAGMA_BLOCKING_SIZE:
00280 remove = TRUE;
00281 if (next_non_prag_stid == NULL ||
00282 WN_opcode(next_non_prag_stid) != OPC_DO_LOOP) {
00283 if (!FF_Pragma_Seen_Before(wn))
00284 ErrMsgSrcpos(EC_LNO_Bad_Pragma_String, WN_Get_Linenum(wn),
00285 WN_pragmas[pragma_id].name,
00286 "not followed by a loop, ignored");
00287 break;
00288 }
00289 dli=Get_Do_Loop_Info(next_non_prag_stid);
00290 if (prag_arg1 >= -1)
00291 dli->Required_Blocksize[0] = prag_arg1;
00292 else if (!FF_Pragma_Seen_Before(wn))
00293 ErrMsgSrcpos(EC_LNO_Bad_Pragma_Int, WN_Get_Linenum(wn),
00294 WN_pragmas[pragma_id].name, prag_arg1);
00295 if (prag_arg1 >= -1)
00296 dli->Required_Blocksize[1] = prag_arg2;
00297 else if (!FF_Pragma_Seen_Before(wn))
00298 ErrMsgSrcpos(EC_LNO_Bad_Pragma_Int, WN_Get_Linenum(wn),
00299 WN_pragmas[pragma_id].name, prag_arg2);
00300 break;
00301
00302 case WN_PRAGMA_NO_BLOCKING:
00303 remove = TRUE;
00304 if (next_non_prag_stid == NULL ||
00305 WN_opcode(next_non_prag_stid) != OPC_DO_LOOP) {
00306 if (!FF_Pragma_Seen_Before(wn))
00307 ErrMsgSrcpos(EC_LNO_Bad_Pragma_String, WN_Get_Linenum(wn),
00308 WN_pragmas[pragma_id].name,
00309 "not followed by a loop, ignored");
00310 break;
00311 }
00312 dli=Get_Do_Loop_Info(next_non_prag_stid);
00313 dli->Cannot_Block = TRUE;
00314 break;
00315
00316 case WN_PRAGMA_UNROLL:
00317 remove = TRUE;
00318 if (next_non_prag_stid == NULL ||
00319 WN_opcode(next_non_prag_stid) != OPC_DO_LOOP) {
00320 if (!FF_Pragma_Seen_Before(wn))
00321 ErrMsgSrcpos(EC_LNO_Bad_Pragma_String, WN_Get_Linenum(wn),
00322 WN_pragmas[pragma_id].name,
00323 "not followed by a loop, ignored");
00324 break;
00325 }
00326 if (prag_arg1 > 0)
00327 Get_Do_Loop_Info(next_non_prag_stid)->Required_Unroll = prag_arg1;
00328 else if (prag_arg1 == 0)
00329 ;
00330 else if (!FF_Pragma_Seen_Before(wn))
00331 ErrMsgSrcpos(EC_LNO_Bad_Pragma_Int, WN_Get_Linenum(wn),
00332 WN_pragmas[pragma_id].name, prag_arg1);
00333 break;
00334
00335 case WN_PRAGMA_AGGRESSIVE_INNER_LOOP_FISSION:
00336 if (next_non_prag_stid == NULL ||
00337 WN_opcode(next_non_prag_stid) != OPC_DO_LOOP) {
00338 if (!FF_Pragma_Seen_Before(wn))
00339 ErrMsgSrcpos(EC_LNO_Bad_Pragma_String, WN_Get_Linenum(wn),
00340 WN_pragmas[pragma_id].name,
00341 "not followed by a loop, ignored");
00342 break;
00343 }
00344 remove = TRUE;
00345 dli=Get_Do_Loop_Info(next_non_prag_stid);
00346 dli->Aggressive_Inner_Fission=TRUE;
00347 break;
00348
00349 case WN_PRAGMA_FISSION:
00350 {
00351
00352 INT level=prag_arg1;
00353
00354 remove = TRUE;
00355 if (Good_Do_Depth(wn)+1 < level) {
00356 ErrMsgSrcpos(EC_LNO_Bad_Pragma_String, WN_Get_Linenum(wn),
00357 WN_pragmas[pragma_id].name,
00358 "does not have enough enclosing loops");
00359 break;
00360 }
00361 WN* parent_loop=Enclosing_Do_Loop(wn);
00362
00363
00364
00365 BOOL fissionable=
00366 Find_Preceeding_Pragma(next_non_prag_stid,WN_PRAGMA_FISSIONABLE);
00367 FISSION_FUSION_STATUS fission_status=Failed;
00368
00369 if (fissionable) {
00370
00371 MEM_POOL_Push(&FF_PRAGMA_default_pool);
00372
00373 DYN_ARRAY<FF_STMT_LIST> loops(&FF_PRAGMA_default_pool);
00374 loops.Newidx();
00375 loops.Newidx();
00376 loops[0].Clear();
00377 loops[1].Clear();
00378
00379
00380 WN* stmt=WN_first(WN_do_body(parent_loop));
00381 while (stmt!=wn) {
00382 loops[0].Append(stmt,&FF_PRAGMA_default_pool);
00383 stmt=WN_next(stmt);
00384 }
00385 loops[0].Append(wn,&FF_PRAGMA_default_pool);
00386
00387
00388 stmt=WN_next(wn);
00389 while (stmt) {
00390 loops[1].Append(stmt,&FF_PRAGMA_default_pool);
00391 stmt=WN_next(stmt);
00392 }
00393
00394
00395 Separate_And_Update(parent_loop, loops, level);
00396 fission_status=Succeeded;
00397
00398 MEM_POOL_Pop(&FF_PRAGMA_default_pool);
00399
00400 } else if (WN_prev(wn)!=NULL) {
00401
00402 fission_status=Fission(parent_loop, WN_prev(wn), level);
00403 }
00404 dli=Get_Do_Loop_Info(parent_loop);
00405 dli->No_Fusion=TRUE;
00406 if (fission_status==Succeeded) {
00407 dli1=Get_Do_Loop_Info(WN_next(parent_loop));
00408 dli1->No_Fusion=TRUE;
00409 }
00410 }
00411 break;
00412
00413 case WN_PRAGMA_FISSIONABLE:
00414 remove = TRUE;
00415 break;
00416
00417 case WN_PRAGMA_FUSE:
00418
00419 {
00420 remove = TRUE;
00421 UINT number_of_loops=prag_arg1;
00422 UINT number_of_levels=prag_arg2;
00423
00424
00425
00426 BOOL fuseable=
00427 Find_Preceeding_Pragma(next_non_prag_stid,WN_PRAGMA_FUSEABLE);
00428
00429 WN* first_loop=next_non_prag_stid;
00430
00431 if (number_of_levels==0) {
00432 INT max_level=LNO_MAX_DO_LOOP_DEPTH;
00433 WN* loop=first_loop;
00434 for (INT i=0; i<number_of_loops; i++) {
00435 #ifdef KEY
00436 if (!loop)
00437 break;
00438 #endif
00439 if (WN_opcode(loop)!=OPC_DO_LOOP) {
00440 max_level=0;
00441 break;
00442 }
00443 INT level=1;
00444 WN* inner_loop=loop;
00445 while (inner_loop=Get_Only_Loop_Inside(inner_loop,FALSE))
00446 level++;
00447 if (level<max_level) max_level=level;
00448 loop=WN_next(loop);
00449 }
00450 number_of_levels=max_level;
00451 }
00452
00453
00454
00455
00456
00457 for (INT j=0; j<number_of_levels; j++) {
00458
00459 BOOL failed=FALSE;
00460
00461 FmtAssert(WN_opcode(first_loop)==OPC_DO_LOOP,
00462 ("FUSION pragma has to be followed by loops with sufficient nesting"));
00463
00464 WN* next_first_loop=Get_Only_Loop_Inside(first_loop,FALSE);
00465 WN* block=LWN_Get_Parent(first_loop);
00466 WN* stmt=WN_next(first_loop);
00467
00468 for (INT i=1; i<number_of_loops; i++) {
00469
00470 do {
00471 if (stmt &&
00472 (WN_opcode(stmt)==OPC_PRAGMA ||
00473 WN_opcode(stmt)==OPC_XPRAGMA)) {
00474
00475 LWN_Extract_From_Block(wn, block);
00476 LWN_Insert_Block_Before(wn, block, first_loop);
00477 } else
00478 break;
00479 stmt=WN_next(stmt);
00480 } while (1);
00481
00482 WN* next_stmt=WN_next(stmt);
00483
00484 FmtAssert(WN_opcode(stmt)==OPC_DO_LOOP,
00485 ("Not enough loops following a FUSION pragma"));
00486
00487 FISSION_FUSION_STATUS status;
00488 if (failed) {
00489
00490 } if (fuseable) {
00491
00492
00493
00494
00495 dli=Get_Do_Loop_Info(first_loop);
00496 dli1=Get_Do_Loop_Info(stmt);
00497
00498 FmtAssert(!dli->LB->Too_Messy,
00499 ("FUSIONABLE pragma requires lower bounds to be simple"));
00500
00501 FmtAssert(!dli->UB->Too_Messy,
00502 ("FUSIONABLE pragma requires upper bounds to be simple"));
00503
00504 FmtAssert(dli->LB==dli1->LB,
00505 ("FUSIONABLE pragma requires lower bounds to be the same"));
00506
00507 FmtAssert(dli->UB==dli1->UB,
00508 ("FUSIONABLE pragma requires upper bounds to be the same"));
00509
00510 FmtAssert(dli->Step==dli1->Step,
00511 ("FUSIONABLE pragma requires steps to be the same"));
00512
00513
00514
00515 UINT64 prolog=0;
00516 UINT64 epilog=0;
00517 WN* epilog_loop=NULL;
00518 mINT32 offset[1];
00519 offset[0]=0;
00520 status=Fuse(first_loop, stmt, 1, 0, TRUE,
00521 &prolog, &epilog, &epilog_loop, offset);
00522 if (status!=Succeeded &&
00523 status!=Succeeded_and_Inner_Loop_Removed)
00524 failed=TRUE;
00525
00526 } else {
00527 status=Fuse(first_loop, stmt, 1, LNO_Fusion_Peeling_Limit, TRUE);
00528 if (status!=Succeeded &&
00529 status!=Succeeded_and_Inner_Loop_Removed)
00530 failed=TRUE;
00531 }
00532 stmt=next_stmt;
00533 }
00534
00535
00536
00537
00538
00539 ((DO_LOOP_INFO*)Get_Do_Loop_Info(first_loop))->No_Fission=TRUE;
00540 first_loop=next_first_loop;
00541
00542 }
00543
00544 }
00545 break;
00546
00547 case WN_PRAGMA_FUSEABLE:
00548 remove = TRUE;
00549 break;
00550
00551 case WN_PRAGMA_NO_FISSION:
00552 remove = TRUE;
00553 if (next_non_prag_stid == NULL ||
00554 WN_opcode(next_non_prag_stid) != OPC_DO_LOOP) {
00555 if (!FF_Pragma_Seen_Before(wn))
00556 ErrMsgSrcpos(EC_LNO_Bad_Pragma_String, WN_Get_Linenum(wn),
00557 WN_pragmas[pragma_id].name,
00558 "not followed by a loop, ignored");
00559 break;
00560 }
00561 dli=Get_Do_Loop_Info(next_non_prag_stid);
00562 dli->No_Fission=TRUE;
00563 break;
00564
00565 case WN_PRAGMA_NO_FUSION:
00566 remove = TRUE;
00567 if (next_non_prag_stid == NULL ||
00568 WN_opcode(next_non_prag_stid) != OPC_DO_LOOP) {
00569 if (!FF_Pragma_Seen_Before(wn))
00570 ErrMsgSrcpos(EC_LNO_Bad_Pragma_String, WN_Get_Linenum(wn),
00571 WN_pragmas[pragma_id].name,
00572 "not followed by a loop, ignored");
00573 break;
00574 }
00575 dli=Get_Do_Loop_Info(next_non_prag_stid);
00576 dli->No_Fusion=TRUE;
00577 break;
00578
00579 case WN_PRAGMA_NEXT_SCALAR:
00580 remove = TRUE;
00581 if (next_non_prag_stid == NULL ||
00582 WN_opcode(next_non_prag_stid) != OPC_DO_LOOP) {
00583 if (!FF_Pragma_Seen_Before(wn))
00584 ErrMsgSrcpos(EC_LNO_Bad_Pragma_String, WN_Get_Linenum(wn),
00585 WN_pragmas[pragma_id].name,
00586 "not followed by a loop, ignored");
00587 break;
00588 }
00589 dli = Get_Do_Loop_Info(next_non_prag_stid);
00590 dli->Pragma_Cannot_Concurrentize = TRUE;
00591 break;
00592
00593 case WN_PRAGMA_KAP_ASSERT_DO:
00594 if (next_non_prag_stid == NULL ||
00595 WN_opcode(next_non_prag_stid) != OPC_DO_LOOP) {
00596 if (!FF_Pragma_Seen_Before(wn))
00597 ErrMsgSrcpos(EC_LNO_Bad_Pragma_String, WN_Get_Linenum(wn),
00598 WN_pragmas[pragma_id].name,
00599 "not followed by a loop, ignored");
00600 break;
00601 }
00602 if (WN_pragma_arg1(wn) == ASSERT_DO_CONCURRENT) {
00603 remove = TRUE;
00604 dli = Get_Do_Loop_Info(next_non_prag_stid);
00605 dli->Pragma_Prefer_Concurrentize = TRUE;
00606 } else if (WN_pragma_arg1(wn) == ASSERT_DO_SERIAL) {
00607 remove = TRUE;
00608 dli = Get_Do_Loop_Info(next_non_prag_stid);
00609 dli->Pragma_Cannot_Concurrentize = TRUE;
00610 }
00611 break;
00612
00613 case WN_PRAGMA_KAP_ASSERT_DOPREFER:
00614 if (next_non_prag_stid == NULL ||
00615 WN_opcode(next_non_prag_stid) != OPC_DO_LOOP) {
00616 if (!FF_Pragma_Seen_Before(wn))
00617 ErrMsgSrcpos(EC_LNO_Bad_Pragma_String, WN_Get_Linenum(wn),
00618 WN_pragmas[pragma_id].name,
00619 "not followed by a loop, ignored");
00620 break;
00621 }
00622 if (WN_pragma_arg1(wn) == ASSERT_DO_CONCURRENT) {
00623 remove = TRUE;
00624 dli = Get_Do_Loop_Info(next_non_prag_stid);
00625 dli->Pragma_Prefer_Concurrentize = TRUE;
00626 } else if (WN_pragma_arg1(wn) == ASSERT_DO_SERIAL) {
00627 remove = TRUE;
00628 dli = Get_Do_Loop_Info(next_non_prag_stid);
00629 dli->Pragma_Cannot_Concurrentize = TRUE;
00630 }
00631 break;
00632
00633 }
00634
00635 if (remove) {
00636 LWN_Delete_From_Block(LWN_Get_Parent(wn), wn);
00637 }
00638
00639 return;
00640 }
00641
00642 WN* kid;
00643 WN* nkid = NULL;
00644
00645 if (opc==OPC_BLOCK) {
00646 for (kid=WN_first(wn); kid; ) {
00647 WN* this_kid = kid;
00648 kid = WN_next(kid);
00649 LWN_Process_FF_Pragmas_Walk_r(this_kid);
00650 }
00651 return;
00652 }
00653
00654 for (UINT kidno=0; kidno<WN_kid_count(wn); kidno++) {
00655 kid=WN_kid(wn,kidno);
00656 if (!OPCODE_is_expression(WN_opcode(kid)))
00657 LWN_Process_FF_Pragmas_Walk_r(kid);
00658 }
00659 }
00660
00661
00662 extern void LWN_Process_FF_Pragmas(WN* func_nd) {
00663
00664 MEM_POOL_Initialize(&FF_PRAGMA_default_pool,"FF_PRAGMA_default_pool",FALSE);
00665
00666 LWN_Process_FF_Pragmas_Walk_r(func_nd);
00667
00668 MEM_POOL_Delete(&FF_PRAGMA_default_pool);
00669 }
00670
00671
00672 extern void LNO_Insert_Pragmas(WN* wn)
00673 {
00674 OPCODE opc = WN_opcode(wn);
00675
00676 if (opc == OPC_DO_LOOP) {
00677 DO_LOOP_INFO* dli = Get_Do_Loop_Info(wn);
00678 if (dli->Is_Inner) {
00679 if (dli->Required_Unroll > 0) {
00680 WN* pragma = WN_CreatePragma(WN_PRAGMA_UNROLL, (ST_IDX) NULL,
00681 dli->Required_Unroll, 0);
00682 WN_set_pragma_compiler_generated(pragma);
00683 LWN_Insert_Block_Before(LWN_Get_Parent(wn), wn, pragma);
00684 }
00685 return;
00686 }
00687 }
00688
00689 if (opc==OPC_BLOCK) {
00690 for (WN* kid = WN_first(wn); kid; kid = WN_next(kid)) {
00691 LNO_Insert_Pragmas(kid);
00692 }
00693 return;
00694 }
00695
00696 for (UINT kidno = 0; kidno < WN_kid_count(wn); kidno++) {
00697 WN* kid=WN_kid(wn,kidno);
00698 if (!OPCODE_is_expression(WN_opcode(kid)))
00699 LNO_Insert_Pragmas(kid);
00700 }
00701 }