Coverage Report

Created: 2017-04-29 12:21

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/tools/polly/lib/Analysis/ScopDetectionDiagnostic.cpp
Line
Count
Source (jump to first uncovered line)
1
//=== ScopDetectionDiagnostic.cpp - Error diagnostics --------- -*- C++ -*-===//
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
#include "polly/ScopDetectionDiagnostic.h"
21
#include "polly/Support/ScopLocation.h"
22
#include "llvm/ADT/SmallVector.h"
23
#include "llvm/ADT/Statistic.h"
24
#include "llvm/Analysis/AliasSetTracker.h"
25
#include "llvm/Analysis/LoopInfo.h"
26
#include "llvm/Analysis/RegionInfo.h"
27
#include "llvm/IR/BasicBlock.h"
28
#include "llvm/IR/DebugInfo.h"
29
#include "llvm/IR/DebugLoc.h"
30
#include "llvm/IR/DiagnosticInfo.h"
31
#include "llvm/IR/LLVMContext.h"
32
#include "llvm/IR/Value.h"
33
34
1.39k
#define DEBUG_TYPE "polly-detect"
35
#include "llvm/Support/Debug.h"
36
37
#include <string>
38
39
using namespace llvm;
40
41
#define SCOP_STAT(NAME, DESC)                                                  \
42
  { "polly-detect", "NAME", "Number of rejected regions: " DESC, {0}, false }
