1 //===- Remark.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 // Implementation of the Remark type and the C API. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "llvm/Remarks/Remark.h" 14 #include "llvm/ADT/APInt.h" 15 #include "llvm/ADT/ArrayRef.h" 16 #include <optional> 17 18 using namespace llvm; 19 using namespace llvm::remarks; 20 21 std::string Remark::getArgsAsMsg() const { 22 std::string Str; 23 raw_string_ostream OS(Str); 24 for (const Argument &Arg : Args) 25 OS << Arg.Val; 26 return OS.str(); 27 } 28 29 /// Returns the value of a specified key parsed from StringRef. 30 std::optional<int> Argument::getValAsInt() const { 31 APInt KeyVal; 32 if (Val.getAsInteger(10, KeyVal)) 33 return std::nullopt; 34 return KeyVal.getSExtValue(); 35 } 36 37 bool Argument::isValInt() const { return getValAsInt().has_value(); } 38 39 void RemarkLocation::print(raw_ostream &OS) const { 40 OS << "{ " 41 << "File: " << SourceFilePath << ", Line: " << SourceLine 42 << " Column:" << SourceColumn << " }\n"; 43 } 44 45 void Argument::print(raw_ostream &OS) const { 46 OS << Key << ": " << Val << "\n"; 47 } 48 49 void Remark::print(raw_ostream &OS) const { 50 OS << "Name: "; 51 OS << RemarkName << "\n"; 52 OS << "Type: " << typeToStr(RemarkType) << "\n"; 53 OS << "FunctionName: " << FunctionName << "\n"; 54 OS << "PassName: " << PassName << "\n"; 55 if (Loc) 56 OS << "Loc: " << Loc.value(); 57 if (Hotness) 58 OS << "Hotness: " << Hotness; 59 if (!Args.empty()) { 60 OS << "Args:\n"; 61 for (auto Arg : Args) 62 OS << "\t" << Arg; 63 } 64 } 65 66 // Create wrappers for C Binding types (see CBindingWrapping.h). 67 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(StringRef, LLVMRemarkStringRef) 68 69 extern "C" const char *LLVMRemarkStringGetData(LLVMRemarkStringRef String) { 70 return unwrap(String)->data(); 71 } 72 73 extern "C" uint32_t LLVMRemarkStringGetLen(LLVMRemarkStringRef String) { 74 return unwrap(String)->size(); 75 } 76 77 extern "C" LLVMRemarkStringRef 78 LLVMRemarkDebugLocGetSourceFilePath(LLVMRemarkDebugLocRef DL) { 79 return wrap(&unwrap(DL)->SourceFilePath); 80 } 81 82 extern "C" uint32_t LLVMRemarkDebugLocGetSourceLine(LLVMRemarkDebugLocRef DL) { 83 return unwrap(DL)->SourceLine; 84 } 85 86 extern "C" uint32_t 87 LLVMRemarkDebugLocGetSourceColumn(LLVMRemarkDebugLocRef DL) { 88 return unwrap(DL)->SourceColumn; 89 } 90 91 extern "C" LLVMRemarkStringRef LLVMRemarkArgGetKey(LLVMRemarkArgRef Arg) { 92 return wrap(&unwrap(Arg)->Key); 93 } 94 95 extern "C" LLVMRemarkStringRef LLVMRemarkArgGetValue(LLVMRemarkArgRef Arg) { 96 return wrap(&unwrap(Arg)->Val); 97 } 98 99 extern "C" LLVMRemarkDebugLocRef 100 LLVMRemarkArgGetDebugLoc(LLVMRemarkArgRef Arg) { 101 if (const std::optional<RemarkLocation> &Loc = unwrap(Arg)->Loc) 102 return wrap(&*Loc); 103 return nullptr; 104 } 105 106 extern "C" void LLVMRemarkEntryDispose(LLVMRemarkEntryRef Remark) { 107 delete unwrap(Remark); 108 } 109 110 extern "C" LLVMRemarkType LLVMRemarkEntryGetType(LLVMRemarkEntryRef Remark) { 111 // Assume here that the enums can be converted both ways. 112 return static_cast<LLVMRemarkType>(unwrap(Remark)->RemarkType); 113 } 114 115 extern "C" LLVMRemarkStringRef 116 LLVMRemarkEntryGetPassName(LLVMRemarkEntryRef Remark) { 117 return wrap(&unwrap(Remark)->PassName); 118 } 119 120 extern "C" LLVMRemarkStringRef 121 LLVMRemarkEntryGetRemarkName(LLVMRemarkEntryRef Remark) { 122 return wrap(&unwrap(Remark)->RemarkName); 123 } 124 125 extern "C" LLVMRemarkStringRef 126 LLVMRemarkEntryGetFunctionName(LLVMRemarkEntryRef Remark) { 127 return wrap(&unwrap(Remark)->FunctionName); 128 } 129 130 extern "C" LLVMRemarkDebugLocRef 131 LLVMRemarkEntryGetDebugLoc(LLVMRemarkEntryRef Remark) { 132 if (const std::optional<RemarkLocation> &Loc = unwrap(Remark)->Loc) 133 return wrap(&*Loc); 134 return nullptr; 135 } 136 137 extern "C" uint64_t LLVMRemarkEntryGetHotness(LLVMRemarkEntryRef Remark) { 138 if (const std::optional<uint64_t> &Hotness = unwrap(Remark)->Hotness) 139 return *Hotness; 140 return 0; 141 } 142 143 extern "C" uint32_t LLVMRemarkEntryGetNumArgs(LLVMRemarkEntryRef Remark) { 144 return unwrap(Remark)->Args.size(); 145 } 146 147 extern "C" LLVMRemarkArgRef 148 LLVMRemarkEntryGetFirstArg(LLVMRemarkEntryRef Remark) { 149 ArrayRef<Argument> Args = unwrap(Remark)->Args; 150 // No arguments to iterate on. 151 if (Args.empty()) 152 return nullptr; 153 return reinterpret_cast<LLVMRemarkArgRef>( 154 const_cast<Argument *>(Args.begin())); 155 } 156 157 extern "C" LLVMRemarkArgRef 158 LLVMRemarkEntryGetNextArg(LLVMRemarkArgRef ArgIt, LLVMRemarkEntryRef Remark) { 159 // No more arguments to iterate on. 160 if (ArgIt == nullptr) 161 return nullptr; 162 163 auto It = (ArrayRef<Argument>::const_iterator)ArgIt; 164 auto Next = std::next(It); 165 if (Next == unwrap(Remark)->Args.end()) 166 return nullptr; 167 168 return reinterpret_cast<LLVMRemarkArgRef>(const_cast<Argument *>(Next)); 169 } 170