/*-----------------------------------------------------------------*/ eBBlock * iCode2eBBlock (iCode * ic) { iCode *loop; eBBlock *ebb = neweBBlock (); /* allocate an entry */ /* put the first one unconditionally */ ebb->sch = ic; /* if this is a label then */ if (ic->op == LABEL) ebb->entryLabel = ic->label; else { SNPRINTF (buffer, sizeof(buffer), "_eBBlock%d", eBBNum++); ebb->entryLabel = newSymbol (buffer, 1); ebb->entryLabel->key = labelKey++; } if (ic && (ic->op == GOTO || ic->op == JUMPTABLE || ic->op == IFX)) { ebb->ech = ebb->sch; return ebb; } /* if this is a function call */ if (ic->op == CALL || ic->op == PCALL) { ebb->hasFcall = 1; if (currFunc) FUNC_HASFCALL(currFunc->type) = 1; } if ((ic->next && ic->next->op == LABEL) || !ic->next) { ebb->ech = ebb->sch; return ebb; } /* loop thru till we find one with a label */ for (loop = ic->next; loop; loop = loop->next) { /* if this is the last one */ if (!loop->next) break; /* if this is a function call */ if (loop->op == CALL || loop->op == PCALL) { ebb->hasFcall = 1; if (currFunc) FUNC_HASFCALL(currFunc->type) = 1; } /* if the next one is a label */ /* if this is a goto or ifx */ if (loop->next->op == LABEL || loop->op == GOTO || loop->op == JUMPTABLE || loop->op == IFX) break; } /* mark the end of the chain */ ebb->ech = loop; return ebb; }
/*-----------------------------------------------------------------*/ 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; }
/*-----------------------------------------------------------------*/ eBBlock * iCode2eBBlock (iCode * ic) { iCode *loop; eBBlock *ebb = neweBBlock (); /* allocate an entry */ /* put the first one unconditionally */ ebb->sch = ic; ic->seq = 0; /* if this is a label then */ if (ic->op == LABEL) ebb->entryLabel = ic->label; else { struct dbuf_s dbuf; dbuf_init (&dbuf, 128); dbuf_printf (&dbuf, "_eBBlock%d", eBBNum++); ebb->entryLabel = newSymbol (dbuf_c_str (&dbuf), 1); dbuf_destroy (&dbuf); ebb->entryLabel->key = labelKey++; } if (ic && (ic->op == GOTO || ic->op == JUMPTABLE || ic->op == IFX)) { ebb->ech = ebb->sch; return ebb; } /* if this is a function call */ if (ic->op == CALL || ic->op == PCALL) { sym_link *type = operandType (IC_LEFT (ic)); ebb->hasFcall = 1; if (currFunc) FUNC_HASFCALL (currFunc->type) = 1; if (IS_FUNCPTR (type)) type = type->next; if (type && FUNC_ISNORETURN (type)) { ebb->ech = ebb->sch; return ebb; } } if ((ic->next && ic->next->op == LABEL) || !ic->next) { ebb->ech = ebb->sch; return ebb; } /* loop thru till we find one with a label */ for (loop = ic->next; loop; loop = loop->next) { loop->seq = 0; /* if this is the last one */ if (!loop->next) break; /* if this is a function call */ if (loop->op == CALL || loop->op == PCALL) { sym_link *type = operandType (IC_LEFT (loop)); ebb->hasFcall = 1; if (currFunc) FUNC_HASFCALL (currFunc->type) = 1; if (IS_FUNCPTR (type)) type = type->next; if (type && FUNC_ISNORETURN (type)) break; } /* if the next one is a label */ /* if this is a goto or ifx */ if (loop->next->op == LABEL || loop->op == GOTO || loop->op == JUMPTABLE || loop->op == IFX) break; } /* mark the end of the chain */ ebb->ech = loop; return ebb; }