static void tool_initialization(int argc, const char* argv[])
{
    atexit(cleanup_routine);

#if !defined(WIN32_BUILD) || defined(__CYGWIN__)
    // Define alternate stack
    stack_t alternate_stack;

	// Allocate a maximum of 1 Mbyte or more if MINSIGSTKSZ was
	// bigger than that (this is unlikely)
	int allocated_size = 1024 * 1024;
	if (MINSIGSTKSZ > 1024*1024)
	{
		allocated_size = MINSIGSTKSZ;
	}

	_alternate_signal_stack = malloc(allocated_size);

    alternate_stack.ss_flags = 0;
    alternate_stack.ss_size = allocated_size;
    alternate_stack.ss_sp = (void*)_alternate_signal_stack;

    if (alternate_stack.ss_sp == 0
            || sigaltstack(&alternate_stack, /* oss */ NULL) != 0)
    {
        running_error("Setting alternate signal stack failed (%s)\n",
				strerror(errno));
    }

    // Program signals
    struct sigaction terminating_sigaction;
    memset(&terminating_sigaction, 0, sizeof(terminating_sigaction));

    terminating_sigaction.sa_handler = terminating_signal_handler;
    // Use alternate stack and we want the signal be reset when it happens
    terminating_sigaction.sa_flags = SA_RESETHAND | SA_ONSTACK;
    // Block all blockable signals while handling the termination
    sigfillset(&terminating_sigaction.sa_mask);

    int result = 0;
    result |= sigaction(SIGSEGV, &terminating_sigaction, /* old_sigaction */ NULL);
    result |= sigaction(SIGQUIT, &terminating_sigaction, /* old_sigaction */ NULL);
    result |= sigaction(SIGINT,  &terminating_sigaction, /* old_sigaction */ NULL);
    result |= sigaction(SIGTERM, &terminating_sigaction, /* old_sigaction */ NULL);
    result |= sigaction(SIGABRT, &terminating_sigaction, /* old_sigaction */ NULL);
    
    if (result != 0)
    {
        running_error("Signal programming failed with '%s'\n", strerror(errno));
    }
#endif

    memset(&compilation_process, 0, sizeof(compilation_process));
    compilation_process.argc = argc;
    compilation_process.argv = (const char**)argv;
    compilation_process.exec_basename = give_basename(argv[0]);

    // Find my own directory
    compilation_process.home_directory = find_home(argv[0]);
}
Esempio n. 2
0
static void open_files(prescanner_t* prescanner)
{
	if (strcmp(prescanner->input_filename, "-") != 0)
	{
		prescanner->input_file = fopen(prescanner->input_filename, "r");

		if (prescanner->input_file == NULL)
		{
			running_error("Cannot open input file '%s' (%s)\n", prescanner->input_filename,
					strerror(errno));
		}
	}
	else 
	{
		prescanner->input_file = stdin;
		prescanner->input_filename = "(stdin)";
	}

	if (strcmp(prescanner->output_filename, "-") != 0)
	{
		prescanner->output_file = fopen(prescanner->output_filename, "w");

		if (prescanner->output_file == NULL)
		{
			running_error("Cannot open output file '%s' (%s)\n", prescanner->output_filename,
					strerror(errno));
		}
	}
	else
	{
		prescanner->output_file = stdout;
		prescanner->output_filename = "(stdout)";
	}
}
 void Interface::interface_preorder(PragmaCustomConstruct ctr)
 {
     PragmaCustomClause version_clause = ctr.get_clause("version");
     PragmaCustomClause family_clause = ctr.get_clause("family");
     
     // The runtime must provide always a pair of Family/Version, never only one of them
     if (family_clause.is_defined()
         && !family_clause.get_arguments(ExpressionTokenizer()).empty()
         && version_clause.is_defined()
         && !version_clause.get_arguments(ExpressionTokenizer()).empty())
     {
         std::string new_family = family_clause.get_arguments(ExpressionTokenizer())[0];
         if (Version::_interfaces.find(new_family) != Version::_interfaces.end()
             && (new_family != Version::DEFAULT_FAMILY
             || Version::_interfaces[new_family] != Version::DEFAULT_VERSION))
         {
             std::stringstream ss;
             ss << Version::_interfaces[family_clause.get_arguments(ExpressionTokenizer())[0]];
             running_error("error: Nanos family %s previously defined with version %s\n",
                           family_clause.get_arguments(ExpressionTokenizer())[0].c_str(), 
                           ss.str().c_str());
         }
         else
         {
             Version::_interfaces[family_clause.get_arguments(ExpressionTokenizer())[0]] 
                     = atoi(version_clause.get_arguments(ExpressionTokenizer())[0].c_str());                
         }
     }
     else
     {
         running_error("error: Both, family and version must be provided by the runtime.\n");
     }
 }
Esempio n. 4
0
    void KNCModuleVisitor::visit(const Nodecl::VectorBitwiseXor& node) 
    { 
        TL::Type type = node.get_type().basic_type();

        // Intrinsic name
        file << "_mm512_xor";
        
        // Postfix
        if (type.is_float()) 
        { 
            file << "_ps"; 
        } 
        else if (type.is_integral_type())
        { 
            file << "_si128"; 
        }
        else
        {
            running_error("KNC Codegen: Node %s at %s has an unsupported type.", 
                    ast_print_node_type(node.get_kind()),
                    node.get_locus_str().c_str());
        }      

        file << "("; 
        walk(node.get_lhs());
        file << ", ";
        walk(node.get_rhs());
        file << ")"; 
    }   
