VapourSynth-llvmexpr
Loading...
Searching...
No Matches
SingleExprIRGenerator Class Reference

#include <llvmexpr/codegen/llvm/SingleExprIRGenerator.hpp>

Inheritance diagram for SingleExprIRGenerator:
Collaboration diagram for SingleExprIRGenerator:

Public Member Functions

 SingleExprIRGenerator (const std::vector< Token > &tokens_in, const VSVideoInfo *out_vi, const std::vector< const VSVideoInfo * > &in_vi, bool mirror, const std::map< std::pair< int, std::string >, int > &p_map, const std::vector< std::string > &output_props, 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)
Public Member Functions inherited from IRGeneratorBase
 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)
virtual ~IRGeneratorBase ()=default
 IRGeneratorBase (const IRGeneratorBase &)=delete
IRGeneratorBaseoperator= (const IRGeneratorBase &)=delete
 IRGeneratorBase (IRGeneratorBase &&)=delete
IRGeneratorBaseoperator= (IRGeneratorBase &&)=delete
void generate ()

Protected Member Functions

void defineFunctionSignature () override
void generateLoops () override
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) override
void finalizeAndStoreResult (llvm::Value *result_val, llvm::Value *x, llvm::Value *y) override
Protected Member Functions inherited from IRGeneratorBase
llvm::AllocaInst * createAllocaInEntry (llvm::Type *type, const std::string &name)
template<typename... Args>
llvm::Value * createIntrinsicCall (llvm::Intrinsic::ID intrinsic_id, Args... args)
void assumeAligned (llvm::Value *ptr_value, unsigned alignment)
template<typename MemInstT>
void setMemoryInstAttrs (MemInstT *inst, unsigned alignment, int rwptr_index)
llvm::Value * getFinalCoord (llvm::Value *coord, llvm::Value *max_dim, bool use_mirror)
llvm::Value * generateLoadFromRowPtr (llvm::Value *row_ptr, int clip_idx, llvm::Value *x, int rel_x, bool use_mirror, bool no_x_bounds_check)
void addLoopMetadata (llvm::BranchInst *loop_br)
llvm::Value * generatePixelLoad (int clip_idx, llvm::Value *x, llvm::Value *y, bool mirror)
void generatePixelStore (llvm::Value *value_to_store, llvm::Value *x, llvm::Value *y)
void generateIRFromTokens (llvm::Value *x, llvm::Value *y, llvm::Value *x_fp, llvm::Value *y_fp, bool no_x_bounds_check)
bool processCommonToken (const Token &token, std::vector< llvm::Value * > &rpn_stack, llvm::Type *float_ty, llvm::Type *i32_ty, bool use_approx_math)

Additional Inherited Members

Protected Attributes inherited from IRGeneratorBase
const std::vector< Token > & tokens
const VSVideoInfo * vo
const std::vector< const VSVideoInfo * > & vi
int num_inputs
int width
int height
bool mirror_boundary
const std::map< std::pair< int, std::string >, int > & prop_map
const analysis::ExpressionAnalysisResultsanalysis_results
std::string func_name
int approx_math
llvm::LLVMContext & context
llvm::Module & module
llvm::IRBuilder & builder
MathLibraryManagermath_manager
llvm::Function * func
llvm::Value * rwptrs_arg
llvm::Value * strides_arg
llvm::Value * props_arg
std::vector< llvm::Value * > preloaded_base_ptrs
std::vector< llvm::Value * > preloaded_strides
llvm::MDNode * alias_scope_domain
std::vector< llvm::MDNode * > alias_scopes
std::vector< llvm::MDNode * > alias_scope_lists
std::vector< llvm::MDNode * > noalias_scope_lists
std::map< analysis::RelYAccess, llvm::Value * > row_ptr_cache

Detailed Description

Copyright (C) 2025 yuygfgg

This file is part of Vapoursynth-llvmexpr.

Vapoursynth-llvmexpr is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

Vapoursynth-llvmexpr is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with Vapoursynth-llvmexpr. If not, see https://www.gnu.org/licenses/.

Definition at line 25 of file SingleExprIRGenerator.hpp.

Constructor & Destructor Documentation

◆ SingleExprIRGenerator()

SingleExprIRGenerator::SingleExprIRGenerator ( const std::vector< Token > & tokens_in,
const VSVideoInfo * out_vi,
const std::vector< const VSVideoInfo * > & in_vi,
bool mirror,
const std::map< std::pair< int, std::string >, int > & p_map,
const std::vector< std::string > & output_props,
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 )

