/* Don't allow duplicate entries. */
ann = get_var_ann (var);
- if (ann->in_vuse_list || ann->in_vdef_list)
+ if (ann->in_vuse_list)
return;
+ else if (ann->in_vdef_list)
+ {
+ /* We don't want a vuse if we already have a vdef, but we must
+ still put this in build_loads. */
+ bitmap_set_bit (build_loads, DECL_UID (var));
+ return;
+ }
ann->in_vuse_list = true;
sym = var;
}
To implement this, we just punt on accesses through union
pointers entirely.
+
+ Another case we have to allow is accessing a variable
+ through an array access at offset zero. This happens from
+ code generated by the fortran frontend like
+
+ char[1:1] & my_char_ref;
+ char my_char;
+ my_char_ref_1 = (char[1:1] &) &my_char;
+ D.874_2 = (*my_char_ref_1)[1]{lb: 1 sz: 1};
*/
else if (ref
&& flag_strict_aliasing
&& base
&& (TREE_CODE (base) != INDIRECT_REF
|| TREE_CODE (TREE_TYPE (base)) != UNION_TYPE)
+ && (TREE_CODE (base) != INDIRECT_REF
+ || TREE_CODE (ref) != ARRAY_REF
+ || offset != 0
+ || (DECL_SIZE (alias)
+ && TREE_CODE (DECL_SIZE (alias)) == INTEGER_CST
+ && size != -1
+ && (unsigned HOST_WIDE_INT)size
+ != TREE_INT_CST_LOW (DECL_SIZE (alias))))
&& !AGGREGATE_TYPE_P (TREE_TYPE (alias))
&& TREE_CODE (TREE_TYPE (alias)) != COMPLEX_TYPE
&& !var_ann (alias)->is_heapvar
get_expr_operands (stmt, &CHANGE_DYNAMIC_TYPE_LOCATION (expr), opf_use);
return;
+ case OMP_FOR:
+ {
+ tree init = OMP_FOR_INIT (expr);
+ tree cond = OMP_FOR_COND (expr);
+ tree incr = OMP_FOR_INCR (expr);
+ tree c, clauses = OMP_FOR_CLAUSES (stmt);
+
+ get_expr_operands (stmt, &GIMPLE_STMT_OPERAND (init, 0), opf_def);
+ get_expr_operands (stmt, &GIMPLE_STMT_OPERAND (init, 1), opf_use);
+ get_expr_operands (stmt, &TREE_OPERAND (cond, 1), opf_use);
+ get_expr_operands (stmt, &TREE_OPERAND (GIMPLE_STMT_OPERAND (incr, 1), 1),
+ opf_use);
+
+ c = find_omp_clause (clauses, OMP_CLAUSE_SCHEDULE);
+ if (c)
+ get_expr_operands (stmt, &OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c),
+ opf_use);
+ return;
+ }
+
+ case OMP_CONTINUE:
+ {
+ get_expr_operands (stmt, &TREE_OPERAND (expr, 0), opf_def);
+ get_expr_operands (stmt, &TREE_OPERAND (expr, 1), opf_use);
+ return;
+ }
+
+ case OMP_PARALLEL:
+ {
+ tree c, clauses = OMP_PARALLEL_CLAUSES (stmt);
+
+ if (OMP_PARALLEL_DATA_ARG (stmt))
+ {
+ get_expr_operands (stmt, &OMP_PARALLEL_DATA_ARG (stmt), opf_use);
+ add_to_addressable_set (OMP_PARALLEL_DATA_ARG (stmt),
+ &s_ann->addresses_taken);
+ }
+
+ c = find_omp_clause (clauses, OMP_CLAUSE_IF);
+ if (c)
+ get_expr_operands (stmt, &OMP_CLAUSE_IF_EXPR (c), opf_use);
+ c = find_omp_clause (clauses, OMP_CLAUSE_NUM_THREADS);
+ if (c)
+ get_expr_operands (stmt, &OMP_CLAUSE_NUM_THREADS_EXPR (c), opf_use);
+ return;
+ }
+
+ case OMP_SECTIONS:
+ {
+ get_expr_operands (stmt, &OMP_SECTIONS_CONTROL (expr), opf_def);
+ return;
+ }
+
case BLOCK:
case FUNCTION_DECL:
case EXC_PTR_EXPR:
case FILTER_EXPR:
case LABEL_DECL:
case CONST_DECL:
- case OMP_PARALLEL:
- case OMP_SECTIONS:
- case OMP_FOR:
case OMP_SINGLE:
case OMP_MASTER:
case OMP_ORDERED:
case OMP_CRITICAL:
case OMP_RETURN:
- case OMP_CONTINUE:
+ case OMP_SECTION:
+ case OMP_SECTIONS_SWITCH:
/* Expressions that make no memory references. */
return;
ann->references_memory = true;
}
+/* Releases the operands of STMT back to their freelists, and clears
+ the stmt operand lists. */
+
+void
+free_stmt_operands (tree stmt)
+{
+ def_optype_p defs = DEF_OPS (stmt), last_def;
+ use_optype_p uses = USE_OPS (stmt), last_use;
+ voptype_p vuses = VUSE_OPS (stmt);
+ voptype_p vdefs = VDEF_OPS (stmt), vdef, next_vdef;
+ unsigned i;
+
+ if (defs)
+ {
+ for (last_def = defs; last_def->next; last_def = last_def->next)
+ continue;
+ last_def->next = gimple_ssa_operands (cfun)->free_defs;
+ gimple_ssa_operands (cfun)->free_defs = defs;
+ DEF_OPS (stmt) = NULL;
+ }
+
+ if (uses)
+ {
+ for (last_use = uses; last_use->next; last_use = last_use->next)
+ delink_imm_use (USE_OP_PTR (last_use));
+ delink_imm_use (USE_OP_PTR (last_use));
+ last_use->next = gimple_ssa_operands (cfun)->free_uses;
+ gimple_ssa_operands (cfun)->free_uses = uses;
+ USE_OPS (stmt) = NULL;
+ }
+
+ if (vuses)
+ {
+ for (i = 0; i < VUSE_NUM (vuses); i++)
+ delink_imm_use (VUSE_OP_PTR (vuses, i));
+ add_vop_to_freelist (vuses);
+ VUSE_OPS (stmt) = NULL;
+ }
+
+ if (vdefs)
+ {
+ for (vdef = vdefs; vdef; vdef = next_vdef)
+ {
+ next_vdef = vdef->next;
+ delink_imm_use (VDEF_OP_PTR (vdef, 0));
+ add_vop_to_freelist (vdef);
+ }
+ VDEF_OPS (stmt) = NULL;
+ }
+}
/* Free any operands vectors in OPS. */