Exemple #1
0
static void
AddExtensionFields (FGraph graph)
{
  Node ptr;
  Arc arc;
  struct Ext *ext;
  int change;
  Set all;
  FreeExtensionFields ();
  if (graph->nodes == 0)
    return;
  if (graph->root == 0)
    Punt ("no root node");
  all = 0;
  for (ptr = graph->nodes; ptr != 0; ptr = nextNode (ptr))
    {
      nodeExt (ptr) = (others + n_others);
      others[n_others].dominator = 0;
      others[n_others].level = -1;
      others[n_others].order = n_others;
      all = Set_add (all, n_others);
      n_others += 1;
    }
  ext = (struct Ext *) nodeExt (graph->root);
  ext->level = 0;
  ext->dominator = Set_add (0, ext->order);
  for (ptr = graph->nodes; ptr != 0; ptr = nextNode (ptr))
    {
      if (ptr == graph->root)
        continue;
      ext = (struct Ext *) nodeExt (ptr);
      ext->dominator = Set_union (0, all);
    }
  /*
   *  compute dominators.
   */
  change = 1;
  while (change != 0)
    {
      change = 0;
      for (ptr = graph->nodes; ptr != 0; ptr = nextNode (ptr))
        {
          Set dom, temp;
          if (ptr == graph->root)
            continue;
          arc = sourceArcs (ptr);
          if (arc == 0)
            {
              dom = 0;
            }
          else
            {
              dom = Set_union (all, 0);
              for (; arc != 0; arc = nextArc (arc))
                {
                  ext = (struct Ext *) nodeExt (sourceNode (arc));
                  temp = Set_intersect (dom, ext->dominator);
                  Set_dispose (dom);
                  dom = temp;
                  temp = 0;
                }
              ext = (struct Ext *) nodeExt (ptr);
              dom = Set_add (dom, ext->order);
              if (Set_same (dom, ext->dominator))
                {
                  Set_dispose (dom);
                }
              else
                {
                  Set_dispose (ext->dominator);
                  ext->dominator = dom;
                  change += 1;
                }
            }
        }
    }
  all = Set_dispose (all);
  /*
   *  compute level.
   */
  change = 1;
  while (change != 0)
    {
      change = 0;
      for (ptr = graph->nodes; ptr != 0; ptr = nextNode (ptr))
        {
          int max;
          ext = (struct Ext *) nodeExt (ptr);
          if (ext->level >= 0)
            continue;
          max = -1;
          for (arc = sourceArcs (ptr); arc != 0; arc = arc->next)
            {
              Node src;
              struct Ext *ex;
              src = sourceNode (arc);
              ex = (struct Ext *) nodeExt (src);
              /* ignore back-edges */
              if (ex->order >= ext->order)
                continue;
              if (ex->level < 0)
                break;
              if (ex->level > max)
                max = ex->level;
            }
          if (arc == 0)
            {                   /* all source have been visited */
              ext->level = max + 1;
              change += 1;
            }
        }
    }
#ifdef DEBUG
  printf ("--------------------------------------------------\n");
  for (ptr = graph->nodes; ptr != 0; ptr = nextNode (ptr))
    {
      ext = nodeExt (ptr);
      printf ("# id=%d, order=%d, level=%d, ",
              ptr->id, ext->order, ext->level);
      PrintSet (stdout, "dominator", ext->dominator);
    }
#endif
}
int
L_global_memflow_multiloadstore_load (L_Func * fn, L_Cb * cb, L_Oper * oper)
{
  return 0;

#if 0
  int change = 0;
  Set RAMB_ST, RAMB_JSR;
  Set RDEF_ST, RDEF_LD;

  if (!L_general_load_opcode (oper))
    return 0;

  /* 02/07/03 REK Adding a check to make sure we don't touch a volatile
   *              oper. */
  if (L_EXTRACT_BIT_VAL (oper->flags, L_OPER_VOLATILE))
    return 0;

  RDEF_ST = NULL;
  RDEF_LD = NULL;
  RAMB_ST = NULL;
  RAMB_JSR = NULL;

  /* Get all reaching stores */
  RDEF_ST =
    L_get_mem_oper_RIN_defining_opers (oper, (MDF_RET_DEP | MDF_RET_STORES));

  /* Get all reaching loads */
  RDEF_LD =
    L_get_mem_oper_RIN_defining_opers (oper, (MDF_RET_DEP | MDF_RET_LOADS));

  if (!Set_size (RDEF_LD) || !Set_size (RDEF_ST))
    return change;


  fprintf (stderr, "\n\nMFMLSL: Examining load %d\n", oper->id);

  /* Are there any reaching, ambiguous stores */
  RAMB_ST =
    L_get_mem_oper_RIN_defining_opers (oper, (MDF_RET_AMB | MDF_RET_STORES));

  /* Are there any reaching, unsafe jsrs */
  RAMB_JSR =
    L_get_mem_oper_RIN_defining_opers (oper, (MDF_RET_AMB | MDF_RET_JSRS));

  fprintf (stderr, "MFMLSL: Dep Stores reach load %d ", oper->id);
  Set_print (stderr, "MSMLSL: ", RDEF_ST);
  fprintf (stderr, "MFMLSL: Dep Loads reach load %d ", oper->id);
  Set_print (stderr, "MSMLSL: ", RDEF_LD);
  fprintf (stderr, "MFMLSL: Amb Stores reach load %d ", oper->id);
  Set_print (stderr, "MSMLSL: ", RAMB_ST);
  fprintf (stderr, "MFMLSL: Unsafe jsrs reach load %d ", oper->id);
  Set_print (stderr, "MSMLSL: ", RAMB_JSR);

  if (!L_load_compatible_each_store (fn, oper, RDEF_ST))
    {
      fprintf (stderr, "MFMLSL: Load is incompatible with a store\n");
      Set_dispose (RDEF);
      Set_dispose (RDEF_LD);
      Set_dispose (RAMB_ST);
      Set_dispose (RAMB_JSR);
      return change;
    }

  if (!L_load_compatible_each_load (fn, oper, RDEF_LD))
    {
      fprintf (stderr, "MFMLSL: Load is incompatible with a store\n");
      Set_dispose (RDEF);
      Set_dispose (RDEF_LD);
      Set_dispose (RAMB_ST);
      Set_dispose (RAMB_JSR);
      return change;
    }

  if (!L_store_union_dominates_load
      (fn, cb, oper, Set_union (RDEF_LD, RDEF_ST)))
    {
      fprintf (stderr,
               "MFMLSL: Path to load exists not through a store/load\n");
      Set_dispose (RDEF);
      Set_dispose (RDEF_LD);
      Set_dispose (RAMB_ST);
      Set_dispose (RAMB_JSR);
      return change;
    }

  if (!L_loadstore_union_postdominates_amb (fn, cb, oper,
                                            Set_union (RDEF_LD, RDEF_ST),
                                            Set_union (RAMB_ST, RAMB_JSR)))
    {
      fprintf (stderr, "MFMLSL: A amb st/jsr lies between ld/st and load \n");
      Set_dispose (RDEF);
      Set_dispose (RDEF_LD);
      Set_dispose (RAMB_ST);
      Set_dispose (RAMB_JSR);
      return change;
    }


  /* Load can be removed, moves added */
  fprintf (stderr, "MFMLSL: red Load %d can be converted\n", oper->id);

  Set_dispose (RDEF);
  Set_dispose (RDEF_LD);
  Set_dispose (RAMB_ST);
  Set_dispose (RAMB_JSR);
  return change;
#endif
}
Exemple #3
0
int main() {
    //Set console default size.
    system(CONSOLE_SIZE);
    //Testing fields
    int testSize = 10;
    Set_T * mainSet = Set_new(testSize);

    //Fill the set
    Set_fill(mainSet);
    //Print it out
    puts("**********");
    printf("Creating a new set...\n"
           "Filling it with non-repeatable numbers...\n");
    Set_print(mainSet);
    puts("**********");
    //Get some elements
    printf("Getting element on the index 4...\n");
    int test_a = Set_getValueAt(mainSet,4);
    printf("Element with the index 4 is %d\n", test_a);
    printf("Getting element on the index 10...\n");
    int test_b = Set_getValueAt(mainSet,10);
    printf("Element with the index 10 is %d\n", test_b);
    //Set some elements
    printf("Setting element with index 3 to \"123\"\n");
    Set_setValueAt(mainSet, 3, 123);
    printf("Setting element with index 10 to \"123\"\n");
    Set_setValueAt(mainSet, 10, 123);
    //Print set again
    puts("**********");
    Set_print(mainSet);
    //Delete some elements
    printf("Deleting element index 3\n");
    Set_removeValueAt(mainSet, 3);

    //Print the set again
    puts("**********");
    Set_print(mainSet);
    //In the end - free allocated memory
    puts("----------------------------------------------------------------------");
    printf("Creating two more sets.\n");
    Set_T * first = Set_new(testSize+1);
    Set_T * second = Set_new(testSize+4); //15
    Set_fill(first);
    Set_fill(second);
    puts("**********");
    printf("First set:\n");
    Set_print(first);
    printf("Second set:\n");
    Set_print(second);
    puts("**********");
    printf("Union with the first set and the second set.\n");
    Set_T * test_unionSet = Set_union(first, second);
    printf("The 'union' set:\n");
    Set_print(test_unionSet);
    puts("**********");
    printf("Intersection with the first and the second set.\n");
    Set_T * test_intersectionSet = Set_intersection(first, second);
    printf("The 'intersection' set:\n");
    Set_print(test_intersectionSet);
    puts("**********");
    printf("Difference between the first and the second set.\n");
    for(int i = 0; i < Set_getSize(first); i++) {
        Set_setValueAt(first, i, 8+i);
    }
    printf("Changed first set:\n");
    Set_print(first);
    Set_T * test_differenceSet = Set_difference(first, second);
    printf("The 'difference' set:\n");
    Set_print(test_differenceSet);
    puts("**********");
    //free allocated memory
    Set_delete(first);
    Set_delete(second);
    Set_delete(mainSet);
    Set_delete(test_unionSet);
    Set_delete(test_intersectionSet);
    Set_delete(test_differenceSet);
    puts("allocated memory was deleted.");
    return (0);
}
Exemple #4
0
/*! \brief Finds loops in the CFG. Builds lp hdr, body and exit bb sets, and 
 *   puts this lp info in a PC_Loop struct, which is appended to the CFG lp list.
 *
 * \param cfg
 *  control flow graph for the func being processed
 *
 *  Multiple back edges coming into the same loop header are considered as one
 *  loop. The loop body is a union of the bodies of the loops corresponding to 
 *  each one of these back edges. 
 *
 * \return void
 */
