X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fexternal%2Fread.c;h=388b570054aba39dffd66fe2405674c30fa6bf16;hb=5af0c3e521bf6375f0249b661605f9f5570c6e4e;hp=340ccf5223031c0176116e6a6047d06f3315bfaf;hpb=957f55e9d65646269f76d0f6c34e5f90217ecfd7;p=libfirm diff --git a/ir/external/read.c b/ir/external/read.c index 340ccf522..388b57005 100644 --- a/ir/external/read.c +++ b/ir/external/read.c @@ -1,5 +1,6 @@ /* -*- c -*- */ + /* * Project: libFIRM * File name: ir/external/read.c @@ -23,16 +24,38 @@ #ifdef HAVE_STDLIB_H # include #endif +#ifdef HAVE_STRING_H +# include +#endif + +#include -# include "read.h" +#include +#include +#include + +#include "read_t.h" +#include "read.h" #include "irprog.h" #include "irgraph.h" +#include "pseudo_irg.h" #include "ircons.h" #include "irmode.h" #include "irdump.h" #include "irvrfy.h" #include "type.h" #include "tv.h" +#include "xmalloc.h" + +# define MY_ENCODING "ISO-8859-1" + +# define CHECK(ptr,msg) assert (ptr && msg) + +# define NODE_NAME(n, m) (0 == xmlStrcmp (n->name, (const xmlChar*) #m)) +# define CHECK_NAME(n, m) assert (0 == xmlStrcmp (n->name, (const xmlChar*) #m)) + +# define NEW(T) (T*)xmalloc(sizeof (T)) + #define VERBOSE_PRINTING 0 @@ -52,7 +75,9 @@ static module_t *modules = NULL; /* @@@ HACK */ static module_t *current_module = NULL; -static char *effect_string[] = { +#if VERBOSE_PRINTING +/* this is only used inside a VERBOSE_PRINT() call */ +static const char *effect_string[] = { "arg", "valref", "select", @@ -65,8 +90,9 @@ static char *effect_string[] = { "raise", "ret" }; +#endif /* defined VERBOSE_PRINTING */ -static const ident* +static ident* getNodeModuleIdent (xmlNodePtr node) { const char *mod_str = (const char*) xmlGetProp (node, BAD_CAST "module"); @@ -74,7 +100,7 @@ getNodeModuleIdent (xmlNodePtr node) if (NULL == mod_str) { return (NULL); } else { - const ident *res = new_id_from_str (mod_str); + ident *res = new_id_from_str (mod_str); return (res); } } @@ -87,6 +113,7 @@ getNodeProcName (xmlNodePtr node) return (proc_str); } +# ifdef NEEDED static char* getNodeClassName (xmlNodePtr node) { @@ -94,6 +121,7 @@ getNodeClassName (xmlNodePtr node) assert (proc_str); return ( (proc_str)); } +# endif /* defined NEEDED */ static const char* getNodeId (xmlNodePtr node) @@ -148,8 +176,9 @@ static const char /* was Public Interface */ +# ifdef NEEDED static -type_t *getTypeByIdent (const ident *id) +type_t *getTypeByIdent (ident *id) { type_t *curr = types; // @@@ TODO module -> types @@ -162,9 +191,11 @@ type_t *getTypeByIdent (const ident *id) return (NULL); } +# endif /* defined NEEDED */ +# ifdef NEEDED static -type_t *getTypeById (const ident *id) +type_t *getTypeById (ident *id) { type_t *curr = types; // which ones? @@ -177,15 +208,17 @@ type_t *getTypeById (const ident *id) return (NULL); } +# endif /* defined NEEDED */ +# ifdef NEEDED static -entity_t *getEntityByIdents (const ident *name, const ident *tp_ident) +entity_t *getEntityByIdents (ident *name, ident *tp_ident) { entity_t *curr = entities; // TODO module -> entities while (NULL != curr) { if ((name == curr -> ent_ident) - && (tp_ident == curr -> tp_ident)) { + && (tp_ident == curr -> tp_ident)) { return (curr); } curr = curr->prev; @@ -193,9 +226,10 @@ entity_t *getEntityByIdents (const ident *name, const ident *tp_ident) return (NULL); } +# endif /* defined NEEDED */ static -entity_t *getEntityById (const ident *id) +entity_t *getEntityById (ident *id) { entity_t *curr = entities; @@ -209,8 +243,9 @@ entity_t *getEntityById (const ident *id) return (NULL); } +# ifdef NEEDED static -proc_t *getEffectByName (const ident *proc_ident) +proc_t *getEffectByName (ident *proc_ident) { proc_t *curr_effs = procs; @@ -223,7 +258,30 @@ proc_t *getEffectByName (const ident *proc_ident) return (NULL); } +# endif /* defined NEEDED */ +static +xmlNodePtr get_any_valid_child(xmlNodePtr elem) +{ + xmlNodePtr child; + + assert(elem && "no element"); + child = elem -> xmlChildrenNode; + while(child && (NODE_NAME (child, comment))) { + child = child -> next; + } + return(child); +} + +static +xmlNodePtr get_valid_child(xmlNodePtr elem) +{ + xmlNodePtr child; + + child = get_any_valid_child(elem); + assert(child && "lost child in deep black forest"); + return(child); +} /* * parse XML structure and construct an additional structure @@ -257,8 +315,8 @@ parseArg (xmlDocPtr doc, xmlNodePtr argelm) return (arg); } -static eff_t -*parseValref (xmlDocPtr doc, xmlNodePtr valelm) +static eff_t* +parseValref (xmlDocPtr doc, xmlNodePtr valelm) { const char *ref_id; eff_t *valref; @@ -276,10 +334,10 @@ static eff_t return (valref); } -static eff_t -*parseSelect (xmlDocPtr doc, xmlNodePtr selelm) +static eff_t* +parseSelect (xmlDocPtr doc, xmlNodePtr selelm) { - const ident *entity_id = new_id_from_str(getNodeEntityStr (selelm)); + ident *entity_id = new_id_from_str(getNodeEntityStr (selelm)); entity_t *ent; xmlNodePtr child; eff_t *valref = NULL; @@ -309,10 +367,10 @@ static eff_t return (sel); } -static eff_t -*parseLoad (xmlDocPtr doc, xmlNodePtr loadelm) +static eff_t* +parseLoad (xmlDocPtr doc, xmlNodePtr loadelm) { - const ident *id; + ident *id; xmlNodePtr child; eff_t *sel; eff_t *load = NEW (eff_t); @@ -322,22 +380,28 @@ static eff_t VERBOSE_PRINT ((stdout, "load node \t0x%08x\n", (int) loadelm)); id = new_id_from_str(getNodeId (loadelm)); - child = loadelm->xmlChildrenNode; - sel = parseSelect (doc, child); + child = get_valid_child(loadelm); + if(NODE_NAME (child, select)) { + sel = parseSelect (doc, child); + load-> effect.load.ent = sel-> effect.select.ent; + VERBOSE_PRINT ((stdout, "load entity \t%s\n", + get_id_str(load -> effect.load.ent -> ent_ident))); + } + else { + sel = parseValref (doc, child); + load-> effect.load.ent = NULL; + } load-> id = id; load-> effect.load.ptrrefid = sel-> id; - load-> effect.load.ent = sel-> effect.select.ent; - VERBOSE_PRINT ((stdout, "load entity \t%s\n", - get_id_str(load -> effect.load.ent -> ent_ident))); free (sel); return (load); } -static eff_t -*parseStore (xmlDocPtr doc, xmlNodePtr storeelm) +static eff_t* +parseStore (xmlDocPtr doc, xmlNodePtr storeelm) { xmlNodePtr child; eff_t *sel; @@ -348,12 +412,19 @@ static eff_t CHECK_NAME (storeelm, store); VERBOSE_PRINT ((stdout, "store node \t0x%08x\n", (int) storeelm)); - child = storeelm->xmlChildrenNode; - sel = parseSelect (doc, child); + child = get_valid_child(storeelm); + if(NODE_NAME (child, select)) { + sel = parseSelect (doc, child); + store-> effect.store.ent = sel-> effect.select.ent; + } + else { + sel = parseValref (doc, child); + store-> effect.store.ent = NULL; + } + child = child->next; valref = parseValref (doc, child); - store-> effect.store.ent = sel-> effect.select.ent; store-> effect.store.ptrrefid = sel-> id; store-> effect.store.valrefid = valref-> id; @@ -363,11 +434,11 @@ static eff_t return (store); } -static eff_t -*parseAlloc (xmlDocPtr doc, xmlNodePtr allocelm) +static eff_t* +parseAlloc (xmlDocPtr doc, xmlNodePtr allocelm) { - const ident *id; - const ident *type_id; + ident *id; + ident *type_id; eff_t *alloc = NEW (eff_t); /* ...! */ alloc->kind = eff_alloc; @@ -384,10 +455,10 @@ static eff_t return (alloc); } -static eff_t -*parseCall (xmlDocPtr doc, xmlNodePtr callelm) +static eff_t* +parseCall (xmlDocPtr doc, xmlNodePtr callelm) { - const ident *id; + ident *id; xmlNodePtr child; eff_t *sel; xmlNodePtr arg; @@ -400,8 +471,16 @@ static eff_t id = new_id_from_str(getNodeId (callelm)); VERBOSE_PRINT ((stdout, "call->id = \"%s\"\n", get_id_str(id))); - child = callelm->xmlChildrenNode; - sel = parseSelect (doc, child); + child = get_valid_child(callelm); + if(NODE_NAME (child, select)) { + sel = parseSelect (doc, child); + call-> effect.call.ent = sel-> effect.select.ent; + } + else { + sel = parseValref (doc, child); + call-> effect.call.ent = NULL; + } + arg = child = child->next; n_args = 0; @@ -412,14 +491,13 @@ static eff_t call-> id = id; call-> effect.call.valrefid = sel-> id; - call-> effect.call.ent = sel-> effect.select.ent; call-> effect.call.n_args = n_args; call-> effect.call.args = NULL; free (sel); if (0 != n_args) { - const ident **args = (const ident**) malloc(n_args * sizeof(const ident*)); + ident **args = (ident**) xmalloc(n_args * sizeof(ident*)); int i = 0; while (NULL != arg) { @@ -435,12 +513,12 @@ static eff_t return (call); } -static eff_t -*parseJoin (xmlDocPtr doc, xmlNodePtr joinelm) +static eff_t* +parseJoin (xmlDocPtr doc, xmlNodePtr joinelm) { - const ident *id; + ident *id; int n_ins; - const ident **ins; + ident **ins; int i; xmlNodePtr child; eff_t *join = NEW (eff_t); @@ -451,7 +529,7 @@ static eff_t id = new_id_from_str(getNodeId (joinelm)); VERBOSE_PRINT ((stdout, "join->id = \"%s\"\n", get_id_str(id))); - child = joinelm->xmlChildrenNode; + child = get_valid_child(joinelm); n_ins = 0; while (NULL != child) { @@ -459,9 +537,9 @@ static eff_t child = child->next; } - ins = (const ident **) malloc (n_ins * sizeof (const ident *) ); + ins = (ident **) xmalloc (n_ins * sizeof (ident *) ); i = 0; - child = joinelm->xmlChildrenNode; + child = get_valid_child(joinelm); while (NULL != child) { eff_t *valref = parseValref (doc, child); @@ -477,10 +555,10 @@ static eff_t return (join); } -static eff_t -*parseUnknown (xmlDocPtr doc, xmlNodePtr unknownelm) +static eff_t* +parseUnknown (xmlDocPtr doc, xmlNodePtr unknownelm) { - const ident *id; + ident *id; eff_t *unknown = NEW (eff_t); unknown->kind = eff_unknown; @@ -492,8 +570,8 @@ static eff_t return (unknown); } -static eff_t -*parseReturn (xmlDocPtr doc, xmlNodePtr retelm) +static eff_t* +parseReturn (xmlDocPtr doc, xmlNodePtr retelm) { xmlNodePtr child; eff_t *ret = NEW (eff_t); @@ -502,7 +580,7 @@ static eff_t CHECK_NAME (retelm, ret); VERBOSE_PRINT ((stdout, "ret node \t0x%08x\n", (int) retelm)); - child = retelm->xmlChildrenNode; + child = get_any_valid_child(retelm); if (child) { eff_t *valref = parseValref (doc, child); @@ -515,8 +593,8 @@ static eff_t return (ret); } -static eff_t -*parseRaise (xmlDocPtr doc, xmlNodePtr raiseelm) +static eff_t* +parseRaise (xmlDocPtr doc, xmlNodePtr raiseelm) { const char *tp_id; eff_t *valref; @@ -528,7 +606,7 @@ static eff_t VERBOSE_PRINT ((stdout, "raise node \t0x%08x\n", (int) raiseelm)); tp_id = getNodeTypeId (raiseelm); VERBOSE_PRINT ((stdout, "raise->type = \"%s\"\n", tp_id)); - child = raiseelm->xmlChildrenNode; + child = get_valid_child(raiseelm); assert (NULL != child); @@ -554,7 +632,7 @@ parseType (xmlDocPtr doc, xmlNodePtr typeelm) VERBOSE_PRINT ((stdout, "type node \t0x%08x (%s)\n", (int) typeelm, tp_id)); VERBOSE_PRINT ((stdout, "type = \"%s\"\n", getNodeTypeStr (typeelm))); - type = (type_t*) malloc (sizeof (type_t)); + type = (type_t*) xmalloc (sizeof (type_t)); type -> type_ident = new_id_from_str(getNodeTypeStr (typeelm)); type -> id = new_id_from_str(tp_id); @@ -572,8 +650,8 @@ parseEntity (xmlDocPtr doc, xmlNodePtr entelm) const char *ent_id = getNodeId (entelm); /* fprintf (stdout, "entity node \t0x%08x (%d)\n", (int) entelm, ent_id); */ VERBOSE_PRINT ((stdout, "ent = \"%s.%s\"\n", - getNodeTypeStr (entelm), - getNodeEntityStr (entelm))); + getNodeTypeStr (entelm), + getNodeEntityStr (entelm))); ent -> ent_ident = new_id_from_str (getNodeEntityStr (entelm)); @@ -591,7 +669,7 @@ parseEffect (xmlDocPtr doc, xmlNodePtr effelm) { xmlNodePtr cur; const char *procname = getNodeProcName (effelm); - const char *typeid = getNodeTypeStr (effelm); + const char *ownerid = getNodeOwnerStr (effelm); proc_t *curr_effs = NULL; int i = 0; int n_effs = 0; @@ -607,8 +685,8 @@ parseEffect (xmlDocPtr doc, xmlNodePtr effelm) curr_effs = NEW (proc_t); curr_effs -> proc_ident = new_id_from_str(procname); - curr_effs -> typeid = new_id_from_str(typeid); - curr_effs->effs = (eff_t**) malloc (n_effs * sizeof (eff_t*)); + curr_effs -> ownerid = new_id_from_str(ownerid); + curr_effs->effs = (eff_t**) xmalloc (n_effs * sizeof (eff_t*)); cur = effelm -> xmlChildrenNode; while (NULL != cur) { @@ -653,7 +731,7 @@ parseEffect (xmlDocPtr doc, xmlNodePtr effelm) static -void read_extern (const char *filename) +int read_extern (const char *filename) { /* xmlNsPtr ns = NULL; */ /* no namespace for us */ xmlDocPtr doc; /* whole document */ @@ -666,7 +744,8 @@ void read_extern (const char *filename) LIBXML_TEST_VERSION xmlKeepBlanksDefault (0); VERBOSE_PRINT((stdout, "read file %s\n", filename)); doc = xmlParseFile (filename); - CHECK (doc, "xmlParseFile"); + if (! doc) + return 0; cur = xmlDocGetRootElement (doc); CHECK (cur, "xmlDocGetRootElement"); @@ -680,7 +759,7 @@ void read_extern (const char *filename) mod_id = getNodeModuleIdent (cur); if (NULL != mod_id) { VERBOSE_PRINT ((stdout, "effects for \"%s\"\n", - get_id_str(mod_id))); + get_id_str(mod_id))); } else { VERBOSE_PRINT ((stdout, "effects \t0x%08x\n", (int) cur)); @@ -716,6 +795,8 @@ void read_extern (const char *filename) module -> next = modules; modules = module; + + return 1; } /********************************************************************/ @@ -821,7 +902,7 @@ void freeProcEffs(proc_t *proc) int num; VERBOSE_PRINT ((stdout, "free effect for method \"%s\"\n", - get_id_str(proc -> proc_ident))); + get_id_str(proc -> proc_ident))); num = proc -> n_effs; for(i = 0; i < num; i++) { @@ -874,7 +955,7 @@ void freeModuleProcs(module_t *module) proc_t *next_proc, *proc; VERBOSE_PRINT ((stdout, "free procs for module \"%s\"\n", - get_id_str(module -> id))); + get_id_str(module -> id))); proc = module -> procs; while(proc) { @@ -902,7 +983,7 @@ void free_data(void) /********************************************************************/ static -type_t *find_type_in_module(module_t *module, const ident *typeid) +type_t *find_type_in_module(module_t *module, ident *typeid) { type_t *type; @@ -926,7 +1007,7 @@ static void add_value_to_proc(proc_t *proc, eff_t *eff) } -eff_t *find_valueid_in_proc_effects(const ident *id, proc_t *proc) +eff_t *find_valueid_in_proc_effects(ident *id, proc_t *proc) { eff_t *val; @@ -946,7 +1027,7 @@ static void create_abstract_return(ir_graph *irg, proc_t *proc, eff_t *eff) eff_t *eff_res; VERBOSE_PRINT((stdout, "create effect:return in %s\n", - get_id_str(proc -> proc_ident))); + get_id_str(proc -> proc_ident))); if(NO_ID == eff -> effect.ret.ret_id) { /* return void */ x = new_Return (get_store(), 0, NULL); @@ -977,11 +1058,11 @@ static void create_abstract_arg(ir_graph *irg, proc_t *proc, eff_t *eff) ir_node *arg; entity *ent; ir_mode *mode; - type *typ; + ir_type *typ; int num; VERBOSE_PRINT((stdout, "create effect:arg %d in %s\n", - eff -> effect.arg.num, get_id_str(proc -> proc_ident))); + eff -> effect.arg.num, get_id_str(proc -> proc_ident))); ent = get_irg_entity(irg); typ = get_entity_type(ent); @@ -1006,20 +1087,32 @@ static void create_abstract_load(ir_graph *irg, proc_t *proc, eff_t *eff) eff_t *addr; VERBOSE_PRINT((stdout, "create load in %s\n", - get_id_str(proc -> proc_ident))); + get_id_str(proc -> proc_ident))); - ent = eff -> effect.load.ent -> f_ent; - VERBOSE_PRINT((stdout, "load from %s\n", get_entity_name(ent))); + if(eff -> effect.load.ent) { + ent = eff -> effect.load.ent -> f_ent; + VERBOSE_PRINT((stdout, "load from %s\n", get_entity_name(ent))); + } + else { + VERBOSE_PRINT((stdout, "store to memory\n")); + ent = NULL; + } addr = find_valueid_in_proc_effects(eff -> effect.load.ptrrefid, proc); assert(addr && "no address for load"); - /* if addr is Unknown, set propper mode */ + /* if addr is Unknown, set proper mode */ if(iro_Unknown == get_irn_opcode(addr -> firmnode)) { set_irn_mode(addr -> firmnode, mode_P); } - sel = new_simpleSel(get_store(), addr -> firmnode, ent); - mode = get_type_mode(get_entity_type(ent)); + if(ent) { + sel = new_simpleSel(get_store(), addr -> firmnode, ent); + mode = get_type_mode(get_entity_type(ent)); + } + else { + sel = addr -> firmnode; + mode = mode_ANY; + } load = new_Load(get_store(), sel, mode); set_store(new_Proj(load, mode_M, 0)); eff -> firmnode = new_Proj(load, mode, 2); @@ -1035,10 +1128,16 @@ static void create_abstract_store(ir_graph *irg, proc_t *proc, eff_t *eff) eff_t *addr, *val; VERBOSE_PRINT((stdout, "create store in %s\n", - get_id_str(proc -> proc_ident))); + get_id_str(proc -> proc_ident))); - ent = eff -> effect.store.ent -> f_ent; - VERBOSE_PRINT((stdout, "store to %s\n", get_entity_name(ent))); + if(eff -> effect.store.ent) { + ent = eff -> effect.store.ent -> f_ent; + VERBOSE_PRINT((stdout, "store to entity %s\n", get_entity_name(ent))); + } + else { + VERBOSE_PRINT((stdout, "store to memory\n")); + ent = NULL; + } addr = find_valueid_in_proc_effects(eff -> effect.store.ptrrefid, proc); assert(addr && "no address for store"); @@ -1054,7 +1153,12 @@ static void create_abstract_store(ir_graph *irg, proc_t *proc, eff_t *eff) set_irn_mode(val -> firmnode, get_type_mode(get_entity_type(ent))); } - sel = new_simpleSel(get_store(), addr -> firmnode, ent); + if(ent) { + sel = new_simpleSel(get_store(), addr -> firmnode, ent); + } + else { + sel = addr -> firmnode; + } store = new_Store(get_store(), sel, val -> firmnode); set_store(new_Proj(store, mode_M, 0)); eff -> firmnode = store; @@ -1063,21 +1167,21 @@ static void create_abstract_store(ir_graph *irg, proc_t *proc, eff_t *eff) static void create_abstract_alloc(ir_graph *irg, proc_t *proc, eff_t *eff) { - type *ftype; + ir_type *ftype; ir_node *alloc; type_t *xtype; symconst_symbol sym; VERBOSE_PRINT((stdout, "create alloc in %s\n", - get_id_str(proc -> proc_ident))); + get_id_str(proc -> proc_ident))); xtype = find_type_in_module(current_module, eff -> effect.alloc.tp_id); assert(xtype && "type not found"); ftype = xtype -> f_tp; sym.type_p = ftype; - alloc = new_Alloc(get_store(), new_SymConst(sym, symconst_size), ftype, - heap_alloc); + alloc = new_Alloc(get_store(), new_SymConst(sym, symconst_type_size), ftype, + heap_alloc); set_store(new_Proj(alloc, mode_M, 0)); eff -> firmnode = new_Proj(alloc, mode_P, 2); @@ -1090,7 +1194,7 @@ static void create_abstract_unknown(ir_graph *irg, proc_t *proc, eff_t *eff) ir_node *unknown; VERBOSE_PRINT((stdout, "create unknown in %s\n", - get_id_str(proc -> proc_ident))); + get_id_str(proc -> proc_ident))); unknown = new_Unknown(mode_ANY); eff -> firmnode = unknown; @@ -1106,44 +1210,69 @@ static void create_abstract_call(ir_graph *irg, proc_t *proc, eff_t *eff) eff_t *addr; ir_node **irns; int i, num; - type *mtype; + ir_type *mtype; + int mik; /* is method somehow known? */ VERBOSE_PRINT((stdout, "create call in %s\n", - get_id_str(proc -> proc_ident))); + get_id_str(proc -> proc_ident))); - ent = eff -> effect.call.ent -> f_ent; - VERBOSE_PRINT((stdout, "call %s\n", get_entity_name(ent))); + if(eff -> effect.call.ent) { + ent = eff -> effect.call.ent -> f_ent; + VERBOSE_PRINT((stdout, "call %s\n", get_entity_name(ent))); + } + else { + ent = NULL; + VERBOSE_PRINT((stdout, "call something in memory\n")); + } addr = find_valueid_in_proc_effects(eff -> effect.call.valrefid, proc); assert(addr && "no address for load"); - /* if addr is Unknown, set propper mode */ + /* if addr is Unknown, set proper mode */ if(iro_Unknown == get_irn_opcode(addr -> firmnode)) { set_irn_mode(addr -> firmnode, mode_P); } - /* the address */ - sel = new_simpleSel(get_store(), addr -> firmnode, ent); - /* mthod type */ - mtype = get_entity_type(ent); + if(ent) { + /* the address */ + sel = new_simpleSel(get_store(), addr -> firmnode, ent); + /* method type */ + mtype = get_entity_type(ent); + mik = 1; + } + else { + /* the address */ + sel = addr -> firmnode; + /* method type */ + mtype = get_unknown_type(); + mik = 0; + } + /* the args */ num = eff -> effect.call.n_args; VERBOSE_PRINT((stdout, "number of args given: %d\n", num)); - VERBOSE_PRINT((stdout, "number of args expected: %d\n", - get_method_n_params(mtype))); + if(mik) { + VERBOSE_PRINT((stdout, "number of args expected: %d\n", + get_method_n_params(mtype))); + } irns = alloca(num * sizeof(ir_node*)); for(i = 0; i < num; i++) { irns[i] = find_valueid_in_proc_effects(eff -> effect.call.args[i], proc) -> firmnode; if(iro_Unknown == get_irn_opcode(irns[i])) { - set_irn_mode(irns[i], get_type_mode(get_method_param_type(mtype, i))); + if(mik) { + set_irn_mode(irns[i], get_type_mode(get_method_param_type(mtype, i))); + } + else { + set_irn_mode(irns[i], mode_ANY); + } } } - call = new_Call(get_store(), sel, num, irns, get_entity_type(ent)); + call = new_Call(get_store(), sel, num, irns, mtype); set_store(new_Proj(call, mode_M, 0)); - if(0 != get_method_n_ress(mtype)) { + if(mik && (0 != get_method_n_ress(mtype))) { eff -> firmnode = new_Proj(call, - get_type_mode(get_method_res_type(mtype, 0)), - 0); + get_type_mode(get_method_res_type(mtype, 0)), + 0); add_value_to_proc(proc, eff); /* result can be accessed */ } else { @@ -1151,6 +1280,126 @@ static void create_abstract_call(ir_graph *irg, proc_t *proc, eff_t *eff) } } +static void create_abstract_join (ir_graph *irg, proc_t *proc, eff_t *eff) +{ + ir_node **ins = NULL; + ir_node *unknown = NULL; + ir_node *cond = NULL; + ir_node *block = NULL; + ir_node *c_block = NULL; + ir_node *phi = NULL; + ir_mode *join_md = mode_ANY; + int n_ins = -1; + int i; + + VERBOSE_PRINT((stdout, "create join in %s\n", + get_id_str(proc -> proc_ident))); + + assert (eff_join == eff->kind); + + n_ins = eff->effect.join.n_ins; + + /* seems like current_block is not always mature at this point */ + mature_immBlock (get_cur_block ()); + + block = get_cur_block (); /* remember this so we can put the ProjXs into it */ + + /* jump based on an unknown condition so all values are possible */ + unknown = new_Unknown (mode_Iu); + cond = new_Cond (unknown); + + c_block = new_immBlock (); /* for the Phi after the branch(es) */ + + ins = (ir_node**) xmalloc (n_ins * sizeof (ir_node*)); + for (i = 0; i < n_ins; i ++) { + ir_node *projX = NULL; + ir_node *s_block = NULL; + ir_node *jmp = NULL; + eff_t *in_eff; + + /* make sure the projX is in the 'switch' block */ + set_cur_block (block); + projX = new_Proj (cond, mode_X, (long) i); + + /* this also sets current_block, so the rest of the code ends up there: */ + s_block = new_immBlock (); + + add_immBlock_pred (s_block, projX); + mature_immBlock (s_block); + + in_eff = find_valueid_in_proc_effects (eff->effect.join.ins [i], proc); + + ins [i] = in_eff->firmnode; + + /* need to find a suitable mode for the Phi node */ + if (mode_ANY != get_irn_mode (ins [i])) { + join_md = get_irn_mode (ins [i]); + } + + jmp = new_Jmp (); + add_immBlock_pred (c_block, jmp); + } + + set_cur_block (c_block); + + phi = new_Phi (n_ins, ins, join_md); + + mature_immBlock (c_block); + memset (ins, 0x00, n_ins * sizeof (ir_node*)); + free (ins); + + eff->firmnode = phi; + + add_value_to_proc (proc, eff); +} + +static void create_abstract_raise (ir_graph *irg, proc_t *proc, eff_t *eff) +{ + ir_node *block = NULL; + ir_node *unknown = NULL; + ir_node *cond = NULL; + + /* seems like current_block is not always mature at this point */ + mature_immBlock (get_cur_block ()); + block = get_cur_block (); /* remember this so we can put the ProjXs into it */ + + /* jump based on an unknown condition so both values are possible */ + unknown = new_Unknown (mode_Iu); + cond = new_Cond (unknown); + + /* one branch for 'throw-exception' case */ + { + ir_node *projX = new_Proj (cond, mode_X, 1L); + ir_node *b_exc = new_immBlock (); + ir_node *obj = NULL; + ir_node *thrw = NULL; + eff_t *thrw_eff = NULL; + + add_immBlock_pred (b_exc, projX); + + thrw_eff = find_valueid_in_proc_effects (eff->effect.raise.valref, proc); + obj = thrw_eff->firmnode; + + thrw = new_Raise (get_store (), obj); + /* exc-jump to end block */ + thrw = new_Proj (thrw, mode_X, 0L); + + add_immBlock_pred (get_irg_end_block (irg), thrw); + mature_immBlock (get_cur_block ()); + } + + set_cur_block (block); /* back to the first block */ + + /* one branch for 'non-exception' case */ + { + ir_node *projX = new_Proj (cond, mode_X, 0); + new_immBlock (); /* also sets current_block */ + add_immBlock_pred (get_cur_block (), projX); + mature_immBlock (get_cur_block ()); + /* continue building in current_block */ + } + +} static void create_abstract_firm(module_t *module, proc_t *proc, entity *fent) { @@ -1160,21 +1409,24 @@ static void create_abstract_firm(module_t *module, proc_t *proc, entity *fent) /* test entity */ assert(visibility_external_allocated == get_entity_visibility(fent) - && peculiarity_existent == get_entity_peculiarity(fent) - && "not an abstract entity"); + && peculiarity_existent == get_entity_peculiarity(fent) + && "not an abstract entity"); /* create irg in entity */ - irg = new_ir_graph(fent, 0); + irg = new_pseudo_ir_graph(fent, 0); set_irg_inline_property(irg, irg_inline_forbidden); + /* @@@ If the spec says so: */ + set_entity_visibility(fent, visibility_local); + VERBOSE_PRINT((stdout, "create effects for %s\n", - get_id_str(proc -> proc_ident))); + get_id_str(proc -> proc_ident))); /* create effects in irg */ num = proc -> n_effs; for(i = 0; i < num; i++) { eff = proc -> effs[i]; VERBOSE_PRINT((stdout, - "create effect \"%s\"\n", effect_string[(int)eff -> kind])); + "create effect \"%s\"\n", effect_string[(int)eff -> kind])); switch(eff -> kind) { case eff_ret: create_abstract_return(irg, proc, eff); @@ -1197,6 +1449,12 @@ static void create_abstract_firm(module_t *module, proc_t *proc, entity *fent) case eff_call: create_abstract_call(irg, proc, eff); break; + case eff_join: + create_abstract_join(irg, proc, eff); + break; + case eff_raise: + create_abstract_raise(irg, proc, eff); + break; default: assert(0 && "effect not implemented"); break; @@ -1211,7 +1469,7 @@ static void create_abstract_firm(module_t *module, proc_t *proc, entity *fent) VERBOSE_PRINT((stdout, "verify graph\n")); irg_vrfy(irg); VERBOSE_PRINT((stdout, "finalize construction\n")); - finalize_cons (irg); + irg_finalize_cons (irg); } /********************************************************************/ @@ -1220,24 +1478,24 @@ static void assign_firm_entity(module_t *module, entity_t *xmlent) { int i, num; type_t *typ; - type *type; + ir_type *type; entity *ent; VERBOSE_PRINT((stdout, "assign entity %s to typeid %s\n", - get_id_str(xmlent -> ent_ident), - get_id_str(xmlent -> owner))); + get_id_str(xmlent -> ent_ident), + get_id_str(xmlent -> owner))); typ = find_type_in_module(module, xmlent -> owner); assert(typ && "class not found in module"); type = typ -> f_tp; - assert(is_class_type(type)); + assert(is_Class_type(type)); num = get_class_n_members(type); ent = NULL; for(i = 0; i < num; i++) { ent = get_class_member(type, i); VERBOSE_PRINT((stdout, "compare entity %s and %s\n", - get_id_str(xmlent -> ent_ident), get_entity_name(ent))); + get_id_str(xmlent -> ent_ident), get_entity_name(ent))); if(get_entity_ident(ent) == xmlent -> ent_ident) { break; @@ -1254,11 +1512,11 @@ static void assign_firm_entity(module_t *module, entity_t *xmlent) static void assign_firm_type(type_t *xmltype) { int i; - type *typ = NULL; + ir_type *typ = NULL; int num; VERBOSE_PRINT((stdout, "assign firm type to type %s\n", - get_id_str(xmltype -> type_ident))); + get_id_str(xmltype -> type_ident))); /* is it global type? */ typ = get_glob_type(); @@ -1266,16 +1524,15 @@ static void assign_firm_type(type_t *xmltype) /* yes */ xmltype -> f_tp = typ; VERBOSE_PRINT((stdout, "is global type %s\n", get_type_name(typ))); - } - else { + } else { num = get_irp_n_types(); for(i = 0; i < num; i++) { typ = get_irp_type(i); VERBOSE_PRINT((stdout, "test type %s\n", get_type_name(typ))); if(xmltype -> type_ident == get_type_ident(typ)) { - VERBOSE_PRINT((stdout, "found type %s\n", get_type_name(typ))); - xmltype -> f_tp = typ; - break; + VERBOSE_PRINT((stdout, "found type %s\n", get_type_name(typ))); + xmltype -> f_tp = typ; + break; } typ = NULL; } @@ -1288,13 +1545,13 @@ static void create_abstract_proc_effect(module_t *module, proc_t *proc) { int i, num; - type *class_typ = NULL; + ir_type *class_typ = NULL; type_t *type; entity *fent; /* find the class of a procedure */ - VERBOSE_PRINT((stdout, "do find typeid %s\n", get_id_str(proc -> typeid))); - type = find_type_in_module(module, proc -> typeid); + VERBOSE_PRINT((stdout, "do find owner id %s\n", get_id_str(proc -> ownerid))); + type = find_type_in_module(module, proc -> ownerid); assert(type && "class not found in module"); class_typ = get_glob_type(); @@ -1305,11 +1562,11 @@ void create_abstract_proc_effect(module_t *module, proc_t *proc) for(i = 0; i < num; i++) { class_typ = get_irp_type(i); VERBOSE_PRINT((stdout, "test type %s\n", get_type_name(class_typ))); - if(is_class_type(class_typ) - && (type -> type_ident == get_type_ident(class_typ))) { - /* found class type */ - VERBOSE_PRINT((stdout, "found type %s\n", get_type_name(class_typ))); - break; + if (is_Class_type(class_typ) + && (type -> type_ident == get_type_ident(class_typ))) { + /* found class type */ + VERBOSE_PRINT((stdout, "found type %s\n", get_type_name(class_typ))); + break; } class_typ = NULL; } @@ -1318,12 +1575,12 @@ void create_abstract_proc_effect(module_t *module, proc_t *proc) VERBOSE_PRINT((stdout, "found global type %s\n", get_type_name(class_typ))); } assert(class_typ && "type not found"); - assert(is_class_type(class_typ) && "is not a class type"); + assert(is_Class_type(class_typ) && "is not a class type"); type -> f_tp = class_typ; /* find entity for procedure in class */ VERBOSE_PRINT((stdout, "find method %s\n", - get_id_str(proc -> proc_ident))); + get_id_str(proc -> proc_ident))); num = get_class_n_members(class_typ); fent = NULL; @@ -1332,17 +1589,26 @@ void create_abstract_proc_effect(module_t *module, proc_t *proc) VERBOSE_PRINT((stdout, "test proc %s\n", get_entity_name(fent))); if(proc -> proc_ident == get_entity_ident(fent)) { VERBOSE_PRINT((stdout, "found proc %s\n", - get_id_str(proc -> proc_ident))); + get_id_str(proc -> proc_ident))); /* @@@ TODO check args types - not in xml yet */ /* create Firm stuff */ create_abstract_firm(module, proc, fent); - break; + return; } else { fent = NULL; } } - assert(fent && "procedure not found in class"); + + /* fail */ + fprintf(stderr, + "method %s not found\nNo effects generated\nCandidates are:\n", + get_id_str(proc -> proc_ident)); + for(i = 0; i < num; i++) { + fent = get_class_member(class_typ, i); + fprintf(stderr, "%s\n", get_entity_name(fent)); + } + //assert(fent && "procedure not found in class"); } static @@ -1353,7 +1619,7 @@ void create_abstract_module(module_t *module) entity_t *ent; VERBOSE_PRINT((stdout, "create an abstraction for module %s\n", - get_id_str(module -> id))); + get_id_str(module -> id))); VERBOSE_PRINT((stdout, "--handle types for module\n")); for(type = module -> types; type; type = type -> prev) { @@ -1373,12 +1639,13 @@ void create_abstract_module(module_t *module) } -void create_abstraction(const char *filename) +int create_abstraction(const char *filename) { module_t *module; /* read and parse XML file */ - read_extern(filename); + if (! read_extern(filename)) + return 0; /* finished reading and parsing here */ /* build FIRM graphs */ @@ -1392,13 +1659,81 @@ void create_abstraction(const char *filename) /* free data structures */ free_data(); + + types = NULL; + entities = NULL; + procs = NULL; + modules = NULL; + + return 1; +} + + +void free_abstraction(void) { + int i, n_pseudo_irgs = get_irp_n_pseudo_irgs(); + for (i = 0; i < n_pseudo_irgs; ++i) { + ir_graph *p_irg = get_irp_pseudo_irg(i); + set_entity_visibility(get_irg_entity(p_irg), visibility_external_allocated); + // @@@ free_pseudo_ir_graph(p_irg); + } } + /********************************************************************/ /* * $Log$ + * Revision 1.26 2006/12/15 12:37:40 matze + * fix warnings + * + * Revision 1.25 2006/06/09 11:26:35 firm + * renamed type to ir_type + * + * Revision 1.24 2006/05/29 13:34:49 beck + * renamed symconst_size to symconst_type_size + * + * Revision 1.22 2005/08/16 10:18:35 beck + * create_abstraction() now returns an error code if the file could not + * be opened. + * + * Revision 1.21 2005/03/10 10:05:38 goetz + * chanmged method name + * + * Revision 1.20 2005/01/05 14:28:35 beck + * renames all is_x*_type() functions to is_X*_type() to prevent name clash with EDG frontend + * + * Revision 1.19 2004/12/10 15:14:34 beck + * used xmalloc instead of malloc + * + * Revision 1.18 2004/12/02 16:21:42 beck + * fixed config.h include + * + * Revision 1.17 2004/11/23 14:17:31 liekweg + * fenced out currently unneeded static functions + * + * Revision 1.16 2004/11/11 12:24:52 goetz + * fixes + * + * Revision 1.15 2004/11/11 09:28:32 goetz + * treat pseudo irgs special + * parse 'local' from xml files + * + * Revision 1.14 2004/11/10 14:42:00 boesler + * be more helpful if a method does not exist + * + * Revision 1.13 2004/11/05 14:00:53 liekweg + * added raise + * + * Revision 1.12 2004/11/02 14:30:31 liekweg + * fixed multi-input join (thx, Boris) --flo + * + * Revision 1.11 2004/10/29 18:51:53 liekweg + * Added Join + * + * Revision 1.10 2004/10/25 13:52:24 boesler + * seperated read.h (public interface) and read_t.h (types) + * * Revision 1.9 2004/10/22 13:51:35 boesler * prohibit inlining of pseudo ir_graphs *