Skip to content

Commit c08defe

Browse files
committed
Add tracy profiling to the SparrowCompiler
Add tracy repository as external Add Profiling options for Sparrow. If enabled, one can capture profiling data while running the compiler. Add scopes for most important operations (including Nest_setContext, Nest_computeType and Nest_semanticCheck). Make the compiler used optimized version of the parser.
1 parent 8b1533a commit c08defe

22 files changed

+378
-24
lines changed

.gitmodules

+4
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,7 @@
22
path = externals/rapidcheck
33
url = https://github.com/emil-e/rapidcheck.git
44
branch = master
5+
[submodule "externals/tracy"]
6+
path = externals/tracy
7+
url = https://[email protected]/wolfpld/tracy.git
8+
branch = master

CMakeLists.txt

+9-1
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/src/SparrowCompiler/VersionInfo.h.in
4848
# User passed compilation options
4949
option(BOOTSTRAP_SPARROW "Use system-wide SparrowCompiler to compile Sparrow files needed for the compiler" OFF)
5050
message(STATUS "BOOTSTRAP_SPARROW: ${BOOTSTRAP_SPARROW}")
51+
option(SPARROW_PROFILING "Enable Tracy integration into Sparrow compiler" OFF)
52+
message(STATUS "SPARROW_PROFILING: ${SPARROW_PROFILING}")
5153

5254
# Where to output the results of the compilation
5355
set(OutDir ${CMAKE_CURRENT_SOURCE_DIR}/build/bin)
@@ -91,12 +93,18 @@ if(MSVC)
9193
add_definitions( -D_SCL_SECURE_NO_WARNINGS -D_CRT_SECURE_NO_DEPRECATE )
9294
else()
9395
add_definitions( -D__STDC_LIMIT_MACROS=1 )
94-
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11" )
9596
# set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address" )
9697
add_definitions( -Wall ) # All warnings...
9798
add_definitions( -Wno-deprecated ) # ... and except deprecated functions
9899
endif()
99100

101+
if(SPARROW_PROFILING)
102+
add_definitions( -DSPARROW_PROFILING=1 )
103+
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17" )
104+
else()
105+
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11" )
106+
endif()
107+
100108
# Add our macros
101109
include(Macros.cmake)
102110

Macros.cmake

+3-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON)
88
find_program(SPARROW_EXECUTABLE_EXT NAMES SparrowCompiler DOC "path to the SparrowCompiler executable (external)")
99
# Try to find an external llc executable
1010
find_program(LLC_EXECUTABLE_EXT NAMES spr-llc "${LLVM_TOOLS_BINARY_DIR}/llc" DOC "path to the llc executable (external)")
11+
# Try to find an external opt executable
12+
find_program(OPT_EXECUTABLE_EXT NAMES spr-opt "${LLVM_TOOLS_BINARY_DIR}/opt" DOC "path to the opt executable (external)")
1113

1214
MACRO(GROUP_NAME_FROM_PATH filePath resultVar)
1315
IF(MSVC OR APPLE)
@@ -104,7 +106,7 @@ macro(LLVMASM_TARGET Name Input Output)
104106
endif()
105107