Esempio n. 5
0
static char* read_whole_line(FILE* input)
{
	// It should be enough
	int buffer_size = 1024;
	int was_eof;
	int length_read;
	char* temporal_buffer = xcalloc(buffer_size, sizeof(char));
	// We read buffer_size-1 characters
	if (fgets(temporal_buffer, buffer_size, input) == NULL)
    {
        if (ferror(input))
        {
            running_error("error: while starting to split file\n");
        }
    }

	if (temporal_buffer[0] == '\0')
	{
		xfree(temporal_buffer);
		return NULL;
	}

	length_read = strlen(temporal_buffer);
	was_eof = feof(input);

	while ((temporal_buffer[length_read - 1] != '\n') && !was_eof)
	{
		temporal_buffer = xrealloc(temporal_buffer, 2*sizeof(char)*buffer_size);
		if (fgets(&temporal_buffer[length_read], buffer_size, input) == NULL)
        {
            if (ferror(input))
            {
                running_error("error: while splitting file\n");
            }
        }

		length_read = strlen(temporal_buffer);
		buffer_size = buffer_size * 2;
		was_eof = feof(input);
	}

	return temporal_buffer;
}
        void OpenMPTransform::critical_postorder(PragmaCustomConstruct critical_construct)
        {
            Source critical_source;

            Statement critical_body = critical_construct.get_statement();
            ScopeLink scope_link = critical_construct.get_scope_link();

            std::string mutex_variable;

            if (!critical_construct.is_parameterized())
            {
                mutex_variable = "_nthf_unspecified_critical";
            }
            else
            {
                // ObjectList<IdExpression> id_expressions = region_name.id_expressions(TL::ALL_FOUND_SYMBOLS);
                // IdExpression head = id_expressions[0];

                ObjectList<std::string> args = critical_construct.get_parameter_arguments();

                if (args.size() > 1)
                {
                    std::cerr << critical_construct.get_ast().get_locus() 
                        << ": warning: #pragma omp critical only receives one argument, using first one" 
                        << std::endl;
                }
                else if (args.size() == 0)
                {
                    running_error("%s: error: #pragma omp critical needs an argument",
                            critical_construct.get_ast().get_locus().c_str());
                }

                mutex_variable = "_nthf_"  + args[0];
            }

            critical_source
                << "{"
                //                    <<   "extern void nthf_spin_lock_(void*);"
                //                    <<   "extern void nthf_spin_unlock_(void*);"
                <<   "nthf_spin_lock_(&" << mutex_variable << ");"
                <<   critical_body.prettyprint()
                <<   "nthf_spin_unlock_(&" << mutex_variable << ");"
                << "}"
                ;

            define_global_mutex(mutex_variable, critical_construct.get_ast(),
                    critical_construct.get_scope_link());

            AST_t critical_tree = critical_source.parse_statement(critical_construct.get_ast(),
                    critical_construct.get_scope_link());

            critical_construct.get_ast().replace(critical_tree);
        }
Esempio n. 7
0
    void KNCModuleVisitor::visit(const Nodecl::VectorMinus& node) 
    { 
        TL::Type type = node.get_type().basic_type();

        // Intrinsic name
        file << "_mm512_sub";
        
        // Postfix
        if (type.is_float()) 
        { 
            file << "_ps"; 
        } 
        else if (type.is_double()) 
        { 
            file << "_pd"; 
        } 
        else if (type.is_signed_int() ||
            type.is_unsigned_int()) 
        { 
            file << "_epi32"; 
        } 
        else if (type.is_signed_short_int() ||
            type.is_unsigned_short_int()) 
        { 
            file << "_epi16"; 
        } 
        else if (type.is_char() || 
            type.is_signed_char() ||
            type.is_unsigned_char()) 
        { 
            file << "_epi8"; 
        } 
        else
        {
            running_error("KNC Codegen: Node %s at %s has an unsupported type.", 
                    ast_print_node_type(node.get_kind()),
                    node.get_locus_str().c_str());
        }      

        file << "("; 
        walk(node.get_lhs());
        file << ", ";
        walk(node.get_rhs());
        file << ")"; 
    }                                                 
Esempio n. 8
0
static void remove_inlined_comments(void)
{
	line_t* iter = file_lines;
	char unended_string;
	while (iter != NULL)
	{
		// Getting here that a string is unended 
		// would be a scanning error
		trim_inline_comment(iter, &unended_string);

		if (unended_string != 0)
		{
			running_error("%s:%d: error: unended string at line %d !\n", 
                    prescanner->input_filename,
                    iter->line_number);
		}
		iter = iter->next;
	}
}
Esempio n. 9
0
    Nodecl::NodeclBase Source::parse_common(ReferenceScope ref_scope,
            ParseFlags parse_flags,
            const std::string& subparsing_prefix,
            prepare_lexer_fun_t prepare_lexer,
            parse_fun_t parse,
            compute_nodecl_fun_t compute_nodecl,
            decl_context_map_fun_t decl_context_map_fun)
    {

        source_language_t kept_language;
        switch_language(kept_language);

        std::string extended_source = "\n" + this->get_source(true);

        std::string mangled_text = subparsing_prefix + extended_source;

        prepare_lexer(mangled_text.c_str());

        int parse_result = 0;
        AST a = NULL;

        parse_result = parse(&a);

        if (parse_result != 0)
        {
            running_error("Could not parse source\n\n%s\n", 
                    format_source(extended_source).c_str());
        }

        decl_context_t decl_context = decl_context_map_fun(ref_scope.get_scope().get_decl_context());

        nodecl_t nodecl_output = nodecl_null();
        compute_nodecl(a, decl_context, &nodecl_output);

        restore_language(kept_language);

        return nodecl_output;
    }
