summaryrefslogtreecommitdiffstats
path: root/polly/lib
diff options
context:
space:
mode:
Diffstat (limited to 'polly/lib')
-rw-r--r--polly/lib/Analysis/ScopInfo.cpp40
-rw-r--r--polly/lib/Support/SCEVValidator.cpp29
2 files changed, 66 insertions, 3 deletions
diff --git a/polly/lib/Analysis/ScopInfo.cpp b/polly/lib/Analysis/ScopInfo.cpp
index 08566c550c5..5faeb6f0817 100644
--- a/polly/lib/Analysis/ScopInfo.cpp
+++ b/polly/lib/Analysis/ScopInfo.cpp
@@ -1998,16 +1998,50 @@ const SCEV *Scop::getRepresentingInvariantLoadSCEV(const SCEV *S) {
return SCEVSensitiveParameterRewriter::rewrite(S, *SE, InvEquivClassVMap);
}
+// This table of function names is used to translate parameter names in more
+// human-readable names. This makes it easier to interpret Polly analysis
+// results.
+StringMap<std::string> KnownNames = {
+ {"_Z13get_global_idj", "global_id"},
+ {"_Z12get_local_idj", "local_id"},
+ {"_Z15get_global_sizej", "global_size"},
+ {"_Z14get_local_sizej", "local_size"},
+ {"_Z12get_work_dimv", "work_dim"},
+ {"_Z17get_global_offsetj", "global_offset"},
+ {"_Z12get_group_idj", "group_id"},
+ {"_Z14get_num_groupsj", "num_groups"},
+};
+
+static std::string getCallParamName(CallInst *Call) {
+ std::string Result;
+ raw_string_ostream OS(Result);
+ std::string Name = Call->getCalledFunction()->getName();
+
+ auto Iterator = KnownNames.find(Name);
+ if (Iterator != KnownNames.end())
+ Name = "__" + KnownNames[Name];
+ OS << Name;
+ for (auto &Operand : Call->arg_operands()) {
+ ConstantInt *Op = cast<ConstantInt>(&Operand);
+ OS << "_" << Op->getValue();
+ }
+ OS.flush();
+ return Result;
+}
+
void Scop::createParameterId(const SCEV *Parameter) {
assert(Parameters.count(Parameter));
assert(!ParameterIds.count(Parameter));
std::string ParameterName = "p_" + std::to_string(getNumParams() - 1);
- if (UseInstructionNames) {
- if (const SCEVUnknown *ValueParameter = dyn_cast<SCEVUnknown>(Parameter)) {
- Value *Val = ValueParameter->getValue();
+ if (const SCEVUnknown *ValueParameter = dyn_cast<SCEVUnknown>(Parameter)) {
+ Value *Val = ValueParameter->getValue();
+ CallInst *Call = dyn_cast<CallInst>(Val);
+ if (Call && isConstCall(Call)) {
+ ParameterName = getCallParamName(Call);
+ } else if (UseInstructionNames) {
// If this parameter references a specific Value and this value has a name
// we use this name as it is likely to be unique and more useful than just
// a number.
diff --git a/polly/lib/Support/SCEVValidator.cpp b/polly/lib/Support/SCEVValidator.cpp
index 848357f5afb..0e159f42993 100644
--- a/polly/lib/Support/SCEVValidator.cpp
+++ b/polly/lib/Support/SCEVValidator.cpp
@@ -117,6 +117,17 @@ raw_ostream &operator<<(raw_ostream &OS, class ValidatorResult &VR) {
return OS;
}
+bool polly::isConstCall(llvm::CallInst *Call) {
+ if (Call->mayReadOrWriteMemory())
+ return false;
+
+ for (auto &Operand : Call->arg_operands())
+ if (!isa<ConstantInt>(&Operand))
+ return false;
+
+ return true;
+}
+
/// Check if a SCEV is valid in a SCoP.
struct SCEVValidator
: public SCEVVisitor<SCEVValidator, class ValidatorResult> {
@@ -306,6 +317,17 @@ public:
return ValidatorResult(SCEVType::PARAM, S);
}
+ ValidatorResult visitCallInstruction(Instruction *I, const SCEV *S) {
+ assert(I->getOpcode() == Instruction::Call && "Call instruction expected");
+
+ auto Call = cast<CallInst>(I);
+
+ if (!isConstCall(Call))
+ return ValidatorResult(SCEVType::INVALID, S);
+
+ return ValidatorResult(SCEVType::PARAM, S);
+ }
+
ValidatorResult visitLoadInstruction(Instruction *I, const SCEV *S) {
if (R->contains(I) && ILS) {
ILS->insert(cast<LoadInst>(I));
@@ -396,6 +418,8 @@ public:
return visitSDivInstruction(I, Expr);
case Instruction::SRem:
return visitSRemInstruction(I, Expr);
+ case Instruction::Call:
+ return visitCallInstruction(I, Expr);
default:
return visitGenericInst(I, Expr);
}
@@ -420,6 +444,11 @@ public:
if (auto Unknown = dyn_cast<SCEVUnknown>(S)) {
Instruction *Inst = dyn_cast<Instruction>(Unknown->getValue());
+ CallInst *Call = dyn_cast<CallInst>(Unknown->getValue());
+
+ if (Call && isConstCall(Call))
+ return false;
+
// Return true when Inst is defined inside the region R.
if (!Inst || !R->contains(Inst))
return true;
OpenPOWER on IntegriCloud