llvm::Module *ClangCompiler::Compile(const string &source, LLVMContext *context) const { // write the source to a temporary file and invoke the compiler string temp_tmpl = ".tmp_XXXXXX"; const char *tmpfile = UniqueFilename(temp_tmpl); //const char *tmpfile = "temp.c"; SourceToFile(tmpfile, source); FrontendOptions &opts = invocation_->getFrontendOpts(); #if CLANG_VERSION_MAJOR == 3 # if CLANG_VERSION_MINOR == 0 opts.Inputs.clear(); // clear any old inputs opts.Inputs.push_back(make_pair(IK_C, tmpfile)); # elif CLANG_VERSION_MINOR == 5 opts.Inputs.clear(); // clear any old inputs opts.Inputs.push_back(FrontendInputFile(tmpfile, IK_C)); # endif #endif // compiler_->setInvocation(invocation_.get()); compiler_->setInvocation(invocation_); // Setup diagnostics for the compilation process itself #if CLANG_VERSION_MAJOR == 3 # if CLANG_VERSION_MINOR == 0 const char *const dummy_argv[] = { "" }; compiler_->createDiagnostics(1, dummy_argv); # elif CLANG_VERSION_MINOR == 5 compiler_->createDiagnostics(); # endif #endif if (!compiler_->hasDiagnostics()) { *log_stream_ << "createDiagnostics() failed\n"; return 0; } // Compile and emit LLVM IR // OwningPtr<CodeGenAction> llvm_codegen(new EmitLLVMOnlyAction(context)); CodeGenAction *llvm_codegen(new EmitLLVMOnlyAction(context)); if (!compiler_->ExecuteAction(*llvm_codegen)) { *log_stream_ << "compilation failed: " << "generated source is in " << tmpfile << "\n"; return 0; } // Remove input file and return the compiled module if (!keep_temporaries_) RemoveFile(tmpfile); return llvm_codegen->takeModule(); }
void pocl_basic_run (void *data, _cl_command_node* cmd) { struct data *d; int error; const char *module_fn; char command[COMMAND_LENGTH]; char workgroup_string[WORKGROUP_STRING_LENGTH]; unsigned device; struct pocl_argument *al; size_t x, y, z; unsigned i; pocl_workgroup w; char* tmpdir = cmd->command.run.tmp_dir; cl_kernel kernel = cmd->command.run.kernel; struct pocl_context *pc = &cmd->command.run.pc; assert (data != NULL); d = (struct data *) data; module_fn = llvm_codegen (tmpdir); d->current_dlhandle = lt_dlopen (module_fn); if (d->current_dlhandle == NULL) { printf ("pocl error: lt_dlopen(\"%s\") failed with '%s'.\n", module_fn, lt_dlerror()); printf ("note: missing symbols in the kernel binary might be reported as 'file not found' errors.\n"); abort(); } d->current_kernel = kernel; /* Find which device number within the context correspond to current device. */ for (i = 0; i < kernel->context->num_devices; ++i) { if (kernel->context->devices[i]->data == data) { device = i; break; } } snprintf (workgroup_string, WORKGROUP_STRING_LENGTH, "_%s_workgroup", kernel->function_name); w = (pocl_workgroup) lt_dlsym (d->current_dlhandle, workgroup_string); if (w == NULL) { printf("pocl error: could not load the work-group function '%s' in module '%s'.\n", workgroup_string, module_fn); abort(); } free ((void*) module_fn); void *arguments[kernel->num_args + kernel->num_locals]; /* Process the kernel arguments. Convert the opaque buffer pointers to real device pointers, allocate dynamic local memory buffers, etc. */ for (i = 0; i < kernel->num_args; ++i) { al = &(cmd->command.run.arguments[i]); if (kernel->arg_is_local[i]) { arguments[i] = malloc (sizeof (void *)); *(void **)(arguments[i]) = pocl_basic_malloc(data, 0, al->size, NULL); } else if (kernel->arg_is_pointer[i]) { /* It's legal to pass a NULL pointer to clSetKernelArguments. In that case we must pass the same NULL forward to the kernel. Otherwise, the user must have created a buffer with per device pointers stored in the cl_mem. */ if (al->value == NULL) { arguments[i] = malloc (sizeof (void *)); *(void **)arguments[i] = NULL; } else arguments[i] = &((*(cl_mem *) (al->value))->device_ptrs[device]); } else if (kernel->arg_is_image[i]) { dev_image2d_t di; cl_mem mem = *(cl_mem*)al->value; di.data = &((*(cl_mem *) (al->value))->device_ptrs[device]); di.data = ((*(cl_mem *) (al->value))->device_ptrs[device]); di.width = mem->image_width; di.height = mem->image_height; di.rowpitch = mem->image_row_pitch; di.order = mem->image_channel_order; di.data_type = mem->image_channel_data_type; void* devptr = pocl_basic_malloc(data, 0, sizeof(dev_image2d_t), NULL); arguments[i] = malloc (sizeof (void *)); *(void **)(arguments[i]) = devptr; pocl_basic_write (data, &di, devptr, sizeof(dev_image2d_t)); } else if (kernel->arg_is_sampler[i]) { dev_sampler_t ds; arguments[i] = malloc (sizeof (void *)); *(void **)(arguments[i]) = pocl_basic_malloc(data, 0, sizeof(dev_sampler_t), NULL); pocl_basic_write (data, &ds, *(void**)arguments[i], sizeof(dev_sampler_t)); } else { arguments[i] = al->value; } } for (i = kernel->num_args; i < kernel->num_args + kernel->num_locals; ++i) { al = &(cmd->command.run.arguments[i]); arguments[i] = malloc (sizeof (void *)); *(void **)(arguments[i]) = pocl_basic_malloc(data, 0, al->size, NULL); } for (z = 0; z < pc->num_groups[2]; ++z) { for (y = 0; y < pc->num_groups[1]; ++y) { for (x = 0; x < pc->num_groups[0]; ++x) { pc->group_id[0] = x; pc->group_id[1] = y; pc->group_id[2] = z; w (arguments, pc); } } } for (i = 0; i < kernel->num_args; ++i) { if (kernel->arg_is_local[i]) pocl_basic_free(data, 0, *(void **)(arguments[i])); } for (i = kernel->num_args; i < kernel->num_args + kernel->num_locals; ++i) pocl_basic_free(data, 0, *(void **)(arguments[i])); }