Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Zwinkau
libfirm
Commits
6b5dba40
Commit
6b5dba40
authored
Mar 09, 2010
by
Matthias Braun
Browse files
not used anymore (you can revive it from svn if needed)
[r27276]
parent
b1956da9
Changes
1
Show whitespace changes
Inline
Side-by-side
ir/ir/irdump_grgen.c
deleted
100644 → 0
View file @
b1956da9
/*
* Copyright (C) 1995-2007 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 Write ir graph as a grgen construction rule
* @author Andreas Schoesser
* @version $Id$
*/
/*
* THIS IS A COMPLETE QUICK HACK! USE WITH CARE
* NOT FOR PRODUCTION BUILD ;-)
*/
#define MAX_NODENAME_LEN 100
#include <assert.h>
#include <stdio.h>
#include <obst.h>
#include "irgraph.h"
#include "firm_types.h"
#include "pmap.h"
#include "tv.h"
#include "irgwalk.h"
#include "firm_types.h"
#include "irdump_grgen.h"
typedef
struct
{
ir_graph
*
irg
;
struct
pmap
*
mode_edge_map
;
struct
pmap
*
edge_name_map
;
struct
pmap
*
node_name_map
;
// Contains the mapping firm node -> node name
struct
obstack
node_names
;
// Contains the node name data
struct
pmap
*
mode_name_map
;
// Contains the mapping firm mode -> mode node name
struct
obstack
mode_names
;
// Contains the "mode node name" data
struct
pmap
*
nodes_to_dump
;
// Contains firm nodes, that have to be dumped
}
grgen_dumpinfo_t
;
typedef
struct
// Holds information needed througout the usage of a grgen dumper instance
{
FILE
*
output_file
;
// The file the grgen rules will be dumped to
}
irg_grgen_dumper_env_t
;
static
void
dump_grg_node
(
ir_node
*
n
,
grgen_dumpinfo_t
*
dump_info
,
FILE
*
fp
);
static
void
dump_grg_egde
(
ir_node
*
n
,
int
n_edge
,
grgen_dumpinfo_t
*
dump_info
,
FILE
*
fp
);
static
void
dump_grgen_mode
(
ir_node
*
n
,
grgen_dumpinfo_t
*
dump_info
,
FILE
*
fp
,
ir_mode
*
alt_mode
);
static
char
*
dump_grgen_mode_node
(
ir_mode
*
irn_mode
,
grgen_dumpinfo_t
*
dump_info
,
FILE
*
fp
);
static
void
dump_grgen_eval
(
ir_node
*
n
,
grgen_dumpinfo_t
*
dump_info
,
FILE
*
fp
);
static
int
dump_pattern
(
grgen_dumpinfo_t
*
dump_info
,
FILE
*
fp
);
static
void
set_indent
(
int
i
);
/*****************************************************************************
* Program: grgen_dumper.c
* Function: Dumps parts of a firm graph (those which have to be extracted
* as search and replace patterns) as a grGen rule.
* Depends on: Needs the analysis info generated by the pattern creator
* Author: Andreas Schoesser
* Date: 2006-12-07
*****************************************************************************/
// ---------------------------- INCLUDES --------------------------------
/* #include "grgen_dumper__t.h"
#include "create_pattern_t.h"
#include "firm_node_ext.h" */
// ----------------------------- GLOABALS --------------------------------
// Saves the current indent value and keeps spaces in a string
#define MAX_INDENT 100
static
char
indent
[
MAX_INDENT
]
=
""
;
// Saves the current node number to generate node names
static
int
node_counter
;
static
int
edge_counter
;
/************************************************************************
* Initializes the grgen_dumper module and dumps the GrGen File header
* Returns: An environment to be passed to all functions of the GrGen
* dumper.
* Parameters: file: filename of the file to dump to
* append: 1 if the previous file content should be
* maintained.
************************************************************************/
irg_grgen_dumper_env_t
*
init_irg_grgen_dumper
(
char
*
file
,
int
append
)
{
irg_grgen_dumper_env_t
*
const
grgen_dumper_env
=
XMALLOC
(
irg_grgen_dumper_env_t
);
FILE
*
fp
;
if
(
append
)
fp
=
fopen
(
file
,
"at"
);
else
{
fp
=
fopen
(
file
,
"wt"
);
// *** Dump header
fprintf
(
fp
,
"%susing Firm;
\n\n
"
,
indent
);
}
grgen_dumper_env
->
output_file
=
fp
;
return
(
grgen_dumper_env
);
}
/************************************************************************
* Frees information used by the grgen_dumper and closes the output file
************************************************************************/
void
deinit_irg_grgen_dumper
(
irg_grgen_dumper_env_t
*
grgen_dumper_env
)
{
fclose
(
grgen_dumper_env
->
output_file
);
xfree
(
grgen_dumper_env
);
}
static
void
collect_nodes
(
ir_node
*
n
,
void
*
env
)
{
pmap
*
nodes_to_dump
=
(
pmap
*
)
env
;
pmap_insert
(
nodes_to_dump
,
n
,
NULL
);
}
/************************************************************************
* Starts dumping
************************************************************************/
void
dump_irg_grgen_file
(
ir_graph
*
irg
,
char
*
filename
,
int
append
)
{
FILE
*
fp
;
grgen_dumpinfo_t
dump_info
;
int
uses_memory
=
0
;
irg_grgen_dumper_env_t
*
grgen_dumper_env
=
init_irg_grgen_dumper
(
filename
,
append
);
fp
=
grgen_dumper_env
->
output_file
;
// Do initialization
dump_info
.
irg
=
irg
;
// Basically copy the graph_ana_struct, ugly
dump_info
.
mode_edge_map
=
pmap_create
();
// Create some additional pmaps to hold
dump_info
.
edge_name_map
=
pmap_create
();
// node and edge name information etc.
dump_info
.
node_name_map
=
pmap_create
();
dump_info
.
mode_name_map
=
pmap_create
();
dump_info
.
nodes_to_dump
=
pmap_create
();
// Node and egde count start at 0 for each pattern to be dumped.
node_counter
=
0
;
edge_counter
=
0
;
obstack_init
(
&
(
dump_info
.
node_names
));
obstack_init
(
&
(
dump_info
.
mode_names
));
// Dump rule header
set_indent
(
0
);
fprintf
(
fp
,
"
\n\n
%srule %s
\n
%s{
\n
"
,
indent
,
get_entity_name
(
get_irg_entity
(
irg
)),
indent
);
set_indent
(
2
);
fprintf
(
fp
,
"%spattern { }
\n
"
,
indent
);
// Empty pattern
fprintf
(
fp
,
"%sreplace
\n
%s{
\n
"
,
indent
,
indent
);
// Graph is contrcuted in the replacement part
set_indent
(
4
);
irg_walk_graph
(
irg
,
collect_nodes
,
NULL
,
dump_info
.
nodes_to_dump
);
uses_memory
=
dump_pattern
(
&
dump_info
,
fp
);
// *** Dump footer
set_indent
(
0
);
fprintf
(
fp
,
"%s}
\n
"
,
indent
);
// Clean up
pmap_destroy
(
dump_info
.
mode_edge_map
);
pmap_destroy
(
dump_info
.
edge_name_map
);
pmap_destroy
(
dump_info
.
node_name_map
);
pmap_destroy
(
dump_info
.
mode_name_map
);
obstack_free
(
&
(
dump_info
.
node_names
),
NULL
);
obstack_finish
(
&
(
dump_info
.
node_names
));
obstack_free
(
&
(
dump_info
.
mode_names
),
NULL
);
obstack_finish
(
&
(
dump_info
.
mode_names
));
deinit_irg_grgen_dumper
(
grgen_dumper_env
);
}
void
dump_irg_grgen
(
ir_graph
*
irg
,
char
*
suffix
)
{
char
filename
[
100
]
=
""
;
strncat
(
filename
,
get_entity_name
(
get_irg_entity
(
irg
)),
sizeof
(
filename
)
-
1
);
strncat
(
filename
,
suffix
,
sizeof
(
filename
)
-
1
);
strncat
(
filename
,
".grg"
,
sizeof
(
filename
)
-
1
);
dump_irg_grgen_file
(
irg
,
filename
,
0
);
}
/************************************************************************
* Dumps the left hand side of the rule
************************************************************************/
static
int
dump_pattern
(
grgen_dumpinfo_t
*
dump_info
,
FILE
*
fp
)
{
struct
pmap
*
nodes_to_dump
=
dump_info
->
nodes_to_dump
;
pmap_entry
*
entry
;
int
uses_memory
=
0
;
// Dump all nodes
foreach_pmap
(
nodes_to_dump
,
entry
)
{
ir_node
*
n
=
(
ir_node
*
)
entry
->
key
;
// Dump node
if
(
get_irn_opcode
(
n
)
==
iro_Proj
&&
get_irn_mode
(
n
)
==
mode_M
)
uses_memory
=
1
;
dump_grg_node
(
n
,
dump_info
,
fp
);
dump_grgen_mode
(
n
,
dump_info
,
fp
,
NULL
);
}
// Dump all edges
foreach_pmap
(
nodes_to_dump
,
entry
)
{
ir_node
*
n
=
(
ir_node
*
)
entry
->
key
;
int
i
;
// Dump edges
for
(
i
=
is_Block
(
n
)
?
0
:
-
1
;
i
<
get_irn_arity
(
n
);
i
++
)
dump_grg_egde
(
n
,
i
,
dump_info
,
fp
);
}
fprintf
(
fp
,
"%seval {
\n
"
,
indent
);
set_indent
(
6
);
foreach_pmap
(
nodes_to_dump
,
entry
)
{
ir_node
*
n
=
(
ir_node
*
)
entry
->
key
;
dump_grgen_eval
(
n
,
dump_info
,
fp
);
}
set_indent
(
4
);
fprintf
(
fp
,
"%s}
\n
"
,
indent
);
set_indent
(
2
);
fprintf
(
fp
,
"%s} /* Replacement */
\n
"
,
indent
);
return
(
uses_memory
);
}
/************************************************************************
* Dumps a node in GrGen Format
************************************************************************/
static
void
dump_grg_node
(
ir_node
*
n
,
grgen_dumpinfo_t
*
dump_info
,
FILE
*
fp
)
{
char
*
node_name
;
// Already dumped the node? Then do nothing
if
(
pmap_contains
(
dump_info
->
node_name_map
,
n
))
return
;
// Else generate new node name and dump the node
node_name
=
OALLOCN
(
&
dump_info
->
node_names
,
char
,
MAX_NODENAME_LEN
);
sprintf
(
node_name
,
"%s%ld"
,
get_op_name
(
get_irn_op
(
n
)),
get_irn_node_nr
(
n
));
fprintf
(
fp
,
"%s%s : %s;
\n
"
,
indent
,
node_name
,
get_op_name
(
get_irn_op
(
n
)));
pmap_insert
(
dump_info
->
node_name_map
,
n
,
node_name
);
node_counter
++
;
}
/************************************************************************
* Dumps an edge in GrGen format
************************************************************************/
static
void
dump_grg_egde
(
ir_node
*
n
,
int
n_edge
,
grgen_dumpinfo_t
*
dump_info
,
FILE
*
fp
)
{
ir_node
*
to_node
;
char
*
from_node_name
,
*
to_node_name
;
char
**
nodes_edge_names
;
// Check if to_node has also to be dumped. If not, skip this edge
// We have to dump to_node here, because to_node has to be known by grgen before
// connecting an edge to it.
to_node
=
get_irn_n
(
n
,
n_edge
);
if
(
!
pmap_contains
(
dump_info
->
nodes_to_dump
,
to_node
))
return
;
if
((
nodes_edge_names
=
pmap_get
(
dump_info
->
edge_name_map
,
n
))
==
NULL
)
{
size_t
const
count
=
get_irn_arity
(
n
)
+
1
;
nodes_edge_names
=
OALLOCNZ
(
&
dump_info
->
node_names
,
char
*
,
count
);
pmap_insert
(
dump_info
->
edge_name_map
,
n
,
nodes_edge_names
);
}
assert
(
pmap_contains
(
dump_info
->
node_name_map
,
n
));
assert
(
pmap_contains
(
dump_info
->
node_name_map
,
to_node
));
from_node_name
=
(
char
*
)
pmap_get
(
dump_info
->
node_name_map
,
n
);
to_node_name
=
(
char
*
)
pmap_get
(
dump_info
->
node_name_map
,
to_node
);
{
char
edge_name
[
50
],
*
edge_name_obst
;
sprintf
(
edge_name
,
"pos%d_%d"
,
n_edge
+
1
,
edge_counter
++
);
edge_name_obst
=
OALLOCN
(
&
dump_info
->
node_names
,
char
,
strlen
(
edge_name
)
+
1
);
strcpy
(
edge_name_obst
,
edge_name
);
nodes_edge_names
[
n_edge
+
1
]
=
edge_name_obst
;
fprintf
(
fp
,
"%s%s -%s:df-> %s;
\n
"
,
indent
,
from_node_name
,
edge_name_obst
,
to_node_name
);
}
}
/************************************************************************
* Dumps an FIRM Mode as GrGen Code
* If source_node_name == NULL, that name of n that was already
* generated is used.
* If source_node_name != NULL, this given source will be used
* (useful for retyped nodes)
************************************************************************/
static
void
dump_grgen_mode
(
ir_node
*
n
,
grgen_dumpinfo_t
*
dump_info
,
FILE
*
fp
,
ir_mode
*
alt_mode
)
{
char
*
node_name
=
(
char
*
)
pmap_get
(
dump_info
->
node_name_map
,
n
);
ir_mode
*
irn_mode
=
(
alt_mode
!=
NULL
)
?
alt_mode
:
get_irn_mode
(
n
);
char
edge_name
[
50
];
char
*
mode_node_name
;
mode_node_name
=
dump_grgen_mode_node
(
irn_mode
,
dump_info
,
fp
);
//mode_code = get_mode_modecode(irn_mode);
//mode_name = get_mode_name(irn_mode);
// Yes, use the given mode-node
//mode_node_name = pmap_get(dump_info -> mode_name_map, (void *) mode_code);
sprintf
(
edge_name
,
"m%d"
,
edge_counter
++
);
if
(
pmap_get
(
dump_info
->
mode_edge_map
,
n
)
==
NULL
)
{
char
*
edge_name_obst
=
OALLOCN
(
&
dump_info
->
node_names
,
char
,
strlen
(
edge_name
)
+
1
);
strcpy
(
edge_name_obst
,
edge_name
);
pmap_insert
(
dump_info
->
mode_edge_map
,
n
,
edge_name_obst
);
}
// Dump the edge from the current node to it's mode node
fprintf
(
fp
,
"%s%s -%s:has_mode-> %s;
\n
"
,
indent
,
node_name
,
edge_name
,
mode_node_name
);
}
/************************************************************************
* Dumps a node representing a node
************************************************************************/
static
char
*
dump_grgen_mode_node
(
ir_mode
*
irn_mode
,
grgen_dumpinfo_t
*
dump_info
,
FILE
*
fp
)
{
const
char
*
mode_name
=
get_mode_name
(
irn_mode
);
char
*
mode_node_name
;
if
(
!
pmap_contains
(
dump_info
->
mode_name_map
,
irn_mode
))
{
// No, create a new mode-node
mode_node_name
=
OALLOCN
(
&
dump_info
->
mode_names
,
char
,
MAX_NODENAME_LEN
);
sprintf
(
mode_node_name
,
"mode_%s_node"
,
mode_name
);
pmap_insert
(
dump_info
->
mode_name_map
,
irn_mode
,
mode_node_name
);
fprintf
(
fp
,
"%s%s : Mode_%s;
\n
"
,
indent
,
mode_node_name
,
mode_name
);
return
(
mode_node_name
);
}
else
{
return
((
char
*
)
pmap_get
(
dump_info
->
mode_name_map
,
irn_mode
));
}
}
/************************************************************************
* Dumps the condition for the given node, depending on the node's
* attributes and the node's opcode
************************************************************************/
static
void
dump_grgen_eval
(
ir_node
*
n
,
grgen_dumpinfo_t
*
dump_info
,
FILE
*
fp
)
{
char
*
node_name
;
ir_opcode
code
=
get_irn_opcode
(
n
);
if
(
code
==
iro_Const
)
{
node_name
=
pmap_get
(
dump_info
->
node_name_map
,
n
);
fprintf
(
fp
,
"%s%s.value =
\"
%ld
\"
;
\n
"
,
indent
,
node_name
,
get_tarval_long
(
get_Const_tarval
(
n
)));
}
if
(
code
==
iro_Proj
)
{
node_name
=
pmap_get
(
dump_info
->
node_name_map
,
n
);
fprintf
(
fp
,
"%s%s.proj = %ld;
\n
"
,
indent
,
node_name
,
get_Proj_proj
(
n
));
}
/*if (code == iro_Block)
{
node_name = pmap_get(dump_info->node_name_map, n);
fprintf(fp, "%s%s.pos = %d;\n", indent, node_name, ??);
}
if (code == iro_Phi)
{
node_name = pmap_get(dump_info->node_name_map, n);
fprintf(fp, "%s%s.pos = %d;\n", indent, node_name, ??);
}*/
// TODO: Dump Block evals: edge numbers
if
(
code
==
iro_Phi
||
code
==
iro_Block
)
{
char
**
edge_names
;
int
i
;
//assert((get_irn_arity(n) == get_irn_arity(phi_block)) && "Phi has other arity than it's block! Pattern seems to be broken.");
// Load the edge names that have been saved
edge_names
=
pmap_get
(
dump_info
->
edge_name_map
,
n
);
assert
(
edge_names
&&
"Some edge names have not been dumped!"
);
// Correlate the matched phi edges with the matched block edges
// Caution: Position 0 in the edge_names array is the block edge, so start at 1
for
(
i
=
code
==
iro_Block
;
i
<
get_irn_arity
(
n
)
+
1
;
i
++
)
{
assert
(
edge_names
[
i
]
!=
NULL
&&
"Some edges have not been dumped!"
);
fprintf
(
fp
,
"%s%s.pos = %d;
\n
"
,
indent
,
edge_names
[
i
],
i
);
}
return
;
}
}
/************************************************************************
* Sets current indent
************************************************************************/
static
void
set_indent
(
int
i
)
{
int
j
;
// Generate a string containing i blank characters
if
(
i
<
MAX_INDENT
-
1
)
{
for
(
j
=
0
;
j
<
i
;
j
++
)
indent
[
j
]
=
' '
;
indent
[
j
]
=
0x0
;
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment