Skip to content

Commit

Permalink
Add cache for CompositeDITypes to fix problem with recursive DIType l…
Browse files Browse the repository at this point in the history
…ookup
  • Loading branch information
marcauberer committed Jun 1, 2024
1 parent 95706d1 commit 0f5ebf6
Show file tree
Hide file tree
Showing 8 changed files with 439 additions and 457 deletions.
2 changes: 1 addition & 1 deletion .run/spice.run.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="spice" type="CMakeRunConfiguration" factoryName="Application" PROGRAM_PARAMS="run -O0 -d -ir ../../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="run -O0 -d -ir -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">
<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
29 changes: 24 additions & 5 deletions src/irgenerator/DebugInfoGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <irgenerator/NameMangling.h>
#include <model/Function.h>
#include <model/Struct.h>
#include <util/CustomHashFunctions.h>
#include <util/FileUtil.h>

#include <llvm/BinaryFormat/Dwarf.h>
Expand Down Expand Up @@ -277,20 +278,20 @@ void DebugInfoGenerator::finalize() {
diBuilder->finalize();
}

llvm::DIType *DebugInfoGenerator::getDITypeForQualType(const ASTNode *node, const QualType &ty) const { // NOLINT(*-no-recursion)
// Pointer ty
llvm::DIType *DebugInfoGenerator::getDITypeForQualType(const ASTNode *node, const QualType &ty) { // NOLINT(*-no-recursion)
// Pointer type
if (ty.isPtr()) {
llvm::DIType *pointeeTy = getDITypeForQualType(node, ty.getContained());
return diBuilder->createPointerType(pointeeTy, pointerWidth);
}

// Reference ty
// Reference type
if (ty.isRef()) {
llvm::DIType *referencedType = getDITypeForQualType(node, ty.getContained());
return diBuilder->createReferenceType(llvm::dwarf::DW_TAG_reference_type, referencedType, pointerWidth);
}

// Array ty
// Array type
if (ty.isArray()) {
llvm::DIType *itemTy = getDITypeForQualType(node, ty.getContained());
const size_t size = ty.getArraySize();
Expand Down Expand Up @@ -326,6 +327,12 @@ llvm::DIType *DebugInfoGenerator::getDITypeForQualType(const ASTNode *node, cons
baseDiType = boolTy;
break;
case TY_STRUCT: {
// Do cache lookup
const size_t hashKey = std::hash<QualType>{}(ty);
if (structTypeCache.contains(hashKey))
return structTypeCache.at(hashKey);

// Cache miss, generate struct type
Struct *spiceStruct = ty.getStruct(node);
assert(spiceStruct != nullptr);

Expand All @@ -344,6 +351,9 @@ llvm::DIType *DebugInfoGenerator::getDITypeForQualType(const ASTNode *node, cons
llvm::DINode::FlagTypePassByReference | llvm::DINode::FlagNonTrivial, nullptr, {}, 0, nullptr, mangledName);
baseDiType = structDiType;

// Insert into cache
structTypeCache.insert({hashKey, structDiType});

// Collect DI types for fields
std::vector<llvm::Metadata *> fieldTypes;
for (size_t i = 0; i < spiceStruct->scope->getFieldCount(); i++) {
Expand All @@ -369,6 +379,12 @@ llvm::DIType *DebugInfoGenerator::getDITypeForQualType(const ASTNode *node, cons
break;
}
case TY_INTERFACE: {
// Do cache lookup
const size_t hashKey = std::hash<QualType>{}(ty);
if (structTypeCache.contains(hashKey))
return structTypeCache.at(hashKey);

// Cache miss, generate interface type
Interface *spiceInterface = ty.getInterface(node);
assert(spiceInterface != nullptr);

Expand All @@ -388,8 +404,11 @@ llvm::DIType *DebugInfoGenerator::getDITypeForQualType(const ASTNode *node, cons

// Set vtable holder to itself for interfaces
interfaceDiType->replaceVTableHolder(interfaceDiType);

baseDiType = interfaceDiType;

// Insert into cache
structTypeCache.insert({hashKey, interfaceDiType});

break;
}
case TY_FUNCTION: // fall-through
Expand Down
3 changes: 2 additions & 1 deletion src/irgenerator/DebugInfoGenerator.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class DebugInfoGenerator {
llvm::DICompileUnit *compileUnit = nullptr;
llvm::DIFile *diFile = nullptr;
std::stack<llvm::DIScope *> lexicalBlocks;
std::unordered_map<size_t, llvm::DICompositeType *> structTypeCache;
unsigned int pointerWidth = 0;
// Debug types
llvm::DIType *doubleTy = nullptr;
Expand All @@ -62,7 +63,7 @@ class DebugInfoGenerator {
llvm::DICompositeType *fatPtrTy = nullptr;

// Private methods
[[nodiscard]] llvm::DIType *getDITypeForQualType(const ASTNode *node, const QualType &ty) const;
[[nodiscard]] llvm::DIType *getDITypeForQualType(const ASTNode *node, const QualType &ty);
};

} // namespace spice::compiler
6 changes: 3 additions & 3 deletions src/symboltablebuilder/Type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,19 @@

#include "Type.h"

#include <utility>

#include <SourceFile.h>
#include <ast/Attributes.h>
#include <exception/CompilerError.h>
#include <exception/SemanticError.h>
#include <global/TypeRegistry.h>
#include <irgenerator/NameMangling.h>
#include <irgenerator/StdFunctionManager.h>
#include <model/GenericType.h>
#include <model/Struct.h>
#include <symboltablebuilder/Scope.h>
#include <symboltablebuilder/SymbolTableEntry.h>

#include <utility>
#include <llvm/IR/Type.h>

namespace spice::compiler {

Expand Down
5 changes: 4 additions & 1 deletion src/symboltablebuilder/Type.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@
#include <symboltablebuilder/TypeChain.h>
#include <util/GlobalDefinitions.h>

#include <llvm/IR/Type.h>
// LLVM forward declarations
namespace llvm {
class Type;
} // namespace llvm

namespace spice::compiler {

Expand Down
16 changes: 15 additions & 1 deletion std/type/common.spice
Original file line number Diff line number Diff line change
@@ -1,2 +1,16 @@
// Common type aliases
type Size alias long;
public type Size alias unsigned long;
public type PtrDiff alias unsigned long;

// Integer type aliases
public type I8 alias unsigned signed byte;
public type U8 alias unsigned unsigned byte;
public type I16 alias unsigned signed short;
public type U16 alias unsigned unsigned short;
public type I32 alias unsigned signed int;
public type U32 alias unsigned unsigned int;
public type I64 alias unsigned signed long;
public type U64 alias unsigned unsigned long;

// Floating point type aliases
public type F64 alias double;
Loading

0 comments on commit 0f5ebf6

Please sign in to comment.