blob: e3a59993aecae54247c9d8fbeea2c10c32b778ec [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
Tobias Grosser43720002016-08-26 12:01:07 +000033 // As isl is interpreting the input always as unsigned value, we need some
34 // additional pre and post processing to import signed values. The approach
35 // we take is to first obtain the absolute value of Int and then negate the
36 // value after it has been imported to isl.
37 //
38 // It should be noted that the smallest integer value represented in two's
39 // complement with a certain amount of bits does not have a corresponding
40 // positive representation in two's complement representation with the same
41 // number of bits. E.g. 110 (-2) does not have a corresponding value for (2).
42 // To ensure that there is always a corresponding value available we first
43 // sign-extend the input by one bit and only then take the absolute value.
Tobias Grosseredab1352013-06-21 06:41:31 +000044 if (IsSigned)
Tobias Grosser43720002016-08-26 12:01:07 +000045 Abs = Int.sext(Int.getBitWidth() + 1).abs();
Tobias Grosseredab1352013-06-21 06:41:31 +000046 else
47 Abs = Int;
48
49 const uint64_t *Data = Abs.getRawData();
50 unsigned Words = Abs.getNumWords();
51
52 v = isl_val_int_from_chunks(Ctx, Words, sizeof(uint64_t), Data);
53
54 if (IsSigned && Int.isNegative())
55 v = isl_val_neg(v);
56
57 return v;
58}
59
Tobias Grosseredab1352013-06-21 06:41:31 +000060APInt polly::APIntFromVal(__isl_take isl_val *Val) {
61 uint64_t *Data;
62 int NumChunks;
Tobias Grosser76f82792016-08-26 10:43:28 +000063 const static int ChunkSize = sizeof(uint64_t);
Tobias Grosseredab1352013-06-21 06:41:31 +000064
Tobias Grosser76f82792016-08-26 10:43:28 +000065 assert(isl_val_is_int(Val) && "Only integers can be converted to APInt");
Tobias Grosseredab1352013-06-21 06:41:31 +000066
Tobias Grosser76f82792016-08-26 10:43:28 +000067 NumChunks = isl_val_n_abs_num_chunks(Val, ChunkSize);
68 Data = (uint64_t *)malloc(NumChunks * ChunkSize);
69 isl_val_get_abs_num_chunks(Val, ChunkSize, Data);
70 int NumBits = CHAR_BIT * ChunkSize * NumChunks;
71 APInt A(NumBits, NumChunks, Data);
Tobias Grosseredab1352013-06-21 06:41:31 +000072
Tobias Grosser76f82792016-08-26 10:43:28 +000073 // As isl provides only an interface to obtain data that describes the
74 // absolute value of an isl_val, A at this point always contains a positive
75 // number. In case Val was originally negative, we expand the size of A by
76 // one and negate the value (in two's complement representation). As a result,
77 // the new value in A corresponds now with Val.
Tobias Grosseredab1352013-06-21 06:41:31 +000078 if (isl_val_is_neg(Val)) {
79 A = A.zext(A.getBitWidth() + 1);
80 A = -A;
81 }
82
Tobias Grosser76f82792016-08-26 10:43:28 +000083 // isl may represent small numbers with more than the minimal number of bits.
84 // We truncate the APInt to the minimal number of bits needed to represent the
85 // signed value it contains, to ensure that the bitwidth is always minimal.
Tobias Grosseredab1352013-06-21 06:41:31 +000086 if (A.getMinSignedBits() < A.getBitWidth())
87 A = A.trunc(A.getMinSignedBits());
88
89 free(Data);
90 isl_val_free(Val);
91 return A;
92}
93
Tobias Grosserde49b8f2013-02-22 08:21:52 +000094template <typename ISLTy, typename ISL_CTX_GETTER, typename ISL_PRINTER>
Tobias Grossere602a072013-05-07 07:30:56 +000095static inline std::string stringFromIslObjInternal(__isl_keep ISLTy *isl_obj,
96 ISL_CTX_GETTER ctx_getter_fn,
97 ISL_PRINTER printer_fn) {
Michael Kruseb8d26442015-12-13 19:35:26 +000098 if (!isl_obj)
99 return "null";
Hongbin Zheng5205e0c2012-07-05 08:42:39 +0000100 isl_ctx *ctx = ctx_getter_fn(isl_obj);
101 isl_printer *p = isl_printer_to_str(ctx);
102 printer_fn(p, isl_obj);
Tobias Grosser15f5eff2011-08-20 11:11:18 +0000103 char *char_str = isl_printer_get_str(p);
Tobias Grosserb43cc622015-11-10 15:09:44 +0000104 std::string string;
105 if (char_str)
106 string = char_str;
107 else
108 string = "null";
Tobias Grosser15f5eff2011-08-20 11:11:18 +0000109 free(char_str);
Tobias Grosser75805372011-04-29 06:27:02 +0000110 isl_printer_free(p);
111 return string;
112}
113
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000114std::string polly::stringFromIslObj(__isl_keep isl_map *map) {
115 return stringFromIslObjInternal(map, isl_map_get_ctx, isl_printer_print_map);
Hongbin Zheng5205e0c2012-07-05 08:42:39 +0000116}
117
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000118std::string polly::stringFromIslObj(__isl_keep isl_set *set) {
119 return stringFromIslObjInternal(set, isl_set_get_ctx, isl_printer_print_set);
Tobias Grosser75805372011-04-29 06:27:02 +0000120}
121
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000122std::string polly::stringFromIslObj(__isl_keep isl_union_map *umap) {
Hongbin Zheng5205e0c2012-07-05 08:42:39 +0000123 return stringFromIslObjInternal(umap, isl_union_map_get_ctx,
124 isl_printer_print_union_map);
Tobias Grosser75805372011-04-29 06:27:02 +0000125}
126
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000127std::string polly::stringFromIslObj(__isl_keep isl_union_set *uset) {
Hongbin Zheng5205e0c2012-07-05 08:42:39 +0000128 return stringFromIslObjInternal(uset, isl_union_set_get_ctx,
129 isl_printer_print_union_set);
Tobias Grosser75805372011-04-29 06:27:02 +0000130}
Tobias Grosserde68cc92011-06-30 20:01:02 +0000131
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000132std::string polly::stringFromIslObj(__isl_keep isl_schedule *schedule) {
Tobias Grosser6a629c52014-11-21 19:39:42 +0000133 return stringFromIslObjInternal(schedule, isl_schedule_get_ctx,
Hongbin Zheng5205e0c2012-07-05 08:42:39 +0000134 isl_printer_print_schedule);
Tobias Grosserde68cc92011-06-30 20:01:02 +0000135}
Hongbin Zheng454e8f92012-07-05 08:55:31 +0000136
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000137std::string polly::stringFromIslObj(__isl_keep isl_multi_aff *maff) {
Hongbin Zheng454e8f92012-07-05 08:55:31 +0000138 return stringFromIslObjInternal(maff, isl_multi_aff_get_ctx,
139 isl_printer_print_multi_aff);
140}
141
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000142std::string polly::stringFromIslObj(__isl_keep isl_pw_multi_aff *pma) {
Hongbin Zheng454e8f92012-07-05 08:55:31 +0000143 return stringFromIslObjInternal(pma, isl_pw_multi_aff_get_ctx,
144 isl_printer_print_pw_multi_aff);
145}
146
Hongbin Zheng2ac7ee72016-02-20 03:40:19 +0000147std::string polly::stringFromIslObj(__isl_keep isl_union_pw_multi_aff *upma) {
148 return stringFromIslObjInternal(upma, isl_union_pw_multi_aff_get_ctx,
149 isl_printer_print_union_pw_multi_aff);
150}
151
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000152std::string polly::stringFromIslObj(__isl_keep isl_aff *aff) {
Hongbin Zheng454e8f92012-07-05 08:55:31 +0000153 return stringFromIslObjInternal(aff, isl_aff_get_ctx, isl_printer_print_aff);
154}
155
Tobias Grosserde49b8f2013-02-22 08:21:52 +0000156std::string polly::stringFromIslObj(__isl_keep isl_pw_aff *pwaff) {
Hongbin Zheng454e8f92012-07-05 08:55:31 +0000157 return stringFromIslObjInternal(pwaff, isl_pw_aff_get_ctx,
158 isl_printer_print_pw_aff);
159}
Johannes Doerfert79fc23f2014-07-24 23:48:02 +0000160
Hongbin Zhenga7bdd292016-02-18 15:24:42 +0000161std::string polly::stringFromIslObj(__isl_keep isl_space *space) {
162 return stringFromIslObjInternal(space, isl_space_get_ctx,
163 isl_printer_print_space);
164}
165
Johannes Doerfert79fc23f2014-07-24 23:48:02 +0000166static void replace(std::string &str, const std::string &find,
167 const std::string &replace) {
168 size_t pos = 0;
169 while ((pos = str.find(find, pos)) != std::string::npos) {
170 str.replace(pos, find.length(), replace);
171 pos += replace.length();
172 }
173}
174
175static void makeIslCompatible(std::string &str) {
176 replace(str, ".", "_");
177 replace(str, "\"", "_");
Tobias Grosser16c44032015-07-09 07:31:45 +0000178 replace(str, " ", "__");
179 replace(str, "=>", "TO");
Johannes Doerfert79fc23f2014-07-24 23:48:02 +0000180}
181
Johannes Doerfert3a7e8122015-02-19 18:09:39 +0000182std::string polly::getIslCompatibleName(const std::string &Prefix,
183 const std::string &Middle,
184 const std::string &Suffix) {
185 std::string S = Prefix + Middle + Suffix;
186 makeIslCompatible(S);
187 return S;
188}
189
Tobias Grosserf567e1a2015-02-19 22:16:12 +0000190std::string polly::getIslCompatibleName(const std::string &Prefix,
191 const Value *Val,
Johannes Doerfert3a7e8122015-02-19 18:09:39 +0000192 const std::string &Suffix) {
Johannes Doerfert79fc23f2014-07-24 23:48:02 +0000193 std::string ValStr;
194 raw_string_ostream OS(ValStr);
195 Val->printAsOperand(OS, false);
196 ValStr = OS.str();
197 // Remove the leading %
198 ValStr.erase(0, 1);
Johannes Doerfert3a7e8122015-02-19 18:09:39 +0000199 return getIslCompatibleName(Prefix, ValStr, Suffix);
Johannes Doerfert79fc23f2014-07-24 23:48:02 +0000200}