Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
fb_whirl.h
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines