From 8ac61af705335691fd0d91ec6cd96e65bb81201c Mon Sep 17 00:00:00 2001 From: Richard Kenner Date: Tue, 23 Oct 2001 18:51:18 +0000 Subject: [PATCH] alias.c (can_address_p): Compnonents are not addressable if the containing type has alias set 0. * alias.c (can_address_p): Compnonents are not addressable if the containing type has alias set 0. (get_alias_set): Rework to use STRIP_NOPS. Only call front-end routine on object, type, or object with NOPs stripped, not inner values. Use language hook to call front-end routine. * builtins.c (get_memory_rtx): Always call set_mem_attributes. (expand_builtin_apply): Call set_mem_align on MEMs we make. Don't pass alignment to emit_block_move. (expand_builtin_memcpy, expand_builtin_va_copy): Likewise. (expand_builtin_memset): Likewise, but for clear_storage. * c-common.c (lang_get_alias_set): Renamed to c_common_alias_set and remove C++ specific parts. * c-common.h (c_common_get_alias_set): Add declaration. * c-lang.c (LANG_HOOKS_GET_ALIAS_SET): New macro. * calls.c (emit_call_1): Fix typo in sibcall_pop case. (save_fixed_argument_area): Call set_mem_align. Remove alignment in call to emit_block_move. (emit_library_call_value_1, store_one_arg): Likewise. (target_for_arg): Remove; disabled long ago. * emit-rtl.c (set_mem_attributes): Rework to only call get_mem_attrs once and similar cleanups. (offset_address): Use proper introductory comment. * expr.c (emit_block_move): Use alignment from that of MEM args, not from explicit operand; all callers changed. (clear_storage): Likewise. (expand_assignment): Don't call set_mem_alias_set on to_rtx. (store_field): Remove kludge on alias set used for to_rtx. (highest_pow2_factor, case *_DIV_EXPR): Never return 0. (expand_expr_unaligned): Call set_mem_attributes instead of set_mem_alias_set. * expr.h (emit_block_move, clear_storage): Remove ALIGN argument. * function.c (assign_stack_temp_for_type): Set MEM alignment. (expand_function_end): Track MEM attributes of trampolines. * ifcvt.c (noce_try_cmove_arith): Set alignment of new MEM. * integrate.c (copy_rtx_and_substitute, case CALL): Copy memory attributes from original. * langhooks.c (lang_hook_default_get_alias_set): New function. (hook_get_alias_set_0): New function. * langhooks.h (hook_get_alias_set_0): New declaration. (lang_hook_default_get_alias_set): Likewise. (LANG_HOOKS_GET_ALIAS_SET): New macro; add to initializer. * reload1.c (alter_reg): Use adjust_address_nv. * rtl.c (get_mode_alignment): Moved to here. * rtl.h (MEM_ALIGN): Take default from mode, if not BLKmode, and change default if unknown from 1 to BITS_PER_UNIT. * stor-layout.c (get_mode_alignment): Remove from here. * toplev.h (struct lang_hoks): Add get_alias_set field. * tree.h (lang_get_alias_set): Delete declaration. * config/arc/arc.c (arc_setup_incoming_varags): Set MEM alignment. * config/i386/i386.c (ix86_setup_incoming_varargs): Likewise. (ix86_va_arg): Likewise. * config/i960/i960.c (i960_setup_incoming_varargs): Likewise. * config/pa/pa.c (hppa_builtin_saveregs): Likewise. * config/sparc/sparc.c (sparc_va_arg): Likewise. * config/rs6000/rs6000.c (setup_incoming_varargs): Likewise. (expand_block_move_mem): Remove dead code. * cp/cp-lang.c (cxx_get_alias_set): New function. Point LANG_HOOKS_GET_ALIAS_SET to it. * f/com.c (LANG_HOOKS_GET_ALIAS_SET): New macro. (lang_get_alias_set): Delete. * java/lang.c (lang_get_alias_set): Deleted. From-SVN: r46440 --- gcc/ChangeLog | 60 ++++++++++++++++++++++++ gcc/alias.c | 44 +++++++++--------- gcc/builtins.c | 27 +++++++---- gcc/c-common.c | 6 +-- gcc/c-common.h | 2 +- gcc/c-lang.c | 3 ++ gcc/calls.c | 79 +++++++++---------------------- gcc/config/arc/arc.c | 1 + gcc/config/i386/i386.c | 12 +++-- gcc/config/i960/i960.c | 1 + gcc/config/pa/pa.c | 1 + gcc/config/rs6000/rs6000.c | 20 ++++---- gcc/config/sparc/sparc.c | 25 +++++----- gcc/cp/ChangeLog | 5 ++ gcc/cp/cp-lang.c | 18 ++++++++ gcc/emit-rtl.c | 95 +++++++++++++++++++------------------- gcc/expr.c | 75 +++++++++++------------------- gcc/expr.h | 7 ++- gcc/f/ChangeLog | 5 ++ gcc/f/com.c | 23 ++++----- gcc/ifcvt.c | 2 + gcc/integrate.c | 19 +++++--- gcc/java/ChangeLog | 4 ++ gcc/java/lang.c | 10 ---- gcc/langhooks.c | 22 +++++++++ gcc/langhooks.h | 27 +++++++---- gcc/reload1.c | 5 +- gcc/rtl.c | 18 ++++++++ gcc/rtl.h | 6 ++- gcc/stor-layout.c | 17 ------- gcc/toplev.h | 9 +++- gcc/tree.h | 3 -- 32 files changed, 363 insertions(+), 288 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a3b17b2c4e0..6272d5bab1c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,63 @@ +Tue Oct 23 13:05:53 2001 Richard Kenner + + * alias.c (can_address_p): Compnonents are not addressable if + the containing type has alias set 0. + (get_alias_set): Rework to use STRIP_NOPS. + Only call front-end routine on object, type, or object with + NOPs stripped, not inner values. + Use language hook to call front-end routine. + * builtins.c (get_memory_rtx): Always call set_mem_attributes. + (expand_builtin_apply): Call set_mem_align on MEMs we make. + Don't pass alignment to emit_block_move. + (expand_builtin_memcpy, expand_builtin_va_copy): Likewise. + (expand_builtin_memset): Likewise, but for clear_storage. + * c-common.c (lang_get_alias_set): Renamed to c_common_alias_set + and remove C++ specific parts. + * c-common.h (c_common_get_alias_set): Add declaration. + * c-lang.c (LANG_HOOKS_GET_ALIAS_SET): New macro. + * calls.c (emit_call_1): Fix typo in sibcall_pop case. + (save_fixed_argument_area): Call set_mem_align. + Remove alignment in call to emit_block_move. + (emit_library_call_value_1, store_one_arg): Likewise. + (target_for_arg): Remove; disabled long ago. + * emit-rtl.c (set_mem_attributes): Rework to only call get_mem_attrs + once and similar cleanups. + (offset_address): Use proper introductory comment. + * expr.c (emit_block_move): Use alignment from that of MEM args, not + from explicit operand; all callers changed. + (clear_storage): Likewise. + (expand_assignment): Don't call set_mem_alias_set on to_rtx. + (store_field): Remove kludge on alias set used for to_rtx. + (highest_pow2_factor, case *_DIV_EXPR): Never return 0. + (expand_expr_unaligned): Call set_mem_attributes instead of + set_mem_alias_set. + * expr.h (emit_block_move, clear_storage): Remove ALIGN argument. + * function.c (assign_stack_temp_for_type): Set MEM alignment. + (expand_function_end): Track MEM attributes of trampolines. + * ifcvt.c (noce_try_cmove_arith): Set alignment of new MEM. + * integrate.c (copy_rtx_and_substitute, case CALL): Copy memory + attributes from original. + * langhooks.c (lang_hook_default_get_alias_set): New function. + (hook_get_alias_set_0): New function. + * langhooks.h (hook_get_alias_set_0): New declaration. + (lang_hook_default_get_alias_set): Likewise. + (LANG_HOOKS_GET_ALIAS_SET): New macro; add to initializer. + * reload1.c (alter_reg): Use adjust_address_nv. + * rtl.c (get_mode_alignment): Moved to here. + * rtl.h (MEM_ALIGN): Take default from mode, if not BLKmode, and + change default if unknown from 1 to BITS_PER_UNIT. + * stor-layout.c (get_mode_alignment): Remove from here. + * toplev.h (struct lang_hoks): Add get_alias_set field. + * tree.h (lang_get_alias_set): Delete declaration. + * config/arc/arc.c (arc_setup_incoming_varags): Set MEM alignment. + * config/i386/i386.c (ix86_setup_incoming_varargs): Likewise. + (ix86_va_arg): Likewise. + * config/i960/i960.c (i960_setup_incoming_varargs): Likewise. + * config/pa/pa.c (hppa_builtin_saveregs): Likewise. + * config/sparc/sparc.c (sparc_va_arg): Likewise. + * config/rs6000/rs6000.c (setup_incoming_varargs): Likewise. + (expand_block_move_mem): Remove dead code. + 2001-10-22 Neil Booth * c-common.c (warn_div_by_zero): New. diff --git a/gcc/alias.c b/gcc/alias.c index af0141f8cb3..3de48b2973b 100644 --- a/gcc/alias.c +++ b/gcc/alias.c @@ -438,13 +438,18 @@ can_address_p (t) else if (TREE_CODE (t) == BIT_FIELD_REF) return 0; + /* Fields are addressable unless they are marked as nonaddressable or + the containing type has alias set 0. */ else if (TREE_CODE (t) == COMPONENT_REF && ! DECL_NONADDRESSABLE_P (TREE_OPERAND (t, 1)) + && get_alias_set (TREE_TYPE (TREE_OPERAND (t, 0))) != 0 && can_address_p (TREE_OPERAND (t, 0))) return 1; + /* Likewise for arrays. */ else if ((TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF) && ! TYPE_NONALIASED_COMPONENT (TREE_TYPE (TREE_OPERAND (t, 0))) + && get_alias_set (TREE_TYPE (TREE_OPERAND (t, 0))) != 0 && can_address_p (TREE_OPERAND (t, 0))) return 1; @@ -478,22 +483,25 @@ get_alias_set (t) tree inner = t; tree placeholder_ptr = 0; + /* Remove any nops, then give the language a chance to do + something with this tree before we look at it. */ + STRIP_NOPS (t); + set = (*lang_hooks.get_alias_set) (t); + if (set != -1) + return set; + /* First see if the actual object referenced is an INDIRECT_REF from a - restrict-qualified pointer or a "void *". Start by removing nops - since we care only about the actual object. Also replace + restrict-qualified pointer or a "void *". Replace PLACEHOLDER_EXPRs. */ - while (((TREE_CODE (inner) == NOP_EXPR - || TREE_CODE (inner) == CONVERT_EXPR) - && (TYPE_MODE (TREE_TYPE (inner)) - == TYPE_MODE (TREE_TYPE (TREE_OPERAND (inner, 0))))) - || TREE_CODE (inner) == NON_LVALUE_EXPR - || TREE_CODE (inner) == PLACEHOLDER_EXPR + while (TREE_CODE (inner) == PLACEHOLDER_EXPR || handled_component_p (inner)) { if (TREE_CODE (inner) == PLACEHOLDER_EXPR) inner = find_placeholder (inner, &placeholder_ptr); else inner = TREE_OPERAND (inner, 0); + + STRIP_NOPS (inner); } /* Check for accesses through restrict-qualified pointers. */ @@ -540,27 +548,16 @@ get_alias_set (t) /* Otherwise, pick up the outermost object that we could have a pointer to, processing conversion and PLACEHOLDER_EXPR as above. */ placeholder_ptr = 0; - while (((TREE_CODE (t) == NOP_EXPR || TREE_CODE (t) == CONVERT_EXPR) - && (TYPE_MODE (TREE_TYPE (t)) - == TYPE_MODE (TREE_TYPE (TREE_OPERAND (t, 0))))) - || TREE_CODE (t) == NON_LVALUE_EXPR - || TREE_CODE (t) == PLACEHOLDER_EXPR + while (TREE_CODE (t) == PLACEHOLDER_EXPR || (handled_component_p (t) && ! can_address_p (t))) { - /* Give the language a chance to do something with this tree - before we go inside it. */ - if ((set = lang_get_alias_set (t)) != -1) - return set; - if (TREE_CODE (t) == PLACEHOLDER_EXPR) t = find_placeholder (t, &placeholder_ptr); else t = TREE_OPERAND (t, 0); - } - /* Give the language another chance to do something. */ - if ((set = lang_get_alias_set (t)) != -1) - return set; + STRIP_NOPS (t); + } /* If we've already determined the alias set for a decl, just return it. This is necessary for C++ anonymous unions, whose component @@ -580,7 +577,8 @@ get_alias_set (t) return TYPE_ALIAS_SET (t); /* See if the language has special handling for this type. */ - if ((set = lang_get_alias_set (t)) != -1) + set = (*lang_hooks.get_alias_set) (t); + if (set != -1) return set; /* There are no objects of FUNCTION_TYPE, so there's no point in diff --git a/gcc/builtins.c b/gcc/builtins.c index 0576886490d..fe127925ac2 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -724,6 +724,8 @@ get_memory_rtx (exp) expand_expr (exp, NULL_RTX, ptr_mode, EXPAND_SUM))); + set_mem_attributes (mem, exp, 0); + /* Get an expression we can use to find the attributes to assign to MEM. If it is an ADDR_EXPR, use the operand. Otherwise, dereference it if we can. First remove any nops. */ @@ -739,7 +741,6 @@ get_memory_rtx (exp) else return mem; - set_mem_attributes (mem, exp, 0); /* memcpy, memset and other builtin stringops can alias with anything. */ set_mem_alias_set (mem, 0); return mem; @@ -1040,7 +1041,7 @@ expand_builtin_apply (function, arguments, argsize) { int size, align, regno; enum machine_mode mode; - rtx incoming_args, result, reg, dest, call_insn; + rtx incoming_args, result, reg, dest, src, call_insn; rtx old_stack_level = 0; rtx call_fusage = 0; @@ -1079,13 +1080,16 @@ expand_builtin_apply (function, arguments, argsize) but it's likely that the source and/or destination addresses in the block copy will need updating in machine specific ways. */ dest = allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT); - emit_block_move (gen_rtx_MEM (BLKmode, dest), - gen_rtx_MEM (BLKmode, incoming_args), - argsize, PARM_BOUNDARY); + dest = gen_rtx_MEM (BLKmode, dest); + set_mem_align (dest, PARM_BOUNDARY); + src = gen_rtx_MEM (BLKmode, incoming_args); + set_mem_align (src, PARM_BOUNDARY); + emit_block_move (dest, src, argsize); /* Refer to the argument block. */ apply_args_size (); arguments = gen_rtx_MEM (BLKmode, arguments); + set_mem_align (arguments, PARM_BOUNDARY); /* Walk past the arg-pointer and structure value address. */ size = GET_MODE_SIZE (Pmode); @@ -1813,6 +1817,7 @@ expand_builtin_memcpy (arglist) return 0; dest_mem = get_memory_rtx (dest); + set_mem_align (dest_mem, dest_align); len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0); src_str = c_getstr (src); @@ -1833,6 +1838,7 @@ expand_builtin_memcpy (arglist) } src_mem = get_memory_rtx (src); + set_mem_align (src_mem, src_align); /* Just copy the rights of SRC to the rights of DEST. */ if (current_function_check_memory_usage) @@ -1842,9 +1848,7 @@ expand_builtin_memcpy (arglist) len_rtx, TYPE_MODE (sizetype)); /* Copy word part most expediently. */ - dest_addr - = emit_block_move (dest_mem, src_mem, len_rtx, - MIN (src_align, dest_align)); + dest_addr = emit_block_move (dest_mem, src_mem, len_rtx); if (dest_addr == 0) dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX); @@ -2041,6 +2045,7 @@ expand_builtin_memset (exp) len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0); dest_mem = get_memory_rtx (dest); + set_mem_align (dest_mem, dest_align); /* Just check DST is writable and mark it as readable. */ if (current_function_check_memory_usage) @@ -2051,7 +2056,7 @@ expand_builtin_memset (exp) TYPE_MODE (integer_type_node)); - dest_addr = clear_storage (dest_mem, len_rtx, dest_align); + dest_addr = clear_storage (dest_mem, len_rtx); if (dest_addr == 0) dest_addr = force_operand (XEXP (dest_mem, 0), NULL_RTX); @@ -3013,11 +3018,13 @@ expand_builtin_va_copy (arglist) /* "Dereference" to BLKmode memories. */ dstb = gen_rtx_MEM (BLKmode, dstb); set_mem_alias_set (dstb, get_alias_set (TREE_TYPE (TREE_TYPE (dst)))); + set_mem_align (dstb, TYPE_ALIGN (va_list_type_node)); srcb = gen_rtx_MEM (BLKmode, srcb); set_mem_alias_set (srcb, get_alias_set (TREE_TYPE (TREE_TYPE (src)))); + set_mem_align (srcb, TYPE_ALIGN (va_list_type_node)); /* Copy. */ - emit_block_move (dstb, srcb, size, TYPE_ALIGN (va_list_type_node)); + emit_block_move (dstb, srcb, size); } return const0_rtx; diff --git a/gcc/c-common.c b/gcc/c-common.c index bc81a1a3a01..7f42e5cddeb 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -2146,7 +2146,7 @@ c_apply_type_quals_to_decl (type_quals, decl) or a type. Return -1 if we don't do anything special. */ HOST_WIDE_INT -lang_get_alias_set (t) +c_common_get_alias_set (t) tree t; { tree u; @@ -2221,10 +2221,6 @@ lang_get_alias_set (t) if (t1 != t) return get_alias_set (t1); } - /* It's not yet safe to use alias sets for classes in C++ because - the TYPE_FIELDs list for a class doesn't mention base classes. */ - else if (c_language == clk_cplusplus && AGGREGATE_TYPE_P (t)) - return 0; return -1; } diff --git a/gcc/c-common.h b/gcc/c-common.h index 0d45693531f..8d378b82348 100644 --- a/gcc/c-common.h +++ b/gcc/c-common.h @@ -542,7 +542,7 @@ extern void c_common_nodes_and_builtins PARAMS ((void)); extern tree build_va_arg PARAMS ((tree, tree)); extern void c_common_lang_init PARAMS ((void)); - +extern HOST_WIDE_INT c_common_get_alias_set PARAMS ((tree)); extern bool c_promoting_integer_type_p PARAMS ((tree)); extern int self_promoting_args_p PARAMS ((tree)); extern tree simple_type_promotes_to PARAMS ((tree)); diff --git a/gcc/c-lang.c b/gcc/c-lang.c index e1fd83eaa56..59e8d5c040a 100644 --- a/gcc/c-lang.c +++ b/gcc/c-lang.c @@ -56,6 +56,9 @@ static int c_cannot_inline_tree_fn PARAMS ((tree *)); #define LANG_HOOKS_DECODE_OPTION c_decode_option #undef LANG_HOOKS_POST_OPTIONS #define LANG_HOOKS_POST_OPTIONS c_post_options +#undef LANG_HOOKS_GET_ALIAS_SET +#define LANG_HOOKS_GET_ALIAS_SET c_common_get_alias_set + #undef LANG_HOOKS_TREE_INLINING_CANNOT_INLINE_TREE_FN #define LANG_HOOKS_TREE_INLINING_CANNOT_INLINE_TREE_FN \ c_cannot_inline_tree_fn diff --git a/gcc/calls.c b/gcc/calls.c index 5a4850242bc..957ddaedf3e 100644 --- a/gcc/calls.c +++ b/gcc/calls.c @@ -475,7 +475,7 @@ emit_call_1 (funexp, fndecl, funtype, stack_size, rounded_stack_size, && HAVE_sibcall_pop && HAVE_sibcall_value_pop && (n_popped > 0 || stack_size == 0)) { - rtx n_pop = GEN_INT (n_popped)); + rtx n_pop = GEN_INT (n_popped); rtx pat; /* If this subroutine pops its own args, record that in the call insn @@ -497,10 +497,10 @@ emit_call_1 (funexp, fndecl, funtype, stack_size, rounded_stack_size, #endif #if defined (HAVE_call_pop) && defined (HAVE_call_value_pop) -/* If the target has "call" or "call_value" insns, then prefer them - if no arguments are actually popped. If the target does not have - "call" or "call_value" insns, then we must use the popping versions - even if the call has no arguments to pop. */ + /* If the target has "call" or "call_value" insns, then prefer them + if no arguments are actually popped. If the target does not have + "call" or "call_value" insns, then we must use the popping versions + even if the call has no arguments to pop. */ #if defined (HAVE_call) && defined (HAVE_call_value) if (HAVE_call && HAVE_call_value && HAVE_call_pop && HAVE_call_value_pop && n_popped > 0 && ! (ecf_flags & ECF_SP_DEPRESSED)) @@ -573,12 +573,12 @@ emit_call_1 (funexp, fndecl, funtype, stack_size, rounded_stack_size, /* Mark memory as used for "pure" function call. */ if (ecf_flags & ECF_PURE) - { - call_fusage = gen_rtx_EXPR_LIST (VOIDmode, - gen_rtx_USE (VOIDmode, - gen_rtx_MEM (BLKmode, - gen_rtx_SCRATCH (VOIDmode))), call_fusage); - } + call_fusage + = gen_rtx_EXPR_LIST + (VOIDmode, + gen_rtx_USE (VOIDmode, + gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode))), + call_fusage); /* Put the register usage information on the CALL. If there is already some usage information, put ours at the end. */ @@ -939,6 +939,8 @@ save_fixed_argument_area (reg_parm_stack_space, argblock, plus_constant (argblock, *low_to_save))); #endif + + set_mem_align (stack_area, PARM_BOUNDARY); if (save_mode == BLKmode) { save_area = assign_stack_temp (BLKmode, num_to_save, 0); @@ -954,6 +956,7 @@ save_fixed_argument_area (reg_parm_stack_space, argblock, emit_move_insn (save_area, stack_area); } } + return save_area; } @@ -3322,8 +3325,7 @@ expand_call (exp, target, ignore) else emit_block_move (stack_area, validize_mem (args[i].save_area), - GEN_INT (args[i].size.constant), - PARM_BOUNDARY); + GEN_INT (args[i].size.constant)); } highest_outgoing_arg_in_use = initial_highest_arg_in_use; @@ -3447,6 +3449,7 @@ expand_call (exp, target, ignore) /* Output a library call to function FUN (a SYMBOL_REF rtx). The RETVAL parameter specifies whether return value needs to be saved, other parameters are documented in the emit_library_call function below. */ + static rtx emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p) int retval; @@ -3894,8 +3897,8 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p) if (save_mode == BLKmode) { save_area = assign_stack_temp (BLKmode, num_to_save, 0); - emit_block_move (validize_mem (save_area), stack_area, - GEN_INT (num_to_save), PARM_BOUNDARY); + set_mem_align (save_area, PARM_BOUNDARY); + emit_block_move (validize_mem (save_area), stack_area); } else { @@ -4161,12 +4164,13 @@ emit_library_call_value_1 (retval, orgfun, value, fn_type, outmode, nargs, p) memory_address (save_mode, plus_constant (argblock, low_to_save))); #endif + + set_mem_align (stack_area, PARM_BOUNDARY); if (save_mode != BLKmode) emit_move_insn (stack_area, save_area); else emit_block_move (stack_area, validize_mem (save_area), - GEN_INT (high_to_save - low_to_save + 1), - PARM_BOUNDARY); + GEN_INT (high_to_save - low_to_save + 1)); } #endif @@ -4250,44 +4254,6 @@ emit_library_call_value VPARAMS((rtx orgfun, rtx value, return result; } -#if 0 -/* Return an rtx which represents a suitable home on the stack - given TYPE, the type of the argument looking for a home. - This is called only for BLKmode arguments. - - SIZE is the size needed for this target. - ARGS_ADDR is the address of the bottom of the argument block for this call. - OFFSET describes this parameter's offset into ARGS_ADDR. It is meaningless - if this machine uses push insns. */ - -static rtx -target_for_arg (type, size, args_addr, offset) - tree type; - rtx size; - rtx args_addr; - struct args_size offset; -{ - rtx target; - rtx offset_rtx = ARGS_SIZE_RTX (offset); - - /* We do not call memory_address if possible, - because we want to address as close to the stack - as possible. For non-variable sized arguments, - this will be stack-pointer relative addressing. */ - if (GET_CODE (offset_rtx) == CONST_INT) - target = plus_constant (args_addr, INTVAL (offset_rtx)); - else - { - /* I have no idea how to guarantee that this - will work in the presence of register parameters. */ - target = gen_rtx_PLUS (Pmode, args_addr, offset_rtx); - target = memory_address (QImode, target); - } - - return gen_rtx_MEM (BLKmode, target); -} -#endif - /* Store a single argument for a function call into the register or memory area where it must be passed. *ARG describes the argument value and where to pass it. @@ -4379,8 +4345,7 @@ store_one_arg (arg, argblock, flags, variable_size, reg_parm_stack_space) arg->save_area = assign_temp (nt, 0, 1, 1); preserve_temp_slots (arg->save_area); emit_block_move (validize_mem (arg->save_area), stack_area, - expr_size (arg->tree_value), - MIN (PARM_BOUNDARY, TYPE_ALIGN (nt))); + expr_size (arg->tree_value)); } else { diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c index 49b0f162b8e..79586d04f16 100644 --- a/gcc/config/arc/arc.c +++ b/gcc/config/arc/arc.c @@ -813,6 +813,7 @@ arc_setup_incoming_varargs (cum, mode, type, pretend_size, no_rtl) FIRST_PARM_OFFSET (0) + align_slop * UNITS_PER_WORD)); set_mem_alias_set (regblock, get_varargs_alias_set ()); + set_mem_align (regblock, BITS_PER_WORD); move_block_from_reg (first_reg_offset, regblock, MAX_ARC_PARM_REGS - first_reg_offset, ((MAX_ARC_PARM_REGS - first_reg_offset) diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 5291d9c0d94..52e24146cb8 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -2249,14 +2249,16 @@ ix86_setup_incoming_varargs (cum, mode, type, pretend_size, no_rtl) pointing 127 bytes after first byte to store - this is needed to keep instruction size limited by 4 bytes. */ tmp_reg = gen_reg_rtx (Pmode); - emit_insn (gen_rtx_SET(VOIDmode, tmp_reg, - plus_constant (save_area, 8 * REGPARM_MAX + 127))); + emit_insn (gen_rtx_SET (VOIDmode, tmp_reg, + plus_constant (save_area, + 8 * REGPARM_MAX + 127))); mem = gen_rtx_MEM (BLKmode, plus_constant (tmp_reg, -127)); set_mem_alias_set (mem, set); + set_mem_align (mem, BITS_PER_WORD); /* And finally do the dirty job! */ - emit_insn (gen_sse_prologue_save (mem, nsse_reg, GEN_INT (next_cum.sse_regno), - label)); + emit_insn (gen_sse_prologue_save (mem, nsse_reg, + GEN_INT (next_cum.sse_regno), label)); } } @@ -2467,6 +2469,7 @@ ix86_va_arg (valist, type) addr_rtx = XEXP (assign_temp (type, 0, 1, 0), 0); mem = gen_rtx_MEM (BLKmode, addr_rtx); set_mem_alias_set (mem, get_varargs_alias_set ()); + set_mem_align (mem, BITS_PER_UNIT); for (i = 0; i < XVECLEN (container, 0); i++) { @@ -2492,7 +2495,6 @@ ix86_va_arg (valist, type) set_mem_alias_set (src_mem, get_varargs_alias_set ()); src_mem = adjust_address (src_mem, mode, src_offset); dest_mem = adjust_address (mem, mode, INTVAL (XEXP (slot, 1))); - PUT_MODE (dest_mem, mode); emit_move_insn (dest_mem, src_mem); } } diff --git a/gcc/config/i960/i960.c b/gcc/config/i960/i960.c index 12b1548d3d8..8c7c8d40b12 100644 --- a/gcc/config/i960/i960.c +++ b/gcc/config/i960/i960.c @@ -2583,6 +2583,7 @@ i960_setup_incoming_varargs (cum, mode, type, pretend_size, no_rtl) regblock = gen_rtx_MEM (BLKmode, plus_constant (arg_pointer_rtx, first_reg * 4)); set_mem_alias_set (regblock, get_varargs_alias_set ()); + set_mem_align (regblock, BITS_PER_WORD); move_block_from_reg (first_reg, regblock, NPARM_REGS - first_reg, (NPARM_REGS - first_reg) * UNITS_PER_WORD); diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c index fa23eaa9018..593f0858cf4 100644 --- a/gcc/config/pa/pa.c +++ b/gcc/config/pa/pa.c @@ -4872,6 +4872,7 @@ hppa_builtin_saveregs () plus_constant (current_function_internal_arg_pointer, -16)); set_mem_alias_set (dest, get_varargs_alias_set ()); + set_mem_align (dest, BITS_PER_WORD); move_block_from_reg (23, dest, 4, 4 * UNITS_PER_WORD); /* move_block_from_reg will emit code to store the argument registers diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index a55459edf02..6e6f428f6e0 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -2499,6 +2499,7 @@ setup_incoming_varargs (cum, mode, type, pretend_size, no_rtl) plus_constant (save_area, first_reg_offset * reg_size)), set_mem_alias_set (mem, set); + set_mem_align (mem, BITS_PER_WORD); move_block_from_reg (GP_ARG_MIN_REG + first_reg_offset, mem, @@ -2850,9 +2851,6 @@ expand_block_move_mem (mode, addr, orig_mem) rtx mem = gen_rtx_MEM (mode, addr); MEM_COPY_ATTRIBUTES (mem, orig_mem); -#ifdef MEM_UNALIGNED_P - MEM_UNALIGNED_P (mem) = MEM_UNALIGNED_P (orig_mem); -#endif return mem; } @@ -5697,12 +5695,16 @@ rs6000_return_addr (count, frame) || DEFAULT_ABI == ABI_AIX_NODESC) { cfun->machine->ra_needs_full_frame = 1; - return gen_rtx_MEM (Pmode, - memory_address (Pmode, - plus_constant (copy_to_reg - (gen_rtx_MEM (Pmode, - memory_address (Pmode, frame))), - RETURN_ADDRESS_OFFSET))); + + return + gen_rtx_MEM + (Pmode, + memory_address + (Pmode, + plus_constant (copy_to_reg + (gen_rtx_MEM (Pmode, + memory_address (Pmode, frame))), + RETURN_ADDRESS_OFFSET))); } return get_hard_reg_initial_val (Pmode, LINK_REGISTER_REGNUM); diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index 1af8c5f4ff1..1b64987dabe 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -2811,8 +2811,8 @@ legitimize_pic_address (orig, mode, reg) address = orig; pic_ref = gen_rtx_MEM (Pmode, - gen_rtx_PLUS (Pmode, - pic_offset_table_rtx, address)); + gen_rtx_PLUS (Pmode, + pic_offset_table_rtx, address)); current_function_uses_pic_offset_table = 1; RTX_UNCHANGING_P (pic_ref) = 1; insn = emit_move_insn (reg, pic_ref); @@ -4833,17 +4833,18 @@ sparc_builtin_saveregs () for (regno = first_reg; regno < NPARM_REGS (word_mode); regno++) emit_move_insn (gen_rtx_MEM (word_mode, - gen_rtx_PLUS (Pmode, - frame_pointer_rtx, - GEN_INT (STACK_POINTER_OFFSET - + UNITS_PER_WORD * regno))), + gen_rtx_PLUS (Pmode, + frame_pointer_rtx, + GEN_INT (STACK_POINTER_OFFSET + + (UNITS_PER_WORD + * regno)))), gen_rtx_REG (word_mode, - BASE_INCOMING_ARG_REG (word_mode) + regno)); + BASE_INCOMING_ARG_REG (word_mode) + regno)); address = gen_rtx_PLUS (Pmode, - frame_pointer_rtx, - GEN_INT (STACK_POINTER_OFFSET - + UNITS_PER_WORD * first_reg)); + frame_pointer_rtx, + GEN_INT (STACK_POINTER_OFFSET + + UNITS_PER_WORD * first_reg)); if (current_function_check_memory_usage && first_reg < NPARM_REGS (word_mode)) @@ -4955,12 +4956,12 @@ sparc_va_arg (valist, type) addr_rtx = force_reg (Pmode, addr_rtx); addr_rtx = gen_rtx_MEM (BLKmode, addr_rtx); set_mem_alias_set (addr_rtx, get_varargs_alias_set ()); + set_mem_align (addr_rtx, BITS_PER_WORD); tmp = shallow_copy_rtx (tmp); PUT_MODE (tmp, BLKmode); set_mem_alias_set (tmp, 0); - dest_addr = emit_block_move (tmp, addr_rtx, GEN_INT (rsize), - BITS_PER_WORD); + dest_addr = emit_block_move (tmp, addr_rtx, GEN_INT (rsize)); if (dest_addr != NULL_RTX) addr_rtx = dest_addr; else diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index b8c3740ffa5..a8f7c2fdafb 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +Tue Oct 23 14:00:20 2001 Richard Kenner + + * cp-lang.c (cxx_get_alias_set): New function. + Point LANG_HOOKS_GET_ALIAS_SET to it. + 2001-10-23 Kriang Lerdsuwanakij * cp-tree.def (UNBOUND_CLASS_TEMPLATE): New tree node. diff --git a/gcc/cp/cp-lang.c b/gcc/cp/cp-lang.c index 719f55840c0..ca9f88fb8cb 100644 --- a/gcc/cp/cp-lang.c +++ b/gcc/cp/cp-lang.c @@ -26,6 +26,8 @@ Boston, MA 02111-1307, USA. */ #include "toplev.h" #include "langhooks.h" +static HOST_WIDE_INT cxx_get_alias_set PARAMS ((tree)); + #undef LANG_HOOKS_INIT #define LANG_HOOKS_INIT cxx_init #undef LANG_HOOKS_FINISH @@ -36,6 +38,8 @@ Boston, MA 02111-1307, USA. */ #define LANG_HOOKS_DECODE_OPTION cxx_decode_option #undef LANG_HOOKS_POST_OPTIONS #define LANG_HOOKS_POST_OPTIONS cxx_post_options +#undef LANG_HOOKS_GET_ALIAS_SET +#define LANG_HOOKS_GET_ALIAS_SET cxx_get_alias_set #undef LANG_HOOKS_TREE_INLINING_WALK_SUBTREES #define LANG_HOOKS_TREE_INLINING_WALK_SUBTREES \ @@ -60,3 +64,17 @@ Boston, MA 02111-1307, USA. */ /* Each front end provides its own hooks, for toplev.c. */ struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER; + +/* Special routine to get the alias set for C++. */ + +static HOST_WIDE_INT +cxx_get_alias_set (t) + tree t; +{ + /* It's not yet safe to use alias sets for classes in C++ because + the TYPE_FIELDs list for a class doesn't mention base classes. */ + if (AGGREGATE_TYPE_P (t)) + return 0; + + return c_common_get_alias_set (t); +} diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c index eb71518ead6..79cdf5cdfab 100644 --- a/gcc/emit-rtl.c +++ b/gcc/emit-rtl.c @@ -1651,6 +1651,11 @@ set_mem_attributes (ref, t, objectp) tree t; int objectp; { + HOST_WIDE_INT alias = MEM_ALIAS_SET (ref); + tree decl = MEM_DECL (ref); + rtx offset = MEM_OFFSET (ref); + rtx size = MEM_SIZE (ref); + unsigned int align = MEM_ALIGN (ref); tree type; /* It can happen that type_for_mode was given a mode for which there @@ -1669,8 +1674,8 @@ set_mem_attributes (ref, t, objectp) abort (); /* Get the alias set from the expression or type (perhaps using a - front-end routine). */ - set_mem_alias_set (ref, get_alias_set (t)); + front-end routine) and use it. */ + alias = get_alias_set (t); MEM_VOLATILE_P (ref) = TYPE_VOLATILE (type); MEM_IN_STRUCT_P (ref) = AGGREGATE_TYPE_P (type); @@ -1678,57 +1683,54 @@ set_mem_attributes (ref, t, objectp) |= (lang_hooks.honor_readonly && (TYPE_READONLY (type) || TREE_READONLY (t))); - /* If we are making an object of this type, we know that it is a scalar if - the type is not an aggregate. */ - if (objectp && ! AGGREGATE_TYPE_P (type)) + /* If we are making an object of this type, or if this is a DECL, we know + that it is a scalar if the type is not an aggregate. */ + if ((objectp || DECL_P (t)) && ! AGGREGATE_TYPE_P (type)) MEM_SCALAR_P (ref) = 1; /* If the size is known, we can set that. */ if (TYPE_SIZE_UNIT (type) && host_integerp (TYPE_SIZE_UNIT (type), 1)) - MEM_ATTRS (ref) - = get_mem_attrs (MEM_ALIAS_SET (ref), MEM_DECL (ref), MEM_OFFSET (ref), - GEN_INT (tree_low_cst (TYPE_SIZE_UNIT (type), 1)), - MEM_ALIGN (ref)); + size = GEN_INT (tree_low_cst (TYPE_SIZE_UNIT (type), 1)); - /* If T is a type, there's nothing more we can do. Otherwise, we may be able - to deduce some more information about the expression. */ + /* If T is not a type. Otherwise, we may be able to deduce some more + information about the expression. */ if (TYPE_P (t)) - return; - - maybe_set_unchanging (ref, t); - if (TREE_THIS_VOLATILE (t)) - MEM_VOLATILE_P (ref) = 1; + { + maybe_set_unchanging (ref, t); + if (TREE_THIS_VOLATILE (t)) + MEM_VOLATILE_P (ref) = 1; - /* Now remove any NOPs: they don't change what the underlying object is. + /* Now remove any NOPs: they don't change what the underlying object is. Likewise for SAVE_EXPR. */ - while (TREE_CODE (t) == NOP_EXPR || TREE_CODE (t) == CONVERT_EXPR - || TREE_CODE (t) == NON_LVALUE_EXPR || TREE_CODE (t) == SAVE_EXPR) - t = TREE_OPERAND (t, 0); - - /* If this is a decl, set the attributes of the MEM from it. */ - if (DECL_P (t)) - MEM_ATTRS (ref) - = get_mem_attrs - (MEM_ALIAS_SET (ref), t, GEN_INT (0), - (TYPE_SIZE_UNIT (TREE_TYPE (t)) - && host_integerp (TYPE_SIZE_UNIT (TREE_TYPE (t)), 1)) - ? GEN_INT (tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (t)), 1)) - : 0, DECL_ALIGN (t)); - - /* If this is an INDIRECT_REF, we know its alignment. */ - if (TREE_CODE (t) == INDIRECT_REF) - set_mem_align (ref, TYPE_ALIGN (type)); - - /* Now see if we can say more about whether it's an aggregate or - scalar. If we already know it's an aggregate, don't bother. */ - if (MEM_IN_STRUCT_P (ref)) + while (TREE_CODE (t) == NOP_EXPR || TREE_CODE (t) == CONVERT_EXPR + || TREE_CODE (t) == NON_LVALUE_EXPR || TREE_CODE (t) == SAVE_EXPR) + t = TREE_OPERAND (t, 0); + + /* If this is a decl, set the attributes of the MEM from it. */ + if (DECL_P (t)) + { + decl = t; + offset = GEN_INT (0); + size = (DECL_SIZE_UNIT (t) + && host_integerp (DECL_SIZE_UNIT (t), 1) + ? GEN_INT (tree_low_cst (DECL_SIZE_UNIT (t), 1)) : 0); + align = DECL_ALIGN (t); + } + + /* If this is an INDIRECT_REF, we know its alignment. */ + else if (TREE_CODE (t) == INDIRECT_REF) + align = TYPE_ALIGN (type); + } + + /* Now set the attributes we computed above. */ + MEM_ATTRS (ref) = get_mem_attrs (alias, decl, offset, size, align); + + /* If this is already known to be a scalar or aggregate, we are done. */ + if (MEM_IN_STRUCT_P (ref) || MEM_SCALAR_P (ref)) return; - /* Since we already know the type isn't an aggregate, if this is a decl, - it must be a scalar. Or if it is a reference into an aggregate, - this is part of an aggregate. Otherwise we don't know. */ - if (DECL_P (t)) - MEM_SCALAR_P (ref) = 1; + /* If it is a reference into an aggregate, this is part of an aggregate. + Otherwise we don't know. */ else if (TREE_CODE (t) == COMPONENT_REF || TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF || TREE_CODE (t) == BIT_FIELD_REF) @@ -1878,10 +1880,9 @@ adjust_address_1 (memref, mode, offset, validate) return new; } -/* Return a memory reference like MEMREF, but with its address changed to - ADDR. The caller is asserting that the actual piece of memory pointed - to is the same, just the form of the address is being changed, such as - by putting something into a register. */ +/* Return a memory reference like MEMREF, but whose address is changed by + adding OFFSET, an RTX, to it. POW2 is the highest power of two factor + known to be in OFFSET (possibly 1). */ rtx offset_address (memref, offset, pow2) diff --git a/gcc/expr.c b/gcc/expr.c index 3290b39496d..77503d3bc95 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -1635,16 +1635,16 @@ move_by_pieces_1 (genfun, mode, data) 0 otherwise. */ rtx -emit_block_move (x, y, size, align) +emit_block_move (x, y, size) rtx x, y; rtx size; - unsigned int align; { rtx retval = 0; #ifdef TARGET_MEM_FUNCTIONS static tree fn; tree call_expr, arg_list; #endif + unsigned int align = MIN (MEM_ALIGN (x), MEM_ALIGN (y)); if (GET_MODE (x) != BLKmode) abort (); @@ -2540,21 +2540,20 @@ store_by_pieces_2 (genfun, mode, data) } /* Write zeros through the storage of OBJECT. If OBJECT has BLKmode, SIZE is - its length in bytes and ALIGN is the maximum alignment we can is has. - - If we call a function that returns the length of the block, return it. */ + its length in bytes. */ rtx -clear_storage (object, size, align) +clear_storage (object, size) rtx object; rtx size; - unsigned int align; { #ifdef TARGET_MEM_FUNCTIONS static tree fn; tree call_expr, arg_list; #endif rtx retval = 0; + unsigned int align = (GET_CODE (object) == MEM ? MEM_ALIGN (object) + : GET_MODE_ALIGNMENT (GET_MODE (object))); /* If OBJECT is not BLKmode and SIZE is the same size as its mode, just move a zero. Otherwise, do this a piece at a time. */ @@ -3415,6 +3414,8 @@ emit_push_insn (x, mode, type, size, align, partial, reg, extra, of sibling calls. */ set_mem_alias_set (target, 0); } + else + set_mem_align (target, align); /* TEMP is the address of the block. Copy the data there. */ if (GET_CODE (size) == CONST_INT @@ -3833,8 +3834,8 @@ expand_assignment (to, from, want_value, suggest_reg) rtx inner_to_rtx = adjust_address (to_rtx, BLKmode, bitpos / BITS_PER_UNIT); - emit_block_move (inner_to_rtx, from_rtx, expr_size (from), - MIN (alignment, from_align)); + emit_block_move (inner_to_rtx, from_rtx, expr_size (from)); + free_temp_slots (); pop_temp_slots (); return to_rtx; @@ -3894,8 +3895,7 @@ expand_assignment (to, from, want_value, suggest_reg) emit_group_load (to_rtx, value, int_size_in_bytes (TREE_TYPE (from)), TYPE_ALIGN (TREE_TYPE (from))); else if (GET_MODE (to_rtx) == BLKmode) - emit_block_move (to_rtx, value, expr_size (from), - TYPE_ALIGN (TREE_TYPE (from))); + emit_block_move (to_rtx, value, expr_size (from)); else { #ifdef POINTERS_EXTEND_UNSIGNED @@ -3915,11 +3915,7 @@ expand_assignment (to, from, want_value, suggest_reg) Don't re-expand if it was expanded already (in COMPONENT_REF case). */ if (to_rtx == 0) - { - to_rtx = expand_expr (to, NULL_RTX, VOIDmode, EXPAND_MEMORY_USE_WO); - if (GET_CODE (to_rtx) == MEM) - set_mem_alias_set (to_rtx, get_alias_set (to)); - } + to_rtx = expand_expr (to, NULL_RTX, VOIDmode, EXPAND_MEMORY_USE_WO); /* Don't move directly into a return register. */ if (TREE_CODE (to) == RESULT_DECL @@ -4274,7 +4270,7 @@ store_expr (exp, target, want_value) size = expr_size (exp); if (GET_CODE (size) == CONST_INT && INTVAL (size) < TREE_STRING_LENGTH (exp)) - emit_block_move (target, temp, size, TYPE_ALIGN (TREE_TYPE (exp))); + emit_block_move (target, temp, size); else { /* Compute the size of the data to copy from the string. */ @@ -4282,14 +4278,12 @@ store_expr (exp, target, want_value) = size_binop (MIN_EXPR, make_tree (sizetype, size), size_int (TREE_STRING_LENGTH (exp))); - unsigned int align = TYPE_ALIGN (TREE_TYPE (exp)); rtx copy_size_rtx = expand_expr (copy_size, NULL_RTX, VOIDmode, 0); rtx label = 0; /* Copy that much. */ - emit_block_move (target, temp, copy_size_rtx, - TYPE_ALIGN (TREE_TYPE (exp))); + emit_block_move (target, temp, copy_size_rtx); /* Figure out how much is left in TARGET that we have to clear. Do all calculations in ptr_mode. */ @@ -4301,10 +4295,6 @@ store_expr (exp, target, want_value) { addr = plus_constant (addr, TREE_STRING_LENGTH (exp)); size = plus_constant (size, -TREE_STRING_LENGTH (exp)); - align = MIN (align, - (unsigned int) (BITS_PER_UNIT - * (INTVAL (copy_size_rtx) - & - INTVAL (copy_size_rtx)))); } else { @@ -4317,12 +4307,10 @@ store_expr (exp, target, want_value) copy_size_rtx, NULL_RTX, 0, OPTAB_LIB_WIDEN); - align = BITS_PER_UNIT; label = gen_label_rtx (); emit_cmp_and_jump_insns (size, const0_rtx, LT, NULL_RTX, GET_MODE (size), 0, 0, label); } - align = MIN (align, expr_align (copy_size)); if (size != const0_rtx) { @@ -4340,7 +4328,7 @@ store_expr (exp, target, want_value) GEN_INT (MEMORY_USE_WO), TYPE_MODE (integer_type_node)); in_check_memory_usage = 0; - clear_storage (dest, size, align); + clear_storage (dest, size); } if (label) @@ -4353,8 +4341,7 @@ store_expr (exp, target, want_value) emit_group_load (target, temp, int_size_in_bytes (TREE_TYPE (exp)), TYPE_ALIGN (TREE_TYPE (exp))); else if (GET_MODE (temp) == BLKmode) - emit_block_move (target, temp, expr_size (exp), - TYPE_ALIGN (TREE_TYPE (exp))); + emit_block_move (target, temp, expr_size (exp)); else emit_move_insn (target, temp); } @@ -4552,7 +4539,7 @@ store_constructor (exp, target, align, cleared, size) /* If the constructor is empty, clear the union. */ if (! CONSTRUCTOR_ELTS (exp) && ! cleared) - clear_storage (target, expr_size (exp), TYPE_ALIGN (type)); + clear_storage (target, expr_size (exp)); } /* If we are building a static constructor into a register, @@ -4581,7 +4568,7 @@ store_constructor (exp, target, align, cleared, size) || (HOST_WIDE_INT) GET_MODE_SIZE (GET_MODE (target)) == size)) { if (! cleared) - clear_storage (target, GEN_INT (size), align); + clear_storage (target, GEN_INT (size)); cleared = 1; } @@ -4776,7 +4763,7 @@ store_constructor (exp, target, align, cleared, size) if (need_to_clear && size > 0) { if (! cleared) - clear_storage (target, GEN_INT (size), align); + clear_storage (target, GEN_INT (size)); cleared = 1; } else if (REG_P (target)) @@ -4962,7 +4949,7 @@ store_constructor (exp, target, align, cleared, size) if (elt == NULL_TREE && size > 0) { if (!cleared) - clear_storage (target, GEN_INT (size), TYPE_ALIGN (type)); + clear_storage (target, GEN_INT (size)); return; } @@ -5037,7 +5024,7 @@ store_constructor (exp, target, align, cleared, size) || (tree_low_cst (TREE_VALUE (elt), 0) - tree_low_cst (TREE_PURPOSE (elt), 0) + 1 != (HOST_WIDE_INT) nbits)))) - clear_storage (target, expr_size (exp), TYPE_ALIGN (type)); + clear_storage (target, expr_size (exp)); for (; elt != NULL_TREE; elt = TREE_CHAIN (elt)) { @@ -5281,8 +5268,7 @@ store_field (target, bitsize, bitpos, mode, exp, value_mode, emit_block_move (target, temp, bitsize == -1 ? expr_size (exp) : GEN_INT ((bitsize + BITS_PER_UNIT - 1) - / BITS_PER_UNIT), - align); + / BITS_PER_UNIT)); return value_mode == VOIDmode ? const0_rtx : target; } @@ -5343,15 +5329,7 @@ store_field (target, bitsize, bitpos, mode, exp, value_mode, bitpos / BITS_PER_UNIT)); MEM_SET_IN_STRUCT_P (to_rtx, 1); - /* If the address of the structure varies, then it might be on - the stack. And, stack slots may be shared across scopes. - So, two different structures, of different types, can end up - at the same location. We will give the structures alias set - zero; here we must be careful not to give non-zero alias sets - to their fields. */ - set_mem_alias_set (to_rtx, - rtx_varies_p (addr, /*for_alias=*/0) - ? 0 : alias_set); + set_mem_alias_set (to_rtx, alias_set); return store_expr (exp, to_rtx, value_mode != VOIDmode); } @@ -5999,7 +5977,7 @@ highest_pow2_factor (exp) case CEIL_DIV_EXPR: c0 = highest_pow2_factor (TREE_OPERAND (exp, 0)); c1 = highest_pow2_factor (TREE_OPERAND (exp, 1)); - return c0 / c1; + return MAX (1, c0 / c1); case NON_LVALUE_EXPR: case NOP_EXPR: case CONVERT_EXPR: case COMPOUND_EXPR: case SAVE_EXPR: @@ -7189,8 +7167,7 @@ expand_expr (exp, target, tmode, modifier) emit_block_move (target, op0, bitsize == -1 ? expr_size (exp) : GEN_INT ((bitsize + BITS_PER_UNIT - 1) - / BITS_PER_UNIT), - BITS_PER_UNIT); + / BITS_PER_UNIT)); return target; } @@ -9172,7 +9149,7 @@ expand_expr_unaligned (exp, palign) /* Get a reference to just this component. */ op0 = adjust_address (op0, mode1, bitpos / BITS_PER_UNIT); - set_mem_alias_set (op0, get_alias_set (exp)); + set_mem_attributes (op0, exp, 0); /* Adjust the alignment in case the bit position is not a multiple of the alignment of the inner object. */ diff --git a/gcc/expr.h b/gcc/expr.h index fbf12a04b2e..015561159bb 100644 --- a/gcc/expr.h +++ b/gcc/expr.h @@ -410,7 +410,7 @@ extern rtx convert_modes PARAMS ((enum machine_mode, enum machine_mode, rtx, int)); /* Emit code to move a block Y to a block X. */ -extern rtx emit_block_move PARAMS ((rtx, rtx, rtx, unsigned int)); +extern rtx emit_block_move PARAMS ((rtx, rtx, rtx)); /* Copy all or part of a value X into registers starting at REGNO. The number of registers to be filled is NREGS. */ @@ -444,9 +444,8 @@ extern void use_regs PARAMS ((rtx *, int, int)); extern void use_group_regs PARAMS ((rtx *, rtx)); /* Write zeros through the storage of OBJECT. - If OBJECT has BLKmode, SIZE is its length in bytes and ALIGN is its - alignment. */ -extern rtx clear_storage PARAMS ((rtx, rtx, unsigned int)); + If OBJECT has BLKmode, SIZE is its length in bytes. */ +extern rtx clear_storage PARAMS ((rtx, rtx)); /* Return non-zero if it is desirable to store LEN bytes generated by CONSTFUN with several move instructions by store_by_pieces diff --git a/gcc/f/ChangeLog b/gcc/f/ChangeLog index 3754e628c45..b0fa255dc9c 100644 --- a/gcc/f/ChangeLog +++ b/gcc/f/ChangeLog @@ -1,3 +1,8 @@ +Tue Oct 23 14:01:27 2001 Richard Kenner + + * com.c (LANG_HOOKS_GET_ALIAS_SET): New macro. + (lang_get_alias_set): Delete. + 2001-10-23 Joseph S. Myers * g77.texi (Sending Patches): Remove. diff --git a/gcc/f/com.c b/gcc/f/com.c index 821a637fd5a..ccff61a9d68 100644 --- a/gcc/f/com.c +++ b/gcc/f/com.c @@ -14276,6 +14276,14 @@ static void ffe_init_options PARAMS ((void)); #undef LANG_HOOKS_DECODE_OPTION #define LANG_HOOKS_DECODE_OPTION ffe_decode_option +/* We do not wish to use alias-set based aliasing at all. Used in the + extreme (every object with its own set, with equivalences recorded) it + might be helpful, but there are problems when it comes to inlining. We + get on ok with flag_argument_noalias, and alias-set aliasing does + currently limit how stack slots can be reused, which is a lose. */ +#undef LANG_HOOKS_GET_ALIAS_SET +#define LANG_HOOKS_GET_ALIAS_SET hook_get_alias_set_0 + struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER; /* used by print-tree.c */ @@ -14303,21 +14311,6 @@ lang_identify () return "f77"; } -/* Return the typed-based alias set for T, which may be an expression - or a type. Return -1 if we don't do anything special. */ - -HOST_WIDE_INT -lang_get_alias_set (t) - tree t ATTRIBUTE_UNUSED; -{ - /* We do not wish to use alias-set based aliasing at all. Used in the - extreme (every object with its own set, with equivalences recorded) - it might be helpful, but there are problems when it comes to inlining. - We get on ok with flag_argument_noalias, and alias-set aliasing does - currently limit how stack slots can be reused, which is a lose. */ - return 0; -} - static void ffe_init_options () { diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c index da9c003682e..1cbd68892bd 100644 --- a/gcc/ifcvt.c +++ b/gcc/ifcvt.c @@ -1109,6 +1109,8 @@ noce_try_cmove_arith (if_info) MEM_SCALAR_P (tmp) = 1; if (MEM_ALIAS_SET (if_info->a) == MEM_ALIAS_SET (if_info->b)) set_mem_alias_set (tmp, MEM_ALIAS_SET (if_info->a)); + set_mem_align (tmp, + MIN (MEM_ALIGN (if_info->a), MEM_ALIGN (if_info->b))); noce_emit_move_insn (if_info->x, tmp); } diff --git a/gcc/integrate.c b/gcc/integrate.c index 874029fbb9c..05522671f46 100644 --- a/gcc/integrate.c +++ b/gcc/integrate.c @@ -2184,13 +2184,18 @@ copy_rtx_and_substitute (orig, map, for_lhs) #ifndef NO_FUNCTION_CSE if (! (optimize && ! flag_no_function_cse)) #endif - return - gen_rtx_CALL - (GET_MODE (orig), - gen_rtx_MEM (GET_MODE (XEXP (orig, 0)), - copy_rtx_and_substitute (XEXP (XEXP (orig, 0), 0), - map, 0)), - copy_rtx_and_substitute (XEXP (orig, 1), map, 0)); + { + rtx copy + = gen_rtx_MEM (GET_MODE (XEXP (orig, 0)), + copy_rtx_and_substitute (XEXP (XEXP (orig, 0), 0), + map, 0)); + + MEM_COPY_ATTRIBUTES (copy, orig); + + return + gen_rtx_CALL (GET_MODE (orig), copy, + copy_rtx_and_substitute (XEXP (orig, 1), map, 0)); + } break; #if 0 diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog index 5526e4e8ced..6ed62044613 100644 --- a/gcc/java/ChangeLog +++ b/gcc/java/ChangeLog @@ -1,3 +1,7 @@ +Tue Oct 23 14:02:17 2001 Richard Kenner + + * lang.c (lang_get_alias_set): Deleted. + 2001-10-21 Kaveh R. Ghazi * gjavah.c (jni_print_char): Fix thinko in last change. diff --git a/gcc/java/lang.c b/gcc/java/lang.c index 8187e672059..ff1fce58252 100644 --- a/gcc/java/lang.c +++ b/gcc/java/lang.c @@ -789,13 +789,3 @@ lang_print_xnode (file, node, indent) int indent __attribute ((__unused__)); { } - -/* Return the typed-based alias set for T, which may be an expression - or a type. Return -1 if we don't do anything special. */ - -HOST_WIDE_INT -lang_get_alias_set (t) - tree t ATTRIBUTE_UNUSED; -{ - return -1; -} diff --git a/gcc/langhooks.c b/gcc/langhooks.c index aa6422a325c..b912e711bfc 100644 --- a/gcc/langhooks.c +++ b/gcc/langhooks.c @@ -30,12 +30,24 @@ Boston, MA 02111-1307, USA. */ #include "langhooks.h" /* Do nothing; in many cases the default hook. */ + void lang_hook_default_do_nothing () { } +/* Provide a default routine for alias sets that always returns -1. This + is used by languages that don't need to do anything special. */ + +HOST_WIDE_INT +lang_hook_default_get_alias_set (t) + tree t ATTRIBUTE_UNUSED; +{ + return -1; +} + /* Do nothing; the default hook to decode an option. */ + int lang_hook_default_decode_option (argc, argv) int argc ATTRIBUTE_UNUSED; @@ -44,6 +56,16 @@ lang_hook_default_decode_option (argc, argv) return 0; } +/* Provide a hook routine for alias sets that always returns 0. This is + used by languages that haven't deal with alias sets yet. */ + +HOST_WIDE_INT +hook_get_alias_set_0 (t) + tree t ATTRIBUTE_UNUSED; +{ + return 0; +} + /* lang_hooks.tree_inlining.walk_subtrees is called by walk_tree() after handling common cases, but before walking code-specific sub-trees. If this hook is overridden for a language, it should diff --git a/gcc/langhooks.h b/gcc/langhooks.h index 0b4d72f6c46..69ff1d819bf 100644 --- a/gcc/langhooks.h +++ b/gcc/langhooks.h @@ -22,6 +22,10 @@ Boston, MA 02111-1307, USA. */ #ifndef GCC_LANG_HOOKS_H #define GCC_LANG_HOOKS_H +/* Provide a hook routine for alias sets that always returns 1. This is + used by languages that haven't deal with alias sets yet. */ +extern HOST_WIDE_INT hook_get_alias_set_0 PARAMS ((tree)); + /* Note to creators of new hooks: The macros in this file should NOT be surrounded by a @@ -33,30 +37,34 @@ Boston, MA 02111-1307, USA. */ extern void lang_hook_default_do_nothing PARAMS ((void)); extern int lang_hook_default_decode_option PARAMS ((int, char **)); +extern HOST_WIDE_INT lang_hook_default_get_alias_set PARAMS ((tree)); #define LANG_HOOKS_INIT lang_hook_default_do_nothing #define LANG_HOOKS_FINISH lang_hook_default_do_nothing #define LANG_HOOKS_INIT_OPTIONS lang_hook_default_do_nothing #define LANG_HOOKS_DECODE_OPTION lang_hook_default_decode_option #define LANG_HOOKS_POST_OPTIONS lang_hook_default_do_nothing +#define LANG_HOOKS_GET_ALIAS_SET lang_hook_default_get_alias_set #define LANG_HOOKS_HONOR_READONLY false /* Declarations of default tree inlining hooks. */ -tree tree_inlining_default_hook_walk_subtrees PARAMS ((tree*, int *, - walk_tree_fn, - void *, void *)); -int tree_inlining_default_hook_cannot_inline_tree_fn PARAMS ((tree*)); -int tree_inlining_default_hook_disregard_inline_limits PARAMS ((tree)); -tree tree_inlining_default_hook_add_pending_fn_decls PARAMS ((void*, tree)); -int tree_inlining_default_hook_tree_chain_matters_p PARAMS ((tree)); -int tree_inlining_default_hook_auto_var_in_fn_p PARAMS ((tree, tree)); +tree tree_inlining_default_hook_walk_subtrees PARAMS ((tree *, int *, + walk_tree_fn, + void *, + void *)); +int tree_inlining_default_hook_cannot_inline_tree_fn PARAMS ((tree *)); +int tree_inlining_default_hook_disregard_inline_limits PARAMS ((tree)); +tree tree_inlining_default_hook_add_pending_fn_decls PARAMS ((void *, + tree)); +int tree_inlining_default_hook_tree_chain_matters_p PARAMS ((tree)); +int tree_inlining_default_hook_auto_var_in_fn_p PARAMS ((tree, tree)); tree tree_inlining_default_hook_copy_res_decl_for_inlining PARAMS ((tree, tree, tree, void *, int *, void *)); -int tree_inlining_default_hook_anon_aggr_type_p PARAMS ((tree)); +int tree_inlining_default_hook_anon_aggr_type_p PARAMS ((tree)); /* Tree inlining hooks. */ #define LANG_HOOKS_TREE_INLINING_WALK_SUBTREES \ @@ -94,6 +102,7 @@ int tree_inlining_default_hook_anon_aggr_type_p PARAMS ((tree)); LANG_HOOKS_INIT_OPTIONS, \ LANG_HOOKS_DECODE_OPTION, \ LANG_HOOKS_POST_OPTIONS, \ + LANG_HOOKS_GET_ALIAS_SET, \ LANG_HOOKS_HONOR_READONLY, \ LANG_HOOKS_TREE_INLINING_INITIALIZER \ } diff --git a/gcc/reload1.c b/gcc/reload1.c index 0b53ac90501..1f98f7cdf1d 100644 --- a/gcc/reload1.c +++ b/gcc/reload1.c @@ -2025,10 +2025,11 @@ alter_reg (i, from_reg) below. */ adjust = GET_MODE_SIZE (mode) - total_size; if (adjust) - stack_slot = gen_rtx_MEM (mode_for_size (total_size + stack_slot + = adjust_address_nv (x, mode_for_size (total_size * BITS_PER_UNIT, MODE_INT, 1), - plus_constant (XEXP (x, 0), adjust)); + adjust); } spill_stack_slot[from_reg] = stack_slot; diff --git a/gcc/rtl.c b/gcc/rtl.c index 7a07b7279c0..deaf22c24cf 100644 --- a/gcc/rtl.c +++ b/gcc/rtl.c @@ -531,6 +531,7 @@ copy_most_rtx (orig, may_share) } /* Create a new copy of an rtx. Only copy just one level. */ + rtx shallow_copy_rtx (orig) rtx orig; @@ -551,6 +552,23 @@ shallow_copy_rtx (orig) return copy; } + +/* Return the alignment of MODE. This will be bounded by 1 and + BIGGEST_ALIGNMENT. */ + +unsigned int +get_mode_alignment (mode) + enum machine_mode mode; +{ + unsigned int alignment = GET_MODE_UNIT_SIZE (mode); + + /* Extract the LSB of the size. */ + alignment = alignment & -alignment; + alignment *= BITS_PER_UNIT; + + alignment = MIN (BIGGEST_ALIGNMENT, MAX (1, alignment)); + return alignment; +} /* This is 1 until after the rtl generation pass. */ int rtx_equal_function_value_matters; diff --git a/gcc/rtl.h b/gcc/rtl.h index 45b62ee3c39..d1071673e35 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -913,7 +913,11 @@ extern unsigned int subreg_regno PARAMS ((rtx)); #define MEM_SIZE(RTX) (MEM_ATTRS (RTX) == 0 ? 0 : MEM_ATTRS (RTX)->size) /* For a MEM rtx, the alignment in bits. */ -#define MEM_ALIGN(RTX) (MEM_ATTRS (RTX) == 0 ? 1 : MEM_ATTRS (RTX)->align) +#define MEM_ALIGN(RTX) \ +(MEM_ATTRS (RTX) != 0 ? MEM_ATTRS (RTX)->align \ + : GET_MODE (RTX) != BLKmode ? GET_MODE_ALIGNMENT (GET_MODE (RTX)) \ + : BITS_PER_UNIT) + /* Copy the attributes that apply to memory locations from RHS to LHS. */ #define MEM_COPY_ATTRIBUTES(LHS, RHS) \ diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c index 9de3233821a..c0837dafd5e 100644 --- a/gcc/stor-layout.c +++ b/gcc/stor-layout.c @@ -1860,23 +1860,6 @@ get_best_mode (bitsize, bitpos, align, largest_mode, volatilep) return mode; } -/* Return the alignment of MODE. This will be bounded by 1 and - BIGGEST_ALIGNMENT. */ - -unsigned int -get_mode_alignment (mode) - enum machine_mode mode; -{ - unsigned int alignment = GET_MODE_UNIT_SIZE (mode); - - /* Extract the LSB of the size. */ - alignment = alignment & -alignment; - alignment *= BITS_PER_UNIT; - - alignment = MIN (BIGGEST_ALIGNMENT, MAX (1, alignment)); - return alignment; -} - /* This function is run once to initialize stor-layout.c. */ void diff --git a/gcc/toplev.h b/gcc/toplev.h index 4203207f096..93b30f44578 100644 --- a/gcc/toplev.h +++ b/gcc/toplev.h @@ -31,7 +31,7 @@ struct rtx_def; #define skip_leading_substring(whole, part) \ (strncmp (whole, part, strlen (part)) ? NULL : whole + strlen (part)) -extern int toplev_main PARAMS ((int argc, char **argv)); +extern int toplev_main PARAMS ((int, char **)); extern int read_integral_parameter PARAMS ((const char *, const char *, const int)); extern int count_error PARAMS ((int)); @@ -127,7 +127,8 @@ struct lang_hooks_for_tree_inlining void *, void *)); int (*cannot_inline_tree_fn) PARAMS ((union tree_node **)); int (*disregard_inline_limits) PARAMS ((union tree_node *)); - union tree_node *(*add_pending_fn_decls) PARAMS ((void*, union tree_node *)); + union tree_node *(*add_pending_fn_decls) PARAMS ((void *, + union tree_node *)); int (*tree_chain_matters_p) PARAMS ((union tree_node *)); int (*auto_var_in_fn_p) PARAMS ((union tree_node *, union tree_node *)); union tree_node *(*copy_res_decl_for_inlining) PARAMS ((union tree_node *, @@ -164,6 +165,10 @@ struct lang_hooks /* Called when all command line options have been processed. */ void (*post_options) PARAMS ((void)); + /* Called to obtain the alias set to be used for an expression or type. + Returns -1 if the language does nothing special for it. */ + HOST_WIDE_INT (*get_alias_set) PARAMS ((tree)); + /* Nonzero if TYPE_READONLY and TREE_READONLY should always be honored. */ bool honor_readonly; diff --git a/gcc/tree.h b/gcc/tree.h index 5c35fd730c2..44c54974e22 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -2818,9 +2818,6 @@ extern int alias_sets_conflict_p PARAMS ((HOST_WIDE_INT, extern int readonly_fields_p PARAMS ((tree)); extern int objects_must_conflict_p PARAMS ((tree, tree)); -/* In c-common.c */ -extern HOST_WIDE_INT lang_get_alias_set PARAMS ((tree)); - /* Set the DECL_ASSEMBLER_NAME for a node. If it is the sort of thing that the assembler should talk about, set DECL_ASSEMBLER_NAME to an appropriate IDENTIFIER_NODE. Otherwise, set it to the -- 2.30.2