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
ee44e331
Commit
ee44e331
authored
Jan 20, 2009
by
Michael Beck
Browse files
- fixed handling of outer frame access
[r25277]
parent
a63ae972
Changes
3
Hide whitespace changes
Inline
Side-by-side
ir/ana/analyze_irg_args.c
View file @
ee44e331
...
...
@@ -20,19 +20,21 @@
/**
* @file
* @brief read/write analyze of graph argument, which have mode reference.
* @author Beyhan Veliev
* @author Beyhan Veliev
, Michael Beck
* @version $Id$
*/
#include "config.h"
#include <stdlib.h>
#include "adt/raw_bitset.h"
#include "irouts.h"
#include "irnode_t.h"
#include "irmode_t.h"
#include "array_t.h"
#include "irprog.h"
#include "entity_t.h"
#include "irgwalk.h"
#include "analyze_irg_args.h"
...
...
@@ -493,6 +495,110 @@ unsigned get_method_param_weight(ir_entity *ent, int pos)
return
null_weight
;
}
typedef
struct
walk_env
{
unsigned
*
marks
;
/**< raw bitset for nodes that could be analysed */
unsigned
*
param_mask
;
/**< raw bitset of constant parameters */
unsigned
mask_len
;
/**< length of the parameter bitmask */
unsigned
weight
;
/**< the accumulated weight */
}
walk_env
;
/**
* Walker, evaluates possible constant folding
*/
static
void
evaluate_weight
(
ir_node
*
irn
,
void
*
ctx
)
{
walk_env
*
env
=
ctx
;
int
i
,
n
;
ir_node
*
ptr
;
if
(
is_arg_Proj
(
irn
))
{
unsigned
argnum
=
(
unsigned
)
get_Proj_proj
(
irn
);
if
(
argnum
<
env
->
mask_len
)
{
if
(
rbitset_is_set
(
env
->
param_mask
,
argnum
))
{
/* is a constant parameter */
rbitset_set
(
env
->
marks
,
get_irn_idx
(
irn
));
}
}
return
;
}
if
(
is_irn_constlike
(
irn
))
{
/* is a constant by itself */
rbitset_set
(
env
->
marks
,
get_irn_idx
(
irn
));
return
;
}
if
(
is_Block
(
irn
))
return
;
/* handle some special cases */
switch
(
get_irn_opcode
(
irn
))
{
case
iro_Div
:
case
iro_Quot
:
case
iro_Mod
:
case
iro_DivMod
:
/* skip the memory input of these nodes */
assert
(
pn_Generic_M_regular
==
0
);
n
=
1
;
break
;
case
iro_Call
:
ptr
=
get_Call_ptr
(
irn
);
if
(
!
is_SymConst
(
ptr
)
&&
rbitset_is_set
(
env
->
marks
,
get_irn_idx
(
ptr
)))
{
/* the arguments is used as an pointer input for a call,
we can probably change an indirect Call into a direct one. */
env
->
weight
+=
indirect_call_weight
;
}
n
=
2
;
break
;
default:
n
=
0
;
break
;
}
for
(
i
=
get_irn_arity
(
irn
)
-
1
;
i
>=
n
;
--
i
)
{
ir_node
*
pred
=
get_irn_n
(
irn
,
i
);
if
(
!
rbitset_is_set
(
env
->
marks
,
get_irn_idx
(
pred
)))
{
/* not constant predecessor ... */
return
;
}
}
/* all predecessors are constant, we probably can fold this node */
rbitset_set
(
env
->
marks
,
get_irn_idx
(
irn
));
if
(
is_binop
(
irn
))
{
env
->
weight
+=
const_binop_weight
;
}
else
if
(
is_unop
(
irn
))
{
env
->
weight
+=
const_binop_weight
;
}
else
if
(
is_Proj
(
irn
))
{
ir_node
*
pred
=
get_Proj_pred
(
irn
);
if
(
is_Cmp
(
pred
))
{
env
->
weight
+=
const_cmp_weight
;
}
else
if
(
is_Cond
(
pred
))
{
/* the argument is used for a SwitchCond, a big win */
env
->
weight
+=
const_cmp_weight
;
}
}
}
/**
*
*/
unsigned
analyze_irg_param_weights
(
ir_graph
*
irg
,
unsigned
*
bitmask
,
unsigned
len
)
{
unsigned
nodes
=
get_irg_last_idx
(
irg
);
unsigned
*
marks
=
rbitset_malloc
(
nodes
);
walk_env
env
;
env
.
marks
=
marks
;
env
.
param_mask
=
bitmask
;
env
.
mask_len
=
len
;
env
.
weight
=
null_weight
;
irg_walk_graph
(
irg
,
NULL
,
evaluate_weight
,
&
env
);
xfree
(
marks
);
return
env
.
weight
;
}
/**
* Analyze argument's weight of a given
* ir graph.
...
...
ir/be/beabi.c
View file @
ee44e331
...
...
@@ -1741,9 +1741,12 @@ static void fix_start_block(ir_graph *irg)
panic
(
"Initial exec has no follow block in %+F"
,
irg
);
}
static
void
lower_outer_frame_sels
(
ir_node
*
irn
,
void
*
env
)
{
/**
* Update the entity of Sels to the outer value parameters.
*/
static
void
update_outer_frame_sels
(
ir_node
*
irn
,
void
*
env
)
{
lower_frame_sels_env_t
*
ctx
=
env
;
ir_node
*
ptr
,
*
bl
,
*
nw
;
ir_node
*
ptr
;
ir_entity
*
ent
;
int
pos
=
0
;
...
...
@@ -1760,21 +1763,19 @@ static void lower_outer_frame_sels(ir_node *irn, void *env) {
/* replace by its copy from the argument type */
pos
=
get_struct_member_index
(
ctx
->
value_tp
,
ent
);
ent
=
get_argument_entity
(
ent
,
ctx
);
}
bl
=
get_nodes_block
(
irn
);
nw
=
be_new_FrameAddr
(
ctx
->
link_class
,
current_ir_graph
,
bl
,
ptr
,
ent
);
exchange
(
irn
,
nw
);
/* check, if it's a param sel and if have not seen this entity before */
if
(
get_entity_owner
(
ent
)
==
ctx
->
value_tp
&&
get_entity_link
(
ent
)
==
NULL
)
{
ent_pos_pair
pair
;
pair
.
ent
=
ent
;
pair
.
pos
=
pos
;
pair
.
next
=
NULL
;
ARR_APP1
(
ent_pos_pair
,
ctx
->
value_param_list
,
pair
);
/* just a mark */
set_entity_link
(
ent
,
ctx
->
value_param_list
);
set_Sel_entity
(
irn
,
ent
);
/* check, if we have not seen this entity before */
if
(
get_entity_link
(
ent
)
==
NULL
)
{
ent_pos_pair
pair
;
pair
.
ent
=
ent
;
pair
.
pos
=
pos
;
pair
.
next
=
NULL
;
ARR_APP1
(
ent_pos_pair
,
ctx
->
value_param_list
,
pair
);
/* just a mark */
set_entity_link
(
ent
,
ctx
->
value_param_list
);
}
}
}
...
...
@@ -1799,7 +1800,7 @@ static void fix_outer_variable_access(be_abi_irg_t *env, lower_frame_sels_env_t
ctx
->
static_link_pos
=
0
;
irg
=
get_entity_irg
(
ent
);
irg_walk_graph
(
irg
,
NULL
,
lower
_outer_frame_sels
,
ctx
);
irg_walk_graph
(
irg
,
NULL
,
update
_outer_frame_sels
,
ctx
);
}
}
...
...
@@ -2598,9 +2599,45 @@ static void stack_bias_walker(ir_node *bl, void *data)
}
}
/**
* Walker: finally lower all Sels of outer frame or parameter
* entities.
*/
static
void
lower_outer_frame_sels
(
ir_node
*
sel
,
void
*
ctx
)
{
be_abi_irg_t
*
env
=
ctx
;
ir_node
*
ptr
;
ir_entity
*
ent
;
ir_type
*
owner
;
if
(
!
is_Sel
(
sel
))
return
;
ent
=
get_Sel_entity
(
sel
);
owner
=
get_entity_owner
(
ent
);
ptr
=
get_Sel_ptr
(
sel
);
if
(
owner
==
env
->
frame
.
frame_type
||
owner
==
env
->
frame
.
arg_type
)
{
/* found access to outer frame or arguments */
int
offset
=
get_stack_entity_offset
(
&
env
->
frame
,
ent
,
0
);
if
(
offset
!=
0
)
{
ir_node
*
bl
=
get_nodes_block
(
sel
);
dbg_info
*
dbgi
=
get_irn_dbg_info
(
sel
);
ir_mode
*
mode
=
get_irn_mode
(
sel
);
ir_mode
*
mode_UInt
=
get_reference_mode_unsigned_eq
(
mode
);
ir_node
*
cnst
=
new_r_Const_long
(
current_ir_graph
,
mode_UInt
,
offset
);
ptr
=
new_rd_Add
(
dbgi
,
current_ir_graph
,
bl
,
ptr
,
cnst
,
mode
);
}
exchange
(
sel
,
ptr
);
}
}
void
be_abi_fix_stack_bias
(
be_abi_irg_t
*
env
)
{
ir_graph
*
irg
=
env
->
birg
->
irg
;
ir_graph
*
irg
=
env
->
birg
->
irg
;
ir_type
*
frame_tp
;
int
i
;
struct
bias_walk
bw
;
stack_frame_compute_initial_offset
(
&
env
->
frame
);
...
...
@@ -2614,6 +2651,19 @@ void be_abi_fix_stack_bias(be_abi_irg_t *env)
bw
.
env
=
env
;
bw
.
start_block
=
get_irg_start_block
(
irg
);
irg_block_walk_graph
(
irg
,
stack_bias_walker
,
NULL
,
&
bw
);
/* fix now inner functions: these still have Sel node to outer
frame and parameter entities */
frame_tp
=
get_irg_frame_type
(
irg
);
for
(
i
=
get_class_n_members
(
frame_tp
)
-
1
;
i
>=
0
;
--
i
)
{
ir_entity
*
ent
=
get_class_member
(
frame_tp
,
i
);
if
(
is_method_entity
(
ent
))
{
ir_graph
*
irg
=
get_entity_irg
(
ent
);
irg_walk_graph
(
irg
,
NULL
,
lower_outer_frame_sels
,
env
);
}
}
}
ir_node
*
be_abi_get_callee_save_irn
(
be_abi_irg_t
*
abi
,
const
arch_register_t
*
reg
)
...
...
ir/opt/gvn_pre.c
View file @
ee44e331
...
...
@@ -407,9 +407,10 @@ static ir_node *phi_translate(ir_node *node, ir_node *block, int pos, ir_valuese
if
(
trans
==
NULL
)
trans
=
leader
;
if
(
is_Phi
(
trans
)
&&
get_nodes_block
(
trans
)
==
block
)
set_irn_n
(
nn
,
i
,
get_Phi_pred
(
trans
,
pos
));
else
if
(
is_Phi
(
trans
)
&&
get_nodes_block
(
trans
)
==
block
)
{
ir_node
*
trans_pred
=
get_Phi_pred
(
trans
,
pos
);
set_irn_n
(
nn
,
i
,
trans_pred
);
}
else
set_irn_n
(
nn
,
i
,
trans
);
}
nn
=
optimize_node
(
nn
);
...
...
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