Commit 14e24f75 authored by Moritz Kroll's avatar Moritz Kroll
Browse files

Started Python implementation of gen_ir.pl

[r25753]
parent 15d18ec0
#!/usr/bin/env python
import sys
from jinja2 import Environment, Template
from jinja2.filters import do_dictsort
import ir_spec
def format_argdecls(node, first = False):
if not node.has_key("args"):
return ""
res = ""
if not first:
comma = ", "
else:
comma = ""
for arg in node["args"]:
res = res + (comma + arg["type"] + " " + arg["name"])
comma = ", "
return res
def format_args(node):
if not node.has_key("args"):
return ""
res = ""
for arg in node["args"]:
res = res + (", " + arg["name"])
return res
def format_blockdecl(node):
if node.get("knownBlock"):
return ""
else:
return ", ir_node *block"
def format_block(node):
if node.get("knownBlock"):
return ""
else:
return ", block"
def format_curblock(node):
if node.get("knownBlock"):
return ""
else:
return ", current_ir_graph->current_block"
def format_insdecl(node):
arity = node["arity"]
if arity == "variable" and len(node["ins"]) == 0 or arity == "dynamic" or arity == 0:
return ""
if arity == "variable":
insarity = len(node["ins"])
res = "int r_arity = arity + " + `insarity` + ";\n\tir_node **r_in;\n\t" \
+ "NEW_ARR_A(ir_node *, r_in, r_arity);\n\t"
i = 0
for input in node["ins"]:
res += "r_in[" + `i` + "] = irn_" + input + ";\n\t"
i += 1
res += "memcpy(&r_in[" + `insarity` + "], in, sizeof(ir_node *) * arity);\n\t"
else:
res = "ir_node *in[" + `arity` + "];\n\t"
i = 0
for input in node["ins"]:
res += "in[" + `i` + "] = irn_" + input + ";\n\t"
i += 1
return res
def format_arity_and_ins(node):
arity = node["arity"]
if arity == "dynamic":
return "-1, NULL"
elif arity == "variable":
if len(node["ins"]) == 0:
return "arity, in"
else:
return "r_arity, r_in"
elif arity == 0:
return "0, NULL"
else:
return `arity` + ", in"
env = Environment()
env.filters['argdecls'] = format_argdecls
env.filters['args'] = format_args
env.filters['blockdecl'] = format_blockdecl
env.filters['block'] = format_block
env.filters['curblock'] = format_curblock
env.filters['insdecl'] = format_insdecl
env.filters['arity_and_ins'] = format_arity_and_ins
def add_attr(list, type, name, init = None, initname = None):
if initname == None:
initname = "." + name
if init != None:
list.append(dict(type = type, name = name, init = init, initname = initname))
else:
list.append(dict(type = type, name = name, initname = initname))
def prepare_attr(attr):
if "init" in attr:
return dict(type = attr["type"], name = attr["name"], init = attr["init"])
else:
return dict(type = attr["type"], name = attr["name"])
def preprocess_node(nodename, node):
print "nodename: " + nodename
if "is_a" in node:
parent = ir_spec.nodes[node["is_a"]]
node["ins"] = parent["ins"]
if "outs" in parent:
node["outs"] = parent["outs"]
if "ins" not in node:
node["ins"] = []
if "outs" in node:
node["mode"] = "mode_T"
if "arity" not in node:
node["arity"] = len(node["ins"])
if "attrs" not in node:
node["attrs"] = []
if "constructor_args" not in node:
node["constructor_args"] = []
if "attrs_name" not in node:
node["attrs_name"] = nodename.lower()
if "block" not in node:
node["block"] = "block"
if "nodbginfo" in node:
node["db"] = "NULL"
node["dbdecl"] = ""
node["dbdeclnocomma"] = ""
else:
node["db"] = "db"
node["dbdecl"] = "dbg_info *db, "
node["dbdeclnocomma"] = "dbg_info *db"
# construct node arguments
arguments = [ ]
initargs = [ ]
initattrs = [ ]
specialconstrs = [ ]
i = 0
for input in node["ins"]:
print "ins: " + input
arguments.append(dict(type = "ir_node *", name = "irn_" + input))
i += 1
# Special case for Builtin...
if nodename == "Builtin":
for attr in node["attrs"]:
if attr["name"] == "kind":
arguments.append(prepare_attr(attr))
if node["arity"] == "variable":
arguments.append(dict(type = "int", name = "arity"))
arguments.append(dict(type = "ir_node **", name = "in"))
if "mode" not in node:
arguments.append(dict(type = "ir_mode *", name = "mode"))
node["mode"] = "mode"
attrs_with_special = 0
for attr in node["attrs"]:
print "attr: " + attr["name"]
if nodename == "Builtin" and attr["name"] == "kind":
continue
if "initname" not in attr:
attr["initname"] = "." + attr["name"]
# "special" stuff does not work at all, yet
if "special" in attr:
if not "init" in attr:
print "Node type %s has an attribute with a \"special\" entry but without \"init\"" % nodename
sys.exit(1)
if attrs_with_special != 0:
print "Node type %s has more than one attribute with a \"special\" entry" % nodename
sys.exit(1)
attrs_with_special += 1
if "prefix" in attr["special"]:
specialname = attr["special"]["prefix"] + nodename
elif "suffix" in attr["special"]:
specialname = nodename + attr["special"]["suffix"]
else:
print "Unknown special constructor type for node type %s" %nodename
sys.exit(1)
specialconstrs.append(
dict(
constrname = specialname,
attrname = attr["name"],
value = attr["special"]["init"]
)
)
elif "init" in attr:
initargs.append(attr["name"])
else:
arguments.append(prepare_attr(attr))
for arg in node["constructor_args"]:
arguments.append(prepare_attr(arg))
if arg["type"] == "ir_cons_flags":
name = arg["name"]
initattrs.append(dict(initname = ".exc.pin_state",
init = name + " & cons_floats ? op_pin_state_floats : op_pin_state_pinned"))
initattrs.append(dict(initname = ".volatility",
init = name + " & cons_volatile ? volatility_is_volatile : volatility_non_volatile"))
initattrs.append(dict(initname = ".aligned",
init = name + " & cons_unaligned ? align_non_aligned : align_is_aligned"))
node["args"] = arguments
node["initargs"] = initargs
node["initattrs"] = initattrs
node["special_constructors"] = specialconstrs
#############################
node_template = env.from_string('''
ir_node *new_rd_{{nodename}}({{node["dbdecl"]}}ir_graph *irg{{node|blockdecl}}{{node|argdecls}})
{
ir_node *res;
ir_graph *rem = current_ir_graph;
{{node|insdecl}}
current_ir_graph = irg;
res = new_ir_node({{node["db"]}}, irg, {{node["block"]}}, op_{{nodename}}, {{node["mode"]}}, {{node|arity_and_ins}});
{% for attr in node["attrs"] -%}
res->attr.{{node["attrs_name"]}}{{attr["initname"]}} =
{%- if "init" in attr %} {{ attr["init"] -}};
{%- else %} {{ attr["name"] -}};
{% endif %}
{% endfor %}
{%- for attr in node["initattrs"] -%}
res->attr.{{node["attrs_name"]}}{{attr["initname"]}} = {{ attr["init"] -}};
{% endfor %}
{{- node["init"] }}
{% if node["optimize"] != False -%}
res = optimize_node(res);
{% endif -%}
IRN_VRFY_IRG(res, irg);
current_ir_graph = rem;
return res;
}
ir_node *new_r_{{nodename}}(ir_graph *irg{{node|blockdecl}}{{node|argdecls}})
{
{% if node["nodbginfo"] -%}
return new_rd_{{nodename}}(irg{{node|block}}{{node|args}});
{%- else -%}
return new_rd_{{nodename}}(NULL, irg{{node|block}}{{node|args}});
{%- endif %}
}
ir_node *new_d_{{nodename}}({{node["dbdeclnocomma"]}}{{node|argdecls(node["nodbginfo"])}})
{
ir_node *res;
{{ node["d_pre"] }}
{% if node["nodbginfo"] -%}
res = new_rd_{{nodename}}(current_ir_graph{{node|curblock}}{{node|args}});
{%- else -%}
res = new_rd_{{nodename}}(db, current_ir_graph{{node|curblock}}{{node|args}});
{%- endif %}
{{ node["d_post"] }}
return res;
}
''')
#############################
def main(argv):
"""the main function"""
if len(argv) < 3:
print "usage: %s specname(ignored) destdirectory" % argv[0]
sys.exit(1)
gendir = argv[2]
# List of TODOs
niymap = ["Alloc", "Anchor", "ASM", "Bad", "Bound", "Break", "Builtin",
"Call", "CallBegin", "Cast", "Const", "Const_type", "Const_long", "CopyB",
"defaultProj", "Div", "DivRL", "DivMod", "EndReg", "EndExcept",
"Filter", "InstOf", "Mod", "NoMem", "Phi", "Quot", "Raise",
"simpleSel", "strictConv", "SymConst", "SymConst_type", "Sync"]
file = open(gendir + "/gen_ir_cons_py.c.inl", "w")
for nodename, node in do_dictsort(ir_spec.nodes):
if nodename in niymap:
continue
preprocess_node(nodename, node)
if not "abstract" in node:
file.write(node_template.render(vars()))
file.write("\n")
file.close()
if __name__ == "__main__":
main(sys.argv)
......@@ -16,6 +16,10 @@ End = dict(
optimize = False
),
Id = dict(
ins = [ "pred" ]
),
Phi = dict(
noconstr = True,
state = "pinned",
......@@ -49,8 +53,9 @@ Const = dict(
),
Block = dict(
mode = "mode_BB",
mode = "mode_BB",
knownBlock = True,
block = "NULL",
noconstr = True,
optimize = False,
arity = "variable",
......@@ -74,6 +79,30 @@ Block = dict(
set_Block_block_visited(res, 0);
''',
d_pre = '''
int i;
int has_unknown = 0;
''',
d_post = '''
/* Create and initialize array for Phi-node construction. */
if (get_irg_phase_state(current_ir_graph) == phase_building) {
res->attr.block.graph_arr = NEW_ARR_D(ir_node *, current_ir_graph->obst,
current_ir_graph->n_loc);
memset(res->attr.block.graph_arr, 0, sizeof(ir_node *)*current_ir_graph->n_loc);
}
for (i = arity - 1; i >= 0; i--)
if (is_Unknown(in[i])) {
has_unknown = 1;
break;
}
if (!has_unknown) res = optimize_node(res);
IRN_VRFY_IRG(res, current_ir_graph);
''',
java_add = '''
public void addPred(Node node) {
binding_cons.add_immBlock_pred(ptr, node.ptr);
......@@ -289,6 +318,11 @@ Load = dict(
name = "flags",
),
],
d_post = '''
#if PRECISE_EXC_CONTEXT
firm_alloc_frag_arr(res, op_Load, &res->attr.load.exc.frag_arr);
#endif
'''
),
Store = dict(
......@@ -300,6 +334,11 @@ Store = dict(
name = "flags",
),
],
d_post = '''
#if PRECISE_EXC_CONTEXT
firm_alloc_frag_arr(res, op_Store, &res->attr.store.exc.frag_arr);
#endif
'''
),
Anchor = dict(
......@@ -324,7 +363,7 @@ Bad = dict(
Pin = dict(
ins = [ "op" ],
mode = "get_irn_mode(op);"
mode = "get_irn_mode(irn_op)"
),
Proj = dict(
......@@ -332,7 +371,8 @@ Proj = dict(
attrs = [
dict(
type = "long",
name = "proj"
name = "proj",
initname = ""
)
]
),
......@@ -340,7 +380,7 @@ Proj = dict(
Sel = dict(
ins = [ "mem", "ptr" ],
arity = "variable",
mode = "mode_P",
mode = "is_Method_type(get_entity_type(entity)) ? mode_P_code : mode_P_data",
attrs = [
dict(
type = "ir_entity*",
......@@ -361,12 +401,14 @@ Tuple = dict(
),
Unknown = dict(
knownBlock = True
knownBlock = True,
block = "get_irg_start_block(irg)",
nodbginfo = True
),
Confirm = dict(
ins = [ "value", "bound" ],
mode = "get_irn_mode(value)",
mode = "get_irn_mode(irn_value)",
attrs = [
dict(
name = "cmp",
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment