-AliasAnalysis::DependenceResult
-AliasAnalysis::getDependenceViaModRefInfo(const Instruction *First,
- const Value *FirstPHITranslatedAddr,
- DependenceQueryFlags FirstFlags,
- const Instruction *Second,
- const Value *SecondPHITranslatedAddr,
- DependenceQueryFlags SecondFlags) {
- if (const LoadInst *L = dyn_cast<LoadInst>(First)) {
- // Be over-conservative with volatile for now.
- if (L->isVolatile())
- return Unknown;
-
- // If we don't have a phi-translated address, use the actual one.
- if (!FirstPHITranslatedAddr)
- FirstPHITranslatedAddr = L->getPointerOperand();
-
- // Forward this query to getModRefInfo.
- switch (getModRefInfo(Second,
- FirstPHITranslatedAddr,
- getTypeStoreSize(L->getType()))) {
- case NoModRef:
- // Second doesn't reference First's memory, so they're independent.
- return Independent;
-
- case Ref:
- // Second only reads from the memory read from by First. If it
- // also writes to any other memory, be conservative.
- if (Second->mayWriteToMemory())
- return Unknown;
-
- // If it's loading the same size from the same address, we can
- // give a more precise result.
- if (const LoadInst *SecondL = dyn_cast<LoadInst>(Second)) {
- // If we don't have a phi-translated address, use the actual one.
- if (!SecondPHITranslatedAddr)
- SecondPHITranslatedAddr = SecondL->getPointerOperand();
-
- unsigned LSize = getTypeStoreSize(L->getType());
- unsigned SecondLSize = getTypeStoreSize(SecondL->getType());
- if (alias(FirstPHITranslatedAddr, LSize,
- SecondPHITranslatedAddr, SecondLSize) ==
- MustAlias) {
- // If the loads are the same size, it's ReadThenRead.
- if (LSize == SecondLSize)
- return ReadThenRead;
-
- // If the second load is smaller, it's only ReadThenReadSome.
- if (LSize > SecondLSize)
- return ReadThenReadSome;
- }
- }
-
- // Otherwise it's just two loads.
- return Independent;
-
- case Mod:
- // Second only writes to the memory read from by First. If it
- // also reads from any other memory, be conservative.
- if (Second->mayReadFromMemory())
- return Unknown;
-
- // If it's storing the same size to the same address, we can
- // give a more precise result.
- if (const StoreInst *SecondS = dyn_cast<StoreInst>(Second)) {
- // If we don't have a phi-translated address, use the actual one.
- if (!SecondPHITranslatedAddr)
- SecondPHITranslatedAddr = SecondS->getPointerOperand();
-
- unsigned LSize = getTypeStoreSize(L->getType());
- unsigned SecondSSize = getTypeStoreSize(SecondS->getType());
- if (alias(FirstPHITranslatedAddr, LSize,
- SecondPHITranslatedAddr, SecondSSize) ==
- MustAlias) {
- // If the load and the store are the same size, it's ReadThenWrite.
- if (LSize == SecondSSize)
- return ReadThenWrite;
- }
- }
-
- // Otherwise we don't know if it could be writing to other memory.
- return Unknown;
-
- case ModRef:
- // Second reads and writes to the memory read from by First.
- // We don't have a way to express that.
- return Unknown;
- }
-
- } else if (const StoreInst *S = dyn_cast<StoreInst>(First)) {
- // Be over-conservative with volatile for now.
- if (S->isVolatile())
- return Unknown;
-
- // If we don't have a phi-translated address, use the actual one.
- if (!FirstPHITranslatedAddr)
- FirstPHITranslatedAddr = S->getPointerOperand();
-
- // Forward this query to getModRefInfo.
- switch (getModRefInfo(Second,
- FirstPHITranslatedAddr,
- getTypeStoreSize(S->getValueOperand()->getType()))) {
- case NoModRef:
- // Second doesn't reference First's memory, so they're independent.
- return Independent;
-
- case Ref:
- // Second only reads from the memory written to by First. If it
- // also writes to any other memory, be conservative.
- if (Second->mayWriteToMemory())
- return Unknown;
-
- // If it's loading the same size from the same address, we can
- // give a more precise result.
- if (const LoadInst *SecondL = dyn_cast<LoadInst>(Second)) {
- // If we don't have a phi-translated address, use the actual one.
- if (!SecondPHITranslatedAddr)
- SecondPHITranslatedAddr = SecondL->getPointerOperand();
-
- unsigned SSize = getTypeStoreSize(S->getValueOperand()->getType());
- unsigned SecondLSize = getTypeStoreSize(SecondL->getType());
- if (alias(FirstPHITranslatedAddr, SSize,
- SecondPHITranslatedAddr, SecondLSize) ==
- MustAlias) {
- // If the store and the load are the same size, it's WriteThenRead.
- if (SSize == SecondLSize)
- return WriteThenRead;
-
- // If the load is smaller, it's only WriteThenReadSome.
- if (SSize > SecondLSize)
- return WriteThenReadSome;
- }
- }
-
- // Otherwise we don't know if it could be reading from other memory.
- return Unknown;
-
- case Mod:
- // Second only writes to the memory written to by First. If it
- // also reads from any other memory, be conservative.
- if (Second->mayReadFromMemory())
- return Unknown;
-
- // If it's storing the same size to the same address, we can
- // give a more precise result.
- if (const StoreInst *SecondS = dyn_cast<StoreInst>(Second)) {
- // If we don't have a phi-translated address, use the actual one.
- if (!SecondPHITranslatedAddr)
- SecondPHITranslatedAddr = SecondS->getPointerOperand();
-
- unsigned SSize = getTypeStoreSize(S->getValueOperand()->getType());
- unsigned SecondSSize = getTypeStoreSize(SecondS->getType());
- if (alias(FirstPHITranslatedAddr, SSize,
- SecondPHITranslatedAddr, SecondSSize) ==
- MustAlias) {
- // If the stores are the same size, it's WriteThenWrite.
- if (SSize == SecondSSize)
- return WriteThenWrite;
-
- // If the second store is larger, it's only WriteSomeThenWrite.
- if (SSize < SecondSSize)
- return WriteSomeThenWrite;
- }
- }
-
- // Otherwise we don't know if it could be writing to other memory.
- return Unknown;
-
- case ModRef:
- // Second reads and writes to the memory written to by First.
- // We don't have a way to express that.
- return Unknown;
- }
-
- } else if (const VAArgInst *V = dyn_cast<VAArgInst>(First)) {
- // If we don't have a phi-translated address, use the actual one.
- if (!FirstPHITranslatedAddr)
- FirstPHITranslatedAddr = V->getPointerOperand();
-
- // Forward this query to getModRefInfo.
- if (getModRefInfo(Second, FirstPHITranslatedAddr, UnknownSize) == NoModRef)
- // Second doesn't reference First's memory, so they're independent.
- return Independent;
-
- } else if (ImmutableCallSite FirstCS = cast<Value>(First)) {
- assert(!FirstPHITranslatedAddr &&
- !SecondPHITranslatedAddr &&
- "PHI translation with calls not supported yet!");
-
- // If both instructions are calls/invokes we can use the two-callsite
- // form of getModRefInfo.
- if (ImmutableCallSite SecondCS = cast<Value>(Second))
- // getModRefInfo's arguments are backwards from intuition.
- switch (getModRefInfo(SecondCS, FirstCS)) {
- case NoModRef:
- // Second doesn't reference First's memory, so they're independent.
- return Independent;
-
- case Ref:
- // If they're both read-only, there's no dependence.
- if (FirstCS.onlyReadsMemory() && SecondCS.onlyReadsMemory())
- return Independent;
-
- // Otherwise it's not obvious what we can do here.
- return Unknown;
-
- case Mod:
- // It's not obvious what we can do here.
- return Unknown;
-
- case ModRef:
- // I know, right?
- return Unknown;
- }
- }
-
- // For anything else, be conservative.
- return Unknown;
-}
-
-AliasAnalysis::ModRefBehavior
-AliasAnalysis::getIntrinsicModRefBehavior(unsigned iid) {
-#define GET_INTRINSIC_MODREF_BEHAVIOR
-#include "llvm/Intrinsics.gen"
-#undef GET_INTRINSIC_MODREF_BEHAVIOR
-}
-