示例#1
0
    int SuitableAlignmentVisitor::visit( const Nodecl::Symbol& n ) 
    {
        if (is_suitable_expression(n))
        {
            return 0;
        }
        else if( n.is_constant( ) )
        {
            int value = const_value_cast_to_signed_int( n.get_constant( )) * _type_size;

            if(is_suitable_constant(value))
                return 0;
            else
                return value;
        }
        else if( Utils::induction_variable_list_contains_variable( _induction_variables, n ) )
        {
            Utils::InductionVariableData* iv = Utils::get_induction_variable_from_list( _induction_variables, n );
            Nodecl::Utils::ReduceExpressionVisitor v;
            
            Nodecl::NodeclBase lb = iv->get_lb( ).shallow_copy( );
            v.walk( lb );
            if( lb.is_constant( ) )
            {
                Nodecl::NodeclBase incr = iv->get_increment( ).shallow_copy( );
                v.walk( incr );
                if( incr.is_constant( ) )
                {
                    return (const_value_cast_to_signed_int( lb.get_constant( ) ) 
                                  + ( const_value_cast_to_signed_int( incr.get_constant( ) ) 
                                      * _unroll_factor)) * _type_size;
                }
            }
        }

        return -1;
    }
示例#2
0
    void loop_hlt_handler_post(TL::PragmaCustomStatement construct)
    {
        TL::PragmaCustomLine pragma_line = construct.get_pragma_line();
        TL::PragmaCustomClause collapse = construct.get_pragma_line().get_clause("collapse");
        if (!collapse.is_defined())
            return;

        TL::ObjectList<Nodecl::NodeclBase> expr_list = collapse.get_arguments_as_expressions(construct);
        if (expr_list.size() != 1)
        {
            error_printf_at(construct.get_locus(), "'collapse' clause needs exactly one argument\n");
            return;
        }

        Nodecl::NodeclBase expr = expr_list[0];
        if (!expr.is_constant()
                || !is_any_int_type(expr.get_type().get_internal_type()))
        {
            error_printf_at(construct.get_locus(),
                    "'collapse' clause requires an integer constant expression\n");
            return;
        }

        int collapse_factor = const_value_cast_to_signed_int(expr.get_constant());

        if (collapse_factor <= 0)
        {
            error_printf_at(
                    construct.get_locus(),
                    "Non-positive factor (%d) is not allowed in the 'collapse' clause\n",
                    collapse_factor);
        }
        else if (collapse_factor == 1)
        {
            // Removing the collapse clause from the pragma
            pragma_line.remove_clause("collapse");
        }
        else if (collapse_factor > 1)
        {
            Nodecl::NodeclBase loop = get_statement_from_pragma(construct);

            HLT::LoopCollapse loop_collapse;
            loop_collapse.set_loop(loop);
            loop_collapse.set_pragma_context(construct.retrieve_context());
            loop_collapse.set_collapse_factor(collapse_factor);

            loop_collapse.collapse();

            Nodecl::NodeclBase transformed_code = loop_collapse.get_whole_transformation();
            TL::ObjectList<TL::Symbol> capture_symbols = loop_collapse.get_omp_capture_symbols();

            // We may need to add some symbols that are used to implement the collapse clause to the pragma
            std::string names;
            for (TL::ObjectList<TL::Symbol>::iterator it = capture_symbols.begin();
                    it != capture_symbols.end();
                    it++)
            {
                if (it != capture_symbols.begin())
                    names += ",";
                names += it->get_name();
            }
            Nodecl::List clauses = pragma_line.get_clauses().as<Nodecl::List>();
            clauses.append(Nodecl::PragmaCustomClause::make(Nodecl::List::make(Nodecl::PragmaClauseArg::make(names)), "firstprivate"));

            // Removing the collapse clause from the pragma
            pragma_line.remove_clause("collapse");

            // Create a new pragma over the new for stmt
            ERROR_CONDITION(!transformed_code.is<Nodecl::Context>(), "Unexpected node\n", 0);
            Nodecl::NodeclBase compound_statement =
                transformed_code.as<Nodecl::Context>().get_in_context().as<Nodecl::List>().front();

            ERROR_CONDITION(!compound_statement.is<Nodecl::CompoundStatement>(), "Unexpected node\n", 0);
            Nodecl::Context context_for_stmt =
                compound_statement.as<Nodecl::CompoundStatement>().get_statements()
                .as<Nodecl::List>().find_first<Nodecl::Context>();

            Nodecl::Utils::remove_from_enclosing_list(context_for_stmt);

            Nodecl::List stmt_list =
                compound_statement.as<Nodecl::CompoundStatement>().get_statements().as<Nodecl::List>();
            ERROR_CONDITION(stmt_list.is_null(), "Unreachable code\n", 0);

            Nodecl::PragmaCustomStatement new_pragma =
                Nodecl::PragmaCustomStatement::make(pragma_line,
                        Nodecl::List::make(context_for_stmt),
                        construct.get_text(),
                        construct.get_locus());

            stmt_list.append(new_pragma);

            construct.replace(transformed_code);
        }
    }
