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

- representing the 3-state visibility (default,local,external) with 2 bits was

  clumsy. Bring back get_entity_visibility and set_entity_visibility

[r27039]
parent ec1235ae
......@@ -74,49 +74,61 @@
* @see ir_type, ir_entity
*/
/**
* Visibility classed for entities.
*/
typedef enum {
/**
* The entity is visible outside the compilation unit, but it is defined
* here.
*/
ir_visibility_default,
/**
* The entity is local to the compilation unit.
* A local entity is not visible in other compilation units.
* Note that the entity might still be accessed indirectly from other units
* through pointers.
*/
ir_visibility_local,
/**
* The entity is defined outside the compilation unit but potentially used
* here.
*/
ir_visibility_external
} ir_visibility;
/**
* linkage specifies how the linker treats symbols
*/
typedef enum {
IR_LINKAGE_DEFAULT = 0,
IR_LINKAGE_DEFAULT = 0,
/**
* A symbol whose definition won't change in a program.
* Optimisation might replace loads from this entity with constants.
* Also most linkers put such data in a constant segment which is shared
* between multiple running instances of the same application.
*/
IR_LINKAGE_CONSTANT = 1 << 0,
IR_LINKAGE_CONSTANT = 1 << 0,
/**
* The entity is a weak symbol.
* A weak symbol is overridden by a non-weak symbol if one exists.
* Most linkers only support the IR_LINKAGE_WEAK in combination with
* IR_LINKAGE_MERGE.
*/
IR_LINKAGE_WEAK = 1 << 1,
/**
* The entity is local to the compilation unit.
* A local entity will not be exported by the linker and is not visible
* in other compilation units. Note that the entity might still be accessed
* indirectly from other units through pointers.
*/
IR_LINKAGE_LOCAL = 1 << 2,
/**
* The entity is defined in another compilation.
*/
IR_LINKAGE_EXTERN = 1 << 3,
IR_LINKAGE_WEAK = 1 << 1,
/**
* The entity may be removed when it isn't referenced anywhere in the
* compilation unit even if it is exported (non-local).
* Typically used for C++ instantiated template code (,,COMDAT'' section).
*/
IR_LINKAGE_GARBAGE_COLLECT = 1 << 5,
IR_LINKAGE_GARBAGE_COLLECT = 1 << 2,
/**
* The linker will try to merge entities with same name from different
* compilation units. This is the usual behaviour for global variables
* without explicit initialisation in C (``COMMON'' symbols). It's also
* typically used in C++ for instantiated template code (,,COMDAT'' section)
*/
IR_LINKAGE_MERGE = 1 << 6,
IR_LINKAGE_MERGE = 1 << 3,
/**
* Some entity uses are potentially hidden from the compiler.
* (For example because they happen in an asm("") statement. This flag
......@@ -125,7 +137,7 @@ typedef enum {
* read/write behaviour to global variables or changing calling conventions
* from cdecl to fastcall.
*/
IR_LINKAGE_HIDDEN_USER = 1 << 7,
IR_LINKAGE_HIDDEN_USER = 1 << 4
} ir_linkage;
/**
......@@ -142,34 +154,30 @@ enum ir_common_linkages {
};
/**
* Return 1 if the entity is visible outside the current compilation unit.
* (The entity might still be accessible indirectly through pointers)
* This is a convenience function and does the same as
* (get_entity_linkage(entity) & IR_LINKAGE_LOCAL) == 0
* Return the visibility class of an entity
*/
int entity_is_externally_visible(const ir_entity *entity);
ir_visibility get_entity_visibility(const ir_entity *entity);
/**
* Return 1 if the entity has a definition (initializer) in the current
* compilation unit
* Set visibility class of an entity
*/
int entity_has_definition(const ir_entity *entity);
void set_entity_visibility(ir_entity *entity, ir_visibility visibility);
/**
* Return 1 if the entity is/will be defined in the current compilation unit.
* This is a convenience function for
* (get_entity_linkage(entity) & IR_LINKAGE_EXTERN) == 0.
*
* In contrast to entity_has_definition(entity) you have no guarantee here that
* the entity actually has a firm initializer.
* Return 1 if the entity is visible outside the current compilation unit
* or to unknown callers (like asm statements).
* (The entity might still be accessible indirectly through pointers)
* This is a convenience function and does the same as
* get_entity_visibility(entity) != ir_visibility_local ||
* (get_entity_linkage(entity) & IR_LINKAGE_HIDDEN_USER)
*/
int entity_is_defined_here(const ir_entity *entity);
int entity_is_externally_visible(const ir_entity *entity);
/**
* Return 1 if the entity is constant. Constant means the entities value
* won't change at all when the program is running.
* Return 1 if the entity has a definition (initializer) in the current
* compilation unit
*/
int entity_is_constant(const ir_entity *entity);
int entity_has_definition(const ir_entity *entity);
/**
* Creates a new entity.
......@@ -2429,15 +2437,6 @@ void walk_types_entities(ir_type *tp, entity_walk_func *doit, void *env);
*/
void types_calc_finalization(void);
/**
* @deprecated
*/
typedef enum {
visibility_local,
visibility_external_visible,
visibility_external_allocated
} ir_visibility;
/** @deprecated */
ir_visibility get_type_visibility(const ir_type *tp);
/** @deprecated */
......
......@@ -567,7 +567,7 @@ static ir_entity **get_free_methods(int *length)
ent = get_irg_entity(irg);
linkage = get_entity_linkage(ent);
if (!(linkage & IR_LINKAGE_LOCAL)
if (entity_is_externally_visible(ent)
|| (linkage & IR_LINKAGE_HIDDEN_USER)) {
eset_insert(free_set, ent);
}
......
......@@ -1048,7 +1048,7 @@ static void init_entity_usage(ir_type *tp)
ir_entity *ent = get_compound_member(tp, i);
ir_entity_usage flags = ir_usage_none;
if (! (get_entity_linkage(ent) & IR_LINKAGE_LOCAL)) {
if (entity_is_externally_visible(ent)) {
flags |= ir_usage_unknown;
}
set_entity_usage(ent, flags);
......@@ -1310,10 +1310,8 @@ void mark_private_methods(void)
ir_graph *irg = get_irp_irg(i);
ir_entity *ent = get_irg_entity(irg);
ir_entity_usage flags = get_entity_usage(ent);
ir_linkage linkage = get_entity_linkage(ent);
if ((linkage & IR_LINKAGE_LOCAL) &&
!(linkage & IR_LINKAGE_HIDDEN_USER) &&
if (!entity_is_externally_visible(ent) &&
!(flags & ir_usage_address_taken)) {
ir_type *mtp = get_entity_type(ent);
......
......@@ -212,7 +212,7 @@ static int rta_fill_incremental(void)
ir_entity *ent = get_irg_entity(graph);
ir_linkage linkage = get_entity_linkage(ent);
if (!(linkage & IR_LINKAGE_LOCAL)
if (entity_is_externally_visible(ent)
|| (linkage & IR_LINKAGE_HIDDEN_USER)) {
eset_insert(_live_graphs, graph);
}
......
......@@ -566,7 +566,8 @@ static void arm_handle_intrinsics(void)
rt_iDiv.exc_mem_proj_nr = pn_Div_M;
rt_iDiv.res_proj_nr = pn_Div_res;
set_entity_linkage(rt_iDiv.ent, IR_LINKAGE_EXTERN | IR_LINKAGE_CONSTANT);
add_entity_linkage(rt_iDiv.ent, IR_LINKAGE_CONSTANT);
set_entity_visibility(rt_iDiv.ent, ir_visibility_external);
map_Div->kind = INTRINSIC_INSTR;
map_Div->op = op_Div;
......@@ -592,7 +593,7 @@ static void arm_handle_intrinsics(void)
rt_uDiv.exc_mem_proj_nr = pn_Div_M;
rt_uDiv.res_proj_nr = pn_Div_res;
set_entity_linkage(rt_uDiv.ent, IR_LINKAGE_EXTERN);
set_entity_visibility(rt_uDiv.ent, ir_visibility_external);
map_Div->kind = INTRINSIC_INSTR;
map_Div->op = op_Div;
......@@ -618,7 +619,7 @@ static void arm_handle_intrinsics(void)
rt_iMod.exc_mem_proj_nr = pn_Mod_M;
rt_iMod.res_proj_nr = pn_Mod_res;
set_entity_linkage(rt_iMod.ent, IR_LINKAGE_EXTERN);
set_entity_visibility(rt_iMod.ent, ir_visibility_external);
map_Mod->kind = INTRINSIC_INSTR;
map_Mod->op = op_Mod;
......@@ -644,7 +645,7 @@ static void arm_handle_intrinsics(void)
rt_uMod.exc_mem_proj_nr = pn_Mod_M;
rt_uMod.res_proj_nr = pn_Mod_res;
set_entity_linkage(rt_uMod.ent, IR_LINKAGE_EXTERN);
set_entity_visibility(rt_uMod.ent, ir_visibility_external);
map_Mod->kind = INTRINSIC_INSTR;
map_Mod->op = op_Mod;
......
......@@ -2111,7 +2111,7 @@ static ir_entity *create_trampoline(be_main_env_t *be, ir_entity *method)
ir_type *parent = be->pic_trampolines_type;
ir_entity *ent = new_entity(parent, old_id, type);
set_entity_ld_ident(ent, id);
set_entity_linkage(ent, IR_LINKAGE_LOCAL);
set_entity_visibility(ent, ir_visibility_local);
return ent;
}
......@@ -2139,7 +2139,7 @@ static ir_entity *create_pic_symbol(be_main_env_t *be, ir_entity *entity)
ir_type *parent = be->pic_symbols_type;
ir_entity *ent = new_entity(parent, old_id, type);
set_entity_ld_ident(ent, id);
set_entity_linkage(ent, IR_LINKAGE_LOCAL);
set_entity_visibility(ent, ir_visibility_local);
return ent;
}
......@@ -2162,7 +2162,7 @@ static ir_entity *get_pic_symbol(be_main_env_t *env, ir_entity *entity)
*/
static int can_address_relative(ir_entity *entity)
{
return !(get_entity_linkage(entity) & IR_LINKAGE_EXTERN);
return get_entity_visibility(entity) != ir_visibility_external;
}
/** patches SymConsts to work in position independent code */
......
......@@ -120,9 +120,10 @@ void be_gas_emit_switch_section(be_gas_section_t section)
static void emit_entity_visibility(const ir_entity *entity)
{
ir_linkage linkage = get_entity_linkage(entity);
ir_visibility visibility = get_entity_visibility(entity);
ir_linkage linkage = get_entity_linkage(entity);
if (! (linkage & IR_LINKAGE_LOCAL)) {
if (visibility != ir_visibility_local) {
be_emit_cstring(".globl ");
be_emit_ident(get_entity_ld_ident(entity));
be_emit_char('\n');
......@@ -179,7 +180,7 @@ void be_gas_emit_function_prolog(ir_entity *entity, unsigned po2alignment)
be_emit_cstring("\t.def\t");
be_emit_string(name);
be_emit_cstring(";");
if (get_entity_linkage(entity) & IR_LINKAGE_LOCAL) {
if (get_entity_visibility(entity) == ir_visibility_local) {
be_emit_cstring("\t.scl\t3;");
} else {
be_emit_cstring("\t.scl\t2;");
......@@ -1197,7 +1198,6 @@ static void dump_global(be_gas_decl_env_t *env, const ir_entity *ent)
ident *ld_ident = get_entity_ld_ident(ent);
unsigned alignment = get_effective_entity_alignment(ent);
be_gas_section_t section = determine_section(env, ent);
ir_linkage linkage = get_entity_linkage(ent);
/* we already emitted all methods. Except for the trampolines which
* the assembler/linker generates */
......@@ -1211,7 +1211,7 @@ static void dump_global(be_gas_decl_env_t *env, const ir_entity *ent)
be_dbg_variable(ent);
/* nothing to do for externally defined values */
if (linkage & IR_LINKAGE_EXTERN)
if (get_entity_visibility(ent) == ir_visibility_external)
return;
if (!is_po2(alignment))
......@@ -1219,7 +1219,7 @@ static void dump_global(be_gas_decl_env_t *env, const ir_entity *ent)
if (section == GAS_SECTION_BSS &&
(get_entity_linkage(ent) & IR_LINKAGE_MERGE)) {
if (get_entity_linkage(ent) & (IR_LINKAGE_LOCAL|IR_LINKAGE_EXTERN)) {
if (get_entity_visibility(ent) != ir_visibility_default) {
panic("merge link semantic not supported for local/extern entities");
}
emit_common(ent);
......
......@@ -682,7 +682,7 @@ static void stabs_method_begin(dbg_handle *handle, ir_entity *ent, const be_stac
type_num = get_type_number(h, rtp);
be_emit_irprintf("\t.stabs\t\"%s:%c%u\",%u,0,0,%s\n",
get_entity_name(ent),
entity_is_externally_visible(ent) ? 'F' : 'f',
get_entity_visibility(ent) == ir_visibility_local ? 'f' : 'F',
type_num,
N_FUN,
get_entity_ld_name(ent));
......@@ -794,11 +794,7 @@ static void stabs_variable(dbg_handle *handle, ir_entity *ent) {
unsigned tp_num = get_type_number(h, get_entity_type(ent));
char buf[1024];
if (entity_is_externally_visible(ent)) {
/* a global variable */
snprintf(buf, sizeof(buf), "\t.stabs\t\"%s:G%u\",%d,0,0,0\n",
get_entity_name(ent), tp_num, N_GSYM);
} else {
if (get_entity_visibility(ent) == ir_visibility_local) {
/* some kind of local */
ir_linkage linkage = get_entity_linkage(ent);
int kind = N_STSYM;
......@@ -807,6 +803,10 @@ static void stabs_variable(dbg_handle *handle, ir_entity *ent) {
kind = N_ROSYM;
snprintf(buf, sizeof(buf), "\t.stabs\t\"%s:S%u\",%d,0,0,%s\n",
get_entity_name(ent), tp_num, kind, get_entity_ld_name(ent));
} else {
/* a global variable */
snprintf(buf, sizeof(buf), "\t.stabs\t\"%s:G%u\",%d,0,0,0\n",
get_entity_name(ent), tp_num, N_GSYM);
}
buf[sizeof(buf) - 1] = '\0';
......
......@@ -872,7 +872,7 @@ static void ia32_before_abi(void *self)
mcount = new_entity(get_glob_type(), ID("mcount"), tp);
/* FIXME: enter the right ld_ident here */
set_entity_ld_ident(mcount, get_entity_ident(mcount));
set_entity_linkage(mcount, IR_LINKAGE_EXTERN);
set_entity_visibility(mcount, ir_visibility_external);
}
instrument_initcall(cg->irg, mcount);
}
......
......@@ -143,7 +143,8 @@ ir_entity *create_float_const_entity(ir_node *cnst)
res = new_entity(get_glob_type(), ia32_unique_id(".LC%u"), tp);
set_entity_ld_ident(res, get_entity_ident(res));
set_entity_linkage(res, IR_LINKAGE_LOCAL | IR_LINKAGE_CONSTANT);
set_entity_visibility(res, ir_visibility_local);
add_entity_linkage(res, IR_LINKAGE_CONSTANT);
/* we create a new entity here: It's initialization must resist on the
const code irg */
......
......@@ -285,7 +285,7 @@ static void ia32_emit_entity(ir_entity *entity, int no_pic_adjust)
be_gas_emit_entity(entity);
if (get_entity_owner(entity) == get_tls_type()) {
if (get_entity_linkage(entity) & IR_LINKAGE_EXTERN) {
if (get_entity_visibility(entity) == ir_visibility_external) {
be_emit_cstring("@INDNTPOFF");
} else {
be_emit_cstring("@NTPOFF");
......@@ -2417,7 +2417,7 @@ static void bemit_entity(ir_entity *entity, bool entity_sign, int offset,
be_gas_emit_entity(entity);
if (get_entity_owner(entity) == get_tls_type()) {
if (get_entity_linkage(entity) & IR_LINKAGE_EXTERN) {
if (get_entity_visibility(entity) == ir_visibility_external) {
be_emit_cstring("@INDNTPOFF");
} else {
be_emit_cstring("@NTPOFF");
......
......@@ -68,7 +68,8 @@ static ir_entity *create_ent(int value, const char *name)
tv = new_tarval_from_long(value, mode);
ent = new_entity(glob, new_id_from_str(name), type);
set_entity_ld_ident(ent, get_entity_ident(ent));
set_entity_linkage(ent, IR_LINKAGE_LOCAL | IR_LINKAGE_CONSTANT);
set_entity_visibility(ent, ir_visibility_local);
add_entity_linkage(ent, IR_LINKAGE_CONSTANT);
cnst_irg = get_const_code_irg();
cnst = new_r_Const(cnst_irg, tv);
......
......@@ -683,7 +683,7 @@ static int map_Div(ir_node *call, void *ctx)
if (ent == NULL) {
/* create library entity */
ent = env->divdi3 = new_entity(get_glob_type(), ID("__divdi3"), method);
set_entity_linkage(ent, IR_LINKAGE_EXTERN);
set_entity_visibility(ent, ir_visibility_external);
set_entity_ld_ident(ent, ID("__divdi3"));
}
} else {
......@@ -692,7 +692,7 @@ static int map_Div(ir_node *call, void *ctx)
if (ent == NULL) {
/* create library entity */
ent = env->udivdi3 = new_entity(get_glob_type(), ID("__udivdi3"), method);
set_entity_linkage(ent, IR_LINKAGE_EXTERN);
set_entity_visibility(ent, ir_visibility_external);
set_entity_ld_ident(ent, ID("__udivdi3"));
}
}
......@@ -723,7 +723,7 @@ static int map_Mod(ir_node *call, void *ctx) {
if (ent == NULL) {
/* create library entity */
ent = env->moddi3 = new_entity(get_glob_type(), ID("__moddi3"), method);
set_entity_linkage(ent, IR_LINKAGE_EXTERN);
set_entity_visibility(ent, ir_visibility_external);
set_entity_ld_ident(ent, ID("__moddi3"));
}
} else {
......@@ -732,7 +732,7 @@ static int map_Mod(ir_node *call, void *ctx) {
if (ent == NULL) {
/* create library entity */
ent = env->umoddi3 = new_entity(get_glob_type(), ID("__umoddi3"), method);
set_entity_linkage(ent, IR_LINKAGE_EXTERN);
set_entity_visibility(ent, ir_visibility_external);
set_entity_ld_ident(ent, ID("__umoddi3"));
}
}
......
......@@ -509,7 +509,8 @@ ir_entity *ia32_gen_fp_known_const(ia32_known_const_t kct)
ent = new_entity(get_glob_type(), new_id_from_str(ent_name), tp);
set_entity_ld_ident(ent, get_entity_ident(ent));
set_entity_linkage(ent, IR_LINKAGE_LOCAL | IR_LINKAGE_CONSTANT);
add_entity_linkage(ent, IR_LINKAGE_CONSTANT);
set_entity_visibility(ent, ir_visibility_local);
if (kct == ia32_ULLBIAS) {
ir_initializer_t *initializer = create_initializer_compound(2);
......@@ -3101,7 +3102,8 @@ static ir_entity *ia32_create_const_array(ir_node *c0, ir_node *c1, ir_mode **ne
ent = new_entity(get_glob_type(), ia32_unique_id(".LC%u"), tp);
set_entity_ld_ident(ent, get_entity_ident(ent));
set_entity_linkage(ent, IR_LINKAGE_LOCAL | IR_LINKAGE_CONSTANT);
set_entity_visibility(ent, ir_visibility_local);
add_entity_linkage(ent, IR_LINKAGE_CONSTANT);
initializer = create_initializer_compound(2);
......
......@@ -1410,7 +1410,8 @@ static ir_node *gen_fp_known_symconst(ppc32_transform_env_t *env,
ent = new_entity(get_glob_type(), new_id_from_str(buf), tp);
set_entity_ld_ident(ent, get_entity_ident(ent));
set_entity_linkage(ent, IR_LINKAGE_CONSTANT|IR_LINKAGE_LOCAL);
set_entity_visibility(ent, ir_visibility_local);
add_entity_linkage(ent, IR_LINKAGE_CONSTANT);
/* we create a new entity here: It's initialization must resist on the
const code irg */
......
......@@ -621,10 +621,6 @@ static void dump_entity_linkage(FILE *F, const ir_entity *entity)
fprintf(F, " constant");
if (linkage & IR_LINKAGE_WEAK)
fprintf(F, " weak");
if (linkage & IR_LINKAGE_LOCAL)
fprintf(F, " local");
if (linkage & IR_LINKAGE_EXTERN)
fprintf(F, " extern");
if (linkage & IR_LINKAGE_GARBAGE_COLLECT)
fprintf(F, " garbage_collect");
if (linkage & IR_LINKAGE_MERGE)
......
......@@ -76,7 +76,8 @@ typedef enum typetag_t
tt_type_state,
tt_volatility,
tt_linkage,
tt_segment
tt_segment,
tt_visibility
} typetag_t;
typedef enum keyword_t
......@@ -193,12 +194,14 @@ static void symtbl_init(void)
INSERT(tt_linkage, "constant", IR_LINKAGE_CONSTANT);
INSERT(tt_linkage, "weak", IR_LINKAGE_WEAK);
INSERT(tt_linkage, "local", IR_LINKAGE_LOCAL);
INSERT(tt_linkage, "extern", IR_LINKAGE_EXTERN);
INSERT(tt_linkage, "garbage_collect", IR_LINKAGE_GARBAGE_COLLECT);
INSERT(tt_linkage, "merge", IR_LINKAGE_MERGE);
INSERT(tt_linkage, "hidden_user", IR_LINKAGE_HIDDEN_USER);
INSERT(tt_visibility, "local", ir_visibility_local);
INSERT(tt_visibility, "external", ir_visibility_external);
INSERT(tt_visibility, "default", ir_visibility_default);
INSERTKEYWORD(constirg);
INSERTKEYWORD(entity);
INSERTKEYWORD(irg);
......@@ -1076,6 +1079,7 @@ static const char *get_typetag_name(typetag_t typetag)
case tt_tpo: return "type";
case tt_type_state: return "type state";
case tt_volatility: return "volatility";
case tt_visibility: return "visibility";
}
return "<UNKNOWN>";
}
......
......@@ -818,7 +818,8 @@ ir_entity *create_Block_entity(ir_node *block) {
glob = get_glob_type();
entity = new_entity(glob, id_unique("block_%u"), get_code_type());
set_entity_linkage(entity, IR_LINKAGE_LOCAL|IR_LINKAGE_CONSTANT);
set_entity_visibility(entity, ir_visibility_local);
set_entity_linkage(entity, IR_LINKAGE_CONSTANT);
nr = get_irp_next_label_nr();
set_entity_label(entity, nr);
set_entity_compiler_generated(entity, 1);
......
......@@ -1146,9 +1146,11 @@ static unsigned optimize_load(ir_node *load)
value = NULL;
/* check if we can determine the entity that will be loaded */
ent = find_constant_entity(ptr);
if (ent != NULL && !(get_entity_linkage(ent) & IR_LINKAGE_EXTERN)) {
/* a static allocation that is not external: there should be NO exception
* when loading even if we cannot replace the load itself. */
if (ent != NULL
&& get_entity_visibility(ent) != ir_visibility_external) {
/* a static allocation that is not external: there should be NO
* exception when loading even if we cannot replace the load itself.
*/
/* no exception, clear the info field as it might be checked later again */
if (info->projs[pn_Load_X_except]) {
......
......@@ -2050,7 +2050,7 @@ static int calc_inline_benefice(call_entry *entry, ir_graph *callee)
callee_env = get_irg_link(callee);
if (callee_env->n_callers == 1 &&
callee != current_ir_graph &&
(get_entity_linkage(ent) & IR_LINKAGE_LOCAL)) {
!entity_is_externally_visible(ent)) {
weight += 700;
}
......
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