--- trunk-orig/gcc/omp-low.c 2018-12-12 18:19:40.920852744 +0800 +++ trunk-work/gcc/omp-low.c 2018-12-13 22:28:29.149913219 +0800 @@ -2600,6 +2600,50 @@ layout_type (ctx->record_type); } +/* Reorder clauses so that dynamic array map clauses are placed at the very + front of the chain. */ + +static void +reorder_dynamic_array_clauses (tree *clauses_ptr) +{ + tree c, clauses = *clauses_ptr; + tree prev_clause = NULL_TREE, next_clause; + tree da_clauses = NULL_TREE, da_clauses_tail = NULL_TREE; + + for (c = clauses; c; c = next_clause) + { + next_clause = OMP_CLAUSE_CHAIN (c); + + if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP + && GOMP_MAP_DYNAMIC_ARRAY_P (OMP_CLAUSE_MAP_KIND (c))) + { + /* Unchain c from clauses. */ + if (c == clauses) + clauses = next_clause; + + /* Link on to da_clauses. */ + if (da_clauses_tail) + OMP_CLAUSE_CHAIN (da_clauses_tail) = c; + else + da_clauses = c; + da_clauses_tail = c; + + if (prev_clause) + OMP_CLAUSE_CHAIN (prev_clause) = next_clause; + continue; + } + + prev_clause = c; + } + + /* Place dynamic array clauses at the start of the clause list. */ + if (da_clauses) + { + OMP_CLAUSE_CHAIN (da_clauses_tail) = clauses; + *clauses_ptr = da_clauses; + } +} + /* Scan a GIMPLE_OMP_TARGET. */ static void @@ -2608,7 +2652,6 @@ omp_context *ctx; tree name; bool offloaded = is_gimple_omp_offloaded (stmt); - tree clauses = gimple_omp_target_clauses (stmt); ctx = new_omp_context (stmt, outer_ctx); ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0); @@ -2627,6 +2670,14 @@ gimple_omp_target_set_child_fn (stmt, ctx->cb.dst_fn); } + /* If OpenACC construct, put dynamic array clauses (if any) in front of + clause chain. The runtime can then test the first to see if the + additional map processing for them is required. */ + if (is_gimple_omp_oacc (stmt)) + reorder_dynamic_array_clauses (gimple_omp_target_clauses_ptr (stmt)); + + tree clauses = gimple_omp_target_clauses (stmt); + scan_sharing_clauses (clauses, ctx); scan_omp (gimple_omp_body_ptr (stmt), ctx);