Move cost calculation to nds32-cost.c module.

gcc/
	* config/nds32/nds32.c (nds32_rtx_costs): Move implementation to ...
	(nds32_address_cost): Move implementation to ...
	* config/nds32/nds32-cost.c: ... here.
	* config/nds32/nds32-protos.h (nds32_rtx_costs_impl): Declare.
	(nds32_address_cost_impl): Declare.

Co-Authored-By: Kito Cheng <kito@0xlab.org>
Co-Authored-By: Monk Chiang <sh.chiang04@gmail.com>

From-SVN: r212284
This commit is contained in:
Chung-Ju Wu 2014-07-04 07:31:24 +00:00 committed by Chung-Ju Wu
parent 6a2a98b1a6
commit 89a4b5475a
4 changed files with 268 additions and 195 deletions

View file

@ -1,3 +1,13 @@
2014-07-04 Chung-Ju Wu <jasonwucj@gmail.com>
Kito Cheng <kito@0xlab.org>
Monk Chiang <sh.chiang04@gmail.com>
* config/nds32/nds32.c (nds32_rtx_costs): Move implementation to ...
(nds32_address_cost): Move implementation to ...
* config/nds32/nds32-cost.c: ... here.
* config/nds32/nds32-protos.h (nds32_rtx_costs_impl): Declare.
(nds32_address_cost_impl): Declare.
2014-07-04 Chung-Ju Wu <jasonwucj@gmail.com>
Kito Cheng <kito@0xlab.org>
Monk Chiang <sh.chiang04@gmail.com>

View file