示例#3
0
 int SuitableAlignmentVisitor::visit( const Nodecl::IntegerLiteral& n )
 {
     return const_value_cast_to_signed_int( n.get_constant( )) * _type_size;
 }
示例#4
0
    int SuitableAlignmentVisitor::visit( const Nodecl::ArraySubscript& n ) 
    {
        if( _nesting_level == 0 )  // Target access
        {
            _nesting_level++;
            
            int i;
            int alignment = 0;
            
            Nodecl::NodeclBase subscripted = n.get_subscripted( );
            TL::Type element_type = subscripted.get_type( );
            // TODO: subscript is aligned
            
            Nodecl::List subscripts = n.get_subscripts( ).as<Nodecl::List>( );
            int num_subscripts = subscripts.size( );
            
            // Get dimension sizes
            int *dimension_sizes = (int *)malloc( ( num_subscripts-1 ) * sizeof( int ) );
            
            for( i = 0; i < (num_subscripts-1); i++ ) // Skip the first one. It does not have size
            {
                // Iterate on array subscript type
                if( element_type.is_array( ) )
                {
                    element_type = element_type.array_element( );
                }
                else if( element_type.is_pointer( ) )
                {
                    element_type = element_type.points_to( );
                }
                else
                {
                    WARNING_MESSAGE( "Array subscript does not have array type or pointer to array type", 0 );
                    return -1;
                }
                
                if( !element_type.array_has_size( ) )
                {
                    WARNING_MESSAGE( "Array type does not have size", 0 );
                    return -1;
                }
                
                // Compute dimension alignment 
                Nodecl::NodeclBase dimension_size_node = element_type.array_get_size( );

                // If VLA, get the actual size
                if(dimension_size_node.is<Nodecl::Symbol>() &&
                        dimension_size_node.get_symbol().is_saved_expression())
                {
                    dimension_size_node = dimension_size_node.get_symbol().get_value();
                }
               
                int dimension_size = -1;
                if( dimension_size_node.is_constant( ) )
                {
                    dimension_size = const_value_cast_to_signed_int( dimension_size_node.get_constant( ) );
                    
                    if( is_suitable_constant( dimension_size * _type_size ) )
                        dimension_size = 0;
                }
                // If dimension size is suitable
                else if( is_suitable_expression( dimension_size_node ) )
                {
                    dimension_size = 0;
                }
                if( VERBOSE )
                    printf( "Dim %d, size %d\n", i, dimension_size );
                
                dimension_sizes[i] = dimension_size;
            }
            
            int it_alignment;
            Nodecl::List::iterator it = subscripts.begin( );
            // Multiply dimension sizes by indexes
            for( i=0; it != subscripts.end( ); i++ )
            {
                it_alignment = walk( *it );
                
                it++;
                if( it == subscripts.end( ) ) break; // Last dimmension does not have to be multiplied
                
                // a[i][j][k] -> i -> i*J*K
                for( int j = i; j < (num_subscripts-1); j++ )
                {
                    if( ( dimension_sizes[j] == 0 ) || ( it_alignment == 0 ) )
                    {
                        it_alignment = 0;
                    }
                    else if( ( dimension_sizes[j] < 0 ) || ( it_alignment < 0 ) )
                    {
                        it_alignment = -1;
                    }
                    else
                    {
                        it_alignment *= dimension_sizes[j];
                    }
                }
                
                if( it_alignment < 0 )
                {
                    return -1;
                }
                
                alignment += it_alignment;
            }
            // Add adjacent dimension
            alignment += it_alignment;
            
            free(dimension_sizes);
            
            _nesting_level--;
            
            return alignment;
        }
        // Nested array subscript
        else
        {
            if (is_suitable_expression(n))
            {
                return 0;
            }
            
            return -1;
        }
    }