Esempio n. 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);
            }
        }
    }
}
Esempio n. 2
0
static int implement_lospre_assignment(const assignment_lospre a, T_t &T, G_t &G, const iCode *ic) // Assignment has to be passed as a copy (not reference), since the transformations on the tree-decomposition will invalidate it otherwise.
{
  operand *tmpop;
  unsigned substituted = 0, split = 0;

  typedef typename boost::graph_traits<G_t>::edge_iterator edge_iter_t;
  typedef typename boost::graph_traits<G_t>::edge_descriptor edge_desc_t;
  std::set<edge_desc_t> calculation_edges; // Use descriptor, not iterator due to possible invalidation of iterators when inserting vertices or edges.
  edge_iter_t e, e_end;
  for(boost::tie(e, e_end) = boost::edges(G); e != e_end; ++e)
    if(!((a.global[boost::source(*e, G)] & true) && !G[boost::source(*e, G)].invalidates) && (a.global[boost::target(*e, G)] & true))
      calculation_edges.insert(*e);

  if(!calculation_edges.size())
    return(0);

#ifdef DEBUG_LOSPRE
  std::cout << "Optimizing at " << ic->key << "\n"; std::cout.flush();
#endif

  tmpop = newiTempOperand (operandType (IC_RESULT (ic)), TRUE);
  tmpop->isvolatile = false;
#ifdef DEBUG_LOSPRE
  std::cout << "New tmpop: " << OP_SYMBOL_CONST(tmpop)->name << " "; printTypeChain(operandType (IC_RESULT(ic)), stdout); std::cout << "\n";
#endif

  for(typename std::set<edge_desc_t>::iterator i = calculation_edges.begin(); i != calculation_edges.end(); ++i)
  {
    split_edge(T, G, *i, ic, tmpop);
    split++;
  }

  typedef typename boost::graph_traits<G_t>::vertex_iterator vertex_iter_t;
  vertex_iter_t v, v_end;

  for(boost::tie(v, v_end) = boost::vertices(G); v != v_end; ++v)
    {
      if(!G[*v].uses)
        continue;
      typename boost::graph_traits<G_t>::in_edge_iterator e = in_edges(*v, G).first;
      if (a.global.size() <= *v)
        continue;
      if(!((a.global[*v] & true) && !G[*v].invalidates || boost::source(*e, G) < a.global.size() && (a.global[boost::source(*e, G)] & true)))
        continue;
#ifdef DEBUG_LOSPRE
      std::cout << "Substituting ic " << G[*v].ic->key << "\n";
#endif
      substituted++;

      iCode *ic = G[*v].ic;
      //if (IC_LEFT (ic) && IS_ITEMP (IC_LEFT (ic)))
      //  bitVectUnSetBit (OP_SYMBOL (IC_LEFT (ic))->uses, ic->key);
      //if (IC_RIGHT (ic) && IS_ITEMP (IC_RIGHT (ic)))
       // bitVectUnSetBit (OP_SYMBOL (IC_RIGHT (ic))->uses, ic->key);
      IC_RIGHT(ic) = tmpop;
      //bitVectSetBit (OP_SYMBOL (IC_RIGHT(ic))->uses, ic->key);
      if (!POINTER_SET (ic))
        {
          IC_LEFT(ic) = 0;
          ic->op = '=';
          IC_RESULT(ic) = operandFromOperand (IC_RESULT (ic));
          IC_RESULT(ic)->isaddr = 0;
        }
      if(IS_OP_VOLATILE(IC_RESULT (ic)))
        continue;

      {
        typedef typename boost::graph_traits<G_t>::adjacency_iterator adjacency_iter_t;
        adjacency_iter_t c, c_end;
        boost::tie(c, c_end) = adjacent_vertices(*v, G);
        if (c != c_end)
          forward_lospre_assignment(G, *c, ic, a);
      }
    }

  if(substituted <= 0)
    {
      std::cerr << "Introduced " << OP_SYMBOL_CONST(tmpop)->name << ", but did not substitute any calculations.\n";
      return (-1);
    }

  if(substituted < split) // Todo: Remove this warning when optimization for speed instead of code size is implemented!
    std::cout << "Introduced " << OP_SYMBOL_CONST(tmpop)->name << ", but did substitute only " << substituted << " calculations, while introducing "<< split << ".\n"; std::cout.flush();

  return(1);
}
Esempio n. 3
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;
    }
}
Esempio n. 4
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);
}