Statement* multi_way_branch_statement_walker::dismantle_multi_way_branch_statement(MultiWayBranchStatement *the_case){ StatementList *replacement = create_statement_list(the_case->get_suif_env()); Expression *operand = the_case->get_decision_operand (); remove_suif_object(operand); DataType *type = operand->get_result_type(); CodeLabelSymbol *default_lab = the_case->get_default_target(); the_case->set_default_target(0); Iter<MultiWayBranchStatement::case_pair > iter = the_case->get_case_iterator(); while (iter.is_valid()) { MultiWayBranchStatement::case_pair pair = iter.current(); IInteger value = pair.first; CodeLabelSymbol *lab = pair.second; IntConstant *exp = create_int_constant(the_case->get_suif_env(),type, value); // Expression *exp = create_load_constant_expression(get_env(),type,iconst); TypeBuilder *type_builder = (TypeBuilder *) the_case->get_suif_env()->get_object_factory(TypeBuilder::get_class_name()); Expression *compare = create_binary_expression(the_case->get_suif_env(),type_builder->get_boolean_type(), k_is_equal_to, deep_suif_clone(operand), exp); replacement->append_statement(create_branch_statement(the_case->get_suif_env(),compare,lab)); iter.next(); } delete operand; replacement->append_statement(create_jump_statement(the_case->get_suif_env(),default_lab)); the_case->get_parent()->replace(the_case,replacement); return replacement; }
Statement *while_statement_walker::dismantle_while_statement(WhileStatement *the_while){ Statement *result = 0; Expression *condition = the_while->get_condition(); // we are going to reuse the condition so we must remove it // from the if statement first to avoid ownership conflicts // the_while->set_condition(SourceOp()); // remove_source_op(condition); remove_suif_object(condition); Statement *body = the_while->get_body(); CodeLabelSymbol *break_label = the_while->get_break_label(); CodeLabelSymbol *continue_label = the_while->get_continue_label(); // likewise of these parts - remove from if. the_while->set_body(0); the_while->set_break_label(0); the_while->set_continue_label(0); if (body != 0) { StatementList *replacement = create_statement_list(body->get_suif_env()); result = replacement; suif_assert(continue_label != 0); UnaryExpression* negated_condition = create_unary_expression(body->get_suif_env(), condition->get_result_type(), k_logical_not, condition ); replacement-> append_statement(create_label_location_statement(body->get_suif_env(), continue_label)); replacement-> append_statement(create_branch_statement(body->get_suif_env(), negated_condition, break_label)); replacement->append_statement(body); suif_assert(break_label != 0); replacement->append_statement(create_jump_statement(body->get_suif_env(),continue_label)); replacement-> append_statement(create_label_location_statement(body->get_suif_env(), break_label)); } the_while->get_parent()->replace(the_while,result); return result; }
Walker::ApplyStatus multi_way_branch_statement_compactor::operator () (SuifObject *x) { MultiWayBranchStatement *the_case = to<MultiWayBranchStatement>(x); // is the table already compact? if (is_compact(the_case)) return Walker::Continue; SymbolTable *scope = find_scope(x); if (!scope) return Walker::Continue; CodeLabelSymbol *default_lab = the_case->get_default_target(); // very special case - the case list is empty, so just jump to the default label if (the_case->get_case_count() == 0) { Statement *replacement = create_jump_statement(get_env(),default_lab); the_case->get_parent()->replace(the_case,replacement); set_address(replacement); return Walker::Replaced; } StatementList *replacement = create_statement_list(get_env()); Expression *operand = the_case->get_decision_operand (); remove_suif_object(operand); DataType *type = operand->get_result_type(); VariableSymbol *decision = create_variable_symbol(get_env(),get_type_builder(get_env())->get_qualified_type(type)); scope->add_symbol(decision); replacement->append_statement(create_store_variable_statement(get_env(),decision,operand)); the_case->set_default_target(0); MultiWayGroupList jump_list(get_env(),default_lab,decision);; Iter<MultiWayBranchStatement::case_pair > iter = the_case->get_case_iterator(); while (iter.is_valid()) { MultiWayBranchStatement::case_pair pair = iter.current(); jump_list.add_element(pair.first,pair.second); iter.next(); } // we have built the new structure, now need to generate code for it jump_list.generate_code(replacement); the_case->get_parent()->replace(the_case,replacement); set_address(replacement); return Walker::Replaced; }
Walker::ApplyStatus dw2wtp_do_while_statement_walker::operator () (SuifObject *x) { SuifEnv *env = get_env(); DoWhileStatement *do_while_stmt = to<DoWhileStatement>(x); Expression *do_while_condition = do_while_stmt->get_condition(); do_while_stmt->set_condition(0); Statement *do_while_body = do_while_stmt->get_body(); do_while_stmt->set_body(0); IfStatement *first_iteration = create_if_statement(env, to<Expression>(deep_suif_clone(do_while_condition)), to<Statement>(deep_suif_clone(do_while_body))); WhileStatement *remaining_iterations = create_while_statement(env, do_while_condition, do_while_body); StatementList *replacement = create_statement_list(env); replacement->append_statement(first_iteration); replacement->append_statement(remaining_iterations); do_while_stmt->get_parent()->replace(do_while_stmt, replacement); set_address(replacement); return Walker::Replaced; }
Statement* c_for_statement_walker::dismantle_c_for_statement(CForStatement *the_for){ StatementList *replacement = create_statement_list(the_for->get_suif_env()); StatementList *body = create_statement_list(the_for->get_suif_env()); Statement* original_body = the_for->get_body(); the_for->set_body(0); body->append_statement(original_body); the_for->set_body(body); Statement* pre_pad = the_for->get_pre_pad(); CodeLabelSymbol* break_lab = the_for->get_break_label(); CodeLabelSymbol* continue_lab = the_for->get_continue_label(); Statement* before = the_for->get_before(); Expression* test = the_for->get_test(); Statement* step = the_for->get_step();; if(before)remove_suif_object(before); if(test)remove_suif_object(test); if(step)remove_suif_object(step); if(body)remove_suif_object(body); if(pre_pad)remove_suif_object(pre_pad); the_for->set_break_label(0); the_for->set_continue_label(0); // I am guessing what pre-pad and post-pad do if (before) replacement->append_statement(before); // and loop if not out of range replacement->append_statement( create_label_location_statement(the_for->get_suif_env(), continue_lab)); if(test) { SuifEnv *env = the_for->get_suif_env(); DataType *bool_type = get_type_builder(env)->get_boolean_type(); test = create_unary_expression(env,bool_type,k_logical_not,test); replacement->append_statement(create_branch_statement(env,test,break_lab)); } if(pre_pad){ replacement->append_statement(pre_pad); } append_flattened(replacement,body); append_flattened(replacement,step); replacement->append_statement(create_jump_statement(body->get_suif_env(),continue_lab)); replacement->append_statement( create_label_location_statement(body->get_suif_env(), break_lab)); // end of loop the_for->get_parent()->replace(the_for, replacement); return replacement; }
void ScalarReplacementPass2::AppendStores() { assert(procDef != NULL) ; StatementList* innermost = InnermostList(procDef) ; assert(innermost != NULL) ; list<std::pair<Expression*, VariableSymbol*> >::iterator storeIter = IdentifiedStores.begin() ; while (storeIter != IdentifiedStores.end()) { (*storeIter).first->set_parent(NULL) ; LoadVariableExpression* loadTmp = create_load_variable_expression(theEnv, (*storeIter).second->get_type()->get_base_type(), (*storeIter).second) ; StoreStatement* postStore = create_store_statement(theEnv, loadTmp, (*storeIter).first) ; innermost->append_statement(postStore) ; ++storeIter ; } }
Walker::ApplyStatus dste_call_statement_walker2::operator () (SuifObject *x) { SuifEnv *env = get_env(); CallStatement *call_stmt = to<CallStatement>(x); SymbolAddressExpression *callee_address = to<SymbolAddressExpression>(call_stmt->get_callee_address()); ProcedureSymbol *proc_symbol = to<ProcedureSymbol>(callee_address->get_addressed_symbol()); String called_proc_name = proc_symbol->get_name(); if(called_proc_name == String("ROCCC_lookup_in_state_table")){ Expression *argument_expr = call_stmt->get_argument(0); if(is_a<UnaryExpression>(argument_expr)) argument_expr = (to<UnaryExpression>(argument_expr))->get_source(); int st_id = (to<IntConstant>(argument_expr))->get_value().c_int(); suif_map<int, ST*>::iterator iter = state_table_defs->find(st_id); if(iter == state_table_defs->end()) return Walker::Continue; ST* state_table_def = (*iter).second; int pattern_length = state_table_def->get_length(); int state_count = state_table_def->get_state_count(); int alphabet_count = state_table_def->get_alphabet_count(); int start_state = state_table_def->get_start_state(); int error_state = state_table_def->get_error_state(); int final_state = state_table_def->get_final_state(); VariableSymbol *char_set_array_sym = state_table_def->get_char_set_sym(); DataType *stream_data_type = get_array_element_type(char_set_array_sym); QualifiedType *qualed_stream_data_type = retrieve_qualified_type(stream_data_type); VariableSymbol *state_table_sym = state_table_def->get_state_table_sym(); DataType *dfa_state_data_type = get_array_element_type(state_table_sym); QualifiedType *qualed_dfa_state_type = retrieve_qualified_type(dfa_state_data_type); StatementList *replacement = create_statement_list(env); argument_expr = call_stmt->get_argument(1); argument_expr->set_parent(0); if(is_a<UnaryExpression>(argument_expr)) argument_expr = (to<UnaryExpression>(argument_expr))->get_source(); VariableSymbol* input_char_sym = new_anonymous_variable(env, proc_def_body, qualed_stream_data_type); name_variable(input_char_sym, "ic"); StoreVariableStatement *store_var_stmt = create_store_variable_statement(env, input_char_sym, argument_expr); replacement->append_statement(store_var_stmt); TypeBuilder *tb = get_type_builder(env); SymbolTable *external_symbol_table = get_external_symbol_table(get_procedure_definition(call_stmt)); list<QualifiedType*> cam_proc_argument_types; for(int j = 0; j < alphabet_count+1; j++) cam_proc_argument_types.push_back(qualed_stream_data_type); DataType *cam_return_type; int cam_return_bit_size = get_unsigned_bit_size(alphabet_count); cam_return_type = tb->get_integer_type(cam_return_bit_size, cam_return_bit_size, 0); cam_return_type->set_name(String("ROCCC_int") + String(cam_return_bit_size)); CProcedureType *cam_proc_type = tb->get_c_procedure_type(cam_return_type, cam_proc_argument_types); ProcedureSymbol *cam_proc_sym = create_procedure_symbol(env, cam_proc_type, String("ROCCC_cam") + String(alphabet_count)); external_symbol_table->add_symbol(cam_proc_sym); VariableSymbol* alphabet_index_sym = new_anonymous_variable(env, proc_def_body, retrieve_qualified_type(cam_return_type)); name_variable(alphabet_index_sym, "ais"); SymbolAddressExpression *cam_proc_sym_expr = create_symbol_address_expression(env, tb->get_pointer_type(cam_proc_type), cam_proc_sym); CallStatement *cam_macro_stmt = create_call_statement(env, alphabet_index_sym, cam_proc_sym_expr); for(int j = 0; j < alphabet_count; j++){ Expression *cam_argument_expr = create_symbol_address_expression(env, char_set_array_sym->get_type()->get_base_type(), char_set_array_sym); cam_argument_expr = create_array_reference_expression(env, stream_data_type, cam_argument_expr, create_int_constant(env, tb->get_integer_type(), IInteger(j))); cam_argument_expr = create_load_expression(env, stream_data_type, cam_argument_expr); cam_macro_stmt->append_argument(cam_argument_expr); } cam_macro_stmt->append_argument(create_load_variable_expression(env, stream_data_type, input_char_sym)); replacement->append_statement(cam_macro_stmt); suif_vector<VariableSymbol*>* state_column_vars = new suif_vector<VariableSymbol*>; for(int i = 0; i < state_count; i++){ VariableSymbol* state_column_sym = new_anonymous_variable(env, proc_def_body, qualed_dfa_state_type); name_variable(state_column_sym, "st"); state_column_vars->push_back(state_column_sym); } list<QualifiedType*> mux_proc_argument_types; for(int j = 0; j < alphabet_count; j++) mux_proc_argument_types.push_back(qualed_dfa_state_type); mux_proc_argument_types.push_back(retrieve_qualified_type(cam_return_type)); CProcedureType *mux_proc_type = tb->get_c_procedure_type(dfa_state_data_type, mux_proc_argument_types); ProcedureSymbol *mux_proc_sym = create_procedure_symbol(env, mux_proc_type, String("ROCCC_mux") + String(alphabet_count)); external_symbol_table->add_symbol(mux_proc_sym); ArrayType *state_table_array_type = to<ArrayType>(state_table_sym->get_type()->get_base_type()); for(int i = 0; i < state_count; i++){ if(i == error_state){ StoreVariableStatement *state_column_var_init_stmt = create_store_variable_statement(env, state_column_vars->at(i), create_int_constant(env, tb->get_integer_type(), IInteger(i))); replacement->append_statement(state_column_var_init_stmt); continue; } SymbolAddressExpression *mux_proc_sym_expr = create_symbol_address_expression(env, tb->get_pointer_type(mux_proc_type), mux_proc_sym); CallStatement *mux_macro_stmt = create_call_statement(env, state_column_vars->at(i), mux_proc_sym_expr); for(int j = 0; j < alphabet_count; j++){ Expression *mux_argument_expr = create_symbol_address_expression(env, state_table_array_type, state_table_sym); mux_argument_expr = create_array_reference_expression(env, state_table_array_type->get_element_type()->get_base_type(), mux_argument_expr, create_int_constant(env, tb->get_integer_type(), IInteger(i))); mux_argument_expr = create_array_reference_expression(env, dfa_state_data_type, mux_argument_expr, create_int_constant(env, tb->get_integer_type(), IInteger(j))); mux_argument_expr = create_load_expression(env, dfa_state_data_type, mux_argument_expr); mux_macro_stmt->append_argument(mux_argument_expr); } mux_macro_stmt->append_argument(create_load_variable_expression(env, cam_return_type, alphabet_index_sym)); replacement->append_statement(mux_macro_stmt); } suif_vector<VariableSymbol*>* current_state_vars = new suif_vector<VariableSymbol*>; suif_vector<VariableSymbol*>* next_state_vars = new suif_vector<VariableSymbol*>; StatementList *var_init_stmt_list = create_statement_list(env); for(int i = 0; i < pattern_length; i++){ VariableSymbol* current_state_sym = new_anonymous_variable(env, proc_def_body, qualed_dfa_state_type); name_variable(current_state_sym, "cs"); BrickAnnote *feedback_level_annote = create_brick_annote(env, "feedback_level"); current_state_sym->append_annote(feedback_level_annote); feedback_level_annote->insert_brick(0, create_integer_brick(env, IInteger(0))); current_state_vars->push_back(current_state_sym); StoreVariableStatement *init_var_stmt = create_store_variable_statement(env, current_state_sym, create_int_constant(env, dfa_state_data_type, IInteger(start_state))); var_init_stmt_list->append_statement(init_var_stmt); VariableSymbol* next_state_sym = new_anonymous_variable(env, proc_def_body, qualed_dfa_state_type); name_variable(next_state_sym, "ns"); next_state_vars->push_back(next_state_sym); } insert_statement_before(get_enclosing_c_for_stmt(call_stmt), var_init_stmt_list); mux_proc_argument_types.empty(); for(int j = 0; j < state_count+1; j++) mux_proc_argument_types.push_back(qualed_dfa_state_type); mux_proc_type = tb->get_c_procedure_type(dfa_state_data_type, mux_proc_argument_types); mux_proc_sym = create_procedure_symbol(env, mux_proc_type, String("ROCCC_mux") + String(state_count)); external_symbol_table->add_symbol(mux_proc_sym); for(int i = 0; i < pattern_length; i++){ SymbolAddressExpression *mux_proc_sym_expr = create_symbol_address_expression(env, tb->get_pointer_type(mux_proc_type), mux_proc_sym); CallStatement *mux_macro_stmt = create_call_statement(env, next_state_vars->at(i), mux_proc_sym_expr); for(int k = 0; k < state_count; k++) mux_macro_stmt->append_argument(create_load_variable_expression(env, dfa_state_data_type, state_column_vars->at(k))); mux_macro_stmt->append_argument(create_load_variable_expression(env, dfa_state_data_type, current_state_vars->at(i))); replacement->append_statement(mux_macro_stmt); } Expression *equality_check_expr = create_binary_expression(env, tb->get_boolean_type(), String("is_equal_to"), create_load_variable_expression(env, dfa_state_data_type, next_state_vars->at(0)), create_int_constant(env, dfa_state_data_type, IInteger(final_state))); VariableSymbol *destination_sym = call_stmt->get_destination(); StoreVariableStatement *result_stmt = create_store_variable_statement(env, destination_sym, equality_check_expr); replacement->append_statement(result_stmt); for(int i = 1; i < pattern_length; i++){ equality_check_expr = create_binary_expression(env, tb->get_boolean_type(), String("is_equal_to"), create_load_variable_expression(env, dfa_state_data_type, next_state_vars->at(i)), create_int_constant(env, dfa_state_data_type, IInteger(final_state))); Expression *result_expr = create_binary_expression(env, tb->get_boolean_type(), String("logical_or"), create_load_variable_expression(env, tb->get_boolean_type(), destination_sym), equality_check_expr); result_stmt = create_store_variable_statement(env, destination_sym, result_expr); replacement->append_statement(result_stmt); } for(int i = 0; i < pattern_length-1; i++){ StoreVariableStatement *store_var_stmt = create_store_variable_statement(env, current_state_vars->at(i+1), create_load_variable_expression(env, dfa_state_data_type, next_state_vars->at(i))); replacement->append_statement(store_var_stmt); } call_stmt->get_parent()->replace(call_stmt, replacement); return Walker::Truncate; } return Walker::Continue; }
Statement* if_statement_walker::dismantle_if_statement(IfStatement* the_if){ Statement *result = 0; ProcedureDefinition* proc_def = get_procedure_definition(the_if); Expression *condition = the_if->get_condition(); // we are going to reuse the condition so we must remove it // from the if statement first to avoid ownership conflicts remove_suif_object(condition); // the_if->set_condition(SourceOp()); // remove_source_op(condition); Statement *then_part = the_if->get_then_part(); Statement *else_part = the_if->get_else_part(); // likewise of these parts - remove from if. the_if->set_then_part(0); the_if->set_else_part(0); remove_suif_object(then_part); remove_suif_object(else_part); if (then_part != 0) { StatementList *replacement = create_statement_list( the_if->get_suif_env() ); result = replacement; UnaryExpression* negated_condition = create_unary_expression( the_if->get_suif_env(), condition->get_result_type(), k_logical_not, condition ); if (else_part != 0) { CodeLabelSymbol *else_label = new_anonymous_label(proc_def->get_symbol_table()); CodeLabelSymbol *done_label = new_anonymous_label(proc_def->get_symbol_table()); replacement->append_statement(create_branch_statement(the_if->get_suif_env(), negated_condition, else_label)); replacement->append_statement(then_part); replacement->append_statement(create_jump_statement(the_if->get_suif_env(),done_label)); replacement->append_statement(create_label_location_statement(the_if->get_suif_env(), else_label)); replacement->append_statement(else_part); replacement->append_statement(create_label_location_statement(the_if->get_suif_env(), done_label)); } else { CodeLabelSymbol *done_label = create_new_label(get_procedure_definition(the_if)); replacement-> append_statement(create_branch_statement(the_if->get_suif_env(), negated_condition, done_label)); replacement->append_statement(then_part); replacement-> append_statement(create_label_location_statement(the_if->get_suif_env(), done_label)); } } else { if (else_part != 0) { StatementList *replacement = create_statement_list(the_if->get_suif_env()); result = replacement; CodeLabelSymbol *done_label = create_new_label(proc_def); replacement->append_statement(create_branch_statement(the_if->get_suif_env(), condition, done_label)); replacement->append_statement(else_part); replacement-> append_statement(create_label_location_statement(the_if->get_suif_env(), done_label)); } else { EvalStatement *replacement = create_eval_statement(the_if->get_suif_env()); result = replacement; replacement->append_expression(condition); } } the_if->get_parent()->replace(the_if, result); return result; }
Statement *for_statement_walker::dismantle_for_statement(ForStatement *the_for){ StatementList *replacement = create_statement_list(the_for->get_suif_env()); VariableSymbol* index = the_for->get_index(); DataType *type = unqualify_data_type(index->get_type()); Expression *lower = the_for->get_lower_bound(); Expression *upper = the_for->get_upper_bound(); Expression *step = the_for->get_step(); LString compare_op = the_for->get_comparison_opcode(); Statement* body = the_for->get_body(); Statement* pre_pad = the_for->get_pre_pad(); // Statement* post_pad = the_for->get_post_pad(); CodeLabelSymbol* break_lab = the_for->get_break_label(); CodeLabelSymbol* continue_lab = the_for->get_continue_label(); the_for->set_index(0); remove_suif_object(lower); remove_suif_object(upper); remove_suif_object(step); remove_suif_object(body); remove_suif_object(pre_pad); // the_for->set_post_pad(0); // remove_suif_object(post_pad); the_for->set_break_label(0); the_for->set_continue_label(0); // I am guessing what pre-pad and post-pad do if(pre_pad != 0)replacement->append_statement(pre_pad); // initialize the index. Is this right? should we ever initialize to upper, for -ve steps? // Is index guaranteed not to be changed? Should we be creating a temporary? replacement->append_statement(create_store_variable_statement(body->get_suif_env(),index,lower)); replacement->append_statement(create_label_location_statement(body->get_suif_env(), continue_lab)); if (body != 0) replacement->append_statement(body); // increment the counter Expression *index_expr = create_load_variable_expression(body->get_suif_env(), unqualify_data_type(index->get_type()), index); Expression *increment = create_binary_expression(body->get_suif_env(),type,k_add, index_expr,step); replacement->append_statement(create_store_variable_statement(body->get_suif_env(),index,increment)); // and loop if not out of range Expression *compare = create_binary_expression(body->get_suif_env(),type, compare_op, deep_suif_clone<Expression>(index_expr), deep_suif_clone<Expression>(step)); replacement->append_statement(create_branch_statement(body->get_suif_env(),compare,continue_lab)); // end of loop replacement->append_statement(create_label_location_statement(body->get_suif_env(),break_lab)); // if(post_pad != 0)replacement->append_statement(post_pad); the_for->get_parent()->replace(the_for,replacement); return replacement; }