Ejemplo n.º 1
0
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") ;
}
Ejemplo n.º 2
0
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::do_procedure_definition(ProcedureDefinition* proc_def)
{
  procDef = proc_def ;
  assert(procDef != NULL) ;

  OutputInformation("Solve feedback variables 2.0 pass begins") ;

  // Feedback variables should only exist in loops, and I am currently
  //  assuming one loop nest.  I need to find the innermost for loop
  //  and base all of my 

  innermost = InnermostLoop(procDef) ;

  if (innermost == NULL)
  {
    OutputInformation("Solve feedback variables 2.0 pass ends") ;
    return ;
  }

  DetermineNewFeedbacks() ;

  SetupAnnotations() ;

  OutputInformation("Solve feedback variables 2.0 pass ends") ;
}
void AvailableCodeEliminationPass::do_procedure_definition(ProcedureDefinition* p)
{
  procDef = p ;
  assert(procDef != NULL) ;

  OutputInformation("Available Code Elimination 2.0 Pass Begins") ;

  StatementList* innermost = NULL ;
  CForStatement* innermostFor = InnermostLoop(procDef) ;
  if (innermostFor != NULL)
  {
    innermost = dynamic_cast<StatementList*>(innermostFor->get_body()) ;
  }
  else
  {
    innermost = dynamic_cast<StatementList*>(procDef->get_body()) ;
  }
  assert(innermost != NULL) ;

  bool change ;
  do
  {
    change = false ;
    change |= ProcessStatementList(innermost) ;

  } while (change == true) ;  

  OutputInformation("Available Code Elimination 2.0 Pass Ends") ;
}
Ejemplo n.º 5
0
void IfConversionPass2::do_procedure_definition(ProcedureDefinition* proc_def)
{
  procDef = proc_def ;
  assert(procDef != NULL) ;

  OutputInformation("If conversion pass 2.0 begins") ;

  bool changed ;

  do
  {
    changed = false ;
    list<IfStatement*>* allIfs =
      collect_objects<IfStatement>(procDef->get_body()) ;
    list<IfStatement*>::iterator ifIter = allIfs->begin() ;
    while (ifIter != allIfs->end())
    {
      changed |= ConvertIf(*ifIter) ;
      ++ifIter ;
    }
    delete allIfs ;

  } while (changed == true) ;

  OutputInformation("If conversion pass 2.0 ends") ;
}
void CleanupStoreStatementsPass::do_procedure_definition(ProcedureDefinition* 
							 proc_def)
{
  procDef = proc_def ;
  assert(procDef != NULL) ;

  OutputInformation("Cleanup store statements pass begins") ;

  list<StoreStatement*>* allStores = 
    collect_objects<StoreStatement>(procDef->get_body()) ;

  list<StoreStatement*>::iterator storeIter = allStores->begin() ;
  while (storeIter != allStores->end())
  {
    Expression* destAddress = (*storeIter)->get_destination_address() ;
    
    LoadVariableExpression* convertExp = 
      dynamic_cast<LoadVariableExpression*>(destAddress) ;
    if (convertExp != NULL)
    {
      // This store statement must be replaced with a store variable statement
      
      VariableSymbol* sym = convertExp->get_source() ;
      convertExp->set_source(NULL) ;

      Expression* value = (*storeIter)->get_value() ;
      (*storeIter)->set_value(NULL) ;
      StoreVariableStatement* replacement = 
	create_store_variable_statement(theEnv,
					sym,
					value) ;
      (*storeIter)->get_parent()->replace((*storeIter), replacement) ;
    }
    else if (dynamic_cast<SymbolAddressExpression*>(destAddress) != NULL)
    {
      SymbolAddressExpression* symAddr = 
	dynamic_cast<SymbolAddressExpression*>(destAddress) ;
      VariableSymbol* sym = 
	dynamic_cast<VariableSymbol*>(symAddr->get_addressed_symbol()) ;
      assert(sym != NULL) ;

      Expression* value = (*storeIter)->get_value() ;
      (*storeIter)->set_value(NULL) ;
      StoreVariableStatement* replacement = 
	create_store_variable_statement(theEnv,
					sym,
					value) ;
      (*storeIter)->get_parent()->replace((*storeIter), replacement) ;
    }

    ++storeIter ;
  }
  
  delete allStores ;

  OutputInformation("Cleanup store statements pass ends") ;
}
void DoWhileToWhileTransformPass::do_procedure_definition(ProcedureDefinition* proc_def)
{
  OutputInformation("Do...while to while loop transformation begins") ;
  if (proc_def)
  {
    dw2wtp_do_while_statement_walker walker(get_suif_env());
    proc_def->walk(walker);
  }
  OutputInformation("Do...while to while loop transformation ends") ;
}
Ejemplo n.º 8
0
void CodeHoistingPass::do_procedure_definition(ProcedureDefinition* proc_def)
{
  OutputInformation("Code hoisting pass begins") ;
  if (proc_def)
  {
    worklist = new list<IfStatement*>;
    form_worklist(to<Statement>(proc_def->get_body()));
    process_worklist();
  }
  OutputInformation("Code hoisting pass ends") ;
}
void ReferenceCleanupPass::do_procedure_definition(ProcedureDefinition* p)
{
  procDef = p ;
  assert(procDef != NULL) ;
  
  OutputInformation("Reference Cleanup pass begins") ;

  CleanupCalls() ;
  //  CleanupArrayStores() ;
  
  OutputInformation("Reference Cleanup pass ends") ;
}
Ejemplo n.º 10
0
void RemoveModulePass::execute()
{
    OutputInformation("Remove module pass begins") ;

    InitializeRepository() ;

    RemoveProcedure(FindProcedure(moduleName)) ;

    DumpRepository() ;

    OutputInformation("Remove module pass ends") ;
}
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") ;
}
Ejemplo n.º 12
0
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") ;
}
void TransformSystemsToModules::do_procedure_definition(ProcedureDefinition* proc_def)
{
  procDef = proc_def ;
  assert(procDef != NULL) ;
  OutputInformation("Transform Systems To Modules Pass Begins") ;

  if (!HasLoop() && !PassedStruct() && !ComposedSystem())
  {
    HandleFeedback() ;
    Transform() ;
    procDef->append_annote(create_brick_annote(theEnv, "TransformedModule")) ;
  }

  OutputInformation("Transform Systems To Modules Pass Ends") ;  
}
void ConstantArrayPropagationPass::do_procedure_definition(ProcedureDefinition* proc_def)
{
  procDef = proc_def ;
  assert(procDef != NULL) ;

  OutputInformation("Constant Array Propagation Pass begins") ;

  // Step one: Find all of definition blocks for constant arrays
  CollectInitializations() ;
  
  // Step two: Go through load expressions and replace them with 
  //  any appropriate initialization.
  ReplaceLoads() ;

  OutputInformation("Constant Array Propagation Pass ends") ;
}
Ejemplo n.º 15
0
bool TestEvolution(void)
{
	// Test the temp fitness against the current fitness. If it is greater or equal, replace 
	// all pixels in Best with pixels from Evolve and update the current fitness.
	Attempts++;
	TempFitness = CalculateFitness();
	if (TempFitness > Fitness)
	{
		Mutations++;
		if (TempFitness != Fitness) GoodMutations++;

		// Copy over all pixels to the Best surface and write in the new fitness
		memcpy((void*)((Uint32*)Best->pixels), (void*)((Uint32*)Evolve->pixels), Evolve->pitch * Evolve->h);
		Fitness = TempFitness;

		// Output information to console
		OutputInformation(Fitness, GoodMutations, Mutations, Attempts, (SDL_GetTicks() - OpeningTick) / 1000.0);

		// Return an indication that the triangle list mutation was successful
		return true;
	}
	else PolygonList[ListIterator] = TempPolygon;
	
	// Return an indication that the triangle list mutation was not successful
	return false;
}
Ejemplo n.º 16
0
void ImportBinary(void)
{
	// Import the Polygon list from a binary file
	std::fstream Input("SaveFile.tie", std::ios_base::binary | std::ios_base::in);
	if (Input.bad())		return;
	if (!Input.good())		return;
	for (unsigned int i = 0; i < POLYGON_COUNT; i++) Input.read((char*)&PolygonList[i], sizeof(Poly));
	Input.close();

	// Clear the Evolve surface and allow a new fitness to be calculated
	ClearSurface(Evolve);
	Fitness = 0.0;
	
	printf("\n\n\nTriangle List Imported!");

	// Normally after this occurs, a single mutation would be set and the resulting fitness would be higher than
	// what is was before importing. To prevent this, calculate the fitness before returning to the loop
	
	// Draw the Evolve Image
	ClearSurface(Evolve);
	for (unsigned int i = 0; i < POLYGON_COUNT; i++)
		if (PolygonList[i].BitFlag & DEFINED_BIT)
			filledPolygonRGBA(Evolve, PolygonList[i].X, PolygonList[i].Y, VERTEX_COUNT, PolygonList[i].Color[0], PolygonList[i].Color[1], PolygonList[i].Color[2], PolygonList[i].Color[3]);

	Fitness = CalculateFitness();
	memcpy((void*)((Uint32*)Best->pixels), (void*)((Uint32*)Evolve->pixels), Evolve->pitch * Evolve->h);

	GoodMutations = 0;
	Mutations = 0;
	Attempts = 0;
	OpeningTick = SDL_GetTicks();
	OutputInformation(Fitness, GoodMutations, Mutations, Attempts, 0.0);
}
void ScalarReplacementPass2::do_procedure_definition(ProcedureDefinition* p)
{
  procDef = p ;
  assert(procDef != NULL) ;

  OutputInformation("Scalar replacement pass 2.0 begins") ;

  VerifyArrayReferences() ;
  CollectArrayReferences() ;

  ProcessLoads() ;
  ProcessStores() ;

  PrependLoads() ;
  AppendStores() ;

  OutputInformation("Scalar replacement pass 2.0 ends") ;
}
Ejemplo n.º 18
0
void CleanupRedundantVotes::do_procedure_definition(ProcedureDefinition* proc_def)
{
  procDef = proc_def ;
  assert(procDef != NULL) ;
  OutputInformation("Cleanup Redundant Votes Begins") ;
  
  list<CallStatement*>* allCalls = 
    collect_objects<CallStatement>(procDef->get_body()) ;
  list<CallStatement*>::iterator callIter = allCalls->begin() ;
  while (callIter != allCalls->end())
  {
    ProcessCall(*callIter) ;
    ++callIter ;
  }
  delete allCalls ;

  OutputInformation("Cleanup Redundant Votes Ends") ;
}
void TransformUnrolledArraysPass::do_procedure_definition(ProcedureDefinition* proc_def)
{
  procDef = proc_def ;
  assert(procDef != NULL) ;
  
  OutputInformation("Transforming Unrolled Arrays Pass Begins") ;

  innermost = InnermostList(procDef) ;
  assert(innermost != NULL) ;

  int maxD = MaxDimension() ;
  for (int i = maxD ; i > 0 ; --i)
  {    
    TransformNDIntoNMinusOneD(i) ;
  }

  OutputInformation("Transforming Unrolled Arrays Pass Ends") ;
}
Ejemplo n.º 20
0
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 ConstQualedVarPropagationPass::do_procedure_definition(ProcedureDefinition* proc_def)
{
  OutputInformation("Constant qualified variable propagation pass begins");

  suif_map<VariableSymbol*, ValueBlock*> temp_const_defs;
    if (proc_def){
        DefinitionBlock *proc_def_block = proc_def->get_definition_block();
        for(Iter<VariableDefinition*> iter = proc_def_block->get_variable_definition_iterator();
            iter.is_valid(); iter.next()){
            VariableDefinition *var_def = iter.current();
            VariableSymbol *var_sym = var_def->get_variable_symbol();
            QualifiedType *qualed_var_type = var_sym->get_type();
            if(is_a<IntegerType>(qualed_var_type->get_base_type())){
               bool found = 0;
               for(Iter<LString> iter2 = qualed_var_type->get_qualification_iterator();
                   iter2.is_valid(); iter2.next())
                   if(iter2.current() == LString("const"))
                      found = 1;
               if(found){
                  temp_const_defs.enter_value(var_sym, var_def->get_initialization());
               }
            }
        }
        for(Iter<StoreVariableStatement> iter = object_iterator<StoreVariableStatement>(proc_def->get_body());
            iter.is_valid(); iter.next()){
            StoreVariableStatement *store_var_stmt = &iter.current();
            Expression *store_var_value = store_var_stmt->get_value();
            if(!is_a<IntConstant>(store_var_value))
               continue;
            VariableSymbol *store_var_destination = store_var_stmt->get_destination();
            if(!is_a<IntegerType>(store_var_destination->get_type()->get_base_type()))  
               continue;
            suif_map<VariableSymbol*,ValueBlock*>::iterator iter2 =
                        temp_const_defs.find(to<LoadVariableExpression>(store_var_value)->get_source());
            if(iter2 != temp_const_defs.end())
               const_qualified_scalars.enter_value(store_var_destination, (*iter2).second);
        }
        cqvp_load_variable_expression_walker walker(get_suif_env());
        proc_def->walk(walker);
    }
  OutputInformation("Constant qualified variable propagation pass ends");
}
void HW_SW_BoundaryMarkPass::do_procedure_definition(ProcedureDefinition* proc_def)
{
  OutputInformation("Determination of Hardware/Software boundary pass begins");
    if (proc_def){
	SuifEnv *env = get_suif_env();

        if(proc_def->lookup_annote_by_name("begin_hw"))
           delete (to<BrickAnnote>(proc_def->remove_annote_by_name("begin_hw")));
        if(proc_def->lookup_annote_by_name("end_hw"))
           delete (to<BrickAnnote>(proc_def->remove_annote_by_name("end_hw")));

        BrickAnnote *ba = create_brick_annote(env, "begin_hw");
        proc_def->append_annote(ba);
        ba = create_brick_annote(env, "end_hw");
        proc_def->append_annote(ba);

	hsbm_call_statement_walker walker(get_suif_env());
	proc_def->walk(walker);
    }
  OutputInformation("Determination of Hardware/Software boundary pass ends");
}
Ejemplo n.º 23
0
void CleanupLoadPass::do_procedure_definition(ProcedureDefinition* p)
{
  procDef = p ;
  assert(procDef != NULL) ;
  OutputInformation("Cleanup load pass begins") ;
  list<LoadExpression*>* allLoads = 
    collect_objects<LoadExpression>(procDef->get_body()) ;
  list<LoadExpression*>::iterator loadIter = allLoads->begin() ;
  while (loadIter != allLoads->end())
  {
    Expression* internal = (*loadIter)->get_source_address() ;
    if (dynamic_cast<LoadVariableExpression*>(internal) != NULL)
    {
      (*loadIter)->set_source_address(NULL) ;
      (*loadIter)->get_parent()->replace((*loadIter), internal) ;
      delete (*loadIter) ;
    }
    ++loadIter ;
  }
  delete allLoads ;
  OutputInformation("Cleanup load pass ends") ;
}
void CopyPropagationPass2::do_procedure_definition(ProcedureDefinition* proc_def)
{
  procDef = proc_def ;
  assert(procDef != NULL) ;

  OutputInformation("Copy propagation pass 2.0 begins") ;
  totalDefinitions = 0 ;

  Initialize() ;

  if (Special())
  {
    ProcessSpecialIfs() ;
  }
  else
  { 
    // First, find all the possible copy instructions.  These
    //  can only be store variable statements

    list<StoreVariableStatement*>* allStoreVars =
      collect_objects<StoreVariableStatement>(procDef->get_body()) ;
    assert(allStoreVars != NULL) ;

    list<StoreVariableStatement*>::iterator storeVarIter = 
      allStoreVars->begin();
    while(storeVarIter != allStoreVars->end())
    {
      ProcessPossibleCopy(*storeVarIter) ;
      ++storeVarIter ;
    }
  
    delete allStoreVars ;
  }
  
  CleanUp() ;

  OutputInformation("Copy propagation pass 2.0 ends") ;
}
void MiniConstantPropagationPass::do_procedure_definition(ProcedureDefinition* p)
{
    procDef = p ;
    assert(procDef != NULL) ;
    OutputInformation("Mini Constant Propagation Pass begins") ;

    StatementList* innermostList = InnermostList(procDef) ;
    assert(innermostList != NULL) ;

    list<StatementList*>* allStatementLists =
        collect_objects<StatementList>(innermostList) ;

    list<StatementList*>::iterator listIter = allStatementLists->begin() ;
    while (listIter != allStatementLists->end())
    {
        ProcessList(*listIter) ;
        ++listIter ;
    }

    delete allStatementLists ;

    OutputInformation("Mini Constant Propagation Pass ends") ;
}
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") ;
}