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
34namespace clover {
35   namespace llvm {
36      template<typename E> void
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
43      as_string(const std::vector<char> &v) {
44         return { v.begin(), v.end() };
45      }
46
47      struct target {
48         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
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
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