/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/polly/lib/Support/GICHelper.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===- GmpConv.cpp - Recreate LLVM IR from the Scop. ---------------------===// |
2 | | // |
3 | | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | | // See https://llvm.org/LICENSE.txt for license information. |
5 | | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | | // |
7 | | //===----------------------------------------------------------------------===// |
8 | | // |
9 | | // Functions for converting between gmp objects and llvm::APInt. |
10 | | // |
11 | | //===----------------------------------------------------------------------===// |
12 | | |
13 | | #include "polly/Support/GICHelper.h" |
14 | | #include "llvm/ADT/APInt.h" |
15 | | #include "isl/val.h" |
16 | | |
17 | | using namespace llvm; |
18 | | |
19 | | __isl_give isl_val *polly::isl_valFromAPInt(isl_ctx *Ctx, const APInt Int, |
20 | 20.4k | bool IsSigned) { |
21 | 20.4k | APInt Abs; |
22 | 20.4k | isl_val *v; |
23 | 20.4k | |
24 | 20.4k | // As isl is interpreting the input always as unsigned value, we need some |
25 | 20.4k | // additional pre and post processing to import signed values. The approach |
26 | 20.4k | // we take is to first obtain the absolute value of Int and then negate the |
27 | 20.4k | // value after it has been imported to isl. |
28 | 20.4k | // |
29 | 20.4k | // It should be noted that the smallest integer value represented in two's |
30 | 20.4k | // complement with a certain amount of bits does not have a corresponding |
31 | 20.4k | // positive representation in two's complement representation with the same |
32 | 20.4k | // number of bits. E.g. 110 (-2) does not have a corresponding value for (2). |
33 | 20.4k | // To ensure that there is always a corresponding value available we first |
34 | 20.4k | // sign-extend the input by one bit and only then take the absolute value. |
35 | 20.4k | if (IsSigned) |
36 | 20.4k | Abs = Int.sext(Int.getBitWidth() + 1).abs(); |
37 | 24 | else |
38 | 24 | Abs = Int; |
39 | 20.4k | |
40 | 20.4k | const uint64_t *Data = Abs.getRawData(); |
41 | 20.4k | unsigned Words = Abs.getNumWords(); |
42 | 20.4k | |
43 | 20.4k | v = isl_val_int_from_chunks(Ctx, Words, sizeof(uint64_t), Data); |
44 | 20.4k | |
45 | 20.4k | if (IsSigned && Int.isNegative()20.4k ) |
46 | 1.43k | v = isl_val_neg(v); |
47 | 20.4k | |
48 | 20.4k | return v; |
49 | 20.4k | } |
50 | | |
51 | 3.89k | APInt polly::APIntFromVal(__isl_take isl_val *Val) { |
52 | 3.89k | uint64_t *Data; |
53 | 3.89k | int NumChunks; |
54 | 3.89k | const static int ChunkSize = sizeof(uint64_t); |
55 | 3.89k | |
56 | 3.89k | assert(isl_val_is_int(Val) && "Only integers can be converted to APInt"); |
57 | 3.89k | |
58 | 3.89k | NumChunks = isl_val_n_abs_num_chunks(Val, ChunkSize); |
59 | 3.89k | Data = (uint64_t *)malloc(NumChunks * ChunkSize); |
60 | 3.89k | isl_val_get_abs_num_chunks(Val, ChunkSize, Data); |
61 | 3.89k | int NumBits = CHAR_BIT * ChunkSize * NumChunks; |
62 | 3.89k | APInt A(NumBits, NumChunks, Data); |
63 | 3.89k | |
64 | 3.89k | // As isl provides only an interface to obtain data that describes the |
65 | 3.89k | // absolute value of an isl_val, A at this point always contains a positive |
66 | 3.89k | // number. In case Val was originally negative, we expand the size of A by |
67 | 3.89k | // one and negate the value (in two's complement representation). As a result, |
68 | 3.89k | // the new value in A corresponds now with Val. |
69 | 3.89k | if (isl_val_is_neg(Val)) { |
70 | 127 | A = A.zext(A.getBitWidth() + 1); |
71 | 127 | A = -A; |
72 | 127 | } |
73 | 3.89k | |
74 | 3.89k | // isl may represent small numbers with more than the minimal number of bits. |
75 | 3.89k | // We truncate the APInt to the minimal number of bits needed to represent the |
76 | 3.89k | // signed value it contains, to ensure that the bitwidth is always minimal. |
77 | 3.89k | if (A.getMinSignedBits() < A.getBitWidth()) |
78 | 3.88k | A = A.trunc(A.getMinSignedBits()); |
79 | 3.89k | |
80 | 3.89k | free(Data); |
81 | 3.89k | isl_val_free(Val); |
82 | 3.89k | return A; |
83 | 3.89k | } |
84 | | |
85 | | template <typename ISLTy, typename ISL_CTX_GETTER, typename ISL_PRINTER> |
86 | | static inline std::string stringFromIslObjInternal(__isl_keep ISLTy *isl_obj, |
87 | | ISL_CTX_GETTER ctx_getter_fn, |
88 | 1.13k | ISL_PRINTER printer_fn) { |
89 | 1.13k | if (!isl_obj) |
90 | 0 | return "null"; |
91 | 1.13k | isl_ctx *ctx = ctx_getter_fn(isl_obj); |
92 | 1.13k | isl_printer *p = isl_printer_to_str(ctx); |
93 | 1.13k | p = printer_fn(p, isl_obj); |
94 | 1.13k | char *char_str = isl_printer_get_str(p); |
95 | 1.13k | std::string string; |
96 | 1.13k | if (char_str) |
97 | 1.13k | string = char_str; |
98 | 0 | else |
99 | 0 | string = "null"; |
100 | 1.13k | free(char_str); |
101 | 1.13k | isl_printer_free(p); |
102 | 1.13k | return string; |
103 | 1.13k | } GICHelper.cpp:std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > stringFromIslObjInternal<isl_map, isl_ctx* (*)(isl_map*), isl_printer* (*)(isl_printer*, isl_map*)>(isl_map*, isl_ctx* (*)(isl_map*), isl_printer* (*)(isl_printer*, isl_map*)) Line | Count | Source | 88 | 850 | ISL_PRINTER printer_fn) { | 89 | 850 | if (!isl_obj) | 90 | 0 | return "null"; | 91 | 850 | isl_ctx *ctx = ctx_getter_fn(isl_obj); | 92 | 850 | isl_printer *p = isl_printer_to_str(ctx); | 93 | 850 | p = printer_fn(p, isl_obj); | 94 | 850 | char *char_str = isl_printer_get_str(p); | 95 | 850 | std::string string; | 96 | 850 | if (char_str) | 97 | 850 | string = char_str; | 98 | 0 | else | 99 | 0 | string = "null"; | 100 | 850 | free(char_str); | 101 | 850 | isl_printer_free(p); | 102 | 850 | return string; | 103 | 850 | } |
GICHelper.cpp:std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > stringFromIslObjInternal<isl_set, isl_ctx* (*)(isl_set*), isl_printer* (*)(isl_printer*, isl_set*)>(isl_set*, isl_ctx* (*)(isl_set*), isl_printer* (*)(isl_printer*, isl_set*)) Line | Count | Source | 88 | 21 | ISL_PRINTER printer_fn) { | 89 | 21 | if (!isl_obj) | 90 | 0 | return "null"; | 91 | 21 | isl_ctx *ctx = ctx_getter_fn(isl_obj); | 92 | 21 | isl_printer *p = isl_printer_to_str(ctx); | 93 | 21 | p = printer_fn(p, isl_obj); | 94 | 21 | char *char_str = isl_printer_get_str(p); | 95 | 21 | std::string string; | 96 | 21 | if (char_str) | 97 | 21 | string = char_str; | 98 | 0 | else | 99 | 0 | string = "null"; | 100 | 21 | free(char_str); | 101 | 21 | isl_printer_free(p); | 102 | 21 | return string; | 103 | 21 | } |
GICHelper.cpp:std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > stringFromIslObjInternal<isl_union_map, isl_ctx* (*)(isl_union_map*), isl_printer* (*)(isl_printer*, isl_union_map*)>(isl_union_map*, isl_ctx* (*)(isl_union_map*), isl_printer* (*)(isl_printer*, isl_union_map*)) Line | Count | Source | 88 | 261 | ISL_PRINTER printer_fn) { | 89 | 261 | if (!isl_obj) | 90 | 0 | return "null"; | 91 | 261 | isl_ctx *ctx = ctx_getter_fn(isl_obj); | 92 | 261 | isl_printer *p = isl_printer_to_str(ctx); | 93 | 261 | p = printer_fn(p, isl_obj); | 94 | 261 | char *char_str = isl_printer_get_str(p); | 95 | 261 | std::string string; | 96 | 261 | if (char_str) | 97 | 261 | string = char_str; | 98 | 0 | else | 99 | 0 | string = "null"; | 100 | 261 | free(char_str); | 101 | 261 | isl_printer_free(p); | 102 | 261 | return string; | 103 | 261 | } |
Unexecuted instantiation: GICHelper.cpp:std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > stringFromIslObjInternal<isl_union_set, isl_ctx* (*)(isl_union_set*), isl_printer* (*)(isl_printer*, isl_union_set*)>(isl_union_set*, isl_ctx* (*)(isl_union_set*), isl_printer* (*)(isl_printer*, isl_union_set*)) Unexecuted instantiation: GICHelper.cpp:std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > stringFromIslObjInternal<isl_schedule, isl_ctx* (*)(isl_schedule*), isl_printer* (*)(isl_printer*, isl_schedule*)>(isl_schedule*, isl_ctx* (*)(isl_schedule*), isl_printer* (*)(isl_printer*, isl_schedule*)) Unexecuted instantiation: GICHelper.cpp:std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > stringFromIslObjInternal<isl_multi_aff, isl_ctx* (*)(isl_multi_aff*), isl_printer* (*)(isl_printer*, isl_multi_aff*)>(isl_multi_aff*, isl_ctx* (*)(isl_multi_aff*), isl_printer* (*)(isl_printer*, isl_multi_aff*)) Unexecuted instantiation: GICHelper.cpp:std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > stringFromIslObjInternal<isl_pw_multi_aff, isl_ctx* (*)(isl_pw_multi_aff*), isl_printer* (*)(isl_printer*, isl_pw_multi_aff*)>(isl_pw_multi_aff*, isl_ctx* (*)(isl_pw_multi_aff*), isl_printer* (*)(isl_printer*, isl_pw_multi_aff*)) Unexecuted instantiation: GICHelper.cpp:std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > stringFromIslObjInternal<isl_multi_pw_aff, isl_ctx* (*)(isl_multi_pw_aff*), isl_printer* (*)(isl_printer*, isl_multi_pw_aff*)>(isl_multi_pw_aff*, isl_ctx* (*)(isl_multi_pw_aff*), isl_printer* (*)(isl_printer*, isl_multi_pw_aff*)) Unexecuted instantiation: GICHelper.cpp:std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > stringFromIslObjInternal<isl_union_pw_multi_aff, isl_ctx* (*)(isl_union_pw_multi_aff*), isl_printer* (*)(isl_printer*, isl_union_pw_multi_aff*)>(isl_union_pw_multi_aff*, isl_ctx* (*)(isl_union_pw_multi_aff*), isl_printer* (*)(isl_printer*, isl_union_pw_multi_aff*)) Unexecuted instantiation: GICHelper.cpp:std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > stringFromIslObjInternal<isl_aff, isl_ctx* (*)(isl_aff*), isl_printer* (*)(isl_printer*, isl_aff*)>(isl_aff*, isl_ctx* (*)(isl_aff*), isl_printer* (*)(isl_printer*, isl_aff*)) Unexecuted instantiation: GICHelper.cpp:std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > stringFromIslObjInternal<isl_pw_aff, isl_ctx* (*)(isl_pw_aff*), isl_printer* (*)(isl_printer*, isl_pw_aff*)>(isl_pw_aff*, isl_ctx* (*)(isl_pw_aff*), isl_printer* (*)(isl_printer*, isl_pw_aff*)) Unexecuted instantiation: GICHelper.cpp:std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > stringFromIslObjInternal<isl_space, isl_ctx* (*)(isl_space*), isl_printer* (*)(isl_printer*, isl_space*)>(isl_space*, isl_ctx* (*)(isl_space*), isl_printer* (*)(isl_printer*, isl_space*)) |
104 | | |
105 | 850 | std::string polly::stringFromIslObj(__isl_keep isl_map *map) { |
106 | 850 | return stringFromIslObjInternal(map, isl_map_get_ctx, isl_printer_print_map); |
107 | 850 | } |
108 | | |
109 | 21 | std::string polly::stringFromIslObj(__isl_keep isl_set *set) { |
110 | 21 | return stringFromIslObjInternal(set, isl_set_get_ctx, isl_printer_print_set); |
111 | 21 | } |
112 | | |
113 | 261 | std::string polly::stringFromIslObj(__isl_keep isl_union_map *umap) { |
114 | 261 | return stringFromIslObjInternal(umap, isl_union_map_get_ctx, |
115 | 261 | isl_printer_print_union_map); |
116 | 261 | } |
117 | | |
118 | 0 | std::string polly::stringFromIslObj(__isl_keep isl_union_set *uset) { |
119 | 0 | return stringFromIslObjInternal(uset, isl_union_set_get_ctx, |
120 | 0 | isl_printer_print_union_set); |
121 | 0 | } |
122 | | |
123 | 0 | std::string polly::stringFromIslObj(__isl_keep isl_schedule *schedule) { |
124 | 0 | return stringFromIslObjInternal(schedule, isl_schedule_get_ctx, |
125 | 0 | isl_printer_print_schedule); |
126 | 0 | } |
127 | | |
128 | 0 | std::string polly::stringFromIslObj(__isl_keep isl_multi_aff *maff) { |
129 | 0 | return stringFromIslObjInternal(maff, isl_multi_aff_get_ctx, |
130 | 0 | isl_printer_print_multi_aff); |
131 | 0 | } |
132 | | |
133 | 0 | std::string polly::stringFromIslObj(__isl_keep isl_pw_multi_aff *pma) { |
134 | 0 | return stringFromIslObjInternal(pma, isl_pw_multi_aff_get_ctx, |
135 | 0 | isl_printer_print_pw_multi_aff); |
136 | 0 | } |
137 | | |
138 | 0 | std::string polly::stringFromIslObj(__isl_keep isl_multi_pw_aff *mpa) { |
139 | 0 | return stringFromIslObjInternal(mpa, isl_multi_pw_aff_get_ctx, |
140 | 0 | isl_printer_print_multi_pw_aff); |
141 | 0 | } |
142 | | |
143 | 0 | std::string polly::stringFromIslObj(__isl_keep isl_union_pw_multi_aff *upma) { |
144 | 0 | return stringFromIslObjInternal(upma, isl_union_pw_multi_aff_get_ctx, |
145 | 0 | isl_printer_print_union_pw_multi_aff); |
146 | 0 | } |
147 | | |
148 | 0 | std::string polly::stringFromIslObj(__isl_keep isl_aff *aff) { |
149 | 0 | return stringFromIslObjInternal(aff, isl_aff_get_ctx, isl_printer_print_aff); |
150 | 0 | } |
151 | | |
152 | 0 | std::string polly::stringFromIslObj(__isl_keep isl_pw_aff *pwaff) { |
153 | 0 | return stringFromIslObjInternal(pwaff, isl_pw_aff_get_ctx, |
154 | 0 | isl_printer_print_pw_aff); |
155 | 0 | } |
156 | | |
157 | 0 | std::string polly::stringFromIslObj(__isl_keep isl_space *space) { |
158 | 0 | return stringFromIslObjInternal(space, isl_space_get_ctx, |
159 | 0 | isl_printer_print_space); |
160 | 0 | } |
161 | | |
162 | | static void replace(std::string &str, const std::string &find, |
163 | 67.0k | const std::string &replace) { |
164 | 67.0k | size_t pos = 0; |
165 | 74.9k | while ((pos = str.find(find, pos)) != std::string::npos) { |
166 | 7.91k | str.replace(pos, find.length(), replace); |
167 | 7.91k | pos += replace.length(); |
168 | 7.91k | } |
169 | 67.0k | } |
170 | | |
171 | 13.4k | static void makeIslCompatible(std::string &str) { |
172 | 13.4k | replace(str, ".", "_"); |
173 | 13.4k | replace(str, "\"", "_"); |
174 | 13.4k | replace(str, " ", "__"); |
175 | 13.4k | replace(str, "=>", "TO"); |
176 | 13.4k | replace(str, "+", "_"); |
177 | 13.4k | } |
178 | | |
179 | | std::string polly::getIslCompatibleName(const std::string &Prefix, |
180 | | const std::string &Middle, |
181 | 13.2k | const std::string &Suffix) { |
182 | 13.2k | std::string S = Prefix + Middle + Suffix; |
183 | 13.2k | makeIslCompatible(S); |
184 | 13.2k | return S; |
185 | 13.2k | } |
186 | | |
187 | | std::string polly::getIslCompatibleName(const std::string &Prefix, |
188 | | const std::string &Name, long Number, |
189 | | const std::string &Suffix, |
190 | 122 | bool UseInstructionNames) { |
191 | 122 | std::string S = Prefix; |
192 | 122 | |
193 | 122 | if (UseInstructionNames) |
194 | 121 | S += std::string("_") + Name; |
195 | 1 | else |
196 | 1 | S += std::to_string(Number); |
197 | 122 | |
198 | 122 | S += Suffix; |
199 | 122 | |
200 | 122 | makeIslCompatible(S); |
201 | 122 | return S; |
202 | 122 | } |
203 | | |
204 | | std::string polly::getIslCompatibleName(const std::string &Prefix, |
205 | | const Value *Val, long Number, |
206 | | const std::string &Suffix, |
207 | 12.0k | bool UseInstructionNames) { |
208 | 12.0k | std::string ValStr; |
209 | 12.0k | |
210 | 12.0k | if (UseInstructionNames && Val->hasName()12.0k ) |
211 | 11.8k | ValStr = std::string("_") + std::string(Val->getName()); |
212 | 213 | else |
213 | 213 | ValStr = std::to_string(Number); |
214 | 12.0k | |
215 | 12.0k | return getIslCompatibleName(Prefix, ValStr, Suffix); |
216 | 12.0k | } |
217 | | |
218 | | #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) |
219 | | /// To call a inline dump() method in a debugger, at it must have been |
220 | | /// instantiated in at least one translation unit. Because isl's dump() method |
221 | | /// are meant to be called from a debugger only, but not from code, no such |
222 | | /// instantiation would exist. We use this method to force an instantiation in |
223 | | /// this translation unit. Because it has non-static linking, the compiler does |
224 | | /// not know that it is never called, and therefore must ensure the existence of |
225 | | /// the dump functions. |
226 | | void neverCalled() { |
227 | | isl::aff().dump(); |
228 | | isl::aff_list().dump(); |
229 | | isl::ast_expr().dump(); |
230 | | isl::ast_expr_list().dump(); |
231 | | isl::ast_node().dump(); |
232 | | isl::ast_node_list().dump(); |
233 | | isl::basic_map().dump(); |
234 | | isl::basic_map_list().dump(); |
235 | | isl::basic_set().dump(); |
236 | | isl::basic_set_list().dump(); |
237 | | isl::constraint().dump(); |
238 | | isl::constraint_list().dump(); |
239 | | isl::id().dump(); |
240 | | isl::id_list().dump(); |
241 | | isl::id_to_ast_expr().dump(); |
242 | | isl::local_space().dump(); |
243 | | isl::map().dump(); |
244 | | isl::map_list().dump(); |
245 | | isl::multi_aff().dump(); |
246 | | isl::multi_pw_aff().dump(); |
247 | | isl::multi_union_pw_aff().dump(); |
248 | | isl::multi_val().dump(); |
249 | | isl::point().dump(); |
250 | | isl::pw_aff().dump(); |
251 | | isl::pw_aff_list().dump(); |
252 | | isl::pw_multi_aff().dump(); |
253 | | isl::pw_qpolynomial().dump(); |
254 | | isl::qpolynomial().dump(); |
255 | | isl::schedule().dump(); |
256 | | isl::schedule_constraints().dump(); |
257 | | isl::schedule_node().dump(); |
258 | | isl::set().dump(); |
259 | | isl::set_list().dump(); |
260 | | isl::space().dump(); |
261 | | isl::union_map().dump(); |
262 | | isl::union_map_list().dump(); |
263 | | isl::union_pw_aff().dump(); |
264 | | isl::union_pw_aff_list().dump(); |
265 | | isl::union_pw_multi_aff().dump(); |
266 | | isl::union_pw_multi_aff_list().dump(); |
267 | | isl::union_set().dump(); |
268 | | isl::union_set_list().dump(); |
269 | | isl::val().dump(); |
270 | | isl::val_list().dump(); |
271 | | } |
272 | | #endif |