mirror of
https://github.com/cc65/cc65.git
synced 2024-11-19 06:31:31 +00:00
Do size improvements always if they have no impact on speed.
git-svn-id: svn://svn.cc65.org/cc65/trunk@4002 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
f374e746af
commit
50b410eb32
@ -1489,22 +1489,21 @@ static unsigned RunOptGroup6 (CodeSeg* S)
|
|||||||
unsigned Changes = 0;
|
unsigned Changes = 0;
|
||||||
unsigned C;
|
unsigned C;
|
||||||
|
|
||||||
if (S->CodeSizeFactor <= 100) {
|
/* Optimize for size, that is replace operations by shorter ones, even
|
||||||
/* Optimize for size, that is replace operations by shorter ones, even
|
* if this does hinder further optimizations (no problem since we're
|
||||||
* if this does hinder further optimizations (no problem since we're
|
* done soon).
|
||||||
* done soon).
|
*/
|
||||||
|
C = RunOptFunc (S, &DOptSize1, 1);
|
||||||
|
if (C) {
|
||||||
|
Changes += C;
|
||||||
|
/* Run some optimization passes again, since the size optimizations
|
||||||
|
* may have opened new oportunities.
|
||||||
*/
|
*/
|
||||||
C = RunOptFunc (S, &DOptSize1, 1);
|
Changes += RunOptFunc (S, &DOptUnusedLoads, 1);
|
||||||
if (C) {
|
Changes += RunOptFunc (S, &DOptJumpTarget, 5);
|
||||||
Changes += C;
|
Changes += RunOptFunc (S, &DOptStore5, 1);
|
||||||
/* Run some optimization passes again, since the size optimizations
|
|
||||||
* may have opened new oportunities.
|
|
||||||
*/
|
|
||||||
Changes += RunOptFunc (S, &DOptUnusedLoads, 1);
|
|
||||||
Changes += RunOptFunc (S, &DOptJumpTarget, 5);
|
|
||||||
Changes += RunOptFunc (S, &DOptStore5, 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
C = RunOptFunc (S, &DOptSize2, 1);
|
C = RunOptFunc (S, &DOptSize2, 1);
|
||||||
if (C) {
|
if (C) {
|
||||||
Changes += C;
|
Changes += C;
|
||||||
|
@ -52,11 +52,16 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Flags for CallDesc */
|
||||||
|
#define F_NONE 0x0000U /* No extra flags */
|
||||||
|
#define F_SLOWER 0x0001U /* Function call is slower */
|
||||||
|
|
||||||
typedef struct CallDesc CallDesc;
|
typedef struct CallDesc CallDesc;
|
||||||
struct CallDesc {
|
struct CallDesc {
|
||||||
const char* LongFunc; /* Long function name */
|
const char* LongFunc; /* Long function name */
|
||||||
short A, X, Y; /* Register contents */
|
short A, X, Y; /* Register contents */
|
||||||
const char* ShortFunc; /* Short function name */
|
unsigned Flags; /* Flags from above */
|
||||||
|
const char* ShortFunc; /* Short function name */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Note: The table is sorted. If there is more than one entry with the same
|
/* Note: The table is sorted. If there is more than one entry with the same
|
||||||
@ -65,55 +70,60 @@ struct CallDesc {
|
|||||||
* at least none of the following ones are better).
|
* at least none of the following ones are better).
|
||||||
*/
|
*/
|
||||||
static const CallDesc CallTable [] = {
|
static const CallDesc CallTable [] = {
|
||||||
/* Name A register X register Y register replacement */
|
/* Name A register X register Y register flags replacement */
|
||||||
{ "addeqysp", UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, "addeq0sp" },
|
{ "addeqysp", UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, F_NONE, "addeq0sp" },
|
||||||
{ "laddeqysp", UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, "laddeq0sp" },
|
{ "laddeqysp", UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, F_NONE, "laddeq0sp" },
|
||||||
{ "ldaxidx", UNKNOWN_REGVAL, UNKNOWN_REGVAL, 1, "ldaxi" },
|
{ "ldaxidx", UNKNOWN_REGVAL, UNKNOWN_REGVAL, 1, F_NONE, "ldaxi" },
|
||||||
{ "ldaxysp", UNKNOWN_REGVAL, UNKNOWN_REGVAL, 1, "ldax0sp" },
|
{ "ldaxysp", UNKNOWN_REGVAL, UNKNOWN_REGVAL, 1, F_NONE, "ldax0sp" },
|
||||||
{ "ldeaxidx", UNKNOWN_REGVAL, UNKNOWN_REGVAL, 3, "ldeaxi" },
|
{ "ldeaxidx", UNKNOWN_REGVAL, UNKNOWN_REGVAL, 3, F_NONE, "ldeaxi" },
|
||||||
{ "ldeaxysp", UNKNOWN_REGVAL, UNKNOWN_REGVAL, 3, "ldeax0sp" },
|
{ "ldeaxysp", UNKNOWN_REGVAL, UNKNOWN_REGVAL, 3, F_NONE, "ldeax0sp" },
|
||||||
{ "pusha", 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, "pushc0" },
|
{ "lsubeqysp", UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, F_NONE, "lsubeq0sp" },
|
||||||
{ "pusha", 1, UNKNOWN_REGVAL, UNKNOWN_REGVAL, "pushc1" },
|
{ "pusha", 0, UNKNOWN_REGVAL, UNKNOWN_REGVAL, F_SLOWER, "pushc0" },
|
||||||
{ "pusha", 2, UNKNOWN_REGVAL, UNKNOWN_REGVAL, "pushc2" },
|
{ "pusha", 1, UNKNOWN_REGVAL, UNKNOWN_REGVAL, F_SLOWER, "pushc1" },
|
||||||
{ "pushax", 0, 0, UNKNOWN_REGVAL, "push0" },
|
{ "pusha", 2, UNKNOWN_REGVAL, UNKNOWN_REGVAL, F_SLOWER, "pushc2" },
|
||||||
{ "pushax", 1, 0, UNKNOWN_REGVAL, "push1" },
|
{ "pushax", 0, 0, UNKNOWN_REGVAL, F_NONE, "push0" },
|
||||||
{ "pushax", 2, 0, UNKNOWN_REGVAL, "push2" },
|
{ "pushax", 1, 0, UNKNOWN_REGVAL, F_SLOWER, "push1" },
|
||||||
{ "pushax", 3, 0, UNKNOWN_REGVAL, "push3" },
|
{ "pushax", 2, 0, UNKNOWN_REGVAL, F_SLOWER, "push2" },
|
||||||
{ "pushax", 4, 0, UNKNOWN_REGVAL, "push4" },
|
{ "pushax", 3, 0, UNKNOWN_REGVAL, F_SLOWER, "push3" },
|
||||||
{ "pushax", 5, 0, UNKNOWN_REGVAL, "push5" },
|
{ "pushax", 4, 0, UNKNOWN_REGVAL, F_SLOWER, "push4" },
|
||||||
{ "pushax", 6, 0, UNKNOWN_REGVAL, "push6" },
|
{ "pushax", 5, 0, UNKNOWN_REGVAL, F_SLOWER, "push5" },
|
||||||
{ "pushax", 7, 0, UNKNOWN_REGVAL, "push7" },
|
{ "pushax", 6, 0, UNKNOWN_REGVAL, F_SLOWER, "push6" },
|
||||||
{ "pushax", UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, "pusha0" },
|
{ "pushax", 7, 0, UNKNOWN_REGVAL, F_SLOWER, "push7" },
|
||||||
{ "pushax", UNKNOWN_REGVAL, 0xFF, UNKNOWN_REGVAL, "pushaFF" },
|
{ "pushax", UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, F_NONE, "pusha0" },
|
||||||
{ "pushaysp", UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, "pusha0sp" },
|
{ "pushax", UNKNOWN_REGVAL, 0xFF, UNKNOWN_REGVAL, F_SLOWER, "pushaFF" },
|
||||||
{ "pushwidx", UNKNOWN_REGVAL, UNKNOWN_REGVAL, 1, "pushw" },
|
{ "pushaysp", UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, F_NONE, "pusha0sp" },
|
||||||
{ "pushwysp", UNKNOWN_REGVAL, UNKNOWN_REGVAL, 3, "pushw0sp" },
|
{ "pushwidx", UNKNOWN_REGVAL, UNKNOWN_REGVAL, 1, F_NONE, "pushw" },
|
||||||
{ "staxysp", UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, "stax0sp" },
|
{ "pushwysp", UNKNOWN_REGVAL, UNKNOWN_REGVAL, 3, F_NONE, "pushw0sp" },
|
||||||
{ "tosaddax", UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, "tosadda0" },
|
{ "staxysp", UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, F_NONE, "stax0sp" },
|
||||||
{ "tosandax", UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, "tosanda0" },
|
{ "steaxysp", UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, F_NONE, "steax0sp" },
|
||||||
{ "tosdivax", UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, "tosdiva0" },
|
{ "subeqysp", UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, F_NONE, "subeq0sp" },
|
||||||
{ "toseqax", UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, "toseqa0" },
|
{ "tosaddax", UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, F_NONE, "tosadda0" },
|
||||||
{ "tosgeax", UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, "tosgea0" },
|
{ "tosandax", UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, F_NONE, "tosanda0" },
|
||||||
{ "tosgtax", UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, "tosgta0" },
|
{ "tosdivax", UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, F_NONE, "tosdiva0" },
|
||||||
{ "tosleax", UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, "toslea0" },
|
{ "toseqax", 0, 0, UNKNOWN_REGVAL, F_NONE, "toseq00" },
|
||||||
{ "tosorax", UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, "tosora0" },
|
{ "toseqax", UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, F_NONE, "toseqa0" },
|
||||||
{ "lsubeqysp", UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, "lsubeq0sp" },
|
{ "tosgeax", 0, 0, UNKNOWN_REGVAL, F_NONE, "tosge00" },
|
||||||
{ "steaxysp", UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, "steax0sp" },
|
{ "tosgeax", UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, F_NONE, "tosgea0" },
|
||||||
{ "subeqysp", UNKNOWN_REGVAL, UNKNOWN_REGVAL, 0, "subeq0sp" },
|
{ "tosgtax", 0, 0, UNKNOWN_REGVAL, F_NONE, "tosgt00" },
|
||||||
{ "tosltax", UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, "toslta0" },
|
{ "tosgtax", UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, F_NONE, "tosgta0" },
|
||||||
{ "tosmodax", UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, "tosmoda0" },
|
{ "tosleax", 0, 0, UNKNOWN_REGVAL, F_NONE, "tosle00" },
|
||||||
{ "tosmulax", UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, "tosmula0" },
|
{ "tosleax", UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, F_NONE, "toslea0" },
|
||||||
{ "tosneax", UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, "tosnea0" },
|
{ "tosltax", 0, 0, UNKNOWN_REGVAL, F_NONE, "toslt00" },
|
||||||
{ "tosrsubax", UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, "tosrsuba0" },
|
{ "tosltax", UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, F_NONE, "toslta0" },
|
||||||
{ "tossubax", UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, "tossuba0" },
|
{ "tosmodax", UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, F_NONE, "tosmoda0" },
|
||||||
{ "tosudivax", UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, "tosudiva0" },
|
{ "tosmulax", UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, F_NONE, "tosmula0" },
|
||||||
{ "tosugeax", UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, "tosugea0" },
|
{ "tosneax", UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, F_NONE, "tosnea0" },
|
||||||
{ "tosugtax", UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, "tosugta0" },
|
{ "tosorax", UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, F_NONE, "tosora0" },
|
||||||
{ "tosuleax", UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, "tosulea0" },
|
{ "tosrsubax", UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, F_NONE, "tosrsuba0" },
|
||||||
{ "tosultax", UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, "tosulta0" },
|
{ "tossubax", UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, F_NONE, "tossuba0" },
|
||||||
{ "tosumodax", UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, "tosumoda0" },
|
{ "tosudivax", UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, F_NONE, "tosudiva0" },
|
||||||
{ "tosumulax", UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, "tosumula0" },
|
{ "tosugeax", UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, F_NONE, "tosugea0" },
|
||||||
{ "tosxorax", UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, "tosxora0" },
|
{ "tosugtax", UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, F_NONE, "tosugta0" },
|
||||||
|
{ "tosuleax", UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, F_NONE, "tosulea0" },
|
||||||
|
{ "tosultax", UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, F_NONE, "tosulta0" },
|
||||||
|
{ "tosumodax", UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, F_NONE, "tosumoda0" },
|
||||||
|
{ "tosumulax", UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, F_NONE, "tosumula0" },
|
||||||
|
{ "tosxorax", UNKNOWN_REGVAL, 0, UNKNOWN_REGVAL, F_NONE, "tosxora0" },
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
"tosadd0ax", /* tosaddeax, sreg = 0 */
|
"tosadd0ax", /* tosaddeax, sreg = 0 */
|
||||||
@ -201,6 +211,9 @@ unsigned OptSize1 (CodeSeg* S)
|
|||||||
unsigned Changes = 0;
|
unsigned Changes = 0;
|
||||||
unsigned I;
|
unsigned I;
|
||||||
|
|
||||||
|
/* Are we optimizing for size */
|
||||||
|
int OptForSize = (S->CodeSizeFactor < 100);
|
||||||
|
|
||||||
/* Generate register info for the following step */
|
/* Generate register info for the following step */
|
||||||
CS_GenRegInfo (S);
|
CS_GenRegInfo (S);
|
||||||
|
|
||||||
@ -216,15 +229,23 @@ unsigned OptSize1 (CodeSeg* S)
|
|||||||
/* Check if it's a subroutine call */
|
/* Check if it's a subroutine call */
|
||||||
if (E->OPC == OP65_JSR && (D = FindCall (E->Arg)) != 0) {
|
if (E->OPC == OP65_JSR && (D = FindCall (E->Arg)) != 0) {
|
||||||
|
|
||||||
/* Check for any of the known functions. */
|
printf ("Found \"%s\" for \"%s\"\n", D->LongFunc, D->ShortFunc);
|
||||||
|
|
||||||
|
/* FindCall finds the first entry that matches our function name.
|
||||||
|
* The names are listed in "best match" order, so search for the
|
||||||
|
* first one, that fulfills our conditions.
|
||||||
|
*/
|
||||||
while (1) {
|
while (1) {
|
||||||
|
|
||||||
/* Check the registers */
|
/* Check the registers and allow slower code only if
|
||||||
|
* optimizing for size.
|
||||||
|
*/
|
||||||
if ((D->A < 0 || D->A == E->RI->In.RegA) &&
|
if ((D->A < 0 || D->A == E->RI->In.RegA) &&
|
||||||
(D->X < 0 || D->X == E->RI->In.RegX) &&
|
(D->X < 0 || D->X == E->RI->In.RegX) &&
|
||||||
(D->Y < 0 || D->Y == E->RI->In.RegY)) {
|
(D->Y < 0 || D->Y == E->RI->In.RegY) &&
|
||||||
|
(OptForSize || (D->Flags & F_SLOWER) == 0)) {
|
||||||
|
|
||||||
/* Ok, match for all registers */
|
/* Ok, match for all conditions */
|
||||||
CodeEntry* X;
|
CodeEntry* X;
|
||||||
X = NewCodeEntry (E->OPC, E->AM, D->ShortFunc, 0, E->LI);
|
X = NewCodeEntry (E->OPC, E->AM, D->ShortFunc, 0, E->LI);
|
||||||
CS_InsertEntry (S, X, I+1);
|
CS_InsertEntry (S, X, I+1);
|
||||||
@ -246,8 +267,8 @@ unsigned OptSize1 (CodeSeg* S)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Next entry */
|
/* Next entry */
|
||||||
++I;
|
++I;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user