gen_ir_io.py 6.58 KB
Newer Older
Christoph Mallon's avatar
Christoph Mallon committed
1
#!/usr/bin/env python
2
import sys
3
import re
4
from jinja2 import Environment, Template
5
from jinja2.filters import do_dictsort
6
from spec_util import is_dynamic_pinned, verify_node, isAbstract
7
8
import ir_spec

9
10
11
12
13
14
15
16
def error(msg):
	"""writes an error message to stderr"""
	sys.stderr.write("Error: " + msg + "\n");

def warning(msg):
	"""writes a warning message to stderr"""
	sys.stderr.write("Warning: " + msg + "\n");

17
def format_args(arglist):
18
	return "\n".join(arglist)
19
20

def format_ifnset(string, node, key):
21
	if hasattr(node, key):
22
23
24
25
		return ""
	return string

def format_block(node):
26
	if hasattr(node, "knownBlock"):
27
28
		if hasattr(node, "knownGraph"):
			return ""
29
		return "irg"
30
	else:
31
		return "preds[0]"
32

33
34
35
36
37
38
39
40
def format_arguments(string):
	args = re.split('\s*\n\s*', string)
	if args[0] == '':
		args = args[1:]
	if len(args) > 0 and args[-1] == '':
		args = args[:-1]
	return ", ".join(args)

41
env = Environment()
42
43
44
45
env.filters['args']      = format_args
env.filters['ifnset']    = format_ifnset
env.filters['block']     = format_block
env.filters['arguments'] = format_arguments
46

47
def get_io_type(type, attrname, node):
Matthias Braun's avatar
Matthias Braun committed
48
49
	if type == "ir_tarval*":
		importcmd = "ir_tarval *%s = read_tv(env);" % attrname
50
		exportcmd = "write_tarval(env, %(val)s);";
51
52
53
54
55
	elif type == "ir_mode*":
		importcmd = "ir_mode *%s = read_mode(env);" % attrname
		exportcmd = "write_mode(env, %(val)s);"
	elif type == "ir_entity*":
		importcmd = "ir_entity *%s = read_entity(env);" % attrname
56
		exportcmd = "write_entity_ref(env, %(val)s);"
57
58
	elif type == "ir_type*":
		importcmd = "ir_type *%s = read_type(env);" % attrname
59
		exportcmd = "write_type_ref(env, %(val)s);"
60
	elif type == "long" and node.name == "Proj":
61
		importcmd = "long %s = read_long(env);" % attrname
62
		exportcmd = "write_long(env, %(val)s);"
63
	elif type == "ir_relation" or type == "ir_where_alloc":
64
		importcmd = "%s %s = (%s) read_long(env);" % (type, attrname, type)
65
66
67
68
69
70
71
72
		exportcmd = "write_long(env, (long) %(val)s);"
	elif type == "ir_align":
		importcmd = "ir_align %s = read_align(env);" % attrname
		exportcmd = "write_align(env, %(val)s);"
	elif type == "ir_volatility":
		importcmd = "ir_volatility %s = read_volatility(env);" % attrname
		exportcmd = "write_volatility(env, %(val)s);"
	elif type == "ir_cons_flags":
73
		importcmd = "ir_cons_flags %s = get_cons_flags(env);" % attrname
74
		exportcmd = "" # can't really export cons_flags
75
76
77
	elif type == "op_pin_state":
		importcmd = "op_pin_state %s = read_pin_state(env);" % attrname
		exportcmd = "write_pin_state(env, irn);"
78
79
80
	elif type == "ir_builtin_kind":
		importcmd = "ir_builtin_kind %s = read_builtin_kind(env);" % attrname
		exportcmd = "write_builtin_kind(env, irn);"
81
82
83
84
85
86
	elif type == "cond_kind":
		importcmd = "cond_kind %s = read_cond_kind(env);" % attrname
		exportcmd = "write_cond_kind(env, irn);"
	elif type == "cond_jmp_predicate":
		importcmd = "cond_jmp_predicate %s = read_cond_jmp_predicate(env);" % attrname
		exportcmd = "write_cond_jmp_predicate(env, irn);"
87
	elif type == "int":
88
		importcmd = "int %s = read_int(env);" % attrname
89
		exportcmd = "write_int(env, %(val)s);"
90
	elif type == "unsigned":
91
		importcmd = "unsigned %s = read_unsigned(env);" % attrname
92
		exportcmd = "write_unsigned(env, %(val)s);"
93
94
	elif type == "long":
		importcmd = "long %s = read_long(env);" % attrname
95
		exportcmd = "write_long(env, %(val)s);"
96
	else:
97
		warning("cannot generate import/export for node %s: unsupported attribute type: %s" % (node.name, type))
