Coverage Report

Created: 2017-11-23 03:11

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