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 + "])"); }
/** 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") ; } }