aboutsummaryrefslogtreecommitdiff
path: root/gcc/jit/jit-playback.c
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2014-12-09 15:35:39 +0000
committerDavid Malcolm <dmalcolm@gcc.gnu.org>2014-12-09 15:35:39 +0000
commit463366a06a14ae693a56571b6ed348e70a146168 (patch)
tree9eab3d6e19824a1c4a3da5c613e0e4dfc2d313ad /gcc/jit/jit-playback.c
parent799505ae0c8aa82a1557b882b495b303f24e3be3 (diff)
downloadgcc-463366a06a14ae693a56571b6ed348e70a146168.zip
gcc-463366a06a14ae693a56571b6ed348e70a146168.tar.gz
gcc-463366a06a14ae693a56571b6ed348e70a146168.tar.bz2
PR jit/64166: Add API entrypoint gcc_jit_context_enable_dump
gcc/jit/ChangeLog: PR jit/64166 * docs/topics/contexts.rst (Debugging): Add description of gcc_jit_context_enable_dump. * docs/_build/texinfo/libgccjit.texi: Regenerate. * jit-playback.c: Include context.h. (class auto_argvec): New class. (auto_argvec::~auto_argvec): New function. (gcc::jit::playback::context::compile): Convert fake_args to be an auto_argvec, so that it can contain dynamically-allocated strings. Construct a vec of all requested dumps, and pass it to make_fake_args. Extract requested dumps between the calls to toplev::main and toplev::finalize. (gcc::jit::playback::context::make_fake_args): Convert param "argvec" to be a vec <char *>, and gain a "requested_dumps" param. Convert to dynamically-allocated arg strings by converting ADD_ARG to take a copy of the arg, and add ADD_ARG_TAKE_OWNERSHIP for args that are already a copy. Add args for all requested dumps. (gcc::jit::playback::context::extract_any_requested_dumps): New function. (gcc::jit::playback::context::read_dump_file): New function. * jit-playback.h (gcc::jit::playback::context::make_fake_args): Convert param "argvec" to be a vec <char *>, and gain a "requested_dumps" param. (gcc::jit::playback::context::extract_any_requested_dumps): New function. (gcc::jit::playback::context::read_dump_file): New function. * jit-recording.c (gcc::jit::recording::context::enable_dump): New function. (gcc::jit::recording::context::get_all_requested_dumps): New function. * jit-recording.h (gcc::jit::recording::requested_dump): New struct. (gcc::jit::recording::context::enable_dump): New function. (gcc::jit::recording::context::get_all_requested_dumps): New function. (gcc::jit::recording::context::m_requested_dumps): New field. * libgccjit.c (gcc_jit_context_enable_dump): New API entrypoint. * libgccjit.h (gcc_jit_context_enable_dump): New API entrypoint. * libgccjit.map (gcc_jit_context_enable_dump): New API entrypoint. gcc/testsuite/ChangeLog: PR jit/64166 PR jit/64020 * jit.dg/harness.h (CHECK_STRING_CONTAINS): New macro. (check_string_contains): New function. * jit.dg/test-error-unrecognized-dump.c: New file. * jit.dg/test-functions.c (trig_sincos_dump): New variable. (trig_statistics_dump): New variable. (create_test_of_builtin_trig): Enable dumping of "sincos" and "statistics" into "trig_sincos_dump" and "trig_statistics_dump". (verify_test_of_builtin_trig): Verify the sincos and statistics dumps. * jit.dg/test-sum-of-squares.c (dump_vrp1): New variable. (create_code): Enable dumping of "tree-vrp1" into dump_vrp1. (verify_code): Verify the tree-vrp1 dump. From-SVN: r218521
Diffstat (limited to 'gcc/jit/jit-playback.c')
-rw-r--r--gcc/jit/jit-playback.c141
1 files changed, 136 insertions, 5 deletions
diff --git a/gcc/jit/jit-playback.c b/gcc/jit/jit-playback.c
index ecdae80..cf50fb3 100644
--- a/gcc/jit/jit-playback.c
+++ b/gcc/jit/jit-playback.c
@@ -47,6 +47,7 @@ along with GCC; see the file COPYING3. If not see
#include "gimplify.h"
#include "gcc-driver-name.h"
#include "attribs.h"
+#include "context.h"
#include "jit-common.h"
#include "jit-playback.h"
@@ -1552,6 +1553,26 @@ make_tempdir_path_template ()
return result;
}
+/* A subclass of auto_vec <char *> that frees all of its elements on
+ deletion. */
+
+class auto_argvec : public auto_vec <char *>
+{
+ public:
+ ~auto_argvec ();
+};
+
+/* auto_argvec's dtor, freeing all contained strings, automatically
+ chaining up to ~auto_vec <char *>, which frees the internal buffer. */
+
+auto_argvec::~auto_argvec ()
+{
+ int i;
+ char *str;
+ FOR_EACH_VEC_ELT (*this, i, str)
+ free (str);
+}
+
/* Compile a playback::context:
- Use the context's options to cconstruct command-line options, and
@@ -1594,14 +1615,25 @@ compile ()
if (!ctxt_progname)
ctxt_progname = "libgccjit.so";
- auto_vec <const char *> fake_args;
- make_fake_args (&fake_args, ctxt_progname);
+ auto_vec <recording::requested_dump> requested_dumps;
+ m_recording_ctxt->get_all_requested_dumps (&requested_dumps);
+
+ auto_argvec fake_args;
+ make_fake_args (&fake_args, ctxt_progname, &requested_dumps);
if (errors_occurred ())
return NULL;
+ /* This runs the compiler. */
toplev toplev (false);
toplev.main (fake_args.length (),
const_cast <char **> (fake_args.address ()));
+
+ /* Extracting dumps makes use of the gcc::dump_manager, hence we
+ need to do it between toplev::main (which creates the dump manager)
+ and toplev::finalize (which deletes it). */
+ extract_any_requested_dumps (&requested_dumps);
+
+ /* Clean up the compiler. */
toplev.finalize ();
active_playback_ctxt = NULL;
@@ -1645,10 +1677,12 @@ compile ()
void
playback::context::
-make_fake_args (auto_vec <const char *> *argvec,
- const char *ctxt_progname)
+make_fake_args (vec <char *> *argvec,
+ const char *ctxt_progname,
+ vec <recording::requested_dump> *requested_dumps)
{
-#define ADD_ARG(arg) argvec->safe_push (arg)
+#define ADD_ARG(arg) argvec->safe_push (xstrdup (arg))
+#define ADD_ARG_TAKE_OWNERSHIP(arg) argvec->safe_push (arg)
ADD_ARG (ctxt_progname);
ADD_ARG (m_path_c_file);
@@ -1707,7 +1741,104 @@ make_fake_args (auto_vec <const char *> *argvec,
ADD_ARG ("-fdump-rtl-all");
ADD_ARG ("-fdump-ipa-all");
}
+
+ /* Add "-fdump-" options for any calls to
+ gcc_jit_context_enable_dump. */
+ {
+ int i;
+ recording::requested_dump *d;
+ FOR_EACH_VEC_ELT (*requested_dumps, i, d)
+ {
+ char *arg = concat ("-fdump-", d->m_dumpname, NULL);
+ ADD_ARG_TAKE_OWNERSHIP (arg);
+ }
+ }
+
#undef ADD_ARG
+#undef ADD_ARG_TAKE_OWNERSHIP
+}
+
+/* The second half of the implementation of gcc_jit_context_enable_dump.
+ Iterate through the requested dumps, reading the underlying files
+ into heap-allocated buffers, writing pointers to the buffers into
+ the char ** pointers provided by client code.
+ Client code is responsible for calling free on the results. */
+
+void
+playback::context::
+extract_any_requested_dumps (vec <recording::requested_dump> *requested_dumps)
+{
+ int i;
+ recording::requested_dump *d;
+ FOR_EACH_VEC_ELT (*requested_dumps, i, d)
+ {
+ dump_file_info *dfi;
+ char *filename;
+ char *content;
+
+ dfi = g->get_dumps ()->get_dump_file_info_by_switch (d->m_dumpname);
+ if (!dfi)
+ {
+ add_error (NULL, "unrecognized dump: %s", d->m_dumpname);
+ continue;
+ }
+
+ filename = g->get_dumps ()->get_dump_file_name (dfi);
+ content = read_dump_file (filename);
+ *(d->m_out_ptr) = content;
+ free (filename);
+ }
+}
+
+/* Helper function for playback::context::extract_any_requested_dumps
+ (itself for use in implementation of gcc_jit_context_enable_dump).
+
+ Attempt to read the complete file at the given path, returning the
+ bytes found there as a buffer.
+ The caller is responsible for calling free on the result.
+ Errors will be reported on the context, and lead to NULL being
+ returned; an out-of-memory error will terminate the process. */
+
+char *
+playback::context::read_dump_file (const char *path)
+{
+ char *result = NULL;
+ size_t total_sz = 0;
+ char buf[4096];
+ size_t sz;
+ FILE *f_in;
+
+ f_in = fopen (path, "r");
+ if (!f_in)
+ {
+ add_error (NULL, "unable to open %s for reading", path);
+ return NULL;
+ }
+
+ while ( (sz = fread (buf, 1, sizeof (buf), f_in)) )
+ {
+ size_t old_total_sz = total_sz;
+ total_sz += sz;
+ result = reinterpret_cast <char *> (xrealloc (result, total_sz + 1));
+ memcpy (result + old_total_sz, buf, sz);
+ }
+
+ if (!feof (f_in))
+ {
+ add_error (NULL, "error reading from %s", path);
+ free (result);
+ return NULL;
+ }
+
+ fclose (f_in);
+
+ if (result)
+ {
+ result[total_sz] = '\0';
+ return result;
+ }
+ else
+ return xstrdup ("");
}
/* Part of playback::context::compile ().