Beispiel #1
0
    // We redefine the visitor of Nodecl::FunctionCode because  we need to
    // visit first the internal functions and later the statements
    void LoweringVisitor::visit(const Nodecl::FunctionCode& function_code)
    {
        Nodecl::List stmts = function_code.get_statements().as<Nodecl::List>();

        // First, traverse nested functions
        for (Nodecl::List::iterator it = stmts.begin();
                it != stmts.end();
                it++)
        {
            if (it->is<Nodecl::FunctionCode>())
            {
                walk(*it);
            }
        }
        // Second, remaining statements
        for (Nodecl::List::iterator it = stmts.begin();
                it != stmts.end();
                it++)
        {
            if (!it->is<Nodecl::FunctionCode>())
            {
                walk(*it);
            }
        }
    }
Beispiel #2
0
    bool NodeclStaticInfo::is_constant_access( const Nodecl::NodeclBase& n ) const
    {
        bool result = true;
        
        if( n.is<Nodecl::ArraySubscript>( ) )
        {
            Nodecl::ArraySubscript array = n.as<Nodecl::ArraySubscript>( );

            //Check subscripted
            if ( !is_constant( array.get_subscripted( ) ))
            {
                return false;
            }

            // Check subscrips
            Nodecl::List subscript = array.get_subscripts( ).as<Nodecl::List>( );
            Nodecl::List::iterator it = subscript.begin( );
            for( ; it != subscript.end( ); ++it )
            {   // All dimensions must be constant
                if( !is_constant( *it ) )
                {
                    result = false;
                    break;
                }
            }
        }
        
        return result;
    }