43
44
llvm::Statistic RejectStatistics[] = {
45
    SCOP_STAT(CFG, ""),
46
    SCOP_STAT(InvalidTerminator, "Unsupported terminator instruction"),
47
    SCOP_STAT(UnreachableInExit, "Unreachable in exit block"),
48
    SCOP_STAT(IrreducibleRegion, "Irreducible loops"),
49
    SCOP_STAT(LastCFG, ""),
50
    SCOP_STAT(AffFunc, ""),
51
    SCOP_STAT(UndefCond, "Undefined branch condition"),
52
    SCOP_STAT(InvalidCond, "Non-integer branch condition"),
53
    SCOP_STAT(UndefOperand, "Undefined operands in comparison"),
54
    SCOP_STAT(NonAffBranch, "Non-affine branch condition"),
55
    SCOP_STAT(NoBasePtr, "No base pointer"),
56
    SCOP_STAT(UndefBasePtr, "Undefined base pointer"),
57
    SCOP_STAT(VariantBasePtr, "Variant base pointer"),
58
    SCOP_STAT(NonAffineAccess, "Non-affine memory accesses"),
59
    SCOP_STAT(DifferentElementSize, "Accesses with differing sizes"),
60
    SCOP_STAT(LastAffFunc, ""),
61
    SCOP_STAT(LoopBound, "Uncomputable loop bounds"),
62
    SCOP_STAT(LoopHasNoExit, "Loop without exit"),
63
    SCOP_STAT(FuncCall, "Function call with side effects"),
64
    SCOP_STAT(NonSimpleMemoryAccess,
65
              "Compilated access semantics (volatile or atomic)"),
66
    SCOP_STAT(Alias, "Base address aliasing"),
67
    SCOP_STAT(Other, ""),
68
    SCOP_STAT(IntToPtr, "Integer to pointer conversions"),
69
    SCOP_STAT(Alloca, "Stack allocations"),
70
    SCOP_STAT(UnknownInst, "Unknown Instructions"),
71
    SCOP_STAT(Entry, "Contains entry block"),
72
    SCOP_STAT(Unprofitable, "Assumed to be unprofitable"),
73
    SCOP_STAT(LastOther, ""),
74
};
75
76
namespace polly {
77
/// Small string conversion via raw_string_stream.
78
0
template <typename T> std::string operator+(Twine LHS, const T &RHS) {
79
0
  std::string Buf;
80
0
  raw_string_ostream fmt(Buf);
81
0
  fmt << RHS;
82
0
  fmt.flush();
83
0
84
0
  return LHS.concat(Buf).str();
85
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+<llvm::Instruction>(llvm::Twine, llvm::Instruction const&)
86
} // namespace polly
87
88
namespace llvm {
89
// Lexicographic order on (line, col) of our debug locations.
90
822
static bool operator<(const llvm::DebugLoc &LHS, const llvm::DebugLoc &RHS) {
91
822
  return LHS.getLine() < RHS.getLine() ||
92
760
         
(LHS.getLine() == RHS.getLine() && 760
LHS.getCol() < RHS.getCol()289
);
93
822
}
94
} // namespace llvm
95
96
namespace polly {
97
8.27k
BBPair getBBPairForRegion(const Region *R) {
98
8.27k
  return std::make_pair(R->getEntry(), R->getExit());
99
8.27k
}
100
101
1.37k
void getDebugLocations(const BBPair &P, DebugLoc &Begin, DebugLoc &End) {
102
1.37k
  SmallPtrSet<BasicBlock *, 32> Seen;
103
1.37k
  SmallVector<BasicBlock *, 32> Todo;
104
1.37k
  Todo.push_back(P.first);
105
12.3k
  while (
!Todo.empty()12.3k
)
{11.0k
106
11.0k
    auto *BB = Todo.pop_back_val();
107
11.0k
    if (BB == P.second)
108
1.87k
      continue;
109
9.13k
    
if (9.13k
!Seen.insert(BB).second9.13k
)
110
2.48k
      continue;
111
6.65k
    Todo.append(succ_begin(BB), succ_end(BB));
112
23.3k
    for (const Instruction &Inst : *BB) {
113
23.3k
      DebugLoc DL = Inst.getDebugLoc();
114
23.3k
      if (!DL)
115
22.8k
        continue;
116
23.3k
117
438
      
Begin = Begin ? 438
std::min(Begin, DL)411
:
DL27
;
118
411
      End = End ? 
std::max(End, DL)411
:
DL27
;
119
438
    }
120
6.65k
  }
121
1.37k
}
122
123
430
void emitRejectionRemarks(const BBPair &P, const RejectLog &Log) {
124
430
  Function &F = *P.first->getParent();
125
430
  LLVMContext &Ctx = F.getContext();
126
430
127
430
  DebugLoc Begin, End;
128
430
  getDebugLocations(P, Begin, End);
129
430
130
430
  emitOptimizationRemarkMissed(
131
430
      Ctx, DEBUG_TYPE, F, Begin,
132
430
      "The following errors keep this region from being a Scop.");
133
430
134
532
  for (RejectReasonPtr RR : Log) {
135
532
    if (const DebugLoc &Loc = RR->getDebugLoc())
136
32
      
emitOptimizationRemarkMissed(Ctx, 32
DEBUG_TYPE32
, F, Loc,
137
32
                                   RR->getEndUserMessage());
138
532
    else
139
500
      
emitOptimizationRemarkMissed(Ctx, 500
DEBUG_TYPE500
, F, Begin,
140
500
                                   RR->getEndUserMessage());
141
532
  }
142
430
143
430
  emitOptimizationRemarkMissed(Ctx, DEBUG_TYPE, F, End,
144
430
                               "Invalid Scop candidate ends here.");
145
430
}
146
147
//===----------------------------------------------------------------------===//
148
// RejectReason.
149
150
587
RejectReason::RejectReason(RejectReasonKind K) : Kind(K) {
151
587
  RejectStatistics[static_cast<int>(K)]++;
152
587
}
153
154
const DebugLoc RejectReason::Unknown = DebugLoc();
155
156
0
const llvm::DebugLoc &RejectReason::getDebugLoc() const {
157
0
  // Allocate an empty DebugLoc and return it a reference to it.
158
0
  return Unknown;
159
0
}
160
161
// RejectLog.
162
0
void RejectLog::print(raw_ostream &OS, int level) const {
163
0
  int j = 0;
164
0
  for (auto Reason : ErrorReports)
165
0
    OS.indent(level) << "[" << j++ << "] " << Reason->getMessage() << "\n";
166
0
}
167
168
//===----------------------------------------------------------------------===//
169
// ReportCFG.
170
171
29
ReportCFG::ReportCFG(const RejectReasonKind K) : RejectReason(K) {}
172
173
0
bool ReportCFG::classof(const RejectReason *RR) {
174
0
  return RR->getKind() >= RejectReasonKind::CFG &&
175
0
         RR->getKind() <= RejectReasonKind::LastCFG;
176
0
}
177
178
//===----------------------------------------------------------------------===//
179
// ReportInvalidTerminator.
180
181
0
std::string ReportInvalidTerminator::getMessage() const {
182
0
  return ("Invalid instruction terminates BB: " + BB->getName()).str();
183
0
}
184
185
0
const DebugLoc &ReportInvalidTerminator::getDebugLoc() const {
186
0
  return BB->getTerminator()->getDebugLoc();
187
0
}
188
189
0
bool ReportInvalidTerminator::classof(const RejectReason *RR) {
190
0
  return RR->getKind() == RejectReasonKind::InvalidTerminator;
191
0
}
192
193
//===----------------------------------------------------------------------===//
194
// UnreachableInExit.
195
196
0
std::string ReportUnreachableInExit::getMessage() const {
197
0
  std::string BBName = BB->getName();
198
0
  return "Unreachable in exit block" + BBName;
199
0
}
200
201
24
const DebugLoc &ReportUnreachableInExit::getDebugLoc() const { return DbgLoc; }
202
203
24
std::string ReportUnreachableInExit::getEndUserMessage() const {
204
24
  return "Unreachable in exit block.";
205
24
}
206
207
0
bool ReportUnreachableInExit::classof(const RejectReason *RR) {
208
0
  return RR->getKind() == RejectReasonKind::UnreachableInExit;
209
0
}
210
211
//===----------------------------------------------------------------------===//
212
// ReportIrreducibleRegion.
213
214
0
std::string ReportIrreducibleRegion::getMessage() const {
215
0
  return "Irreducible region encountered: " + R->getNameStr();
216
0
}
217
218
3
const DebugLoc &ReportIrreducibleRegion::getDebugLoc() const { return DbgLoc; }
219
220
3
std::string ReportIrreducibleRegion::getEndUserMessage() const {
221
3
  return "Irreducible region encountered in control flow.";
222
3
}
223
224
0
bool ReportIrreducibleRegion::classof(const RejectReason *RR) {
225
0
  return RR->getKind() == RejectReasonKind::IrreducibleRegion;
226
0
}
227
228
//===----------------------------------------------------------------------===//
229
// ReportAffFunc.
230
231
ReportAffFunc::ReportAffFunc(const RejectReasonKind K, const Instruction *Inst)
232
235
    : RejectReason(K), Inst(Inst) {}
233
234
0
bool ReportAffFunc::classof(const RejectReason *RR) {
235
0
  return RR->getKind() >= RejectReasonKind::AffFunc &&
236
0
         RR->getKind() <= RejectReasonKind::LastAffFunc;
237
0
}
238
239
//===----------------------------------------------------------------------===//
240
// ReportUndefCond.
241
242
0
std::string ReportUndefCond::getMessage() const {
243
0
  return ("Condition based on 'undef' value in BB: " + BB->getName()).str();
244
0
}
245
246
0
bool ReportUndefCond::classof(const RejectReason *RR) {
247
0
  return RR->getKind() == RejectReasonKind::UndefCond;
248
0
}
249
250
//===----------------------------------------------------------------------===//
251
// ReportInvalidCond.
252
253
0
std::string ReportInvalidCond::getMessage() const {
254
0
  return ("Condition in BB '" + BB->getName()).str() +
255
0
         "' neither constant nor an icmp instruction";
256
0
}
257
258
0
bool ReportInvalidCond::classof(const RejectReason *RR) {
259
0
  return RR->getKind() == RejectReasonKind::InvalidCond;
260
0
}
261
262
//===----------------------------------------------------------------------===//
263
// ReportUndefOperand.
264
265
0
std::string ReportUndefOperand::getMessage() const {
266
0
  return ("undef operand in branch at BB: " + BB->getName()).str();
267
0
}
268
269
0
bool ReportUndefOperand::classof(const RejectReason *RR) {
270
0
  return RR->getKind() == RejectReasonKind::UndefOperand;
271
0
}
272
273
//===----------------------------------------------------------------------===//
274
// ReportNonAffBranch.
275
276
0
std::string ReportNonAffBranch::getMessage() const {
277
0
  return ("Non affine branch in BB '" + BB->getName()).str() +
278
0
         "' with LHS: " + *LHS + " and RHS: " + *RHS;
279
0
}
280
281
0
bool ReportNonAffBranch::classof(const RejectReason *RR) {
282
0
  return RR->getKind() == RejectReasonKind::NonAffBranch;
283
0
}
284
285
//===----------------------------------------------------------------------===//
286
// ReportNoBasePtr.
287
288
0
std::string ReportNoBasePtr::getMessage() const { return "No base pointer"; }
289
290
0
bool ReportNoBasePtr::classof(const RejectReason *RR) {
291
0
  return RR->getKind() == RejectReasonKind::NoBasePtr;
292
0
}
293
294
//===----------------------------------------------------------------------===//
295
// ReportUndefBasePtr.
296
297
0
std::string ReportUndefBasePtr::getMessage() const {
298
0
  return "Undefined base pointer";
299
0
}
300
301
0
bool ReportUndefBasePtr::classof(const RejectReason *RR) {
302
0
  return RR->getKind() == RejectReasonKind::UndefBasePtr;
303
0
}
304
305
//===----------------------------------------------------------------------===//
306
// ReportVariantBasePtr.
307
308
0
std::string ReportVariantBasePtr::getMessage() const {
309
0
  return "Base address not invariant in current region:" + *BaseValue;
310
0
}
311
312
10
std::string ReportVariantBasePtr::getEndUserMessage() const {
313
10
  return "The base address of this array is not invariant inside the loop";
314
10
}
315
316
0
bool ReportVariantBasePtr::classof(const RejectReason *RR) {
317
0
  return RR->getKind() == RejectReasonKind::VariantBasePtr;
318
0
}
319
320
//===----------------------------------------------------------------------===//
321
// ReportDifferentArrayElementSize
322
323
0
std::string ReportDifferentArrayElementSize::getMessage() const {
324
0
  return "Access to one array through data types of different size";
325
0
}
326
327
0
bool ReportDifferentArrayElementSize::classof(const RejectReason *RR) {
328
0
  return RR->getKind() == RejectReasonKind::DifferentElementSize;
329
0
}
330
331
0
std::string ReportDifferentArrayElementSize::getEndUserMessage() const {
332
0
  llvm::StringRef BaseName = BaseValue->getName();
333
0
  std::string Name = (BaseName.size() > 0) ? 
BaseName0
:
"UNKNOWN"0
;
334
0
  return "The array \"" + Name +
335
0
         "\" is accessed through elements that differ "
336
0
         "in size";
337
0
}
338
339
//===----------------------------------------------------------------------===//
340
// ReportNonAffineAccess.
341
342
0
std::string ReportNonAffineAccess::getMessage() const {
343
0
  return "Non affine access function: " + *AccessFunction;
344
0
}
345
346
0
bool ReportNonAffineAccess::classof(const RejectReason *RR) {
347
0
  return RR->getKind() == RejectReasonKind::NonAffineAccess;
348
0
}
349
350
52
std::string ReportNonAffineAccess::getEndUserMessage() const {
351
52
  llvm::StringRef BaseName = BaseValue->getName();
352
52
  std::string Name = (BaseName.size() > 0) ? 
BaseName52
:
"UNKNOWN"0
;
353
52
  return "The array subscript of \"" + Name + "\" is not affine";
354
52
}
355
356
//===----------------------------------------------------------------------===//
357
// ReportLoopBound.
358
359
ReportLoopBound::ReportLoopBound(Loop *L, const SCEV *LoopCount)
360
    : RejectReason(RejectReasonKind::LoopBound), L(L), LoopCount(LoopCount),
361
143
      Loc(L->getStartLoc()) {}
362
363
0
std::string ReportLoopBound::getMessage() const {
364
0
  return "Non affine loop bound '" + *LoopCount +
365
0
         "' in loop: " + L->getHeader()->getName();
366
0
}
367
368
136
const DebugLoc &ReportLoopBound::getDebugLoc() const { return Loc; }
369
370
0
bool ReportLoopBound::classof(const RejectReason *RR) {
371
0
  return RR->getKind() == RejectReasonKind::LoopBound;
372
0
}
373
374
136
std::string ReportLoopBound::getEndUserMessage() const {
375
136
  return "Failed to derive an affine function from the loop bounds.";
376
136
}
377
378
//===----------------------------------------------------------------------===//
379
// ReportLoopHasNoExit.
380
381
0
std::string ReportLoopHasNoExit::getMessage() const {
382
0
  return "Loop " + L->getHeader()->getName() + " has no exit.";
383
0
}
384
385
0
bool ReportLoopHasNoExit::classof(const RejectReason *RR) {
386
0
  return RR->getKind() == RejectReasonKind::LoopHasNoExit;
387
0
}
388
389
14
const DebugLoc &ReportLoopHasNoExit::getDebugLoc() const { return Loc; }
390
391
14
std::string ReportLoopHasNoExit::getEndUserMessage() const {
392
14
  return "Loop cannot be handled because it has no exit.";
393
14
}
394
395
//===----------------------------------------------------------------------===//
396
// ReportFuncCall.
397
398
ReportFuncCall::ReportFuncCall(Instruction *Inst)
399
12
    : RejectReason(RejectReasonKind::FuncCall), Inst(Inst) {}
400
401
0
std::string ReportFuncCall::getMessage() const {
402
0
  return "Call instruction: " + *Inst;
403
0
}
404
405
11
const DebugLoc &ReportFuncCall::getDebugLoc() const {
406
11
  return Inst->getDebugLoc();
407
11
}
408
409
11
std::string ReportFuncCall::getEndUserMessage() const {
410
11
  return "This function call cannot be handled. "
411
11
         "Try to inline it.";
412
11
}
413
414
0
bool ReportFuncCall::classof(const RejectReason *RR) {
415
0
  return RR->getKind() == RejectReasonKind::FuncCall;
416
0
}
417
418
//===----------------------------------------------------------------------===//
419
// ReportNonSimpleMemoryAccess
420
421
ReportNonSimpleMemoryAccess::ReportNonSimpleMemoryAccess(Instruction *Inst)
422
0
    : ReportOther(RejectReasonKind::NonSimpleMemoryAccess), Inst(Inst) {}
423
424
0
std::string ReportNonSimpleMemoryAccess::getMessage() const {
425
0
  return "Non-simple memory access: " + *Inst;
426
0
}
427
428
0
const DebugLoc &ReportNonSimpleMemoryAccess::getDebugLoc() const {
429
0
  return Inst->getDebugLoc();
430
0
}
431
432
0
std::string ReportNonSimpleMemoryAccess::getEndUserMessage() const {
433
0
  return "Volatile memory accesses or memory accesses for atomic types "
434
0
         "are not supported.";
435
0
}
436
437
0
bool ReportNonSimpleMemoryAccess::classof(const RejectReason *RR) {
438
0
  return RR->getKind() == RejectReasonKind::NonSimpleMemoryAccess;
439
0
}
440
441
//===----------------------------------------------------------------------===//
442
// ReportAlias.
443
444
ReportAlias::ReportAlias(Instruction *Inst, AliasSet &AS)
445
3
    : RejectReason(RejectReasonKind::Alias), Inst(Inst) {
446
3
447
3
  for (const auto &I : AS)
448
6
    Pointers.push_back(I.getValue());
449
3
}
450
451
std::string ReportAlias::formatInvalidAlias(std::string Prefix,
452
3
                                            std::string Suffix) const {
453
3
  std::string Message;
454
3
  raw_string_ostream OS(Message);
455
3
456
3
  OS << Prefix;
457
3
458
3
  for (PointerSnapshotTy::const_iterator PI = Pointers.begin(),
459
3
                                         PE = Pointers.end();
460
6
       ;) {
461
6
    const Value *V = *PI;
462
6
    assert(V && "Diagnostic info does not match found LLVM-IR anymore.");
463
6
464
6
    if (V->getName().size() == 0)
465
1
      OS << "\" <unknown> \"";
466
6
    else
467
5
      OS << "\"" << V->getName() << "\"";
468
6
469
6
    ++PI;
470
6
471
6
    if (PI != PE)
472
3
      OS << ", ";
473
6
    else
474
3
      break;
475
6
  }
476
3
477
3
  OS << Suffix;
478
3
479
3
  return OS.str();
480
3
}
481
482
0
std::string ReportAlias::getMessage() const {
483
0
  return formatInvalidAlias("Possible aliasing: ");
484
0
}
485
486
3
std::string ReportAlias::getEndUserMessage() const {
487
3
  return formatInvalidAlias("Accesses to the arrays ",
488
3
                            " may access the same memory.");
489
3
}
490
491
3
const DebugLoc &ReportAlias::getDebugLoc() const { return Inst->getDebugLoc(); }
492
493
0
bool ReportAlias::classof(const RejectReason *RR) {
494
0
  return RR->getKind() == RejectReasonKind::Alias;
495
0
}
496
497
//===----------------------------------------------------------------------===//
498
// ReportOther.
499
500
0
std::string ReportOther::getMessage() const { return "Unknown reject reason"; }
501
502
149
ReportOther::ReportOther(const RejectReasonKind K) : RejectReason(K) {}
503
504
0
bool ReportOther::classof(const RejectReason *RR) {
505
0
  return RR->getKind() >= RejectReasonKind::Other &&
506
0
         RR->getKind() <= RejectReasonKind::LastOther;
507
0
}
508
509
//===----------------------------------------------------------------------===//
510
// ReportIntToPtr.
511
ReportIntToPtr::ReportIntToPtr(Instruction *BaseValue)
512
1
    : ReportOther(RejectReasonKind::IntToPtr), BaseValue(BaseValue) {}
513
514
0
std::string ReportIntToPtr::getMessage() const {
515
0
  return "Find bad intToptr prt: " + *BaseValue;
516
0
}
517
518
1
const DebugLoc &ReportIntToPtr::getDebugLoc() const {
519
1
  return BaseValue->getDebugLoc();
520
1
}
521
522
0
bool ReportIntToPtr::classof(const RejectReason *RR) {
523
0
  return RR->getKind() == RejectReasonKind::IntToPtr;
524
0
}
525
526
//===----------------------------------------------------------------------===//
527
// ReportAlloca.
528
529
ReportAlloca::ReportAlloca(Instruction *Inst)
530
0
    : ReportOther(RejectReasonKind::Alloca), Inst(Inst) {}
531
532
0
std::string ReportAlloca::getMessage() const {
533
0
  return "Alloca instruction: " + *Inst;
534
0
}
535
536
0
const DebugLoc &ReportAlloca::getDebugLoc() const {
537
0
  return Inst->getDebugLoc();
538
0
}
539
540
0
bool ReportAlloca::classof(const RejectReason *RR) {
541
0
  return RR->getKind() == RejectReasonKind::Alloca;
542
0
}
543
544
//===----------------------------------------------------------------------===//
545
// ReportUnknownInst.
546
547
ReportUnknownInst::ReportUnknownInst(Instruction *Inst)
548
51
    : ReportOther(RejectReasonKind::UnknownInst), Inst(Inst) {}
549
550
0
std::string ReportUnknownInst::getMessage() const {
551
0
  return "Unknown instruction: " + *Inst;
552
0
}
553
554
27
const DebugLoc &ReportUnknownInst::getDebugLoc() const {
555
27
  return Inst->getDebugLoc();
556
27
}
557
558
0
bool ReportUnknownInst::classof(const RejectReason *RR) {
559
0
  return RR->getKind() == RejectReasonKind::UnknownInst;
560
0
}
561
562
//===----------------------------------------------------------------------===//
563
// ReportEntry.
564
ReportEntry::ReportEntry(BasicBlock *BB)
565
83
    : ReportOther(RejectReasonKind::Entry), BB(BB) {}
566
567
0
std::string ReportEntry::getMessage() const {
568
0
  return "Region containing entry block of function is invalid!";
569
0
}
570
571
83
std::string ReportEntry::getEndUserMessage() const {
572
83
  return "Scop contains function entry (not yet supported).";
573
83
}
574
575
83
const DebugLoc &ReportEntry::getDebugLoc() const {
576
83
  return BB->getTerminator()->getDebugLoc();
577
83
}
578
579
0
bool ReportEntry::classof(const RejectReason *RR) {
580
0
  return RR->getKind() == RejectReasonKind::Entry;
581
0
}
582
583
//===----------------------------------------------------------------------===//
584
// ReportUnprofitable.
585
ReportUnprofitable::ReportUnprofitable(Region *R)
586
14
    : ReportOther(RejectReasonKind::Unprofitable), R(R) {}
587
588
0
std::string ReportUnprofitable::getMessage() const {
589
0
  return "Region can not profitably be optimized!";
590
0
}
591
592
14
std::string ReportUnprofitable::getEndUserMessage() const {
593
14
  return "No profitable polyhedral optimization found";
594
14
}
595
596
14
const DebugLoc &ReportUnprofitable::getDebugLoc() const {
597
14
  for (const BasicBlock *BB : R->blocks())
598
60
    for (const Instruction &Inst : *BB)
599
226
      
if (const DebugLoc &226
DL226
= Inst.getDebugLoc())
600
3
        return DL;
601
14
602
11
  return R->getEntry()->getTerminator()->getDebugLoc();
603
14
}
604
605
0
bool ReportUnprofitable::classof(const RejectReason *RR) {
606
0
  return RR->getKind() == RejectReasonKind::Unprofitable;
607
0
}
608
} // namespace polly