Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mutual resources #421

Merged
merged 2 commits into from
Nov 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions WYBE.md
Original file line number Diff line number Diff line change
Expand Up @@ -1559,11 +1559,16 @@ A resource can be declared at the level of a module, as follows:

> `resource` *name*`:`*type*

It may optionally specify an initial value, in which case the resource is
defined throughout the execution of the program.
It may optionally specify an initial value:

> `resource` *name*`:`*type* `=` *expr*

In this case, the resource is
defined in any top level code in that module, as well as any top level code in
any module that `use`s this module, but not in any module that this module
`use`s. The latter restriction is necessary because when two modules depend on
one another, the order in which their resources are initialised is unspecified.

A resource may be exported, allowing it to be referred to in other modules, by
preceding the `resource` declaration with the `pub` keyword.

Expand Down
22 changes: 13 additions & 9 deletions src/Normalise.hs
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ completeNormalisation :: [ModSpec] -> Compiler ()
completeNormalisation modSCC = do
logNormalise $ "Completing normalisation of modules " ++ showModSpecs modSCC
completeTypeNormalisation modSCC
mapM_ (normaliseModMain `inModule`) modSCC
mapM_ (normaliseModMain modSCC `inModule`) modSCC
mapM_ (transformModuleProcs flattenProcBody) modSCC


Expand Down Expand Up @@ -442,18 +442,19 @@ typeRepresentation _ _ = Address


----------------------------------------------------------------
-- Generating top-level code for the current module
-- Generating top-level code for the current module, given a list of all
-- the modules in the same module dependency SCC.

normaliseModMain :: Compiler ()
normaliseModMain = do
normaliseModMain :: [ModSpec] -> Compiler ()
normaliseModMain modSCC = do
stmts <- getModule stmtDecls
modSpec <- getModuleSpec
logNormalise $ "Completing main normalisation of module "
++ showModSpec modSpec
let initBody = List.reverse stmts
logNormalise $ "Top-level statements = " ++ show initBody
unless (List.null stmts) $ do
resources <- initResources
resources <- initResources modSCC
logNormalise $ "Initialised resources in main code for module "
++ showModSpec modSpec
++ ": " ++ show resources
Expand All @@ -463,9 +464,11 @@ normaliseModMain = do

-- |The resources available at the top level of this module, plus the
-- initialisations to be performed before executing any code that uses this
-- module.
initResources :: Compiler (Set ResourceFlowSpec)
initResources = do
-- module. All resources initialised by the current module are taken to be
-- outputs, and all resources defined by modules used by this module but not in
-- the same SCC are taken as inputs.
initResources :: [ModSpec] -> Compiler (Set ResourceFlowSpec)
initResources modSCC = do
thisMod <- getModule modSpec
mods <- getModuleImplementationField (Map.keys . modImports)
mods' <- (mods ++) . concat <$> mapM descendentModules mods
Expand All @@ -474,7 +477,8 @@ initResources = do
(localInitialised,visibleInitialised) <- initialisedResources
let visibleInitSet = Map.keysSet visibleInitialised
let localInitSet = Map.keysSet localInitialised
let importedInitSet = visibleInitSet Set.\\ localInitSet
let importedInitSet = Set.filter (not . (`elem` modSCC) . resourceMod)
$ visibleInitSet Set.\\ localInitSet
logNormalise $ "in initResources, initialised resources = "
++ show visibleInitSet
logNormalise $ " initialised local resources = "
Expand Down
81 changes: 81 additions & 0 deletions test-cases/final-dump/mutual_res_a.exp
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
======================================================================
AFTER EVERYTHING:
Module mutual_res_a
representation : (not a type)
public submods :
public resources: a_res: mutual_res_a.a_res
public procs : mutual_res_a.<0>
imports : use mutual_res_b
use wybe
resources : a_res: fromList [(mutual_res_a.a_res,wybe.int = 42 @mutual_res_a:nn:nn @mutual_res_a:nn:nn)]
procs :

module top-level code > public {inline,semipure} (0 calls)
0: mutual_res_a.<0>
()<{}; {<<mutual_res_a.a_res>>}; {}>:
AliasPairs: []
InterestingCallProperties: []
foreign lpvm store(42:wybe.int, <<mutual_res_a.a_res>>:wybe.int) @mutual_res_a:nn:nn

LLVM code :

; ModuleID = 'mutual_res_a'





@"resource#mutual_res_a.a_res" = global i64 undef


