Beispiel #1
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 #2
0
 bool ArrayAccessInfoVisitor::visit( const Nodecl::ArraySubscript& n )
 {
     // Collect information about the induction variables contained in the node
     bool n_is_iv = variable_is_iv( n );
     walk( n.get_subscripted( ) );
     walk( n.get_subscripts( ) );
    
     _is_adjacent_access = ( n_is_iv && _ivs.back( )->is_increment_one( ) );
    
     return !Utils::ext_sym_set_contains_nodecl( n, _killed );
 }
Beispiel #3
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;
        }
    }
        void VectorizerVisitorExpression::visit(const Nodecl::ArraySubscript& n)
        {
            // Computing new vector type
            TL::Type vector_type = n.get_type();
            if (vector_type.is_lvalue_reference())
            {
                vector_type = vector_type.references_to();
            }
            vector_type = get_qualified_vector_to(vector_type, _vector_length);

            TL::Type basic_type = n.get_type();
            if (basic_type.is_lvalue_reference())
            {
                basic_type = basic_type.references_to();
            }

            // Vector Load
            if (Vectorizer::_analysis_info->is_adjacent_access(
                        Vectorizer::_analysis_scopes->back(),
                        n))
            {
                const Nodecl::VectorLoad vector_load =
                    Nodecl::VectorLoad::make(
                            Nodecl::Reference::make(
                                Nodecl::ParenthesizedExpression::make(
                                    n.shallow_copy(),
                                    basic_type,
                                    n.get_locus()),
                                basic_type.get_pointer_to(),
                                n.get_locus()),
                            vector_type,
                            n.get_locus());

                n.replace(vector_load);
            }
            else // Vector Gather
            {
                const Nodecl::NodeclBase base = n.get_subscripted();
                const Nodecl::List subscripts = n.get_subscripts().as<Nodecl::List>();

                ERROR_CONDITION(subscripts.size() > 1,
                    "Vectorizer: Gather on multidimensional array is not supported yet!", 0);

                std::cerr << "Gather: " << n.prettyprint() << "\n";

                Nodecl::NodeclBase strides = *subscripts.begin();
                walk(strides);

                const Nodecl::VectorGather vector_gather =
                    Nodecl::VectorGather::make(
                            base.shallow_copy(),
                            strides,
                            vector_type,
                            n.get_locus());

                n.replace(vector_gather);
            }
        }
        void VectorizerVisitorExpression::visit(const Nodecl::Assignment& n)
        {
            Nodecl::NodeclBase lhs = n.get_lhs();
            walk(n.get_rhs());

            // Computing new vector type
            TL::Type vector_type = n.get_type();
            /*
            if (vector_type.is_lvalue_reference())
            {
                vector_type = vector_type.references_to();
            }
            */
            vector_type = get_qualified_vector_to(vector_type, _vector_length);

            if(lhs.is<Nodecl::ArraySubscript>())
            {
                // Vector Store
                if(Vectorizer::_analysis_info->is_adjacent_access(
                            Vectorizer::_analysis_scopes->back(),
                            lhs))
                {
                    TL::Type basic_type = lhs.get_type();
                    if (basic_type.is_lvalue_reference())
                    {
                        basic_type = basic_type.references_to();
                    }

                    const Nodecl::VectorStore vector_store =
                        Nodecl::VectorStore::make(
                                Nodecl::Reference::make(
                                    Nodecl::ParenthesizedExpression::make(
                                        lhs.shallow_copy(),
                                        basic_type,
                                        n.get_locus()),
                                    basic_type.get_pointer_to(),
                                    n.get_locus()),
                                n.get_rhs().shallow_copy(),
                                vector_type,
                                n.get_locus());

                    n.replace(vector_store);
                }
                else // Vector Scatter
                {
                    const Nodecl::ArraySubscript lhs_array = lhs.as<Nodecl::ArraySubscript>();

                    const Nodecl::NodeclBase base = lhs_array.get_subscripted();
                    const Nodecl::List subscripts = lhs_array.get_subscripts().as<Nodecl::List>();

                    std::cerr << "Scatter: " << lhs_array.prettyprint() << "\n";

                    ERROR_CONDITION(subscripts.size() > 1,
                            "Vectorizer: Scatter on multidimensional array is not supported yet!", 0);

                    Nodecl::NodeclBase strides = *subscripts.begin();
                    walk(strides);

                    const Nodecl::VectorScatter vector_scatter =
                        Nodecl::VectorScatter::make(
                                base.shallow_copy(),
                                strides,
                                n.get_rhs().shallow_copy(),
                                vector_type,
                                n.get_locus());

                    n.replace(vector_scatter);
                }
            }
            else // Register
            {
                walk(lhs);

                const Nodecl::VectorAssignment vector_assignment =
                    Nodecl::VectorAssignment::make(
                            lhs.shallow_copy(),
                            n.get_rhs().shallow_copy(),
                            vector_type,
                            n.get_locus());

                n.replace(vector_assignment);
            }
        }