Esempio n. 10
0
    void AST_t::prettyprint_in_file(const CompiledFile& compiled_file, bool internal) const
    {
        if (!internal)
        {
            prettyprint_set_not_internal_output();
        }
        else
        {
            prettyprint_set_internal_output();
        }

        FILE *file = fopen(compiled_file.get_filename().c_str(), "a");
        if (file == NULL)
        {
            running_error("Could not open output file '%s' (%s)\n", 
                    compiled_file.get_filename().c_str(), 
                    strerror(errno));
        }

        ::prettyprint(file, this->_ast);

        fclose(file);
    }
        void OpenMPTransform::ordered_postorder(PragmaCustomConstruct ordered_construct)
        {
            running_error("%s: error: '#pragma omp ordered' is not supported",
                    ordered_construct.get_ast().get_locus().c_str());
            /* 
            Symbol induction_var = induction_var_stack.top();

            Statement construct_body = ordered_construct.get_statement();
            Source ordered_source;

            ordered_source
                << "{"
                <<   "in__tone_enter_ordered_ (& "<< induction_var.get_name() << ");"
                <<   construct_body.prettyprint()
                <<   "in__tone_leave_ordered_ (&" << induction_var.get_name() << ");"
                << "}"
                ;

            AST_t ordered_code = ordered_source.parse_statement(ordered_construct.get_ast(),
                    ordered_construct.get_scope_link());

            ordered_construct.get_ast().replace(ordered_code);
            */
        }
        void Core::collapse_loop_first(PragmaCustomConstruct& construct)
        {
            PragmaCustomClause collapse = construct.get_clause("collapse");

            if (!collapse.is_defined())
                return;

            ObjectList<Expression> expr_list = collapse.get_expression_list();
            if (expr_list.size() != 1)
            {
                running_error("%s: error: 'collapse' clause must have one argument\n",
                        construct.get_ast().get_locus().c_str());
            }

            Expression &expr = expr_list.front();
            if (!expr.is_constant())
            {
                running_error("%s: error: 'collapse' clause argument '%s' is not a constant expression\n",
                        expr.get_ast().get_locus().c_str(),
                        expr.prettyprint().c_str());
            }

            bool valid;
            int nest_level = expr.evaluate_constant_int_expression(valid);
            if (!valid)
            {
                running_error("%s: error: 'collapse' clause argument '%s' is not a constant expression\n",
                        expr.get_ast().get_locus().c_str(),
                        expr.prettyprint().c_str());
            }

            if (nest_level <= 0)
            {
                running_error("%s: error: nesting level of 'collapse' clause must be a nonzero positive integer\n",
                        expr.get_ast().get_locus().c_str());
            }

            if (!ForStatement::predicate(construct.get_statement().get_ast()))
            {
                running_error("%s: error: collapsed '#pragma omp for' or '#pragma omp parallel for' require a for-statement\n",
                        construct.get_statement().get_ast().get_locus().c_str());
            }

            ForStatement for_stmt(construct.get_statement().get_ast(), 
                    construct.get_scope_link());
            HLT::LoopCollapse loop_collapse(for_stmt);

            ObjectList<std::string> ancillary_names;

            Source header;
            loop_collapse
                .set_nesting_level(nest_level)
                .set_split_transform(header)
                .set_induction_private(true)
                .keep_ancillary_names(ancillary_names);

            Source collapsed_for = loop_collapse;

            Source transformed_code;
            AST_t pragma_placeholder;
            transformed_code
                << "{"
                << header
                << statement_placeholder(pragma_placeholder)
                << "}"
                ;

            AST_t tree = transformed_code.parse_statement(construct.get_ast(), construct.get_scope_link());

            Source new_firstprivate_entities;
            Source pragma_line;
            Source omp_part_src;
            omp_part_src
                << "#pragma omp " << pragma_line << new_firstprivate_entities << "\n"
                << collapsed_for
                ;

            new_firstprivate_entities << "firstprivate(" << concat_strings(ancillary_names, ",") << ")";

            pragma_line << construct.get_pragma_line().prettyprint_with_callback(functor(remove_collapse_clause));

            AST_t omp_part_tree = omp_part_src.parse_statement(pragma_placeholder, 
                    construct.get_scope_link());

            // Replace the pragma part
            pragma_placeholder.replace(omp_part_tree);

            // Replace the whole construct
            construct.get_ast().replace(tree);

            // Now overwrite the old construct with this new one
            construct = PragmaCustomConstruct(pragma_placeholder, construct.get_scope_link());
        }
