X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCCpeeph.c;h=c5534bc2ed69466b94901c1971551695d90bb7bd;hb=07a1703a01eefbf8c73f4fed0879b3fcc184649f;hp=ed9e4bdfabb86db89a82dc774bb4378841eb14b7;hpb=07cbddd43b4358d9f193bdccc860d7563e2aab93;p=fw%2Fsdcc diff --git a/src/SDCCpeeph.c b/src/SDCCpeeph.c index ed9e4bdf..c5534bc2 100644 --- a/src/SDCCpeeph.c +++ b/src/SDCCpeeph.c @@ -178,6 +178,51 @@ FBYNAME (labelInRange) return TRUE; } + +/*-----------------------------------------------------------------*/ +/* labelJTInRange - will check to see if label %5 and up are */ +/* within range. */ +/* Specifically meant to optimize long (3-byte) jumps to short */ +/* (2-byte) jumps in jumptables */ +/*-----------------------------------------------------------------*/ +FBYNAME (labelJTInRange) +{ + char *lbl; + int dist, count, i; + + if (!getenv("SDCC_SJMP_JUMPTABLE")) + return FALSE; + + /* Only optimize within a jump table */ + if (currPl->ic && currPl->ic->op != JUMPTABLE) + return FALSE; + + count = elementsInSet( IC_JTLABELS (currPl->ic) ); + + /* check all labels (this is needed if the case statements are unsorted) */ + for (i=0; i 127+ /* range of sjmp */ + (7+3*i)+ /* offset between this jump and currPl, + should use pcDistance instead? */ + (count-i-1) /* if peephole applies distance is shortened */ + ) + return FALSE; + } + return TRUE; +} + + /*-----------------------------------------------------------------*/ /* labelIsReturnOnly - Check if label %5 is followed by RET */ /*-----------------------------------------------------------------*/ @@ -187,13 +232,14 @@ FBYNAME (labelIsReturnOnly) const char *label, *p; const lineNode *pl; int len; + char * retInst; label = hTabItemWithKey (vars, 5); if (!label) return FALSE; len = strlen(label); for(pl = currPl; pl; pl = pl->next) { - if (pl->line && !pl->isDebug && + 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 || !isdigit(*(pl->line)) || @@ -206,11 +252,17 @@ FBYNAME (labelIsReturnOnly) } 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 */ p = pl->line; for (p = pl->line; *p && isspace(*p); p++) ; - if (strcmp(p, "ret") == 0) return TRUE; + + retInst = "ret"; + if (TARGET_IS_HC08) + retInst = "rts"; + if (strcmp(p, retInst) == 0) return TRUE; return FALSE; } @@ -728,6 +780,10 @@ callFuncByName (char *fname, "labelInRange", labelInRange } , + { + "labelJTInRange", labelJTInRange + } + , { "operandsNotSame", operandsNotSame } @@ -945,6 +1001,7 @@ getPeepLine (lineNode ** head, char **bpp) { char lines[MAX_PATTERN_LEN]; char *lp; + int isComment; lineNode *currL = NULL; char *bp = *bpp; @@ -975,18 +1032,22 @@ getPeepLine (lineNode ** head, char **bpp) lp = lines; while ((*bp != '\n' && *bp != '}') && *bp) *lp++ = *bp++; - *lp = '\0'; - if (!currL) - *head = currL = newLineNode (lines); - else - currL = connectLine (currL, newLineNode (lines)); - + lp = lines; while (*lp && isspace(*lp)) lp++; - if (*lp==';') - currL->isComment = 1; + isComment = (*lp == ';'); + + if (!isComment || (isComment && !options.noPeepComments)) + { + if (!currL) + *head = currL = newLineNode (lines); + else + currL = connectLine (currL, newLineNode (lines)); + currL->isComment = isComment; + } + } *bpp = bp; @@ -1558,23 +1619,35 @@ replaceRule (lineNode ** shead, lineNode * stail, peepRule * pr) lhead = comment; } - /* determine which iCodes the replacment lines relate to */ - reassociate_ic(*shead,stail,lhead,cl); - - /* now we need to connect / replace the original chain */ - /* if there is a prev then change it */ - if ((*shead)->prev) + if (lhead) { - (*shead)->prev->next = lhead; - lhead->prev = (*shead)->prev; + /* determine which iCodes the replacment lines relate to */ + reassociate_ic(*shead,stail,lhead,cl); + + /* now we need to connect / replace the original chain */ + /* if there is a prev then change it */ + if ((*shead)->prev) + { + (*shead)->prev->next = lhead; + lhead->prev = (*shead)->prev; + } + *shead = lhead; + /* now for the tail */ + if (stail && stail->next) + { + stail->next->prev = cl; + if (cl) + cl->next = stail->next; + } } - *shead = lhead; - /* now for the tail */ - if (stail && stail->next) + else { - stail->next->prev = cl; - if (cl) - cl->next = stail->next; + /* the replacement is empty - delete the source lines */ + if ((*shead)->prev) + (*shead)->prev->next = stail->next; + if (stail->next) + stail->next->prev = (*shead)->prev; + *shead = stail->next; } } @@ -1668,6 +1741,12 @@ buildLabelRefCountHash (lineNode * head) 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++; hTabAddItem (&labelHash, hashSymbolName (entry->name), entry); }