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
f617d134
Commit
f617d134
authored
Jul 31, 2015
by
Christoph Mallon
Browse files
becopyilp: Clean up a bit.
parent
0e5175cf
Changes
4
Hide whitespace changes
Inline
Side-by-side
ir/be/becopyilp.c
View file @
f617d134
...
...
@@ -10,26 +10,24 @@
* @date 28.02.2006
*/
#include <stdbool.h>
#include <stdio.h>
#include "be_t.h"
#include "becopyilp_t.h"
#include "becopyopt_t.h"
#include "beifg.h"
#include "belive.h"
#include "beirg.h"
#include "irtools.h"
#include "irprintf.h"
#include "statev_t.h"
#include "bemodule.h"
#include "panic.h"
#include "lpp.h"
#include "lc_opts.h"
#include "irprintf.h"
#include "irtools.h"
#include "lc_opts_enum.h"
#include "panic.h"
#include "statev_t.h"
#define DUMP_ILP 1
static
int
time_limit
=
60
;
static
bool
solve_log
=
false
;
static
int
time_limit
=
60
;
static
bool
solve_log
=
false
;
static
unsigned
dump_flags
=
0
;
static
const
lc_opt_enum_mask_items_t
dump_items
[]
=
{
...
...
@@ -60,9 +58,6 @@ void be_init_copyilp(void)
lc_opt_add_table
(
ilp_grp
,
options
);
}
#include "becopyilp_t.h"
#include "beifg.h"
/******************************************************************************
_____ _ _ _ _
/ ____(_) | | | | (_)
...
...
@@ -109,14 +104,13 @@ end:
*/
static
void
sr_remove
(
ilp_env_t
*
const
ienv
)
{
bool
redo
=
true
;
const
be_ifg_t
*
ifg
=
ienv
->
co
->
cenv
->
ifg
;
be_ifg_t
const
*
const
ifg
=
ienv
->
co
->
cenv
->
ifg
;
bool
redo
=
true
;
while
(
redo
)
{
redo
=
false
;
be_ifg_foreach_node
(
ifg
,
irn
)
{
const
arch_register_req_t
*
req
=
arch_get_irn_register_req
(
irn
);
if
(
req
->
limited
!=
NULL
||
sr_is_removed
(
ienv
,
irn
))
arch_register_req_t
const
*
const
req
=
arch_get_irn_register_req
(
irn
);
if
(
req
->
limited
||
sr_is_removed
(
ienv
,
irn
))
continue
;
if
(
co_gs_is_optimizable
(
ienv
->
co
,
irn
))
continue
;
...
...
@@ -149,27 +143,24 @@ static void sr_reinsert(ilp_env_t *const ienv)
/* get free color by inspecting all neighbors */
neighbours_iter_t
iter
;
be_ifg_foreach_neighbour
(
ifg
,
&
iter
,
irn
,
other
)
{
const
arch_register_req_t
*
cur_req
;
unsigned
cur_col
;
/* only inspect nodes which are in graph right now */
if
(
sr_is_removed
(
ienv
,
other
))
continue
;
cur_req
=
arch_get_irn_register_req
(
other
);
cur_col
=
get_irn_col
(
other
);
/* Invalidate all single size register when it is a large one */
unsigned
const
width
=
arch_get_irn_register_req
(
other
)
->
width
;
unsigned
cur_col
=
get_irn_col
(
other
);
do
{
rbitset_clear
(
possible_cols
,
cur_col
);
++
cur_col
;
}
while
(
(
cur_col
%
cur_req
->
width
)
!=
0
);
}
while
(
cur_col
%
width
!=
0
);
}
/* now all bits not set are possible colors */
/* take one that matches the alignment constraint */
unsigned
free_col
=
0
;
assert
(
!
rbitset_is_empty
(
possible_cols
,
n_regs
)
&&
"No free color found. This can not be."
);
unsigned
free_col
=
0
;
for
(;;)
{
free_col
=
(
unsigned
)
rbitset_next
(
possible_cols
,
free_col
,
true
);
if
(
free_col
%
arch_get_irn_register_req
(
irn
)
->
width
==
0
)
...
...
@@ -192,40 +183,31 @@ static void sr_reinsert(ilp_env_t *const ienv)
*****************************************************************************/
#include <stdio.h>
ilp_env_t
*
new_ilp_env
(
copy_opt_t
*
co
,
ilp_callback
build
,
ilp_callback
apply
,
void
*
env
)
ilp_env_t
*
new_ilp_env
(
copy_opt_t
*
const
co
,
ilp_callback
const
build
,
ilp_callback
const
apply
,
void
*
const
env
)
{
ilp_env_t
*
res
=
XMALLOC
(
ilp_env_t
);
res
->
co
=
co
;
res
->
build
=
build
;
res
->
apply
=
apply
;
res
->
env
=
env
;
res
->
col_suff
=
NEW_ARR_F
(
ir_node
*
,
0
);
ilp_env_t
*
const
res
=
XMALLOC
(
ilp_env_t
);
res
->
co
=
co
;
res
->
build
=
build
;
res
->
apply
=
apply
;
res
->
env
=
env
;
res
->
col_suff
=
NEW_ARR_F
(
ir_node
*
,
0
);
ir_nodeset_init
(
&
res
->
all_removed
);
return
res
;
}
lpp_sol_state_t
ilp_go
(
ilp_env_t
*
ienv
)
lpp_sol_state_t
ilp_go
(
ilp_env_t
*
const
ienv
)
{
ir_graph
*
irg
=
ienv
->
co
->
irg
;
sr_remove
(
ienv
);
ienv
->
build
(
ienv
);
if
(
dump_flags
&
DUMP_ILP
)
{
char
buf
[
128
];
FILE
*
f
;
ir_snprintf
(
buf
,
sizeof
(
buf
),
"%F_%s-co.ilp"
,
irg
,
ienv
->
co
->
cenv
->
cls
->
name
);
f
=
fopen
(
buf
,
"wt"
);
if
(
f
==
NULL
)
{
ir_snprintf
(
buf
,
sizeof
(
buf
),
"%F_%s-co.ilp"
,
ienv
->
co
->
irg
,
ienv
->
co
->
cenv
->
cls
->
name
);
FILE
*
const
f
=
fopen
(
buf
,
"wt"
);
if
(
!
f
)
panic
(
"couldn't open '%s' for writing"
,
buf
);
}
lpp_dump_plain
(
ienv
->
lp
,
f
);
fclose
(
f
);
}
...
...
@@ -248,7 +230,7 @@ lpp_sol_state_t ilp_go(ilp_env_t *ienv)
return
lpp_get_sol_state
(
ienv
->
lp
);
}
void
free_ilp_env
(
ilp_env_t
*
ienv
)
void
free_ilp_env
(
ilp_env_t
*
const
ienv
)
{
ir_nodeset_destroy
(
&
ienv
->
all_removed
);
DEL_ARR_F
(
ienv
->
col_suff
);
...
...
ir/be/becopyilp2.c
View file @
f617d134
...
...
@@ -29,27 +29,21 @@
*
* x_nc, y_ij \in N, w_ij \in R^+
*/
#include "be_t.h"
#include "bearch.h"
#include "becopyilp_t.h"
#include "becopyopt_t.h"
#include "belive.h"
#include "be
irg
.h"
#include "be
module
.h"
#include "debug.h"
#include "irprintf.h"
#include "panic.h"
#include "raw_bitset.h"
#include "pdeq.h"
#include "util.h"
#include "irgwalk.h"
#include "becopyilp_t.h"
#include "beifg.h"
#include "bemodule.h"
#include "irprintf.h"
DEBUG_ONLY
(
static
firm_dbg_module_t
*
dbg
;)
typedef
struct
local_env_t
{
int
first_x_var
;
int
last_x_var
;
const
unsigned
*
allocatable_colors
;
int
first_x_var
;
int
last_x_var
;
}
local_env_t
;
static
unsigned
check_alignment_constraints
(
ir_node
*
node
)
...
...
@@ -64,56 +58,47 @@ static unsigned check_alignment_constraints(ir_node *node)
static
void
make_color_var_name
(
char
*
buf
,
size_t
buf_size
,
const
ir_node
*
node
,
unsigned
color
)
{
unsigned
node_idx
=
get_irn_idx
(
node
);
unsigned
const
node_idx
=
get_irn_idx
(
node
);
snprintf
(
buf
,
buf_size
,
"x_%u_%u"
,
node_idx
,
color
);
}
static
void
build_coloring_cstr
(
ilp_env_t
*
ienv
)
{
local_env_t
*
lenv
=
(
local_env_t
*
)
ienv
->
env
;
be_ifg_t
*
ifg
=
ienv
->
co
->
cenv
->
ifg
;
unsigned
n_regs
=
ienv
->
co
->
cls
->
n_regs
;
const
unsigned
*
allocatable_colors
=
lenv
->
allocatable_colors
;
char
buf
[
32
];
local_env_t
*
const
lenv
=
(
local_env_t
*
)
ienv
->
env
;
be_ifg_t
*
const
ifg
=
ienv
->
co
->
cenv
->
ifg
;
unsigned
const
n_regs
=
ienv
->
co
->
cls
->
n_regs
;
unsigned
const
*
const
allocatable_colors
=
ienv
->
co
->
cenv
->
allocatable_regs
->
data
;
unsigned
*
const
colors
=
rbitset_alloca
(
n_regs
);
be_ifg_foreach_node
(
ifg
,
irn
)
{
const
arch_register_req_t
*
req
;
unsigned
col
;
int
cst_idx
;
unsigned
curr_node_color
;
unsigned
has_alignment_cstr
;
if
(
sr_is_removed
(
ienv
,
irn
))
continue
;
has_alignment_cstr
=
check_alignment_constraints
(
irn
);
unsigned
const
has_alignment_cstr
=
check_alignment_constraints
(
irn
);
req
=
arch_get_irn_register_req
(
irn
);
arch_register_req_t
const
*
const
req
=
arch_get_irn_register_req
(
irn
);
/* get assignable colors */
if
(
req
->
limited
!=
NULL
)
{
if
(
req
->
limited
)
{
rbitset_copy
(
colors
,
req
->
limited
,
n_regs
);
}
else
{
rbitset_copy
(
colors
,
allocatable_colors
,
n_regs
);
}
/* add the coloring constraint */
cst_idx
=
lpp_add_cst
(
ienv
->
lp
,
NULL
,
lpp_equal
,
1
.
0
);
curr_node_color
=
get_irn_col
(
irn
);
for
(
col
=
0
;
col
<
n_regs
;
++
col
)
{
int
var_idx
;
double
val
;
int
const
cst_idx
=
lpp_add_cst
(
ienv
->
lp
,
NULL
,
lpp_equal
,
1
.
0
);
unsigned
const
curr_node_color
=
get_irn_col
(
irn
);
for
(
unsigned
col
=
0
;
col
<
n_regs
;
++
col
)
{
if
(
!
rbitset_is_set
(
colors
,
col
)
||
(
has_alignment_cstr
&&
((
col
%
req
->
width
)
!=
0
)))
continue
;
char
buf
[
32
];
make_color_var_name
(
buf
,
sizeof
(
buf
),
irn
,
col
);
var_idx
=
lpp_add_var
(
ienv
->
lp
,
buf
,
lpp_binary
,
0
.
0
);
int
const
var_idx
=
lpp_add_var
(
ienv
->
lp
,
buf
,
lpp_binary
,
0
.
0
);
lpp_set_factor_fast
(
ienv
->
lp
,
cst_idx
,
var_idx
,
1
);
val
=
(
col
==
curr_node_color
)
?
1
.
0
:
0
.
0
;
double
const
val
=
col
==
curr_node_color
?
1
.
0
:
0
.
0
;
lpp_set_start_value
(
ienv
->
lp
,
var_idx
,
val
);
lenv
->
last_x_var
=
var_idx
;
...
...
@@ -122,17 +107,16 @@ static void build_coloring_cstr(ilp_env_t *ienv)
}
/* add register constraint constraints */
for
(
col
=
0
;
col
<
n_regs
;
++
col
)
{
int
cst_idx
;
int
var_idx
;
for
(
unsigned
col
=
0
;
col
<
n_regs
;
++
col
)
{
if
(
rbitset_is_set
(
colors
,
col
)
// for aligned variable, we set the unaligned part to 0
&&
(
!
has_alignment_cstr
||
((
col
%
req
->
width
)
==
0
)))
continue
;
char
buf
[
32
];
make_color_var_name
(
buf
,
sizeof
(
buf
),
irn
,
col
);
cst_idx
=
lpp_add_cst
(
ienv
->
lp
,
NULL
,
lpp_equal
,
0
.
0
);
var_idx
=
lpp_add_var
(
ienv
->
lp
,
buf
,
lpp_binary
,
0
.
0
);
int
const
cst_idx
=
lpp_add_cst
(
ienv
->
lp
,
NULL
,
lpp_equal
,
0
.
0
);
int
const
var_idx
=
lpp_add_var
(
ienv
->
lp
,
buf
,
lpp_binary
,
0
.
0
);
lpp_set_start_value
(
ienv
->
lp
,
var_idx
,
0
.
0
);
lpp_set_factor_fast
(
ienv
->
lp
,
cst_idx
,
var_idx
,
1
);
...
...
@@ -141,24 +125,20 @@ static void build_coloring_cstr(ilp_env_t *ienv)
}
}
static
void
build_interference_cstr
(
ilp_env_t
*
ienv
)
static
void
build_interference_cstr
(
ilp_env_t
*
const
ienv
)
{
lpp_t
*
lpp
=
ienv
->
lp
;
local_env_t
*
lenv
=
(
local_env_t
*
)
ienv
->
env
;
be_ifg_t
*
ifg
=
ienv
->
co
->
cenv
->
ifg
;
unsigned
n_colors
=
ienv
->
co
->
cls
->
n_regs
;
ir_node
**
clique
=
ALLOCAN
(
ir_node
*
,
n_colors
);
const
unsigned
*
allocatable_colors
=
lenv
->
allocatable_colors
;
cliques_iter_t
iter
;
int
size
;
unsigned
col
;
int
i
;
lpp_t
*
const
lpp
=
ienv
->
lp
;
be_ifg_t
*
const
ifg
=
ienv
->
co
->
cenv
->
ifg
;
unsigned
const
n_colors
=
ienv
->
co
->
cls
->
n_regs
;
ir_node
**
const
clique
=
ALLOCAN
(
ir_node
*
,
n_colors
);
unsigned
const
*
const
allocatable_colors
=
ienv
->
co
->
cenv
->
allocatable_regs
->
data
;
/* for each maximal clique */
cliques_iter_t
iter
;
int
size
;
be_ifg_foreach_clique
(
ifg
,
&
iter
,
clique
,
&
size
)
{
unsigned
realsize
=
0
;
for
(
i
=
0
;
i
<
size
;
++
i
)
{
for
(
int
i
=
0
;
i
<
size
;
++
i
)
{
if
(
!
sr_is_removed
(
ienv
,
clique
[
i
]))
++
realsize
;
}
...
...
@@ -167,34 +147,29 @@ static void build_interference_cstr(ilp_env_t *ienv)
continue
;
/* for all colors */
for
(
col
=
0
;
col
<
n_colors
;
++
col
)
{
int
cst_idx
;
for
(
unsigned
col
=
0
;
col
<
n_colors
;
++
col
)
{
if
(
!
rbitset_is_set
(
allocatable_colors
,
col
))
continue
;
cst_idx
=
lpp_add_cst
(
lpp
,
NULL
,
lpp_less_equal
,
1
.
0
);
int
const
cst_idx
=
lpp_add_cst
(
lpp
,
NULL
,
lpp_less_equal
,
1
.
0
);
/* for each member of this clique */
for
(
i
=
0
;
i
<
size
;
++
i
)
{
ir_node
*
irn
=
clique
[
i
];
char
buf
[
32
];
int
var_idx
;
unsigned
aligment_offset
=
0
;
for
(
int
i
=
0
;
i
<
size
;
++
i
)
{
ir_node
*
const
irn
=
clique
[
i
];
if
(
sr_is_removed
(
ienv
,
irn
))
continue
;
// Use the first part of the large registers for all
// interference, since it is the only colorable one.
unsigned
aligment_offset
=
0
;
if
(
check_alignment_constraints
(
irn
))
{
const
arch_register_req_t
*
req
=
arch_get_irn_register_req
(
irn
);
arch_register_req_t
const
*
const
req
=
arch_get_irn_register_req
(
irn
);
aligment_offset
=
col
%
req
->
width
;
}
make_color_var_name
(
buf
,
sizeof
(
buf
),
irn
,
col
-
aligment_offset
);
var_idx
=
lpp_get_var_idx
(
lpp
,
buf
);
char
buf
[
32
];
make_color_var_name
(
buf
,
sizeof
(
buf
),
irn
,
col
-
aligment_offset
);
int
const
var_idx
=
lpp_get_var_idx
(
lpp
,
buf
);
lpp_set_factor_fast
(
lpp
,
cst_idx
,
var_idx
,
1
);
}
}
...
...
@@ -206,11 +181,12 @@ static void make_affinity_var_name(char *buf, size_t buf_size,
{
unsigned
n1
=
get_irn_idx
(
node1
);
unsigned
n2
=
get_irn_idx
(
node2
);
if
(
n
1
<
n
2
)
{
snprintf
(
buf
,
buf_size
,
"y_%u_%u"
,
n1
,
n2
)
;
}
else
{
snprintf
(
buf
,
buf_size
,
"y_%u_%u"
,
n2
,
n1
)
;
if
(
n
2
<
n
1
)
{
unsigned
const
t
=
n1
;
n1
=
n2
;
n2
=
t
;
}
snprintf
(
buf
,
buf_size
,
"y_%u_%u"
,
n1
,
n2
);
}
...
...
@@ -265,11 +241,11 @@ typedef struct edge_t {
static
int
compare_edge_t
(
const
void
*
k1
,
const
void
*
k2
,
size_t
size
)
{
const
edge_t
*
e1
=
(
const
edge_t
*
)
k1
;
const
edge_t
*
e2
=
(
const
edge_t
*
)
k2
;
(
void
)
size
;
(
void
)
size
;
return
!
(
e1
->
n1
==
e2
->
n1
&&
e1
->
n2
==
e2
->
n2
);
edge_t
const
*
const
e1
=
(
edge_t
const
*
)
k1
;
edge_t
const
*
const
e2
=
(
edge_t
const
*
)
k2
;
return
e1
->
n1
!=
e2
->
n1
||
e1
->
n2
!=
e2
->
n2
;
}
static
void
init_edge
(
edge_t
*
const
edge
,
ir_node
*
const
n1
,
ir_node
*
const
n2
)
...
...
@@ -290,7 +266,7 @@ static inline edge_t *add_edge(set *edges, ir_node *n1, ir_node *n2, size_t *cou
edge_t
new_edge
;
init_edge
(
&
new_edge
,
n1
,
n2
);
(
*
counter
)
++
;
++
*
counter
;
return
set_insert
(
edge_t
,
edges
,
&
new_edge
,
sizeof
(
new_edge
),
HASH_EDGE
(
&
new_edge
));
}
...
...
@@ -311,7 +287,7 @@ static inline void remove_edge(set *edges, ir_node *n1, ir_node *n2, size_t *cou
if
(
e
)
{
e
->
n1
=
NULL
;
e
->
n2
=
NULL
;
(
*
counter
)
--
;
--
*
counter
;
}
}
...
...
@@ -326,33 +302,28 @@ static void build_clique_star_cstr(ilp_env_t *ienv)
{
/* for each node with affinity edges */
co_gs_foreach_aff_node
(
ienv
->
co
,
aff
)
{
struct
obstack
ob
;
const
ir_node
*
center
=
aff
->
irn
;
ir_node
**
nodes
;
set
*
edges
;
int
i
,
o
,
n_nodes
;
size_t
n_edges
;
if
(
arch_irn_is_ignore
(
aff
->
irn
))
ir_node
const
*
const
center
=
aff
->
irn
;
if
(
arch_irn_is_ignore
(
center
))
continue
;
struct
obstack
ob
;
obstack_init
(
&
ob
);
edges
=
new_set
(
compare_edge_t
,
8
);
set
*
const
edges
=
new_set
(
compare_edge_t
,
8
);
/* get all affinity neighbours */
n_nodes
=
0
;
int
n_nodes
=
0
;
co_gs_foreach_neighb
(
aff
,
nbr
)
{
if
(
!
arch_irn_is_ignore
(
nbr
->
irn
))
{
obstack_ptr_grow
(
&
ob
,
nbr
->
irn
);
++
n_nodes
;
}
}
nodes
=
(
ir_node
**
)
obstack_finish
(
&
ob
);
ir_node
**
const
nodes
=
(
ir_node
**
)
obstack_finish
(
&
ob
);
/* get all interference edges between these */
n_edges
=
0
;
for
(
i
=
0
;
i
<
n_nodes
;
++
i
)
{
for
(
o
=
0
;
o
<
i
;
++
o
)
{
size_t
n_edges
=
0
;
for
(
i
nt
i
=
0
;
i
<
n_nodes
;
++
i
)
{
for
(
int
o
=
0
;
o
<
i
;
++
o
)
{
if
(
be_values_interfere
(
nodes
[
i
],
nodes
[
o
]))
add_edge
(
edges
,
nodes
[
i
],
nodes
[
o
],
&
n_edges
);
}
...
...
@@ -360,35 +331,33 @@ static void build_clique_star_cstr(ilp_env_t *ienv)
/* cover all these interference edges with maximal cliques */
while
(
n_edges
)
{
edge_t
*
e
;
pset
*
clique
=
pset_new_ptr
(
8
);
bool
growed
;
/* get 2 starting nodes to form a clique */
edge_t
*
e
;
for
(
e
=
set_first
(
edge_t
,
edges
);
!
e
->
n1
;
e
=
set_next
(
edge_t
,
edges
))
{}
/* we could be stepped out of the loop before the set iterated to the end */
set_break
(
edges
);
pset
*
const
clique
=
pset_new_ptr
(
8
);
pset_insert_ptr
(
clique
,
e
->
n1
);
pset_insert_ptr
(
clique
,
e
->
n2
);
remove_edge
(
edges
,
e
->
n1
,
e
->
n2
,
&
n_edges
);
/* while the clique is growing */
bool
grew
;
do
{
gr
owed
=
false
;
gr
ew
=
false
;
/* search for a candidate to extend the clique */
for
(
i
=
0
;
i
<
n_nodes
;
++
i
)
{
ir_node
*
cand
=
nodes
[
i
];
bool
is_cand
;
for
(
int
i
=
0
;
i
<
n_nodes
;
++
i
)
{
ir_node
*
const
cand
=
nodes
[
i
];
/* if its already in the clique try the next */
if
(
pset_find_ptr
(
clique
,
cand
))
continue
;
/* are there all necessary interferences? */
is_cand
=
true
;
bool
is_cand
=
true
;
pset_foreach
(
clique
,
member
)
{
if
(
!
find_edge
(
edges
,
cand
,
member
))
{
is_cand
=
false
;
...
...
@@ -400,28 +369,25 @@ static void build_clique_star_cstr(ilp_env_t *ienv)
/* now we know if we have a clique extender */
if
(
is_cand
)
{
/* first remove all covered edges */
pset_foreach
(
clique
,
member
)
pset_foreach
(
clique
,
member
)
{
remove_edge
(
edges
,
cand
,
member
,
&
n_edges
);
}
/* insert into clique */
pset_insert_ptr
(
clique
,
cand
);
gr
owed
=
true
;
gr
ew
=
true
;
break
;
}
}
}
while
(
gr
owed
);
}
while
(
gr
ew
);
/* now the clique is maximal. Finally add the constraint */
{
int
var_idx
;
int
cst_idx
;
char
buf
[
32
];
cst_idx
=
lpp_add_cst
(
ienv
->
lp
,
NULL
,
lpp_greater_equal
,
pset_count
(
clique
)
-
1
);
int
const
cst_idx
=
lpp_add_cst
(
ienv
->
lp
,
NULL
,
lpp_greater_equal
,
pset_count
(
clique
)
-
1
);
pset_foreach
(
clique
,
member
)
{
char
buf
[
32
];
make_affinity_var_name
(
buf
,
sizeof
(
buf
),
center
,
member
);
var_idx
=
lpp_get_var_idx
(
ienv
->
lp
,
buf
);
int
const
var_idx
=
lpp_get_var_idx
(
ienv
->
lp
,
buf
);
lpp_set_factor_fast
(
ienv
->
lp
,
cst_idx
,
var_idx
,
1
.
0
);
}
}
...
...
@@ -436,10 +402,6 @@ static void build_clique_star_cstr(ilp_env_t *ienv)
static
void
extend_path
(
ilp_env_t
*
ienv
,
pdeq
*
path
,
const
ir_node
*
irn
)
{
int
i
,
len
;
ir_node
**
curr_path
;
affinity_node_t
*
aff
;
/* do not walk backwards or in circles */
if
(
pdeq_contains
(
path
,
irn
))
return
;
...
...
@@ -451,11 +413,11 @@ static void extend_path(ilp_env_t *ienv, pdeq *path, const ir_node *irn)
pdeq_putr
(
path
,
irn
);
/* check for forbidden interferences */
len
=
pdeq_len
(
path
);
curr_path
=
ALLOCAN
(
ir_node
*
,
len
);
int
const
len
=
pdeq_len
(
path
);
ir_node
**
const
curr_path
=
ALLOCAN
(
ir_node
*
,
len
);
pdeq_copyl
(
path
,
(
const
void
**
)
curr_path
);
for
(
i
=
1
;
i
<
len
;
++
i
)
{
for
(
i
nt
i
=
1
;
i
<
len
;
++
i
)
{
if
(
be_values_interfere
(
irn
,
curr_path
[
i
]))
goto
end
;
}
...
...
@@ -467,7 +429,7 @@ static void extend_path(ilp_env_t *ienv, pdeq *path, const ir_node *irn)
if
(
len
>
2
)
{
/* finally build the constraint */
int
cst_idx
=
lpp_add_cst
(
ienv
->
lp
,
NULL
,
lpp_greater_equal
,
1
.
0
);
for
(
i
=
1
;
i
<
len
;
++
i
)
{
for
(
i
nt
i
=
1
;
i
<
len
;
++
i
)
{
char
buf
[
32
];
int
var_idx
;
...
...
@@ -482,7 +444,7 @@ static void extend_path(ilp_env_t *ienv, pdeq *path, const ir_node *irn)
}
/* recursively extend the path */
aff
=
get_affinity_info
(
ienv
->
co
,
irn
);
affinity_node_t
*
const
aff
=
get_affinity_info
(
ienv
->
co
,
irn
);
co_gs_foreach_neighb
(
aff
,
nbr
)
{
extend_path
(
ienv
,
path
,
nbr
->
irn
);
}
...
...
@@ -502,18 +464,14 @@ static void build_path_cstr(ilp_env_t *ienv)
{
/* for each node with affinity edges */
co_gs_foreach_aff_node
(
ienv
->
co
,
aff_info
)
{
pdeq
*
path
=
new_pdeq
();
pdeq
*
const
path
=
new_pdeq
();
extend_path
(
ienv
,
path
,
aff_info
->
irn
);
del_pdeq
(
path
);
}
}
static
void
ilp2_build
(
ilp_env_t
*
ienv
)
{
int
lower_bound
;
ienv
->
lp
=
lpp_new
(
"copyilp"
,
lpp_minimize
);
build_coloring_cstr
(
ienv
);
build_interference_cstr
(
ienv
);
...
...
@@ -521,43 +479,41 @@ static void ilp2_build(ilp_env_t *ienv)
build_clique_star_cstr
(
ienv
);
build_path_cstr
(
ienv
);
lower_bound
=
co_get_lower_bound
(
ienv
->
co
)
-
co_get_inevit_copy_costs
(
ienv
->
co
);
int
const
lower_bound
=
co_get_lower_bound
(
ienv
->
co
)
-
co_get_inevit_copy_costs
(
ienv
->
co
);
lpp_set_bound
(
ienv
->
lp
,
lower_bound
);
}
static
void
ilp2_apply
(
ilp_env_t
*
ienv
)
static
void
ilp2_apply
(
ilp_env_t
*
const
ienv
)
{
local_env_t
*
lenv
=
(
local_env_t
*
)
ienv
->
env
;
ir_graph
*
irg
=
ienv
->
co
->
irg
;
local_env_t
*
const
lenv
=
(
local_env_t
*
)
ienv
->
env
;
/* first check if there was sth. to optimize */
if
(
lenv
->
first_x_var
>=
0
)
{
i
nt
co
unt
=
l
env
->
last_x_var
-
lenv
->
f
ir
st_x_var
+
1
;
double
*
sol
=
XMALLOCN
(
double
,
count
)
;
lpp_sol_state_t
state
=
lpp_get_solution
(
ienv
->
lp
,
sol
,
lenv
->
first_x_var
,
lenv
->
last_x_var
);
int
i
;
i
r_graph
*
co
nst
irg
=
i
env
->
co
->
ir
g
;
int
const
count
=
lenv
->
last_x_var
-
lenv
->
<