Beispiel #6
0
 void visit_pre(const Nodecl::ArraySubscript &node)
 {
     _extra_data_sharing.walk(node.get_subscripts());
 }
Beispiel #7
0
 ObjectList<Nodecl::NodeclBase> ExtendedSymbol::get_nodecls_base( const Nodecl::NodeclBase& n )
 {
     if (n.is<Nodecl::Symbol>() || n.is<Nodecl::PointerToMember>() || n.is<Nodecl::ObjectInit>() || n.is<Nodecl::FunctionCall>())
     {
         return ObjectList<Nodecl::NodeclBase>(1, n);
     }
     else if (n.is<Nodecl::IntegerLiteral>() || n.is<Nodecl::FloatingLiteral>() || n.is<Nodecl::ComplexLiteral>()
             || n.is<Nodecl::StringLiteral>() || n.is<Nodecl::BooleanLiteral>())
     {
         return ObjectList<Nodecl::NodeclBase>();
     }
     else if (n.is<Nodecl::ClassMemberAccess>())
     {
         Nodecl::ClassMemberAccess aux = n.as<Nodecl::ClassMemberAccess>();
         return get_nodecls_base(aux.get_lhs());
     }
     else if (n.is<Nodecl::ArraySubscript>())
     {
         Nodecl::ArraySubscript aux = n.as<Nodecl::ArraySubscript>();
         return get_nodecls_base(aux.get_subscripted());
     }
     else if (n.is<Nodecl::Reference>())
     {
         Nodecl::Reference aux = n.as<Nodecl::Reference>();
         return get_nodecls_base(aux.get_rhs());
     }
     else if (n.is<Nodecl::Dereference>())
     {
         Nodecl::Dereference aux = n.as<Nodecl::Dereference>();
         return get_nodecls_base(aux.get_rhs());
     }
     else if (n.is<Nodecl::Conversion>())
     {
         Nodecl::Conversion aux = n.as<Nodecl::Conversion>();
         return get_nodecls_base(aux.get_nest());
     }
     else if (n.is<Nodecl::Cast>())
     {
         Nodecl::Cast aux = n.as<Nodecl::Cast>();
         return get_nodecls_base(aux.get_rhs());
     }
     /*!
     * We can have (pre- post-) in- de-crements and other arithmetic operations
     * Example:
     * T *curr_high = ...;
     * *curr_high-- = l;
     * "*curr_high--" is a _KILLED_VAR
     */
     else if (n.is<Nodecl::Predecrement>())
     {
         Nodecl::Predecrement aux = n.as<Nodecl::Predecrement>();
         return get_nodecls_base(aux.get_rhs());
     }
     else if (n.is<Nodecl::Postdecrement>())
     {
         Nodecl::Postdecrement aux = n.as<Nodecl::Postdecrement>();
         return get_nodecls_base(aux.get_rhs());
     }
     else if (n.is<Nodecl::Preincrement>())
     {
         Nodecl::Preincrement aux = n.as<Nodecl::Preincrement>();
         return get_nodecls_base(aux.get_rhs());
     }
     else if (n.is<Nodecl::Postincrement>())
     {
         Nodecl::Postincrement aux = n.as<Nodecl::Postincrement>();
         return get_nodecls_base(aux.get_rhs());
     }
     else if (n.is<Nodecl::Add>())
     {
         Nodecl::Add aux = n.as<Nodecl::Add>();
         ObjectList<Nodecl::NodeclBase> rhs = get_nodecls_base(aux.get_rhs());
         ObjectList<Nodecl::NodeclBase> lhs = get_nodecls_base(aux.get_lhs());
         return rhs.append(lhs);
     }
     else
     {
         internal_error("Unexpected type of nodecl '%s' contained in an ExtendedSymbol '%s'",
                     ast_print_node_type(n.get_kind()), n.prettyprint().c_str());
     }
 }