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]

[PATCH 15/27] New file: gcc/jit/jit-playback.h


This files declares the gcc::jit::playback internal API, called by
the dummy "frontend" to replay the public API calls made to the
library.  A thin wrapper around trees.

gcc/jit/
	* jit-playback.h: New.
---
 gcc/jit/jit-playback.h | 564 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 564 insertions(+)
 create mode 100644 gcc/jit/jit-playback.h

diff --git a/gcc/jit/jit-playback.h b/gcc/jit/jit-playback.h
new file mode 100644
index 0000000..dcb19bf
--- /dev/null
+++ b/gcc/jit/jit-playback.h
@@ -0,0 +1,564 @@
+/* Internals of libgccjit: classes for playing back recorded API calls.
+   Copyright (C) 2013-2014 Free Software Foundation, Inc.
+   Contributed by David Malcolm <dmalcolm@redhat.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/>.  */
+
+#ifndef JIT_PLAYBACK_H
+#define JIT_PLAYBACK_H
+
+#include <utility> // for std::pair
+
+#include "jit-recording.h"
+
+namespace gcc {
+
+namespace jit {
+
+/**********************************************************************
+ Playback.
+ **********************************************************************/
+
+namespace playback {
+
+class context
+{
+public:
+  context (::gcc::jit::recording::context *ctxt);
+  ~context ();
+
+  void gt_ggc_mx ();
+
+  void replay ();
+
+  location *
+  new_location (recording::location *rloc,
+		const char *filename,
+		int line,
+		int column);
+
+  type *
+  get_type (enum gcc_jit_types type);
+
+  type *
+  new_array_type (location *loc,
+		  type *element_type,
+		  int num_elements);
+
+  field *
+  new_field (location *loc,
+	     type *type,
+	     const char *name);
+
+  compound_type *
+  new_compound_type (location *loc,
+		     const char *name,
+		     bool is_struct); /* else is union */
+
+  type *
+  new_function_type (type *return_type,
+		     vec<type *> *param_types,
+		     int is_variadic);
+
+  param *
+  new_param (location *loc,
+	     type *type,
+	     const char *name);
+
+  function *
+  new_function (location *loc,
+		enum gcc_jit_function_kind kind,
+		type *return_type,
+		const char *name,
+		vec<param *> *params,
+		int is_variadic,
+		enum built_in_function builtin_id);
+
+  lvalue *
+  new_global (location *loc,
+	      type *type,
+	      const char *name);
+
+  rvalue *
+  new_rvalue_from_int (type *type,
+		       int value);
+
+  rvalue *
+  new_rvalue_from_double (type *type,
+			  double value);
+
+  rvalue *
+  new_rvalue_from_ptr (type *type,
+		       void *value);
+
+  rvalue *
+  new_string_literal (const char *value);
+
+  rvalue *
+  new_unary_op (location *loc,
+		enum gcc_jit_unary_op op,
+		type *result_type,
+		rvalue *a);
+
+  rvalue *
+  new_binary_op (location *loc,
+		 enum gcc_jit_binary_op op,
+		 type *result_type,
+		 rvalue *a, rvalue *b);
+
+  rvalue *
+  new_comparison (location *loc,
+		  enum gcc_jit_comparison op,
+		  rvalue *a, rvalue *b);
+
+  rvalue *
+  new_call (location *loc,
+	    function *func,
+	    vec<rvalue *> args);
+
+  rvalue *
+  new_call_through_ptr (location *loc,
+			rvalue *fn_ptr,
+			vec<rvalue *> args);
+
+  rvalue *
+  new_cast (location *loc,
+	    rvalue *expr,
+	    type *type_);
+
+  lvalue *
+  new_array_access (location *loc,
+		    rvalue *ptr,
+		    rvalue *index);
+
+  void
+  set_str_option (enum gcc_jit_str_option opt,
+		  const char *value);
+
+  void
+  set_int_option (enum gcc_jit_int_option opt,
+		  int value);
+
+  void
+  set_bool_option (enum gcc_jit_bool_option opt,
+		   int value);
+
+  const char *
+  get_str_option (enum gcc_jit_str_option opt) const
+  {
+    return m_recording_ctxt->get_str_option (opt);
+  }
+
+  int
+  get_int_option (enum gcc_jit_int_option opt) const
+  {
+    return m_recording_ctxt->get_int_option (opt);
+  }
+
+  int
+  get_bool_option (enum gcc_jit_bool_option opt) const
+  {
+    return m_recording_ctxt->get_bool_option (opt);
+  }
+
+  result *
+  compile ();
+
+  void
+  add_error (location *loc, const char *fmt, ...)
+      GNU_PRINTF(3, 4);
+
+  void
+  add_error_va (location *loc, const char *fmt, va_list ap)
+      GNU_PRINTF(3, 0);
+
+  const char *
+  get_first_error () const;
+
+  void
+  set_tree_location (tree t, location *loc);
+
+  tree
+  new_field_access (location *loc,
+		    tree datum,
+		    field *field);
+
+  tree
+  new_dereference (tree ptr, location *loc);
+
+  tree
+  as_truth_value (tree expr, location *loc);
+
+  bool errors_occurred () const
+  {
+    return m_recording_ctxt->errors_occurred ();
+  }
+
+private:
+  void dump_generated_code ();
+
+  rvalue *
+  build_call (location *loc,
+	      tree fn_ptr,
+	      vec<rvalue *> args);
+
+  tree
+  build_cast (location *loc,
+	      rvalue *expr,
+	      type *type_);
+
+  source_file *
+  get_source_file (const char *filename);
+
+  void handle_locations ();
+
+private:
+  ::gcc::jit::recording::context *m_recording_ctxt;
+
+  /* Allocated using xmalloc (by xstrdup).  */
+  char *m_path_template;
+
+  /* This either aliases m_path_template, or is NULL.  */
+  char *m_path_tempdir;
+
+  /* The following are allocated using xmalloc.  */
+  char *m_path_c_file;
+  char *m_path_s_file;
+  char *m_path_so_file;
+
+  vec<function *> m_functions;
+  tree m_char_array_type_node;
+  tree m_const_char_ptr;
+
+  /* Source location handling.  */
+  vec<source_file *> m_source_files;
+
+  vec<std::pair<tree, location *> > m_cached_locations;
+};
+
+/* 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.
+   The exception is the "function" class, which is tracked and marked by
+   the jit::context, since it needs to stay alive during post-processing
+   (when the GC could run). */
+class wrapper
+{
+public:
+  /* Allocate in the GC heap.  */
+  void *operator new (size_t sz);
+
+};
+
+class type : public wrapper
+{
+public:
+  type (tree inner)
+    : m_inner(inner)
+  {}
+
+  tree as_tree () const { return m_inner; }
+
+  type *get_pointer () const { return new type (build_pointer_type (m_inner)); }
+
+  type *get_const () const
+  {
+    return new type (build_qualified_type (m_inner, TYPE_QUAL_CONST));
+  }
+
+  type *get_volatile () const
+  {
+    return new type (build_qualified_type (m_inner, TYPE_QUAL_VOLATILE));
+  }
+
+private:
+  tree m_inner;
+};
+
+class compound_type : public type
+{
+public:
+  compound_type (tree inner)
+    : type (inner)
+  {}
+
+  void set_fields (const vec<field *> &fields);
+};
+
+class field : public wrapper
+{
+public:
+  field (tree inner)
+    : m_inner(inner)
+  {}
+
+  tree as_tree () const { return m_inner; }
+
+private:
+  tree m_inner;
+};
+
+class function : public wrapper
+{
+public:
+  function(context *ctxt, tree fndecl, enum gcc_jit_function_kind kind);
+
+  void gt_ggc_mx ();
+
+  tree get_return_type_as_tree () const;
+
+  tree as_fndecl () const { return m_inner_fndecl; }
+
+  enum gcc_jit_function_kind get_kind () const { return m_kind; }
+
+  lvalue *
+  new_local (location *loc,
+	     type *type,
+	     const char *name);
+
+  block*
+  new_block (const char *name);
+
+  void
+  build_stmt_list ();
+
+  void
+  postprocess ();
+
+public:
+  context *m_ctxt;
+
+public:
+  void
+  set_tree_location (tree t, location *loc)
+  {
+    m_ctxt->set_tree_location (t, loc);
+  }
+
+private:
+  tree m_inner_fndecl;
+  tree m_inner_block;
+  tree m_inner_bind_expr;
+  enum gcc_jit_function_kind m_kind;
+  tree m_stmt_list;
+  tree_stmt_iterator m_stmt_iter;
+  vec<block *> m_blocks;
+};
+
+class block : public wrapper
+{
+public:
+  block (function *func,
+	 const char *name);
+
+  tree as_label_decl () const { return m_label_decl; }
+
+  void
+  add_eval (location *loc,
+	    rvalue *rvalue);
+
+  void
+  add_assignment (location *loc,
+		  lvalue *lvalue,
+		  rvalue *rvalue);
+
+  void
+  add_comment (location *loc,
+	       const char *text);
+
+  void
+  add_conditional (location *loc,
+		   rvalue *boolval,
+		   block *on_true,
+		   block *on_false);
+
+  block *
+  add_block (location *loc,
+	     const char *name);
+
+  void
+  add_jump (location *loc,
+	    block *target);
+
+  void
+  add_return (location *loc,
+	      rvalue *rvalue);
+
+private:
+  void
+  set_tree_location (tree t, location *loc)
+  {
+    m_func->set_tree_location (t, loc);
+  }
+
+  void add_stmt (tree stmt)
+  {
+    /* TODO: use one stmt_list per block.  */
+    m_stmts.safe_push (stmt);
+  }
+
+private:
+  function *m_func;
+  tree m_label_decl;
+  vec<tree> m_stmts;
+
+public: // for now
+  tree m_label_expr;
+
+  friend class function;
+};
+
+class rvalue : public wrapper
+{
+public:
+  rvalue (context *ctxt, tree inner)
+    : m_ctxt (ctxt),
+      m_inner (inner)
+  {}
+
+  rvalue *
+  as_rvalue () { return this; }
+
+  tree as_tree () const { return m_inner; }
+
+  context *get_context () const { return m_ctxt; }
+
+  type *
+  get_type () { return new type (TREE_TYPE (m_inner)); }
+
+  rvalue *
+  access_field (location *loc,
+		field *field);
+
+  lvalue *
+  dereference_field (location *loc,
+		     field *field);
+
+  lvalue *
+  dereference (location *loc);
+
+private:
+  context *m_ctxt;
+  tree m_inner;
+};
+
+class lvalue : public rvalue
+{
+public:
+  lvalue (context *ctxt, tree inner)
+    : rvalue(ctxt, inner)
+  {}
+
+  lvalue *
+  as_lvalue () { return this; }
+
+  lvalue *
+  access_field (location *loc,
+		field *field);
+
+  rvalue *
+  get_address (location *loc);
+
+};
+
+class param : public lvalue
+{
+public:
+  param (context *ctxt, tree inner)
+    : lvalue(ctxt, inner)
+  {}
+};
+
+/* 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);
+
+  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);
+
+  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;
+
+} // namespace gcc::jit
+
+} // namespace gcc
+
+#endif /* JIT_PLAYBACK_H */
+
-- 
1.8.5.3


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