public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* nvptx offloading patches [4/n]
@ 2014-11-01 12:11 Bernd Schmidt
  2015-01-28 18:03 ` Thomas Schwinge
                   ` (2 more replies)
  0 siblings, 3 replies; 20+ messages in thread
From: Bernd Schmidt @ 2014-11-01 12:11 UTC (permalink / raw)
  To: GCC Patches

[-- Attachment #1: Type: text/plain, Size: 485 bytes --]

I'm sending this for reference more than anything else - this is the 
patch that adds the target support for offloading to the nvptx port. It 
depends on the other offloading patches Ilya is currently submitting.

I actually expect this to change a little in the near future; the nvptx 
mkoffload duplicates some of the logic that we have in nvptx-as and I'm 
thinking of making some improvements. But I figure it would be good to 
show the entire picture, as it is as of now.


Bernd

[-- Attachment #2: ptx-offload.diff --]
[-- Type: text/x-patch, Size: 22327 bytes --]

Index: git/gcc/config/nvptx/mkoffload.c
===================================================================
--- /dev/null
+++ git/gcc/config/nvptx/mkoffload.c
@@ -0,0 +1,889 @@
+/* Offload image generation tool for ptx
+
+   Nathan Sidwell <nathan@codesourcery.com>
+   Bernd Schmidt <bernds@codesourcery.com>
+
+   Munges PTX assembly into a C source file defining the PTX code as a
+   string.
+
+   This is not a complete assembler.  We presume the source is well
+   formed from the compiler and can die horribly if it is not.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "intl.h"
+#include <libgen.h>
+#include "obstack.h"
+#include "diagnostic-core.h"
+#include "collect-utils.h"
+
+const char tool_name[] = "nvptx mkoffload";
+
+#define COMMENT_PREFIX "#"
+
+typedef enum Kind
+{
+  /* 0-ff used for single char tokens */
+  K_symbol = 0x100, /* a symbol */
+  K_label,  /* a label defn (i.e. symbol:) */
+  K_ident,  /* other ident */
+  K_dotted, /* dotted identifier */
+  K_number,
+  K_string,
+  K_comment
+} Kind;
+
+typedef struct Token
+{
+  unsigned short kind : 12;
+  unsigned short space : 1; /* preceded by space */
+  unsigned short end : 1;   /* succeeded by end of line */
+  /* Length of token */
+  unsigned short len;
+
+  /* Token itself */
+  char const *ptr;
+} Token;
+
+/* statement info */
+typedef enum Vis
+{
+  V_dot = 0,  /* random pseudo */
+  V_var = 1,  /* var decl/defn */
+  V_func = 2, /* func decl/defn */
+  V_insn = 3, /* random insn */
+  V_label = 4, /* label defn */
+  V_comment = 5,
+  V_pred = 6,  /* predicate */
+  V_mask = 0x7,
+  V_global = 0x08, /* globalize */
+  V_weak = 0x10,   /* weakly globalize */
+  V_no_eol = 0x20, /* no end of line */
+  V_prefix_comment = 0x40 /* prefixed comment */
+} Vis;
+
+typedef struct Stmt
+{
+  struct Stmt *next;
+  Token *tokens;
+  unsigned char vis;
+  unsigned len : 12;
+  unsigned sym : 12;
+} Stmt;
+
+struct id_map
+{
+  id_map *next;
+  char *ptx_name;
+};
+
+static const char *read_file (FILE *);
+static Token *tokenize (const char *);
+
+static void write_token (FILE *, const Token *);
+static void write_tokens (FILE *, const Token *, unsigned, int);
+
+static Stmt *alloc_stmt (unsigned, Token *, Token *, const Token *);
+#define alloc_comment(S,E) alloc_stmt (V_comment, S, E, 0)
+#define append_stmt(V, S) ((S)->next = *(V), *(V) = (S))
+static Stmt *rev_stmts (Stmt *);
+static void write_stmt (FILE *, const Stmt *);
+static void write_stmts (FILE *, const Stmt *);
+
+static Token *parse_insn (Token *);
+static Token *parse_list_nosemi (Token *);
+static Token *parse_init (Token *);
+static Token *parse_file (Token *);
+
+static Stmt *decls;
+static Stmt *vars;
+static Stmt *fns;
+
+static id_map *func_ids, **funcs_tail = &func_ids;
+static id_map *var_ids, **vars_tail = &var_ids;
+
+/* Files to unlink.  */
+static const char *ptx_name;
+static const char *ptx_cfile_name;
+
+/* Delete tempfiles.  */
+
+/* Unlink a temporary file unless requested otherwise.  */
+
+void
+maybe_unlink (const char *file)
+{
+  if (! debug)
+    {
+      if (unlink_if_ordinary (file)
+	  && errno != ENOENT)
+	fatal_error ("deleting file %s: %m", file);
+    }
+  else
+    fprintf (stderr, "[Leaving %s]\n", file);
+}
+
+void
+tool_cleanup (bool)
+{
+}
+
+/* Add or change the value of an environment variable, outputting the
+   change to standard error if in verbose mode.  */
+static void
+xputenv (const char *string)
+{
+  if (verbose)
+    fprintf (stderr, "%s\n", string);
+  putenv (CONST_CAST (char *, string));
+}
+
+
+static void
+record_id (const char *p1, id_map ***where)
+{
+  const char *end = strchr (p1, '\n');
+  if (!end)
+    fatal_error ("malformed ptx file");
+
+  id_map *v = XNEW (id_map);
+  size_t len = end - p1;
+  v->ptx_name = XNEWVEC (char, len + 1);
+  memcpy (v->ptx_name, p1, len);
+  v->ptx_name[len] = '\0';
+  v->next = NULL;
+  id_map **tail = *where;
+  *tail = v;
+  *where = &v->next;
+}
+
+/* Read the whole input file.  It will be NUL terminated (but
+   remember, there could be a NUL in the file itself.  */
+
+static const char *
+read_file (FILE *stream)
+{
+  size_t alloc = 16384;
+  size_t base = 0;
+  char *buffer;
+
+  if (!fseek (stream, 0, SEEK_END))
+    {
+      /* Get the file size.  */
+      long s = ftell (stream);
+      if (s >= 0)
+	alloc = s + 100;
+      fseek (stream, 0, SEEK_SET);
+    }
+  buffer = XNEWVEC (char, alloc);
+
+  for (;;)
+    {
+      size_t n = fread (buffer + base, 1, alloc - base - 1, stream);
+
+      if (!n)
+	break;
+      base += n;
+      if (base + 1 == alloc)
+	{
+	  alloc *= 2;
+	  buffer = XRESIZEVEC (char, buffer, alloc);
+	}
+    }
+  buffer[base] = 0;
+  return buffer;
+}
+
+/* Read a token, advancing ptr.
+   If we read a comment, append it to the comments block. */
+
+static Token *
+tokenize (const char *ptr)
+{
+  unsigned alloc = 1000;
+  unsigned num = 0;
+  Token *toks = XNEWVEC (Token, alloc);
+  int in_comment = 0;
+  int not_comment = 0;
+
+  for (;; num++)
+    {
+      const char *base;
+      unsigned kind;
+      int ws = 0;
+      int eol = 0;
+
+    again:
+      base = ptr;
+      if (in_comment)
+	goto block_comment;
+      switch (kind = *ptr++)
+	{
+	default:
+	  break;
+
+	case '\n':
+	  eol = 1;
+	  /* Fall through */
+	case ' ':
+	case '\t':
+	case '\r':
+	case '\v':
+	  /* White space */
+	  ws = not_comment;
+	  goto again;
+
+	case '/':
+	  {
+	    if (*ptr == '/')
+	      {
+		/* line comment.  Do not include trailing \n */
+		base += 2;
+		for (; *ptr; ptr++)
+		  if (*ptr == '\n')
+		    break;
+		kind = K_comment;
+	      }
+	    else if (*ptr == '*')
+	      {
+		/* block comment */
+		base += 2;
+		ptr++;
+
+	      block_comment:
+		eol = in_comment;
+		in_comment = 1;
+		for (; *ptr; ptr++)
+		  {
+		    if (*ptr == '\n')
+		      {
+			ptr++;
+			break;
+		      }
+		    if (ptr[0] == '*' && ptr[1] == '/')
+		      {
+			in_comment = 2;
+			ptr += 2;
+			break;
+		      }
+		  }
+		kind = K_comment;
+	      }
+	    else
+	      break;
+	  }
+	  break;
+
+	case '"':
+	  /* quoted string */
+	  kind = K_string;
+	  while (*ptr)
+	    if (*ptr == '"')
+	      {
+		ptr++;
+		break;
+	      }
+	    else if (*ptr++ == '\\')
+	      ptr++;
+	  break;
+
+	case '.':
+	  if (*ptr < '0' || *ptr > '9')
+	    {
+	      kind = K_dotted;
+	      ws = not_comment;
+	      goto ident;
+	    }
+	  /* FALLTHROUGH */
+	case '0'...'9':
+	  kind = K_number;
+	  goto ident;
+	  break;
+
+	case '$':  /* local labels.  */
+	case '%':  /* register names, pseudoes etc */
+	  kind = K_ident;
+	  goto ident;
+
+	case 'a'...'z':
+	case 'A'...'Z':
+	case '_':
+	  kind = K_symbol; /* possible symbol name */
+	ident:
+	  for (; *ptr; ptr++)
+	    {
+	      if (*ptr >= 'A' && *ptr <= 'Z')
+		continue;
+	      if (*ptr >= 'a' && *ptr <= 'z')
+		continue;
+	      if (*ptr >= '0' && *ptr <= '9')
+		continue;
+	      if (*ptr == '_' || *ptr == '$')
+		continue;
+	      if (*ptr == '.' && kind != K_dotted)
+		/* Idents starting with a dot, cannot have internal dots. */
+		continue;
+	      if ((*ptr == '+' || *ptr == '-')
+		  && kind == K_number
+		  && (ptr[-1] == 'e' || ptr[-1] == 'E'
+		      || ptr[-1] == 'p' || ptr[-1] == 'P'))
+		/* exponent */
+		continue;
+	      break;
+	    }
+	  if (*ptr == ':')
+	    {
+	      ptr++;
+	      kind = K_label;
+	    }
+	  break;
+	}
+
+      if (alloc == num)
+	{
+	  alloc *= 2;
+	  toks = XRESIZEVEC (Token, toks, alloc);
+	}
+      Token *tok = toks + num;
+
+      tok->kind = kind;
+      tok->space = ws;
+      tok->end = 0;
+      tok->ptr = base;
+      tok->len = ptr - base - in_comment;
+      in_comment &= 1;
+      not_comment = kind != K_comment;
+      if (eol && num)
+	tok[-1].end = 1;
+      if (!kind)
+	break;
+    }
+
+  return toks;
+}
+
+/* Write an encoded token. */
+
+static void
+write_token (FILE *out, Token const *tok)
+{
+  if (tok->space)
+    fputc (' ', out);
+
+  switch (tok->kind)
+    {
+    case K_string:
+      {
+	const char *c = tok->ptr + 1;
+	size_t len = tok->len - 2;
+
+	fputs ("\\\"", out);
+	while (len)
+	  {
+	    const char *bs = (const char *)memchr (c, '\\', len);
+	    size_t l = bs ? bs - c : len;
+
+	    fprintf (out, "%.*s", (int)l, c);
+	    len -= l;
+	    c += l;
+	    if (bs)
+	      {
+		fputs ("\\\\", out);
+		len--, c++;
+	      }
+	  }
+	fputs ("\\\"", out);
+      }
+      break;
+
+    default:
+      /* All other tokens shouldn't have anything magic in them */
+      fprintf (out, "%.*s", tok->len, tok->ptr);
+      break;
+    }
+  if (tok->end)
+    fputs ("\\n", out);
+}
+
+static void
+write_tokens (FILE *out, Token const *toks, unsigned len, int spc)
+{
+  fputs ("\t\"", out);
+  for (; len--; toks++)
+    write_token (out, toks);
+  if (spc)
+    fputs (" ", out);
+  fputs ("\"", out);
+}
+
+static Stmt *
+alloc_stmt (unsigned vis, Token *tokens, Token *end, Token const *sym)
+{
+  static unsigned alloc = 0;
+  static Stmt *heap = 0;
+
+  if (!alloc)
+    {
+      alloc = 1000;
+      heap = XNEWVEC (Stmt, alloc);
+    }
+
+  Stmt *stmt = heap++;
+  alloc--;
+
+  tokens->space = 0;
+  stmt->next = 0;
+  stmt->vis = vis;
+  stmt->tokens = tokens;
+  stmt->len = end - tokens;
+  stmt->sym = sym ? sym - tokens : ~0;
+
+  return stmt;
+}
+
+static Stmt *
+rev_stmts (Stmt *stmt)
+{
+  Stmt *prev = 0;
+  Stmt *next;
+
+  while (stmt)
+    {
+      next = stmt->next;
+      stmt->next = prev;
+      prev = stmt;
+      stmt = next;
+    }
+
+  return prev;
+}
+
+static void
+write_stmt (FILE *out, const Stmt *stmt)
+{
+  if ((stmt->vis & V_mask) != V_comment)
+    {
+      write_tokens (out, stmt->tokens, stmt->len,
+		    (stmt->vis & V_mask) == V_pred);
+      fputs (stmt->vis & V_no_eol ? "\t" : "\n", out);
+    }
+}
+
+static void
+write_stmts (FILE *out, const Stmt *stmts)
+{
+  for (; stmts; stmts = stmts->next)
+    write_stmt (out, stmts);
+}
+
+static Token *
+parse_insn (Token *tok)
+{
+  unsigned depth = 0;
+
+  do
+    {
+      Stmt *stmt;
+      Token *sym = 0;
+      unsigned s = V_insn;
+      Token *start = tok;
+
+      switch (tok++->kind)
+	{
+	case K_comment:
+	  while (tok->kind == K_comment)
+	    tok++;
+	  stmt = alloc_comment (start, tok);
+	  append_stmt (&fns, stmt);
+	  continue;
+
+	case '{':
+	  depth++;
+	  break;
+
+	case '}':
+	  depth--;
+	  break;
+
+	case K_label:
+	  if (tok[-1].ptr[0] != '$')
+	    sym = tok - 1;
+	  tok[-1].end = 1;
+	  s = V_label;
+	  break;
+
+	case '@':
+	  tok->space = 0;
+	  if (tok->kind == '!')
+	    tok++;
+	  if (tok->kind == K_symbol)
+	    sym = tok;
+	  tok++;
+	  s = V_pred;
+	  break;
+
+	default:
+	  for (; tok->kind != ';'; tok++)
+	    {
+	      if (tok->kind == ',')
+		tok[1].space = 0;
+	      else if (tok->kind == K_symbol)
+		sym = tok;
+	    }
+	  tok++->end = 1;
+	  break;
+	}
+
+      stmt = alloc_stmt (s, start, tok, sym);
+      append_stmt (&fns, stmt);
+
+      if (!tok[-1].end && tok[0].kind == K_comment)
+	{
+	  stmt->vis |= V_no_eol;
+	  stmt = alloc_comment (tok, tok + 1);
+	  append_stmt (&fns, stmt);
+	  tok++;
+	}
+    }
+  while (depth);
+
+  return tok;
+}
+
+/* comma separated list of tokens */
+
+static Token *
+parse_list_nosemi (Token *tok)
+{
+  Token *start = tok;
+
+  do
+    if (!(++tok)->kind)
+      break;
+  while ((++tok)->kind == ',');
+
+  tok[-1].end = 1;
+  Stmt *stmt = alloc_stmt (V_dot, start, tok, 0);
+  append_stmt (&decls, stmt);
+
+  return tok;
+}
+
+#define is_keyword(T,S) \
+  (sizeof (S) == (T)->len && !memcmp ((T)->ptr + 1, (S), (T)->len - 1))
+
+static Token *
+parse_init (Token *tok)
+{
+  for (;;)
+    {
+      Token *start = tok;
+      Token const *sym = 0;
+      Stmt *stmt;
+
+      if (tok->kind == K_comment)
+	{
+	  while (tok->kind == K_comment)
+	    tok++;
+	  stmt = alloc_comment (start, tok);
+	  append_stmt (&vars, stmt);
+	  start = tok;
+	}
+
+      if (tok->kind == '{')
+	tok[1].space = 0;
+      for (; tok->kind != ',' && tok->kind != ';'; tok++)
+	if (tok->kind == K_symbol)
+	  sym = tok;
+      tok[1].space = 0;
+      int end = tok++->kind == ';';
+      stmt = alloc_stmt (V_insn, start, tok, sym);
+      append_stmt (&vars, stmt);
+      if (!tok[-1].end && tok->kind == K_comment)
+	{
+	  stmt->vis |= V_no_eol;
+	  stmt = alloc_comment (tok, tok + 1);
+	  append_stmt (&vars, stmt);
+	  tok++;
+	}
+      if (end)
+	break;
+    }
+  return tok;
+}
+
+static Token *
+parse_file (Token *tok)
+{
+  Stmt *comment = 0;
+
+  if (tok->kind == K_comment)
+    {
+      Token *start = tok;
+
+      while (tok->kind == K_comment)
+	{
+	  if (strncmp (tok->ptr, ":VAR_MAP ", 9) == 0)
+	    record_id (tok->ptr + 9, &vars_tail);
+	  if (strncmp (tok->ptr, ":FUNC_MAP ", 10) == 0)
+	    record_id (tok->ptr + 10, &funcs_tail);
+	  tok++;
+	}
+      comment = alloc_comment (start, tok);
+      comment->vis |= V_prefix_comment;
+    }
+
+  if (tok->kind == K_dotted)
+    {
+      if (is_keyword (tok, "version")
+	  || is_keyword (tok, "target")
+	  || is_keyword (tok, "address_size"))
+	{
+	  if (comment)
+	    append_stmt (&decls, comment);
+	  tok = parse_list_nosemi (tok);
+	}
+      else
+	{
+	  unsigned vis = 0;
+	  const Token *def = 0;
+	  unsigned is_decl = 0;
+	  Token *start;
+
+	  for (start = tok;
+	       tok->kind && tok->kind != '=' && tok->kind != K_comment
+		 && tok->kind != '{' && tok->kind != ';'; tok++)
+	    {
+	      if (is_keyword (tok, "global")
+		  || is_keyword (tok, "const"))
+		vis |= V_var;
+	      else if (is_keyword (tok, "func")
+		       || is_keyword (tok, "entry"))
+		vis |= V_func;
+	      else if (is_keyword (tok, "visible"))
+		vis |= V_global;
+	      else if (is_keyword (tok, "extern"))
+		is_decl = 1;
+	      else if (is_keyword (tok, "weak"))
+		vis |= V_weak;
+	      if (tok->kind == '(')
+		{
+		  tok[1].space = 0;
+		  tok[0].space = 1;
+		}
+	      else if (tok->kind == ')' && tok[1].kind != ';')
+		tok[1].space = 1;
+
+	      if (tok->kind == K_symbol)
+		def = tok;
+	    }
+
+	  if (!tok->kind)
+	    {
+	      /* end of file */
+	      if (comment)
+		append_stmt (&fns, comment);
+	    }
+	  else if (tok->kind == '{'
+		   || tok->kind == K_comment)
+	    {
+	      /* function defn */
+	      Stmt *stmt = alloc_stmt (vis, start, tok, def);
+	      if (comment)
+		{
+		  append_stmt (&fns, comment);
+		  stmt->vis |= V_prefix_comment;
+		}
+	      append_stmt (&fns, stmt);
+	      tok = parse_insn (tok);
+	    }
+	  else
+	    {
+	      int assign = tok->kind == '=';
+
+	      tok++->end = 1;
+	      if ((vis & V_mask) == V_var && !is_decl)
+		{
+		  /* variable */
+		  Stmt *stmt = alloc_stmt (vis, start, tok, def);
+		  if (comment)
+		    {
+		      append_stmt (&vars, comment);
+		      stmt->vis |= V_prefix_comment;
+		    }
+		  append_stmt (&vars, stmt);
+		  if (assign)
+		    tok = parse_init (tok);
+		}
+	      else
+		{
+		  /* declaration */
+		  Stmt *stmt = alloc_stmt (vis, start, tok, 0);
+		  if (comment)
+		    {
+		      append_stmt (&decls, comment);
+		      stmt->vis |= V_prefix_comment;
+		    }
+		  append_stmt (&decls, stmt);
+		}
+	    }
+	}
+    }
+  else
+    {
+      /* Something strange.  Ignore it.  */
+      if (comment)
+	append_stmt (&fns, comment);
+
+      while (tok->kind && !tok->end)
+	tok++;
+    }
+  return tok;
+}
+
+static void
+process (FILE *in, FILE *out)
+{
+  const char *input = read_file (in);
+  Token *tok = tokenize (input);
+
+  do
+    tok = parse_file (tok);
+  while (tok->kind);
+
+  fprintf (out, "static const char ptx_code[] = \n");
+  write_stmts (out, rev_stmts (decls));
+  write_stmts (out, rev_stmts (vars));
+  write_stmts (out, rev_stmts (fns));
+  fprintf (out, ";\n\n");
+  fprintf (out, "static const char *var_mappings[] = {\n");
+  for (id_map *id = var_ids; id; id = id->next)
+    fprintf (out, "\t\"%s\"%s\n", id->ptx_name, id->next ? "," : "");
+  fprintf (out, "};\n\n");
+  fprintf (out, "static const char *func_mappings[] = {\n");
+  for (id_map *id = func_ids; id; id = id->next)
+    fprintf (out, "\t\"%s\"%s\n", id->ptx_name, id->next ? "," : "");
+  fprintf (out, "};\n\n");
+
+  fprintf (out, "static const void *target_data[] = {\n");
+  fprintf (out, "  ptx_code, var_mappings, func_mappings\n");
+  fprintf (out, "};\n\n");
+
+  fprintf (out, "extern void GOMP_offload_register (const void *, int, void *);\n");
+
+  fprintf (out, "extern void *__OPENMP_TARGET__[];\n\n");
+  fprintf (out, "#define PTX_ID 1\n");
+  fprintf (out, "static __attribute__((constructor)) void init (void)\n{\n");
+  fprintf (out, "  GOMP_offload_register (__OPENMP_TARGET__, PTX_ID,\n");
+  fprintf (out, "                         &target_data);\n");
+  fprintf (out, "};\n");
+}
+
+static void
+compile_native (const char *infile, const char *outfile, const char *compiler)
+{
+  const char *collect_gcc_options = getenv ("COLLECT_GCC_OPTIONS");
+  if (!collect_gcc_options)
+    fatal_error ("environment variable COLLECT_GCC_OPTIONS must be set");
+
+  struct obstack argv_obstack;
+  obstack_init (&argv_obstack);
+  obstack_ptr_grow (&argv_obstack, compiler);
+  obstack_ptr_grow (&argv_obstack, infile);
+  obstack_ptr_grow (&argv_obstack, "-c");
+  obstack_ptr_grow (&argv_obstack, "-o");
+  obstack_ptr_grow (&argv_obstack, outfile);
+  obstack_ptr_grow (&argv_obstack, NULL);
+
+  const char **new_argv = XOBFINISH (&argv_obstack, const char **);
+  fork_execute (new_argv[0], CONST_CAST (char **, new_argv), true);
+  obstack_free (&argv_obstack, NULL);
+}
+
+int
+main (int argc, char **argv)
+{
+  FILE *in = stdin;
+  FILE *out = stdout;
+  const char *outname = 0;
+
+  char *collect_gcc = getenv ("COLLECT_GCC");
+  if (collect_gcc == NULL)
+    fatal_error ("COLLECT_GCC must be set.");
+  const char *gcc_path = dirname (ASTRDUP (collect_gcc));
+  const char *gcc_exec = basename (ASTRDUP (collect_gcc));
+
+  size_t len = (strlen (gcc_path) + 1
+		+ strlen (GCC_INSTALL_NAME)
+		+ 1);
+  char *driver = XALLOCAVEC (char, len);
+
+  if (strcmp (gcc_exec, collect_gcc) == 0)
+    /* collect_gcc has no path, so it was found in PATH.  Make sure we also
+       find accel-gcc in PATH.  */
+    gcc_path = NULL;
+
+  int driver_used = 0;
+  if (gcc_path != NULL)
+    driver_used = sprintf (driver, "%s/", gcc_path);
+  sprintf (driver + driver_used, "%s", GCC_INSTALL_NAME);
+
+  /* We may be called with all the arguments stored in some file and
+     passed with @file.  Expand them into argv before processing.  */
+  expandargv (&argc, &argv);
+
+  struct obstack argv_obstack;
+  obstack_init (&argv_obstack);
+  obstack_ptr_grow (&argv_obstack, driver);
+  obstack_ptr_grow (&argv_obstack, "-xlto");
+  obstack_ptr_grow (&argv_obstack, "-m64");
+  obstack_ptr_grow (&argv_obstack, "-S");
+
+  for (int ix = 1; ix != argc; ix++)
+    {
+      if (!strcmp (argv[ix], "-o") && ix + 1 != argc)
+	outname = argv[++ix];
+      else
+	obstack_ptr_grow (&argv_obstack, argv[ix]);
+    }
+
+  ptx_name = make_temp_file (".mkoffload");
+  obstack_ptr_grow (&argv_obstack, "-o");
+  obstack_ptr_grow (&argv_obstack, ptx_name);
+  obstack_ptr_grow (&argv_obstack, NULL);
+  const char **new_argv = XOBFINISH (&argv_obstack, const char **);
+
+  char *execpath = getenv ("GCC_EXEC_PREFIX");
+  char *cpath = getenv ("COMPILER_PATH");
+  char *lpath = getenv ("LIBRARY_PATH");
+  unsetenv ("GCC_EXEC_PREFIX");
+  unsetenv ("COMPILER_PATH");
+  unsetenv ("LIBRARY_PATH");
+
+  fork_execute (new_argv[0], CONST_CAST (char **, new_argv), true);
+  obstack_free (&argv_obstack, NULL);
+
+  xputenv (concat ("GCC_EXEC_PREFIX=", execpath, NULL));
+  xputenv (concat ("COMPILER_PATH=", cpath, NULL));
+  xputenv (concat ("LIBRARY_PATH=", lpath, NULL));
+
+  in = fopen (ptx_name, "r");
+  if (!in)
+    fatal_error ("cannot open intermediate ptx file");
+
+  ptx_cfile_name = make_temp_file (".c");
+
+  out = fopen (ptx_cfile_name, "w");
+  if (!out)
+    fatal_error ("cannot open '%s'", ptx_cfile_name);
+
+  process (in, out);
+  fclose (out);
+
+  compile_native (ptx_cfile_name, outname, collect_gcc);
+
+  utils_cleanup (false);
+
+  return 0;
+}
Index: git/gcc/config.gcc
===================================================================
--- git.orig/gcc/config.gcc
+++ git/gcc/config.gcc
@@ -2155,6 +2155,9 @@ nvptx-*)
 	tm_file="${tm_file} newlib-stdint.h"
 	tmake_file="nvptx/t-nvptx"
 	extra_programs="collect-ld\$(exeext) as\$(exeext) ar\$(exeext) ranlib\$(exeext)"
