X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCpeeph.c;h=871ca6768d519e3dc632224f70bb0f54f576ffda;hb=c4cd7a8c98eaf5ef8e39c76533a9277e83cf7585;hp=8225ac5e705611e42a6bfcce1d852587831c4e35;hpb=195ee3f3ee25ce2c5f2a59fbd2779c4cb80527c3;p=fw%2Fsdcc diff --git a/src/SDCCpeeph.c b/src/SDCCpeeph.c index 8225ac5e..871ca676 100644 --- a/src/SDCCpeeph.c +++ b/src/SDCCpeeph.c @@ -24,6 +24,7 @@ -------------------------------------------------------------------------*/ #include "common.h" +#include "dbuf_string.h" #define ISCHARDIGIT(c) isdigit((unsigned char)c) #define ISCHARSPACE(c) isspace((unsigned char)c) @@ -33,14 +34,8 @@ static peepRule *rootRules = NULL; static peepRule *currRule = NULL; #define HTAB_SIZE 53 -typedef struct - { - char name[SDCC_NAME_MAX + 1]; - int refCount; - } -labelHashEntry; -static hTab *labelHash = NULL; +hTab *labelHash = NULL; static struct { @@ -50,11 +45,11 @@ static struct static int hashSymbolName (const char *name); static void buildLabelRefCountHash (lineNode * head); +static void bindVar (int key, char **s, hTab ** vtab); static bool matchLine (char *, char *, hTab **); -bool isLabelDefinition (const char *line, const char **start, int *len); -#define FBYNAME(x) int x (hTab *vars, lineNode *currPl, lineNode *endPl, \ +#define FBYNAME(x) static int x (hTab *vars, lineNode *currPl, lineNode *endPl, \ lineNode *head, char *cmdLine) #if !OPT_DISABLE_PIC @@ -69,7 +64,7 @@ void pic16_peepRules2pCode(peepRule *); /* pcDistance - afinds a label back ward or forward */ /*-----------------------------------------------------------------*/ -int +static int pcDistance (lineNode * cpos, char *lbl, bool back) { lineNode *pl = cpos; @@ -81,8 +76,8 @@ pcDistance (lineNode * cpos, char *lbl, bool back) { if (pl->line && - *pl->line != ';' && - pl->line[strlen (pl->line) - 1] != ':' && + !pl->isComment && + !pl->isLabel && !pl->isDebug) { if (port->peep.getSize) { dist += port->peep.getSize(pl); @@ -103,16 +98,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 */ /*-----------------------------------------------------------------*/ @@ -138,10 +123,13 @@ 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 */ @@ -182,7 +170,6 @@ FBYNAME (labelInRange) return TRUE; } - /*-----------------------------------------------------------------*/ /* labelJTInRange - will check to see if label %5 and up are */ /* within range. */ @@ -226,7 +213,6 @@ FBYNAME (labelJTInRange) return TRUE; } - /*-----------------------------------------------------------------*/ /* labelIsReturnOnly - Check if label %5 is followed by RET */ /*-----------------------------------------------------------------*/ @@ -238,38 +224,131 @@ FBYNAME (labelIsReturnOnly) int len; char * retInst; + /* Don't optimize jumps in a jump table; a more generic test */ + if (currPl->ic && currPl->ic->op == JUMPTABLE) + return FALSE; + label = hTabItemWithKey (vars, 5); - if (!label) return FALSE; + if (!label) + return FALSE; len = strlen(label); - for(pl = currPl; pl; pl = pl->next) { - if (pl->line && !pl->isDebug && !pl->isComment && - pl->line[strlen(pl->line)-1] == ':') { - if (strncmp(pl->line, label, len) == 0) break; /* Found Label */ - 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) != '$') { - return FALSE; /* non-local label encountered */ - } + for(pl = currPl; pl; pl = pl->next) + { + if (pl->line && !pl->isDebug && !pl->isComment && pl->isLabel) + { + if (strncmp(pl->line, label, len) == 0) + break; /* Found Label */ + 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) != '$') + { + return FALSE; /* non-local label encountered */ + } } - } - if (!pl) return FALSE; /* did not find the label */ + } + if (!pl) + return FALSE; /* did not find the label */ pl = pl->next; while (pl && (pl->isDebug || pl->isComment)) pl = pl->next; - if (!pl || !pl->line || pl->isDebug) return FALSE; /* next line not valid */ + if (!pl || !pl->line || pl->isDebug) + return FALSE; /* next line not valid */ p = pl->line; for (p = pl->line; *p && ISCHARSPACE(*p); p++) - ; + ; retInst = "ret"; if (TARGET_IS_HC08) retInst = "rts"; - if (strcmp(p, retInst) == 0) return TRUE; + if (strcmp(p, retInst) == 0) + return TRUE; return FALSE; } +/*-----------------------------------------------------------------*/ +/* labelIsUncondJump - Check if label %5 is followed by an */ +/* unconditional jump and put the destination of that jump in %6 */ +/*-----------------------------------------------------------------*/ +FBYNAME (labelIsUncondJump) +{ + /* assumes that %5 pattern variable has the label name */ + const char *label; + char *p, *q; + const lineNode *pl; + int len; + char * jpInst = NULL; + + /* Don't optimize jumps in a jump table; a more generic test */ + if (currPl->ic && currPl->ic->op == JUMPTABLE) + return FALSE; + + label = hTabItemWithKey (vars, 5); + if (!label) + return FALSE; + len = strlen(label); + + for (pl = currPl; pl; pl = pl->next) + { + if (pl->line && !pl->isDebug && !pl->isComment && pl->isLabel) + { + if (strncmp(pl->line, label, len) == 0) + break; /* Found Label */ + 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) != '$') + { + return FALSE; /* non-local label encountered */ + } + } + } + if (!pl) + return FALSE; /* did not find the label */ + pl = pl->next; + while (pl && (pl->isDebug || pl->isComment)) + pl = pl->next; + if (!pl || !pl->line) + return FALSE; /* next line not valid */ + p = pl->line; + while (*p && ISCHARSPACE(*p)) + p++; + + if (TARGET_MCS51_LIKE) + jpInst = "ljmp"; + if (TARGET_IS_HC08) + jpInst = "jmp"; + if (TARGET_Z80_LIKE) + jpInst = "jp"; + len = strlen(jpInst); + if (strncmp(p, jpInst, len) != 0) + return FALSE; /* next line is no jump */ + p += len; + while (*p && ISCHARSPACE(*p)) + p++; + + q = p; + while (*q && *q!=';') + q++; + while (q>p && ISCHARSPACE(*q)) + q--; + len = q-p; + if (len == 0) + return FALSE; /* no destination? */ + if (TARGET_Z80_LIKE) + { + while (q>p && *q!=',') + q--; + 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 */ @@ -306,6 +385,19 @@ FBYNAME (okToRemoveSLOC) return TRUE; /* safe for a peephole to remove it :) */ } +/*-----------------------------------------------------------------*/ +/* deadMove - Check, if a pop/push pair can be removed */ +/*-----------------------------------------------------------------*/ +FBYNAME (deadMove) +{ + const char *reg = hTabItemWithKey (vars, 1); + + if (port->peep.deadMove) + return port->peep.deadMove (reg, currPl, head); + + fprintf (stderr, "Function deadMove not initialized in port structure\n"); + return FALSE; +} /*-----------------------------------------------------------------*/ /* operandsNotSame - check if %1 & %2 are the same */ @@ -417,7 +509,6 @@ FBYNAME (operandsNotSame6) return TRUE; } - /*-----------------------------------------------------------------*/ /* operandsNotSame7- check if any pair of %1,%2,%3,.. are the same */ /*-----------------------------------------------------------------*/ @@ -504,6 +595,34 @@ FBYNAME (operandsNotSame8) return TRUE; } +/*-----------------------------------------------------------------*/ +/* labelHashEntry- searches for a label in the list labelHash */ +/* Builds labelHash, if it does not yet exist. */ +/* Returns the labelHashEntry or NULL */ +/*-----------------------------------------------------------------*/ +labelHashEntry * +getLabelRef (const char *label, lineNode *head) +{ + labelHashEntry *entry; + + /* If we don't have the label hash table yet, build it. */ + if (!labelHash) + { + buildLabelRefCountHash (head); + } + + entry = hTabFirstItemWK (labelHash, hashSymbolName (label)); + + while (entry) + { + if (!strcmp (label, entry->name)) + { + break; + } + entry = hTabNextItemWK (labelHash); + } + return entry; +} /* labelRefCount: @@ -518,30 +637,14 @@ FBYNAME (labelRefCount) int varNumber, expectedRefCount; bool rc = FALSE; - /* If we don't have the label hash table yet, build it. */ - if (!labelHash) - { - buildLabelRefCountHash (head); - } - if (sscanf (cmdLine, "%*[ \t%]%d %d", &varNumber, &expectedRefCount) == 2) { char *label = hTabItemWithKey (vars, varNumber); if (label) { - labelHashEntry *entry; - - entry = hTabFirstItemWK (labelHash, hashSymbolName (label)); + labelHashEntry *entry = getLabelRef (label, head); - while (entry) - { - if (!strcmp (label, entry->name)) - { - break; - } - entry = hTabNextItemWK (labelHash); - } if (entry) { #if 0 @@ -576,7 +679,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. @@ -653,7 +755,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 @@ -718,22 +819,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; + } } } } @@ -832,7 +963,6 @@ FBYNAME (notVolatile) return TRUE; - error: fprintf (stderr, "*** internal error: notVolatile peephole restriction" @@ -840,7 +970,6 @@ error: return FALSE; } - /*------------------------------------------------------------------*/ /* setFromConditionArgs - parse a peephole condition's arguments */ /* to produce a set of strings, one per argument. Variables %x will */ @@ -921,9 +1050,8 @@ operandBaseName (const char *op) return op; } - /*-------------------------------------------------------------------*/ -/* operandsNotRelated - returns true of the condition's operands are */ +/* operandsNotRelated - returns true if the condition's operands are */ /* not related (taking into account register name aliases). N-way */ /* comparison performed between all operands. */ /*-------------------------------------------------------------------*/ @@ -962,94 +1090,122 @@ FBYNAME (operandsNotRelated) return TRUE; } +/*-------------------------------------------------------------------*/ +/* operandsLiteral - returns true of the condition's operands are */ +/* literals. */ +/*-------------------------------------------------------------------*/ +FBYNAME (operandsLiteral) +{ + set *operands; + const char *op; + operands = setFromConditionArgs (cmdLine, vars); + + if (!operands) + { + fprintf (stderr, + "*** internal error: operandsLiteral peephole restriction" + " malformed: %s\n", cmdLine); + return FALSE; + } + + for (op = setFirstItem (operands); op; op = setNextItem (operands)) + { + if (!isdigit(*op)) + { + deleteSet (&operands); + return FALSE; + } + } + + deleteSet (&operands); + 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 + } +}; /*-----------------------------------------------------------------*/ /* callFuncByName - calls a function as defined in the table */ /*-----------------------------------------------------------------*/ -int +static int callFuncByName (char *fname, hTab * vars, lineNode * currPl, lineNode * endPl, 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 - }, - { - "okToRemoveSLOC", okToRemoveSLOC - }, - { - "24bitModeAndPortDS390", flat24bitModeAndPortDS390 - }, - { - "notVolatile", notVolatile - }, - { - "operandsNotRelated", operandsNotRelated - }, - { - "labelRefCountChange", labelRefCountChange - } - }; int i; char *cmdCopy, *funcName, *funcArgs, *cmdTerm; char c; @@ -1108,8 +1264,7 @@ callFuncByName (char *fname, { if (strcmp (ftab[i].fname, funcName) == 0) { - rc = (*ftab[i].func) (vars, currPl, endPl, head, - funcArgs); + rc = (*ftab[i].func) (vars, currPl, endPl, head, funcArgs); break; } } @@ -1137,14 +1292,11 @@ callFuncByName (char *fname, /* printLine - prints a line chain into a given file */ /*-----------------------------------------------------------------*/ void -printLine (lineNode * head, FILE * of) +printLine (lineNode * head, struct dbuf_s * oBuf) { iCode *last_ic = NULL; bool debug_iCode_tracking = (getenv("DEBUG_ICODE_TRACKING")!=NULL); - if (!of) - of = stdout; - while (head) { if (head->ic!=last_ic) @@ -1153,24 +1305,23 @@ printLine (lineNode * head, FILE * of) if (debug_iCode_tracking) { if (head->ic) - fprintf (of, "; block = %d, seq = %d\n", + dbuf_printf (oBuf, "; block = %d, seq = %d\n", head->ic->block, head->ic->seq); else - fprintf (of, "; iCode lost\n"); + dbuf_append_str (oBuf, "; iCode lost\n"); } } /* don't indent comments & labels */ if (head->line && - (*head->line == ';' || - head->line[strlen (head->line) - 1] == ':')) { - fprintf (of, "%s\n", head->line); + (head->isComment || head->isLabel)) { + dbuf_printf (oBuf, "%s\n", head->line); } else { if (head->isInline && *head->line=='#') { // comment out preprocessor directives in inline asm - fprintf (of, ";"); + dbuf_append_char (oBuf, ';'); } - fprintf (of, "\t%s\n", head->line); + dbuf_printf (oBuf, "\t%s\n", head->line); } head = head->next; } @@ -1179,7 +1330,7 @@ printLine (lineNode * head, FILE * of) /*-----------------------------------------------------------------*/ /* newPeepRule - creates a new peeprule and attach it to the root */ /*-----------------------------------------------------------------*/ -peepRule * +static peepRule * newPeepRule (lineNode * match, lineNode * replace, char *cond, @@ -1214,7 +1365,7 @@ newPeepRule (lineNode * match, /* newLineNode - creates a new peep line */ /*-----------------------------------------------------------------*/ lineNode * -newLineNode (char *line) +newLineNode (const char *line) { lineNode *pl; @@ -1298,11 +1449,16 @@ getPeepLine (lineNode ** head, char **bpp) if (!isComment || (isComment && !options.noPeepComments)) { + const char *dummy1; + int dummy2; + if (!currL) *head = currL = newLineNode (lines); else currL = connectLine (currL, newLineNode (lines)); currL->isComment = isComment; + currL->isLabel = isLabelDefinition (currL->line, &dummy1, &dummy2, + TRUE); } } @@ -1318,7 +1474,7 @@ readRules (char *bp) { char restart = 0; char lines[MAX_PATTERN_LEN]; - char *lp; + char *lp, *rp; lineNode *match; lineNode *replace; lineNode *currL = NULL; @@ -1374,6 +1530,9 @@ top: EXPECT_CHR (bp, '{', "expected '{'\n"); bp++; + /* save char position (needed for generating error msg) */ + rp = bp; + SKIP_SPACE (bp, "unexpected end of rule\n"); getPeepLine (&replace, &bp); @@ -1403,7 +1562,33 @@ top: newPeepRule (match, replace, lines, restart); } else - newPeepRule (match, replace, NULL, restart); + { + 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))) + *cp++ = *rp++; + + /* and now the rest of the line */ + while (*rp && (*rp != '\n') && ((cp - strbuff) < sizeof(strbuff))) + *cp++ = *rp++; + + *cp = '\0'; + fprintf (stderr, "%s\nexpected '} if ...'\n", strbuff); + return; + } + newPeepRule (match, replace, NULL, restart); + } goto top; } @@ -1504,8 +1689,7 @@ matchLine (char *s, char *d, hTab ** vars) return FALSE; } else - /* variable not bound we need to - bind it */ + /* variable not bound we need to bind it */ bindVar (keyForVar (d + 1), &s, vars); /* in either case go past the variable */ @@ -1751,16 +1935,13 @@ reassociate_ic (lineNode *shead, lineNode *stail, csl = shead; while (1) { - const char *labelStart; - int labelLength; - /* skip over any comments */ while (csl!=stail->next && csl->isComment) csl = csl->next; if (csl==stail->next) break; - if (isLabelDefinition(csl->line, &labelStart, &labelLength)) + if (csl->isLabel) { /* found a source line label; look for it in the replacment lines */ crl = rhead; @@ -1862,6 +2043,7 @@ replaceRule (lineNode ** shead, lineNode * stail, peepRule * pr) else lhead = cl = newLineNode (lb); cl->isComment = pl->isComment; + cl->isLabel = pl->isLabel; } /* add the comments if any to the head of list */ @@ -1914,7 +2096,8 @@ replaceRule (lineNode ** shead, lineNode * stail, peepRule * pr) * and len will be it's length. */ bool -isLabelDefinition (const char *line, const char **start, int *len) +isLabelDefinition (const char *line, const char **start, int *len, + bool isPeepRule) { const char *cp = line; @@ -1935,7 +2118,8 @@ isLabelDefinition (const char *line, const char **start, int *len) *start = cp; - while (ISCHARALNUM (*cp) || (*cp == '$') || (*cp == '_')) + while (ISCHARALNUM (*cp) || (*cp == '$') || (*cp == '_') || + (isPeepRule && (*cp == '%'))) { cp++; } @@ -1984,30 +2168,35 @@ buildLabelRefCountHash (lineNode * head) labelHash = newHashTable (HTAB_SIZE); /* First pass: locate all the labels. */ - line = head; - - while (line) + for (line = head; line; line = line->next) { - if (isLabelDefinition (line->line, &label, &labelLen) - && labelLen <= SDCC_NAME_MAX) + if (line->isLabel || + line->isInline) { - labelHashEntry *entry; + /* run isLabelDefinition to: + - look for labels in inline assembler + - calculate labelLen + */ + if (isLabelDefinition (line->line, &label, &labelLen, FALSE) && + labelLen <= SDCC_NAME_MAX) + { + labelHashEntry *entry; - entry = traceAlloc (&_G.labels, Safe_alloc(sizeof (labelHashEntry))); + entry = traceAlloc (&_G.labels, Safe_alloc(sizeof (labelHashEntry))); - memcpy (entry->name, label, labelLen); - entry->name[labelLen] = 0; - entry->refCount = -1; + memcpy (entry->name, label, labelLen); + entry->name[labelLen] = 0; + entry->refCount = -1; - /* Assume function entry points are referenced somewhere, */ - /* even if we can't find a reference (might be from outside */ - /* the function) */ - if (line->ic && (line->ic->op == FUNCTION)) - entry->refCount++; + /* Assume function entry points are referenced somewhere, */ + /* even if we can't find a reference (might be from outside */ + /* the function) */ + if (line->ic && (line->ic->op == FUNCTION)) + entry->refCount++; - hTabAddItem (&labelHash, hashSymbolName (entry->name), entry); + hTabAddItem (&labelHash, hashSymbolName (entry->name), entry); + } } - line = line->next; } @@ -2076,7 +2265,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" */ @@ -2093,8 +2282,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; @@ -2111,10 +2302,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); @@ -2214,13 +2410,18 @@ initPeepHole () char *s; /* read in the default rules */ - readRules (port->peep.default_rules); + if (!options.nopeep) + { + readRules (port->peep.default_rules); + } /* if we have any additional file read it too */ if (options.peep_file) { readRules (s = readFileIntoBuffer (options.peep_file)); setToNull ((void *) &s); + /* override nopeep setting, default rules have not been read */ + options.nopeep = 0; }