Example #1
0
/* this function searches an expression to see if it includes a loop invariant
 * atom */
static void search_expr_for_unchanged_atom(expr_t *expr, mloop_t *mloop) {
  int array=0;
  int numdims;
  int innerdim;

  if (expr  && T_TYPEINFO(expr) &&
      S_CLASS(T_TYPEINFO(expr))==DT_ARRAY) {
    array=1;
  }
  if (expr) {
    if (expr_is_atom(expr) && !array &&
	(T_TYPE(expr)!=ARRAY_REF || (expr_const(nthoperand(expr,2)) &&  
				     !expr_contains_indexi(nthoperand(expr,2))
				     && !expr_contains_ia_indexi(nthoperand(expr,2))))) {
      expr_t *typeinfo;
      datatype_t *type = NULL;
      expr_t* at_expr;

      at_expr = expr_find_at(expr);
      if (at_expr && T_SUBTYPE(at_expr) == AT_RANDACC) {
        return;
      }
      typeinfo = T_TYPEINFO_REG(expr);
      if (typeinfo) {
        type = T_TYPEINFO(typeinfo);
      }
      if (type && (D_CLASS(type) == DT_REGION)) {
	numdims = T_MLOOP_RANK(mloop);
	innerdim = T_MLOOP_ORDER(mloop,numdims);
	if (D_REG_DIM_TYPE(type, innerdim) == DIM_FLOOD) {
	  replace_expression(expr,mloop);
	}
      }
    } else if (T_TYPE(expr)!=ARRAY_REF) {
      search_expr_for_unchanged_atom(T_OPLS(expr),mloop);
    }
    search_expr_for_unchanged_atom(T_NEXT(expr),mloop);
  } /* if expr */

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