diff options
Diffstat (limited to 'gcc/omp-low.c')
-rw-r--r-- | gcc/omp-low.c | 50 |
1 files changed, 40 insertions, 10 deletions
diff --git a/gcc/omp-low.c b/gcc/omp-low.c index 81ae5b4..bd7e7e6 100644 --- a/gcc/omp-low.c +++ b/gcc/omp-low.c @@ -3571,11 +3571,10 @@ expand_omp_taskreg (struct omp_region *region) new_bb = move_sese_region_to_fn (child_cfun, entry_bb, exit_bb, block); if (exit_bb) single_succ_edge (new_bb)->flags = EDGE_FALLTHRU; - /* ??? As the OMP expansion process does not update the loop - tree of the original function before outlining the region to - the new child function we need to discover loops in the child. - Arrange for that. */ - child_cfun->x_current_loops->state |= LOOPS_NEED_FIXUP; + /* When the OMP expansion process cannot guarantee an up-to-date + loop tree arrange for the child function to fixup loops. */ + if (loops_state_satisfies_p (LOOPS_NEED_FIXUP)) + child_cfun->x_current_loops->state |= LOOPS_NEED_FIXUP; /* Remove non-local VAR_DECLs from child_cfun->local_decls list. */ num = vec_safe_length (child_cfun->local_decls); @@ -4148,6 +4147,16 @@ expand_omp_for_generic (struct omp_region *region, recompute_dominator (CDI_DOMINATORS, l0_bb)); set_immediate_dominator (CDI_DOMINATORS, l1_bb, recompute_dominator (CDI_DOMINATORS, l1_bb)); + + struct loop *outer_loop = alloc_loop (); + outer_loop->header = l0_bb; + outer_loop->latch = l2_bb; + add_loop (outer_loop, l0_bb->loop_father); + + struct loop *loop = alloc_loop (); + loop->header = l1_bb; + /* The loop may have multiple latches. */ + add_loop (loop, outer_loop); } } @@ -4370,6 +4379,11 @@ expand_omp_for_static_nochunk (struct omp_region *region, recompute_dominator (CDI_DOMINATORS, body_bb)); set_immediate_dominator (CDI_DOMINATORS, fin_bb, recompute_dominator (CDI_DOMINATORS, fin_bb)); + + struct loop *loop = alloc_loop (); + loop->header = body_bb; + loop->latch = cont_bb; + add_loop (loop, body_bb->loop_father); } @@ -4671,6 +4685,16 @@ expand_omp_for_static_chunk (struct omp_region *region, struct omp_for_data *fd) recompute_dominator (CDI_DOMINATORS, seq_start_bb)); set_immediate_dominator (CDI_DOMINATORS, body_bb, recompute_dominator (CDI_DOMINATORS, body_bb)); + + struct loop *trip_loop = alloc_loop (); + trip_loop->header = iter_part_bb; + trip_loop->latch = trip_update_bb; + add_loop (trip_loop, iter_part_bb->loop_father); + + struct loop *loop = alloc_loop (); + loop->header = body_bb; + loop->latch = cont_bb; + add_loop (loop, trip_loop); } @@ -4698,6 +4722,11 @@ expand_omp_for (struct omp_region *region) BRANCH_EDGE (region->cont)->flags &= ~EDGE_ABNORMAL; FALLTHRU_EDGE (region->cont)->flags &= ~EDGE_ABNORMAL; } + else + /* If there isnt a continue then this is a degerate case where + the introduction of abnormal edges during lowering will prevent + original loops from being detected. Fix that up. */ + loops_state_set (LOOPS_NEED_FIXUP); if (fd.sched_kind == OMP_CLAUSE_SCHEDULE_STATIC && !fd.have_ordered @@ -4914,7 +4943,7 @@ expand_omp_sections (struct omp_region *region) u = build_case_label (NULL, NULL, t); make_edge (l0_bb, default_bb, 0); if (current_loops) - add_bb_to_loop (default_bb, l0_bb->loop_father); + add_bb_to_loop (default_bb, current_loops->tree_root); stmt = gimple_build_switch (vmain, u, label_vec); gsi_insert_after (&switch_si, stmt, GSI_SAME_STMT); @@ -5448,13 +5477,14 @@ expand_omp_atomic_pipeline (basic_block load_bb, basic_block store_bb, /* Remove GIMPLE_OMP_ATOMIC_STORE. */ gsi_remove (&si, true); + struct loop *loop = alloc_loop (); + loop->header = loop_header; + loop->latch = loop_header; + add_loop (loop, loop_header->loop_father); + if (gimple_in_ssa_p (cfun)) update_ssa (TODO_update_ssa_no_phi); - /* ??? The above could use loop construction primitives. */ - if (current_loops) - loops_state_set (LOOPS_NEED_FIXUP); - return true; } |