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


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

Re: [PATCH 3/4] Extract deferred-location handling from jit


On Wed, May 4, 2016 at 10:49 PM, David Malcolm <dmalcolm@redhat.com> wrote:
> In order to faithfully load RTL dumps that contain references to
> source locations, the RTL frontend needs to be able to parse file
> and line information and turn then into location_t values.
>
> Unfortunately, the libcpp API makes it rather fiddly to create
> location_t values from a sequence of arbitrary file/line pairs: the
> API assumes that the locations are created in ascending order as
> if we were parsing the source file, but as we read an RTL dump,
> the insns could be jumping forwards and backwards in lines and
> between files.  Also, if we want to support column numbers, the
> presence of a very high column number could exceed the bits available
> in a line_map_ordinary for storing it.
>
> The JIT has some code for handling this, in gcc/jit/jit-playback.[ch],
> (since the JIT support source location information, and doesn't impose
> any ordering requirement on users of the API).
>
> This patch moves the relevant code from
>   gcc/jit/jit-playback.[ch]
> into a new pair of files:
>   gcc/deferred-locations.[ch]
>
> The idea is that a deferred_locations instances manages these
> "deferred locations"; they are created, and then all of the location_t
> values are created at once by calling
>   deferred_locations::add_to_line_table
> After this call, the actual location_t values can be read from out of
> deferred_location instances.
>
> There are some suboptimal parts of the code (some linear searches, and
> the use of gc), but it's mostly a move of existing code from out of the
> jit subdirectory and into "gcc" proper for reuse by the RTL frontend.
>
> This is likely to be useful for the gimple frontend as well.
>
> OK for trunk?

The LTO FE faces similar issues - see lto-streamer-in.c

Richard.

