case REAL_TYPE:
case ENUMERAL_TYPE:
case BOOLEAN_TYPE:
- case CHAR_TYPE:
t = TYPE_MIN_VALUE (new);
if (t && TREE_CODE (t) != INTEGER_CST)
walk_tree (&TYPE_MIN_VALUE (new), copy_body_r, id, NULL);
if (n)
{
tree new;
+ tree old;
/* If we happen to get an ADDR_EXPR in n->value, strip
it manually here as we'll eventually get ADDR_EXPRs
which lie about their types pointed to. In this case
does other useful transformations, try that first, though. */
tree type = TREE_TYPE (TREE_TYPE ((tree)n->value));
new = unshare_expr ((tree)n->value);
+ old = *tp;
*tp = fold_indirect_ref_1 (type, new);
if (! *tp)
{
if (TREE_CODE (new) == ADDR_EXPR)
*tp = TREE_OPERAND (new, 0);
else
- *tp = build1 (INDIRECT_REF, type, new);
+ {
+ *tp = build1 (INDIRECT_REF, type, new);
+ TREE_THIS_VOLATILE (*tp) = TREE_THIS_VOLATILE (old);
+ }
}
*walk_subtrees = 0;
return NULL;
else if (TREE_CODE (*tp) == ADDR_EXPR)
{
walk_tree (&TREE_OPERAND (*tp, 0), copy_body_r, id, NULL);
- recompute_tree_invariant_for_addr_expr (*tp);
+ /* Handle the case where we substituted an INDIRECT_REF
+ into the operand of the ADDR_EXPR. */
+ if (TREE_CODE (TREE_OPERAND (*tp, 0)) == INDIRECT_REF)
+ *tp = TREE_OPERAND (TREE_OPERAND (*tp, 0), 0);
+ else
+ recompute_tree_invariant_for_addr_expr (*tp);
*walk_subtrees = 0;
}
}
if (stmt)
{
tree call, decl;
+
+ /* With return slot optimization we can end up with
+ non-gimple (foo *)&this->m, fix that here. */
+ if (TREE_CODE (stmt) == MODIFY_EXPR
+ && TREE_CODE (TREE_OPERAND (stmt, 1)) == NOP_EXPR
+ && !is_gimple_val (TREE_OPERAND (TREE_OPERAND (stmt, 1), 0)))
+ gimplify_stmt (&stmt);
+
bsi_insert_after (©_bsi, stmt, BSI_NEW_STMT);
call = get_call_expr_in (stmt);
/* We're duplicating a CALL_EXPR. Find any corresponding
*new_cfun = *DECL_STRUCT_FUNCTION (callee_fndecl);
new_cfun->cfg = NULL;
new_cfun->decl = new_fndecl = copy_node (callee_fndecl);
- new_cfun->ib_boundaries_block = (varray_type) 0;
+ new_cfun->ib_boundaries_block = NULL;
DECL_STRUCT_FUNCTION (new_fndecl) = new_cfun;
push_cfun (new_cfun);
init_empty_tree_cfg ();
if (id->transform_new_cfg)
init_eh_for_function ();
id->eh_region_offset
- = duplicate_eh_regions (cfun_to_copy, remap_decl_1, id, id->eh_region);
+ = duplicate_eh_regions (cfun_to_copy, remap_decl_1, id,
+ 0, id->eh_region);
}
/* Use aux pointers to map the original blocks to copy. */
FOR_EACH_BB_FN (bb, cfun_to_copy)
if (rhs == error_mark_node)
return;
+
+ STRIP_USELESS_TYPE_CONVERSION (rhs);
/* We want to use MODIFY_EXPR, not INIT_EXPR here so that we
keep our trees in gimple form. */
use_it = false;
else if (is_global_var (base_m))
use_it = false;
+ else if (TREE_CODE (TREE_TYPE (result)) == COMPLEX_TYPE
+ && !DECL_COMPLEX_GIMPLE_REG_P (result)
+ && DECL_COMPLEX_GIMPLE_REG_P (base_m))
+ use_it = false;
else if (!TREE_ADDRESSABLE (base_m))
use_it = true;
}
use = var;
if (!lang_hooks.types_compatible_p (TREE_TYPE (var), caller_type))
use = fold_convert (caller_type, var);
+
+ STRIP_USELESS_TYPE_CONVERSION (use);
done:
/* Register the VAR_DECL as the equivalent for the RESULT_DECL; that
case LOOP_EXPR:
case PHI_NODE:
case WITH_SIZE_EXPR:
+ case OMP_CLAUSE:
+ case OMP_RETURN:
+ case OMP_CONTINUE:
break;
/* We don't account constants for now. Assume that the cost is amortized
*count += PARAM_VALUE (PARAM_INLINE_CALL_COST);
break;
}
+
+ case OMP_PARALLEL:
+ case OMP_FOR:
+ case OMP_SECTIONS:
+ case OMP_SINGLE:
+ case OMP_SECTION:
+ case OMP_MASTER:
+ case OMP_ORDERED:
+ case OMP_CRITICAL:
+ case OMP_ATOMIC:
+ /* OpenMP directives are generally very expensive. */
+ *count += 40;
+ break;
+
default:
gcc_unreachable ();
}
if (CALL_EXPR_RETURN_SLOT_OPT (t))
{
return_slot_addr = build_fold_addr_expr (modify_dest);
+ STRIP_USELESS_TYPE_CONVERSION (return_slot_addr);
modify_dest = NULL;
}
}
/* Update callgraph if needed. */
cgraph_remove_node (cg_edge->callee);
- /* Declare the 'auto' variables added with this inlined body. */
- record_vars (BLOCK_VARS (id->block));
id->block = NULL_TREE;
successfully_inlined = TRUE;
if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code))
|| code == TREE_LIST
|| code == TREE_VEC
- || code == TYPE_DECL)
+ || code == TYPE_DECL
+ || code == OMP_CLAUSE)
{
/* Because the chain gets clobbered when we make a copy, we save it
here. */
/* Now, restore the chain, if appropriate. That will cause
walk_tree to walk into the chain as well. */
- if (code == PARM_DECL || code == TREE_LIST)
+ if (code == PARM_DECL
+ || code == TREE_LIST
+ || code == OMP_CLAUSE)
TREE_CHAIN (*tp) = chain;
/* For now, we don't update BLOCKs when we make copies. So, we
{
tree t;
for (t = vars; t; t = TREE_CHAIN (t))
- DECL_SEEN_IN_BIND_EXPR_P (t) = 1;
+ {
+ DECL_SEEN_IN_BIND_EXPR_P (t) = 1;
+ gcc_assert (!TREE_STATIC (t) && !TREE_ASM_WRITTEN (t));
+ cfun->unexpanded_var_list =
+ tree_cons (NULL_TREE, t,
+ cfun->unexpanded_var_list);
+ }
if (block)
BLOCK_VARS (block) = chainon (BLOCK_VARS (block), vars);