214 lines · cpp
1//===- MachineStableHashTest.cpp ------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "llvm/CodeGen/MachineStableHash.h"10#include "llvm/CodeGen/MIRParser/MIRParser.h"11#include "llvm/CodeGen/MachineFunction.h"12#include "llvm/CodeGen/MachineModuleInfo.h"13#include "llvm/FileCheck/FileCheck.h"14#include "llvm/IR/Module.h"15#include "llvm/MC/TargetRegistry.h"16#include "llvm/Support/SourceMgr.h"17#include "llvm/Support/TargetSelect.h"18#include "llvm/Target/TargetMachine.h"19#include "gtest/gtest.h"20 21using namespace llvm;22 23class MachineStableHashTest : public testing::Test {24public:25 MachineStableHashTest() = default;26 27protected:28 LLVMContext Context;29 std::unique_ptr<Module> M;30 std::unique_ptr<MIRParser> MIR;31 32 static void SetUpTestCase() {33 InitializeAllTargetInfos();34 InitializeAllTargets();35 InitializeAllTargetMCs();36 }37 38 void SetUp() override { M = std::make_unique<Module>("Dummy", Context); }39 40 std::unique_ptr<TargetMachine>41 createTargetMachine(std::string TStr, StringRef CPU, StringRef FS) {42 std::string Error;43 Triple TT(TStr);44 const Target *T = TargetRegistry::lookupTarget(TT, Error);45 if (!T)46 return nullptr;47 TargetOptions Options;48 return std::unique_ptr<TargetMachine>(T->createTargetMachine(49 TT, CPU, FS, Options, std::nullopt, std::nullopt));50 }51 52 std::unique_ptr<Module> parseMIR(const TargetMachine &TM, StringRef MIRCode,53 MachineModuleInfo &MMI) {54 SMDiagnostic Diagnostic;55 std::unique_ptr<MemoryBuffer> MBuffer = MemoryBuffer::getMemBuffer(MIRCode);56 MIR = createMIRParser(std::move(MBuffer), Context);57 if (!MIR)58 return nullptr;59 60 std::unique_ptr<Module> Mod = MIR->parseIRModule();61 if (!Mod)62 return nullptr;63 64 Mod->setDataLayout(TM.createDataLayout());65 66 if (MIR->parseMachineFunctions(*Mod, MMI)) {67 M.reset();68 return nullptr;69 }70 71 return Mod;72 }73};74 75TEST_F(MachineStableHashTest, StableGlobalName) {76 auto TM = createTargetMachine(("aarch64--"), "", "");77 if (!TM)78 GTEST_SKIP();79 StringRef MIRString = R"MIR(80--- |81 define void @f1() { ret void }82 define void @f2() { ret void }83 define void @f3() { ret void }84 define void @f4() { ret void }85 declare void @goo()86 declare void @goo.llvm.123()87 declare void @goo.__uniq.456()88 declare void @goo.invalid.789()89...90---91name: f192alignment: 1693tracksRegLiveness: true94frameInfo:95 maxAlignment: 1696machineFunctionInfo: {}97body: |98 bb.0:99 liveins: $lr100 BL @goo101 RET undef $lr102 103...104---105name: f2106body: |107 bb.0:108 liveins: $lr109 BL @goo.llvm.123110 RET undef $lr111...112---113name: f3114body: |115 bb.0:116 liveins: $lr117 BL @goo.__uniq.456118 RET undef $lr119...120---121name: f4122body: |123 bb.0:124 liveins: $lr125 BL @goo.invalid.789126 RET undef $lr127...128)MIR";129 MachineModuleInfo MMI(TM.get());130 M = parseMIR(*TM, MIRString, MMI);131 ASSERT_TRUE(M);132 auto *MF1 = MMI.getMachineFunction(*M->getFunction("f1"));133 auto *MF2 = MMI.getMachineFunction(*M->getFunction("f2"));134 auto *MF3 = MMI.getMachineFunction(*M->getFunction("f3"));135 auto *MF4 = MMI.getMachineFunction(*M->getFunction("f4"));136 137 EXPECT_EQ(stableHashValue(*MF1), stableHashValue(*MF2))138 << "Expect the suffix, `.llvm.{number}` to be ignored.";139 EXPECT_EQ(stableHashValue(*MF1), stableHashValue(*MF3))140 << "Expect the suffix, `.__uniq.{number}` to be ignored.";141 // Do not ignore `.invalid.{number}`.142 EXPECT_NE(stableHashValue(*MF1), stableHashValue(*MF4));143}144 145TEST_F(MachineStableHashTest, ContentName) {146 auto TM = createTargetMachine(("aarch64--"), "", "");147 if (!TM)148 GTEST_SKIP();149 StringRef MIRString = R"MIR(150--- |151 define void @f1() { ret void }152 define void @f2() { ret void }153 define void @f3() { ret void }154 define void @f4() { ret void }155 declare void @goo()156 declare void @goo.content.123()157 declare void @zoo.content.123()158 declare void @goo.content.456()159...160---161name: f1162alignment: 16163tracksRegLiveness: true164frameInfo:165 maxAlignment: 16166machineFunctionInfo: {}167body: |168 bb.0:169 liveins: $lr170 BL @goo171 RET undef $lr172...173---174name: f2175body: |176 bb.0:177 liveins: $lr178 BL @goo.content.123179 RET undef $lr180...181---182name: f3183body: |184 bb.0:185 liveins: $lr186 BL @zoo.content.123187 RET undef $lr188...189---190name: f4191body: |192 bb.0:193 liveins: $lr194 BL @goo.content.456195 RET undef $lr196...197)MIR";198 MachineModuleInfo MMI(TM.get());199 M = parseMIR(*TM, MIRString, MMI);200 ASSERT_TRUE(M);201 auto *MF1 = MMI.getMachineFunction(*M->getFunction("f1"));202 auto *MF2 = MMI.getMachineFunction(*M->getFunction("f2"));203 auto *MF3 = MMI.getMachineFunction(*M->getFunction("f3"));204 auto *MF4 = MMI.getMachineFunction(*M->getFunction("f4"));205 206 // Do not ignore `.content.{number}`.207 EXPECT_NE(stableHashValue(*MF1), stableHashValue(*MF2));208 EXPECT_EQ(stableHashValue(*MF2), stableHashValue(*MF3))209 << "Expect the same hash for the same suffix, `.content.{number}`";210 // Different suffixes should result in different hashes.211 EXPECT_NE(stableHashValue(*MF2), stableHashValue(*MF4));212 EXPECT_NE(stableHashValue(*MF3), stableHashValue(*MF4));213}214