diff options
Diffstat (limited to 'gcc/tree-ssa-phiopt.c')
-rw-r--r-- | gcc/tree-ssa-phiopt.c | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c index 7088ff9..a514ed8 100644 --- a/gcc/tree-ssa-phiopt.c +++ b/gcc/tree-ssa-phiopt.c @@ -2196,7 +2196,8 @@ get_non_trapping (void) We check that MIDDLE_BB contains only one store, that that store doesn't trap (not via NOTRAP, but via checking if an access to the same - memory location dominates us) and that the store has a "simple" RHS. */ + memory location dominates us, or the store is to a local addressable + object) and that the store has a "simple" RHS. */ static bool cond_store_replacement (basic_block middle_bb, basic_block join_bb, @@ -2218,8 +2219,9 @@ cond_store_replacement (basic_block middle_bb, basic_block join_bb, locus = gimple_location (assign); lhs = gimple_assign_lhs (assign); rhs = gimple_assign_rhs1 (assign); - if (TREE_CODE (lhs) != MEM_REF - || TREE_CODE (TREE_OPERAND (lhs, 0)) != SSA_NAME + if ((TREE_CODE (lhs) != MEM_REF + && TREE_CODE (lhs) != ARRAY_REF + && TREE_CODE (lhs) != COMPONENT_REF) || !is_gimple_reg_type (TREE_TYPE (lhs))) return false; @@ -2227,7 +2229,13 @@ cond_store_replacement (basic_block middle_bb, basic_block join_bb, TREE_THIS_NOTRAP here, but in that case we also could move stores, whose value is not available readily, which we want to avoid. */ if (!nontrap->contains (lhs)) - return false; + { + /* If LHS is a local variable without address-taken, we could + always safely move down the store. */ + tree base = get_base_address (lhs); + if (!auto_var_p (base) || TREE_ADDRESSABLE (base)) + return false; + } /* Now we've checked the constraints, so do the transformation: 1) Remove the single store. */ @@ -2280,6 +2288,14 @@ cond_store_replacement (basic_block middle_bb, basic_block join_bb, else gsi_insert_before (&gsi, new_stmt, GSI_NEW_STMT); + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, "\nConditional store replacement happened!"); + fprintf (dump_file, "\nReplaced the store with a load."); + fprintf (dump_file, "\nInserted a new PHI statement in joint block:\n"); + print_gimple_stmt (dump_file, new_stmt, 0, TDF_VOPS|TDF_MEMSYMS); + } + return true; } |