Coverage Report

Created: 2018-12-09 11:54

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/polly/lib/Analysis/ScopDetectionDiagnostic.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- ScopDetectionDiagnostic.cpp - Error diagnostics --------------------===//
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
// Small set of diagnostic helper classes to encapsulate any errors occurred
11
// during the detection of Scops.
12
//
13
// The ScopDetection defines a set of error classes (via Statistic variables)
14
// that groups a number of individual errors into a group, e.g. non-affinity
15
// related errors.
16
// On error we generate an object that carries enough additional information
17
// to diagnose the error and generate a helpful error message.
18
//
19
//===----------------------------------------------------------------------===//
20
21
#include "polly/ScopDetectionDiagnostic.h"
22
#include "llvm/ADT/SmallPtrSet.h"
23
#include "llvm/ADT/SmallVector.h"
24
#include "llvm/ADT/Statistic.h"
25
#include "llvm/ADT/StringRef.h"
26
#include "llvm/ADT/Twine.h"
27
#include "llvm/Analysis/AliasSetTracker.h"
28
#include "llvm/Analysis/LoopInfo.h"
29
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
30
#include "llvm/Analysis/RegionInfo.h"
31
#include "llvm/Analysis/ScalarEvolution.h"
32
#include "llvm/IR/BasicBlock.h"
33
#include "llvm/IR/CFG.h"
34
#include "llvm/IR/DebugLoc.h"
35
#include "llvm/IR/DiagnosticInfo.h"
36
#include "llvm/IR/Instruction.h"
37
#include "llvm/IR/Value.h"
38
#include "llvm/Support/raw_ostream.h"
39
#include <algorithm>
40
#include <cassert>
41
#include <string>
42
#include <utility>
43
44
using namespace llvm;
45
46
1.43k
#define DEBUG_TYPE "polly-detect"
47
48
#define SCOP_STAT(NAME, DESC)                                                  \
49
  {                                                                            \
50
    "polly-detect", "NAME", "Number of rejected regions: " DESC, {0}, {        \
51
      false                                                                    \
52
    }                                                                          \
53
  }
