Example #1
0
/*-----------------------------------------------------------------*/
static void 
computeDFOrdering (eBBlock * ebbp, int *count)
{

  ebbp->visited = 1;
  /* for each successor that is not visited */
  applyToSet (ebbp->succList, DFOrdering, count);

  /* set the depth first number */
  ebbp->dfnum = *count;
  *count -= 1;
}
Example #2
0
/*-----------------------------------------------------------------*/
void 
computeDataFlow (eBBlock ** ebbs, int count)
{
  int i;
  int change = 1;

  while (change)
    {

      change = 0;

      /* for all blocks */
      for (i = 0; i < count; i++)
	{

	  set *pred;
	  set *oldOut;
	  int firstTime;
	  eBBlock *pBlock;

	  /* if this is the entry block then continue     */
	  /* since entry block can never have any inExprs */
	  if (ebbs[i]->noPath)
	    continue;

	  /* get blocks that can come to this block */
	  pred = edgesTo (ebbs[i]);

	  /* make a copy of the outExpressions : to be */
	  /* used for iteration   */
	  oldOut = setFromSet (ebbs[i]->outExprs);
	  setToNull ((void **) &ebbs[i]->inDefs);

	  /* indefitions are easy just merge them by union */
	  /* these are the definitions that can possibly   */
	  /* reach this block                              */
	  firstTime = 1;
	  applyToSet (pred, mergeInDefs, ebbs[i], &firstTime);

	  /* if none of the edges coming to this block */
	  /* dominate this block then add the immediate dominator */
	  /* of this block to the list of predecessors */
	  for (pBlock = setFirstItem (pred); pBlock;
	       pBlock = setNextItem (pred))
	    {
	      if (bitVectBitValue (ebbs[i]->domVect, pBlock->bbnum))
		break;
	    }

	  /* get the immediate dominator and put it there */
	  if (!pBlock)
	    {
	      eBBlock *idom = immedDom (ebbs, ebbs[i]);
	      if (idom)
		addSetHead (&pred, idom);
	    }

	  /* figure out the incoming expressions */
	  /* this is a little more complex       */
	  setToNull ((void **) &ebbs[i]->inExprs);
	  if (optimize.global_cse)
	    {
	      firstTime = 1;
	      applyToSet (pred, mergeInExprs, ebbs[i], &firstTime);
	    }
	  setToNull ((void **) &pred);

	  /* do cse with computeOnly flag set to TRUE */
	  /* this by far the quickest way of computing */
	  cseBBlock (ebbs[i], TRUE, ebbs, count);

	  /* if it change we will need to iterate */
	  change += !isSetsEqualWith (ebbs[i]->outExprs, oldOut, isCseDefEqual);
	}

      if (!change)		/* iterate till no change */
	break;
    }

  return;
}
Example #3
0
/*-----------------------------------------------------------------*/
int 
killDeadCode (eBBlock ** ebbs, int count)
{
  int change = 1;
  int gchange = 0;
  int i = 0;


  /* basic algorithm :-                                          */
  /* first the exclusion rules :-                                */
  /*  1. if result is a global or volatile then skip             */
  /*  2. if assignment and result is a temp & isaddr  then skip  */
  /*     since this means array & pointer access, will be taken  */
  /*     care of by alias analysis.                              */
  /*  3. if the result is used in the remainder of the block skip */
  /*  4. if this definition does not reach the end of the block  */
  /*     i.e. the result is not present in the outExprs then KILL */
  /*  5. if it reaches the end of block & is used by some success */
  /*     or then skip                                            */
  /*     else            KILL                                    */
  /* this whole process is carried on iteratively till no change */
  while (1)
    {

      change = 0;
      /* for all blocks do */
      for (i = 0; i < count; i++)
	{
	  iCode *ic;

	  /* for all instructions in the block do */
	  for (ic = ebbs[i]->sch; ic; ic = ic->next)
	    {
	      int kill, j;
	      kill = 0;

	      if (SKIP_IC (ic) ||
		  ic->op == IFX ||
		  ic->op == RETURN)
		continue;

	      /* if the result is volatile then continue */
	      if (IC_RESULT (ic) && isOperandVolatile (IC_RESULT (ic), FALSE))
		continue;

	      /* if the result is a temp & isaddr then skip */
	      if (IC_RESULT (ic) && POINTER_SET (ic))
		continue;

	      /* if the result is used in the remainder of the */
	      /* block then skip */
	      if (usedInRemaining (IC_RESULT (ic), ic->next))
		continue;

	      /* does this definition reach the end of the block 
	         or the usage is zero then we can kill */
	      if (!bitVectBitValue (ebbs[i]->outDefs, ic->key))
		kill = 1;	/* if not we can kill it */
	      else
		{
		  /* if this is a global variable or function parameter */
		  /* we cannot kill anyway             */
		  if (isOperandGlobal (IC_RESULT (ic)) ||
		      (OP_SYMBOL (IC_RESULT (ic))->_isparm &&
		       !OP_SYMBOL (IC_RESULT (ic))->ismyparm))
		    continue;

		  /* if we are sure there are no usages */
		  if (bitVectIsZero (OP_USES (IC_RESULT (ic))))
		    {
		      kill = 1;
		      goto kill;
		    }

		  /* reset visited flag */
		  for (j = 0; j < count; ebbs[j++]->visited = 0);

		  /* find out if this definition is alive */
		  if (applyToSet (ebbs[i]->succList,
				  isDefAlive,
				  ic))
		    continue;

		  kill = 1;
		}

	    kill:
	      /* kill this one if required */
	      if (kill)
		{
		  change = 1;
		  gchange++;
		  /* eliminate this */
		  remiCodeFromeBBlock (ebbs[i], ic);

		  /* now delete from defUseSet */
		  deleteItemIf (&ebbs[i]->outExprs, ifDiCodeIsX, ic);
		  bitVectUnSetBit (ebbs[i]->outDefs, ic->key);

		  /* and defset of the block */
		  bitVectUnSetBit (ebbs[i]->defSet, ic->key);

		  /* for the left & right remove the usage */
		  if (IS_SYMOP (IC_LEFT (ic)))
		    bitVectUnSetBit (OP_USES (IC_LEFT (ic)), ic->key);

		  if (IS_SYMOP (IC_RIGHT (ic)))
		    bitVectUnSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
		}

	    }			/* end of all instructions */

	  if (!ebbs[i]->sch && !ebbs[i]->noPath)
	    disconBBlock (ebbs[i], ebbs, count);

	}			/* end of for all blocks */

      if (!change)
	break;
    }				/* end of while(1) */

  return gchange;
}
Example #4
0
/*-----------------------------------------------------------------*/
static symbol *
createStackSpil (symbol * sym)
{
  symbol *sloc = NULL;
  struct dbuf_s dbuf;

  D (D_ALLOC, ("createStackSpil: for sym %p %s\n", sym, sym->name));

  /* first go try and find a free one that is already
     existing on the stack */
  if (applyToSet (_G.stackSpil, isFreeSTM8, &sloc, sym))
    {
      /* found a free one : just update & return */
      sym->usl.spillLoc = sloc;
      sym->stackSpil = 1;
      sloc->isFree = 0;
      addSetHead (&sloc->usl.itmpStack, sym);
      D (D_ALLOC, ("createStackSpil: found existing\n"));
      return sym;
    }

  /* could not then have to create one , this is the hard part
     we need to allocate this on the stack : this is really a
     hack!! but cannot think of anything better at this time */

  dbuf_init (&dbuf, 128);
  dbuf_printf (&dbuf, "sloc%d", _G.slocNum++);
  sloc = newiTemp (dbuf_c_str (&dbuf));
  dbuf_destroy (&dbuf);

  /* set the type to the spilling symbol */
  sloc->type = copyLinkChain (sym->type);
  sloc->etype = getSpec (sloc->type);
  SPEC_SCLS (sloc->etype) = S_AUTO;
  SPEC_EXTR (sloc->etype) = 0;
  SPEC_STAT (sloc->etype) = 0;
  SPEC_VOLATILE (sloc->etype) = 0;

  allocLocal (sloc);

  sloc->isref = 1;              /* to prevent compiler warning */

  wassertl (currFunc, "Local variable used outside of function.");

  /* if it is on the stack then update the stack */
  if (IN_STACK (sloc->etype))
    {
      if (currFunc)
        currFunc->stack += getSize (sloc->type);
      _G.stackExtend += getSize (sloc->type);
    }
  else
    {
      _G.dataExtend += getSize (sloc->type);
    }

  /* add it to the stackSpil set */
  addSetHead (&_G.stackSpil, sloc);
  sym->usl.spillLoc = sloc;
  sym->stackSpil = 1;

  /* add it to the set of itempStack set
     of the spill location */
  addSetHead (&sloc->usl.itmpStack, sym);

  D (D_ALLOC, ("createStackSpil: created new\n"));
  return sym;
}