gomp-discuss
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Gomp-discuss] Hacking


From: Steven Bosscher
Subject: Re: [Gomp-discuss] Hacking
Date: 07 Feb 2003 00:49:05 +0100

Op do 06-02-2003, om 21:16 schreef Biagio Lucini:
> Hi - I would love to start hackjing the parser as well, but I don't know
> how to avoid conflicts: it is difficult without a working cvs.
> 
> Moreover, have we decided how to parse?
>
>
> Any suggestion?

We need to add the information from the pragmas to the parse tree via
callbacks, one in add_stmt() and one in the declaration handler (the one
that the other pragmas use).
 
For parsing the directives:  I've been hacking up this skeleton of a
"#pragma omp" parser, in a file I called "c-openmp.c".  I've attached
it, as you can see it's there's not much yet.  I killed the part that
parsed the clauses because it did not turn out the way I wanted it. 
Right now it doesn't even compile.  But it gives you an idea of the
lines that I was thining along.
Don't make too much fun of it  ;-)

Greetz
Steven



/* Handle OpenMP 2.0 #pragmas for GNU CC.
   Copyright (C) 2003 Free Software Foundation, Inc.
   Contributed by Steven Bosscher <address@hidden>

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 2, or (at your
option) any later version.

GCC is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "rtl.h"
#include "tree.h"
#include "function.h"
#include "cpplib.h"
#include "c-pragma.h"
#include "flags.h"
#include "toplev.h"
#include "ggc.h"
#include "c-common.h"
#include "output.h"
#include "tm_p.h"

#define GCC_BAD_OMP_DIRECTIVE(msg) do { warning (msg); return; } while (0)

/* All the OpenMP directives in the OpenMP C and C++ API, version 2.0  */
enum omp_directive
{
  ATOMIC, BARRIER, CRITICAL, FLUSH, FOR, MASTER,
  ORDERED, PARALLEL, PARALLEL_FOR, PARALLEL_SECTIONS,
  SECTION, SECTIONS, SINGLE, THREADPRIVATE, UNKNOWN
};

/* OpenMP directive handler.  */
static void omp_handle_directive PARAMS ((enum omp_directive));

/* OpenMP clauses parser.  */
static omp_clause *get_omp_clause PARAMS ((void));

/* See if a clause makes sense for the current directive.  */
static omp_clause_legal_for PARAMS ((omp_clause *, enum omp_directive));


/* Parse OpenMP directives.  Some directives can have clause lists,
   others do not.  Here we just try to find a handler for the
   directive we see, or we drop the whole pragma if there's no
   directive or one that we don't know about.

   These are the OpenMP directives we recognise:

      # pragma omp atomic
      # pragma omp barrier
      # pragma omp critical '(' region-phrase ')'
      # pragma omp flush '(' variable-list ')'
      # pragma omp for (for-clauses)
      # pragma omp master
      # pragma omp ordered
      # pragma omp parallel (parallel-clauses)
      # pragma omp parallel for (parallel-for-clauses)
      # pragma omp parallel sections (parallel-sections-clauses)
      # pragma omp section
      # pragma omp sections (sections-clauses)
      # pragma omp single (single-clauses)
      # pragma omp threadprivate '(' variable-list ')'

  The implementation here is a bit crude and it could be done faster
  with a binary chop or something, but I doubt it would make a big
  difference.  */