Beispiel #3
0
void AutoScopeVisitor::visit( const Nodecl::OpenMP::Task& n )
{
    // Retrieve the results of the Auto-Scoping process to the user
    _analysis_info->print_auto_scoping_results( n );

    // Modify the Nodecl with the new variables' scope
    Analysis::Utils::AutoScopedVariables autosc_vars = _analysis_info->get_auto_scoped_variables( n );
    Analysis::Utils::ext_sym_set private_ext_syms, firstprivate_ext_syms, race_ext_syms,
             shared_ext_syms, undef_ext_syms;
    Nodecl::NodeclBase user_private_vars, user_firstprivate_vars, user_shared_vars;

    // Get actual environment
    Nodecl::List environ = n.get_environment().as<Nodecl::List>();
    for( Nodecl::List::iterator it = environ.begin( ); it != environ.end( ); )
    {
        if( it->is<Nodecl::OpenMP::Auto>( ) )
        {
            it = environ.erase( it );
        }
        else
        {
            if( it->is<Nodecl::OpenMP::Private>( ) )
            {
                user_private_vars = it->as<Nodecl::OpenMP::Private>( );
            }
            if( it->is<Nodecl::OpenMP::Firstprivate>( ) )
            {
                user_firstprivate_vars = it->as<Nodecl::OpenMP::Firstprivate>( );
            }
            if( it->is<Nodecl::OpenMP::Shared>( ) )
            {
                user_shared_vars = it->as<Nodecl::OpenMP::Shared>( );
            }
            ++it;
        }
    }

    // Remove user-scoped variables from auto-scoped variables and reset environment
    private_ext_syms = autosc_vars.get_private_vars( );
    if( !private_ext_syms.empty( ) )
    {
        ObjectList<Nodecl::NodeclBase> autosc_private_vars;
        for( Analysis::Utils::ext_sym_set::iterator it = private_ext_syms.begin( ); it != private_ext_syms.end( ); ++it )
        {
            autosc_private_vars.insert( it->get_nodecl( ) );
        }
        ObjectList<Nodecl::NodeclBase> purged_autosc_private_vars;
        for( ObjectList<Nodecl::NodeclBase>::iterator it = autosc_private_vars.begin( );
                it != autosc_private_vars.end( ); ++it )
        {
            if( !Nodecl::Utils::nodecl_is_in_nodecl_list( *it, user_firstprivate_vars.as<Nodecl::List>( ) )
                    && !Nodecl::Utils::nodecl_is_in_nodecl_list( *it, user_private_vars.as<Nodecl::List>( ) )
                    && !Nodecl::Utils::nodecl_is_in_nodecl_list( *it, user_shared_vars.as<Nodecl::List>( ) ) )
            {
                purged_autosc_private_vars.insert( it->shallow_copy() );
            }
        }
        if( !purged_autosc_private_vars.empty( ) )
        {
            Nodecl::OpenMP::Private private_node =
                Nodecl::OpenMP::Private::make( Nodecl::List::make( purged_autosc_private_vars ),
                                               n.get_locus( ) );
            environ.append( private_node );
        }
    }

    firstprivate_ext_syms = autosc_vars.get_firstprivate_vars( );
    if( !firstprivate_ext_syms.empty( ) )
    {
        ObjectList<Nodecl::NodeclBase> autosc_firstprivate_vars;
        for( Analysis::Utils::ext_sym_set::iterator it = firstprivate_ext_syms.begin( ); it != firstprivate_ext_syms.end( ); ++it )
        {
            autosc_firstprivate_vars.insert( it->get_nodecl( ) );
        }
        ObjectList<Nodecl::NodeclBase> purged_autosc_firstprivate_vars;
        for( ObjectList<Nodecl::NodeclBase>::iterator it = autosc_firstprivate_vars.begin( );
                it != autosc_firstprivate_vars.end( ); ++it )
        {
            if( !Nodecl::Utils::nodecl_is_in_nodecl_list( *it, user_firstprivate_vars.as<Nodecl::List>( ) )
                    && !Nodecl::Utils::nodecl_is_in_nodecl_list( *it, user_private_vars.as<Nodecl::List>( ) )
                    && !Nodecl::Utils::nodecl_is_in_nodecl_list( *it, user_shared_vars.as<Nodecl::List>( ) ) )
            {
                purged_autosc_firstprivate_vars.insert( it->shallow_copy() );
            }
        }
        if( !purged_autosc_firstprivate_vars.empty( ) )
        {
            Nodecl::OpenMP::Firstprivate firstprivate_node =
                Nodecl::OpenMP::Firstprivate::make( Nodecl::List::make( purged_autosc_firstprivate_vars ),
                                                    n.get_locus( ) );
            environ.append( firstprivate_node );
        }
    }

    shared_ext_syms = autosc_vars.get_shared_vars( );
    if( !shared_ext_syms.empty( ) )
    {
        ObjectList<Nodecl::NodeclBase> autosc_shared_vars;
        for( Analysis::Utils::ext_sym_set::iterator it = shared_ext_syms.begin( ); it != shared_ext_syms.end( ); ++it )
        {
            autosc_shared_vars.insert( it->get_nodecl( ) );
        }
        ObjectList<Nodecl::NodeclBase> purged_autosc_shared_vars;
        for( ObjectList<Nodecl::NodeclBase>::iterator it = autosc_shared_vars.begin( );
                it != autosc_shared_vars.end( ); ++it )
        {
            if( !Nodecl::Utils::nodecl_is_in_nodecl_list( *it, user_firstprivate_vars.as<Nodecl::List>( ) )
                    && !Nodecl::Utils::nodecl_is_in_nodecl_list( *it, user_private_vars.as<Nodecl::List>( ) )
                    && !Nodecl::Utils::nodecl_is_in_nodecl_list( *it, user_shared_vars.as<Nodecl::List>( ) ) )
            {
                purged_autosc_shared_vars.insert( it->shallow_copy() );
            }
        }
        if( !purged_autosc_shared_vars.empty( ) )
        {
            Nodecl::OpenMP::Shared shared_node =
                Nodecl::OpenMP::Shared::make( Nodecl::List::make( purged_autosc_shared_vars ),
                                              n.get_locus( ) );
            environ.append( shared_node );
        }
    }
}
Beispiel #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;
        }
    }