23#include <system_error>
34 if (Ty->isIntegerTy()) {
35 auto BW = Ty->getIntegerBitWidth();
37 return {
"bool ",
"bool *"};
38 auto S =
"int" + std::to_string(BW) +
"_t ";
41 if (Ty->isPointerTy())
44 return {
"float ",
"float *"};
46 return {
"double ",
"double *"};
54 if (Ty->isIntegerTy()) {
55 if (Ty->getIntegerBitWidth() > 32) {
56 assert(Ty->getIntegerBitWidth() == 64);
61 if (Ty->isPointerTy())
71 std::string DirectFormat =
"printf(\"" +
IO.getName().str() +
72 (
IO.IP.isPRE() ?
" pre" :
" post") +
" -- ";
73 std::string IndirectFormat = DirectFormat;
74 std::string DirectArg, IndirectArg, DirectReturnValue, IndirectReturnValue;
76 auto AddToFormats = [&](
Twine S) {
77 DirectFormat += S.str();
78 IndirectFormat += S.str();
80 auto AddToArgs = [&](
Twine S) {
82 IndirectArg += S.str();
85 for (
auto &IRArg :
IO.IRTArgs) {
91 AddToArgs(
", " + IRArg.Name);
92 AddToFormats(IRArg.Name +
": ");
94 DirectReturnValue = IRArg.Name;
96 IndirectReturnValue = IRArg.Name;
102 IndirectFormat +=
"%p";
103 IndirectArg +=
"_ptr";
106 IndirectFormat +=
", " + IRArg.Name.str() +
"_size: %i";
107 IndirectArg +=
", " + IRArg.Name.str() +
"_size";
112 std::string DirectBody = DirectFormat +
"\\n\"" + DirectArg +
");\n";
113 std::string IndirectBody = IndirectFormat +
"\\n\"" + IndirectArg +
");\n";
115 IndirectReturnValue = DirectReturnValue =
"0";
116 if (!DirectReturnValue.empty())
117 DirectBody +=
" return " + DirectReturnValue +
";\n";
118 if (!IndirectReturnValue.empty())
119 IndirectBody +=
" return " + IndirectReturnValue +
";\n";
120 return {DirectBody, IndirectBody};
123std::pair<std::string, std::string>
126 std::string DirectRetTy =
"void ", IndirectRetTy =
"void ";
127 for (
auto &IRArg :
IO.IRTArgs) {
130 const auto &[DirectArgTy, IndirectArgTy] =
132 std::string DirectArg = DirectArgTy + IRArg.Name.str();
133 std::string IndirectArg = IndirectArgTy + IRArg.Name.str() +
"_ptr";
134 std::string IndirectArgSize =
"int32_t " + IRArg.Name.str() +
"_size";
137 DirectRetTy = DirectArgTy;
139 IndirectRetTy = DirectArgTy;
151 IConf.
getRTName(
IO.IP.isPRE() ?
"pre_" :
"post_",
IO.getName(),
"");
153 IConf.
getRTName(
IO.IP.isPRE() ?
"pre_" :
"post_",
IO.getName(),
"_ind");
154 auto MakeSignature = [&](std::string &
RetTy, std::string &Name,
156 return RetTy + Name +
"(" +
join(Args,
", ") +
")";
161 assert((DirectRetTy == UserRetTy || DirectRetTy ==
"void ") &&
162 (IndirectRetTy == UserRetTy || IndirectRetTy ==
"void ") &&
163 "Explicit return type but also implicit one!");
164 IndirectRetTy = DirectRetTy = UserRetTy;
167 return {
"", MakeSignature(IndirectRetTy, IndirectName, IndirectArgs)};
169 return {MakeSignature(DirectRetTy, DirectName, DirectArgs),
""};
170 return {MakeSignature(DirectRetTy, DirectName, DirectArgs),
171 MakeSignature(IndirectRetTy, IndirectName, IndirectArgs)};
176 if (StubRuntimeName.
empty())
183 Twine(
"failed to open instrumentor stub runtime file for writing: ") +
188 OS <<
"// LLVM Instrumentor stub runtime\n\n";
189 OS <<
"#include <stdint.h>\n";
190 OS <<
"#include <stdio.h>\n\n";
192 for (
auto &ChoiceMap : IConf.
IChoices) {
193 for (
auto &[
_, IO] : ChoiceMap) {
199 if (!Signatures.first.empty()) {
200 OS << Signatures.first <<
" {\n";
201 OS <<
" " << Bodies.first <<
"}\n\n";
203 if (!Signatures.second.empty()) {
204 OS << Signatures.second <<
" {\n";
205 OS <<
" " << Bodies.second <<
"}\n\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.
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.
static std::pair< std::string, std::string > getAsCType(Type *Ty, unsigned Flags)
Get the string representation of an argument with type Ty.
void printRuntimeStub(const InstrumentationConfig &IConf, StringRef StubRuntimeName, LLVMContext &Ctx)
Print a runtime stub file with the implementation of the instrumentation runtime functions correspond...
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.
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.
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.
StringRef getRTName() const
Get the runtime prefix for the instrumentation runtime functions.
EnumeratedArray< StringMap< InstrumentationOpportunity * >, InstrumentationLocation::KindTy > IChoices
The map registered instrumentation opportunities.