Skip to content

Commit

Permalink
Introduce SpecialCaseList::isIn overload for GlobalAliases.
Browse files Browse the repository at this point in the history
Differential Revision: http://llvm-reviews.chandlerc.com/D1437

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@188688 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
pcc committed Aug 19, 2013
1 parent 756e89c commit 2b762cc
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 2 deletions.
9 changes: 9 additions & 0 deletions include/llvm/Transforms/Utils/SpecialCaseList.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@

namespace llvm {
class Function;
class GlobalAlias;
class GlobalVariable;
class MemoryBuffer;
class Module;
Expand Down Expand Up @@ -79,6 +80,14 @@ class SpecialCaseList {
bool isIn(const GlobalVariable &G,
const StringRef Category = StringRef()) const;

/// Returns whether this global alias is listed in the given category, which
/// may be omitted to search the empty category.
///
/// If GA aliases a function, the alias's name is matched as a function name
/// would be. Similarly, aliases of globals are matched like globals.
bool isIn(const GlobalAlias &GA,
const StringRef Category = StringRef()) const;

/// Returns whether this module is listed in the given category, which may be
/// omitted to search the empty category.
bool isIn(const Module &M, const StringRef Category = StringRef()) const;
Expand Down
16 changes: 14 additions & 2 deletions lib/Transforms/Utils/SpecialCaseList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ bool SpecialCaseList::isIn(const Function& F, const StringRef Category) const {
inSectionCategory("fun", F.getName(), Category);
}

static StringRef GetGVTypeString(const GlobalVariable &G) {
static StringRef GetGlobalTypeString(const GlobalValue &G) {
// Types of GlobalVariables are always pointer types.
Type *GType = G.getType()->getElementType();
// For now we support blacklisting struct types only.
Expand All @@ -189,7 +189,19 @@ bool SpecialCaseList::isIn(const GlobalVariable &G,
const StringRef Category) const {
return isIn(*G.getParent(), Category) ||
inSectionCategory("global", G.getName(), Category) ||
inSectionCategory("type", GetGVTypeString(G), Category);
inSectionCategory("type", GetGlobalTypeString(G), Category);
}

bool SpecialCaseList::isIn(const GlobalAlias &GA,
const StringRef Category) const {
if (isIn(*GA.getParent(), Category))
return true;

if (isa<FunctionType>(GA.getType()->getElementType()))
return inSectionCategory("fun", GA.getName(), Category);

return inSectionCategory("global", GA.getName(), Category) ||
inSectionCategory("type", GetGlobalTypeString(GA), Category);
}

bool SpecialCaseList::isIn(const Module &M, const StringRef Category) const {
Expand Down
46 changes: 46 additions & 0 deletions unittests/Transforms/Utils/SpecialCaseList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ class SpecialCaseListTest : public ::testing::Test {
M, ST, false, GlobalValue::ExternalLinkage, 0, Name);
}

GlobalAlias *makeAlias(StringRef Name, GlobalValue *Aliasee) {
return new GlobalAlias(Aliasee->getType(), GlobalValue::ExternalLinkage,
Name, Aliasee, Aliasee->getParent());
}

SpecialCaseList *makeSpecialCaseList(StringRef List, std::string &Error) {
OwningPtr<MemoryBuffer> MB(MemoryBuffer::getMemBuffer(List));
return SpecialCaseList::create(MB.get(), Error);
Expand Down Expand Up @@ -145,20 +150,61 @@ TEST_F(SpecialCaseListTest, GlobalIsIn) {
EXPECT_TRUE(SCL->isIn(*Bar, "init"));
}

TEST_F(SpecialCaseListTest, AliasIsIn) {
Module M("hello", Ctx);
Function *Foo = makeFunction("foo", M);
GlobalVariable *Bar = makeGlobal("bar", "t", M);
GlobalAlias *FooAlias = makeAlias("fooalias", Foo);
GlobalAlias *BarAlias = makeAlias("baralias", Bar);

OwningPtr<SpecialCaseList> SCL(makeSpecialCaseList("fun:foo\n"));
EXPECT_FALSE(SCL->isIn(*FooAlias));
EXPECT_FALSE(SCL->isIn(*BarAlias));

SCL.reset(makeSpecialCaseList("global:bar\n"));
EXPECT_FALSE(SCL->isIn(*FooAlias));
EXPECT_FALSE(SCL->isIn(*BarAlias));

SCL.reset(makeSpecialCaseList("global:fooalias\n"));
EXPECT_FALSE(SCL->isIn(*FooAlias));
EXPECT_FALSE(SCL->isIn(*BarAlias));

SCL.reset(makeSpecialCaseList("fun:fooalias\n"));
EXPECT_TRUE(SCL->isIn(*FooAlias));
EXPECT_FALSE(SCL->isIn(*BarAlias));

SCL.reset(makeSpecialCaseList("global:baralias=init\n"));
EXPECT_FALSE(SCL->isIn(*FooAlias, "init"));
EXPECT_TRUE(SCL->isIn(*BarAlias, "init"));

SCL.reset(makeSpecialCaseList("type:t=init\n"));
EXPECT_FALSE(SCL->isIn(*FooAlias, "init"));
EXPECT_TRUE(SCL->isIn(*BarAlias, "init"));

SCL.reset(makeSpecialCaseList("fun:baralias=init\n"));
EXPECT_FALSE(SCL->isIn(*FooAlias, "init"));
EXPECT_FALSE(SCL->isIn(*BarAlias, "init"));
}

TEST_F(SpecialCaseListTest, Substring) {
Module M("othello", Ctx);
Function *F = makeFunction("tomfoolery", M);
GlobalVariable *GV = makeGlobal("bartender", "t", M);
GlobalAlias *GA1 = makeAlias("buffoonery", F);
GlobalAlias *GA2 = makeAlias("foobar", GV);

OwningPtr<SpecialCaseList> SCL(makeSpecialCaseList("src:hello\n"
"fun:foo\n"
"global:bar\n"));
EXPECT_FALSE(SCL->isIn(M));
EXPECT_FALSE(SCL->isIn(*F));
EXPECT_FALSE(SCL->isIn(*GV));
EXPECT_FALSE(SCL->isIn(*GA1));
EXPECT_FALSE(SCL->isIn(*GA2));

SCL.reset(makeSpecialCaseList("fun:*foo*\n"));
EXPECT_TRUE(SCL->isIn(*F));
EXPECT_TRUE(SCL->isIn(*GA1));
}

TEST_F(SpecialCaseListTest, InvalidSpecialCaseList) {
Expand Down

0 comments on commit 2b762cc

Please sign in to comment.