| 172 | } |
| 173 | |
| 174 | llvm::Value* CodegenAnyVal::CreateCall(LlvmCodeGen* cg, LlvmBuilder* builder, |
| 175 | llvm::Function* fn, llvm::ArrayRef<llvm::Value*> args, const char* name, |
| 176 | llvm::Value* result_ptr) { |
| 177 | if (fn->getReturnType()->isVoidTy()) { |
| 178 | // Void return type indicates that this function returns a DecimalVal via the first |
| 179 | // argument (which should be a DecimalVal*). |
| 180 | llvm::Function::arg_iterator ret_arg = fn->arg_begin(); |
| 181 | DCHECK(ret_arg->getType()->isPointerTy()); |
| 182 | llvm::Type* ret_type = ret_arg->getType()->getPointerElementType(); |
| 183 | DCHECK_EQ(ret_type, cg->GetNamedType(LLVM_DECIMALVAL_NAME)); |
| 184 | |
| 185 | // We need to pass a DecimalVal pointer to 'fn' that will be populated with the result |
| 186 | // value. Use 'result_ptr' if specified, otherwise alloca one. |
| 187 | llvm::Value* ret_ptr = (result_ptr == NULL) ? |
| 188 | cg->CreateEntryBlockAlloca(*builder, ret_type, name) : |
| 189 | result_ptr; |
| 190 | vector<llvm::Value*> new_args = args.vec(); |
| 191 | new_args.insert(new_args.begin(), ret_ptr); |
| 192 | // Bitcasting the args is often necessary when calling an IR UDF because the types |
| 193 | // in the IR module may have been renamed while linking. Bitcasting them avoids a |
| 194 | // type assertion. |
| 195 | CodeGenUtil::CreateCallWithBitCasts(builder, fn, new_args); |
| 196 | |
| 197 | // If 'result_ptr' was specified, we're done. Otherwise load and return the result. |
| 198 | if (result_ptr != NULL) return NULL; |
| 199 | return builder->CreateLoad(ret_ptr, name); |
| 200 | } else { |
| 201 | // Function returns *Val normally (note that it could still be returning a |
| 202 | // DecimalVal, since we generate non-compliant functions). |
| 203 | // Bitcasting the args is often necessary when calling an IR UDF because the types |
| 204 | // in the IR module may have been renamed while linking. Bitcasting them avoids a |
| 205 | // type assertion. |
| 206 | llvm::Value* ret = CodeGenUtil::CreateCallWithBitCasts(builder, fn, args, name); |
| 207 | if (result_ptr == NULL) return ret; |
| 208 | builder->CreateStore(ret, result_ptr); |
| 209 | return NULL; |
| 210 | } |
| 211 | } |
| 212 | |
| 213 | CodegenAnyVal CodegenAnyVal::CreateCallWrapped(LlvmCodeGen* cg, LlvmBuilder* builder, |
| 214 | const ColumnType& type, llvm::Function* fn, llvm::ArrayRef<llvm::Value*> args, |