1 //=-- InstrProf.cpp - Instrumented profiling format support -----------------=// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file contains support for clang's instrumentation based PGO and 11 // coverage. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "llvm/IR/Constants.h" 16 #include "llvm/IR/Function.h" 17 #include "llvm/IR/Module.h" 18 #include "llvm/IR/GlobalVariable.h" 19 #include "llvm/ProfileData/InstrProf.h" 20 #include "llvm/Support/ErrorHandling.h" 21 #include "llvm/Support/ManagedStatic.h" 22 23 using namespace llvm; 24 25 namespace { 26 class InstrProfErrorCategoryType : public std::error_category { 27 const char *name() const LLVM_NOEXCEPT override { return "llvm.instrprof"; } 28 std::string message(int IE) const override { 29 instrprof_error E = static_cast<instrprof_error>(IE); 30 switch (E) { 31 case instrprof_error::success: 32 return "Success"; 33 case instrprof_error::eof: 34 return "End of File"; 35 case instrprof_error::unrecognized_format: 36 return "Unrecognized instrumentation profile encoding format"; 37 case instrprof_error::bad_magic: 38 return "Invalid instrumentation profile data (bad magic)"; 39 case instrprof_error::bad_header: 40 return "Invalid instrumentation profile data (file header is corrupt)"; 41 case instrprof_error::unsupported_version: 42 return "Unsupported instrumentation profile format version"; 43 case instrprof_error::unsupported_hash_type: 44 return "Unsupported instrumentation profile hash type"; 45 case instrprof_error::too_large: 46 return "Too much profile data"; 47 case instrprof_error::truncated: 48 return "Truncated profile data"; 49 case instrprof_error::malformed: 50 return "Malformed instrumentation profile data"; 51 case instrprof_error::unknown_function: 52 return "No profile data available for function"; 53 case instrprof_error::hash_mismatch: 54 return "Function hash mismatch"; 55 case instrprof_error::count_mismatch: 56 return "Function count mismatch"; 57 case instrprof_error::counter_overflow: 58 return "Counter overflow"; 59 case instrprof_error::value_site_count_mismatch: 60 return "Function's value site counts mismatch"; 61 } 62 llvm_unreachable("A value of instrprof_error has no message."); 63 } 64 }; 65 } 66 67 static ManagedStatic<InstrProfErrorCategoryType> ErrorCategory; 68 69 const std::error_category &llvm::instrprof_category() { 70 return *ErrorCategory; 71 } 72 73 namespace llvm { 74 75 std::string getPGOFuncName(StringRef RawFuncName, 76 GlobalValue::LinkageTypes Linkage, 77 StringRef FileName) { 78 79 // Function names may be prefixed with a binary '1' to indicate 80 // that the backend should not modify the symbols due to any platform 81 // naming convention. Do not include that '1' in the PGO profile name. 82 if (RawFuncName[0] == '\1') 83 RawFuncName = RawFuncName.substr(1); 84 85 std::string FuncName = RawFuncName; 86 if (llvm::GlobalValue::isLocalLinkage(Linkage)) { 87 // For local symbols, prepend the main file name to distinguish them. 88 // Do not include the full path in the file name since there's no guarantee 89 // that it will stay the same, e.g., if the files are checked out from 90 // version control in different locations. 91 if (FileName.empty()) 92 FuncName = FuncName.insert(0, "<unknown>:"); 93 else 94 FuncName = FuncName.insert(0, FileName.str() + ":"); 95 } 96 return FuncName; 97 } 98 99 std::string getPGOFuncName(const Function &F) { 100 return getPGOFuncName(F.getName(), F.getLinkage(), F.getParent()->getName()); 101 } 102 103 GlobalVariable *createPGOFuncNameVar(Module &M, 104 GlobalValue::LinkageTypes Linkage, 105 StringRef FuncName) { 106 107 // We generally want to match the function's linkage, but available_externally 108 // and extern_weak both have the wrong semantics, and anything that doesn't 109 // need to link across compilation units doesn't need to be visible at all. 110 if (Linkage == GlobalValue::ExternalWeakLinkage) 111 Linkage = GlobalValue::LinkOnceAnyLinkage; 112 else if (Linkage == GlobalValue::AvailableExternallyLinkage) 113 Linkage = GlobalValue::LinkOnceODRLinkage; 114 else if (Linkage == GlobalValue::InternalLinkage || 115 Linkage == GlobalValue::ExternalLinkage) 116 Linkage = GlobalValue::PrivateLinkage; 117 118 auto *Value = ConstantDataArray::getString(M.getContext(), FuncName, false); 119 auto FuncNameVar = 120 new GlobalVariable(M, Value->getType(), true, Linkage, Value, 121 Twine(getInstrProfNameVarPrefix()) + FuncName); 122 123 // Hide the symbol so that we correctly get a copy for each executable. 124 if (!GlobalValue::isLocalLinkage(FuncNameVar->getLinkage())) 125 FuncNameVar->setVisibility(GlobalValue::HiddenVisibility); 126 127 return FuncNameVar; 128 } 129 130 GlobalVariable *createPGOFuncNameVar(Function &F, StringRef FuncName) { 131 return createPGOFuncNameVar(*F.getParent(), F.getLinkage(), FuncName); 132 } 133 134 namespace IndexedInstrProf { 135 136 uint32_t ValueProfRecord::getHeaderSize(uint32_t NumValueSites) { 137 uint32_t Size = offsetof(ValueProfRecord, SiteCountArray) + 138 sizeof(uint8_t) * NumValueSites; 139 // Round the size to multiple of 8 bytes. 140 Size = (Size + 7) & ~7; 141 return Size; 142 } 143 144 uint32_t ValueProfRecord::getSize(uint32_t NumValueSites, 145 uint32_t NumValueData) { 146 return getHeaderSize(NumValueSites) + 147 sizeof(InstrProfValueData) * NumValueData; 148 } 149 150 void ValueProfRecord::deserializeTo(InstrProfRecord &Record, 151 InstrProfRecord::ValueMapType *VMap) { 152 Record.reserveSites(Kind, NumValueSites); 153 154 InstrProfValueData *ValueData = this->getValueData(); 155 for (uint64_t VSite = 0; VSite < NumValueSites; ++VSite) { 156 uint8_t ValueDataCount = this->SiteCountArray[VSite]; 157 Record.addValueData(Kind, VSite, ValueData, ValueDataCount, VMap); 158 ValueData += ValueDataCount; 159 } 160 } 161 162 void ValueProfRecord::serializeFrom(const InstrProfRecord &Record, 163 uint32_t ValueKind, 164 uint32_t NumValueSites) { 165 Kind = ValueKind; 166 this->NumValueSites = NumValueSites; 167 InstrProfValueData *DstVD = getValueData(); 168 for (uint32_t S = 0; S < NumValueSites; S++) { 169 uint32_t ND = Record.getNumValueDataForSite(ValueKind, S); 170 SiteCountArray[S] = ND; 171 std::unique_ptr<InstrProfValueData[]> SrcVD = 172 Record.getValueForSite(ValueKind, S); 173 for (uint32_t I = 0; I < ND; I++) { 174 DstVD[I] = SrcVD[I]; 175 switch (ValueKind) { 176 case IPVK_IndirectCallTarget: 177 DstVD[I].Value = ComputeHash(HashType, (const char *)DstVD[I].Value); 178 break; 179 default: 180 llvm_unreachable("value kind not handled !"); 181 } 182 } 183 DstVD += ND; 184 } 185 } 186 187 template <class T> 188 static T swapToHostOrder(const unsigned char *&D, support::endianness Orig) { 189 using namespace support; 190 if (Orig == little) 191 return endian::readNext<T, little, unaligned>(D); 192 else 193 return endian::readNext<T, big, unaligned>(D); 194 } 195 196 // For writing/serializing, Old is the host endianness, and New is 197 // byte order intended on disk. For Reading/deserialization, Old 198 // is the on-disk source endianness, and New is the host endianness. 199 void ValueProfRecord::swapBytes(support::endianness Old, 200 support::endianness New) { 201 using namespace support; 202 if (Old == New) 203 return; 204 205 if (getHostEndianness() != Old) { 206 sys::swapByteOrder<uint32_t>(NumValueSites); 207 sys::swapByteOrder<uint32_t>(Kind); 208 } 209 uint32_t ND = getNumValueData(); 210 InstrProfValueData *VD = getValueData(); 211 212 // No need to swap byte array: SiteCountArrray. 213 for (uint32_t I = 0; I < ND; I++) { 214 sys::swapByteOrder<uint64_t>(VD[I].Value); 215 sys::swapByteOrder<uint64_t>(VD[I].Count); 216 } 217 if (getHostEndianness() == Old) { 218 sys::swapByteOrder<uint32_t>(NumValueSites); 219 sys::swapByteOrder<uint32_t>(Kind); 220 } 221 } 222 223 uint32_t ValueProfData::getSize(const InstrProfRecord &Record) { 224 uint32_t TotalSize = sizeof(ValueProfData); 225 uint32_t NumValueKinds = Record.getNumValueKinds(); 226 if (NumValueKinds == 0) 227 return TotalSize; 228 229 for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; Kind++) { 230 uint32_t NumValueSites = Record.getNumValueSites(Kind); 231 if (!NumValueSites) 232 continue; 233 TotalSize += 234 ValueProfRecord::getSize(NumValueSites, Record.getNumValueData(Kind)); 235 } 236 return TotalSize; 237 } 238 239 void ValueProfData::deserializeTo(InstrProfRecord &Record, 240 InstrProfRecord::ValueMapType *VMap) { 241 if (NumValueKinds == 0) 242 return; 243 244 ValueProfRecord *VR = getFirstValueProfRecord(); 245 for (uint32_t K = 0; K < NumValueKinds; K++) { 246 VR->deserializeTo(Record, VMap); 247 VR = VR->getNext(); 248 } 249 } 250 251 static std::unique_ptr<ValueProfData> AllocValueProfData(uint32_t TotalSize) { 252 return std::unique_ptr<ValueProfData>(new (::operator new(TotalSize)) 253 ValueProfData()); 254 } 255 256 std::unique_ptr<ValueProfData> 257 ValueProfData::serializeFrom(const InstrProfRecord &Record) { 258 uint32_t TotalSize = getSize(Record); 259 260 std::unique_ptr<ValueProfData> VPD = AllocValueProfData(TotalSize); 261 262 VPD->TotalSize = TotalSize; 263 VPD->NumValueKinds = Record.getNumValueKinds(); 264 ValueProfRecord *VR = VPD->getFirstValueProfRecord(); 265 for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; Kind++) { 266 uint32_t NumValueSites = Record.getNumValueSites(Kind); 267 if (!NumValueSites) 268 continue; 269 VR->serializeFrom(Record, Kind, NumValueSites); 270 VR = VR->getNext(); 271 } 272 return VPD; 273 } 274 275 ErrorOr<std::unique_ptr<ValueProfData>> 276 ValueProfData::getValueProfData(const unsigned char *D, 277 const unsigned char *const BufferEnd, 278 support::endianness Endianness) { 279 using namespace support; 280 if (D + sizeof(ValueProfData) > BufferEnd) 281 return instrprof_error::truncated; 282 283 const unsigned char *Header = D; 284 uint32_t TotalSize = swapToHostOrder<uint32_t>(Header, Endianness); 285 uint32_t NumValueKinds = swapToHostOrder<uint32_t>(Header, Endianness); 286 287 if (D + TotalSize > BufferEnd) 288 return instrprof_error::too_large; 289 if (NumValueKinds > IPVK_Last + 1) 290 return instrprof_error::malformed; 291 // Total size needs to be mulltiple of quadword size. 292 if (TotalSize % sizeof(uint64_t)) 293 return instrprof_error::malformed; 294 295 std::unique_ptr<ValueProfData> VPD = AllocValueProfData(TotalSize); 296 297 memcpy(VPD.get(), D, TotalSize); 298 // Byte swap. 299 VPD->swapBytesToHost(Endianness); 300 301 // Data integrety check: 302 ValueProfRecord *VR = VPD->getFirstValueProfRecord(); 303 for (uint32_t K = 0; K < VPD->NumValueKinds; K++) { 304 if (VR->Kind > IPVK_Last) 305 return instrprof_error::malformed; 306 VR = VR->getNext(); 307 if ((char *)VR - (char *)VPD.get() > (ptrdiff_t)TotalSize) 308 return instrprof_error::malformed; 309 } 310 311 return std::move(VPD); 312 } 313 314 void ValueProfData::swapBytesToHost(support::endianness Endianness) { 315 using namespace support; 316 if (Endianness == getHostEndianness()) 317 return; 318 319 sys::swapByteOrder<uint32_t>(TotalSize); 320 sys::swapByteOrder<uint32_t>(NumValueKinds); 321 322 ValueProfRecord *VR = getFirstValueProfRecord(); 323 for (uint32_t K = 0; K < NumValueKinds; K++) { 324 VR->swapBytes(Endianness, getHostEndianness()); 325 VR = VR->getNext(); 326 } 327 } 328 329 void ValueProfData::swapBytesFromHost(support::endianness Endianness) { 330 using namespace support; 331 if (Endianness == getHostEndianness()) 332 return; 333 334 ValueProfRecord *VR = getFirstValueProfRecord(); 335 for (uint32_t K = 0; K < NumValueKinds; K++) { 336 ValueProfRecord *NVR = VR->getNext(); 337 VR->swapBytes(getHostEndianness(), Endianness); 338 VR = NVR; 339 } 340 sys::swapByteOrder<uint32_t>(TotalSize); 341 sys::swapByteOrder<uint32_t>(NumValueKinds); 342 } 343 344 ValueProfRecord *ValueProfData::getFirstValueProfRecord() { 345 return reinterpret_cast<ValueProfRecord *>((char *)this + 346 sizeof(ValueProfData)); 347 } 348 349 uint32_t ValueProfRecord::getNumValueData() const { 350 uint32_t NumValueData = 0; 351 for (uint32_t I = 0; I < NumValueSites; I++) 352 NumValueData += SiteCountArray[I]; 353 return NumValueData; 354 } 355 356 ValueProfRecord *ValueProfRecord::getNext() { 357 return reinterpret_cast<ValueProfRecord *>((char *)this + getSize()); 358 } 359 360 InstrProfValueData *ValueProfRecord::getValueData() { 361 return reinterpret_cast<InstrProfValueData *>((char *)this + 362 getHeaderSize(NumValueSites)); 363 } 364 365 } // End of IndexedInstrProf namespace. 366 } 367