Example #1
0
File: debug.c Project: liesen/found
void
print_tree(FILE *fp, const struct predicate *pred, int indent)
{
  int i;

  if (pred == NULL)
    return;

  for (i = 0; i < indent; i++)
    fprintf(fp, "  ");

  fprintf(fp, "pred=[");
  print_predicate(fp, pred);
  fprintf(fp, "]\n");

  for (i = 0; i < indent; i++)
    fprintf(fp, "  ");

  if (pred->pred_left)
    {
      fprintf(fp, "left:\n");
      print_tree(fp, pred->pred_left, indent + 1);
    }

  if (pred->pred_right)
    {
      fprintf(fp, "right:\n");
      print_tree(fp, pred->pred_right, indent + 1);
    }
}
Example #2
0
static bool
opt_expr (struct predicate **eval_treep)
{
  struct predlist regex_list={NULL,NULL}, name_list={NULL,NULL};
  struct predlist cbo_list[NumEvaluationCosts];
  int i;
  struct predicate *curr;
  struct predicate **prevp;	/* Address of `curr' node. */
  struct predicate **last_sidep; /* Last predicate with side effects. */
  PRED_FUNC pred_func;
  enum predicate_type p_type;
  bool has_side_effects = false; /* Return value. */
  enum predicate_precedence prev_prec, /* precedence of last BI_OP in branch */
			    biop_prec; /* topmost BI_OP precedence in branch */

  if (eval_treep == NULL || *eval_treep == NULL)
    return (false);

  for (i=0; i<NumEvaluationCosts; i++)
    predlist_init (&cbo_list[i]);

  /* Set up to normalize tree as a left-linked list of ANDs or ORs.
     Set `curr' to the leftmost node, `prevp' to its address, and
     `pred_func' to the predicate type of its parent. */
  prevp = eval_treep;
  prev_prec = AND_PREC;
  curr = *prevp;
  while (curr->pred_left != NULL)
    {
      prevp = &curr->pred_left;
      prev_prec = curr->p_prec;	/* must be a BI_OP */
      curr = curr->pred_left;
    }

  /* Link in the appropriate BI_OP for the last expression, if needed. */
  if (curr->p_type != BI_OP)
    set_new_parent (curr, prev_prec, prevp);

  if (options.debug_options & (DebugExpressionTree|DebugTreeOpt))
    {
      /* Normalized tree. */
      fprintf (stderr, "Normalized Eval Tree:\n");
      print_tree (stderr, *eval_treep, 0);
    }

  /* Rearrange the predicates. */
  prevp = eval_treep;
  biop_prec = NO_PREC; /* not COMMA_PREC */
  if ((*prevp) && (*prevp)->p_type == BI_OP)
    biop_prec = (*prevp)->p_prec;
  while ((curr = *prevp) != NULL)
    {
      /* If there is a BI_OP of different precedence from the first
	 in the pred_left chain, create a new parent of the
	 original precedence, link the new parent to the left of the
	 previous and link CURR to the right of the new parent.
	 This preserves the precedence of expressions in the tree
	 in case we rearrange them. */
      if (curr->p_type == BI_OP)
	{
          if (curr->p_prec != biop_prec)
	    curr = set_new_parent (curr, biop_prec, prevp);
	}

      /* See which predicate type we have. */
      p_type = curr->pred_right->p_type;
      pred_func = curr->pred_right->pred_func;


      switch (p_type)
	{
	case NO_TYPE:
	case PRIMARY_TYPE:
	  /* Don't rearrange the arguments of the comma operator, it is
	     not commutative.  */
	  if (biop_prec == COMMA_PREC)
	    break;

	  /* If this predicate has no side effects, consider reordering it. */
	  if (!curr->pred_right->side_effects)
	    {
	      bool reorder;

	      /* If it's one of our special primaries, move it to the
		 front of the list for that primary. */
	      if (predicate_is_cost_free (curr->pred_right))
		{
		  if (options.debug_options & DebugTreeOpt)
		    {
		      fprintf (stderr, "-O%d: promoting cheap predicate ",
			       (int)options.optimisation_level);
		      print_predicate (stderr, curr->pred_right);
		      fprintf (stderr, " into name_list\n");
		    }
		  predlist_insert (&name_list, curr, prevp);
		  continue;
		}

	      if (pred_func == pred_regex)
		{
		  predlist_insert (&regex_list, curr, prevp);
		  continue;
		}

	      reorder = ((options.optimisation_level > 1)
			 && (NeedsType == curr->pred_right->p_cost
			     || NeedsInodeNumber == curr->pred_right->p_cost)
			 && !curr->pred_right->need_stat) ||
		(options.optimisation_level > 2);

	      if (reorder)
		{
		  if (options.debug_options & DebugTreeOpt)
		    {
		      fprintf (stderr, "-O%d: categorising predicate ",
			       (int)options.optimisation_level);
		      print_predicate (stderr, curr->pred_right);
		      fprintf (stderr, " by cost (%s)\n",
			       cost_name(curr->pred_right->p_cost));
		    }
		  predlist_insert (&cbo_list[curr->pred_right->p_cost], curr, prevp);
		  continue;
		}
	    }

	  break;

	case UNI_OP:
	  /* For NOT, check the expression trees below the NOT. */
	  curr->pred_right->side_effects
	    = opt_expr (&curr->pred_right->pred_right);
	  break;

	case BI_OP:
	  /* For nested 'AND' or 'OR', recurse (AND/OR form layers on
	     the left of the tree), and continue scanning this level
	     of 'AND' or 'OR'. */
	  curr->pred_right->side_effects = opt_expr (&curr->pred_right);
	  break;

	  /* At this point, get_expr and scan_rest have already removed
	     all of the user's parentheses. */

	default:
	  error (EXIT_FAILURE, 0, _("oops -- invalid expression type!"));
	  break;
	}

      if (curr->pred_right->side_effects == true)
	{
	  last_sidep = prevp;

	  /* Incorporate lists and reset list pointers for this group.  */
	  merge_lists (cbo_list, NumEvaluationCosts, &name_list, &regex_list, last_sidep);
	  has_side_effects = true;
	}

      prevp = &curr->pred_left;
    }

  /* Do final list merges. */
  last_sidep = prevp;
  merge_lists (cbo_list, NumEvaluationCosts, &name_list, &regex_list, last_sidep);
  return has_side_effects;
}
Example #3
0
void
print_tree (FILE *fp, struct predicate *node, int indent)
{
  int i;

  if (node == NULL)
    return;
  for (i = 0; i < indent; i++)
    fprintf (fp, "    ");
  fprintf (fp, "pred=[");
  print_predicate (fp, node);
  fprintf (fp, "] type=%s prec=%s",
	  type_name (node->p_type), prec_name (node->p_prec));
  fprintf (fp, " cost=%s rate=%#03.2g %sside effects ",
	   cost_name (node->p_cost),
	   node->est_success_rate,
	   (node->side_effects ? "" : "no "));

  if (node->need_stat || node->need_type || node->need_inum)
    {
      int comma = 0;

      fprintf (fp, "Needs ");
      if (node->need_stat)
	{
	  fprintf (fp, "stat");
	  comma = 1;
	}
      if (node->need_inum)
	{
	  fprintf (fp, "%sinode", comma ? "," : "");
	  comma = 1;
	}
      if (node->need_type)
	{
	  fprintf (fp, "%stype", comma ? "," : "");
	}
    }
  fprintf (fp, "\n");


  for (i = 0; i < indent; i++)
    fprintf (fp, "    ");
  if (NULL == node->pred_left && NULL == node->pred_right)
    {
      fprintf (fp, "no children.\n");
    }
  else
    {
      if (node->pred_left)
	{
	  fprintf (fp, "left:\n");
	  print_tree (fp, node->pred_left, indent + 1);
	}
      else
	{
	  fprintf (fp, "no left.\n");
	}

      for (i = 0; i < indent; i++)
	fprintf (fp, "    ");
      if (node->pred_right)
	{
	  fprintf (fp, "right:\n");
	  print_tree (fp, node->pred_right, indent + 1);
	}
      else
	{
	  fprintf (fp, "no right.\n");
	}
    }
}