Coverage Report

Created: 2017-08-18 19:41

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