Revision 2c48ba87ac173341f641479cb711f6f755d48e93 authored by Volodymyr Kysenko on 08 December 2023, 21:58:37 UTC, committed by Volodymyr Kysenko on 08 December 2023, 21:58:37 UTC
1 parent d84e3a6
CodeGen_Xtensa.h
#ifndef HALIDE_CODEGEN_XTENSA_H
#define HALIDE_CODEGEN_XTENSA_H
/** \file
* Defines the code-generator for producing Xtensa code
*/
#include <set>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include "CodeGen_C.h"
namespace Halide {
namespace Internal {
class CodeGen_Xtensa : public CodeGen_C {
public:
CodeGen_Xtensa(std::ostream &dest,
const Target &target,
OutputKind output_kind = CImplementation,
const std::string &include_guard = "");
protected:
Stmt preprocess_function_body(const Stmt &stmt) override;
using CodeGen_C::visit;
std::string print_type(Type t, CodeGen_C::AppendSpaceIfNeeded space_option = DoNotAppendSpace) override;
std::string print_xtensa_call(const Call *op);
void add_platform_prologue() override;
void add_vector_typedefs(const std::set<Type> &vector_types) override;
void visit(const Mul *) override;
void visit(const Div *) override;
void visit(const Mod *) override;
void visit(const Allocate *) override;
void visit(const For *) override;
void visit(const Ramp *op) override;
void visit(const Broadcast *op) override;
void visit(const Call *op) override;
void visit(const Cast *op) override;
void visit(const Load *op) override;
void visit(const EQ *op) override;
void visit(const LE *op) override;
void visit(const LT *op) override;
void visit(const GE *op) override;
void visit(const GT *op) override;
void visit(const Or *op) override;
void visit(const And *op) override;
void visit(const Not *op) override;
void visit(const Reinterpret *op) override;
void visit(const Store *op) override;
void visit(const Select *op) override;
void visit(const Shuffle *op) override;
void visit(const Min *op) override;
void visit(const Max *op) override;
void visit(const IntImm *op) override;
void visit(const Let *op) override;
void visit(const LetStmt *op) override;
template<typename ComparisonOp>
void visit_comparison_op(const ComparisonOp *op, const std::string &op_name);
bool is_stack_private_to_thread() const override;
void emit_halide_free_helper(const std::string &alloc_name, const std::string &free_function) override;
int current_loop_level = 0;
std::vector<std::string> global_static_allocations;
// TODO: this appears to be unused; we read from it but never write to it?
std::set<std::string> external_buffers;
template<typename T>
bool is_native_xtensa_vector(halide_type_t op_type) const;
halide_type_t get_native_xtensa_vector(const halide_type_t &t) const;
bool is_native_vector_type(const halide_type_t &t) const {
return t == get_native_xtensa_vector(t);
}
bool is_double_native_vector_type(const halide_type_t &t) const {
const halide_type_t native_vector_type = get_native_xtensa_vector(t);
return t == native_vector_type.with_lanes(2 * native_vector_type.lanes);
}
const std::unordered_map<std::string, std::string> op_name_to_intrinsic;
};
// The C++ standard does not allow explicit specialization of a member of a class at class scope;
// Clang will let you get away with it, but GCC and MSVC won't.
template<typename T>
inline bool CodeGen_Xtensa::is_native_xtensa_vector(halide_type_t op_type) const {
constexpr halide_type_t cpp_type = halide_type_of<T>();
return op_type == cpp_type.with_lanes(target.natural_vector_size<T>());
}
template<>
inline bool CodeGen_Xtensa::is_native_xtensa_vector<int64_t>(halide_type_t op_type) const {
constexpr halide_type_t cpp_type = halide_type_of<int64_t>();
// On Xtensa int64 vectors are *wide* vectors, so the number of lanes match
// the number of lanes for 32-bit vectors.
return op_type == cpp_type.with_lanes(target.natural_vector_size<int32_t>());
}
} // namespace Internal
} // namespace Halide
#endif
Computing file changes ...