10b57cec5SDimitry Andric /*===-- llvm-c/Remarks.h - Remarks Public C Interface -------------*- C -*-===*\ 20b57cec5SDimitry Andric |* *| 30b57cec5SDimitry Andric |* Part of the LLVM Project, under the Apache License v2.0 with LLVM *| 40b57cec5SDimitry Andric |* Exceptions. *| 50b57cec5SDimitry Andric |* See https://llvm.org/LICENSE.txt for license information. *| 60b57cec5SDimitry Andric |* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *| 70b57cec5SDimitry Andric |* *| 80b57cec5SDimitry Andric |*===----------------------------------------------------------------------===*| 90b57cec5SDimitry Andric |* *| 100b57cec5SDimitry Andric |* This header provides a public interface to a remark diagnostics library. *| 110b57cec5SDimitry Andric |* LLVM provides an implementation of this interface. *| 120b57cec5SDimitry Andric |* *| 130b57cec5SDimitry Andric \*===----------------------------------------------------------------------===*/ 140b57cec5SDimitry Andric 150b57cec5SDimitry Andric #ifndef LLVM_C_REMARKS_H 160b57cec5SDimitry Andric #define LLVM_C_REMARKS_H 170b57cec5SDimitry Andric 18*480093f4SDimitry Andric #include "llvm-c/ExternC.h" 190b57cec5SDimitry Andric #include "llvm-c/Types.h" 200b57cec5SDimitry Andric #ifdef __cplusplus 210b57cec5SDimitry Andric #include <cstddef> 220b57cec5SDimitry Andric #else 230b57cec5SDimitry Andric #include <stddef.h> 240b57cec5SDimitry Andric #endif /* !defined(__cplusplus) */ 250b57cec5SDimitry Andric 26*480093f4SDimitry Andric LLVM_C_EXTERN_C_BEGIN 27*480093f4SDimitry Andric 280b57cec5SDimitry Andric /** 290b57cec5SDimitry Andric * @defgroup LLVMCREMARKS Remarks 300b57cec5SDimitry Andric * @ingroup LLVMC 310b57cec5SDimitry Andric * 320b57cec5SDimitry Andric * @{ 330b57cec5SDimitry Andric */ 340b57cec5SDimitry Andric 358bcb0991SDimitry Andric // 0 -> 1: Bitstream remarks support. 368bcb0991SDimitry Andric #define REMARKS_API_VERSION 1 370b57cec5SDimitry Andric 380b57cec5SDimitry Andric /** 390b57cec5SDimitry Andric * The type of the emitted remark. 400b57cec5SDimitry Andric */ 410b57cec5SDimitry Andric enum LLVMRemarkType { 420b57cec5SDimitry Andric LLVMRemarkTypeUnknown, 430b57cec5SDimitry Andric LLVMRemarkTypePassed, 440b57cec5SDimitry Andric LLVMRemarkTypeMissed, 450b57cec5SDimitry Andric LLVMRemarkTypeAnalysis, 460b57cec5SDimitry Andric LLVMRemarkTypeAnalysisFPCommute, 470b57cec5SDimitry Andric LLVMRemarkTypeAnalysisAliasing, 480b57cec5SDimitry Andric LLVMRemarkTypeFailure 490b57cec5SDimitry Andric }; 500b57cec5SDimitry Andric 510b57cec5SDimitry Andric /** 520b57cec5SDimitry Andric * String containing a buffer and a length. The buffer is not guaranteed to be 530b57cec5SDimitry Andric * zero-terminated. 540b57cec5SDimitry Andric * 550b57cec5SDimitry Andric * \since REMARKS_API_VERSION=0 560b57cec5SDimitry Andric */ 570b57cec5SDimitry Andric typedef struct LLVMRemarkOpaqueString *LLVMRemarkStringRef; 580b57cec5SDimitry Andric 590b57cec5SDimitry Andric /** 600b57cec5SDimitry Andric * Returns the buffer holding the string. 610b57cec5SDimitry Andric * 620b57cec5SDimitry Andric * \since REMARKS_API_VERSION=0 630b57cec5SDimitry Andric */ 640b57cec5SDimitry Andric extern const char *LLVMRemarkStringGetData(LLVMRemarkStringRef String); 650b57cec5SDimitry Andric 660b57cec5SDimitry Andric /** 670b57cec5SDimitry Andric * Returns the size of the string. 680b57cec5SDimitry Andric * 690b57cec5SDimitry Andric * \since REMARKS_API_VERSION=0 700b57cec5SDimitry Andric */ 710b57cec5SDimitry Andric extern uint32_t LLVMRemarkStringGetLen(LLVMRemarkStringRef String); 720b57cec5SDimitry Andric 730b57cec5SDimitry Andric /** 740b57cec5SDimitry Andric * DebugLoc containing File, Line and Column. 750b57cec5SDimitry Andric * 760b57cec5SDimitry Andric * \since REMARKS_API_VERSION=0 770b57cec5SDimitry Andric */ 780b57cec5SDimitry Andric typedef struct LLVMRemarkOpaqueDebugLoc *LLVMRemarkDebugLocRef; 790b57cec5SDimitry Andric 800b57cec5SDimitry Andric /** 810b57cec5SDimitry Andric * Return the path to the source file for a debug location. 820b57cec5SDimitry Andric * 830b57cec5SDimitry Andric * \since REMARKS_API_VERSION=0 840b57cec5SDimitry Andric */ 850b57cec5SDimitry Andric extern LLVMRemarkStringRef 860b57cec5SDimitry Andric LLVMRemarkDebugLocGetSourceFilePath(LLVMRemarkDebugLocRef DL); 870b57cec5SDimitry Andric 880b57cec5SDimitry Andric /** 890b57cec5SDimitry Andric * Return the line in the source file for a debug location. 900b57cec5SDimitry Andric * 910b57cec5SDimitry Andric * \since REMARKS_API_VERSION=0 920b57cec5SDimitry Andric */ 930b57cec5SDimitry Andric extern uint32_t LLVMRemarkDebugLocGetSourceLine(LLVMRemarkDebugLocRef DL); 940b57cec5SDimitry Andric 950b57cec5SDimitry Andric /** 960b57cec5SDimitry Andric * Return the column in the source file for a debug location. 970b57cec5SDimitry Andric * 980b57cec5SDimitry Andric * \since REMARKS_API_VERSION=0 990b57cec5SDimitry Andric */ 1000b57cec5SDimitry Andric extern uint32_t LLVMRemarkDebugLocGetSourceColumn(LLVMRemarkDebugLocRef DL); 1010b57cec5SDimitry Andric 1020b57cec5SDimitry Andric /** 1030b57cec5SDimitry Andric * Element of the "Args" list. The key might give more information about what 1040b57cec5SDimitry Andric * the semantics of the value are, e.g. "Callee" will tell you that the value 1050b57cec5SDimitry Andric * is a symbol that names a function. 1060b57cec5SDimitry Andric * 1070b57cec5SDimitry Andric * \since REMARKS_API_VERSION=0 1080b57cec5SDimitry Andric */ 1090b57cec5SDimitry Andric typedef struct LLVMRemarkOpaqueArg *LLVMRemarkArgRef; 1100b57cec5SDimitry Andric 1110b57cec5SDimitry Andric /** 1120b57cec5SDimitry Andric * Returns the key of an argument. The key defines what the value is, and the 1130b57cec5SDimitry Andric * same key can appear multiple times in the list of arguments. 1140b57cec5SDimitry Andric * 1150b57cec5SDimitry Andric * \since REMARKS_API_VERSION=0 1160b57cec5SDimitry Andric */ 1170b57cec5SDimitry Andric extern LLVMRemarkStringRef LLVMRemarkArgGetKey(LLVMRemarkArgRef Arg); 1180b57cec5SDimitry Andric 1190b57cec5SDimitry Andric /** 1200b57cec5SDimitry Andric * Returns the value of an argument. This is a string that can contain newlines. 1210b57cec5SDimitry Andric * 1220b57cec5SDimitry Andric * \since REMARKS_API_VERSION=0 1230b57cec5SDimitry Andric */ 1240b57cec5SDimitry Andric extern LLVMRemarkStringRef LLVMRemarkArgGetValue(LLVMRemarkArgRef Arg); 1250b57cec5SDimitry Andric 1260b57cec5SDimitry Andric /** 1270b57cec5SDimitry Andric * Returns the debug location that is attached to the value of this argument. 1280b57cec5SDimitry Andric * 1290b57cec5SDimitry Andric * If there is no debug location, the return value will be `NULL`. 1300b57cec5SDimitry Andric * 1310b57cec5SDimitry Andric * \since REMARKS_API_VERSION=0 1320b57cec5SDimitry Andric */ 1330b57cec5SDimitry Andric extern LLVMRemarkDebugLocRef LLVMRemarkArgGetDebugLoc(LLVMRemarkArgRef Arg); 1340b57cec5SDimitry Andric 1350b57cec5SDimitry Andric /** 1360b57cec5SDimitry Andric * A remark emitted by the compiler. 1370b57cec5SDimitry Andric * 1380b57cec5SDimitry Andric * \since REMARKS_API_VERSION=0 1390b57cec5SDimitry Andric */ 1400b57cec5SDimitry Andric typedef struct LLVMRemarkOpaqueEntry *LLVMRemarkEntryRef; 1410b57cec5SDimitry Andric 1420b57cec5SDimitry Andric /** 1430b57cec5SDimitry Andric * Free the resources used by the remark entry. 1440b57cec5SDimitry Andric * 1450b57cec5SDimitry Andric * \since REMARKS_API_VERSION=0 1460b57cec5SDimitry Andric */ 1470b57cec5SDimitry Andric extern void LLVMRemarkEntryDispose(LLVMRemarkEntryRef Remark); 1480b57cec5SDimitry Andric 1490b57cec5SDimitry Andric /** 1500b57cec5SDimitry Andric * The type of the remark. For example, it can allow users to only keep the 1510b57cec5SDimitry Andric * missed optimizations from the compiler. 1520b57cec5SDimitry Andric * 1530b57cec5SDimitry Andric * \since REMARKS_API_VERSION=0 1540b57cec5SDimitry Andric */ 1550b57cec5SDimitry Andric extern enum LLVMRemarkType LLVMRemarkEntryGetType(LLVMRemarkEntryRef Remark); 1560b57cec5SDimitry Andric 1570b57cec5SDimitry Andric /** 1580b57cec5SDimitry Andric * Get the name of the pass that emitted this remark. 1590b57cec5SDimitry Andric * 1600b57cec5SDimitry Andric * \since REMARKS_API_VERSION=0 1610b57cec5SDimitry Andric */ 1620b57cec5SDimitry Andric extern LLVMRemarkStringRef 1630b57cec5SDimitry Andric LLVMRemarkEntryGetPassName(LLVMRemarkEntryRef Remark); 1640b57cec5SDimitry Andric 1650b57cec5SDimitry Andric /** 1660b57cec5SDimitry Andric * Get an identifier of the remark. 1670b57cec5SDimitry Andric * 1680b57cec5SDimitry Andric * \since REMARKS_API_VERSION=0 1690b57cec5SDimitry Andric */ 1700b57cec5SDimitry Andric extern LLVMRemarkStringRef 1710b57cec5SDimitry Andric LLVMRemarkEntryGetRemarkName(LLVMRemarkEntryRef Remark); 1720b57cec5SDimitry Andric 1730b57cec5SDimitry Andric /** 1740b57cec5SDimitry Andric * Get the name of the function being processed when the remark was emitted. 1750b57cec5SDimitry Andric * 1760b57cec5SDimitry Andric * \since REMARKS_API_VERSION=0 1770b57cec5SDimitry Andric */ 1780b57cec5SDimitry Andric extern LLVMRemarkStringRef 1790b57cec5SDimitry Andric LLVMRemarkEntryGetFunctionName(LLVMRemarkEntryRef Remark); 1800b57cec5SDimitry Andric 1810b57cec5SDimitry Andric /** 1820b57cec5SDimitry Andric * Returns the debug location that is attached to this remark. 1830b57cec5SDimitry Andric * 1840b57cec5SDimitry Andric * If there is no debug location, the return value will be `NULL`. 1850b57cec5SDimitry Andric * 1860b57cec5SDimitry Andric * \since REMARKS_API_VERSION=0 1870b57cec5SDimitry Andric */ 1880b57cec5SDimitry Andric extern LLVMRemarkDebugLocRef 1890b57cec5SDimitry Andric LLVMRemarkEntryGetDebugLoc(LLVMRemarkEntryRef Remark); 1900b57cec5SDimitry Andric 1910b57cec5SDimitry Andric /** 1920b57cec5SDimitry Andric * Return the hotness of the remark. 1930b57cec5SDimitry Andric * 1940b57cec5SDimitry Andric * A hotness of `0` means this value is not set. 1950b57cec5SDimitry Andric * 1960b57cec5SDimitry Andric * \since REMARKS_API_VERSION=0 1970b57cec5SDimitry Andric */ 1980b57cec5SDimitry Andric extern uint64_t LLVMRemarkEntryGetHotness(LLVMRemarkEntryRef Remark); 1990b57cec5SDimitry Andric 2000b57cec5SDimitry Andric /** 2010b57cec5SDimitry Andric * The number of arguments the remark holds. 2020b57cec5SDimitry Andric * 2030b57cec5SDimitry Andric * \since REMARKS_API_VERSION=0 2040b57cec5SDimitry Andric */ 2050b57cec5SDimitry Andric extern uint32_t LLVMRemarkEntryGetNumArgs(LLVMRemarkEntryRef Remark); 2060b57cec5SDimitry Andric 2070b57cec5SDimitry Andric /** 2080b57cec5SDimitry Andric * Get a new iterator to iterate over a remark's argument. 2090b57cec5SDimitry Andric * 2100b57cec5SDimitry Andric * If there are no arguments in \p Remark, the return value will be `NULL`. 2110b57cec5SDimitry Andric * 2120b57cec5SDimitry Andric * The lifetime of the returned value is bound to the lifetime of \p Remark. 2130b57cec5SDimitry Andric * 2140b57cec5SDimitry Andric * \since REMARKS_API_VERSION=0 2150b57cec5SDimitry Andric */ 2160b57cec5SDimitry Andric extern LLVMRemarkArgRef LLVMRemarkEntryGetFirstArg(LLVMRemarkEntryRef Remark); 2170b57cec5SDimitry Andric 2180b57cec5SDimitry Andric /** 2190b57cec5SDimitry Andric * Get the next argument in \p Remark from the position of \p It. 2200b57cec5SDimitry Andric * 2210b57cec5SDimitry Andric * Returns `NULL` if there are no more arguments available. 2220b57cec5SDimitry Andric * 2230b57cec5SDimitry Andric * The lifetime of the returned value is bound to the lifetime of \p Remark. 2240b57cec5SDimitry Andric * 2250b57cec5SDimitry Andric * \since REMARKS_API_VERSION=0 2260b57cec5SDimitry Andric */ 2270b57cec5SDimitry Andric extern LLVMRemarkArgRef LLVMRemarkEntryGetNextArg(LLVMRemarkArgRef It, 2280b57cec5SDimitry Andric LLVMRemarkEntryRef Remark); 2290b57cec5SDimitry Andric 2300b57cec5SDimitry Andric typedef struct LLVMRemarkOpaqueParser *LLVMRemarkParserRef; 2310b57cec5SDimitry Andric 2320b57cec5SDimitry Andric /** 2330b57cec5SDimitry Andric * Creates a remark parser that can be used to parse the buffer located in \p 2340b57cec5SDimitry Andric * Buf of size \p Size bytes. 2350b57cec5SDimitry Andric * 2360b57cec5SDimitry Andric * \p Buf cannot be `NULL`. 2370b57cec5SDimitry Andric * 2380b57cec5SDimitry Andric * This function should be paired with LLVMRemarkParserDispose() to avoid 2390b57cec5SDimitry Andric * leaking resources. 2400b57cec5SDimitry Andric * 2410b57cec5SDimitry Andric * \since REMARKS_API_VERSION=0 2420b57cec5SDimitry Andric */ 2430b57cec5SDimitry Andric extern LLVMRemarkParserRef LLVMRemarkParserCreateYAML(const void *Buf, 2440b57cec5SDimitry Andric uint64_t Size); 2450b57cec5SDimitry Andric 2460b57cec5SDimitry Andric /** 2478bcb0991SDimitry Andric * Creates a remark parser that can be used to parse the buffer located in \p 2488bcb0991SDimitry Andric * Buf of size \p Size bytes. 2498bcb0991SDimitry Andric * 2508bcb0991SDimitry Andric * \p Buf cannot be `NULL`. 2518bcb0991SDimitry Andric * 2528bcb0991SDimitry Andric * This function should be paired with LLVMRemarkParserDispose() to avoid 2538bcb0991SDimitry Andric * leaking resources. 2548bcb0991SDimitry Andric * 2558bcb0991SDimitry Andric * \since REMARKS_API_VERSION=1 2568bcb0991SDimitry Andric */ 2578bcb0991SDimitry Andric extern LLVMRemarkParserRef LLVMRemarkParserCreateBitstream(const void *Buf, 2588bcb0991SDimitry Andric uint64_t Size); 2598bcb0991SDimitry Andric 2608bcb0991SDimitry Andric /** 2610b57cec5SDimitry Andric * Returns the next remark in the file. 2620b57cec5SDimitry Andric * 2630b57cec5SDimitry Andric * The value pointed to by the return value needs to be disposed using a call to 2640b57cec5SDimitry Andric * LLVMRemarkEntryDispose(). 2650b57cec5SDimitry Andric * 2660b57cec5SDimitry Andric * All the entries in the returned value that are of LLVMRemarkStringRef type 2670b57cec5SDimitry Andric * will become invalidated once a call to LLVMRemarkParserDispose is made. 2680b57cec5SDimitry Andric * 2690b57cec5SDimitry Andric * If the parser reaches the end of the buffer, the return value will be `NULL`. 2700b57cec5SDimitry Andric * 2710b57cec5SDimitry Andric * In the case of an error, the return value will be `NULL`, and: 2720b57cec5SDimitry Andric * 2730b57cec5SDimitry Andric * 1) LLVMRemarkParserHasError() will return `1`. 2740b57cec5SDimitry Andric * 2750b57cec5SDimitry Andric * 2) LLVMRemarkParserGetErrorMessage() will return a descriptive error 2760b57cec5SDimitry Andric * message. 2770b57cec5SDimitry Andric * 2780b57cec5SDimitry Andric * An error may occur if: 2790b57cec5SDimitry Andric * 2800b57cec5SDimitry Andric * 1) An argument is invalid. 2810b57cec5SDimitry Andric * 2820b57cec5SDimitry Andric * 2) There is a parsing error. This can occur on things like malformed YAML. 2830b57cec5SDimitry Andric * 2840b57cec5SDimitry Andric * 3) There is a Remark semantic error. This can occur on well-formed files with 2850b57cec5SDimitry Andric * missing or extra fields. 2860b57cec5SDimitry Andric * 2870b57cec5SDimitry Andric * Here is a quick example of the usage: 2880b57cec5SDimitry Andric * 2890b57cec5SDimitry Andric * ``` 2900b57cec5SDimitry Andric * LLVMRemarkParserRef Parser = LLVMRemarkParserCreateYAML(Buf, Size); 2910b57cec5SDimitry Andric * LLVMRemarkEntryRef Remark = NULL; 2920b57cec5SDimitry Andric * while ((Remark = LLVMRemarkParserGetNext(Parser))) { 2930b57cec5SDimitry Andric * // use Remark 2940b57cec5SDimitry Andric * LLVMRemarkEntryDispose(Remark); // Release memory. 2950b57cec5SDimitry Andric * } 2960b57cec5SDimitry Andric * bool HasError = LLVMRemarkParserHasError(Parser); 2970b57cec5SDimitry Andric * LLVMRemarkParserDispose(Parser); 2980b57cec5SDimitry Andric * ``` 2990b57cec5SDimitry Andric * 3000b57cec5SDimitry Andric * \since REMARKS_API_VERSION=0 3010b57cec5SDimitry Andric */ 3020b57cec5SDimitry Andric extern LLVMRemarkEntryRef LLVMRemarkParserGetNext(LLVMRemarkParserRef Parser); 3030b57cec5SDimitry Andric 3040b57cec5SDimitry Andric /** 3050b57cec5SDimitry Andric * Returns `1` if the parser encountered an error while parsing the buffer. 3060b57cec5SDimitry Andric * 3070b57cec5SDimitry Andric * \since REMARKS_API_VERSION=0 3080b57cec5SDimitry Andric */ 3090b57cec5SDimitry Andric extern LLVMBool LLVMRemarkParserHasError(LLVMRemarkParserRef Parser); 3100b57cec5SDimitry Andric 3110b57cec5SDimitry Andric /** 3120b57cec5SDimitry Andric * Returns a null-terminated string containing an error message. 3130b57cec5SDimitry Andric * 3140b57cec5SDimitry Andric * In case of no error, the result is `NULL`. 3150b57cec5SDimitry Andric * 3160b57cec5SDimitry Andric * The memory of the string is bound to the lifetime of \p Parser. If 3170b57cec5SDimitry Andric * LLVMRemarkParserDispose() is called, the memory of the string will be 3180b57cec5SDimitry Andric * released. 3190b57cec5SDimitry Andric * 3200b57cec5SDimitry Andric * \since REMARKS_API_VERSION=0 3210b57cec5SDimitry Andric */ 3220b57cec5SDimitry Andric extern const char *LLVMRemarkParserGetErrorMessage(LLVMRemarkParserRef Parser); 3230b57cec5SDimitry Andric 3240b57cec5SDimitry Andric /** 3250b57cec5SDimitry Andric * Releases all the resources used by \p Parser. 3260b57cec5SDimitry Andric * 3270b57cec5SDimitry Andric * \since REMARKS_API_VERSION=0 3280b57cec5SDimitry Andric */ 3290b57cec5SDimitry Andric extern void LLVMRemarkParserDispose(LLVMRemarkParserRef Parser); 3300b57cec5SDimitry Andric 3310b57cec5SDimitry Andric /** 3320b57cec5SDimitry Andric * Returns the version of the remarks library. 3330b57cec5SDimitry Andric * 3340b57cec5SDimitry Andric * \since REMARKS_API_VERSION=0 3350b57cec5SDimitry Andric */ 3360b57cec5SDimitry Andric extern uint32_t LLVMRemarkVersion(void); 3370b57cec5SDimitry Andric 3380b57cec5SDimitry Andric /** 3390b57cec5SDimitry Andric * @} // endgoup LLVMCREMARKS 3400b57cec5SDimitry Andric */ 3410b57cec5SDimitry Andric 342*480093f4SDimitry Andric LLVM_C_EXTERN_C_END 3430b57cec5SDimitry Andric 3440b57cec5SDimitry Andric #endif /* LLVM_C_REMARKS_H */ 345