X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=scripts%2Fgen_ir_io.py;h=2a7d64192c9faea308a5839d7a5d32bbbfea7da3;hb=8205228fcd3fd0e1dec436e1650cf09720bd6503;hp=d9a77ef4a2a058a645c70ee4f44f2df9d616ae91;hpb=ce3205fbd27a87a89eeaf9980b364cc1f92226fc;p=libfirm diff --git a/scripts/gen_ir_io.py b/scripts/gen_ir_io.py index d9a77ef4a..2a7d64192 100755 --- a/scripts/gen_ir_io.py +++ b/scripts/gen_ir_io.py @@ -1,279 +1,275 @@ #!/usr/bin/env python import sys from jinja2 import Environment, Template -import ir_spec +from spec_util import is_dynamic_pinned, isAbstract, load_spec +from filters import format_arguments, filter_isnot, filter_hasnot, filter_notset -def format_args(arglist): - #argstrings = map(lambda arg : arg["name"], arglist) - #return ", ".join(argstrings) - s = ", ".join(arglist) - if len(s) == 0: - return ""; - return ", " + s; +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"); -def format_ifnset(string, node, key): - if key in node: - return "" - return string +def format_args(arglist): + return "\n".join(arglist) def format_block(node): - if node.get("knownBlock"): - return "" + if hasattr(node, "knownBlock"): + if hasattr(node, "knownGraph"): + return "" + return "env->irg" else: - return ", get_node(env, preds[0])" + return "block" env = Environment() -env.filters['args'] = format_args -env.filters['ifnset'] = format_ifnset -env.filters['block'] = format_block +env.filters['args'] = format_args +env.filters['block'] = format_block +env.filters['arguments'] = format_arguments +env.filters['isnot'] = filter_isnot +env.filters['notset'] = filter_notset +env.filters['hasnot'] = filter_hasnot -def get_io_type(type, attrname, nodename): - if type == "tarval*": - importcmd = "tarval *%s = read_tv(env);" % attrname - exportcmd = "write_tarval(env, %(val)s);"; +def get_io_type(type, attrname, node): + if type == "ir_tarval*": + importcmd = "read_tarval(env)" + exportcmd = "write_tarval(env, %(val)s);" elif type == "ir_mode*": - importcmd = "ir_mode *%s = read_mode(env);" % attrname - exportcmd = "write_mode(env, %(val)s);" + importcmd = "read_mode_ref(env)" + exportcmd = "write_mode_ref(env, %(val)s);" elif type == "ir_entity*": - importcmd = "ir_entity *%s = read_entity(env);" % attrname - exportcmd = """fprintf(env->file, "%%ld ", get_entity_nr(%(val)s));""" + importcmd = "read_entity_ref(env)" + exportcmd = "write_entity_ref(env, %(val)s);" elif type == "ir_type*": - importcmd = "ir_type *%s = read_type(env);" % attrname - exportcmd = """fprintf(env->file, "%%ld ", get_type_nr(%(val)s));""" - elif type == "long" and nodename == "Proj": - importcmd = "long %s = read_long(env);" % attrname - exportcmd = """fprintf(env->file, "%%ld ", %(val)s);""" - elif type == "pn_Cmp" or type == "ir_where_alloc": - importcmd = "%s %s = (%s) read_long(env);" % (type, attrname, type) - exportcmd = """fprintf(env->file, "%%ld ", (long) %(val)s);""" - elif type == "ir_cons_flags" and nodename == "Store": - importcmd = "ir_cons_flags %s = get_cons_flags(env);" % attrname - exportcmd = """write_pin_state(env, irn); - write_volatility(env, irn); - write_align(env, irn);""" - elif type == "ir_cons_flags" and nodename == "Load": - importcmd = "ir_cons_flags %s = get_cons_flags(env);" % attrname - exportcmd = """write_pin_state(env, irn); - write_volatility(env, irn); - write_align(env, irn);""" + importcmd = "read_type_ref(env)" + exportcmd = "write_type_ref(env, %(val)s);" + elif type == "long": + importcmd = "read_long(env)" + exportcmd = "write_long(env, %(val)s);" + elif type == "ir_relation": + importcmd = "read_relation(env)" + exportcmd = "write_relation(env, %(val)s);" + elif type == "ir_where_alloc": + importcmd = "read_where_alloc(env)" + exportcmd = "write_where_alloc(env, %(val)s);" + elif type == "ir_align": + importcmd = "read_align(env)" + exportcmd = "write_align(env, %(val)s);" + elif type == "ir_volatility": + importcmd = "read_volatility(env)" + exportcmd = "write_volatility(env, %(val)s);" + elif type == "ir_cons_flags": + importcmd = "cons_none" + exportcmd = "" # can't really export cons_flags elif type == "op_pin_state": - importcmd = "op_pin_state %s = read_pin_state(env);" % attrname - exportcmd = "write_pin_state(env, irn);" + importcmd = "read_pin_state(env)" + exportcmd = "write_pin_state(env, node);" elif type == "ir_builtin_kind": - importcmd = "ir_builtin_kind %s = read_builtin_kind(env);" % attrname - exportcmd = "write_builtin_kind(env, irn);" + importcmd = "read_builtin_kind(env)" + exportcmd = "write_builtin_kind(env, node);" elif type == "cond_kind": - importcmd = "cond_kind %s = read_cond_kind(env);" % attrname - exportcmd = "write_cond_kind(env, irn);" + importcmd = "read_cond_kind(env)" + exportcmd = "write_cond_kind(env, node);" elif type == "cond_jmp_predicate": - importcmd = "cond_jmp_predicate %s = read_cond_jmp_predicate(env);" % attrname - exportcmd = "write_cond_jmp_predicate(env, irn);" + importcmd = "read_cond_jmp_predicate(env)" + exportcmd = "write_cond_jmp_predicate(env, node);" elif type == "int": - importcmd = "int %s = (int) read_long(env);" % attrname - exportcmd = """fprintf(env->file, "%%d ", %(val)s);""" + importcmd = "read_int(env)" + exportcmd = "write_int(env, %(val)s);" + elif type == "unsigned": + importcmd = "read_unsigned(env)" + exportcmd = "write_unsigned(env, %(val)s);" elif type == "long": - importcmd = "long %s = read_long(env);" % attrname - exportcmd = """fprintf(env->file, "%%ld ", %(val)s);""" + importcmd = "read_long(env)" + exportcmd = "write_long(env, %(val)s);" + elif type == "ir_switch_table*": + importcmd = "read_switch_table(env)" + exportcmd = "write_switch_table(env, %(val)s);" else: - print "UNKNOWN TYPE: %s" % type - importcmd = """// BAD: %s %s - %s %s = (%s) 0;""" % (type, attrname, type, attrname, type) + warning("cannot generate import/export for node %s: unsupported attribute type: %s" % (node.name, type)) + importcmd = "/* BAD: %s %s */ (%s)0" % (type, attrname, type) exportcmd = "// BAD: %s" % type return (importcmd, exportcmd) -""" if type == "ir_type*": - java_type = "firm.Type" - wrap_type = "Pointer" - to_wrapper = "%s.ptr" - from_wrapper = "firm.Type.createWrapper(%s)" - elif type == "ir_mode*": - java_type = "firm.Mode" - wrap_type = "Pointer" - to_wrapper = "%s.ptr" - from_wrapper = "new firm.Mode(%s)" - elif type == "tarval*": - java_type = "firm.TargetValue" - wrap_type = "Pointer" - to_wrapper = "%s.ptr" - from_wrapper = "new firm.TargetValue(%s)" - elif type == "pn_Cmp": - java_type = "int" - wrap_type = "int" - to_wrapper = "%s" - from_wrapper = "%s" - elif type == "long": - java_type = "int" - wrap_type = "com.sun.jna.NativeLong" - to_wrapper = "new com.sun.jna.NativeLong(%s)" - from_wrapper = "%s.intValue()" - elif type == "cons_flags": - java_type = "firm.bindings.binding_ircons.ir_cons_flags" - wrap_type = "int" - to_wrapper = "%s.val" - from_wrapper = "firm.bindings.binding_ircons.ir_cons_flags.getEnum(%s)" - elif type == "ir_where_alloc": - java_type = "firm.bindings.binding_ircons.ir_where_alloc" - wrap_type = "int" - to_wrapper = "%s.val" - from_wrapper = "firm.bindings.binding_ircons.ir_where_alloc.getEnum(%s)" - elif type == "ir_entity*": - java_type = "firm.Entity" - wrap_type = "Pointer" - to_wrapper = "%s.ptr" - from_wrapper = "new firm.Entity(%s)" - else: - print "UNKNOWN TYPE" - java_type = "BAD" - wrap_type = "BAD" - to_wrapper = "BAD" - from_wrapper = "BAD" - return (java_type,wrap_type,to_wrapper,from_wrapper)""" - -def prepare_attr(nodename, attr): - (importcmd,exportcmd) = get_io_type(attr["type"], attr["name"], nodename) +def prepare_attr(node, attr): + (importcmd,exportcmd) = get_io_type(attr["type"], attr["name"], node) attr["importcmd"] = importcmd - attr["exportcmd"] = exportcmd % {"val": "get_%s_%s(irn)" % (nodename, attr["name"])} + attr["exportcmd"] = exportcmd % {"val": "get_%s_%s(node)" % (node.name, attr["name"])} + -def preprocess_node(nodename, node): - 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"] = [] +def preprocess_node(node): + if node.customSerializer: + return # construct node arguments arguments = [ ] - initargs = [ ] - specialconstrs = [ ] - i = 0 - for input in node["ins"]: - arguments.append("prednodes[%i]" % i) - i += 1 - - # Special case for Builtin... - if nodename == "Builtin": - for attr in node["attrs"]: - if attr["name"] == "kind": - prepare_attr(nodename, attr) - arguments.append(attr["name"]) + extraattrs = [ ] + for input in node.ins: + arguments.append("in_%s" % input[0]) - if node["arity"] == "variable" or node["arity"] == "dynamic": - arguments.append("numpreds - %i" % (i + 1)) - arguments.append("prednodes + %i" % i) + if node.arity == "variable" or node.arity == "dynamic": + arguments.append("n_preds") + arguments.append("preds") - if "mode" not in node: + if not hasattr(node, "mode"): arguments.append("mode") - attrs_with_special = 0 - for attr in node["attrs"]: - if nodename == "Builtin" and attr["name"] == "kind": + for attr in node.attrs: + prepare_attr(node, attr) + if "to_flags" in attr: + node.constructorFlags = True + attr['to_flags'] = attr['to_flags'] % (attr["name"]) + elif "init" in attr: + extraattrs.append(attr) + else: + arguments.append(attr["name"]) + + for arg in node.constructor_args: + if arg['type'] != "ir_cons_flags" and arg['name'] != "flags": + error("only ir_cons_flags constructor arg supported in irio") continue - prepare_attr(nodename, attr) - 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) + node.constructorFlags = True + arguments.append("flags") - if attrs_with_special != 0: - print "Node type %s has more than one attribute with a \"special\" entry" % nodename - sys.exit(1) + node.arguments = arguments + node.extraattrs = extraattrs + node.dynamic_pinned = is_dynamic_pinned(node) - attrs_with_special += 1 +io_template = env.from_string('''/* Warning: automatically generated code */ +{%- for node in nodes|notset('customSerializer') %} +static ir_node *read_{{node.name}}(read_env_t *env) +{ + {%- if not node.knownBlock %} + ir_node *block = read_node_ref(env); + {%- endif %} + {%- for input in node.ins %} + ir_node *in_{{input[0]}} = read_node_ref(env); + {%- endfor %} + {%- if not hasattr(node, "mode") %} + ir_mode *mode = read_mode_ref(env); + {%- endif %} + {%- for attr in node.attrs %} + {{attr.type}} {{attr.name}} = {{attr.importcmd}}; + {%- endfor %} + {%- if node.dynamic_pinned %} + op_pin_state pin_state = read_pin_state(env); + {%- endif %} + {%- if "fragile" in node.flags %} + bool throws = read_throws(env); + {%- endif %} + {%- if node.arity == "dynamic" or node.arity == "variable" %} + int n_preds = read_preds(env); + ir_node **preds = (ir_node**)obstack_finish(&env->preds_obst); + {%- endif %} + {%- if node.constructorFlags %} + ir_cons_flags flags = cons_none; + {%- endif %} + ir_node *res; + {%- if node.constructorFlags %} + {%- for attr in node.attrs %} + {%- if "to_flags" in attr %} + flags |= {{attr.to_flags}}; + {%- endif %} + {%- endfor %} + {%- if node.dynamic_pinned %} + flags |= pin_state == op_pin_state_floats ? cons_floats : cons_none; + {%- endif %} + {%- if "fragile" in node.flags %} + flags |= throws ? cons_throws_exception : cons_none; + {%- endif %} + {%- endif %} + res = new_r_{{node.name}}( + {%- filter arguments %} +{{node|block}} +{{node.arguments|args}} + {%- if node.dynamic_pinned and not hasattr(node, "pinned_init") %} +pin_state + {%- endif %} +{% endfilter %}); - 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) + {%- if node.arity == "dynamic" or node.arity == "variable" %} + obstack_free(&env->preds_obst, preds); + {%- endif %} + {%- for attr in node.extraattrs %} + set_{{node.name}}_{{attr.name}}(res, {{attr.name}}); + {%- endfor %} + {%- if not node.constructorFlags %} + {%- if node.dynamic_pinned and hasattr(node, "pinned_init") %} + set_irn_pinned(res, pin_state); + {%- endif %} + {%- if "fragile" in node.flags and hasattr(node, "throws_init") %} + ir_set_throws_exception(res, throws); + {%- endif %} + {%- endif %} + return res; +} +{% endfor %} - specialconstrs.append( - dict( - constrname = specialname, - attrname = attr["name"], - value = attr["special"]["init"] - ) - ) - elif "init" in attr: - initargs.append(attr["name"]) - else: - arguments.append(attr["name"]) +{%- for node in nodes|notset('customSerializer') %} +static void write_{{node.name}}(write_env_t *env, const ir_node *node) +{ + write_symbol(env, "{{node.name}}"); + write_node_nr(env, node); + {%- if not node.knownBlock %} + write_node_ref(env, get_nodes_block(node)); + {%- endif %} + {%- for input in node.ins %} + write_node_ref(env, get_{{node.name}}_{{input[0]}}(node)); + {%- endfor %} + {%- if not hasattr(node, "mode") %} + write_mode_ref(env, get_irn_mode(node)); + {%- endif %} + {%- for attr in node.attrs %} + {{attr.exportcmd}} + {%- endfor %} + {%- if node.dynamic_pinned %} + write_pin_state(env, get_irn_pinned(node)); + {%- endif %} + {%- if "fragile" in node.flags %} + write_throws(env, ir_throws_exception(node)); + {%- endif %} + {%- if node.arity == "dynamic" or node.arity == "variable" %} + write_pred_refs(env, node, {% if node.ins %}n_{{node.name}}_max+1{% else %}0{%endif%}); + {%- endif %} +} +{% endfor %} - for arg in node["constructor_args"]: - prepare_attr(nodename, arg) - arguments.append(arg["name"]) +static void register_generated_node_readers(void) +{ + {%- for node in nodes|notset('customSerializer') %} + register_node_reader(new_id_from_str("{{node.name}}"), read_{{node.name}}); + {%- endfor %} +} - node["arguments"] = arguments - node["initargs"] = initargs - node["special_constructors"] = specialconstrs +static void register_generated_node_writers(void) +{ + {%- for node in nodes|notset('customSerializer') %} + register_node_writer(op_{{node.name}}, write_{{node.name}}); + {%- endfor %} +} -export_attrs_template = env.from_string(''' - case iro_{{nodename}}: - {{"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(''' - case iro_{{nodename}}: - { - {{"ir_mode *mode = read_mode(env);"|ifnset(node,"mode")}} - {% for attr in node.attrs %}{{attr.importcmd}} - {% endfor %} - {% for attr in node.constructor_args %}{{attr.importcmd}} - {% endfor %} - {% for special in node.special_constructors %}if({{special.attrname}} == {{special.value}}) - newnode = new_r_{{special.constrname}}(current_ir_graph{{node|block}}{{node["arguments"]|args}}); - else{% endfor %} - newnode = new_r_{{nodename}}(current_ir_graph{{node|block}}{{node["arguments"]|args}}); - {% for initarg in node.initargs %}set_{{nodename}}_{{initarg}}(newnode, {{initarg}}); - {% endfor %} - break; - } ''') def main(argv): - """the main function""" - if len(argv) < 3: print "usage: %s specname(ignored) destdirectory" % argv[0] sys.exit(1) + specfile = argv[1] gendir = argv[2] - file = open(gendir + "/gen_irio_export.inl", "w"); - for nodename, node in ir_spec.nodes.iteritems(): - preprocess_node(nodename, node) - if not "abstract" in node: - file.write(export_attrs_template.render(vars())) - file.write("\n") - file.close() - - file = open(gendir + "/gen_irio_import.inl", "w"); - for nodename, node in ir_spec.nodes.iteritems(): - if not "abstract" in node and nodename != "Start" and nodename != "End" and nodename != "Anchor" and nodename != "SymConst" and nodename != "Block": - file.write(import_attrs_template.render(vars())) - # TODO: SymConst - file.write("\n") - file.close() + spec = load_spec(specfile) + nodes = spec.nodes + real_nodes = [] + for node in nodes: + if isAbstract(node): + continue + preprocess_node(node) + real_nodes.append(node) - file = open(gendir + "/gen_irio_lex.inl", "w"); - for nodename, node in ir_spec.nodes.iteritems(): - if not "abstract" in node: - file.write("\tINSERT(\"" + nodename + "\", tt_iro, iro_" + nodename + ");\n"); + file = open(gendir + "/gen_irio.inl", "w"); + file.write(io_template.render(nodes = real_nodes, hasattr=hasattr)) file.close() -if __name__ == "__main__": - main(sys.argv) +main(sys.argv)