349 lines · cpp
1//===- unittest/Support/BitstreamRemarksSerializerTest.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/Bitcode/BitcodeAnalyzer.h"10#include "llvm/Remarks/Remark.h"11#include "llvm/Remarks/RemarkSerializer.h"12#include "llvm/Support/raw_ostream.h"13#include "gtest/gtest.h"14#include <optional>15#include <string>16 17// We need to supprt Windows paths as well. In order to have paths with the same18// length, use a different path according to the platform.19#ifdef _WIN3220#define EXTERNALFILETESTPATH "C:/externalfi"21#else22#define EXTERNALFILETESTPATH "/externalfile"23#endif24 25using namespace llvm;26 27static void checkAnalyze(StringRef Input, StringRef Expected) {28 std::string OutputBuf;29 raw_string_ostream OutputOS(OutputBuf);30 BCDumpOptions O(OutputOS);31 O.ShowBinaryBlobs = true;32 BitcodeAnalyzer BA(Input);33 EXPECT_FALSE(BA.analyze(O)); // Expect no errors.34 EXPECT_EQ(OutputOS.str(), Expected);35}36 37static void check(const remarks::Remark &R, StringRef ExpectedR,38 std::optional<StringRef> ExpectedMeta = std::nullopt,39 std::optional<remarks::StringTable> StrTab = std::nullopt) {40 // Emit the remark.41 std::string InputBuf;42 raw_string_ostream InputOS(InputBuf);43 Expected<std::unique_ptr<remarks::RemarkSerializer>> MaybeSerializer = [&] {44 if (StrTab)45 return createRemarkSerializer(remarks::Format::Bitstream, InputOS,46 std::move(*StrTab));47 else48 return createRemarkSerializer(remarks::Format::Bitstream, InputOS);49 }();50 EXPECT_FALSE(errorToBool(MaybeSerializer.takeError()));51 std::unique_ptr<remarks::RemarkSerializer> Serializer =52 std::move(*MaybeSerializer);53 Serializer->emit(R);54 Serializer->finalize();55 56 // Analyze the serialized remark.57 checkAnalyze(InputOS.str(), ExpectedR);58 59 // Analyze the serialized metadata if it's not in standalone mode.60 if (ExpectedMeta) {61 std::string MetaBuf;62 raw_string_ostream MetaOS(MetaBuf);63 std::unique_ptr<remarks::MetaSerializer> MetaSerializer =64 Serializer->metaSerializer(MetaOS, StringRef(EXTERNALFILETESTPATH));65 MetaSerializer->emit();66 checkAnalyze(MetaOS.str(), *ExpectedMeta);67 }68}69 70TEST(BitstreamRemarkSerializer, SeparateRemarkFileNoOptionals) {71 remarks::Remark R;72 R.RemarkType = remarks::Type::Missed;73 R.PassName = "pass";74 R.RemarkName = "remark";75 R.FunctionName = "function";76 check(R,77 "<BLOCKINFO_BLOCK/>\n"78 "<Meta BlockID=8 NumWords=3 BlockCodeSize=3>\n"79 " <Container info codeid=1 abbrevid=4 op0=1 op1=1/>\n"80 " <Remark version codeid=2 abbrevid=5 op0=0/>\n"81 "</Meta>\n"82 "<Remark BlockID=9 NumWords=1 BlockCodeSize=4>\n"83 " <Remark header codeid=5 abbrevid=4 op0=2 op1=0 op2=1 op3=2/>\n"84 "</Remark>\n"85 "<Meta BlockID=8 NumWords=8 BlockCodeSize=3>\n"86 " <String table codeid=3 abbrevid=6/> blob data = "87 "'remark\\x00pass\\x00function\\x00'\n"88 "</Meta>\n",89 "<BLOCKINFO_BLOCK/>\n"90 "<Meta BlockID=8 NumWords=7 BlockCodeSize=3>\n"91 " <Container info codeid=1 abbrevid=4 op0=1 op1=0/>\n"92 " <External File codeid=4 abbrevid=5/> blob data = "93 "'" EXTERNALFILETESTPATH "'\n"94 "</Meta>\n");95}96 97TEST(BitstreamRemarkSerializer, SeparateRemarkFileNoOptionalsSeparateStrTab) {98 remarks::StringTable StrTab;99 StrTab.add("function");100 StrTab.add("pass");101 StrTab.add("remark");102 remarks::Remark R;103 R.RemarkType = remarks::Type::Missed;104 R.PassName = "pass";105 R.RemarkName = "remark";106 R.FunctionName = "function";107 check(R,108 "<BLOCKINFO_BLOCK/>\n"109 "<Meta BlockID=8 NumWords=3 BlockCodeSize=3>\n"110 " <Container info codeid=1 abbrevid=4 op0=1 op1=1/>\n"111 " <Remark version codeid=2 abbrevid=5 op0=0/>\n"112 "</Meta>\n"113 "<Remark BlockID=9 NumWords=1 BlockCodeSize=4>\n"114 " <Remark header codeid=5 abbrevid=4 op0=2 op1=2 op2=1 op3=0/>\n"115 "</Remark>\n"116 "<Meta BlockID=8 NumWords=8 BlockCodeSize=3>\n"117 " <String table codeid=3 abbrevid=6/> blob data = "118 "'function\\x00pass\\x00remark\\x00'\n"119 "</Meta>\n",120 "<BLOCKINFO_BLOCK/>\n"121 "<Meta BlockID=8 NumWords=7 BlockCodeSize=3>\n"122 " <Container info codeid=1 abbrevid=4 op0=1 op1=0/>\n"123 " <External File codeid=4 abbrevid=5/> blob data = "124 "'" EXTERNALFILETESTPATH "'\n"125 "</Meta>\n",126 std::move(StrTab));127}128 129TEST(BitstreamRemarkSerializer, SeparateRemarkFileDebugLoc) {130 remarks::Remark R;131 R.RemarkType = remarks::Type::Missed;132 R.PassName = "pass";133 R.RemarkName = "remark";134 R.FunctionName = "function";135 R.Loc.emplace();136 R.Loc->SourceFilePath = "path";137 R.Loc->SourceLine = 99;138 R.Loc->SourceColumn = 55;139 check(R,140 "<BLOCKINFO_BLOCK/>\n"141 "<Meta BlockID=8 NumWords=3 BlockCodeSize=3>\n"142 " <Container info codeid=1 abbrevid=4 op0=1 op1=1/>\n"143 " <Remark version codeid=2 abbrevid=5 op0=0/>\n"144 "</Meta>\n"145 "<Remark BlockID=9 NumWords=4 BlockCodeSize=4>\n"146 " <Remark header codeid=5 abbrevid=4 op0=2 op1=0 op2=1 op3=2/>\n"147 " <Remark debug location codeid=6 abbrevid=5 op0=3 op1=99 op2=55/>\n"148 "</Remark>\n"149 "<Meta BlockID=8 NumWords=9 BlockCodeSize=3>\n"150 " <String table codeid=3 abbrevid=6/> blob data = "151 "'remark\\x00pass\\x00function\\x00path\\x00'\n"152 "</Meta>\n",153 "<BLOCKINFO_BLOCK/>\n"154 "<Meta BlockID=8 NumWords=7 BlockCodeSize=3>\n"155 " <Container info codeid=1 abbrevid=4 op0=1 op1=0/>\n"156 " <External File codeid=4 abbrevid=5/> blob data = "157 "'" EXTERNALFILETESTPATH "'\n"158 "</Meta>\n");159}160 161TEST(BitstreamRemarkSerializer, SeparateRemarkFileHotness) {162 remarks::Remark R;163 R.RemarkType = remarks::Type::Missed;164 R.PassName = "pass";165 R.RemarkName = "remark";166 R.FunctionName = "function";167 R.Hotness.emplace(999999999);168 check(R,169 "<BLOCKINFO_BLOCK/>\n"170 "<Meta BlockID=8 NumWords=3 BlockCodeSize=3>\n"171 " <Container info codeid=1 abbrevid=4 op0=1 op1=1/>\n"172 " <Remark version codeid=2 abbrevid=5 op0=0/>\n"173 "</Meta>\n"174 "<Remark BlockID=9 NumWords=3 BlockCodeSize=4>\n"175 " <Remark header codeid=5 abbrevid=4 op0=2 op1=0 op2=1 op3=2/>\n"176 " <Remark hotness codeid=7 abbrevid=6 op0=999999999/>\n"177 "</Remark>\n"178 "<Meta BlockID=8 NumWords=8 BlockCodeSize=3>\n"179 " <String table codeid=3 abbrevid=6/> blob data = "180 "'remark\\x00pass\\x00function\\x00'\n"181 "</Meta>\n",182 "<BLOCKINFO_BLOCK/>\n"183 "<Meta BlockID=8 NumWords=7 BlockCodeSize=3>\n"184 " <Container info codeid=1 abbrevid=4 op0=1 op1=0/>\n"185 " <External File codeid=4 abbrevid=5/> blob data = "186 "'" EXTERNALFILETESTPATH "'\n"187 "</Meta>\n");188}189 190TEST(BitstreamRemarkSerializer, SeparateRemarkFileArgNoDebugLoc) {191 remarks::Remark R;192 R.RemarkType = remarks::Type::Missed;193 R.PassName = "pass";194 R.RemarkName = "remark";195 R.FunctionName = "function";196 R.Args.emplace_back();197 R.Args.back().Key = "key";198 R.Args.back().Val = "value";199 check(R,200 "<BLOCKINFO_BLOCK/>\n"201 "<Meta BlockID=8 NumWords=3 BlockCodeSize=3>\n"202 " <Container info codeid=1 abbrevid=4 op0=1 op1=1/>\n"203 " <Remark version codeid=2 abbrevid=5 op0=0/>\n"204 "</Meta>\n"205 "<Remark BlockID=9 NumWords=2 BlockCodeSize=4>\n"206 " <Remark header codeid=5 abbrevid=4 op0=2 op1=0 op2=1 op3=2/>\n"207 " <Argument codeid=9 abbrevid=8 op0=3 op1=4/>\n"208 "</Remark>\n"209 "<Meta BlockID=8 NumWords=10 BlockCodeSize=3>\n"210 " <String table codeid=3 abbrevid=6/> blob data = "211 "'remark\\x00pass\\x00function\\x00key\\x00value\\x00'\n"212 "</Meta>\n",213 "<BLOCKINFO_BLOCK/>\n"214 "<Meta BlockID=8 NumWords=7 BlockCodeSize=3>\n"215 " <Container info codeid=1 abbrevid=4 op0=1 op1=0/>\n"216 " <External File codeid=4 abbrevid=5/> blob data = "217 "'" EXTERNALFILETESTPATH "'\n"218 "</Meta>\n");219}220 221TEST(BitstreamRemarkSerializer, SeparateRemarkFileArgDebugLoc) {222 remarks::Remark R;223 R.RemarkType = remarks::Type::Missed;224 R.PassName = "pass";225 R.RemarkName = "remark";226 R.FunctionName = "function";227 R.Args.emplace_back();228 R.Args.back().Key = "key";229 R.Args.back().Val = "value";230 R.Args.back().Loc.emplace();231 R.Args.back().Loc->SourceFilePath = "path";232 R.Args.back().Loc->SourceLine = 99;233 R.Args.back().Loc->SourceColumn = 55;234 check(R,235 "<BLOCKINFO_BLOCK/>\n"236 "<Meta BlockID=8 NumWords=3 BlockCodeSize=3>\n"237 " <Container info codeid=1 abbrevid=4 op0=1 op1=1/>\n"238 " <Remark version codeid=2 abbrevid=5 op0=0/>\n"239 "</Meta>\n"240 "<Remark BlockID=9 NumWords=4 BlockCodeSize=4>\n"241 " <Remark header codeid=5 abbrevid=4 op0=2 op1=0 op2=1 op3=2/>\n"242 " <Argument with debug location codeid=8 abbrevid=7 op0=3 op1=4 op2=5 "243 "op3=99 op4=55/>\n"244 "</Remark>\n"245 "<Meta BlockID=8 NumWords=11 BlockCodeSize=3>\n"246 " <String table codeid=3 abbrevid=6/> blob data = "247 "'remark\\x00pass\\x00function\\x00key\\x00value\\x00path\\x00'\n"248 "</Meta>\n",249 "<BLOCKINFO_BLOCK/>\n"250 "<Meta BlockID=8 NumWords=7 BlockCodeSize=3>\n"251 " <Container info codeid=1 abbrevid=4 op0=1 op1=0/>\n"252 " <External File codeid=4 abbrevid=5/> blob data = "253 "'" EXTERNALFILETESTPATH "'\n"254 "</Meta>\n");255}256 257TEST(BitstreamRemarkSerializer, SeparateRemarkFileAll) {258 remarks::Remark R;259 R.RemarkType = remarks::Type::Missed;260 R.PassName = "pass";261 R.RemarkName = "remark";262 R.FunctionName = "function";263 R.Loc.emplace();264 R.Loc->SourceFilePath = "path";265 R.Loc->SourceLine = 99;266 R.Loc->SourceColumn = 55;267 R.Hotness.emplace(999999999);268 R.Args.emplace_back();269 R.Args.back().Key = "key";270 R.Args.back().Val = "value";271 R.Args.back().Loc.emplace();272 R.Args.back().Loc->SourceFilePath = "argpath";273 R.Args.back().Loc->SourceLine = 11;274 R.Args.back().Loc->SourceColumn = 66;275 check(R,276 "<BLOCKINFO_BLOCK/>\n"277 "<Meta BlockID=8 NumWords=3 BlockCodeSize=3>\n"278 " <Container info codeid=1 abbrevid=4 op0=1 op1=1/>\n"279 " <Remark version codeid=2 abbrevid=5 op0=0/>\n"280 "</Meta>\n"281 "<Remark BlockID=9 NumWords=8 BlockCodeSize=4>\n"282 " <Remark header codeid=5 abbrevid=4 op0=2 op1=0 op2=1 op3=2/>\n"283 " <Remark debug location codeid=6 abbrevid=5 op0=3 op1=99 op2=55/>\n"284 " <Remark hotness codeid=7 abbrevid=6 op0=999999999/>\n"285 " <Argument with debug location codeid=8 abbrevid=7 op0=4 op1=5 op2=6 "286 "op3=11 op4=66/>\n"287 "</Remark>\n"288 "<Meta BlockID=8 NumWords=13 BlockCodeSize=3>\n"289 " <String table codeid=3 abbrevid=6/> blob data = "290 "'remark\\x00pass\\x00function\\x00path\\x00key\\x00value\\x00argpa"291 "th\\x00'\n"292 "</Meta>\n",293 "<BLOCKINFO_BLOCK/>\n"294 "<Meta BlockID=8 NumWords=7 BlockCodeSize=3>\n"295 " <Container info codeid=1 abbrevid=4 op0=1 op1=0/>\n"296 " <External File codeid=4 abbrevid=5/> blob data = "297 "'" EXTERNALFILETESTPATH "'\n"298 "</Meta>\n");299}300 301TEST(BitstreamRemarkSerializer, Standalone) {302 // Pre-populate the string table.303 remarks::StringTable StrTab;304 StrTab.add("pass");305 StrTab.add("remark");306 StrTab.add("function");307 StrTab.add("path");308 StrTab.add("key");309 StrTab.add("value");310 StrTab.add("argpath");311 remarks::Remark R;312 R.RemarkType = remarks::Type::Missed;313 R.PassName = "pass";314 R.RemarkName = "remark";315 R.FunctionName = "function";316 R.Loc.emplace();317 R.Loc->SourceFilePath = "path";318 R.Loc->SourceLine = 99;319 R.Loc->SourceColumn = 55;320 R.Hotness.emplace(999999999);321 R.Args.emplace_back();322 R.Args.back().Key = "key";323 R.Args.back().Val = "value";324 R.Args.back().Loc.emplace();325 R.Args.back().Loc->SourceFilePath = "argpath";326 R.Args.back().Loc->SourceLine = 11;327 R.Args.back().Loc->SourceColumn = 66;328 check(329 R,330 "<BLOCKINFO_BLOCK/>\n"331 "<Meta BlockID=8 NumWords=3 BlockCodeSize=3>\n"332 " <Container info codeid=1 abbrevid=4 op0=1 op1=1/>\n"333 " <Remark version codeid=2 abbrevid=5 op0=0/>\n"334 "</Meta>\n"335 "<Remark BlockID=9 NumWords=8 BlockCodeSize=4>\n"336 " <Remark header codeid=5 abbrevid=4 op0=2 op1=1 op2=0 op3=2/>\n"337 " <Remark debug location codeid=6 abbrevid=5 op0=3 op1=99 op2=55/>\n"338 " <Remark hotness codeid=7 abbrevid=6 op0=999999999/>\n"339 " <Argument with debug location codeid=8 abbrevid=7 op0=4 op1=5 op2=6 "340 "op3=11 op4=66/>\n"341 "</Remark>\n"342 "<Meta BlockID=8 NumWords=13 BlockCodeSize=3>\n"343 " <String table codeid=3 abbrevid=6/> blob data = "344 "'pass\\x00remark\\x00function\\x00path\\x00key\\x00value\\x00argpath\\x0"345 "0'\n"346 "</Meta>\n",347 std::nullopt, std::move(StrTab));348}349