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
5ae1785f
Commit
5ae1785f
authored
Feb 22, 2008
by
Michael Beck
Browse files
Add an DivRL for remainderless div nodes (we don't have to generate correction
code than ... [r17833]
parent
5cfae452
Changes
9
Hide whitespace changes
Inline
Side-by-side
include/libfirm/ircons.h
View file @
5ae1785f
...
...
@@ -1515,6 +1515,20 @@ ir_node *new_rd_DivMod (dbg_info *db, ir_graph *irg, ir_node *block,
ir_node
*
new_rd_Div
(
dbg_info
*
db
,
ir_graph
*
irg
,
ir_node
*
block
,
ir_node
*
memop
,
ir_node
*
op1
,
ir_node
*
op2
,
ir_mode
*
mode
,
op_pin_state
state
);
/** Constructor for a remainderless Div node.
*
* @param *db A pointer for debug information.
* @param *irg The IR graph the node belongs to.
* @param *block The IR block the node belongs to.
* @param *memop The store needed to model exceptions
* @param *op1 The first operand.
* @param *op2 The second operand.
* @param *mode The mode of the result.
* @param state The pinned state.
*/
ir_node
*
new_rd_DivRL
(
dbg_info
*
db
,
ir_graph
*
irg
,
ir_node
*
block
,
ir_node
*
memop
,
ir_node
*
op1
,
ir_node
*
op2
,
ir_mode
*
mode
,
op_pin_state
state
);
/** Constructor for a Mod node.
*
* @param *db A pointer for debug information.
...
...
@@ -2349,6 +2363,19 @@ ir_node *new_r_DivMod (ir_graph *irg, ir_node *block,
ir_node
*
new_r_Div
(
ir_graph
*
irg
,
ir_node
*
block
,
ir_node
*
memop
,
ir_node
*
op1
,
ir_node
*
op2
,
ir_mode
*
mode
,
op_pin_state
state
);
/** Constructor for a remainderless Div node.
*
* @param *irg The IR graph the node belongs to.
* @param *block The IR block the node belongs to.
* @param *memop The store needed to model exceptions
* @param *op1 The first operand.
* @param *op2 The second operand.
* @param *mode The mode of the result.
* @param state The pinned state.
*/
ir_node
*
new_r_DivRL
(
ir_graph
*
irg
,
ir_node
*
block
,
ir_node
*
memop
,
ir_node
*
op1
,
ir_node
*
op2
,
ir_mode
*
mode
,
op_pin_state
state
);
/** Constructor for a Mod node.
*
* @param *irg The IR graph the node belongs to.
...
...
@@ -3167,6 +3194,19 @@ ir_node *new_d_DivMod (dbg_info *db, ir_node *memop, ir_node *op1, ir_node *op2,
*/
ir_node
*
new_d_Div
(
dbg_info
*
db
,
ir_node
*
memop
,
ir_node
*
op1
,
ir_node
*
op2
,
ir_mode
*
mode
,
op_pin_state
state
);
/** Constructor for a remainderless Div node.
*
* Adds the node to the block in current_ir_block.
*
* @param *db A pointer for debug information.
* @param *memop The store needed to model exceptions
* @param *op1 The first operand.
* @param *op2 The second operand.
* @param *mode The mode of the result.
* @param state The pinned state.
*/
ir_node
*
new_d_DivRL
(
dbg_info
*
db
,
ir_node
*
memop
,
ir_node
*
op1
,
ir_node
*
op2
,
ir_mode
*
mode
,
op_pin_state
state
);
/** Constructor for a Mod node.
*
* Adds the node to the block in current_ir_block.
...
...
@@ -3989,6 +4029,18 @@ ir_node *new_DivMod (ir_node *memop, ir_node *op1, ir_node *op2, ir_mode *mode,
*/
ir_node
*
new_Div
(
ir_node
*
memop
,
ir_node
*
op1
,
ir_node
*
op2
,
ir_mode
*
mode
,
op_pin_state
state
);
/** Constructor for a remainderless Div node.
*
* Adds the node to the block in current_ir_block.
*
* @param *memop The store needed to model exceptions
* @param *op1 The first operand.
* @param *op2 The second operand.
* @param *mode The mode of the result.
* @param state The pinned state.
*/
ir_node
*
new_DivRL
(
ir_node
*
memop
,
ir_node
*
op1
,
ir_node
*
op2
,
ir_mode
*
mode
,
op_pin_state
state
);
/** Constructor for a Mod node.
*
* Adds the node to the block in current_ir_block.
...
...
include/libfirm/irnode.h
View file @
5ae1785f
...
...
@@ -763,6 +763,7 @@ ir_node *get_Div_mem(const ir_node *node);
void
set_Div_mem
(
ir_node
*
node
,
ir_node
*
mem
);
ir_mode
*
get_Div_resmode
(
const
ir_node
*
node
);
void
set_Div_resmode
(
ir_node
*
node
,
ir_mode
*
mode
);
int
is_Div_remainderless
(
const
ir_node
*
node
);
/**
* Projection numbers for Div: use for Proj nodes!
...
...
ir/ir/irarch.c
View file @
5ae1785f
...
...
@@ -930,16 +930,20 @@ ir_node *arch_dep_replace_div_by_const(ir_node *irn) {
ir_node
*
k_node
;
ir_node
*
curr
=
left
;
if
(
k
!=
1
)
{
k_node
=
new_r_Const_long
(
current_ir_graph
,
block
,
mode_Iu
,
k
-
1
);
curr
=
new_rd_Shrs
(
dbg
,
current_ir_graph
,
block
,
left
,
k_node
,
mode
);
if
(
!
is_Div_remainderless
(
irn
))
{
if
(
k
!=
1
)
{
k_node
=
new_r_Const_long
(
current_ir_graph
,
block
,
mode_Iu
,
k
-
1
);
curr
=
new_rd_Shrs
(
dbg
,
current_ir_graph
,
block
,
left
,
k_node
,
mode
);
}
k_node
=
new_r_Const_long
(
current_ir_graph
,
block
,
mode_Iu
,
bits
-
k
);
curr
=
new_rd_Shr
(
dbg
,
current_ir_graph
,
block
,
curr
,
k_node
,
mode
);
curr
=
new_rd_Add
(
dbg
,
current_ir_graph
,
block
,
left
,
curr
,
mode
);
}
else
{
k_node
=
left
;
}
k_node
=
new_r_Const_long
(
current_ir_graph
,
block
,
mode_Iu
,
bits
-
k
);
curr
=
new_rd_Shr
(
dbg
,
current_ir_graph
,
block
,
curr
,
k_node
,
mode
);
curr
=
new_rd_Add
(
dbg
,
current_ir_graph
,
block
,
left
,
curr
,
mode
);
k_node
=
new_r_Const_long
(
current_ir_graph
,
block
,
mode_Iu
,
k
);
res
=
new_rd_Shrs
(
dbg
,
current_ir_graph
,
block
,
curr
,
k_node
,
mode
);
...
...
ir/ir/ircons.c
View file @
5ae1785f
...
...
@@ -115,6 +115,7 @@ new_bd_##instr(dbg_info *db, ir_node *block, \
res = new_ir_node(db, irg, block, op_##instr, mode_T, 3, in); \
res->attr.divmod.exc.pin_state = state; \
res->attr.divmod.res_mode = mode; \
res->attr.divmod.no_remainder = 0; \
res = optimize_node(res); \
IRN_VRFY_IRG(res, irg); \
return res; \
...
...
@@ -399,6 +400,25 @@ NEW_BD_UNOP(Abs)
NEW_BD_BINOP
(
Carry
)
NEW_BD_BINOP
(
Borrow
)
/** Creates a remainderless Div node. */
static
ir_node
*
new_bd_DivRL
(
dbg_info
*
db
,
ir_node
*
block
,
ir_node
*
memop
,
ir_node
*
op1
,
ir_node
*
op2
,
ir_mode
*
mode
,
op_pin_state
state
)
{
ir_node
*
in
[
3
];
ir_node
*
res
;
ir_graph
*
irg
=
current_ir_graph
;
in
[
0
]
=
memop
;
in
[
1
]
=
op1
;
in
[
2
]
=
op2
;
res
=
new_ir_node
(
db
,
irg
,
block
,
op_Div
,
mode_T
,
3
,
in
);
res
->
attr
.
divmod
.
exc
.
pin_state
=
state
;
res
->
attr
.
divmod
.
res_mode
=
mode
;
res
->
attr
.
divmod
.
no_remainder
=
1
;
res
=
optimize_node
(
res
);
IRN_VRFY_IRG
(
res
,
irg
);
return
res
;
}
static
ir_node
*
new_bd_Cmp
(
dbg_info
*
db
,
ir_node
*
block
,
ir_node
*
op1
,
ir_node
*
op2
)
{
ir_node
*
in
[
2
];
...
...
@@ -1035,6 +1055,18 @@ NEW_RD_UNOP(Abs)
NEW_RD_BINOP
(
Carry
)
NEW_RD_BINOP
(
Borrow
)
/* creates a rd constructor for an divRL */
ir_node
*
new_rd_DivRL
(
dbg_info
*
db
,
ir_graph
*
irg
,
ir_node
*
block
,
ir_node
*
memop
,
ir_node
*
op1
,
ir_node
*
op2
,
ir_mode
*
mode
,
op_pin_state
state
)
{
ir_node
*
res
;
ir_graph
*
rem
=
current_ir_graph
;
current_ir_graph
=
irg
;
res
=
new_bd_DivRL
(
db
,
block
,
memop
,
op1
,
op2
,
mode
,
state
);
current_ir_graph
=
rem
;
return
res
;
}
ir_node
*
new_rd_Cmp
(
dbg_info
*
db
,
ir_graph
*
irg
,
ir_node
*
block
,
ir_node
*
op1
,
ir_node
*
op2
)
{
...
...
@@ -1535,6 +1567,10 @@ ir_node *new_r_Div(ir_graph *irg, ir_node *block,
ir_node
*
memop
,
ir_node
*
op1
,
ir_node
*
op2
,
ir_mode
*
mode
,
op_pin_state
state
)
{
return
new_rd_Div
(
NULL
,
irg
,
block
,
memop
,
op1
,
op2
,
mode
,
state
);
}
ir_node
*
new_r_DivRL
(
ir_graph
*
irg
,
ir_node
*
block
,
ir_node
*
memop
,
ir_node
*
op1
,
ir_node
*
op2
,
ir_mode
*
mode
,
op_pin_state
state
)
{
return
new_rd_DivRL
(
NULL
,
irg
,
block
,
memop
,
op1
,
op2
,
mode
,
state
);
}
ir_node
*
new_r_Mod
(
ir_graph
*
irg
,
ir_node
*
block
,
ir_node
*
memop
,
ir_node
*
op1
,
ir_node
*
op2
,
ir_mode
*
mode
,
op_pin_state
state
)
{
return
new_rd_Mod
(
NULL
,
irg
,
block
,
memop
,
op1
,
op2
,
mode
,
state
);
...
...
@@ -2391,7 +2427,18 @@ new_d_Div(dbg_info *db, ir_node *memop, ir_node *op1, ir_node *op2, ir_mode *mod
#endif
return
res
;
}
}
/* new_d_Div */
ir_node
*
new_d_DivRL
(
dbg_info
*
db
,
ir_node
*
memop
,
ir_node
*
op1
,
ir_node
*
op2
,
ir_mode
*
mode
,
op_pin_state
state
)
{
ir_node
*
res
;
res
=
new_bd_DivRL
(
db
,
current_ir_graph
->
current_block
,
memop
,
op1
,
op2
,
mode
,
state
);
#if PRECISE_EXC_CONTEXT
allocate_frag_arr
(
res
,
op_Div
,
&
res
->
attr
.
except
.
frag_arr
);
/* Could be optimized away. */
#endif
return
res
;
}
/* new_d_DivRL */
ir_node
*
new_d_Mod
(
dbg_info
*
db
,
ir_node
*
memop
,
ir_node
*
op1
,
ir_node
*
op2
,
ir_mode
*
mode
,
op_pin_state
state
)
{
...
...
@@ -2931,6 +2978,9 @@ ir_node *new_DivMod(ir_node *memop, ir_node *op1, ir_node *op2, ir_mode *mode, o
ir_node
*
new_Div
(
ir_node
*
memop
,
ir_node
*
op1
,
ir_node
*
op2
,
ir_mode
*
mode
,
op_pin_state
state
)
{
return
new_d_Div
(
NULL
,
memop
,
op1
,
op2
,
mode
,
state
);
}
ir_node
*
new_DivRL
(
ir_node
*
memop
,
ir_node
*
op1
,
ir_node
*
op2
,
ir_mode
*
mode
,
op_pin_state
state
)
{
return
new_d_DivRL
(
NULL
,
memop
,
op1
,
op2
,
mode
,
state
);
}
ir_node
*
new_Mod
(
ir_node
*
memop
,
ir_node
*
op1
,
ir_node
*
op2
,
ir_mode
*
mode
,
op_pin_state
state
)
{
return
new_d_Mod
(
NULL
,
memop
,
op1
,
op2
,
mode
,
state
);
}
...
...
ir/ir/irdump.c
View file @
5ae1785f
...
...
@@ -827,7 +827,10 @@ int dump_node_opcode(FILE *F, ir_node *n)
fprintf
(
F
,
"%s"
,
get_irn_opname
(
n
));
break
;
case
iro_Div
:
fprintf
(
F
,
"%s[%s]"
,
get_irn_opname
(
n
),
get_mode_name_ex
(
get_Div_resmode
(
n
),
&
bad
));
fprintf
(
F
,
"%s"
,
get_irn_opname
(
n
));
if
(
is_Div_remainderless
(
n
))
fprintf
(
F
,
"RL"
);
fprintf
(
F
,
"[%s]"
,
get_mode_name_ex
(
get_Div_resmode
(
n
),
&
bad
));
break
;
case
iro_Mod
:
fprintf
(
F
,
"%s[%s]"
,
get_irn_opname
(
n
),
get_mode_name_ex
(
get_Mod_resmode
(
n
),
&
bad
));
...
...
ir/ir/irnode.c
View file @
5ae1785f
...
...
@@ -571,10 +571,16 @@ store_attr *get_irn_store_attr(ir_node *node) {
except_attr
*
get_irn_except_attr
(
ir_node
*
node
)
{
assert
(
node
->
op
==
op_Div
||
node
->
op
==
op_Quot
||
node
->
op
==
op_DivMod
||
node
->
op
==
op_Mod
||
node
->
op
==
op_Call
||
node
->
op
==
op_Alloc
);
node
->
op
==
op_DivMod
||
node
->
op
==
op_Mod
||
node
->
op
==
op_Call
||
node
->
op
==
op_Alloc
||
node
->
op
==
op_Bound
);
return
&
node
->
attr
.
except
;
}
divmod_attr
*
get_irn_divmod_attr
(
ir_node
*
node
)
{
assert
(
node
->
op
==
op_Div
||
node
->
op
==
op_Quot
||
node
->
op
==
op_DivMod
||
node
->
op
==
op_Mod
);
return
&
node
->
attr
.
divmod
;
}
void
*
(
get_irn_generic_attr
)(
ir_node
*
node
)
{
assert
(
is_ir_node
(
node
));
return
_get_irn_generic_attr
(
node
);
...
...
@@ -1456,6 +1462,11 @@ BINOP(Cmp)
UNOP
(
Conv
)
UNOP
(
Cast
)
int
is_Div_remainderless
(
const
ir_node
*
node
)
{
assert
(
node
->
op
==
op_Div
);
return
node
->
attr
.
divmod
.
no_remainder
;
}
int
get_Conv_strict
(
const
ir_node
*
node
)
{
assert
(
node
->
op
==
op_Conv
);
return
node
->
attr
.
conv
.
strict
;
...
...
ir/ir/irnode_t.h
View file @
5ae1785f
...
...
@@ -58,6 +58,7 @@ block_attr *get_irn_block_attr (ir_node *node);
load_attr
*
get_irn_load_attr
(
ir_node
*
node
);
store_attr
*
get_irn_store_attr
(
ir_node
*
node
);
except_attr
*
get_irn_except_attr
(
ir_node
*
node
);
divmod_attr
*
get_irn_divmod_attr
(
ir_node
*
node
);
/** @} */
/**
...
...
ir/ir/iropt.c
View file @
5ae1785f
...
...
@@ -4997,7 +4997,7 @@ static int node_cmp_attr_SymConst(ir_node *a, ir_node *b) {
/** Compares the attributes of two Call nodes. */
static
int
node_cmp_attr_Call
(
ir_node
*
a
,
ir_node
*
b
)
{
return
(
get_irn_call_attr
(
a
)
!=
get_irn_call_attr
(
b
)
)
;
return
get_irn_call_attr
(
a
)
!=
get_irn_call_attr
(
b
);
}
/* node_cmp_attr_Call */
/** Compares the attributes of two Sel nodes. */
...
...
@@ -5057,6 +5057,49 @@ static int node_cmp_attr_Store(ir_node *a, ir_node *b) {
get_Store_volatility
(
b
)
==
volatility_is_volatile
);
}
/* node_cmp_attr_Store */
/** Compares two exception attributes */
static
int
node_cmp_exception
(
ir_node
*
a
,
ir_node
*
b
)
{
const
except_attr
*
ea
=
get_irn_except_attr
(
a
);
const
except_attr
*
eb
=
get_irn_except_attr
(
b
);
return
ea
->
pin_state
!=
eb
->
pin_state
;
}
#define node_cmp_attr_Bound node_cmp_exception
/** Compares the attributes of two Div nodes. */
static
int
node_cmp_attr_Div
(
ir_node
*
a
,
ir_node
*
b
)
{
const
divmod_attr
*
ma
=
get_irn_divmod_attr
(
a
);
const
divmod_attr
*
mb
=
get_irn_divmod_attr
(
b
);
return
ma
->
exc
.
pin_state
!=
mb
->
exc
.
pin_state
||
ma
->
res_mode
!=
mb
->
res_mode
||
ma
->
no_remainder
!=
mb
->
no_remainder
;
}
/* node_cmp_attr_Div */
/** Compares the attributes of two DivMod nodes. */
static
int
node_cmp_attr_DivMod
(
ir_node
*
a
,
ir_node
*
b
)
{
const
divmod_attr
*
ma
=
get_irn_divmod_attr
(
a
);
const
divmod_attr
*
mb
=
get_irn_divmod_attr
(
b
);
return
ma
->
exc
.
pin_state
!=
mb
->
exc
.
pin_state
||
ma
->
res_mode
!=
mb
->
res_mode
;
}
/* node_cmp_attr_DivMod */
/** Compares the attributes of two Mod nodes. */
static
int
node_cmp_attr_Mod
(
ir_node
*
a
,
ir_node
*
b
)
{
const
divmod_attr
*
ma
=
get_irn_divmod_attr
(
a
);
const
divmod_attr
*
mb
=
get_irn_divmod_attr
(
b
);
return
ma
->
exc
.
pin_state
!=
mb
->
exc
.
pin_state
||
ma
->
res_mode
!=
mb
->
res_mode
;
}
/* node_cmp_attr_Mod */
/** Compares the attributes of two Quot nodes. */
static
int
node_cmp_attr_Quot
(
ir_node
*
a
,
ir_node
*
b
)
{
const
divmod_attr
*
ma
=
get_irn_divmod_attr
(
a
);
const
divmod_attr
*
mb
=
get_irn_divmod_attr
(
b
);
return
ma
->
exc
.
pin_state
!=
mb
->
exc
.
pin_state
||
ma
->
res_mode
!=
mb
->
res_mode
;
}
/* node_cmp_attr_Quot */
/** Compares the attributes of two Confirm nodes. */
static
int
node_cmp_attr_Confirm
(
ir_node
*
a
,
ir_node
*
b
)
{
return
(
get_Confirm_cmp
(
a
)
!=
get_Confirm_cmp
(
b
));
...
...
@@ -5140,6 +5183,12 @@ static ir_op_ops *firm_set_default_node_cmp_attr(ir_opcode code, ir_op_ops *ops)
CASE
(
Store
);
CASE
(
Confirm
);
CASE
(
ASM
);
CASE
(
Div
);
CASE
(
DivMod
);
CASE
(
Mod
);
CASE
(
Quot
);
CASE
(
Bound
);
/* FIXME CopyB */
default:
/* leave NULL */
;
}
...
...
ir/ir/irtypes.h
View file @
5ae1785f
...
...
@@ -280,6 +280,7 @@ typedef struct {
typedef
struct
{
except_attr
exc
;
/**< The exception attribute. MUST be the first one. */
ir_mode
*
res_mode
;
/**< Result mode for the division. */
char
no_remainder
;
/**< Set, if known that a division can be done without a remainder. */
}
divmod_attr
;
/** Inline Assembler support attribute. */
...
...
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