blob: 48b601334d12adec221991cae86a6d8c04aadd91 [file] [log] [blame]
Tobias Grosser75805372011-04-29 06:27:02 +00001//===- GmpConv.cpp - Recreate LLVM IR from the Scop. ---------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// Functions for converting between gmp objects and apint.
11//
12//===----------------------------------------------------------------------===//
13#include "polly/Support/GICHelper.h"
Johannes Doerfert79fc23f2014-07-24 23:48:02 +000014#include "llvm/IR/Value.h"
Hongbin Zheng454e8f92012-07-05 08:55:31 +000015#include "isl/aff.h"
Tobias Grosser83628182013-05-07 08:11:54 +000016#include "isl/map.h"
17#include "isl/schedule.h"
18#include "isl/set.h"
Hongbin Zhenga7bdd292016-02-18 15:24:42 +000019#include "isl/space.h"
Tobias Grosser83628182013-05-07 08:11:54 +000020#include "isl/union_map.h"
21#include "isl/union_set.h"
Tobias Grosseredab1352013-06-21 06:41:31 +000022#include "isl/val.h"
23
Tobias Grosser76f82792016-08-26 10:43:28 +000024#include <climits>
25
Tobias Grosser75805372011-04-29 06:27:02 +000026using namespace llvm;
27
Tobias Grosseredab1352013-06-21 06:41:31 +000028__isl_give isl_val *polly::isl_valFromAPInt(isl_ctx *Ctx, const APInt Int,
29 bool IsSigned) {
30 APInt Abs;
31 isl_val *v;
32
33 if (IsSigned)
34 Abs = Int.abs();
35 else
36 Abs = Int;
37
38 const uint64_t *Data = Abs.getRawData();
39 unsigned Words = Abs.getNumWords();
40
41 v = isl_val_int_from_chunks(Ctx, Words, sizeof(uint64_t), Data);
42
43 if (IsSigned && Int.isNegative())
44 v = isl_val_neg(v);
45
46 return v;
47}
48
Tobias Grosseredab1352013-06-21 06:41:31 +000049APInt polly::APIntFromVal(__isl_take isl_val *Val) {
50 uint64_t *Data;
51 int NumChunks;
Tobias Grosser76f82792016-08-26 10:43:28 +000052 const static int ChunkSize = sizeof(uint64_t);
Tobias Grosseredab1352013-06-21 06:41:31 +000053
Tobias Grosser76f82792016-08-26 10:43:28 +000054 assert(isl_val_is_int(Val) && "Only integers can be converted to APInt");
Tobias Grosseredab1352013-06-21 06:41:31 +000055
Tobias Grosser76f82792016-08-26 10:43:28 +000056 NumChunks = isl_val_n_abs_num_chunks(Val, ChunkSize);
57 Data = (uint64_t *)malloc(NumChunks * ChunkSize);
58 isl_val_get_abs_num_chunks(Val, ChunkSize, Data);
59 int NumBits = CHAR_BIT * ChunkSize * NumChunks;
60 APInt A(NumBits, NumChunks, Data);
Tobias Grosseredab1352013-06-21 06:41:31 +000061
Tobias Grosser76f82792016-08-26 10:43:28 +000062 // As isl provides only an interface to obtain data that describes the
63 // absolute value of an isl_val, A at this point always contains a positive
64 // number. In case Val was originally negative, we expand the size of A by
65 // one and negate the value (in two's complement representation). As a result,
66 // the new value in A corresponds now with Val.
Tobias Grosseredab1352013-06-21 06:41:31 +000067 if (isl_val_is_neg(Val)) {
68 A = A.zext(A.getBitWidth() + 1);
69 A = -A;
70 }
71
Tobias Grosser76f82792016-08-26 10:43:28 +000072 // isl may represent small numbers with more than the minimal number of bits.
73 // We truncate the APInt to the minimal number of bits needed to represent the
74 // signed value it contains, to ensure that the bitwidth is always minimal.
Tobias Grosseredab1352013-06-21 06:41:31 +000075 if (A.getMinSignedBits() < A.getBitWidth())
76 A = A.trunc(A.getMinSignedBits());
77
78 free(Data);
79 isl_val_free(Val);
80 return A;
81}
82
Tobias Grosserde49b8f2013-02-22 08:21:52 +000083template <typename ISLTy, typename ISL_CTX_GETTER, typename ISL_PRINTER>
Tobias Grossere602a072013-05-07 07:30:56 +000084static inline std::string stringFromIslObjInternal(__isl_keep ISLTy *isl_obj,
85 ISL_CTX_GETTER ctx_getter_fn,
86 ISL_PRINTER printer_fn) {
Michael Kruseb8d26442015-12-13 19:35:26 +000087 if (!isl_obj)
88 return "null";
Hongbin Zheng5205e0c2012-07-05 08:42:39 +000089 isl_ctx *ctx = ctx_getter_fn(isl_obj);
90 isl_printer *p = isl_printer_to_str(ctx);
91 printer_fn(p, isl_obj);
Tobias Grosser15f5eff2011-08-20 11:11:18 +000092 char *char_str = isl_printer_get_str(p);
Tobias Grosserb43cc622015-11-10 15:09:44 +000093 std::string string;
94 if (char_str)
95 string = char_str;
96 else
97 string = "null";
Tobias Grosser15f5eff2011-08-20 11:11:18 +000098 free(char_str);
Tobias Grosser75805372011-04-29 06:27:02 +000099 isl_printer_free(p);
100 return string;
101}
102
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000103std::string polly::stringFromIslObj(__isl_keep isl_map *map) {
104 return stringFromIslObjInternal(map, isl_map_get_ctx, isl_printer_print_map);
Hongbin Zheng5205e0c2012-07-05 08:42:39 +0000105}
106
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000107std::string polly::stringFromIslObj(__isl_keep isl_set *set) {
108 return stringFromIslObjInternal(set, isl_set_get_ctx, isl_printer_print_set);
Tobias Grosser75805372011-04-29 06:27:02 +0000109}
110
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000111std::string polly::stringFromIslObj(__isl_keep isl_union_map *umap) {
Hongbin Zheng5205e0c2012-07-05 08:42:39 +0000112 return stringFromIslObjInternal(umap, isl_union_map_get_ctx,
113 isl_printer_print_union_map);
Tobias Grosser75805372011-04-29 06:27:02 +0000114}
115
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000116std::string polly::stringFromIslObj(__isl_keep isl_union_set *uset) {
Hongbin Zheng5205e0c2012-07-05 08:42:39 +0000117 return stringFromIslObjInternal(uset, isl_union_set_get_ctx,
118 isl_printer_print_union_set);
Tobias Grosser75805372011-04-29 06:27:02 +0000119}
Tobias Grosserde68cc92011-06-30 20:01:02 +0000120
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000121std::string polly::stringFromIslObj(__isl_keep isl_schedule *schedule) {
Tobias Grosser6a629c52014-11-21 19:39:42 +0000122 return stringFromIslObjInternal(schedule, isl_schedule_get_ctx,
Hongbin Zheng5205e0c2012-07-05 08:42:39 +0000123 isl_printer_print_schedule);
Tobias Grosserde68cc92011-06-30 20:01:02 +0000124}
Hongbin Zheng454e8f92012-07-05 08:55:31 +0000125
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000126std::string polly::stringFromIslObj(__isl_keep isl_multi_aff *maff) {
Hongbin Zheng454e8f92012-07-05 08:55:31 +0000127 return stringFromIslObjInternal(maff, isl_multi_aff_get_ctx,
128 isl_printer_print_multi_aff);
129}
130
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000131std::string polly::stringFromIslObj(__isl_keep isl_pw_multi_aff *pma) {
Hongbin Zheng454e8f92012-07-05 08:55:31 +0000132 return stringFromIslObjInternal(pma, isl_pw_multi_aff_get_ctx,
133 isl_printer_print_pw_multi_aff);
134}
135
Hongbin Zheng2ac7ee72016-02-20 03:40:19 +0000136std::string polly::stringFromIslObj(__isl_keep isl_union_pw_multi_aff *upma) {
137 return stringFromIslObjInternal(upma, isl_union_pw_multi_aff_get_ctx,
138 isl_printer_print_union_pw_multi_aff);
139}
140
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000141std::string polly::stringFromIslObj(__isl_keep isl_aff *aff) {
Hongbin Zheng454e8f92012-07-05 08:55:31 +0000142 return stringFromIslObjInternal(aff, isl_aff_get_ctx, isl_printer_print_aff);
143}
144
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000145std::string polly::stringFromIslObj(__isl_keep isl_pw_aff *pwaff) {
Hongbin Zheng454e8f92012-07-05 08:55:31 +0000146 return stringFromIslObjInternal(pwaff, isl_pw_aff_get_ctx,
147 isl_printer_print_pw_aff);
148}
Johannes Doerfert79fc23f2014-07-24 23:48:02 +0000149
Hongbin Zhenga7bdd292016-02-18 15:24:42 +0000150std::string polly::stringFromIslObj(__isl_keep isl_space *space) {
151 return stringFromIslObjInternal(space, isl_space_get_ctx,
152 isl_printer_print_space);
153}
154
Johannes Doerfert79fc23f2014-07-24 23:48:02 +0000155static void replace(std::string &str, const std::string &find,
156 const std::string &replace) {
157 size_t pos = 0;
158 while ((pos = str.find(find, pos)) != std::string::npos) {
159 str.replace(pos, find.length(), replace);
160 pos += replace.length();
161 }
162}
163
164static void makeIslCompatible(std::string &str) {
165 replace(str, ".", "_");
166 replace(str, "\"", "_");
Tobias Grosser16c44032015-07-09 07:31:45 +0000167 replace(str, " ", "__");
168 replace(str, "=>", "TO");
Johannes Doerfert79fc23f2014-07-24 23:48:02 +0000169}
170
Johannes Doerfert3a7e8122015-02-19 18:09:39 +0000171std::string polly::getIslCompatibleName(const std::string &Prefix,
172 const std::string &Middle,
173 const std::string &Suffix) {
174 std::string S = Prefix + Middle + Suffix;
175 makeIslCompatible(S);
176 return S;
177}
178
Tobias Grosserf567e1a2015-02-19 22:16:12 +0000179std::string polly::getIslCompatibleName(const std::string &Prefix,
180 const Value *Val,
Johannes Doerfert3a7e8122015-02-19 18:09:39 +0000181 const std::string &Suffix) {
Johannes Doerfert79fc23f2014-07-24 23:48:02 +0000182 std::string ValStr;
183 raw_string_ostream OS(ValStr);
184 Val->printAsOperand(OS, false);
185 ValStr = OS.str();
186 // Remove the leading %
187 ValStr.erase(0, 1);
Johannes Doerfert3a7e8122015-02-19 18:09:39 +0000188 return getIslCompatibleName(Prefix, ValStr, Suffix);
Johannes Doerfert79fc23f2014-07-24 23:48:02 +0000189}