LLVM 23.0.0git
InstrumentorConfigFile.cpp
Go to the documentation of this file.
1//===-- InstrumentorConfigFile.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-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// The implementation of the utilities for the Instrumentor JSON configuration
10// file.
11//
12//===----------------------------------------------------------------------===//
13
15
16#include "llvm/ADT/StringMap.h"
17#include "llvm/ADT/StringRef.h"
20#include "llvm/Support/JSON.h"
23
24#include <string>
25
26namespace llvm {
27namespace instrumentor {
28
30 LLVMContext &Ctx) {
31 if (OutputFile.empty())
32 return;
33
34 std::error_code EC;
35 raw_fd_stream OS(OutputFile, EC);
36 if (EC) {
38 Twine("failed to open instrumentor configuration file for writing: ") +
39 EC.message(),
40 DS_Warning));
41 return;
42 }
43
44 json::OStream J(OS, 2);
45 J.objectBegin();
46
47 J.attributeBegin("configuration");
48 J.objectBegin();
49 for (auto *BaseCO : IConf.BaseConfigurationOptions) {
50 switch (BaseCO->Kind) {
52 J.attribute(BaseCO->Name, BaseCO->getString());
53 break;
55 J.attribute(BaseCO->Name, BaseCO->getBool());
56 break;
57 }
58 if (!BaseCO->Description.empty())
59 J.attribute(std::string(BaseCO->Name) + ".description",
60 BaseCO->Description);
61 }
62 J.objectEnd();
63 J.attributeEnd();
64
65 for (unsigned KindVal = 0; KindVal <= InstrumentationLocation::Last;
66 ++KindVal) {
67 auto Kind = InstrumentationLocation::KindTy(KindVal);
68
69 auto &KindChoices = IConf.IChoices[Kind];
70 if (KindChoices.empty())
71 continue;
72
74 J.objectBegin();
75 for (auto &ChoiceIt : KindChoices) {
76 J.attributeBegin(ChoiceIt.getKey());
77 J.objectBegin();
78 J.attribute("enabled", ChoiceIt.second->Enabled);
79 for (auto &ArgIt : ChoiceIt.second->IRTArgs) {
80 J.attribute(ArgIt.Name, ArgIt.Enabled);
81 if ((ArgIt.Flags & IRTArg::REPLACABLE) ||
82 (ArgIt.Flags & IRTArg::REPLACABLE_CUSTOM))
83 J.attribute(std::string(ArgIt.Name) + ".replace", true);
84 if (!ArgIt.Description.empty())
85 J.attribute(std::string(ArgIt.Name) + ".description",
86 ArgIt.Description);
87 }
88 J.objectEnd();
89 J.attributeEnd();
90 }
91 J.objectEnd();
92 J.attributeEnd();
93 }
94
95 J.objectEnd();
96}
97
99 LLVMContext &Ctx) {
100 if (InputFile.empty())
101 return true;
102
103 std::error_code EC;
104 auto BufferOrErr = MemoryBuffer::getFileOrSTDIN(InputFile);
105 if (std::error_code EC = BufferOrErr.getError()) {
107 Twine("failed to open instrumentor configuration file for reading: ") +
108 EC.message(),
109 DS_Warning));
110 return false;
111 }
112 auto Buffer = std::move(BufferOrErr.get());
113 json::Path::Root NullRoot;
114 auto Parsed = json::parse(Buffer->getBuffer());
115 if (!Parsed) {
117 Twine("failed to parse instrumentor configuration file: ") +
118 toString(Parsed.takeError()),
119 DS_Warning));
120 return false;
121 }
122 auto *Config = Parsed->getAsObject();
123 if (!Config) {
125 "failed to parse instrumentor configuration file, expected an object "
126 "'{ ... }'",
127 DS_Warning));
128 return false;
129 }
130
132 for (auto *BO : IConf.BaseConfigurationOptions)
133 BCOMap[BO->Name] = BO;
134
136 for (auto &It : *Config) {
137 auto *Obj = It.second.getAsObject();
138 if (!Obj) {
140 "malformed JSON configuration, expected an object", DS_Warning));
141 continue;
142 }
143 if (It.first == "configuration") {
144 for (auto &ObjIt : *Obj) {
145 if (auto *BO = BCOMap.lookup(ObjIt.first)) {
146 switch (BO->Kind) {
148 if (auto V = ObjIt.second.getAsString()) {
149 BO->setString(IConf.SS.save(*V));
150 } else {
152 Twine("configuration key '") + ObjIt.first.str() +
153 Twine("' expects a string, value ignored"),
154 DS_Warning));
155 }
156 break;
158 if (auto V = ObjIt.second.getAsBoolean())
159 BO->setBool(*V);
160 else {
162 Twine("configuration key '") + ObjIt.first.str() +
163 Twine("' expects a boolean, value ignored"),
164 DS_Warning));
165 }
166 break;
167 }
168 } else if (!StringRef(ObjIt.first).ends_with(".description")) {
170 Twine("configuration key '") + ObjIt.first.str() +
171 Twine("' not found and ignored"),
172 DS_Warning));
173 }
174 }
175 continue;
176 }
177
178 auto &IChoiceMap =
180 for (auto &ObjIt : *Obj) {
181 auto *InnerObj = ObjIt.second.getAsObject();
182 if (!InnerObj) {
184 "malformed JSON configuration, expected an object", DS_Warning));
185 continue;
186 }
187 auto *IO = IChoiceMap.lookup(ObjIt.first);
188 if (!IO) {
190 Twine("malformed JSON configuration, expected an object matching "
191 "an instrumentor choice, got ") +
192 ObjIt.first.str(),
193 DS_Warning));
194 continue;
195 }
196 SeenIOs.insert(IO);
198 for (auto &InnerObjIt : *InnerObj) {
199 auto Name = StringRef(InnerObjIt.first);
200 if (Name.consume_back(".replace"))
201 ReplaceMap[Name] = InnerObjIt.second.getAsBoolean().value_or(false);
202 else
203 ValueMap[Name] = InnerObjIt.second.getAsBoolean().value_or(false);
204 }
205 IO->Enabled = ValueMap["enabled"];
206 for (auto &IRArg : IO->IRTArgs) {
207 IRArg.Enabled = ValueMap[IRArg.Name];
208 if (!ReplaceMap.lookup(IRArg.Name)) {
209 IRArg.Flags &= ~IRTArg::REPLACABLE;
210 IRArg.Flags &= ~IRTArg::REPLACABLE_CUSTOM;
211 }
212 }
213 }
214 }
215
216 for (auto &IChoiceMap : IConf.IChoices)
217 for (auto &It : IChoiceMap)
218 if (!SeenIOs.count(It.second))
219 It.second->Enabled = false;
220
221 return true;
222}
223
224} // end namespace instrumentor
225} // end namespace llvm
This file defines the StringMap class.
static constexpr std::pair< StringLiteral, StringLiteral > ReplaceMap[]
This file supports working with JSON data.
Diagnostic information for IR instrumentation reporting.
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:68
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFileOrSTDIN(const Twine &Filename, bool IsText=false, bool RequiresNullTerminator=true, std::optional< Align > Alignment=std::nullopt)
Open the specified file as a MemoryBuffer, or open stdin if the Filename is "-".
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Definition StringMap.h:133
ValueTy lookup(StringRef Key) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
Definition StringMap.h:260
Represent a constant reference to a string, i.e.
Definition StringRef.h:55
constexpr bool empty() const
Check if the string is empty.
Definition StringRef.h:140
bool ends_with(StringRef Suffix) const
Check if this string ends with the given Suffix.
Definition StringRef.h:269
StringRef save(const char *S)
Definition StringSaver.h:31
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
LLVM_ABI std::string str() const
Return the twine contents as a std::string.
Definition Twine.cpp:17
See the file comment.
Definition ValueMap.h:84
json::OStream allows writing well-formed JSON without materializing all structures as json::Value ahe...
Definition JSON.h:982
LLVM_ABI void attributeBegin(llvm::StringRef Key)
Definition JSON.cpp:883
void attribute(llvm::StringRef Key, const Value &Contents)
Emit an attribute whose value is self-contained (number, vector<int> etc).
Definition JSON.h:1037
LLVM_ABI void objectBegin()
Definition JSON.cpp:864
LLVM_ABI void attributeEnd()
Definition JSON.cpp:903
LLVM_ABI void objectEnd()
Definition JSON.cpp:872
The root is the trivial Path to the root value.
Definition JSON.h:699
A raw_ostream of a file for reading/writing/seeking.
bool readConfigFromJSON(InstrumentationConfig &IConf, StringRef InputFile, LLVMContext &Ctx)
Read the configuration from the file with path InputFile into /p IConf.
void writeConfigToJSON(InstrumentationConfig &IConf, StringRef OutputFile, LLVMContext &Ctx)
Write the configuration in /p IConf to the file with path OutputFile.
LLVM_ABI llvm::Expected< Value > parse(llvm::StringRef JSON)
Parses the provided JSON source, or returns a ParseError.
Definition JSON.cpp:681
This is an optimization pass for GlobalISel generic memory operations.
std::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral=false, bool UpperCase=true, bool InsertSeparators=false)
unsigned Flags
The flags that describe the properties of the argument.
The class that contains the configuration for the instrumentor.
SmallVector< BaseConfigurationOption * > BaseConfigurationOptions
The list of enabled base configuration options.
EnumeratedArray< StringMap< InstrumentationOpportunity * >, InstrumentationLocation::KindTy > IChoices
The map registered instrumentation opportunities.
static KindTy getKindFromStr(StringRef S)
Return the location kind described by a string.
static StringRef getKindStr(KindTy Kind)
Return the string representation given a location kind.
KindTy
The supported location kinds, which are composed of a opportunity type and position.