forked from OSchip/llvm-project
[TBAA] Drop support for "old style" scalar TBAA tags
Summary: We've had support for auto upgrading old style scalar TBAA access metadata tags into the "new" struct path aware TBAA metadata for 3 years now. The only way to actually generate old style TBAA was explicitly through the IRBuilder API. I think this is a good time for dropping support for old style scalar TBAA. I'm not removing support for textual or bitcode upgrade -- if you have IR with the old style scalar TBAA tags that go through the AsmParser orf the bitcode parser before LLVM sees them, they will keep working as usual. Note: %val = load i32, i32* %ptr, !tbaa !N !N = < scalar tbaa node > is equivalent to %val = load i32, i32* %ptr, !tbaa !M !N = < scalar tbaa node > !M = !{!N, !N, 0} Reviewers: manmanren, chandlerc, sunfish Subscribers: mcrosier, llvm-commits, mgorny Differential Revision: https://reviews.llvm.org/D26229 llvm-svn: 286291
This commit is contained in:
parent
d092107b0e
commit
2582e690b7
|
@ -417,15 +417,14 @@ MDNode *MDNode::getMostGenericTBAA(MDNode *A, MDNode *B) {
|
||||||
return A;
|
return A;
|
||||||
|
|
||||||
// For struct-path aware TBAA, we use the access type of the tag.
|
// For struct-path aware TBAA, we use the access type of the tag.
|
||||||
bool StructPath = isStructPathTBAA(A) && isStructPathTBAA(B);
|
assert(isStructPathTBAA(A) && isStructPathTBAA(B) &&
|
||||||
if (StructPath) {
|
"Auto upgrade should have taken care of this!");
|
||||||
A = cast_or_null<MDNode>(MutableTBAAStructTagNode(A).getAccessType());
|
A = cast_or_null<MDNode>(MutableTBAAStructTagNode(A).getAccessType());
|
||||||
if (!A)
|
if (!A)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
B = cast_or_null<MDNode>(MutableTBAAStructTagNode(B).getAccessType());
|
B = cast_or_null<MDNode>(MutableTBAAStructTagNode(B).getAccessType());
|
||||||
if (!B)
|
if (!B)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
|
||||||
|
|
||||||
SmallSetVector<MDNode *, 4> PathA;
|
SmallSetVector<MDNode *, 4> PathA;
|
||||||
MutableTBAANode TA(A);
|
MutableTBAANode TA(A);
|
||||||
|
@ -457,8 +456,6 @@ MDNode *MDNode::getMostGenericTBAA(MDNode *A, MDNode *B) {
|
||||||
--IA;
|
--IA;
|
||||||
--IB;
|
--IB;
|
||||||
}
|
}
|
||||||
if (!StructPath)
|
|
||||||
return Ret;
|
|
||||||
|
|
||||||
if (!Ret)
|
if (!Ret)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -492,52 +489,8 @@ void Instruction::getAAMetadata(AAMDNodes &N, bool Merge) const {
|
||||||
/// Aliases - Test whether the type represented by A may alias the
|
/// Aliases - Test whether the type represented by A may alias the
|
||||||
/// type represented by B.
|
/// type represented by B.
|
||||||
bool TypeBasedAAResult::Aliases(const MDNode *A, const MDNode *B) const {
|
bool TypeBasedAAResult::Aliases(const MDNode *A, const MDNode *B) const {
|
||||||
// Make sure that both MDNodes are struct-path aware.
|
// Verify that both input nodes are struct-path aware. Auto-upgrade should
|
||||||
if (isStructPathTBAA(A) && isStructPathTBAA(B))
|
// have taken care of this.
|
||||||
return PathAliases(A, B);
|
|
||||||
|
|
||||||
// Keep track of the root node for A and B.
|
|
||||||
TBAANode RootA, RootB;
|
|
||||||
|
|
||||||
// Climb the tree from A to see if we reach B.
|
|
||||||
for (TBAANode T(A);;) {
|
|
||||||
if (T.getNode() == B)
|
|
||||||
// B is an ancestor of A.
|
|
||||||
return true;
|
|
||||||
|
|
||||||
RootA = T;
|
|
||||||
T = T.getParent();
|
|
||||||
if (!T.getNode())
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Climb the tree from B to see if we reach A.
|
|
||||||
for (TBAANode T(B);;) {
|
|
||||||
if (T.getNode() == A)
|
|
||||||
// A is an ancestor of B.
|
|
||||||
return true;
|
|
||||||
|
|
||||||
RootB = T;
|
|
||||||
T = T.getParent();
|
|
||||||
if (!T.getNode())
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Neither node is an ancestor of the other.
|
|
||||||
|
|
||||||
// If they have different roots, they're part of different potentially
|
|
||||||
// unrelated type systems, so we must be conservative.
|
|
||||||
if (RootA.getNode() != RootB.getNode())
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// If they have the same root, then we've proved there's no alias.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Test whether the struct-path tag represented by A may alias the
|
|
||||||
/// struct-path tag represented by B.
|
|
||||||
bool TypeBasedAAResult::PathAliases(const MDNode *A, const MDNode *B) const {
|
|
||||||
// Verify that both input nodes are struct-path aware.
|
|
||||||
assert(isStructPathTBAA(A) && "MDNode A is not struct-path aware.");
|
assert(isStructPathTBAA(A) && "MDNode A is not struct-path aware.");
|
||||||
assert(isStructPathTBAA(B) && "MDNode B is not struct-path aware.");
|
assert(isStructPathTBAA(B) && "MDNode B is not struct-path aware.");
|
||||||
|
|
||||||
|
|
|
@ -391,6 +391,7 @@ private:
|
||||||
void visitBasicBlock(BasicBlock &BB);
|
void visitBasicBlock(BasicBlock &BB);
|
||||||
void visitRangeMetadata(Instruction& I, MDNode* Range, Type* Ty);
|
void visitRangeMetadata(Instruction& I, MDNode* Range, Type* Ty);
|
||||||
void visitDereferenceableMetadata(Instruction& I, MDNode* MD);
|
void visitDereferenceableMetadata(Instruction& I, MDNode* MD);
|
||||||
|
void visitTBAAMetadata(Instruction &I, MDNode *MD);
|
||||||
|
|
||||||
template <class Ty> bool isValidMetadataArray(const MDTuple &N);
|
template <class Ty> bool isValidMetadataArray(const MDTuple &N);
|
||||||
#define HANDLE_SPECIALIZED_MDNODE_LEAF(CLASS) void visit##CLASS(const CLASS &N);
|
#define HANDLE_SPECIALIZED_MDNODE_LEAF(CLASS) void visit##CLASS(const CLASS &N);
|
||||||
|
@ -3658,6 +3659,15 @@ void Verifier::visitDereferenceableMetadata(Instruction& I, MDNode* MD) {
|
||||||
"dereferenceable_or_null metadata value must be an i64!", &I);
|
"dereferenceable_or_null metadata value must be an i64!", &I);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Verifier::visitTBAAMetadata(Instruction &I, MDNode *MD) {
|
||||||
|
bool IsStructPathTBAA =
|
||||||
|
isa<MDNode>(MD->getOperand(0)) && MD->getNumOperands() >= 3;
|
||||||
|
|
||||||
|
Assert(IsStructPathTBAA,
|
||||||
|
"Old-style TBAA is no longer allowed, use struct-path TBAA instead",
|
||||||
|
&I);
|
||||||
|
}
|
||||||
|
|
||||||
/// verifyInstruction - Verify that an instruction is well formed.
|
/// verifyInstruction - Verify that an instruction is well formed.
|
||||||
///
|
///
|
||||||
void Verifier::visitInstruction(Instruction &I) {
|
void Verifier::visitInstruction(Instruction &I) {
|
||||||
|
@ -3793,6 +3803,9 @@ void Verifier::visitInstruction(Instruction &I) {
|
||||||
if (MDNode *MD = I.getMetadata(LLVMContext::MD_dereferenceable_or_null))
|
if (MDNode *MD = I.getMetadata(LLVMContext::MD_dereferenceable_or_null))
|
||||||
visitDereferenceableMetadata(I, MD);
|
visitDereferenceableMetadata(I, MD);
|
||||||
|
|
||||||
|
if (MDNode *MD = I.getMetadata(LLVMContext::MD_tbaa))
|
||||||
|
visitTBAAMetadata(I, MD);
|
||||||
|
|
||||||
if (MDNode *AlignMD = I.getMetadata(LLVMContext::MD_align)) {
|
if (MDNode *AlignMD = I.getMetadata(LLVMContext::MD_align)) {
|
||||||
Assert(I.getType()->isPointerTy(), "align applies only to pointer types",
|
Assert(I.getType()->isPointerTy(), "align applies only to pointer types",
|
||||||
&I);
|
&I);
|
||||||
|
|
|
@ -14,7 +14,7 @@ add_llvm_unittest(AnalysisTests
|
||||||
LazyCallGraphTest.cpp
|
LazyCallGraphTest.cpp
|
||||||
LoopPassManagerTest.cpp
|
LoopPassManagerTest.cpp
|
||||||
ScalarEvolutionTest.cpp
|
ScalarEvolutionTest.cpp
|
||||||
MixedTBAATest.cpp
|
TBAATest.cpp
|
||||||
ValueTrackingTest.cpp
|
ValueTrackingTest.cpp
|
||||||
UnrollAnalyzer.cpp
|
UnrollAnalyzer.cpp
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,79 +0,0 @@
|
||||||
//===--- MixedTBAATest.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/TypeBasedAliasAnalysis.h"
|
|
||||||
#include "llvm/Analysis/AliasAnalysisEvaluator.h"
|
|
||||||
#include "llvm/Analysis/Passes.h"
|
|
||||||
#include "llvm/IR/Constants.h"
|
|
||||||
#include "llvm/IR/Instructions.h"
|
|
||||||
#include "llvm/IR/LLVMContext.h"
|
|
||||||
#include "llvm/IR/MDBuilder.h"
|
|
||||||
#include "llvm/IR/Module.h"
|
|
||||||
#include "llvm/IR/LegacyPassManager.h"
|
|
||||||
#include "llvm/Support/CommandLine.h"
|
|
||||||
#include "gtest/gtest.h"
|
|
||||||
|
|
||||||
namespace llvm {
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
class MixedTBAATest : public testing::Test {
|
|
||||||
protected:
|
|
||||||
MixedTBAATest() : M("MixedTBAATest", C), MD(C) {}
|
|
||||||
|
|
||||||
LLVMContext C;
|
|
||||||
Module M;
|
|
||||||
MDBuilder MD;
|
|
||||||
legacy::PassManager PM;
|
|
||||||
};
|
|
||||||
|
|
||||||
TEST_F(MixedTBAATest, MixedTBAA) {
|
|
||||||
// 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 *Store2 = new StoreInst(Value, Addr, BB);
|
|
||||||
ReturnInst::Create(C, nullptr, BB);
|
|
||||||
|
|
||||||
// New TBAA metadata
|
|
||||||
{
|
|
||||||
auto RootMD = MD.createTBAARoot("Simple C/C++ TBAA");
|
|
||||||
auto MD1 = MD.createTBAAScalarTypeNode("omnipotent char", RootMD);
|
|
||||||
auto MD2 = MD.createTBAAScalarTypeNode("int", MD1);
|
|
||||||
auto MD3 = MD.createTBAAStructTagNode(MD2, MD2, 0);
|
|
||||||
Store2->setMetadata(LLVMContext::MD_tbaa, MD3);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Old TBAA metadata
|
|
||||||
{
|
|
||||||
auto RootMD = MD.createTBAARoot("Simple C/C++ TBAA");
|
|
||||||
auto MD1 = MD.createTBAANode("omnipotent char", RootMD);
|
|
||||||
auto MD2 = MD.createTBAANode("int", MD1);
|
|
||||||
Store1->setMetadata(LLVMContext::MD_tbaa, MD2);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run the TBAA eval pass on a mixture of path-aware and non-path-aware TBAA.
|
|
||||||
// The order of the metadata (path-aware vs non-path-aware) is important,
|
|
||||||
// because the AA eval pass only runs one test per store-pair.
|
|
||||||
const char* args[] = { "MixedTBAATest", "-evaluate-aa-metadata" };
|
|
||||||
cl::ParseCommandLineOptions(sizeof(args) / sizeof(const char*), args);
|
|
||||||
PM.add(createTypeBasedAAWrapperPass());
|
|
||||||
PM.add(createAAEvalPass());
|
|
||||||
PM.run(M);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // end anonymous namspace
|
|
||||||
} // end llvm namespace
|
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
//===--- TBAATest.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/AliasAnalysisEvaluator.h"
|
||||||
|
#include "llvm/Analysis/Passes.h"
|
||||||
|
#include "llvm/IR/Constants.h"
|
||||||
|
#include "llvm/IR/Instructions.h"
|
||||||
|
#include "llvm/IR/LLVMContext.h"
|
||||||
|
#include "llvm/IR/MDBuilder.h"
|
||||||
|
#include "llvm/IR/Module.h"
|
||||||
|
#include "llvm/IR/LegacyPassManager.h"
|
||||||
|
#include "llvm/IR/Verifier.h"
|
||||||
|
#include "llvm/Support/CommandLine.h"
|
||||||
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
|
namespace llvm {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
class OldTBAATest : public testing::Test {
|
||||||
|
protected:
|
||||||
|
OldTBAATest() : M("MixedTBAATest", C), MD(C) {}
|
||||||
|
|
||||||
|
LLVMContext C;
|
||||||
|
Module M;
|
||||||
|
MDBuilder MD;
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_F(OldTBAATest, checkVerifierBehavior) {
|
||||||
|
// C++ unit test case to avoid going through the auto upgrade logic.
|
||||||
|
|
||||||
|
FunctionType *FTy = FunctionType::get(Type::getVoidTy(C), {});
|
||||||
|
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 *SI = new StoreInst(ConstantInt::get(IntType, 42),
|
||||||
|
ConstantPointerNull::get(PtrType), BB);
|
||||||
|
ReturnInst::Create(C, nullptr, BB);
|
||||||
|
|
||||||
|
auto *RootMD = MD.createTBAARoot("Simple C/C++ TBAA");
|
||||||
|
auto *MD1 = MD.createTBAANode("omnipotent char", RootMD);
|
||||||
|
auto *MD2 = MD.createTBAANode("int", MD1);
|
||||||
|
SI->setMetadata(LLVMContext::MD_tbaa, MD2);
|
||||||
|
|
||||||
|
SmallVector<char, 0> ErrorMsg;
|
||||||
|
raw_svector_ostream Outs(ErrorMsg);
|
||||||
|
|
||||||
|
StringRef ExpectedFailureMsg(
|
||||||
|
"Old-style TBAA is no longer allowed, use struct-path TBAA instead");
|
||||||
|
|
||||||
|
EXPECT_TRUE(verifyFunction(*F, &Outs));
|
||||||
|
EXPECT_TRUE(StringRef(ErrorMsg.begin(), ErrorMsg.size())
|
||||||
|
.startswith(ExpectedFailureMsg));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end anonymous namspace
|
||||||
|
} // end llvm namespace
|
Loading…
Reference in New Issue