From: Jan Hubicka Date: Thu, 3 Oct 2002 19:40:46 +0000 (+0200) Subject: toplev.c (rest_of_compilation): Dump loops before clobbering the structure. X-Git-Tag: releases/gcc-3.2.1~214 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0f500bdc5c171b183b325f2c8ead0c701c02dda0;p=thirdparty%2Fgcc.git toplev.c (rest_of_compilation): Dump loops before clobbering the structure. * toplev.c (rest_of_compilation): Dump loops before clobbering the structure. * expr.c (force_operand): Use expand_simple_* to handle more cases. * i386.c (q_regs_operand): Use ANY_QI_REG_P. * i386.c (override_options): Fix stack alignment. (classify_argument): Handle variable sized types. (ix86_expand_int_movcc): Avoid RTL sharing problem. * i386.md (prefetch_sse_rex, prefetch_3dnow_rex): New. (prefetch): Properly handle 64bit case. * i386.c (classify_argument): Properly compute word size of the analyzed object. * jump.c (reg_or_subregno): New function. * rtl.h (reg_or_subregno): Declare * unroll.c (find_splittable_givs): Handle subregs. Richard Sandiford : * expr.c (force_operand): Fix reversed move. Andreas Jaeger : * config/i386/linux64.h (STARTFILE_PREFIX_SPEC): New. Janis Johnson : * loop.c (emit_prefetch_instructions): Several small fixes. From-SVN: r57784 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5c40db13a931..12b99719565c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,38 @@ +Thu Oct 3 21:35:36 CEST 2002 Jan Hubicka + + * toplev.c (rest_of_compilation): Dump loops before clobbering + the structure. + + * expr.c (force_operand): Use expand_simple_* to handle more + cases. + + * i386.c (q_regs_operand): Use ANY_QI_REG_P. + + * i386.c (override_options): Fix stack alignment. + (classify_argument): Handle variable sized types. + (ix86_expand_int_movcc): Avoid RTL sharing problem. + + * i386.md (prefetch_sse_rex, prefetch_3dnow_rex): New. + (prefetch): Properly handle 64bit case. + + * i386.c (classify_argument): Properly compute word size of the analyzed object. + + * jump.c (reg_or_subregno): New function. + * rtl.h (reg_or_subregno): Declare + * unroll.c (find_splittable_givs): Handle subregs. + + Richard Sandiford : + + * expr.c (force_operand): Fix reversed move. + + Andreas Jaeger : + + * config/i386/linux64.h (STARTFILE_PREFIX_SPEC): New. + + Janis Johnson : + + * loop.c (emit_prefetch_instructions): Several small fixes. + Thu Sep 5 00:34:33 2002 J"orn Rennecke * loop.c (scan_loop): Don't mark separate insns out of a libcall diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index f07ebad251f4..ff9903c33fcb 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -1649,7 +1649,11 @@ classify_argument (mode, type, classes, bit_offset) { int bytes = (mode == BLKmode) ? int_size_in_bytes (type) : (int) GET_MODE_SIZE (mode); - int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD; + int words = (bytes + (bit_offset % 64) / 8 + UNITS_PER_WORD - 1) / UNITS_PER_WORD; + + /* Variable sized structures are always passed on the stack. */ + if (mode == BLKmode && type && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST) + return 0; if (type && AGGREGATE_TYPE_P (type)) { @@ -3206,7 +3210,7 @@ q_regs_operand (op, mode) return 0; if (GET_CODE (op) == SUBREG) op = SUBREG_REG (op); - return QI_REG_P (op); + return ANY_QI_REG_P (op); } /* Return true if op is a NON_Q_REGS class register. */ @@ -6123,7 +6127,10 @@ print_operand_address (file, addr) int scale; if (! ix86_decompose_address (addr, &parts)) - abort (); + { + output_operand_lossage ("Wrong address expression or operand constraint"); + return; + } base = parts.base; index = parts.index; @@ -8237,7 +8244,7 @@ ix86_expand_int_movcc (operands) clob = gen_rtx_CLOBBER (VOIDmode, clob); tmp = gen_rtx_SET (VOIDmode, out, tmp); - tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob)); + tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, copy_rtx (tmp), clob)); emit_insn (tmp); } else diff --git a/gcc/config/i386/linux64.h b/gcc/config/i386/linux64.h index 61584315d43d..7ffbd0d07ea5 100644 --- a/gcc/config/i386/linux64.h +++ b/gcc/config/i386/linux64.h @@ -48,6 +48,12 @@ Boston, MA 02111-1307, USA. */ %{!m32:%{!dynamic-linker:-dynamic-linker /lib64/ld-linux-x86-64.so.2}}} \ %{static:-static}}" + +#define STARTFILE_PREFIX_SPEC "\ + %{m32: /usr/local/lib/ /lib/ /usr/lib/} \ + %{!m32: /usr/local/lib64/ /lib64/ /usr/lib64/}" + + #undef STARTFILE_SPEC #define STARTFILE_SPEC \ "%{m32:%{!shared: \ diff --git a/gcc/expr.c b/gcc/expr.c index 2a5c6f9b890b..a7d78a121a6e 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -5434,16 +5434,13 @@ rtx force_operand (value, target) rtx value, target; { - optab binoptab = 0; - /* Use a temporary to force order of execution of calls to - `force_operand'. */ - rtx tmp; - rtx op2; + rtx op1, op2; /* Use subtarget as the target for operand 0 of a binary operation. */ rtx subtarget = get_subtarget (target); + enum rtx_code code = GET_CODE (value); /* Check for a PIC address load. */ - if ((GET_CODE (value) == PLUS || GET_CODE (value) == MINUS) + if ((code == PLUS || code == MINUS) && XEXP (value, 0) == pic_offset_table_rtx && (GET_CODE (XEXP (value, 1)) == SYMBOL_REF || GET_CODE (XEXP (value, 1)) == LABEL_REF @@ -5455,60 +5452,88 @@ force_operand (value, target) return subtarget; } - if (GET_CODE (value) == PLUS) - binoptab = add_optab; - else if (GET_CODE (value) == MINUS) - binoptab = sub_optab; - else if (GET_CODE (value) == MULT) + if (code == ZERO_EXTEND || code == SIGN_EXTEND) { - op2 = XEXP (value, 1); - if (!CONSTANT_P (op2) - && !(GET_CODE (op2) == REG && op2 != subtarget)) - subtarget = 0; - tmp = force_operand (XEXP (value, 0), subtarget); - return expand_mult (GET_MODE (value), tmp, - force_operand (op2, NULL_RTX), - target, 1); + if (!target) + target = gen_reg_rtx (GET_MODE (value)); + convert_move (target, force_operand (XEXP (value, 0), NULL), + code == ZERO_EXTEND); + return target; } - if (binoptab) + if (GET_RTX_CLASS (code) == '2' || GET_RTX_CLASS (code) == 'c') { op2 = XEXP (value, 1); - if (!CONSTANT_P (op2) - && !(GET_CODE (op2) == REG && op2 != subtarget)) + if (!CONSTANT_P (op2) && !(GET_CODE (op2) == REG && op2 != subtarget)) subtarget = 0; - if (binoptab == sub_optab && GET_CODE (op2) == CONST_INT) + if (code == MINUS && GET_CODE (op2) == CONST_INT) { - binoptab = add_optab; + code = PLUS; op2 = negate_rtx (GET_MODE (value), op2); } /* Check for an addition with OP2 a constant integer and our first - operand a PLUS of a virtual register and something else. In that - case, we want to emit the sum of the virtual register and the - constant first and then add the other value. This allows virtual - register instantiation to simply modify the constant rather than - creating another one around this addition. */ - if (binoptab == add_optab && GET_CODE (op2) == CONST_INT + operand a PLUS of a virtual register and something else. In that + case, we want to emit the sum of the virtual register and the + constant first and then add the other value. This allows virtual + register instantiation to simply modify the constant rather than + creating another one around this addition. */ + if (code == PLUS && GET_CODE (op2) == CONST_INT && GET_CODE (XEXP (value, 0)) == PLUS && GET_CODE (XEXP (XEXP (value, 0), 0)) == REG && REGNO (XEXP (XEXP (value, 0), 0)) >= FIRST_VIRTUAL_REGISTER && REGNO (XEXP (XEXP (value, 0), 0)) <= LAST_VIRTUAL_REGISTER) { - rtx temp = expand_binop (GET_MODE (value), binoptab, - XEXP (XEXP (value, 0), 0), op2, - subtarget, 0, OPTAB_LIB_WIDEN); - return expand_binop (GET_MODE (value), binoptab, temp, - force_operand (XEXP (XEXP (value, 0), 1), 0), - target, 0, OPTAB_LIB_WIDEN); + rtx temp = expand_simple_binop (GET_MODE (value), code, + XEXP (XEXP (value, 0), 0), op2, + subtarget, 0, OPTAB_LIB_WIDEN); + return expand_simple_binop (GET_MODE (value), code, temp, + force_operand (XEXP (XEXP (value, + 0), 1), 0), + target, 0, OPTAB_LIB_WIDEN); + } + + op1 = force_operand (XEXP (value, 0), subtarget); + op2 = force_operand (op2, NULL_RTX); + switch (code) + { + case MULT: + return expand_mult (GET_MODE (value), op1, op2, target, 1); + case DIV: + if (!INTEGRAL_MODE_P (GET_MODE (value))) + return expand_simple_binop (GET_MODE (value), code, op1, op2, + target, 1, OPTAB_LIB_WIDEN); + else + return expand_divmod (0, + FLOAT_MODE_P (GET_MODE (value)) + ? RDIV_EXPR : TRUNC_DIV_EXPR, + GET_MODE (value), op1, op2, target, 0); + break; + case MOD: + return expand_divmod (1, TRUNC_MOD_EXPR, GET_MODE (value), op1, op2, + target, 0); + break; + case UDIV: + return expand_divmod (0, TRUNC_DIV_EXPR, GET_MODE (value), op1, op2, + target, 1); + break; + case UMOD: + return expand_divmod (1, TRUNC_MOD_EXPR, GET_MODE (value), op1, op2, + target, 1); + break; + case ASHIFTRT: + return expand_simple_binop (GET_MODE (value), code, op1, op2, + target, 0, OPTAB_LIB_WIDEN); + break; + default: + return expand_simple_binop (GET_MODE (value), code, op1, op2, + target, 1, OPTAB_LIB_WIDEN); } - - tmp = force_operand (XEXP (value, 0), subtarget); - return expand_binop (GET_MODE (value), binoptab, tmp, - force_operand (op2, NULL_RTX), - target, 0, OPTAB_LIB_WIDEN); - /* We give UNSIGNEDP = 0 to expand_binop - because the only operations we are expanding here are signed ones. */ + } + if (GET_RTX_CLASS (code) == '1') + { + op1 = force_operand (XEXP (value, 0), NULL_RTX); + return expand_simple_unop (GET_MODE (value), code, op1, target, 0); } #ifdef INSN_SCHEDULING diff --git a/gcc/jump.c b/gcc/jump.c index cad10ff51ca2..1a26b5924b93 100644 --- a/gcc/jump.c +++ b/gcc/jump.c @@ -2428,3 +2428,15 @@ true_regnum (x) } return -1; } + +/* Return regno of the register REG and handle subregs too. */ +unsigned int +reg_or_subregno (reg) + rtx reg; +{ + if (REG_P (reg)) + return REGNO (reg); + if (GET_CODE (reg) == SUBREG) + return REGNO (SUBREG_REG (reg)); + abort (); +} diff --git a/gcc/loop.c b/gcc/loop.c index 8cbc43e19ee0..732a84d64b72 100644 --- a/gcc/loop.c +++ b/gcc/loop.c @@ -4112,11 +4112,17 @@ emit_prefetch_instructions (loop) { rtx reg = gen_reg_rtx (Pmode); rtx loop_start = loop->start; + rtx init_val = info[i].class->initial_value; rtx add_val = simplify_gen_binary (PLUS, Pmode, info[i].giv->add_val, GEN_INT (y * PREFETCH_BLOCK)); - loop_iv_add_mult_emit_before (loop, info[i].class->initial_value, + /* Functions called by LOOP_IV_ADD_EMIT_BEFORE expect a + non-constant INIT_VAL to have the same mode as REG, which + in this case we know to be Pmode. */ + if (GET_MODE (init_val) != Pmode && !CONSTANT_P (init_val)) + init_val = convert_to_mode (Pmode, init_val, 0); + loop_iv_add_mult_emit_before (loop, init_val, info[i].giv->mult_val, add_val, reg, 0, loop_start); emit_insn_before (gen_prefetch (reg, GEN_INT (info[i].write), diff --git a/gcc/reload1.c b/gcc/reload1.c index 001d3edf142b..9782f3ab0c7f 100644 --- a/gcc/reload1.c +++ b/gcc/reload1.c @@ -7586,6 +7586,11 @@ delete_output_reload (insn, j, last_reload_reg) rtx i1; rtx substed; + /* It is possible that this reload has been only used to set another reload + we eliminated earlier and thus deleted this instruction too. */ + if (INSN_DELETED_P (output_reload_insn)) + return; + /* Get the raw pseudo-register referred to. */ while (GET_CODE (reg) == SUBREG) diff --git a/gcc/rtl.h b/gcc/rtl.h index 12f994bc63e3..63b9f5812a44 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -1811,6 +1811,7 @@ extern int invert_jump_1 PARAMS ((rtx, rtx)); extern int invert_jump PARAMS ((rtx, rtx, int)); extern int rtx_renumbered_equal_p PARAMS ((rtx, rtx)); extern int true_regnum PARAMS ((rtx)); +extern unsigned int reg_or_subregno PARAMS ((rtx)); extern int redirect_jump_1 PARAMS ((rtx, rtx)); extern int redirect_jump PARAMS ((rtx, rtx, int)); extern void rebuild_jump_labels PARAMS ((rtx)); diff --git a/gcc/toplev.c b/gcc/toplev.c index efc7c973ac41..2a44398925ce 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -3016,13 +3016,13 @@ rest_of_compilation (decl) block. The loop infrastructure does the real job for us. */ flow_loops_find (&loops, LOOP_TREE); + if (rtl_dump_file) + flow_loops_dump (&loops, rtl_dump_file, NULL, 0); + /* Estimate using heuristics if no profiling info is available. */ if (flag_guess_branch_prob) estimate_probability (&loops); - if (rtl_dump_file) - flow_loops_dump (&loops, rtl_dump_file, NULL, 0); - flow_loops_free (&loops); } life_analysis (insns, rtl_dump_file, PROP_FINAL); diff --git a/gcc/unroll.c b/gcc/unroll.c index 509636c0a6a8..83327c7ba4cf 100644 --- a/gcc/unroll.c +++ b/gcc/unroll.c @@ -2871,7 +2871,7 @@ find_splittable_givs (loop, bl, unroll_type, increment, unroll_number) value = tem; } - splittable_regs[REGNO (v->new_reg)] = value; + splittable_regs[reg_or_subregno (v->new_reg)] = value; } else { @@ -3050,21 +3050,21 @@ find_splittable_givs (loop, bl, unroll_type, increment, unroll_number) itself does not have to be splittable. */ if (v->same && v->same->giv_type == DEST_REG) - addr_combined_regs[REGNO (v->same->new_reg)] = v->same; + addr_combined_regs[reg_or_subregno (v->same->new_reg)] = v->same; if (GET_CODE (v->new_reg) == REG) { /* This giv maybe hasn't been combined with any others. Make sure that it's giv is marked as splittable here. */ - splittable_regs[REGNO (v->new_reg)] = value; + splittable_regs[reg_or_subregno (v->new_reg)] = value; /* Make it appear to depend upon itself, so that the giv will be properly split in the main loop above. */ if (! v->same) { v->same = v; - addr_combined_regs[REGNO (v->new_reg)] = v; + addr_combined_regs[reg_or_subregno (v->new_reg)] = v; } } @@ -3101,7 +3101,7 @@ find_splittable_givs (loop, bl, unroll_type, increment, unroll_number) if (! v->ignore) count = REG_IV_CLASS (ivs, REGNO (v->src_reg))->biv_count; - splittable_regs_updates[REGNO (v->new_reg)] = count; + splittable_regs_updates[reg_or_subregno (v->new_reg)] = count; } result++;