Copyright (C) 2025 yuygfgg

This file is part of Vapoursynth-llvmexpr.

Vapoursynth-llvmexpr is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

Vapoursynth-llvmexpr is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with Vapoursynth-llvmexpr. If not, see https://www.gnu.org/licenses/.

Definition at line 30 of file SingleExprIRGenerator.cpp.

39 : IRGeneratorBase(tokens_in, out_vi, in_vi, out_vi->width, out_vi->height,
40 mirror, p_map, analysis_results_in, context_ref,
41 module_ref, builder_ref, math_mgr,
42 std::move(func_name_in), approx_math_in),
43 output_props_list(output_props) {
44
45 for (size_t i = 0; i < output_props_list.size(); ++i) {
46 output_prop_map[output_props_list[i]] = static_cast<int>(i);
47 }
48}
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)

References IRGeneratorBase::height, IRGeneratorBase::IRGeneratorBase(), and IRGeneratorBase::width.

Member Function Documentation

◆ defineFunctionSignature()

void SingleExprIRGenerator::defineFunctionSignature ( )
overrideprotectedvirtual

Implements IRGeneratorBase.

Definition at line 50 of file SingleExprIRGenerator.cpp.

50 {
51 llvm::Type* void_ty = llvm::Type::getVoidTy(context);
52 llvm::Type* ptr_ty = llvm::PointerType::get(context, 0);
53 llvm::Type* context_ptr_ty = ptr_ty; // opaque pointer (void*)
54 llvm::Type* i8_ptr_ptr_ty = ptr_ty; // opaque pointer (represents uint8_t**)
55 llvm::Type* i32_ptr_ty = ptr_ty; // opaque pointer (represents int32_t*)
56 llvm::Type* float_ptr_ty = ptr_ty; // opaque pointer (represents float*)
57
58 llvm::FunctionType* func_ty = llvm::FunctionType::get(
59 void_ty, {context_ptr_ty, i8_ptr_ptr_ty, i32_ptr_ty, float_ptr_ty},
60 false);
61
62 func = llvm::Function::Create(func_ty, llvm::Function::ExternalLinkage,
64 func->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::None);
65
66 context_arg = func->getArg(0);
67 context_arg->setName("context");
68 rwptrs_arg = func->getArg(1);
69 rwptrs_arg->setName("rwptrs");
70 strides_arg = func->getArg(2);
71 strides_arg->setName("strides");
72 props_arg = func->getArg(3);
73 props_arg->setName("props");
74
75 func->addParamAttr(2, llvm::Attribute::ReadOnly); // strides (int32_t*)
76
77 // Declare Host API functions for dynamic array management
78 llvm::Type* i64_ty = builder.getInt64Ty();
79 llvm::Type* i8_ptr_ty = ptr_ty;
80
81 // float* llvmexpr_ensure_buffer(const char* name, int64_t size)
82 llvm::FunctionType* ensure_buffer_ty =
83 llvm::FunctionType::get(float_ptr_ty, {i8_ptr_ty, i64_ty}, false);
84 llvmexpr_ensure_buffer_func = llvm::Function::Create(
85 ensure_buffer_ty, llvm::Function::ExternalLinkage,
86 "llvmexpr_ensure_buffer", &module);
87
88 // int64_t llvmexpr_get_buffer_size(const char* name)
89 llvm::FunctionType* get_buffer_size_ty =
90 llvm::FunctionType::get(i64_ty, {i8_ptr_ty}, false);
91 llvmexpr_get_buffer_size_func = llvm::Function::Create(
92 get_buffer_size_ty, llvm::Function::ExternalLinkage,
93 "llvmexpr_get_buffer_size", &module);
94}
llvm::IRBuilder & builder
std::string func_name
llvm::LLVMContext & context
llvm::Value * rwptrs_arg
llvm::Function * func
llvm::Module & module
llvm::Value * props_arg
llvm::Value * strides_arg

References IRGeneratorBase::builder, IRGeneratorBase::context, IRGeneratorBase::func, IRGeneratorBase::func_name, IRGeneratorBase::module, IRGeneratorBase::props_arg, IRGeneratorBase::rwptrs_arg, and IRGeneratorBase::strides_arg.

◆ finalizeAndStoreResult()