> gcc/ChangeLog:
>         * Makefile.in (OBJS): Add deferred-locations.o.
>         * deferred-locations.c: New file, adapted from parts of
>         jit/jit-playback.c.
>         * deferred-locations.h: New file, adapted from parts of
>         jit/jit-playback.h.
>
> gcc/jit/ChangeLog:
>         * jit-common.h: Include deferred-locations.h.
>         (gcc::jit::playback::source_file): Remove forward decl.
>         (gcc::jit::playback::source_line): Likewise.
>         (gcc::jit::playback::location): Replace forward decl, with
>         a typedef, aliasing deferred_location.
>         * jit-playback.c (gcc::jit::playback::context::context): Remove
>         create call on m_source_files.
>         (line_comparator): Move to deferred-locations.c.
>         (location_comparator): Likewise.
>         (handle_locations): Move logic to deferred-locations.c, as
>         deferred_locations::add_to_line_table.
>         (get_recording_loc): New function.
>         (gcc::jit::playback::context::add_error): Call get_recording_loc
>         as a function, rather than as a method.
>         (gcc::jit::playback::context::add_error_va): Likewise.
>         (gcc::jit::playback::context::get_source_file): Update return type
>         to reflect move of source_file to deferred-locations.h.
>         Replace body with a call to m_deferred_locations.get_source_file.
>         (gcc::jit::playback::source_file::source_file): Move to
>         deferred-locations.h, losing the namespaces.
>         (gcc::jit::playback::source_file::finalizer): Likewise.
>         (gcc::jit::playback::source_file::get_source_line): Likewise.
>         (gcc::jit::playback::source_line::source_line): Likewise.
>         (gcc::jit::playback::source_line::finalizer): Likewise.
>         (gcc::jit::playback::source_line::get_location): Likewise.
>         (gcc::jit::playback::location::location): Likewise, renaming to
>         deferred_location.
>         * jit-playback.h: Include deferred-locations.h.
>         (gcc::jit::playback::context::m_source_files): Replace field with
>         m_deferred_locations.
>         (gcc::jit::playback::source_file): Move to deferred-locations.h,
>         losing the namespaces.
>         (gcc::jit::playback::source_line): Likewise.
>         (gcc::jit::playback::location): Likewise, renaming to
>         deferred_location.  Eliminate get_recording_loc accessor and
>         m_recording_loc field in favor of get_user_data and m_user_data
>         respectively.
> ---
>  gcc/Makefile.in          |   1 +
>  gcc/deferred-locations.c | 240 +++++++++++++++++++++++++++++++++++++++++++++++
>  gcc/deferred-locations.h | 139 +++++++++++++++++++++++++++
>  gcc/jit/jit-common.h     |   5 +-
>  gcc/jit/jit-playback.c   | 194 ++++----------------------------------
>  gcc/jit/jit-playback.h   |  73 +-------------
>  6 files changed, 402 insertions(+), 250 deletions(-)
>  create mode 100644 gcc/deferred-locations.c
>  create mode 100644 gcc/deferred-locations.h
>
> diff --git a/gcc/Makefile.in b/gcc/Makefile.in
> index 6c5adc0..c61f303 100644
> --- a/gcc/Makefile.in
> +++ b/gcc/Makefile.in
> @@ -1239,6 +1239,7 @@ OBJS = \
>         dce.o \
>         ddg.o \
>         debug.o \
> +       deferred-locations.o \
>         df-core.o \
>         df-problems.o \
>         df-scan.o \
> diff --git a/gcc/deferred-locations.c b/gcc/deferred-locations.c
> new file mode 100644
> index 0000000..cd02938
> --- /dev/null
> +++ b/gcc/deferred-locations.c
> @@ -0,0 +1,240 @@
> +/* Dealing with the linemap API.
> +   Copyright (C) 2013-2016 Free Software Foundation, Inc.
> +
> +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/>.  */
> +
> +#include "config.h"
> +#include "system.h"
> +#include "coretypes.h"
> +#include "input.h"
> +#include "deferred-locations.h"
> +#include "stringpool.h"
> +#include "tree.h"
> +
> +/* The wrapper subclasses are GC-managed, but can own non-GC memory.
> +   Provide this finalization hook for calling then they are collected,
> +   which calls the finalizer vfunc.  This allows them to call "release"
> +   on any vec<> within them.  */
> +
> +static void
> +wrapper_finalizer (void *ptr)
> +{
> +  wrapper *w = reinterpret_cast <wrapper *> (ptr);
> +  w->finalizer ();
> +}
> +
> +/* wrapper subclasses are GC-managed:
> +   allocate them using ggc_internal_cleared_alloc.  */
> +
> +void *
> +wrapper::operator new (size_t sz)
> +{
> +  return ggc_internal_cleared_alloc (sz, wrapper_finalizer, 0, 1);
> +
> +}
> +
> +/* Constructor for source_file.  */
> +
> +source_file::source_file (tree filename) :
> +  m_source_lines (),
> +  m_filename (filename)
> +{
> +}
> +
> +/* Don't leak vec's internal buffer (in non-GC heap) when we are
> +   GC-ed.  */
> +
> +void
> +source_file::finalizer ()
> +{
> +  m_source_lines.release ();
> +}
> +
> +/* Construct a source_line for the given line
> +   within this source file, if one doesn't exist already.  */
> +
> +source_line *
> +source_file::get_source_line (int line_num)
> +{
> +  /* Locate the line.
> +     For simplicitly, this is currently a linear search.
> +     Replace with a hash if this shows up in the profile.  */
> +  int i;
> +  source_line *line;
> +
> +  FOR_EACH_VEC_ELT (m_source_lines, i, line)
> +    if (line->get_line_num () == line_num)
> +      return line;
> +
> +  /* Not found.  */
> +  line = new source_line (this, line_num);
> +  m_source_lines.safe_push (line);
> +  return line;
> +}
> +
> +const char *
> +source_file::get_filename () const
> +{
> +  return IDENTIFIER_POINTER (m_filename);
> +}
> +
> +/* Constructor for source_line.  */
> +
> +source_line::source_line (source_file *file, int line_num) :
> +  m_locations (),
> +  m_source_file (file),
> +  m_line_num (line_num)
> +{
> +}
> +
> +/* Don't leak vec's internal buffer (in non-GC heap) when we are
> +   GC-ed.  */
> +
> +void
> +source_line::finalizer ()
> +{
> +  m_locations.release ();
> +}
> +
> +/* Construct a location for the given column
> +   within this line of a specific source file, if one doesn't exist
> +   already.  */
> +
> +deferred_location *
> +source_line::get_location (void *user_data, int column_num)
> +{
> +  int i;
> +  deferred_location *loc;
> +
> +  /* Another linear search that probably should be a hash table.  */
> +  FOR_EACH_VEC_ELT (m_locations, i, loc)
> +    if (loc->get_column_num () == column_num)
> +      return loc;
> +
> +  /* Not found.  */
> +  loc = new deferred_location (user_data, this, column_num);
> +  m_locations.safe_push (loc);
> +  return loc;
> +}
> +
> +/* Constructor for deferred_location.  */
> +deferred_location::deferred_location (void *user_data,
> +                                     source_line *line,
> +                                     int column_num) :
> +  m_srcloc (UNKNOWN_LOCATION),
> +  m_user_data (user_data),
> +  m_line (line),
> +  m_column_num(column_num)
> +{
> +}
> +
> +/* qsort comparator for comparing pairs of source_line *,
> +   ordering them by line number.  */
> +
> +static int
> +line_comparator (const void *lhs, const void *rhs)
> +{
> +  const source_line *line_lhs = *static_cast<const source_line * const*> (lhs);
> +  const source_line *line_rhs = *static_cast<const source_line * const*> (rhs);
> +  return line_lhs->get_line_num () - line_rhs->get_line_num ();
> +}
> +
> +/* qsort comparator for comparing pairs of deferred_location *,
> +   ordering them by column number.  */
> +
> +static int
> +location_comparator (const void *lhs, const void *rhs)
> +{
> +  const deferred_location *loc_lhs = \
> +    *static_cast<const deferred_location * const *> (lhs);
> +  const deferred_location *loc_rhs = \
> +    *static_cast<const deferred_location * const *> (rhs);
> +  return loc_lhs->get_column_num () - loc_rhs->get_column_num ();
> +}
> +
> +/* class deferred_locations */
> +
> +deferred_locations::deferred_locations ()
> +{
> +  m_source_files.create (0);
> +}
> +
> +/* Construct a source_file for the given source
> +   filename, if it doesn't exist already.  */
> +
> +source_file *
> +deferred_locations::get_source_file (const char *filename)
> +{
> +  /* Locate the file.
> +     For simplicitly, this is currently a linear search.
> +     Replace with a hash if this shows up in the profile.  */
> +  int i;
> +  source_file *file;
> +  tree ident_filename = get_identifier (filename);
> +
> +  FOR_EACH_VEC_ELT (m_source_files, i, file)
> +    if (file->filename_as_tree () == ident_filename)
> +      return file;
> +
> +  /* Not found.  */
> +  file = new source_file (ident_filename);
> +  m_source_files.safe_push (file);
> +  return file;
> +
> +}
> +
> +void
> +deferred_locations::add_to_line_table ()
> +{
> +  int i;
> +  source_file *file;
> +
> +  FOR_EACH_VEC_ELT (m_source_files, i, file)
> +    {
> +      linemap_add (line_table, LC_ENTER, false, file->get_filename (), 0);
> +
> +      /* Sort lines by ascending line numbers.  */
> +      file->m_source_lines.qsort (&line_comparator);
> +
> +      int j;
> +      source_line *line;
> +      FOR_EACH_VEC_ELT (file->m_source_lines, j, line)
> +       {
> +         int k;
> +         deferred_location *loc;
> +
> +         /* Sort locations in line by ascending column numbers.  */
> +         line->m_locations.qsort (&location_comparator);
> +
> +         /* Determine maximum column within this line.  */
> +         gcc_assert (line->m_locations.length () > 0);
> +         deferred_location *final_column =
> +           line->m_locations[line->m_locations.length () - 1];
> +         int max_col = final_column->get_column_num ();
> +
> +         linemap_line_start (line_table, line->get_line_num (), max_col);
> +         FOR_EACH_VEC_ELT (line->m_locations, k, loc)
> +           {
> +             loc->m_srcloc =
> +               linemap_position_for_column (line_table, loc->get_column_num ());
> +           }
> +       }
> +
> +      linemap_add (line_table, LC_LEAVE, false, NULL, 0);
> +    }
> +
> +}
> diff --git a/gcc/deferred-locations.h b/gcc/deferred-locations.h
> new file mode 100644
> index 0000000..209cb0d
> --- /dev/null
> +++ b/gcc/deferred-locations.h
> @@ -0,0 +1,139 @@
> +/* Dealing with the linemap API.
> +   Copyright (C) 2013-2016 Free Software Foundation, Inc.
> +
> +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/>.  */
> +
> +#ifndef GCC_DEFERRED_LOCATIONS_H
> +#define GCC_DEFERRED_LOCATIONS_H
> +
> +/* Dealing with the linemap API.
> +
> +   libcpp requires locations to be created as if by
> +   a tokenizer, creating them by filename, in ascending order of
> +   line/column, whereas the libgccjit API doesn't impose any such constraints:
> +   we allow client code to create locations in arbitrary orders.
> +
> +   To square this circle, we need to cache all location creation,
> +   grouping things up by filename/line, and then creating the linemap
> +   entries in a post-processing phase.  */
> +
> +/* A temporary wrapper object.
> +   These objects are (mostly) only valid during replay.
> +   We allocate them on the GC heap, so that they will be cleaned
> +   the next time the GC collects.  */
> +class wrapper
> +{
> +public:
> +  /* Allocate in the GC heap.  */
> +  void *operator new (size_t sz);
> +
> +  /* Some wrapper subclasses contain vec<> and so need to
> +     release them when they are GC-ed.  */
> +  virtual void finalizer () { }
> +};
> +
> +class source_file;
> +class source_line;
> +class deferred_location;
> +
> +/* A set of locations, all sharing a filename */
> +class source_file : public wrapper
> +{
> +public:
> +  source_file (tree filename);
> +  void finalizer ();
> +
> +  source_line *
> +  get_source_line (int line_num);
> +
> +  tree filename_as_tree () const { return m_filename; }
> +
> +  const char *get_filename () const;
> +
> +  vec<source_line *> m_source_lines;
> +
> +private:
> +  tree m_filename;
> +};
> +
> +/* A source line, with one or more locations of interest.  */
> +class source_line : public wrapper
> +{
> +public:
> +  source_line (source_file *file, int line_num);
> +  void finalizer ();
> +
> +  deferred_location *
> +  get_location (void *user_data, int column_num);
> +
> +  int get_line_num () const { return m_line_num; }
> +
> +  vec<deferred_location *> m_locations;
> +
> +private:
> +  source_file *m_source_file;
> +  int m_line_num;
> +};
> +
> +/* A specific location on a source line.  This is what we expose
> +   to the JIT client API.  */
> +class deferred_location : public wrapper
> +{
> +public:
> +  deferred_location (void *user_data, source_line *line, int column_num);
> +
> +  int get_column_num () const { return m_column_num; }
> +
> +  void *get_user_data () const { return m_user_data; }
> +
> +  source_location m_srcloc;
> +
> +private:
> +  void *m_user_data;
> +  source_line *m_line;
> +  int m_column_num;
> +};
> +
> +/* A class for managing the deferred creation of location_t values.
> +
> +   Locations are created in two phases:
> +
> +   - first phase: creation of source_file instances (via
> +   deferred_locations::get_source_file), from which source_line
> +   instances can be created (via source_file::get_source_line), from
> +   which deferred_location instances can be created (via
> +   source_line::get_location).
> +
> +   - second phase: call deferred_location::add_to_line_table, which
> +   walks all of the above and populates line_table, filling in
> +   the various deferred_location instances with source_location
> +   (aka location_t) values.  */
> +
> +class deferred_locations
> +{
> + public:
> +  deferred_locations ();
> +
> +  source_file *get_source_file (const char *filename);
> +
> +  void add_to_line_table ();
> +
> + private:
> +  auto_vec<source_file *> m_source_files;
> +};
> +
> +#endif /* #ifndef GCC_DEFERRED_LOCATIONS_H */
> diff --git a/gcc/jit/jit-common.h b/gcc/jit/jit-common.h
> index 8a6cd74..0a10cdf 100644
> --- a/gcc/jit/jit-common.h
> +++ b/gcc/jit/jit-common.h
> @@ -27,6 +27,7 @@ along with GCC; see the file COPYING3.  If not see
>  #include "tree.h"
>  #include "inchash.h"
>  #include "tree-iterator.h"
> +#include "deferred-locations.h"
>
>  #ifdef GCC_VERSION
>  #if GCC_VERSION >= 4001
> @@ -146,9 +147,7 @@ namespace playback {
>      class rvalue;
>        class lvalue;
>          class param;
> -    class source_file;
> -    class source_line;
> -    class location;
> +    typedef deferred_location location;
>      class case_;
>
>    /* End of playback types. */
> diff --git a/gcc/jit/jit-playback.c b/gcc/jit/jit-playback.c
> index 579230d..f17c55b 100644
> --- a/gcc/jit/jit-playback.c
> +++ b/gcc/jit/jit-playback.c
> @@ -85,7 +85,6 @@ playback::context::context (recording::context *ctxt)
>    JIT_LOG_SCOPE (get_logger ());
>    m_functions.create (0);
>    m_globals.create (0);
> -  m_source_files.create (0);
>    m_cached_locations.create (0);
>  }
>
> @@ -2705,32 +2704,6 @@ get_path_so_file () const
>    return m_tempdir->get_path_so_file ();
>  }
>
> -/* qsort comparator for comparing pairs of playback::source_line *,
> -   ordering them by line number.  */
> -
> -static int
> -line_comparator (const void *lhs, const void *rhs)
> -{
> -  const playback::source_line *line_lhs = \
> -    *static_cast<const playback::source_line * const*> (lhs);
> -  const playback::source_line *line_rhs = \
> -    *static_cast<const playback::source_line * const*> (rhs);
> -  return line_lhs->get_line_num () - line_rhs->get_line_num ();
> -}
> -
> -/* qsort comparator for comparing pairs of playback::location *,
> -   ordering them by column number.  */
> -
> -static int
> -location_comparator (const void *lhs, const void *rhs)
> -{
> -  const playback::location *loc_lhs = \
> -    *static_cast<const playback::location * const *> (lhs);
> -  const playback::location *loc_rhs = \
> -    *static_cast<const playback::location * const *> (rhs);
> -  return loc_lhs->get_column_num () - loc_rhs->get_column_num ();
> -}
> -
>  /* Our API allows locations to be created in arbitrary orders, but the
>     linemap API requires locations to be created in ascending order
>     as if we were tokenizing files.
> @@ -2748,47 +2721,13 @@ handle_locations ()
>
>       line_table is a global.  */
>    JIT_LOG_SCOPE (get_logger ());
> -  int i;
> -  source_file *file;
> -
> -  FOR_EACH_VEC_ELT (m_source_files, i, file)
> -    {
> -      linemap_add (line_table, LC_ENTER, false, file->get_filename (), 0);
> -
> -      /* Sort lines by ascending line numbers.  */
> -      file->m_source_lines.qsort (&line_comparator);
> -
> -      int j;
> -      source_line *line;
> -      FOR_EACH_VEC_ELT (file->m_source_lines, j, line)
> -       {
> -         int k;
> -         location *loc;
> -
> -         /* Sort locations in line by ascending column numbers.  */
> -         line->m_locations.qsort (&location_comparator);
> -
> -         /* Determine maximum column within this line.  */
> -         gcc_assert (line->m_locations.length () > 0);
> -         location *final_column =
> -           line->m_locations[line->m_locations.length () - 1];
> -         int max_col = final_column->get_column_num ();
> -
> -         linemap_line_start (line_table, line->get_line_num (), max_col);
> -         FOR_EACH_VEC_ELT (line->m_locations, k, loc)
> -           {
> -             loc->m_srcloc =                                      \
> -               linemap_position_for_column (line_table, loc->get_column_num ());
> -           }
> -       }
> -
> -      linemap_add (line_table, LC_LEAVE, false, NULL, 0);
> -    }
>
> +  m_deferred_locations.add_to_line_table ();
>    /* line_table should now be populated; every playback::location should
>       now have an m_srcloc.  */
>
>    /* Now assign them to tree nodes as appropriate.  */
> +  int i;
>    std::pair<tree, location *> *cached_location;
>
>    FOR_EACH_VEC_ELT (m_cached_locations, i, cached_location)
> @@ -2808,6 +2747,17 @@ handle_locations ()
>      }
>  }
>
> +/* Return the recording::location for playback::location LOC.
> +   Return NULL if LOC is NULL.  */
> +
> +static recording::location *
> +get_recording_loc (playback::location *loc)
> +{
> +  if (!loc)
> +    return NULL;
> +  return reinterpret_cast <recording::location *> (loc->get_user_data ());
> +}
> +
>  /* We handle errors on a playback::context by adding them to the
>     corresponding recording::context.  */
>
> @@ -2817,8 +2767,7 @@ add_error (location *loc, const char *fmt, ...)
>  {
>    va_list ap;
>    va_start (ap, fmt);
> -  m_recording_ctxt->add_error_va (loc ? loc->get_recording_loc () : NULL,
> -                                 fmt, ap);
> +  m_recording_ctxt->add_error_va (get_recording_loc (loc), fmt, ap);
>    va_end (ap);
>  }
>
> @@ -2829,8 +2778,7 @@ void
>  playback::context::
>  add_error_va (location *loc, const char *fmt, va_list ap)
>  {
> -  m_recording_ctxt->add_error_va (loc ? loc->get_recording_loc () : NULL,
> -                                 fmt, ap);
> +  m_recording_ctxt->add_error_va (get_recording_loc (loc), fmt, ap);
>  }
>
>  /* Dealing with the linemap API.  */
> @@ -2868,120 +2816,14 @@ set_tree_location (tree t, location *loc)
>  }
>
>
> -/* Construct a playback::source_file for the given source
> +/* Construct a source_file for the given source
>     filename, if it doesn't exist already.  */
>
> -playback::source_file *
> +source_file *
>  playback::context::
>  get_source_file (const char *filename)
>  {
> -  /* Locate the file.
> -     For simplicitly, this is currently a linear search.
> -     Replace with a hash if this shows up in the profile.  */
> -  int i;
> -  source_file *file;
> -  tree ident_filename = get_identifier (filename);
> -
> -  FOR_EACH_VEC_ELT (m_source_files, i, file)
> -    if (file->filename_as_tree () == ident_filename)
> -      return file;
> -
> -  /* Not found.  */
> -  file = new source_file (ident_filename);
> -  m_source_files.safe_push (file);
> -  return file;
> -}
> -
> -/* Constructor for gcc::jit::playback::source_file.  */
> -
> -playback::source_file::source_file (tree filename) :
> -  m_source_lines (),
> -  m_filename (filename)
> -{
> -}
> -
> -/* Don't leak vec's internal buffer (in non-GC heap) when we are
> -   GC-ed.  */
> -
> -void
> -playback::source_file::finalizer ()
> -{
> -  m_source_lines.release ();
> -}
> -
> -/* Construct a playback::source_line for the given line
> -   within this source file, if one doesn't exist already.  */
> -
> -playback::source_line *
> -playback::source_file::
> -get_source_line (int line_num)
> -{
> -  /* Locate the line.
> -     For simplicitly, this is currently a linear search.
> -     Replace with a hash if this shows up in the profile.  */
> -  int i;
> -  source_line *line;
> -
> -  FOR_EACH_VEC_ELT (m_source_lines, i, line)
> -    if (line->get_line_num () == line_num)
> -      return line;
> -
> -  /* Not found.  */
> -  line = new source_line (this, line_num);
> -  m_source_lines.safe_push (line);
> -  return line;
> -}
> -
> -/* Constructor for gcc::jit::playback::source_line.  */
> -
> -playback::source_line::source_line (source_file *file, int line_num) :
> -  m_locations (),
> -  m_source_file (file),
> -  m_line_num (line_num)
> -{
> -}
> -
> -/* Don't leak vec's internal buffer (in non-GC heap) when we are
> -   GC-ed.  */
> -
> -void
> -playback::source_line::finalizer ()
> -{
> -  m_locations.release ();
> -}
> -
> -/* Construct a playback::location for the given column
> -   within this line of a specific source file, if one doesn't exist
> -   already.  */
> -
> -playback::location *
> -playback::source_line::
> -get_location (recording::location *rloc, int column_num)
> -{
> -  int i;
> -  location *loc;
> -
> -  /* Another linear search that probably should be a hash table.  */
> -  FOR_EACH_VEC_ELT (m_locations, i, loc)
> -    if (loc->get_column_num () == column_num)
> -      return loc;
> -
> -  /* Not found.  */
> -  loc = new location (rloc, this, column_num);
> -  m_locations.safe_push (loc);
> -  return loc;
> -}
> -
> -/* Constructor for gcc::jit::playback::location.  */
> -
> -playback::location::location (recording::location *loc,
> -                             source_line *line,
> -                             int column_num) :
> -  m_srcloc (UNKNOWN_LOCATION),
> -  m_recording_loc (loc),
> -  m_line (line),
> -  m_column_num(column_num)
> -{
> +  return m_deferred_locations.get_source_file (filename);
>  }
>
>  /* The active gcc::jit::playback::context instance.  This is a singleton,
> diff --git a/gcc/jit/jit-playback.h b/gcc/jit/jit-playback.h
> index 7519bc4..86118d9 100644
> --- a/gcc/jit/jit-playback.h
> +++ b/gcc/jit/jit-playback.h
> @@ -24,6 +24,7 @@ along with GCC; see the file COPYING3.  If not see
>  #include <utility> // for std::pair
>
>  #include "timevar.h"
> +#include "deferred-locations.h"
>
>  #include "jit-recording.h"
>
> @@ -305,7 +306,7 @@ private:
>    tree m_const_char_ptr;
>
>    /* Source location handling.  */
> -  auto_vec<source_file *> m_source_files;
> +  deferred_locations m_deferred_locations;
>
>    auto_vec<std::pair<tree, location *> > m_cached_locations;
>  };
> @@ -603,76 +604,6 @@ public:
>    {}
>  };
>
> -/* Dealing with the linemap API.
> -
> -   It appears that libcpp requires locations to be created as if by
> -   a tokenizer, creating them by filename, in ascending order of
> -   line/column, whereas our API doesn't impose any such constraints:
> -   we allow client code to create locations in arbitrary orders.
> -
> -   To square this circle, we need to cache all location creation,
> -   grouping things up by filename/line, and then creating the linemap
> -   entries in a post-processing phase.  */
> -
> -/* A set of locations, all sharing a filename */
> -class source_file : public wrapper
> -{
> -public:
> -  source_file (tree filename);
> -  void finalizer ();
> -
> -  source_line *
> -  get_source_line (int line_num);
> -
> -  tree filename_as_tree () const { return m_filename; }
> -
> -  const char*
> -  get_filename () const { return IDENTIFIER_POINTER (m_filename); }
> -
> -  vec<source_line *> m_source_lines;
> -
> -private:
> -  tree m_filename;
> -};
> -
> -/* A source line, with one or more locations of interest.  */
> -class source_line : public wrapper
> -{
> -public:
> -  source_line (source_file *file, int line_num);
> -  void finalizer ();
> -
> -  location *
> -  get_location (recording::location *rloc, int column_num);
> -
> -  int get_line_num () const { return m_line_num; }
> -
> -  vec<location *> m_locations;
> -
> -private:
> -  source_file *m_source_file;
> -  int m_line_num;
> -};
> -
> -/* A specific location on a source line.  This is what we expose
> -   to the client API.  */
> -class location : public wrapper
> -{
> -public:
> -  location (recording::location *loc, source_line *line, int column_num);
> -
> -  int get_column_num () const { return m_column_num; }
> -
> -  recording::location *get_recording_loc () const { return m_recording_loc; }
> -
> -  source_location m_srcloc;
> -
> -private:
> -  recording::location *m_recording_loc;
> -  source_line *m_line;
> -  int m_column_num;
> -};
> -
>  } // namespace gcc::jit::playback
>
>  extern playback::context *active_playback_ctxt;
> --
> 1.8.5.3
>


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