Coverage Report

Created: 2019-07-24 05:18

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