]> git.proxmox.com Git - ceph.git/blame - ceph/src/arrow/cpp/src/gandiva/llvm_generator.h
import quincy 17.2.0
[ceph.git] / ceph / src / arrow / cpp / src / gandiva / llvm_generator.h
CommitLineData
1d09f67e
TL
1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements. See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership. The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License. You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied. See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18#pragma once
19
20#include <cstdint>
21#include <memory>
22#include <string>
23#include <vector>
24
25#include "arrow/util/macros.h"
26
27#include "gandiva/annotator.h"
28#include "gandiva/compiled_expr.h"
29#include "gandiva/configuration.h"
30#include "gandiva/dex_visitor.h"
31#include "gandiva/engine.h"
32#include "gandiva/execution_context.h"
33#include "gandiva/function_registry.h"
34#include "gandiva/gandiva_aliases.h"
35#include "gandiva/llvm_types.h"
36#include "gandiva/lvalue.h"
37#include "gandiva/selection_vector.h"
38#include "gandiva/value_validity_pair.h"
39#include "gandiva/visibility.h"
40
41namespace gandiva {
42
43class FunctionHolder;
44
45/// Builds an LLVM module and generates code for the specified set of expressions.
46class GANDIVA_EXPORT LLVMGenerator {
47 public:
48 /// \brief Factory method to initialize the generator.
49 static Status Make(std::shared_ptr<Configuration> config,
50 std::unique_ptr<LLVMGenerator>* llvm_generator);
51
52 /// \brief Build the code for the expression trees for default mode. Each
53 /// element in the vector represents an expression tree
54 Status Build(const ExpressionVector& exprs, SelectionVector::Mode mode);
55
56 /// \brief Build the code for the expression trees for default mode. Each
57 /// element in the vector represents an expression tree
58 Status Build(const ExpressionVector& exprs) {
59 return Build(exprs, SelectionVector::Mode::MODE_NONE);
60 }
61
62 /// \brief Execute the built expression against the provided arguments for
63 /// default mode.
64 Status Execute(const arrow::RecordBatch& record_batch,
65 const ArrayDataVector& output_vector);
66
67 /// \brief Execute the built expression against the provided arguments for
68 /// all modes. Only works on the records specified in the selection_vector.
69 Status Execute(const arrow::RecordBatch& record_batch,
70 const SelectionVector* selection_vector,
71 const ArrayDataVector& output_vector);
72
73 SelectionVector::Mode selection_vector_mode() { return selection_vector_mode_; }
74 LLVMTypes* types() { return engine_->types(); }
75 llvm::Module* module() { return engine_->module(); }
76 std::string DumpIR() { return engine_->DumpIR(); }
77
78 private:
79 LLVMGenerator();
80
81 FRIEND_TEST(TestLLVMGenerator, VerifyPCFunctions);
82 FRIEND_TEST(TestLLVMGenerator, TestAdd);
83 FRIEND_TEST(TestLLVMGenerator, TestNullInternal);
84
85 llvm::LLVMContext* context() { return engine_->context(); }
86 llvm::IRBuilder<>* ir_builder() { return engine_->ir_builder(); }
87
88 /// Visitor to generate the code for a decomposed expression.
89 class Visitor : public DexVisitor {
90 public:
91 Visitor(LLVMGenerator* generator, llvm::Function* function,
92 llvm::BasicBlock* entry_block, llvm::Value* arg_addrs,
93 llvm::Value* arg_local_bitmaps, std::vector<llvm::Value*> slice_offsets,
94 llvm::Value* arg_context_ptr, llvm::Value* loop_var);
95
96 void Visit(const VectorReadValidityDex& dex) override;
97 void Visit(const VectorReadFixedLenValueDex& dex) override;
98 void Visit(const VectorReadVarLenValueDex& dex) override;
99 void Visit(const LocalBitMapValidityDex& dex) override;
100 void Visit(const TrueDex& dex) override;
101 void Visit(const FalseDex& dex) override;
102 void Visit(const LiteralDex& dex) override;
103 void Visit(const NonNullableFuncDex& dex) override;
104 void Visit(const NullableNeverFuncDex& dex) override;
105 void Visit(const NullableInternalFuncDex& dex) override;
106 void Visit(const IfDex& dex) override;
107 void Visit(const BooleanAndDex& dex) override;
108 void Visit(const BooleanOrDex& dex) override;
109 void Visit(const InExprDexBase<int32_t>& dex) override;
110 void Visit(const InExprDexBase<int64_t>& dex) override;
111 void Visit(const InExprDexBase<float>& dex) override;
112 void Visit(const InExprDexBase<double>& dex) override;
113 void Visit(const InExprDexBase<gandiva::DecimalScalar128>& dex) override;
114 void Visit(const InExprDexBase<std::string>& dex) override;
115 template <typename Type>
116 void VisitInExpression(const InExprDexBase<Type>& dex);
117
118 LValuePtr result() { return result_; }
119
120 bool has_arena_allocs() { return has_arena_allocs_; }
121
122 private:
123 enum BufferType { kBufferTypeValidity = 0, kBufferTypeData, kBufferTypeOffsets };
124
125 llvm::IRBuilder<>* ir_builder() { return generator_->ir_builder(); }
126 llvm::Module* module() { return generator_->module(); }
127
128 // Generate the code to build the combined validity (bitwise and) from the
129 // vector of validities.
130 llvm::Value* BuildCombinedValidity(const DexVector& validities);
131
132 // Generate the code to build the validity and the value for the given pair.
133 LValuePtr BuildValueAndValidity(const ValueValidityPair& pair);
134
135 // Generate code to build the params.
136 std::vector<llvm::Value*> BuildParams(FunctionHolder* holder,
137 const ValueValidityPairVector& args,
138 bool with_validity, bool with_context);
139
140 // Generate code to onvoke a function call.
141 LValuePtr BuildFunctionCall(const NativeFunction* func, DataTypePtr arrow_return_type,
142 std::vector<llvm::Value*>* params);
143
144 // Generate code for an if-else condition.
145 LValuePtr BuildIfElse(llvm::Value* condition, std::function<LValuePtr()> then_func,
146 std::function<LValuePtr()> else_func,
147 DataTypePtr arrow_return_type);
148
149 // Switch to the entry_block and get reference of the validity/value/offsets buffer
150 llvm::Value* GetBufferReference(int idx, BufferType buffer_type, FieldPtr field);
151
152 // Get the slice offset of the validity/value/offsets buffer
153 llvm::Value* GetSliceOffset(int idx);
154
155 // Switch to the entry_block and get reference to the local bitmap.
156 llvm::Value* GetLocalBitMapReference(int idx);
157
158 // Clear the bit in the local bitmap, if is_valid is 'false'
159 void ClearLocalBitMapIfNotValid(int local_bitmap_idx, llvm::Value* is_valid);
160
161 LLVMGenerator* generator_;
162 LValuePtr result_;
163 llvm::Function* function_;
164 llvm::BasicBlock* entry_block_;
165 llvm::Value* arg_addrs_;
166 llvm::Value* arg_local_bitmaps_;
167 std::vector<llvm::Value*> slice_offsets_;
168 llvm::Value* arg_context_ptr_;
169 llvm::Value* loop_var_;
170 bool has_arena_allocs_;
171 };
172
173 // Generate the code for one expression for default mode, with the output of
174 // the expression going to 'output'.
175 Status Add(const ExpressionPtr expr, const FieldDescriptorPtr output);
176
177 /// Generate code to load the vector at specified index in the 'arg_addrs' array.
178 llvm::Value* LoadVectorAtIndex(llvm::Value* arg_addrs, int idx,
179 const std::string& name);
180
181 /// Generate code to load the vector at specified index and cast it as bitmap.
182 llvm::Value* GetValidityReference(llvm::Value* arg_addrs, int idx, FieldPtr field);
183
184 /// Generate code to load the vector at specified index and cast it as data array.
185 llvm::Value* GetDataReference(llvm::Value* arg_addrs, int idx, FieldPtr field);
186
187 /// Generate code to load the vector at specified index and cast it as offsets array.
188 llvm::Value* GetOffsetsReference(llvm::Value* arg_addrs, int idx, FieldPtr field);
189
190 /// Generate code to load the vector at specified index and cast it as buffer pointer.
191 llvm::Value* GetDataBufferPtrReference(llvm::Value* arg_addrs, int idx, FieldPtr field);
192
193 /// Generate code for the value array of one expression.
194 Status CodeGenExprValue(DexPtr value_expr, int num_buffers, FieldDescriptorPtr output,
195 int suffix_idx, llvm::Function** fn,
196 SelectionVector::Mode selection_vector_mode);
197
198 /// Generate code to load the local bitmap specified index and cast it as bitmap.
199 llvm::Value* GetLocalBitMapReference(llvm::Value* arg_bitmaps, int idx);
200
201 /// Generate code to get the bit value at 'position' in the bitmap.
202 llvm::Value* GetPackedBitValue(llvm::Value* bitmap, llvm::Value* position);
203
204 /// Generate code to get the bit value at 'position' in the validity bitmap.
205 llvm::Value* GetPackedValidityBitValue(llvm::Value* bitmap, llvm::Value* position);
206
207 /// Generate code to set the bit value at 'position' in the bitmap to 'value'.
208 void SetPackedBitValue(llvm::Value* bitmap, llvm::Value* position, llvm::Value* value);
209
210 /// Generate code to clear the bit value at 'position' in the bitmap if 'value'
211 /// is false.
212 void ClearPackedBitValueIfFalse(llvm::Value* bitmap, llvm::Value* position,
213 llvm::Value* value);
214
215 // Generate code to build a DecimalLValue with specified value/precision/scale.
216 std::shared_ptr<DecimalLValue> BuildDecimalLValue(llvm::Value* value,
217 DataTypePtr arrow_type);
218
219 /// Generate code to make a function call (to a pre-compiled IR function) which takes
220 /// 'args' and has a return type 'ret_type'.
221 llvm::Value* AddFunctionCall(const std::string& full_name, llvm::Type* ret_type,
222 const std::vector<llvm::Value*>& args);
223
224 /// Compute the result bitmap for the expression.
225 ///
226 /// \param[in] compiled_expr the compiled expression (includes the bitmap indices to be
227 /// used for computing the validity bitmap of the result).
228 /// \param[in] eval_batch (includes input/output buffer addresses)
229 /// \param[in] selection_vector the list of selected positions
230 void ComputeBitMapsForExpr(const CompiledExpr& compiled_expr,
231 const EvalBatch& eval_batch,
232 const SelectionVector* selection_vector);
233
234 /// Replace the %T in the trace msg with the correct type corresponding to 'type'
235 /// eg. %d for int32, %ld for int64, ..
236 std::string ReplaceFormatInTrace(const std::string& msg, llvm::Value* value,
237 std::string* print_fn);
238
239 /// Generate the code to print a trace msg with one optional argument (%T)
240 void AddTrace(const std::string& msg, llvm::Value* value = NULLPTR);
241
242 std::unique_ptr<Engine> engine_;
243 std::vector<std::unique_ptr<CompiledExpr>> compiled_exprs_;
244 FunctionRegistry function_registry_;
245 Annotator annotator_;
246 SelectionVector::Mode selection_vector_mode_;
247
248 // used for debug
249 bool enable_ir_traces_;
250 std::vector<std::string> trace_strings_;
251};
252
253} // namespace gandiva