98
99
100
101
102
		importcmd = """// BAD: %s %s
			%s %s = (%s) 0;""" % (type, attrname, type, attrname, type)
		exportcmd = "// BAD: %s" % type
	return (importcmd, exportcmd)

103
104
def prepare_attr(node, attr):
	(importcmd,exportcmd) = get_io_type(attr["type"], attr["name"], node)
105
	attr["importcmd"] = importcmd
106
107
108
109
	attr["exportcmd"] = exportcmd % {"val": "get_%s_%s(irn)" % (node.name, attr["name"])}


def preprocess_node(node):
110
111
112
113
114
115
	# dynamic pin state means, we have to im/export that
	if is_dynamic_pinned(node):
		newattr = dict(
			name = "state",
			type = "op_pin_state"
		)
116
117
118
		if hasattr(node, "pinned_init"):
			newattr["init"] = node.pinned_init
		node.attrs.append(newattr)
119

120
	verify_node(node)
121
122
123

	# construct node arguments
	arguments = [ ]
124
	initargs = [ ]
125
	i = 1
126
	for input in node.ins:
127
		arguments.append("preds[%i]" % i)
128
129
		i += 1

130
	if node.arity == "variable" or node.arity == "dynamic":
131
132
		arguments.append("numpreds - %i" % i)
		arguments.append("preds + %i" % i)
133

134
	if not hasattr(node, "mode"):
135
136
		arguments.append("mode")

137
138
	for attr in node.attrs:
		prepare_attr(node, attr)
139
		if "init" in attr:
140
141
142
			if attr["type"] == "op_pin_state":
				initfunc = "set_irn_pinned"
			else:
143
				initfunc = "set_" + node.name + "_" + attr["name"]
144
			initargs.append((attr["name"], initfunc))
145
146
		else:
			arguments.append(attr["name"])
147

148
149
	for arg in node.constructor_args:
		prepare_attr(node, arg)
150
151
		arguments.append(arg["name"])

152
153
	node.arguments = arguments
	node.initargs = initargs
154
155

export_attrs_template = env.from_string('''
156
	case iro_{{node.name}}:
157
158
159
160
161
162
163
		{{"write_mode(env, get_irn_mode(irn));"|ifnset(node,"mode")}}
		{% for attr in node.attrs %}{{attr.exportcmd}}
		{% endfor %}
		{% for attr in node.constructor_args %}{{attr.exportcmd}}
		{% endfor %}break;''')

import_attrs_template = env.from_string('''
164
	case iro_{{node.name}}:	{
165
		{{"ir_mode *mode = read_mode(env);"|ifnset(node,"mode")}}
166
167
168
169
170
171
172
173
174
175
176
177
178
179
		{% for attr in node.attrs %}
		{{attr.importcmd}}
		{% endfor -%}
		{% for attr in node.constructor_args %}
		{{attr.importcmd}}
		{% endfor -%}
		newnode = new_r_{{node.name}}(
{%- filter arguments %}
{{node|block}}
{{node.arguments|args}}
{% endfilter %});
		{% for (initarg, initfunc) in node.initargs %}
		{{initfunc}}(newnode, {{initarg}});
		{% endfor -%}
180
181
182
183
184
185
186
		break;
	}
''')

def main(argv):
	"""the main function"""

Moritz Kroll's avatar
Moritz Kroll committed
187
188
	if len(argv) < 3:
		print "usage: %s specname(ignored) destdirectory" % argv[0]
189
190
		sys.exit(1)

Moritz Kroll's avatar
Moritz Kroll committed
191
	gendir = argv[2]
192

193
194
195
196
197
198
	real_nodes = []
	for node in ir_spec.nodes:
		if isAbstract(node):
			continue
		real_nodes.append(node)

199
	file = open(gendir + "/gen_irio_export.inl", "w");
200
	file.write("/* Warning: automatically generated code */")
201
	for node in real_nodes:
202
		if node.customSerializer:
203
204
			continue

205
206
		preprocess_node(node)
		file.write(export_attrs_template.render(vars()))
207
208
209
210
	file.write("\n")
	file.close()

	file = open(gendir + "/gen_irio_import.inl", "w");
211
	file.write("/* Warning: automatically generated code */")
212
	for node in real_nodes:
213
		if node.customSerializer:
214
215
			continue
		file.write(import_attrs_template.render(vars()))
216
217
218
219
	file.write("\n")
	file.close()

	file = open(gendir + "/gen_irio_lex.inl", "w");
220
	file.write("/* Warning: automatically generated code */")
221
	for node in real_nodes:
222
		file.write("\tINSERT(tt_iro, \"%s\", iro_%s);\n" % (node.name, node.name));
223
224
	file.close()

225
main(sys.argv)