* of these may be discovered by analyses.
*/
typedef enum mtp_additional_properties {
- mtp_no_property = 0x00000000, /**< no additional properties, default */
- mtp_property_const = 0x00000001, /**< This method did not access memory and calculates
- its return values solely from its parameters.
- The only observable effect of a const function must be its
- return value. So they must not exhibit infinite loops or wait
- for user input. The return value must not depend on any
- global variables/state.
- GCC: __attribute__((const)). */
- mtp_property_pure = 0x00000002, /**< This method did NOT write to memory and calculates
- its return values solely from its parameters and
- the memory they points to (or global vars).
- The only observable effect of a const function must be its
- return value. So they must not exhibit infinite loops or wait
- for user input.
- GCC: __attribute__((pure)). */
- mtp_property_noreturn = 0x00000004, /**< This method did not return due to an aborting system
- call.
- GCC: __attribute__((noreturn)). */
- mtp_property_nothrow = 0x00000008, /**< This method cannot throw an exception.
- GCC: __attribute__((nothrow)). */
- mtp_property_naked = 0x00000010, /**< This method is naked.
- GCC: __attribute__((naked)). */
- mtp_property_malloc = 0x00000020, /**< This method returns newly allocate memory.
- GCC: __attribute__((malloc)). */
- mtp_property_returns_twice = 0x00000040, /**< This method can return more than one (typically setjmp).
- GCC: __attribute__((returns_twice)). */
- mtp_property_intrinsic = 0x00000080, /**< This method is intrinsic. It is expected that
- a lowering phase will remove all calls to it. */
- mtp_property_runtime = 0x00000100, /**< This method represents a runtime routine. */
- mtp_property_private = 0x00000200, /**< All method invocations are known, the backend is free to
- optimize the call in any possible way. */
- mtp_property_has_loop = 0x00000400, /**< Set, if this method contains one possible endless loop. */
- mtp_property_inherited = (1<<31) /**< Internal. Used only in irg's, means property is
- inherited from type. */
+ /** no additional properties */
+ mtp_no_property = 0,
+ /** This method did not access memory and calculates its return values
+ * solely from its parameters. The only observable effect of a const
+ * function must be its return value. So they must not exhibit infinite
+ * loops or wait for user input. The return value must not depend on any
+ * global variables/state.
+ * GCC: __attribute__((const)). */
+ mtp_property_const = 1u << 0,
+ /** This method did NOT write to memory and calculates its return values
+ * solely from its parameters and the memory they points to (or global
+ * vars). The only observable effect of a const function must be its return
+ * value. So they must not exhibit infinite loops or wait for user input.
+ * GCC: __attribute__((pure)). */
+ mtp_property_pure = 1u << 1,
+ /** This method did not return due to an aborting system call.
+ * GCC: __attribute__((noreturn)). */
+ mtp_property_noreturn = 1u << 2,
+ /** This method cannot throw an exception. GCC: __attribute__((nothrow)). */
+ mtp_property_nothrow = 1u << 3,
+ /** This method is naked. GCC: __attribute__((naked)). */
+ mtp_property_naked = 1u << 4,
+ /** This method returns newly allocate memory.
+ * GCC: __attribute__((malloc)). */
+ mtp_property_malloc = 1u << 5,
+ /** This method can return more than one (typically setjmp).
+ * GCC: __attribute__((returns_twice)). */
+ mtp_property_returns_twice = 1u << 6,
+ /** This method is intrinsic. It is expected that a lowering phase will
+ * remove all calls to it. */
+ mtp_property_intrinsic = 1u << 7,
+ /** This method represents a runtime routine. */
+ mtp_property_runtime = 1u << 8,
+ /** All method invocations are known, the backend is free to optimize the
+ * call in any possible way. */
+ mtp_property_private = 1u << 9,
+ /** Set, if this method contains one possibly endless loop. */
+ mtp_property_has_loop = 1u << 10,
+ /** try to always inline this function, even if it seems nonprofitable */
+ mtp_property_always_inline = 1u << 11,
+ /** the function should not be inlined */
+ mtp_property_noinline = 1u << 12,
+ /** the programmer recommends to inline the function */
+ mtp_property_inline_recommended = 1u << 13,
+ /** stupid hack used by opt_funccall... */
+ mtp_temporary = 1u << 31,
} mtp_additional_properties;
ENUM_BITSET(mtp_additional_properties)
/** Sets the callee_info_state of an IR graph. */
FIRM_API void set_irg_callee_info_state(ir_graph *irg, irg_callee_info_state s);
-/** property:
- * Tells how to handle an ir graph in inlining.
- */
-typedef enum {
- irg_inline_any, /**< No restriction on inlining. Default. */
- irg_inline_forbidden, /**< The graph must not be inlined. */
- irg_inline_recomended, /**< The graph should be inlined. */
- irg_inline_forced, /**< The graph must be inlined. */
- irg_inline_forced_no_body /**< The graph must be inlined. No body is allowed
- to be emitted. */
-} irg_inline_property;
-
-/** Returns the inline property of a graph. */
-FIRM_API irg_inline_property get_irg_inline_property(const ir_graph *irg);
-/** Sets the inline property of a graph. */
-FIRM_API void set_irg_inline_property(ir_graph *irg, irg_inline_property s);
-
-/**
- * Returns the mask of the additional graph properties.
- * The properties are automatically inherited from the method type
- * if they were not set using set_irg_additional_properties() or
- * set_irg_additional_properties().
- *
- * @return a bitset of mtp_additional_properties values
- */
-FIRM_API mtp_additional_properties get_irg_additional_properties(const ir_graph *irg);
-
-/** Sets the mask of the additional graph properties. */
-FIRM_API void set_irg_additional_properties(ir_graph *irg,
- mtp_additional_properties property_mask);
-
-/** Sets one additional graph property. */
-FIRM_API void add_irg_additional_properties(ir_graph *irg,
- mtp_additional_properties flag);
-
/** A void * field to link arbitrary information to the node. */
FIRM_API void set_irg_link(ir_graph *irg, void *thing);
/** Return void* field previously set by set_irg_link() */
new_identities(res);
- res->inline_property = irg_inline_any;
- res->additional_properties = mtp_property_inherited; /* inherited from type */
-
res->irg_pinned_state = op_pin_state_pinned;
res->typeinfo_state = ir_typeinfo_none;
set_irp_typeinfo_inconsistent(); /* there is a new graph with typeinfo_none. */
set_irg_callee_info_state_(irg, s);
}
-irg_inline_property (get_irg_inline_property)(const ir_graph *irg)
-{
- return get_irg_inline_property_(irg);
-}
-
-void (set_irg_inline_property)(ir_graph *irg, irg_inline_property s)
-{
- set_irg_inline_property_(irg, s);
-}
-
-mtp_additional_properties (get_irg_additional_properties)(const ir_graph *irg)
-{
- return get_irg_additional_properties_(irg);
-}
-
-void (set_irg_additional_properties)(ir_graph *irg, mtp_additional_properties property_mask)
-{
- set_irg_additional_properties_(irg, property_mask);
-}
-
-void (add_irg_additional_properties)(ir_graph *irg, mtp_additional_properties flag)
-{
- add_irg_additional_properties_(irg, flag);
-}
-
void (set_irg_link)(ir_graph *irg, void *thing)
{
set_irg_link_(irg, thing);
set_irp_callee_info_state(s);
}
-static inline irg_inline_property get_irg_inline_property_(const ir_graph *irg)
-{
- return irg->inline_property;
-}
-
-static inline void set_irg_inline_property_(ir_graph *irg, irg_inline_property s)
-{
- irg->inline_property = s;
-}
-
-static inline mtp_additional_properties get_irg_additional_properties_(const ir_graph *irg)
-{
- if (irg->additional_properties & mtp_property_inherited)
- return get_method_additional_properties(get_entity_type(irg->ent));
- return irg->additional_properties;
-}
-
-static inline void set_irg_additional_properties_(ir_graph *irg, mtp_additional_properties mask)
-{
- irg->additional_properties = mask & ~mtp_property_inherited;
-}
-
-static inline void add_irg_additional_properties_(ir_graph *irg, mtp_additional_properties flag)
-{
- mtp_additional_properties prop = irg->additional_properties;
-
- if (prop & mtp_property_inherited)
- prop = get_method_additional_properties(get_entity_type(irg->ent));
- irg->additional_properties = prop | flag;
-}
-
static inline void set_irg_link_(ir_graph *irg, void *thing)
{
irg->link = thing;
#define set_irg_pinned(irg, p) set_irg_pinned_(irg, p)
#define get_irg_callee_info_state(irg) get_irg_callee_info_state_(irg)
#define set_irg_callee_info_state(irg, s) set_irg_callee_info_state_(irg, s)
-#define get_irg_inline_property(irg) get_irg_inline_property_(irg)
-#define set_irg_inline_property(irg, s) set_irg_inline_property_(irg, s)
#define get_irg_additional_properties(irg) get_irg_additional_properties_(irg)
#define set_irg_additional_properties(irg, m) set_irg_additional_properties_(irg, m)
#define set_irg_additional_property(irg, f) set_irg_additional_property_(irg, f)
tt_builtin_kind,
tt_cond_jmp_predicate,
tt_initializer,
- tt_irg_inline_property,
tt_keyword,
tt_linkage,
tt_mode_arithmetic,
INSERT(tt_mode_arithmetic, "ieee754", irma_ieee754);
INSERT(tt_mode_arithmetic, "x86_extended_float", irma_x86_extended_float);
- INSERT(tt_irg_inline_property, "any", irg_inline_any);
- INSERT(tt_irg_inline_property, "recommended", irg_inline_recomended);
- INSERT(tt_irg_inline_property, "forbidden", irg_inline_forbidden);
- INSERT(tt_irg_inline_property, "forced", irg_inline_forced);
- INSERT(tt_irg_inline_property, "forced_no_body", irg_inline_forced_no_body);
-
INSERTENUM(tt_pin_state, op_pin_state_floats);
INSERTENUM(tt_pin_state, op_pin_state_pinned);
INSERTENUM(tt_pin_state, op_pin_state_exc_pinned);
panic("invalid mode_arithmetic");
}
-static const char *get_irg_inline_property_name(irg_inline_property prop)
-{
- switch (prop) {
- case irg_inline_any: return "any";
- case irg_inline_recomended: return "recommended";
- case irg_inline_forbidden: return "forbidden";
- case irg_inline_forced: return "forced";
- case irg_inline_forced_no_body: return "forced_no_body";
- }
- panic("invalid irg_inline_property");
-}
-
/** Returns the according symbol value for the given string and tag, or SYMERROR if none was found. */
static unsigned symbol(const char *str, typetag_t typetag)
{
fputc(' ', env->file);
}
-static void write_inline_property(write_env_t *env, irg_inline_property prop)
-{
- fputs(get_irg_inline_property_name(prop), env->file);
- fputc(' ', env->file);
-}
-
static void write_type_state(write_env_t *env, ir_type_state state)
{
fputs(get_type_state_name(state), env->file);
write_symbol(env, "irg");
write_entity_ref(env, get_irg_entity(irg));
write_type_ref(env, get_irg_frame_type(irg));
- write_inline_property(env, get_irg_inline_property(irg));
- write_unsigned(env, get_irg_additional_properties(irg));
write_scope_begin(env);
ir_reserve_resources(irg, IR_RESOURCE_IRN_VISITED);
inc_irg_visited(irg);
case tt_builtin_kind: return "builtin kind";
case tt_cond_jmp_predicate: return "cond_jmp_predicate";
case tt_initializer: return "initializer kind";
- case tt_irg_inline_property: return "irg_inline_property";
case tt_keyword: return "keyword";
case tt_linkage: return "linkage";
case tt_mode_arithmetic: return "mode_arithmetic";
return (keyword_t)read_enum(env, tt_keyword);
}
-static irg_inline_property read_inline_property(read_env_t *env)
-{
- return (irg_inline_property)read_enum(env, tt_irg_inline_property);
-}
-
static ir_relation read_relation(read_env_t *env)
{
return (ir_relation)read_long(env);
static ir_graph *read_irg(read_env_t *env)
{
- ir_entity *irgent = get_entity(env, read_long(env));
- ir_graph *irg = new_ir_graph(irgent, 0);
- ir_type *frame = read_type_ref(env);
- irg_inline_property prop = read_inline_property(env);
- unsigned props = read_unsigned(env);
+ ir_entity *irgent = get_entity(env, read_long(env));
+ ir_graph *irg = new_ir_graph(irgent, 0);
+ ir_type *frame = read_type_ref(env);
set_irg_frame_type(irg, frame);
- set_irg_inline_property(irg, prop);
- set_irg_additional_properties(irg, (mtp_additional_properties)props);
read_graph(env, irg);
irg_finalize_cons(irg);
return irg;
struct obstack *obst; /**< The obstack where all of the ir_nodes live. */
ir_node *current_block; /**< Current block for newly gen_*()-erated ir_nodes. */
- /* -- Fields for graph properties -- */
- irg_inline_property inline_property; /**< How to handle inlineing. */
- mtp_additional_properties additional_properties; /**< Additional graph properties. */
-
/* -- Fields indicating different states of irgraph -- */
ir_graph_properties_t properties;
ir_graph_constraints_t constraints;
/** IRG's that are in progress are marked here. */
static unsigned *busy_set;
-/**
- * We misuse the mtp_property_inherited flag as temporary here.
- * The is ok, as we cannot set or get it anyway using the
- * get_addtional_properties API.
- */
-#define mtp_temporary mtp_property_inherited
-
/**
* Walker: Collect all calls to const and pure functions
* to lists. Collect all Proj(Call) nodes into a Proj list.
ir_type *type = get_entity_type(entity);
size_t n_params = get_method_n_params(type);
mtp_additional_properties may_be_const = mtp_property_const;
- mtp_additional_properties prop = get_irg_additional_properties(irg);
+ mtp_additional_properties prop = get_entity_additional_properties(entity);
/* libfirm handles aggregate parameters by passing around pointers to
* stuff in memory, so if we have compound parameters we are never const */
if (top) {
/* Set the property only if we are at top-level. */
if (prop != mtp_no_property) {
- add_irg_additional_properties(irg, prop);
+ add_entity_additional_properties(entity, prop);
}
SET_IRG_READY(irg);
}
mtp_additional_properties curr_prop
= mtp_property_malloc | mtp_property_nothrow;
+ ir_entity *ent = get_irg_entity(irg);
if (IS_IRG_READY(irg)) {
/* already checked */
- return get_irg_additional_properties(irg);
+ return get_entity_additional_properties(ent);
}
if (IS_IRG_BUSY(irg)) {
/* we are still evaluate this method. Be optimistic,
}
SET_IRG_BUSY(irg);
- ir_entity *ent = get_irg_entity(irg);
- ir_type *mtp = get_entity_type(ent);
-
+ ir_type *mtp = get_entity_type(ent);
if (get_method_n_ress(mtp) <= 0)
curr_prop &= ~mtp_property_malloc;
/* We use the temporary flag here to mark an optimistic result.
* Set the property only if we are sure that it does NOT base on
* temporary results OR if we are at top-level. */
- add_irg_additional_properties(irg, curr_prop & ~mtp_temporary);
+ add_entity_additional_properties(ent, curr_prop & ~mtp_temporary);
SET_IRG_READY(irg);
}
if (top)
assure_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_LOOPINFO);
ir_loop *root_loop = get_irg_loop(irg);
- if (root_loop->flags & loop_outer_loop)
- add_irg_additional_properties(irg, mtp_property_has_loop);
+ if (root_loop->flags & loop_outer_loop) {
+ ir_entity *ent = get_irg_entity(irg);
+ add_entity_additional_properties(ent, mtp_property_has_loop);
+ }
confirm_irg_properties(irg, IR_GRAPH_PROPERTIES_ALL);
}
size_t n_params = get_method_n_params(called_type);
size_t n_arguments = get_method_n_params(call_type);
size_t n_res = get_method_n_ress(called_type);
- irg_inline_property prop = get_irg_inline_property(called_graph);
+ mtp_additional_properties props = get_entity_additional_properties(called);
size_t i;
bool res;
- if (prop == irg_inline_forbidden)
+ if (props & mtp_property_noinline)
return false;
if (n_arguments != n_params) {
collect_phiprojs(irg);
list_for_each_entry(call_entry, entry, &env.calls, list) {
- ir_graph *callee = entry->callee;
- irg_inline_property prop = get_irg_inline_property(callee);
+ ir_graph *callee = entry->callee;
+ ir_entity *called = get_irg_entity(callee);
+ mtp_additional_properties props
+ = get_entity_additional_properties(called);
- if (prop == irg_inline_forbidden) {
+ if (props & mtp_property_noinline)
continue;
- }
- if (prop >= irg_inline_forced ||
+ if ((props & mtp_property_always_inline) ||
_obstack_memory_used(callee->obst) - (int)obstack_room(callee->obst) < size) {
inline_method(entry->call, callee);
}
did_inline = 0;
for (i = 0; i < n_irgs; ++i) {
- ir_node *call;
int phiproj_computed = 0;
current_ir_graph = get_irp_irg(i);
ir_reserve_resources(current_ir_graph, IR_RESOURCE_IRN_LINK|IR_RESOURCE_PHI_LIST);
list_for_each_entry_safe(call_entry, entry, next, &env->calls, list) {
- ir_graph *callee;
- irg_inline_property prop;
-
if (env->n_nodes > maxsize)
break;
- call = entry->call;
- callee = entry->callee;
-
- prop = get_irg_inline_property(callee);
- if (prop == irg_inline_forbidden) {
+ ir_node *call = entry->call;
+ ir_graph *callee = entry->callee;
+ ir_entity *called = get_irg_entity(callee);
+ mtp_additional_properties props
+ = get_entity_additional_properties(called);
+ if (props & mtp_property_noinline)
continue;
- }
if (is_leaf(callee) && (
- is_smaller(callee, leafsize) || prop >= irg_inline_forced)) {
+ is_smaller(callee, leafsize) || (props & mtp_property_always_inline))) {
if (!phiproj_computed) {
phiproj_computed = 1;
collect_phiprojs(current_ir_graph);
/* inline other small functions. */
for (i = 0; i < n_irgs; ++i) {
- ir_node *call;
int phiproj_computed = 0;
current_ir_graph = get_irp_irg(i);
/* note that the list of possible calls is updated during the process */
list_for_each_entry_safe(call_entry, entry, next, &env->calls, list) {
- irg_inline_property prop;
- ir_graph *callee;
- ir_graph *calleee;
-
- call = entry->call;
- callee = entry->callee;
+ ir_node *call = entry->call;
+ ir_graph *callee = entry->callee;
+ ir_entity *called = get_irg_entity(callee);
- prop = get_irg_inline_property(callee);
- if (prop == irg_inline_forbidden) {
+ mtp_additional_properties props = get_entity_additional_properties(called);
+ if (props & mtp_property_noinline)
continue;
- }
- calleee = pmap_get(ir_graph, copied_graphs, callee);
+ ir_graph *calleee = pmap_get(ir_graph, copied_graphs, callee);
if (calleee != NULL) {
/*
* Remap callee if we have a copy.
callee = calleee;
}
- if (prop >= irg_inline_forced ||
+ if ((props & mtp_property_always_inline) ||
(is_smaller(callee, size) && env->n_nodes < maxsize) /* small function */) {
if (current_ir_graph == callee) {
/*
int weight = 0;
int all_const;
unsigned cc, v;
- irg_inline_property prop;
inline_irg_env *callee_env;
- prop = get_irg_inline_property(callee);
- if (prop == irg_inline_forbidden) {
+ mtp_additional_properties props = get_entity_additional_properties(ent);
+ if (props & mtp_property_noinline) {
DB((dbg, LEVEL_2, "In %+F Call to %+F: inlining forbidden\n",
call, callee));
return entry->benefice = INT_MIN;
if (is_parameter_entity(frame_ent)) {
// TODO inliner should handle parameter entities by inserting Store operations
DB((dbg, LEVEL_2, "In %+F Call to %+F: inlining forbidden due to parameter entity\n", call, callee));
- set_irg_inline_property(callee, irg_inline_forbidden);
+ add_entity_additional_properties(ent, mtp_property_noinline);
return entry->benefice = INT_MIN;
}
}
- if (get_irg_additional_properties(callee) & mtp_property_noreturn) {
+ if (props & mtp_property_noreturn) {
DB((dbg, LEVEL_2, "In %+F Call to %+F: not inlining noreturn or weak\n",
call, callee));
return entry->benefice = INT_MIN;
static void maybe_push_call(pqueue_t *pqueue, call_entry *call,
int inline_threshold)
{
- ir_graph *callee = call->callee;
- irg_inline_property prop = get_irg_inline_property(callee);
- int benefice = calc_inline_benefice(call, callee);
+ ir_graph *callee = call->callee;
+ int benefice = calc_inline_benefice(call, callee);
DB((dbg, LEVEL_2, "In %+F Call %+F to %+F has benefice %d\n",
get_irn_irg(call->call), call->call, callee, benefice));
- if (prop < irg_inline_forced && benefice < inline_threshold) {
+ ir_entity *ent = get_irg_entity(callee);
+ mtp_additional_properties props = get_entity_additional_properties(ent);
+ if (!(props & mtp_property_always_inline) && benefice < inline_threshold) {
return;
}
ir_graph *callee = curr_call->callee;
ir_node *call_node = curr_call->call;
inline_irg_env *callee_env = (inline_irg_env*)get_irg_link(callee);
- irg_inline_property prop = get_irg_inline_property(callee);
+ ir_entity *ent = get_irg_entity(callee);
+ mtp_additional_properties props
+ = get_entity_additional_properties(ent);
ir_graph *calleee;
int loop_depth;
- if ((prop < irg_inline_forced) && env->n_nodes + callee_env->n_nodes > maxsize) {
+ if (!(props & mtp_property_always_inline)
+ && env->n_nodes + callee_env->n_nodes > maxsize) {
DB((dbg, LEVEL_2, "%+F: too big (%d) + %+F (%d)\n", irg,
env->n_nodes, callee, callee_env->n_nodes));
continue;
if (is_Method_type(type)) {
ir_graph *irg = get_const_code_irg();
symconst_symbol sym;
- ir_mode *mode = is_Method_type(type) ? mode_P_code : mode_P_data;
res = intern_new_entity(owner, IR_ENTITY_METHOD, name, type, db);
sym.entity_p = res;
- set_atomic_ent_value(res, new_r_SymConst(irg, mode, sym, symconst_addr_ent));
- res->linkage = IR_LINKAGE_CONSTANT;
- res->attr.mtd_attr.irg_add_properties = mtp_property_inherited;
- res->attr.mtd_attr.vtable_number = IR_VTABLE_NUM_NOT_SET;
- res->attr.mtd_attr.param_access = NULL;
- res->attr.mtd_attr.param_weight = NULL;
- res->attr.mtd_attr.irg = NULL;
+ set_atomic_ent_value(res, new_r_SymConst(irg, mode_P_code, sym, symconst_addr_ent));
+ res->linkage = IR_LINKAGE_CONSTANT;
+ res->attr.mtd_attr.properties = get_method_additional_properties(type);
+ res->attr.mtd_attr.vtable_number = IR_VTABLE_NUM_NOT_SET;
+ res->attr.mtd_attr.param_access = NULL;
+ res->attr.mtd_attr.param_weight = NULL;
+ res->attr.mtd_attr.irg = NULL;
} else if (owner != NULL
&& (is_compound_type(owner) && !(owner->flags & tf_segment))) {
res = intern_new_entity(owner, IR_ENTITY_COMPOUND_MEMBER, name, type, db);
mtp_additional_properties get_entity_additional_properties(const ir_entity *ent)
{
- ir_graph *irg;
-
assert(is_method_entity(ent));
-
- /* first check, if the graph has additional properties */
- irg = get_entity_irg(ent);
-
- if (irg)
- return get_irg_additional_properties(irg);
-
- if (ent->attr.mtd_attr.irg_add_properties & mtp_property_inherited)
- return get_method_additional_properties(get_entity_type(ent));
-
- return ent->attr.mtd_attr.irg_add_properties;
+ return ent->attr.mtd_attr.properties;
}
void set_entity_additional_properties(ir_entity *ent, mtp_additional_properties property_mask)
{
- ir_graph *irg;
-
assert(is_method_entity(ent));
+ /* you mustn't set less properties than the entities type */
+ assert((get_method_additional_properties(get_entity_type(ent)) & ~property_mask) == 0);
- /* first check, if the graph exists */
- irg = get_entity_irg(ent);
- if (irg)
- set_irg_additional_properties(irg, property_mask);
- else {
- /* do not allow to set the mtp_property_inherited flag or
- * the automatic inheritance of flags will not work */
- ent->attr.mtd_attr.irg_add_properties = property_mask & ~mtp_property_inherited;
- }
+ /* do not allow to set the mtp_property_inherited flag or
+ * the automatic inheritance of flags will not work */
+ ent->attr.mtd_attr.properties = property_mask;
}
void add_entity_additional_properties(ir_entity *ent, mtp_additional_properties properties)
{
- ir_graph *irg;
-
assert(is_method_entity(ent));
- /* first check, if the graph exists */
- irg = get_entity_irg(ent);
- if (irg)
- add_irg_additional_properties(irg, properties);
- else {
- mtp_additional_properties mask = ent->attr.mtd_attr.irg_add_properties;
-
- if (mask & mtp_property_inherited)
- mask = get_method_additional_properties(get_entity_type(ent));
-
- /* do not allow to set the mtp_property_inherited flag or
- * the automatic inheritance of flags will not work */
- ent->attr.mtd_attr.irg_add_properties = mask | (properties & ~mtp_property_inherited);
- }
+ /* do not allow to set the mtp_property_inherited flag or
+ * the automatic inheritance of flags will not work */
+ ent->attr.mtd_attr.properties |= properties;
}
ir_type *(get_entity_repr_class)(const ir_entity *ent)
typedef struct method_ent_attr {
ir_graph *irg; /**< The corresponding irg if known.
The ir_graph constructor automatically sets this field. */
- mtp_additional_properties irg_add_properties; /**< Additional graph properties can be
+ mtp_additional_properties properties; /**< Additional graph properties can be
stored in a entity if no irg is available. */
unsigned vtable_number; /**< For a dynamically called method, the number assigned
assert((get_mode_size_bits(mode_P_code) % 8 == 0) && "unorthodox modes not implemented");
res = new_type(type_method, mode_P_code, db);
- res->flags |= tf_layout_fixed;
- res->size = get_mode_size_bytes(mode_P_code);
- res->attr.ma.n_params = n_param;
- res->attr.ma.params = XMALLOCNZ(tp_ent_pair, n_param);
- res->attr.ma.n_res = n_res;
- res->attr.ma.res_type = XMALLOCNZ(tp_ent_pair, n_res);
- res->attr.ma.variadicity = variadicity_non_variadic;
- res->attr.ma.additional_properties = mtp_no_property;
+ res->flags |= tf_layout_fixed;
+ res->size = get_mode_size_bytes(mode_P_code);
+ res->attr.ma.n_params = n_param;
+ res->attr.ma.params = XMALLOCNZ(tp_ent_pair, n_param);
+ res->attr.ma.n_res = n_res;
+ res->attr.ma.res_type = XMALLOCNZ(tp_ent_pair, n_res);
+ res->attr.ma.variadicity = variadicity_non_variadic;
+ res->attr.ma.properties = mtp_no_property;
hook_new_type(res);
return res;
}
res = new_type(type_method, mode, db);
- res->flags = tp->flags;
- res->higher_type = tp->higher_type;
- res->size = tp->size;
- res->attr.ma.n_params = n_params;
- res->attr.ma.params = XMALLOCN(tp_ent_pair, n_params);
+ res->flags = tp->flags;
+ res->higher_type = tp->higher_type;
+ res->size = tp->size;
+ res->attr.ma.n_params = n_params;
+ res->attr.ma.params = XMALLOCN(tp_ent_pair, n_params);
memcpy(res->attr.ma.params, tp->attr.ma.params, n_params * sizeof(res->attr.ma.params[0]));
- res->attr.ma.n_res = n_res;
- res->attr.ma.res_type = XMALLOCN(tp_ent_pair, n_res);
+ res->attr.ma.n_res = n_res;
+ res->attr.ma.res_type = XMALLOCN(tp_ent_pair, n_res);
memcpy(res->attr.ma.res_type, tp->attr.ma.res_type, n_res * sizeof(res->attr.ma.res_type[0]));
- res->attr.ma.variadicity = tp->attr.ma.variadicity;
- res->attr.ma.additional_properties = tp->attr.ma.additional_properties;
- res->attr.ma.irg_calling_conv = tp->attr.ma.irg_calling_conv;
+ res->attr.ma.variadicity = tp->attr.ma.variadicity;
+ res->attr.ma.properties = tp->attr.ma.properties;
+ res->attr.ma.irg_calling_conv = tp->attr.ma.irg_calling_conv;
hook_new_type(res);
return res;
}
size_t n_res; /**< Number of results. */
tp_ent_pair *res_type; /**< Array of result type/value ir_entity pairs. */
ir_variadicity variadicity; /**< The variadicity of the method. */
- mtp_additional_properties additional_properties; /**< Set of additional method properties. */
+ mtp_additional_properties properties; /**< Set of additional method properties. */
unsigned irg_calling_conv; /**< A set of calling convention flags. */
} mtd_attr;
static inline mtp_additional_properties _get_method_additional_properties(const ir_type *method)
{
assert(method->type_op == type_method);
- return method->attr.ma.additional_properties;
+ return method->attr.ma.properties;
}
-static inline void _set_method_additional_properties(ir_type *method, mtp_additional_properties mask)
+static inline void _set_method_additional_properties(ir_type *method, mtp_additional_properties properties)
{
assert(method->type_op == type_method);
-
- /* do not allow to set the mtp_property_inherited flag or
- * the automatic inheritance of flags will not work */
- method->attr.ma.additional_properties = mask & ~mtp_property_inherited;
+ method->attr.ma.properties = properties;
}
-static inline void _add_method_additional_properties(ir_type *method, mtp_additional_properties flag)
+static inline void _add_method_additional_properties(ir_type *method, mtp_additional_properties properties)
{
assert(method->type_op == type_method);
-
- /* do not allow to set the mtp_property_inherited flag or
- * the automatic inheritance of flags will not work */
- method->attr.ma.additional_properties |= flag & ~mtp_property_inherited;
+ method->attr.ma.properties |= properties;
}
static inline unsigned _get_method_calling_convention(const ir_type *method)