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 {
* 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);
......
......@@ -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;
}
......
......@@ -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) {
num_birgs = 0;
for (i = 0; i < num_irgs; ++i) {
ir_graph *irg = get_irp_irg(i);
initialize_birg(&birgs[i], irg, &env);
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);
......
......@@ -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);
......
......@@ -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);
......
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