From patchwork Sat Sep 8 22:41:56 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [committed] PA cost update From: John David Anglin X-Patchwork-Id: 182601 Message-Id: <20120908224155.GA26632@hiauly1.hia.nrc.ca> To: gcc-patches@gcc.gnu.org Date: Sat, 8 Sep 2012 18:41:56 -0400 The attached patch improves the cost estimate for multiplication, etc, on parisc. It was noted debugging various PRs that the cost for multiplication of long longs was seriously underestimated. Tested on hppa2.0w-hp-hpux11.11, hppa64-hp-hpux11.11 and hppa-unknown-linux-gnu. Committed to trunk. Dave Index: config/pa/pa.c =================================================================== --- config/pa/pa.c (revision 191079) +++ config/pa/pa.c (working copy) @@ -1422,6 +1422,8 @@ hppa_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED, int *total, bool speed ATTRIBUTE_UNUSED) { + int factor; + switch (code) { case CONST_INT: @@ -1453,11 +1455,20 @@ case MULT: if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT) - *total = COSTS_N_INSNS (3); - else if (TARGET_PA_11 && !TARGET_DISABLE_FPREGS && !TARGET_SOFT_FLOAT) - *total = COSTS_N_INSNS (8); + { + *total = COSTS_N_INSNS (3); + return true; + } + + /* A mode size N times larger than SImode needs O(N*N) more insns. */ + factor = GET_MODE_SIZE (GET_MODE (x)) / 4; + if (factor == 0) + factor = 1; + + if (TARGET_PA_11 && !TARGET_DISABLE_FPREGS && !TARGET_SOFT_FLOAT) + *total = factor * factor * COSTS_N_INSNS (8); else - *total = COSTS_N_INSNS (20); + *total = factor * factor * COSTS_N_INSNS (20); return true; case DIV: @@ -1471,15 +1482,28 @@ case UDIV: case MOD: case UMOD: - *total = COSTS_N_INSNS (60); + /* A mode size N times larger than SImode needs O(N*N) more insns. */ + factor = GET_MODE_SIZE (GET_MODE (x)) / 4; + if (factor == 0) + factor = 1; + + *total = factor * factor * COSTS_N_INSNS (60); return true; case PLUS: /* this includes shNadd insns */ case MINUS: if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT) - *total = COSTS_N_INSNS (3); - else - *total = COSTS_N_INSNS (1); + { + *total = COSTS_N_INSNS (3); + return true; + } + + /* A size N times larger than UNITS_PER_WORD needs N times as + many insns, taking N times as long. */ + factor = GET_MODE_SIZE (GET_MODE (x)) / UNITS_PER_WORD; + if (factor == 0) + factor = 1; + *total = factor * COSTS_N_INSNS (1); return true; case ASHIFT: