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:
@@ -1565,7 +1565,6 @@ static unsigned RunOptGroup1 (CodeSeg* S)
|
|||||||
unsigned Changes = 0;
|
unsigned Changes = 0;
|
||||||
|
|
||||||
Changes += RunOptFunc (S, &DOptStackPtrOps, 5);
|
Changes += RunOptFunc (S, &DOptStackPtrOps, 5);
|
||||||
Changes += RunOptFunc (S, &DOptPtrLoad13, 1); /* ### */
|
|
||||||
Changes += RunOptFunc (S, &DOptPtrStore1, 1);
|
Changes += RunOptFunc (S, &DOptPtrStore1, 1);
|
||||||
Changes += RunOptFunc (S, &DOptPtrStore2, 1);
|
Changes += RunOptFunc (S, &DOptPtrStore2, 1);
|
||||||
Changes += RunOptFunc (S, &DOptPtrStore3, 1);
|
Changes += RunOptFunc (S, &DOptPtrStore3, 1);
|
||||||
|
|||||||
@@ -1789,10 +1789,11 @@ static void hie_internal (const GenDesc* Ops, /* List of generators */
|
|||||||
const GenDesc* Gen;
|
const GenDesc* Gen;
|
||||||
token_t Tok; /* The operator token */
|
token_t Tok; /* The operator token */
|
||||||
unsigned ltype, type;
|
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;
|
*UsedGen = 0;
|
||||||
while ((Gen = FindGen (CurTok.Tok, Ops)) != 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 */
|
/* Get the lhs on stack */
|
||||||
GetCodePos (&Mark1);
|
GetCodePos (&Mark1);
|
||||||
ltype = TypeOf (Expr->Type);
|
ltype = TypeOf (Expr->Type);
|
||||||
if (ED_IsConstAbs (Expr)) {
|
lconst = ED_IsConstAbs (Expr);
|
||||||
|
if (lconst) {
|
||||||
/* Constant value */
|
/* Constant value */
|
||||||
GetCodePos (&Mark2);
|
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 {
|
} else {
|
||||||
/* Value not constant */
|
/* Value not constant */
|
||||||
LoadExpr (CF_NONE, Expr);
|
LoadExpr (CF_NONE, Expr);
|
||||||
@@ -1841,7 +1848,7 @@ static void hie_internal (const GenDesc* Ops, /* List of generators */
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Check for const operands */
|
/* Check for const operands */
|
||||||
if (ED_IsConstAbs (Expr) && rconst) {
|
if (lconst && rconst) {
|
||||||
|
|
||||||
/* Both operands are constant, remove the generated code */
|
/* Both operands are constant, remove the generated code */
|
||||||
RemoveCode (&Mark1);
|
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 {
|
} else {
|
||||||
|
|
||||||
/* If the right hand side is constant, and the generator function
|
/* 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) {
|
if (rconst) {
|
||||||
/* Second value is constant - check for div */
|
/* Second value is constant - check for div */
|
||||||
type |= CF_CONST;
|
type |= CF_CONST;
|
||||||
rtype |= CF_CONST;
|
rtype |= CF_CONST;
|
||||||
if (Tok == TOK_DIV && Expr2.IVal == 0) {
|
if (Tok == TOK_DIV && Expr2.IVal == 0) {
|
||||||
Error ("Division by zero");
|
Error ("Division by zero");
|
||||||
} else if (Tok == TOK_MOD && Expr2.IVal == 0) {
|
} else if (Tok == TOK_MOD && Expr2.IVal == 0) {
|
||||||
Error ("Modulo operation with zero");
|
Error ("Modulo operation with zero");
|
||||||
}
|
}
|
||||||
if ((Gen->Flags & GEN_NOPUSH) != 0) {
|
if ((Gen->Flags & GEN_NOPUSH) != 0) {
|
||||||
RemoveCode (&Mark2);
|
RemoveCode (&Mark2);
|
||||||
ltype |= CF_REG; /* Value is in register */
|
ltype |= CF_REG; /* Value is in register */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Determine the type of the operation result. */
|
/* Determine the type of the operation result. */
|
||||||
@@ -1980,7 +2012,7 @@ static void hie_compare (const GenDesc* Ops, /* List of generators */
|
|||||||
|
|
||||||
|
|
||||||
GetCodePos (&Mark0);
|
GetCodePos (&Mark0);
|
||||||
hienext (Expr);
|
ExprWithCheck (hienext, Expr);
|
||||||
|
|
||||||
while ((Gen = FindGen (CurTok.Tok, Ops)) != 0) {
|
while ((Gen = FindGen (CurTok.Tok, Ops)) != 0) {
|
||||||
|
|
||||||
@@ -2324,7 +2356,7 @@ static void parseadd (ExprDesc* Expr)
|
|||||||
if (ED_IsConst (Expr)) {
|
if (ED_IsConst (Expr)) {
|
||||||
|
|
||||||
/* The left hand side is a constant of some sort. Good. Get rhs */
|
/* The left hand side is a constant of some sort. Good. Get rhs */
|
||||||
hie9 (&Expr2);
|
ExprWithCheck (hie9, &Expr2);
|
||||||
if (ED_IsConstAbs (&Expr2)) {
|
if (ED_IsConstAbs (&Expr2)) {
|
||||||
|
|
||||||
/* Right hand side is a constant numeric value. Get the rhs type */
|
/* 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 */
|
/* Get the left hand side type, initialize operation flags */
|
||||||
lhst = Expr->Type;
|
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 */
|
/* Remember the output queue position, then bring the value onto the stack */
|
||||||
GetCodePos (&Mark1);
|
GetCodePos (&Mark1);
|
||||||
@@ -2708,7 +2740,7 @@ static void parsesub (ExprDesc* Expr)
|
|||||||
void hie8 (ExprDesc* Expr)
|
void hie8 (ExprDesc* Expr)
|
||||||
/* Process + and - binary operators. */
|
/* Process + and - binary operators. */
|
||||||
{
|
{
|
||||||
hie9 (Expr);
|
ExprWithCheck (hie9, Expr);
|
||||||
while (CurTok.Tok == TOK_PLUS || CurTok.Tok == TOK_MINUS) {
|
while (CurTok.Tok == TOK_PLUS || CurTok.Tok == TOK_MINUS) {
|
||||||
if (CurTok.Tok == TOK_PLUS) {
|
if (CurTok.Tok == TOK_PLUS) {
|
||||||
parseadd (Expr);
|
parseadd (Expr);
|
||||||
@@ -2842,7 +2874,7 @@ static void hieAnd (ExprDesc* Expr, unsigned TrueLab, int* BoolOp)
|
|||||||
int FalseLab;
|
int FalseLab;
|
||||||
ExprDesc Expr2;
|
ExprDesc Expr2;
|
||||||
|
|
||||||
hie2 (Expr);
|
ExprWithCheck (hie2, Expr);
|
||||||
if (CurTok.Tok == TOK_BOOL_AND) {
|
if (CurTok.Tok == TOK_BOOL_AND) {
|
||||||
|
|
||||||
/* Tell our caller that we're evaluating a boolean */
|
/* Tell our caller that we're evaluating a boolean */
|
||||||
@@ -2978,14 +3010,14 @@ static void hieQuest (ExprDesc* Expr)
|
|||||||
ExprDesc Expr3; /* Expression 3 */
|
ExprDesc Expr3; /* Expression 3 */
|
||||||
int Expr2IsNULL; /* Expression 2 is a NULL pointer */
|
int Expr2IsNULL; /* Expression 2 is a NULL pointer */
|
||||||
int Expr3IsNULL; /* Expression 3 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 */
|
/* Call the lower level eval routine */
|
||||||
if (Preprocessing) {
|
if (Preprocessing) {
|
||||||
hieOrPP (Expr);
|
ExprWithCheck (hieOrPP, Expr);
|
||||||
} else {
|
} else {
|
||||||
hieOr (Expr);
|
ExprWithCheck (hieOr, Expr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if it's a ternary expression */
|
/* Check if it's a ternary expression */
|
||||||
|
|||||||
Reference in New Issue
Block a user