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
c5b09702
Commit
c5b09702
authored
Oct 17, 2011
by
Matthias Braun
Browse files
be: factor out can_move_to function from sparc_emitter
parent
6da9f4a5
Changes
3
Hide whitespace changes
Inline
Side-by-side
ir/be/bepeephole.c
View file @
c5b09702
...
...
@@ -248,6 +248,55 @@ bool be_has_only_one_user(ir_node *node)
return
n_users
==
1
;
}
bool
be_can_move_before
(
const
ir_node
*
node
,
const
ir_node
*
before
)
{
int
node_arity
=
get_irn_arity
(
node
);
ir_node
*
schedpoint
=
sched_next
(
node
);
while
(
schedpoint
!=
before
)
{
int
i
;
int
arity
=
get_irn_arity
(
schedpoint
);
unsigned
n_outs
=
arch_get_irn_n_outs
(
schedpoint
);
/* the node must not use our computed values */
for
(
i
=
0
;
i
<
arity
;
++
i
)
{
ir_node
*
in
=
get_irn_n
(
schedpoint
,
i
);
if
(
skip_Proj
(
in
)
==
node
)
return
false
;
}
/* the node must not overwrite registers of our inputs */
for
(
i
=
0
;
i
<
node_arity
;
++
i
)
{
ir_node
*
in
=
get_irn_n
(
node
,
i
);
const
arch_register_t
*
reg
=
arch_get_irn_register
(
in
);
const
arch_register_req_t
*
in_req
=
arch_get_irn_register_req_in
(
node
,
i
);
unsigned
o
;
if
(
reg
==
NULL
)
continue
;
for
(
o
=
0
;
o
<
n_outs
;
++
o
)
{
const
arch_register_t
*
outreg
=
arch_get_irn_register_out
(
schedpoint
,
o
);
const
arch_register_req_t
*
outreq
=
arch_get_irn_register_req_out
(
schedpoint
,
o
);
if
(
outreg
==
NULL
)
continue
;
if
(
outreg
->
global_index
>=
reg
->
global_index
&&
outreg
->
global_index
<
(
unsigned
)
reg
->
global_index
+
in_req
->
width
)
return
false
;
if
(
reg
->
global_index
>=
outreg
->
global_index
&&
reg
->
global_index
<
(
unsigned
)
outreg
->
global_index
+
outreq
->
width
)
return
false
;
}
}
schedpoint
=
sched_next
(
schedpoint
);
}
return
true
;
}
/*
* Tries to optimize a beIncSP node with its previous IncSP node.
* Must be run from a be_peephole_opt() context.
...
...
ir/be/bepeephole.h
View file @
c5b09702
...
...
@@ -73,6 +73,16 @@ ir_node *be_peephole_IncSP_IncSP(ir_node *node);
bool
be_has_only_one_user
(
ir_node
*
node
);
/**
* In a scheduled program with registers assigned,
* checks wether @p node can be moved before @p before without changing program
* semantics.
*
* Note: It is allowed to use this function without being in a peephole
* optimization phase.
*/
bool
be_can_move_before
(
const
ir_node
*
node
,
const
ir_node
*
before
);
/**
* Do peephole optimisations. It traverses the schedule of all blocks in
* backward direction. The register_values variable indicates which (live)
...
...
ir/be/sparc/sparc_emitter.c
View file @
c5b09702
...
...
@@ -50,6 +50,7 @@
#include
"be_dbgout.h"
#include
"benode.h"
#include
"bestack.h"
#include
"bepeephole.h"
#include
"sparc_emitter.h"
#include
"gen_sparc_emitter.h"
...
...
@@ -392,85 +393,41 @@ static bool writes_reg(const ir_node *node, const arch_register_t *reg)
static
bool
can_move_into_delayslot
(
const
ir_node
*
node
,
const
ir_node
*
to
)
{
int
node_arity
=
get_irn_arity
(
node
);
ir_node
*
schedpoint
=
sched_next
(
node
);
while
(
true
)
{
if
(
schedpoint
!=
to
)
{
int
i
;
int
arity
=
get_irn_arity
(
schedpoint
);
unsigned
n_outs
=
arch_get_irn_n_outs
(
schedpoint
);
/* the node must not use our computed values */
for
(
i
=
0
;
i
<
arity
;
++
i
)
{
ir_node
*
in
=
get_irn_n
(
schedpoint
,
i
);
if
(
skip_Proj
(
in
)
==
node
)
return
false
;
}
/* the node must not overwrite registers of our inputs */
for
(
i
=
0
;
i
<
node_arity
;
++
i
)
{
ir_node
*
in
=
get_irn_n
(
node
,
i
);
const
arch_register_t
*
reg
=
arch_get_irn_register
(
in
);
const
arch_register_req_t
*
in_req
=
arch_get_irn_register_req_in
(
node
,
i
);
unsigned
o
;
if
(
reg
==
NULL
)
continue
;
for
(
o
=
0
;
o
<
n_outs
;
++
o
)
{
const
arch_register_t
*
outreg
=
arch_get_irn_register_out
(
schedpoint
,
o
);
const
arch_register_req_t
*
outreq
=
arch_get_irn_register_req_out
(
schedpoint
,
o
);
if
(
outreg
==
NULL
)
continue
;
if
(
outreg
->
global_index
>=
reg
->
global_index
&&
outreg
->
global_index
<
(
unsigned
)
reg
->
global_index
+
in_req
->
width
)
return
false
;
if
(
reg
->
global_index
>=
outreg
->
global_index
&&
reg
->
global_index
<
(
unsigned
)
outreg
->
global_index
+
outreq
->
width
)
return
false
;
}
}
}
else
{
if
(
is_sparc_Call
(
to
))
{
ir_node
*
check
;
/** all deps are used after the delay slot so, we're fine */
if
(
!
is_sparc_reg_call
(
to
))
return
true
;
check
=
get_irn_n
(
to
,
get_sparc_Call_dest_addr_pos
(
to
));
if
(
skip_Proj
(
check
)
==
node
)
return
false
;
/* the Call also destroys the value of %o7, but since this is
* currently marked as ignore register in the backend, it
* should never be used by the instruction in the delay slot. */
if
(
uses_reg
(
node
,
&
sparc_registers
[
REG_O7
]))
return
false
;
return
true
;
}
else
if
(
is_sparc_Return
(
to
))
{
/* return uses the value of %o7, all other values are not
* immediately used */
if
(
writes_reg
(
node
,
&
sparc_registers
[
REG_O7
]))
return
false
;
return
true
;
}
else
{
/* the node must not use our computed values */
int
arity
=
get_irn_arity
(
to
);
int
i
;
for
(
i
=
0
;
i
<
arity
;
++
i
)
{
ir_node
*
in
=
get_irn_n
(
to
,
i
);
if
(
skip_Proj
(
in
)
==
node
)
return
false
;
}
return
true
;
}
}
if
(
!
be_can_move_before
(
node
,
to
))
return
false
;
schedpoint
=
sched_next
(
schedpoint
);
if
(
is_sparc_Call
(
to
))
{
ir_node
*
check
;
/** all deps are used after the delay slot so, we're fine */
if
(
!
is_sparc_reg_call
(
to
))
return
true
;
check
=
get_irn_n
(
to
,
get_sparc_Call_dest_addr_pos
(
to
));
if
(
skip_Proj
(
check
)
==
node
)
return
false
;
/* the Call also destroys the value of %o7, but since this is
* currently marked as ignore register in the backend, it
* should never be used by the instruction in the delay slot. */
if
(
uses_reg
(
node
,
&
sparc_registers
[
REG_O7
]))
return
false
;
return
true
;
}
else
if
(
is_sparc_Return
(
to
))
{
/* return uses the value of %o7, all other values are not
* immediately used */
if
(
writes_reg
(
node
,
&
sparc_registers
[
REG_O7
]))
return
false
;
return
true
;
}
else
{
/* the node must not use our computed values */
int
arity
=
get_irn_arity
(
to
);
int
i
;
for
(
i
=
0
;
i
<
arity
;
++
i
)
{
ir_node
*
in
=
get_irn_n
(
to
,
i
);
if
(
skip_Proj
(
in
)
==
node
)
return
false
;
}
return
true
;
}
}
...
...
Write
Preview
Supports
Markdown
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