54
55
Statistic RejectStatistics[] = {
56
    SCOP_STAT(CFG, ""),
57
    SCOP_STAT(InvalidTerminator, "Unsupported terminator instruction"),
58
    SCOP_STAT(UnreachableInExit, "Unreachable in exit block"),
59
    SCOP_STAT(IrreducibleRegion, "Irreducible loops"),
60
    SCOP_STAT(LastCFG, ""),
61
    SCOP_STAT(AffFunc, ""),
62
    SCOP_STAT(UndefCond, "Undefined branch condition"),
63
    SCOP_STAT(InvalidCond, "Non-integer branch condition"),
64
    SCOP_STAT(UndefOperand, "Undefined operands in comparison"),
65
    SCOP_STAT(NonAffBranch, "Non-affine branch condition"),
66
    SCOP_STAT(NoBasePtr, "No base pointer"),
67
    SCOP_STAT(UndefBasePtr, "Undefined base pointer"),
68
    SCOP_STAT(VariantBasePtr, "Variant base pointer"),
69
    SCOP_STAT(NonAffineAccess, "Non-affine memory accesses"),
70
    SCOP_STAT(DifferentElementSize, "Accesses with differing sizes"),
71
    SCOP_STAT(LastAffFunc, ""),
72
    SCOP_STAT(LoopBound, "Uncomputable loop bounds"),
73
    SCOP_STAT(LoopHasNoExit, "Loop without exit"),
74
    SCOP_STAT(LoopHasMultipleExits, "Loop with multiple exits"),
75
    SCOP_STAT(LoopOnlySomeLatches, "Not all loop latches in scop"),
76
    SCOP_STAT(FuncCall, "Function call with side effects"),
77
    SCOP_STAT(NonSimpleMemoryAccess,
78
              "Compilated access semantics (volatile or atomic)"),
79
    SCOP_STAT(Alias, "Base address aliasing"),
80
    SCOP_STAT(Other, ""),
81
    SCOP_STAT(IntToPtr, "Integer to pointer conversions"),
82
    SCOP_STAT(Alloca, "Stack allocations"),
83
    SCOP_STAT(UnknownInst, "Unknown Instructions"),
84
    SCOP_STAT(Entry, "Contains entry block"),
85
    SCOP_STAT(Unprofitable, "Assumed to be unprofitable"),
86
    SCOP_STAT(LastOther, ""),
87
};
88
89
namespace polly {
90
91
/// Small string conversion via raw_string_stream.
92
0
template <typename T> std::string operator+(Twine LHS, const T &RHS) {
93
0
  std::string Buf;
94
0
  raw_string_ostream fmt(Buf);
95
0
  fmt << RHS;
96
0
  fmt.flush();
97
0
98
0
  return LHS.concat(Buf).str();
99
0
}
Unexecuted instantiation: std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > polly::operator+<llvm::SCEV>(llvm::Twine, llvm::SCEV const&)
Unexecuted instantiation: std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > polly::operator+<llvm::Value>(llvm::Twine, llvm::Value const&)
Unexecuted instantiation: std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > polly::operator+<llvm::StringRef>(llvm::Twine, llvm::StringRef const&)
Unexecuted instantiation: std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > polly::operator+<char [14]>(llvm::Twine, char const (&) [14])
Unexecuted instantiation: std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > polly::operator+<char [21]>(llvm::Twine, char const (&) [21])
Unexecuted instantiation: std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > polly::operator+<char [15]>(llvm::Twine, char const (&) [15])
Unexecuted instantiation: std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > polly::operator+<llvm::Instruction>(llvm::Twine, llvm::Instruction const&)
100
} // namespace polly
101
102
namespace llvm {
103
104
// Lexicographic order on (line, col) of our debug locations.
105
1.14k
static bool operator<(const DebugLoc &LHS, const DebugLoc &RHS) {
106
1.14k
  return LHS.getLine() < RHS.getLine() ||
107
1.14k
         
(1.06k
LHS.getLine() == RHS.getLine()1.06k
&&
LHS.getCol() < RHS.getCol()377
);
108
1.14k
}
109
} // namespace llvm
110
111
namespace polly {
112
113
10.2k
BBPair getBBPairForRegion(const Region *R) {
114
10.2k
  return std::make_pair(R->getEntry(), R->getExit());
115
10.2k
}
116
117
1.63k
void getDebugLocations(const BBPair &P, DebugLoc &Begin, DebugLoc &End) {
118
1.63k
  SmallPtrSet<BasicBlock *, 32> Seen;
119
1.63k
  SmallVector<BasicBlock *, 32> Todo;
120
1.63k
  Todo.push_back(P.first);
121
14.9k
  while (!Todo.empty()) {
122
13.2k
    auto *BB = Todo.pop_back_val();
123
13.2k
    if (BB == P.second)
124
2.23k
      continue;
125
11.0k
    if (!Seen.insert(BB).second)
126
2.94k
      continue;
127
8.09k
    Todo.append(succ_begin(BB), succ_end(BB));
128
28.3k
    for (const Instruction &Inst : *BB) {
129
28.3k
      DebugLoc DL = Inst.getDebugLoc();
130
28.3k
      if (!DL)
131
27.7k
        continue;
132
601
133
601
      Begin = Begin ? 
std::min(Begin, DL)574
:
DL27
;
134
601
      End = End ? 
std::max(End, DL)574
:
DL27
;
135
601
    }
136
8.09k
  }
137
1.63k
}
138
139
void emitRejectionRemarks(const BBPair &P, const RejectLog &Log,
140
445
                          OptimizationRemarkEmitter &ORE) {
141
445
  DebugLoc Begin, End;
142
445
  getDebugLocations(P, Begin, End);
143
445
144
445
  ORE.emit(
145
445
      OptimizationRemarkMissed(DEBUG_TYPE, "RejectionErrors", Begin, P.first)
146
445
      << "The following errors keep this region from being a Scop.");
147
445
148
546
  for (RejectReasonPtr RR : Log) {
149
546
150
546
    if (const DebugLoc &Loc = RR->getDebugLoc())
151
32
      ORE.emit(OptimizationRemarkMissed(DEBUG_TYPE, RR->getRemarkName(), Loc,
152
32
                                        RR->getRemarkBB())
153
32
               << RR->getEndUserMessage());
154
514
    else
155
514
      ORE.emit(OptimizationRemarkMissed(DEBUG_TYPE, RR->getRemarkName(), Begin,
156
514
                                        RR->getRemarkBB())
157
514
               << RR->getEndUserMessage());
158
546
  }
159
445
160
445
  /* Check to see if Region is a top level region, getExit = NULL*/
161
445
  if (P.second)
162
444
    ORE.emit(
163
444
        OptimizationRemarkMissed(DEBUG_TYPE, "InvalidScopEnd", End, P.second)
164
444
        << "Invalid Scop candidate ends here.");
165
1
  else
166
1
    ORE.emit(
167
1
        OptimizationRemarkMissed(DEBUG_TYPE, "InvalidScopEnd", End, P.first)
168
1
        << "Invalid Scop candidate ends here.");
169
445
}
170
171
//===----------------------------------------------------------------------===//
172
// RejectReason.
173
174
602
RejectReason::RejectReason(RejectReasonKind K) : Kind(K) {
175
602
  RejectStatistics[static_cast<int>(K)]++;
176
602
}
177
178
const DebugLoc RejectReason::Unknown = DebugLoc();
179
180
0
const DebugLoc &RejectReason::getDebugLoc() const {
181
0
  // Allocate an empty DebugLoc and return it a reference to it.
182
0
  return Unknown;
183
0
}
184
185
// RejectLog.
186
0
void RejectLog::print(raw_ostream &OS, int level) const {
187
0
  int j = 0;
188
0
  for (auto Reason : ErrorReports)
189
0
    OS.indent(level) << "[" << j++ << "] " << Reason->getMessage() << "\n";
190
0
}
191
192
//===----------------------------------------------------------------------===//
193
// ReportCFG.
194
195
28
ReportCFG::ReportCFG(const RejectReasonKind K) : RejectReason(K) {}
196
197
0
bool ReportCFG::classof(const RejectReason *RR) {
198
0
  return RR->getKind() >= RejectReasonKind::CFG &&
199
0
         RR->getKind() <= RejectReasonKind::LastCFG;
200
0
}
201
202
//===----------------------------------------------------------------------===//
203
// ReportInvalidTerminator.
204
205
0
std::string ReportInvalidTerminator::getRemarkName() const {
206
0
  return "InvalidTerminator";
207
0
}
208
209
0
const Value *ReportInvalidTerminator::getRemarkBB() const { return BB; }
210
211
0
std::string ReportInvalidTerminator::getMessage() const {
212
0
  return ("Invalid instruction terminates BB: " + BB->getName()).str();
213
0
}
214
215
0
const DebugLoc &ReportInvalidTerminator::getDebugLoc() const {
216
0
  return BB->getTerminator()->getDebugLoc();
217
0
}
218
219
0
bool ReportInvalidTerminator::classof(const RejectReason *RR) {
220
0
  return RR->getKind() == RejectReasonKind::InvalidTerminator;
221
0
}
222
223
//===----------------------------------------------------------------------===//
224
// UnreachableInExit.
225
226
23
std::string ReportUnreachableInExit::getRemarkName() const {
227
23
  return "UnreachableInExit";
228
23
}
229
230
23
const Value *ReportUnreachableInExit::getRemarkBB() const { return BB; }
231
232
0
std::string ReportUnreachableInExit::getMessage() const {
233
0
  std::string BBName = BB->getName();
234
0
  return "Unreachable in exit block" + BBName;
235
0
}
236
237
23
const DebugLoc &ReportUnreachableInExit::getDebugLoc() const { return DbgLoc; }
238
239
23
std::string ReportUnreachableInExit::getEndUserMessage() const {
240
23
  return "Unreachable in exit block.";
241
23
}
242
243
0
bool ReportUnreachableInExit::classof(const RejectReason *RR) {
244
0
  return RR->getKind() == RejectReasonKind::UnreachableInExit;
245
0
}
246
247
//===----------------------------------------------------------------------===//
248
// ReportIrreducibleRegion.
249
250
3
std::string ReportIrreducibleRegion::getRemarkName() const {
251
3
  return "IrreducibleRegion";
252
3
}
253
254
3
const Value *ReportIrreducibleRegion::getRemarkBB() const {
255
3
  return R->getEntry();
256
3
}
257
258
0
std::string ReportIrreducibleRegion::getMessage() const {
259
0
  return "Irreducible region encountered: " + R->getNameStr();
260
0
}
261
262
3
const DebugLoc &ReportIrreducibleRegion::getDebugLoc() const { return DbgLoc; }
263
264
3
std::string ReportIrreducibleRegion::getEndUserMessage() const {
265
3
  return "Irreducible region encountered in control flow.";
266
3
}
267
268
0
bool ReportIrreducibleRegion::classof(const RejectReason *RR) {
269
0
  return RR->getKind() == RejectReasonKind::IrreducibleRegion;
270
0
}
271
272
//===----------------------------------------------------------------------===//
273
// ReportAffFunc.
274
275
ReportAffFunc::ReportAffFunc(const RejectReasonKind K, const Instruction *Inst)
276
236
    : RejectReason(K), Inst(Inst) {}
277
278
0
bool ReportAffFunc::classof(const RejectReason *RR) {
279
0
  return RR->getKind() >= RejectReasonKind::AffFunc &&
280
0
         RR->getKind() <= RejectReasonKind::LastAffFunc;
281
0
}
282
283
//===----------------------------------------------------------------------===//
284
// ReportUndefCond.
285
286
141
std::string ReportUndefCond::getRemarkName() const { return "UndefCond"; }
287
288
141
const Value *ReportUndefCond::getRemarkBB() const { return BB; }
289
290
0
std::string ReportUndefCond::getMessage() const {
291
0
  return ("Condition based on 'undef' value in BB: " + BB->getName()).str();
292
0
}
293
294
0
bool ReportUndefCond::classof(const RejectReason *RR) {
295
0
  return RR->getKind() == RejectReasonKind::UndefCond;
296
0
}
297
298
//===----------------------------------------------------------------------===//
299
// ReportInvalidCond.
300
301
1
std::string ReportInvalidCond::getRemarkName() const { return "InvalidCond"; }
302
303
1
const Value *ReportInvalidCond::getRemarkBB() const { return BB; }
304
305
0
std::string ReportInvalidCond::getMessage() const {
306
0
  return ("Condition in BB '" + BB->getName()).str() +
307
0
         "' neither constant nor an icmp instruction";
308
0
}
309
310
0
bool ReportInvalidCond::classof(const RejectReason *RR) {
311
0
  return RR->getKind() == RejectReasonKind::InvalidCond;
312
0
}
313
314
//===----------------------------------------------------------------------===//
315
// ReportUndefOperand.
316
317
5
std::string ReportUndefOperand::getRemarkName() const { return "UndefOperand"; }
318
319
5
const Value *ReportUndefOperand::getRemarkBB() const { return BB; }
320
321
0
std::string ReportUndefOperand::getMessage() const {
322
0
  return ("undef operand in branch at BB: " + BB->getName()).str();
323
0
}
324
325
0
bool ReportUndefOperand::classof(const RejectReason *RR) {
326
0
  return RR->getKind() == RejectReasonKind::UndefOperand;
327
0
}
328
329
//===----------------------------------------------------------------------===//
330
// ReportNonAffBranch.
331
332
3
std::string ReportNonAffBranch::getRemarkName() const { return "NonAffBranch"; }
333
334
3
const Value *ReportNonAffBranch::getRemarkBB() const { return BB; }
335
336
0
std::string ReportNonAffBranch::getMessage() const {
337
0
  return ("Non affine branch in BB '" + BB->getName()).str() +
338
0
         "' with LHS: " + *LHS + " and RHS: " + *RHS;
339
0
}
340
341
0
bool ReportNonAffBranch::classof(const RejectReason *RR) {
342
0
  return RR->getKind() == RejectReasonKind::NonAffBranch;
343
0
}
344
345
//===----------------------------------------------------------------------===//
346
// ReportNoBasePtr.
347
348
0
std::string ReportNoBasePtr::getRemarkName() const { return "NoBasePtr"; }
349
350
0
const Value *ReportNoBasePtr::getRemarkBB() const { return Inst->getParent(); }
351
352
0
std::string ReportNoBasePtr::getMessage() const { return "No base pointer"; }
353
354
0
bool ReportNoBasePtr::classof(const RejectReason *RR) {
355
0
  return RR->getKind() == RejectReasonKind::NoBasePtr;
356
0
}
357
358
//===----------------------------------------------------------------------===//
359
// ReportUndefBasePtr.
360
361
5
std::string ReportUndefBasePtr::getRemarkName() const { return "UndefBasePtr"; }
362
363
5
const Value *ReportUndefBasePtr::getRemarkBB() const {
364
5
  return Inst->getParent();
365
5
}
366
367
0
std::string ReportUndefBasePtr::getMessage() const {
368
0
  return "Undefined base pointer";
369
0
}
370
371
0
bool ReportUndefBasePtr::classof(const RejectReason *RR) {
372
0
  return RR->getKind() == RejectReasonKind::UndefBasePtr;
373
0
}
374
375
//===----------------------------------------------------------------------===//
376
// ReportVariantBasePtr.
377
378
10
std::string ReportVariantBasePtr::getRemarkName() const {
379
10
  return "VariantBasePtr";
380
10
}
381
382
10
const Value *ReportVariantBasePtr::getRemarkBB() const {
383
10
  return Inst->getParent();
384
10
}
385
386
0
std::string ReportVariantBasePtr::getMessage() const {
387
0
  return "Base address not invariant in current region:" + *BaseValue;
388
0
}
389
390
10
std::string ReportVariantBasePtr::getEndUserMessage() const {
391
10
  return "The base address of this array is not invariant inside the loop";
392
10
}
393
394
0
bool ReportVariantBasePtr::classof(const RejectReason *RR) {
395
0
  return RR->getKind() == RejectReasonKind::VariantBasePtr;
396
0
}
397
398
//===----------------------------------------------------------------------===//
399
// ReportDifferentArrayElementSize
400
401
0
std::string ReportDifferentArrayElementSize::getRemarkName() const {
402
0
  return "DifferentArrayElementSize";
403
0
}
404
405
0
const Value *ReportDifferentArrayElementSize::getRemarkBB() const {
406
0
  return Inst->getParent();
407
0
}
408
409
0
std::string ReportDifferentArrayElementSize::getMessage() const {
410
0
  return "Access to one array through data types of different size";
411
0
}
412
413
0
bool ReportDifferentArrayElementSize::classof(const RejectReason *RR) {
414
0
  return RR->getKind() == RejectReasonKind::DifferentElementSize;
415
0
}
416
417
0
std::string ReportDifferentArrayElementSize::getEndUserMessage() const {
418
0
  StringRef BaseName = BaseValue->getName();
419
0
  std::string Name = BaseName.empty() ? "UNKNOWN" : BaseName;
420
0
  return "The array \"" + Name +
421
0
         "\" is accessed through elements that differ "
422
0
         "in size";
423
0
}
424
425
//===----------------------------------------------------------------------===//
426
// ReportNonAffineAccess.
427
428
51
std::string ReportNonAffineAccess::getRemarkName() const {
429
51
  return "NonAffineAccess";
430
51
}
431
432
51
const Value *ReportNonAffineAccess::getRemarkBB() const {
433
51
  return Inst->getParent();
434
51
}
435
436
0
std::string ReportNonAffineAccess::getMessage() const {
437
0
  return "Non affine access function: " + *AccessFunction;
438
0
}
439
440
0
bool ReportNonAffineAccess::classof(const RejectReason *RR) {
441
0
  return RR->getKind() == RejectReasonKind::NonAffineAccess;
442
0
}
443
444
51
std::string ReportNonAffineAccess::getEndUserMessage() const {
445
51
  StringRef BaseName = BaseValue->getName();
446
51
  std::string Name = BaseName.empty() ? 
"UNKNOWN"0
: BaseName;
447
51
  return "The array subscript of \"" + Name + "\" is not affine";
448
51
}
449
450
//===----------------------------------------------------------------------===//
451
// ReportLoopBound.
452
453
ReportLoopBound::ReportLoopBound(Loop *L, const SCEV *LoopCount)
454
    : RejectReason(RejectReasonKind::LoopBound), L(L), LoopCount(LoopCount),
455
134
      Loc(L->getStartLoc()) {}
456
457
126
std::string ReportLoopBound::getRemarkName() const { return "LoopBound"; }
458
459
126
const Value *ReportLoopBound::getRemarkBB() const { return L->getHeader(); }
460
461
0
std::string ReportLoopBound::getMessage() const {
462
0
  return "Non affine loop bound '" + *LoopCount +
463
0
         "' in loop: " + L->getHeader()->getName();
464
0
}
465
466
126
const DebugLoc &ReportLoopBound::getDebugLoc() const { return Loc; }
467
468
0
bool ReportLoopBound::classof(const RejectReason *RR) {
469
0
  return RR->getKind() == RejectReasonKind::LoopBound;
470
0
}
471
472
126
std::string ReportLoopBound::getEndUserMessage() const {
473
126
  return "Failed to derive an affine function from the loop bounds.";
474
126
}
475
476
//===----------------------------------------------------------------------===//
477
// ReportLoopHasNoExit.
478
479
0
std::string ReportLoopHasNoExit::getRemarkName() const {
480
0
  return "LoopHasNoExit";
481
0
}
482
483
0
const Value *ReportLoopHasNoExit::getRemarkBB() const { return L->getHeader(); }
484
485
0
std::string ReportLoopHasNoExit::getMessage() const {
486
0
  return "Loop " + L->getHeader()->getName() + " has no exit.";
487
0
}
488
489
0
bool ReportLoopHasNoExit::classof(const RejectReason *RR) {
490
0
  return RR->getKind() == RejectReasonKind::LoopHasNoExit;
491
0
}
492
493
0
const DebugLoc &ReportLoopHasNoExit::getDebugLoc() const { return Loc; }
494
495
0
std::string ReportLoopHasNoExit::getEndUserMessage() const {
496
0
  return "Loop cannot be handled because it has no exit.";
497
0
}
498
499
//===----------------------------------------------------------------------===//
500
// ReportLoopHasMultipleExits.
501
502
34
std::string ReportLoopHasMultipleExits::getRemarkName() const {
503
34
  return "ReportLoopHasMultipleExits";
504
34
}
505
506
34
const Value *ReportLoopHasMultipleExits::getRemarkBB() const {
507
34
  return L->getHeader();
508
34
}
509
510
0
std::string ReportLoopHasMultipleExits::getMessage() const {
511
0
  return "Loop " + L->getHeader()->getName() + " has multiple exits.";
512
0
}
513
514
0
bool ReportLoopHasMultipleExits::classof(const RejectReason *RR) {
515
0
  return RR->getKind() == RejectReasonKind::LoopHasMultipleExits;
516
0
}
517
518
34
const DebugLoc &ReportLoopHasMultipleExits::getDebugLoc() const { return Loc; }
519
520
34
std::string ReportLoopHasMultipleExits::getEndUserMessage() const {
521
34
  return "Loop cannot be handled because it has multiple exits.";
522
34
}
523
524
//===----------------------------------------------------------------------===//
525
// ReportLoopOnlySomeLatches
526
527
5
std::string ReportLoopOnlySomeLatches::getRemarkName() const {
528
5
  return "LoopHasNoExit";
529
5
}
530
531
5
const Value *ReportLoopOnlySomeLatches::getRemarkBB() const {
532
5
  return L->getHeader();
533
5
}
534
535
0
std::string ReportLoopOnlySomeLatches::getMessage() const {
536
0
  return "Not all latches of loop " + L->getHeader()->getName() +
537
0
         " part of scop.";
538
0
}
539
540
0
bool ReportLoopOnlySomeLatches::classof(const RejectReason *RR) {
541
0
  return RR->getKind() == RejectReasonKind::LoopHasNoExit;
542
0
}
543
544
5
const DebugLoc &ReportLoopOnlySomeLatches::getDebugLoc() const { return Loc; }
545
546
5
std::string ReportLoopOnlySomeLatches::getEndUserMessage() const {
547
5
  return "Loop cannot be handled because not all latches are part of loop "
548
5
         "region.";
549
5
}
550
551
//===----------------------------------------------------------------------===//
552
// ReportFuncCall.
553
554
ReportFuncCall::ReportFuncCall(Instruction *Inst)
555
11
    : RejectReason(RejectReasonKind::FuncCall), Inst(Inst) {}
556
557
9
std::string ReportFuncCall::getRemarkName() const { return "FuncCall"; }
558
559
9
const Value *ReportFuncCall::getRemarkBB() const { return Inst->getParent(); }
560
561
0
std::string ReportFuncCall::getMessage() const {
562
0
  return "Call instruction: " + *Inst;
563
0
}
564
565
9
const DebugLoc &ReportFuncCall::getDebugLoc() const {
566
9
  return Inst->getDebugLoc();
567
9
}
568
569
9
std::string ReportFuncCall::getEndUserMessage() const {
570
9
  return "This function call cannot be handled. "
571
9
         "Try to inline it.";
572
9
}
573
574
0
bool ReportFuncCall::classof(const RejectReason *RR) {
575
0
  return RR->getKind() == RejectReasonKind::FuncCall;
576
0
}
577
578
//===----------------------------------------------------------------------===//
579
// ReportNonSimpleMemoryAccess
580
581
ReportNonSimpleMemoryAccess::ReportNonSimpleMemoryAccess(Instruction *Inst)
582
0
    : ReportOther(RejectReasonKind::NonSimpleMemoryAccess), Inst(Inst) {}
583
584
0
std::string ReportNonSimpleMemoryAccess::getRemarkName() const {
585
0
  return "NonSimpleMemoryAccess";
586
0
}
587
588
0
const Value *ReportNonSimpleMemoryAccess::getRemarkBB() const {
589
0
  return Inst->getParent();
590
0
}
591
592
0
std::string ReportNonSimpleMemoryAccess::getMessage() const {
593
0
  return "Non-simple memory access: " + *Inst;
594
0
}
595
596
0
const DebugLoc &ReportNonSimpleMemoryAccess::getDebugLoc() const {
597
0
  return Inst->getDebugLoc();
598
0
}
599
600
0
std::string ReportNonSimpleMemoryAccess::getEndUserMessage() const {
601
0
  return "Volatile memory accesses or memory accesses for atomic types "
602
0
         "are not supported.";
603
0
}
604
605
0
bool ReportNonSimpleMemoryAccess::classof(const RejectReason *RR) {
606
0
  return RR->getKind() == RejectReasonKind::NonSimpleMemoryAccess;
607
0
}
608
609
//===----------------------------------------------------------------------===//
610
// ReportAlias.
611
612
ReportAlias::ReportAlias(Instruction *Inst, AliasSet &AS)
613
3
    : RejectReason(RejectReasonKind::Alias), Inst(Inst) {
614
3
  for (const auto &I : AS)
615
6
    Pointers.push_back(I.getValue());
616
3
}
617
618
std::string ReportAlias::formatInvalidAlias(std::string Prefix,
619
3
                                            std::string Suffix) const {
620
3
  std::string Message;
621
3
  raw_string_ostream OS(Message);
622
3
623
3
  OS << Prefix;
624
3
625
3
  for (PointerSnapshotTy::const_iterator PI = Pointers.begin(),
626
3
                                         PE = Pointers.end();
627
6
       ;) {
628
6
    const Value *V = *PI;
629
6
    assert(V && "Diagnostic info does not match found LLVM-IR anymore.");
630
6
631
6
    if (V->getName().empty())
632
1
      OS << "\" <unknown> \"";
633
5
    else
634
5
      OS << "\"" << V->getName() << "\"";
635
6
636
6
    ++PI;
637
6
638
6
    if (PI != PE)
639
3
      OS << ", ";
640
3
    else
641
3
      break;
642
6
  }
643
3
644
3
  OS << Suffix;
645
3
646
3
  return OS.str();
647
3
}
648
649
3
std::string ReportAlias::getRemarkName() const { return "Alias"; }
650
651
3
const Value *ReportAlias::getRemarkBB() const { return Inst->getParent(); }
652
653
0
std::string ReportAlias::getMessage() const {
654
0
  return formatInvalidAlias("Possible aliasing: ");
655
0
}
656
657
3
std::string ReportAlias::getEndUserMessage() const {
658
3
  return formatInvalidAlias("Accesses to the arrays ",
659
3
                            " may access the same memory.");
660
3
}
661
662
3
const DebugLoc &ReportAlias::getDebugLoc() const { return Inst->getDebugLoc(); }
663
664
0
bool ReportAlias::classof(const RejectReason *RR) {
665
0
  return RR->getKind() == RejectReasonKind::Alias;
666
0
}
667
668
//===----------------------------------------------------------------------===//
669
// ReportOther.
670
671
0
std::string ReportOther::getRemarkName() const { return "UnknownRejectReason"; }
672
673
0
std::string ReportOther::getMessage() const { return "Unknown reject reason"; }
674
675
150
ReportOther::ReportOther(const RejectReasonKind K) : RejectReason(K) {}
676
677
0
bool ReportOther::classof(const RejectReason *RR) {
678
0
  return RR->getKind() >= RejectReasonKind::Other &&
679
0
         RR->getKind() <= RejectReasonKind::LastOther;
680
0
}
681
682
//===----------------------------------------------------------------------===//
683
// ReportIntToPtr.
684
ReportIntToPtr::ReportIntToPtr(Instruction *BaseValue)
685
1
    : ReportOther(RejectReasonKind::IntToPtr), BaseValue(BaseValue) {}
686
687
1
std::string ReportIntToPtr::getRemarkName() const { return "IntToPtr"; }
688
689
1
const Value *ReportIntToPtr::getRemarkBB() const {
690
1
  return BaseValue->getParent();
691
1
}
692
693
0
std::string ReportIntToPtr::getMessage() const {
694
0
  return "Find bad intToptr prt: " + *BaseValue;
695
0
}
696
697
1
const DebugLoc &ReportIntToPtr::getDebugLoc() const {
698
1
  return BaseValue->getDebugLoc();
699
1
}
700
701
0
bool ReportIntToPtr::classof(const RejectReason *RR) {
702
0
  return RR->getKind() == RejectReasonKind::IntToPtr;
703
0
}
704
705
//===----------------------------------------------------------------------===//
706
// ReportAlloca.
707
708
ReportAlloca::ReportAlloca(Instruction *Inst)
709
0
    : ReportOther(RejectReasonKind::Alloca), Inst(Inst) {}
710
711
0
std::string ReportAlloca::getRemarkName() const { return "Alloca"; }
712
713
0
const Value *ReportAlloca::getRemarkBB() const { return Inst->getParent(); }
714
715
0
std::string ReportAlloca::getMessage() const {
716
0
  return "Alloca instruction: " + *Inst;
717
0
}
718
719
0
const DebugLoc &ReportAlloca::getDebugLoc() const {
720
0
  return Inst->getDebugLoc();
721
0
}
722
723
0
bool ReportAlloca::classof(const RejectReason *RR) {
724
0
  return RR->getKind() == RejectReasonKind::Alloca;
725
0
}
726
727
//===----------------------------------------------------------------------===//
728
// ReportUnknownInst.
729
730
ReportUnknownInst::ReportUnknownInst(Instruction *Inst)
731
49
    : ReportOther(RejectReasonKind::UnknownInst), Inst(Inst) {}
732
733
26
std::string ReportUnknownInst::getRemarkName() const { return "UnknownInst"; }
734
735
26
const Value *ReportUnknownInst::getRemarkBB() const {
736
26
  return Inst->getParent();
737
26
}
738
739
0
std::string ReportUnknownInst::getMessage() const {
740
0
  return "Unknown instruction: " + *Inst;
741
0
}
742
743
26
const DebugLoc &ReportUnknownInst::getDebugLoc() const {
744
26
  return Inst->getDebugLoc();
745
26
}
746
747
0
bool ReportUnknownInst::classof(const RejectReason *RR) {
748
0
  return RR->getKind() == RejectReasonKind::UnknownInst;
749
0
}
750
751
//===----------------------------------------------------------------------===//
752
// ReportEntry.
753
754
ReportEntry::ReportEntry(BasicBlock *BB)
755
84
    : ReportOther(RejectReasonKind::Entry), BB(BB) {}
756
757
84
std::string ReportEntry::getRemarkName() const { return "Entry"; }
758
759
84
const Value *ReportEntry::getRemarkBB() const { return BB; }
760
761
0
std::string ReportEntry::getMessage() const {
762
0
  return "Region containing entry block of function is invalid!";
763
0
}
764
765
84
std::string ReportEntry::getEndUserMessage() const {
766
84
  return "Scop contains function entry (not yet supported).";
767
84
}
768
769
84
const DebugLoc &ReportEntry::getDebugLoc() const {
770
84
  return BB->getTerminator()->getDebugLoc();
771
84
}
772
773
0
bool ReportEntry::classof(const RejectReason *RR) {
774
0
  return RR->getKind() == RejectReasonKind::Entry;
775
0
}
776
777
//===----------------------------------------------------------------------===//
778
// ReportUnprofitable.
779
780
ReportUnprofitable::ReportUnprofitable(Region *R)
781
16
    : ReportOther(RejectReasonKind::Unprofitable), R(R) {}
782
783
16
std::string ReportUnprofitable::getRemarkName() const { return "Unprofitable"; }
784
785
16
const Value *ReportUnprofitable::getRemarkBB() const { return R->getEntry(); }
786
787
0
std::string ReportUnprofitable::getMessage() const {
788
0
  return "Region can not profitably be optimized!";
789
0
}
790
791
16
std::string ReportUnprofitable::getEndUserMessage() const {
792
16
  return "No profitable polyhedral optimization found";
793
16
}
794
795
16
const DebugLoc &ReportUnprofitable::getDebugLoc() const {
796
16
  for (const BasicBlock *BB : R->blocks())
797
62
    for (const Instruction &Inst : *BB)
798
230
      if (const DebugLoc &DL = Inst.getDebugLoc())
799
5
        return DL;
800
16
801
16
  
return R->getEntry()->getTerminator()->getDebugLoc()11
;
802
16
}
803
804
0
bool ReportUnprofitable::classof(const RejectReason *RR) {
805
0
  return RR->getKind() == RejectReasonKind::Unprofitable;
806
0
}
807
} // namespace polly