Esempio n. 13
0
void fortran_split_lines(FILE* input, FILE* output, int width)
{
    ERROR_CONDITION(width <= 0, "Invalid width = %d\n", width);

	int length;
	char* line;

	while ((line = read_whole_line(input)) != NULL)
	{
		// We must remove trailing spaces before "\n" (if any)
		// since we cannot continuate to an empty line
		trim_right_line(line);

		// Comments that will reach here are those created within the compiler 
		// (e.g. TPL) because scanner always trims them
        char prefix[33] = { 0 };
        char is_construct = check_for_construct(line, prefix, 32);
		char is_comment = check_for_comment(line);

		length = strlen(line);
		// Many times we will fall here by means of length <= width
		if ((length <= width))
		{
			fputs(line, output);
		}
        else if (is_construct)
        {
            // Do not complicate ourselves, rely on a double continuation
            int column = 1;
            double_continuate_construct(output, prefix, line, width, &column);
            fprintf(output, "\n");
        }
        else if (is_comment)
        {
			fputs(line, output);
        }
		else
		{
			int column, next_column;
			char* position;
			char* next_position;

			YY_BUFFER_STATE scan_line = mf03_scan_string(line);
			mf03_switch_to_buffer(scan_line);

			// Initialize stuff
			column = 1;
			position = line;

			// Scan
			int token = mf03lex();
			while (token != EOS)
			{
				// Find the token as there can be spaces
				// next_position has the first character of the token
				next_position = strstr(position, mf03lval.token_atrib.token_text);

				if (next_position == NULL)
				{
					running_error("Serious problem when splitting line:\n\n %s", line);
				}

				// Next column has the column where the token will start
				next_column = column + (next_position - position);


				// Check if we have reached the last column or if spaces plus
				// token will not fit in this line
				if (column == width
						|| (next_column + (int)strlen(mf03lval.token_atrib.token_text) >= width))
				{
					DEBUG_CODE() DEBUG_MESSAGE("Cutting at '%s'", mf03lval.token_atrib.token_text);
					// Nothing fits here already
                    fprintf(output, "&\n");
                    column = 1;
				}

				// Write the blanks
				char* c;
				for (c = position; c < next_position; c++)
				{
					DEBUG_CODE() DEBUG_MESSAGE("%d - Blank - '%c'", column, *c);
					fprintf(output, "%c", *c);
					column++;
				}

				if ((column + (int)strlen(mf03lval.token_atrib.token_text)) >= width)
				{
					// We are very unlucky, the whole token still does not fit
					// in this line !
					double_continuate(output, mf03lval.token_atrib.token_text, width, &column);
				}
				else
				{
					// Write the token
					DEBUG_CODE() DEBUG_MESSAGE("%d - Token '%s'", column, mf03lval.token_atrib.token_text);
					fprintf(output, "%s", mf03lval.token_atrib.token_text);
					column += strlen(mf03lval.token_atrib.token_text);
				}

				// Update state to be coherent before entering the next iteration
				// column has been updated before
				position = next_position + strlen(mf03lval.token_atrib.token_text);
				token = mf03lex();
			}

			// The EOS
			fprintf(output, "\n");

			mf03_delete_buffer(scan_line);
		}
		
		xfree(line);
	}
}
Esempio n. 14
0
    void LoweringVisitor::reduction_initialization_code(
            OutlineInfo& outline_info,
            Nodecl::NodeclBase ref_tree,
            Nodecl::NodeclBase construct)
    {
        ERROR_CONDITION(ref_tree.is_null(), "Invalid tree", 0);

        if (!Nanos::Version::interface_is_at_least("master", 5023))
        {
            running_error("%s: error: a newer version of Nanos++ (>=5023) is required for reductions support\n",
                    construct.get_locus_str().c_str());
        }

        TL::ObjectList<OutlineDataItem*> reduction_items = outline_info.get_data_items().filter(
                predicate(lift_pointer(functor(&OutlineDataItem::is_reduction))));
        ERROR_CONDITION (reduction_items.empty(), "No reductions to process", 0);

        Source result;

        Source reduction_declaration,
               thread_initializing_reduction_info,
               thread_fetching_reduction_info;

        result
            << reduction_declaration
            << "{"
            << as_type(get_bool_type()) << " red_single_guard;"
            << "nanos_err_t err;"
            << "err = nanos_enter_sync_init(&red_single_guard);"
            << "if (err != NANOS_OK)"
            <<     "nanos_handle_error(err);"
            << "if (red_single_guard)"
            << "{"
            <<    "int nanos_num_threads = nanos_omp_get_num_threads();"
            <<    thread_initializing_reduction_info
            <<    "err = nanos_release_sync_init();"
            <<    "if (err != NANOS_OK)"
            <<        "nanos_handle_error(err);"
            << "}"
            << "else"
            << "{"
            <<    "err = nanos_wait_sync_init();"
            <<    "if (err != NANOS_OK)"
            <<        "nanos_handle_error(err);"
            <<    thread_fetching_reduction_info
            << "}"
            << "}"
            ;

        for (TL::ObjectList<OutlineDataItem*>::iterator it = reduction_items.begin();
                it != reduction_items.end();
                it++)
        {
            std::string nanos_red_name = "nanos_red_" + (*it)->get_symbol().get_name();

            std::pair<OpenMP::Reduction*, TL::Type> reduction_info = (*it)->get_reduction_info();
            OpenMP::Reduction* reduction = reduction_info.first;
            TL::Type reduction_type = reduction_info.second;

            if (reduction_type.is_any_reference())
                reduction_type = reduction_type.references_to();

            TL::Type reduction_element_type = reduction_type;
            if (IS_FORTRAN_LANGUAGE)
            {
                while (reduction_element_type.is_fortran_array())
                    reduction_element_type = reduction_element_type.array_element();
            }
            else
            {
                while (reduction_element_type.is_array())
                    reduction_element_type = reduction_element_type.array_element();
            }

            Source element_size;
            if (IS_FORTRAN_LANGUAGE)
            {
                if (reduction_type.is_fortran_array())
                {
                    // We need to parse this bit in Fortran
                    Source number_of_bytes;
                    number_of_bytes << "SIZE(" << (*it)->get_symbol().get_name() << ") * " << reduction_element_type.get_size();

                    element_size << as_expression(number_of_bytes.parse_expression(construct));
                }
                else
                {
                    element_size << "sizeof(" << as_type(reduction_type) << ")";
                }
            }
            else
            {
                element_size << "sizeof(" << as_type(reduction_type) << ")";
            }

            reduction_declaration
                << "nanos_reduction_t* " << nanos_red_name << ";"
                ;

            Source allocate_private_buffer, cleanup_code;

            Source num_scalars;

            TL::Symbol basic_reduction_function, vector_reduction_function;
            create_reduction_function(reduction, construct, reduction_type, basic_reduction_function, vector_reduction_function);
            (*it)->reduction_set_basic_function(basic_reduction_function);

            thread_initializing_reduction_info
                << "err = nanos_malloc((void**)&" << nanos_red_name << ", sizeof(nanos_reduction_t), " 
                << "\"" << construct.get_filename() << "\", " << construct.get_line() << ");"
                << "if (err != NANOS_OK)"
                <<     "nanos_handle_error(err);"
                << nanos_red_name << "->original = (void*)" 
                <<            (reduction_type.is_array() ? "" : "&") << (*it)->get_symbol().get_name() << ";"
                << allocate_private_buffer
                << nanos_red_name << "->vop = "
                <<      (vector_reduction_function.is_valid() ? as_symbol(vector_reduction_function) : "0") << ";"
                << nanos_red_name << "->bop = (void(*)(void*,void*,int))" << as_symbol(basic_reduction_function) << ";"
                << nanos_red_name << "->element_size = " << element_size << ";"
                << nanos_red_name << "->num_scalars = " << num_scalars << ";"
                << cleanup_code
                << "err = nanos_register_reduction(" << nanos_red_name << ");"
                << "if (err != NANOS_OK)"
                <<     "nanos_handle_error(err);"
                ;

            if (IS_C_LANGUAGE
                    || IS_CXX_LANGUAGE)
            {
                if (reduction_type.is_array())
                {
                    num_scalars << "sizeof(" << as_type(reduction_type) << ") / sizeof(" << as_type(reduction_element_type) <<")";
                }
                else
                {
                    num_scalars << "1";
                }

                allocate_private_buffer
                    << "err = nanos_malloc(&" << nanos_red_name << "->privates, sizeof(" << as_type(reduction_type) << ") * nanos_num_threads, "
                    << "\"" << construct.get_filename() << "\", " << construct.get_line() << ");"
                    << "if (err != NANOS_OK)"
                    <<     "nanos_handle_error(err);"
                    << nanos_red_name << "->descriptor = " << nanos_red_name << "->privates;"
                    << "rdv_" << (*it)->get_field_name() << " = (" <<  as_type( (*it)->get_private_type().get_pointer_to() ) << ")" << nanos_red_name << "->privates;"
                    ;


                thread_fetching_reduction_info
                    << "err = nanos_reduction_get(&" << nanos_red_name << ", " 
                    << (reduction_type.is_array() ? "" : "&") << (*it)->get_symbol().get_name() << ");"

                    << "if (err != NANOS_OK)"
                    <<     "nanos_handle_error(err);"
                    << "rdv_" << (*it)->get_field_name() << " = (" <<  as_type( (*it)->get_private_type().get_pointer_to() ) << ")" << nanos_red_name << "->privates;"
                    ;
                cleanup_code
                    << nanos_red_name << "->cleanup = nanos_free0;"
                    ;
            }
            else if (IS_FORTRAN_LANGUAGE)
            {

                Type private_reduction_vector_type;

                Source extra_dims;
                {
                    TL::Type t = (*it)->get_symbol().get_type().no_ref();
                    int rank = 0;
                    if (t.is_fortran_array())
                    {
                        rank = t.fortran_rank();
                    }

                    if (rank != 0)
                    {
                        // We need to parse this bit in Fortran
                        Source size_call;
                        size_call << "SIZE(" << (*it)->get_symbol().get_name() << ")";

                        num_scalars << as_expression(size_call.parse_expression(construct));
                    }
                    else
                    {
                        num_scalars << "1";
                    }
                    private_reduction_vector_type = fortran_get_n_ranked_type_with_descriptor(
                            get_void_type(), rank + 1, construct.retrieve_context().get_decl_context());

                    int i;
                    for (i = 0; i < rank; i++)
                    {
                        Source lbound_src;
                        lbound_src << "LBOUND(" << (*it)->get_symbol().get_name() << ", DIM = " << (rank - i) << ")";
                        Source ubound_src;
                        ubound_src << "UBOUND(" << (*it)->get_symbol().get_name() << ", DIM = " << (rank - i) << ")";

                        extra_dims 
                            << "["
                            << as_expression(lbound_src.parse_expression(construct))
                            << ":"
                            << as_expression(ubound_src.parse_expression(construct))
                            << "]";

                        t = t.array_element();
                    }
                }

                allocate_private_buffer
                    << "@FORTRAN_ALLOCATE@((*rdv_" << (*it)->get_field_name() << ")[0:(nanos_num_threads-1)]" << extra_dims <<");"
                    << nanos_red_name << "->privates = &(*rdv_" << (*it)->get_field_name() << ");"
                    << "err = nanos_malloc(&" << nanos_red_name << "->descriptor, sizeof(" << as_type(private_reduction_vector_type) << "), "
                    << "\"" << construct.get_filename() << "\", " << construct.get_line() << ");"
                    << "if (err != NANOS_OK)"
                    <<     "nanos_handle_error(err);"
                    << "err = nanos_memcpy(" << nanos_red_name << "->descriptor, "
                    "&rdv_" << (*it)->get_field_name() << ", sizeof(" << as_type(private_reduction_vector_type) << "));"
                    << "if (err != NANOS_OK)"
                    <<     "nanos_handle_error(err);"
                    ;

                thread_fetching_reduction_info
                    << "err = nanos_reduction_get(&" << nanos_red_name << ", &" << (*it)->get_symbol().get_name() << ");"
                    << "if (err != NANOS_OK)"
                    <<     "nanos_handle_error(err);"
                    << "err = nanos_memcpy("
                    << "&rdv_" << (*it)->get_field_name() << ","
                    << nanos_red_name << "->descriptor, "
                    << "sizeof(" << as_type(private_reduction_vector_type) << "));"
                    << "if (err != NANOS_OK)"
                    <<     "nanos_handle_error(err);"
                    ;

                TL::Symbol reduction_cleanup = create_reduction_cleanup_function(reduction, construct);
                cleanup_code
                    << nanos_red_name << "->cleanup = " << as_symbol(reduction_cleanup) << ";"
                    ;
            }
            else
            {
                internal_error("Code unreachable", 0);
            }
        }

        FORTRAN_LANGUAGE()
        {
            Source::source_language = SourceLanguage::C;
        }
        ref_tree.replace(result.parse_statement(ref_tree));
        FORTRAN_LANGUAGE()
        {
            Source::source_language = SourceLanguage::Current;
        }
    }