void
handle_pragma_omp (dummy)
     cpp_reader *dummy ATTRIBUTE_UNUSED;
{
  tree x;
  enum cpp_ttype token;
  const char *dir;
  omp_directive directive = UNKNOWN;

  token = c_lex (&x);
  if (token != CPP_NAME)
    GCC_BAD_OMP_DIRECTIVE ("malformed '#pragma omp' - ignored");

  *dir = IDENTIFIER_POINTER (x);
  switch (dir[0])
    {
    case 'a':
      if (!strcmp (directive, "atomic"))
        directive = ATOMIC;
      break;

    case 'b':
      if (!strcmp (directive, "barrier"))
        directive = BARRIER;
      break;

    case 'c':
      if (!strcmp (directive, "critical"))
        directive = CRITICAL;
      break;

    case 'f':
      if (!strcmp (directive, "flush"))
        directive = FLUSH;
      else if (!strcmp (directive, "for"))
        directive = FOR;
      break;

    case 'm':
      if (!strcmp (directive, "master"))
        directive = MASTER;
      break;

    case 'o':
      if (!strcmp (directive, "ordered"))
        directive = ORDERED;
      break;

    case 'p':
      if (!strcmp (op, "parallel"))
        {
          /* "opm parallel" is special because there may
             be a second keyword after "parallel".  */
          token = c_lex (&x);
          if (token == CPP_NAME)
            {
              dir = IDENTIFIER_POINTER (x);
              if (!strcmp (dir, 'for'))
                {
                  directive = PARALLEL_FOR;
                  break;        /* from the switch block.  */
                }
              else if (!strcmp (dir, 'sections'))
                {
                  directive = PARALLEL_SECTIONS;
                  break;
                }
            }

          /* It's a normal 'parallel' directive.  Put
             the token back in the input buffer.  */
          _cpp_backup_tokens (parse_in, 1);
          directive = PARALLEL;
          break;
        }

    case 's':

      if (dir[1] == 'e')
        {
          /* This is subtle. One extra 's' after 'section'
             and you're screwed.  Be careful.  */
          if (!strcmp (directive, "section"))
            directive = SECTION;
          else if (!strcmp (directive, "sections"))
            directive = SECTIONS;
        }
      else if (!strcmp (directive, "single"))
        directive = SINGLE;
      break;

    case 't':
      if (!strcmp (directive, "threadprivate"))
        directive = THREADPRIVATE;
      break;

    default:
      break;
    }

  if (directive = UNKNOWN)
    GCC_BAD_OMP_DIRECTIVE ("malformed '#pragma omp' - ignored");
  else
    omp_handle_directive (directive);

  return;
}

/* CPP_COMMA CPP_NAME CPP_NUMBER CPP_OPEN_PAREN CPP_CLOSE_PAREN CPP_EOF 
CPP_STRING */


/* Given the directive we've seen, handle all the clauses that it may
   have.  */
static void omp_handle_directive (enum omp_directive directive);
{
  tree var_list;
  enum cpp_ttype token;

  switch (directive)
    {
    case ATOMIC:
    case BARIER:
    case MASTER:
    case ORDERED:
    case SECTION:
      /* These directives do not have any clauses.

         atomic-directive:       #pragma omp atomic new-line
         barrier-directive:      #pragma omp barrier new-line
         master-directive:       #pragma omp master new-line
         ordered-directive:      #pragma omp ordered new-line
         section-directive:      #pragma omp section new-line
       */
      if (c_lex (&x) != CPP_EOF)
        GCC_BAD_OMP_DIRECTIVE ("junk at end of '#pragma omp' - ignored");
      /* Do something with the directive.  */
      break;

    case FLUSH:
      /* flush-directive
         : #pragma omp flush flush-vars new-line

         flush-vars
         : empty
         | '(' variable-list ')'
       */
      var_list = NULL_TREE;
      token = c_lex (&x);
      if (token == CPP_OPEN_PAREN)
        {
          var_list = omp_get_variable_list ();
          if (var_list == NULL_TREE || c_lex (&x) != CPP_CLOSE_PAREN)
            GCC_BAD_OMP_DIRECTIVE ("malformed '#pragma omp' - ignored");

          token = c_lex (&x);
        }

      if (token != CPP_EOF)
        GCC_BAD_OMP_DIRECTIVE ("junk at end of '#pragma omp' - ignored");
      /* Do something with the directive.  (varlist == NULL_TREE) is
         legal at this point.  */
      break;

    case THREADPRIVATE:
      /* threadprivate-directive
         : #pragma omp threadprivate '(' variable-list ')' new-line
       */
      var_list = NULL_TREE;
      token = c_lex (&x);
      if (token == CPP_OPEN_PAREN)
        {
          var_list = omp_get_variable_list ();
          if (var_list == NULL_TREE || c_lex (&x) != CPP_CLOSE_PAREN)
            GCC_BAD_OMP_DIRECTIVE ("malformed '#pragma omp' - ignored");

          token = c_lex (&x);
          if (c_lex (&x) != CPP_EOF)
            GCC_BAD_OMP_DIRECTIVE ("junk at end of '#pragma omp' - ignored");
          /* Do something with the directive.  */
        }
      else
        GCC_BAD_OMP_DIRECTIVE ("malformed '#pragma omp' - ignored");

      break;


/* TODO:
      # pragma omp critical '(' region-phrase ')'
      # pragma omp for (for-clauses)
      # pragma omp parallel (parallel-clauses)
      # pragma omp parallel for (parallel-for-clauses)
      # pragma omp parallel sections (parallel-sections-clauses)
      # pragma omp sections (sections-clauses)
      # pragma omp single (single-clauses)
*/
    case default:
      break;
    }

  return;
}









reply via email to

[Prev in Thread] Current Thread [Next in Thread]