1 //
2 // Copyright 2012-2016 Francisco Jerez
3 // Copyright 2012-2016 Advanced Micro Devices, Inc.
4 //
5 // Permission is hereby granted, free of charge, to any person obtaining a
6 // copy of this software and associated documentation files (the "Software"),
7 // to deal in the Software without restriction, including without limitation
8 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 // and/or sell copies of the Software, and to permit persons to whom the
10 // Software is furnished to do so, subject to the following conditions:
11 //
12 // The above copyright notice and this permission notice shall be included in
13 // all copies or substantial portions of the Software.
14 //
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
19 // OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21 // OTHER DEALINGS IN THE SOFTWARE.
22 //
23 
24 #ifndef CLOVER_LLVM_UTIL_HPP
25 #define CLOVER_LLVM_UTIL_HPP
26 
27 #include "core/error.hpp"
28 #include "util/u_debug.h"
29 
30 #include <vector>
31 #include <fstream>
32 #include <iostream>
33 
34 namespace clover {
35    namespace llvm {
36       template<typename E> void
fail(std::string & r_log,E && e,const std::string & s)37       fail(std::string &r_log, E &&e, const std::string &s) {
38          r_log += s;
39          throw std::forward<E>(e);
40       }
41 
42       inline std::string
as_string(const std::vector<char> & v)43       as_string(const std::vector<char> &v) {
44          return { v.begin(), v.end() };
45       }
46 
47       struct target {
targetclover::llvm::target48          target(const std::string &s) :
49             cpu(s.begin(), s.begin() + s.find_first_of("-")),
50             triple(s.begin() + s.find_first_of("-") + 1, s.end()) {}
51 
52          std::string cpu;
53          std::string triple;
54       };
55 
56       namespace debug {
57          enum flag {
58             clc = 1 << 0,
59             llvm = 1 << 1,
60             native = 1 << 2,
61             spirv = 1 << 3,
62          };
63 
64          inline bool
has_flag(flag f)65          has_flag(flag f) {
66             static const struct debug_named_value debug_options[] = {
67                { "clc", clc, "Dump the OpenCL C code for all kernels." },
68                { "llvm", llvm, "Dump the generated LLVM IR for all kernels." },
69                { "native", native, "Dump kernel assembly code for targets "
70                  "specifying PIPE_SHADER_IR_NATIVE" },
71                { "spirv", spirv, "Dump the generated SPIR-V for all kernels." },
72                DEBUG_NAMED_VALUE_END
73             };
74             static const unsigned flags =
75                debug_get_flags_option("CLOVER_DEBUG", debug_options, 0);
76 
77             return flags & f;
78          }
79 
80          inline void
log(const std::string & suffix,const std::string & s)81          log(const std::string &suffix, const std::string &s) {
82             const std::string path = debug_get_option("CLOVER_DEBUG_FILE",
83                                                       "stderr");
84             if (path == "stderr")
85                std::cerr << s;
86             else
87                std::ofstream(path + suffix, std::ios::app) << s;
88          }
89       }
90    }
91 }
92 
93 #endif
94