//	If bound_below (bound_above) is not indeterminate it is a value which the condition value
//	is known top be greater than (less than or equal)
void MultiWayGroupList::generate_code(StatementList *x) {

    // start by trying to merge blocks

    bool closed = false;
    while (!closed) {
	closed = true;
	size_t i = 0;
	while (i + 1 < _list.length()) {
	    MultiWayGroup *low = _list[i];
	    MultiWayGroup *high = _list[i + 1];
	    double density = (double)(low->get_label_count() + high->get_label_count())
			/(high->get_high_bound() - low->get_low_bound() + 1).c_double();
            if (density >= required_density) {
	 	low->merge(*high);
		delete high->get_statement();
		delete high;
		_list.erase(i + 1);
		closed = false;
		i++; // skip over element we just removed
		}
	    i ++;
	    }
	}
    generate_code_subgroup(x,IInteger(),IInteger(),0,_list.length() - 1);
    }
CForStatement* make_strip(SuifEnv *env, VariableSymbol* loop_counter, int upper_bound, int step_size, Statement* body) {

    TypeBuilder *type_builder = get_type_builder(env);

    Statement *before_stmt = create_store_variable_statement(env, loop_counter, create_int_constant(env, IInteger(0)));
    Expression *test_expr = create_binary_expression(env, type_builder->get_boolean_type(), "is_less_than", create_var_use(loop_counter),
                            create_int_constant(env, IInteger(upper_bound)));
    Expression *step_expr = create_binary_expression(env, loop_counter->get_type()->get_base_type(), "add",
                            create_var_use(loop_counter), create_int_constant(env, IInteger(step_size)));
    Statement *step_stmt = create_store_variable_statement(env, loop_counter, step_expr);

    return create_c_for_statement(env, before_stmt, test_expr, step_stmt, body);
}
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") ;
}
Exemple #4
0
void SingleInheritanceVtbls::
attach_vtbl_slot_number_annotes( SingleInheritanceClassType* ctype ) {
  vtbl_t* vtbl = build_vtbls( ctype );
  unsigned vtbl_size = vtbl->size();
    
  for ( unsigned i = 0 ; i < vtbl_size ; i++ ) {
    InstanceMethodSymbol* msym = (*vtbl)[i];
    ::attach_vtbl_slot_number_annote( _env, msym, IInteger(i) );
  }
}
DataType* ExportPass::CloneDataType(DataType* t)
{
  assert(t != NULL) ;
  PointerType* pointerClone = dynamic_cast<PointerType*>(t) ;
  ReferenceType* referenceClone = dynamic_cast<ReferenceType*>(t) ;
  ArrayType* arrayClone = dynamic_cast<ArrayType*>(t) ;
  if (pointerClone != NULL)
  {
    QualifiedType* refType = 
      dynamic_cast<QualifiedType*>(pointerClone->get_reference_type()) ;
    assert(refType != NULL) ;
    DataType* cloneType = CloneDataType(refType->get_base_type()) ;
    assert(cloneType != NULL) ;

    return create_pointer_type(theEnv, 
			       IInteger(32),
			       0,
			       create_qualified_type(theEnv, cloneType)) ;
  }
  if (referenceClone != NULL)
  {
    QualifiedType* refType = 
      dynamic_cast<QualifiedType*>(referenceClone->get_reference_type()) ;
    assert(refType != NULL) ;
    DataType* clonedType = CloneDataType(refType->get_base_type()) ;
    
    return create_reference_type(theEnv,
				 IInteger(32),
				 0,
				 create_qualified_type(theEnv, clonedType)) ;
  }
  if (arrayClone != NULL)
  {
    QualifiedType* elementType = arrayClone->get_element_type() ;
    DataType* internalType = CloneDataType(elementType->get_base_type()) ;
    QualifiedType* finalQual = create_qualified_type(theEnv, internalType) ;
    return create_pointer_type(theEnv,
			       IInteger(32),
			       0, 
			       finalQual) ;    
  }
  return dynamic_cast<DataType*>(t->deep_clone()) ;
}
MultiValueBlock* NodeBuilder::new_cstr_value_block(String s)
{
  ArrayType* type =
    _type_builder->get_array_type(get_qualified_type(get_char_type()),
				  IInteger(0),
				  IInteger(s.length()+1));
  MultiValueBlock* mb = create_multi_value_block(_suif_env, type);
  IInteger charlen = get_char_type()->get_bit_size();
  IInteger offset(0);
  for (int i =0; i<s.length(); i++) {
    mb->add_sub_block(offset,
		      create_expression_value_block(_suif_env,
						    char_const(s[i])));
    offset += charlen;
  }
  mb->add_sub_block(offset,
		    create_expression_value_block(_suif_env,
						  char_const('\0')));
  return mb;
}
static Expression *build_empty_expression(DataType *t) {
  SuifEnv *s = t->get_suif_env();

  suif_assert_message(!is_kind_of<GroupType>(t),
		      ("build_empty_expression:: can not handle GroupType"));
  if (is_kind_of<VoidType>(t))
    return(NULL);

  if (is_kind_of<IntegerType>(t)) {
    IntConstant *c = create_int_constant(s, t, IInteger(0));
    return c;
  }
  // This works for Int, Float, Enum, pointers
  TypeBuilder *tb = get_type_builder(s);
  
  IntegerType *it = tb->get_integer_type();
  IntConstant *c = create_int_constant(s, it, IInteger(0));
  Expression *cvt = create_unary_expression(s, t,  k_convert, c);
  return(cvt);
}
/** Create an expression for byte offset of a group field.
  *
  */
