return build_zero_cst (TREE_TYPE (expr));
}
+/* Helper function for convert_lvalue_to_rvalue called via
+ walk_tree_without_duplicates. Find DATA inside of the expression. */
+
+static tree
+c_find_var_r (tree *tp, int *walk_subtrees, void *data)
+{
+ if (TYPE_P (*tp))
+ *walk_subtrees = 0;
+ else if (*tp == (tree) data)
+ return *tp;
+ return NULL_TREE;
+}
+
/* Convert expression EXP (location LOC) from lvalue to rvalue,
including converting functions and arrays to pointers if CONVERT_P.
If READ_P, also mark the expression as having been read. If
/* EXPR is always read. */
mark_exp_read (exp.value);
+ /* Optimize the common case where c_build_function_call_vec
+ immediately folds __atomic_load (&expr, &tmp, SEQ_CST); into
+ tmp = __atomic_load_<N> (&expr, SEQ_CST);
+ In that case tmp is not addressable and can be initialized
+ fully by the rhs of the MODIFY_EXPR. */
+ tree tem = func_call;
+ if (CONVERT_EXPR_P (tem) && VOID_TYPE_P (TREE_TYPE (tem)))
+ {
+ tem = TREE_OPERAND (tem, 0);
+ if (TREE_CODE (tem) == MODIFY_EXPR
+ && TREE_OPERAND (tem, 0) == tmp
+ && !walk_tree_without_duplicates (&TREE_OPERAND (tem, 1),
+ c_find_var_r, tmp))
+ {
+ TREE_ADDRESSABLE (tmp) = 0;
+ func_call = TREE_OPERAND (tem, 1);
+ }
+ }
+
/* Return tmp which contains the value loaded. */
exp.value = build4 (TARGET_EXPR, nonatomic_type, tmp, func_call,
NULL_TREE, NULL_TREE);