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
1c8a3d61
Commit
1c8a3d61
authored
Sep 09, 2014
by
Matthias Braun
Browse files
bearch: cleanup, improve struct packing
parent
66fa68a3
Changes
3
Hide whitespace changes
Inline
Side-by-side
ir/be/bearch.h
View file @
1c8a3d61
...
...
@@ -37,16 +37,16 @@ typedef enum arch_register_class_flags_t {
ENUM_BITSET
(
arch_register_class_flags_t
)
typedef
enum
arch_register_type_t
{
arch_register_type_none
=
0
,
arch_register_type_none
=
0
,
/** Do not consider this register when allocating. */
arch_register_type_ignore
=
1U
<<
0
,
arch_register_type_ignore
=
1U
<<
0
,
/** This is just a virtual register. Virtual registers fulfill any register
* constraints as long as the register class matches. It is a allowed to
* have multiple definitions for the same virtual register at a point */
arch_register_type_virtual
=
1U
<<
1
,
arch_register_type_virtual
=
1U
<<
1
,
/** The register represents a state that should be handled by bestate
* code */
arch_register_type_state
=
1U
<<
2
,
arch_register_type_state
=
1U
<<
2
,
}
arch_register_type_t
;
ENUM_BITSET
(
arch_register_type_t
)
...
...
@@ -84,12 +84,14 @@ void arch_dump_reqs_and_registers(FILE *F, const ir_node *node);
void
arch_set_frame_offset
(
ir_node
*
irn
,
int
bias
);
ir_entity
*
arch_get_frame_entity
(
const
ir_node
*
irn
);
int
arch_get_sp_bias
(
ir_node
*
irn
);
int
arch_get_op_estimated_cost
(
const
ir_node
*
irn
);
int
arch_possible_memory_operand
(
const
ir_node
*
irn
,
unsigned
int
i
);
void
arch_perform_memory_operand
(
ir_node
*
irn
,
unsigned
int
i
);
int
arch_get_sp_bias
(
ir_node
*
irn
);
int
arch_get_op_estimated_cost
(
const
ir_node
*
irn
);
int
arch_possible_memory_operand
(
const
ir_node
*
irn
,
unsigned
i
);
void
arch_perform_memory_operand
(
ir_node
*
irn
,
unsigned
i
);
/**
* Get the register allocated for a value.
...
...
@@ -153,15 +155,14 @@ static inline const arch_register_req_t **arch_get_irn_register_reqs_in(
static
inline
reg_out_info_t
*
get_out_info
(
const
ir_node
*
node
)
{
size_t
pos
=
0
;
const
backend_info_t
*
info
;
assert
(
get_irn_mode
(
node
)
!=
mode_T
);
size_t
pos
=
0
;
if
(
is_Proj
(
node
))
{
pos
=
get_Proj_proj
(
node
);
node
=
get_Proj_pred
(
node
);
}
info
=
be_get_info
(
node
);
const
backend_info_t
*
info
=
be_get_info
(
node
);
assert
(
pos
<
ARR_LEN
(
info
->
out_infos
));
return
&
info
->
out_infos
[
pos
];
}
...
...
@@ -184,6 +185,7 @@ static inline arch_irn_flags_t arch_get_irn_flags(const ir_node *node)
}
void
arch_set_irn_flags
(
ir_node
*
node
,
arch_irn_flags_t
flags
);
void
arch_add_irn_flags
(
ir_node
*
node
,
arch_irn_flags_t
flags
);
/**
...
...
@@ -218,13 +220,13 @@ void be_register_isa_if(const char *name, const arch_isa_if_t *isa);
struct
arch_register_t
{
const
char
*
name
;
/**< The name of the register. */
const
arch_register_class_t
*
reg_class
;
/**< The class of the register */
/** register constraint allowing just this register */
const
arch_register_req_t
*
single_req
;
arch_register_type_t
type
;
/**< The type of the register. */
unsigned
short
index
;
/**< The index of the register in
the class. */
unsigned
short
global_index
;
/**< The global index this
register in the architecture. */
arch_register_type_t
type
;
/**< The type of the register. */
/** register constraint allowing just this register */
const
arch_register_req_t
*
single_req
;
/** register number in dwarf debugging format */
unsigned
short
dwarf_number
;
/** register number in instruction encoding */
...
...
@@ -236,14 +238,14 @@ struct arch_register_t {
* Like general purpose or floating point.
*/
struct
arch_register_class_t
{
unsigned
index
;
/**< index of this register class */
const
char
*
name
;
/**< The name of the register class.*/
unsigned
n_regs
;
/**< Number of registers in this
class. */
ir_mode
*
mode
;
/**< The mode of the register class.*/
const
arch_register_t
*
regs
;
/**< The array of registers. */
arch_register_class_flags_t
flags
;
/**< register class flags. */
const
char
*
name
;
/**< The name of the register class.*/
ir_mode
*
mode
;
/**< The mode of the register class.*/
const
arch_register_t
*
regs
;
/**< The array of registers. */
const
arch_register_req_t
*
class_req
;
unsigned
index
;
/**< index of this register class */
unsigned
n_regs
;
/**< Number of registers in this
class. */
arch_register_class_flags_t
flags
;
/**< register class flags. */
};
/** return the number of registers in this register class */
...
...
@@ -282,19 +284,18 @@ static inline const arch_register_t *arch_register_for_index(
* Expresses requirements to register allocation for an operand.
*/
struct
arch_register_req_t
{
/** The register class this constraint belongs to. */
const
arch_register_class_t
*
cls
;
/** allowed register bitset (in case of wide-values this is only about the
* first register) */
const
unsigned
*
limited
;
arch_register_req_type_t
type
;
/**< The type of the constraint. */
const
arch_register_class_t
*
cls
;
/**< The register class this constraint
belongs to. */
const
unsigned
*
limited
;
/**< allowed register bitset
(in case of wide-values this is
only about the first register) */
unsigned
other_same
;
/**< Bitmask of ins which should use the
same register (should_be_same). */
unsigned
other_different
;
/**< Bitmask of ins which shall use a
different register
(must_be_different) */
unsigned
char
width
;
/**< specifies how many sequential
registers are required */
/** Bitmask of ins which should use the same register (should_be_same). */
unsigned
other_same
;
/** Bitmask of ins which shall use a different register (must_be_different) */
unsigned
other_different
;
/** Specifies how many sequential registers are required */
unsigned
char
width
;
};
static
inline
bool
reg_reqs_equal
(
const
arch_register_req_t
*
req1
,
...
...
@@ -320,7 +321,6 @@ static inline bool reg_reqs_equal(const arch_register_req_t *req1,
}
struct
arch_irn_ops_t
{
/**
* Get the entity on the stack frame this node depends on.
* @param irn The node in question.
...
...
@@ -366,7 +366,7 @@ struct arch_irn_ops_t {
* can load it form memory internally
* @return nonzero if argument can be loaded or zero otherwise
*/
int
(
*
possible_memory_operand
)(
const
ir_node
*
irn
,
unsigned
int
i
);
int
(
*
possible_memory_operand
)(
const
ir_node
*
irn
,
unsigned
i
);
/**
* Ask the backend to assimilate @p reload of operand @p i into @p irn.
...
...
@@ -374,7 +374,7 @@ struct arch_irn_ops_t {
* @param irn The node.
* @param i The position of the reload.
*/
void
(
*
perform_memory_operand
)(
ir_node
*
irn
,
unsigned
int
i
);
void
(
*
perform_memory_operand
)(
ir_node
*
irn
,
unsigned
i
);
};
/**
...
...
@@ -433,9 +433,8 @@ struct arch_isa_if_t {
void
(
*
mark_remat
)(
ir_node
*
node
);
/**
* Create a spill instruction. We assume that spill instructions
* do not need any additional registers and do not affect cpu-flags in any
* way.
* Create a spill instruction. We assume that spill instructions do not need
* any additional registers and do not affect cpu-flags in any way.
* Construct a sequence of instructions after @p after (the resulting nodes
* are already scheduled).
* Returns a mode_M value which is used as input for a reload instruction.
...
...
@@ -497,15 +496,17 @@ struct arch_isa_if_t {
*/
struct
arch_env_t
{
const
arch_isa_if_t
*
impl
;
unsigned
n_registers
;
/**< number of registers */
const
arch_register_t
*
registers
;
/**< register array */
unsigned
n_register_classes
;
/**< number of register classes*/
const
arch_register_class_t
*
register_classes
;
/**< register classes */
const
arch_register_t
*
sp
;
/**< The stack pointer register. */
const
arch_register_t
*
bp
;
/**< The base pointer register. */
int
stack_alignment
;
/**< power of 2 stack alignment */
int
spill_cost
;
/**< cost for a be_Spill node */
int
reload_cost
;
/**< cost for a be_Reload node */
unsigned
n_registers
;
/**< number of registers */
const
arch_register_t
*
registers
;
/**< register array */
/** number of register classes*/
unsigned
n_register_classes
;
/** register classes */
const
arch_register_class_t
*
register_classes
;
const
arch_register_t
*
sp
;
/**< The stack pointer register. */
const
arch_register_t
*
bp
;
/**< The base pointer register. */
unsigned
stack_alignment
;
/**< power of 2 stack alignment */
unsigned
spill_cost
;
/**< cost for a be_Spill node */
unsigned
reload_cost
;
/**< cost for a be_Reload node */
};
static
inline
bool
arch_irn_is_ignore
(
const
ir_node
*
irn
)
...
...
@@ -536,12 +537,6 @@ static inline bool arch_irn_consider_in_reg_alloc(
} \
} while (0)
/**
* Iterate over all values defined by an instruction.
* Only looks at values in a certain register class where the requirements
* are not marked as ignore.
* Executes @p code for each definition.
*/
#define be_foreach_definition_(node, ccls, value, req, code) \
be_foreach_value(node, value, \
arch_register_req_t const *const req = arch_get_irn_register_req(value); \
...
...
@@ -550,6 +545,12 @@ static inline bool arch_irn_consider_in_reg_alloc(
code \
)
/**
* Iterate over all values defined by an instruction.
* Only looks at values in a certain register class where the requirements
* are not marked as ignore.
* Executes @p code for each definition.
*/
#define be_foreach_definition(node, ccls, value, req, code) \
be_foreach_definition_(node, ccls, value, req, \
if (arch_register_req_is(req, ignore)) \
...
...
ir/be/bespilldaemel.c
View file @
1c8a3d61
...
...
@@ -56,7 +56,6 @@ static int compare_spill_candidates_desc(const void *d1, const void *d2)
{
const
spill_candidate_t
*
c1
=
(
const
spill_candidate_t
*
)
d1
;
const
spill_candidate_t
*
c2
=
(
const
spill_candidate_t
*
)
d2
;
return
(
int
)
(
c1
->
costs
-
c2
->
costs
);
}
...
...
@@ -66,12 +65,10 @@ static double get_spill_costs(ir_node *node)
double
costs
=
be_get_spill_costs
(
spill_env
,
node
,
spill_place
);
foreach_out_edge
(
node
,
edge
)
{
ir_node
*
use
=
get_edge_src_irn
(
edge
);
/* keeps should be directly below the node */
if
(
be_is_Keep
(
use
))
{
ir_node
*
use
=
get_edge_src_irn
(
edge
);
if
(
be_is_Keep
(
use
))
continue
;
}
if
(
is_Phi
(
use
))
{
int
in
=
get_edge_src_pos
(
edge
);
...
...
@@ -160,13 +157,11 @@ static void do_spilling(ir_nodeset_t *live_nodes, ir_node *node)
/* construct array with spill candidates and calculate their costs */
size_t
c
=
0
;
foreach_ir_nodeset
(
live_nodes
,
n
,
iter
)
{
spill_candidate_t
*
candidate
=
&
candidates
[
c
];
assert
(
!
bitset_is_set
(
spilled_nodes
,
get_irn_idx
(
n
)));
spill_candidate_t
*
candidate
=
&
candidates
[
c
++
];
candidate
->
node
=
n
;
candidate
->
costs
=
get_spill_costs
(
n
);
++
c
;
}
assert
(
c
==
n_live_nodes
);
...
...
@@ -176,9 +171,8 @@ static void do_spilling(ir_nodeset_t *live_nodes, ir_node *node)
/* spill cheapest ones */
size_t
cand_idx
=
0
;
while
(
spills_needed
>
0
)
{
if
(
cand_idx
>=
n_live_nodes
)
{
if
(
cand_idx
>=
n_live_nodes
)
panic
(
"can't spill enough values for node %+F"
,
node
);
}
spill_candidate_t
*
candidate
=
&
candidates
[
cand_idx
];
ir_node
*
cand_node
=
candidate
->
node
;
...
...
@@ -220,10 +214,9 @@ static void remove_defs(ir_node *node, ir_nodeset_t *nodeset)
static
void
add_uses
(
ir_node
*
node
,
ir_nodeset_t
*
nodeset
)
{
foreach_irn_in
(
node
,
i
,
op
)
{
if
(
arch_irn_consider_in_reg_alloc
(
cls
,
op
)
&&
!
bitset_is_set
(
spilled_nodes
,
get_irn_idx
(
op
)))
{
if
(
arch_irn_consider_in_reg_alloc
(
cls
,
op
)
&&
!
bitset_is_set
(
spilled_nodes
,
get_irn_idx
(
op
)))
ir_nodeset_insert
(
nodeset
,
op
);
}
}
}
...
...
@@ -242,7 +235,7 @@ void print_nodeset(ir_nodeset_t *nodeset)
*/
static
void
spill_block
(
ir_node
*
block
,
void
*
data
)
{
(
void
)
data
;
(
void
)
data
;
DBG
((
dbg
,
LEVEL_1
,
"spilling block %+F
\n
"
,
block
));
/* construct set of live nodes at end of block */
...
...
@@ -280,9 +273,8 @@ static void spill_block(ir_node *block, void *data)
if
(
!
is_Phi
(
node
))
break
;
if
(
bitset_is_set
(
spilled_nodes
,
get_irn_idx
(
node
)))
{
if
(
bitset_is_set
(
spilled_nodes
,
get_irn_idx
(
node
)))
n_phi_values_spilled
+=
get_value_width
(
node
);
}
}
int
live_nodes_pressure
=
0
;
...
...
ir/be/ia32/bearch_ia32.c
View file @
1c8a3d61
...
...
@@ -2081,7 +2081,7 @@ static const lc_opt_table_entry_t ia32_options[] = {
LC_OPT_ENT_ENUM_INT
(
"transformer"
,
"the transformer used for code selection"
,
&
transformer_var
),
#endif
LC_OPT_ENT_INT
(
"stackalign"
,
"set power of two stack alignment for calls"
,
&
ia32_isa_template
.
base
.
stack_alignment
),
(
int
*
)
&
ia32_isa_template
.
base
.
stack_alignment
),
LC_OPT_ENT_BOOL
(
"gprof"
,
"create gprof profiling code"
,
&
gprof
),
LC_OPT_ENT_BOOL
(
"precise_float_spill"
,
"Spill floatingpoint values precisely (the whole 80 bits)"
,
&
precise_x87_spills
),
LC_OPT_LAST
...
...
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