X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCpeeph.c;h=5a7447fff503ce66a2099c3a4ccd4d7da8c5a905;hb=5a1d5e778e85664f4e6657019348b4756b16eacb;hp=a4341f1f2e34757362be8b045d44f779c443e498;hpb=3d5f7dfa8edf8ea9a0e1b0d74ab0daadbf7e819c;p=fw%2Fsdcc diff --git a/src/SDCCpeeph.c b/src/SDCCpeeph.c index a4341f1f..5a7447ff 100644 --- a/src/SDCCpeeph.c +++ b/src/SDCCpeeph.c @@ -61,7 +61,38 @@ void pic16_peepRules2pCode(peepRule *); #endif /*-----------------------------------------------------------------*/ -/* pcDistance - afinds a label back ward or forward */ +/* getPatternVar - finds a pattern variable */ +/*-----------------------------------------------------------------*/ + +static char* +getPatternVar (hTab *vars, char **cmdLine) +{ + int varNumber; + char *digitend; + + if (!cmdLine || !*cmdLine || !**cmdLine) + return NULL; /* no parameters given */ + + while (**cmdLine && ISCHARSPACE(**cmdLine)) + (*cmdLine)++; /* skip whitespace */ + + if (**cmdLine != '%') + goto error; + (*cmdLine)++; + if (!ISCHARDIGIT (**cmdLine)) + goto error; + varNumber = strtol (*cmdLine, &digitend, 10); + *cmdLine = digitend; + return hTabItemWithKey (vars, varNumber); + +error: + fprintf (stderr, + "*** internal error: peephole restriction malformed: %s\n", *cmdLine); + return NULL; +} + +/*-----------------------------------------------------------------*/ +/* pcDistance - finds a label backward or forward */ /*-----------------------------------------------------------------*/ static int @@ -74,16 +105,19 @@ pcDistance (lineNode * cpos, char *lbl, bool back) SNPRINTF (buff, sizeof(buff), "%s:", lbl); while (pl) { - if (pl->line && !pl->isComment && !pl->isLabel && - !pl->isDebug) { - if (port->peep.getSize) { - dist += port->peep.getSize(pl); - } else { - dist += 3; - } + !pl->isDebug) + { + if (port->peep.getSize) + { + dist += port->peep.getSize(pl); + } + else + { + dist += 3; + } } if (strncmp (pl->line, buff, strlen (buff)) == 0) @@ -98,16 +132,6 @@ pcDistance (lineNode * cpos, char *lbl, bool back) return 0; } -/*-----------------------------------------------------------------*/ -/* flat24bitModeAndPortDS390 - */ -/*-----------------------------------------------------------------*/ -FBYNAME (flat24bitModeAndPortDS390) -{ - return (((strcmp(port->target,"ds390") == 0) || - (strcmp(port->target,"ds400") == 0)) && - (options.model == MODEL_FLAT24)); -} - /*-----------------------------------------------------------------*/ /* portIsDS390 - return true if port is DS390 */ /*-----------------------------------------------------------------*/ @@ -133,51 +157,65 @@ FBYNAME (xramMovcOption) return (options.xram_movc && (strcmp(port->target,"mcs51") == 0)); } - - - - +/*-----------------------------------------------------------------*/ +/* useAcallAjmp - Enable replacement of lcall/ljmp with acall/ajmp */ +/*-----------------------------------------------------------------*/ +FBYNAME (useAcallAjmp) +{ + return (options.acall_ajmp && (strcmp(port->target,"mcs51") == 0)); +} /*-----------------------------------------------------------------*/ -/* labelInRange - will check to see if label %5 is within range */ +/* labelInRange - will check to see if label is within range */ /*-----------------------------------------------------------------*/ FBYNAME (labelInRange) { - /* assumes that %5 pattern variable has the label name */ - char *lbl = hTabItemWithKey (vars, 5); int dist = 0; + char *lbl = getPatternVar (vars, &cmdLine); if (!lbl) - return FALSE; + { + /* If no parameters given, assume that %5 pattern variable + has the label name for backward compatibility */ + lbl = hTabItemWithKey (vars, 5); + } - /* Don't optimize jumps in a jump table; a more generic test */ - if (currPl->ic && currPl->ic->op == JUMPTABLE) + if (!lbl) return FALSE; - /* if the previous two instructions are "ljmp"s then don't - do it since it can be part of a jump table */ - if (currPl->prev && currPl->prev->prev && - strstr (currPl->prev->line, "ljmp") && - strstr (currPl->prev->prev->line, "ljmp")) - return FALSE; + do + { + /* Don't optimize jumps in a jump table; a more generic test */ + if (currPl->ic && currPl->ic->op == JUMPTABLE) + return FALSE; - /* calculate the label distance : the jump for reladdr can be - +/- 127 bytes, here Iam assuming that an average 8051 - instruction is 2 bytes long, so if the label is more than - 63 intructions away, the label is considered out of range - for a relative jump. we could get more precise this will - suffice for now since it catches > 90% cases */ - dist = (pcDistance (currPl, lbl, TRUE) + - pcDistance (currPl, lbl, FALSE)); - -/* changed to 127, now that pcDistance return actual number of bytes */ - if (!dist || dist > 127) - return FALSE; + /* if the previous two instructions are "ljmp"s then don't + do it since it can be part of a jump table */ + if (currPl->prev && currPl->prev->prev && + strstr (currPl->prev->line, "ljmp") && + strstr (currPl->prev->prev->line, "ljmp")) + return FALSE; + + /* calculate the label distance : the jump for reladdr can be + +/- 127 bytes, here I am assuming that an average 8051 + instruction is 2 bytes long, so if the label is more than + 63 intructions away, the label is considered out of range + for a relative jump. we could get more precise this will + suffice for now since it catches > 90% cases */ + dist = (pcDistance (currPl, lbl, TRUE) + + pcDistance (currPl, lbl, FALSE)); + + /* changed to 127, now that pcDistance return actual number of bytes */ + if (!dist || dist > 127) + return FALSE; + + lbl = getPatternVar (vars, &cmdLine); + } + while (lbl); return TRUE; } - /*-----------------------------------------------------------------*/ /* labelJTInRange - will check to see if label %5 and up are */ /* within range. */ @@ -221,7 +259,6 @@ FBYNAME (labelJTInRange) return TRUE; } - /*-----------------------------------------------------------------*/ /* labelIsReturnOnly - Check if label %5 is followed by RET */ /*-----------------------------------------------------------------*/ @@ -248,7 +285,7 @@ FBYNAME (labelIsReturnOnly) { if (strncmp(pl->line, label, len) == 0) break; /* Found Label */ - if (strlen(pl->line) != 7 || !ISCHARDIGIT(*(pl->line)) || + if (strlen(pl->line) != 7 || !ISCHARDIGIT(*(pl->line)) || !ISCHARDIGIT(*(pl->line+1)) || !ISCHARDIGIT(*(pl->line+2)) || !ISCHARDIGIT(*(pl->line+3)) || !ISCHARDIGIT(*(pl->line+4)) || *(pl->line+5) != '$') @@ -266,7 +303,7 @@ FBYNAME (labelIsReturnOnly) return FALSE; /* next line not valid */ p = pl->line; for (p = pl->line; *p && ISCHARSPACE(*p); p++) - ; + ; retInst = "ret"; if (TARGET_IS_HC08) @@ -276,7 +313,6 @@ FBYNAME (labelIsReturnOnly) return FALSE; } - /*-----------------------------------------------------------------*/ /* labelIsUncondJump - Check if label %5 is followed by an */ /* unconditional jump and put the destination of that jump in %6 */ @@ -353,12 +389,13 @@ FBYNAME (labelIsUncondJump) if (*q==',') return FALSE; /* conditional jump */ } + if (strcmp(p, q) == 0) + return FALSE; /* labels are equal */ /* now put the destination in %6 */ bindVar (6, &p, &vars); return TRUE; } - /*-----------------------------------------------------------------*/ /* okToRemoveSLOC - Check if label %1 is a SLOC and not other */ /* usage of it in the code depends on a value from this section */ @@ -404,7 +441,29 @@ FBYNAME (deadMove) if (port->peep.deadMove) return port->peep.deadMove (reg, currPl, head); - fprintf (stderr, "Function deadMove not initialized in port structure\n"); + fprintf (stderr, "Function deadMove not initialized in port structure\n"); + return FALSE; +} + +/*-----------------------------------------------------------------*/ +/* notUsed - Check, if value in register is not read again */ +/*-----------------------------------------------------------------*/ +FBYNAME (notUsed) +{ + const char *what; + + if(cmdLine[0] != '\'') + what = hTabItemWithKey (vars, 1); + else + { + cmdLine[strlen(cmdLine) - 1] = 0; + what = cmdLine + 1; + } + + if (port->peep.notUsed) + return port->peep.notUsed (what, endPl, head); + + fprintf (stderr, "Function notUsed not initialized in port structure\n"); return FALSE; } @@ -518,7 +577,6 @@ FBYNAME (operandsNotSame6) return TRUE; } - /*-----------------------------------------------------------------*/ /* operandsNotSame7- check if any pair of %1,%2,%3,.. are the same */ /*-----------------------------------------------------------------*/ @@ -689,7 +747,6 @@ FBYNAME (labelRefCount) return rc; } - /* labelRefCountChange: * takes two parameters: a variable (bound to a label name) * and a signed int for changing the reference count. @@ -766,7 +823,6 @@ FBYNAME (labelRefCountChange) return rc; } - /* Within the context of the lines currPl through endPl, determine ** if the variable var contains a symbol that is volatile. Returns ** TRUE only if it is certain that this was not volatile (the symbol @@ -831,22 +887,52 @@ notVolatileVariable(char *var, lineNode *currPl, lineNode *endPl) { case IFX: op = IC_COND (cl->ic); - if (IS_SYMOP (op) && !strcmp(OP_SYMBOL (op)->rname,symname) ) - return !op->isvolatile; + if (IS_SYMOP (op) && + ( !strcmp(OP_SYMBOL (op)->rname, symname) || + (OP_SYMBOL (op)->isspilt && + SPIL_LOC (op) && + !strcmp(SPIL_LOC (op)->rname, symname)) )) + { + return !op->isvolatile; + } case JUMPTABLE: op = IC_JTCOND (cl->ic); - if (IS_SYMOP (op) && !strcmp(OP_SYMBOL (op)->rname,symname) ) - return !op->isvolatile; + if (IS_SYMOP (op) && + ( !strcmp(OP_SYMBOL (op)->rname, symname) || + (OP_SYMBOL (op)->isspilt && + SPIL_LOC (op) && + !strcmp(SPIL_LOC (op)->rname, symname)) )) + { + return !op->isvolatile; + } default: op = IC_LEFT (cl->ic); - if (IS_SYMOP (op) && !strcmp(OP_SYMBOL (op)->rname,symname) ) - return !op->isvolatile; + if (IS_SYMOP (op) && + ( !strcmp(OP_SYMBOL (op)->rname, symname) || + (OP_SYMBOL (op)->isspilt && + SPIL_LOC (op) && + !strcmp(SPIL_LOC (op)->rname, symname)) )) + { + return !op->isvolatile; + } op = IC_RIGHT (cl->ic); - if (IS_SYMOP (op) && !strcmp(OP_SYMBOL (op)->rname,symname) ) - return !op->isvolatile; + if (IS_SYMOP (op) && + ( !strcmp(OP_SYMBOL (op)->rname, symname) || + (OP_SYMBOL (op)->isspilt && + SPIL_LOC (op) && + !strcmp(SPIL_LOC (op)->rname, symname)) )) + { + return !op->isvolatile; + } op = IC_RESULT (cl->ic); - if (IS_SYMOP (op) && !strcmp(OP_SYMBOL (op)->rname,symname) ) - return !op->isvolatile; + if (IS_SYMOP (op) && + ( !strcmp(OP_SYMBOL (op)->rname, symname) || + (OP_SYMBOL (op)->isspilt && + SPIL_LOC (op) && + !strcmp(SPIL_LOC (op)->rname, symname)) )) + { + return !op->isvolatile; + } } } } @@ -945,7 +1031,6 @@ FBYNAME (notVolatile) return TRUE; - error: fprintf (stderr, "*** internal error: notVolatile peephole restriction" @@ -953,7 +1038,6 @@ error: return FALSE; } - /*------------------------------------------------------------------*/ /* setFromConditionArgs - parse a peephole condition's arguments */ /* to produce a set of strings, one per argument. Variables %x will */ @@ -1029,12 +1113,14 @@ operandBaseName (const char *op) return "a"; if (!strncmp (op, "ar", 2) && ISCHARDIGIT(*(op+2)) && !*(op+3)) return op+1; + // bug 1739475, temp fix + if (op[0] == '@') + return operandBaseName(op+1); } return op; } - /*-------------------------------------------------------------------*/ /* operandsNotRelated - returns true if the condition's operands are */ /* not related (taking into account register name aliases). N-way */ @@ -1075,7 +1161,6 @@ FBYNAME (operandsNotRelated) return TRUE; } - /*-------------------------------------------------------------------*/ /* operandsLiteral - returns true of the condition's operands are */ /* literals. */ @@ -1108,103 +1193,93 @@ FBYNAME (operandsLiteral) return TRUE; } - +static const struct ftab +{ + char *fname; + int (*func) (hTab *, lineNode *, lineNode *, lineNode *, char *); +} +ftab[] = // sorted on the number of times used +{ // in the peephole rules on 2007-10-29 + { + "labelRefCount", labelRefCount //105 + }, + { + "notVolatile", notVolatile //85 + }, + { + "labelRefCountChange", labelRefCountChange //74 + }, + { + "labelInRange", labelInRange //37 + }, + { + "labelJTInRange", labelJTInRange //13 + }, + { + "operandsNotRelated", operandsNotRelated //9 + }, + { + "24bitMode", flat24bitMode //9 + }, + { + "operandsNotSame", operandsNotSame //8 + }, + { + "operandsNotSame3", operandsNotSame3 + }, + { + "operandsNotSame4", operandsNotSame4 + }, + { + "operandsNotSame5", operandsNotSame5 + }, + { + "operandsNotSame6", operandsNotSame6 + }, + { + "operandsNotSame7", operandsNotSame7 + }, + { + "operandsNotSame8", operandsNotSame8 + }, + { + "xramMovcOption", xramMovcOption + }, + { + "portIsDS390", portIsDS390 + }, + { + "labelIsReturnOnly", labelIsReturnOnly + }, + { + "labelIsUncondJump", labelIsUncondJump + }, + { + "okToRemoveSLOC", okToRemoveSLOC + }, + { + "deadMove", deadMove + }, + { + "operandsLiteral", operandsLiteral + }, + { + "useAcallAjmp", useAcallAjmp + }, + { + "notUsed", notUsed + } +}; /*-----------------------------------------------------------------*/ /* callFuncByName - calls a function as defined in the table */ /*-----------------------------------------------------------------*/ static int callFuncByName (char *fname, hTab * vars, - lineNode * currPl, - lineNode * endPl, + lineNode * currPl, /* first source line matched */ + lineNode * endPl, /* last source line matched */ lineNode * head) { - struct ftab - { - char *fname; - int (*func) (hTab *, lineNode *, lineNode *, lineNode *, char *); - } - ftab[] = - { - { - "labelInRange", labelInRange - } - , - { - "labelJTInRange", labelJTInRange - } - , - { - "operandsNotSame", operandsNotSame - } - , - { - "operandsNotSame3", operandsNotSame3 - } - , - { - "operandsNotSame4", operandsNotSame4 - } - , - { - "operandsNotSame5", operandsNotSame5 - } - , - { - "operandsNotSame6", operandsNotSame6 - } - , - { - "operandsNotSame7", operandsNotSame7 - } - , - { - "operandsNotSame8", operandsNotSame8 - } - , - { - "24bitMode", flat24bitMode - } - , - { - "xramMovcOption", xramMovcOption - } - , - { - "labelRefCount", labelRefCount - } - , - { - "portIsDS390", portIsDS390 - }, - { - "labelIsReturnOnly", labelIsReturnOnly - }, - { - "labelIsUncondJump", labelIsUncondJump - }, - { - "okToRemoveSLOC", okToRemoveSLOC - }, - { - "deadMove", deadMove - }, - { - "24bitModeAndPortDS390", flat24bitModeAndPortDS390 - }, - { - "notVolatile", notVolatile - }, - { - "operandsNotRelated", operandsNotRelated - }, - { - "operandsLiteral", operandsLiteral - }, - { - "labelRefCountChange", labelRefCountChange - } - }; int i; char *cmdCopy, *funcName, *funcArgs, *cmdTerm; char c; @@ -1237,9 +1312,18 @@ callFuncByName (char *fname, /* and there can be no additional conditions. */ if (c == '(') { - cmdTerm = funcArgs; - while ((c = *cmdTerm) && c != ')') - cmdTerm++; + + int num_parenthesis = 0; + cmdTerm = funcArgs; + + while ((c = *cmdTerm) && (c != ')' || num_parenthesis)) + { + if (c == '(') + num_parenthesis++; + else if (c == ')') + num_parenthesis--; + cmdTerm++; + } *cmdTerm = '\0'; /* terminate the arguments */ if (c == ')') { @@ -1561,18 +1645,18 @@ top: newPeepRule (match, replace, lines, restart); } else - { + { if (*bp && strncmp (bp, "replace", 7)) { /* not the start of a new peeprule, so "if" should be here */ - + char strbuff[1000]; char *cp; - + /* go to the start of the line following "{" of the "by" token */ while (*rp && (*rp == '\n')) rp++; - + /* copy text of rule starting with line after "by {" */ cp = strbuff; while (*rp && (rp < bp) && ((cp - strbuff) < sizeof(strbuff))) @@ -1587,7 +1671,7 @@ top: return; } newPeepRule (match, replace, NULL, restart); - } + } goto top; } @@ -1662,13 +1746,11 @@ bindVar (int key, char **s, hTab ** vtab) static bool matchLine (char *s, char *d, hTab ** vars) { - if (!s || !(*s)) return FALSE; while (*s && *d) { - /* skip white space in both */ while (ISCHARSPACE (*s)) s++; @@ -2264,7 +2346,7 @@ peepHole (lineNode ** pls) lineNode *spl; peepRule *pr; lineNode *mtail = NULL; - bool restart; + bool restart, replaced; #if !OPT_DISABLE_PIC || !OPT_DISABLE_PIC16 /* The PIC port uses a different peep hole optimizer based on "pCode" */ @@ -2281,8 +2363,10 @@ peepHole (lineNode ** pls) /* for all rules */ for (pr = rootRules; pr; pr = pr->next) { - for (spl = *pls; spl; spl = spl->next) + for (spl = *pls; spl; spl = replaced ? spl : spl->next) { + replaced = FALSE; + /* if inline assembler then no peep hole */ if (spl->isInline) continue; @@ -2299,10 +2383,15 @@ peepHole (lineNode ** pls) /* if it matches */ if (matchRule (spl, &mtail, pr, *pls)) { + /* restart at the replaced line */ + replaced = TRUE; /* then replace */ if (spl == *pls) - replaceRule (pls, mtail, pr); + { + replaceRule (pls, mtail, pr); + spl = *pls; + } else replaceRule (&spl, mtail, pr); @@ -2375,7 +2464,7 @@ readFileIntoBuffer (char *fname) } } - /* if some charaters left over */ + /* if some characters left over */ if (nch) { lb[nch] = '\0';