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 // ==================================================================== 00038 // ==================================================================== 00039 // 00040 // 00041 // Description: 00042 // 00043 // fb_cfg.h and fb_cfg.cxx implement a control flow graph for edge 00044 // frequency data. The CFG can be displayed (using daVinci), and can 00045 // propagate known frequencies to compute unknown values. 00046 // The CFG _MUST_ contain no critical edges. 00047 // 00048 // ==================================================================== 00049 // ==================================================================== 00050 00051 #ifndef fb_cfg_INCLUDED 00052 #define fb_cfg_INCLUDED 00053 00054 #include "mempool_allocator.h" 00055 00056 #include <vector> 00057 #include <deque> 00058 00059 #ifndef _USE_STL_EXT 00060 #include <map> 00061 #else 00062 #include <hash_map> 00063 #endif 00064 00065 using namespace std; 00066 00067 #include "fb_whirl.h" 00068 00069 // ==================================================================== 00070 // FB_NODEX -- Nodes are numbered from 0 upwards 00071 // ==================================================================== 00072 00073 typedef INT32 FB_NODEX; 00074 #define FB_NODEX_UNINIT (-1) 00075 #define FB_NODEX_VALID(nx) ((nx) >= 0) 00076 00077 // ==================================================================== 00078 // FB_CFG Nodes 00079 // ==================================================================== 00080 00081 // Since FB_CFG contains no critical edges, if pred preceeds succ, then 00082 // either pred.one_edge_succs or succ.one_edge_preds (or both) are true 00083 00084 struct FB_NODE { 00085 00086 vector<FB_NODEX> preds; // Predecessors 00087 vector<FB_NODEX> succs; // Successors 00088 00089 bool one_edge_preds; // true iff every pred has no other succs 00090 bool one_edge_succs; // true iff every succ has no other preds 00091 00092 INT undelayed_succs; // Used by daVinci 00093 00094 // Source of node frequency data 00095 FB_EDGE_TYPE node_type; 00096 WN *source; 00097 00098 // Frequency data. If in_out_same is true, then we may assume that 00099 // freq_total_in and freq_total_out are equal. 00100 bool in_out_same; 00101 FB_FREQ freq_total_in; 00102 FB_FREQ freq_total_out; 00103 00104 INT unknown_in; 00105 INT unknown_out; 00106 INT unexact_in; 00107 INT unexact_out; 00108 00109 FB_NODE() : 00110 one_edge_preds( true ), 00111 one_edge_succs( true ), 00112 undelayed_succs( 0), 00113 node_type( FB_EDGE_UNINIT ), 00114 source( NULL ), 00115 in_out_same( true ), 00116 freq_total_in( FB_FREQ_UNKNOWN ), 00117 freq_total_out( FB_FREQ_UNKNOWN ), 00118 unknown_in( 1 ), 00119 unknown_out( 1 ), 00120 unexact_in( 1 ), 00121 unexact_out( 1 ) {} 00122 00123 FB_NODE( FB_EDGE_TYPE type, WN *src, bool same, 00124 FB_FREQ freq_in, FB_FREQ freq_out ) : 00125 one_edge_preds( true ), 00126 one_edge_succs( true ), 00127 undelayed_succs( 0 ), 00128 node_type( type ), 00129 source( src ), 00130 in_out_same( same ), 00131 freq_total_in( freq_in ), 00132 freq_total_out( freq_out ), 00133 unknown_in( freq_in.Known() ? 0 : 1 ), 00134 unknown_out( freq_out.Known() ? 0 : 1 ), 00135 unexact_in( freq_in.Exact() ? 0 : 1 ), 00136 unexact_out( freq_out.Exact() ? 0 : 1 ) {} 00137 00138 void Print( FILE *fp, FB_NODEX nx ) const { 00139 INT t; 00140 char buffer[FB_EDGE_TYPE_NAME_LENGTH]; 00141 FB_EDGE_TYPE_sprintf( buffer, node_type ); 00142 fprintf( fp, "node %d: node_type %s, source 0x%p, in_out_same %c,\n", 00143 nx, buffer, source, ( in_out_same ? 'Y' : 'N' ) ); 00144 fprintf( fp, " one_edge_preds %c, one_edge_succs %c," 00145 " undelayed_succs %d,\n", ( one_edge_preds ? 'Y' : 'N' ), 00146 ( one_edge_succs ? 'Y' : 'N' ), undelayed_succs ); 00147 fprintf( fp, " unknown_in %d, unexact_in %d, freq_total_in ", 00148 unknown_in, unexact_in ); 00149 freq_total_in.Print( fp ); 00150 fprintf( fp, ", preds [" ); 00151 for ( t = 0; t < preds.size(); t++ ) 00152 fprintf( fp, " %d", preds[t] ); 00153 fprintf( fp, " ],\n"); 00154 fprintf( fp, " unknown_out %d, unexact_out %d, freq_total_out ", 00155 unknown_out, unexact_out ); 00156 freq_total_out.Print( fp ); 00157 fprintf( fp, ", succs [" ); 00158 for ( t = 0; t < succs.size(); t++ ) 00159 fprintf( fp, " %d", succs[t] ); 00160 fprintf( fp, " ]\n"); 00161 } 00162 }; 00163 00164 struct FB_EDGE_DELAYED { // Destination is a label instead of a node 00165 FB_NODEX source; 00166 LABEL_IDX destination; 00167 00168 FB_EDGE_DELAYED( FB_NODEX src, LABEL_IDX dst ) { 00169 source = src; 00170 destination = dst; 00171 } 00172 }; 00173 00174 // ==================================================================== 00175 00176 class FB_CFG_MEM { 00177 protected: 00178 MEM_POOL _m; 00179 00180 FB_CFG_MEM() { 00181 MEM_POOL_Initialize( &_m, "FB_CFG_MEM", true ); 00182 MEM_POOL_Push( &_m ); 00183 } 00184 ~FB_CFG_MEM() { 00185 MEM_POOL_Pop( &_m ); 00186 MEM_POOL_Delete(&_m ); 00187 } 00188 }; 00189 00190 class FB_CFG : public FB_CFG_MEM { 00191 private: 00192 00193 bool _trace; // Get_Trace(TP_FEEDBACK, TP_FEEDBACK_CFG) 00194 bool _trace_draw; // Get_Trace(TP_FEEDBACK, TP_FEEDBACK_CFG_DRAW) 00195 bool _trace_before; // Get_Trace(TP_FEEDBACK, TP_FEEDBACK_CFG_BEFORE) 00196 bool _trace_prop; // Get_Trace(TP_FEEDBACK, TP_FEEDBACK_CFG_PROP) 00197 00198 // vectors containing all nodes, indexed by FB_NODEX 00199 vector< FB_NODE, mempool_allocator<FB_NODE> > _nodes; 00200 00201 // The following data elements are needed only during the construction of 00202 // the feedback control flow graph, to maintain state as the WHIRL code is 00203 // processed. 00204 // _lblx_to_nx maps label indicies to node indicies; assumes label 00205 // numbers are unique within a program unit 00206 // _delayed_edges lists edges that will need to be added to the graph 00207 // after all nodes are in place 00208 // _curr_nx is the node currently being visited; if no node is 00209 // current, then nx == FB_NODEX_UNINIT 00210 00211 00212 // Solaris CC workaround 00213 // to replace hash_map with map 00214 #ifndef _USE_STL_EXT 00215 struct LABEL_IDX_ss_compare { 00216 bool operator() (LABEL_IDX idx1, LABEL_IDX idx2) 00217 { 00218 return idx1 < idx2; 00219 } 00220 } ; 00221 00222 map< LABEL_IDX, FB_NODEX, LABEL_IDX_ss_compare, 00223 mempool_allocator< pair<const LABEL_IDX,FB_NODEX> > > _lblx_to_nx; 00224 00225 #else 00226 hash_map< LABEL_IDX, FB_NODEX, hash<LABEL_IDX>, equal_to<LABEL_IDX>, 00227 mempool_allocator< pair<const LABEL_IDX,FB_NODEX> > > _lblx_to_nx; 00228 00229 #endif 00230 00231 deque< FB_EDGE_DELAYED, mempool_allocator<FB_EDGE_DELAYED> > _delayed_edges; 00232 00233 FB_NODEX _curr_nx; 00234 00235 private: 00236 00237 // The following functions access the FB_CFG data representation 00238 00239 FB_NODEX New_node(); 00240 FB_NODEX New_node( FB_EDGE_TYPE node_type, WN *source, FB_FREQ freq_total_in, 00241 FB_FREQ freq_total_out, bool in_out_same = false ); 00242 FB_NODEX New_node( FB_EDGE_TYPE node_type, WN *source, 00243 FB_FREQ freq_total_in ) { 00244 return New_node( node_type, source, freq_total_in, freq_total_in, true ); 00245 } 00246 00247 void Add_label( LABEL_IDX labelx, FB_NODEX nx ) { _lblx_to_nx[labelx] = nx; } 00248 00249 void Add_edge(FB_NODEX nx_src, FB_NODEX nx_dst, bool delayed = false ); 00250 void Add_delayed_edge( FB_NODEX nx_src, WN *wn ); 00251 void Complete_delayed_edges(); 00252 00253 FB_NODEX Curr() const { return _curr_nx; } 00254 void Set_curr( FB_NODEX nx ) { _curr_nx = nx; } 00255 FB_NODEX Get_curr(); // Creates a new _curr if there isn't one already 00256 00257 // The following functions are invoked during the construction of the cfg 00258 00259 void Walk_WN_expression( WN *wn ); 00260 void Walk_WN_test_expression( WN *wn, FB_NODEX true_nx, FB_NODEX false_nx ); 00261 void Walk_WN_statement( WN *wn ); 00262 00263 void Freq_propagate_node_in( FB_NODEX nx ); 00264 void Freq_propagate_node_out( FB_NODEX nx ); 00265 void Freq_propagate(); 00266 00267 char *Node_label( FB_NODEX nx ) const; 00268 00269 public: 00270 00271 FB_CFG() : 00272 _trace( Get_Trace( TP_FEEDBACK, TP_FEEDBACK_CFG ) ), 00273 _trace_draw( Get_Trace( TP_FEEDBACK, TP_FEEDBACK_CFG_DRAW ) ), 00274 _trace_before( Get_Trace( TP_FEEDBACK, TP_FEEDBACK_CFG_BEFORE ) ), 00275 _trace_prop( Get_Trace( TP_FEEDBACK, TP_FEEDBACK_CFG_PROP ) ), 00276 _nodes( mempool_allocator<FB_NODE>(&_m) ), 00277 00278 // Solaris CC workaround 00279 // this is the construction of <map> instead of <hash_map> 00280 00281 #ifndef _USE_STL_EXT 00282 _lblx_to_nx(), 00283 00284 #else 00285 _lblx_to_nx( 100, hash<LABEL_IDX>(), equal_to<LABEL_IDX>(), 00286 mempool_allocator< pair<LABEL_IDX,FB_NODEX> >(&_m) ), 00287 00288 #endif 00289 00290 _delayed_edges( mempool_allocator<FB_EDGE_DELAYED>(&_m) ), 00291 _curr_nx( FB_NODEX_UNINIT ) {} 00292 00293 ~FB_CFG() {} 00294 00295 void Construct_from_whirl( WN *wn_root, const char *caller ); 00296 void Guess_unknowns( WN *wn_root, const char *caller ); 00297 FB_VERIFY_STATUS Verify_frequencies() const; 00298 void Patch_whirl_frequencies() const; 00299 00300 void Print( FILE *fp ) const; 00301 void Print_node( FILE *fp, FB_NODEX nx ) const; 00302 void Print_edge( FILE *fp, FB_NODEX src_nx, FB_NODEX dst_nx ) const; 00303 void Draw() const; 00304 }; 00305 00306 void dV_view_fb_cfg(const FB_CFG& cfg, WN *root_wn, const char *caller); 00307 00308 #endif