// Turn an reference pointer into an array reference expression void ReferenceCleanupPass::CleanupArrayStore(StoreStatement* s) { assert(s != NULL) ; // Check to see if the destination is a reference variable Expression* destination = s->get_destination_address() ; VariableSymbol* storedVariable = FindVariable(destination) ; if (storedVariable == NULL) { return ; } if (dynamic_cast<ReferenceType*>(storedVariable->get_type()->get_base_type())) { // Can I just change the type? Pointer conversion should take care of it // then, but I'll have to annotate it ReferenceType* refType = dynamic_cast<ReferenceType*>(storedVariable->get_type()->get_base_type()) ; QualifiedType* internalType = dynamic_cast<QualifiedType*>(refType->get_reference_type()) ; assert(internalType != NULL) ; DataType* internalType2 = internalType->get_base_type() ; QualifiedType* qualType = storedVariable->get_type() ; qualType->set_base_type(NULL) ; refType->set_parent(NULL) ; internalType->set_parent(NULL) ; refType->set_reference_type(NULL) ; qualType->set_base_type(internalType2) ; } }
void LUTDetectionPass::do_procedure_definition(ProcedureDefinition* p) { procDef = p ; assert(procDef != NULL) ; OutputInformation("LUT Detection Pass begins") ; // LUTs can only exist in New Style Systems or Modules if (isLegacy(procDef)) { OutputInformation("Legacy code - No LUTs supported") ; return ; } // LUTs are defined to be arrays that are not parameter symbols SymbolTable* symTab = procDef->get_symbol_table() ; for (int i = 0 ; i < symTab->get_symbol_table_object_count() ; ++i) { SymbolTableObject* currentObject = symTab->get_symbol_table_object(i) ; VariableSymbol* currentVar = dynamic_cast<VariableSymbol*>(currentObject) ; ParameterSymbol* currentParam = dynamic_cast<ParameterSymbol*>(currentObject) ; if (currentVar != NULL && dynamic_cast<ArrayType*>(currentVar->get_type()->get_base_type()) != NULL && currentParam == NULL && currentVar->lookup_annote_by_name("ConstPropArray") == NULL) { // Found one! Let's mark it! currentObject->append_annote(create_brick_annote(theEnv, "LUT")) ; } } OutputInformation("LUT Detection Pass ends") ; }
void ExportPass::ConstructModuleSymbols() { CProcedureType* originalType = dynamic_cast<CProcedureType*>(originalProcedure->get_procedure_symbol()->get_type()) ; assert(originalType != NULL) ; // The original type takes and returns a struct. We need to change this // to a list of arguments. VoidType* newReturnType = create_void_type(theEnv, IInteger(0), 0) ; constructedType = create_c_procedure_type(theEnv, newReturnType, false, // has varargs true, // arguments_known 0, // bit alignment LString("ConstructedType")) ; StructType* returnType = dynamic_cast<StructType*>(originalType->get_result_type()) ; assert(returnType != NULL) ; SymbolTable* structSymTab = returnType->get_group_symbol_table() ; assert(structSymTab != NULL) ; for (int i = 0 ; i < structSymTab->get_symbol_table_object_count() ; ++i) { VariableSymbol* nextVariable = dynamic_cast<VariableSymbol*>(structSymTab->get_symbol_table_object(i)); if (nextVariable != NULL) { // Check to see if this is an output or not QualifiedType* cloneType ; DataType* cloneBase = dynamic_cast<DataType*>(nextVariable->get_type()->get_base_type()->deep_clone()) ; assert(cloneBase != NULL) ; cloneType = create_qualified_type(theEnv, cloneBase) ; if (nextVariable->lookup_annote_by_name("Output") != NULL) { cloneType->append_annote(create_brick_annote(theEnv, "Output")) ; // Why doesn't this stick around? } constructedType->append_argument(cloneType) ; } } constructedSymbol = create_procedure_symbol(theEnv, constructedType, originalProcedure->get_procedure_symbol()->get_name()) ; constructedSymbol->set_definition(NULL) ; }
void ReferenceCleanupPass::CleanupCall(CallStatement* c) { assert(procDef != NULL) ; assert(c != NULL) ; // We only need to clean up module calls. If they are built in // functions, like boolsel, we don't want to do this. if (IsBuiltIn(c)) { return ; } // Go through the arguments and see if any of them are load variable // expressions to a reference typed variable, and replace those with // symbol address expressions for (unsigned int i = 0 ; i < c->get_argument_count() ; ++i) { Expression* currentArg = c->get_argument(i) ; LoadVariableExpression* currentLoadVar = dynamic_cast<LoadVariableExpression*>(currentArg) ; if (currentLoadVar != NULL) { VariableSymbol* currentVar = currentLoadVar->get_source() ; DataType* varType = currentVar->get_type()->get_base_type() ; ReferenceType* refType = dynamic_cast<ReferenceType*>(varType) ; if (refType != NULL) { QualifiedType* internalType = dynamic_cast<QualifiedType*>(refType->get_reference_type()) ; assert(internalType != NULL) ; // currentVar->set_type(internalType) ; SymbolAddressExpression* symAddrExp = create_symbol_address_expression(theEnv, internalType->get_base_type(), currentVar) ; if (currentLoadVar->lookup_annote_by_name("UndefinedPath") != NULL) { symAddrExp->append_annote(create_brick_annote(theEnv, "UndefinedPath")) ; } currentLoadVar->get_parent()->replace(currentLoadVar, symAddrExp) ; } } } }
void CleanupRedundantVotes::ProcessCall(CallStatement* c) { assert(c != NULL) ; SymbolAddressExpression* symAddress = dynamic_cast<SymbolAddressExpression*>(c->get_callee_address()) ; assert(symAddress != NULL) ; Symbol* sym = symAddress->get_addressed_symbol() ; assert(sym != NULL) ; if (sym->get_name() == LString("ROCCCTripleVote") || sym->get_name() == LString("ROCCCDoubleVote") ) { LoadVariableExpression* errorVariableExpression = dynamic_cast<LoadVariableExpression*>(c->get_argument(0)) ; assert(errorVariableExpression != NULL) ; VariableSymbol* currentError = errorVariableExpression->get_source() ; assert(currentError != NULL) ; if (InList(currentError)) { // Create a new variable VariableSymbol* errorDupe = create_variable_symbol(theEnv, currentError->get_type(), TempName(LString("UnrolledRedundantError"))) ; errorDupe->append_annote(create_brick_annote(theEnv, "DebugRegister")) ; procDef->get_symbol_table()->append_symbol_table_object(errorDupe) ; usedVariables.push_back(errorDupe) ; errorVariableExpression->set_source(errorDupe) ; } else { usedVariables.push_back(currentError) ; } } }
void ScalarReplacementPass2::ProcessLoad(LoadExpression* e) { assert(e != NULL) ; Expression* innerExp = e->get_source_address() ; ArrayReferenceExpression* innerRef = dynamic_cast<ArrayReferenceExpression*>(innerExp) ; if (innerRef == NULL) { return ; } // Again, don't process lookup tables if (IsLookupTable(GetArrayVariable(innerRef))) { return ; } VariableSymbol* replacement = NULL ; list<std::pair<Expression*, VariableSymbol*> >::iterator identIter = Identified.begin() ; while (identIter != Identified.end()) { if (EquivalentExpressions((*identIter).first, innerRef)) { replacement = (*identIter).second ; break ; } ++identIter ; } assert(replacement != NULL) ; LoadVariableExpression* loadVar = create_load_variable_expression(theEnv, replacement->get_type()->get_base_type(), replacement) ; e->get_parent()->replace(e, loadVar) ; }
// 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 ; }
Statement *for_statement_walker::dismantle_for_statement(ForStatement *the_for){ StatementList *replacement = create_statement_list(the_for->get_suif_env()); VariableSymbol* index = the_for->get_index(); DataType *type = unqualify_data_type(index->get_type()); Expression *lower = the_for->get_lower_bound(); Expression *upper = the_for->get_upper_bound(); Expression *step = the_for->get_step(); LString compare_op = the_for->get_comparison_opcode(); Statement* body = the_for->get_body(); Statement* pre_pad = the_for->get_pre_pad(); // Statement* post_pad = the_for->get_post_pad(); CodeLabelSymbol* break_lab = the_for->get_break_label(); CodeLabelSymbol* continue_lab = the_for->get_continue_label(); the_for->set_index(0); remove_suif_object(lower); remove_suif_object(upper); remove_suif_object(step); remove_suif_object(body); remove_suif_object(pre_pad); // the_for->set_post_pad(0); // remove_suif_object(post_pad); the_for->set_break_label(0); the_for->set_continue_label(0); // I am guessing what pre-pad and post-pad do if(pre_pad != 0)replacement->append_statement(pre_pad); // initialize the index. Is this right? should we ever initialize to upper, for -ve steps? // Is index guaranteed not to be changed? Should we be creating a temporary? replacement->append_statement(create_store_variable_statement(body->get_suif_env(),index,lower)); replacement->append_statement(create_label_location_statement(body->get_suif_env(), continue_lab)); if (body != 0) replacement->append_statement(body); // increment the counter Expression *index_expr = create_load_variable_expression(body->get_suif_env(), unqualify_data_type(index->get_type()), index); Expression *increment = create_binary_expression(body->get_suif_env(),type,k_add, index_expr,step); replacement->append_statement(create_store_variable_statement(body->get_suif_env(),index,increment)); // and loop if not out of range Expression *compare = create_binary_expression(body->get_suif_env(),type, compare_op, deep_suif_clone<Expression>(index_expr), deep_suif_clone<Expression>(step)); replacement->append_statement(create_branch_statement(body->get_suif_env(),compare,continue_lab)); // end of loop replacement->append_statement(create_label_location_statement(body->get_suif_env(),break_lab)); // if(post_pad != 0)replacement->append_statement(post_pad); the_for->get_parent()->replace(the_for,replacement); return replacement; }
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 } }