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; }
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(); }
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(); }
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); } } }
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); } }
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()); } }