+static void
+setup_one_parameter (inline_data *id, tree p, tree value, tree fn,
+ tree *init_stmts, tree *vars, bool *gimplify_init_stmts_p)
+{
+ tree init_stmt;
+ tree var;
+
+ /* If the parameter is never assigned to, we may not need to
+ create a new variable here at all. Instead, we may be able
+ to just use the argument value. */
+ if (TREE_READONLY (p)
+ && !TREE_ADDRESSABLE (p)
+ && value && !TREE_SIDE_EFFECTS (value))
+ {
+ /* We can't risk substituting complex expressions. They
+ might contain variables that will be assigned to later.
+ Theoretically, we could check the expression to see if
+ all of the variables that determine its value are
+ read-only, but we don't bother. */
+ /* We may produce non-gimple trees by adding NOPs or introduce
+ invalid sharing when operand is not really constant.
+ It is not big deal to prohibit constant propagation here as
+ we will constant propagate in DOM1 pass anyway. */
+ if (is_gimple_min_invariant (value)
+ && lang_hooks.types_compatible_p (TREE_TYPE (value), TREE_TYPE (p)))
+ {
+ insert_decl_map (id, p, value);
+ return;
+ }
+ }
+
+ /* Make an equivalent VAR_DECL. Note that we must NOT remap the type
+ here since the type of this decl must be visible to the calling
+ function. */
+ var = copy_decl_for_inlining (p, fn, VARRAY_TREE (id->fns, 0));
+
+ /* Register the VAR_DECL as the equivalent for the PARM_DECL;
+ that way, when the PARM_DECL is encountered, it will be
+ automatically replaced by the VAR_DECL. */
+ insert_decl_map (id, p, var);
+
+ /* Declare this new variable. */
+ TREE_CHAIN (var) = *vars;
+ *vars = var;
+
+ /* Make gimplifier happy about this variable. */
+ DECL_SEEN_IN_BIND_EXPR_P (var) = 1;
+
+ /* Even if P was TREE_READONLY, the new VAR should not be.
+ In the original code, we would have constructed a
+ temporary, and then the function body would have never
+ changed the value of P. However, now, we will be
+ constructing VAR directly. The constructor body may
+ change its value multiple times as it is being
+ constructed. Therefore, it must not be TREE_READONLY;
+ the back-end assumes that TREE_READONLY variable is
+ assigned to only once. */
+ if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (p)))
+ TREE_READONLY (var) = 0;
+
+ /* Initialize this VAR_DECL from the equivalent argument. Convert
+ the argument to the proper type in case it was promoted. */
+ if (value)
+ {
+ tree rhs = fold_convert (TREE_TYPE (var), value);
+
+ if (rhs == error_mark_node)
+ return;
+
+ /* We want to use MODIFY_EXPR, not INIT_EXPR here so that we
+ keep our trees in gimple form. */
+ init_stmt = build (MODIFY_EXPR, TREE_TYPE (var), var, rhs);
+ append_to_statement_list (init_stmt, init_stmts);
+
+ /* If we did not create a gimple value and we did not create a gimple
+ cast of a gimple value, then we will need to gimplify INIT_STMTS
+ at the end. Note that is_gimple_cast only checks the outer
+ tree code, not its operand. Thus the explicit check that it's
+ operand is a gimple value. */
+ if (!is_gimple_val (rhs)
+ && (!is_gimple_cast (rhs)
+ || !is_gimple_val (TREE_OPERAND (rhs, 0))))
+ *gimplify_init_stmts_p = true;
+ }
+}
+