1 //===- 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" 14 #include "llvm/IR/Value.h" 15 #include "isl/aff.h" 16 #include "isl/map.h" 17 #include "isl/schedule.h" 18 #include "isl/set.h" 19 #include "isl/space.h" 20 #include "isl/union_map.h" 21 #include "isl/union_set.h" 22 #include "isl/val.h" 23 24 using namespace llvm; 25 26 __isl_give isl_val *polly::isl_valFromAPInt(isl_ctx *Ctx, const APInt Int, 27 bool IsSigned) { 28 APInt Abs; 29 isl_val *v; 30 31 if (IsSigned) 32 Abs = Int.abs(); 33 else 34 Abs = Int; 35 36 const uint64_t *Data = Abs.getRawData(); 37 unsigned Words = Abs.getNumWords(); 38 39 v = isl_val_int_from_chunks(Ctx, Words, sizeof(uint64_t), Data); 40 41 if (IsSigned && Int.isNegative()) 42 v = isl_val_neg(v); 43 44 return v; 45 } 46 47 APInt polly::APIntFromVal(__isl_take isl_val *Val) { 48 uint64_t *Data; 49 int NumChunks; 50 51 NumChunks = isl_val_n_abs_num_chunks(Val, sizeof(uint64_t)); 52 53 Data = (uint64_t *)malloc(NumChunks * sizeof(uint64_t)); 54 isl_val_get_abs_num_chunks(Val, sizeof(uint64_t), Data); 55 APInt A(8 * sizeof(uint64_t) * NumChunks, NumChunks, Data); 56 57 if (isl_val_is_neg(Val)) { 58 A = A.zext(A.getBitWidth() + 1); 59 A = -A; 60 } 61 62 if (A.getMinSignedBits() < A.getBitWidth()) 63 A = A.trunc(A.getMinSignedBits()); 64 65 free(Data); 66 isl_val_free(Val); 67 return A; 68 } 69 70 template <typename ISLTy, typename ISL_CTX_GETTER, typename ISL_PRINTER> 71 static inline std::string stringFromIslObjInternal(__isl_keep ISLTy *isl_obj, 72 ISL_CTX_GETTER ctx_getter_fn, 73 ISL_PRINTER printer_fn) { 74 if (!isl_obj) 75 return "null"; 76 isl_ctx *ctx = ctx_getter_fn(isl_obj); 77 isl_printer *p = isl_printer_to_str(ctx); 78 printer_fn(p, isl_obj); 79 char *char_str = isl_printer_get_str(p); 80 std::string string; 81 if (char_str) 82 string = char_str; 83 else 84 string = "null"; 85 free(char_str); 86 isl_printer_free(p); 87 return string; 88 } 89 90 std::string polly::stringFromIslObj(__isl_keep isl_map *map) { 91 return stringFromIslObjInternal(map, isl_map_get_ctx, isl_printer_print_map); 92 } 93 94 std::string polly::stringFromIslObj(__isl_keep isl_set *set) { 95 return stringFromIslObjInternal(set, isl_set_get_ctx, isl_printer_print_set); 96 } 97 98 std::string polly::stringFromIslObj(__isl_keep isl_union_map *umap) { 99 return stringFromIslObjInternal(umap, isl_union_map_get_ctx, 100 isl_printer_print_union_map); 101 } 102 103 std::string polly::stringFromIslObj(__isl_keep isl_union_set *uset) { 104 return stringFromIslObjInternal(uset, isl_union_set_get_ctx, 105 isl_printer_print_union_set); 106 } 107 108 std::string polly::stringFromIslObj(__isl_keep isl_schedule *schedule) { 109 return stringFromIslObjInternal(schedule, isl_schedule_get_ctx, 110 isl_printer_print_schedule); 111 } 112 113 std::string polly::stringFromIslObj(__isl_keep isl_multi_aff *maff) { 114 return stringFromIslObjInternal(maff, isl_multi_aff_get_ctx, 115 isl_printer_print_multi_aff); 116 } 117 118 std::string polly::stringFromIslObj(__isl_keep isl_pw_multi_aff *pma) { 119 return stringFromIslObjInternal(pma, isl_pw_multi_aff_get_ctx, 120 isl_printer_print_pw_multi_aff); 121 } 122 123 std::string polly::stringFromIslObj(__isl_keep isl_union_pw_multi_aff *upma) { 124 return stringFromIslObjInternal(upma, isl_union_pw_multi_aff_get_ctx, 125 isl_printer_print_union_pw_multi_aff); 126 } 127 128 std::string polly::stringFromIslObj(__isl_keep isl_aff *aff) { 129 return stringFromIslObjInternal(aff, isl_aff_get_ctx, isl_printer_print_aff); 130 } 131 132 std::string polly::stringFromIslObj(__isl_keep isl_pw_aff *pwaff) { 133 return stringFromIslObjInternal(pwaff, isl_pw_aff_get_ctx, 134 isl_printer_print_pw_aff); 135 } 136 137 std::string polly::stringFromIslObj(__isl_keep isl_space *space) { 138 return stringFromIslObjInternal(space, isl_space_get_ctx, 139 isl_printer_print_space); 140 } 141 142 static void replace(std::string &str, const std::string &find, 143 const std::string &replace) { 144 size_t pos = 0; 145 while ((pos = str.find(find, pos)) != std::string::npos) { 146 str.replace(pos, find.length(), replace); 147 pos += replace.length(); 148 } 149 } 150 151 static void makeIslCompatible(std::string &str) { 152 replace(str, ".", "_"); 153 replace(str, "\"", "_"); 154 replace(str, " ", "__"); 155 replace(str, "=>", "TO"); 156 } 157 158 std::string polly::getIslCompatibleName(const std::string &Prefix, 159 const std::string &Middle, 160 const std::string &Suffix) { 161 std::string S = Prefix + Middle + Suffix; 162 makeIslCompatible(S); 163 return S; 164 } 165 166 std::string polly::getIslCompatibleName(const std::string &Prefix, 167 const Value *Val, 168 const std::string &Suffix) { 169 std::string ValStr; 170 raw_string_ostream OS(ValStr); 171 Val->printAsOperand(OS, false); 172 ValStr = OS.str(); 173 // Remove the leading % 174 ValStr.erase(0, 1); 175 return getIslCompatibleName(Prefix, ValStr, Suffix); 176 } 177