// Attempt to get the instance for S, whose static type is the same as // its exact dynamic type, returning a null SILValue() if we cannot find it. // The information that a static type is the same as the exact dynamic, // can be derived e.g.: // - from a constructor or // - from a successful outcome of a checked_cast_br [exact] instruction. static SILValue getInstanceWithExactDynamicType(SILValue S) { while (S) { S = S.stripCasts(); if (isa<AllocRefInst>(S) || isa<MetatypeInst>(S)) return S; auto *Arg = dyn_cast<SILArgument>(S); if (!Arg) break; auto *SinglePred = Arg->getParent()->getSinglePredecessor(); if (!SinglePred) break; // Traverse the chain of predecessors. if (isa<BranchInst>(SinglePred->getTerminator()) || isa<CondBranchInst>(SinglePred->getTerminator())) { S = Arg->getIncomingValue(SinglePred); continue; } // If it is a BB argument received on a success branch // of a checked_cast_br, then we know its exact type. auto *CCBI = dyn_cast<CheckedCastBranchInst>(SinglePred->getTerminator()); if (!CCBI) break; if (!CCBI->isExact() || CCBI->getSuccessBB() != Arg->getParent()) break; return S; } return SILValue(); }
/// Strip off casts/indexing insts/address projections from V until there is /// nothing left to strip. /// FIXME: Maybe put this on SILValue? /// FIXME: Why don't we strip projections after stripping indexes? SILValue swift::getUnderlyingObject(SILValue V) { while (true) { SILValue V2 = V.stripCasts().stripAddressProjections().stripIndexingInsts(); if (V2 == V) return V2; V = V2; } }
// Attempt to get the instance for S, whose static type is the same as // its exact dynamic type, returning a null SILValue() if we cannot find it. // The information that a static type is the same as the exact dynamic, // can be derived e.g.: // - from a constructor or // - from a successful outcome of a checked_cast_br [exact] instruction. static SILValue getInstanceWithExactDynamicType(SILValue S, SILModule &M, ClassHierarchyAnalysis *CHA) { while (S) { S = S.stripCasts(); if (isa<AllocRefInst>(S) || isa<MetatypeInst>(S)) return S; auto *Arg = dyn_cast<SILArgument>(S); if (!Arg) break; auto *SinglePred = Arg->getParent()->getSinglePredecessor(); if (!SinglePred) { if (!Arg->isFunctionArg()) break; auto *CD = Arg->getType().getClassOrBoundGenericClass(); // Check if this class is effectively final. if (!CD || !isKnownFinalClass(CD, M, CHA)) break; return Arg; } // Traverse the chain of predecessors. if (isa<BranchInst>(SinglePred->getTerminator()) || isa<CondBranchInst>(SinglePred->getTerminator())) { S = Arg->getIncomingValue(SinglePred); continue; } // If it is a BB argument received on a success branch // of a checked_cast_br, then we know its exact type. auto *CCBI = dyn_cast<CheckedCastBranchInst>(SinglePred->getTerminator()); if (!CCBI) break; if (!CCBI->isExact() || CCBI->getSuccessBB() != Arg->getParent()) break; return S; } return SILValue(); }
/// The main AA entry point. Performs various analyses on V1, V2 in an attempt /// to disambiguate the two values. AliasResult AliasAnalysis::aliasInner(SILValue V1, SILValue V2, SILType TBAAType1, SILType TBAAType2) { #ifndef NDEBUG // If alias analysis is disabled, always return may alias. if (!shouldRunAA()) return AliasResult::MayAlias; #endif // If the two values equal, quickly return must alias. if (isSameValueOrGlobal(V1, V2)) return AliasResult::MustAlias; DEBUG(llvm::dbgs() << "ALIAS ANALYSIS:\n V1: " << *V1.getDef() << " V2: " << *V2.getDef()); // Pass in both the TBAA types so we can perform typed access TBAA and the // actual types of V1, V2 so we can perform class based TBAA. if (!typesMayAlias(TBAAType1, TBAAType2)) return AliasResult::NoAlias; #ifndef NDEBUG if (!shouldRunBasicAA()) return AliasResult::MayAlias; #endif // Strip off any casts on V1, V2. V1 = V1.stripCasts(); V2 = V2.stripCasts(); DEBUG(llvm::dbgs() << " After Cast Stripping V1:" << *V1.getDef()); DEBUG(llvm::dbgs() << " After Cast Stripping V2:" << *V2.getDef()); // Ok, we need to actually compute an Alias Analysis result for V1, V2. Begin // by finding the "base" of V1, V2 by stripping off all casts and GEPs. SILValue O1 = getUnderlyingObject(V1); SILValue O2 = getUnderlyingObject(V2); DEBUG(llvm::dbgs() << " Underlying V1:" << *O1.getDef()); DEBUG(llvm::dbgs() << " Underlying V2:" << *O2.getDef()); // If O1 and O2 do not equal, see if we can prove that they cannot be the // same object. If we can, return No Alias. if (O1 != O2 && aliasUnequalObjects(O1, O2)) return AliasResult::NoAlias; // Ok, either O1, O2 are the same or we could not prove anything based off of // their inequality. // Next: ask escape analysis. This catches cases where we compare e.g. a // non-escaping pointer with another (maybe escaping) pointer. Escape analysis // uses the connection graph to check if the pointers may point to the same // content. // Note that escape analysis must work with the original pointers and not the // underlying objects because it treats projections differently. if (!EA->canPointToSameMemory(V1, V2)) { DEBUG(llvm::dbgs() << " Found not-aliased objects based on" "escape analysis\n"); return AliasResult::NoAlias; } // Now we climb up use-def chains and attempt to do tricks based off of GEPs. // First if one instruction is a gep and the other is not, canonicalize our // inputs so that V1 always is the instruction containing the GEP. if (!NewProjection::isAddressProjection(V1) && NewProjection::isAddressProjection(V2)) { std::swap(V1, V2); std::swap(O1, O2); } // If V1 is an address projection, attempt to use information from the // aggregate type tree to disambiguate it from V2. if (NewProjection::isAddressProjection(V1)) { AliasResult Result = aliasAddressProjection(V1, V2, O1, O2); if (Result != AliasResult::MayAlias) return Result; } // We could not prove anything. Be conservative and return that V1, V2 may // alias. return AliasResult::MayAlias; }
/// Uses a bunch of ad-hoc rules to disambiguate a GEP instruction against /// another pointer. We know that V1 is a GEP, but we don't know anything about /// V2. O1, O2 are getUnderlyingObject of V1, V2 respectively. AliasResult AliasAnalysis::aliasAddressProjection(SILValue V1, SILValue V2, SILValue O1, SILValue O2) { // If V2 is also a gep instruction with a must-alias or not-aliasing base // pointer, figure out if the indices of the GEPs tell us anything about the // derived pointers. if (!NewProjection::isAddressProjection(V2)) { // Ok, V2 is not an address projection. See if V2 after stripping casts // aliases O1. If so, then we know that V2 must partially alias V1 via a // must alias relation on O1. This ensures that given an alloc_stack and a // gep from that alloc_stack, we say that they partially alias. if (isSameValueOrGlobal(O1, V2.stripCasts())) return AliasResult::PartialAlias; return AliasResult::MayAlias; } assert(!NewProjection::isAddressProjection(O1) && "underlying object may not be a projection"); assert(!NewProjection::isAddressProjection(O2) && "underlying object may not be a projection"); // Do the base pointers alias? AliasResult BaseAlias = aliasInner(O1, O2); // If the underlying objects are not aliased, the projected values are also // not aliased. if (BaseAlias == AliasResult::NoAlias) return AliasResult::NoAlias; // Let's do alias checking based on projections. auto V1Path = ProjectionPath::getAddrProjectionPath(O1, V1, true); auto V2Path = ProjectionPath::getAddrProjectionPath(O2, V2, true); // getUnderlyingPath and findAddressProjectionPathBetweenValues disagree on // what the base pointer of the two values are. Be conservative and return // MayAlias. // // FIXME: The only way this should happen realistically is if there are // casts in between two projection instructions. getUnderlyingObject will // ignore that, while findAddressProjectionPathBetweenValues wont. The two // solutions are to make address projections variadic (something on the wee // horizon) or enable Projection to represent a cast as a special sort of // projection. if (!V1Path || !V2Path) return AliasResult::MayAlias; auto R = V1Path->computeSubSeqRelation(*V2Path); // If all of the projections are equal (and they have the same base pointer), // the two GEPs must be the same. if (BaseAlias == AliasResult::MustAlias && R == SubSeqRelation_t::Equal) return AliasResult::MustAlias; // The two GEPs do not alias if they are accessing different fields, even if // we don't know the base pointers. Different fields should not overlap. // // TODO: Replace this with a check on the computed subseq relation. See the // TODO in computeSubSeqRelation. if (V1Path->hasNonEmptySymmetricDifference(V2Path.getValue())) return AliasResult::NoAlias; // If one of the GEPs is a super path of the other then they partially // alias. if (BaseAlias == AliasResult::MustAlias && isStrictSubSeqRelation(R)) return AliasResult::PartialAlias; // We failed to prove anything. Be conservative and return MayAlias. return AliasResult::MayAlias; }