Commit 5ea4510c authored by Matthias Braun's avatar Matthias Braun
Browse files

cleanup spec by introducing new Attribute object

parent 679c7573
......@@ -12,14 +12,8 @@ def format_arguments(string, voidwhenempty = False):
return "void"
return ", ".join(args)
def filter_isnot(list, flag):
return filter(lambda x: not hasattr(x, flag), list)
def filter_hasnot(list, flag):
return filter(lambda x: flag not in x, list)
return filter(lambda x: not hasattr(x, flag) or not getattr(x, flag), list)
def filter_has(list, flag):
return filter(lambda x: flag in x, list)
def filter_notset(list, flag):
return filter(lambda x: not getattr(x,flag), list)
return filter(lambda x: hasattr(x, flag) and getattr(x, flag), list)
......@@ -4,24 +4,24 @@
# Copyright (C) 2012 Karlsruhe Institute of Technology.
import sys
from jinja2 import Environment, Template, FileSystemLoader
from spec_util import is_dynamic_pinned, isAbstract, setdefault, load_spec
from filters import format_arguments, filter_isnot, filter_has, filter_hasnot, filter_notset
from spec_util import is_dynamic_pinned, isAbstract, setdefault, load_spec, Attribute
from filters import format_arguments, filter_has, filter_hasnot
def format_parameterlist(parameterlist):
return "\n".join(parameterlist)
def format_nodearguments(node):
arguments = map(lambda arg: arg["name"], node.arguments)
arguments = [arg.name for arg in node.arguments]
return format_parameterlist(arguments)
def format_nodeparameters(node):
parameters = map(lambda arg: arg["type"] + " " + arg["name"], node.arguments)
parameters = ["%s %s" % (arg.type, arg.name) for arg in node.arguments]
return format_parameterlist(parameters)
def format_nodeparametershelp(node):
res = ""
for param in node.arguments:
res += " * @param %-9s %s\n" % (param["name"], param["comment"])
res += " * @param %-9s %s\n" % (param.name, param.comment)
return res
def format_a_an(text):
......@@ -156,7 +156,7 @@ def format_parameters(string):
return format_arguments(string, voidwhenempty = True)
def format_args(arglist):
argument_names = [ a['name'] for a in arglist ]
argument_names = [ arg.name for arg in arglist ]
return "\n".join(argument_names)
def format_block(node):
......@@ -194,11 +194,9 @@ env.filters['has'] = filter_has
env.filters['hasnot'] = filter_hasnot
env.filters['insdecl'] = format_insdecl
env.filters['irgassign'] = format_irgassign
env.filters['isnot'] = filter_isnot
env.filters['nodearguments'] = format_nodearguments
env.filters['nodeparameters'] = format_nodeparameters
env.filters['nodeparametershelp'] = format_nodeparametershelp
env.filters['notset'] = filter_notset
env.filters['opindex'] = format_opindex
env.filters['parameterlist'] = format_parameterlist
env.filters['parameters'] = format_parameters
......@@ -206,19 +204,6 @@ env.filters['pinned'] = format_pinned
env.filters['simplify_type'] = format_simplify_type
env.filters['stringformat'] = format_stringformat
def prepare_attr(attr):
if "init" in attr:
return dict(
type = attr["type"],
name = attr["name"],
init = attr["init"],
comment = attr["comment"])
else:
return dict(
type = attr["type"],
name = attr["name"],
comment = attr["comment"])
def preprocess_node(node):
setdefault(node, "attrs_name", node.name.lower())
setdefault(node, "block", "block")
......@@ -227,60 +212,48 @@ def preprocess_node(node):
arguments = [ ]
initattrs = [ ]
for input in node.ins:
arguments.append(dict(
type = "ir_node *",
name = "irn_" + input[0],
comment = input[1]))
arguments.append(
Attribute("irn_" + input[0], type="ir_node *",
comment=input[1]))
if node.arity == "variable" or node.arity == "dynamic":
arguments.append(dict(
type = "int",
name = "arity",
comment = "size of additional inputs array"))
arguments.append(dict(
type = "ir_node *const *",
name = "in",
comment = "additional inputs"))
arguments.append(
Attribute("arity", type="int",
comment="size of additional inputs array"))
arguments.append(
Attribute("in", type="ir_node *const *",
comment="additional inputs"))
if not hasattr(node, "mode"):
arguments.append(dict(
type = "ir_mode *",
name = "mode",
comment = "mode of the operations result"))
arguments.append(
Attribute("mode", type="ir_mode *",
comment = "mode of the operations result"))
for attr in node.attrs:
attr["fqname"] = attr["name"]
if "init" in attr:
if attr.init is not None:
continue
arguments.append(attr)
# dynamic pin state means more constructor arguments
if is_dynamic_pinned(node):
if hasattr(node, "pinned_init"):
initattrs.append(dict(
fqname = "exc.pin_state",
init = node.pinned_init
))
initattrs.append(
Attribute("pin_state", fqname="exc.pin_state",
type="op_pin_state", init=node.pinned_init))
else:
node.constructor_args.append(
dict(
name = "pin_state",
type = "op_pin_state",
comment = "pinned state",
)
)
initattrs.append(dict(
fqname = "exc.pin_state",
init = "pin_state"
))
Attribute("pin_state", type="op_pin_state",
comment = "pinned state"))
initattrs.append(
Attribute("pin_state", fqname="exc.pin_state",
type="op_pin_state", init="pin_state"))
if hasattr(node, "throws_init"):
initattrs.append(dict(
fqname = "exc.throws_exception",
init = node.throws_init
))
initattrs.append(
Attribute("throws_exception", fqname="exc.throws_exception",
type="unsigned", init=node.throws_init))
for arg in node.constructor_args:
arguments.append(prepare_attr(arg))
arguments.append(arg)
node.arguments = arguments
node.initattrs = initattrs
......
......@@ -4,7 +4,7 @@
# Firm node specifications
# The comments are in (standard python) restructured text format and are used
# to generate documentation.
from spec_util import abstract, op
from spec_util import abstract, op, Attribute
name = "ir"
......@@ -31,11 +31,7 @@ class EntConst(object):
knownBlock = True
pinned = "no"
attrs = [
dict(
type = "ir_entity*",
name = "entity",
comment = "entity to operate on",
),
Attribute("entity", type="ir_entity*", comment="entity to operate on"),
]
attr_struct = "entconst_attr"
attrs_name = "entc"
......@@ -50,11 +46,7 @@ class TypeConst:
knownBlock = True
pinned = "no"
attrs = [
dict(
type = "ir_type*",
name = "type",
comment = "type to operate on",
),
Attribute("type", type="ir_type*", comment="type to operate on"),
]
attr_struct = "typeconst_attr"
attrs_name = "typec"
......@@ -85,11 +77,8 @@ class Alloc:
("res", "pointer to newly allocated memory"),
]
attrs = [
dict(
name = "alignment",
type = "unsigned",
comment = "alignment of the memory block (must be a power of 2)",
),
Attribute("alignment", type="unsigned",
comment="alignment of the memory block (must be a power of 2)"),
]
flags = [ "uses_memory" ]
pinned = "yes"
......@@ -160,38 +149,17 @@ class ASM:
("mem", "memory dependency"),
]
attrs = [
dict(
name = "input_constraints",
type = "ir_asm_constraint*",
comment = "input constraints",
),
dict(
name = "n_output_constraints",
type = "size_t",
noprop = True,
comment = "number of output constraints",
),
dict(
name = "output_constraints",
type = "ir_asm_constraint*",
comment = "output constraints",
),
dict(
name = "n_clobbers",
type = "size_t",
noprop = True,
comment = "number of clobbered registers/memory",
),
dict(
name = "clobbers",
type = "ident**",
comment = "list of clobbered registers/memory",
),
dict(
name = "text",
type = "ident*",
comment = "assembler text",
),
Attribute("input_constraints", type="ir_asm_constraint*",
comment="input constraints"),
Attribute("n_output_constraints", type="size_t", noprop=True,
comment="number of output constraints"),
Attribute("output_constraints", type="ir_asm_constraint*",
comment="output constraints"),
Attribute("n_clobbers", type="size_t", noprop=True,
comment="number of clobbered registers/memory"),
Attribute("clobbers", type="ident**",
comment="list of clobbered registers/memory"),
Attribute("text", type="ident*", comment="assembler text"),
]
# constructor is written manually at the moment, because of the clobbers+
# constraints arrays needing special handling (2 arguments for 1 attribute)
......@@ -247,12 +215,8 @@ class Block:
flags = []
attr_struct = "block_attr"
attrs = [
dict(
name = "entity",
type = "ir_entity*",
comment = "entity representing this block",
init = "NULL",
),
Attribute("entity", type="ir_entity*", init="NULL",
comment="entity representing this block"),
]
customSerializer = True
......@@ -281,16 +245,9 @@ class Builtin:
]
flags = [ "uses_memory" ]
attrs = [
dict(
type = "ir_builtin_kind",
name = "kind",
comment = "kind of builtin",
),
dict(
type = "ir_type*",
name = "type",
comment = "method type for the builtin call",
)
Attribute("kind", type="ir_builtin_kind", comment="kind of builtin"),
Attribute("type", type="ir_type*",
comment="method type for the builtin call"),
]
pinned = "exception"
pinned_init = "op_pin_state_pinned"
......@@ -319,11 +276,8 @@ class Call:
]
flags = [ "fragile", "uses_memory" ]
attrs = [
dict(
type = "ir_type*",
name = "type",
comment = "type of the call (usually type of the called procedure)",
),
Attribute("type", type="ir_type*",
comment="type of the call (usually type of the called procedure)"),
]
attr_struct = "call_attr"
pinned = "exception"
......@@ -340,11 +294,8 @@ class Cmp(Binop):
flags = []
mode = "mode_b"
attrs = [
dict(
type = "ir_relation",
name = "relation",
comment = "Comparison relation"
)
Attribute("relation", type="ir_relation",
comment="Comparison relation"),
]
attr_struct = "cmp_attr"
......@@ -361,12 +312,9 @@ class Cond:
flags = [ "cfopcode", "forking" ]
pinned = "yes"
attrs = [
dict(
name = "jmp_pred",
type = "cond_jmp_predicate",
init = "COND_JMP_PRED_NONE",
comment = "can indicate the most likely jump",
),
Attribute("jmp_pred", type="cond_jmp_predicate",
init="COND_JMP_PRED_NONE",
comment = "can indicate the most likely jump"),
]
attr_struct = "cond_attr"
......@@ -384,16 +332,10 @@ class Switch:
flags = [ "cfopcode", "forking" ]
pinned = "yes"
attrs = [
dict(
name = "n_outs",
type = "unsigned",
comment = "number of outputs (including pn_Switch_default)",
),
dict(
name = "table",
type = "ir_switch_table*",
comment = "table describing mapping from input values to Proj numbers",
),
Attribute("n_outs", type="unsigned",
comment="number of outputs (including pn_Switch_default)"),
Attribute("table", type="ir_switch_table*",
comment="table describing mapping from input values to Proj numbers"),
]
attr_struct = "switch_attr"
attrs_name = "switcha"
......@@ -417,11 +359,8 @@ class Confirm:
flags = [ "highlevel" ]
pinned = "yes"
attrs = [
dict(
name = "relation",
type = "ir_relation",
comment = "relation of value to bound",
),
Attribute("relation", type="ir_relation",
comment="relation of value to bound"),
]
attr_struct = "confirm_attr"
......@@ -434,11 +373,8 @@ class Const:
knownBlock = True
pinned = "no"
attrs = [
dict(
type = "ir_tarval*",
name = "tarval",
comment = "constant value (a tarval object)",
)
Attribute("tarval", type="ir_tarval*",
comment="constant value (a tarval object)"),
]
attr_struct = "const_attr"
attrs_name = "con"
......@@ -463,26 +399,16 @@ class CopyB:
mode = "mode_M"
flags = [ "uses_memory" ]
attrs = [
dict(
name = "type",
type = "ir_type*",
comment = "type of copied data",
),
dict(
type = "ir_volatility",
name = "volatility",
comment = "volatile CopyB nodes have a visible side-effect and may not be optimized",
init = "flags & cons_volatile ? volatility_is_volatile : volatility_non_volatile",
to_flags = "%s == volatility_is_volatile ? cons_volatile : cons_none"
)
Attribute("type", type="ir_type*", comment="type of copied data"),
Attribute("volatility", type="ir_volatility",
init="flags & cons_volatile ? volatility_is_volatile : volatility_non_volatile",
to_flags="%s == volatility_is_volatile ? cons_volatile : cons_none",
comment="volatile CopyB nodes have a visible side-effect and may not be optimized"),
]
attr_struct = "copyb_attr"
constructor_args = [
dict(
type = "ir_cons_flags",
name = "flags",
comment = "specifies volatility",
),
Attribute("flags", type="ir_cons_flags",
comment="specifies volatility"),
]
pinned = "no"
......@@ -502,16 +428,9 @@ class Div:
]
flags = [ "fragile", "uses_memory" ]
attrs = [
dict(
type = "ir_mode*",
name = "resmode",
comment = "mode of the result value",
),
dict(
name = "no_remainder",
type = "int",
init = "0",
)
Attribute("resmode", type="ir_mode*",
comment="mode of the result value"),
Attribute("no_remainder", type="int", init="0"),
]
attr_struct = "div_attr"
pinned = "exception"
......@@ -609,33 +528,21 @@ class Load:
flags = [ "fragile", "uses_memory" ]
pinned = "exception"
attrs = [
dict(
type = "ir_mode*",
name = "mode",
comment = "mode of the value to be loaded",
),
dict(
type = "ir_volatility",
name = "volatility",
comment = "volatile loads are a visible side-effect and may not be optimized",
init = "flags & cons_volatile ? volatility_is_volatile : volatility_non_volatile",
to_flags = "%s == volatility_is_volatile ? cons_volatile : cons_none"
),
dict(
type = "ir_align",
name = "unaligned",
comment = "pointers to unaligned loads don't need to respect the load-mode/type alignments",
init = "flags & cons_unaligned ? align_non_aligned : align_is_aligned",
to_flags = "%s == align_non_aligned ? cons_unaligned : cons_none"
),
Attribute("mode", type="ir_mode*",
comment="mode of the value to be loaded"),
Attribute("volatility", type="ir_volatility",
init="flags & cons_volatile ? volatility_is_volatile : volatility_non_volatile",
to_flags="%s == volatility_is_volatile ? cons_volatile : cons_none",
comment="volatile loads are a visible side-effect and may not be optimized"),
Attribute("unaligned", type="ir_align",
init="flags & cons_unaligned ? align_non_aligned : align_is_aligned",
to_flags="%s == align_non_aligned ? cons_unaligned : cons_none",
comment="pointers to unaligned loads don't need to respect the load-mode/type alignments"),
]
attr_struct = "load_attr"
constructor_args = [
dict(
type = "ir_cons_flags",
name = "flags",
comment = "specifies alignment, volatility and pin state",
),
Attribute("flags", type="ir_cons_flags",
comment="specifies alignment, volatility and pin state"),
]
pinned_init = "flags & cons_floats ? op_pin_state_floats : op_pin_state_pinned"
throws_init = "(flags & cons_throws_exception) != 0"
......@@ -673,11 +580,7 @@ class Mod:
]
flags = [ "fragile", "uses_memory" ]
attrs = [
dict(
type = "ir_mode*",
name = "resmode",
comment = "mode of the result",
),
Attribute("resmode", type="ir_mode*", comment="mode of the result"),
]
attr_struct = "mod_attr"
pinned = "exception"
......@@ -763,21 +666,18 @@ class Pin:
@op
class Proj:
"""returns an entry of a tuple value"""
ins = [
ins = [
("pred", "the tuple value from which a part is extracted"),
]
flags = []
pinned = "no"
knownBlock = True
knownGraph = True
block = "get_nodes_block(irn_pred)"
graph = "get_irn_irg(irn_pred)"
flags = []
pinned = "no"
knownBlock = True
knownGraph = True
block = "get_nodes_block(irn_pred)"
graph = "get_irn_irg(irn_pred)"
attrs = [
dict(
type = "long",
name = "proj",
comment = "number of tuple component to be extracted",
),
Attribute("proj", type="long",
comment="number of tuple component to be extracted"),
]
attr_struct = "proj_attr"
......@@ -827,11 +727,8 @@ class Sel:
mode = "is_Method_type(get_entity_type(entity)) ? mode_P_code : mode_P_data"
pinned = "no"
attrs = [
dict(
type = "ir_entity*",
name = "entity",
comment = "entity which is selected",
)
Attribute("entity", type="ir_entity*",
comment="entity which is selected"),
]
attr_struct = "sel_attr"
......@@ -898,27 +795,18 @@ class Store:
pinned_init = "flags & cons_floats ? op_pin_state_floats : op_pin_state_pinned"
throws_init = "(flags & cons_throws_exception) != 0"
attrs = [
dict(
type = "ir_volatility",
name = "volatility",
comment = "volatile stores are a visible side-effect and may not be optimized",
init = "flags & cons_volatile ? volatility_is_volatile : volatility_non_volatile",
to_flags = "%s == volatility_is_volatile ? cons_volatile : cons_none"
),
dict(
type = "ir_align",
name = "unaligned",
comment = "pointers to unaligned stores don't need to respect the load-mode/type alignments",
init = "flags & cons_unaligned ? align_non_aligned : align_is_aligned",
to_flags = "%s == align_non_aligned ? cons_unaligned : cons_none"
),
Attribute("volatility", type="ir_volatility",
init="flags & cons_volatile ? volatility_is_volatile : volatility_non_volatile",
to_flags="%s == volatility_is_volatile ? cons_volatile : cons_none",
comment="volatile stores are a visible side-effect and may not be optimized"),
Attribute("unaligned", type="ir_align",
init="flags & cons_unaligned ? align_non_aligned : align_is_aligned",
to_flags="%s == align_non_aligned ? cons_unaligned : cons_none",
comment="pointers to unaligned stores don't need to respect the load-mode/type alignments"),
]
constructor_args = [
dict(
type = "ir_cons_flags",
name = "flags",
comment = "specifies alignment, volatility and pin state",
),
Attribute("flags", type="ir_cons_flags",
comment="specifies alignment, volatility and pin state"),
]
@op
......
......@@ -16,6 +16,18 @@ def op(cls):
def isOp(nodetype):
return hasattr(nodetype, "__is_firm_op")
class Attribute(object):
def __init__(self, name, type, comment="", init=None, to_flags=None, noprop=False, fqname=None):
self.type = type
self.name = name
self.comment = comment
self.init = init
self.to_flags = to_flags
self.noprop = noprop
if fqname is None:
fqname = name
self.fqname = fqname
def is_dynamic_pinned(node):
return node.pinned == "exception"
......
{{warning}}
{%- for node in nodes|notset('customSerializer') %}
{%- for node in nodes|hasnot('customSerializer') %}
static ir_node *read_{{node.name}}(read_env_t *env)
{
{%- if not node.knownBlock %}
......@@ -27,7 +27,7 @@ static ir_node *read_{{node.name}}(read_env_t *env)
{%- if node.attrs|has('to_flags') %}
ir_cons_flags flags = cons_none
{%- for attr in node.attrs %}
{%- if "to_flags" in attr %}
{%- if attr.to_flags %}
| ({{attr.to_flags|stringformat(attr.name)}})
{%- endif %}
{%- endfor %}
......@@ -63,7 +63,7 @@ static ir_node *read_{{node.name}}(read_env_t *env)
}
{% endfor %}
{%- for node in nodes|notset('customSerializer') %}
{%- for node in nodes|hasnot('customSerializer') %}
static void write_{{node.name}}(write_env_t *env, const ir_node *node)
{