Exemplo n.º 1
0
    void KNCModuleVisitor::visit(const Nodecl::VectorBitwiseXor& node) 
    { 
        TL::Type type = node.get_type().basic_type();

        // Intrinsic name
        file << "_mm512_xor";
        
        // Postfix
        if (type.is_float()) 
        { 
            file << "_ps"; 
        } 
        else if (type.is_integral_type())
        { 
            file << "_si128"; 
        }
        else
        {
            running_error("KNC Codegen: Node %s at %s has an unsupported type.", 
                    ast_print_node_type(node.get_kind()),
                    node.get_locus_str().c_str());
        }      

        file << "("; 
        walk(node.get_lhs());
        file << ", ";
        walk(node.get_rhs());
        file << ")"; 
    }   
Exemplo n.º 2
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;
 }
Exemplo n.º 3
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();
        }
Exemplo n.º 4
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(); 
        }
Exemplo n.º 5
0
    // XXX - Fixme, implement it using ast_list_concat
    void AST_t::prepend_list(AST orig_list, AST prepended_list)
    {
        if (ASTType(orig_list) != AST_NODE_LIST
                || ASTType(prepended_list) != AST_NODE_LIST)
        {
            std::cerr << "You tried to prepend two lists that are not " 
                << "orig_list=" << ast_print_node_type(ASTType(orig_list)) << " "
                << "prepend_list=" << ast_print_node_type(ASTType(prepended_list)) << std::endl;
            return;
        }

        // Relink the parent, first remove pointer to the prepended_list
        if (ASTParent(prepended_list) != NULL)
        {
            AST parent = ASTParent(prepended_list);
            for (int i = 0; i < ASTNumChildren(parent); i++)
            {
                if (ASTChild(parent, i) == prepended_list)
                {
                    ast_set_child(parent, i, NULL);
                    break;
                }
            }
        }

        // Now make the prepended_list as the son
        AST original_previous = ASTSon0(orig_list);

        ast_set_child(orig_list, 0, prepended_list);

        // Go to the deeper node of prepended_list
        AST iter = prepended_list;
        while (ASTSon0(iter) != NULL)
        {
            iter = ASTSon0(iter);
        }

        ast_set_child(iter, 0, original_previous);
    }
    LoopNormalize& LoopNormalize::set_loop(Nodecl::NodeclBase loop)
    {
        this->_loop = loop;
        ERROR_CONDITION (!this->_loop.is<Nodecl::ForStatement>(),
                "Only ForStatement can be unrolled. This is a %s",
                ast_print_node_type(loop.get_kind()));
        Nodecl::NodeclBase loop_control = this->_loop.as<Nodecl::ForStatement>().get_loop_header();
        ERROR_CONDITION(!loop_control.is<Nodecl::LoopControl>()
                && !loop_control.is<Nodecl::RangeLoopControl>(),
                "Only LoopControl or RangeLoopControl can be unrolled", 0);
        TL::ForStatement for_stmt(loop.as<Nodecl::ForStatement>());
        ERROR_CONDITION(!for_stmt.is_omp_valid_loop(), "Loop is too complicated", 0);

        return *this;
    }
Exemplo n.º 7
0
    void KNCModuleVisitor::visit(const Nodecl::VectorMinus& node) 
    { 
        TL::Type type = node.get_type().basic_type();

        // Intrinsic name
        file << "_mm512_sub";
        
        // Postfix
        if (type.is_float()) 
        { 
            file << "_ps"; 
        } 
        else if (type.is_double()) 
        { 
            file << "_pd"; 
        } 
        else if (type.is_signed_int() ||
            type.is_unsigned_int()) 
        { 
            file << "_epi32"; 
        } 
        else if (type.is_signed_short_int() ||
            type.is_unsigned_short_int()) 
        { 
            file << "_epi16"; 
        } 
        else if (type.is_char() || 
            type.is_signed_char() ||
            type.is_unsigned_char()) 
        { 
            file << "_epi8"; 
        } 
        else
        {
            running_error("KNC Codegen: Node %s at %s has an unsupported type.", 
                    ast_print_node_type(node.get_kind()),
                    node.get_locus_str().c_str());
        }      

        file << "("; 
        walk(node.get_lhs());
        file << ", ";
        walk(node.get_rhs());
        file << ")"; 
    }                                                 
