VapourSynth-llvmexpr
Loading...
Searching...
No Matches
IRGeneratorBase.hpp
Go to the documentation of this file.
1
19
20#ifndef LLVMEXPR_IRGENERATORBASE_HPP
21#define LLVMEXPR_IRGENERATORBASE_HPP
22
25#include "Math.hpp"
26
27#include <map>
28#include <string>
29#include <vector>
30
31#include "VapourSynth4.h"
32#include "llvm/IR/IRBuilder.h"
33#include "llvm/IR/Intrinsics.h"
34#include "llvm/IR/LLVMContext.h"
35#include "llvm/IR/MDBuilder.h"
36#include "llvm/IR/Module.h"
37
39 public:
41 const std::vector<Token>& tokens_in, const VSVideoInfo* out_vi,
42 const std::vector<const VSVideoInfo*>& in_vi, int width_in,
43 int height_in, bool mirror,
44 const std::map<std::pair<int, std::string>, int>& p_map,
45 const analysis::ExpressionAnalysisResults& analysis_results_in,
46 llvm::LLVMContext& context_ref, llvm::Module& module_ref,
47 llvm::IRBuilder<>& builder_ref, MathLibraryManager& math_mgr,
48 std::string func_name_in, int approx_math_in);
49
50 virtual ~IRGeneratorBase() = default;
51
56
57 void generate();
58
59 protected:
60 // NOLINTBEGIN(cppcoreguidelines-non-private-member-variables-in-classes)
61 // Input parameters
62 const std::vector<Token>& tokens;
63 const VSVideoInfo* vo;
64 const std::vector<const VSVideoInfo*>& vi;
66 int width;
67 int height;
69 const std::map<std::pair<int, std::string>, int>& prop_map;
71 std::string func_name;
73
74 llvm::LLVMContext& context;
75 llvm::Module& module;
76 llvm::IRBuilder<>& builder;
78
79 llvm::Function* func;
80 llvm::Value* rwptrs_arg;
81 llvm::Value* strides_arg;
82 llvm::Value* props_arg;
83
84 std::vector<llvm::Value*> preloaded_base_ptrs;
85 std::vector<llvm::Value*> preloaded_strides;
86
87 llvm::MDNode* alias_scope_domain;
88 std::vector<llvm::MDNode*> alias_scopes;
89 std::vector<llvm::MDNode*> alias_scope_lists;
90 std::vector<llvm::MDNode*> noalias_scope_lists;
91
92 std::map<analysis::RelYAccess, llvm::Value*> row_ptr_cache;
93
94 // NOLINTEND(cppcoreguidelines-non-private-member-variables-in-classes)
95
96 virtual void defineFunctionSignature() = 0;
97
98 virtual void generateLoops() = 0;
99
100 llvm::AllocaInst* createAllocaInEntry(llvm::Type* type,
101 const std::string& name);
102
103 template <typename... Args>
104 llvm::Value* createIntrinsicCall(llvm::Intrinsic::ID intrinsic_id,
105 Args... args);
106
107 void assumeAligned(llvm::Value* ptr_value, unsigned alignment);
108
109 template <typename MemInstT>
110 void setMemoryInstAttrs(MemInstT* inst, unsigned alignment,
111 int rwptr_index);
112
113 llvm::Value* getFinalCoord(llvm::Value* coord, llvm::Value* max_dim,
114 bool use_mirror);
115
116 llvm::Value* generateLoadFromRowPtr(llvm::Value* row_ptr, int clip_idx,
117 llvm::Value* x, int rel_x,
118 bool use_mirror,
119 bool no_x_bounds_check);
120
121 void addLoopMetadata(llvm::BranchInst* loop_br);
122
123 llvm::Value* generatePixelLoad(int clip_idx, llvm::Value* x, llvm::Value* y,
124 bool mirror);
125
126 void generatePixelStore(llvm::Value* value_to_store, llvm::Value* x,
127 llvm::Value* y);
128
129 void generateIRFromTokens(llvm::Value* x, llvm::Value* y, llvm::Value* x_fp,
130 llvm::Value* y_fp, bool no_x_bounds_check);
131
132 bool processCommonToken(const Token& token,
133 std::vector<llvm::Value*>& rpn_stack,
134 llvm::Type* float_ty, llvm::Type* i32_ty,
135 bool use_approx_math);
136
137 virtual bool processModeSpecificToken(const Token& token,
138 std::vector<llvm::Value*>& rpn_stack,
139 llvm::Value* x, llvm::Value* y,
140 llvm::Value* x_fp, llvm::Value* y_fp,
141 bool no_x_bounds_check) = 0;
142
143 virtual void finalizeAndStoreResult(llvm::Value* result_val, llvm::Value* x,
144 llvm::Value* y) = 0;
145};
146
147template <typename... Args>
148llvm::Value*
149IRGeneratorBase::createIntrinsicCall(llvm::Intrinsic::ID intrinsic_id,
150 Args... args) {
151 static_assert(sizeof...(Args) >= 1, "At least one argument required");
152 llvm::SmallVector<llvm::Value*, 4> arg_vec{args...};
153 auto* callee = llvm::Intrinsic::getOrInsertDeclaration(
154 &module, intrinsic_id, {arg_vec[0]->getType()});
155 auto* call = builder.CreateCall(callee, arg_vec);
156 call->setFastMathFlags(builder.getFastMathFlags());
157 return call;
158}
159
160template <typename MemInstT>
161void IRGeneratorBase::setMemoryInstAttrs(MemInstT* inst, unsigned alignment,
162 int rwptr_index) {
163 inst->setAlignment(llvm::Align(alignment));
164 inst->setMetadata(llvm::LLVMContext::MD_alias_scope,
165 alias_scope_lists[rwptr_index]);
166 inst->setMetadata(llvm::LLVMContext::MD_noalias,
167 noalias_scope_lists[rwptr_index]);
168}
169
170#endif // LLVMEXPR_IRGENERATORBASE_HPP
llvm::Value * createIntrinsicCall(llvm::Intrinsic::ID intrinsic_id, Args... args)
const std::map< std::pair< int, std::string >, int > & prop_map
llvm::Value * getFinalCoord(llvm::Value *coord, llvm::Value *max_dim, bool use_mirror)
virtual void defineFunctionSignature()=0
llvm::IRBuilder & builder
IRGeneratorBase & operator=(const IRGeneratorBase &)=delete
std::string func_name
llvm::LLVMContext & context
llvm::Value * generatePixelLoad(int clip_idx, llvm::Value *x, llvm::Value *y, bool mirror)
virtual bool processModeSpecificToken(const Token &token, std::vector< llvm::Value * > &rpn_stack, llvm::Value *x, llvm::Value *y, llvm::Value *x_fp, llvm::Value *y_fp, bool no_x_bounds_check)=0
const std::vector< const VSVideoInfo * > & vi
void generateIRFromTokens(llvm::Value *x, llvm::Value *y, llvm::Value *x_fp, llvm::Value *y_fp, bool no_x_bounds_check)
std::vector< llvm::MDNode * > alias_scopes
llvm::Value * rwptrs_arg
const std::vector< Token > & tokens
IRGeneratorBase(const std::vector< Token > &tokens_in, const VSVideoInfo *out_vi, const std::vector< const VSVideoInfo * > &in_vi, int width_in, int height_in, bool mirror, const std::map< std::pair< int, std::string >, int > &p_map, const analysis::ExpressionAnalysisResults &analysis_results_in, llvm::LLVMContext &context_ref, llvm::Module &module_ref, llvm::IRBuilder<> &builder_ref, MathLibraryManager &math_mgr, std::string func_name_in, int approx_math_in)
llvm::Value * generateLoadFromRowPtr(llvm::Value *row_ptr, int clip_idx, llvm::Value *x, int rel_x, bool use_mirror, bool no_x_bounds_check)
std::vector< llvm::MDNode * > alias_scope_lists
IRGeneratorBase(const IRGeneratorBase &)=delete
IRGeneratorBase(IRGeneratorBase &&)=delete
IRGeneratorBase & operator=(IRGeneratorBase &&)=delete
void setMemoryInstAttrs(MemInstT *inst, unsigned alignment, int rwptr_index)
llvm::AllocaInst * createAllocaInEntry(llvm::Type *type, const std::string &name)
void assumeAligned(llvm::Value *ptr_value, unsigned alignment)
llvm::Function * func
virtual void generateLoops()=0
virtual ~IRGeneratorBase()=default
std::vector< llvm::Value * > preloaded_base_ptrs
const VSVideoInfo * vo
std::vector< llvm::Value * > preloaded_strides
llvm::Module & module
std::map< analysis::RelYAccess, llvm::Value * > row_ptr_cache
llvm::MDNode * alias_scope_domain
llvm::Value * props_arg
std::vector< llvm::MDNode * > noalias_scope_lists
MathLibraryManager & math_manager
void addLoopMetadata(llvm::BranchInst *loop_br)
virtual void finalizeAndStoreResult(llvm::Value *result_val, llvm::Value *x, llvm::Value *y)=0
const analysis::ExpressionAnalysisResults & analysis_results
void generatePixelStore(llvm::Value *value_to_store, llvm::Value *x, llvm::Value *y)
bool processCommonToken(const Token &token, std::vector< llvm::Value * > &rpn_stack, llvm::Type *float_ty, llvm::Type *i32_ty, bool use_approx_math)
llvm::Value * strides_arg