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 #define rail_CXX "rail.cxx"
00057 #ifdef _KEEP_RCS_ID
00058 static char *rcs_id = rail_CXX"$Revision: 1.2 $";
00059 #endif
00060
00061 #include "wn.h"
00062 #include "wn_util.h"
00063 #include "rail.h"
00064 #include "ir_reader.h"
00065 #include "region_util.h"
00066 #include "tracing.h"
00067
00068 RAIL::RAIL(void)
00069 {
00070 _trace_flag = Get_Trace(TP_REGION,TT_REGION_RAIL_DEBUG,);
00071 }
00072
00073
00074 #define BLOCK_STACK_SIZE 20
00075
00076 void
00077 RAIL::Process_func_entry(WN *wn)
00078 {
00079
00080 Set_fe(wn);
00081 do {
00082 FmtAssert(WN_opcode(Get_fe()) == OPC_FUNC_ENTRY,
00083 ("RAIL::Process_func_entry, could not find function entry"));
00084 if (Trace())
00085 fprintf(TFile,"===== RAIL::Process_func_entry: %s\n",
00086 ST_name(WN_st(Get_fe())));
00087 Process_block(WN_func_body(Get_fe()),1);
00088 RID *rid = REGION_get_rid(Get_fe());
00089 RID_level(rid) = RL_RAIL;
00090 RID_bounds_exist(rid) = REGION_BOUND_UNKNOWN;
00091 RID_has_return(rid) = REGION_NO_RETURN;
00092 Next_fe();
00093 } while (Get_fe());
00094 }
00095
00096
00097 BOOL
00098 RAIL::Process_block(WN *wn_block, INT32 nest_level)
00099 {
00100 WN *wn_after_loop = NULL;
00101 BOOL found_loop = FALSE;
00102
00103 FmtAssert(WN_opcode(wn_block) == OPC_BLOCK,
00104 ("RAIL::Process_block, could not find block"));
00105
00106
00107 for (WN *wtmp=WN_first(wn_block); wtmp!=NULL; wtmp=WN_next(wtmp)) {
00108 const OPCODE opc = WN_opcode(wtmp);
00109 const OPERATOR opr = OPCODE_operator(opc);
00110
00111
00112 if (opr == OPR_DO_LOOP || opr == OPR_WHILE_DO || opr == OPR_DO_WHILE) {
00113 found_loop = TRUE;
00114 if (WN_next(wtmp))
00115 wn_after_loop = WN_next(wtmp);
00116
00117
00118 WN *wn_body = (opr == OPR_DO_LOOP) ? WN_do_body(wtmp) :
00119 WN_while_body(wtmp);
00120 if (!Process_block(wn_body,nest_level+1)) {
00121 if (Trace())
00122 fprintf(TFile,
00123 "===== RAIL::Process_block, %s begin, level %d, inner loop\n",
00124 OPCODE_name(opc),nest_level);
00125
00126 wtmp = WN_EXTRACT_FromBlock(wn_block,wtmp);
00127
00128 WN *wnew = Add_region_around_loop(wtmp,nest_level);
00129
00130 wn_after_loop = REGION_add_exit(wn_block,wn_after_loop,wnew);
00131
00132 WN_INSERT_BlockBefore(wn_block,wn_after_loop,wnew);
00133
00134 wtmp = wnew;
00135 } else {
00136 if (Trace())
00137 fprintf(TFile,"===== RAIL::Process_block, %s begin, level %d\n",
00138 OPCODE_name(opc),nest_level);
00139 }
00140 }
00141
00142
00143 switch (opc) {
00144 case OPC_BLOCK:
00145 found_loop |= Process_block(wtmp,nest_level);
00146 break;
00147 case OPC_REGION:
00148 found_loop |= Process_block(WN_region_body(wtmp),nest_level);
00149 break;
00150 case OPC_IF:
00151 found_loop |= Process_block(WN_then(wtmp),nest_level);
00152 found_loop |= Process_block(WN_else(wtmp),nest_level);
00153 break;
00154 default:
00155 break;
00156 }
00157
00158 }
00159
00160 return found_loop;
00161 }
00162
00163
00164 WN *
00165 RAIL::Add_region_around_loop(WN *wn_loop, INT32 nest_level)
00166 {
00167
00168 WN *wnew = WN_CreateRegion(REGION_KIND_PRAGMA, wn_loop,NULL,NULL,
00169 RID_CREATE_NEW_ID,NULL);
00170
00171
00172 RID *rid = RID_Create(WN_region_id(wnew), nest_level, wnew);
00173 RID_level(rid) = RL_RAIL;
00174 RID_bounds_exist(rid) = REGION_BOUND_UNKNOWN;
00175 RID_has_return(rid) = REGION_NO_RETURN;
00176 RID_num_exits(rid) = 1;
00177 RID_TYPE_loop_Set(rid);
00178 WN_MAP_Set(RID_map,wnew,(void *)rid);
00179 if (Trace())
00180 fprintf(TFile,"===== RAIL::Add_regions_around_loop, New RID: %d\n",
00181 RID_id(rid));
00182
00183
00184 RID *root_rid = REGION_get_rid(Get_fe());
00185 FmtAssert(root_rid != NULL,
00186 ("RAIL::Add_region_around_loop, can't find root RID"));
00187 RID_Add_kid(rid,root_rid);
00188
00189 return wnew;
00190 }
00191
00192 extern "C"
00193 void
00194 Rail(WN *itree)
00195 {
00196 RAIL rtmp;
00197
00198 if (!PU_has_region (Get_Current_PU ()))
00199 return;
00200
00201 FmtAssert(WN_opcode(itree) == OPC_FUNC_ENTRY,
00202 ("Rail must be called on a PU"));
00203
00204
00205 rtmp.Process_func_entry(itree);
00206
00207 if (rtmp.Trace()) {
00208 fprintf(TFile,"===== RAIL finished\n");
00209 RID_WN_Tree_Print(TFile,itree);
00210 }
00211 }