14#include "llvm/Transforms/IPO/InstrumentorVariables.inc"
25#include <system_error>
36 if (Ty->isIntegerTy()) {
37 auto BW = Ty->getIntegerBitWidth();
39 return {
"bool ",
"bool *"};
40 auto S =
"int" + std::to_string(BW) +
"_t ";
43 if (Ty->isPointerTy())
46 return {
"float ",
"float *"};
48 return {
"double ",
"double *"};
58 if (Ty->isIntegerTy()) {
59 if (Ty->getIntegerBitWidth() > 32) {
60 assert(Ty->getIntegerBitWidth() == 64);
61 return "%\" PRId64 \"";
63 return "%\" PRId32 \"";
65 if (Ty->isPointerTy())
75 std::string DirectFormat =
"printf(\"" +
IO.getName().str() +
76 (
IO.IP.isPRE() ?
" pre" :
" post") +
" -- ";
77 std::string IndirectFormat = DirectFormat;
78 std::string DirectArg, IndirectArg, DirectReturnValue, IndirectReturnValue;
80 auto AddToFormats = [&](
Twine S) {
81 DirectFormat += S.str();
82 IndirectFormat += S.str();
84 auto AddToArgs = [&](
Twine S) {
86 IndirectArg += S.str();
89 for (
auto &IRArg :
IO.IRTArgs) {
97 AddToArgs(
", " + IRArg.Name);
99 AddToArgs(
", getLLVMTypeIDName(" + IRArg.Name +
")");
101 AddToFormats(IRArg.Name +
": ");
103 DirectReturnValue = IRArg.Name;
105 IndirectReturnValue = IRArg.Name;
110 DirectFormat +=
"[value pack at %p]";
111 IndirectFormat +=
"[value pack at %p]";
119 IndirectFormat +=
"%p";
120 IndirectArg +=
"_ptr";
123 IndirectFormat +=
", " + IRArg.Name.str() +
"_size: %\" PRId32 \"";
124 IndirectArg +=
", " + IRArg.Name.str() +
"_size";
129 std::string DirectBody = DirectFormat +
"\\n\"" + DirectArg +
");\n";
130 std::string IndirectBody = IndirectFormat +
"\\n\"" + IndirectArg +
");\n";
133 for (
size_t ArgIdx = 0; ArgIdx <
IO.IRTArgs.size(); ++ArgIdx) {
134 auto &IRArg =
IO.IRTArgs[ArgIdx];
139 std::string CountParam;
140 for (
int PrevIdx = ArgIdx - 1; PrevIdx >= 0; --PrevIdx) {
141 if (
IO.IRTArgs[PrevIdx].Enabled &&
142 IO.IRTArgs[PrevIdx].Name.equals_insensitive(
143 (
"num_" + IRArg.Name).str())) {
144 CountParam =
IO.IRTArgs[PrevIdx].Name.str();
150 if (CountParam.empty())
151 CountParam =
"0 /* count not enabled! */";
153 auto AddToBodies = [&](
Twine T) {
154 DirectBody +=
T.str();
155 IndirectBody +=
T.str();
159 AddToBodies(
" ValuePackIterator iter_" + IRArg.Name.str() +
";\n");
160 AddToBodies(
" initValuePackIterator(&iter_" + IRArg.Name.str() +
", " +
161 IRArg.Name.str() +
", " + CountParam +
");\n");
162 AddToBodies(
" while (iter_" + IRArg.Name.str() +
".index < iter_" +
163 IRArg.Name.str() +
".count) {\n");
164 AddToBodies(
" ValuePackHeader header_" + IRArg.Name.str() +
165 " = getValuePackHeader(&iter_" + IRArg.Name.str() +
");\n");
166 AddToBodies(
" const void *data_" + IRArg.Name.str() +
167 " = getValuePackData(&iter_" + IRArg.Name.str() +
");\n");
168 AddToBodies(
" printf(\" [%" PRIu32
"] type=%s size=%" PRIu32
169 " data=%p\\n\", iter_" +
170 IRArg.Name.str() +
".index, getLLVMTypeIDName(header_" +
171 IRArg.Name.str() +
".type_id), header_" + IRArg.Name.str() +
172 ".size, data_" + IRArg.Name.str() +
");\n");
173 AddToBodies(
" nextValuePack(&iter_" + IRArg.Name.str() +
");\n");
178 IndirectReturnValue = DirectReturnValue =
"0";
179 if (!DirectReturnValue.empty())
180 DirectBody +=
" return " + DirectReturnValue +
";\n";
181 if (!IndirectReturnValue.empty())
182 IndirectBody +=
" return " + IndirectReturnValue +
";\n";
183 return {DirectBody, IndirectBody};
186std::pair<std::string, std::string>
189 std::string DirectRetTy =
"void ", IndirectRetTy =
"void ";
190 for (
auto &IRArg :
IO.IRTArgs) {
193 const auto &[DirectArgTy, IndirectArgTy] =
195 std::string DirectArg = DirectArgTy + IRArg.Name.str();
196 std::string IndirectArg = IndirectArgTy + IRArg.Name.str() +
"_ptr";
197 std::string IndirectArgSize =
"int32_t " + IRArg.Name.str() +
"_size";
200 DirectRetTy = DirectArgTy;
202 IndirectRetTy = DirectArgTy;
214 IConf.
getRTName(
IO.IP.isPRE() ?
"pre_" :
"post_",
IO.getName(),
"");
216 IConf.
getRTName(
IO.IP.isPRE() ?
"pre_" :
"post_",
IO.getName(),
"_ind");
217 auto MakeSignature = [&](std::string &
RetTy, std::string &Name,
219 return RetTy + Name +
"(" +
join(Args,
", ") +
")";
224 assert((DirectRetTy == UserRetTy || DirectRetTy ==
"void ") &&
225 (IndirectRetTy == UserRetTy || IndirectRetTy ==
"void ") &&
226 "Explicit return type but also implicit one!");
227 IndirectRetTy = DirectRetTy = UserRetTy;
230 return {
"", MakeSignature(IndirectRetTy, IndirectName, IndirectArgs)};
232 return {MakeSignature(DirectRetTy, DirectName, DirectArgs),
""};
233 return {MakeSignature(DirectRetTy, DirectName, DirectArgs),
234 MakeSignature(IndirectRetTy, IndirectName, IndirectArgs)};
239 if (HeaderFileName.
empty())
246 Twine(
"failed to open instrumentor runtime header file for writing: ") +
253 OS << InstrumentorRuntimeHelper;
254 OS <<
"\n// Generated with runtime prefix: " << Prefix <<
"\n";
259 if (StubRuntimeName.
empty())
266 Twine(
"failed to open instrumentor stub runtime file for writing: ") +
273 std::string HeaderFileName = StubRuntimeName.
str();
274 size_t DotPos = HeaderFileName.rfind(
'.');
275 if (DotPos != std::string::npos)
276 HeaderFileName = HeaderFileName.substr(0, DotPos);
277 HeaderFileName +=
".h";
280 OS <<
"//===-- Instrumentor Runtime Stub "
281 "-----------------------------------------===//\n";
283 OS <<
"// Part of the LLVM Project, under the Apache License v2.0 with LLVM "
285 OS <<
"// See https://llvm.org/LICENSE.txt for license information.\n";
286 OS <<
"// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception\n";
289 "===-------------------------------------------------------------------"
292 OS <<
"// This file is auto-generated by the LLVM Instrumentor pass.\n";
293 OS <<
"// It provides stub implementations of instrumentation runtime "
295 OS <<
"// that print human-readable information about instrumentation "
298 OS <<
"// Generated with runtime prefix: " << Prefix <<
"\n";
301 "===-------------------------------------------------------------------"
303 OS <<
"#include <inttypes.h>\n";
304 OS <<
"#include <stdint.h>\n";
305 OS <<
"#include <stdio.h>\n";
307 OS <<
"#ifdef __cplusplus\n";
308 OS <<
"extern \"C\" {\n";
311 for (
auto &ChoiceMap : IConf.
IChoices) {
312 for (
auto &[
_, IO] : ChoiceMap) {
318 if (!Signatures.first.empty()) {
319 OS << Signatures.first <<
" {\n";
320 OS <<
" " << Bodies.first <<
"}\n\n";
322 if (!Signatures.second.empty()) {
323 OS << Signatures.second <<
" {\n";
324 OS <<
" " << Bodies.second <<
"}\n\n";
329 OS <<
"#ifdef __cplusplus\n";
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file defines the SmallVector class.
This is an important class for using LLVM in a threaded context.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
std::string str() const
Get the contents as an std::string.
constexpr bool empty() const
Check if the string is empty.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
A raw_ostream that writes to a file descriptor.
static std::string getPrintfFormatString(Type *Ty, unsigned Flags)
Get the string representation of the C printf format of an argument with type Ty.
LLVM_ABI void printRuntimeHeader(const InstrumentationConfig &IConf, StringRef HeaderFileName, LLVMContext &Ctx)
Print the runtime header file that provides helper structures and functions for reading data generate...
static std::pair< std::string, std::string > getAsCType(Type *Ty, unsigned Flags)
Get the string representation of an argument with type Ty.
LLVM_ABI void printRuntimeStub(const InstrumentationConfig &IConf, StringRef StubRuntimeName, LLVMContext &Ctx)
Print a runtime stub file with the implementation of the instrumentation runtime functions correspond...
LLVM_ABI StringRef filename(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get filename.
This is an optimization pass for GlobalISel generic memory operations.
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
std::string join(IteratorT Begin, IteratorT End, StringRef Separator)
Joins the strings in the range [Begin, End), adding Separator between the elements.
Helper to represent an instrumentation runtime function that is related to an instrumentation opportu...
bool MightRequireIndirection
Whether any argument may require indirection.
LLVM_ABI std::pair< std::string, std::string > createCBodies() const
Create a string representation of the function definition in C.
Type * RetTy
The return type of the instrumentation function.
InstrumentationOpportunity & IO
The instrumentation opportunity which it is linked to.
LLVM_ABI std::pair< std::string, std::string > createCSignature(const InstrumentationConfig &IConf) const
Create a string representation of the function declaration in C.
unsigned NumReplaceableArgs
The number of arguments that can be replaced.
bool RequiresIndirection
Whether the function requires indirection in some argument.
bool isPotentiallyIndirect(IRTArg &IRTA) const
Return whether the function may have any indirect argument.
The class that contains the configuration for the instrumentor.
EnumeratedArray< MapVector< StringRef, InstrumentationOpportunity * >, InstrumentationLocation::KindTy > IChoices
The map registered instrumentation opportunities.
StringRef getRTName() const
Get the runtime prefix for the instrumentation runtime functions.