Expression* NodeBuilder::get_field_offset_exp(FieldSymbol* fsym)
{
  Expression *boffset = fsym->get_bit_offset();
  if (!is_kind_of<IntConstant>(boffset)) {
    trash(fsym);
    SUIF_THROW(SuifException(String("Field offset not in IntConstant ") +
			     to_id_string(fsym)));
  }
  IInteger v = to<IntConstant>(boffset)->get_value();
  return int_const(v.div(IInteger(BITSPERBYTE)));
}
Exemple #9
0
IntConstant* build_vtbl_slot_count_int_constant( SuifEnv* env,
						 ClassType* owning_class )
{
  TypeBuilder* tb = get_type_builder( env );

  IntConstant* icnst =
    ::create_int_constant( env,
			   tb->get_integer_type( true ), // result_type
			   IInteger() // value: inserted later
			   );
  attach_vtbl_slot_count_annote( env, icnst, owning_class );
  return icnst;
}
Exemple #10
0
IntConstant* build_vtbl_slot_int_constant( SuifEnv* env,
					   InstanceMethodSymbol* msym )
{
  TypeBuilder* tb = get_type_builder( env );

  IntConstant* icnst =
    ::create_int_constant( env,
			   tb->get_integer_type( true ), // result_type
			   IInteger() // value: inserted later
			   );
  attach_vtbl_slot_annote( env, icnst, msym );
  return icnst;
}
Exemple #11
0
/*
 * The default type of a vtbl slot is void* [ <vtbl-size> ].
 */