declare external ccc i8* @wybe_malloc(i32)


declare external ccc void @llvm.memcpy.p0i8.p0i8.i32(i8*, i8*, i32, i1)


define external fastcc void @"mutual_res_a.<0>"() alwaysinline {
entry:
store i64 42, i64* @"resource#mutual_res_a.a_res"
ret void
}
--------------------------------------------------
Module mutual_res_b
representation : (not a type)
public submods :
public resources: b_res: mutual_res_b.b_res
public procs : mutual_res_b.<0>
imports : use mutual_res_a
use wybe
resources : b_res: fromList [(mutual_res_b.b_res,wybe.char = 'c' @mutual_res_b:nn:nn @mutual_res_b:nn:nn)]
procs :

module top-level code > public {inline,semipure} (0 calls)
0: mutual_res_b.<0>
()<{}; {<<mutual_res_b.b_res>>}; {}>:
AliasPairs: []
InterestingCallProperties: []
foreign lpvm store('c':wybe.char, <<mutual_res_b.b_res>>:wybe.char) @mutual_res_b:nn:nn

LLVM code :

; ModuleID = 'mutual_res_b'





@"resource#mutual_res_b.b_res" = global i8 undef


declare external ccc i8* @wybe_malloc(i32)


declare external ccc void @llvm.memcpy.p0i8.p0i8.i32(i8*, i8*, i32, i1)


define external fastcc void @"mutual_res_b.<0>"() alwaysinline {
entry:
store i8 99, i8* @"resource#mutual_res_b.b_res"
ret void
}
2 changes: 2 additions & 0 deletions test-cases/final-dump/mutual_res_a.wybe
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
use mutual_res_b
pub resource a_res:int = 42
81 changes: 81 additions & 0 deletions test-cases/final-dump/mutual_res_b.exp
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
======================================================================
AFTER EVERYTHING:
Module mutual_res_a
representation : (not a type)
public submods :
public resources: a_res: mutual_res_a.a_res
public procs : mutual_res_a.<0>
imports : use mutual_res_b
use wybe
resources : a_res: fromList [(mutual_res_a.a_res,wybe.int = 42 @mutual_res_a:nn:nn @mutual_res_a:nn:nn)]
procs :

module top-level code > public {inline,semipure} (0 calls)
0: mutual_res_a.<0>
()<{}; {<<mutual_res_a.a_res>>}; {}>:
AliasPairs: []
InterestingCallProperties: []
foreign lpvm store(42:wybe.int, <<mutual_res_a.a_res>>:wybe.int) @mutual_res_a:nn:nn

LLVM code :

; ModuleID = 'mutual_res_a'





@"resource#mutual_res_a.a_res" = global i64 undef


declare external ccc i8* @wybe_malloc(i32)


declare external ccc void @llvm.memcpy.p0i8.p0i8.i32(i8*, i8*, i32, i1)


define external fastcc void @"mutual_res_a.<0>"() alwaysinline {
entry:
store i64 42, i64* @"resource#mutual_res_a.a_res"
ret void
}
--------------------------------------------------
Module mutual_res_b
representation : (not a type)
public submods :
public resources: b_res: mutual_res_b.b_res
public procs : mutual_res_b.<0>
imports : use mutual_res_a
use wybe
resources : b_res: fromList [(mutual_res_b.b_res,wybe.char = 'c' @mutual_res_b:nn:nn @mutual_res_b:nn:nn)]
procs :

module top-level code > public {inline,semipure} (0 calls)
0: mutual_res_b.<0>
()<{}; {<<mutual_res_b.b_res>>}; {}>:
AliasPairs: []
InterestingCallProperties: []
foreign lpvm store('c':wybe.char, <<mutual_res_b.b_res>>:wybe.char) @mutual_res_b:nn:nn

LLVM code :

; ModuleID = 'mutual_res_b'





@"resource#mutual_res_b.b_res" = global i8 undef


declare external ccc i8* @wybe_malloc(i32)


declare external ccc void @llvm.memcpy.p0i8.p0i8.i32(i8*, i8*, i32, i1)


define external fastcc void @"mutual_res_b.<0>"() alwaysinline {
entry:
store i8 99, i8* @"resource#mutual_res_b.b_res"
ret void
}
2 changes: 2 additions & 0 deletions test-cases/final-dump/mutual_res_b.wybe
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
use mutual_res_a
pub resource b_res:char = 'c'
Loading