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 // During instrumentation, certain events associated with program 00044 // control flow (such as the number of times a particular branch is 00045 // taken, or not taken) are counted. During subsequent compilations, 00046 // this data may be retrieved and used to guide optimization decisions. 00047 // 00048 // fb_whirl.h and fb_whirl.cxx define data structures and functions to 00049 // manipulate this feedback information. 00050 // 00051 // When initially retrieved from the file of instrumentation data, 00052 // frequencies count the number of times that certain events occurred 00053 // during execution. 00054 // 00055 // Some whirl transformations require frequency values to be scaled 00056 // or estimated. Consequently, these values may not always be exact 00057 // or even compatible. 00058 // 00059 // ==================================================================== 00060 // ==================================================================== 00061 00062 #ifndef fb_whirl_INCLUDED 00063 #define fb_whirl_INCLUDED 00064 00065 #include "fb_info.h" 00066 #include "mempool_allocator.h" 00067 #ifndef wn_INCLUDED 00068 #include "wn.h" 00069 #endif 00070 00071 #include <vector> 00072 00073 using namespace std; 00074 00075 #ifndef instr_reader_INCLUDED 00076 #include "instr_reader.h" 00077 #endif 00078 00079 00080 // ==================================================================== 00081 // Tracing masks for TP_FEEDBACK tracing phase 00082 // ==================================================================== 00083 00084 #define TP_FEEDBACK_WN 0x0001 00085 #define TP_FEEDBACK_WN_DRAW 0x0002 00086 #define TP_FEEDBACK_CFG 0x0010 00087 #define TP_FEEDBACK_CFG_DRAW 0x0020 00088 #define TP_FEEDBACK_CFG_BEFORE 0x0040 00089 #define TP_FEEDBACK_CFG_PROP 0x0080 00090 #define TP_OPT_FEEDBACK 0x0100 00091 #define TP_OPT_FEEDBACK_DRAW 0x0200 00092 #define TP_OPT_FEEDBACK_BEFORE 0x0400 00093 #define TP_OPT_FEEDBACK_PROP 0x0800 00094 #define TP_CG_FEEDBACK 0x1000 00095 #define TP_CG_FEEDBACK_DRAW 0x2000 00096 00097 00098 // ==================================================================== 00099 00100 // FEEDBACK::Verify(...) and OPT_FEEDBACK::Verify(...) return one of 00101 // the following values. "UNBALANCED" means that some of the frequency 00102 // values are UNKNOWN or do not add up, and "INVALID" indicates the 00103 // presence of UNINITialized or ERROR frequencies. 00104 00105 enum FB_VERIFY_STATUS { 00106 FB_VERIFY_CONSISTENT, 00107 FB_VERIFY_UNBALANCED, 00108 FB_VERIFY_INVALID 00109 }; 00110 00111 // ==================================================================== 00112 00113 class FEEDBACK { 00114 private: 00115 00116 MEM_POOL *_m; 00117 WN_MAP_TAB *_maptab; 00118 WN *_root_wn; 00119 bool _trace; // Get_Trace(TP_FEEDBACK, TP_FEEDBACK_WN) 00120 bool _trace_draw; // Get_Trace(TP_FEEDBACK, TP_FEEDBACK_WN_DRAW) 00121 00122 // For Whirl nodes, the map WN_MAP_FEEDBACK holds an index into 00123 // one of the following vectors: 00124 00125 vector< FB_Info_Invoke, mempool_allocator<FB_Info_Invoke> > _invokes; 00126 vector< FB_Info_Branch, mempool_allocator<FB_Info_Branch> > _branches; 00127 vector< FB_Info_Loop, mempool_allocator<FB_Info_Loop> > _loops; 00128 vector< FB_Info_Circuit, mempool_allocator<FB_Info_Circuit> > _circuits; 00129 vector< FB_Info_Call, mempool_allocator<FB_Info_Call> > _calls; 00130 vector< FB_Info_Switch, mempool_allocator<FB_Info_Switch> > _switches; 00131 00132 INT32 Get_index_invoke ( const WN *wn ) const; 00133 INT32 Get_index_branch ( const WN *wn ) const; 00134 INT32 Get_index_loop ( const WN *wn ) const; 00135 INT32 Get_index_circuit ( const WN *wn ) const; 00136 INT32 Get_index_call ( const WN *wn ) const; 00137 INT32 Get_index_switch ( const WN *wn ) const; 00138 00139 INT32 Add_index_invoke ( WN *wn ); 00140 INT32 Add_index_branch ( WN *wn ); 00141 INT32 Add_index_loop ( WN *wn ); 00142 INT32 Add_index_circuit ( WN *wn ); 00143 INT32 Add_index_call ( WN *wn ); 00144 INT32 Add_index_switch ( WN *wn ); 00145 00146 public: 00147 00148 FEEDBACK( WN *wn, MEM_POOL *m, 00149 INT32 invoke_size = 1, 00150 INT32 branch_size = 1, 00151 INT32 loop_size = 1, 00152 INT32 circuit_size = 1, 00153 INT32 call_size = 1, 00154 INT32 switch_size = 1, 00155 WN_MAP_TAB *maptab = Current_Map_Tab ); 00156 00157 void Reset_Root_WN( WN *root_wn ) { _root_wn = root_wn; } 00158 00159 bool Same_in_out( const WN *wn ); 00160 void FB_set_in_out_same_node( WN *wn ); 00161 void FB_set_in_out_same( WN *wn ); 00162 00163 void Print ( FILE *fp, const WN *wn ) const; 00164 void Print_with_wn ( FILE *fp, WN *wn ) const; 00165 00166 const FB_Info_Invoke& Query_invoke ( const WN *wn ) const; 00167 const FB_Info_Branch& Query_branch ( const WN *wn ) const; 00168 const FB_Info_Loop& Query_loop ( const WN *wn ) const; 00169 const FB_Info_Circuit& Query_circuit ( const WN *wn ) const; 00170 const FB_Info_Call& Query_call ( const WN *wn ) const; 00171 const FB_Info_Switch& Query_switch ( const WN *wn ) const; 00172 00173 FB_FREQ Query ( const WN *wn, const FB_EDGE_TYPE type ) const; 00174 FB_FREQ Query_prob ( const WN *wn, const FB_EDGE_TYPE type ) const; 00175 FB_FREQ Query_total_out ( const WN *wn ) const; 00176 00177 void Annot_invoke ( WN *wn, const FB_Info_Invoke & fb_info ); 00178 void Annot_branch ( WN *wn, const FB_Info_Branch & fb_info ); 00179 void Annot_loop ( WN *wn, const FB_Info_Loop & fb_info ); 00180 void Annot_circuit ( WN *wn, const FB_Info_Circuit& fb_info ); 00181 void Annot_call ( WN *wn, const FB_Info_Call & fb_info ); 00182 void Annot_switch ( WN *wn, const FB_Info_Switch & fb_info ); 00183 00184 void Annot ( WN *wn, const FB_EDGE_TYPE type, FB_FREQ freq ); 00185 00186 // Resets feedback info to FB_FREQ_UNINIT; use when wn is deleted 00187 void Delete(WN *wn) { 00188 IPA_WN_MAP32_Set ( _maptab, WN_MAP_FEEDBACK, wn, 0 ); 00189 } 00190 00191 FB_VERIFY_STATUS Verify( const char *caller = NULL, 00192 bool abort_if_error = TRUE ) const; 00193 00194 FB_VERIFY_STATUS Verify_and_guess( const char *caller = NULL, 00195 bool abort_if_error = TRUE ) const; 00196 00197 // Feedback info in CG is carried by code-gen internal structures. 00198 // Verification for CG feedback info done apart from FEEDBACK class. 00199 00200 // Lower feedback info 00201 00202 void FB_lower_branch ( WN *wn_br, WN *wn_branch ); 00203 void FB_lower_circuit ( WN *wn_cand, WN *wn_left_br, WN *wn_right_br ); 00204 void FB_factor_circuit( WN *wn_left, WN *wn_right, 00205 WN *wn_outer, WN *wn_inner ); 00206 00207 void FB_lower_loop ( WN *wn_loop, WN *wn_top_br, WN *wn_back_br ); 00208 void FB_lower_loop_alt ( WN *wn_loop, WN *wn_top_br ); 00209 void FB_lower_while_do_to_do_while ( WN *wn_loop, WN *wn_top_br ); 00210 00211 void FB_lower_compgoto ( WN *wn_compgoto, WN *wn_xgoto, WN *wn_branch ); 00212 00213 void FB_lower_call ( WN *wn_call, WN *wn_new_call ); 00214 void FB_lower_return_val ( WN *wn_return_val, WN *wn_return ); 00215 00216 void FB_lower_mstore_to_loop ( WN *wn_mstore, WN *wn_loop, INT64 nMoves ); 00217 00218 // Goto conversion 00219 00220 void FB_move_goto_out( WN *wn_branch, WN *wn_inner_br, WN *wn_outer_br ); 00221 void FB_convert_goto_to_if( WN *wn_branch, WN *wn_if ); 00222 void FB_convert_goto_to_loop( WN *wn_branch, WN *wn_loop ); 00223 00224 void FB_simplify_branch_to_goto( WN *wn_branch ); 00225 00226 // Cloning (clone freq = original freq * scale; original reduced by same) 00227 void FB_set_zero_node( WN *wn ); 00228 void FB_set_zero( WN *wn ); 00229 void FB_set_unknown_node( WN *wn ); 00230 void FB_set_unknown( WN *wn ); 00231 void FB_scale_node( WN *wn, FB_FREQ freq_scale ); 00232 void FB_scale( WN *wn, FB_FREQ freq_scale ); 00233 void FB_duplicate_node( WN *wn_origl, WN *wn_clone ); 00234 void FB_duplicate( WN *wn_origl, WN *wn_clone ); 00235 void FB_recombine_node( WN *wn_origl, WN *wn_clone ); 00236 void FB_recombine( WN *wn_origl, WN *wn_clone ); 00237 void FB_clone_node( WN *wn_origl, WN *wn_clone, FB_FREQ freq_scale ); 00238 void FB_clone( WN *wn_origl, WN *wn_clone, FB_FREQ freq_scale ); 00239 00240 private: 00241 void FB_clone_test( WN *wn_origl, WN *wn_clone, 00242 FB_FREQ freq_origl_taken, FB_FREQ freq_origl_not, 00243 FB_FREQ freq_clone_taken, FB_FREQ freq_clone_not ); 00244 public: 00245 void FB_clone_loop_test( WN *wn_origl, WN *wn_clone, WN *wn_loop ); 00246 00247 void Display_FB_CFG_From_Whirl(const char *caller = NULL); 00248 00249 // IPA interface 00250 00251 friend void FB_IPA_Clone_node( 00252 FEEDBACK *feedback_origl, FEEDBACK *feedback_clone, 00253 WN *wn_origl, WN *wn_clone, 00254 FB_FREQ freq_scale ); 00255 00256 friend void FB_IPA_Clone( FEEDBACK *feedback_origl, FEEDBACK *feedback_clone, 00257 WN *wn_origl, WN *wn_clone, 00258 FB_FREQ freq_scale ); 00259 00260 friend void FB_IPA_Clone( FEEDBACK *feedback_origl, FEEDBACK *feedback_clone, 00261 WN *wn_origl, WN *wn_clone, 00262 float scale ) { 00263 FB_IPA_Clone( feedback_origl, feedback_clone, wn_origl, wn_clone, 00264 FB_FREQ( scale, false ) ); 00265 } 00266 00267 friend void FB_IPA_Inline(FEEDBACK *feedback_origl, FEEDBACK *feedback_clone, 00268 WN *wn_origl, WN *wn_clone, 00269 FB_FREQ freq_scale ); 00270 00271 // Transfer FB from one PU to another, for MP lowerer 00272 00273 friend void FB_Transfer_node( 00274 FEEDBACK *feedback_origl, FEEDBACK *feedback_new, 00275 WN *wn); 00276 00277 friend void FB_Transfer(FEEDBACK *feedback_origl, FEEDBACK *feedback_new, 00278 WN *wn); 00279 00280 }; 00281 00282 extern "C" void dump_fb ( const FEEDBACK *feedback, const WN *wn ); 00283 00284 extern FEEDBACK *Cur_PU_Feedback; 00285 00286 extern INT 00287 Convert_Feedback_Info (const FEEDBACK* fb, const WN* tree, 00288 PU_Profile_Handle& pu_handle); 00289 00290 extern void 00291 Read_Feedback_Info (FEEDBACK* fb, WN* tree, const Pu_Hdr& pu_hdr); 00292 00293 // scale is portion of freq transfered to clone; original gets (1 - scale) 00294 00295 #ifdef __cplusplus 00296 extern "C" { 00297 #endif 00298 00299 void FB_old_Annotate_whirl(WN *); // remove when new scheme ready .. 00300 00301 #ifdef __cplusplus 00302 } 00303 #endif 00304 00305 #define FB_DEVWARN_LIMIT 5 00306 00307 #endif