+	if test x$enable_as_accelerator = xyes; then
+		extra_programs="${extra_programs} mkoffload\$(exeext)"
+	fi
 	;;
 pdp11-*-*)
 	tm_file="${tm_file} newlib-stdint.h"
Index: git/gcc/config/nvptx/t-nvptx
===================================================================
--- git.orig/gcc/config/nvptx/t-nvptx
+++ git/gcc/config/nvptx/t-nvptx
@@ -1,5 +1,15 @@
 #
 
+CFLAGS-mkoffload.o += $(DRIVER_DEFINES) \
+	-DGCC_INSTALL_NAME=\"$(GCC_INSTALL_NAME)\"
+mkoffload.o: $(srcdir)/config/nvptx/mkoffload.c
+	$(COMPILE) $<
+	$(POSTCOMPILE)
+
+mkoffload$(exeext): mkoffload.o collect-utils.o libcommon-target.a $(LIBIBERTY) $(LIBDEPS)
+	+$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
+	  mkoffload.o collect-utils.o libcommon-target.a $(LIBIBERTY) $(LIBS)
+
 nvptx-ld.o: $(srcdir)/config/nvptx/nvptx-ld.c
 	$(COMPILE) $<
 	$(POSTCOMPILE)
@@ -23,5 +33,3 @@ ar$(exeext):
 ranlib$(exeext):
 	echo -e "#! /bin/sh\n$(RANLIB) \"$$""@\"" >$@
 	chmod a+x $@
-
-
Index: git/gcc/config/nvptx/nvptx.c
===================================================================
--- git.orig/gcc/config/nvptx/nvptx.c
+++ git/gcc/config/nvptx/nvptx.c
@@ -1990,6 +1990,16 @@ nvptx_vector_alignment (const_tree type)
   return MIN (align, BIGGEST_ALIGNMENT);
 }
 \f
