llvm/polly/include/polly/ScopDetectionDiagnostic.h

//===- ScopDetectionDiagnostic.h - Diagnostic for ScopDetection -*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Small set of diagnostic helper classes to encapsulate any errors occurred
// during the detection of Scops.
//
// The ScopDetection defines a set of error classes (via Statistic variables)
// that groups a number of individual errors into a group, e.g. non-affinity
// related errors.
// On error we generate an object that carries enough additional information
// to diagnose the error and generate a helpful error message.
//
//===----------------------------------------------------------------------===//

#ifndef POLLY_SCOPDETECTIONDIAGNOSTIC_H
#define POLLY_SCOPDETECTIONDIAGNOSTIC_H

#include "llvm/Analysis/LoopInfo.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/Instruction.h"
#include <cstddef>

namespace llvm {
class AliasSet;
class BasicBlock;
class OptimizationRemarkEmitter;
class Region;
class SCEV;
} // namespace llvm

namespace polly {
AliasSet;
BasicBlock;
DebugLoc;
Instruction;
Loop;
OptimizationRemarkEmitter;
raw_ostream;
Region;
SCEV;
SmallVector;
Value;

/// Type to hold region delimiters (entry & exit block).
BBPair;

/// Return the region delimiters (entry & exit block) of @p R.
BBPair getBBPairForRegion(const Region *R);

/// Set the begin and end source location for the region limited by @p P.
void getDebugLocations(const BBPair &P, DebugLoc &Begin, DebugLoc &End);

class RejectLog;

/// Emit optimization remarks about the rejected regions to the user.
///
/// This emits the content of the reject log as optimization remarks.
/// Remember to at least track failures (-polly-detect-track-failures).
/// @param P The region delimiters (entry & exit) we emit remarks for.
/// @param Log The error log containing all messages being emitted as remark.
void emitRejectionRemarks(const BBPair &P, const RejectLog &Log,
                          OptimizationRemarkEmitter &ORE);

// Discriminator for LLVM-style RTTI (dyn_cast<> et al.)
enum class RejectReasonKind {};

//===----------------------------------------------------------------------===//
/// Base class of all reject reasons found during Scop detection.
///
/// Subclasses of RejectReason should provide means to capture enough
/// diagnostic information to help clients figure out what and where something
/// went wrong in the Scop detection.
class RejectReason {};

RejectReasonPtr;

/// Stores all errors that occurred during the detection.
class RejectLog final {};

//===----------------------------------------------------------------------===//
/// Base class for CFG related reject reasons.
///
/// Scop candidates that violate structural restrictions can be grouped under
/// this reject reason class.
class ReportCFG : public RejectReason {};

//===----------------------------------------------------------------------===//
/// Captures bad terminator within a Scop candidate.
class ReportInvalidTerminator final : public ReportCFG {};

//===----------------------------------------------------------------------===//
/// Captures irreducible regions in CFG.
class ReportIrreducibleRegion final : public ReportCFG {};

//===----------------------------------------------------------------------===//
/// Captures regions with an unreachable in the exit block.
class ReportUnreachableInExit final : public ReportCFG {};

//===----------------------------------------------------------------------===//
/// Captures regions with an IndirectBr predecessor.
class ReportIndirectPredecessor final : public ReportCFG {};

//===----------------------------------------------------------------------===//
/// Base class for non-affine reject reasons.
///
/// Scop candidates that violate restrictions to affinity are reported under
/// this class.
class ReportAffFunc : public RejectReason {};

//===----------------------------------------------------------------------===//
/// Captures a condition that is based on an 'undef' value.
class ReportUndefCond final : public ReportAffFunc {};

//===----------------------------------------------------------------------===//
/// Captures an invalid condition
///
/// Conditions have to be either constants or icmp instructions.
class ReportInvalidCond final : public ReportAffFunc {};

//===----------------------------------------------------------------------===//
/// Captures an undefined operand.
class ReportUndefOperand final : public ReportAffFunc {};

//===----------------------------------------------------------------------===//
/// Captures a non-affine branch.
class ReportNonAffBranch final : public ReportAffFunc {};

//===----------------------------------------------------------------------===//
/// Captures a missing base pointer.
class ReportNoBasePtr final : public ReportAffFunc {};

//===----------------------------------------------------------------------===//
/// Captures an undefined base pointer.
class ReportUndefBasePtr final : public ReportAffFunc {};

//===----------------------------------------------------------------------===//
/// Captures a base pointer that is not invariant in the region.
class ReportVariantBasePtr final : public ReportAffFunc {};

//===----------------------------------------------------------------------===//
/// Captures a non-affine access function.
class ReportNonAffineAccess final : public ReportAffFunc {};

//===----------------------------------------------------------------------===//
/// Report array accesses with differing element size.
class ReportDifferentArrayElementSize final : public ReportAffFunc {};

//===----------------------------------------------------------------------===//
/// Captures errors with non affine loop bounds.
class ReportLoopBound final : public RejectReason {};

//===----------------------------------------------------------------------===//
/// Captures errors when loop has no exit.
class ReportLoopHasNoExit final : public RejectReason {};

//===----------------------------------------------------------------------===//
/// Captures errors when a loop has multiple exists.
class ReportLoopHasMultipleExits final : public RejectReason {};

//===----------------------------------------------------------------------===//
/// Captures errors when not all loop latches are part of the scop.
class ReportLoopOnlySomeLatches final : public RejectReason {};

//===----------------------------------------------------------------------===//
/// Captures errors with non-side-effect-known function calls.
class ReportFuncCall final : public RejectReason {};

//===----------------------------------------------------------------------===//
/// Captures errors with aliasing.
class ReportAlias final : public RejectReason {};

//===----------------------------------------------------------------------===//
/// Base class for otherwise ungrouped reject reasons.
class ReportOther : public RejectReason {};

//===----------------------------------------------------------------------===//
/// Captures errors with bad IntToPtr instructions.
class ReportIntToPtr final : public ReportOther {};

//===----------------------------------------------------------------------===//
/// Captures errors with alloca instructions.
class ReportAlloca final : public ReportOther {};

//===----------------------------------------------------------------------===//
/// Captures errors with unknown instructions.
class ReportUnknownInst final : public ReportOther {};

//===----------------------------------------------------------------------===//
/// Captures errors with regions containing the function entry block.
class ReportEntry final : public ReportOther {};

//===----------------------------------------------------------------------===//
/// Report regions that seem not profitable to be optimized.
class ReportUnprofitable final : public ReportOther {};

//===----------------------------------------------------------------------===//
/// Captures errors with non-simple memory accesses.
class ReportNonSimpleMemoryAccess final : public ReportOther {};
} // namespace polly

#endif // POLLY_SCOPDETECTIONDIAGNOSTIC_H