blob: e2ed275f2f7731897b0a16852e332a36f4d928e8 [file] [edit]
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
#include "llvm/CodeGen/AccelTable.h"
#include "TestAsmPrinter.h"
#include "llvm/CodeGen/DwarfStringPoolEntry.h"
#include "llvm/Testing/Support/Error.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
using namespace llvm;
namespace {
class AccelTableTest : public testing::Test {
protected:
void SetUp() override {
auto ExpectedTestPrinter = TestAsmPrinter::create(
"x86_64-pc-linux", /*DwarfVersion=*/5, dwarf::DWARF32);
ASSERT_THAT_EXPECTED(ExpectedTestPrinter, Succeeded());
TestPrinter = std::move(*ExpectedTestPrinter);
if (!TestPrinter)
GTEST_SKIP();
}
/// Builds a table holding \p Names and returns each bucket's contents in the
/// order they would be emitted in.
std::vector<std::vector<StringRef>>
bucketOrder(ArrayRef<const DwarfStringPoolEntryWithExtString *> Names) {
DWARF5AccelTable Table;
for (const DwarfStringPoolEntryWithExtString *Name : Names)
Table.addName(DwarfStringPoolEntryRef(*Name), /*DieOffset=*/0x11,
/*DefiningParentOffset=*/std::nullopt,
/*DieTag=*/dwarf::DW_TAG_variable, /*UnitID=*/0,
/*IsTU=*/false);
Table.finalize(TestPrinter->getAP(), "names");
std::vector<std::vector<StringRef>> Order;
for (const AccelTableBase::HashList &Bucket : Table.getBuckets()) {
Order.emplace_back();
for (const AccelTableBase::HashData *Hash : Bucket)
Order.back().push_back(Hash->Name.getString());
}
return Order;
}
std::unique_ptr<TestAsmPrinter> TestPrinter;
};
TEST_F(AccelTableTest, CollidingNamesOrderedIndependentlyOfInsertion) {
// The DWARF v5 hash folds case, so these three names always collide.
DwarfStringPoolEntryWithExtString Lower = {{}, "fixups"};
DwarfStringPoolEntryWithExtString Mixed = {{}, "Fixups"};
DwarfStringPoolEntryWithExtString Upper = {{}, "FIXUPS"};
DwarfStringPoolEntryWithExtString Other = {{}, "gamma"};
const uint32_t Hash = DWARF5AccelTableData::hash(Lower.String);
ASSERT_EQ(Hash, DWARF5AccelTableData::hash(Mixed.String));
ASSERT_EQ(Hash, DWARF5AccelTableData::hash(Upper.String));
ASSERT_LT(DWARF5AccelTableData::hash(Other.String), Hash);
const std::vector<std::vector<StringRef>> Order =
bucketOrder({&Lower, &Mixed, &Upper, &Other});
EXPECT_EQ(bucketOrder({&Other, &Upper, &Mixed, &Lower}), Order);
EXPECT_EQ(bucketOrder({&Mixed, &Other, &Lower, &Upper}), Order);
// The hash value orders before the name, so "gamma" comes first even though
// it sorts after the names it shares a bucket with.
EXPECT_THAT(Order, testing::Contains(testing::ElementsAre(
"gamma", "FIXUPS", "Fixups", "fixups")));
}
} // end namespace