static String handle_static_array_reference_expression(CPrintStyleModule *state, const SuifObject *obj) { ArrayReferenceExpression *expr = to<ArrayReferenceExpression>(obj); String base = state->print_to_string(expr->get_base_array_address()); String idx = state->print_to_string(expr->get_index()); return(String("&(") + base + "[" + idx + "])"); }
Walker::ApplyStatus pp_array_reference_expression_walker::operator () (SuifObject *x) { SuifEnv *env = get_env(); ArrayReferenceExpression *array_ref_expr = to<ArrayReferenceExpression>(x); if(array_ref_expr->lookup_annote_by_name("array_ref_info")) delete (array_ref_expr->remove_annote_by_name("array_ref_info")); BrickAnnote *array_ref_info_annote = create_brick_annote(env, "array_ref_info"); // Removed by Jason to make my life a little easier // Reinstated to get systolic array working again... array_ref_expr->append_annote(array_ref_info_annote); // Also, create an annote to help me later... BrickAnnote* array_ref_info_annote2 = create_brick_annote(env, "array_ref_info") ; // Added by Jason to make my life a little easier //dynamic_cast<SymbolAddressExpression*>(array_ref_expr->get_base_array_address())->get_addressed_symbol()->append_annote(array_ref_info_annote) ; // Modified by Jason on 3/24/2009 // The previous version did not work with multidimensional arrays ArrayReferenceExpression* currentCast = array_ref_expr ; while(dynamic_cast<SymbolAddressExpression*>(currentCast->get_base_array_address()) == NULL) { currentCast = dynamic_cast<ArrayReferenceExpression*>(currentCast->get_base_array_address()) ; assert(currentCast != NULL) ; } dynamic_cast<SymbolAddressExpression*>(currentCast->get_base_array_address())->get_addressed_symbol()->append_annote(array_ref_info_annote2) ; // Unfortunately, this causes problems in the strip annotes phase // so I need to change that as well. ArrayInfo *array_ref_info = new ArrayInfo(); Expression *base_array_address = array_ref_expr; Expression *index = NULL; int dimension = 0; do{ index = (to<ArrayReferenceExpression>(base_array_address))->get_index(); String var = get_var(index); int a = get_a(index); int c = get_c(index); array_ref_info->push_front_index_var_name(var); array_ref_info->push_front_a(a); array_ref_info->push_front_c(c); dimension++; base_array_address = (to<ArrayReferenceExpression>(base_array_address))->get_base_array_address(); }while(is_a<ArrayReferenceExpression>(base_array_address)); SymbolAddressExpression *array_sym_expr = to<SymbolAddressExpression>(base_array_address); VariableSymbol *array_sym = to<VariableSymbol>(array_sym_expr->get_addressed_symbol()); array_ref_info->set_array_symbol_name(array_sym->get_name()); array_ref_info->set_dimension(dimension); array_ref_info_annote->append_brick(create_suif_object_brick(env, array_ref_info)); // Added for my benefit array_ref_info_annote2->append_brick(create_suif_object_brick(env, array_ref_info)) ; return Walker::Truncate; }
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 } }
/** 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); }
void ConstantArrayPropagationPass::ReplaceLoad(LoadExpression* load, ArrayReferenceExpression* ref, VariableSymbol* var, ValueBlock* topBlock) { list<IntConstant*> allDimensions ; IntConstant* nextIndex = dynamic_cast<IntConstant*>(ref->get_index()) ; if (nextIndex == NULL) { OutputWarning("Trying to access a constant array with a nonconstant index!") ; delete var->remove_annote_by_name("ConstPropArray") ; // assert(0) ; return ; } allDimensions.push_front(nextIndex) ; ArrayReferenceExpression* nextDimension = dynamic_cast<ArrayReferenceExpression*>(ref->get_base_array_address()) ; while (nextDimension != NULL) { nextIndex = dynamic_cast<IntConstant*>(nextDimension->get_index()) ; assert(nextIndex != NULL) ; allDimensions.push_front(nextIndex) ; nextDimension = dynamic_cast<ArrayReferenceExpression*>(nextDimension->get_base_array_address()) ; } ValueBlock* currentBlock = topBlock ; list<IntConstant*>::iterator dimIter = allDimensions.begin() ; for (int i = 0 ; i < allDimensions.size() ; ++i) { MultiValueBlock* multiBlock = dynamic_cast<MultiValueBlock*>(currentBlock); assert(multiBlock != NULL) ; currentBlock = multiBlock->lookup_sub_block((*dimIter)->get_value()) ; ++dimIter ; } ExpressionValueBlock* finalBlock = dynamic_cast<ExpressionValueBlock*>(currentBlock) ; assert(finalBlock != NULL && "Attempted to use an uninitialized constant value!") ; Expression* replacementValue = finalBlock->get_expression() ; if (dynamic_cast<IntConstant*>(replacementValue) != NULL) { IntConstant* constInt = dynamic_cast<IntConstant*>(replacementValue) ; IntConstant* replacement = create_int_constant(theEnv, constInt->get_result_type(), constInt->get_value()) ; load->get_parent()->replace(load, replacement) ; delete load ; } else if (dynamic_cast<FloatConstant*>(replacementValue) != NULL) { FloatConstant* constFloat = dynamic_cast<FloatConstant*>(replacementValue) ; FloatConstant* replacement = create_float_constant(theEnv, constFloat->get_result_type(), constFloat->get_value()) ; load->get_parent()->replace(load, replacement) ; delete load ; } else { assert(0 && "Unknown constant") ; } }