diff options
author | Richard Sandiford <richard@codesourcery.com> | 2006-02-18 22:06:53 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2006-02-18 22:06:53 +0000 |
commit | aacd3885eb07280eed4558f0dacad4d977052dc2 (patch) | |
tree | b8f39049c93e479153dfa0a8aa3f5539993a4a56 /gcc/expr.c | |
parent | dcf966bd82b34172175ca8ff4aa39f91729a9dbb (diff) | |
download | gcc-aacd3885eb07280eed4558f0dacad4d977052dc2.zip gcc-aacd3885eb07280eed4558f0dacad4d977052dc2.tar.gz gcc-aacd3885eb07280eed4558f0dacad4d977052dc2.tar.bz2 |
re PR target/9703 ([arm] Accessing data through constant pool more times could be solved in less instructions)
* cselib.c (cselib_init): Change RTX_SIZE to RTX_CODE_SIZE.
* emit-rtl.c (copy_rtx_if_shared_1): Use shallow_copy_rtx.
(copy_insn_1): Likewise. Don't copy each field individually.
Reindent.
* read-rtl.c (apply_macro_to_rtx): Use RTX_CODE_SIZE instead
of RTX_SIZE.
* reload1.c (eliminate_regs): Use shallow_copy_rtx.
* rtl.c (rtx_size): Rename variable to...
(rtx_code_size): ...this.
(rtx_size): New function.
(rtx_alloc_stat): Use RTX_CODE_SIZE instead of RTX_SIZE.
(copy_rtx): Use shallow_copy_rtx. Don't copy each field individually.
Reindent.
(shallow_copy_rtx_stat): Use rtx_size instead of RTX_SIZE.
* rtl.h (rtx_code_size): New variable.
(rtx_size): Change from a variable to a function.
(RTX_SIZE): Rename to...
(RTX_CODE_SIZE): ...this.
PR target/9703
PR tree-optimization/17106
* doc/tm.texi (TARGET_USE_BLOCKS_FOR_CONSTANT_P): Document.
(Anchored Addresses): New section.
* doc/invoke.texi (-fsection-anchors): Document.
* doc/rtl.texi (SYMBOL_REF_IN_BLOCK_P, SYMBOL_FLAG_IN_BLOCK): Likewise.
(SYMBOL_REF_ANCHOR_P, SYMBOL_FLAG_ANCHOR): Likewise.
(SYMBOL_REF_BLOCK, SYMBOL_REF_BLOCK_OFFSET): Likewise.
* hooks.c (hook_bool_mode_rtx_false): New function.
* hooks.h (hook_bool_mode_rtx_false): Declare.
* gengtype.c (create_optional_field): New function.
(adjust_field_rtx_def): Add the "block_sym" field for SYMBOL_REFs when
SYMBOL_REF_IN_BLOCK_P is true.
* target.h (output_anchor, use_blocks_for_constant_p): New hooks.
(min_anchor_offset, max_anchor_offset): Likewise.
(use_anchors_for_symbol_p): New hook.
* toplev.c (compile_file): Call output_object_blocks.
(target_supports_section_anchors_p): New function.
(process_options): Check that -fsection-anchors is only used on
targets that support it and when -funit-at-a-time is in effect.
* tree-ssa-loop-ivopts.c (prepare_decl_rtl): Only create DECL_RTL
if the decl doesn't have one.
* dwarf2out.c: Remove instantiations of VEC(rtx,gc).
* expr.c (emit_move_multi_word, emit_move_insn): Pass the result
of force_const_mem through use_anchored_address.
(expand_expr_constant): New function.
(expand_expr_addr_expr_1): Call it. Use the same modifier when
calling expand_expr for INDIRECT_REF.
(expand_expr_real_1): Pass DECL_RTL through use_anchored_address
for all modifiers except EXPAND_INITIALIZER. Use expand_expr_constant.
* expr.h (use_anchored_address): Declare.
* loop-unroll.c: Don't declare rtx vectors here.
* explow.c: Include output.h.
(validize_mem): Call use_anchored_address.
(use_anchored_address): New function.
* common.opt (-fsection-anchors): New switch.
* varasm.c (object_block_htab, anchor_labelno): New variables.
(hash_section, object_block_entry_eq, object_block_entry_hash)
(use_object_blocks_p, get_block_for_section, create_block_symbol)
(use_blocks_for_decl_p, change_symbol_section): New functions.
(get_variable_section): New function, split out from assemble_variable.
(make_decl_rtl): Create a block symbol if use_object_blocks_p and
use_blocks_for_decl_p say so. Use change_symbol_section if the
symbol has already been created.
(assemble_variable_contents): New function, split out from...
(assemble_variable): ...here. Don't output any code for
block symbols; just pass them to place_block_symbol.
Use get_variable_section and assemble_variable_contents.
(get_constant_alignment, get_constant_section, get_constant_size): New
functions, split from output_constant_def_contents.
(build_constant_desc): Create a block symbol if use_object_blocks_p
says so. Or into SYMBOL_REF_FLAGS.
(assemble_constant_contents): New function, split from...
(output_constant_def_contents): ...here. Don't output any code
for block symbols; just pass them to place_section_symbol.
Use get_constant_section and get_constant_alignment.
(force_const_mem): Create a block symbol if use_object_blocks_p and
use_blocks_for_constant_p say so. Or into SYMBOL_REF_FLAGS.
(output_constant_pool_1): Add an explicit alignment argument.
Don't switch sections here.
(output_constant_pool): Adjust call to output_constant_pool_1.
Switch sections here instead. Don't output anything for block symbols;
just pass them to place_block_symbol.
(init_varasm_once): Initialize object_block_htab.
(default_encode_section_info): Keep the old SYMBOL_FLAG_IN_BLOCK.
(default_asm_output_anchor, default_use_aenchors_for_symbol_p)
(place_block_symbol, get_section_anchor, output_object_block)
(output_object_block_htab, output_object_blocks): New functions.
* target-def.h (TARGET_ASM_OUTPUT_ANCHOR): New macro.
(TARGET_ASM_OUT): Include it.
(TARGET_USE_BLOCKS_FOR_CONSTANT_P): New macro.
(TARGET_MIN_ANCHOR_OFFSET, TARGET_MAX_ANCHOR_OFFSET): New macros.
(TARGET_USE_ANCHORS_FOR_SYMBOL_P): New macro.
(TARGET_INITIALIZER): Include them.
* rtl.c (rtl_check_failed_block_symbol): New function.
* rtl.h: Include vec.h. Declare heap and gc rtx vectors.
(block_symbol, object_block): New structures.
(rtx_def): Add a block_symbol field to the union.
(BLOCK_SYMBOL_CHECK): New macro.
(rtl_check_failed_block_symbol): Declare.
(SYMBOL_FLAG_IN_BLOCK, SYMBOL_FLAG_ANCHOR): New SYMBOL_REF flags.
(SYMBOL_REF_IN_BLOCK_P, SYMBOL_REF_ANCHOR_P): New predicates.
(SYMBOL_FLAG_MACH_DEP_SHIFT): Bump by 2.
(SYMBOL_REF_BLOCK, SYMBOL_REF_BLOCK_OFFSET): New accessors.
* output.h (output_section_symbols): Declare.
(object_block): Name structure.
(place_section_symbol, get_section_anchor, default_asm_output_anchor)
(default_use_anchors_for_symbol_p): Declare.
* Makefile.in (RTL_BASE_H): Add vec.h.
(explow.o): Depend on output.h.
* config/rs6000/rs6000.c (TARGET_MIN_ANCHOR_OFFSET): Override default.
(TARGET_MAX_ANCHOR_OFFSET): Likewise.
(TARGET_USE_BLOCKS_FOR_CONSTANT_P): Likewise.
(rs6000_use_blocks_for_constant_p): New function.
From-SVN: r111254
Diffstat (limited to 'gcc/expr.c')
-rw-r--r-- | gcc/expr.c | 66 |
1 files changed, 40 insertions, 26 deletions
@@ -3081,7 +3081,7 @@ emit_move_multi_word (enum machine_mode mode, rtx x, rtx y) be able to get a part of Y. */ if (ypart == 0 && CONSTANT_P (y)) { - y = force_const_mem (mode, y); + y = use_anchored_address (force_const_mem (mode, y)); ypart = operand_subword (y, i, 1, mode); } else if (ypart == 0) @@ -3194,6 +3194,8 @@ emit_move_insn (rtx x, rtx y) of the non-legitimate constant. */ if (!y) y = y_cst; + else + y = use_anchored_address (y); } } @@ -6280,6 +6282,20 @@ expand_operands (tree exp0, tree exp1, rtx target, rtx *op0, rtx *op1, } +/* Return a MEM that constains constant EXP. DEFER is as for + output_constant_def and MODIFIER is as for expand_expr. */ + +static rtx +expand_expr_constant (tree exp, int defer, enum expand_modifier modifier) +{ + rtx mem; + + mem = output_constant_def (exp, defer); + if (modifier != EXPAND_INITIALIZER) + mem = use_anchored_address (mem); + return mem; +} + /* A subroutine of expand_expr_addr_expr. Evaluate the address of EXP. The TARGET, TMODE and MODIFIER arguments are as for expand_expr. */ @@ -6301,14 +6317,14 @@ expand_expr_addr_expr_1 (tree exp, rtx target, enum machine_mode tmode, exception here is STRING_CST. */ if (TREE_CODE (exp) == CONSTRUCTOR || CONSTANT_CLASS_P (exp)) - return XEXP (output_constant_def (exp, 0), 0); + return XEXP (expand_expr_constant (exp, 0, modifier), 0); /* Everything must be something allowed by is_gimple_addressable. */ switch (TREE_CODE (exp)) { case INDIRECT_REF: /* This case will happen via recursion for &a->b. */ - return expand_expr (TREE_OPERAND (exp, 0), target, tmode, EXPAND_NORMAL); + return expand_expr (TREE_OPERAND (exp, 0), target, tmode, modifier); case CONST_DECL: /* Recurse and make the output_constant_def clause above handle this. */ @@ -6579,7 +6595,7 @@ static rtx expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, enum expand_modifier modifier, rtx *alt_rtl) { - rtx op0, op1, temp; + rtx op0, op1, temp, decl_rtl; tree type = TREE_TYPE (exp); int unsignedp; enum machine_mode mode; @@ -6701,7 +6717,8 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, case FUNCTION_DECL: case RESULT_DECL: - gcc_assert (DECL_RTL (exp)); + decl_rtl = DECL_RTL (exp); + gcc_assert (decl_rtl); /* Ensure variable marked as used even if it doesn't go through a parser. If it hasn't be used yet, write out an external @@ -6728,27 +6745,24 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, from its initializer, while the initializer is still being parsed. See expand_decl. */ - if (MEM_P (DECL_RTL (exp)) - && REG_P (XEXP (DECL_RTL (exp), 0))) - temp = validize_mem (DECL_RTL (exp)); + if (MEM_P (decl_rtl) && REG_P (XEXP (decl_rtl, 0))) + temp = validize_mem (decl_rtl); /* If DECL_RTL is memory, we are in the normal case and either the address is not valid or it is not a register and -fforce-addr is specified, get the address into a register. */ - else if (MEM_P (DECL_RTL (exp)) - && modifier != EXPAND_CONST_ADDRESS - && modifier != EXPAND_SUM - && modifier != EXPAND_INITIALIZER - && (! memory_address_p (DECL_MODE (exp), - XEXP (DECL_RTL (exp), 0)) - || (flag_force_addr - && !REG_P (XEXP (DECL_RTL (exp), 0))))) + else if (MEM_P (decl_rtl) && modifier != EXPAND_INITIALIZER) { if (alt_rtl) - *alt_rtl = DECL_RTL (exp); - temp = replace_equiv_address (DECL_RTL (exp), - copy_rtx (XEXP (DECL_RTL (exp), 0))); + *alt_rtl = decl_rtl; + decl_rtl = use_anchored_address (decl_rtl); + if (modifier != EXPAND_CONST_ADDRESS + && modifier != EXPAND_SUM + && (!memory_address_p (DECL_MODE (exp), XEXP (decl_rtl, 0)) + || (flag_force_addr && !REG_P (XEXP (decl_rtl, 0))))) + temp = replace_equiv_address (decl_rtl, + copy_rtx (XEXP (decl_rtl, 0))); } /* If we got something, return it. But first, set the alignment @@ -6765,8 +6779,8 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, must be a promoted value. We return a SUBREG of the wanted mode, but mark it so that we know that it was already extended. */ - if (REG_P (DECL_RTL (exp)) - && GET_MODE (DECL_RTL (exp)) != DECL_MODE (exp)) + if (REG_P (decl_rtl) + && GET_MODE (decl_rtl) != DECL_MODE (exp)) { enum machine_mode pmode; @@ -6775,15 +6789,15 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, pmode = promote_mode (type, DECL_MODE (exp), &unsignedp, (TREE_CODE (exp) == RESULT_DECL || TREE_CODE (exp) == PARM_DECL) ? 1 : 0); - gcc_assert (GET_MODE (DECL_RTL (exp)) == pmode); + gcc_assert (GET_MODE (decl_rtl) == pmode); - temp = gen_lowpart_SUBREG (mode, DECL_RTL (exp)); + temp = gen_lowpart_SUBREG (mode, decl_rtl); SUBREG_PROMOTED_VAR_P (temp) = 1; SUBREG_PROMOTED_UNSIGNED_SET (temp, unsignedp); return temp; } - return DECL_RTL (exp); + return decl_rtl; case INTEGER_CST: temp = immed_double_const (TREE_INT_CST_LOW (exp), @@ -6852,7 +6866,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, /* ... fall through ... */ case STRING_CST: - temp = output_constant_def (exp, 1); + temp = expand_expr_constant (exp, 1, modifier); /* temp contains a constant address. On RISC machines where a constant address isn't valid, @@ -6953,7 +6967,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, || modifier == EXPAND_CONST_ADDRESS) && TREE_CONSTANT (exp))) { - rtx constructor = output_constant_def (exp, 1); + rtx constructor = expand_expr_constant (exp, 1, modifier); if (modifier != EXPAND_CONST_ADDRESS && modifier != EXPAND_INITIALIZER |