void
PC_FindLoops (PC_Graph cfg)
{
  PC_Block h_bb;

  /* build dominator sets for each bb in the cfg */
  PC_BuildDomSets (cfg);

  /* check each cfg bb in turn to see if it's a lp header bb */
  for (h_bb = cfg->first_bb; h_bb; h_bb = h_bb->next)
    {
      PC_Flow be;
      PC_Loop *loop;
      int num_back_edge;
      int num_exit;
      int s_lp_head = -1;
      Set s_lp_body = Set_new (), s_lp_exits = Set_new ();

      /* check all edges coming into h_bb to see if they are back edges */
      num_back_edge = 0;
      for (be = h_bb->p_flow; be; be = be->p_next_flow)
	{
	  /* check to see if be is indeed a back edge */
	  if (PC_BB1DominatesBB2 (be->dest_bb, be->src_bb))
	    {
	      PC_Block bb;
	      Stack *st = New_Stack ();
	      Set lp_body = Set_new ();

              num_back_edge++;
	      s_lp_head = be->dest_bb->ID;

	      if (be->src_bb->ID == be->dest_bb->ID)
		P_warn
		  ("PC_FindNaturalLoop: back edge head & tail are same.");


	      /* Build the set of all bbs in the lp body. */
	      lp_body = Set_add (lp_body, s_lp_head);

	      if (!Set_in (lp_body, be->src_bb->ID))
		{
		  lp_body = Set_add (lp_body, be->src_bb->ID);
		  Push_Top (st, be->src_bb);
		}

	      while ((bb = Pop (st)) != ((void*)-1))
		{
		  PC_Flow fl;
		  for (fl = bb->p_flow; fl; fl = fl->p_next_flow)
		    {
		      if (!Set_in (lp_body, fl->src_bb->ID))
			{
			  lp_body = Set_add (lp_body, fl->src_bb->ID);
			  Push_Top (st, fl->src_bb);
			}
		    }
		}


	      /* the s_lp body is a union of all of these 'inner' lp bodies */
	      s_lp_body = Set_union (s_lp_body, lp_body);

	      Clear_Stack (st);
	      Set_dispose (lp_body);
	    }
	}

      /* If a loop was found, build its set of exits bbs, and append it to the 
         list of loops in the cfg. */
      if (s_lp_head != -1)
	{
	  int *s_lp_bod;
	  int lp_size = 0, i;

	  /* Build the set of all bbs that are exits out of the lp. */
	  s_lp_bod = (int *) calloc (Set_size (s_lp_body), sizeof (int));
	  lp_size = Set_2array (s_lp_body, s_lp_bod);
          num_exit = 0;
	  for (i = 0; i < lp_size; i++)
	    {
	      PC_Block bb;
	      PC_Flow fl;
	      bb = PC_FindBlock (cfg, s_lp_bod[i]);
	      for (fl = bb->s_flow; fl; fl = fl->s_next_flow)
		if (!Set_in (s_lp_body, fl->dest_bb->ID)) 
                  {
                    num_exit++;
                    s_lp_exits = Set_add (s_lp_exits, fl->dest_bb->ID);
                  }
	    }
	  free (s_lp_bod);

	  /* check for redundant loops */
	    {
	      PC_Loop lp = NULL;
	      int same = 0;
	      
	      for (lp = cfg->lp; lp; lp = lp->next)
		if (Set_same (s_lp_body, lp->body))
		  {
		    same = 1;
		    break;
		  }
	      
	      if (same)
		{
		  Set_dispose (s_lp_body);
		  Set_dispose (s_lp_exits);
		  continue;
		}
	    }

	  /* Create a new PC_Loop and append it to the current CFG
             loop list. */
	  loop = &cfg->lp;
	  while (*loop)
	    loop = &(*loop)->next;
	  *loop = PC_NewLoop (s_lp_head, s_lp_body, s_lp_exits, 
			      num_back_edge, num_exit);

	  cfg->lp_tree = PC_LoopTreeInsert (cfg->lp_tree, *loop, 1);
	}

      Set_dispose (s_lp_body);
      Set_dispose (s_lp_exits);
    }

  PC_SetBlockLoops (cfg);

  return;
}