00001 /* 00002 * Copyright 2003, 2004, 2005, 2006 PathScale, Inc. All Rights Reserved. 00003 */ 00004 00005 /* 00006 00007 Copyright (C) 2000, 2001 Silicon Graphics, Inc. All Rights Reserved. 00008 00009 This program is free software; you can redistribute it and/or modify it 00010 under the terms of version 2 of the GNU General Public License as 00011 published by the Free Software Foundation. 00012 00013 This program is distributed in the hope that it would be useful, but 00014 WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00016 00017 Further, this software is distributed without any warranty that it is 00018 free of the rightful claim of any third person regarding infringement 00019 or the like. Any license provided herein, whether implied or 00020 otherwise, applies only to this software file. Patent licenses, if 00021 any, provided herein do not apply to combinations of this program with 00022 other software, or any other product whatsoever. 00023 00024 You should have received a copy of the GNU General Public License along 00025 with this program; if not, write the Free Software Foundation, Inc., 59 00026 Temple Place - Suite 330, Boston MA 02111-1307, USA. 00027 00028 Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pky, 00029 Mountain View, CA 94043, or: 00030 00031 http://www.sgi.com 00032 00033 For further information regarding this notice, see: 00034 00035 http://oss.sgi.com/projects/GenInfo/NoticeExplan 00036 00037 */ 00038 00039 00040 // 00041 // Hyperblock formation module 00042 // 00044 // 00045 // Description: 00046 // 00047 // This module implements an algorithm to choose hyperblocks from 00048 // multiple control flow paths in a program unit. The algorithm 00049 // attempts to choose only those paths that can be profitably 00050 // executed together (as opposed to full if-conversion). The 00051 // algorithm is largely the same as that proposed by Scott Malke 00052 // in his PhD thesis (section 7.2). We diverge from it primarily 00053 // in the fact that we do not tail duplicate unconditionally, and 00054 // we modify the path priority algorithms if we are dealing with 00055 // statically generated frequency data. Here is a brief overview 00056 // of the algorithm: 00057 // 00058 // 1. Identify hyperblock candidates - select regions of the CFG 00059 // that might be profitably converted into hyperblocks. 00060 // 00061 // 2. Coalesce backedges - only acyclic graphs can be if converted, 00062 // so we make all backedges in a loop body branch to a single 00063 // block with an unconditional branch to the loop head (physically, 00064 // this step currently happens during step 1 above). 00065 // 00066 // 3. Block selection - use heuristics to select blocks for inclusion 00067 // in the hyperblock on a per path basis (I.e. blocks are not 00068 // considered individually). 00069 // 00070 // 4. Tail duplication - side entrances to the hyperblock are not 00071 // allowed, so we must duplicate blocks to remove them. 00072 // 00073 // 5. If conversion - removal of branches, insertion of predicate 00074 // calculations, and modification of instructions to predicated 00075 // forms. 00076 // 00077 // 00078 // Exported types: 00079 // 00080 // HYPER_BLOCK: structure describing a hyperblock. 00081 // 00082 // entry - entry block. 00083 // flags - informational flags on hyperblock. 00084 // blocks - set of bb's making up the hyperblock. Even though 00085 // a hyperblock is logically one block with possibly 00086 // multiple exits, we still break it into basic blocks 00087 // at the exit branches. Otherwise, its just too hard 00088 // for other CG components to deal with. 00089 // 00090 // 00091 // Exported globals: 00092 // HB_bb_map 00093 // Maps bb's to hyperblocks. Not valid until after block selection. 00094 // 00095 // Exported functions: 00096 // 00097 // void HB_Form_Hyperblocks(RID* rid, const BB_REGION& bb_region) 00098 // Driver routine for hyperblock formation. 00099 // 00100 // BB* HB_Entry(HB* hb) 00101 // void HB_Entry_Set(HB* hb, BB* entry) 00102 // BB* HB_Exit(HB* hb) 00103 // void HB_Exit_Set(HB* hb, BB* entry) 00104 // Return/Set entry/exit block for a given hyperblock. 00105 // 00106 // BB* HB_Fall_Thru_Exit(HB* hb) 00107 // void HB_Fall_Thru_Exit_Set(HB* hb, BB* fall_thru_exit 00108 // Return/Set block that the hyperblock may fall thru to if it 00109 // does not take a side exit. This is, more or less, the "join" 00110 // point where control flow comes back together at the bottom 00111 // of the region of blocks chosen for hyperblock formation. It 00112 // may not exist for all hyperblocks, and there is no requirement 00113 // that the hyperblock actually fall thru into it (from the hyperblocks 00114 // perspective it can, but it may have multiple blocks that target 00115 // it). This block will terminate every path in the hyperblock for 00116 // the purposes of calculating costs, but will not actually be 00117 // included in the hyperblock itself. 00118 // 00119 // BB_SET* HB_Blocks(HB* hb) 00120 // void HB_Blocks_Set(HB* hb, BB_SET* bbs) 00121 // void HB_Blocks_Copy(HB* hb, BB_SET* bbs) 00122 // Return/Set/Copy BB_SET of BBs in the hyperblock. 00123 // 00124 // void HB_Add_Block(HB* hb, BB* bb) 00125 // void HB_Remove_Block(HB* hb, BB* bb) 00126 // void HB_Add_BB_SET(HB* hb, BB* bb, MEM_POOL* pool) 00127 // void HB_Intersect_BB_SET(hb, BB_SET* bb_set) 00128 // Manipulate contents of bb_set representing the hyperblock. 00129 // Doesn't touch HB_bb_map. We provide these so that we can 00130 // use the HB structure to represent potential hyperblocks. 00131 // 00132 // void HB_Replace_Block(HB* hb, BB* old_bb,new_bb) 00133 // Replace old_bb with new_bb in the hyperblock. Also update HB_bb_map. 00134 // 00135 // void HB_Add_Block_And_Map(HB* hb, BB* bb) 00136 // void HB_Remove_Block_And_Map(HB* hb, BB* bb) 00137 // Add/remove a block to bit set and adjust map. 00138 // 00139 // 00140 // BOOL HB_Contains_Block(HB* hb, BB* bb) 00141 // Returns true if a block is part of a given hyperblock. 00142 // 00143 // void HB_Add_BBs_And_Map(HB* hb, BB_SET* bbset) 00144 // void HB_Copy_BBs_And_Map(HB* hb, BB_SET* bbset) 00145 // Add/copy bb's in set to a hyperblock and set up map 00146 // 00147 // void HB_Remove_Map(HB* hb) 00148 // Remove map for all blocks in a partially formed hyperblock that 00149 // has been discarded. 00150 // 00151 // INT HB_Flags(HB* hb) 00152 // BOOL HB_Flags_Check(HB* hb, INT flag) 00153 // void HB_Flags_Set(HB* hb, INT flag) 00154 // void HB_Flags_Clear(HB* hb) 00155 // Access flags field of hyperblock. 00156 // 00157 // HB_Predecessor_Count(HB* hb, BB_MAP& predecessor_count) 00158 // Utility routine to make a map that contains a count of all 00159 // of the predecessors of a block within the hyperblock. 00160 // 00161 // BB * Force_If_Convert(BB_REGION& bb_region) 00162 // Fully if-convert a region, if possible. If the conversion happened, the single resulting 00163 // BB is returned. If it did not happen, NULL is returned. 00164 // 00165 // void HB_Remove_Deleted_Blocks(void) 00166 // remove all deleted blocks from the HB_list list. To be run before trying to schedule. 00167 // 00168 // void Get_HB_Blocks_List(list<BB *> &blocks, HB* hb) 00169 // fill in a list of BB's from a hyperblock. 00170 // 00171 // void Setup_HB_bb_map(void) 00172 // recreate the BB->HB mapping 00175 00176 #ifndef HB_H_INCLUDED 00177 #define HB_H_INCLUDED 00178 00179 #include <list> 00180 #include "bb.h" 00181 #include "findloops.h" 00182 00183 // 00184 // Some typedefs to make using STL lists easier 00185 // 00186 typedef std::list<BB*> HB_bb_list; 00187 00189 // 00190 // Hyperblock list structure. 00191 // 00193 00194 struct HB { 00195 BB* entry; 00196 BB* exit; 00197 BB* fall_thru_exit; 00198 HB_bb_list block_list; 00199 BB_SET* blocks; 00200 INT8 flags; 00201 public: 00202 void Print(void); 00203 }; 00204 00205 extern BB_MAP HB_bb_map; 00206 00208 // 00209 // Hyperblock flags. 00210 // 00212 #define HB_LOOP_FLAG 0x0001 00213 #define HB_ERASE_FLAG 0x0002 00214 #define HB_SEEN_FLAG 0x0004 00215 00217 inline INT 00218 HB_Flags(HB* hb) 00220 // See interface description. 00222 { 00223 return hb->flags; 00224 } 00225 00227 inline void 00228 HB_Flags_Clear(HB* hb) 00230 // See interface description. 00232 { 00233 hb->flags = 0; 00234 } 00235 00237 inline BOOL 00238 HB_Flags_Check(HB* hb, INT flag) 00240 // See interface description. 00242 { 00243 return hb->flags & flag; 00244 } 00245 00247 inline void 00248 HB_Flags_Set(HB* hb, INT flag) 00250 // See interface description. 00252 { 00253 hb->flags |= flag; 00254 } 00255 00257 inline BB* 00258 HB_Entry(HB* hb) 00260 // See interface description. 00262 { 00263 return hb->entry; 00264 } 00265 00267 inline void 00268 HB_Entry_Set(HB* hb, BB* entry) 00270 // See interface description. 00272 { 00273 hb->entry = entry; 00274 } 00275 00276 00278 inline BB* 00279 HB_Exit(HB* hb) 00281 // See interface description. 00283 { 00284 return hb->exit; 00285 } 00286 00288 inline void 00289 HB_Exit_Set(HB* hb, BB* exit) 00291 // See interface description. 00293 { 00294 hb->exit = exit; 00295 } 00296 00298 inline BB* 00299 HB_Fall_Thru_Exit(HB* hb) 00301 // See interface description. 00303 { 00304 return hb->fall_thru_exit; 00305 } 00306 00308 inline void 00309 HB_Fall_Thru_Exit_Set(HB* hb, BB* fall_thru_exit) 00311 // See interface description. 00313 { 00314 hb->fall_thru_exit = fall_thru_exit; 00315 } 00316 00318 inline BB_SET* 00319 HB_Blocks(HB* hb) 00321 // See interface description. 00323 { 00324 return hb->blocks; 00325 } 00326 00328 inline void 00329 HB_Blocks_Set(HB* hb, BB_SET* bb_set) 00331 // See interface description 00333 { 00334 hb->blocks = bb_set; 00335 } 00336 00338 inline void 00339 HB_Blocks_Copy(HB* hb, BB_SET* bb_set) 00341 // See interface description 00343 { 00344 hb->blocks = BB_SET_Copy(bb_set, &MEM_pu_pool); 00345 } 00346 00348 inline void 00349 HB_Add_Block(HB* hb, BB* bb) 00351 // See interface description. 00353 { 00354 hb->blocks = BB_SET_Union1D(HB_Blocks(hb), bb, &MEM_pu_pool); 00355 } 00356 00358 inline void 00359 HB_Add_Block_And_Map(HB* hb, BB* bb) 00361 // See interface description. 00363 { 00364 hb->blocks = BB_SET_Union1D(HB_Blocks(hb), bb, &MEM_pu_pool); 00365 BB_MAP_Set(HB_bb_map, bb, hb); 00366 } 00367 00368 00370 inline void 00371 HB_Add_BB_SET(HB* hb, BB_SET* bb_set, MEM_POOL* pool) 00373 // See interface description. 00375 { 00376 hb->blocks = BB_SET_UnionD(HB_Blocks(hb), bb_set, pool); 00377 } 00378 00380 inline void 00381 HB_Intersect_BB_SET(HB* hb, BB_SET* bb_set) 00383 // See interface description. 00385 { 00386 hb->blocks = BB_SET_IntersectionD(HB_Blocks(hb), bb_set); 00387 } 00388 00390 inline void 00391 HB_Remove_Block(HB* hb, BB* bb) 00393 // See interface description. 00395 { 00396 hb->blocks = BB_SET_Difference1D(HB_Blocks(hb), bb); 00397 } 00398 00400 inline void 00401 HB_Remove_Blocks(HB* hb, BB_SET* bbs) 00403 // See interface description. 00405 { 00406 hb->blocks = BB_SET_DifferenceD(hb->blocks, bbs); 00407 } 00408 00410 inline void 00411 HB_Remove_Block_And_Map(HB* hb, BB* bb) 00413 // See interface description. 00415 { 00416 hb->blocks = BB_SET_Difference1D(HB_Blocks(hb), bb); 00417 BB_MAP_Set(HB_bb_map, bb, NULL); 00418 } 00419 00421 inline BOOL 00422 HB_Contains_Block(HB* hb, BB* bb) 00424 // See interface description. 00426 { 00427 return BB_SET_MemberP(HB_Blocks(hb), bb); 00428 } 00429 00430 00431 void Get_HB_Blocks_List(std::list<BB *> &blocks, HB* hb); 00432 00434 inline void 00435 HB_Remove_Map(HB* hb) 00437 // See interface description. 00439 { 00440 BB* bb; 00441 FOR_ALL_BB_SET_members(HB_Blocks(hb), bb) { 00442 BB_MAP_Set(HB_bb_map, bb, NULL); 00443 } 00444 } 00445 00446 inline HB_bb_list * HB_Blocks_List(HB *hb) 00447 { 00448 return &(hb->block_list); 00449 } 00450 00451 extern HB* HB_Alloc(MEM_POOL* pool); 00452 00453 extern void HB_Init(void); 00454 extern void HB_Form_Hyperblocks(RID* rid, const BB_REGION& bb_region); 00455 // 00456 // Some typedefs to make using STL lists easier 00457 // 00458 typedef std::list<BB*> HB_bb_list; 00459 00460 extern void HB_Predecessor_Count(HB* hb, BB_MAP& predecessor_count); 00461 00462 extern void HB_Add_BBs_And_Map(HB* hb, BB_SET* bbset); 00463 extern void HB_Copy_BBs_And_Map(HB* hb, BB_SET* bbset); 00464 00465 extern MEM_POOL MEM_HB_pool; 00466 00467 extern std::list<HB *> HB_list; 00468 00469 extern float HB_minimum_priority; 00470 00471 // 00472 // Used to control whether or not we update liveness information on a 00473 // per hyperblock basis. There are some problems with the current 00474 // interface to the liveness routines in that they don't deal well 00475 // with the "messy" sort of regions that we want analyzed (i.e. the 00476 // exit blocks reenter the region). For now, we're updating for the 00477 // whole PU. 00478 // 00479 extern BOOL HB_do_local_liveness; 00480 00481 // 00482 // Do we allow any tail duplication to happen at all? 00483 // 00484 extern BOOL HB_allow_tail_duplication; 00485 00486 extern BOOL HB_did_tail_duplication; 00487 00488 00490 // BB * Force_If_Convert(LOOP_DESCR *loop, BOOL allow_multi_bb) 00491 // Fully if-convert a region, if possible. If the conversion happened, the 00492 // single resulting BB is returned. If it did not happen, NULL is returned. 00493 // If allow_multi_bb is true, if-conversion is performed if possible, even 00494 // if multiple BB's will be produced. 00496 00497 extern BB * Force_If_Convert(LOOP_DESCR *loop, BOOL allow_multi_bb); 00498 00499 extern void HB_Remove_Deleted_Blocks(void); 00500 00501 extern void Setup_HB_bb_map(void); 00502 00503 #endif 00504 #ifdef KEY 00505 extern BOOL hammock_region; 00506 #endif
1.5.6