Halide
CodeGen_Hexagon.h
Go to the documentation of this file.
1 #ifndef HALIDE_CODEGEN_HEXAGON_H
2 #define HALIDE_CODEGEN_HEXAGON_H
3 
4 /** \file
5  * Defines the code-generator for producing Hexagon machine code
6  */
7 
8 #include "CodeGen_Posix.h"
9 
10 namespace Halide {
11 namespace Internal {
12 
13 /** A code generator that emits Hexagon code from a given Halide stmt. */
15 public:
16  /** Create a Hexagon code generator for the given Hexagon target. */
18 
19 protected:
20  void compile_func(const LoweredFunc &f,
21  const std::string &simple_name, const std::string &extern_name) override;
22 
23  void init_module() override;
24 
25  std::string mcpu() const override;
26  std::string mattrs() const override;
28  bool use_soft_float_abi() const override;
29  int native_vector_bits() const override;
30 
31  llvm::Function *define_hvx_intrinsic(llvm::Function *intrin, Type ret_ty,
32  const std::string &name,
33  std::vector<Type> arg_types,
34  int flags);
35 
36  int is_hvx_v65_or_later() const {
37  return (isa_version >= 65);
38  }
39 
41 
42  /** Nodes for which we want to emit specific hexagon intrinsics */
43  ///@{
44  void visit(const Max *) override;
45  void visit(const Min *) override;
46  void visit(const Call *) override;
47  void visit(const Mul *) override;
48  void visit(const Select *) override;
49  void visit(const Allocate *) override;
50  ///@}
51 
52  /** We ask for an extra vector on each allocation to enable fast
53  * clamped ramp loads. */
54  int allocation_padding(Type type) const override {
56  }
57 
58  /** Call an LLVM intrinsic, potentially casting the operands to
59  * match the type of the function. */
60  ///@{
61  llvm::Value *call_intrin_cast(llvm::Type *ret_ty, llvm::Function *F,
62  std::vector<llvm::Value *> Ops);
63  llvm::Value *call_intrin_cast(llvm::Type *ret_ty, int id,
64  std::vector<llvm::Value *> Ops);
65  ///@}
66 
67  /** Define overloads of CodeGen_LLVM::call_intrin that determine
68  * the intrin_lanes from the type, and allows the function to
69  * return null if the maybe option is true and the intrinsic is
70  * not found. */
71  ///@{
73  llvm::Value *call_intrin(Type t, const std::string &name,
74  std::vector<Expr>, bool maybe = false);
75  llvm::Value *call_intrin(llvm::Type *t, const std::string &name,
76  std::vector<llvm::Value *>, bool maybe = false);
77  ///@}
78 
79  /** Override CodeGen_LLVM to use hexagon intrinics when possible. */
80  ///@{
81  llvm::Value *interleave_vectors(const std::vector<llvm::Value *> &v) override;
82  llvm::Value *shuffle_vectors(llvm::Value *a, llvm::Value *b,
83  const std::vector<int> &indices) override;
85  ///@}
86 
87  /** Generate a LUT lookup using vlut instructions. */
88  ///@{
89  llvm::Value *vlut(llvm::Value *lut, llvm::Value *indices, int min_index = 0, int max_index = 1 << 30);
90  llvm::Value *vlut(llvm::Value *lut, const std::vector<int> &indices);
91  ///@}
92 
93  llvm::Value *vdelta(llvm::Value *lut, const std::vector<int> &indices);
94 
95  /** Because HVX intrinsics operate on vectors of i32, using them
96  * requires a lot of extraneous bitcasts, which make it difficult
97  * to manipulate the IR. This function avoids generating redundant
98  * bitcasts. */
99  llvm::Value *create_bitcast(llvm::Value *v, llvm::Type *ty);
100 
101 private:
102  /** Generates code for computing the size of an allocation from a
103  * list of its extents and its size. Fires a runtime assert
104  * (halide_error) if the size overflows 2^31 -1, the maximum
105  * positive number an int32_t can hold. */
106  llvm::Value *codegen_cache_allocation_size(const std::string &name, Type type, const std::vector<Expr> &extents);
107 
108  /** Generate a LUT (8/16 bit, max_index < 256) lookup using vlut instructions. */
109  llvm::Value *vlut256(llvm::Value *lut, llvm::Value *indices, int min_index = 0, int max_index = 255);
110 };
111 
112 } // namespace Internal
113 } // namespace Halide
114 
115 #endif
Halide::Internal::Allocate
Allocate a scratch area called with the given name, type, and size.
Definition: IR.h:352
Halide::Internal::IRMatcher::intrin
HALIDE_ALWAYS_INLINE auto intrin(Call::IntrinsicOp intrinsic_op, Args... args) noexcept -> Intrin< decltype(pattern_arg(args))... >
Definition: IRMatch.h:1393
Halide::Internal::CodeGen_Hexagon::is_hvx_v65_or_later
int is_hvx_v65_or_later() const
Definition: CodeGen_Hexagon.h:36
Halide::Internal::CodeGen_LLVM::shuffle_vectors
virtual llvm::Value * shuffle_vectors(llvm::Value *a, llvm::Value *b, const std::vector< int > &indices)
Create an LLVM shuffle vectors instruction.
Halide::Internal::CodeGen_Posix
A code generator that emits posix code from a given Halide stmt.
Definition: CodeGen_Posix.h:14
Halide::Internal::CodeGen_Posix::visit
void visit(const Allocate *) override
Posix implementation of Allocate.
Halide::Internal::CodeGen_Hexagon::call_intrin_cast
llvm::Value * call_intrin_cast(llvm::Type *ret_ty, llvm::Function *F, std::vector< llvm::Value * > Ops)
Call an LLVM intrinsic, potentially casting the operands to match the type of the function.
Halide::Internal::CodeGen_Hexagon::isa_version
int isa_version
Definition: CodeGen_Hexagon.h:27
Halide::Internal::CodeGen_Hexagon::call_intrin
llvm::Value * call_intrin(Type t, const std::string &name, std::vector< Expr >, bool maybe=false)
Define overloads of CodeGen_LLVM::call_intrin that determine the intrin_lanes from the type,...
Halide::Internal::CodeGen_Hexagon
A code generator that emits Hexagon code from a given Halide stmt.
Definition: CodeGen_Hexagon.h:14
Halide::Type
Types in the halide type system.
Definition: Type.h:269
Halide
This file defines the class FunctionDAG, which is our representation of a Halide pipeline,...
Definition: AddAtomicMutex.h:21
Halide::LinkageType::Internal
@ Internal
Not visible externally, similar to 'static' linkage in C.
Halide::Internal::Max
The greater of two values.
Definition: IR.h:94
Halide::Internal::CodeGen_Hexagon::mcpu
std::string mcpu() const override
What should be passed as -mcpu, -mattrs, and related for compilation.
Halide::Internal::CodeGen_Hexagon::mattrs
std::string mattrs() const override
Halide::Internal::CodeGen_Hexagon::visit
void visit(const Max *) override
Nodes for which we want to emit specific hexagon intrinsics.
Halide::Internal::CodeGen_Hexagon::use_soft_float_abi
bool use_soft_float_abi() const override
Halide::Internal::CodeGen_Hexagon::native_vector_bits
int native_vector_bits() const override
What's the natural vector bit-width to use for loads, stores, etc.
Halide::Internal::CodeGen_Hexagon::create_bitcast
llvm::Value * create_bitcast(llvm::Value *v, llvm::Type *ty)
Because HVX intrinsics operate on vectors of i32, using them requires a lot of extraneous bitcasts,...
Halide::Internal::CodeGen_Hexagon::allocation_padding
int allocation_padding(Type type) const override
We ask for an extra vector on each allocation to enable fast clamped ramp loads.
Definition: CodeGen_Hexagon.h:54
Halide::Internal::LoweredFunc
Definition of a lowered function.
Definition: Module.h:97
Halide::Internal::Min
The lesser of two values.
Definition: IR.h:85
Halide::Internal::CodeGen_LLVM::call_intrin
llvm::Value * call_intrin(const Type &t, int intrin_lanes, const std::string &name, std::vector< Expr >)
Generate a call to a vector intrinsic or runtime inlined function.
Halide::Internal::Call
A function call.
Definition: IR.h:464
Halide::Internal::CodeGen_Hexagon::vdelta
llvm::Value * vdelta(llvm::Value *lut, const std::vector< int > &indices)
Halide::Internal::CodeGen_Hexagon::interleave_vectors
llvm::Value * interleave_vectors(const std::vector< llvm::Value * > &v) override
Override CodeGen_LLVM to use hexagon intrinics when possible.
Halide::Internal::Select
A ternary operator.
Definition: IR.h:186
Halide::Internal::CodeGen_Hexagon::init_module
void init_module() override
Initialize the CodeGen_LLVM internal state to compile a fresh module.
Halide::Internal::CodeGen_Hexagon::define_hvx_intrinsic
llvm::Function * define_hvx_intrinsic(llvm::Function *intrin, Type ret_ty, const std::string &name, std::vector< Type > arg_types, int flags)
Halide::Internal::CodeGen_Hexagon::shuffle_vectors
llvm::Value * shuffle_vectors(llvm::Value *a, llvm::Value *b, const std::vector< int > &indices) override
Override CodeGen_LLVM to use hexagon intrinics when possible.
Halide::Internal::CodeGen_Posix::allocation_padding
virtual int allocation_padding(Type type) const
It can be convenient for backends to assume there is extra padding beyond the end of a buffer to enab...
Halide::Internal::CodeGen_Hexagon::CodeGen_Hexagon
CodeGen_Hexagon(Target)
Create a Hexagon code generator for the given Hexagon target.
Halide::Target
A struct representing a target machine and os to generate code for.
Definition: Target.h:19
CodeGen_Posix.h
Halide::Internal::CodeGen_Hexagon::compile_func
void compile_func(const LoweredFunc &f, const std::string &simple_name, const std::string &extern_name) override
Compile a specific halide declaration into the llvm Module.
Halide::Internal::CodeGen_Hexagon::vlut
llvm::Value * vlut(llvm::Value *lut, llvm::Value *indices, int min_index=0, int max_index=1<< 30)
Generate a LUT lookup using vlut instructions.
Halide::Internal::Mul
The product of two expressions.
Definition: IR.h:56