Exemplo n.º 8
0
 void ExtensibleGraph::propagate_arguments_in_function_graph( Nodecl::NodeclBase arguments )
 {
     ERROR_CONDITION( _nodecl.is_null( ), "Found a null nodecl for a graph that is supposed to contain a FunctionCode", 0 );
     ERROR_CONDITION( !_nodecl.is<Nodecl::FunctionCode>( ), "Expected FunctionCode but '%s' found", 
                      ast_print_node_type( _nodecl.get_kind( ) ) );
     Symbol func_sym( _nodecl.get_symbol( ) );
     ERROR_CONDITION( !func_sym.is_valid( ), "Invalid symbol for a nodecl that is supposed to contain a FunctionCode", 0 );
     
     Nodecl::List args = arguments.as<Nodecl::List>( );
     ObjectList<Symbol> params = func_sym.get_function_parameters( );
     int n_common_params = std::max( args.size( ), params.size( ) );
     
     sym_to_nodecl_map rename_map;
     for( int i = 0; i < n_common_params; ++i )
     {
         rename_map[params[i]] = args[i];
     }
     RenameVisitor rv( rename_map );
     Node* graph_entry = _graph->get_graph_entry_node( );
     propagate_argument_rec( graph_entry, &rv );
     ExtensibleGraph::clear_visits( graph_entry );
 }
Exemplo n.º 9
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);
            }
        }
Exemplo n.º 11
0
static void ast_dump_graphviz_rec(AST a, FILE* f, int parent_node, int position)
{
    // static char* octagon = "octagon";
    // static char* doubleoctagon = "doubleoctagon";
    static char* ellipse = "ellipse";
    static char* mdiamond = "Mdiamond";
    static char* box = "box";
    char* shape;

    int node_actual = nodes_counter++;
    if (a != NULL)
    {
        // Select shape
        shape = box;
        if (ASTType(a) == AST_AMBIGUITY) shape = ellipse;
        if (ASTType(a) == AST_NODE_LIST) shape = mdiamond;
        // if (a->construct_type == CT_SPECIFICATION) shape = ellipse;
        // else if (a->construct_type == CT_OMP_SPECIFICATION) shape = mdiamond;
        // else if (a->construct_type == CT_EXECUTABLE) shape = octagon;
        // else if (a->construct_type == CT_OMP_EXECUTABLE) shape = doubleoctagon;

        if (ASTText(a))
        {
            fprintf(f, "n%d[shape=%s,label=\"%s\\nNode=%p\\nParent=%p\\n%s\\nText: -%s-\"]\n", 
                    node_actual, shape, ast_print_node_type(ASTType(a)), a, ASTParent(a), ast_location(a), ASTText(a));
        }
        else
        {
            fprintf(f, "n%d[shape=%s,label=\"%s\\nNode=%p\\nParent=%p\\n%s\"]\n", 
                    node_actual, shape, ast_print_node_type(ASTType(a)), a, ASTParent(a), ast_location(a));
        }

        if (parent_node != 0)
        {
            fprintf(f, "n%d -> n%d [label=\"%d\"]\n", parent_node, node_actual, position);
        }


        if (ASTType(a) != AST_AMBIGUITY)
        {
            int i;
            for(i = 0; i < ASTNumChildren(a); i++)
            {
                ast_dump_graphviz_rec(ASTChild(a, i),f,  node_actual, i);
            }
        }
        else if (ASTType(a) == AST_AMBIGUITY)
        {
            int i;
            for(i = 0; i < ast_get_num_ambiguities(a); i++)
            {
                ast_dump_graphviz_rec(ast_get_ambiguity(a, i), f, node_actual, i);
            }
        }
    }
    else
    {
        fprintf(f, "n%d[shape=circle,label=\"\",fixedsize=true,style=filled,fillcolor=black,height=0.1,width=0.1]\n", node_actual);
        if (parent_node != 0)
        {
            fprintf(f, "n%d -> n%d [label=\"%d\"]\n", parent_node, node_actual, position);
        }
    }
}
Exemplo n.º 12
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());
     }
 }
