mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-01 05:01:59 +01:00
Allow basicaa to walk through geps with identical indices in
parallel, allowing it to decide that P/Q must alias if A/B must alias in things like: P = gep A, 0, i, 1 Q = gep B, 0, i, 1 This allows GVN to delete 62 more instructions out of 403.gcc. llvm-svn: 60820
This commit is contained in:
parent
a3b718a3c9
commit
e2b5854e41
@ -85,7 +85,7 @@ static const User *isGEP(const Value *V) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const Value *GetGEPOperands(const Value *V,
|
static const Value *GetGEPOperands(const Value *V,
|
||||||
SmallVector<Value*, 16> &GEPOps){
|
SmallVector<Value*, 16> &GEPOps) {
|
||||||
assert(GEPOps.empty() && "Expect empty list to populate!");
|
assert(GEPOps.empty() && "Expect empty list to populate!");
|
||||||
GEPOps.insert(GEPOps.end(), cast<User>(V)->op_begin()+1,
|
GEPOps.insert(GEPOps.end(), cast<User>(V)->op_begin()+1,
|
||||||
cast<User>(V)->op_end());
|
cast<User>(V)->op_end());
|
||||||
@ -369,8 +369,7 @@ BasicAliasAnalysis::getModRefInfo(CallSite CS1, CallSite CS2) {
|
|||||||
|
|
||||||
|
|
||||||
// alias - Provide a bunch of ad-hoc rules to disambiguate in common cases, such
|
// alias - Provide a bunch of ad-hoc rules to disambiguate in common cases, such
|
||||||
// as array references. Note that this function is heavily tail recursive.
|
// as array references.
|
||||||
// Hopefully we have a smart C++ compiler. :)
|
|
||||||
//
|
//
|
||||||
AliasAnalysis::AliasResult
|
AliasAnalysis::AliasResult
|
||||||
BasicAliasAnalysis::alias(const Value *V1, unsigned V1Size,
|
BasicAliasAnalysis::alias(const Value *V1, unsigned V1Size,
|
||||||
@ -389,13 +388,14 @@ BasicAliasAnalysis::alias(const Value *V1, unsigned V1Size,
|
|||||||
if (!isa<PointerType>(V1->getType()) || !isa<PointerType>(V2->getType()))
|
if (!isa<PointerType>(V1->getType()) || !isa<PointerType>(V2->getType()))
|
||||||
return NoAlias; // Scalars cannot alias each other
|
return NoAlias; // Scalars cannot alias each other
|
||||||
|
|
||||||
// Strip off cast instructions...
|
// Strip off cast instructions. Since V1 and V2 are pointers, they must be
|
||||||
|
// pointer<->pointer bitcasts.
|
||||||
if (const BitCastInst *I = dyn_cast<BitCastInst>(V1))
|
if (const BitCastInst *I = dyn_cast<BitCastInst>(V1))
|
||||||
return alias(I->getOperand(0), V1Size, V2, V2Size);
|
return alias(I->getOperand(0), V1Size, V2, V2Size);
|
||||||
if (const BitCastInst *I = dyn_cast<BitCastInst>(V2))
|
if (const BitCastInst *I = dyn_cast<BitCastInst>(V2))
|
||||||
return alias(V1, V1Size, I->getOperand(0), V2Size);
|
return alias(V1, V1Size, I->getOperand(0), V2Size);
|
||||||
|
|
||||||
// Figure out what objects these things are pointing to if we can...
|
// Figure out what objects these things are pointing to if we can.
|
||||||
const Value *O1 = V1->getUnderlyingObject();
|
const Value *O1 = V1->getUnderlyingObject();
|
||||||
const Value *O2 = V2->getUnderlyingObject();
|
const Value *O2 = V2->getUnderlyingObject();
|
||||||
|
|
||||||
@ -438,21 +438,35 @@ BasicAliasAnalysis::alias(const Value *V1, unsigned V1Size,
|
|||||||
// constant expression getelementptrs here.
|
// constant expression getelementptrs here.
|
||||||
//
|
//
|
||||||
if (isGEP(V1) && isGEP(V2)) {
|
if (isGEP(V1) && isGEP(V2)) {
|
||||||
|
const User *GEP1 = cast<User>(V1);
|
||||||
|
const User *GEP2 = cast<User>(V2);
|
||||||
|
|
||||||
|
// If V1 and V2 are identical GEPs, just recurse down on both of them.
|
||||||
|
// This allows us to analyze things like:
|
||||||
|
// P = gep A, 0, i, 1
|
||||||
|
// Q = gep B, 0, i, 1
|
||||||
|
// by just analyzing A and B. This is even safe for variable indices.
|
||||||
|
if (GEP1->getType() == GEP2->getType() &&
|
||||||
|
GEP1->getNumOperands() == GEP2->getNumOperands() &&
|
||||||
|
GEP1->getOperand(0)->getType() == GEP2->getOperand(0)->getType() &&
|
||||||
|
// All operands are the same, ignoring the base.
|
||||||
|
std::equal(GEP1->op_begin()+1, GEP1->op_end(), GEP2->op_begin()+1))
|
||||||
|
return alias(GEP1->getOperand(0), V1Size, GEP2->getOperand(0), V2Size);
|
||||||
|
|
||||||
|
|
||||||
// Drill down into the first non-gep value, to test for must-aliasing of
|
// Drill down into the first non-gep value, to test for must-aliasing of
|
||||||
// the base pointers.
|
// the base pointers.
|
||||||
const User *G = cast<User>(V1);
|
while (isGEP(GEP1->getOperand(0)) &&
|
||||||
while (isGEP(G->getOperand(0)) &&
|
GEP1->getOperand(1) ==
|
||||||
G->getOperand(1) ==
|
Constant::getNullValue(GEP1->getOperand(1)->getType()))
|
||||||
Constant::getNullValue(G->getOperand(1)->getType()))
|
GEP1 = cast<User>(GEP1->getOperand(0));
|
||||||
G = cast<User>(G->getOperand(0));
|
const Value *BasePtr1 = GEP1->getOperand(0);
|
||||||
const Value *BasePtr1 = G->getOperand(0);
|
|
||||||
|
|
||||||
G = cast<User>(V2);
|
while (isGEP(GEP2->getOperand(0)) &&
|
||||||
while (isGEP(G->getOperand(0)) &&
|
GEP2->getOperand(1) ==
|
||||||
G->getOperand(1) ==
|
Constant::getNullValue(GEP2->getOperand(1)->getType()))
|
||||||
Constant::getNullValue(G->getOperand(1)->getType()))
|
GEP2 = cast<User>(GEP2->getOperand(0));
|
||||||
G = cast<User>(G->getOperand(0));
|
const Value *BasePtr2 = GEP2->getOperand(0);
|
||||||
const Value *BasePtr2 = G->getOperand(0);
|
|
||||||
|
|
||||||
// Do the base pointers alias?
|
// Do the base pointers alias?
|
||||||
AliasResult BaseAlias = alias(BasePtr1, ~0U, BasePtr2, ~0U);
|
AliasResult BaseAlias = alias(BasePtr1, ~0U, BasePtr2, ~0U);
|
||||||
|
16
test/Analysis/BasicAA/2008-12-09-GEP-IndicesAlias.ll
Normal file
16
test/Analysis/BasicAA/2008-12-09-GEP-IndicesAlias.ll
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
; RUN: llvm-as < %s | opt -aa-eval -print-all-alias-modref-info -disable-output |& grep {MustAlias:.*%R,.*%r}
|
||||||
|
; Make sure that basicaa thinks R and r are must aliases.
|
||||||
|
|
||||||
|
define i32 @test(i8 * %P) {
|
||||||
|
entry:
|
||||||
|
%Q = bitcast i8* %P to {i32, i32}*
|
||||||
|
%R = getelementptr {i32, i32}* %Q, i32 0, i32 1
|
||||||
|
%S = load i32* %R
|
||||||
|
|
||||||
|
%q = bitcast i8* %P to {i32, i32}*
|
||||||
|
%r = getelementptr {i32, i32}* %q, i32 0, i32 1
|
||||||
|
%s = load i32* %r
|
||||||
|
|
||||||
|
%t = sub i32 %S, %s
|
||||||
|
ret i32 %t
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user