diff options
author | Chris Lattner <sabre@nondot.org> | 2009-11-26 16:18:10 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2009-11-26 16:18:10 +0000 |
commit | f6ac4d9dadaa62959e04a0281e3bc5f4270fc260 (patch) | |
tree | 0338bfc3cfec9e27f68da330a34fafa7cd86a29a /lib/Analysis/BasicAliasAnalysis.cpp | |
parent | 61d24624005f3cb7973819217e9141febce37c61 (diff) |
teach basicaa that A[i] != A[i+1].
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@89951 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/BasicAliasAnalysis.cpp')
-rw-r--r-- | lib/Analysis/BasicAliasAnalysis.cpp | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/lib/Analysis/BasicAliasAnalysis.cpp b/lib/Analysis/BasicAliasAnalysis.cpp index 15ae344522..fb6b9df608 100644 --- a/lib/Analysis/BasicAliasAnalysis.cpp +++ b/lib/Analysis/BasicAliasAnalysis.cpp @@ -378,6 +378,30 @@ BasicAliasAnalysis::getModRefInfo(CallSite CS1, CallSite CS2) { return NoAA::getModRefInfo(CS1, CS2); } +/// GetLinearExpression - Analyze the specified value as a linear expression: +/// "A*V + B". Return the scale and offset values as APInts and return V as a +/// Value*. The incoming Value is known to be a scalar integer. +static Value *GetLinearExpression(Value *V, APInt &Scale, APInt &Offset) { + assert(isa<IntegerType>(V->getType()) && "Not an integer value"); + + if (BinaryOperator *BOp = dyn_cast<BinaryOperator>(V)) { + if (ConstantInt *RHSC = dyn_cast<ConstantInt>(BOp->getOperand(1))) { + switch (BOp->getOpcode()) { + default: break; + case Instruction::Add: + V = GetLinearExpression(BOp->getOperand(0), Scale, Offset); + Offset += RHSC->getValue(); + return V; + // TODO: SHL, MUL, OR. + } + } + } + + Scale = 1; + Offset = 0; + return V; +} + /// DecomposeGEPExpression - If V is a symbolic pointer expression, decompose it /// into a base pointer with a constant offset and a number of scaled symbolic /// offsets. @@ -456,6 +480,14 @@ static const Value *DecomposeGEPExpression(const Value *V, int64_t &BaseOffs, // TODO: Could handle linear expressions here like A[X+1], also A[X*4|1]. uint64_t Scale = TD->getTypeAllocSize(*GTI); + unsigned Width = cast<IntegerType>(Index->getType())->getBitWidth(); + APInt IndexScale(Width, 0), IndexOffset(Width, 0); + Index = GetLinearExpression(Index, IndexScale, IndexOffset); + + Scale *= IndexScale.getZExtValue(); + BaseOffs += IndexOffset.getZExtValue()*Scale; + + // If we already had an occurrance of this index variable, merge this // scale into it. For example, we want to handle: // A[x][x] -> x*16 + x*4 -> x*20 |