예제 #1
0
/*-----------------------------------------------------------------*/
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;
}
예제 #2
0
파일: SDCCcflow.c 프로젝트: Jason-K/sdcc
/*-----------------------------------------------------------------*/
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);
	    }
	}
    }
}