bool IfConversionPass2::VerifyIf(IfStatement* toConvert) { Statement* thenPart = toConvert->get_then_part() ; Statement* elsePart = toConvert->get_else_part() ; if (thenPart == NULL || elsePart == NULL) { return false ; } StatementList* thenList = dynamic_cast<StatementList*>(thenPart) ; StatementList* elseList = dynamic_cast<StatementList*>(elsePart) ; if (thenList != NULL && thenList->get_statement_count() != 1) { return false ; } if (elseList != NULL && elseList->get_statement_count() != 1) { return false ; } thenPart = Denormalize(thenPart) ; elsePart = Denormalize(elsePart) ; return CorrectTypes(thenPart, elsePart) ; }
void TransformSystemsToModules::ReplaceUses(VariableSymbol* original, VariableSymbol* replacement) { assert(procDef != NULL) ; StatementList* bodyList = dynamic_cast<StatementList*>(procDef->get_body()) ; assert(bodyList != NULL) ; for (int i = 0 ; i < bodyList->get_statement_count() ; ++i) { list<LoadVariableExpression*>* allLoads = collect_objects<LoadVariableExpression>(bodyList->get_statement(i)) ; list<LoadVariableExpression*>::iterator loadIter = allLoads->begin() ; while (loadIter != allLoads->end()) { if ((*loadIter)->get_source() == original) { (*loadIter)->set_source(replacement) ; } ++loadIter ; } delete allLoads ; if (IsDefinition(bodyList->get_statement(i), original)) { // We no longer have to replace the value return ; } } }
void TransformSystemsToModules::ReplaceDefinition(VariableSymbol* original, VariableSymbol* replacement) { assert(procDef != NULL) ; std::cout << "Replacing a definition: " << original << " " << replacement << std::endl ; StatementList* bodyList = dynamic_cast<StatementList*>(procDef->get_body()) ; assert(bodyList != NULL) ; // From the back, find the last definition for (int i = bodyList->get_statement_count() - 1 ; i > 0 ; --i) { Statement* currentStatement = bodyList->get_statement(i) ; if (IsDefinition(currentStatement, original)) { // This is either going to be a store variable statement or // a symbol address expression (if the definition was in a call) list<StoreVariableStatement*>* allStores = collect_objects<StoreVariableStatement>(currentStatement) ; list<StoreVariableStatement*>::iterator storeIter = allStores->begin() ; while (storeIter != allStores->end()) { if ((*storeIter)->get_destination() == original) { (*storeIter)->set_destination(replacement) ; } ++storeIter ; } delete allStores ; list<SymbolAddressExpression*>* allSymAddr = collect_objects<SymbolAddressExpression>(currentStatement) ; list<SymbolAddressExpression*>::iterator symAddrIter = allSymAddr->begin(); while (symAddrIter != allSymAddr->end()) { if ((*symAddrIter)->get_addressed_symbol() == original) { (*symAddrIter)->set_addressed_symbol(replacement) ; } ++symAddrIter ; } delete allSymAddr ; return ; } } }
Statement* IfConversionPass2::Denormalize(Statement* x) { if (dynamic_cast<StatementList*>(x) != NULL) { StatementList* theList = dynamic_cast<StatementList*>(x) ; assert(theList->get_statement_count() == 1 && "Unsupported if detected!") ; return theList->get_statement(0) ; } else { return x ; } }
void RemoveUnsupportedStatements::do_procedure_definition(ProcedureDefinition* p) { procDef = p ; assert(procDef != NULL) ; OutputInformation("Remove Unsupported statements begins") ; CForStatement* innermost = InnermostLoop(procDef) ; if (innermost == NULL) { OutputInformation("Remove Unsupported statements ends") ; return ; } StatementList* parentList = dynamic_cast<StatementList*>(innermost->get_parent()) ; CForStatement* outerLoops = dynamic_cast<CForStatement*>(innermost->get_parent()) ; CForStatement* outermostLoop = innermost ; while (parentList == NULL && outerLoops != NULL) { parentList = dynamic_cast<StatementList*>(outerLoops->get_parent()) ; outermostLoop = outerLoops ; outerLoops = dynamic_cast<CForStatement*>(outerLoops->get_parent()) ; } assert(parentList != NULL) ; assert(outermostLoop != NULL) ; int position = DeterminePosition(parentList, outermostLoop) ; assert(position >= 0) ; for (int i = 0 ; i < position ; ++i) { StatementList* blankList = create_statement_list(theEnv) ; Statement* toReplace = parentList->get_statement(i) ; parentList->replace(toReplace, blankList) ; // Will this delete kill me? //delete toReplace ; } for (int i = position + 1 ; i < parentList->get_statement_count() ; ++i) { StatementList* blankList = create_statement_list(theEnv) ; Statement* toReplace = parentList->get_statement(i) ; parentList->replace(toReplace, blankList) ; // Will this delete kill me?... yep! or not... //delete toReplace ; } OutputInformation("Remove Unsupported statments ends") ; }
static void append_flattened(StatementList *slist,Statement *stat) { if (!stat) return; if (is_kind_of<StatementList>(stat)) { StatementList *sl = to<StatementList>(stat); int len = sl->get_statement_count(); for (int i = 0; i < len; i++) { Statement *s = sl->get_statement(i); s->set_parent(0); slist->append_statement(s); } } else { stat->set_parent(0); slist->append_statement(stat); } }
// Modified to handle cases where a variable is defined for the first time // in a call and used in a store variable. void SolveFeedbackVariablesPass3::DetermineNewFeedbacks() { assert(innermost != NULL) ; assert(procDef != NULL) ; assert(theEnv != NULL) ; StatementList* bodyList = dynamic_cast<StatementList*>(innermost->get_body()) ; assert(bodyList != NULL) ; std::map<VariableSymbol*, Statement*> lastDefinitions ; std::map<VariableSymbol*, int> lastLocations ; // Go backwards through the list and determine the last definition // for each variable. for (int i = bodyList->get_statement_count() - 1 ; i >= 0 ; --i) { list<VariableSymbol*> definedVariables = AllDefinedVariables(bodyList->get_statement(i)) ; list<VariableSymbol*>::iterator defIter = definedVariables.begin() ; int j = 0 ; while (defIter != definedVariables.end()) { if (lastDefinitions[(*defIter)] == NULL) { lastDefinitions[(*defIter)] = bodyList->get_statement(i) ; lastLocations[(*defIter)] = j ; } ++defIter ; ++j ; } } std::map<VariableSymbol*, int> killedVariables ; // Now go from the front and create actual feedbacks for each // live variable. for (int i = 0 ; i < bodyList->get_statement_count() ; ++i) { list<LoadVariableExpression*>* allLoads = collect_objects<LoadVariableExpression>(bodyList->get_statement(i)) ; list<LoadVariableExpression*>::iterator loadIter = allLoads->begin() ; while(loadIter != allLoads->end()) { if (killedVariables[(*loadIter)->get_source()] == 0 && lastDefinitions[(*loadIter)->get_source()] != NULL) { // Create a feedback here PossibleFeedbackPair toAdd ; toAdd.varSym = (*loadIter)->get_source() ; toAdd.use = (*loadIter) ; toAdd.definition = lastDefinitions[(*loadIter)->get_source()] ; toAdd.definitionLocation = lastLocations[(*loadIter)->get_source()] ; actualFeedbacks.push_back(toAdd) ; } ++loadIter ; } delete allLoads ; // Add all the definitions to the list of killed variables. list<VariableSymbol*> definedVariables = AllDefinedVariables(bodyList->get_statement(i)) ; list<VariableSymbol*>::iterator defIter = definedVariables.begin() ; while (defIter != definedVariables.end()) { killedVariables[(*defIter)] = 1 ; ++defIter ; } } }
void CombineSummationPass::do_procedure_definition(ProcedureDefinition* p) { procDef = p ; assert(procDef != NULL) ; OutputInformation("Combine summation pass begins") ; StatementList* innermost = InnermostList(procDef) ; assert(innermost != NULL) ; bool change = false ; do { // Find the first summation StoreVariableStatement* firstStatement = NULL ; StoreVariableStatement* secondStatement = NULL ; change = false ; int i ; int firstStatementPosition = -1 ; i = 0 ; while (i < innermost->get_statement_count()) { StoreVariableStatement* currentStoreVariable = dynamic_cast<StoreVariableStatement*>(innermost->get_statement(i)) ; if (currentStoreVariable != NULL && IsSummation(currentStoreVariable)) { firstStatement = currentStoreVariable ; firstStatementPosition = i ; break ; } ++i ; } if (firstStatement != NULL) { VariableSymbol* firstDest = firstStatement->get_destination() ; for (int j = i+1 ; j < innermost->get_statement_count() ; ++j) { StoreVariableStatement* nextStoreVar = dynamic_cast<StoreVariableStatement*>(innermost->get_statement(j)); if (nextStoreVar != NULL && IsSummation(nextStoreVar, firstDest)) { secondStatement = nextStoreVar ; break ; } if (IsDefinition(innermost->get_statement(j), firstDest) || HasUses(innermost->get_statement(j), firstDest)) { break ; } } } if (secondStatement != NULL) { // Go through each of the variables used in the first statement and // make sure there are no definitions to any of them. // I only have to worry about variables and not array accesses because // we don't allow them to read and write to array values. int originalPosition = DeterminePosition(innermost, firstStatement) ; assert(originalPosition >= 0) ; list<VariableSymbol*> usedVars = AllUsedVariablesBut(firstStatement, firstStatement->get_destination()); bool goodPath = true ; for (int j = originalPosition ; j < innermost->get_statement_count() && innermost->get_statement(j) != secondStatement ; ++j) { list<VariableSymbol*>::iterator usedIter = usedVars.begin() ; while (usedIter != usedVars.end()) { if (IsOutputVariable((*usedIter), innermost->get_statement(j))) { goodPath = false ; break ; } ++usedIter ; } if (!goodPath) { break ; } } if (!goodPath) { continue ; } // Actually do the combining here change = true ; Expression* remains = RemoveValue(firstStatement) ; Expression* secondRemains = RemoveValue(secondStatement) ; // Create two binary expressions BinaryExpression* remainsSum = create_binary_expression(theEnv, remains->get_result_type(), LString("add"), remains, secondRemains) ; LoadVariableExpression* loadDest = create_load_variable_expression(theEnv, secondStatement->get_destination()->get_type()->get_base_type(), secondStatement->get_destination()) ; BinaryExpression* finalSum = create_binary_expression(theEnv, remainsSum->get_result_type(), LString("add"), remainsSum, loadDest) ; secondStatement->set_value(finalSum) ; // Delete? innermost->remove_statement(firstStatementPosition) ; } } while (change == true) ; OutputInformation("Combine summation pass ends") ; }
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 ; }