Skip to content

Commit

Permalink
Improve code
Browse files Browse the repository at this point in the history
  • Loading branch information
marcauberer committed May 9, 2024
1 parent 3d94b27 commit 15c0ecf
Show file tree
Hide file tree
Showing 9 changed files with 167 additions and 25 deletions.
129 changes: 113 additions & 16 deletions media/test-project/test.spice
Original file line number Diff line number Diff line change
@@ -1,26 +1,123 @@
type T int|long;
import "bootstrap/bindings/llvm/llvm" as llvm;
import "std/data/vector";

type TestStruct<T> struct {
T _f1
unsigned long length
}
f<int> main() {
llvm::initializeNativeTarget();
llvm::initializeNativeAsmPrinter();

p TestStruct.ctor(const unsigned long initialLength) {
this.length = initialLength;
}
heap string targetTriple = llvm::getDefaultTargetTriple();
string error;
llvm::Target target = llvm::getTargetFromTriple(targetTriple, &error);
llvm::TargetMachine targetMachine = target.createTargetMachine(targetTriple, "generic", "", llvm::LLVMCodeGenOptLevel::Default, llvm::LLVMRelocMode::Default, llvm::LLVMCodeModel::Default);

llvm::LLVMContext context;
llvm::Module module = llvm::Module("test", context);
module.setDataLayout(targetMachine.createDataLayout());
//module.setTargetTriple(targetTriple); // This emits target dependent information in the IR, which is not what we want here.
llvm::Builder builder = llvm::Builder(context);

llvm::Type returnType = builder.getInt32Ty();
Vector<llvm::Type> argTypes;
llvm::Type funcType = llvm::getFunctionType(returnType, argTypes);
llvm::Function func = llvm::Function(module, "main", funcType);
func.setLinkage(llvm::LLVMLinkage::ExternalLinkage);

llvm::BasicBlock entry = llvm::BasicBlock(context, "");
func.pushBack(entry);
builder.setInsertPoint(entry);

llvm::Value calcResult = builder.createAdd(builder.getInt32(1), builder.getInt32(2), "calcResult");

llvm::Value helloWorldStr = builder.createGlobalStringPtr("Hello, world!\n", "helloWorldStr");
Vector<llvm::Type> printfArgTypes;
printfArgTypes.pushBack(builder.getPtrTy());
printfArgTypes.pushBack(builder.getInt32Ty());
llvm::Type printfFuncType = llvm::getFunctionType(builder.getInt32Ty(), printfArgTypes, true);
llvm::Function printfFunc = module.getOrInsertFunction("printf", printfFuncType);

Vector<llvm::Value> printfArgs;
printfArgs.pushBack(helloWorldStr);
printfArgs.pushBack(calcResult);
builder.createCall(printfFunc, printfArgs);

builder.createRet(builder.getInt32(0));

assert !llvm::verifyFunction(func);
string output;
assert !llvm::verifyModule(module, &output);

p TestStruct.printLength() {
printf("%d\n", this.length);
printf("Unoptimized IR:\n%s", module.print());

llvm::PassBuilderOptions pto;
llvm::PassBuilder passBuilder = llvm::PassBuilder(pto);
passBuilder.buildPerModuleDefaultPipeline(llvm::OptimizationLevel::O2);
passBuilder.addPass(llvm::AlwaysInlinerPass());
passBuilder.run(module, targetMachine);

printf("Optimized IR:\n%s", module.print());

targetMachine.emitToFile(module, "this-is-a-test.o", llvm::LLVMCodeGenFileType::ObjectFile);
}

type Alias alias TestStruct<long>;
/*import "std/iterator/array-iterator";
import "std/data/pair";

f<int> main() {
Alias a = Alias{12345l, (unsigned long) 54321l};
a.printLength();
dyn b = Alias(12l);
b.printLength();
}
// Create test array to iterate over
int[5] a = [ 123, 4321, 9876, 321, -99 ];

// Test base functionality
dyn it = iterate(a, len(a));
assert it.isValid();
assert it.get() == 123;
assert it.get() == 123;
it.next();
assert it.get() == 4321;
assert it.isValid();
it.next();
dyn pair = it.getIdx();
assert pair.getFirst() == 2;
assert pair.getSecond() == 9876;
it.next();

// Test overloaded operators
it -= 3;
assert it.get() == 123;
assert it.isValid();
it++;
assert it.get() == 4321;
it--;
assert it.get() == 123;
it += 4;
assert it.get() == -99;
it.next();
assert !it.isValid();

// Test foreach value
foreach int item : iterate(a, len(a)) {
item++;
}
assert a[0] == 123;
assert a[1] == 4321;
assert a[2] == 9876;

// Test foreach ref
foreach int& item : iterate(a, len(a)) {
item++;
}
assert a[0] == 124;
assert a[1] == 4322;
assert a[2] == 9877;

foreach long idx, int& item : iterate(a, len(a)) {
item += idx;
}
assert a[0] == 124;
assert a[1] == 4323;
assert a[2] == 9879;

printf("All assertions passed!");
}*/

/*import "bootstrap/util/block-allocator";
import "bootstrap/util/memory";
Expand Down
2 changes: 1 addition & 1 deletion src-bootstrap/bindings/llvm/llvm.spice
Original file line number Diff line number Diff line change
Expand Up @@ -780,7 +780,7 @@ public f<Value> Builder.getStruct(const Vector<Value>& values, bool packed = fal
public f<Value> Builder.getArray(Type ty, const Vector<Value>& values) {
unsafe {
LLVMValueRef* valuesRef = (LLVMValueRef*) values.getDataPtr();
LLVMValueRef valueRef = LLVMConstArray2(ty.self, valuesRef, (unsigned long) values.getSize());
LLVMValueRef valueRef = LLVMConstArray2(ty.self, valuesRef, values.getSize());
return Value{ valueRef };
}
}
Expand Down
6 changes: 4 additions & 2 deletions src/SourceFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <exception/AntlrThrowingErrorListener.h>
#include <exception/CompilerError.h>
#include <global/GlobalResourceManager.h>
#include <global/TypeRegistry.h>
#include <importcollector/ImportCollector.h>
#include <irgenerator/IRGenerator.h>
#include <iroptimizer/IROptimizer.h>
Expand Down Expand Up @@ -554,6 +555,7 @@ void SourceFile::runBackEnd() { // NOLINT(misc-no-recursion)
CHECK_ABORT_FLAG_V()
std::cout << "\nSuccessfully compiled " << std::to_string(resourceManager.sourceFiles.size()) << " source file(s)";
std::cout << " or " << std::to_string(resourceManager.getTotalLineCount()) << " lines in total.\n";
std::cout << "Total number of types: " << std::to_string(TypeRegistry::getTypeCount()) << "\n";
std::cout << "Total compile time: " << std::to_string(resourceManager.totalTimer.getDurationMilliseconds()) << " ms\n";
}
}
Expand Down Expand Up @@ -582,8 +584,8 @@ bool SourceFile::imports(const SourceFile *sourceFile) const {
return std::ranges::any_of(dependencies, [=](const auto &dependency) { return dependency.second == sourceFile; });
}

bool SourceFile::isAlreadyImported(const std::string &filePathSearch,
std::vector<const SourceFile *> &circle) const { // NOLINT(misc-no-recursion)
bool SourceFile::isAlreadyImported(const std::string &filePathSearch, // NOLINT(misc-no-recursion)
std::vector<const SourceFile *> &circle) const {
circle.push_back(this);
// Check if the current source file corresponds to the path to search
if (std::filesystem::equivalent(filePath, filePathSearch))
Expand Down
42 changes: 42 additions & 0 deletions src/global/TypeRegistry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ namespace spice::compiler {
// Static member initialization
std::unordered_map<uint64_t, std::unique_ptr<Type>> TypeRegistry::types = {};

/**
* Get or insert a type into the type registry
*
* @param type The type to insert
* @return The inserted type
*/
const Type *TypeRegistry::getOrInsert(const Type &&type) {
const uint64_t hash = std::hash<Type>{}(type);

Expand All @@ -22,17 +28,53 @@ const Type *TypeRegistry::getOrInsert(const Type &&type) {
return insertedElement.first->second.get();
}

/**
* Get or insert a type into the type registry
*
* @param superType The super type of the type
* @return The inserted type
*/
const Type *TypeRegistry::getOrInsert(SuperType superType) { return getOrInsert(Type(superType)); }

/**
* Get or insert a type into the type registry
*
* @param superType The super type of the type
* @param subType The sub type of the type
* @return The inserted type
*/
const Type *TypeRegistry::getOrInsert(SuperType superType, const std::string &subType) {
return getOrInsert(Type(superType, subType));
}

/**
* Get or insert a type into the type registry
*
* @param superType The super type of the type
* @param subType The sub type of the type
* @param typeId The type ID of the type
* @param data The data of the type
* @param templateTypes The template types of the type
* @return The inserted type
*/
const Type *TypeRegistry::getOrInsert(SuperType superType, const std::string &subType, uint64_t typeId,
const TypeChainElementData &data, const QualTypeList &templateTypes) {
return getOrInsert(Type(superType, subType, typeId, data, templateTypes));
}

/**
* Get or insert a type into the type registry
*
* @param typeChain The type chain of the type
* @return The inserted type
*/
const Type *TypeRegistry::getOrInsert(const TypeChain &typeChain) { return getOrInsert(Type(typeChain)); }

/**
* Get the number of types in the type registry
*
* @return The number of types in the type registry
*/
const size_t TypeRegistry::getTypeCount() { return types.size(); }

} // namespace spice::compiler
1 change: 1 addition & 0 deletions src/global/TypeRegistry.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class TypeRegistry {
static const Type *getOrInsert(SuperType superType, const std::string &subType, uint64_t typeId,
const TypeChainElementData &data, const QualTypeList &templateTypes);
static const Type *getOrInsert(const TypeChain& typeChain);
static const size_t getTypeCount();

private:
// Private members
Expand Down
2 changes: 1 addition & 1 deletion src/symboltablebuilder/QualType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -461,7 +461,7 @@ QualType QualType::toRef(const ASTNode *node) const {
*/
QualType QualType::toConstRef(const ASTNode *node) const {
QualType qualType = toRef(node);
qualType.specifiers.isConst = true;
qualType.makeConst();
return qualType;
}

Expand Down
2 changes: 1 addition & 1 deletion src/typechecker/OpRuleManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -710,7 +710,7 @@ QualType OpRuleManager::validateBinaryOperation(const ASTNode *node, const Binar
for (size_t i = 0; i < opRulesSize; i++) {
const BinaryOpRule &rule = opRules[i];
if (std::get<0>(rule) == lhs.getSuperType() && std::get<1>(rule) == rhs.getSuperType()) {
QualType resultType = QualType(SuperType(std::get<2>(rule)));
QualType resultType(SuperType(std::get<2>(rule)));
if (preserveSpecifiersFromLhs)
resultType.setSpecifiers(lhs.getSpecifiers());
return resultType;
Expand Down
4 changes: 2 additions & 2 deletions src/typechecker/TypeChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,8 @@ std::any TypeChecker::visitForeachLoop(ForeachLoopNode *node) {
Scope *matchScope = nameRegistryEntry->targetScope->parent;
assert(matchScope->type == ScopeType::GLOBAL);
QualType unsignedLongType(TY_LONG);
unsignedLongType.getSpecifiers().isSigned = false;
unsignedLongType.getSpecifiers().isUnsigned = true;
unsignedLongType.makeSigned(false);
unsignedLongType.makeUnsigned(true);
const ArgList argTypes = {Arg(iterableType, false), Arg(unsignedLongType, false)};
const QualType thisType(TY_DYN);
node->getIteratorFct = FunctionManager::matchFunction(matchScope, "iterate", thisType, argTypes, {}, true, iteratorNode);
Expand Down
4 changes: 2 additions & 2 deletions src/typechecker/TypeCheckerImplicit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ void TypeChecker::createDefaultStructMethod(const Struct &spiceStruct, const std

// Procedure type
QualType procedureType(TY_PROCEDURE);
procedureType.getSpecifiers().isPublic = true; // Always public
procedureType.makePublic(); // Always public

// Insert symbol for function into the symbol table
const std::string entryName = Function::getSymbolTableEntryName(methodName, node->codeLoc);
Expand Down Expand Up @@ -229,7 +229,7 @@ void TypeChecker::createDefaultDtorIfRequired(const Struct &spiceStruct, Scope *
// Set dealloc function to used
const QualType thisType(TY_DYN);
QualType bytePtrRefType = QualType(TY_BYTE).toPtr(node).toRef(node);
bytePtrRefType.getSpecifiers().isHeap = true;
bytePtrRefType.makeHeap();
const ArgList args = {{bytePtrRefType, false /* we always have the field as storage */}};
Function *deallocFct = FunctionManager::matchFunction(matchScope, FCT_NAME_DEALLOC, thisType, args, {}, true, node);
assert(deallocFct != nullptr);
Expand Down

0 comments on commit 15c0ecf

Please sign in to comment.