@ -17,3 +17,251 @@
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
/* ------------------------------------------------------------------------ */
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
#include "stor-layout.h"
#include "varasm.h"
#include "calls.h"
#include "rtl.h"
#include "regs.h"
#include "hard-reg-set.h"
#include "insn-config.h" /* Required by recog.h. */
#include "conditions.h"
#include "output.h"
#include "insn-attr.h" /* For DFA state_t. */
#include "insn-codes.h" /* For CODE_FOR_xxx. */
#include "reload.h" /* For push_reload(). */
#include "flags.h"
#include "function.h"
#include "expr.h"
#include "recog.h"
#include "diagnostic-core.h"
#include "df.h"
#include "tm_p.h"
#include "tm-constrs.h"
#include "optabs.h" /* For GEN_FCN. */
#include "target.h"
#include "target-def.h"
#include "langhooks.h" /* For add_builtin_function(). */
#include "ggc.h"
#include "builtins.h"
/* ------------------------------------------------------------------------ */
bool
nds32_rtx_costs_impl (rtx x,
int code,
int outer_code,
int opno ATTRIBUTE_UNUSED,
int *total,
bool speed)
{
/* According to 'speed', goto suitable cost model section. */
if (speed)
goto performance_cost;
else
goto size_cost;
performance_cost:
/* This is section for performance cost model. */
/* In gcc/rtl.h, the default value of COSTS_N_INSNS(N) is N*4.
We treat it as 4-cycle cost for each instruction
under performance consideration. */
switch (code)
{
case SET:
/* For 'SET' rtx, we need to return false
so that it can recursively calculate costs. */
return false;
case USE:
/* Used in combine.c as a marker. */
*total = 0;
break;
case MULT:
*total = COSTS_N_INSNS (1);
break;
case DIV:
case UDIV:
case MOD:
case UMOD:
*total = COSTS_N_INSNS (7);
break;
default:
*total = COSTS_N_INSNS (1);
break;
}
return true;
size_cost:
/* This is section for size cost model. */
/* In gcc/rtl.h, the default value of COSTS_N_INSNS(N) is N*4.
We treat it as 4-byte cost for each instruction
under code size consideration. */
switch (code)
{
case SET:
/* For 'SET' rtx, we need to return false
so that it can recursively calculate costs. */
return false;
case USE:
/* Used in combine.c as a marker. */
*total = 0;
break;
case CONST_INT:
/* All instructions involving constant operation
need to be considered for cost evaluation. */
if (outer_code == SET)
{
/* (set X imm5s), use movi55, 2-byte cost.
(set X imm20s), use movi, 4-byte cost.
(set X BIG_INT), use sethi/ori, 8-byte cost. */
if (satisfies_constraint_Is05 (x))
*total = COSTS_N_INSNS (1) - 2;
else if (satisfies_constraint_Is20 (x))
*total = COSTS_N_INSNS (1);
else
*total = COSTS_N_INSNS (2);
}
else if (outer_code == PLUS || outer_code == MINUS)
{
/* Possible addi333/subi333 or subi45/addi45, 2-byte cost.
General case, cost 1 instruction with 4-byte. */
if (satisfies_constraint_Iu05 (x))
*total = COSTS_N_INSNS (1) - 2;
else
*total = COSTS_N_INSNS (1);
}
else if (outer_code == ASHIFT)
{
/* Possible slli333, 2-byte cost.
General case, cost 1 instruction with 4-byte. */
if (satisfies_constraint_Iu03 (x))
*total = COSTS_N_INSNS (1) - 2;
else
*total = COSTS_N_INSNS (1);
}
else if (outer_code == ASHIFTRT || outer_code == LSHIFTRT)
{
/* Possible srai45 or srli45, 2-byte cost.
General case, cost 1 instruction with 4-byte. */
if (satisfies_constraint_Iu05 (x))
*total = COSTS_N_INSNS (1) - 2;
else
*total = COSTS_N_INSNS (1);
}
else
{
/* For other cases, simply set it 4-byte cost. */
*total = COSTS_N_INSNS (1);
}
break;
case CONST_DOUBLE:
/* It requires high part and low part processing, set it 8-byte cost. */
*total = COSTS_N_INSNS (2);
break;
default:
/* For other cases, generally we set it 4-byte cost
and stop resurively traversing. */
*total = COSTS_N_INSNS (1);
break;
}
return true;
}
int
nds32_address_cost_impl (rtx address,
enum machine_mode mode ATTRIBUTE_UNUSED,
addr_space_t as ATTRIBUTE_UNUSED,
bool speed)
{
rtx plus0, plus1;
enum rtx_code code;
code = GET_CODE (address);
/* According to 'speed', goto suitable cost model section. */
if (speed)
goto performance_cost;
else
goto size_cost;
performance_cost:
/* This is section for performance cost model. */
/* FALLTHRU, currently we use same cost model as size_cost. */
size_cost:
/* This is section for size cost model. */
switch (code)
{
case POST_MODIFY:
case POST_INC:
case POST_DEC:
/* We encourage that rtx contains
POST_MODIFY/POST_INC/POST_DEC behavior. */
return 0;
case SYMBOL_REF:
/* We can have gp-relative load/store for symbol_ref.
Have it 4-byte cost. */
return COSTS_N_INSNS (1);
case CONST:
/* It is supposed to be the pattern (const (plus symbol_ref const_int)).
Have it 4-byte cost. */
return COSTS_N_INSNS (1);
case REG:
/* Simply return 4-byte costs. */
return COSTS_N_INSNS (1);
case PLUS:
/* We do not need to check if the address is a legitimate address,
because this hook is never called with an invalid address.
But we better check the range of
const_int value for cost, if it exists. */
plus0 = XEXP (address, 0);
plus1 = XEXP (address, 1);
if (REG_P (plus0) && CONST_INT_P (plus1))
{
/* If it is possible to be lwi333/swi333 form,
make it 2-byte cost. */
if (satisfies_constraint_Iu05 (plus1))
return (COSTS_N_INSNS (1) - 2);
else
return COSTS_N_INSNS (1);
}
/* For other 'plus' situation, make it cost 4-byte. */
return COSTS_N_INSNS (1);
default:
break;
}
return COSTS_N_INSNS (4);
}
/* ------------------------------------------------------------------------ */

View file

@ -138,4 +138,9 @@ extern void nds32_construct_isr_vectors_information (tree, const char *);
extern void nds32_asm_file_start_for_isr (void);
extern void nds32_asm_file_end_for_isr (void);
/* Auxiliary functions for cost calculation. */
extern bool nds32_rtx_costs_impl (rtx, int, int, int, int *, bool);
extern int nds32_address_cost_impl (rtx, enum machine_mode, addr_space_t, bool);
/* ------------------------------------------------------------------------ */

View file

