// Then is a call statement, else is a store variable statement bool IfConversionPass2::ConvertCallStoreVarIf(IfStatement* toConvert) { Statement* thenPart = Denormalize(toConvert->get_then_part()) ; Statement* elsePart = Denormalize(toConvert->get_else_part()) ; CallStatement* thenCall = dynamic_cast<CallStatement*>(thenPart) ; StoreVariableStatement* elseStoreVar = dynamic_cast<StoreVariableStatement*>(elsePart) ; assert(thenCall != NULL) ; assert(elseStoreVar != NULL) ; CallStatement* boolSelectCall = CreateBoolCall(thenCall->get_destination()) ; // Append the arguments Expression* thenCallValue = thenCall->get_callee_address() ; thenCall->set_callee_address(NULL) ; CallExpression* thenCallExp = create_call_expression(theEnv, thenCall->get_destination()->get_type()->get_base_type(), thenCallValue) ; // Append all of the call arguments to the expression for (int i = 0 ; i < thenCall->get_argument_count() ; ++i) { Expression* nextArg = thenCall->get_argument(i) ; nextArg->set_parent(NULL) ; thenCallExp->append_argument(nextArg) ; } boolSelectCall->append_argument(thenCallExp) ; Expression* elseStoreVarValue = elseStoreVar->get_value() ; elseStoreVar->set_value(NULL) ; boolSelectCall->append_argument(elseStoreVarValue) ; Expression* condition = toConvert->get_condition() ; toConvert->set_condition(NULL) ; boolSelectCall->append_argument(condition) ; toConvert->get_parent()->replace(toConvert, boolSelectCall) ; return true ; }
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") ; }