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 #define __STDC_LIMIT_MACROS
00043 #include <stdint.h>
00044 #ifdef USE_PCH
00045 #include "lno_pch.h"
00046 #endif // USE_PCH
00047 #pragma hdrstop
00048
00049 #include <sys/types.h>
00050 #include <ctype.h>
00051 #include <limits.h>
00052 #include <alloca.h>
00053 #include "pu_info.h"
00054 #include "ara.h"
00055 #include "opt_du.h"
00056 #include "lnoutils.h"
00057 #include "lwn_util.h"
00058 #include "config.h"
00059 #include "config_lno.h"
00060 #include "anl_driver.h"
00061 #include "prompf.h"
00062 #include "glob.h"
00063 #include "fiz_fuse.h"
00064 #include "lego_util.h"
00065 #include "parids.h"
00066 #include "cond.h"
00067
00068 #if ! defined(BUILD_OS_DARWIN)
00069 #pragma weak Anl_File_Path
00070 #endif
00071
00072 MEM_POOL ARA_memory_pool;
00073 static BOOL ara_mem_pool_initialized=FALSE;
00074
00075
00076
00077
00078
00079
00080
00081
00082 void
00083 Set_Invariant_Symbols(ARA_LOOP_INFO *loop_info, WN* wn)
00084 {
00085 Is_True(loop_info, ("No loop is given in Set_Invariant_Symbols\n"));
00086
00087 if (WN_operator(wn) == OPR_ARRAY) {
00088 for (INT32 i = 0; i < WN_num_dim(wn); ++i) {
00089 Set_Invariant_Symbols(loop_info, WN_array_index(wn,i));
00090 }
00091 return;
00092 }
00093
00094 if (WN_operator(wn)==OPR_LDID) {
00095 DEF_LIST *defs = Du_Mgr->Ud_Get_Def(wn);
00096 if (!defs || defs->Incomplete())
00097 return;
00098
00099 if (!loop_info->Processed(wn)) {
00100 loop_info->Add_Processed(wn);
00101
00102
00103 INT depth = -1;
00104 WN* deepest_loop = NULL;
00105 DEF_LIST_ITER iter(defs);
00106 WN* cur_loop = (WN *) loop_info->Loop();
00107 for (DU_NODE* node=iter.First(); !iter.Is_Empty(); node=iter.Next()){
00108 WN* def = node->Wn();
00109 WN* common_loop = LNO_Common_Loop(def, cur_loop);
00110 INT depth_new = Do_Depth(common_loop);
00111
00112 if (Do_Depth(common_loop)>depth) {
00113 depth = depth_new;
00114 deepest_loop = common_loop;
00115 }
00116 }
00117
00118
00119 ARA_LOOP_INFO* cur_info = loop_info;
00120 while (cur_info && cur_info->Loop()!=deepest_loop) {
00121 cur_info->Add_Invariant(wn);
00122 cur_info = cur_info->Parent();
00123 }
00124 }
00125
00126 } else
00127 for (INT kidno=0; kidno<WN_kid_count(wn); ++kidno)
00128 Set_Invariant_Symbols(loop_info,WN_kid(wn,kidno));
00129
00130 }
00131
00132
00133
00134 extern void ARA_Initialize_Loops(WN* wn,
00135 ARA_LOOP_INFO *parent_info)
00136 {
00137
00138 #if 0
00139 fprintf(stdout, "Visiting %s ", OPERATOR_name(WN_operator(wn)));
00140 Dump_WN(wn, stdout, 3, 0, 3, NULL, NULL, LWN_Get_Parent(wn));
00141 #endif
00142
00143 if (WN_operator(wn) == OPR_ILOAD) {
00144 if (WN_operator(WN_kid0(wn)) == OPR_ARRAY) {
00145
00146 Set_Invariant_Symbols(parent_info,WN_kid0(wn));
00147
00148 }
00149
00150 return;
00151
00152 } else if (WN_operator(wn) == OPR_ISTORE) {
00153 if (WN_operator(WN_kid0(wn)) == OPR_ARRAY) {
00154
00155 Set_Invariant_Symbols(parent_info,WN_kid1(wn));
00156
00157 }
00158
00159 return;
00160
00161 }
00162
00163 if (WN_opcode(wn) == OPC_DO_LOOP){
00164 DO_LOOP_INFO *dli = Get_Do_Loop_Info(wn);
00165 ARA_LOOP_INFO *cur_loop_info =
00166 CXX_NEW(ARA_LOOP_INFO(wn,
00167 parent_info,
00168 parent_info->Invariant_Bounds()),
00169 &ARA_memory_pool);
00170 dli->ARA_Info = cur_loop_info;
00171 parent_info->Add_Child(cur_loop_info);
00172
00173
00174 for (INT kidno=1; kidno<=3; ++kidno){
00175 Set_Invariant_Symbols(cur_loop_info, WN_kid(wn,kidno));
00176 }
00177
00178
00179 ARA_Initialize_Loops(WN_do_body(wn),cur_loop_info);
00180
00181 return;
00182
00183 }
00184
00185 if (WN_opcode(wn)==OPC_BLOCK){
00186 for (WN* kid = WN_first(wn); kid != NULL; kid = WN_next(kid))
00187 ARA_Initialize_Loops(kid,parent_info);
00188 return;
00189 }
00190
00191 for (INT kidno=0; kidno<WN_kid_count(wn); ++kidno) {
00192 WN* kid = WN_kid(wn,kidno);
00193 ARA_Initialize_Loops(kid,parent_info);
00194 }
00195
00196 }
00197
00198
00199
00200
00201
00202 static void ARA_Print_Loops(ARA_LOOP_INFO *root_info)
00203 {
00204 ARA_LOOP_INFO_ST & inner_loops = root_info->Children();
00205 WN* func_nd = (WN*) root_info->Loop();
00206
00207 if (Get_Trace(TP_LNOPT2,TT_LNO_ARA_VERBOSE) ||
00208 Get_Trace(TP_LNOPT2,TT_LNO_ARA_DEBUG))
00209 for (INT i = 0; i < inner_loops.Elements(); ++i) {
00210 inner_loops.Bottom_nth(i)->Print_Loop_Property();
00211 }
00212
00213 if (LNO_Analysis) {
00214 for (INT i = 0; i < inner_loops.Elements(); ++i) {
00215 inner_loops.Bottom_nth(i)->Print_Analysis_Info();
00216 }
00217 }
00218 }
00219
00220
00221
00222
00223 void Perform_ARA_and_Parallelization(PU_Info* current_pu,
00224 WN* func_nd)
00225 {
00226
00227 ARA_LOOP_INFO *root =
00228 CXX_NEW(ARA_LOOP_INFO(func_nd, NULL, TRUE), &ARA_memory_pool);
00229
00230 ARA_Initialize_Loops(func_nd, root);
00231
00232
00233 ARA_Walk_Loops(root);
00234
00235
00236 root->Create_Live_Use();
00237
00238
00239 root->Determine_Last_Value();
00240
00241
00242 Walk_Loop_Dependence(func_nd);
00243
00244
00245 root->Determine_Peel();
00246
00247
00248 ARA_Print_Loops(root);
00249
00250 for (INT i = 0; i < root->Children().Elements(); ++i)
00251 root->Children().Bottom_nth(i)->Generate_Parallel_Pragma();
00252
00253 if (Eliminate_Dead_SCF(func_nd, LWN_Delete_Tree))
00254 Mark_Code(func_nd, FALSE, FALSE);
00255
00256
00257 Annotate_For_Mp_Lowering(current_pu, func_nd);
00258
00259 if (Run_prompf) {
00260 Print_Prompf_Transaction_Log(FALSE);
00261 Print_Prompf_Parallelization_Log(func_nd);
00262 Print_Prompf_Doacross_Log(current_pu, func_nd, FALSE);
00263 Print_Prompf_Parallel_Region_Log(current_pu, func_nd, FALSE);
00264 Print_Prompf_Nest_Log(func_nd, FALSE);
00265 }
00266
00267 if (LNO_Prompl)
00268 Print_Prompl_Msgs(current_pu, func_nd);
00269
00270 ARA_Cleanup(func_nd);
00271 }
00272
00273
00274
00275
00276
00277 void ARA_Walk_Loops(ARA_LOOP_INFO *root_info)
00278 {
00279
00280 #if 0
00281 ARA_LOOP_INFO_ST & inner_loops = root_info->Children();
00282
00283
00284 for (INT i = 0; i < inner_loops.Elements(); ++i) {
00285 inner_loops.Bottom_nth(i)->Walk_Loop();
00286 }
00287 #endif
00288
00289 root_info->Default_For_Bad_Loop();
00290
00291 }
00292
00293 static void ARA_Cleanup_Traverse(WN* wn_tree)
00294 {
00295 if (WN_opcode(wn_tree) == OPC_DO_LOOP) {
00296 DO_LOOP_INFO* dli = Get_Do_Loop_Info(wn_tree);
00297 CXX_DELETE(dli->ARA_Info, &ARA_memory_pool);
00298 dli->ARA_Info = NULL;
00299 }
00300
00301 if (WN_opcode(wn_tree) == OPC_BLOCK) {
00302 for (WN* wn = WN_first(wn_tree); wn != NULL; wn = WN_next(wn))
00303 ARA_Cleanup_Traverse(wn);
00304 } else {
00305 for (INT i = 0; i < WN_kid_count(wn_tree); i++)
00306 ARA_Cleanup_Traverse(WN_kid(wn_tree, i));
00307 }
00308 }
00309
00310
00311 extern void ARA_Cleanup(WN* func_nd)
00312 {
00313 ARA_Cleanup_Traverse(func_nd);
00314 }
00315
00316