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") ; }
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) ; } } } }
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) ; }
/* 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; }