From e74dacd8141446760aa773abf6098fffff4f57d0 Mon Sep 17 00:00:00 2001 From: Marc Auberer Date: Sun, 16 Jun 2024 02:54:07 +0200 Subject: [PATCH] Add experimental cli flag to generate lifetime markers --- .run/spice run.run.xml | 2 +- docs/docs/cli/build.md | 47 +++++++++++++------------ docs/docs/cli/install.md | 33 ++++++++--------- docs/docs/cli/run.md | 35 +++++++++--------- docs/docs/cli/test.md | 29 +++++++-------- media/test-project/test.spice | 39 ++++++++++++++++++++ src/driver/Driver.cpp | 3 ++ src/driver/Driver.h | 1 + src/irgenerator/GenImplicit.cpp | 12 +++++++ src/irgenerator/IRGenerator.cpp | 7 ++++ src/typechecker/TypeCheckerImplicit.cpp | 2 +- test/TestRunner.cpp | 1 + 12 files changed, 139 insertions(+), 72 deletions(-) diff --git a/.run/spice run.run.xml b/.run/spice run.run.xml index f1152f57e..a89d5de74 100644 --- a/.run/spice run.run.xml +++ b/.run/spice run.run.xml @@ -1,5 +1,5 @@ - + diff --git a/docs/docs/cli/build.md b/docs/docs/cli/build.md index f7433ffb9..84b60d96a 100644 --- a/docs/docs/cli/build.md +++ b/docs/docs/cli/build.md @@ -19,26 +19,27 @@ The `build` subcommand can be used to compile your Spice project to an executabl ## Options You can apply following options to the `build` subcommand: -| Option | Long | Description | -|--------------|----------------------|-----------------------------------------------------------------------------------------------------------------| -| `-d` | `--debug-output` | Print compiler output for debugging. | -| `-cst` | `--dump-cst` | Dump CST as serialized string and SVG image | -| `-ast` | `--dump-ast` | Dump AST as serialized string and SVG image | -| `-symtab` | `--dump-symtab` | Dump serialized symbol tables | -| `-types` | `--dump-types` | Dump all used types | -| `-ir` | `--dump-ir` | Dump LLVM-IR | -| `-s`, `-asm` | `--dump-assembly` | Dump Assembly code | -| `-b`, `-obj` | `--dump-object-file` | Dump object files | -| - | `--dump-to-files` | Redirect all dumps to files instead of printing them to the screen | -| - | `--abort-after-dump` | Abort the compilation process after dumping the first requested resource | -| `-j ` | `--jobs ` | Set number of jobs to parallelize compilation (default is auto) | -| `-t` | `--target` | Target triple for the emitted executable (for cross-compiling).
Format: `---` | -| `-o` | `--output` | Set path for executable output. | -| `-O` | - | Set optimization level.
Valid options: `-O0`, `-O1`, `-O2`, `-O3`, `-Os`, `-Oz` | -| `-m` | `--build-mode` | Controls the build mode. Valid values are `debug`, `release` and `test`. | -| `-lto` | - | Enable link-time-optimization | -| `-g` | `--debug-info` | Generate debug info to debug the executable in GDB, etc. | -| - | `--static` | Produce stand-alone executable by linking statically | -| - | `--no-entry` | Do not require or generate main function (useful for web assembly target) | -| - | `--disable-verifier` | Disable LLVM module and function verification (only recommended for debugging the compiler) | -| - | `--ignore-cache` | Compile always and ignore the compile cache | \ No newline at end of file +| Option | Long | Description | +|--------------|----------------------------|-----------------------------------------------------------------------------------------------------------------| +| `-d` | `--debug-output` | Print compiler output for debugging. | +| `-cst` | `--dump-cst` | Dump CST as serialized string and SVG image | +| `-ast` | `--dump-ast` | Dump AST as serialized string and SVG image | +| `-symtab` | `--dump-symtab` | Dump serialized symbol tables | +| `-types` | `--dump-types` | Dump all used types | +| `-ir` | `--dump-ir` | Dump LLVM-IR | +| `-s`, `-asm` | `--dump-assembly` | Dump Assembly code | +| `-b`, `-obj` | `--dump-object-file` | Dump object files | +| - | `--dump-to-files` | Redirect all dumps to files instead of printing them to the screen | +| - | `--abort-after-dump` | Abort the compilation process after dumping the first requested resource | +| `-j ` | `--jobs ` | Set number of jobs to parallelize compilation (default is auto) | +| `-t` | `--target` | Target triple for the emitted executable (for cross-compiling).
Format: `---` | +| `-o` | `--output` | Set path for executable output. | +| `-O` | - | Set optimization level.
Valid options: `-O0`, `-O1`, `-O2`, `-O3`, `-Os`, `-Oz` | +| `-m` | `--build-mode` | Controls the build mode. Valid values are `debug`, `release` and `test`. | +| `-lto` | - | Enable link-time-optimization | +| `-g` | `--debug-info` | Generate debug info to debug the executable in GDB, etc. | +| - | `--static` | Produce stand-alone executable by linking statically | +| - | `--no-entry` | Do not require or generate main function (useful for web assembly target) | +| - | `--disable-verifier` | Disable LLVM module and function verification (only recommended for debugging the compiler) | +| - | `--ignore-cache` | Compile always and ignore the compile cache | +| - | `--use-lifetime-markers` | Generate lifetime markers to enhance optimizations | \ No newline at end of file diff --git a/docs/docs/cli/install.md b/docs/docs/cli/install.md index b1785d033..e7fc080fa 100644 --- a/docs/docs/cli/install.md +++ b/docs/docs/cli/install.md @@ -19,19 +19,20 @@ The `install` subcommand can be used to compile your Spice project to an executa ## Options You can apply following options to the `install` subcommand: -| Option | Long | Description | -|--------------|----------------------|--------------------------------------------------------------------------------------| -| `-d` | `--debug-output` | Print compiler output for debugging. | -| `-cst` | `--dump-cst` | Dump CST as serialized string and SVG image | -| `-ast` | `--dump-ast` | Dump AST as serialized string and SVG image | -| `-symtab` | `--dump-symtab` | Dump serialized symbol tables | -| `-types` | `--dump-types` | Dump all used types | -| `-ir` | `--dump-ir` | Dump LLVM-IR | -| `-s`, `-asm` | `--dump-assembly` | Dump Assembly code | -| `-b`, `-obj` | `--dump-object-file` | Dump object files | -| `-d` | `--debug-output` | Print compiler output for debugging. | -| `-j ` | `--jobs ` | Set number of jobs to parallelize compilation (Default is auto) | -| `-o` | `--output` | Set path for executable output. | -| `-O` | - | Set optimization level.
Valid options: `-O0`, `-O1`, `-O2`, `-O3`, `-Os`, `-Oz` | -| `-m` | `--build-mode` | Controls the build mode. Valid values are `debug` and `release` | -| - | `--ignore-cache` | Compile always and ignore the compile cache | \ No newline at end of file +| Option | Long | Description | +|--------------|----------------------------|--------------------------------------------------------------------------------------| +| `-d` | `--debug-output` | Print compiler output for debugging. | +| `-cst` | `--dump-cst` | Dump CST as serialized string and SVG image | +| `-ast` | `--dump-ast` | Dump AST as serialized string and SVG image | +| `-symtab` | `--dump-symtab` | Dump serialized symbol tables | +| `-types` | `--dump-types` | Dump all used types | +| `-ir` | `--dump-ir` | Dump LLVM-IR | +| `-s`, `-asm` | `--dump-assembly` | Dump Assembly code | +| `-b`, `-obj` | `--dump-object-file` | Dump object files | +| `-d` | `--debug-output` | Print compiler output for debugging. | +| `-j ` | `--jobs ` | Set number of jobs to parallelize compilation (Default is auto) | +| `-o` | `--output` | Set path for executable output. | +| `-O` | - | Set optimization level.
Valid options: `-O0`, `-O1`, `-O2`, `-O3`, `-Os`, `-Oz` | +| `-m` | `--build-mode` | Controls the build mode. Valid values are `debug` and `release` | +| - | `--ignore-cache` | Compile always and ignore the compile cache | +| - | `--use-lifetime-markers` | Generate lifetime markers to enhance optimizations | \ No newline at end of file diff --git a/docs/docs/cli/run.md b/docs/docs/cli/run.md index 2b2939988..d2f0f3374 100644 --- a/docs/docs/cli/run.md +++ b/docs/docs/cli/run.md @@ -19,20 +19,21 @@ The `run` subcommand can be used to compile your Spice project to an executable ## Options You can apply following options to the `run` subcommand: -| Option | Long | Description | -|--------------|----------------------|---------------------------------------------------------------------------------------------| -| `-d` | `--debug-output` | Print compiler output for debugging. | -| `-cst` | `--dump-cst` | Dump CST as serialized string and SVG image | -| `-ast` | `--dump-ast` | Dump AST as serialized string and SVG image | -| `-symtab` | `--dump-symtab` | Dump serialized symbol tables | -| `-types` | `--dump-types` | Dump all used types | -| `-ir` | `--dump-ir` | Dump LLVM-IR | -| `-s`, `-asm` | `--dump-assembly` | Dump Assembly code | -| `-b`, `-obj` | `--dump-object-file` | Dump object files | -| `-j ` | `--jobs ` | Set number of jobs to parallelize compilation (default is auto) | -| `-o` | `--output` | Set path for executable output. | -| `-O` | - | Set optimization level.
Valid options: `-O0`, `-O1`, `-O2`, `-O3`, `-Os`, `-Oz` | -| `-m` | `--build-mode` | Controls the build mode. Valid values are `debug` and `release` | -| `-g` | `--debug-info` | Generate debug info to debug the executable in GDB, etc. | -| - | `--disable-verifier` | Disable LLVM module and function verification (only recommended for debugging the compiler) | -| - | `--ignore-cache` | Compile always and ignore the compile cache | \ No newline at end of file +| Option | Long | Description | +|--------------|----------------------------|---------------------------------------------------------------------------------------------| +| `-d` | `--debug-output` | Print compiler output for debugging. | +| `-cst` | `--dump-cst` | Dump CST as serialized string and SVG image | +| `-ast` | `--dump-ast` | Dump AST as serialized string and SVG image | +| `-symtab` | `--dump-symtab` | Dump serialized symbol tables | +| `-types` | `--dump-types` | Dump all used types | +| `-ir` | `--dump-ir` | Dump LLVM-IR | +| `-s`, `-asm` | `--dump-assembly` | Dump Assembly code | +| `-b`, `-obj` | `--dump-object-file` | Dump object files | +| `-j ` | `--jobs ` | Set number of jobs to parallelize compilation (default is auto) | +| `-o` | `--output` | Set path for executable output. | +| `-O` | - | Set optimization level.
Valid options: `-O0`, `-O1`, `-O2`, `-O3`, `-Os`, `-Oz` | +| `-m` | `--build-mode` | Controls the build mode. Valid values are `debug` and `release` | +| `-g` | `--debug-info` | Generate debug info to debug the executable in GDB, etc. | +| - | `--disable-verifier` | Disable LLVM module and function verification (only recommended for debugging the compiler) | +| - | `--ignore-cache` | Compile always and ignore the compile cache | +| - | `--use-lifetime-markers` | Generate lifetime markers to enhance optimizations | \ No newline at end of file diff --git a/docs/docs/cli/test.md b/docs/docs/cli/test.md index 5efd23e4f..599da95bc 100644 --- a/docs/docs/cli/test.md +++ b/docs/docs/cli/test.md @@ -19,17 +19,18 @@ The `test` subcommand can be used to run individual tests or the whole test suit ## Options You can apply following options to the `test` subcommand: -| Option | Long | Description | -|--------------|----------------------|---------------------------------------------------------------------------------------------| -| `-d` | `--debug-output` | Print compiler output for debugging. | -| `-cst` | `--dump-cst` | Dump CST as serialized string and SVG image | -| `-ast` | `--dump-ast` | Dump AST as serialized string and SVG image | -| `-symtab` | `--dump-symtab` | Dump serialized symbol tables | -| `-types` | `--dump-types` | Dump all used types | -| `-ir` | `--dump-ir` | Dump LLVM-IR | -| `-s`, `-asm` | `--dump-assembly` | Dump Assembly code | -| `-j ` | `--jobs ` | Set number of jobs to parallelize compilation (default is auto) | -| `-O` | - | Set optimization level.
Valid options: `-O0`, `-O1`, `-O2`, `-O3`, `-Os`, `-Oz` | -| `-g` | `--debug-info` | Generate debug info to debug the executable in GDB, etc. | -| - | `--disable-verifier` | Disable LLVM module and function verification (only recommended for debugging the compiler) | -| - | `--ignore-cache` | Compile always and ignore the compile cache | \ No newline at end of file +| Option | Long | Description | +|--------------|------------------------------|---------------------------------------------------------------------------------------------| +| `-d` | `--debug-output` | Print compiler output for debugging. | +| `-cst` | `--dump-cst` | Dump CST as serialized string and SVG image | +| `-ast` | `--dump-ast` | Dump AST as serialized string and SVG image | +| `-symtab` | `--dump-symtab` | Dump serialized symbol tables | +| `-types` | `--dump-types` | Dump all used types | +| `-ir` | `--dump-ir` | Dump LLVM-IR | +| `-s`, `-asm` | `--dump-assembly` | Dump Assembly code | +| `-j ` | `--jobs ` | Set number of jobs to parallelize compilation (default is auto) | +| `-O` | - | Set optimization level.
Valid options: `-O0`, `-O1`, `-O2`, `-O3`, `-Os`, `-Oz` | +| `-g` | `--debug-info` | Generate debug info to debug the executable in GDB, etc. | +| - | `--disable-verifier` | Disable LLVM module and function verification (only recommended for debugging the compiler) | +| - | `--ignore-cache` | Compile always and ignore the compile cache | +| - | `--use-lifetime-markers` | Generate lifetime markers to enhance optimizations | \ No newline at end of file diff --git a/media/test-project/test.spice b/media/test-project/test.spice index 206b0b8b1..c6da289b3 100644 --- a/media/test-project/test.spice +++ b/media/test-project/test.spice @@ -1,5 +1,44 @@ +// Algorithm taken from: https://stackoverflow.com/a/54967370/14945975 +// Please note: With iterations > 20 the numbers get huge and do not fit in a long + f main() { + long q = 1l; + long q_new; + long r = 0l; + long r_new; + long t = 1l; + long t_new; + long k = 1l; + long k_new; + long m = 3l; + long x = 3l; + + int iterations = 20; // Change here + int printedDigits = 0; + for int i = 0; i < iterations; i++ { + if 4l * q + r - t < m * t { + printf("%d", m); + if printedDigits == 0 { printf("."); } + printedDigits++; + q_new = 10l * q; + r_new = 10l * (r - m * t); + m = (10l * (3l * q + r)) / t - 10l * m; + q = q_new; + r = r_new; + } else { + q_new = q * k; + r_new = (2l * q + r) * x; + t_new = t * x; + k_new = k + 1l; + m = (q * (7l * k + 2l) + r * x) / (t * x); + x += 2l; + q = q_new; + r = r_new; + t = t_new; + k = k_new; + } + } } /*import "std/os/env"; diff --git a/src/driver/Driver.cpp b/src/driver/Driver.cpp index 8e74981e5..20beaed72 100644 --- a/src/driver/Driver.cpp +++ b/src/driver/Driver.cpp @@ -334,6 +334,9 @@ void Driver::addCompileSubcommandOptions(CLI::App *subCmd) { subCmd->add_option("--jobs,-j", cliOptions.compileJobCount, "Compile jobs (threads), used for compilation"); // --ignore-cache subCmd->add_flag("--ignore-cache", cliOptions.ignoreCache, "Force re-compilation of all source files"); + // --use-lifetime-markers + subCmd->add_flag("--use-lifetime-markers", cliOptions.useLifetimeMarkers, + "Generate lifetime markers to enhance optimizations"); // Opt levels subCmd->add_flag_callback( diff --git a/src/driver/Driver.h b/src/driver/Driver.h index a858a9124..aa7bf5ded 100644 --- a/src/driver/Driver.h +++ b/src/driver/Driver.h @@ -63,6 +63,7 @@ struct CliOptions { bool abortAfterDump = false; } dumpSettings; bool namesForIRValues = false; + bool useLifetimeMarkers = false; OptLevel optLevel = OptLevel::O0; // Default optimization level for debug build mode is O0 bool useLTO = false; bool noEntryFct = false; diff --git a/src/irgenerator/GenImplicit.cpp b/src/irgenerator/GenImplicit.cpp index 1ef6a2403..96f734f89 100644 --- a/src/irgenerator/GenImplicit.cpp +++ b/src/irgenerator/GenImplicit.cpp @@ -58,6 +58,18 @@ void IRGenerator::generateScopeCleanup(const StmtLstNode *node) const { // Call all dtor functions for (auto [entry, dtor] : node->dtorFunctions.at(manIdx)) generateCtorOrDtorCall(entry, dtor, {}); + + // Generate lifetime end markers + if (cliOptions.useLifetimeMarkers) { + std::vector vars = currentScope->getVarsGoingOutOfScope(); + for (SymbolTableEntry *var : vars) { + llvm::Value *address = var->getAddress(); + if (address == nullptr) + continue; + const uint64_t sizeInBytes = module->getDataLayout().getTypeAllocSize(var->getQualType().toLLVMType(sourceFile)); + builder.CreateLifetimeEnd(address, builder.getInt64(sizeInBytes)); + } + } } void IRGenerator::generateCtorOrDtorCall(SymbolTableEntry *entry, const Function *ctorOrDtor, diff --git a/src/irgenerator/IRGenerator.cpp b/src/irgenerator/IRGenerator.cpp index 39721e435..8e522864e 100644 --- a/src/irgenerator/IRGenerator.cpp +++ b/src/irgenerator/IRGenerator.cpp @@ -67,6 +67,13 @@ llvm::Value *IRGenerator::insertAlloca(llvm::Type *llvmType, std::string varName // Restore old basic block builder.SetInsertPoint(currentBlock); } + + // Insert lifetime start marker + if (cliOptions.useLifetimeMarkers) { + const uint64_t sizeInBytes = module->getDataLayout().getTypeAllocSize(llvmType); + builder.CreateLifetimeStart(allocaInsertInst, builder.getInt64(sizeInBytes)); + } + return static_cast(allocaInsertInst); } diff --git a/src/typechecker/TypeCheckerImplicit.cpp b/src/typechecker/TypeCheckerImplicit.cpp index c7b5f1d93..6b278987e 100644 --- a/src/typechecker/TypeCheckerImplicit.cpp +++ b/src/typechecker/TypeCheckerImplicit.cpp @@ -1,12 +1,12 @@ // Copyright (c) 2021-2024 ChilliBits. All rights reserved. #include "TypeChecker.h" -#include "TypeMatcher.h" #include #include #include #include +#include namespace spice::compiler { diff --git a/test/TestRunner.cpp b/test/TestRunner.cpp index 4001bf14a..6aa76e1fa 100644 --- a/test/TestRunner.cpp +++ b/test/TestRunner.cpp @@ -64,6 +64,7 @@ void execTestCase(const TestCase &testCase) { /* abortAfterDump */ false, }, /* namesForIRValues= */ true, + /* useLifetimeMarkers= */ false, /* optLevel= */ OptLevel::O0, /* useLTO= */ std::filesystem::exists(testCase.testPath / CTL_LTO), /* noEntryFct= */ std::filesystem::exists(testCase.testPath / CTL_RUN_BUILTIN_TESTS),