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
cdd903d8
Commit
cdd903d8
authored
Jun 03, 2006
by
Michael Beck
Browse files
added support for Thread local storage
[r7863]
parent
54c4f924
Changes
10
Hide whitespace changes
Inline
Side-by-side
ir/ir/irdump.c
View file @
cdd903d8
...
...
@@ -818,6 +818,7 @@ static const pns_lookup_t start_lut[] = {
X
(
X_initial_exec
),
X
(
P_frame_base
),
X
(
P_globals
),
X
(
P_tls
),
X
(
T_args
),
X
(
P_value_arg_base
)
#undef X
...
...
ir/ir/irgopt.c
View file @
cdd903d8
...
...
@@ -900,7 +900,7 @@ static int can_inline(ir_node *call, ir_graph *called_graph)
int
inline_method
(
ir_node
*
call
,
ir_graph
*
called_graph
)
{
ir_node
*
pre_call
;
ir_node
*
post_call
,
*
post_bl
;
ir_node
*
in
[
5
];
ir_node
*
in
[
pn_Start_max
];
ir_node
*
end
,
*
end_bl
;
ir_node
**
res_pred
;
ir_node
**
cf_pred
;
...
...
@@ -983,14 +983,15 @@ int inline_method(ir_node *call, ir_graph *called_graph) {
graph. Both will end up being a tuple. -- */
post_bl
=
get_nodes_block
(
call
);
set_irg_current_block
(
current_ir_graph
,
post_bl
);
/* XxMxPxP of Start + parameter of Call */
/* XxMxPxP
xPxT
of Start + parameter of Call */
in
[
pn_Start_X_initial_exec
]
=
new_Jmp
();
in
[
pn_Start_M
]
=
get_Call_mem
(
call
);
in
[
pn_Start_P_frame_base
]
=
get_irg_frame
(
current_ir_graph
);
in
[
pn_Start_P_globals
]
=
get_irg_globals
(
current_ir_graph
);
in
[
pn_Start_P_tls
]
=
get_irg_tls
(
current_ir_graph
);
in
[
pn_Start_T_args
]
=
new_Tuple
(
get_Call_n_params
(
call
),
get_Call_param_arr
(
call
));
/* in[pn_Start_P_value_arg_base] = ??? */
pre_call
=
new_Tuple
(
5
,
in
);
pre_call
=
new_Tuple
(
pn_Start_max
,
in
);
post_call
=
call
;
/* --
...
...
ir/ir/irgraph.c
View file @
cdd903d8
...
...
@@ -227,6 +227,7 @@ new_r_ir_graph (entity *ent, int n_loc)
projX
=
new_Proj
(
start
,
mode_X
,
pn_Start_X_initial_exec
);
set_irg_frame
(
res
,
new_Proj
(
start
,
mode_P_data
,
pn_Start_P_frame_base
));
set_irg_globals
(
res
,
new_Proj
(
start
,
mode_P_data
,
pn_Start_P_globals
));
set_irg_tls
(
res
,
new_Proj
(
start
,
mode_P_data
,
pn_Start_P_tls
));
set_irg_args
(
res
,
new_Proj
(
start
,
mode_T
,
pn_Start_T_args
));
initial_mem
=
new_Proj
(
start
,
mode_M
,
pn_Start_M
);
set_irg_initial_mem
(
res
,
initial_mem
);
...
...
@@ -244,11 +245,11 @@ new_r_ir_graph (entity *ent, int n_loc)
* Use of this edge is matter of discussion, unresolved. Also possible:
* add_immBlock_pred(res->start_block, res->start_block), but invalid typed.
*/
mature_immBlock
(
res
->
current_block
);
mature_immBlock
(
res
->
current_block
);
/*-- Make a block to start with --*/
first_block
=
new_immBlock
();
add_immBlock_pred
(
first_block
,
projX
);
add_immBlock_pred
(
first_block
,
projX
);
res
->
method_execution_frequency
=
-
1
;
res
->
estimated_node_count
=
0
;
...
...
@@ -258,9 +259,9 @@ new_r_ir_graph (entity *ent, int n_loc)
ir_graph
*
new_ir_graph
(
entity
*
ent
,
int
n_loc
)
new_ir_graph
(
entity
*
ent
,
int
n_loc
)
{
ir_graph
*
res
=
new_r_ir_graph
(
ent
,
n_loc
);
ir_graph
*
res
=
new_r_ir_graph
(
ent
,
n_loc
);
add_irp_irg
(
res
);
/* remember this graph global. */
return
res
;
}
...
...
@@ -478,6 +479,16 @@ void
_set_irg_globals
(
irg
,
node
);
}
ir_node
*
(
get_irg_tls
)(
const
ir_graph
*
irg
)
{
return
_get_irg_tls
(
irg
);
}
void
(
set_irg_tls
)(
ir_graph
*
irg
,
ir_node
*
node
)
{
_set_irg_tls
(
irg
,
node
);
}
ir_node
*
(
get_irg_initial_mem
)(
const
ir_graph
*
irg
)
{
return
_get_irg_initial_mem
(
irg
);
...
...
ir/ir/irgraph.h
View file @
cdd903d8
...
...
@@ -56,22 +56,26 @@
* *frame The ir_node producing the pointer to the stack frame of
* the procedure as output. This is the Proj node on the
* third output of the start node. This output of the start
* node is tagged as pns_frame_base. In FIRM most local
*
node is tagged as pns_frame_base. In FIRM most local
* variables are modeled as data flow edges. Static
* allocated arrays can not be represented as data flow
* edges. Therefore FIRM has to represent them in the stack
* frame.
*
* *globals This models a pointer to a space in the memory where
* _all_ global things are held. Select from this pointer
* with a Sel node the pointer to a global variable /
* procedure / compiler known function... .
*
_all_ global things are held. Select from this pointer
*
with a Sel node the pointer to a global variable /
*
procedure / compiler known function... .
*
* *
args
Th
e ir_node that produces the arguments of the method as
*
it's result. This is a Proj node on the fourth output of
*
the start node. This output is tagged as pn_Start_T_args
.
* *
tls
Th
is models a pointer to a space in the memory where
*
thread local things are held. Select from this pointer
*
with a Sel node the pointer to a thread local variable
.
*
* *proj_args The proj nodes of the args node.
* *args The ir_node that produces the arguments of the method as
* it's result. This is a Proj node on the fourth output of
* the start node. This output is tagged as pn_Start_T_args.
*
* *proj_args The proj nodes of the args node.
*
* *bad The Bad node is an auxiliary node. It is needed only once,
* so there is this globally reachable node.
...
...
@@ -89,14 +93,14 @@
* Only needed for ir construction.
*
* params/n_loc An int giving the number of local variables in this
* procedure. This is needed for ir construction. Name will
* be changed.
*
procedure. This is needed for ir construction. Name will
*
be changed.
*
* *value_table This hash table (pset) is used for global value numbering
* for optimizing use in iropt.c.
*
for optimizing use in iropt.c.
*
* *Phi_in_stack; a stack needed for automatic Phi construction, needed only
* during ir construction.
*
during ir construction.
*
* visited A int used as flag to traverse the ir_graph.
*
...
...
@@ -137,7 +141,7 @@ void set_interprocedural_view(int state);
* procedure:
*
* - The start block containing a start node and Proj nodes for it's
*
fi
ve results (X, M, P, P,
T
).
*
se
ve
n
results (X, M, P, P,
P, T, P
).
* - The end block containing an end node. This block is not matured
* after executing new_ir_graph() as predecessors need to be added to it.
* (Maturing a block means fixing it's number of predecessors.)
...
...
@@ -220,6 +224,11 @@ ir_node *get_irg_globals (const ir_graph *irg);
/** Sets the node that represents the global pointer. */
void
set_irg_globals
(
ir_graph
*
irg
,
ir_node
*
node
);
/** Returns the node that represents the tls pointer. */
ir_node
*
get_irg_tls
(
const
ir_graph
*
irg
);
/** Sets the node that represents the tls pointer. */
void
set_irg_tls
(
ir_graph
*
irg
,
ir_node
*
node
);
/** Returns the node that represents the initial memory. */
ir_node
*
get_irg_initial_mem
(
const
ir_graph
*
irg
);
/** Sets the node that represents the initial memory. */
...
...
ir/ir/irgraph_t.h
View file @
cdd903d8
...
...
@@ -64,6 +64,8 @@ enum irg_anchors {
anchor_frame
,
/**< method's frame */
anchor_globals
,
/**< pointer to the data segment containing all
globals as well as global procedures. */
anchor_tls
,
/**< pointer to the thread local storage containing all
thread local data. */
anchor_initial_mem
,
/**< initial memory of this graph */
anchor_args
,
/**< methods arguments */
anchor_bad
,
/**< bad node of this ir_graph, the one and
...
...
@@ -271,6 +273,16 @@ _set_irg_globals(ir_graph *irg, ir_node *node) {
irg
->
anchors
[
anchor_globals
]
=
node
;
}
static
INLINE
ir_node
*
_get_irg_tls
(
const
ir_graph
*
irg
)
{
return
irg
->
anchors
[
anchor_tls
];
}
static
INLINE
void
_set_irg_tls
(
ir_graph
*
irg
,
ir_node
*
node
)
{
irg
->
anchors
[
anchor_tls
]
=
node
;
}
static
INLINE
ir_node
*
_get_irg_initial_mem
(
const
ir_graph
*
irg
)
{
return
irg
->
anchors
[
anchor_initial_mem
];
...
...
@@ -583,6 +595,8 @@ get_idx_irn(ir_graph *irg, unsigned idx) {
#define set_irg_frame(irg, node) _set_irg_frame(irg, node)
#define get_irg_globals(irg) _get_irg_globals(irg)
#define set_irg_globals(irg, node) _set_irg_globals(irg, node)
#define get_irg_tls(irg) _get_irg_tls(irg)
#define set_irg_tls(irg, node) _set_irg_tls(irg, node)
#define get_irg_initial_mem(irg) _get_irg_initial_mem(irg)
#define set_irg_initial_mem(irg, node) _set_irg_initial_mem(irg, node)
#define get_irg_args(irg) _get_irg_args(irg)
...
...
ir/ir/irnode.c
View file @
cdd903d8
...
...
@@ -592,8 +592,7 @@ set_nodes_block (ir_node *node, ir_node *block) {
/* Test whether arbitrary node is frame pointer, i.e. Proj(pn_Start_P_frame_base)
* from Start. If so returns frame type, else Null. */
ir_type
*
is_frame_pointer
(
ir_node
*
n
)
{
if
((
get_irn_op
(
n
)
==
op_Proj
)
&&
(
get_Proj_proj
(
n
)
==
pn_Start_P_frame_base
))
{
if
(
is_Proj
(
n
)
&&
(
get_Proj_proj
(
n
)
==
pn_Start_P_frame_base
))
{
ir_node
*
start
=
get_Proj_pred
(
n
);
if
(
get_irn_op
(
start
)
==
op_Start
)
{
return
get_irg_frame_type
(
get_irn_irg
(
start
));
...
...
@@ -605,8 +604,7 @@ ir_type *is_frame_pointer(ir_node *n) {
/* Test whether arbitrary node is globals pointer, i.e. Proj(pn_Start_P_globals)
* from Start. If so returns global type, else Null. */
ir_type
*
is_globals_pointer
(
ir_node
*
n
)
{
if
((
get_irn_op
(
n
)
==
op_Proj
)
&&
(
get_Proj_proj
(
n
)
==
pn_Start_P_globals
))
{
if
(
is_Proj
(
n
)
&&
(
get_Proj_proj
(
n
)
==
pn_Start_P_globals
))
{
ir_node
*
start
=
get_Proj_pred
(
n
);
if
(
get_irn_op
(
start
)
==
op_Start
)
{
return
get_glob_type
();
...
...
@@ -615,6 +613,18 @@ ir_type *is_globals_pointer(ir_node *n) {
return
NULL
;
}
/* Test whether arbitrary node is tls pointer, i.e. Proj(pn_Start_P_tls)
* from Start. If so returns tls type, else Null. */
ir_type
*
is_tls_pointer
(
ir_node
*
n
)
{
if
(
is_Proj
(
n
)
&&
(
get_Proj_proj
(
n
)
==
pn_Start_P_globals
))
{
ir_node
*
start
=
get_Proj_pred
(
n
);
if
(
get_irn_op
(
start
)
==
op_Start
)
{
return
get_tls_type
();
}
}
return
NULL
;
}
/* Test whether arbitrary node is value arg base, i.e. Proj(pn_Start_P_value_arg_base)
* from Start. If so returns 1, else 0. */
int
is_value_arg_pointer
(
ir_node
*
n
)
{
...
...
ir/ir/irnode.h
View file @
cdd903d8
...
...
@@ -245,14 +245,16 @@ typedef enum {
pn_Start_M
,
/**< Projection on the initial memory. */
pn_Start_P_frame_base
,
/**< Projection on the frame base pointer. */
pn_Start_P_globals
,
/**< Projection on the pointer to the data segment
containing _all_ global entities. */
containing _all_ global entities. Use for
position independent data/code access. */
pn_Start_P_tls
,
/**< Projection on the pointer to the thread local store
segment containing _all_thread local variables. */
pn_Start_T_args
,
/**< Projection on all arguments. */
pn_Start_P_value_arg_base
,
/**< Pointer to region of compound value arguments as defined by
type of this method. */
pn_Start_max
/**< number of projections from a Start */
}
pn_Start
;
/* Projection numbers for Start. */
/** Test whether arbitrary node is frame pointer.
*
* Test whether arbitrary node is frame pointer, i.e. Proj(pn_Start_P_frame_base)
...
...
@@ -265,6 +267,12 @@ ir_type *is_frame_pointer(ir_node *n);
* from Start. If so returns global type, else Null. */
ir_type
*
is_globals_pointer
(
ir_node
*
n
);
/** Test whether arbitrary node is tls pointer.
*
* Test whether arbitrary node is tls pointer, i.e. Proj(pn_Start_P_tls)
* from Start. If so returns tls type, else Null. */
ir_type
*
is_tls_pointer
(
ir_node
*
n
);
/** Test whether arbitrary node is value arg base.
*
* Test whether arbitrary node is value arg base, i.e. Proj(pn_Start_P_value_arg_base)
...
...
ir/ir/irprog.c
View file @
cdd903d8
...
...
@@ -26,7 +26,11 @@
#include
"typegmod.h"
#include
"irop_t.h"
/** The name of the Global Type. */
#define GLOBAL_TYPE_NAME "GlobalType"
/** The name of the Thread Local STorage Type. */
#define TLS_TYPE_NAME "TLS"
/** The initial name of the irp program. */
#define INITAL_PROG_NAME "no_name_set"
/* A variable from where everything in the ir can be accessed. */
...
...
@@ -39,7 +43,7 @@ ir_prog *get_irp(void) { return irp; }
static
ir_prog
*
new_incomplete_ir_prog
(
void
)
{
ir_prog
*
res
;
res
=
xmalloc
(
sizeof
(
*
res
));
res
=
xmalloc
(
sizeof
(
*
res
));
memset
(
res
,
0
,
sizeof
(
*
res
));
irp
=
res
;
...
...
@@ -59,13 +63,15 @@ static ir_prog *new_incomplete_ir_prog (void) {
/** Completes an incomplete irprog. */
static
ir_prog
*
complete_ir_prog
(
ir_prog
*
irp
)
{
#define X(s) s, sizeof(s)-1
irp
->
name
=
new_id_from_chars
(
X
(
INITAL_PROG_NAME
));
irp
->
name
=
new_id_from_str
(
INITAL_PROG_NAME
);
irp
->
glob_type
=
new_type_class
(
new_id_from_str
(
GLOBAL_TYPE_NAME
));
/* Remove type from type list. Must be treated differently than
irp
->
glob_type
=
new_type_class
(
new_id_from_chars
(
X
(
GLOBAL_TYPE_NAME
)));
irp
->
tls_type
=
new_type_struct
(
new_id_from_chars
(
X
(
TLS_TYPE_NAME
)));
/* Remove these types from type list. Must be treated differently than
other types. */
remove_irp_type
(
irp
->
glob_type
);
remove_irp_type
(
irp
->
tls_type
);
irp
->
const_code_irg
=
new_const_code_irg
();
...
...
@@ -99,6 +105,8 @@ ir_prog *new_ir_prog (void) {
void
free_ir_prog
(
void
)
{
if
(
irp
->
glob_type
)
free_type
(
irp
->
glob_type
);
if
(
irp
->
tls_type
)
free_type
(
irp
->
tls_type
);
/* @@@ * free_ir_graph(irp->const_code_irg); * ?? End has no in?? */
DEL_ARR_F
(
irp
->
graphs
);
...
...
@@ -130,6 +138,10 @@ ir_type *(get_glob_type)(void) {
return
_get_glob_type
();
}
ir_type
*
(
get_tls_type
)(
void
)
{
return
_get_tls_type
();
}
/* Adds irg to the list of ir graphs in irp. */
void
add_irp_irg
(
ir_graph
*
irg
)
{
assert
(
irg
!=
NULL
);
...
...
@@ -186,7 +198,7 @@ void set_irp_irg(int pos, ir_graph *irg) {
}
/* Gets the number of graphs _and_ pseudo graphs. */
int
get_irp_n_allirgs
(
void
)
{
int
get_irp_n_allirgs
(
void
)
{
/* We can not call get_irp_n_irgs, as we end up in a recursion ... */
return
ARR_LEN
(
irp
->
graphs
)
+
get_irp_n_pseudo_irgs
();
}
...
...
ir/ir/irprog.h
View file @
cdd903d8
...
...
@@ -131,10 +131,18 @@ int get_irp_n_allirgs(void);
pseudo graphs). Visits first graphs, then pseudo graphs. */
ir_graph
*
get_irp_allirg
(
int
pos
);
/** Returns the "global" type of the irp. */
/**
* Returns the "global" type of the irp.
* Upon creation this is an empty class type.
*/
ir_type
*
get_glob_type
(
void
);
/**
* Returns the "thread local storage" type of the irp.
* Upon creation this is an empty struct type.
*/
ir_type
*
get_tls_type
(
void
);
/** Adds type to the list of types in irp. */
void
add_irp_type
(
ir_type
*
typ
);
...
...
ir/ir/irprog_t.h
View file @
cdd903d8
...
...
@@ -48,8 +48,10 @@ struct ir_prog {
to allocate nodes the represent values
of constant entities. It is not meant as
a procedure. */
ir_type
*
glob_type
;
/**< global type. Must be a class as it can
ir_type
*
glob_type
;
/**<
The
global type. Must be a class as it can
have fields and procedures. */
ir_type
*
tls_type
;
/**< The thread local storage type. Must be a struct as it can
only have fields. */
ir_type
**
types
;
/**< all types in the ir */
ir_mode
**
modes
;
/**< all modes in the ir */
ir_op
**
opcodes
;
/**< all opcodes in the ir */
...
...
@@ -96,6 +98,12 @@ _get_glob_type(void) {
return
irp
->
glob_type
=
skip_tid
(
irp
->
glob_type
);
}
static
INLINE
ir_type
*
_get_tls_type
(
void
)
{
assert
(
irp
);
return
irp
->
tls_type
=
skip_tid
(
irp
->
tls_type
);
}
static
INLINE
int
_get_irp_n_irgs
(
void
)
{
assert
(
irp
&&
irp
->
graphs
);
...
...
@@ -181,5 +189,6 @@ void init_irprog_2(void);
#define get_irp_opcode(pos) _get_irp_opcode(pos)
#define get_const_code_irg() _get_const_code_irg()
#define get_glob_type() _get_glob_type()
#define get_tls_type() _get_tls_type()
#endif
/* ifndef _FIRM_IR_IRPROG_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