diff options
author | law <law@138bc75d-0d04-0410-961f-82ee72b054a4> | 1997-12-07 00:31:01 +0000 |
---|---|---|
committer | law <law@138bc75d-0d04-0410-961f-82ee72b054a4> | 1997-12-07 00:31:01 +0000 |
commit | ad87de1ece2f52d260b582709751ab9f315ab349 (patch) | |
tree | ec80f8d1e46852ac1ba45aecdcda7201c302ac6f /gcc/expr.c | |
parent | 8098b1a5d828997acb2555106b3edccc0b43b661 (diff) | |
download | gcc-ad87de1ece2f52d260b582709751ab9f315ab349.tar.gz |
Merge from gcc-2.8
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@16987 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/expr.c')
-rw-r--r-- | gcc/expr.c | 123 |
1 files changed, 85 insertions, 38 deletions
diff --git a/gcc/expr.c b/gcc/expr.c index f07b3f67477..a84beb583f5 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -110,9 +110,13 @@ static rtx saveregs_value; /* Similarly for __builtin_apply_args. */ static rtx apply_args_value; +/* Don't check memory usage, since code is being emitted to check a memory + usage. Used when flag_check_memory_usage is true, to avoid infinite + recursion. */ +static int in_check_memory_usage; + /* This structure is used by move_by_pieces to describe the move to be performed. */ - struct move_by_pieces { rtx to; @@ -2551,10 +2555,11 @@ emit_push_insn (x, mode, type, size, align, partial, reg, extra, move_by_pieces (gen_rtx (MEM, BLKmode, gen_push_operand ()), xinner, INTVAL (size) - used, align); - if (flag_check_memory_usage) + if (flag_check_memory_usage && ! in_check_memory_usage) { rtx temp; + in_check_memory_usage = 1; temp = get_push_address (INTVAL(size) - used); if (GET_CODE (x) == MEM && AGGREGATE_TYPE_P (type)) emit_library_call (chkr_copy_bitmap_libfunc, 1, VOIDmode, 3, @@ -2567,7 +2572,9 @@ emit_push_insn (x, mode, type, size, align, partial, reg, extra, temp, ptr_mode, GEN_INT (INTVAL(size) - used), TYPE_MODE (sizetype), - GEN_INT (MEMORY_USE_RW), QImode); + GEN_INT (MEMORY_USE_RW), + TYPE_MODE (integer_type_node)); + in_check_memory_usage = 0; } } else @@ -2604,10 +2611,11 @@ emit_push_insn (x, mode, type, size, align, partial, reg, extra, plus_constant (gen_rtx (PLUS, Pmode, args_addr, args_so_far), skip)); - if (flag_check_memory_usage) + if (flag_check_memory_usage && ! in_check_memory_usage) { rtx target; + in_check_memory_usage = 1; target = copy_to_reg (temp); if (GET_CODE (x) == MEM && AGGREGATE_TYPE_P (type)) emit_library_call (chkr_copy_bitmap_libfunc, 1, VOIDmode, 3, @@ -2618,7 +2626,9 @@ emit_push_insn (x, mode, type, size, align, partial, reg, extra, emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3, target, ptr_mode, size, TYPE_MODE (sizetype), - GEN_INT (MEMORY_USE_RW), QImode); + GEN_INT (MEMORY_USE_RW), + TYPE_MODE (integer_type_node)); + in_check_memory_usage = 0; } /* TEMP is the address of the block. Copy the data there. */ @@ -2813,8 +2823,9 @@ emit_push_insn (x, mode, type, size, align, partial, reg, extra, emit_move_insn (gen_rtx (MEM, mode, addr), x); - if (flag_check_memory_usage) + if (flag_check_memory_usage && ! in_check_memory_usage) { + in_check_memory_usage = 1; if (target == 0) target = get_push_address (GET_MODE_SIZE (mode)); @@ -2829,7 +2840,9 @@ emit_push_insn (x, mode, type, size, align, partial, reg, extra, target, ptr_mode, GEN_INT (GET_MODE_SIZE (mode)), TYPE_MODE (sizetype), - GEN_INT (MEMORY_USE_RW), QImode); + GEN_INT (MEMORY_USE_RW), + TYPE_MODE (integer_type_node)); + in_check_memory_usage = 0; } } @@ -2954,6 +2967,15 @@ expand_assignment (to, from, want_value, suggest_reg) #endif } + if (TREE_CODE (to) == COMPONENT_REF + && TREE_READONLY (TREE_OPERAND (to, 1))) + { + if (offset = 0) + to_rtx = copy_rtx (to_rtx); + + RTX_UNCHANGING_P (to_rtx) = 1; + } + /* Check the access. */ if (flag_check_memory_usage && GET_CODE (to_rtx) == MEM) { @@ -2978,7 +3000,8 @@ expand_assignment (to, from, want_value, suggest_reg) emit_library_call (chkr_check_addr_libfunc, 1, VOIDmode, 3, to_addr, ptr_mode, GEN_INT (size), TYPE_MODE (sizetype), - GEN_INT (MEMORY_USE_WO), QImode); + GEN_INT (MEMORY_USE_WO), + TYPE_MODE (integer_type_node)); } result = store_field (to_rtx, bitsize, bitpos, mode1, from, @@ -3169,16 +3192,16 @@ store_expr (exp, target, want_value) do_pending_stack_adjust (); NO_DEFER_POP; jumpifnot (TREE_OPERAND (exp, 0), lab1); - start_cleanup_deferal (); + start_cleanup_deferral (); store_expr (TREE_OPERAND (exp, 1), target, 0); - end_cleanup_deferal (); + end_cleanup_deferral (); emit_queue (); emit_jump_insn (gen_jump (lab2)); emit_barrier (); emit_label (lab1); - start_cleanup_deferal (); + start_cleanup_deferral (); store_expr (TREE_OPERAND (exp, 2), target, 0); - end_cleanup_deferal (); + end_cleanup_deferral (); emit_queue (); emit_label (lab2); OK_DEFER_POP; @@ -3309,7 +3332,8 @@ store_expr (exp, target, want_value) emit_library_call (chkr_check_addr_libfunc, 1, VOIDmode, 3, XEXP (target, 0), ptr_mode, expr_size (exp), TYPE_MODE (sizetype), - GEN_INT (MEMORY_USE_WO), QImode); + GEN_INT (MEMORY_USE_WO), + TYPE_MODE (integer_type_node)); } /* If value was not generated in the target, store it there. @@ -3400,7 +3424,8 @@ store_expr (exp, target, want_value) emit_library_call (chkr_check_addr_libfunc, 1, VOIDmode, 3, addr, ptr_mode, size, TYPE_MODE (sizetype), - GEN_INT (MEMORY_USE_WO), QImode); + GEN_INT (MEMORY_USE_WO), + TYPE_MODE (integer_type_node)); #ifdef TARGET_MEM_FUNCTIONS emit_library_call (memset_libfunc, 0, VOIDmode, 3, addr, ptr_mode, @@ -3675,7 +3700,7 @@ store_constructor (exp, target, cleared) if (contains_placeholder_p (offset)) offset = build (WITH_RECORD_EXPR, sizetype, - offset, exp); + offset, make_tree (TREE_TYPE (exp), target)); offset = size_binop (FLOOR_DIV_EXPR, offset, size_int (BITS_PER_UNIT)); @@ -4403,9 +4428,14 @@ get_inner_reference (exp, pbitsize, pbitpos, poffset, pmode, && TREE_INT_CST_HIGH (index) == 0) *pbitpos += TREE_INT_CST_LOW (index); else - offset = size_binop (PLUS_EXPR, offset, - size_binop (FLOOR_DIV_EXPR, index, - size_int (BITS_PER_UNIT))); + { + offset = size_binop (PLUS_EXPR, offset, + size_binop (FLOOR_DIV_EXPR, index, + size_int (BITS_PER_UNIT))); + + if (contains_placeholder_p (offset)) + offset = build (WITH_RECORD_EXPR, sizetype, offset, exp); + } } else if (TREE_CODE (exp) != NON_LVALUE_EXPR && ! ((TREE_CODE (exp) == NOP_EXPR @@ -5016,7 +5046,8 @@ expand_expr (exp, target, tmode, modifier) XEXP (DECL_RTL (exp), 0), ptr_mode, GEN_INT (int_size_in_bytes (type)), TYPE_MODE (sizetype), - GEN_INT (memory_usage), QImode); + GEN_INT (memory_usage), + TYPE_MODE (integer_type_node)); } /* ... fall through ... */ @@ -5483,7 +5514,8 @@ expand_expr (exp, target, tmode, modifier) op0, ptr_mode, GEN_INT (int_size_in_bytes (type)), TYPE_MODE (sizetype), - GEN_INT (memory_usage), QImode); + GEN_INT (memory_usage), + TYPE_MODE (integer_type_node)); } temp = gen_rtx (MEM, mode, op0); @@ -5737,7 +5769,8 @@ expand_expr (exp, target, tmode, modifier) to, ptr_mode, GEN_INT (size / BITS_PER_UNIT), TYPE_MODE (sizetype), - GEN_INT (memory_usage), QImode); + GEN_INT (memory_usage), + TYPE_MODE (integer_type_node)); } } @@ -6859,7 +6892,7 @@ expand_expr (exp, target, tmode, modifier) else jumpifnot (TREE_OPERAND (exp, 0), op0); - start_cleanup_deferal (); + start_cleanup_deferral (); if (binary_op && temp == 0) /* Just touch the other operand. */ expand_expr (TREE_OPERAND (binary_op, 1), @@ -6893,7 +6926,7 @@ expand_expr (exp, target, tmode, modifier) store_expr (TREE_OPERAND (exp, 1), temp, 0); jumpif (TREE_OPERAND (exp, 0), op0); - start_cleanup_deferal (); + start_cleanup_deferral (); store_expr (TREE_OPERAND (exp, 2), temp, 0); op1 = op0; } @@ -6911,7 +6944,7 @@ expand_expr (exp, target, tmode, modifier) store_expr (TREE_OPERAND (exp, 2), temp, 0); jumpifnot (TREE_OPERAND (exp, 0), op0); - start_cleanup_deferal (); + start_cleanup_deferral (); store_expr (TREE_OPERAND (exp, 1), temp, 0); op1 = op0; } @@ -6920,18 +6953,18 @@ expand_expr (exp, target, tmode, modifier) op1 = gen_label_rtx (); jumpifnot (TREE_OPERAND (exp, 0), op0); - start_cleanup_deferal (); + start_cleanup_deferral (); if (temp != 0) store_expr (TREE_OPERAND (exp, 1), temp, 0); else expand_expr (TREE_OPERAND (exp, 1), ignore ? const0_rtx : NULL_RTX, VOIDmode, 0); - end_cleanup_deferal (); + end_cleanup_deferral (); emit_queue (); emit_jump_insn (gen_jump (op1)); emit_barrier (); emit_label (op0); - start_cleanup_deferal (); + start_cleanup_deferral (); if (temp != 0) store_expr (TREE_OPERAND (exp, 2), temp, 0); else @@ -6939,7 +6972,7 @@ expand_expr (exp, target, tmode, modifier) ignore ? const0_rtx : NULL_RTX, VOIDmode, 0); } - end_cleanup_deferal (); + end_cleanup_deferral (); emit_queue (); emit_label (op1); @@ -8855,7 +8888,8 @@ expand_builtin (exp, target, subtarget, mode, ignore) if (flag_check_memory_usage) emit_library_call (chkr_check_str_libfunc, 1, VOIDmode, 2, src_rtx, ptr_mode, - GEN_INT (MEMORY_USE_RO), QImode); + GEN_INT (MEMORY_USE_RO), + TYPE_MODE (integer_type_node)); char_rtx = const0_rtx; char_mode = insn_operand_mode[(int)icode][2]; @@ -9024,7 +9058,8 @@ expand_builtin (exp, target, subtarget, mode, ignore) emit_library_call (chkr_check_addr_libfunc, 1, VOIDmode, 3, dest_rtx, ptr_mode, len_rtx, TYPE_MODE (sizetype), - GEN_INT (MEMORY_USE_WO), QImode); + GEN_INT (MEMORY_USE_WO), + TYPE_MODE (integer_type_node)); /* There could be a void* cast on top of the object. */ @@ -9598,7 +9633,14 @@ expand_builtin_apply (function, arguments, argsize) /* Push a new argument block and copy the arguments. */ do_pending_stack_adjust (); - emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX); + + /* Save the stack with nonlocal if available */ +#ifdef HAVE_save_stack_nonlocal + if (HAVE_save_stack_nonlocal) + emit_stack_save (SAVE_NONLOCAL, &old_stack_level, NULL_RTX); + else +#endif + emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX); /* Push a block of memory onto the stack to store the memory arguments. Save the address in a register, and copy the memory arguments. ??? I @@ -9724,7 +9766,12 @@ expand_builtin_apply (function, arguments, argsize) CALL_INSN_FUNCTION_USAGE (call_insn) = call_fusage; /* Restore the stack. */ - emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX); +#ifdef HAVE_save_stack_nonlocal + if (HAVE_save_stack_nonlocal) + emit_stack_restore (SAVE_NONLOCAL, old_stack_level, NULL_RTX); + else +#endif + emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX); /* Return the address of the result block. */ return copy_addr_to_reg (XEXP (result, 0)); @@ -10249,18 +10296,18 @@ do_jump (exp, if_false_label, if_true_label) if (if_false_label == 0) if_false_label = drop_through_label = gen_label_rtx (); do_jump (TREE_OPERAND (exp, 0), if_false_label, NULL_RTX); - start_cleanup_deferal (); + start_cleanup_deferral (); do_jump (TREE_OPERAND (exp, 1), if_false_label, if_true_label); - end_cleanup_deferal (); + end_cleanup_deferral (); break; case TRUTH_ORIF_EXPR: if (if_true_label == 0) if_true_label = drop_through_label = gen_label_rtx (); do_jump (TREE_OPERAND (exp, 0), NULL_RTX, if_true_label); - start_cleanup_deferal (); + start_cleanup_deferral (); do_jump (TREE_OPERAND (exp, 1), if_false_label, if_true_label); - end_cleanup_deferal (); + end_cleanup_deferral (); break; case COMPOUND_EXPR: @@ -10321,7 +10368,7 @@ do_jump (exp, if_false_label, if_true_label) do_jump (TREE_OPERAND (exp, 0), label1, NULL_RTX); - start_cleanup_deferal (); + start_cleanup_deferral (); /* Now the THEN-expression. */ do_jump (TREE_OPERAND (exp, 1), if_false_label ? if_false_label : drop_through_label, @@ -10334,7 +10381,7 @@ do_jump (exp, if_false_label, if_true_label) do_jump (TREE_OPERAND (exp, 2), if_false_label ? if_false_label : drop_through_label, if_true_label ? if_true_label : drop_through_label); - end_cleanup_deferal (); + end_cleanup_deferral (); } break; |