mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 19:52:54 +01:00
3fc1696aca
Summary: Adding contained caching to AliasAnalysis. BasicAA is currently the only one using it. AA changes: - This patch is pulling the caches from BasicAAResults to AAResults, meaning the getModRefInfo call benefits from the IsCapturedCache as well when in "batch mode". - All AAResultBase implementations add the QueryInfo member to all APIs. AAResults APIs maintain wrapper APIs such that all alias()/getModRefInfo call sites are unchanged. - AA now provides a BatchAAResults type as a wrapper to AAResults. It keeps the AAResults instance and a QueryInfo instantiated to batch mode. It delegates all work to the AAResults instance with the batched QueryInfo. More API wrappers may be needed in BatchAAResults; only the minimum needed is currently added. MemorySSA changes: - All walkers are now templated on the AA used (AliasAnalysis=AAResults or BatchAAResults). - At build time, we optimize uses; now we create a local walker (lives only as long as OptimizeUses does) using BatchAAResults. - All Walkers have an internal AA and only use that now, never the AA in MemorySSA. The Walkers receive the AA they will use when built. - The walker we use for queries after the build is instantiated on AliasAnalysis and is built after building MemorySSA and setting AA. - All static methods doing walking are now templated on AliasAnalysisType if they are used both during build and after. If used only during build, the method now only takes a BatchAAResults. If used only after build, the method now takes an AliasAnalysis. Subscribers: sanjoy, arsenm, jvesely, nhaehnle, jlebar, george.burgess.iv, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D59315 llvm-svn: 356783
132 lines
4.5 KiB
C++
132 lines
4.5 KiB
C++
//===- BasicAliasAnalysisTest.cpp - Unit tests for BasicAA ----------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// Targeted tests that are hard/convoluted to make happen with just `opt`.
|
|
//
|
|
|
|
#include "llvm/Analysis/BasicAliasAnalysis.h"
|
|
#include "llvm/Analysis/AliasAnalysis.h"
|
|
#include "llvm/AsmParser/Parser.h"
|
|
#include "llvm/IR/Dominators.h"
|
|
#include "llvm/IR/IRBuilder.h"
|
|
#include "llvm/IR/LLVMContext.h"
|
|
#include "llvm/IR/Module.h"
|
|
#include "llvm/Support/SourceMgr.h"
|
|
#include "gtest/gtest.h"
|
|
|
|
using namespace llvm;
|
|
|
|
// FIXME: This is duplicated between this file and MemorySSATest. Refactor.
|
|
const static char DLString[] = "e-i64:64-f80:128-n8:16:32:64-S128";
|
|
|
|
/// There's a lot of common setup between these tests. This fixture helps reduce
|
|
/// that. Tests should mock up a function, store it in F, and then call
|
|
/// setupAnalyses().
|
|
class BasicAATest : public testing::Test {
|
|
protected:
|
|
// N.B. Many of these members depend on each other (e.g. the Module depends on
|
|
// the Context, etc.). So, order matters here (and in TestAnalyses).
|
|
LLVMContext C;
|
|
Module M;
|
|
IRBuilder<> B;
|
|
DataLayout DL;
|
|
TargetLibraryInfoImpl TLII;
|
|
TargetLibraryInfo TLI;
|
|
Function *F;
|
|
|
|
// Things that we need to build after the function is created.
|
|
struct TestAnalyses {
|
|
DominatorTree DT;
|
|
AssumptionCache AC;
|
|
BasicAAResult BAA;
|
|
AAQueryInfo AAQI;
|
|
|
|
TestAnalyses(BasicAATest &Test)
|
|
: DT(*Test.F), AC(*Test.F), BAA(Test.DL, *Test.F, Test.TLI, AC, &DT),
|
|
AAQI() {}
|
|
};
|
|
|
|
llvm::Optional<TestAnalyses> Analyses;
|
|
|
|
TestAnalyses &setupAnalyses() {
|
|
assert(F);
|
|
Analyses.emplace(*this);
|
|
return Analyses.getValue();
|
|
}
|
|
|
|
public:
|
|
BasicAATest()
|
|
: M("BasicAATest", C), B(C), DL(DLString), TLI(TLII), F(nullptr) {}
|
|
};
|
|
|
|
// Check that a function arg can't trivially alias a global when we're accessing
|
|
// >sizeof(global) bytes through that arg, unless the access size is just an
|
|
// upper-bound.
|
|
TEST_F(BasicAATest, AliasInstWithObjectOfImpreciseSize) {
|
|
F = Function::Create(
|
|
FunctionType::get(B.getVoidTy(), {B.getInt32Ty()->getPointerTo()}, false),
|
|
GlobalValue::ExternalLinkage, "F", &M);
|
|
|
|
BasicBlock *Entry(BasicBlock::Create(C, "", F));
|
|
B.SetInsertPoint(Entry);
|
|
|
|
Value *IncomingI32Ptr = F->arg_begin();
|
|
|
|
auto *GlobalPtr =
|
|
cast<GlobalVariable>(M.getOrInsertGlobal("some_global", B.getInt8Ty()));
|
|
|
|
// Without sufficiently restricted linkage/an init, some of the object size
|
|
// checking bits get more conservative.
|
|
GlobalPtr->setLinkage(GlobalValue::LinkageTypes::InternalLinkage);
|
|
GlobalPtr->setInitializer(B.getInt8(0));
|
|
|
|
auto &AllAnalyses = setupAnalyses();
|
|
BasicAAResult &BasicAA = AllAnalyses.BAA;
|
|
AAQueryInfo &AAQI = AllAnalyses.AAQI;
|
|
ASSERT_EQ(
|
|
BasicAA.alias(MemoryLocation(IncomingI32Ptr, LocationSize::precise(4)),
|
|
MemoryLocation(GlobalPtr, LocationSize::precise(1)), AAQI),
|
|
AliasResult::NoAlias);
|
|
|
|
ASSERT_EQ(
|
|
BasicAA.alias(MemoryLocation(IncomingI32Ptr, LocationSize::upperBound(4)),
|
|
MemoryLocation(GlobalPtr, LocationSize::precise(1)), AAQI),
|
|
AliasResult::MayAlias);
|
|
}
|
|
|
|
// Check that we fall back to MayAlias if we see an access of an entire object
|
|
// that's just an upper-bound.
|
|
TEST_F(BasicAATest, AliasInstWithFullObjectOfImpreciseSize) {
|
|
F = Function::Create(
|
|
FunctionType::get(B.getVoidTy(), {B.getInt64Ty()}, false),
|
|
GlobalValue::ExternalLinkage, "F", &M);
|
|
|
|
BasicBlock *Entry(BasicBlock::Create(C, "", F));
|
|
B.SetInsertPoint(Entry);
|
|
|
|
Value *ArbitraryI32 = F->arg_begin();
|
|
AllocaInst *I8 = B.CreateAlloca(B.getInt8Ty(), B.getInt32(2));
|
|
auto *I8AtUncertainOffset =
|
|
cast<GetElementPtrInst>(B.CreateGEP(B.getInt8Ty(), I8, ArbitraryI32));
|
|
|
|
auto &AllAnalyses = setupAnalyses();
|
|
BasicAAResult &BasicAA = AllAnalyses.BAA;
|
|
AAQueryInfo &AAQI = AllAnalyses.AAQI;
|
|
ASSERT_EQ(BasicAA.alias(
|
|
MemoryLocation(I8, LocationSize::precise(2)),
|
|
MemoryLocation(I8AtUncertainOffset, LocationSize::precise(1)),
|
|
AAQI),
|
|
AliasResult::PartialAlias);
|
|
|
|
ASSERT_EQ(BasicAA.alias(
|
|
MemoryLocation(I8, LocationSize::upperBound(2)),
|
|
MemoryLocation(I8AtUncertainOffset, LocationSize::precise(1)),
|
|
AAQI),
|
|
AliasResult::MayAlias);
|
|
}
|