106108
add_custom_command(OUTPUT ${LLVMASM_TARGET_outputs}
107-
COMMAND ${LLC_EXECUTABLE_EXT} --filetype=obj ${LLVMASM_EXECUTABLE_opts} -o ${Output} ${Input}
109+
COMMAND ${OPT_EXECUTABLE_EXT} -O2 ${Input} | ${LLC_EXECUTABLE_EXT} --filetype=obj ${LLVMASM_EXECUTABLE_opts} -o ${Output}
108110
VERBATIM
109111
DEPENDS ${Input} ${LLVMASM_TARGET_ARG_DEPENDS}
110112
COMMENT "[LLVM][${Name}] Building object ${Output}"

externals/tracy

Submodule tracy added at c0d0d0d

src/LLVMBackend/CtModule.cpp

+24-5
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "Nest/Api/Compiler.h"
1616
#include "Nest/Utils/CompilerSettings.hpp"
1717
#include "Nest/Utils/Diagnostic.hpp"
18+
#include "Nest/Utils/Profiling.h"
1819
#include "Nest/Utils/CompilerStats.hpp"
1920
#include "Nest/Utils/cppif/StringRef.hpp"
2021

@@ -140,6 +141,7 @@ void CtModule::recreateModule() {
140141
}
141142

142143
void CtModule::syncModule() {
144+
PROFILING_ZONE();
143145
if (!llvmModule_->empty() || !llvmModule_->global_empty()) {
144146
// Uncomment this for debugging
145147
// llvmModule_->dump();
@@ -179,6 +181,8 @@ void CtModule::ctProcessBackendCode(Node* node) {
179181
}
180182

181183
Node* CtModule::ctEvaluateExpression(Node* node) {
184+
PROFILING_ZONE_TEXT(Nest_toStringEx(node));
185+
182186
ASSERT(llvmModule_);
183187

184188
// Gather statistics if requested
@@ -284,10 +288,17 @@ Node* CtModule::ctEvaluateExpression(Node* node) {
284288
// - transform this into a function pointer that receives the output as a parameter
285289
// - call the function, to fill up the data buffer
286290
using FunType = void (*)(const char*);
287-
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-cstyle-cast)
288-
auto fptr = (FunType)llvmExecutionEngine_->getFunctionAddress(funName);
291+
FunType fptr;
292+
{
293+
PROFILING_ZONE_NAMED("CT getFunctionAddress");
294+
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-cstyle-cast)
295+
fptr = (FunType)llvmExecutionEngine_->getFunctionAddress(funName);
296+
}
289297
ASSERT(fptr);
290-
fptr(dataBuffer.begin);
298+
{
299+
PROFILING_ZONE_NAMED("CT exec");
300+
fptr(dataBuffer.begin);
301+
}
291302

292303
// Create a CtValue containing the data resulted from expression evaluation
293304
Type t = node->type;
@@ -301,9 +312,17 @@ Node* CtModule::ctEvaluateExpression(Node* node) {
301312
// - call the function
302313
using FunType = void (*)();
303314
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-cstyle-cast)
304-
auto fptr = (FunType)llvmExecutionEngine_->getFunctionAddress(funName);
315+
FunType fptr;
316+
{
317+
PROFILING_ZONE_NAMED("CT getFunctionAddress");
318+
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-cstyle-cast)
319+
fptr = (FunType)llvmExecutionEngine_->getFunctionAddress(funName);
320+
}
305321
ASSERT(fptr);
306-
fptr();
322+
{
323+
PROFILING_ZONE_NAMED("CT exec");
324+
fptr();
325+
}
307326

308327
// Create a Nop operation for return
309328
res = Feather_mkNop(node->location);

src/LLVMBackend/Generator.cpp

+34-10
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "Nest/Api/Compiler.h"
77
#include "Nest/Utils/CompilerSettings.hpp"
88
#include "Nest/Utils/CompilerStats.hpp"
9+
#include "Nest/Utils/Profiling.h"
910

1011
#include <boost/filesystem.hpp>
1112

@@ -49,6 +50,13 @@ string replaceExtension(
4950
/// Run the command with the given arguments
5051
/// The command should be the first in the list of arguments
5152
void runCmd(const vector<string>& args) {
53+
#if SPARROW_PROFILING
54+
std::ostringstream ossProfiling;
55+
for (const string& arg : args)
56+
ossProfiling << arg << " ";
57+
PROFILING_ZONE_TEXT(ossProfiling.str().c_str());
58+
#endif
59+
5260
ASSERT(args.size() > 0);
5361

5462
const auto& s = *Nest_compilerSettings();
@@ -84,6 +92,8 @@ void runCmd(const vector<string>& args) {
8492

8593
/// Write the given LLVM module, as a bitcode to disk
8694
void writeBitcodeFile(const Module& module, const string& outputFilename) {
95+
PROFILING_ZONE();
96+
8797
error_code errorInfo;
8898
unique_ptr<TOOL_OUPUT_FILE_CLS> outFile(
8999
new TOOL_OUPUT_FILE_CLS(outputFilename.c_str(), errorInfo, sys::fs::OpenFlags::F_None));
@@ -98,6 +108,8 @@ void writeBitcodeFile(const Module& module, const string& outputFilename) {
98108

99109
/// Write the given LLVM module, as an assembly file to disk
100110
void writeAssemblyFile(const Module& module, const string& outputFilename) {
111+
PROFILING_ZONE();
112+
101113
error_code errorInfo;
102114
unique_ptr<TOOL_OUPUT_FILE_CLS> outFile(
103115
new TOOL_OUPUT_FILE_CLS(outputFilename.c_str(), errorInfo, sys::fs::OpenFlags::F_None));
@@ -185,13 +197,17 @@ void generateNativeObjGCC(
185197
} // namespace
186198

187199
void LLVMB::generateRtAssembly(const llvm::Module& module) {
200+
PROFILING_ZONE();
201+
188202
const auto& s = *Nest_compilerSettings();
189203

190204
string filename = replaceExtension(s.output_, s.output_, ".ll");
191205
writeAssemblyFile(module, filename);
192206
}
193207

194208
void LLVMB::generateCtAssembly(const llvm::Module& module) {
209+
PROFILING_ZONE();
210+
195211
const auto& s = *Nest_compilerSettings();
196212

197213
// Safety check
@@ -229,22 +245,30 @@ void LLVMB::link(const vector<llvm::Module*>& inputs, const string& outFilename)
229245
// the sourcecodes into one big module, and perform those operations here
230246

231247
// Link all the input modules to a single module
232-
// we desotry all the modules in this process
248+
// we destroy all the modules in this process
233249
if (inputs.empty())
234250
REP_INTERNAL(NOLOC, "At least one bitcode needs to be passed to the linker");
235251
llvm::Module* compositeModule = inputs[0];
236-
llvm::Linker liner(*compositeModule);
237-
for (size_t i = 1; i < inputs.size(); ++i) {
238-
unique_ptr<llvm::Module> mod(inputs[i]);
239-
if (liner.linkInModule(move(mod), llvm::Linker::OverrideFromSrc))
240-
REP_INTERNAL(NOLOC, "Link error");
252+
{
253+
PROFILING_ZONE_NAMED("linking modules")
254+
255+
llvm::Linker linker(*compositeModule);
256+
for (size_t i = 1; i < inputs.size(); ++i) {
257+
unique_ptr<llvm::Module> mod(inputs[i]);
258+
if (linker.linkInModule(move(mod), llvm::Linker::OverrideFromSrc))
259+
REP_INTERNAL(NOLOC, "Link error");
260+
}
241261
}
242262

243263
// Verify the module
244-
string err;
245-
raw_string_ostream errStream(err);
246-
if (verifyModule(*compositeModule, &errStream))
247-
REP_INTERNAL(NOLOC, "LLVM Verification failed for generated program: %1%") % err;
264+
{
265+
PROFILING_ZONE_NAMED("verifying composite module")
266+
267+
string err;
268+
raw_string_ostream errStream(err);
269+
if (verifyModule(*compositeModule, &errStream))
270+
REP_INTERNAL(NOLOC, "LLVM Verification failed for generated program: %1%") % err;
271+
}
248272

249273
bool shouldOptimize = !s.optimizerArgs_.empty() || s.optimizationLevel_ != "0";
250274

src/LLVMBackend/Tr/PrepareTranslate.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <Nest/Api/SourceCode.h>
99
#include <Nest/Utils/cppif/NodeUtils.hpp>
1010
#include <Nest/Utils/Diagnostic.hpp>
11+
#include "Nest/Utils/Profiling.h"
1112
#include <Feather/Api/Feather.h>
1213

1314
using namespace LLVMB;
@@ -28,6 +29,8 @@ bool isDecl(Node* node) {
2829
} // namespace
2930

3031
void Tr::prepareTranslate(Node* node, GlobalContext& ctx) {
32+
// PROFILING_ZONE();
33+
3134
if (!node)
3235
return;
3336

src/Nest/Api/NodeKindRegistrar.h

+9
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#pragma once
22

33
#include "TypeRef.h"
4+
#include "Nest/Utils/ProfilingFwd.h"
45

56
#ifdef __cplusplus
67
extern "C" {
@@ -33,6 +34,14 @@ FToString Nest_getToStringFun(int nodeKind);
3334
//! Resets the registered node kinds
3435
void Nest_resetRegisteredNodeKinds();
3536

37+
#if SPARROW_PROFILING
38+
39+
const Nest_Profiling_LocType* Nest_Profiling_getSetContextLoc(int nodeKind);
40+
const Nest_Profiling_LocType* Nest_Profiling_getComputeTypeLoc(int nodeKind);
41+
const Nest_Profiling_LocType* Nest_Profiling_getSemanticCheckLoc(int nodeKind);
42+
43+
#endif
44+
3645
#ifdef __cplusplus
3746
}
3847
#endif

src/Nest/CMakeLists.txt

+8
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,15 @@ SET(sourceFiles
6969
"src/Utils/cppif/StringRef.cpp"
7070
"src/Utils/cppif/Type.cpp"
7171
"src/Utils/cppif/TypeWithStorage.cpp"
72+
7273
)
74+
if(SPARROW_PROFILING)
75+
SET(sourceFiles
76+
${sourceFiles}
77+
"src/Utils/Profiling.cpp"
78+
)
79+
add_definitions( -DSPARROW_PROFILING=1 )
80+
endif()
7381

7482
# Project settings
7583
INCLUDE_DIRECTORIES( "." )

src/Nest/Utils/Profiling.h

+104
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
#pragma once
2+
3+
#include "ProfilingFwd.h"
4+
5+
#if SPARROW_PROFILING
6+
7+
#define TRACY_ENABLE 1
8+
9+
#ifdef __cplusplus
10+
11+
////////////////////////////////////////////////////////////////////////////////
12+
// C++ profiling definitions
13+
14+
#include "../../../externals/tracy/Tracy.hpp"
15+
16+
#include "Nest/Api/StringRef.h"
17+
18+
#define PROFILING_ZONE() ZoneScoped
19+
#define PROFILING_ZONE_NAMED(staticName) ZoneScopedN(staticName)
20+
#define PROFILING_ZONE_TEXT(text) \
21+
ZoneScoped; \
22+
_Nest_Profiling_zoneSetText(___tracy_scoped_zone, text)
23+
#define PROFILING_ZONE_NAMED_TEXT(staticName, text) \
24+
ZoneScopedN(staticName); \
25+
_Nest_Profiling_zoneSetText(___tracy_scoped_zone, text)
26+
#define PROFILING_ZONE_SETTEEXT(text) _Nest_Profiling_zoneSetText(___tracy_scoped_zone, text)
27+
28+
#define PROFILING_PLOT(name, val) tracy::Profiler::PlotData(name, val)
29+
30+
#define PROFILING_MESSAGE_STATIC(staticText) tracy::Profiler::Message(staticText)
31+
#define PROFILING_MESSAGE(text) _Nest_Profiling_message(text)
32+
33+
inline void _Nest_Profiling_zoneSetText(tracy::ScopedZone& zone, const char* text) {
34+
zone.Text(text, strlen(text));
35+
}
36+
inline void _Nest_Profiling_zoneSetText(tracy::ScopedZone& zone, Nest_StringRef text) {
37+
zone.Text(text.begin, text.end - text.begin);
38+
}
39+
40+
inline void _Nest_Profiling_message(const char* text) {
41+
tracy::Profiler::Message(text, strlen(text));
42+
}
43+
inline void _Nest_Profiling_message(Nest_StringRef text) {
44+
tracy::Profiler::Message(text.begin, text.end - text.begin);
45+
}
46+
47+
#else // __cplusplus
48+
49+
////////////////////////////////////////////////////////////////////////////////
50+
// C-only profiling definitions
51+
52+
#include "../../../externals/tracy/TracyC.h"
53+
54+
typedef TracyCZoneCtx Nest_Profiling_ZoneCtx;
55+
56+
#define PROFILING_C_ZONE_BEGIN(ctx) \
57+
static const struct Nest_Profiling_LocType TracyConcat(__tracy_source_location, __LINE__) = { \
58+
NULL, __FUNCTION__, __FILE__, (uint32_t)__LINE__, 0}; \
59+
Nest_Profiling_ZoneCtx ctx = \
60+
___tracy_emit_zone_begin(&TracyConcat(__tracy_source_location, __LINE__), 1);
61+
62+
#define PROFILING_C_ZONE_BEGIN_LOC(ctx, locPtr) \
63+
Nest_Profiling_ZoneCtx ctx = ___tracy_emit_zone_begin(locPtr, 1)
64+
65+
#define PROFILING_C_ZONE_END(ctx) ___tracy_emit_zone_end(ctx)
66+
#define PROFILING_C_ZONE_SETTEEXT(ctx, text) ___tracy_emit_zone_text(ctx, text, strlen(text))
67+
68+
#endif // __cplusplus
69+
70+
////////////////////////////////////////////////////////////////////////////////
71+
// Both C and C++ profiling definitions
72+
73+
#ifdef __cplusplus
74+
extern "C" {
75+
#endif
76+
77+
//! Creates a location type for profiling
78+
const Nest_Profiling_LocType* Nest_Profiling_createLoc(
79+
const char* name, const char* function, const char* file, unsigned line, unsigned color);
80+
81+
#ifdef __cplusplus
82+
}
83+
#endif
84+
85+
#else // SPARROW_PROFILING
86+
87+
////////////////////////////////////////////////////////////////////////////////
88+
// Profiling not enabled
89+
90+
#define PROFILING_ZONE() /*nothing*/
91+
#define PROFILING_ZONE_NAMED(staticName) /*nothing*/
92+
#define PROFILING_ZONE_TEXT(text) /*nothing*/
93+
#define PROFILING_ZONE_NAMED_TEXT(staticName, text) /*nothing*/
94+
#define PROFILING_ZONE_SETTEEXT(text) /*nothing*/
95+
#define PROFILING_PLOT(name, val) /*nothing*/
96+
#define PROFILING_MESSAGE_STATIC(staticText) /*nothing*/
97+
#define PROFILING_MESSAGE(text) /*nothing*/
98+
99+
#define PROFILING_C_ZONE_BEGIN(ctx) /*nothing*/
100+
#define PROFILING_C_ZONE_BEGIN_LOC(ctx, locPtr) /*nothing*/
101+
#define PROFILING_C_ZONE_END(ctx) /*nothing*/
102+
#define PROFILING_C_ZONE_SETTEEXT(ctx, text) /*nothing*/
103+
104+
#endif

src/Nest/Utils/ProfilingFwd.h

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#pragma once
2+
3+
#ifndef SPARROW_PROFILING
4+
#define SPARROW_PROFILING 0
5+
#endif
6+
7+
#if SPARROW_PROFILING
8+
9+
//! Profiling type to store the source location data (from the compiler).
10+
//! Includes zone name, function name, filename, line number and color
11+
typedef struct ___tracy_source_location_data Nest_Profiling_LocType;
12+
13+
#endif

0 commit comments

Comments
 (0)