DataType*
SingleInheritanceVtbls::get_vtbl_type( SingleInheritanceClassType* ctype,
				       IInteger vtbl_size )
{
  DataType* slot_type = vtbl_slot_type( ctype );
  QualifiedType* q_slot_type = _tb->get_qualified_type( slot_type );

  ArrayType* vtbl_type =
    _tb->get_array_type( q_slot_type,
			 IInteger(0),
			 (vtbl_size - 1) );
  return vtbl_type;
}
Exemple #12
0
void ExportPass::ConstructModuleSymbols()
{
  CProcedureType* originalType = dynamic_cast<CProcedureType*>(originalProcedure->get_procedure_symbol()->get_type()) ;
  assert(originalType != NULL) ;

  // The original type takes and returns a struct.  We need to change this
  //  to a list of arguments.

  VoidType* newReturnType = create_void_type(theEnv, IInteger(0), 0) ;
  constructedType = create_c_procedure_type(theEnv,
					    newReturnType,
					    false, // has varargs
					    true, // arguments_known
					    0, // bit alignment
					    LString("ConstructedType")) ;

  StructType* returnType = 
    dynamic_cast<StructType*>(originalType->get_result_type()) ;
  assert(returnType != NULL) ;

  SymbolTable* structSymTab = returnType->get_group_symbol_table() ;
  assert(structSymTab != NULL) ;

  for (int i = 0 ; i < structSymTab->get_symbol_table_object_count() ; ++i)
  {
    VariableSymbol* nextVariable = 
      dynamic_cast<VariableSymbol*>(structSymTab->get_symbol_table_object(i));
    if (nextVariable != NULL)
    {
      // Check to see if this is an output or not
      QualifiedType* cloneType ;
      DataType* cloneBase = 
	dynamic_cast<DataType*>(nextVariable->get_type()->get_base_type()->deep_clone()) ;
      assert(cloneBase != NULL) ;
      cloneType = create_qualified_type(theEnv, cloneBase) ;
 
      if (nextVariable->lookup_annote_by_name("Output") != NULL)
      {
	cloneType->append_annote(create_brick_annote(theEnv, "Output")) ;
	// Why doesn't this stick around?
      }
      constructedType->append_argument(cloneType) ;
    }
  }

  constructedSymbol = create_procedure_symbol(theEnv,
					      constructedType,
					      originalProcedure->get_procedure_symbol()->get_name()) ;
  constructedSymbol->set_definition(NULL) ;

}
void solve_li_c_for_stmt(Statement *s){
	SuifEnv *env = s->get_suif_env();
	CForStatement *c_for_stmt = to<CForStatement>(s);

	BrickAnnote *nest_level = to<BrickAnnote>(s->lookup_annote_by_name("c_for_info"));
	if(nest_level->get_brick_count() == 0){
   	   nest_level->insert_brick(0, create_integer_brick(env, IInteger(++loop_level)));
	   BrickAnnote *loop_label = to<BrickAnnote>(s->lookup_annote_by_name("c_for_label"));
	   if(loop_label->get_brick_count() == 0){
	      loop_label->insert_brick(0, create_string_brick(env, String(loop_level)));
  	   }  
	}

	Statement *body = c_for_stmt->get_body();  
	solve_li_statement(body);	

	--loop_level;
}
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") ;
}
Exemple #15
0
/*
 * Constructs the actual vtbl.
 * A vtbl is implemented as an array of pointers that point to
 * the addresses of the dispatched methods.
 * A method address is kept in a ExpressionValueBlock.
 *
 * The VariableDefinition that holds the array is returned. It
 * must be 
 * - inserted into a DefinitionBlock
 * - attached to a VariableSymbol.
 */
VariableDefinition*
SingleInheritanceVtbls::get_vtbl( SingleInheritanceClassType* ctype ) {
  vtbl_t* vtbl = build_vtbls( ctype );
  unsigned vtbl_size = vtbl->size();

//  DataType* slot_type = vtbl_slot_type( ctype );
//  QualifiedType* q_slot_type = _tb->get_qualified_type( slot_type );

  DataType* vtbl_type = get_vtbl_type( ctype, vtbl_size );

  //    _tb->get_array_type( q_slot_type,
  //			 IInteger(0),
  //			 IInteger(vtbl_size - 1) );
			 
  MultiValueBlock* mvb = ::create_multi_value_block( _env, vtbl_type );
    
  for ( unsigned i = 0 ; i < vtbl_size ; i++ ) {
    InstanceMethodSymbol* msym = (*vtbl)[i];

    ::attach_vtbl_slot_number_annote( _env, msym, IInteger(i) );
    
    ProcedureType* mtype = msym->get_type();
    PointerType* ptr_to_mtype = get_pointer_type( _env, mtype );

    SymbolAddressExpression* sa_expr =
      ::create_symbol_address_expression( _env, ptr_to_mtype, msym );
    msym->set_is_address_taken( true );

    ExpressionValueBlock* evb =
      ::create_expression_value_block( _env, sa_expr );

    append_to_multi_value_block( mvb, evb );
  }

  return ::create_variable_definition( _env,
				       NULL, // variable_symbol
				       0, // @@@ bit_alignment
				       mvb,
				       true // is_static
				       );
}
Constant* MiniConstantPropagationPass::Merge(Constant* x, Constant* y,
        LString opcode)
{
    assert(theEnv != NULL) ;

    if (x == NULL || y == NULL)
    {
        return NULL ;
    }

    IntConstant* xInt = dynamic_cast<IntConstant*>(x) ;
    IntConstant* yInt = dynamic_cast<IntConstant*>(y) ;
    FloatConstant* xFloat = dynamic_cast<FloatConstant*>(x) ;
    FloatConstant* yFloat = dynamic_cast<FloatConstant*>(y) ;

    // This mini propagation only cares for addition and subtraction.  Other
    //  propagations will be handled in a later pass.

    if (opcode == LString("add"))
    {
        if (xInt != NULL && yInt != NULL)
        {
            int mergedValue = xInt->get_value().c_int() + yInt->get_value().c_int() ;
            return create_int_constant(theEnv, xInt->get_result_type(),
                                       IInteger(mergedValue)) ;
        }
        if (xFloat != NULL && yFloat != NULL)
        {
            float mergedValue = StringToFloat(xFloat->get_value()) +
                                StringToFloat(yFloat->get_value()) ;
            return create_float_constant(theEnv, xFloat->get_result_type(),
                                         FloatToString(mergedValue)) ;
        }
        if (xInt != NULL && yFloat != NULL)
        {
            float mergedValue = xInt->get_value().c_int() +
                                StringToFloat(yFloat->get_value()) ;
            return create_float_constant(theEnv, yFloat->get_result_type(),
                                         FloatToString(mergedValue)) ;
        }
        if (xFloat != NULL && yInt != NULL)
        {
            float mergedValue = StringToFloat(xFloat->get_value()) +
                                yInt->get_value().c_int() ;
            return create_float_constant(theEnv, xFloat->get_result_type(),
                                         FloatToString(mergedValue)) ;
        }
    }

    if (opcode == LString("subtract"))
    {
        if (xInt != NULL && yInt != NULL)
        {
            int mergedValue = xInt->get_value().c_int() - yInt->get_value().c_int() ;
            return create_int_constant(theEnv, xInt->get_result_type(),
                                       IInteger(mergedValue)) ;
        }
        if (xFloat != NULL && yFloat != NULL)
        {
            float mergedValue = StringToFloat(xFloat->get_value()) -
                                StringToFloat(yFloat->get_value()) ;
            return create_float_constant(theEnv, xFloat->get_result_type(),
                                         FloatToString(mergedValue)) ;
        }
        if (xInt != NULL && yFloat != NULL)
        {
            float mergedValue = xInt->get_value().c_int() -
                                StringToFloat(yFloat->get_value()) ;
            return create_float_constant(theEnv, yFloat->get_result_type(),
                                         FloatToString(mergedValue)) ;
        }
        if (xFloat != NULL && yInt != NULL)
        {
            float mergedValue = StringToFloat(xFloat->get_value()) -
                                yInt->get_value().c_int() ;
            return create_float_constant(theEnv, xFloat->get_result_type(),
                                         FloatToString(mergedValue)) ;
        }
    }

    return NULL ;

}
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 ;
}
IntConstant* NodeBuilder::bool_const(bool v)
{
  return int_const(IInteger(v ? 1 : 0));
}
IntConstant* NodeBuilder::int_const(int i)
{
  return int_const(IInteger(i));
}