
This avoids doing a Triple -> std::string -> Triple round trip in lots of places, now that the Module stores a Triple.
214 lines
5.4 KiB
C++
214 lines
5.4 KiB
C++
//===- MachineStableHashTest.cpp ------------------------------------------===//
|
|
//
|
|
// 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/MachineStableHash.h"
|
|
#include "llvm/CodeGen/MIRParser/MIRParser.h"
|
|
#include "llvm/CodeGen/MachineFunction.h"
|
|
#include "llvm/CodeGen/MachineModuleInfo.h"
|
|
#include "llvm/FileCheck/FileCheck.h"
|
|
#include "llvm/IR/Module.h"
|
|
#include "llvm/MC/TargetRegistry.h"
|
|
#include "llvm/Support/SourceMgr.h"
|
|
#include "llvm/Support/TargetSelect.h"
|
|
#include "llvm/Target/TargetMachine.h"
|
|
#include "gtest/gtest.h"
|
|
|
|
using namespace llvm;
|
|
|
|
class MachineStableHashTest : public testing::Test {
|
|
public:
|
|
MachineStableHashTest() {}
|
|
|
|
protected:
|
|
LLVMContext Context;
|
|
std::unique_ptr<Module> M;
|
|
std::unique_ptr<MIRParser> MIR;
|
|
|
|
static void SetUpTestCase() {
|
|
InitializeAllTargetInfos();
|
|
InitializeAllTargets();
|
|
InitializeAllTargetMCs();
|
|
}
|
|
|
|
void SetUp() override { M = std::make_unique<Module>("Dummy", Context); }
|
|
|
|
std::unique_ptr<TargetMachine>
|
|
createTargetMachine(std::string TStr, StringRef CPU, StringRef FS) {
|
|
std::string Error;
|
|
Triple TT(TStr);
|
|
const Target *T = TargetRegistry::lookupTarget(TT, Error);
|
|
if (!T)
|
|
return nullptr;
|
|
TargetOptions Options;
|
|
return std::unique_ptr<TargetMachine>(T->createTargetMachine(
|
|
TT, CPU, FS, Options, std::nullopt, std::nullopt));
|
|
}
|
|
|
|
std::unique_ptr<Module> parseMIR(const TargetMachine &TM, StringRef MIRCode,
|
|
MachineModuleInfo &MMI) {
|
|
SMDiagnostic Diagnostic;
|
|
std::unique_ptr<MemoryBuffer> MBuffer = MemoryBuffer::getMemBuffer(MIRCode);
|
|
MIR = createMIRParser(std::move(MBuffer), Context);
|
|
if (!MIR)
|
|
return nullptr;
|
|
|
|
std::unique_ptr<Module> Mod = MIR->parseIRModule();
|
|
if (!Mod)
|
|
return nullptr;
|
|
|
|
Mod->setDataLayout(TM.createDataLayout());
|
|
|
|
if (MIR->parseMachineFunctions(*Mod, MMI)) {
|
|
M.reset();
|
|
return nullptr;
|
|
}
|
|
|
|
return Mod;
|
|
}
|
|
};
|
|
|
|
TEST_F(MachineStableHashTest, StableGlobalName) {
|
|
auto TM = createTargetMachine(("aarch64--"), "", "");
|
|
if (!TM)
|
|
GTEST_SKIP();
|
|
StringRef MIRString = R"MIR(
|
|
--- |
|
|
define void @f1() { ret void }
|
|
define void @f2() { ret void }
|
|
define void @f3() { ret void }
|
|
define void @f4() { ret void }
|
|
declare void @goo()
|
|
declare void @goo.llvm.123()
|
|
declare void @goo.__uniq.456()
|
|
declare void @goo.invalid.789()
|
|
...
|
|
---
|
|
name: f1
|
|
alignment: 16
|
|
tracksRegLiveness: true
|
|
frameInfo:
|
|
maxAlignment: 16
|
|
machineFunctionInfo: {}
|
|
body: |
|
|
bb.0:
|
|
liveins: $lr
|
|
BL @goo
|
|
RET undef $lr
|
|
|
|
...
|
|
---
|
|
name: f2
|
|
body: |
|
|
bb.0:
|
|
liveins: $lr
|
|
BL @goo.llvm.123
|
|
RET undef $lr
|
|
...
|
|
---
|
|
name: f3
|
|
body: |
|
|
bb.0:
|
|
liveins: $lr
|
|
BL @goo.__uniq.456
|
|
RET undef $lr
|
|
...
|
|
---
|
|
name: f4
|
|
body: |
|
|
bb.0:
|
|
liveins: $lr
|
|
BL @goo.invalid.789
|
|
RET undef $lr
|
|
...
|
|
)MIR";
|
|
MachineModuleInfo MMI(TM.get());
|
|
M = parseMIR(*TM, MIRString, MMI);
|
|
ASSERT_TRUE(M);
|
|
auto *MF1 = MMI.getMachineFunction(*M->getFunction("f1"));
|
|
auto *MF2 = MMI.getMachineFunction(*M->getFunction("f2"));
|
|
auto *MF3 = MMI.getMachineFunction(*M->getFunction("f3"));
|
|
auto *MF4 = MMI.getMachineFunction(*M->getFunction("f4"));
|
|
|
|
EXPECT_EQ(stableHashValue(*MF1), stableHashValue(*MF2))
|
|
<< "Expect the suffix, `.llvm.{number}` to be ignored.";
|
|
EXPECT_EQ(stableHashValue(*MF1), stableHashValue(*MF3))
|
|
<< "Expect the suffix, `.__uniq.{number}` to be ignored.";
|
|
// Do not ignore `.invalid.{number}`.
|
|
EXPECT_NE(stableHashValue(*MF1), stableHashValue(*MF4));
|
|
}
|
|
|
|
TEST_F(MachineStableHashTest, ContentName) {
|
|
auto TM = createTargetMachine(("aarch64--"), "", "");
|
|
if (!TM)
|
|
GTEST_SKIP();
|
|
StringRef MIRString = R"MIR(
|
|
--- |
|
|
define void @f1() { ret void }
|
|
define void @f2() { ret void }
|
|
define void @f3() { ret void }
|
|
define void @f4() { ret void }
|
|
declare void @goo()
|
|
declare void @goo.content.123()
|
|
declare void @zoo.content.123()
|
|
declare void @goo.content.456()
|
|
...
|
|
---
|
|
name: f1
|
|
alignment: 16
|
|
tracksRegLiveness: true
|
|
frameInfo:
|
|
maxAlignment: 16
|
|
machineFunctionInfo: {}
|
|
body: |
|
|
bb.0:
|
|
liveins: $lr
|
|
BL @goo
|
|
RET undef $lr
|
|
...
|
|
---
|
|
name: f2
|
|
body: |
|
|
bb.0:
|
|
liveins: $lr
|
|
BL @goo.content.123
|
|
RET undef $lr
|
|
...
|
|
---
|
|
name: f3
|
|
body: |
|
|
bb.0:
|
|
liveins: $lr
|
|
BL @zoo.content.123
|
|
RET undef $lr
|
|
...
|
|
---
|
|
name: f4
|
|
body: |
|
|
bb.0:
|
|
liveins: $lr
|
|
BL @goo.content.456
|
|
RET undef $lr
|
|
...
|
|
)MIR";
|
|
MachineModuleInfo MMI(TM.get());
|
|
M = parseMIR(*TM, MIRString, MMI);
|
|
ASSERT_TRUE(M);
|
|
auto *MF1 = MMI.getMachineFunction(*M->getFunction("f1"));
|
|
auto *MF2 = MMI.getMachineFunction(*M->getFunction("f2"));
|
|
auto *MF3 = MMI.getMachineFunction(*M->getFunction("f3"));
|
|
auto *MF4 = MMI.getMachineFunction(*M->getFunction("f4"));
|
|
|
|
// Do not ignore `.content.{number}`.
|
|
EXPECT_NE(stableHashValue(*MF1), stableHashValue(*MF2));
|
|
EXPECT_EQ(stableHashValue(*MF2), stableHashValue(*MF3))
|
|
<< "Expect the same hash for the same suffix, `.content.{number}`";
|
|
// Different suffixes should result in different hashes.
|
|
EXPECT_NE(stableHashValue(*MF2), stableHashValue(*MF4));
|
|
EXPECT_NE(stableHashValue(*MF3), stableHashValue(*MF4));
|
|
}
|