X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=scripts%2Fgen_ir_io.py;h=2deead73df8d1d26f0807d58c8e6953a770c3ae7;hb=9d3c8631459f431c313160dab5778e8a7b88dd92;hp=58100c99de3cc238f8fb9a2c2cc2f5ed7f47d94a;hpb=a3f5aabc950cc57f38a5b3060984ae29d77d28e4;p=libfirm diff --git a/scripts/gen_ir_io.py b/scripts/gen_ir_io.py index 58100c99d..2deead73d 100755 --- a/scripts/gen_ir_io.py +++ b/scripts/gen_ir_io.py @@ -1,37 +1,52 @@ #!/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 +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): - if type == "tarval*": - importcmd = "tarval *%s = read_tv(env);" % attrname +def get_io_type(type, attrname, node): + if type == "ir_tarval*": + importcmd = "ir_tarval *%s = read_tv(env);" % attrname exportcmd = "write_tarval(env, %(val)s);"; elif type == "ir_mode*": importcmd = "ir_mode *%s = read_mode(env);" % attrname @@ -42,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); @@ -73,48 +88,35 @@ 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 + warning("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) -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"] = [] - if "pinned" not in node: - node["pinned"] = "no" + 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 "pinned_init" in node: - newattr["init"] = node["pinned_init"] - node["attrs"].append(newattr) + if hasattr(node, "pinned_init"): + newattr["init"] = node.pinned_init + node.attrs.append(newattr) verify_node(node) @@ -123,37 +125,37 @@ def preprocess_node(nodename, node): initargs = [ ] specialconstrs = [ ] i = 0 - for input in node["ins"]: + for input in node.ins: arguments.append("prednodes[%i]" % i) i += 1 - 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"]: - 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( @@ -167,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 %} @@ -189,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; } ''') @@ -214,36 +228,40 @@ def main(argv): sys.exit(1) gendir = argv[2] - sortednodes = do_dictsort(ir_spec.nodes) # these nodes don't work correctly yet for some reasons... - niynodes = [ "EndExcept", "EndReg", "ASM" ] + niynodes = [ "ASM" ] # these have custom im-/export code - customcode = [ "Start", "End", "Anchor", "SymConst", "Block" ] + customcode = [ "Start", "End", "Anchor", "SymConst", "Block", "Deleted" ] + + 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: - if nodename in niynodes: + for node in real_nodes: + if node.__name__ in niynodes: continue - preprocess_node(nodename, node) - if "abstract" not in node: - file.write(export_attrs_template.render(vars())) + 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 "abstract" in node or nodename in customcode or nodename in niynodes: + 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 "abstract" not in node and nodename not in niynodes: - 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)