Skip to content

Commit

Permalink
Add type registry dumper (#549)
Browse files Browse the repository at this point in the history
  • Loading branch information
marcauberer committed May 12, 2024
1 parent 5f47fc8 commit c2db112
Show file tree
Hide file tree
Showing 23 changed files with 149 additions and 29 deletions.
2 changes: 1 addition & 1 deletion .run/spice.run.xml
@@ -1,5 +1,5 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="spice" type="CMakeRunConfiguration" factoryName="Application" PROGRAM_PARAMS="build -O0 -d -g ../../media/test-project/test.spice" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="Spice" TARGET_NAME="spice" CONFIG_NAME="Debug" RUN_TARGET_PROJECT_NAME="Spice" RUN_TARGET_NAME="spice">
<configuration default="false" name="spice" type="CMakeRunConfiguration" factoryName="Application" PROGRAM_PARAMS="build -O2 -d ../../media/test-project/test.spice" REDIRECT_INPUT="false" ELEVATE="false" USE_EXTERNAL_CONSOLE="false" EMULATE_TERMINAL="false" PASS_PARENT_ENVS_2="true" PROJECT_NAME="Spice" TARGET_NAME="spice" CONFIG_NAME="Debug" RUN_TARGET_PROJECT_NAME="Spice" RUN_TARGET_NAME="spice">
<envs>
<env name="LLVM_ADDITIONAL_FLAGS" value="-lole32 -lws2_32" />
<env name="LLVM_BUILD_INCLUDE_DIR" value="$PROJECT_DIR$/../llvm-project-latest/build/include" />
Expand Down
1 change: 1 addition & 0 deletions docs/docs/cli/build.md
Expand Up @@ -25,6 +25,7 @@ You can apply following options to the `build` subcommand:
| `-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 |
Expand Down
1 change: 1 addition & 0 deletions docs/docs/cli/install.md
Expand Up @@ -25,6 +25,7 @@ You can apply following options to the `install` subcommand:
| `-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 |
Expand Down
1 change: 1 addition & 0 deletions docs/docs/cli/run.md
Expand Up @@ -25,6 +25,7 @@ You can apply following options to the `run` subcommand:
| `-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 |
Expand Down
1 change: 1 addition & 0 deletions docs/docs/cli/test.md
Expand Up @@ -27,6 +27,7 @@ You can apply following options to the `test` subcommand:
| `-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 <n>` | `--jobs <n>` | Set number of jobs to parallelize compilation (default is auto) |
Expand Down
46 changes: 21 additions & 25 deletions media/test-project/test.spice
@@ -1,32 +1,28 @@
import "std/os/env";
import "bootstrap/lexer/lexer";
import "std/os/thread";

f<int> main() {
String filePath = getEnv("SPICE_STD_DIR") + "/../test/test-files/bootstrap-compiler/standalone-lexer-test/test-file.spice";
Lexer lexer = Lexer(filePath.getRaw());
unsigned long tokenCount = 0l;
while (!lexer.isEOF()) {
Token token = lexer.getToken();
token.print();
lexer.advance();
tokenCount++;
}
printf("\nLexed tokens: %d\n", tokenCount);
f<int> fib(int n) {
if n <= 2 { return 1; }
return fib(n - 1) + fib(n - 2);
}

/*import "std/iterator/number-iterator";

f<int> main() {
NumberIterator<int> itInt = range(1, 10);
dyn idxAndValueInt = itInt.getIdx();
assert idxAndValueInt.getSecond() == 4;
}*/

/*import "std/data/hash-table";

f<int> main() {
HashTable<int, string> map = HashTable<int, string>(3l);
}*/
int threadCount = 8;
Thread[8] threads = [];
for unsigned int i = 0; i < threadCount; i++ {
threads[i] = Thread(p() {
int res = fib(30);
printf("Thread returned with result: %d\n", res);
});
Thread& thread = threads[i];
thread.run();
}
printf("Started all threads. Waiting for results ...\n");
for unsigned int i = 0; i < threadCount; i++ {
Thread& thread = threads[i];
thread.join();
}
printf("Program finished");
}

/*import "bootstrap/util/block-allocator";
import "bootstrap/util/memory";
Expand Down
8 changes: 8 additions & 0 deletions src/SourceFile.cpp
Expand Up @@ -483,6 +483,14 @@ void SourceFile::concludeCompilation() {
if (!cliOptions.ignoreCache)
resourceManager.cacheManager.cacheSourceFile(this);

// Save type registry as string in the compiler output
if (mainFile && (cliOptions.dumpSettings.dumpTypes || cliOptions.testMode))
compilerOutput.typesString = TypeRegistry::dump();

// Dump type registry
if (mainFile && cliOptions.dumpSettings.dumpTypes)
dumpOutput(compilerOutput.typesString, "Type Registry", "type-registry.out");

// Print warning if verifier is disabled
if (parent == nullptr && cliOptions.disableVerifier) {
const std::string warningMessage =
Expand Down
1 change: 1 addition & 0 deletions src/SourceFile.h
Expand Up @@ -92,6 +92,7 @@ struct CompilerOutput {
std::string irString;
std::string irOptString;
std::string asmString;
std::string typesString;
std::vector<CompilerWarning> warnings;
TimerOutput times;
};
Expand Down
2 changes: 2 additions & 0 deletions src/driver/Driver.cpp
Expand Up @@ -337,6 +337,8 @@ void Driver::addCompileSubcommandOptions(CLI::App *subCmd) {
subCmd->add_flag<bool>("--dump-ast,-ast", cliOptions.dumpSettings.dumpAST, "Dump AST as serialized string and SVG image");
// --dump-symtab
subCmd->add_flag<bool>("--dump-symtab,-symtab", cliOptions.dumpSettings.dumpSymbolTable, "Dump serialized symbol tables");
// --dump-types
subCmd->add_flag<bool>("--dump-types,-types", cliOptions.dumpSettings.dumpTypes, "Dump all used types");
// --dump-ir
subCmd->add_flag<bool>("--dump-ir,-ir", cliOptions.dumpSettings.dumpIR, "Dump LLVM-IR");
// --dump-assembly
Expand Down
1 change: 1 addition & 0 deletions src/driver/Driver.h
Expand Up @@ -55,6 +55,7 @@ struct CliOptions {
bool dumpCST = false;
bool dumpAST = false;
bool dumpSymbolTable = false;
bool dumpTypes = false;
bool dumpIR = false;
bool dumpAssembly = false;
bool dumpObjectFile = false;
Expand Down
24 changes: 23 additions & 1 deletion src/global/TypeRegistry.cpp
Expand Up @@ -2,6 +2,8 @@

#include "TypeRegistry.h"

#include <sstream>

#include <util/CustomHashFunctions.h>

namespace spice::compiler {
Expand Down Expand Up @@ -77,6 +79,26 @@ const Type *TypeRegistry::getOrInsert(const TypeChain &typeChain) { return getOr
*/
size_t TypeRegistry::getTypeCount() { return types.size(); }

void TypeRegistry::clear() { types.clear();}
/**
* Dump all types in the type registry
*/
std::string TypeRegistry::dump() {
std::vector<std::string> typeStrings;
typeStrings.reserve(types.size());
for (const auto &type : types)
typeStrings.push_back(type.second->getName());
// Sort to ensure deterministic output
std::sort(typeStrings.begin(), typeStrings.end());
// Serialize type registry
std::stringstream typeRegistryString;
for (const std::string &typeString : typeStrings)
typeRegistryString << typeString << "\n";
return typeRegistryString.str();
}

/**
* Clear the type registry
*/
void TypeRegistry::clear() { types.clear(); }

} // namespace spice::compiler
1 change: 1 addition & 0 deletions src/global/TypeRegistry.h
Expand Up @@ -24,6 +24,7 @@ class TypeRegistry {
const TypeChainElementData &data, const QualTypeList &templateTypes);
static const Type *getOrInsert(const TypeChain& typeChain);
static size_t getTypeCount();
static std::string dump();
static void clear();

private:
Expand Down
4 changes: 3 additions & 1 deletion src/symboltablebuilder/TypeChain.cpp
Expand Up @@ -102,7 +102,9 @@ void TypeChainElement::getName(std::stringstream &name, bool withSize) const {
name << "f";
if (data.hasCaptures)
name << "[]";
name << "<" << paramTypes.front().getName(true) << ">(";
if (!paramTypes.empty())
name << "<" << paramTypes.front().getName(true) << ">";
name << "(";
for (size_t i = 1; i < paramTypes.size(); i++) {
if (i > 1)
name << ",";
Expand Down
2 changes: 1 addition & 1 deletion src/util/CustomHashFunctions.cpp
Expand Up @@ -6,7 +6,7 @@ namespace std {

size_t hash<spice::compiler::TypeChainElement>::operator()(const spice::compiler::TypeChainElement &tce) const {
// Hasher for QualTypeList
const auto pred = [](size_t acc, const spice::compiler::QualType &val) {
constexpr auto pred = [](size_t acc, const spice::compiler::QualType &val) {
// Combine the previous hash value with the current element's hash, adjusted by a prime number to reduce collisions
return acc * 31 + std::hash<spice::compiler::QualType>{}(val);
};
Expand Down
6 changes: 6 additions & 0 deletions test/TestRunner.cpp
Expand Up @@ -17,6 +17,7 @@
#include <exception/ParserError.h>
#include <exception/SemanticError.h>
#include <global/GlobalResourceManager.h>
#include <global/TypeRegistry.h>
#include <symboltablebuilder/SymbolTable.h>
#include <util/FileUtil.h>

Expand Down Expand Up @@ -55,6 +56,7 @@ void execTestCase(const TestCase &testCase) {
/* dumpCST= */ false,
/* dumpAST= */ false,
/* dumpSymbolTables= */ false,
/* dumpTypes= */ false,
/* dumpIR= */ false,
/* dumpAssembly= */ false,
/* dumpObjectFile= */ false,
Expand All @@ -71,6 +73,7 @@ void execTestCase(const TestCase &testCase) {
/* disableVerifier= */ false,
/* testMode= */ true,
};
static_assert(sizeof(CliOptions::DumpSettings) == 9, "CliOptions::DumpSettings struct size changed");
static_assert(sizeof(CliOptions) == 360, "CliOptions struct size changed");

// Instantiate GlobalResourceManager
Expand Down Expand Up @@ -196,6 +199,9 @@ void execTestCase(const TestCase &testCase) {
resourceManager.linker.link();
}

// Check type registry output
TestUtil::checkRefMatch(testCase.testPath / REF_NAME_TYPE_REGISTRY, [&]() { return TypeRegistry::dump(); });

// Check if the execution output matches the expected output
TestUtil::checkRefMatch(testCase.testPath / REF_NAME_EXECUTION_OUTPUT, [&]() {
const std::filesystem::path cliFlagsFile = testCase.testPath / INPUT_NAME_CLI_FLAGS;
Expand Down
7 changes: 7 additions & 0 deletions test/test-files/benchmark/success-ackermann/type-registry.out
@@ -0,0 +1,7 @@
bool
dyn
f()
f<int>()
f<int>(int,int)
int
invalid
7 changes: 7 additions & 0 deletions test/test-files/benchmark/success-faculty/type-registry.out
@@ -0,0 +1,7 @@
bool
dyn
f()
f<int>()
f<int>(int)
int
invalid
@@ -0,0 +1,37 @@
*
Error
Error&
Error*
Pthread_attr_t
Pthread_attr_t&
Pthread_attr_t*
Thread
Thread
Thread&
Thread*
bool
byte
byte*
byte**
char
char*
dyn
dyn
f()
f<int>()
f<int>(int)
f<int>(long*,Pthread_attr_t*,p())
f<int>(long,byte**)
f<long>()
import
int
invalid
long
long
long*
p()
p()
p(int,string)
p(p())
p(string)
string
7 changes: 7 additions & 0 deletions test/test-files/benchmark/success-fibonacci/type-registry.out
@@ -0,0 +1,7 @@
bool
dyn
f()
f<int>()
f<int>(int)
int
invalid
@@ -0,0 +1,5 @@
bool
f()
f<int>()
int
invalid
@@ -0,0 +1,7 @@
bool
char
f()
f<int>()
int
invalid
long
6 changes: 6 additions & 0 deletions test/test-files/benchmark/success-pidigits/type-registry.out
@@ -0,0 +1,6 @@
bool
f()
f<int>()
int
invalid
long
1 change: 1 addition & 0 deletions test/util/TestUtil.h
Expand Up @@ -30,6 +30,7 @@ const char *const REF_NAME_SOURCE = "source.spice";
const char *const REF_NAME_PARSE_TREE = "parse-tree.dot";
const char *const REF_NAME_SYNTAX_TREE = "syntax-tree.dot";
const char *const REF_NAME_SYMBOL_TABLE = "symbol-table.json";
const char *const REF_NAME_TYPE_REGISTRY = "type-registry.out";
const char *const REF_NAME_IR = "ir-code.ll";
const char *const REF_NAME_ASM = "assembly.asm";
const char *const REF_NAME_OPT_IR[5] = {"ir-code-O1.ll", "ir-code-O2.ll", "ir-code-O3.ll", "ir-code-Os.ll", "ir-code-Oz.ll"};
Expand Down

0 comments on commit c2db112

Please sign in to comment.