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 #ifdef USE_PCH
00037 #include "lno_pch.h"
00038 #endif // USE_PCH
00039 #pragma hdrstop
00040
00041 #include "pf_manual.h"
00042 #include "wn_map.h"
00043 #include "lwn_util.h"
00044 #include "pf_cg.h"
00045
00046 extern WN_MAP LNO_Info_Map;
00047
00048 MANUAL_PREFETCH_SYMBOLS* mpf_syms = NULL;
00049
00050
00051
00052
00053
00054
00055
00056 static void Map_Memop_To_Prefetch (WN* ref_wn, WN* pf_wn) {
00057 VB_PRINT (printf ("Found a match, setting map\n");
00058 printf ("Ref : "); dump_tree (ref_wn); printf ("\n");
00059 printf ("Pref: "); dump_tree (pf_wn); printf ("\n"));
00060 PF_POINTER* tmp = (PF_POINTER*) WN_MAP_Get (WN_MAP_PREFETCH, ref_wn);
00061 if (tmp == NULL) {
00062 extern MEM_POOL PF_CG_mpool;
00063 tmp = CXX_NEW (PF_POINTER, &PF_CG_mpool);
00064 PF_PTR_wn_pref_1L(tmp) = NULL;
00065 PF_PTR_lrnum_1L(tmp) = 0;
00066 PF_PTR_distance_1L(tmp) = 0;
00067 PF_PTR_wn_pref_2L(tmp) = NULL;
00068 PF_PTR_lrnum_2L(tmp) = 0;
00069 PF_PTR_distance_2L(tmp) = 0;
00070 PF_PTR_flag(tmp) = 0;
00071 WN_MAP_Set (WN_MAP_PREFETCH, ref_wn, tmp);
00072 if (WN_pf_stride_1L(pf_wn)) {
00073 PF_PTR_wn_pref_1L(tmp) = pf_wn;
00074 PF_PTR_distance_1L(tmp) = WN_offset(pf_wn);
00075 PF_PTR_set_conf_1L(tmp, WN_pf_confidence(pf_wn));
00076 }
00077 if (WN_pf_stride_2L(pf_wn)) {
00078 PF_PTR_wn_pref_2L(tmp) = pf_wn;
00079 PF_PTR_distance_2L(tmp) = WN_offset(pf_wn);
00080 PF_PTR_set_conf_2L(tmp, WN_pf_confidence(pf_wn));
00081 }
00082 }
00083 else {
00084
00085
00086
00087 if (WN_pf_stride_1L(pf_wn) && (PF_PTR_wn_pref_1L(tmp) == NULL)) {
00088 PF_PTR_wn_pref_1L(tmp) = pf_wn;
00089 PF_PTR_distance_1L(tmp) = WN_offset(pf_wn);
00090 PF_PTR_set_conf_1L(tmp, WN_pf_confidence(pf_wn));
00091 }
00092 if (WN_pf_stride_2L(pf_wn) && (PF_PTR_wn_pref_2L(tmp) == NULL)) {
00093 PF_PTR_wn_pref_2L(tmp) = pf_wn;
00094 PF_PTR_distance_2L(tmp) = WN_offset(pf_wn);
00095 PF_PTR_set_conf_2L(tmp, WN_pf_confidence(pf_wn));
00096 }
00097 DevWarn ("Preexisting prefetch map: duplicate prefetch?");
00098 }
00099 }
00100
00101
00102
00103
00104
00105
00106
00107
00108 void SINGLE_ARRAY_REF_PREF::Match_Refs_Prefs () {
00109 INT i, j;
00110 for (i=0; i<_pref_da.Elements(); i++) {
00111 WN* pf_wn = _pref_da[i];
00112 WN* pragma_wn = _pragma_da[i];
00113
00114 WN* addr_wn = WN_kid0(pf_wn);
00115 OPERATOR opr = WN_operator(addr_wn);
00116 switch (opr) {
00117 case OPR_LDA:
00118
00119 for (j=0; j<_ref_da.Elements(); j++) {
00120 WN* ref_wn = _ref_da[j];
00121 OPERATOR ref_opr = WN_operator(ref_wn);
00122 if ((ref_opr != OPR_LDID) && (ref_opr != OPR_STID)) continue;
00123 if ((WN_st(addr_wn) != WN_st(ref_wn)) ||
00124 (WN_offset(addr_wn) != WN_offset(ref_wn))) continue;
00125
00126 Map_Memop_To_Prefetch (ref_wn, pf_wn);
00127 break;
00128 }
00129 if (j == _ref_da.Elements()) {
00130
00131 DevWarn("Could not match manual prefetch to ref, issuing prefetch anyway\n");
00132
00133 }
00134 break;
00135 case OPR_ARRAY:
00136
00137
00138 for (j=0; j<_ref_da.Elements(); j++) {
00139 WN* ref_wn = _ref_da[j];
00140 OPERATOR ref_opr = WN_operator(ref_wn);
00141 if ((ref_opr != OPR_ILOAD) && (ref_opr != OPR_ISTORE)) continue;
00142 WN* ref_addr_wn;
00143 ref_addr_wn = ((ref_opr == OPR_ILOAD) ?
00144 WN_kid0(ref_wn) :
00145 WN_kid1(ref_wn));
00146 if (WN_operator(ref_addr_wn) != OPR_ARRAY) continue;
00147 if (!Tree_Equiv (addr_wn, ref_addr_wn)) continue;
00148
00149 Map_Memop_To_Prefetch (ref_wn, pf_wn);
00150 break;
00151 }
00152 if (j == _ref_da.Elements()) {
00153
00154 DevWarn("Could not match manual prefetch to ref, issuing prefetch anyway\n");
00155
00156 }
00157 break;
00158 default:
00159
00160 for (j=0; j<_ref_da.Elements(); j++) {
00161 WN* ref_wn = _ref_da[j];
00162 OPERATOR ref_opr = WN_operator(ref_wn);
00163 if ((ref_opr != OPR_ILOAD) && (ref_opr != OPR_ISTORE)) continue;
00164 WN* ref_addr_wn;
00165 ref_addr_wn = ((ref_opr == OPR_ILOAD) ?
00166 WN_kid0(ref_wn) :
00167 WN_kid1(ref_wn));
00168 if (!Tree_Equiv (addr_wn, ref_addr_wn)) continue;
00169
00170 Map_Memop_To_Prefetch (ref_wn, pf_wn);
00171 break;
00172 }
00173 if (j == _ref_da.Elements()) {
00174
00175 DevWarn("Could not match manual prefetch to ref, issuing prefetch anyway\n");
00176
00177 }
00178 break;
00179 }
00180 }
00181 }
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192 void SINGLE_LOOP::Insert_Pref (WN* pragma_wn, WN* pf_wn) {
00193
00194 VB_PRINT(printf ("Insert_Pref: Manual prefetch in loop 0x%p: \n", this);
00195 dump_tree (pf_wn));
00196
00197
00198 WN_pf_unset_manual(pf_wn);
00199 WN_pf_set_confidence(pf_wn, 3);
00200
00201
00202 SYMBOL *sym = NULL;
00203 WN* addr_wn = WN_kid0(pf_wn);
00204 OPERATOR opr = WN_operator(addr_wn);
00205 switch (opr) {
00206 case OPR_LDA:
00207
00208 sym = CXX_NEW (SYMBOL(addr_wn), PF_mpool);
00209 break;
00210 case OPR_ARRAY:
00211 {
00212
00213 WN* array_base = WN_array_base(addr_wn);
00214 OPERATOR op = WN_operator(array_base);
00215
00216 if ((op == OPR_LDID) || (op == OPR_LDA)) {
00217 sym = CXX_NEW (SYMBOL(array_base), PF_mpool);
00218 }
00219 break;
00220 }
00221 default:
00222
00223 break;
00224 }
00225
00226 if (sym) {
00227 VB_PRINT(printf (" Insert_Pref into bucket for sym ");
00228 sym->Print(stdout); printf ("\n"));
00229
00230 INT i;
00231 for (i=1; i<_sarp_list.Elements(); i++) {
00232 if (_sarp_list[i]->Same_Base_Symbol(sym)) {
00233 _sarp_list[i]->Insert_Pref (pragma_wn, pf_wn);
00234 mpf_syms->Enter (sym, (pragma_wn ? WN_pragma_arg2(pragma_wn) : 0));
00235 break;
00236 }
00237 }
00238 if (i == _sarp_list.Elements()) {
00239
00240 SINGLE_ARRAY_REF_PREF* sarp =
00241 CXX_NEW (SINGLE_ARRAY_REF_PREF(sym),PF_mpool);
00242 sarp->Insert_Pref (pragma_wn, pf_wn);
00243 _sarp_list[_sarp_list.Newidx()] = sarp;
00244 mpf_syms->Enter (sym, (pragma_wn ? WN_pragma_arg2(pragma_wn) : 0));
00245 }
00246 CXX_DELETE (sym, PF_mpool);
00247 }
00248 else {
00249 VB_PRINT(printf (" Insert_Pref into bucket 0\n"));
00250
00251 _sarp_list[0]->Insert_Pref (pragma_wn, pf_wn);
00252 }
00253 }
00254
00255
00256
00257
00258
00259
00260
00261 void SINGLE_LOOP::Insert_Ref (WN* ref_wn) {
00262
00263 VB_PRINT(printf ("Insert_Ref: Reference in loop 0x%p: \n", this);
00264 dump_tree (ref_wn));
00265
00266
00267 SYMBOL *sym = NULL;
00268 OPERATOR opr = WN_operator(ref_wn);
00269 switch (opr) {
00270 case OPR_LDID:
00271 case OPR_STID:
00272 sym = CXX_NEW (SYMBOL(ref_wn), PF_mpool);
00273 break;
00274 case OPR_ILOAD:
00275 if (WN_operator(WN_kid0(ref_wn)) == OPR_ARRAY) {
00276 WN* array_base = WN_array_base(WN_kid0(ref_wn));
00277 OPERATOR op = WN_operator(array_base);
00278
00279 if ((op == OPR_LDID) || (op == OPR_LDA)) {
00280 sym = CXX_NEW (SYMBOL(array_base), PF_mpool);
00281 }
00282 }
00283
00284 break;
00285 case OPR_ISTORE:
00286 if (WN_operator(WN_kid1(ref_wn)) == OPR_ARRAY) {
00287 WN* array_base = WN_array_base(WN_kid1(ref_wn));
00288 OPERATOR op = WN_operator(array_base);
00289
00290 if ((op == OPR_LDID) || (op == OPR_LDA)) {
00291 sym = CXX_NEW (SYMBOL(array_base), PF_mpool);
00292 }
00293 }
00294
00295 break;
00296 default:
00297 Is_True (FALSE, ("Invalid memory op"));
00298 return;
00299 }
00300
00301 if (sym) {
00302 VB_PRINT(printf (" Insert_Ref into bucket for sym ");
00303 sym->Print(stdout); printf ("\n"));
00304
00305 INT i;
00306 for (i=1; i<_sarp_list.Elements(); i++) {
00307 if (_sarp_list[i]->Same_Base_Symbol(sym)) {
00308 _sarp_list[i]->Insert_Ref (ref_wn);
00309 break;
00310 }
00311 }
00312 if (i == _sarp_list.Elements()) {
00313
00314 SINGLE_ARRAY_REF_PREF* sarp =
00315 CXX_NEW (SINGLE_ARRAY_REF_PREF(sym),PF_mpool);
00316 sarp->Insert_Ref (ref_wn);
00317 _sarp_list[_sarp_list.Newidx()] = sarp;
00318 }
00319 CXX_DELETE (sym, PF_mpool);
00320 }
00321 else {
00322 VB_PRINT(printf (" Insert_Ref into bucket 0\n"));
00323
00324 _sarp_list[0]->Insert_Ref (ref_wn);
00325 }
00326 }
00327
00328
00329
00330
00331
00332
00333
00334 void SINGLE_LOOP::Collect_Refs_Prefs (WN* wn) {
00335 OPERATOR opr = WN_operator(wn);
00336 switch (opr) {
00337 case OPR_DO_LOOP:
00338 {
00339 SINGLE_LOOP loop (PF_mpool);
00340 loop.Process_Loop_Manual (WN_do_body(wn));
00341 break;
00342 }
00343 case OPR_WHILE_DO:
00344 case OPR_DO_WHILE:
00345 {
00346 SINGLE_LOOP loop (PF_mpool);
00347 loop.Process_Loop_Manual (WN_while_body(wn));
00348 break;
00349 }
00350 case OPR_BLOCK:
00351 {
00352 WN* kid = WN_first (wn);
00353 while (kid) {
00354 Collect_Refs_Prefs (kid);
00355
00356
00357
00358 if ((WN_operator(kid) == OPR_PRAGMA) &&
00359 (WN_pragma(kid) == WN_PRAGMA_PREFETCH_REF)) {
00360 WN* pf_wn = WN_next(kid);
00361 FmtAssert(pf_wn && (WN_opcode(pf_wn) == OPC_PREFETCH),
00362 ("FE Error: pragma prefetch_ref not followed by prefetch\n"));
00363 kid = WN_next(kid);
00364 }
00365 kid = WN_next(kid);
00366 }
00367 break;
00368 }
00369 case OPR_PRAGMA:
00370 {
00371 switch (WN_pragma(wn)) {
00372 case WN_PRAGMA_PREFETCH:
00373 case WN_PRAGMA_PREFETCH_MANUAL:
00374 case WN_PRAGMA_PREFETCH_REF_DISABLE:
00375 Is_True (FALSE,
00376 ("Error: Prefetch(-Manual/Disable) pragma in middle of PU"));
00377 break;
00378 case WN_PRAGMA_PREFETCH_REF:
00379 {
00380 WN* pf_wn = WN_next(wn);
00381 FmtAssert (pf_wn && (WN_opcode(pf_wn) == OPC_PREFETCH),
00382 ("FE Error: pragma prefetch_ref not followed by prefetch\n"));
00383 Insert_Pref (wn, pf_wn);
00384 break;
00385 }
00386 default:
00387 break;
00388 }
00389 break;
00390 }
00391 case OPR_PREFETCH:
00392 {
00393
00394
00395
00396 if (WN_prev(wn)) {
00397 OPERATOR opr = WN_operator (WN_prev(wn));
00398 Is_True ((opr != OPR_PRAGMA) ||
00399 (WN_pragma(WN_prev(wn)) != WN_PRAGMA_PREFETCH_REF),
00400 ("FE error: prefetch not processed by prefetch_ref pragma"));
00401 }
00402 VB_PRINT(printf ("Manual prefetch in loop 0x%p: \n", this);
00403 dump_tree (wn));
00404 Insert_Pref (NULL, wn);
00405 break;
00406 }
00407 case OPR_LDID:
00408 case OPR_STID:
00409 case OPR_ILOAD:
00410 case OPR_ISTORE:
00411 {
00412 Insert_Ref (wn);
00413
00414 for (INT kidno=0; kidno<WN_kid_count(wn); kidno++)
00415 Collect_Refs_Prefs (WN_kid(wn, kidno));
00416 break;
00417 }
00418 default:
00419 {
00420 for (INT kidno=0; kidno<WN_kid_count(wn); kidno++)
00421 Collect_Refs_Prefs (WN_kid(wn, kidno));
00422 break;
00423 }
00424 }
00425 }
00426
00427
00428
00429
00430
00431
00432 void MANUAL_PREFETCH_SYMBOLS::Enter (SYMBOL* sym, INT64 vol) {
00433 VB_PRINT (printf ("mpf_syms.Enter'ing symbol: ");
00434 sym->Print(stdout);
00435 printf (", vol = %lld\n", vol));
00436 for (INT i=0; i<_sym_da.Elements(); i++) {
00437 if (*sym == *(_sym_da[i])) {
00438
00439 return;
00440 }
00441 }
00442
00443 SYMBOL* lsym = CXX_NEW (SYMBOL(*sym), PF_mpool);
00444 _sym_da[_sym_da.Newidx()] = lsym;
00445 _vol_da[_vol_da.Newidx()] = vol;
00446 }