1
0
mirror of https://github.com/cc65/cc65.git synced 2024-06-17 00:29:31 +00:00

For commutative operators processed by hie_internal, if the left side is a

constant, exchange the order of the operands so that better code can be
generated.


git-svn-id: svn://svn.cc65.org/cc65/trunk@5721 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
uz 2012-06-16 18:12:24 +00:00
parent b5d88fdedd
commit ec1f955a6e
2 changed files with 51 additions and 20 deletions

View File

@ -1565,7 +1565,6 @@ static unsigned RunOptGroup1 (CodeSeg* S)
unsigned Changes = 0;
Changes += RunOptFunc (S, &DOptStackPtrOps, 5);
Changes += RunOptFunc (S, &DOptPtrLoad13, 1); /* ### */
Changes += RunOptFunc (S, &DOptPtrStore1, 1);
Changes += RunOptFunc (S, &DOptPtrStore2, 1);
Changes += RunOptFunc (S, &DOptPtrStore3, 1);

View File

@ -1757,7 +1757,7 @@ void hie10 (ExprDesc* Expr)
/* A typecast */
TypeCast (Expr);
} else {
/* An expression */
@ -1789,10 +1789,11 @@ static void hie_internal (const GenDesc* Ops, /* List of generators */
const GenDesc* Gen;
token_t Tok; /* The operator token */
unsigned ltype, type;
int rconst; /* Operand is a constant */
int lconst; /* Left operand is a constant */
int rconst; /* Right operand is a constant */
hienext (Expr);
ExprWithCheck (hienext, Expr);
*UsedGen = 0;
while ((Gen = FindGen (CurTok.Tok, Ops)) != 0) {
@ -1814,10 +1815,16 @@ static void hie_internal (const GenDesc* Ops, /* List of generators */
/* Get the lhs on stack */
GetCodePos (&Mark1);
ltype = TypeOf (Expr->Type);
if (ED_IsConstAbs (Expr)) {
lconst = ED_IsConstAbs (Expr);
if (lconst) {
/* Constant value */
GetCodePos (&Mark2);
g_push (ltype | CF_CONST, Expr->IVal);
/* If the operator is commutative, don't push the left side, if
* it's a constant, since we will exchange both operands.
*/
if ((Gen->Flags & GEN_COMM) == 0) {
g_push (ltype | CF_CONST, Expr->IVal);
}
} else {
/* Value not constant */
LoadExpr (CF_NONE, Expr);
@ -1841,7 +1848,7 @@ static void hie_internal (const GenDesc* Ops, /* List of generators */
}
/* Check for const operands */
if (ED_IsConstAbs (Expr) && rconst) {
if (lconst && rconst) {
/* Both operands are constant, remove the generated code */
RemoveCode (&Mark1);
@ -1926,6 +1933,31 @@ static void hie_internal (const GenDesc* Ops, /* List of generators */
}
}
} else if (lconst && (Gen->Flags & GEN_COMM) && !rconst) {
/* The left side is constant, the right side is not, and the
* operator allows swapping the operands. We haven't pushed the
* left side onto the stack in this case, and will reverse the
* operation because this allows for better code.
*/
unsigned rtype = ltype | CF_CONST;
ltype = TypeOf (Expr2.Type); /* Expr2 is now left */
type = CF_CONST;
if ((Gen->Flags & GEN_NOPUSH) == 0) {
g_push (ltype, 0);
ltype |= CF_REG; /* Value is in register */
}
/* Determine the type of the operation result. */
type |= g_typeadjust (ltype, rtype);
Expr->Type = promoteint (Expr->Type, Expr2.Type);
/* Generate code */
Gen->Func (type, Expr->IVal);
/* We have a rvalue in the primary now */
ED_MakeRValExpr (Expr);
} else {
/* If the right hand side is constant, and the generator function
@ -1937,16 +1969,16 @@ static void hie_internal (const GenDesc* Ops, /* List of generators */
if (rconst) {
/* Second value is constant - check for div */
type |= CF_CONST;
rtype |= CF_CONST;
rtype |= CF_CONST;
if (Tok == TOK_DIV && Expr2.IVal == 0) {
Error ("Division by zero");
} else if (Tok == TOK_MOD && Expr2.IVal == 0) {
Error ("Modulo operation with zero");
}
if ((Gen->Flags & GEN_NOPUSH) != 0) {
RemoveCode (&Mark2);
ltype |= CF_REG; /* Value is in register */
}
if ((Gen->Flags & GEN_NOPUSH) != 0) {
RemoveCode (&Mark2);
ltype |= CF_REG; /* Value is in register */
}
}
/* Determine the type of the operation result. */
@ -1980,7 +2012,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */
GetCodePos (&Mark0);
hienext (Expr);
ExprWithCheck (hienext, Expr);
while ((Gen = FindGen (CurTok.Tok, Ops)) != 0) {
@ -2324,7 +2356,7 @@ static void parseadd (ExprDesc* Expr)
if (ED_IsConst (Expr)) {
/* The left hand side is a constant of some sort. Good. Get rhs */
hie9 (&Expr2);
ExprWithCheck (hie9, &Expr2);
if (ED_IsConstAbs (&Expr2)) {
/* Right hand side is a constant numeric value. Get the rhs type */
@ -2554,7 +2586,7 @@ static void parsesub (ExprDesc* Expr)
/* Get the left hand side type, initialize operation flags */
lhst = Expr->Type;
rscale = 1; /* Scale by 1, that is, don't scale */
rscale = 1; /* Scale by 1, that is, don't scale */
/* Remember the output queue position, then bring the value onto the stack */
GetCodePos (&Mark1);
@ -2708,7 +2740,7 @@ static void parsesub (ExprDesc* Expr)
void hie8 (ExprDesc* Expr)
/* Process + and - binary operators. */
{
hie9 (Expr);
ExprWithCheck (hie9, Expr);
while (CurTok.Tok == TOK_PLUS || CurTok.Tok == TOK_MINUS) {
if (CurTok.Tok == TOK_PLUS) {
parseadd (Expr);
@ -2842,7 +2874,7 @@ static void hieAnd (ExprDesc* Expr, unsigned TrueLab, int* BoolOp)
int FalseLab;
ExprDesc Expr2;
hie2 (Expr);
ExprWithCheck (hie2, Expr);
if (CurTok.Tok == TOK_BOOL_AND) {
/* Tell our caller that we're evaluating a boolean */
@ -2978,14 +3010,14 @@ static void hieQuest (ExprDesc* Expr)
ExprDesc Expr3; /* Expression 3 */
int Expr2IsNULL; /* Expression 2 is a NULL pointer */
int Expr3IsNULL; /* Expression 3 is a NULL pointer */
Type* ResultType; /* Type of result */
Type* ResultType; /* Type of result */
/* Call the lower level eval routine */
if (Preprocessing) {
hieOrPP (Expr);
ExprWithCheck (hieOrPP, Expr);
} else {
hieOr (Expr);
ExprWithCheck (hieOr, Expr);
}
/* Check if it's a ternary expression */