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")); } } } } }
void One2MultiArrayExpressionPass::do_procedure_definition(ProcedureDefinition* proc_def) { bool kill_all = !(_preserve_one_dim->is_set()); // access all array type declarations and create corresponding multi array types SuifEnv* suif_env = proc_def->get_suif_env(); TypeBuilder* tb = (TypeBuilder*)suif_env-> get_object_factory(TypeBuilder::get_class_name()); (void) tb; // avoid warning #ifdef CONVERT_TYPES for (Iter<ArrayType> at_iter = object_iterator<ArrayType>(proc_def); at_iter.is_valid();at_iter.next()) { MultiDimArrayType* multi_type = converter->array_type2multi_array_type(&at_iter.current()); } #endif //CONVERT_TYPES // collect tops of array access chains into this list list<ArrayReferenceExpression*> ref_exprs; for (Iter<ArrayReferenceExpression> are_iter = object_iterator<ArrayReferenceExpression>(proc_def); are_iter.is_valid(); are_iter.next()) { // itself an array and parent is *not* an array ArrayReferenceExpression* are = &are_iter.current(); if((kill_all || is_kind_of<ArrayReferenceExpression>(are->get_base_array_address())) && !is_kind_of<ArrayReferenceExpression>(are->get_parent())) { //printf("%p \t", are);are->print_to_default(); ref_exprs.push_back(are); } } // for top all expressions, convert them to multi-exprs for(list<ArrayReferenceExpression*>::iterator ref_iter = ref_exprs.begin(); ref_iter != ref_exprs.end(); ref_iter++) { ArrayReferenceExpression* top_array = *ref_iter; converter->convert_array_expr2multi_array_expr(top_array); } #ifdef CONVERT_TYPES // replace the types of all array variables for (Iter<VariableSymbol> iter = object_iterator<VariableSymbol>(proc_def); iter.is_valid();iter.next()) { VariableSymbol* vd = &iter.current(); DataType *vtype = tb->unqualify_data_type(vd->get_type()); if (is_kind_of<ArrayType>(vtype)) { MultiDimArrayType* multi_type = converter->array_type2multi_array_type(to<ArrayType>(vtype)); vd->replace(vd->get_type(), tb->get_qualified_type(multi_type)); } } // remove the remaining one-dim array types converter->remove_all_one_dim_array_types(); #endif //CONVERT_TYPES // make sure no traces of single-dim arrays are left if(kill_all){ {for(Iter<ArrayReferenceExpression> iter = object_iterator<ArrayReferenceExpression>(proc_def); iter.is_valid(); iter.next()) { // ArrayReferenceExpression* are = &iter.current(); //are->print_to_default(); printf("at %p \t", are); suif_assert_message(false, ("ARE not eliminated")); } } #ifdef CONVERT_TYPES {for(Iter<ArrayType> iter = object_iterator<ArrayType>(proc_def); iter.is_valid(); iter.next()) {suif_assert_message(false, ("ArrayType not eliminated"));}} #endif } }