Пример #1
0
/*-----------------------------------------------------------------*/
void
replaceSymBySym (set * sset, operand * src, operand * dest)
{
  set *loop;
  eBBlock *rBlock;

  /* for all blocks in the set do */
  for (loop = sset; loop; loop = loop->next)
    {
      iCode *ic;

      rBlock = loop->item;
      /* for all instructions in this block do */
      for (ic = rBlock->sch; ic; ic = ic->next)
        {

          /* if we find usage */
          if (ic->op == IFX && isOperandEqual (src, IC_COND (ic)))
            {
              bitVectUnSetBit (OP_USES (IC_COND (ic)), ic->key);
              IC_COND (ic) = operandFromOperand (dest);
              OP_USES (dest) = bitVectSetBit (OP_USES (dest), ic->key);
              continue;
            }

          if (isOperandEqual (IC_RIGHT (ic), src))
            {
              bitVectUnSetBit (OP_USES (IC_RIGHT (ic)), ic->key);
              IC_RIGHT (ic) = operandFromOperand (dest);
              IC_RIGHT (ic)->isaddr = 0;
              OP_USES (dest) = bitVectSetBit (OP_USES (dest), ic->key);
            }

          if (isOperandEqual (IC_LEFT (ic), src))
            {
              bitVectUnSetBit (OP_USES (IC_LEFT (ic)), ic->key);
              if (POINTER_GET (ic) && IS_ITEMP (dest))
                {
                  IC_LEFT (ic) = operandFromOperand (dest);
                  IC_LEFT (ic)->isaddr = 1;
                }
              else
                {
                  IC_LEFT (ic) = operandFromOperand (dest);
                  IC_LEFT (ic)->isaddr = 0;
                }
              OP_USES (dest) = bitVectSetBit (OP_USES (dest), ic->key);
            }

          /* special case for pointer sets */
          if (POINTER_SET (ic) && isOperandEqual (IC_RESULT (ic), src))
            {
              bitVectUnSetBit (OP_USES (IC_RESULT (ic)), ic->key);
              IC_RESULT (ic) = operandFromOperand (dest);
              IC_RESULT (ic)->isaddr = 1;
              OP_USES (dest) = bitVectSetBit (OP_USES (dest), ic->key);
            }
        }
    }
}
Пример #2
0
static int pattern1 (iCode *sic)
{
        /* this is what we do. look for sequences like

        iTempX := _SOME_POINTER_;
        iTempY := _SOME_POINTER_ + nn ;   nn  = sizeof (pointed to object)      sic->next
        _SOME_POINTER_ := iTempY;                                               sic->next->next
        either       
        iTempZ := @[iTempX];                                                    sic->next->next->next
        or
        *(iTempX) := ..something..                                              sic->next->next->next
        if we find this then transform this to
        iTempX := _SOME_POINTER_;
        either       
        iTempZ := @[iTempX];
        or 
        *(iTempX) := ..something..
        iTempY := _SOME_POINTER_ + nn ;   nn  = sizeof (pointed to object)
        _SOME_POINTER_ := iTempY; */
        
        /* sounds simple enough so let's start , here I use negative
           tests all the way to return if any test fails */
        iCode *pgs, *sh, *st;

        if (!(sic->next && sic->next->next && sic->next->next->next))
                return 0;
        if (sic->next->op != '+' && sic->next->op != '-')
                return 0;
        if (!(sic->next->next->op == '=' &&
              !POINTER_SET (sic->next->next)))
                return 0;
        if (!isOperandEqual (IC_LEFT (sic->next), IC_RIGHT (sic)) ||
            !IS_OP_LITERAL (IC_RIGHT (sic->next)))
                return 0;
        if (operandLitValue (IC_RIGHT (sic->next)) !=
            getSize (operandType (IC_RIGHT (sic))->next))
                return 0;
        if (!isOperandEqual (IC_RESULT (sic->next->next),
                             IC_RIGHT (sic)))
                return 0;
        if (!isOperandEqual (IC_RESULT (sic->next), IC_RIGHT (sic->next->next)))
                return 0;
        if (!(pgs = findPointerGetSet (sic->next->next, IC_RESULT (sic))))
                return 0;

        /* found the pattern .. now do the transformation */
        sh = sic->next;
        st = sic->next->next;

        /* take the two out of the chain */
        sic->next = st->next;
        st->next->prev = sic;

        /* and put them after the pointer get/set icode */
        if ((st->next = pgs->next))
                st->next->prev = st;
        pgs->next = sh;
        sh->prev = pgs;
        return 1;
}
Пример #3
0
/*-----------------------------------------------------------------------*/
static iCode *
findPointerGetSet (iCode * sic, operand * op)
{
  iCode *ic = sic;

  for (; ic; ic = ic->next)
    {
      if ((POINTER_SET (ic) && isOperandEqual (op, IC_RESULT (ic))) ||
          (POINTER_GET (ic) && isOperandEqual (op, IC_LEFT (ic))))
        return ic;

      /* if we find any other usage or definition of op null */
      if (IC_RESULT (ic) && isOperandEqual (IC_RESULT (ic), op))
        return NULL;

      if (IC_RIGHT (ic) && isOperandEqual (IC_RIGHT (ic), op))
        return NULL;

      if (IC_LEFT (ic) && isOperandEqual (IC_LEFT (ic), op))
        return NULL;

    }

  return NULL;
}
Пример #4
0
static int pattern2 (iCode *sic)
{
        /* this is what we do. look for sequences like

        iTempX := _SOME_POINTER_;
        iTempY := _SOME_POINTER_ + nn ;   nn  = sizeof (pointed to object)      sic->next
        iTempK := iTempY;                                                       sic->next->next
        _SOME_POINTER_ := iTempK;                                               sic->next->next->next
        either       
        iTempZ := @[iTempX];                                                    sic->next->next->next->next
        or
        *(iTempX) := ..something..                                              sic->next->next->next->next
        if we find this then transform this to
        iTempX := _SOME_POINTER_;
        either       
        iTempZ := @[iTempX];
        or 
        *(iTempX) := ..something..
        iTempY := _SOME_POINTER_ + nn ;   nn  = sizeof (pointed to object)
        iTempK := iTempY;       
        _SOME_POINTER_ := iTempK; */
        
        /* sounds simple enough so let's start , here I use negative
           tests all the way to return if any test fails */
        iCode *pgs, *sh, *st;

        if (!(sic->next && sic->next->next && sic->next->next->next && 
              sic->next->next->next->next))
                return 0;

        /* yes I can OR them together and make one large if... but I have
           simple mind and like to keep things simple & readable */
        if (!(sic->next->op == '+' || sic->next->op == '-')) return 0;
        if (!isOperandEqual(IC_RIGHT(sic),IC_LEFT(sic->next))) return 0;
        if (!IS_OP_LITERAL (IC_RIGHT (sic->next))) return 0;
        if (operandLitValue (IC_RIGHT (sic->next)) !=
            getSize (operandType (IC_RIGHT (sic))->next)) return 0;
        if (!IS_ASSIGN_ICODE(sic->next->next)) return 0;
        if (!isOperandEqual(IC_RIGHT(sic->next->next),IC_RESULT(sic->next))) return 0;
        if (!IS_ASSIGN_ICODE(sic->next->next->next)) return 0;
        if (!isOperandEqual(IC_RIGHT(sic->next->next->next),IC_RESULT(sic->next->next))) return 0;
        if (!isOperandEqual(IC_RESULT(sic->next->next->next),IC_LEFT(sic->next))) return 0;
        if (!(pgs = findPointerGetSet (sic->next->next->next, IC_RESULT (sic)))) return 0;
        
        /* found the pattern .. now do the transformation */
        sh = sic->next;
        st = sic->next->next->next;

        /* take the three out of the chain */
        sic->next = st->next;
        st->next->prev = sic;

        /* and put them after the pointer get/set icode */
        if ((st->next = pgs->next))
                st->next->prev = st;
        pgs->next = sh;
        sh->prev = pgs;
        return 1;
}
Пример #5
0
/*-----------------------------------------------------------------*/
iCode *
usedInRemaining (operand * op, iCode * ic)
{
  iCode *lic = ic;

  if (!IS_SYMOP (op))
    return 0;

  for (; lic; lic = lic->next)
    {

      /* if the operand is a parameter */
      /* then check for calls and return */
      /* true if there is a call       */
      /* if this is a global variable then 
         return true */
      if (lic->op == CALL || lic->op == PCALL)
	{

	  if ((IS_PARM (op) &&
	       isParameterToCall (IC_ARGS (lic), op)) ||
	      isOperandGlobal (op))
	    return lic;
	}

      if (ic->op == SEND &&
	  isOperandEqual (IC_LEFT (lic), op))
	return lic;

      if (SKIP_IC1 (lic))
	continue;

      /* if ifx then check the condition */
      if (lic->op == IFX &&
	  isOperandEqual (IC_COND (lic), op))
	return lic;

      if (lic->op == JUMPTABLE &&
	  isOperandEqual (IC_JTCOND (lic), op))
	return lic;

      if (IC_RIGHT (lic) &&
	  isOperandEqual (IC_RIGHT (lic), op))
	return lic;

      if (IC_LEFT (lic) &&
	  isOperandEqual (IC_LEFT (lic), op))
	return lic;

      /* for a pointer assignment usage */
      if (POINTER_SET (lic) &&
	  isOperandEqual (op, IC_RESULT (lic)))
	return lic;
      else if (IC_RESULT (lic) && isOperandEqual (IC_RESULT (lic), op))
	return NULL;
    }

  return NULL;
}
Пример #6
0
static void forward_lospre_assignment(G_t &G, typename boost::graph_traits<G_t>::vertex_descriptor i, const iCode *ic, const assignment_lospre& a)
{
  typedef typename boost::graph_traits<G_t>::adjacency_iterator adjacency_iter_t;

  adjacency_iter_t c, c_end;

  operand *tmpop = IC_RIGHT(ic);
  const std::pair<int, int> forward(IC_RESULT(ic)->key, IC_RIGHT(ic)->key);

  for(;;)
    {
      if (G[i].forward == forward)
        break; // Was here before.

      iCode *nic = G[i].ic;

      if (isOperandEqual(IC_RESULT(ic), IC_LEFT(nic)) && nic->op != ADDRESS_OF && (!POINTER_GET(nic) || !IS_PTR(operandType(IC_RESULT(nic))) || !IS_BITFIELD(operandType(IC_LEFT(nic))->next) || compareType(operandType(IC_LEFT(nic)), operandType(tmpop)) == 1))
        {
          bool isaddr = IC_LEFT (nic)->isaddr;
#ifdef DEBUG_LOSPRE
          std::cout << "Forward substituted left operand " << OP_SYMBOL_CONST(IC_LEFT(nic))->name << " at " << nic->key << "\n";
#endif
          //bitVectUnSetBit (OP_SYMBOL (IC_LEFT (nic))->uses, nic->key);
          IC_LEFT(nic) = operandFromOperand (tmpop);
          //bitVectSetBit (OP_SYMBOL (IC_LEFT (nic))->uses, nic->key);
          IC_LEFT (nic)->isaddr = isaddr;
        }
      if (isOperandEqual(IC_RESULT(ic), IC_RIGHT(nic)))
        {
#ifdef DEBUG_LOSPRE
          std::cout << "Forward substituted right operand " << OP_SYMBOL_CONST(IC_RIGHT(nic))->name << " at " << nic->key << "\n";
#endif
          //bitVectUnSetBit (OP_SYMBOL (IC_RIGHT (nic))->uses, nic->key);
          IC_RIGHT(nic) = operandFromOperand (tmpop);
          //bitVectSetBit (OP_SYMBOL (IC_RIGHT (nic))->uses, nic->key);
        }
      if (POINTER_SET(nic) && isOperandEqual(IC_RESULT(ic), IC_RESULT(nic)) && (!IS_PTR(operandType(IC_RESULT(nic))) || !IS_BITFIELD(operandType(IC_RESULT(nic))->next) || compareType(operandType(IC_RESULT(nic)), operandType(tmpop)) == 1))
        {
#ifdef DEBUG_LOSPRE
          std::cout << "Forward substituted result operand " << OP_SYMBOL_CONST(IC_RESULT(nic))->name << " at " << nic->key << "\n";
#endif
          //bitVectUnSetBit (OP_SYMBOL (IC_RESULT (nic))->uses, nic->key);
          IC_RESULT(nic) = operandFromOperand (tmpop);
          IC_RESULT(nic)->isaddr = true;
          //bitVectSetBit (OP_SYMBOL (IC_RESULT (nic))->uses, nic->key);
        }

      if (nic->op == LABEL) // Reached label. Continue only if all edges goining here are safe.
        {
          typedef typename boost::graph_traits<G_t>::in_edge_iterator in_edge_iter_t;
          in_edge_iter_t e, e_end;
          for (boost::tie(e, e_end) = boost::in_edges(i, G); e != e_end; ++e)
            if (G[boost::source(*e, G)].forward != forward)
              break;
          if(e != e_end)
            break;
        }
      if (isOperandEqual(IC_RESULT (ic), IC_RESULT(nic)) && !POINTER_SET(nic) /*|| G[i].uses*/)
        break;
      if ((nic->op == CALL || nic->op == PCALL || POINTER_SET(nic)) && IS_TRUE_SYMOP(IC_RESULT(ic)))
        break;

      G[i].forward = forward;

      if (nic->op == GOTO || nic->op == IFX || nic->op == JUMPTABLE)
        {
          adjacency_iter_t c, c_end;
          for(boost::tie(c, c_end) = boost::adjacent_vertices(i, G); c != c_end; ++c)
            {
              if(!((a.global[i] & true) && !G[i].invalidates) && (a.global[*c] & true)) // Calculation edge
                continue;
              forward_lospre_assignment(G, *c, ic, a);
            }
          break;
        }

      boost::tie(c, c_end) = adjacent_vertices(i, G);
      if(c == c_end)
        break;
      if(!((a.global[i] & true) && !G[i].invalidates) && (a.global[*c] & true)) // Calculation edge
        break;
      i = *c;
    }
}