QualifiedType* TransformUnrolledArraysPass::OneLessDimension(QualifiedType* original, int dimensionality) { ArrayType* topLevelType = dynamic_cast<ArrayType*>(original->get_base_type()) ; assert(topLevelType != NULL) ; if (dynamic_cast<ArrayType*>(topLevelType->get_element_type()->get_base_type()) != NULL) { ArrayType* nextLevel = dynamic_cast<ArrayType*>(topLevelType->get_element_type()->get_base_type()) ; return nextLevel->get_element_type() ; } else { return topLevelType->get_element_type() ; } }
DataType* ExportPass::CloneDataType(DataType* t) { assert(t != NULL) ; PointerType* pointerClone = dynamic_cast<PointerType*>(t) ; ReferenceType* referenceClone = dynamic_cast<ReferenceType*>(t) ; ArrayType* arrayClone = dynamic_cast<ArrayType*>(t) ; if (pointerClone != NULL) { QualifiedType* refType = dynamic_cast<QualifiedType*>(pointerClone->get_reference_type()) ; assert(refType != NULL) ; DataType* cloneType = CloneDataType(refType->get_base_type()) ; assert(cloneType != NULL) ; return create_pointer_type(theEnv, IInteger(32), 0, create_qualified_type(theEnv, cloneType)) ; } if (referenceClone != NULL) { QualifiedType* refType = dynamic_cast<QualifiedType*>(referenceClone->get_reference_type()) ; assert(refType != NULL) ; DataType* clonedType = CloneDataType(refType->get_base_type()) ; return create_reference_type(theEnv, IInteger(32), 0, create_qualified_type(theEnv, clonedType)) ; } if (arrayClone != NULL) { QualifiedType* elementType = arrayClone->get_element_type() ; DataType* internalType = CloneDataType(elementType->get_base_type()) ; QualifiedType* finalQual = create_qualified_type(theEnv, internalType) ; return create_pointer_type(theEnv, IInteger(32), 0, finalQual) ; } return dynamic_cast<DataType*>(t->deep_clone()) ; }
MultiDimArrayType* OneDimArrayConverter::array_type2multi_array_type(ArrayType* at){ suif_vector<ArrayType*> array_types; suif_map<ArrayType*, MultiDimArrayType*>::iterator type_iter = type_map->find(to<ArrayType>(at)); if (type_iter == type_map->end()) { suif_vector<Expression*> lower_bounds; suif_vector<Expression*> upper_bounds; suif_vector<ArrayType*> array_types; Type *type = at->get_element_type()->get_base_type(); array_types.push_back(at); // sub-types for this array type all_array_types->push_back(at); // all array types while (is_kind_of<ArrayType>(type)) { // unwrap array access ArrayType *atyp = to<ArrayType>(type); array_types.push_back(atyp); type = atyp->get_element_type()->get_base_type(); } // save lower and upper bounds for (int i = array_types.size()-1;i >=0;i--) { ArrayType *atyp = array_types[i]; lower_bounds.push_back(deep_suif_clone(atyp->get_lower_bound())); upper_bounds.push_back(deep_suif_clone(atyp->get_upper_bound())); } IInteger bit_size = to<DataType>(type)->get_bit_size(); IInteger bit_alignment = to<DataType>(type)->get_bit_alignment(); MultiDimArrayType* multi_type = tb->get_multi_dim_array_type( bit_size, bit_alignment.c_int(), tb->get_qualified_type(type), lower_bounds, upper_bounds); // save the translation in the map type_map->enter_value(at, multi_type); return multi_type; }else return (*type_iter).second; }
bool ConstantArrayPropagationPass::ValidSymbol(VariableSymbol* var) { assert(var != NULL) ; // The variable should be an array type and have the const qualifier. if (dynamic_cast<ArrayType*>(var->get_type()->get_base_type()) == NULL) { return false ; } QualifiedType* qualType = var->get_type() ; while (dynamic_cast<ArrayType*>(qualType->get_base_type()) != NULL) { ArrayType* array = dynamic_cast<ArrayType*>(qualType->get_base_type()) ; qualType = array->get_element_type() ; } assert(qualType != NULL) ; for (int i = 0 ; i < qualType->get_qualification_count(); ++i) { if (qualType->get_qualification(i) == LString("const")) { return true ; } } return false ; }
// All of the array references expressions in the passed in the struct are // equivalent, so we can determine types of the original and use that // to create a new expression with which to replace everything. bool TransformUnrolledArraysPass::ReplaceNDReference(EquivalentReferences* a) { assert(a != NULL) ; assert(a->original != NULL) ; // Check to see if the reference at this stage is a constant or not IntConstant* constantIndex = dynamic_cast<IntConstant*>(a->original->get_index()) ; if (constantIndex == NULL) { // There was no replacement made return false ; } Expression* baseAddress = a->original->get_base_array_address() ; assert(baseAddress != NULL) ; assert(constantIndex != NULL) ; // Create a replacement expression for this value. This will either // be another array reference expression or a single variable. Expression* replacementExp = NULL ; // QualifiedType* elementType = GetQualifiedTypeOfElement(a->original) ; VariableSymbol* originalSymbol = GetArrayVariable(a->original) ; assert(originalSymbol != NULL) ; LString replacementName = GetReplacementName(originalSymbol->get_name(), constantIndex->get_value().c_int()) ; int dimensionality = GetDimensionality(a->original) ; QualifiedType* elementType = originalSymbol->get_type() ; while (dynamic_cast<ArrayType*>(elementType->get_base_type()) != NULL) { elementType = dynamic_cast<ArrayType*>(elementType->get_base_type())->get_element_type() ; } // There is a special case for one dimensional arrays as opposed to all // other dimensional arrays. It only should happen if we are truly // replacing an array with a one dimensional array. if (dimensionality == 1 && dynamic_cast<ArrayReferenceExpression*>(a->original->get_parent())==NULL) { VariableSymbol* replacementVar = create_variable_symbol(theEnv, GetQualifiedTypeOfElement(a->original), TempName(replacementName)) ; procDef->get_symbol_table()->append_symbol_table_object(replacementVar) ; replacementExp = create_load_variable_expression(theEnv, elementType->get_base_type(), replacementVar) ; } else { // Create a new array with one less dimension. This requires a new // array type. ArrayType* varType = dynamic_cast<ArrayType*>(originalSymbol->get_type()->get_base_type()) ; assert(varType != NULL) ; ArrayType* replacementArrayType = create_array_type(theEnv, varType->get_element_type()->get_base_type()->get_bit_size(), 0, // bit alignment OneLessDimension(originalSymbol->get_type(), dimensionality), dynamic_cast<Expression*>(varType->get_lower_bound()->deep_clone()), dynamic_cast<Expression*>(varType->get_upper_bound()->deep_clone()), TempName(varType->get_name())) ; procDef->get_symbol_table()->append_symbol_table_object(replacementArrayType) ; VariableSymbol* replacementArraySymbol = create_variable_symbol(theEnv, create_qualified_type(theEnv, replacementArrayType, TempName(LString("qualType"))), TempName(replacementName)) ; procDef->get_symbol_table()->append_symbol_table_object(replacementArraySymbol) ; // Create a new symbol address expression for this variable symbol SymbolAddressExpression* replacementAddrExp = create_symbol_address_expression(theEnv, replacementArrayType, replacementArraySymbol) ; // Now, replace the symbol address expression in the base // array address with this symbol. ReplaceSymbol(a->original, replacementAddrExp) ; // And replace this reference with the base array address. replacementExp = a->original->get_base_array_address() ; a->original->set_base_array_address(NULL) ; replacementExp->set_parent(NULL) ; } // Replace all of the equivalent expressions with the newly generated // replacement expression. assert(replacementExp != NULL) ; a->original->get_parent()->replace(a->original, replacementExp) ; // ReplaceChildExpression(a->original->get_parent(), // a->original, // replacementExp) ; list<ArrayReferenceExpression*>::iterator equivIter = a->allEquivalent.begin() ; while (equivIter != a->allEquivalent.end()) { (*equivIter)->get_parent()->replace((*equivIter), dynamic_cast<Expression*>(replacementExp->deep_clone())) ; // ReplaceChildExpression((*equivIter)->get_parent(), // (*equivIter), // dynamic_cast<Expression*>(replacementExp->deep_clone())) ; ++equivIter ; } return true ; }
static void dismantle_multi_dim_array_expression( SuifEnv *env, MultiDimArrayExpression *exp, TypeBuilder *type_builder, suif_hash_map<MultiDimArrayType *,Type *> &type_map) { Expression *ref_exp = exp->get_array_address(); Type *typ = ref_exp->get_result_type(); if (is_kind_of<PointerType>(typ)) typ = to<PointerType>(typ)->get_reference_type(); if (is_kind_of<ReferenceType>(typ)) typ = to<ReferenceType>(typ)->get_reference_type(); if (is_kind_of<QualifiedType>(typ)) typ = to<QualifiedType>(typ)->get_base_type(); simple_stack<Expression *> lows; int dims; Type *rep_type; if (is_kind_of<MultiDimArrayType>(typ)) { MultiDimArrayType *mdatyp= to<MultiDimArrayType>(typ); suif_hash_map<MultiDimArrayType *,Type *>::iterator iter = type_map.find(mdatyp); kernel_assert_message(iter != type_map.end(), ("Error - type not converted")); rep_type = (*iter).second; dims = exp->get_index_count(); for (int i = dims - 1;i >=0 ; i--) { lows.push(mdatyp->get_lower_bound(i)); } } else { // this arm should never be taken, so assert kernel_assert_message(false,("This code should not have been accessed")); rep_type = typ; dims = 0; while (is_kind_of<ArrayType>(typ)) { ArrayType *atype = to<ArrayType>(typ); dims ++; lows.push(atype->get_lower_bound()); typ = to<QualifiedType>(atype->get_element_type())->get_base_type(); } } exp->replace(ref_exp,0); ref_exp->set_parent(0); int index_count = exp->get_index_count(); for (int i = 0;i < index_count;i ++) { Type *ref_type = rep_type; for (int j = 0;j <= i;j ++) { ref_type = type_builder->unqualify_type(ref_type); ref_type = to<ArrayType>(ref_type)->get_element_type(); } ref_type = type_builder->unqualify_type(ref_type); ref_type = type_builder->get_pointer_type(ref_type); Expression *index = exp->get_index(index_count - i - 1); // process nested multi dim arra expressions for (Iter<MultiDimArrayExpression> iter = object_iterator<MultiDimArrayExpression>(index); iter.is_valid(); iter.next()) { MultiDimArrayExpression *mexpr = &iter.current(); dismantle_multi_dim_array_expression(env,mexpr,type_builder,type_map); } exp->replace(index,0); index->set_parent(0); ref_exp = create_array_reference_expression( env,to<DataType>(ref_type),ref_exp, index); } exp->get_parent()->replace(exp,ref_exp); }