Author: hjz Date: 2010-09-19 07:56:35 -0400 (Sun, 19 Sep 2010) New Revision: 3345
Modified: trunk/osprey/be/be/driver.cxx trunk/osprey/be/be/omp_lower.cxx trunk/osprey/be/com/wn_mp.cxx trunk/osprey/be/com/wn_mp.h trunk/osprey/driver/OPTIONS trunk/osprey/wgen/wgen_decl.cxx trunk/osprey/wgen/wgen_omp_directives.cxx trunk/osprey/wgen/wgen_omp_directives.h Log: Fixed several OpenMP bugs. 1. Fixed the bug of OpenMP driver. Now -fopenmp option works as well as -mp. 2. Fixed the bug of OpenMP atomic directive. Previously, some operation inside OpenMP ATOMIC was lowered to INTRN_COMPARE_AND_SWAP_XXX, but in fact they should be lowered to INTRN_BOOL_COMPARE_AND_SWAP_XXX. 3. Previously, local variables defined in parallel region was treated as shared variable. I added new code in wgen to generate PRIVATE clause in such parallel region for such variables implicitly, to solve the problem. 4. Previously, some nested OpenMP directives (such as CRITICAL inside another CRITICAL) may trigger an assertion failure. I fixed this problem by changing the place to call the verifier. Approved by: Sun Chan Modified: trunk/osprey/be/be/driver.cxx =================================================================== --- trunk/osprey/be/be/driver.cxx 2010-09-17 20:19:03 UTC (rev 3344) +++ trunk/osprey/be/be/driver.cxx 2010-09-19 11:56:35 UTC (rev 3345) @@ -158,6 +158,7 @@ #include "ti_si.h" #include "isr.h" #endif +#include "wn_mp.h" // for Verify_No_MP() extern ERROR_DESC EDESC_BE[], EDESC_CG[]; @@ -1481,6 +1482,7 @@ Set_Error_Phase ( "MP Lowering" ); WB_LWR_Initialize(pu, NULL); pu = WN_Lower (pu, LOWER_MP, NULL, "Before MP Lowering"); + Verify_No_MP(WN_func_body(pu)); //Bug 4688 #ifdef KEY extern void Post_MP_Processing (WN *); Modified: trunk/osprey/be/be/omp_lower.cxx =================================================================== --- trunk/osprey/be/be/omp_lower.cxx 2010-09-17 20:19:03 UTC (rev 3344) +++ trunk/osprey/be/be/omp_lower.cxx 2010-09-19 11:56:35 UTC (rev 3345) @@ -2269,10 +2269,10 @@ WN *c_s; if (swap_type == MTYPE_I4) { c_s=WN_Create_Intrinsic(OPC_U4INTRINSIC_CALL, - INTRN_COMPARE_AND_SWAP_I4,3,kids); + INTRN_BOOL_COMPARE_AND_SWAP_I4,3,kids); } else { c_s=WN_Create_Intrinsic(OPC_U8INTRINSIC_CALL, - INTRN_COMPARE_AND_SWAP_I8,3,kids); + INTRN_BOOL_COMPARE_AND_SWAP_I8,3,kids); } WN_Set_Call_Parm_Mod(c_s); WN_Set_Call_Parm_Ref(c_s); @@ -2441,8 +2441,8 @@ case INTRN_FETCH_AND_OR_I8: case INTRN_FETCH_AND_XOR_I8: // from Atomic_Using_Swap() - case INTRN_COMPARE_AND_SWAP_I4: - case INTRN_COMPARE_AND_SWAP_I8: + case INTRN_BOOL_COMPARE_AND_SWAP_I4: + case INTRN_BOOL_COMPARE_AND_SWAP_I8: break; default: return NULL; Modified: trunk/osprey/be/com/wn_mp.cxx =================================================================== --- trunk/osprey/be/com/wn_mp.cxx 2010-09-17 20:19:03 UTC (rev 3344) +++ trunk/osprey/be/com/wn_mp.cxx 2010-09-19 11:56:35 UTC (rev 3345) @@ -823,81 +823,9 @@ #define IS_MASTER_PREG_NAME "mp_is_master" -/* -After returning from lower_mp(), all MP constructs should have been lowered -in both the Whirl tree passed to lower_mp() and the nested PU (if one was -created). If all MP constructs have been lowered in a Whirl tree, the tree -will contain no MP pragmas, MP IF's, or non-POD finalization IF's. This -class verifies this post- condition just before returning from lower_mp(). - -This class could easily be extended to perform additional verification on -the lowered Whirl. -*/ - -class Verify_MP_Lowered { - BOOL replace_block_set; - WN *replace_block_start; - // i.e. WN_next() of last node in replace_block - WN *replace_block_sibling; - BOOL nested_pu_set; - WN *nested_pu; - - static void Verify_No_MP(WN *tree); - -public: - Verify_MP_Lowered() : replace_block_set(FALSE), nested_pu_set(FALSE) { } - - void Set_replace_block(WN *replace, WN *sibling) { - Is_True(!replace_block_set, ("Set_replace_block() called already")); - replace_block_set = TRUE; - replace_block_start = replace; - replace_block_sibling = sibling; - } - - void Set_nested_pu_tree(WN *pu) { - Is_True(!nested_pu_set, ("Set_nested_pu_tree() called already")); - nested_pu_set = TRUE; - nested_pu = pu; - } - - void Set_replace_block_and_nested_pu(WN *replace, WN *sibling, WN *pu) { - Is_True(!replace_block_set && !nested_pu_set, - ("replace_block_start and/or nested_pu set already")); - replace_block_set = TRUE; - replace_block_start = replace; - replace_block_sibling = sibling; - nested_pu_set = TRUE; - nested_pu = pu; - } - - ~Verify_MP_Lowered(); -}; - -/* -Destructor verifies that both the replace_block and nested PU have been set -(either may be NULL), then verifies that neither contains any MP pragmas, -MP IF's, or non-POD finalization IF's. If compiled without debugging -support, it does nothing. -*/ - -Verify_MP_Lowered::~Verify_MP_Lowered() +// Verify that tree contains no MP pragmas or IF's +void Verify_No_MP(WN *tree) { - Is_True(replace_block_set, ("replace_block_start not set")); - Is_True(nested_pu_set, ("nested_pu not set")); - -#ifdef Is_True_On - for (WN *wn = replace_block_start; wn && wn != replace_block_sibling; - wn = WN_next(wn)) - Verify_No_MP(wn); - - if (nested_pu) - Verify_No_MP(nested_pu); -#endif -} - - // Verify that tree contains no MP pragmas or IF's -void Verify_MP_Lowered::Verify_No_MP(WN *tree) -{ WN_ITER *wni = WN_WALK_TreeIter(tree); for ( ; wni; wni = WN_WALK_TreeNext(wni)) { @@ -922,9 +850,7 @@ } } -Verify_MP_Lowered *verify_mp_lowered_ptr; // set upon entry to lower_mp() - /* Forward function declarations. */ static WN * Gen_MP_Load_Store ( ST * from_st, WN_OFFSET from_offset, @@ -2823,7 +2749,6 @@ PU_Info *parallel_pu = TYPE_MEM_POOL_ALLOC ( PU_Info, Malloc_Mem_Pool ); PU_Info_init ( parallel_pu ); Set_PU_Info_tree_ptr (parallel_pu, func_entry ); - verify_mp_lowered_ptr->Set_nested_pu_tree(func_entry); PU_Info_proc_sym(parallel_pu) = ST_st_idx(parallel_proc); PU_Info_maptab(parallel_pu) = cmaptab = WN_MAP_TAB_Create(MEM_pu_pool_ptr); @@ -4216,7 +4141,6 @@ PU_Info *copy_pu = TYPE_MEM_POOL_ALLOC ( PU_Info, Malloc_Mem_Pool ); PU_Info_init ( copy_pu ); Set_PU_Info_tree_ptr (copy_pu, func_entry ); - //verify_mp_lowered_ptr->Set_nested_pu_tree(func_entry); PU_Info_proc_sym(copy_pu) = ST_st_idx(parallel_proc); PU_Info_maptab(copy_pu) = cp_cmaptab = WN_MAP_TAB_Create(MEM_pu_pool_ptr); @@ -11780,6 +11704,7 @@ } Transform_Parallel_Block ( stmt_block ); + Verify_No_MP(stmt_block); #ifdef KEY Gen_Threadpriv_Func(reference_block, parallel_func, FALSE); #endif @@ -11909,9 +11834,6 @@ Is_True(PU_Info_proc_sym(Current_PU_Info) == last_pu_proc_sym, ("LowerMP_PU_Init() not called for this PU")); - Verify_MP_Lowered verify_mp_lowered; - verify_mp_lowered_ptr = &verify_mp_lowered; - /* Special case handling of PU-scope pragmas. */ if (block == NULL) { @@ -11927,7 +11849,6 @@ } - verify_mp_lowered.Set_replace_block_and_nested_pu(NULL, NULL, NULL); return (NULL); } @@ -12047,18 +11968,14 @@ WN *return_wn = WN_first( store_gtid ); WN_DELETE_Tree(node); WN_Delete( store_gtid ); - verify_mp_lowered.Set_replace_block_and_nested_pu( return_wn, - WN_next(call), NULL); return return_wn; } else if (WN_pragma(node) == WN_PRAGMA_CHUNKSIZE) { pu_chunk_node = node; - verify_mp_lowered.Set_replace_block_and_nested_pu(NULL, NULL, NULL); return (WN_next(node)); } else if (WN_pragma(node) == WN_PRAGMA_MPSCHEDTYPE) { pu_mpsched_node = node; - verify_mp_lowered.Set_replace_block_and_nested_pu(NULL, NULL, NULL); return (WN_next(node)); } else if (WN_pragma(node) == WN_PRAGMA_COPYIN) { @@ -12070,7 +11987,6 @@ wn = WN_next(node); WN_DELETE_Tree ( node ); - verify_mp_lowered.Set_replace_block_and_nested_pu(NULL, NULL, NULL); return (wn); } else if (WN_pragma(node) == WN_PRAGMA_CRITICAL_SECTION_BEGIN) { @@ -12094,8 +12010,6 @@ WN *return_wn = WN_first( store_gtid ); WN_DELETE_Tree(node); WN_Delete( store_gtid ); - verify_mp_lowered.Set_replace_block_and_nested_pu( return_wn, - WN_next(call), NULL); return return_wn; } else if (WN_pragma(node) == WN_PRAGMA_ORDERED_END) { @@ -12108,8 +12022,6 @@ WN_next(call) = wn; if (wn) WN_prev(wn) = call; WN_DELETE_Tree(node); - verify_mp_lowered.Set_replace_block_and_nested_pu(call, - WN_next(call), NULL); return call; } else @@ -12142,8 +12054,6 @@ WN_DELETE_Tree(WN_region_exits(node)); RID_Delete(Current_Map_Tab, node); WN_Delete(node); - verify_mp_lowered.Set_replace_block_and_nested_pu(wn, WN_next(wn), - NULL); return wn; case WN_PRAGMA_MASTER_BEGIN: @@ -12155,8 +12065,6 @@ WN_DELETE_Tree(WN_region_exits(node)); RID_Delete(Current_Map_Tab, node); WN_Delete(node); - verify_mp_lowered.Set_replace_block_and_nested_pu(wn, WN_next(wn), - NULL); return wn; case WN_PRAGMA_DOACROSS: @@ -12166,7 +12074,6 @@ case WN_PRAGMA_PDO_BEGIN: mpt = MPP_ORPHANED_PDO; - verify_mp_lowered.Set_nested_pu_tree(NULL); break; case WN_PRAGMA_PARALLEL_BEGIN: @@ -12497,8 +12404,6 @@ WN_INSERT_BlockLast ( replace_block, Gen_MP_Copyin ( FALSE ) ); - verify_mp_lowered.Set_nested_pu_tree(NULL); - } else if (mpt == MPP_CRITICAL_SECTION) { line_number = WN_linenum(node); @@ -12540,8 +12445,6 @@ WN_DELETE_Tree ( node ); WN_Delete ( cur_node ); - verify_mp_lowered.Set_nested_pu_tree(NULL); - } else if (mpt == MPP_PARALLEL_DO) { BOOL is_omp = WN_pragma_omp(WN_first(WN_region_pragmas(node))); @@ -12581,7 +12484,6 @@ WN_Delete ( node ); local_count = 0; WN_INSERT_BlockLast ( replace_block, do_preamble_block ); - verify_mp_lowered_ptr->Set_nested_pu_tree(NULL); goto finish_processing; } else Fail_FmtAssertion @@ -12732,7 +12634,6 @@ WN_Delete ( node ); local_count = 0; WN_INSERT_BlockLast ( replace_block, do_preamble_block ); - verify_mp_lowered_ptr->Set_nested_pu_tree(NULL); goto finish_processing; } else Fail_FmtAssertion @@ -13084,8 +12985,6 @@ /* For mp if's return the entire replacement block and the caller will handle it from there. */ - verify_mp_lowered.Set_replace_block(replace_block, - WN_next(WN_last(replace_block))); return_nodes = replace_block; } else { @@ -13102,7 +13001,6 @@ return_nodes = cont_nodes; WN_Delete ( replace_block ); - verify_mp_lowered.Set_replace_block(return_nodes, cont_nodes); } return (return_nodes); Modified: trunk/osprey/be/com/wn_mp.h =================================================================== --- trunk/osprey/be/com/wn_mp.h 2010-09-17 20:19:03 UTC (rev 3344) +++ trunk/osprey/be/com/wn_mp.h 2010-09-19 11:56:35 UTC (rev 3345) @@ -100,6 +100,8 @@ extern WN * Gen_MP_Setlock ( void ); extern WN * Gen_MP_Unsetlock ( void ); +extern void Verify_No_MP(WN *tree); + // list of the STORE nodes for the REDUCTION pragmas of an MP construct typedef DYN_ARRAY<WN *> REDUCTION_LIST; extern INT Modified: trunk/osprey/driver/OPTIONS =================================================================== --- trunk/osprey/driver/OPTIONS 2010-09-17 20:19:03 UTC (rev 3344) +++ trunk/osprey/driver/OPTIONS 2010-09-19 11:56:35 UTC (rev 3345) @@ -962,8 +962,8 @@ -openmp ; FTN,Cc ffe -mp "enable the multiprocessing directives (same as -mp)" #ifdef KEY --fopenmp ; Cc cfe self - "" +-fopenmp toggle(&mpkind,NORMAL_MP); FTN,Cc ffe,cfe self + "enable the multiprocessing directives" #endif #ifndef KEY -dsm_clone ; ALL ipl,be,d self Modified: trunk/osprey/wgen/wgen_decl.cxx =================================================================== --- trunk/osprey/wgen/wgen_decl.cxx 2010-09-17 20:19:03 UTC (rev 3344) +++ trunk/osprey/wgen/wgen_decl.cxx 2010-09-19 11:56:35 UTC (rev 3345) @@ -95,6 +95,7 @@ #include "wgen_dst.h" // DST_enter_member_function #include "dwarf_DST_dump.h" #include "targ_sim.h" // PUSH_RETURN_ADDRESS_ON_STACK +#include "wgen_omp_directives.h" #ifdef KEY #include <ext/hash_map> @@ -707,6 +708,7 @@ Init_Deferred_Function_Stack(); } */ + ST *var_st; switch (gs_tree_code(decl)) { case GS_CONST_DECL: @@ -885,7 +887,9 @@ expanded_decl(decl) = TRUE; #endif - (void) Get_ST(decl); + var_st = Get_ST(decl); + if (!gs_tree_static(decl) && !gs_decl_external(decl)) + WGEN_register_local_variable(var_st); if (gs_decl_initial(decl) && !gs_decl_external(decl)) { gs_t init = gs_decl_initial(decl); gs_code_t code = gs_tree_code(init); Modified: trunk/osprey/wgen/wgen_omp_directives.cxx =================================================================== --- trunk/osprey/wgen/wgen_omp_directives.cxx 2010-09-17 20:19:03 UTC (rev 3344) +++ trunk/osprey/wgen/wgen_omp_directives.cxx 2010-09-19 11:56:35 UTC (rev 3345) @@ -87,6 +87,8 @@ // vector for storing DO-loop side-effects, to be emitted before the loop. std::vector<WN *> doloop_side_effects; +static std::stack<WN *> omp_construct_stack; + BOOL Trace_Omp = FALSE; // Put in per-file OpenMP specific initializations here. @@ -840,6 +842,7 @@ /* create a region on current block */ WN * region = WGEN_region(REGION_KIND_MP); + omp_construct_stack.push(region); WN *wn; @@ -892,6 +895,7 @@ WGEN_maybe_do_eh_cleanups (); } + omp_construct_stack.pop(); WGEN_Stmt_Pop (wgen_stmk_scope); WGEN_CS_pop (wgen_omp_parallel); }; @@ -1255,6 +1259,7 @@ /* create a region on current block */ WN * region = WGEN_region(REGION_KIND_MP); + omp_construct_stack.push(region); WN *wn; @@ -1298,6 +1303,7 @@ { WN *wn = WGEN_Stmt_Top (); //WGEN_check_parallel_for (wn); + omp_construct_stack.pop(); WGEN_Stmt_Pop (wgen_stmk_scope); WGEN_CS_pop(wgen_omp_parallel_for); } @@ -1312,6 +1318,7 @@ /* create a region on current block */ WN * region = WGEN_region(REGION_KIND_MP); + omp_construct_stack.push(region); WN *wn; @@ -1357,6 +1364,7 @@ { WN *wn = WGEN_Stmt_Top (); // WGEN_check_parallel_sections (wn); + omp_construct_stack.pop(); WGEN_Stmt_Pop (wgen_stmk_scope); WGEN_CS_pop(wgen_omp_parallel_sections); @@ -1819,3 +1827,13 @@ WGEN_Stmt_Pop (wgen_stmk_for_cond); } +void WGEN_register_local_variable(ST * st) +{ + if (omp_construct_stack.empty()) + return; + WN * last_region = omp_construct_stack.top(); + WN * pragmas = WN_region_pragmas(last_region); + WN * private_pragma = WN_CreatePragma(WN_PRAGMA_LOCAL, st, 0, 0); + WN_set_pragma_omp(private_pragma); + WN_INSERT_BlockLast(pragmas, private_pragma); +} Modified: trunk/osprey/wgen/wgen_omp_directives.h =================================================================== --- trunk/osprey/wgen/wgen_omp_directives.h 2010-09-17 20:19:03 UTC (rev 3344) +++ trunk/osprey/wgen/wgen_omp_directives.h 2010-09-19 11:56:35 UTC (rev 3345) @@ -99,6 +99,8 @@ extern void WGEN_expand_end_do_loop (void); +extern void WGEN_register_local_variable(ST * st); + extern BOOL Trace_Omp; #endif ------------------------------------------------------------------------------ Start uncovering the many advantages of virtual appliances and start using them to simplify application deployment and accelerate your shift to cloud computing. http://p.sf.net/sfu/novell-sfdev2dev _______________________________________________ Open64-devel mailing list Open64-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/open64-devel