/*-----------------------------------------------------------------*/ void replaceLabel (eBBlock * ebp, symbol * fromLbl, symbol * toLbl) { iCode *ic; if (!ebp) return; for (ic = ebp->sch; ic; ic = ic->next) { switch (ic->op) { case GOTO: if (isSymbolEqual (IC_LABEL (ic), fromLbl)) IC_LABEL (ic) = toLbl; break; case IFX: if (IC_TRUE (ic) && isSymbolEqual (IC_TRUE (ic), fromLbl)) IC_TRUE (ic) = toLbl; else if (isSymbolEqual (IC_FALSE (ic), fromLbl)) IC_FALSE (ic) = toLbl; break; } } return; }
static void visit (set **visited, iCode *ic, const int key) { symbol *lbl; while (ic && !isinSet (*visited, ic) && bitVectBitValue (ic->rlive, key)) { addSet (visited, ic); switch (ic->op) { case GOTO: ic = hTabItemWithKey (labelDef, (IC_LABEL (ic))->key); break; case RETURN: ic = hTabItemWithKey (labelDef, returnLabel->key); break; case JUMPTABLE: for (lbl = setFirstItem (IC_JTLABELS (ic)); lbl; lbl = setNextItem (IC_JTLABELS (ic))) visit (visited, hTabItemWithKey (labelDef, lbl->key), key); break; case IFX: visit (visited, hTabItemWithKey (labelDef, (IC_TRUE(ic) ? IC_TRUE (ic) : IC_FALSE (ic))->key), key); ic = ic->next; break; default: ic = ic->next; if (!POINTER_SET (ic) && IC_RESULT (ic) && IS_SYMOP (IC_RESULT (ic)) && OP_SYMBOL_CONST (IC_RESULT (ic))->key == key) { addSet (visited, ic); return; } } } }
/*-----------------------------------------------------------------*/ ebbIndex * iCodeBreakDown (iCode * ic) { eBBlock **ebbs = NULL; iCode *loop = ic; ebbIndex *ebbi; ebbi = Safe_alloc (sizeof (ebbIndex)); ebbi->count = 0; ebbi->dfOrder = NULL; /* no depth first order information yet */ /* allocate for the first entry */ ebbs = Safe_alloc (sizeof (eBBlock *)); ebbi->bbOrder = ebbs; while (loop) { /* convert 2 block */ eBBlock *ebb = iCode2eBBlock (loop); loop = ebb->ech->next; ebb->ech->next = NULL; /* mark the end of this chain */ if (loop) loop->prev = NULL; ebb->bbnum = ebbi->count; /* save this block number */ /* put it in the array */ ebbs[(ebbi->count)++] = ebb; /* allocate for the next one. Remember to clear the new */ /* pointer at the end, that was created by realloc. */ ebbs = Safe_realloc (ebbs, (ebbi->count + 1) * sizeof (eBBlock *)); ebbi->bbOrder = ebbs; ebbs[ebbi->count] = 0; /* if this one ends in a goto or a conditional */ /* branch then check if the block it is going */ /* to already exists, if yes then this could */ /* be a loop, add a preheader to the block it */ /* goes to if it does not already have one */ if (ebbs[(ebbi->count) - 1]->ech && (ebbs[(ebbi->count) - 1]->ech->op == GOTO || ebbs[(ebbi->count) - 1]->ech->op == IFX)) { symbol *label; eBBlock *destBlock; if (ebbs[(ebbi->count) - 1]->ech->op == GOTO) label = IC_LABEL (ebbs[(ebbi->count) - 1]->ech); else if (!(label = IC_TRUE (ebbs[(ebbi->count) - 1]->ech))) label = IC_FALSE (ebbs[(ebbi->count) - 1]->ech); if ((destBlock = eBBWithEntryLabel (ebbi, label)) && destBlock->preHeader == NULL && otherPathsPresent (ebbs, destBlock)) { symbol *preHeaderLabel = newiTempLoopHeaderLabel (1); int i, j; eBBlock *pBlock; /* go thru all block replacing the entryLabel with new label */ /* till we reach the block , then we insert a new ebblock */ for (i = 0; i < (ebbi->count); i++) { if (ebbs[i] == destBlock) break; replaceLabel (ebbs[i], label, preHeaderLabel); } (ebbi->count)++; /* if we have stopped at the block , allocate for an extra one */ ebbs = Safe_realloc (ebbs, (ebbi->count + 1) * sizeof (eBBlock *)); ebbi->bbOrder = ebbs; ebbs[ebbi->count] = 0; /* then move the block down one count */ pBlock = ebbs[j = i]; for (i += 1; i < (ebbi->count); i++) { eBBlock *xBlock; xBlock = ebbs[i]; ebbs[i] = pBlock; ebbs[i]->bbnum = i; pBlock = xBlock; } destBlock->preHeader = ebbs[j] = neweBBlock (); ebbs[j]->bbnum = j; ebbs[j]->entryLabel = preHeaderLabel; ebbs[j]->sch = ebbs[j]->ech = newiCodeLabelGoto (LABEL, preHeaderLabel); ebbs[j]->sch->filename = destBlock->sch->filename; ebbs[j]->sch->lineno = destBlock->sch->lineno; } } } /* mark the end */ ebbs[ebbi->count] = NULL; return ebbi; }