Author: dcoakley Date: 2011-05-26 16:15:16 -0400 (Thu, 26 May 2011) New Revision: 3629
Modified: trunk/osprey/be/cg/cflow.cxx trunk/osprey/be/cg/eh_region.cxx trunk/osprey/be/vho/vho_lower.cxx trunk/osprey/common/com/config.cxx trunk/osprey/common/com/config.h trunk/osprey/common/com/config_opt.cxx trunk/osprey/common/com/symtab_access.h trunk/osprey/common/com/symtab_defs.h Log: Enable CFLOW optimization within some EH regions. Allow CG control flow optimization to reorder BB's inside of EH regions by updating EH region information for each BB when performing transformations. Previously, CFLOW would simply skip all BB's of any EH region in Optimize_Cyclic_Chain. To make room for CFLOW optimization, in VHO simple EH regions are merged into larger simple EH regions. Here, a simple EH region is an EH region with no real catch blocks or cleanup. Approved by: Jian-Xin Lai Modified: trunk/osprey/be/cg/cflow.cxx =================================================================== --- trunk/osprey/be/cg/cflow.cxx 2011-05-25 14:53:17 UTC (rev 3628) +++ trunk/osprey/be/cg/cflow.cxx 2011-05-26 20:15:16 UTC (rev 3629) @@ -231,6 +231,7 @@ struct vargoto_info v; } u; mUINT16 eh_rgn; /* exc handling region number */ + mUINT16 pseudo_eh_rgn; mBOOL cold; /* part of cold region */ INT nsuccs; /* number of successors */ struct succedge succs[BBINFO_NSUCCS]; /* successor edges; we dynamically @@ -246,6 +247,8 @@ #define Set_BBINFO_kind(b,k) (BB_BBINFO(b)->kind=(k)) #define BBINFO_eh_rgn(b) (BB_BBINFO(b)->eh_rgn+0) #define Set_BBINFO_eh_rgn(b, e) (BB_BBINFO(b)->eh_rgn=(e)) +#define BBINFO_pseudo_eh_rgn(b) (BB_BBINFO(b)->pseudo_eh_rgn+0) +#define Set_BBINFO_pseudo_eh_rgn(b, e) (BB_BBINFO(b)->pseudo_eh_rgn=(e)) #define BBINFO_cold(b) (BB_BBINFO(b)->cold+0) #define Set_BBINFO_cold(b, e) (BB_BBINFO(b)->cold=(e)) #define BBINFO_nsuccs(b) (BB_BBINFO(b)->nsuccs+0) @@ -1787,6 +1790,8 @@ * points to unused link list elements */ INT eh_rgn; /* The current EH region ID */ + INT prev_eh_rgn = -2; + INT pseudo_eh_rgn = -1; INT eh_id; /* Highest EH region ID used */ BB *bb; @@ -1866,6 +1871,11 @@ /* Set the exception region ID for this block. */ bbinfo->eh_rgn = eh_rgn; + if (eh_rgn != prev_eh_rgn) { + prev_eh_rgn = eh_rgn; + pseudo_eh_rgn++; + } + bbinfo->pseudo_eh_rgn = pseudo_eh_rgn; /* Determine if BB is in cold region or not. We cache this in * the BB-info rather than overload BB_local_flag1 since cflow @@ -5423,18 +5433,30 @@ * Exception regions are similar except that the created chain need * only consist of the BBs in the same or nested exception region. */ - Is_True(BB_rid(bb) == first_rid, - ("region nesting botched at BB:%d", BB_id(bb))); next_bb = BB_next(tail); - while ( next_bb - && ((BB_rid(next_bb) != first_rid) - || (BBINFO_eh_rgn(tail) && BBINFO_eh_rgn(next_bb))) - ) { - do { - tail = next_bb; - BB_MAP_Set(chain_map, tail, chains); - next_bb = BB_next(tail); - } while (next_bb && BB_rid(tail) != first_rid); + if (Optimize_exception_ranges != 2 && + !(Optimize_exception_ranges == 1 && PU_cxx_lang(Get_Current_PU()))) { + // if the next BB is of different REGION, put them into a chain + while (next_bb && + ((BB_rid(next_bb) != first_rid) || + (BBINFO_eh_rgn(tail) && BBINFO_eh_rgn(next_bb))) + ) { + do { + tail = next_bb; + BB_MAP_Set(chain_map, tail, chains); + next_bb = BB_next(tail); + } while (next_bb && BB_rid(tail) != first_rid); + } + } else if (!PU_simple_eh(Get_Current_PU())) { + while (TRUE) { + if (next_bb && + (BB_rid(next_bb) != BB_rid(tail) || + BBINFO_pseudo_eh_rgn(next_bb) != BBINFO_pseudo_eh_rgn(tail))) { + tail = next_bb; + BB_MAP_Set(chain_map, next_bb, chains); + next_bb = BB_next(tail); + } else break; + } } /* Isolate the new chain. @@ -5518,6 +5540,7 @@ Weight_Succ_Chains(BB_MAP chain_map, BBCHAIN *chain) { BB *bb; + mINT16 last_rgn = BBINFO_pseudo_eh_rgn(chain->tail); /* The successors of 'chain' are the successors of the BBs in 'chain'. */ @@ -6052,7 +6075,12 @@ while (unordered) { BBCHAIN *ch; double max_weight; + BOOL eh_succ; + BOOL eh_continue; + mINT32 last_eh; + last_eh = BBINFO_pseudo_eh_rgn(last_ordered->tail); + /* Adjust the weights for the edges from the last ordered chain * to the unordered chains. */ @@ -6062,11 +6090,26 @@ * normal BBs over those with a NEVER freq hint. */ max_weight = unordered->weight; + eh_succ = (BBINFO_pseudo_eh_rgn(unordered->head) == last_eh); + eh_continue = (BBINFO_pseudo_eh_rgn(unordered->tail) == last_eh); + chain = unordered; for (ch = unordered->next; ch; ch = ch->next) { - if ( (ch->never == chain->never && ch->weight > max_weight) - || (!ch->never && chain->never)) + BOOL my_succ = (BBINFO_pseudo_eh_rgn(ch->head) == last_eh); + BOOL my_continue = (BBINFO_pseudo_eh_rgn(ch->tail) == last_eh); + if (eh_succ && !my_succ) + continue; + if (eh_continue && !my_continue) + continue; + if ((my_succ && !eh_succ) || (my_continue && !eh_continue)) { + eh_succ = my_succ; + eh_continue = my_continue; + chain = ch; + max_weight = ch->weight; + } else if ((ch->never == chain->never && ch->weight > max_weight) || + (!ch->never && chain->never)) + { chain = ch; max_weight = ch->weight; } @@ -6151,6 +6194,7 @@ } +static void Print_Chain_BBs(BBCHAIN *chain); /* ==================================================================== * * Optimize_Cyclic_Chain @@ -6193,8 +6237,14 @@ /* Can't place the tail in the middle of an EH region -- * the EH region must be kept contiguous and in the same order. */ - if (BBINFO_eh_rgn(bb) && BBINFO_eh_rgn(next)) continue; + if ((Optimize_exception_ranges != 2 && + !(PU_cxx_lang(Get_Current_PU())) && Optimize_exception_ranges == 1) + && BBINFO_eh_rgn(bb) && BBINFO_eh_rgn(next)) continue; + if (BBINFO_pseudo_eh_rgn(bb) != BBINFO_pseudo_eh_rgn(next) || + BBINFO_pseudo_eh_rgn(bb) != BBINFO_pseudo_eh_rgn(chain->tail) || + BBINFO_pseudo_eh_rgn(bb) != BBINFO_pseudo_eh_rgn(chain->head)) continue; + /* Can't place the tail such that the new head and tail BBs * would not be in the same region as originally. */ @@ -6291,6 +6341,7 @@ fprintf(TFile, " BB:%d would be a better head of cyclic chain than BB:%d\n", BB_id(best_head), BB_id(orig_head)); + Print_Chain_BBs(chain); } Chain_BBs(NULL, best_head); Chain_BBs(best_tail, NULL); @@ -6351,6 +6402,9 @@ * another, then combine the chains. */ if ((can_combine) && + BBINFO_pseudo_eh_rgn(succ) == BBINFO_pseudo_eh_rgn(pred) && + (BBINFO_pseudo_eh_rgn(succ) == BBINFO_pseudo_eh_rgn(schain->tail) || + BBINFO_pseudo_eh_rgn(pred) == BBINFO_pseudo_eh_rgn(pchain->head)) && (pchain != schain && pchain->tail == pred && schain->head == succ)) { INT j; INT nsuccs; Modified: trunk/osprey/be/cg/eh_region.cxx =================================================================== --- trunk/osprey/be/cg/eh_region.cxx 2011-05-25 14:53:17 UTC (rev 3628) +++ trunk/osprey/be/cg/eh_region.cxx 2011-05-26 20:15:16 UTC (rev 3629) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009, 2011 Advanced Micro Devices, Inc. All Rights Reserved. + * Copyright (C) 2009-2011 Advanced Micro Devices, Inc. All Rights Reserved. */ /* @@ -2245,11 +2245,10 @@ #endif // KEY fix_mask_ranges(); - reorder_range_list(); #ifdef KEY flatten_regions(); - reorder_range_list(); #endif + reorder_range_list(); ST * st = ST_For_Range_Table(wn); eh_pu_range_st = st; Modified: trunk/osprey/be/vho/vho_lower.cxx =================================================================== --- trunk/osprey/be/vho/vho_lower.cxx 2011-05-25 14:53:17 UTC (rev 3628) +++ trunk/osprey/be/vho/vho_lower.cxx 2011-05-26 20:15:16 UTC (rev 3629) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2010 Advanced Micro Devices, Inc. All Rights Reserved. + * Copyright (C) 2009-2011 Advanced Micro Devices, Inc. All Rights Reserved. */ /* * Copyright 2003, 2004, 2005, 2006 PathScale, Inc. All Rights Reserved. @@ -5786,10 +5786,60 @@ return last; } +BOOL is_simple_eh_region(WN *wn) +{ + FmtAssert((WN_operator(wn) == OPR_REGION) && (WN_region_is_EH(wn)), ("It is not an EH region WN.")); + if (Optimize_exception_ranges == 0 || + (Optimize_exception_ranges == 1 && !PU_cxx_lang(Get_Current_PU()))) + return FALSE; + if (!WN_block_empty(WN_region_pragmas(wn))) + return FALSE; + if (!WN_block_empty(WN_region_exits(wn))) + return FALSE; + INITO_IDX init_idx = WN_ereg_supp (wn); + INITV_IDX initv = INITV_blk (INITO_val (init_idx)); + if (INITV_kind(initv) != INITVKIND_ZERO) + return FALSE; + return TRUE; +} + +BOOL are_all_simple_eh_regions(WN* root) +{ + BOOL met = FALSE; + if (Optimize_exception_ranges == 0 || + (Optimize_exception_ranges == 1 && !PU_cxx_lang(Get_Current_PU()))) + return FALSE; + // Iteration of all REGION is needed, the SCFIter is not used, + // as there can be comma EXPR in the VH WHIRL, so that SCFIter + // and StmtIter can not work properly. + for (WN_ITER* wn_walker = WN_WALK_TreeIter(root); + wn_walker != NULL; + wn_walker = WN_WALK_TreeNext(wn_walker)) { + WN *wn = WN_ITER_wn(wn_walker); + if ((WN_operator(wn) == OPR_REGION) && (WN_region_is_EH(wn))) { + if (is_simple_eh_region(wn)) + met = TRUE; + else + return FALSE; + } + } + return met; +} + +static int Enclosing_Simple_EH = 0; + static WN * vho_lower_region ( WN * wn, WN * block ) { - WN_region_body(wn) = vho_lower_block ( WN_region_body(wn) ); + BOOL is_simple_eh = FALSE; + if (WN_region_kind(wn) == REGION_KIND_EH && is_simple_eh_region(wn)) { + is_simple_eh = TRUE; + Enclosing_Simple_EH++; + WN_region_body(wn) = vho_lower_block ( WN_region_body(wn) ); + Enclosing_Simple_EH--; + } + else + WN_region_body(wn) = vho_lower_block ( WN_region_body(wn) ); INT region_id = WN_region_id(wn); if ((WN_region_kind(wn) == REGION_KIND_MP) && @@ -5888,6 +5938,14 @@ WN_INSERT_BlockLast (block, last); wn = NULL; // don't insert it again } + + if (Enclosing_Simple_EH != 0 && is_simple_eh) { + WN *p; + p = WN_region_body(wn); + WN_region_body(wn) = NULL; + WN_Delete(wn); + return p; + } return wn; } /* vho_lower_region */ #else @@ -6465,6 +6523,17 @@ } } /* vho_lower_check_labels */ +static void vho_lower_rename_region_id(WN * root) +{ + WN * wn; + for (WN_ITER* wni = WN_WALK_TreeIter(root); + wni != NULL; + wni = WN_WALK_TreeNext(wni)) { + wn = WN_ITER_wn(wni); + if (WN_operator(wn) == OPR_REGION) + WN_set_region_id(wn, New_Region_Id()); + } +} static void vho_lower_rename_labels_defined ( WN * wn ) @@ -7645,6 +7714,7 @@ if ( vho_lower_labels_defined ) vho_lower_rename_labels_defined ( test_block ); + vho_lower_rename_region_id ( test_block ); if ( VHO_Use_Do_While ) { @@ -8462,6 +8532,11 @@ #ifdef KEY current_pu_id ++; #endif + + if (are_all_simple_eh_regions(wn)) + Set_PU_simple_eh(Get_Current_PU()); + else + Clear_PU_simple_eh(Get_Current_PU()); /* See if we need to lower the pu */ if ( PU_has_very_high_whirl (Get_Current_PU ()) == FALSE @@ -8470,6 +8545,51 @@ return wn; } + if (PU_simple_eh(Get_Current_PU())) { + char * pu_name = ST_name(&St_Table[PU_Info_proc_sym(Current_PU_Info)]); + WN *region_body = WN_func_body(wn); + INITV_IDX initv_label = New_INITV(); + INITV_Set_ZERO (Initv_Table[initv_label], MTYPE_U4, 1); + INITV_IDX blk = New_INITV(); + INITV_Init_Block (blk, initv_label); + + INITV_IDX iv; + iv = New_INITV(); + INITV_Set_ZERO (Initv_Table[iv], MTYPE_U4, 1); + + Set_INITV_next (initv_label, iv); + + TY_IDX ty = MTYPE_TO_TY_array[MTYPE_U4]; + ST * ereg = Gen_Temp_Named_Symbol (ty, "ehpit", CLASS_VAR, + SCLASS_EH_REGION_SUPP); + Set_ST_is_initialized (*ereg); + Set_ST_is_not_used (*ereg); + INITO_IDX ereg_supp = New_INITO (ST_st_idx(ereg), blk); + WN * ehr = WN_CreateRegion (REGION_KIND_EH, region_body, + WN_CreateBlock(), WN_CreateBlock(), New_Region_Id(), ereg_supp); + WN_func_body(wn) = WN_CreateBlock(); + WN_INSERT_BlockFirst(WN_func_body(wn), ehr); + WN *preamble_end; + WN *eh_block = WN_region_body(ehr); + preamble_end = WN_first(eh_block); + while (preamble_end && + !(WN_operator(preamble_end) == OPR_PRAGMA && + WN_pragma(preamble_end) == WN_PRAGMA_PREAMBLE_END)) + preamble_end = WN_next(preamble_end); + if (preamble_end) { + WN *first,*p; + WN *func_body = WN_func_body(wn); + first = WN_first(eh_block); + WN_first(eh_block) = WN_next(preamble_end); + p = preamble_end; + while (p != NULL) { + preamble_end = WN_prev(p); + WN_INSERT_BlockFirst(func_body, p); + p = preamble_end; + } + } + } + WN_func_body(wn) = vho_lower_block ( WN_func_body(wn) ); if ( VHO_Recycle_Pregs ) Modified: trunk/osprey/common/com/config.cxx =================================================================== --- trunk/osprey/common/com/config.cxx 2011-05-25 14:53:17 UTC (rev 3628) +++ trunk/osprey/common/com/config.cxx 2011-05-26 20:15:16 UTC (rev 3629) @@ -1309,6 +1309,10 @@ OPT_Reorg_Common = TRUE; } + if ( ! Optimize_exception_ranges_set && Opt_Level == 0) { + Optimize_exception_ranges = 0; + } + if (Force_GP_Prolog) Force_Jalr = TRUE; #ifdef TARG_X8664 // Bug 1039 - align aggregates to 16-byte for all optimization levels Modified: trunk/osprey/common/com/config.h =================================================================== --- trunk/osprey/common/com/config.h 2011-05-25 14:53:17 UTC (rev 3628) +++ trunk/osprey/common/com/config.h 2011-05-26 20:15:16 UTC (rev 3629) @@ -593,6 +593,8 @@ extern BOOL CG_mem_intrinsics; extern BOOL Emulate_memset; extern INT32 CG_memmove_inst_count; +extern INT32 Optimize_exception_ranges; +extern BOOL Optimize_exception_ranges_set; extern BOOL CG_memmove_inst_count_overridden; extern BOOL CG_bcopy_cannot_overlap; extern BOOL CG_memcpy_cannot_overlap; Modified: trunk/osprey/common/com/config_opt.cxx =================================================================== --- trunk/osprey/common/com/config_opt.cxx 2011-05-25 14:53:17 UTC (rev 3628) +++ trunk/osprey/common/com/config_opt.cxx 2011-05-26 20:15:16 UTC (rev 3629) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2009 Advanced Micro Devices, Inc. All Rights Reserved. + * Copyright (C) 2008-2010 Advanced Micro Devices, Inc. All Rights Reserved. */ /* @@ -283,6 +283,8 @@ BOOL Outlining_Enabled = FALSE; BOOL Instrumentation_Enabled_Before = FALSE; +INT32 Optimize_exception_ranges = 1; +BOOL Optimize_exception_ranges_set = FALSE; #ifdef KEY INT32 OPT_Cyg_Instrument = 0; BOOL Asm_Memory = FALSE; @@ -885,6 +887,10 @@ 0, 0, 0, &LANG_Ansi_Setjmp_On, &LANG_Ansi_Setjmp_Set, "C/C++: enable optimization of functions with calls to setjmp" }, + { OVK_INT32, OV_VISIBLE, 1, "exception_range_opt", "", + 1, 0, 2, &Optimize_exception_ranges, &Optimize_exception_ranges_set, + "Enable control flow optimization for exception ranges" }, + #if defined(__linux__) || defined(BUILD_OS_DARWIN) { OVK_BOOL, OV_INTERNAL, TRUE, "wfe_dfe", "wfe_dfe", 0, 0, 0, &Enable_WFE_DFE, NULL, Modified: trunk/osprey/common/com/symtab_access.h =================================================================== --- trunk/osprey/common/com/symtab_access.h 2011-05-25 14:53:17 UTC (rev 3628) +++ trunk/osprey/common/com/symtab_access.h 2011-05-26 20:15:16 UTC (rev 3629) @@ -1136,6 +1136,13 @@ PU_src_lang (const PU& pu) { return pu.src_lang; } inline BOOL +PU_simple_eh(const PU& pu) { return (pu.flags & PU_SIMPLE_EH_RANGE) != 0;} +inline void +Set_PU_simple_eh(PU& pu) { pu.flags |= PU_SIMPLE_EH_RANGE; } +inline void +Clear_PU_simple_eh(PU& pu) { pu.flags &= ~PU_SIMPLE_EH_RANGE; } + +inline BOOL PU_mixed_lang (const PU& pu) { return (pu.src_lang & PU_MIXED_LANG) != 0; } inline void Set_PU_mixed_lang (PU& pu) { pu.src_lang |= PU_MIXED_LANG; } Modified: trunk/osprey/common/com/symtab_defs.h =================================================================== --- trunk/osprey/common/com/symtab_defs.h 2011-05-25 14:53:17 UTC (rev 3628) +++ trunk/osprey/common/com/symtab_defs.h 2011-05-26 20:15:16 UTC (rev 3629) @@ -764,6 +764,7 @@ #define PU_IS_CDECL 0x0002000000000000LL // __attribute__((cdecl)) semantic #define PU_NOTHROW 0x0004000000000000LL // doesn't throw, e.g. decl as "void foo() throw()". #define PU_HAS_APPLY_ARGS 0x0008000000000000LL // __builtin_apply_args +#define PU_SIMPLE_EH_RANGE 0x0010000000000000LL // there is a single eh range in PU, no clean-up or catch enum PU_SRC_LANG_FLAGS { ------------------------------------------------------------------------------ vRanger cuts backup time in half-while increasing security. With the market-leading solution for virtual backup and recovery, you get blazing-fast, flexible, and affordable data protection. Download your free trial now. http://p.sf.net/sfu/quest-d2dcopy1 _______________________________________________ Open64-devel mailing list Open64-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/open64-devel