Esempio n. 15
0
static void manage_included_file(
        prescanner_t* prescanner, 
        char* included_filename, 
        FILE** handle_included_file, 
		FILE** handle_output_file)
{
	*handle_included_file = NULL;
	*handle_output_file = NULL;

	int i;
	for (i = 0; i < prescanner->num_include_directories; i++)
	{
		FILE* handle;
		char* full_name = xcalloc(strlen(prescanner->include_directories[i]) +
				strlen("/") + strlen(included_filename) + 1, sizeof(char));

		strcat(full_name, prescanner->include_directories[i]);
		strcat(full_name, "/");
		strcat(full_name, included_filename);

		handle = fopen(full_name, "r");

		if (handle != NULL)
		{
            prescanner->input_filename = full_name;
			// We got to open the include then create the output filename
			// 
			// If the user specified a directory for include regeneration use it
			// otherwise use the original directory of this include
			char* full_output_name;
			if (prescanner->output_include_directory == NULL)
			{
				full_output_name = xcalloc(strlen(prescanner->include_directories[i]) +
						strlen("/"INCLUDES_PREFIX) + strlen(included_filename) + 1, sizeof(char));

				strcat(full_output_name, prescanner->include_directories[i]);
				strcat(full_output_name, "/"INCLUDES_PREFIX);
				strcat(full_output_name, included_filename);
			}
			else
			{
				full_output_name = xcalloc(strlen(prescanner->output_include_directory) +
						strlen("/"INCLUDES_PREFIX) + strlen(included_filename) + 1, sizeof(char));

				strcat(full_output_name, prescanner->output_include_directory);
				strcat(full_output_name, "/"INCLUDES_PREFIX);
				strcat(full_output_name, included_filename);
			}

			FILE* handle_output;

			handle_output = fopen(full_output_name, "w");

			if (handle_output == NULL)
			{
				running_error("Cannot open output of included file '%s' (%s)\n", 
                        full_output_name, strerror(errno));
			}

			*handle_included_file = handle;
			*handle_output_file = handle_output;
			return;
		}

		xfree(full_name);
	}
}
Esempio n. 16
0
static void read_lines(prescanner_t* prescanner)
{
	int line_number = 1;
	while (!feof(prescanner->input_file))
	{
		// We will start with a width + 10 buffer size
		int buffer_size = prescanner->width + 10;
		char* line_buffer = (char*)xcalloc(buffer_size, sizeof(char));

		// Read till '\n' or till buffer_size-1
		if (fgets(line_buffer, buffer_size, prescanner->input_file) == NULL)
        {
            if (ferror(prescanner->input_file))
            {
                running_error("error while reading line");
            }
        }

		// How many characters have we read
		int length_read = strlen(line_buffer);

		// Have we read all the line ? (we could have reach the end of the file ...)
		char was_eof = feof(prescanner->input_file);

		// The line is not '\n'-ended and we are not in the EOF
		// so we must enlarge the buffer
		while ((length_read > 0) && line_buffer[length_read-1] != '\n' && !was_eof)
		{
            DEBUG_CODE()
			{
				fprintf(stderr, "DEBUG: Enlarging after having read @%s|\n", line_buffer);
			}
			// Enlarge exponentially
			line_buffer = (char*) xrealloc(line_buffer, 2*buffer_size*sizeof(char));

			// We read from the former end
			if (fgets(&line_buffer[length_read], buffer_size, prescanner->input_file) == NULL)
            {
                if (ferror(prescanner->input_file))
                {
                    running_error("error while reading line");
                }
            }
			
			buffer_size = buffer_size * 2;
			length_read = strlen(line_buffer);
			was_eof = feof(prescanner->input_file);
		}

		// Remove '\n'
		if (!was_eof)
		{
			line_buffer[length_read-1] = '\0';
			length_read--;
		}

		if (length_read > 0)
		{
			// We found \r\n, kill the '\r' as well
			if (line_buffer[length_read-1] == '\r')
			{
				line_buffer[length_read-1] = '\0';
				length_read--;
			}
		}

        if (is_blank_string(line_buffer))
        {
            // Merrily ignore this line
            xfree(line_buffer);
        }
        else
        {

            line_t* new_line = (line_t*) xcalloc(1, sizeof(line_t));

            DEBUG_CODE()
            {
                fprintf(stderr, "DEBUG: We have read @%s|\n", line_buffer);
            }

            new_line->line = line_buffer;
            new_line->line_number = line_number;
            new_line->next = NULL;
            new_line->joined_lines = 0;

            if (file_lines == NULL)
            {
                file_lines = new_line;
                last_line = new_line;
            }
            else
            {
                last_line->next = new_line;
                last_line = new_line;
            }

        }

        line_number++;
	}
}
Esempio n. 17
0
static void join_continuated_lines(prescanner_t* prescanner)
{
	int code;
	line_t* iter = file_lines;
	regex_t match_continuated;

	line_t* previous_line = NULL;

	// First we prepare a regex to match continuated lines
	if ((code = regcomp(&match_continuated, "^(([ ]{5})|(![$](omp))|(![$][ ]{3}))[^0[:blank:]]", REG_EXTENDED | REG_NOSUB | REG_ICASE)) != 0)
	{
		char error_message[120];
		regerror(code, &match_continuated, error_message, 120);
		internal_error("Error when compiling regular expression (%s)\n", error_message);
	}

	while (iter != NULL)
	{
		if (regexec(&match_continuated, iter->line, 0, NULL, 0) == 0)
		{
			if (previous_line == NULL)
			{
				running_error("%s:%d: error: cannot continuate the first non-comment line", 
                        prescanner->input_filename,
                        iter->line_number);
			}

			// Pay attention to not to b0rk 'iter'
			join_two_lines(prescanner, previous_line, iter);

			line_t* old_line = iter;
			iter = iter->next;

			xfree_line_t(old_line);
		}
		else // Not a continuating one
		{
			char ignored_line = 1;

			if (iter->line[0] == '!')
			{
				// We spring over this comment unless it is a coco line or an omp line
				if ((strncmp(iter->line, "!$ ", 3) == 0)
						|| (strncasecmp(iter->line, "!$omp", 5) == 0))
				{
					ignored_line = 0;
				}
			}
			else
			{
				ignored_line = 0;
			}

			if (!ignored_line)
			{
				// It could have an annoying zero 
				if (iter->line[5] == '0')
				{
					iter->line[5] = ' ';
				}

				previous_line = iter;
			}
			iter = iter->next;
		}
	}

	regfree(&match_continuated);
}
Esempio n. 18
0
static void handle_include_line(
        prescanner_t* prescanner,
        line_t* iter,
        regmatch_t *sub_matching)
{
    static int maximum_nesting_level = 0;
    // We save current information
    line_t* current_file_lines = file_lines;
    line_t* current_last_line = last_line;
    FILE* current_input_file = prescanner->input_file;
    FILE* current_output_file = prescanner->output_file;
    const char* current_filename = prescanner->input_filename;

    if (maximum_nesting_level > 99)
    {
        running_error("%s:%d: error: too many levels of nesting (> %d)",
                prescanner->input_filename,
                iter->line_number,
                maximum_nesting_level);
    }
    maximum_nesting_level++;

    // Get the filename
    char* included_filename = get_filename_include(iter->line, sub_matching);
    char* new_included_filename = create_new_filename(included_filename);
    char* fortran_literal_filename = fortran_literal(new_included_filename);

    // We replace the include with the new file
    iter->line[0] = '\0';
    strcat(iter->line, "      INCLUDE \"");
    strcat(iter->line, fortran_literal_filename);
    strcat(iter->line, "\"");

    DEBUG_CODE()
    {
        fprintf(stderr, "DEBUG: INCLUDE LINE-> Opening file '%s'\n", included_filename);
    }

    manage_included_file(prescanner, included_filename, &prescanner->input_file, &prescanner->output_file);

    if (prescanner->input_file == NULL)
    {
        running_error("%s:%d: error: cannot open included file '%s' (%s)\n",
                prescanner->input_filename,
                iter->line_number,
                included_filename,
                strerror(errno));
    }

    // Now, recursive processing
    fortran_prescanner_process(prescanner);

    xfree(included_filename);
    xfree(new_included_filename);
    xfree(fortran_literal_filename);

    maximum_nesting_level--;

    // We restore saved information
    file_lines = current_file_lines;
    last_line = current_last_line;
    prescanner->input_filename = current_filename;
    prescanner->input_file = current_input_file;
    prescanner->output_file = current_output_file;
}
        void VectorizerVisitorExpression::visit(const Nodecl::FunctionCall& n)
        {
            Nodecl::NodeclBase called = n.get_called();
            ERROR_CONDITION(!called.is<Nodecl::Symbol>(),
                    "Vectorizer: %s found. This kind of function call is not supported yet",
                    ast_print_node_type(called.get_kind()));

            Nodecl::Symbol called_sym = called.as<Nodecl::Symbol>();

            // Vectorizing arguments
            walk(n.get_arguments());

            // Special functions
            if (called_sym.get_symbol().get_name() == "fabsf")
            {
                const Nodecl::VectorFabs vector_fabs_call =
                    Nodecl::VectorFabs::make(
                            n.get_arguments().as<Nodecl::List>().front().shallow_copy(),
                            get_qualified_vector_to(n.get_type(), _vector_length),
                            n.get_locus());

                n.replace(vector_fabs_call);
            }
            else //Common functions
            {
                // Get the best vector version of the function available
                Nodecl::NodeclBase best_version =
                    TL::Vectorization::Vectorizer::_function_versioning.get_best_version(
                            called_sym.get_symbol().get_name(), _device, _vector_length, _target_type);

                ERROR_CONDITION(best_version.is_null(), "Vectorizer: the best vector function for '%s' is null",
                        called_sym.get_symbol().get_name().c_str());

                // Create new called symbol
                Nodecl::Symbol new_called;
                if (best_version.is<Nodecl::FunctionCode>())
                {
                    new_called = best_version.as<Nodecl::FunctionCode>().get_symbol().
                        make_nodecl(n.get_locus());
                }
                else if (best_version.is<Nodecl::Symbol>())
                {
                    new_called = best_version.as<Nodecl::Symbol>().get_symbol().
                        make_nodecl(n.get_locus());
                }
                else
                {
                    running_error("Vectorizer: %s found as vector function version in function versioning.",
                            ast_print_node_type(best_version.get_kind()));
                }

                const Nodecl::VectorFunctionCall vector_function_call =
                    Nodecl::VectorFunctionCall::make(
                            new_called,
                            n.get_arguments().shallow_copy(),
                            n.get_alternate_name().shallow_copy(),
                            n.get_function_form().shallow_copy(),
                            get_qualified_vector_to(n.get_type(), _vector_length),
                            n.get_locus());

                n.replace(vector_function_call);
            }
        }
        void VectorizerVisitorExpression::visit(const Nodecl::Symbol& n)
        {
            TL::Type sym_type = n.get_type();

            //std::cerr << "scalar_type: " << n.prettyprint() << std::endl;

            if (!sym_type.is_vector())
            {
               // Vectorize BASIC induction variable
                if (Vectorizer::_analysis_info->is_basic_induction_variable(
                            Vectorizer::_analysis_scopes->back(),
                            n))
                {
                    std::cerr << "Basic IV: " << n.prettyprint() << "\n";

                    // Computing IV offset {0, 1, 2, 3}
                    TL::ObjectList<Nodecl::NodeclBase> literal_list;

                    const_value_t *ind_var_increment = Vectorizer::_analysis_info->get_induction_variable_increment(
                            Vectorizer::_analysis_scopes->back(), n);

                    for(const_value_t *i = const_value_get_zero(4, 0);
                            const_value_is_nonzero(const_value_lt(i, const_value_get_unsigned_int(_unroll_factor)));
                            i = const_value_add(i, ind_var_increment))
                    {
                        literal_list.prepend(const_value_to_nodecl(i));
                    }

                    Nodecl::List offset = Nodecl::List::make(literal_list);

                    // IV cannot be a reference
                    TL::Type ind_var_type = get_qualified_vector_to(n.get_type(), _vector_length).no_ref();

                    TL::Type offset_type = ind_var_type;

                    Nodecl::ParenthesizedExpression vector_induction_var =
                        Nodecl::ParenthesizedExpression::make(
                                Nodecl::VectorAdd::make(
                                    Nodecl::VectorPromotion::make(
                                        n.shallow_copy(),
                                        ind_var_type,
                                        n.get_locus()),
                                    Nodecl::VectorLiteral::make(
                                        offset,
                                        offset_type,
                                        n.get_locus()),
                                    get_qualified_vector_to(n.get_type(), _vector_length),
                                    n.get_locus()),
                                get_qualified_vector_to(n.get_type(), _vector_length),
                                n.get_locus());

                    n.replace(vector_induction_var);
                }
                // Vectorize symbols declared in the SIMD scope
                else if (is_declared_in_scope(
                            _simd_inner_scope.get_decl_context().current_scope,
                            n.get_symbol().get_scope().get_decl_context().current_scope))
                {
                    //std::cerr << "NS scalar_type: " << n.prettyprint() << std::endl;

                    TL::Symbol tl_sym = n.get_symbol();
                    TL::Type tl_sym_type = tl_sym.get_type();

                    //TL::Symbol
                    if (tl_sym_type.is_scalar_type())
                    {
                        //std::cerr << "TS scalar_type: " << n.prettyprint() << std::endl;
                        tl_sym.set_type(get_qualified_vector_to(tl_sym_type, _vector_length));
                        tl_sym_type = tl_sym.get_type();
                    }

                    //Nodecl::Symbol
                    Nodecl::Symbol new_sym =
                        Nodecl::Symbol::make(tl_sym,
                                n.get_locus());

                    new_sym.set_type(tl_sym_type.get_lvalue_reference_to());

                    n.replace(new_sym);
                }
                // Vectorize constants
                else if (Vectorizer::_analysis_info->is_constant(
                            Vectorizer::_analysis_scopes->back(),
                            n))
                {
                    const Nodecl::VectorPromotion vector_prom =
                        Nodecl::VectorPromotion::make(
                                n.shallow_copy(),
                                get_qualified_vector_to(sym_type, _vector_length),
                                n.get_locus());

                    n.replace(vector_prom);
                }
                else
                {
                    //TODO: If you are from outside of the loop -> Vector local copy.
                    running_error("Vectorizer: Loop is not vectorizable. '%s' is not IV or Constant or Local.",
                            n.get_symbol().get_name().c_str());
                }
            }
        }