void SingleExprIRGenerator::finalizeAndStoreResult ( llvm::Value * result_val,
llvm::Value * x,
llvm::Value * y )
overrideprotectedvirtual

Implements IRGeneratorBase.

Definition at line 538 of file SingleExprIRGenerator.cpp.

540 {
541 // No-op for SingleExpr, all stores are explicit
542}

◆ generateLoops()

void SingleExprIRGenerator::generateLoops ( )
overrideprotectedvirtual

Implements IRGeneratorBase.

Definition at line 96 of file SingleExprIRGenerator.cpp.

97 { // TODO: rename this. Nothing to do with loops here.
98 llvm::BasicBlock* entry_bb =
99 llvm::BasicBlock::Create(context, "entry", func);
100 builder.SetInsertPoint(entry_bb);
101
102 // Pre-load all plane pointers and strides
103 plane_base_ptrs.resize(num_inputs + 1);
104 plane_strides.resize(num_inputs + 1);
105 const int num_planes = // NOLINT(cppcoreguidelines-init-variables)
106 vo->format.numPlanes;
107 for (int i = 0; i <= num_inputs; ++i) {
108 plane_base_ptrs[i].resize(num_planes);
109 plane_strides[i].resize(num_planes);
110 for (int p = 0; p < num_planes; ++p) {
111 int flat_idx = (i * num_planes) + p;
112 llvm::Value* base_ptr_i = builder.CreateLoad(
113 llvm::PointerType::get(context, 0),
114 builder.CreateGEP(llvm::PointerType::get(context, 0),
115 rwptrs_arg, builder.getInt32(flat_idx)));
116 llvm::Value* stride_i = builder.CreateLoad(
117 builder.getInt32Ty(),
118 builder.CreateGEP(builder.getInt32Ty(), strides_arg,
119 builder.getInt32(flat_idx)));
120 plane_base_ptrs[i][p] = base_ptr_i;
121 plane_strides[i][p] = stride_i;
122 }
123 }
124
125 // Aligned loads for properties
126 for (const auto& [key, idx] : prop_map) {
127 llvm::Value* prop_val = builder.CreateLoad(
128 builder.getFloatTy(),
129 builder.CreateGEP(builder.getFloatTy(), props_arg,
130 builder.getInt32(idx)));
131 const std::string unique_prop_name =
132 std::format("prop_{}_{}", key.first, key.second);
133 llvm::Value* alloca =
134 createAllocaInEntry(builder.getFloatTy(), unique_prop_name);
135 builder.CreateStore(prop_val, alloca);
136 prop_allocas[unique_prop_name] = alloca;
137 }
138
139 //NOLINTNEXTLINE(cppcoreguidelines-avoid-magic-numbers)
140 llvm::APInt payload_bits(32, 0x7FC0DEAD);
141 llvm::APFloat nan_payload_apf(llvm::APFloat::IEEEsingle(), payload_bits);
142 llvm::Value* nan_with_payload =
143 llvm::ConstantFP::get(context, nan_payload_apf);
144
145 for (const auto& prop_name : output_props_list) {
146 const std::string mangled_input_name =
147 std::format("prop_0_{}", prop_name);
148 if (prop_allocas.contains(mangled_input_name)) {
149 prop_allocas[prop_name] = prop_allocas.at(mangled_input_name);
150 } else {
151 if (!prop_allocas.contains(prop_name)) {
152 llvm::Value* alloca =
153 createAllocaInEntry(builder.getFloatTy(), prop_name);
154 builder.CreateStore(nan_with_payload, alloca);
155 prop_allocas[prop_name] = alloca;
156 }
157 }
158 }
159
160 // Only generate IR if there are tokens to process
161 if (!tokens.empty()) {
162 generateIRFromTokens(nullptr, nullptr, nullptr, nullptr, true);
163 }
164
165 // Store output properties back
166 for (const auto& [name, idx] : output_prop_map) {
167 llvm::Value* val =
168 builder.CreateLoad(builder.getFloatTy(), prop_allocas.at(name));
169 builder.CreateStore(
170 val,
171 builder.CreateGEP(builder.getFloatTy(), props_arg,
172 builder.getInt32(prop_map.size() + 1 + idx)));
173 }
174
175 builder.CreateRetVoid();
176}
const std::map< std::pair< int, std::string >, int > & prop_map
void generateIRFromTokens(llvm::Value *x, llvm::Value *y, llvm::Value *x_fp, llvm::Value *y_fp, bool no_x_bounds_check)
const std::vector< Token > & tokens
llvm::AllocaInst * createAllocaInEntry(llvm::Type *type, const std::string &name)
const VSVideoInfo * vo

