/*-----------------------------------------------------------------*/ bitVect * bitVectCopy (bitVect * bvp) { bitVect *newBvp; int i; if (!bvp) return NULL; newBvp = newBitVect (bvp->size); for (i = 0; i < bvp->bSize; i++) newBvp->vect[i] = bvp->vect[i]; return newBvp; }
/*-----------------------------------------------------------------*/ bitVect * bitVectUnion (bitVect * bvp1, bitVect * bvp2) { int i; bitVect *newBvp; unsigned int *pn, *p1, *p2; int nbits; /* if both null */ if (!bvp1 && !bvp2) return NULL; /* if one of them null then return the other */ if (!bvp1 && bvp2) return bitVectCopy (bvp2); if (bvp1 && !bvp2) return bitVectCopy (bvp1); /* if they are not the same size */ /* make them the same size */ if (bvp1->bSize < bvp2->bSize) bvp1 = bitVectResize (bvp1, bvp2->size); else if (bvp2->bSize < bvp1->bSize) bvp2 = bitVectResize (bvp2, bvp1->size); newBvp = newBitVect (bvp1->size); nbits = bvp1->bSize; i = 0; pn = (unsigned int *)newBvp->vect; p1 = (unsigned int *)bvp1->vect; p2 = (unsigned int *)bvp2->vect; while ((nbits - i) >= sizeof(*pn)) { *pn++ = *p1++ | *p2++; i += sizeof(*pn); } for (; i < nbits; i++) newBvp->vect[i] = bvp1->vect[i] | bvp2->vect[i]; return newBvp; }
/*-----------------------------------------------------------------*/ bitVect * bitVectSetBit (bitVect * bvp, int pos) { int byteSize; int offset; assert (pos>=0); /* if set is null then allocate it */ if (!bvp) bvp = newBitVect (bitVectDefault); /* allocate for twice the size */ if (bvp->size <= pos) bvp = bitVectResize (bvp, pos + 2); /* conservatively resize */ byteSize = pos / 8; offset = pos % 8; bvp->vect[byteSize] |= (((unsigned char) 1) << (7 - offset)); return bvp; }
/*-----------------------------------------------------------------*/ bitVect * bitVectResize (bitVect * bvp, int size) { int bSize = (size / 8) + 1; if (!bvp) return newBitVect (size); /* if we already have enough space */ if (bvp->bSize >= bSize) { if (size > bvp->size) bvp->size = size; return bvp; } bvp->vect = Clear_realloc (bvp->vect, bvp->bSize, bSize); bvp->size = size; bvp->bSize = bSize; return bvp; }
/*-----------------------------------------------------------------*/ bitVect * bitVectIntersect (bitVect * bvp1, bitVect * bvp2) { int i; bitVect *newBvp; unsigned int *pn, *p1, *p2; int nbits; if (!bvp2 || !bvp1) return NULL; /* if they are not the same size */ /* make them the same size */ if (bvp1->bSize < bvp2->bSize) bvp1 = bitVectResize (bvp1, bvp2->bSize); else if (bvp2->size < bvp1->size) bvp2 = bitVectResize (bvp2, bvp1->size); newBvp = newBitVect (bvp1->size); nbits = bvp1->bSize; i = 0; pn = (unsigned int *)newBvp->vect; p1 = (unsigned int *)bvp1->vect; p2 = (unsigned int *)bvp2->vect; while ((nbits - i) >= sizeof(*pn)) { *pn++ = *p1++ & *p2++; i += sizeof(*pn); } for (; i < nbits; i++) newBvp->vect[i] = bvp1->vect[i] & bvp2->vect[i]; return newBvp; }
/*-----------------------------------------------------------------*/ static void rlivePoint (eBBlock ** ebbs, int count, bool emitWarnings) { int i, key; eBBlock *succ; bitVect *alive; /* for all blocks do */ for (i = 0; i < count; i++) { iCode *ic; /* for all instructions in this block do */ for (ic = ebbs[i]->sch; ic; ic = ic->next) { if (!ic->rlive) ic->rlive = newBitVect (operandKey); if (SKIP_IC2(ic)) continue; if (ic->op == JUMPTABLE && IS_SYMOP(IC_JTCOND(ic))) { incUsed (ic, IC_JTCOND(ic)); if (!IS_AUTOSYM(IC_JTCOND(ic))) continue; findPrevUse (ebbs[i], ic, IC_JTCOND(ic), ebbs, count, emitWarnings); if (IS_ITEMP(IC_JTCOND(ic))) { unvisitBlocks(ebbs, count); ic->rlive = bitVectSetBit (ic->rlive, IC_JTCOND(ic)->key); findNextUse (ebbs[i], ic->next, IC_JTCOND(ic)); } continue; } if (ic->op == IFX && IS_SYMOP(IC_COND(ic))) { incUsed (ic, IC_COND(ic)); if (!IS_AUTOSYM(IC_COND(ic))) continue; findPrevUse (ebbs[i], ic, IC_COND(ic), ebbs, count, emitWarnings); if (IS_ITEMP(IC_COND(ic))) { unvisitBlocks (ebbs, count); ic->rlive = bitVectSetBit (ic->rlive, IC_COND(ic)->key); findNextUse (ebbs[i], ic->next, IC_COND(ic)); } continue; } if (IS_SYMOP(IC_LEFT(ic))) { incUsed (ic, IC_LEFT(ic)); if (IS_AUTOSYM(IC_LEFT(ic)) && ic->op != ADDRESS_OF) { findPrevUse (ebbs[i], ic, IC_LEFT(ic), ebbs, count, emitWarnings); if (IS_ITEMP(IC_LEFT(ic))) { unvisitBlocks(ebbs, count); ic->rlive = bitVectSetBit (ic->rlive, IC_LEFT(ic)->key); findNextUse (ebbs[i], ic->next, IC_LEFT(ic)); /* if this is a send extend the LR to the call */ if (ic->op == SEND) { iCode *lic; for (lic = ic; lic; lic = lic->next) { if (lic->op == CALL || lic->op == PCALL) { markAlive (ic, lic->prev, IC_LEFT (ic)->key); break; } } } } } } if (IS_SYMOP(IC_RIGHT(ic))) { incUsed (ic, IC_RIGHT(ic)); if (IS_AUTOSYM(IC_RIGHT(ic))) { findPrevUse (ebbs[i], ic, IC_RIGHT(ic), ebbs, count, emitWarnings); if (IS_ITEMP(IC_RIGHT(ic))) { unvisitBlocks(ebbs, count); ic->rlive = bitVectSetBit (ic->rlive, IC_RIGHT(ic)->key); findNextUse (ebbs[i], ic->next, IC_RIGHT(ic)); } } } if (POINTER_SET(ic) && IS_SYMOP(IC_RESULT(ic))) incUsed (ic, IC_RESULT(ic)); if (IS_AUTOSYM(IC_RESULT(ic))) { if (POINTER_SET(ic)) { findPrevUse (ebbs[i], ic, IC_RESULT(ic), ebbs, count, emitWarnings); } if (IS_ITEMP(IC_RESULT(ic))) { unvisitBlocks(ebbs, count); ic->rlive = bitVectSetBit (ic->rlive, IC_RESULT(ic)->key); findNextUse (ebbs[i], ic->next, IC_RESULT(ic)); /* findNextUse sometimes returns 0 here, which means that ic is dead code. Something should be done about this dead code since e.g. register allocation suffers. */ } } if (!POINTER_SET(ic) && IC_RESULT(ic)) ic->defKey = IC_RESULT(ic)->key; } /* check all symbols that are alive in the last instruction */ /* but are not alive in all successors */ succ = setFirstItem (ebbs[i]->succList); if (!succ) continue; alive = succ->sch->rlive; while ((succ = setNextItem (ebbs[i]->succList))) { if (succ->sch) alive = bitVectIntersect (alive, succ->sch->rlive); } if (ebbs[i]->ech) alive = bitVectCplAnd ( bitVectCopy (ebbs[i]->ech->rlive), alive); if(!alive) continue; for (key = 1; key < alive->size; key++) { if (!bitVectBitValue (alive, key)) continue; unvisitBlocks(ebbs, count); findNextUseSym (ebbs[i], NULL, hTabItemWithKey (liveRanges, key)); } } }
static asmLineNode * asmLineNodeFromLineNode (lineNode *ln) { asmLineNode *aln = newAsmLineNode(); char *op, op1[256], op2[256]; int opsize; const char *p; char inst[8]; mcs51opcodedata *opdat; p = ln->line; while (*p && isspace(*p)) p++; for (op = inst, opsize=1; *p; p++) { if (isspace(*p) || *p == ';' || *p == ':' || *p == '=') break; else if (opsize < sizeof(inst)) *op++ = tolower(*p), opsize++; } *op = '\0'; if (*p == ';' || *p == ':' || *p == '=') return aln; while (*p && isspace(*p)) p++; if (*p == '=') return aln; for (op = op1, opsize=1; *p && *p != ','; p++) { if (!isspace(*p) && opsize < sizeof(op1)) *op++ = tolower(*p), opsize++; } *op = '\0'; if (*p == ',') p++; for (op = op2, opsize=1; *p && *p != ','; p++) { if (!isspace(*p) && opsize < sizeof(op2)) *op++ = tolower(*p), opsize++; } *op = '\0'; aln->size = instructionSize(inst, op1, op2); aln->regsRead = newBitVect (END_IDX); aln->regsWritten = newBitVect (END_IDX); opdat = bsearch (inst, mcs51opcodeDataTable, sizeof(mcs51opcodeDataTable)/sizeof(mcs51opcodedata), sizeof(mcs51opcodedata), mcs51opcodeCompare); if (opdat) { updateOpRW (aln, op1, opdat->op1type); updateOpRW (aln, op2, opdat->op2type); if (strchr(opdat->pswtype,'r')) aln->regsRead = bitVectSetBit (aln->regsRead, CND_IDX); if (strchr(opdat->pswtype,'w')) aln->regsWritten = bitVectSetBit (aln->regsWritten, CND_IDX); } return aln; }
/*-----------------------------------------------------------------*/ static void computeDominance (ebbIndex * ebbi) { eBBlock ** ebbs = ebbi->bbOrder; int count = ebbi->count; int i, j; /* now do the initialisation */ /* D(n0) := { n0 } */ ebbs[0]->domVect = bitVectSetBit (ebbs[0]->domVect = newBitVect (count), ebbs[0]->bbnum); /* for n in N - { n0 } do D(n) = N */ for (i = 1; i < count; i++) { ebbs[i]->domVect = newBitVect (count); for (j = 0; j < count; j++) { ebbs[i]->domVect = bitVectSetBit (ebbs[i]->domVect, ebbs[j]->bbnum); } } /* end of initialisation */ /* while changes to any D(n) occur do */ /* for n in N - { n0 } do */ /* D(n) := { n } U (intersection of D( all predecessors of n)) */ while (1) { int change; change = 0; for (i = 1; i < count; i++) { bitVect *cDomVect; eBBlock *pred; cDomVect = NULL; /* get the intersection of the dominance of all predecessors */ for (pred = setFirstItem (ebbs[i]->predList), cDomVect = (pred ? bitVectCopy (pred->domVect) : NULL); pred; pred = setNextItem (ebbs[i]->predList)) { cDomVect = bitVectIntersect (cDomVect, pred->domVect); } if (!cDomVect) cDomVect = newBitVect (count); /* this node to the list */ cDomVect = bitVectSetBit (cDomVect, ebbs[i]->bbnum); if (!bitVectEqual (cDomVect, ebbs[i]->domVect)) { ebbs[i]->domVect = cDomVect; change = 1; } } /* if no change then exit */ if (!change) break; } }
/*-----------------------------------------------------------------*/ static void eBBSuccessors (ebbIndex * ebbi) { eBBlock ** ebbs = ebbi->bbOrder; int count = ebbi->count; int i = 0; /* for all the blocks do */ for (; i < count; i++) { iCode *ic; if (ebbs[i]->noPath) continue; ebbs[i]->succVect = newBitVect (count); /* if the next on exists & this one does not */ /* end in a GOTO or RETURN then the next is */ /* a natural successor of this. Note we have */ /* consider eBBlocks with no instructions */ if (ebbs[i + 1]) { if (ebbs[i]->ech) { bool foundNoReturn = FALSE; if (ebbs[i]->ech->op == CALL || ebbs[i]->ech->op == PCALL) { sym_link *type = operandType (IC_LEFT (ebbs[i]->ech)); if (IS_FUNCPTR (type)) type = type->next; if (type && FUNC_ISNORETURN (type)) foundNoReturn = TRUE; } if (!foundNoReturn && ebbs[i]->ech->op != GOTO && ebbs[i]->ech->op != RETURN && ebbs[i]->ech->op != JUMPTABLE) { int j = i + 1; while (ebbs[j] && ebbs[j]->noPath) j++; addSuccessor (ebbs[i], ebbs[j]); /* add it */ } else { if (i && ebbs[i-1]->ech && ebbs[i-1]->ech->op==IFX) { ebbs[i]->isConditionalExitFrom=ebbs[i-1]; } } } /* no instructions in the block */ /* could happen for dummy blocks */ else addSuccessor (ebbs[i], ebbs[i + 1]); } /* go thru all the instructions: if we find a */ /* goto or ifx or a return then we have a succ */ if ((ic = ebbs[i]->ech)) { eBBlock *succ; /* special case for jumptable */ if (ic->op == JUMPTABLE) { symbol *lbl; for (lbl = setFirstItem (IC_JTLABELS (ic)); lbl; lbl = setNextItem (IC_JTLABELS (ic))) addSuccessor (ebbs[i], eBBWithEntryLabel (ebbi, lbl)); } else { succ = NULL; /* depending on the instruction operator */ switch (ic->op) { case GOTO: /* goto has edge to label */ succ = eBBWithEntryLabel (ebbi, ic->label); break; case IFX: /* conditional jump */ /* if true label is present */ if (IC_TRUE (ic)) succ = eBBWithEntryLabel (ebbi, IC_TRUE (ic)); else succ = eBBWithEntryLabel (ebbi, IC_FALSE (ic)); break; case RETURN: /* block with return */ succ = eBBWithEntryLabel (ebbi, returnLabel); break; } /* if there is a successor add to the list */ /* if it is not already present in the list */ if (succ) addSuccessor (ebbs[i], succ); } } } }