Commit 659cb790 authored by Moritz Kroll's avatar Moritz Kroll
Browse files

Removed obsolete perl ir spec

[r25822]
parent 4b29a317
# This is the specification for the IR nodes
# Code is generated by scripts/gen_ir.pl
#
# $Id$
$NONE = "#_#_#_#_#_NONE_#_#_#_#_#";
$MANUALFROMPARAM = "#_#_#_#_#_MANUALFROMPARAM_#_#_#_#_#";
# The IR node description is done as a perl hash with the following structure:
#
# %nodes = (
#
# <opname> => {
# op => use given node type instead of opname
# or 0 is this is an abstract node type (default: none)
# when present, no ir_op will be created
# is_a => name of another IR node description from which all data
# except "op" is inherited (default: none),
# mode => the mode of the op (default: parameter),
# op_flags => "N|L|C|X|I|F|Y|H|c|K|S|M|NB|NI" (default: "N"),
# state => "floats|pinned|mem_pinned|exc_pinned" (default: "floats"),
# arity => "dynamic|variable"
# dynamic allows to add inputs later,
# variable means, that the ins are given at construction time
# (default: automatically from args)
# block => the block for the node (default: parameter)
# ins => [ "in1", "in2", ... ] list of node inputs (default: none)
# attrs_name => name of the attribute structure
# (default if attrs exists: lcfirst(opname)),
# attrs_type => type of the attribute structure (default: auto generated),
# attrs => ordered list of attributes which will default to parameters
# after the ins and the mode parameters
# [
# {
# type => the C type of the attribute or "bit",
# name => the name of the attribute,
# init => an initializer instead of a parameter
# or $MANUALFROMPARAM to disable automatic
# initialization but still using a parameter
# or $NONE to disable initialization completely
# by also not using a parameter
# (default: parameter),
# initname => name to access attribute
# when present, attribute will not be added
# to the according attribute struct
# (default: ".".name)
# comment => documentation for the attribute
# }, ...
# ] (default: none),
# init => additional initialization code to be emitted after the
# attribute initialization (default: none)
# optimize => whether optimize_node should be called (0|1, default: 1),
# d_pre => code to be inserted at the begining of the new_d_* function
# (may include declarations and statements, default: none),
# d_post => code to be inserted into the new_d_* function after the call
# to the new_rd_* function whose result is stored in the
# local variable res (default: none)
# },
#
# <more nodes>
#
# ); # close the %nodes initializer
#
# op_flags: flags for the operation corresponding to the firm irop_flags:
# N irop_flag_none
# L irop_flag_labeled
# C irop_flag_commutative
# X irop_flag_cfopcode
# I irop_flag_ip_cfopcode
# F irop_flag_fragile
# Y irop_flag_forking
# H irop_flag_highlevel
# c irop_flag_constlike
# K irop_flag_keep
# S irop_flag_start_block
# M irop_flag_uses_memory
# NB irop_flag_dump_noblock
# NI irop_flag_dump_noinput
#
%nodes = (
Start => {
mode => "mode_T",
op_flags => "X",
state => "pinned"
},
End => {
mode => "mode_X",
op_flags => "X",
state => "pinned",
arity => "dynamic"
},
Block => {
mode => "mode_BB",
op_flags => "L",
state => "pinned",
arity => "variable",
block => "NULL",
attrs => [
{
type => "ir_graph *",
name => "irg",
init => "irg",
comment => "The graph this block belongs to."
},
{
type => "ir_visited_t",
name => "block_visited",
init => $NONE,
comment => "For the walker that walks over all blocks."
},
{
type => "bit",
name => "is_matured",
init => $NONE,
comment => "If set, all in-nodes of the block are fixed."
},
{
type => "bit",
name => "is_dead",
init => "0",
comment => "If set, the block is dead (and could be replace by a Bad."
},
{
type => "bit",
name => "is_mb_head",
init => "1",
comment => "Set if this block is a macroblock head."
},
{
type => "bit",
name => "has_label",
init => "0",
comment => "Set if this block has a label assigned."
},
{
type => "bit",
name => "marked",
init => $NONE, # TODO: This is uninitialized!!
comment => "Can be set/unset to temporary mark a block."
},
{
type => "ir_node **",
name => "graph_arr",
init => $NONE, # TODO: This is uninitialized!!
comment => "An array to store all parameters."
},
{
type => "ir_dom_info",
name => "dom",
init => $NONE, # TODO: This is uninitialized!!
comment => "Datastructure that holds information about dominators.
@@@ \@todo
Eventually overlay with graph_arr as only valid
in different phases. Eventually inline the whole
datastructure."
},
{
type => "ir_dom_info",
name => "pdom",
init => $NONE, # TODO: This is uninitialized!!
comment => "Datastructure that holds information about post-dominators."
},
{
type => "ir_node **",
name => "in_cg",
init => "NULL",
comment => "array with predecessors in
* interprocedural_view, if they differ
* from intraprocedural predecessors"
},
{
type => "unsigned *",
name => "backedge",
init => "new_backedge_arr(irg->obst, arity)",
comment => "Raw Bitfield n set to true if pred n is backedge."
},
{
type => "unsigned *",
name => "cg_backedge",
init => "NULL",
comment => "Raw Bitfield n set to true if pred n is interprocedural backedge."
},
{
type => "ir_extblk *",
name => "extblk",
init => "NULL",
comment => "The extended basic block this block belongs to."
},
{
type => "ir_region *",
name => "region",
init => $NONE, # TODO: This is uninitialized!!
comment => "The immediate structural region this block belongs to."
},
{
type => "unsigned",
name => "mb_depth",
init => "0",
comment => "The macroblock depth: A distance from the macroblock header."
},
{
type => "ir_label_t",
name => "label",
init => "0",
comment => "The block label if assigned."
},
{
type => "ir_node *",
name => "phis",
init => $NONE, # TODO: This is uninitialized!!
comment => "The list of Phi nodes in this block."
},
{
type => "struct list_head",
name => "succ_head",
init => $NONE, # TODO: This is uninitialized!!
comment => "A list head for all successor edges of a block."
},
],
init => "\t/* macroblock header */\n".
"\tres->in[0] = res;\n\n".
"\tset_Block_matured(res, 1);\n".
"\tset_Block_block_visited(res, 0);\n",
optimize => 0,
d_pre => "\tint i;\n\tint has_unknown = 0;\n",
d_post => "\t/* Create and initialize array for Phi-node construction. */\n".
"\tif (get_irg_phase_state(current_ir_graph) == phase_building) {\n".
"\t\tres->attr.block.graph_arr = NEW_ARR_D(ir_node *, current_ir_graph->obst,\n".
"\t\t current_ir_graph->n_loc);\n".
"\t\tmemset(res->attr.block.graph_arr, 0, sizeof(ir_node *) * current_ir_graph->n_loc);\n".
"\t}\n\n".
"\tfor (i = arity-1; i >= 0; i--)\n".
"\t\tif (is_Unknown(in[i])) {\n".
"\t\thas_unknown = 1;\n".
"\t\tbreak;\n".
"\t}\n".
"\tif (!has_unknown) res = optimize_node(res);\n".
"\tcurrent_ir_graph->current_block = res;\n".
"\tIRN_VRFY_IRG(res, current_ir_graph);\n"
},
Const_type => {
op => "Const",
op_flags => "c|S",
mode => "get_tarval_mode(tv)",
block => "get_irg_start_block(irg)",
attrs_name => "con",
attrs => [
{
type => "tarval *",
name => "tv"
},
{
type => "ir_type *",
name => "tp",
init => $MANUALFROMPARAM
}
],
init => "set_Const_type(res, tp);\n"
},
Id => {
ins => [ "val" ]
},
Proj => {
ins => [ "arg" ],
attrs_type => "long",
attrs => [
{
type => "long",
name => "proj",
initname => "",
}
],
init => "assert(get_Proj_pred(res));\n".
"\tassert(get_nodes_block(get_Proj_pred(res)));\n"
},
# Conv => {
# ins => [ "op" ],
# attrs => [
# {
# type => "char",
# name => "strict",
# #init => "0",
# comment => "If set, this is a strict Conv that cannot be removed."
# }
# ]
# },
Cast => {
op_flags => "H",
mode => "get_irn_mode(op)",
ins => [ "op" ],
attrs => [
{
type => "ir_type *",
name => "totype",
comment => "Type of the casted node."
}
],
init => "assert(is_atomic_type(totype));\n"
},
Jmp => {
op_flags => "X",
state => "pinned",
mode => "mode_X"
},
IJmp => {
op_flags => "X",
state => "pinned",
mode => "mode_X",
ins => [ "target" ]
},
Cond => {
op_flags => "X|Y",
state => "pinned",
mode => "mode_T",
ins => [ "selector" ],
attrs => [
{
type => "cond_kind",
name => "kind",
init => "dense",
comment => "Flavor of Cond."
},
{
type => "long",
name => "default_proj",
init => "0",
comment => "Only for non-binary Conds: biggest Proj number, i.e. the one used for default."
},
{
type => "cond_jmp_predicate",
name => "jmp_pred",
init => "COND_JMP_PRED_NONE",
comment => "Only for binary Conds: The jump predication."
},
]
},
Tuple => {
op_flags => "L",
mode => "mode_T",
arity => "variable"
},
BinOp => {
op => 0,
ins => [ "left", "right" ]
},
Cmp => {
is_a => "BinOp",
mode => "mode_T"
},
Add => {
is_a => "BinOp",
op_flags => "C",
},
Div => {
mode => "mode_T",
op_flags => "F|M",
state => "exc_pinned",
ins => [ "mem", "left", "right" ],
attrs_name => "divmod",
attrs => [
{
type => "except_attr",
name => "exc",
init => $NONE
},
{
type => "ir_mode *",
name => "res_mode"
},
{
type => "op_pin_state",
name => "state",
initname => ".exc.pin_state"
},
{
type => "char",
name => "no_remainder",
init => "0"
}
],
d_post => "\t#if PRECISE_EXC_CONTEXT\n".
"\tfirm_alloc_frag_arr(res, op_Div, &res->attr.except.frag_arr);\n".
"\t#endif\n"
}
);
#!/usr/bin/perl -w
#
# 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.
#
# This script generates C code for the IR nodes specified
# in ../ir/ir/ir_spec.pl.
#
# $Id$
use strict;
my $specfile = $ARGV[0];
my $target_dir = $ARGV[1];
my $target_cons = $target_dir."/gen_ir_cons.c.inl";
our %nodes;
our $NONE;
our $MANUALFROMPARAM;
# include spec file
my $return;
no strict "subs";
unless ($return = do $specfile) {
die "Fatal error: couldn't parse $specfile: $@" if $@;
die "Fatal error: couldn't do $specfile: $!" unless defined $return;
die "Fatal error: couldn't run $specfile" unless $return;
}
use strict "subs";
my @text_cons;
my $ARITY_DYNAMIC = -1;
my $ARITY_VARIABLE = "arity";
my $had_error = 0;
# generate IR node constructors
foreach my $nodename (keys(%nodes)) {
my %curnode = %{ $nodes{"$nodename"} };
my $op_name;
if (exists($curnode{"op"})) {
$op_name = $curnode{"op"};
} else {
$op_name = $nodename;
}
if ($op_name eq 0) {
next;
}
print "${op_name}\n";
# handle inheritance
my @hierarchy;
my %curop = %curnode;
my $supername;
push(@hierarchy, $nodename);
while (exists($curop{"is_a"})) {
$supername = $curop{"is_a"};
push(@hierarchy, $supername);
%curop = %{ $nodes{$supername} };
}
my %node;
foreach my $cursupername (reverse @hierarchy) {
# print " - $cursupername\n";
my %supernode = %{ $nodes{$cursupername} };
foreach my $keyname (keys(%supernode)) {
# print " --- $keyname\n";
if ($keyname eq "op") {
next;
}
my $value = $supernode{$keyname};
$node{$keyname} = $value;
}
}
# check op_flags and state fields
if (!exists($node{"op_flags"})) {
$node{"op_flags"} = "N";
}
if (!exists($node{"state"})) {
$node{"state"} = "floats";
}
# calculate arity
my $arity = 0;
if (exists($node{"arity"})) {
$arity = $node{"arity"};
if (exists($node{"ins"})) {
print "ERROR: $nodename defines \"arity\" AND \"ins\" field\n";
$had_error = 1;
}
} elsif (exists($node{"ins"})) {
$arity = scalar(@{ $node{"ins"} });
}
if ($arity eq "dynamic") {
$arity = $ARITY_DYNAMIC;
} elsif ($arity eq "variable") {
$arity = $ARITY_VARIABLE;
}
# build new_rd_$nodename function
push(@text_cons, "ir_node *new_rd_$nodename(dbg_info *db, ir_graph *irg");
my @text_paramdecls;
my @text_paramuse;
my $block_name;
if (!exists($node{"block"})) {
push(@text_cons, ", ir_node *block");
$block_name = "block";
} else {
$block_name = $node{"block"};
}
if (exists($node{"ins"})) {
my @ins = @{ $node{"ins"} };
foreach my $inname (@ins) {
push(@text_paramdecls, "ir_node *$inname");
push(@text_paramuse, "$inname");
}
} elsif ($arity eq $ARITY_VARIABLE) {
push(@text_paramdecls, "int arity, ir_node **in");
push(@text_paramuse, "arity, in");
}
my $mode_name;
if (exists($node{"mode"})) {
$mode_name = $node{"mode"};
} else {
$mode_name = "mode";
push(@text_paramdecls, "ir_mode *mode");
push(@text_paramuse, "mode");
}
if (exists($node{"attrs"})) {
my @attrs = @{ $node{"attrs"} };
if (!exists($node{"attrs_name"})) {
$node{"attrs_name"} = lcfirst($nodename);
}
foreach my $attritem (@attrs) {
my %attr = %{ $attritem };
if (!exists($attr{"init"}) || $attr{"init"} eq $MANUALFROMPARAM) {
push(@text_paramdecls, $attr{"type"}. " ".$attr{"name"});
push(@text_paramuse, $attr{"name"});
}
}
}
push(@text_cons, ", " . join(", ", @text_paramdecls)) if @text_paramdecls;
push(@text_cons, ")\n{\n".
"\tir_node *res;\n");
push(@text_cons, "\tir_graph *rem = current_ir_graph;\n");
my $in_array = "NULL";
if ($arity eq $ARITY_VARIABLE) {
$in_array = "in";
} elsif ($arity > 0) {
push(@text_cons, "\tir_node *in[$arity];\n");
$in_array = "in";
my @ins = @{ $node{"ins"} };
for (my $idx = 0; $idx <= $#ins; $idx++) {
push(@text_cons, "\tin[$idx] = ".$ins[$idx].";\n");
}
}
push(@text_cons, "\tcurrent_ir_graph = irg;\n");
push(@text_cons, "\tres = new_ir_node(db, irg, $block_name, op_$op_name, $mode_name, $arity, $in_array);\n");
if (exists($node{"attrs"})) {
my @attrs = @{ $node{"attrs"} };
foreach my $attritem (@attrs) {
my %attr = %{ $attritem };
if (!exists($attr{"init"}) || $attr{"init"} ne $MANUALFROMPARAM &&
$attr{"init"} ne $NONE) {
my $initname = exists($attr{"initname"}) ? $attr{"initname"} : "." . $attr{"name"};
my $initval = exists($attr{"init"}) ? $attr{"init"} : $attr{"name"};
push(@text_cons, "\tres->attr.".$node{"attrs_name"}."$initname = $initval;\n");
}
}
}
if (exists($node{"init"})) {
push(@text_cons, $node{"init"});
}
if (!exists($node{"optimize"}) || $node{"optimize"} eq 1) {
push(@text_cons, "\tres = optimize_node(res);\n");
}
push(@text_cons, "\tIRN_VRFY_IRG(res, irg);\n".
"\tcurrent_ir_graph = rem;\n".
"\treturn res;\n".