ir_node *get_atomic_ent_value(const ir_entity *entity) { ir_initializer_t *initializer = get_entity_initializer(entity); assert(is_atomic_entity(entity)); if (initializer == NULL) { ir_type *type = get_entity_type(entity); return new_r_Unknown(get_const_code_irg(), get_type_mode(type)); } switch (get_initializer_kind(initializer)) { case IR_INITIALIZER_NULL: { ir_type *type = get_entity_type(entity); ir_mode *mode = get_type_mode(type); return new_r_Const(get_const_code_irg(), get_mode_null(mode)); } case IR_INITIALIZER_TARVAL: { ir_tarval *tv = get_initializer_tarval_value(initializer); return new_r_Const(get_const_code_irg(), tv); } case IR_INITIALIZER_CONST: return get_initializer_const_value(initializer); case IR_INITIALIZER_COMPOUND: panic("compound initializer in atomic entity not allowed (%+F)", entity); } panic("invalid initializer kind (%+F)", entity); }
ir_entity *new_d_entity(ir_type *owner, ident *name, ir_type *type, dbg_info *db) { ir_entity *res; if (is_Method_type(type)) { ir_graph *irg = get_const_code_irg(); symconst_symbol sym; 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_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 (is_compound_type(owner) && !(owner->flags & tf_segment)) { res = intern_new_entity(owner, IR_ENTITY_COMPOUND_MEMBER, name, type, db); } else { res = intern_new_entity(owner, IR_ENTITY_NORMAL, name, type, db); } hook_new_entity(res); return res; }
static bool constant_on_correct_irg(ir_node *n) { myenv env; env.fine = true; env.irg = get_const_code_irg(); irg_walk(n, on_irg_storage, NULL, (void *)&env); return env.fine; }
static void set_compound_init_entref(ir_initializer_t *init, size_t idx, ir_entity *entity) { if (entity == NULL) { set_compound_init_null(init, idx); return; } ir_graph *ccode = get_const_code_irg(); ir_node *node = new_r_Address(ccode, entity); set_compound_init_node(init, idx, node); }
ir_initializer_t *create_initializer_tarval(ir_tarval *tv) { struct obstack *obst = get_irg_obstack(get_const_code_irg()); ir_initializer_t *initializer = (ir_initializer_t*)OALLOC(obst, ir_initializer_tarval_t); initializer->kind = IR_INITIALIZER_TARVAL; initializer->tarval.value = tv; return initializer; }
ir_initializer_t *create_initializer_const(ir_node *value) { struct obstack *obst = get_irg_obstack(get_const_code_irg()); ir_initializer_t *initializer = (ir_initializer_t*)OALLOC(obst, ir_initializer_const_t); initializer->kind = IR_INITIALIZER_CONST; initializer->consti.value = value; return initializer; }
void analyze_irg_args(ir_graph *irg) { if (irg == get_const_code_irg()) return; ir_entity *entity = get_irg_entity(irg); if (! entity) return; if (! entity->attr.mtd_attr.param_access) analyze_ent_args(entity); }
/** * count the DAG's size of a graph * * @param global the global entry * @param graph the current graph entry */ void count_dags_in_graph(graph_entry_t *global, graph_entry_t *graph) { dag_env_t root_env; dag_entry_t *entry; unsigned id; (void) global; /* do NOT check the const code irg */ if (graph->irg == get_const_code_irg()) return; /* first step, clear the links */ irg_walk_graph(graph->irg, firm_clear_link, NULL, NULL); obstack_init(&root_env.obst); root_env.num_of_dags = 0; root_env.list_of_dags = NULL; root_env.options = FIRMSTAT_COPY_CONSTANTS | FIRMSTAT_LOAD_IS_LEAVE | FIRMSTAT_CALL_IS_LEAVE; /* find the DAG roots that are referenced from other block */ irg_walk_graph(graph->irg, NULL, find_dag_roots, &root_env); /* connect and count them */ irg_walk_graph(graph->irg, connect_dags, NULL, &root_env); printf("Graph %p %s --- %u\n", (void *)graph->irg, get_entity_name(get_irg_entity(graph->irg)), root_env.num_of_dags); for (id = 0, entry = root_env.list_of_dags; entry; entry = entry->next) { if (entry->is_dead) continue; entry->id = id++; printf("number of roots %u number of nodes %u inner %u tree %u %ld\n", entry->num_roots, entry->num_nodes, entry->num_inner_nodes, (unsigned)entry->is_tree, get_irn_node_nr(entry->root)); } /* dump for test */ mark_options = root_env.options; set_dump_node_vcgattr_hook(stat_dag_mark_hook); dump_ir_graph(graph->irg, "dag"); set_dump_node_vcgattr_hook(NULL); assert(id == root_env.num_of_dags); obstack_free(&root_env.obst, NULL); }
static ir_node *get_vtable_ref(ir_type *type) { ir_entity *cls_vtable = oo_get_class_vtable_entity(type); if (cls_vtable == NULL) return NULL; ir_graph *ccode = get_const_code_irg(); ir_node *addr = new_r_Address(ccode, cls_vtable); unsigned offset = ddispatch_get_vptr_points_to_index() * get_mode_size_bytes(mode_reference); ir_mode *offset_mode = get_reference_offset_mode(mode_reference); ir_node *cnst = new_r_Const_long(ccode, offset_mode, offset); ir_node *block = get_r_cur_block(ccode); ir_node *add = new_r_Add(block, addr, cnst); return add; }
static void add_pointer_in_jcr_segment(ir_entity *entity) { if (!create_jcr_segment) return; ir_type *segment = get_segment_type(IR_SEGMENT_JCR); ident *id = id_unique("jcr_ptr"); ir_entity *ptr = new_entity(segment, id, type_reference); ir_graph *irg = get_const_code_irg(); ir_node *val = new_r_Address(irg, entity); set_entity_ld_ident(ptr, new_id_from_chars("", 0)); set_entity_visibility(ptr, ir_visibility_private); set_entity_linkage(ptr, IR_LINKAGE_CONSTANT|IR_LINKAGE_HIDDEN_USER); set_entity_alignment(ptr, 1); ir_initializer_t *const init = create_initializer_const(val); set_entity_initializer(ptr, init); }
ir_initializer_t *create_initializer_compound(size_t n_entries) { struct obstack *obst = get_irg_obstack(get_const_code_irg()); size_t size = sizeof(ir_initializer_compound_t) + n_entries * sizeof(ir_initializer_t*) - sizeof(ir_initializer_t*); ir_initializer_t *initializer = (ir_initializer_t*)obstack_alloc(obst, size); initializer->kind = IR_INITIALIZER_COMPOUND; initializer->compound.n_initializers = n_entries; for (size_t i = 0; i < n_entries; ++i) { initializer->compound.initializers[i] = get_initializer_null(); } return initializer; }
static ir_entity *create_ent(ir_entity **const dst, int value, const char *name) { if (!*dst) { ir_mode *const mode = mode_Hu; ir_type *const type = new_type_primitive(mode); set_type_alignment_bytes(type, 4); ir_type *const glob = get_glob_type(); ident *const id = new_id_from_str(name); ir_entity *const ent = new_entity(glob, id, type); set_entity_ld_ident(ent, id); set_entity_visibility(ent, ir_visibility_local); add_entity_linkage(ent, IR_LINKAGE_CONSTANT); ir_graph *const cnst_irg = get_const_code_irg(); ir_node *const cnst = new_r_Const_long(cnst_irg, mode, value); set_atomic_ent_value(ent, cnst); *dst = ent; } return *dst; }
static ir_initializer_t *get_field_desc(ir_type *classtype, ir_entity *ent) { class_t *linked_class = (class_t*) oo_get_type_link(classtype); field_t *linked_field = (field_t*) oo_get_entity_link(ent); assert(linked_class && linked_field); constant_t *name_const = linked_class->constants[linked_field->name_index]; ir_entity *name_ent = gcji_emit_utf8_const(name_const, 1); ir_type *field_type = get_entity_type(ent); ir_entity *rtti_entity = gcji_get_rtti_entity(field_type); if (rtti_entity == NULL) { rtti_entity = emit_type_signature(field_type); } ir_graph *ccode = get_const_code_irg(); ir_node *bsize = new_r_Size(ccode, mode_ushort, field_type); ir_initializer_t *offset_addr_init = create_initializer_compound(2); if (linked_field->access_flags & ACCESS_FLAG_STATIC) { set_compound_init_null(offset_addr_init, 0); set_compound_init_entref(offset_addr_init, 1, ent); } else { ir_node *offset = new_r_Offset(ccode, mode_int, ent); set_compound_init_node(offset_addr_init, 0, offset); set_compound_init_null(offset_addr_init, 1); } unsigned NUM_FIELDS = 5; ir_initializer_t *init = create_initializer_compound(NUM_FIELDS); size_t f = 0; set_compound_init_entref(init, f++, name_ent); set_compound_init_entref(init, f++, rtti_entity); set_compound_init_num(init, f++, mode_ushort, linked_field->access_flags); set_compound_init_node(init, f++, bsize); set_initializer_compound_value(init, f++, offset_addr_init); assert(f == NUM_FIELDS); return init; }
void gcji_setup_rtti_entity(class_t *cls, ir_type *type) { ir_entity *rtti_entity = oo_get_class_rtti_entity(type); assert(type_java_lang_class != NULL); set_entity_type(rtti_entity, type_java_lang_class); ir_entity *name_ent = gcji_emit_utf8_const( cls->constants[cls->constants[cls->this_class]->classref.name_index], 1); uint16_t accflags = cls->access_flags; ir_entity *method_table = emit_method_table(type); ir_entity *field_table = emit_field_table(type); ir_graph *ccode = get_const_code_irg(); ir_node *size_in_bytes = new_r_Size(ccode, mode_int, type); int16_t field_count = cls->n_fields; int16_t static_field_count = 0; for (int16_t i = 0; i < field_count; i++) { if ((cls->fields[i]->access_flags & ACCESS_FLAG_STATIC) != 0) ++static_field_count; } ir_entity *superclass_rtti = NULL; if (get_class_n_supertypes(type) > 0) { ir_type *superclass = get_class_supertype(type, 0); /* TODO: search for first non-interface instead of taking the * first one and hoping it is a non-interface */ assert(!oo_get_class_is_interface(superclass)); superclass_rtti = gcji_get_rtti_entity(superclass); } ir_node *vtable_init = get_vtable_ref(type); int16_t interface_count = cls->n_interfaces; ir_entity *interfaces = emit_interface_table(type); // w/o slots 0=rtti. see lower_oo.c int16_t vtable_method_count = oo_get_class_vtable_size(type) - (ddispatch_get_index_of_first_method() - ddispatch_get_vptr_points_to_index()); ir_node *class_vtable = get_vtable_ref(type_java_lang_class); /* initializer for base class java.lang.Object */ ir_initializer_t *base_init = create_initializer_compound(1); set_compound_init_node(base_init, 0, class_vtable); /* initializer for java.lang.Class */ unsigned NUM_FIELDS = 39; ir_initializer_t *init = create_initializer_compound(NUM_FIELDS); size_t f = 0; set_initializer_compound_value(init, f++, base_init); set_compound_init_num(init, f++, mode_P, 407000); set_compound_init_entref(init, f++, name_ent); set_compound_init_num(init, f++, mode_ushort, accflags); set_compound_init_entref(init, f++, superclass_rtti); // _Jv_Constants inlined. not sure if this is needed for compiled code. set_compound_init_null(init, f++); set_compound_init_null(init, f++); set_compound_init_null(init, f++); set_compound_init_entref(init, f++, method_table); set_compound_init_num(init, f++, mode_short, cls->n_methods); set_compound_init_num(init, f++, mode_short, vtable_method_count); set_compound_init_entref(init, f++, field_table); set_compound_init_node(init, f++, size_in_bytes); set_compound_init_num(init, f++, mode_short, field_count); set_compound_init_num(init, f++, mode_short, static_field_count); set_compound_init_node(init, f++, vtable_init); // most of the following fields are set at runtime during the class linking. set_compound_init_null(init, f++); set_compound_init_null(init, f++); set_compound_init_null(init, f++); set_compound_init_null(init, f++); set_compound_init_null(init, f++); set_compound_init_null(init, f++); set_compound_init_null(init, f++); set_compound_init_entref(init, f++, interfaces); set_compound_init_null(init, f++); set_compound_init_num(init, f++, mode_short, interface_count); set_compound_init_num(init, f++, mode_byte, 1); // state set_compound_init_null(init, f++); set_compound_init_null(init, f++); set_compound_init_null(init, f++); set_compound_init_null(init, f++); set_compound_init_null(init, f++); set_compound_init_null(init, f++); set_compound_init_null(init, f++); set_compound_init_null(init, f++); set_compound_init_null(init, f++); set_compound_init_null(init, f++); set_compound_init_null(init, f++); // engine set_compound_init_null(init, f++); assert(f == NUM_FIELDS); set_entity_initializer(rtti_entity, init); set_entity_alignment(rtti_entity, 32); add_pointer_in_jcr_segment(rtti_entity); }