From 22dcbc6a1315c1faa085bf44560e72d30547f2fc Mon Sep 17 00:00:00 2001 From: Samuel Hammersberg Date: Mon, 1 May 2023 22:50:22 +0200 Subject: [PATCH] Various codegen fixes --- sample-programs/insertion-sort.chrf | 9 +++++- sample-programs/loop.crf | 18 +++++++++++ src/Codegen/CompilerState.hs | 46 +++++++++++++------------- src/Codegen/Emits.hs | 50 ++++++++++++++--------------- src/Compiler.hs | 9 +++--- src/GC/include/cheap.h | 2 +- src/GC/include/heap.hpp | 42 ++++++++++++------------ 7 files changed, 99 insertions(+), 77 deletions(-) create mode 100644 sample-programs/loop.crf diff --git a/sample-programs/insertion-sort.chrf b/sample-programs/insertion-sort.chrf index 573f2de..fc61691 100644 --- a/sample-programs/insertion-sort.chrf +++ b/sample-programs/insertion-sort.chrf @@ -16,8 +16,15 @@ insertionSort xs = case xs of Nil => xs Nil => Nil -main = head (insertionSort (Cons 5 (Cons 4 (Cons 3 (Cons 2 (Cons 1 Nil)))))) +main = head (insertionSort (revRange 1250)) head xs = case xs of Cons x _ => x +revRange x = case x of + 0 => Cons x Nil + x => Cons x (revRange (x + minusOne)) + +-- represents minus one :) +minusOne : Int ; +minusOne = 9223372036854775807 + 9223372036854775807 + 1; \ No newline at end of file diff --git a/sample-programs/loop.crf b/sample-programs/loop.crf new file mode 100644 index 0000000..e3c3c38 --- /dev/null +++ b/sample-programs/loop.crf @@ -0,0 +1,18 @@ +main = for 0 1000 + +for x n = case n of + 0 => 0 + n => for (revRange 1000) (n + minusOne) + +data List (a) where + Nil : List (a) + Cons : a -> List (a) -> List (a) + +-- create a list of x to 0 +revRange x = case x of + 0 => Cons x Nil + x => Cons x (revRange (x + minusOne)) + +-- represents minus one :) +minusOne : Int ; +minusOne = 9223372036854775807 + 9223372036854775807 + 1; \ No newline at end of file diff --git a/src/Codegen/CompilerState.hs b/src/Codegen/CompilerState.hs index 1379d2f..523cc54 100644 --- a/src/Codegen/CompilerState.hs +++ b/src/Codegen/CompilerState.hs @@ -1,42 +1,39 @@ module Codegen.CompilerState where -import Auxiliary (snoc) -import Codegen.Auxillary (type2LlvmType, typeByteSize) -import Codegen.LlvmIr as LIR (LLVMIr (UnsafeRaw), LLVMType) -import Control.Monad.State ( - StateT, - gets, - modify, - ) -import Data.Map (Map) -import Data.Map qualified as Map -import Grammar.ErrM (Err) -import Monomorphizer.MonomorphizerIr as MIR -import TypeChecker.TypeCheckerIr qualified as TIR +import Auxiliary (snoc) +import Codegen.Auxillary (type2LlvmType, typeByteSize) +import Codegen.LlvmIr as LIR (LLVMIr (UnsafeRaw), + LLVMType) +import Control.Monad.State (StateT, gets, modify) +import Data.Map (Map) +import qualified Data.Map as Map +import Grammar.ErrM (Err) +import Monomorphizer.MonomorphizerIr as MIR +import qualified TypeChecker.TypeCheckerIr as TIR -- | The record used as the code generator state data CodeGenerator = CodeGenerator - { instructions :: [LLVMIr] - , functions :: Map MIR.Id FunctionInfo - , customTypes :: Map LLVMType Integer - , constructors :: Map TIR.Ident ConstructorInfo + { instructions :: [LLVMIr] + , functions :: Map MIR.Id FunctionInfo + , customTypes :: Map LLVMType Integer + , constructors :: Map TIR.Ident ConstructorInfo , variableCount :: Integer - , labelCount :: Integer - , gcEnabled :: Bool + , labelCount :: Integer + , gcEnabled :: Bool } -- | A state type synonym type CompilerState a = StateT CodeGenerator Err a data FunctionInfo = FunctionInfo - { numArgs :: Int + { numArgs :: Int , arguments :: [Id] } deriving (Show) data ConstructorInfo = ConstructorInfo - { numArgsCI :: Int - , argumentsCI :: [Id] - , numCI :: Integer + { numArgsCI :: Int + , argumentsCI :: [Id] + , numCI :: Integer , returnTypeCI :: MIR.Type } deriving (Show) @@ -146,4 +143,5 @@ gcStart = , UnsafeRaw "declare external void @cheap_dispose()\n" , UnsafeRaw "declare external ptr @cheap_the()\n" , UnsafeRaw "declare external void @cheap_set_profiler(ptr, i1)\n" - ] \ No newline at end of file + , UnsafeRaw "declare external void @cheap_profiler_log_options(ptr, i64)\n" + ] diff --git a/src/Codegen/Emits.hs b/src/Codegen/Emits.hs index 66cad6e..9eca23e 100644 --- a/src/Codegen/Emits.hs +++ b/src/Codegen/Emits.hs @@ -1,25 +1,22 @@ -{-# LANGUAGE LambdaCase #-} +{-# LANGUAGE LambdaCase #-} {-# LANGUAGE OverloadedStrings #-} module Codegen.Emits where -import Codegen.Auxillary -import Codegen.CompilerState -import Codegen.LlvmIr as LIR -import Control.Applicative ((<|>)) -import Control.Monad (when) -import Control.Monad.State ( - gets, - modify, - ) -import Data.Bifunctor qualified as BI -import Data.Char (ord) -import Data.Coerce (coerce) -import Data.Map qualified as Map -import Data.Maybe (fromJust, fromMaybe) -import Data.Tuple.Extra (dupe, first, second) -import Monomorphizer.MonomorphizerIr as MIR -import TypeChecker.TypeCheckerIr qualified as TIR +import Codegen.Auxillary +import Codegen.CompilerState +import Codegen.LlvmIr as LIR +import Control.Applicative ((<|>)) +import Control.Monad (when) +import Control.Monad.State (gets, modify) +import qualified Data.Bifunctor as BI +import Data.Char (ord) +import Data.Coerce (coerce) +import qualified Data.Map as Map +import Data.Maybe (fromJust, fromMaybe) +import Data.Tuple.Extra (dupe, first, second) +import Monomorphizer.MonomorphizerIr as MIR +import qualified TypeChecker.TypeCheckerIr as TIR compileScs :: [MIR.Def] -> CompilerState () compileScs [] = do @@ -132,6 +129,7 @@ firstMainContent :: Bool -> [LLVMIr] firstMainContent True = [ UnsafeRaw "%prof = call ptr @cheap_the()\n" , UnsafeRaw "call void @cheap_set_profiler(ptr %prof, i1 true)\n" + , UnsafeRaw "call void @cheap_profiler_log_options(ptr %prof, i64 30)\n" , UnsafeRaw "call void @cheap_init()\n" ] firstMainContent False = [] @@ -150,12 +148,12 @@ lastMainContent False var = ] compileExp :: ExpT -> CompilerState () -compileExp (MIR.ELit lit, _t) = emitLit lit -compileExp (MIR.EAdd e1 e2, t) = emitAdd t e1 e2 -compileExp (MIR.EVar name, _t) = emitIdent name -compileExp (MIR.EApp e1 e2, t) = emitApp t e1 e2 +compileExp (MIR.ELit lit, _t) = emitLit lit +compileExp (MIR.EAdd e1 e2, t) = emitAdd t e1 e2 +compileExp (MIR.EVar name, _t) = emitIdent name +compileExp (MIR.EApp e1 e2, t) = emitApp t e1 e2 compileExp (MIR.ELet bind e, _) = emitLet bind e -compileExp (MIR.ECase e cs, t) = emitECased t e (map (t,) cs) +compileExp (MIR.ECase e cs, t) = emitECased t e (map (t,) cs) emitLet :: MIR.Bind -> ExpT -> CompilerState () emitLet (MIR.Bind id [] innerExp) e = do @@ -241,7 +239,7 @@ emitECased t e cases = do emitCases _rt ty label stackPtr vs (Branch (MIR.PLit (i, ct), t) exp) = do emit $ Comment "Plit" let i' = case i of - MIR.LInt i -> VInteger i + MIR.LInt i -> VInteger i MIR.LChar i -> VChar (ord i) ns <- getNewVar lbl_failPos <- (\x -> TIR.Ident $ "failed_" <> show x) <$> getNewLabel @@ -341,7 +339,7 @@ emitLit :: MIR.Lit -> CompilerState () emitLit i = do -- !!this should never happen!! let (i', t) = case i of - (MIR.LInt i'') -> (VInteger i'', I64) + (MIR.LInt i'') -> (VInteger i'', I64) (MIR.LChar i'') -> (VChar $ ord i'', I8) varCount <- getNewVar emit $ Comment "This should not have happened!" @@ -357,7 +355,7 @@ emitAdd t e1 e2 = do exprToValue :: ExpT -> CompilerState LLVMValue exprToValue = \case (MIR.ELit i, _t) -> pure $ case i of - (MIR.LInt i) -> VInteger i + (MIR.LInt i) -> VInteger i (MIR.LChar i) -> VChar $ ord i (MIR.EVar (TIR.Ident "True"), _t) -> pure $ VInteger 1 (MIR.EVar (TIR.Ident "False"), _t) -> pure $ VInteger 0 diff --git a/src/Compiler.hs b/src/Compiler.hs index 72598cb..3fb1fe1 100644 --- a/src/Compiler.hs +++ b/src/Compiler.hs @@ -1,9 +1,6 @@ module Compiler (compile) where -import System.Process.Extra ( - readCreateProcess, - shell, - ) +import System.Process.Extra (readCreateProcess, shell) -- spawnWait s = spawnCommand s >>= \s >>= waitForProcess @@ -31,7 +28,9 @@ compileClang True = , "src/GC/lib/event.cpp" , "src/GC/lib/heap.cpp" , "src/GC/lib/profiler.cpp" - , "-Wall -Wextra -g -std=gnu++20 -stdlib=libstdc++ -O3" + , "-Wall -Wextra -g -std=gnu++20 -stdlib=libstdc++" + , "-O3" + --, "-tailcallopt" , "-Isrc/GC/include" , "-x" , "ir" -- , "-Lsrc/GC/lib -l:gcoll.a" diff --git a/src/GC/include/cheap.h b/src/GC/include/cheap.h index 7d803a8..d74af9d 100644 --- a/src/GC/include/cheap.h +++ b/src/GC/include/cheap.h @@ -7,7 +7,7 @@ extern "C" { #endif -#define WRAPPER_DEBUG +//#define WRAPPER_DEBUG #ifdef WRAPPER_DEBUG typedef struct cheap diff --git a/src/GC/include/heap.hpp b/src/GC/include/heap.hpp index eb161c0..909ac99 100644 --- a/src/GC/include/heap.hpp +++ b/src/GC/include/heap.hpp @@ -7,8 +7,8 @@ #include "chunk.hpp" #include "profiler.hpp" -#define HEAP_SIZE 65536 -#define FREE_THRESH (uint) 100 +#define HEAP_SIZE 240240240 +#define FREE_THRESH (uint)100 #define HEAP_DEBUG namespace GC @@ -16,14 +16,15 @@ namespace GC /** * Flags for the collect overlead for conditional * collection (mark/sweep/free/all). - */ - enum CollectOption { - MARK = 1 << 0, - SWEEP = 1 << 1, - MARK_SWEEP = 1 << 2, - FREE = 1 << 3, - COLLECT_ALL = 0b1111 // all flags above - }; + */ + enum CollectOption + { + MARK = 1 << 0, + SWEEP = 1 << 1, + MARK_SWEEP = 1 << 2, + FREE = 1 << 3, + COLLECT_ALL = 0b1111 // all flags above + }; /** * The heap class to represent the heap for the @@ -32,7 +33,7 @@ namespace GC * inside the heap class. The heap is represented * by a char array of size 65536 and can enable * a profiler to track the actions on the heap. - */ + */ class Heap { private: @@ -44,11 +45,11 @@ namespace GC } char *const m_heap; - size_t m_size {0}; - char *m_heap_top {nullptr}; + size_t m_size{0}; + char *m_heap_top{nullptr}; // static Heap *m_instance {nullptr}; - uintptr_t *m_stack_top {nullptr}; - bool m_profiler_enable {false}; + uintptr_t *m_stack_top{nullptr}; + bool m_profiler_enable{false}; std::vector m_allocated_chunks; std::vector m_freed_chunks; @@ -69,6 +70,7 @@ namespace GC // Temporary Chunk *try_recycle_chunks_new(size_t size); void free_overlap_new(Heap &heap); + public: /** * These are the only five functions which are exposed @@ -86,13 +88,13 @@ namespace GC void set_profiler_log_options(RecordOption flags); // Stop the compiler from generating copy-methods - Heap(Heap const&) = delete; - Heap& operator=(Heap const&) = delete; + Heap(Heap const &) = delete; + Heap &operator=(Heap const &) = delete; #ifdef HEAP_DEBUG - void collect(CollectOption flags); // conditional collection - void check_init(); // print dummy things - void print_contents(); // print dummy things + void collect(CollectOption flags); // conditional collection + void check_init(); // print dummy things + void print_contents(); // print dummy things void print_allocated_chunks(Heap *heap); // print the contents in m_allocated_chunks void print_summary(); #endif