Commit a207bef2 authored by Matthias Braun's avatar Matthias Braun
Browse files

Remove the whole type op concept

The simple tp_opcode enum is enough, no need to have dispatch tables and
information structs behind each type kind.
parent f119db24
......@@ -248,7 +248,6 @@ set(SOURCES
ir/stat/stat_timing.c
ir/stat/statev.c
ir/tr/entity.c
ir/tr/tpop.c
ir/tr/tr_inheritance.c
ir/tr/trverify.c
ir/tr/type.c
......
......@@ -728,18 +728,6 @@ ENUM_BITSET(ptr_access_kind)
* @{
*/
/**
* @defgroup tp_op Type Opcodes
* This module specifies the kinds of types available in firm.
*
* They are called type opcodes. These include classes, structs, methods,
* unions, arrays, pointers and primitive types.
* Special types with own opcodes are the id type, a type representing an
* unknown type and a type used to specify that something has no type.
*
* @{
*/
/**
* An enum for the type kinds.
* For each type kind exists a typecode to identify it.
......@@ -759,33 +747,9 @@ typedef enum tp_opcode {
} tp_opcode;
/**
* A structure containing information about a kind of type.
* A structure containing information about a kind of type. So far
* this is only the kind name, an enum for case-switching and some
* internal values.
*
* @see get_tpop_name(), get_tpop_code()
*/
typedef struct tp_op tp_op;
/**
* Returns the string for the type opcode.
*
* @param op The type opcode to get the string from.
* @return a string.
*/
FIRM_API const char *get_tpop_name(const tp_op *op);
/**
* Returns an enum for the type opcode.
*
* @param op The type opcode to get the enum from.
* @return the enum.
* Returns the name of the type opcode @p opcode.
*/
FIRM_API tp_opcode get_tpop_code(const tp_op *op);
/** @} */
FIRM_API const char *get_type_opcode_name(tp_opcode opcode);
/** Returns true if low is subclass of high.
*
......@@ -939,14 +903,8 @@ FIRM_API int tr_verify(void);
*/
FIRM_API void free_type(ir_type *tp);
/** Returns type opcode of type @p tp */
FIRM_API const tp_op *get_type_tpop(const ir_type *tp);
/** Returns name identifier of type opcode of type @p tp */
FIRM_API ident *get_type_tpop_nameid(const ir_type *tp);
/** Returns name of type opcode of type @p tp */
FIRM_API const char *get_type_tpop_name(const ir_type *tp);
/** Returns opcode of type opcode of type @p tp */
FIRM_API tp_opcode get_type_tpop_code(const ir_type *tp);
/** Returns opcode of type @p type */
FIRM_API tp_opcode get_type_opcode(const ir_type *type);
/**
* construct a string representing the type.
......@@ -1175,18 +1133,6 @@ FIRM_API void remove_class_supertype(ir_type *clss, ir_type *supertype);
/** Returns true if a type is a class type. */
FIRM_API int is_Class_type(const ir_type *clss);
/**
* This type opcode marks that the corresponding type is a class type.
*
* Consequently the type refers to supertypes, subtypes and entities.
* Entities can be any fields, but also methods.
* This struct is dynamically allocated but constant for the lifetime
* of the library.
*/
FIRM_API const tp_op *type_class;
/** Returns type opcode for class type. @see type_class */
FIRM_API const tp_op *get_tpop_class(void);
/** @} */
/** @ingroup compound_type
......@@ -1229,19 +1175,6 @@ FIRM_API size_t get_struct_member_index(ir_type const *strct,
/** Returns true if a type is a struct type. */
FIRM_API int is_Struct_type(const ir_type *strct);
/**
* This type opcode marks that the corresponding type is a compound type
* as a struct in C.
*
* Consequently the type refers to a list of entities
* which may not be methods (but pointers to methods).
* This struct is dynamically allocated but constant for the lifetime
* of the library.
*/
FIRM_API const tp_op *type_struct;
/** Returns type opcode for struct type. @see type_struct */
FIRM_API const tp_op *get_tpop_struct(void);
/** @} */
/**
......@@ -1280,17 +1213,6 @@ FIRM_API size_t get_union_member_index(ir_type const *uni,
/** Returns true if a type is a union type. */
FIRM_API int is_Union_type(const ir_type *uni);
/**
* This type opcode marks that the corresponding type is a union type.
*
* Consequently it refers to a list of unioned types.
* This struct is dynamically allocated but constant for the lifetime
* of the library.
*/
FIRM_API const tp_op *type_union;
/** Returns type opcode for union type. @see type_union */
FIRM_API const tp_op *get_tpop_union(void);
/** @} */
/**
......@@ -1442,17 +1364,6 @@ FIRM_API void set_method_n_regparams(ir_type *method, unsigned n_regs);
/** Returns true if a type is a method type. */
FIRM_API int is_Method_type(const ir_type *method);
/**
* This type opcode marks that the corresponding type is a method type.
*
* Consequently it refers to a list of arguments and results.
* This struct is dynamically allocated but constant for the lifetime
* of the library.
*/
FIRM_API const tp_op *type_method;
/** Returns type opcode for method type @see type_method */
FIRM_API const tp_op *get_tpop_method(void);
/** @} */
/**
......@@ -1503,18 +1414,6 @@ FIRM_API int is_array_variable_size(const ir_type *array);
/** Returns true if a type is an array type. */
FIRM_API int is_Array_type(const ir_type *array);
/**
* This type opcode marks that the corresponding type is an array type.
*
* Consequently it contains a list of dimensions (lower and upper bounds)
* and an element type.
* This struct is dynamically allocated but constant for the lifetime
* of the library.
*/
FIRM_API const tp_op *type_array;
/** Returns type opcode for array type. @see type_array */
FIRM_API const tp_op *get_tpop_array(void);
/** @} */
/**
......@@ -1545,17 +1444,6 @@ FIRM_API int is_Pointer_type(const ir_type *pointer);
* If not found returns firm_unknown_type. */
FIRM_API ir_type *find_pointer_type_to_type(ir_type *tp);
/**
* This type opcode marks that the corresponding type is a pointer type.
*
* It contains a reference to the type the pointer points to.
* This struct is dynamically allocated but constant for the lifetime
* of the library.
*/
FIRM_API const tp_op *type_pointer;
/** Returns type opcode for pointer type. @see type_pointer */
FIRM_API const tp_op *get_tpop_pointer(void);
/** @} */
/**
......@@ -1572,18 +1460,6 @@ FIRM_API ir_type *new_type_primitive(ir_mode *mode);
/** Returns true if a type is a primitive type. */
FIRM_API int is_Primitive_type(const ir_type *primitive);
/**
* This type opcode marks that the corresponding type is a primitive type.
*
* Primitive types are types that are directly mapped to target machine
* modes.
* This struct is dynamically allocated but constant for the lifetime
* of the library.
*/
FIRM_API const tp_op *type_primitive;
/** Returns type opcode for primitive type. @see type_primitive */
FIRM_API const tp_op *get_tpop_primitive(void);
/** @} */
/** @defgroup code_type Code
......@@ -1595,12 +1471,6 @@ FIRM_API ir_type *get_code_type(void);
* Checks whether a type is a code type.
*/
FIRM_API int is_code_type(const ir_type *tp);
/**
* The code type is used to mark pieces of code (basic blocks)
*/
FIRM_API const tp_op *tpop_code;
/** Returns type opcode for code type. @see tpop_code */
FIRM_API const tp_op *get_tpop_code_type(void);
/** @} */
/**
......@@ -1625,17 +1495,6 @@ FIRM_API const tp_op *get_tpop_code_type(void);
FIRM_API ir_type *get_unknown_type(void);
/** Checks whether type @p type is the unknown type */
FIRM_API int is_unknown_type(const ir_type *type);
/**
* This type opcode is an auxiliary opcode dedicated to support type analyses.
*
* Types with this opcode represents that there could be a type, but it is not
* known. This type can be used to initialize fields before an analysis (not known
* yet) or to represent the top of a lattice (could not be determined). There exists
* exactly one type with this opcode.
*/
FIRM_API const tp_op *tpop_unknown;
/** Returns type opcode for unknown type. @see tpop_unknown */
FIRM_API const tp_op *get_tpop_unknown(void);
/** @} */
/**
......
......@@ -768,17 +768,20 @@ static void emit_type(ir_type *type)
if (!pset_new_insert(&env.emitted_types, type))
return;
switch (get_type_tpop_code(type)) {
case tpo_primitive: emit_base_type(type); break;
case tpo_pointer: emit_pointer_type(type); break;
case tpo_array: emit_array_type(type); break;
switch (get_type_opcode(type)) {
case tpo_primitive: emit_base_type(type); return;
case tpo_pointer: emit_pointer_type(type); return;
case tpo_array: emit_array_type(type); return;
case tpo_class:
case tpo_struct:
case tpo_union: emit_compound_type(type); break;
case tpo_method: emit_subroutine_type(type); break;
default:
panic("type %+F not implemented yet", type);
case tpo_union: emit_compound_type(type); return;
case tpo_method: emit_subroutine_type(type); return;
case tpo_code:
case tpo_unknown:
case tpo_uninitialized:
panic("unexpected type %+F", type);
}
panic("invalid type");
}
static void emit_op_addr(const ir_entity *entity)
......
......@@ -20,7 +20,6 @@
#include "firm.h"
#include "irflag_t.h"
#include "tv_t.h"
#include "tpop_t.h"
#include "irprog_t.h"
#include "irnode_t.h"
#include "irmode_t.h"
......@@ -52,7 +51,6 @@ void ir_init(void)
firm_init_flags();
init_ident();
init_edges();
init_tpop();
init_tarval_1();
/* Builds a basic program representation, so modes can be added. */
init_irprog_1();
......@@ -91,7 +89,6 @@ void ir_finish(void)
firm_finish_op();
finish_tarval();
finish_mode();
finish_tpop();
finish_ident();
}
......
......@@ -126,8 +126,9 @@ static int firm_emit(lc_appendable_t *app, const lc_arg_occ_t *occ,
ir_type *type = (ir_type*)X;
char type_name[256];
ir_print_type(type_name, sizeof(type_name), type);
tp_opcode opcode = get_type_opcode(type);
snprintf(buf, sizeof(buf), "%s%s:%s", A("type"),
get_type_tpop_name(type), type_name);
get_type_opcode_name(opcode), type_name);
snprintf(add, sizeof(add), "[%ld]", get_type_nr(type));
break;
}
......
......@@ -39,6 +39,7 @@
#include "array.h"
#include "pmap.h"
#include "obst.h"
#include "panic.h"
#include "pset.h"
#include "util.h"
......@@ -1404,7 +1405,8 @@ void dump_type_node(FILE *F, ir_type *tp)
if (tp->dbi != NULL) {
char buf[1024];
ir_print_type(buf, sizeof(buf), tp);
fprintf(F, "%s '%s'", get_type_tpop_name(tp), buf);
tp_opcode opcode = get_type_opcode(tp);
fprintf(F, "%s '%s'", get_type_opcode_name(opcode), buf);
} else {
ir_fprintf(F, "%+F", tp);
}
......@@ -1459,7 +1461,7 @@ static void dump_type_info(ir_type *const tp, ir_entity *const ent, void *const
} else {
dump_type_node(F, tp);
/* and now the edges */
switch (get_type_tpop_code(tp)) {
switch (get_type_opcode(tp)) {
case tpo_class:
for (size_t i = get_class_n_supertypes(tp); i-- > 0;) {
print_type_type_edge(F, tp, get_class_supertype(tp, i), TYPE_SUPER_EDGE_ATTR);
......@@ -1471,7 +1473,7 @@ static void dump_type_info(ir_type *const tp, ir_entity *const ent, void *const
ir_entity const *const entity = get_compound_member(tp, i);
print_type_ent_edge(F, tp, entity, TYPE_MEMBER_EDGE_ATTR);
}
break;
return;
case tpo_method:
for (size_t i = get_method_n_params(tp); i-- > 0;) {
print_type_type_edge(F, tp, get_method_param_type(tp, i), METH_PAR_EDGE_ATTR,i);
......@@ -1479,22 +1481,23 @@ static void dump_type_info(ir_type *const tp, ir_entity *const ent, void *const
for (size_t i = get_method_n_ress(tp); i-- > 0;) {
print_type_type_edge(F, tp, get_method_res_type(tp, i), METH_RES_EDGE_ATTR,i);
}
break;
return;
case tpo_array:
print_type_type_edge(F, tp, get_array_element_type(tp), ARR_ELT_TYPE_EDGE_ATTR);
ir_node *size = get_array_size(tp);
print_node_type_edge(F, size, tp, "label: \"size\"");
dump_const_expression(F, size);
break;
return;
case tpo_pointer:
print_type_type_edge(F, tp, get_pointer_points_to_type(tp), PTR_PTS_TO_EDGE_ATTR);
break;
return;
case tpo_unknown:
case tpo_code:
case tpo_uninitialized:
case tpo_primitive:
break;
return;
}
panic("invalid type");
}
}
......@@ -1524,16 +1527,13 @@ static void dump_class_hierarchy_node(ir_type *const tp, ir_entity *const ent, v
} else {
if (tp == get_glob_type())
return;
switch (get_type_tpop_code(tp)) {
case tpo_class:
if (is_Class_type(tp)) {
dump_type_node(F, tp);
/* and now the edges */
for (size_t i = get_class_n_supertypes(tp); i-- > 0;) {
print_type_type_edge(F,tp,get_class_supertype(tp, i),TYPE_SUPER_EDGE_ATTR);
print_type_type_edge(F, tp, get_class_supertype(tp, i),
TYPE_SUPER_EDGE_ATTR);
}
break;
default:
break;
}
}
}
......
......@@ -670,12 +670,9 @@ static void dump_compound_members(FILE *const F, ir_type const *const type)
}
}
void dump_type_to_file(FILE *const F, const ir_type *const tp)
static void dump_type_details(FILE *const F, ir_type const *const tp)
{
ir_fprintf(F, "%+F", tp);
if (verbosity & dump_verbosity_onlynames) { fprintf(F, "\n"); return; }
switch (get_type_tpop_code(tp)) {
switch (get_type_opcode(tp)) {
case tpo_class:
dump_compound_members(F, tp);
if (verbosity & dump_verbosity_typeattrs) {
......@@ -703,12 +700,12 @@ void dump_type_to_file(FILE *const F, const ir_type *const tp)
}
}
}
break;
return;
case tpo_union:
case tpo_struct:
dump_compound_members(F, tp);
break;
return;
case tpo_array:
if (verbosity & dump_verbosity_typeattrs) {
......@@ -726,14 +723,14 @@ void dump_type_to_file(FILE *const F, const ir_type *const tp)
ir_fprintf(F, "] of <%+F>", elem_tp);
fprintf(F, "\n");
}
break;
return;
case tpo_pointer:
if (verbosity & dump_verbosity_typeattrs) {
const ir_type *tt = get_pointer_points_to_type(tp);
ir_fprintf(F, "\n points to %+F\n", tt);
}
break;
return;
case tpo_method:
if (verbosity & dump_verbosity_typeattrs) {
......@@ -762,18 +759,24 @@ void dump_type_to_file(FILE *const F, const ir_type *const tp)
print_bitflags(F, cc_names, (unsigned)cconv);
fprintf(F, "\n");
}
break;
return;
case tpo_primitive:
case tpo_unknown:
case tpo_code:
case tpo_uninitialized:
fprintf(F, "\n");
break;
default:
if (verbosity & dump_verbosity_typeattrs) {
fprintf(F, ": details not implemented\n");
}
return;
}
panic("invalid type");
}
void dump_type_to_file(FILE *const F, const ir_type *const tp)
{
ir_fprintf(F, "%+F", tp);
if (verbosity & dump_verbosity_onlynames) { fprintf(F, "\n"); return; }
dump_type_details(F, tp);
fprintf(F, " state: %s,\n", get_type_state_name(get_type_state(tp)));
fprintf(F, " size: %2u Bytes,\n", get_type_size_bytes(tp));
......
......@@ -366,7 +366,7 @@ static void write_entity_ref(write_env_t *env, ir_entity *entity)
static void write_type_ref(write_env_t *env, ir_type *type)
{
switch (get_type_tpop_code(type)) {
switch (get_type_opcode(type)) {
case tpo_unknown:
write_symbol(env, "unknown");
return;
......@@ -554,7 +554,7 @@ static void write_type_common(write_env_t *env, ir_type *tp)
fputc('\t', env->file);
write_symbol(env, "type");
write_long(env, get_type_nr(tp));
write_symbol(env, get_type_tpop_name(tp));
write_symbol(env, get_type_opcode_name(get_type_opcode(tp)));
write_unsigned(env, get_type_size_bytes(tp));
write_unsigned(env, get_type_alignment_bytes(tp));
write_type_state(env, get_type_state(tp));
......@@ -664,7 +664,7 @@ static void write_type(write_env_t *env, ir_type *tp)
return;
mark_type_visited(tp);
switch ((tp_opcode)get_type_tpop_code(tp)) {
switch (get_type_opcode(tp)) {
case tpo_unknown:
case tpo_code:
case tpo_uninitialized:
......@@ -1640,14 +1640,14 @@ static ir_initializer_t *read_initializer(read_env_t *env)
static void read_type(read_env_t *env)
{
long typenr = read_long(env);
tp_opcode tpop = (tp_opcode) read_enum(env, tt_tpo);
tp_opcode opcode = (tp_opcode) read_enum(env, tt_tpo);
unsigned size = (unsigned) read_long(env);
unsigned align = (unsigned) read_long(env);
ir_type_state state = read_type_state(env);
unsigned flags = (unsigned) read_long(env);
ir_type *type;
switch (tpop) {
switch (opcode) {
case tpo_array: {
ir_type *elemtype = read_type_ref(env);
type = new_type_array(elemtype);
......@@ -1734,10 +1734,10 @@ static void read_type(read_env_t *env)
case tpo_code:
case tpo_unknown:
case tpo_uninitialized:
parse_error(env, "can't import this type kind (%d)", tpop);
parse_error(env, "can't import this type kind (%d)", opcode);
return;
}
parse_error(env, "unknown type kind: \"%d\"\n", tpop);
parse_error(env, "unknown type kind: \"%d\"\n", opcode);
skip_to(env, '\n');
return;
......
......@@ -761,18 +761,16 @@ int is_unknown_entity(const ir_entity *entity)
int is_atomic_entity(const ir_entity *ent)
{
ir_type *t = get_entity_type(ent);
const tp_op *op = get_type_tpop(t);
return op == type_primitive || op == type_pointer
|| op == type_method;
ir_type const *const type = get_entity_type(ent);
tp_opcode const opcode = get_type_opcode(type);
return opcode == tpo_primitive || opcode == tpo_pointer
|| opcode == tpo_method;
}
int is_compound_entity(const ir_entity *ent)
{
ir_type *t = get_entity_type(ent);
const tp_op *op = get_type_tpop(t);
return (op == type_class || op == type_struct ||
op == type_array || op == type_union);
ir_type const *const type = get_entity_type(ent);
return is_compound_type(type);
}
int is_method_entity(const ir_entity *ent)
......
/*
* This file is part of libFirm.
* Copyright (C) 2012 University of Karlsruhe.
*/
/**
* @file
* @brief Opcode of types.
* @author Goetz Lindenmaier, Michael Beck
*/
#include "ident_t.h"
#include "xmalloc.h"
#include "tpop_t.h"
#include "type_t.h"
const tp_op *type_class; const tp_op *get_tpop_class (void) { return type_class; }
const tp_op *type_struct; const tp_op *get_tpop_struct (void) { return type_struct; }
const tp_op *type_method; const tp_op *get_tpop_method (void) { return type_method; }
const tp_op *type_union; const tp_op *get_tpop_union (void) { return type_union; }
const tp_op *type_array; const tp_op *get_tpop_array (void) { return type_array; }
const tp_op *type_pointer; const tp_op *get_tpop_pointer (void) { return type_pointer; }
const tp_op *type_primitive; const tp_op *get_tpop_primitive(void) { return type_primitive; }
const tp_op *tpop_code; const tp_op *get_tpop_code_type(void) { return tpop_code; }
const tp_op *tpop_unknown; const tp_op *get_tpop_unknown (void) { return tpop_unknown; }
const tp_op *new_tpop(tp_opcode code, ident *name, size_t attr_size)
{
tp_op *res = XMALLOC(tp_op);
res->code = code;
res->name = name;
res->attr_size = attr_size;
return res;
}
void free_tpop(const tp_op *tpop)
{
free((void*)tpop);
}
void init_tpop(void)
{
type_class = new_tpop(tpo_class, NEW_IDENT("class"), sizeof(cls_attr) );
type_struct = new_tpop(tpo_struct, NEW_IDENT("struct"), sizeof(compound_attr));
type_method = new_tpop(tpo_method, NEW_IDENT("method"), sizeof(mtd_attr) );
type_union = new_tpop(tpo_union, NEW_IDENT("union"), sizeof(compound_attr));
type_array = new_tpop(tpo_array, NEW_IDENT("array"), sizeof(arr_attr) );
type_pointer = new_tpop(tpo_pointer, NEW_IDENT("pointer"), sizeof(ptr_attr) );
type_primitive = new_tpop(tpo_primitive, NEW_IDENT("primitive"), 0 );
tpop_code = new_tpop(tpo_code, NEW_IDENT("code"), 0 );
tpop_unknown = new_tpop(tpo_unknown, NEW_IDENT("Unknown"), 0 );
}
void finish_tpop(void)
{
free_tpop(type_class ); type_class = NULL;
free_tpop(type_struct ); type_struct = NULL;
free_tpop(type_method ); type_method = NULL;
free_tpop(type_union ); type_union = NULL;
free_tpop(type_array ); type_array = NULL;
free_tpop(type_pointer ); type_pointer = NULL;
free_tpop(type_primitive); type_primitive = NULL;
free_tpop(tpop_code ); tpop_code = NULL;
free_tpop(tpop_unknown ); tpop_unknown = NULL;
}
const char *get_tpop_name(const tp_op *op)
{
return get_id_str(op->name);
}
tp_opcode (get_tpop_code)(const tp_op *op)
{
return _get_tpop_code(op);
}
/*
* This file is part of libFirm.
* Copyright (C) 2012 University of Karlsruhe.
*/
/**
* @file