[PATCH] D74691: [Attributor] Detect possibly unbounded cycles in functions
omar ahmed via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Wed Feb 26 03:01:01 PST 2020
omarahmed added a comment.
In D74691#1892769 <https://reviews.llvm.org/D74691#1892769>, @jdoerfert wrote:
> In D74691#1892447 <https://reviews.llvm.org/D74691#1892447>, @omarahmed wrote:
>
> > I am sorry but I can't get what the test that the approach of moving on the SCCs fails in as I have tried to test it a bit with tests like that and printed the SCCs that it gets
> >
> > https://i.imgur.com/fpZhpST.png
> > 1 - entry
> > 2- condition - body
> > 3- return
> > 4 - l4
> >
> > https://i.imgur.com/UJJ3aH0.png
> > 1- entry
> > 2- l1 - l2 - l3 - l4 - l5
> > 3- return
> > 4- l6 - l7 - l8
> >
> > https://i.imgur.com/92NS6rp.png
> > 1- entry
> > 2- l1 - l2 - l3 - l4 - l5 - l6 - l7
> > 3- return
> >
> > and in all of them it reached the cycle and outputs that the loop does not have a max trip count
>
>
> Can u share the IR (with the appropriate RUN lines, thus tests) not the images please?
okay , sorry for this anonymous comment
the first IR :
define i32* @test1(i32* %n0, i32* %r0, i32* %w0) {
entry:
%tmp = add i32 0, 0
br label %condition
condition:
%tobool2 = icmp ne i32* %n0, null
br i1 %tobool2, label %body, label %return
body:
%tobool3 = icmp ne i32* %n0, null
br i1 %tobool3, label %l4, label %condition
l4:
br label %l4
return:
ret i32* %w0
}
the second IR :
define i32* @test2(i32* %n0, i32* %r0, i32* %w0) {
entry:
br label %l1
l1:
br label %l2
l2:
br label %l3
l3:
%tobool = icmp ne i32* %n0, null
br i1 %tobool, label %return, label %l4
l4:
%tobool2 = icmp ne i32* %n0, null
br i1 %tobool2, label %l6, label %l5
l5:
br label %l1
l6:
br label %l7
l7:
br label %l8
l8:
br label %l6
return:
ret i32* %w0
}
the third IR :
define i32* @test3(i32* %n0, i32* %r0, i32* %w0) {
entry:
br label %l1
l1:
br label %l2
l2:
br label %l3
l3:
%tobool = icmp ne i32* %n0, null
br i1 %tobool, label %return, label %l4
l4:
%tobool2 = icmp ne i32* %n0, null
br i1 %tobool2, label %l6, label %l5
l5:
br label %l1
l6:
br label %l7
l7:
br label %l4
return:
ret i32* %w0
}
the run command :
./bin/opt -passes=attributor --attributor-disable=false /home/omar/mytest.ll -S
the code I tested it on :
static bool containsUnboundedCycle(Function &F, Attributor &A) {
bool NoAnalysis = false;
ScalarEvolution *SE =
A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(F);
LoopInfo *LI = A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(F);
if (!LI || !SE){
NoAnalysis = true;
dbgs() << "no analysis in function\n";
}
for (scc_iterator<Function *> It = scc_begin(&F), IE = scc_end(&F); It != IE;
++It) {
dbgs()<<"SCC start\n\n\n";
for(auto SCCBB : *It){
dbgs()<< *SCCBB <<"\n";
}
bool SCCHasLoop = It.hasLoop();
if (!SCCHasLoop){
dbgs()<<"SCC does not have loop\n";
continue;
}
// When NoAnalysis available then check only if the SCC has loop or not.
if (NoAnalysis && SCCHasLoop){
dbgs() << "no analysis and does have loop\n";
return true;
}
const std::vector<BasicBlock *> &SCCBBs = *It;
// If any random block in this SCC does not belong to a loop, then this SCC
// is definitely not a loop.
Loop *L = LI->getLoopFor(SCCBBs.front());
if (!L){
dbgs() << "loop is null so current SCC does not have loop\n";
return true;
}
// L is the innermost loop that has a common block with the SCC. Since a
// loop is always an SCC, if their number of blocks are equal, the SCC is a
// loop so we check if it is bounded or Unbounded loop by checking the
// maxTripCount. Otherwise, there are 2 cases:
// - If the SCC has less blocks, then it is definitely not a loop.
// - If it has more, then we can't decide since the SCC can be a parent loop
// of L. So, we perform the same test for the parent of L.
do {
if (L->getNumBlocks() > SCCBBs.size()){
dbgs() << "SCC is less so not loop\n";
return true;
}
if (L->getNumBlocks() == SCCBBs.size())
if (!SE->getSmallConstantMaxTripCount(L)){
dbgs() << "there is no max trip count for the current SCC\n";
return true;
}
dbgs() << "loop with max trip count\n";
break;
} while ((L = L->getParentLoop()));
// Check if L is null, we found no loop that matches exactly the number of
// blocks of the SCC and so the SCC is not a loop.
if (!L)
return true;
}
return false;
}
and in the three tests it gets me "there is no max trip count for the current SCC\n" and return true
so I what I was asking is that I can't figure out what test fails in this code ?
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D74691/new/
https://reviews.llvm.org/D74691
More information about the llvm-commits
mailing list