Coverage Report

Created: 2017-10-03 07:32

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/tools/polly/include/polly/Support/GICHelper.h
Line
Count
Source (jump to first uncovered line)
1
//===- Support/GICHelper.h -- Helper functions for ISL --------------------===//
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
// Helper functions for isl objects.
11
//
12
//===----------------------------------------------------------------------===//
13
//
14
#ifndef POLLY_SUPPORT_GIC_HELPER_H
15
#define POLLY_SUPPORT_GIC_HELPER_H
16
17
#include "llvm/ADT/APInt.h"
18
#include "llvm/IR/DiagnosticInfo.h"
19
#include "llvm/Support/raw_ostream.h"
20
#include "isl/aff.h"
21
#include "isl/ctx.h"
22
#include "isl/isl-noexceptions.h"
23
#include "isl/map.h"
24
#include "isl/options.h"
25
#include "isl/set.h"
26
#include "isl/union_map.h"
27
#include "isl/union_set.h"
28
#include <functional>
29
#include <string>
30
31
struct isl_schedule;
32
struct isl_multi_aff;
33
34
namespace llvm {
35
class Value;
36
} // namespace llvm
37
38
namespace polly {
39
40
/// Translate an llvm::APInt to an isl_val.
41
///
42
/// Translate the bitsequence without sign information as provided by APInt into
43
/// a signed isl_val type. Depending on the value of @p IsSigned @p Int is
44
/// interpreted as unsigned value or as signed value in two's complement
45
/// representation.
46
///
47
/// Input IsSigned                 Output
48
///
49
///     0        0           ->    0
50
///     1        0           ->    1
51
///    00        0           ->    0
52
///    01        0           ->    1
53
///    10        0           ->    2
54
///    11        0           ->    3
55
///
56
///     0        1           ->    0
57
///     1        1           ->   -1
58
///    00        1           ->    0
59
///    01        1           ->    1
60
///    10        1           ->   -2
61
///    11        1           ->   -1
62
///
63
/// @param Ctx      The isl_ctx to create the isl_val in.
64
/// @param Int      The integer value to translate.
65
/// @param IsSigned If the APInt should be interpreted as signed or unsigned
66
///                 value.
67
///
68
/// @return The isl_val corresponding to @p Int.
69
__isl_give isl_val *isl_valFromAPInt(isl_ctx *Ctx, const llvm::APInt Int,
70
                                     bool IsSigned);
71
72
/// Translate an llvm::APInt to an isl::val.
73
///
74
/// Translate the bitsequence without sign information as provided by APInt into
75
/// a signed isl::val type. Depending on the value of @p IsSigned @p Int is
76
/// interpreted as unsigned value or as signed value in two's complement
77
/// representation.
78
///
79
/// Input IsSigned                 Output
80
///
81
///     0        0           ->    0
82
///     1        0           ->    1
83
///    00        0           ->    0
84
///    01        0           ->    1
85
///    10        0           ->    2
86
///    11        0           ->    3
87
///
88
///     0        1           ->    0
89
///     1        1           ->   -1
90
///    00        1           ->    0
91
///    01        1           ->    1
92
///    10        1           ->   -2
93
///    11        1           ->   -1
94
///
95
/// @param Ctx      The isl_ctx to create the isl::val in.
96
/// @param Int      The integer value to translate.
97
/// @param IsSigned If the APInt should be interpreted as signed or unsigned
98
///                 value.
99
///
100
/// @return The isl::val corresponding to @p Int.
101
inline isl::val valFromAPInt(isl_ctx *Ctx, const llvm::APInt Int,
102
2.41k
                             bool IsSigned) {
103
2.41k
  return isl::manage(isl_valFromAPInt(Ctx, Int, IsSigned));
104
2.41k
}
105
106
/// Translate isl_val to llvm::APInt.
107
///
108
/// This function can only be called on isl_val values which are integers.
109
/// Calling this function with a non-integral rational, NaN or infinity value
110
/// is not allowed.
111
///
112
/// As the input isl_val may be negative, the APInt that this function returns
113
/// must always be interpreted as signed two's complement value. The bitwidth of
114
/// the generated APInt is always the minimal bitwidth necessary to model the
115
/// provided integer when interpreting the bit pattern as signed value.
116
///
117
/// Some example conversions are:
118
///
119
///   Input      Bits    Signed  Bitwidth
120
///       0 ->      0         0         1
121
///      -1 ->      1        -1         1
122
///       1 ->     01         1         2
123
///      -2 ->     10        -2         2
124
///       2 ->    010         2         3
125
///      -3 ->    101        -3         3
126
///       3 ->    011         3         3
127
///      -4 ->    100        -4         3
128
///       4 ->   0100         4         4
129
///
130
/// @param Val The isl val to translate.
131
///
132
/// @return The APInt value corresponding to @p Val.
133
llvm::APInt APIntFromVal(__isl_take isl_val *Val);
134
135
/// Translate isl::val to llvm::APInt.
136
///
137
/// This function can only be called on isl::val values which are integers.
138
/// Calling this function with a non-integral rational, NaN or infinity value
139
/// is not allowed.
140
///
141
/// As the input isl::val may be negative, the APInt that this function returns
142
/// must always be interpreted as signed two's complement value. The bitwidth of
143
/// the generated APInt is always the minimal bitwidth necessary to model the
144
/// provided integer when interpreting the bit pattern as signed value.
145
///
146
/// Some example conversions are:
147
///
148
///   Input      Bits    Signed  Bitwidth
149
///       0 ->      0         0         1
150
///      -1 ->      1        -1         1
151
///       1 ->     01         1         2
152
///      -2 ->     10        -2         2
153
///       2 ->    010         2         3
154
///      -3 ->    101        -3         3
155
///       3 ->    011         3         3
156
///      -4 ->    100        -4         3
157
///       4 ->   0100         4         4
158
///
159
/// @param Val The isl val to translate.
160
///
161
/// @return The APInt value corresponding to @p Val.
162
911
inline llvm::APInt APIntFromVal(isl::val V) {
163
911
  return APIntFromVal(V.release());
164
911
}
165
166
/// Get c++ string from Isl objects.
167
//@{
168
std::string stringFromIslObj(__isl_keep isl_map *map);
169
std::string stringFromIslObj(__isl_keep isl_union_map *umap);
170
std::string stringFromIslObj(__isl_keep isl_set *set);
171
std::string stringFromIslObj(__isl_keep isl_union_set *uset);
172
std::string stringFromIslObj(__isl_keep isl_schedule *schedule);
173
std::string stringFromIslObj(__isl_keep isl_multi_aff *maff);
174
std::string stringFromIslObj(__isl_keep isl_pw_multi_aff *pma);
175
std::string stringFromIslObj(__isl_keep isl_multi_pw_aff *mpa);
176
std::string stringFromIslObj(__isl_keep isl_union_pw_multi_aff *upma);
177
std::string stringFromIslObj(__isl_keep isl_aff *aff);
178
std::string stringFromIslObj(__isl_keep isl_pw_aff *pwaff);
179
std::string stringFromIslObj(__isl_keep isl_space *space);
180
//@}
181
182
inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
183
244
                                     __isl_keep isl_union_map *Map) {
184
244
  OS << polly::stringFromIslObj(Map);
185
244
  return OS;
186
244
}
187
188
inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
189
0
                                     __isl_keep isl_map *Map) {
190
0
  OS << polly::stringFromIslObj(Map);
191
0
  return OS;
192
0
}
193
194
inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
195
1.59k
                                     __isl_keep isl_set *Set) {
196
1.59k
  OS << polly::stringFromIslObj(Set);
197
1.59k
  return OS;
198
1.59k
}
199
200
inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
201
0
                                     __isl_keep isl_pw_aff *Map) {
202
0
  OS << polly::stringFromIslObj(Map);
203
0
  return OS;
204
0
}
205
206
inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
207
532
                                     __isl_keep isl_pw_multi_aff *PMA) {
208
532
  OS << polly::stringFromIslObj(PMA);
209
532
  return OS;
210
532
}
211
212
inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
213
0
                                     __isl_keep isl_multi_aff *MA) {
214
0
  OS << polly::stringFromIslObj(MA);
215
0
  return OS;
216
0
}
217
218
inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
219
0
                                     __isl_keep isl_union_pw_multi_aff *UPMA) {
220
0
  OS << polly::stringFromIslObj(UPMA);
221
0
  return OS;
222
0
}
223
224
inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
225
0
                                     __isl_keep isl_schedule *Schedule) {
226
0
  OS << polly::stringFromIslObj(Schedule);
227
0
  return OS;
228
0
}
229
230
inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
231
0
                                     __isl_keep isl_space *Space) {
232
0
  OS << polly::stringFromIslObj(Space);
233
0
  return OS;
234
0
}
235
236
/// Combine Prefix, Val (or Number) and Suffix to an isl-compatible name.
237
///
238
/// In case @p UseInstructionNames is set, this function returns:
239
///
240
/// @p Prefix + "_" + @p Val->getName() + @p Suffix
241
///
242
/// otherwise
243
///
244
/// @p Prefix + to_string(Number) + @p Suffix
245
///
246
/// We ignore the value names by default, as they may change between release
247
/// and debug mode and can consequently not be used when aiming for reproducible
248
/// builds. However, for debugging named statements are often helpful, hence
249
/// we allow their optional use.
250
std::string getIslCompatibleName(const std::string &Prefix,
251
                                 const llvm::Value *Val, long Number,
252
                                 const std::string &Suffix,
253
                                 bool UseInstructionNames);
