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
7ac90687
Commit
7ac90687
authored
Mar 22, 2006
by
Sebastian Hack
Browse files
Added phi handler
parent
90572f67
Changes
3
Hide whitespace changes
Inline
Side-by-side
ir/be/bemain.c
View file @
7ac90687
...
...
@@ -26,6 +26,7 @@
#include
"iredges_t.h"
#include
"irloop_t.h"
#include
"irtools.h"
#include
"return.h"
#include
"bearch.h"
#include
"firm/bearch_firm.h"
...
...
@@ -60,7 +61,7 @@
#define DUMP_FINAL (1 << 5)
/* options visible for anyone */
be_options_t
be_options
=
{
static
be_options_t
be_options
=
{
/* ilp server */
"i44pc52.info.uni-karlsruhe.de"
,
...
...
@@ -175,9 +176,10 @@ static be_main_env_t *be_init_env(be_main_env_t *env)
{
memset
(
env
,
0
,
sizeof
(
*
env
));
obstack_init
(
&
env
->
obst
);
env
->
dbg
=
firm_dbg_register
(
"be.main"
);
env
->
dbg
=
firm_dbg_register
(
"be.main"
);
env
->
arch_env
=
obstack_alloc
(
&
env
->
obst
,
sizeof
(
env
->
arch_env
[
0
]));
env
->
options
=
&
be_options
;
arch_env_init
(
env
->
arch_env
,
isa_if
);
/* Register the irn handler of the architecture */
...
...
@@ -190,6 +192,8 @@ static be_main_env_t *be_init_env(be_main_env_t *env)
* spill, reload and perm nodes.
*/
arch_env_push_irn_handler
(
env
->
arch_env
,
&
be_node_irn_handler
);
env
->
phi_handler
=
be_phi_handler_new
(
env
->
arch_env
);
arch_env_push_irn_handler
(
env
->
arch_env
,
env
->
phi_handler
);
return
env
;
}
...
...
@@ -197,6 +201,7 @@ static be_main_env_t *be_init_env(be_main_env_t *env)
static
void
be_done_env
(
be_main_env_t
*
env
)
{
env
->
arch_env
->
isa
->
impl
->
done
(
env
->
arch_env
->
isa
);
be_phi_handler_free
(
env
->
phi_handler
);
obstack_free
(
&
env
->
obst
,
NULL
);
}
...
...
@@ -218,7 +223,7 @@ static void prepare_graph(be_irg_t *birg)
normalize_proj_nodes
(
irg
);
/* Make just one return node. */
//
normalize_one_return(irg);
normalize_one_return
(
irg
);
/* Remove critical edges */
remove_critical_cf_edges
(
irg
);
...
...
@@ -232,6 +237,9 @@ static void prepare_graph(be_irg_t *birg)
/* check, if the dominance property is fulfilled. */
be_check_dominance
(
irg
);
/* reset the phi handler. */
be_phi_handler_reset
(
birg
->
main_env
->
phi_handler
);
}
/**
...
...
@@ -298,8 +306,7 @@ static void be_main_loop(FILE *file_handle)
dump
(
DUMP_PREPARED
,
irg
,
"-prepared"
,
dump_ir_block_graph
);
/* add Keeps for should_be_different constrained nodes */
assure_constraints
(
&
birg
);
// assure_constraints(&birg);
dump
(
DUMP_PREPARED
,
irg
,
"-assured"
,
dump_ir_block_graph
);
/* Schedule the graphs. */
...
...
ir/be/benode.c
View file @
7ac90687
...
...
@@ -23,6 +23,7 @@
#include
"util.h"
#include
"debug.h"
#include
"fourcc.h"
#include
"offset.h"
#include
"bitfiddle.h"
#include
"irop_t.h"
...
...
@@ -860,12 +861,29 @@ ir_node *be_reload(const arch_env_t *arch_env, const arch_register_class_t *cls,
return
reload
;
}
/*
____ ____
| _ \ ___ __ _ | _ \ ___ __ _ ___
| |_) / _ \/ _` | | |_) / _ \/ _` / __|
| _ < __/ (_| | | _ < __/ (_| \__ \
|_| \_\___|\__, | |_| \_\___|\__, |___/
|___/ |_|
*/
static
void
*
put_out_reg_req
(
arch_register_req_t
*
req
,
const
ir_node
*
irn
,
int
out_pos
)
{
const
be_node_attr_t
*
a
=
get_irn_attr
(
irn
);
if
(
out_pos
<
a
->
max_reg_data
)
if
(
out_pos
<
a
->
max_reg_data
)
{
memcpy
(
req
,
&
a
->
reg_data
[
out_pos
].
req
,
sizeof
(
req
[
0
]));
if
(
be_is_Copy
(
irn
))
{
req
->
type
|=
arch_register_req_type_should_be_same
;
req
->
other_same
=
get_irn_n
(
irn
,
be_pos_Copy_orig
);
}
}
else
{
req
->
type
=
arch_register_req_type_none
;
req
->
cls
=
NULL
;
...
...
@@ -970,6 +988,14 @@ static void be_node_set_frame_offset(const void *self, ir_node *irn, int offset)
}
}
/*
___ ____ _ _ _ _ _ _
|_ _| _ \| \ | | | | | | __ _ _ __ __| | | ___ _ __
| || |_) | \| | | |_| |/ _` | '_ \ / _` | |/ _ \ '__|
| || _ <| |\ | | _ | (_| | | | | (_| | | __/ |
|___|_| \_\_| \_| |_| |_|\__,_|_| |_|\__,_|_|\___|_|
*/
static
const
arch_irn_ops_if_t
be_node_irn_ops_if
=
{
be_node_get_irn_reg_req
,
...
...
@@ -985,16 +1011,178 @@ static const arch_irn_ops_t be_node_irn_ops = {
&
be_node_irn_ops_if
};
const
void
*
be_node_get_
arch
_ops
(
const
arch_irn_handler_t
*
self
,
const
ir_node
*
irn
)
const
void
*
be_node_get_
irn
_ops
(
const
arch_irn_handler_t
*
self
,
const
ir_node
*
irn
)
{
redir_proj
((
const
ir_node
**
)
&
irn
,
-
1
);
return
is_be_node
(
irn
)
?
&
be_node_irn_ops
:
NULL
;
}
const
arch_irn_handler_t
be_node_irn_handler
=
{
be_node_get_arch_ops
be_node_get_irn_ops
};
/*
____ _ _ ___ ____ _ _ _ _ _ _
| _ \| |__ (_) |_ _| _ \| \ | | | | | | __ _ _ __ __| | | ___ _ __
| |_) | '_ \| | | || |_) | \| | | |_| |/ _` | '_ \ / _` | |/ _ \ '__|
| __/| | | | | | || _ <| |\ | | _ | (_| | | | | (_| | | __/ |
|_| |_| |_|_| |___|_| \_\_| \_| |_| |_|\__,_|_| |_|\__,_|_|\___|_|
*/
typedef
struct
{
arch_irn_handler_t
irn_handler
;
arch_irn_ops_t
irn_ops
;
const
arch_env_t
*
arch_env
;
pmap
*
regs
;
}
phi_handler_t
;
#define get_phi_handler_from_handler(h) container_of(h, phi_handler_t, irn_handler)
#define get_phi_handler_from_ops(h) container_of(h, phi_handler_t, irn_ops)
static
const
void
*
phi_get_irn_ops
(
const
arch_irn_handler_t
*
handler
,
const
ir_node
*
irn
)
{
const
phi_handler_t
*
h
=
get_phi_handler_from_handler
(
handler
);
return
is_Phi
(
irn
)
&&
mode_is_datab
(
get_irn_mode
(
irn
))
?
&
h
->
irn_ops
:
NULL
;
}
/**
* Get register class of a Phi.
*
*/
static
const
arch_register_req_t
*
get_Phi_reg_req_recursive
(
const
phi_handler_t
*
h
,
arch_register_req_t
*
req
,
const
ir_node
*
phi
,
pset
**
visited
)
{
int
n
=
get_irn_arity
(
phi
);
ir_node
*
op
;
int
done
=
0
;
int
i
;
if
(
*
visited
&&
pset_find_ptr
(
*
visited
,
phi
))
return
NULL
;
for
(
i
=
0
;
i
<
n
;
++
i
)
{
op
=
get_irn_n
(
phi
,
i
);
if
(
!
is_Phi
(
op
))
return
arch_get_register_req
(
h
->
arch_env
,
req
,
op
,
BE_OUT_POS
(
0
));
}
/*
The operands of that Phi were all Phis themselves.
We have to start a DFS for a non-Phi argument now.
*/
if
(
!*
visited
)
*
visited
=
pset_new_ptr
(
16
);
pset_insert_ptr
(
*
visited
,
phi
);
for
(
i
=
0
;
i
<
n
;
++
i
)
{
op
=
get_irn_n
(
phi
,
i
);
if
(
get_Phi_reg_req_recursive
(
h
,
req
,
op
,
visited
))
return
req
;
}
return
NULL
;
}
static
const
arch_register_req_t
*
phi_get_irn_reg_req
(
const
void
*
self
,
arch_register_req_t
*
req
,
const
ir_node
*
irn
,
int
pos
)
{
phi_handler_t
*
phi_handler
=
get_phi_handler_from_ops
(
self
);
pset
*
visited
=
NULL
;
get_Phi_reg_req_recursive
(
phi_handler
,
req
,
irn
,
&
visited
);
/* Set the requirements type to normal, since an operand of the Phi could have had constraints. */
req
->
type
=
arch_register_req_type_normal
;
if
(
visited
)
del_pset
(
visited
);
return
req
;
}
static
void
phi_set_irn_reg
(
const
void
*
self
,
ir_node
*
irn
,
const
arch_register_t
*
reg
)
{
phi_handler_t
*
h
=
get_phi_handler_from_ops
(
self
);
pmap_insert
(
h
->
regs
,
irn
,
(
void
*
)
reg
);
}
static
const
arch_register_t
*
phi_get_irn_reg
(
const
void
*
self
,
const
ir_node
*
irn
)
{
phi_handler_t
*
h
=
get_phi_handler_from_ops
(
self
);
return
pmap_get
(
h
->
regs
,
(
void
*
)
irn
);
}
static
arch_irn_class_t
phi_classify
(
const
void
*
_self
,
const
ir_node
*
irn
)
{
return
arch_irn_class_normal
;
}
static
arch_irn_flags_t
phi_get_flags
(
const
void
*
_self
,
const
ir_node
*
irn
)
{
return
arch_irn_flags_none
;
}
static
entity
*
phi_get_frame_entity
(
const
void
*
_self
,
const
ir_node
*
irn
)
{
return
NULL
;
}
static
void
phi_set_frame_offset
(
const
void
*
_self
,
ir_node
*
irn
,
int
bias
)
{
}
static
const
arch_irn_ops_if_t
phi_irn_ops
=
{
phi_get_irn_reg_req
,
phi_set_irn_reg
,
phi_get_irn_reg
,
phi_classify
,
phi_get_flags
,
phi_get_frame_entity
,
phi_set_frame_offset
};
static
const
arch_irn_handler_t
phi_irn_handler
=
{
phi_get_irn_ops
};
arch_irn_handler_t
*
be_phi_handler_new
(
const
arch_env_t
*
arch_env
)
{
phi_handler_t
*
h
=
xmalloc
(
sizeof
(
h
[
0
]));
h
->
irn_handler
.
get_irn_ops
=
phi_get_irn_ops
;
h
->
irn_ops
.
impl
=
&
phi_irn_ops
;
h
->
arch_env
=
arch_env
;
h
->
regs
=
pmap_create
();
return
(
arch_irn_handler_t
*
)
h
;
}
void
be_phi_handler_free
(
arch_irn_handler_t
*
handler
)
{
phi_handler_t
*
h
=
(
void
*
)
handler
;
pmap_destroy
(
h
->
regs
);
free
(
handler
);
}
const
void
*
be_phi_get_irn_ops
(
const
arch_irn_handler_t
*
self
,
const
ir_node
*
irn
)
{
phi_handler_t
*
phi_handler
=
get_phi_handler_from_handler
(
self
);
return
is_Phi
(
irn
)
?
&
phi_handler
->
irn_ops
:
NULL
;
}
void
be_phi_handler_reset
(
arch_irn_handler_t
*
handler
)
{
phi_handler_t
*
h
=
get_phi_handler_from_handler
(
handler
);
if
(
h
->
regs
)
pmap_destroy
(
h
->
regs
);
h
->
regs
=
pmap_create
();
}
/*
_ _ _ ____ _
| \ | | ___ __| | ___ | _ \ _ _ _ __ ___ _ __ (_)_ __ __ _
| \| |/ _ \ / _` |/ _ \ | | | | | | | '_ ` _ \| '_ \| | '_ \ / _` |
| |\ | (_) | (_| | __/ | |_| | |_| | | | | | | |_) | | | | | (_| |
|_| \_|\___/ \__,_|\___| |____/ \__,_|_| |_| |_| .__/|_|_| |_|\__, |
|_| |___/
*/
static
void
dump_node_req
(
FILE
*
f
,
int
idx
,
be_req_t
*
req
)
{
...
...
ir/be/benode_t.h
View file @
7ac90687
...
...
@@ -87,8 +87,6 @@ typedef enum {
void
be_node_init
(
void
);
const
arch_irn_handler_t
be_node_irn_handler
;
enum
{
be_pos_Spill_frame
=
0
,
be_pos_Spill_val
=
1
...
...
@@ -262,15 +260,27 @@ void be_node_set_flags(ir_node *irn, int pos, arch_irn_flags_t flags);
void
be_node_set_reg_class
(
ir_node
*
irn
,
int
pos
,
const
arch_register_class_t
*
cls
);
/**
* Insert a Perm node after a specific node in the schedule.
* The Perm permutes over all values live at the given node.
* This means that all liveness intervals are cut apart at this
* location in the program.
* Make a new phi handler.
* @param env The architecture environment.
* @return A new phi handler.
*/
ir_node
*
insert_Perm_after
(
const
arch_env_t
*
env
,
const
arch_register_class_t
*
cls
,
dom_front_info_t
*
dom_front
,
ir_node
*
pos
);
arch_irn_handler_t
*
be_phi_handler_new
(
const
arch_env_t
*
arch_env
);
/**
* Free a phi handler.
* @param handler The handler to free.
*/
void
be_phi_handler_free
(
arch_irn_handler_t
*
handler
);
/**
* Reset the register data in the phi handler.
* This should be called on each new graph and deletes the register information of the current graph.
*/
void
be_phi_handler_reset
(
arch_irn_handler_t
*
handler
);
/**
* irn handler for common be nodes.
*/
extern
const
arch_irn_handler_t
be_node_irn_handler
;
#endif
/* _BENODE_T_H */
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