예제 #1
0
 bool ArrayAccessInfoVisitor::unhandled_node( const Nodecl::NodeclBase& n )
 {
     std::cerr << "Unhandled node while parsing Array Subscript '"
               << codegen_to_str( n.get_internal_nodecl( ),
                                 nodecl_retrieve_context( n.get_internal_nodecl( ) ) )
               << "' of type '" << ast_print_node_type( n.get_kind( ) ) << "'" << std::endl;
     return false;
 }
예제 #2
0
        Nodecl::NodeclVisitor<void>::Ret NeonVectorBackend::unhandled_node(const Nodecl::NodeclBase& n)
        {
            internal_error("NEON Backend: Unknown node %s at %s.",
                    ast_print_node_type(n.get_kind()),
                    locus_to_str(n.get_locus()));

            return Ret();
        }
예제 #3
0
        Nodecl::NodeclVisitor<void>::Ret VectorizerVisitorFunction::unhandled_node(const Nodecl::NodeclBase& n) 
        { 
            std::cerr << "Function Visitor: Unknown node " 
                << ast_print_node_type(n.get_kind()) 
                << " at " << n.get_locus() 
                << std::endl;

            return Ret(); 
        }
예제 #4
0
void DeviceFPGA::add_hls_pragmas(
        Nodecl::NodeclBase &task,
        TL::ObjectList<OutlineDataItem*> &data_items
        )
{
    /*
     * Insert hls pragmas in order to denerate input/output connections
     * Every parameter needs a directive:
     * scalar: create plain wire connections:
     *      #pragma HLS INTERFACE ap_none port=VAR
     *      #pragma AP resource core=AXI_SLAVE variable=VAR metadata="-bus_bundle AXIlite"
     *
     * Array; create fifo port to be handled by axi stream
     *      #pragma HLS stream variable=VAR <-- NOT NEEDED
     *      #pragma HLS resource core=AXI4Stream variable=VAR
     *      #pragma HLS interface ap_fifo port=VAR
     *
     * For every task there is a control bus defined to kick the accelerator off:
     *
     * #pragma AP resource core=AXI_SLAVE variable=return metadata="-bus_bundle AXIlite" \
     *      port_map={{ap_start START} {ap_done DONE} {ap_idle IDLE} {ap_return RETURN}}
     *
     * All of this stuff must be inside the function body i.e.
     *
     * void foo(...)
     * {
     *     pragma stuff
     *     function body
     * }
     *
     */

    //see what kind of ast it really is

    std::cerr << ast_node_type_name(task.get_kind()) 
        << " in_list: " << task.is_in_list()
        << " locus: " << task.get_locus()
        << std::endl;

    //Dig into the tree and find where the function statements are
    ObjectList<Nodecl::NodeclBase> tchildren = task.children();
    Nodecl::NodeclBase& context = tchildren.front();
    ObjectList<Nodecl::NodeclBase> cchildren = context.children();
    Nodecl::List list(cchildren.front().get_internal_nodecl());
    Nodecl::List stlist(list.begin()->children().front().get_internal_nodecl());

    Nodecl::UnknownPragma ctrl_bus = Nodecl::UnknownPragma::make(
        "AP resource core=AXI_SLAVE variable=return metadata=\"-bus_bundle AXIlite\" port_map={{ap_start START} {ap_done DONE} {ap_idle IDLE} {ap_return RETURN}}");
    stlist.prepend(ctrl_bus);


    //since we are using prepend, everything is going to appar in reverse order
    //but this may not be a real issue
//    TL::ObjectList<OutlineDataItem*> data_items = outline_info.get_data_items();
    for (TL::ObjectList<OutlineDataItem*>::iterator it = data_items.begin();
            it != data_items.end();
            it++)
    {
        std::string field_name = (*it)->get_field_name();
        Nodecl::UnknownPragma pragma_node;

        if ((*it)->get_copies().empty())
        {
            //set scalar argumenit pragmas
            pragma_node = Nodecl::UnknownPragma::make("HLS INTERFACE ap_none port=" + field_name);
            stlist.prepend(pragma_node);

            pragma_node = Nodecl::UnknownPragma::make("AP resource core=AXI_SLAVE variable="
                    + field_name
                    + " metadata=\"-bus_bundle AXIlite\"");
            stlist.prepend(pragma_node);
        }
        else
        {
            //set array/stream pragmas
            pragma_node = Nodecl::UnknownPragma::make(
                    "HLS resource core=AXI4Stream variable=" + field_name);
            stlist.prepend(pragma_node);
            pragma_node = Nodecl::UnknownPragma::make(
                    "HLS interface ap_fifo port=" + field_name);
            stlist.prepend(pragma_node);
            
        }
    }
}
예제 #5
0
 int SuitableAlignmentVisitor::unhandled_node(const Nodecl::NodeclBase& n) 
 {
     WARNING_MESSAGE( "Suitable Alignment Visitor: Unknown node '%s' at '%s'\n", 
                      ast_print_node_type( n.get_kind( ) ), n.get_locus_str( ).c_str( ) );
     return -1;
 }
        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);
            }
        }
예제 #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());
     }
 }