Commit 634d25a4 authored by Matthias Braun's avatar Matthias Braun
Browse files

Introduce IR_LINKAGE_NO_CODEGEN

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.
parent 07c77ebb
...@@ -154,7 +154,15 @@ typedef enum ir_linkage { ...@@ -154,7 +154,15 @@ typedef enum ir_linkage {
* read/write behaviour to global variables or changing calling conventions * read/write behaviour to global variables or changing calling conventions
* from cdecl to fastcall. * 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; } ir_linkage;
ENUM_BITSET(ir_linkage) ENUM_BITSET(ir_linkage)
...@@ -180,7 +188,8 @@ FIRM_API int entity_is_externally_visible(const ir_entity *entity); ...@@ -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 * 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); FIRM_API int entity_has_definition(const ir_entity *entity);
......
...@@ -1587,14 +1587,10 @@ static void emit_global(be_gas_decl_env_t *env, const ir_entity *entity) ...@@ -1587,14 +1587,10 @@ static void emit_global(be_gas_decl_env_t *env, const ir_entity *entity)
if (type == get_code_type()) if (type == get_code_type())
return; return;
/* we already emitted all methods. Except for the trampolines which /* we already emitted all methods with graphs in other functions like
* the assembler/linker generates */ * be_gas_emit_function_prolog(). All others don't need to be emitted.
*/
if (is_Method_type(type) && section != GAS_SECTION_PIC_TRAMPOLINES) { 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; return;
} }
......
...@@ -520,7 +520,9 @@ static void be_main_loop(FILE *file_handle, const char *cup_name) ...@@ -520,7 +520,9 @@ static void be_main_loop(FILE *file_handle, const char *cup_name)
{ {
static const char suffix[] = ".prof"; 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; be_main_env_t env;
char prof_filename[256]; char prof_filename[256];
be_irg_t *birgs; be_irg_t *birgs;
...@@ -543,15 +545,19 @@ static void be_main_loop(FILE *file_handle, const char *cup_name) ...@@ -543,15 +545,19 @@ static void be_main_loop(FILE *file_handle, const char *cup_name)
arch_env = env.arch_env; arch_env = env.arch_env;
/* we might need 1 birg more for instrumentation constructor */ /* we might need 1 birg more for instrumentation constructor */
num_birgs = get_irp_n_irgs(); num_irgs = get_irp_n_irgs();
birgs = ALLOCAN(be_irg_t, num_birgs + 1); birgs = ALLOCAN(be_irg_t, num_irgs + 1);
be_info_init(); be_info_init();
/* First: initialize all birgs */ /* First: initialize all birgs */
for (i = 0; i < num_birgs; ++i) { num_birgs = 0;
ir_graph *irg = get_irp_irg(i); for (i = 0; i < num_irgs; ++i) {
initialize_birg(&birgs[i], irg, &env); 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); arch_env_handle_intrinsics(arch_env);
......
...@@ -123,7 +123,8 @@ static void visit_segment(ir_type *segment) ...@@ -123,7 +123,8 @@ static void visit_segment(ir_type *segment)
for (i = 0; i < n_entities; ++i) { for (i = 0; i < n_entities; ++i) {
ir_entity *entity = get_compound_member(segment, i); ir_entity *entity = get_compound_member(segment, i);
if (get_entity_visibility(entity) != ir_visibility_external 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; continue;
visit_entity(entity); visit_entity(entity);
......
...@@ -1063,7 +1063,8 @@ int entity_is_externally_visible(const ir_entity *entity) ...@@ -1063,7 +1063,8 @@ int entity_is_externally_visible(const ir_entity *entity)
int entity_has_definition(const ir_entity *entity) int entity_has_definition(const ir_entity *entity)
{ {
if (is_method_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 { } else {
return entity->initializer != NULL return entity->initializer != NULL
|| entity_has_compound_ent_values(entity); || entity_has_compound_ent_values(entity);
......
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