X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2FSDCClabel.c;h=ba78d47900ceb109c9715d9eada48410e88a2440;hb=HEAD;hp=d579fe9a18413daeb2863223e359ce9adc6a5021;hpb=958a651d053c089412d87ab75101812383d03f19;p=fw%2Fsdcc diff --git a/src/SDCClabel.c b/src/SDCClabel.c index d579fe9a..ba78d479 100644 --- a/src/SDCClabel.c +++ b/src/SDCClabel.c @@ -24,409 +24,451 @@ #include "common.h" -hTab *labelRef = NULL ; -hTab *labelDef = NULL ; +hTab *labelRef = NULL; +hTab *labelDef = NULL; /*-----------------------------------------------------------------*/ -/* buildLabelRefTable - creates an hashTable of label referneces */ +/* buildLabelRefTable - creates an hashTable of label references */ /*-----------------------------------------------------------------*/ -void buildLabelRefTable (iCode *ic) +void +buildLabelRefTable (iCode * ic) { - iCode *lic; - - setToNull ((void **)&labelRef); - setToNull ((void **)&labelDef); - labelRef = newHashTable(labelKey + 1); - labelDef = newHashTable(labelKey + 1); - - for (lic = ic ; lic ; lic = lic->next ) { - if ( lic->op == GOTO ) - hTabAddItem (&labelRef, (IC_LABEL(lic))->key, lic); - - if ( lic->op == JUMPTABLE ) { - symbol *lbl ; - for (lbl = setFirstItem(IC_JTLABELS(lic)); lbl; - lbl = setNextItem(IC_JTLABELS(lic))) { - hTabAddItem(&labelRef,lbl->key,lic); + iCode *lic; + + setToNull ((void *) &labelRef); + setToNull ((void *) &labelDef); + labelRef = newHashTable (labelKey + 1); + labelDef = newHashTable (labelKey + 1); + + for (lic = ic; lic; lic = lic->next) + { + if (lic->op == GOTO) + hTabAddItem (&labelRef, (IC_LABEL (lic))->key, lic); + + if (lic->op == JUMPTABLE) + { + symbol *lbl; + for (lbl = setFirstItem (IC_JTLABELS (lic)); lbl; + lbl = setNextItem (IC_JTLABELS (lic))) + { + hTabAddItem (&labelRef, lbl->key, lic); } } - - if (lic->op == IFX ) { - if (IC_TRUE(lic)) - hTabAddItem(&labelRef,(IC_TRUE(lic))->key, lic); - else - hTabAddItem(&labelRef,(IC_FALSE(lic))->key, lic); + + if (lic->op == IFX) + { + if (IC_TRUE (lic)) + hTabAddItem (&labelRef, (IC_TRUE (lic))->key, lic); + else + hTabAddItem (&labelRef, (IC_FALSE (lic))->key, lic); } - if ( lic->op == LABEL ) - hTabAddItem (&labelDef,(IC_LABEL(lic))->key, lic); - + if (lic->op == LABEL) + hTabAddItem (&labelDef, (IC_LABEL (lic))->key, lic); + } } /*-----------------------------------------------------------------*/ /* labelGotoNext - kills gotos to next statement */ /*-----------------------------------------------------------------*/ -int labelGotoNext (iCode *ic) +int +labelGotoNext (iCode * ic) { - iCode *loop; - int change = 0 ; - - for ( loop = ic ; loop ; loop = loop->next) { - - if (loop->op == GOTO && /* if this is a goto */ - loop->next && /* and we have a next one */ - loop->next->op == LABEL && /* next one is a label */ - loop->next->argLabel.label->key == loop->argLabel.label->key) /* same label */ - { - loop->prev->next = loop->next ; /* get this out of the chain */ - loop->next->prev = loop->prev ; - hTabDeleteItem (&labelRef,(IC_LABEL(loop))->key, loop, DELETE_ITEM, NULL); - change++ ; - } + iCode *loop; + int change = 0; + + for (loop = ic; loop; loop = loop->next) + { + + if (loop->op == GOTO && /* if this is a goto */ + loop->next && /* and we have a next one */ + loop->next->op == LABEL && /* next one is a label */ + loop->next->label->key == loop->label->key) /* same label */ + { + loop->prev->next = loop->next; /* get this out of the chain */ + loop->next->prev = loop->prev; + hTabDeleteItem (&labelRef, (IC_LABEL (loop))->key, loop, DELETE_ITEM, NULL); + change++; + } } - return change ; + return change; } +/*-------------------------------------------------------------------*/ +/* deleteIfx - delete an IFX iCode or convert to DUMMY_READ_VOLATILE */ +/*-------------------------------------------------------------------*/ +static void +deleteIfx (iCode * loop, int key) +{ + if (!options.lessPedantic) + { + werrorfl (loop->filename, loop->lineno, W_CONTROL_FLOW); + } + hTabDeleteItem (&labelRef, key, loop, DELETE_ITEM, NULL); + + /* If the condition was volatile, convert IFX to */ + /* DUMMY_READ_VOLATILE. Otherwise just delete the */ + /* IFX iCode */ + if (IS_OP_VOLATILE (IC_COND (loop))) + { + IC_RIGHT (loop) = IC_COND (loop); + IC_LEFT (loop) = NULL; + IC_RESULT (loop) = NULL; + loop->op = DUMMY_READ_VOLATILE; + } + else + { + loop->prev->next = loop->next; + loop->next->prev = loop->prev; + } +} + + /*-----------------------------------------------------------------*/ /* labelIfx - special case Ifx elimination */ /*-----------------------------------------------------------------*/ -int labelIfx ( iCode *ic) +int +labelIfx (iCode * ic) { - iCode *loop ; - int change = 0; - - - for ( loop = ic ; loop ; loop = loop->next ) { - /* if condition goto label */ - /* goto label */ - /* i.e. the flow is going to the same location - regardless of the condition in this case the - condition can be eliminated with a WARNING ofcource */ - if ( loop->op == IFX && - loop->next && - loop->next->op == GOTO ) { - if (IC_TRUE(loop) && - IC_TRUE(loop)->key == IC_LABEL(loop->next)->key) { - - /* get rid of this if */ - werror(W_CONTROL_FLOW,loop->filename,loop->lineno); - loop->prev->next = loop->next; - loop->next->prev = loop->prev; - hTabDeleteItem(&labelRef, - (IC_TRUE(loop))->key, - loop, DELETE_ITEM,NULL); - change++ ; - continue ; + iCode *loop; + int change = 0; + + + for (loop = ic; loop; loop = loop->next) + { + /* if condition goto label */ + /* goto label */ + /* i.e. the flow is going to the same location + regardless of the condition in this case the + condition can be eliminated with a WARNING ofcource */ + if (loop->op == IFX && + loop->next && + loop->next->op == GOTO) + { + if (IC_TRUE (loop) && + IC_TRUE (loop)->key == IC_LABEL (loop->next)->key) + { + deleteIfx (loop, IC_TRUE (loop)->key); + change++; + continue; } - else { - if (IC_FALSE(loop) && - IC_FALSE(loop)->key == IC_LABEL(loop->next)->key){ - /* get rid of this if */ - werror(W_CONTROL_FLOW,loop->filename,loop->lineno); - loop->prev->next = loop->next; - loop->next->prev = loop->prev; - hTabDeleteItem(&labelRef, - (IC_FALSE(loop))->key, - loop, DELETE_ITEM,NULL); - change++; - continue ; - } + else + { + if (IC_FALSE (loop) && + IC_FALSE (loop)->key == IC_LABEL (loop->next)->key) + { + deleteIfx (loop, IC_FALSE (loop)->key); + change++; + continue; + } } } - /* same as above but with a twist */ - /* if condition goto label */ - /* label: */ - if (loop->op == IFX && - loop->next && - loop->next->op == LABEL && - ((IC_TRUE(loop) && IC_TRUE(loop)->key == IC_LABEL(loop->next)->key) || - (IC_FALSE(loop) && IC_FALSE(loop)->key == IC_LABEL(loop->next)->key))) { - - werror(W_CONTROL_FLOW,loop->filename,loop->lineno); - loop->prev->next = loop->next; - loop->next->prev = loop->prev; - hTabDeleteItem(&labelRef, - IC_LABEL(loop->next)->key, - loop, DELETE_ITEM,NULL); - change++; - continue ; + /* same as above but with a twist */ + /* if condition goto label */ + /* label: */ + if (loop->op == IFX && + loop->next && + loop->next->op == LABEL && + ((IC_TRUE (loop) && IC_TRUE (loop)->key == IC_LABEL (loop->next)->key) || + (IC_FALSE (loop) && IC_FALSE (loop)->key == IC_LABEL (loop->next)->key))) + { + deleteIfx (loop, IC_LABEL (loop->next)->key); + change++; + continue; } - - /* we will eliminate certain special case situations*/ - /* of the conditional statement :- */ - /* if cond != 0 goto _trueLabel */ - /* goto _falseLabel */ - /* _trueLabel : */ - /* ... */ - /* in these cases , if this is the only reference */ - /* to the _trueLabel, we can change it to :- */ - /* if cond == 0 goto _falseLabel */ - /* ... */ - /* similarly if we have a situation like :- */ - /* if cond == 0 goto _falseLabel */ - /* goto _someLabel */ - /* _falseLabel : */ - /* we can change this to */ - /* if cond != 0 goto _someLabel */ - /* ... */ - if (loop->op == IFX && - loop->next && - loop->next->op == GOTO && - loop->next->next && - loop->next->next->op == LABEL ) { - - - /* now check that the last label is the */ - /* same as the _trueLabel of this */ - if (IC_TRUE(loop)) - if ( (IC_TRUE(loop))->key != (IC_LABEL(loop->next->next))->key ) - continue ; - else ; - else - if ( (IC_FALSE(loop))->key != (IC_LABEL(loop->next->next))->key ) - continue; - - /* now make sure that this is the only */ - /* referenece to the _trueLabel */ - if ( IC_TRUE(loop) && hTabItemWithKey(labelRef,(IC_TRUE(loop))->key) ) { - - /* we just change the falseLabel */ - /* to the next goto statement */ - /* unreferenced label will take */ - /* care of removing the label */ - /* delete reference to the true label */ - - hTabDeleteItem(&labelRef, (IC_TRUE(loop))->key, loop, DELETE_ITEM,NULL); - IC_TRUE(loop) = NULL ; - IC_FALSE(loop) = IC_LABEL(loop->next); - /* add reference to the LABEL */ - hTabAddItem (&labelRef,(IC_FALSE(loop))->key,loop); - /* next remove the goto */ - hTabDeleteItem(&labelRef, - (IC_LABEL(loop->next))->key,loop->next,DELETE_ITEM,NULL); - loop->next = loop->next->next ; - loop->next->prev = loop ; - change++; - continue ; + + /* we will eliminate certain special case situations */ + /* of the conditional statement :- */ + /* if cond != 0 goto _trueLabel */ + /* goto _falseLabel */ + /* _trueLabel : */ + /* ... */ + /* in these cases , if this is the only reference */ + /* to the _trueLabel, we can change it to :- */ + /* if cond == 0 goto _falseLabel */ + /* ... */ + /* similarly if we have a situation like :- */ + /* if cond == 0 goto _falseLabel */ + /* goto _someLabel */ + /* _falseLabel : */ + /* we can change this to */ + /* if cond != 0 goto _someLabel */ + /* ... */ + if (loop->op == IFX && + loop->next && + loop->next->op == GOTO && + loop->next->next && + loop->next->next->op == LABEL) + { + + + /* now check that the last label is the */ + /* same as the _trueLabel of this */ + if (IC_TRUE (loop)) + if ((IC_TRUE (loop))->key != (IC_LABEL (loop->next->next))->key) + continue; + else; + else if ((IC_FALSE (loop))->key != (IC_LABEL (loop->next->next))->key) + continue; + + /* now make sure that this is the only */ + /* referenece to the _trueLabel */ + if (IC_TRUE (loop) && hTabItemWithKey (labelRef, (IC_TRUE (loop))->key)) + { + + /* we just change the falseLabel */ + /* to the next goto statement */ + /* unreferenced label will take */ + /* care of removing the label */ + /* delete reference to the true label */ + + hTabDeleteItem (&labelRef, (IC_TRUE (loop))->key, loop, DELETE_ITEM, NULL); + IC_TRUE (loop) = NULL; + IC_FALSE (loop) = IC_LABEL (loop->next); + /* add reference to the LABEL */ + hTabAddItem (&labelRef, (IC_FALSE (loop))->key, loop); + /* next remove the goto */ + hTabDeleteItem (&labelRef, + (IC_LABEL (loop->next))->key, loop->next, DELETE_ITEM, NULL); + loop->next = loop->next->next; + loop->next->prev = loop; + change++; + continue; + } + + /* now do the same with the false labels */ + if (IC_FALSE (loop) && + hTabItemWithKey (labelRef, (IC_FALSE (loop))->key)) + { + + hTabDeleteItem (&labelRef, (IC_FALSE (loop))->key, loop, DELETE_ITEM, NULL); + IC_FALSE (loop) = NULL; + IC_TRUE (loop) = IC_LABEL (loop->next); + hTabAddItem (&labelRef, (IC_TRUE (loop))->key, loop); + hTabDeleteItem (&labelRef, (IC_LABEL (loop->next))->key, loop->next, DELETE_ITEM, NULL); + loop->next = loop->next->next; + loop->next->prev = loop; + change++; + continue; } - - /* now do the same with the false labels */ - if (IC_FALSE(loop) && - hTabItemWithKey(labelRef,(IC_FALSE(loop))->key)) { - - hTabDeleteItem(&labelRef, (IC_FALSE(loop))->key, loop, DELETE_ITEM,NULL); - IC_FALSE(loop) = NULL ; - IC_TRUE(loop) = IC_LABEL(loop->next); - hTabAddItem (&labelRef,(IC_TRUE(loop))->key,loop); - hTabDeleteItem(&labelRef,(IC_LABEL(loop->next))->key,loop->next,DELETE_ITEM,NULL); - loop->next = loop->next->next ; - loop->next->prev = loop ; - change++; - continue ; - } } } - return change ; + return change; } /*-----------------------------------------------------------------*/ /* labelGotoGoto - target of a goto is a goto */ /*-----------------------------------------------------------------*/ -int labelGotoGoto (iCode *ic) +int +labelGotoGoto (iCode * ic) { - iCode *loop; - int change = 0 ; - - for ( loop = ic ; loop ; loop = loop->next ) { - iCode *stat ; - symbol *sLabel = NULL; - stat = NULL ; - switch (loop->op) { - case GOTO: /* for a goto statement */ - stat = hTabItemWithKey(labelDef,(sLabel = IC_LABEL(loop))->key) ; - break ; - case IFX : /* for a conditional jump */ - if (IC_TRUE(loop)) - stat = hTabItemWithKey(labelDef,(sLabel = IC_TRUE(loop))->key); - else - stat = hTabItemWithKey (labelDef,(sLabel = IC_FALSE(loop))->key); + iCode *loop; + int change = 0; + + for (loop = ic; loop; loop = loop->next) + { + iCode *stat; + symbol *sLabel = NULL; + stat = NULL; + switch (loop->op) + { + case GOTO: /* for a goto statement */ + stat = hTabItemWithKey (labelDef, (sLabel = IC_LABEL (loop))->key); + break; + case IFX: /* for a conditional jump */ + if (IC_TRUE (loop)) + stat = hTabItemWithKey (labelDef, (sLabel = IC_TRUE (loop))->key); + else + stat = hTabItemWithKey (labelDef, (sLabel = IC_FALSE (loop))->key); } - - /* if we have a target statement then check if the next */ - /* one is a goto: this means target of goto is a goto */ - if ( stat && stat->next && - ( stat->next->op == GOTO || - stat->next->op == LABEL) && - stat->next != loop ) { - - symbol *repLabel = stat->next->argLabel.label ; /* replace with label */ - - /* if they are the same then continue */ - if (repLabel->key == sLabel->key) - continue ; - - /* replacement depends on the statement type */ - switch (loop->op) { - - case GOTO: /* for a goto statement */ - - hTabDeleteItem (&labelRef, (IC_LABEL(loop))->key, loop,DELETE_ITEM,NULL); - loop->argLabel.label = repLabel ; - hTabAddItem (&labelRef, repLabel->key, loop); - break ; - - case IFX : /* for a conditional jump */ - if (IC_TRUE(loop)) { - - hTabDeleteItem (&labelRef, (IC_TRUE(loop))->key, loop,DELETE_ITEM,NULL); - IC_TRUE(loop) = repLabel ; - } - else { - - hTabDeleteItem (&labelRef, (IC_FALSE(loop))->key, loop,DELETE_ITEM,NULL); - IC_FALSE(loop) = repLabel; + + /* if we have a target statement then check if the next */ + /* one is a goto: this means target of goto is a goto */ + if (stat && stat->next && + (stat->next->op == GOTO || + stat->next->op == LABEL) && + stat->next != loop) + { + + symbol *repLabel = stat->next->label; /* replace with label */ + + /* if they are the same then continue */ + if (repLabel->key == sLabel->key) + continue; + + /* replacement depends on the statement type */ + switch (loop->op) + { + + case GOTO: /* for a goto statement */ + + hTabDeleteItem (&labelRef, (IC_LABEL (loop))->key, loop, DELETE_ITEM, NULL); + loop->label = repLabel; + hTabAddItem (&labelRef, repLabel->key, loop); + break; + + case IFX: /* for a conditional jump */ + if (IC_TRUE (loop)) + { + + hTabDeleteItem (&labelRef, (IC_TRUE (loop))->key, loop, DELETE_ITEM, NULL); + IC_TRUE (loop) = repLabel; + } + else + { + + hTabDeleteItem (&labelRef, (IC_FALSE (loop))->key, loop, DELETE_ITEM, NULL); + IC_FALSE (loop) = repLabel; } - hTabAddItem (&labelRef, repLabel->key, loop); - + hTabAddItem (&labelRef, repLabel->key, loop); + } - change++ ; + change++; } } - - return change ; + + return change; } /*-----------------------------------------------------------------*/ -/* labelUnrefLabel - remove unreferneced labels */ +/* labelUnrefLabel - remove unreferenced labels */ /*-----------------------------------------------------------------*/ -int labelUnrefLabel (iCode *ic) +int +labelUnrefLabel (iCode * ic) { - iCode *loop; - int change = 0 ; - - for ( loop = ic ; loop ; loop = loop->next) { - - /* if this is a label */ - if (loop->op == LABEL) { - set *refs ; - - refs = NULL ; - if ( ( (IC_LABEL(loop))->key == returnLabel->key ) || - ( (IC_LABEL(loop))->key == entryLabel->key ) ) - continue ; - - if (hTabItemWithKey(labelRef,(IC_LABEL(loop))->key) ) - continue ; - - /* else eliminitate this one */ - loop->prev->next = loop->next ; /* get this out of the chain */ - loop->next->prev = loop->prev ; - change ++ ; + iCode *loop; + int change = 0; + + for (loop = ic; loop; loop = loop->next) + { + + /* if this is a label */ + if (loop->op == LABEL) + { + if (((IC_LABEL (loop))->key == returnLabel->key) || + ((IC_LABEL (loop))->key == entryLabel->key)) + continue; + + if (hTabItemWithKey (labelRef, (IC_LABEL (loop))->key)) + continue; + + /* else eliminitate this one */ + loop->prev->next = loop->next; /* get this out of the chain */ + loop->next->prev = loop->prev; + change++; } } - return change ; + return change; } /*-----------------------------------------------------------------*/ /* labelUnreach - remove unreachable code */ /*-----------------------------------------------------------------*/ -int labelUnreach (iCode *ic) +int +labelUnreach (iCode * ic) { - iCode *loop; - iCode *tic; - int change = 0 ; - - /* if we hit a return statement or a goto statement */ - /* remove all statements till we hit the next label */ - for (loop = ic ; loop ; loop = loop->next) { - iCode *loop2 ; - - /* found a goto || return && the next */ - /* statement is not a label */ - if (loop->op == GOTO || loop->op == RETURN ) { - - if (loop->next && - (loop->next->op == LABEL || - loop->next->op == ENDFUNCTION )) - continue ; - - /* loop till we find a label */ - loop2 = loop->next ; - while (loop2 && loop2->op != LABEL) - loop2 = loop2->next; - - /* throw away those in between */ - for (tic = loop->next ; tic && tic != loop2 ; tic=tic->next) { - /* remove label references if any */ - switch (tic->op) { - case GOTO : - hTabDeleteItem (&labelRef,IC_LABEL(tic)->key,tic,DELETE_ITEM,NULL); - break; - case IFX : - if (IC_TRUE(tic)) - hTabDeleteItem (&labelRef,IC_TRUE(tic)->key,tic,DELETE_ITEM,NULL); - else - hTabDeleteItem (&labelRef,IC_FALSE(tic)->key,tic,DELETE_ITEM,NULL); - break; - - } + iCode *loop; + iCode *tic; + int change = 0; + + /* if we hit a return statement or a goto statement */ + /* remove all statements till we hit the next label */ + for (loop = ic; loop; loop = loop->next) + { + iCode *loop2; + + /* found a goto || return && the next */ + /* statement is not a label */ + if (loop->op == GOTO || loop->op == RETURN) + { + if (loop->next && + (loop->next->op == LABEL || + loop->next->op == ENDFUNCTION)) + continue; + + /* loop till we find a label */ + loop2 = loop->next; + while (loop2 && loop2->op != LABEL) + loop2 = loop2->next; + + /* throw away those in between */ + for (tic = loop->next; tic && tic != loop2; tic = tic->next) + { + /* remove label references if any */ + switch (tic->op) + { + case GOTO: + hTabDeleteItem (&labelRef, IC_LABEL (tic)->key, tic, DELETE_ITEM, NULL); + break; + case IFX: + werrorfl (tic->filename, tic->lineno, W_CODE_UNREACH); + if (IC_TRUE (tic)) + hTabDeleteItem (&labelRef, IC_TRUE (tic)->key, tic, DELETE_ITEM, NULL); + else + hTabDeleteItem (&labelRef, IC_FALSE (tic)->key, tic, DELETE_ITEM, NULL); + break; + default: + werrorfl (tic->filename, tic->lineno, W_CODE_UNREACH); + } } - /* now set up the pointers */ - loop->next = loop2; - if (loop2) - loop2->prev = loop ; - change++; + /* now set up the pointers */ + loop->next = loop2; + if (loop2) + loop2->prev = loop; + change++; } } - return change ; + return change; } /*-----------------------------------------------------------------*/ /* iCodeLabelOptimize - some obvious & general optimizations */ /*-----------------------------------------------------------------*/ -iCode *iCodeLabelOptimize (iCode *ic) -{ - if (!optimize.label1 && - !optimize.label2 && - !optimize.label3 && - !optimize.label4 ) - return ic; - - /* build labelreferences */ - buildLabelRefTable (ic); - - /* the following transformations need to ne done */ - /* repeatedly till a fixed point is reached */ - while (1) { - int change ; - change = 0 ; - - /* first eliminate any goto statement */ - /* that goes to the next statement */ - if (optimize.label1) - change += labelGotoNext (ic); - - if ( optimize.label2 ) - change += labelIfx (ic); - - /* target of a goto is a goto then rename this goto */ - if (optimize.label3 ) - change += labelGotoGoto (ic); - - /* remove unreference labels */ - if (optimize.label4) - change += labelUnrefLabel (ic); - - /* remove unreachable code */ - change += labelUnreach (ic); - - if (!change) /* fixed point reached */ - break; - } - +iCode * +iCodeLabelOptimize (iCode * ic) +{ + if (!optimize.label1 && + !optimize.label2 && + !optimize.label3 && + !optimize.label4) return ic; + + /* build labelreferences */ + buildLabelRefTable (ic); + + /* the following transformations need to ne done */ + /* repeatedly till a fixed point is reached */ + while (1) + { + int change; + change = 0; + + /* first eliminate any goto statement */ + /* that goes to the next statement */ + if (optimize.label1) + change += labelGotoNext (ic); + + if (optimize.label2) + change += labelIfx (ic); + + /* target of a goto is a goto then rename this goto */ + if (optimize.label3) + change += labelGotoGoto (ic); + + /* remove unreference labels */ + if (optimize.label4) + change += labelUnrefLabel (ic); + + /* remove unreachable code */ + change += labelUnreach (ic); + + if (!change) /* fixed point reached */ + break; + } + + return ic; }