[docs] Fix build-docs.sh
[llvm-project.git] / llvm / unittests / CodeGen / MLRegallocDevelopmentFeatures.cpp
blob022cfab94c8957f08db218fab22edf345201989e
1 //===- MLRegAllocDevelopmentFeatures.cpp - test dev MLRegalloc features ---===//
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-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #include "../../lib/CodeGen/MLRegallocEvictAdvisor.h"
10 #include "llvm/Analysis/NoInferenceModelRunner.h"
11 #include "llvm/CodeGen/SlotIndexes.h"
12 #include "llvm/IR/LLVMContext.h"
13 #include "llvm/Support/Allocator.h"
14 #include "llvm/Support/CodeGen.h"
15 #include "gmock/gmock.h"
16 #include "gtest/gtest.h"
18 #include <vector>
20 using testing::ContainerEq;
21 using testing::Test;
23 struct LRPosInfoIndexes {
24 size_t StartIndex;
25 size_t EndIndex;
26 size_t PhysReg;
29 class RegallocDevelopmentFeaturesTest : public ::Test {
30 protected:
31 SmallVector<LRStartEndInfo>
32 setupOverlapProblem(const SmallVectorImpl<LRPosInfoIndexes> &Segments,
33 ilist<IndexListEntry> &IndexList) {
34 SmallVector<LRStartEndInfo> PositionsToReturn;
35 PositionsToReturn.reserve(Segments.size());
36 for (auto CurrentPosIndexInfo : Segments) {
37 LRStartEndInfo CurrentPosInfo = {};
38 CurrentPosInfo.Pos = CurrentPosIndexInfo.PhysReg;
39 PositionsToReturn.push_back(CurrentPosInfo);
41 size_t CurrentSegmentIndex = 0;
42 size_t CurrentIndex = 0;
43 while (CurrentSegmentIndex < Segments.size()) {
44 auto *CurrentLEMem = static_cast<IndexListEntry *>(
45 Allocator.Allocate(sizeof(IndexListEntry), alignof(IndexListEntry)));
46 auto *CurrentListEntry =
47 new (CurrentLEMem) IndexListEntry(nullptr, CurrentIndex);
48 IndexList.push_back(CurrentListEntry);
49 for (size_t CurrentPosInfoIndex = 0;
50 CurrentPosInfoIndex < Segments.size(); ++CurrentPosInfoIndex) {
51 if ((CurrentIndex / SlotIndex::InstrDist) ==
52 Segments[CurrentPosInfoIndex].StartIndex) {
53 PositionsToReturn[CurrentPosInfoIndex].Begin =
54 SlotIndex(CurrentListEntry, 0);
55 } else if ((CurrentIndex / SlotIndex::InstrDist) ==
56 Segments[CurrentPosInfoIndex].EndIndex) {
57 PositionsToReturn[CurrentPosInfoIndex].End =
58 SlotIndex(CurrentListEntry, 0);
59 ++CurrentSegmentIndex;
62 CurrentIndex += SlotIndex::InstrDist;
64 return PositionsToReturn;
67 NoInferenceModelRunner setupModelRunner() {
68 const std::vector<TensorSpec> Inputs{
69 TensorSpec::createSpec<int64_t>("instructions", InstructionsShape),
70 TensorSpec::createSpec<int64_t>("instructions_mapping",
71 InstructionsMappingShape)};
72 LLVMContext Ctx;
73 return NoInferenceModelRunner(Ctx, Inputs);
76 std::vector<int64_t>
77 getExpectedMappingMatrix(SmallVectorImpl<LRPosInfoIndexes> &OverlapSetup) {
78 std::vector<int64_t> ExpectedMappingMatrix(
79 NumberOfInterferences * ModelMaxSupportedInstructionCount, 0);
80 for (auto NewSegment : OverlapSetup) {
81 for (size_t CurrentIndex = NewSegment.StartIndex;
82 CurrentIndex <= NewSegment.EndIndex; ++CurrentIndex) {
83 ExpectedMappingMatrix[NewSegment.PhysReg *
84 ModelMaxSupportedInstructionCount +
85 CurrentIndex] = 1;
88 return ExpectedMappingMatrix;
91 void runOverlapTest(SmallVectorImpl<LRPosInfoIndexes> &OverlapSetup) {
92 ilist<IndexListEntry> IndexList;
93 auto OverlapProblem = setupOverlapProblem(OverlapSetup, IndexList);
94 NoInferenceModelRunner ModelRunner = setupModelRunner();
95 size_t MaxIndex = 0;
96 for (size_t CurrentOverlap = 0; CurrentOverlap < OverlapSetup.size();
97 ++CurrentOverlap) {
98 if (OverlapSetup[CurrentOverlap].EndIndex >
99 OverlapSetup[MaxIndex].EndIndex) {
100 MaxIndex = CurrentOverlap;
103 SlotIndex LastIndex = OverlapProblem[MaxIndex].End;
104 extractInstructionFeatures(
105 OverlapProblem, &ModelRunner,
106 [](SlotIndex InputSlot) -> int { return 0; }, 0, 1, LastIndex);
107 std::vector<int64_t> MappingMatrix(
108 ModelRunner.getTensor<int64_t>(1),
109 ModelRunner.getTensor<int64_t>(1) +
110 NumberOfInterferences * ModelMaxSupportedInstructionCount);
111 ASSERT_THAT(MappingMatrix,
112 ContainerEq(getExpectedMappingMatrix(OverlapSetup)));
113 IndexList.clearAndLeakNodesUnsafely();
116 BumpPtrAllocator Allocator;
119 // meta tests to ensure that test setup works correctly
121 TEST_F(RegallocDevelopmentFeaturesTest,
122 MetaOverlapInstructionDistancesAreCorrect) {
123 SmallVector<LRPosInfoIndexes, 2> OverlapSetup;
124 OverlapSetup.push_back({0, 5, 0});
125 OverlapSetup.push_back({5, 10, 0});
126 ilist<IndexListEntry> IndexList;
127 auto OverlapProblem = setupOverlapProblem(OverlapSetup, IndexList);
128 ASSERT_EQ(OverlapProblem[0].End.distance(OverlapProblem[1].End),
129 5 * SlotIndex::InstrDist);
130 ASSERT_EQ(OverlapProblem[0].End.distance(OverlapProblem[1].Begin), 0);
133 TEST_F(RegallocDevelopmentFeaturesTest, MetaSlotIndicesAreValid) {
134 SmallVector<LRPosInfoIndexes, 1> OverlapSetup;
135 OverlapSetup.push_back({0, 10, 0});
136 ilist<IndexListEntry> IndexList;
137 auto OverlapProblem = setupOverlapProblem(OverlapSetup, IndexList);
138 ASSERT_TRUE(OverlapProblem[0].Begin.isValid());
139 ASSERT_TRUE(OverlapProblem[0].End.isValid());
142 // Testing of feature extraction for per-instruction features
144 TEST_F(RegallocDevelopmentFeaturesTest, InstructionOpcodesAreCorrect) {
145 SmallVector<LRPosInfoIndexes, 1> OverlapSetup;
146 OverlapSetup.push_back({0, ModelMaxSupportedInstructionCount - 1, 0});
147 ilist<IndexListEntry> IndexList;
148 auto OverlapProblem = setupOverlapProblem(OverlapSetup, IndexList);
149 NoInferenceModelRunner ModelRunner = setupModelRunner();
150 SlotIndex LastIndex = OverlapProblem[0].End;
151 SlotIndex FirstIndex = OverlapProblem[0].Begin;
152 extractInstructionFeatures(
153 OverlapProblem, &ModelRunner,
154 [FirstIndex](SlotIndex InputSlot) -> int {
155 return FirstIndex.distance(InputSlot) / SlotIndex::InstrDist;
157 0, 1, LastIndex);
158 for (size_t CurrentInstructionIndex = 0;
159 CurrentInstructionIndex < ModelMaxSupportedInstructionCount;
160 ++CurrentInstructionIndex) {
161 ASSERT_EQ(
162 (size_t)ModelRunner.getTensor<int64_t>(0)[CurrentInstructionIndex],
163 CurrentInstructionIndex);
167 TEST_F(RegallocDevelopmentFeaturesTest, FullOverlap) {
168 SmallVector<LRPosInfoIndexes, 2> OverlapSetup;
169 OverlapSetup.push_back({0, ModelMaxSupportedInstructionCount - 1, 0});
170 OverlapSetup.push_back({0, ModelMaxSupportedInstructionCount - 1, 1});
171 runOverlapTest(OverlapSetup);
174 TEST_F(RegallocDevelopmentFeaturesTest, PartialOverlap) {
175 SmallVector<LRPosInfoIndexes, 2> OverlapSetup;
176 OverlapSetup.push_back({0, 20, 0});
177 OverlapSetup.push_back({15, 30, 1});
178 runOverlapTest(OverlapSetup);
181 TEST_F(RegallocDevelopmentFeaturesTest, PartialOverlapOpposite) {
182 SmallVector<LRPosInfoIndexes, 2> OverlapSetup;
183 OverlapSetup.push_back({15, 30, 1});
184 OverlapSetup.push_back({0, 20, 0});
185 runOverlapTest(OverlapSetup);
188 TEST_F(RegallocDevelopmentFeaturesTest, InternalOverlap) {
189 SmallVector<LRPosInfoIndexes, 2> OverlapSetup;
190 OverlapSetup.push_back({0, 30, 0});
191 OverlapSetup.push_back({10, 20, 1});
192 runOverlapTest(OverlapSetup);
195 TEST_F(RegallocDevelopmentFeaturesTest, TripleInternalOverlap) {
196 SmallVector<LRPosInfoIndexes, 3> OverlapSetup;
197 OverlapSetup.push_back({0, 30, 0});
198 OverlapSetup.push_back({10, 25, 1});
199 OverlapSetup.push_back({15, 20, 2});
200 runOverlapTest(OverlapSetup);
203 TEST_F(RegallocDevelopmentFeaturesTest, InternalMultiOverlap) {
204 SmallVector<LRPosInfoIndexes, 3> OverlapSetup;
205 OverlapSetup.push_back({0, 45, 0});
206 OverlapSetup.push_back({30, 40, 1});
207 OverlapSetup.push_back({35, 60, 2});
208 runOverlapTest(OverlapSetup);