25 auto void_type = llvm::Type::getVoidTy(cgen_state->
context_);
27 std::vector<llvm::Type*> parameter_types(2, int8_ptr_type);
28 const auto func_type = llvm::FunctionType::get(void_type, parameter_types,
false);
29 auto function = llvm::Function::Create(
30 func_type, llvm::Function::ExternalLinkage, name, cgen_state->
module_);
32 llvm::BasicBlock::Create(cgen_state->
context_,
".entry",
function, 0);
40 std::string read_arg_name{
"read_stub_arg_"};
44 read_arg_name +=
"int";
48 read_arg_name +=
"float";
52 read_arg_name +=
"double";
56 read_arg_name +=
"pi8";
60 read_arg_name +=
"pi32";
64 read_arg_name +=
"pi64";
68 read_arg_name +=
"pvoid";
72 read_arg_name +=
"ppi64";
76 LOG(
FATAL) <<
"Invalid type: " <<
static_cast<int>(arg_type);
120 CHECK_LT(static_cast<size_t>(i), inputs.size());
121 return inputs[i].int_val;
126 CHECK_LT(static_cast<size_t>(i), inputs.size());
127 return inputs[i].float_val;
132 CHECK_LT(static_cast<size_t>(i), inputs.size());
133 return inputs[i].double_val;
138 CHECK_LT(static_cast<size_t>(i), inputs.size());
139 return inputs[i].ptr;
173 const std::vector<Type>& arg_types,
175 const bool is_external) {
176 const auto stub_name = name +
"_stub";
180 if (compilation_context) {
186 auto cgen_state = std::make_unique<CgenState>(0,
189 cgen_state->module_ = module.get();
192 auto& ctx = cgen_state->context_;
193 std::vector<llvm::Value*> callee_args;
194 auto inputs_it =
function->arg_begin() + 1;
195 for (
size_t i = 0; i < arg_types.size(); ++i) {
196 const auto arg_type = arg_types[i];
198 const auto llvm_arg_type =
llvm_type(arg_type, ctx);
199 auto callee_arg = cgen_state->emitExternalCall(
200 read_arg_name, llvm_arg_type, {&*inputs_it, cgen_state->llInt<int32_t>(i)});
202 CHECK(llvm_arg_type->isIntegerTy());
203 callee_arg = cgen_state->ir_builder_.CreateTrunc(callee_arg, llvm_arg_type);
205 CHECK(llvm_arg_type->isPointerTy());
206 callee_arg = cgen_state->ir_builder_.CreateBitCast(callee_arg, llvm_arg_type);
208 callee_args.push_back(callee_arg);
210 const auto llvm_ret_type =
llvm_type(ret_type, ctx);
211 auto value = is_external
212 ? cgen_state->emitExternalCall(name, llvm_ret_type, callee_args)
213 : cgen_state->emitCall(name, callee_args);
214 auto output = &*(
function->arg_begin());
215 auto void_type = llvm::Type::getVoidTy(ctx);
216 std::string write_arg_name{
"write_stub_result_"};
219 write_arg_name +=
"int";
220 const auto i64_type =
get_int_type(64, cgen_state->context_);
221 value = cgen_state->ir_builder_.CreateSExt(value, i64_type);
225 write_arg_name +=
"int";
226 const auto i64_type =
get_int_type(64, cgen_state->context_);
227 value = cgen_state->ir_builder_.CreateSExt(value, i64_type);
235 LOG(
FATAL) <<
"Invalid type: " <<
static_cast<int>(ret_type);
239 cgen_state->emitExternalCall(write_arg_name, void_type, {output, value});
241 cgen_state->ir_builder_.CreateRetVoid();
250 auto cpu_compilation_context = std::make_shared<CpuCompilationContext>(std::move(ee));
251 cpu_compilation_context->setFunctionPointer(
function);
253 key, cpu_compilation_context, function->getParent(),
s_stubs_cache);
std::unique_ptr< llvm::Module > runtime_module_shallow_copy(CgenState *cgen_state)
std::vector< ReductionInterpreter::EvalValue > InputsType
llvm::IRBuilder ir_builder_
int64_t read_stub_arg_int(const void *inputs_handle, const int32_t i)
std::vector< std::string > CodeCacheKey
static ExecutionEngineWrapper generateNativeCPUCode(llvm::Function *func, const std::unordered_set< llvm::Function * > &live_funcs, const CompilationOptions &co)
llvm::Type * get_int_type(const int width, llvm::LLVMContext &context)
float read_stub_arg_float(const void *inputs_handle, const int32_t i)
static CodeCache s_stubs_cache
const void * read_stub_arg_pvoid(const void *inputs_handle, const int32_t i)
static std::mutex s_stubs_cache_mutex
void verify_function_ir(const llvm::Function *func)
llvm::LLVMContext & context_
double read_stub_arg_double(const void *inputs_handle, const int32_t i)
static Stub generateStub(const std::string &name, const std::vector< Type > &arg_types, const Type ret_type, const bool is_external)
static void addCodeToCache(const CodeCacheKey &, std::shared_ptr< CompilationContext >, llvm::Module *, CodeCache &)
llvm::Type * llvm_type(const Type type, llvm::LLVMContext &ctx)
std::string get_stub_read_argument_name(const Type arg_type)
const int32_t * read_stub_arg_pi32(const void *inputs_handle, const int32_t i)
ReductionInterpreter::EvalValue(*)(void *output_handle, const void *inputs_handle) Stub
const int64_t *const * read_stub_arg_ppi64(const void *inputs_handle, const int32_t i)
const int32_t * read_stub_arg_pi64(const void *inputs_handle, const int32_t i)
bool is_pointer_type(const Type type)
value_t * get(const key_t &key)
const int8_t * read_stub_arg_pi8(const void *inputs_handle, const int32_t i)
bool is_integer_type(const Type type)
llvm::Function * create_stub_function(const std::string &name, CgenState *cgen_state)
void write_stub_result_int(void *output_handle, const int64_t int_val)