symbol *currFunc;
static ast *createIval (ast *, sym_link *, initList *, ast *);
static ast *createIvalCharPtr (ast *, sym_link *, ast *);
+static ast *optimizeCompare (ast *);
ast *optimizeRRCRLC (ast *);
ast *optimizeGetHbit (ast *);
ast *backPatchLabels (ast *, symbol *, symbol *);
return tree;
}
+/*-------------------------------------------------------------*/
+/* constExprTree - returns TRUE if this tree is a constant */
+/* expression */
+/*-------------------------------------------------------------*/
+bool constExprTree (ast *cexpr) {
+
+ if (!cexpr) {
+ return TRUE;
+ }
+
+ cexpr = decorateType (resolveSymbols (cexpr));
+
+ switch (cexpr->type)
+ {
+ case EX_VALUE:
+ if (IS_AST_LIT_VALUE(cexpr)) {
+ // this is a literal
+ return TRUE;
+ }
+ if (IS_AST_SYM_VALUE(cexpr) && IS_FUNC(AST_SYMBOL(cexpr)->type)) {
+ // a function's address will never change
+ return TRUE;
+ }
+ if (IS_AST_SYM_VALUE(cexpr) &&
+ IN_CODESPACE(SPEC_OCLS(AST_SYMBOL(cexpr)->etype))) {
+ // a symbol in code space will never change
+ // This is only for the 'char *s="hallo"' case and will have to leave
+ return TRUE;
+ }
+ return FALSE;
+ case EX_LINK:
+ werror (E_INTERNAL_ERROR, __FILE__, __LINE__,
+ "unexpected link in expression tree\n");
+ return FALSE;
+ case EX_OP:
+ if (cexpr->opval.op==ARRAYINIT) {
+ fprintf (stderr, "skipping arrayinit\n");
+ // this is a list of literals
+ return TRUE;
+ }
+ if (cexpr->opval.op=='=') {
+ return constExprTree(cexpr->right);
+ }
+ if (cexpr->opval.op==CAST) {
+ // jwk: cast ignored, maybe we should throw a warning here
+ return constExprTree(cexpr->right);
+ }
+ if (cexpr->opval.op=='&') {
+ return TRUE;
+ }
+ if (cexpr->opval.op==CALL || cexpr->opval.op==PCALL) {
+ return FALSE;
+ }
+ if (constExprTree(cexpr->left) && constExprTree(cexpr->right)) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
/*-----------------------------------------------------------------*/
/* constExprValue - returns the value of a constant expression */
/* or NULL if it is not a constant expression */
switch (tree->opval.op)
{
- /*------------------------------------------------------------------*/
- /*----------------------------*/
- /* array node */
- /*----------------------------*/
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
+ /* array node */
+ /*----------------------------*/
case '[':
/* determine which is the array & which the index */
return tree;
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
/* ++/-- operation */
-/*----------------------------*/
+ /*----------------------------*/
case INC_OP: /* incerement operator unary so left only */
case DEC_OP:
{
return tree;
}
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
/* bitwise and */
-/*----------------------------*/
+ /*----------------------------*/
case '&': /* can be unary */
/* if right is NULL then unary operation */
if (tree->right) /* not an unary operation */
return tree;
}
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
/* address of */
-/*----------------------------*/
+ /*----------------------------*/
p = newLink ();
p->class = DECLARATOR;
/* if bit field then error */
TLVAL (tree) = 1;
return tree;
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
/* bitwise or */
-/*----------------------------*/
+ /*----------------------------*/
case '|':
/* if the rewrite succeeds then don't go any furthur */
{
if (wtree != tree)
return decorateType (wtree);
}
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
/* bitwise xor */
-/*----------------------------*/
+ /*----------------------------*/
case '^':
if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
{
computeType (LTYPE (tree),
RTYPE (tree)));
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
/* division */
-/*----------------------------*/
+ /*----------------------------*/
case '/':
if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
{
RTYPE (tree)));
return tree;
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
/* modulus */
-/*----------------------------*/
+ /*----------------------------*/
case '%':
if (!IS_INTEGRAL (LTYPE (tree)) || !IS_INTEGRAL (RTYPE (tree)))
{
RTYPE (tree)));
return tree;
-/*------------------------------------------------------------------*/
-/*----------------------------*/
-/* address dereference */
-/*----------------------------*/
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
+ /* address dereference */
+ /*----------------------------*/
case '*': /* can be unary : if right is null then unary operation */
if (!tree->right)
{
return tree;
}
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
/* multiplication */
-/*----------------------------*/
+ /*----------------------------*/
if (!IS_ARITHMETIC (LTYPE (tree)) || !IS_ARITHMETIC (RTYPE (tree)))
{
werror (E_INVALID_OP, "multiplication");
}
return tree;
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
/* unary '+' operator */
-/*----------------------------*/
+ /*----------------------------*/
case '+':
/* if unary plus */
if (!tree->right)
return tree;
}
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
/* addition */
-/*----------------------------*/
+ /*----------------------------*/
/* this is not a unary operation */
/* if both pointers then problem */
RTYPE (tree)));
return tree;
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
/* unary '-' */
-/*----------------------------*/
+ /*----------------------------*/
case '-': /* can be unary */
/* if right is null then unary */
if (!tree->right)
return tree;
}
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
/* subtraction */
-/*----------------------------*/
+ /*----------------------------*/
if (!(IS_PTR (LTYPE (tree)) ||
IS_ARRAY (LTYPE (tree)) ||
LRVAL (tree) = RRVAL (tree) = 1;
return tree;
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
/* compliment */
-/*----------------------------*/
+ /*----------------------------*/
case '~':
/* can be only integral type */
if (!IS_INTEGRAL (LTYPE (tree)))
COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
return tree;
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
/* not */
-/*----------------------------*/
+ /*----------------------------*/
case '!':
/* can be pointer */
if (!IS_ARITHMETIC (LTYPE (tree)) &&
TTYPE (tree) = TETYPE (tree) = newCharLink ();
return tree;
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
/* shift */
-/*----------------------------*/
+ /*----------------------------*/
case RRC:
case RLC:
TTYPE (tree) = LTYPE (tree);
return tree;
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
/* logical &&, || */
-/*----------------------------*/
+ /*----------------------------*/
case AND_OP:
case OR_OP:
/* each must me arithmetic type or be a pointer */
TTYPE (tree) = TETYPE (tree) = newCharLink ();
return tree;
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
/* comparison operators */
-/*----------------------------*/
+ /*----------------------------*/
case '>':
case '<':
case LE_OP:
goto errorTreeReturn;
}
}
+ /* if unsigned value < 0 then always false */
+ /* if (unsigned value) > 0 then (unsigned value) */
+ if (SPEC_USIGN(LETYPE(tree)) && IS_LITERAL(RTYPE(tree)) &&
+ ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0) {
+ if (tree->opval.op == '<') {
+ return tree->right;
+ }
+ if (tree->opval.op == '>') {
+ return tree->left;
+ }
+ }
/* if they are both literal then */
/* rewrite the tree */
if (IS_LITERAL (RTYPE (tree)) &&
TTYPE (tree) = TETYPE (tree) = newCharLink ();
return tree;
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
/* sizeof */
-/*----------------------------*/
+ /*----------------------------*/
case SIZEOF: /* evaluate wihout code generation */
/* change the type to a integer */
tree->type = EX_VALUE;
return tree;
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
/* assignment operators */
-/*----------------------------*/
+ /*----------------------------*/
case MUL_ASSIGN:
case DIV_ASSIGN:
/* for these it must be both must be integral */
return tree;
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
/* -= operator */
-/*----------------------------*/
+ /*----------------------------*/
case SUB_ASSIGN:
if (!(IS_PTR (LTYPE (tree)) ||
IS_ARITHMETIC (LTYPE (tree))))
return tree;
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
/* += operator */
-/*----------------------------*/
+ /*----------------------------*/
case ADD_ASSIGN:
/* this is not a unary operation */
/* if both pointers then problem */
return tree;
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
/* straight assignemnt */
-/*----------------------------*/
+ /*----------------------------*/
case '=':
/* cannot be an aggregate */
if (IS_AGGREGATE (LTYPE (tree)))
return tree;
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
/* comma operator */
-/*----------------------------*/
+ /*----------------------------*/
case ',':
TETYPE (tree) = getSpec (TTYPE (tree) = RTYPE (tree));
return tree;
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
/* function call */
-/*----------------------------*/
+ /*----------------------------*/
case CALL:
parmNumber = 1;
TETYPE (tree) = getSpec (TTYPE (tree) = LTYPE (tree)->next);
return tree;
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
/* return statement */
-/*----------------------------*/
+ /*----------------------------*/
case RETURN:
if (!tree->right)
goto voidcheck;
TTYPE (tree) = TETYPE (tree) = NULL;
return tree;
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
/* switch statement */
-/*----------------------------*/
+ /*----------------------------*/
case SWITCH:
/* the switch value must be an integer */
if (!IS_INTEGRAL (LTYPE (tree)))
TTYPE (tree) = TETYPE (tree) = NULL;
return tree;
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
/* ifx Statement */
-/*----------------------------*/
+ /*----------------------------*/
case IFX:
tree->left = backPatchLabels (tree->left,
tree->trueLabel,
TTYPE (tree) = TETYPE (tree) = NULL;
return tree;
-/*------------------------------------------------------------------*/
-/*----------------------------*/
+ /*------------------------------------------------------------------*/
+ /*----------------------------*/
/* for Statement */
-/*----------------------------*/
+ /*----------------------------*/
case FOR:
decorateType (resolveSymbols (AST_FOR (tree, initExpr)));
/*-----------------------------------------------------------------*/
/* optimizeCompare - otimizes compares for bit variables */
/*-----------------------------------------------------------------*/
-ast *
+static ast *
optimizeCompare (ast * root)
{
ast *optExpr = NULL;
vright = (root->right->type == EX_VALUE ?
root->right->opval.val : NULL);
- //#define EXPERIMENTAL
-#ifdef EXPERIMENTAL
- /* if left is unsigned and right is literal */
- if (vleft && vright &&
- IS_UNSIGNED(vleft->etype) &&
- IS_LITERAL(vright->etype)) {
- double dval=floatFromVal(vright);
- int op=root->opval.op;
-
- fprintf (stderr,"op: '");
- switch (op) {
- case LE_OP: fprintf (stderr, "<= '"); break;
- case EQ_OP: fprintf (stderr, "== '"); break;
- case GE_OP: fprintf (stderr, ">= '"); break;
- default: fprintf (stderr, "%c '", op); break;
- }
- fprintf (stderr, "%f\n", dval);
-
- switch (op)
- {
- case EQ_OP:
- case LE_OP:
- case '<':
- if (dval<0 || (op=='<' && dval==0)) {
- // unsigned is never < 0
- werror (W_IF_NEVER_TRUE);
- optExpr = newAst_VALUE (constVal("0"));
- return decorateType (optExpr);
- }
- if (dval==0) {
- if (op==LE_OP) {
- // change this into a cheaper EQ_OP
- fprintf (stderr, "warning *** changed '<=' to '==' because of unsigned\n");
- root->opval.op=EQ_OP;
- return root;
- }
- }
- break;
- case GE_OP:
- case '>':
- if (dval>0 || (op==GE_OP && dval==0)) {
- // unsigned is never < 0
- werror (W_IF_ALWAYS_TRUE);
- optExpr = newAst_VALUE (constVal("1"));
- return decorateType (optExpr);
- }
- if (dval==0) {
- if (op=='>') {
- // change this into a cheaper reversed EQ_OP
- fprintf (stderr, "warning *** changed '>' to '!=' because of unsigned\n");
- root->opval.op=EQ_OP;
- }
- }
- }
- }
-#endif
-
/* if left is a BITVAR in BITSPACE */
/* and right is a LITERAL then opt- */
/* imize else do nothing */