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
2ba0d753
Commit
2ba0d753
authored
Apr 13, 2011
by
Matthias Braun
Browse files
adapt sparc backend to new prolog/epilog handling
parent
df2b9574
Changes
10
Hide whitespace changes
Inline
Side-by-side
ir/be/benode.c
View file @
2ba0d753
...
...
@@ -1050,6 +1050,63 @@ static const arch_irn_ops_t be_node_irn_ops = {
NULL
,
/* perform_memory_operand */
};
static
int
get_start_reg_index
(
ir_graph
*
irg
,
const
arch_register_t
*
reg
)
{
ir_node
*
start
=
get_irg_start
(
irg
);
unsigned
n_outs
=
arch_irn_get_n_outs
(
start
);
int
i
;
/* do a naive linear search... */
for
(
i
=
0
;
i
<
(
int
)
n_outs
;
++
i
)
{
const
arch_register_req_t
*
out_req
=
arch_get_out_register_req
(
start
,
i
);
if
(
!
(
out_req
->
type
&
arch_register_req_type_limited
))
continue
;
if
(
out_req
->
cls
!=
arch_register_get_class
(
reg
))
continue
;
if
(
!
rbitset_is_set
(
out_req
->
limited
,
reg
->
index
))
continue
;
return
i
;
}
panic
(
"Tried querying undefined register '%s' at Start"
,
reg
->
name
);
}
ir_node
*
be_get_initial_reg_value
(
ir_graph
*
irg
,
const
arch_register_t
*
reg
)
{
int
i
=
get_start_reg_index
(
irg
,
reg
);
ir_node
*
start
=
get_irg_start
(
irg
);
ir_mode
*
mode
=
arch_register_class_mode
(
arch_register_get_class
(
reg
));
const
ir_edge_t
*
edge
;
foreach_out_edge
(
start
,
edge
)
{
ir_node
*
proj
=
get_edge_src_irn
(
edge
);
if
(
!
is_Proj
(
proj
))
// maybe End/Anchor
continue
;
if
(
get_Proj_proj
(
proj
)
==
i
)
{
return
proj
;
}
}
return
new_r_Proj
(
start
,
mode
,
i
);
}
int
be_find_return_reg_input
(
ir_node
*
ret
,
const
arch_register_t
*
reg
)
{
int
arity
=
get_irn_arity
(
ret
);
int
i
;
/* do a naive linear search... */
for
(
i
=
0
;
i
<
arity
;
++
i
)
{
const
arch_register_req_t
*
req
=
arch_get_in_register_req
(
ret
,
i
);
if
(
!
(
req
->
type
&
arch_register_req_type_limited
))
continue
;
if
(
req
->
cls
!=
arch_register_get_class
(
reg
))
continue
;
if
(
!
rbitset_is_set
(
req
->
limited
,
reg
->
index
))
continue
;
return
i
;
}
panic
(
"Tried querying undefined register '%s' at Return"
,
reg
->
name
);
}
static
arch_irn_class_t
dummy_classify
(
const
ir_node
*
node
)
{
(
void
)
node
;
...
...
ir/be/benode.h
View file @
2ba0d753
...
...
@@ -479,6 +479,17 @@ void be_dump_phi_reg_reqs(FILE *out, ir_node *node, dump_reason_t reason);
ir_node
*
be_new_Phi
(
ir_node
*
block
,
int
n_ins
,
ir_node
**
ins
,
ir_mode
*
mode
,
const
arch_register_class_t
*
cls
);
/**
* Search for output of start node with a specific register
*/
ir_node
*
be_get_initial_reg_value
(
ir_graph
*
irg
,
const
arch_register_t
*
reg
);
/**
* Search for input of a return node with a specific register and return
* its number.
*/
int
be_find_return_reg_input
(
ir_node
*
ret
,
const
arch_register_t
*
reg
);
static
inline
int
be_is_Spill
(
const
ir_node
*
irn
)
{
return
get_irn_opcode
(
irn
)
==
beo_Spill
;
}
static
inline
int
be_is_Reload
(
const
ir_node
*
irn
)
{
return
get_irn_opcode
(
irn
)
==
beo_Reload
;
}
static
inline
int
be_is_Copy
(
const
ir_node
*
irn
)
{
return
get_irn_opcode
(
irn
)
==
beo_Copy
;
}
...
...
@@ -491,7 +502,7 @@ static inline int be_is_Return (const ir_node *irn) { return get_irn_opcode(ir
static
inline
int
be_is_IncSP
(
const
ir_node
*
irn
)
{
return
get_irn_opcode
(
irn
)
==
beo_IncSP
;
}
static
inline
int
be_is_AddSP
(
const
ir_node
*
irn
)
{
return
get_irn_opcode
(
irn
)
==
beo_AddSP
;
}
static
inline
int
be_is_SubSP
(
const
ir_node
*
irn
)
{
return
get_irn_opcode
(
irn
)
==
beo_SubSP
;
}
static
inline
int
be_is_Start
(
const
ir_node
*
irn
)
{
return
get_irn_opcode
(
irn
)
==
beo_Start
;
}
static
inline
int
be_is_Start
(
const
ir_node
*
irn
)
{
return
get_irn_opcode
(
irn
)
==
beo_Start
;
}
static
inline
int
be_is_FrameAddr
(
const
ir_node
*
irn
)
{
return
get_irn_opcode
(
irn
)
==
beo_FrameAddr
;
}
#endif
ir/be/ia32/bearch_ia32.c
View file @
2ba0d753
...
...
@@ -263,45 +263,6 @@ static int ia32_get_sp_bias(const ir_node *node)
return
0
;
}
static
int
get_start_reg_index
(
ir_graph
*
irg
,
const
arch_register_t
*
reg
)
{
ir_node
*
start
=
get_irg_start
(
irg
);
unsigned
n_outs
=
arch_irn_get_n_outs
(
start
);
int
i
;
/* do a naive linear search... */
for
(
i
=
0
;
i
<
(
int
)
n_outs
;
++
i
)
{
const
arch_register_req_t
*
out_req
=
arch_get_out_register_req
(
start
,
i
);
if
(
!
(
out_req
->
type
&
arch_register_req_type_limited
))
continue
;
if
(
out_req
->
cls
!=
arch_register_get_class
(
reg
))
continue
;
if
(
!
rbitset_is_set
(
out_req
->
limited
,
reg
->
index
))
continue
;
return
i
;
}
panic
(
"Tried querying undefined register '%s' at Start"
,
reg
->
name
);
}
ir_node
*
ia32_get_initial_reg_value
(
ir_graph
*
irg
,
const
arch_register_t
*
reg
)
{
int
i
=
get_start_reg_index
(
irg
,
reg
);
ir_node
*
start
=
get_irg_start
(
irg
);
ir_mode
*
mode
=
arch_register_class_mode
(
arch_register_get_class
(
reg
));
const
ir_edge_t
*
edge
;
foreach_out_edge
(
start
,
edge
)
{
ir_node
*
proj
=
get_edge_src_irn
(
edge
);
if
(
!
is_Proj
(
proj
))
// maybe End/Anchor
continue
;
if
(
get_Proj_proj
(
proj
)
==
i
)
{
return
proj
;
}
}
return
new_r_Proj
(
start
,
mode
,
i
);
}
/**
* Build the between type and entities if not already build.
*/
...
...
@@ -1028,7 +989,7 @@ static void transform_MemPerm(ir_node *node)
{
ir_node
*
block
=
get_nodes_block
(
node
);
ir_graph
*
irg
=
get_irn_irg
(
node
);
ir_node
*
sp
=
ia32
_get_initial_reg_value
(
irg
,
&
ia32_registers
[
REG_ESP
]);
ir_node
*
sp
=
be
_get_initial_reg_value
(
irg
,
&
ia32_registers
[
REG_ESP
]);
int
arity
=
be_get_MemPerm_entity_arity
(
node
);
ir_node
**
pops
=
ALLOCAN
(
ir_node
*
,
arity
);
ir_node
*
in
[
1
];
...
...
@@ -1292,7 +1253,7 @@ static void introduce_prolog_epilog(ir_graph *irg)
ir_type
*
frame_type
=
get_irg_frame_type
(
irg
);
unsigned
frame_size
=
get_type_size_bytes
(
frame_type
);
be_stack_layout_t
*
layout
=
be_get_irg_stack_layout
(
irg
);
ir_node
*
initial_sp
=
ia32
_get_initial_reg_value
(
irg
,
sp
);
ir_node
*
initial_sp
=
be
_get_initial_reg_value
(
irg
,
sp
);
ir_node
*
curr_sp
=
initial_sp
;
ir_mode
*
mode_gp
=
mode_Iu
;
...
...
@@ -1300,7 +1261,7 @@ static void introduce_prolog_epilog(ir_graph *irg)
/* push ebp */
ir_node
*
mem
=
get_irg_initial_mem
(
irg
);
ir_node
*
noreg
=
ia32_new_NoReg_gp
(
irg
);
ir_node
*
initial_bp
=
ia32
_get_initial_reg_value
(
irg
,
bp
);
ir_node
*
initial_bp
=
be
_get_initial_reg_value
(
irg
,
bp
);
ir_node
*
curr_bp
=
initial_bp
;
ir_node
*
push
=
new_bd_ia32_Push
(
NULL
,
block
,
noreg
,
noreg
,
mem
,
curr_bp
,
curr_sp
);
ir_node
*
incsp
;
...
...
ir/be/ia32/bearch_ia32_t.h
View file @
2ba0d753
...
...
@@ -154,9 +154,4 @@ ir_entity *ia32_get_return_address_entity(ir_graph *irg);
*/
ir_entity
*
ia32_get_frame_address_entity
(
ir_graph
*
irg
);
/**
* Get node representing the initial value of a register
*/
ir_node
*
ia32_get_initial_reg_value
(
ir_graph
*
irg
,
const
arch_register_t
*
reg
);
#endif
ir/be/ia32/ia32_fpu.c
View file @
2ba0d753
...
...
@@ -260,7 +260,7 @@ static void rewire_fpu_mode_nodes(ir_graph *irg)
return
;
}
initial_value
=
ia32
_get_initial_reg_value
(
irg
,
reg
);
initial_value
=
be
_get_initial_reg_value
(
irg
,
reg
);
be_ssa_construction_init
(
&
senv
,
irg
);
be_ssa_construction_add_copies
(
&
senv
,
env
.
state_nodes
,
ARR_LEN
(
env
.
state_nodes
));
...
...
ir/be/ia32/ia32_transform.c
View file @
2ba0d753
...
...
@@ -5822,8 +5822,7 @@ void ia32_transform_graph(ir_graph *irg)
initial_fpcw
=
NULL
;
ia32_no_pic_adjust
=
0
;
old_initial_fpcw
=
ia32_get_initial_reg_value
(
irg
,
&
ia32_registers
[
REG_FPCW
]);
old_initial_fpcw
=
be_get_initial_reg_value
(
irg
,
&
ia32_registers
[
REG_FPCW
]);
be_timer_push
(
T_HEIGHTS
);
ia32_heights
=
heights_new
(
irg
);
...
...
ir/be/sparc/bearch_sparc.c
View file @
2ba0d753
...
...
@@ -292,6 +292,8 @@ static void sparc_after_ra(ir_graph *irg)
be_free_frame_entity_coalescer
(
fec_env
);
irg_block_walk_graph
(
irg
,
NULL
,
sparc_after_ra_walker
,
NULL
);
sparc_introduce_prolog_epilog
(
irg
);
}
static
void
sparc_init_graph
(
ir_graph
*
irg
)
...
...
ir/be/sparc/bearch_sparc_t.h
View file @
2ba0d753
...
...
@@ -74,4 +74,6 @@ static inline bool sparc_is_value_imm_encodeable(int32_t value)
void
sparc_finish
(
ir_graph
*
irg
);
void
sparc_introduce_prolog_epilog
(
ir_graph
*
irg
);
#endif
ir/be/sparc/sparc_finish.c
View file @
2ba0d753
...
...
@@ -44,11 +44,120 @@
#include "sparc_new_nodes.h"
#include "irprog.h"
#include "irgmod.h"
#include "ircons.h"
#include "../bepeephole.h"
#include "../benode.h"
#include "../besched.h"
static
void
kill_unused_stacknodes
(
ir_node
*
node
)
{
if
(
get_irn_n_edges
(
node
)
>
0
)
return
;
if
(
be_is_IncSP
(
node
))
{
sched_remove
(
node
);
kill_node
(
node
);
}
else
if
(
is_Phi
(
node
))
{
int
arity
=
get_irn_arity
(
node
);
ir_node
**
ins
=
ALLOCAN
(
ir_node
*
,
arity
);
int
i
;
sched_remove
(
node
);
memcpy
(
ins
,
get_irn_in
(
node
),
arity
*
sizeof
(
ins
[
0
]));
kill_node
(
node
);
for
(
i
=
0
;
i
<
arity
;
++
i
)
kill_unused_stacknodes
(
ins
[
i
]);
}
}
static
void
introduce_epilog
(
ir_node
*
ret
)
{
const
arch_register_t
*
sp_reg
=
&
sparc_registers
[
REG_SP
];
ir_graph
*
irg
=
get_irn_irg
(
ret
);
be_stack_layout_t
*
layout
=
be_get_irg_stack_layout
(
irg
);
ir_node
*
block
=
get_nodes_block
(
ret
);
ir_type
*
frame_type
=
get_irg_frame_type
(
irg
);
unsigned
frame_size
=
get_type_size_bytes
(
frame_type
);
int
sp_idx
=
be_find_return_reg_input
(
ret
,
sp_reg
);
ir_node
*
sp
=
get_irn_n
(
ret
,
sp_idx
);
if
(
!
layout
->
sp_relative
)
{
const
arch_register_t
*
fp_reg
=
&
sparc_registers
[
REG_FRAME_POINTER
];
ir_node
*
fp
=
be_get_initial_reg_value
(
irg
,
fp_reg
);
ir_node
*
restore
=
new_bd_sparc_RestoreZero
(
NULL
,
block
,
fp
);
sched_add_before
(
ret
,
restore
);
arch_set_irn_register
(
restore
,
sp_reg
);
set_irn_n
(
ret
,
sp_idx
,
restore
);
kill_unused_stacknodes
(
sp
);
}
else
{
ir_node
*
incsp
=
be_new_IncSP
(
sp_reg
,
block
,
sp
,
frame_size
,
0
);
set_irn_n
(
ret
,
sp_idx
,
incsp
);
sched_add_before
(
ret
,
incsp
);
}
}
void
sparc_introduce_prolog_epilog
(
ir_graph
*
irg
)
{
const
arch_register_t
*
sp_reg
=
&
sparc_registers
[
REG_SP
];
ir_node
*
start
=
get_irg_start
(
irg
);
be_stack_layout_t
*
layout
=
be_get_irg_stack_layout
(
irg
);
ir_node
*
block
=
get_nodes_block
(
start
);
ir_node
*
initial_sp
=
be_get_initial_reg_value
(
irg
,
sp_reg
);
ir_node
*
sp
=
initial_sp
;
ir_node
*
schedpoint
=
start
;
ir_type
*
frame_type
=
get_irg_frame_type
(
irg
);
unsigned
frame_size
=
get_type_size_bytes
(
frame_type
);
/* introduce epilog for every return node */
{
ir_node
*
end_block
=
get_irg_end_block
(
irg
);
int
arity
=
get_irn_arity
(
end_block
);
int
i
;
for
(
i
=
0
;
i
<
arity
;
++
i
)
{
ir_node
*
ret
=
get_irn_n
(
end_block
,
i
);
assert
(
be_is_Return
(
ret
));
introduce_epilog
(
ret
);
}
}
while
(
be_is_Keep
(
sched_next
(
schedpoint
)))
schedpoint
=
sched_next
(
schedpoint
);
if
(
!
layout
->
sp_relative
)
{
ir_node
*
incsp
;
ir_node
*
save
=
new_bd_sparc_Save_imm
(
NULL
,
block
,
sp
,
NULL
,
-
SPARC_MIN_STACKSIZE
);
arch_set_irn_register
(
save
,
sp_reg
);
sched_add_after
(
schedpoint
,
save
);
schedpoint
=
save
;
incsp
=
be_new_IncSP
(
sp_reg
,
block
,
save
,
frame_size
,
0
);
edges_reroute
(
initial_sp
,
incsp
);
set_irn_n
(
save
,
n_sparc_Save_stack
,
initial_sp
);
sched_add_after
(
schedpoint
,
incsp
);
schedpoint
=
incsp
;
/* we still need the IncSP even if noone is explicitely using the
* value. (TODO: this isn't 100% correct yet, something at the end of
* the function should hold the IncSP, even if we use a restore
* which just overrides it instead of using the value)
*/
if
(
get_irn_n_edges
(
incsp
)
==
0
)
{
ir_node
*
in
[]
=
{
incsp
};
ir_node
*
keep
=
be_new_Keep
(
block
,
1
,
in
);
sched_add_after
(
schedpoint
,
keep
);
}
}
else
{
ir_node
*
incsp
=
be_new_IncSP
(
sp_reg
,
block
,
sp
,
frame_size
,
0
);
edges_reroute
(
initial_sp
,
incsp
);
be_set_IncSP_pred
(
incsp
,
sp
);
sched_add_after
(
schedpoint
,
incsp
);
}
}
static
void
finish_sparc_Save
(
ir_node
*
node
)
{
sparc_attr_t
*
attr
=
get_sparc_attr
(
node
);
...
...
@@ -265,11 +374,13 @@ static void register_peephole_optimisation(ir_op *op, peephole_opt_func func)
void
sparc_finish
(
ir_graph
*
irg
)
{
/* perform peephole optimizations */
clear_irp_opcodes_generic_func
();
register_peephole_optimisation
(
op_be_IncSP
,
peephole_be_IncSP
);
register_peephole_optimisation
(
op_sparc_FrameAddr
,
peephole_sparc_FrameAddr
);
be_peephole_opt
(
irg
);
/* perform legalizations (mostly fix nodes with too big immediates) */
clear_irp_opcodes_generic_func
();
register_peephole_optimisation
(
op_be_IncSP
,
finish_be_IncSP
);
register_peephole_optimisation
(
op_be_Return
,
finish_be_Return
);
...
...
ir/be/sparc/sparc_transform.c
View file @
2ba0d753
...
...
@@ -1301,9 +1301,7 @@ static ir_node *gen_Start(ir_node *node)
ir_node
*
block
=
get_nodes_block
(
node
);
ir_node
*
new_block
=
be_transform_node
(
block
);
dbg_info
*
dbgi
=
get_irn_dbg_info
(
node
);
ir_node
*
mem
;
ir_node
*
start
;
ir_node
*
sp
;
size_t
i
;
/* stackpointer is important at function prolog */
...
...
@@ -1337,25 +1335,6 @@ ir_node *sp;
}
start
=
be_prolog_create_start
(
abihelper
,
dbgi
,
new_block
);
#if 0
mem = be_prolog_get_memory(abihelper);
sp = be_prolog_get_reg_value(abihelper, sp_reg);
if (!cconv->omit_fp) {
ir_node *save = new_bd_sparc_Save_imm(NULL, block, sp, NULL,
-SPARC_MIN_STACKSIZE);
arch_irn_add_flags(save, arch_irn_flags_prolog);
arch_set_irn_register(save, sp_reg);
sp = save;
keep_alive(save);
}
sp = be_new_IncSP(sp_reg, new_block, sp, BE_STACK_FRAME_SIZE_EXPAND, 0);
arch_irn_add_flags(sp, arch_irn_flags_prolog);
be_prolog_set_reg_value(abihelper, sp_reg, sp);
be_prolog_set_memory(abihelper, mem);
#endif
return
start
;
}
...
...
@@ -1428,24 +1407,6 @@ static ir_node *gen_Return(ir_node *node)
}
}
#if 0
/* we need a restore instruction */
if (!cconv->omit_fp) {
ir_node *fp = be_prolog_get_reg_value(abihelper, fp_reg);
ir_node *restore = new_bd_sparc_RestoreZero(NULL, block, fp);
arch_irn_add_flags(restore, arch_irn_flags_epilog);
arch_set_irn_register(restore, sp_reg);
be_epilog_set_reg_value(abihelper, sp_reg, restore);
} else {
/* epilog code: an incsp */
sp = be_epilog_get_reg_value(abihelper, sp_reg);
sp = be_new_IncSP(sp_reg, new_block, sp,
BE_STACK_FRAME_SIZE_SHRINK, 0);
arch_irn_add_flags(sp, arch_irn_flags_epilog);
be_epilog_set_reg_value(abihelper, sp_reg, sp);
}
#endif
bereturn
=
be_epilog_create_return
(
abihelper
,
dbgi
,
new_block
);
return
bereturn
;
}
...
...
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