mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 11:13:28 +01:00
[BasicAA] Avoid calling GetUnderlyingObject, when the result of a previous call can be reused.
Recursive calls to aliasCheck from alias[GEP|Select|PHI] may result in a second call to GetUnderlyingObject for a Value, whose underlying object is already computed. This patch ensures that in this situations, the underlying object is not computed again, and the result of the previous call is resued. https://reviews.llvm.org/D22305 llvm-svn: 278519
This commit is contained in:
parent
595cd6dff6
commit
03643a9b1f
@ -180,14 +180,17 @@ private:
|
||||
|
||||
AliasResult aliasPHI(const PHINode *PN, uint64_t PNSize,
|
||||
const AAMDNodes &PNAAInfo, const Value *V2,
|
||||
uint64_t V2Size, const AAMDNodes &V2AAInfo);
|
||||
uint64_t V2Size, const AAMDNodes &V2AAInfo,
|
||||
const Value *UnderV2);
|
||||
|
||||
AliasResult aliasSelect(const SelectInst *SI, uint64_t SISize,
|
||||
const AAMDNodes &SIAAInfo, const Value *V2,
|
||||
uint64_t V2Size, const AAMDNodes &V2AAInfo);
|
||||
uint64_t V2Size, const AAMDNodes &V2AAInfo,
|
||||
const Value *UnderV2);
|
||||
|
||||
AliasResult aliasCheck(const Value *V1, uint64_t V1Size, AAMDNodes V1AATag,
|
||||
const Value *V2, uint64_t V2Size, AAMDNodes V2AATag);
|
||||
const Value *V2, uint64_t V2Size, AAMDNodes V2AATag,
|
||||
const Value *O1 = nullptr, const Value *O2 = nullptr);
|
||||
};
|
||||
|
||||
/// Analysis pass providing a never-invalidated alias analysis result.
|
||||
|
@ -1140,7 +1140,8 @@ AliasResult BasicAAResult::aliasGEP(const GEPOperator *GEP1, uint64_t V1Size,
|
||||
return MayAlias;
|
||||
|
||||
AliasResult R = aliasCheck(UnderlyingV1, MemoryLocation::UnknownSize,
|
||||
AAMDNodes(), V2, V2Size, V2AAInfo);
|
||||
AAMDNodes(), V2, V2Size, V2AAInfo,
|
||||
nullptr, UnderlyingV2);
|
||||
if (R != MustAlias)
|
||||
// If V2 may alias GEP base pointer, conservatively returns MayAlias.
|
||||
// If V2 is known not to alias GEP base pointer, then the two values
|
||||
@ -1277,7 +1278,8 @@ static AliasResult MergeAliasResults(AliasResult A, AliasResult B) {
|
||||
AliasResult BasicAAResult::aliasSelect(const SelectInst *SI, uint64_t SISize,
|
||||
const AAMDNodes &SIAAInfo,
|
||||
const Value *V2, uint64_t V2Size,
|
||||
const AAMDNodes &V2AAInfo) {
|
||||
const AAMDNodes &V2AAInfo,
|
||||
const Value *UnderV2) {
|
||||
// If the values are Selects with the same condition, we can do a more precise
|
||||
// check: just check for aliases between the values on corresponding arms.
|
||||
if (const SelectInst *SI2 = dyn_cast<SelectInst>(V2))
|
||||
@ -1295,12 +1297,14 @@ AliasResult BasicAAResult::aliasSelect(const SelectInst *SI, uint64_t SISize,
|
||||
// If both arms of the Select node NoAlias or MustAlias V2, then returns
|
||||
// NoAlias / MustAlias. Otherwise, returns MayAlias.
|
||||
AliasResult Alias =
|
||||
aliasCheck(V2, V2Size, V2AAInfo, SI->getTrueValue(), SISize, SIAAInfo);
|
||||
aliasCheck(V2, V2Size, V2AAInfo, SI->getTrueValue(),
|
||||
SISize, SIAAInfo, UnderV2);
|
||||
if (Alias == MayAlias)
|
||||
return MayAlias;
|
||||
|
||||
AliasResult ThisAlias =
|
||||
aliasCheck(V2, V2Size, V2AAInfo, SI->getFalseValue(), SISize, SIAAInfo);
|
||||
aliasCheck(V2, V2Size, V2AAInfo, SI->getFalseValue(), SISize, SIAAInfo,
|
||||
UnderV2);
|
||||
return MergeAliasResults(ThisAlias, Alias);
|
||||
}
|
||||
|
||||
@ -1308,8 +1312,8 @@ AliasResult BasicAAResult::aliasSelect(const SelectInst *SI, uint64_t SISize,
|
||||
/// another.
|
||||
AliasResult BasicAAResult::aliasPHI(const PHINode *PN, uint64_t PNSize,
|
||||
const AAMDNodes &PNAAInfo, const Value *V2,
|
||||
uint64_t V2Size,
|
||||
const AAMDNodes &V2AAInfo) {
|
||||
uint64_t V2Size, const AAMDNodes &V2AAInfo,
|
||||
const Value *UnderV2) {
|
||||
// Track phi nodes we have visited. We use this information when we determine
|
||||
// value equivalence.
|
||||
VisitedPhiBBs.insert(PN->getParent());
|
||||
@ -1388,7 +1392,8 @@ AliasResult BasicAAResult::aliasPHI(const PHINode *PN, uint64_t PNSize,
|
||||
PNSize = MemoryLocation::UnknownSize;
|
||||
|
||||
AliasResult Alias =
|
||||
aliasCheck(V2, V2Size, V2AAInfo, V1Srcs[0], PNSize, PNAAInfo);
|
||||
aliasCheck(V2, V2Size, V2AAInfo, V1Srcs[0],
|
||||
PNSize, PNAAInfo, UnderV2);
|
||||
|
||||
// Early exit if the check of the first PHI source against V2 is MayAlias.
|
||||
// Other results are not possible.
|
||||
@ -1401,7 +1406,7 @@ AliasResult BasicAAResult::aliasPHI(const PHINode *PN, uint64_t PNSize,
|
||||
Value *V = V1Srcs[i];
|
||||
|
||||
AliasResult ThisAlias =
|
||||
aliasCheck(V2, V2Size, V2AAInfo, V, PNSize, PNAAInfo);
|
||||
aliasCheck(V2, V2Size, V2AAInfo, V, PNSize, PNAAInfo, UnderV2);
|
||||
Alias = MergeAliasResults(ThisAlias, Alias);
|
||||
if (Alias == MayAlias)
|
||||
break;
|
||||
@ -1414,7 +1419,8 @@ AliasResult BasicAAResult::aliasPHI(const PHINode *PN, uint64_t PNSize,
|
||||
/// array references.
|
||||
AliasResult BasicAAResult::aliasCheck(const Value *V1, uint64_t V1Size,
|
||||
AAMDNodes V1AAInfo, const Value *V2,
|
||||
uint64_t V2Size, AAMDNodes V2AAInfo) {
|
||||
uint64_t V2Size, AAMDNodes V2AAInfo,
|
||||
const Value *O1, const Value *O2) {
|
||||
// If either of the memory references is empty, it doesn't matter what the
|
||||
// pointer values are.
|
||||
if (V1Size == 0 || V2Size == 0)
|
||||
@ -1442,8 +1448,11 @@ AliasResult BasicAAResult::aliasCheck(const Value *V1, uint64_t V1Size,
|
||||
return NoAlias; // Scalars cannot alias each other
|
||||
|
||||
// Figure out what objects these things are pointing to if we can.
|
||||
const Value *O1 = GetUnderlyingObject(V1, DL, MaxLookupSearchDepth);
|
||||
const Value *O2 = GetUnderlyingObject(V2, DL, MaxLookupSearchDepth);
|
||||
if (O1 == nullptr)
|
||||
O1 = GetUnderlyingObject(V1, DL, MaxLookupSearchDepth);
|
||||
|
||||
if (O2 == nullptr)
|
||||
O2 = GetUnderlyingObject(V2, DL, MaxLookupSearchDepth);
|
||||
|
||||
// Null values in the default address space don't point to any object, so they
|
||||
// don't alias any other pointer.
|
||||
@ -1526,23 +1535,26 @@ AliasResult BasicAAResult::aliasCheck(const Value *V1, uint64_t V1Size,
|
||||
|
||||
if (isa<PHINode>(V2) && !isa<PHINode>(V1)) {
|
||||
std::swap(V1, V2);
|
||||
std::swap(O1, O2);
|
||||
std::swap(V1Size, V2Size);
|
||||
std::swap(V1AAInfo, V2AAInfo);
|
||||
}
|
||||
if (const PHINode *PN = dyn_cast<PHINode>(V1)) {
|
||||
AliasResult Result = aliasPHI(PN, V1Size, V1AAInfo, V2, V2Size, V2AAInfo);
|
||||
AliasResult Result = aliasPHI(PN, V1Size, V1AAInfo,
|
||||
V2, V2Size, V2AAInfo, O2);
|
||||
if (Result != MayAlias)
|
||||
return AliasCache[Locs] = Result;
|
||||
}
|
||||
|
||||
if (isa<SelectInst>(V2) && !isa<SelectInst>(V1)) {
|
||||
std::swap(V1, V2);
|
||||
std::swap(O1, O2);
|
||||
std::swap(V1Size, V2Size);
|
||||
std::swap(V1AAInfo, V2AAInfo);
|
||||
}
|
||||
if (const SelectInst *S1 = dyn_cast<SelectInst>(V1)) {
|
||||
AliasResult Result =
|
||||
aliasSelect(S1, V1Size, V1AAInfo, V2, V2Size, V2AAInfo);
|
||||
aliasSelect(S1, V1Size, V1AAInfo, V2, V2Size, V2AAInfo, O2);
|
||||
if (Result != MayAlias)
|
||||
return AliasCache[Locs] = Result;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user