Exemplo n.º 13
0
static void ast_dump_graphviz_rec(AST a, FILE* f, size_t parent_node, int position, char is_extended UNUSED_PARAMETER)
{
    // static char* octagon = "octagon";
    // static char* doubleoctagon = "doubleoctagon";
    static char* ellipse = "ellipse";
    static char* mdiamond = "Mdiamond";
    static char* box = "box";
    char* shape;

    // I know this is not exact, but there is a %z qualifier in printf
    // while there is not such thing for intptr_t
    size_t current_node = (size_t)a;

    if (a != NULL)
    {
        // Select shape
        shape = box;
        if (ASTType(a) == AST_AMBIGUITY) shape = ellipse;
        if (ASTType(a) == AST_NODE_LIST) shape = mdiamond;
        // if (a->construct_type == CT_SPECIFICATION) shape = ellipse;
        // else if (a->construct_type == CT_OMP_SPECIFICATION) shape = mdiamond;
        // else if (a->construct_type == CT_EXECUTABLE) shape = octagon;
        // else if (a->construct_type == CT_OMP_EXECUTABLE) shape = doubleoctagon;

        if (ASTText(a))
        {
            char *quoted = quote_protect(ASTText(a));

            fprintf(f, "n%zd[shape=%s,label=\"%s\\nNode=%p\\nParent=%p\\n%s\\nText: \\\"%s\\\"\"]\n", 
                    current_node, shape, ast_print_node_type(ASTType(a)), a, ASTParent(a), ast_location(a), quoted);

            free(quoted);
        }
        else
        {
            fprintf(f, "n%zd[shape=%s,label=\"%s\\nNode=%p\\nParent=%p\\n%s\"]\n", 
                    current_node, shape, ast_print_node_type(ASTType(a)), a, ASTParent(a), ast_location(a));
        }

        // Print this only for non extended referenced nodes
        if (parent_node != 0)
        {
            fprintf(f, "n%zd -> n%zd [label=\"%d\"]\n", parent_node, current_node, position);
        }

        if (ASTType(a) != AST_AMBIGUITY)
        {
            int i;
            if (!is_extended)
            {
                for(i = 0; i < ASTNumChildren(a); i++)
                {
                    if (ASTChild(a, i) != NULL)
                    {
                        ast_dump_graphviz_rec(ASTChild(a, i), f, current_node, i, /* is_extended */ is_extended);
                    }
                }
            }

            // Now print all extended trees referenced here
            // First get all TL_AST in 'orig' that point to its childrens

            extensible_struct_t* extended_data = ast_get_extensible_struct(a);

            if (extended_data != NULL
                    && !is_extended)
            {
                int num_fields = 0;
                const char** keys = NULL;
                const void** values = NULL;

                extensible_struct_get_all_data(extended_data, &num_fields, &keys, &values);

                for (i = 0; i < num_fields; i++)
                {
                    const char* field_name = keys[i];
                    tl_type_t* tl_data = (tl_type_t*)values[i];
                    if (tl_data->kind == TL_AST)
                    {
                        if (tl_data->data._ast != a)
                        {
                            ast_dump_graphviz_rec(tl_data->data._ast, f, /* parent_node */ 0, /* position */ 0, /* is_extended */ 1);
                        }

                        // Add an edge
                        fprintf(f, "n%zd -> n%zd [label=\"%s\",style=dashed]\n",
                                current_node,
                                (size_t)(tl_data->data._ast),
                                field_name);
                    }
                }
            }
        }
        else if (ASTType(a) == AST_AMBIGUITY)
        {
            int i;
            for(i = 0; i < ast_get_num_ambiguities(a); i++)
            {
                ast_dump_graphviz_rec(ast_get_ambiguity(a, i), f, current_node, i, /* is_extended */ 0);
            }
        }
    }
    else
    {
        fprintf(f, "n%zd[shape=circle,label=\"\",fixedsize=true,style=filled,fillcolor=black,height=0.1,width=0.1]\n", current_node);
        if (parent_node != 0)
        {
            fprintf(f, "n%zd -> n%zd [label=\"%d\"]\n", parent_node, current_node, position);
        }
    }
}