diff options
| -rw-r--r-- | polly/include/polly/ScopDetectionDiagnostic.h | 177 | ||||
| -rw-r--r-- | polly/lib/Analysis/ScopDetectionDiagnostic.cpp | 208 | ||||
| -rw-r--r-- | polly/lib/CMakeLists.txt | 1 |
3 files changed, 257 insertions, 129 deletions
diff --git a/polly/include/polly/ScopDetectionDiagnostic.h b/polly/include/polly/ScopDetectionDiagnostic.h index 3eb9e8645c9..26441c01db9 100644 --- a/polly/include/polly/ScopDetectionDiagnostic.h +++ b/polly/include/polly/ScopDetectionDiagnostic.h @@ -5,6 +5,8 @@ // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // +//===----------------------------------------------------------------------===// +// // Small set of diagnostic helper classes to encapsulate any errors occurred // during the detection of Scops. // @@ -13,6 +15,7 @@ // 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_SCOP_DETECTION_DIAGNOSTIC_H #define POLLY_SCOP_DETECTION_DIAGNOSTIC_H @@ -21,39 +24,24 @@ #include "llvm/Analysis/AliasSetTracker.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/Value.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/Twine.h" -#include "llvm/Support/Debug.h" -#include "llvm/Support/raw_ostream.h" -#include <string> - -#define DEBUG_TYPE "polly-detect" +#include "llvm/Analysis/ScalarEvolutionExpressions.h" -#define BADSCOP_STAT(NAME, DESC) \ - STATISTIC(Bad##NAME##ForScop, "Number of bad regions for Scop: " DESC) - -BADSCOP_STAT(CFG, "CFG too complex"); -BADSCOP_STAT(IndVar, "Non canonical induction variable in loop"); -BADSCOP_STAT(IndEdge, "Found invalid region entering edges"); -BADSCOP_STAT(LoopBound, "Loop bounds can not be computed"); -BADSCOP_STAT(FuncCall, "Function call with side effects appeared"); -BADSCOP_STAT(AffFunc, "Expression not affine"); -BADSCOP_STAT(Alias, "Found base address alias"); -BADSCOP_STAT(SimpleLoop, "Loop not in -loop-simplify form"); -BADSCOP_STAT(Other, "Others"); - -namespace polly { +#include <string> +#include <memory> -/// @brief Small string conversion via raw_string_stream. -template <typename T> std::string operator+(Twine LHS, const T &RHS) { - std::string Buf; - raw_string_ostream fmt(Buf); - fmt << RHS; - fmt.flush(); +using namespace llvm; - return LHS.concat(Buf).str(); +namespace llvm { +class SCEV; +class BasicBlock; +class Value; +class Region; } +namespace polly { //===----------------------------------------------------------------------===// /// @brief Base class of all reject reasons found during Scop detection. /// @@ -79,7 +67,7 @@ public: class ReportCFG : public RejectReason { //===--------------------------------------------------------------------===// public: - ReportCFG() { ++BadCFGForScop; } + ReportCFG(); }; class ReportNonBranchTerminator : public ReportCFG { @@ -90,9 +78,7 @@ public: /// @name RejectReason interface //@{ - virtual std::string getMessage() const { - return ("Non branch instruction terminates BB: " + BB->getName()).str(); - } + virtual std::string getMessage() const; //@} }; @@ -109,9 +95,7 @@ public: /// @name RejectReason interface //@{ - virtual std::string getMessage() const { - return ("Not well structured condition at BB: " + BB->getName()).str(); - } + virtual std::string getMessage() const; //@} }; @@ -123,7 +107,7 @@ public: class ReportAffFunc : public RejectReason { //===--------------------------------------------------------------------===// public: - ReportAffFunc() { ++BadAffFuncForScop; } + ReportAffFunc(); }; //===----------------------------------------------------------------------===// @@ -139,9 +123,7 @@ public: /// @name RejectReason interface //@{ - virtual std::string getMessage() const { - return ("Condition based on 'undef' value in BB: " + BB->getName()).str(); - } + virtual std::string getMessage() const; //@} }; @@ -160,10 +142,7 @@ public: /// @name RejectReason interface //@{ - virtual std::string getMessage() const { - return ("Condition in BB '" + BB->getName()).str() + - "' neither constant nor an icmp instruction"; - } + virtual std::string getMessage() const; //@} }; @@ -180,9 +159,7 @@ public: /// @name RejectReason interface //@{ - virtual std::string getMessage() const { - return ("undef operand in branch at BB: " + BB->getName()).str(); - } + virtual std::string getMessage() const; //@} }; @@ -206,10 +183,7 @@ public: /// @name RejectReason interface //@{ - virtual std::string getMessage() const { - return ("Non affine branch in BB '" + BB->getName()).str() + - "' with LHS: " + *LHS + " and RHS: " + *RHS; - } + virtual std::string getMessage() const; //@} }; @@ -220,7 +194,7 @@ class ReportNoBasePtr : public ReportAffFunc { public: /// @name RejectReason interface //@{ - virtual std::string getMessage() const { return "No base pointer"; } + virtual std::string getMessage() const; //@} }; @@ -231,7 +205,7 @@ class ReportUndefBasePtr : public ReportAffFunc { public: /// @name RejectReason interface //@{ - virtual std::string getMessage() const { return "Undefined base pointer"; } + virtual std::string getMessage() const; //@} }; @@ -248,9 +222,7 @@ public: /// @name RejectReason interface //@{ - virtual std::string getMessage() const { - return "Base address not invariant in current region:" + *BaseValue; - } + virtual std::string getMessage() const; //@} }; @@ -268,9 +240,7 @@ public: /// @name RejectReason interface //@{ - virtual std::string getMessage() const { - return "Non affine access function: " + *AccessFunction; - } + virtual std::string getMessage() const; //@} }; @@ -282,7 +252,7 @@ public: class ReportIndVar : public RejectReason { //===--------------------------------------------------------------------===// public: - ReportIndVar() { ++BadIndVarForScop; } + ReportIndVar(); }; //===----------------------------------------------------------------------===// @@ -298,9 +268,7 @@ public: /// @name RejectReason interface //@{ - virtual std::string getMessage() const { - return "SCEV of PHI node refers to SSA names in region: " + *Inst; - } + virtual std::string getMessage() const; //@} }; @@ -317,9 +285,7 @@ public: /// @name RejectReason interface //@{ - virtual std::string getMessage() const { - return "Non canonical PHI node: " + *Inst; - } + virtual std::string getMessage() const; //@} }; @@ -336,10 +302,7 @@ public: /// @name RejectReason interface //@{ - virtual std::string getMessage() const { - return ("No canonical IV at loop header: " + L->getHeader()->getName()) - .str(); - } + virtual std::string getMessage() const; //@} }; @@ -348,13 +311,12 @@ public: class ReportIndEdge : public RejectReason { //===--------------------------------------------------------------------===// public: - ReportIndEdge() { ++BadIndEdgeForScop; } + ReportIndEdge(); /// @name RejectReason interface //@{ - virtual std::string getMessage() const { - return "Region has invalid entering edges!"; - } + virtual std::string getMessage() const; + //@} }; //===----------------------------------------------------------------------===// @@ -369,16 +331,11 @@ class ReportLoopBound : public RejectReason { const SCEV *LoopCount; public: - ReportLoopBound(Loop *L, const SCEV *LoopCount) : L(L), LoopCount(LoopCount) { - ++BadLoopBoundForScop; - } + ReportLoopBound(Loop *L, const SCEV *LoopCount); /// @name RejectReason interface //@{ - virtual std::string getMessage() const { - return "Non affine loop bound '" + *LoopCount + "' in loop: " + - L->getHeader()->getName(); - } + virtual std::string getMessage() const; //@} }; @@ -391,11 +348,11 @@ class ReportFuncCall : public RejectReason { Instruction *Inst; public: - ReportFuncCall(Instruction *Inst) : Inst(Inst) { ++BadFuncCallForScop; } + ReportFuncCall(Instruction *Inst); /// @name RejectReason interface //@{ - std::string getMessage() const { return "Call instruction: " + *Inst; } + std::string getMessage() const; //@} }; @@ -410,46 +367,14 @@ class ReportAlias : public RejectReason { /// @brief Format an invalid alias set. /// /// @param AS The invalid alias set to format. - std::string formatInvalidAlias(AliasSet &AS) const { - std::string Message; - raw_string_ostream OS(Message); - - OS << "Possible aliasing: "; - - std::vector<Value *> Pointers; - - for (const auto &I : AS) - Pointers.push_back(I.getValue()); - - std::sort(Pointers.begin(), Pointers.end()); - - for (std::vector<Value *>::iterator PI = Pointers.begin(), - PE = Pointers.end(); - ;) { - Value *V = *PI; - - if (V->getName().size() == 0) - OS << "\"" << *V << "\""; - else - OS << "\"" << V->getName() << "\""; - - ++PI; - - if (PI != PE) - OS << ", "; - else - break; - } - - return OS.str(); - } + std::string formatInvalidAlias(AliasSet &AS) const; public: - ReportAlias(AliasSet *AS) : AS(AS) { ++BadAliasForScop; } + ReportAlias(AliasSet *AS); /// @name RejectReason interface //@{ - std::string getMessage() const { return formatInvalidAlias(*AS); } + std::string getMessage() const; //@} }; @@ -458,13 +383,11 @@ public: class ReportSimpleLoop : public RejectReason { //===--------------------------------------------------------------------===// public: - ReportSimpleLoop() { ++BadSimpleLoopForScop; } + ReportSimpleLoop(); /// @name RejectReason interface //@{ - std::string getMessage() const { - return "Loop not in simplify form is invalid!"; - } + std::string getMessage() const; //@} }; @@ -473,7 +396,7 @@ public: class ReportOther : public RejectReason { //===--------------------------------------------------------------------===// public: - ReportOther() { ++BadOtherForScop; } + ReportOther(); /// @name RejectReason interface //@{ @@ -494,9 +417,7 @@ public: /// @name RejectReason interface //@{ - std::string getMessage() const { - return "Find bad intToptr prt: " + *BaseValue; - } + std::string getMessage() const; //@} }; @@ -511,7 +432,7 @@ public: /// @name RejectReason interface //@{ - std::string getMessage() const { return "Alloca instruction: " + *Inst; } + std::string getMessage() const; //@} }; @@ -526,7 +447,7 @@ public: /// @name RejectReason interface //@{ - std::string getMessage() const { return "Unknown instruction: " + *Inst; } + std::string getMessage() const; //@} }; @@ -537,7 +458,7 @@ class ReportPHIinExit : public ReportOther { public: /// @name RejectReason interface //@{ - std::string getMessage() const { return "PHI node in exit BB"; } + std::string getMessage() const; //@} }; @@ -548,9 +469,7 @@ class ReportEntry : public ReportOther { public: /// @name RejectReason interface //@{ - std::string getMessage() const { - return "Region containing entry block of function is invalid!"; - } + std::string getMessage() const; //@} }; diff --git a/polly/lib/Analysis/ScopDetectionDiagnostic.cpp b/polly/lib/Analysis/ScopDetectionDiagnostic.cpp new file mode 100644 index 00000000000..4a3091d815b --- /dev/null +++ b/polly/lib/Analysis/ScopDetectionDiagnostic.cpp @@ -0,0 +1,208 @@ +//=== ScopDetectionDiagnostic.cpp - Error diagnostics --------- -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// +#include "polly/ScopDetectionDiagnostic.h" + +#include "llvm/Analysis/LoopInfo.h" +#include "llvm/Analysis/AliasSetTracker.h" +#include "llvm/IR/BasicBlock.h" +#include "llvm/IR/Value.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/Statistic.h" + +#define DEBUG_TYPE "polly-detect" +#include "llvm/Support/Debug.h" + +#include <string> + +#define BADSCOP_STAT(NAME, DESC) \ + STATISTIC(Bad##NAME##ForScop, "Number of bad regions for Scop: " DESC) + +BADSCOP_STAT(CFG, "CFG too complex"); +BADSCOP_STAT(IndVar, "Non canonical induction variable in loop"); +BADSCOP_STAT(IndEdge, "Found invalid region entering edges"); +BADSCOP_STAT(LoopBound, "Loop bounds can not be computed"); +BADSCOP_STAT(FuncCall, "Function call with side effects appeared"); +BADSCOP_STAT(AffFunc, "Expression not affine"); +BADSCOP_STAT(Alias, "Found base address alias"); +BADSCOP_STAT(SimpleLoop, "Loop not in -loop-simplify form"); +BADSCOP_STAT(Other, "Others"); + +namespace polly { +/// @brief Small string conversion via raw_string_stream. +template <typename T> std::string operator+(Twine LHS, const T &RHS) { + std::string Buf; + raw_string_ostream fmt(Buf); + fmt << RHS; + fmt.flush(); + + return LHS.concat(Buf).str(); +} + +//===----------------------------------------------------------------------===// +// ReportCFG. + +ReportCFG::ReportCFG() { ++BadCFGForScop; } + +std::string ReportNonBranchTerminator::getMessage() const { + return ("Non branch instruction terminates BB: " + BB->getName()).str(); +} + +std::string ReportCondition::getMessage() const { + return ("Not well structured condition at BB: " + BB->getName()).str(); +} + +ReportAffFunc::ReportAffFunc() { ++BadAffFuncForScop; } + +std::string ReportUndefCond::getMessage() const { + return ("Condition based on 'undef' value in BB: " + BB->getName()).str(); +} + +std::string ReportInvalidCond::getMessage() const { + return ("Condition in BB '" + BB->getName()).str() + + "' neither constant nor an icmp instruction"; +} + +std::string ReportUndefOperand::getMessage() const { + return ("undef operand in branch at BB: " + BB->getName()).str(); +} + +std::string ReportNonAffBranch::getMessage() const { + return ("Non affine branch in BB '" + BB->getName()).str() + "' with LHS: " + + *LHS + " and RHS: " + *RHS; +} + +std::string ReportNoBasePtr::getMessage() const { return "No base pointer"; } + +std::string ReportUndefBasePtr::getMessage() const { + return "Undefined base pointer"; +} + +std::string ReportVariantBasePtr::getMessage() const { + return "Base address not invariant in current region:" + *BaseValue; +} + +std::string ReportNonAffineAccess::getMessage() const { + return "Non affine access function: " + *AccessFunction; +} + +ReportIndVar::ReportIndVar() { ++BadIndVarForScop; } + +std::string ReportPhiNodeRefInRegion::getMessage() const { + return "SCEV of PHI node refers to SSA names in region: " + *Inst; +} + +std::string ReportNonCanonicalPhiNode::getMessage() const { + return "Non canonical PHI node: " + *Inst; +} + +std::string ReportLoopHeader::getMessage() const { + return ("No canonical IV at loop header: " + L->getHeader()->getName()).str(); +} + +ReportIndEdge::ReportIndEdge() { ++BadIndEdgeForScop; } + +std::string ReportIndEdge::getMessage() const { + return "Region has invalid entering edges!"; +} + +ReportLoopBound::ReportLoopBound(Loop *L, const SCEV *LoopCount) + : L(L), LoopCount(LoopCount) { + ++BadLoopBoundForScop; +} + +std::string ReportLoopBound::getMessage() const { + return "Non affine loop bound '" + *LoopCount + "' in loop: " + + L->getHeader()->getName(); +} + +ReportFuncCall::ReportFuncCall(Instruction *Inst) : Inst(Inst) { + ++BadFuncCallForScop; +} + +std::string ReportFuncCall::getMessage() const { + return "Call instruction: " + *Inst; +} + +ReportAlias::ReportAlias(AliasSet *AS) : AS(AS) { ++BadAliasForScop; } + +std::string ReportAlias::formatInvalidAlias(AliasSet &AS) const { + std::string Message; + raw_string_ostream OS(Message); + + OS << "Possible aliasing: "; + + std::vector<Value *> Pointers; + + for (const auto &I : AS) + Pointers.push_back(I.getValue()); + + std::sort(Pointers.begin(), Pointers.end()); + + for (std::vector<Value *>::iterator PI = Pointers.begin(), + PE = Pointers.end(); + ;) { + Value *V = *PI; + + if (V->getName().size() == 0) + OS << "\"" << *V << "\""; + else + OS << "\"" << V->getName() << "\""; + + ++PI; + + if (PI != PE) + OS << ", "; + else + break; + } + + return OS.str(); +} + +std::string ReportAlias::getMessage() const { return formatInvalidAlias(*AS); } + +ReportSimpleLoop::ReportSimpleLoop() { ++BadSimpleLoopForScop; } + +std::string ReportSimpleLoop::getMessage() const { + return "Loop not in simplify form is invalid!"; +} + +ReportOther::ReportOther() { ++BadOtherForScop; } + +std::string ReportIntToPtr::getMessage() const { + return "Find bad intToptr prt: " + *BaseValue; +} + +std::string ReportAlloca::getMessage() const { + return "Alloca instruction: " + *Inst; +} + +std::string ReportUnknownInst::getMessage() const { + return "Unknown instruction: " + *Inst; +} + +std::string ReportPHIinExit::getMessage() const { + return "PHI node in exit BB"; +} + +std::string ReportEntry::getMessage() const { + return "Region containing entry block of function is invalid!"; +} +} // namespace polly diff --git a/polly/lib/CMakeLists.txt b/polly/lib/CMakeLists.txt index 1ac4be1eaa4..81273ae09c9 100644 --- a/polly/lib/CMakeLists.txt +++ b/polly/lib/CMakeLists.txt @@ -36,6 +36,7 @@ endif (SCOPLIB_FOUND) add_polly_library(Polly Analysis/Dependences.cpp Analysis/ScopDetection.cpp + Analysis/ScopDetectionDiagnostic.cpp Analysis/ScopInfo.cpp Analysis/ScopGraphPrinter.cpp Analysis/ScopPass.cpp |