254
255
/// Combine Prefix, Name (or Number) and Suffix to an isl-compatible name.
256
///
257
/// In case @p UseInstructionNames is set, this function returns:
258
///
259
/// @p Prefix + "_" + Name + @p Suffix
260
///
261
/// otherwise
262
///
263
/// @p Prefix + to_string(Number) + @p Suffix
264
///
265
/// We ignore @p Name by default, as they may change between release
266
/// and debug mode and can consequently not be used when aiming for reproducible
267
/// builds. However, for debugging named statements are often helpful, hence
268
/// we allow their optional use.
269
std::string getIslCompatibleName(const std::string &Prefix,
270
                                 const std::string &Middle, long Number,
271
                                 const std::string &Suffix,
272
                                 bool UseInstructionNames);
273
274
std::string getIslCompatibleName(const std::string &Prefix,
275
                                 const std::string &Middle,
276
                                 const std::string &Suffix);
277
278
// Make isl::give available in polly namespace. We do this as there was
279
// previously a function polly::give() which did the very same thing and we
280
// did not want yet to introduce the isl:: prefix to each call of give.
281
using isl::give;
282
283
inline llvm::DiagnosticInfoOptimizationBase &
284
operator<<(llvm::DiagnosticInfoOptimizationBase &OS,
285
8
           const isl::union_map &Obj) {
286
8
  OS << Obj.to_str();
287
8
  return OS;
288
8
}
289
290
/// Scope guard for code that allows arbitrary isl function to return an error
291
/// if the max-operations quota exceeds.
292
///
293
/// This allows to opt-in code sections that have known long executions times.
294
/// code not in a hot path can continue to assume that no unexpected error
295
/// occurs.
296
///
297
/// This is typically used inside a nested IslMaxOperationsGuard scope. The
298
/// IslMaxOperationsGuard defines the number of allowed base operations for some
299
/// code, IslQuotaScope defines where it is allowed to return an error result.
300
class IslQuotaScope {
301
  isl_ctx *IslCtx;
302
  int OldOnError;
303
304
public:
305
1.11k
  IslQuotaScope() : IslCtx(nullptr) {}
306
  IslQuotaScope(const IslQuotaScope &) = delete;
307
  IslQuotaScope(IslQuotaScope &&Other)
308
0
      : IslCtx(Other.IslCtx), OldOnError(Other.OldOnError) {
309
0
    Other.IslCtx = nullptr;
310
0
  }
311
1.04k
  const IslQuotaScope &operator=(IslQuotaScope &&Other) {
312
1.04k
    std::swap(this->IslCtx, Other.IslCtx);
313
1.04k
    std::swap(this->OldOnError, Other.OldOnError);
314
1.04k
    return *this;
315
1.04k
  }
316
317
  /// Enter a quota-aware scope.
318
  ///
319
  /// Should not be used directly. Use IslMaxOperationsGuard::enter() instead.
320
  explicit IslQuotaScope(isl_ctx *IslCtx, unsigned long LocalMaxOps)
321
1.09k
      : IslCtx(IslCtx) {
322
1.09k
    assert(IslCtx);
323
1.09k
    assert(isl_ctx_get_max_operations(IslCtx) == 0 && "Incorrect nesting");
324
1.09k
    if (
LocalMaxOps == 01.09k
) {
325
0
      this->IslCtx = nullptr;
326
0
      return;
327
0
    }
328
1.09k
329
1.09k
    OldOnError = isl_options_get_on_error(IslCtx);
330
1.09k
    isl_options_set_on_error(IslCtx, ISL_ON_ERROR_CONTINUE);
331
1.09k
    isl_ctx_reset_error(IslCtx);
332
1.09k
    isl_ctx_set_max_operations(IslCtx, LocalMaxOps);
333
1.09k
  }
334
335
2.20k
  ~IslQuotaScope() {
336
2.20k
    if (!IslCtx)
337
1.11k
      return;
338
2.20k
339
1.09k
    assert(isl_ctx_get_max_operations(IslCtx) > 0 && "Incorrect nesting");
340
1.09k
    assert(isl_options_get_on_error(IslCtx) == ISL_ON_ERROR_CONTINUE &&
341
1.09k
           "Incorrect nesting");
342
1.09k
    isl_ctx_set_max_operations(IslCtx, 0);
343
1.09k
    isl_options_set_on_error(IslCtx, OldOnError);
344
1.09k
  }
345
346
  /// Return whether the current quota has exceeded.
347
0
  bool hasQuotaExceeded() const {
348
0
    if (!IslCtx)
349
0
      return false;
350
0
351
0
    return isl_ctx_last_error(IslCtx) == isl_error_quota;
352
0
  }
353
};
354
355
/// Scoped limit of ISL operations.
356
///
357
/// Limits the number of ISL operations during the lifetime of this object. The
358
/// idea is to use this as an RAII guard for the scope where the code is aware
359
/// that ISL can return errors even when all input is valid. After leaving the
360
/// scope, it will return to the error setting as it was before. That also means
361
/// that the error setting should not be changed while in that scope.
362
///
363
/// Such scopes are not allowed to be nested because the previous operations
364
/// counter cannot be reset to the previous state, or one that adds the
365
/// operations while being in the nested scope. Use therefore is only allowed
366
/// while currently a no operations-limit is active.
367
class IslMaxOperationsGuard {
368
private:
369
  /// The ISL context to set the operations limit.
370
  ///
371
  /// If set to nullptr, there is no need for any action at the end of the
372
  /// scope.
373
  isl_ctx *IslCtx;
374
375
  /// Maximum number of operations for the scope.
376
  unsigned long LocalMaxOps;
377
378
  /// When AutoEnter is enabled, holds the IslQuotaScope object.
379
  IslQuotaScope TopLevelScope;
380
381
public:
382
  /// Enter a max operations scope.
383
  ///
384
  /// @param IslCtx      The ISL context to set the operations limit for.
385
  /// @param LocalMaxOps Maximum number of operations allowed in the
386
  ///                    scope. If set to zero, no operations limit is enforced.
387
  /// @param AutoEnter   If true, automatically enters an IslQuotaScope such
388
  ///                    that isl operations may return quota errors
389
  ///                    immediately. If false, only starts the operations
390
  ///                    counter, but isl does not return quota errors before
391
  ///                    calling enter().
392
  IslMaxOperationsGuard(isl_ctx *IslCtx, unsigned long LocalMaxOps,
393
                        bool AutoEnter = true)
394
1.04k
      : IslCtx(IslCtx), LocalMaxOps(LocalMaxOps) {
395
1.04k
    assert(IslCtx);
396
1.04k
    assert(isl_ctx_get_max_operations(IslCtx) == 0 &&
397
1.04k
           "Nested max operations not supported");
398
1.04k
399
1.04k
    if (
LocalMaxOps == 01.04k
) {
400
0
      // No limit on operations; also disable restoring on_error/max_operations.
401
0
      this->IslCtx = nullptr;
402
0
      return;
403
0
    }
404
1.04k
405
1.04k
    isl_ctx_reset_operations(IslCtx);
406
1.04k
    TopLevelScope = enter(AutoEnter);
407
1.04k
  }
408
409
  /// Enter a scope that can handle out-of-quota errors.
410
  ///
411
  /// @param AllowReturnNull Whether the scoped code can handle out-of-quota
412
  ///                        errors. If false, returns a dummy scope object that
413
  ///                        does nothing.
414
1.16k
  IslQuotaScope enter(bool AllowReturnNull = true) {
415
1.16k
    return AllowReturnNull && 
IslCtx1.09k
?
IslQuotaScope(IslCtx, LocalMaxOps)1.09k
416
71
                                     : IslQuotaScope();
417
1.16k
  }
418
419
  /// Return whether the current quota has exceeded.
420
69
  bool hasQuotaExceeded() const {
421
69
    if (!IslCtx)
422
0
      return false;
423
69
424
69
    return isl_ctx_last_error(IslCtx) == isl_error_quota;
425
69
  }
426
};
427
428
} // end namespace polly
429
430
#endif