[llvm-commits] CVS: llvm/lib/Analysis/BasicAliasAnalysis.cpp AliasAnalysis.cpp
Chris Lattner
lattner at cs.uiuc.edu
Wed Feb 26 13:43:00 PST 2003
Changes in directory llvm/lib/Analysis:
BasicAliasAnalysis.cpp added (r1.1)
AliasAnalysis.cpp updated: 1.11 -> 1.12
---
Log message:
Move BasicAA pass out to it's own header file
---
Diffs of the changes:
Index: llvm/lib/Analysis/AliasAnalysis.cpp
diff -u llvm/lib/Analysis/AliasAnalysis.cpp:1.11 llvm/lib/Analysis/AliasAnalysis.cpp:1.12
--- llvm/lib/Analysis/AliasAnalysis.cpp:1.11 Wed Feb 26 13:26:51 2003
+++ llvm/lib/Analysis/AliasAnalysis.cpp Wed Feb 26 13:41:54 2003
@@ -17,14 +17,9 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/Analysis/BasicAliasAnalysis.h"
+#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/BasicBlock.h"
#include "llvm/iMemory.h"
-#include "llvm/iOther.h"
-#include "llvm/Constants.h"
-#include "llvm/ConstantHandling.h"
-#include "llvm/GlobalValue.h"
-#include "llvm/DerivedTypes.h"
#include "llvm/Target/TargetData.h"
// Register the AliasAnalysis interface, providing a nice name to refer to.
@@ -94,257 +89,11 @@
return false;
}
-//===----------------------------------------------------------------------===//
-// BasicAliasAnalysis Pass Implementation
-//===----------------------------------------------------------------------===//
+// Because of the way .a files work, we must force the BasicAA implementation to
+// be pulled in if the AliasAnalysis classes are pulled in. Otherwise we run
+// the risk of AliasAnalysis being used, but the default implementation not
+// being linked into the tool that uses it.
//
-// Because of the way .a files work, the implementation of the
-// BasicAliasAnalysis class MUST be in the AliasAnalysis file itself, or else we
-// run the risk of AliasAnalysis being used, but the default implementation not
-// being linked into the tool that uses it. As such, we register and implement
-// the class here.
-//
-namespace {
- // Register this pass...
- RegisterOpt<BasicAliasAnalysis>
- X("basicaa", "Basic Alias Analysis (default AA impl)");
-
- // Declare that we implement the AliasAnalysis interface
- RegisterAnalysisGroup<AliasAnalysis, BasicAliasAnalysis, true> Y;
-} // End of anonymous namespace
-
-void BasicAliasAnalysis::initializePass() {
- InitializeAliasAnalysis(this);
-}
-
-
-
-// hasUniqueAddress - Return true if the
-static inline bool hasUniqueAddress(const Value *V) {
- return isa<GlobalValue>(V) || isa<MallocInst>(V) || isa<AllocaInst>(V);
-}
-
-static const Value *getUnderlyingObject(const Value *V) {
- if (!isa<PointerType>(V->getType())) return 0;
-
- // If we are at some type of object... return it.
- if (hasUniqueAddress(V)) return V;
-
- // Traverse through different addressing mechanisms...
- if (const Instruction *I = dyn_cast<Instruction>(V)) {
- if (isa<CastInst>(I) || isa<GetElementPtrInst>(I))
- return getUnderlyingObject(I->getOperand(0));
- }
- return 0;
-}
-
-
-// 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.
-// Hopefully we have a smart C++ compiler. :)
-//
-AliasAnalysis::AliasResult
-BasicAliasAnalysis::alias(const Value *V1, unsigned V1Size,
- const Value *V2, unsigned V2Size) {
- // Strip off constant pointer refs if they exist
- if (const ConstantPointerRef *CPR = dyn_cast<ConstantPointerRef>(V1))
- V1 = CPR->getValue();
- if (const ConstantPointerRef *CPR = dyn_cast<ConstantPointerRef>(V2))
- V2 = CPR->getValue();
-
- // Are we checking for alias of the same value?
- if (V1 == V2) return MustAlias;
-
- if ((!isa<PointerType>(V1->getType()) || !isa<PointerType>(V2->getType())) &&
- V1->getType() != Type::LongTy && V2->getType() != Type::LongTy)
- return NoAlias; // Scalars cannot alias each other
-
- // Strip off cast instructions...
- if (const Instruction *I = dyn_cast<CastInst>(V1))
- return alias(I->getOperand(0), V1Size, V2, V2Size);
- if (const Instruction *I = dyn_cast<CastInst>(V2))
- return alias(V1, V1Size, I->getOperand(0), V2Size);
-
- // Figure out what objects these things are pointing to if we can...
- const Value *O1 = getUnderlyingObject(V1);
- const Value *O2 = getUnderlyingObject(V2);
-
- // Pointing at a discernable object?
- if (O1 && O2) {
- // If they are two different objects, we know that we have no alias...
- if (O1 != O2) return NoAlias;
-
- // If they are the same object, they we can look at the indexes. If they
- // index off of the object is the same for both pointers, they must alias.
- // If they are provably different, they must not alias. Otherwise, we can't
- // tell anything.
- } else if (O1 && isa<ConstantPointerNull>(V2)) {
- return NoAlias; // Unique values don't alias null
- } else if (O2 && isa<ConstantPointerNull>(V1)) {
- return NoAlias; // Unique values don't alias null
- }
-
- // If we have two gep instructions with identical indices, return an alias
- // result equal to the alias result of the original pointer...
- //
- if (const GetElementPtrInst *GEP1 = dyn_cast<GetElementPtrInst>(V1))
- if (const GetElementPtrInst *GEP2 = dyn_cast<GetElementPtrInst>(V2))
- if (GEP1->getNumOperands() == GEP2->getNumOperands() &&
- GEP1->getOperand(0)->getType() == GEP2->getOperand(0)->getType()) {
- AliasResult GAlias =
- CheckGEPInstructions((GetElementPtrInst*)GEP1, V1Size,
- (GetElementPtrInst*)GEP2, V2Size);
- if (GAlias != MayAlias)
- return GAlias;
- }
-
- // Check to see if these two pointers are related by a getelementptr
- // instruction. If one pointer is a GEP with a non-zero index of the other
- // pointer, we know they cannot alias.
- //
- if (isa<GetElementPtrInst>(V2)) {
- std::swap(V1, V2);
- std::swap(V1Size, V2Size);
- }
-
- if (const GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(V1))
- if (GEP->getOperand(0) == V2) {
- // If there is at least one non-zero constant index, we know they cannot
- // alias.
- for (unsigned i = 1, e = GEP->getNumOperands(); i != e; ++i)
- if (const Constant *C = dyn_cast<Constant>(GEP->getOperand(i)))
- if (!C->isNullValue())
- return NoAlias;
- }
-
- return MayAlias;
-}
-
-// CheckGEPInstructions - Check two GEP instructions of compatible types and
-// equal number of arguments. This checks to see if the index expressions
-// preclude the pointers from aliasing...
-//
-AliasAnalysis::AliasResult
-BasicAliasAnalysis::CheckGEPInstructions(GetElementPtrInst *GEP1, unsigned G1S,
- GetElementPtrInst *GEP2, unsigned G2S){
- // Do the base pointers alias?
- AliasResult BaseAlias = alias(GEP1->getOperand(0), G1S,
- GEP2->getOperand(0), G2S);
- if (BaseAlias != MustAlias) // No or May alias: We cannot add anything...
- return BaseAlias;
-
- // Find the (possibly empty) initial sequence of equal values...
- unsigned NumGEPOperands = GEP1->getNumOperands();
- unsigned UnequalOper = 1;
- while (UnequalOper != NumGEPOperands &&
- GEP1->getOperand(UnequalOper) == GEP2->getOperand(UnequalOper))
- ++UnequalOper;
-
- // If all operands equal each other, then the derived pointers must
- // alias each other...
- if (UnequalOper == NumGEPOperands) return MustAlias;
-
- // So now we know that the indexes derived from the base pointers,
- // which are known to alias, are different. We can still determine a
- // no-alias result if there are differing constant pairs in the index
- // chain. For example:
- // A[i][0] != A[j][1] iff (&A[0][1]-&A[0][0] >= std::max(G1S, G2S))
- //
- unsigned SizeMax = std::max(G1S, G2S);
- if (SizeMax == ~0U) return MayAlias; // Avoid frivolous work...
-
- // Scan for the first operand that is constant and unequal in the
- // two getelemenptrs...
- unsigned FirstConstantOper = UnequalOper;
- for (; FirstConstantOper != NumGEPOperands; ++FirstConstantOper) {
- const Value *G1Oper = GEP1->getOperand(FirstConstantOper);
- const Value *G2Oper = GEP2->getOperand(FirstConstantOper);
- if (G1Oper != G2Oper && // Found non-equal constant indexes...
- isa<Constant>(G1Oper) && isa<Constant>(G2Oper)) {
- // Make sure they are comparable... and make sure the GEP with
- // the smaller leading constant is GEP1.
- ConstantBool *Compare =
- *cast<Constant>(GEP1->getOperand(FirstConstantOper)) >
- *cast<Constant>(GEP2->getOperand(FirstConstantOper));
- if (Compare) { // If they are comparable...
- if (Compare->getValue())
- std::swap(GEP1, GEP2); // Make GEP1 < GEP2
- break;
- }
- }
- }
-
- // No constant operands, we cannot tell anything...
- if (FirstConstantOper == NumGEPOperands) return MayAlias;
-
- // If there are non-equal constants arguments, then we can figure
- // out a minimum known delta between the two index expressions... at
- // this point we know that the first constant index of GEP1 is less
- // than the first constant index of GEP2.
- //
- std::vector<Value*> Indices1;
- Indices1.reserve(NumGEPOperands-1);
- for (unsigned i = 1; i != FirstConstantOper; ++i)
- Indices1.push_back(Constant::getNullValue(GEP1->getOperand(i)
- ->getType()));
- std::vector<Value*> Indices2;
- Indices2.reserve(NumGEPOperands-1);
- Indices2 = Indices1; // Copy the zeros prefix...
-
- // Add the two known constant operands...
- Indices1.push_back((Value*)GEP1->getOperand(FirstConstantOper));
- Indices2.push_back((Value*)GEP2->getOperand(FirstConstantOper));
-
- const Type *GEPPointerTy = GEP1->getOperand(0)->getType();
-
- // Loop over the rest of the operands...
- for (unsigned i = FirstConstantOper+1; i!=NumGEPOperands; ++i){
- const Value *Op1 = GEP1->getOperand(i);
- const Value *Op2 = GEP1->getOperand(i);
- if (Op1 == Op2) { // If they are equal, use a zero index...
- Indices1.push_back(Constant::getNullValue(Op1->getType()));
- Indices2.push_back(Indices1.back());
- } else {
- if (isa<Constant>(Op1))
- Indices1.push_back((Value*)Op1);
- else {
- // GEP1 is known to produce a value less than GEP2. To be
- // conservatively correct, we must assume the largest
- // possible constant is used in this position. This cannot
- // be the initial index to the GEP instructions (because we
- // know we have at least one element before this one with
- // the different constant arguments), so we know that the
- // current index must be into either a struct or array.
- // Because of this, we can calculate the maximum value
- // possible.
- //
- const Type *ElTy = GEP1->getIndexedType(GEPPointerTy,
- Indices1, true);
- if (const StructType *STy = dyn_cast<StructType>(ElTy)) {
- Indices1.push_back(ConstantUInt::get(Type::UByteTy,
- STy->getNumContainedTypes()));
- } else {
- Indices1.push_back(ConstantSInt::get(Type::LongTy,
- cast<ArrayType>(ElTy)->getNumElements()));
- }
- }
-
- if (isa<Constant>(Op2))
- Indices2.push_back((Value*)Op2);
- else // Conservatively assume the minimum value for this index
- Indices2.push_back(Constant::getNullValue(Op1->getType()));
- }
- }
-
- unsigned Offset1 = getTargetData().getIndexedOffset(GEPPointerTy, Indices1);
- unsigned Offset2 = getTargetData().getIndexedOffset(GEPPointerTy, Indices2);
- assert(Offset1 < Offset2 &&"There is at least one different constant here!");
-
- if (Offset2-Offset1 >= SizeMax) {
- //std::cerr << "Determined that these two GEP's don't alias ["
- // << SizeMax << " bytes]: \n" << *GEP1 << *GEP2;
- return NoAlias;
- }
- return MayAlias;
-}
+extern void BasicAAStub();
+static IncludeFile INCLUDE_BASICAA_CPP((void*)&BasicAAStub);
More information about the llvm-commits
mailing list