/*}}}*/ PRIVATE void tselection (treenode * tptr, const int joinlab) { treenode *specsptr = tptr; tptr = tspecs (tptr); if (TagOf (tptr) != S_SELECTION) badtag (genlocn, TagOf (tptr), "tselection"); tprocess (CondBodyOf (tptr)); tdespecs (specsptr); genbranch (I_J, joinlab); }
/*{{{ ProfTabEntry *get_proftab_entry(INT32 index) */ ProfTabEntry *get_proftab_entry (ProfTab *prof_table, treenode *tptr) { ProfTabEntryTag typeofentry; ProfTabEntry *pt; if (nodetypeoftag (TagOf (tptr)) == NAMENODE) typeofentry = ProfRoutineCount; else if (nodetypeoftag (TagOf (tptr)) == INSTANCENODE) typeofentry = ProfCallCount; else typeofentry = ProfLineCount; for (pt = prof_table->entry_list_head; pt != NULL; pt = proftab_next_ (pt)) if (proftab_tag_ (pt) == typeofentry && proftab_tptr_ (pt) == tptr) return pt; #if 0 if (pt == NULL) { printtree (outfile, 0, tptr); fputc ('\n', outfile); } #endif return NULL; }
/***************************************************************************** * * casesin takes a list of selections 'tptr' and returns the number of * distinct selections (including an ELSE if one present). * *****************************************************************************/ PRIVATE int casesin (treenode * tptr) { int n = 0; for (; !EndOfList (tptr); tptr = NextItem (tptr)) { treenode *thisguard = CondGuardOf (skipspecifications (ThisItem (tptr))); if (TagOf (thisguard) == S_ELSE) n++; else n += listitems (thisguard); } return (n); }
/*{{{ void get_proftab_routine_address(ProfTab *table, treenode *nptr) */ INT32 get_proftab_routine_address (ProfTab *table, treenode *nptr) { RoutineInfoEntry *rptr; RoutineInfoEntry **hash_table = table->rout_hash_table; const int hash_value = hash_function (nptr); for (rptr = hash_table[hash_value]; rptr != NULL; rptr = rptr->next) if (rptr->nptr == nptr) return (rptr->address); #if 0 msg_out_s (SEV_INTERNAL, GEN, GEN_INDEX_HASH_TABLE_ERR, LocnOf (nptr), itagstring (TagOf (address))); #endif return (0); /* not reached */ }
/***************************************************************************** * * mapcase maps the case tree, tptr. * *****************************************************************************/ PUBLIC void mapcase (treenode * tptr) { treenode *selector_exp; treenode *selectionlist = RHSOf (tptr); mapexp (LHSAddr (tptr)); selector_exp = LHSOf (tptr); if (!issimplelocal (selector_exp, be_lexlevel)) { selector_exp = gettemp (selector_exp, NM_WORKSPACE); SetLHS (tptr, selector_exp); } if (nodetypeoftag (TagOf (selector_exp)) == NAMENODE) /* bug INSdi01959 06/04/93 */ upusecount (selector_exp, 4); mapconstruction (selectionlist, mapprocess); }
CFUN__PROTO(fu1_type, tagged_t, tagged_t t0) { DEREF(t0,t0); switch (TagOf(t0)) { case UBV: case SVA: case HVA: return atm_var; case CVA: return atm_attv; case STR: if (STRIsLarge(t0)) return LargeIsFloat(t0) ? atm_float : atm_int; return atm_str; case ATM: return atm_atm; case LST: return atm_lst; case NUM: return atm_int; } return (tagged_t)NULL; /* avoid warnings */ }
/***************************************************************************** * * tcase generates code for a case process tptr * *****************************************************************************/ PUBLIC void tcase (treenode * tptr) { /*{{{ save globals */ caseentry *const oldcasetable = casetable; const int olddefaultlab = defaultlab; const int olddefaultjumpdest = defaultjumpdest; const int oldselectortype = selectortype; treenode *const oldselectorexp = selectorexp; /*}}} */ BOOL makedefault = TRUE; treenode *selectionlist = RHSOf (tptr); const int joinlab = newlab (); int maxcase = 0; treenode *defaultp = NULL; /*{{{ initialise globals */ defaultlab = NO_LABEL; defaultjumpdest = FALSE; selectorexp = LHSOf (tptr); selectortype = ntypeof (selectorexp); /* make sure that we don't call memalloc with zero bytes */ casetable = (caseentry *) memalloc (sizeof (caseentry) * casesin (selectionlist) + 1); /*}}} */ /*{{{ evaluate the selector, if neccessary */ tpreexp (selectorexp); simplify (P_EXP, selectorexp); /*}}} */ /*{{{ build up table of selections, and generate jumps into case body */ { treenode *slist; for (slist = selectionlist; !EndOfList (slist); slist = NextItem (slist)) { treenode *thisselection = skipspecifications (ThisItem (slist)); treenode *v = CondGuardOf (thisselection); const int l = newlab (); if (TagOf (v) == S_ELSE) { defaultlab = l; defaultp = ThisItem (slist); makedefault = FALSE; } else /*{{{ set up labels and values */ for (; !EndOfList (v); v = NextItem (v)) { treenode *thisconstant = ThisItem (v); caseentry *caseentryptr = &(casetable[maxcase]); caseentryptr->label = l; caseentryptr->jumpdest = FALSE; caseentryptr->lowvalue = LoValOf (thisconstant); caseentryptr->highvalue = HiValOf (thisconstant); caseentryptr->selectionexp = thisconstant; caseentryptr->selectionp = ThisItem (slist); maxcase++; } /*}}} */ } if (makedefault) defaultlab = newlab (); #if 0 sup_qsort (casetable, maxcase, sizeof (caseentry), fitsinword (selectortype) ? comparecases : doublecomparecases); #else sup_qsort (casetable, maxcase, sizeof (caseentry), (bytesinscalar (selectortype) <= 4) ? comparecases : doublecomparecases); #endif tjumptable (0, maxcase - 1, FALSE); } /*}}} */ /*{{{ generate case body */ { int casesdone = 0; /*{{{ generate default process */ setlab (defaultlab); if (makedefault) { if (NEED_ERRORS) /* bug TS/2071 29/01/93 */ tstop (tptr); } else { if (defaultjumpdest) genstartblock (); tselection (defaultp, joinlab); } /*}}} */ while (casesdone < maxcase) { treenode *thisprocess; int i; BOOL jdest; /* Find a process to generate */ for (i = 0; (i < maxcase) && (casetable[i].selectionp == NULL); i++) /* skip */ ; thisprocess = casetable[i].selectionp; /* Generate thisprocess */ setlab (casetable[i].label); jdest = casetable[i].jumpdest; /*{{{ find and delete other entries for this process */ { int j; for (j = i + 1; j < maxcase; j++) if (casetable[j].selectionp == thisprocess) { /* Delete the process, so we only generate it once */ jdest = jdest | casetable[j].jumpdest; casetable[j].selectionp = NULL; casesdone++; } } /*}}} */ if (jdest) genstartblock (); tselection (thisprocess, joinlab); casetable[i].selectionp = NULL; casesdone++; } setlab (joinlab); genstartblock (); } /*}}} */ /*{{{ restore globals */ memfree (casetable); casetable = oldcasetable; defaultlab = olddefaultlab; defaultjumpdest = olddefaultjumpdest; selectortype = oldselectortype; selectorexp = oldselectorexp; /*}}} */ }