Open64 (mfef90, whirl2f, and IR tools)
TAG: version-openad; SVN changeset: 916
|
00001 /* 00002 00003 Copyright (C) 2000, 2001 Silicon Graphics, Inc. All Rights Reserved. 00004 00005 This program is free software; you can redistribute it and/or modify it 00006 under the terms of version 2 of the GNU General Public License as 00007 published by the Free Software Foundation. 00008 00009 This program is distributed in the hope that it would be useful, but 00010 WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00012 00013 Further, this software is distributed without any warranty that it is 00014 free of the rightful claim of any third person regarding infringement 00015 or the like. Any license provided herein, whether implied or 00016 otherwise, applies only to this software file. Patent licenses, if 00017 any, provided herein do not apply to combinations of this program with 00018 other software, or any other product whatsoever. 00019 00020 You should have received a copy of the GNU General Public License along 00021 with this program; if not, write the Free Software Foundation, Inc., 59 00022 Temple Place - Suite 330, Boston MA 02111-1307, USA. 00023 00024 Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pky, 00025 Mountain View, CA 94043, or: 00026 00027 http://www.sgi.com 00028 00029 For further information regarding this notice, see: 00030 00031 http://oss.sgi.com/projects/GenInfo/NoticeExplan 00032 00033 */ 00034 00035 00036 //-*-c++-*- 00037 // Data Dependence Graph for Arrays 00038 // --------------------------------- 00039 // 00040 // Description: 00041 // 00042 // A data dependence graph. This data structure is used for three different 00043 // graphs. 00044 // 00045 // 1. LNO has a graph for all array statements in the program unit. 00046 // There is one graph per program unit but edges only exist between 00047 // two array loads/stores that share at least one common "good" DO loop. 00048 // We attach to each edge a DEPV_ARRAY. 00049 // Each load/store of an array WN is mapped to the vertex in the graph. 00050 // Each dependence is defined to be the difference between loop iterations, 00051 // ie, we divide by the step size 00052 // 00053 // Non-array loads/stores (i.e. LDIDs/STIDs) can be in the graph, as 00054 // second class citizens, if there is a dependence between an array 00055 // load/store and an LDID/STID. They are second class citizens in the 00056 // sense that they only appear in the graph if they are dependent on an 00057 // array load/store, and there is never any edges between two LDIDs/STIDs. 00058 // 00059 // 2. Fission/fusion usess a graph of dependence levels. The dependences 00060 // are mapped to statements. 00061 // 00062 // 3. CG uses a dependence graph of DEPs. This defines edges on 00063 // array loads/stores in the same "good" inner DO loop. 00064 // TODO: also should put edges in non-good inner loops. 00065 // The CG graph also contains must dependences. A must dependence 00066 // means that modulo control flow, there is guranteed to be a dependence 00067 // between all pairs of references satisfying the dependence 00068 // distance/direction. In addition, two references with a must dependence 00069 // must be the same size. As opposed to regular dependences, must 00070 // dependences can also be read-read dependences. 00071 // other loads. A boolean flag is set to true on the dependence 00072 // edge if the dependence edge is a must dependence. 00073 // Each dependence is defined to be the difference between loop iterations, 00074 // ie, we divide by the step size 00075 // As opposed to the DEPV_ARRAY graph, LDIDs/STIDs never appear in the graph. 00076 // 00077 // For all graphs: 00078 // An unmapped vertex must be assumed to be dependent on everything. 00079 // Each edge only contains lexicographically positive dependences. 00080 // 00081 // 00082 // 00083 // 00084 // 00085 // Exported types and functions: 00086 // 00087 // enum DEP_GRAPH_TYPE 00088 // {DEPV_ARRAY_ARRAY_GRAPH,LEVEL_ARRAY_GRAPH,DEP_ARRAY_GRAPH}; 00089 // 00090 // Which type of graph 00091 // 00092 // ARRAY_VERTEX16 : public VERTEX16 00093 // 00094 // A vertex 00095 // 00096 // WN *wn 00097 // 00098 // The WN of the load/store 00099 // 00100 // 00101 // ARRAY_EDGE16 : public EDGE16 00102 // 00103 // An edge 00104 // 00105 // Union 00106 // class DEPV_ARRAY *Depv_Array 00107 // class LEVEL_STRUCT Level_Info 00108 // Struct { 00109 // DEP Dep 00110 // mBOOL Is_Must 00111 // } 00112 // 00113 // The dependence 00114 // 00115 // ARRAY_DIRECTED_GRAPH16 : 00116 // public DIRECTED_GRAPH16<ARRAY_VERTEX16, ARRAY_EDGE16> 00117 // 00118 // The graph 00119 // 00120 // ARRAY_DIRECTED_GRAPH16(mUINT16 num_v, mUINT16 num_e, WN_MAP map, 00121 // DEP_GRAPH_TYPE type) 00122 // 00123 // Create a graph of type type. 00124 // The graph will be attached to the code using map. 00125 // 00126 // EINDEX16 Add_Edge(VINDEX16 from, VINDEX16 to, DEP dep, 00127 // BOOL is_must = FALSE) 00128 // 00129 // Add a non-must edge to the graph. 00130 // Return 0 if the graph is full. 00131 // 00132 // VINDEX16 Add_Vertex(WN *wn) 00133 // 00134 // Add a vertex to the graph. Return 0 if the graph is full. 00135 // Use map to map the vertex to this wn. 00136 // 00137 // UINT8 Level(EINDEX16 edge) 00138 // 00139 // Return the dependence associated with the edge 00140 // 00141 // void Set_Level(EINDEX16 edge, UINT8 level) 00142 // 00143 // DEP Dep(EINDEX16 edge) 00144 // 00145 // Return the dependence associated with the edge 00146 // 00147 // BOOL Is_Must(EINDEX16 edge) 00148 // 00149 // Is the dependence a must dependence 00150 // 00151 // void Set_Dep(EINDEX16 edge, DEP dep, BOOL is_must) 00152 // 00153 // MEM_POOL *Pool() 00154 // 00155 // Return the pool used for the DEPV_ARRAYS in the graph 00156 // 00157 // void Print(FILE *fp) 00158 // 00159 // void Remove_Edge(EINDEX16 e) 00160 // 00161 // Remove the edge from the graph. Do not delete the 00162 // Depv_Array (this is useful for stack-based memory disciplines) 00163 // 00164 // VINDEX16 Get_Vertex(WN *wn) 00165 // 00166 // Use the map to find the index associated with this wn. 00167 // Returns 0 if this wn has no vertex 00168 // 00169 // VINDEX16 Get_Vertex() 00170 // 00171 // Get the first vertex in the graph 00172 // 00173 // WN *Get_Wn(VINDEX16 v) 00174 // 00175 // Find the wn associated with this v. 00176 // 00177 // void Set_Wn(VINDEX16 v, WN* wn) { 00178 // 00179 // Make wn to be associated with v and update the map 00180 // 00181 // void Clear_Map_For_Vertex(VINDEX v) 00182 // 00183 // Remove the wn from the map and reset the wn of the vertex. 00184 // This method is solely used by wopt when wn node is being 00185 // transformed into the CODEREP representations. 00186 // 00187 // void Clear_Map() 00188 // 00189 // Remove all mappings in the map and reset wns of all 00190 // vertex to be NULL. 00191 // 00192 // mBOOL Copy_Vertex(VINDEX16 v1, VINDEX16 v2) 00193 // 00194 // Copy all edges to/from v1 to v2 00195 // return 0 if the graph is full. 00196 // This only works on CG's dependence graph. 00197 // 00198 // void Erase_Graph() 00199 // 00200 // Remove all edge edges and vertices from the graph 00201 // 00202 // The remaining routines of this class are LNO specific. No one else 00203 // should use them 00204 // 00205 // EINDEX16 Add_Edge(VINDEX16 from, VINDEX16 to, DEPV_ARRAY *array) 00206 // 00207 // Add an edge to the graph. Return 0 if the graph is full. 00208 // 00209 // BOOL Add_Edge(WN *ref1, const DOLOOP_STACK *s1, 00210 // WN *ref2, const DOLOOP_STACK *s2, 00211 // BOOL s1_lex_before_s2,BOOL use_bounds=TRUE) 00212 // 00213 // Compute the dependences (a DEPV_ARRAY or a DEP) and 00214 // add two edges to the graph (from ref1 to ref2 and 00215 // from ref2 to ref1). Ref1 and Ref2 are loads/stores/call nodes. 00216 // s1_lex_before_s2 should be true 00217 // if s1 appears lexically before s2 in the code. 00218 // This routine assumes that the vertices for the two 00219 // references are already in the graph. 00220 // If this is a DEP graph and not a DEPV_ARRAY graph, the 00221 // two references must be in the same inner loop 00222 // Return 0 if the graph is full. 00223 // If use_bounds is FALSE, don't use bounds information to 00224 // compute dependences (this is an efficiency vrs accuracy 00225 // issue) 00226 // 00227 // BOOL Add_Edge_Stars(WN *ref1, DOLOOP_STACK *s1, WN *ref2, 00228 // DOLOOP_STACK *s2,BOOL s1_lex_before_s2, 00229 // BOOL pos_only=FALSE) 00230 // 00231 // Like Add_Edge above, but rather than actually computing 00232 // depedences, just make them all stars. pos_only adds 00233 // an edge only from ref1 to ref2. 00234 // 00235 // BOOL Add_Edge_Equals(WN *ref1, DOLOOP_STACK *s1, WN *ref2, 00236 // DOLOOP_STACK *s2) 00237 // 00238 // Add an all equals edge from ref1 to ref2 00239 // 00240 // EINDEX16 Add_Edge(VINDEX16 from, VINDEX16 to, UINT8 level) 00241 // 00242 // Add an edge to the graph. Return 0 if the graph is full. 00243 // 00244 // DEPV_ARRAY *Depv_Array(EINDEX16 edge) 00245 // 00246 // void Set_Depv_Array(EINDEX16 edge, DEPV_ARRAY*) 00247 // 00248 // INT Build(WN *func_nd,MEM_POOL *pool=0); 00249 // 00250 // Build the graph for the procedure. Store the DEPV_ARRAYs, 00251 // if this is a DEPV_ARRAY graph, in pool. 00252 // (the actual graph is stored in its own pool) 00253 // Map each l/s node to its vertex in the graph. 00254 // Return 0 on error 00255 // 00256 // INT Build(ARRAY_DIRECTED_GRAPH16 *da_graph) 00257 // 00258 // Given a DEPV_ARRAY graph, build a DEP graph. Copy the 00259 // vertices (although map them to l/s rather than arrays). 00260 // Throw out all the edges between two vertices not in the 00261 // same inner loop. Convert all remaining DEPV_ARRAYs to 00262 // DEPs. 00263 // 00264 // void Delete_Array_Edge(EINDEX16 e) 00265 // 00266 // Remove the edge from a DEPV_ARRAY graph and delete the array 00267 // 00268 // INT Add_Deps_To_Copy_Block(WN *orig,WN *copy, 00269 // BOOL keep_internal_edge) 00270 // 00271 // Given that copy is a copy of the tree rooted at orig. 00272 // Given that all the dependences for orig are in the graph 00273 // Add copies of the dependences to the graph for the nodes in 00274 // copy. This works on the DEPV_ARRAY graph. By default, 00275 // keep_internal_edge is set to TRUE which allows copying 00276 // the edges within the orig. tree. Set it to FALSE would make 00277 // edges within the orig. tree NOT be copied. 00278 // Return 0 on error 00279 // 00280 // INT Unrolled_Dependences_Update(WN** bodies, UINT u, UINT loopno) 00281 // 00282 // Fix the array dependences after loop unrolling. 00283 // Loopno is the number of the loop being unrolled u times. 00284 // bodies[0..u-1] are identical copies of code 00285 // bodies 0 is the original. 00286 // Return 0 on error 00287 // 00288 // void Fission_Dep_Update(WN* in_loop,UINT32 total_loops) 00289 // 00290 // Fix the array dependences after fission. 00291 // in_loop points to the outer loop of the first fissioned loop 00292 // (the rest can be found via next pointers). Total_loops gives 00293 // the number of loops. 00294 // 00295 // INT Fission_Dep_Update(WN* in_loop,UINT32 total_loops, 00296 // UINT fission_depth) 00297 // Fix the statement dependence graph after fission. 00298 // in_loop points to the outer loop of the first fissioned loop 00299 // (the rest can be found via next pointers). Total_loops gives 00300 // the number of loops. Fission_depth gives the number of 00301 // perfectly nested loops being fissioned together 00302 // Return 0 on error (can only happen for statement graph). 00303 // 00304 // INT Build_Region(WN* start, WN* end, DOLOOP_STACK *stack, 00305 // BOOL rebuild=FALSE, BOOL skip_bad=FALSE) 00306 // 00307 // Build the dependences WITHIN a region specified by start 00308 // and end WHIRL nodes. Old edges will be removed 00309 // if rebuild==TRUE. 00310 // If skip_bad do not visit bad loops within this region 00311 // 00312 // 00313 // void Versioned_Dependences_Update (WN* body_orig, WN* body_new, 00314 // UINT loopno, WN_MAP version_map) 00315 // Fix the array dependence graph after versioning loops for 00316 // prefetching. 00317 // body_orig is the original body (the then part after versioning), 00318 // body_new is the new body (the then part after versioning), 00319 // and loopno is the depth of the loop being split. 00320 // 00321 // void Versioned_Create_Vertices (WN* body_orig, WN* body_new) 00322 // Given the original and new body of a versioned loop, 00323 // add vertices in the new body for each node in orig-body that 00324 // has a vertex. 00325 // 00326 // void Versioned_Dependences_Update_E (WN *body_orig, 00327 // WN* body_new, 00328 // WN* root_orig, 00329 // WN* root_new, 00330 // UINT loopno, 00331 // WN_MAP version_map) 00332 // Given the orig-body and new-body of a versioned loop, 00333 // add the edges based on the edges in the original dependence 00334 // graph. 00335 // 00336 // void Check_Graph() 00337 // 00338 // Assertion fails if a few simple checks fail. 00339 // Only defined if Is_True_On is set. 00340 // 00341 // 00342 00343 #ifndef dep_graph_INCLUDED 00344 #define dep_graph_INCLUDED "dep_graph.h" 00345 00346 #ifdef _KEEP_RCS_ID 00347 #endif /* _KEEP_RCS_ID */ 00348 00349 #ifndef cxx_graph_INCLUDED 00350 #include "cxx_graph.h" 00351 #endif 00352 #ifndef graph_template_INCLUDED 00353 #include "graph_template.h" 00354 #endif 00355 #ifndef _defs_INCLUDED 00356 #include "cxx_memory.h" 00357 #endif 00358 00359 #ifdef LNO 00360 #ifndef dep_INCLUDED 00361 #include "dep.h" 00362 #endif 00363 #ifndef cxx_hash_INCLUDED 00364 #include "cxx_hash.h" 00365 #endif 00366 #endif 00367 00368 #ifndef LNO 00369 #ifndef dvector_INCLUDED 00370 #include "dvector.h" 00371 #endif 00372 #endif 00373 00374 /* C interface functions used for reading and writing graphs */ 00375 extern "C" { 00376 void *C_Dep_Graph(void); 00377 void Init_Dep_Graph(void *g); 00378 void Dealloc_Dep_Graph(void); 00379 void Depgraph_Write(void *depgraph, struct output_file *fl, WN_MAP off_map); 00380 void *Depgraph_Read(char *cur_addr, char *end_addr, char *wn_base); 00381 00382 void LNOPreserveMapPair(WN *orig, WN *wn1, WN *wn2); 00383 void LNOPruneMapsUsingParity(void); 00384 void LNOPrintDepGraph(FILE *fp); 00385 VINDEX16 LNOGetVertex(WN *wn); 00386 00387 BOOL WN_parity_independent(WN *wn1, WN *wn2); 00388 00389 BOOL LnoDependenceEdge(WN *wn1, WN *wn2, EINDEX16 *distance, DIRECTION *direction, BOOL *is_must, BOOL *status); 00390 } 00391 00392 enum DEP_GRAPH_TYPE {DEPV_ARRAY_ARRAY_GRAPH,LEVEL_ARRAY_GRAPH,DEP_ARRAY_GRAPH}; 00393 00394 class ARRAY_VERTEX16 : public VERTEX16 { 00395 public: 00396 WN *Wn; 00397 ARRAY_VERTEX16(WN *wn) { Wn = wn;} 00398 friend class ARRAY_DIRECTED_GRAPH16; 00399 }; 00400 00401 #define HAS_ALL_ZERO 0x0001 00402 #define HAS_SCALAR_FLOW 0x0002 00403 #define HAS_SCALAR_ANTI 0x0004 00404 #define HAS_SCALAR_OUTPUT 0x0008 00405 #define HAS_ARRAY_FLOW 0x0010 00406 #define HAS_ARRAY_ANTI 0x0020 00407 #define HAS_ARRAY_OUTPUT 0x0040 00408 00409 struct LEVEL_STRUCT { 00410 UINT8 Level; 00411 UINT16 Property; 00412 }; 00413 00414 struct DEP_STRUCT { 00415 DEP Dep; 00416 mBOOL Is_Must; 00417 }; 00418 00419 class ARRAY_EDGE16 : public EDGE16 { 00420 public: 00421 friend class ARRAY_DIRECTED_GRAPH16; 00422 union { 00423 class DEPV_ARRAY *Depv_Array; 00424 struct LEVEL_STRUCT Level_Info; 00425 DEP_STRUCT DEP_Struct; 00426 }; 00427 }; 00428 00429 #ifdef LNO 00430 class REFERENCE_LIST; 00431 typedef STACK<REFERENCE_LIST *> REF_LIST_STACK; 00432 typedef STACK<VINDEX16 > VINDEX16_STACK; 00433 00434 class VINDEX16P_LEX_COUNT { 00435 public: 00436 VINDEX16 *_vp; 00437 INT _lex_count; 00438 VINDEX16P_LEX_COUNT(VINDEX16 *vp, INT lex_count) { 00439 _vp = vp; 00440 _lex_count = lex_count; 00441 } 00442 }; 00443 00444 #endif 00445 00446 class ARRAY_DIRECTED_GRAPH16 : 00447 public DIRECTED_GRAPH16<ARRAY_EDGE16,ARRAY_VERTEX16> { 00448 WN_MAP _map; 00449 DEP_GRAPH_TYPE _type; 00450 MEM_POOL *_pool; 00451 public: 00452 void Print(FILE *fp); 00453 ARRAY_DIRECTED_GRAPH16(mUINT16 num_v, mUINT16 num_e, WN_MAP map, 00454 DEP_GRAPH_TYPE type) : 00455 DIRECTED_GRAPH16<ARRAY_EDGE16,ARRAY_VERTEX16>(num_v,num_e) { 00456 _map=map; 00457 _type = type; 00458 _pool = NULL; 00459 } 00460 00461 MEM_POOL *Pool() { return _pool; } 00462 00463 void Erase_Graph(); 00464 00465 EINDEX16 Add_Edge(VINDEX16 from, VINDEX16 to, DEP dep, BOOL is_must=FALSE) { 00466 Is_True(_type==DEP_ARRAY_GRAPH, 00467 ("Trying to add a dep edge to a non-dep graph")); 00468 EINDEX16 result = 00469 DIRECTED_GRAPH16<ARRAY_EDGE16,ARRAY_VERTEX16>::Add_Edge(from,to); 00470 if (result != 0) _e[result].DEP_Struct.Dep = dep; 00471 _e[result].DEP_Struct.Is_Must = is_must; 00472 return result; 00473 } 00474 00475 DEP Dep(EINDEX16 edge) { 00476 Is_True(_type==DEP_ARRAY_GRAPH, 00477 ("Trying to get a dep edge from a non-dep graph")); 00478 return(_e[edge].DEP_Struct.Dep); 00479 } 00480 BOOL Is_Must(EINDEX16 edge) { 00481 Is_True(_type==DEP_ARRAY_GRAPH, 00482 ("Trying to get a dep edge from a non-dep graph")); 00483 return(_e[edge].DEP_Struct.Is_Must); 00484 } 00485 void Set_Dep(EINDEX16 edge, DEP dep, BOOL is_must=FALSE) { 00486 Is_True(_type==DEP_ARRAY_GRAPH, 00487 ("Trying to set a dep edge in a non-dep graph")); 00488 _e[edge].DEP_Struct.Dep = dep; 00489 _e[edge].DEP_Struct.Is_Must = is_must; 00490 } 00491 00492 VINDEX16 Add_Vertex(WN *wn) { 00493 VINDEX16 result = 00494 DIRECTED_GRAPH16<ARRAY_EDGE16,ARRAY_VERTEX16>::Add_Vertex(); 00495 if (result != 0) { 00496 _v[result].Wn = wn; 00497 WN_MAP_Set(_map,wn, (void *) (UINT) result); 00498 } 00499 return result; 00500 } 00501 00502 void Remove_Edge(EINDEX16 e) { 00503 DIRECTED_GRAPH16<ARRAY_EDGE16,ARRAY_VERTEX16>::Delete_Edge(e); 00504 } 00505 00506 VINDEX16 Get_Vertex(WN *wn) { 00507 return (VINDEX16) (UINT) (INTPTR) WN_MAP_Get(_map,wn); 00508 } 00509 00510 VINDEX16 Get_Vertex() { 00511 return DIRECTED_GRAPH16<ARRAY_EDGE16,ARRAY_VERTEX16>::Get_Vertex(); 00512 } 00513 00514 void Delete_Vertex(VINDEX16 v) { 00515 WN_MAP_Set(_map, _v[v].Wn, NULL); 00516 DIRECTED_GRAPH16<ARRAY_EDGE16,ARRAY_VERTEX16>::Delete_Vertex(v); 00517 } 00518 00519 WN* Get_Wn(VINDEX16 v) { 00520 return _v[v].Wn; 00521 } 00522 00523 void Set_Wn(VINDEX16 v, WN* wn) { 00524 _v[v].Wn=wn; 00525 WN_MAP_Set(_map, _v[v].Wn, (void*)(UINT)v); 00526 } 00527 00528 void Delete_Vertex(WN *wn) { 00529 Delete_Vertex(Get_Vertex(wn)); 00530 } 00531 00532 void Clear_Map_For_Vertex(VINDEX16 v) { 00533 WN_MAP_Set(_map, _v[v].Wn, NULL); 00534 _v[v].Wn=NULL; 00535 } 00536 00537 void Clear_Map() { 00538 VINDEX16 v=Get_Vertex(); 00539 while (v!=0) { 00540 Clear_Map_For_Vertex(v); 00541 v=Get_Next_Vertex(v); 00542 } 00543 } 00544 00545 mBOOL Copy_Vertex(VINDEX16 v1, VINDEX16 v2) { 00546 Is_True(_type==DEP_ARRAY_GRAPH, 00547 ("Copy_Vertex only works on DEP_ARRAY_GRAPH")); 00548 if (v2 != 0) { 00549 EINDEX16 e=Get_Out_Edge(v2); 00550 while (e) { 00551 EINDEX16 e1=Get_Next_Out_Edge(e); 00552 Remove_Edge(e); 00553 e=e1; 00554 } 00555 e=Get_In_Edge(v2); 00556 while (e) { 00557 EINDEX16 e1=Get_Next_In_Edge(e); 00558 Remove_Edge(e); 00559 e=e1; 00560 } 00561 e=Get_Out_Edge(v1); 00562 while (e) { 00563 VINDEX16 to=Get_Sink(e); 00564 if (!Add_Edge(v2,to,_e[e].DEP_Struct.Dep,_e[e].DEP_Struct.Is_Must)) { 00565 return 0; 00566 } 00567 e=Get_Next_Out_Edge(e); 00568 } 00569 e=Get_In_Edge(v1); 00570 while (e) { 00571 VINDEX16 source=Get_Source(e); 00572 if (!Add_Edge(source,v2,_e[e].DEP_Struct.Dep,_e[e].DEP_Struct.Is_Must)) { 00573 return 0; 00574 } 00575 e=Get_Next_In_Edge(e); 00576 } 00577 } 00578 return 1; 00579 } 00580 00581 00582 void PreserveMapPair(WN *orig, WN *wn1, WN *wn2) 00583 { 00584 VINDEX16 origV; 00585 Is_True((Get_Vertex(wn1)==0),("Dep_PreserveMapPair(): unexpected map")); 00586 Is_True((Get_Vertex(wn2)==0),("Dep_PreserveMapPair(): unexpected map")); 00587 00588 if (origV = Get_Vertex(orig)) 00589 { 00590 VINDEX16 v1 = Get_Vertex(wn1); 00591 VINDEX16 v2 = Get_Vertex(wn2); 00592 00593 if (v1 == 0) 00594 v1 = Add_Vertex(wn1); 00595 00596 if (v2 == 0) 00597 v2 = Add_Vertex(wn2); 00598 00599 Copy_Vertex(origV, v1); 00600 Copy_Vertex(origV, v2); 00601 } 00602 } 00603 00604 void PruneMapsUsingParity(void); 00605 00606 00607 #ifdef LNO 00608 INT Build(WN *func_nd,MEM_POOL *pool=0); 00609 INT Build(ARRAY_DIRECTED_GRAPH16 *da_graph); 00610 EINDEX16 Add_Edge(VINDEX16 from, VINDEX16 to, DEPV_ARRAY *array) { 00611 Is_True(_type==DEPV_ARRAY_ARRAY_GRAPH, 00612 ("Trying to add a DEPV_ARRAY edge to a non-DEPV_ARRAY graph")); 00613 Is_True(!Get_Edge(from,to),("Duplicate edge in Add_Edge \n")); 00614 Is_True(array,("Null array in Add_Edge")); 00615 if (!array) return (EINDEX16) 0; 00616 EINDEX16 result = 00617 DIRECTED_GRAPH16<ARRAY_EDGE16,ARRAY_VERTEX16>::Add_Edge(from,to); 00618 if (result != 0) _e[result].Depv_Array = array; 00619 return result; 00620 } 00621 EINDEX16 Add_Edge(VINDEX16 from, VINDEX16 to, UINT8 level) { 00622 Is_True(_type==LEVEL_ARRAY_GRAPH, 00623 ("Trying to add a level edge to a non-level graph")); 00624 EINDEX16 result = 00625 DIRECTED_GRAPH16<ARRAY_EDGE16,ARRAY_VERTEX16>::Add_Edge(from,to); 00626 if (result != 0) _e[result].Level_Info.Level = level; 00627 return result; 00628 } 00629 BOOL Add_Edge(WN *ref1, const DOLOOP_STACK *s1, 00630 WN *ref2, const DOLOOP_STACK *s2, 00631 BOOL s1_lex_before_s2, BOOL use_bounds=TRUE); 00632 BOOL Add_Edge_Stars(WN *ref1, const DOLOOP_STACK *s1, 00633 WN *ref2, const DOLOOP_STACK *s2, 00634 BOOL s1_lex_before_s2, BOOL pos_only=FALSE); 00635 BOOL Add_Edge_Equals(WN *ref1, const DOLOOP_STACK *s1, 00636 WN *ref2, const DOLOOP_STACK *s2); 00637 00638 DEPV_ARRAY *Depv_Array(EINDEX16 edge) { 00639 Is_True(_type==DEPV_ARRAY_ARRAY_GRAPH, 00640 ("Trying to get a DEPV_ARRAY edge from a non-DEPV_ARRAY graph")); 00641 return(_e[edge].Depv_Array); 00642 } 00643 00644 void Set_Depv_Array(EINDEX16 edge, DEPV_ARRAY* newdv) { 00645 Is_True(_type==DEPV_ARRAY_ARRAY_GRAPH, 00646 ("Trying to set a DEPV_ARRAY edge in a non-DEPV_ARRAY graph")); 00647 _e[edge].Depv_Array = newdv; 00648 } 00649 00650 UINT8 Level(EINDEX16 edge) { 00651 Is_True(_type==LEVEL_ARRAY_GRAPH, 00652 ("Trying to get a level edge from a non-level graph")); 00653 return(_e[edge].Level_Info.Level); 00654 } 00655 00656 void Set_Level(EINDEX16 edge, UINT8 level) { 00657 Is_True(_type==LEVEL_ARRAY_GRAPH, 00658 ("Trying to set a level edge in a non-level graph")); 00659 _e[edge].Level_Info.Level = level; 00660 } 00661 00662 00663 void Delete_Array_Edge(EINDEX16 e) { 00664 Is_True(_type==DEPV_ARRAY_ARRAY_GRAPH, 00665 ("Trying to delete a DEPV_ARRAY edge from a non-DEPV_ARRAY graph")); 00666 Delete_DEPV_ARRAY(_e[e].Depv_Array,_pool); 00667 DIRECTED_GRAPH16<ARRAY_EDGE16,ARRAY_VERTEX16>::Delete_Edge(e); 00668 } 00669 00670 00671 void Set_Level_Property(EINDEX16 e, UINT16 property) { 00672 _e[e].Level_Info.Property |= property; 00673 } 00674 00675 BOOL Get_Level_Property(EINDEX16 e, UINT16 property) { 00676 return ((_e[e].Level_Info.Property & property) != 0); 00677 } 00678 00679 INT Add_Deps_To_Copy_Block(WN *orig, WN *copy, BOOL keep_internal_edge=TRUE); 00680 INT Unrolled_Dependences_Update(WN** bodies, UINT u, UINT loopno); 00681 void Fission_Dep_Update(WN* in_loop,UINT32 total_loops); 00682 INT Fission_Dep_Update(WN* in_loop,UINT32 total_loops, UINT fission_depth); 00683 void Fission_Dep_Update_R(WN* wn,WN *in_loop,UINT depth); 00684 INT Build_Region(WN* start, WN* end,DOLOOP_STACK *stack,BOOL rebuild=FALSE, BOOL skip_bad=FALSE); 00685 BOOL Versioned_Dependences_Update (WN* body_orig, WN* body_new, UINT loopno, 00686 WN_MAP version_map); 00687 void Versioned_Create_Vertices (WN* body_orig, WN* body_new); 00688 BOOL Versioned_Dependences_Update_E (WN *body_orig, 00689 WN* body_new, 00690 WN* root_orig, 00691 WN* root_new, 00692 UINT loopno, 00693 WN_MAP version_map); 00694 00695 #ifdef Is_True_On 00696 void Check_Graph(); 00697 #endif 00698 #endif /* LNO */ 00699 00700 private: 00701 00702 #ifdef LNO 00703 void Add_Must(); 00704 void Set_Must(EINDEX16 edge) { 00705 _e[edge].DEP_Struct.Is_Must = TRUE; 00706 } 00707 BOOL Is_Must(ACCESS_ARRAY *a1, ACCESS_ARRAY *a2, WN *inner_loop, 00708 DEP *dep=NULL); 00709 00710 INT Find_Region(WN *wn, DOLOOP_STACK *stack); 00711 INT Gather_References(WN *wn, REF_LIST_STACK *writes, 00712 REF_LIST_STACK *reads, DOLOOP_STACK *stack, 00713 class SCALAR_STACK *scalar_writes, class SCALAR_STACK *scalar_reads, 00714 class CALL_STACK *calls, BOOL skip_bad=FALSE); 00715 INT Add_Deps_To_Copy_Block_V(WN *orig, WN *copy, 00716 class HASH_TABLE<VINDEX16,VINDEX16> *hash_table); 00717 INT Add_Deps_To_Copy_Block_E(WN *orig, WN *copy, 00718 class HASH_TABLE<VINDEX16,VINDEX16> *hash_table, 00719 BOOL keep_internal_edge=TRUE); 00720 INT Unrolled_Dependences_Update_V(WN** bodies, UINT u, 00721 class HASH_TABLE<VINDEX16,VINDEX16P_LEX_COUNT *> *hash_table, 00722 VINDEX16_STACK *orig_vertices); 00723 INT Unrolled_Dependences_Update_E(UINT u, 00724 UINT loopno,class HASH_TABLE<VINDEX16,VINDEX16P_LEX_COUNT*>*hash_table, 00725 VINDEX16_STACK *orig_vertices); 00726 INT Unrolled_Dependences_Update_E(VINDEX16 *sources, VINDEX16 *sinks, 00727 EINDEX16 fedge, EINDEX16 bedge,UINT u, UINT loopno, INT lex_count, 00728 INT sink_lex_count); 00729 void Fission_Dep_Update_V(VINDEX16 v,WN *in_loop, UINT depth); 00730 INT Copy_Do_Loop_Deps(VINDEX16 *do_loop_vertices, INT num_loops); 00731 INT Fission_Dep_Update_R(WN *in_loop,UINT fission_depth, UINT depth, 00732 BOOL outer_good_do); 00733 #endif 00734 00735 /* friends called from C functions for reading and writing graphs */ 00736 friend void Depgraph_Write(void *depgraph, struct output_file *fl, 00737 WN_MAP off_map); 00738 friend void *Depgraph_Read(char *cur_addr, char *end_addr, char *wn_base); 00739 }; 00740 00741 extern ARRAY_DIRECTED_GRAPH16 *Current_Dep_Graph; 00742 extern void LNO_Erase_Dg_From_Here_In(WN* wn, ARRAY_DIRECTED_GRAPH16* dg); 00743 extern void Unmapped_Vertices_Here_Out(WN* wn); 00744 00745 #ifdef LNO 00746 // A list of references and their associated DOLOOP_STACKs 00747 // For efficiency reasons, the build routines use stacks of 00748 // REFERENCE_LISTs, one element for each base array. 00749 // A base array is represented by its ST_Base pointer. 00750 // We only call the dependence routines on two arrays with the same 00751 // base pointer. If we can't figure out an element's 00752 // base pointer, we put it on the list of zero base pointers. 00753 // Zero base pointers will be compared to everything. 00754 00755 00756 class REFERENCE_NODE: public SLIST_NODE { 00757 DECLARE_SLIST_NODE_CLASS( REFERENCE_NODE); 00758 public: 00759 DOLOOP_STACK *Stack; 00760 WN *Wn; 00761 UINT Statement_Number; 00762 00763 REFERENCE_NODE(WN *wn, DOLOOP_STACK *stack, UINT statement_number) { 00764 Wn = wn; 00765 Stack = stack; 00766 Statement_Number = statement_number; 00767 }; 00768 void Print(FILE *fp) { 00769 fprintf(fp,"Wn, Statment_Number = 0x%p %d\n", 00770 Wn,Statement_Number); 00771 } 00772 ~REFERENCE_NODE(); 00773 }; 00774 00775 class REFERENCE_LIST: public SLIST { 00776 DECLARE_SLIST_CLASS( REFERENCE_LIST, REFERENCE_NODE ) 00777 public: 00778 ST *ST_Base; 00779 WN *Array; 00780 WN *Inner_Loop; 00781 REFERENCE_LIST(ST *st_base, WN *array, WN *inner_loop=0) { 00782 ST_Base = st_base; 00783 Array = array; 00784 Inner_Loop = inner_loop; 00785 }; 00786 void Print(FILE *fp); 00787 ~REFERENCE_LIST(); 00788 }; 00789 00790 00791 // A stack of SYMBOLs and all the WNs that access that symbol 00792 00793 // one reference 00794 class SCALAR_REF { 00795 public: 00796 WN *Wn; 00797 UINT Statement_Number; 00798 SCALAR_REF(WN *wn, UINT statement_number) { 00799 Wn = wn; 00800 Statement_Number = statement_number; 00801 } 00802 SCALAR_REF& operator=(const SCALAR_REF& scalar_ref) { 00803 Wn = scalar_ref.Wn; 00804 Statement_Number = scalar_ref.Statement_Number; 00805 return *this; 00806 } 00807 }; 00808 00809 // all the references to a particular SYMBOL 00810 class SCALAR_NODE 00811 { 00812 MEM_POOL *_pool; 00813 public: 00814 SYMBOL _scalar; 00815 STACK <SCALAR_REF> *_scalar_ref_stack; 00816 SCALAR_NODE(MEM_POOL *pool, SYMBOL scalar) { 00817 typedef STACK<SCALAR_REF> SCALAR_REF_STACK; 00818 _pool = pool; 00819 _scalar_ref_stack = CXX_NEW(SCALAR_REF_STACK(pool),pool); 00820 _scalar = scalar; 00821 } 00822 INT Elements() const { return _scalar_ref_stack->Elements(); }; 00823 SCALAR_REF *Bottom_nth(INT i) { return &_scalar_ref_stack->Bottom_nth(i); }; 00824 SCALAR_REF *Top_nth(INT i) { return &_scalar_ref_stack->Top_nth(i); }; 00825 }; 00826 00827 class SCALAR_STACK 00828 { 00829 STACK <SCALAR_NODE> *_stack; 00830 MEM_POOL *_pool; 00831 public: 00832 SCALAR_STACK(MEM_POOL *pool) { 00833 typedef STACK<SCALAR_NODE> SNODE_STACK; 00834 typedef STACK<INT> INT_STACK; 00835 _pool = pool; 00836 _stack = CXX_NEW(SNODE_STACK(pool),pool); 00837 } 00838 void Add_Scalar(WN *wn, UINT snumber); 00839 void Add_Scalar(WN *wn_call, SYMBOL* symbol, UINT snumber); 00840 void Print(FILE *fp); 00841 void Clear() { _stack->Clear(); }; 00842 INT Elements() const { return _stack->Elements(); }; 00843 SCALAR_NODE* Bottom_nth(INT i) { return &_stack->Bottom_nth(i); }; 00844 SCALAR_NODE* Top_nth(INT i) { return &_stack->Top_nth(i); }; 00845 void Add_Scalar_Node(SCALAR_NODE* sn) {_stack->Push(*sn);}; 00846 void Clear_Formal(INT i); 00847 }; 00848 00849 // describe the calls 00850 class CALL_NODE 00851 { 00852 public: 00853 WN *_call; 00854 UINT _statement_number; 00855 DOLOOP_STACK *_stack; 00856 BOOL _is_concurrent_call; 00857 CALL_NODE(WN *call, UINT statement_number, DOLOOP_STACK *stack, 00858 BOOL is_concurrent_call) { 00859 _call = call; 00860 _statement_number = statement_number; 00861 _stack = stack; 00862 _is_concurrent_call = is_concurrent_call; 00863 } 00864 }; 00865 00866 class CALL_STACK 00867 { 00868 STACK <CALL_NODE> *_stack; 00869 MEM_POOL *_pool; 00870 public: 00871 CALL_STACK(MEM_POOL *pool) { 00872 typedef STACK<CALL_NODE> CNODE_STACK; 00873 _pool = pool; 00874 _stack = CXX_NEW(CNODE_STACK(pool),pool); 00875 } 00876 void Clear() { _stack->Clear(); } 00877 INT Elements() const { return _stack->Elements(); }; 00878 CALL_NODE *Bottom_nth(INT i) { return &_stack->Bottom_nth(i); }; 00879 CALL_NODE *Top_nth(INT i) { return &_stack->Top_nth(i); }; 00880 void Push(WN *call, UINT statement_number,DOLOOP_STACK *stack, 00881 BOOL is_concurrent_call) { 00882 _stack->Push(CALL_NODE(call,statement_number,stack,is_concurrent_call)); 00883 }; 00884 }; 00885 00886 // describe the calls 00887 00888 00889 00890 class REFERENCE_ITER: public SLIST_ITER { 00891 DECLARE_SLIST_ITER_CLASS( REFERENCE_ITER, REFERENCE_NODE ,REFERENCE_LIST); 00892 public: 00893 ~REFERENCE_ITER() {}; 00894 }; 00895 00896 #endif 00897 00898 00899 #endif 00900 00901