[llvm-dev] Finding Reduction Variables in a Loop

Malhar Thakkar via llvm-dev llvm-dev at lists.llvm.org
Thu Jun 21 14:27:59 PDT 2018


Hello everyone,

I'm trying to find reduction variables in a loop and I have a couple of
questions about it.

Is it necessary that a reduction variable should be associated with a Phi
node?

For my purpose, I tried using isReductionPHI() from LoopUtils.cpp (that is
used by LoopVectorizer) for a toy C program (find below) that has a clear
reduction variable but it still returns false.

// Toy program where "sum" is the reduction variable.

#include <stdio.h>int main(int argc, char const *argv[])
{
	int sum = 0, a[100], i;

	for(i = 0; i < 100; i++)
		sum += a[i];

	printf("sum: %d\n", sum);
	return 0;
}

I generated LLVM IR (toy_reduction.ll) for the above program and then
applied mem2reg on top of it (toy_reduction_mem2reg.ll). I have implemented
a toy analysis pass which prints the phi nodes that are associated with
reduction variables which is as under.

void checkRedux(Loop *L) {
	for (BasicBlock *BB : L->getBlocks()) {
		for (Instruction &I : *BB) {
			if (auto *Phi = dyn_cast<PHINode>(&I)) {
				errs() << *Phi << "\n";
				RecurrenceDescriptor RedDes;
		        if (RecurrenceDescriptor::isReductionPHI(Phi, L, RedDes)) {
		        	errs() << "Found reduction object\n";
		        	errs() << *Phi << "\n";
		        }
			}
		}
	}
}

bool runOnFunction(Function &F) override {
	auto *LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
	for(Loop *L : *LI){
			checkRedux(L);
	}
	return false;
}


However, for the input file toy_reduction_mem2reg.ll, isReductionPHI()
returns false every time the control reaches there thereby declaring that
there are no reduction variables when clearly there is one (sum).

Find below a snippet of the LLVM IR after applying mem2reg.

define i32 @main(i32 %argc, i8** %argv) #0 {entry:
  %a = alloca [100 x i32], align 16
  br label %for.cond
for.cond:                                         ; preds = %for.inc, %entry
  %sum.0 = phi i32 [ 0, %entry ], [ %add, %for.inc ]
  %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
  %cmp = icmp slt i32 %i.0, 100
  br i1 %cmp, label %for.body, label %for.end
for.body:                                         ; preds = %for.cond
  %idxprom = sext i32 %i.0 to i64
  %arrayidx = getelementptr inbounds [100 x i32], [100 x i32]* %a, i64
0, i64 %idxprom
  %0 = load i32, i32* %arrayidx, align 4
  %add = add nsw i32 %sum.0, %0
  br label %for.inc
for.inc:                                          ; preds = %for.body
  %inc = add nsw i32 %i.0, 1
  br label %for.cond
for.end:                                          ; preds = %for.cond
  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([9 x
i8], [9 x i8]* @.str, i32 0, i32 0), i32 %sum.0)
  ret i32 0
}
declare i32 @printf(i8*, ...) #

Do I need to run some passes other than mem2reg to obtain the desired
result?

Is there a better way of finding reduction variables in LLVM?


Thank you.



Regards,
Malhar


ᐧ
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20180621/b97f11f4/attachment-0001.html>


More information about the llvm-dev mailing list