Statement* c_for_statement_walker::dismantle_c_for_statement(CForStatement *the_for){ StatementList *replacement = create_statement_list(the_for->get_suif_env()); StatementList *body = create_statement_list(the_for->get_suif_env()); Statement* original_body = the_for->get_body(); the_for->set_body(0); body->append_statement(original_body); the_for->set_body(body); Statement* pre_pad = the_for->get_pre_pad(); CodeLabelSymbol* break_lab = the_for->get_break_label(); CodeLabelSymbol* continue_lab = the_for->get_continue_label(); Statement* before = the_for->get_before(); Expression* test = the_for->get_test(); Statement* step = the_for->get_step();; if(before)remove_suif_object(before); if(test)remove_suif_object(test); if(step)remove_suif_object(step); if(body)remove_suif_object(body); if(pre_pad)remove_suif_object(pre_pad); the_for->set_break_label(0); the_for->set_continue_label(0); // I am guessing what pre-pad and post-pad do if (before) replacement->append_statement(before); // and loop if not out of range replacement->append_statement( create_label_location_statement(the_for->get_suif_env(), continue_lab)); if(test) { SuifEnv *env = the_for->get_suif_env(); DataType *bool_type = get_type_builder(env)->get_boolean_type(); test = create_unary_expression(env,bool_type,k_logical_not,test); replacement->append_statement(create_branch_statement(env,test,break_lab)); } if(pre_pad){ replacement->append_statement(pre_pad); } append_flattened(replacement,body); append_flattened(replacement,step); replacement->append_statement(create_jump_statement(body->get_suif_env(),continue_lab)); replacement->append_statement( create_label_location_statement(body->get_suif_env(), break_lab)); // end of loop the_for->get_parent()->replace(the_for, replacement); return replacement; }
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); } } } }
Statement* multi_way_branch_statement_walker::dismantle_multi_way_branch_statement(MultiWayBranchStatement *the_case){ StatementList *replacement = create_statement_list(the_case->get_suif_env()); Expression *operand = the_case->get_decision_operand (); remove_suif_object(operand); DataType *type = operand->get_result_type(); CodeLabelSymbol *default_lab = the_case->get_default_target(); the_case->set_default_target(0); Iter<MultiWayBranchStatement::case_pair > iter = the_case->get_case_iterator(); while (iter.is_valid()) { MultiWayBranchStatement::case_pair pair = iter.current(); IInteger value = pair.first; CodeLabelSymbol *lab = pair.second; IntConstant *exp = create_int_constant(the_case->get_suif_env(),type, value); // Expression *exp = create_load_constant_expression(get_env(),type,iconst); TypeBuilder *type_builder = (TypeBuilder *) the_case->get_suif_env()->get_object_factory(TypeBuilder::get_class_name()); Expression *compare = create_binary_expression(the_case->get_suif_env(),type_builder->get_boolean_type(), k_is_equal_to, deep_suif_clone(operand), exp); replacement->append_statement(create_branch_statement(the_case->get_suif_env(),compare,lab)); iter.next(); } delete operand; replacement->append_statement(create_jump_statement(the_case->get_suif_env(),default_lab)); the_case->get_parent()->replace(the_case,replacement); return replacement; }
Walker::ApplyStatus multi_way_branch_statement_compactor::operator () (SuifObject *x) { MultiWayBranchStatement *the_case = to<MultiWayBranchStatement>(x); // is the table already compact? if (is_compact(the_case)) return Walker::Continue; SymbolTable *scope = find_scope(x); if (!scope) return Walker::Continue; CodeLabelSymbol *default_lab = the_case->get_default_target(); // very special case - the case list is empty, so just jump to the default label if (the_case->get_case_count() == 0) { Statement *replacement = create_jump_statement(get_env(),default_lab); the_case->get_parent()->replace(the_case,replacement); set_address(replacement); return Walker::Replaced; } StatementList *replacement = create_statement_list(get_env()); Expression *operand = the_case->get_decision_operand (); remove_suif_object(operand); DataType *type = operand->get_result_type(); VariableSymbol *decision = create_variable_symbol(get_env(),get_type_builder(get_env())->get_qualified_type(type)); scope->add_symbol(decision); replacement->append_statement(create_store_variable_statement(get_env(),decision,operand)); the_case->set_default_target(0); MultiWayGroupList jump_list(get_env(),default_lab,decision);; Iter<MultiWayBranchStatement::case_pair > iter = the_case->get_case_iterator(); while (iter.is_valid()) { MultiWayBranchStatement::case_pair pair = iter.current(); jump_list.add_element(pair.first,pair.second); iter.next(); } // we have built the new structure, now need to generate code for it jump_list.generate_code(replacement); the_case->get_parent()->replace(the_case,replacement); set_address(replacement); return Walker::Replaced; }
Statement *do_while_statement_walker::dismantle_do_while_statement(DoWhileStatement *the_do_while){ Statement *result = 0; Expression *condition = the_do_while->get_condition(); // we are going to reuse the condition so we must remove it // from the if statement first to avoid ownership conflicts remove_suif_object(condition); Statement *body = the_do_while->get_body(); CodeLabelSymbol *break_label = the_do_while->get_break_label(); CodeLabelSymbol *continue_label = the_do_while->get_continue_label(); // likewise of these parts - remove from if. the_do_while->set_body(0); remove_suif_object(body); the_do_while->set_break_label(0); the_do_while->set_continue_label(0); if (body != 0) { StatementList *replacement = create_statement_list(body->get_suif_env()); result = replacement; suif_assert(continue_label != 0); replacement-> append_statement(create_label_location_statement(body->get_suif_env(), continue_label)); replacement->append_statement(body); replacement-> append_statement(create_branch_statement(body->get_suif_env(), condition, continue_label)); suif_assert(break_label != 0); replacement-> append_statement(create_label_location_statement(body->get_suif_env(), break_label)); } the_do_while->get_parent()->replace(the_do_while,result); return result; }
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()); }
Statement* if_statement_walker::dismantle_if_statement(IfStatement* the_if){ Statement *result = 0; ProcedureDefinition* proc_def = get_procedure_definition(the_if); Expression *condition = the_if->get_condition(); // we are going to reuse the condition so we must remove it // from the if statement first to avoid ownership conflicts remove_suif_object(condition); // the_if->set_condition(SourceOp()); // remove_source_op(condition); Statement *then_part = the_if->get_then_part(); Statement *else_part = the_if->get_else_part(); // likewise of these parts - remove from if. the_if->set_then_part(0); the_if->set_else_part(0); remove_suif_object(then_part); remove_suif_object(else_part); if (then_part != 0) { StatementList *replacement = create_statement_list( the_if->get_suif_env() ); result = replacement; UnaryExpression* negated_condition = create_unary_expression( the_if->get_suif_env(), condition->get_result_type(), k_logical_not, condition ); if (else_part != 0) { CodeLabelSymbol *else_label = new_anonymous_label(proc_def->get_symbol_table()); CodeLabelSymbol *done_label = new_anonymous_label(proc_def->get_symbol_table()); replacement->append_statement(create_branch_statement(the_if->get_suif_env(), negated_condition, else_label)); replacement->append_statement(then_part); replacement->append_statement(create_jump_statement(the_if->get_suif_env(),done_label)); replacement->append_statement(create_label_location_statement(the_if->get_suif_env(), else_label)); replacement->append_statement(else_part); replacement->append_statement(create_label_location_statement(the_if->get_suif_env(), done_label)); } else { CodeLabelSymbol *done_label = create_new_label(get_procedure_definition(the_if)); replacement-> append_statement(create_branch_statement(the_if->get_suif_env(), negated_condition, done_label)); replacement->append_statement(then_part); replacement-> append_statement(create_label_location_statement(the_if->get_suif_env(), done_label)); } } else { if (else_part != 0) { StatementList *replacement = create_statement_list(the_if->get_suif_env()); result = replacement; CodeLabelSymbol *done_label = create_new_label(proc_def); replacement->append_statement(create_branch_statement(the_if->get_suif_env(), condition, done_label)); replacement->append_statement(else_part); replacement-> append_statement(create_label_location_statement(the_if->get_suif_env(), done_label)); } else { EvalStatement *replacement = create_eval_statement(the_if->get_suif_env()); result = replacement; replacement->append_expression(condition); } } the_if->get_parent()->replace(the_if, result); return result; }
Statement *for_statement_walker::dismantle_for_statement(ForStatement *the_for){ StatementList *replacement = create_statement_list(the_for->get_suif_env()); VariableSymbol* index = the_for->get_index(); DataType *type = unqualify_data_type(index->get_type()); Expression *lower = the_for->get_lower_bound(); Expression *upper = the_for->get_upper_bound(); Expression *step = the_for->get_step(); LString compare_op = the_for->get_comparison_opcode(); Statement* body = the_for->get_body(); Statement* pre_pad = the_for->get_pre_pad(); // Statement* post_pad = the_for->get_post_pad(); CodeLabelSymbol* break_lab = the_for->get_break_label(); CodeLabelSymbol* continue_lab = the_for->get_continue_label(); the_for->set_index(0); remove_suif_object(lower); remove_suif_object(upper); remove_suif_object(step); remove_suif_object(body); remove_suif_object(pre_pad); // the_for->set_post_pad(0); // remove_suif_object(post_pad); the_for->set_break_label(0); the_for->set_continue_label(0); // I am guessing what pre-pad and post-pad do if(pre_pad != 0)replacement->append_statement(pre_pad); // initialize the index. Is this right? should we ever initialize to upper, for -ve steps? // Is index guaranteed not to be changed? Should we be creating a temporary? replacement->append_statement(create_store_variable_statement(body->get_suif_env(),index,lower)); replacement->append_statement(create_label_location_statement(body->get_suif_env(), continue_lab)); if (body != 0) replacement->append_statement(body); // increment the counter Expression *index_expr = create_load_variable_expression(body->get_suif_env(), unqualify_data_type(index->get_type()), index); Expression *increment = create_binary_expression(body->get_suif_env(),type,k_add, index_expr,step); replacement->append_statement(create_store_variable_statement(body->get_suif_env(),index,increment)); // and loop if not out of range Expression *compare = create_binary_expression(body->get_suif_env(),type, compare_op, deep_suif_clone<Expression>(index_expr), deep_suif_clone<Expression>(step)); replacement->append_statement(create_branch_statement(body->get_suif_env(),compare,continue_lab)); // end of loop replacement->append_statement(create_label_location_statement(body->get_suif_env(),break_lab)); // if(post_pad != 0)replacement->append_statement(post_pad); the_for->get_parent()->replace(the_for,replacement); return replacement; }
void EliminateArrayConvertsPass::do_procedure_definition(ProcedureDefinition* proc_def){ suif_hash_map<ParameterSymbol*, Type*> params; TypeBuilder *tb = (TypeBuilder*) get_suif_env()->get_object_factory(TypeBuilder::get_class_name()); // collect all procedure parameters of pointer type into params list for(Iter<ParameterSymbol*> iter = proc_def->get_formal_parameter_iterator(); iter.is_valid(); iter.next()) { ParameterSymbol* par_sym = iter.current(); Type* par_type = tb->unqualify_type(par_sym->get_type()); if(is_kind_of<PointerType>(par_type)){ // put NULLs into the map at first, // they will later be overwritten params[par_sym] = NULL; } } if(params.size()==0) return; // nothing to do // walk thru all AREs and look for arrays that are in the param list {for(Iter<ArrayReferenceExpression> iter = object_iterator<ArrayReferenceExpression>(proc_def); iter.is_valid(); iter.next()) { ArrayReferenceExpression* are = &iter.current(); if(is_kind_of<UnaryExpression>(are->get_base_array_address())){ UnaryExpression* ue = to<UnaryExpression>(are->get_base_array_address()); if(ue->get_opcode() == k_convert){ if(is_kind_of<LoadVariableExpression>(ue->get_source())){ LoadVariableExpression* lve = to<LoadVariableExpression>(ue->get_source()); VariableSymbol* array = lve->get_source(); for(suif_hash_map<ParameterSymbol*, Type*>::iterator iter = params.begin(); iter!=params.end();iter++) { ParameterSymbol* par_sym = (*iter).first; if(par_sym == array){ // match! Type* array_type; suif_hash_map<ParameterSymbol*, Type*>::iterator iter = params.find(par_sym); if(iter==params.end() || (*iter).second==NULL){ //array_type = to<PointerType>(ue->get_result_type())->get_reference_type(); array_type = tb->get_qualified_type(ue->get_result_type()); params[par_sym] = array_type; //printf("%s has type ",par_sym->get_name().c_str()); //array_type->print_to_default(); }else{ array_type = params[par_sym].second; suif_assert(is_kind_of<QualifiedType>(array_type)); } array->replace(array->get_type(), array_type); remove_suif_object(ue); remove_suif_object(lve); lve->replace(lve->get_result_type(), tb->unqualify_type(array_type)); // put the LoadVar directly under ARE are->set_base_array_address(lve); //are->print_to_default(); } } } else { suif_warning(ue->get_source(), ("Expecting a LoadVariableExpression here")); } } else { suif_warning(ue, ("Disallow converts in AREs for " "things other than procedure parameters")); } } } } }
/** Remove all the array types collected by all the calls to array_type2multi_array_type. \see array_type2multi_array_type */ void OneDimArrayConverter::remove_all_one_dim_array_types(){ for (int j=0;j < (int)all_array_types->size();j++) { remove_suif_object((*all_array_types)[j]); } }
/** Convert ArrayReferenceExpression \a top_array to a MultiDimArrayExpression. */ void OneDimArrayConverter:: convert_array_expr2multi_array_expr(ArrayReferenceExpression* top_array){ Expression* expr = top_array; unsigned int i = 0; suif_vector<Expression*> lower_bounds; suif_vector<Expression*> upper_bounds; list<Expression*> indices; IInteger bit_size, bit_alignment; suif_vector<ArrayReferenceExpression *> exprs; do{ ArrayReferenceExpression* are = to<ArrayReferenceExpression>(expr); expr = are->get_base_array_address(); exprs.push_back(are); } while(is_kind_of<ArrayReferenceExpression>(expr)); // collect bounds and indeces for (unsigned int exp_ind = 0; exp_ind < exprs.size();exp_ind++) { ArrayReferenceExpression* are = exprs[exp_ind]; DataType* type = are->get_base_array_address()->get_result_type(); ArrayType* array_type; if(is_kind_of<ArrayType>(type)){ array_type = to<ArrayType>(type); }else{ array_type = to<ArrayType>( unwrap_ptr_ref_type(type)->get_base_type()); } bit_size = array_type->get_element_type()-> get_base_type()->get_bit_size(); bit_alignment = array_type->get_element_type()-> get_base_type()->get_bit_alignment(); // What happens to ArrayType?? Does it become garbage? suif_assert(array_type->get_lower_bound()); suif_assert(array_type->get_upper_bound()); // clone bounds and add to the lists lower_bounds.push_back(array_type->get_lower_bound()); upper_bounds.push_back(array_type->get_upper_bound()); // save the index Expression* index = are->get_index(); remove_suif_object(index); index->set_parent(NULL); indices.push_back(index); suif_assert(upper_bounds[i]); suif_assert(lower_bounds[i]); suif_assert(indices[i]); i++; } // Build the offset for the expression. We have to traverse upwards to do this Expression *top_expr_base = exprs[exprs.size()-1]->get_base_array_address(); DataType* top_expr_base_type = top_expr_base->get_result_type(); ArrayType* top_array_type; if(is_kind_of<ArrayType>(top_expr_base_type)){ top_array_type = to<ArrayType>(top_expr_base_type); }else{ top_array_type = to<ArrayType>(tb->unqualify_data_type(unwrap_ptr_ref_type( top_expr_base_type))); } Expression* inc = create_int_constant(suif_env, 1); Expression* offset = create_int_constant(suif_env, 0); suif_vector<Expression *> elements; for (unsigned int ind = 0;ind < lower_bounds.size(); ind ++) { Expression *lower = lower_bounds[ind]; Expression *upper = upper_bounds[ind]; offset = build_dyadic_expression(k_add, offset, build_dyadic_expression( k_multiply, deep_suif_clone(inc), deep_suif_clone(lower))); Expression *element = build_dyadic_expression(k_add, build_dyadic_expression(k_subtract, deep_suif_clone(upper), deep_suif_clone(lower)), create_int_constant(suif_env,1)); inc = build_dyadic_expression(k_multiply, inc, deep_suif_clone(element)); elements.push_back(element); } // Now, inc and offset are ready // retrieve the multi-type MultiDimArrayType* multi_type; suif_map<ArrayType*, MultiDimArrayType*>::iterator type_iter = type_map->find(top_array_type); #ifdef CONVERT_TYPES suif_assert_message((type_iter != type_map->end()), ("Array type never translated")); #else if(type_iter == type_map->end()){ multi_type = array_type2multi_array_type(top_array_type); }else #endif //CONVERT_TYPES multi_type = (*type_iter).second; remove_suif_object(top_expr_base); // add a convert to the necessary type top_expr_base = create_unary_expression(suif_env, tb->get_pointer_type(multi_type), k_convert, top_expr_base); //top_expr_base->print_to_default(); // construct the expression to be returned MultiDimArrayExpression* mae = create_multi_dim_array_expression(suif_env, top_array->get_result_type(), top_expr_base, offset); // now when we have the expression, set the indices for (list<Expression*>::iterator ind_iter = indices.begin(); ind_iter!=indices.end(); ind_iter++) { Expression* index = *ind_iter; //printf("%p \t", index);index->print_to_default(); mae->append_index(index); } for (suif_vector<Expression *>::iterator eiter = elements.begin(); eiter != elements.end(); eiter ++) { Expression* element = *eiter; mae->append_element(element); } replace_expression(top_array, mae); }