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
e1fa42e4
Commit
e1fa42e4
authored
May 26, 2014
by
Matthias Braun
Browse files
cleanup, use C99
parent
8dda77c8
Changes
1
Hide whitespace changes
Inline
Side-by-side
ir/be/becopyheur4.c
View file @
e1fa42e4
...
...
@@ -57,42 +57,43 @@ static firm_dbg_module_t *dbg = NULL;
typedef
float
real_t
;
#define REAL(C) (C ## f)
static
unsigned
last_chunk_id
=
0
;
static
int
recolor_limit
=
7
;
static
double
dislike_influence
=
REAL
(
0
.
1
);
static
unsigned
last_chunk_id
;
static
int
recolor_limit
=
7
;
static
double
dislike_influence
=
REAL
(
0
.
1
);
typedef
struct
col_cost_t
{
int
col
;
real_t
cost
;
unsigned
col
;
real_t
cost
;
}
col_cost_t
;
/**
* An affinity chunk.
*/
typedef
struct
aff_chunk_t
{
const
ir_node
**
n
;
/**< An ARR_F containing all nodes of the chunk. */
const
ir_node
**
interfere
;
/**< An ARR_F containing all inference. */
int
weight
;
/**< Weight of this chunk */
unsigned
weight_consistent
:
1
;
/**< Set if the weight is consistent. */
unsigned
deleted
:
1
;
/**< For debugging: Set if the was deleted. */
unsigned
id
;
/**< An id of this chunk. */
unsigned
visited
;
list_head
list
;
col_cost_t
color_affinity
[
1
];
const
ir_node
**
n
;
/**< An ARR_F containing all nodes of the chunk. */
const
ir_node
**
interfere
;
/**< An ARR_F containing all inference. */
int
weight
;
/**< Weight of this chunk */
unsigned
id
;
/**< An id of this chunk. */
unsigned
visited
;
list_head
list
;
bool
weight_consistent
:
1
;
/**< Set if the weight is consistent. */
#ifndef NDEBUG
bool
deleted
:
1
;
/**< For debugging: Set if the was deleted. */
#endif
col_cost_t
color_affinity
[];
}
aff_chunk_t
;
/**
* An affinity edge.
*/
typedef
struct
aff_edge_t
{
const
ir_node
*
src
;
/**< Source node. */
const
ir_node
*
tgt
;
/**< Target node. */
int
weight
;
/**< The weight of this edge. */
const
ir_node
*
src
;
/**< Source node. */
const
ir_node
*
tgt
;
/**< Target node. */
int
weight
;
/**< The weight of this edge. */
}
aff_edge_t
;
/* main coalescing environment */
typedef
struct
co_mst_env_t
{
int
n_regs
;
/**< number of regs in class */
bitset_t
const
*
allocatable_regs
;
/**< set containing all global ignore registers */
ir_nodemap
map
;
/**< phase object holding data for nodes */
struct
obstack
obst
;
...
...
@@ -100,24 +101,25 @@ typedef struct co_mst_env_t {
list_head
chunklist
;
/**< list holding all chunks */
be_ifg_t
*
ifg
;
/**< the interference graph */
copy_opt_t
*
co
;
/**< the copy opt object */
unsigned
chunk_visited
;
col_cost_t
**
single_cols
;
unsigned
n_regs
;
/**< number of regs in class */
unsigned
chunk_visited
;
}
co_mst_env_t
;
/* stores coalescing related information for a node */
typedef
struct
co_mst_irn_t
{
const
ir_node
*
irn
;
/**< the irn this information belongs to */
aff_chunk_t
*
chunk
;
/**< the chunk this irn belongs to */
bitset_t
*
adm_colors
;
/**< set of admissible colors for this irn */
ir_node
**
int_neighs
;
/**< array of all interfering neighbours (cached for speed reasons) */
int
n_neighs
;
/**< length of the interfering neighbours array. */
int
int_aff_neigh
;
/**< number of interfering affinity neighbours */
int
col
;
/**< color currently assigned */
int
init_col
;
/**< the initial color */
int
tmp_col
;
/**< a temporary assigned color */
unsigned
fixed
:
1
;
/**< the color is fixed */
struct
list_head
list
;
/**< Queue for coloring undo. */
const
ir_node
*
irn
;
/**< the irn this information belongs to */
aff_chunk_t
*
chunk
;
/**< the chunk this irn belongs to */
bitset_t
*
adm_colors
;
/**< set of admissible colors for this irn */
ir_node
**
int_neighs
;
/**< array of all interfering neighbours (cached for speed reasons) */
unsigned
n_neighs
;
/**< length of the interfering neighbours array. */
int
int_aff_neigh
;
/**< number of interfering affinity neighbours */
unsigned
col
;
/**< color currently assigned */
unsigned
init_col
;
/**< the initial color */
int
tmp_col
;
/**< a temporary assigned color */
struct
list_head
list
;
/**< Queue for coloring undo. */
real_t
constr_factor
;
bool
fixed
:
1
;
/**< the color is fixed */
}
co_mst_irn_t
;
/**
...
...
@@ -177,7 +179,7 @@ static co_mst_irn_t *get_co_mst_irn(co_mst_env_t *env, const ir_node *node)
return
res
;
}
typedef
int
decide_func_t
(
const
co_mst_irn_t
*
node
,
int
col
);
typedef
bool
decide_func_t
(
const
co_mst_irn_t
*
node
,
unsigned
col
);
#ifdef DEBUG_libfirm
...
...
@@ -186,12 +188,11 @@ typedef int decide_func_t(const co_mst_irn_t *node, int col);
*/
static
void
dbg_aff_chunk
(
const
co_mst_env_t
*
env
,
const
aff_chunk_t
*
c
)
{
int
i
,
l
;
(
void
)
env
;
(
void
)
env
;
if
(
c
->
weight_consistent
)
ir_fprintf
(
stderr
,
" $%d "
,
c
->
weight
);
ir_fprintf
(
stderr
,
"{"
);
for
(
i
=
0
,
l
=
ARR_LEN
(
c
->
n
);
i
<
l
;
++
i
)
{
for
(
size_t
i
=
0
,
l
=
ARR_LEN
(
c
->
n
);
i
<
l
;
++
i
)
{
const
ir_node
*
n
=
c
->
n
[
i
];
ir_fprintf
(
stderr
,
" %+F,"
,
n
);
}
...
...
@@ -201,10 +202,10 @@ static void dbg_aff_chunk(const co_mst_env_t *env, const aff_chunk_t *c)
/**
* Dump all admissible colors to stderr.
*/
static
void
dbg_admissible_colors
(
const
co_mst_env_t
*
env
,
const
co_mst_irn_t
*
node
)
static
void
dbg_admissible_colors
(
const
co_mst_env_t
*
env
,
const
co_mst_irn_t
*
node
)
{
(
void
)
env
;
(
void
)
env
;
if
(
bitset_popcount
(
node
->
adm_colors
)
<
1
)
{
fprintf
(
stderr
,
"no admissible colors?!?"
);
}
else
{
...
...
@@ -219,30 +220,29 @@ static void dbg_admissible_colors(const co_mst_env_t *env, const co_mst_irn_t *n
*/
static
void
dbg_col_cost
(
const
co_mst_env_t
*
env
,
const
col_cost_t
*
cost
)
{
int
i
;
for
(
i
=
0
;
i
<
env
->
n_regs
;
++
i
)
fprintf
(
stderr
,
" (%d, %.4f)"
,
cost
[
i
].
col
,
cost
[
i
].
cost
);
for
(
unsigned
i
=
0
,
n
=
env
->
n_regs
;
i
<
n
;
++
i
)
fprintf
(
stderr
,
" (%u, %.4f)"
,
cost
[
i
].
col
,
cost
[
i
].
cost
);
}
#endif
/* DEBUG_libfirm */
static
inline
int
get_mst_irn_col
(
const
co_mst_irn_t
*
node
)
static
inline
unsigned
get_mst_irn_col
(
const
co_mst_irn_t
*
node
)
{
return
node
->
tmp_col
>=
0
?
node
->
tmp_col
:
node
->
col
;
return
node
->
tmp_col
>=
0
?
(
unsigned
)
node
->
tmp_col
:
node
->
col
;
}
/**
* @return
1
if node @p node has color @p col,
0
otherwise.
* @return
true
if node @p node has color @p col,
false
otherwise.
*/
static
int
decider_has_color
(
const
co_mst_irn_t
*
node
,
int
col
)
static
bool
decider_has_color
(
const
co_mst_irn_t
*
node
,
unsigned
col
)
{
return
get_mst_irn_col
(
node
)
==
col
;
}
/**
* @return
1
if node @p node has not color @p col,
0
otherwise.
* @return
true
if node @p node has not color @p col,
false
otherwise.
*/
static
int
decider_hasnot_color
(
const
co_mst_irn_t
*
node
,
int
col
)
static
bool
decider_hasnot_color
(
const
co_mst_irn_t
*
node
,
unsigned
col
)
{
return
get_mst_irn_col
(
node
)
!=
col
;
}
...
...
@@ -250,11 +250,11 @@ static int decider_hasnot_color(const co_mst_irn_t *node, int col)
/**
* Always returns true.
*/
static
int
decider_always_yes
(
const
co_mst_irn_t
*
node
,
int
col
)
static
bool
decider_always_yes
(
const
co_mst_irn_t
*
node
,
unsigned
col
)
{
(
void
)
node
;
(
void
)
col
;
return
1
;
(
void
)
node
;
(
void
)
col
;
return
true
;
}
/** compares two affinity edges by its weight */
...
...
@@ -276,9 +276,9 @@ static int cmp_aff_edge(const void *a, const void *b)
/** compares to color-cost pairs */
static
__attribute__
((
unused
))
int
cmp_col_cost_lt
(
const
void
*
a
,
const
void
*
b
)
{
const
col_cost_t
*
c1
=
(
const
col_cost_t
*
)
a
;
const
col_cost_t
*
c2
=
(
const
col_cost_t
*
)
b
;
real_t
diff
=
c1
->
cost
-
c2
->
cost
;
const
col_cost_t
*
c1
=
(
const
col_cost_t
*
)
a
;
const
col_cost_t
*
c2
=
(
const
col_cost_t
*
)
b
;
real_t
diff
=
c1
->
cost
-
c2
->
cost
;
if
(
diff
<
0
)
return
1
;
...
...
@@ -290,9 +290,9 @@ static __attribute__((unused)) int cmp_col_cost_lt(const void *a, const void *b)
static
int
cmp_col_cost_gt
(
const
void
*
a
,
const
void
*
b
)
{
const
col_cost_t
*
c1
=
(
const
col_cost_t
*
)
a
;
const
col_cost_t
*
c2
=
(
const
col_cost_t
*
)
b
;
real_t
diff
=
c2
->
cost
-
c1
->
cost
;
const
col_cost_t
*
c1
=
(
const
col_cost_t
*
)
a
;
const
col_cost_t
*
c2
=
(
const
col_cost_t
*
)
b
;
real_t
diff
=
c2
->
cost
-
c1
->
cost
;
if
(
diff
>
0
)
return
1
;
...
...
@@ -311,8 +311,10 @@ static inline aff_chunk_t *new_aff_chunk(co_mst_env_t *env)
c
->
n
=
NEW_ARR_F
(
const
ir_node
*
,
0
);
c
->
interfere
=
NEW_ARR_F
(
const
ir_node
*
,
0
);
c
->
weight
=
-
1
;
c
->
weight_consistent
=
0
;
c
->
deleted
=
0
;
c
->
weight_consistent
=
false
;
#ifndef NDEBUG
c
->
deleted
=
false
;
#endif
c
->
id
=
++
last_chunk_id
;
c
->
visited
=
0
;
list_add
(
&
c
->
list
,
&
env
->
chunklist
);
...
...
@@ -327,7 +329,9 @@ static inline void delete_aff_chunk(aff_chunk_t *c)
list_del
(
&
c
->
list
);
DEL_ARR_F
(
c
->
interfere
);
DEL_ARR_F
(
c
->
n
);
c
->
deleted
=
1
;
#ifndef NDEBUG
c
->
deleted
=
true
;
#endif
free
(
c
);
}
...
...
@@ -339,11 +343,11 @@ static inline void delete_aff_chunk(aff_chunk_t *c)
*/
static
inline
int
nodes_bsearch
(
const
ir_node
**
arr
,
const
ir_node
*
n
)
{
int
hi
=
ARR_LEN
(
arr
);
int
lo
=
0
;
unsigned
hi
=
ARR_LEN
(
arr
);
unsigned
lo
=
0
;
while
(
lo
<
hi
)
{
int
md
=
lo
+
((
hi
-
lo
)
>>
1
);
unsigned
md
=
lo
+
((
hi
-
lo
)
/
2
);
if
(
arr
[
md
]
==
n
)
return
md
;
...
...
@@ -357,7 +361,7 @@ static inline int nodes_bsearch(const ir_node **arr, const ir_node *n)
}
/** Check if a node n can be found inside arr. */
static
int
node_contains
(
const
ir_node
**
arr
,
const
ir_node
*
n
)
static
bool
node_contains
(
const
ir_node
**
arr
,
const
ir_node
*
n
)
{
int
i
=
nodes_bsearch
(
arr
,
n
);
return
i
>=
0
;
...
...
@@ -365,28 +369,23 @@ static int node_contains(const ir_node **arr, const ir_node *n)
/**
* Insert a node into the sorted nodes list.
*
* @return 1 if the node was inserted, 0 else
* @return true if the node was inserted
*/
static
int
nodes_insert
(
const
ir_node
***
arr
,
const
ir_node
*
irn
)
static
bool
nodes_insert
(
const
ir_node
***
arr
,
const
ir_node
*
irn
)
{
int
idx
=
nodes_bsearch
(
*
arr
,
irn
);
if
(
idx
<
0
)
{
int
i
,
n
=
ARR_LEN
(
*
arr
);
const
ir_node
**
l
;
ARR_APP1
(
const
ir_node
*
,
*
arr
,
irn
);
/* move it */
idx
=
~
idx
;
l
=
*
arr
;
for
(
i
=
n
-
1
;
i
>=
idx
;
--
i
)
l
[
i
+
1
]
=
l
[
i
];
l
[
idx
]
=
irn
;
return
1
;
}
return
0
;
if
(
idx
>=
0
)
return
false
;
ARR_APP1
(
const
ir_node
*
,
*
arr
,
irn
);
/* move it */
idx
=
~
idx
;
const
ir_node
**
l
=
*
arr
;
for
(
int
i
=
ARR_LEN
(
*
arr
)
-
2
;
i
>=
idx
;
--
i
)
l
[
i
+
1
]
=
l
[
i
];
l
[
idx
]
=
irn
;
return
true
;
}
/**
...
...
@@ -394,15 +393,13 @@ static int nodes_insert(const ir_node ***arr, const ir_node *irn)
*/
static
inline
void
aff_chunk_add_node
(
aff_chunk_t
*
c
,
co_mst_irn_t
*
node
)
{
int
i
;
if
(
!
nodes_insert
(
&
c
->
n
,
node
->
irn
))
if
(
!
nodes_insert
(
&
c
->
n
,
node
->
irn
))
return
;
c
->
weight_consistent
=
0
;
c
->
weight_consistent
=
false
;
node
->
chunk
=
c
;
for
(
i
=
node
->
n_neighs
-
1
;
i
>
=
0
;
--
i
)
{
for
(
unsigned
i
=
node
->
n_neighs
;
i
--
>
0
;
)
{
ir_node
*
neigh
=
node
->
int_neighs
[
i
];
nodes_insert
(
&
c
->
interfere
,
neigh
);
}
...
...
@@ -411,7 +408,8 @@ static inline void aff_chunk_add_node(aff_chunk_t *c, co_mst_irn_t *node)
/**
* Check if affinity chunk @p chunk interferes with node @p irn.
*/
static
inline
int
aff_chunk_interferes
(
const
aff_chunk_t
*
chunk
,
const
ir_node
*
irn
)
static
inline
bool
aff_chunk_interferes
(
const
aff_chunk_t
*
chunk
,
const
ir_node
*
irn
)
{
return
node_contains
(
chunk
->
interfere
,
irn
);
}
...
...
@@ -420,23 +418,22 @@ static inline int aff_chunk_interferes(const aff_chunk_t *chunk, const ir_node *
* Check if there are interference edges from c1 to c2.
* @param c1 A chunk
* @param c2 Another chunk
* @return
1
if there are interferences between nodes of c1 and c2
, 0 otherwise.
* @return
true
if there are interferences between nodes of c1 and c2
*/
static
inline
int
aff_chunks_interfere
(
const
aff_chunk_t
*
c1
,
const
aff_chunk_t
*
c2
)
static
inline
bool
aff_chunks_interfere
(
const
aff_chunk_t
*
c1
,
const
aff_chunk_t
*
c2
)
{
int
i
;
if
(
c1
==
c2
)
return
0
;
return
false
;
/* check if there is a node in c2 having an interfering neighbor in c1 */
for
(
i
=
ARR_LEN
(
c2
->
n
)
-
1
;
i
>
=
0
;
--
i
)
{
for
(
size_t
i
=
ARR_LEN
(
c2
->
n
);
i
--
>
0
;
)
{
const
ir_node
*
irn
=
c2
->
n
[
i
];
if
(
node_contains
(
c1
->
interfere
,
irn
))
return
1
;
return
true
;
}
return
0
;
return
false
;
}
/**
...
...
@@ -452,36 +449,37 @@ static inline aff_chunk_t *get_aff_chunk(co_mst_env_t *env, const ir_node *irn)
/**
* Let chunk(src) absorb the nodes of chunk(tgt) (only possible when there
* are no interference edges from chunk(src) to chunk(tgt)).
* @return
1
if successful,
0
if not possible
* @return
true
if successful,
false
if not possible
*/
static
int
aff_chunk_absorb
(
co_mst_env_t
*
env
,
const
ir_node
*
src
,
const
ir_node
*
tgt
)
static
bool
aff_chunk_absorb
(
co_mst_env_t
*
env
,
const
ir_node
*
src
,
const
ir_node
*
tgt
)
{
aff_chunk_t
*
c1
=
get_aff_chunk
(
env
,
src
);
aff_chunk_t
*
c2
=
get_aff_chunk
(
env
,
tgt
);
#ifdef DEBUG_libfirm
DB
((
dbg
,
LEVEL_4
,
"Attempt to let c1 (id %u): "
,
c1
?
c1
->
id
:
0
));
if
(
c1
)
{
DBG_AFF_CHUNK
(
env
,
LEVEL_4
,
c1
);
}
else
{
DB
((
dbg
,
LEVEL_4
,
"{%+F}"
,
src
));
}
DB
((
dbg
,
LEVEL_4
,
"
\n\t
absorb c2 (id %u): "
,
c2
?
c2
->
id
:
0
));
if
(
c2
)
{
DBG_AFF_CHUNK
(
env
,
LEVEL_4
,
c2
);
}
else
{
DB
((
dbg
,
LEVEL_4
,
"{%+F}"
,
tgt
));
}
DB
((
dbg
,
LEVEL_4
,
"
\n
"
));
DB
((
dbg
,
LEVEL_4
,
"Attempt to let c1 (id %u): "
,
c1
?
c1
->
id
:
0
));
if
(
c1
)
{
DBG_AFF_CHUNK
(
env
,
LEVEL_4
,
c1
);
}
else
{
DB
((
dbg
,
LEVEL_4
,
"{%+F}"
,
src
));
}
DB
((
dbg
,
LEVEL_4
,
"
\n\t
absorb c2 (id %u): "
,
c2
?
c2
->
id
:
0
));
if
(
c2
)
{
DBG_AFF_CHUNK
(
env
,
LEVEL_4
,
c2
);
}
else
{
DB
((
dbg
,
LEVEL_4
,
"{%+F}"
,
tgt
));
}
DB
((
dbg
,
LEVEL_4
,
"
\n
"
));
#endif
if
(
c1
==
NULL
)
{
if
(
c2
==
NULL
)
{
/* no chunk exists */
co_mst_irn_t
*
mirn
=
get_co_mst_irn
(
env
,
src
);
int
i
;
for
(
i
=
mirn
->
n_neighs
-
1
;
i
>=
0
;
--
i
)
{
int
i
;
for
(
i
=
mirn
->
n_neighs
;
i
--
>
0
;
)
{
if
(
mirn
->
int_neighs
[
i
]
==
tgt
)
break
;
}
...
...
@@ -494,39 +492,37 @@ static int aff_chunk_absorb(co_mst_env_t *env, const ir_node *src, const ir_node
}
}
else
{
/* c2 already exists */
if
(
!
aff_chunk_interferes
(
c2
,
src
))
{
if
(
!
aff_chunk_interferes
(
c2
,
src
))
{
aff_chunk_add_node
(
c2
,
get_co_mst_irn
(
env
,
src
));
goto
absorbed
;
}
}
}
else
if
(
c2
==
NULL
)
{
/* c1 already exists */
if
(
!
aff_chunk_interferes
(
c1
,
tgt
))
{
if
(
!
aff_chunk_interferes
(
c1
,
tgt
))
{
aff_chunk_add_node
(
c1
,
get_co_mst_irn
(
env
,
tgt
));
goto
absorbed
;
}
}
else
if
(
c1
!=
c2
&&
!
aff_chunks_interfere
(
c1
,
c2
))
{
int
idx
,
len
;
for
(
idx
=
0
,
len
=
ARR_LEN
(
c2
->
n
);
idx
<
len
;
++
idx
)
}
else
if
(
c1
!=
c2
&&
!
aff_chunks_interfere
(
c1
,
c2
))
{
for
(
size_t
idx
=
0
,
len
=
ARR_LEN
(
c2
->
n
);
idx
<
len
;
++
idx
)
aff_chunk_add_node
(
c1
,
get_co_mst_irn
(
env
,
c2
->
n
[
idx
]));
for
(
idx
=
0
,
len
=
ARR_LEN
(
c2
->
interfere
);
idx
<
len
;
++
idx
)
{
for
(
size_t
idx
=
0
,
len
=
ARR_LEN
(
c2
->
interfere
);
idx
<
len
;
++
idx
)
{
const
ir_node
*
irn
=
c2
->
interfere
[
idx
];
nodes_insert
(
&
c1
->
interfere
,
irn
);
}
c1
->
weight_consistent
=
0
;
c1
->
weight_consistent
=
false
;
delete_aff_chunk
(
c2
);
goto
absorbed
;
}
DB
((
dbg
,
LEVEL_4
,
" ... c1 interferes with c2, skipped
\n
"
));
return
0
;
return
false
;
absorbed:
DB
((
dbg
,
LEVEL_4
,
" ... absorbed
\n
"
));
return
1
;
return
true
;
}
/**
...
...
@@ -534,19 +530,17 @@ absorbed:
*/
static
void
aff_chunk_assure_weight
(
co_mst_env_t
*
env
,
aff_chunk_t
*
c
)
{
if
(
!
c
->
weight_consistent
)
{
int
w
=
0
;
int
idx
,
len
,
i
;
for
(
i
=
0
;
i
<
env
->
n_regs
;
++
i
)
{
if
(
!
c
->
weight_consistent
)
{
for
(
unsigned
i
=
0
,
n
=
env
->
n_regs
;
i
<
n
;
++
i
)
{
c
->
color_affinity
[
i
].
col
=
i
;
c
->
color_affinity
[
i
].
cost
=
REAL
(
0
.
0
);
}
for
(
idx
=
0
,
len
=
ARR_LEN
(
c
->
n
);
idx
<
len
;
++
idx
)
{
const
ir_node
*
n
=
c
->
n
[
idx
];
const
affinity_node_t
*
an
=
get_affinity_info
(
env
->
co
,
n
);
co_mst_irn_t
*
node
=
get_co_mst_irn
(
env
,
n
);
int
w
=
0
;
for
(
unsigned
idx
=
0
,
len
=
ARR_LEN
(
c
->
n
);
idx
<
len
;
++
idx
)
{
const
ir_node
*
n
=
c
->
n
[
idx
];
const
affinity_node_t
*
an
=
get_affinity_info
(
env
->
co
,
n
);
co_mst_irn_t
*
node
=
get_co_mst_irn
(
env
,
n
);
node
->
chunk
=
c
;
if
(
node
->
constr_factor
>
REAL
(
0
.
0
))
{
...
...
@@ -566,33 +560,32 @@ static void aff_chunk_assure_weight(co_mst_env_t *env, aff_chunk_t *c)
}
}
for
(
i
=
0
;
i
<
env
->
n_regs
;
++
i
)
for
(
unsigned
i
=
0
,
n
=
env
->
n_regs
;
i
<
n
;
++
i
)
c
->
color_affinity
[
i
].
cost
*=
(
REAL
(
1
.
0
)
/
ARR_LEN
(
c
->
n
));
c
->
weight
=
w
;
// c->weight = bitset_popcount(c->nodes);
c
->
weight_consistent
=
1
;
c
->
weight_consistent
=
true
;
}
}
/**
* Count the number of interfering affinity neighbours
*/
static
int
count_interfering_aff_neighs
(
co_mst_env_t
*
env
,
const
affinity_node_t
*
an
)
static
unsigned
count_interfering_aff_neighs
(
co_mst_env_t
*
env
,
const
affinity_node_t
*
an
)
{
const
ir_node
*
irn
=
an
->
irn
;
const
co_mst_irn_t
*
node
=
get_co_mst_irn
(
env
,
irn
);
int
res
=
0
;
unsigned
res
=
0
;
co_gs_foreach_neighb
(
an
,
neigh
)
{
const
ir_node
*
n
=
neigh
->
irn
;
int
i
;
if
(
arch_irn_is_ignore
(
n
))
continue
;
/* check if the affinity neighbour interfere */
for
(
i
=
0
;
i
<
node
->
n_neighs
;
++
i
)
{
for
(
unsigned
i
=
0
,
n_neighs
=
node
->
n_neighs
;
i
<
n_neighs
;
++
i
)
{
if
(
node
->
int_neighs
[
i
]
==
n
)
{
++
res
;
break
;
...
...
@@ -616,15 +609,12 @@ static void build_affinity_chunks(co_mst_env_t *env)
/* at first we create the affinity edge objects */
be_ifg_foreach_node
(
env
->
ifg
,
n
)
{
int
n_idx
=
get_irn_idx
(
n
);
co_mst_irn_t
*
n1
;
affinity_node_t
*
an
;
if
(
arch_irn_is_ignore
(
n
))
continue
;
n1
=
get_co_mst_irn
(
env
,
n
);
an
=
get_affinity_info
(
env
->
co
,
n
);
co_mst_irn_t
*
n1
=
get_co_mst_irn
(
env
,
n
);
affinity_node_t
*
an
=
get_affinity_info
(
env
->
co
,
n
);
unsigned
n_idx
=
get_irn_idx
(
n
);
if
(
an
!=
NULL
)
{
if
(
n1
->
int_aff_neigh
<
0
)
...
...
@@ -633,21 +623,19 @@ static void build_affinity_chunks(co_mst_env_t *env)
/* build the affinity edges */
co_gs_foreach_neighb
(
an
,
neigh
)
{
const
ir_node
*
m
=
neigh
->
irn
;
int
m_idx
=
get_irn_idx
(
m
);
unsigned
m_idx
=
get_irn_idx
(
m
);
/* record the edge in only one direction */
if
(
n_idx
<
m_idx
)
{
co_mst_irn_t
*
n2
;
aff_edge_t
edge
;
/* skip ignore nodes */
if
(
arch_irn_is_ignore
(
m
))
continue
;
aff_edge_t
edge
;
edge
.
src
=
n
;
edge
.
tgt
=
m
;
n2
=
get_co_mst_irn
(
env
,
m
);
co_mst_irn_t
*
n2
=
get_co_mst_irn
(
env
,
m
);
if
(
n2
->
int_aff_neigh
<
0
)
{
affinity_node_t
*
am
=
get_affinity_info
(
env
->
co
,
m
);
n2
->
int_aff_neigh
=
count_interfering_aff_neighs
(
env
,
am
);
...
...
@@ -682,7 +670,7 @@ static void build_affinity_chunks(co_mst_env_t *env)
pqueue_put
(
env
->
chunks
,
curr_chunk
,
curr_chunk
->
weight
);
}
for
(
size_t
pn
=
0
;
p
n
<
ARR_LEN
(
env
->
map
.
data
);
++
pn
)
{
for
(
size_t
pn
=
0
,
n
=
ARR_LEN
(
env
->
map
.
data
);
pn
<
n
;
++
pn
)
{
co_mst_irn_t
*
mirn
=
(
co_mst_irn_t
*
)
env
->
map
.
data
[
pn
];
if
(
mirn
==
NULL
)
continue
;
...
...
@@ -710,16 +698,14 @@ static __attribute__((unused)) void chunk_order_nodes(co_mst_env_t *env, aff_chu
pqueue_t
*
grow
=
new_pqueue
();
ir_node
const
*
max_node
=
NULL
;
int
max_weight
=
0
;
size_t
i
;
for
(
i
=
ARR_LEN
(
chunk
->
n
);
i
!=
0
;)
{
const
ir_node
*
irn
=
chunk
->
n
[
--
i
];
affinity_node_t
*
an
=
get_affinity_info
(
env
->
co
,
irn
);
int
w
=
0
;
for
(
size_t
i
=
ARR_LEN
(
chunk
->
n
);
i
--
>
0
;
)
{
const
ir_node
*
irn
=
chunk
->
n
[
i
];
if
(
arch_irn_is_ignore
(
irn
))
continue
;
affinity_node_t
*
an
=
get_affinity_info
(
env
->
co
,
irn
);
int
w
=
0
;
if
(
an
)
{
co_gs_foreach_neighb
(
an
,
neigh
)
w
+=
neigh
->
costs
;
...
...
@@ -734,12 +720,12 @@ static __attribute__((unused)) void chunk_order_nodes(co_mst_env_t *env, aff_chu
if
(
max_node
)
{
bitset_t
*
visited
=
bitset_malloc
(
get_irg_last_idx
(
env
->
co
->
irg
));
for
(
i
=
ARR_LEN
(
chunk
->
n
);
i
!=
0
;)
bitset_set
(
visited
,
get_irn_idx
(
chunk
->
n
[
--
i
]));
for
(
size_t
i
=
ARR_LEN
(
chunk
->
n
);
i
--
>
0
;
)
bitset_set
(
visited
,
get_irn_idx
(
chunk
->
n
[
i
]));
pqueue_put
(
grow
,
(
void
*
)
max_node
,
max_weight
);
pqueue_put
(
grow
,
(
void
*
)
max_node
,
max_weight
);
bitset_clear
(
visited
,
get_irn_idx
(
max_node
));
i
=
0
;