[LLVMdev] help with pointer-to-array conversion
Chris Lattner
sabre at nondot.org
Thu Jul 28 14:39:13 PDT 2005
On Thu, 28 Jul 2005, Naftali Schwartz wrote:
> I now understand that IndVarSimplify.cpp is capable of reproducing array
> references when the pointer initialization from the array address is found
> inside the immediately enclosing loop, such that in the following code:
Ok.
> int A[20000], B[100], Z;
> int main()
> {
> int i, j, *a, *b;
> for ( a = &A[0], i = 0; i != 200; i++ )
> for ( b = &B[0], j = 0; j != 100; j++ )
> Z += *a++ * *b++;
> }
>
> the pointer b can be transformed into an offset from B[], but a cannot be
> transformed into an offset from A[] because the initialization is two levels
> up.
Hrm, that should work.
> I started poking around in IndVarSimplify.cpp and I have a patch which should
> (at least partially) enable the transformation for a as well, but I find that
> although the code looks OK in debug printouts, the gccas output is unchanged.
Ok
> So two questions: 1) Am I on the right track with this transformation (patch
> enclosed) and
I haven't taken a look at the code. Could you please give a very simple
example showing what it is supposed to change that is currently not
handled? Also, can you make sure to wrap the lines to fit in 80-columns?
Finally, please send diffs as "unified" diffs, this makes it easier to
read. You can get unified diffs by passing "-u" to cvs diff or normal
diff.
> 2) why does the output not reflect my changes?
There are a couple of different possibilities. I'm not sure exactly what
you're trying to accomplish here, but one of the following may happen:
1. Something in the compiler is running after indvars that undoes what you
are trying to do.
2. The input to indvars in not what you think it is, so running the pass
in the middle of gccas is not giving you the same output as running it
logically at the end of gccas with the opt program.
To isolate #2, it might be useful to get the full set of passes that gccas
is doing. gccas will dump the passes if you run it like this:
gccas /dev/null -o /dev/null -debug-pass=Arguments
That way you can use the passes with 'opt' to see exactly what code is
given to indvars.
-Chris
> Index: lib/Transforms/Scalar/IndVarSimplify.cpp
> ===================================================================
> RCS file: /var/cvs/llvm/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp,v
> retrieving revision 1.78
> diff -r1.78 IndVarSimplify.cpp
> 310c310
> < runOnLoop(*I);
> ---
>> runOnLoop(LI, *I);
> 322,323c322,323
> < void runOnLoop(Loop *L);
> < void EliminatePointerRecurrence(PHINode *PN, BasicBlock *Preheader,
> ---
>> void runOnLoop(LoopInfo *LI, Loop *L);
>> void EliminatePointerRecurrence(LoopInfo *LI, Loop *L, PHINode *PN,
> BasicBlock *Preheader,
> 361c361
> < void IndVarSimplify::EliminatePointerRecurrence(PHINode *PN,
> ---
>> void IndVarSimplify::EliminatePointerRecurrence(LoopInfo *LI, Loop *L,
> PHINode *PN,
> 366a367
>> Value *saved_trip_count = L->getTripCount(); // save before it's
> clobbered
> 392c393,408
> <
> ---
>> std::cerr << "\tGEPI: " << *GEPI;
>> if (PHINode *phi = dyn_cast<PHINode>(GEPI->getOperand(0)))
>> {
>> if (ConstantExpr *CE =
> dyn_cast<ConstantExpr>(phi->getIncomingValue(0)))
>> if (CE->getOpcode() == Instruction::GetElementPtr) // We
> want this to become explicit...
>> {
>> std::cerr << "Block Before: " << *GEPI->getParent();
>> Instruction *mul =
> BinaryOperator::createMul(saved_trip_count,
>> LI->getLoopFor( phi->getIncomingBlock(1) )
>> ->getCanonicalInductionVariable(), "mul.",
> GEPI);
>> Instruction *add = BinaryOperator::createAdd(mul,
> NewAdd, "add.", GEPI);
>> GEPI->setOperand( 0, phi->getIncomingValue(0) );
>> GEPI->setOperand( 1, add );
>> std::cerr << "Block After: " << *GEPI->getParent();
>> }
>> }
> 605c621,622
> < void IndVarSimplify::runOnLoop(Loop *L) {
> ---
>> void IndVarSimplify::runOnLoop(LoopInfo *LI, Loop *L) {
>>
> 617c634
> < EliminatePointerRecurrence(PN, Preheader, DeadInsts);
> ---
>> EliminatePointerRecurrence(LI, L, PN, Preheader, DeadInsts);
> 626c643
> < runOnLoop(*I);
> ---
>> runOnLoop(LI,*I);
> 652,653c669,670
> < if (SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(SCEV))
> < if (AR->getNumOperands() == 2 &&
> isa<SCEVConstant>(AR->getOperand(1)))
> ---
>> if (1)//SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(SCEV))
>> if (1)//AR->getNumOperands() == 2 &&
> isa<SCEVConstant>(AR->getOperand(1)))
>
> Naftali
>
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>
-Chris
--
http://nondot.org/sabre/
http://llvm.org/
More information about the llvm-dev
mailing list