- representing the 3-state visibility (default,local,external) with 2 bits was
authorMatthias Braun <matze@braunis.de>
Thu, 4 Feb 2010 13:27:45 +0000 (13:27 +0000)
committerMatthias Braun <matze@braunis.de>
Thu, 4 Feb 2010 13:27:45 +0000 (13:27 +0000)
  clumsy. Bring back get_entity_visibility and set_entity_visibility

[r27039]

24 files changed:
include/libfirm/typerep.h
ir/ana/cgana.c
ir/ana/irmemory.c
ir/ana/rta.c
ir/be/arm/bearch_arm.c
ir/be/beabi.c
ir/be/begnuas.c
ir/be/bestabs.c
ir/be/ia32/bearch_ia32.c
ir/be/ia32/ia32_common_transform.c
ir/be/ia32/ia32_emitter.c
ir/be/ia32/ia32_fpu.c
ir/be/ia32/ia32_intrinsics.c
ir/be/ia32/ia32_transform.c
ir/be/ppc32/ppc32_transform.c
ir/ir/irdumptxt.c
ir/ir/irio.c
ir/ir/irnode.c
ir/opt/ldstopt.c
ir/opt/opt_inline.c
ir/opt/opt_ldst.c
ir/opt/proc_cloning.c
ir/tr/entity.c
ir/tr/type.c

index 82c7198..bf7d74a 100644 (file)
  * @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 */
index c63da59..2fc3773 100644 (file)
@@ -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);
                }
index 3f05909..8ae19aa 100644 (file)
@@ -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);
 
index 48f54af..b16b84d 100644 (file)
@@ -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);
                }
index 9e14232..217a88d 100644 (file)
@@ -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;
index e24bedf..75e43ff 100644 (file)
@@ -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 */
index 483afe2..b4bffed 100644 (file)
@@ -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);
index 6b5fe3c..a51fdfd 100644 (file)
@@ -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';
 
index 86cdcc1..1e57d19 100644 (file)
@@ -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);
        }
index 44f69e0..0c41013 100644 (file)
@@ -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 */
index 4716f55..8d0399c 100644 (file)
@@ -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");
index 330267a..1522bf8 100644 (file)
@@ -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);
index 5835636..b203c5a 100644 (file)
@@ -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"));
                }
        }
index 615a69c..57809b2 100644 (file)
@@ -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);
 
index 789988f..9fbad77 100644 (file)
@@ -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 */
index 2e1aa4d..afd542c 100644 (file)
@@ -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)
index 1a9893c..cdec4f2 100644 (file)
@@ -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>";
 }
index 7f320c3..c61f32a 100644 (file)
@@ -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);
index 4c63e0c..be8abb7 100644 (file)
@@ -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]) {
index c868be6..eb01365 100644 (file)
@@ -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;
        }
 
index e9dce0f..3102b6b 100644 (file)
@@ -1026,7 +1026,7 @@ static void update_Load_memop(memop_t *m) {
        /* 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)) {
+       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. */
                ir_node *value = NULL;
index ca1d034..2f80cbc 100644 (file)
@@ -417,7 +417,7 @@ static ir_entity *clone_method(quadruple_t *q)
        new_entity  = copy_entity_name(q->ent, clone_ident);
 
        /* a cloned entity is always local */
-       add_entity_linkage(new_entity, IR_LINKAGE_LOCAL);
+       set_entity_visibility(new_entity, ir_visibility_local);
 
        /* set a ld name here: Should we mangle this ? */
        set_entity_ld_ident(new_entity, get_entity_ident(new_entity));
index 8d92a07..f4f29a1 100644 (file)
@@ -113,6 +113,7 @@ new_rd_entity(dbg_info *db, ir_type *owner, ident *name, ir_type *type)
        res->aligned              = align_is_aligned;
        res->usage                = ir_usage_unknown;
        res->compiler_gen         = 0;
+       res->visibility           = ir_visibility_default;
        res->offset               = -1;
        res->offset_bit_remainder = 0;
        res->alignment            = 0;
@@ -433,15 +434,30 @@ ir_label_t get_entity_label(const ir_entity *ent)
        return ent->attr.code_attr.label;
 }
 
-static void verify_linkage(ir_entity *entity)
+static void verify_visibility(const ir_entity *entity)
 {
-       ir_linkage linkage = entity->linkage;
-       /* local and extern are mutually exclusive */
-       (void) linkage;
-       assert(! ((linkage & IR_LINKAGE_EXTERN) && (linkage & IR_LINKAGE_LOCAL)));
-       if (!is_method_entity(entity) && (linkage & IR_LINKAGE_EXTERN)) {
+       if (get_entity_visibility(entity) == ir_visibility_external
+                       && !is_method_entity(entity)) {
                assert(!entity_has_definition(entity));
        }
+}
+
+void set_entity_visibility(ir_entity *entity, ir_visibility visibility)
+{
+       entity->visibility = visibility;
+       verify_visibility(entity);
+}
+
+ir_visibility get_entity_visibility(const ir_entity *entity)
+{
+       return entity->visibility;
+}
+
+static void verify_linkage(const ir_entity *entity)
+{
+       ir_linkage linkage = entity->linkage;
+       /* weak symbols can't really be constant, since someone else can always
+        * exchange them */
        assert(! ((linkage & IR_LINKAGE_CONSTANT) && (linkage & IR_LINKAGE_WEAK)));
 }
 
@@ -1040,7 +1056,8 @@ void (set_entity_dbg_info)(ir_entity *ent, dbg_info *db)
 
 int entity_is_externally_visible(const ir_entity *entity)
 {
-       return (get_entity_linkage(entity) & IR_LINKAGE_LOCAL) == 0;
+       return get_entity_visibility(entity) != ir_visibility_local
+               || (get_entity_linkage(entity) & IR_LINKAGE_HIDDEN_USER);
 }
 
 int entity_has_definition(const ir_entity *entity)
@@ -1058,7 +1075,7 @@ void firm_init_entity(void)
        assert(!unknown_entity && "Call firm_init_entity() only once!");
 
        unknown_entity = new_rd_entity(NULL, firm_unknown_type, new_id_from_str(UNKNOWN_ENTITY_NAME), firm_unknown_type);
-       set_entity_linkage(unknown_entity, IR_LINKAGE_EXTERN);
+       set_entity_visibility(unknown_entity, ir_visibility_external);
 
        set_entity_ld_ident(unknown_entity, get_entity_ident(unknown_entity));
 
index d9c5126..ab81082 100644 (file)
@@ -144,7 +144,7 @@ ir_type *new_type(const tp_op *type_op, ir_mode *mode, type_dbg_info *db)
        res->kind       = k_type;
        res->type_op    = type_op;
        res->mode       = mode;
-       res->visibility = visibility_external_allocated;
+       res->visibility = ir_visibility_external;
        res->flags      = tf_none;
        res->size       = 0;
        res->align      = 0;