Skip to content

Commit 8cbc7b6

Browse files
authored
Merge pull request #78 from Sparrow-lang/profiling
Add tracy profiling to the SparrowCompiler
2 parents 8b1533a + c08defe commit 8cbc7b6

22 files changed

+378
-24
lines changed

.gitmodules

Lines changed: 4 additions & 0 deletions
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

Lines changed: 9 additions & 1 deletion
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

Lines changed: 3 additions & 1 deletion
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

Lines changed: 24 additions & 5 deletions
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

Lines changed: 34 additions & 10 deletions
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

Lines changed: 3 additions & 0 deletions
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

Lines changed: 9 additions & 0 deletions
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

Lines changed: 8 additions & 0 deletions
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

Lines changed: 104 additions & 0 deletions
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

0 commit comments

Comments
 (0)