void MarkRedundantPass::do_procedure_definition(ProcedureDefinition* proc_def) { procDef = proc_def ; assert(procDef != NULL) ; OutputInformation("Marking a redundant label") ; list<LabelLocationStatement*>* allLabels = collect_objects<LabelLocationStatement>(procDef->get_body()) ; list<LabelLocationStatement*>::iterator labelIter = allLabels->begin() ; while (labelIter != allLabels->end()) { if ((*labelIter)->get_defined_label()->get_name() == redundantLabel) { BrickAnnote* labelBrick = create_brick_annote(theEnv, "Redundant") ; IntegerBrick* doubleBrick = create_integer_brick(theEnv, IInteger(doubleOrTriple)) ; labelBrick->append_brick(doubleBrick) ; (*labelIter)->append_annote(labelBrick) ; } ++labelIter ; } delete allLabels ; OutputInformation("Done marking a redundant label") ; }
void SolveFeedbackVariablesPass3::SetupAnnotations(VariableSymbol* toAnnote, VariableSymbol* source, VariableSymbol* destination) { // Clean up any annotation that previously existed if (toAnnote->lookup_annote_by_name("FeedbackVariable") != NULL) { // Do I need to remove the bricks associated with this as well, or // does the destructor handle that? delete toAnnote->remove_annote_by_name("FeedbackVariable") ; } // Now create the annotation we will use BrickAnnote* feedbackAnnote = to<BrickAnnote>(create_brick_annote(theEnv, "FeedbackVariable")) ; // Create the bricks and add them to the annotation feedbackAnnote->append_brick(create_suif_object_brick(theEnv, destination)) ; feedbackAnnote->append_brick(create_suif_object_brick(theEnv, source)) ; // And finally attach the annotation to the variable toAnnote->append_annote(feedbackAnnote) ; // Mark this as non systolic if appropriate if (!isSystolic) { toAnnote->append_annote(create_brick_annote(theEnv,"NonSystolic")) ; } }
Walker::ApplyStatus hsbm_call_statement_walker::operator () (SuifObject *x) { SuifEnv *env = get_env(); CallStatement *call_stmt = to<CallStatement>(x); SymbolAddressExpression *callee_address = to<SymbolAddressExpression>(call_stmt->get_callee_address()); ProcedureSymbol *proc_symbol = to<ProcedureSymbol>(callee_address->get_addressed_symbol()); String called_proc_name = proc_symbol->get_name(); MarkStatement *mark_stmt = NULL; ProcedureDefinition* proc_def = get_procedure_definition(call_stmt); if(called_proc_name == String("begin_hw")){ mark_stmt = create_mark_statement(env); BrickAnnote *ba = to<BrickAnnote>(proc_def->lookup_annote_by_name("begin_hw")); ba->append_brick(create_suif_object_brick(env, mark_stmt)); }else if(called_proc_name == String("end_hw")){ mark_stmt = create_mark_statement(env); BrickAnnote *ba = to<BrickAnnote>(proc_def->lookup_annote_by_name("end_hw")); ba->append_brick(create_suif_object_brick(env, mark_stmt)); } if(mark_stmt){ call_stmt->get_parent()->replace(call_stmt, mark_stmt); set_address(mark_stmt); return Walker::Replaced; } return Walker::Continue; }
bool CopyPropagationPass2::IsOnlyDefinition(StoreVariableStatement* def, LoadVariableExpression* use) { BrickAnnote* defAnnote = to<BrickAnnote>(use->lookup_annote_by_name("reaching_defs")) ; assert(defAnnote != NULL) ; if (defAnnote->get_brick_count() != 1) { return false ; } SuifBrick* defBrick = defAnnote->get_brick(0) ; SuifObjectBrick* sob = dynamic_cast<SuifObjectBrick*>(defBrick) ; assert(sob != NULL) ; if (def == sob->get_object()) { return true ; } else { return false ; } }
/* Useful for printing annotations as comments. Expects that * the annotation is a BrickAnnote. */ void Printer::print_annote(Annote *annote) { start_comment(); IdString name = annote->get_name(); if (name != k_comment) fprintf(out, "[%s", name.chars()); if (is_kind_of<BrickAnnote>(annote)) { BrickAnnote *an = (BrickAnnote *)(annote); char *separator = ": "; for (Iter<SuifBrick*> iter = an->get_brick_iterator(); iter.is_valid(); iter.next()) { fputs(separator, out); separator = ", "; SuifBrick *brick = iter.current(); if (is_a<IntegerBrick>(brick)) { Integer i = ((IntegerBrick*)iter.current())->get_value(); if (i.is_c_string_int()) fputs(i.chars(), out); else fprintf(out, "%ld", i.c_long()); } else if (is_a<StringBrick>(brick)) { putc('"', out); for (const char *p = ((StringBrick*)iter.current())->get_value().c_str(); *p != '\0'; ++p) { if (*p == '"' || *p == '\\') putc('\\', out); putc(*p, out); } putc('"', out); } else { claim(is_a<SuifObjectBrick>(brick)); SuifObject *so = ((SuifObjectBrick*)brick)->get_object(); if (is_kind_of<Type>(so)) fprint(out, (TypeId)so); else { const char *kind = so ? get_class_name(so) : "NULL"; fprintf(out, "<<<%s object>>>", kind); } } } } else { claim(is_kind_of<GeneralAnnote>(annote), "Unexpected kind of Annote"); } if (name != k_comment) fputs("]", out); fputs("\n", out); }
void ExportPass::execute() { assert(theEnv != NULL) ; OutputInformation("Export pass begins") ; // Get the information regarding the current procedure by looking at // the first procedure from the first file in the file set block. Iter<FileBlock*> temp = theEnv->get_file_set_block()->get_file_block_iterator() ; Iter<ProcedureDefinition*> temp2 = (temp.current())->get_definition_block()->get_procedure_definition_iterator() ; originalProcedure = temp2.current() ; assert(originalProcedure != NULL) ; // Modules have been transformed into structs so all the previous // passes work, and here we have to do a little bit of backtracking // and convert them to the straight model. BrickAnnote* rocccType = dynamic_cast<BrickAnnote*>(originalProcedure->lookup_annote_by_name("FunctionType")) ; assert(rocccType != NULL) ; IntegerBrick* valueBrick = dynamic_cast<IntegerBrick*>(rocccType->get_brick(0)) ; assert(valueBrick != NULL) ; int functionType = valueBrick->get_value().c_int() ; delete rocccType->remove_brick(0) ; delete originalProcedure->remove_annote_by_name("FunctionType") ; if (functionType == 1) // Module { // De-modulize it ConstructModuleSymbols() ; } else if (functionType == 2 || functionType == 3) // Systems { // Just create clones ConstructSystemSymbols() ; } else { assert(0 && "Trying to export something unknown") ; } ReadRepository() ; AddSymbols() ; DumpRepository() ; OutputInformation("Export pass ends") ; }
static String handle_static_mark_statement(CPrintStyleModule *state, const SuifObject *obj) { MarkStatement *stmt = to<MarkStatement>(obj); String return_str; BrickAnnote *br = to<BrickAnnote>(stmt->peek_annote("line")); return_str = "Mark"; if (br != 0) { String file = to<StringBrick>(br->get_brick(1))->get_value(); IInteger line = to<IntegerBrick>(br->get_brick(0))->get_value(); return_str += " "; return_str += file + ":" + line.to_String(); } return(return_str); }
void CopyPropagationPass2::HandleFeedbackVariables(LoadVariableExpression* n, VariableSymbol* replacement) { assert(n != NULL) ; assert(replacement != NULL) ; VariableSymbol* toReplace = n->get_source() ; // Go through all the feedback variables list<VariableSymbol*>::iterator feedbackIter = feedbackVariables.begin() ; while (feedbackIter != feedbackVariables.end()) { BrickAnnote* nextAnnote = to<BrickAnnote>((*feedbackIter)->lookup_annote_by_name("FeedbackVariable")) ; assert(nextAnnote != NULL) ; SuifBrick* one = nextAnnote->get_brick(0) ; SuifBrick* two = nextAnnote->get_brick(1) ; SuifObjectBrick* firstObj = dynamic_cast<SuifObjectBrick*>(one) ; SuifObjectBrick* secondObj = dynamic_cast<SuifObjectBrick*>(two) ; assert(firstObj != NULL) ; assert(secondObj != NULL) ; VariableSymbol* dest = dynamic_cast<VariableSymbol*>(firstObj->get_object()) ; VariableSymbol* source = dynamic_cast<VariableSymbol*>(secondObj->get_object()) ; assert(dest != NULL) ; assert(source != NULL) ; if (dest == toReplace) { firstObj->set_object(replacement) ; } if (source == toReplace) { secondObj->set_object(replacement) ; } ++feedbackIter ; } }
void CleanupBoolSelsPass::do_procedure_definition(ProcedureDefinition* p) { procDef = p ; assert(procDef != NULL) ; OutputInformation("Cleanup Boolean Select Pass Begins") ; // Find all of the locations that have been marked as "UndefinedPath" Annote* functionAnnote = procDef->lookup_annote_by_name("FunctionType") ; BrickAnnote* functionBrickAnnote = dynamic_cast<BrickAnnote*>(functionAnnote) ; assert(functionBrickAnnote != NULL) ; IntegerBrick* valueBrick = dynamic_cast<IntegerBrick*>(functionBrickAnnote->get_brick(0)) ; assert(valueBrick != NULL) ; int myType = valueBrick->get_value().c_int() ; if (myType == MODULE) { // Find all of the expressions marked "UndefinedPath" and replace with // the integer constant zero. list<Expression*>* allExpr = collect_objects<Expression>(procDef->get_body()) ; list<Expression*>::iterator exprIter = allExpr->begin() ; while (exprIter != allExpr->end()) { if ((*exprIter)->lookup_annote_by_name("UndefinedPath") != NULL) { Expression* zero = create_int_constant(theEnv, (*exprIter)->get_result_type(), IInteger(0)) ; (*exprIter)->get_parent()->replace((*exprIter), zero) ; } ++exprIter ; } delete allExpr ; } OutputInformation("Cleanup Boolean Select Pass Ends") ; }
void ExportPass::ConstructSystemSymbols() { ProcedureSymbol* originalSymbol = originalProcedure->get_procedure_symbol() ; assert(originalSymbol != NULL) ; CProcedureType* originalType = dynamic_cast<CProcedureType*>(originalSymbol->get_type()) ; assert(originalType != NULL) ; constructedType = create_c_procedure_type(theEnv, dynamic_cast<DataType*>(originalType->get_result_type()->deep_clone()), false, // has variable arguments false, // arguments known 0) ; // bit alignment // The system has been written in one of two ways, either the old // way where there are no arguments, or the new way where everything // is put into the arguments. if (originalType->get_argument_count() > 0) { for (int i = 0 ; i < originalType->get_argument_count() ; ++i) { QualifiedType* originalArgument = originalType->get_argument(i) ; DataType* originalBase = originalArgument->get_base_type() ; DataType* constructedBase = CloneDataType(originalBase) ; QualifiedType* constructedArgument = create_qualified_type(theEnv, constructedBase) ; constructedType->append_argument(constructedArgument) ; // Go through the symbol table and find the parameter symbol // that matches the parameter number, and check to see if it // is an output or not... SymbolTable* symTab = originalProcedure->get_symbol_table() ; ParameterSymbol* correspondingSymbol = NULL ; for (int j = 0 ; j < symTab->get_symbol_table_object_count() ; ++j) { ParameterSymbol* currentSym = dynamic_cast<ParameterSymbol*>(symTab->get_symbol_table_object(j)) ; if (currentSym != NULL) { BrickAnnote* orderAnnote = dynamic_cast<BrickAnnote*>(currentSym->lookup_annote_by_name("ParameterOrder")) ; assert(orderAnnote != NULL) ; IntegerBrick* orderBrick = dynamic_cast<IntegerBrick*>(orderAnnote->get_brick(0)) ; assert(orderBrick != NULL) ; if (orderBrick->get_value().c_int() == i) { correspondingSymbol = currentSym ; break ; } } } if (correspondingSymbol != NULL) { if (correspondingSymbol->lookup_annote_by_name("OutputScalar") != NULL || correspondingSymbol->lookup_annote_by_name("OutputVariable") != NULL || correspondingSymbol->lookup_annote_by_name("OutputFifo") != NULL) { constructedArgument->append_annote(create_brick_annote(theEnv, "Output")) ; } } // if (dynamic_cast<ReferenceType*>(originalBase) != NULL) //{ // constructedArgument->append_annote(create_brick_annote(theEnv, // "Output")) ; // } } } else { SymbolTable* symTab = originalProcedure->get_symbol_table() ; assert(symTab != NULL) ; list<VariableSymbol*> inputScalars ; list<VariableSymbol*> inputFifos ; list<VariableSymbol*> outputScalars ; list<VariableSymbol*> outputFifos ; for (int i = 0 ; i < symTab->get_symbol_table_object_count() ; ++i) { VariableSymbol* currentVar = dynamic_cast<VariableSymbol*>(symTab->get_symbol_table_object(i)) ; if (currentVar != NULL && currentVar->lookup_annote_by_name("InputScalar") != NULL && currentVar->lookup_annote_by_name("TemporalFeedback") == NULL && currentVar->lookup_annote_by_name("NormalFeedback") == NULL && currentVar->lookup_annote_by_name("DebugRegister") == NULL) { inputScalars.push_back(currentVar) ; } if (currentVar != NULL && currentVar->lookup_annote_by_name("InputFifo") != NULL) { inputFifos.push_back(currentVar) ; } if (currentVar != NULL && currentVar->lookup_annote_by_name("OutputVariable") != NULL && currentVar->lookup_annote_by_name("Dummy") == NULL && currentVar->lookup_annote_by_name("FeedbackSource") == NULL) { outputScalars.push_back(currentVar) ; } if (currentVar != NULL && currentVar->lookup_annote_by_name("OutputFifo") != NULL) { outputFifos.push_back(currentVar) ; } } // Add the types of the input scalars, then the input fifos, // then the output scalars, and finally the output fifos. list<VariableSymbol*>::iterator varIter = inputScalars.begin() ; while (varIter != inputScalars.end()) { QualifiedType* originalQual = (*varIter)->get_type() ; assert(originalQual != NULL) ; DataType* originalBase = originalQual->get_base_type() ; assert(originalBase != NULL) ; DataType* constructedBase = dynamic_cast<DataType*>(originalBase->deep_clone()) ; QualifiedType* constructedQual = create_qualified_type(theEnv, constructedBase) ; constructedType->append_argument(constructedQual) ; ++varIter ; } varIter = inputFifos.begin() ; while (varIter != inputFifos.end()) { QualifiedType* originalQual = (*varIter)->get_type() ; assert(originalQual != NULL) ; DataType* originalBase = originalQual->get_base_type() ; assert(originalBase != NULL) ; // Fifos will have pointer types or reference types. A // simple deep clone will not suffice, I need to build up a // new type from the bottom up. DataType* constructedBase = CloneDataType(originalBase) ; assert(constructedBase != NULL) ; QualifiedType* constructedQual = create_qualified_type(theEnv, constructedBase) ; assert(constructedBase != NULL) ; assert(constructedType != NULL) ; constructedType->append_argument(constructedQual) ; ++varIter ; } varIter = outputScalars.begin() ; while (varIter != outputScalars.end()) { QualifiedType* originalQual = (*varIter)->get_type() ; DataType* originalBase = originalQual->get_base_type() ; DataType* constructedBase = CloneDataType(originalBase) ; QualifiedType* constructedQual = create_qualified_type(theEnv, constructedBase) ; constructedQual->append_annote(create_brick_annote(theEnv, "Output")) ; constructedType->append_argument(constructedQual) ; ++varIter ; } varIter = outputFifos.begin() ; while (varIter != outputFifos.end()) { QualifiedType* originalQual = (*varIter)->get_type() ; assert(originalQual != NULL) ; DataType* originalBase = originalQual->get_base_type() ; assert(originalBase != NULL) ; DataType* constructedBase = CloneDataType(originalBase) ; assert(constructedBase != NULL) ; QualifiedType* constructedQual = create_qualified_type(theEnv, constructedBase) ; assert(constructedQual != NULL) ; constructedQual->append_annote(create_brick_annote(theEnv, "Output")) ; assert(constructedType != NULL) ; constructedType->append_argument(constructedQual) ; ++varIter ; } } constructedSymbol = create_procedure_symbol(theEnv, constructedType, originalProcedure->get_procedure_symbol()->get_name()) ; }
Walker::ApplyStatus mdbm_c_for_statement_walker::operator () (SuifObject *x) { SuifEnv *env = get_env(); CForStatement *c_for_stmt = to<CForStatement>(x); // if(!is_stmt_within_begin_end_hw_marks(c_for_stmt)) // return Walker::Continue; Statement *body = c_for_stmt->get_body(); if (body){ Iter<CForStatement> iter_c_for = object_iterator<CForStatement>(body); if(iter_c_for.is_valid()) return Walker::Continue; StatementList *stmt_list_body = NULL; if(is_a<StatementList>(body)) stmt_list_body = to<StatementList>(body); else{ stmt_list_body = create_statement_list(env); c_for_stmt->set_body(0); stmt_list_body->append_statement(body); c_for_stmt->set_body(stmt_list_body); } Iter<Statement*> iter = stmt_list_body->get_statement_iterator(); for( ; iter.is_valid(); iter.next()){ Statement *child_stmt = iter.current(); if(is_a<StoreVariableStatement>(child_stmt)){ Iter<LoadExpression> iter2 = object_iterator<LoadExpression>(child_stmt); if(!iter2.is_valid()) break; }else break; } MarkStatement *end_of_mem_reads_mark = create_mark_statement(env); if(iter.is_valid()) insert_statement_before(iter.current(), end_of_mem_reads_mark); else stmt_list_body->insert_statement(0, end_of_mem_reads_mark); BrickAnnote *ba = create_brick_annote(env, "end_of_mem_reads"); ba->append_brick(create_suif_object_brick(env, end_of_mem_reads_mark)); c_for_stmt->append_annote(ba); for( ; iter.is_valid(); iter.next()){ Statement *child_stmt = iter.current(); if(is_a<StoreStatement>(child_stmt)) break; } MarkStatement *beg_of_mem_writes_mark = create_mark_statement(env); if(iter.is_valid()) insert_statement_before(iter.current(), beg_of_mem_writes_mark); else stmt_list_body->append_statement(beg_of_mem_writes_mark); ba = create_brick_annote(env, "beg_of_mem_writes"); ba->append_brick(create_suif_object_brick(env, beg_of_mem_writes_mark)); c_for_stmt->append_annote(ba); } return Walker::Continue; }
void TransformSystemsToModules::Transform() { assert(procDef != NULL) ; // Collect all the input scalars and output scalars list<VariableSymbol*> ports ; SymbolTable* procSymTab = procDef->get_symbol_table() ; bool foundInputs = false ; bool foundOutputs = false ; for (int i = 0 ; i < procSymTab->get_symbol_table_object_count() ; ++i) { SymbolTableObject* nextObject = procSymTab->get_symbol_table_object(i) ; if (nextObject->lookup_annote_by_name("InputScalar") != NULL) { VariableSymbol* toConvert = dynamic_cast<VariableSymbol*>(nextObject) ; assert(toConvert != NULL) ; LString inputName = toConvert->get_name() ; inputName = inputName + "_in" ; toConvert->set_name(inputName) ; ports.push_back(toConvert) ; foundInputs = true ; } if (nextObject->lookup_annote_by_name("OutputVariable") != NULL) { VariableSymbol* toConvert = dynamic_cast<VariableSymbol*>(nextObject) ; assert(toConvert != NULL) ; LString outputName = toConvert->get_name() ; outputName = outputName + "_out" ; toConvert->set_name(outputName) ; ports.push_back(toConvert) ; foundOutputs = true ; } } assert(foundInputs && "Could not identify inputs. Were they removed via optimizations?") ; assert(foundOutputs && "Could not identify outputs. Were they removed via optimizations?") ; // Determine the bit size and add everything to a new symbol table int bitSize = 0 ; GroupSymbolTable* structTable = create_group_symbol_table(theEnv, procDef->get_symbol_table()) ; std::map<VariableSymbol*, FieldSymbol*> replacementFields ; bool portsRemoved = false ; // If this was actually a new style module, we should make sure to // put these in the correct order. if (isModule(procDef)) { // Go through the original symbol table and remove any parameter // symbols that originally existed SymbolTable* originalSymTab = procDef->get_symbol_table() ; Iter<SymbolTableObject*> originalIter = originalSymTab->get_symbol_table_object_iterator() ; while (originalIter.is_valid()) { SymbolTableObject* currentObj = originalIter.current() ; originalIter.next() ; if (dynamic_cast<ParameterSymbol*>(currentObj) != NULL) { originalSymTab->remove_symbol_table_object(currentObj) ; } } portsRemoved = true ; // Sort the variable symbols in parameter order. This is just an // insertion sort, so it could be done faster. list<VariableSymbol*> sortedPorts ; for (int i = 0 ; i < ports.size() ; ++i) { list<VariableSymbol*>::iterator portIter = ports.begin() ; while (portIter != ports.end()) { BrickAnnote* orderAnnote = dynamic_cast<BrickAnnote*>((*portIter)-> lookup_annote_by_name("ParameterOrder")) ; if (orderAnnote == NULL) { ++portIter ; continue ; } IntegerBrick* orderBrick = dynamic_cast<IntegerBrick*>(orderAnnote->get_brick(0)) ; assert(orderBrick != NULL) ; if (orderBrick->get_value().c_int() == i) { sortedPorts.push_back(*portIter) ; break ; } ++portIter ; } } if (sortedPorts.size() != ports.size()) { OutputWarning("Warning! Analysis detected some input scalars not in" " the parameter list") ; } // Replace ports with sortedPorts ports = sortedPorts ; } list<VariableSymbol*>::iterator portIter = ports.begin() ; while (portIter != ports.end()) { bitSize += (*portIter)->get_type()->get_base_type()->get_bit_size().c_int() ; LString dupeName = (*portIter)->get_name() ; // Create offset expression: IntConstant* offset = create_int_constant(theEnv, create_data_type(theEnv, IInteger(32), 0), IInteger(bitSize)) ; QualifiedType* dupeType = (*portIter)->get_type() ; // Deal with the case where reference types were passed in ReferenceType* refType = dynamic_cast<ReferenceType*>(dupeType->get_base_type()) ; while (refType != NULL) { dupeType = dynamic_cast<QualifiedType*>(refType->get_reference_type()) ; assert(dupeType != NULL) ; refType = dynamic_cast<ReferenceType*>(dupeType->get_base_type()) ; } // Create a new variable symbol clone FieldSymbol* dupe = create_field_symbol(theEnv, dupeType, offset, dupeName) ; structTable->append_symbol_table_object(dupe) ; // Make the connection with the duplicated symbol replacementFields[(*portIter)] = dupe ; // Remove the original variable symbol from the procedure definition // symbol table. if (!portsRemoved) { procDef->get_symbol_table()->remove_symbol_table_object(*portIter) ; } ++portIter ; } assert(bitSize != 0); StructType* moduleStruct = create_struct_type(theEnv, IInteger(bitSize), 0, // bit_alignment TempName(procDef->get_procedure_symbol()->get_name()), 0, // is_complete structTable) ; Iter<FileBlock*> fBlocks = theEnv->get_file_set_block()->get_file_block_iterator() ; assert(fBlocks.is_valid()) ; (fBlocks.current())->get_symbol_table()->append_symbol_table_object(moduleStruct) ; // This is commented out because it is in the file state block //procDef->get_symbol_table()->append_symbol_table_object(moduleStruct) ; QualifiedType* qualifiedModuleStruct = create_qualified_type(theEnv, moduleStruct, TempName(LString("qualifiedModuleStruct"))) ; procDef->get_symbol_table()->append_symbol_table_object(qualifiedModuleStruct) ; // Create an instance of this type and add it to the symbol table. ParameterSymbol* structInstance = create_parameter_symbol(theEnv, qualifiedModuleStruct, TempName(LString("structInstance"))) ; procDef->get_symbol_table()->append_symbol_table_object(structInstance) ; // Now, set up the procedure symbol to take the struct and return the // struct. assert(procDef != NULL) ; ProcedureSymbol* procSym = procDef->get_procedure_symbol() ; assert(procSym != NULL) ; ProcedureType* procType = procSym->get_type() ; assert(procType != NULL) ; CProcedureType* cProcType = dynamic_cast<CProcedureType*>(procType) ; assert(cProcType != NULL) ; // Instead of appending the struct argument, we need to replace all of the // arguments with the struct. while (cProcType->get_argument_count() > 0) { cProcType->remove_argument(0) ; } cProcType->set_result_type(moduleStruct) ; cProcType->append_argument(qualifiedModuleStruct) ; // Now go through all load variable expressions and replace them all with // field symbol values if appropriate list<LoadVariableExpression*>* allLoads = collect_objects<LoadVariableExpression>(procDef->get_body()) ; list<LoadVariableExpression*>::iterator loadIter = allLoads->begin() ; while (loadIter != allLoads->end()) { VariableSymbol* currentVariable = (*loadIter)->get_source() ; if (replacementFields.find(currentVariable) != replacementFields.end()) { (*loadIter)->set_source(replacementFields[currentVariable]) ; } ++loadIter ; } delete allLoads ; // Also replace all of the definitions with the field symbol list<StoreVariableStatement*>* allStoreVars = collect_objects<StoreVariableStatement>(procDef->get_body()) ; list<StoreVariableStatement*>::iterator storeVarIter = allStoreVars->begin(); while (storeVarIter != allStoreVars->end()) { VariableSymbol* currentDest = (*storeVarIter)->get_destination() ; if (replacementFields.find(currentDest) != replacementFields.end()) { (*storeVarIter)->set_destination(replacementFields[currentDest]) ; } ++storeVarIter ; } delete allStoreVars ; list<SymbolAddressExpression*>* allSymAddr = collect_objects<SymbolAddressExpression>(procDef->get_body()) ; list<SymbolAddressExpression*>::iterator symAddrIter = allSymAddr->begin() ; while (symAddrIter != allSymAddr->end()) { VariableSymbol* currentVar = dynamic_cast<VariableSymbol*>((*symAddrIter)->get_addressed_symbol()) ; if (currentVar != NULL && replacementFields.find(currentVar) != replacementFields.end()) { (*symAddrIter)->set_addressed_symbol(replacementFields[currentVar]) ; } ++symAddrIter ; } delete allSymAddr ; // One final for bool selects list<CallStatement*>* allCalls = collect_objects<CallStatement>(procDef->get_body()) ; list<CallStatement*>::iterator callIter = allCalls->begin() ; while(callIter != allCalls->end()) { VariableSymbol* currentVar = (*callIter)->get_destination() ; if (currentVar != NULL && replacementFields.find(currentVar) != replacementFields.end()) { (*callIter)->set_destination(replacementFields[currentVar]) ; } ++callIter ; } delete allCalls ; }
Walker::ApplyStatus fle_c_for_statement_walker::operator () (SuifObject *x) { SuifEnv *env = get_env(); CForStatement *c_for_stmt = to<CForStatement>(x); // if(!is_stmt_within_begin_end_hw_marks(c_for_stmt)) // return Walker::Continue; Statement *body = c_for_stmt->get_body(); Iter<CForStatement> iter = object_iterator<CForStatement>(body); if(iter.is_valid()) return Walker::Continue; BrickAnnote* c_for_info = to<BrickAnnote>(c_for_stmt->lookup_annote_by_name("c_for_info")); String c_for_loop_counter_name = (to<StringBrick>(c_for_info->get_brick(1)))->get_value(); int c_for_loop_step_size = (to<IntegerBrick>(c_for_info->get_brick(4)))->get_value().c_int(); if(body){ list<StoreStatement*>* stores_list = collect_objects<StoreStatement>(body); if(stores_list->size() <= 0){ delete stores_list; return Walker::Continue; } ProcedureDefinition* proc_def = get_procedure_definition(c_for_stmt); VariableSymbol *c_for_stmt_index_var = get_c_for_basic_induction_variable(c_for_stmt); Expression *c_for_stmt_lower_bound_expr = get_c_for_lower_bound_expr(c_for_stmt); BrickAnnote *ba = to<BrickAnnote>(c_for_stmt->lookup_annote_by_name("end_of_mem_reads")); SuifObjectBrick *sob = to<SuifObjectBrick>(ba->get_brick(0)); MarkStatement *end_of_mem_reads = to<MarkStatement>(sob->get_object()); ba = to<BrickAnnote>(c_for_stmt->lookup_annote_by_name("beg_of_mem_writes")); sob = to<SuifObjectBrick>(ba->get_brick(0)); MarkStatement *beg_of_mem_writes = to<MarkStatement>(sob->get_object()); list<VariableSymbol*>* array_names_in_load_exprs = collect_array_name_symbols_used_in_loads(body); suif_map<LoadExpression*, ArrayInfo*>* load_expr_array_info_map = new suif_map<LoadExpression*, ArrayInfo*>; list<LoadExpression*>* loads_list = collect_objects<LoadExpression>(body); for(list<LoadExpression*>::iterator iter2 = loads_list->begin(); iter2 != loads_list->end(); iter2++) { LoadExpression *load_expr = *iter2; StoreVariableStatement *load_parent = to<StoreVariableStatement>(get_expression_owner(load_expr)); if(!is_a<ArrayReferenceExpression>(load_expr->get_source_address())) continue; ArrayReferenceExpression *source_address_expr = to<ArrayReferenceExpression>(load_expr->get_source_address()); BrickAnnote *source_address_info_annote = to<BrickAnnote>(source_address_expr->lookup_annote_by_name("array_ref_info")); sob = to<SuifObjectBrick>(source_address_info_annote->get_brick(0)); ArrayInfo *source_address_info = (ArrayInfo*)(sob->get_object()); load_expr_array_info_map->enter_value(load_expr, source_address_info); } delete loads_list; StatementList* before_beg_of_mem_writes = create_statement_list(env); StatementList* after_end_of_mem_reads = create_statement_list(env); StatementList* load_inits = create_statement_list(env); list<Statement*>* to_be_removed = new list<Statement*>; for(list<StoreStatement*>::iterator iter = stores_list->begin(); iter != stores_list->end(); iter++) { StoreStatement *store_stmt = *iter; if(!is_a<ArrayReferenceExpression>(store_stmt->get_destination_address())) continue; ArrayReferenceExpression *destination_address_expr = to<ArrayReferenceExpression>(store_stmt->get_destination_address()); BrickAnnote *destination_address_info_annote = to<BrickAnnote>(destination_address_expr->lookup_annote_by_name("array_ref_info")); SuifObjectBrick *sob = to<SuifObjectBrick>(destination_address_info_annote->get_brick(0)); ArrayInfo *destination_address_info = (ArrayInfo*)(sob->get_object()); VariableSymbol *array_sym = get_array_name_symbol(destination_address_expr); Type *t = get_base_type(destination_address_expr->get_result_type()); VariableSymbol *feedback_var = NULL; for(suif_map<LoadExpression*, ArrayInfo*>::iterator iter2 = load_expr_array_info_map->begin(); iter2 != load_expr_array_info_map->end(); ) { ArrayInfo *source_address_info = (*iter2).second; if(destination_address_info->get_array_symbol_name() != source_address_info->get_array_symbol_name()){ iter2++; continue; } if(is_a_feedback_pair(destination_address_info, source_address_info, c_for_loop_counter_name, c_for_loop_step_size)){ if(!feedback_var){ feedback_var = new_anonymous_variable(env, find_scope(proc_def->get_body()), retrieve_qualified_type(to<DataType>(t))); name_variable(feedback_var); StoreVariableStatement *feedback_var_set = create_store_variable_statement(env, feedback_var, to<LoadVariableExpression>(deep_suif_clone(store_stmt->get_value()))); before_beg_of_mem_writes->append_statement(feedback_var_set); } LoadExpression *load_expr = (*iter2).first; StoreVariableStatement *load_parent = to<StoreVariableStatement>(get_expression_owner(load_expr)); StoreVariableStatement *feedback_var_get = create_store_variable_statement(env, load_parent->get_destination(), create_load_variable_expression(env, to<DataType>(t), feedback_var)); after_end_of_mem_reads->append_statement(feedback_var_get); suif_map<LoadExpression*, ArrayInfo*>::iterator iter_temp = iter2; iter2++; load_expr_array_info_map->erase(iter_temp); to_be_removed->push_back(load_parent); load_parent->set_parent(0); load_parent->set_destination(feedback_var); load_inits->append_statement(load_parent); }else iter2++; } } int i = 0; StatementList* the_list = to<StatementList>(body); while(i < the_list->get_statement_count()){ if(is_in_list(the_list->get_statement(i), to_be_removed)) the_list->remove_statement(i); else i++; } fle_load_variable_expression_walker walker(env, c_for_stmt_index_var, c_for_stmt_lower_bound_expr); load_inits->walk(walker); insert_statement_before(beg_of_mem_writes, before_beg_of_mem_writes); insert_statement_after(end_of_mem_reads, after_end_of_mem_reads); insert_statement_before(c_for_stmt, load_inits); delete stores_list; delete array_names_in_load_exprs; delete load_expr_array_info_map; delete to_be_removed; } return Walker::Continue; }
void CopyPropagationPass2::ProcessSpecialIfs() { list<IfStatement*>* allIfs = collect_objects<IfStatement>(procDef->get_body()) ; assert(allIfs != NULL) ; list<IfStatement*>::iterator ifIter = allIfs->begin() ; while (ifIter != allIfs->end()) { Statement* elsePart = (*ifIter)->get_else_part() ; assert(elsePart != NULL) ; StatementList* elseList = dynamic_cast<StatementList*>(elsePart) ; if (elseList == NULL) { ++ifIter ; continue ; } assert(elseList != NULL) ; if (elseList->get_statement_count() == 2) { // Process this if statement Statement* thenPart = (*ifIter)->get_then_part() ; assert(thenPart != NULL) ; /* StatementList* thenList = dynamic_cast<StatementList*>(thenPart) ; assert(thenList != NULL) ; assert(thenList->get_statement_count() == 1) ; Statement* thenStatement = thenList->get_statement(0) ; assert(thenStatement != NULL) ; */ StoreVariableStatement* thenStoreVar = dynamic_cast<StoreVariableStatement*>(thenPart) ; assert(thenStoreVar != NULL) ; Statement* firstElseStatement = elseList->get_statement(0) ; Statement* secondElseStatement = elseList->get_statement(1) ; assert(firstElseStatement != NULL && secondElseStatement != NULL) ; // We are definitely going to break the rules here // We know that the destination has to be replaced with // the source StoreVariableStatement* secondElseStore = dynamic_cast<StoreVariableStatement*>(secondElseStatement) ; assert(secondElseStore != NULL) ; Expression* source = secondElseStore->get_value() ; assert(source != NULL) ; LoadVariableExpression* sourceLoadExp = dynamic_cast<LoadVariableExpression*>(source) ; assert(sourceLoadExp != NULL) ; VariableSymbol* sourceVariable = sourceLoadExp->get_source() ; assert(sourceVariable != NULL) ; // First, find the use of the then portion and replace that use // with the source variable BrickAnnote* ba = to<BrickAnnote>(thenStoreVar->lookup_annote_by_name("reached_uses")) ; assert(ba != NULL) ; assert(ba->get_brick_count() == 1) ; Iter<SuifBrick*> tmpIter = ba->get_brick_iterator() ; SuifObjectBrick* sob = to<SuifObjectBrick>(tmpIter.current()) ; assert(sob != NULL) ; SuifObject* finalDest = sob->get_object() ; LoadVariableExpression* finalLoad = dynamic_cast<LoadVariableExpression*>(finalDest) ; assert(finalLoad != NULL) ; // Before we make the change, mark the variable we are replacing as // removed. finalLoad->get_source()->append_annote(create_brick_annote(theEnv, "RemovedVariable")) ; finalLoad->set_source(sourceVariable) ; // Now, change the then portion thenStoreVar->set_destination(sourceVariable) ; // Now, remove the second else statement elseList->remove_statement(1) ; // We should be done. } ++ifIter ; } delete allIfs ; }
void CopyPropagationPass2::ProcessPossibleCopy(StoreVariableStatement* c) { assert(c != NULL) ; // If this isn't a straight copy, just return LoadVariableExpression* replacement = dynamic_cast<LoadVariableExpression*>(c->get_value()) ; if (replacement == NULL) { return ; } // If the variables are different types, don't propagate this away // (it is a cast) DataType* destType = c->get_destination()->get_type()->get_base_type() ; DataType* sourceType = replacement->get_source()->get_type()->get_base_type(); if (!EquivalentTypes(destType, sourceType)) { return ; } // Find all the reached uses BrickAnnote* reachedUses = to<BrickAnnote>(c->lookup_annote_by_name("reached_uses")) ; assert(reachedUses != NULL) ; // Just in case we have no reached uses, we don't want to do // dead code elimination in this pass as well... bool removable = false ; Iter<SuifBrick*> useIter = reachedUses->get_brick_iterator() ; // First verify that we are the only definition for all of our uses. // If we aren't then we can't make the replacement while(useIter.is_valid()) { SuifObjectBrick* sob = to<SuifObjectBrick>(useIter.current()) ; assert (sob != NULL) ; LoadVariableExpression* nextLoad = dynamic_cast<LoadVariableExpression*>(sob->get_object()) ; assert(nextLoad != NULL) ; if (IsOnlyDefinition(c, nextLoad) == false) { return ; } useIter.next() ; } // We also need to make sure that for each reached use, the copy is // not redefined. We do this by checking to make sure all of the // definitions associated with it in the kill map are identical. // This is a little conservative, but will make sure that no incorrect // code is created. // Get the bit vector associated with all the reaching definitions // coming into this statement BrickAnnote* inStatements = dynamic_cast<BrickAnnote*>(c->lookup_annote_by_name("in_stmts")) ; assert(inStatements != NULL) ; SuifBrick* inBrick = inStatements->get_brick(0) ; assert(inBrick != NULL) ; SuifObjectBrick* inSOB = dynamic_cast<SuifObjectBrick*>(inBrick) ; assert(inSOB != NULL) ; SuifObject* inObj = inSOB->get_object() ; assert(inObj != NULL) ; BitVector2* inBits = dynamic_cast<BitVector2*>(inObj) ; assert(inBits != NULL) ; VariableSymbol* replacementVariable = replacement->get_source() ; assert(replacementVariable != NULL) ; list<std::pair<Statement*, int> >* definitions =killMap[replacementVariable]; assert(definitions != NULL) ; list<bool> activeDefinitions ; list<std::pair<Statement*, int> >::iterator defIter = definitions->begin() ; while (defIter != definitions->end()) { activeDefinitions.push_back(inBits->isMarked((*defIter).second)) ; ++defIter ; } useIter = reachedUses->get_brick_iterator() ; while (useIter.is_valid()) { SuifObjectBrick* sob = to<SuifObjectBrick>(useIter.current()) ; assert(sob != NULL) ; LoadVariableExpression* nextLoad = dynamic_cast<LoadVariableExpression*>(sob->get_object()) ; assert(nextLoad != NULL) ; SuifObject* loadParent = nextLoad->get_parent() ; while (dynamic_cast<Statement*>(loadParent) == NULL && loadParent != NULL) { loadParent = loadParent->get_parent() ; } assert(loadParent != NULL) ; Statement* parentStatement = dynamic_cast<Statement*>(loadParent) ; assert(parentStatement != NULL) ; BrickAnnote* parentInAnnote = dynamic_cast<BrickAnnote*> (parentStatement->lookup_annote_by_name("in_stmts")) ; assert(parentInAnnote != NULL) ; SuifBrick* parentInBrick = parentInAnnote->get_brick(0) ; assert(parentInBrick != NULL) ; SuifObjectBrick* parentInSOB = dynamic_cast<SuifObjectBrick*>(parentInBrick) ; assert(parentInSOB != NULL) ; SuifObject* parentInObj = parentInSOB->get_object() ; assert(parentInObj != NULL) ; BitVector2* parentInBits = dynamic_cast<BitVector2*>(parentInObj) ; assert(parentInBits != NULL) ; defIter = definitions->begin() ; list<bool>::iterator activeIter = activeDefinitions.begin() ; while (defIter != definitions->end()) { if ((*activeIter) != parentInBits->isMarked((*defIter).second)) { // They are different, so don't do the replacement. return ; } ++activeIter ; ++defIter ; } useIter.next() ; } // Now go through each reached use and replace it with the copy. // Each reached use should be a load variable expression. // We also have to deal with any feedback variables useIter = reachedUses->get_brick_iterator() ; while (useIter.is_valid()) { SuifObjectBrick* sob = to<SuifObjectBrick>(useIter.current()) ; assert(sob != NULL) ; LoadVariableExpression* nextLoad = dynamic_cast<LoadVariableExpression*>(sob->get_object()) ; assert(nextLoad != NULL) ; // Keep track of if we need to handle feedback variables HandleFeedbackVariables(nextLoad, replacement->get_source()) ; nextLoad->set_source(replacement->get_source()) ; removable = true ; useIter.next() ; } if (removable) { toBeRemoved.push_back(c) ; } }