Sample IR code for "c1:int + c2:int" The C-code equivalent is : ------------------------------ int expr_0(int64_t *addrs, int64_t *local_bitmaps, int64_t execution_context_ptr, int64_t nrecords) { int *outVec = (int *) addrs[5]; int *c0Vec = (int *) addrs[1]; int *c1Vec = (int *) addrs[3]; for (int loop_var = 0; loop_var < nrecords; ++loop_var) { int c0 = c0Vec[loop_var]; int c1 = c1Vec[loop_var]
| 274 | // ret i32 0 |
| 275 | // } |
| 276 | Status LLVMGenerator::CodeGenExprValue(DexPtr value_expr, int buffer_count, |
| 277 | FieldDescriptorPtr output, int suffix_idx, |
| 278 | std::string& fn_name, |
| 279 | SelectionVector::Mode selection_vector_mode) { |
| 280 | llvm::IRBuilder<>* builder = ir_builder(); |
| 281 | const auto output_type_id = output->Type()->id(); |
| 282 | |
| 283 | // Create fn prototype : |
| 284 | // int expr_1 (long **addrs, long *offsets, long **bitmaps, |
| 285 | // long *context_ptr, long nrec) |
| 286 | std::vector<llvm::Type*> arguments; |
| 287 | arguments.push_back(types()->i64_ptr_type()); // addrs |
| 288 | arguments.push_back(types()->i64_ptr_type()); // offsets |
| 289 | arguments.push_back(types()->i64_ptr_type()); // bitmaps |
| 290 | arguments.push_back(types()->i64_ptr_type()); // holders |
| 291 | llvm::Type* selection_vector_type = nullptr; |
| 292 | switch (selection_vector_mode) { |
| 293 | case SelectionVector::MODE_NONE: |
| 294 | case SelectionVector::MODE_UINT16: |
| 295 | arguments.push_back(types()->ptr_type(types()->i16_type())); |
| 296 | selection_vector_type = types()->i16_type(); |
| 297 | break; |
| 298 | case SelectionVector::MODE_UINT32: |
| 299 | arguments.push_back(types()->i32_ptr_type()); |
| 300 | selection_vector_type = types()->i32_type(); |
| 301 | break; |
| 302 | case SelectionVector::MODE_UINT64: |
| 303 | arguments.push_back(types()->i64_ptr_type()); |
| 304 | selection_vector_type = types()->i64_type(); |
| 305 | break; |
| 306 | } |
| 307 | arguments.push_back(types()->i64_type()); // ctx_ptr |
| 308 | arguments.push_back(types()->i64_type()); // nrec |
| 309 | llvm::FunctionType* prototype = |
| 310 | llvm::FunctionType::get(types()->i32_type(), arguments, false /*isVarArg*/); |
| 311 | |
| 312 | // Create fn |
| 313 | engine_->AddFunctionToCompile(fn_name); |
| 314 | llvm::Function* fn = llvm::Function::Create( |
| 315 | prototype, llvm::GlobalValue::ExternalLinkage, fn_name, module()); |
| 316 | ARROW_RETURN_IF((fn == nullptr), Status::CodeGenError("Error creating function.")); |
| 317 | |
| 318 | // Name the arguments |
| 319 | llvm::Function::arg_iterator args = (fn)->arg_begin(); |
| 320 | llvm::Value* arg_addrs = &*args; |
| 321 | arg_addrs->setName("inputs_addr"); |
| 322 | ++args; |
| 323 | llvm::Value* arg_addr_offsets = &*args; |
| 324 | arg_addr_offsets->setName("inputs_addr_offsets"); |
| 325 | ++args; |
| 326 | llvm::Value* arg_local_bitmaps = &*args; |
| 327 | arg_local_bitmaps->setName("local_bitmaps"); |
| 328 | ++args; |
| 329 | llvm::Value* arg_holder_ptrs = &*args; |
| 330 | arg_holder_ptrs->setName("holder_ptrs"); |
| 331 | ++args; |
| 332 | llvm::Value* arg_selection_vector = &*args; |
| 333 | arg_selection_vector->setName("selection_vector"); |