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
cb53b30c
Commit
cb53b30c
authored
Apr 20, 2007
by
Christian Würdig
Browse files
fixed some Bugs
[r13425]
parent
9027d4a4
Changes
1
Hide whitespace changes
Inline
Side-by-side
ir/be/becopyheur4.c
View file @
cb53b30c
...
...
@@ -71,6 +71,7 @@ typedef struct _co_mst_irn_t {
bitset_t
*
adm_colors
;
int
int_neigh
;
int
col
;
int
init_col
;
int
tmp_col
;
unsigned
fixed
:
1
;
unsigned
tmp_fixed
:
1
;
...
...
@@ -123,6 +124,36 @@ static int cmp_col_cost(const void *a, const void *b) {
return
c1
->
cost
<
c2
->
cost
?
-
1
:
1
;
}
/**
* Creates a new affinity chunk
*/
static
INLINE
aff_chunk_t
*
new_aff_chunk
(
co_mst_env_t
*
env
)
{
aff_chunk_t
*
c
=
xmalloc
(
sizeof
(
*
c
));
c
->
weight_consistent
=
0
;
c
->
nodes
=
bitset_irg_malloc
(
env
->
co
->
irg
);
pset_new_insert
(
&
env
->
chunkset
,
c
);
return
c
;
}
/**
* Frees all memory allocated by an affinity chunk.
*/
static
INLINE
void
delete_aff_chunk
(
co_mst_env_t
*
env
,
aff_chunk_t
*
c
)
{
pset_new_remove
(
&
env
->
chunkset
,
c
);
bitset_free
(
c
->
nodes
);
free
(
c
);
}
/**
* Adds a node to an affinity chunk
*/
static
INLINE
void
aff_chunk_add_node
(
aff_chunk_t
*
c
,
co_mst_irn_t
*
node
)
{
c
->
weight_consistent
=
0
;
node
->
chunk
=
c
;
bitset_set
(
c
->
nodes
,
get_irn_idx
(
node
->
irn
));
}
/**
* In case there is no phase information for irn, initialize it.
*/
...
...
@@ -136,12 +167,16 @@ static void *co_mst_irn_init(ir_phase *ph, ir_node *irn, void *old) {
ir_node
*
m
;
res
->
irn
=
irn
;
res
->
chunk
=
NULL
;
res
->
chunk
=
new_aff_chunk
(
env
)
;
res
->
fixed
=
0
;
res
->
tmp_fixed
=
0
;
res
->
tmp_col
=
-
1
;
res
->
int_neigh
=
0
;
res
->
col
=
arch_register_get_index
(
arch_get_irn_register
(
env
->
aenv
,
irn
));
res
->
init_col
=
res
->
col
;
/* add note to new chunk */
aff_chunk_add_node
(
res
->
chunk
,
res
);
/* set admissible registers */
res
->
adm_colors
=
bitset_obstack_alloc
(
phase_obst
(
ph
),
env
->
n_regs
);
...
...
@@ -165,35 +200,6 @@ static void *co_mst_irn_init(ir_phase *ph, ir_node *irn, void *old) {
return
res
;
}
/**
* Creates a new affinity chunk
*/
static
INLINE
aff_chunk_t
*
new_aff_chunk
(
co_mst_env_t
*
env
)
{
aff_chunk_t
*
c
=
xmalloc
(
sizeof
(
*
c
));
c
->
weight_consistent
=
0
;
c
->
nodes
=
bitset_irg_malloc
(
env
->
co
->
irg
);
pset_new_insert
(
&
env
->
chunkset
,
c
);
return
c
;
}
/**
* Frees all memory allocated by an affinity chunk.
*/
static
INLINE
void
delete_aff_chunk
(
co_mst_env_t
*
env
,
aff_chunk_t
*
c
)
{
pset_new_remove
(
&
env
->
chunkset
,
c
);
bitset_free
(
c
->
nodes
);
free
(
c
);
}
/**
* Adds a node to an affinity chunk
*/
static
INLINE
void
aff_chunk_add_node
(
aff_chunk_t
*
c
,
co_mst_irn_t
*
node
)
{
c
->
weight_consistent
=
0
;
node
->
chunk
=
c
;
bitset_set
(
c
->
nodes
,
get_irn_idx
(
node
->
irn
));
}
/**
* Check if there are interference edges from c1 to c2.
* @param env The global co_mst environment
...
...
@@ -225,7 +231,7 @@ static INLINE int aff_chunks_interfere(co_mst_env_t *env, aff_chunk_t *c1, aff_c
* @return 1 if successful, 0 if not possible
*/
static
INLINE
int
aff_chunk_absorb
(
co_mst_env_t
*
env
,
aff_chunk_t
*
c1
,
aff_chunk_t
*
c2
)
{
if
(
!
aff_chunks_interfere
(
env
,
c1
,
c2
))
{
if
(
!
aff_chunks_interfere
(
env
,
c1
,
c2
)
&&
c1
!=
c2
)
{
int
idx
;
bitset_or
(
c1
->
nodes
,
c2
->
nodes
);
...
...
@@ -247,14 +253,9 @@ static INLINE int aff_chunk_absorb(co_mst_env_t *env, aff_chunk_t *c1, aff_chunk
* Returns the affinity chunk of @p irn or creates a new
* one with @p irn as element if there is none assigned.
*/
static
INLINE
aff_chunk_t
*
get_
or_set_
aff_chunk
(
co_mst_env_t
*
env
,
ir_node
*
irn
)
{
static
INLINE
aff_chunk_t
*
get_aff_chunk
(
co_mst_env_t
*
env
,
ir_node
*
irn
)
{
co_mst_irn_t
*
node
=
get_co_mst_irn
(
env
,
irn
);
if
(
node
->
chunk
==
NULL
)
{
node
->
chunk
=
new_aff_chunk
(
env
);
aff_chunk_add_node
(
node
->
chunk
,
node
);
}
assert
(
node
->
chunk
&&
"Node should have a chunk."
);
return
node
->
chunk
;
}
...
...
@@ -353,8 +354,8 @@ static void build_affinity_chunks(co_mst_env_t *env) {
/* now: sort edges and build the affinity chunks */
qsort
(
edges
,
ARR_LEN
(
edges
),
sizeof
(
edges
[
0
]),
cmp_aff_edge
);
for
(
i
=
0
;
i
<
ARR_LEN
(
edges
);
++
i
)
{
aff_chunk_t
*
c1
=
get_
or_set_
aff_chunk
(
env
,
edges
[
i
].
src
);
aff_chunk_t
*
c2
=
get_
or_set_
aff_chunk
(
env
,
edges
[
i
].
tgt
);
aff_chunk_t
*
c1
=
get_aff_chunk
(
env
,
edges
[
i
].
src
);
aff_chunk_t
*
c2
=
get_aff_chunk
(
env
,
edges
[
i
].
tgt
);
(
void
)
aff_chunk_absorb
(
env
,
c1
,
c2
);
}
...
...
@@ -441,6 +442,7 @@ static aff_chunk_t *fragment_chunk(co_mst_env_t *env, int col, aff_chunk_t *c, w
co_mst_irn_t
*
node
;
aff_chunk_t
*
tmp_chunk
;
decide_func_t
*
decider
;
int
check_for_best
;
if
(
bitset_is_set
(
visited
,
idx
))
continue
;
...
...
@@ -448,16 +450,24 @@ static aff_chunk_t *fragment_chunk(co_mst_env_t *env, int col, aff_chunk_t *c, w
irn
=
get_idx_irn
(
env
->
co
->
irg
,
idx
);
node
=
get_co_mst_irn
(
env
,
irn
);
if
(
get_mst_irn_col
(
node
)
==
col
)
{
decider
=
decider_has_color
;
check_for_best
=
1
;
}
else
{
decider
=
decider_hasnot_color
;
check_for_best
=
0
;
}
/* create a new chunk starting at current node */
tmp_chunk
=
new_aff_chunk
(
env
);
waitq_put
(
tmp
,
tmp_chunk
);
decider
=
get_mst_irn_col
(
node
)
==
col
?
decider_has_color
:
decider_hasnot_color
;
expand_chunk_from
(
env
,
node
,
visited
,
tmp_chunk
,
c
,
decider
,
col
);
assert
(
bitset_popcnt
(
tmp_chunk
->
nodes
)
>
0
&&
"No nodes added to chunk"
);
/* remember the local best */
aff_chunk_assure_weight
(
env
,
tmp_chunk
);
if
(
!
best
||
best
->
weight
<
tmp_chunk
->
weight
)
if
(
check_for_best
&&
(
!
best
||
best
->
weight
<
tmp_chunk
->
weight
)
)
best
=
tmp_chunk
;
}
...
...
@@ -745,9 +755,6 @@ static void color_aff_chunk(co_mst_env_t *env, aff_chunk_t *c) {
aff_chunk_assure_weight
(
env
,
local_best
);
if
(
!
best_chunk
||
best_chunk
->
weight
<
local_best
->
weight
)
{
/* kill the old best */
if
(
best_chunk
)
delete_aff_chunk
(
env
,
best_chunk
);
best_chunk
=
local_best
;
best_color
=
col
;
}
...
...
@@ -795,6 +802,13 @@ static void color_aff_chunk(co_mst_env_t *env, aff_chunk_t *c) {
/* remove the nodes in best chunk from original chunk */
bitset_andnot
(
c
->
nodes
,
best_chunk
->
nodes
);
/* we have to get the nodes back into the original chunk because they are scattered over temporary chunks */
bitset_foreach
(
c
->
nodes
,
idx
)
{
ir_node
*
n
=
get_idx_irn
(
env
->
co
->
irg
,
idx
);
co_mst_irn_t
*
nn
=
get_co_mst_irn
(
env
,
n
);
nn
->
chunk
=
c
;
}
/* fragment the remaining chunk */
visited
=
bitset_irg_malloc
(
env
->
co
->
irg
);
bitset_or
(
visited
,
best_chunk
->
nodes
);
...
...
@@ -825,6 +839,7 @@ int co_solve_heuristic_mst(copy_opt_t *co)
unsigned
n_regs
=
co
->
cenv
->
cls
->
n_regs
;
bitset_t
*
ignore_regs
=
bitset_alloca
(
n_regs
);
unsigned
k
;
ir_node
*
irn
;
co_mst_env_t
mst_env
;
memset
(
&
mst_env
,
0
,
sizeof
(
mst_env
));
...
...
@@ -853,6 +868,18 @@ int co_solve_heuristic_mst(copy_opt_t *co)
color_aff_chunk
(
&
mst_env
,
chunk
);
}
/* apply coloring */
foreach_phase_irn
(
&
mst_env
.
ph
,
irn
)
{
co_mst_irn_t
*
mirn
=
get_co_mst_irn
(
&
mst_env
,
irn
);
const
arch_register_t
*
reg
;
assert
(
mirn
->
fixed
&&
"Node should have fixed color"
);
reg
=
arch_register_for_index
(
co
->
cenv
->
cls
,
mirn
->
col
);
arch_set_irn_register
(
co
->
aenv
,
irn
,
reg
);
ir_printf
(
"%+F set color from %d to %d
\n
"
,
irn
,
mirn
->
init_col
,
mirn
->
col
);
}
/* free allocated memory */
del_pqueue
(
mst_env
.
chunks
);
phase_free
(
&
mst_env
.
ph
);
...
...
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