@ -1853,209 +1853,19 @@ static bool
nds32_rtx_costs (rtx x,
int code,
int outer_code,
int opno ATTRIBUTE_UNUSED,
int opno,
int *total,
bool speed)
{
/* According to 'speed', goto suitable cost model section. */
if (speed)
goto performance_cost;
else
goto size_cost;
performance_cost:
/* This is section for performance cost model. */
/* In gcc/rtl.h, the default value of COSTS_N_INSNS(N) is N*4.
We treat it as 4-cycle cost for each instruction
under performance consideration. */
switch (code)
{
case SET:
/* For 'SET' rtx, we need to return false
so that it can recursively calculate costs. */
return false;
case USE:
/* Used in combine.c as a marker. */
*total = 0;
break;
case MULT:
*total = COSTS_N_INSNS (1);
break;
case DIV:
case UDIV:
case MOD:
case UMOD:
*total = COSTS_N_INSNS (7);
break;
default:
*total = COSTS_N_INSNS (1);
break;
}
return true;
size_cost:
/* This is section for size cost model. */
/* In gcc/rtl.h, the default value of COSTS_N_INSNS(N) is N*4.
We treat it as 4-byte cost for each instruction
under code size consideration. */
switch (code)
{
case SET:
/* For 'SET' rtx, we need to return false
so that it can recursively calculate costs. */
return false;
case USE:
/* Used in combine.c as a marker. */
*total = 0;
break;
case CONST_INT:
/* All instructions involving constant operation
need to be considered for cost evaluation. */
if (outer_code == SET)
{
/* (set X imm5s), use movi55, 2-byte cost.
(set X imm20s), use movi, 4-byte cost.
(set X BIG_INT), use sethi/ori, 8-byte cost. */
if (satisfies_constraint_Is05 (x))
*total = COSTS_N_INSNS (1) - 2;
else if (satisfies_constraint_Is20 (x))
*total = COSTS_N_INSNS (1);
else
*total = COSTS_N_INSNS (2);
}
else if (outer_code == PLUS || outer_code == MINUS)
{
/* Possible addi333/subi333 or subi45/addi45, 2-byte cost.
General case, cost 1 instruction with 4-byte. */
if (satisfies_constraint_Iu05 (x))
*total = COSTS_N_INSNS (1) - 2;
else
*total = COSTS_N_INSNS (1);
}
else if (outer_code == ASHIFT)
{
/* Possible slli333, 2-byte cost.
General case, cost 1 instruction with 4-byte. */
if (satisfies_constraint_Iu03 (x))
*total = COSTS_N_INSNS (1) - 2;
else
*total = COSTS_N_INSNS (1);
}
else if (outer_code == ASHIFTRT || outer_code == LSHIFTRT)
{
/* Possible srai45 or srli45, 2-byte cost.
General case, cost 1 instruction with 4-byte. */
if (satisfies_constraint_Iu05 (x))
*total = COSTS_N_INSNS (1) - 2;
else
*total = COSTS_N_INSNS (1);
}
else
{
/* For other cases, simply set it 4-byte cost. */
*total = COSTS_N_INSNS (1);
}
break;
case CONST_DOUBLE:
/* It requires high part and low part processing, set it 8-byte cost. */
*total = COSTS_N_INSNS (2);
break;
default:
/* For other cases, generally we set it 4-byte cost
and stop resurively traversing. */
*total = COSTS_N_INSNS (1);
break;
}
return true;
return nds32_rtx_costs_impl (x, code, outer_code, opno, total, speed);
}
static int nds32_address_cost (rtx address,
enum machine_mode mode ATTRIBUTE_UNUSED,
addr_space_t as ATTRIBUTE_UNUSED,
enum machine_mode mode,
addr_space_t as,
bool speed)
{
rtx plus0, plus1;
enum rtx_code code;
code = GET_CODE (address);
/* According to 'speed', goto suitable cost model section. */
if (speed)
goto performance_cost;
else
goto size_cost;
performance_cost:
/* This is section for performance cost model. */
/* FALLTHRU, currently we use same cost model as size_cost. */
size_cost:
/* This is section for size cost model. */
switch (code)
{
case POST_MODIFY:
case POST_INC:
case POST_DEC:
/* We encourage that rtx contains
POST_MODIFY/POST_INC/POST_DEC behavior. */
return 0;
case SYMBOL_REF:
/* We can have gp-relative load/store for symbol_ref.
Have it 4-byte cost. */
return COSTS_N_INSNS (1);
case CONST:
/* It is supposed to be the pattern (const (plus symbol_ref const_int)).
Have it 4-byte cost. */
return COSTS_N_INSNS (1);
case REG:
/* Simply return 4-byte costs. */
return COSTS_N_INSNS (1);
case PLUS:
/* We do not need to check if the address is a legitimate address,
because this hook is never called with an invalid address.
But we better check the range of
const_int value for cost, if it exists. */
plus0 = XEXP (address, 0);
plus1 = XEXP (address, 1);
if (REG_P (plus0) && CONST_INT_P (plus1))
{
/* If it is possible to be lwi333/swi333 form,
make it 2-byte cost. */
if (satisfies_constraint_Iu05 (plus1))
return (COSTS_N_INSNS (1) - 2);
else
return COSTS_N_INSNS (1);
}
/* For other 'plus' situation, make it cost 4-byte. */
return COSTS_N_INSNS (1);
default:
break;
}
return COSTS_N_INSNS (4);
return nds32_address_cost_impl (address, mode, as, speed);
}