+/* Record a symbol for mkoffload to enter into the mapping table.  */
+
+static void
+nvptx_record_offload_symbol (tree decl)
+{
+  fprintf (asm_out_file, "//:%s_MAP %s\n",
+	   TREE_CODE (decl) == VAR_DECL ? "VAR" : "FUNC",
+	   IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
+}
+
 /* Implement TARGET_ASM_FILE_START.  Write the kinds of things ptxas expects
    at the start of a file.  */
 
@@ -2101,6 +2111,9 @@ nvptx_file_end (void)
 #undef TARGET_NO_REGISTER_ALLOCATION
 #define TARGET_NO_REGISTER_ALLOCATION true
 
+#undef TARGET_RECORD_OFFLOAD_SYMBOL
+#define TARGET_RECORD_OFFLOAD_SYMBOL nvptx_record_offload_symbol
+
 #undef TARGET_VECTOR_ALIGNMENT
 #define TARGET_VECTOR_ALIGNMENT nvptx_vector_alignment
 

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: nvptx offloading patches [4/n]
  2014-11-01 12:11 nvptx offloading patches [4/n] Bernd Schmidt
@ 2015-01-28 18:03 ` Thomas Schwinge
  2015-01-28 18:16   ` Ilya Verbin
                     ` (2 more replies)
  2015-02-11 14:44 ` Thomas Schwinge
  2015-02-18  8:26 ` nvptx mkoffload: For non-installed testing, look in all COMPILER_PATHs for GCC_INSTALL_NAME (was: nvptx offloading patches [4/n]) Thomas Schwinge
  2 siblings, 3 replies; 20+ messages in thread
From: Thomas Schwinge @ 2015-01-28 18:03 UTC (permalink / raw)
  To: GCC Patches; +Cc: Bernd Schmidt

[-- Attachment #1: Type: text/plain, Size: 25774 bytes --]

Hi!

On Sat, 1 Nov 2014 13:11:29 +0100, Bernd Schmidt <bernds@codesourcery.com> wrote:
> I'm sending this for reference more than anything else - this is the 
> patch that adds the target support for offloading to the nvptx port. It 
> depends on the other offloading patches Ilya is currently submitting.

Committed to trunk in r220209:

commit 9c08fbb35aa95420268c2762151f22a6a9b90e85
Author: tschwinge <tschwinge@138bc75d-0d04-0410-961f-82ee72b054a4>
Date:   Wed Jan 28 17:03:44 2015 +0000

    nvptx mkoffload.
    
    	gcc/
    	* config/nvptx/mkoffload.c: New file.
    	* config/nvptx/t-nvptx: Add build rules for it.
    	* config.gcc <nvptx-*> [$enable_as_accelerator = yes]
    	(extra_programs): Add mkoffload.
    	* config/nvptx/nvptx.c (nvptx_record_offload_symbol): New
    	function.
    	(TARGET_RECORD_OFFLOAD_SYMBOL): Define macro to use it.
    
    git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@220209 138bc75d-0d04-0410-961f-82ee72b054a4
---
 gcc/ChangeLog                |  12 +
 gcc/config.gcc               |   5 +-
 gcc/config/nvptx/mkoffload.c | 907 +++++++++++++++++++++++++++++++++++++++++++
 gcc/config/nvptx/nvptx.c     |  13 +
 gcc/config/nvptx/t-nvptx     |   9 +-
 5 files changed, 944 insertions(+), 2 deletions(-)

diff --git gcc/ChangeLog gcc/ChangeLog
index 6968b82..6b957bf 100644
--- gcc/ChangeLog
+++ gcc/ChangeLog
@@ -1,3 +1,15 @@
+2015-01-28  Thomas Schwinge  <thomas@codesourcery.com>
+	    Bernd Schmidt  <bernds@codesourcery.com>
+	    Nathan Sidwell  <nathan@codesourcery.com>
+
+	* config/nvptx/mkoffload.c: New file.
+	* config/nvptx/t-nvptx: Add build rules for it.
+	* config.gcc <nvptx-*> [$enable_as_accelerator = yes]
+	(extra_programs): Add mkoffload.
+	* config/nvptx/nvptx.c (nvptx_record_offload_symbol): New
+	function.
+	(TARGET_RECORD_OFFLOAD_SYMBOL): Define macro to use it.
+
 2015-01-28  Yuri Rumyantsev  <ysrumyan@gmail.com>
 
 	PR middle-end/64809
diff --git gcc/config.gcc gcc/config.gcc
index bf67beb..abd915e 100644
--- gcc/config.gcc
+++ gcc/config.gcc
@@ -2233,7 +2233,10 @@ nios2-*-*)
 nvptx-*)
 	tm_file="${tm_file} newlib-stdint.h"
 	tmake_file="nvptx/t-nvptx"
-	tm_file="${tm_file} nvptx/offload.h"
+	if test x$enable_as_accelerator = xyes; then
+		extra_programs="${extra_programs} mkoffload\$(exeext)"
+		tm_file="${tm_file} nvptx/offload.h"
+	fi
 	;;
 pdp11-*-*)
 	tm_file="${tm_file} newlib-stdint.h"
diff --git gcc/config/nvptx/mkoffload.c gcc/config/nvptx/mkoffload.c
new file mode 100644
index 0000000..9138bdd
--- /dev/null
+++ gcc/config/nvptx/mkoffload.c
@@ -0,0 +1,907 @@
+/* Offload image generation tool for PTX.
+
+   Copyright (C) 2014-2015 Free Software Foundation, Inc.
+
+   Contributed by Nathan Sidwell <nathan@codesourcery.com> and
+   Bernd Schmidt <bernds@codesourcery.com>.
+
+   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 3, 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 COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+/* Munges PTX assembly into a C source file defining the PTX code as a
+   string.
+
+   This is not a complete assembler.  We presume the source is well
+   formed from the compiler and can die horribly if it is not.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "intl.h"
+#include <libgen.h>
+#include "obstack.h"
+#include "diagnostic-core.h"
+#include "collect-utils.h"
+
+const char tool_name[] = "nvptx mkoffload";
+
+#define COMMENT_PREFIX "#"
+
+typedef enum Kind
+{
+  /* 0-ff used for single char tokens */
+  K_symbol = 0x100, /* a symbol */
+  K_label,  /* a label defn (i.e. symbol:) */
+  K_ident,  /* other ident */
+  K_dotted, /* dotted identifier */
+  K_number,
+  K_string,
+  K_comment
+} Kind;
+
+typedef struct Token
+{
+  unsigned short kind : 12;
+  unsigned short space : 1; /* preceded by space */
+  unsigned short end : 1;   /* succeeded by end of line */
+  /* Length of token */
+  unsigned short len;
+
+  /* Token itself */
+  char const *ptr;
+} Token;
+
+/* statement info */
+typedef enum Vis
+{
+  V_dot = 0,  /* random pseudo */
+  V_var = 1,  /* var decl/defn */
+  V_func = 2, /* func decl/defn */
+  V_insn = 3, /* random insn */
+  V_label = 4, /* label defn */
+  V_comment = 5,
+  V_pred = 6,  /* predicate */
+  V_mask = 0x7,
+  V_global = 0x08, /* globalize */
+  V_weak = 0x10,   /* weakly globalize */
+  V_no_eol = 0x20, /* no end of line */
+  V_prefix_comment = 0x40 /* prefixed comment */
+} Vis;
+
+typedef struct Stmt
+{
+  struct Stmt *next;
+  Token *tokens;
+  unsigned char vis;
+  unsigned len : 12;
+  unsigned sym : 12;
+} Stmt;
+
+struct id_map
+{
+  id_map *next;
+  char *ptx_name;
+};
+
+static const char *read_file (FILE *);
+static Token *tokenize (const char *);
+
+static void write_token (FILE *, const Token *);
+static void write_tokens (FILE *, const Token *, unsigned, int);
+
+static Stmt *alloc_stmt (unsigned, Token *, Token *, const Token *);
+#define alloc_comment(S,E) alloc_stmt (V_comment, S, E, 0)
+#define append_stmt(V, S) ((S)->next = *(V), *(V) = (S))
+static Stmt *rev_stmts (Stmt *);
+static void write_stmt (FILE *, const Stmt *);
+static void write_stmts (FILE *, const Stmt *);
+
+static Token *parse_insn (Token *);
+static Token *parse_list_nosemi (Token *);
+static Token *parse_init (Token *);
+static Token *parse_file (Token *);
+
+static Stmt *decls;
+static Stmt *vars;
+static Stmt *fns;
+
+static id_map *func_ids, **funcs_tail = &func_ids;
+static id_map *var_ids, **vars_tail = &var_ids;
+
+/* Files to unlink.  */
+static const char *ptx_name;
+static const char *ptx_cfile_name;
+
+/* Delete tempfiles.  */
+
+/* Unlink a temporary file unless requested otherwise.  */
+
+void
+maybe_unlink (const char *file)
+{
+  if (! debug)
+    {
+      if (unlink_if_ordinary (file)
+	  && errno != ENOENT)
+	fatal_error ("deleting file %s: %m", file);
+    }
+  else
+    fprintf (stderr, "[Leaving %s]\n", file);
+}
+
+void
+tool_cleanup (bool)
+{
+}
+
+/* Add or change the value of an environment variable, outputting the
+   change to standard error if in verbose mode.  */
+static void
+xputenv (const char *string)
+{
+  if (verbose)
+    fprintf (stderr, "%s\n", string);
+  putenv (CONST_CAST (char *, string));
+}
+
+
+static void
+record_id (const char *p1, id_map ***where)
+{
+  const char *end = strchr (p1, '\n');
+  if (!end)
+    fatal_error ("malformed ptx file");
+
+  id_map *v = XNEW (id_map);
+  size_t len = end - p1;
+  v->ptx_name = XNEWVEC (char, len + 1);
+  memcpy (v->ptx_name, p1, len);
+  v->ptx_name[len] = '\0';
+  v->next = NULL;
+  id_map **tail = *where;
+  *tail = v;
+  *where = &v->next;
+}
+
+/* Read the whole input file.  It will be NUL terminated (but
+   remember, there could be a NUL in the file itself.  */
+
+static const char *
+read_file (FILE *stream)
+{
+  size_t alloc = 16384;
+  size_t base = 0;
+  char *buffer;
+
+  if (!fseek (stream, 0, SEEK_END))
+    {
+      /* Get the file size.  */
+      long s = ftell (stream);
+      if (s >= 0)
+	alloc = s + 100;
+      fseek (stream, 0, SEEK_SET);
+    }
+  buffer = XNEWVEC (char, alloc);
+
+  for (;;)
+    {
+      size_t n = fread (buffer + base, 1, alloc - base - 1, stream);
+
+      if (!n)
+	break;
+      base += n;
+      if (base + 1 == alloc)
+	{
+	  alloc *= 2;
+	  buffer = XRESIZEVEC (char, buffer, alloc);
+	}
+    }
+  buffer[base] = 0;
+  return buffer;
+}
+
+/* Read a token, advancing ptr.
+   If we read a comment, append it to the comments block. */
+
+static Token *
+tokenize (const char *ptr)
+{
+  unsigned alloc = 1000;
+  unsigned num = 0;
+  Token *toks = XNEWVEC (Token, alloc);
+  int in_comment = 0;
+  int not_comment = 0;
+
+  for (;; num++)
+    {
+      const char *base;
+      unsigned kind;
+      int ws = 0;
+      int eol = 0;
+
+    again:
+      base = ptr;
+      if (in_comment)
+	goto block_comment;
+      switch (kind = *ptr++)
+	{
+	default:
+	  break;
+
+	case '\n':
+	  eol = 1;
+	  /* Fall through */
+	case ' ':
+	case '\t':
+	case '\r':
+	case '\v':
+	  /* White space */
+	  ws = not_comment;
+	  goto again;
+
+	case '/':
+	  {
+	    if (*ptr == '/')
+	      {
+		/* line comment.  Do not include trailing \n */
+		base += 2;
+		for (; *ptr; ptr++)
+		  if (*ptr == '\n')
+		    break;
+		kind = K_comment;
+	      }
+	    else if (*ptr == '*')
+	      {
+		/* block comment */
+		base += 2;
+		ptr++;
+
+	      block_comment:
+		eol = in_comment;
+		in_comment = 1;
+		for (; *ptr; ptr++)
+		  {
+		    if (*ptr == '\n')
+		      {
+			ptr++;
+			break;
+		      }
+		    if (ptr[0] == '*' && ptr[1] == '/')
+		      {
+			in_comment = 2;
+			ptr += 2;
+			break;
+		      }
+		  }
+		kind = K_comment;
+	      }
+	    else
+	      break;
+	  }
+	  break;
+
+	case '"':
+	  /* quoted string */
+	  kind = K_string;
+	  while (*ptr)
+	    if (*ptr == '"')
+	      {
+		ptr++;
+		break;
+	      }
+	    else if (*ptr++ == '\\')
+	      ptr++;
+	  break;
+
+	case '.':
+	  if (*ptr < '0' || *ptr > '9')
+	    {
+	      kind = K_dotted;
+	      ws = not_comment;
+	      goto ident;
+	    }
+	  /* FALLTHROUGH */
+	case '0'...'9':
+	  kind = K_number;
+	  goto ident;
+	  break;
+
+	case '$':  /* local labels.  */
+	case '%':  /* register names, pseudoes etc */
+	  kind = K_ident;
+	  goto ident;
+
+	case 'a'...'z':
+	case 'A'...'Z':
+	case '_':
+	  kind = K_symbol; /* possible symbol name */
+	ident:
+	  for (; *ptr; ptr++)
+	    {
+	      if (*ptr >= 'A' && *ptr <= 'Z')
+		continue;
+	      if (*ptr >= 'a' && *ptr <= 'z')
+		continue;
+	      if (*ptr >= '0' && *ptr <= '9')
+		continue;
+	      if (*ptr == '_' || *ptr == '$')
+		continue;
+	      if (*ptr == '.' && kind != K_dotted)
+		/* Idents starting with a dot, cannot have internal dots. */
+		continue;
+	      if ((*ptr == '+' || *ptr == '-')
+		  && kind == K_number
+		  && (ptr[-1] == 'e' || ptr[-1] == 'E'
+		      || ptr[-1] == 'p' || ptr[-1] == 'P'))
+		/* exponent */
+		continue;
+	      break;
+	    }
+	  if (*ptr == ':')
+	    {
+	      ptr++;
+	      kind = K_label;
+	    }
+	  break;
+	}
+
+      if (alloc == num)
+	{
+	  alloc *= 2;
+	  toks = XRESIZEVEC (Token, toks, alloc);
+	}
+      Token *tok = toks + num;
+
+      tok->kind = kind;
+      tok->space = ws;
+      tok->end = 0;
+      tok->ptr = base;
+      tok->len = ptr - base - in_comment;
+      in_comment &= 1;
+      not_comment = kind != K_comment;
+      if (eol && num)
+	tok[-1].end = 1;
+      if (!kind)
+	break;
+    }
+
+  return toks;
+}
+
+/* Write an encoded token. */
+
+static void
+write_token (FILE *out, Token const *tok)
+{
+  if (tok->space)
+    fputc (' ', out);
+
+  switch (tok->kind)
+    {
+    case K_string:
+      {
+	const char *c = tok->ptr + 1;
+	size_t len = tok->len - 2;
+
+	fputs ("\\\"", out);
+	while (len)
+	  {
+	    const char *bs = (const char *)memchr (c, '\\', len);
+	    size_t l = bs ? bs - c : len;
+
+	    fprintf (out, "%.*s", (int)l, c);
+	    len -= l;
+	    c += l;
+	    if (bs)
+	      {
+		fputs ("\\\\", out);
+		len--, c++;
+	      }
+	  }
+	fputs ("\\\"", out);
+      }
+      break;
+
+    default:
+      /* All other tokens shouldn't have anything magic in them */
+      fprintf (out, "%.*s", tok->len, tok->ptr);
+      break;
+    }
+  if (tok->end)
+    fputs ("\\n", out);
+}
+
+static void
+write_tokens (FILE *out, Token const *toks, unsigned len, int spc)
+{
+  fputs ("\t\"", out);
+  for (; len--; toks++)
+    write_token (out, toks);
+  if (spc)
+    fputs (" ", out);
+  fputs ("\"", out);
+}
+
+static Stmt *
+alloc_stmt (unsigned vis, Token *tokens, Token *end, Token const *sym)
+{
+  static unsigned alloc = 0;
+  static Stmt *heap = 0;
+
+  if (!alloc)
+    {
+      alloc = 1000;
+      heap = XNEWVEC (Stmt, alloc);
+    }
+
+  Stmt *stmt = heap++;
+  alloc--;
+
+  tokens->space = 0;
+  stmt->next = 0;
+  stmt->vis = vis;
+  stmt->tokens = tokens;
+  stmt->len = end - tokens;
+  stmt->sym = sym ? sym - tokens : ~0;
+
+  return stmt;
+}
+
+static Stmt *
+rev_stmts (Stmt *stmt)
+{
+  Stmt *prev = 0;
+  Stmt *next;
+
+  while (stmt)
+    {
+      next = stmt->next;
+      stmt->next = prev;
+      prev = stmt;
+      stmt = next;
+    }
+
+  return prev;
+}
+
+static void
+write_stmt (FILE *out, const Stmt *stmt)
+{
+  if ((stmt->vis & V_mask) != V_comment)
+    {
+      write_tokens (out, stmt->tokens, stmt->len,
+		    (stmt->vis & V_mask) == V_pred);
+      fputs (stmt->vis & V_no_eol ? "\t" : "\n", out);
+    }
+}
+
+static void
+write_stmts (FILE *out, const Stmt *stmts)
+{
+  for (; stmts; stmts = stmts->next)
+    write_stmt (out, stmts);
+}
+
+static Token *
+parse_insn (Token *tok)
+{
+  unsigned depth = 0;
+
+  do
+    {
+      Stmt *stmt;
+      Token *sym = 0;
+      unsigned s = V_insn;
+      Token *start = tok;
+
+      switch (tok++->kind)
+	{
+	case K_comment:
+	  while (tok->kind == K_comment)
+	    tok++;
+	  stmt = alloc_comment (start, tok);
+	  append_stmt (&fns, stmt);
+	  continue;
+
+	case '{':
+	  depth++;
+	  break;
+
+	case '}':
+	  depth--;
+	  break;
+
+	case K_label:
+	  if (tok[-1].ptr[0] != '$')
+	    sym = tok - 1;
+	  tok[-1].end = 1;
+	  s = V_label;
+	  break;
+
+	case '@':
+	  tok->space = 0;
+	  if (tok->kind == '!')
+	    tok++;
+	  if (tok->kind == K_symbol)
+	    sym = tok;
+	  tok++;
+	  s = V_pred;
+	  break;
+
+	default:
+	  for (; tok->kind != ';'; tok++)
+	    {
+	      if (tok->kind == ',')
+		tok[1].space = 0;
+	      else if (tok->kind == K_symbol)
+		sym = tok;
+	    }
+	  tok++->end = 1;
+	  break;
+	}
+
+      stmt = alloc_stmt (s, start, tok, sym);
+      append_stmt (&fns, stmt);
+
+      if (!tok[-1].end && tok[0].kind == K_comment)
+	{
+	  stmt->vis |= V_no_eol;
+	  stmt = alloc_comment (tok, tok + 1);
+	  append_stmt (&fns, stmt);
+	  tok++;
+	}
+    }
+  while (depth);
+
+  return tok;
+}
+
+/* comma separated list of tokens */
+
+static Token *
+parse_list_nosemi (Token *tok)
+{
+  Token *start = tok;
+
+  do
+    if (!(++tok)->kind)
+      break;
+  while ((++tok)->kind == ',');
+
+  tok[-1].end = 1;
+  Stmt *stmt = alloc_stmt (V_dot, start, tok, 0);
+  append_stmt (&decls, stmt);
+
+  return tok;
+}
+
+#define is_keyword(T,S) \
+  (sizeof (S) == (T)->len && !memcmp ((T)->ptr + 1, (S), (T)->len - 1))
+
+static Token *
+parse_init (Token *tok)
+{
+  for (;;)
+    {
+      Token *start = tok;
+      Token const *sym = 0;
+      Stmt *stmt;
+
+      if (tok->kind == K_comment)
+	{
+	  while (tok->kind == K_comment)
+	    tok++;
+	  stmt = alloc_comment (start, tok);
+	  append_stmt (&vars, stmt);
+	  start = tok;
+	}
+
+      if (tok->kind == '{')
+	tok[1].space = 0;
+      for (; tok->kind != ',' && tok->kind != ';'; tok++)
+	if (tok->kind == K_symbol)
+	  sym = tok;
+      tok[1].space = 0;
+      int end = tok++->kind == ';';
+      stmt = alloc_stmt (V_insn, start, tok, sym);
+      append_stmt (&vars, stmt);
+      if (!tok[-1].end && tok->kind == K_comment)
+	{
+	  stmt->vis |= V_no_eol;
+	  stmt = alloc_comment (tok, tok + 1);
+	  append_stmt (&vars, stmt);
+	  tok++;
+	}
+      if (end)
+	break;
+    }
+  return tok;
+}
+
+static Token *
+parse_file (Token *tok)
+{
+  Stmt *comment = 0;
+
+  if (tok->kind == K_comment)
+    {
+      Token *start = tok;
+
+      while (tok->kind == K_comment)
+	{
+	  if (strncmp (tok->ptr, ":VAR_MAP ", 9) == 0)
+	    record_id (tok->ptr + 9, &vars_tail);
+	  if (strncmp (tok->ptr, ":FUNC_MAP ", 10) == 0)
+	    record_id (tok->ptr + 10, &funcs_tail);
+	  tok++;
+	}
+      comment = alloc_comment (start, tok);
+      comment->vis |= V_prefix_comment;
+    }
+
+  if (tok->kind == K_dotted)
+    {
+      if (is_keyword (tok, "version")
+	  || is_keyword (tok, "target")
+	  || is_keyword (tok, "address_size"))
+	{
+	  if (comment)
+	    append_stmt (&decls, comment);
+	  tok = parse_list_nosemi (tok);
+	}
+      else
+	{
+	  unsigned vis = 0;
+	  const Token *def = 0;
+	  unsigned is_decl = 0;
+	  Token *start;
+
+	  for (start = tok;
+	       tok->kind && tok->kind != '=' && tok->kind != K_comment
+		 && tok->kind != '{' && tok->kind != ';'; tok++)
+	    {
+	      if (is_keyword (tok, "global")
+		  || is_keyword (tok, "const"))
+		vis |= V_var;
+	      else if (is_keyword (tok, "func")
+		       || is_keyword (tok, "entry"))
+		vis |= V_func;
+	      else if (is_keyword (tok, "visible"))
+		vis |= V_global;
+	      else if (is_keyword (tok, "extern"))
+		is_decl = 1;
+	      else if (is_keyword (tok, "weak"))
+		vis |= V_weak;
+	      if (tok->kind == '(')
+		{
+		  tok[1].space = 0;
+		  tok[0].space = 1;
+		}
+	      else if (tok->kind == ')' && tok[1].kind != ';')
+		tok[1].space = 1;
+
+	      if (tok->kind == K_symbol)
+		def = tok;
+	    }
+
+	  if (!tok->kind)
+	    {
+	      /* end of file */
+	      if (comment)
+		append_stmt (&fns, comment);
+	    }
+	  else if (tok->kind == '{'
+		   || tok->kind == K_comment)
+	    {
+	      /* function defn */
+	      Stmt *stmt = alloc_stmt (vis, start, tok, def);
+	      if (comment)
+		{
+		  append_stmt (&fns, comment);
+		  stmt->vis |= V_prefix_comment;
+		}
+	      append_stmt (&fns, stmt);
+	      tok = parse_insn (tok);
+	    }
+	  else
+	    {
+	      int assign = tok->kind == '=';
+
+	      tok++->end = 1;
+	      if ((vis & V_mask) == V_var && !is_decl)
+		{
+		  /* variable */
+		  Stmt *stmt = alloc_stmt (vis, start, tok, def);
+		  if (comment)
+		    {
+		      append_stmt (&vars, comment);
+		      stmt->vis |= V_prefix_comment;
+		    }
+		  append_stmt (&vars, stmt);
+		  if (assign)
+		    tok = parse_init (tok);
+		}
+	      else
+		{
+		  /* declaration */
+		  Stmt *stmt = alloc_stmt (vis, start, tok, 0);
+		  if (comment)
+		    {
+		      append_stmt (&decls, comment);
+		      stmt->vis |= V_prefix_comment;
+		    }
+		  append_stmt (&decls, stmt);
+		}
+	    }
+	}
+    }
+  else
+    {
+      /* Something strange.  Ignore it.  */
+      if (comment)
+	append_stmt (&fns, comment);
+
+      while (tok->kind && !tok->end)
+	tok++;
+    }
+  return tok;
+}
+
+static void
+process (FILE *in, FILE *out)
+{
+  const char *input = read_file (in);
+  Token *tok = tokenize (input);
+
+  do
+    tok = parse_file (tok);
+  while (tok->kind);
+
+  fprintf (out, "static const char ptx_code[] = \n");
+  write_stmts (out, rev_stmts (decls));
+  write_stmts (out, rev_stmts (vars));
+  write_stmts (out, rev_stmts (fns));
+  fprintf (out, ";\n\n");
+  fprintf (out, "static const char *var_mappings[] = {\n");
+  for (id_map *id = var_ids; id; id = id->next)
+    fprintf (out, "\t\"%s\"%s\n", id->ptx_name, id->next ? "," : "");
+  fprintf (out, "};\n\n");
+  fprintf (out, "static const char *func_mappings[] = {\n");
+  for (id_map *id = func_ids; id; id = id->next)
+    fprintf (out, "\t\"%s\"%s\n", id->ptx_name, id->next ? "," : "");
+  fprintf (out, "};\n\n");
+
+  fprintf (out, "static const void *target_data[] = {\n");
+  fprintf (out, "  ptx_code, var_mappings, func_mappings\n");
+  fprintf (out, "};\n\n");
+
+  fprintf (out, "extern void GOMP_offload_register (const void *, int, void *);\n");
+
+  fprintf (out, "extern void *__OPENMP_TARGET__[];\n\n");
+  fprintf (out, "#define PTX_ID 1\n");
+  fprintf (out, "static __attribute__((constructor)) void init (void)\n{\n");
+  fprintf (out, "  GOMP_offload_register (__OPENMP_TARGET__, PTX_ID,\n");
+  fprintf (out, "                         &target_data);\n");
+  fprintf (out, "};\n");
+}
+
+static void
+compile_native (const char *infile, const char *outfile, const char *compiler)
+{
+  const char *collect_gcc_options = getenv ("COLLECT_GCC_OPTIONS");
+  if (!collect_gcc_options)
+    fatal_error ("environment variable COLLECT_GCC_OPTIONS must be set");
+
+  struct obstack argv_obstack;
+  obstack_init (&argv_obstack);
+  obstack_ptr_grow (&argv_obstack, compiler);
+  obstack_ptr_grow (&argv_obstack, infile);
+  obstack_ptr_grow (&argv_obstack, "-c");
+  obstack_ptr_grow (&argv_obstack, "-o");
+  obstack_ptr_grow (&argv_obstack, outfile);
+  obstack_ptr_grow (&argv_obstack, NULL);
+
+  const char **new_argv = XOBFINISH (&argv_obstack, const char **);
+  fork_execute (new_argv[0], CONST_CAST (char **, new_argv), true);
+  obstack_free (&argv_obstack, NULL);
+}
+
+int
+main (int argc, char **argv)
+{
+  FILE *in = stdin;
+  FILE *out = stdout;
+  const char *outname = 0;
+
+  char *collect_gcc = getenv ("COLLECT_GCC");
+  if (collect_gcc == NULL)
+    fatal_error ("COLLECT_GCC must be set.");
+  const char *gcc_path = dirname (ASTRDUP (collect_gcc));
+  const char *gcc_exec = basename (ASTRDUP (collect_gcc));
+
+  size_t len = (strlen (gcc_path) + 1
+		+ strlen (GCC_INSTALL_NAME)
+		+ 1);
+  char *driver = XALLOCAVEC (char, len);
+
+  if (strcmp (gcc_exec, collect_gcc) == 0)
+    /* collect_gcc has no path, so it was found in PATH.  Make sure we also
+       find accel-gcc in PATH.  */
+    gcc_path = NULL;
+
+  int driver_used = 0;
+  if (gcc_path != NULL)
+    driver_used = sprintf (driver, "%s/", gcc_path);
+  sprintf (driver + driver_used, "%s", GCC_INSTALL_NAME);
+
+  /* We may be called with all the arguments stored in some file and
+     passed with @file.  Expand them into argv before processing.  */
+  expandargv (&argc, &argv);
+
+  struct obstack argv_obstack;
+  obstack_init (&argv_obstack);
+  obstack_ptr_grow (&argv_obstack, driver);
+  obstack_ptr_grow (&argv_obstack, "-xlto");
+  obstack_ptr_grow (&argv_obstack, "-m64");
+  obstack_ptr_grow (&argv_obstack, "-S");
+
+  for (int ix = 1; ix != argc; ix++)
+    {
+      if (!strcmp (argv[ix], "-o") && ix + 1 != argc)
+	outname = argv[++ix];
+      else
+	obstack_ptr_grow (&argv_obstack, argv[ix]);
+    }
+
+  ptx_name = make_temp_file (".mkoffload");
+  obstack_ptr_grow (&argv_obstack, "-o");
+  obstack_ptr_grow (&argv_obstack, ptx_name);
+  obstack_ptr_grow (&argv_obstack, NULL);
+  const char **new_argv = XOBFINISH (&argv_obstack, const char **);
+
+  char *execpath = getenv ("GCC_EXEC_PREFIX");
+  char *cpath = getenv ("COMPILER_PATH");
+  char *lpath = getenv ("LIBRARY_PATH");
+  unsetenv ("GCC_EXEC_PREFIX");
+  unsetenv ("COMPILER_PATH");
+  unsetenv ("LIBRARY_PATH");
+
+  fork_execute (new_argv[0], CONST_CAST (char **, new_argv), true);
+  obstack_free (&argv_obstack, NULL);
+
+  xputenv (concat ("GCC_EXEC_PREFIX=", execpath, NULL));
+  xputenv (concat ("COMPILER_PATH=", cpath, NULL));
+  xputenv (concat ("LIBRARY_PATH=", lpath, NULL));
+
+  in = fopen (ptx_name, "r");
+  if (!in)
+    fatal_error ("cannot open intermediate ptx file");
+
+  ptx_cfile_name = make_temp_file (".c");
+
+  out = fopen (ptx_cfile_name, "w");
+  if (!out)
+    fatal_error ("cannot open '%s'", ptx_cfile_name);
+
+  process (in, out);
+  fclose (out);
+
+  compile_native (ptx_cfile_name, outname, collect_gcc);
+
+  utils_cleanup (false);
+
+  return 0;
+}
diff --git gcc/config/nvptx/nvptx.c gcc/config/nvptx/nvptx.c
index 7cfe550..53922bc 100644
--- gcc/config/nvptx/nvptx.c
+++ gcc/config/nvptx/nvptx.c
@@ -2030,6 +2030,16 @@ nvptx_vector_alignment (const_tree type)
   return MIN (align, BIGGEST_ALIGNMENT);
 }
 \f
+/* Record a symbol for mkoffload to enter into the mapping table.  */
+
+static void
+nvptx_record_offload_symbol (tree decl)
+{
+  fprintf (asm_out_file, "//:%s_MAP %s\n",
+	   TREE_CODE (decl) == VAR_DECL ? "VAR" : "FUNC",
+	   IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
+}
+
 /* Implement TARGET_ASM_FILE_START.  Write the kinds of things ptxas expects
    at the start of a file.  */
 
@@ -2133,6 +2143,9 @@ nvptx_file_end (void)
 #undef TARGET_NO_REGISTER_ALLOCATION
 #define TARGET_NO_REGISTER_ALLOCATION true
 
+#undef TARGET_RECORD_OFFLOAD_SYMBOL
+#define TARGET_RECORD_OFFLOAD_SYMBOL nvptx_record_offload_symbol
+
 #undef TARGET_VECTOR_ALIGNMENT
 #define TARGET_VECTOR_ALIGNMENT nvptx_vector_alignment
 
diff --git gcc/config/nvptx/t-nvptx gcc/config/nvptx/t-nvptx
index 8fa2136..d53471f 100644
--- gcc/config/nvptx/t-nvptx
+++ gcc/config/nvptx/t-nvptx
@@ -1,2 +1,9 @@
-#
+CFLAGS-mkoffload.o += $(DRIVER_DEFINES) \
+	-DGCC_INSTALL_NAME=\"$(GCC_INSTALL_NAME)\"
+mkoffload.o: $(srcdir)/config/nvptx/mkoffload.c
+	$(COMPILE) $<
+	$(POSTCOMPILE)
 
+mkoffload$(exeext): mkoffload.o collect-utils.o libcommon-target.a $(LIBIBERTY) $(LIBDEPS)
+	+$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
+	  mkoffload.o collect-utils.o libcommon-target.a $(LIBIBERTY) $(LIBS)


Grüße,
 Thomas

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 472 bytes --]

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: nvptx offloading patches [4/n]
  2015-01-28 18:03 ` Thomas Schwinge
@ 2015-01-28 18:16   ` Ilya Verbin
  2015-02-11 14:20     ` Thomas Schwinge
  2015-02-11 14:19   ` Thomas Schwinge
  2015-02-11 14:20   ` Thomas Schwinge
  2 siblings, 1 reply; 20+ messages in thread
From: Ilya Verbin @ 2015-01-28 18:16 UTC (permalink / raw)
  To: Thomas Schwinge; +Cc: GCC Patches, Bernd Schmidt

On 28 Jan 18:05, Thomas Schwinge wrote:
> +  fprintf (out, "#define PTX_ID 1\n");
> +  fprintf (out, "static __attribute__((constructor)) void init (void)\n{\n");
> +  fprintf (out, "  GOMP_offload_register (__OPENMP_TARGET__, PTX_ID,\n");

The file include/gomp-constants.h already contains:
#define GOMP_DEVICE_NVIDIA_PTX          5

I guess it would be better to include gomp-constants.h into mkoffload and to use
this define.

  -- Ilya

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: nvptx offloading patches [4/n]
  2015-01-28 18:03 ` Thomas Schwinge
  2015-01-28 18:16   ` Ilya Verbin
@ 2015-02-11 14:19   ` Thomas Schwinge
  2015-02-11 14:20   ` Thomas Schwinge
  2 siblings, 0 replies; 20+ messages in thread
From: Thomas Schwinge @ 2015-02-11 14:19 UTC (permalink / raw)
  To: GCC Patches; +Cc: Bernd Schmidt

[-- Attachment #1: Type: text/plain, Size: 2458 bytes --]

Hi!

On Wed, 28 Jan 2015 18:05:25 +0100, I wrote:
> On Sat, 1 Nov 2014 13:11:29 +0100, Bernd Schmidt <bernds@codesourcery.com> wrote:
> > I'm sending this for reference more than anything else - this is the 
> > patch that adds the target support for offloading to the nvptx port. It 
> > depends on the other offloading patches Ilya is currently submitting.
> 
> Committed to trunk in r220209:
> 
> commit 9c08fbb35aa95420268c2762151f22a6a9b90e85
> Author: tschwinge <tschwinge@138bc75d-0d04-0410-961f-82ee72b054a4>
> Date:   Wed Jan 28 17:03:44 2015 +0000
> 
>     nvptx mkoffload.

Committed to trunk in r220620:

commit c84c7f1923ab042478d73029475cf7f1aab6a61a
Author: tschwinge <tschwinge@138bc75d-0d04-0410-961f-82ee72b054a4>
Date:   Wed Feb 11 14:15:38 2015 +0000

    nvptx mkoffload: __OPENMP_TARGET__ -> __OFFLOAD_TABLE__.
    
    	gcc/
    	* config/nvptx/mkoffload.c (process): Refer to __OFFLOAD_TABLE__
    	instead of __OPENMP_TARGET__.
    
    git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@220620 138bc75d-0d04-0410-961f-82ee72b054a4
---
 gcc/ChangeLog                | 3 +++
 gcc/config/nvptx/mkoffload.c | 4 ++--
 2 files changed, 5 insertions(+), 2 deletions(-)

diff --git gcc/ChangeLog gcc/ChangeLog
index 1479dcb..bc4a050 100644
--- gcc/ChangeLog
+++ gcc/ChangeLog
@@ -1,5 +1,8 @@
 2015-02-11  Thomas Schwinge  <thomas@codesourcery.com>
 
+	* config/nvptx/mkoffload.c (process): Refer to __OFFLOAD_TABLE__
+	instead of __OPENMP_TARGET__.
+
 	* config/nvptx/mkoffload.c: Include "gomp-constants.h".
 	(process): Use its GOMP_DEVICE_NVIDIA_PTX instead of (wrongly)
 	hard-coding PTX_ID.
diff --git gcc/config/nvptx/mkoffload.c gcc/config/nvptx/mkoffload.c
index 8f359cf..2287316 100644
--- gcc/config/nvptx/mkoffload.c
+++ gcc/config/nvptx/mkoffload.c
@@ -791,9 +791,9 @@ process (FILE *in, FILE *out)
 
   fprintf (out, "extern void GOMP_offload_register (const void *, int, void *);\n");
 
-  fprintf (out, "extern void *__OPENMP_TARGET__[];\n\n");
+  fprintf (out, "extern void *__OFFLOAD_TABLE__[];\n\n");
   fprintf (out, "static __attribute__((constructor)) void init (void)\n{\n");
-  fprintf (out, "  GOMP_offload_register (__OPENMP_TARGET__, %d,\n",
+  fprintf (out, "  GOMP_offload_register (__OFFLOAD_TABLE__, %d,\n",
 	   GOMP_DEVICE_NVIDIA_PTX);
   fprintf (out, "                         &target_data);\n");
   fprintf (out, "};\n");


Grüße,
 Thomas

[-- Attachment #2: Type: application/pgp-signature, Size: 472 bytes --]

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: nvptx offloading patches [4/n]
  2015-01-28 18:16   ` Ilya Verbin
@ 2015-02-11 14:20     ` Thomas Schwinge
  0 siblings, 0 replies; 20+ messages in thread
From: Thomas Schwinge @ 2015-02-11 14:20 UTC (permalink / raw)
  To: Ilya Verbin; +Cc: GCC Patches, Bernd Schmidt

[-- Attachment #1: Type: text/plain, Size: 2714 bytes --]

Hi!

On Wed, 28 Jan 2015 20:59:45 +0300, Ilya Verbin <iverbin@gmail.com> wrote:
> On 28 Jan 18:05, Thomas Schwinge wrote:
> > +  fprintf (out, "#define PTX_ID 1\n");
> > +  fprintf (out, "static __attribute__((constructor)) void init (void)\n{\n");
> > +  fprintf (out, "  GOMP_offload_register (__OPENMP_TARGET__, PTX_ID,\n");
> 
> The file include/gomp-constants.h already contains:
> #define GOMP_DEVICE_NVIDIA_PTX          5
> 
> I guess it would be better to include gomp-constants.h into mkoffload and to use
> this define.

Thanks!  You're right indeed -- I mistakenly committed an older version
of this file.  Committed to trunk in r220619:

commit ab0e6fbc36cacaa619dfacec41e17a681a28562a
Author: tschwinge <tschwinge@138bc75d-0d04-0410-961f-82ee72b054a4>
Date:   Wed Feb 11 14:15:28 2015 +0000

    nvptx mkoffload: Don't hard-code GOMP_DEVICE_NVIDIA_PTX.
    
    	gcc/
    	* config/nvptx/mkoffload.c: Include "gomp-constants.h".
    	(process): Use its GOMP_DEVICE_NVIDIA_PTX instead of (wrongly)
    	hard-coding PTX_ID.
    
    git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@220619 138bc75d-0d04-0410-961f-82ee72b054a4
---
 gcc/ChangeLog                | 6 ++++++
 gcc/config/nvptx/mkoffload.c | 5 +++--
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git gcc/ChangeLog gcc/ChangeLog
index 2fa7ff2..1479dcb 100644
--- gcc/ChangeLog
+++ gcc/ChangeLog
@@ -1,3 +1,9 @@
+2015-02-11  Thomas Schwinge  <thomas@codesourcery.com>
+
+	* config/nvptx/mkoffload.c: Include "gomp-constants.h".
+	(process): Use its GOMP_DEVICE_NVIDIA_PTX instead of (wrongly)
+	hard-coding PTX_ID.
+
 2015-02-11  H.J. Lu  <hongjiu.lu@intel.com>
 
 	* doc/sourcebuild.texi (pie_enabled): Document.
diff --git gcc/config/nvptx/mkoffload.c gcc/config/nvptx/mkoffload.c
index 38ccdba..8f359cf 100644
--- gcc/config/nvptx/mkoffload.c
+++ gcc/config/nvptx/mkoffload.c
@@ -35,6 +35,7 @@
 #include "obstack.h"
 #include "diagnostic-core.h"
 #include "collect-utils.h"
+#include "gomp-constants.h"
 
 const char tool_name[] = "nvptx mkoffload";
 
@@ -791,9 +792,9 @@ process (FILE *in, FILE *out)
   fprintf (out, "extern void GOMP_offload_register (const void *, int, void *);\n");
 
   fprintf (out, "extern void *__OPENMP_TARGET__[];\n\n");
-  fprintf (out, "#define PTX_ID 1\n");
   fprintf (out, "static __attribute__((constructor)) void init (void)\n{\n");
-  fprintf (out, "  GOMP_offload_register (__OPENMP_TARGET__, PTX_ID,\n");
+  fprintf (out, "  GOMP_offload_register (__OPENMP_TARGET__, %d,\n",
+	   GOMP_DEVICE_NVIDIA_PTX);
   fprintf (out, "                         &target_data);\n");
   fprintf (out, "};\n");
 }


Grüße,
 Thomas

[-- Attachment #2: Type: application/pgp-signature, Size: 472 bytes --]

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: nvptx offloading patches [4/n]
  2015-01-28 18:03 ` Thomas Schwinge
  2015-01-28 18:16   ` Ilya Verbin
  2015-02-11 14:19   ` Thomas Schwinge
@ 2015-02-11 14:20   ` Thomas Schwinge
  2 siblings, 0 replies; 20+ messages in thread
From: Thomas Schwinge @ 2015-02-11 14:20 UTC (permalink / raw)
  To: GCC Patches; +Cc: Bernd Schmidt

[-- Attachment #1: Type: text/plain, Size: 2450 bytes --]

Hi!

On Wed, 28 Jan 2015 18:05:25 +0100, I wrote:
> On Sat, 1 Nov 2014 13:11:29 +0100, Bernd Schmidt <bernds@codesourcery.com> wrote:
> > I'm sending this for reference more than anything else - this is the 
> > patch that adds the target support for offloading to the nvptx port. It 
> > depends on the other offloading patches Ilya is currently submitting.
> 
> Committed to trunk in r220209:
> 
> commit 9c08fbb35aa95420268c2762151f22a6a9b90e85
> Author: tschwinge <tschwinge@138bc75d-0d04-0410-961f-82ee72b054a4>
> Date:   Wed Jan 28 17:03:44 2015 +0000
> 
>     nvptx mkoffload.

Committed to trunk in r220621:

commit bfeb7c1c69130bb13265c49126e6159dbd9b8a5d
Author: tschwinge <tschwinge@138bc75d-0d04-0410-961f-82ee72b054a4>
Date:   Wed Feb 11 14:15:47 2015 +0000

    nvptx mkoffload: Initialize GCC diagnostic machinery before using it.
    
    	gcc/
    	* config/nvptx/mkoffload.c: Include "diagnostic.h" instead of
    	"diagnostic-core.h".
    	(main): Initialize progname, and call diagnostic_initialize.
    
    git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@220621 138bc75d-0d04-0410-961f-82ee72b054a4
---
 gcc/ChangeLog                | 4 ++++
 gcc/config/nvptx/mkoffload.c | 5 ++++-
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git gcc/ChangeLog gcc/ChangeLog
index bc4a050..482b128 100644
--- gcc/ChangeLog
+++ gcc/ChangeLog
@@ -1,5 +1,9 @@
 2015-02-11  Thomas Schwinge  <thomas@codesourcery.com>
 
+	* config/nvptx/mkoffload.c: Include "diagnostic.h" instead of
+	"diagnostic-core.h".
+	(main): Initialize progname, and call diagnostic_initialize.
+
 	* config/nvptx/mkoffload.c (process): Refer to __OFFLOAD_TABLE__
 	instead of __OPENMP_TARGET__.
 
diff --git gcc/config/nvptx/mkoffload.c gcc/config/nvptx/mkoffload.c
index 2287316..739aee8 100644
--- gcc/config/nvptx/mkoffload.c
+++ gcc/config/nvptx/mkoffload.c
@@ -33,7 +33,7 @@
 #include "intl.h"
 #include <libgen.h>
 #include "obstack.h"
-#include "diagnostic-core.h"
+#include "diagnostic.h"
 #include "collect-utils.h"
 #include "gomp-constants.h"
 
@@ -828,6 +828,9 @@ main (int argc, char **argv)
   FILE *out = stdout;
   const char *outname = 0;
 
+  progname = "mkoffload";
+  diagnostic_initialize (global_dc, 0);
+
   char *collect_gcc = getenv ("COLLECT_GCC");
   if (collect_gcc == NULL)
     fatal_error (input_location, "COLLECT_GCC must be set.");


Grüße,
 Thomas

[-- Attachment #2: Type: application/pgp-signature, Size: 472 bytes --]

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: nvptx offloading patches [4/n]
  2014-11-01 12:11 nvptx offloading patches [4/n] Bernd Schmidt
  2015-01-28 18:03 ` Thomas Schwinge
@ 2015-02-11 14:44 ` Thomas Schwinge
  2015-02-11 14:50   ` [nvptx] -freorder-blocks-and-partition, -freorder-functions (was: nvptx offloading patches [4/n]) Thomas Schwinge
  2015-02-11 15:21   ` nvptx offloading patches [4/n] Bernd Schmidt
  2015-02-18  8:26 ` nvptx mkoffload: For non-installed testing, look in all COMPILER_PATHs for GCC_INSTALL_NAME (was: nvptx offloading patches [4/n]) Thomas Schwinge
  2 siblings, 2 replies; 20+ messages in thread
From: Thomas Schwinge @ 2015-02-11 14:44 UTC (permalink / raw)
  To: Bernd Schmidt; +Cc: GCC Patches

[-- Attachment #1: Type: text/plain, Size: 2275 bytes --]

Hi Bernd!

On Sat, 1 Nov 2014 13:11:29 +0100, Bernd Schmidt <bernds@codesourcery.com> wrote:
> I'm sending this for reference more than anything else - this is the 
> patch that adds the target support for offloading to the nvptx port.

(I committed this in r220209.)


> I actually expect this to change a little in the near future; the nvptx 
> mkoffload duplicates some of the logic that we have in nvptx-as and I'm 
> thinking of making some improvements. But I figure it would be good to 
> show the entire picture, as it is as of now.

I'm aware this is in progress, and will replace the code I'm commenting
on below.  Just to make sure that similar issues don't exist in nvptx-as,
too.


> --- /dev/null
> +++ git/gcc/config/nvptx/mkoffload.c

> +static Token *
> +parse_file (Token *tok)
> +{
> +  [...]
> +  else
> +    {
> +      /* Something strange.  Ignore it.  */
> +      if (comment)
> +	append_stmt (&fns, comment);
> +
> +      while (tok->kind && !tok->end)
> +	tok++;
> +    }
> +  return tok;
> +}

I'm not sure if silently ignoring "strange" tokens is a good strategy?


If -freorder-blocks-and-partition is active, this results in PTX code
such as:

    // BEGIN PREAMBLE
            .version        3.1
            .target sm_30
            .address_size 64
    // END PREAMBLE
    
    $LCOLDB0:
    $LHOTB0:
    // BEGIN FUNCTION DECL: vec_mult$_omp_fn$1
    .entry vec_mult$_omp_fn$1(.param.u64 %in_ar1);
    // BEGIN FUNCTION DEF: vec_mult$_omp_fn$1
    .entry vec_mult$_omp_fn$1(.param.u64 %in_ar1)
    {
            .reg.u64 %ar1;
    [...]

Note the global cold/hot labels.  This confuses mkoffload, and it runs
into a busy loop due to what I understand to be a bug in skipping of
"strange" tokens, cited above, which such global labels would fall under.
Here is what might be a fix for this (but I didn't analyze the parsing
code in detail); OK for trunk?

--- gcc/config/nvptx/mkoffload.c
+++ gcc/config/nvptx/mkoffload.c
@@ -755,8 +755,9 @@ parse_file (Token *tok)
       if (comment)
 	append_stmt (&fns, comment);
 
-      while (tok->kind && !tok->end)
+      do
 	tok++;
+      while (tok->kind && !tok->end);
     }
   return tok;
 }


Grüße,
 Thomas

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 472 bytes --]

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [nvptx] -freorder-blocks-and-partition, -freorder-functions (was: nvptx offloading patches [4/n])
  2015-02-11 14:44 ` Thomas Schwinge
@ 2015-02-11 14:50   ` Thomas Schwinge
  2015-02-25 10:54     ` Option overriding in the offloading code path (was: [nvptx] -freorder-blocks-and-partition, -freorder-functions) Thomas Schwinge
  2015-02-11 15:21   ` nvptx offloading patches [4/n] Bernd Schmidt
  1 sibling, 1 reply; 20+ messages in thread
From: Thomas Schwinge @ 2015-02-11 14:50 UTC (permalink / raw)
  To: Bernd Schmidt; +Cc: GCC Patches, Jakub Jelinek

[-- Attachment #1: Type: text/plain, Size: 2262 bytes --]

Hi!

On Wed, 11 Feb 2015 15:44:26 +0100, I wrote:
> If -freorder-blocks-and-partition is active, this results in PTX code
> such as:
> 
>     // BEGIN PREAMBLE
>             .version        3.1
>             .target sm_30
>             .address_size 64
>     // END PREAMBLE
>     
>     $LCOLDB0:
>     $LHOTB0:
>     // BEGIN FUNCTION DECL: vec_mult$_omp_fn$1
>     .entry vec_mult$_omp_fn$1(.param.u64 %in_ar1);
>     // BEGIN FUNCTION DEF: vec_mult$_omp_fn$1
>     .entry vec_mult$_omp_fn$1(.param.u64 %in_ar1)
>     {
>             .reg.u64 %ar1;
>     [...]
> 
> Note the global cold/hot labels.

Such partitioning might not make a lot of sense for the virtual ISA that
PTX is, but disabling it in nvptx.c:nvptx_option_override does not work.
(Because that is not invoked in the offloading code path?)  I see x86 has
a ix86_option_override_internal (but I don't know how that options
processing works) -- is something like that needed for nvptx, too, and
how to interconnect that with the offloading code path?  Sounds a bit
like what Jakub suggests in <https://gcc.gnu.org/PR64374#c8>?


Maybe -freorder-functions (of no use?) should also be disabled?


Here is a WIP patch for -freorder-blocks-and-partition (missing handling
of the offloading code path) -- does something like that make sense?

--- gcc/config/nvptx/nvptx.c
+++ gcc/config/nvptx/nvptx.c
@@ -93,6 +93,18 @@ nvptx_option_override (void)
   init_machine_status = nvptx_init_machine_status;
   /* Gives us a predictable order, which we need especially for variables.  */
   flag_toplevel_reorder = 1;
+  /* If enabled, global cold/hot labels will be emitted, which our mkoffload
+     currently doesn't cope with.  Also, it's not clear whether such
+     partitioning actually has any positive effect on the virtual ISA that PTX
+     is.  */
+  if (flag_reorder_blocks_and_partition)
+    {
+      inform (input_location,
+	      "-freorder-blocks-and-partition not supported on this "
+	      "architecture");
+      flag_reorder_blocks_and_partition = 0;
+      flag_reorder_blocks = 1;
+    }
   /* Assumes that it will see only hard registers.  */
   flag_var_tracking = 0;
   write_symbols = NO_DEBUG;


Grüße,
 Thomas

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 472 bytes --]

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: nvptx offloading patches [4/n]
  2015-02-11 14:44 ` Thomas Schwinge
  2015-02-11 14:50   ` [nvptx] -freorder-blocks-and-partition, -freorder-functions (was: nvptx offloading patches [4/n]) Thomas Schwinge
@ 2015-02-11 15:21   ` Bernd Schmidt
  2015-02-17 18:14     ` Thomas Schwinge
  1 sibling, 1 reply; 20+ messages in thread
From: Bernd Schmidt @ 2015-02-11 15:21 UTC (permalink / raw)
  To: Thomas Schwinge; +Cc: GCC Patches

On 02/11/2015 03:44 PM, Thomas Schwinge wrote:
> Note the global cold/hot labels.  This confuses mkoffload, and it runs
> into a busy loop due to what I understand to be a bug in skipping of
> "strange" tokens, cited above, which such global labels would fall under.
> Here is what might be a fix for this (but I didn't analyze the parsing
> code in detail); OK for trunk?

I'd rather fail if anything unexpected is seen. Things like 
-freorder-blocks-and-partition should be forced off in 
nvptx_option_override.


Bernd

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: nvptx offloading patches [4/n]
  2015-02-11 15:21   ` nvptx offloading patches [4/n] Bernd Schmidt
@ 2015-02-17 18:14     ` Thomas Schwinge
  0 siblings, 0 replies; 20+ messages in thread
From: Thomas Schwinge @ 2015-02-17 18:14 UTC (permalink / raw)
  To: Bernd Schmidt; +Cc: GCC Patches

[-- Attachment #1: Type: text/plain, Size: 854 bytes --]

Hi!

On Wed, 11 Feb 2015 16:20:51 +0100, Bernd Schmidt <bernds@codesourcery.com> wrote:
> On 02/11/2015 03:44 PM, Thomas Schwinge wrote:
> > Note the global cold/hot labels.  This confuses mkoffload, and it runs
> > into a busy loop due to what I understand to be a bug in skipping of
> > "strange" tokens, cited above, which such global labels would fall under.
> > Here is what might be a fix for this (but I didn't analyze the parsing
> > code in detail); OK for trunk?

Committed to trunk in r220769.


> I'd rather fail if anything unexpected is seen. Things like 
> -freorder-blocks-and-partition should be forced off in 
> nvptx_option_override.

Yes; that's basically what I suggested in my other email,
<http://news.gmane.org/find-root.php?message_id=%3C87a90klcyb.fsf%40kepler.schwinge.homeip.net%3E>.


Grüße,
 Thomas

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 472 bytes --]

^ permalink raw reply	[flat|nested] 20+ messages in thread

* nvptx mkoffload: For non-installed testing, look in all COMPILER_PATHs for GCC_INSTALL_NAME (was: nvptx offloading patches [4/n])
  2014-11-01 12:11 nvptx offloading patches [4/n] Bernd Schmidt
  2015-01-28 18:03 ` Thomas Schwinge
  2015-02-11 14:44 ` Thomas Schwinge
@ 2015-02-18  8:26 ` Thomas Schwinge
  2 siblings, 0 replies; 20+ messages in thread
From: Thomas Schwinge @ 2015-02-18  8:26 UTC (permalink / raw)
  To: GCC Patches; +Cc: Bernd Schmidt, ilya.verbin, andrey.turetskiy

[-- Attachment #1: Type: text/plain, Size: 5010 bytes --]

Hi!

On Sat, 1 Nov 2014 13:11:29 +0100, Bernd Schmidt <bernds@codesourcery.com> wrote:
> [nvptx mkoffload]

To support the --enable-offload-targets=nvptx-none=[install directory]
configuration option, I committed the following to trunk in r220782 (and
filed <https://gcc.gnu.org/PR65097>):

commit a7243b5200794d53b01d59fa69d467a0545db73f
Author: tschwinge <tschwinge@138bc75d-0d04-0410-961f-82ee72b054a4>
Date:   Wed Feb 18 08:17:32 2015 +0000

    nvptx mkoffload: For non-installed testing, look in all COMPILER_PATHs for GCC_INSTALL_NAME.
    
    	gcc/
    	* config/nvptx/mkoffload.c (parse_env_var, free_array_of_ptrs)
    	(access_check): New functions, copied from
    	config/i386/intelmic-mkoffload.c.
    	(main): For non-installed testing, look in all COMPILER_PATHs for
    	GCC_INSTALL_NAME.
    
    git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@220782 138bc75d-0d04-0410-961f-82ee72b054a4
---
 gcc/ChangeLog                |    6 +++
 gcc/config/nvptx/mkoffload.c |  103 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 109 insertions(+)

diff --git gcc/ChangeLog gcc/ChangeLog
index 180a605..0f144f5 100644
--- gcc/ChangeLog
+++ gcc/ChangeLog
@@ -1,5 +1,11 @@
 2015-02-18  Thomas Schwinge  <thomas@codesourcery.com>
 
+	* config/nvptx/mkoffload.c (parse_env_var, free_array_of_ptrs)
+	(access_check): New functions, copied from
+	config/i386/intelmic-mkoffload.c.
+	(main): For non-installed testing, look in all COMPILER_PATHs for
+	GCC_INSTALL_NAME.
+
 	* config/nvptx/nvptx.h (GOMP_SELF_SPECS): Define macro.
 
 2015-02-18  Andrew Pinski  <apinski@cavium.com>
diff --git gcc/config/nvptx/mkoffload.c gcc/config/nvptx/mkoffload.c
index 96341b8..02c44b6 100644
--- gcc/config/nvptx/mkoffload.c
+++ gcc/config/nvptx/mkoffload.c
@@ -762,6 +762,78 @@ parse_file (Token *tok)
   return tok;
 }
 
+/* Parse STR, saving found tokens into PVALUES and return their number.
+   Tokens are assumed to be delimited by ':'.  */
+static unsigned
+parse_env_var (const char *str, char ***pvalues)
+{
+  const char *curval, *nextval;
+  char **values;
+  unsigned num = 1, i;
+
+  curval = strchr (str, ':');
+  while (curval)
+    {
+      num++;
+      curval = strchr (curval + 1, ':');
+    }
+
+  values = (char **) xmalloc (num * sizeof (char *));
+  curval = str;
+  nextval = strchr (curval, ':');
+  if (nextval == NULL)
+    nextval = strchr (curval, '\0');
+
+  for (i = 0; i < num; i++)
+    {
+      int l = nextval - curval;
+      values[i] = (char *) xmalloc (l + 1);
+      memcpy (values[i], curval, l);
+      values[i][l] = 0;
+      curval = nextval + 1;
+      nextval = strchr (curval, ':');
+      if (nextval == NULL)
+	nextval = strchr (curval, '\0');
+    }
+  *pvalues = values;
+  return num;
+}
+
+/* Auxiliary function that frees elements of PTR and PTR itself.
+   N is number of elements to be freed.  If PTR is NULL, nothing is freed.
+   If an element is NULL, subsequent elements are not freed.  */
+static void
+free_array_of_ptrs (void **ptr, unsigned n)
+{
+  unsigned i;
+  if (!ptr)
+    return;
+  for (i = 0; i < n; i++)
+    {
+      if (!ptr[i])
+	break;
+      free (ptr[i]);
+    }
+  free (ptr);
+  return;
+}
+
+/* Check whether NAME can be accessed in MODE.  This is like access,
+   except that it never considers directories to be executable.  */
+static int
+access_check (const char *name, int mode)
+{
+  if (mode == X_OK)
+    {
+      struct stat st;
+
+      if (stat (name, &st) < 0 || S_ISDIR (st.st_mode))
+	return -1;
+    }
+
+  return access (name, mode);
+}
+
 static void
 process (FILE *in, FILE *out)
 {
@@ -853,6 +925,37 @@ main (int argc, char **argv)
     driver_used = sprintf (driver, "%s/", gcc_path);
   sprintf (driver + driver_used, "%s", GCC_INSTALL_NAME);
 
+  bool found = false;
+  if (gcc_path == NULL)
+    found = true;
+  else if (access_check (driver, X_OK) == 0)
+    found = true;
+  else
+    {
+      /* Don't use alloca pointer with XRESIZEVEC.  */
+      driver = NULL;
+      /* Look in all COMPILER_PATHs for GCC_INSTALL_NAME.  */
+      char **paths = NULL;
+      unsigned n_paths;
+      n_paths = parse_env_var (getenv ("COMPILER_PATH"), &paths);
+      for (unsigned i = 0; i < n_paths; i++)
+	{
+	  len = strlen (paths[i]) + 1 + strlen (GCC_INSTALL_NAME) + 1;
+	  driver = XRESIZEVEC (char, driver, len);
+	  sprintf (driver, "%s/%s", paths[i], GCC_INSTALL_NAME);
+	  if (access_check (driver, X_OK) == 0)
+	    {
+	      found = true;
+	      break;
+	    }
+	}
+      free_array_of_ptrs ((void **) paths, n_paths);
+    }
+
+  if (!found)
+    fatal_error (input_location,
+		 "offload compiler %s not found", GCC_INSTALL_NAME);
+
   /* We may be called with all the arguments stored in some file and
      passed with @file.  Expand them into argv before processing.  */
   expandargv (&argc, &argv);


Grüße,
 Thomas

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 472 bytes --]

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Option overriding in the offloading code path (was: [nvptx] -freorder-blocks-and-partition, -freorder-functions)
  2015-02-11 14:50   ` [nvptx] -freorder-blocks-and-partition, -freorder-functions (was: nvptx offloading patches [4/n]) Thomas Schwinge
@ 2015-02-25 10:54     ` Thomas Schwinge
  2015-02-25 13:23       ` Option overriding in the offloading code path Bernd Schmidt
                         ` (2 more replies)
  0 siblings, 3 replies; 20+ messages in thread
From: Thomas Schwinge @ 2015-02-25 10:54 UTC (permalink / raw)
  To: Bernd Schmidt, Jakub Jelinek; +Cc: GCC Patches

[-- Attachment #1: Type: text/plain, Size: 4408 bytes --]

Hi!

On Wed, 11 Feb 2015 15:50:20 +0100, I wrote:
> On Wed, 11 Feb 2015 15:44:26 +0100, I wrote:
> > If -freorder-blocks-and-partition is active, this results in PTX code
> > such as: [...]

> Such partitioning might not make a lot of sense for the virtual ISA that
> PTX is, but disabling it in nvptx.c:nvptx_option_override does not work.
> (Because that is not invoked in the offloading code path?)  I see x86 has
> a ix86_option_override_internal (but I don't know how that options
> processing works) -- is something like that needed for nvptx, too, and
> how to interconnect that with the offloading code path?  Sounds a bit
> like what Jakub suggests in <https://gcc.gnu.org/PR64374#c8>?

Am I on the right track with my assumption that it is correct that
nvptx.c:nvptx_option_override is not invoked in the offloading code path,
so we'd need a new target hook (?) to consolidate/override the options in
this scenario?


Using this to forcefully disable -fvar-tracking (as done in
nvptx_option_override), should then allow me to drop the following
beautiful specimen of a patch (which I didn't commit anywhere, so far):

commit ab5a010357f4c7347dd892f3666cdeecd08cc083
Author: Thomas Schwinge <thomas@codesourcery.com>
Date:   Mon Feb 16 13:57:08 2015 +0100

    libgomp Fortran testing: for -g torture testing, disable variable tracking.
    
    Otherwise, the nvptx-none offloading compiler will run into issues such as:
    
        source-gcc/libgomp/testsuite/libgomp.fortran/examples-4/e.50.1.f90: In function '__e_50_1_mod_MOD_vec_mult._omp_fn.1':
        source-gcc/libgomp/testsuite/libgomp.fortran/examples-4/e.50.1.f90:31:0: internal compiler error: in use_type, at var-tracking.c:5442
                 p(i) = v1(i) * v2(i)
         ^
        0xc4dc72 use_type
                source-gcc/gcc/var-tracking.c:5442
        0xc504b3 add_stores
                source-gcc/gcc/var-tracking.c:5869
        0xc4cd28 add_with_sets
                source-gcc/gcc/var-tracking.c:6553
        0x5e9b7d cselib_record_sets
                source-gcc/gcc/cselib.c:2574
        0x5ea8a7 cselib_process_insn(rtx_insn*)
                source-gcc/gcc/cselib.c:2686
        0xc586a3 vt_initialize
                source-gcc/gcc/var-tracking.c:10126
        0xc65a8e variable_tracking_main_1
                source-gcc/gcc/var-tracking.c:10322
        0xc65a8e variable_tracking_main
                source-gcc/gcc/var-tracking.c:10375
        0xc65a8e execute
                source-gcc/gcc/var-tracking.c:10412
        Please submit a full bug report,
        with preprocessed source if appropriate.
        Please include the complete backtrace with any bug report.
        See <http://gcc.gnu.org/bugs.html> for instructions.
        mkoffload: fatal error: install/offload-nvptx-none/bin//x86_64-unknown-linux-gnu-accel-nvptx-none-gcc returned 1 exit status
---
 libgomp/testsuite/libgomp.fortran/fortran.exp      |    3 +++
 libgomp/testsuite/libgomp.oacc-fortran/fortran.exp |    3 +++
 2 files changed, 6 insertions(+)

diff --git libgomp/testsuite/libgomp.fortran/fortran.exp libgomp/testsuite/libgomp.fortran/fortran.exp
index 9e6b643..0b597e6 100644
--- libgomp/testsuite/libgomp.fortran/fortran.exp
+++ libgomp/testsuite/libgomp.fortran/fortran.exp
@@ -21,6 +21,9 @@ dg-init
 # Turn on OpenMP.
 lappend ALWAYS_CFLAGS "additional_flags=-fopenmp"
 
+# TODO: for -g torture testing, disable variable tracking.
+regsub -all -- { -g[^ ]*} $DG_TORTURE_OPTIONS {& -fno-var-tracking} DG_TORTURE_OPTIONS
+
 if { $blddir != "" } {
     set lang_source_re {^.*\.[fF](|90|95|03|08)$}
     set lang_include_flags "-fintrinsic-modules-path=${blddir}"
diff --git libgomp/testsuite/libgomp.oacc-fortran/fortran.exp libgomp/testsuite/libgomp.oacc-fortran/fortran.exp
index a8f62e8..080a7b9 100644
--- libgomp/testsuite/libgomp.oacc-fortran/fortran.exp
+++ libgomp/testsuite/libgomp.oacc-fortran/fortran.exp
@@ -23,6 +23,9 @@ dg-init
 # Turn on OpenACC.
 lappend ALWAYS_CFLAGS "additional_flags=-fopenacc"
 
+# TODO: for -g torture testing, disable variable tracking.
+regsub -all -- { -g[^ ]*} $DG_TORTURE_OPTIONS {& -fno-var-tracking} DG_TORTURE_OPTIONS
+
 if { $blddir != "" } {
     set lang_source_re {^.*\.[fF](|90|95|03|08)$}
     set lang_include_flags "-fintrinsic-modules-path=${blddir}"


Grüße,
 Thomas

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 472 bytes --]

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Option overriding in the offloading code path
  2015-02-25 10:54     ` Option overriding in the offloading code path (was: [nvptx] -freorder-blocks-and-partition, -freorder-functions) Thomas Schwinge
@ 2015-02-25 13:23       ` Bernd Schmidt
  2015-02-25 17:15       ` Option overriding in the offloading code path (was: [nvptx] -freorder-blocks-and-partition, -freorder-functions) Jakub Jelinek
  2015-03-13  9:07       ` Option overriding in the offloading code path Thomas Schwinge
  2 siblings, 0 replies; 20+ messages in thread
From: Bernd Schmidt @ 2015-02-25 13:23 UTC (permalink / raw)
  To: Thomas Schwinge, Jakub Jelinek; +Cc: GCC Patches

On 02/25/2015 11:28 AM, Thomas Schwinge wrote:

> Am I on the right track with my assumption that it is correct that
> nvptx.c:nvptx_option_override is not invoked in the offloading code path,
> so we'd need a new target hook (?) to consolidate/override the options in
> this scenario?

I'm surprised by this. Does lto1 not go through do_compile? I guess 
that's plausible, but I think in that case we should invoke this hook if 
ACCEL_COMPILER.


Bernd

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Option overriding in the offloading code path (was: [nvptx] -freorder-blocks-and-partition, -freorder-functions)
  2015-02-25 10:54     ` Option overriding in the offloading code path (was: [nvptx] -freorder-blocks-and-partition, -freorder-functions) Thomas Schwinge
  2015-02-25 13:23       ` Option overriding in the offloading code path Bernd Schmidt
@ 2015-02-25 17:15       ` Jakub Jelinek
  2015-02-26 10:42         ` var-tracking vs. pseudo registers (was: Option overriding in the offloading code path) Thomas Schwinge
  2015-03-13  9:07       ` Option overriding in the offloading code path Thomas Schwinge
  2 siblings, 1 reply; 20+ messages in thread
From: Jakub Jelinek @ 2015-02-25 17:15 UTC (permalink / raw)
  To: Thomas Schwinge; +Cc: Bernd Schmidt, GCC Patches

On Wed, Feb 25, 2015 at 11:28:12AM +0100, Thomas Schwinge wrote:
> Am I on the right track with my assumption that it is correct that
> nvptx.c:nvptx_option_override is not invoked in the offloading code path,
> so we'd need a new target hook (?) to consolidate/override the options in
> this scenario?
> 
> 
> Using this to forcefully disable -fvar-tracking (as done in
> nvptx_option_override), should then allow me to drop the following
> beautiful specimen of a patch (which I didn't commit anywhere, so far):

Supposedly you could just disable var-tracking for
targetm.no_register_allocation case, or change that assert to
allow pseudos for targetm.no_register_allocation?

Anyway, if var-tracking is never useful for NVPTX, if you want to override
it early, flag_var_tracking* options are Optimization options, thus you'd
need a target hook similar to the one I've added today, but instead of
TARGET_OPTION_NODE do something similar for OPTIMIZATION_NODE streaming.

	Jakub

^ permalink raw reply	[flat|nested] 20+ messages in thread

* var-tracking vs. pseudo registers (was: Option overriding in the offloading code path)
  2015-02-25 17:15       ` Option overriding in the offloading code path (was: [nvptx] -freorder-blocks-and-partition, -freorder-functions) Jakub Jelinek
@ 2015-02-26 10:42         ` Thomas Schwinge
  2015-02-26 10:53           ` Jakub Jelinek
  0 siblings, 1 reply; 20+ messages in thread
From: Thomas Schwinge @ 2015-02-26 10:42 UTC (permalink / raw)
  To: Jakub Jelinek, Bernd Schmidt; +Cc: GCC Patches


[-- Attachment #1.1: Type: text/plain, Size: 4852 bytes --]

Hi!

On Wed, 25 Feb 2015 18:00:54 +0100, Jakub Jelinek <jakub@redhat.com> wrote:
> On Wed, Feb 25, 2015 at 11:28:12AM +0100, Thomas Schwinge wrote:
> > Am I on the right track with my assumption that it is correct that
> > nvptx.c:nvptx_option_override is not invoked in the offloading code path,
> > so we'd need a new target hook (?) to consolidate/override the options in
> > this scenario?
> > 
> > 
> > Using this to forcefully disable -fvar-tracking (as done in
> > nvptx_option_override), should then allow me to drop the following
> > beautiful specimen of a patch (which I didn't commit anywhere, so far):
> 
> Supposedly you could just disable var-tracking for
> targetm.no_register_allocation case, or change that assert to
> allow pseudos for targetm.no_register_allocation?

Just changing the assert, or handling this configuration differently:

diff --git gcc/var-tracking.c gcc/var-tracking.c
index 9ec5d8b..e37dc19 100644
--- gcc/var-tracking.c
+++ gcc/var-tracking.c
@@ -5439,6 +5449,10 @@ use_type (rtx loc, struct count_use_info *cui, machine_mode *modep)
 
   if (REG_P (loc))
     {
+      if (targetm.no_register_allocation)
+	if (REGNO (loc) >= FIRST_PSEUDO_REGISTER)
+	  return MO_CLOBBER;
+
       gcc_assert (REGNO (loc) < FIRST_PSEUDO_REGISTER);
 
       if (loc == cfa_base_rtx)

... is not enough: by the looks of it, the var-tracking code is just not
prepared to see pseudo registers, for example:

    /* Structure holding the IN or OUT set for a basic block.  */
    typedef struct dataflow_set_def
    {
    [...]
      /* Attributes for registers (lists of attrs).  */
      attrs regs[FIRST_PSEUDO_REGISTER];
    [...]

..., which is asserted in several places (one of which we stumbled over;
I added more in the attached var-tracking-asserts.patch).  I tried
disabling it:

diff --git gcc/var-tracking.c gcc/var-tracking.c
index 9ec5d8b..e37dc19 100644
--- gcc/var-tracking.c
+++ gcc/var-tracking.c
@@ -10404,7 +10421,10 @@ public:
   /* opt_pass methods: */
   virtual bool gate (function *)
     {
-      return (flag_var_tracking && !targetm.delay_vartrack);
+      return (flag_var_tracking
+	      && !targetm.delay_vartrack
+	      /* This code is not prepared to handle pseudo registers.  */
+	      && !targetm.no_register_allocation);
     }
 
   virtual unsigned int execute (function *)

..., but then we run into:

    $ build-gcc/gcc/xgcc -Bbuild-gcc/gcc/ -Bbuild-gcc/x86_64-unknown-linux-gnu/lib{gomp,gfortran}/ -Bbuild-gcc/x86_64-unknown-linux-gnu/lib{gomp,gfortran}/.libs -Ibuild-gcc/x86_64-unknown-linux-gnu/lib{gomp,gfortran} -Isource-gcc/{include,lib{gomp,gfortran}} -Lbuild-gcc/x86_64-unknown-linux-gnu/lib{gomp,gfortran}/.libs -Wl,-rpath,"$PWD"/build-gcc/x86_64-unknown-linux-gnu/lib{gomp,gfortran}/.libs source-gcc/libgomp/testsuite/libgomp.fortran/examples-4/e.50.1.f90 -Wall -Wextra -O2 -fopenmp -lgfortran -g
    source-gcc/libgomp/testsuite/libgomp.fortran/examples-4/e.50.1.f90: In function '__e_50_1_mod_MOD_vec_mult._omp_fn.1':
    source-gcc/libgomp/testsuite/libgomp.fortran/examples-4/e.50.1.f90:31:0: internal compiler error: in get_insn_template, at final.c:2124
             p(i) = v1(i) * v2(i)
     ^
    0x6b3765 get_insn_template(int, rtx_def*)
            [...]/source-gcc/gcc/final.c:2124
    0x6b55de final_scan_insn(rtx_insn*, _IO_FILE*, int, int, int*)
            [...]/source-gcc/gcc/final.c:2986
    0x6b6bff final(rtx_insn*, _IO_FILE*, int)
            [...]/source-gcc/gcc/final.c:2089
    0x6b76e9 rest_of_handle_final
            [...]/source-gcc/gcc/final.c:4488
    0x6b76e9 execute
            [...]/source-gcc/gcc/final.c:4563
    [...]
    mkoffload: fatal error: build-gcc/gcc/x86_64-unknown-linux-gnu-accel-nvptx-none-gcc returned 1 exit status
    [...]

Is this not the right way to skip it, or, Bernd, is this because we're
not yet handling some debug stuff in nvptx?  (I tested that
<http://news.gmane.org/find-root.php?message_id=%3C5466473A.1090809%40codesourcery.com%3E>
does not help with that.)  The following does make it work (that is,
resolve the ICEs), but that feels a bit too much ;-) of a hack:

--- gcc/var-tracking.c
+++ gcc/var-tracking.c
@@ -10305,7 +10322,8 @@ variable_tracking_main_1 (void)
 {
   bool success;
 
-  if (flag_var_tracking_assignments < 0)
+  if (flag_var_tracking_assignments < 0
+      || targetm.no_register_allocation)
     {
       delete_debug_insns ();
       return 0;


> Anyway, if var-tracking is never useful for NVPTX, if you want to override
> it early, flag_var_tracking* options are Optimization options, thus you'd
> need a target hook similar to the one I've added today, but instead of
> TARGET_OPTION_NODE do something similar for OPTIMIZATION_NODE streaming.


Grüße,
 Thomas



[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1.2: var-tracking-asserts.patch --]
[-- Type: text/x-diff, Size: 3847 bytes --]

diff --git gcc/var-tracking.c gcc/var-tracking.c
index 9ec5d8b..e37dc19 100644
--- gcc/var-tracking.c
+++ gcc/var-tracking.c
@@ -1854,6 +1854,7 @@ var_reg_decl_set (dataflow_set *set, rtx loc, enum var_init_status initialized,
   if (decl_p)
     dv = dv_from_decl (var_debug_decl (dv_as_decl (dv)));
 
+  gcc_assert (REGNO (loc) < FIRST_PSEUDO_REGISTER);
   for (node = set->regs[REGNO (loc)]; node; node = node->next)
     if (dv_as_opaque (node->dv) == dv_as_opaque (dv)
 	&& node->offset == offset)
@@ -1925,6 +1926,7 @@ var_reg_delete_and_set (dataflow_set *set, rtx loc, bool modify,
   if (initialized == VAR_INIT_STATUS_UNKNOWN)
     initialized = get_init_value (set, loc, dv_from_decl (decl));
 
+  gcc_assert (REGNO (loc) < FIRST_PSEUDO_REGISTER);
   nextp = &set->regs[REGNO (loc)];
   for (node = *nextp; node; node = next)
     {
@@ -1954,6 +1956,7 @@ var_reg_delete_and_set (dataflow_set *set, rtx loc, bool modify,
 static void
 var_reg_delete (dataflow_set *set, rtx loc, bool clobber)
 {
+  gcc_assert (REGNO (loc) < FIRST_PSEUDO_REGISTER);
   attrs *nextp = &set->regs[REGNO (loc)];
   attrs node, next;
 
@@ -1986,6 +1989,7 @@ var_reg_delete (dataflow_set *set, rtx loc, bool clobber)
 static void
 var_regno_delete (dataflow_set *set, int regno)
 {
+  gcc_assert (regno < FIRST_PSEUDO_REGISTER);
   attrs *reg = &set->regs[regno];
   attrs node, next;
 
@@ -2630,6 +2634,7 @@ val_resolve (dataflow_set *set, rtx val, rtx loc, rtx_insn *insn)
     {
       attrs node, found = NULL;
 
+      gcc_assert (REGNO (loc) < FIRST_PSEUDO_REGISTER);
       for (node = set->regs[REGNO (loc)]; node; node = node->next)
 	if (dv_is_value_p (node->dv)
 	    && GET_MODE (dv_as_value (node->dv)) == GET_MODE (loc))
@@ -3784,6 +3789,7 @@ canonicalize_values_star (variable_def **slot, dataflow_set *set)
 	  }
 	else if (GET_CODE (node->loc) == REG)
 	  {
+	    gcc_assert (REGNO (node->loc) < FIRST_PSEUDO_REGISTER);
 	    attrs list = set->regs[REGNO (node->loc)], *listp;
 
 	    /* Change an existing attribute referring to dv so that it
@@ -4045,6 +4051,7 @@ variable_merge_over_cur (variable s1var, struct dfset_merge *dsm)
 	{
 	  attrs list;
 
+	  gcc_assert (REGNO (node->loc) < FIRST_PSEUDO_REGISTER);
 	  for (list = dst->regs[REGNO (node->loc)]; list; list = list->next)
 	    if (GET_MODE (node->loc) == GET_MODE (list->loc)
 		&& dv_is_value_p (list->dv))
@@ -4426,6 +4433,7 @@ variable_post_merge_new_vals (variable_def **slot, dfset_post_merge *dfpm)
 		  goto restart;
 		}
 
+	      gcc_assert (REGNO (node->loc) < FIRST_PSEUDO_REGISTER);
 	      for (attp = &set->regs[REGNO (node->loc)]; (att = *attp);
 		   attp = &att->next)
 		if (att->offset == 0
@@ -4466,6 +4474,7 @@ variable_post_merge_new_vals (variable_def **slot, dfset_post_merge *dfpm)
 		      dataflow_set_init (*dfpm->permp);
 		    }
 
+		  gcc_assert (REGNO (node->loc) < FIRST_PSEUDO_REGISTER);
 		  for (att = (*dfpm->permp)->regs[REGNO (node->loc)];
 		       att; att = att->next)
 		    if (GET_MODE (att->loc) == GET_MODE (node->loc))
@@ -4561,6 +4570,7 @@ variable_post_merge_perm_vals (variable_def **pslot, dfset_post_merge *dfpm)
       val_reset (set, dv);
     }
 
+  gcc_assert (REGNO (pnode->loc) < FIRST_PSEUDO_REGISTER);
   for (att = set->regs[REGNO (pnode->loc)]; att; att = att->next)
     if (att->offset == 0
 	&& GET_MODE (att->loc) == GET_MODE (pnode->loc)
@@ -7837,6 +7853,7 @@ clobber_slot_part (dataflow_set *set, rtx loc, variable_def **slot,
 		     list, but preserve any other variable parts
 		     that might be regarded as live in that same
 		     register.  */
+		  gcc_assert (REGNO (node->loc) < FIRST_PSEUDO_REGISTER);
 		  anextp = &set->regs[REGNO (node->loc)];
 		  for (anode = *anextp; anode; anode = anext)
 		    {

[-- Attachment #2: Type: application/pgp-signature, Size: 472 bytes --]

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: var-tracking vs. pseudo registers (was: Option overriding in the offloading code path)
  2015-02-26 10:42         ` var-tracking vs. pseudo registers (was: Option overriding in the offloading code path) Thomas Schwinge
@ 2015-02-26 10:53           ` Jakub Jelinek
  2015-03-26 11:00             ` [PATCH] Don't run var-tracking for targetm.no_register_allocation targets Jakub Jelinek
  0 siblings, 1 reply; 20+ messages in thread
From: Jakub Jelinek @ 2015-02-26 10:53 UTC (permalink / raw)
  To: Thomas Schwinge; +Cc: Bernd Schmidt, GCC Patches

On Thu, Feb 26, 2015 at 11:27:06AM +0100, Thomas Schwinge wrote:
> Is this not the right way to skip it, or, Bernd, is this because we're
> not yet handling some debug stuff in nvptx?  (I tested that
> <http://news.gmane.org/find-root.php?message_id=%3C5466473A.1090809%40codesourcery.com%3E>
> does not help with that.)  The following does make it work (that is,
> resolve the ICEs), but that feels a bit too much ;-) of a hack:
> 
> --- gcc/var-tracking.c
> +++ gcc/var-tracking.c
> @@ -10305,7 +10322,8 @@ variable_tracking_main_1 (void)
>  {
>    bool success;
>  
> -  if (flag_var_tracking_assignments < 0)
> +  if (flag_var_tracking_assignments < 0
> +      || targetm.no_register_allocation)
>      {
>        delete_debug_insns ();
>        return 0;

No, IMHO that is the right fix, not a hack.  But of course would deserve
a comment.  Plus of course you can also just override
flag_var_tracking_assignments in the nvptx override option hook, and
perhaps in tree-streamer-in.c clear flag_var_tracking_assignments in the
OPTIMIZATION_NODE too (or just add a hook for that, as I said before).

	Jakub

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Option overriding in the offloading code path
  2015-02-25 10:54     ` Option overriding in the offloading code path (was: [nvptx] -freorder-blocks-and-partition, -freorder-functions) Thomas Schwinge
  2015-02-25 13:23       ` Option overriding in the offloading code path Bernd Schmidt
  2015-02-25 17:15       ` Option overriding in the offloading code path (was: [nvptx] -freorder-blocks-and-partition, -freorder-functions) Jakub Jelinek
@ 2015-03-13  9:07       ` Thomas Schwinge
  2 siblings, 0 replies; 20+ messages in thread
From: Thomas Schwinge @ 2015-03-13  9:07 UTC (permalink / raw)
  To: GCC Patches; +Cc: Bernd Schmidt, Jakub Jelinek

[-- Attachment #1: Type: text/plain, Size: 4807 bytes --]

Hi!

On Wed, 25 Feb 2015 11:28:12 +0100, I wrote:
> Using [...] to forcefully disable -fvar-tracking (as done in
> nvptx_option_override), should then allow me to drop the following
> beautiful specimen of a patch (which I didn't commit anywhere, so far):

No progress yet with that, so for now, committed to gomp-4_0-branch in
r221411:

commit 2b54430cec7ac5b51ee3cbb568bd505d86bf0768
Author: tschwinge <tschwinge@138bc75d-0d04-0410-961f-82ee72b054a4>
Date:   Fri Mar 13 09:03:21 2015 +0000

    libgomp Fortran testing: for -g torture testing, disable variable tracking.
    
    Otherwise, the nvptx-none offloading compiler will run into issues such as:
    
        source-gcc/libgomp/testsuite/libgomp.fortran/examples-4/e.50.1.f90: In function '__e_50_1_mod_MOD_vec_mult._omp_fn.1':
        source-gcc/libgomp/testsuite/libgomp.fortran/examples-4/e.50.1.f90:31:0: internal compiler error: in use_type, at var-tracking.c:5442
                 p(i) = v1(i) * v2(i)
         ^
        0xc4dc72 use_type
                source-gcc/gcc/var-tracking.c:5442
        0xc504b3 add_stores
                source-gcc/gcc/var-tracking.c:5869
        0xc4cd28 add_with_sets
                source-gcc/gcc/var-tracking.c:6553
        0x5e9b7d cselib_record_sets
                source-gcc/gcc/cselib.c:2574
        0x5ea8a7 cselib_process_insn(rtx_insn*)
                source-gcc/gcc/cselib.c:2686
        0xc586a3 vt_initialize
                source-gcc/gcc/var-tracking.c:10126
        0xc65a8e variable_tracking_main_1
                source-gcc/gcc/var-tracking.c:10322
        0xc65a8e variable_tracking_main
                source-gcc/gcc/var-tracking.c:10375
        0xc65a8e execute
                source-gcc/gcc/var-tracking.c:10412
        Please submit a full bug report,
        with preprocessed source if appropriate.
        Please include the complete backtrace with any bug report.
        See <http://gcc.gnu.org/bugs.html> for instructions.
        mkoffload: fatal error: install/offload-nvptx-none/bin//x86_64-unknown-linux-gnu-accel-nvptx-none-gcc returned 1 exit status
    
    	libgomp/
    	* testsuite/libgomp.fortran/fortran.exp (DG_TORTURE_OPTIONS): Add
    	-fno-var-tracking next to any -g usage.
    	* testsuite/libgomp.oacc-fortran/fortran.exp (DG_TORTURE_OPTIONS):
    	Likewise.
    
    git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gomp-4_0-branch@221411 138bc75d-0d04-0410-961f-82ee72b054a4
---
 libgomp/ChangeLog.gomp                             |    7 +++++++
 libgomp/testsuite/libgomp.fortran/fortran.exp      |    4 ++++
 libgomp/testsuite/libgomp.oacc-fortran/fortran.exp |    4 ++++
 3 files changed, 15 insertions(+)

diff --git libgomp/ChangeLog.gomp libgomp/ChangeLog.gomp
index c2566cf..f052d3e 100644
--- libgomp/ChangeLog.gomp
+++ libgomp/ChangeLog.gomp
@@ -1,3 +1,10 @@
+2015-03-13  Thomas Schwinge  <thomas@codesourcery.com>
+
+	* testsuite/libgomp.fortran/fortran.exp (DG_TORTURE_OPTIONS): Add
+	-fno-var-tracking next to any -g usage.
+	* testsuite/libgomp.oacc-fortran/fortran.exp (DG_TORTURE_OPTIONS):
+	Likewise.
+
 2015-01-12  Thomas Schwinge  <thomas@codesourcery.com>
 
 	* plugin/plugin-host.c [HOST_NONSHM_PLUGIN]: Don't include "libgomp.h".
diff --git libgomp/testsuite/libgomp.fortran/fortran.exp libgomp/testsuite/libgomp.fortran/fortran.exp
index 9e6b643..ead94f3 100644
--- libgomp/testsuite/libgomp.fortran/fortran.exp
+++ libgomp/testsuite/libgomp.fortran/fortran.exp
@@ -21,6 +21,10 @@ dg-init
 # Turn on OpenMP.
 lappend ALWAYS_CFLAGS "additional_flags=-fopenmp"
 
+# TODO: for -g torture testing, disable variable tracking.
+# <http://news.gmane.org/find-root.php?message_id=%3C87mw429tfn.fsf%40kepler.schwinge.homeip.net%3E>.
+regsub -all -- { -g[^ ]*} $DG_TORTURE_OPTIONS {& -fno-var-tracking} DG_TORTURE_OPTIONS
+
 if { $blddir != "" } {
     set lang_source_re {^.*\.[fF](|90|95|03|08)$}
     set lang_include_flags "-fintrinsic-modules-path=${blddir}"
diff --git libgomp/testsuite/libgomp.oacc-fortran/fortran.exp libgomp/testsuite/libgomp.oacc-fortran/fortran.exp
index a68e039..203106e 100644
--- libgomp/testsuite/libgomp.oacc-fortran/fortran.exp
+++ libgomp/testsuite/libgomp.oacc-fortran/fortran.exp
@@ -23,6 +23,10 @@ dg-init
 # Turn on OpenACC.
 lappend ALWAYS_CFLAGS "additional_flags=-fopenacc"
 
+# TODO: for -g torture testing, disable variable tracking.
+# <http://news.gmane.org/find-root.php?message_id=%3C87mw429tfn.fsf%40kepler.schwinge.homeip.net%3E>.
+regsub -all -- { -g[^ ]*} $DG_TORTURE_OPTIONS {& -fno-var-tracking} DG_TORTURE_OPTIONS
+
 if { $blddir != "" } {
     set lang_source_re {^.*\.[fF](|90|95|03|08)$}
     set lang_include_flags "-fintrinsic-modules-path=${blddir}"


Grüße,
 Thomas

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 472 bytes --]

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH] Don't run var-tracking for targetm.no_register_allocation targets
@ 2015-03-26 11:00             ` Jakub Jelinek
  2015-03-26 11:20               ` Richard Biener
  2015-04-27 16:44               ` var-tracking vs. pseudo registers (was: Option overriding in the offloading code path) Thomas Schwinge
  0 siblings, 2 replies; 20+ messages in thread
From: Jakub Jelinek @ 2015-03-26 11:00 UTC (permalink / raw)
  To: Richard Biener; +Cc: gcc-patches

Hi!

As discussed earlier, var-tracking assumes no pseudos are in the IL
at the point it is run, which isn't the case for nvptx.
While it would be also reasonable to kill debug stmts earlier or
disable var-tracking, making it clear that var-tracking can't handle this
case is IMHO desirable too.

Ok for trunk?

2015-03-26  Jakub Jelinek  <jakub@redhat.com>

	* var-tracking.c (variable_tracking_main_1): Don't track
	variables for targetm.no_register_allocation targets.

--- gcc/var-tracking.c.jj	2015-03-10 07:35:30.000000000 +0100
+++ gcc/var-tracking.c	2015-03-24 16:55:07.611328164 +0100
@@ -10311,7 +10311,10 @@ variable_tracking_main_1 (void)
 {
   bool success;
 
-  if (flag_var_tracking_assignments < 0)
+  if (flag_var_tracking_assignments < 0
+      /* Var-tracking right now assumes the IR doesn't contain
+	 any pseudos at this point.  */
+      || targetm.no_register_allocation)
     {
       delete_debug_insns ();
       return 0;

	Jakub

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH] Don't run var-tracking for targetm.no_register_allocation targets
  2015-03-26 11:00             ` [PATCH] Don't run var-tracking for targetm.no_register_allocation targets Jakub Jelinek
@ 2015-03-26 11:20               ` Richard Biener
  2015-04-27 16:44               ` var-tracking vs. pseudo registers (was: Option overriding in the offloading code path) Thomas Schwinge
  1 sibling, 0 replies; 20+ messages in thread
From: Richard Biener @ 2015-03-26 11:20 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: gcc-patches

On Thu, 26 Mar 2015, Jakub Jelinek wrote:

> Hi!
> 
> As discussed earlier, var-tracking assumes no pseudos are in the IL
> at the point it is run, which isn't the case for nvptx.
> While it would be also reasonable to kill debug stmts earlier or
> disable var-tracking, making it clear that var-tracking can't handle this
> case is IMHO desirable too.
> 
> Ok for trunk?

Ok.

Thanks,
Richard.

> 2015-03-26  Jakub Jelinek  <jakub@redhat.com>
> 
> 	* var-tracking.c (variable_tracking_main_1): Don't track
> 	variables for targetm.no_register_allocation targets.
> 
> --- gcc/var-tracking.c.jj	2015-03-10 07:35:30.000000000 +0100
> +++ gcc/var-tracking.c	2015-03-24 16:55:07.611328164 +0100
> @@ -10311,7 +10311,10 @@ variable_tracking_main_1 (void)
>  {
>    bool success;
>  
> -  if (flag_var_tracking_assignments < 0)
> +  if (flag_var_tracking_assignments < 0
> +      /* Var-tracking right now assumes the IR doesn't contain
> +	 any pseudos at this point.  */
> +      || targetm.no_register_allocation)
>      {
>        delete_debug_insns ();
>        return 0;
> 
> 	Jakub
> 
> 

-- 
Richard Biener <rguenther@suse.de>
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Jennifer Guild,
Dilip Upmanyu, Graham Norton HRB 21284 (AG Nuernberg)

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: var-tracking vs. pseudo registers (was: Option overriding in the offloading code path)
  2015-03-26 11:00             ` [PATCH] Don't run var-tracking for targetm.no_register_allocation targets Jakub Jelinek
  2015-03-26 11:20               ` Richard Biener
@ 2015-04-27 16:44               ` Thomas Schwinge
  1 sibling, 0 replies; 20+ messages in thread
From: Thomas Schwinge @ 2015-04-27 16:44 UTC (permalink / raw)
  To: GCC Patches; +Cc: Jakub Jelinek, Bernd Schmidt

[-- Attachment #1: Type: text/plain, Size: 4515 bytes --]

Hi!

On Thu, 26 Feb 2015 11:46:00 +0100, Jakub Jelinek <jakub@redhat.com> wrote:
> On Thu, Feb 26, 2015 at 11:27:06AM +0100, Thomas Schwinge wrote:
> > Is this not the right way to skip it, or, Bernd, is this because we're
> > not yet handling some debug stuff in nvptx?  (I tested that
> > <http://news.gmane.org/find-root.php?message_id=%3C5466473A.1090809%40codesourcery.com%3E>
> > does not help with that.)  The following does make it work (that is,
> > resolve the ICEs), but that feels a bit too much ;-) of a hack:
> > 
> > --- gcc/var-tracking.c
> > +++ gcc/var-tracking.c
> > @@ -10305,7 +10322,8 @@ variable_tracking_main_1 (void)
> >  {
> >    bool success;
> >  
> > -  if (flag_var_tracking_assignments < 0)
> > +  if (flag_var_tracking_assignments < 0
> > +      || targetm.no_register_allocation)
> >      {
> >        delete_debug_insns ();
> >        return 0;
> 
> No, IMHO that is the right fix, not a hack.  But of course would deserve
> a comment.

Jakub has done that in r221693,
<http://news.gmane.org/find-root.php?message_id=%3C20150326110015.GW1746%40tucnak.redhat.com%3E>
-- thanks!


> Plus of course you can also just override
> flag_var_tracking_assignments in the nvptx override option hook, and
> perhaps in tree-streamer-in.c clear flag_var_tracking_assignments in the
> OPTIMIZATION_NODE too (or just add a hook for that, as I said before).

That remains to be done.


Given Jakub's commit got merged into gomp-4_0-branch, I committed the
following to gomp-4_0-branch in r222472:

commit 9973ee1f73fc61ad643e3f7b83331a3e3fef1fd4
Author: tschwinge <tschwinge@138bc75d-0d04-0410-961f-82ee72b054a4>
Date:   Mon Apr 27 16:41:31 2015 +0000

    Revert "libgomp Fortran testing: for -g torture testing, disable variable tracking."
    
    This reverts commit r221411.
    
    	libgomp/
    	* testsuite/libgomp.fortran/fortran.exp (DG_TORTURE_OPTIONS):
    	Don't add -fno-var-tracking next to any -g usage.
    	* testsuite/libgomp.oacc-fortran/fortran.exp (DG_TORTURE_OPTIONS):
    	Likewise.
    
    git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gomp-4_0-branch@222472 138bc75d-0d04-0410-961f-82ee72b054a4
---
 libgomp/ChangeLog.gomp                             |    7 +++++++
 libgomp/testsuite/libgomp.fortran/fortran.exp      |    4 ----
 libgomp/testsuite/libgomp.oacc-fortran/fortran.exp |    4 ----
 3 files changed, 7 insertions(+), 8 deletions(-)

diff --git libgomp/ChangeLog.gomp libgomp/ChangeLog.gomp
index 3d762bd..0f1b23d 100644
--- libgomp/ChangeLog.gomp
+++ libgomp/ChangeLog.gomp
@@ -1,3 +1,10 @@
+2015-04-27  Thomas Schwinge  <thomas@codesourcery.com>
+
+	* testsuite/libgomp.fortran/fortran.exp (DG_TORTURE_OPTIONS):
+	Don't add -fno-var-tracking next to any -g usage.
+	* testsuite/libgomp.oacc-fortran/fortran.exp (DG_TORTURE_OPTIONS):
+	Likewise.
+
 2015-04-21  Tom de Vries  <tom@codesourcery.com>
 	    Thomas Schwinge  <thomas@codesourcery.com>
 
diff --git libgomp/testsuite/libgomp.fortran/fortran.exp libgomp/testsuite/libgomp.fortran/fortran.exp
index ead94f3..9e6b643 100644
--- libgomp/testsuite/libgomp.fortran/fortran.exp
+++ libgomp/testsuite/libgomp.fortran/fortran.exp
@@ -21,10 +21,6 @@ dg-init
 # Turn on OpenMP.
 lappend ALWAYS_CFLAGS "additional_flags=-fopenmp"
 
-# TODO: for -g torture testing, disable variable tracking.
-# <http://news.gmane.org/find-root.php?message_id=%3C87mw429tfn.fsf%40kepler.schwinge.homeip.net%3E>.
-regsub -all -- { -g[^ ]*} $DG_TORTURE_OPTIONS {& -fno-var-tracking} DG_TORTURE_OPTIONS
-
 if { $blddir != "" } {
     set lang_source_re {^.*\.[fF](|90|95|03|08)$}
     set lang_include_flags "-fintrinsic-modules-path=${blddir}"
diff --git libgomp/testsuite/libgomp.oacc-fortran/fortran.exp libgomp/testsuite/libgomp.oacc-fortran/fortran.exp
index 203106e..a68e039 100644
--- libgomp/testsuite/libgomp.oacc-fortran/fortran.exp
+++ libgomp/testsuite/libgomp.oacc-fortran/fortran.exp
@@ -23,10 +23,6 @@ dg-init
 # Turn on OpenACC.
 lappend ALWAYS_CFLAGS "additional_flags=-fopenacc"
 
-# TODO: for -g torture testing, disable variable tracking.
-# <http://news.gmane.org/find-root.php?message_id=%3C87mw429tfn.fsf%40kepler.schwinge.homeip.net%3E>.
-regsub -all -- { -g[^ ]*} $DG_TORTURE_OPTIONS {& -fno-var-tracking} DG_TORTURE_OPTIONS
-
 if { $blddir != "" } {
     set lang_source_re {^.*\.[fF](|90|95|03|08)$}
     set lang_include_flags "-fintrinsic-modules-path=${blddir}"


Grüße,
 Thomas

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 472 bytes --]

^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2015-04-27 16:44 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-11-01 12:11 nvptx offloading patches [4/n] Bernd Schmidt
2015-01-28 18:03 ` Thomas Schwinge
2015-01-28 18:16   ` Ilya Verbin
2015-02-11 14:20     ` Thomas Schwinge
2015-02-11 14:19   ` Thomas Schwinge
2015-02-11 14:20   ` Thomas Schwinge
2015-02-11 14:44 ` Thomas Schwinge
2015-02-11 14:50   ` [nvptx] -freorder-blocks-and-partition, -freorder-functions (was: nvptx offloading patches [4/n]) Thomas Schwinge
2015-02-25 10:54     ` Option overriding in the offloading code path (was: [nvptx] -freorder-blocks-and-partition, -freorder-functions) Thomas Schwinge
2015-02-25 13:23       ` Option overriding in the offloading code path Bernd Schmidt
2015-02-25 17:15       ` Option overriding in the offloading code path (was: [nvptx] -freorder-blocks-and-partition, -freorder-functions) Jakub Jelinek
2015-02-26 10:42         ` var-tracking vs. pseudo registers (was: Option overriding in the offloading code path) Thomas Schwinge
2015-02-26 10:53           ` Jakub Jelinek
2015-03-26 11:00             ` [PATCH] Don't run var-tracking for targetm.no_register_allocation targets Jakub Jelinek
2015-03-26 11:20               ` Richard Biener
2015-04-27 16:44               ` var-tracking vs. pseudo registers (was: Option overriding in the offloading code path) Thomas Schwinge
2015-03-13  9:07       ` Option overriding in the offloading code path Thomas Schwinge
2015-02-11 15:21   ` nvptx offloading patches [4/n] Bernd Schmidt
2015-02-17 18:14     ` Thomas Schwinge
2015-02-18  8:26 ` nvptx mkoffload: For non-installed testing, look in all COMPILER_PATHs for GCC_INSTALL_NAME (was: nvptx offloading patches [4/n]) Thomas Schwinge

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).