Skip to content

Commit b64cff1

Browse files
committed
Generate appropriate gcc.Gimple subclasses for each statement; add some experiments on also wrapping the underlying layouts
1 parent 1b85d43 commit b64cff1

6 files changed

+213
-6
lines changed

Makefile

+2-2
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,10 @@ autogenerated-gimple-types.txt: gimple-types.txt.in
3636
autogenerated-tree-types.txt: tree-types.txt.in
3737
cpp $(CFLAGS) $^ -o $@
3838

39-
autogenerated-tree.c: cpybuilder.py generate-tree-c.py autogenerated-tree-types.txt
39+
autogenerated-tree.c: cpybuilder.py generate-tree-c.py autogenerated-tree-types.txt maketreetypes.py
4040
python generate-tree-c.py > $@
4141

42-
autogenerated-gimple.c: cpybuilder.py generate-gimple-c.py autogenerated-gimple-types.txt
42+
autogenerated-gimple.c: cpybuilder.py generate-gimple-c.py autogenerated-gimple-types.txt maketreetypes.py
4343
python generate-gimple-c.py > $@
4444

4545
# Hint for debugging: add -v to the gcc options

gcc-python-tree.c

+6-1
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,13 @@ PyObject*
5454
gcc_python_make_wrapper_gimple(gimple stmt)
5555
{
5656
struct PyGccGimple *gimple_obj = NULL;
57+
PyTypeObject* tp;
58+
59+
tp = gcc_python_autogenerated_gimple_type_for_stmt(stmt);
60+
assert(tp);
61+
//printf("tp:%p\n", tp);
5762

58-
gimple_obj = PyObject_New(struct PyGccGimple, &gcc_GimpleType);
63+
gimple_obj = PyObject_New(struct PyGccGimple, tp);
5964
if (!gimple_obj) {
6065
goto error;
6166
}

gcc-python.h

+2
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ DECLARE_SIMPLE_WRAPPER(PyGccTree,
5757
/* autogenerated-gimple.c */
5858
int autogenerated_gimple_init_types(void);
5959
void autogenerated_gimple_add_types(PyObject *m);
60+
PyTypeObject* gcc_python_autogenerated_gimple_type_for_stmt(gimple g);
61+
6062

6163
int
6264
gcc_python_autogenerated_tree_init_types(void);

generate-gimple-c.py

+172-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from maketreetypes import iter_gimple_types
1+
from maketreetypes import iter_gimple_types, iter_gimple_struct_types
22

33
from cpybuilder import *
44

@@ -11,8 +11,155 @@
1111
modinit_preinit = ''
1212
modinit_postinit = ''
1313

14+
gimple_struct_types = list(iter_gimple_struct_types())
1415
gimple_types = list(iter_gimple_types())
1516

17+
# gimple.h declares a family of struct gimple_statement_* which internally express an inheritance hierarchy, via enum enum gimple_statement_structure_enum (see gsstruct.def).
18+
# FIXME there's also enum gimple_code, which is used to look up into this hierarchy
19+
#
20+
# From reading gimple.h, the struct hierarchy is:
21+
#
22+
# gimple_statement_base (GSS_BASE)
23+
# gimple_statement_with_ops_base
24+
# gimple_statement_with_ops (GSS_WITH_OPS)
25+
# gimple_statement_with_memory_ops_base (GSS_WITH_MEM_OPS_BASE)
26+
# gimple_statement_with_memory_ops (GSS_WITH_MEM_OPS)
27+
# gimple_statement_call (GSS_CALL)
28+
# gimple_statement_asm (GSS_ASM)
29+
# gimple_statement_omp (GSS_OMP)
30+
# gimple_statement_omp_critical (GSS_OMP_CRITICAL)
31+
# gimple_statement_omp_for (GSS_OMP_FOR)
32+
# gimple_statement_omp_parallel (GSS_OMP_PARALLEL)
33+
# gimple_statement_omp_task (GSS_OMP_TASK)
34+
# gimple_statement_omp_sections (GSS_OMP_SECTIONS)
35+
# gimple_statement_omp_single (GSS_OMP_SINGLE)
36+
# gimple_statement_bind (GSS_BIND)
37+
# gimple_statement_catch (GSS_CATCH)
38+
# gimple_statement_eh_filter (GSS_EH_FILTER)
39+
# gimple_statement_eh_mnt (GSS_EH_MNT)
40+
# gimple_statement_phi (GSS_PHI)
41+
# gimple_statement_eh_ctrl (GSS_EH_CTRL)
42+
# gimple_statement_try (GSS_TRY)
43+
# gimple_statement_wce (GSS_WCE)
44+
# gimple_statement_omp_continue (GSS_OMP_CONTINUE) (does not inherit from gimple_statement_omp)
45+
# gimple_statement_omp_atomic_load (GSS_OMP_ATOMIC_LOAD (likewise)
46+
# gimple_statement_omp_atomic_store (GSS_OMP_ATOMIC_STORE) (ditto)
47+
48+
# The inheritance hierarchy of struct gimple_statement_*,
49+
# expressed as (structname, parentstructname) pairs:
50+
struct_hier = (('gimple_statement_base', None),
51+
('gimple_statement_with_ops_base', 'simple_statement_base'),
52+
('gimple_statement_with_ops', 'gimple_statement_with_ops_base'),
53+
('gimple_statement_with_memory_ops_base', 'gimple_statement_with_ops_base opbase'),
54+
('gimple_statement_with_memory_ops', 'gimple_statement_with_memory_ops_base membase'),
55+
('gimple_statement_call', 'gimple_statement_with_memory_ops_base membase'),
56+
('gimple_statement_omp', 'gimple_statement_base'),
57+
('gimple_statement_bind', 'gimple_statement_base'),
58+
('gimple_statement_catch', 'gimple_statement_base'),
59+
('gimple_statement_eh_filter', 'gimple_statement_base'),
60+
('gimple_statement_eh_mnt', 'gimple_statement_base'),
61+
('gimple_statement_phi', 'gimple_statement_base'),
62+
('gimple_statement_eh_ct', 'gimple_statement_base'),
63+
('gimple_statement_try', 'gimple_statement_base'),
64+
('gimple_statement_wce', 'gimple_statement_base'),
65+
('gimple_statement_asm', 'gimple_statement_with_memory_ops_base'),
66+
('gimple_statement_omp_critical', 'gimple_statement_omp'),
67+
('gimple_statement_omp_for', 'gimple_statement_omp'),
68+
('gimple_statement_omp_parallel', 'gimple_statement_omp'),
69+
('gimple_statement_omp_task', 'gimple_statement_omp_parallel'),
70+
('gimple_statement_omp_sections', 'gimple_statement_omp'),
71+
('gimple_statement_omp_continue', 'gimple_statement_base'),
72+
('gimple_statement_omp_single', 'gimple_statement_omp'),
73+
('gimple_statement_omp_atomic_load', 'gimple_statement_base'),
74+
('gimple_statement_omp_atomic_store', 'gimple_statement_base'))
75+
76+
# Interleaving with the material from gimple.def:
77+
# gimple_statement_base (GSS_BASE)
78+
# GIMPLE_ERROR_MARK, "gimple_error_mark", GSS_BASE
79+
# GIMPLE_NOP, "gimple_nop", GSS_BASE
80+
# GIMPLE_OMP_RETURN, "gimple_omp_return", GSS_BASE
81+
# GIMPLE_OMP_SECTIONS_SWITCH, "gimple_omp_sections_switch", GSS_BASE
82+
# GIMPLE_PREDICT, "gimple_predict", GSS_BASE
83+
# gimple_statement_with_ops_base
84+
# gimple_statement_with_ops (GSS_WITH_OPS)
85+
# GIMPLE_COND, "gimple_cond", GSS_WITH_OPS
86+
# GIMPLE_DEBUG, "gimple_debug", GSS_WITH_OPS
87+
# GIMPLE_GOTO, "gimple_goto", GSS_WITH_OPS
88+
# GIMPLE_LABEL, "gimple_label", GSS_WITH_OPS
89+
# GIMPLE_SWITCH, "gimple_switch", GSS_WITH_OPS
90+
# gimple_statement_with_memory_ops_base (GSS_WITH_MEM_OPS_BASE)
91+
# gimple_statement_with_memory_ops (GSS_WITH_MEM_OPS)
92+
# GIMPLE_ASSIGN, "gimple_assign", GSS_WITH_MEM_OPS
93+
# GIMPLE_RETURN, "gimple_return", GSS_WITH_MEM_OPS
94+
# gimple_statement_call (GSS_CALL)
95+
# GIMPLE_CALL, "gimple_call", GSS_CALL
96+
# gimple_statement_asm (GSS_ASM)
97+
# GIMPLE_ASM, "gimple_asm", GSS_ASM
98+
# gimple_statement_omp (GSS_OMP)
99+
# GIMPLE_OMP_MASTER, "gimple_omp_master", GSS_OMP
100+
# GIMPLE_OMP_ORDERED, "gimple_omp_ordered", GSS_OMP
101+
# GIMPLE_OMP_SECTION, "gimple_omp_section", GSS_OMP
102+
# gimple_statement_omp_critical (GSS_OMP_CRITICAL)
103+
# GIMPLE_OMP_CRITICAL, "gimple_omp_critical", GSS_OMP_CRITICAL
104+
# gimple_statement_omp_for (GSS_OMP_FOR)
105+
# GIMPLE_OMP_FOR, "gimple_omp_for", GSS_OMP_FOR
106+
# gimple_statement_omp_parallel (GSS_OMP_PARALLEL)
107+
# GIMPLE_OMP_PARALLEL, "gimple_omp_parallel", GSS_OMP_PARALLEL
108+
# gimple_statement_omp_task (GSS_OMP_TASK)
109+
# GIMPLE_OMP_TASK, "gimple_omp_task", GSS_OMP_TASK
110+
# gimple_statement_omp_sections (GSS_OMP_SECTIONS)
111+
# GIMPLE_OMP_SECTIONS, "gimple_omp_sections", GSS_OMP_SECTIONS
112+
# gimple_statement_omp_single (GSS_OMP_SINGLE)
113+
# GIMPLE_OMP_SINGLE, "gimple_omp_single", GSS_OMP_SINGLE
114+
# gimple_statement_bind (GSS_BIND)
115+
# GIMPLE_BIND, "gimple_bind", GSS_BIND
116+
# gimple_statement_catch (GSS_CATCH)
117+
# GIMPLE_CATCH, "gimple_catch", GSS_CATCH
118+
# gimple_statement_eh_filter (GSS_EH_FILTER)
119+
# GIMPLE_EH_FILTER, "gimple_eh_filter", GSS_EH_FILTER
120+
# gimple_statement_eh_mnt (GSS_EH_MNT)
121+
# GIMPLE_EH_MUST_NOT_THROW, "gimple_eh_must_not_throw", GSS_EH_MNT
122+
# gimple_statement_phi (GSS_PHI)
123+
# GIMPLE_PHI, "gimple_phi", GSS_PHI
124+
# gimple_statement_eh_ctrl (GSS_EH_CTRL)
125+
# GIMPLE_RESX, "gimple_resx", GSS_EH_CTRL
126+
# GIMPLE_EH_DISPATCH, "gimple_eh_dispatch", GSS_EH_CTRL
127+
# gimple_statement_try (GSS_TRY)
128+
# GIMPLE_TRY, "gimple_try", GSS_TRY
129+
# gimple_statement_wce (GSS_WCE)
130+
# GIMPLE_WITH_CLEANUP_EXPR, "gimple_with_cleanup_expr", GSS_WCE
131+
# gimple_statement_omp_continue (GSS_OMP_CONTINUE) (does not inherit from gimple_statement_omp)
132+
# GIMPLE_OMP_CONTINUE, "gimple_omp_continue", GSS_OMP_CONTINUE
133+
# gimple_statement_omp_atomic_load (GSS_OMP_ATOMIC_LOAD (likewise)
134+
# GIMPLE_OMP_ATOMIC_LOAD, "gimple_omp_atomic_load", GSS_OMP_ATOMIC_LOAD
135+
# gimple_statement_omp_atomic_store (GSS_OMP_ATOMIC_STORE) (ditto)
136+
# GIMPLE_OMP_ATOMIC_STORE, "gimple_omp_atomic_store", GSS_OMP_ATOMIC_STORE
137+
138+
139+
def generate_gimple_struct_subclasses():
140+
global modinit_preinit
141+
global modinit_postinit
142+
143+
for gt in gimple_struct_types:
144+
#print gimple_types
145+
cc = gt.camel_cased_string()
146+
pytype = PyTypeObject(identifier = 'gcc_GimpleStructType%sType' % cc,
147+
localname = 'GimpleStructType' + cc,
148+
tp_name = 'gcc.GimpleStructType%s' % cc,
149+
struct_name = 'struct PyGccGimple',
150+
tp_new = 'PyType_GenericNew',
151+
tp_base = '&gcc_GimpleType',
152+
#tp_getset = getsettable.identifier,
153+
#tp_repr = '(reprfunc)gcc_Gimple_repr',
154+
#tp_str = '(reprfunc)gcc_Gimple_str',
155+
)
156+
cu.add_defn(pytype.c_defn())
157+
modinit_preinit += pytype.c_invoke_type_ready()
158+
modinit_postinit += pytype.c_invoke_add_to_module()
159+
160+
#generate_gimple_struct_subclasses()
161+
162+
16163
def generate_gimple_subclasses():
17164
global modinit_preinit
18165
global modinit_postinit
@@ -36,6 +183,30 @@ def generate_gimple_subclasses():
36183

37184
generate_gimple_subclasses()
38185

186+
def generate_gimple_code_map():
187+
cu.add_defn('\n/* Map from GCC gimple codes to PyTypeObject* */\n')
188+
cu.add_defn('PyTypeObject *pytype_for_gimple_code[] = {\n')
189+
for gt in gimple_types:
190+
cc = gt.camel_cased_string()
191+
cu.add_defn(' &gcc_%sType, /* %s */\n' % (cc, gt.gimple_symbol))
192+
cu.add_defn('};\n\n')
193+
194+
cu.add_defn("""
195+
PyTypeObject*
196+
gcc_python_autogenerated_gimple_type_for_stmt(gimple g)
197+
{
198+
enum gimple_code code = gimple_code(g);
199+
200+
/* printf("code:%i\\n", code); */
201+
assert(code >= 0);
202+
assert(code < LAST_AND_UNUSED_GIMPLE_CODE);
203+
return pytype_for_gimple_code[code];
204+
}
205+
""")
206+
207+
generate_gimple_code_map()
208+
209+
39210
cu.add_defn("""
40211
int autogenerated_gimple_init_types(void)
41212
{

gimple-types.txt.in

+7
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,10 @@
22
GIMPLE_symbol, printable_name, GSS_symbol
33
#include "gimple.def"
44
#undef DEFGSCODE
5+
6+
#define DEFGSSTRUCT(GSS_enumeration_value, structure_name, has_tree_operands) \
7+
GSS_enumeration_value, structure_name, has_tree_operands
8+
#include "gsstruct.def"
9+
#undef DEFGSSTRUCT
10+
11+

maketreetypes.py

+24-2
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,34 @@ def iter_gimple_types():
3737
for line in f:
3838
# e.g.
3939
# GIMPLE_ERROR_MARK, "gimple_error_mark", GSS_BASE
40-
m = re.match('(.+), (.+), (.+)', line)
40+
m = re.match('(GIMPLE_.+), (.+), (.+)', line)
4141
if m:
4242
yield GimpleType(gimple_symbol=m.group(1),
4343
printable_name=m.group(2)[1:-1],
4444
gss_symbol=m.group(3))
4545
else:
4646
# print 'UNMATCHED: ', line
47-
assert(line.startswith('#') or line.strip() == '')
47+
assert(line.startswith('#') or line.strip() == '' or line.startswith('GSS_'))
48+
f.close()
49+
50+
51+
# Corresponds to a DEFGSTRUCT macro from gsstruct.def
52+
class GimpleStructType(namedtuple('GimpleStructType', 'enum_value struct_name has_tree_operands')):
53+
def camel_cased_string(self):
54+
return camel_case(self.struct_name)
55+
56+
def iter_gimple_struct_types():
57+
import re
58+
f = open('autogenerated-gimple-types.txt')
59+
for line in f:
60+
# e.g.
61+
# GSS_BASE, gimple_statement_base, false
62+
m = re.match('(GSS_.+), (.+), (.+)', line)
63+
if m:
64+
yield GimpleStructType(enum_value=m.group(1),
65+
struct_name=m.group(2),
66+
has_tree_operands=m.group(3))
67+
else:
68+
# print 'UNMATCHED: ', line
69+
assert(line.startswith('#') or line.strip() == '' or line.startswith('GIMPLE_'))
4870
f.close()

0 commit comments

Comments
 (0)