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
7571a0e5
Commit
7571a0e5
authored
May 30, 2006
by
Christian Würdig
Browse files
added comments
fixed indents fixed CRLF
parent
f712b4e8
Changes
1
Hide whitespace changes
Inline
Side-by-side
ir/be/beverify.c
View file @
7571a0e5
/*
* Author:
Matthias Braun
* Date:
05.05.2006
* Copyright:
(c) Universitaet Karlsruhe
* License:
This file protected by GPL - GNU GENERAL PUBLIC LICENSE.
*
* Author: Matthias Braun
* Date:
05.05.2006
* Copyright: (c) Universitaet Karlsruhe
* License: This file protected by GPL - GNU GENERAL PUBLIC LICENSE.
*
CVS-Id: $Id$
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
...
...
@@ -20,96 +20,102 @@
#include "irdump_t.h"
typedef
struct
be_verify_register_pressure_env_t_
{
ir_graph
*
irg
;
const
arch_env_t
*
arch_env
;
const
arch_register_class_t
*
cls
;
int
registers_available
;
int
problem_found
;
ir_graph
*
irg
;
/**< the irg to verify */
const
arch_env_t
*
arch_env
;
/**< an architecture environment */
const
arch_register_class_t
*
cls
;
/**< the register class to check for */
int
registers_available
;
/**< number of available registers */
int
problem_found
;
/**< flag indicating if a problem was found */
}
be_verify_register_pressure_env_t
;
static
void
print_living_values
(
pset
*
live_nodes
)
/**
* Print all nodes of a pset into a file.
*/
static
void
print_living_values
(
FILE
*
F
,
pset
*
live_nodes
)
{
ir_node
*
node
;
ir_printf
(
"
\t
"
);
ir_
f
printf
(
F
,
"
\t
"
);
foreach_pset
(
live_nodes
,
node
)
{
ir_printf
(
"%+F "
,
node
);
ir_
f
printf
(
F
,
"%+F "
,
node
);
}
ir_printf
(
"
\n
"
);
ir_
f
printf
(
F
,
"
\n
"
);
}
/**
* Check if number of live nodes never exceeds the number of available registers.
*/
static
void
verify_liveness_walker
(
ir_node
*
bl
,
void
*
data
)
{
be_verify_register_pressure_env_t
*
env
=
(
be_verify_register_pressure_env_t
*
)
data
;
int
pressure
;
pset
*
live_nodes
=
pset_new_ptr_default
();
be_verify_register_pressure_env_t
*
env
=
(
be_verify_register_pressure_env_t
*
)
data
;
pset
*
live_nodes
=
pset_new_ptr_default
();
ir_node
*
irn
;
/
/
collect register pressure info
/
*
collect register pressure info
, start with end of a block */
be_liveness_end_of_block
(
env
->
arch_env
,
env
->
cls
,
bl
,
live_nodes
);
pressure
=
pset_count
(
live_nodes
);
if
(
pressure
>
env
->
registers_available
)
{
ir_printf
(
"Verify Warning: Register pressure too high at end of block %+F(%s) (%d/%d):
\n
"
,
bl
,
get_irg_dump_name
(
env
->
irg
),
pressure
,
env
->
registers_available
);
print_living_values
(
live_nodes
);
env
->
problem_found
=
1
;
}
sched_foreach_reverse
(
bl
,
irn
)
{
int
pressure
;
int
pressure
=
pset_count
(
live_nodes
)
;
if
(
is_Phi
(
irn
))
if
(
is_Phi
(
irn
))
break
;
be_liveness_transfer
(
env
->
arch_env
,
env
->
cls
,
irn
,
live_nodes
);
pressure
=
pset_count
(
live_nodes
);
if
(
pressure
>
env
->
registers_available
)
{
ir_printf
(
"Verify Warning: Register pressure too high
before %+F (in
block %+F(%s) (%d/%d)
.
\n
"
,
irn
,
bl
,
get_irg_dump_name
(
env
->
irg
),
pressure
,
env
->
registers_available
);
print_living_values
(
live_nodes
);
ir_
f
printf
(
stderr
,
"Verify Warning: Register pressure too high
at end of
block %+F(%s) (%d/%d)
:
\n
"
,
bl
,
get_irg_dump_name
(
env
->
irg
),
pressure
,
env
->
registers_available
);
print_living_values
(
stderr
,
live_nodes
);
env
->
problem_found
=
1
;
}
be_liveness_transfer
(
env
->
arch_env
,
env
->
cls
,
irn
,
live_nodes
);
}
del_pset
(
live_nodes
);
}
/**
* Start a walk over the irg and check the register pressure.
*/
int
be_verify_register_pressure
(
const
arch_env_t
*
arch_env
,
const
arch_register_class_t
*
cls
,
ir_graph
*
irg
)
{
be_verify_register_pressure_env_t
env
;
be_liveness
(
irg
);
env
.
irg
=
irg
;
env
.
arch_env
=
arch_env
;
env
.
cls
=
cls
;
env
.
irg
=
irg
;
env
.
arch_env
=
arch_env
;
env
.
cls
=
cls
;
env
.
registers_available
=
arch_count_non_ignore_regs
(
arch_env
,
cls
);
env
.
problem_found
=
0
;
env
.
problem_found
=
0
;
return
!
env
.
problem_found
;
irg_block_walk_graph
(
irg
,
verify_liveness_walker
,
NULL
,
&
env
);
return
!
env
.
problem_found
;
}
typedef
struct
be_verify_schedule_env_t_
{
int
problem_found
;
ir_graph
*
irg
;
int
problem_found
;
/**< flags indicating if there was a problem */
ir_graph
*
irg
;
/**< the irg to check */
}
be_verify_schedule_env_t
;
/**
* Simple schedule checker.
*/
static
void
verify_schedule_walker
(
ir_node
*
bl
,
void
*
data
)
{
be_verify_schedule_env_t
*
env
=
(
be_verify_schedule_env_t
*
)
data
;
ir_node
*
irn
;
int
non_phi_found
=
0
;
int
non_phi_found
=
0
;
int
cfchange_found
=
0
;
// TODO ask ABI about delay branches
int
delay_branches
=
0
;
/*
*
Make sure that all phi nodes are scheduled at the beginning of the block, and that there
*
is 1 or no control flow changing node scheduled as last operation
Make sure that all phi nodes are scheduled at the beginning of the block, and that there
is 1 or no control flow changing node scheduled as last operation
*/
sched_foreach
(
bl
,
irn
)
{
if
(
is_Phi
(
irn
))
{
if
(
non_phi_found
)
{
ir_printf
(
"Verify Warning: Phi node %+F scheduled after non-Phi nodes in block %+F (%s)
\n
"
,
if
(
is_Phi
(
irn
))
{
if
(
non_phi_found
)
{
ir_
f
printf
(
stderr
,
"Verify Warning: Phi node %+F scheduled after non-Phi nodes in block %+F (%s)
\n
"
,
irn
,
bl
,
get_irg_dump_name
(
env
->
irg
));
env
->
problem_found
=
1
;
}
...
...
@@ -117,16 +123,18 @@ static void verify_schedule_walker(ir_node *bl, void *data)
}
non_phi_found
=
1
;
if
(
is_cfop
(
irn
)
&&
get_irn_opcode
(
irn
)
!=
iro_Start
)
{
if
(
cfchange_found
==
1
)
{
ir_printf
(
"Verify Warning: More than 1 control flow changing node (%+F) scheduled in block %+F (%s)
\n
"
,
if
(
is_cfop
(
irn
)
&&
get_irn_opcode
(
irn
)
!=
iro_Start
)
{
/* check, that only one CF operation is scheduled */
if
(
cfchange_found
==
1
)
{
ir_fprintf
(
stderr
,
"Verify Warning: More than 1 control flow changing node (%+F) scheduled in block %+F (%s)
\n
"
,
irn
,
bl
,
get_irg_dump_name
(
env
->
irg
));
env
->
problem_found
=
1
;
}
cfchange_found
=
1
;
}
else
if
(
cfchange_found
)
{
if
(
delay_branches
==
0
)
{
ir_printf
(
"Verify Warning: Node %+F scheduled after control flow changing node (+delay branches) in block %+F (%s)
\n
"
,
}
else
if
(
cfchange_found
)
{
/* check for delay branches */
if
(
delay_branches
==
0
)
{
ir_fprintf
(
stderr
,
"Verify Warning: Node %+F scheduled after control flow changing node (+delay branches) in block %+F (%s)
\n
"
,
irn
,
bl
,
get_irg_dump_name
(
env
->
irg
));
env
->
problem_found
=
1
;
}
else
{
...
...
@@ -135,21 +143,25 @@ static void verify_schedule_walker(ir_node *bl, void *data)
}
}
if
(
cfchange_found
&&
delay_branches
!=
0
)
{
ir_printf
(
"Not all delay slots filled after jump (%d/%d) in block %+F (%s)
\n
"
,
/* check that all delay branches are used (at least with NOPs) */
if
(
cfchange_found
&&
delay_branches
!=
0
)
{
ir_fprintf
(
stderr
,
"Not all delay slots filled after jump (%d/%d) in block %+F (%s)
\n
"
,
bl
,
get_irg_dump_name
(
env
->
irg
));
env
->
problem_found
=
1
;
}
}
/**
* Start a walk over the irg and check schedule.
*/
int
be_verify_schedule
(
ir_graph
*
irg
)
{
be_verify_schedule_env_t
env
;
env
.
problem_found
=
0
;
env
.
irg
=
irg
;
env
.
irg
=
irg
;
irg_block_walk_graph
(
irg
,
verify_schedule_walker
,
NULL
,
&
env
);
return
!
env
.
problem_found
;
return
!
env
.
problem_found
;
}
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