Example #1
0
void
dumpIcRlive (eBBlock ** ebbs, int count)
{
  int i, j;
  iCode *ic;

  /* for all blocks do */
  for (i = 0; i < count; i++)
    {
      printf ("bb %d %s alive symbols:\n", i, ebbs[i]->entryLabel->name);
      /* for all instructions in this block do */
      for (ic = ebbs[i]->sch; ic; ic = ic->next)
        {
          printf ("\tic->key %d\n", ic->key);

          if (!ic->rlive)
            continue;
          /* for all live Ranges alive at this point */
          for (j = 1; j < ic->rlive->size; j++)
            {
              symbol *sym;

              if (!bitVectBitValue (ic->rlive, j))
                continue;

              /* find the live range we are interested in */
              if ((sym = hTabItemWithKey (liveRanges, j)))
                printf ("\t\tsym->key %2d: %s\n", sym->key, sym->rname[0] ? sym->rname : sym->name);
            }
        }
    }
}
Example #2
0
/*-----------------------------------------------------------------*/
static void
markLiveRanges (eBBlock **ebbs, int count)
{
  int i, key;
  symbol *sym;

  for (i = 0; i < count; i++)
    {
      iCode *ic;

      for (ic = ebbs[i]->sch; ic; ic = ic->next)
        {
	  if (ic->op == CALL || ic->op == PCALL)
	    if (bitVectIsZero (OP_SYMBOL (IC_RESULT (ic))->uses))
              bitVectUnSetBit (ebbs[i]->defSet, ic->key);

	  /* for all iTemps alive at this iCode */
	  for (key = 1; key < ic->rlive->size; key++)
	    {
	      if (!bitVectBitValue(ic->rlive, key))
	        continue;

	      sym = hTabItemWithKey(liveRanges, key);
	      setLiveTo(sym, ic->seq);
	      setLiveFrom(sym, ic->seq);
	    }

	}
    }
}
Example #3
0
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;
            }
        }
    }
}
Example #4
0
/*-----------------------------------------------------------------*/
static void 
eBBPredecessors (ebbIndex * ebbi)
{
  eBBlock ** ebbs = ebbi->bbOrder;
  int count = ebbi->count;
  int i = 0, j;

  /* for each block do */
  for (i = 0; i < count; i++)
    {

      /* if there is no path to this then continue */
      if (ebbs[i]->noPath)
	continue;

      /* for each successor of this block if */
      /* it has depth first number > this block */
      /* then this block precedes the successor  */
      for (j = 0; j < ebbs[i]->succVect->size; j++)

	if (bitVectBitValue (ebbs[i]->succVect, j) &&
	    ebbs[j]->dfnum > ebbs[i]->dfnum)

	  addSet (&ebbs[j]->predList, ebbs[i]);
    }
}
Example #5
0
/*-----------------------------------------------------------------*/
int 
bitVectFirstBit (bitVect * bvp)
{
  int i;

  if (!bvp)
    return -1;
  for (i = 0; i < bvp->size; i++)
    if (bitVectBitValue (bvp, i))
      return i;

  return -1;
}
Example #6
0
/*-----------------------------------------------------------------*/
static set *
domSetFromVect (ebbIndex *ebbi, bitVect * domVect)
{
  int i = 0;
  set *domSet = NULL;

  if (!domVect)
    return NULL;

  for (i = 0; i < domVect->size; i++)
    if (bitVectBitValue (domVect, i))
      addSet (&domSet, ebbi->bbOrder[i]);
  return domSet;
}
Example #7
0
/*-----------------------------------------------------------------*/
void 
bitVectDebugOn (bitVect * bvp, FILE * of)
{
  int i;

  if (of == NULL)
    of = stdout;
  if (!bvp)
    return;

  fprintf (of, "bitvector Size = %d bSize = %d\n", bvp->size, bvp->bSize);
  fprintf (of, "Bits on { ");
  for (i = 0; i < bvp->size; i++)
    {
      if (bitVectBitValue (bvp, i))
	fprintf (of, "(%d) ", i);
    }
  fprintf (of, "}\n");
}
Example #8
0
/*-----------------------------------------------------------------*/
bool
allDefsOutOfRange (bitVect * defs, int fseq, int toseq)
{
  int i;

  if (!defs)
    return TRUE;

  for (i = 0; i < defs->size; i++)
    {
      iCode *ic;

      if (bitVectBitValue (defs, i) &&
	  (ic = hTabItemWithKey (iCodehTab, i)) &&
	  (ic->seq >= fseq && ic->seq <= toseq))
	return FALSE;

    }

  return TRUE;
}
Example #9
0
/** noOverLap - will iterate through the list looking for over lap
 */
