X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=scripts%2Fgen_ir_io.py;h=acf29fbaf3f5efbced1d2db5fc9178d4b32c30b8;hb=ece3a1a6be8612fdc48f572099c32f94fdb72575;hp=10e627b068d7994b9aa52a355e32e739f12e28f6;hpb=853027b0e1c8a114bc25f5ba342ee5b652239ed6;p=libfirm diff --git a/scripts/gen_ir_io.py b/scripts/gen_ir_io.py index 10e627b06..acf29fbaf 100755 --- a/scripts/gen_ir_io.py +++ b/scripts/gen_ir_io.py @@ -1,34 +1,50 @@ #!/usr/bin/env python import sys +import re from jinja2 import Environment, Template from jinja2.filters import do_dictsort +from spec_util import is_dynamic_pinned, verify_node, isAbstract import ir_spec +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_args(arglist): - #argstrings = map(lambda arg : arg["name"], arglist) - #return ", ".join(argstrings) - s = ", ".join(arglist) - if len(s) == 0: - return ""; - return ", " + s; + return "\n".join(arglist) def format_ifnset(string, node, key): - if key in node: + if hasattr(node, key): return "" return string def format_block(node): - if node.get("knownBlock"): - return "" + if hasattr(node, "knownBlock"): + if hasattr(node, "knownGraph"): + return "" + return "current_ir_graph" else: - return ", get_node(env, preds[0])" + return "get_node(env, preds[0])" + +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) env = Environment() -env.filters['args'] = format_args -env.filters['ifnset'] = format_ifnset -env.filters['block'] = format_block +env.filters['args'] = format_args +env.filters['ifnset'] = format_ifnset +env.filters['block'] = format_block +env.filters['arguments'] = format_arguments -def get_io_type(type, attrname, nodename): +def get_io_type(type, attrname, node): if type == "tarval*": importcmd = "tarval *%s = read_tv(env);" % attrname exportcmd = "write_tarval(env, %(val)s);"; @@ -41,18 +57,18 @@ def get_io_type(type, attrname, nodename): 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": + elif type == "long" and node.name == "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": + elif type == "ir_cons_flags" and node.name == "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": + elif type == "ir_cons_flags" and node.name == "Load": importcmd = "ir_cons_flags %s = get_cons_flags(env);" % attrname exportcmd = """write_pin_state(env, irn); write_volatility(env, irn); @@ -72,131 +88,74 @@ def get_io_type(type, attrname, nodename): elif type == "int": importcmd = "int %s = (int) read_long(env);" % attrname exportcmd = """fprintf(env->file, "%%d ", %(val)s);""" + elif type == "unsigned": + importcmd = "unsigned %s = (unsigned) read_long(env);" % attrname + exportcmd = """fprintf(env->file, "%%u ", %(val)s);""" elif type == "long": importcmd = "long %s = read_long(env);" % attrname exportcmd = """fprintf(env->file, "%%ld ", %(val)s);""" else: - print "UNKNOWN TYPE: %s" % type + error("cannot generate import/export for node %s: unsupported attribute type: %s" % (node.name, type)) importcmd = """// BAD: %s %s %s %s = (%s) 0;""" % (type, attrname, 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"])} - -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"] = [] + attr["exportcmd"] = exportcmd % {"val": "get_%s_%s(irn)" % (node.name, attr["name"])} + + +def preprocess_node(node): + # dynamic pin state means, we have to im/export that + if is_dynamic_pinned(node): + newattr = dict( + name = "state", + type = "op_pin_state" + ) + if hasattr(node, "pinned_init"): + newattr["init"] = node.pinned_init + node.attrs.append(newattr) + + verify_node(node) # construct node arguments arguments = [ ] initargs = [ ] specialconstrs = [ ] i = 0 - for input in node["ins"]: + 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"]) - - if node["arity"] == "variable" or node["arity"] == "dynamic": + if node.arity == "variable" or node.arity == "dynamic": arguments.append("numpreds - %i" % (i + 1)) arguments.append("prednodes + %i" % i) - 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": - continue - prepare_attr(nodename, attr) + for attr in node.attrs: + prepare_attr(node, 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 + warning("Node type %s has an attribute with a \"special\" entry but without \"init\"" % node.name) sys.exit(1) if attrs_with_special != 0: - print "Node type %s has more than one attribute with a \"special\" entry" % nodename + warning("Node type %s has more than one attribute with a \"special\" entry" % node.name) sys.exit(1) attrs_with_special += 1 if "prefix" in attr["special"]: - specialname = attr["special"]["prefix"] + nodename + specialname = attr["special"]["prefix"] + node.name elif "suffix" in attr["special"]: - specialname = nodename + attr["special"]["suffix"] + specialname = node.name + attr["special"]["suffix"] else: - print "Unknown special constructor type for node type %s" %nodename + error("Unknown special constructor type for node type %s" % node.name) sys.exit(1) specialconstrs.append( @@ -210,21 +169,21 @@ def preprocess_node(nodename, node): if attr["type"] == "op_pin_state": initfunc = "set_irn_pinned" else: - initfunc = "set_" + nodename + "_" + attr["name"] + initfunc = "set_" + node.name + "_" + attr["name"] initargs.append((attr["name"], initfunc)) else: arguments.append(attr["name"]) - for arg in node["constructor_args"]: - prepare_attr(nodename, arg) + for arg in node.constructor_args: + prepare_attr(node, arg) arguments.append(arg["name"]) - node["arguments"] = arguments - node["initargs"] = initargs - node["special_constructors"] = specialconstrs + node.arguments = arguments + node.initargs = initargs + node.special_constructors = specialconstrs export_attrs_template = env.from_string(''' - case iro_{{nodename}}: + case iro_{{node.name}}: {{"write_mode(env, get_irn_mode(irn));"|ifnset(node,"mode")}} {% for attr in node.attrs %}{{attr.exportcmd}} {% endfor %} @@ -232,19 +191,31 @@ export_attrs_template = env.from_string(''' {% endfor %}break;''') import_attrs_template = env.from_string(''' - case iro_{{nodename}}: - { + case iro_{{node.name}}: { {{"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, initfunc) in node.initargs %}{{initfunc}}(newnode, {{initarg}}); - {% endfor %} + {% 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}}( +{%- filter arguments %} +{{node|block}} +{{node.arguments|args}} +{% endfilter %}); + else + {% endfor -%} + newnode = new_r_{{node.name}}( +{%- filter arguments %} +{{node|block}} +{{node.arguments|args}} +{% endfilter %}); + {% for (initarg, initfunc) in node.initargs %} + {{initfunc}}(newnode, {{initarg}}); + {% endfor -%} break; } ''') @@ -257,30 +228,40 @@ def main(argv): sys.exit(1) gendir = argv[2] + # these nodes don't work correctly yet for some reasons... + niynodes = [ "EndExcept", "EndReg", "ASM" ] + # these have custom im-/export code + customcode = [ "Start", "End", "Anchor", "SymConst", "Block" ] - sortednodes = do_dictsort(ir_spec.nodes) + real_nodes = [] + for node in ir_spec.nodes: + if isAbstract(node): + continue + real_nodes.append(node) file = open(gendir + "/gen_irio_export.inl", "w"); - for nodename, node in sortednodes: - preprocess_node(nodename, node) - if not "abstract" in node: - file.write(export_attrs_template.render(vars())) + for node in real_nodes: + if node.__name__ in niynodes: + continue + + preprocess_node(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 sortednodes: - 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 + for node in real_nodes: + if node.name in customcode or node.name in niynodes: + continue + file.write(import_attrs_template.render(vars())) file.write("\n") file.close() file = open(gendir + "/gen_irio_lex.inl", "w"); - for nodename, node in sortednodes: - if not "abstract" in node: - file.write("\tINSERT(\"" + nodename + "\", tt_iro, iro_" + nodename + ");\n"); + for node in real_nodes: + if node.name in niynodes: + continue + file.write("\tINSERT(tt_iro, \"%s\", iro_%s);\n" % (node.name, node.name)); file.close() -if __name__ == "__main__": - main(sys.argv) +main(sys.argv)