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
8b76d044
Commit
8b76d044
authored
Jan 12, 2006
by
Sebastian Hack
Browse files
Prototypely implemented constrained coloring
parent
b46c894c
Changes
5
Hide whitespace changes
Inline
Side-by-side
ir/be/bechordal.c
View file @
8b76d044
...
...
@@ -11,6 +11,14 @@
#include "config.h"
#endif
#ifdef HAVE_MALLOC_H
#include <malloc.h>
#endif
#ifdef HAVE_ALLOCA_H
#include <alloca.h>
#endif
#include <ctype.h>
#include "obst.h"
...
...
@@ -33,6 +41,7 @@
#include "benumb_t.h"
#include "besched_t.h"
#include "belive_t.h"
#include "benode_t.h"
#include "bearch.h"
#include "beifg.h"
...
...
@@ -152,6 +161,91 @@ static INLINE int has_reg_class(const be_chordal_env_t *env, const ir_node *irn)
return
arch_irn_has_reg_class
(
env
->
main_env
->
arch_env
,
irn
,
-
1
,
env
->
cls
);
}
static
border_t
*
handle_constraint_perm
(
be_chordal_alloc_env_t
*
alloc_env
,
border_t
*
perm_border
)
{
const
arch_env_t
*
arch_env
=
alloc_env
->
chordal_env
->
main_env
->
arch_env
;
bitset_t
*
bs
=
bitset_alloca
(
alloc_env
->
chordal_env
->
cls
->
n_regs
);
ir_node
*
perm
=
perm_border
->
irn
;
int
n
=
get_irn_arity
(
perm_border
->
irn
);
int
n_projs
=
0
;
border_t
*
b
,
*
next_border
;
arch_register_req_t
req
;
ir_node
*
cnstr
;
int
has_cnstr
=
0
;
int
i
,
m
;
assert
(
is_Perm
(
perm
));
/*
* After the Perm, there must be a sequence of Projs
* which extract the permuted values of the Perm.
*/
for
(
b
=
border_next
(
perm_border
);
is_Proj
(
b
->
irn
);
b
=
border_next
(
b
))
{
assert
(
is_Proj
(
b
->
irn
));
assert
(
b
->
is_def
);
n_projs
++
;
}
cnstr
=
b
->
irn
;
next_border
=
border_next
(
b
);
assert
(
n_projs
==
n
&&
"There must be as many Projs as the Perm is wide"
);
/* The node after the last perm proj must be the constrained node. */
cnstr
=
b
->
irn
;
for
(
i
=
-
1
,
m
=
get_irn_arity
(
cnstr
);
i
<
m
;
++
i
)
{
req
.
type
=
arch_register_req_type_normal
;
if
(
arch_get_register_req
(
arch_env
,
&
req
,
cnstr
,
i
)
&&
req
.
type
==
arch_register_req_type_limited
)
{
has_cnstr
=
1
;
break
;
}
}
assert
(
has_cnstr
&&
"The node must have a register constraint"
);
/*
* Consider the code in beconstrperm.c
* We turned each input constraint of a node into an output
* constraint of the Perm's Proj. So we only have to
* consider output constraints here.
*/
for
(
b
=
border_next
(
perm_border
);
b
!=
next_border
;
b
=
border_next
(
b
))
{
ir_node
*
irn
=
b
->
irn
;
req
.
type
=
arch_register_req_type_normal
;
if
(
arch_get_register_req
(
arch_env
,
&
req
,
irn
,
-
1
)
&&
req
.
type
==
arch_register_req_type_limited
)
{
const
arch_register_t
*
reg
;
int
col
;
bitset_clear_all
(
bs
);
req
.
data
.
limited
(
irn
,
-
1
,
bs
);
col
=
bitset_next_set
(
bs
,
0
);
reg
=
arch_register_for_index
(
alloc_env
->
chordal_env
->
cls
,
col
);
arch_set_irn_register
(
arch_env
,
irn
,
reg
);
bitset_set
(
alloc_env
->
colors
,
col
);
}
}
for
(
b
=
border_next
(
perm_border
);
b
!=
next_border
;
b
=
border_next
(
b
))
{
ir_node
*
irn
=
b
->
irn
;
int
nr
=
get_irn_graph_nr
(
irn
);
bitset_set
(
alloc_env
->
live
,
nr
);
if
(
arch_get_irn_register
(
arch_env
,
irn
)
==
NULL
)
{
int
col
=
bitset_next_clear
(
alloc_env
->
colors
,
0
);
const
arch_register_t
*
reg
=
arch_register_for_index
(
alloc_env
->
chordal_env
->
cls
,
col
);
arch_set_irn_register
(
arch_env
,
irn
,
reg
);
}
}
return
next_border
;
}
/**
* Annotate the register pressure to the nodes and compute
* the liveness intervals.
...
...
@@ -211,10 +305,10 @@ static void pressure(ir_node *block, void *env_ptr)
DBG
((
dbg
,
LEVEL_1
,
"
\t
insn: %+F, pressure: %d
\n
"
,
irn
,
pressure
));
DBG
((
dbg
,
LEVEL_2
,
"
\t
live: %b
\n
"
,
live
));
/*
* If the node defines some value, which can put into a
* register of the current class, make a border for it.
*/
/*
* If the node defines some value, which can put into a
* register of the current class, make a border for it.
*/
if
(
has_reg_class
(
env
,
irn
))
{
int
nr
=
get_irn_graph_nr
(
irn
);
...
...
@@ -356,6 +450,18 @@ static void assign(ir_node *block, void *env_ptr)
bitset_clear
(
colors
,
col
);
bitset_clear
(
live
,
nr
);
/*
* If we encounter a Perm, it is due to register constraints.
* To achieve a valid coloring in the presence of register
* constraints, we invoke a special function which takes care
* that all constraints are fulfilled.
* This function assigned valid colors to the projs of the
* Perm and the constrained node itself and skips these
* nodes in the border list.
*/
if
(
is_Perm
(
b
->
irn
))
b
=
handle_constraint_perm
(
alloc_env
,
b
);
}
}
...
...
ir/be/bechordal_t.h
View file @
8b76d044
...
...
@@ -30,8 +30,6 @@
/** Defines an invalid register index. */
#define NO_COLOR (-1)
#define DBG_CHORDAL "firm.be.ra.chordal"
/**
* A liveness interval border.
*/
...
...
@@ -71,6 +69,8 @@ static INLINE struct list_head *_get_block_border_head(const be_chordal_env_t *i
#define get_block_border_head(info, bl) _get_block_border_head(info, bl)
#define foreach_border_head(head, pos) list_for_each_entry_reverse(border_t, pos, head, list)
#define border_next(b) (list_entry((b)->list.next, border_t, list))
#define border_prev(b) (list_entry((b)->list.prev, border_t, list))
#define chordal_has_class(chordal_env, irn) \
arch_irn_has_reg_class(chordal_env->main_env->arch_env, irn, -1, chordal_env->cls)
...
...
@@ -108,7 +108,7 @@ enum {
};
typedef
struct
{
int
dump_flags
;
unsigned
dump_flags
;
int
spill_method
;
int
copymin_method
;
int
ifg_flavor
;
...
...
ir/be/beconstrperm.c
View file @
8b76d044
...
...
@@ -28,18 +28,48 @@ static void walker_insert_constr_perms(ir_node *bl, void *env) {
int
pos
,
max
;
sched_foreach
(
bl
,
irn
)
{
ir_node
*
perm
=
NULL
;
/* check for a restriction of the result (-1) or one of the operands (0..n) */
max
=
get_irn_arity
(
irn
);
for
(
pos
=-
1
;
pos
<
max
;
++
pos
)
{
arch_get_register_req
(
aenv
,
&
req
,
irn
,
pos
);
/* if a restriction is found, insert a perm before the irn */
if
(
cenv
->
cls
==
arch_get_irn_reg_class
(
aenv
,
irn
,
pos
)
&&
req
.
type
==
arch_register_req_type_limited
)
{
insert_Perm_after
(
menv
,
cenv
->
cls
,
cenv
->
dom_front
,
sched_prev
(
irn
));
/* TODO: Next line is overkill. Update_liveness would suffice. */
be_liveness
(
get_irn_irg
(
bl
));
break
;
if
(
!
perm
)
perm
=
insert_Perm_after
(
menv
,
cenv
->
cls
,
cenv
->
dom_front
,
sched_prev
(
irn
));
/*
* Turn an input constraint into an output constraint:
* The Proj of the Perm which corresponds to the input
* constraint will have the input constraint of the node
* as an output constraint
*/
if
(
pos
>=
0
)
{
ir_node
*
op
=
get_irn_n
(
irn
,
pos
);
/*
* The operand must be a proj now, since a perm cut
* all live ranges.
*/
assert
(
is_Proj
(
op
));
be_set_Perm_out_req
(
perm
,
get_Proj_proj
(
op
),
&
req
);
}
}
}
/*
* If we inserted a perm,
* we have to recompute liveness analysis since inserting
* a Perm changes the liveness situation at the end
* of the block.
* (its needed by successive calls to insert_Perm_after)
* Perhaps thinking about an online liveness analysis
* would help.
*/
if
(
perm
)
be_liveness
(
get_irn_irg
(
bl
));
}
}
...
...
ir/be/benode.c
View file @
8b76d044
...
...
@@ -5,6 +5,8 @@
*
* Backend node support.
*
* This file provdies Perm, Copy, Spill and Reload nodes.
*
* Copyright (C) 2005 Universitaet Karlsruhe
* Released under the GPL
*/
...
...
@@ -20,6 +22,7 @@
#include "pmap.h"
#include "util.h"
#include "debug.h"
#include "fourcc.h"
#include "irop_t.h"
#include "irmode_t.h"
...
...
@@ -36,6 +39,8 @@
#define DBG_LEVEL 0
#define BENODE_MAGIC FOURCC('B', 'E', 'N', 'O')
typedef
enum
_node_kind_t
{
node_kind_spill
,
node_kind_reload
,
...
...
@@ -53,14 +58,22 @@ typedef struct {
}
be_op_t
;
typedef
struct
{
const
be_node_factory_t
*
factory
;
int
n_regs
;
const
arch_register_t
*
reg
[
1
];
const
arch_register_t
*
reg
;
arch_register_req_t
req
;
}
be_reg_data_t
;
typedef
struct
{
unsigned
magic
;
const
be_op_t
*
op
;
int
n_regs
;
be_reg_data_t
reg_data
[
1
];
}
be_node_attr_t
;
typedef
struct
{
be_node_attr_t
attr
;
ir_node
*
spill_ctx
;
ir_node
*
spill_ctx
;
/**< The node in whose context this spill was introduced. */
unsigned
offset
;
/**< The offset of the memory location the spill writes to
in the spill area. */
}
be_spill_attr_t
;
static
int
templ_pos_Spill
[]
=
{
...
...
@@ -93,17 +106,44 @@ static const ir_op_ops be_node_ops = {
NULL
};
static
INLINE
int
is_be_node
(
const
ir_node
*
irn
)
{
const
be_node_attr_t
*
attr
=
(
const
be_node_attr_t
*
)
&
irn
->
attr
;
return
attr
->
magic
==
BENODE_MAGIC
;
}
static
INLINE
int
is_be_kind
(
const
ir_node
*
irn
,
node_kind_t
kind
)
{
const
be_node_attr_t
*
a
=
(
const
be_node_attr_t
*
)
&
irn
->
attr
;
return
a
->
magic
==
BENODE_MAGIC
&&
a
->
op
&&
a
->
op
->
kind
==
kind
;
}
static
INLINE
void
*
get_attr_and_check
(
ir_node
*
irn
,
node_kind_t
kind
)
{
is_be_kind
(
irn
,
kind
);
return
&
irn
->
attr
;
}
static
be_node_attr_t
*
init_node_attr
(
ir_node
*
irn
,
const
be_node_factory_t
*
fact
,
int
n_regs
)
const
be_op_t
*
op
,
const
arch_register_class_t
*
cls
,
int
n_regs
)
{
be_node_attr_t
*
attr
=
(
be_node_attr_t
*
)
&
irn
->
attr
;
int
i
;
attr
->
magic
=
BENODE_MAGIC
;
attr
->
n_regs
=
n_regs
;
attr
->
factory
=
fact
;
attr
->
op
=
op
;
for
(
i
=
0
;
i
<
n_regs
;
++
i
)
attr
->
reg
[
i
]
=
NULL
;
for
(
i
=
0
;
i
<
n_regs
;
++
i
)
{
be_reg_data_t
*
rd
=
attr
->
reg_data
+
i
;
rd
->
reg
=
NULL
;
rd
->
req
.
cls
=
cls
;
rd
->
req
.
type
=
arch_register_req_type_normal
;
}
return
attr
;
}
...
...
@@ -134,33 +174,97 @@ ir_node *new_Spill(const be_node_factory_t *factory,
const
arch_register_class_t
*
cls
,
ir_graph
*
irg
,
ir_node
*
bl
,
ir_node
*
node_to_spill
,
ir_node
*
ctx
)
{
be_spill_attr_t
*
a
ttr
;
be_spill_attr_t
*
a
;
ir_node
*
irn
;
ir_node
*
in
[
1
];
ir_op
*
op
=
get_op
(
factory
,
cls
,
node_kind_spill
)
->
op
;
be_op_t
*
bop
=
get_op
(
factory
,
cls
,
node_kind_spill
);
ir_op
*
op
=
bop
->
op
;
assert
(
op
&&
"Spill opcode must be present for this register class"
);
in
[
0
]
=
node_to_spill
;
irn
=
new_ir_node
(
NULL
,
irg
,
bl
,
op
,
mode_M
,
1
,
in
);
attr
=
(
be_spill_attr_t
*
)
init_node_attr
(
irn
,
factory
,
0
);
attr
->
spill_ctx
=
ctx
;
in
[
0
]
=
node_to_spill
;
irn
=
new_ir_node
(
NULL
,
irg
,
bl
,
op
,
mode_M
,
1
,
in
);
a
=
(
be_spill_attr_t
*
)
init_node_attr
(
irn
,
bop
,
cls
,
0
);
a
->
spill_ctx
=
ctx
;
a
->
offset
=
0
;
return
irn
;
}
void
set_Spill_offset
(
ir_node
*
irn
,
unsigned
offset
)
{
be_spill_attr_t
*
a
=
(
be_spill_attr_t
*
)
&
irn
->
attr
;
assert
(
is_be_kind
(
irn
,
node_kind_spill
));
a
->
offset
=
offset
;
}
static
ir_node
*
find_a_spill_walker
(
ir_node
*
irn
,
unsigned
visited_nr
)
{
if
(
get_irn_visited
(
irn
)
<
visited_nr
)
{
set_irn_visited
(
irn
,
visited_nr
);
if
(
is_Phi
(
irn
))
{
int
i
,
n
;
for
(
i
=
0
,
n
=
get_irn_arity
(
irn
);
i
<
n
;
++
i
)
{
ir_node
*
n
=
find_a_spill_walker
(
get_irn_n
(
irn
,
i
),
visited_nr
);
if
(
n
!=
NULL
)
return
n
;
}
}
else
if
(
is_be_kind
(
irn
,
node_kind_spill
))
return
irn
;
}
return
NULL
;
}
/**
* Finds a spill for a reload.
* If the reload is directly using the spill, this is simple,
* else we perform DFS from the reload (over all PhiMs) and return
* the first spill node we find.
*/
static
INLINE
ir_node
*
find_a_spill
(
ir_node
*
irn
)
{
ir_graph
*
irg
=
get_irn_irg
(
irn
);
unsigned
visited_nr
=
get_irg_visited
(
irg
)
+
1
;
assert
(
is_be_kind
(
irn
,
node_kind_reload
));
set_irg_visited
(
irg
,
visited_nr
);
return
find_a_spill_walker
(
irn
,
visited_nr
);
}
unsigned
get_irn_spill_offset
(
ir_node
*
irn
)
{
be_node_attr_t
*
a
=
(
be_node_attr_t
*
)
&
irn
->
attr
;
assert
(
is_be_node
(
irn
));
switch
(
a
->
op
->
kind
)
{
case
node_kind_reload
:
assert
(
0
&&
"not yet implemented"
);
return
get_irn_spill_offset
(
find_a_spill
(
irn
));
case
node_kind_spill
:
return
((
be_spill_attr_t
*
)
a
)
->
offset
;
default:
assert
(
0
&&
"Illegal node kind (spill/reload required)"
);
}
return
0
;
}
ir_node
*
new_Reload
(
const
be_node_factory_t
*
factory
,
const
arch_register_class_t
*
cls
,
ir_graph
*
irg
,
ir_node
*
bl
,
ir_mode
*
mode
,
ir_node
*
spill_node
)
{
ir_node
*
irn
,
*
in
[
1
];
ir_op
*
op
=
get_op
(
factory
,
cls
,
node_kind_reload
)
->
op
;
be_op_t
*
bop
=
get_op
(
factory
,
cls
,
node_kind_reload
);
ir_op
*
op
=
bop
->
op
;
assert
(
op
&&
"Reload opcode must be present for this register class"
);
// assert(is_Spill(factory, spill_node) && "Operand of Reload must be a Spill");
in
[
0
]
=
spill_node
;
irn
=
new_ir_node
(
NULL
,
irg
,
bl
,
op
,
mode
,
1
,
in
);
init_node_attr
(
irn
,
factory
,
1
);
init_node_attr
(
irn
,
bop
,
cls
,
1
);
return
irn
;
}
...
...
@@ -170,10 +274,11 @@ ir_node *new_Perm(const be_node_factory_t *factory,
ir_graph
*
irg
,
ir_node
*
bl
,
int
arity
,
ir_node
**
in
)
{
ir_node
*
irn
;
ir_op
*
op
=
get_op
(
factory
,
cls
,
node_kind_perm
)
->
op
;
be_op_t
*
bop
=
get_op
(
factory
,
cls
,
node_kind_perm
);
ir_op
*
op
=
bop
->
op
;
irn
=
new_ir_node
(
NULL
,
irg
,
bl
,
op
,
mode_T
,
arity
,
in
);
init_node_attr
(
irn
,
factory
,
arity
);
init_node_attr
(
irn
,
bop
,
cls
,
arity
);
return
irn
;
}
...
...
@@ -183,12 +288,13 @@ ir_node *new_Copy(const be_node_factory_t *factory,
ir_graph
*
irg
,
ir_node
*
bl
,
ir_node
*
in
)
{
ir_node
*
irn
,
*
ins
[
1
];
ir_op
*
op
=
get_op
(
factory
,
cls
,
node_kind_copy
)
->
op
;
be_op_t
*
bop
=
get_op
(
factory
,
cls
,
node_kind_copy
);
ir_op
*
op
=
bop
->
op
;
ins
[
0
]
=
in
;
irn
=
new_ir_node
(
NULL
,
irg
,
bl
,
op
,
get_irn_mode
(
in
),
1
,
ins
);
init_node_attr
(
irn
,
factory
,
1
);
init_node_attr
(
irn
,
bop
,
cls
,
1
);
return
irn
;
}
...
...
@@ -228,7 +334,7 @@ ir_node *be_reload(const be_node_factory_t *factory,
ir_node
*
bl
=
get_nodes_block
(
irn
);
ir_graph
*
irg
=
get_irn_irg
(
bl
);
assert
(
is_Spill
(
factory
,
spill
)
assert
(
is_Spill
(
spill
)
||
(
is_Phi
(
spill
)
&&
get_irn_mode
(
spill
)
==
mode_M
));
reload
=
new_Reload
(
factory
,
cls
,
irg
,
bl
,
mode
,
spill
);
...
...
@@ -238,6 +344,17 @@ ir_node *be_reload(const be_node_factory_t *factory,
return
reload
;
}
static
INLINE
arch_register_req_t
*
get_Perm_reqs
(
ir_node
*
perm
)
{
be_node_attr_t
*
attr
=
(
be_node_attr_t
*
)
&
perm
->
attr
;
char
*
ptr
=
(
char
*
)
&
perm
->
attr
;
ptr
+=
sizeof
(
be_node_attr_t
);
ptr
+=
sizeof
(
arch_register_t
*
)
*
attr
->
n_regs
;
return
(
arch_register_req_t
*
)
ptr
;
}
/**
* If the node is a proj, reset the node to the proj's target and return
* the proj number.
...
...
@@ -267,32 +384,60 @@ be_node_get_irn_reg_req(const arch_irn_ops_t *_self,
const
be_node_factory_t
*
factory
=
container_of
(
_self
,
const
be_node_factory_t
,
irn_ops
);
/* We cannot get output requirements for tuple nodes. */
if
(
get_irn_mode
(
irn
)
==
mode_T
&&
pos
<
0
)
return
NULL
;
/*
* were interested in an output operand, so
* let's resolve projs.
* if we're interested in an output operand (pos < 0), so let's resolve projs.
*/
if
(
pos
<
0
)
pos
=
redir_proj
((
const
ir_node
**
)
&
irn
,
pos
);
/* look if the node is one of ours. */
bo
=
pmap_get
(
factory
->
irn_op_map
,
get_irn_op
(
irn
));
if
(
bo
)
{
int
i
;
req
->
type
=
arch_register_req_type_normal
;
req
->
cls
=
bo
->
cls
;
for
(
i
=
0
;
i
<
bo
->
n_pos
;
++
i
)
{
if
(
pos
==
bo
->
pos
[
i
])
{
/* be nodes have no input constraints.
so return normal register requirements. */
if
(
pos
>=
0
)
{
req
->
cls
=
bo
->
cls
;
req
->
type
=
arch_register_req_type_normal
;
}
/*
* if an output requirement is requested,
* return the one stored in the node.
*/
else
{
be_node_attr_t
*
attr
=
(
be_node_attr_t
*
)
&
irn
->
attr
;
*
req
=
attr
->
reg_data
[
pos
].
req
;
}
for
(
i
=
0
;
i
<
bo
->
n_pos
;
++
i
)
if
(
pos
==
bo
->
pos
[
i
])
return
req
;
}
}
}
return
NULL
;
}
void
be_set_Perm_out_req
(
ir_node
*
irn
,
int
pos
,
const
arch_register_req_t
*
req
)
{
be_op_t
*
bo
;
be_node_attr_t
*
a
=
get_attr_and_check
(
irn
,
node_kind_perm
);
assert
(
pos
>=
0
&&
pos
<
get_irn_arity
(
irn
)
&&
"position out of range"
);
assert
(
a
->
op
->
kind
==
node_kind_perm
&&
"node must be a perm node"
);
a
->
reg_data
[
pos
].
req
=
*
req
;
}
void
be_node_set_irn_reg
(
const
arch_irn_ops_t
*
_self
,
ir_node
*
irn
,
const
arch_register_t
*
reg
)
...
...
@@ -303,7 +448,7 @@ be_node_set_irn_reg(const arch_irn_ops_t *_self, ir_node *irn,
const
be_node_factory_t
*
factory
=
container_of
(
_self
,
const
be_node_factory_t
,
irn_ops
);
if
(
get_irn_mode
(
irn
)
==
mode_T
&&
pos
<
0
)
if
(
get_irn_mode
(
irn
)
==
mode_T
)
return
;
pos
=
redir_proj
((
const
ir_node
**
)
&
irn
,
-
1
);
...
...
@@ -313,7 +458,7 @@ be_node_set_irn_reg(const arch_irn_ops_t *_self, ir_node *irn,
return
;
attr
=
(
be_node_attr_t
*
)
&
irn
->
attr
;
attr
->
reg
[
-
pos
-
1
]
=
reg
;
attr
->
reg
_data
[
-
pos
-
1
]
.
reg
=
reg
;
}
const
arch_register_t
*
...
...
@@ -324,7 +469,7 @@ be_node_get_irn_reg(const arch_irn_ops_t *_self, const ir_node *irn)
const
be_node_factory_t
*
factory
=
container_of
(
_self
,
const
be_node_factory_t
,
irn_ops
);
if
(
get_irn_mode
(
irn
)
==
mode_T
&&
pos
<
0
)
if
(
get_irn_mode
(
irn
)
==
mode_T
)
return
NULL
;
pos
=
redir_proj
((
const
ir_node
**
)
&
irn
,
-
1
);
...
...
@@ -336,7 +481,7 @@ be_node_get_irn_reg(const arch_irn_ops_t *_self, const ir_node *irn)
for
(
i
=
0
;
i
<
bo
->
n_pos
;
++
i
)
{
if
(
bo
->
pos
[
i
]
==
pos
)
{
be_node_attr_t
*
attr
=
(
be_node_attr_t
*
)
&
irn
->
attr
;
return
attr
->
reg
[
-
pos
-
1
];
return
attr
->
reg
_data
[
-
pos
-
1
]
.
reg
;
}
}
...
...
@@ -390,11 +535,14 @@ const arch_irn_handler_t *be_node_get_irn_handler(const be_node_factory_t *f)
return
&
f
->
handler
;
}
int
is_Spill
(
const
be_node_factory_t
*
f
,
const
ir_node
*
irn
)
int
is_Spill
(
const
ir_node
*
irn
)
{
be_op_t
*
bo
;
bo
=
pmap_get
(
f
->
irn_op_map
,
get_irn_op
(
irn
));
return
bo
!=
NULL
&&
bo
->
kind
==
node_kind_spill
;
return
is_be_kind
(
irn
,
node_kind_spill
);
}
int
is_Perm
(
const
ir_node
*
irn
)
{
return
is_be_kind
(
irn
,
node_kind_perm
);
}
be_node_factory_t
*
be_node_factory_init
(
be_node_factory_t
*
factory
,
const
arch_isa_t
*
isa
)
...
...
@@ -441,7 +589,8 @@ be_node_factory_t *be_node_factory_init(be_node_factory_t *factory, const arch_i
ent
=
get_op
(
factory
,
cls
,
node_kind_perm
);
ent
->
op
=
new_ir_op
(
get_next_ir_opcode
(),
"Perm"
,
op_pin_state_pinned
,
0
,
oparity_variable
,
0
,
sizeof
(
be_node_attr_t
)
+
sizeof
(
arch_register_t
)
*
cls
->
n_regs
,
&
be_node_ops
);
sizeof
(
be_node_attr_t
)
+
sizeof
(
be_reg_data_t
)
*
cls
->
n_regs
,
&
be_node_ops
);
ent
->
n_pos
=
2
*
cls
->
n_regs
;
ent
->
pos
=
obstack_alloc
(
&
factory
->
obst
,
sizeof
(
ent
->
pos
[
0
])
*
ent
->
n_pos
);
for
(
j
=
0
;
j
<
ent
->
n_pos
;
j
+=
2
)
{
...
...
@@ -458,11 +607,13 @@ be_node_factory_t *be_node_factory_init(be_node_factory_t *factory, const arch_i
static
int
dump_node
(
ir_node
*
irn
,
FILE
*
f
,
dump_reason_t
reason
)
{
be_node_attr_t
*
attr
=
(
be_node_attr_t
*
)
&
irn
->
attr
;
be_op_t
*
bo
=
pmap_get
(
attr
->
factory
->
irn_op_map
,
get_irn_op
(
irn
));
be_node_attr_t
*
at
=
(
be_node_attr_t
*
)
&
irn
->
attr
;
const
be_op_t
*
bo
;
int
i
;
assert
(
is_be_node
(
irn
));