void ConstantArrayPropagationPass::CollectInitializations() { if (!initializations.empty()) { initializations.clear() ; } DefinitionBlock* procDefBlock = procDef->get_definition_block() ; assert(procDefBlock != NULL) ; Iter<VariableDefinition*> varDefIter = procDefBlock->get_variable_definition_iterator() ; while (varDefIter.is_valid()) { VariableDefinition* varDef = varDefIter.current() ; assert(varDef != NULL) ; VariableSymbol* varSym = varDef->get_variable_symbol() ; ValueBlock* valBlock = varDef->get_initialization() ; assert(varSym != NULL) ; assert(valBlock != NULL) ; if (ValidSymbol(varSym)) { initializations[varSym] = valBlock ; varSym->append_annote(create_brick_annote(theEnv, "ConstPropArray")) ; } varDefIter.next() ; } }
// This is a vastly simpler way to setup annotations that doesn't worry // or assume that all feedbacks come from a single store variable statement void SolveFeedbackVariablesPass3::SetupAnnotations() { assert(theEnv != NULL) ; // Go through the list of all feedback instances we have discovered. list<PossibleFeedbackPair>::iterator feedbackIter = actualFeedbacks.begin(); while (feedbackIter != actualFeedbacks.end()) { // For every feedback, we need to create a two variables // The first one is a replacement for the original use. // The second one is the variable used for feedback. LString replacementName = (*feedbackIter).varSym->get_name() ; replacementName = replacementName + "_replacementTmp" ; VariableSymbol* replacementVariable = create_variable_symbol(theEnv, (*feedbackIter).varSym->get_type(), TempName(replacementName)) ; procDef->get_symbol_table()->append_symbol_table_object(replacementVariable); VariableSymbol* feedbackVariable = create_variable_symbol(theEnv, (*feedbackIter).varSym->get_type(), TempName(LString("feedbackTmp"))) ; procDef->get_symbol_table()->append_symbol_table_object(feedbackVariable) ; // Replace the use with this new feedback variable (*feedbackIter).use->set_source(replacementVariable) ; // I am looking for the variable that originally defined me and // the variable that will replace me. Statement* definition = (*feedbackIter).definition ; VariableSymbol* definitionVariable = GetDefinedVariable(definition, (*feedbackIter).definitionLocation) ; assert(definitionVariable != NULL) ; // Finally, annotate the feedback variable SetupAnnotations(feedbackVariable, definitionVariable, replacementVariable) ; replacementVariable->append_annote(create_brick_annote(theEnv, "NonInputScalar")); ++feedbackIter ; } }
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::CollectArrayReferences() { assert(procDef != NULL) ; list<ArrayReferenceExpression*>* allRefs = collect_objects<ArrayReferenceExpression>(procDef->get_body()) ; list<ArrayReferenceExpression*>::iterator refIter = allRefs->begin() ; while (refIter != allRefs->end()) { // If this is not the topmost array reference, skip it. if (dynamic_cast<ArrayReferenceExpression*>((*refIter)->get_parent()) != NULL) { ++refIter ; continue ; } // Also, skip lookup tables if (IsLookupTable(GetArrayVariable(*refIter))) { ++refIter ; continue ; } bool found = false ; std::pair<Expression*, VariableSymbol*> toAdd ; list<std::pair<Expression*, VariableSymbol*> >::iterator identIter = Identified.begin() ; while (identIter != Identified.end()) { if (EquivalentExpressions((*identIter).first, *refIter)) { found = true ; toAdd = (*identIter) ; break ; } ++identIter ; } if (!found) { VariableSymbol* replacement = create_variable_symbol(theEnv, GetQualifiedTypeOfElement(*refIter), TempName(LString("suifTmp"))) ; replacement->append_annote(create_brick_annote(theEnv, "ScalarReplacedVariable")) ; procDef->get_symbol_table()->append_symbol_table_object(replacement) ; toAdd.first = (*refIter) ; toAdd.second = replacement ; Identified.push_back(toAdd) ; } if (dynamic_cast<LoadExpression*>((*refIter)->get_parent()) != NULL) { found = false ; identIter = IdentifiedLoads.begin() ; while (identIter != IdentifiedLoads.end()) { if (EquivalentExpressions((*identIter).first, *refIter)) { found = true ; break ; } ++identIter ; } if (!found) { IdentifiedLoads.push_back(toAdd) ; } } else if (dynamic_cast<StoreStatement*>((*refIter)->get_parent()) != NULL) { found = false ; identIter = IdentifiedStores.begin() ; while (identIter != IdentifiedStores.end()) { if (EquivalentExpressions((*identIter).first, *refIter)) { found = true ; break ; } ++identIter ; } if (!found) { IdentifiedStores.push_back(toAdd) ; } } else { assert(0 && "Improperly formatted array reference!") ; } ++refIter ; } delete allRefs ; }
void TransformSystemsToModules::HandleFeedback() { assert(procDef != NULL) ; list<VariableSymbol*> toReplace ; // This function needs to find all variables that are both input and // output scalars (they used to be feedbacks, but now there is no loop) SymbolTable* procSymTab = procDef->get_symbol_table() ; 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 && nextObject->lookup_annote_by_name("OutputVariable") != NULL) { VariableSymbol* var = dynamic_cast<VariableSymbol*>(nextObject) ; assert(var != NULL) ; toReplace.push_back(var) ; } } // Now, go through all of the different values that need to be replaced and // find all of the uses and definitions and replace them... list<VariableSymbol*>::iterator replaceIter = toReplace.begin() ; while (replaceIter != toReplace.end()) { LString inputName = (*replaceIter)->get_name() ; inputName = inputName + LString("_in") ; LString outputName = (*replaceIter)->get_name() ; outputName = outputName + LString("_out") ; // Create two variables, one for input and one for output VariableSymbol* inputReplacement = create_variable_symbol(theEnv, (*replaceIter)->get_type(), inputName) ; VariableSymbol* outputReplacement = create_variable_symbol(theEnv, (*replaceIter)->get_type(), outputName) ; procDef->get_symbol_table()->append_symbol_table_object(inputReplacement) ; procDef->get_symbol_table()->append_symbol_table_object(outputReplacement); inputReplacement->append_annote(create_brick_annote(theEnv, "InputScalar")) ; outputReplacement->append_annote(create_brick_annote(theEnv, "OutputVariable")) ; // Find all uses before the first definition and replace them with the // input variable. ReplaceUses((*replaceIter), inputReplacement) ; // Find the last definition and replace it with the output variable. ReplaceDefinition((*replaceIter), outputReplacement) ; // Remove the annotes that started the whole thing delete (*replaceIter)->remove_annote_by_name("InputScalar") ; delete (*replaceIter)->remove_annote_by_name("OutputVariable") ; ++replaceIter ; } }