Commit 80d22a2b authored by Matthias Braun's avatar Matthias Braun
Browse files

Rework Block labels: They are entities now so we don't need a special symconst type for them

[r26080]
parent 25969fba
...@@ -160,9 +160,8 @@ typedef enum { ...@@ -160,9 +160,8 @@ typedef enum {
symconst_symbol is entity *. */ symconst_symbol is entity *. */
symconst_ofs_ent, /**< The SymConst is the offset of its entity in the entities symconst_ofs_ent, /**< The SymConst is the offset of its entity in the entities
owner type. */ owner type. */
symconst_enum_const, /**< The SymConst is a enumeration constant of an symconst_enum_const /**< The SymConst is a enumeration constant of an
enumeration type. */ enumeration type. */
symconst_label /**< The SymConst is a label address. */
} symconst_kind; } symconst_kind;
/** SymConst attribute. /** SymConst attribute.
...@@ -174,7 +173,6 @@ typedef union symconst_symbol { ...@@ -174,7 +173,6 @@ typedef union symconst_symbol {
ident *ident_p; /**< The ident of a SymConst. */ ident *ident_p; /**< The ident of a SymConst. */
ir_entity *entity_p; /**< The entity of a SymConst. */ ir_entity *entity_p; /**< The entity of a SymConst. */
ir_enum_const *enum_p; /**< The enumeration constant of a SymConst. */ ir_enum_const *enum_p; /**< The enumeration constant of a SymConst. */
ir_label_t label; /**< The label of a SymConst. */
} symconst_symbol; } symconst_symbol;
/** /**
......
...@@ -419,12 +419,14 @@ void set_Block_MacroBlock(ir_node *block, ir_node *mbh); ...@@ -419,12 +419,14 @@ void set_Block_MacroBlock(ir_node *block, ir_node *mbh);
ir_node *get_irn_MacroBlock(const ir_node *n); ir_node *get_irn_MacroBlock(const ir_node *n);
/** Returns the ir_graph this Block belongs to. */ /** Returns the ir_graph this Block belongs to. */
ir_graph *get_Block_irg(const ir_node *block); ir_graph *get_Block_irg(const ir_node *block);
/** Returns non-zero if the block has an assigned label. */ /** Returns non-zero if the block has an entity assigned */
int has_Block_label(const ir_node *block); int has_Block_entity(const ir_node *block);
/** Returns the label of a Block. */ /** Returns the entity for a Block */
ir_label_t get_Block_label(const ir_node *block); ir_entity *get_Block_entity(const ir_node *block);
/** Sets a label to a block. */ /** Returns the entity for a Block (creating it if necessary) */
void set_Block_label(ir_node *block, ir_label_t label); ir_entity *create_Block_entity(ir_node *block);
/** Set a new entity for a block */
void set_Block_entity(ir_node *block, ir_entity *entity);
/** Gets the head of the Phi list for this block. */ /** Gets the head of the Phi list for this block. */
ir_node *get_Block_phis(const ir_node *block); ir_node *get_Block_phis(const ir_node *block);
/** Sets the head of the Phi list for this block. */ /** Sets the head of the Phi list for this block. */
...@@ -552,9 +554,6 @@ void set_Const_type(ir_node *node, ir_type *tp); ...@@ -552,9 +554,6 @@ void set_Const_type(ir_node *node, ir_type *tp);
/** Returns non-zero if s symconst kind has an enum_const attribute */ /** Returns non-zero if s symconst kind has an enum_const attribute */
#define SYMCONST_HAS_ENUM(kind) ((kind) == symconst_enum_const) #define SYMCONST_HAS_ENUM(kind) ((kind) == symconst_enum_const)
/** Returns non-zero if s symconst kind has a label attribute */
#define SYMCONST_HAS_LABEL(kind) ((kind) == symconst_label)
/** Get the kind of the SymConst. */ /** Get the kind of the SymConst. */
symconst_kind get_SymConst_kind(const ir_node *node); symconst_kind get_SymConst_kind(const ir_node *node);
/** Set the kind of the SymConst. */ /** Set the kind of the SymConst. */
...@@ -583,11 +582,6 @@ union symconst_symbol get_SymConst_symbol(const ir_node *node); ...@@ -583,11 +582,6 @@ union symconst_symbol get_SymConst_symbol(const ir_node *node);
void set_SymConst_symbol(ir_node *node, void set_SymConst_symbol(ir_node *node,
union symconst_symbol sym); union symconst_symbol sym);
/** Only to access SymConst of kind symconst_label. Else assertion: */
ir_label_t get_SymConst_label(const ir_node *node);
void set_SymConst_label(ir_node *node, ir_label_t label);
/** Access the type of the value represented by the SymConst. /** Access the type of the value represented by the SymConst.
* *
* Example: primitive type int for SymConst size. */ * Example: primitive type int for SymConst size. */
......
...@@ -360,6 +360,11 @@ int is_entity_final(const ir_entity *ent); ...@@ -360,6 +360,11 @@ int is_entity_final(const ir_entity *ent);
/** Sets/resets the final flag of an entity. */ /** Sets/resets the final flag of an entity. */
void set_entity_final(ir_entity *ent, int final); void set_entity_final(ir_entity *ent, int final);
/** Set label number of an entity with code type */
void set_entity_label(ir_entity *ent, ir_label_t label);
/** Return label number of an entity with code type */
ir_label_t get_entity_label(const ir_entity *ent);
/** Checks if an entity is compiler generated. */ /** Checks if an entity is compiler generated. */
int is_entity_compiler_generated(const ir_entity *ent); int is_entity_compiler_generated(const ir_entity *ent);
...@@ -767,6 +772,7 @@ typedef enum { ...@@ -767,6 +772,7 @@ typedef enum {
tpo_pointer, /**< A pointer type. */ tpo_pointer, /**< A pointer type. */
tpo_primitive, /**< A primitive type. */ tpo_primitive, /**< A primitive type. */
tpo_id, /**< Special Id tag used for type replacement. */ tpo_id, /**< Special Id tag used for type replacement. */
tpo_code, /**< a piece of code (a basic block) */
tpo_none, /**< Special type for the None type. */ tpo_none, /**< Special type for the None type. */
tpo_unknown, /**< Special code for the Unknown type. */ tpo_unknown, /**< Special code for the Unknown type. */
tpo_max /* not a type opcode */ tpo_max /* not a type opcode */
...@@ -915,6 +921,12 @@ const tp_op *get_tpop_primitive(void); ...@@ -915,6 +921,12 @@ const tp_op *get_tpop_primitive(void);
extern const tp_op *type_id; extern const tp_op *type_id;
const tp_op *get_tpop_id(void); const tp_op *get_tpop_id(void);
/**
* The code type is used to mark pieces of code (basic blocks)
*/
extern const tp_op *tpop_code;
const tp_op *get_tpop_code_type(void);
/** /**
* This type opcode is an auxiliary opcode dedicated to support type analyses. * This type opcode is an auxiliary opcode dedicated to support type analyses.
* *
...@@ -2295,8 +2307,13 @@ void set_primitive_base_type(ir_type *tp, ir_type *base_tp); ...@@ -2295,8 +2307,13 @@ void set_primitive_base_type(ir_type *tp, ir_type *base_tp);
/** A variable that contains the only none type. */ /** A variable that contains the only none type. */
extern ir_type *firm_none_type; extern ir_type *firm_none_type;
/** A variable that contains the only code type. */
extern ir_type *firm_code_type;
/** Returns the none type. */ /** Returns the none type. */
ir_type *get_none_type(void); ir_type *get_none_type(void);
/** Returns the code type. */
ir_type *get_code_type(void);
/** /**
* @page unknown_type The Unknown type * @page unknown_type The Unknown type
...@@ -2368,6 +2385,11 @@ int get_compound_member_index(const ir_type *tp, ir_entity *member); ...@@ -2368,6 +2385,11 @@ int get_compound_member_index(const ir_type *tp, ir_entity *member);
*/ */
int is_compound_type(const ir_type *tp); int is_compound_type(const ir_type *tp);
/**
* Checks wether a type is a code type.
*/
int is_code_type(const ir_type *tp);
/** /**
* Checks, whether a type is a frame type. * Checks, whether a type is a frame type.
*/ */
......
...@@ -330,9 +330,9 @@ static ir_node *get_cfop_target_block(const ir_node *irn) { ...@@ -330,9 +330,9 @@ static ir_node *get_cfop_target_block(const ir_node *irn) {
* Emits a block label for the given block. * Emits a block label for the given block.
*/ */
static void arm_emit_block_name(const ir_node *block) { static void arm_emit_block_name(const ir_node *block) {
if (has_Block_label(block)) { if (has_Block_entity(block)) {
be_emit_string(be_gas_block_label_prefix()); ir_entity *entity = get_Block_entity(block);
be_emit_irprintf("%lu", get_Block_label(block)); be_gas_emit_entity(entity);
} else { } else {
be_emit_cstring(BLOCK_PREFIX); be_emit_cstring(BLOCK_PREFIX);
be_emit_irprintf("%d", get_irn_node_nr(block)); be_emit_irprintf("%d", get_irn_node_nr(block));
......
...@@ -2210,8 +2210,7 @@ static ir_entity *get_pic_symbol(be_main_env_t *env, ir_entity *entity) ...@@ -2210,8 +2210,7 @@ static ir_entity *get_pic_symbol(be_main_env_t *env, ir_entity *entity)
*/ */
static int can_address_relative(ir_entity *entity) static int can_address_relative(ir_entity *entity)
{ {
return get_entity_variability(entity) == variability_initialized return get_entity_visibility(entity) != visibility_external_allocated;
&& get_entity_visibility(entity) != visibility_external_allocated;
} }
/** patches SymConsts to work in position independent code */ /** patches SymConsts to work in position independent code */
......
...@@ -41,8 +41,6 @@ extern struct obstack emit_obst; ...@@ -41,8 +41,6 @@ extern struct obstack emit_obst;
/** /**
* Emit a character to the (assembler) output. * Emit a character to the (assembler) output.
*
* @param env the emitter environment
*/ */
static inline void be_emit_char(char c) static inline void be_emit_char(char c)
{ {
...@@ -52,7 +50,6 @@ static inline void be_emit_char(char c) ...@@ -52,7 +50,6 @@ static inline void be_emit_char(char c)
/** /**
* Emit a string to the (assembler) output. * Emit a string to the (assembler) output.
* *
* @param env the emitter environment
* @param str the string * @param str the string
* @param l the length of the given string * @param l the length of the given string
*/ */
...@@ -64,7 +61,6 @@ static inline void be_emit_string_len(const char *str, size_t l) ...@@ -64,7 +61,6 @@ static inline void be_emit_string_len(const char *str, size_t l)
/** /**
* Emit a null-terminated string to the (assembler) output. * Emit a null-terminated string to the (assembler) output.
* *
* @param env the emitter environment
* @param str the null-terminated string * @param str the null-terminated string
*/ */
static inline void be_emit_string(const char *str) static inline void be_emit_string(const char *str)
...@@ -76,7 +72,6 @@ static inline void be_emit_string(const char *str) ...@@ -76,7 +72,6 @@ static inline void be_emit_string(const char *str)
/** /**
* Emit a C string-constant to the (assembler) output. * Emit a C string-constant to the (assembler) output.
* *
* @param env the emitter environment
* @param str the null-terminated string constant * @param str the null-terminated string constant
*/ */
#define be_emit_cstring(str) \ #define be_emit_cstring(str) \
...@@ -85,22 +80,18 @@ static inline void be_emit_string(const char *str) ...@@ -85,22 +80,18 @@ static inline void be_emit_string(const char *str)
/** /**
* Initializes an emitter environment. * Initializes an emitter environment.
* *
* @param env the (uninitialized) emitter environment
* @param F a file handle where the emitted file is written to. * @param F a file handle where the emitted file is written to.
*/ */
void be_emit_init(FILE *F); void be_emit_init(FILE *F);
/** /**
* Destroys the given emitter environment. * Destroys the given emitter environment.
*
* @param env the emitter environment
*/ */
void be_emit_exit(void); void be_emit_exit(void);
/** /**
* Emit an ident to the (assembler) output. * Emit an ident to the (assembler) output.
* *
* @param env the emitter environment
* @param id the ident to be emitted * @param id the ident to be emitted
*/ */
void be_emit_ident(ident *id); void be_emit_ident(ident *id);
...@@ -108,7 +99,6 @@ void be_emit_ident(ident *id); ...@@ -108,7 +99,6 @@ void be_emit_ident(ident *id);
/** /**
* Emit a firm tarval. * Emit a firm tarval.
* *
* @param env the emitter environment
* @param tv the tarval to be emitted * @param tv the tarval to be emitted
*/ */
void be_emit_tarval(tarval *tv); void be_emit_tarval(tarval *tv);
...@@ -116,7 +106,6 @@ void be_emit_tarval(tarval *tv); ...@@ -116,7 +106,6 @@ void be_emit_tarval(tarval *tv);
/** /**
* Emit the output of an ir_printf. * Emit the output of an ir_printf.
* *
* @param env the emitter environment
* @param fmt the ir_printf format * @param fmt the ir_printf format
*/ */
void be_emit_irprintf(const char *fmt, ...); void be_emit_irprintf(const char *fmt, ...);
...@@ -124,15 +113,12 @@ void be_emit_irprintf(const char *fmt, ...); ...@@ -124,15 +113,12 @@ void be_emit_irprintf(const char *fmt, ...);
/** /**
* Emit the output of an ir_vprintf. * Emit the output of an ir_vprintf.
* *
* @param env the emitter environment
* @param fmt the ir_printf format * @param fmt the ir_printf format
*/ */
void be_emit_irvprintf(const char *fmt, va_list args); void be_emit_irvprintf(const char *fmt, va_list args);
/** /**
* Flush the line in the current line buffer to the emitter file. * Flush the line in the current line buffer to the emitter file.
*
* @param env the emitter environment
*/ */
void be_emit_write_line(void); void be_emit_write_line(void);
...@@ -140,15 +126,12 @@ void be_emit_write_line(void); ...@@ -140,15 +126,12 @@ void be_emit_write_line(void);
* Flush the line in the current line buffer to the emitter file and * Flush the line in the current line buffer to the emitter file and
* appends a gas-style comment with the node number and writes the line * appends a gas-style comment with the node number and writes the line
* *
* @param env the emitter environment
* @param node the node to get the debug info from * @param node the node to get the debug info from
*/ */
void be_emit_finish_line_gas(const ir_node *node); void be_emit_finish_line_gas(const ir_node *node);
/** /**
* Emit spaces until the comment position is reached. * Emit spaces until the comment position is reached.
*
* @param env the emitter environment
*/ */
void be_emit_pad_comment(void); void be_emit_pad_comment(void);
......
...@@ -293,11 +293,15 @@ const char *be_gas_insn_label_prefix(void) { ...@@ -293,11 +293,15 @@ const char *be_gas_insn_label_prefix(void) {
return ".LE"; return ".LE";
} }
/** void be_gas_emit_entity(ir_entity *entity)
* Dump a label. {
*/ if (entity->type == firm_code_type) {
static void dump_label(ir_label_t label) { ir_label_t label = get_entity_label(entity);
be_emit_irprintf("%s%lu", be_gas_block_label_prefix(), label); be_emit_string(be_gas_block_label_prefix());
be_emit_irprintf("%lu", label);
} else {
be_emit_ident(get_entity_ld_ident(entity));
}
} }
/** /**
...@@ -339,9 +343,6 @@ static tarval *get_atomic_init_tv(ir_node *init) ...@@ -339,9 +343,6 @@ static tarval *get_atomic_init_tv(ir_node *init)
case symconst_enum_const: case symconst_enum_const:
return get_enumeration_value(get_SymConst_enum(init)); return get_enumeration_value(get_SymConst_enum(init));
case symconst_label:
return NULL;
default: default:
return NULL; return NULL;
} }
...@@ -363,7 +364,6 @@ static void do_dump_atomic_init(be_gas_decl_env_t *env, ir_node *init) ...@@ -363,7 +364,6 @@ static void do_dump_atomic_init(be_gas_decl_env_t *env, ir_node *init)
ir_mode *mode = get_irn_mode(init); ir_mode *mode = get_irn_mode(init);
int bytes = get_mode_size_bytes(mode); int bytes = get_mode_size_bytes(mode);
tarval *tv; tarval *tv;
ir_label_t label;
ir_entity *ent; ir_entity *ent;
init = skip_Id(init); init = skip_Id(init);
...@@ -396,17 +396,11 @@ static void do_dump_atomic_init(be_gas_decl_env_t *env, ir_node *init) ...@@ -396,17 +396,11 @@ static void do_dump_atomic_init(be_gas_decl_env_t *env, ir_node *init)
waitq_put(env->worklist, ent); waitq_put(env->worklist, ent);
set_entity_backend_marked(ent, 1); set_entity_backend_marked(ent, 1);
} }
be_emit_ident(get_entity_ld_ident(ent)); be_gas_emit_entity(ent);
break; break;
case symconst_ofs_ent: case symconst_ofs_ent:
ent = get_SymConst_entity(init); ent = get_SymConst_entity(init);
#if 0 /* not needed, is it? */
if (!is_entity_backend_marked(ent)) {
waitq_put(env->worklist, ent);
set_entity_backend_marked(ent, 1);
}
#endif
be_emit_irprintf("%d", get_entity_offset(ent)); be_emit_irprintf("%d", get_entity_offset(ent));
break; break;
...@@ -423,11 +417,6 @@ static void do_dump_atomic_init(be_gas_decl_env_t *env, ir_node *init) ...@@ -423,11 +417,6 @@ static void do_dump_atomic_init(be_gas_decl_env_t *env, ir_node *init)
dump_arith_tarval(tv, bytes); dump_arith_tarval(tv, bytes);
break; break;
case symconst_label:
label = get_SymConst_label(init);
dump_label(label);
break;
default: default:
assert(!"dump_atomic_init(): don't know how to init from this SymConst"); assert(!"dump_atomic_init(): don't know how to init from this SymConst");
} }
......
...@@ -71,6 +71,11 @@ extern be_gas_flavour_t be_gas_flavour; ...@@ -71,6 +71,11 @@ extern be_gas_flavour_t be_gas_flavour;
void be_gas_emit_decls(const be_main_env_t *main_env, void be_gas_emit_decls(const be_main_env_t *main_env,
int only_emit_marked_entities); int only_emit_marked_entities);
/**
* Emit an entity (the entities name or a block label)
*/
void be_gas_emit_entity(ir_entity *entity);
/** /**
* Switch the current output section to the given out. * Switch the current output section to the given out.
* *
......
...@@ -184,7 +184,7 @@ static void remove_empty_block(ir_node *block) ...@@ -184,7 +184,7 @@ static void remove_empty_block(ir_node *block)
assert(succ_block == NULL); assert(succ_block == NULL);
succ_block = get_edge_src_irn(edge); succ_block = get_edge_src_irn(edge);
if (has_Block_label(succ_block) && has_Block_label(block)) { if (has_Block_entity(succ_block) && has_Block_entity(block)) {
/* /*
* Currently we can add only one label for a block. * Currently we can add only one label for a block.
* Therefore we cannot combine them if both block already have one. * Therefore we cannot combine them if both block already have one.
...@@ -195,10 +195,10 @@ static void remove_empty_block(ir_node *block) ...@@ -195,10 +195,10 @@ static void remove_empty_block(ir_node *block)
set_irn_n(succ_block, pos, pred); set_irn_n(succ_block, pos, pred);
} }
if (has_Block_label(block)) { if (has_Block_entity(block)) {
/* move the label to the successor block */ /* move the label to the successor block */
ir_label_t label = get_Block_label(block); ir_entity *entity = get_Block_entity(block);
set_Block_label(succ_block, label); set_Block_entity(succ_block, entity);
} }
/* there can be some non-scheduled Pin nodes left in the block, move them /* there can be some non-scheduled Pin nodes left in the block, move them
......
...@@ -357,9 +357,11 @@ static void assign_reg(const ir_node *block, ir_node *node) ...@@ -357,9 +357,11 @@ static void assign_reg(const ir_node *block, ir_node *node)
/* give should_be_same boni */ /* give should_be_same boni */
info = get_allocation_info(node); info = get_allocation_info(node);
req = arch_get_register_req_out(node); req = arch_get_register_req_out(node);
ir_node *in_node = skip_Proj(node);
if (req->type & arch_register_req_type_should_be_same) { if (req->type & arch_register_req_type_should_be_same) {
float weight = get_block_execfreq(execfreqs, block); float weight = get_block_execfreq(execfreqs, block);
int arity = get_irn_arity(node); int arity = get_irn_arity(in_node);
int i; int i;
assert(arity <= (int) sizeof(req->other_same) * 8); assert(arity <= (int) sizeof(req->other_same) * 8);
...@@ -370,7 +372,7 @@ static void assign_reg(const ir_node *block, ir_node *node) ...@@ -370,7 +372,7 @@ static void assign_reg(const ir_node *block, ir_node *node)
if (!rbitset_is_set(&req->other_same, i)) if (!rbitset_is_set(&req->other_same, i))
continue; continue;
in = get_irn_n(node, i); in = get_irn_n(in_node, i);
reg = arch_get_irn_register(in); reg = arch_get_irn_register(in);
assert(reg != NULL); assert(reg != NULL);
r = arch_register_get_index(reg); r = arch_register_get_index(reg);
......
...@@ -102,6 +102,9 @@ static int block_needs_label(const ir_node *block) ...@@ -102,6 +102,9 @@ static int block_needs_label(const ir_node *block)
int need_label = 1; int need_label = 1;
int n_cfgpreds = get_Block_n_cfgpreds(block); int n_cfgpreds = get_Block_n_cfgpreds(block);
if (has_Block_entity(block))
return 1;
if (n_cfgpreds == 0) { if (n_cfgpreds == 0) {
need_label = 0; need_label = 0;
} else if (n_cfgpreds == 1) { } else if (n_cfgpreds == 1) {
...@@ -277,11 +280,8 @@ void ia32_emit_source_register(const ir_node *node, int pos) ...@@ -277,11 +280,8 @@ void ia32_emit_source_register(const ir_node *node, int pos)
static void ia32_emit_entity(ir_entity *entity, int no_pic_adjust) static void ia32_emit_entity(ir_entity *entity, int no_pic_adjust)
{ {
ident *id;
set_entity_backend_marked(entity, 1); set_entity_backend_marked(entity, 1);
id = get_entity_ld_ident(entity); be_gas_emit_entity(entity);
be_emit_ident(id);
if (get_entity_owner(entity) == get_tls_type()) { if (get_entity_owner(entity) == get_tls_type()) {
if (get_entity_visibility(entity) == visibility_external_allocated) { if (get_entity_visibility(entity) == visibility_external_allocated) {
...@@ -497,9 +497,9 @@ static ir_node *get_cfop_target_block(const ir_node *irn) ...@@ -497,9 +497,9 @@ static ir_node *get_cfop_target_block(const ir_node *irn)
*/ */
static void ia32_emit_block_name(const ir_node *block) static void ia32_emit_block_name(const ir_node *block)
{ {
if (has_Block_label(block)) { if (has_Block_entity(block)) {
be_emit_string(be_gas_block_label_prefix()); ir_entity *entity = get_Block_entity(block);
be_emit_irprintf("%lu", get_Block_label(block)); be_gas_emit_entity(entity);
} else { } else {
be_emit_cstring(BLOCK_PREFIX); be_emit_cstring(BLOCK_PREFIX);
be_emit_irprintf("%ld", get_irn_node_nr(block)); be_emit_irprintf("%ld", get_irn_node_nr(block));
...@@ -2058,7 +2058,7 @@ static void ia32_emit_block_header(ir_node *block) ...@@ -2058,7 +2058,7 @@ static void ia32_emit_block_header(ir_node *block)
} }
} }
if (need_label || has_Block_label(block)) { if (need_label) {
ia32_emit_block_name(block); ia32_emit_block_name(block);
be_emit_char(':'); be_emit_char(':');
......
...@@ -423,9 +423,9 @@ const char* mips_get_block_label(const ir_node* block) ...@@ -423,9 +423,9 @@ const char* mips_get_block_label(const ir_node* block)
*/ */
static void mips_emit_block_label(const ir_node *block) static void mips_emit_block_label(const ir_node *block)
{ {
if (has_Block_label(block)) { if (has_Block_entity(block)) {
be_emit_string(be_gas_block_label_prefix()); ir_entity *entity = get_Block_entity(block);
be_emit_irprintf("%lu", get_Block_label(block)); be_gas_emit_entity(entity);
} else { } else {
be_emit_cstring(BLOCK_PREFIX); be_emit_cstring(BLOCK_PREFIX);
be_emit_irprintf("%ld", get_irn_node_nr(block)); be_emit_irprintf("%ld", get_irn_node_nr(block));
......