Revert "clover: Fix build after llvm r221375"
[mesa.git] / src / gallium / state_trackers / clover / llvm / invocation.cpp
1 //
2 // Copyright 2012 Francisco Jerez
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining a
5 // copy of this software and associated documentation files (the "Software"),
6 // to deal in the Software without restriction, including without limitation
7 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 // and/or sell copies of the Software, and to permit persons to whom the
9 // Software is furnished to do so, subject to the following conditions:
10 //
11 // The above copyright notice and this permission notice shall be included in
12 // all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 // OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 // OTHER DEALINGS IN THE SOFTWARE.
21 //
22
23 #include "core/compiler.hpp"
24
25 #include <clang/Frontend/CompilerInstance.h>
26 #include <clang/Frontend/TextDiagnosticBuffer.h>
27 #include <clang/Frontend/TextDiagnosticPrinter.h>
28 #include <clang/CodeGen/CodeGenAction.h>
29 #include <clang/Basic/TargetInfo.h>
30 #include <llvm/Bitcode/BitstreamWriter.h>
31 #include <llvm/Bitcode/ReaderWriter.h>
32 #if HAVE_LLVM < 0x0305
33 #include <llvm/Linker.h>
34 #else
35 #include <llvm/Linker/Linker.h>
36 #include <llvm/IR/DiagnosticInfo.h>
37 #include <llvm/IR/DiagnosticPrinter.h>
38 #endif
39 #include <llvm/IR/DerivedTypes.h>
40 #include <llvm/IR/LLVMContext.h>
41 #include <llvm/IR/Module.h>
42 #include <llvm/Support/SourceMgr.h>
43 #include <llvm/IRReader/IRReader.h>
44 #if HAVE_LLVM < 0x0305
45 #include <llvm/ADT/OwningPtr.h>
46 #endif
47 #include <llvm/PassManager.h>
48 #include <llvm/Support/CodeGen.h>
49 #include <llvm/Support/TargetSelect.h>
50 #include <llvm/Support/MemoryBuffer.h>
51 #include <llvm/Support/FormattedStream.h>
52 #include <llvm/Support/TargetRegistry.h>
53 #include <llvm/Transforms/IPO.h>
54 #include <llvm/Transforms/IPO/PassManagerBuilder.h>
55 #include <llvm/Transforms/Utils/Cloning.h>
56
57
58 #include <llvm/IR/DataLayout.h>
59 #include <llvm/Target/TargetLibraryInfo.h>
60 #include <llvm/Target/TargetMachine.h>
61 #include <llvm/Target/TargetOptions.h>
62
63 #include <llvm-c/Target.h>
64 #include <llvm-c/TargetMachine.h>
65 #include <llvm-c/Core.h>
66
67 #include "pipe/p_state.h"
68 #include "util/u_memory.h"
69 #include "util/u_math.h"
70
71 #include <iostream>
72 #include <iomanip>
73 #include <fstream>
74 #include <cstdio>
75 #include <sstream>
76 #include <libelf.h>
77 #include <gelf.h>
78
79 using namespace clover;
80
81 namespace {
82 #if 0
83 void
84 build_binary(const std::string &source, const std::string &target,
85 const std::string &name) {
86 clang::CompilerInstance c;
87 clang::EmitObjAction act(&llvm::getGlobalContext());
88 std::string log;
89 llvm::raw_string_ostream s_log(log);
90
91 LLVMInitializeTGSITarget();
92 LLVMInitializeTGSITargetInfo();
93 LLVMInitializeTGSITargetMC();
94 LLVMInitializeTGSIAsmPrinter();
95
96 c.getFrontendOpts().Inputs.push_back(
97 std::make_pair(clang::IK_OpenCL, name));
98 c.getHeaderSearchOpts().UseBuiltinIncludes = false;
99 c.getHeaderSearchOpts().UseStandardIncludes = false;
100 c.getLangOpts().NoBuiltin = true;
101 c.getTargetOpts().Triple = target;
102 c.getInvocation().setLangDefaults(clang::IK_OpenCL);
103 c.createDiagnostics(0, NULL, new clang::TextDiagnosticPrinter(
104 s_log, c.getDiagnosticOpts()));
105
106 c.getPreprocessorOpts().addRemappedFile(
107 name, llvm::MemoryBuffer::getMemBuffer(source));
108
109 if (!c.ExecuteAction(act))
110 throw build_error(log);
111 }
112
113 module
114 load_binary(const char *name) {
115 std::ifstream fs((name));
116 std::vector<unsigned char> str((std::istreambuf_iterator<char>(fs)),
117 (std::istreambuf_iterator<char>()));
118 compat::istream cs(str);
119 return module::deserialize(cs);
120 }
121 #endif
122 void debug_log(const std::string &msg, const std::string &suffix) {
123 const char *dbg_file = debug_get_option("CLOVER_DEBUG_FILE", "stderr");
124 if (!strcmp("stderr", dbg_file)) {
125 std::cerr << msg;
126 } else {
127 std::ofstream file(dbg_file + suffix, std::ios::app);
128 file << msg;
129 }
130 }
131
132 llvm::Module *
133 compile_llvm(llvm::LLVMContext &llvm_ctx, const std::string &source,
134 const header_map &headers,
135 const std::string &name, const std::string &triple,
136 const std::string &processor, const std::string &opts,
137 clang::LangAS::Map& address_spaces, unsigned &optimization_level,
138 compat::string &r_log) {
139
140 clang::CompilerInstance c;
141 clang::EmitLLVMOnlyAction act(&llvm_ctx);
142 std::string log;
143 llvm::raw_string_ostream s_log(log);
144 std::string libclc_path = LIBCLC_LIBEXECDIR + processor + "-"
145 + triple + ".bc";
146
147 // Parse the compiler options:
148 std::vector<std::string> opts_array;
149 std::istringstream ss(opts);
150
151 while (!ss.eof()) {
152 std::string opt;
153 getline(ss, opt, ' ');
154 opts_array.push_back(opt);
155 }
156
157 opts_array.push_back(name);
158
159 std::vector<const char *> opts_carray;
160 for (unsigned i = 0; i < opts_array.size(); i++) {
161 opts_carray.push_back(opts_array.at(i).c_str());
162 }
163
164 llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> DiagID;
165 llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> DiagOpts;
166 clang::TextDiagnosticBuffer *DiagsBuffer;
167
168 DiagID = new clang::DiagnosticIDs();
169 DiagOpts = new clang::DiagnosticOptions();
170 DiagsBuffer = new clang::TextDiagnosticBuffer();
171
172 clang::DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagsBuffer);
173 bool Success;
174
175 Success = clang::CompilerInvocation::CreateFromArgs(c.getInvocation(),
176 opts_carray.data(),
177 opts_carray.data() + opts_carray.size(),
178 Diags);
179 if (!Success) {
180 throw error(CL_INVALID_BUILD_OPTIONS);
181 }
182 c.getFrontendOpts().ProgramAction = clang::frontend::EmitLLVMOnly;
183 c.getHeaderSearchOpts().UseBuiltinIncludes = true;
184 c.getHeaderSearchOpts().UseStandardSystemIncludes = true;
185 c.getHeaderSearchOpts().ResourceDir = CLANG_RESOURCE_DIR;
186
187 // Add libclc generic search path
188 c.getHeaderSearchOpts().AddPath(LIBCLC_INCLUDEDIR,
189 clang::frontend::Angled,
190 false, false
191 );
192
193 // Add libclc include
194 c.getPreprocessorOpts().Includes.push_back("clc/clc.h");
195
196 // clc.h requires that this macro be defined:
197 c.getPreprocessorOpts().addMacroDef("cl_clang_storage_class_specifiers");
198 c.getPreprocessorOpts().addMacroDef("cl_khr_fp64");
199
200 c.getLangOpts().NoBuiltin = true;
201 c.getTargetOpts().Triple = triple;
202 c.getTargetOpts().CPU = processor;
203
204 // This is a workaround for a Clang bug which causes the number
205 // of warnings and errors to be printed to stderr.
206 // http://www.llvm.org/bugs/show_bug.cgi?id=19735
207 c.getDiagnosticOpts().ShowCarets = false;
208 c.getInvocation().setLangDefaults(c.getLangOpts(), clang::IK_OpenCL,
209 clang::LangStandard::lang_opencl11);
210 c.createDiagnostics(
211 new clang::TextDiagnosticPrinter(
212 s_log,
213 &c.getDiagnosticOpts()));
214
215 #if HAVE_LLVM >= 0x0306
216 c.getPreprocessorOpts().addRemappedFile(name,
217 llvm::MemoryBuffer::getMemBuffer(source).release());
218 #else
219 c.getPreprocessorOpts().addRemappedFile(name,
220 llvm::MemoryBuffer::getMemBuffer(source));
221 #endif
222
223 if (headers.size()) {
224 const std::string tmp_header_path = "/tmp/clover/";
225
226 c.getHeaderSearchOpts().AddPath(tmp_header_path,
227 clang::frontend::Angled,
228 false, false
229 );
230
231 for (header_map::const_iterator it = headers.begin();
232 it != headers.end(); ++it) {
233 const std::string path = tmp_header_path + std::string(it->first);
234 c.getPreprocessorOpts().addRemappedFile(path,
235 #if HAVE_LLVM >= 0x0306
236 llvm::MemoryBuffer::getMemBuffer(it->second.c_str()).release());
237 #else
238 llvm::MemoryBuffer::getMemBuffer(it->second.c_str()));
239 #endif
240 }
241 }
242
243 // Setting this attribute tells clang to link this file before
244 // performing any optimizations. This is required so that
245 // we can replace calls to the OpenCL C barrier() builtin
246 // with calls to target intrinsics that have the noduplicate
247 // attribute. This attribute will prevent Clang from creating
248 // illegal uses of barrier() (e.g. Moving barrier() inside a conditional
249 // that is no executed by all threads) during its optimizaton passes.
250 c.getCodeGenOpts().LinkBitcodeFile = libclc_path;
251
252 optimization_level = c.getCodeGenOpts().OptimizationLevel;
253
254 // Compile the code
255 bool ExecSuccess = c.ExecuteAction(act);
256 r_log = log;
257
258 if (!ExecSuccess)
259 throw build_error();
260
261 // Get address spaces map to be able to find kernel argument address space
262 memcpy(address_spaces, c.getTarget().getAddressSpaceMap(),
263 sizeof(address_spaces));
264
265 #if HAVE_LLVM >= 0x0306
266 return act.takeModule().release();
267 #else
268 return act.takeModule();
269 #endif
270 }
271
272 void
273 find_kernels(llvm::Module *mod, std::vector<llvm::Function *> &kernels) {
274 const llvm::NamedMDNode *kernel_node =
275 mod->getNamedMetadata("opencl.kernels");
276 // This means there are no kernels in the program. The spec does not
277 // require that we return an error here, but there will be an error if
278 // the user tries to pass this program to a clCreateKernel() call.
279 if (!kernel_node) {
280 return;
281 }
282
283 for (unsigned i = 0; i < kernel_node->getNumOperands(); ++i) {
284 kernels.push_back(llvm::dyn_cast<llvm::Function>(
285 kernel_node->getOperand(i)->getOperand(0)));
286 }
287 }
288
289 void
290 optimize(llvm::Module *mod, unsigned optimization_level,
291 const std::vector<llvm::Function *> &kernels) {
292
293 llvm::PassManager PM;
294 // Add a function internalizer pass.
295 //
296 // By default, the function internalizer pass will look for a function
297 // called "main" and then mark all other functions as internal. Marking
298 // functions as internal enables the optimizer to perform optimizations
299 // like function inlining and global dead-code elimination.
300 //
301 // When there is no "main" function in a module, the internalize pass will
302 // treat the module like a library, and it won't internalize any functions.
303 // Since there is no "main" function in our kernels, we need to tell
304 // the internalizer pass that this module is not a library by passing a
305 // list of kernel functions to the internalizer. The internalizer will
306 // treat the functions in the list as "main" functions and internalize
307 // all of the other functions.
308 std::vector<const char*> export_list;
309 for (std::vector<llvm::Function *>::const_iterator I = kernels.begin(),
310 E = kernels.end();
311 I != E; ++I) {
312 llvm::Function *kernel = *I;
313 export_list.push_back(kernel->getName().data());
314 }
315 #if HAVE_LLVM < 0x0305
316 PM.add(new llvm::DataLayout(mod));
317 #elif HAVE_LLVM < 0x0306
318 PM.add(new llvm::DataLayoutPass(mod));
319 #else
320 PM.add(new llvm::DataLayoutPass());
321 #endif
322 PM.add(llvm::createInternalizePass(export_list));
323
324 llvm::PassManagerBuilder PMB;
325 PMB.OptLevel = optimization_level;
326 PMB.LibraryInfo = new llvm::TargetLibraryInfo(
327 llvm::Triple(mod->getTargetTriple()));
328 PMB.populateModulePassManager(PM);
329 PM.run(*mod);
330 }
331
332 compat::vector<module::argument>
333 get_kernel_args(const llvm::Module *mod, const std::string &kernel_name,
334 const clang::LangAS::Map &address_spaces) {
335
336 compat::vector<module::argument> args;
337 llvm::Function *kernel_func = mod->getFunction(kernel_name);
338
339 #if HAVE_LLVM < 0x0305
340 llvm::DataLayout TD(kernel_func->getParent()->getDataLayout());
341 #else
342 llvm::DataLayout TD(mod);
343 #endif
344
345 for (llvm::Function::const_arg_iterator I = kernel_func->arg_begin(),
346 E = kernel_func->arg_end(); I != E; ++I) {
347 const llvm::Argument &arg = *I;
348
349 llvm::Type *arg_type = arg.getType();
350 const unsigned arg_store_size = TD.getTypeStoreSize(arg_type);
351
352 // OpenCL 1.2 specification, Ch. 6.1.5: "A built-in data
353 // type that is not a power of two bytes in size must be
354 // aligned to the next larger power of two". We need this
355 // alignment for three element vectors, which have
356 // non-power-of-2 store size.
357 const unsigned arg_api_size = util_next_power_of_two(arg_store_size);
358
359 llvm::Type *target_type = arg_type->isIntegerTy() ?
360 TD.getSmallestLegalIntType(mod->getContext(), arg_store_size * 8)
361 : arg_type;
362 unsigned target_size = TD.getTypeStoreSize(target_type);
363 unsigned target_align = TD.getABITypeAlignment(target_type);
364
365 if (llvm::isa<llvm::PointerType>(arg_type) && arg.hasByValAttr()) {
366 arg_type =
367 llvm::dyn_cast<llvm::PointerType>(arg_type)->getElementType();
368 }
369
370 if (arg_type->isPointerTy()) {
371 unsigned address_space = llvm::cast<llvm::PointerType>(arg_type)->getAddressSpace();
372 if (address_space == address_spaces[clang::LangAS::opencl_local
373 - clang::LangAS::Offset]) {
374 args.push_back(module::argument(module::argument::local,
375 arg_api_size, target_size,
376 target_align,
377 module::argument::zero_ext));
378 } else {
379 // XXX: Correctly handle constant address space. There is no
380 // way for r600g to pass a handle for constant buffers back
381 // to clover like it can for global buffers, so
382 // creating constant arguments will break r600g. For now,
383 // continue treating constant buffers as global buffers
384 // until we can come up with a way to create handles for
385 // constant buffers.
386 args.push_back(module::argument(module::argument::global,
387 arg_api_size, target_size,
388 target_align,
389 module::argument::zero_ext));
390 }
391
392 } else {
393 llvm::AttributeSet attrs = kernel_func->getAttributes();
394 enum module::argument::ext_type ext_type =
395 (attrs.hasAttribute(arg.getArgNo() + 1,
396 llvm::Attribute::SExt) ?
397 module::argument::sign_ext :
398 module::argument::zero_ext);
399
400 args.push_back(
401 module::argument(module::argument::scalar, arg_api_size,
402 target_size, target_align, ext_type));
403 }
404 }
405
406 // Append implicit arguments. XXX - The types, ordering and
407 // vector size of the implicit arguments should depend on the
408 // target according to the selected calling convention.
409 llvm::Type *size_type =
410 TD.getSmallestLegalIntType(mod->getContext(), sizeof(cl_uint) * 8);
411
412 args.push_back(
413 module::argument(module::argument::scalar, sizeof(cl_uint),
414 TD.getTypeStoreSize(size_type),
415 TD.getABITypeAlignment(size_type),
416 module::argument::zero_ext,
417 module::argument::grid_dimension));
418
419 args.push_back(
420 module::argument(module::argument::scalar, sizeof(cl_uint),
421 TD.getTypeStoreSize(size_type),
422 TD.getABITypeAlignment(size_type),
423 module::argument::zero_ext,
424 module::argument::grid_offset));
425
426 return args;
427 }
428
429 module
430 build_module_llvm(llvm::Module *mod,
431 const std::vector<llvm::Function *> &kernels,
432 clang::LangAS::Map& address_spaces) {
433
434 module m;
435 struct pipe_llvm_program_header header;
436
437 llvm::SmallVector<char, 1024> llvm_bitcode;
438 llvm::raw_svector_ostream bitcode_ostream(llvm_bitcode);
439 llvm::BitstreamWriter writer(llvm_bitcode);
440 llvm::WriteBitcodeToFile(mod, bitcode_ostream);
441 bitcode_ostream.flush();
442
443 for (unsigned i = 0; i < kernels.size(); ++i) {
444 std::string kernel_name = kernels[i]->getName();
445 compat::vector<module::argument> args =
446 get_kernel_args(mod, kernel_name, address_spaces);
447
448 m.syms.push_back(module::symbol(kernel_name, 0, i, args ));
449 }
450
451 header.num_bytes = llvm_bitcode.size();
452 std::string data;
453 data.insert(0, (char*)(&header), sizeof(header));
454 data.insert(data.end(), llvm_bitcode.begin(),
455 llvm_bitcode.end());
456 m.secs.push_back(module::section(0, module::section::text,
457 header.num_bytes, data));
458
459 return m;
460 }
461
462 void
463 emit_code(LLVMTargetMachineRef tm, LLVMModuleRef mod,
464 LLVMCodeGenFileType file_type,
465 LLVMMemoryBufferRef *out_buffer,
466 compat::string &r_log) {
467 LLVMBool err;
468 char *err_message = NULL;
469
470 err = LLVMTargetMachineEmitToMemoryBuffer(tm, mod, file_type,
471 &err_message, out_buffer);
472
473 if (err) {
474 r_log = std::string(err_message);
475 }
476
477 LLVMDisposeMessage(err_message);
478
479 if (err) {
480 throw build_error();
481 }
482 }
483
484 std::vector<char>
485 compile_native(const llvm::Module *mod, const std::string &triple,
486 const std::string &processor, unsigned dump_asm,
487 compat::string &r_log) {
488
489 std::string log;
490 LLVMTargetRef target;
491 char *error_message;
492 LLVMMemoryBufferRef out_buffer;
493 unsigned buffer_size;
494 const char *buffer_data;
495 LLVMModuleRef mod_ref = wrap(mod);
496
497 if (LLVMGetTargetFromTriple(triple.c_str(), &target, &error_message)) {
498 r_log = std::string(error_message);
499 LLVMDisposeMessage(error_message);
500 throw build_error();
501 }
502
503 LLVMTargetMachineRef tm = LLVMCreateTargetMachine(
504 target, triple.c_str(), processor.c_str(), "",
505 LLVMCodeGenLevelDefault, LLVMRelocDefault, LLVMCodeModelDefault);
506
507 if (!tm) {
508 r_log = "Could not create TargetMachine: " + triple;
509 throw build_error();
510 }
511
512 if (dump_asm) {
513 LLVMSetTargetMachineAsmVerbosity(tm, true);
514 LLVMModuleRef debug_mod = wrap(llvm::CloneModule(mod));
515 emit_code(tm, debug_mod, LLVMAssemblyFile, &out_buffer, r_log);
516 buffer_size = LLVMGetBufferSize(out_buffer);
517 buffer_data = LLVMGetBufferStart(out_buffer);
518 debug_log(std::string(buffer_data, buffer_size), ".asm");
519
520 LLVMSetTargetMachineAsmVerbosity(tm, false);
521 LLVMDisposeMemoryBuffer(out_buffer);
522 LLVMDisposeModule(debug_mod);
523 }
524
525 emit_code(tm, mod_ref, LLVMObjectFile, &out_buffer, r_log);
526
527 buffer_size = LLVMGetBufferSize(out_buffer);
528 buffer_data = LLVMGetBufferStart(out_buffer);
529
530 std::vector<char> code(buffer_data, buffer_data + buffer_size);
531
532 LLVMDisposeMemoryBuffer(out_buffer);
533 LLVMDisposeTargetMachine(tm);
534
535 return code;
536 }
537
538 std::map<std::string, unsigned>
539 get_kernel_offsets(std::vector<char> &code,
540 const std::vector<llvm::Function *> &kernels,
541 compat::string &r_log) {
542
543 // One of the libelf implementations
544 // (http://www.mr511.de/software/english.htm) requires calling
545 // elf_version() before elf_memory().
546 //
547 elf_version(EV_CURRENT);
548
549 Elf *elf = elf_memory(&code[0], code.size());
550 size_t section_str_index;
551 elf_getshdrstrndx(elf, &section_str_index);
552 Elf_Scn *section = NULL;
553 Elf_Scn *symtab = NULL;
554 GElf_Shdr symtab_header;
555
556 // Find the symbol table
557 try {
558 while ((section = elf_nextscn(elf, section))) {
559 const char *name;
560 if (gelf_getshdr(section, &symtab_header) != &symtab_header) {
561 r_log = "Failed to read ELF section header.";
562 throw build_error();
563 }
564 name = elf_strptr(elf, section_str_index, symtab_header.sh_name);
565 if (!strcmp(name, ".symtab")) {
566 symtab = section;
567 break;
568 }
569 }
570 if (!symtab) {
571 r_log = "Unable to find symbol table.";
572 throw build_error();
573 }
574 } catch (build_error &e) {
575 elf_end(elf);
576 throw e;
577 }
578
579
580 // Extract symbol information from the table
581 Elf_Data *symtab_data = NULL;
582 GElf_Sym *symbol;
583 GElf_Sym s;
584
585 std::map<std::string, unsigned> kernel_offsets;
586 symtab_data = elf_getdata(symtab, symtab_data);
587
588 // Determine the offsets for each kernel
589 for (int i = 0; (symbol = gelf_getsym(symtab_data, i, &s)); i++) {
590 char *name = elf_strptr(elf, symtab_header.sh_link, symbol->st_name);
591 for (std::vector<llvm::Function*>::const_iterator it = kernels.begin(),
592 e = kernels.end(); it != e; ++it) {
593 llvm::Function *f = *it;
594 if (f->getName() == std::string(name))
595 kernel_offsets[f->getName()] = symbol->st_value;
596 }
597 }
598 elf_end(elf);
599 return kernel_offsets;
600 }
601
602 module
603 build_module_native(std::vector<char> &code,
604 const llvm::Module *mod,
605 const std::vector<llvm::Function *> &kernels,
606 const clang::LangAS::Map &address_spaces,
607 compat::string &r_log) {
608
609 std::map<std::string, unsigned> kernel_offsets =
610 get_kernel_offsets(code, kernels, r_log);
611
612 // Begin building the clover module
613 module m;
614 struct pipe_llvm_program_header header;
615
616 // Store the generated ELF binary in the module's text section.
617 header.num_bytes = code.size();
618 std::string data;
619 data.append((char*)(&header), sizeof(header));
620 data.append(code.begin(), code.end());
621 m.secs.push_back(module::section(0, module::section::text,
622 header.num_bytes, data));
623
624 for (std::map<std::string, unsigned>::iterator i = kernel_offsets.begin(),
625 e = kernel_offsets.end(); i != e; ++i) {
626 compat::vector<module::argument> args =
627 get_kernel_args(mod, i->first, address_spaces);
628 m.syms.push_back(module::symbol(i->first, 0, i->second, args ));
629 }
630
631 return m;
632 }
633
634 #if HAVE_LLVM >= 0x0305
635
636 void
637 diagnostic_handler(const llvm::DiagnosticInfo &di, void *data) {
638 if (di.getSeverity() == llvm::DS_Error) {
639 std::string message = *(compat::string*)data;
640 llvm::raw_string_ostream stream(message);
641 llvm::DiagnosticPrinterRawOStream dp(stream);
642 di.print(dp);
643 stream.flush();
644 *(compat::string*)data = message;
645
646 throw build_error();
647 }
648 }
649
650 #endif
651
652 void
653 init_targets() {
654 static bool targets_initialized = false;
655 if (!targets_initialized) {
656 LLVMInitializeAllTargets();
657 LLVMInitializeAllTargetInfos();
658 LLVMInitializeAllTargetMCs();
659 LLVMInitializeAllAsmPrinters();
660 targets_initialized = true;
661 }
662 }
663 } // End anonymous namespace
664
665 #define DBG_CLC (1 << 0)
666 #define DBG_LLVM (1 << 1)
667 #define DBG_ASM (1 << 2)
668
669 static const struct debug_named_value debug_options[] = {
670 {"clc", DBG_CLC, "Dump the OpenCL C code for all kernels."},
671 {"llvm", DBG_LLVM, "Dump the generated LLVM IR for all kernels."},
672 {"asm", DBG_ASM, "Dump kernel assembly code for targets specifying "
673 "PIPE_SHADER_IR_NATIVE"},
674 DEBUG_NAMED_VALUE_END // must be last
675 };
676
677 module
678 clover::compile_program_llvm(const compat::string &source,
679 const header_map &headers,
680 enum pipe_shader_ir ir,
681 const compat::string &target,
682 const compat::string &opts,
683 compat::string &r_log) {
684
685 init_targets();
686 static unsigned debug_flags = debug_get_flags_option("CLOVER_DEBUG",
687 debug_options, 0);
688
689 std::vector<llvm::Function *> kernels;
690 size_t processor_str_len = std::string(target.begin()).find_first_of("-");
691 std::string processor(target.begin(), 0, processor_str_len);
692 std::string triple(target.begin(), processor_str_len + 1,
693 target.size() - processor_str_len - 1);
694 clang::LangAS::Map address_spaces;
695 llvm::LLVMContext llvm_ctx;
696 unsigned optimization_level;
697
698 #if HAVE_LLVM >= 0x0305
699 llvm_ctx.setDiagnosticHandler(diagnostic_handler, &r_log);
700 #endif
701
702 // The input file name must have the .cl extension in order for the
703 // CompilerInvocation class to recognize it as an OpenCL source file.
704 llvm::Module *mod = compile_llvm(llvm_ctx, source, headers, "input.cl",
705 triple, processor, opts, address_spaces,
706 optimization_level, r_log);
707
708 find_kernels(mod, kernels);
709
710 optimize(mod, optimization_level, kernels);
711
712 if (debug_flags & DBG_CLC)
713 debug_log(source, ".cl");
714
715 if (debug_flags & DBG_LLVM) {
716 std::string log;
717 llvm::raw_string_ostream s_log(log);
718 mod->print(s_log, NULL);
719 s_log.flush();
720 debug_log(log, ".ll");
721 }
722
723 module m;
724 // Build the clover::module
725 switch (ir) {
726 case PIPE_SHADER_IR_TGSI:
727 //XXX: Handle TGSI
728 assert(0);
729 m = module();
730 break;
731 case PIPE_SHADER_IR_LLVM:
732 m = build_module_llvm(mod, kernels, address_spaces);
733 break;
734 case PIPE_SHADER_IR_NATIVE: {
735 std::vector<char> code = compile_native(mod, triple, processor,
736 debug_flags & DBG_ASM, r_log);
737 m = build_module_native(code, mod, kernels, address_spaces, r_log);
738 break;
739 }
740 }
741 #if HAVE_LLVM >= 0x0306
742 // LLVM 3.6 and newer, the user takes ownership of the module.
743 delete mod;
744 #endif
745
746 return m;
747 }