This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [patch, fortran] Make frontend walker more general


On Tue, Sep 14, 2010 at 12:08:12AM +0200, Mikael Morin wrote:
> Your walker looks like :
> 
> void walk_code (gfc_code *c, void (*handler)(gfc_code *))
> {
>   if (c == NULL)
>     return;
> 
>   (*handler) (c);
>   walk_code (c->next);
> }
> 
> your handler like :
> 
> void handler (gfc_code *c)
> {
>   switch (c->op)
>     {
>     case EXEC_ASSIGN:
>       /* Do stuff */
>       break;
> 
>     case EXEC_CALL:
>       /* Do other stuff */
>       break;
> 
>     default:
>       default_handler (c);
>       break;
>     }
> }

I meant something like:

typedef int (*walk_code_fn_t) (gfc_code **, int *, void *);
typedef int (*walk_expr_fn_t) (gfc_expr **, int *, void *);

#define WALK_SUBEXPR(NODE) do { result = walk_expr (&(NODE), exprfn, data); if (result) return result; } while (0)
#define WALK_SUBEXPR_TAIL(NODE) e = &(NODE), continue

int
walk_expr (gfc_expr **e, walk_expr_fn_t exprfn, void *data)
{
  while (*e)
    {
      int walk_subtrees = 1;
      gfc_actual_arglist *a;
      int result = exprfn (e, &walk_subtrees, data);
      if (result)
	return result;
      if (walk_subtrees)
	switch ((*e)->expr_type)
	  {
	  case EXPR_OP:
	    WALK_SUBEXPR ((*e)->value.op1);
	    WALK_SUBEXPR_TAIL ((*e)->value.op2);
	    break;
	  case EXPR_FUNCTION:
	    for (a = (*e)->value.function.actual; a; a = a->next)
	      WALK_SUBEXPR (a->expr);
	    break;
	  case EXPR_COMPCALL:
	  case EXPR_PPC:
	    for (a = (*e)->value.compcall.actual; a; a = a->next)
	      WALK_SUBEXPR (a->expr);
	    break;
	  default:
	    break;
	  }
      return 0;
    }
}

#define WALK_SUBCODE(NODE) do { result = walk_code (&(NODE), codefn, exprfn, data); if (result) return result; } while (0)

int
walk_code (gfc_code **c, walk_code_fn_t codefn, walk_expr_fn_t exprfn, void *data)
{
  while (*c)
    {
      int walk_subtrees = 1;
      int result = codefn (c, &walk_subtrees, data);
      if (result)
	return result;
      if (walk_subtrees)
	{
	  gfc_code *b;
	  for (b = (*c)->block; b; b = b->block)
	    WALK_SUBCODE (b->next);
	  switch ((*c)->code)
	    {
	    ...
	    case EXEC_DO:
	      WALK_SUBEXPR ((*c)->ext.iterator->start);
	      WALK_SUBEXPR ((*c)->ext.iterator->end);
	      WALK_SUBEXPR ((*c)->ext.iterator->step);
	      break;
	    ...
	    case EXEC_OMP_DO:
	    case EXEC_OMP_PARALLEL:
	    case EXEC_OMP_PARALLEL_DO:
	    case EXEC_OMP_PARALLEL_SECTIONS:
	    case EXEC_OMP_PARALLEL_WORKSHARE:                  
	    case EXEC_OMP_SECTIONS:                            
	    case EXEC_OMP_SINGLE:
	    case EXEC_OMP_WORKSHARE:                           
	    case EXEC_OMP_END_SINGLE:                          
	    case EXEC_OMP_TASK:
	      if ((*c)->ext.omp_clauses)
		{
		  WALK_SUBEXPR ((c)->ext.omp_clauses->if_expr);
		  WALK_SUBEXPR ((c)->ext.omp_clauses->num_threads);
		  WALK_SUBEXPR ((c)->ext.omp_clauses->chunk_size);
		}
	      break;
	    }
	}
      c = &(*c)->next;
    }
}

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]