[polly] r330466 - Allow arbitrary function calls for debugging purposes.
Michael Kruse via llvm-commits
llvm-commits at lists.llvm.org
Fri Apr 20 11:55:44 PDT 2018
Author: meinersbur
Date: Fri Apr 20 11:55:44 2018
New Revision: 330466
URL: http://llvm.org/viewvc/llvm-project?rev=330466&view=rev
Log:
Allow arbitrary function calls for debugging purposes.
Add the switch -polly-debug-func to define the name of a debug
function. This function is ignored for any validity check.
Its purpose is to allow to observe a value after transformation by a
SCoP, and to follow which statements are executed in which order. For
instance, consider the following code:
static void dbg_printf(int sum, int i) {
fprintf(stderr, "The value of sum is %d, i=%d\n", sum, i);
fflush(stderr);
}
void func(int n) {
int sum = 0;
for (int i = 0; i < 16; i+=1) {
sum += i;
dbg_printf(sum, i);
}
}
Executing this after Polly's codegen with -polly-debug-func=dbg_printf
reveals the new execution order and the assumed values at that point of
execution.
Differential Revision: https://reviews.llvm.org/D45728
Added:
polly/trunk/test/ScopInfo/debug_call.ll
Modified:
polly/trunk/include/polly/Support/ScopHelper.h
polly/trunk/lib/Analysis/ScopBuilder.cpp
polly/trunk/lib/Analysis/ScopDetection.cpp
polly/trunk/lib/Analysis/ScopInfo.cpp
polly/trunk/lib/Support/ScopHelper.cpp
Modified: polly/trunk/include/polly/Support/ScopHelper.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/include/polly/Support/ScopHelper.h?rev=330466&r1=330465&r2=330466&view=diff
==============================================================================
--- polly/trunk/include/polly/Support/ScopHelper.h (original)
+++ polly/trunk/include/polly/Support/ScopHelper.h Fri Apr 20 11:55:44 2018
@@ -36,6 +36,7 @@ class GetElementPtrInst;
namespace polly {
class Scop;
+class ScopStmt;
/// Type to remap values.
using ValueMapT = llvm::DenseMap<llvm::AssertingVH<llvm::Value>,
@@ -458,5 +459,24 @@ llvm::Loop *getFirstNonBoxedLoopFor(llvm
// @param BoxedLoops Set of Boxed Loops we get from the SCoP.
llvm::Loop *getFirstNonBoxedLoopFor(llvm::BasicBlock *BB, llvm::LoopInfo &LI,
const BoxedLoopsSetTy &BoxedLoops);
+
+/// Is the given instruction a call to a debug function?
+///
+/// A debug function can be used to insert output in Polly-optimized code which
+/// normally does not allow function calls with side-effects. For instance, a
+/// printf can be inserted to check whether a value still has the expected value
+/// after Polly generated code:
+///
+/// int sum = 0;
+/// for (int i = 0; i < 16; i+=1) {
+/// sum += i;
+/// printf("The value of sum at i=%d is %d\n", sum, i);
+/// }
+bool isDebugCall(llvm::Instruction *Inst);
+
+/// Does the statement contain a call to a debug function?
+///
+/// Such a statement must not be removed, even if has no side-effects.
+bool hasDebugCall(ScopStmt *Stmt);
} // namespace polly
#endif
Modified: polly/trunk/lib/Analysis/ScopBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Analysis/ScopBuilder.cpp?rev=330466&r1=330465&r2=330466&view=diff
==============================================================================
--- polly/trunk/lib/Analysis/ScopBuilder.cpp (original)
+++ polly/trunk/lib/Analysis/ScopBuilder.cpp Fri Apr 20 11:55:44 2018
@@ -559,7 +559,7 @@ bool ScopBuilder::buildAccessCallInst(Me
if (CI == nullptr)
return false;
- if (CI->doesNotAccessMemory() || isIgnoredIntrinsic(CI))
+ if (CI->doesNotAccessMemory() || isIgnoredIntrinsic(CI) || isDebugCall(CI))
return true;
bool ReadOnly = false;
Modified: polly/trunk/lib/Analysis/ScopDetection.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Analysis/ScopDetection.cpp?rev=330466&r1=330465&r2=330466&view=diff
==============================================================================
--- polly/trunk/lib/Analysis/ScopDetection.cpp (original)
+++ polly/trunk/lib/Analysis/ScopDetection.cpp Fri Apr 20 11:55:44 2018
@@ -703,6 +703,12 @@ bool ScopDetection::isValidCallInst(Call
if (CalledFunction == nullptr)
return false;
+ if (isDebugCall(&CI)) {
+ DEBUG(dbgs() << "Allow call to debug function: "
+ << CalledFunction->getName() << '\n');
+ return true;
+ }
+
if (AllowModrefCall) {
switch (AA.getModRefBehavior(CalledFunction)) {
case FMRB_UnknownModRefBehavior:
Modified: polly/trunk/lib/Analysis/ScopInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Analysis/ScopInfo.cpp?rev=330466&r1=330465&r2=330466&view=diff
==============================================================================
--- polly/trunk/lib/Analysis/ScopInfo.cpp (original)
+++ polly/trunk/lib/Analysis/ScopInfo.cpp Fri Apr 20 11:55:44 2018
@@ -3585,6 +3585,10 @@ void Scop::removeStmtNotInDomainMap() {
void Scop::simplifySCoP(bool AfterHoisting) {
auto ShouldDelete = [AfterHoisting](ScopStmt &Stmt) -> bool {
+ // Never delete statements that contain calls to debug functions.
+ if (hasDebugCall(&Stmt))
+ return false;
+
bool RemoveStmt = Stmt.isEmpty();
// Remove read only statements only after invariant load hoisting.
Modified: polly/trunk/lib/Support/ScopHelper.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Support/ScopHelper.cpp?rev=330466&r1=330465&r2=330466&view=diff
==============================================================================
--- polly/trunk/lib/Support/ScopHelper.cpp (original)
+++ polly/trunk/lib/Support/ScopHelper.cpp Fri Apr 20 11:55:44 2018
@@ -35,6 +35,13 @@ static cl::opt<bool> PollyAllowErrorBloc
cl::desc("Allow to speculate on the execution of 'error blocks'."),
cl::Hidden, cl::init(true), cl::ZeroOrMore, cl::cat(PollyCategory));
+static cl::list<std::string> DebugFunctions(
+ "polly-debug-func",
+ cl::desc("Allow calls to the specified functions in SCoPs even if their "
+ "side-effects are unknown. This can be used to do debug output in "
+ "Polly-transformed code."),
+ cl::Hidden, cl::ZeroOrMore, cl::CommaSeparated, cl::cat(PollyCategory));
+
// Ensures that there is just one predecessor to the entry node from outside the
// region.
// The identity of the region entry node is preserved.
@@ -401,6 +408,9 @@ bool polly::isErrorBlock(BasicBlock &BB,
for (Instruction &Inst : BB)
if (CallInst *CI = dyn_cast<CallInst>(&Inst)) {
+ if (isDebugCall(CI))
+ continue;
+
if (isIgnoredIntrinsic(CI))
continue;
@@ -586,3 +596,45 @@ llvm::Loop *polly::getFirstNonBoxedLoopF
Loop *L = LI.getLoopFor(BB);
return getFirstNonBoxedLoopFor(L, LI, BoxedLoops);
}
+
+bool polly::isDebugCall(Instruction *Inst) {
+ auto *CI = dyn_cast<CallInst>(Inst);
+ if (!CI)
+ return false;
+
+ Function *CF = CI->getCalledFunction();
+ if (!CF)
+ return false;
+
+ return std::find(DebugFunctions.begin(), DebugFunctions.end(),
+ CF->getName()) != DebugFunctions.end();
+}
+
+static bool hasDebugCall(BasicBlock *BB) {
+ for (Instruction &Inst : *BB) {
+ if (isDebugCall(&Inst))
+ return true;
+ }
+ return false;
+}
+
+bool polly::hasDebugCall(ScopStmt *Stmt) {
+ // Quick skip if no debug functions have been defined.
+ if (DebugFunctions.empty())
+ return false;
+
+ if (!Stmt)
+ return false;
+
+ for (Instruction *Inst : Stmt->getInstructions())
+ if (isDebugCall(Inst))
+ return true;
+
+ if (Stmt->isRegionStmt()) {
+ for (BasicBlock *RBB : Stmt->getRegion()->blocks())
+ if (RBB != Stmt->getEntryBlock() && ::hasDebugCall(RBB))
+ return true;
+ }
+
+ return false;
+}
Added: polly/trunk/test/ScopInfo/debug_call.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/ScopInfo/debug_call.ll?rev=330466&view=auto
==============================================================================
--- polly/trunk/test/ScopInfo/debug_call.ll (added)
+++ polly/trunk/test/ScopInfo/debug_call.ll Fri Apr 20 11:55:44 2018
@@ -0,0 +1,37 @@
+; RUN: opt %loadPolly -polly-debug-func=dbg_printf -polly-scops -analyze < %s | FileCheck %s -match-full-lines
+;
+; Check that the call to dbg_printf is accepted as a debug-function.
+;
+declare void @dbg_printf(i8*, ...)
+
+define void @func(i32 %n) {
+entry:
+ br label %for
+
+for:
+ %j = phi i32 [0, %entry], [%j.inc, %inc]
+ %j.cmp = icmp slt i32 %j, %n
+ br i1 %j.cmp, label %body, label %exit
+
+ body:
+ call void (i8*, ...) @dbg_printf(i8* null, i32 %j)
+ br label %inc
+
+inc:
+ %j.inc = add nuw nsw i32 %j, 1
+ br label %for
+
+exit:
+ br label %return
+
+return:
+ ret void
+}
+
+; CHECK: Statements {
+; CHECK-NEXT: Stmt_body
+; CHECK-NEXT: Domain :=
+; CHECK-NEXT: [n] -> { Stmt_body[i0] : 0 <= i0 < n };
+; CHECK-NEXT: Schedule :=
+; CHECK-NEXT: [n] -> { Stmt_body[i0] -> [i0] };
+; CHECK-NEXT: }
More information about the llvm-commits
mailing list