Commit eb294bb1 authored by Christoph Mallon's avatar Christoph Mallon
Browse files

Split EntConst into Address and Offset.

parent 2327654f
......@@ -48,8 +48,8 @@
* and Craig Chambers.
*
* Performs some optimizations possible by the analysed information:
* - Replace (Sel-method(Alloc)) by EntConst-entity.
* - Replaces Sel-method by EntConst-entity if the method is never overwritten.
* - Replace (Sel-method(Alloc)) by Address.
* - Replaces Sel-method by Address if the method is never overwritten.
*/
FIRM_API size_t cgana(ir_entity ***free_methods);
......
......@@ -263,19 +263,6 @@ typedef enum mtp_additional_properties {
} mtp_additional_properties;
ENUM_BITSET(mtp_additional_properties)
/**
* @ingroup EntConst
* This enum names the different kinds of symbolic Constants represented by
* EntConst.
*/
typedef enum entconst_kind {
entconst_addr, /**< The EntConst is a symbolic pointer to be filled in
by the linker. The pointer is represented by an
entity. */
entconst_ofs, /**< The EntConst is the offset of its entity in the
entities owner type. */
} entconst_kind;
/**
* @ingroup TypeConst
* This enum names the different kinds of symbolic Constants represented by
......
......@@ -332,18 +332,6 @@ FIRM_API int is_Const_all_one(const ir_node *node);
/** @} */
/**
* @addtogroup EntConst
* @{
*/
/**
* Returns true if node is a EntConst node with kind entconst_addr.
*/
FIRM_API int is_EntConst_addr(const ir_node *node);
/** @} */
/**
* @addtogroup Call
* @{
......@@ -514,7 +502,7 @@ FIRM_API void copy_node_attr(ir_graph *irg, const ir_node *old_node, ir_node *ne
* or NULL.*/
FIRM_API ir_type *get_irn_type_attr(ir_node *n);
/** Returns the entity attribute of a node n (EntConst, Sel) or NULL. */
/** Returns the entity attribute of a node n (Address, Offset, Sel) or NULL. */
FIRM_API ir_entity *get_irn_entity_attr(ir_node *n);
/** Returns non-zero for constant-like nodes. */
......
......@@ -571,7 +571,7 @@ FIRM_API int value_not_zero(const ir_node *n, const ir_node **confirm);
*
* - If option sel_based_null_check_elim is enabled, all
* Sel nodes can be skipped.
* - A EntConst is NEVER a NULL pointer
* - A Address is NEVER a NULL pointer
* - A Const != NULL is NEVER a NULL pointer
* - Confirms are evaluated
*
......
......@@ -92,7 +92,7 @@ FIRM_API void lower_switch(ir_graph *irg, unsigned small_switch,
unsigned spare_size, ir_mode *selector_mode);
/**
* Replaces EntConsts and TypeConsts by a real constant if possible.
* Replaces Offsets and TypeConsts by a real constant if possible.
* Replaces Sel nodes by address computation. Also resolves array access.
* Handle bit fields by added And/Or calculations.
*
......@@ -104,7 +104,7 @@ FIRM_API void lower_switch(ir_graph *irg, unsigned small_switch,
FIRM_API void lower_highlevel_graph(ir_graph *irg);
/**
* Replaces EntConsts and TypeConsts by a real constant if possible.
* Replaces Offsets and TypeConsts by a real constant if possible.
* Replaces Sel nodes by address computation. Also resolves array access.
* Handle bit fields by added And/Or calculations.
* Lowers all graphs.
......
......@@ -25,7 +25,7 @@
* Each type gets a list of all Alloc nodes allocating it.
* Each entity gets two lists:
* - one containing all accesses (Load, (Call), Store),
* - and one containing all uses to get a reference (Sel, EntConst).
* - and one containing all uses to get a reference (Address, Sel).
* @{
*/
......@@ -34,11 +34,11 @@ FIRM_API size_t get_entity_n_accesses(const ir_entity *entity);
/** Returns Load/Store node number @p pos that possibly accesses entity @p entity. */
FIRM_API ir_node *get_entity_access(const ir_entity *entity, size_t pos);
/** Returns number of references to entity @p entity, in form of EntConst/Sel,
/** Returns number of references to entity @p entity, in form of Address/Sel,
* including references from constant entities and the like. */
FIRM_API size_t get_entity_n_references(const ir_entity *entity);
/** Returns reference number @p pos of references to an entity, in form of
* EntConst/Sel, including references from constants. */
* Address/Sel, including references from constants. */
FIRM_API ir_node *get_entity_reference(const ir_entity *entity, size_t pos);
/** Returns number of Alloc nodes that create an instance of type @p type. */
......@@ -63,11 +63,11 @@ FIRM_API ir_type *get_type_arraytype_of(const ir_type *type, size_t pos);
* types and entities.
*
* Annotates the following nodes:
* Address --> get_Address_entity()
* Alloc --> get_Alloc_type()
* Cast --> get_Cast_type()
* Sel --> get_Sel_entity()
* EntConst --> get_EntConst_entity()
* Load(addr) --> get_addr_entity() \ ent von EntConst, oder falls Sel: ent von
* Load(addr) --> get_addr_entity() \ ent von Address, oder falls Sel: ent von
* Store(addr) --> get_addr_entity() / outermost im compound. Ansonsten: nirgends.
* d.h. wir bekommen die array Elementzugriffe
* an die jack array Klasse annotiert.
......
......@@ -676,7 +676,7 @@ FIRM_API void add_entity_additional_properties(ir_entity *ent,
* - owner = unknown_type
* - type = unknown_type
* - offset = -1
* - value = EntConst(unknown_entity)
* - value = Address(unknown_entity)
* - values = NULL
* - val_paths = NULL
* - volatility = volatility_non_volatile
......
......@@ -169,7 +169,7 @@ static void sel_methods_walker(ir_node *node, void *env)
return;
/* we may have a vtable entry and need this redirection to get the actually
* called method */
ir_entity *const called = get_EntConst_entity(get_atomic_ent_value(entity));
ir_entity *const called = get_Address_entity(get_atomic_ent_value(entity));
if (!pset_find_ptr(entities, called)) {
/* Entity not yet handled. Find all (internal or external)
* implemented methods that overwrites this entity.
......@@ -186,7 +186,7 @@ static void sel_methods_walker(ir_node *node, void *env)
* an implementation. The set is stored in the entity's link field.
*
* Further replaces Sel nodes where this set contains exactly one
* method by EntConst nodes.
* method by Address nodes.
*/
static void sel_methods_init(void)
{
......@@ -303,14 +303,14 @@ static void free_mark(ir_node *node, pset *set)
}
break;
}
case iro_EntConst:
if (get_EntConst_kind(node) == entconst_addr) {
const ir_entity *ent = get_EntConst_entity(node);
if (is_method_entity(ent)) {
pset_insert_ptr(set, ent);
}
case iro_Address: {
const ir_entity *ent = get_Address_entity(node);
if (is_method_entity(ent)) {
pset_insert_ptr(set, ent);
}
break;
}
case iro_Phi:
for (int i = 0, n = get_Phi_n_preds(node); i < n; ++i) {
......@@ -339,9 +339,10 @@ static void free_ana_walker(ir_node *node, void *env)
pset *set = (pset*) env;
switch (get_irn_opcode(node)) {
/* special nodes */
case iro_Address:
case iro_Sel:
case iro_EntConst:
case iro_Const:
case iro_Offset:
case iro_Phi:
case iro_Id:
case iro_Proj:
......@@ -394,8 +395,8 @@ static void add_method_address_inititializer(ir_initializer_t *initializer,
ir_node *n = initializer->consti.value;
/* let's check if it's the address of a function */
if (is_EntConst_addr(n)) {
ir_entity *ent = get_EntConst_entity(n);
if (is_Address(n)) {
ir_entity *ent = get_Address_entity(n);
if (is_Method_type(get_entity_type(ent)))
pset_insert_ptr(set, ent);
......@@ -561,10 +562,8 @@ static void callee_ana_node(ir_node *node, pset *methods)
pset_insert_ptr(methods, get_unknown_entity()); /* free method -> unknown */
break;
case iro_EntConst: {
if (!is_EntConst_addr(node))
break;
ir_entity *ent = get_EntConst_entity(node);
case iro_Address: {
ir_entity *ent = get_Address_entity(node);
if (is_method_entity(ent))
pset_insert_ptr(methods, ent);
break;
......@@ -689,7 +688,7 @@ static void destruct_walker(ir_node *node, void *env)
size_t cgana(ir_entity ***free_methods)
{
/* Optimize Sel/EntConst nodes and compute all methods that implement an entity. */
/* Optimize Address/Sel nodes and compute all methods that implement an entity. */
sel_methods_init();
size_t length = get_free_methods(free_methods);
callee_ana();
......@@ -716,7 +715,7 @@ void opt_call_addrs(void)
*
* This optimization performs the following transformations for
* all ir graphs:
* - All EntConst operations that refer to intern methods are replaced
* - All Address operations that refer to intern methods are replaced
* by Const operations referring to the corresponding entity.
* - Sel nodes, that select entities that are not overwritten are
* replaced by Const nodes referring to the selected entity.
......
......@@ -257,12 +257,21 @@ static void handle_if(ir_node *block, ir_node *cmp, ir_relation rel, env_t *env)
return;
/* try to place the constant on the right side for a Confirm */
if (is_Const(left) || is_EntConst(left) || is_TypeConst(left)) {
switch (get_irn_opcode(left)) {
case iro_Address:
case iro_Const:
case iro_Offset:
case iro_TypeConst: {
ir_node *t = left;
left = right;
right = t;
rel = get_inversed_relation(rel);
break;
}
default:
break;
}
/*
......@@ -441,11 +450,11 @@ static bool is_non_null_Confirm(const ir_node *ptr)
ptr = get_Confirm_value(ptr);
}
/*
* While an EntConst is not a Confirm, it is non-null
* While an Address is not a Confirm, it is non-null
* anyway. This helps to reduce the number of
* constructed Confirms.
*/
if (is_EntConst_addr(ptr))
if (is_Address(ptr))
return true;
return false;
}
......
......@@ -345,13 +345,13 @@ static ir_alias_relation different_types(const ir_node *adr1,
ir_entity *ent1 = NULL;
ir_entity *ent2 = NULL;
if (is_EntConst_addr(adr1))
ent1 = get_EntConst_entity(adr1);
if (is_Address(adr1))
ent1 = get_Address_entity(adr1);
else if (is_Sel(adr1))
ent1 = get_Sel_entity(adr1);
if (is_EntConst_addr(adr2))
ent2 = get_EntConst_entity(adr2);
if (is_Address(adr2))
ent2 = get_Address_entity(adr2);
else if (is_Sel(adr2))
ent2 = get_Sel_entity(adr2);
......@@ -408,8 +408,8 @@ ir_storage_class_class_t classify_pointer(const ir_node *irn,
{
ir_graph *irg = get_irn_irg(irn);
ir_storage_class_class_t res = ir_sc_pointer;
if (is_EntConst_addr(irn)) {
ir_entity *entity = get_EntConst_entity(irn);
if (is_Address(irn)) {
ir_entity *entity = get_Address_entity(irn);
ir_type *owner = get_entity_owner(entity);
res = owner == get_tls_type() ? ir_sc_tls : ir_sc_globalvar;
if (!(get_entity_usage(entity) & ir_usage_address_taken))
......@@ -631,12 +631,12 @@ static ir_alias_relation _get_alias_relation(
} else {
/* both classes are equal */
if (class1 == ir_sc_globalvar) {
ir_entity *entity1 = get_EntConst_entity(base1);
ir_entity *entity2 = get_EntConst_entity(base2);
ir_entity *entity1 = get_Address_entity(base1);
ir_entity *entity2 = get_Address_entity(base2);
if (entity1 != entity2)
return ir_no_alias;
/* for some reason CSE didn't happen yet for the 2 EntConsts... */
/* for some reason CSE didn't happen yet for the 2 Addresses... */
return ir_may_alias;
} else if (class1 == ir_sc_globaladdr) {
ir_tarval *tv = get_Const_tarval(base1);
......@@ -1059,8 +1059,8 @@ static void check_initializer_value(ir_node *value)
return;
/* let's check if it's an address */
if (is_EntConst_addr(value)) {
ir_entity *ent = get_EntConst_entity(value);
if (is_Address(value)) {
ir_entity *ent = get_Address_entity(value);
set_entity_usage(ent, ir_usage_unknown);
}
......@@ -1172,10 +1172,10 @@ static void print_entity_usage_flags(const ir_type *tp)
static void check_global_address(ir_node *irn, void *data)
{
(void) data;
if (!is_EntConst_addr(irn))
if (!is_Address(irn))
return;
ir_entity *entity = get_EntConst_entity(irn);
ir_entity *entity = get_Address_entity(irn);
unsigned flags = get_entity_usage(entity);
flags |= determine_entity_usage(irn, entity);
set_entity_usage(entity, (ir_entity_usage) flags);
......@@ -1339,8 +1339,8 @@ void mark_private_methods(void)
static ir_entity *find_entity(ir_node *ptr)
{
switch (get_irn_opcode(ptr)) {
case iro_EntConst:
return get_EntConst_entity(ptr);
case iro_Address:
return get_Address_entity(ptr);
case iro_Sel:
return get_Sel_entity(ptr);
case iro_Sub:
......
......@@ -238,23 +238,21 @@ static ir_entity *get_Sel_accessed_entity(const ir_node *sel)
return get_Sel_entity(sel);
}
/** An addr node is a EntConst or a Sel. */
/** An addr node is an Address or a Sel. */
static int get_addr_n_entities(const ir_node *addr)
{
switch (get_irn_opcode(addr)) {
case iro_Sel:
/* Treat jack array sels? */
return get_Sel_n_accessed_entities(addr);
case iro_EntConst:
if (get_EntConst_kind(addr) == entconst_addr)
return 1;
return 0;
case iro_Address:
return 1;
default:
return 0;
}
}
/** An addr node is a EntConst or a Sel.
/** An addr node is an Address or a Sel.
If Sel follow to outermost of compound. */
static ir_entity *get_addr_entity(const ir_node *addr, int pos)
{
......@@ -270,12 +268,9 @@ static ir_entity *get_addr_entity(const ir_node *addr, int pos)
assert(0 <= pos && pos < get_Sel_n_accessed_entities(addr));
return get_Sel_accessed_entity(addr);
}
case iro_EntConst:
if (get_EntConst_kind(addr) == entconst_addr) {
assert(pos == 0);
return get_EntConst_entity(addr);
}
return NULL;
case iro_Address:
assert(pos == 0);
return get_Address_entity(addr);
default:
return NULL;
}
......@@ -288,8 +283,8 @@ static void chain_accesses(ir_node *n, void *env)
if (is_Sel(n)) {
add_entity_reference(get_Sel_entity(n), n);
return;
} else if (is_EntConst_addr(n)) {
add_entity_reference(get_EntConst_entity(n), n);
} else if (is_Address(n)) {
add_entity_reference(get_Address_entity(n), n);
return;
} else if (is_Store(n)) {
addr = get_Store_ptr(n);
......
......@@ -351,14 +351,14 @@ static int vrp_update_node(ir_vrp_info *info, ir_node *node)
/* TODO: Check, if there can be information derived from any of these:
is_Abs(node) is_Alloc(node) is_Anchor(node) is_Borrow(node) is_Bound(node)
is_Break(node) is_Builtin(node) is_Call(node)
is_Abs(node) is_Address(node) is_Alloc(node) is_Anchor(node) is_Borrow(node)
is_Bound(node) is_Break(node) is_Builtin(node) is_Call(node)
is_Carry(node) is_Cmp(node) is_Cond(node)
is_CopyB(node) is_Div(node) is_Dummy(node)
is_End(node) is_EntConst(node) is_Free(node)
is_End(node) is_Free(node)
is_IJmp(node) is_Jmp(node) is_Load(node) is_Minus(node)
is_Mod(node) is_Mul(node) is_Mulh(node) is_Mux(node) is_NoMem(node)
is_Pin(node) is_Proj(node)
is_Offset(node) is_Pin(node) is_Proj(node)
is_Raise(node) is_Return(node) is_Sel(node) is_Start(node) is_Store(node)
is_Sync(node) is_Tuple(node) is_TypeConst(node)
*/
......
......@@ -151,11 +151,11 @@ static reference_mode_t need_relative_addressing(const ir_entity *entity)
? REFERENCE_IP_RELATIVE : REFERENCE_GOT;
}
static ir_node *gen_EntConst(ir_node *node)
static ir_node *gen_Address(ir_node *node)
{
ir_node *block = be_transform_node(get_nodes_block(node));
dbg_info *dbgi = get_irn_dbg_info(node);
ir_entity *entity = get_EntConst_entity(node);
ir_entity *entity = get_Address_entity(node);
/* do we need RIP-relative addressing because of PIC? */
reference_mode_t mode = need_relative_addressing(entity);
......@@ -1112,6 +1112,7 @@ static void amd64_register_transformers(void)
be_start_transform_setup();
be_set_transform_function(op_Add, gen_Add);
be_set_transform_function(op_Address, gen_Address);
be_set_transform_function(op_And, gen_And);
be_set_transform_function(op_Cmp, gen_Cmp);
be_set_transform_function(op_Call, gen_Call);
......@@ -1137,7 +1138,6 @@ static void amd64_register_transformers(void)
be_set_transform_function(op_Store, gen_Store);
be_set_transform_function(op_Sub, gen_Sub);
be_set_transform_function(op_Switch, gen_Switch);
be_set_transform_function(op_EntConst, gen_EntConst);
be_set_transform_proj_function(op_Call, gen_Proj_Call);
be_set_transform_proj_function(op_Cond, be_duplicate_node);
......
......@@ -1026,10 +1026,10 @@ static ir_node *gen_Const(ir_node *node)
return create_const_graph(node, block);
}
static ir_node *gen_EntConst(ir_node *node)
static ir_node *gen_Address(ir_node *node)
{
ir_node *block = be_transform_node(get_nodes_block(node));
ir_entity *entity = get_EntConst_entity(node);
ir_entity *entity = get_Address_entity(node);
dbg_info *dbgi = get_irn_dbg_info(node);
ir_node *new_node;
......@@ -1726,8 +1726,8 @@ static ir_node *gen_Call(ir_node *node)
}
/* TODO: use a generic address matcher here */
if (is_EntConst(callee)) {
entity = get_EntConst_entity(callee);
if (is_Address(callee)) {
entity = get_Address_entity(callee);
} else {
/* TODO: finish load matcher here */
in[in_arity] = be_transform_node(callee);
......@@ -1823,6 +1823,7 @@ static void arm_register_transformers(void)
be_start_transform_setup();
be_set_transform_function(op_Add, gen_Add);
be_set_transform_function(op_Address, gen_Address);
be_set_transform_function(op_And, gen_And);
be_set_transform_function(op_Call, gen_Call);
be_set_transform_function(op_Cmp, gen_Cmp);
......@@ -1848,7 +1849,6 @@ static void arm_register_transformers(void)
be_set_transform_function(op_Store, gen_Store);
be_set_transform_function(op_Sub, gen_Sub);
be_set_transform_function(op_Switch, gen_Switch);
be_set_transform_function(op_EntConst, gen_EntConst);
be_set_transform_function(op_Unknown, gen_Unknown);
be_set_transform_function(op_Builtin, gen_Builtin);
......
......@@ -504,13 +504,13 @@ static ir_node *adjust_call(be_abi_irg_t *env, ir_node *irn, ir_node *curr_sp)
/* ins collected, build the call */
ir_node *low_call;
if (env->call->flags.call_has_imm && is_EntConst(call_ptr)) {
if (env->call->flags.call_has_imm && is_Address(call_ptr)) {
/* direct call */
low_call = be_new_Call(dbgi, bl, curr_mem, sp->single_req, curr_sp,
sp->single_req, curr_sp,
n_reg_results + pn_be_Call_first_res + ARR_LEN(destroyed_regs),
n_ins, in, get_Call_type(irn));
be_Call_set_entity(low_call, get_EntConst_entity(call_ptr));
be_Call_set_entity(low_call, get_Address_entity(call_ptr));
} else {
/* indirect call */
low_call = be_new_Call(dbgi, bl, curr_mem, sp->single_req, curr_sp,
......
......@@ -642,19 +642,13 @@ static void emit_init_expression(be_gas_decl_env_t *env, ir_node *init)
return;
}
case iro_EntConst: {
ir_entity *const ent = get_EntConst_entity(init);
switch (get_EntConst_kind(init)) {
case entconst_addr:
be_gas_emit_entity(ent);
return;
case iro_Address:
be_gas_emit_entity(get_Address_entity(init));
return;
case entconst_ofs:
be_emit_irprintf("%d", get_entity_offset(ent));
return;
}
panic("invalid EntConst kind");
}
case iro_Offset:
be_emit_irprintf("%d", get_entity_offset(get_Offset_entity(init)));
return;
case iro_TypeConst: {
ir_type *const type = get_TypeConst_type(init);
......
......@@ -627,7 +627,7 @@ void be_map_exc_node_to_runtime_call(ir_node *node, ir_mode *res_mode,
ir_graph *irg = get_irn_irg(node);
dbg_info *dbgi = get_irn_dbg_info(node);
ir_node *addr = new_r_EntConst(irg, mode_P_code, runtime_entity, entconst_addr);
ir_node *addr = new_r_Address(irg, mode_P_code, runtime_entity);
ir_node *block = get_nodes_block(node);
ir_node *mem = get_memop_mem(node);
ir_node *call = new_rd_Call(dbgi, block, mem, addr, n_in, in, mtp);
......
......@@ -52,17 +52,15 @@ static bool do_is_immediate(const ir_node *node, int *entities, bool negate)
return false;
}
return true;
case iro_EntConst:
/* the first EntConst of a DAG can be folded into an immediate */
case iro_Address:
/* the first Address of a DAG can be folded into an immediate */
/* unfortunately the assembler/linker doesn't support -entity */
if (negate)
return false;
if (get_EntConst_kind(node) != entconst_addr)
return false;
if (++*entities > 1)
return false;
return true;
case iro_Unknown:
/* we can use '0' for Unknowns */
return true;
......@@ -122,12 +120,12 @@ static void eat_immediate(ia32_address_t *addr, ir_node *node, bool negate)
}
break;
}
case iro_EntConst:
case iro_Address:
/* place the entity into the immediate */
if (addr->entity != NULL) {
panic("Internal error: more than 1 entity in address calculation");
}
addr->entity = get_EntConst_entity(node);
addr->entity = get_Address_entity(node);
if (is_tls_entity(addr->entity))
addr->tls_segment = true;
assert(!negate);
......
......@@ -802,20 +802,20 @@ ir_node *ia32_try_create_Immediate(ir_node *node, char immediate_constraint_type
if (is_Const(node)) {
cnst = node;
entity = NULL;
} else if (is_EntConst_addr(node)) {
} else if (is_Address(node)) {
cnst = NULL;
entity = get_EntConst_entity(node);
entity = get_Address_entity(node);
if (is_tls_entity(entity))
return NULL;
} else if (is_Add(node)) {
ir_node *left = get_Add_left(node);
ir_node *right = get_Add_right(node);
if (is_Const(left) && is_EntConst_addr(right)) {
if (is_Const(left) && is_Address(right)) {
cnst = left;
entity = get_EntConst_entity(right);
} else if (is_EntConst_addr(left) && is_Const(right)) {
entity = get_Address_entity(right);
} else if (is_Address(left) && is_Const(right)) {
cnst = right;
entity = get_EntConst_entity(left);
entity = get_Address_entity(left);
} else {
return NULL;
}
......
......@@ -84,7 +84,7 @@ static int can_address_relative(ir_entity *entity)
return entity_has_definition(entity) && !(get_entity_linkage(entity) & IR_LINKAGE_MERGE);
}
/** patches EntConsts to work in position independent code */
/** patches Addresses to work in position independent code */
static void fix_pic_addresses(ir_node *node, void *data)
{
(void) data;
......@@ -93,21 +93,20 @@ static void fix_pic_addresses(ir_node *node, void *data)
for (int i = 0, arity = get_irn_arity(node); i < arity; ++i) {
ir_node *pred = get_irn_n(node, i);
if (!is_EntConst(pred))
if (!is_Address(pred))
continue;
/* calls can jump to relative addresses, so we can directly jump to
the (relatively) known call address or the trampoline */
ir_entity *const entity = get_EntConst_entity(pred);
ir_entity *const entity = get_Address_entity(pred);
ir_node *const block = get_nodes_block(pred);
dbg_info *const dbgi = get_irn_dbg_info(pred);