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
78a73b3b
Commit
78a73b3b
authored
Sep 29, 2003
by
Götz Lindenmaier
Browse files
fixed various errors with exceptions + inlineing, dumping and interproc representation
added new asserstio in vrfy [r1891]
parent
65fc134f
Changes
6
Hide whitespace changes
Inline
Side-by-side
ir/ir/ircgcons.c
View file @
78a73b3b
...
...
@@ -498,6 +498,32 @@ static ir_node * get_except(ir_node * call) {
return
NULL
;
}
/* Returns true if control flow operation exc is predecessor of end
block in irg. Works also for Return nodes, not only exceptions. */
static
bool
exc_branches_to_end
(
ir_graph
*
irg
,
ir_node
*
exc
)
{
int
i
;
ir_node
*
end
=
get_irg_end_block
(
irg
);
for
(
i
=
get_Block_n_cfgpreds
(
end
)
-
1
;
i
>=
0
;
--
i
)
if
(
get_Block_cfgpred
(
end
,
i
)
==
exc
)
return
true
;
return
false
;
}
/* Returns true if only caller of irg is "Unknown". */
static
bool
is_outermost_graph
(
ir_graph
*
irg
)
{
irg_data_t
*
data
=
get_entity_link
(
get_irg_ent
(
irg
));
if
(
data
->
count
)
{
return
false
;
}
else
if
(
data
->
open
)
{
/* Die Methode wird nur von "der" unbekannten Aufrufstelle
* aufgerufen. Darstellung wird fr diese Methode nicht
* gendert. */
}
else
{
/* Methode kann nicht aufgerufen werden. Die Darstellung wird
* fr diese Methode nicht gendert. Das kann nicht vorkommen,
* wenn zuvor "gc_irgs()" aufgerufen wurde. */
}
return
true
;
}
/* Grundblock der Call-Operation aufteilen. CallBegin- und Filter-Operationen
* einfgen. Die Steuer- und Datenflussabhngigkeiten von den aufgerufenen
...
...
@@ -568,12 +594,31 @@ static void construct_call(ir_node * call) {
/* Die interprozeduralen Steuerflussvorgnger des except_block
* bestimmen. */
if
((
proj
=
get_except
(
call
))
!=
NULL
)
{
except_block
=
create_Block
(
1
,
&
proj
);
set_nodes_Block
(
proj
,
except_block
);
exchange
(
proj
,
new_Break
());
set_irg_current_block
(
current_ir_graph
,
pre_block
);
set_irn_n
(
except_block
,
0
,
new_Proj
(
call
,
mode_X
,
1
));
set_irg_current_block
(
current_ir_graph
,
post_block
);
int
preds
=
0
;
bool
exc_to_end
=
false
;
#if 1
if
(
exc_branches_to_end
(
current_ir_graph
,
proj
))
{
/* The Call aborts the procedure if it returns with an exception.
If this is an outermost procedure, the normal handling of exceptions
will generate a Break that goes to the end block. This is illegal
Frim. So directly branch to the end block with all exceptions. */
exc_to_end
=
true
;
if
(
is_outermost_graph
(
current_ir_graph
))
{
except_block
=
get_irg_end_block
(
current_ir_graph
);
}
else
{
irg_data_t
*
data
=
get_entity_link
(
get_irg_ent
(
current_ir_graph
));
except_block
=
get_nodes_block
(
data
->
except
);
}
}
else
#endif
{
except_block
=
create_Block
(
1
,
&
proj
);
set_nodes_Block
(
proj
,
except_block
);
exchange
(
proj
,
new_Break
());
set_irg_current_block
(
current_ir_graph
,
pre_block
);
set_irn_n
(
except_block
,
0
,
new_Proj
(
call
,
mode_X
,
1
));
set_irg_current_block
(
current_ir_graph
,
post_block
);
}
/*
* Set flag to suppress verifying placement on proper irg:
...
...
@@ -594,9 +639,24 @@ static void construct_call(ir_node * call) {
in
[
i
]
=
new_Unknown
();
}
}
set_Block_cg_cfgpred_arr
(
except_block
,
n_callees
,
in
);
}
preds
=
n_callees
;
if
(
exc_to_end
)
{
/* append all existing preds of the end block to new in array.
* Normal access routine guarantees that with first visit we
* get the normal preds, and from then on the _cg_ preds.
* (interporcedural view is set!)
* Do not add the exc pred of end we are replacing! */
for
(
i
=
get_Block_n_cfgpreds
(
except_block
)
-
1
;
i
>=
0
;
--
i
)
{
ir_node
*
pred
=
get_Block_cfgpred
(
except_block
,
i
);
if
(
pred
!=
proj
)
{
ARR_APP1
(
ir_node
*
,
in
,
pred
);
preds
++
;
}
}
}
set_Block_cg_cfgpred_arr
(
except_block
,
preds
,
in
);
}
set_interprocedural_view
(
0
);
/* Diesen Vorgnger in den Start-Blcken der aufgerufenen Methoden
...
...
ir/ir/irdump.c
View file @
78a73b3b
...
...
@@ -63,7 +63,7 @@
#define TYPE_CLASS_NODE_ATTR "color: green"
#define TYPE_DESCRIPTION_NODE_ATTR "color: lightgreen"
#define ENTITY_NODE_ATTR "color: yellow"
#define ENT_TYPE_EDGE_ATTR "class: 3 label
:
\"type\" color: red"
#define ENT_TYPE_EDGE_ATTR "class: 3 label \"type\" color: red"
#define ENT_OWN_EDGE_ATTR "class: 4 label: \"owner\" color: black"
#define METH_PAR_EDGE_ATTR "class: 5 label: \"param %d\" color: green"
#define METH_RES_EDGE_ATTR "class: 6 label: \"res %d\" color: green"
...
...
@@ -352,10 +352,12 @@ static bool pred_in_wrong_graph(ir_node *n, int pos, pmap *irgmap) {
static
INLINE
bool
is_constlike_node
(
ir_node
*
n
)
{
ir_op
*
op
=
get_irn_op
(
n
);
return
(
op
==
op_Const
||
op
==
op_Bad
||
op
==
op_SymConst
);
return
(
op
==
op_Const
||
op
==
op_Bad
||
op
==
op_SymConst
||
op
==
op_Unknown
);
}
/* outputs the predecessors of n, that are constants, local. I.e.,
generates a copy of the constant for each node called with. */
static
void
dump_const_node_local
(
ir_node
*
n
,
pmap
*
irgmap
)
{
int
i
;
if
(
!
get_opt_dump_const_local
())
return
;
...
...
@@ -517,7 +519,7 @@ static void print_edge_vcgattr(ir_node *from, int to) {
/* dump edges to our inputs */
static
void
dump_ir_data_edges
(
ir_node
*
n
)
{
dump_ir_data_edges
(
ir_node
*
n
,
pmap
*
irgmap
)
{
int
i
,
visited
=
get_irn_visited
(
n
);
if
((
get_irn_op
(
n
)
==
op_End
)
&&
(
!
dump_keepalive
))
...
...
@@ -534,9 +536,10 @@ dump_ir_data_edges(ir_node *n) {
fprintf
(
F
,
"edge: {sourcename:
\"
"
);
PRINT_NODEID
(
n
);
fprintf
(
F
,
"
\"
targetname: "
);
if
((
get_opt_dump_const_local
())
&&
is_constlike_node
(
pred
))
if
((
get_opt_dump_const_local
())
&&
is_constlike_node
(
pred
)
&&
!
pred_in_wrong_graph
(
n
,
i
,
irgmap
))
{
PRINT_CONSTID
(
n
,
pred
);
PRINT_CONSTID
(
n
,
pred
);
}
else
{
fprintf
(
F
,
"
\"
"
);
PRINT_NODEID
(
pred
);
fprintf
(
F
,
"
\"
"
);
...
...
@@ -1074,7 +1077,7 @@ static void
dump_whole_node
(
ir_node
*
n
,
void
*
env
)
{
dump_node
(
n
,
NULL
);
if
(
!
node_floats
(
n
))
dump_ir_block_edge
(
n
);
dump_ir_data_edges
(
n
);
dump_ir_data_edges
(
n
,
NULL
);
}
void
...
...
@@ -1110,7 +1113,7 @@ dump_ir_blocks_nodes (ir_node *n, void *env) {
if
(
is_no_Block
(
n
)
&&
get_nodes_Block
(
n
)
==
block
&&
!
node_floats
(
n
))
{
dump_node
(
n
,
NULL
);
dump_ir_data_edges
(
n
);
dump_ir_data_edges
(
n
,
NULL
);
}
if
(
get_irn_op
(
n
)
==
op_Bad
)
Bad_dumped
=
1
;
...
...
@@ -1137,7 +1140,7 @@ dump_ir_block (ir_node *block, void *env) {
fprintf
(
F
,
"
\"
status:clustered color:%s
\n
"
,
get_Block_matured
(
block
)
?
"yellow"
:
"red"
);
/* dump the blocks edges */
dump_ir_data_edges
(
block
);
dump_ir_data_edges
(
block
,
NULL
);
/* dump the nodes that go into the block */
irg_walk
(
get_irg_end
(
irg
),
dump_ir_blocks_nodes
,
NULL
,
block
);
...
...
@@ -1153,14 +1156,14 @@ static void
dump_blockless_nodes
(
ir_node
*
n
,
void
*
env
)
{
if
(
is_no_Block
(
n
)
&&
get_irn_op
(
get_nodes_Block
(
n
))
==
op_Bad
)
{
dump_node
(
n
,
NULL
);
dump_ir_data_edges
(
n
);
dump_ir_data_edges
(
n
,
NULL
);
dump_ir_block_edge
(
n
);
if
(
get_irn_op
(
n
)
==
op_Bad
)
Bad_dumped
=
1
;
return
;
}
if
(
node_floats
(
n
))
{
dump_node
(
n
,
NULL
);
dump_ir_data_edges
(
n
);
dump_ir_data_edges
(
n
,
NULL
);
if
(
get_irn_op
(
n
)
==
op_Bad
)
Bad_dumped
=
1
;
}
}
...
...
@@ -1426,6 +1429,7 @@ static void clear_link(ir_node * node, void * env) {
set_irn_link
(
node
,
NULL
);
}
static
void
collect_blocks_floats_cg
(
ir_node
*
node
,
pmap
*
map
)
{
assert
(
node
);
assert
(
map
);
if
(
is_Block
(
node
)
...
...
@@ -1458,15 +1462,13 @@ static void dump_cg_ir_block(ir_node * block, void * env) {
ir_node
*
node
;
pmap
*
irgmap
=
(
pmap
*
)
env
;
assert
(
is_Block
(
block
));
fprintf
(
F
,
"graph: { title:
\"
"
);
PRINT_NODEID
(
block
);
fprintf
(
F
,
"
\"
label:
\"
"
);
fprintf
(
F
,
"%s "
,
get_op_name
(
get_irn_op
(
block
)));
#ifdef DEBUG_libfirm
fprintf
(
F
,
"%ld"
,
get_irn_node_nr
(
block
));
#else
fprintf
(
F
,
"%p"
,
(
void
*
)
block
);
#endif
dump_node_opcode
(
block
);
fprintf
(
F
,
" %ld"
,
get_irn_node_nr
(
block
));
if
(
exc_normal
!=
get_Block_exc
(
block
))
{
fprintf
(
F
,
" (%s)"
,
exc_to_string
(
get_Block_exc
(
block
)));
}
...
...
@@ -1475,34 +1477,36 @@ static void dump_cg_ir_block(ir_node * block, void * env) {
get_Block_matured
(
block
)
?
"yellow"
:
"red"
);
/* dump the blocks edges */
dump_ir_data_edges
(
block
);
dump_ir_data_edges
(
block
,
irgmap
);
/* dump the nodes that go into the block */
for
(
node
=
get_irn_link
(
block
);
node
;
node
=
get_irn_link
(
node
))
{
dump_node
(
node
,
irgmap
);
dump_ir_data_edges
(
node
);
dump_ir_data_edges
(
node
,
irgmap
);
}
/* Close the vcg information for the block */
fprintf
(
F
,
"}
\n\n
"
);
fprintf
(
F
,
"}
\n
"
);
dump_const_node_local
(
block
,
irgmap
);
fprintf
(
F
,
"
\n
"
);
}
static
void
d_cg_block_graph
(
ir_graph
*
irg
,
ir_node
**
arr
,
pmap
*
irgmap
)
{
int
i
;
fprintf
(
F
,
"graph: { title:
%p
label:
%s
status:clustered color:white
\n
"
,
fprintf
(
F
,
"graph: { title:
\"
%p
\"
label:
\"
%s
\"
status:clustered color:white
\n
"
,
(
void
*
)
irg
,
get_entity_name
(
get_irg_ent
(
irg
)));
for
(
i
=
ARR_LEN
(
arr
)
-
1
;
i
>=
0
;
--
i
)
{
ir_node
*
node
=
arr
[
i
];
if
(
is_Block
(
node
))
{
/* Dumps the block and all the nodes in the block
, which are to
/* Dumps the block and all the nodes in the block, which are to
be found in Block->link. */
dump_cg_ir_block
(
node
,
irgmap
);
}
else
{
/* Nodes that are not in a Block. */
dump_node
(
node
,
NULL
);
dump_ir_data_edges
(
node
);
dump_ir_data_edges
(
node
,
NULL
);
}
}
/* Close the vcg information for the irg */
...
...
@@ -1604,12 +1608,12 @@ void dump_cg_graph(ir_graph * irg) {
for
(
i
=
ARR_LEN
(
arr
)
-
1
;
i
>=
0
;
--
i
)
{
ir_node
*
node
=
arr
[
i
];
dump_node
(
node
,
map2
);
dump_ir_data_edges
(
node
);
dump_ir_data_edges
(
node
,
NULL
);
if
(
is_Block
(
node
))
{
for
(
node
=
get_irn_link
(
node
);
node
;
node
=
get_irn_link
(
node
))
{
dump_node
(
node
,
map2
);
dump_ir_block_edge
(
node
);
dump_ir_data_edges
(
node
);
dump_ir_data_edges
(
node
,
NULL
);
}
}
}
...
...
ir/ir/irgopt.c
View file @
78a73b3b
...
...
@@ -529,6 +529,8 @@ copy_node_inline (ir_node *n, void *env) {
}
}
#include "irdump.h"
void
inline_method
(
ir_node
*
call
,
ir_graph
*
called_graph
)
{
ir_node
*
pre_call
;
ir_node
*
post_call
,
*
post_bl
;
...
...
@@ -775,8 +777,10 @@ void inline_method(ir_node *call, ir_graph *called_graph) {
cf_op
=
get_Block_cfgpred
(
end_bl
,
i
);
if
(
get_irn_op
(
cf_op
)
==
op_Proj
)
{
cf_op
=
get_Proj_pred
(
cf_op
);
if
(
get_irn_op
(
cf_op
)
==
op_Tuple
)
{
cf_op
=
get_Tuple_pred
(
cf_op
,
1
);
if
((
get_irn_op
(
cf_op
)
==
op_Tuple
)
&&
(
cf_op
==
call
))
{
// There are unoptimized tuples from inlineing before when no exc
assert
(
get_Proj_proj
(
get_Block_cfgpred
(
end_bl
,
i
))
==
pn_Call_X_except
);
cf_op
=
get_Tuple_pred
(
cf_op
,
pn_Call_X_except
);
assert
(
get_irn_op
(
cf_op
)
==
op_Jmp
);
break
;
}
...
...
@@ -1182,7 +1186,9 @@ static void merge_blocks(ir_node *n, void *env) {
while
(
irn_not_visited
(
b
)
&&
(
!
is_Bad
(
new
))
&&
(
new
!=
b
))
{
/* We would have to run gigo if new is bad, so we
promote it directly below. */
assert
(((
b
==
new
)
||
get_opt_control_flow_straightening
()
||
get_opt_control_flow_weak_simplification
())
&&
assert
(((
b
==
new
)
||
get_opt_control_flow_straightening
()
||
get_opt_control_flow_weak_simplification
())
&&
(
"strange flag setting"
));
exchange
(
b
,
new
);
b
=
new
;
...
...
@@ -1491,10 +1497,14 @@ static void walk_critical_cf_edges(ir_node *n, void *env) {
(
get_irn_arity
(
n
)
>
1
))
{
arity
=
get_irn_arity
(
n
);
if
(
n
==
get_irg_end_block
(
current_ir_graph
))
return
;
// No use to add a block here.
for
(
i
=
0
;
i
<
arity
;
i
++
)
{
pre
=
get_irn_n
(
n
,
i
);
/* Predecessor has multiple sucessors. Insert new flow edge */
if
((
NULL
!=
pre
)
&&
(
op_Proj
==
get_irn_op
(
pre
))
&&
if
((
NULL
!=
pre
)
&&
(
op_Proj
==
get_irn_op
(
pre
))
&&
op_Raise
!=
get_irn_op
(
skip_Proj
(
pre
)))
{
/* set predecessor array for new block */
...
...
ir/ir/irnode.c
View file @
78a73b3b
...
...
@@ -384,7 +384,7 @@ get_irn_node_nr(const ir_node *node) {
#ifdef DEBUG_libfirm
return
node
->
node_nr
;
#else
return
0
;
return
(
long
)
&
node
;
#endif
}
...
...
ir/ir/irnode.h
View file @
78a73b3b
...
...
@@ -150,7 +150,8 @@ INLINE void set_irn_link (ir_node *node, void *link);
INLINE
void
*
get_irn_link
(
const
ir_node
*
node
);
/** Outputs a unique number for this node if libfirm is compiled for
debugging, (configure with --enable-debug) else returns 0. */
debugging, (configure with --enable-debug) else returns address
of node cast to long. */
INLINE
long
get_irn_node_nr
(
const
ir_node
*
node
);
/** Returns the ir_graph this node belongs to. Only valid for
...
...
ir/ir/irvrfy.c
View file @
78a73b3b
...
...
@@ -263,23 +263,14 @@ int irn_vrfy_irg(ir_node *n, ir_graph *irg)
// End block may only have Return, Raise or fragile ops as preds.
if
(
n
==
get_irg_end_block
(
irg
))
for
(
i
=
0
;
i
<
get_Block_n_cfgpreds
(
n
);
++
i
)
{
#if 1 // Some optimization seems to add a Jmp to the End Block??
ir_node
*
pred
=
skip_Proj
(
get_Block_cfgpred
(
n
,
i
));
if
((
get_irn_op
(
pred
)
==
op_Return
)
||
is_Bad
(
pred
)
||
(
get_irn_op
(
pred
)
==
op_Raise
)
||
is_fragile_op
(
pred
)
)
{
}
else
{
DDMG
(
irg
);
printf
(
" pred %d, "
,
i
);
DDMN
(
n
);
DDMN
(
pred
);
}
if
(
is_Proj
(
pred
)
||
get_irn_op
(
pred
)
==
op_Tuple
)
break
;
// We can not test properly. How many tuples are there?
ASSERT_AND_RET
(((
get_irn_op
(
pred
)
==
op_Return
)
||
is_Bad
(
pred
)
||
(
get_irn_op
(
pred
)
==
op_Raise
)
||
is_fragile_op
(
pred
)
),
"End Block node"
,
0
);
#endif
}
break
;
...
...
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