#include "llvm/Pass.h"
#include "llvm/Analysis/AliasSetTracker.h"
+#include "polly/ScopDetectionDiagnostic.h"
+
#include <set>
#include <map>
Region &CurRegion; // The region to check.
AliasSetTracker AST; // The AliasSetTracker to hold the alias information.
bool Verifying; // If we are in the verification phase?
+ RejectLog Log;
// Map a base pointer to all access functions accessing it.
BaseToAFs NonAffineAccesses, AffineAccesses;
DetectionContext(Region &R, AliasAnalysis &AA, bool Verify)
- : CurRegion(R), AST(AA), Verifying(Verify) {}
+ : CurRegion(R), AST(AA), Verifying(Verify), Log(&R) {}
};
// Remember the valid regions
// Invalid regions and the reason they fail.
std::map<const Region *, std::string> InvalidRegions;
+ // Remember a list of errors for every region.
+ mutable std::map<const Region *, RejectLog> RejectLogs;
+
// Remember the invalid functions producted by backends;
typedef std::set<const Function *> FunctionSet;
FunctionSet InvalidFunctions;
const_iterator end() const { return ValidRegions.end(); }
//@}
+ /// @name Reject log iterators
+ ///
+ /// These iterators iterate over the logs of all rejected regions of this
+ // function.
+ //@{
+ typedef std::map<const Region *, RejectLog>::iterator reject_iterator;
+ typedef std::map<const Region *, RejectLog>::const_iterator
+ const_reject_iterator;
+
+ reject_iterator reject_begin() { return RejectLogs.begin(); }
+ reject_iterator reject_end() { return RejectLogs.end(); }
+
+ const_reject_iterator reject_begin() const { return RejectLogs.begin(); }
+ const_reject_iterator reject_end() const { return RejectLogs.end(); }
+ //@}
+
/// @brief Mark the function as invalid so we will not extract any scop from
/// the function.
///
virtual std::string getMessage() const = 0;
};
+typedef std::shared_ptr<RejectReason> RejectReasonPtr;
+
+/// @brief Stores all errors that ocurred during the detection.
+class RejectLog {
+ Region *R;
+ llvm::SmallVector<RejectReasonPtr, 1> ErrorReports;
+
+public:
+ explicit RejectLog(Region *R) : R(R) {};
+
+ typedef llvm::SmallVector<RejectReasonPtr, 1>::iterator iterator;
+
+ iterator begin() { return ErrorReports.begin(); }
+ iterator end() { return ErrorReports.end(); }
+
+ const Region *region() const { return R; }
+ void report(RejectReasonPtr Reject) { ErrorReports.push_back(Reject); }
+};
+
//===----------------------------------------------------------------------===//
/// @brief Base class for CFG related reject reasons.
///
Args &&... Arguments) const {
if (!Context.Verifying) {
- RR RejectReason = RR(Arguments...);
- if (PollyTrackFailures)
- LastFailure = RejectReason.getMessage();
+ RejectLog &Log = Context.Log;
+ std::shared_ptr<RR> RejectReason = std::make_shared<RR>(Arguments...);
- DEBUG(dbgs() << RejectReason.getMessage());
+ if (PollyTrackFailures) {
+ Log.report(RejectReason);
+ LastFailure = RejectReason->getMessage();
+ }
+
+ DEBUG(dbgs() << RejectReason->getMessage());
DEBUG(dbgs() << "\n");
} else {
assert(!Assert && "Verification of detected scop failed");
bool ScopDetection::isValidRegion(Region &R) const {
DetectionContext Context(R, *AA, false /*verifying*/);
- return isValidRegion(Context);
+
+ bool RegionIsValid = isValidRegion(Context);
+ if (PollyTrackFailures && !RegionIsValid) {
+ // std::map::insert does not replace.
+ std::pair<reject_iterator, bool> InsertedValue =
+ RejectLogs.insert(std::make_pair(&R, Context.Log));
+ assert(InsertedValue.second && "Two logs generated for the same Region.");
+ }
+
+ return RegionIsValid;
}
bool ScopDetection::isValidRegion(DetectionContext &Context) const {
void ScopDetection::releaseMemory() {
ValidRegions.clear();
InvalidRegions.clear();
+ RejectLogs.clear();
+
// Do not clear the invalid function set.
}