Permalink
Browse files

Add support for another kind of callback; start wrapping trees

  • Loading branch information...
1 parent 2bdc603 commit 7a7517f1f05810d6c6dd3ed7ceb62053cf0fdbf9 @davidmalcolm committed Mar 31, 2011
Showing with 99 additions and 27 deletions.
  1. +1 −0 .gitignore
  2. +5 −1 Makefile
  3. +4 −0 gcc-python-wrappers.h
  4. +42 −24 gcc-python.c
  5. +3 −2 test.py
  6. +44 −0 tree.pyx
View
@@ -5,3 +5,4 @@ a.out
# Generated by Cython:
optpass.c
+tree.c
View
@@ -3,7 +3,8 @@ GCC=gcc
PLUGIN_SOURCE_FILES= \
gcc-python.c \
gcc-python-closure.c \
- optpass.c
+ optpass.c \
+ tree.c
PLUGIN_OBJECT_FILES= $(patsubst %.c,%.o,$(PLUGIN_SOURCE_FILES))
GCCPLUGINS_DIR:= $(shell $(GCC) --print-file-name=plugin)
@@ -26,6 +27,9 @@ clean:
optpass.c: optpass.pyx
cython $^ -o $@
+tree.c: tree.pyx
+ cython $^ -o $@
+
# Hint for debugging: add -v to the gcc options
# to get a command line for invoking individual subprocesses
# Doing so seems to require that paths be absolute, rather than relative
View
@@ -4,6 +4,10 @@
#include "tree-pass.h"
PyMODINIT_FUNC initoptpass(void);
+PyMODINIT_FUNC inittree(void);
+
+extern PyObject *
+gcc_python_make_wrapper_tree(tree t);
extern PyObject *
gcc_python_make_wrapper_opt_pass(struct opt_pass *ptr);
View
@@ -102,34 +102,15 @@ static void my_callback_for_##NAME(void *gcc_data, void *user_data) \
# undef DEFEVENT
#endif /* GCC_PYTHON_TRACE_ALL_EVENTS */
-//gcc_debug_callback(enum plugin_event event, void *gcc_data, void *user_data)
-
static void
-gcc_python_callback_for_PLUGIN_PASS_EXECUTION(void *gcc_data, void *user_data)
+gcc_python_finish_invoking_callback(PyGILState_STATE gstate, PyObject *wrapped_gcc_data, void *user_data)
{
- //gcc_data: struct opt_pass *pass
- struct opt_pass *pass = (struct opt_pass *)gcc_data;
struct callback_closure *closure = (struct callback_closure *)user_data;
- PyObject *wrapped_gcc_data = NULL;
PyObject *args = NULL;
PyObject *result = NULL;
- PyGILState_STATE gstate;
-
- //printf("%s:%i:gcc_python_callback_for_PLUGIN_PASS_EXECUTION(%p, %p)\n", __FILE__, __LINE__, gcc_data, user_data);
- assert(pass);
assert(closure);
-
- gstate = PyGILState_Ensure();
-
- //PyObject_Print(closure->callback, stdout, 0);
- //PyObject_Print(closure->extraargs, stdout, 0);
-
- // printf("%s:%i:gcc_python_callback_for_PLUGIN_PASS_EXECUTION(%p, %p)\n", __FILE__, __LINE__, gcc_data, user_data);
-
- wrapped_gcc_data = gcc_python_make_wrapper_opt_pass(pass);
-
- //PyObject_Print(wrapped_gcc_data, stdout, 0);
+ /* We take ownership of wrapped_gcc_data, which could also be NULL */
if (!wrapped_gcc_data) {
goto cleanup;
@@ -150,10 +131,38 @@ gcc_python_callback_for_PLUGIN_PASS_EXECUTION(void *gcc_data, void *user_data)
Py_XDECREF(result);
PyGILState_Release(gstate);
- return;
+}
+
+static void
+gcc_python_callback_for_PLUGIN_PASS_PRE_GENERICIZE(void *gcc_data, void *user_data)
+{
+ PyGILState_STATE gstate;
+ tree fndecl = (tree)gcc_data;
+
+ //printf("%s:%i:(%p, %p)\n", __FILE__, __LINE__, gcc_data, user_data);
+ assert(fndecl);
+ gstate = PyGILState_Ensure();
-
+ gcc_python_finish_invoking_callback(gstate,
+ gcc_python_make_wrapper_tree(fndecl),
+ user_data);
+}
+
+static void
+gcc_python_callback_for_PLUGIN_PASS_EXECUTION(void *gcc_data, void *user_data)
+{
+ PyGILState_STATE gstate;
+ struct opt_pass *pass = (struct opt_pass *)gcc_data;
+
+ //printf("%s:%i:(%p, %p)\n", __FILE__, __LINE__, gcc_data, user_data);
+ assert(pass);
+
+ gstate = PyGILState_Ensure();
+
+ gcc_python_finish_invoking_callback(gstate,
+ gcc_python_make_wrapper_opt_pass(pass),
+ user_data);
}
@@ -178,6 +187,13 @@ gcc_python_register_callback(PyObject *self, PyObject *args)
}
switch ((enum plugin_event)event) {
+ case PLUGIN_PRE_GENERICIZE:
+ register_callback("python", // FIXME
+ (enum plugin_event)event,
+ gcc_python_callback_for_PLUGIN_PASS_PRE_GENERICIZE,
+ closure);
+ break;
+
case PLUGIN_PASS_EXECUTION:
register_callback("python", // FIXME
(enum plugin_event)event,
@@ -307,8 +323,10 @@ plugin_init (struct plugin_name_args *plugin_info,
return 1;
}
- // init other modules
+ /* Init other modules */
+ /* FIXME: properly integrate them within the module hierarchy */
initoptpass();
+ inittree();
gcc_python_run_any_script();
View
@@ -1,14 +1,15 @@
# Sample python script, to be run by our gcc plugin (see "make test")
-print "hello world"
+#print "hello world"
import gcc
-#help(gcc)
+help(gcc)
def my_callback(*args, **kwargs):
print('my_callback was called: args=%r kwargs=%r' % (args, kwargs))
gcc.register_callback(gcc.PLUGIN_PASS_EXECUTION, my_callback)
+gcc.register_callback(gcc.PLUGIN_PRE_GENERICIZE, my_callback)
# Try some insane values:
#gcc.register_callback(-1, my_callback)
View
@@ -0,0 +1,44 @@
+"""
+Wrapper around one of gcc's "tree"
+
+This seems to be this typedef:
+ coretypes.h:60:typedef union tree_node *tree;
+ coretypes.h:63:typedef const union tree_node *const_tree;
+"""
+import sys
+
+cdef extern from "config.h":
+ pass
+
+cdef extern from "system.h":
+ pass
+
+cdef extern from "coretypes.h":
+ cdef union tree_node:
+ pass
+ ctypedef tree_node *tree
+
+cdef extern from "gcc-python-wrappers.h":
+ pass
+
+cdef class Tree:
+ cdef tree t
+
+ def __init__(self):
+ self.t = NULL
+
+ cdef __set_ptr(self, tree t):
+ self.t = t
+ # FIXME: interaction with gcc's GC ?
+
+ cdef __get_ptr(self, tree t):
+ self.t = t
+
+ #def __repr__(self):
+ # return 'optpass.OptPass(%r)' % self.ptr.name
+
+
+cdef extern gcc_python_make_wrapper_tree(tree t):
+ obj = Tree()
+ obj.__set_ptr(t)
+ return obj

0 comments on commit 7a7517f

Please sign in to comment.