1 //===- GmpConv.cpp - Recreate LLVM IR from the Scop. ---------------------===//
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
7 //===----------------------------------------------------------------------===//
9 // Functions for converting between gmp objects and llvm::APInt.
11 //===----------------------------------------------------------------------===//
13 #include "polly/Support/GICHelper.h"
14 #include "llvm/ADT/APInt.h"
19 __isl_give isl_val
*polly::isl_valFromAPInt(isl_ctx
*Ctx
, const APInt Int
,
24 // As isl is interpreting the input always as unsigned value, we need some
25 // additional pre and post processing to import signed values. The approach
26 // we take is to first obtain the absolute value of Int and then negate the
27 // value after it has been imported to isl.
29 // It should be noted that the smallest integer value represented in two's
30 // complement with a certain amount of bits does not have a corresponding
31 // positive representation in two's complement representation with the same
32 // number of bits. E.g. 110 (-2) does not have a corresponding value for (2).
33 // To ensure that there is always a corresponding value available we first
34 // sign-extend the input by one bit and only then take the absolute value.
36 Abs
= Int
.sext(Int
.getBitWidth() + 1).abs();
40 const uint64_t *Data
= Abs
.getRawData();
41 unsigned Words
= Abs
.getNumWords();
43 v
= isl_val_int_from_chunks(Ctx
, Words
, sizeof(uint64_t), Data
);
45 if (IsSigned
&& Int
.isNegative())
51 APInt
polly::APIntFromVal(__isl_take isl_val
*Val
) {
54 const static int ChunkSize
= sizeof(uint64_t);
56 assert(isl_val_is_int(Val
) && "Only integers can be converted to APInt");
58 NumChunks
= isl_val_n_abs_num_chunks(Val
, ChunkSize
);
59 Data
= (uint64_t *)malloc(NumChunks
* ChunkSize
);
60 isl_val_get_abs_num_chunks(Val
, ChunkSize
, Data
);
61 int NumBits
= CHAR_BIT
* ChunkSize
* NumChunks
;
62 APInt
A(NumBits
, NumChunks
, Data
);
64 // As isl provides only an interface to obtain data that describes the
65 // absolute value of an isl_val, A at this point always contains a positive
66 // number. In case Val was originally negative, we expand the size of A by
67 // one and negate the value (in two's complement representation). As a result,
68 // the new value in A corresponds now with Val.
69 if (isl_val_is_neg(Val
)) {
70 A
= A
.zext(A
.getBitWidth() + 1);
74 // isl may represent small numbers with more than the minimal number of bits.
75 // We truncate the APInt to the minimal number of bits needed to represent the
76 // signed value it contains, to ensure that the bitwidth is always minimal.
77 if (A
.getMinSignedBits() < A
.getBitWidth())
78 A
= A
.trunc(A
.getMinSignedBits());
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 ISL_PRINTER printer_fn
) {
91 isl_ctx
*ctx
= ctx_getter_fn(isl_obj
);
92 isl_printer
*p
= isl_printer_to_str(ctx
);
93 p
= printer_fn(p
, isl_obj
);
94 char *char_str
= isl_printer_get_str(p
);
105 std::string
polly::stringFromIslObj(__isl_keep isl_map
*map
) {
106 return stringFromIslObjInternal(map
, isl_map_get_ctx
, isl_printer_print_map
);
109 std::string
polly::stringFromIslObj(__isl_keep isl_set
*set
) {
110 return stringFromIslObjInternal(set
, isl_set_get_ctx
, isl_printer_print_set
);
113 std::string
polly::stringFromIslObj(__isl_keep isl_union_map
*umap
) {
114 return stringFromIslObjInternal(umap
, isl_union_map_get_ctx
,
115 isl_printer_print_union_map
);
118 std::string
polly::stringFromIslObj(__isl_keep isl_union_set
*uset
) {
119 return stringFromIslObjInternal(uset
, isl_union_set_get_ctx
,
120 isl_printer_print_union_set
);
123 std::string
polly::stringFromIslObj(__isl_keep isl_schedule
*schedule
) {
124 return stringFromIslObjInternal(schedule
, isl_schedule_get_ctx
,
125 isl_printer_print_schedule
);
128 std::string
polly::stringFromIslObj(__isl_keep isl_multi_aff
*maff
) {
129 return stringFromIslObjInternal(maff
, isl_multi_aff_get_ctx
,
130 isl_printer_print_multi_aff
);
133 std::string
polly::stringFromIslObj(__isl_keep isl_pw_multi_aff
*pma
) {
134 return stringFromIslObjInternal(pma
, isl_pw_multi_aff_get_ctx
,
135 isl_printer_print_pw_multi_aff
);
138 std::string
polly::stringFromIslObj(__isl_keep isl_multi_pw_aff
*mpa
) {
139 return stringFromIslObjInternal(mpa
, isl_multi_pw_aff_get_ctx
,
140 isl_printer_print_multi_pw_aff
);
143 std::string
polly::stringFromIslObj(__isl_keep isl_union_pw_multi_aff
*upma
) {
144 return stringFromIslObjInternal(upma
, isl_union_pw_multi_aff_get_ctx
,
145 isl_printer_print_union_pw_multi_aff
);
148 std::string
polly::stringFromIslObj(__isl_keep isl_aff
*aff
) {
149 return stringFromIslObjInternal(aff
, isl_aff_get_ctx
, isl_printer_print_aff
);
152 std::string
polly::stringFromIslObj(__isl_keep isl_pw_aff
*pwaff
) {
153 return stringFromIslObjInternal(pwaff
, isl_pw_aff_get_ctx
,
154 isl_printer_print_pw_aff
);
157 std::string
polly::stringFromIslObj(__isl_keep isl_space
*space
) {
158 return stringFromIslObjInternal(space
, isl_space_get_ctx
,
159 isl_printer_print_space
);
162 static void replace(std::string
&str
, const std::string
&find
,
163 const std::string
&replace
) {
165 while ((pos
= str
.find(find
, pos
)) != std::string::npos
) {
166 str
.replace(pos
, find
.length(), replace
);
167 pos
+= replace
.length();
171 static void makeIslCompatible(std::string
&str
) {
172 replace(str
, ".", "_");
173 replace(str
, "\"", "_");
174 replace(str
, " ", "__");
175 replace(str
, "=>", "TO");
176 replace(str
, "+", "_");
179 std::string
polly::getIslCompatibleName(const std::string
&Prefix
,
180 const std::string
&Middle
,
181 const std::string
&Suffix
) {
182 std::string S
= Prefix
+ Middle
+ Suffix
;
183 makeIslCompatible(S
);
187 std::string
polly::getIslCompatibleName(const std::string
&Prefix
,
188 const std::string
&Name
, long Number
,
189 const std::string
&Suffix
,
190 bool UseInstructionNames
) {
191 std::string S
= Prefix
;
193 if (UseInstructionNames
)
194 S
+= std::string("_") + Name
;
196 S
+= std::to_string(Number
);
200 makeIslCompatible(S
);
204 std::string
polly::getIslCompatibleName(const std::string
&Prefix
,
205 const Value
*Val
, long Number
,
206 const std::string
&Suffix
,
207 bool UseInstructionNames
) {
210 if (UseInstructionNames
&& Val
->hasName())
211 ValStr
= std::string("_") + std::string(Val
->getName());
213 ValStr
= std::to_string(Number
);
215 return getIslCompatibleName(Prefix
, ValStr
, Suffix
);
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.
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();
240 isl::id_list().dump();
241 isl::id_to_ast_expr().dump();
242 isl::local_space().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();
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();
259 isl::set_list().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();
270 isl::val_list().dump();