static int
noOverLap (set *itmpStack, symbol *fsym)
{
  symbol *sym;

  for (sym = setFirstItem (itmpStack); sym; sym = setNextItem (itmpStack))
    {
      if (bitVectBitValue (sym->clashes, fsym->key))
        return 0;
#if 0
      // if sym starts before (or on) our end point
      // and ends after (or on) our start point,
      // it is an overlap.
      if (sym->liveFrom <= fsym->liveTo && sym->liveTo >= fsym->liveFrom)
        {
          return 0;
        }
#endif
    }
  return 1;
}
Example #10
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 #11
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 #12
0
/*-----------------------------------------------------------------*/
static S4O_RET
scan4op (lineNode **pl, const char *pReg, const char *untilOp,
         lineNode **plCond)
{
  char *p;
  int len;
  bool isConditionalJump;
  int rIdx;
  S4O_RET ret;
  bool findPushPop;

  findPushPop = untilOp && (strcmp (untilOp, "push") == 0 || strcmp (untilOp, "pop") == 0);

  /* pReg points to e.g. "ar0"..."ar7" */
  len = strlen (pReg);

  /* get index into pReg table */
  for (rIdx = 0; rIdx < mcs51_nRegs; ++rIdx)
    if (strcmp (regs8051[rIdx].name, pReg + 1) == 0)
      break;

  /* sanity check */
  if (rIdx >= mcs51_nRegs)
    {
      DEADMOVEERROR();
      return S4O_ABORT;
    }

  for (; *pl; *pl = (*pl)->next)
    {
      if (!(*pl)->line || (*pl)->isDebug || (*pl)->isComment)
        continue;

      /* don't optimize across inline assembler,
         e.g. isLabel doesn't work there */
      if ((*pl)->isInline)
        return S4O_ABORT;

      if ((*pl)->visited)
        return S4O_VISITED;
      (*pl)->visited = TRUE;

      /* found untilOp? */
      if (untilOp && strncmp ((*pl)->line, untilOp, strlen (untilOp)) == 0)
        {
          p = (*pl)->line + strlen (untilOp);
          if (*p == '\t' && strncmp (p + 1, pReg, len) == 0)
            return S4O_FOUNDOPCODE;
          else
            {
              /* found untilOp but without our pReg */
              return S4O_ABORT;
            }
        }

      /* found pReg? */
      p = strchr ((*pl)->line, '\t');
      if (p)
        {
          /* skip '\t' */
          p++;

          /* when looking for push or pop and we find a direct access of sp: abort */
          if (findPushPop && strstr (p, "sp"))
            return S4O_ABORT;

          /* course search */
          if (strstr (p, pReg + 1))
            {
              /* ok, let's have a closer look */

              /* does opcode read from pReg? */
              if (bitVectBitValue (port->peep.getRegsRead ((*pl)), rIdx))
                return S4O_RD_OP;
              /* does opcode write to pReg? */
              if (bitVectBitValue (port->peep.getRegsWritten ((*pl)), rIdx))
                return S4O_WR_OP;

              /* we can get here, if the register name is
                 part of a variable name: ignore it */
            }
        }

      /* found label? */
      if ((*pl)->isLabel)
        {
          const char *start;
          char label[SDCC_NAME_MAX + 1];
          int len;

          if (!isLabelDefinition ((*pl)->line, &start, &len, FALSE))
            return S4O_ABORT;
          memcpy (label, start, len);
          label[len] = '\0';
          /* register passing this label */
          if (!setLabelRefPassedLabel (label))
            {
              DEADMOVEERROR();
              return S4O_ABORT;
            }
          continue;
        }

      /* branch or terminate? */
      isConditionalJump = FALSE;
      switch ((*pl)->line[0])
        {
          case 'a':
            if (strncmp ("acall", (*pl)->line, 5) == 0)
              {
                /* for comments see 'lcall' */
                ret = termScanAtFunc (*pl, rIdx);
                if (ret != S4O_CONTINUE)
                  return ret;
                break;
              }
            if (strncmp ("ajmp", (*pl)->line, 4) == 0)
              {
                *pl = findLabel (*pl);
                if (!*pl)
                  return S4O_ABORT;
              }
            break;
          case 'c':
            if (strncmp ("cjne", (*pl)->line, 4) == 0)
              {
                isConditionalJump = TRUE;
                break;
              }
            break;
          case 'd':
            if (strncmp ("djnz", (*pl)->line, 4) == 0)
              {
                isConditionalJump = TRUE;
                break;
              }
            break;
          case 'j':
            if (strncmp ("jmp", (*pl)->line, 3) == 0)
              /* "jmp @a+dptr": no chance to trace execution */
              return S4O_ABORT;
            if (strncmp ("jc",  (*pl)->line, 2) == 0 ||
                strncmp ("jnc", (*pl)->line, 3) == 0 ||
                strncmp ("jz",  (*pl)->line, 2) == 0 ||
                strncmp ("jnz", (*pl)->line, 3) == 0)
              {
                isConditionalJump = TRUE;
                break;
              }
            if (strncmp ("jbc", (*pl)->line, 3) == 0 ||
                strncmp ("jb",  (*pl)->line, 2) == 0 ||
                strncmp ("jnb", (*pl)->line, 3) == 0)
              {
                isConditionalJump = TRUE;
                break;
              }
            break;
          case 'l':
            if (strncmp ("lcall", (*pl)->line, 5) == 0)
              {
                const char *p = (*pl)->line+5;
                while (*p == ' ' || *p == '\t')
                  p++;
                while (isdigit (*p))
                  p++;
                if (isdigit(p[-1]) && *p == '$') /* at least one digit */
                  {
                    /* this is a temp label for a pcall */
                    *pl = findLabel (*pl);
                    if (!*pl)
                      return S4O_ABORT;
                    break;
                  }

                ret = termScanAtFunc (*pl, rIdx);
                /* If it's a 'normal' 'caller save' function call, all
                   registers have been saved until the 'lcall'. The
                   'life range' of all registers end at the lcall,
                   and we can terminate our search.
                 * If the function is 'banked', the registers r0, r1 and r2
                   are used to tell the trampoline the destination. After
                   that their 'life range' ends just like the other registers.
                 * If it's a 'callee save' function call, registers are saved
                   by the callee. We've got no information, if the register
                   might live beyond the lcall. Therefore we've to continue
                   the search.
                */
                if (ret != S4O_CONTINUE)
                  return ret;
                break;
              }
            if (strncmp ("ljmp", (*pl)->line, 4) == 0)
              {
                *pl = findLabel (*pl);
                if (!*pl)
                  return S4O_ABORT;
              }
            break;
          case 'p':
            if (strncmp ("pop", (*pl)->line, 3) == 0 ||
                strncmp ("push", (*pl)->line, 4) == 0)
              return S4O_PUSHPOP;
            break;
          case 'r':
            if (strncmp ("reti", (*pl)->line, 4) == 0)
              return S4O_TERM;

            if (strncmp ("ret", (*pl)->line, 3) == 0)
              {
                /* pcall uses 'ret' */
                if (isFunc (*pl))
                  {
                    /* for comments see 'lcall' */
                    ret = termScanAtFunc (*pl, rIdx);
                    if (ret != S4O_CONTINUE)
                      return ret;
                    break;
                  }

                /* it's a normal function return */
                if (!((*pl)->ic) || (IS_SYMOP (IC_LEFT ((*pl)->ic)) &&
                    IS_FUNC (OP_SYM_TYPE(IC_LEFT ((*pl)->ic))) &&
                    FUNC_CALLEESAVES (OP_SYM_TYPE(IC_LEFT ((*pl)->ic)))))
                  return S4O_ABORT;
                else
                  return S4O_TERM;
              }
            break;
          case 's':
            if (strncmp ("sjmp", (*pl)->line, 4) == 0)
              {
                *pl = findLabel (*pl);
                if (!*pl)
                  return S4O_ABORT;
              }
            break;
          default:
            break;
        } /* switch ((*pl)->line[0]) */

      if (isConditionalJump)
        {
          *plCond = findLabel (*pl);
          if (!*plCond)
            return S4O_ABORT;
          return S4O_CONDJMP;
        }
    } /* for (; *pl; *pl = (*pl)->next) */
  return S4O_ABORT;
}
Example #13
0
/*-----------------------------------------------------------------*/
void
separateLiveRanges (iCode *sic, ebbIndex *ebbi)
{
  iCode *ic;
  set *candidates = 0;
  symbol *sym;

  // printf("separateLiveRanges()\n");

  for (ic = sic; ic; ic = ic->next)
    {
      if (ic->op == IFX || ic->op == GOTO || ic->op == JUMPTABLE || !IC_RESULT (ic) || !IS_ITEMP (IC_RESULT (ic)) || bitVectnBitsOn (OP_DEFS (IC_RESULT (ic))) <= 1 || isinSet (candidates, OP_SYMBOL (IC_RESULT (ic))))
        continue;

      addSet (&candidates, OP_SYMBOL (IC_RESULT (ic)));
    }

  if (!candidates)
    return;

  for(sym = setFirstItem (candidates); sym; sym = setNextItem (candidates))
    {
      // printf("Looking at %s, %d definitions\n", sym->name, bitVectnBitsOn (sym->defs));

      int i;
      set *defs = 0;

      for (i = 0; i < sym->defs->size; i++)
        if (bitVectBitValue (sym->defs, i))
          {
            iCode *dic;
            if(dic = hTabItemWithKey (iCodehTab, i))
              addSet (&defs, hTabItemWithKey (iCodehTab, i));
            else
              {
                werror (W_INTERNAL_ERROR, __FILE__, __LINE__, "Definition not found");
                return;
              }
          }

      do
        {
          set *visited = 0;
          set *newdefs = 0;
          int oldsize;

          wassert (defs);
          wassert (setFirstItem (defs));

          // printf("Looking at def at %d now\n", ((iCode *)(setFirstItem (defs)))->key);

          if (!bitVectBitValue (((iCode *)(setFirstItem (defs)))->rlive, sym->key))
            {
              werror (W_INTERNAL_ERROR, __FILE__, __LINE__, "Variable is not alive at one of its definitions");
              break;
            }
 
          visit (&visited, setFirstItem (defs), sym->key);
          addSet (&newdefs, setFirstItem (defs));

          do
            {
              oldsize = elementsInSet(visited);
              ic = setFirstItem (defs);
              for(ic = setNextItem (defs); ic; ic = setNextItem (defs))
                {
                  // printf("Looking at other def at %d now\n", ic->key);
                  set *visited2 = 0;
                  set *intersection = 0;
                  visit (&visited2, ic, sym->key);
                  intersection = intersectSets (visited, visited2, THROW_NONE);
                  intersection = subtractFromSet (intersection, defs, THROW_DEST);
                  if (intersection)
                    {
                      visited = unionSets (visited, visited2, THROW_DEST);
                      addSet (&newdefs, ic);
                    }
                  deleteSet (&intersection);
                  deleteSet (&visited2);
                }
             }
          while (oldsize < elementsInSet(visited));

          defs = subtractFromSet (defs, newdefs, THROW_DEST);

          if (newdefs && defs)
            {
              operand *tmpop = newiTempOperand (operandType (IC_RESULT ((iCode *)(setFirstItem (newdefs)))), TRUE);

              // printf("Splitting %s from %s, using def at %d, op %d\n", OP_SYMBOL_CONST(tmpop)->name, sym->name, ((iCode *)(setFirstItem (newdefs)))->key, ((iCode *)(setFirstItem (newdefs)))->op);

              for (ic = setFirstItem (visited); ic; ic = setNextItem (visited))
                {
                  if (IC_LEFT (ic) && IS_ITEMP (IC_LEFT (ic)) && OP_SYMBOL (IC_LEFT (ic)) == sym)
                    IC_LEFT (ic) = operandFromOperand (tmpop);
                  if (IC_RIGHT (ic) && IS_ITEMP (IC_RIGHT (ic)) && OP_SYMBOL (IC_RIGHT (ic)) == sym)
                      IC_RIGHT (ic) = operandFromOperand (tmpop);
                  if (IC_RESULT (ic) && IS_ITEMP (IC_RESULT (ic)) && OP_SYMBOL (IC_RESULT (ic)) == sym && !POINTER_SET(ic) && ic->next && !isinSet (visited, ic->next))
                    continue;
                  if (IC_RESULT (ic) && IS_ITEMP (IC_RESULT (ic)) && OP_SYMBOL (IC_RESULT (ic)) == sym)
                    {
                      bool pset = POINTER_SET(ic);
                      IC_RESULT (ic) = operandFromOperand (tmpop);
                      if (pset)
                        IC_RESULT(ic)->isaddr = TRUE;
                    }
                  bitVectUnSetBit (sym->uses, ic->key);
                }
            }
          deleteSet (&newdefs);
          deleteSet (&visited);
        }
      while (elementsInSet(defs) > 1);

      deleteSet (&defs);
    }

  deleteSet (&candidates);
}
Example #14
0
/*-----------------------------------------------------------------*/
void
dumpEbbsToFileExt (int id, ebbIndex * ebbi)
{
  FILE *of;
  int i;
  eBBlock *bb;
  set *cseSet;
  eBBlock ** ebbs = ebbi->dfOrder ? ebbi->dfOrder : ebbi->bbOrder;
  int count = ebbi->count;

  if (id) {
    of=createDumpFile(id);
  } else {
    of = stdout;
  }

  for (i = 0; i < count; i++)
    {
      fprintf (of, "\n----------------------------------------------------------------\n");
      fprintf (of, "Basic Block %s (df:%d bb:%d lvl:%d): loopDepth=%d%s%s%s\n",
               ebbs[i]->entryLabel->name,
               ebbs[i]->dfnum, ebbs[i]->bbnum, ebbs[i]->entryLabel->level,
               ebbs[i]->depth,
               ebbs[i]->noPath ? " noPath" : "",
               ebbs[i]->partOfLoop ? " partOfLoop" : "",
               ebbs[i]->isLastInLoop ? " isLastInLoop" : "");

      // a --nolabelopt makes this more readable
      fprintf (of, "\nsuccessors: ");
      for (bb=setFirstItem(ebbs[i]->succList);
           bb;
           bb=setNextItem(ebbs[i]->succList)) {
        fprintf (of, "%s ", bb->entryLabel->name);
      }
      fprintf (of, "\npredecessors: ");
      for (bb=setFirstItem(ebbs[i]->predList);
           bb;
           bb=setNextItem(ebbs[i]->predList)) {
        fprintf (of, "%s ", bb->entryLabel->name);
      }
      {
        int d;
        fprintf (of, "\ndominators: ");
        for (d=0; d<ebbs[i]->domVect->size; d++) {
          if (bitVectBitValue(ebbs[i]->domVect, d)) {
            fprintf (of, "%s ", ebbi->bbOrder[d]->entryLabel->name); //ebbs[d]->entryLabel->name);
          }
        }
      }
      fprintf (of, "\n");

      fprintf (of, "\ndefines bitVector :");
      bitVectDebugOn (ebbs[i]->defSet, of);
      fprintf (of, "\nlocal defines bitVector :");
      bitVectDebugOn (ebbs[i]->ldefs, of);
      fprintf (of, "\npointers Set bitvector :");
      bitVectDebugOn (ebbs[i]->ptrsSet, of);
#if 0
      fprintf (of, "\nin coming definitions :");
      bitVectDebugOn (ebbs[i]->inDefs, of);
      fprintf (of, "\nout going definitions :");
      bitVectDebugOn (ebbs[i]->outDefs, of);
      fprintf (of, "\ndefines used :");
      bitVectDebugOn (ebbs[i]->usesDefs, of);
#endif

      if (ebbs[i]->isLastInLoop) {
              fprintf (of, "\nInductions Set bitvector :");
              bitVectDebugOn (ebbs[i]->linds, of);
      }

      fprintf (of, "\ninExprs:");
      for (cseSet = ebbs[i]->inExprs; cseSet; cseSet=cseSet->next) {
        cseDef *item=cseSet->item;
        fprintf (of, " %s(%d)",OP_SYMBOL(item->sym)->name,item->diCode->key);
        if (item->fromGlobal)
          fprintf (of, "g");
      }
      fprintf (of, "\noutExprs:");
      for (cseSet = ebbs[i]->outExprs; cseSet; cseSet=cseSet->next) {
        cseDef *item=cseSet->item;
        fprintf (of, " %s(%d)",OP_SYMBOL(item->sym)->name,item->diCode->key);
        if (item->fromGlobal)
          fprintf (of, "g");
      }
      fprintf (of, "\nkilledExprs:");
      for (cseSet = ebbs[i]->killedExprs; cseSet; cseSet=cseSet->next) {
        cseDef *item=cseSet->item;
        fprintf (of, " %s(%d)",OP_SYMBOL(item->sym)->name,item->diCode->key);
        if (item->fromGlobal)
          fprintf (of, "g");
      }

      fprintf (of, "\n----------------------------------------------------------------\n");
      printiCChain (ebbs[i]->sch, of);
    }
  fflush(of);
}
Example #15
0
/*-----------------------------------------------------------------*/
static int
findNextUseSym (eBBlock *ebp, iCode *ic, symbol * sym)
{
  int retval = 0;
  iCode *uic;
  eBBlock *succ;

  hTabAddItemIfNotP (&liveRanges, sym->key, sym);

  if (!ic)
    goto check_successors;

  /* if we check a complete block and the symbol */
  /* is alive at the beginning of the block */
  /* and not defined in the first instructions */
  /* then a next use exists (return 1) */
  if ((ic == ebp->sch) && bitVectBitValue(ic->rlive, sym->key))
    {
      /* check if the first instruction is a def of this op */
      if (ic->op == JUMPTABLE || ic->op == IFX || SKIP_IC2(ic))
        return 1;

      if (IS_ITEMP(IC_RESULT(ic)))
        if (IC_RESULT(ic)->key == sym->key)
          return 0;

      return 1;
    }

  if (ebp->visited)
    return 0;

  if (ic == ebp->sch)
    ebp->visited = 1;

  /* for all remaining instructions in current block */
  for (uic = ic; uic; uic = uic->next)
    {

      if (SKIP_IC2(uic))
        continue;

      if (uic->op == JUMPTABLE)
        {
          if (IS_ITEMP(IC_JTCOND(uic)) && IC_JTCOND(uic)->key == sym->key)
            {
	      markAlive(ic, uic, sym->key);
	      return 1;
	    }
	   continue;
	}

      if (uic->op == IFX)
        {
          if (IS_ITEMP(IC_COND(uic)) && IC_COND(uic)->key == sym->key)
            {
	      markAlive(ic, uic, sym->key);
	      return 1;
	    }
	   continue;
	}

      if (IS_ITEMP (IC_LEFT (uic)))
        if (IC_LEFT (uic)->key == sym->key)
          {
	    markAlive(ic, uic, sym->key);
	    return 1;
	  }

      if (IS_ITEMP (IC_RIGHT (uic)))
        if (IC_RIGHT (uic)->key == sym->key)
	  {
	    markAlive (ic, uic, sym->key);
	    return 1;
	  }

      if (IS_ITEMP (IC_RESULT (uic)))
        if (IC_RESULT (uic)->key == sym->key)
	  {
	    if (POINTER_SET (uic))
	      {
	        markAlive (ic, uic, sym->key);
                return 1;
	      }
	    else
	      return 0;
	  }

    }

  /* check all successors */
check_successors:

  succ = setFirstItem (ebp->succList);
  for (; succ; succ = setNextItem (ebp->succList))
    {
      retval += findNextUseSym (succ, succ->sch, sym);
    }

  if (retval)
    {
      if (ic) markAlive (ic, ebp->ech, sym->key);
      return 1;
    }

  return 0;
}
Example #16
0
/*-----------------------------------------------------------------*/
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));
	}

    }
}
Example #17
0
/*-----------------------------------------------------------------*/
static void
computeClash (eBBlock ** ebbs, int count)
{
  int i;

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

      /* for every iCode do */
      for (ic = ebbs[i]->sch; ic; ic = ic->next)
	{
	  symbol *sym1, *sym2;
	  int key1, key2;

	  /* for all iTemps alive at this iCode */
	  for (key1 = 1; key1 < ic->rlive->size; key1++)
	    {
	      if (!bitVectBitValue(ic->rlive, key1))
	        continue;

	      sym1 = hTabItemWithKey(liveRanges, key1);

	      if (!sym1->isitmp)
	        continue;

	      /* for all other iTemps alive at this iCode */
	      for (key2 = key1+1; key2 < ic->rlive->size; key2++)
	        {
		  if (!bitVectBitValue(ic->rlive, key2))
		    continue;

		  sym2 = hTabItemWithKey(liveRanges, key2);

		  if (!sym2->isitmp)
		    continue;

		  /* if the result and left or right is an iTemp */
		  /* than possibly the iTemps do not clash */
		  if ((ic->op != JUMPTABLE) && (ic->op != IFX) &&
		      IS_ITEMP(IC_RESULT(ic)) &&
		      (IS_ITEMP(IC_LEFT(ic)) || IS_ITEMP(IC_RIGHT(ic))))
		    {
		      if (OP_SYMBOL(IC_RESULT(ic))->key == key1
			  && sym1->liveFrom == ic->seq
			  && sym2->liveTo == ic->seq)
		        {
		          if (IS_SYMOP(IC_LEFT(ic)))
			    if (OP_SYMBOL(IC_LEFT(ic))->key == key2)
			      continue;
		          if (IS_SYMOP(IC_RIGHT(ic)))
			    if (OP_SYMBOL(IC_RIGHT(ic))->key == key2)
			      continue;
			}

		      if (OP_SYMBOL(IC_RESULT(ic))->key == key2
			  && sym2->liveFrom == ic->seq
			  && sym1->liveTo == ic->seq)
		        {
		          if (IS_SYMOP(IC_LEFT(ic)))
			    if (OP_SYMBOL(IC_LEFT(ic))->key == key1)
			      continue;
		          if (IS_SYMOP(IC_RIGHT(ic)))
			    if (OP_SYMBOL(IC_RIGHT(ic))->key == key1)
			      continue;
			}
		    }

		  /* the iTemps do clash. set the bits in clashes */
		  sym1->clashes = bitVectSetBit (sym1->clashes, key2);
		  sym2->clashes = bitVectSetBit (sym2->clashes, key1);

		  /* check if they share the same spill location */
		  /* what is this good for? */
	          if (SYM_SPIL_LOC(sym1) && SYM_SPIL_LOC(sym2) &&
		      SYM_SPIL_LOC(sym1) == SYM_SPIL_LOC(sym2))
		    {
		      if (sym1->reqv && !sym2->reqv) SYM_SPIL_LOC(sym2)=NULL;
		      else if (sym2->reqv && !sym1->reqv) SYM_SPIL_LOC(sym1)=NULL;
		      else if (sym1->used > sym2->used) SYM_SPIL_LOC(sym2)=NULL;
		      else SYM_SPIL_LOC(sym1)=NULL;
		    }
		}
	    }
	}
    }
}