void NormalizeProcedureReturns:: do_procedure_definition( ProcedureDefinition *pd ) { ProcedureSymbol *ps = pd->get_procedure_symbol(); if (!ps) return; ProcedureType *t = to<ProcedureType>(ps->get_type()); if (!is_kind_of<CProcedureType>(t)) return; CProcedureType *ct = to<CProcedureType>(t); DataType *result = ct->get_result_type(); bool is_void = is_kind_of<VoidType>(result); for (Iter<ReturnStatement> iter = object_iterator<ReturnStatement>(pd); iter.is_valid(); iter.next()) { ReturnStatement *ret = &iter.current(); if (ret == NULL) continue; Expression *ret_expr = ret->get_return_value(); if (is_void) { if (ret_expr != NULL) { // Should not be here trash_it(remove_suif_object(ret_expr)); } } else { if (ret_expr == NULL) { // build a NULL expression to match the DataType. Expression *x = build_empty_expression(result); ret->set_return_value(x); } } } }
void DismantleEmptyScopeStatements:: do_procedure_definition(ProcedureDefinition *pd) { list<ScopeStatement*> *l = collect_objects<ScopeStatement>(pd); while (!l->empty()) { ScopeStatement *sc = l->front(); l->pop_front(); if ((sc->get_definition_block()->get_variable_definition_count() == 0) && sc->get_symbol_table()->get_symbol_table_object_count() == 0) { Statement *body = sc->get_body(); sc->set_body(NULL); replace_statement(sc, body); trash_it(sc); } } delete l; }
void GCSymbolTablePass::execute(void) { // Let's try a little optimization. // we'll do GC like the trash_it routine. // walk through all of the owned objects in the program. // for the non-symbols, walk through their sub-objects and // find any referenced symbols // throw away any that are not needed. FileSetBlock *fsb = get_suif_env()->get_file_set_block(); if (fsb == NULL) return; static LString k_trash = "trash"; // remove the trash annote. we'll replace it later Annote *trash_annote = fsb->take_annote(k_trash); suif_hash_map<SymbolTableObject*,bool> referenced_map; suif_list<SymbolTableObject*> live_symbols; // Now we have a map of Object->parent object // We need another one for object -> referenced for (Iter<SuifObject> all_iter1 = object_iterator<SuifObject>(fsb); all_iter1.is_valid(); all_iter1.next()) { SuifObject *obj = &all_iter1.current(); // for the ownership links of symbols: if (is_kind_of<SymbolTable>(obj)) continue; if (is_kind_of<SymbolTableObject>(obj)) { SymbolTableObject *sym = to<SymbolTableObject>(obj); //sym->print_to_default(); if (referenced_map.find(sym) == referenced_map.end()) { //fprintf(stderr, "Found unreferenced Symbol:"); // referenced_map[sym] = false; referenced_map.enter_value(sym, false); } // we will check these later. continue; } for (Iter<SymbolTableObject> ref_iter = suif_object_ref_iterator<SymbolTableObject>(obj, SuifObject::get_class_name()); ref_iter.is_valid(); ref_iter.next()) { SymbolTableObject *sym_ref = &ref_iter.current(); suif_hash_map<SymbolTableObject*,bool>::iterator find = referenced_map.find(sym_ref); if (find == referenced_map.end() || (*find).second == false) { //fprintf(stderr, "Found Symbol Reference:"); //sym_ref->print_to_default(); //referenced_map[sym_ref] = true; referenced_map.enter_value(sym_ref, true); live_symbols.push_back(sym_ref); } } } // Now we have to do a worklist algorithm with the live symbols. // any symbol they own or reference must also be live while (!live_symbols.empty()) { SymbolTableObject *obj = live_symbols.back(); live_symbols.pop_back(); // Implicit assumption: // it will NEVER OWN another symbol. // If it did, we just need to use the object_instance_iterator // to add these. // Everything it references is live. for (Iter<SymbolTableObject> ref_iter = suif_object_ref_iterator<SymbolTableObject>(obj, SuifObject::get_class_name()); ref_iter.is_valid(); ref_iter.next()) { SymbolTableObject *sym_ref = &ref_iter.current(); suif_hash_map<SymbolTableObject*,bool>::iterator find = referenced_map.find(sym_ref); if (find == referenced_map.end() || (*find).second == false) { //fprintf(stderr, "Found Symbol reference:"); //sym_ref->print_to_default(); // referenced_map[sym_ref] = true; referenced_map.enter_value(sym_ref, true); live_symbols.push_back(sym_ref); } } } if (trash_annote != NULL) fsb->append_annote(trash_annote); // walk over all of the reference // and delete or put back for (suif_hash_map<SymbolTableObject*, bool>::iterator obj_iter = referenced_map.begin(); obj_iter != referenced_map.end(); obj_iter++) { bool is_referenced = (*obj_iter).second; if (!is_referenced) { SymbolTableObject *sym = (*obj_iter).first; //fprintf(stderr, "Trashing unused symbol:"); //sym->print_to_default(); SymbolTable *st = sym->get_symbol_table(); if (st != NULL) { if (sym->get_name() != emptyLString) { st->remove_all_from_lookup_table(sym); } st->remove_symbol_table_object(sym); } remove_suif_object(sym); trash_it(_suif_env, sym); // delete sym; } } // SuifGC::collect(_suif_env->get_file_set_block()); }