mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 11:13:28 +01:00
Make getModRefInfo with a default location not crash.
Add getModRefInfo that works without location. Add unit tests. llvm-svn: 234811
This commit is contained in:
parent
d87ccce8e0
commit
0dd1c441f1
@ -352,6 +352,24 @@ public:
|
|||||||
return (MRB & ModRef) && (MRB & ArgumentPointees);
|
return (MRB & ModRef) && (MRB & ArgumentPointees);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// getModRefInfo - Return information about whether or not an
|
||||||
|
/// instruction may read or write memory (without regard to a
|
||||||
|
/// specific location)
|
||||||
|
ModRefResult getModRefInfo(const Instruction *I) {
|
||||||
|
if (auto CS = ImmutableCallSite(I)) {
|
||||||
|
auto MRB = getModRefBehavior(CS);
|
||||||
|
if (MRB & ModRef)
|
||||||
|
return ModRef;
|
||||||
|
else if (MRB & Ref)
|
||||||
|
return Ref;
|
||||||
|
else if (MRB & Mod)
|
||||||
|
return Mod;
|
||||||
|
return NoModRef;
|
||||||
|
}
|
||||||
|
|
||||||
|
return getModRefInfo(I, Location());
|
||||||
|
}
|
||||||
|
|
||||||
/// getModRefInfo - Return information about whether or not an instruction may
|
/// getModRefInfo - Return information about whether or not an instruction may
|
||||||
/// read or write the specified memory location. An instruction
|
/// read or write the specified memory location. An instruction
|
||||||
/// that doesn't read or write memory may be trivially LICM'd for example.
|
/// that doesn't read or write memory may be trivially LICM'd for example.
|
||||||
|
@ -330,7 +330,7 @@ AliasAnalysis::getModRefInfo(const LoadInst *L, const Location &Loc) {
|
|||||||
|
|
||||||
// If the load address doesn't alias the given address, it doesn't read
|
// If the load address doesn't alias the given address, it doesn't read
|
||||||
// or write the specified memory.
|
// or write the specified memory.
|
||||||
if (!alias(getLocation(L), Loc))
|
if (Loc.Ptr && !alias(getLocation(L), Loc))
|
||||||
return NoModRef;
|
return NoModRef;
|
||||||
|
|
||||||
// Otherwise, a load just reads.
|
// Otherwise, a load just reads.
|
||||||
@ -343,16 +343,19 @@ AliasAnalysis::getModRefInfo(const StoreInst *S, const Location &Loc) {
|
|||||||
if (!S->isUnordered())
|
if (!S->isUnordered())
|
||||||
return ModRef;
|
return ModRef;
|
||||||
|
|
||||||
|
if (Loc.Ptr) {
|
||||||
// If the store address cannot alias the pointer in question, then the
|
// If the store address cannot alias the pointer in question, then the
|
||||||
// specified memory cannot be modified by the store.
|
// specified memory cannot be modified by the store.
|
||||||
if (!alias(getLocation(S), Loc))
|
if (!alias(getLocation(S), Loc))
|
||||||
return NoModRef;
|
return NoModRef;
|
||||||
|
|
||||||
// If the pointer is a pointer to constant memory, then it could not have been
|
// If the pointer is a pointer to constant memory, then it could not have
|
||||||
// modified by this store.
|
// been modified by this store.
|
||||||
if (pointsToConstantMemory(Loc))
|
if (pointsToConstantMemory(Loc))
|
||||||
return NoModRef;
|
return NoModRef;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// Otherwise, a store just writes.
|
// Otherwise, a store just writes.
|
||||||
return Mod;
|
return Mod;
|
||||||
}
|
}
|
||||||
|
94
unittests/Analysis/AliasAnalysisTest.cpp
Normal file
94
unittests/Analysis/AliasAnalysisTest.cpp
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
//===--- AliasAnalysisTest.cpp - Mixed TBAA unit tests --------------------===//
|
||||||
|
//
|
||||||
|
// The LLVM Compiler Infrastructure
|
||||||
|
//
|
||||||
|
// This file is distributed under the University of Illinois Open Source
|
||||||
|
// License. See LICENSE.TXT for details.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#include "llvm/Analysis/AliasAnalysis.h"
|
||||||
|
#include "llvm/Analysis/Passes.h"
|
||||||
|
#include "llvm/IR/Constants.h"
|
||||||
|
#include "llvm/IR/Instructions.h"
|
||||||
|
#include "llvm/IR/LLVMContext.h"
|
||||||
|
#include "llvm/IR/Module.h"
|
||||||
|
#include "llvm/IR/LegacyPassManager.h"
|
||||||
|
#include "llvm/Support/CommandLine.h"
|
||||||
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
|
namespace llvm {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
class AliasAnalysisTest : public testing::Test {
|
||||||
|
protected:
|
||||||
|
AliasAnalysisTest() : M("AliasAnalysisTBAATest", C) {}
|
||||||
|
|
||||||
|
// This is going to check that calling getModRefInfo without a location, and
|
||||||
|
// with a default location, first, doesn't crash, and second, gives the right
|
||||||
|
// answer.
|
||||||
|
void CheckModRef(Instruction *I, AliasAnalysis::ModRefResult Result) {
|
||||||
|
static char ID;
|
||||||
|
class CheckModRefTestPass : public FunctionPass {
|
||||||
|
public:
|
||||||
|
CheckModRefTestPass(Instruction *I, AliasAnalysis::ModRefResult Result)
|
||||||
|
: FunctionPass(ID), ExpectResult(Result), I(I) {}
|
||||||
|
static int initialize() {
|
||||||
|
PassInfo *PI = new PassInfo("CheckModRef testing pass", "", &ID,
|
||||||
|
nullptr, true, true);
|
||||||
|
PassRegistry::getPassRegistry()->registerPass(*PI, false);
|
||||||
|
initializeAliasAnalysisAnalysisGroup(*PassRegistry::getPassRegistry());
|
||||||
|
initializeBasicAliasAnalysisPass(*PassRegistry::getPassRegistry());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||||
|
AU.setPreservesAll();
|
||||||
|
AU.addRequiredTransitive<AliasAnalysis>();
|
||||||
|
}
|
||||||
|
bool runOnFunction(Function &) override {
|
||||||
|
AliasAnalysis &AA = getAnalysis<AliasAnalysis>();
|
||||||
|
EXPECT_EQ(AA.getModRefInfo(I, AliasAnalysis::Location()), ExpectResult);
|
||||||
|
EXPECT_EQ(AA.getModRefInfo(I), ExpectResult);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
AliasAnalysis::ModRefResult ExpectResult;
|
||||||
|
Instruction *I;
|
||||||
|
};
|
||||||
|
static int initialize = CheckModRefTestPass::initialize();
|
||||||
|
(void)initialize;
|
||||||
|
CheckModRefTestPass *P = new CheckModRefTestPass(I, Result);
|
||||||
|
legacy::PassManager PM;
|
||||||
|
PM.add(createBasicAliasAnalysisPass());
|
||||||
|
PM.add(P);
|
||||||
|
PM.run(M);
|
||||||
|
}
|
||||||
|
|
||||||
|
LLVMContext C;
|
||||||
|
Module M;
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_F(AliasAnalysisTest, getModRefInfo) {
|
||||||
|
// Setup function.
|
||||||
|
FunctionType *FTy =
|
||||||
|
FunctionType::get(Type::getVoidTy(C), std::vector<Type *>(), false);
|
||||||
|
auto *F = cast<Function>(M.getOrInsertFunction("f", FTy));
|
||||||
|
auto *BB = BasicBlock::Create(C, "entry", F);
|
||||||
|
auto IntType = Type::getInt32Ty(C);
|
||||||
|
auto PtrType = Type::getInt32PtrTy(C);
|
||||||
|
auto *Value = ConstantInt::get(IntType, 42);
|
||||||
|
auto *Addr = ConstantPointerNull::get(PtrType);
|
||||||
|
|
||||||
|
auto *Store1 = new StoreInst(Value, Addr, BB);
|
||||||
|
auto *Load1 = new LoadInst(Addr, "load", BB);
|
||||||
|
auto *Add1 = BinaryOperator::CreateAdd(Value, Value, "add", BB);
|
||||||
|
|
||||||
|
ReturnInst::Create(C, nullptr, BB);
|
||||||
|
|
||||||
|
// Check basic results
|
||||||
|
CheckModRef(Store1, AliasAnalysis::ModRefResult::Mod);
|
||||||
|
CheckModRef(Load1, AliasAnalysis::ModRefResult::Ref);
|
||||||
|
CheckModRef(Add1, AliasAnalysis::ModRefResult::NoModRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end anonymous namspace
|
||||||
|
} // end llvm namespace
|
@ -7,6 +7,7 @@ set(LLVM_LINK_COMPONENTS
|
|||||||
)
|
)
|
||||||
|
|
||||||
add_llvm_unittest(AnalysisTests
|
add_llvm_unittest(AnalysisTests
|
||||||
|
AliasAnalysisTest.cpp
|
||||||
CallGraphTest.cpp
|
CallGraphTest.cpp
|
||||||
CFGTest.cpp
|
CFGTest.cpp
|
||||||
LazyCallGraphTest.cpp
|
LazyCallGraphTest.cpp
|
||||||
|
Loading…
Reference in New Issue
Block a user