diff options
Diffstat (limited to 'gcc/cfgexpand.c')
-rw-r--r-- | gcc/cfgexpand.c | 32 |
1 files changed, 31 insertions, 1 deletions
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index 86efa22..b270a4d 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -4616,7 +4616,8 @@ expand_debug_expr (tree exp) op0 = copy_rtx (op0); if (op0 == orig_op0) op0 = shallow_copy_rtx (op0); - set_mem_attributes (op0, exp, 0); + if (TREE_CODE (tem) != SSA_NAME) + set_mem_attributes (op0, exp, 0); } if (known_eq (bitpos, 0) && mode == GET_MODE (op0)) @@ -6126,6 +6127,29 @@ discover_nonconstant_array_refs_r (tree * tp, int *walk_subtrees, return NULL_TREE; } +/* If there's a chance to get a pseudo for t then if it would be of float mode + and the actual access is via an integer mode (lowered memcpy or similar + access) then avoid the register expansion if the mode likely is not storage + suitable for raw bits processing (like XFmode on i?86). */ + +static void +avoid_type_punning_on_regs (tree t) +{ + machine_mode access_mode = TYPE_MODE (TREE_TYPE (t)); + if (access_mode != BLKmode + && !SCALAR_INT_MODE_P (access_mode)) + return; + tree base = get_base_address (t); + if (DECL_P (base) + && !TREE_ADDRESSABLE (base) + && FLOAT_MODE_P (DECL_MODE (base)) + && maybe_lt (GET_MODE_PRECISION (DECL_MODE (base)), + GET_MODE_BITSIZE (GET_MODE_INNER (DECL_MODE (base)))) + /* Double check in the expensive way we really would get a pseudo. */ + && use_register_for_decl (base)) + TREE_ADDRESSABLE (base) = 1; +} + /* RTL expansion is not able to compile array references with variable offsets for arrays stored in single register. Discover such expressions and mark variables as addressable to avoid this @@ -6159,6 +6183,12 @@ discover_nonconstant_array_refs (void) default: break; } + if (gimple_vdef (stmt)) + { + tree t = gimple_get_lhs (stmt); + if (t && REFERENCE_CLASS_P (t)) + avoid_type_punning_on_regs (t); + } } } } |