Introduce IR_LINKAGE_NO_CODEGEN
authorMatthias Braun <matthias.braun@kit.edu>
Fri, 4 May 2012 12:30:03 +0000 (14:30 +0200)
committerMatthias Braun <matthias.braun@kit.edu>
Fri, 4 May 2012 12:45:27 +0000 (14:45 +0200)
This is used to implement C99 "inline"/GNU89 "extern inline" ie. an
entity which is externally defined but where we know an inlineable
definition anyway.

include/libfirm/typerep.h
ir/be/begnuas.c
ir/be/bemain.c
ir/opt/garbage_collect.c
ir/tr/entity.c

index 45db4bf..8174351 100644 (file)
@@ -154,7 +154,15 @@ typedef enum ir_linkage {
         * read/write behaviour to global variables or changing calling conventions
         * from cdecl to fastcall.
         */
-       IR_LINKAGE_HIDDEN_USER     = 1 << 4
+       IR_LINKAGE_HIDDEN_USER     = 1 << 4,
+       /**
+        * Do not generate code even if the entity has a graph attached. The graph
+        * is only used for inlining. Otherwise the entity is regarded as a
+        * declaration of an externally defined entity.
+        * This linkage flag can be used to implement C99 "inline" or GNU89
+        * "extern inline".
+        */
+       IR_LINKAGE_NO_CODEGEN      = 1 << 5,
 } ir_linkage;
 ENUM_BITSET(ir_linkage)
 
@@ -180,7 +188,8 @@ FIRM_API int entity_is_externally_visible(const ir_entity *entity);
 
 /**
  * Returns 1 if the entity has a definition (initializer) in the current
- * compilation unit
+ * compilation unit. Note that this function returns false if
+ * IR_LINKAGE_NO_CODEGEN is set even if a graph is present.
  */
 FIRM_API int entity_has_definition(const ir_entity *entity);
 
index 0904d64..9d33f2b 100644 (file)
@@ -1587,14 +1587,10 @@ static void emit_global(be_gas_decl_env_t *env, const ir_entity *entity)
        if (type == get_code_type())
                return;
 
-       /* we already emitted all methods. Except for the trampolines which
-        * the assembler/linker generates */
+       /* we already emitted all methods with graphs in other functions like
+        * be_gas_emit_function_prolog(). All others don't need to be emitted.
+        */
        if (is_Method_type(type) && section != GAS_SECTION_PIC_TRAMPOLINES) {
-               /* functions with graph are already emitted with
-                * be_gas_emit_function_prolog */
-               if (get_entity_irg(entity) == NULL) {
-                       emit_visibility(entity);
-               }
                return;
        }
 
index b4e9dfc..07c0a0f 100644 (file)
@@ -520,7 +520,9 @@ static void be_main_loop(FILE *file_handle, const char *cup_name)
 {
        static const char suffix[] = ".prof";
 
-       size_t        i, num_birgs;
+       size_t        i;
+       size_t        num_irgs;
+       size_t        num_birgs;
        be_main_env_t env;
        char          prof_filename[256];
        be_irg_t      *birgs;
@@ -543,15 +545,19 @@ static void be_main_loop(FILE *file_handle, const char *cup_name)
        arch_env = env.arch_env;
 
        /* we might need 1 birg more for instrumentation constructor */
-       num_birgs = get_irp_n_irgs();
-       birgs     = ALLOCAN(be_irg_t, num_birgs + 1);
+       num_irgs = get_irp_n_irgs();
+       birgs    = ALLOCAN(be_irg_t, num_irgs + 1);
 
        be_info_init();
 
        /* First: initialize all birgs */
-       for (i = 0; i < num_birgs; ++i) {
-               ir_graph *irg = get_irp_irg(i);
-               initialize_birg(&birgs[i], irg, &env);
+       num_birgs = 0;
+       for (i = 0; i < num_irgs; ++i) {
+               ir_graph  *irg    = get_irp_irg(i);
+               ir_entity *entity = get_irg_entity(irg);
+               if (get_entity_linkage(entity) & IR_LINKAGE_NO_CODEGEN)
+                       continue;
+               initialize_birg(&birgs[num_birgs++], irg, &env);
        }
        arch_env_handle_intrinsics(arch_env);
 
index 7fc81ec..08cc9a7 100644 (file)
@@ -123,7 +123,8 @@ static void visit_segment(ir_type *segment)
        for (i = 0; i < n_entities; ++i) {
                ir_entity *entity = get_compound_member(segment, i);
                if (get_entity_visibility(entity) != ir_visibility_external
-                               && !(get_entity_linkage(entity) & IR_LINKAGE_HIDDEN_USER))
+                               && !(get_entity_linkage(entity) & IR_LINKAGE_HIDDEN_USER)
+                               && !(get_entity_linkage(entity) & IR_LINKAGE_NO_CODEGEN))
                        continue;
 
                visit_entity(entity);
index e8e0de7..943ad6b 100644 (file)
@@ -1063,7 +1063,8 @@ int entity_is_externally_visible(const ir_entity *entity)
 int entity_has_definition(const ir_entity *entity)
 {
        if (is_method_entity(entity)) {
-               return get_entity_irg(entity) != NULL;
+               return get_entity_irg(entity) != NULL
+                   && (get_entity_linkage(entity) & IR_LINKAGE_NO_CODEGEN) == 0;
        } else {
                return entity->initializer != NULL
                    || entity_has_compound_ent_values(entity);