void InstrumentCalls::InstrumentCallsFunctor::postorder(Context ctx, AST_t node) { ScopeLink scope_link = ctx.scope_link; AST_t called_expression_tree = node.get_attribute(LANG_CALLED_EXPRESSION); AST_t arguments_tree = node.get_attribute(LANG_FUNCTION_ARGUMENTS); Expression called_expression(called_expression_tree, scope_link); // Only function-names are considered here if (!called_expression.is_id_expression()) { // std::cerr << "Called expression is not an id expression" << std::endl; return; } IdExpression called_id_expression = called_expression.get_id_expression(); if (!_instrument_filter.match(called_id_expression.prettyprint())) return; std::string shadow_function_name = "_" + called_id_expression.mangle_id_expression() + "_instr"; if (defined_shadows.find(shadow_function_name) == defined_shadows.end()) { // The shadow has not been defined, define it here if (!define_shadow(called_id_expression, shadow_function_name)) { // Ignore this shadow return; } defined_shadows.insert(shadow_function_name); } // Now replace the arguments Source replaced_arguments; replaced_arguments << "\"" << node.get_file() << "\"" << "," << node.get_line() ; if (arguments_tree.prettyprint() != "") { replaced_arguments << "," << arguments_tree.prettyprint(/*commas=*/true); } // Now create an expression tree Source shadow_function_call; shadow_function_call << shadow_function_name << "(" << replaced_arguments << ")" ; AST_t shadow_function_call_tree = shadow_function_call.parse_expression(node, scope_link); node.replace(shadow_function_call_tree); }
void DeviceCUDA::replace_kernel_config(AST_t &kernel_call, ScopeLink sl) { CUDA::KernelCall kcall(kernel_call, sl); Source new_kernel_call; Source new_config, new_param_list, nanos_stream_call; new_kernel_call << kcall.get_called_expression() << "<<<" << new_config << ">>>(" << new_param_list << ")"; ObjectList<Expression> argument_list = kcall.get_argument_list(); for (ObjectList<Expression>::iterator it = argument_list.begin(); it != argument_list.end(); it++) { new_param_list.append_with_separator(it->prettyprint(), ","); } nanos_stream_call << "nanos_get_kernel_execution_stream()"; ObjectList<Expression> kernel_config = kcall.get_kernel_configuration(); if (kernel_config.size() == 2) { new_config << kernel_config[0] << "," << kernel_config[1] << "," << "0, " << nanos_stream_call; } else if (kernel_config.size() == 3) { new_config << kernel_config[0] << "," << kernel_config[1] << "," << kernel_config[2] << "," << nanos_stream_call; } else if (kernel_config.size() == 4) { // Do nothing at the moment } else { internal_error("Code unreachable: a kernel call configuration must have between 2 and 4 parameters", 0); } AST_t expr = new_kernel_call.parse_expression(kernel_call, sl); kernel_call.replace(expr); }
void InstrumentCalls::MainWrapper::postorder(Context, AST_t node) { FunctionDefinition function_def(node, _sl); IdExpression function_name = function_def.get_function_name(); Symbol function_symbol = function_name.get_symbol(); Type function_type = function_symbol.get_type(); ObjectList<std::string> parameters; Source main_declaration = function_type.get_declaration_with_parameters(function_symbol.get_scope(), "main", parameters); // "main" is always an unqualified name so this transformation is safe function_name.get_ast().replace_text("__instrumented_main"); Source instrumented_main_declaration = function_type.get_declaration(function_symbol.get_scope(), "__instrumented_main"); Source null_expr; C_LANGUAGE() { null_expr << "(void*)0"; } CXX_LANGUAGE() { null_expr << "0"; } Source new_main; new_main << instrumented_main_declaration << ";" << "pthread_mutex_t __mintaka_instr_global_lock;" << "int __mintaka_pthread_global_counter;" << main_declaration << "{" // Begin << " pthread_mutex_init(&__mintaka_instr_global_lock, " << null_expr << ");" << " __mintaka_pthread_global_counter = 0;" << " mintaka_app_begin();" << " mintaka_set_filebase(_p_1[0]);" << " mintaka_thread_begin(1, ++__mintaka_pthread_global_counter);" << " mintaka_state_run();" // Event definition << " static const char* EVENT_CALL_USER_FUNCTION_DESCR = \"User function call\";" << " const int EVENT_CALL_USER_FUNCTION = 60000018;" << " mintaka_index_event(EVENT_CALL_USER_FUNCTION, EVENT_CALL_USER_FUNCTION_DESCR);" // Program << " int __result = __instrumented_main(_p_0, _p_1);" // End << " mintaka_thread_end();" << " mintaka_app_end();" << " mintaka_merge();" << " mintaka_index_generate();" << " return __result;" << "}" << node.prettyprint() ; AST_t new_main_tree = new_main.parse_global(function_def.get_ast(), function_def.get_scope_link()); node.replace(new_main_tree); }