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
83bf742e
Commit
83bf742e
authored
Aug 09, 2010
by
Matthias Braun
Browse files
allow ignore registers as inputs of Phis; cleanup bessadestr.c
[r27909]
parent
67359026
Changes
3
Hide whitespace changes
Inline
Side-by-side
ir/be/bearch.h
View file @
83bf742e
...
...
@@ -842,7 +842,7 @@ static inline void arch_set_out_register_req(ir_node *node, int pos,
* are not marked as ignore.
* Executes @p code for each definition.
*/
#define be_foreach_definition(node, cls, value, code)
\
#define be_foreach_definition
_
(node, cls, value, code) \
do { \
if (get_irn_mode(node) == mode_T) { \
const ir_edge_t *edge_; \
...
...
@@ -852,18 +852,22 @@ static inline void arch_set_out_register_req(ir_node *node, int pos,
req_ = arch_get_register_req_out(value); \
if (req_->cls != cls) \
continue; \
if (req_->type & arch_register_req_type_ignore) \
continue; \
code \
} \
} else { \
const arch_register_req_t *req_ = arch_get_register_req_out(node); \
value = node; \
if (req_->cls == cls \
&& !(req_->type & arch_register_req_type_ignore)) { \
if (req_->cls == cls) { \
code \
} \
} \
} while (0)
#define be_foreach_definition(node, cls, value, code) \
be_foreach_definition_(node, cls, value, \
if (req_->type & arch_register_req_type_ignore) \
continue; \
code \
)
#endif
ir/be/beprefalloc.c
View file @
83bf742e
...
...
@@ -368,8 +368,9 @@ static void analyze_block(ir_node *block, void *data)
info
=
get_allocation_info
(
node
);
for
(
i
=
0
;
i
<
arity
;
++
i
)
{
ir_node
*
op
=
get_irn_n
(
node
,
i
);
if
(
!
arch_irn_consider_in_reg_alloc
(
cls
,
op
))
ir_node
*
op
=
get_irn_n
(
node
,
i
);
const
arch_register_req_t
*
req
=
arch_get_register_req_out
(
op
);
if
(
req
->
cls
!=
cls
)
continue
;
/* last usage of a value? */
...
...
@@ -767,8 +768,6 @@ static void assign_reg(const ir_node *block, ir_node *node,
unsigned
r
;
assert
(
!
is_Phi
(
node
));
assert
(
arch_irn_consider_in_reg_alloc
(
cls
,
node
));
/* preassigned register? */
reg
=
arch_get_irn_register
(
node
);
if
(
reg
!=
NULL
)
{
...
...
@@ -777,10 +776,12 @@ static void assign_reg(const ir_node *block, ir_node *node,
return
;
}
/* give should_be_same boni */
info
=
get_allocation_info
(
node
);
req
=
arch_
get_
register_req_
out
(
node
);
req
=
arch_get_register_req_out
(
node
);
/* ignore reqs must be preassigned */
assert
(
!
(
req
->
type
&
arch_register_req_
type_ignore
)
);
/* give should_be_same boni */
info
=
get_allocation_info
(
node
);
in_node
=
skip_Proj
(
node
);
if
(
req
->
type
&
arch_register_req_type_should_be_same
)
{
float
weight
=
(
float
)
get_block_execfreq
(
execfreqs
,
block
);
...
...
@@ -1042,10 +1043,10 @@ static void permute_values(ir_nodeset_t *live_nodes, ir_node *before,
*/
static
void
free_last_uses
(
ir_nodeset_t
*
live_nodes
,
ir_node
*
node
)
{
allocation_info_t
*
info
=
get_allocation_info
(
node
);
const
unsigned
*
last_uses
=
info
->
last_uses
;
int
arity
=
get_irn_arity
(
node
);
int
i
;
allocation_info_t
*
info
=
get_allocation_info
(
node
);
const
unsigned
*
last_uses
=
info
->
last_uses
;
int
arity
=
get_irn_arity
(
node
);
int
i
;
for
(
i
=
0
;
i
<
arity
;
++
i
)
{
ir_node
*
op
;
...
...
@@ -1301,7 +1302,7 @@ static void add_phi_permutations(ir_node *block, int p)
unsigned
*
permutation
;
ir_node
**
old_assignments
;
bool
need_permutation
;
ir_node
*
node
;
ir_node
*
phi
;
ir_node
*
pred
=
get_Block_cfgpred_block
(
block
,
p
);
block_info_t
*
pred_info
=
get_block_info
(
pred
);
...
...
@@ -1317,29 +1318,36 @@ static void add_phi_permutations(ir_node *block, int p)
/* check phi nodes */
need_permutation
=
false
;
node
=
sched_first
(
block
);
for
(
;
is_Phi
(
node
);
node
=
sched_next
(
node
))
{
phi
=
sched_first
(
block
);
for
(
;
is_Phi
(
phi
);
phi
=
sched_next
(
phi
))
{
const
arch_register_t
*
reg
;
const
arch_register_t
*
op_reg
;
int
regn
;
int
a
;
ir_node
*
op
;
if
(
!
arch_irn_consider_in_reg_alloc
(
cls
,
node
))
continue
;
op
=
get_Phi_pred
(
node
,
p
);
if
(
!
arch_irn_consider_in_reg_alloc
(
cls
,
op
))
if
(
!
arch_irn_consider_in_reg_alloc
(
cls
,
phi
))
continue
;
a
=
find_value_in_block_info
(
pred_info
,
op
);
op
=
get_Phi_pred
(
phi
,
p
);
a
=
find_value_in_block_info
(
pred_info
,
op
);
assert
(
a
>=
0
);
reg
=
arch_get_irn_register
(
node
);
reg
=
arch_get_irn_register
(
phi
);
regn
=
arch_register_get_index
(
reg
);
if
(
regn
!=
a
)
{
permutation
[
regn
]
=
a
;
need_permutation
=
true
;
}
/* same register? nothing to do */
if
(
regn
==
a
)
continue
;
op
=
pred_info
->
assignments
[
a
];
op_reg
=
arch_get_irn_register
(
op
);
/* virtual or joker registers are ok too */
if
((
op_reg
->
type
&
arch_register_type_joker
)
||
(
op_reg
->
type
&
arch_register_type_virtual
))
continue
;
permutation
[
regn
]
=
a
;
need_permutation
=
true
;
}
if
(
need_permutation
)
{
...
...
@@ -1347,30 +1355,27 @@ static void add_phi_permutations(ir_node *block, int p)
old_assignments
=
assignments
;
assignments
=
pred_info
->
assignments
;
permute_values
(
NULL
,
be_get_end_of_block_insertion_point
(
pred
),
permutation
);
permutation
);
assignments
=
old_assignments
;
}
/* change phi nodes to use the copied values */
node
=
sched_first
(
block
);
for
(
;
is_Phi
(
node
);
node
=
sched_next
(
node
))
{
phi
=
sched_first
(
block
);
for
(
;
is_Phi
(
phi
);
phi
=
sched_next
(
phi
))
{
int
a
;
ir_node
*
op
;
if
(
!
arch_irn_consider_in_reg_alloc
(
cls
,
node
))
if
(
!
arch_irn_consider_in_reg_alloc
(
cls
,
phi
))
continue
;
op
=
get_Phi_pred
(
node
,
p
);
/* no need to do anything for Unknown inputs */
if
(
!
arch_irn_consider_in_reg_alloc
(
cls
,
op
))
continue
;
op
=
get_Phi_pred
(
phi
,
p
);
/* we have permuted all values into the correct registers so we can
simply query which value occupies the phis register in the
predecessor */
a
=
arch_register_get_index
(
arch_get_irn_register
(
node
));
a
=
arch_register_get_index
(
arch_get_irn_register
(
phi
));
op
=
pred_info
->
assignments
[
a
];
set_Phi_pred
(
node
,
p
,
op
);
set_Phi_pred
(
phi
,
p
,
op
);
}
}
...
...
@@ -1536,14 +1541,14 @@ static void assign_phi_registers(ir_node *block)
*/
static
void
allocate_coalesce_block
(
ir_node
*
block
,
void
*
data
)
{
int
i
;
ir_nodeset_t
live_nodes
;
ir_node
*
node
;
int
n_preds
;
block_info_t
*
block_info
;
block_info_t
**
pred_block_infos
;
ir_node
**
phi_ins
;
unsigned
*
forbidden_regs
;
/**< collects registers which must
int
i
;
ir_nodeset_t
live_nodes
;
ir_node
*
node
;
int
n_preds
;
block_info_t
*
block_info
;
block_info_t
**
pred_block_infos
;
ir_node
**
phi_ins
;
unsigned
*
forbidden_regs
;
/**< collects registers which must
not be used for optimistic splits */
(
void
)
data
;
...
...
@@ -1556,8 +1561,8 @@ static void allocate_coalesce_block(ir_node *block, void *data)
ir_nodeset_init
(
&
live_nodes
);
/* gather regalloc infos of predecessor blocks */
n_preds
=
get_Block_n_cfgpreds
(
block
);
pred_block_infos
=
ALLOCAN
(
block_info_t
*
,
n_preds
);
n_preds
=
get_Block_n_cfgpreds
(
block
);
pred_block_infos
=
ALLOCAN
(
block_info_t
*
,
n_preds
);
for
(
i
=
0
;
i
<
n_preds
;
++
i
)
{
ir_node
*
pred
=
get_Block_cfgpred_block
(
block
,
i
);
block_info_t
*
pred_info
=
get_block_info
(
pred
);
...
...
@@ -1568,14 +1573,26 @@ static void allocate_coalesce_block(ir_node *block, void *data)
/* collect live-in nodes and preassigned values */
be_lv_foreach
(
lv
,
block
,
be_lv_state_in
,
i
)
{
const
arch_register_t
*
reg
;
int
p
;
bool
need_phi
=
false
;
bool
need_phi
=
false
;
const
arch_register_req_t
*
req
;
const
arch_register_t
*
reg
;
int
p
;
node
=
be_lv_get_irn
(
lv
,
block
,
i
);
if
(
!
arch_irn_consider_in_reg_alloc
(
cls
,
node
))
req
=
arch_get_register_req_out
(
node
);
if
(
req
->
cls
!=
cls
)
continue
;
if
(
req
->
type
&
arch_register_req_type_ignore
)
{
allocation_info_t
*
info
=
get_allocation_info
(
node
);
info
->
current_value
=
node
;
reg
=
arch_get_irn_register
(
node
);
assert
(
reg
!=
NULL
);
/* ignore values must be preassigned */
use_reg
(
node
,
reg
);
continue
;
}
/* check all predecessors for this value, if it is not everywhere the
same or unknown then we have to construct a phi
(we collect the potential phi inputs here) */
...
...
@@ -1691,8 +1708,7 @@ static void allocate_coalesce_block(ir_node *block, void *data)
free_last_uses
(
&
live_nodes
,
node
);
/* assign output registers */
/* TODO: 2 phases: first: pre-assigned ones, 2nd real regs */
be_foreach_definition
(
node
,
cls
,
value
,
be_foreach_definition_
(
node
,
cls
,
value
,
assign_reg
(
block
,
value
,
forbidden_regs
);
);
}
...
...
ir/be/bessadestr.c
View file @
83bf742e
...
...
@@ -137,13 +137,9 @@ static void insert_all_perms_walker(ir_node *bl, void *data)
*/
for
(
phi
=
get_irn_link
(
bl
);
phi
;
phi
=
get_irn_link
(
phi
))
{
ir_node
*
arg
=
get_irn_n
(
phi
,
i
);
const
arch_register_req_t
*
req
=
arch_get_register_req_out
(
arg
);
unsigned
hash
;
perm_proj_t
templ
;
if
(
req
->
type
&
arch_register_req_type_ignore
)
continue
;
hash
=
hash_irn
(
arg
);
templ
.
arg
=
arg
;
pp
=
set_find
(
arg_set
,
&
templ
,
sizeof
(
templ
),
hash
);
...
...
@@ -251,13 +247,9 @@ static void set_regs_or_place_dupls_walker(ir_node *bl, void *data)
/* process all arguments of the phi */
for
(
i
=
0
,
max
=
get_irn_arity
(
phi
);
i
<
max
;
++
i
)
{
ir_node
*
arg
=
get_irn_n
(
phi
,
i
);
const
arch_register_req_t
*
req
=
arch_get_register_req_out
(
arg
);
const
arch_register_t
*
arg_reg
;
ir_node
*
arg_block
;
if
(
req
->
type
&
arch_register_req_type_ignore
)
continue
;
arg_block
=
get_Block_cfgpred_block
(
phi_block
,
i
);
arg_reg
=
get_reg
(
arg
);
...
...
@@ -265,6 +257,15 @@ static void set_regs_or_place_dupls_walker(ir_node *bl, void *data)
DBG
((
dbg
,
LEVEL_1
,
" for %+F(%s) -- %+F(%s)
\n
"
,
phi
,
phi_reg
->
name
,
arg
,
arg_reg
->
name
));
if
(
phi_reg
==
arg_reg
||
(
arg_reg
->
type
&
arch_register_type_joker
)
||
(
arg_reg
->
type
&
arch_register_type_virtual
))
{
/* Phi and arg have the same register, so pin and continue */
pin_irn
(
arg
,
phi_block
);
DBG
((
dbg
,
LEVEL_1
,
" arg has same reg: pin %+F(%s)
\n
"
,
arg
,
get_reg
(
arg
)
->
name
));
continue
;
}
if
(
be_values_interfere
(
lv
,
phi
,
arg
))
{
/*
Insert a duplicate in arguments block,
...
...
@@ -275,19 +276,6 @@ static void set_regs_or_place_dupls_walker(ir_node *bl, void *data)
*/
ir_node
*
dupl
=
be_new_Copy
(
cls
,
arg_block
,
arg
);
/* this is commented out because it will fail in case of unknown float */
#if 0
ir_mode *m_phi = get_irn_mode(phi), *m_dupl = get_irn_mode(dupl);
/*
Conv signed <-> unsigned is killed on ia32
check for: (both int OR both float) AND equal mode sizes
*/
assert(((mode_is_int(m_phi) && mode_is_int(m_dupl)) ||
(mode_is_float(m_phi) && mode_is_float(m_dupl))) &&
(get_mode_size_bits(m_phi) == get_mode_size_bits(m_dupl)));
#endif /* if 0 */
set_irn_n
(
phi
,
i
,
dupl
);
set_reg
(
dupl
,
phi_reg
);
sched_add_after
(
sched_skip
(
sched_last
(
arg_block
),
0
,
sched_skip_cf_predicator
,
NULL
),
dupl
);
...
...
@@ -298,13 +286,6 @@ static void set_regs_or_place_dupls_walker(ir_node *bl, void *data)
continue
;
/* with next argument */
}
if
(
phi_reg
==
arg_reg
)
{
/* Phi and arg have the same register, so pin and continue */
pin_irn
(
arg
,
phi_block
);
DBG
((
dbg
,
LEVEL_1
,
" arg has same reg: pin %+F(%s)
\n
"
,
arg
,
get_reg
(
arg
)
->
name
));
continue
;
}
DBG
((
dbg
,
LEVEL_1
,
" they do not interfere
\n
"
));
assert
(
is_Proj
(
arg
));
/*
...
...
@@ -346,20 +327,6 @@ static void set_regs_or_place_dupls_walker(ir_node *bl, void *data)
ir_node
*
dupl
=
be_new_Copy
(
cls
,
arg_block
,
arg
);
ir_node
*
ins
;
/* this is commented out because it will fail in case of unknown float */
#if 0
ir_mode *m_phi = get_irn_mode(phi);
ir_mode *m_dupl = get_irn_mode(dupl);
/*
Conv signed <-> unsigned is killed on ia32
check for: (both int OR both float) AND equal mode sizes
*/
assert(((mode_is_int(m_phi) && mode_is_int(m_dupl)) ||
(mode_is_float(m_phi) && mode_is_float(m_dupl))) &&
(get_mode_size_bits(m_phi) == get_mode_size_bits(m_dupl)));
#endif /* if 0 */
set_irn_n
(
phi
,
i
,
dupl
);
set_reg
(
dupl
,
phi_reg
);
/* skip the Perm's Projs and insert the copies behind. */
...
...
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