Commit 279822e9 authored by Moritz Kroll's avatar Moritz Kroll
Browse files

Added first version of IR importer/exporter

[r25422]
parent ebddb7c8
......@@ -116,6 +116,7 @@ extern "C" {
#include "firm_ycomp.h" /* ycomp debugging support */
#include "irdump.h"
#include "irio.h"
#include "irprintf.h"
#include "irvrfy.h"
......
/*
* Copyright (C) 1995-2008 University of Karlsruhe. All right reserved.
*
* This file is part of libFirm.
*
* This file may be distributed and/or modified under the terms of the
* GNU General Public License version 2 as published by the Free Software
* Foundation and appearing in the file LICENSE.GPL included in the
* packaging of this file.
*
* Licensees holding valid libFirm Professional Edition licenses may use
* this file in accordance with the libFirm Commercial License.
* Agreement provided with the Software.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
* WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE.
*/
/**
* @file
* @brief Import/export textual representation of firm.
* @author Moritz Kroll
* @version $Id$
*/
#ifndef FIRM_IR_IRIO_H
#define FIRM_IR_IRIO_H
#include <stdio.h>
#include "firm_types.h"
/**
* Exports the given ir graph to the given file in a textual form.
*
* @param irg the ir graph
* @param filename the name of the resulting file
*
* Exports the type graph used by the given graph and the graph itself.
*/
void ir_export_irg(ir_graph *irg, const char *filename);
/**
* Imports the data stored in the given file.
*
* @param filename the name of the file
*
* Imports any type graphs and ir graphs contained in the file.
*/
void ir_import(const char *filename);
#endif
This diff is collapsed.
#!/usr/bin/python
import sys
from jinja2 import Environment, Template
import ir_spec
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 format_ifnset(string, node, key):
if key in node:
return ""
return string
def format_block(node):
if node.get("knownBlock"):
return ""
else:
return ", get_node(env, preds[0])"
env = Environment()
env.filters['args'] = format_args
env.filters['ifnset'] = format_ifnset
env.filters['block'] = format_block
def get_io_type(type, attrname, nodename):
if type == "tarval*":
importcmd = "tarval *%s = read_tv(env);" % attrname
exportcmd = """
write_mode(env, get_tarval_mode(%(val)s));
tarval_snprintf(buf, sizeof(buf), %(val)s);
fprintf(env->file, "%%s ", buf);"""
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
exportcmd = """fprintf(env->file, "%%ld ", get_entity_nr(%(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 == "cons_flags" and nodename == "Store":
importcmd = """ir_cons_flags %s = read_pinned(env)
| read_volatility(env)
| read_align(env);""" % attrname
exportcmd = """write_pinned(env, irn);
write_volatility(env, irn);
write_align(env, irn);"""
elif type == "cons_flags" and nodename == "Load":
importcmd = """ir_cons_flags %s = read_pinned(env)
| read_volatility(env)
| read_align(env);""" % attrname
exportcmd = """write_pinned(env, irn);
write_volatility(env, irn);
write_align(env, irn);"""
else:
print "UNKNOWN TYPE: %s" % 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)
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"] = []
# construct node arguments
arguments = [ ]
i = 0
for input in node["ins"]:
arguments.append("prednodes[%i]" % i)
i += 1
if node["arity"] == "variable" or node["arity"] == "dynamic":
arguments.append("numpreds - %i" % (i + 1))
arguments.append("prednodes + %i" % i)
if "mode" not in node:
arguments.append("mode")
for attr in node["attrs"]:
prepare_attr(nodename, attr)
arguments.append(attr["name"])
for arg in node["constructor_args"]:
prepare_attr(nodename, arg)
arguments.append(arg["name"])
node["arguments"] = arguments
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 %}newnode = new_r_{{nodename}}(current_ir_graph{{node|block}}{{node["arguments"]|args}});
break;
}
''')
def main(argv):
"""the main function"""
if len(argv) < 2:
print "usage: %s destdirectory" % argv[0]
sys.exit(1)
gendir = argv[1]
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()
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.close()
if __name__ == "__main__":
main(sys.argv)
nodes = dict(
Start = dict(
mode = "mode_T",
op_flags = "cfopcode",
state = "pinned",
knownBlock = True,
noconstr = True,
),
End = dict(
mode = "mode_X",
op_flags = "cfopcode",
state = "pinned",
arity = "dynamic",
knownBlock = True,
noconstr = True,
),
Phi = dict(
noconstr = True,
state = "pinned",
arity = "variable",
),
Jmp = dict(
mode = "mode_X",
op_flags = "cfopcode",
state = "pinned",
ins = [],
),
IJmp = dict(
mode = "mode_X",
op_flags = "cfopcode",
state = "pinned",
ins = [ "target" ],
),
Const = dict(
mode = "",
knownBlock = True,
attrs = [
dict(
type = "tarval*",
name = "tarval",
)
],
),
Block = dict(
mode = "mode_BB",
knownBlock = True,
noconstr = True,
arity = "variable",
java_add = '''
public void addPred(Node node) {
binding_cons.add_immBlock_pred(ptr, node.ptr);
}
public void mature() {
binding_cons.mature_immBlock(ptr);
}
@Override
public Block getBlock() {
return null;
}
public boolean blockVisited() {
return 0 != binding.Block_block_visited(ptr);
}
public void markBlockVisited() {
binding.mark_Block_block_visited(ptr);
}''',
),
SymConst = dict(
mode = "mode_P",
knownBlock = True,
noconstr = True,
attrs = [
dict(
type = "ir_entity*",
name = "entity"
)
],
),
# SymConst
Call = dict(
ins = [ "mem", "ptr" ],
arity = "variable",
outs = [ "M_regular", "X_regular", "X_except", "T_result", "M_except", "P_value_res_base" ],
attrs = [
dict(
type = "ir_type*",
name = "type"
)
]
),
binop = dict(
abstract = True,
ins = [ "left", "right" ]
),
Add = dict(
is_a = "binop"
),
Carry = dict(
is_a = "binop"
),
Sub = dict(
is_a = "binop"
),
Borrow = dict(
is_a = "binop"
),
Mul = dict(
is_a = "binop"
),
Mulh = dict(
is_a = "binop"
),
Abs = dict(
is_a = "unop"
),
And = dict(
is_a = "binop"
),
Or = dict(
is_a = "binop"
),
Eor = dict(
is_a = "binop"
),
Not = dict(
is_a = "unop"
),
Shl = dict(
is_a = "binop"
),
Shr = dict(
is_a = "binop"
),
Shrs = dict(
is_a = "binop"
),
Rotl = dict(
is_a = "binop"
),
Load = dict(
ins = [ "mem", "ptr" ],
outs = [ "M", "X_regular", "X_except", "res" ],
attrs = [
dict(
type = "ir_mode*",
name = "mode",
java_name = "load_mode"
),
],
constructor_args = [
dict(
type = "cons_flags",
name = "flags",
),
],
),
Store = dict(
ins = [ "mem", "ptr", "value" ],
outs = [ "M", "X_regular", "X_except" ],
constructor_args = [
dict(
type = "cons_flags",
name = "flags",
),
],
),
Anchor = dict(
mode = "mode_ANY",
ins = [ "end_block", "start_block", "end", "start",
"end_reg", "end_except", "initial_exec",
"frame", "tls", "initial_mem", "args",
"bad", "no_mem" ],
knownBlock = True,
noconstr = True
),
NoMem = dict(
mode = "mode_M",
knownBlock = True,
),
Bad = dict(
mode = "mode_Bad",
knownBlock = True,
),
Pin = dict(
ins = [ "op" ],
mode = "get_irn_mode(op);"
),
Proj = dict(
ins = [ "pred" ],
attrs = [
dict(
type = "long",
name = "proj"
)
]
),
Sel = dict(
ins = [ "mem", "ptr" ],
arity = "variable",
mode = "mode_P",
attrs = [
dict(
type = "ir_entity*",
name = "entity"
)
]
),
Sync = dict(
mode = "mode_M",
arity = "dynamic"
),
Tuple = dict(
arity = "variable",
mode = "mode_T",
),
Unknown = dict(
knownBlock = True
),
Confirm = dict(
ins = [ "value", "bound" ],
block = "get_nodes_block(value)",
mode = "get_irn_mode(value)",
attrs = [
dict(
name = "cmp",
type = "pn_Cmp"
),
],
),
Return = dict(
ins = [ "mem" ],
arity = "variable",
mode = "mode_X"
),
unop = dict(
abstract = True,
ins = [ "op" ]
),
Minus = dict(
is_a = "unop"
),
Mux = dict(
ins = [ "sel", "false", "true" ]
),
Cond = dict(
ins = [ "selector" ],
outs = [ "false", "true" ],
),
Cmp = dict(
is_a = "binop",
outs = [ "False", "Eq", "Lt", "Le", "Gt", "Ge", "Lg", "Leg", "Uo", "Ue", "Ul", "Ule", "Ug", "Uge", "Ne", "True" ],
),
Conv = dict(
is_a = "unop"
),
Alloc = dict(
ins = [ "mem", "size" ],
outs = [ "M", "X_regular", "X_except", "res" ],
attrs = [
dict(
name = "type",
type = "ir_type*"
),
dict(
name = "where",
type = "ir_where_alloc"
)
]
),
Free = dict(
ins = [ "mem", "ptr", "size" ],
mode = "mode_M",
attrs = [
dict(
name = "type",
type = "ir_type*"
),
dict(
name = "where",
type = "ir_where_alloc"
)
]
),
)
# -*- coding: utf-8 -*-
"""
jinja2
~~~~~~
Jinja2 is a template engine written in pure Python. It provides a
Django inspired non-XML syntax but supports inline expressions and
an optional sandboxed environment.
Nutshell
--------
Here a small example of a Jinja2 template::
{% extends 'base.html' %}