Commit a9950b7e authored by Matthias Braun's avatar Matthias Braun
Browse files

remove get_irg_tls() concept, simply use SymConst and let the backend figure it out

parent b7a0d752
......@@ -333,7 +333,6 @@ static int verify_node_Proj_Start(ir_node *n, ir_node *p)
(proj == pn_Start_X_initial_exec && mode == mode_X) ||
(proj == pn_Start_M && mode == mode_M) ||
(proj == pn_Start_P_frame_base && mode_is_reference(mode)) ||
(proj == pn_Start_P_tls && mode_is_reference(mode)) ||
(proj == pn_Start_T_args && mode == mode_T)
),
"wrong Proj from Start", 0,
......
......@@ -73,160 +73,148 @@ static void lower_sel(ir_node *sel)
mode_Int = get_reference_mode_signed_eq(mode);
/* TLS access, must be handled by the linker */
if (get_tls_type() == owner) {
symconst_symbol sym;
assert(get_type_state(get_entity_owner(ent)) == layout_fixed);
assert(get_type_state(get_entity_type(ent)) == layout_fixed);
bl = get_nodes_block(sel);
if (0 < get_Sel_n_indexs(sel)) {
/* an Array access */
basetyp = get_entity_type(ent);
if (is_Primitive_type(basetyp))
basemode = get_type_mode(basetyp);
else
basemode = mode_P_data;
assert(basemode && "no mode for lowering Sel");
assert((get_mode_size_bits(basemode) % 8 == 0) && "can not deal with unorthodox modes");
index = get_Sel_index(sel, 0);
if (is_Array_type(owner)) {
ir_type *arr_ty = owner;
int dims = get_array_n_dimensions(arr_ty);
int *map = ALLOCAN(int, dims);
ir_node *last_size;
int i;
assert(dims == get_Sel_n_indexs(sel)
&& "array dimension must match number of indices of Sel node");
for (i = 0; i < dims; i++) {
int order = get_array_order(arr_ty, i);
assert(order < dims &&
"order of a dimension must be smaller than the arrays dim");
map[order] = i;
}
newn = get_Sel_ptr(sel);
/* Size of the array element */
tv = new_tarval_from_long(get_type_size_bytes(basetyp), mode_Int);
last_size = new_rd_Const(dbg, irg, tv);
/*
* We compute the offset part of dimension d_i recursively
* with the the offset part of dimension d_{i-1}
*
* off_0 = sizeof(array_element_type);
* off_i = (u_i - l_i) * off_{i-1} ; i >= 1
*
* whereas u_i is the upper bound of the current dimension
* and l_i the lower bound of the current dimension.
*/
for (i = dims - 1; i >= 0; i--) {
int dim = map[i];
ir_node *lb, *ub, *elms, *n, *ind;
elms = NULL;
lb = get_array_lower_bound(arr_ty, dim);
ub = get_array_upper_bound(arr_ty, dim);
assert(irg == current_ir_graph);
if (! is_Unknown(lb))
lb = new_rd_Conv(dbg, bl, copy_const_value(get_irn_dbg_info(sel), lb, bl), mode_Int);
else
lb = NULL;
if (! is_Unknown(ub))
ub = new_rd_Conv(dbg, bl, copy_const_value(get_irn_dbg_info(sel), ub, bl), mode_Int);
else
ub = NULL;
sym.entity_p = ent;
bl = get_nodes_block(sel);
/*
* If the array has more than one dimension, lower and upper
* bounds have to be set in the non-last dimension.
*/
if (i > 0) {
assert(lb != NULL && "lower bound has to be set in multi-dim array");
assert(ub != NULL && "upper bound has to be set in multi-dim array");
cnst = new_rd_SymConst(dbg, irg, mode, sym, symconst_addr_ent);
newn = new_rd_Add(dbg, bl, ptr, cnst, mode);
} else {
/* not TLS */
/* Elements in one Dimension */
elms = new_rd_Sub(dbg, bl, ub, lb, mode_Int);
}
assert(get_type_state(get_entity_owner(ent)) == layout_fixed);
assert(get_type_state(get_entity_type(ent)) == layout_fixed);
ind = new_rd_Conv(dbg, bl, get_Sel_index(sel, dim), mode_Int);
bl = get_nodes_block(sel);
if (0 < get_Sel_n_indexs(sel)) {
/* an Array access */
basetyp = get_entity_type(ent);
if (is_Primitive_type(basetyp))
basemode = get_type_mode(basetyp);
else
basemode = mode_P_data;
assert(basemode && "no mode for lowering Sel");
assert((get_mode_size_bits(basemode) % 8 == 0) && "can not deal with unorthodox modes");
index = get_Sel_index(sel, 0);
if (is_Array_type(owner)) {
ir_type *arr_ty = owner;
int dims = get_array_n_dimensions(arr_ty);
int *map = ALLOCAN(int, dims);
ir_node *last_size;
int i;
assert(dims == get_Sel_n_indexs(sel)
&& "array dimension must match number of indices of Sel node");
for (i = 0; i < dims; i++) {
int order = get_array_order(arr_ty, i);
assert(order < dims &&
"order of a dimension must be smaller than the arrays dim");
map[order] = i;
}
newn = get_Sel_ptr(sel);
/*
* Normalize index, id lower bound is set, also assume
* lower bound == 0
*/
if (lb != NULL)
ind = new_rd_Sub(dbg, bl, ind, lb, mode_Int);
/* Size of the array element */
tv = new_tarval_from_long(get_type_size_bytes(basetyp), mode_Int);
last_size = new_rd_Const(dbg, irg, tv);
n = new_rd_Mul(dbg, bl, ind, last_size, mode_Int);
/*
* We compute the offset part of dimension d_i recursively
* with the the offset part of dimension d_{i-1}
*
* off_0 = sizeof(array_element_type);
* off_i = (u_i - l_i) * off_{i-1} ; i >= 1
*
* whereas u_i is the upper bound of the current dimension
* and l_i the lower bound of the current dimension.
* see comment above.
*/
for (i = dims - 1; i >= 0; i--) {
int dim = map[i];
ir_node *lb, *ub, *elms, *n, *ind;
elms = NULL;
lb = get_array_lower_bound(arr_ty, dim);
ub = get_array_upper_bound(arr_ty, dim);
assert(irg == current_ir_graph);
if (! is_Unknown(lb))
lb = new_rd_Conv(dbg, bl, copy_const_value(get_irn_dbg_info(sel), lb, bl), mode_Int);
else
lb = NULL;
if (! is_Unknown(ub))
ub = new_rd_Conv(dbg, bl, copy_const_value(get_irn_dbg_info(sel), ub, bl), mode_Int);
else
ub = NULL;
/*
* If the array has more than one dimension, lower and upper
* bounds have to be set in the non-last dimension.
*/
if (i > 0) {
assert(lb != NULL && "lower bound has to be set in multi-dim array");
assert(ub != NULL && "upper bound has to be set in multi-dim array");
/* Elements in one Dimension */
elms = new_rd_Sub(dbg, bl, ub, lb, mode_Int);
}
ind = new_rd_Conv(dbg, bl, get_Sel_index(sel, dim), mode_Int);
/*
* Normalize index, id lower bound is set, also assume
* lower bound == 0
*/
if (lb != NULL)
ind = new_rd_Sub(dbg, bl, ind, lb, mode_Int);
n = new_rd_Mul(dbg, bl, ind, last_size, mode_Int);
/*
* see comment above.
*/
if (i > 0)
last_size = new_rd_Mul(dbg, bl, last_size, elms, mode_Int);
newn = new_rd_Add(dbg, bl, newn, n, mode);
}
} else {
/* no array type */
ir_mode *idx_mode = get_irn_mode(index);
ir_tarval *tv = new_tarval_from_long(get_mode_size_bytes(basemode), idx_mode);
newn = new_rd_Add(dbg, bl, get_Sel_ptr(sel),
new_rd_Mul(dbg, bl, index,
new_r_Const(irg, tv),
idx_mode),
mode);
}
} else if (is_Method_type(get_entity_type(ent)) &&
is_Class_type(owner) &&
(owner != get_glob_type()) &&
(!is_frame_type(owner))) {
ir_node *add;
ir_mode *ent_mode = get_type_mode(get_entity_type(ent));
/* We need an additional load when accessing methods from a dispatch table. */
tv = new_tarval_from_long(get_entity_offset(ent), mode_Int);
cnst = new_rd_Const(dbg, irg, tv);
add = new_rd_Add(dbg, bl, get_Sel_ptr(sel), cnst, mode);
newn = new_rd_Load(dbg, bl, get_Sel_mem(sel), add, ent_mode, cons_none);
newn = new_r_Proj(newn, ent_mode, pn_Load_res);
} else if (get_entity_owner(ent) != get_glob_type()) {
int offset;
/* replace Sel by add(obj, const(ent.offset)) */
newn = get_Sel_ptr(sel);
offset = get_entity_offset(ent);
if (offset != 0) {
ir_mode *mode_UInt = get_reference_mode_unsigned_eq(mode);
tv = new_tarval_from_long(offset, mode_UInt);
cnst = new_r_Const(irg, tv);
newn = new_rd_Add(dbg, bl, newn, cnst, mode);
if (i > 0)
last_size = new_rd_Mul(dbg, bl, last_size, elms, mode_Int);
newn = new_rd_Add(dbg, bl, newn, n, mode);
}
} else {
/* global_type */
newn = new_rd_SymConst_addr_ent(NULL, irg, mode, ent);
/* no array type */
ir_mode *idx_mode = get_irn_mode(index);
ir_tarval *tv = new_tarval_from_long(get_mode_size_bytes(basemode), idx_mode);
newn = new_rd_Add(dbg, bl, get_Sel_ptr(sel),
new_rd_Mul(dbg, bl, index,
new_r_Const(irg, tv),
idx_mode),
mode);
}
} else if (is_Method_type(get_entity_type(ent)) &&
is_Class_type(owner) &&
(owner != get_glob_type()) &&
(!is_frame_type(owner))) {
ir_node *add;
ir_mode *ent_mode = get_type_mode(get_entity_type(ent));
/* We need an additional load when accessing methods from a dispatch table. */
tv = new_tarval_from_long(get_entity_offset(ent), mode_Int);
cnst = new_rd_Const(dbg, irg, tv);
add = new_rd_Add(dbg, bl, get_Sel_ptr(sel), cnst, mode);
newn = new_rd_Load(dbg, bl, get_Sel_mem(sel), add, ent_mode, cons_none);
newn = new_r_Proj(newn, ent_mode, pn_Load_res);
} else if (get_entity_owner(ent) != get_glob_type()) {
int offset;
/* replace Sel by add(obj, const(ent.offset)) */
newn = get_Sel_ptr(sel);
offset = get_entity_offset(ent);
if (offset != 0) {
ir_mode *mode_UInt = get_reference_mode_unsigned_eq(mode);
tv = new_tarval_from_long(offset, mode_UInt);
cnst = new_r_Const(irg, tv);
newn = new_rd_Add(dbg, bl, newn, cnst, mode);
}
} else {
/* global_type */
newn = new_rd_SymConst_addr_ent(NULL, irg, mode, ent);
}
/* run the hooks */
hook_lower(sel);
......
......@@ -393,7 +393,6 @@ int inline_method(ir_node *call, ir_graph *called_graph)
in[pn_Start_M] = get_Call_mem(call);
in[pn_Start_X_initial_exec] = new_r_Jmp(post_bl);
in[pn_Start_P_frame_base] = get_irg_frame(irg);
in[pn_Start_P_tls] = get_irg_tls(irg);
in[pn_Start_T_args] = new_r_Tuple(post_bl, n_params, args_in);
pre_call = new_r_Tuple(post_bl, pn_Start_max, in);
post_call = call;
......
......@@ -919,10 +919,7 @@ static void stat_update_address(ir_node *node, graph_entry_t *graph)
case iro_Sel:
base = find_base_adr(node);
irg = current_ir_graph;
if (base == get_irg_tls(irg)) {
/* a TLS variable, like a global. */
cnt_inc(&graph->cnt[gcnt_global_adr]);
} else if (base == get_irg_frame(irg)) {
if (base == get_irg_frame(irg)) {
/* a local Variable. */
cnt_inc(&graph->cnt[gcnt_local_adr]);
} else {
......
......@@ -809,7 +809,6 @@ class Start(Op):
("X_initial_exec", "control flow"),
("M", "initial memory"),
("P_frame_base", "frame base pointer"),
("P_tls", "pointer to thread local storage segment"),
("T_args", "function arguments")
]
mode = "mode_T"
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment