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") ;
}
예제 #2
0
파일: cprint_style.cpp 프로젝트: jrk/suif2
static
String handle_static_symbol_address_expression(CPrintStyleModule *state,
					       const SuifObject *obj)
{
  SymbolAddressExpression *expr =
    to<SymbolAddressExpression>(obj);
  Symbol *sym = expr->get_addressed_symbol();
  return(String("&") + state->print_to_string(sym));
}
void ReferenceCleanupPass::CleanupCall(CallStatement* c)
{
  assert(procDef != NULL) ;
  assert(c != NULL) ;

  // We only need to clean up module calls.  If they are built in
  //  functions, like boolsel, we don't want to do this.
  if (IsBuiltIn(c))
  {
    return ;
  }
  
  // Go through the arguments and see if any of them are load variable
  //  expressions to a reference typed variable, and replace those with
  //  symbol address expressions
  for (unsigned int i = 0 ; i < c->get_argument_count() ; ++i)
  {
    Expression* currentArg = c->get_argument(i) ;
    LoadVariableExpression* currentLoadVar = 
      dynamic_cast<LoadVariableExpression*>(currentArg) ;
    if (currentLoadVar != NULL)
    {
      VariableSymbol* currentVar = currentLoadVar->get_source() ;
      DataType* varType = currentVar->get_type()->get_base_type() ;
      ReferenceType* refType = dynamic_cast<ReferenceType*>(varType) ;
      if (refType != NULL)
      {
	QualifiedType* internalType = 
	  dynamic_cast<QualifiedType*>(refType->get_reference_type()) ;
	assert(internalType != NULL) ;
	//	currentVar->set_type(internalType) ;
	SymbolAddressExpression* symAddrExp = 
	  create_symbol_address_expression(theEnv, 
					   internalType->get_base_type(),
					   currentVar) ;
	if (currentLoadVar->lookup_annote_by_name("UndefinedPath") != NULL)
	{
	  symAddrExp->append_annote(create_brick_annote(theEnv, "UndefinedPath")) ;
	}
	currentLoadVar->get_parent()->replace(currentLoadVar, symAddrExp) ;
      }
    }
  }
}
예제 #4
0
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 TransformUnrolledArraysPass::ReplaceSymbol(ArrayReferenceExpression* x,
						SymbolAddressExpression* addr)
{
  Expression* address = x->get_base_array_address() ;
  SymbolAddressExpression* symAddr =
    dynamic_cast<SymbolAddressExpression*>(address) ;
  ArrayReferenceExpression* anotherRef = 
    dynamic_cast<ArrayReferenceExpression*>(address) ;
  
  if (symAddr != NULL)
  {
    symAddr->set_parent(NULL) ;
    x->set_base_array_address(addr) ;
    delete symAddr ;    
    return ;
  }
  if (anotherRef != NULL)
  {
    ReplaceSymbol(anotherRef, addr) ;
    return ;
  }
  assert(0) ;
}
예제 #6
0
/* Another helper function for print_var_def().   This function
 * expects that it will need to add a return before printing
 * anything, and it expects that you will add a return after
 * it is done.
 * It returns the number of bits of initialization data that it
 * generates.
 */
int
PrinterX86::process_value_block(ValueBlock *vblk)
{
    int bits_filled = 0;

    if (is_a<ExpressionValueBlock>(vblk)) {
	// An ExpressionValueBlock either holds a constant value or a
	// simple expression representing either an address relative to
	// a symbol or a pointer generated by conversion from an integer
	// constant (presumably zero).

	ExpressionValueBlock *evb = (ExpressionValueBlock*)vblk;
	Expression *exp = evb->get_expression();

	if (is_a<IntConstant>(exp)) {
	    IntConstant *ic = (IntConstant*)exp;
	    bits_filled = print_size_directive(ic->get_result_type());
	    fprint(out, ic->get_value());
	    cur_opnd_cnt++;
	}
	else if (is_a<FloatConstant>(exp)) {
	    FloatConstant *fc = (FloatConstant*)exp;
	    bits_filled = print_size_directive(fc->get_result_type());
	    fputs(fc->get_value().c_str(), out);
	    cur_opnd_cnt++;
	}
	else {
	    // We use non-constant ExpressionValueBlocks to hold a symbolic
	    // address, optionally with an offset, or a pointer initializer
	    // consisting of a `convert' expression.
	    // A SymbolAddressExpression represents a plain symbolic
	    // address.
	    // An address obtained by conversion from another type is a
	    // unary expression with opcode "convert".
	    // A symbol+delta is represented by an add whose first operand
	    // is the load-address and whose second is an IntConstant
	    // expression.
	    // No other kind of "expression" is recognized.

	    if (is_a<UnaryExpression>(exp)) {
		UnaryExpression *ux = (UnaryExpression*)exp;
		claim(ux->get_opcode() == k_convert,
		      "unexpected unary expression in expression block");
		DataType *tt = ux->get_result_type();	// target type
		claim(is_kind_of<PointerType>(tt),
		      "unexpected target type when converting initializer");
		exp = ux->get_source();
		if (is_a<IntConstant>(exp)) {
		    IntConstant *ic = (IntConstant*)exp;
		    bits_filled = print_size_directive(tt);
		    fprint(out, ic->get_value());
		    cur_opnd_cnt++;
		    return bits_filled;
		}
		// Fall through to handle symbol-relative address, on the
		// assumption that the front end validated the conversion.
	    }
	    SymbolAddressExpression *sax;
	    long delta;
	    if (is_a<BinaryExpression>(exp)) {
		BinaryExpression *bx = (BinaryExpression*)exp;
		claim(bx->get_opcode() == k_add,
		      "unexpected binary expression in expression block");
		Expression *s1 = bx->get_source1();
		Expression *s2 = bx->get_source2();
		sax = to<SymbolAddressExpression>(s1);
		delta = to<IntConstant>(s2)->get_value().c_long();
	    } else if (is_a<SymbolAddressExpression>(exp)) {
		sax = (SymbolAddressExpression*)exp;
		delta = 0;
	    } else {
		claim(false, "unexpected kind of expression block");
	    }
	    Sym *sym = sax->get_addressed_symbol();

	    // symbol initialization
	    bits_filled = print_size_directive(type_ptr);
	    print_sym(sym);
	    if (delta != 0) {
		fprintf(out, "%+ld", delta);
	    }
	    // always force the start of a new data directive
	    cur_opcode = opcode_null;
	    cur_opnd_cnt = 0;
	}
    }

    else if (is_a<MultiValueBlock>(vblk)) {
	MultiValueBlock *mvb = (MultiValueBlock*)vblk;
	for (int i = 0; i < mvb->get_sub_block_count(); i++ ) {
	    int offset = mvb->get_sub_block(i).first.c_int();
	    claim(offset >= bits_filled);

	    if (bits_filled < offset)		// pad to offset
		bits_filled += print_bit_filler(offset - bits_filled);
	    bits_filled += process_value_block(mvb->get_sub_block(i).second);
	}
	int all_bits = get_bit_size(mvb->get_type());
	if (all_bits > bits_filled)
	    bits_filled += print_bit_filler(all_bits - bits_filled);

    } else if (is_a<RepeatValueBlock>(vblk)) {
	// Simplifying assumption: We now expect the front-end
	// to remove initialization code of large arrays of zeros.
	RepeatValueBlock *rvb = (RepeatValueBlock*)vblk;
	int repeat_cnt = rvb->get_num_repetitions();

	if (repeat_cnt > 1) {		// insert .repeat pseudo-op
	    fprintf(out, "\n\t%s\t%d", x86_opcode_names[REPEAT], repeat_cnt);
	    cur_opcode = opcode_null;	// force new data directive
	}
	// actual data directive
	bits_filled = repeat_cnt * process_value_block(rvb->get_sub_block());

	if (repeat_cnt > 1) {		// insert .endr pseudo-op
	    fprintf(out, "\n\t%s", x86_opcode_names[ENDR]);
	    cur_opcode = opcode_null;	// force new data directive
	}

    } else if (is_a<UndefinedValueBlock>(vblk)) {
	bits_filled += print_bit_filler(get_bit_size(vblk->get_type()));

    } else {
	claim(false, "unexpected kind of ValueBlock");
    }
    return bits_filled;
}