References IRGeneratorBase::builder, IRGeneratorBase::context, IRGeneratorBase::createAllocaInEntry(), IRGeneratorBase::func, IRGeneratorBase::generateIRFromTokens(), IRGeneratorBase::num_inputs, IRGeneratorBase::prop_map, IRGeneratorBase::props_arg, IRGeneratorBase::rwptrs_arg, IRGeneratorBase::strides_arg, IRGeneratorBase::tokens, and IRGeneratorBase::vo.

◆ processModeSpecificToken()

bool SingleExprIRGenerator::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 )
overrideprotectedvirtual

Implements IRGeneratorBase.

Definition at line 289 of file SingleExprIRGenerator.cpp.

293 {
294 llvm::Type* float_ty = builder.getFloatTy();
295 llvm::Type* i32_ty = builder.getInt32Ty();
296
297 switch (token.type) {
299 const auto& payload = std::get<TokenPayloadClipDim>(token.payload);
300 const VSVideoInfo* vinfo = vi[payload.clip_idx];
301 rpn_stack.push_back(
302 builder.CreateSIToFP(builder.getInt32(vinfo->width), float_ty));
303 return true;
304 }
306 const auto& payload = std::get<TokenPayloadClipDim>(token.payload);
307 const VSVideoInfo* vinfo = vi[payload.clip_idx];
308 rpn_stack.push_back(
309 builder.CreateSIToFP(builder.getInt32(vinfo->height), float_ty));
310 return true;
311 }
313 const auto& payload = std::get<TokenPayloadClipPlaneDim>(token.payload);
314 const VSVideoInfo* vinfo = vi[payload.clip_idx];
315 int plane_w = vinfo->width;
316 if (vinfo->format.colorFamily == cfYUV && payload.plane_idx > 0) {
317 plane_w >>= vinfo->format.subSamplingW;
318 }
319 rpn_stack.push_back(
320 builder.CreateSIToFP(builder.getInt32(plane_w), float_ty));
321 return true;
322 }
324 const auto& payload = std::get<TokenPayloadClipPlaneDim>(token.payload);
325 const VSVideoInfo* vinfo = vi[payload.clip_idx];
326 int plane_h = vinfo->height;
327 if (vinfo->format.colorFamily == cfYUV && payload.plane_idx > 0) {
328 plane_h >>= vinfo->format.subSamplingH;
329 }
330 rpn_stack.push_back(
331 builder.CreateSIToFP(builder.getInt32(plane_h), float_ty));
332 return true;
333 }
335 const auto& payload = std::get<TokenPayloadPlaneDim>(token.payload);
336 int plane_w = vo->width; // NOLINT(cppcoreguidelines-init-variables)
337 if (vo->format.colorFamily == cfYUV && payload.plane_idx > 0) {
338 plane_w >>= vo->format.subSamplingW;
339 }
340 rpn_stack.push_back(
341 builder.CreateSIToFP(builder.getInt32(plane_w), float_ty));
342 return true;
343 }
345 const auto& payload = std::get<TokenPayloadPlaneDim>(token.payload);
346 int plane_h = vo->height; // NOLINT(cppcoreguidelines-init-variables)
347 if (vo->format.colorFamily == cfYUV && payload.plane_idx > 0) {
348 plane_h >>= vo->format.subSamplingH;
349 }
350 rpn_stack.push_back(
351 builder.CreateSIToFP(builder.getInt32(plane_h), float_ty));
352 return true;
353 }
355 const auto& payload =
356 std::get<TokenPayloadClipAccessPlane>(token.payload);
357 llvm::Value* coord_y_f = rpn_stack.back();
358 rpn_stack.pop_back();
359 llvm::Value* coord_x_f = rpn_stack.back();
360 rpn_stack.pop_back();
361
362 llvm::Value* coord_y =
363 builder.CreateCall(llvm::Intrinsic::getOrInsertDeclaration(
364 &module, llvm::Intrinsic::rint, {float_ty}),
365 {coord_y_f});
366 coord_y = builder.CreateFPToSI(coord_y, i32_ty);
367
368 llvm::Value* coord_x =
369 builder.CreateCall(llvm::Intrinsic::getOrInsertDeclaration(
370 &module, llvm::Intrinsic::rint, {float_ty}),
371 {coord_x_f});
372 coord_x = builder.CreateFPToSI(coord_x, i32_ty);
373
374 rpn_stack.push_back(generatePixelLoadPlane(
375 payload.clip_idx, payload.plane_idx, coord_x, coord_y));
376 return true;
377 }
379 const auto& payload =
380 std::get<TokenPayloadStoreAbsPlane>(token.payload);
381 llvm::Value* coord_y_f = rpn_stack.back();
382 rpn_stack.pop_back();
383 llvm::Value* coord_x_f = rpn_stack.back();
384 rpn_stack.pop_back();
385 llvm::Value* val_to_store = rpn_stack.back();
386 rpn_stack.pop_back();
387
388 llvm::Value* coord_y =
389 builder.CreateCall(llvm::Intrinsic::getOrInsertDeclaration(
390 &module, llvm::Intrinsic::rint, {float_ty}),
391 {coord_y_f});
392 coord_y = builder.CreateFPToSI(coord_y, i32_ty);
393
394 llvm::Value* coord_x =
395 builder.CreateCall(llvm::Intrinsic::getOrInsertDeclaration(
396 &module, llvm::Intrinsic::rint, {float_ty}),
397 {coord_x_f});
398 coord_x = builder.CreateFPToSI(coord_x, i32_ty);
399
400 generatePixelStorePlane(val_to_store, payload.plane_idx, coord_x,
401 coord_y);
402 return true;
403 }
405 const auto& payload = std::get<TokenPayloadPropStore>(token.payload);
406 if (payload.type == PropWriteType::Delete) {
407 // NOLINTNEXTLINE(cppcoreguidelines-avoid-magic-numbers)
408 llvm::APInt payload_bits(32, 0x7FC0DE1E); // PROP_DELETE_NAN_PAYLOAD
409 llvm::APFloat nan_payload_apf(llvm::APFloat::IEEEsingle(),
410 payload_bits);
411 llvm::Value* nan_with_payload =
412 llvm::ConstantFP::get(context, nan_payload_apf);
413 builder.CreateStore(nan_with_payload,
414 prop_allocas.at(payload.prop_name));
415 } else {
416 llvm::Value* val_to_store = rpn_stack.back();
417 rpn_stack.pop_back();
418 builder.CreateStore(val_to_store,
419 prop_allocas.at(payload.prop_name));
420 }
421 return true;
422 }
424 const auto& payload = std::get<TokenPayloadPropAccess>(token.payload);
425 if (payload.clip_idx == 0 &&
426 output_prop_map.contains(payload.prop_name)) {
427 rpn_stack.push_back(builder.CreateLoad(
428 float_ty, prop_allocas.at(payload.prop_name)));
429 } else {
430 const std::string unique_prop_name =
431 std::format("prop_{}_{}", payload.clip_idx, payload.prop_name);
432 rpn_stack.push_back(builder.CreateLoad(
433 float_ty, prop_allocas.at(unique_prop_name)));
434 }
435 return true;
436 }
437
439 const auto& payload = std::get<TokenPayloadPropAccess>(token.payload);
440 llvm::Value* prop_val = nullptr;
441 if (payload.clip_idx == 0 &&
442 output_prop_map.contains(payload.prop_name)) {
443 prop_val = builder.CreateLoad(float_ty,
444 prop_allocas.at(payload.prop_name));
445 } else {
446 const std::string unique_prop_name =
447 std::format("prop_{}_{}", payload.clip_idx, payload.prop_name);
448 if (!prop_allocas.contains(unique_prop_name)) {
449 rpn_stack.push_back(llvm::ConstantFP::get(float_ty, 0.0));
450 return true;
451 }
452 prop_val =
453 builder.CreateLoad(float_ty, prop_allocas.at(unique_prop_name));
454 }
455
456 llvm::Value* prop_val_int = builder.CreateBitCast(prop_val, i32_ty);
457
458 // NOLINTNEXTLINE(cppcoreguidelines-avoid-magic-numbers)
459 llvm::Value* read_nan_payload = builder.getInt32(0x7FC0BEEF);
460 llvm::Value* is_read_nan =
461 builder.CreateICmpEQ(prop_val_int, read_nan_payload);
462
463 // NOLINTNEXTLINE(cppcoreguidelines-avoid-magic-numbers)
464 llvm::Value* delete_nan_payload = builder.getInt32(0x7FC0DE1E);
465 llvm::Value* is_delete_nan =
466 builder.CreateICmpEQ(prop_val_int, delete_nan_payload);
467
468 llvm::Value* does_not_exist =
469 builder.CreateOr(is_read_nan, is_delete_nan);
470
471 llvm::Value* exists_val = builder.CreateSelect(
472 does_not_exist, llvm::ConstantFP::get(float_ty, 0.0),
473 llvm::ConstantFP::get(float_ty, 1.0));
474 rpn_stack.push_back(exists_val);
475 return true;
476 }
477
478 // Array
480 const auto& payload = std::get<TokenPayloadArrayOp>(token.payload);
481 llvm::Value* size_val = builder.getInt64(payload.static_size);
482 llvm::Value* name_str =
483 builder.CreateGlobalString(payload.name, payload.name + "_name");
484 llvm::Value* buffer_ptr = builder.CreateCall(
485 llvmexpr_ensure_buffer_func, {name_str, size_val});
486 array_ptr_cache[payload.name] = buffer_ptr;
487 return true;
488 }
489
491 const auto& payload = std::get<TokenPayloadArrayOp>(token.payload);
492 llvm::Value* size_f = rpn_stack.back();
493 rpn_stack.pop_back();
494
495 llvm::Value* size_val =
496 builder.CreateFPToSI(size_f, builder.getInt64Ty());
497 llvm::Value* name_str =
498 builder.CreateGlobalString(payload.name, payload.name + "_name");
499 llvm::Value* buffer_ptr = builder.CreateCall(
500 llvmexpr_ensure_buffer_func, {name_str, size_val});
501 array_ptr_cache[payload.name] = buffer_ptr;
502 return true;
503 }
504
506 const auto& payload = std::get<TokenPayloadArrayOp>(token.payload);
507 llvm::Value* idx_f = rpn_stack.back();
508 rpn_stack.pop_back();
509 llvm::Value* idx = builder.CreateFPToSI(idx_f, i32_ty);
510
511 llvm::Value* array_ptr = array_ptr_cache.at(payload.name);
512 llvm::Value* elem_ptr = builder.CreateGEP(float_ty, array_ptr, idx);
513 llvm::Value* value = builder.CreateLoad(float_ty, elem_ptr);
514 rpn_stack.push_back(value);
515 return true;
516 }
517
519 const auto& payload = std::get<TokenPayloadArrayOp>(token.payload);
520 llvm::Value* idx_f = rpn_stack.back();
521 rpn_stack.pop_back();
522 llvm::Value* value = rpn_stack.back();
523 rpn_stack.pop_back();
524
525 llvm::Value* idx = builder.CreateFPToSI(idx_f, i32_ty);
526
527 llvm::Value* array_ptr = array_ptr_cache.at(payload.name);
528 llvm::Value* elem_ptr = builder.CreateGEP(float_ty, array_ptr, idx);
529 builder.CreateStore(value, elem_ptr);
530 return true;
531 }
532
533 default:
534 return false;
535 }
536}
@ ConstantClipPlaneHeight
Definition Tokenizer.hpp:42
@ ConstantPlaneWidth
Definition Tokenizer.hpp:37
@ ArrayAllocStatic
Definition Tokenizer.hpp:51
@ ConstantPlaneHeight
Definition Tokenizer.hpp:38
@ ConstantClipHeight
Definition Tokenizer.hpp:40
@ ConstantClipPlaneWidth
Definition Tokenizer.hpp:41
@ ConstantClipWidth
Definition Tokenizer.hpp:39
const std::vector< const VSVideoInfo * > & vi
TokenType type
PayloadVariant payload

References ArrayAllocDyn, ArrayAllocStatic, ArrayLoad, ArrayStore, IRGeneratorBase::builder, ClipAbsPlane, ConstantClipHeight, ConstantClipPlaneHeight, ConstantClipPlaneWidth, ConstantClipWidth, ConstantPlaneHeight, ConstantPlaneWidth, IRGeneratorBase::context, Delete, IRGeneratorBase::module, Token::payload, PropAccess, PropExists, PropStore, StoreAbsPlane, Token::type, IRGeneratorBase::vi, and IRGeneratorBase::vo.


The documentation for this class was generated from the following files: