diff --git a/IR.log b/IR.log new file mode 100644 index 000000000..5baf44ccb --- /dev/null +++ b/IR.log @@ -0,0 +1,2308 @@ + ! Responding to env Var: GIBBON_DEBUG=4 + ! We set DEBUG based on command-line verbose arg: 4 +cleaned: +module Addimport where + import Addone + import Addtwo + + + main :: Tree + main = Addtwo.add1 2 (Addtwo.add1 (Node (Leaf 1) (Leaf 2))) + +parsed: +ParseOk (Module (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 2 1 8 64, srcInfoPoints = [SrcSpan ".hs" 2 1 2 1,SrcSpan ".hs" 2 1 2 1,SrcSpan ".hs" 3 5 3 5,SrcSpan ".hs" 4 5 4 5,SrcSpan ".hs" 7 5 7 5,SrcSpan ".hs" 8 5 8 5,SrcSpan ".hs" 8 64 8 64]}) (Just (ModuleHead (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 2 1 2 23, srcInfoPoints = [SrcSpan ".hs" 2 1 2 7,SrcSpan ".hs" 2 18 2 23]}) (ModuleName (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 2 8 2 17, srcInfoPoints = []}) "Addimport") Nothing Nothing)) [] [ImportDecl {importAnn = SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 3 5 3 18, srcInfoPoints = [SrcSpan ".hs" 3 5 3 11]}, importModule = ModuleName (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 3 12 3 18, srcInfoPoints = []}) "Addone", importQualified = False, importSrc = False, importSafe = False, importPkg = Nothing, importAs = Nothing, importSpecs = Nothing},ImportDecl {importAnn = SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 4 5 4 18, srcInfoPoints = [SrcSpan ".hs" 4 5 4 11]}, importModule = ModuleName (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 4 12 4 18, srcInfoPoints = []}) "Addtwo", importQualified = False, importSrc = False, importSafe = False, importPkg = Nothing, importAs = Nothing, importSpecs = Nothing}] [TypeSig (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 7 5 7 17, srcInfoPoints = [SrcSpan ".hs" 7 10 7 12]}) [Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 7 5 7 9, srcInfoPoints = []}) "main"] (TyCon (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 7 13 7 17, srcInfoPoints = []}) (UnQual (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 7 13 7 17, srcInfoPoints = []}) (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 7 13 7 17, srcInfoPoints = []}) "Tree"))),PatBind (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 5 8 64, srcInfoPoints = []}) (PVar (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 5 8 9, srcInfoPoints = []}) (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 5 8 9, srcInfoPoints = []}) "main")) (UnGuardedRhs (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 10 8 64, srcInfoPoints = [SrcSpan ".hs" 8 10 8 11]}) (App (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 12 8 64, srcInfoPoints = []}) (App (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 12 8 25, srcInfoPoints = []}) (Var (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 12 8 23, srcInfoPoints = []}) (Qual (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 12 8 23, srcInfoPoints = []}) (ModuleName (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 12 8 23, srcInfoPoints = []}) "Addtwo") (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 12 8 23, srcInfoPoints = []}) "add1"))) (Lit (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 24 8 25, srcInfoPoints = []}) (Int (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 24 8 25, srcInfoPoints = []}) 2 "2"))) (Paren (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 26 8 64, srcInfoPoints = [SrcSpan ".hs" 8 26 8 27,SrcSpan ".hs" 8 63 8 64]}) (App (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 27 8 63, srcInfoPoints = []}) (Var (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 27 8 38, srcInfoPoints = []}) (Qual (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 27 8 38, srcInfoPoints = []}) (ModuleName (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 27 8 38, srcInfoPoints = []}) "Addtwo") (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 27 8 38, srcInfoPoints = []}) "add1"))) (Paren (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 39 8 63, srcInfoPoints = [SrcSpan ".hs" 8 39 8 40,SrcSpan ".hs" 8 62 8 63]}) (App (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 40 8 62, srcInfoPoints = []}) (App (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 40 8 53, srcInfoPoints = []}) (Con (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 40 8 44, srcInfoPoints = []}) (UnQual (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 40 8 44, srcInfoPoints = []}) (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 40 8 44, srcInfoPoints = []}) "Node"))) (Paren (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 45 8 53, srcInfoPoints = [SrcSpan ".hs" 8 45 8 46,SrcSpan ".hs" 8 52 8 53]}) (App (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 46 8 52, srcInfoPoints = []}) (Con (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 46 8 50, srcInfoPoints = []}) (UnQual (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 46 8 50, srcInfoPoints = []}) (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 46 8 50, srcInfoPoints = []}) "Leaf"))) (Lit (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 51 8 52, srcInfoPoints = []}) (Int (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 51 8 52, srcInfoPoints = []}) 1 "1"))))) (Paren (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 54 8 62, srcInfoPoints = [SrcSpan ".hs" 8 54 8 55,SrcSpan ".hs" 8 61 8 62]}) (App (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 55 8 61, srcInfoPoints = []}) (Con (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 55 8 59, srcInfoPoints = []}) (UnQual (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 55 8 59, srcInfoPoints = []}) (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 55 8 59, srcInfoPoints = []}) "Leaf"))) (Lit (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 60 8 61, srcInfoPoints = []}) (Int (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 60 8 61, srcInfoPoints = []}) 2 "2")))))))))) Nothing],[Comment True (SrcSpan ".hs" 1 1 1 30) "# LINE 1 \".hs\" #"]) + +cleaned: +module Addone where + data Tree = Leaf Int | Node Tree Tree + + add1 :: Tree -> Tree + add1 t = case t of + Leaf x -> Leaf (x + 1) + Node x1 x2 -> Node (add1 x1) (add1 x2) + + main :: Tree + main = add1 (Node (Leaf 1) (Leaf 2)) + + +parsed: +ParseOk (Module (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 2 1 12 0, srcInfoPoints = [SrcSpan ".hs" 2 1 2 1,SrcSpan ".hs" 2 1 2 1,SrcSpan ".hs" 3 5 3 5,SrcSpan ".hs" 5 5 5 5,SrcSpan ".hs" 6 5 6 5,SrcSpan ".hs" 10 5 10 5,SrcSpan ".hs" 11 5 11 5,SrcSpan ".hs" 12 1 12 0]}) (Just (ModuleHead (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 2 1 2 20, srcInfoPoints = [SrcSpan ".hs" 2 1 2 7,SrcSpan ".hs" 2 15 2 20]}) (ModuleName (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 2 8 2 14, srcInfoPoints = []}) "Addone") Nothing Nothing)) [] [] [DataDecl (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 3 5 3 42, srcInfoPoints = [SrcSpan ".hs" 3 15 3 16,SrcSpan ".hs" 3 26 3 27]}) (DataType (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 3 5 3 9, srcInfoPoints = []})) Nothing (DHead (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 3 10 3 14, srcInfoPoints = []}) (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 3 10 3 14, srcInfoPoints = []}) "Tree")) [QualConDecl (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 3 17 3 25, srcInfoPoints = []}) Nothing Nothing (ConDecl (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 3 17 3 25, srcInfoPoints = []}) (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 3 17 3 21, srcInfoPoints = []}) "Leaf") [TyCon (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 3 22 3 25, srcInfoPoints = []}) (UnQual (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 3 22 3 25, srcInfoPoints = []}) (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 3 22 3 25, srcInfoPoints = []}) "Int"))]),QualConDecl (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 3 28 3 42, srcInfoPoints = []}) Nothing Nothing (ConDecl (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 3 28 3 42, srcInfoPoints = []}) (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 3 28 3 32, srcInfoPoints = []}) "Node") [TyCon (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 3 33 3 37, srcInfoPoints = []}) (UnQual (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 3 33 3 37, srcInfoPoints = []}) (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 3 33 3 37, srcInfoPoints = []}) "Tree")),TyCon (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 3 38 3 42, srcInfoPoints = []}) (UnQual (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 3 38 3 42, srcInfoPoints = []}) (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 3 38 3 42, srcInfoPoints = []}) "Tree"))])] [],TypeSig (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 5 5 5 25, srcInfoPoints = [SrcSpan ".hs" 5 10 5 12]}) [Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 5 5 5 9, srcInfoPoints = []}) "add1"] (TyFun (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 5 13 5 25, srcInfoPoints = [SrcSpan ".hs" 5 18 5 20]}) (TyCon (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 5 13 5 17, srcInfoPoints = []}) (UnQual (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 5 13 5 17, srcInfoPoints = []}) (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 5 13 5 17, srcInfoPoints = []}) "Tree"))) (TyCon (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 5 21 5 25, srcInfoPoints = []}) (UnQual (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 5 21 5 25, srcInfoPoints = []}) (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 5 21 5 25, srcInfoPoints = []}) "Tree")))),FunBind (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 6 5 8 51, srcInfoPoints = []}) [Match (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 6 5 8 51, srcInfoPoints = []}) (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 6 5 6 9, srcInfoPoints = []}) "add1") [PVar (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 6 10 6 11, srcInfoPoints = []}) (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 6 10 6 11, srcInfoPoints = []}) "t")] (UnGuardedRhs (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 6 12 8 51, srcInfoPoints = [SrcSpan ".hs" 6 12 6 13]}) (Case (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 6 14 8 51, srcInfoPoints = [SrcSpan ".hs" 6 14 6 18,SrcSpan ".hs" 6 21 6 23,SrcSpan ".hs" 7 13 7 13,SrcSpan ".hs" 8 13 8 13,SrcSpan ".hs" 10 5 10 0]}) (Var (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 6 19 6 20, srcInfoPoints = []}) (UnQual (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 6 19 6 20, srcInfoPoints = []}) (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 6 19 6 20, srcInfoPoints = []}) "t"))) [Alt (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 7 13 7 39, srcInfoPoints = []}) (PApp (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 7 13 7 19, srcInfoPoints = []}) (UnQual (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 7 13 7 17, srcInfoPoints = []}) (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 7 13 7 17, srcInfoPoints = []}) "Leaf")) [PVar (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 7 18 7 19, srcInfoPoints = []}) (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 7 18 7 19, srcInfoPoints = []}) "x")]) (UnGuardedRhs (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 7 24 7 39, srcInfoPoints = [SrcSpan ".hs" 7 24 7 26]}) (App (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 7 27 7 39, srcInfoPoints = []}) (Con (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 7 27 7 31, srcInfoPoints = []}) (UnQual (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 7 27 7 31, srcInfoPoints = []}) (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 7 27 7 31, srcInfoPoints = []}) "Leaf"))) (Paren (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 7 32 7 39, srcInfoPoints = [SrcSpan ".hs" 7 32 7 33,SrcSpan ".hs" 7 38 7 39]}) (InfixApp (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 7 33 7 38, srcInfoPoints = []}) (Var (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 7 33 7 34, srcInfoPoints = []}) (UnQual (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 7 33 7 34, srcInfoPoints = []}) (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 7 33 7 34, srcInfoPoints = []}) "x"))) (QVarOp (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 7 35 7 36, srcInfoPoints = []}) (UnQual (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 7 35 7 36, srcInfoPoints = []}) (Symbol (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 7 35 7 36, srcInfoPoints = []}) "+"))) (Lit (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 7 37 7 38, srcInfoPoints = []}) (Int (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 7 37 7 38, srcInfoPoints = []}) 1 "1")))))) Nothing,Alt (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 13 8 51, srcInfoPoints = []}) (PApp (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 13 8 23, srcInfoPoints = []}) (UnQual (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 13 8 17, srcInfoPoints = []}) (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 13 8 17, srcInfoPoints = []}) "Node")) [PVar (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 18 8 20, srcInfoPoints = []}) (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 18 8 20, srcInfoPoints = []}) "x1"),PVar (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 21 8 23, srcInfoPoints = []}) (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 21 8 23, srcInfoPoints = []}) "x2")]) (UnGuardedRhs (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 24 8 51, srcInfoPoints = [SrcSpan ".hs" 8 24 8 26]}) (App (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 27 8 51, srcInfoPoints = []}) (App (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 27 8 41, srcInfoPoints = []}) (Con (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 27 8 31, srcInfoPoints = []}) (UnQual (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 27 8 31, srcInfoPoints = []}) (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 27 8 31, srcInfoPoints = []}) "Node"))) (Paren (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 32 8 41, srcInfoPoints = [SrcSpan ".hs" 8 32 8 33,SrcSpan ".hs" 8 40 8 41]}) (App (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 33 8 40, srcInfoPoints = []}) (Var (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 33 8 37, srcInfoPoints = []}) (UnQual (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 33 8 37, srcInfoPoints = []}) (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 33 8 37, srcInfoPoints = []}) "add1"))) (Var (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 38 8 40, srcInfoPoints = []}) (UnQual (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 38 8 40, srcInfoPoints = []}) (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 38 8 40, srcInfoPoints = []}) "x1")))))) (Paren (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 42 8 51, srcInfoPoints = [SrcSpan ".hs" 8 42 8 43,SrcSpan ".hs" 8 50 8 51]}) (App (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 43 8 50, srcInfoPoints = []}) (Var (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 43 8 47, srcInfoPoints = []}) (UnQual (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 43 8 47, srcInfoPoints = []}) (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 43 8 47, srcInfoPoints = []}) "add1"))) (Var (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 48 8 50, srcInfoPoints = []}) (UnQual (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 48 8 50, srcInfoPoints = []}) (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 48 8 50, srcInfoPoints = []}) "x2"))))))) Nothing])) Nothing],TypeSig (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 10 5 10 17, srcInfoPoints = [SrcSpan ".hs" 10 10 10 12]}) [Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 10 5 10 9, srcInfoPoints = []}) "main"] (TyCon (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 10 13 10 17, srcInfoPoints = []}) (UnQual (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 10 13 10 17, srcInfoPoints = []}) (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 10 13 10 17, srcInfoPoints = []}) "Tree"))),PatBind (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 11 5 11 41, srcInfoPoints = []}) (PVar (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 11 5 11 9, srcInfoPoints = []}) (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 11 5 11 9, srcInfoPoints = []}) "main")) (UnGuardedRhs (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 11 10 11 41, srcInfoPoints = [SrcSpan ".hs" 11 10 11 11]}) (App (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 11 12 11 41, srcInfoPoints = []}) (Var (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 11 12 11 16, srcInfoPoints = []}) (UnQual (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 11 12 11 16, srcInfoPoints = []}) (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 11 12 11 16, srcInfoPoints = []}) "add1"))) (Paren (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 11 17 11 41, srcInfoPoints = [SrcSpan ".hs" 11 17 11 18,SrcSpan ".hs" 11 40 11 41]}) (App (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 11 18 11 40, srcInfoPoints = []}) (App (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 11 18 11 31, srcInfoPoints = []}) (Con (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 11 18 11 22, srcInfoPoints = []}) (UnQual (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 11 18 11 22, srcInfoPoints = []}) (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 11 18 11 22, srcInfoPoints = []}) "Node"))) (Paren (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 11 23 11 31, srcInfoPoints = [SrcSpan ".hs" 11 23 11 24,SrcSpan ".hs" 11 30 11 31]}) (App (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 11 24 11 30, srcInfoPoints = []}) (Con (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 11 24 11 28, srcInfoPoints = []}) (UnQual (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 11 24 11 28, srcInfoPoints = []}) (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 11 24 11 28, srcInfoPoints = []}) "Leaf"))) (Lit (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 11 29 11 30, srcInfoPoints = []}) (Int (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 11 29 11 30, srcInfoPoints = []}) 1 "1"))))) (Paren (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 11 32 11 40, srcInfoPoints = [SrcSpan ".hs" 11 32 11 33,SrcSpan ".hs" 11 39 11 40]}) (App (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 11 33 11 39, srcInfoPoints = []}) (Con (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 11 33 11 37, srcInfoPoints = []}) (UnQual (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 11 33 11 37, srcInfoPoints = []}) (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 11 33 11 37, srcInfoPoints = []}) "Leaf"))) (Lit (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 11 38 11 39, srcInfoPoints = []}) (Int (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 11 38 11 39, srcInfoPoints = []}) 2 "2")))))))) Nothing],[Comment True (SrcSpan ".hs" 1 1 1 30) "# LINE 1 \".hs\" #"]) + +cleaned: +module Addone where + data Tree = Leaf Int | Node Tree Tree + + add1 :: Tree -> Tree + add1 t = case t of + Leaf x -> Leaf (x + 1) + Node x1 x2 -> Node (add1 x1) (add1 x2) + + main :: Tree + main = add1 (Node (Leaf 1) (Leaf 2)) + + +parsed: +ParseOk (Module (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 2 1 12 0, srcInfoPoints = [SrcSpan ".hs" 2 1 2 1,SrcSpan ".hs" 2 1 2 1,SrcSpan ".hs" 3 5 3 5,SrcSpan ".hs" 5 5 5 5,SrcSpan ".hs" 6 5 6 5,SrcSpan ".hs" 10 5 10 5,SrcSpan ".hs" 11 5 11 5,SrcSpan ".hs" 12 1 12 0]}) (Just (ModuleHead (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 2 1 2 20, srcInfoPoints = [SrcSpan ".hs" 2 1 2 7,SrcSpan ".hs" 2 15 2 20]}) (ModuleName (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 2 8 2 14, srcInfoPoints = []}) "Addone") Nothing Nothing)) [] [] [DataDecl (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 3 5 3 42, srcInfoPoints = [SrcSpan ".hs" 3 15 3 16,SrcSpan ".hs" 3 26 3 27]}) (DataType (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 3 5 3 9, srcInfoPoints = []})) Nothing (DHead (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 3 10 3 14, srcInfoPoints = []}) (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 3 10 3 14, srcInfoPoints = []}) "Tree")) [QualConDecl (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 3 17 3 25, srcInfoPoints = []}) Nothing Nothing (ConDecl (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 3 17 3 25, srcInfoPoints = []}) (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 3 17 3 21, srcInfoPoints = []}) "Leaf") [TyCon (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 3 22 3 25, srcInfoPoints = []}) (UnQual (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 3 22 3 25, srcInfoPoints = []}) (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 3 22 3 25, srcInfoPoints = []}) "Int"))]),QualConDecl (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 3 28 3 42, srcInfoPoints = []}) Nothing Nothing (ConDecl (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 3 28 3 42, srcInfoPoints = []}) (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 3 28 3 32, srcInfoPoints = []}) "Node") [TyCon (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 3 33 3 37, srcInfoPoints = []}) (UnQual (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 3 33 3 37, srcInfoPoints = []}) (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 3 33 3 37, srcInfoPoints = []}) "Tree")),TyCon (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 3 38 3 42, srcInfoPoints = []}) (UnQual (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 3 38 3 42, srcInfoPoints = []}) (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 3 38 3 42, srcInfoPoints = []}) "Tree"))])] [],TypeSig (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 5 5 5 25, srcInfoPoints = [SrcSpan ".hs" 5 10 5 12]}) [Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 5 5 5 9, srcInfoPoints = []}) "add1"] (TyFun (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 5 13 5 25, srcInfoPoints = [SrcSpan ".hs" 5 18 5 20]}) (TyCon (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 5 13 5 17, srcInfoPoints = []}) (UnQual (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 5 13 5 17, srcInfoPoints = []}) (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 5 13 5 17, srcInfoPoints = []}) "Tree"))) (TyCon (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 5 21 5 25, srcInfoPoints = []}) (UnQual (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 5 21 5 25, srcInfoPoints = []}) (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 5 21 5 25, srcInfoPoints = []}) "Tree")))),FunBind (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 6 5 8 51, srcInfoPoints = []}) [Match (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 6 5 8 51, srcInfoPoints = []}) (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 6 5 6 9, srcInfoPoints = []}) "add1") [PVar (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 6 10 6 11, srcInfoPoints = []}) (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 6 10 6 11, srcInfoPoints = []}) "t")] (UnGuardedRhs (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 6 12 8 51, srcInfoPoints = [SrcSpan ".hs" 6 12 6 13]}) (Case (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 6 14 8 51, srcInfoPoints = [SrcSpan ".hs" 6 14 6 18,SrcSpan ".hs" 6 21 6 23,SrcSpan ".hs" 7 13 7 13,SrcSpan ".hs" 8 13 8 13,SrcSpan ".hs" 10 5 10 0]}) (Var (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 6 19 6 20, srcInfoPoints = []}) (UnQual (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 6 19 6 20, srcInfoPoints = []}) (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 6 19 6 20, srcInfoPoints = []}) "t"))) [Alt (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 7 13 7 39, srcInfoPoints = []}) (PApp (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 7 13 7 19, srcInfoPoints = []}) (UnQual (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 7 13 7 17, srcInfoPoints = []}) (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 7 13 7 17, srcInfoPoints = []}) "Leaf")) [PVar (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 7 18 7 19, srcInfoPoints = []}) (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 7 18 7 19, srcInfoPoints = []}) "x")]) (UnGuardedRhs (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 7 24 7 39, srcInfoPoints = [SrcSpan ".hs" 7 24 7 26]}) (App (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 7 27 7 39, srcInfoPoints = []}) (Con (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 7 27 7 31, srcInfoPoints = []}) (UnQual (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 7 27 7 31, srcInfoPoints = []}) (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 7 27 7 31, srcInfoPoints = []}) "Leaf"))) (Paren (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 7 32 7 39, srcInfoPoints = [SrcSpan ".hs" 7 32 7 33,SrcSpan ".hs" 7 38 7 39]}) (InfixApp (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 7 33 7 38, srcInfoPoints = []}) (Var (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 7 33 7 34, srcInfoPoints = []}) (UnQual (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 7 33 7 34, srcInfoPoints = []}) (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 7 33 7 34, srcInfoPoints = []}) "x"))) (QVarOp (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 7 35 7 36, srcInfoPoints = []}) (UnQual (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 7 35 7 36, srcInfoPoints = []}) (Symbol (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 7 35 7 36, srcInfoPoints = []}) "+"))) (Lit (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 7 37 7 38, srcInfoPoints = []}) (Int (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 7 37 7 38, srcInfoPoints = []}) 1 "1")))))) Nothing,Alt (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 13 8 51, srcInfoPoints = []}) (PApp (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 13 8 23, srcInfoPoints = []}) (UnQual (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 13 8 17, srcInfoPoints = []}) (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 13 8 17, srcInfoPoints = []}) "Node")) [PVar (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 18 8 20, srcInfoPoints = []}) (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 18 8 20, srcInfoPoints = []}) "x1"),PVar (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 21 8 23, srcInfoPoints = []}) (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 21 8 23, srcInfoPoints = []}) "x2")]) (UnGuardedRhs (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 24 8 51, srcInfoPoints = [SrcSpan ".hs" 8 24 8 26]}) (App (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 27 8 51, srcInfoPoints = []}) (App (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 27 8 41, srcInfoPoints = []}) (Con (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 27 8 31, srcInfoPoints = []}) (UnQual (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 27 8 31, srcInfoPoints = []}) (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 27 8 31, srcInfoPoints = []}) "Node"))) (Paren (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 32 8 41, srcInfoPoints = [SrcSpan ".hs" 8 32 8 33,SrcSpan ".hs" 8 40 8 41]}) (App (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 33 8 40, srcInfoPoints = []}) (Var (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 33 8 37, srcInfoPoints = []}) (UnQual (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 33 8 37, srcInfoPoints = []}) (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 33 8 37, srcInfoPoints = []}) "add1"))) (Var (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 38 8 40, srcInfoPoints = []}) (UnQual (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 38 8 40, srcInfoPoints = []}) (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 38 8 40, srcInfoPoints = []}) "x1")))))) (Paren (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 42 8 51, srcInfoPoints = [SrcSpan ".hs" 8 42 8 43,SrcSpan ".hs" 8 50 8 51]}) (App (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 43 8 50, srcInfoPoints = []}) (Var (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 43 8 47, srcInfoPoints = []}) (UnQual (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 43 8 47, srcInfoPoints = []}) (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 43 8 47, srcInfoPoints = []}) "add1"))) (Var (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 48 8 50, srcInfoPoints = []}) (UnQual (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 48 8 50, srcInfoPoints = []}) (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 8 48 8 50, srcInfoPoints = []}) "x2"))))))) Nothing])) Nothing],TypeSig (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 10 5 10 17, srcInfoPoints = [SrcSpan ".hs" 10 10 10 12]}) [Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 10 5 10 9, srcInfoPoints = []}) "main"] (TyCon (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 10 13 10 17, srcInfoPoints = []}) (UnQual (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 10 13 10 17, srcInfoPoints = []}) (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 10 13 10 17, srcInfoPoints = []}) "Tree"))),PatBind (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 11 5 11 41, srcInfoPoints = []}) (PVar (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 11 5 11 9, srcInfoPoints = []}) (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 11 5 11 9, srcInfoPoints = []}) "main")) (UnGuardedRhs (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 11 10 11 41, srcInfoPoints = [SrcSpan ".hs" 11 10 11 11]}) (App (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 11 12 11 41, srcInfoPoints = []}) (Var (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 11 12 11 16, srcInfoPoints = []}) (UnQual (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 11 12 11 16, srcInfoPoints = []}) (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 11 12 11 16, srcInfoPoints = []}) "add1"))) (Paren (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 11 17 11 41, srcInfoPoints = [SrcSpan ".hs" 11 17 11 18,SrcSpan ".hs" 11 40 11 41]}) (App (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 11 18 11 40, srcInfoPoints = []}) (App (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 11 18 11 31, srcInfoPoints = []}) (Con (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 11 18 11 22, srcInfoPoints = []}) (UnQual (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 11 18 11 22, srcInfoPoints = []}) (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 11 18 11 22, srcInfoPoints = []}) "Node"))) (Paren (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 11 23 11 31, srcInfoPoints = [SrcSpan ".hs" 11 23 11 24,SrcSpan ".hs" 11 30 11 31]}) (App (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 11 24 11 30, srcInfoPoints = []}) (Con (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 11 24 11 28, srcInfoPoints = []}) (UnQual (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 11 24 11 28, srcInfoPoints = []}) (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 11 24 11 28, srcInfoPoints = []}) "Leaf"))) (Lit (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 11 29 11 30, srcInfoPoints = []}) (Int (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 11 29 11 30, srcInfoPoints = []}) 1 "1"))))) (Paren (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 11 32 11 40, srcInfoPoints = [SrcSpan ".hs" 11 32 11 33,SrcSpan ".hs" 11 39 11 40]}) (App (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 11 33 11 39, srcInfoPoints = []}) (Con (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 11 33 11 37, srcInfoPoints = []}) (UnQual (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 11 33 11 37, srcInfoPoints = []}) (Ident (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 11 33 11 37, srcInfoPoints = []}) "Leaf"))) (Lit (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 11 38 11 39, srcInfoPoints = []}) (Int (SrcSpanInfo {srcInfoSpan = SrcSpan ".hs" 11 38 11 39, srcInfoPoints = []}) 2 "2")))))))) Nothing],[Comment True (SrcSpan ".hs" 1 1 1 30) "# LINE 1 \".hs\" #"]) + +config: Config {input = Unspecified, mode = ToExe, benchInput = Nothing, arrayInput = Nothing, verbosity = 4, cc = "gcc", optc = " -O3 -flto ", cfile = Nothing, exefile = Nothing, backend = C, dynflags = DynFlags {generalFlags = fromList [], debugFlags = fromList []}, srcFile = Nothing} + + [compiler] pipeline starting, parsed program: +================================================================================ +Prog {ddefs = [(Tree, + DDef {tyName = "Tree", + tyArgs = [], + dataCons = [("Leaf", [(False, IntTy)]), + ("Node", + [(False, PackedTy "Tree" []),(False, PackedTy "Tree" [])])]})], + fundefs = [(add1, + FunDef {funName = "add1", + funArgs = [t], + funTy = ForAll [] + (ArrowTy [PackedTy "Tree" []] (PackedTy "Tree" [])), + funBody = CaseE (VarE "t") + [("Leaf", + [(x, MetaTv $2)], + DataConE (MetaTv $1) + "Leaf" + [PrimAppE AddP [VarE "x",LitE 1]]), + ("Node", + [(x1, MetaTv $4),(x2, MetaTv $5)], + DataConE (MetaTv $3) + "Node" + [AppE "add1" [] [VarE "x1"], + AppE "add1" [] [VarE "x2"]])], + funMeta = FunMeta {funRec = NotRec, + funInline = NoInline, + funCanTriggerGC = False, + funOptLayout = NoLayoutOpt, + userConstraintsDataCon = Nothing}})], + mainExp = Nothing} + + [compiler] Running pass, renameModules +Pass output: +================================================================================ +data Tree = Leaf Int | + Node (Packed Tree []) (Packed Tree []) +{meta: FunMeta {funRec = NotRec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +add1 :: forall. ((Packed Tree []) -> (Packed Tree [])) +add1 t_0 = + case t_0 of + Leaf x_1::$2 -> + (Leaf $1 x_1 + 1) + Node x1_2::$4 x2_3::$5 -> + (Node $3 (add1 [] x1_2) (add1 [] x2_3)) + + + [compiler] Running pass, freshen +Pass output: +================================================================================ +data Tree = Leaf Int | + Node (Packed Tree []) (Packed Tree []) +{meta: FunMeta {funRec = NotRec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +add1 :: forall. ((Packed Tree []) -> (Packed Tree [])) +add1 t_0_4 = + case t_0_4 of + Leaf x_1_5::$2 -> + (Leaf $1 x_1_5 + 1) + Node x1_2_6::$4 x2_3_7::$5 -> + (Node $3 (add1 [] x1_2_6) (add1 [] x2_3_7)) + + + [compiler] Running pass, typecheck +Pass output: +================================================================================ +data Tree = Leaf Int | + Node (Packed Tree []) (Packed Tree []) +{meta: FunMeta {funRec = NotRec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +add1 :: forall. ((Packed Tree []) -> (Packed Tree [])) +add1 t_0_4 = + case t_0_4 of + Leaf x_1_5::Int -> + (Leaf () x_1_5 + 1) + Node x1_2_6::(Packed Tree []) x2_3_7::(Packed Tree []) -> + (Node () (add1 [] x1_2_6) (add1 [] x2_3_7)) + + + [compiler] Running pass, bindLambdas +Pass output: +================================================================================ +data Tree = Leaf Int | + Node (Packed Tree []) (Packed Tree []) +{meta: FunMeta {funRec = NotRec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +add1 :: forall. ((Packed Tree []) -> (Packed Tree [])) +add1 t_0_4 = + case t_0_4 of + Leaf x_1_5::Int -> + (Leaf () x_1_5 + 1) + Node x1_2_6::(Packed Tree []) x2_3_7::(Packed Tree []) -> + (Node () (add1 [] x1_2_6) (add1 [] x2_3_7)) + + + [compiler] Running pass, monomorphize +Pass output: +================================================================================ +data Tree = Leaf Int | + Node (Packed Tree []) (Packed Tree []) +{meta: FunMeta {funRec = NotRec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +add1 :: forall. ((Packed Tree []) -> (Packed Tree [])) +add1 t_0_4 = + case t_0_4 of + Leaf x_1_5::Int -> + (Leaf () x_1_5 + 1) + Node x1_2_6::(Packed Tree []) x2_3_7::(Packed Tree []) -> + (Node () (add1 [] x1_2_6) (add1 [] x2_3_7)) + + + [compiler] Running pass, specLambdas +Pass output: +================================================================================ +data Tree = Leaf Int | + Node (Packed Tree []) (Packed Tree []) +{meta: FunMeta {funRec = NotRec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +add1 :: forall. ((Packed Tree []) -> (Packed Tree [])) +add1 t_0_4 = + case t_0_4 of + Leaf x_1_5::Int -> + (Leaf () x_1_5 + 1) + Node x1_2_6::(Packed Tree []) x2_3_7::(Packed Tree []) -> + (Node () (add1 [] x1_2_6) (add1 [] x2_3_7)) + + + [compiler] Running pass, desugarL0 +Pass output: +================================================================================ +data Tree = Leaf Int | + Node (Packed Tree []) (Packed Tree []) +{meta: FunMeta {funRec = NotRec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +add1 :: forall. ((Packed Tree []) -> (Packed Tree [])) +add1 t_0_4 = + case t_0_4 of + Leaf x_1_5::() -> + (Leaf () x_1_5 + 1) + Node x1_2_6::() x2_3_7::() -> + (Node () (add1 [] x1_2_6) (add1 [] x2_3_7)) + +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_copy_Tree :: forall. ((Packed Tree []) -> (Packed Tree [])) +_copy_Tree arg_16 = + case arg_16 of + Leaf x_17::() -> + let y_18 :: Int = x_17 in + (Leaf () y_18) + Node x_19::() x_20::() -> + let y_21 :: (Packed Tree []) = (_copy_Tree [] x_19) in + let y_22 :: (Packed Tree []) = (_copy_Tree [] x_20) in + (Node () y_21 y_22) + +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_copy_without_ptrs_Tree :: forall. ((Packed Tree []) -> (Packed Tree [])) +_copy_without_ptrs_Tree arg_23 = + case arg_23 of + Leaf x_24::() -> + let y_25 :: Int = x_24 in + (Leaf () y_25) + Node x_26::() x_27::() -> + let y_28 :: (Packed Tree []) = (_copy_without_ptrs_Tree [] x_26) in + let y_29 :: (Packed Tree []) = (_copy_without_ptrs_Tree [] x_27) in + (Node () y_28 y_29) + +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_traverse_Tree :: forall. ((Packed Tree []) -> ()) +_traverse_Tree arg_30 = + case arg_30 of + Leaf x_31::() -> + () + Node x_33::() x_34::() -> + let y_35 :: () = (_traverse_Tree [] x_33) in + let y_36 :: () = (_traverse_Tree [] x_34) in + () + +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_print_Tree :: forall. ((Packed Tree []) -> ()) +_print_Tree arg_37 = + case arg_37 of + Leaf x_38::() -> + let wildcard_40 :: () = printsym("(Leaf") in + let wildcard_42 :: () = printsym(" ") in + let y_39 :: () = printint(x_38) in + let wildcard_41 :: () = printsym(")") in + () + Node x_43::() x_44::() -> + let wildcard_47 :: () = printsym("(Node") in + let wildcard_50 :: () = printsym(" ") in + let y_45 :: () = (_print_Tree [] x_43) in + let wildcard_49 :: () = printsym(" ") in + let y_46 :: () = (_print_Tree [] x_44) in + let wildcard_48 :: () = printsym(")") in + () + + + [compiler] Running pass, floatOutCase +Pass output: +================================================================================ +data Tree = Leaf Int | + Node (Packed Tree []) (Packed Tree []) +{meta: FunMeta {funRec = NotRec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +add1 :: forall. ((Packed Tree []) -> (Packed Tree [])) +add1 t_0_4 = + case t_0_4 of + Leaf x_1_5::() -> + (Leaf () x_1_5 + 1) + Node x1_2_6::() x2_3_7::() -> + (Node () (add1 [] x1_2_6) (add1 [] x2_3_7)) + +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_copy_Tree :: forall. ((Packed Tree []) -> (Packed Tree [])) +_copy_Tree arg_16 = + case arg_16 of + Leaf x_17::() -> + let y_18 :: Int = x_17 in + (Leaf () y_18) + Node x_19::() x_20::() -> + let y_21 :: (Packed Tree []) = (_copy_Tree [] x_19) in + let y_22 :: (Packed Tree []) = (_copy_Tree [] x_20) in + (Node () y_21 y_22) + +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_copy_without_ptrs_Tree :: forall. ((Packed Tree []) -> (Packed Tree [])) +_copy_without_ptrs_Tree arg_23 = + case arg_23 of + Leaf x_24::() -> + let y_25 :: Int = x_24 in + (Leaf () y_25) + Node x_26::() x_27::() -> + let y_28 :: (Packed Tree []) = (_copy_without_ptrs_Tree [] x_26) in + let y_29 :: (Packed Tree []) = (_copy_without_ptrs_Tree [] x_27) in + (Node () y_28 y_29) + +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_traverse_Tree :: forall. ((Packed Tree []) -> ()) +_traverse_Tree arg_30 = + case arg_30 of + Leaf x_31::() -> + () + Node x_33::() x_34::() -> + let y_35 :: () = (_traverse_Tree [] x_33) in + let y_36 :: () = (_traverse_Tree [] x_34) in + () + +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_print_Tree :: forall. ((Packed Tree []) -> ()) +_print_Tree arg_37 = + case arg_37 of + Leaf x_38::() -> + let wildcard_40 :: () = printsym("(Leaf") in + let wildcard_42 :: () = printsym(" ") in + let y_39 :: () = printint(x_38) in + let wildcard_41 :: () = printsym(")") in + () + Node x_43::() x_44::() -> + let wildcard_47 :: () = printsym("(Node") in + let wildcard_50 :: () = printsym(" ") in + let y_45 :: () = (_print_Tree [] x_43) in + let wildcard_49 :: () = printsym(" ") in + let y_46 :: () = (_print_Tree [] x_44) in + let wildcard_48 :: () = printsym(")") in + () + + + [compiler] Running pass, toL1 +Pass output: +================================================================================ +data Tree = Leaf Int | + Node (Packed Tree) (Packed Tree) +{meta: FunMeta {funRec = NotRec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +add1 :: (Packed Tree) -> (Packed Tree) +add1 t_0_4 = + case t_0_4 of + Leaf x_1_5 -> + (Leaf x_1_5 + 1) + Node x1_2_6 x2_3_7 -> + (Node (add1 [] x1_2_6) (add1 [] x2_3_7)) + +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_copy_Tree :: (Packed Tree) -> (Packed Tree) +_copy_Tree arg_16 = + case arg_16 of + Leaf x_17 -> + let y_18 :: Int = x_17 in + (Leaf y_18) + Node x_19 x_20 -> + let y_21 :: (Packed Tree) = (_copy_Tree [] x_19) in + let y_22 :: (Packed Tree) = (_copy_Tree [] x_20) in + (Node y_21 y_22) + +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_copy_without_ptrs_Tree :: (Packed Tree) -> (Packed Tree) +_copy_without_ptrs_Tree arg_23 = + case arg_23 of + Leaf x_24 -> + let y_25 :: Int = x_24 in + (Leaf y_25) + Node x_26 x_27 -> + let y_28 :: (Packed Tree) = (_copy_without_ptrs_Tree [] x_26) in + let y_29 :: (Packed Tree) = (_copy_without_ptrs_Tree [] x_27) in + (Node y_28 y_29) + +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_traverse_Tree :: (Packed Tree) -> () +_traverse_Tree arg_30 = + case arg_30 of + Leaf x_31 -> + () + Node x_33 x_34 -> + let y_35 :: () = (_traverse_Tree [] x_33) in + let y_36 :: () = (_traverse_Tree [] x_34) in + () + +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_print_Tree :: (Packed Tree) -> () +_print_Tree arg_37 = + case arg_37 of + Leaf x_38 -> + let wildcard_40 :: () = printsym("(Leaf") in + let wildcard_42 :: () = printsym(" ") in + let y_39 :: () = printint(x_38) in + let wildcard_41 :: () = printsym(")") in + () + Node x_43 x_44 -> + let wildcard_47 :: () = printsym("(Node") in + let wildcard_50 :: () = printsym(" ") in + let y_45 :: () = (_print_Tree [] x_43) in + let wildcard_49 :: () = printsym(" ") in + let y_46 :: () = (_print_Tree [] x_44) in + let wildcard_48 :: () = printsym(")") in + () + + + [compiler] Running pass, typecheck +Pass output: +================================================================================ +data Tree = Leaf Int | + Node (Packed Tree) (Packed Tree) +{meta: FunMeta {funRec = NotRec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +add1 :: (Packed Tree) -> (Packed Tree) +add1 t_0_4 = + case t_0_4 of + Leaf x_1_5 -> + (Leaf x_1_5 + 1) + Node x1_2_6 x2_3_7 -> + (Node (add1 [] x1_2_6) (add1 [] x2_3_7)) + +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_copy_Tree :: (Packed Tree) -> (Packed Tree) +_copy_Tree arg_16 = + case arg_16 of + Leaf x_17 -> + let y_18 :: Int = x_17 in + (Leaf y_18) + Node x_19 x_20 -> + let y_21 :: (Packed Tree) = (_copy_Tree [] x_19) in + let y_22 :: (Packed Tree) = (_copy_Tree [] x_20) in + (Node y_21 y_22) + +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_copy_without_ptrs_Tree :: (Packed Tree) -> (Packed Tree) +_copy_without_ptrs_Tree arg_23 = + case arg_23 of + Leaf x_24 -> + let y_25 :: Int = x_24 in + (Leaf y_25) + Node x_26 x_27 -> + let y_28 :: (Packed Tree) = (_copy_without_ptrs_Tree [] x_26) in + let y_29 :: (Packed Tree) = (_copy_without_ptrs_Tree [] x_27) in + (Node y_28 y_29) + +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_traverse_Tree :: (Packed Tree) -> () +_traverse_Tree arg_30 = + case arg_30 of + Leaf x_31 -> + () + Node x_33 x_34 -> + let y_35 :: () = (_traverse_Tree [] x_33) in + let y_36 :: () = (_traverse_Tree [] x_34) in + () + +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_print_Tree :: (Packed Tree) -> () +_print_Tree arg_37 = + case arg_37 of + Leaf x_38 -> + let wildcard_40 :: () = printsym("(Leaf") in + let wildcard_42 :: () = printsym(" ") in + let y_39 :: () = printint(x_38) in + let wildcard_41 :: () = printsym(")") in + () + Node x_43 x_44 -> + let wildcard_47 :: () = printsym("(Node") in + let wildcard_50 :: () = printsym(" ") in + let y_45 :: () = (_print_Tree [] x_43) in + let wildcard_49 :: () = printsym(" ") in + let y_46 :: () = (_print_Tree [] x_44) in + let wildcard_48 :: () = printsym(")") in + () + + + [compiler] Running pass, benchMainExp +Pass output: +================================================================================ +data Tree = Leaf Int | + Node (Packed Tree) (Packed Tree) +{meta: FunMeta {funRec = NotRec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +add1 :: (Packed Tree) -> (Packed Tree) +add1 t_0_4 = + case t_0_4 of + Leaf x_1_5 -> + (Leaf x_1_5 + 1) + Node x1_2_6 x2_3_7 -> + (Node (add1 [] x1_2_6) (add1 [] x2_3_7)) + +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_copy_Tree :: (Packed Tree) -> (Packed Tree) +_copy_Tree arg_16 = + case arg_16 of + Leaf x_17 -> + let y_18 :: Int = x_17 in + (Leaf y_18) + Node x_19 x_20 -> + let y_21 :: (Packed Tree) = (_copy_Tree [] x_19) in + let y_22 :: (Packed Tree) = (_copy_Tree [] x_20) in + (Node y_21 y_22) + +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_copy_without_ptrs_Tree :: (Packed Tree) -> (Packed Tree) +_copy_without_ptrs_Tree arg_23 = + case arg_23 of + Leaf x_24 -> + let y_25 :: Int = x_24 in + (Leaf y_25) + Node x_26 x_27 -> + let y_28 :: (Packed Tree) = (_copy_without_ptrs_Tree [] x_26) in + let y_29 :: (Packed Tree) = (_copy_without_ptrs_Tree [] x_27) in + (Node y_28 y_29) + +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_traverse_Tree :: (Packed Tree) -> () +_traverse_Tree arg_30 = + case arg_30 of + Leaf x_31 -> + () + Node x_33 x_34 -> + let y_35 :: () = (_traverse_Tree [] x_33) in + let y_36 :: () = (_traverse_Tree [] x_34) in + () + +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_print_Tree :: (Packed Tree) -> () +_print_Tree arg_37 = + case arg_37 of + Leaf x_38 -> + let wildcard_40 :: () = printsym("(Leaf") in + let wildcard_42 :: () = printsym(" ") in + let y_39 :: () = printint(x_38) in + let wildcard_41 :: () = printsym(")") in + () + Node x_43 x_44 -> + let wildcard_47 :: () = printsym("(Node") in + let wildcard_50 :: () = printsym(" ") in + let y_45 :: () = (_print_Tree [] x_43) in + let wildcard_49 :: () = printsym(" ") in + let y_46 :: () = (_print_Tree [] x_44) in + let wildcard_48 :: () = printsym(")") in + () + + + [compiler] Running pass, typecheck +Pass output: +================================================================================ +data Tree = Leaf Int | + Node (Packed Tree) (Packed Tree) +{meta: FunMeta {funRec = NotRec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +add1 :: (Packed Tree) -> (Packed Tree) +add1 t_0_4 = + case t_0_4 of + Leaf x_1_5 -> + (Leaf x_1_5 + 1) + Node x1_2_6 x2_3_7 -> + (Node (add1 [] x1_2_6) (add1 [] x2_3_7)) + +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_copy_Tree :: (Packed Tree) -> (Packed Tree) +_copy_Tree arg_16 = + case arg_16 of + Leaf x_17 -> + let y_18 :: Int = x_17 in + (Leaf y_18) + Node x_19 x_20 -> + let y_21 :: (Packed Tree) = (_copy_Tree [] x_19) in + let y_22 :: (Packed Tree) = (_copy_Tree [] x_20) in + (Node y_21 y_22) + +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_copy_without_ptrs_Tree :: (Packed Tree) -> (Packed Tree) +_copy_without_ptrs_Tree arg_23 = + case arg_23 of + Leaf x_24 -> + let y_25 :: Int = x_24 in + (Leaf y_25) + Node x_26 x_27 -> + let y_28 :: (Packed Tree) = (_copy_without_ptrs_Tree [] x_26) in + let y_29 :: (Packed Tree) = (_copy_without_ptrs_Tree [] x_27) in + (Node y_28 y_29) + +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_traverse_Tree :: (Packed Tree) -> () +_traverse_Tree arg_30 = + case arg_30 of + Leaf x_31 -> + () + Node x_33 x_34 -> + let y_35 :: () = (_traverse_Tree [] x_33) in + let y_36 :: () = (_traverse_Tree [] x_34) in + () + +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_print_Tree :: (Packed Tree) -> () +_print_Tree arg_37 = + case arg_37 of + Leaf x_38 -> + let wildcard_40 :: () = printsym("(Leaf") in + let wildcard_42 :: () = printsym(" ") in + let y_39 :: () = printint(x_38) in + let wildcard_41 :: () = printsym(")") in + () + Node x_43 x_44 -> + let wildcard_47 :: () = printsym("(Node") in + let wildcard_50 :: () = printsym(" ") in + let y_45 :: () = (_print_Tree [] x_43) in + let wildcard_49 :: () = printsym(" ") in + let y_46 :: () = (_print_Tree [] x_44) in + let wildcard_48 :: () = printsym(")") in + () + + + [compiler] Running pass, simplify +Removed unused functions: [Var "add1"] +Pass output: +================================================================================ +data Tree = Leaf Int | + Node (Packed Tree) (Packed Tree) +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_copy_Tree :: (Packed Tree) -> (Packed Tree) +_copy_Tree arg_16_55 = + case arg_16_55 of + Leaf x_17_56 -> + let y_18_57 :: Int = x_17_56 in + (Leaf y_18_57) + Node x_19_58 x_20_59 -> + let y_21_60 :: (Packed Tree) = (_copy_Tree [] x_19_58) in + let y_22_61 :: (Packed Tree) = (_copy_Tree [] x_20_59) in + (Node y_21_60 y_22_61) + +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_copy_without_ptrs_Tree :: (Packed Tree) -> (Packed Tree) +_copy_without_ptrs_Tree arg_23_62 = + case arg_23_62 of + Leaf x_24_63 -> + let y_25_64 :: Int = x_24_63 in + (Leaf y_25_64) + Node x_26_65 x_27_66 -> + let y_28_67 :: (Packed Tree) = (_copy_without_ptrs_Tree [] x_26_65) in + let y_29_68 :: (Packed Tree) = (_copy_without_ptrs_Tree [] x_27_66) in + (Node y_28_67 y_29_68) + +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_traverse_Tree :: (Packed Tree) -> () +_traverse_Tree arg_30_69 = + case arg_30_69 of + Leaf x_31_70 -> + () + Node x_33_71 x_34_72 -> + let y_35_73 :: () = (_traverse_Tree [] x_33_71) in + let y_36_74 :: () = (_traverse_Tree [] x_34_72) in + () + +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_print_Tree :: (Packed Tree) -> () +_print_Tree arg_37_75 = + case arg_37_75 of + Leaf x_38_76 -> + let wildcard_40_77 :: () = printsym("(Leaf") in + let wildcard_42_78 :: () = printsym(" ") in + let y_39_79 :: () = printint(x_38_76) in + let wildcard_41_80 :: () = printsym(")") in + () + Node x_43_81 x_44_82 -> + let wildcard_47_83 :: () = printsym("(Node") in + let wildcard_50_84 :: () = printsym(" ") in + let y_45_85 :: () = (_print_Tree [] x_43_81) in + let wildcard_49_86 :: () = printsym(" ") in + let y_46_87 :: () = (_print_Tree [] x_44_82) in + let wildcard_48_88 :: () = printsym(")") in + () + + + [compiler] Running pass, typecheck +Pass output: +================================================================================ +data Tree = Leaf Int | + Node (Packed Tree) (Packed Tree) +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_copy_Tree :: (Packed Tree) -> (Packed Tree) +_copy_Tree arg_16_55 = + case arg_16_55 of + Leaf x_17_56 -> + let y_18_57 :: Int = x_17_56 in + (Leaf y_18_57) + Node x_19_58 x_20_59 -> + let y_21_60 :: (Packed Tree) = (_copy_Tree [] x_19_58) in + let y_22_61 :: (Packed Tree) = (_copy_Tree [] x_20_59) in + (Node y_21_60 y_22_61) + +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_copy_without_ptrs_Tree :: (Packed Tree) -> (Packed Tree) +_copy_without_ptrs_Tree arg_23_62 = + case arg_23_62 of + Leaf x_24_63 -> + let y_25_64 :: Int = x_24_63 in + (Leaf y_25_64) + Node x_26_65 x_27_66 -> + let y_28_67 :: (Packed Tree) = (_copy_without_ptrs_Tree [] x_26_65) in + let y_29_68 :: (Packed Tree) = (_copy_without_ptrs_Tree [] x_27_66) in + (Node y_28_67 y_29_68) + +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_traverse_Tree :: (Packed Tree) -> () +_traverse_Tree arg_30_69 = + case arg_30_69 of + Leaf x_31_70 -> + () + Node x_33_71 x_34_72 -> + let y_35_73 :: () = (_traverse_Tree [] x_33_71) in + let y_36_74 :: () = (_traverse_Tree [] x_34_72) in + () + +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_print_Tree :: (Packed Tree) -> () +_print_Tree arg_37_75 = + case arg_37_75 of + Leaf x_38_76 -> + let wildcard_40_77 :: () = printsym("(Leaf") in + let wildcard_42_78 :: () = printsym(" ") in + let y_39_79 :: () = printint(x_38_76) in + let wildcard_41_80 :: () = printsym(")") in + () + Node x_43_81 x_44_82 -> + let wildcard_47_83 :: () = printsym("(Node") in + let wildcard_50_84 :: () = printsym(" ") in + let y_45_85 :: () = (_print_Tree [] x_43_81) in + let wildcard_49_86 :: () = printsym(" ") in + let y_46_87 :: () = (_print_Tree [] x_44_82) in + let wildcard_48_88 :: () = printsym(")") in + () + + + [compiler] Running pass, flatten +Pass output: +================================================================================ +data Tree = Leaf Int | + Node (Packed Tree) (Packed Tree) +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_copy_Tree :: (Packed Tree) -> (Packed Tree) +_copy_Tree arg_16_55 = + case arg_16_55 of + Leaf x_17_56 -> + let y_18_57 :: Int = x_17_56 in + (Leaf y_18_57) + Node x_19_58 x_20_59 -> + let y_21_60 :: (Packed Tree) = (_copy_Tree [] x_19_58) in + let y_22_61 :: (Packed Tree) = (_copy_Tree [] x_20_59) in + (Node y_21_60 y_22_61) + +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_copy_without_ptrs_Tree :: (Packed Tree) -> (Packed Tree) +_copy_without_ptrs_Tree arg_23_62 = + case arg_23_62 of + Leaf x_24_63 -> + let y_25_64 :: Int = x_24_63 in + (Leaf y_25_64) + Node x_26_65 x_27_66 -> + let y_28_67 :: (Packed Tree) = (_copy_without_ptrs_Tree [] x_26_65) in + let y_29_68 :: (Packed Tree) = (_copy_without_ptrs_Tree [] x_27_66) in + (Node y_28_67 y_29_68) + +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_traverse_Tree :: (Packed Tree) -> () +_traverse_Tree arg_30_69 = + case arg_30_69 of + Leaf x_31_70 -> + () + Node x_33_71 x_34_72 -> + let y_35_73 :: () = (_traverse_Tree [] x_33_71) in + let y_36_74 :: () = (_traverse_Tree [] x_34_72) in + () + +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_print_Tree :: (Packed Tree) -> () +_print_Tree arg_37_75 = + case arg_37_75 of + Leaf x_38_76 -> + let wildcard_40_77 :: () = printsym("(Leaf") in + let wildcard_42_78 :: () = printsym(" ") in + let y_39_79 :: () = printint(x_38_76) in + let wildcard_41_80 :: () = printsym(")") in + () + Node x_43_81 x_44_82 -> + let wildcard_47_83 :: () = printsym("(Node") in + let wildcard_50_84 :: () = printsym(" ") in + let y_45_85 :: () = (_print_Tree [] x_43_81) in + let wildcard_49_86 :: () = printsym(" ") in + let y_46_87 :: () = (_print_Tree [] x_44_82) in + let wildcard_48_88 :: () = printsym(")") in + () + + + [compiler] Running pass, simplify +Removed unused functions: [] +Pass output: +================================================================================ +data Tree = Leaf Int | + Node (Packed Tree) (Packed Tree) +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_copy_Tree :: (Packed Tree) -> (Packed Tree) +_copy_Tree arg_16_55_89 = + case arg_16_55_89 of + Leaf x_17_56_90 -> + let y_18_57_91 :: Int = x_17_56_90 in + (Leaf y_18_57_91) + Node x_19_58_92 x_20_59_93 -> + let y_21_60_94 :: (Packed Tree) = (_copy_Tree [] x_19_58_92) in + let y_22_61_95 :: (Packed Tree) = (_copy_Tree [] x_20_59_93) in + (Node y_21_60_94 y_22_61_95) + +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_copy_without_ptrs_Tree :: (Packed Tree) -> (Packed Tree) +_copy_without_ptrs_Tree arg_23_62_96 = + case arg_23_62_96 of + Leaf x_24_63_97 -> + let y_25_64_98 :: Int = x_24_63_97 in + (Leaf y_25_64_98) + Node x_26_65_99 x_27_66_100 -> + let y_28_67_101 :: (Packed Tree) = (_copy_without_ptrs_Tree [] x_26_65_99) in + let y_29_68_102 :: (Packed Tree) = (_copy_without_ptrs_Tree [] x_27_66_100) in + (Node y_28_67_101 y_29_68_102) + +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_traverse_Tree :: (Packed Tree) -> () +_traverse_Tree arg_30_69_103 = + case arg_30_69_103 of + Leaf x_31_70_104 -> + () + Node x_33_71_105 x_34_72_106 -> + let y_35_73_107 :: () = (_traverse_Tree [] x_33_71_105) in + let y_36_74_108 :: () = (_traverse_Tree [] x_34_72_106) in + () + +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_print_Tree :: (Packed Tree) -> () +_print_Tree arg_37_75_109 = + case arg_37_75_109 of + Leaf x_38_76_110 -> + let wildcard_40_77_111 :: () = printsym("(Leaf") in + let wildcard_42_78_112 :: () = printsym(" ") in + let y_39_79_113 :: () = printint(x_38_76_110) in + let wildcard_41_80_114 :: () = printsym(")") in + () + Node x_43_81_115 x_44_82_116 -> + let wildcard_47_83_117 :: () = printsym("(Node") in + let wildcard_50_84_118 :: () = printsym(" ") in + let y_45_85_119 :: () = (_print_Tree [] x_43_81_115) in + let wildcard_49_86_120 :: () = printsym(" ") in + let y_46_87_121 :: () = (_print_Tree [] x_44_82_116) in + let wildcard_48_88_122 :: () = printsym(")") in + () + + + [compiler] Running pass, inlineTriv +Pass output: +================================================================================ +data Tree = Leaf Int | + Node (Packed Tree) (Packed Tree) +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_copy_Tree :: (Packed Tree) -> (Packed Tree) +_copy_Tree arg_16_55_89 = + case arg_16_55_89 of + Leaf x_17_56_90 -> + (Leaf x_17_56_90) + Node x_19_58_92 x_20_59_93 -> + let y_21_60_94 :: (Packed Tree) = (_copy_Tree [] x_19_58_92) in + let y_22_61_95 :: (Packed Tree) = (_copy_Tree [] x_20_59_93) in + (Node y_21_60_94 y_22_61_95) + +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_copy_without_ptrs_Tree :: (Packed Tree) -> (Packed Tree) +_copy_without_ptrs_Tree arg_23_62_96 = + case arg_23_62_96 of + Leaf x_24_63_97 -> + (Leaf x_24_63_97) + Node x_26_65_99 x_27_66_100 -> + let y_28_67_101 :: (Packed Tree) = (_copy_without_ptrs_Tree [] x_26_65_99) in + let y_29_68_102 :: (Packed Tree) = (_copy_without_ptrs_Tree [] x_27_66_100) in + (Node y_28_67_101 y_29_68_102) + +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_traverse_Tree :: (Packed Tree) -> () +_traverse_Tree arg_30_69_103 = + case arg_30_69_103 of + Leaf x_31_70_104 -> + () + Node x_33_71_105 x_34_72_106 -> + let y_35_73_107 :: () = (_traverse_Tree [] x_33_71_105) in + let y_36_74_108 :: () = (_traverse_Tree [] x_34_72_106) in + () + +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_print_Tree :: (Packed Tree) -> () +_print_Tree arg_37_75_109 = + case arg_37_75_109 of + Leaf x_38_76_110 -> + let wildcard_40_77_111 :: () = printsym("(Leaf") in + let wildcard_42_78_112 :: () = printsym(" ") in + let y_39_79_113 :: () = printint(x_38_76_110) in + let wildcard_41_80_114 :: () = printsym(")") in + () + Node x_43_81_115 x_44_82_116 -> + let wildcard_47_83_117 :: () = printsym("(Node") in + let wildcard_50_84_118 :: () = printsym(" ") in + let y_45_85_119 :: () = (_print_Tree [] x_43_81_115) in + let wildcard_49_86_120 :: () = printsym(" ") in + let y_46_87_121 :: () = (_print_Tree [] x_44_82_116) in + let wildcard_48_88_122 :: () = printsym(")") in + () + + + [compiler] Running pass, typecheck +Pass output: +================================================================================ +data Tree = Leaf Int | + Node (Packed Tree) (Packed Tree) +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_copy_Tree :: (Packed Tree) -> (Packed Tree) +_copy_Tree arg_16_55_89 = + case arg_16_55_89 of + Leaf x_17_56_90 -> + (Leaf x_17_56_90) + Node x_19_58_92 x_20_59_93 -> + let y_21_60_94 :: (Packed Tree) = (_copy_Tree [] x_19_58_92) in + let y_22_61_95 :: (Packed Tree) = (_copy_Tree [] x_20_59_93) in + (Node y_21_60_94 y_22_61_95) + +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_copy_without_ptrs_Tree :: (Packed Tree) -> (Packed Tree) +_copy_without_ptrs_Tree arg_23_62_96 = + case arg_23_62_96 of + Leaf x_24_63_97 -> + (Leaf x_24_63_97) + Node x_26_65_99 x_27_66_100 -> + let y_28_67_101 :: (Packed Tree) = (_copy_without_ptrs_Tree [] x_26_65_99) in + let y_29_68_102 :: (Packed Tree) = (_copy_without_ptrs_Tree [] x_27_66_100) in + (Node y_28_67_101 y_29_68_102) + +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_traverse_Tree :: (Packed Tree) -> () +_traverse_Tree arg_30_69_103 = + case arg_30_69_103 of + Leaf x_31_70_104 -> + () + Node x_33_71_105 x_34_72_106 -> + let y_35_73_107 :: () = (_traverse_Tree [] x_33_71_105) in + let y_36_74_108 :: () = (_traverse_Tree [] x_34_72_106) in + () + +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_print_Tree :: (Packed Tree) -> () +_print_Tree arg_37_75_109 = + case arg_37_75_109 of + Leaf x_38_76_110 -> + let wildcard_40_77_111 :: () = printsym("(Leaf") in + let wildcard_42_78_112 :: () = printsym(" ") in + let y_39_79_113 :: () = printint(x_38_76_110) in + let wildcard_41_80_114 :: () = printsym(")") in + () + Node x_43_81_115 x_44_82_116 -> + let wildcard_47_83_117 :: () = printsym("(Node") in + let wildcard_50_84_118 :: () = printsym(" ") in + let y_45_85_119 :: () = (_print_Tree [] x_43_81_115) in + let wildcard_49_86_120 :: () = printsym(" ") in + let y_46_87_121 :: () = (_print_Tree [] x_44_82_116) in + let wildcard_48_88_122 :: () = printsym(")") in + () + + + [compiler] Running pass, typecheck +Pass output: +================================================================================ +data Tree = Leaf Int | + Node (Packed Tree) (Packed Tree) +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_copy_Tree :: (Packed Tree) -> (Packed Tree) +_copy_Tree arg_16_55_89 = + case arg_16_55_89 of + Leaf x_17_56_90 -> + (Leaf x_17_56_90) + Node x_19_58_92 x_20_59_93 -> + let y_21_60_94 :: (Packed Tree) = (_copy_Tree [] x_19_58_92) in + let y_22_61_95 :: (Packed Tree) = (_copy_Tree [] x_20_59_93) in + (Node y_21_60_94 y_22_61_95) + +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_copy_without_ptrs_Tree :: (Packed Tree) -> (Packed Tree) +_copy_without_ptrs_Tree arg_23_62_96 = + case arg_23_62_96 of + Leaf x_24_63_97 -> + (Leaf x_24_63_97) + Node x_26_65_99 x_27_66_100 -> + let y_28_67_101 :: (Packed Tree) = (_copy_without_ptrs_Tree [] x_26_65_99) in + let y_29_68_102 :: (Packed Tree) = (_copy_without_ptrs_Tree [] x_27_66_100) in + (Node y_28_67_101 y_29_68_102) + +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_traverse_Tree :: (Packed Tree) -> () +_traverse_Tree arg_30_69_103 = + case arg_30_69_103 of + Leaf x_31_70_104 -> + () + Node x_33_71_105 x_34_72_106 -> + let y_35_73_107 :: () = (_traverse_Tree [] x_33_71_105) in + let y_36_74_108 :: () = (_traverse_Tree [] x_34_72_106) in + () + +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_print_Tree :: (Packed Tree) -> () +_print_Tree arg_37_75_109 = + case arg_37_75_109 of + Leaf x_38_76_110 -> + let wildcard_40_77_111 :: () = printsym("(Leaf") in + let wildcard_42_78_112 :: () = printsym(" ") in + let y_39_79_113 :: () = printint(x_38_76_110) in + let wildcard_41_80_114 :: () = printsym(")") in + () + Node x_43_81_115 x_44_82_116 -> + let wildcard_47_83_117 :: () = printsym("(Node") in + let wildcard_50_84_118 :: () = printsym(" ") in + let y_45_85_119 :: () = (_print_Tree [] x_43_81_115) in + let wildcard_49_86_120 :: () = printsym(" ") in + let y_46_87_121 :: () = (_print_Tree [] x_44_82_116) in + let wildcard_48_88_122 :: () = printsym(")") in + () + + + [compiler] Running pass, directL3 +Pass output: +================================================================================ +data Tree = Leaf Int | + Node Cursor Cursor +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_copy_Tree :: Cursor -> Cursor +_copy_Tree arg_16_55_89 = + case arg_16_55_89 of + Leaf x_17_56_90 -> + (Leaf x_17_56_90) + Node x_19_58_92 x_20_59_93 -> + let y_21_60_94 :: Cursor = (_copy_Tree [] x_19_58_92) in + let y_22_61_95 :: Cursor = (_copy_Tree [] x_20_59_93) in + (Node y_21_60_94 y_22_61_95) + +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_copy_without_ptrs_Tree :: Cursor -> Cursor +_copy_without_ptrs_Tree arg_23_62_96 = + case arg_23_62_96 of + Leaf x_24_63_97 -> + (Leaf x_24_63_97) + Node x_26_65_99 x_27_66_100 -> + let y_28_67_101 :: Cursor = (_copy_without_ptrs_Tree [] x_26_65_99) in + let y_29_68_102 :: Cursor = (_copy_without_ptrs_Tree [] x_27_66_100) in + (Node y_28_67_101 y_29_68_102) + +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_traverse_Tree :: Cursor -> () +_traverse_Tree arg_30_69_103 = + case arg_30_69_103 of + Leaf x_31_70_104 -> + () + Node x_33_71_105 x_34_72_106 -> + let y_35_73_107 :: () = (_traverse_Tree [] x_33_71_105) in + let y_36_74_108 :: () = (_traverse_Tree [] x_34_72_106) in + () + +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_print_Tree :: Cursor -> () +_print_Tree arg_37_75_109 = + case arg_37_75_109 of + Leaf x_38_76_110 -> + let wildcard_40_77_111 :: () = printsym("(Leaf") in + let wildcard_42_78_112 :: () = printsym(" ") in + let y_39_79_113 :: () = printint(x_38_76_110) in + let wildcard_41_80_114 :: () = printsym(")") in + () + Node x_43_81_115 x_44_82_116 -> + let wildcard_47_83_117 :: () = printsym("(Node") in + let wildcard_50_84_118 :: () = printsym(" ") in + let y_45_85_119 :: () = (_print_Tree [] x_43_81_115) in + let wildcard_49_86_120 :: () = printsym(" ") in + let y_46_87_121 :: () = (_print_Tree [] x_44_82_116) in + let wildcard_48_88_122 :: () = printsym(")") in + () + + + [compiler] Running pass, L3.typecheck +Pass output: +================================================================================ +data Tree = Leaf Int | + Node Cursor Cursor +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_copy_Tree :: Cursor -> Cursor +_copy_Tree arg_16_55_89 = + case arg_16_55_89 of + Leaf x_17_56_90 -> + (Leaf x_17_56_90) + Node x_19_58_92 x_20_59_93 -> + let y_21_60_94 :: Cursor = (_copy_Tree [] x_19_58_92) in + let y_22_61_95 :: Cursor = (_copy_Tree [] x_20_59_93) in + (Node y_21_60_94 y_22_61_95) + +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_copy_without_ptrs_Tree :: Cursor -> Cursor +_copy_without_ptrs_Tree arg_23_62_96 = + case arg_23_62_96 of + Leaf x_24_63_97 -> + (Leaf x_24_63_97) + Node x_26_65_99 x_27_66_100 -> + let y_28_67_101 :: Cursor = (_copy_without_ptrs_Tree [] x_26_65_99) in + let y_29_68_102 :: Cursor = (_copy_without_ptrs_Tree [] x_27_66_100) in + (Node y_28_67_101 y_29_68_102) + +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_traverse_Tree :: Cursor -> () +_traverse_Tree arg_30_69_103 = + case arg_30_69_103 of + Leaf x_31_70_104 -> + () + Node x_33_71_105 x_34_72_106 -> + let y_35_73_107 :: () = (_traverse_Tree [] x_33_71_105) in + let y_36_74_108 :: () = (_traverse_Tree [] x_34_72_106) in + () + +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_print_Tree :: Cursor -> () +_print_Tree arg_37_75_109 = + case arg_37_75_109 of + Leaf x_38_76_110 -> + let wildcard_40_77_111 :: () = printsym("(Leaf") in + let wildcard_42_78_112 :: () = printsym(" ") in + let y_39_79_113 :: () = printint(x_38_76_110) in + let wildcard_41_80_114 :: () = printsym(")") in + () + Node x_43_81_115 x_44_82_116 -> + let wildcard_47_83_117 :: () = printsym("(Node") in + let wildcard_50_84_118 :: () = printsym(" ") in + let y_45_85_119 :: () = (_print_Tree [] x_43_81_115) in + let wildcard_49_86_120 :: () = printsym(" ") in + let y_46_87_121 :: () = (_print_Tree [] x_44_82_116) in + let wildcard_48_88_122 :: () = printsym(")") in + () + + + [compiler] Running pass, unariser +Pass output: +================================================================================ +data Tree = Leaf Int | + Node Cursor Cursor +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_copy_Tree :: Cursor -> Cursor +_copy_Tree arg_16_55_89 = + case arg_16_55_89 of + Leaf x_17_56_90 -> + (Leaf x_17_56_90) + Node x_19_58_92 x_20_59_93 -> + let y_21_60_94 :: Cursor = (_copy_Tree [] x_19_58_92) in + let y_22_61_95 :: Cursor = (_copy_Tree [] x_20_59_93) in + (Node y_21_60_94 y_22_61_95) + +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_copy_without_ptrs_Tree :: Cursor -> Cursor +_copy_without_ptrs_Tree arg_23_62_96 = + case arg_23_62_96 of + Leaf x_24_63_97 -> + (Leaf x_24_63_97) + Node x_26_65_99 x_27_66_100 -> + let y_28_67_101 :: Cursor = (_copy_without_ptrs_Tree [] x_26_65_99) in + let y_29_68_102 :: Cursor = (_copy_without_ptrs_Tree [] x_27_66_100) in + (Node y_28_67_101 y_29_68_102) + +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_traverse_Tree :: Cursor -> () +_traverse_Tree arg_30_69_103 = + case arg_30_69_103 of + Leaf x_31_70_104 -> + () + Node x_33_71_105 x_34_72_106 -> + let y_35_73_107 :: () = (_traverse_Tree [] x_33_71_105) in + let y_36_74_108 :: () = (_traverse_Tree [] x_34_72_106) in + () + +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_print_Tree :: Cursor -> () +_print_Tree arg_37_75_109 = + case arg_37_75_109 of + Leaf x_38_76_110 -> + let wildcard_40_77_111 :: () = printsym("(Leaf") in + let wildcard_42_78_112 :: () = printsym(" ") in + let y_39_79_113 :: () = printint(x_38_76_110) in + let wildcard_41_80_114 :: () = printsym(")") in + () + Node x_43_81_115 x_44_82_116 -> + let wildcard_47_83_117 :: () = printsym("(Node") in + let wildcard_50_84_118 :: () = printsym(" ") in + let y_45_85_119 :: () = (_print_Tree [] x_43_81_115) in + let wildcard_49_86_120 :: () = printsym(" ") in + let y_46_87_121 :: () = (_print_Tree [] x_44_82_116) in + let wildcard_48_88_122 :: () = printsym(")") in + () + + + [compiler] Running pass, L3.typecheck +Pass output: +================================================================================ +data Tree = Leaf Int | + Node Cursor Cursor +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_copy_Tree :: Cursor -> Cursor +_copy_Tree arg_16_55_89 = + case arg_16_55_89 of + Leaf x_17_56_90 -> + (Leaf x_17_56_90) + Node x_19_58_92 x_20_59_93 -> + let y_21_60_94 :: Cursor = (_copy_Tree [] x_19_58_92) in + let y_22_61_95 :: Cursor = (_copy_Tree [] x_20_59_93) in + (Node y_21_60_94 y_22_61_95) + +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_copy_without_ptrs_Tree :: Cursor -> Cursor +_copy_without_ptrs_Tree arg_23_62_96 = + case arg_23_62_96 of + Leaf x_24_63_97 -> + (Leaf x_24_63_97) + Node x_26_65_99 x_27_66_100 -> + let y_28_67_101 :: Cursor = (_copy_without_ptrs_Tree [] x_26_65_99) in + let y_29_68_102 :: Cursor = (_copy_without_ptrs_Tree [] x_27_66_100) in + (Node y_28_67_101 y_29_68_102) + +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_traverse_Tree :: Cursor -> () +_traverse_Tree arg_30_69_103 = + case arg_30_69_103 of + Leaf x_31_70_104 -> + () + Node x_33_71_105 x_34_72_106 -> + let y_35_73_107 :: () = (_traverse_Tree [] x_33_71_105) in + let y_36_74_108 :: () = (_traverse_Tree [] x_34_72_106) in + () + +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_print_Tree :: Cursor -> () +_print_Tree arg_37_75_109 = + case arg_37_75_109 of + Leaf x_38_76_110 -> + let wildcard_40_77_111 :: () = printsym("(Leaf") in + let wildcard_42_78_112 :: () = printsym(" ") in + let y_39_79_113 :: () = printint(x_38_76_110) in + let wildcard_41_80_114 :: () = printsym(")") in + () + Node x_43_81_115 x_44_82_116 -> + let wildcard_47_83_117 :: () = printsym("(Node") in + let wildcard_50_84_118 :: () = printsym(" ") in + let y_45_85_119 :: () = (_print_Tree [] x_43_81_115) in + let wildcard_49_86_120 :: () = printsym(" ") in + let y_46_87_121 :: () = (_print_Tree [] x_44_82_116) in + let wildcard_48_88_122 :: () = printsym(")") in + () + + + [compiler] Running pass, L3.flatten +Pass output: +================================================================================ +data Tree = Leaf Int | + Node Cursor Cursor +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_copy_Tree :: Cursor -> Cursor +_copy_Tree arg_16_55_89 = + case arg_16_55_89 of + Leaf x_17_56_90 -> + (Leaf x_17_56_90) + Node x_19_58_92 x_20_59_93 -> + let y_21_60_94 :: Cursor = (_copy_Tree [] x_19_58_92) in + let y_22_61_95 :: Cursor = (_copy_Tree [] x_20_59_93) in + (Node y_21_60_94 y_22_61_95) + +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_copy_without_ptrs_Tree :: Cursor -> Cursor +_copy_without_ptrs_Tree arg_23_62_96 = + case arg_23_62_96 of + Leaf x_24_63_97 -> + (Leaf x_24_63_97) + Node x_26_65_99 x_27_66_100 -> + let y_28_67_101 :: Cursor = (_copy_without_ptrs_Tree [] x_26_65_99) in + let y_29_68_102 :: Cursor = (_copy_without_ptrs_Tree [] x_27_66_100) in + (Node y_28_67_101 y_29_68_102) + +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_traverse_Tree :: Cursor -> () +_traverse_Tree arg_30_69_103 = + case arg_30_69_103 of + Leaf x_31_70_104 -> + () + Node x_33_71_105 x_34_72_106 -> + let y_35_73_107 :: () = (_traverse_Tree [] x_33_71_105) in + let y_36_74_108 :: () = (_traverse_Tree [] x_34_72_106) in + () + +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_print_Tree :: Cursor -> () +_print_Tree arg_37_75_109 = + case arg_37_75_109 of + Leaf x_38_76_110 -> + let wildcard_40_77_111 :: () = printsym("(Leaf") in + let wildcard_42_78_112 :: () = printsym(" ") in + let y_39_79_113 :: () = printint(x_38_76_110) in + let wildcard_41_80_114 :: () = printsym(")") in + () + Node x_43_81_115 x_44_82_116 -> + let wildcard_47_83_117 :: () = printsym("(Node") in + let wildcard_50_84_118 :: () = printsym(" ") in + let y_45_85_119 :: () = (_print_Tree [] x_43_81_115) in + let wildcard_49_86_120 :: () = printsym(" ") in + let y_46_87_121 :: () = (_print_Tree [] x_44_82_116) in + let wildcard_48_88_122 :: () = printsym(")") in + () + + + [compiler] Running pass, L3.typecheck +Pass output: +================================================================================ +data Tree = Leaf Int | + Node Cursor Cursor +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_copy_Tree :: Cursor -> Cursor +_copy_Tree arg_16_55_89 = + case arg_16_55_89 of + Leaf x_17_56_90 -> + (Leaf x_17_56_90) + Node x_19_58_92 x_20_59_93 -> + let y_21_60_94 :: Cursor = (_copy_Tree [] x_19_58_92) in + let y_22_61_95 :: Cursor = (_copy_Tree [] x_20_59_93) in + (Node y_21_60_94 y_22_61_95) + +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_copy_without_ptrs_Tree :: Cursor -> Cursor +_copy_without_ptrs_Tree arg_23_62_96 = + case arg_23_62_96 of + Leaf x_24_63_97 -> + (Leaf x_24_63_97) + Node x_26_65_99 x_27_66_100 -> + let y_28_67_101 :: Cursor = (_copy_without_ptrs_Tree [] x_26_65_99) in + let y_29_68_102 :: Cursor = (_copy_without_ptrs_Tree [] x_27_66_100) in + (Node y_28_67_101 y_29_68_102) + +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_traverse_Tree :: Cursor -> () +_traverse_Tree arg_30_69_103 = + case arg_30_69_103 of + Leaf x_31_70_104 -> + () + Node x_33_71_105 x_34_72_106 -> + let y_35_73_107 :: () = (_traverse_Tree [] x_33_71_105) in + let y_36_74_108 :: () = (_traverse_Tree [] x_34_72_106) in + () + +{meta: FunMeta {funRec = Rec, funInline = NoInline, funCanTriggerGC = False, funOptLayout = NoLayoutOpt, userConstraintsDataCon = Nothing}} +_print_Tree :: Cursor -> () +_print_Tree arg_37_75_109 = + case arg_37_75_109 of + Leaf x_38_76_110 -> + let wildcard_40_77_111 :: () = printsym("(Leaf") in + let wildcard_42_78_112 :: () = printsym(" ") in + let y_39_79_113 :: () = printint(x_38_76_110) in + let wildcard_41_80_114 :: () = printsym(")") in + () + Node x_43_81_115 x_44_82_116 -> + let wildcard_47_83_117 :: () = printsym("(Node") in + let wildcard_50_84_118 :: () = printsym(" ") in + let y_45_85_119 :: () = (_print_Tree [] x_43_81_115) in + let wildcard_49_86_120 :: () = printsym(" ") in + let y_46_87_121 :: () = (_print_Tree [] x_44_82_116) in + let wildcard_48_88_122 :: () = printsym(")") in + () + + + [compiler] Running pass, lower +Pass output: +================================================================================ +Prog {infoTable = [("Tree", + [("Leaf", + DataConInfo {dcon_tag = 0, + scalar_bytes = 8, + num_shortcut = 0, + num_scalars = 1, + num_packed = 0, + field_tys = [IntTy]}), + ("Node", + DataConInfo {dcon_tag = 1, + scalar_bytes = 0, + num_shortcut = 2, + num_scalars = 0, + num_packed = 0, + field_tys = [CursorTy,CursorTy]})])], + symbolTable = [(123, ")"),(124, "(Node"),(125, "(Leaf"), + (126, " ")], + fundefs = [FunDecl {funName = "_copy_Tree", + funArgs = [(arg_16_55_89, CursorTy)], + funRetTy = CursorTy, + funBody = LetPrimCallT {binds = [(tag_127, TagTyPacked), + (tail_128, CursorTy)], + prim = ReadScalar IntS, + rands = [VarTriv "arg_16_55_89"], + bod = Switch "switch_131" + (VarTriv "tag_127") + (IntAlts [(0, + LetUnpackT {binds = [(x_17_56_90, + IntTy)], + ptr = "tail_128", + bod = LetAllocT {lhs = "tailift_129", + vals = [(IntTy, + IntTriv 0), + (IntTy, + VarTriv "x_17_56_90")], + bod = RetValsT [VarTriv "tailift_129"]}}), + (1, + LetUnpackT {binds = [(x_19_58_92, + CursorTy), + (x_20_59_93, + CursorTy)], + ptr = "tail_128", + bod = LetCallT {async = False, + binds = [(y_21_60_94, + CursorTy)], + rator = "_copy_Tree", + rands = [VarTriv "x_19_58_92"], + bod = LetCallT {async = False, + binds = [(y_22_61_95, + CursorTy)], + rator = "_copy_Tree", + rands = [VarTriv "x_20_59_93"], + bod = LetAllocT {lhs = "tailift_130", + vals = [(IntTy, + IntTriv 1), + (CursorTy, + VarTriv "y_21_60_94"), + (CursorTy, + VarTriv "y_22_61_95")], + bod = RetValsT [VarTriv "tailift_130"]}}}})]) + (Just ErrT "Unknown tag in: tag_127")}, + isPure = True}, + FunDecl {funName = "_copy_without_ptrs_Tree", + funArgs = [(arg_23_62_96, CursorTy)], + funRetTy = CursorTy, + funBody = LetPrimCallT {binds = [(tag_132, TagTyPacked), + (tail_133, CursorTy)], + prim = ReadScalar IntS, + rands = [VarTriv "arg_23_62_96"], + bod = Switch "switch_136" + (VarTriv "tag_132") + (IntAlts [(0, + LetUnpackT {binds = [(x_24_63_97, + IntTy)], + ptr = "tail_133", + bod = LetAllocT {lhs = "tailift_134", + vals = [(IntTy, + IntTriv 0), + (IntTy, + VarTriv "x_24_63_97")], + bod = RetValsT [VarTriv "tailift_134"]}}), + (1, + LetUnpackT {binds = [(x_26_65_99, + CursorTy), + (x_27_66_100, + CursorTy)], + ptr = "tail_133", + bod = LetCallT {async = False, + binds = [(y_28_67_101, + CursorTy)], + rator = "_copy_without_ptrs_Tree", + rands = [VarTriv "x_26_65_99"], + bod = LetCallT {async = False, + binds = [(y_29_68_102, + CursorTy)], + rator = "_copy_without_ptrs_Tree", + rands = [VarTriv "x_27_66_100"], + bod = LetAllocT {lhs = "tailift_135", + vals = [(IntTy, + IntTriv 1), + (CursorTy, + VarTriv "y_28_67_101"), + (CursorTy, + VarTriv "y_29_68_102")], + bod = RetValsT [VarTriv "tailift_135"]}}}})]) + (Just ErrT "Unknown tag in: tag_132")}, + isPure = True}, + FunDecl {funName = "_traverse_Tree", + funArgs = [(arg_30_69_103, CursorTy)], + funRetTy = ProdTy [], + funBody = LetPrimCallT {binds = [(tag_137, TagTyPacked), + (tail_138, CursorTy)], + prim = ReadScalar IntS, + rands = [VarTriv "arg_30_69_103"], + bod = Switch "switch_139" + (VarTriv "tag_137") + (IntAlts [(0, + LetUnpackT {binds = [(x_31_70_104, + IntTy)], + ptr = "tail_138", + bod = RetValsT []}), + (1, + LetUnpackT {binds = [(x_33_71_105, + CursorTy), + (x_34_72_106, + CursorTy)], + ptr = "tail_138", + bod = LetCallT {async = False, + binds = [(y_35_73_107, + ProdTy [])], + rator = "_traverse_Tree", + rands = [VarTriv "x_33_71_105"], + bod = LetCallT {async = False, + binds = [(y_36_74_108, + ProdTy [])], + rator = "_traverse_Tree", + rands = [VarTriv "x_34_72_106"], + bod = RetValsT []}}})]) + (Just ErrT "Unknown tag in: tag_137")}, + isPure = True}, + FunDecl {funName = "_print_Tree", + funArgs = [(arg_37_75_109, CursorTy)], + funRetTy = ProdTy [], + funBody = LetPrimCallT {binds = [(tag_140, TagTyPacked), + (tail_141, CursorTy)], + prim = ReadScalar IntS, + rands = [VarTriv "arg_37_75_109"], + bod = Switch "switch_142" + (VarTriv "tag_140") + (IntAlts [(0, + LetUnpackT {binds = [(x_38_76_110, + IntTy)], + ptr = "tail_141", + bod = LetPrimCallT {binds = [(wildcard_40_77_111, + ProdTy [])], + prim = PrintSym, + rands = [SymTriv 125], + bod = LetPrimCallT {binds = [(wildcard_42_78_112, + ProdTy [])], + prim = PrintSym, + rands = [SymTriv 126], + bod = LetPrimCallT {binds = [(y_39_79_113, + ProdTy [])], + prim = PrintInt, + rands = [VarTriv "x_38_76_110"], + bod = LetPrimCallT {binds = [(wildcard_41_80_114, + ProdTy [])], + prim = PrintSym, + rands = [SymTriv 123], + bod = RetValsT []}}}}}), + (1, + LetUnpackT {binds = [(x_43_81_115, + CursorTy), + (x_44_82_116, + CursorTy)], + ptr = "tail_141", + bod = LetPrimCallT {binds = [(wildcard_47_83_117, + ProdTy [])], + prim = PrintSym, + rands = [SymTriv 124], + bod = LetPrimCallT {binds = [(wildcard_50_84_118, + ProdTy [])], + prim = PrintSym, + rands = [SymTriv 126], + bod = LetCallT {async = False, + binds = [(y_45_85_119, + ProdTy [])], + rator = "_print_Tree", + rands = [VarTriv "x_43_81_115"], + bod = LetPrimCallT {binds = [(wildcard_49_86_120, + ProdTy [])], + prim = PrintSym, + rands = [SymTriv 126], + bod = LetCallT {async = False, + binds = [(y_46_87_121, + ProdTy [])], + rator = "_print_Tree", + rands = [VarTriv "x_44_82_116"], + bod = LetPrimCallT {binds = [(wildcard_48_88_122, + ProdTy [])], + prim = PrintSym, + rands = [SymTriv 123], + bod = RetValsT []}}}}}}})]) + (Just ErrT "Unknown tag in: tag_140")}, + isPure = True}], + mainExp = Nothing} + + [compiler] Running pass, lateInlineTriv +Pass output: +================================================================================ +Prog {infoTable = [("Tree", + [("Leaf", + DataConInfo {dcon_tag = 0, + scalar_bytes = 8, + num_shortcut = 0, + num_scalars = 1, + num_packed = 0, + field_tys = [IntTy]}), + ("Node", + DataConInfo {dcon_tag = 1, + scalar_bytes = 0, + num_shortcut = 2, + num_scalars = 0, + num_packed = 0, + field_tys = [CursorTy,CursorTy]})])], + symbolTable = [(123, ")"),(124, "(Node"),(125, "(Leaf"), + (126, " ")], + fundefs = [FunDecl {funName = "_copy_Tree", + funArgs = [(arg_16_55_89, CursorTy)], + funRetTy = CursorTy, + funBody = LetPrimCallT {binds = [(tag_127, TagTyPacked), + (tail_128, CursorTy)], + prim = ReadScalar IntS, + rands = [VarTriv "arg_16_55_89"], + bod = Switch "switch_131" + (VarTriv "tag_127") + (IntAlts [(0, + LetUnpackT {binds = [(x_17_56_90, + IntTy)], + ptr = "tail_128", + bod = LetAllocT {lhs = "tailift_129", + vals = [(IntTy, + IntTriv 0), + (IntTy, + VarTriv "x_17_56_90")], + bod = RetValsT [VarTriv "tailift_129"]}}), + (1, + LetUnpackT {binds = [(x_19_58_92, + CursorTy), + (x_20_59_93, + CursorTy)], + ptr = "tail_128", + bod = LetCallT {async = False, + binds = [(y_21_60_94, + CursorTy)], + rator = "_copy_Tree", + rands = [VarTriv "x_19_58_92"], + bod = LetCallT {async = False, + binds = [(y_22_61_95, + CursorTy)], + rator = "_copy_Tree", + rands = [VarTriv "x_20_59_93"], + bod = LetAllocT {lhs = "tailift_130", + vals = [(IntTy, + IntTriv 1), + (CursorTy, + VarTriv "y_21_60_94"), + (CursorTy, + VarTriv "y_22_61_95")], + bod = RetValsT [VarTriv "tailift_130"]}}}})]) + (Just ErrT "Unknown tag in: tag_127")}, + isPure = True}, + FunDecl {funName = "_copy_without_ptrs_Tree", + funArgs = [(arg_23_62_96, CursorTy)], + funRetTy = CursorTy, + funBody = LetPrimCallT {binds = [(tag_132, TagTyPacked), + (tail_133, CursorTy)], + prim = ReadScalar IntS, + rands = [VarTriv "arg_23_62_96"], + bod = Switch "switch_136" + (VarTriv "tag_132") + (IntAlts [(0, + LetUnpackT {binds = [(x_24_63_97, + IntTy)], + ptr = "tail_133", + bod = LetAllocT {lhs = "tailift_134", + vals = [(IntTy, + IntTriv 0), + (IntTy, + VarTriv "x_24_63_97")], + bod = RetValsT [VarTriv "tailift_134"]}}), + (1, + LetUnpackT {binds = [(x_26_65_99, + CursorTy), + (x_27_66_100, + CursorTy)], + ptr = "tail_133", + bod = LetCallT {async = False, + binds = [(y_28_67_101, + CursorTy)], + rator = "_copy_without_ptrs_Tree", + rands = [VarTriv "x_26_65_99"], + bod = LetCallT {async = False, + binds = [(y_29_68_102, + CursorTy)], + rator = "_copy_without_ptrs_Tree", + rands = [VarTriv "x_27_66_100"], + bod = LetAllocT {lhs = "tailift_135", + vals = [(IntTy, + IntTriv 1), + (CursorTy, + VarTriv "y_28_67_101"), + (CursorTy, + VarTriv "y_29_68_102")], + bod = RetValsT [VarTriv "tailift_135"]}}}})]) + (Just ErrT "Unknown tag in: tag_132")}, + isPure = True}, + FunDecl {funName = "_traverse_Tree", + funArgs = [(arg_30_69_103, CursorTy)], + funRetTy = ProdTy [], + funBody = LetPrimCallT {binds = [(tag_137, TagTyPacked), + (tail_138, CursorTy)], + prim = ReadScalar IntS, + rands = [VarTriv "arg_30_69_103"], + bod = Switch "switch_139" + (VarTriv "tag_137") + (IntAlts [(0, + LetUnpackT {binds = [(x_31_70_104, + IntTy)], + ptr = "tail_138", + bod = RetValsT []}), + (1, + LetUnpackT {binds = [(x_33_71_105, + CursorTy), + (x_34_72_106, + CursorTy)], + ptr = "tail_138", + bod = LetCallT {async = False, + binds = [(y_35_73_107, + ProdTy [])], + rator = "_traverse_Tree", + rands = [VarTriv "x_33_71_105"], + bod = LetCallT {async = False, + binds = [(y_36_74_108, + ProdTy [])], + rator = "_traverse_Tree", + rands = [VarTriv "x_34_72_106"], + bod = RetValsT []}}})]) + (Just ErrT "Unknown tag in: tag_137")}, + isPure = True}, + FunDecl {funName = "_print_Tree", + funArgs = [(arg_37_75_109, CursorTy)], + funRetTy = ProdTy [], + funBody = LetPrimCallT {binds = [(tag_140, TagTyPacked), + (tail_141, CursorTy)], + prim = ReadScalar IntS, + rands = [VarTriv "arg_37_75_109"], + bod = Switch "switch_142" + (VarTriv "tag_140") + (IntAlts [(0, + LetUnpackT {binds = [(x_38_76_110, + IntTy)], + ptr = "tail_141", + bod = LetPrimCallT {binds = [(wildcard_40_77_111, + ProdTy [])], + prim = PrintSym, + rands = [SymTriv 125], + bod = LetPrimCallT {binds = [(wildcard_42_78_112, + ProdTy [])], + prim = PrintSym, + rands = [SymTriv 126], + bod = LetPrimCallT {binds = [(y_39_79_113, + ProdTy [])], + prim = PrintInt, + rands = [VarTriv "x_38_76_110"], + bod = LetPrimCallT {binds = [(wildcard_41_80_114, + ProdTy [])], + prim = PrintSym, + rands = [SymTriv 123], + bod = RetValsT []}}}}}), + (1, + LetUnpackT {binds = [(x_43_81_115, + CursorTy), + (x_44_82_116, + CursorTy)], + ptr = "tail_141", + bod = LetPrimCallT {binds = [(wildcard_47_83_117, + ProdTy [])], + prim = PrintSym, + rands = [SymTriv 124], + bod = LetPrimCallT {binds = [(wildcard_50_84_118, + ProdTy [])], + prim = PrintSym, + rands = [SymTriv 126], + bod = LetCallT {async = False, + binds = [(y_45_85_119, + ProdTy [])], + rator = "_print_Tree", + rands = [VarTriv "x_43_81_115"], + bod = LetPrimCallT {binds = [(wildcard_49_86_120, + ProdTy [])], + prim = PrintSym, + rands = [SymTriv 126], + bod = LetCallT {async = False, + binds = [(y_46_87_121, + ProdTy [])], + rator = "_print_Tree", + rands = [VarTriv "x_44_82_116"], + bod = LetPrimCallT {binds = [(wildcard_48_88_122, + ProdTy [])], + prim = PrintSym, + rands = [SymTriv 123], + bod = RetValsT []}}}}}}})]) + (Just ErrT "Unknown tag in: tag_140")}, + isPure = True}], + mainExp = Nothing} + + [compiler] Running pass, rearrangeFree +Pass output: +================================================================================ +Prog {infoTable = [("Tree", + [("Leaf", + DataConInfo {dcon_tag = 0, + scalar_bytes = 8, + num_shortcut = 0, + num_scalars = 1, + num_packed = 0, + field_tys = [IntTy]}), + ("Node", + DataConInfo {dcon_tag = 1, + scalar_bytes = 0, + num_shortcut = 2, + num_scalars = 0, + num_packed = 0, + field_tys = [CursorTy,CursorTy]})])], + symbolTable = [(123, ")"),(124, "(Node"),(125, "(Leaf"), + (126, " ")], + fundefs = [FunDecl {funName = "_copy_Tree", + funArgs = [(arg_16_55_89, CursorTy)], + funRetTy = CursorTy, + funBody = LetPrimCallT {binds = [(tag_127, TagTyPacked), + (tail_128, CursorTy)], + prim = ReadScalar IntS, + rands = [VarTriv "arg_16_55_89"], + bod = Switch "switch_131" + (VarTriv "tag_127") + (IntAlts [(0, + LetUnpackT {binds = [(x_17_56_90, + IntTy)], + ptr = "tail_128", + bod = LetAllocT {lhs = "tailift_129", + vals = [(IntTy, + IntTriv 0), + (IntTy, + VarTriv "x_17_56_90")], + bod = RetValsT [VarTriv "tailift_129"]}}), + (1, + LetUnpackT {binds = [(x_19_58_92, + CursorTy), + (x_20_59_93, + CursorTy)], + ptr = "tail_128", + bod = LetCallT {async = False, + binds = [(y_21_60_94, + CursorTy)], + rator = "_copy_Tree", + rands = [VarTriv "x_19_58_92"], + bod = LetCallT {async = False, + binds = [(y_22_61_95, + CursorTy)], + rator = "_copy_Tree", + rands = [VarTriv "x_20_59_93"], + bod = LetAllocT {lhs = "tailift_130", + vals = [(IntTy, + IntTriv 1), + (CursorTy, + VarTriv "y_21_60_94"), + (CursorTy, + VarTriv "y_22_61_95")], + bod = RetValsT [VarTriv "tailift_130"]}}}})]) + (Just ErrT "Unknown tag in: tag_127")}, + isPure = True}, + FunDecl {funName = "_copy_without_ptrs_Tree", + funArgs = [(arg_23_62_96, CursorTy)], + funRetTy = CursorTy, + funBody = LetPrimCallT {binds = [(tag_132, TagTyPacked), + (tail_133, CursorTy)], + prim = ReadScalar IntS, + rands = [VarTriv "arg_23_62_96"], + bod = Switch "switch_136" + (VarTriv "tag_132") + (IntAlts [(0, + LetUnpackT {binds = [(x_24_63_97, + IntTy)], + ptr = "tail_133", + bod = LetAllocT {lhs = "tailift_134", + vals = [(IntTy, + IntTriv 0), + (IntTy, + VarTriv "x_24_63_97")], + bod = RetValsT [VarTriv "tailift_134"]}}), + (1, + LetUnpackT {binds = [(x_26_65_99, + CursorTy), + (x_27_66_100, + CursorTy)], + ptr = "tail_133", + bod = LetCallT {async = False, + binds = [(y_28_67_101, + CursorTy)], + rator = "_copy_without_ptrs_Tree", + rands = [VarTriv "x_26_65_99"], + bod = LetCallT {async = False, + binds = [(y_29_68_102, + CursorTy)], + rator = "_copy_without_ptrs_Tree", + rands = [VarTriv "x_27_66_100"], + bod = LetAllocT {lhs = "tailift_135", + vals = [(IntTy, + IntTriv 1), + (CursorTy, + VarTriv "y_28_67_101"), + (CursorTy, + VarTriv "y_29_68_102")], + bod = RetValsT [VarTriv "tailift_135"]}}}})]) + (Just ErrT "Unknown tag in: tag_132")}, + isPure = True}, + FunDecl {funName = "_traverse_Tree", + funArgs = [(arg_30_69_103, CursorTy)], + funRetTy = ProdTy [], + funBody = LetPrimCallT {binds = [(tag_137, TagTyPacked), + (tail_138, CursorTy)], + prim = ReadScalar IntS, + rands = [VarTriv "arg_30_69_103"], + bod = Switch "switch_139" + (VarTriv "tag_137") + (IntAlts [(0, + LetUnpackT {binds = [(x_31_70_104, + IntTy)], + ptr = "tail_138", + bod = RetValsT []}), + (1, + LetUnpackT {binds = [(x_33_71_105, + CursorTy), + (x_34_72_106, + CursorTy)], + ptr = "tail_138", + bod = LetCallT {async = False, + binds = [(y_35_73_107, + ProdTy [])], + rator = "_traverse_Tree", + rands = [VarTriv "x_33_71_105"], + bod = LetCallT {async = False, + binds = [(y_36_74_108, + ProdTy [])], + rator = "_traverse_Tree", + rands = [VarTriv "x_34_72_106"], + bod = RetValsT []}}})]) + (Just ErrT "Unknown tag in: tag_137")}, + isPure = True}, + FunDecl {funName = "_print_Tree", + funArgs = [(arg_37_75_109, CursorTy)], + funRetTy = ProdTy [], + funBody = LetPrimCallT {binds = [(tag_140, TagTyPacked), + (tail_141, CursorTy)], + prim = ReadScalar IntS, + rands = [VarTriv "arg_37_75_109"], + bod = Switch "switch_142" + (VarTriv "tag_140") + (IntAlts [(0, + LetUnpackT {binds = [(x_38_76_110, + IntTy)], + ptr = "tail_141", + bod = LetPrimCallT {binds = [(wildcard_40_77_111, + ProdTy [])], + prim = PrintSym, + rands = [SymTriv 125], + bod = LetPrimCallT {binds = [(wildcard_42_78_112, + ProdTy [])], + prim = PrintSym, + rands = [SymTriv 126], + bod = LetPrimCallT {binds = [(y_39_79_113, + ProdTy [])], + prim = PrintInt, + rands = [VarTriv "x_38_76_110"], + bod = LetPrimCallT {binds = [(wildcard_41_80_114, + ProdTy [])], + prim = PrintSym, + rands = [SymTriv 123], + bod = RetValsT []}}}}}), + (1, + LetUnpackT {binds = [(x_43_81_115, + CursorTy), + (x_44_82_116, + CursorTy)], + ptr = "tail_141", + bod = LetPrimCallT {binds = [(wildcard_47_83_117, + ProdTy [])], + prim = PrintSym, + rands = [SymTriv 124], + bod = LetPrimCallT {binds = [(wildcard_50_84_118, + ProdTy [])], + prim = PrintSym, + rands = [SymTriv 126], + bod = LetCallT {async = False, + binds = [(y_45_85_119, + ProdTy [])], + rator = "_print_Tree", + rands = [VarTriv "x_43_81_115"], + bod = LetPrimCallT {binds = [(wildcard_49_86_120, + ProdTy [])], + prim = PrintSym, + rands = [SymTriv 126], + bod = LetCallT {async = False, + binds = [(y_46_87_121, + ProdTy [])], + rator = "_print_Tree", + rands = [VarTriv "x_44_82_116"], + bod = LetPrimCallT {binds = [(wildcard_48_88_122, + ProdTy [])], + prim = PrintSym, + rands = [SymTriv 123], + bod = RetValsT []}}}}}}})]) + (Just ErrT "Unknown tag in: tag_140")}, + isPure = True}], + mainExp = Nothing} + + [compiler] Final C codegen: 8787 characters. +================================================================================ +/* Gibbon program. */ + +#include "gibbon_rts.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef _WIN64 +#include +#endif + +#ifdef _GIBBON_POINTER +#include +#endif + +#ifdef _GIBBON_PARALLEL +#include +#include +#endif + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Program starts here + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +typedef struct GibIntProd_struct { + GibInt field0; + } GibIntProd; +typedef struct GibIntGibIntProd_struct { + GibInt field0; + GibInt field1; + } GibIntGibIntProd; +typedef struct GibIntGibCursorGibCursorProd_struct { + GibInt field0; + GibCursor field1; + GibCursor field2; + } GibIntGibCursorGibCursorProd; +typedef struct GibPackedTagGibCursorProd_struct { + GibPackedTag field0; + GibCursor field1; + } GibPackedTagGibCursorProd; +typedef struct GibCursorProd_struct { + GibCursor field0; + } GibCursorProd; +typedef struct GibCursorGibCursorProd_struct { + GibCursor field0; + GibCursor field1; + } GibCursorGibCursorProd; +GibCursor _copy_Tree(GibCursor arg_16_55_89); +GibCursor _copy_without_ptrs_Tree(GibCursor arg_23_62_96); +unsigned char _traverse_Tree(GibCursor arg_30_69_103); +unsigned char _print_Tree(GibCursor arg_37_75_109); +typedef enum { + GibInt_T, + GibFloat_T, + GibSym_T, + GibBool_T, + GibVector_T, + GibList_T, + GibCursor_T, + Tree_T, + } GibDatatype; +void info_table_initialize(void) +{ + int error = gib_info_table_initialize(8); + + if (error < 0) { + fprintf(stderr, "Couldn't initialize info table, errorno=%d", error); + exit(1); + } + + GibDatatype field_tys[1]; + + error = gib_info_table_insert_packed_dcon(Tree_T, 0, 8, 0, 1, 0, field_tys, + 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, Tree_T, 0); + exit(1); + } + error = gib_info_table_insert_packed_dcon(Tree_T, 1, 0, 2, 0, 0, field_tys, + 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, Tree_T, 1); + exit(1); + } + gib_info_table_finalize(); +} +void symbol_table_initialize(void) +{ + gib_add_symbol(123, ")"); + gib_add_symbol(124, "(Node"); + gib_add_symbol(125, "(Leaf"); + gib_add_symbol(126, " "); +} +GibCursor _copy_Tree(GibCursor arg_16_55_89) +{ + GibPackedTag tag_127 = *(GibPackedTag *) arg_16_55_89; + GibCursor tail_128 = arg_16_55_89 + sizeof(GibInt); + + + switch_131: + ; + switch (tag_127) { + + case 0: + { + GibInt x_17_56_90 = ((GibIntProd *) tail_128)->field0; + GibPtr tailift_129 = gib_alloc(sizeof(GibIntGibIntProd)); + + ((GibIntGibIntProd *) tailift_129)->field0 = 0; + ((GibIntGibIntProd *) tailift_129)->field1 = x_17_56_90; + return tailift_129; + break; + } + + case 1: + { + GibCursor x_19_58_92 = + ((GibCursorGibCursorProd *) tail_128)->field0; + GibCursor x_20_59_93 = + ((GibCursorGibCursorProd *) tail_128)->field1; + GibCursor y_21_60_94 = _copy_Tree(x_19_58_92); + GibCursor y_22_61_95 = _copy_Tree(x_20_59_93); + GibPtr tailift_130 = + gib_alloc(sizeof(GibIntGibCursorGibCursorProd)); + + ((GibIntGibCursorGibCursorProd *) tailift_130)->field0 = 1; + ((GibIntGibCursorGibCursorProd *) tailift_130)->field1 = y_21_60_94; + ((GibIntGibCursorGibCursorProd *) tailift_130)->field2 = y_22_61_95; + return tailift_130; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_127"); + exit(1); + } + } +} +GibCursor _copy_without_ptrs_Tree(GibCursor arg_23_62_96) +{ + GibPackedTag tag_132 = *(GibPackedTag *) arg_23_62_96; + GibCursor tail_133 = arg_23_62_96 + sizeof(GibInt); + + + switch_136: + ; + switch (tag_132) { + + case 0: + { + GibInt x_24_63_97 = ((GibIntProd *) tail_133)->field0; + GibPtr tailift_134 = gib_alloc(sizeof(GibIntGibIntProd)); + + ((GibIntGibIntProd *) tailift_134)->field0 = 0; + ((GibIntGibIntProd *) tailift_134)->field1 = x_24_63_97; + return tailift_134; + break; + } + + case 1: + { + GibCursor x_26_65_99 = + ((GibCursorGibCursorProd *) tail_133)->field0; + GibCursor x_27_66_100 = + ((GibCursorGibCursorProd *) tail_133)->field1; + GibCursor y_28_67_101 = _copy_without_ptrs_Tree(x_26_65_99); + GibCursor y_29_68_102 = _copy_without_ptrs_Tree(x_27_66_100); + GibPtr tailift_135 = + gib_alloc(sizeof(GibIntGibCursorGibCursorProd)); + + ((GibIntGibCursorGibCursorProd *) tailift_135)->field0 = 1; + ((GibIntGibCursorGibCursorProd *) tailift_135)->field1 = + y_28_67_101; + ((GibIntGibCursorGibCursorProd *) tailift_135)->field2 = + y_29_68_102; + return tailift_135; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_132"); + exit(1); + } + } +} +unsigned char _traverse_Tree(GibCursor arg_30_69_103) +{ + GibPackedTag tag_137 = *(GibPackedTag *) arg_30_69_103; + GibCursor tail_138 = arg_30_69_103 + sizeof(GibInt); + + + switch_139: + ; + switch (tag_137) { + + case 0: + { + GibInt x_31_70_104 = ((GibIntProd *) tail_138)->field0; + + return 0; + break; + } + + case 1: + { + GibCursor x_33_71_105 = + ((GibCursorGibCursorProd *) tail_138)->field0; + GibCursor x_34_72_106 = + ((GibCursorGibCursorProd *) tail_138)->field1; + unsigned char y_35_73_107 = _traverse_Tree(x_33_71_105); + unsigned char y_36_74_108 = _traverse_Tree(x_34_72_106); + + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_137"); + exit(1); + } + } +} +unsigned char _print_Tree(GibCursor arg_37_75_109) +{ + GibPackedTag tag_140 = *(GibPackedTag *) arg_37_75_109; + GibCursor tail_141 = arg_37_75_109 + sizeof(GibInt); + + + switch_142: + ; + switch (tag_140) { + + case 0: + { + GibInt x_38_76_110 = ((GibIntProd *) tail_141)->field0; + unsigned char wildcard_40_77_111 = gib_print_symbol(125); + unsigned char wildcard_42_78_112 = gib_print_symbol(126); + unsigned char y_39_79_113 = printf("%ld", x_38_76_110); + unsigned char wildcard_41_80_114 = gib_print_symbol(123); + + return 0; + break; + } + + case 1: + { + GibCursor x_43_81_115 = + ((GibCursorGibCursorProd *) tail_141)->field0; + GibCursor x_44_82_116 = + ((GibCursorGibCursorProd *) tail_141)->field1; + unsigned char wildcard_47_83_117 = gib_print_symbol(124); + unsigned char wildcard_50_84_118 = gib_print_symbol(126); + unsigned char y_45_85_119 = _print_Tree(x_43_81_115); + unsigned char wildcard_49_86_120 = gib_print_symbol(126); + unsigned char y_46_87_121 = _print_Tree(x_44_82_116); + unsigned char wildcard_48_88_122 = gib_print_symbol(123); + + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_140"); + exit(1); + } + } +} +int main(int argc, char **argv) +{ + int init_0 = gib_init(argc, argv); + + info_table_initialize(); + symbol_table_initialize(); + + int exit_1 = gib_exit(); + + return exit_1; +} + +Compiling RTS +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +make -f /home/timmy/git/gibbon/gibbon-rts/Makefile MODE=release GC=nongen USER_CFLAGS=" -O3 -flto " VERBOSITY=4 + +make: Nothing to be done for 'all'. + + + + +Compiling the program +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +gcc -std=gnu11 -O3 -flto -D_GIBBON_GENGC=0 -D_GIBBON_SIMPLE_WRITE_BARRIER=0 -D_GIBBON_EAGER_PROMOTION=1 -o /home/timmy/git/gibbon/./gibbon-compiler/examples/addimport.exe -I/home/timmy/git/gibbon/gibbon-rts/build -L/home/timmy/git/gibbon/gibbon-rts/build -Wl,-rpath=/home/timmy/git/gibbon/gibbon-rts/build /home/timmy/git/gibbon/./gibbon-compiler/examples/addimport.c /home/timmy/git/gibbon/gibbon-rts/build/gibbon_rts.o -lm -lgibbon_rts_ng + + + +In file included from /home/timmy/git/gibbon/./gibbon-compiler/examples/addimport.c:3:0: +/home/timmy/git/gibbon/gibbon-rts/build/gibbon_rts.h: In function ‘gib_indirection_barrier’: +/home/timmy/git/gibbon/gibbon-rts/build/gibbon_rts.h:1075:6: warning: #warning "Simple write barrier is disabled." [-Wcpp] + #warning "Simple write barrier is disabled." + ^~~~~~~ + + diff --git a/README.md b/README.md index d24bb970c..2fd040a1d 100644 --- a/README.md +++ b/README.md @@ -89,10 +89,21 @@ Gibbon from source: $ cd gibbon-compiler && cabal v2-build At this point you can run the Gibbon executable: +``` + $ cabal v2-exec -w ghc-9.0.1 gibbon -- -h +``` - $ cabal v2-run gibbon -- -h +And add gibbon to PATH +``` +$ export PATH = "{ ... }/gibbon/dist-newstyle/build/{architecture}/ghc-{version}/gibbon-0.2/x/gibbon/build/gibbon/gibbon:$PATH" +``` If you'd like to run the testsuite, you can do so with: +``` +$ cd gibbon-compiler +$ cabal v2-exec -w ghc test-gibbon-examples -- -v2 +``` + $ ./run_all_tests.sh @@ -140,6 +151,12 @@ Here's a simple Gibbon program that builds a binary tree and sums up its leaves using a parallel tuple (`par`): + + + + + + ```haskell module Main where diff --git a/benchmarks/AddImport.c b/benchmarks/AddImport.c new file mode 100644 index 000000000..59ad8c64e --- /dev/null +++ b/benchmarks/AddImport.c @@ -0,0 +1,93 @@ +/* Gibbon program. */ + +#include "gibbon_rts.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef _WIN64 +#include +#endif + +#ifdef _GIBBON_POINTER +#include +#endif + +#ifdef _GIBBON_PARALLEL +#include +#include +#endif + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Program starts here + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +typedef struct GibIntProd_struct { + GibInt field0; + } GibIntProd; +GibInt add1(GibInt x_1_10_13); +typedef enum { + GibInt_T, + GibFloat_T, + GibSym_T, + GibBool_T, + GibVector_T, + GibList_T, + GibCursor_T, + } GibDatatype; +void info_table_initialize(void) +{ + int error = gib_info_table_initialize(7); + + if (error < 0) { + fprintf(stderr, "Couldn't initialize info table, errorno=%d", error); + exit(1); + } + + GibDatatype field_tys[0]; + + gib_info_table_finalize(); +} +void symbol_table_initialize(void) +{ } +GibInt add1(GibInt x_1_10_13) +{ + GibInt flt_15 = x_1_10_13 + 1; + + return flt_15; +} +int main(int argc, char **argv) +{ + int init_0 = gib_init(argc, argv); + + info_table_initialize(); + symbol_table_initialize(); + + GibInt fltAppE_11_12 = add1(0); + GibInt tmp_app_14 = add1(fltAppE_11_12); + + printf("%ld", tmp_app_14); + printf("\n"); + return 0; + + int exit_1 = gib_exit(); + + return exit_1; +} \ No newline at end of file diff --git a/benchmarks/Addone.c b/benchmarks/Addone.c new file mode 100644 index 000000000..bb458c5cc --- /dev/null +++ b/benchmarks/Addone.c @@ -0,0 +1,76 @@ +/* Gibbon program. */ + +#include "gibbon_rts.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef _WIN64 +#include +#endif + +#ifdef _GIBBON_POINTER +#include +#endif + +#ifdef _GIBBON_PARALLEL +#include +#include +#endif + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Program starts here + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +typedef enum { + GibInt_T, + GibFloat_T, + GibSym_T, + GibBool_T, + GibVector_T, + GibList_T, + GibCursor_T, + } GibDatatype; +void info_table_initialize(void) +{ + int error = gib_info_table_initialize(7); + + if (error < 0) { + fprintf(stderr, "Couldn't initialize info table, errorno=%d", error); + exit(1); + } + + GibDatatype field_tys[0]; + + gib_info_table_finalize(); +} +void symbol_table_initialize(void) +{ } +int main(int argc, char **argv) +{ + int init_0 = gib_init(argc, argv); + + info_table_initialize(); + symbol_table_initialize(); + + int exit_1 = gib_exit(); + + return exit_1; +} \ No newline at end of file diff --git a/benchmarks/Addtwo.c b/benchmarks/Addtwo.c new file mode 100644 index 000000000..bb458c5cc --- /dev/null +++ b/benchmarks/Addtwo.c @@ -0,0 +1,76 @@ +/* Gibbon program. */ + +#include "gibbon_rts.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef _WIN64 +#include +#endif + +#ifdef _GIBBON_POINTER +#include +#endif + +#ifdef _GIBBON_PARALLEL +#include +#include +#endif + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Program starts here + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +typedef enum { + GibInt_T, + GibFloat_T, + GibSym_T, + GibBool_T, + GibVector_T, + GibList_T, + GibCursor_T, + } GibDatatype; +void info_table_initialize(void) +{ + int error = gib_info_table_initialize(7); + + if (error < 0) { + fprintf(stderr, "Couldn't initialize info table, errorno=%d", error); + exit(1); + } + + GibDatatype field_tys[0]; + + gib_info_table_finalize(); +} +void symbol_table_initialize(void) +{ } +int main(int argc, char **argv) +{ + int init_0 = gib_init(argc, argv); + + info_table_initialize(); + symbol_table_initialize(); + + int exit_1 = gib_exit(); + + return exit_1; +} \ No newline at end of file diff --git a/benchmarks/CRDTs/Clock.c b/benchmarks/CRDTs/Clock.c new file mode 100644 index 000000000..0467c67a9 --- /dev/null +++ b/benchmarks/CRDTs/Clock.c @@ -0,0 +1,902 @@ +/* Gibbon program. */ + +#include "gibbon_rts.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef _WIN64 +#include +#endif + +#ifdef _GIBBON_POINTER +#include +#endif + +#ifdef _GIBBON_PARALLEL +#include +#include +#endif + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Program starts here + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +typedef struct GibIntProd_struct { + GibInt field0; + } GibIntProd; +typedef struct GibIntGibIntProd_struct { + GibInt field0; + GibInt field1; + } GibIntGibIntProd; +typedef struct GibIntGibIntGibIntGibIntGibCursorGibCursorProd_struct { + GibInt field0; + GibInt field1; + GibInt field2; + GibInt field3; + GibCursor field4; + GibCursor field5; + } GibIntGibIntGibIntGibIntGibCursorGibCursorProd; +typedef struct GibIntGibIntGibIntGibCursorGibCursorProd_struct { + GibInt field0; + GibInt field1; + GibInt field2; + GibCursor field3; + GibCursor field4; + } GibIntGibIntGibIntGibCursorGibCursorProd; +typedef struct GibIntGibIntGibCursorProd_struct { + GibInt field0; + GibInt field1; + GibCursor field2; + } GibIntGibIntGibCursorProd; +typedef struct GibPackedTagGibCursorProd_struct { + GibPackedTag field0; + GibCursor field1; + } GibPackedTagGibCursorProd; +typedef struct GibCursorProd_struct { + GibCursor field0; + } GibCursorProd; +GibCursor _copy_Clock94(GibCursor arg102213191506); +GibCursor _copy_without_ptrs_Clock94(GibCursor arg102713241511); +unsigned char _traverse_Clock94(GibCursor arg103213291516); +unsigned char _print_Clock94(GibCursor arg103713331520); +GibCursor _copy_Timestamp95(GibCursor arg104613421529); +GibCursor _copy_without_ptrs_Timestamp95(GibCursor arg105113471534); +unsigned char _traverse_Timestamp95(GibCursor arg105613521539); +unsigned char _print_Timestamp95(GibCursor arg106113561543); +GibCursor _copy_Ord100(GibCursor arg107013651552); +GibCursor _copy_without_ptrs_Ord100(GibCursor arg107113661553); +unsigned char _traverse_Ord100(GibCursor arg107213671554); +unsigned char _print_Ord100(GibCursor arg107313681555); +GibCursor _copy_Maybe99_v676(GibCursor arg108213771564); +GibCursor _copy_without_ptrs_Maybe99_v676(GibCursor arg108513801567); +unsigned char _traverse_Maybe99_v676(GibCursor arg108813831570); +unsigned char _print_Maybe99_v676(GibCursor arg109113851572); +GibCursor _copy_Map129_v674(GibCursor arg109913931580); +GibCursor _copy_without_ptrs_Map129_v674(GibCursor arg111014041591); +unsigned char _traverse_Map129_v674(GibCursor arg112114151602); +unsigned char _print_Map129_v674(GibCursor arg113214231610); +typedef enum { + GibInt_T, + GibFloat_T, + GibSym_T, + GibBool_T, + GibVector_T, + GibList_T, + GibCursor_T, + Clock94_T, + Map129_v674_T, + Maybe99_v676_T, + Ord100_T, + Timestamp95_T, + } GibDatatype; +void info_table_initialize(void) +{ + int error = gib_info_table_initialize(12); + + if (error < 0) { + fprintf(stderr, "Couldn't initialize info table, errorno=%d", error); + exit(1); + } + + GibDatatype field_tys[3]; + + error = gib_info_table_insert_packed_dcon(Clock94_T, 0, 8, 1, 1, 0, + field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, Clock94_T, 0); + exit(1); + } + error = gib_info_table_insert_packed_dcon(Map129_v674_T, 1, 24, 2, 3, 0, + field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, Map129_v674_T, 1); + exit(1); + } + error = gib_info_table_insert_packed_dcon(Map129_v674_T, 0, 0, 0, 0, 0, + field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, Map129_v674_T, 0); + exit(1); + } + error = gib_info_table_insert_packed_dcon(Maybe99_v676_T, 1, 8, 0, 1, 0, + field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, Maybe99_v676_T, 1); + exit(1); + } + error = gib_info_table_insert_packed_dcon(Maybe99_v676_T, 0, 0, 0, 0, 0, + field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, Maybe99_v676_T, 0); + exit(1); + } + error = gib_info_table_insert_packed_dcon(Ord100_T, 3, 0, 0, 0, 0, + field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, Ord100_T, 3); + exit(1); + } + error = gib_info_table_insert_packed_dcon(Ord100_T, 2, 0, 0, 0, 0, + field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, Ord100_T, 2); + exit(1); + } + error = gib_info_table_insert_packed_dcon(Ord100_T, 1, 0, 0, 0, 0, + field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, Ord100_T, 1); + exit(1); + } + error = gib_info_table_insert_packed_dcon(Ord100_T, 0, 0, 0, 0, 0, + field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, Ord100_T, 0); + exit(1); + } + error = gib_info_table_insert_packed_dcon(Timestamp95_T, 0, 8, 1, 1, 0, + field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, Timestamp95_T, 0); + exit(1); + } + gib_info_table_finalize(); +} +void symbol_table_initialize(void) +{ + gib_add_symbol(1630, ")"); + gib_add_symbol(1631, "(Tip130_v674"); + gib_add_symbol(1632, "(Timestamp96"); + gib_add_symbol(1633, "(Nothing105_v676"); + gib_add_symbol(1634, "(Lt101"); + gib_add_symbol(1635, "(Just106_v676"); + gib_add_symbol(1636, "(Gt102"); + gib_add_symbol(1637, "(Eq103"); + gib_add_symbol(1638, "(Clk97"); + gib_add_symbol(1639, "(Cc104"); + gib_add_symbol(1640, "(Bin131_v674"); + gib_add_symbol(1641, " "); +} +GibCursor _copy_Clock94(GibCursor arg102213191506) +{ + GibInt tag1642 = ((GibIntGibIntGibCursorProd *) arg102213191506)->field0; + GibInt x102313201507 = + ((GibIntGibIntGibCursorProd *) arg102213191506)->field1; + GibCursor x102413211508 = + ((GibIntGibIntGibCursorProd *) arg102213191506)->field2; + GibCursor y102613231510 = _copy_Map129_v674(x102413211508); + GibPtr tailift1643 = gib_alloc(sizeof(GibIntGibIntGibCursorProd)); + + ((GibIntGibIntGibCursorProd *) tailift1643)->field0 = 0; + ((GibIntGibIntGibCursorProd *) tailift1643)->field1 = x102313201507; + ((GibIntGibIntGibCursorProd *) tailift1643)->field2 = y102613231510; + return tailift1643; +} +GibCursor _copy_without_ptrs_Clock94(GibCursor arg102713241511) +{ + GibInt tag1644 = ((GibIntGibIntGibCursorProd *) arg102713241511)->field0; + GibInt x102813251512 = + ((GibIntGibIntGibCursorProd *) arg102713241511)->field1; + GibCursor x102913261513 = + ((GibIntGibIntGibCursorProd *) arg102713241511)->field2; + GibCursor y103113281515 = _copy_without_ptrs_Map129_v674(x102913261513); + GibPtr tailift1645 = gib_alloc(sizeof(GibIntGibIntGibCursorProd)); + + ((GibIntGibIntGibCursorProd *) tailift1645)->field0 = 0; + ((GibIntGibIntGibCursorProd *) tailift1645)->field1 = x102813251512; + ((GibIntGibIntGibCursorProd *) tailift1645)->field2 = y103113281515; + return tailift1645; +} +unsigned char _traverse_Clock94(GibCursor arg103213291516) +{ + GibInt tag1646 = ((GibIntGibIntGibCursorProd *) arg103213291516)->field0; + GibInt x103313301517 = + ((GibIntGibIntGibCursorProd *) arg103213291516)->field1; + GibCursor x103413311518 = + ((GibIntGibIntGibCursorProd *) arg103213291516)->field2; + unsigned char y103613321519 = _traverse_Map129_v674(x103413311518); + + return 0; +} +unsigned char _print_Clock94(GibCursor arg103713331520) +{ + GibInt tag1647 = ((GibIntGibIntGibCursorProd *) arg103713331520)->field0; + GibInt x103813341521 = + ((GibIntGibIntGibCursorProd *) arg103713331520)->field1; + GibCursor x103913351522 = + ((GibIntGibIntGibCursorProd *) arg103713331520)->field2; + unsigned char wildcard104213361523 = gib_print_symbol(1638); + unsigned char wildcard104513371524 = gib_print_symbol(1641); + unsigned char y104013381525 = printf("%ld", x103813341521); + unsigned char wildcard104413391526 = gib_print_symbol(1641); + unsigned char y104113401527 = _print_Map129_v674(x103913351522); + unsigned char wildcard104313411528 = gib_print_symbol(1630); + + return 0; +} +GibCursor _copy_Timestamp95(GibCursor arg104613421529) +{ + GibInt tag1648 = ((GibIntGibIntGibCursorProd *) arg104613421529)->field0; + GibInt x104713431530 = + ((GibIntGibIntGibCursorProd *) arg104613421529)->field1; + GibCursor x104813441531 = + ((GibIntGibIntGibCursorProd *) arg104613421529)->field2; + GibCursor y105013461533 = _copy_Clock94(x104813441531); + GibPtr tailift1649 = gib_alloc(sizeof(GibIntGibIntGibCursorProd)); + + ((GibIntGibIntGibCursorProd *) tailift1649)->field0 = 0; + ((GibIntGibIntGibCursorProd *) tailift1649)->field1 = x104713431530; + ((GibIntGibIntGibCursorProd *) tailift1649)->field2 = y105013461533; + return tailift1649; +} +GibCursor _copy_without_ptrs_Timestamp95(GibCursor arg105113471534) +{ + GibInt tag1650 = ((GibIntGibIntGibCursorProd *) arg105113471534)->field0; + GibInt x105213481535 = + ((GibIntGibIntGibCursorProd *) arg105113471534)->field1; + GibCursor x105313491536 = + ((GibIntGibIntGibCursorProd *) arg105113471534)->field2; + GibCursor y105513511538 = _copy_without_ptrs_Clock94(x105313491536); + GibPtr tailift1651 = gib_alloc(sizeof(GibIntGibIntGibCursorProd)); + + ((GibIntGibIntGibCursorProd *) tailift1651)->field0 = 0; + ((GibIntGibIntGibCursorProd *) tailift1651)->field1 = x105213481535; + ((GibIntGibIntGibCursorProd *) tailift1651)->field2 = y105513511538; + return tailift1651; +} +unsigned char _traverse_Timestamp95(GibCursor arg105613521539) +{ + GibInt tag1652 = ((GibIntGibIntGibCursorProd *) arg105613521539)->field0; + GibInt x105713531540 = + ((GibIntGibIntGibCursorProd *) arg105613521539)->field1; + GibCursor x105813541541 = + ((GibIntGibIntGibCursorProd *) arg105613521539)->field2; + unsigned char y106013551542 = _traverse_Clock94(x105813541541); + + return 0; +} +unsigned char _print_Timestamp95(GibCursor arg106113561543) +{ + GibInt tag1653 = ((GibIntGibIntGibCursorProd *) arg106113561543)->field0; + GibInt x106213571544 = + ((GibIntGibIntGibCursorProd *) arg106113561543)->field1; + GibCursor x106313581545 = + ((GibIntGibIntGibCursorProd *) arg106113561543)->field2; + unsigned char wildcard106613591546 = gib_print_symbol(1632); + unsigned char wildcard106913601547 = gib_print_symbol(1641); + unsigned char y106413611548 = printf("%ld", x106213571544); + unsigned char wildcard106813621549 = gib_print_symbol(1641); + unsigned char y106513631550 = _print_Clock94(x106313581545); + unsigned char wildcard106713641551 = gib_print_symbol(1630); + + return 0; +} +GibCursor _copy_Ord100(GibCursor arg107013651552) +{ + GibPackedTag tag1654 = *(GibPackedTag *) arg107013651552; + GibCursor tail1655 = arg107013651552 + sizeof(GibInt); + + + switch1660: + ; + switch (tag1654) { + + case 0: + { + GibPtr tailift1656 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift1656)->field0 = 0; + return tailift1656; + break; + } + + case 1: + { + GibPtr tailift1657 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift1657)->field0 = 1; + return tailift1657; + break; + } + + case 2: + { + GibPtr tailift1658 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift1658)->field0 = 2; + return tailift1658; + break; + } + + case 3: + { + GibPtr tailift1659 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift1659)->field0 = 3; + return tailift1659; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1654"); + exit(1); + } + } +} +GibCursor _copy_without_ptrs_Ord100(GibCursor arg107113661553) +{ + GibPackedTag tag1661 = *(GibPackedTag *) arg107113661553; + GibCursor tail1662 = arg107113661553 + sizeof(GibInt); + + + switch1667: + ; + switch (tag1661) { + + case 0: + { + GibPtr tailift1663 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift1663)->field0 = 0; + return tailift1663; + break; + } + + case 1: + { + GibPtr tailift1664 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift1664)->field0 = 1; + return tailift1664; + break; + } + + case 2: + { + GibPtr tailift1665 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift1665)->field0 = 2; + return tailift1665; + break; + } + + case 3: + { + GibPtr tailift1666 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift1666)->field0 = 3; + return tailift1666; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1661"); + exit(1); + } + } +} +unsigned char _traverse_Ord100(GibCursor arg107213671554) +{ + GibPackedTag tag1668 = *(GibPackedTag *) arg107213671554; + GibCursor tail1669 = arg107213671554 + sizeof(GibInt); + + + switch1670: + ; + switch (tag1668) { + + case 0: + { + return 0; + break; + } + + case 1: + { + return 0; + break; + } + + case 2: + { + return 0; + break; + } + + case 3: + { + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1668"); + exit(1); + } + } +} +unsigned char _print_Ord100(GibCursor arg107313681555) +{ + GibPackedTag tag1671 = *(GibPackedTag *) arg107313681555; + GibCursor tail1672 = arg107313681555 + sizeof(GibInt); + + + switch1673: + ; + switch (tag1671) { + + case 0: + { + unsigned char wildcard107413691556 = gib_print_symbol(1634); + unsigned char wildcard107513701557 = gib_print_symbol(1630); + + return 0; + break; + } + + case 1: + { + unsigned char wildcard107613711558 = gib_print_symbol(1636); + unsigned char wildcard107713721559 = gib_print_symbol(1630); + + return 0; + break; + } + + case 2: + { + unsigned char wildcard107813731560 = gib_print_symbol(1637); + unsigned char wildcard107913741561 = gib_print_symbol(1630); + + return 0; + break; + } + + case 3: + { + unsigned char wildcard108013751562 = gib_print_symbol(1639); + unsigned char wildcard108113761563 = gib_print_symbol(1630); + + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1671"); + exit(1); + } + } +} +GibCursor _copy_Maybe99_v676(GibCursor arg108213771564) +{ + GibPackedTag tag1674 = *(GibPackedTag *) arg108213771564; + GibCursor tail1675 = arg108213771564 + sizeof(GibInt); + + + switch1678: + ; + switch (tag1674) { + + case 0: + { + GibPtr tailift1676 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift1676)->field0 = 0; + return tailift1676; + break; + } + + case 1: + { + GibInt x108313781565 = ((GibIntProd *) tail1675)->field0; + GibPtr tailift1677 = gib_alloc(sizeof(GibIntGibIntProd)); + + ((GibIntGibIntProd *) tailift1677)->field0 = 1; + ((GibIntGibIntProd *) tailift1677)->field1 = x108313781565; + return tailift1677; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1674"); + exit(1); + } + } +} +GibCursor _copy_without_ptrs_Maybe99_v676(GibCursor arg108513801567) +{ + GibPackedTag tag1679 = *(GibPackedTag *) arg108513801567; + GibCursor tail1680 = arg108513801567 + sizeof(GibInt); + + + switch1683: + ; + switch (tag1679) { + + case 0: + { + GibPtr tailift1681 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift1681)->field0 = 0; + return tailift1681; + break; + } + + case 1: + { + GibInt x108613811568 = ((GibIntProd *) tail1680)->field0; + GibPtr tailift1682 = gib_alloc(sizeof(GibIntGibIntProd)); + + ((GibIntGibIntProd *) tailift1682)->field0 = 1; + ((GibIntGibIntProd *) tailift1682)->field1 = x108613811568; + return tailift1682; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1679"); + exit(1); + } + } +} +unsigned char _traverse_Maybe99_v676(GibCursor arg108813831570) +{ + GibPackedTag tag1684 = *(GibPackedTag *) arg108813831570; + GibCursor tail1685 = arg108813831570 + sizeof(GibInt); + + + switch1686: + ; + switch (tag1684) { + + case 0: + { + return 0; + break; + } + + case 1: + { + GibInt x108913841571 = ((GibIntProd *) tail1685)->field0; + + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1684"); + exit(1); + } + } +} +unsigned char _print_Maybe99_v676(GibCursor arg109113851572) +{ + GibPackedTag tag1687 = *(GibPackedTag *) arg109113851572; + GibCursor tail1688 = arg109113851572 + sizeof(GibInt); + + + switch1689: + ; + switch (tag1687) { + + case 0: + { + unsigned char wildcard109213861573 = gib_print_symbol(1633); + unsigned char wildcard109313871574 = gib_print_symbol(1630); + + return 0; + break; + } + + case 1: + { + GibInt x109413881575 = ((GibIntProd *) tail1688)->field0; + unsigned char wildcard109613891576 = gib_print_symbol(1635); + unsigned char wildcard109813901577 = gib_print_symbol(1641); + unsigned char y109513911578 = printf("%ld", x109413881575); + unsigned char wildcard109713921579 = gib_print_symbol(1630); + + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1687"); + exit(1); + } + } +} +GibCursor _copy_Map129_v674(GibCursor arg109913931580) +{ + GibPackedTag tag1690 = *(GibPackedTag *) arg109913931580; + GibCursor tail1691 = arg109913931580 + sizeof(GibInt); + + + switch1694: + ; + switch (tag1690) { + + case 0: + { + GibPtr tailift1692 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift1692)->field0 = 0; + return tailift1692; + break; + } + + case 1: + { + GibInt x110013941581 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail1691)->field0; + GibInt x110113951582 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail1691)->field1; + GibInt x110213961583 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail1691)->field2; + GibCursor x110313971584 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail1691)->field3; + GibCursor x110413981585 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail1691)->field4; + GibCursor y110814021589 = _copy_Map129_v674(x110313971584); + GibCursor y110914031590 = _copy_Map129_v674(x110413981585); + GibPtr tailift1693 = + gib_alloc(sizeof(GibIntGibIntGibIntGibIntGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift1693)->field0 = + 1; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift1693)->field1 = + x110013941581; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift1693)->field2 = + x110113951582; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift1693)->field3 = + x110213961583; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift1693)->field4 = + y110814021589; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift1693)->field5 = + y110914031590; + return tailift1693; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1690"); + exit(1); + } + } +} +GibCursor _copy_without_ptrs_Map129_v674(GibCursor arg111014041591) +{ + GibPackedTag tag1695 = *(GibPackedTag *) arg111014041591; + GibCursor tail1696 = arg111014041591 + sizeof(GibInt); + + + switch1699: + ; + switch (tag1695) { + + case 0: + { + GibPtr tailift1697 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift1697)->field0 = 0; + return tailift1697; + break; + } + + case 1: + { + GibInt x111114051592 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail1696)->field0; + GibInt x111214061593 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail1696)->field1; + GibInt x111314071594 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail1696)->field2; + GibCursor x111414081595 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail1696)->field3; + GibCursor x111514091596 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail1696)->field4; + GibCursor y111914131600 = + _copy_without_ptrs_Map129_v674(x111414081595); + GibCursor y112014141601 = + _copy_without_ptrs_Map129_v674(x111514091596); + GibPtr tailift1698 = + gib_alloc(sizeof(GibIntGibIntGibIntGibIntGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift1698)->field0 = + 1; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift1698)->field1 = + x111114051592; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift1698)->field2 = + x111214061593; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift1698)->field3 = + x111314071594; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift1698)->field4 = + y111914131600; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift1698)->field5 = + y112014141601; + return tailift1698; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1695"); + exit(1); + } + } +} +unsigned char _traverse_Map129_v674(GibCursor arg112114151602) +{ + GibPackedTag tag1700 = *(GibPackedTag *) arg112114151602; + GibCursor tail1701 = arg112114151602 + sizeof(GibInt); + + + switch1702: + ; + switch (tag1700) { + + case 0: + { + return 0; + break; + } + + case 1: + { + GibInt x112214161603 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail1701)->field0; + GibInt x112314171604 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail1701)->field1; + GibInt x112414181605 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail1701)->field2; + GibCursor x112514191606 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail1701)->field3; + GibCursor x112614201607 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail1701)->field4; + unsigned char y113014211608 = _traverse_Map129_v674(x112514191606); + unsigned char y113114221609 = _traverse_Map129_v674(x112614201607); + + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1700"); + exit(1); + } + } +} +unsigned char _print_Map129_v674(GibCursor arg113214231610) +{ + GibPackedTag tag1703 = *(GibPackedTag *) arg113214231610; + GibCursor tail1704 = arg113214231610 + sizeof(GibInt); + + + switch1705: + ; + switch (tag1703) { + + case 0: + { + unsigned char wildcard113314241611 = gib_print_symbol(1631); + unsigned char wildcard113414251612 = gib_print_symbol(1630); + + return 0; + break; + } + + case 1: + { + GibInt x113514261613 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail1704)->field0; + GibInt x113614271614 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail1704)->field1; + GibInt x113714281615 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail1704)->field2; + GibCursor x113814291616 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail1704)->field3; + GibCursor x113914301617 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail1704)->field4; + unsigned char wildcard114514311618 = gib_print_symbol(1640); + unsigned char wildcard115114321619 = gib_print_symbol(1641); + unsigned char y114014331620 = printf("%ld", x113514261613); + unsigned char wildcard115014341621 = gib_print_symbol(1641); + unsigned char y114114351622 = printf("%ld", x113614271614); + unsigned char wildcard114914361623 = gib_print_symbol(1641); + unsigned char y114214371624 = printf("%ld", x113714281615); + unsigned char wildcard114814381625 = gib_print_symbol(1641); + unsigned char y114314391626 = _print_Map129_v674(x113814291616); + unsigned char wildcard114714401627 = gib_print_symbol(1641); + unsigned char y114414411628 = _print_Map129_v674(x113914301617); + unsigned char wildcard114614421629 = gib_print_symbol(1630); + + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1703"); + exit(1); + } + } +} +int main(int argc, char **argv) +{ + int init0 = gib_init(argc, argv); + + info_table_initialize(); + symbol_table_initialize(); + + int exit1 = gib_exit(); + + return exit1; +} \ No newline at end of file diff --git a/benchmarks/CRDTs/ClockMap.hs b/benchmarks/CRDTs/ClockMap.hs new file mode 100644 index 000000000..ff1a29f51 --- /dev/null +++ b/benchmarks/CRDTs/ClockMap.hs @@ -0,0 +1,141 @@ +{-# LANGUAGE BlockArguments #-} +{-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE DataKinds #-} + +module ClockMap where +import Common +import Clock + +type Size = Int +data ClockMap a = Tip + | Bin Size Clock a (ClockMap a) (ClockMap a) + +-- Construction ----------------------- + +empty :: ClockMap a +empty = Tip + +singleton :: Clock -> a -> ClockMap a +singleton k x = Bin 1 k x Tip Tip + + +-- Query ------------------------------ + +null :: ClockMap a -> Bool +null m = case m of + Tip -> True + Bin _ _ _ _ _ -> False + +size :: ClockMap a -> Size +size m = case m of + Tip -> 0 + Bin sz _ _ _ _ -> sz + +key :: ClockMap a -> Clock +key s = case s of + Tip -> (Clock.init 0) + Bin _ k _ _ _ -> k + +lookup :: Clock -> ClockMap a -> Common.Maybe a +lookup k m = + case m of + Tip -> Common.Nothing + Bin _ kx v l r -> + case (Clock.compare k kx) of + Eq -> Common.Just v + Lt -> ClockMap.lookup k l + Gt -> ClockMap.lookup k r + Cc -> ClockMap.lookup k r + +member :: Clock -> ClockMap a -> Bool +member k m = case (ClockMap.lookup k m) of + Common.Nothing -> False + Common.Just _ -> True + +-- Insertion -------------------------- + +insert :: Clock -> a -> ClockMap a -> ClockMap a +insert kx x m = + case m of + Tip -> singleton kx x + Bin sz k v l r -> + case (Clock.compare k kx) of + Eq -> Bin sz k x l r + Lt -> balance k v (insert kx x l) r + Gt -> balance k v l (insert kx x r) + Cc -> balance k v l (insert kx x r) + +delta :: Int +delta = 4 +ratio :: Int +ratio = 2 + +balance :: Clock -> a -> ClockMap a -> ClockMap a -> ClockMap a +balance k x l r = + if (size l) + (size r) <= 1 then Bin ((size l) + (size r)) k x l r + else if (size r) >= delta*(size l) then rotateL k x l r + else if (size l) >= delta*(size r) then rotateR k x l r + else Bin ((size l) + (size r)) k x l r + +rotateL :: Clock -> b -> ClockMap b -> ClockMap b -> ClockMap b +rotateL k x l r = + case r of + Bin _ _ _ ly ry -> + if (size ly) < ratio*(size ry) then singleL k x l r + else doubleL k x l r + Tip -> empty -- cry +rotateR :: Clock -> b -> ClockMap b -> ClockMap b -> ClockMap b +rotateR k x l r = + case l of + Bin _ _ _ ly ry -> + if (size ry) < ratio*(size ly) then singleR k x l r + else doubleR k x l r + Tip -> empty --cry + +bin :: Clock -> a -> ClockMap a -> ClockMap a -> ClockMap a +bin k x l r = Bin ((size l) + (size r) + 1) k x l r + +singleL :: Clock -> b -> ClockMap b -> ClockMap b -> ClockMap b +singleL k1 x1 t1 m = + case m of + Bin _ k2 x2 t2 t3 -> bin k2 x2 (bin k1 x1 t1 t2) t3 + Tip -> empty --cry + +singleR :: Clock -> b -> ClockMap b -> ClockMap b -> ClockMap b +singleR k1 x1 m t3 = + case m of + Bin _ k2 x2 t1 t2 -> bin k2 x2 t1 (bin k1 x1 t2 t3) + Tip -> empty --cry + +doubleL :: Clock -> b -> ClockMap b -> ClockMap b -> ClockMap b +doubleL k1 x1 t1 m0 = + case m0 of + Bin _ k2 x2 m1 t4 -> + case m1 of + Bin _ k3 x3 t2 t3 -> bin k3 x3 (bin k1 x1 t1 t2) (bin k2 x2 t3 t4) + Tip -> empty --cry + Tip -> empty --cry + +doubleR :: Clock -> b -> ClockMap b -> ClockMap b -> ClockMap b +doubleR k1 x1 m0 t4 = + case m0 of + Bin _ k2 x2 t1 m1 -> + case m1 of + Bin _ k3 x3 t2 t3 -> bin k3 x3 (bin k2 x2 t1 t2) (bin k1 x1 t3 t4) + Tip -> empty + Tip -> empty --cry + +gibbon_main = + let clk0 = Clock.init 0 + m0 = singleton clk0 "a" + clk1 = step 1 clk0 + m1 = insert clk1 "a" + clk2 = step 2 clk1 + m2 = insert clk2 "a" + clk3 = step 0 clk2 + m3 = insert clk3 "b" + clk4 = step 1 clk3 + m4 = insert clk4 "b" + clk5 = step 2 clk4 + m5 = insert clk5 "b" + in m5 diff --git a/benchmarks/CRDTs/Common.c b/benchmarks/CRDTs/Common.c new file mode 100644 index 000000000..eecfa0cf8 --- /dev/null +++ b/benchmarks/CRDTs/Common.c @@ -0,0 +1,326 @@ +/* Gibbon program. */ + +#include "gibbon_rts.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef _WIN64 +#include +#endif + +#ifdef _GIBBON_POINTER +#include +#endif + +#ifdef _GIBBON_PARALLEL +#include +#include +#endif + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Program starts here + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +typedef struct GibIntProd_struct { + GibInt field0; + } GibIntProd; +typedef struct GibPackedTagGibCursorProd_struct { + GibPackedTag field0; + GibCursor field1; + } GibPackedTagGibCursorProd; +GibCursor _copy_Ord9(GibCursor arg203547); +GibCursor _copy_without_ptrs_Ord9(GibCursor arg213648); +unsigned char _traverse_Ord9(GibCursor arg223749); +unsigned char _print_Ord9(GibCursor arg233850); +typedef enum { + GibInt_T, + GibFloat_T, + GibSym_T, + GibBool_T, + GibVector_T, + GibList_T, + GibCursor_T, + Ord9_T, + } GibDatatype; +void info_table_initialize(void) +{ + int error = gib_info_table_initialize(8); + + if (error < 0) { + fprintf(stderr, "Couldn't initialize info table, errorno=%d", error); + exit(1); + } + + GibDatatype field_tys[0]; + + error = gib_info_table_insert_packed_dcon(Ord9_T, 3, 0, 0, 0, 0, field_tys, + 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, Ord9_T, 3); + exit(1); + } + error = gib_info_table_insert_packed_dcon(Ord9_T, 2, 0, 0, 0, 0, field_tys, + 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, Ord9_T, 2); + exit(1); + } + error = gib_info_table_insert_packed_dcon(Ord9_T, 1, 0, 0, 0, 0, field_tys, + 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, Ord9_T, 1); + exit(1); + } + error = gib_info_table_insert_packed_dcon(Ord9_T, 0, 0, 0, 0, 0, field_tys, + 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, Ord9_T, 0); + exit(1); + } + gib_info_table_finalize(); +} +void symbol_table_initialize(void) +{ + gib_add_symbol(59, ")"); + gib_add_symbol(60, "(Lt10"); + gib_add_symbol(61, "(Gt11"); + gib_add_symbol(62, "(Eq12"); + gib_add_symbol(63, "(Cc13"); +} +GibCursor _copy_Ord9(GibCursor arg203547) +{ + GibPackedTag tag64 = *(GibPackedTag *) arg203547; + GibCursor tail65 = arg203547 + sizeof(GibInt); + + + switch70: + ; + switch (tag64) { + + case 0: + { + GibPtr tailift66 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift66)->field0 = 0; + return tailift66; + break; + } + + case 1: + { + GibPtr tailift67 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift67)->field0 = 1; + return tailift67; + break; + } + + case 2: + { + GibPtr tailift68 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift68)->field0 = 2; + return tailift68; + break; + } + + case 3: + { + GibPtr tailift69 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift69)->field0 = 3; + return tailift69; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag64"); + exit(1); + } + } +} +GibCursor _copy_without_ptrs_Ord9(GibCursor arg213648) +{ + GibPackedTag tag71 = *(GibPackedTag *) arg213648; + GibCursor tail72 = arg213648 + sizeof(GibInt); + + + switch77: + ; + switch (tag71) { + + case 0: + { + GibPtr tailift73 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift73)->field0 = 0; + return tailift73; + break; + } + + case 1: + { + GibPtr tailift74 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift74)->field0 = 1; + return tailift74; + break; + } + + case 2: + { + GibPtr tailift75 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift75)->field0 = 2; + return tailift75; + break; + } + + case 3: + { + GibPtr tailift76 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift76)->field0 = 3; + return tailift76; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag71"); + exit(1); + } + } +} +unsigned char _traverse_Ord9(GibCursor arg223749) +{ + GibPackedTag tag78 = *(GibPackedTag *) arg223749; + GibCursor tail79 = arg223749 + sizeof(GibInt); + + + switch80: + ; + switch (tag78) { + + case 0: + { + return 0; + break; + } + + case 1: + { + return 0; + break; + } + + case 2: + { + return 0; + break; + } + + case 3: + { + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag78"); + exit(1); + } + } +} +unsigned char _print_Ord9(GibCursor arg233850) +{ + GibPackedTag tag81 = *(GibPackedTag *) arg233850; + GibCursor tail82 = arg233850 + sizeof(GibInt); + + + switch83: + ; + switch (tag81) { + + case 0: + { + unsigned char wildcard243951 = gib_print_symbol(60); + unsigned char wildcard254052 = gib_print_symbol(59); + + return 0; + break; + } + + case 1: + { + unsigned char wildcard264153 = gib_print_symbol(61); + unsigned char wildcard274254 = gib_print_symbol(59); + + return 0; + break; + } + + case 2: + { + unsigned char wildcard284355 = gib_print_symbol(62); + unsigned char wildcard294456 = gib_print_symbol(59); + + return 0; + break; + } + + case 3: + { + unsigned char wildcard304557 = gib_print_symbol(63); + unsigned char wildcard314658 = gib_print_symbol(59); + + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag81"); + exit(1); + } + } +} +int main(int argc, char **argv) +{ + int init0 = gib_init(argc, argv); + + info_table_initialize(); + symbol_table_initialize(); + + int exit1 = gib_exit(); + + return exit1; +} \ No newline at end of file diff --git a/benchmarks/CRDTs/Common.hs b/benchmarks/CRDTs/Common.hs new file mode 100644 index 000000000..8095d84fb --- /dev/null +++ b/benchmarks/CRDTs/Common.hs @@ -0,0 +1,14 @@ +module Common where + +data Maybe a = Nothing | Just a + +data Ord = Lt | Gt | Eq | Cc + +compareInt :: Int -> Int -> Common.Ord +compareInt a b = + let sub = a - b + in + if sub < 0 then Lt + else if sub > 0 then Gt + else if sub == 0 then Eq + else Cc \ No newline at end of file diff --git a/benchmarks/CRDTs/DocumentEditor.hs b/benchmarks/CRDTs/DocumentEditor.hs new file mode 100644 index 000000000..52b0707c9 --- /dev/null +++ b/benchmarks/CRDTs/DocumentEditor.hs @@ -0,0 +1,66 @@ +module DocumentEditor where + +import IntOrMap as M +import OrderedList as L +import Timekeeping as T + +data RichText = Text String + | Block (IntOrMap String) (OrderedList RichText) + +data Path = Pth T.Timestamp Path + | Leaf T.Timestamp + +data Update = Up Path Transaction +data Transaction = SetAttr Int String + | DelAttr Int + | Insert T.Timestamp T.Timestamp RichText + | Del T.Timestamp + +-- attrs +-- 1="name" +render_opening :: IntOrMap String -> String + +render_closing :: IntOrMap String -> String + + +render :: RichText -> RichText +render x = + case x of + Text c -> + let _ = printsym (quote c) + in x + Block attrs content -> + let _ = printsym (quote "\n") + _ = printsym (quote (render_opening attrs)) + _ = printsym (quote "\n") + _ = printsym (quote (render content)) + _ = printsym (quote "\n") + _ = printsym (quote (render_closing attrs)) + _ = printsym (quote "\n") + in x + +edit :: Int -> RichText -> Update -> RichText +edit uid doc up = case up of + Up p tr -> case p of + Pth t np -> case doc of + Text _ -> doc + Block attrs els -> case (lookup t els) of + Just ndoc -> edit ndoc (Up np tr) + Nothing -> doc + Leaf t -> case doc of + Text -> doc + Block attrs els -> case tr of + SetAttr key val -> Block (M.add uid key val attrs) els + DelAttr key -> Block (M.remove uid key attrs) els + Insert l r val -> Block attrs (L.insert uid l r val els) + Del t -> Block attrs (L.del uid t els) + +listen :: Int -> RichText -> RichText +listen for doc = + let uid, up = -- This should be the network primitive + ndoc = edit uid doc upd + in if for > 0 then listen (for-1) ndoc + else ndoc + +gibbon_main = + render (listen 10 (Block (M.init 0 1 "document") (L.singleton 0 (Text " ")))) \ No newline at end of file diff --git a/benchmarks/CRDTs/IntOrMap.hs b/benchmarks/CRDTs/IntOrMap.hs new file mode 100644 index 000000000..69f8b6159 --- /dev/null +++ b/benchmarks/CRDTs/IntOrMap.hs @@ -0,0 +1,68 @@ +{-# LANGUAGE BlockArguments #-} +module IntOrMap where +import qualified Timekeeping as T +import qualified Map as M +import qualified Set as S +import qualified Common as C + +data Pair a = Pr T.Timestamp a +data IntOrMap a = OrMap T.Clock (M.Map (Pair a)) (M.Map T.Timestamp) + +getClock :: IntOrMap a -> T.Clock +getClock x = case x of + OrMap clk _ _ -> clk + +getState :: IntOrMap a -> M.Map (Pair a) +getState x = case x of + OrMap _ s _ -> s + +getDelSet :: IntOrMap a -> M.Map T.Timestamp +getDelSet x = case x of + OrMap _ _ delset -> delset + +init :: Int -> Int -> a -> IntOrMap a +init uid key val = + let clk = (T.init uid) + v = Pr (T.stamp uid clk) val + in OrMap (T.step uid clk) (M.singleton key v) M.Tip + +add :: Int -> Int -> a -> IntOrMap a -> IntOrMap a +add uid key val s = + let clk = (getClock s) + timestamp = M.lookup key (getState s) + v = Pr (T.stamp uid clk) val + in OrMap (T.step uid clk) (M.insert key v (getState s)) (getDelSet s) + +toDelSet :: Int -> T.Timestamp -> (M.Map T.Timestamp) -> (M.Map T.Timestamp) +toDelSet key t delset = (M.insert key t delset) + +remove :: Int -> Int -> IntOrMap a -> IntOrMap a +remove uid key s = + let clk = (getClock s) + in case (M.lookup key (getState s)) of + C.Just val -> + case val of + Pr t _ -> OrMap (T.step uid clk) (M.delete key (getState s)) (toDelSet key t (getDelSet s)) + C.Nothing -> s + + + +-- --merge :: Ord eltype => OrMap eltype -> OrMap eltype -> OrMap eltype + +value :: IntOrMap a -> M.Map a +value s = buildValue (getState s) M.Tip + + +buildValue :: M.Map (Pair a) -> M.Map a -> M.Map a +buildValue m s = case m of + M.Tip -> s + M.Bin _ k v l r -> case v of + Pr _ val -> (buildValue l (M.insert k val (buildValue r s))) + + +gibbon_main = + let x = (init 0 0 0) + x = (add 1 9 5 x) + x = (add 0 2 8 x) + x = (add 1 3 1 x) + in value x diff --git a/benchmarks/CRDTs/IntOrSet.c b/benchmarks/CRDTs/IntOrSet.c new file mode 100644 index 000000000..28dffcec0 --- /dev/null +++ b/benchmarks/CRDTs/IntOrSet.c @@ -0,0 +1,1676 @@ +/* Gibbon program. */ + +#include "gibbon_rts.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef _WIN64 +#include +#endif + +#ifdef _GIBBON_POINTER +#include +#endif + +#ifdef _GIBBON_PARALLEL +#include +#include +#endif + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Program starts here + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +typedef struct GibIntProd_struct { + GibInt field0; + } GibIntProd; +typedef struct GibIntGibIntProd_struct { + GibInt field0; + GibInt field1; + } GibIntGibIntProd; +typedef struct GibIntGibIntGibIntGibIntGibCursorGibCursorProd_struct { + GibInt field0; + GibInt field1; + GibInt field2; + GibInt field3; + GibCursor field4; + GibCursor field5; + } GibIntGibIntGibIntGibIntGibCursorGibCursorProd; +typedef struct GibIntGibIntGibIntGibCursorGibCursorProd_struct { + GibInt field0; + GibInt field1; + GibInt field2; + GibCursor field3; + GibCursor field4; + } GibIntGibIntGibIntGibCursorGibCursorProd; +typedef struct GibIntGibIntGibIntGibCursorGibCursorGibCursorProd_struct { + GibInt field0; + GibInt field1; + GibInt field2; + GibCursor field3; + GibCursor field4; + GibCursor field5; + } GibIntGibIntGibIntGibCursorGibCursorGibCursorProd; +typedef struct GibIntGibIntGibCursorProd_struct { + GibInt field0; + GibInt field1; + GibCursor field2; + } GibIntGibIntGibCursorProd; +typedef struct GibIntGibIntGibCursorGibCursorProd_struct { + GibInt field0; + GibInt field1; + GibCursor field2; + GibCursor field3; + } GibIntGibIntGibCursorGibCursorProd; +typedef struct GibIntGibIntGibCursorGibCursorGibCursorProd_struct { + GibInt field0; + GibInt field1; + GibCursor field2; + GibCursor field3; + GibCursor field4; + } GibIntGibIntGibCursorGibCursorGibCursorProd; +typedef struct GibIntGibCursorProd_struct { + GibInt field0; + GibCursor field1; + } GibIntGibCursorProd; +typedef struct GibIntGibCursorGibCursorGibCursorProd_struct { + GibInt field0; + GibCursor field1; + GibCursor field2; + GibCursor field3; + } GibIntGibCursorGibCursorGibCursorProd; +typedef struct GibPackedTagGibCursorProd_struct { + GibPackedTag field0; + GibCursor field1; + } GibPackedTagGibCursorProd; +typedef struct GibCursorProd_struct { + GibCursor field0; + } GibCursorProd; +GibCursor _copy_IntOrSet57(GibCursor arg179825272971); +GibCursor _copy_without_ptrs_IntOrSet57(GibCursor arg180525342978); +unsigned char _traverse_IntOrSet57(GibCursor arg181225412985); +unsigned char _print_IntOrSet57(GibCursor arg181925482992); +GibCursor _copy_Clock120(GibCursor arg183125603004); +GibCursor _copy_without_ptrs_Clock120(GibCursor arg183625653009); +unsigned char _traverse_Clock120(GibCursor arg184125703014); +unsigned char _print_Clock120(GibCursor arg184625743018); +GibCursor _copy_Timestamp121(GibCursor arg185525833027); +GibCursor _copy_without_ptrs_Timestamp121(GibCursor arg186025883032); +unsigned char _traverse_Timestamp121(GibCursor arg186525933037); +unsigned char _print_Timestamp121(GibCursor arg187025973041); +GibCursor _copy_Ord104(GibCursor arg187926063050); +GibCursor _copy_without_ptrs_Ord104(GibCursor arg188026073051); +unsigned char _traverse_Ord104(GibCursor arg188126083052); +unsigned char _print_Ord104(GibCursor arg188226093053); +GibCursor _copy_IntSet73(GibCursor arg189126183062); +GibCursor _copy_without_ptrs_IntSet73(GibCursor arg190026273071); +unsigned char _traverse_IntSet73(GibCursor arg190926363080); +unsigned char _print_IntSet73(GibCursor arg191826433087); +GibCursor _copy_Maybe103_v1006(GibCursor arg193526603104); +GibCursor _copy_without_ptrs_Maybe103_v1006(GibCursor arg193826633107); +unsigned char _traverse_Maybe103_v1006(GibCursor arg194126663110); +unsigned char _print_Maybe103_v1006(GibCursor arg194426693113); +GibCursor _copy_Maybe103_v1013(GibCursor arg195226773121); +GibCursor _copy_without_ptrs_Maybe103_v1013(GibCursor arg195526803124); +unsigned char _traverse_Maybe103_v1013(GibCursor arg195826833127); +unsigned char _print_Maybe103_v1013(GibCursor arg196126853129); +GibCursor _copy_Map99_v1004(GibCursor arg196926933137); +GibCursor _copy_without_ptrs_Map99_v1004(GibCursor arg198027043148); +unsigned char _traverse_Map99_v1004(GibCursor arg199127153159); +unsigned char _print_Map99_v1004(GibCursor arg200227243168); +GibCursor _copy_Map99_v1005(GibCursor arg202227443188); +GibCursor _copy_without_ptrs_Map99_v1005(GibCursor arg203327553199); +unsigned char _traverse_Map99_v1005(GibCursor arg204427663210); +unsigned char _print_Map99_v1005(GibCursor arg205527743218); +typedef enum { + GibInt_T, + GibFloat_T, + GibSym_T, + GibBool_T, + GibVector_T, + GibList_T, + GibCursor_T, + Clock120_T, + IntOrSet57_T, + IntSet73_T, + Map99_v1004_T, + Map99_v1005_T, + Maybe103_v1006_T, + Maybe103_v1013_T, + Ord104_T, + Timestamp121_T, + } GibDatatype; +void info_table_initialize(void) +{ + int error = gib_info_table_initialize(16); + + if (error < 0) { + fprintf(stderr, "Couldn't initialize info table, errorno=%d", error); + exit(1); + } + + GibDatatype field_tys[3]; + + error = gib_info_table_insert_packed_dcon(Clock120_T, 0, 8, 1, 1, 0, + field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, Clock120_T, 0); + exit(1); + } + error = gib_info_table_insert_packed_dcon(IntOrSet57_T, 0, 0, 3, 0, 0, + field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, IntOrSet57_T, 0); + exit(1); + } + error = gib_info_table_insert_packed_dcon(IntSet73_T, 1, 0, 0, 0, 0, + field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, IntSet73_T, 1); + exit(1); + } + error = gib_info_table_insert_packed_dcon(IntSet73_T, 0, 16, 2, 2, 0, + field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, IntSet73_T, 0); + exit(1); + } + error = gib_info_table_insert_packed_dcon(Map99_v1004_T, 1, 16, 3, 2, 0, + field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, Map99_v1004_T, 1); + exit(1); + } + error = gib_info_table_insert_packed_dcon(Map99_v1004_T, 0, 0, 0, 0, 0, + field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, Map99_v1004_T, 0); + exit(1); + } + error = gib_info_table_insert_packed_dcon(Map99_v1005_T, 1, 24, 2, 3, 0, + field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, Map99_v1005_T, 1); + exit(1); + } + error = gib_info_table_insert_packed_dcon(Map99_v1005_T, 0, 0, 0, 0, 0, + field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, Map99_v1005_T, 0); + exit(1); + } + error = gib_info_table_insert_packed_dcon(Maybe103_v1006_T, 1, 0, 1, 0, 0, + field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, Maybe103_v1006_T, 1); + exit(1); + } + error = gib_info_table_insert_packed_dcon(Maybe103_v1006_T, 0, 0, 0, 0, 0, + field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, Maybe103_v1006_T, 0); + exit(1); + } + error = gib_info_table_insert_packed_dcon(Maybe103_v1013_T, 1, 8, 0, 1, 0, + field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, Maybe103_v1013_T, 1); + exit(1); + } + error = gib_info_table_insert_packed_dcon(Maybe103_v1013_T, 0, 0, 0, 0, 0, + field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, Maybe103_v1013_T, 0); + exit(1); + } + error = gib_info_table_insert_packed_dcon(Ord104_T, 3, 0, 0, 0, 0, + field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, Ord104_T, 3); + exit(1); + } + error = gib_info_table_insert_packed_dcon(Ord104_T, 2, 0, 0, 0, 0, + field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, Ord104_T, 2); + exit(1); + } + error = gib_info_table_insert_packed_dcon(Ord104_T, 1, 0, 0, 0, 0, + field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, Ord104_T, 1); + exit(1); + } + error = gib_info_table_insert_packed_dcon(Ord104_T, 0, 0, 0, 0, 0, + field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, Ord104_T, 0); + exit(1); + } + error = gib_info_table_insert_packed_dcon(Timestamp121_T, 0, 8, 1, 1, 0, + field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, Timestamp121_T, 0); + exit(1); + } + gib_info_table_finalize(); +} +void symbol_table_initialize(void) +{ + gib_add_symbol(3238, ")"); + gib_add_symbol(3239, "(Tip100_v1005"); + gib_add_symbol(3240, "(Tip100_v1004"); + gib_add_symbol(3241, "(Timestamp122"); + gib_add_symbol(3242, "(PureSet74"); + gib_add_symbol(3243, "(OrSet58"); + gib_add_symbol(3244, "(Nothing109_v1013"); + gib_add_symbol(3245, "(Nothing109_v1006"); + gib_add_symbol(3246, "(Lt105"); + gib_add_symbol(3247, "(Just110_v1013"); + gib_add_symbol(3248, "(Just110_v1006"); + gib_add_symbol(3249, "(Gt106"); + gib_add_symbol(3250, "(Eq107"); + gib_add_symbol(3251, "(EmptySet75"); + gib_add_symbol(3252, "(Clk123"); + gib_add_symbol(3253, "(Cc108"); + gib_add_symbol(3254, "(Bin101_v1005"); + gib_add_symbol(3255, "(Bin101_v1004"); + gib_add_symbol(3256, " "); +} +GibCursor _copy_IntOrSet57(GibCursor arg179825272971) +{ + GibInt tag3257 = + ((GibIntGibCursorGibCursorGibCursorProd *) arg179825272971)->field0; + GibCursor x179925282972 = + ((GibIntGibCursorGibCursorGibCursorProd *) arg179825272971)->field1; + GibCursor x180025292973 = + ((GibIntGibCursorGibCursorGibCursorProd *) arg179825272971)->field2; + GibCursor x180125302974 = + ((GibIntGibCursorGibCursorGibCursorProd *) arg179825272971)->field3; + GibCursor y180225312975 = _copy_Clock120(x179925282972); + GibCursor y180325322976 = _copy_Map99_v1004(x180025292973); + GibCursor y180425332977 = _copy_IntSet73(x180125302974); + GibPtr tailift3258 = + gib_alloc(sizeof(GibIntGibCursorGibCursorGibCursorProd)); + + ((GibIntGibCursorGibCursorGibCursorProd *) tailift3258)->field0 = 0; + ((GibIntGibCursorGibCursorGibCursorProd *) tailift3258)->field1 = + y180225312975; + ((GibIntGibCursorGibCursorGibCursorProd *) tailift3258)->field2 = + y180325322976; + ((GibIntGibCursorGibCursorGibCursorProd *) tailift3258)->field3 = + y180425332977; + return tailift3258; +} +GibCursor _copy_without_ptrs_IntOrSet57(GibCursor arg180525342978) +{ + GibInt tag3259 = + ((GibIntGibCursorGibCursorGibCursorProd *) arg180525342978)->field0; + GibCursor x180625352979 = + ((GibIntGibCursorGibCursorGibCursorProd *) arg180525342978)->field1; + GibCursor x180725362980 = + ((GibIntGibCursorGibCursorGibCursorProd *) arg180525342978)->field2; + GibCursor x180825372981 = + ((GibIntGibCursorGibCursorGibCursorProd *) arg180525342978)->field3; + GibCursor y180925382982 = _copy_without_ptrs_Clock120(x180625352979); + GibCursor y181025392983 = _copy_without_ptrs_Map99_v1004(x180725362980); + GibCursor y181125402984 = _copy_without_ptrs_IntSet73(x180825372981); + GibPtr tailift3260 = + gib_alloc(sizeof(GibIntGibCursorGibCursorGibCursorProd)); + + ((GibIntGibCursorGibCursorGibCursorProd *) tailift3260)->field0 = 0; + ((GibIntGibCursorGibCursorGibCursorProd *) tailift3260)->field1 = + y180925382982; + ((GibIntGibCursorGibCursorGibCursorProd *) tailift3260)->field2 = + y181025392983; + ((GibIntGibCursorGibCursorGibCursorProd *) tailift3260)->field3 = + y181125402984; + return tailift3260; +} +unsigned char _traverse_IntOrSet57(GibCursor arg181225412985) +{ + GibInt tag3261 = + ((GibIntGibCursorGibCursorGibCursorProd *) arg181225412985)->field0; + GibCursor x181325422986 = + ((GibIntGibCursorGibCursorGibCursorProd *) arg181225412985)->field1; + GibCursor x181425432987 = + ((GibIntGibCursorGibCursorGibCursorProd *) arg181225412985)->field2; + GibCursor x181525442988 = + ((GibIntGibCursorGibCursorGibCursorProd *) arg181225412985)->field3; + unsigned char y181625452989 = _traverse_Clock120(x181325422986); + unsigned char y181725462990 = _traverse_Map99_v1004(x181425432987); + unsigned char y181825472991 = _traverse_IntSet73(x181525442988); + + return 0; +} +unsigned char _print_IntOrSet57(GibCursor arg181925482992) +{ + GibInt tag3262 = + ((GibIntGibCursorGibCursorGibCursorProd *) arg181925482992)->field0; + GibCursor x182025492993 = + ((GibIntGibCursorGibCursorGibCursorProd *) arg181925482992)->field1; + GibCursor x182125502994 = + ((GibIntGibCursorGibCursorGibCursorProd *) arg181925482992)->field2; + GibCursor x182225512995 = + ((GibIntGibCursorGibCursorGibCursorProd *) arg181925482992)->field3; + unsigned char wildcard182625522996 = gib_print_symbol(3243); + unsigned char wildcard183025532997 = gib_print_symbol(3256); + unsigned char y182325542998 = _print_Clock120(x182025492993); + unsigned char wildcard182925552999 = gib_print_symbol(3256); + unsigned char y182425563000 = _print_Map99_v1004(x182125502994); + unsigned char wildcard182825573001 = gib_print_symbol(3256); + unsigned char y182525583002 = _print_IntSet73(x182225512995); + unsigned char wildcard182725593003 = gib_print_symbol(3238); + + return 0; +} +GibCursor _copy_Clock120(GibCursor arg183125603004) +{ + GibInt tag3263 = ((GibIntGibIntGibCursorProd *) arg183125603004)->field0; + GibInt x183225613005 = + ((GibIntGibIntGibCursorProd *) arg183125603004)->field1; + GibCursor x183325623006 = + ((GibIntGibIntGibCursorProd *) arg183125603004)->field2; + GibCursor y183525643008 = _copy_Map99_v1005(x183325623006); + GibPtr tailift3264 = gib_alloc(sizeof(GibIntGibIntGibCursorProd)); + + ((GibIntGibIntGibCursorProd *) tailift3264)->field0 = 0; + ((GibIntGibIntGibCursorProd *) tailift3264)->field1 = x183225613005; + ((GibIntGibIntGibCursorProd *) tailift3264)->field2 = y183525643008; + return tailift3264; +} +GibCursor _copy_without_ptrs_Clock120(GibCursor arg183625653009) +{ + GibInt tag3265 = ((GibIntGibIntGibCursorProd *) arg183625653009)->field0; + GibInt x183725663010 = + ((GibIntGibIntGibCursorProd *) arg183625653009)->field1; + GibCursor x183825673011 = + ((GibIntGibIntGibCursorProd *) arg183625653009)->field2; + GibCursor y184025693013 = _copy_without_ptrs_Map99_v1005(x183825673011); + GibPtr tailift3266 = gib_alloc(sizeof(GibIntGibIntGibCursorProd)); + + ((GibIntGibIntGibCursorProd *) tailift3266)->field0 = 0; + ((GibIntGibIntGibCursorProd *) tailift3266)->field1 = x183725663010; + ((GibIntGibIntGibCursorProd *) tailift3266)->field2 = y184025693013; + return tailift3266; +} +unsigned char _traverse_Clock120(GibCursor arg184125703014) +{ + GibInt tag3267 = ((GibIntGibIntGibCursorProd *) arg184125703014)->field0; + GibInt x184225713015 = + ((GibIntGibIntGibCursorProd *) arg184125703014)->field1; + GibCursor x184325723016 = + ((GibIntGibIntGibCursorProd *) arg184125703014)->field2; + unsigned char y184525733017 = _traverse_Map99_v1005(x184325723016); + + return 0; +} +unsigned char _print_Clock120(GibCursor arg184625743018) +{ + GibInt tag3268 = ((GibIntGibIntGibCursorProd *) arg184625743018)->field0; + GibInt x184725753019 = + ((GibIntGibIntGibCursorProd *) arg184625743018)->field1; + GibCursor x184825763020 = + ((GibIntGibIntGibCursorProd *) arg184625743018)->field2; + unsigned char wildcard185125773021 = gib_print_symbol(3252); + unsigned char wildcard185425783022 = gib_print_symbol(3256); + unsigned char y184925793023 = printf("%ld", x184725753019); + unsigned char wildcard185325803024 = gib_print_symbol(3256); + unsigned char y185025813025 = _print_Map99_v1005(x184825763020); + unsigned char wildcard185225823026 = gib_print_symbol(3238); + + return 0; +} +GibCursor _copy_Timestamp121(GibCursor arg185525833027) +{ + GibInt tag3269 = ((GibIntGibIntGibCursorProd *) arg185525833027)->field0; + GibInt x185625843028 = + ((GibIntGibIntGibCursorProd *) arg185525833027)->field1; + GibCursor x185725853029 = + ((GibIntGibIntGibCursorProd *) arg185525833027)->field2; + GibCursor y185925873031 = _copy_Clock120(x185725853029); + GibPtr tailift3270 = gib_alloc(sizeof(GibIntGibIntGibCursorProd)); + + ((GibIntGibIntGibCursorProd *) tailift3270)->field0 = 0; + ((GibIntGibIntGibCursorProd *) tailift3270)->field1 = x185625843028; + ((GibIntGibIntGibCursorProd *) tailift3270)->field2 = y185925873031; + return tailift3270; +} +GibCursor _copy_without_ptrs_Timestamp121(GibCursor arg186025883032) +{ + GibInt tag3271 = ((GibIntGibIntGibCursorProd *) arg186025883032)->field0; + GibInt x186125893033 = + ((GibIntGibIntGibCursorProd *) arg186025883032)->field1; + GibCursor x186225903034 = + ((GibIntGibIntGibCursorProd *) arg186025883032)->field2; + GibCursor y186425923036 = _copy_without_ptrs_Clock120(x186225903034); + GibPtr tailift3272 = gib_alloc(sizeof(GibIntGibIntGibCursorProd)); + + ((GibIntGibIntGibCursorProd *) tailift3272)->field0 = 0; + ((GibIntGibIntGibCursorProd *) tailift3272)->field1 = x186125893033; + ((GibIntGibIntGibCursorProd *) tailift3272)->field2 = y186425923036; + return tailift3272; +} +unsigned char _traverse_Timestamp121(GibCursor arg186525933037) +{ + GibInt tag3273 = ((GibIntGibIntGibCursorProd *) arg186525933037)->field0; + GibInt x186625943038 = + ((GibIntGibIntGibCursorProd *) arg186525933037)->field1; + GibCursor x186725953039 = + ((GibIntGibIntGibCursorProd *) arg186525933037)->field2; + unsigned char y186925963040 = _traverse_Clock120(x186725953039); + + return 0; +} +unsigned char _print_Timestamp121(GibCursor arg187025973041) +{ + GibInt tag3274 = ((GibIntGibIntGibCursorProd *) arg187025973041)->field0; + GibInt x187125983042 = + ((GibIntGibIntGibCursorProd *) arg187025973041)->field1; + GibCursor x187225993043 = + ((GibIntGibIntGibCursorProd *) arg187025973041)->field2; + unsigned char wildcard187526003044 = gib_print_symbol(3241); + unsigned char wildcard187826013045 = gib_print_symbol(3256); + unsigned char y187326023046 = printf("%ld", x187125983042); + unsigned char wildcard187726033047 = gib_print_symbol(3256); + unsigned char y187426043048 = _print_Clock120(x187225993043); + unsigned char wildcard187626053049 = gib_print_symbol(3238); + + return 0; +} +GibCursor _copy_Ord104(GibCursor arg187926063050) +{ + GibPackedTag tag3275 = *(GibPackedTag *) arg187926063050; + GibCursor tail3276 = arg187926063050 + sizeof(GibInt); + + + switch3281: + ; + switch (tag3275) { + + case 0: + { + GibPtr tailift3277 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift3277)->field0 = 0; + return tailift3277; + break; + } + + case 1: + { + GibPtr tailift3278 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift3278)->field0 = 1; + return tailift3278; + break; + } + + case 2: + { + GibPtr tailift3279 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift3279)->field0 = 2; + return tailift3279; + break; + } + + case 3: + { + GibPtr tailift3280 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift3280)->field0 = 3; + return tailift3280; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag3275"); + exit(1); + } + } +} +GibCursor _copy_without_ptrs_Ord104(GibCursor arg188026073051) +{ + GibPackedTag tag3282 = *(GibPackedTag *) arg188026073051; + GibCursor tail3283 = arg188026073051 + sizeof(GibInt); + + + switch3288: + ; + switch (tag3282) { + + case 0: + { + GibPtr tailift3284 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift3284)->field0 = 0; + return tailift3284; + break; + } + + case 1: + { + GibPtr tailift3285 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift3285)->field0 = 1; + return tailift3285; + break; + } + + case 2: + { + GibPtr tailift3286 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift3286)->field0 = 2; + return tailift3286; + break; + } + + case 3: + { + GibPtr tailift3287 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift3287)->field0 = 3; + return tailift3287; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag3282"); + exit(1); + } + } +} +unsigned char _traverse_Ord104(GibCursor arg188126083052) +{ + GibPackedTag tag3289 = *(GibPackedTag *) arg188126083052; + GibCursor tail3290 = arg188126083052 + sizeof(GibInt); + + + switch3291: + ; + switch (tag3289) { + + case 0: + { + return 0; + break; + } + + case 1: + { + return 0; + break; + } + + case 2: + { + return 0; + break; + } + + case 3: + { + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag3289"); + exit(1); + } + } +} +unsigned char _print_Ord104(GibCursor arg188226093053) +{ + GibPackedTag tag3292 = *(GibPackedTag *) arg188226093053; + GibCursor tail3293 = arg188226093053 + sizeof(GibInt); + + + switch3294: + ; + switch (tag3292) { + + case 0: + { + unsigned char wildcard188326103054 = gib_print_symbol(3246); + unsigned char wildcard188426113055 = gib_print_symbol(3238); + + return 0; + break; + } + + case 1: + { + unsigned char wildcard188526123056 = gib_print_symbol(3249); + unsigned char wildcard188626133057 = gib_print_symbol(3238); + + return 0; + break; + } + + case 2: + { + unsigned char wildcard188726143058 = gib_print_symbol(3250); + unsigned char wildcard188826153059 = gib_print_symbol(3238); + + return 0; + break; + } + + case 3: + { + unsigned char wildcard188926163060 = gib_print_symbol(3253); + unsigned char wildcard189026173061 = gib_print_symbol(3238); + + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag3292"); + exit(1); + } + } +} +GibCursor _copy_IntSet73(GibCursor arg189126183062) +{ + GibPackedTag tag3295 = *(GibPackedTag *) arg189126183062; + GibCursor tail3296 = arg189126183062 + sizeof(GibInt); + + + switch3299: + ; + switch (tag3295) { + + case 0: + { + GibInt x189226193063 = + ((GibIntGibIntGibCursorGibCursorProd *) tail3296)->field0; + GibInt x189326203064 = + ((GibIntGibIntGibCursorGibCursorProd *) tail3296)->field1; + GibCursor x189426213065 = + ((GibIntGibIntGibCursorGibCursorProd *) tail3296)->field2; + GibCursor x189526223066 = + ((GibIntGibIntGibCursorGibCursorProd *) tail3296)->field3; + GibCursor y189826253069 = _copy_IntSet73(x189426213065); + GibCursor y189926263070 = _copy_IntSet73(x189526223066); + GibPtr tailift3297 = + gib_alloc(sizeof(GibIntGibIntGibIntGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift3297)->field0 = + 0; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift3297)->field1 = + x189226193063; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift3297)->field2 = + x189326203064; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift3297)->field3 = + y189826253069; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift3297)->field4 = + y189926263070; + return tailift3297; + break; + } + + case 1: + { + GibPtr tailift3298 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift3298)->field0 = 1; + return tailift3298; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag3295"); + exit(1); + } + } +} +GibCursor _copy_without_ptrs_IntSet73(GibCursor arg190026273071) +{ + GibPackedTag tag3300 = *(GibPackedTag *) arg190026273071; + GibCursor tail3301 = arg190026273071 + sizeof(GibInt); + + + switch3304: + ; + switch (tag3300) { + + case 0: + { + GibInt x190126283072 = + ((GibIntGibIntGibCursorGibCursorProd *) tail3301)->field0; + GibInt x190226293073 = + ((GibIntGibIntGibCursorGibCursorProd *) tail3301)->field1; + GibCursor x190326303074 = + ((GibIntGibIntGibCursorGibCursorProd *) tail3301)->field2; + GibCursor x190426313075 = + ((GibIntGibIntGibCursorGibCursorProd *) tail3301)->field3; + GibCursor y190726343078 = + _copy_without_ptrs_IntSet73(x190326303074); + GibCursor y190826353079 = + _copy_without_ptrs_IntSet73(x190426313075); + GibPtr tailift3302 = + gib_alloc(sizeof(GibIntGibIntGibIntGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift3302)->field0 = + 0; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift3302)->field1 = + x190126283072; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift3302)->field2 = + x190226293073; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift3302)->field3 = + y190726343078; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift3302)->field4 = + y190826353079; + return tailift3302; + break; + } + + case 1: + { + GibPtr tailift3303 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift3303)->field0 = 1; + return tailift3303; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag3300"); + exit(1); + } + } +} +unsigned char _traverse_IntSet73(GibCursor arg190926363080) +{ + GibPackedTag tag3305 = *(GibPackedTag *) arg190926363080; + GibCursor tail3306 = arg190926363080 + sizeof(GibInt); + + + switch3307: + ; + switch (tag3305) { + + case 0: + { + GibInt x191026373081 = + ((GibIntGibIntGibCursorGibCursorProd *) tail3306)->field0; + GibInt x191126383082 = + ((GibIntGibIntGibCursorGibCursorProd *) tail3306)->field1; + GibCursor x191226393083 = + ((GibIntGibIntGibCursorGibCursorProd *) tail3306)->field2; + GibCursor x191326403084 = + ((GibIntGibIntGibCursorGibCursorProd *) tail3306)->field3; + unsigned char y191626413085 = _traverse_IntSet73(x191226393083); + unsigned char y191726423086 = _traverse_IntSet73(x191326403084); + + return 0; + break; + } + + case 1: + { + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag3305"); + exit(1); + } + } +} +unsigned char _print_IntSet73(GibCursor arg191826433087) +{ + GibPackedTag tag3308 = *(GibPackedTag *) arg191826433087; + GibCursor tail3309 = arg191826433087 + sizeof(GibInt); + + + switch3310: + ; + switch (tag3308) { + + case 0: + { + GibInt x191926443088 = + ((GibIntGibIntGibCursorGibCursorProd *) tail3309)->field0; + GibInt x192026453089 = + ((GibIntGibIntGibCursorGibCursorProd *) tail3309)->field1; + GibCursor x192126463090 = + ((GibIntGibIntGibCursorGibCursorProd *) tail3309)->field2; + GibCursor x192226473091 = + ((GibIntGibIntGibCursorGibCursorProd *) tail3309)->field3; + unsigned char wildcard192726483092 = gib_print_symbol(3242); + unsigned char wildcard193226493093 = gib_print_symbol(3256); + unsigned char y192326503094 = printf("%ld", x191926443088); + unsigned char wildcard193126513095 = gib_print_symbol(3256); + unsigned char y192426523096 = printf("%ld", x192026453089); + unsigned char wildcard193026533097 = gib_print_symbol(3256); + unsigned char y192526543098 = _print_IntSet73(x192126463090); + unsigned char wildcard192926553099 = gib_print_symbol(3256); + unsigned char y192626563100 = _print_IntSet73(x192226473091); + unsigned char wildcard192826573101 = gib_print_symbol(3238); + + return 0; + break; + } + + case 1: + { + unsigned char wildcard193326583102 = gib_print_symbol(3251); + unsigned char wildcard193426593103 = gib_print_symbol(3238); + + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag3308"); + exit(1); + } + } +} +GibCursor _copy_Maybe103_v1006(GibCursor arg193526603104) +{ + GibPackedTag tag3311 = *(GibPackedTag *) arg193526603104; + GibCursor tail3312 = arg193526603104 + sizeof(GibInt); + + + switch3315: + ; + switch (tag3311) { + + case 0: + { + GibPtr tailift3313 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift3313)->field0 = 0; + return tailift3313; + break; + } + + case 1: + { + GibCursor x193626613105 = ((GibCursorProd *) tail3312)->field0; + GibCursor y193726623106 = _copy_Timestamp121(x193626613105); + GibPtr tailift3314 = gib_alloc(sizeof(GibIntGibCursorProd)); + + ((GibIntGibCursorProd *) tailift3314)->field0 = 1; + ((GibIntGibCursorProd *) tailift3314)->field1 = y193726623106; + return tailift3314; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag3311"); + exit(1); + } + } +} +GibCursor _copy_without_ptrs_Maybe103_v1006(GibCursor arg193826633107) +{ + GibPackedTag tag3316 = *(GibPackedTag *) arg193826633107; + GibCursor tail3317 = arg193826633107 + sizeof(GibInt); + + + switch3320: + ; + switch (tag3316) { + + case 0: + { + GibPtr tailift3318 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift3318)->field0 = 0; + return tailift3318; + break; + } + + case 1: + { + GibCursor x193926643108 = ((GibCursorProd *) tail3317)->field0; + GibCursor y194026653109 = + _copy_without_ptrs_Timestamp121(x193926643108); + GibPtr tailift3319 = gib_alloc(sizeof(GibIntGibCursorProd)); + + ((GibIntGibCursorProd *) tailift3319)->field0 = 1; + ((GibIntGibCursorProd *) tailift3319)->field1 = y194026653109; + return tailift3319; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag3316"); + exit(1); + } + } +} +unsigned char _traverse_Maybe103_v1006(GibCursor arg194126663110) +{ + GibPackedTag tag3321 = *(GibPackedTag *) arg194126663110; + GibCursor tail3322 = arg194126663110 + sizeof(GibInt); + + + switch3323: + ; + switch (tag3321) { + + case 0: + { + return 0; + break; + } + + case 1: + { + GibCursor x194226673111 = ((GibCursorProd *) tail3322)->field0; + unsigned char y194326683112 = + _traverse_Timestamp121(x194226673111); + + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag3321"); + exit(1); + } + } +} +unsigned char _print_Maybe103_v1006(GibCursor arg194426693113) +{ + GibPackedTag tag3324 = *(GibPackedTag *) arg194426693113; + GibCursor tail3325 = arg194426693113 + sizeof(GibInt); + + + switch3326: + ; + switch (tag3324) { + + case 0: + { + unsigned char wildcard194526703114 = gib_print_symbol(3245); + unsigned char wildcard194626713115 = gib_print_symbol(3238); + + return 0; + break; + } + + case 1: + { + GibCursor x194726723116 = ((GibCursorProd *) tail3325)->field0; + unsigned char wildcard194926733117 = gib_print_symbol(3248); + unsigned char wildcard195126743118 = gib_print_symbol(3256); + unsigned char y194826753119 = _print_Timestamp121(x194726723116); + unsigned char wildcard195026763120 = gib_print_symbol(3238); + + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag3324"); + exit(1); + } + } +} +GibCursor _copy_Maybe103_v1013(GibCursor arg195226773121) +{ + GibPackedTag tag3327 = *(GibPackedTag *) arg195226773121; + GibCursor tail3328 = arg195226773121 + sizeof(GibInt); + + + switch3331: + ; + switch (tag3327) { + + case 0: + { + GibPtr tailift3329 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift3329)->field0 = 0; + return tailift3329; + break; + } + + case 1: + { + GibInt x195326783122 = ((GibIntProd *) tail3328)->field0; + GibPtr tailift3330 = gib_alloc(sizeof(GibIntGibIntProd)); + + ((GibIntGibIntProd *) tailift3330)->field0 = 1; + ((GibIntGibIntProd *) tailift3330)->field1 = x195326783122; + return tailift3330; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag3327"); + exit(1); + } + } +} +GibCursor _copy_without_ptrs_Maybe103_v1013(GibCursor arg195526803124) +{ + GibPackedTag tag3332 = *(GibPackedTag *) arg195526803124; + GibCursor tail3333 = arg195526803124 + sizeof(GibInt); + + + switch3336: + ; + switch (tag3332) { + + case 0: + { + GibPtr tailift3334 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift3334)->field0 = 0; + return tailift3334; + break; + } + + case 1: + { + GibInt x195626813125 = ((GibIntProd *) tail3333)->field0; + GibPtr tailift3335 = gib_alloc(sizeof(GibIntGibIntProd)); + + ((GibIntGibIntProd *) tailift3335)->field0 = 1; + ((GibIntGibIntProd *) tailift3335)->field1 = x195626813125; + return tailift3335; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag3332"); + exit(1); + } + } +} +unsigned char _traverse_Maybe103_v1013(GibCursor arg195826833127) +{ + GibPackedTag tag3337 = *(GibPackedTag *) arg195826833127; + GibCursor tail3338 = arg195826833127 + sizeof(GibInt); + + + switch3339: + ; + switch (tag3337) { + + case 0: + { + return 0; + break; + } + + case 1: + { + GibInt x195926843128 = ((GibIntProd *) tail3338)->field0; + + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag3337"); + exit(1); + } + } +} +unsigned char _print_Maybe103_v1013(GibCursor arg196126853129) +{ + GibPackedTag tag3340 = *(GibPackedTag *) arg196126853129; + GibCursor tail3341 = arg196126853129 + sizeof(GibInt); + + + switch3342: + ; + switch (tag3340) { + + case 0: + { + unsigned char wildcard196226863130 = gib_print_symbol(3244); + unsigned char wildcard196326873131 = gib_print_symbol(3238); + + return 0; + break; + } + + case 1: + { + GibInt x196426883132 = ((GibIntProd *) tail3341)->field0; + unsigned char wildcard196626893133 = gib_print_symbol(3247); + unsigned char wildcard196826903134 = gib_print_symbol(3256); + unsigned char y196526913135 = printf("%ld", x196426883132); + unsigned char wildcard196726923136 = gib_print_symbol(3238); + + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag3340"); + exit(1); + } + } +} +GibCursor _copy_Map99_v1004(GibCursor arg196926933137) +{ + GibPackedTag tag3343 = *(GibPackedTag *) arg196926933137; + GibCursor tail3344 = arg196926933137 + sizeof(GibInt); + + + switch3347: + ; + switch (tag3343) { + + case 0: + { + GibPtr tailift3345 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift3345)->field0 = 0; + return tailift3345; + break; + } + + case 1: + { + GibInt x197026943138 = + ((GibIntGibIntGibCursorGibCursorGibCursorProd *) tail3344)->field0; + GibInt x197126953139 = + ((GibIntGibIntGibCursorGibCursorGibCursorProd *) tail3344)->field1; + GibCursor x197226963140 = + ((GibIntGibIntGibCursorGibCursorGibCursorProd *) tail3344)->field2; + GibCursor x197326973141 = + ((GibIntGibIntGibCursorGibCursorGibCursorProd *) tail3344)->field3; + GibCursor x197426983142 = + ((GibIntGibIntGibCursorGibCursorGibCursorProd *) tail3344)->field4; + GibCursor y197727013145 = _copy_Timestamp121(x197226963140); + GibCursor y197827023146 = _copy_Map99_v1004(x197326973141); + GibCursor y197927033147 = _copy_Map99_v1004(x197426983142); + GibPtr tailift3346 = + gib_alloc(sizeof(GibIntGibIntGibIntGibCursorGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibCursorGibCursorGibCursorProd *) tailift3346)->field0 = + 1; + ((GibIntGibIntGibIntGibCursorGibCursorGibCursorProd *) tailift3346)->field1 = + x197026943138; + ((GibIntGibIntGibIntGibCursorGibCursorGibCursorProd *) tailift3346)->field2 = + x197126953139; + ((GibIntGibIntGibIntGibCursorGibCursorGibCursorProd *) tailift3346)->field3 = + y197727013145; + ((GibIntGibIntGibIntGibCursorGibCursorGibCursorProd *) tailift3346)->field4 = + y197827023146; + ((GibIntGibIntGibIntGibCursorGibCursorGibCursorProd *) tailift3346)->field5 = + y197927033147; + return tailift3346; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag3343"); + exit(1); + } + } +} +GibCursor _copy_without_ptrs_Map99_v1004(GibCursor arg198027043148) +{ + GibPackedTag tag3348 = *(GibPackedTag *) arg198027043148; + GibCursor tail3349 = arg198027043148 + sizeof(GibInt); + + + switch3352: + ; + switch (tag3348) { + + case 0: + { + GibPtr tailift3350 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift3350)->field0 = 0; + return tailift3350; + break; + } + + case 1: + { + GibInt x198127053149 = + ((GibIntGibIntGibCursorGibCursorGibCursorProd *) tail3349)->field0; + GibInt x198227063150 = + ((GibIntGibIntGibCursorGibCursorGibCursorProd *) tail3349)->field1; + GibCursor x198327073151 = + ((GibIntGibIntGibCursorGibCursorGibCursorProd *) tail3349)->field2; + GibCursor x198427083152 = + ((GibIntGibIntGibCursorGibCursorGibCursorProd *) tail3349)->field3; + GibCursor x198527093153 = + ((GibIntGibIntGibCursorGibCursorGibCursorProd *) tail3349)->field4; + GibCursor y198827123156 = + _copy_without_ptrs_Timestamp121(x198327073151); + GibCursor y198927133157 = + _copy_without_ptrs_Map99_v1004(x198427083152); + GibCursor y199027143158 = + _copy_without_ptrs_Map99_v1004(x198527093153); + GibPtr tailift3351 = + gib_alloc(sizeof(GibIntGibIntGibIntGibCursorGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibCursorGibCursorGibCursorProd *) tailift3351)->field0 = + 1; + ((GibIntGibIntGibIntGibCursorGibCursorGibCursorProd *) tailift3351)->field1 = + x198127053149; + ((GibIntGibIntGibIntGibCursorGibCursorGibCursorProd *) tailift3351)->field2 = + x198227063150; + ((GibIntGibIntGibIntGibCursorGibCursorGibCursorProd *) tailift3351)->field3 = + y198827123156; + ((GibIntGibIntGibIntGibCursorGibCursorGibCursorProd *) tailift3351)->field4 = + y198927133157; + ((GibIntGibIntGibIntGibCursorGibCursorGibCursorProd *) tailift3351)->field5 = + y199027143158; + return tailift3351; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag3348"); + exit(1); + } + } +} +unsigned char _traverse_Map99_v1004(GibCursor arg199127153159) +{ + GibPackedTag tag3353 = *(GibPackedTag *) arg199127153159; + GibCursor tail3354 = arg199127153159 + sizeof(GibInt); + + + switch3355: + ; + switch (tag3353) { + + case 0: + { + return 0; + break; + } + + case 1: + { + GibInt x199227163160 = + ((GibIntGibIntGibCursorGibCursorGibCursorProd *) tail3354)->field0; + GibInt x199327173161 = + ((GibIntGibIntGibCursorGibCursorGibCursorProd *) tail3354)->field1; + GibCursor x199427183162 = + ((GibIntGibIntGibCursorGibCursorGibCursorProd *) tail3354)->field2; + GibCursor x199527193163 = + ((GibIntGibIntGibCursorGibCursorGibCursorProd *) tail3354)->field3; + GibCursor x199627203164 = + ((GibIntGibIntGibCursorGibCursorGibCursorProd *) tail3354)->field4; + unsigned char y199927213165 = + _traverse_Timestamp121(x199427183162); + unsigned char y200027223166 = _traverse_Map99_v1004(x199527193163); + unsigned char y200127233167 = _traverse_Map99_v1004(x199627203164); + + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag3353"); + exit(1); + } + } +} +unsigned char _print_Map99_v1004(GibCursor arg200227243168) +{ + GibPackedTag tag3356 = *(GibPackedTag *) arg200227243168; + GibCursor tail3357 = arg200227243168 + sizeof(GibInt); + + + switch3358: + ; + switch (tag3356) { + + case 0: + { + unsigned char wildcard200327253169 = gib_print_symbol(3240); + unsigned char wildcard200427263170 = gib_print_symbol(3238); + + return 0; + break; + } + + case 1: + { + GibInt x200527273171 = + ((GibIntGibIntGibCursorGibCursorGibCursorProd *) tail3357)->field0; + GibInt x200627283172 = + ((GibIntGibIntGibCursorGibCursorGibCursorProd *) tail3357)->field1; + GibCursor x200727293173 = + ((GibIntGibIntGibCursorGibCursorGibCursorProd *) tail3357)->field2; + GibCursor x200827303174 = + ((GibIntGibIntGibCursorGibCursorGibCursorProd *) tail3357)->field3; + GibCursor x200927313175 = + ((GibIntGibIntGibCursorGibCursorGibCursorProd *) tail3357)->field4; + unsigned char wildcard201527323176 = gib_print_symbol(3255); + unsigned char wildcard202127333177 = gib_print_symbol(3256); + unsigned char y201027343178 = printf("%ld", x200527273171); + unsigned char wildcard202027353179 = gib_print_symbol(3256); + unsigned char y201127363180 = printf("%ld", x200627283172); + unsigned char wildcard201927373181 = gib_print_symbol(3256); + unsigned char y201227383182 = _print_Timestamp121(x200727293173); + unsigned char wildcard201827393183 = gib_print_symbol(3256); + unsigned char y201327403184 = _print_Map99_v1004(x200827303174); + unsigned char wildcard201727413185 = gib_print_symbol(3256); + unsigned char y201427423186 = _print_Map99_v1004(x200927313175); + unsigned char wildcard201627433187 = gib_print_symbol(3238); + + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag3356"); + exit(1); + } + } +} +GibCursor _copy_Map99_v1005(GibCursor arg202227443188) +{ + GibPackedTag tag3359 = *(GibPackedTag *) arg202227443188; + GibCursor tail3360 = arg202227443188 + sizeof(GibInt); + + + switch3363: + ; + switch (tag3359) { + + case 0: + { + GibPtr tailift3361 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift3361)->field0 = 0; + return tailift3361; + break; + } + + case 1: + { + GibInt x202327453189 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3360)->field0; + GibInt x202427463190 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3360)->field1; + GibInt x202527473191 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3360)->field2; + GibCursor x202627483192 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3360)->field3; + GibCursor x202727493193 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3360)->field4; + GibCursor y203127533197 = _copy_Map99_v1005(x202627483192); + GibCursor y203227543198 = _copy_Map99_v1005(x202727493193); + GibPtr tailift3362 = + gib_alloc(sizeof(GibIntGibIntGibIntGibIntGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift3362)->field0 = + 1; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift3362)->field1 = + x202327453189; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift3362)->field2 = + x202427463190; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift3362)->field3 = + x202527473191; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift3362)->field4 = + y203127533197; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift3362)->field5 = + y203227543198; + return tailift3362; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag3359"); + exit(1); + } + } +} +GibCursor _copy_without_ptrs_Map99_v1005(GibCursor arg203327553199) +{ + GibPackedTag tag3364 = *(GibPackedTag *) arg203327553199; + GibCursor tail3365 = arg203327553199 + sizeof(GibInt); + + + switch3368: + ; + switch (tag3364) { + + case 0: + { + GibPtr tailift3366 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift3366)->field0 = 0; + return tailift3366; + break; + } + + case 1: + { + GibInt x203427563200 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3365)->field0; + GibInt x203527573201 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3365)->field1; + GibInt x203627583202 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3365)->field2; + GibCursor x203727593203 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3365)->field3; + GibCursor x203827603204 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3365)->field4; + GibCursor y204227643208 = + _copy_without_ptrs_Map99_v1005(x203727593203); + GibCursor y204327653209 = + _copy_without_ptrs_Map99_v1005(x203827603204); + GibPtr tailift3367 = + gib_alloc(sizeof(GibIntGibIntGibIntGibIntGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift3367)->field0 = + 1; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift3367)->field1 = + x203427563200; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift3367)->field2 = + x203527573201; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift3367)->field3 = + x203627583202; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift3367)->field4 = + y204227643208; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift3367)->field5 = + y204327653209; + return tailift3367; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag3364"); + exit(1); + } + } +} +unsigned char _traverse_Map99_v1005(GibCursor arg204427663210) +{ + GibPackedTag tag3369 = *(GibPackedTag *) arg204427663210; + GibCursor tail3370 = arg204427663210 + sizeof(GibInt); + + + switch3371: + ; + switch (tag3369) { + + case 0: + { + return 0; + break; + } + + case 1: + { + GibInt x204527673211 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3370)->field0; + GibInt x204627683212 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3370)->field1; + GibInt x204727693213 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3370)->field2; + GibCursor x204827703214 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3370)->field3; + GibCursor x204927713215 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3370)->field4; + unsigned char y205327723216 = _traverse_Map99_v1005(x204827703214); + unsigned char y205427733217 = _traverse_Map99_v1005(x204927713215); + + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag3369"); + exit(1); + } + } +} +unsigned char _print_Map99_v1005(GibCursor arg205527743218) +{ + GibPackedTag tag3372 = *(GibPackedTag *) arg205527743218; + GibCursor tail3373 = arg205527743218 + sizeof(GibInt); + + + switch3374: + ; + switch (tag3372) { + + case 0: + { + unsigned char wildcard205627753219 = gib_print_symbol(3239); + unsigned char wildcard205727763220 = gib_print_symbol(3238); + + return 0; + break; + } + + case 1: + { + GibInt x205827773221 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3373)->field0; + GibInt x205927783222 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3373)->field1; + GibInt x206027793223 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3373)->field2; + GibCursor x206127803224 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3373)->field3; + GibCursor x206227813225 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3373)->field4; + unsigned char wildcard206827823226 = gib_print_symbol(3254); + unsigned char wildcard207427833227 = gib_print_symbol(3256); + unsigned char y206327843228 = printf("%ld", x205827773221); + unsigned char wildcard207327853229 = gib_print_symbol(3256); + unsigned char y206427863230 = printf("%ld", x205927783222); + unsigned char wildcard207227873231 = gib_print_symbol(3256); + unsigned char y206527883232 = printf("%ld", x206027793223); + unsigned char wildcard207127893233 = gib_print_symbol(3256); + unsigned char y206627903234 = _print_Map99_v1005(x206127803224); + unsigned char wildcard207027913235 = gib_print_symbol(3256); + unsigned char y206727923236 = _print_Map99_v1005(x206227813225); + unsigned char wildcard206927933237 = gib_print_symbol(3238); + + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag3372"); + exit(1); + } + } +} +int main(int argc, char **argv) +{ + int init0 = gib_init(argc, argv); + + info_table_initialize(); + symbol_table_initialize(); + + int exit1 = gib_exit(); + + return exit1; +} \ No newline at end of file diff --git a/benchmarks/CRDTs/IntOrSet.hs b/benchmarks/CRDTs/IntOrSet.hs new file mode 100644 index 000000000..e0cae5efe --- /dev/null +++ b/benchmarks/CRDTs/IntOrSet.hs @@ -0,0 +1,50 @@ +{-# LANGUAGE BlockArguments #-} + +module IntOrSet where +import qualified Timekeeping as T +import Common +import qualified Map as M +import qualified Set as S + +data IntOrSet = OrSet T.Clock (M.Map T.Timestamp) S.IntSet + +getClock :: IntOrSet -> T.Clock +getClock x = case x of + OrSet clk _ _ -> clk + +getState :: IntOrSet -> (M.Map T.Timestamp) +getState x = case x of + OrSet _ s _ -> s + +getDelSet :: IntOrSet -> S.IntSet +getDelSet x = case x of + OrSet _ _ delset -> delset + +init :: T.Timestamp -> Int -> IntOrSet +init el uid = + OrSet (T.step uid (T.init uid)) (M.singleton (T.serializetimestamp el) (T.stamp uid (T.init uid))) S.EmptySet + +add :: T.Timestamp -> Int -> IntOrSet -> IntOrSet +add el uid s = + let clk = getClock s + timestamp = M.lookup (T.serializetimestamp el) (getState s) + in OrSet (T.step uid clk) (M.insert (T.serializetimestamp el) (T.stamp uid clk) (getState s)) + case timestamp of + Just timestamp -> S.insert (T.serializetimestamp timestamp) (getDelSet s) + Nothing -> (getDelSet s) + +remove :: T.Timestamp -> Int -> IntOrSet -> IntOrSet +remove el uid s = case (M.lookup (T.serializetimestamp el) (getState s)) of + Just timestamp -> OrSet (T.step uid (getClock s)) (M.delete (T.serializetimestamp el) (getState s)) (S.insert (T.serializetimestamp timestamp) (getDelSet s)) + Nothing -> s + +--merge :: Ord eltype => ORSet eltype -> ORSet eltype -> ORSet eltype + +buildValue :: (M.Map T.Timestamp) -> S.IntSet -> S.IntSet +buildValue m s = case m of + M.Tip -> s + M.Bin _ k v l r -> buildValue l (S.insert k (buildValue r s)) + +value :: IntOrSet -> S.IntSet +value x = case x of + OrSet _ s _ -> (buildValue s S.EmptySet) \ No newline at end of file diff --git a/benchmarks/CRDTs/IntOrderedList.c b/benchmarks/CRDTs/IntOrderedList.c new file mode 100644 index 000000000..14c06d1f5 --- /dev/null +++ b/benchmarks/CRDTs/IntOrderedList.c @@ -0,0 +1,4382 @@ +/* Gibbon program. */ + +#include "gibbon_rts.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef _WIN64 +#include +#endif + +#ifdef _GIBBON_POINTER +#include +#endif + +#ifdef _GIBBON_PARALLEL +#include +#include +#endif + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Program starts here + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +typedef struct GibIntProd_struct { + GibInt field0; + } GibIntProd; +typedef struct GibIntGibIntProd_struct { + GibInt field0; + GibInt field1; + } GibIntGibIntProd; +typedef struct GibIntGibIntGibIntGibIntGibCursorGibCursorProd_struct { + GibInt field0; + GibInt field1; + GibInt field2; + GibInt field3; + GibCursor field4; + GibCursor field5; + } GibIntGibIntGibIntGibIntGibCursorGibCursorProd; +typedef struct GibIntGibIntGibIntGibCursorGibCursorProd_struct { + GibInt field0; + GibInt field1; + GibInt field2; + GibCursor field3; + GibCursor field4; + } GibIntGibIntGibIntGibCursorGibCursorProd; +typedef struct GibIntGibIntGibCursorProd_struct { + GibInt field0; + GibInt field1; + GibCursor field2; + } GibIntGibIntGibCursorProd; +typedef struct GibIntGibCursorProd_struct { + GibInt field0; + GibCursor field1; + } GibIntGibCursorProd; +typedef struct GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd_struct { + GibInt field0; + GibCursor field1; + GibInt field2; + GibCursor field3; + GibCursor field4; + GibCursor field5; + } GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd; +typedef struct GibIntGibCursorGibCursorProd_struct { + GibInt field0; + GibCursor field1; + GibCursor field2; + } GibIntGibCursorGibCursorProd; +typedef struct GibBoolProd_struct { + GibBool field0; + } GibBoolProd; +typedef struct GibPackedTagGibCursorProd_struct { + GibPackedTag field0; + GibCursor field1; + } GibPackedTagGibCursorProd; +typedef struct GibCursorProd_struct { + GibCursor field0; + } GibCursorProd; +typedef struct GibCursorGibIntGibCursorGibCursorGibCursorProd_struct { + GibCursor field0; + GibInt field1; + GibCursor field2; + GibCursor field3; + GibCursor field4; + } GibCursorGibIntGibCursorGibCursorGibCursorProd; +GibCursor compare170(GibCursor a27624343183, GibCursor b27724353184); +GibCursor stamp171(GibInt uid29824413191, GibCursor clk29924423192); +GibCursor step172(GibInt uid30024433193, GibCursor clk30124443194); +GibCursor clockmap173(GibCursor x30724463197); +GibCursor lookup174(GibInt k31024493200, GibCursor clk31124503201); +GibCursor init175(GibInt uid31424533204); +GibInt author176(GibCursor t31524543206); +GibCursor clock177(GibCursor t31824573209); +GibCursor compareInt154(GibInt a33424603212, GibInt b33524613213); +GibInt ratio141(); +GibInt delta142(); +GibCursor cursor_1151249(GibInt i21724693218, GibCursor x21824703219); +GibCursor value_1131252(GibCursor x21024763228); +GibCursor getHead1111248(GibCursor list20624823235); +GibCursor value1121240(GibCursor x20424853238); +GibCursor insert1181239(GibInt uid19724863240, GibInt x19824873241, + GibCursor l19924883242, GibCursor r20024893243, + GibCursor list20124903244); +GibCursor cursor1141238(GibInt t19424923250, GibCursor x19524933251); +GibCursor singleton1191237(GibInt uid18924943253, GibInt x19024953254); +GibInt size1491257(GibCursor m49924983259); +GibInt key1481241(GibCursor s49225043265); +GibCursor singleL1361264(GibInt k140425103271, GibInt x140525113272, + GibCursor t140625123273, GibCursor m40725133274); +GibCursor doubleL1341265(GibInt k137925193281, GibInt x138025203282, + GibCursor t138125213283, GibCursor m038225223284); +GibCursor rotateL1391258(GibInt k42925283290, GibInt x43025293291, + GibCursor l43125303292, GibCursor r43225313293); +GibCursor bin1371263(GibInt k41425373304, GibInt x41525383305, + GibCursor l41625393306, GibCursor r41725403307); +GibCursor singleR1351260(GibInt k139425413312, GibInt x139525423313, + GibCursor m39625433314, GibCursor t339725443315); +GibCursor doubleR1331261(GibInt k136425503322, GibInt x136525513323, + GibCursor m036625523324, GibCursor t436725533325); +GibCursor empty1311262(); +GibCursor rotateR1381259(GibInt k41925593331, GibInt x42025603332, + GibCursor l42125613333, GibCursor r42225623334); +GibCursor balance1401256(GibInt k43925683345, GibInt x44025693346, + GibCursor l44125703347, GibCursor r44225713348); +GibCursor lookup1301244(GibInt k34925723369, GibCursor m35025733370); +GibCursor singleton1291245(GibInt k34625793378, GibInt x34725803379); +GibCursor insert1281243(GibInt kx33725813382, GibInt x33825823383, + GibCursor m33925833384); +GibCursor getClock1221250(GibCursor list26725893394); +GibCursor getStamp1211254(GibCursor x26025923397); +GibCursor place_1171255(GibCursor x24025983406, GibCursor acc24125993407); +GibCursor place1161251(GibInt uid22526053413, GibCursor clk22626063414, + GibInt x22726073415, GibCursor s22826083416, + GibCursor l22926093417, GibCursor r23026103418); +GibCursor _copy_Clock178(GibCursor arg206826123420); +GibCursor _copy_without_ptrs_Clock178(GibCursor arg207326173425); +unsigned char _traverse_Clock178(GibCursor arg207826223430); +unsigned char _print_Clock178(GibCursor arg208326263434); +GibCursor _copy_Timestamp179(GibCursor arg209226353443); +GibCursor _copy_without_ptrs_Timestamp179(GibCursor arg209726403448); +unsigned char _traverse_Timestamp179(GibCursor arg210226453453); +unsigned char _print_Timestamp179(GibCursor arg210726493457); +GibCursor _copy_Ord156(GibCursor arg211626583466); +GibCursor _copy_without_ptrs_Ord156(GibCursor arg211726593467); +unsigned char _traverse_Ord156(GibCursor arg211826603468); +unsigned char _print_Ord156(GibCursor arg211926613469); +GibCursor _copy_OrderedNode124_v1246(GibCursor arg212826703478); +GibCursor _copy_without_ptrs_OrderedNode124_v1246(GibCursor arg213926813489); +unsigned char _traverse_OrderedNode124_v1246(GibCursor arg215026923500); +unsigned char _print_OrderedNode124_v1246(GibCursor arg216127023510); +GibCursor _copy_OrderedList123_v1247(GibCursor arg218127223530); +GibCursor _copy_without_ptrs_OrderedList123_v1247(GibCursor arg218627273535); +unsigned char _traverse_OrderedList123_v1247(GibCursor arg219127323540); +unsigned char _print_OrderedList123_v1247(GibCursor arg219627373545); +GibCursor _copy_Node166_v1253(GibCursor arg220527463554); +GibCursor _copy_without_ptrs_Node166_v1253(GibCursor arg221027513559); +unsigned char _traverse_Node166_v1253(GibCursor arg221527563564); +unsigned char _print_Node166_v1253(GibCursor arg222027603568); +GibCursor _copy_Maybe155_v1242(GibCursor arg223127713579); +GibCursor _copy_without_ptrs_Maybe155_v1242(GibCursor arg223427743582); +unsigned char _traverse_Maybe155_v1242(GibCursor arg223727773585); +unsigned char _print_Maybe155_v1242(GibCursor arg224027793587); +GibCursor _copy_Map151_v1236(GibCursor arg224827873595); +GibCursor _copy_without_ptrs_Map151_v1236(GibCursor arg225927983606); +unsigned char _traverse_Map151_v1236(GibCursor arg227028093617); +unsigned char _print_Map151_v1236(GibCursor arg228128173625); +GibCursor caseFn2304(GibCursor b277230528413645); +GibCursor caseFn2306(GibCursor b277230728473652, GibInt k293230828483653); +GibCursor caseFn2309(GibCursor b277231028503656, GibInt k293231128513657, + GibInt ax295231228523658); +GibCursor caseFn2313(GibCursor a276231428543661, GibCursor b277231528553662, + GibInt k293231628563663); +GibCursor caseFn2317(GibCursor diff297231828583666); +GibCursor caseFn2319(GibCursor diff297232028593667); +GibCursor caseFn2321(GibCursor diff297232228603668); +GibCursor caseFn2323(GibCursor diff297232428613669); +GibCursor caseFn2325(GibCursor a276232628623670, GibCursor b277232728633671); +GibCursor caseFn2328(GibInt uid300232928713681, GibCursor clk301233028723682, + GibInt v302233128733683); +GibCursor caseFn2332(GibInt uid300233328763688, GibCursor clk301233428773689); +GibCursor caseFn2335(GibInt i217233628803693, GibCursor n224233728813694, + GibCursor t220233828823695); +GibCursor caseFn2339(GibInt k1379234028883703, GibInt x1380234128893704, + GibCursor t1381234228903705, GibCursor m1387234328913706, + GibInt k2385234428923707, GibInt x2386234528933708, + GibCursor t4388234628943709); +GibCursor caseFn2347(GibInt k1364234829003717, GibInt x1365234929013718, + GibCursor t4367235029023719, GibCursor m1373235129033720, + GibInt k2370235229043721, GibInt x2371235329053722, + GibCursor t1372235429063723); +GibCursor caseFn2355(GibCursor x240235629123731, GibCursor acc241235729133732, + GibCursor tx243235829143733, GibInt vx244235929153734, + GibCursor lx245236029163735, GibCursor rx246236129173736); +GibCursor caseFn2362(GibInt uid225236329233743, GibCursor clk226236429243744, + GibInt x227236529253745, GibCursor l229236629263746, + GibCursor r230236729273747, GibCursor t235236829283748, + GibInt v236236929293749, GibCursor n239237029303750); +GibCursor caseFn2371(GibInt uid225237229313779, GibCursor clk226237329323780, + GibInt x227237429333781, GibCursor s228237529343782, + GibCursor l229237629353783, GibCursor r230237729363784, + GibCursor t232237829373785); +GibCursor caseFn2379(GibInt uid225238029433793, GibCursor clk226238129443794, + GibInt x227238229453795, GibCursor l229238329463796, + GibCursor r230238429473797, GibCursor t235238529483798, + GibInt v236238629493799, GibCursor n239238729503800); +GibCursor caseFn2388(GibInt uid225238929513829, GibCursor clk226239029523830, + GibInt x227239129533831, GibCursor s228239229543832, + GibCursor l229239329553833, GibCursor r230239429563834, + GibCursor t232239529573835); +GibCursor caseFn2396(GibInt uid225239729633843, GibCursor clk226239829643844, + GibInt x227239929653845, GibCursor l229240029663846, + GibCursor r230240129673847, GibCursor t235240229683848, + GibInt v236240329693849, GibCursor n239240429703850); +GibCursor caseFn2405(GibInt uid225240629713879, GibCursor clk226240729723880, + GibInt x227240829733881, GibCursor s228240929743882, + GibCursor l229241029753883, GibCursor r230241129763884, + GibCursor t232241229773885); +GibCursor caseFn2413(GibInt uid225241429833893, GibCursor clk226241529843894, + GibInt x227241629853895, GibCursor s228241729863896, + GibCursor l229241829873897, GibCursor r230241929883898, + GibCursor t232242029893899); +GibCursor caseFn2421(GibInt uid225242229903905, GibCursor clk226242329913906, + GibInt x227242429923907, GibCursor s228242529933908, + GibCursor l229242629943909, GibCursor r230242729953910, + GibCursor t232242829963911); +typedef enum { + GibInt_T, + GibFloat_T, + GibSym_T, + GibBool_T, + GibVector_T, + GibList_T, + GibCursor_T, + Clock178_T, + Map151_v1236_T, + Maybe155_v1242_T, + Node166_v1253_T, + Ord156_T, + OrderedList123_v1247_T, + OrderedNode124_v1246_T, + Timestamp179_T, + } GibDatatype; +void info_table_initialize(void) +{ + int error = gib_info_table_initialize(15); + + if (error < 0) { + fprintf(stderr, "Couldn't initialize info table, errorno=%d", error); + exit(1); + } + + GibDatatype field_tys[3]; + + error = gib_info_table_insert_packed_dcon(Clock178_T, 0, 8, 1, 1, 0, + field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, Clock178_T, 0); + exit(1); + } + error = gib_info_table_insert_packed_dcon(Map151_v1236_T, 1, 24, 2, 3, 0, + field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, Map151_v1236_T, 1); + exit(1); + } + error = gib_info_table_insert_packed_dcon(Map151_v1236_T, 0, 0, 0, 0, 0, + field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, Map151_v1236_T, 0); + exit(1); + } + error = gib_info_table_insert_packed_dcon(Maybe155_v1242_T, 1, 8, 0, 1, 0, + field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, Maybe155_v1242_T, 1); + exit(1); + } + error = gib_info_table_insert_packed_dcon(Maybe155_v1242_T, 0, 0, 0, 0, 0, + field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, Maybe155_v1242_T, 0); + exit(1); + } + error = gib_info_table_insert_packed_dcon(Node166_v1253_T, 1, 8, 1, 1, 0, + field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, Node166_v1253_T, 1); + exit(1); + } + error = gib_info_table_insert_packed_dcon(Node166_v1253_T, 0, 0, 0, 0, 0, + field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, Node166_v1253_T, 0); + exit(1); + } + error = gib_info_table_insert_packed_dcon(Ord156_T, 3, 0, 0, 0, 0, + field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, Ord156_T, 3); + exit(1); + } + error = gib_info_table_insert_packed_dcon(Ord156_T, 2, 0, 0, 0, 0, + field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, Ord156_T, 2); + exit(1); + } + error = gib_info_table_insert_packed_dcon(Ord156_T, 1, 0, 0, 0, 0, + field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, Ord156_T, 1); + exit(1); + } + error = gib_info_table_insert_packed_dcon(Ord156_T, 0, 0, 0, 0, 0, + field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, Ord156_T, 0); + exit(1); + } + error = gib_info_table_insert_packed_dcon(OrderedList123_v1247_T, 0, 0, 2, + 0, 0, field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, OrderedList123_v1247_T, 0); + exit(1); + } + error = gib_info_table_insert_packed_dcon(OrderedNode124_v1246_T, 0, 8, 4, + 1, 0, field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, OrderedNode124_v1246_T, 0); + exit(1); + } + error = gib_info_table_insert_packed_dcon(OrderedNode124_v1246_T, 1, 0, 0, + 0, 0, field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, OrderedNode124_v1246_T, 1); + exit(1); + } + error = gib_info_table_insert_packed_dcon(Timestamp179_T, 0, 8, 1, 1, 0, + field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, Timestamp179_T, 0); + exit(1); + } + gib_info_table_finalize(); +} +void symbol_table_initialize(void) +{ + gib_add_symbol(3917, ")"); + gib_add_symbol(3918, "(Tip167_v1253"); + gib_add_symbol(3919, "(Tip152_v1236"); + gib_add_symbol(3920, "(Tip126_v1246"); + gib_add_symbol(3921, "(Timestamp180"); + gib_add_symbol(3922, "(OrderedList127_v1247"); + gib_add_symbol(3923, "(Nothing161_v1242"); + gib_add_symbol(3924, "(Lt157"); + gib_add_symbol(3925, "(Just162_v1242"); + gib_add_symbol(3926, "(Gt158"); + gib_add_symbol(3927, "(Eq159"); + gib_add_symbol(3928, "(Clk181"); + gib_add_symbol(3929, "(Cc160"); + gib_add_symbol(3930, "(Bin168_v1253"); + gib_add_symbol(3931, "(Bin153_v1236"); + gib_add_symbol(3932, "(Bin125_v1246"); + gib_add_symbol(3933, " "); +} +GibCursor compare170(GibCursor a27624343183, GibCursor b27724353184) +{ + GibCursor fltCse30013185 = clockmap173(a27624343183); + GibPackedTag tag3934 = *(GibPackedTag *) fltCse30013185; + GibCursor tail3935 = fltCse30013185 + sizeof(GibInt); + + + switch3936: + ; + switch (tag3934) { + + case 0: + { + return caseFn2304(b27724353184); + break; + } + + case 1: + { + GibInt wildcard_5328324363186 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3935)->field0; + GibInt wildcard_5428424373187 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3935)->field1; + GibInt wildcard_5528524383188 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3935)->field2; + GibCursor wildcard_5628624393189 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3935)->field3; + GibCursor wildcard_5728724403190 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3935)->field4; + + return caseFn2325(a27624343183, b27724353184); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag3934"); + exit(1); + } + } +} +GibCursor stamp171(GibInt uid29824413191, GibCursor clk29924423192) +{ + GibPtr tailift3937 = gib_alloc(sizeof(GibIntGibIntGibCursorProd)); + + ((GibIntGibIntGibCursorProd *) tailift3937)->field0 = 0; + ((GibIntGibIntGibCursorProd *) tailift3937)->field1 = uid29824413191; + ((GibIntGibIntGibCursorProd *) tailift3937)->field2 = clk29924423192; + return tailift3937; +} +GibCursor step172(GibInt uid30024433193, GibCursor clk30124443194) +{ + GibCursor fltCse30023195 = lookup174(uid30024433193, clk30124443194); + GibPackedTag tag3938 = *(GibPackedTag *) fltCse30023195; + GibCursor tail3939 = fltCse30023195 + sizeof(GibInt); + + + switch3940: + ; + switch (tag3938) { + + case 1: + { + GibInt v30224453196 = ((GibIntProd *) tail3939)->field0; + + return caseFn2328(uid30024433193, clk30124443194, v30224453196); + break; + } + + case 0: + { + return caseFn2332(uid30024433193, clk30124443194); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag3938"); + exit(1); + } + } +} +GibCursor clockmap173(GibCursor x30724463197) +{ + GibInt tag3941 = ((GibIntGibIntGibCursorProd *) x30724463197)->field0; + GibInt wildcard_2230824473198 = + ((GibIntGibIntGibCursorProd *) x30724463197)->field1; + GibCursor y30924483199 = + ((GibIntGibIntGibCursorProd *) x30724463197)->field2; + + return y30924483199; +} +GibCursor lookup174(GibInt k31024493200, GibCursor clk31124503201) +{ + GibInt tag3942 = ((GibIntGibIntGibCursorProd *) clk31124503201)->field0; + GibInt wildcard_1831224513202 = + ((GibIntGibIntGibCursorProd *) clk31124503201)->field1; + GibCursor m31324523203 = + ((GibIntGibIntGibCursorProd *) clk31124503201)->field2; + + return lookup1301244(k31024493200, m31324523203); +} +GibCursor init175(GibInt uid31424533204) +{ + GibCursor fltPkd30033205 = singleton1291245(uid31424533204, 0); + GibPtr tailift3943 = gib_alloc(sizeof(GibIntGibIntGibCursorProd)); + + ((GibIntGibIntGibCursorProd *) tailift3943)->field0 = 0; + ((GibIntGibIntGibCursorProd *) tailift3943)->field1 = 0; + ((GibIntGibIntGibCursorProd *) tailift3943)->field2 = fltPkd30033205; + return tailift3943; +} +GibInt author176(GibCursor t31524543206) +{ + GibInt tag3944 = ((GibIntGibIntGibCursorProd *) t31524543206)->field0; + GibInt a31624553207 = ((GibIntGibIntGibCursorProd *) t31524543206)->field1; + GibCursor wildcard_1131724563208 = + ((GibIntGibIntGibCursorProd *) t31524543206)->field2; + + return a31624553207; +} +GibCursor clock177(GibCursor t31824573209) +{ + GibInt tag3945 = ((GibIntGibIntGibCursorProd *) t31824573209)->field0; + GibInt wildcard_731924583210 = + ((GibIntGibIntGibCursorProd *) t31824573209)->field1; + GibCursor c32024593211 = + ((GibIntGibIntGibCursorProd *) t31824573209)->field2; + + return c32024593211; +} +GibCursor compareInt154(GibInt a33424603212, GibInt b33524613213) +{ + GibInt sub33624623214 = a33424603212 - b33524613213; + GibBool fltIf30043215 = sub33624623214 < 0; + + if (fltIf30043215) { + GibPtr tailift3946 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift3946)->field0 = 0; + return tailift3946; + } else { + GibBool fltIf30053216 = sub33624623214 > 0; + + if (fltIf30053216) { + GibPtr tailift3947 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift3947)->field0 = 1; + return tailift3947; + } else { + GibBool fltIf30063217 = sub33624623214 == 0; + + if (fltIf30063217) { + GibPtr tailift3948 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift3948)->field0 = 2; + return tailift3948; + } else { + GibPtr tailift3949 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift3949)->field0 = 3; + return tailift3949; + } + } + } +} +GibInt ratio141() +{ + return 2; +} +GibInt delta142() +{ + return 4; +} +GibCursor cursor_1151249(GibInt i21724693218, GibCursor x21824703219) +{ + GibPackedTag tag3950 = *(GibPackedTag *) x21824703219; + GibCursor tail3951 = x21824703219 + sizeof(GibInt); + + + switch3952: + ; + switch (tag3950) { + + case 1: + { + GibInt fltAppE30073220 = 0 - 1; + GibInt fltAppE30093221 = 0 - 1; + GibCursor fltAppE30083222 = init175(fltAppE30093221); + + return stamp171(fltAppE30073220, fltAppE30083222); + break; + } + + case 0: + { + GibCursor t22024713223 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail3951)->field0; + GibInt wildcard_8622124723224 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail3951)->field1; + GibCursor wildcard_8722224733225 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail3951)->field2; + GibCursor wildcard_8822324743226 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail3951)->field3; + GibCursor n22424753227 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail3951)->field4; + + return caseFn2335(i21724693218, n22424753227, t22024713223); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag3950"); + exit(1); + } + } +} +GibCursor value_1131252(GibCursor x21024763228) +{ + GibPackedTag tag3953 = *(GibPackedTag *) x21024763228; + GibCursor tail3954 = x21024763228 + sizeof(GibInt); + + + switch3957: + ; + switch (tag3953) { + + case 1: + { + GibPtr tailift3955 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift3955)->field0 = 0; + return tailift3955; + break; + } + + case 0: + { + GibCursor wildcard_9821224773229 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail3954)->field0; + GibInt v21324783230 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail3954)->field1; + GibCursor wildcard_9921424793231 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail3954)->field2; + GibCursor wildcard_10021524803232 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail3954)->field3; + GibCursor n21624813233 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail3954)->field4; + GibCursor fltPkd30103234 = value_1131252(n21624813233); + GibPtr tailift3956 = gib_alloc(sizeof(GibIntGibIntGibCursorProd)); + + ((GibIntGibIntGibCursorProd *) tailift3956)->field0 = 1; + ((GibIntGibIntGibCursorProd *) tailift3956)->field1 = v21324783230; + ((GibIntGibIntGibCursorProd *) tailift3956)->field2 = + fltPkd30103234; + return tailift3956; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag3953"); + exit(1); + } + } +} +GibCursor getHead1111248(GibCursor list20624823235) +{ + GibInt tag3958 = ((GibIntGibCursorGibCursorProd *) list20624823235)->field0; + GibCursor wildcard_120824833236 = + ((GibIntGibCursorGibCursorProd *) list20624823235)->field1; + GibCursor node20924843237 = + ((GibIntGibCursorGibCursorProd *) list20624823235)->field2; + + return node20924843237; +} +GibCursor value1121240(GibCursor x20424853238) +{ + GibCursor fltAppE30113239 = getHead1111248(x20424853238); + + return value_1131252(fltAppE30113239); +} +GibCursor insert1181239(GibInt uid19724863240, GibInt x19824873241, + GibCursor l19924883242, GibCursor r20024893243, + GibCursor list20124903244) +{ + GibCursor fltAppE30123245 = getClock1221250(list20124903244); + GibCursor clk20324913246 = step172(uid19724863240, fltAppE30123245); + GibCursor fltAppE30143247 = stamp171(uid19724863240, clk20324913246); + GibCursor fltAppE30153248 = getHead1111248(list20124903244); + GibCursor fltPkd30133249 = + place1161251(uid19724863240, fltAppE30143247, x19824873241, fltAppE30153248, l19924883242, r20024893243); + GibPtr tailift3959 = gib_alloc(sizeof(GibIntGibCursorGibCursorProd)); + + ((GibIntGibCursorGibCursorProd *) tailift3959)->field0 = 0; + ((GibIntGibCursorGibCursorProd *) tailift3959)->field1 = clk20324913246; + ((GibIntGibCursorGibCursorProd *) tailift3959)->field2 = fltPkd30133249; + return tailift3959; +} +GibCursor cursor1141238(GibInt t19424923250, GibCursor x19524933251) +{ + GibCursor fltAppE30163252 = getHead1111248(x19524933251); + + return cursor_1151249(t19424923250, fltAppE30163252); +} +GibCursor singleton1191237(GibInt uid18924943253, GibInt x19024953254) +{ + GibCursor clk19224963255 = init175(uid18924943253); + GibCursor t19324973256 = stamp171(uid18924943253, clk19224963255); + GibPtr fltPkd30183257 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) fltPkd30183257)->field0 = 1; + + GibPtr fltPkd30173258 = + gib_alloc(sizeof(GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd)); + + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd30173258)->field0 = + 0; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd30173258)->field1 = + t19324973256; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd30173258)->field2 = + x19024953254; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd30173258)->field3 = + t19324973256; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd30173258)->field4 = + t19324973256; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd30173258)->field5 = + fltPkd30183257; + + GibPtr tailift3960 = gib_alloc(sizeof(GibIntGibCursorGibCursorProd)); + + ((GibIntGibCursorGibCursorProd *) tailift3960)->field0 = 0; + ((GibIntGibCursorGibCursorProd *) tailift3960)->field1 = clk19224963255; + ((GibIntGibCursorGibCursorProd *) tailift3960)->field2 = fltPkd30173258; + return tailift3960; +} +GibInt size1491257(GibCursor m49924983259) +{ + GibPackedTag tag3961 = *(GibPackedTag *) m49924983259; + GibCursor tail3962 = m49924983259 + sizeof(GibInt); + + + switch3963: + ; + switch (tag3961) { + + case 0: + { + return 0; + break; + } + + case 1: + { + GibInt sz50124993260 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3962)->field0; + GibInt wildcard_1850225003261 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3962)->field1; + GibInt wildcard_1950325013262 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3962)->field2; + GibCursor wildcard_2050425023263 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3962)->field3; + GibCursor wildcard_2150525033264 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3962)->field4; + + return sz50124993260; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag3961"); + exit(1); + } + } +} +GibInt key1481241(GibCursor s49225043265) +{ + GibPackedTag tag3964 = *(GibPackedTag *) s49225043265; + GibCursor tail3965 = s49225043265 + sizeof(GibInt); + + + switch3966: + ; + switch (tag3964) { + + case 0: + { + return 0; + break; + } + + case 1: + { + GibInt wildcard_2849425053266 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3965)->field0; + GibInt k49525063267 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3965)->field1; + GibInt wildcard_2949625073268 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3965)->field2; + GibCursor wildcard_3049725083269 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3965)->field3; + GibCursor wildcard_3149825093270 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3965)->field4; + + return k49525063267; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag3964"); + exit(1); + } + } +} +GibCursor singleL1361264(GibInt k140425103271, GibInt x140525113272, + GibCursor t140625123273, GibCursor m40725133274) +{ + GibPackedTag tag3967 = *(GibPackedTag *) m40725133274; + GibCursor tail3968 = m40725133274 + sizeof(GibInt); + + + switch3969: + ; + switch (tag3967) { + + case 1: + { + GibInt wildcard_15940925143275 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3968)->field0; + GibInt k241025153276 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3968)->field1; + GibInt x241125163277 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3968)->field2; + GibCursor t241225173278 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3968)->field3; + GibCursor t341325183279 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3968)->field4; + GibCursor fltAppE30193280 = + bin1371263(k140425103271, x140525113272, t140625123273, t241225173278); + + return bin1371263(k241025153276, x241125163277, fltAppE30193280, + t341325183279); + break; + } + + case 0: + { + return empty1311262(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag3967"); + exit(1); + } + } +} +GibCursor doubleL1341265(GibInt k137925193281, GibInt x138025203282, + GibCursor t138125213283, GibCursor m038225223284) +{ + GibPackedTag tag3970 = *(GibPackedTag *) m038225223284; + GibCursor tail3971 = m038225223284 + sizeof(GibInt); + + + switch3972: + ; + switch (tag3970) { + + case 1: + { + GibInt wildcard_17938425233285 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3971)->field0; + GibInt k238525243286 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3971)->field1; + GibInt x238625253287 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3971)->field2; + GibCursor m138725263288 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3971)->field3; + GibCursor t438825273289 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3971)->field4; + + return caseFn2339(k137925193281, x138025203282, t138125213283, + m138725263288, k238525243286, x238625253287, + t438825273289); + break; + } + + case 0: + { + return empty1311262(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag3970"); + exit(1); + } + } +} +GibCursor rotateL1391258(GibInt k42925283290, GibInt x43025293291, + GibCursor l43125303292, GibCursor r43225313293) +{ + GibPackedTag tag3973 = *(GibPackedTag *) r43225313293; + GibCursor tail3974 = r43225313293 + sizeof(GibInt); + + + switch3975: + ; + switch (tag3973) { + + case 1: + { + GibInt wildcard_13043425323294 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3974)->field0; + GibInt wildcard_13143525333295 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3974)->field1; + GibInt wildcard_13243625343296 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3974)->field2; + GibCursor ly43725353297 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3974)->field3; + GibCursor ry43825363298 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3974)->field4; + GibInt fltPrm30213299 = size1491257(ly43725353297); + GibInt fltPrm30233300 = ratio141(); + GibInt fltPrm30243301 = size1491257(ry43825363298); + GibInt fltPrm30223302 = fltPrm30233300 * fltPrm30243301; + GibBool fltIf30203303 = fltPrm30213299 < fltPrm30223302; + + if (fltIf30203303) { + return singleL1361264(k42925283290, x43025293291, l43125303292, + r43225313293); + } else { + return doubleL1341265(k42925283290, x43025293291, l43125303292, + r43225313293); + } + break; + } + + case 0: + { + return empty1311262(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag3973"); + exit(1); + } + } +} +GibCursor bin1371263(GibInt k41425373304, GibInt x41525383305, + GibCursor l41625393306, GibCursor r41725403307) +{ + GibInt fltPrm30273308 = size1491257(l41625393306); + GibInt fltPrm30283309 = size1491257(r41725403307); + GibInt fltPrm30263310 = fltPrm30273308 + fltPrm30283309; + GibInt fltPkd30253311 = fltPrm30263310 + 1; + GibPtr tailift3976 = + gib_alloc(sizeof(GibIntGibIntGibIntGibIntGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift3976)->field0 = + 1; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift3976)->field1 = + fltPkd30253311; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift3976)->field2 = + k41425373304; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift3976)->field3 = + x41525383305; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift3976)->field4 = + l41625393306; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift3976)->field5 = + r41725403307; + return tailift3976; +} +GibCursor singleR1351260(GibInt k139425413312, GibInt x139525423313, + GibCursor m39625433314, GibCursor t339725443315) +{ + GibPackedTag tag3977 = *(GibPackedTag *) m39625433314; + GibCursor tail3978 = m39625433314 + sizeof(GibInt); + + + switch3979: + ; + switch (tag3977) { + + case 1: + { + GibInt wildcard_16939925453316 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3978)->field0; + GibInt k240025463317 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3978)->field1; + GibInt x240125473318 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3978)->field2; + GibCursor t140225483319 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3978)->field3; + GibCursor t240325493320 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3978)->field4; + GibCursor fltAppE30293321 = + bin1371263(k139425413312, x139525423313, t240325493320, t339725443315); + + return bin1371263(k240025463317, x240125473318, t140225483319, + fltAppE30293321); + break; + } + + case 0: + { + return empty1311262(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag3977"); + exit(1); + } + } +} +GibCursor doubleR1331261(GibInt k136425503322, GibInt x136525513323, + GibCursor m036625523324, GibCursor t436725533325) +{ + GibPackedTag tag3980 = *(GibPackedTag *) m036625523324; + GibCursor tail3981 = m036625523324 + sizeof(GibInt); + + + switch3982: + ; + switch (tag3980) { + + case 1: + { + GibInt wildcard_19536925543326 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3981)->field0; + GibInt k237025553327 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3981)->field1; + GibInt x237125563328 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3981)->field2; + GibCursor t137225573329 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3981)->field3; + GibCursor m137325583330 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3981)->field4; + + return caseFn2347(k136425503322, x136525513323, t436725533325, + m137325583330, k237025553327, x237125563328, + t137225573329); + break; + } + + case 0: + { + return empty1311262(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag3980"); + exit(1); + } + } +} +GibCursor empty1311262() +{ + GibPtr tailift3983 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift3983)->field0 = 0; + return tailift3983; +} +GibCursor rotateR1381259(GibInt k41925593331, GibInt x42025603332, + GibCursor l42125613333, GibCursor r42225623334) +{ + GibPackedTag tag3984 = *(GibPackedTag *) l42125613333; + GibCursor tail3985 = l42125613333 + sizeof(GibInt); + + + switch3986: + ; + switch (tag3984) { + + case 1: + { + GibInt wildcard_14242425633335 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3985)->field0; + GibInt wildcard_14342525643336 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3985)->field1; + GibInt wildcard_14442625653337 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3985)->field2; + GibCursor ly42725663338 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3985)->field3; + GibCursor ry42825673339 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3985)->field4; + GibInt fltPrm30313340 = size1491257(ry42825673339); + GibInt fltPrm30333341 = ratio141(); + GibInt fltPrm30343342 = size1491257(ly42725663338); + GibInt fltPrm30323343 = fltPrm30333341 * fltPrm30343342; + GibBool fltIf30303344 = fltPrm30313340 < fltPrm30323343; + + if (fltIf30303344) { + return singleR1351260(k41925593331, x42025603332, l42125613333, + r42225623334); + } else { + return doubleR1331261(k41925593331, x42025603332, l42125613333, + r42225623334); + } + break; + } + + case 0: + { + return empty1311262(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag3984"); + exit(1); + } + } +} +GibCursor balance1401256(GibInt k43925683345, GibInt x44025693346, + GibCursor l44125703347, GibCursor r44225713348) +{ + GibInt fltPrm30373349 = size1491257(l44125703347); + GibInt fltPrm30383350 = size1491257(r44225713348); + GibInt fltPrm30363351 = fltPrm30373349 + fltPrm30383350; + GibBool fltIf30353352 = fltPrm30363351 <= 1; + + if (fltIf30353352) { + GibInt fltPrm30403353 = size1491257(l44125703347); + GibInt fltPrm30413354 = size1491257(r44225713348); + GibInt fltPkd30393355 = fltPrm30403353 + fltPrm30413354; + GibPtr tailift3987 = + gib_alloc(sizeof(GibIntGibIntGibIntGibIntGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift3987)->field0 = + 1; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift3987)->field1 = + fltPkd30393355; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift3987)->field2 = + k43925683345; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift3987)->field3 = + x44025693346; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift3987)->field4 = + l44125703347; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift3987)->field5 = + r44225713348; + return tailift3987; + } else { + GibInt fltPrm30433356 = size1491257(r44225713348); + GibInt fltPrm30453357 = delta142(); + GibInt fltPrm30463358 = size1491257(l44125703347); + GibInt fltPrm30443359 = fltPrm30453357 * fltPrm30463358; + GibBool fltIf30423360 = fltPrm30433356 >= fltPrm30443359; + + if (fltIf30423360) { + return rotateL1391258(k43925683345, x44025693346, l44125703347, + r44225713348); + } else { + GibInt fltPrm30483361 = size1491257(l44125703347); + GibInt fltPrm30503362 = delta142(); + GibInt fltPrm30513363 = size1491257(r44225713348); + GibInt fltPrm30493364 = fltPrm30503362 * fltPrm30513363; + GibBool fltIf30473365 = fltPrm30483361 >= fltPrm30493364; + + if (fltIf30473365) { + return rotateR1381259(k43925683345, x44025693346, l44125703347, + r44225713348); + } else { + GibInt fltPrm30533366 = size1491257(l44125703347); + GibInt fltPrm30543367 = size1491257(r44225713348); + GibInt fltPkd30523368 = fltPrm30533366 + fltPrm30543367; + GibPtr tailift3988 = + gib_alloc(sizeof(GibIntGibIntGibIntGibIntGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift3988)->field0 = + 1; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift3988)->field1 = + fltPkd30523368; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift3988)->field2 = + k43925683345; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift3988)->field3 = + x44025693346; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift3988)->field4 = + l44125703347; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift3988)->field5 = + r44225713348; + return tailift3988; + } + } + } +} +GibCursor lookup1301244(GibInt k34925723369, GibCursor m35025733370) +{ + GibPackedTag tag3989 = *(GibPackedTag *) m35025733370; + GibCursor tail3990 = m35025733370 + sizeof(GibInt); + + + switch3993: + ; + switch (tag3989) { + + case 0: + { + GibPtr tailift3991 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift3991)->field0 = 0; + return tailift3991; + break; + } + + case 1: + { + GibInt wildcard_4035225743371 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3990)->field0; + GibInt kx35325753372 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3990)->field1; + GibInt v35425763373 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3990)->field2; + GibCursor l35525773374 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3990)->field3; + GibCursor r35625783375 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3990)->field4; + GibBool fltIf30553376 = k34925723369 < kx35325753372; + + if (fltIf30553376) { + return lookup1301244(k34925723369, l35525773374); + } else { + GibBool fltIf30563377 = k34925723369 > kx35325753372; + + if (fltIf30563377) { + return lookup1301244(k34925723369, r35625783375); + } else { + GibPtr tailift3992 = gib_alloc(sizeof(GibIntGibIntProd)); + + ((GibIntGibIntProd *) tailift3992)->field0 = 1; + ((GibIntGibIntProd *) tailift3992)->field1 = v35425763373; + return tailift3992; + } + } + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag3989"); + exit(1); + } + } +} +GibCursor singleton1291245(GibInt k34625793378, GibInt x34725803379) +{ + GibPtr fltPkd30573380 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) fltPkd30573380)->field0 = 0; + + GibPtr fltPkd30583381 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) fltPkd30583381)->field0 = 0; + + GibPtr tailift3994 = + gib_alloc(sizeof(GibIntGibIntGibIntGibIntGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift3994)->field0 = + 1; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift3994)->field1 = + 1; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift3994)->field2 = + k34625793378; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift3994)->field3 = + x34725803379; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift3994)->field4 = + fltPkd30573380; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift3994)->field5 = + fltPkd30583381; + return tailift3994; +} +GibCursor insert1281243(GibInt kx33725813382, GibInt x33825823383, + GibCursor m33925833384) +{ + GibPackedTag tag3995 = *(GibPackedTag *) m33925833384; + GibCursor tail3996 = m33925833384 + sizeof(GibInt); + + + switch3998: + ; + switch (tag3995) { + + case 0: + { + return singleton1291245(kx33725813382, x33825823383); + break; + } + + case 1: + { + GibInt sz34125843385 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3996)->field0; + GibInt k34225853386 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3996)->field1; + GibInt v34325863387 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3996)->field2; + GibCursor l34425873388 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3996)->field3; + GibCursor r34525883389 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail3996)->field4; + GibBool fltIf30593390 = kx33725813382 == k34225853386; + + if (fltIf30593390) { + GibPtr tailift3997 = + gib_alloc(sizeof(GibIntGibIntGibIntGibIntGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift3997)->field0 = + 1; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift3997)->field1 = + sz34125843385; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift3997)->field2 = + k34225853386; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift3997)->field3 = + x33825823383; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift3997)->field4 = + l34425873388; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift3997)->field5 = + r34525883389; + return tailift3997; + } else { + GibBool fltIf30603391 = kx33725813382 <= k34225853386; + + if (fltIf30603391) { + GibCursor fltAppE30613392 = + insert1281243(kx33725813382, x33825823383, l34425873388); + + return balance1401256(k34225853386, v34325863387, + fltAppE30613392, r34525883389); + } else { + GibCursor fltAppE30623393 = + insert1281243(kx33725813382, x33825823383, r34525883389); + + return balance1401256(k34225853386, v34325863387, + l34425873388, fltAppE30623393); + } + } + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag3995"); + exit(1); + } + } +} +GibCursor getClock1221250(GibCursor list26725893394) +{ + GibInt tag3999 = ((GibIntGibCursorGibCursorProd *) list26725893394)->field0; + GibCursor c26925903395 = + ((GibIntGibCursorGibCursorProd *) list26725893394)->field1; + GibCursor wildcard_527025913396 = + ((GibIntGibCursorGibCursorProd *) list26725893394)->field2; + + return c26925903395; +} +GibCursor getStamp1211254(GibCursor x26025923397) +{ + GibPackedTag tag4000 = *(GibPackedTag *) x26025923397; + GibCursor tail4001 = x26025923397 + sizeof(GibInt); + + + switch4003: + ; + switch (tag4000) { + + case 0: + { + GibCursor t26225933398 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail4001)->field0; + GibInt wildcard_926325943399 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail4001)->field1; + GibCursor wildcard_1026425953400 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail4001)->field2; + GibCursor wildcard_1126525963401 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail4001)->field3; + GibCursor wildcard_1226625973402 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail4001)->field4; + + return t26225933398; + break; + } + + case 1: + { + GibInt fltPkd30633403 = 0 - 1; + GibInt fltAppE30653404 = 0 - 1; + GibCursor fltPkd30643405 = init175(fltAppE30653404); + GibPtr tailift4002 = gib_alloc(sizeof(GibIntGibIntGibCursorProd)); + + ((GibIntGibIntGibCursorProd *) tailift4002)->field0 = 0; + ((GibIntGibIntGibCursorProd *) tailift4002)->field1 = + fltPkd30633403; + ((GibIntGibIntGibCursorProd *) tailift4002)->field2 = + fltPkd30643405; + return tailift4002; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag4000"); + exit(1); + } + } +} +GibCursor place_1171255(GibCursor x24025983406, GibCursor acc24125993407) +{ + GibPackedTag tag4004 = *(GibPackedTag *) x24025983406; + GibCursor tail4005 = x24025983406 + sizeof(GibInt); + + + switch4006: + ; + switch (tag4004) { + + case 1: + { + return acc24125993407; + break; + } + + case 0: + { + GibCursor tx24326003408 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail4005)->field0; + GibInt vx24426013409 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail4005)->field1; + GibCursor lx24526023410 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail4005)->field2; + GibCursor rx24626033411 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail4005)->field3; + GibCursor wildcard_4624726043412 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail4005)->field4; + + return caseFn2355(x24025983406, acc24125993407, tx24326003408, + vx24426013409, lx24526023410, rx24626033411); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag4004"); + exit(1); + } + } +} +GibCursor place1161251(GibInt uid22526053413, GibCursor clk22626063414, + GibInt x22726073415, GibCursor s22826083416, + GibCursor l22926093417, GibCursor r23026103418) +{ + GibCursor t23226113419 = getStamp1211254(s22826083416); + + return caseFn2421(uid22526053413, clk22626063414, x22726073415, + s22826083416, l22926093417, r23026103418, t23226113419); +} +GibCursor _copy_Clock178(GibCursor arg206826123420) +{ + GibInt tag4007 = ((GibIntGibIntGibCursorProd *) arg206826123420)->field0; + GibInt x206926133421 = + ((GibIntGibIntGibCursorProd *) arg206826123420)->field1; + GibCursor x207026143422 = + ((GibIntGibIntGibCursorProd *) arg206826123420)->field2; + GibCursor y207226163424 = _copy_Map151_v1236(x207026143422); + GibPtr tailift4008 = gib_alloc(sizeof(GibIntGibIntGibCursorProd)); + + ((GibIntGibIntGibCursorProd *) tailift4008)->field0 = 0; + ((GibIntGibIntGibCursorProd *) tailift4008)->field1 = x206926133421; + ((GibIntGibIntGibCursorProd *) tailift4008)->field2 = y207226163424; + return tailift4008; +} +GibCursor _copy_without_ptrs_Clock178(GibCursor arg207326173425) +{ + GibInt tag4009 = ((GibIntGibIntGibCursorProd *) arg207326173425)->field0; + GibInt x207426183426 = + ((GibIntGibIntGibCursorProd *) arg207326173425)->field1; + GibCursor x207526193427 = + ((GibIntGibIntGibCursorProd *) arg207326173425)->field2; + GibCursor y207726213429 = _copy_without_ptrs_Map151_v1236(x207526193427); + GibPtr tailift4010 = gib_alloc(sizeof(GibIntGibIntGibCursorProd)); + + ((GibIntGibIntGibCursorProd *) tailift4010)->field0 = 0; + ((GibIntGibIntGibCursorProd *) tailift4010)->field1 = x207426183426; + ((GibIntGibIntGibCursorProd *) tailift4010)->field2 = y207726213429; + return tailift4010; +} +unsigned char _traverse_Clock178(GibCursor arg207826223430) +{ + GibInt tag4011 = ((GibIntGibIntGibCursorProd *) arg207826223430)->field0; + GibInt x207926233431 = + ((GibIntGibIntGibCursorProd *) arg207826223430)->field1; + GibCursor x208026243432 = + ((GibIntGibIntGibCursorProd *) arg207826223430)->field2; + unsigned char y208226253433 = _traverse_Map151_v1236(x208026243432); + + return 0; +} +unsigned char _print_Clock178(GibCursor arg208326263434) +{ + GibInt tag4012 = ((GibIntGibIntGibCursorProd *) arg208326263434)->field0; + GibInt x208426273435 = + ((GibIntGibIntGibCursorProd *) arg208326263434)->field1; + GibCursor x208526283436 = + ((GibIntGibIntGibCursorProd *) arg208326263434)->field2; + unsigned char wildcard208826293437 = gib_print_symbol(3928); + unsigned char wildcard209126303438 = gib_print_symbol(3933); + unsigned char y208626313439 = printf("%ld", x208426273435); + unsigned char wildcard209026323440 = gib_print_symbol(3933); + unsigned char y208726333441 = _print_Map151_v1236(x208526283436); + unsigned char wildcard208926343442 = gib_print_symbol(3917); + + return 0; +} +GibCursor _copy_Timestamp179(GibCursor arg209226353443) +{ + GibInt tag4013 = ((GibIntGibIntGibCursorProd *) arg209226353443)->field0; + GibInt x209326363444 = + ((GibIntGibIntGibCursorProd *) arg209226353443)->field1; + GibCursor x209426373445 = + ((GibIntGibIntGibCursorProd *) arg209226353443)->field2; + GibCursor y209626393447 = _copy_Clock178(x209426373445); + GibPtr tailift4014 = gib_alloc(sizeof(GibIntGibIntGibCursorProd)); + + ((GibIntGibIntGibCursorProd *) tailift4014)->field0 = 0; + ((GibIntGibIntGibCursorProd *) tailift4014)->field1 = x209326363444; + ((GibIntGibIntGibCursorProd *) tailift4014)->field2 = y209626393447; + return tailift4014; +} +GibCursor _copy_without_ptrs_Timestamp179(GibCursor arg209726403448) +{ + GibInt tag4015 = ((GibIntGibIntGibCursorProd *) arg209726403448)->field0; + GibInt x209826413449 = + ((GibIntGibIntGibCursorProd *) arg209726403448)->field1; + GibCursor x209926423450 = + ((GibIntGibIntGibCursorProd *) arg209726403448)->field2; + GibCursor y210126443452 = _copy_without_ptrs_Clock178(x209926423450); + GibPtr tailift4016 = gib_alloc(sizeof(GibIntGibIntGibCursorProd)); + + ((GibIntGibIntGibCursorProd *) tailift4016)->field0 = 0; + ((GibIntGibIntGibCursorProd *) tailift4016)->field1 = x209826413449; + ((GibIntGibIntGibCursorProd *) tailift4016)->field2 = y210126443452; + return tailift4016; +} +unsigned char _traverse_Timestamp179(GibCursor arg210226453453) +{ + GibInt tag4017 = ((GibIntGibIntGibCursorProd *) arg210226453453)->field0; + GibInt x210326463454 = + ((GibIntGibIntGibCursorProd *) arg210226453453)->field1; + GibCursor x210426473455 = + ((GibIntGibIntGibCursorProd *) arg210226453453)->field2; + unsigned char y210626483456 = _traverse_Clock178(x210426473455); + + return 0; +} +unsigned char _print_Timestamp179(GibCursor arg210726493457) +{ + GibInt tag4018 = ((GibIntGibIntGibCursorProd *) arg210726493457)->field0; + GibInt x210826503458 = + ((GibIntGibIntGibCursorProd *) arg210726493457)->field1; + GibCursor x210926513459 = + ((GibIntGibIntGibCursorProd *) arg210726493457)->field2; + unsigned char wildcard211226523460 = gib_print_symbol(3921); + unsigned char wildcard211526533461 = gib_print_symbol(3933); + unsigned char y211026543462 = printf("%ld", x210826503458); + unsigned char wildcard211426553463 = gib_print_symbol(3933); + unsigned char y211126563464 = _print_Clock178(x210926513459); + unsigned char wildcard211326573465 = gib_print_symbol(3917); + + return 0; +} +GibCursor _copy_Ord156(GibCursor arg211626583466) +{ + GibPackedTag tag4019 = *(GibPackedTag *) arg211626583466; + GibCursor tail4020 = arg211626583466 + sizeof(GibInt); + + + switch4025: + ; + switch (tag4019) { + + case 0: + { + GibPtr tailift4021 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift4021)->field0 = 0; + return tailift4021; + break; + } + + case 1: + { + GibPtr tailift4022 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift4022)->field0 = 1; + return tailift4022; + break; + } + + case 2: + { + GibPtr tailift4023 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift4023)->field0 = 2; + return tailift4023; + break; + } + + case 3: + { + GibPtr tailift4024 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift4024)->field0 = 3; + return tailift4024; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag4019"); + exit(1); + } + } +} +GibCursor _copy_without_ptrs_Ord156(GibCursor arg211726593467) +{ + GibPackedTag tag4026 = *(GibPackedTag *) arg211726593467; + GibCursor tail4027 = arg211726593467 + sizeof(GibInt); + + + switch4032: + ; + switch (tag4026) { + + case 0: + { + GibPtr tailift4028 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift4028)->field0 = 0; + return tailift4028; + break; + } + + case 1: + { + GibPtr tailift4029 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift4029)->field0 = 1; + return tailift4029; + break; + } + + case 2: + { + GibPtr tailift4030 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift4030)->field0 = 2; + return tailift4030; + break; + } + + case 3: + { + GibPtr tailift4031 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift4031)->field0 = 3; + return tailift4031; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag4026"); + exit(1); + } + } +} +unsigned char _traverse_Ord156(GibCursor arg211826603468) +{ + GibPackedTag tag4033 = *(GibPackedTag *) arg211826603468; + GibCursor tail4034 = arg211826603468 + sizeof(GibInt); + + + switch4035: + ; + switch (tag4033) { + + case 0: + { + return 0; + break; + } + + case 1: + { + return 0; + break; + } + + case 2: + { + return 0; + break; + } + + case 3: + { + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag4033"); + exit(1); + } + } +} +unsigned char _print_Ord156(GibCursor arg211926613469) +{ + GibPackedTag tag4036 = *(GibPackedTag *) arg211926613469; + GibCursor tail4037 = arg211926613469 + sizeof(GibInt); + + + switch4038: + ; + switch (tag4036) { + + case 0: + { + unsigned char wildcard212026623470 = gib_print_symbol(3924); + unsigned char wildcard212126633471 = gib_print_symbol(3917); + + return 0; + break; + } + + case 1: + { + unsigned char wildcard212226643472 = gib_print_symbol(3926); + unsigned char wildcard212326653473 = gib_print_symbol(3917); + + return 0; + break; + } + + case 2: + { + unsigned char wildcard212426663474 = gib_print_symbol(3927); + unsigned char wildcard212526673475 = gib_print_symbol(3917); + + return 0; + break; + } + + case 3: + { + unsigned char wildcard212626683476 = gib_print_symbol(3929); + unsigned char wildcard212726693477 = gib_print_symbol(3917); + + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag4036"); + exit(1); + } + } +} +GibCursor _copy_OrderedNode124_v1246(GibCursor arg212826703478) +{ + GibPackedTag tag4039 = *(GibPackedTag *) arg212826703478; + GibCursor tail4040 = arg212826703478 + sizeof(GibInt); + + + switch4043: + ; + switch (tag4039) { + + case 0: + { + GibCursor x212926713479 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail4040)->field0; + GibInt x213026723480 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail4040)->field1; + GibCursor x213126733481 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail4040)->field2; + GibCursor x213226743482 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail4040)->field3; + GibCursor x213326753483 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail4040)->field4; + GibCursor y213426763484 = _copy_Timestamp179(x212926713479); + GibCursor y213626783486 = _copy_Timestamp179(x213126733481); + GibCursor y213726793487 = _copy_Timestamp179(x213226743482); + GibCursor y213826803488 = + _copy_OrderedNode124_v1246(x213326753483); + GibPtr tailift4041 = + gib_alloc(sizeof(GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd)); + + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4041)->field0 = + 0; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4041)->field1 = + y213426763484; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4041)->field2 = + x213026723480; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4041)->field3 = + y213626783486; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4041)->field4 = + y213726793487; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4041)->field5 = + y213826803488; + return tailift4041; + break; + } + + case 1: + { + GibPtr tailift4042 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift4042)->field0 = 1; + return tailift4042; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag4039"); + exit(1); + } + } +} +GibCursor _copy_without_ptrs_OrderedNode124_v1246(GibCursor arg213926813489) +{ + GibPackedTag tag4044 = *(GibPackedTag *) arg213926813489; + GibCursor tail4045 = arg213926813489 + sizeof(GibInt); + + + switch4048: + ; + switch (tag4044) { + + case 0: + { + GibCursor x214026823490 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail4045)->field0; + GibInt x214126833491 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail4045)->field1; + GibCursor x214226843492 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail4045)->field2; + GibCursor x214326853493 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail4045)->field3; + GibCursor x214426863494 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail4045)->field4; + GibCursor y214526873495 = + _copy_without_ptrs_Timestamp179(x214026823490); + GibCursor y214726893497 = + _copy_without_ptrs_Timestamp179(x214226843492); + GibCursor y214826903498 = + _copy_without_ptrs_Timestamp179(x214326853493); + GibCursor y214926913499 = + _copy_without_ptrs_OrderedNode124_v1246(x214426863494); + GibPtr tailift4046 = + gib_alloc(sizeof(GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd)); + + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4046)->field0 = + 0; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4046)->field1 = + y214526873495; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4046)->field2 = + x214126833491; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4046)->field3 = + y214726893497; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4046)->field4 = + y214826903498; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4046)->field5 = + y214926913499; + return tailift4046; + break; + } + + case 1: + { + GibPtr tailift4047 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift4047)->field0 = 1; + return tailift4047; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag4044"); + exit(1); + } + } +} +unsigned char _traverse_OrderedNode124_v1246(GibCursor arg215026923500) +{ + GibPackedTag tag4049 = *(GibPackedTag *) arg215026923500; + GibCursor tail4050 = arg215026923500 + sizeof(GibInt); + + + switch4051: + ; + switch (tag4049) { + + case 0: + { + GibCursor x215126933501 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail4050)->field0; + GibInt x215226943502 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail4050)->field1; + GibCursor x215326953503 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail4050)->field2; + GibCursor x215426963504 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail4050)->field3; + GibCursor x215526973505 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail4050)->field4; + unsigned char y215626983506 = + _traverse_Timestamp179(x215126933501); + unsigned char y215826993507 = + _traverse_Timestamp179(x215326953503); + unsigned char y215927003508 = + _traverse_Timestamp179(x215426963504); + unsigned char y216027013509 = + _traverse_OrderedNode124_v1246(x215526973505); + + return 0; + break; + } + + case 1: + { + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag4049"); + exit(1); + } + } +} +unsigned char _print_OrderedNode124_v1246(GibCursor arg216127023510) +{ + GibPackedTag tag4052 = *(GibPackedTag *) arg216127023510; + GibCursor tail4053 = arg216127023510 + sizeof(GibInt); + + + switch4054: + ; + switch (tag4052) { + + case 0: + { + GibCursor x216227033511 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail4053)->field0; + GibInt x216327043512 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail4053)->field1; + GibCursor x216427053513 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail4053)->field2; + GibCursor x216527063514 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail4053)->field3; + GibCursor x216627073515 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail4053)->field4; + unsigned char wildcard217227083516 = gib_print_symbol(3932); + unsigned char wildcard217827093517 = gib_print_symbol(3933); + unsigned char y216727103518 = _print_Timestamp179(x216227033511); + unsigned char wildcard217727113519 = gib_print_symbol(3933); + unsigned char y216827123520 = printf("%ld", x216327043512); + unsigned char wildcard217627133521 = gib_print_symbol(3933); + unsigned char y216927143522 = _print_Timestamp179(x216427053513); + unsigned char wildcard217527153523 = gib_print_symbol(3933); + unsigned char y217027163524 = _print_Timestamp179(x216527063514); + unsigned char wildcard217427173525 = gib_print_symbol(3933); + unsigned char y217127183526 = + _print_OrderedNode124_v1246(x216627073515); + unsigned char wildcard217327193527 = gib_print_symbol(3917); + + return 0; + break; + } + + case 1: + { + unsigned char wildcard217927203528 = gib_print_symbol(3920); + unsigned char wildcard218027213529 = gib_print_symbol(3917); + + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag4052"); + exit(1); + } + } +} +GibCursor _copy_OrderedList123_v1247(GibCursor arg218127223530) +{ + GibInt tag4055 = ((GibIntGibCursorGibCursorProd *) arg218127223530)->field0; + GibCursor x218227233531 = + ((GibIntGibCursorGibCursorProd *) arg218127223530)->field1; + GibCursor x218327243532 = + ((GibIntGibCursorGibCursorProd *) arg218127223530)->field2; + GibCursor y218427253533 = _copy_Clock178(x218227233531); + GibCursor y218527263534 = _copy_OrderedNode124_v1246(x218327243532); + GibPtr tailift4056 = gib_alloc(sizeof(GibIntGibCursorGibCursorProd)); + + ((GibIntGibCursorGibCursorProd *) tailift4056)->field0 = 0; + ((GibIntGibCursorGibCursorProd *) tailift4056)->field1 = y218427253533; + ((GibIntGibCursorGibCursorProd *) tailift4056)->field2 = y218527263534; + return tailift4056; +} +GibCursor _copy_without_ptrs_OrderedList123_v1247(GibCursor arg218627273535) +{ + GibInt tag4057 = ((GibIntGibCursorGibCursorProd *) arg218627273535)->field0; + GibCursor x218727283536 = + ((GibIntGibCursorGibCursorProd *) arg218627273535)->field1; + GibCursor x218827293537 = + ((GibIntGibCursorGibCursorProd *) arg218627273535)->field2; + GibCursor y218927303538 = _copy_without_ptrs_Clock178(x218727283536); + GibCursor y219027313539 = + _copy_without_ptrs_OrderedNode124_v1246(x218827293537); + GibPtr tailift4058 = gib_alloc(sizeof(GibIntGibCursorGibCursorProd)); + + ((GibIntGibCursorGibCursorProd *) tailift4058)->field0 = 0; + ((GibIntGibCursorGibCursorProd *) tailift4058)->field1 = y218927303538; + ((GibIntGibCursorGibCursorProd *) tailift4058)->field2 = y219027313539; + return tailift4058; +} +unsigned char _traverse_OrderedList123_v1247(GibCursor arg219127323540) +{ + GibInt tag4059 = ((GibIntGibCursorGibCursorProd *) arg219127323540)->field0; + GibCursor x219227333541 = + ((GibIntGibCursorGibCursorProd *) arg219127323540)->field1; + GibCursor x219327343542 = + ((GibIntGibCursorGibCursorProd *) arg219127323540)->field2; + unsigned char y219427353543 = _traverse_Clock178(x219227333541); + unsigned char y219527363544 = + _traverse_OrderedNode124_v1246(x219327343542); + + return 0; +} +unsigned char _print_OrderedList123_v1247(GibCursor arg219627373545) +{ + GibInt tag4060 = ((GibIntGibCursorGibCursorProd *) arg219627373545)->field0; + GibCursor x219727383546 = + ((GibIntGibCursorGibCursorProd *) arg219627373545)->field1; + GibCursor x219827393547 = + ((GibIntGibCursorGibCursorProd *) arg219627373545)->field2; + unsigned char wildcard220127403548 = gib_print_symbol(3922); + unsigned char wildcard220427413549 = gib_print_symbol(3933); + unsigned char y219927423550 = _print_Clock178(x219727383546); + unsigned char wildcard220327433551 = gib_print_symbol(3933); + unsigned char y220027443552 = _print_OrderedNode124_v1246(x219827393547); + unsigned char wildcard220227453553 = gib_print_symbol(3917); + + return 0; +} +GibCursor _copy_Node166_v1253(GibCursor arg220527463554) +{ + GibPackedTag tag4061 = *(GibPackedTag *) arg220527463554; + GibCursor tail4062 = arg220527463554 + sizeof(GibInt); + + + switch4065: + ; + switch (tag4061) { + + case 0: + { + GibPtr tailift4063 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift4063)->field0 = 0; + return tailift4063; + break; + } + + case 1: + { + GibInt x220627473555 = ((GibIntGibCursorProd *) tail4062)->field0; + GibCursor x220727483556 = + ((GibIntGibCursorProd *) tail4062)->field1; + GibCursor y220927503558 = _copy_Node166_v1253(x220727483556); + GibPtr tailift4064 = gib_alloc(sizeof(GibIntGibIntGibCursorProd)); + + ((GibIntGibIntGibCursorProd *) tailift4064)->field0 = 1; + ((GibIntGibIntGibCursorProd *) tailift4064)->field1 = x220627473555; + ((GibIntGibIntGibCursorProd *) tailift4064)->field2 = y220927503558; + return tailift4064; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag4061"); + exit(1); + } + } +} +GibCursor _copy_without_ptrs_Node166_v1253(GibCursor arg221027513559) +{ + GibPackedTag tag4066 = *(GibPackedTag *) arg221027513559; + GibCursor tail4067 = arg221027513559 + sizeof(GibInt); + + + switch4070: + ; + switch (tag4066) { + + case 0: + { + GibPtr tailift4068 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift4068)->field0 = 0; + return tailift4068; + break; + } + + case 1: + { + GibInt x221127523560 = ((GibIntGibCursorProd *) tail4067)->field0; + GibCursor x221227533561 = + ((GibIntGibCursorProd *) tail4067)->field1; + GibCursor y221427553563 = + _copy_without_ptrs_Node166_v1253(x221227533561); + GibPtr tailift4069 = gib_alloc(sizeof(GibIntGibIntGibCursorProd)); + + ((GibIntGibIntGibCursorProd *) tailift4069)->field0 = 1; + ((GibIntGibIntGibCursorProd *) tailift4069)->field1 = x221127523560; + ((GibIntGibIntGibCursorProd *) tailift4069)->field2 = y221427553563; + return tailift4069; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag4066"); + exit(1); + } + } +} +unsigned char _traverse_Node166_v1253(GibCursor arg221527563564) +{ + GibPackedTag tag4071 = *(GibPackedTag *) arg221527563564; + GibCursor tail4072 = arg221527563564 + sizeof(GibInt); + + + switch4073: + ; + switch (tag4071) { + + case 0: + { + return 0; + break; + } + + case 1: + { + GibInt x221627573565 = ((GibIntGibCursorProd *) tail4072)->field0; + GibCursor x221727583566 = + ((GibIntGibCursorProd *) tail4072)->field1; + unsigned char y221927593567 = + _traverse_Node166_v1253(x221727583566); + + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag4071"); + exit(1); + } + } +} +unsigned char _print_Node166_v1253(GibCursor arg222027603568) +{ + GibPackedTag tag4074 = *(GibPackedTag *) arg222027603568; + GibCursor tail4075 = arg222027603568 + sizeof(GibInt); + + + switch4076: + ; + switch (tag4074) { + + case 0: + { + unsigned char wildcard222127613569 = gib_print_symbol(3918); + unsigned char wildcard222227623570 = gib_print_symbol(3917); + + return 0; + break; + } + + case 1: + { + GibInt x222327633571 = ((GibIntGibCursorProd *) tail4075)->field0; + GibCursor x222427643572 = + ((GibIntGibCursorProd *) tail4075)->field1; + unsigned char wildcard222727653573 = gib_print_symbol(3930); + unsigned char wildcard223027663574 = gib_print_symbol(3933); + unsigned char y222527673575 = printf("%ld", x222327633571); + unsigned char wildcard222927683576 = gib_print_symbol(3933); + unsigned char y222627693577 = _print_Node166_v1253(x222427643572); + unsigned char wildcard222827703578 = gib_print_symbol(3917); + + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag4074"); + exit(1); + } + } +} +GibCursor _copy_Maybe155_v1242(GibCursor arg223127713579) +{ + GibPackedTag tag4077 = *(GibPackedTag *) arg223127713579; + GibCursor tail4078 = arg223127713579 + sizeof(GibInt); + + + switch4081: + ; + switch (tag4077) { + + case 0: + { + GibPtr tailift4079 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift4079)->field0 = 0; + return tailift4079; + break; + } + + case 1: + { + GibInt x223227723580 = ((GibIntProd *) tail4078)->field0; + GibPtr tailift4080 = gib_alloc(sizeof(GibIntGibIntProd)); + + ((GibIntGibIntProd *) tailift4080)->field0 = 1; + ((GibIntGibIntProd *) tailift4080)->field1 = x223227723580; + return tailift4080; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag4077"); + exit(1); + } + } +} +GibCursor _copy_without_ptrs_Maybe155_v1242(GibCursor arg223427743582) +{ + GibPackedTag tag4082 = *(GibPackedTag *) arg223427743582; + GibCursor tail4083 = arg223427743582 + sizeof(GibInt); + + + switch4086: + ; + switch (tag4082) { + + case 0: + { + GibPtr tailift4084 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift4084)->field0 = 0; + return tailift4084; + break; + } + + case 1: + { + GibInt x223527753583 = ((GibIntProd *) tail4083)->field0; + GibPtr tailift4085 = gib_alloc(sizeof(GibIntGibIntProd)); + + ((GibIntGibIntProd *) tailift4085)->field0 = 1; + ((GibIntGibIntProd *) tailift4085)->field1 = x223527753583; + return tailift4085; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag4082"); + exit(1); + } + } +} +unsigned char _traverse_Maybe155_v1242(GibCursor arg223727773585) +{ + GibPackedTag tag4087 = *(GibPackedTag *) arg223727773585; + GibCursor tail4088 = arg223727773585 + sizeof(GibInt); + + + switch4089: + ; + switch (tag4087) { + + case 0: + { + return 0; + break; + } + + case 1: + { + GibInt x223827783586 = ((GibIntProd *) tail4088)->field0; + + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag4087"); + exit(1); + } + } +} +unsigned char _print_Maybe155_v1242(GibCursor arg224027793587) +{ + GibPackedTag tag4090 = *(GibPackedTag *) arg224027793587; + GibCursor tail4091 = arg224027793587 + sizeof(GibInt); + + + switch4092: + ; + switch (tag4090) { + + case 0: + { + unsigned char wildcard224127803588 = gib_print_symbol(3923); + unsigned char wildcard224227813589 = gib_print_symbol(3917); + + return 0; + break; + } + + case 1: + { + GibInt x224327823590 = ((GibIntProd *) tail4091)->field0; + unsigned char wildcard224527833591 = gib_print_symbol(3925); + unsigned char wildcard224727843592 = gib_print_symbol(3933); + unsigned char y224427853593 = printf("%ld", x224327823590); + unsigned char wildcard224627863594 = gib_print_symbol(3917); + + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag4090"); + exit(1); + } + } +} +GibCursor _copy_Map151_v1236(GibCursor arg224827873595) +{ + GibPackedTag tag4093 = *(GibPackedTag *) arg224827873595; + GibCursor tail4094 = arg224827873595 + sizeof(GibInt); + + + switch4097: + ; + switch (tag4093) { + + case 0: + { + GibPtr tailift4095 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift4095)->field0 = 0; + return tailift4095; + break; + } + + case 1: + { + GibInt x224927883596 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail4094)->field0; + GibInt x225027893597 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail4094)->field1; + GibInt x225127903598 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail4094)->field2; + GibCursor x225227913599 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail4094)->field3; + GibCursor x225327923600 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail4094)->field4; + GibCursor y225727963604 = _copy_Map151_v1236(x225227913599); + GibCursor y225827973605 = _copy_Map151_v1236(x225327923600); + GibPtr tailift4096 = + gib_alloc(sizeof(GibIntGibIntGibIntGibIntGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift4096)->field0 = + 1; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift4096)->field1 = + x224927883596; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift4096)->field2 = + x225027893597; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift4096)->field3 = + x225127903598; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift4096)->field4 = + y225727963604; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift4096)->field5 = + y225827973605; + return tailift4096; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag4093"); + exit(1); + } + } +} +GibCursor _copy_without_ptrs_Map151_v1236(GibCursor arg225927983606) +{ + GibPackedTag tag4098 = *(GibPackedTag *) arg225927983606; + GibCursor tail4099 = arg225927983606 + sizeof(GibInt); + + + switch4102: + ; + switch (tag4098) { + + case 0: + { + GibPtr tailift4100 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift4100)->field0 = 0; + return tailift4100; + break; + } + + case 1: + { + GibInt x226027993607 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail4099)->field0; + GibInt x226128003608 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail4099)->field1; + GibInt x226228013609 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail4099)->field2; + GibCursor x226328023610 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail4099)->field3; + GibCursor x226428033611 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail4099)->field4; + GibCursor y226828073615 = + _copy_without_ptrs_Map151_v1236(x226328023610); + GibCursor y226928083616 = + _copy_without_ptrs_Map151_v1236(x226428033611); + GibPtr tailift4101 = + gib_alloc(sizeof(GibIntGibIntGibIntGibIntGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift4101)->field0 = + 1; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift4101)->field1 = + x226027993607; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift4101)->field2 = + x226128003608; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift4101)->field3 = + x226228013609; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift4101)->field4 = + y226828073615; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift4101)->field5 = + y226928083616; + return tailift4101; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag4098"); + exit(1); + } + } +} +unsigned char _traverse_Map151_v1236(GibCursor arg227028093617) +{ + GibPackedTag tag4103 = *(GibPackedTag *) arg227028093617; + GibCursor tail4104 = arg227028093617 + sizeof(GibInt); + + + switch4105: + ; + switch (tag4103) { + + case 0: + { + return 0; + break; + } + + case 1: + { + GibInt x227128103618 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail4104)->field0; + GibInt x227228113619 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail4104)->field1; + GibInt x227328123620 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail4104)->field2; + GibCursor x227428133621 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail4104)->field3; + GibCursor x227528143622 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail4104)->field4; + unsigned char y227928153623 = + _traverse_Map151_v1236(x227428133621); + unsigned char y228028163624 = + _traverse_Map151_v1236(x227528143622); + + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag4103"); + exit(1); + } + } +} +unsigned char _print_Map151_v1236(GibCursor arg228128173625) +{ + GibPackedTag tag4106 = *(GibPackedTag *) arg228128173625; + GibCursor tail4107 = arg228128173625 + sizeof(GibInt); + + + switch4108: + ; + switch (tag4106) { + + case 0: + { + unsigned char wildcard228228183626 = gib_print_symbol(3919); + unsigned char wildcard228328193627 = gib_print_symbol(3917); + + return 0; + break; + } + + case 1: + { + GibInt x228428203628 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail4107)->field0; + GibInt x228528213629 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail4107)->field1; + GibInt x228628223630 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail4107)->field2; + GibCursor x228728233631 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail4107)->field3; + GibCursor x228828243632 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail4107)->field4; + unsigned char wildcard229428253633 = gib_print_symbol(3931); + unsigned char wildcard230028263634 = gib_print_symbol(3933); + unsigned char y228928273635 = printf("%ld", x228428203628); + unsigned char wildcard229928283636 = gib_print_symbol(3933); + unsigned char y229028293637 = printf("%ld", x228528213629); + unsigned char wildcard229828303638 = gib_print_symbol(3933); + unsigned char y229128313639 = printf("%ld", x228628223630); + unsigned char wildcard229728323640 = gib_print_symbol(3933); + unsigned char y229228333641 = _print_Map151_v1236(x228728233631); + unsigned char wildcard229628343642 = gib_print_symbol(3933); + unsigned char y229328353643 = _print_Map151_v1236(x228828243632); + unsigned char wildcard229528363644 = gib_print_symbol(3917); + + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag4106"); + exit(1); + } + } +} +GibCursor caseFn2304(GibCursor b277230528413645) +{ + GibCursor fltCse30663646 = clockmap173(b277230528413645); + GibPackedTag tag4109 = *(GibPackedTag *) fltCse30663646; + GibCursor tail4110 = fltCse30663646 + sizeof(GibInt); + + + switch4113: + ; + switch (tag4109) { + + case 0: + { + GibPtr tailift4111 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift4111)->field0 = 2; + return tailift4111; + break; + } + + case 1: + { + GibInt wildcard_4227828423647 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail4110)->field0; + GibInt wildcard_4327928433648 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail4110)->field1; + GibInt wildcard_4428028443649 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail4110)->field2; + GibCursor wildcard_4528128453650 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail4110)->field3; + GibCursor wildcard_4628228463651 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail4110)->field4; + GibPtr tailift4112 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift4112)->field0 = 0; + return tailift4112; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag4109"); + exit(1); + } + } +} +GibCursor caseFn2306(GibCursor b277230728473652, GibInt k293230828483653) +{ + GibCursor fltCse30673654 = lookup174(k293230828483653, b277230728473652); + GibPackedTag tag4114 = *(GibPackedTag *) fltCse30673654; + GibCursor tail4115 = fltCse30673654 + sizeof(GibInt); + + + switch4118: + ; + switch (tag4114) { + + case 0: + { + GibPtr tailift4116 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift4116)->field0 = 2; + return tailift4116; + break; + } + + case 1: + { + GibInt wildcard_7429428493655 = ((GibIntProd *) tail4115)->field0; + GibPtr tailift4117 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift4117)->field0 = 0; + return tailift4117; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag4114"); + exit(1); + } + } +} +GibCursor caseFn2309(GibCursor b277231028503656, GibInt k293231128513657, + GibInt ax295231228523658) +{ + GibCursor fltCse30683659 = lookup174(k293231128513657, b277231028503656); + GibPackedTag tag4119 = *(GibPackedTag *) fltCse30683659; + GibCursor tail4120 = fltCse30683659 + sizeof(GibInt); + + + switch4122: + ; + switch (tag4119) { + + case 0: + { + GibPtr tailift4121 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift4121)->field0 = 1; + return tailift4121; + break; + } + + case 1: + { + GibInt bx29628533660 = ((GibIntProd *) tail4120)->field0; + + return compareInt154(ax295231228523658, bx29628533660); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag4119"); + exit(1); + } + } +} +GibCursor caseFn2313(GibCursor a276231428543661, GibCursor b277231528553662, + GibInt k293231628563663) +{ + GibCursor fltCse30693664 = lookup174(k293231628563663, a276231428543661); + GibPackedTag tag4123 = *(GibPackedTag *) fltCse30693664; + GibCursor tail4124 = fltCse30693664 + sizeof(GibInt); + + + switch4125: + ; + switch (tag4123) { + + case 0: + { + return caseFn2306(b277231528553662, k293231628563663); + break; + } + + case 1: + { + GibInt ax29528573665 = ((GibIntProd *) tail4124)->field0; + + return caseFn2309(b277231528553662, k293231628563663, + ax29528573665); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag4123"); + exit(1); + } + } +} +GibCursor caseFn2317(GibCursor diff297231828583666) +{ + GibPackedTag tag4126 = *(GibPackedTag *) diff297231828583666; + GibCursor tail4127 = diff297231828583666 + sizeof(GibInt); + + + switch4132: + ; + switch (tag4126) { + + case 0: + { + GibPtr tailift4128 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift4128)->field0 = 0; + return tailift4128; + break; + } + + case 2: + { + GibPtr tailift4129 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift4129)->field0 = 0; + return tailift4129; + break; + } + + case 1: + { + GibPtr tailift4130 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift4130)->field0 = 3; + return tailift4130; + break; + } + + case 3: + { + GibPtr tailift4131 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift4131)->field0 = 3; + return tailift4131; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag4126"); + exit(1); + } + } +} +GibCursor caseFn2319(GibCursor diff297232028593667) +{ + GibPackedTag tag4133 = *(GibPackedTag *) diff297232028593667; + GibCursor tail4134 = diff297232028593667 + sizeof(GibInt); + + + switch4139: + ; + switch (tag4133) { + + case 1: + { + GibPtr tailift4135 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift4135)->field0 = 1; + return tailift4135; + break; + } + + case 2: + { + GibPtr tailift4136 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift4136)->field0 = 1; + return tailift4136; + break; + } + + case 0: + { + GibPtr tailift4137 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift4137)->field0 = 3; + return tailift4137; + break; + } + + case 3: + { + GibPtr tailift4138 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift4138)->field0 = 3; + return tailift4138; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag4133"); + exit(1); + } + } +} +GibCursor caseFn2321(GibCursor diff297232228603668) +{ + GibPackedTag tag4140 = *(GibPackedTag *) diff297232228603668; + GibCursor tail4141 = diff297232228603668 + sizeof(GibInt); + + + switch4146: + ; + switch (tag4140) { + + case 2: + { + GibPtr tailift4142 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift4142)->field0 = 2; + return tailift4142; + break; + } + + case 0: + { + GibPtr tailift4143 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift4143)->field0 = 3; + return tailift4143; + break; + } + + case 1: + { + GibPtr tailift4144 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift4144)->field0 = 3; + return tailift4144; + break; + } + + case 3: + { + GibPtr tailift4145 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift4145)->field0 = 3; + return tailift4145; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag4140"); + exit(1); + } + } +} +GibCursor caseFn2323(GibCursor diff297232428613669) +{ + GibPackedTag tag4147 = *(GibPackedTag *) diff297232428613669; + GibCursor tail4148 = diff297232428613669 + sizeof(GibInt); + + + switch4150: + ; + switch (tag4147) { + + case 0: + { + return caseFn2317(diff297232428613669); + break; + } + + case 1: + { + return caseFn2319(diff297232428613669); + break; + } + + case 2: + { + return caseFn2321(diff297232428613669); + break; + } + + case 3: + { + GibPtr tailift4149 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift4149)->field0 = 3; + return tailift4149; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag4147"); + exit(1); + } + } +} +GibCursor caseFn2325(GibCursor a276232628623670, GibCursor b277232728633671) +{ + GibCursor fltCse30703672 = clockmap173(b277232728633671); + GibPackedTag tag4151 = *(GibPackedTag *) fltCse30703672; + GibCursor tail4152 = fltCse30703672 + sizeof(GibInt); + + + switch4154: + ; + switch (tag4151) { + + case 0: + { + GibPtr tailift4153 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift4153)->field0 = 1; + return tailift4153; + break; + } + + case 1: + { + GibInt wildcard_5928828643673 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail4152)->field0; + GibInt wildcard_6028928653674 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail4152)->field1; + GibInt wildcard_6129028663675 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail4152)->field2; + GibCursor wildcard_6229128673676 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail4152)->field3; + GibCursor wildcard_6329228683677 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail4152)->field4; + GibCursor fltAppE30713678 = clockmap173(a276232628623670); + GibInt k29328693679 = key1481241(fltAppE30713678); + GibCursor diff29728703680 = + caseFn2313(a276232628623670, b277232728633671, k29328693679); + + return caseFn2323(diff29728703680); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag4151"); + exit(1); + } + } +} +GibCursor caseFn2328(GibInt uid300232928713681, GibCursor clk301233028723682, + GibInt v302233128733683) +{ + GibInt tag4155 = ((GibIntGibIntGibCursorProd *) clk301233028723682)->field0; + GibInt wildcard_2730328743684 = + ((GibIntGibIntGibCursorProd *) clk301233028723682)->field1; + GibCursor m30428753685 = + ((GibIntGibIntGibCursorProd *) clk301233028723682)->field2; + GibInt fltAppE30733686 = v302233128733683 + 1; + GibCursor fltPkd30723687 = + insert1281243(uid300232928713681, fltAppE30733686, m30428753685); + GibPtr tailift4156 = gib_alloc(sizeof(GibIntGibIntGibCursorProd)); + + ((GibIntGibIntGibCursorProd *) tailift4156)->field0 = 0; + ((GibIntGibIntGibCursorProd *) tailift4156)->field1 = 0; + ((GibIntGibIntGibCursorProd *) tailift4156)->field2 = fltPkd30723687; + return tailift4156; +} +GibCursor caseFn2332(GibInt uid300233328763688, GibCursor clk301233428773689) +{ + GibInt tag4157 = ((GibIntGibIntGibCursorProd *) clk301233428773689)->field0; + GibInt wildcard_3230528783690 = + ((GibIntGibIntGibCursorProd *) clk301233428773689)->field1; + GibCursor m30628793691 = + ((GibIntGibIntGibCursorProd *) clk301233428773689)->field2; + GibCursor fltPkd30743692 = + insert1281243(uid300233328763688, 1, m30628793691); + GibPtr tailift4158 = gib_alloc(sizeof(GibIntGibIntGibCursorProd)); + + ((GibIntGibIntGibCursorProd *) tailift4158)->field0 = 0; + ((GibIntGibIntGibCursorProd *) tailift4158)->field1 = 0; + ((GibIntGibIntGibCursorProd *) tailift4158)->field2 = fltPkd30743692; + return tailift4158; +} +GibCursor caseFn2335(GibInt i217233628803693, GibCursor n224233728813694, + GibCursor t220233828823695) +{ + GibPackedTag tag4159 = *(GibPackedTag *) n224233728813694; + GibCursor tail4160 = n224233728813694 + sizeof(GibInt); + + + switch4161: + ; + switch (tag4159) { + + case 1: + { + return t220233828823695; + break; + } + + case 0: + { + GibCursor wildcard54128833696 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail4160)->field0; + GibInt wildcard54228843697 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail4160)->field1; + GibCursor wildcard54328853698 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail4160)->field2; + GibCursor wildcard54428863699 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail4160)->field3; + GibCursor wildcard54528873700 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail4160)->field4; + GibBool fltIf30753701 = i217233628803693 == 0; + + if (fltIf30753701) { + return t220233828823695; + } else { + GibInt fltAppE30763702 = i217233628803693 - 1; + + return cursor_1151249(fltAppE30763702, n224233728813694); + } + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag4159"); + exit(1); + } + } +} +GibCursor caseFn2339(GibInt k1379234028883703, GibInt x1380234128893704, + GibCursor t1381234228903705, GibCursor m1387234328913706, + GibInt k2385234428923707, GibInt x2386234528933708, + GibCursor t4388234628943709) +{ + GibPackedTag tag4162 = *(GibPackedTag *) m1387234328913706; + GibCursor tail4163 = m1387234328913706 + sizeof(GibInt); + + + switch4164: + ; + switch (tag4162) { + + case 1: + { + GibInt wildcard_18038928953710 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail4163)->field0; + GibInt k339028963711 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail4163)->field1; + GibInt x339128973712 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail4163)->field2; + GibCursor t239228983713 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail4163)->field3; + GibCursor t339328993714 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail4163)->field4; + GibCursor fltAppE30773715 = + bin1371263(k1379234028883703, x1380234128893704, t1381234228903705, t239228983713); + GibCursor fltAppE30783716 = + bin1371263(k2385234428923707, x2386234528933708, t339328993714, t4388234628943709); + + return bin1371263(k339028963711, x339128973712, fltAppE30773715, + fltAppE30783716); + break; + } + + case 0: + { + return empty1311262(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag4162"); + exit(1); + } + } +} +GibCursor caseFn2347(GibInt k1364234829003717, GibInt x1365234929013718, + GibCursor t4367235029023719, GibCursor m1373235129033720, + GibInt k2370235229043721, GibInt x2371235329053722, + GibCursor t1372235429063723) +{ + GibPackedTag tag4165 = *(GibPackedTag *) m1373235129033720; + GibCursor tail4166 = m1373235129033720 + sizeof(GibInt); + + + switch4167: + ; + switch (tag4165) { + + case 1: + { + GibInt wildcard_19637429073724 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail4166)->field0; + GibInt k337529083725 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail4166)->field1; + GibInt x337629093726 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail4166)->field2; + GibCursor t237729103727 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail4166)->field3; + GibCursor t337829113728 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail4166)->field4; + GibCursor fltAppE30793729 = + bin1371263(k2370235229043721, x2371235329053722, t1372235429063723, t237729103727); + GibCursor fltAppE30803730 = + bin1371263(k1364234829003717, x1365234929013718, t337829113728, t4367235029023719); + + return bin1371263(k337529083725, x337629093726, fltAppE30793729, + fltAppE30803730); + break; + } + + case 0: + { + return empty1311262(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag4165"); + exit(1); + } + } +} +GibCursor caseFn2355(GibCursor x240235629123731, GibCursor acc241235729133732, + GibCursor tx243235829143733, GibInt vx244235929153734, + GibCursor lx245236029163735, GibCursor rx246236129173736) +{ + GibPackedTag tag4168 = *(GibPackedTag *) acc241235729133732; + GibCursor tail4169 = acc241235729133732 + sizeof(GibInt); + + + switch4171: + ; + switch (tag4168) { + + case 1: + { + return x240235629123731; + break; + } + + case 0: + { + GibCursor tacc24829183737 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail4169)->field0; + GibInt vacc24929193738 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail4169)->field1; + GibCursor lacc25029203739 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail4169)->field2; + GibCursor racc25129213740 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail4169)->field3; + GibCursor nacc25229223741 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail4169)->field4; + GibPtr fltPkd30813742 = + gib_alloc(sizeof(GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd)); + + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd30813742)->field0 = + 0; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd30813742)->field1 = + tx243235829143733; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd30813742)->field2 = + vx244235929153734; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd30813742)->field3 = + lx245236029163735; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd30813742)->field4 = + rx246236129173736; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd30813742)->field5 = + nacc25229223741; + + GibPtr tailift4170 = + gib_alloc(sizeof(GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd)); + + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4170)->field0 = + 0; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4170)->field1 = + tacc24829183737; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4170)->field2 = + vacc24929193738; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4170)->field3 = + lacc25029203739; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4170)->field4 = + racc25129213740; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4170)->field5 = + fltPkd30813742; + return tailift4170; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag4168"); + exit(1); + } + } +} +GibCursor caseFn2362(GibInt uid225236329233743, GibCursor clk226236429243744, + GibInt x227236529253745, GibCursor l229236629263746, + GibCursor r230236729273747, GibCursor t235236829283748, + GibInt v236236929293749, GibCursor n239237029303750) +{ + GibCursor fltAppE30833751 = clock177(t235236829283748); + GibCursor fltAppE30843752 = clock177(l229236629263746); + GibCursor fltCse30823753 = compare170(fltAppE30833751, fltAppE30843752); + GibPackedTag tag4172 = *(GibPackedTag *) fltCse30823753; + GibCursor tail4173 = fltCse30823753 + sizeof(GibInt); + + + switch4181: + ; + switch (tag4172) { + + case 2: + { + GibCursor fltAppE30873754 = clock177(clk226236429243744); + GibCursor fltPkd30863755 = + stamp171(uid225236329233743, fltAppE30873754); + GibCursor fltPkd30883756 = + place1161251(uid225236329233743, clk226236429243744, x227236529253745, n239237029303750, l229236629263746, r230236729273747); + GibPtr fltPkd30853757 = + gib_alloc(sizeof(GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd)); + + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd30853757)->field0 = + 0; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd30853757)->field1 = + fltPkd30863755; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd30853757)->field2 = + x227236529253745; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd30853757)->field3 = + l229236629263746; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd30853757)->field4 = + r230236729273747; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd30853757)->field5 = + fltPkd30883756; + + GibPtr tailift4174 = + gib_alloc(sizeof(GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd)); + + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4174)->field0 = + 0; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4174)->field1 = + t235236829283748; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4174)->field2 = + v236236929293749; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4174)->field3 = + l229236629263746; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4174)->field4 = + r230236729273747; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4174)->field5 = + fltPkd30853757; + return tailift4174; + break; + } + + case 0: + { + GibInt fltPrm30903758 = author176(t235236829283748); + GibBool fltIf30893759 = uid225236329233743 < fltPrm30903758; + + if (fltIf30893759) { + GibCursor fltPkd30913760 = + place1161251(uid225236329233743, clk226236429243744, x227236529253745, n239237029303750, l229236629263746, r230236729273747); + GibPtr tailift4175 = + gib_alloc(sizeof(GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd)); + + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4175)->field0 = + 0; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4175)->field1 = + t235236829283748; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4175)->field2 = + v236236929293749; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4175)->field3 = + l229236629263746; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4175)->field4 = + r230236729273747; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4175)->field5 = + fltPkd30913760; + return tailift4175; + } else { + GibCursor fltAppE30943761 = clock177(clk226236429243744); + GibCursor fltPkd30933762 = + stamp171(uid225236329233743, fltAppE30943761); + GibCursor fltPkd30953763 = + place1161251(uid225236329233743, clk226236429243744, x227236529253745, n239237029303750, l229236629263746, r230236729273747); + GibPtr fltPkd30923764 = + gib_alloc(sizeof(GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd)); + + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd30923764)->field0 = + 0; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd30923764)->field1 = + fltPkd30933762; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd30923764)->field2 = + x227236529253745; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd30923764)->field3 = + l229236629263746; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd30923764)->field4 = + r230236729273747; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd30923764)->field5 = + fltPkd30953763; + + GibPtr tailift4176 = + gib_alloc(sizeof(GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd)); + + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4176)->field0 = + 0; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4176)->field1 = + t235236829283748; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4176)->field2 = + v236236929293749; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4176)->field3 = + l229236629263746; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4176)->field4 = + r230236729273747; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4176)->field5 = + fltPkd30923764; + return tailift4176; + } + break; + } + + case 1: + { + GibInt fltPrm30973765 = author176(t235236829283748); + GibBool fltIf30963766 = uid225236329233743 < fltPrm30973765; + + if (fltIf30963766) { + GibCursor fltPkd30983767 = + place1161251(uid225236329233743, clk226236429243744, x227236529253745, n239237029303750, l229236629263746, r230236729273747); + GibPtr tailift4177 = + gib_alloc(sizeof(GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd)); + + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4177)->field0 = + 0; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4177)->field1 = + t235236829283748; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4177)->field2 = + v236236929293749; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4177)->field3 = + l229236629263746; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4177)->field4 = + r230236729273747; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4177)->field5 = + fltPkd30983767; + return tailift4177; + } else { + GibCursor fltAppE31013768 = clock177(clk226236429243744); + GibCursor fltPkd31003769 = + stamp171(uid225236329233743, fltAppE31013768); + GibCursor fltPkd31023770 = + place1161251(uid225236329233743, clk226236429243744, x227236529253745, n239237029303750, l229236629263746, r230236729273747); + GibPtr fltPkd30993771 = + gib_alloc(sizeof(GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd)); + + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd30993771)->field0 = + 0; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd30993771)->field1 = + fltPkd31003769; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd30993771)->field2 = + x227236529253745; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd30993771)->field3 = + l229236629263746; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd30993771)->field4 = + r230236729273747; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd30993771)->field5 = + fltPkd31023770; + + GibPtr tailift4178 = + gib_alloc(sizeof(GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd)); + + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4178)->field0 = + 0; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4178)->field1 = + t235236829283748; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4178)->field2 = + v236236929293749; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4178)->field3 = + l229236629263746; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4178)->field4 = + r230236729273747; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4178)->field5 = + fltPkd30993771; + return tailift4178; + } + break; + } + + case 3: + { + GibInt fltPrm31043772 = author176(t235236829283748); + GibBool fltIf31033773 = uid225236329233743 < fltPrm31043772; + + if (fltIf31033773) { + GibCursor fltPkd31053774 = + place1161251(uid225236329233743, clk226236429243744, x227236529253745, n239237029303750, l229236629263746, r230236729273747); + GibPtr tailift4179 = + gib_alloc(sizeof(GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd)); + + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4179)->field0 = + 0; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4179)->field1 = + t235236829283748; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4179)->field2 = + v236236929293749; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4179)->field3 = + l229236629263746; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4179)->field4 = + r230236729273747; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4179)->field5 = + fltPkd31053774; + return tailift4179; + } else { + GibCursor fltAppE31083775 = clock177(clk226236429243744); + GibCursor fltPkd31073776 = + stamp171(uid225236329233743, fltAppE31083775); + GibCursor fltPkd31093777 = + place1161251(uid225236329233743, clk226236429243744, x227236529253745, n239237029303750, l229236629263746, r230236729273747); + GibPtr fltPkd31063778 = + gib_alloc(sizeof(GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd)); + + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd31063778)->field0 = + 0; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd31063778)->field1 = + fltPkd31073776; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd31063778)->field2 = + x227236529253745; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd31063778)->field3 = + l229236629263746; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd31063778)->field4 = + r230236729273747; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd31063778)->field5 = + fltPkd31093777; + + GibPtr tailift4180 = + gib_alloc(sizeof(GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd)); + + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4180)->field0 = + 0; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4180)->field1 = + t235236829283748; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4180)->field2 = + v236236929293749; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4180)->field3 = + l229236629263746; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4180)->field4 = + r230236729273747; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4180)->field5 = + fltPkd31063778; + return tailift4180; + } + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag4172"); + exit(1); + } + } +} +GibCursor caseFn2371(GibInt uid225237229313779, GibCursor clk226237329323780, + GibInt x227237429333781, GibCursor s228237529343782, + GibCursor l229237629353783, GibCursor r230237729363784, + GibCursor t232237829373785) +{ + GibPackedTag tag4182 = *(GibPackedTag *) s228237529343782; + GibCursor tail4183 = s228237529343782 + sizeof(GibInt); + + + switch4184: + ; + switch (tag4182) { + + case 1: + { + GibPtr fltPkd31113786 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) fltPkd31113786)->field0 = 1; + + GibPtr fltAppE31103787 = + gib_alloc(sizeof(GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd)); + + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltAppE31103787)->field0 = + 0; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltAppE31103787)->field1 = + t232237829373785; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltAppE31103787)->field2 = + x227237429333781; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltAppE31103787)->field3 = + l229237629353783; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltAppE31103787)->field4 = + r230237729363784; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltAppE31103787)->field5 = + fltPkd31113786; + return place_1171255(fltAppE31103787, s228237529343782); + break; + } + + case 0: + { + GibCursor t23529383788 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail4183)->field0; + GibInt v23629393789 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail4183)->field1; + GibCursor ls23729403790 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail4183)->field2; + GibCursor rs23829413791 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail4183)->field3; + GibCursor n23929423792 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail4183)->field4; + + return caseFn2362(uid225237229313779, clk226237329323780, + x227237429333781, l229237629353783, + r230237729363784, t23529383788, v23629393789, + n23929423792); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag4182"); + exit(1); + } + } +} +GibCursor caseFn2379(GibInt uid225238029433793, GibCursor clk226238129443794, + GibInt x227238229453795, GibCursor l229238329463796, + GibCursor r230238429473797, GibCursor t235238529483798, + GibInt v236238629493799, GibCursor n239238729503800) +{ + GibCursor fltAppE31133801 = clock177(t235238529483798); + GibCursor fltAppE31143802 = clock177(l229238329463796); + GibCursor fltCse31123803 = compare170(fltAppE31133801, fltAppE31143802); + GibPackedTag tag4185 = *(GibPackedTag *) fltCse31123803; + GibCursor tail4186 = fltCse31123803 + sizeof(GibInt); + + + switch4194: + ; + switch (tag4185) { + + case 2: + { + GibCursor fltAppE31173804 = clock177(clk226238129443794); + GibCursor fltPkd31163805 = + stamp171(uid225238029433793, fltAppE31173804); + GibCursor fltPkd31183806 = + place1161251(uid225238029433793, clk226238129443794, x227238229453795, n239238729503800, l229238329463796, r230238429473797); + GibPtr fltPkd31153807 = + gib_alloc(sizeof(GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd)); + + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd31153807)->field0 = + 0; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd31153807)->field1 = + fltPkd31163805; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd31153807)->field2 = + x227238229453795; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd31153807)->field3 = + l229238329463796; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd31153807)->field4 = + r230238429473797; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd31153807)->field5 = + fltPkd31183806; + + GibPtr tailift4187 = + gib_alloc(sizeof(GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd)); + + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4187)->field0 = + 0; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4187)->field1 = + t235238529483798; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4187)->field2 = + v236238629493799; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4187)->field3 = + l229238329463796; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4187)->field4 = + r230238429473797; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4187)->field5 = + fltPkd31153807; + return tailift4187; + break; + } + + case 0: + { + GibInt fltPrm31203808 = author176(t235238529483798); + GibBool fltIf31193809 = uid225238029433793 < fltPrm31203808; + + if (fltIf31193809) { + GibCursor fltPkd31213810 = + place1161251(uid225238029433793, clk226238129443794, x227238229453795, n239238729503800, l229238329463796, r230238429473797); + GibPtr tailift4188 = + gib_alloc(sizeof(GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd)); + + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4188)->field0 = + 0; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4188)->field1 = + t235238529483798; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4188)->field2 = + v236238629493799; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4188)->field3 = + l229238329463796; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4188)->field4 = + r230238429473797; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4188)->field5 = + fltPkd31213810; + return tailift4188; + } else { + GibCursor fltAppE31243811 = clock177(clk226238129443794); + GibCursor fltPkd31233812 = + stamp171(uid225238029433793, fltAppE31243811); + GibCursor fltPkd31253813 = + place1161251(uid225238029433793, clk226238129443794, x227238229453795, n239238729503800, l229238329463796, r230238429473797); + GibPtr fltPkd31223814 = + gib_alloc(sizeof(GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd)); + + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd31223814)->field0 = + 0; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd31223814)->field1 = + fltPkd31233812; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd31223814)->field2 = + x227238229453795; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd31223814)->field3 = + l229238329463796; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd31223814)->field4 = + r230238429473797; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd31223814)->field5 = + fltPkd31253813; + + GibPtr tailift4189 = + gib_alloc(sizeof(GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd)); + + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4189)->field0 = + 0; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4189)->field1 = + t235238529483798; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4189)->field2 = + v236238629493799; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4189)->field3 = + l229238329463796; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4189)->field4 = + r230238429473797; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4189)->field5 = + fltPkd31223814; + return tailift4189; + } + break; + } + + case 1: + { + GibInt fltPrm31273815 = author176(t235238529483798); + GibBool fltIf31263816 = uid225238029433793 < fltPrm31273815; + + if (fltIf31263816) { + GibCursor fltPkd31283817 = + place1161251(uid225238029433793, clk226238129443794, x227238229453795, n239238729503800, l229238329463796, r230238429473797); + GibPtr tailift4190 = + gib_alloc(sizeof(GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd)); + + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4190)->field0 = + 0; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4190)->field1 = + t235238529483798; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4190)->field2 = + v236238629493799; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4190)->field3 = + l229238329463796; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4190)->field4 = + r230238429473797; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4190)->field5 = + fltPkd31283817; + return tailift4190; + } else { + GibCursor fltAppE31313818 = clock177(clk226238129443794); + GibCursor fltPkd31303819 = + stamp171(uid225238029433793, fltAppE31313818); + GibCursor fltPkd31323820 = + place1161251(uid225238029433793, clk226238129443794, x227238229453795, n239238729503800, l229238329463796, r230238429473797); + GibPtr fltPkd31293821 = + gib_alloc(sizeof(GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd)); + + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd31293821)->field0 = + 0; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd31293821)->field1 = + fltPkd31303819; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd31293821)->field2 = + x227238229453795; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd31293821)->field3 = + l229238329463796; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd31293821)->field4 = + r230238429473797; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd31293821)->field5 = + fltPkd31323820; + + GibPtr tailift4191 = + gib_alloc(sizeof(GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd)); + + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4191)->field0 = + 0; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4191)->field1 = + t235238529483798; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4191)->field2 = + v236238629493799; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4191)->field3 = + l229238329463796; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4191)->field4 = + r230238429473797; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4191)->field5 = + fltPkd31293821; + return tailift4191; + } + break; + } + + case 3: + { + GibInt fltPrm31343822 = author176(t235238529483798); + GibBool fltIf31333823 = uid225238029433793 < fltPrm31343822; + + if (fltIf31333823) { + GibCursor fltPkd31353824 = + place1161251(uid225238029433793, clk226238129443794, x227238229453795, n239238729503800, l229238329463796, r230238429473797); + GibPtr tailift4192 = + gib_alloc(sizeof(GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd)); + + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4192)->field0 = + 0; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4192)->field1 = + t235238529483798; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4192)->field2 = + v236238629493799; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4192)->field3 = + l229238329463796; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4192)->field4 = + r230238429473797; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4192)->field5 = + fltPkd31353824; + return tailift4192; + } else { + GibCursor fltAppE31383825 = clock177(clk226238129443794); + GibCursor fltPkd31373826 = + stamp171(uid225238029433793, fltAppE31383825); + GibCursor fltPkd31393827 = + place1161251(uid225238029433793, clk226238129443794, x227238229453795, n239238729503800, l229238329463796, r230238429473797); + GibPtr fltPkd31363828 = + gib_alloc(sizeof(GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd)); + + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd31363828)->field0 = + 0; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd31363828)->field1 = + fltPkd31373826; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd31363828)->field2 = + x227238229453795; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd31363828)->field3 = + l229238329463796; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd31363828)->field4 = + r230238429473797; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd31363828)->field5 = + fltPkd31393827; + + GibPtr tailift4193 = + gib_alloc(sizeof(GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd)); + + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4193)->field0 = + 0; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4193)->field1 = + t235238529483798; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4193)->field2 = + v236238629493799; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4193)->field3 = + l229238329463796; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4193)->field4 = + r230238429473797; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4193)->field5 = + fltPkd31363828; + return tailift4193; + } + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag4185"); + exit(1); + } + } +} +GibCursor caseFn2388(GibInt uid225238929513829, GibCursor clk226239029523830, + GibInt x227239129533831, GibCursor s228239229543832, + GibCursor l229239329553833, GibCursor r230239429563834, + GibCursor t232239529573835) +{ + GibPackedTag tag4195 = *(GibPackedTag *) s228239229543832; + GibCursor tail4196 = s228239229543832 + sizeof(GibInt); + + + switch4197: + ; + switch (tag4195) { + + case 1: + { + GibPtr fltPkd31413836 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) fltPkd31413836)->field0 = 1; + + GibPtr fltAppE31403837 = + gib_alloc(sizeof(GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd)); + + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltAppE31403837)->field0 = + 0; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltAppE31403837)->field1 = + t232239529573835; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltAppE31403837)->field2 = + x227239129533831; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltAppE31403837)->field3 = + l229239329553833; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltAppE31403837)->field4 = + r230239429563834; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltAppE31403837)->field5 = + fltPkd31413836; + return place_1171255(fltAppE31403837, s228239229543832); + break; + } + + case 0: + { + GibCursor t23529583838 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail4196)->field0; + GibInt v23629593839 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail4196)->field1; + GibCursor ls23729603840 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail4196)->field2; + GibCursor rs23829613841 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail4196)->field3; + GibCursor n23929623842 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail4196)->field4; + + return caseFn2379(uid225238929513829, clk226239029523830, + x227239129533831, l229239329553833, + r230239429563834, t23529583838, v23629593839, + n23929623842); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag4195"); + exit(1); + } + } +} +GibCursor caseFn2396(GibInt uid225239729633843, GibCursor clk226239829643844, + GibInt x227239929653845, GibCursor l229240029663846, + GibCursor r230240129673847, GibCursor t235240229683848, + GibInt v236240329693849, GibCursor n239240429703850) +{ + GibCursor fltAppE31433851 = clock177(t235240229683848); + GibCursor fltAppE31443852 = clock177(l229240029663846); + GibCursor fltCse31423853 = compare170(fltAppE31433851, fltAppE31443852); + GibPackedTag tag4198 = *(GibPackedTag *) fltCse31423853; + GibCursor tail4199 = fltCse31423853 + sizeof(GibInt); + + + switch4207: + ; + switch (tag4198) { + + case 2: + { + GibCursor fltAppE31473854 = clock177(clk226239829643844); + GibCursor fltPkd31463855 = + stamp171(uid225239729633843, fltAppE31473854); + GibCursor fltPkd31483856 = + place1161251(uid225239729633843, clk226239829643844, x227239929653845, n239240429703850, l229240029663846, r230240129673847); + GibPtr fltPkd31453857 = + gib_alloc(sizeof(GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd)); + + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd31453857)->field0 = + 0; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd31453857)->field1 = + fltPkd31463855; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd31453857)->field2 = + x227239929653845; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd31453857)->field3 = + l229240029663846; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd31453857)->field4 = + r230240129673847; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd31453857)->field5 = + fltPkd31483856; + + GibPtr tailift4200 = + gib_alloc(sizeof(GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd)); + + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4200)->field0 = + 0; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4200)->field1 = + t235240229683848; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4200)->field2 = + v236240329693849; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4200)->field3 = + l229240029663846; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4200)->field4 = + r230240129673847; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4200)->field5 = + fltPkd31453857; + return tailift4200; + break; + } + + case 0: + { + GibInt fltPrm31503858 = author176(t235240229683848); + GibBool fltIf31493859 = uid225239729633843 < fltPrm31503858; + + if (fltIf31493859) { + GibCursor fltPkd31513860 = + place1161251(uid225239729633843, clk226239829643844, x227239929653845, n239240429703850, l229240029663846, r230240129673847); + GibPtr tailift4201 = + gib_alloc(sizeof(GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd)); + + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4201)->field0 = + 0; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4201)->field1 = + t235240229683848; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4201)->field2 = + v236240329693849; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4201)->field3 = + l229240029663846; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4201)->field4 = + r230240129673847; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4201)->field5 = + fltPkd31513860; + return tailift4201; + } else { + GibCursor fltAppE31543861 = clock177(clk226239829643844); + GibCursor fltPkd31533862 = + stamp171(uid225239729633843, fltAppE31543861); + GibCursor fltPkd31553863 = + place1161251(uid225239729633843, clk226239829643844, x227239929653845, n239240429703850, l229240029663846, r230240129673847); + GibPtr fltPkd31523864 = + gib_alloc(sizeof(GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd)); + + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd31523864)->field0 = + 0; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd31523864)->field1 = + fltPkd31533862; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd31523864)->field2 = + x227239929653845; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd31523864)->field3 = + l229240029663846; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd31523864)->field4 = + r230240129673847; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd31523864)->field5 = + fltPkd31553863; + + GibPtr tailift4202 = + gib_alloc(sizeof(GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd)); + + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4202)->field0 = + 0; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4202)->field1 = + t235240229683848; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4202)->field2 = + v236240329693849; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4202)->field3 = + l229240029663846; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4202)->field4 = + r230240129673847; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4202)->field5 = + fltPkd31523864; + return tailift4202; + } + break; + } + + case 1: + { + GibInt fltPrm31573865 = author176(t235240229683848); + GibBool fltIf31563866 = uid225239729633843 < fltPrm31573865; + + if (fltIf31563866) { + GibCursor fltPkd31583867 = + place1161251(uid225239729633843, clk226239829643844, x227239929653845, n239240429703850, l229240029663846, r230240129673847); + GibPtr tailift4203 = + gib_alloc(sizeof(GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd)); + + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4203)->field0 = + 0; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4203)->field1 = + t235240229683848; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4203)->field2 = + v236240329693849; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4203)->field3 = + l229240029663846; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4203)->field4 = + r230240129673847; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4203)->field5 = + fltPkd31583867; + return tailift4203; + } else { + GibCursor fltAppE31613868 = clock177(clk226239829643844); + GibCursor fltPkd31603869 = + stamp171(uid225239729633843, fltAppE31613868); + GibCursor fltPkd31623870 = + place1161251(uid225239729633843, clk226239829643844, x227239929653845, n239240429703850, l229240029663846, r230240129673847); + GibPtr fltPkd31593871 = + gib_alloc(sizeof(GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd)); + + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd31593871)->field0 = + 0; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd31593871)->field1 = + fltPkd31603869; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd31593871)->field2 = + x227239929653845; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd31593871)->field3 = + l229240029663846; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd31593871)->field4 = + r230240129673847; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd31593871)->field5 = + fltPkd31623870; + + GibPtr tailift4204 = + gib_alloc(sizeof(GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd)); + + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4204)->field0 = + 0; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4204)->field1 = + t235240229683848; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4204)->field2 = + v236240329693849; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4204)->field3 = + l229240029663846; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4204)->field4 = + r230240129673847; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4204)->field5 = + fltPkd31593871; + return tailift4204; + } + break; + } + + case 3: + { + GibInt fltPrm31643872 = author176(t235240229683848); + GibBool fltIf31633873 = uid225239729633843 < fltPrm31643872; + + if (fltIf31633873) { + GibCursor fltPkd31653874 = + place1161251(uid225239729633843, clk226239829643844, x227239929653845, n239240429703850, l229240029663846, r230240129673847); + GibPtr tailift4205 = + gib_alloc(sizeof(GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd)); + + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4205)->field0 = + 0; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4205)->field1 = + t235240229683848; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4205)->field2 = + v236240329693849; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4205)->field3 = + l229240029663846; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4205)->field4 = + r230240129673847; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4205)->field5 = + fltPkd31653874; + return tailift4205; + } else { + GibCursor fltAppE31683875 = clock177(clk226239829643844); + GibCursor fltPkd31673876 = + stamp171(uid225239729633843, fltAppE31683875); + GibCursor fltPkd31693877 = + place1161251(uid225239729633843, clk226239829643844, x227239929653845, n239240429703850, l229240029663846, r230240129673847); + GibPtr fltPkd31663878 = + gib_alloc(sizeof(GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd)); + + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd31663878)->field0 = + 0; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd31663878)->field1 = + fltPkd31673876; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd31663878)->field2 = + x227239929653845; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd31663878)->field3 = + l229240029663846; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd31663878)->field4 = + r230240129673847; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltPkd31663878)->field5 = + fltPkd31693877; + + GibPtr tailift4206 = + gib_alloc(sizeof(GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd)); + + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4206)->field0 = + 0; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4206)->field1 = + t235240229683848; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4206)->field2 = + v236240329693849; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4206)->field3 = + l229240029663846; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4206)->field4 = + r230240129673847; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4206)->field5 = + fltPkd31663878; + return tailift4206; + } + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag4198"); + exit(1); + } + } +} +GibCursor caseFn2405(GibInt uid225240629713879, GibCursor clk226240729723880, + GibInt x227240829733881, GibCursor s228240929743882, + GibCursor l229241029753883, GibCursor r230241129763884, + GibCursor t232241229773885) +{ + GibPackedTag tag4208 = *(GibPackedTag *) s228240929743882; + GibCursor tail4209 = s228240929743882 + sizeof(GibInt); + + + switch4210: + ; + switch (tag4208) { + + case 1: + { + GibPtr fltPkd31713886 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) fltPkd31713886)->field0 = 1; + + GibPtr fltAppE31703887 = + gib_alloc(sizeof(GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd)); + + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltAppE31703887)->field0 = + 0; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltAppE31703887)->field1 = + t232241229773885; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltAppE31703887)->field2 = + x227240829733881; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltAppE31703887)->field3 = + l229241029753883; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltAppE31703887)->field4 = + r230241129763884; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltAppE31703887)->field5 = + fltPkd31713886; + return place_1171255(fltAppE31703887, s228240929743882); + break; + } + + case 0: + { + GibCursor t23529783888 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail4209)->field0; + GibInt v23629793889 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail4209)->field1; + GibCursor ls23729803890 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail4209)->field2; + GibCursor rs23829813891 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail4209)->field3; + GibCursor n23929823892 = + ((GibCursorGibIntGibCursorGibCursorGibCursorProd *) tail4209)->field4; + + return caseFn2396(uid225240629713879, clk226240729723880, + x227240829733881, l229241029753883, + r230241129763884, t23529783888, v23629793889, + n23929823892); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag4208"); + exit(1); + } + } +} +GibCursor caseFn2413(GibInt uid225241429833893, GibCursor clk226241529843894, + GibInt x227241629853895, GibCursor s228241729863896, + GibCursor l229241829873897, GibCursor r230241929883898, + GibCursor t232242029893899) +{ + GibCursor fltAppE31733900 = clock177(t232242029893899); + GibCursor fltAppE31743901 = clock177(r230241929883898); + GibCursor fltCse31723902 = compare170(fltAppE31733900, fltAppE31743901); + GibPackedTag tag4211 = *(GibPackedTag *) fltCse31723902; + GibCursor tail4212 = fltCse31723902 + sizeof(GibInt); + + + switch4213: + ; + switch (tag4211) { + + case 2: + { + GibPtr fltPkd31763903 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) fltPkd31763903)->field0 = 1; + + GibPtr fltAppE31753904 = + gib_alloc(sizeof(GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd)); + + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltAppE31753904)->field0 = + 0; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltAppE31753904)->field1 = + t232242029893899; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltAppE31753904)->field2 = + x227241629853895; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltAppE31753904)->field3 = + l229241829873897; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltAppE31753904)->field4 = + r230241929883898; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) fltAppE31753904)->field5 = + fltPkd31763903; + return place_1171255(fltAppE31753904, s228241729863896); + break; + } + + case 0: + { + return caseFn2371(uid225241429833893, clk226241529843894, + x227241629853895, s228241729863896, + l229241829873897, r230241929883898, + t232242029893899); + break; + } + + case 1: + { + return caseFn2388(uid225241429833893, clk226241529843894, + x227241629853895, s228241729863896, + l229241829873897, r230241929883898, + t232242029893899); + break; + } + + case 3: + { + return caseFn2405(uid225241429833893, clk226241529843894, + x227241629853895, s228241729863896, + l229241829873897, r230241929883898, + t232242029893899); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag4211"); + exit(1); + } + } +} +GibCursor caseFn2421(GibInt uid225242229903905, GibCursor clk226242329913906, + GibInt x227242429923907, GibCursor s228242529933908, + GibCursor l229242629943909, GibCursor r230242729953910, + GibCursor t232242829963911) +{ + GibInt tag4214 = ((GibIntGibIntGibCursorProd *) t232242829963911)->field0; + GibInt suid23329973912 = + ((GibIntGibIntGibCursorProd *) t232242829963911)->field1; + GibCursor sclk23429983913 = + ((GibIntGibIntGibCursorProd *) t232242829963911)->field2; + GibBool fltIf31773914 = suid23329973912 < 0; + + if (fltIf31773914) { + GibPtr fltPkd31783915 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) fltPkd31783915)->field0 = 1; + + GibPtr tailift4215 = + gib_alloc(sizeof(GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd)); + + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4215)->field0 = + 0; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4215)->field1 = + t232242829963911; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4215)->field2 = + x227242429923907; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4215)->field3 = + l229242629943909; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4215)->field4 = + r230242729953910; + ((GibIntGibCursorGibIntGibCursorGibCursorGibCursorProd *) tailift4215)->field5 = + fltPkd31783915; + return tailift4215; + } else { + return caseFn2413(uid225242229903905, clk226242329913906, + x227242429923907, s228242529933908, l229242629943909, + r230242729953910, t232242829963911); + } +} +int main(int argc, char **argv) +{ + int init0 = gib_init(argc, argv); + + info_table_initialize(); + symbol_table_initialize(); + + GibCursor x18224293179 = singleton1191237(0, 0); + GibCursor fltAppE29993180 = cursor1141238(0, x18224293179); + GibCursor fltAppE30003181 = cursor1141238(1, x18224293179); + GibCursor x18324303182 = + insert1181239(0, 1, fltAppE29993180, fltAppE30003181, x18224293179); + GibCursor tmp_app3916 = value1121240(x18324303182); + + _print_Node166_v1253(tmp_app3916); + printf("\n"); + + int exit1 = gib_exit(); + + return exit1; +} \ No newline at end of file diff --git a/benchmarks/CRDTs/IntOrderedList.hs b/benchmarks/CRDTs/IntOrderedList.hs new file mode 100644 index 000000000..24939f5cd --- /dev/null +++ b/benchmarks/CRDTs/IntOrderedList.hs @@ -0,0 +1,125 @@ +{-# LANGUAGE TemplateHaskell #-} +module IntOrderedList where +import Common +import qualified Timekeeping as T +import qualified List as L +import qualified Map as M + +data OrderedList a = OrderedList T.Clock (OrderedNode a) +data OrderedNode a = Bin T.Timestamp a T.Timestamp T.Timestamp (OrderedNode a) + | Tip + +getHead :: OrderedList a -> OrderedNode a +getHead list = + case list of + OrderedList _ node -> node + +getClock :: OrderedList a -> T.Clock +getClock list = + case list of + OrderedList c _ -> c + +getStamp :: OrderedNode a -> T.Timestamp +getStamp x = + case x of + Bin t _ _ _ _ -> t + Tip -> T.Timestamp (-1) (T.init (-1)) + +next :: OrderedNode a -> OrderedNode a +next x = case x of + Bin _ _ _ _ n -> n + Tip -> Tip + +singleton :: Int -> a -> OrderedList a +singleton uid x = + let clk = T.init uid + t = (T.stamp uid clk) + in OrderedList clk (Bin t x t t Tip) + +insert :: Int -> a -> T.Timestamp -> T.Timestamp -> OrderedList a -> OrderedList a +insert uid x l r list = + let clk = T.step uid (getClock list) + in OrderedList clk (place uid (T.stamp uid clk) x (getHead list) l r) + +place' :: OrderedNode a -> OrderedNode a -> OrderedNode a +place' x acc = + case x of + Tip -> acc + Bin tx vx lx rx _ -> + case acc of + Tip -> x + Bin tacc vacc lacc racc nacc -> Bin tacc vacc lacc racc (Bin tx vx lx rx nacc) + +place :: Int -> T.Timestamp -> a -> OrderedNode a -> T.Timestamp -> T.Timestamp -> OrderedNode a +place uid clk x s l r = + let t = getStamp s + in case t of + T.Timestamp suid sclk -> + if suid < 0 then Bin t x l r Tip + else case (T.compare (T.clock t) (T.clock r)) of + Eq -> place' (Bin t x l r Tip) s + _ -> case s of + Tip -> place' (Bin t x l r Tip) s + Bin t v ls rs n -> + case (T.compare (T.clock t) (T.clock l)) of + Eq -> Bin t v l r (Bin (T.stamp uid (T.clock clk)) x l r (place uid clk x n l r)) + _ -> + if uid < (T.author t) then Bin t v l r (place uid clk x n l r) + else Bin t v l r (Bin (T.stamp uid (T.clock clk)) x l r (place uid clk x n l r)) + +cursor' :: Int -> OrderedNode a -> T.Timestamp +cursor' i x = case x of + Tip -> + T.stamp (-1) (T.init (-1)) + Bin t _ _ _ n -> case n of + Tip -> t + _ -> + if i == 0 then t + else (cursor' (i-1) n) + +cursor :: Int -> OrderedList a -> T.Timestamp +cursor t x = (cursor' t (getHead x)) + +value' :: OrderedNode a -> L.Node a +value' x = case x of + Tip -> L.Tip + Bin _ v _ _ n -> L.Bin v (value' n) + +value :: OrderedList a -> L.Node a +value x = value' (getHead x) + +--gibbon_main = ( +-- (insert 1 "\n" () () +-- (insert 1 "d" () () +-- (insert 1 "l" () () +-- (insert 0 " " () () +-- (insert 0 "o" () () +-- (insert 1 "r" () () +-- (insert 0 "l" () () +-- (insert 1 "o" () () +-- (insert 1 "w" () () +-- (insert 0 "l" () () +-- (insert +-- 0 "e" (T.Timestamp 0 ()) (T.Timestamp 0 ()) +-- (singleton 0 "h") +-- ) +-- ) +-- ) +-- ) +-- ) +-- ) +-- ) +-- ) +-- ) +-- ) +-- ) +--) +-- 01234 56789 +-- hello world + +gibbon_main = + let x = (singleton 0 0) + x = (insert 0 1 (cursor 0 x) (cursor 1 x) x) + x = (insert 0 2 (cursor 0 x) (cursor 1 x) x) + x = (insert 1 5 (cursor 0 x) (cursor 1 x) x) + in value x \ No newline at end of file diff --git a/benchmarks/CRDTs/List.c b/benchmarks/CRDTs/List.c new file mode 100644 index 000000000..c6476acf0 --- /dev/null +++ b/benchmarks/CRDTs/List.c @@ -0,0 +1,365 @@ +/* Gibbon program. */ + +#include "gibbon_rts.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef _WIN64 +#include +#endif + +#ifdef _GIBBON_POINTER +#include +#endif + +#ifdef _GIBBON_PARALLEL +#include +#include +#endif + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Program starts here + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +typedef struct GibIntProd_struct { + GibInt field0; + } GibIntProd; +typedef struct GibIntGibIntGibCursorProd_struct { + GibInt field0; + GibInt field1; + GibCursor field2; + } GibIntGibIntGibCursorProd; +typedef struct GibIntGibCursorProd_struct { + GibInt field0; + GibCursor field1; + } GibIntGibCursorProd; +typedef struct GibBoolProd_struct { + GibBool field0; + } GibBoolProd; +typedef struct GibPackedTagGibCursorProd_struct { + GibPackedTag field0; + GibCursor field1; + } GibPackedTagGibCursorProd; +typedef struct GibCursorProd_struct { + GibCursor field0; + } GibCursorProd; +GibCursor insert2085(GibInt idx27145191, GibInt x28146192, GibCursor s29147193); +GibCursor singleton1884(GibInt x25150200); +GibCursor _copy_Node21_v86(GibCursor arg119151202); +GibCursor _copy_without_ptrs_Node21_v86(GibCursor arg124156207); +unsigned char _traverse_Node21_v86(GibCursor arg129161212); +unsigned char _print_Node21_v86(GibCursor arg134165216); +typedef enum { + GibInt_T, + GibFloat_T, + GibSym_T, + GibBool_T, + GibVector_T, + GibList_T, + GibCursor_T, + Node21_v86_T, + } GibDatatype; +void info_table_initialize(void) +{ + int error = gib_info_table_initialize(8); + + if (error < 0) { + fprintf(stderr, "Couldn't initialize info table, errorno=%d", error); + exit(1); + } + + GibDatatype field_tys[1]; + + error = gib_info_table_insert_packed_dcon(Node21_v86_T, 1, 8, 1, 1, 0, + field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, Node21_v86_T, 1); + exit(1); + } + error = gib_info_table_insert_packed_dcon(Node21_v86_T, 0, 0, 0, 0, 0, + field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, Node21_v86_T, 0); + exit(1); + } + gib_info_table_finalize(); +} +void symbol_table_initialize(void) +{ + gib_add_symbol(228, ")"); + gib_add_symbol(229, "(Tip22_v86"); + gib_add_symbol(230, "(Bin23_v86"); + gib_add_symbol(231, " "); +} +GibCursor insert2085(GibInt idx27145191, GibInt x28146192, GibCursor s29147193) +{ + GibPackedTag tag232 = *(GibPackedTag *) s29147193; + GibCursor tail233 = s29147193 + sizeof(GibInt); + + + switch237: + ; + switch (tag232) { + + case 1: + { + GibInt v31148194 = ((GibIntGibCursorProd *) tail233)->field0; + GibCursor n32149195 = ((GibIntGibCursorProd *) tail233)->field1; + GibBool fltIf181196 = idx27145191 == 0; + + if (fltIf181196) { + GibPtr tailift234 = + gib_alloc(sizeof(GibIntGibIntGibCursorProd)); + + ((GibIntGibIntGibCursorProd *) tailift234)->field0 = 1; + ((GibIntGibIntGibCursorProd *) tailift234)->field1 = x28146192; + ((GibIntGibIntGibCursorProd *) tailift234)->field2 = s29147193; + return tailift234; + } else { + GibInt fltAppE183197 = idx27145191 - 1; + GibCursor fltPkd182198 = + insert2085(fltAppE183197, x28146192, n32149195); + GibPtr tailift235 = + gib_alloc(sizeof(GibIntGibIntGibCursorProd)); + + ((GibIntGibIntGibCursorProd *) tailift235)->field0 = 1; + ((GibIntGibIntGibCursorProd *) tailift235)->field1 = v31148194; + ((GibIntGibIntGibCursorProd *) tailift235)->field2 = + fltPkd182198; + return tailift235; + } + break; + } + + case 0: + { + GibPtr fltPkd184199 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) fltPkd184199)->field0 = 0; + + GibPtr tailift236 = gib_alloc(sizeof(GibIntGibIntGibCursorProd)); + + ((GibIntGibIntGibCursorProd *) tailift236)->field0 = 1; + ((GibIntGibIntGibCursorProd *) tailift236)->field1 = x28146192; + ((GibIntGibIntGibCursorProd *) tailift236)->field2 = fltPkd184199; + return tailift236; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag232"); + exit(1); + } + } +} +GibCursor singleton1884(GibInt x25150200) +{ + GibPtr fltPkd185201 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) fltPkd185201)->field0 = 0; + + GibPtr tailift238 = gib_alloc(sizeof(GibIntGibIntGibCursorProd)); + + ((GibIntGibIntGibCursorProd *) tailift238)->field0 = 1; + ((GibIntGibIntGibCursorProd *) tailift238)->field1 = x25150200; + ((GibIntGibIntGibCursorProd *) tailift238)->field2 = fltPkd185201; + return tailift238; +} +GibCursor _copy_Node21_v86(GibCursor arg119151202) +{ + GibPackedTag tag239 = *(GibPackedTag *) arg119151202; + GibCursor tail240 = arg119151202 + sizeof(GibInt); + + + switch243: + ; + switch (tag239) { + + case 0: + { + GibPtr tailift241 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift241)->field0 = 0; + return tailift241; + break; + } + + case 1: + { + GibInt x120152203 = ((GibIntGibCursorProd *) tail240)->field0; + GibCursor x121153204 = ((GibIntGibCursorProd *) tail240)->field1; + GibCursor y123155206 = _copy_Node21_v86(x121153204); + GibPtr tailift242 = gib_alloc(sizeof(GibIntGibIntGibCursorProd)); + + ((GibIntGibIntGibCursorProd *) tailift242)->field0 = 1; + ((GibIntGibIntGibCursorProd *) tailift242)->field1 = x120152203; + ((GibIntGibIntGibCursorProd *) tailift242)->field2 = y123155206; + return tailift242; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag239"); + exit(1); + } + } +} +GibCursor _copy_without_ptrs_Node21_v86(GibCursor arg124156207) +{ + GibPackedTag tag244 = *(GibPackedTag *) arg124156207; + GibCursor tail245 = arg124156207 + sizeof(GibInt); + + + switch248: + ; + switch (tag244) { + + case 0: + { + GibPtr tailift246 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift246)->field0 = 0; + return tailift246; + break; + } + + case 1: + { + GibInt x125157208 = ((GibIntGibCursorProd *) tail245)->field0; + GibCursor x126158209 = ((GibIntGibCursorProd *) tail245)->field1; + GibCursor y128160211 = _copy_without_ptrs_Node21_v86(x126158209); + GibPtr tailift247 = gib_alloc(sizeof(GibIntGibIntGibCursorProd)); + + ((GibIntGibIntGibCursorProd *) tailift247)->field0 = 1; + ((GibIntGibIntGibCursorProd *) tailift247)->field1 = x125157208; + ((GibIntGibIntGibCursorProd *) tailift247)->field2 = y128160211; + return tailift247; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag244"); + exit(1); + } + } +} +unsigned char _traverse_Node21_v86(GibCursor arg129161212) +{ + GibPackedTag tag249 = *(GibPackedTag *) arg129161212; + GibCursor tail250 = arg129161212 + sizeof(GibInt); + + + switch251: + ; + switch (tag249) { + + case 0: + { + return 0; + break; + } + + case 1: + { + GibInt x130162213 = ((GibIntGibCursorProd *) tail250)->field0; + GibCursor x131163214 = ((GibIntGibCursorProd *) tail250)->field1; + unsigned char y133164215 = _traverse_Node21_v86(x131163214); + + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag249"); + exit(1); + } + } +} +unsigned char _print_Node21_v86(GibCursor arg134165216) +{ + GibPackedTag tag252 = *(GibPackedTag *) arg134165216; + GibCursor tail253 = arg134165216 + sizeof(GibInt); + + + switch254: + ; + switch (tag252) { + + case 0: + { + unsigned char wildcard135166217 = gib_print_symbol(229); + unsigned char wildcard136167218 = gib_print_symbol(228); + + return 0; + break; + } + + case 1: + { + GibInt x137168219 = ((GibIntGibCursorProd *) tail253)->field0; + GibCursor x138169220 = ((GibIntGibCursorProd *) tail253)->field1; + unsigned char wildcard141170221 = gib_print_symbol(230); + unsigned char wildcard144171222 = gib_print_symbol(231); + unsigned char y139172223 = printf("%ld", x137168219); + unsigned char wildcard143173224 = gib_print_symbol(231); + unsigned char y140174225 = _print_Node21_v86(x138169220); + unsigned char wildcard142175226 = gib_print_symbol(228); + + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag252"); + exit(1); + } + } +} +int main(int argc, char **argv) +{ + int init0 = gib_init(argc, argv); + + info_table_initialize(); + symbol_table_initialize(); + + GibCursor fltAppE180186 = singleton1884(5); + GibCursor fltAppE179187 = insert2085(1, 4, fltAppE180186); + GibCursor fltAppE178188 = insert2085(2, 3, fltAppE179187); + GibCursor fltAppE177189 = insert2085(3, 2, fltAppE178188); + GibCursor fltAppE176190 = insert2085(4, 1, fltAppE177189); + GibCursor tmp_app227 = insert2085(5, 0, fltAppE176190); + + _print_Node21_v86(tmp_app227); + printf("\n"); + + int exit1 = gib_exit(); + + return exit1; +} \ No newline at end of file diff --git a/benchmarks/CRDTs/List.hs b/benchmarks/CRDTs/List.hs new file mode 100644 index 000000000..d62c48455 --- /dev/null +++ b/benchmarks/CRDTs/List.hs @@ -0,0 +1,26 @@ +{-# LANGUAGE TemplateHaskell #-} + +module List where + +data Node a = Tip | Bin a (Node a) + +singleton :: a -> Node a +singleton x = Bin x Tip + +insert :: Int -> a -> Node a -> Node a +insert idx x s = + case s of + Bin v n -> + if idx == 0 then Bin x s + else Bin v (insert (idx-1) x n) + Tip -> Bin x Tip + +remove :: Int -> Node a -> Node a +remove idx s = + case s of + Bin v n -> + if idx == 0 then n + else Bin v (remove (idx-1) n) + Tip -> s + +gibbon_main = (insert 5 0 (insert 4 1 (insert 3 2 (insert 2 3 (insert 1 4 (singleton 5)))))) \ No newline at end of file diff --git a/benchmarks/CRDTs/Map.c b/benchmarks/CRDTs/Map.c new file mode 100644 index 000000000..48fc16d63 --- /dev/null +++ b/benchmarks/CRDTs/Map.c @@ -0,0 +1,1559 @@ +/* Gibbon program. */ + +#include "gibbon_rts.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef _WIN64 +#include +#endif + +#ifdef _GIBBON_POINTER +#include +#endif + +#ifdef _GIBBON_PARALLEL +#include +#include +#endif + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Program starts here + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +typedef struct GibIntProd_struct { + GibInt field0; + } GibIntProd; +typedef struct GibIntGibIntGibIntGibIntGibCursorGibCursorProd_struct { + GibInt field0; + GibInt field1; + GibInt field2; + GibInt field3; + GibCursor field4; + GibCursor field5; + } GibIntGibIntGibIntGibIntGibCursorGibCursorProd; +typedef struct GibIntGibIntGibIntGibCursorGibCursorProd_struct { + GibInt field0; + GibInt field1; + GibInt field2; + GibCursor field3; + GibCursor field4; + } GibIntGibIntGibIntGibCursorGibCursorProd; +typedef struct GibIntGibIntGibIntGibVectorGibCursorGibCursorProd_struct { + GibInt field0; + GibInt field1; + GibInt field2; + GibVector *field3; + GibCursor field4; + GibCursor field5; + } GibIntGibIntGibIntGibVectorGibCursorGibCursorProd; +typedef struct GibIntGibIntGibVectorGibCursorGibCursorProd_struct { + GibInt field0; + GibInt field1; + GibVector *field2; + GibCursor field3; + GibCursor field4; + } GibIntGibIntGibVectorGibCursorGibCursorProd; +typedef struct GibBoolProd_struct { + GibBool field0; + } GibBoolProd; +typedef struct GibPackedTagGibCursorProd_struct { + GibPackedTag field0; + GibCursor field1; + } GibPackedTagGibCursorProd; +typedef struct GibCursorProd_struct { + GibCursor field0; + } GibCursorProd; +typedef struct GibVectorProd_struct { + GibVector *field0; + } GibVectorProd; +GibInt ratio232(); +GibInt delta233(); +GibCursor singleton244776(GibInt k44612571559, GibVector *x44712581560); +GibInt size242778(GibCursor m43212591563); +GibCursor singleL227784(GibInt k132912651569, GibVector *x133012661570, + GibCursor t133112671571, GibCursor m33212681572); +GibCursor doubleL225785(GibInt k130412741579, GibVector *x130512751580, + GibCursor t130612761581, GibCursor m030712771582); +GibCursor rotateL230779(GibInt k35412831588, GibVector *x35512841589, + GibCursor l35612851590, GibCursor r35712861591); +GibCursor bin228783(GibInt k33912921602, GibVector *x34012931603, + GibCursor l34112941604, GibCursor r34212951605); +GibCursor singleR226781(GibInt k131912961610, GibVector *x132012971611, + GibCursor m32112981612, GibCursor t332212991613); +GibCursor doubleR224782(GibInt k128913051620, GibVector *x129013061621, + GibCursor m029113071622, GibCursor t429213081623); +GibCursor rotateR229780(GibInt k34413141629, GibVector *x34513151630, + GibCursor l34613161631, GibCursor r34713171632); +GibCursor balance231777(GibInt k36413231643, GibVector *x36513241644, + GibCursor l36613251645, GibCursor r36713261646); +GibCursor insert238773(GibInt kx27413271667, GibVector *x27513281668, + GibCursor m27613291669); +GibCursor empty222772(); +GibCursor _copy_Ord250(GibCursor arg110013351679); +GibCursor _copy_without_ptrs_Ord250(GibCursor arg110113361680); +unsigned char _traverse_Ord250(GibCursor arg110213371681); +unsigned char _print_Ord250(GibCursor arg110313381682); +GibCursor _copy_Map245_v775(GibCursor arg111213471691); +GibCursor _copy_without_ptrs_Map245_v775(GibCursor arg112313581702); +unsigned char _traverse_Map245_v775(GibCursor arg113413691713); +unsigned char _print_Map245_v775(GibCursor arg114513771721); +GibCursor _copy_Map245_v774(GibCursor arg116513971741); +GibCursor _copy_without_ptrs_Map245_v774(GibCursor arg117614081752); +unsigned char _traverse_Map245_v774(GibCursor arg118714191763); +unsigned char _print_Map245_v774(GibCursor arg119814271771); +GibCursor caseFn1218(GibInt k1304121914471791, GibVector *x1305122014481792, + GibCursor t1306122114491793, GibCursor m1312122214501794, + GibInt k2310122314511795, GibVector *x2311122414521796, + GibCursor t4313122514531797); +GibCursor caseFn1226(GibInt k1289122714591805, GibVector *x1290122814601806, + GibCursor t4292122914611807, GibCursor m1298123014621808, + GibInt k2295123114631809, GibVector *x2296123214641810, + GibCursor t1297123314651811); +typedef enum { + GibInt_T, + GibFloat_T, + GibSym_T, + GibBool_T, + GibVector_T, + GibList_T, + GibCursor_T, + Map245_v774_T, + Map245_v775_T, + Ord250_T, + } GibDatatype; +void info_table_initialize(void) +{ + int error = gib_info_table_initialize(10); + + if (error < 0) { + fprintf(stderr, "Couldn't initialize info table, errorno=%d", error); + exit(1); + } + + GibDatatype field_tys[3]; + + error = gib_info_table_insert_packed_dcon(Map245_v774_T, 1, 24, 2, 3, 0, + field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, Map245_v774_T, 1); + exit(1); + } + error = gib_info_table_insert_packed_dcon(Map245_v774_T, 0, 0, 0, 0, 0, + field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, Map245_v774_T, 0); + exit(1); + } + error = gib_info_table_insert_packed_dcon(Map245_v775_T, 1, 24, 2, 3, 0, + field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, Map245_v775_T, 1); + exit(1); + } + error = gib_info_table_insert_packed_dcon(Map245_v775_T, 0, 0, 0, 0, 0, + field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, Map245_v775_T, 0); + exit(1); + } + error = gib_info_table_insert_packed_dcon(Ord250_T, 3, 0, 0, 0, 0, + field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, Ord250_T, 3); + exit(1); + } + error = gib_info_table_insert_packed_dcon(Ord250_T, 2, 0, 0, 0, 0, + field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, Ord250_T, 2); + exit(1); + } + error = gib_info_table_insert_packed_dcon(Ord250_T, 1, 0, 0, 0, 0, + field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, Ord250_T, 1); + exit(1); + } + error = gib_info_table_insert_packed_dcon(Ord250_T, 0, 0, 0, 0, 0, + field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, Ord250_T, 0); + exit(1); + } + gib_info_table_finalize(); +} +void symbol_table_initialize(void) +{ + gib_add_symbol(1820, "Vector"); + gib_add_symbol(1821, ")"); + gib_add_symbol(1822, "(Tip246_v775"); + gib_add_symbol(1823, "(Tip246_v774"); + gib_add_symbol(1824, "(Lt251"); + gib_add_symbol(1825, "(Gt252"); + gib_add_symbol(1826, "(Eq253"); + gib_add_symbol(1827, "(Cc254"); + gib_add_symbol(1828, "(Bin247_v775"); + gib_add_symbol(1829, "(Bin247_v774"); + gib_add_symbol(1830, " "); +} +GibInt ratio232() +{ + return 2; +} +GibInt delta233() +{ + return 4; +} +GibCursor singleton244776(GibInt k44612571559, GibVector *x44712581560) +{ + GibPtr fltPkd14851561 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) fltPkd14851561)->field0 = 0; + + GibPtr fltPkd14861562 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) fltPkd14861562)->field0 = 0; + + GibPtr tailift1831 = + gib_alloc(sizeof(GibIntGibIntGibIntGibVectorGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibVectorGibCursorGibCursorProd *) tailift1831)->field0 = + 1; + ((GibIntGibIntGibIntGibVectorGibCursorGibCursorProd *) tailift1831)->field1 = + 1; + ((GibIntGibIntGibIntGibVectorGibCursorGibCursorProd *) tailift1831)->field2 = + k44612571559; + ((GibIntGibIntGibIntGibVectorGibCursorGibCursorProd *) tailift1831)->field3 = + x44712581560; + ((GibIntGibIntGibIntGibVectorGibCursorGibCursorProd *) tailift1831)->field4 = + fltPkd14851561; + ((GibIntGibIntGibIntGibVectorGibCursorGibCursorProd *) tailift1831)->field5 = + fltPkd14861562; + return tailift1831; +} +GibInt size242778(GibCursor m43212591563) +{ + GibPackedTag tag1832 = *(GibPackedTag *) m43212591563; + GibCursor tail1833 = m43212591563 + sizeof(GibInt); + + + switch1834: + ; + switch (tag1832) { + + case 0: + { + return 0; + break; + } + + case 1: + { + GibInt sz43412601564 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1833)->field0; + GibInt wildcard_1843512611565 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1833)->field1; + GibVector *wildcard_1943612621566 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1833)->field2; + GibCursor wildcard_2043712631567 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1833)->field3; + GibCursor wildcard_2143812641568 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1833)->field4; + + return sz43412601564; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1832"); + exit(1); + } + } +} +GibCursor singleL227784(GibInt k132912651569, GibVector *x133012661570, + GibCursor t133112671571, GibCursor m33212681572) +{ + GibPackedTag tag1835 = *(GibPackedTag *) m33212681572; + GibCursor tail1836 = m33212681572 + sizeof(GibInt); + + + switch1837: + ; + switch (tag1835) { + + case 1: + { + GibInt wildcard_15933412691573 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1836)->field0; + GibInt k233512701574 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1836)->field1; + GibVector *x233612711575 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1836)->field2; + GibCursor t233712721576 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1836)->field3; + GibCursor t333812731577 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1836)->field4; + GibCursor fltAppE14871578 = + bin228783(k132912651569, x133012661570, t133112671571, t233712721576); + + return bin228783(k233512701574, x233612711575, fltAppE14871578, + t333812731577); + break; + } + + case 0: + { + return empty222772(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1835"); + exit(1); + } + } +} +GibCursor doubleL225785(GibInt k130412741579, GibVector *x130512751580, + GibCursor t130612761581, GibCursor m030712771582) +{ + GibPackedTag tag1838 = *(GibPackedTag *) m030712771582; + GibCursor tail1839 = m030712771582 + sizeof(GibInt); + + + switch1840: + ; + switch (tag1838) { + + case 1: + { + GibInt wildcard_17930912781583 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1839)->field0; + GibInt k231012791584 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1839)->field1; + GibVector *x231112801585 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1839)->field2; + GibCursor m131212811586 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1839)->field3; + GibCursor t431312821587 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1839)->field4; + + return caseFn1218(k130412741579, x130512751580, t130612761581, + m131212811586, k231012791584, x231112801585, + t431312821587); + break; + } + + case 0: + { + return empty222772(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1838"); + exit(1); + } + } +} +GibCursor rotateL230779(GibInt k35412831588, GibVector *x35512841589, + GibCursor l35612851590, GibCursor r35712861591) +{ + GibPackedTag tag1841 = *(GibPackedTag *) r35712861591; + GibCursor tail1842 = r35712861591 + sizeof(GibInt); + + + switch1843: + ; + switch (tag1841) { + + case 1: + { + GibInt wildcard_13035912871592 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1842)->field0; + GibInt wildcard_13136012881593 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1842)->field1; + GibVector *wildcard_13236112891594 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1842)->field2; + GibCursor ly36212901595 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1842)->field3; + GibCursor ry36312911596 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1842)->field4; + GibInt fltPrm14891597 = size242778(ly36212901595); + GibInt fltPrm14911598 = ratio232(); + GibInt fltPrm14921599 = size242778(ry36312911596); + GibInt fltPrm14901600 = fltPrm14911598 * fltPrm14921599; + GibBool fltIf14881601 = fltPrm14891597 < fltPrm14901600; + + if (fltIf14881601) { + return singleL227784(k35412831588, x35512841589, l35612851590, + r35712861591); + } else { + return doubleL225785(k35412831588, x35512841589, l35612851590, + r35712861591); + } + break; + } + + case 0: + { + return empty222772(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1841"); + exit(1); + } + } +} +GibCursor bin228783(GibInt k33912921602, GibVector *x34012931603, + GibCursor l34112941604, GibCursor r34212951605) +{ + GibInt fltPrm14951606 = size242778(l34112941604); + GibInt fltPrm14961607 = size242778(r34212951605); + GibInt fltPrm14941608 = fltPrm14951606 + fltPrm14961607; + GibInt fltPkd14931609 = fltPrm14941608 + 1; + GibPtr tailift1844 = + gib_alloc(sizeof(GibIntGibIntGibIntGibVectorGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibVectorGibCursorGibCursorProd *) tailift1844)->field0 = + 1; + ((GibIntGibIntGibIntGibVectorGibCursorGibCursorProd *) tailift1844)->field1 = + fltPkd14931609; + ((GibIntGibIntGibIntGibVectorGibCursorGibCursorProd *) tailift1844)->field2 = + k33912921602; + ((GibIntGibIntGibIntGibVectorGibCursorGibCursorProd *) tailift1844)->field3 = + x34012931603; + ((GibIntGibIntGibIntGibVectorGibCursorGibCursorProd *) tailift1844)->field4 = + l34112941604; + ((GibIntGibIntGibIntGibVectorGibCursorGibCursorProd *) tailift1844)->field5 = + r34212951605; + return tailift1844; +} +GibCursor singleR226781(GibInt k131912961610, GibVector *x132012971611, + GibCursor m32112981612, GibCursor t332212991613) +{ + GibPackedTag tag1845 = *(GibPackedTag *) m32112981612; + GibCursor tail1846 = m32112981612 + sizeof(GibInt); + + + switch1847: + ; + switch (tag1845) { + + case 1: + { + GibInt wildcard_16932413001614 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1846)->field0; + GibInt k232513011615 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1846)->field1; + GibVector *x232613021616 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1846)->field2; + GibCursor t132713031617 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1846)->field3; + GibCursor t232813041618 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1846)->field4; + GibCursor fltAppE14971619 = + bin228783(k131912961610, x132012971611, t232813041618, t332212991613); + + return bin228783(k232513011615, x232613021616, t132713031617, + fltAppE14971619); + break; + } + + case 0: + { + return empty222772(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1845"); + exit(1); + } + } +} +GibCursor doubleR224782(GibInt k128913051620, GibVector *x129013061621, + GibCursor m029113071622, GibCursor t429213081623) +{ + GibPackedTag tag1848 = *(GibPackedTag *) m029113071622; + GibCursor tail1849 = m029113071622 + sizeof(GibInt); + + + switch1850: + ; + switch (tag1848) { + + case 1: + { + GibInt wildcard_19529413091624 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1849)->field0; + GibInt k229513101625 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1849)->field1; + GibVector *x229613111626 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1849)->field2; + GibCursor t129713121627 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1849)->field3; + GibCursor m129813131628 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1849)->field4; + + return caseFn1226(k128913051620, x129013061621, t429213081623, + m129813131628, k229513101625, x229613111626, + t129713121627); + break; + } + + case 0: + { + return empty222772(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1848"); + exit(1); + } + } +} +GibCursor rotateR229780(GibInt k34413141629, GibVector *x34513151630, + GibCursor l34613161631, GibCursor r34713171632) +{ + GibPackedTag tag1851 = *(GibPackedTag *) l34613161631; + GibCursor tail1852 = l34613161631 + sizeof(GibInt); + + + switch1853: + ; + switch (tag1851) { + + case 1: + { + GibInt wildcard_14234913181633 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1852)->field0; + GibInt wildcard_14335013191634 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1852)->field1; + GibVector *wildcard_14435113201635 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1852)->field2; + GibCursor ly35213211636 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1852)->field3; + GibCursor ry35313221637 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1852)->field4; + GibInt fltPrm14991638 = size242778(ry35313221637); + GibInt fltPrm15011639 = ratio232(); + GibInt fltPrm15021640 = size242778(ly35213211636); + GibInt fltPrm15001641 = fltPrm15011639 * fltPrm15021640; + GibBool fltIf14981642 = fltPrm14991638 < fltPrm15001641; + + if (fltIf14981642) { + return singleR226781(k34413141629, x34513151630, l34613161631, + r34713171632); + } else { + return doubleR224782(k34413141629, x34513151630, l34613161631, + r34713171632); + } + break; + } + + case 0: + { + return empty222772(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1851"); + exit(1); + } + } +} +GibCursor balance231777(GibInt k36413231643, GibVector *x36513241644, + GibCursor l36613251645, GibCursor r36713261646) +{ + GibInt fltPrm15051647 = size242778(l36613251645); + GibInt fltPrm15061648 = size242778(r36713261646); + GibInt fltPrm15041649 = fltPrm15051647 + fltPrm15061648; + GibBool fltIf15031650 = fltPrm15041649 <= 1; + + if (fltIf15031650) { + GibInt fltPrm15081651 = size242778(l36613251645); + GibInt fltPrm15091652 = size242778(r36713261646); + GibInt fltPkd15071653 = fltPrm15081651 + fltPrm15091652; + GibPtr tailift1854 = + gib_alloc(sizeof(GibIntGibIntGibIntGibVectorGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibVectorGibCursorGibCursorProd *) tailift1854)->field0 = + 1; + ((GibIntGibIntGibIntGibVectorGibCursorGibCursorProd *) tailift1854)->field1 = + fltPkd15071653; + ((GibIntGibIntGibIntGibVectorGibCursorGibCursorProd *) tailift1854)->field2 = + k36413231643; + ((GibIntGibIntGibIntGibVectorGibCursorGibCursorProd *) tailift1854)->field3 = + x36513241644; + ((GibIntGibIntGibIntGibVectorGibCursorGibCursorProd *) tailift1854)->field4 = + l36613251645; + ((GibIntGibIntGibIntGibVectorGibCursorGibCursorProd *) tailift1854)->field5 = + r36713261646; + return tailift1854; + } else { + GibInt fltPrm15111654 = size242778(r36713261646); + GibInt fltPrm15131655 = delta233(); + GibInt fltPrm15141656 = size242778(l36613251645); + GibInt fltPrm15121657 = fltPrm15131655 * fltPrm15141656; + GibBool fltIf15101658 = fltPrm15111654 >= fltPrm15121657; + + if (fltIf15101658) { + return rotateL230779(k36413231643, x36513241644, l36613251645, + r36713261646); + } else { + GibInt fltPrm15161659 = size242778(l36613251645); + GibInt fltPrm15181660 = delta233(); + GibInt fltPrm15191661 = size242778(r36713261646); + GibInt fltPrm15171662 = fltPrm15181660 * fltPrm15191661; + GibBool fltIf15151663 = fltPrm15161659 >= fltPrm15171662; + + if (fltIf15151663) { + return rotateR229780(k36413231643, x36513241644, l36613251645, + r36713261646); + } else { + GibInt fltPrm15211664 = size242778(l36613251645); + GibInt fltPrm15221665 = size242778(r36713261646); + GibInt fltPkd15201666 = fltPrm15211664 + fltPrm15221665; + GibPtr tailift1855 = + gib_alloc(sizeof(GibIntGibIntGibIntGibVectorGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibVectorGibCursorGibCursorProd *) tailift1855)->field0 = + 1; + ((GibIntGibIntGibIntGibVectorGibCursorGibCursorProd *) tailift1855)->field1 = + fltPkd15201666; + ((GibIntGibIntGibIntGibVectorGibCursorGibCursorProd *) tailift1855)->field2 = + k36413231643; + ((GibIntGibIntGibIntGibVectorGibCursorGibCursorProd *) tailift1855)->field3 = + x36513241644; + ((GibIntGibIntGibIntGibVectorGibCursorGibCursorProd *) tailift1855)->field4 = + l36613251645; + ((GibIntGibIntGibIntGibVectorGibCursorGibCursorProd *) tailift1855)->field5 = + r36713261646; + return tailift1855; + } + } + } +} +GibCursor insert238773(GibInt kx27413271667, GibVector *x27513281668, + GibCursor m27613291669) +{ + GibPackedTag tag1856 = *(GibPackedTag *) m27613291669; + GibCursor tail1857 = m27613291669 + sizeof(GibInt); + + + switch1859: + ; + switch (tag1856) { + + case 0: + { + return singleton244776(kx27413271667, x27513281668); + break; + } + + case 1: + { + GibInt sz27813301670 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1857)->field0; + GibInt k27913311671 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1857)->field1; + GibVector *v28013321672 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1857)->field2; + GibCursor l28113331673 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1857)->field3; + GibCursor r28213341674 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1857)->field4; + GibBool fltIf15231675 = kx27413271667 == k27913311671; + + if (fltIf15231675) { + GibPtr tailift1858 = + gib_alloc(sizeof(GibIntGibIntGibIntGibVectorGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibVectorGibCursorGibCursorProd *) tailift1858)->field0 = + 1; + ((GibIntGibIntGibIntGibVectorGibCursorGibCursorProd *) tailift1858)->field1 = + sz27813301670; + ((GibIntGibIntGibIntGibVectorGibCursorGibCursorProd *) tailift1858)->field2 = + k27913311671; + ((GibIntGibIntGibIntGibVectorGibCursorGibCursorProd *) tailift1858)->field3 = + x27513281668; + ((GibIntGibIntGibIntGibVectorGibCursorGibCursorProd *) tailift1858)->field4 = + l28113331673; + ((GibIntGibIntGibIntGibVectorGibCursorGibCursorProd *) tailift1858)->field5 = + r28213341674; + return tailift1858; + } else { + GibBool fltIf15241676 = kx27413271667 <= k27913311671; + + if (fltIf15241676) { + GibCursor fltAppE15251677 = + insert238773(kx27413271667, x27513281668, l28113331673); + + return balance231777(k27913311671, v28013321672, + fltAppE15251677, r28213341674); + } else { + GibCursor fltAppE15261678 = + insert238773(kx27413271667, x27513281668, r28213341674); + + return balance231777(k27913311671, v28013321672, + l28113331673, fltAppE15261678); + } + } + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1856"); + exit(1); + } + } +} +GibCursor empty222772() +{ + GibPtr tailift1860 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift1860)->field0 = 0; + return tailift1860; +} +GibCursor _copy_Ord250(GibCursor arg110013351679) +{ + GibPackedTag tag1861 = *(GibPackedTag *) arg110013351679; + GibCursor tail1862 = arg110013351679 + sizeof(GibInt); + + + switch1867: + ; + switch (tag1861) { + + case 0: + { + GibPtr tailift1863 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift1863)->field0 = 0; + return tailift1863; + break; + } + + case 1: + { + GibPtr tailift1864 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift1864)->field0 = 1; + return tailift1864; + break; + } + + case 2: + { + GibPtr tailift1865 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift1865)->field0 = 2; + return tailift1865; + break; + } + + case 3: + { + GibPtr tailift1866 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift1866)->field0 = 3; + return tailift1866; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1861"); + exit(1); + } + } +} +GibCursor _copy_without_ptrs_Ord250(GibCursor arg110113361680) +{ + GibPackedTag tag1868 = *(GibPackedTag *) arg110113361680; + GibCursor tail1869 = arg110113361680 + sizeof(GibInt); + + + switch1874: + ; + switch (tag1868) { + + case 0: + { + GibPtr tailift1870 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift1870)->field0 = 0; + return tailift1870; + break; + } + + case 1: + { + GibPtr tailift1871 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift1871)->field0 = 1; + return tailift1871; + break; + } + + case 2: + { + GibPtr tailift1872 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift1872)->field0 = 2; + return tailift1872; + break; + } + + case 3: + { + GibPtr tailift1873 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift1873)->field0 = 3; + return tailift1873; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1868"); + exit(1); + } + } +} +unsigned char _traverse_Ord250(GibCursor arg110213371681) +{ + GibPackedTag tag1875 = *(GibPackedTag *) arg110213371681; + GibCursor tail1876 = arg110213371681 + sizeof(GibInt); + + + switch1877: + ; + switch (tag1875) { + + case 0: + { + return 0; + break; + } + + case 1: + { + return 0; + break; + } + + case 2: + { + return 0; + break; + } + + case 3: + { + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1875"); + exit(1); + } + } +} +unsigned char _print_Ord250(GibCursor arg110313381682) +{ + GibPackedTag tag1878 = *(GibPackedTag *) arg110313381682; + GibCursor tail1879 = arg110313381682 + sizeof(GibInt); + + + switch1880: + ; + switch (tag1878) { + + case 0: + { + unsigned char wildcard110413391683 = gib_print_symbol(1824); + unsigned char wildcard110513401684 = gib_print_symbol(1821); + + return 0; + break; + } + + case 1: + { + unsigned char wildcard110613411685 = gib_print_symbol(1825); + unsigned char wildcard110713421686 = gib_print_symbol(1821); + + return 0; + break; + } + + case 2: + { + unsigned char wildcard110813431687 = gib_print_symbol(1826); + unsigned char wildcard110913441688 = gib_print_symbol(1821); + + return 0; + break; + } + + case 3: + { + unsigned char wildcard111013451689 = gib_print_symbol(1827); + unsigned char wildcard111113461690 = gib_print_symbol(1821); + + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1878"); + exit(1); + } + } +} +GibCursor _copy_Map245_v775(GibCursor arg111213471691) +{ + GibPackedTag tag1881 = *(GibPackedTag *) arg111213471691; + GibCursor tail1882 = arg111213471691 + sizeof(GibInt); + + + switch1885: + ; + switch (tag1881) { + + case 0: + { + GibPtr tailift1883 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift1883)->field0 = 0; + return tailift1883; + break; + } + + case 1: + { + GibInt x111313481692 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1882)->field0; + GibInt x111413491693 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1882)->field1; + GibVector *x111513501694 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1882)->field2; + GibCursor x111613511695 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1882)->field3; + GibCursor x111713521696 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1882)->field4; + GibCursor y112113561700 = _copy_Map245_v775(x111613511695); + GibCursor y112213571701 = _copy_Map245_v775(x111713521696); + GibPtr tailift1884 = + gib_alloc(sizeof(GibIntGibIntGibIntGibVectorGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibVectorGibCursorGibCursorProd *) tailift1884)->field0 = + 1; + ((GibIntGibIntGibIntGibVectorGibCursorGibCursorProd *) tailift1884)->field1 = + x111313481692; + ((GibIntGibIntGibIntGibVectorGibCursorGibCursorProd *) tailift1884)->field2 = + x111413491693; + ((GibIntGibIntGibIntGibVectorGibCursorGibCursorProd *) tailift1884)->field3 = + x111513501694; + ((GibIntGibIntGibIntGibVectorGibCursorGibCursorProd *) tailift1884)->field4 = + y112113561700; + ((GibIntGibIntGibIntGibVectorGibCursorGibCursorProd *) tailift1884)->field5 = + y112213571701; + return tailift1884; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1881"); + exit(1); + } + } +} +GibCursor _copy_without_ptrs_Map245_v775(GibCursor arg112313581702) +{ + GibPackedTag tag1886 = *(GibPackedTag *) arg112313581702; + GibCursor tail1887 = arg112313581702 + sizeof(GibInt); + + + switch1890: + ; + switch (tag1886) { + + case 0: + { + GibPtr tailift1888 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift1888)->field0 = 0; + return tailift1888; + break; + } + + case 1: + { + GibInt x112413591703 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1887)->field0; + GibInt x112513601704 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1887)->field1; + GibVector *x112613611705 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1887)->field2; + GibCursor x112713621706 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1887)->field3; + GibCursor x112813631707 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1887)->field4; + GibCursor y113213671711 = + _copy_without_ptrs_Map245_v775(x112713621706); + GibCursor y113313681712 = + _copy_without_ptrs_Map245_v775(x112813631707); + GibPtr tailift1889 = + gib_alloc(sizeof(GibIntGibIntGibIntGibVectorGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibVectorGibCursorGibCursorProd *) tailift1889)->field0 = + 1; + ((GibIntGibIntGibIntGibVectorGibCursorGibCursorProd *) tailift1889)->field1 = + x112413591703; + ((GibIntGibIntGibIntGibVectorGibCursorGibCursorProd *) tailift1889)->field2 = + x112513601704; + ((GibIntGibIntGibIntGibVectorGibCursorGibCursorProd *) tailift1889)->field3 = + x112613611705; + ((GibIntGibIntGibIntGibVectorGibCursorGibCursorProd *) tailift1889)->field4 = + y113213671711; + ((GibIntGibIntGibIntGibVectorGibCursorGibCursorProd *) tailift1889)->field5 = + y113313681712; + return tailift1889; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1886"); + exit(1); + } + } +} +unsigned char _traverse_Map245_v775(GibCursor arg113413691713) +{ + GibPackedTag tag1891 = *(GibPackedTag *) arg113413691713; + GibCursor tail1892 = arg113413691713 + sizeof(GibInt); + + + switch1893: + ; + switch (tag1891) { + + case 0: + { + return 0; + break; + } + + case 1: + { + GibInt x113513701714 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1892)->field0; + GibInt x113613711715 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1892)->field1; + GibVector *x113713721716 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1892)->field2; + GibCursor x113813731717 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1892)->field3; + GibCursor x113913741718 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1892)->field4; + unsigned char y114313751719 = _traverse_Map245_v775(x113813731717); + unsigned char y114413761720 = _traverse_Map245_v775(x113913741718); + + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1891"); + exit(1); + } + } +} +unsigned char _print_Map245_v775(GibCursor arg114513771721) +{ + GibPackedTag tag1894 = *(GibPackedTag *) arg114513771721; + GibCursor tail1895 = arg114513771721 + sizeof(GibInt); + + + switch1896: + ; + switch (tag1894) { + + case 0: + { + unsigned char wildcard114613781722 = gib_print_symbol(1822); + unsigned char wildcard114713791723 = gib_print_symbol(1821); + + return 0; + break; + } + + case 1: + { + GibInt x114813801724 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1895)->field0; + GibInt x114913811725 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1895)->field1; + GibVector *x115013821726 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1895)->field2; + GibCursor x115113831727 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1895)->field3; + GibCursor x115213841728 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1895)->field4; + unsigned char wildcard115813851729 = gib_print_symbol(1828); + unsigned char wildcard116413861730 = gib_print_symbol(1830); + unsigned char y115313871731 = printf("%ld", x114813801724); + unsigned char wildcard116313881732 = gib_print_symbol(1830); + unsigned char y115413891733 = printf("%ld", x114913811725); + unsigned char wildcard116213901734 = gib_print_symbol(1830); + unsigned char y115513911735 = gib_print_symbol(1820); + unsigned char wildcard116113921736 = gib_print_symbol(1830); + unsigned char y115613931737 = _print_Map245_v775(x115113831727); + unsigned char wildcard116013941738 = gib_print_symbol(1830); + unsigned char y115713951739 = _print_Map245_v775(x115213841728); + unsigned char wildcard115913961740 = gib_print_symbol(1821); + + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1894"); + exit(1); + } + } +} +GibCursor _copy_Map245_v774(GibCursor arg116513971741) +{ + GibPackedTag tag1897 = *(GibPackedTag *) arg116513971741; + GibCursor tail1898 = arg116513971741 + sizeof(GibInt); + + + switch1901: + ; + switch (tag1897) { + + case 0: + { + GibPtr tailift1899 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift1899)->field0 = 0; + return tailift1899; + break; + } + + case 1: + { + GibInt x116613981742 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail1898)->field0; + GibInt x116713991743 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail1898)->field1; + GibInt x116814001744 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail1898)->field2; + GibCursor x116914011745 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail1898)->field3; + GibCursor x117014021746 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail1898)->field4; + GibCursor y117414061750 = _copy_Map245_v774(x116914011745); + GibCursor y117514071751 = _copy_Map245_v774(x117014021746); + GibPtr tailift1900 = + gib_alloc(sizeof(GibIntGibIntGibIntGibIntGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift1900)->field0 = + 1; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift1900)->field1 = + x116613981742; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift1900)->field2 = + x116713991743; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift1900)->field3 = + x116814001744; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift1900)->field4 = + y117414061750; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift1900)->field5 = + y117514071751; + return tailift1900; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1897"); + exit(1); + } + } +} +GibCursor _copy_without_ptrs_Map245_v774(GibCursor arg117614081752) +{ + GibPackedTag tag1902 = *(GibPackedTag *) arg117614081752; + GibCursor tail1903 = arg117614081752 + sizeof(GibInt); + + + switch1906: + ; + switch (tag1902) { + + case 0: + { + GibPtr tailift1904 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift1904)->field0 = 0; + return tailift1904; + break; + } + + case 1: + { + GibInt x117714091753 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail1903)->field0; + GibInt x117814101754 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail1903)->field1; + GibInt x117914111755 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail1903)->field2; + GibCursor x118014121756 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail1903)->field3; + GibCursor x118114131757 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail1903)->field4; + GibCursor y118514171761 = + _copy_without_ptrs_Map245_v774(x118014121756); + GibCursor y118614181762 = + _copy_without_ptrs_Map245_v774(x118114131757); + GibPtr tailift1905 = + gib_alloc(sizeof(GibIntGibIntGibIntGibIntGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift1905)->field0 = + 1; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift1905)->field1 = + x117714091753; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift1905)->field2 = + x117814101754; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift1905)->field3 = + x117914111755; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift1905)->field4 = + y118514171761; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift1905)->field5 = + y118614181762; + return tailift1905; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1902"); + exit(1); + } + } +} +unsigned char _traverse_Map245_v774(GibCursor arg118714191763) +{ + GibPackedTag tag1907 = *(GibPackedTag *) arg118714191763; + GibCursor tail1908 = arg118714191763 + sizeof(GibInt); + + + switch1909: + ; + switch (tag1907) { + + case 0: + { + return 0; + break; + } + + case 1: + { + GibInt x118814201764 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail1908)->field0; + GibInt x118914211765 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail1908)->field1; + GibInt x119014221766 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail1908)->field2; + GibCursor x119114231767 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail1908)->field3; + GibCursor x119214241768 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail1908)->field4; + unsigned char y119614251769 = _traverse_Map245_v774(x119114231767); + unsigned char y119714261770 = _traverse_Map245_v774(x119214241768); + + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1907"); + exit(1); + } + } +} +unsigned char _print_Map245_v774(GibCursor arg119814271771) +{ + GibPackedTag tag1910 = *(GibPackedTag *) arg119814271771; + GibCursor tail1911 = arg119814271771 + sizeof(GibInt); + + + switch1912: + ; + switch (tag1910) { + + case 0: + { + unsigned char wildcard119914281772 = gib_print_symbol(1823); + unsigned char wildcard120014291773 = gib_print_symbol(1821); + + return 0; + break; + } + + case 1: + { + GibInt x120114301774 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail1911)->field0; + GibInt x120214311775 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail1911)->field1; + GibInt x120314321776 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail1911)->field2; + GibCursor x120414331777 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail1911)->field3; + GibCursor x120514341778 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail1911)->field4; + unsigned char wildcard121114351779 = gib_print_symbol(1829); + unsigned char wildcard121714361780 = gib_print_symbol(1830); + unsigned char y120614371781 = printf("%ld", x120114301774); + unsigned char wildcard121614381782 = gib_print_symbol(1830); + unsigned char y120714391783 = printf("%ld", x120214311775); + unsigned char wildcard121514401784 = gib_print_symbol(1830); + unsigned char y120814411785 = printf("%ld", x120314321776); + unsigned char wildcard121414421786 = gib_print_symbol(1830); + unsigned char y120914431787 = _print_Map245_v774(x120414331777); + unsigned char wildcard121314441788 = gib_print_symbol(1830); + unsigned char y121014451789 = _print_Map245_v774(x120514341778); + unsigned char wildcard121214461790 = gib_print_symbol(1821); + + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1910"); + exit(1); + } + } +} +GibCursor caseFn1218(GibInt k1304121914471791, GibVector *x1305122014481792, + GibCursor t1306122114491793, GibCursor m1312122214501794, + GibInt k2310122314511795, GibVector *x2311122414521796, + GibCursor t4313122514531797) +{ + GibPackedTag tag1913 = *(GibPackedTag *) m1312122214501794; + GibCursor tail1914 = m1312122214501794 + sizeof(GibInt); + + + switch1915: + ; + switch (tag1913) { + + case 1: + { + GibInt wildcard_18031414541798 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1914)->field0; + GibInt k331514551799 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1914)->field1; + GibVector *x331614561800 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1914)->field2; + GibCursor t231714571801 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1914)->field3; + GibCursor t331814581802 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1914)->field4; + GibCursor fltAppE15271803 = + bin228783(k1304121914471791, x1305122014481792, t1306122114491793, t231714571801); + GibCursor fltAppE15281804 = + bin228783(k2310122314511795, x2311122414521796, t331814581802, t4313122514531797); + + return bin228783(k331514551799, x331614561800, fltAppE15271803, + fltAppE15281804); + break; + } + + case 0: + { + return empty222772(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1913"); + exit(1); + } + } +} +GibCursor caseFn1226(GibInt k1289122714591805, GibVector *x1290122814601806, + GibCursor t4292122914611807, GibCursor m1298123014621808, + GibInt k2295123114631809, GibVector *x2296123214641810, + GibCursor t1297123314651811) +{ + GibPackedTag tag1916 = *(GibPackedTag *) m1298123014621808; + GibCursor tail1917 = m1298123014621808 + sizeof(GibInt); + + + switch1918: + ; + switch (tag1916) { + + case 1: + { + GibInt wildcard_19629914661812 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1917)->field0; + GibInt k330014671813 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1917)->field1; + GibVector *x330114681814 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1917)->field2; + GibCursor t230214691815 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1917)->field3; + GibCursor t330314701816 = + ((GibIntGibIntGibVectorGibCursorGibCursorProd *) tail1917)->field4; + GibCursor fltAppE15291817 = + bin228783(k2295123114631809, x2296123214641810, t1297123314651811, t230214691815); + GibCursor fltAppE15301818 = + bin228783(k1289122714591805, x1290122814601806, t330314701816, t4292122914611807); + + return bin228783(k330014671813, x330114681814, fltAppE15291817, + fltAppE15301818); + break; + } + + case 0: + { + return empty222772(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1916"); + exit(1); + } + } +} +int main(int argc, char **argv) +{ + int init14 = gib_init(argc, argv); + + info_table_initialize(); + symbol_table_initialize(); + + GibInt tmp13 = sizeof(GibChar); + GibVector *vec21425712341531 = gib_vector_alloc(1, tmp13); + GibChar tmp12 = 'f'; + GibVector *_25812351532 = gib_vector_inplace_update(vec21425712341531, 0, + &tmp12); + GibInt tmp11 = sizeof(GibChar); + GibVector *vec21525912361534 = gib_vector_alloc(1, tmp11); + GibChar tmp10 = 'f'; + GibVector *_26012371535 = gib_vector_inplace_update(vec21525912361534, 0, + &tmp10); + GibInt tmp9 = sizeof(GibChar); + GibVector *vec21626112381537 = gib_vector_alloc(1, tmp9); + GibChar tmp8 = 'e'; + GibVector *_26212391538 = gib_vector_inplace_update(vec21626112381537, 0, + &tmp8); + GibInt tmp7 = sizeof(GibChar); + GibVector *vec21726312401540 = gib_vector_alloc(1, tmp7); + GibChar tmp6 = 'd'; + GibVector *_26412411541 = gib_vector_inplace_update(vec21726312401540, 0, + &tmp6); + GibInt tmp5 = sizeof(GibChar); + GibVector *vec21826512421543 = gib_vector_alloc(1, tmp5); + GibChar tmp4 = 'c'; + GibVector *_26612431544 = gib_vector_inplace_update(vec21826512421543, 0, + &tmp4); + GibInt tmp3 = sizeof(GibChar); + GibVector *vec21926712441546 = gib_vector_alloc(1, tmp3); + GibChar tmp2 = 'b'; + GibVector *_26812451547 = gib_vector_inplace_update(vec21926712441546, 0, + &tmp2); + GibInt tmp1 = sizeof(GibChar); + GibVector *vec22026912461549 = gib_vector_alloc(1, tmp1); + GibChar tmp0 = 'a'; + GibVector *_27012471550 = gib_vector_inplace_update(vec22026912461549, 0, + &tmp0); + GibCursor fltAppE14841552 = empty222772(); + GibCursor fltAppE14821553 = + insert238773(0, vec22026912461549, fltAppE14841552); + GibCursor fltAppE14801554 = + insert238773(1, vec21926712441546, fltAppE14821553); + GibCursor fltAppE14781555 = + insert238773(2, vec21826512421543, fltAppE14801554); + GibCursor fltAppE14761556 = + insert238773(3, vec21726312401540, fltAppE14781555); + GibCursor fltAppE14741557 = + insert238773(4, vec21626112381537, fltAppE14761556); + GibCursor fltAppE14721558 = + insert238773(5, vec21525912361534, fltAppE14741557); + GibCursor tmp_app1819 = + insert238773(0, vec21425712341531, fltAppE14721558); + + _print_Map245_v775(tmp_app1819); + printf("\n"); + + int exit15 = gib_exit(); + + return exit15; +} \ No newline at end of file diff --git a/benchmarks/CRDTs/Map.hs b/benchmarks/CRDTs/Map.hs new file mode 100644 index 000000000..20f8e0530 --- /dev/null +++ b/benchmarks/CRDTs/Map.hs @@ -0,0 +1,191 @@ +{-# LANGUAGE BlockArguments #-} +{-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE DataKinds #-} + +module Map where +import Common as C + +type Size = Int +data Map a = Tip | Bin Size Int a (Map a) (Map a) + +-- Construction ----------------------- + +empty :: Map a +empty = Tip + +singleton :: Int -> a -> Map a +singleton k x = Bin 1 k x Tip Tip + + +-- Query ------------------------------ + +null :: Map a -> Bool +null m = case m of + Tip -> True + Bin _ _ _ _ _ -> False + +size :: Map a -> Size +size m = case m of + Tip -> 0 + Bin sz _ _ _ _ -> sz + +key :: Map a -> Int +key s = case s of + Tip -> 0 + Bin _ k _ _ _ -> k + +lookup :: Int -> Map a -> C.Maybe a +lookup k m = + case m of + Tip -> C.Nothing + Bin _ kx v l r -> + if k < kx then Map.lookup k l + else if k > kx then Map.lookup k r + else C.Just v + +member :: Int -> Map a -> Bool +member k m = case Map.lookup k m of + C.Nothing -> False + C.Just _ -> True + +-- Insertion -------------------------- + +insert :: Int -> a -> Map a -> Map a +insert kx x m = + case m of + Tip -> singleton kx x + Bin sz k v l r -> + if kx == k then Bin sz k x l r + else if kx <= k then + balance k v (insert kx x l) r + else + balance k v l (insert kx x r) + +delete :: Int -> Map a -> Map a +delete kx m = + case m of + Tip -> Tip + Bin sz k v l r -> + if kx == k then glue l r + else if kx <= k then balance kx v (delete kx l) r + else balance kx v l (delete kx r) + +glue :: Map a -> Map a -> Map a +glue l r = + case l of + Tip -> r + Bin _ _ _ _ _ -> l + {- + case l r of + (Tip, Tip) -> Tip + (Bin _ _ _ _ _, Tip) -> r + (Tip, Bin _ _ _ _ _) -> l + (Bin _ _ _ _ _, Bin _ _ _ _ _) -> + if size l > size r then + case (deleteFindMax l) of + Just ((km, m),l') -> balance km m l' r + Nothing -> Tip + --let ((km,m),l') = deleteFindMax l in balance km m l' r + else + case (deleteFindMin r) of + Just ((km,m),r') -> balance km m l r' + Nothing -> Tip + + --let ((km,m),r') = deleteFindMin r in balance km m l r' + -} + +deleteFindMin :: Map a -> (C.Maybe ((Int,a),Map a)) +deleteFindMin t = case t of + Tip -> C.Nothing + Bin _ k x l r -> case l of + Tip -> C.Just ((k,x),r) + _ -> case (deleteFindMin l) of + C.Nothing -> C.Nothing + C.Just res -> + let (kv, l') = res + (delk, delv) = kv + in C.Just ((delk, delv), (balance k x l' r)) + + --let (km,l') = deleteFindMin l in Just (km,balance k x l' r) + +deleteFindMax :: Map a -> (C.Maybe ((Int,a),Map a)) +deleteFindMax t = case t of + Tip -> C.Nothing + Bin _ k x l r -> case r of + Tip -> C.Just ((k,x),l) + _ -> case (deleteFindMax r) of + C.Nothing -> C.Nothing + C.Just res -> + let (kv, r') = res + (delk, delv) = kv + in C.Just ((delk, delv), (balance k x l r')) + + --let (km,r') = deleteFindMax r in Just (km,balance k x l r') + +delta :: Int +delta = 4 +ratio :: Int +ratio = 2 + +balance :: Int -> a -> Map a -> Map a -> Map a +balance k x l r = + if (size l) + (size r) <= 1 then Bin ((size l) + (size r)) k x l r + else if (size r) >= delta*(size l) then rotateL k x l r + else if (size l) >= delta*(size r) then rotateR k x l r + else Bin ((size l) + (size r)) k x l r + +rotateL :: Int -> b -> Map b -> Map b -> Map b +rotateL k x l r = + case r of + Bin _ _ _ ly ry -> + if (size ly) < ratio*(size ry) then singleL k x l r + else doubleL k x l r + Tip -> empty -- cry +rotateR :: Int -> b -> Map b -> Map b -> Map b +rotateR k x l r = + case l of + Bin _ _ _ ly ry -> + if (size ry) < ratio*(size ly) then singleR k x l r + else doubleR k x l r + Tip -> empty --cry + +bin :: Int -> a -> Map a -> Map a -> Map a +bin k x l r = Bin ((size l) + (size r) + 1) k x l r + +singleL :: Int -> b -> Map b -> Map b -> Map b +singleL k1 x1 t1 m = + case m of + Bin _ k2 x2 t2 t3 -> bin k2 x2 (bin k1 x1 t1 t2) t3 + Tip -> empty --cry + +singleR :: Int -> b -> Map b -> Map b -> Map b +singleR k1 x1 m t3 = + case m of + Bin _ k2 x2 t1 t2 -> bin k2 x2 t1 (bin k1 x1 t2 t3) + Tip -> empty --cry + +doubleL :: Int -> b -> Map b -> Map b -> Map b +doubleL k1 x1 t1 m0 = + case m0 of + Bin _ k2 x2 m1 t4 -> + case m1 of + Bin _ k3 x3 t2 t3 -> bin k3 x3 (bin k1 x1 t1 t2) (bin k2 x2 t3 t4) + Tip -> empty --cry + Tip -> empty --cry + +doubleR :: Int -> b -> Map b -> Map b -> Map b +doubleR k1 x1 m0 t4 = + case m0 of + Bin _ k2 x2 t1 m1 -> + case m1 of + Bin _ k3 x3 t2 t3 -> bin k3 x3 (bin k2 x2 t1 t2) (bin k1 x1 t3 t4) + Tip -> empty + Tip -> empty --cry + +sum :: Map Int -> Int +sum x = + case x of + Bin _ k v l r -> v + (sum l) + (sum r) + Tip -> 0 + +gibbon_main = insert 0 "f" (insert 5 "f" (insert 4 "e" (insert 3 "d" (insert 2 "c" (insert 1 "b" (insert 0 "a" empty)))))) \ No newline at end of file diff --git a/benchmarks/CRDTs/Set.c b/benchmarks/CRDTs/Set.c new file mode 100644 index 000000000..70f0fd649 --- /dev/null +++ b/benchmarks/CRDTs/Set.c @@ -0,0 +1,1851 @@ +/* Gibbon program. */ + +#include "gibbon_rts.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef _WIN64 +#include +#endif + +#ifdef _GIBBON_POINTER +#include +#endif + +#ifdef _GIBBON_PARALLEL +#include +#include +#endif + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Program starts here + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +typedef struct GibIntProd_struct { + GibInt field0; + } GibIntProd; +typedef struct GibIntGibIntGibIntGibCursorGibCursorProd_struct { + GibInt field0; + GibInt field1; + GibInt field2; + GibCursor field3; + GibCursor field4; + } GibIntGibIntGibIntGibCursorGibCursorProd; +typedef struct GibIntGibIntGibCursorGibCursorProd_struct { + GibInt field0; + GibInt field1; + GibCursor field2; + GibCursor field3; + } GibIntGibIntGibCursorGibCursorProd; +typedef struct GibBoolProd_struct { + GibBool field0; + } GibBoolProd; +typedef struct GibPackedTagGibCursorProd_struct { + GibPackedTag field0; + GibCursor field1; + } GibPackedTagGibCursorProd; +typedef struct GibCursorProd_struct { + GibCursor field0; + } GibCursorProd; +GibCursor empty202(); +GibCursor insert214(GibInt x2196891021, GibCursor s2206901022); +GibInt sum203(GibCursor s2276971031); +GibCursor right205(GibCursor x2347041039); +GibCursor left206(GibCursor x2397091044); +GibInt val207(GibCursor x2447141049); +GibInt size208(GibCursor s2497191054); +GibCursor balanceR212(GibInt x2727421059, GibCursor l2737431060, + GibCursor r2747441061); +GibCursor balanceL213(GibInt x2997491066, GibCursor l3007501067, + GibCursor r3017511068); +GibCursor singleton215(GibInt x3267561073); +GibCursor _copy_IntSet216(GibCursor arg5927571076); +GibCursor _copy_without_ptrs_IntSet216(GibCursor arg6017661085); +unsigned char _traverse_IntSet216(GibCursor arg6107751094); +unsigned char _print_IntSet216(GibCursor arg6197821101); +GibCursor caseFn636(GibInt x2726377991118, GibCursor rr2786388001119, + GibInt rs2756398011120, GibInt rx2766408021121, + GibCursor rl2776418031122); +GibCursor caseFn642(GibInt x2726438081154, GibCursor r2746448091155, + GibInt rx2766458101156, GibCursor rl2776468111157); +GibCursor caseFn647(GibInt x2726488161170, GibCursor r2746498171171, + GibCursor rr2786508181172, GibInt rs2756518191173, + GibInt rx2766528201174, GibCursor rl2776538211175); +GibCursor caseFn654(GibInt x2726558261180, GibCursor r2746568271181); +GibCursor caseFn657(GibCursor l2736588321188, GibInt x2726598331189, + GibCursor r2746608341190, GibInt ls2916618351191); +GibCursor caseFn662(GibInt x2996638401228, GibCursor ll3046648411229, + GibInt ls3026658421230, GibInt lx3036668431231, + GibCursor lr3056678441232, GibInt lls3066688451233); +GibCursor caseFn669(GibInt x2996708501256, GibCursor l3006718511257, + GibInt lx3036728521258, GibCursor lr3056738531259); +GibCursor caseFn674(GibInt x2996758581271, GibCursor l3006768591272, + GibCursor ll3046778601273, GibInt ls3026788611274, + GibInt lx3036798621275, GibCursor lr3056808631276); +GibCursor caseFn681(GibInt x2996828681281, GibCursor l3006838691282); +GibCursor caseFn684(GibCursor r3016858741289, GibInt x2996868751290, + GibCursor l3006878761291, GibInt rs3186888771292); +typedef enum { + GibInt_T, + GibFloat_T, + GibSym_T, + GibBool_T, + GibVector_T, + GibList_T, + GibCursor_T, + IntSet216_T, + } GibDatatype; +void info_table_initialize(void) +{ + int error = gib_info_table_initialize(8); + + if (error < 0) { + fprintf(stderr, "Couldn't initialize info table, errorno=%d", error); + exit(1); + } + + GibDatatype field_tys[2]; + + error = gib_info_table_insert_packed_dcon(IntSet216_T, 1, 0, 0, 0, 0, + field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, IntSet216_T, 1); + exit(1); + } + error = gib_info_table_insert_packed_dcon(IntSet216_T, 0, 16, 2, 2, 0, + field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, IntSet216_T, 0); + exit(1); + } + gib_info_table_finalize(); +} +void symbol_table_initialize(void) +{ + gib_add_symbol(1330, ")"); + gib_add_symbol(1331, "(PureSet217"); + gib_add_symbol(1332, "(EmptySet218"); + gib_add_symbol(1333, " "); +} +GibCursor empty202() +{ + GibPtr tailift1334 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift1334)->field0 = 1; + return tailift1334; +} +GibCursor insert214(GibInt x2196891021, GibCursor s2206901022) +{ + GibPackedTag tag1335 = *(GibPackedTag *) s2206901022; + GibCursor tail1336 = s2206901022 + sizeof(GibInt); + + + switch1337: + ; + switch (tag1335) { + + case 1: + { + return singleton215(x2196891021); + break; + } + + case 0: + { + GibInt sz2216911023 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1336)->field0; + GibInt v2226921024 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1336)->field1; + GibCursor l2236931025 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1336)->field2; + GibCursor r2246941026 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1336)->field3; + GibBool fltIf8841027 = x2196891021 == v2226921024; + + if (fltIf8841027) { + return s2206901022; + } else { + GibBool fltIf8851028 = x2196891021 <= v2226921024; + + if (fltIf8851028) { + GibCursor nl2256951029 = + insert214(x2196891021, l2236931025); + + return balanceL213(v2226921024, nl2256951029, r2246941026); + } else { + GibCursor nr2266961030 = + insert214(x2196891021, r2246941026); + + return balanceR212(v2226921024, l2236931025, nr2266961030); + } + } + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1335"); + exit(1); + } + } +} +GibInt sum203(GibCursor s2276971031) +{ + GibPackedTag tag1338 = *(GibPackedTag *) s2276971031; + GibCursor tail1339 = s2276971031 + sizeof(GibInt); + + + switch1341: + ; + switch (tag1338) { + + case 1: + { + return 0; + break; + } + + case 0: + { + GibInt wildcard_1962286981032 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1339)->field0; + GibInt v2296991033 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1339)->field1; + GibCursor l2307001034 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1339)->field2; + GibCursor r2317011035 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1339)->field3; + GibInt fltPrm8871036 = sum203(l2307001034); + GibInt fltPrm8861037 = v2296991033 + fltPrm8871036; + GibInt fltPrm8881038 = sum203(r2317011035); + GibInt flt1340 = fltPrm8861037 + fltPrm8881038; + + return flt1340; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1338"); + exit(1); + } + } +} +GibCursor right205(GibCursor x2347041039) +{ + GibPackedTag tag1342 = *(GibPackedTag *) x2347041039; + GibCursor tail1343 = x2347041039 + sizeof(GibInt); + + + switch1345: + ; + switch (tag1342) { + + case 1: + { + GibPtr tailift1344 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift1344)->field0 = 1; + return tailift1344; + break; + } + + case 0: + { + GibInt wildcard_1862357051040 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1343)->field0; + GibInt wildcard_1872367061041 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1343)->field1; + GibCursor wildcard_1882377071042 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1343)->field2; + GibCursor r2387081043 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1343)->field3; + + return r2387081043; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1342"); + exit(1); + } + } +} +GibCursor left206(GibCursor x2397091044) +{ + GibPackedTag tag1346 = *(GibPackedTag *) x2397091044; + GibCursor tail1347 = x2397091044 + sizeof(GibInt); + + + switch1349: + ; + switch (tag1346) { + + case 1: + { + GibPtr tailift1348 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift1348)->field0 = 1; + return tailift1348; + break; + } + + case 0: + { + GibInt wildcard_1772407101045 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1347)->field0; + GibInt wildcard_1782417111046 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1347)->field1; + GibCursor l2427121047 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1347)->field2; + GibCursor wildcard_1792437131048 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1347)->field3; + + return l2427121047; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1346"); + exit(1); + } + } +} +GibInt val207(GibCursor x2447141049) +{ + GibPackedTag tag1350 = *(GibPackedTag *) x2447141049; + GibCursor tail1351 = x2447141049 + sizeof(GibInt); + + + switch1352: + ; + switch (tag1350) { + + case 1: + { + return 0; + break; + } + + case 0: + { + GibInt wildcard_1682457151050 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1351)->field0; + GibInt v2467161051 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1351)->field1; + GibCursor wildcard_1692477171052 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1351)->field2; + GibCursor wildcard_1702487181053 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1351)->field3; + + return v2467161051; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1350"); + exit(1); + } + } +} +GibInt size208(GibCursor s2497191054) +{ + GibPackedTag tag1353 = *(GibPackedTag *) s2497191054; + GibCursor tail1354 = s2497191054 + sizeof(GibInt); + + + switch1355: + ; + switch (tag1353) { + + case 1: + { + return 0; + break; + } + + case 0: + { + GibInt sz2507201055 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1354)->field0; + GibInt wildcard_1602517211056 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1354)->field1; + GibCursor wildcard_1612527221057 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1354)->field2; + GibCursor wildcard_1622537231058 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1354)->field3; + + return sz2507201055; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1353"); + exit(1); + } + } +} +GibCursor balanceR212(GibInt x2727421059, GibCursor l2737431060, + GibCursor r2747441061) +{ + GibPackedTag tag1356 = *(GibPackedTag *) l2737431060; + GibCursor tail1357 = l2737431060 + sizeof(GibInt); + + + switch1358: + ; + switch (tag1356) { + + case 1: + { + return caseFn654(x2727421059, r2747441061); + break; + } + + case 0: + { + GibInt ls2917451062 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1357)->field0; + GibInt wildcard_1162927461063 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1357)->field1; + GibCursor wildcard_1172937471064 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1357)->field2; + GibCursor wildcard_1182947481065 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1357)->field3; + + return caseFn657(l2737431060, x2727421059, r2747441061, + ls2917451062); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1356"); + exit(1); + } + } +} +GibCursor balanceL213(GibInt x2997491066, GibCursor l3007501067, + GibCursor r3017511068) +{ + GibPackedTag tag1359 = *(GibPackedTag *) r3017511068; + GibCursor tail1360 = r3017511068 + sizeof(GibInt); + + + switch1361: + ; + switch (tag1359) { + + case 1: + { + return caseFn681(x2997491066, l3007501067); + break; + } + + case 0: + { + GibInt rs3187521069 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1360)->field0; + GibInt wildcard_553197531070 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1360)->field1; + GibCursor wildcard_563207541071 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1360)->field2; + GibCursor wildcard_573217551072 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1360)->field3; + + return caseFn684(r3017511068, x2997491066, l3007501067, + rs3187521069); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1359"); + exit(1); + } + } +} +GibCursor singleton215(GibInt x3267561073) +{ + GibPtr fltPkd8891074 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) fltPkd8891074)->field0 = 1; + + GibPtr fltPkd8901075 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) fltPkd8901075)->field0 = 1; + + GibPtr tailift1362 = + gib_alloc(sizeof(GibIntGibIntGibIntGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1362)->field0 = 0; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1362)->field1 = 1; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1362)->field2 = + x3267561073; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1362)->field3 = + fltPkd8891074; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1362)->field4 = + fltPkd8901075; + return tailift1362; +} +GibCursor _copy_IntSet216(GibCursor arg5927571076) +{ + GibPackedTag tag1363 = *(GibPackedTag *) arg5927571076; + GibCursor tail1364 = arg5927571076 + sizeof(GibInt); + + + switch1367: + ; + switch (tag1363) { + + case 0: + { + GibInt x5937581077 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1364)->field0; + GibInt x5947591078 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1364)->field1; + GibCursor x5957601079 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1364)->field2; + GibCursor x5967611080 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1364)->field3; + GibCursor y5997641083 = _copy_IntSet216(x5957601079); + GibCursor y6007651084 = _copy_IntSet216(x5967611080); + GibPtr tailift1365 = + gib_alloc(sizeof(GibIntGibIntGibIntGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1365)->field0 = + 0; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1365)->field1 = + x5937581077; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1365)->field2 = + x5947591078; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1365)->field3 = + y5997641083; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1365)->field4 = + y6007651084; + return tailift1365; + break; + } + + case 1: + { + GibPtr tailift1366 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift1366)->field0 = 1; + return tailift1366; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1363"); + exit(1); + } + } +} +GibCursor _copy_without_ptrs_IntSet216(GibCursor arg6017661085) +{ + GibPackedTag tag1368 = *(GibPackedTag *) arg6017661085; + GibCursor tail1369 = arg6017661085 + sizeof(GibInt); + + + switch1372: + ; + switch (tag1368) { + + case 0: + { + GibInt x6027671086 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1369)->field0; + GibInt x6037681087 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1369)->field1; + GibCursor x6047691088 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1369)->field2; + GibCursor x6057701089 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1369)->field3; + GibCursor y6087731092 = _copy_without_ptrs_IntSet216(x6047691088); + GibCursor y6097741093 = _copy_without_ptrs_IntSet216(x6057701089); + GibPtr tailift1370 = + gib_alloc(sizeof(GibIntGibIntGibIntGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1370)->field0 = + 0; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1370)->field1 = + x6027671086; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1370)->field2 = + x6037681087; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1370)->field3 = + y6087731092; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1370)->field4 = + y6097741093; + return tailift1370; + break; + } + + case 1: + { + GibPtr tailift1371 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift1371)->field0 = 1; + return tailift1371; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1368"); + exit(1); + } + } +} +unsigned char _traverse_IntSet216(GibCursor arg6107751094) +{ + GibPackedTag tag1373 = *(GibPackedTag *) arg6107751094; + GibCursor tail1374 = arg6107751094 + sizeof(GibInt); + + + switch1375: + ; + switch (tag1373) { + + case 0: + { + GibInt x6117761095 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1374)->field0; + GibInt x6127771096 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1374)->field1; + GibCursor x6137781097 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1374)->field2; + GibCursor x6147791098 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1374)->field3; + unsigned char y6177801099 = _traverse_IntSet216(x6137781097); + unsigned char y6187811100 = _traverse_IntSet216(x6147791098); + + return 0; + break; + } + + case 1: + { + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1373"); + exit(1); + } + } +} +unsigned char _print_IntSet216(GibCursor arg6197821101) +{ + GibPackedTag tag1376 = *(GibPackedTag *) arg6197821101; + GibCursor tail1377 = arg6197821101 + sizeof(GibInt); + + + switch1378: + ; + switch (tag1376) { + + case 0: + { + GibInt x6207831102 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1377)->field0; + GibInt x6217841103 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1377)->field1; + GibCursor x6227851104 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1377)->field2; + GibCursor x6237861105 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1377)->field3; + unsigned char wildcard6287871106 = gib_print_symbol(1331); + unsigned char wildcard6337881107 = gib_print_symbol(1333); + unsigned char y6247891108 = printf("%ld", x6207831102); + unsigned char wildcard6327901109 = gib_print_symbol(1333); + unsigned char y6257911110 = printf("%ld", x6217841103); + unsigned char wildcard6317921111 = gib_print_symbol(1333); + unsigned char y6267931112 = _print_IntSet216(x6227851104); + unsigned char wildcard6307941113 = gib_print_symbol(1333); + unsigned char y6277951114 = _print_IntSet216(x6237861105); + unsigned char wildcard6297961115 = gib_print_symbol(1330); + + return 0; + break; + } + + case 1: + { + unsigned char wildcard6347971116 = gib_print_symbol(1332); + unsigned char wildcard6357981117 = gib_print_symbol(1330); + + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1376"); + exit(1); + } + } +} +GibCursor caseFn636(GibInt x2726377991118, GibCursor rr2786388001119, + GibInt rs2756398011120, GibInt rx2766408021121, + GibCursor rl2776418031122) +{ + GibPackedTag tag1379 = *(GibPackedTag *) rl2776418031122; + GibCursor tail1380 = rl2776418031122 + sizeof(GibInt); + + + switch1384: + ; + switch (tag1379) { + + case 0: + { + GibInt rls2838041123 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1380)->field0; + GibInt rlx2848051124 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1380)->field1; + GibCursor rll2858061125 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1380)->field2; + GibCursor rlr2868071126 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1380)->field3; + GibInt fltPrm8921127 = size208(rl2776418031122); + GibInt fltPrm8941128 = size208(rr2786388001119); + GibInt fltPrm8931129 = 2 * fltPrm8941128; + GibBool fltIf8911130 = fltPrm8921127 < fltPrm8931129; + + if (fltIf8911130) { + GibInt fltPkd8951131 = 1 + rs2756398011120; + GibInt fltPrm8981132 = size208(rl2776418031122); + GibInt fltPkd8971133 = 1 + fltPrm8981132; + GibPtr fltPkd8991134 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) fltPkd8991134)->field0 = 1; + + GibPtr fltPkd8961135 = + gib_alloc(sizeof(GibIntGibIntGibIntGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd8961135)->field0 = + 0; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd8961135)->field1 = + fltPkd8971133; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd8961135)->field2 = + x2726377991118; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd8961135)->field3 = + fltPkd8991134; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd8961135)->field4 = + rl2776418031122; + + GibPtr tailift1381 = + gib_alloc(sizeof(GibIntGibIntGibIntGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1381)->field0 = + 0; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1381)->field1 = + fltPkd8951131; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1381)->field2 = + rx2766408021121; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1381)->field3 = + fltPkd8961135; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1381)->field4 = + rr2786388001119; + return tailift1381; + } else { + GibInt fltPkd9001136 = 1 + rs2756398011120; + GibInt fltPkd9011137 = val207(rl2776418031122); + GibCursor fltAppE9051138 = left206(rl2776418031122); + GibInt fltPrm9041139 = size208(fltAppE9051138); + GibInt fltPkd9031140 = 1 + fltPrm9041139; + GibPtr fltPkd9061141 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) fltPkd9061141)->field0 = 1; + + GibCursor fltPkd9071142 = left206(rl2776418031122); + GibPtr fltPkd9021143 = + gib_alloc(sizeof(GibIntGibIntGibIntGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9021143)->field0 = + 0; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9021143)->field1 = + fltPkd9031140; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9021143)->field2 = + x2726377991118; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9021143)->field3 = + fltPkd9061141; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9021143)->field4 = + fltPkd9071142; + + GibInt fltPrm9111144 = size208(rr2786388001119); + GibInt fltPrm9101145 = 1 + fltPrm9111144; + GibCursor fltAppE9131146 = right205(rl2776418031122); + GibInt fltPrm9121147 = size208(fltAppE9131146); + GibInt fltPkd9091148 = fltPrm9101145 + fltPrm9121147; + GibCursor fltPkd9141149 = right205(rl2776418031122); + GibPtr fltPkd9081150 = + gib_alloc(sizeof(GibIntGibIntGibIntGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9081150)->field0 = + 0; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9081150)->field1 = + fltPkd9091148; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9081150)->field2 = + rx2766408021121; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9081150)->field3 = + fltPkd9141149; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9081150)->field4 = + rr2786388001119; + + GibPtr tailift1382 = + gib_alloc(sizeof(GibIntGibIntGibIntGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1382)->field0 = + 0; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1382)->field1 = + fltPkd9001136; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1382)->field2 = + fltPkd9011137; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1382)->field3 = + fltPkd9021143; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1382)->field4 = + fltPkd9081150; + return tailift1382; + } + break; + } + + case 1: + { + GibPtr fltPkd9161151 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) fltPkd9161151)->field0 = 1; + + GibPtr fltPkd9171152 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) fltPkd9171152)->field0 = 1; + + GibPtr fltPkd9151153 = + gib_alloc(sizeof(GibIntGibIntGibIntGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9151153)->field0 = + 0; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9151153)->field1 = + 1; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9151153)->field2 = + x2726377991118; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9151153)->field3 = + fltPkd9161151; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9151153)->field4 = + fltPkd9171152; + + GibPtr tailift1383 = + gib_alloc(sizeof(GibIntGibIntGibIntGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1383)->field0 = + 0; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1383)->field1 = + 3; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1383)->field2 = + rx2766408021121; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1383)->field3 = + fltPkd9151153; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1383)->field4 = + rr2786388001119; + return tailift1383; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1379"); + exit(1); + } + } +} +GibCursor caseFn642(GibInt x2726438081154, GibCursor r2746448091155, + GibInt rx2766458101156, GibCursor rl2776468111157) +{ + GibPackedTag tag1385 = *(GibPackedTag *) rl2776468111157; + GibCursor tail1386 = rl2776468111157 + sizeof(GibInt); + + + switch1389: + ; + switch (tag1385) { + + case 0: + { + GibInt rls2878121158 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1386)->field0; + GibInt rlx2888131159 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1386)->field1; + GibCursor rll2898141160 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1386)->field2; + GibCursor rlr2908151161 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1386)->field3; + GibInt fltPkd9181162 = val207(rl2776468111157); + GibPtr fltPkd9201163 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) fltPkd9201163)->field0 = 1; + + GibPtr fltPkd9211164 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) fltPkd9211164)->field0 = 1; + + GibPtr fltPkd9191165 = + gib_alloc(sizeof(GibIntGibIntGibIntGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9191165)->field0 = + 0; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9191165)->field1 = + 1; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9191165)->field2 = + x2726438081154; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9191165)->field3 = + fltPkd9201163; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9191165)->field4 = + fltPkd9211164; + + GibPtr fltPkd9231166 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) fltPkd9231166)->field0 = 1; + + GibPtr fltPkd9241167 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) fltPkd9241167)->field0 = 1; + + GibPtr fltPkd9221168 = + gib_alloc(sizeof(GibIntGibIntGibIntGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9221168)->field0 = + 0; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9221168)->field1 = + 1; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9221168)->field2 = + rx2766458101156; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9221168)->field3 = + fltPkd9231166; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9221168)->field4 = + fltPkd9241167; + + GibPtr tailift1387 = + gib_alloc(sizeof(GibIntGibIntGibIntGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1387)->field0 = + 0; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1387)->field1 = + 3; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1387)->field2 = + fltPkd9181162; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1387)->field3 = + fltPkd9191165; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1387)->field4 = + fltPkd9221168; + return tailift1387; + break; + } + + case 1: + { + GibPtr fltPkd9251169 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) fltPkd9251169)->field0 = 1; + + GibPtr tailift1388 = + gib_alloc(sizeof(GibIntGibIntGibIntGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1388)->field0 = + 0; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1388)->field1 = + 2; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1388)->field2 = + x2726438081154; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1388)->field3 = + fltPkd9251169; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1388)->field4 = + r2746448091155; + return tailift1388; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1385"); + exit(1); + } + } +} +GibCursor caseFn647(GibInt x2726488161170, GibCursor r2746498171171, + GibCursor rr2786508181172, GibInt rs2756518191173, + GibInt rx2766528201174, GibCursor rl2776538211175) +{ + GibPackedTag tag1390 = *(GibPackedTag *) rr2786508181172; + GibCursor tail1391 = rr2786508181172 + sizeof(GibInt); + + + switch1392: + ; + switch (tag1390) { + + case 0: + { + GibInt rrs2798221176 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1391)->field0; + GibInt rrx2808231177 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1391)->field1; + GibCursor rrl2818241178 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1391)->field2; + GibCursor rrr2828251179 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1391)->field3; + + return caseFn636(x2726488161170, rr2786508181172, rs2756518191173, + rx2766528201174, rl2776538211175); + break; + } + + case 1: + { + return caseFn642(x2726488161170, r2746498171171, rx2766528201174, + rl2776538211175); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1390"); + exit(1); + } + } +} +GibCursor caseFn654(GibInt x2726558261180, GibCursor r2746568271181) +{ + GibPackedTag tag1393 = *(GibPackedTag *) r2746568271181; + GibCursor tail1394 = r2746568271181 + sizeof(GibInt); + + + switch1396: + ; + switch (tag1393) { + + case 1: + { + GibPtr fltPkd9261182 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) fltPkd9261182)->field0 = 1; + + GibPtr fltPkd9271183 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) fltPkd9271183)->field0 = 1; + + GibPtr tailift1395 = + gib_alloc(sizeof(GibIntGibIntGibIntGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1395)->field0 = + 0; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1395)->field1 = + 1; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1395)->field2 = + x2726558261180; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1395)->field3 = + fltPkd9261182; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1395)->field4 = + fltPkd9271183; + return tailift1395; + break; + } + + case 0: + { + GibInt rs2758281184 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1394)->field0; + GibInt rx2768291185 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1394)->field1; + GibCursor rl2778301186 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1394)->field2; + GibCursor rr2788311187 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1394)->field3; + + return caseFn647(x2726558261180, r2746568271181, rr2788311187, + rs2758281184, rx2768291185, rl2778301186); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1393"); + exit(1); + } + } +} +GibCursor caseFn657(GibCursor l2736588321188, GibInt x2726598331189, + GibCursor r2746608341190, GibInt ls2916618351191) +{ + GibPackedTag tag1397 = *(GibPackedTag *) r2746608341190; + GibCursor tail1398 = r2746608341190 + sizeof(GibInt); + + + switch1403: + ; + switch (tag1397) { + + case 1: + { + GibInt fltPkd9281192 = 1 + ls2916618351191; + GibPtr fltPkd9291193 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) fltPkd9291193)->field0 = 1; + + GibPtr tailift1399 = + gib_alloc(sizeof(GibIntGibIntGibIntGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1399)->field0 = + 0; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1399)->field1 = + fltPkd9281192; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1399)->field2 = + x2726598331189; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1399)->field3 = + l2736588321188; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1399)->field4 = + fltPkd9291193; + return tailift1399; + break; + } + + case 0: + { + GibInt rs2958361194 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1398)->field0; + GibInt rx2968371195 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1398)->field1; + GibCursor rl2978381196 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1398)->field2; + GibCursor rr2988391197 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1398)->field3; + GibInt fltPrm9311198 = 3 * ls2916618351191; + GibBool fltIf9301199 = rs2958361194 > fltPrm9311198; + + if (fltIf9301199) { + GibInt fltPrm9331200 = size208(rl2978381196); + GibInt fltPrm9351201 = size208(rr2988391197); + GibInt fltPrm9341202 = 2 * fltPrm9351201; + GibBool fltIf9321203 = fltPrm9331200 < fltPrm9341202; + + if (fltIf9321203) { + GibInt fltPrm9371204 = 1 + ls2916618351191; + GibInt fltPkd9361205 = fltPrm9371204 + rs2958361194; + GibInt fltPrm9401206 = 1 + ls2916618351191; + GibInt fltPrm9411207 = size208(rl2978381196); + GibInt fltPkd9391208 = fltPrm9401206 + fltPrm9411207; + GibPtr fltPkd9381209 = + gib_alloc(sizeof(GibIntGibIntGibIntGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9381209)->field0 = + 0; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9381209)->field1 = + fltPkd9391208; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9381209)->field2 = + x2726598331189; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9381209)->field3 = + l2736588321188; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9381209)->field4 = + rl2978381196; + + GibPtr tailift1400 = + gib_alloc(sizeof(GibIntGibIntGibIntGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1400)->field0 = + 0; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1400)->field1 = + fltPkd9361205; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1400)->field2 = + rx2968371195; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1400)->field3 = + fltPkd9381209; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1400)->field4 = + rr2988391197; + return tailift1400; + } else { + GibInt fltPrm9431210 = 1 + ls2916618351191; + GibInt fltPkd9421211 = fltPrm9431210 + rs2958361194; + GibInt fltPkd9441212 = val207(rl2978381196); + GibInt fltPrm9471213 = 1 + ls2916618351191; + GibCursor fltAppE9491214 = left206(rl2978381196); + GibInt fltPrm9481215 = size208(fltAppE9491214); + GibInt fltPkd9461216 = fltPrm9471213 + fltPrm9481215; + GibCursor fltPkd9501217 = left206(rl2978381196); + GibPtr fltPkd9451218 = + gib_alloc(sizeof(GibIntGibIntGibIntGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9451218)->field0 = + 0; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9451218)->field1 = + fltPkd9461216; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9451218)->field2 = + x2726598331189; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9451218)->field3 = + l2736588321188; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9451218)->field4 = + fltPkd9501217; + + GibInt fltPrm9541219 = size208(rr2988391197); + GibInt fltPrm9531220 = 1 + fltPrm9541219; + GibCursor fltAppE9561221 = right205(rl2978381196); + GibInt fltPrm9551222 = size208(fltAppE9561221); + GibInt fltPkd9521223 = fltPrm9531220 + fltPrm9551222; + GibCursor fltPkd9571224 = right205(rl2978381196); + GibPtr fltPkd9511225 = + gib_alloc(sizeof(GibIntGibIntGibIntGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9511225)->field0 = + 0; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9511225)->field1 = + fltPkd9521223; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9511225)->field2 = + rx2968371195; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9511225)->field3 = + fltPkd9571224; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9511225)->field4 = + rr2988391197; + + GibPtr tailift1401 = + gib_alloc(sizeof(GibIntGibIntGibIntGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1401)->field0 = + 0; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1401)->field1 = + fltPkd9421211; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1401)->field2 = + fltPkd9441212; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1401)->field3 = + fltPkd9451218; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1401)->field4 = + fltPkd9511225; + return tailift1401; + } + } else { + GibInt fltPrm9591226 = 1 + ls2916618351191; + GibInt fltPkd9581227 = fltPrm9591226 + rs2958361194; + GibPtr tailift1402 = + gib_alloc(sizeof(GibIntGibIntGibIntGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1402)->field0 = + 0; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1402)->field1 = + fltPkd9581227; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1402)->field2 = + x2726598331189; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1402)->field3 = + l2736588321188; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1402)->field4 = + r2746608341190; + return tailift1402; + } + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1397"); + exit(1); + } + } +} +GibCursor caseFn662(GibInt x2996638401228, GibCursor ll3046648411229, + GibInt ls3026658421230, GibInt lx3036668431231, + GibCursor lr3056678441232, GibInt lls3066688451233) +{ + GibPackedTag tag1404 = *(GibPackedTag *) lr3056678441232; + GibCursor tail1405 = lr3056678441232 + sizeof(GibInt); + + + switch1409: + ; + switch (tag1404) { + + case 0: + { + GibInt lrs3108461234 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1405)->field0; + GibInt lrx3118471235 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1405)->field1; + GibCursor lrl3128481236 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1405)->field2; + GibCursor lrr3138491237 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1405)->field3; + GibInt fltPrm9611238 = 2 * lls3066688451233; + GibBool fltIf9601239 = lrs3108461234 < fltPrm9611238; + + if (fltIf9601239) { + GibInt fltPkd9621240 = 1 + ls3026658421230; + GibInt fltPkd9641241 = 1 + lrs3108461234; + GibPtr fltPkd9651242 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) fltPkd9651242)->field0 = 1; + + GibPtr fltPkd9631243 = + gib_alloc(sizeof(GibIntGibIntGibIntGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9631243)->field0 = + 0; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9631243)->field1 = + fltPkd9641241; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9631243)->field2 = + x2996638401228; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9631243)->field3 = + lr3056678441232; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9631243)->field4 = + fltPkd9651242; + + GibPtr tailift1406 = + gib_alloc(sizeof(GibIntGibIntGibIntGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1406)->field0 = + 0; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1406)->field1 = + fltPkd9621240; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1406)->field2 = + lx3036668431231; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1406)->field3 = + ll3046648411229; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1406)->field4 = + fltPkd9631243; + return tailift1406; + } else { + GibInt fltPkd9661244 = 1 + ls3026658421230; + GibInt fltPrm9691245 = 1 + lls3066688451233; + GibInt fltPrm9701246 = size208(lrl3128481236); + GibInt fltPkd9681247 = fltPrm9691245 + fltPrm9701246; + GibPtr fltPkd9671248 = + gib_alloc(sizeof(GibIntGibIntGibIntGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9671248)->field0 = + 0; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9671248)->field1 = + fltPkd9681247; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9671248)->field2 = + lx3036668431231; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9671248)->field3 = + ll3046648411229; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9671248)->field4 = + lrl3128481236; + + GibInt fltPrm9731249 = size208(lrr3138491237); + GibInt fltPkd9721250 = 1 + fltPrm9731249; + GibPtr fltPkd9741251 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) fltPkd9741251)->field0 = 1; + + GibPtr fltPkd9711252 = + gib_alloc(sizeof(GibIntGibIntGibIntGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9711252)->field0 = + 0; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9711252)->field1 = + fltPkd9721250; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9711252)->field2 = + x2996638401228; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9711252)->field3 = + lrr3138491237; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9711252)->field4 = + fltPkd9741251; + + GibPtr tailift1407 = + gib_alloc(sizeof(GibIntGibIntGibIntGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1407)->field0 = + 0; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1407)->field1 = + fltPkd9661244; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1407)->field2 = + lrx3118471235; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1407)->field3 = + fltPkd9671248; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1407)->field4 = + fltPkd9711252; + return tailift1407; + } + break; + } + + case 1: + { + GibPtr fltPkd9761253 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) fltPkd9761253)->field0 = 1; + + GibPtr fltPkd9771254 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) fltPkd9771254)->field0 = 1; + + GibPtr fltPkd9751255 = + gib_alloc(sizeof(GibIntGibIntGibIntGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9751255)->field0 = + 0; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9751255)->field1 = + 1; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9751255)->field2 = + x2996638401228; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9751255)->field3 = + fltPkd9761253; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9751255)->field4 = + fltPkd9771254; + + GibPtr tailift1408 = + gib_alloc(sizeof(GibIntGibIntGibIntGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1408)->field0 = + 0; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1408)->field1 = + 3; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1408)->field2 = + lx3036668431231; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1408)->field3 = + ll3046648411229; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1408)->field4 = + fltPkd9751255; + return tailift1408; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1404"); + exit(1); + } + } +} +GibCursor caseFn669(GibInt x2996708501256, GibCursor l3006718511257, + GibInt lx3036728521258, GibCursor lr3056738531259) +{ + GibPackedTag tag1410 = *(GibPackedTag *) lr3056738531259; + GibCursor tail1411 = lr3056738531259 + sizeof(GibInt); + + + switch1414: + ; + switch (tag1410) { + + case 0: + { + GibInt lrs3148541260 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1411)->field0; + GibInt lrx3158551261 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1411)->field1; + GibCursor lrl3168561262 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1411)->field2; + GibCursor lrr3178571263 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1411)->field3; + GibPtr fltPkd9791264 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) fltPkd9791264)->field0 = 1; + + GibPtr fltPkd9801265 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) fltPkd9801265)->field0 = 1; + + GibPtr fltPkd9781266 = + gib_alloc(sizeof(GibIntGibIntGibIntGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9781266)->field0 = + 0; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9781266)->field1 = + 1; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9781266)->field2 = + lx3036728521258; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9781266)->field3 = + fltPkd9791264; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9781266)->field4 = + fltPkd9801265; + + GibPtr fltPkd9821267 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) fltPkd9821267)->field0 = 1; + + GibPtr fltPkd9831268 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) fltPkd9831268)->field0 = 1; + + GibPtr fltPkd9811269 = + gib_alloc(sizeof(GibIntGibIntGibIntGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9811269)->field0 = + 0; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9811269)->field1 = + 1; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9811269)->field2 = + x2996708501256; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9811269)->field3 = + fltPkd9821267; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9811269)->field4 = + fltPkd9831268; + + GibPtr tailift1412 = + gib_alloc(sizeof(GibIntGibIntGibIntGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1412)->field0 = + 0; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1412)->field1 = + 3; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1412)->field2 = + lrx3158551261; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1412)->field3 = + fltPkd9781266; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1412)->field4 = + fltPkd9811269; + return tailift1412; + break; + } + + case 1: + { + GibPtr fltPkd9841270 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) fltPkd9841270)->field0 = 1; + + GibPtr tailift1413 = + gib_alloc(sizeof(GibIntGibIntGibIntGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1413)->field0 = + 0; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1413)->field1 = + 2; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1413)->field2 = + x2996708501256; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1413)->field3 = + l3006718511257; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1413)->field4 = + fltPkd9841270; + return tailift1413; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1410"); + exit(1); + } + } +} +GibCursor caseFn674(GibInt x2996758581271, GibCursor l3006768591272, + GibCursor ll3046778601273, GibInt ls3026788611274, + GibInt lx3036798621275, GibCursor lr3056808631276) +{ + GibPackedTag tag1415 = *(GibPackedTag *) ll3046778601273; + GibCursor tail1416 = ll3046778601273 + sizeof(GibInt); + + + switch1417: + ; + switch (tag1415) { + + case 0: + { + GibInt lls3068641277 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1416)->field0; + GibInt llx3078651278 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1416)->field1; + GibCursor lll3088661279 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1416)->field2; + GibCursor llr3098671280 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1416)->field3; + + return caseFn662(x2996758581271, ll3046778601273, ls3026788611274, + lx3036798621275, lr3056808631276, lls3068641277); + break; + } + + case 1: + { + return caseFn669(x2996758581271, l3006768591272, lx3036798621275, + lr3056808631276); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1415"); + exit(1); + } + } +} +GibCursor caseFn681(GibInt x2996828681281, GibCursor l3006838691282) +{ + GibPackedTag tag1418 = *(GibPackedTag *) l3006838691282; + GibCursor tail1419 = l3006838691282 + sizeof(GibInt); + + + switch1421: + ; + switch (tag1418) { + + case 1: + { + GibPtr fltPkd9851283 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) fltPkd9851283)->field0 = 1; + + GibPtr fltPkd9861284 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) fltPkd9861284)->field0 = 1; + + GibPtr tailift1420 = + gib_alloc(sizeof(GibIntGibIntGibIntGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1420)->field0 = + 0; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1420)->field1 = + 1; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1420)->field2 = + x2996828681281; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1420)->field3 = + fltPkd9851283; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1420)->field4 = + fltPkd9861284; + return tailift1420; + break; + } + + case 0: + { + GibInt ls3028701285 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1419)->field0; + GibInt lx3038711286 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1419)->field1; + GibCursor ll3048721287 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1419)->field2; + GibCursor lr3058731288 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1419)->field3; + + return caseFn674(x2996828681281, l3006838691282, ll3048721287, + ls3028701285, lx3038711286, lr3058731288); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1418"); + exit(1); + } + } +} +GibCursor caseFn684(GibCursor r3016858741289, GibInt x2996868751290, + GibCursor l3006878761291, GibInt rs3186888771292) +{ + GibPackedTag tag1422 = *(GibPackedTag *) l3006878761291; + GibCursor tail1423 = l3006878761291 + sizeof(GibInt); + + + switch1428: + ; + switch (tag1422) { + + case 1: + { + GibInt fltPkd9871293 = 1 + rs3186888771292; + GibPtr fltPkd9881294 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) fltPkd9881294)->field0 = 1; + + GibPtr tailift1424 = + gib_alloc(sizeof(GibIntGibIntGibIntGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1424)->field0 = + 0; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1424)->field1 = + fltPkd9871293; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1424)->field2 = + x2996868751290; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1424)->field3 = + fltPkd9881294; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1424)->field4 = + r3016858741289; + return tailift1424; + break; + } + + case 0: + { + GibInt ls3228781295 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1423)->field0; + GibInt lx3238791296 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1423)->field1; + GibCursor ll3248801297 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1423)->field2; + GibCursor lr3258811298 = + ((GibIntGibIntGibCursorGibCursorProd *) tail1423)->field3; + GibInt fltPrm9901299 = 3 * rs3186888771292; + GibBool fltIf9891300 = ls3228781295 > fltPrm9901299; + + if (fltIf9891300) { + GibInt fltPrm9921301 = size208(lr3258811298); + GibInt fltPrm9941302 = size208(ll3248801297); + GibInt fltPrm9931303 = 2 * fltPrm9941302; + GibBool fltIf9911304 = fltPrm9921301 < fltPrm9931303; + + if (fltIf9911304) { + GibInt fltPrm9961305 = 1 + ls3228781295; + GibInt fltPkd9951306 = fltPrm9961305 + rs3186888771292; + GibInt fltPrm9991307 = 1 + rs3186888771292; + GibInt fltPrm10001308 = size208(lr3258811298); + GibInt fltPkd9981309 = fltPrm9991307 + fltPrm10001308; + GibPtr fltPkd9971310 = + gib_alloc(sizeof(GibIntGibIntGibIntGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9971310)->field0 = + 0; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9971310)->field1 = + fltPkd9981309; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9971310)->field2 = + x2996868751290; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9971310)->field3 = + lr3258811298; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd9971310)->field4 = + r3016858741289; + + GibPtr tailift1425 = + gib_alloc(sizeof(GibIntGibIntGibIntGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1425)->field0 = + 0; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1425)->field1 = + fltPkd9951306; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1425)->field2 = + lx3238791296; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1425)->field3 = + ll3248801297; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1425)->field4 = + fltPkd9971310; + return tailift1425; + } else { + GibInt fltPrm10021311 = 1 + ls3228781295; + GibInt fltPkd10011312 = fltPrm10021311 + rs3186888771292; + GibInt fltPkd10031313 = val207(lr3258811298); + GibInt fltPrm10071314 = size208(ll3248801297); + GibInt fltPrm10061315 = 1 + fltPrm10071314; + GibCursor fltAppE10091316 = left206(lr3258811298); + GibInt fltPrm10081317 = size208(fltAppE10091316); + GibInt fltPkd10051318 = fltPrm10061315 + fltPrm10081317; + GibCursor fltPkd10101319 = left206(lr3258811298); + GibPtr fltPkd10041320 = + gib_alloc(sizeof(GibIntGibIntGibIntGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd10041320)->field0 = + 0; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd10041320)->field1 = + fltPkd10051318; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd10041320)->field2 = + lx3238791296; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd10041320)->field3 = + ll3248801297; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd10041320)->field4 = + fltPkd10101319; + + GibInt fltPrm10131321 = 1 + rs3186888771292; + GibCursor fltAppE10151322 = right205(lr3258811298); + GibInt fltPrm10141323 = size208(fltAppE10151322); + GibInt fltPkd10121324 = fltPrm10131321 + fltPrm10141323; + GibCursor fltPkd10161325 = right205(lr3258811298); + GibPtr fltPkd10111326 = + gib_alloc(sizeof(GibIntGibIntGibIntGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd10111326)->field0 = + 0; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd10111326)->field1 = + fltPkd10121324; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd10111326)->field2 = + x2996868751290; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd10111326)->field3 = + fltPkd10161325; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) fltPkd10111326)->field4 = + r3016858741289; + + GibPtr tailift1426 = + gib_alloc(sizeof(GibIntGibIntGibIntGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1426)->field0 = + 0; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1426)->field1 = + fltPkd10011312; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1426)->field2 = + fltPkd10031313; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1426)->field3 = + fltPkd10041320; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1426)->field4 = + fltPkd10111326; + return tailift1426; + } + } else { + GibInt fltPrm10181327 = 1 + ls3228781295; + GibInt fltPkd10171328 = fltPrm10181327 + rs3186888771292; + GibPtr tailift1427 = + gib_alloc(sizeof(GibIntGibIntGibIntGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1427)->field0 = + 0; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1427)->field1 = + fltPkd10171328; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1427)->field2 = + x2996868751290; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1427)->field3 = + l3006878761291; + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tailift1427)->field4 = + r3016858741289; + return tailift1427; + } + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1422"); + exit(1); + } + } +} +int main(int argc, char **argv) +{ + int init0 = gib_init(argc, argv); + + info_table_initialize(); + symbol_table_initialize(); + + GibCursor fltAppE8831019 = empty202(); + GibCursor fltAppE8821020 = insert214(0, fltAppE8831019); + GibInt tmp_app1329 = sum203(fltAppE8821020); + + printf("%ld", tmp_app1329); + printf("\n"); + + int exit1 = gib_exit(); + + return exit1; +} \ No newline at end of file diff --git a/benchmarks/CRDTs/Set.hs b/benchmarks/CRDTs/Set.hs new file mode 100644 index 000000000..5686d9e87 --- /dev/null +++ b/benchmarks/CRDTs/Set.hs @@ -0,0 +1,139 @@ +{-# LANGUAGE BlockArguments #-} + +module Set where + +-- type size value left right +type Size = Int +data IntSet = PureSet Int Int IntSet IntSet | EmptySet + +-- Construction -------------------------------------------- + +-- Create an empty set +empty :: IntSet +empty = EmptySet + +-- Create a set with an initialization element +singleton :: Int -> IntSet +singleton x = PureSet 1 x EmptySet EmptySet + +-- Insertion, Deletion -------------------------------------- +insert :: Int -> IntSet -> IntSet +insert x s = + case s of + EmptySet -> singleton x + PureSet sz v l r -> + if x == v then s + else if x <= v then + let nl = insert x l + in balanceL v nl r + else + let nr = insert x r + in balanceR v l nr + +balanceL :: Int -> IntSet -> IntSet -> IntSet +balanceL x l r = case r of + EmptySet -> case l of + EmptySet -> PureSet 1 x EmptySet EmptySet + PureSet ls lx ll lr -> + case ll of + PureSet lls llx lll llr -> case lr of + PureSet lrs lrx lrl lrr -> + if (lrs < 2*lls) then PureSet (1+ls) lx ll (PureSet (1+lrs) x lr EmptySet) + else PureSet (1+ls) lrx (PureSet (1+lls+size lrl) lx ll lrl) (PureSet (1+size lrr) x lrr EmptySet) + EmptySet -> PureSet 3 lx ll (PureSet 1 x EmptySet EmptySet) + EmptySet -> case lr of + PureSet lrs lrx lrl lrr -> PureSet 3 lrx (PureSet 1 lx EmptySet EmptySet) (PureSet 1 x EmptySet EmptySet) + EmptySet -> PureSet 2 x l EmptySet + + PureSet rs _ _ _ -> case l of + EmptySet -> PureSet (1+rs) x EmptySet r + + PureSet ls lx ll lr -> + if (ls > 3*rs) then + if ((size lr) < 2*(size ll)) then PureSet (1+ls+rs) lx ll (PureSet (1+rs+(size lr)) x lr r) + else PureSet (1+ls+rs) (val lr) (PureSet (1+(size ll)+(size (left lr))) lx ll (left lr)) (PureSet (1+rs+(size (right lr))) x (right lr) r) + else PureSet (1+ls+rs) x l r + +balanceR :: Int -> IntSet -> IntSet -> IntSet +balanceR x l r = case l of + EmptySet -> case r of + EmptySet -> PureSet 1 x EmptySet EmptySet + PureSet rs rx rl rr -> + case rr of + PureSet rrs rrx rrl rrr -> case rl of + PureSet rls rlx rll rlr -> + if ((size rl) < 2*(size rr)) then PureSet (1+rs) rx (PureSet (1+(size rl)) x EmptySet rl) rr + else PureSet (1+rs) (val rl) (PureSet (1+(size (left rl))) x EmptySet (left rl)) (PureSet (1+(size rr)+(size (right rl))) rx (right rl) rr) + EmptySet -> PureSet 3 rx (PureSet 1 x EmptySet EmptySet) rr + EmptySet -> case rl of + PureSet rls rlx rll rlr -> PureSet 3 (val rl) (PureSet 1 x EmptySet EmptySet) (PureSet 1 rx EmptySet EmptySet) + EmptySet -> PureSet 2 x EmptySet r + + PureSet ls _ _ _ -> case r of + EmptySet -> PureSet (1+ls) x l EmptySet + + PureSet rs rx rl rr -> + if (rs > 3*ls) then + if ((size rl) < 2*(size rr)) then PureSet (1+ls+rs) rx (PureSet (1+ls+(size rl)) x l rl) rr + else PureSet (1+ls+rs) (val rl) (PureSet (1+ls+(size (left rl))) x l (left rl)) (PureSet (1+(size rr)+(size (right rl))) rx (right rl) rr) + else PureSet (1+ls+rs) x l r + +-- Contents ------------------------------------------------ + +-- Check if the set is empty +null :: IntSet -> Bool +null s = + case s of + EmptySet -> True + PureSet _ _ _ _ -> False +-- Check if a set has an element +member :: Int -> IntSet -> Bool +member x s = + case s of + EmptySet -> False + PureSet _ v l r -> + if x == v then True + else if x <= v then member x l + else member x r + +depth :: Int -> Int -> IntSet -> Int +depth x c s = + case s of + EmptySet -> -1 + PureSet _ v l r -> + if x == v then c + 1 + else if x <= v then depth x (c+1) l + else depth x (c+1) r + +size :: IntSet -> Int +size s = case s of + EmptySet -> 0 + PureSet sz _ _ _ -> sz + +val :: IntSet -> Int +val x = case x of + EmptySet -> 0 + PureSet _ v _ _ -> v + +left :: IntSet -> IntSet +left x = case x of + EmptySet -> EmptySet + PureSet _ _ l _ -> l + +right :: IntSet -> IntSet +right x = case x of + EmptySet -> EmptySet + PureSet _ _ _ r -> r + +insert_num :: Int -> IntSet -> IntSet +insert_num x s = + if x == 0 then insert x s + else insert x (insert_num (x-1) s) + +sum :: IntSet -> Int +sum s = case s of + EmptySet -> 0 + PureSet _ v l r -> v + (Set.sum l) + (Set.sum r) + +--gibbon_main = sum (insert_num 100 (insert_num 100 empty)) +gibbon_main = Set.sum (insert 0 empty) \ No newline at end of file diff --git a/benchmarks/CRDTs/Timekeeping.c b/benchmarks/CRDTs/Timekeeping.c new file mode 100644 index 000000000..d311242e2 --- /dev/null +++ b/benchmarks/CRDTs/Timekeeping.c @@ -0,0 +1,902 @@ +/* Gibbon program. */ + +#include "gibbon_rts.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef _WIN64 +#include +#endif + +#ifdef _GIBBON_POINTER +#include +#endif + +#ifdef _GIBBON_PARALLEL +#include +#include +#endif + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Program starts here + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +typedef struct GibIntProd_struct { + GibInt field0; + } GibIntProd; +typedef struct GibIntGibIntProd_struct { + GibInt field0; + GibInt field1; + } GibIntGibIntProd; +typedef struct GibIntGibIntGibIntGibIntGibCursorGibCursorProd_struct { + GibInt field0; + GibInt field1; + GibInt field2; + GibInt field3; + GibCursor field4; + GibCursor field5; + } GibIntGibIntGibIntGibIntGibCursorGibCursorProd; +typedef struct GibIntGibIntGibIntGibCursorGibCursorProd_struct { + GibInt field0; + GibInt field1; + GibInt field2; + GibCursor field3; + GibCursor field4; + } GibIntGibIntGibIntGibCursorGibCursorProd; +typedef struct GibIntGibIntGibCursorProd_struct { + GibInt field0; + GibInt field1; + GibCursor field2; + } GibIntGibIntGibCursorProd; +typedef struct GibPackedTagGibCursorProd_struct { + GibPackedTag field0; + GibCursor field1; + } GibPackedTagGibCursorProd; +typedef struct GibCursorProd_struct { + GibCursor field0; + } GibCursorProd; +GibCursor _copy_Clock101(GibCursor arg105613651556); +GibCursor _copy_without_ptrs_Clock101(GibCursor arg106113701561); +unsigned char _traverse_Clock101(GibCursor arg106613751566); +unsigned char _print_Clock101(GibCursor arg107113791570); +GibCursor _copy_Timestamp102(GibCursor arg108013881579); +GibCursor _copy_without_ptrs_Timestamp102(GibCursor arg108513931584); +unsigned char _traverse_Timestamp102(GibCursor arg109013981589); +unsigned char _print_Timestamp102(GibCursor arg109514021593); +GibCursor _copy_Ord107(GibCursor arg110414111602); +GibCursor _copy_without_ptrs_Ord107(GibCursor arg110514121603); +unsigned char _traverse_Ord107(GibCursor arg110614131604); +unsigned char _print_Ord107(GibCursor arg110714141605); +GibCursor _copy_Maybe106_v701(GibCursor arg111614231614); +GibCursor _copy_without_ptrs_Maybe106_v701(GibCursor arg111914261617); +unsigned char _traverse_Maybe106_v701(GibCursor arg112214291620); +unsigned char _print_Maybe106_v701(GibCursor arg112514311622); +GibCursor _copy_Map137_v699(GibCursor arg113314391630); +GibCursor _copy_without_ptrs_Map137_v699(GibCursor arg114414501641); +unsigned char _traverse_Map137_v699(GibCursor arg115514611652); +unsigned char _print_Map137_v699(GibCursor arg116614691660); +typedef enum { + GibInt_T, + GibFloat_T, + GibSym_T, + GibBool_T, + GibVector_T, + GibList_T, + GibCursor_T, + Clock101_T, + Map137_v699_T, + Maybe106_v701_T, + Ord107_T, + Timestamp102_T, + } GibDatatype; +void info_table_initialize(void) +{ + int error = gib_info_table_initialize(12); + + if (error < 0) { + fprintf(stderr, "Couldn't initialize info table, errorno=%d", error); + exit(1); + } + + GibDatatype field_tys[3]; + + error = gib_info_table_insert_packed_dcon(Clock101_T, 0, 8, 1, 1, 0, + field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, Clock101_T, 0); + exit(1); + } + error = gib_info_table_insert_packed_dcon(Map137_v699_T, 1, 24, 2, 3, 0, + field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, Map137_v699_T, 1); + exit(1); + } + error = gib_info_table_insert_packed_dcon(Map137_v699_T, 0, 0, 0, 0, 0, + field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, Map137_v699_T, 0); + exit(1); + } + error = gib_info_table_insert_packed_dcon(Maybe106_v701_T, 1, 8, 0, 1, 0, + field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, Maybe106_v701_T, 1); + exit(1); + } + error = gib_info_table_insert_packed_dcon(Maybe106_v701_T, 0, 0, 0, 0, 0, + field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, Maybe106_v701_T, 0); + exit(1); + } + error = gib_info_table_insert_packed_dcon(Ord107_T, 3, 0, 0, 0, 0, + field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, Ord107_T, 3); + exit(1); + } + error = gib_info_table_insert_packed_dcon(Ord107_T, 2, 0, 0, 0, 0, + field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, Ord107_T, 2); + exit(1); + } + error = gib_info_table_insert_packed_dcon(Ord107_T, 1, 0, 0, 0, 0, + field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, Ord107_T, 1); + exit(1); + } + error = gib_info_table_insert_packed_dcon(Ord107_T, 0, 0, 0, 0, 0, + field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, Ord107_T, 0); + exit(1); + } + error = gib_info_table_insert_packed_dcon(Timestamp102_T, 0, 8, 1, 1, 0, + field_tys, 0); + if (error < 0) { + fprintf(stderr, + "Couldn't insert into info table, errorno=%d, tycon=%d, dcon=%d", + error, Timestamp102_T, 0); + exit(1); + } + gib_info_table_finalize(); +} +void symbol_table_initialize(void) +{ + gib_add_symbol(1680, ")"); + gib_add_symbol(1681, "(Tip138_v699"); + gib_add_symbol(1682, "(Timestamp103"); + gib_add_symbol(1683, "(Nothing112_v701"); + gib_add_symbol(1684, "(Lt108"); + gib_add_symbol(1685, "(Just113_v701"); + gib_add_symbol(1686, "(Gt109"); + gib_add_symbol(1687, "(Eq110"); + gib_add_symbol(1688, "(Clk104"); + gib_add_symbol(1689, "(Cc111"); + gib_add_symbol(1690, "(Bin139_v699"); + gib_add_symbol(1691, " "); +} +GibCursor _copy_Clock101(GibCursor arg105613651556) +{ + GibInt tag1692 = ((GibIntGibIntGibCursorProd *) arg105613651556)->field0; + GibInt x105713661557 = + ((GibIntGibIntGibCursorProd *) arg105613651556)->field1; + GibCursor x105813671558 = + ((GibIntGibIntGibCursorProd *) arg105613651556)->field2; + GibCursor y106013691560 = _copy_Map137_v699(x105813671558); + GibPtr tailift1693 = gib_alloc(sizeof(GibIntGibIntGibCursorProd)); + + ((GibIntGibIntGibCursorProd *) tailift1693)->field0 = 0; + ((GibIntGibIntGibCursorProd *) tailift1693)->field1 = x105713661557; + ((GibIntGibIntGibCursorProd *) tailift1693)->field2 = y106013691560; + return tailift1693; +} +GibCursor _copy_without_ptrs_Clock101(GibCursor arg106113701561) +{ + GibInt tag1694 = ((GibIntGibIntGibCursorProd *) arg106113701561)->field0; + GibInt x106213711562 = + ((GibIntGibIntGibCursorProd *) arg106113701561)->field1; + GibCursor x106313721563 = + ((GibIntGibIntGibCursorProd *) arg106113701561)->field2; + GibCursor y106513741565 = _copy_without_ptrs_Map137_v699(x106313721563); + GibPtr tailift1695 = gib_alloc(sizeof(GibIntGibIntGibCursorProd)); + + ((GibIntGibIntGibCursorProd *) tailift1695)->field0 = 0; + ((GibIntGibIntGibCursorProd *) tailift1695)->field1 = x106213711562; + ((GibIntGibIntGibCursorProd *) tailift1695)->field2 = y106513741565; + return tailift1695; +} +unsigned char _traverse_Clock101(GibCursor arg106613751566) +{ + GibInt tag1696 = ((GibIntGibIntGibCursorProd *) arg106613751566)->field0; + GibInt x106713761567 = + ((GibIntGibIntGibCursorProd *) arg106613751566)->field1; + GibCursor x106813771568 = + ((GibIntGibIntGibCursorProd *) arg106613751566)->field2; + unsigned char y107013781569 = _traverse_Map137_v699(x106813771568); + + return 0; +} +unsigned char _print_Clock101(GibCursor arg107113791570) +{ + GibInt tag1697 = ((GibIntGibIntGibCursorProd *) arg107113791570)->field0; + GibInt x107213801571 = + ((GibIntGibIntGibCursorProd *) arg107113791570)->field1; + GibCursor x107313811572 = + ((GibIntGibIntGibCursorProd *) arg107113791570)->field2; + unsigned char wildcard107613821573 = gib_print_symbol(1688); + unsigned char wildcard107913831574 = gib_print_symbol(1691); + unsigned char y107413841575 = printf("%ld", x107213801571); + unsigned char wildcard107813851576 = gib_print_symbol(1691); + unsigned char y107513861577 = _print_Map137_v699(x107313811572); + unsigned char wildcard107713871578 = gib_print_symbol(1680); + + return 0; +} +GibCursor _copy_Timestamp102(GibCursor arg108013881579) +{ + GibInt tag1698 = ((GibIntGibIntGibCursorProd *) arg108013881579)->field0; + GibInt x108113891580 = + ((GibIntGibIntGibCursorProd *) arg108013881579)->field1; + GibCursor x108213901581 = + ((GibIntGibIntGibCursorProd *) arg108013881579)->field2; + GibCursor y108413921583 = _copy_Clock101(x108213901581); + GibPtr tailift1699 = gib_alloc(sizeof(GibIntGibIntGibCursorProd)); + + ((GibIntGibIntGibCursorProd *) tailift1699)->field0 = 0; + ((GibIntGibIntGibCursorProd *) tailift1699)->field1 = x108113891580; + ((GibIntGibIntGibCursorProd *) tailift1699)->field2 = y108413921583; + return tailift1699; +} +GibCursor _copy_without_ptrs_Timestamp102(GibCursor arg108513931584) +{ + GibInt tag1700 = ((GibIntGibIntGibCursorProd *) arg108513931584)->field0; + GibInt x108613941585 = + ((GibIntGibIntGibCursorProd *) arg108513931584)->field1; + GibCursor x108713951586 = + ((GibIntGibIntGibCursorProd *) arg108513931584)->field2; + GibCursor y108913971588 = _copy_without_ptrs_Clock101(x108713951586); + GibPtr tailift1701 = gib_alloc(sizeof(GibIntGibIntGibCursorProd)); + + ((GibIntGibIntGibCursorProd *) tailift1701)->field0 = 0; + ((GibIntGibIntGibCursorProd *) tailift1701)->field1 = x108613941585; + ((GibIntGibIntGibCursorProd *) tailift1701)->field2 = y108913971588; + return tailift1701; +} +unsigned char _traverse_Timestamp102(GibCursor arg109013981589) +{ + GibInt tag1702 = ((GibIntGibIntGibCursorProd *) arg109013981589)->field0; + GibInt x109113991590 = + ((GibIntGibIntGibCursorProd *) arg109013981589)->field1; + GibCursor x109214001591 = + ((GibIntGibIntGibCursorProd *) arg109013981589)->field2; + unsigned char y109414011592 = _traverse_Clock101(x109214001591); + + return 0; +} +unsigned char _print_Timestamp102(GibCursor arg109514021593) +{ + GibInt tag1703 = ((GibIntGibIntGibCursorProd *) arg109514021593)->field0; + GibInt x109614031594 = + ((GibIntGibIntGibCursorProd *) arg109514021593)->field1; + GibCursor x109714041595 = + ((GibIntGibIntGibCursorProd *) arg109514021593)->field2; + unsigned char wildcard110014051596 = gib_print_symbol(1682); + unsigned char wildcard110314061597 = gib_print_symbol(1691); + unsigned char y109814071598 = printf("%ld", x109614031594); + unsigned char wildcard110214081599 = gib_print_symbol(1691); + unsigned char y109914091600 = _print_Clock101(x109714041595); + unsigned char wildcard110114101601 = gib_print_symbol(1680); + + return 0; +} +GibCursor _copy_Ord107(GibCursor arg110414111602) +{ + GibPackedTag tag1704 = *(GibPackedTag *) arg110414111602; + GibCursor tail1705 = arg110414111602 + sizeof(GibInt); + + + switch1710: + ; + switch (tag1704) { + + case 0: + { + GibPtr tailift1706 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift1706)->field0 = 0; + return tailift1706; + break; + } + + case 1: + { + GibPtr tailift1707 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift1707)->field0 = 1; + return tailift1707; + break; + } + + case 2: + { + GibPtr tailift1708 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift1708)->field0 = 2; + return tailift1708; + break; + } + + case 3: + { + GibPtr tailift1709 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift1709)->field0 = 3; + return tailift1709; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1704"); + exit(1); + } + } +} +GibCursor _copy_without_ptrs_Ord107(GibCursor arg110514121603) +{ + GibPackedTag tag1711 = *(GibPackedTag *) arg110514121603; + GibCursor tail1712 = arg110514121603 + sizeof(GibInt); + + + switch1717: + ; + switch (tag1711) { + + case 0: + { + GibPtr tailift1713 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift1713)->field0 = 0; + return tailift1713; + break; + } + + case 1: + { + GibPtr tailift1714 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift1714)->field0 = 1; + return tailift1714; + break; + } + + case 2: + { + GibPtr tailift1715 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift1715)->field0 = 2; + return tailift1715; + break; + } + + case 3: + { + GibPtr tailift1716 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift1716)->field0 = 3; + return tailift1716; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1711"); + exit(1); + } + } +} +unsigned char _traverse_Ord107(GibCursor arg110614131604) +{ + GibPackedTag tag1718 = *(GibPackedTag *) arg110614131604; + GibCursor tail1719 = arg110614131604 + sizeof(GibInt); + + + switch1720: + ; + switch (tag1718) { + + case 0: + { + return 0; + break; + } + + case 1: + { + return 0; + break; + } + + case 2: + { + return 0; + break; + } + + case 3: + { + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1718"); + exit(1); + } + } +} +unsigned char _print_Ord107(GibCursor arg110714141605) +{ + GibPackedTag tag1721 = *(GibPackedTag *) arg110714141605; + GibCursor tail1722 = arg110714141605 + sizeof(GibInt); + + + switch1723: + ; + switch (tag1721) { + + case 0: + { + unsigned char wildcard110814151606 = gib_print_symbol(1684); + unsigned char wildcard110914161607 = gib_print_symbol(1680); + + return 0; + break; + } + + case 1: + { + unsigned char wildcard111014171608 = gib_print_symbol(1686); + unsigned char wildcard111114181609 = gib_print_symbol(1680); + + return 0; + break; + } + + case 2: + { + unsigned char wildcard111214191610 = gib_print_symbol(1687); + unsigned char wildcard111314201611 = gib_print_symbol(1680); + + return 0; + break; + } + + case 3: + { + unsigned char wildcard111414211612 = gib_print_symbol(1689); + unsigned char wildcard111514221613 = gib_print_symbol(1680); + + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1721"); + exit(1); + } + } +} +GibCursor _copy_Maybe106_v701(GibCursor arg111614231614) +{ + GibPackedTag tag1724 = *(GibPackedTag *) arg111614231614; + GibCursor tail1725 = arg111614231614 + sizeof(GibInt); + + + switch1728: + ; + switch (tag1724) { + + case 0: + { + GibPtr tailift1726 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift1726)->field0 = 0; + return tailift1726; + break; + } + + case 1: + { + GibInt x111714241615 = ((GibIntProd *) tail1725)->field0; + GibPtr tailift1727 = gib_alloc(sizeof(GibIntGibIntProd)); + + ((GibIntGibIntProd *) tailift1727)->field0 = 1; + ((GibIntGibIntProd *) tailift1727)->field1 = x111714241615; + return tailift1727; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1724"); + exit(1); + } + } +} +GibCursor _copy_without_ptrs_Maybe106_v701(GibCursor arg111914261617) +{ + GibPackedTag tag1729 = *(GibPackedTag *) arg111914261617; + GibCursor tail1730 = arg111914261617 + sizeof(GibInt); + + + switch1733: + ; + switch (tag1729) { + + case 0: + { + GibPtr tailift1731 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift1731)->field0 = 0; + return tailift1731; + break; + } + + case 1: + { + GibInt x112014271618 = ((GibIntProd *) tail1730)->field0; + GibPtr tailift1732 = gib_alloc(sizeof(GibIntGibIntProd)); + + ((GibIntGibIntProd *) tailift1732)->field0 = 1; + ((GibIntGibIntProd *) tailift1732)->field1 = x112014271618; + return tailift1732; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1729"); + exit(1); + } + } +} +unsigned char _traverse_Maybe106_v701(GibCursor arg112214291620) +{ + GibPackedTag tag1734 = *(GibPackedTag *) arg112214291620; + GibCursor tail1735 = arg112214291620 + sizeof(GibInt); + + + switch1736: + ; + switch (tag1734) { + + case 0: + { + return 0; + break; + } + + case 1: + { + GibInt x112314301621 = ((GibIntProd *) tail1735)->field0; + + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1734"); + exit(1); + } + } +} +unsigned char _print_Maybe106_v701(GibCursor arg112514311622) +{ + GibPackedTag tag1737 = *(GibPackedTag *) arg112514311622; + GibCursor tail1738 = arg112514311622 + sizeof(GibInt); + + + switch1739: + ; + switch (tag1737) { + + case 0: + { + unsigned char wildcard112614321623 = gib_print_symbol(1683); + unsigned char wildcard112714331624 = gib_print_symbol(1680); + + return 0; + break; + } + + case 1: + { + GibInt x112814341625 = ((GibIntProd *) tail1738)->field0; + unsigned char wildcard113014351626 = gib_print_symbol(1685); + unsigned char wildcard113214361627 = gib_print_symbol(1691); + unsigned char y112914371628 = printf("%ld", x112814341625); + unsigned char wildcard113114381629 = gib_print_symbol(1680); + + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1737"); + exit(1); + } + } +} +GibCursor _copy_Map137_v699(GibCursor arg113314391630) +{ + GibPackedTag tag1740 = *(GibPackedTag *) arg113314391630; + GibCursor tail1741 = arg113314391630 + sizeof(GibInt); + + + switch1744: + ; + switch (tag1740) { + + case 0: + { + GibPtr tailift1742 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift1742)->field0 = 0; + return tailift1742; + break; + } + + case 1: + { + GibInt x113414401631 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail1741)->field0; + GibInt x113514411632 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail1741)->field1; + GibInt x113614421633 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail1741)->field2; + GibCursor x113714431634 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail1741)->field3; + GibCursor x113814441635 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail1741)->field4; + GibCursor y114214481639 = _copy_Map137_v699(x113714431634); + GibCursor y114314491640 = _copy_Map137_v699(x113814441635); + GibPtr tailift1743 = + gib_alloc(sizeof(GibIntGibIntGibIntGibIntGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift1743)->field0 = + 1; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift1743)->field1 = + x113414401631; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift1743)->field2 = + x113514411632; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift1743)->field3 = + x113614421633; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift1743)->field4 = + y114214481639; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift1743)->field5 = + y114314491640; + return tailift1743; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1740"); + exit(1); + } + } +} +GibCursor _copy_without_ptrs_Map137_v699(GibCursor arg114414501641) +{ + GibPackedTag tag1745 = *(GibPackedTag *) arg114414501641; + GibCursor tail1746 = arg114414501641 + sizeof(GibInt); + + + switch1749: + ; + switch (tag1745) { + + case 0: + { + GibPtr tailift1747 = gib_alloc(sizeof(GibIntProd)); + + ((GibIntProd *) tailift1747)->field0 = 0; + return tailift1747; + break; + } + + case 1: + { + GibInt x114514511642 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail1746)->field0; + GibInt x114614521643 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail1746)->field1; + GibInt x114714531644 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail1746)->field2; + GibCursor x114814541645 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail1746)->field3; + GibCursor x114914551646 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail1746)->field4; + GibCursor y115314591650 = + _copy_without_ptrs_Map137_v699(x114814541645); + GibCursor y115414601651 = + _copy_without_ptrs_Map137_v699(x114914551646); + GibPtr tailift1748 = + gib_alloc(sizeof(GibIntGibIntGibIntGibIntGibCursorGibCursorProd)); + + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift1748)->field0 = + 1; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift1748)->field1 = + x114514511642; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift1748)->field2 = + x114614521643; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift1748)->field3 = + x114714531644; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift1748)->field4 = + y115314591650; + ((GibIntGibIntGibIntGibIntGibCursorGibCursorProd *) tailift1748)->field5 = + y115414601651; + return tailift1748; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1745"); + exit(1); + } + } +} +unsigned char _traverse_Map137_v699(GibCursor arg115514611652) +{ + GibPackedTag tag1750 = *(GibPackedTag *) arg115514611652; + GibCursor tail1751 = arg115514611652 + sizeof(GibInt); + + + switch1752: + ; + switch (tag1750) { + + case 0: + { + return 0; + break; + } + + case 1: + { + GibInt x115614621653 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail1751)->field0; + GibInt x115714631654 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail1751)->field1; + GibInt x115814641655 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail1751)->field2; + GibCursor x115914651656 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail1751)->field3; + GibCursor x116014661657 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail1751)->field4; + unsigned char y116414671658 = _traverse_Map137_v699(x115914651656); + unsigned char y116514681659 = _traverse_Map137_v699(x116014661657); + + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1750"); + exit(1); + } + } +} +unsigned char _print_Map137_v699(GibCursor arg116614691660) +{ + GibPackedTag tag1753 = *(GibPackedTag *) arg116614691660; + GibCursor tail1754 = arg116614691660 + sizeof(GibInt); + + + switch1755: + ; + switch (tag1753) { + + case 0: + { + unsigned char wildcard116714701661 = gib_print_symbol(1681); + unsigned char wildcard116814711662 = gib_print_symbol(1680); + + return 0; + break; + } + + case 1: + { + GibInt x116914721663 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail1754)->field0; + GibInt x117014731664 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail1754)->field1; + GibInt x117114741665 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail1754)->field2; + GibCursor x117214751666 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail1754)->field3; + GibCursor x117314761667 = + ((GibIntGibIntGibIntGibCursorGibCursorProd *) tail1754)->field4; + unsigned char wildcard117914771668 = gib_print_symbol(1690); + unsigned char wildcard118514781669 = gib_print_symbol(1691); + unsigned char y117414791670 = printf("%ld", x116914721663); + unsigned char wildcard118414801671 = gib_print_symbol(1691); + unsigned char y117514811672 = printf("%ld", x117014731664); + unsigned char wildcard118314821673 = gib_print_symbol(1691); + unsigned char y117614831674 = printf("%ld", x117114741665); + unsigned char wildcard118214841675 = gib_print_symbol(1691); + unsigned char y117714851676 = _print_Map137_v699(x117214751666); + unsigned char wildcard118114861677 = gib_print_symbol(1691); + unsigned char y117814871678 = _print_Map137_v699(x117314761667); + unsigned char wildcard118014881679 = gib_print_symbol(1680); + + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag1753"); + exit(1); + } + } +} +int main(int argc, char **argv) +{ + int init0 = gib_init(argc, argv); + + info_table_initialize(); + symbol_table_initialize(); + + int exit1 = gib_exit(); + + return exit1; +} \ No newline at end of file diff --git a/benchmarks/CRDTs/Timekeeping.hs b/benchmarks/CRDTs/Timekeeping.hs new file mode 100644 index 000000000..c69a32ea3 --- /dev/null +++ b/benchmarks/CRDTs/Timekeeping.hs @@ -0,0 +1,80 @@ +module Timekeeping where +import qualified Map as M +import qualified Common as C + +data Clock = Clk Int (M.Map Int) + +data Timestamp = Timestamp Int Clock + +serializetimestamp :: Timestamp -> Int +serializetimestamp x = case x of + Timestamp uid clk -> case clk of + Clk _ m -> (M.sum m) + 10000 * uid + +clock :: Timestamp -> Clock +clock t = case t of + Timestamp _ c -> c + +author :: Timestamp -> Int +author t = + case t of + Timestamp a _ -> a + +init :: Int -> Clock +init uid = Clk 0 (M.singleton uid 0) + +lookup :: Int -> Clock -> C.Maybe Int +lookup k clk = + case clk of + Clk _ m -> M.lookup k m + +clockmap :: Clock -> (M.Map Int) +clockmap x = case x of + Clk _ y -> y + +step :: Int -> Clock -> Clock +step uid clk = case (Timekeeping.lookup uid clk) of + C.Just v -> case clk of + Clk _ m -> Clk 0 (M.insert uid (v + 1) m) + C.Nothing -> case clk of + Clk _ m -> Clk 0 (M.insert uid 1 m) + +stamp :: Int -> Clock -> Timestamp +stamp uid clk = Timestamp uid clk + +compare :: Clock -> Clock -> C.Ord +compare a b = + case (clockmap a) of + M.Tip -> case (clockmap b) of + M.Tip -> C.Eq + M.Bin _ _ _ _ _ -> C.Lt + M.Bin _ _ _ _ _ -> case (clockmap b) of + M.Tip -> C.Gt + M.Bin _ _ _ _ _ -> + let k = M.key (clockmap a) + diff = case Timekeeping.lookup k a of + C.Nothing -> case Timekeeping.lookup k b of + C.Nothing -> C.Eq + C.Just _ -> C.Lt + C.Just ax -> case Timekeeping.lookup k b of + C.Nothing -> C.Gt + C.Just bx -> C.compareInt ax bx + in case diff of + C.Lt -> case diff of + C.Lt -> C.Lt + C.Eq -> C.Lt + _ -> C.Cc + C.Gt -> case diff of + C.Gt -> C.Gt + C.Eq -> C.Gt + _ -> C.Cc + C.Eq -> case diff of + C.Eq -> C.Eq + _ -> C.Cc + C.Cc -> C.Cc + + + +--gibbon_main = stamp 0 (step 0 (step 1 (step 0 (init 0)))) + +--main = stamp 0 (step 0 (step 1 (step 0 (Clock.init 0)))) \ No newline at end of file diff --git a/benchmarks/Layouts/BasicLayoutAnalysis.png b/benchmarks/Layouts/BasicLayoutAnalysis.png new file mode 100644 index 000000000..01ad519ba Binary files /dev/null and b/benchmarks/Layouts/BasicLayoutAnalysis.png differ diff --git a/benchmarks/Layouts/BasicLayoutAnalysis_small.png b/benchmarks/Layouts/BasicLayoutAnalysis_small.png new file mode 100644 index 000000000..730fdc81d Binary files /dev/null and b/benchmarks/Layouts/BasicLayoutAnalysis_small.png differ diff --git a/benchmarks/Layouts/Common.c b/benchmarks/Layouts/Common.c new file mode 100644 index 000000000..6503f9885 --- /dev/null +++ b/benchmarks/Layouts/Common.c @@ -0,0 +1,1390 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// #include +#ifdef _WIN64 +#include +#endif +#include +#include +#include // For va_start etc +#include +#include +#include +#include +#ifdef _POINTER +#include +#endif +#ifdef _PARALLEL +#include +#include +#endif + +#define KB 1024lu +#define MB (KB * 1000lu) +#define GB (MB * 1000lu) + +#define REDIRECTION_TAG 255 +#define INDIRECTION_TAG 254 + +// Initial size of BigInfinite buffers +static long long global_init_biginf_buf_size = (4 * GB); + +// Initial size of Infinite buffers +static long long global_init_inf_buf_size = 1 * KB; + +// Maximum size of a chunk, see GitHub #110. +static long long global_inf_buf_max_chunk_size = 1 * GB; + +static long long global_size_param = 1; +static long long global_iters_param = 1; + +static char* global_benchfile_param = NULL; +static char* global_arrayfile_param = NULL; +// Number of lines in the arrayfile +static long long global_arrayfile_length_param = -1; + +// Sequential for now: +static const int num_workers = 1; + +// Count the number of regions allocated. +static long long global_region_count = 0; +static bool global_region_count_flag = false; + +#ifdef _PARALLEL +static inline void bump_global_region_count() { + __atomic_add_fetch(&global_region_count, 1, __ATOMIC_SEQ_CST); + return; +} +#else +static inline void bump_global_region_count() { + global_region_count++; + return; +} +#endif + +static inline void print_global_region_count() { + printf("REGION_COUNT: %lld\n", global_region_count); + return; +} + +#define REDIRECTION_NODE_SIZE 9 +#define MAX(a,b) (((a)>(b))?(a):(b)) +#define MIN(a,b) (((a)<(b))?(a):(b)) + +// https://www.cprogramming.com/snippets/source-code/find-the-number-of-cpu-cores-for-windows-mac-or-linux +static int get_num_processors() { +#ifdef _WIN64 + SYSTEM_INFO sysinfo; + GetSystemInfo(&sysinfo); + return sysinfo.dwNumberOfProcessors; +#else + return sysconf(_SC_NPROCESSORS_ONLN); +#endif +} + +// Requires -std=gnu11 +int dbgprintf(const char *format, ...) { + int code = 0; + va_list args; + va_start(args, format); +#ifdef _DEBUG + code = vprintf(format, args); +#endif + va_end(args); + return code; +} + + +// ----------------------------------------------------------------------------- +// Allocators +// ----------------------------------------------------------------------------- + + +// ------------------------------------- +// Bump allocation for linked-lists +// ------------------------------------- + + +#ifdef _BUMPALLOC +// #define _DEBUG +#warning "Using bump allocator." + +__thread char* bumpalloc_heap_ptr = (char*)NULL; +__thread char* bumpalloc_heap_ptr_end = (char*)NULL; + +char* saved_heap_ptr_stack[100]; +int num_saved_heap_ptr = 0; + +// For simplicity just use a single large slab: +static inline void INITBUMPALLOC() { + bumpalloc_heap_ptr = (char*)malloc(global_init_biginf_buf_size); + bumpalloc_heap_ptr_end = bumpalloc_heap_ptr + global_init_biginf_buf_size; +#ifdef _DEBUG + printf("Arena size for bump alloc: %lld\n", global_init_biginf_buf_size); + printf("BUMPALLOC/INITBUMPALLOC DONE: heap_ptr = %p\n", bumpalloc_heap_ptr); +#endif +} + +static inline void* BUMPALLOC(long long n) { + if (! bumpalloc_heap_ptr) { + INITBUMPALLOC(); + } + if (bumpalloc_heap_ptr + n < bumpalloc_heap_ptr_end) { + char* old= bumpalloc_heap_ptr; + bumpalloc_heap_ptr += n; + return old; + } else { + fprintf(stderr, "Warning: bump allocator ran out of memory."); + exit(1); + } +} + +// Snapshot the current heap pointer value across all threads. +void save_alloc_state() { + dbgprintf("Saving(%p): pos %d", heap_ptr, num_saved_heap_ptr); + saved_heap_ptr_stack[num_saved_heap_ptr] = heap_ptr; + num_saved_heap_ptr++; + dbgprintf("\n"); +} + +void restore_alloc_state() { + if(num_saved_heap_ptr <= 0) { + fprintf(stderr, "Bad call to restore_alloc_state! Saved stack empty!\ne"); + exit(1); + } + num_saved_heap_ptr--; + dbgprintf("Restoring(%p): pos %d, discarding %p", + saved_heap_ptr_stack[num_saved_heap_ptr], num_saved_heap_ptr, bumpalloc_heap_ptr); + bumpalloc_heap_ptr = saved_heap_ptr_stack[num_saved_heap_ptr]; +} + + +#else +// Regular malloc mode: +void INITBUMPALLOC() {} +void save_alloc_state() {} +void restore_alloc_state() {} + +#define BUMPALLOC(n) malloc(n) + +#endif // BUMPALLOC + + +// ------------------------------------- +// ALLOC and ALLOC_PACKED macros +// ------------------------------------- + + +/* + +If parallelism is enabled, we always use a malloc based allocator +since Boehm GC is not thread-safe in its default configuration. It can be +made thread-safe by building it with appropriate flags, but we don't do that. +Presently, all parallel pointer-based programs will leak memory. + +*/ + +#ifdef _PARALLEL +#define ALLOC(n) malloc(n) +#define ALLOC_PACKED_BIG(n) malloc(n) +char *ALLOC_COUNTED(size_t size) { + bump_global_region_count(); + return ALLOC(size); +} +#else + #ifdef _POINTER +#define ALLOC(n) GC_MALLOC(n) +#define ALLOC_PACKED_BIG(n) GC_MALLOC(n) +char *ALLOC_COUNTED(size_t size) { + bump_global_region_count(); + return GC_MALLOC(size); +} + #else +#define ALLOC(n) malloc(n) +#define ALLOC_PACKED_BIG(n) malloc(n) +char *ALLOC_COUNTED(size_t size) { + bump_global_region_count(); + return ALLOC(size); +} + #endif // _POINTER +#endif // _PARALLEL + + +// Could try alloca() here. Better yet, we could keep our own, +// separate stack and insert our own code to restore the pointer +// before any function that (may have) called ALLOC_SCOPED returns. + +// #define ALLOC_SCOPED() alloca(1024) +#define ALLOC_SCOPED(n) alloca(n) +// #define ALLOC_SCOPED() alloc_scoped() + +// Stack allocation is either too small or blows our stack. +// We need a way to make a giant stack if we want to use alloca. +// #define ALLOC_SCOPED() ALLOC(global_init_biginf_buf_size) + +// Our global pointer. No parallelism. +// static char* stack_scoped_region; +// char* alloc_scoped() { return stack_scoped_region; } + + + +// ------------------------------------- +// Basic types +// ------------------------------------- + +// Must be consistent with sizeOfTy defined in Gibbon.Language.Syntax. + +typedef unsigned char TagTyPacked; +typedef unsigned char TagTyBoxed; +typedef long long IntTy; +typedef char CharTy; +typedef float FloatTy; +typedef unsigned long long SymTy; +typedef bool BoolTy; +typedef char* PtrTy; +typedef char* CursorTy; + +// ------------------------------------- +// Arenas and dictionaries +// ------------------------------------- + +typedef struct mem_arena { + int ind; + char* mem; // TODO(vollmerm): make this a list of chunks? + void* reflist; +} mem_arena_t; + +typedef mem_arena_t* ArenaTy; + +ArenaTy alloc_arena() { + ArenaTy ar = ALLOC(sizeof(mem_arena_t)); + ar->ind = 0; + ar->mem = malloc(global_inf_buf_max_chunk_size); + ar->reflist = 0; + return ar; +} + +void free_arena(ArenaTy ar) { + free(ar->mem); + // TODO(vollmerm): free everything in ar->reflist + free(ar); +} + +CursorTy extend_arena(ArenaTy ar, int size) { + CursorTy ret = ar->mem + ar->ind; + ar->ind += size; + return ret; +} + +typedef struct dict_item { + struct dict_item * next; + int key; + void * ptrval; +} dict_item_t; + +dict_item_t * dict_alloc(ArenaTy ar) { + return (dict_item_t *) extend_arena(ar, sizeof(dict_item_t)); // ALLOC(sizeof(dict_item_t)); +} + +dict_item_t *dict_insert_ptr(ArenaTy ar, dict_item_t *ptr, SymTy key, PtrTy val) { + dict_item_t *ret = dict_alloc(ar); + ret->key = key; + ret->ptrval = val; + ret->next = ptr; + return ret; +} + +PtrTy dict_lookup_ptr(dict_item_t *ptr, SymTy key) { + while (ptr != 0) { + if (ptr->key == key) { + return ptr->ptrval; + } else { + ptr = ptr->next; + } + } + printf("Error, key %lld not found!\n",key); + exit(1); +} + +// ------------------------------------- +// Sets +// ------------------------------------- + + +struct set_elem { + int val; + UT_hash_handle hh; +}; + +typedef struct set_elem* SymSetTy; + +SymSetTy empty_set() { + return NULL; +} + +SymSetTy insert_set(SymSetTy set, int sym) { + SymSetTy s; + HASH_FIND_INT(set, &sym, s); /* sym already in the hash? */ + if (s==NULL) { + s = malloc(sizeof(struct set_elem)); + s->val = sym; + HASH_ADD_INT(set,val,s); + } + return set; +} + +BoolTy contains_set(SymSetTy set, int sym) { + SymSetTy s; + HASH_FIND_INT(set, &sym, s); + return (s!=NULL); +} + +// ------------------------------------- +// Sym Hash +// ------------------------------------- + +struct sym_hash_elem { + int key; + int val; + UT_hash_handle hh; +}; + +typedef struct sym_hash_elem* SymHashTy; + +typedef struct sym_hash_elem* IntHashTy; + +SymHashTy empty_hash() { + return NULL; +} + +SymHashTy insert_hash(SymHashTy hash, int k, int v) { + SymHashTy s; + // NOTE: not checking for duplicates! + // s = malloc(sizeof(struct sym_hash_elem)); + s = ALLOC(sizeof(struct sym_hash_elem)); + s->val = v; + s->key = k; + HASH_ADD_INT(hash,key,s); + + return hash; +} + +IntTy lookup_hash(SymHashTy hash, int k) { + SymHashTy s; + HASH_FIND_INT(hash,&k,s); + if (s==NULL) { + return k; // NOTE: return original key if val not found + // TODO(vollmerm): come up with something better to do here + } else { + return s->val; + } +} + +BoolTy contains_hash(SymHashTy hash, int sym) { + SymHashTy s; + HASH_FIND_INT(hash,&sym,s); + return (s!=NULL); +} + +// ------------------------------------- +// Helpers +// ------------------------------------- + +char* read_benchfile_param() { + if (global_benchfile_param == NULL) { + fprintf(stderr, "read_benchfile_param: benchmark input file was not set! Set using --bench-input.\n"); + exit(1); + } else + return global_benchfile_param; +} + +char* read_arrayfile_param() { + if (global_arrayfile_param == NULL) { + fprintf(stderr, "read_arrayfile_param: array input file was not set! Set using --array-input.\n"); + exit(1); + } else + return global_arrayfile_param; +} + +IntTy read_arrayfile_length_param() { + if (global_arrayfile_length_param == -1) { + fprintf(stderr, "read_arrayfile_length_param: array input file length was not set! Set using --array-input-length.\n"); + exit(1); + } else + return global_arrayfile_length_param; +} + + +// fun fact: __ prefix is actually reserved and this is an undefined behavior. +// These functions must be provided by the code generator. +int __main_expr(); + + +void show_usage(char** argv) +{ + printf("\n"); + printf("This binary was generated by the Gibbon compiler.\n"); + printf("\n"); + printf("Usage: %s [OPTS] [size] [iters]\n", argv[0]); + + printf("\n"); + printf("Options:\n"); + printf(" --buffer-size Set the buffer size (default %lld).\n", global_init_biginf_buf_size); + printf(" --bench-input Set the input file read for benchmarking. Applies only\n"); + printf(" IF the program was *compiled* with --bench-fun. \n"); + return; +} + +double avg(const double* arr, int n) +{ + double sum = 0.0; + for(int i=0; itv_sec - t0->tv_sec) + + ((double)(t1->tv_nsec - t0->tv_nsec) / 1000000000.0); +} + +int compare_doubles(const void *a, const void *b) +{ + const double *da = (const double *) a; + const double *db = (const double *) b; + return (*da > *db) - (*da < *db); +} + +// Exponentiation +IntTy expll(IntTy base, IntTy pow) { + if (base == 2) { + return (1 << pow); + } else { + IntTy i, result = 1; + for (i = 0; i < pow; i++) + result *= base; + return result; + } + } + +// ------------------------------------- +// Symbol table +// ------------------------------------- + +#define global_max_symbol_len 256 + +// Invariant: should always be equal to max(sym_table_keys) +static SymTy global_gensym_counter = 0; + +// Its value is updated by the flags parser. +static char *global_bench_prog_param; + +static SymTy newline_symbol = -1; +static SymTy space_symbol = -1; +static SymTy comma_symbol = -1; +static SymTy leftparen_symbol = -1; +static SymTy rightparen_symbol = -1; + +typedef struct SymTable_elem { + SymTy idx; /* key */ + char value[global_max_symbol_len]; + UT_hash_handle hh; /* makes this structure hashable */ +} SymTable_elem; + +// important! initialize to NULL +SymTable_elem *global_sym_table = NULL; + +void add_symbol(SymTy idx, char *value) { + struct SymTable_elem *s; + s = ALLOC(sizeof(struct SymTable_elem)); + s->idx = idx; + strcpy(s->value, value); + HASH_ADD(hh, global_sym_table, idx, sizeof(IntTy), s); + if (idx > global_gensym_counter) { + global_gensym_counter = idx; + } +} + +void set_newline(SymTy idx) { + newline_symbol = idx; + add_symbol(idx,"NEWLINE"); +} + +void set_space(SymTy idx) { + space_symbol = idx; + add_symbol(idx,"SPACE"); +} + +void set_comma(SymTy idx) { + comma_symbol = idx; + add_symbol(idx,"COMMA"); +} + +void set_leftparen(SymTy idx) { + leftparen_symbol = idx; + add_symbol(idx,"LEFTPAREN"); +} + +void set_rightparen(SymTy idx) { + rightparen_symbol = idx; + add_symbol(idx,"RIGHTPAREN"); +} + +IntTy print_symbol(SymTy idx) { + if (idx == comma_symbol) { + return printf(","); + } else if (idx == newline_symbol) { + return printf("\n"); + } else if (idx == space_symbol) { + return printf(" "); + } else if (idx == leftparen_symbol) { + return printf("("); + } else if (idx == rightparen_symbol) { + return printf(")"); + } else { + struct SymTable_elem *s; + HASH_FIND(hh, global_sym_table, &idx, sizeof(SymTy), s); + if (s == NULL) { + return printf("%lld", idx); + } else { + return printf("%s", s->value); + } + + } +} + +#ifdef _PARALLEL +SymTy gensym() { + SymTy idx = __atomic_add_fetch(&global_gensym_counter, 1, __ATOMIC_SEQ_CST); + return idx; +} +#else +SymTy gensym() { + global_gensym_counter += 1; + SymTy idx = global_gensym_counter; + return idx; +} +#endif + +void free_symtable() { + struct SymTable_elem *elt, *tmp; + HASH_ITER(hh, global_sym_table, elt, tmp) { + HASH_DEL(global_sym_table,elt); + } + free(elt); + free(tmp); +} + +/* + +---------------------------------------- +Garbage collection +---------------------------------------- + + Gibbon has "growing regions" i.e each logical region is backed by a doubly linked-list + of smaller chunks which grows as required. In addition to actual data, each chunk + stores some additional metadata (RegionFooter) to chain the chunks together in a list + and for garbage collection. The footer: + + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + serialized data | rf_reg_metadata_ptr | rf_seq_no | rf_size | rf_next | rf_prev + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + The metadata after the serialized data serves various purposes: + + - rf_reg_metadata_ptr: A pointer to a RegionTy struct that contains various metadata. + Of particular interest to us are the fields: + + = reg_id: A unique identifier for a region. + + = refcount and outset: Whenever an inter-region indirection is created, we record that information + using these two fields. Suppose we have an indirection from region A that points to some chunk + in region B. Then A's outset will store a pointer to that chunk's footer, and B's refcount will + be bumped by 1. Note that all there's only 1 refcount cell, and 1 outset per logical region, + and chunks only store a pointer to them. + + - rf_seq_no: The index of this particular chunk in the list. + + - rf_size: Used during bounds checking to calculate the size of the next region in + the linked list. + + - rf_next / rf_prev: Point to the next and previous chunk respectively. + + +There are two ways in which a region may be freed: + +(1) Whenever it goes out of scope + + The RTS tries to free a region whenever it goes out of scope. But this doesn't always succeed as + regions sometimes contain values that "escape". One reason why this'll happen is if there's an + indirection from A->B, and A lives longer than B. + In such a case, when B goes out of scope it's refcount won't be 0, and the RTS won't free it. + This brings us to (2). + +(2) + + When the RTS successfully frees a region, it decrements the refcounts of all the regions it + points to (via the outset). At the same time, if it encounters a region in the outset whoose + refcount becomes 0 after the decrement, it calls free_region on that. This way we can be sure + that all regions will eventually be garbage collected before the program exits. + + + +Why is it a doubly linked-list? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Due to way that bounds-checking works, the pointers in the outset may actually point to any +arbitrary chunk in the chain. However, we must call free_region on the first one to ensure that +all of them are GC'd. So we need pointers to traverse backward get to the first one. +'trav_to_first_chunk' accomplishes this. + + */ + +#define MAX_OUTSET_LENGTH 10 + +typedef struct RegionTy_struct { + SymTy reg_id; + uint reg_refcount; + CursorTy reg_heap; + uint reg_outset_len; + CursorTy reg_outset[MAX_OUTSET_LENGTH]; +} RegionTy; + +typedef struct RegionFooter_struct { + RegionTy *rf_reg_metadata_ptr; + + IntTy rf_seq_no; + IntTy rf_size; + struct RegionFooter_struct *rf_next; + struct RegionFooter_struct *rf_prev; +} RegionFooter; + +typedef struct ChunkTy_struct { + CursorTy chunk_start; + CursorTy chunk_end; +} ChunkTy; + +static inline void insert_into_outset(CursorTy ptr, RegionTy *reg) { + uint outset_len = reg->reg_outset_len; + // Check for duplicates. + for (uint i = 0; i < outset_len; i++) { + if (ptr == reg->reg_outset[i]) { + return; + } + } + // Otherwise, insert into the outset. + reg->reg_outset[outset_len] = ptr; + reg->reg_outset_len = outset_len + 1; + return; +} + +static inline void remove_from_outset(CursorTy ptr, RegionTy *reg) { + uint outset_len = reg->reg_outset_len; + CursorTy *outset = reg->reg_outset; + int i; + if (outset_len == 0) { + fprintf(stderr, "remove_from_outset: empty outset\n"); + exit(1); + } + // Position of 'ptr' in the outset. + int elt_idx = -1; + for (i = 0; i < outset_len; i++) { + if (ptr == outset[i]) { + elt_idx = i; + } + } + if (elt_idx == -1) { + fprintf(stderr, "remove_from_outset: element not found\n"); + exit(1); + } + // Move all elements ahead of 'elt_idx' back by one position. + for (i = elt_idx; i < outset_len; i++) { + outset[i] = outset[i+1]; + } + return; +} + +RegionTy *alloc_region(IntTy size) { + // Allocate the region metadata. + RegionTy *reg = ALLOC(sizeof(RegionTy)); + if (reg == NULL) { + printf("alloc_region: allocation failed: %ld", sizeof(RegionTy)); + exit(1); + } + + // Allocate the first chunk. + IntTy total_size = size + sizeof(RegionFooter); + CursorTy heap = ALLOC_PACKED_BIG(total_size); + if (heap == NULL) { + printf("alloc_region: malloc failed: %lld", total_size); + exit(1); + } + // Not heap+total_size, since we must keep space for the footer. + CursorTy heap_end = heap + size; + + // Initialize metadata fields. + reg->reg_id = gensym(); + reg->reg_refcount = 1; + reg->reg_heap = heap; + reg->reg_outset_len = 0; + +#ifdef _DEBUG + printf("Allocated a region(%lld): %lld bytes.\n", reg->reg_id, size); +#endif + + // Write the footer. + RegionFooter *footer = (RegionFooter *) heap_end; + footer->rf_reg_metadata_ptr = reg; + footer->rf_seq_no = 1; + footer->rf_size = size; + footer->rf_next = NULL; + footer->rf_prev = NULL; + + return reg; +} + +RegionTy *alloc_counted_region(IntTy size) { + // Bump the count. + bump_global_region_count(); + return alloc_region(size); +} + +ChunkTy alloc_chunk(CursorTy end_old_chunk) { + // Get size from current footer. + RegionFooter *footer = (RegionFooter *) end_old_chunk; + IntTy newsize = footer->rf_size * 2; + // See #110. + if (newsize > global_inf_buf_max_chunk_size) { + newsize = global_inf_buf_max_chunk_size; + } + IntTy total_size = newsize + sizeof(RegionFooter); + + // Allocate. + CursorTy start = ALLOC_PACKED_BIG(total_size); + if (start == NULL) { + printf("alloc_chunk: malloc failed: %lld", total_size); + exit(1); + } + CursorTy end = start + newsize; + + // Link the next chunk's footer. + footer->rf_next = (RegionFooter *) end; + + // Write the footer. + RegionFooter* new_footer = (RegionFooter *) end; + new_footer->rf_reg_metadata_ptr = footer->rf_reg_metadata_ptr; + new_footer->rf_seq_no = footer->rf_seq_no + 1; + new_footer->rf_size = newsize; + new_footer->rf_next = NULL; + new_footer->rf_prev = footer; + +#ifdef _DEBUG + RegionTy *reg = (RegionTy*) new_footer->rf_reg_metadata_ptr; + printf("alloc_chunk: allocated %lld bytes for region %lld.\n", total_size, reg->reg_id); +#endif + + return (ChunkTy) {start , end}; +} + +RegionFooter* trav_to_first_chunk(RegionFooter *footer) { + if (footer->rf_seq_no == 1) { + return footer; + } else if (footer->rf_prev == NULL) { + fprintf(stderr, "No previous chunk found at rf_seq_no: %lld", footer->rf_seq_no); + return NULL; + } else { + trav_to_first_chunk((RegionFooter *) footer->rf_prev); + } + return NULL; +} + +uint get_ref_count(CursorTy end_ptr) { + RegionFooter *footer = (RegionFooter *) end_ptr; + RegionTy *reg = (RegionTy *) footer->rf_reg_metadata_ptr; + return reg->reg_refcount; +} + +// B is the pointer, and A is the pointee (i.e B -> A). +// Bump A's refcount and update B's outset. +static inline void bump_ref_count(CursorTy end_b, CursorTy end_a) { + // Grab footers. + RegionFooter *footer_a = (RegionFooter *) end_a; + RegionFooter *footer_b = (RegionFooter *) end_b; + + // Grab metadata. + RegionTy *reg_a = (RegionTy *) footer_a->rf_reg_metadata_ptr; + RegionTy *reg_b = (RegionTy *) footer_b->rf_reg_metadata_ptr; + + // Bump A's refcount. + uint current_refcount, new_refcount; + current_refcount = reg_a->reg_refcount; + new_refcount = current_refcount + 1; + reg_a->reg_refcount = new_refcount; + +#ifdef _DEBUG + printf("bump_ref_count: %lld -> %lld\n", reg_b->reg_id, reg_a->reg_id); + printf("bump_ref_count: old-refcount=%d, old-outset-len=%d:\n", current_refcount, reg_b->reg_outset_len); + assert(current_refcount == reg_b->reg_outset_len+1); +#endif + + // Add A to B's outset. + insert_into_outset(end_a, reg_b); + +#ifdef _DEBUG + // printf("bump_ref_count: Added %p to %lld's outset, %p.\n", end_a, reg_b->reg_id, reg_b); + printf("bump_ref_count: new-refcount=%d, new-outset-len=%d\n", new_refcount, reg_b->reg_outset_len); + assert(new_refcount == reg_b->reg_outset_len+1); +#endif + + return; +} + +void free_region(CursorTy end_reg) { + // Grab footer and the metadata. + RegionFooter *footer = (RegionFooter *) end_reg; + RegionTy *reg = (RegionTy *) footer->rf_reg_metadata_ptr; + + // + RegionFooter *first_chunk_footer, *next_chunk_footer; + CursorTy first_chunk, next_chunk; + + // Decrement current reference count. + uint current_refcount, new_refcount; + current_refcount = reg->reg_refcount; + new_refcount = 0; + if (current_refcount != 0) { + new_refcount = current_refcount - 1; + reg->reg_refcount = new_refcount; + } + +#ifdef _DEBUG + printf("free_region(%lld): refcounts (1): old-refcount=%d, new-refcount=%d:\n", reg->reg_id, current_refcount, new_refcount); +#endif + + + // Free this region recount is 0. + if (new_refcount == 0) { + +#ifdef _DEBUG + printf("free_region(%lld): outset length: %d\n", reg->reg_id, reg->reg_outset_len); +#endif + + // Decrement refcounts, free regions with refcount==0 and also free + // elements of the outset. + if (reg->reg_outset_len != 0) { + uint outset_len = reg->reg_outset_len; + CursorTy *outset = reg->reg_outset; + RegionFooter *elt_footer; + RegionTy *elt_reg; + uint elt_current_refcount, elt_new_refcount; + CursorTy to_be_removed[MAX_OUTSET_LENGTH]; + uint to_be_removed_idx = 0; + for (int i = 0; i < outset_len; i++) { + elt_footer = (RegionFooter *) outset[i]; + elt_reg = (RegionTy *) elt_footer->rf_reg_metadata_ptr; +#ifdef _DEBUG + elt_current_refcount = elt_reg->reg_refcount; +#endif + elt_new_refcount = elt_current_refcount - 1; + elt_reg->reg_refcount = elt_new_refcount; +#ifdef _DEBUG + printf("free_region(%lld): old-refcount=%d, new-refcount=%d:\n", + elt_reg->reg_id, elt_current_refcount, elt_reg->reg_refcount); +#endif + if (elt_new_refcount == 0) { + // See [Why is it a doubly linked-list?] above + first_chunk_footer = trav_to_first_chunk(elt_footer); + if (first_chunk_footer != NULL) { + free_region((CursorTy) first_chunk_footer); + } + } + to_be_removed[to_be_removed_idx] = outset[i]; + to_be_removed_idx++; + } + // Remove elements from the outset. + for (uint i = 0; i < to_be_removed_idx; i++) { + remove_from_outset(to_be_removed[i], reg); + } + } + + +#ifdef _DEBUG + // Bookkeeping + IntTy num_freed_chunks = 0, total_bytesize = 0; +#endif + + // Free the chunks in this region. + first_chunk = end_reg - footer->rf_size; + first_chunk_footer = footer; + next_chunk = (char*) footer->rf_next; + +#ifdef _DEBUG + printf("free_region(%lld)\n", reg->reg_id); +#endif + +#ifdef _DEBUG + num_freed_chunks++; + total_bytesize = total_bytesize + first_chunk_footer->rf_size; +#endif + free(first_chunk); + + while (next_chunk != NULL) { + next_chunk_footer = (RegionFooter *) next_chunk; + #ifdef _DEBUG + num_freed_chunks++; + total_bytesize = total_bytesize + next_chunk_footer->rf_size; + #endif + free(next_chunk - next_chunk_footer->rf_size); + next_chunk = (char*) next_chunk_footer->rf_next; + } + +#ifdef _DEBUG + printf("free_region(%lld): Freed %lld bytes across %lld chunks.\n", + reg->reg_id, total_bytesize, num_freed_chunks); +#endif + + // Free the metadata. + free(reg); + + } else { +#ifdef _DEBUG + printf("free_region(%lld): non-zero refcount: %d.\n", + reg->reg_id, reg->reg_refcount); +#endif + } +} + +// Assume that all nodes with size information have tags >= 150. +BoolTy is_big(IntTy i, CursorTy cur) { + TagTyPacked tag = *(TagTyPacked *) cur; + if (tag >= 150) { + cur += 1; + IntTy size = *(IntTy *) cur; + if (size >= i) { + return true; + } else { + return false; + } + } + return false; +} + +// ------------------------------------- +// Vectors +// ------------------------------------- + +typedef struct VectorTy_struct { + // Bounds on the vector. + IntTy vec_lower, vec_upper; + + // Size of each element. + IntTy vec_elt_size; + + // Actual elements of the vector. + void* vec_data; +} VectorTy; + +VectorTy* vector_alloc(IntTy num, IntTy elt_size) { + VectorTy *vec = ALLOC(sizeof(VectorTy)); + if (vec == NULL) { + printf("alloc_vector: malloc failed: %ld", sizeof(VectorTy)); + exit(1); + } + void* data = ALLOC(num * elt_size); + if (data == NULL) { + printf("alloc_vector: malloc failed: %ld", sizeof(num * elt_size)); + exit(1); + } + vec->vec_lower = 0; + vec->vec_upper = num; + vec->vec_elt_size = elt_size; + vec->vec_data = data; + return vec; +} + +IntTy vector_length(VectorTy *vec) { + return (vec->vec_upper - vec->vec_lower); +} + +BoolTy vector_is_empty(VectorTy *vec) { + return (vector_length(vec) == 0); +} + +VectorTy* vector_slice(IntTy i, IntTy n, VectorTy *vec) { + IntTy lower = vec->vec_lower + i; + IntTy upper = vec->vec_lower + i + n; + if ((lower > vec->vec_upper)) { + printf("vector_slice: lower out of bounds, %lld > %lld", lower, vec->vec_upper); + exit(1); + } + if ((upper > vec->vec_upper)) { + printf("vector_slice: upper out of bounds: %lld > %lld", upper, vec->vec_upper); + exit(1); + } + VectorTy *vec2 = ALLOC(sizeof(VectorTy)); + if (vec == NULL) { + printf("vector_slice: malloc failed: %ld", sizeof(VectorTy)); + exit(1); + } + vec2->vec_lower = lower; + vec2->vec_upper = upper; + vec2->vec_elt_size = vec->vec_elt_size; + vec2->vec_data = vec->vec_data; + return vec2; +} + +// The callers must cast the return value. +static inline void* vector_nth(VectorTy *vec, IntTy i) { + // if (i < vec->lower || i > vec->upper) { + // printf("vector_nth index out of bounds: %lld (%lld,%lld) \n", i, vec->vec_lower, vec->vec_upper); + // exit(1); + // } + return (vec->vec_data + (vec->vec_elt_size * (vec->vec_lower + i))); +} + +static inline VectorTy* vector_inplace_update(VectorTy *vec, IntTy i, void* elt) { + void* dst = vector_nth(vec, i); + memcpy(dst, elt, vec->vec_elt_size); + return vec; +} + +static inline VectorTy* vector_copy(VectorTy *vec) { + IntTy len = vector_length(vec); + void *start = vector_nth(vec, 0); + VectorTy *vec2 = vector_alloc(len, vec->vec_elt_size); + memcpy(vec2->vec_data, start, len * vec->vec_elt_size); + return vec2; +} + +static inline VectorTy* vector_inplace_sort(VectorTy *vec, int (*compar)(const void *, const void*)) { + void *start = vector_nth(vec, 0); + qsort(start, vector_length(vec), vec->vec_elt_size, compar); + return vec; +} + +static inline VectorTy* vector_sort(VectorTy *vec, int (*compar)(const void *, const void*)) { + VectorTy *vec2 = vector_copy(vec); + vector_inplace_sort(vec2, compar); + return vec2; +} + +static inline VectorTy* vector_concat(VectorTy *vec) { + // Length of the input vector. + IntTy len = vector_length(vec); + // Length of the concatenated vector. + IntTy result_len = 0; + // Size of each element in the concatenated vector. + IntTy result_elt_size = 0; + VectorTy **elt_ref, *elt; + for (IntTy i = 0; i < len; i++) { + elt_ref = vector_nth(vec, i); + elt = *elt_ref; + result_elt_size = elt->vec_elt_size; + result_len += vector_length(elt); + } + + // Concatenated vector. + VectorTy *result = vector_alloc(result_len, result_elt_size); + IntTy elt_len; + // A counter that tracks the index of elements in 'result'. + IntTy k = 0; + for (IntTy i = 0; i < len; i++) { + elt_ref = vector_nth(vec, i); + elt = *elt_ref; + elt_len = vector_length(elt); + + for (IntTy j = 0; j < elt_len; j++) { + void* k_elt = vector_nth(elt, j); + vector_inplace_update(result, k, k_elt); + k++; + } + } + + return result; +} + +static inline void vector_free(VectorTy *vec) { + free(vec->vec_data); + free(vec); + return; +} + +static inline VectorTy* vector_merge(VectorTy *vec1, VectorTy *vec2) { + if (vec1->vec_upper != vec2->vec_lower) { + printf("vector_merge: non-contiguous slices, (%lld,%lld), (%lld,%lld).", + vec1->vec_lower, vec1->vec_upper, vec2->vec_lower, vec2->vec_upper); + exit(1); + } + VectorTy *merged = ALLOC(sizeof(VectorTy)); + if (merged == NULL) { + printf("vector_merge: malloc failed: %ld", sizeof(VectorTy)); + exit(1); + } + merged->vec_lower = vec1->vec_lower; + merged->vec_upper = vec2->vec_upper; + merged->vec_elt_size = vec1->vec_elt_size; + merged->vec_data = vec1->vec_data; + return merged; +} + +void print_timing_array(VectorTy *times) { + printf("TIMES: ["); + double *d; + IntTy n = vector_length(times); + for(int i = 0; i < n; i++) { + d = vector_nth(times, i); + if (i == (n-1)) { + printf("%f",*d); + } + else { + printf("%f, ",*d); + } + } + printf("]\n"); +} + +double sum_timing_array(VectorTy *times) { + double *d; + double acc = 0; + for(int i = 0; i < vector_length(times); i++) { + d = vector_nth(times, i); + acc += *d; + } + return acc; +} + +// ------------------------------------- +// Linked lists +// ------------------------------------- + +typedef struct ListTy_struct { + IntTy ll_data_size; + void* ll_data; + struct ListTy_struct* ll_next; +} ListTy; + +static inline ListTy* list_alloc(IntTy data_size) { + // ListTy *ls = ALLOC(sizeof(ListTy)); + ListTy *ls = BUMPALLOC(sizeof(ListTy)); + ls->ll_data_size = data_size; + ls->ll_data = NULL; + ls->ll_next = NULL; + return ls; +} + +static inline BoolTy list_is_empty(ListTy *ls) { + return ls->ll_next == NULL; +} + +static inline ListTy* list_cons(void* elt, ListTy *ls) { + // void* data = ALLOC(ls->data_size); + void* data = BUMPALLOC(ls->ll_data_size); + if (data == NULL) { + printf("list_cons: malloc failed: %lld", ls->ll_data_size); + exit(1); + } + memcpy(data, elt, ls->ll_data_size); + // ListTy *res = ALLOC(sizeof(ListTy)); + ListTy *res = BUMPALLOC(sizeof(ListTy)); + res->ll_data_size = ls->ll_data_size; + res->ll_data = data; + res->ll_next = (ListTy*) ls; + return res; +} + +static inline void* list_head(ListTy *ls) { + return ls->ll_data; +} + +static inline ListTy* list_tail(ListTy *ls) { + return ls->ll_next; +} + +static inline void list_free(ListTy *ls) { + free(ls->ll_data); + free(ls); + return; +} + +static inline ListTy* list_copy(ListTy *ls) { + ListTy *ls2 = list_alloc(ls->ll_data_size); + if (ls->ll_data != NULL) { + void* data = BUMPALLOC(ls->ll_data_size); + memcpy(data, ls->ll_data, ls->ll_data_size); + ls2->ll_data = data; + } + ls2->ll_next = ls->ll_next; + return ls2; +} + +// ------------------------------------- +// Ppm Images +// ------------------------------------- + +typedef struct __Pixel_struct { + IntTy field0; + IntTy field1; + IntTy field2; +} __Pixel; + +void writePpm(char* filename, IntTy width, IntTy height, VectorTy *pixels); +void writePpm_loop(FILE *fp, IntTy idx, IntTy end, VectorTy *pixels); + +// Example: writePpm("gibbon_rgb_1000.ppm", 1000, 1000, pixels); +void writePpm(char* filename, IntTy width, IntTy height, VectorTy *pixels) +{ + FILE *fp; + fp = fopen(filename, "w+"); + fprintf(fp, "P3\n"); + fprintf(fp, "%lld %lld\n255\n", width, height); + IntTy len = vector_length(pixels); + writePpm_loop(fp, 0, len, pixels); + fclose(fp); + return; +} + +void writePpm_loop(FILE *fp, IntTy idx, IntTy end, VectorTy *pixels) +{ + BoolTy fltIf_5768_6575 = idx == end; + + if (fltIf_5768_6575) { + return; + } else { + __Pixel *tmp_112; + tmp_112 = (__Pixel *) vector_nth(pixels, idx); + __Pixel tup = *tmp_112; + IntTy x = tup.field0; + IntTy y = tup.field1; + IntTy z = tup.field2; + // write to file. + fprintf(fp, "%lld %lld %lld\n", x, y, z); + writePpm_loop(fp, (idx+1), end, pixels); + } +} + +/* -------------------------------------------------------------------------------- */ + +int main(int argc, char** argv) +{ + // parameters to parse: + // + // num iterations: How many times to repeat a benchmark. + // tree size: An integer passes to `build_tree()`. + + struct rlimit lim; + int code; + if ( (code = getrlimit(RLIMIT_STACK, &lim)) ) { + fprintf(stderr, " [gibbon rts] failed to getrlimit, code %d\n", code); + exit(1); + } + + // lim.rlim_cur = 1024LU * 1024LU * 1024LU; // 1GB stack. + lim.rlim_cur = 512LU * 1024LU * 1024LU; // 500MB stack. + // lim.rlim_max = lim.rlim_cur; // Normal users may only be able to decrease this. + + // WARNING: Haven't yet figured out why this doesn't work on MacOS... +#ifndef __APPLE__ + code = setrlimit(RLIMIT_STACK, &lim); + while (code) { + fprintf(stderr, " [gibbon rts] Failed to set stack size to %llu, code %d\n", (unsigned long long)lim.rlim_cur, code); + lim.rlim_cur /= 2; + // lim.rlim_max /= 2; + if(lim.rlim_cur < 100 * 1024) { + fprintf(stderr, " [gibbon rts] Failed setrlimit stack size to something reasonable; giving up.\n"); + break; // abort(); + } + int code = setrlimit(RLIMIT_STACK, &lim); + } +#endif + + int got_numargs = 0; // How many numeric arguments have we got. + + int i; + for (i = 1; i < argc; ++i) + { + if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) { + show_usage(argv); + exit(0); + } + else if (strcmp(argv[i], "--biginf-buffer-size") == 0 && i < argc - 1) + { + global_init_biginf_buf_size = atoll(argv[i + 1]); + i++; + } + else if (strcmp(argv[i], "--inf-buffer-size") == 0 && i < argc - 1) + { + global_init_inf_buf_size = atoll(argv[i + 1]); + i++; + } + else if ((strcmp(argv[i], "--bench-input") == 0)) { + if (i+1 >= argc) { + fprintf(stderr, "Not enough arguments after --bench-input, expected .\n"); + show_usage(argv); + exit(1); + } + global_benchfile_param = argv[i+1]; + i++; + } + else if ((strcmp(argv[i], "--array-input") == 0)) { + if (i+1 >= argc) { + fprintf(stderr, "Not enough arguments after --array-input, expected .\n"); + show_usage(argv); + exit(1); + } + global_arrayfile_param = argv[i+1]; + i++; + } + else if (strcmp(argv[i], "--array-input-length") == 0 && i < argc - 1) { + global_arrayfile_length_param = atoll(argv[i+1]); + i++; + } + else if (strcmp(argv[i], "--bench-prog") == 0 && i < argc - 1) { + int len = strlen(argv[i+1]); + global_bench_prog_param = (char*) malloc((len+1)*sizeof(char)); + strncpy(global_bench_prog_param,argv[i+1],len); + i++; + } + // If present, we expect the two arguments to be + else if (got_numargs >= 2) { + fprintf(stderr, "Extra arguments left over: "); + for(; i < argc; i++) fprintf(stderr, "%s ", argv[i]); + show_usage(argv); + exit(1); + } else { + if (got_numargs == 0) { + global_size_param = atoll(argv[i]); + got_numargs ++; + } else { + global_iters_param = atoll(argv[i]); + } + } + } + + // Initialize global_bench_prog_param to an empty string in case + // the runtime argument --bench-prog isn't passed. + if (global_bench_prog_param == NULL) { + global_bench_prog_param = (char*) malloc(1*sizeof(char)); + *global_bench_prog_param = '\n'; + } + + __main_expr(); + + return 0; +} + +// ----------------------------------------------------------------------------- +// Program starts here +// ----------------------------------------------------------------------------- + +int __main_expr() +{ } \ No newline at end of file diff --git a/benchmarks/Layouts/Common.hs b/benchmarks/Layouts/Common.hs new file mode 100644 index 000000000..d4078c33b --- /dev/null +++ b/benchmarks/Layouts/Common.hs @@ -0,0 +1,4 @@ +module Common where + + data Maybe a = Nothing + | Just a \ No newline at end of file diff --git a/benchmarks/Layouts/Left.c b/benchmarks/Layouts/Left.c new file mode 100644 index 000000000..0b1e6f873 --- /dev/null +++ b/benchmarks/Layouts/Left.c @@ -0,0 +1,2443 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// #include +#ifdef _WIN64 +#include +#endif +#include +#include +#include // For va_start etc +#include +#include +#include +#include +#ifdef _POINTER +#include +#endif +#ifdef _PARALLEL +#include +#include +#endif + +#define KB 1024lu +#define MB (KB * 1000lu) +#define GB (MB * 1000lu) + +#define REDIRECTION_TAG 255 +#define INDIRECTION_TAG 254 + +// Initial size of BigInfinite buffers +static long long global_init_biginf_buf_size = (4 * GB); + +// Initial size of Infinite buffers +static long long global_init_inf_buf_size = 1 * KB; + +// Maximum size of a chunk, see GitHub #110. +static long long global_inf_buf_max_chunk_size = 1 * GB; + +static long long global_size_param = 1; +static long long global_iters_param = 1; + +static char* global_benchfile_param = NULL; +static char* global_arrayfile_param = NULL; +// Number of lines in the arrayfile +static long long global_arrayfile_length_param = -1; + +// Sequential for now: +static const int num_workers = 1; + +// Count the number of regions allocated. +static long long global_region_count = 0; +static bool global_region_count_flag = false; + +#ifdef _PARALLEL +static inline void bump_global_region_count() { + __atomic_add_fetch(&global_region_count, 1, __ATOMIC_SEQ_CST); + return; +} +#else +static inline void bump_global_region_count() { + global_region_count++; + return; +} +#endif + +static inline void print_global_region_count() { + printf("REGION_COUNT: %lld\n", global_region_count); + return; +} + +#define REDIRECTION_NODE_SIZE 9 +#define MAX(a,b) (((a)>(b))?(a):(b)) +#define MIN(a,b) (((a)<(b))?(a):(b)) + +// https://www.cprogramming.com/snippets/source-code/find-the-number-of-cpu-cores-for-windows-mac-or-linux +static int get_num_processors() { +#ifdef _WIN64 + SYSTEM_INFO sysinfo; + GetSystemInfo(&sysinfo); + return sysinfo.dwNumberOfProcessors; +#else + return sysconf(_SC_NPROCESSORS_ONLN); +#endif +} + +// Requires -std=gnu11 +int dbgprintf(const char *format, ...) { + int code = 0; + va_list args; + va_start(args, format); +#ifdef _DEBUG + code = vprintf(format, args); +#endif + va_end(args); + return code; +} + + +// ----------------------------------------------------------------------------- +// Allocators +// ----------------------------------------------------------------------------- + + +// ------------------------------------- +// Bump allocation for linked-lists +// ------------------------------------- + + +#ifdef _BUMPALLOC +// #define _DEBUG +#warning "Using bump allocator." + +__thread char* bumpalloc_heap_ptr = (char*)NULL; +__thread char* bumpalloc_heap_ptr_end = (char*)NULL; + +char* saved_heap_ptr_stack[100]; +int num_saved_heap_ptr = 0; + +// For simplicity just use a single large slab: +static inline void INITBUMPALLOC() { + bumpalloc_heap_ptr = (char*)malloc(global_init_biginf_buf_size); + bumpalloc_heap_ptr_end = bumpalloc_heap_ptr + global_init_biginf_buf_size; +#ifdef _DEBUG + printf("Arena size for bump alloc: %lld\n", global_init_biginf_buf_size); + printf("BUMPALLOC/INITBUMPALLOC DONE: heap_ptr = %p\n", bumpalloc_heap_ptr); +#endif +} + +static inline void* BUMPALLOC(long long n) { + if (! bumpalloc_heap_ptr) { + INITBUMPALLOC(); + } + if (bumpalloc_heap_ptr + n < bumpalloc_heap_ptr_end) { + char* old= bumpalloc_heap_ptr; + bumpalloc_heap_ptr += n; + return old; + } else { + fprintf(stderr, "Warning: bump allocator ran out of memory."); + exit(1); + } +} + +// Snapshot the current heap pointer value across all threads. +void save_alloc_state() { + dbgprintf("Saving(%p): pos %d", heap_ptr, num_saved_heap_ptr); + saved_heap_ptr_stack[num_saved_heap_ptr] = heap_ptr; + num_saved_heap_ptr++; + dbgprintf("\n"); +} + +void restore_alloc_state() { + if(num_saved_heap_ptr <= 0) { + fprintf(stderr, "Bad call to restore_alloc_state! Saved stack empty!\ne"); + exit(1); + } + num_saved_heap_ptr--; + dbgprintf("Restoring(%p): pos %d, discarding %p", + saved_heap_ptr_stack[num_saved_heap_ptr], num_saved_heap_ptr, bumpalloc_heap_ptr); + bumpalloc_heap_ptr = saved_heap_ptr_stack[num_saved_heap_ptr]; +} + + +#else +// Regular malloc mode: +void INITBUMPALLOC() {} +void save_alloc_state() {} +void restore_alloc_state() {} + +#define BUMPALLOC(n) malloc(n) + +#endif // BUMPALLOC + + +// ------------------------------------- +// ALLOC and ALLOC_PACKED macros +// ------------------------------------- + + +/* + +If parallelism is enabled, we always use a malloc based allocator +since Boehm GC is not thread-safe in its default configuration. It can be +made thread-safe by building it with appropriate flags, but we don't do that. +Presently, all parallel pointer-based programs will leak memory. + +*/ + +#ifdef _PARALLEL +#define ALLOC(n) malloc(n) +#define ALLOC_PACKED_BIG(n) malloc(n) +char *ALLOC_COUNTED(size_t size) { + bump_global_region_count(); + return ALLOC(size); +} +#else + #ifdef _POINTER +#define ALLOC(n) GC_MALLOC(n) +#define ALLOC_PACKED_BIG(n) GC_MALLOC(n) +char *ALLOC_COUNTED(size_t size) { + bump_global_region_count(); + return GC_MALLOC(size); +} + #else +#define ALLOC(n) malloc(n) +#define ALLOC_PACKED_BIG(n) malloc(n) +char *ALLOC_COUNTED(size_t size) { + bump_global_region_count(); + return ALLOC(size); +} + #endif // _POINTER +#endif // _PARALLEL + + +// Could try alloca() here. Better yet, we could keep our own, +// separate stack and insert our own code to restore the pointer +// before any function that (may have) called ALLOC_SCOPED returns. + +// #define ALLOC_SCOPED() alloca(1024) +#define ALLOC_SCOPED(n) alloca(n) +// #define ALLOC_SCOPED() alloc_scoped() + +// Stack allocation is either too small or blows our stack. +// We need a way to make a giant stack if we want to use alloca. +// #define ALLOC_SCOPED() ALLOC(global_init_biginf_buf_size) + +// Our global pointer. No parallelism. +// static char* stack_scoped_region; +// char* alloc_scoped() { return stack_scoped_region; } + + + +// ------------------------------------- +// Basic types +// ------------------------------------- + +// Must be consistent with sizeOfTy defined in Gibbon.Language.Syntax. + +typedef unsigned char TagTyPacked; +typedef unsigned char TagTyBoxed; +typedef long long IntTy; +typedef char CharTy; +typedef float FloatTy; +typedef unsigned long long SymTy; +typedef bool BoolTy; +typedef char* PtrTy; +typedef char* CursorTy; + +// ------------------------------------- +// Arenas and dictionaries +// ------------------------------------- + +typedef struct mem_arena { + int ind; + char* mem; // TODO(vollmerm): make this a list of chunks? + void* reflist; +} mem_arena_t; + +typedef mem_arena_t* ArenaTy; + +ArenaTy alloc_arena() { + ArenaTy ar = ALLOC(sizeof(mem_arena_t)); + ar->ind = 0; + ar->mem = malloc(global_inf_buf_max_chunk_size); + ar->reflist = 0; + return ar; +} + +void free_arena(ArenaTy ar) { + free(ar->mem); + // TODO(vollmerm): free everything in ar->reflist + free(ar); +} + +CursorTy extend_arena(ArenaTy ar, int size) { + CursorTy ret = ar->mem + ar->ind; + ar->ind += size; + return ret; +} + +typedef struct dict_item { + struct dict_item * next; + int key; + void * ptrval; +} dict_item_t; + +dict_item_t * dict_alloc(ArenaTy ar) { + return (dict_item_t *) extend_arena(ar, sizeof(dict_item_t)); // ALLOC(sizeof(dict_item_t)); +} + +dict_item_t *dict_insert_ptr(ArenaTy ar, dict_item_t *ptr, SymTy key, PtrTy val) { + dict_item_t *ret = dict_alloc(ar); + ret->key = key; + ret->ptrval = val; + ret->next = ptr; + return ret; +} + +PtrTy dict_lookup_ptr(dict_item_t *ptr, SymTy key) { + while (ptr != 0) { + if (ptr->key == key) { + return ptr->ptrval; + } else { + ptr = ptr->next; + } + } + printf("Error, key %lld not found!\n",key); + exit(1); +} + +// ------------------------------------- +// Sets +// ------------------------------------- + + +struct set_elem { + int val; + UT_hash_handle hh; +}; + +typedef struct set_elem* SymSetTy; + +SymSetTy empty_set() { + return NULL; +} + +SymSetTy insert_set(SymSetTy set, int sym) { + SymSetTy s; + HASH_FIND_INT(set, &sym, s); /* sym already in the hash? */ + if (s==NULL) { + s = malloc(sizeof(struct set_elem)); + s->val = sym; + HASH_ADD_INT(set,val,s); + } + return set; +} + +BoolTy contains_set(SymSetTy set, int sym) { + SymSetTy s; + HASH_FIND_INT(set, &sym, s); + return (s!=NULL); +} + +// ------------------------------------- +// Sym Hash +// ------------------------------------- + +struct sym_hash_elem { + int key; + int val; + UT_hash_handle hh; +}; + +typedef struct sym_hash_elem* SymHashTy; + +typedef struct sym_hash_elem* IntHashTy; + +SymHashTy empty_hash() { + return NULL; +} + +SymHashTy insert_hash(SymHashTy hash, int k, int v) { + SymHashTy s; + // NOTE: not checking for duplicates! + // s = malloc(sizeof(struct sym_hash_elem)); + s = ALLOC(sizeof(struct sym_hash_elem)); + s->val = v; + s->key = k; + HASH_ADD_INT(hash,key,s); + + return hash; +} + +IntTy lookup_hash(SymHashTy hash, int k) { + SymHashTy s; + HASH_FIND_INT(hash,&k,s); + if (s==NULL) { + return k; // NOTE: return original key if val not found + // TODO(vollmerm): come up with something better to do here + } else { + return s->val; + } +} + +BoolTy contains_hash(SymHashTy hash, int sym) { + SymHashTy s; + HASH_FIND_INT(hash,&sym,s); + return (s!=NULL); +} + +// ------------------------------------- +// Helpers +// ------------------------------------- + +char* read_benchfile_param() { + if (global_benchfile_param == NULL) { + fprintf(stderr, "read_benchfile_param: benchmark input file was not set! Set using --bench-input.\n"); + exit(1); + } else + return global_benchfile_param; +} + +char* read_arrayfile_param() { + if (global_arrayfile_param == NULL) { + fprintf(stderr, "read_arrayfile_param: array input file was not set! Set using --array-input.\n"); + exit(1); + } else + return global_arrayfile_param; +} + +IntTy read_arrayfile_length_param() { + if (global_arrayfile_length_param == -1) { + fprintf(stderr, "read_arrayfile_length_param: array input file length was not set! Set using --array-input-length.\n"); + exit(1); + } else + return global_arrayfile_length_param; +} + + +// fun fact: __ prefix is actually reserved and this is an undefined behavior. +// These functions must be provided by the code generator. +int __main_expr(); + + +void show_usage(char** argv) +{ + printf("\n"); + printf("This binary was generated by the Gibbon compiler.\n"); + printf("\n"); + printf("Usage: %s [OPTS] [size] [iters]\n", argv[0]); + + printf("\n"); + printf("Options:\n"); + printf(" --buffer-size Set the buffer size (default %lld).\n", global_init_biginf_buf_size); + printf(" --bench-input Set the input file read for benchmarking. Applies only\n"); + printf(" IF the program was *compiled* with --bench-fun. \n"); + return; +} + +double avg(const double* arr, int n) +{ + double sum = 0.0; + for(int i=0; itv_sec - t0->tv_sec) + + ((double)(t1->tv_nsec - t0->tv_nsec) / 1000000000.0); +} + +int compare_doubles(const void *a, const void *b) +{ + const double *da = (const double *) a; + const double *db = (const double *) b; + return (*da > *db) - (*da < *db); +} + +// Exponentiation +IntTy expll(IntTy base, IntTy pow) { + if (base == 2) { + return (1 << pow); + } else { + IntTy i, result = 1; + for (i = 0; i < pow; i++) + result *= base; + return result; + } + } + +// ------------------------------------- +// Symbol table +// ------------------------------------- + +#define global_max_symbol_len 256 + +// Invariant: should always be equal to max(sym_table_keys) +static SymTy global_gensym_counter = 0; + +// Its value is updated by the flags parser. +static char *global_bench_prog_param; + +static SymTy newline_symbol = -1; +static SymTy space_symbol = -1; +static SymTy comma_symbol = -1; +static SymTy leftparen_symbol = -1; +static SymTy rightparen_symbol = -1; + +typedef struct SymTable_elem { + SymTy idx; /* key */ + char value[global_max_symbol_len]; + UT_hash_handle hh; /* makes this structure hashable */ +} SymTable_elem; + +// important! initialize to NULL +SymTable_elem *global_sym_table = NULL; + +void add_symbol(SymTy idx, char *value) { + struct SymTable_elem *s; + s = ALLOC(sizeof(struct SymTable_elem)); + s->idx = idx; + strcpy(s->value, value); + HASH_ADD(hh, global_sym_table, idx, sizeof(IntTy), s); + if (idx > global_gensym_counter) { + global_gensym_counter = idx; + } +} + +void set_newline(SymTy idx) { + newline_symbol = idx; + add_symbol(idx,"NEWLINE"); +} + +void set_space(SymTy idx) { + space_symbol = idx; + add_symbol(idx,"SPACE"); +} + +void set_comma(SymTy idx) { + comma_symbol = idx; + add_symbol(idx,"COMMA"); +} + +void set_leftparen(SymTy idx) { + leftparen_symbol = idx; + add_symbol(idx,"LEFTPAREN"); +} + +void set_rightparen(SymTy idx) { + rightparen_symbol = idx; + add_symbol(idx,"RIGHTPAREN"); +} + +IntTy print_symbol(SymTy idx) { + if (idx == comma_symbol) { + return printf(","); + } else if (idx == newline_symbol) { + return printf("\n"); + } else if (idx == space_symbol) { + return printf(" "); + } else if (idx == leftparen_symbol) { + return printf("("); + } else if (idx == rightparen_symbol) { + return printf(")"); + } else { + struct SymTable_elem *s; + HASH_FIND(hh, global_sym_table, &idx, sizeof(SymTy), s); + if (s == NULL) { + return printf("%lld", idx); + } else { + return printf("%s", s->value); + } + + } +} + +#ifdef _PARALLEL +SymTy gensym() { + SymTy idx = __atomic_add_fetch(&global_gensym_counter, 1, __ATOMIC_SEQ_CST); + return idx; +} +#else +SymTy gensym() { + global_gensym_counter += 1; + SymTy idx = global_gensym_counter; + return idx; +} +#endif + +void free_symtable() { + struct SymTable_elem *elt, *tmp; + HASH_ITER(hh, global_sym_table, elt, tmp) { + HASH_DEL(global_sym_table,elt); + } + free(elt); + free(tmp); +} + +/* + +---------------------------------------- +Garbage collection +---------------------------------------- + + Gibbon has "growing regions" i.e each logical region is backed by a doubly linked-list + of smaller chunks which grows as required. In addition to actual data, each chunk + stores some additional metadata (RegionFooter) to chain the chunks together in a list + and for garbage collection. The footer: + + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + serialized data | rf_reg_metadata_ptr | rf_seq_no | rf_size | rf_next | rf_prev + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + The metadata after the serialized data serves various purposes: + + - rf_reg_metadata_ptr: A pointer to a RegionTy struct that contains various metadata. + Of particular interest to us are the fields: + + = reg_id: A unique identifier for a region. + + = refcount and outset: Whenever an inter-region indirection is created, we record that information + using these two fields. Suppose we have an indirection from region A that points to some chunk + in region B. Then A's outset will store a pointer to that chunk's footer, and B's refcount will + be bumped by 1. Note that all there's only 1 refcount cell, and 1 outset per logical region, + and chunks only store a pointer to them. + + - rf_seq_no: The index of this particular chunk in the list. + + - rf_size: Used during bounds checking to calculate the size of the next region in + the linked list. + + - rf_next / rf_prev: Point to the next and previous chunk respectively. + + +There are two ways in which a region may be freed: + +(1) Whenever it goes out of scope + + The RTS tries to free a region whenever it goes out of scope. But this doesn't always succeed as + regions sometimes contain values that "escape". One reason why this'll happen is if there's an + indirection from A->B, and A lives longer than B. + In such a case, when B goes out of scope it's refcount won't be 0, and the RTS won't free it. + This brings us to (2). + +(2) + + When the RTS successfully frees a region, it decrements the refcounts of all the regions it + points to (via the outset). At the same time, if it encounters a region in the outset whoose + refcount becomes 0 after the decrement, it calls free_region on that. This way we can be sure + that all regions will eventually be garbage collected before the program exits. + + + +Why is it a doubly linked-list? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Due to way that bounds-checking works, the pointers in the outset may actually point to any +arbitrary chunk in the chain. However, we must call free_region on the first one to ensure that +all of them are GC'd. So we need pointers to traverse backward get to the first one. +'trav_to_first_chunk' accomplishes this. + + */ + +#define MAX_OUTSET_LENGTH 10 + +typedef struct RegionTy_struct { + SymTy reg_id; + uint reg_refcount; + CursorTy reg_heap; + uint reg_outset_len; + CursorTy reg_outset[MAX_OUTSET_LENGTH]; +} RegionTy; + +typedef struct RegionFooter_struct { + RegionTy *rf_reg_metadata_ptr; + + IntTy rf_seq_no; + IntTy rf_size; + struct RegionFooter_struct *rf_next; + struct RegionFooter_struct *rf_prev; +} RegionFooter; + +typedef struct ChunkTy_struct { + CursorTy chunk_start; + CursorTy chunk_end; +} ChunkTy; + +static inline void insert_into_outset(CursorTy ptr, RegionTy *reg) { + uint outset_len = reg->reg_outset_len; + // Check for duplicates. + for (uint i = 0; i < outset_len; i++) { + if (ptr == reg->reg_outset[i]) { + return; + } + } + // Otherwise, insert into the outset. + reg->reg_outset[outset_len] = ptr; + reg->reg_outset_len = outset_len + 1; + return; +} + +static inline void remove_from_outset(CursorTy ptr, RegionTy *reg) { + uint outset_len = reg->reg_outset_len; + CursorTy *outset = reg->reg_outset; + int i; + if (outset_len == 0) { + fprintf(stderr, "remove_from_outset: empty outset\n"); + exit(1); + } + // Position of 'ptr' in the outset. + int elt_idx = -1; + for (i = 0; i < outset_len; i++) { + if (ptr == outset[i]) { + elt_idx = i; + } + } + if (elt_idx == -1) { + fprintf(stderr, "remove_from_outset: element not found\n"); + exit(1); + } + // Move all elements ahead of 'elt_idx' back by one position. + for (i = elt_idx; i < outset_len; i++) { + outset[i] = outset[i+1]; + } + return; +} + +RegionTy *alloc_region(IntTy size) { + // Allocate the region metadata. + RegionTy *reg = ALLOC(sizeof(RegionTy)); + if (reg == NULL) { + printf("alloc_region: allocation failed: %ld", sizeof(RegionTy)); + exit(1); + } + + // Allocate the first chunk. + IntTy total_size = size + sizeof(RegionFooter); + CursorTy heap = ALLOC_PACKED_BIG(total_size); + if (heap == NULL) { + printf("alloc_region: malloc failed: %lld", total_size); + exit(1); + } + // Not heap+total_size, since we must keep space for the footer. + CursorTy heap_end = heap + size; + + // Initialize metadata fields. + reg->reg_id = gensym(); + reg->reg_refcount = 1; + reg->reg_heap = heap; + reg->reg_outset_len = 0; + +#ifdef _DEBUG + printf("Allocated a region(%lld): %lld bytes.\n", reg->reg_id, size); +#endif + + // Write the footer. + RegionFooter *footer = (RegionFooter *) heap_end; + footer->rf_reg_metadata_ptr = reg; + footer->rf_seq_no = 1; + footer->rf_size = size; + footer->rf_next = NULL; + footer->rf_prev = NULL; + + return reg; +} + +RegionTy *alloc_counted_region(IntTy size) { + // Bump the count. + bump_global_region_count(); + return alloc_region(size); +} + +ChunkTy alloc_chunk(CursorTy end_old_chunk) { + // Get size from current footer. + RegionFooter *footer = (RegionFooter *) end_old_chunk; + IntTy newsize = footer->rf_size * 2; + // See #110. + if (newsize > global_inf_buf_max_chunk_size) { + newsize = global_inf_buf_max_chunk_size; + } + IntTy total_size = newsize + sizeof(RegionFooter); + + // Allocate. + CursorTy start = ALLOC_PACKED_BIG(total_size); + if (start == NULL) { + printf("alloc_chunk: malloc failed: %lld", total_size); + exit(1); + } + CursorTy end = start + newsize; + + // Link the next chunk's footer. + footer->rf_next = (RegionFooter *) end; + + // Write the footer. + RegionFooter* new_footer = (RegionFooter *) end; + new_footer->rf_reg_metadata_ptr = footer->rf_reg_metadata_ptr; + new_footer->rf_seq_no = footer->rf_seq_no + 1; + new_footer->rf_size = newsize; + new_footer->rf_next = NULL; + new_footer->rf_prev = footer; + +#ifdef _DEBUG + RegionTy *reg = (RegionTy*) new_footer->rf_reg_metadata_ptr; + printf("alloc_chunk: allocated %lld bytes for region %lld.\n", total_size, reg->reg_id); +#endif + + return (ChunkTy) {start , end}; +} + +RegionFooter* trav_to_first_chunk(RegionFooter *footer) { + if (footer->rf_seq_no == 1) { + return footer; + } else if (footer->rf_prev == NULL) { + fprintf(stderr, "No previous chunk found at rf_seq_no: %lld", footer->rf_seq_no); + return NULL; + } else { + trav_to_first_chunk((RegionFooter *) footer->rf_prev); + } + return NULL; +} + +uint get_ref_count(CursorTy end_ptr) { + RegionFooter *footer = (RegionFooter *) end_ptr; + RegionTy *reg = (RegionTy *) footer->rf_reg_metadata_ptr; + return reg->reg_refcount; +} + +// B is the pointer, and A is the pointee (i.e B -> A). +// Bump A's refcount and update B's outset. +static inline void bump_ref_count(CursorTy end_b, CursorTy end_a) { + // Grab footers. + RegionFooter *footer_a = (RegionFooter *) end_a; + RegionFooter *footer_b = (RegionFooter *) end_b; + + // Grab metadata. + RegionTy *reg_a = (RegionTy *) footer_a->rf_reg_metadata_ptr; + RegionTy *reg_b = (RegionTy *) footer_b->rf_reg_metadata_ptr; + + // Bump A's refcount. + uint current_refcount, new_refcount; + current_refcount = reg_a->reg_refcount; + new_refcount = current_refcount + 1; + reg_a->reg_refcount = new_refcount; + +#ifdef _DEBUG + printf("bump_ref_count: %lld -> %lld\n", reg_b->reg_id, reg_a->reg_id); + printf("bump_ref_count: old-refcount=%d, old-outset-len=%d:\n", current_refcount, reg_b->reg_outset_len); + assert(current_refcount == reg_b->reg_outset_len+1); +#endif + + // Add A to B's outset. + insert_into_outset(end_a, reg_b); + +#ifdef _DEBUG + // printf("bump_ref_count: Added %p to %lld's outset, %p.\n", end_a, reg_b->reg_id, reg_b); + printf("bump_ref_count: new-refcount=%d, new-outset-len=%d\n", new_refcount, reg_b->reg_outset_len); + assert(new_refcount == reg_b->reg_outset_len+1); +#endif + + return; +} + +void free_region(CursorTy end_reg) { + // Grab footer and the metadata. + RegionFooter *footer = (RegionFooter *) end_reg; + RegionTy *reg = (RegionTy *) footer->rf_reg_metadata_ptr; + + // + RegionFooter *first_chunk_footer, *next_chunk_footer; + CursorTy first_chunk, next_chunk; + + // Decrement current reference count. + uint current_refcount, new_refcount; + current_refcount = reg->reg_refcount; + new_refcount = 0; + if (current_refcount != 0) { + new_refcount = current_refcount - 1; + reg->reg_refcount = new_refcount; + } + +#ifdef _DEBUG + printf("free_region(%lld): refcounts (1): old-refcount=%d, new-refcount=%d:\n", reg->reg_id, current_refcount, new_refcount); +#endif + + + // Free this region recount is 0. + if (new_refcount == 0) { + +#ifdef _DEBUG + printf("free_region(%lld): outset length: %d\n", reg->reg_id, reg->reg_outset_len); +#endif + + // Decrement refcounts, free regions with refcount==0 and also free + // elements of the outset. + if (reg->reg_outset_len != 0) { + uint outset_len = reg->reg_outset_len; + CursorTy *outset = reg->reg_outset; + RegionFooter *elt_footer; + RegionTy *elt_reg; + uint elt_current_refcount, elt_new_refcount; + CursorTy to_be_removed[MAX_OUTSET_LENGTH]; + uint to_be_removed_idx = 0; + for (int i = 0; i < outset_len; i++) { + elt_footer = (RegionFooter *) outset[i]; + elt_reg = (RegionTy *) elt_footer->rf_reg_metadata_ptr; +#ifdef _DEBUG + elt_current_refcount = elt_reg->reg_refcount; +#endif + elt_new_refcount = elt_current_refcount - 1; + elt_reg->reg_refcount = elt_new_refcount; +#ifdef _DEBUG + printf("free_region(%lld): old-refcount=%d, new-refcount=%d:\n", + elt_reg->reg_id, elt_current_refcount, elt_reg->reg_refcount); +#endif + if (elt_new_refcount == 0) { + // See [Why is it a doubly linked-list?] above + first_chunk_footer = trav_to_first_chunk(elt_footer); + if (first_chunk_footer != NULL) { + free_region((CursorTy) first_chunk_footer); + } + } + to_be_removed[to_be_removed_idx] = outset[i]; + to_be_removed_idx++; + } + // Remove elements from the outset. + for (uint i = 0; i < to_be_removed_idx; i++) { + remove_from_outset(to_be_removed[i], reg); + } + } + + +#ifdef _DEBUG + // Bookkeeping + IntTy num_freed_chunks = 0, total_bytesize = 0; +#endif + + // Free the chunks in this region. + first_chunk = end_reg - footer->rf_size; + first_chunk_footer = footer; + next_chunk = (char*) footer->rf_next; + +#ifdef _DEBUG + printf("free_region(%lld)\n", reg->reg_id); +#endif + +#ifdef _DEBUG + num_freed_chunks++; + total_bytesize = total_bytesize + first_chunk_footer->rf_size; +#endif + free(first_chunk); + + while (next_chunk != NULL) { + next_chunk_footer = (RegionFooter *) next_chunk; + #ifdef _DEBUG + num_freed_chunks++; + total_bytesize = total_bytesize + next_chunk_footer->rf_size; + #endif + free(next_chunk - next_chunk_footer->rf_size); + next_chunk = (char*) next_chunk_footer->rf_next; + } + +#ifdef _DEBUG + printf("free_region(%lld): Freed %lld bytes across %lld chunks.\n", + reg->reg_id, total_bytesize, num_freed_chunks); +#endif + + // Free the metadata. + free(reg); + + } else { +#ifdef _DEBUG + printf("free_region(%lld): non-zero refcount: %d.\n", + reg->reg_id, reg->reg_refcount); +#endif + } +} + +// Assume that all nodes with size information have tags >= 150. +BoolTy is_big(IntTy i, CursorTy cur) { + TagTyPacked tag = *(TagTyPacked *) cur; + if (tag >= 150) { + cur += 1; + IntTy size = *(IntTy *) cur; + if (size >= i) { + return true; + } else { + return false; + } + } + return false; +} + +// ------------------------------------- +// Vectors +// ------------------------------------- + +typedef struct VectorTy_struct { + // Bounds on the vector. + IntTy vec_lower, vec_upper; + + // Size of each element. + IntTy vec_elt_size; + + // Actual elements of the vector. + void* vec_data; +} VectorTy; + +VectorTy* vector_alloc(IntTy num, IntTy elt_size) { + VectorTy *vec = ALLOC(sizeof(VectorTy)); + if (vec == NULL) { + printf("alloc_vector: malloc failed: %ld", sizeof(VectorTy)); + exit(1); + } + void* data = ALLOC(num * elt_size); + if (data == NULL) { + printf("alloc_vector: malloc failed: %ld", sizeof(num * elt_size)); + exit(1); + } + vec->vec_lower = 0; + vec->vec_upper = num; + vec->vec_elt_size = elt_size; + vec->vec_data = data; + return vec; +} + +IntTy vector_length(VectorTy *vec) { + return (vec->vec_upper - vec->vec_lower); +} + +BoolTy vector_is_empty(VectorTy *vec) { + return (vector_length(vec) == 0); +} + +VectorTy* vector_slice(IntTy i, IntTy n, VectorTy *vec) { + IntTy lower = vec->vec_lower + i; + IntTy upper = vec->vec_lower + i + n; + if ((lower > vec->vec_upper)) { + printf("vector_slice: lower out of bounds, %lld > %lld", lower, vec->vec_upper); + exit(1); + } + if ((upper > vec->vec_upper)) { + printf("vector_slice: upper out of bounds: %lld > %lld", upper, vec->vec_upper); + exit(1); + } + VectorTy *vec2 = ALLOC(sizeof(VectorTy)); + if (vec == NULL) { + printf("vector_slice: malloc failed: %ld", sizeof(VectorTy)); + exit(1); + } + vec2->vec_lower = lower; + vec2->vec_upper = upper; + vec2->vec_elt_size = vec->vec_elt_size; + vec2->vec_data = vec->vec_data; + return vec2; +} + +// The callers must cast the return value. +static inline void* vector_nth(VectorTy *vec, IntTy i) { + // if (i < vec->lower || i > vec->upper) { + // printf("vector_nth index out of bounds: %lld (%lld,%lld) \n", i, vec->vec_lower, vec->vec_upper); + // exit(1); + // } + return (vec->vec_data + (vec->vec_elt_size * (vec->vec_lower + i))); +} + +static inline VectorTy* vector_inplace_update(VectorTy *vec, IntTy i, void* elt) { + void* dst = vector_nth(vec, i); + memcpy(dst, elt, vec->vec_elt_size); + return vec; +} + +static inline VectorTy* vector_copy(VectorTy *vec) { + IntTy len = vector_length(vec); + void *start = vector_nth(vec, 0); + VectorTy *vec2 = vector_alloc(len, vec->vec_elt_size); + memcpy(vec2->vec_data, start, len * vec->vec_elt_size); + return vec2; +} + +static inline VectorTy* vector_inplace_sort(VectorTy *vec, int (*compar)(const void *, const void*)) { + void *start = vector_nth(vec, 0); + qsort(start, vector_length(vec), vec->vec_elt_size, compar); + return vec; +} + +static inline VectorTy* vector_sort(VectorTy *vec, int (*compar)(const void *, const void*)) { + VectorTy *vec2 = vector_copy(vec); + vector_inplace_sort(vec2, compar); + return vec2; +} + +static inline VectorTy* vector_concat(VectorTy *vec) { + // Length of the input vector. + IntTy len = vector_length(vec); + // Length of the concatenated vector. + IntTy result_len = 0; + // Size of each element in the concatenated vector. + IntTy result_elt_size = 0; + VectorTy **elt_ref, *elt; + for (IntTy i = 0; i < len; i++) { + elt_ref = vector_nth(vec, i); + elt = *elt_ref; + result_elt_size = elt->vec_elt_size; + result_len += vector_length(elt); + } + + // Concatenated vector. + VectorTy *result = vector_alloc(result_len, result_elt_size); + IntTy elt_len; + // A counter that tracks the index of elements in 'result'. + IntTy k = 0; + for (IntTy i = 0; i < len; i++) { + elt_ref = vector_nth(vec, i); + elt = *elt_ref; + elt_len = vector_length(elt); + + for (IntTy j = 0; j < elt_len; j++) { + void* k_elt = vector_nth(elt, j); + vector_inplace_update(result, k, k_elt); + k++; + } + } + + return result; +} + +static inline void vector_free(VectorTy *vec) { + free(vec->vec_data); + free(vec); + return; +} + +static inline VectorTy* vector_merge(VectorTy *vec1, VectorTy *vec2) { + if (vec1->vec_upper != vec2->vec_lower) { + printf("vector_merge: non-contiguous slices, (%lld,%lld), (%lld,%lld).", + vec1->vec_lower, vec1->vec_upper, vec2->vec_lower, vec2->vec_upper); + exit(1); + } + VectorTy *merged = ALLOC(sizeof(VectorTy)); + if (merged == NULL) { + printf("vector_merge: malloc failed: %ld", sizeof(VectorTy)); + exit(1); + } + merged->vec_lower = vec1->vec_lower; + merged->vec_upper = vec2->vec_upper; + merged->vec_elt_size = vec1->vec_elt_size; + merged->vec_data = vec1->vec_data; + return merged; +} + +void print_timing_array(VectorTy *times) { + printf("TIMES: ["); + double *d; + IntTy n = vector_length(times); + for(int i = 0; i < n; i++) { + d = vector_nth(times, i); + if (i == (n-1)) { + printf("%f",*d); + } + else { + printf("%f, ",*d); + } + } + printf("]\n"); +} + +double sum_timing_array(VectorTy *times) { + double *d; + double acc = 0; + for(int i = 0; i < vector_length(times); i++) { + d = vector_nth(times, i); + acc += *d; + } + return acc; +} + +// ------------------------------------- +// Linked lists +// ------------------------------------- + +typedef struct ListTy_struct { + IntTy ll_data_size; + void* ll_data; + struct ListTy_struct* ll_next; +} ListTy; + +static inline ListTy* list_alloc(IntTy data_size) { + // ListTy *ls = ALLOC(sizeof(ListTy)); + ListTy *ls = BUMPALLOC(sizeof(ListTy)); + ls->ll_data_size = data_size; + ls->ll_data = NULL; + ls->ll_next = NULL; + return ls; +} + +static inline BoolTy list_is_empty(ListTy *ls) { + return ls->ll_next == NULL; +} + +static inline ListTy* list_cons(void* elt, ListTy *ls) { + // void* data = ALLOC(ls->data_size); + void* data = BUMPALLOC(ls->ll_data_size); + if (data == NULL) { + printf("list_cons: malloc failed: %lld", ls->ll_data_size); + exit(1); + } + memcpy(data, elt, ls->ll_data_size); + // ListTy *res = ALLOC(sizeof(ListTy)); + ListTy *res = BUMPALLOC(sizeof(ListTy)); + res->ll_data_size = ls->ll_data_size; + res->ll_data = data; + res->ll_next = (ListTy*) ls; + return res; +} + +static inline void* list_head(ListTy *ls) { + return ls->ll_data; +} + +static inline ListTy* list_tail(ListTy *ls) { + return ls->ll_next; +} + +static inline void list_free(ListTy *ls) { + free(ls->ll_data); + free(ls); + return; +} + +static inline ListTy* list_copy(ListTy *ls) { + ListTy *ls2 = list_alloc(ls->ll_data_size); + if (ls->ll_data != NULL) { + void* data = BUMPALLOC(ls->ll_data_size); + memcpy(data, ls->ll_data, ls->ll_data_size); + ls2->ll_data = data; + } + ls2->ll_next = ls->ll_next; + return ls2; +} + +// ------------------------------------- +// Ppm Images +// ------------------------------------- + +typedef struct __Pixel_struct { + IntTy field0; + IntTy field1; + IntTy field2; +} __Pixel; + +void writePpm(char* filename, IntTy width, IntTy height, VectorTy *pixels); +void writePpm_loop(FILE *fp, IntTy idx, IntTy end, VectorTy *pixels); + +// Example: writePpm("gibbon_rgb_1000.ppm", 1000, 1000, pixels); +void writePpm(char* filename, IntTy width, IntTy height, VectorTy *pixels) +{ + FILE *fp; + fp = fopen(filename, "w+"); + fprintf(fp, "P3\n"); + fprintf(fp, "%lld %lld\n255\n", width, height); + IntTy len = vector_length(pixels); + writePpm_loop(fp, 0, len, pixels); + fclose(fp); + return; +} + +void writePpm_loop(FILE *fp, IntTy idx, IntTy end, VectorTy *pixels) +{ + BoolTy fltIf_5768_6575 = idx == end; + + if (fltIf_5768_6575) { + return; + } else { + __Pixel *tmp_112; + tmp_112 = (__Pixel *) vector_nth(pixels, idx); + __Pixel tup = *tmp_112; + IntTy x = tup.field0; + IntTy y = tup.field1; + IntTy z = tup.field2; + // write to file. + fprintf(fp, "%lld %lld %lld\n", x, y, z); + writePpm_loop(fp, (idx+1), end, pixels); + } +} + +/* -------------------------------------------------------------------------------- */ + +int main(int argc, char** argv) +{ + // parameters to parse: + // + // num iterations: How many times to repeat a benchmark. + // tree size: An integer passes to `build_tree()`. + + struct rlimit lim; + int code; + if ( (code = getrlimit(RLIMIT_STACK, &lim)) ) { + fprintf(stderr, " [gibbon rts] failed to getrlimit, code %d\n", code); + exit(1); + } + + // lim.rlim_cur = 1024LU * 1024LU * 1024LU; // 1GB stack. + lim.rlim_cur = 512LU * 1024LU * 1024LU; // 500MB stack. + // lim.rlim_max = lim.rlim_cur; // Normal users may only be able to decrease this. + + // WARNING: Haven't yet figured out why this doesn't work on MacOS... +#ifndef __APPLE__ + code = setrlimit(RLIMIT_STACK, &lim); + while (code) { + fprintf(stderr, " [gibbon rts] Failed to set stack size to %llu, code %d\n", (unsigned long long)lim.rlim_cur, code); + lim.rlim_cur /= 2; + // lim.rlim_max /= 2; + if(lim.rlim_cur < 100 * 1024) { + fprintf(stderr, " [gibbon rts] Failed setrlimit stack size to something reasonable; giving up.\n"); + break; // abort(); + } + int code = setrlimit(RLIMIT_STACK, &lim); + } +#endif + + int got_numargs = 0; // How many numeric arguments have we got. + + int i; + for (i = 1; i < argc; ++i) + { + if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) { + show_usage(argv); + exit(0); + } + else if (strcmp(argv[i], "--biginf-buffer-size") == 0 && i < argc - 1) + { + global_init_biginf_buf_size = atoll(argv[i + 1]); + i++; + } + else if (strcmp(argv[i], "--inf-buffer-size") == 0 && i < argc - 1) + { + global_init_inf_buf_size = atoll(argv[i + 1]); + i++; + } + else if ((strcmp(argv[i], "--bench-input") == 0)) { + if (i+1 >= argc) { + fprintf(stderr, "Not enough arguments after --bench-input, expected .\n"); + show_usage(argv); + exit(1); + } + global_benchfile_param = argv[i+1]; + i++; + } + else if ((strcmp(argv[i], "--array-input") == 0)) { + if (i+1 >= argc) { + fprintf(stderr, "Not enough arguments after --array-input, expected .\n"); + show_usage(argv); + exit(1); + } + global_arrayfile_param = argv[i+1]; + i++; + } + else if (strcmp(argv[i], "--array-input-length") == 0 && i < argc - 1) { + global_arrayfile_length_param = atoll(argv[i+1]); + i++; + } + else if (strcmp(argv[i], "--bench-prog") == 0 && i < argc - 1) { + int len = strlen(argv[i+1]); + global_bench_prog_param = (char*) malloc((len+1)*sizeof(char)); + strncpy(global_bench_prog_param,argv[i+1],len); + i++; + } + // If present, we expect the two arguments to be + else if (got_numargs >= 2) { + fprintf(stderr, "Extra arguments left over: "); + for(; i < argc; i++) fprintf(stderr, "%s ", argv[i]); + show_usage(argv); + exit(1); + } else { + if (got_numargs == 0) { + global_size_param = atoll(argv[i]); + got_numargs ++; + } else { + global_iters_param = atoll(argv[i]); + } + } + } + + // Initialize global_bench_prog_param to an empty string in case + // the runtime argument --bench-prog isn't passed. + if (global_bench_prog_param == NULL) { + global_bench_prog_param = (char*) malloc(1*sizeof(char)); + *global_bench_prog_param = '\n'; + } + + __main_expr(); + + return 0; +} + +// ----------------------------------------------------------------------------- +// Program starts here +// ----------------------------------------------------------------------------- + +typedef struct Prod_struct { } Prod; +typedef struct Int64Prod_struct { + IntTy field0; + } Int64Prod; +typedef struct Int64Int64Int64Int64CursorCursorProd_struct { + IntTy field0; + IntTy field1; + IntTy field2; + IntTy field3; + CursorTy field4; + CursorTy field5; + } Int64Int64Int64Int64CursorCursorProd; +typedef struct Int64Int64Int64CursorCursorProd_struct { + IntTy field0; + IntTy field1; + IntTy field2; + CursorTy field3; + CursorTy field4; + } Int64Int64Int64CursorCursorProd; +typedef struct BoolProd_struct { + BoolTy field0; + } BoolProd; +typedef struct TagCursorProd_struct { + TagTyPacked field0; + CursorTy field1; + } TagCursorProd; +typedef struct CursorProd_struct { + CursorTy field0; + } CursorProd; +IntTy sumLeft(CursorTy m_34_689_917); +CursorTy build(IntTy x_40_695_926, IntTy sz_41_696_927, CursorTy m_42_697_928); +IntTy ratio(); +IntTy delta(); +IntTy size_316(CursorTy m_173_698_938); +CursorTy singleL_323(IntTy k1_100_704_944, IntTy x1_101_705_945, + CursorTy t1_102_706_946, CursorTy m_103_707_947); +CursorTy doubleL_324(IntTy k1_71_713_954, IntTy x1_72_714_955, + CursorTy t1_73_715_956, CursorTy m0_74_716_957); +CursorTy rotateL_317(IntTy k_125_722_963, IntTy x_126_723_964, + CursorTy l_127_724_965, CursorTy r_128_725_966); +CursorTy bin_322(IntTy k_110_731_977, IntTy x_111_732_978, + CursorTy l_112_733_979, CursorTy r_113_734_980); +CursorTy singleR_319(IntTy k1_90_735_985, IntTy x1_91_736_986, + CursorTy m_92_737_987, CursorTy t3_93_738_988); +CursorTy doubleR_320(IntTy k1_56_744_995, IntTy x1_57_745_996, + CursorTy m0_58_746_997, CursorTy t4_59_747_998); +CursorTy empty_321(); +CursorTy rotateR_318(IntTy k_115_753_1004, IntTy x_116_754_1005, + CursorTy l_117_755_1006, CursorTy r_118_756_1007); +CursorTy balance_315(IntTy k_135_762_1018, IntTy x_136_763_1019, + CursorTy l_137_764_1020, CursorTy r_138_765_1021); +CursorTy singleton_312(IntTy k_52_766_1042, IntTy x_53_767_1043); +CursorTy insert_314(IntTy kx_43_768_1046, IntTy x_44_769_1047, + CursorTy m_45_770_1048); +CursorTy _copy_without_ptrs_Map_v_313(CursorTy arg_624_776_1058); +CursorTy _copy_Map_v_313(CursorTy arg_613_787_1069); +unsigned char _traverse_Map_v_313(CursorTy arg_635_798_1080); +unsigned char _print_Map_v_313(CursorTy arg_646_806_1088); +CursorTy caseFn_666(IntTy x1_72_667_826_1108, IntTy k1_71_668_827_1109, + CursorTy t1_73_669_828_1110, CursorTy m1_79_670_829_1111, + IntTy k2_77_671_830_1112, IntTy x2_78_672_831_1113, + CursorTy t4_80_673_832_1114); +CursorTy caseFn_674(IntTy x1_57_675_838_1122, IntTy k1_56_676_839_1123, + CursorTy t4_59_677_840_1124, CursorTy m1_65_678_841_1125, + IntTy k2_62_679_842_1126, IntTy x2_63_680_843_1127, + CursorTy t1_64_681_844_1128); +IntTy sumLeft(CursorTy m_34_689_917) +{ + TagTyPacked tag_1143 = *(TagTyPacked *) m_34_689_917; + CursorTy tail_1144 = m_34_689_917 + sizeof(IntTy); + + + switch_1146: + ; + switch (tag_1143) { + + case 0: + { + return 0; + break; + } + + case 1: + { + IntTy wildcard__1_35_690_918 = + ((Int64Int64Int64CursorCursorProd *) tail_1144)->field0; + IntTy wildcard__2_36_691_919 = + ((Int64Int64Int64CursorCursorProd *) tail_1144)->field1; + IntTy v_37_692_920 = + ((Int64Int64Int64CursorCursorProd *) tail_1144)->field2; + CursorTy l_38_693_921 = + ((Int64Int64Int64CursorCursorProd *) tail_1144)->field3; + CursorTy r_39_694_922 = + ((Int64Int64Int64CursorCursorProd *) tail_1144)->field4; + IntTy fltPrm_852_923 = sumLeft(l_38_693_921); + IntTy fltPrm_851_924 = fltPrm_852_923 + v_37_692_920; + IntTy fltPrm_853_925 = sumLeft(r_39_694_922); + IntTy flt_1145 = fltPrm_851_924 + fltPrm_853_925; + + return flt_1145; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1143"); + exit(1); + } + } +} +CursorTy build(IntTy x_40_695_926, IntTy sz_41_696_927, CursorTy m_42_697_928) +{ + BoolTy fltIf_854_929 = sz_41_696_927 == 0; + + if (fltIf_854_929) { + return m_42_697_928; + } else { + IntTy fltPrm_856_930 = sz_41_696_927 / 2; + IntTy fltAppE_855_931 = x_40_695_926 - fltPrm_856_930; + IntTy fltAppE_857_932 = sz_41_696_927 / 2; + IntTy fltPrm_860_933 = sz_41_696_927 / 2; + IntTy fltAppE_859_934 = x_40_695_926 + fltPrm_860_933; + IntTy fltAppE_861_935 = sz_41_696_927 / 2; + CursorTy fltAppE_862_936 = + insert_314(x_40_695_926, x_40_695_926, m_42_697_928); + CursorTy fltAppE_858_937 = + build(fltAppE_859_934, fltAppE_861_935, fltAppE_862_936); + + return build(fltAppE_855_931, fltAppE_857_932, fltAppE_858_937); + } +} +IntTy ratio() +{ + return 2; +} +IntTy delta() +{ + return 4; +} +IntTy size_316(CursorTy m_173_698_938) +{ + TagTyPacked tag_1147 = *(TagTyPacked *) m_173_698_938; + CursorTy tail_1148 = m_173_698_938 + sizeof(IntTy); + + + switch_1149: + ; + switch (tag_1147) { + + case 0: + { + return 0; + break; + } + + case 1: + { + IntTy sz_175_699_939 = + ((Int64Int64Int64CursorCursorProd *) tail_1148)->field0; + IntTy wildcard__18_176_700_940 = + ((Int64Int64Int64CursorCursorProd *) tail_1148)->field1; + IntTy wildcard__19_177_701_941 = + ((Int64Int64Int64CursorCursorProd *) tail_1148)->field2; + CursorTy wildcard__20_178_702_942 = + ((Int64Int64Int64CursorCursorProd *) tail_1148)->field3; + CursorTy wildcard__21_179_703_943 = + ((Int64Int64Int64CursorCursorProd *) tail_1148)->field4; + + return sz_175_699_939; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1147"); + exit(1); + } + } +} +CursorTy singleL_323(IntTy k1_100_704_944, IntTy x1_101_705_945, + CursorTy t1_102_706_946, CursorTy m_103_707_947) +{ + TagTyPacked tag_1150 = *(TagTyPacked *) m_103_707_947; + CursorTy tail_1151 = m_103_707_947 + sizeof(IntTy); + + + switch_1152: + ; + switch (tag_1150) { + + case 1: + { + IntTy wildcard__123_105_708_948 = + ((Int64Int64Int64CursorCursorProd *) tail_1151)->field0; + IntTy k2_106_709_949 = + ((Int64Int64Int64CursorCursorProd *) tail_1151)->field1; + IntTy x2_107_710_950 = + ((Int64Int64Int64CursorCursorProd *) tail_1151)->field2; + CursorTy t2_108_711_951 = + ((Int64Int64Int64CursorCursorProd *) tail_1151)->field3; + CursorTy t3_109_712_952 = + ((Int64Int64Int64CursorCursorProd *) tail_1151)->field4; + CursorTy fltAppE_863_953 = + bin_322(k1_100_704_944, x1_101_705_945, t1_102_706_946, t2_108_711_951); + + return bin_322(k2_106_709_949, x2_107_710_950, fltAppE_863_953, + t3_109_712_952); + break; + } + + case 0: + { + return empty_321(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1150"); + exit(1); + } + } +} +CursorTy doubleL_324(IntTy k1_71_713_954, IntTy x1_72_714_955, + CursorTy t1_73_715_956, CursorTy m0_74_716_957) +{ + TagTyPacked tag_1153 = *(TagTyPacked *) m0_74_716_957; + CursorTy tail_1154 = m0_74_716_957 + sizeof(IntTy); + + + switch_1155: + ; + switch (tag_1153) { + + case 1: + { + IntTy wildcard__143_76_717_958 = + ((Int64Int64Int64CursorCursorProd *) tail_1154)->field0; + IntTy k2_77_718_959 = + ((Int64Int64Int64CursorCursorProd *) tail_1154)->field1; + IntTy x2_78_719_960 = + ((Int64Int64Int64CursorCursorProd *) tail_1154)->field2; + CursorTy m1_79_720_961 = + ((Int64Int64Int64CursorCursorProd *) tail_1154)->field3; + CursorTy t4_80_721_962 = + ((Int64Int64Int64CursorCursorProd *) tail_1154)->field4; + + return caseFn_666(x1_72_714_955, k1_71_713_954, t1_73_715_956, + m1_79_720_961, k2_77_718_959, x2_78_719_960, + t4_80_721_962); + break; + } + + case 0: + { + return empty_321(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1153"); + exit(1); + } + } +} +CursorTy rotateL_317(IntTy k_125_722_963, IntTy x_126_723_964, + CursorTy l_127_724_965, CursorTy r_128_725_966) +{ + TagTyPacked tag_1156 = *(TagTyPacked *) r_128_725_966; + CursorTy tail_1157 = r_128_725_966 + sizeof(IntTy); + + + switch_1158: + ; + switch (tag_1156) { + + case 1: + { + IntTy wildcard__94_130_726_967 = + ((Int64Int64Int64CursorCursorProd *) tail_1157)->field0; + IntTy wildcard__95_131_727_968 = + ((Int64Int64Int64CursorCursorProd *) tail_1157)->field1; + IntTy wildcard__96_132_728_969 = + ((Int64Int64Int64CursorCursorProd *) tail_1157)->field2; + CursorTy ly_133_729_970 = + ((Int64Int64Int64CursorCursorProd *) tail_1157)->field3; + CursorTy ry_134_730_971 = + ((Int64Int64Int64CursorCursorProd *) tail_1157)->field4; + IntTy fltPrm_865_972 = size_316(ly_133_729_970); + IntTy fltPrm_867_973 = ratio(); + IntTy fltPrm_868_974 = size_316(ry_134_730_971); + IntTy fltPrm_866_975 = fltPrm_867_973 * fltPrm_868_974; + BoolTy fltIf_864_976 = fltPrm_865_972 < fltPrm_866_975; + + if (fltIf_864_976) { + return singleL_323(k_125_722_963, x_126_723_964, l_127_724_965, + r_128_725_966); + } else { + return doubleL_324(k_125_722_963, x_126_723_964, l_127_724_965, + r_128_725_966); + } + break; + } + + case 0: + { + return empty_321(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1156"); + exit(1); + } + } +} +CursorTy bin_322(IntTy k_110_731_977, IntTy x_111_732_978, + CursorTy l_112_733_979, CursorTy r_113_734_980) +{ + IntTy fltPrm_871_981 = size_316(l_112_733_979); + IntTy fltPrm_872_982 = size_316(r_113_734_980); + IntTy fltPrm_870_983 = fltPrm_871_981 + fltPrm_872_982; + IntTy fltPkd_869_984 = fltPrm_870_983 + 1; + PtrTy tailift_1159 = ALLOC(sizeof(Int64Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1159)->field0 = 1; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1159)->field1 = + fltPkd_869_984; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1159)->field2 = + k_110_731_977; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1159)->field3 = + x_111_732_978; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1159)->field4 = + l_112_733_979; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1159)->field5 = + r_113_734_980; + return tailift_1159; +} +CursorTy singleR_319(IntTy k1_90_735_985, IntTy x1_91_736_986, + CursorTy m_92_737_987, CursorTy t3_93_738_988) +{ + TagTyPacked tag_1160 = *(TagTyPacked *) m_92_737_987; + CursorTy tail_1161 = m_92_737_987 + sizeof(IntTy); + + + switch_1162: + ; + switch (tag_1160) { + + case 1: + { + IntTy wildcard__133_95_739_989 = + ((Int64Int64Int64CursorCursorProd *) tail_1161)->field0; + IntTy k2_96_740_990 = + ((Int64Int64Int64CursorCursorProd *) tail_1161)->field1; + IntTy x2_97_741_991 = + ((Int64Int64Int64CursorCursorProd *) tail_1161)->field2; + CursorTy t1_98_742_992 = + ((Int64Int64Int64CursorCursorProd *) tail_1161)->field3; + CursorTy t2_99_743_993 = + ((Int64Int64Int64CursorCursorProd *) tail_1161)->field4; + CursorTy fltAppE_873_994 = + bin_322(k1_90_735_985, x1_91_736_986, t2_99_743_993, t3_93_738_988); + + return bin_322(k2_96_740_990, x2_97_741_991, t1_98_742_992, + fltAppE_873_994); + break; + } + + case 0: + { + return empty_321(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1160"); + exit(1); + } + } +} +CursorTy doubleR_320(IntTy k1_56_744_995, IntTy x1_57_745_996, + CursorTy m0_58_746_997, CursorTy t4_59_747_998) +{ + TagTyPacked tag_1163 = *(TagTyPacked *) m0_58_746_997; + CursorTy tail_1164 = m0_58_746_997 + sizeof(IntTy); + + + switch_1165: + ; + switch (tag_1163) { + + case 1: + { + IntTy wildcard__167_61_748_999 = + ((Int64Int64Int64CursorCursorProd *) tail_1164)->field0; + IntTy k2_62_749_1000 = + ((Int64Int64Int64CursorCursorProd *) tail_1164)->field1; + IntTy x2_63_750_1001 = + ((Int64Int64Int64CursorCursorProd *) tail_1164)->field2; + CursorTy t1_64_751_1002 = + ((Int64Int64Int64CursorCursorProd *) tail_1164)->field3; + CursorTy m1_65_752_1003 = + ((Int64Int64Int64CursorCursorProd *) tail_1164)->field4; + + return caseFn_674(x1_57_745_996, k1_56_744_995, t4_59_747_998, + m1_65_752_1003, k2_62_749_1000, x2_63_750_1001, + t1_64_751_1002); + break; + } + + case 0: + { + return empty_321(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1163"); + exit(1); + } + } +} +CursorTy empty_321() +{ + PtrTy tailift_1166 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) tailift_1166)->field0 = 0; + return tailift_1166; +} +CursorTy rotateR_318(IntTy k_115_753_1004, IntTy x_116_754_1005, + CursorTy l_117_755_1006, CursorTy r_118_756_1007) +{ + TagTyPacked tag_1167 = *(TagTyPacked *) l_117_755_1006; + CursorTy tail_1168 = l_117_755_1006 + sizeof(IntTy); + + + switch_1169: + ; + switch (tag_1167) { + + case 1: + { + IntTy wildcard__106_120_757_1008 = + ((Int64Int64Int64CursorCursorProd *) tail_1168)->field0; + IntTy wildcard__107_121_758_1009 = + ((Int64Int64Int64CursorCursorProd *) tail_1168)->field1; + IntTy wildcard__108_122_759_1010 = + ((Int64Int64Int64CursorCursorProd *) tail_1168)->field2; + CursorTy ly_123_760_1011 = + ((Int64Int64Int64CursorCursorProd *) tail_1168)->field3; + CursorTy ry_124_761_1012 = + ((Int64Int64Int64CursorCursorProd *) tail_1168)->field4; + IntTy fltPrm_875_1013 = size_316(ry_124_761_1012); + IntTy fltPrm_877_1014 = ratio(); + IntTy fltPrm_878_1015 = size_316(ly_123_760_1011); + IntTy fltPrm_876_1016 = fltPrm_877_1014 * fltPrm_878_1015; + BoolTy fltIf_874_1017 = fltPrm_875_1013 < fltPrm_876_1016; + + if (fltIf_874_1017) { + return singleR_319(k_115_753_1004, x_116_754_1005, + l_117_755_1006, r_118_756_1007); + } else { + return doubleR_320(k_115_753_1004, x_116_754_1005, + l_117_755_1006, r_118_756_1007); + } + break; + } + + case 0: + { + return empty_321(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1167"); + exit(1); + } + } +} +CursorTy balance_315(IntTy k_135_762_1018, IntTy x_136_763_1019, + CursorTy l_137_764_1020, CursorTy r_138_765_1021) +{ + IntTy fltPrm_881_1022 = size_316(l_137_764_1020); + IntTy fltPrm_882_1023 = size_316(r_138_765_1021); + IntTy fltPrm_880_1024 = fltPrm_881_1022 + fltPrm_882_1023; + BoolTy fltIf_879_1025 = fltPrm_880_1024 <= 1; + + if (fltIf_879_1025) { + IntTy fltPrm_884_1026 = size_316(l_137_764_1020); + IntTy fltPrm_885_1027 = size_316(r_138_765_1021); + IntTy fltPkd_883_1028 = fltPrm_884_1026 + fltPrm_885_1027; + PtrTy tailift_1170 = + ALLOC(sizeof(Int64Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1170)->field0 = 1; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1170)->field1 = + fltPkd_883_1028; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1170)->field2 = + k_135_762_1018; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1170)->field3 = + x_136_763_1019; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1170)->field4 = + l_137_764_1020; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1170)->field5 = + r_138_765_1021; + return tailift_1170; + } else { + IntTy fltPrm_887_1029 = size_316(r_138_765_1021); + IntTy fltPrm_889_1030 = delta(); + IntTy fltPrm_890_1031 = size_316(l_137_764_1020); + IntTy fltPrm_888_1032 = fltPrm_889_1030 * fltPrm_890_1031; + BoolTy fltIf_886_1033 = fltPrm_887_1029 >= fltPrm_888_1032; + + if (fltIf_886_1033) { + return rotateL_317(k_135_762_1018, x_136_763_1019, l_137_764_1020, + r_138_765_1021); + } else { + IntTy fltPrm_892_1034 = size_316(l_137_764_1020); + IntTy fltPrm_894_1035 = delta(); + IntTy fltPrm_895_1036 = size_316(r_138_765_1021); + IntTy fltPrm_893_1037 = fltPrm_894_1035 * fltPrm_895_1036; + BoolTy fltIf_891_1038 = fltPrm_892_1034 >= fltPrm_893_1037; + + if (fltIf_891_1038) { + return rotateR_318(k_135_762_1018, x_136_763_1019, + l_137_764_1020, r_138_765_1021); + } else { + IntTy fltPrm_897_1039 = size_316(l_137_764_1020); + IntTy fltPrm_898_1040 = size_316(r_138_765_1021); + IntTy fltPkd_896_1041 = fltPrm_897_1039 + fltPrm_898_1040; + PtrTy tailift_1171 = + ALLOC(sizeof(Int64Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1171)->field0 = + 1; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1171)->field1 = + fltPkd_896_1041; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1171)->field2 = + k_135_762_1018; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1171)->field3 = + x_136_763_1019; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1171)->field4 = + l_137_764_1020; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1171)->field5 = + r_138_765_1021; + return tailift_1171; + } + } + } +} +CursorTy singleton_312(IntTy k_52_766_1042, IntTy x_53_767_1043) +{ + PtrTy fltPkd_899_1044 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_899_1044)->field0 = 0; + + PtrTy fltPkd_900_1045 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_900_1045)->field0 = 0; + + PtrTy tailift_1172 = ALLOC(sizeof(Int64Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1172)->field0 = 1; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1172)->field1 = 1; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1172)->field2 = + k_52_766_1042; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1172)->field3 = + x_53_767_1043; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1172)->field4 = + fltPkd_899_1044; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1172)->field5 = + fltPkd_900_1045; + return tailift_1172; +} +CursorTy insert_314(IntTy kx_43_768_1046, IntTy x_44_769_1047, + CursorTy m_45_770_1048) +{ + TagTyPacked tag_1173 = *(TagTyPacked *) m_45_770_1048; + CursorTy tail_1174 = m_45_770_1048 + sizeof(IntTy); + + + switch_1176: + ; + switch (tag_1173) { + + case 0: + { + return singleton_312(kx_43_768_1046, x_44_769_1047); + break; + } + + case 1: + { + IntTy sz_47_771_1049 = + ((Int64Int64Int64CursorCursorProd *) tail_1174)->field0; + IntTy k_48_772_1050 = + ((Int64Int64Int64CursorCursorProd *) tail_1174)->field1; + IntTy v_49_773_1051 = + ((Int64Int64Int64CursorCursorProd *) tail_1174)->field2; + CursorTy l_50_774_1052 = + ((Int64Int64Int64CursorCursorProd *) tail_1174)->field3; + CursorTy r_51_775_1053 = + ((Int64Int64Int64CursorCursorProd *) tail_1174)->field4; + BoolTy fltIf_901_1054 = kx_43_768_1046 == k_48_772_1050; + + if (fltIf_901_1054) { + PtrTy tailift_1175 = + ALLOC(sizeof(Int64Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1175)->field0 = + 1; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1175)->field1 = + sz_47_771_1049; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1175)->field2 = + k_48_772_1050; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1175)->field3 = + x_44_769_1047; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1175)->field4 = + l_50_774_1052; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1175)->field5 = + r_51_775_1053; + return tailift_1175; + } else { + BoolTy fltIf_902_1055 = kx_43_768_1046 <= k_48_772_1050; + + if (fltIf_902_1055) { + CursorTy fltAppE_903_1056 = + insert_314(kx_43_768_1046, x_44_769_1047, l_50_774_1052); + + return balance_315(k_48_772_1050, v_49_773_1051, + fltAppE_903_1056, r_51_775_1053); + } else { + CursorTy fltAppE_904_1057 = + insert_314(kx_43_768_1046, x_44_769_1047, r_51_775_1053); + + return balance_315(k_48_772_1050, v_49_773_1051, + l_50_774_1052, fltAppE_904_1057); + } + } + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1173"); + exit(1); + } + } +} +CursorTy _copy_without_ptrs_Map_v_313(CursorTy arg_624_776_1058) +{ + TagTyPacked tag_1177 = *(TagTyPacked *) arg_624_776_1058; + CursorTy tail_1178 = arg_624_776_1058 + sizeof(IntTy); + + + switch_1181: + ; + switch (tag_1177) { + + case 0: + { + PtrTy tailift_1179 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) tailift_1179)->field0 = 0; + return tailift_1179; + break; + } + + case 1: + { + IntTy x_625_777_1059 = + ((Int64Int64Int64CursorCursorProd *) tail_1178)->field0; + IntTy x_626_778_1060 = + ((Int64Int64Int64CursorCursorProd *) tail_1178)->field1; + IntTy x_627_779_1061 = + ((Int64Int64Int64CursorCursorProd *) tail_1178)->field2; + CursorTy x_628_780_1062 = + ((Int64Int64Int64CursorCursorProd *) tail_1178)->field3; + CursorTy x_629_781_1063 = + ((Int64Int64Int64CursorCursorProd *) tail_1178)->field4; + CursorTy y_633_785_1067 = + _copy_without_ptrs_Map_v_313(x_628_780_1062); + CursorTy y_634_786_1068 = + _copy_without_ptrs_Map_v_313(x_629_781_1063); + PtrTy tailift_1180 = + ALLOC(sizeof(Int64Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1180)->field0 = 1; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1180)->field1 = + x_625_777_1059; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1180)->field2 = + x_626_778_1060; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1180)->field3 = + x_627_779_1061; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1180)->field4 = + y_633_785_1067; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1180)->field5 = + y_634_786_1068; + return tailift_1180; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1177"); + exit(1); + } + } +} +CursorTy _copy_Map_v_313(CursorTy arg_613_787_1069) +{ + TagTyPacked tag_1182 = *(TagTyPacked *) arg_613_787_1069; + CursorTy tail_1183 = arg_613_787_1069 + sizeof(IntTy); + + + switch_1186: + ; + switch (tag_1182) { + + case 0: + { + PtrTy tailift_1184 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) tailift_1184)->field0 = 0; + return tailift_1184; + break; + } + + case 1: + { + IntTy x_614_788_1070 = + ((Int64Int64Int64CursorCursorProd *) tail_1183)->field0; + IntTy x_615_789_1071 = + ((Int64Int64Int64CursorCursorProd *) tail_1183)->field1; + IntTy x_616_790_1072 = + ((Int64Int64Int64CursorCursorProd *) tail_1183)->field2; + CursorTy x_617_791_1073 = + ((Int64Int64Int64CursorCursorProd *) tail_1183)->field3; + CursorTy x_618_792_1074 = + ((Int64Int64Int64CursorCursorProd *) tail_1183)->field4; + CursorTy y_622_796_1078 = _copy_Map_v_313(x_617_791_1073); + CursorTy y_623_797_1079 = _copy_Map_v_313(x_618_792_1074); + PtrTy tailift_1185 = + ALLOC(sizeof(Int64Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1185)->field0 = 1; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1185)->field1 = + x_614_788_1070; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1185)->field2 = + x_615_789_1071; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1185)->field3 = + x_616_790_1072; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1185)->field4 = + y_622_796_1078; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1185)->field5 = + y_623_797_1079; + return tailift_1185; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1182"); + exit(1); + } + } +} +unsigned char _traverse_Map_v_313(CursorTy arg_635_798_1080) +{ + TagTyPacked tag_1187 = *(TagTyPacked *) arg_635_798_1080; + CursorTy tail_1188 = arg_635_798_1080 + sizeof(IntTy); + + + switch_1189: + ; + switch (tag_1187) { + + case 0: + { + return 0; + break; + } + + case 1: + { + IntTy x_636_799_1081 = + ((Int64Int64Int64CursorCursorProd *) tail_1188)->field0; + IntTy x_637_800_1082 = + ((Int64Int64Int64CursorCursorProd *) tail_1188)->field1; + IntTy x_638_801_1083 = + ((Int64Int64Int64CursorCursorProd *) tail_1188)->field2; + CursorTy x_639_802_1084 = + ((Int64Int64Int64CursorCursorProd *) tail_1188)->field3; + CursorTy x_640_803_1085 = + ((Int64Int64Int64CursorCursorProd *) tail_1188)->field4; + unsigned char y_644_804_1086 = _traverse_Map_v_313(x_639_802_1084); + unsigned char y_645_805_1087 = _traverse_Map_v_313(x_640_803_1085); + + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1187"); + exit(1); + } + } +} +unsigned char _print_Map_v_313(CursorTy arg_646_806_1088) +{ + TagTyPacked tag_1190 = *(TagTyPacked *) arg_646_806_1088; + CursorTy tail_1191 = arg_646_806_1088 + sizeof(IntTy); + + + switch_1192: + ; + switch (tag_1190) { + + case 0: + { + unsigned char wildcard_647_807_1089 = print_symbol(1139); + unsigned char wildcard_648_808_1090 = print_symbol(1138); + + return 0; + break; + } + + case 1: + { + IntTy x_649_809_1091 = + ((Int64Int64Int64CursorCursorProd *) tail_1191)->field0; + IntTy x_650_810_1092 = + ((Int64Int64Int64CursorCursorProd *) tail_1191)->field1; + IntTy x_651_811_1093 = + ((Int64Int64Int64CursorCursorProd *) tail_1191)->field2; + CursorTy x_652_812_1094 = + ((Int64Int64Int64CursorCursorProd *) tail_1191)->field3; + CursorTy x_653_813_1095 = + ((Int64Int64Int64CursorCursorProd *) tail_1191)->field4; + unsigned char wildcard_659_814_1096 = print_symbol(1140); + unsigned char wildcard_665_815_1097 = print_symbol(1141); + unsigned char y_654_816_1098 = printf("%lld", x_649_809_1091); + unsigned char wildcard_664_817_1099 = print_symbol(1141); + unsigned char y_655_818_1100 = printf("%lld", x_650_810_1092); + unsigned char wildcard_663_819_1101 = print_symbol(1141); + unsigned char y_656_820_1102 = printf("%lld", x_651_811_1093); + unsigned char wildcard_662_821_1103 = print_symbol(1141); + unsigned char y_657_822_1104 = _print_Map_v_313(x_652_812_1094); + unsigned char wildcard_661_823_1105 = print_symbol(1141); + unsigned char y_658_824_1106 = _print_Map_v_313(x_653_813_1095); + unsigned char wildcard_660_825_1107 = print_symbol(1138); + + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1190"); + exit(1); + } + } +} +CursorTy caseFn_666(IntTy x1_72_667_826_1108, IntTy k1_71_668_827_1109, + CursorTy t1_73_669_828_1110, CursorTy m1_79_670_829_1111, + IntTy k2_77_671_830_1112, IntTy x2_78_672_831_1113, + CursorTy t4_80_673_832_1114) +{ + TagTyPacked tag_1193 = *(TagTyPacked *) m1_79_670_829_1111; + CursorTy tail_1194 = m1_79_670_829_1111 + sizeof(IntTy); + + + switch_1195: + ; + switch (tag_1193) { + + case 1: + { + IntTy wildcard__144_81_833_1115 = + ((Int64Int64Int64CursorCursorProd *) tail_1194)->field0; + IntTy k3_82_834_1116 = + ((Int64Int64Int64CursorCursorProd *) tail_1194)->field1; + IntTy x3_83_835_1117 = + ((Int64Int64Int64CursorCursorProd *) tail_1194)->field2; + CursorTy t2_84_836_1118 = + ((Int64Int64Int64CursorCursorProd *) tail_1194)->field3; + CursorTy t3_85_837_1119 = + ((Int64Int64Int64CursorCursorProd *) tail_1194)->field4; + CursorTy fltAppE_905_1120 = + bin_322(k1_71_668_827_1109, x1_72_667_826_1108, t1_73_669_828_1110, t2_84_836_1118); + CursorTy fltAppE_906_1121 = + bin_322(k2_77_671_830_1112, x2_78_672_831_1113, t3_85_837_1119, t4_80_673_832_1114); + + return bin_322(k3_82_834_1116, x3_83_835_1117, fltAppE_905_1120, + fltAppE_906_1121); + break; + } + + case 0: + { + return empty_321(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1193"); + exit(1); + } + } +} +CursorTy caseFn_674(IntTy x1_57_675_838_1122, IntTy k1_56_676_839_1123, + CursorTy t4_59_677_840_1124, CursorTy m1_65_678_841_1125, + IntTy k2_62_679_842_1126, IntTy x2_63_680_843_1127, + CursorTy t1_64_681_844_1128) +{ + TagTyPacked tag_1196 = *(TagTyPacked *) m1_65_678_841_1125; + CursorTy tail_1197 = m1_65_678_841_1125 + sizeof(IntTy); + + + switch_1198: + ; + switch (tag_1196) { + + case 1: + { + IntTy wildcard__168_66_845_1129 = + ((Int64Int64Int64CursorCursorProd *) tail_1197)->field0; + IntTy k3_67_846_1130 = + ((Int64Int64Int64CursorCursorProd *) tail_1197)->field1; + IntTy x3_68_847_1131 = + ((Int64Int64Int64CursorCursorProd *) tail_1197)->field2; + CursorTy t2_69_848_1132 = + ((Int64Int64Int64CursorCursorProd *) tail_1197)->field3; + CursorTy t3_70_849_1133 = + ((Int64Int64Int64CursorCursorProd *) tail_1197)->field4; + CursorTy fltAppE_907_1134 = + bin_322(k2_62_679_842_1126, x2_63_680_843_1127, t1_64_681_844_1128, t2_69_848_1132); + CursorTy fltAppE_908_1135 = + bin_322(k1_56_676_839_1123, x1_57_675_838_1122, t3_70_849_1133, t4_59_677_840_1124); + + return bin_322(k3_67_846_1130, x3_68_847_1131, fltAppE_907_1134, + fltAppE_908_1135); + break; + } + + case 0: + { + return empty_321(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1196"); + exit(1); + } + } +} +int __main_expr() +{ + add_symbol(1138, ")"); + add_symbol(1139, "(Tip_v_313"); + add_symbol(1140, "(Bin_v_313"); + add_symbol(1141, " "); + add_symbol(1142, "\n"); + + CursorTy fltAppE_850_909 = singleton_312(0, 0); + CursorTy m_25_682_910 = build(0, 10, fltAppE_850_909); + IntTy timed_1136; + VectorTy *times_3 = vector_alloc(global_iters_param, sizeof(double)); + struct timespec begin_timed_1136; + struct timespec end_timed_1136; + + for (long long iters_timed_1136 = 0; iters_timed_1136 < global_iters_param; + iters_timed_1136++) { + if (iters_timed_1136 != global_iters_param - 1) + save_alloc_state(); + clock_gettime(CLOCK_MONOTONIC_RAW, &begin_timed_1136); + + IntTy timed_1136hack = sumLeft(m_25_682_910); + + timed_1136 = timed_1136hack; + clock_gettime(CLOCK_MONOTONIC_RAW, &end_timed_1136); + if (iters_timed_1136 != global_iters_param - 1) + restore_alloc_state(); + + double itertime_0 = difftimespecs(&begin_timed_1136, &end_timed_1136); + + vector_inplace_update(times_3, iters_timed_1136, &itertime_0); + } + vector_inplace_sort(times_3, compare_doubles); + + double *tmp_4 = (double *) vector_nth(times_3, global_iters_param / 2); + double selftimed_2 = *tmp_4; + double batchtime_1 = sum_timing_array(times_3); + + print_timing_array(times_3); + printf("ITERS: %lld\n", global_iters_param); + printf("SIZE: %lld\n", global_size_param); + printf("BATCHTIME: %e\n", batchtime_1); + printf("SELFTIMED: %e\n", selftimed_2); + + unsigned char wildcard__19_27_684_912 = printf("%lld", timed_1136); + unsigned char wildcard__17_28_685_913 = print_symbol(1142); + IntTy timed_1137; + VectorTy *times_8 = vector_alloc(global_iters_param, sizeof(double)); + struct timespec begin_timed_1137; + struct timespec end_timed_1137; + + for (long long iters_timed_1137 = 0; iters_timed_1137 < global_iters_param; + iters_timed_1137++) { + if (iters_timed_1137 != global_iters_param - 1) + save_alloc_state(); + clock_gettime(CLOCK_MONOTONIC_RAW, &begin_timed_1137); + + IntTy timed_1137hack = sumLeft(m_25_682_910); + + timed_1137 = timed_1137hack; + clock_gettime(CLOCK_MONOTONIC_RAW, &end_timed_1137); + if (iters_timed_1137 != global_iters_param - 1) + restore_alloc_state(); + + double itertime_5 = difftimespecs(&begin_timed_1137, &end_timed_1137); + + vector_inplace_update(times_8, iters_timed_1137, &itertime_5); + } + vector_inplace_sort(times_8, compare_doubles); + + double *tmp_9 = (double *) vector_nth(times_8, global_iters_param / 2); + double selftimed_7 = *tmp_9; + double batchtime_6 = sum_timing_array(times_8); + + print_timing_array(times_8); + printf("ITERS: %lld\n", global_iters_param); + printf("SIZE: %lld\n", global_size_param); + printf("BATCHTIME: %e\n", batchtime_6); + printf("SELFTIMED: %e\n", selftimed_7); + + unsigned char wildcard__13_30_687_915 = printf("%lld", timed_1137); + unsigned char wildcard__11_31_688_916 = print_symbol(1142); + + printf("'#()"); + printf("\n"); + free_symtable(); + return 0; +} \ No newline at end of file diff --git a/benchmarks/Layouts/Left.hs b/benchmarks/Layouts/Left.hs new file mode 100644 index 000000000..f332e78dc --- /dev/null +++ b/benchmarks/Layouts/Left.hs @@ -0,0 +1,28 @@ + +module Left where +import Common +import Map + +sumLeft :: Map Int -> Int +sumLeft m = + case m of + Tip -> 0 + Bin _ _ v l r -> sumLeft(l) + v + sumLeft(r) + + +build :: Int -> Int -> Map Int -> Map Int +build x sz m = + if (sz == 0) then m + else (build (x + sz/2) (sz/2) (build (x - sz/2) (sz/2) (insert x x m))) + +gibbon_main = + let m = (build 0 (singleton 0 0)) + --_ = printsym (quote "SUM RIGHT: ") + s0 = iterate (sumLeft m) + _ = printint (s0) + _ = printsym (quote "\n") + --_ = printsym (quote "SUM LEFT: ") + s1 = iterate (sumLeft m) + _ = printint (s1) + _ = printsym (quote "\n") + in () \ No newline at end of file diff --git a/benchmarks/Layouts/Left.out b/benchmarks/Layouts/Left.out new file mode 100644 index 000000000..f3a68828c --- /dev/null +++ b/benchmarks/Layouts/Left.out @@ -0,0 +1,13 @@ +TIMES: [0.000019] +ITERS: 1 +SIZE: 1 +BATCHTIME: 1.946600e-05 +SELFTIMED: 1.946600e-05 +0 +TIMES: [0.000014] +ITERS: 1 +SIZE: 1 +BATCHTIME: 1.414700e-05 +SELFTIMED: 1.414700e-05 +0 +'#() diff --git a/benchmarks/Layouts/LeftAndRight.c b/benchmarks/Layouts/LeftAndRight.c new file mode 100644 index 000000000..aed00bfb6 --- /dev/null +++ b/benchmarks/Layouts/LeftAndRight.c @@ -0,0 +1,2492 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// #include +#ifdef _WIN64 +#include +#endif +#include +#include +#include // For va_start etc +#include +#include +#include +#include +#ifdef _POINTER +#include +#endif +#ifdef _PARALLEL +#include +#include +#endif + +#define KB 1024lu +#define MB (KB * 1000lu) +#define GB (MB * 1000lu) + +#define REDIRECTION_TAG 255 +#define INDIRECTION_TAG 254 + +// Initial size of BigInfinite buffers +static long long global_init_biginf_buf_size = (4 * GB); + +// Initial size of Infinite buffers +static long long global_init_inf_buf_size = 1 * KB; + +// Maximum size of a chunk, see GitHub #110. +static long long global_inf_buf_max_chunk_size = 1 * GB; + +static long long global_size_param = 1; +static long long global_iters_param = 1; + +static char* global_benchfile_param = NULL; +static char* global_arrayfile_param = NULL; +// Number of lines in the arrayfile +static long long global_arrayfile_length_param = -1; + +// Sequential for now: +static const int num_workers = 1; + +// Count the number of regions allocated. +static long long global_region_count = 0; +static bool global_region_count_flag = false; + +#ifdef _PARALLEL +static inline void bump_global_region_count() { + __atomic_add_fetch(&global_region_count, 1, __ATOMIC_SEQ_CST); + return; +} +#else +static inline void bump_global_region_count() { + global_region_count++; + return; +} +#endif + +static inline void print_global_region_count() { + printf("REGION_COUNT: %lld\n", global_region_count); + return; +} + +#define REDIRECTION_NODE_SIZE 9 +#define MAX(a,b) (((a)>(b))?(a):(b)) +#define MIN(a,b) (((a)<(b))?(a):(b)) + +// https://www.cprogramming.com/snippets/source-code/find-the-number-of-cpu-cores-for-windows-mac-or-linux +static int get_num_processors() { +#ifdef _WIN64 + SYSTEM_INFO sysinfo; + GetSystemInfo(&sysinfo); + return sysinfo.dwNumberOfProcessors; +#else + return sysconf(_SC_NPROCESSORS_ONLN); +#endif +} + +// Requires -std=gnu11 +int dbgprintf(const char *format, ...) { + int code = 0; + va_list args; + va_start(args, format); +#ifdef _DEBUG + code = vprintf(format, args); +#endif + va_end(args); + return code; +} + + +// ----------------------------------------------------------------------------- +// Allocators +// ----------------------------------------------------------------------------- + + +// ------------------------------------- +// Bump allocation for linked-lists +// ------------------------------------- + + +#ifdef _BUMPALLOC +// #define _DEBUG +#warning "Using bump allocator." + +__thread char* bumpalloc_heap_ptr = (char*)NULL; +__thread char* bumpalloc_heap_ptr_end = (char*)NULL; + +char* saved_heap_ptr_stack[100]; +int num_saved_heap_ptr = 0; + +// For simplicity just use a single large slab: +static inline void INITBUMPALLOC() { + bumpalloc_heap_ptr = (char*)malloc(global_init_biginf_buf_size); + bumpalloc_heap_ptr_end = bumpalloc_heap_ptr + global_init_biginf_buf_size; +#ifdef _DEBUG + printf("Arena size for bump alloc: %lld\n", global_init_biginf_buf_size); + printf("BUMPALLOC/INITBUMPALLOC DONE: heap_ptr = %p\n", bumpalloc_heap_ptr); +#endif +} + +static inline void* BUMPALLOC(long long n) { + if (! bumpalloc_heap_ptr) { + INITBUMPALLOC(); + } + if (bumpalloc_heap_ptr + n < bumpalloc_heap_ptr_end) { + char* old= bumpalloc_heap_ptr; + bumpalloc_heap_ptr += n; + return old; + } else { + fprintf(stderr, "Warning: bump allocator ran out of memory."); + exit(1); + } +} + +// Snapshot the current heap pointer value across all threads. +void save_alloc_state() { + dbgprintf("Saving(%p): pos %d", heap_ptr, num_saved_heap_ptr); + saved_heap_ptr_stack[num_saved_heap_ptr] = heap_ptr; + num_saved_heap_ptr++; + dbgprintf("\n"); +} + +void restore_alloc_state() { + if(num_saved_heap_ptr <= 0) { + fprintf(stderr, "Bad call to restore_alloc_state! Saved stack empty!\ne"); + exit(1); + } + num_saved_heap_ptr--; + dbgprintf("Restoring(%p): pos %d, discarding %p", + saved_heap_ptr_stack[num_saved_heap_ptr], num_saved_heap_ptr, bumpalloc_heap_ptr); + bumpalloc_heap_ptr = saved_heap_ptr_stack[num_saved_heap_ptr]; +} + + +#else +// Regular malloc mode: +void INITBUMPALLOC() {} +void save_alloc_state() {} +void restore_alloc_state() {} + +#define BUMPALLOC(n) malloc(n) + +#endif // BUMPALLOC + + +// ------------------------------------- +// ALLOC and ALLOC_PACKED macros +// ------------------------------------- + + +/* + +If parallelism is enabled, we always use a malloc based allocator +since Boehm GC is not thread-safe in its default configuration. It can be +made thread-safe by building it with appropriate flags, but we don't do that. +Presently, all parallel pointer-based programs will leak memory. + +*/ + +#ifdef _PARALLEL +#define ALLOC(n) malloc(n) +#define ALLOC_PACKED_BIG(n) malloc(n) +char *ALLOC_COUNTED(size_t size) { + bump_global_region_count(); + return ALLOC(size); +} +#else + #ifdef _POINTER +#define ALLOC(n) GC_MALLOC(n) +#define ALLOC_PACKED_BIG(n) GC_MALLOC(n) +char *ALLOC_COUNTED(size_t size) { + bump_global_region_count(); + return GC_MALLOC(size); +} + #else +#define ALLOC(n) malloc(n) +#define ALLOC_PACKED_BIG(n) malloc(n) +char *ALLOC_COUNTED(size_t size) { + bump_global_region_count(); + return ALLOC(size); +} + #endif // _POINTER +#endif // _PARALLEL + + +// Could try alloca() here. Better yet, we could keep our own, +// separate stack and insert our own code to restore the pointer +// before any function that (may have) called ALLOC_SCOPED returns. + +// #define ALLOC_SCOPED() alloca(1024) +#define ALLOC_SCOPED(n) alloca(n) +// #define ALLOC_SCOPED() alloc_scoped() + +// Stack allocation is either too small or blows our stack. +// We need a way to make a giant stack if we want to use alloca. +// #define ALLOC_SCOPED() ALLOC(global_init_biginf_buf_size) + +// Our global pointer. No parallelism. +// static char* stack_scoped_region; +// char* alloc_scoped() { return stack_scoped_region; } + + + +// ------------------------------------- +// Basic types +// ------------------------------------- + +// Must be consistent with sizeOfTy defined in Gibbon.Language.Syntax. + +typedef unsigned char TagTyPacked; +typedef unsigned char TagTyBoxed; +typedef long long IntTy; +typedef char CharTy; +typedef float FloatTy; +typedef unsigned long long SymTy; +typedef bool BoolTy; +typedef char* PtrTy; +typedef char* CursorTy; + +// ------------------------------------- +// Arenas and dictionaries +// ------------------------------------- + +typedef struct mem_arena { + int ind; + char* mem; // TODO(vollmerm): make this a list of chunks? + void* reflist; +} mem_arena_t; + +typedef mem_arena_t* ArenaTy; + +ArenaTy alloc_arena() { + ArenaTy ar = ALLOC(sizeof(mem_arena_t)); + ar->ind = 0; + ar->mem = malloc(global_inf_buf_max_chunk_size); + ar->reflist = 0; + return ar; +} + +void free_arena(ArenaTy ar) { + free(ar->mem); + // TODO(vollmerm): free everything in ar->reflist + free(ar); +} + +CursorTy extend_arena(ArenaTy ar, int size) { + CursorTy ret = ar->mem + ar->ind; + ar->ind += size; + return ret; +} + +typedef struct dict_item { + struct dict_item * next; + int key; + void * ptrval; +} dict_item_t; + +dict_item_t * dict_alloc(ArenaTy ar) { + return (dict_item_t *) extend_arena(ar, sizeof(dict_item_t)); // ALLOC(sizeof(dict_item_t)); +} + +dict_item_t *dict_insert_ptr(ArenaTy ar, dict_item_t *ptr, SymTy key, PtrTy val) { + dict_item_t *ret = dict_alloc(ar); + ret->key = key; + ret->ptrval = val; + ret->next = ptr; + return ret; +} + +PtrTy dict_lookup_ptr(dict_item_t *ptr, SymTy key) { + while (ptr != 0) { + if (ptr->key == key) { + return ptr->ptrval; + } else { + ptr = ptr->next; + } + } + printf("Error, key %lld not found!\n",key); + exit(1); +} + +// ------------------------------------- +// Sets +// ------------------------------------- + + +struct set_elem { + int val; + UT_hash_handle hh; +}; + +typedef struct set_elem* SymSetTy; + +SymSetTy empty_set() { + return NULL; +} + +SymSetTy insert_set(SymSetTy set, int sym) { + SymSetTy s; + HASH_FIND_INT(set, &sym, s); /* sym already in the hash? */ + if (s==NULL) { + s = malloc(sizeof(struct set_elem)); + s->val = sym; + HASH_ADD_INT(set,val,s); + } + return set; +} + +BoolTy contains_set(SymSetTy set, int sym) { + SymSetTy s; + HASH_FIND_INT(set, &sym, s); + return (s!=NULL); +} + +// ------------------------------------- +// Sym Hash +// ------------------------------------- + +struct sym_hash_elem { + int key; + int val; + UT_hash_handle hh; +}; + +typedef struct sym_hash_elem* SymHashTy; + +typedef struct sym_hash_elem* IntHashTy; + +SymHashTy empty_hash() { + return NULL; +} + +SymHashTy insert_hash(SymHashTy hash, int k, int v) { + SymHashTy s; + // NOTE: not checking for duplicates! + // s = malloc(sizeof(struct sym_hash_elem)); + s = ALLOC(sizeof(struct sym_hash_elem)); + s->val = v; + s->key = k; + HASH_ADD_INT(hash,key,s); + + return hash; +} + +IntTy lookup_hash(SymHashTy hash, int k) { + SymHashTy s; + HASH_FIND_INT(hash,&k,s); + if (s==NULL) { + return k; // NOTE: return original key if val not found + // TODO(vollmerm): come up with something better to do here + } else { + return s->val; + } +} + +BoolTy contains_hash(SymHashTy hash, int sym) { + SymHashTy s; + HASH_FIND_INT(hash,&sym,s); + return (s!=NULL); +} + +// ------------------------------------- +// Helpers +// ------------------------------------- + +char* read_benchfile_param() { + if (global_benchfile_param == NULL) { + fprintf(stderr, "read_benchfile_param: benchmark input file was not set! Set using --bench-input.\n"); + exit(1); + } else + return global_benchfile_param; +} + +char* read_arrayfile_param() { + if (global_arrayfile_param == NULL) { + fprintf(stderr, "read_arrayfile_param: array input file was not set! Set using --array-input.\n"); + exit(1); + } else + return global_arrayfile_param; +} + +IntTy read_arrayfile_length_param() { + if (global_arrayfile_length_param == -1) { + fprintf(stderr, "read_arrayfile_length_param: array input file length was not set! Set using --array-input-length.\n"); + exit(1); + } else + return global_arrayfile_length_param; +} + + +// fun fact: __ prefix is actually reserved and this is an undefined behavior. +// These functions must be provided by the code generator. +int __main_expr(); + + +void show_usage(char** argv) +{ + printf("\n"); + printf("This binary was generated by the Gibbon compiler.\n"); + printf("\n"); + printf("Usage: %s [OPTS] [size] [iters]\n", argv[0]); + + printf("\n"); + printf("Options:\n"); + printf(" --buffer-size Set the buffer size (default %lld).\n", global_init_biginf_buf_size); + printf(" --bench-input Set the input file read for benchmarking. Applies only\n"); + printf(" IF the program was *compiled* with --bench-fun. \n"); + return; +} + +double avg(const double* arr, int n) +{ + double sum = 0.0; + for(int i=0; itv_sec - t0->tv_sec) + + ((double)(t1->tv_nsec - t0->tv_nsec) / 1000000000.0); +} + +int compare_doubles(const void *a, const void *b) +{ + const double *da = (const double *) a; + const double *db = (const double *) b; + return (*da > *db) - (*da < *db); +} + +// Exponentiation +IntTy expll(IntTy base, IntTy pow) { + if (base == 2) { + return (1 << pow); + } else { + IntTy i, result = 1; + for (i = 0; i < pow; i++) + result *= base; + return result; + } + } + +// ------------------------------------- +// Symbol table +// ------------------------------------- + +#define global_max_symbol_len 256 + +// Invariant: should always be equal to max(sym_table_keys) +static SymTy global_gensym_counter = 0; + +// Its value is updated by the flags parser. +static char *global_bench_prog_param; + +static SymTy newline_symbol = -1; +static SymTy space_symbol = -1; +static SymTy comma_symbol = -1; +static SymTy leftparen_symbol = -1; +static SymTy rightparen_symbol = -1; + +typedef struct SymTable_elem { + SymTy idx; /* key */ + char value[global_max_symbol_len]; + UT_hash_handle hh; /* makes this structure hashable */ +} SymTable_elem; + +// important! initialize to NULL +SymTable_elem *global_sym_table = NULL; + +void add_symbol(SymTy idx, char *value) { + struct SymTable_elem *s; + s = ALLOC(sizeof(struct SymTable_elem)); + s->idx = idx; + strcpy(s->value, value); + HASH_ADD(hh, global_sym_table, idx, sizeof(IntTy), s); + if (idx > global_gensym_counter) { + global_gensym_counter = idx; + } +} + +void set_newline(SymTy idx) { + newline_symbol = idx; + add_symbol(idx,"NEWLINE"); +} + +void set_space(SymTy idx) { + space_symbol = idx; + add_symbol(idx,"SPACE"); +} + +void set_comma(SymTy idx) { + comma_symbol = idx; + add_symbol(idx,"COMMA"); +} + +void set_leftparen(SymTy idx) { + leftparen_symbol = idx; + add_symbol(idx,"LEFTPAREN"); +} + +void set_rightparen(SymTy idx) { + rightparen_symbol = idx; + add_symbol(idx,"RIGHTPAREN"); +} + +IntTy print_symbol(SymTy idx) { + if (idx == comma_symbol) { + return printf(","); + } else if (idx == newline_symbol) { + return printf("\n"); + } else if (idx == space_symbol) { + return printf(" "); + } else if (idx == leftparen_symbol) { + return printf("("); + } else if (idx == rightparen_symbol) { + return printf(")"); + } else { + struct SymTable_elem *s; + HASH_FIND(hh, global_sym_table, &idx, sizeof(SymTy), s); + if (s == NULL) { + return printf("%lld", idx); + } else { + return printf("%s", s->value); + } + + } +} + +#ifdef _PARALLEL +SymTy gensym() { + SymTy idx = __atomic_add_fetch(&global_gensym_counter, 1, __ATOMIC_SEQ_CST); + return idx; +} +#else +SymTy gensym() { + global_gensym_counter += 1; + SymTy idx = global_gensym_counter; + return idx; +} +#endif + +void free_symtable() { + struct SymTable_elem *elt, *tmp; + HASH_ITER(hh, global_sym_table, elt, tmp) { + HASH_DEL(global_sym_table,elt); + } + free(elt); + free(tmp); +} + +/* + +---------------------------------------- +Garbage collection +---------------------------------------- + + Gibbon has "growing regions" i.e each logical region is backed by a doubly linked-list + of smaller chunks which grows as required. In addition to actual data, each chunk + stores some additional metadata (RegionFooter) to chain the chunks together in a list + and for garbage collection. The footer: + + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + serialized data | rf_reg_metadata_ptr | rf_seq_no | rf_size | rf_next | rf_prev + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + The metadata after the serialized data serves various purposes: + + - rf_reg_metadata_ptr: A pointer to a RegionTy struct that contains various metadata. + Of particular interest to us are the fields: + + = reg_id: A unique identifier for a region. + + = refcount and outset: Whenever an inter-region indirection is created, we record that information + using these two fields. Suppose we have an indirection from region A that points to some chunk + in region B. Then A's outset will store a pointer to that chunk's footer, and B's refcount will + be bumped by 1. Note that all there's only 1 refcount cell, and 1 outset per logical region, + and chunks only store a pointer to them. + + - rf_seq_no: The index of this particular chunk in the list. + + - rf_size: Used during bounds checking to calculate the size of the next region in + the linked list. + + - rf_next / rf_prev: Point to the next and previous chunk respectively. + + +There are two ways in which a region may be freed: + +(1) Whenever it goes out of scope + + The RTS tries to free a region whenever it goes out of scope. But this doesn't always succeed as + regions sometimes contain values that "escape". One reason why this'll happen is if there's an + indirection from A->B, and A lives longer than B. + In such a case, when B goes out of scope it's refcount won't be 0, and the RTS won't free it. + This brings us to (2). + +(2) + + When the RTS successfully frees a region, it decrements the refcounts of all the regions it + points to (via the outset). At the same time, if it encounters a region in the outset whoose + refcount becomes 0 after the decrement, it calls free_region on that. This way we can be sure + that all regions will eventually be garbage collected before the program exits. + + + +Why is it a doubly linked-list? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Due to way that bounds-checking works, the pointers in the outset may actually point to any +arbitrary chunk in the chain. However, we must call free_region on the first one to ensure that +all of them are GC'd. So we need pointers to traverse backward get to the first one. +'trav_to_first_chunk' accomplishes this. + + */ + +#define MAX_OUTSET_LENGTH 10 + +typedef struct RegionTy_struct { + SymTy reg_id; + uint reg_refcount; + CursorTy reg_heap; + uint reg_outset_len; + CursorTy reg_outset[MAX_OUTSET_LENGTH]; +} RegionTy; + +typedef struct RegionFooter_struct { + RegionTy *rf_reg_metadata_ptr; + + IntTy rf_seq_no; + IntTy rf_size; + struct RegionFooter_struct *rf_next; + struct RegionFooter_struct *rf_prev; +} RegionFooter; + +typedef struct ChunkTy_struct { + CursorTy chunk_start; + CursorTy chunk_end; +} ChunkTy; + +static inline void insert_into_outset(CursorTy ptr, RegionTy *reg) { + uint outset_len = reg->reg_outset_len; + // Check for duplicates. + for (uint i = 0; i < outset_len; i++) { + if (ptr == reg->reg_outset[i]) { + return; + } + } + // Otherwise, insert into the outset. + reg->reg_outset[outset_len] = ptr; + reg->reg_outset_len = outset_len + 1; + return; +} + +static inline void remove_from_outset(CursorTy ptr, RegionTy *reg) { + uint outset_len = reg->reg_outset_len; + CursorTy *outset = reg->reg_outset; + int i; + if (outset_len == 0) { + fprintf(stderr, "remove_from_outset: empty outset\n"); + exit(1); + } + // Position of 'ptr' in the outset. + int elt_idx = -1; + for (i = 0; i < outset_len; i++) { + if (ptr == outset[i]) { + elt_idx = i; + } + } + if (elt_idx == -1) { + fprintf(stderr, "remove_from_outset: element not found\n"); + exit(1); + } + // Move all elements ahead of 'elt_idx' back by one position. + for (i = elt_idx; i < outset_len; i++) { + outset[i] = outset[i+1]; + } + return; +} + +RegionTy *alloc_region(IntTy size) { + // Allocate the region metadata. + RegionTy *reg = ALLOC(sizeof(RegionTy)); + if (reg == NULL) { + printf("alloc_region: allocation failed: %ld", sizeof(RegionTy)); + exit(1); + } + + // Allocate the first chunk. + IntTy total_size = size + sizeof(RegionFooter); + CursorTy heap = ALLOC_PACKED_BIG(total_size); + if (heap == NULL) { + printf("alloc_region: malloc failed: %lld", total_size); + exit(1); + } + // Not heap+total_size, since we must keep space for the footer. + CursorTy heap_end = heap + size; + + // Initialize metadata fields. + reg->reg_id = gensym(); + reg->reg_refcount = 1; + reg->reg_heap = heap; + reg->reg_outset_len = 0; + +#ifdef _DEBUG + printf("Allocated a region(%lld): %lld bytes.\n", reg->reg_id, size); +#endif + + // Write the footer. + RegionFooter *footer = (RegionFooter *) heap_end; + footer->rf_reg_metadata_ptr = reg; + footer->rf_seq_no = 1; + footer->rf_size = size; + footer->rf_next = NULL; + footer->rf_prev = NULL; + + return reg; +} + +RegionTy *alloc_counted_region(IntTy size) { + // Bump the count. + bump_global_region_count(); + return alloc_region(size); +} + +ChunkTy alloc_chunk(CursorTy end_old_chunk) { + // Get size from current footer. + RegionFooter *footer = (RegionFooter *) end_old_chunk; + IntTy newsize = footer->rf_size * 2; + // See #110. + if (newsize > global_inf_buf_max_chunk_size) { + newsize = global_inf_buf_max_chunk_size; + } + IntTy total_size = newsize + sizeof(RegionFooter); + + // Allocate. + CursorTy start = ALLOC_PACKED_BIG(total_size); + if (start == NULL) { + printf("alloc_chunk: malloc failed: %lld", total_size); + exit(1); + } + CursorTy end = start + newsize; + + // Link the next chunk's footer. + footer->rf_next = (RegionFooter *) end; + + // Write the footer. + RegionFooter* new_footer = (RegionFooter *) end; + new_footer->rf_reg_metadata_ptr = footer->rf_reg_metadata_ptr; + new_footer->rf_seq_no = footer->rf_seq_no + 1; + new_footer->rf_size = newsize; + new_footer->rf_next = NULL; + new_footer->rf_prev = footer; + +#ifdef _DEBUG + RegionTy *reg = (RegionTy*) new_footer->rf_reg_metadata_ptr; + printf("alloc_chunk: allocated %lld bytes for region %lld.\n", total_size, reg->reg_id); +#endif + + return (ChunkTy) {start , end}; +} + +RegionFooter* trav_to_first_chunk(RegionFooter *footer) { + if (footer->rf_seq_no == 1) { + return footer; + } else if (footer->rf_prev == NULL) { + fprintf(stderr, "No previous chunk found at rf_seq_no: %lld", footer->rf_seq_no); + return NULL; + } else { + trav_to_first_chunk((RegionFooter *) footer->rf_prev); + } + return NULL; +} + +uint get_ref_count(CursorTy end_ptr) { + RegionFooter *footer = (RegionFooter *) end_ptr; + RegionTy *reg = (RegionTy *) footer->rf_reg_metadata_ptr; + return reg->reg_refcount; +} + +// B is the pointer, and A is the pointee (i.e B -> A). +// Bump A's refcount and update B's outset. +static inline void bump_ref_count(CursorTy end_b, CursorTy end_a) { + // Grab footers. + RegionFooter *footer_a = (RegionFooter *) end_a; + RegionFooter *footer_b = (RegionFooter *) end_b; + + // Grab metadata. + RegionTy *reg_a = (RegionTy *) footer_a->rf_reg_metadata_ptr; + RegionTy *reg_b = (RegionTy *) footer_b->rf_reg_metadata_ptr; + + // Bump A's refcount. + uint current_refcount, new_refcount; + current_refcount = reg_a->reg_refcount; + new_refcount = current_refcount + 1; + reg_a->reg_refcount = new_refcount; + +#ifdef _DEBUG + printf("bump_ref_count: %lld -> %lld\n", reg_b->reg_id, reg_a->reg_id); + printf("bump_ref_count: old-refcount=%d, old-outset-len=%d:\n", current_refcount, reg_b->reg_outset_len); + assert(current_refcount == reg_b->reg_outset_len+1); +#endif + + // Add A to B's outset. + insert_into_outset(end_a, reg_b); + +#ifdef _DEBUG + // printf("bump_ref_count: Added %p to %lld's outset, %p.\n", end_a, reg_b->reg_id, reg_b); + printf("bump_ref_count: new-refcount=%d, new-outset-len=%d\n", new_refcount, reg_b->reg_outset_len); + assert(new_refcount == reg_b->reg_outset_len+1); +#endif + + return; +} + +void free_region(CursorTy end_reg) { + // Grab footer and the metadata. + RegionFooter *footer = (RegionFooter *) end_reg; + RegionTy *reg = (RegionTy *) footer->rf_reg_metadata_ptr; + + // + RegionFooter *first_chunk_footer, *next_chunk_footer; + CursorTy first_chunk, next_chunk; + + // Decrement current reference count. + uint current_refcount, new_refcount; + current_refcount = reg->reg_refcount; + new_refcount = 0; + if (current_refcount != 0) { + new_refcount = current_refcount - 1; + reg->reg_refcount = new_refcount; + } + +#ifdef _DEBUG + printf("free_region(%lld): refcounts (1): old-refcount=%d, new-refcount=%d:\n", reg->reg_id, current_refcount, new_refcount); +#endif + + + // Free this region recount is 0. + if (new_refcount == 0) { + +#ifdef _DEBUG + printf("free_region(%lld): outset length: %d\n", reg->reg_id, reg->reg_outset_len); +#endif + + // Decrement refcounts, free regions with refcount==0 and also free + // elements of the outset. + if (reg->reg_outset_len != 0) { + uint outset_len = reg->reg_outset_len; + CursorTy *outset = reg->reg_outset; + RegionFooter *elt_footer; + RegionTy *elt_reg; + uint elt_current_refcount, elt_new_refcount; + CursorTy to_be_removed[MAX_OUTSET_LENGTH]; + uint to_be_removed_idx = 0; + for (int i = 0; i < outset_len; i++) { + elt_footer = (RegionFooter *) outset[i]; + elt_reg = (RegionTy *) elt_footer->rf_reg_metadata_ptr; +#ifdef _DEBUG + elt_current_refcount = elt_reg->reg_refcount; +#endif + elt_new_refcount = elt_current_refcount - 1; + elt_reg->reg_refcount = elt_new_refcount; +#ifdef _DEBUG + printf("free_region(%lld): old-refcount=%d, new-refcount=%d:\n", + elt_reg->reg_id, elt_current_refcount, elt_reg->reg_refcount); +#endif + if (elt_new_refcount == 0) { + // See [Why is it a doubly linked-list?] above + first_chunk_footer = trav_to_first_chunk(elt_footer); + if (first_chunk_footer != NULL) { + free_region((CursorTy) first_chunk_footer); + } + } + to_be_removed[to_be_removed_idx] = outset[i]; + to_be_removed_idx++; + } + // Remove elements from the outset. + for (uint i = 0; i < to_be_removed_idx; i++) { + remove_from_outset(to_be_removed[i], reg); + } + } + + +#ifdef _DEBUG + // Bookkeeping + IntTy num_freed_chunks = 0, total_bytesize = 0; +#endif + + // Free the chunks in this region. + first_chunk = end_reg - footer->rf_size; + first_chunk_footer = footer; + next_chunk = (char*) footer->rf_next; + +#ifdef _DEBUG + printf("free_region(%lld)\n", reg->reg_id); +#endif + +#ifdef _DEBUG + num_freed_chunks++; + total_bytesize = total_bytesize + first_chunk_footer->rf_size; +#endif + free(first_chunk); + + while (next_chunk != NULL) { + next_chunk_footer = (RegionFooter *) next_chunk; + #ifdef _DEBUG + num_freed_chunks++; + total_bytesize = total_bytesize + next_chunk_footer->rf_size; + #endif + free(next_chunk - next_chunk_footer->rf_size); + next_chunk = (char*) next_chunk_footer->rf_next; + } + +#ifdef _DEBUG + printf("free_region(%lld): Freed %lld bytes across %lld chunks.\n", + reg->reg_id, total_bytesize, num_freed_chunks); +#endif + + // Free the metadata. + free(reg); + + } else { +#ifdef _DEBUG + printf("free_region(%lld): non-zero refcount: %d.\n", + reg->reg_id, reg->reg_refcount); +#endif + } +} + +// Assume that all nodes with size information have tags >= 150. +BoolTy is_big(IntTy i, CursorTy cur) { + TagTyPacked tag = *(TagTyPacked *) cur; + if (tag >= 150) { + cur += 1; + IntTy size = *(IntTy *) cur; + if (size >= i) { + return true; + } else { + return false; + } + } + return false; +} + +// ------------------------------------- +// Vectors +// ------------------------------------- + +typedef struct VectorTy_struct { + // Bounds on the vector. + IntTy vec_lower, vec_upper; + + // Size of each element. + IntTy vec_elt_size; + + // Actual elements of the vector. + void* vec_data; +} VectorTy; + +VectorTy* vector_alloc(IntTy num, IntTy elt_size) { + VectorTy *vec = ALLOC(sizeof(VectorTy)); + if (vec == NULL) { + printf("alloc_vector: malloc failed: %ld", sizeof(VectorTy)); + exit(1); + } + void* data = ALLOC(num * elt_size); + if (data == NULL) { + printf("alloc_vector: malloc failed: %ld", sizeof(num * elt_size)); + exit(1); + } + vec->vec_lower = 0; + vec->vec_upper = num; + vec->vec_elt_size = elt_size; + vec->vec_data = data; + return vec; +} + +IntTy vector_length(VectorTy *vec) { + return (vec->vec_upper - vec->vec_lower); +} + +BoolTy vector_is_empty(VectorTy *vec) { + return (vector_length(vec) == 0); +} + +VectorTy* vector_slice(IntTy i, IntTy n, VectorTy *vec) { + IntTy lower = vec->vec_lower + i; + IntTy upper = vec->vec_lower + i + n; + if ((lower > vec->vec_upper)) { + printf("vector_slice: lower out of bounds, %lld > %lld", lower, vec->vec_upper); + exit(1); + } + if ((upper > vec->vec_upper)) { + printf("vector_slice: upper out of bounds: %lld > %lld", upper, vec->vec_upper); + exit(1); + } + VectorTy *vec2 = ALLOC(sizeof(VectorTy)); + if (vec == NULL) { + printf("vector_slice: malloc failed: %ld", sizeof(VectorTy)); + exit(1); + } + vec2->vec_lower = lower; + vec2->vec_upper = upper; + vec2->vec_elt_size = vec->vec_elt_size; + vec2->vec_data = vec->vec_data; + return vec2; +} + +// The callers must cast the return value. +static inline void* vector_nth(VectorTy *vec, IntTy i) { + // if (i < vec->lower || i > vec->upper) { + // printf("vector_nth index out of bounds: %lld (%lld,%lld) \n", i, vec->vec_lower, vec->vec_upper); + // exit(1); + // } + return (vec->vec_data + (vec->vec_elt_size * (vec->vec_lower + i))); +} + +static inline VectorTy* vector_inplace_update(VectorTy *vec, IntTy i, void* elt) { + void* dst = vector_nth(vec, i); + memcpy(dst, elt, vec->vec_elt_size); + return vec; +} + +static inline VectorTy* vector_copy(VectorTy *vec) { + IntTy len = vector_length(vec); + void *start = vector_nth(vec, 0); + VectorTy *vec2 = vector_alloc(len, vec->vec_elt_size); + memcpy(vec2->vec_data, start, len * vec->vec_elt_size); + return vec2; +} + +static inline VectorTy* vector_inplace_sort(VectorTy *vec, int (*compar)(const void *, const void*)) { + void *start = vector_nth(vec, 0); + qsort(start, vector_length(vec), vec->vec_elt_size, compar); + return vec; +} + +static inline VectorTy* vector_sort(VectorTy *vec, int (*compar)(const void *, const void*)) { + VectorTy *vec2 = vector_copy(vec); + vector_inplace_sort(vec2, compar); + return vec2; +} + +static inline VectorTy* vector_concat(VectorTy *vec) { + // Length of the input vector. + IntTy len = vector_length(vec); + // Length of the concatenated vector. + IntTy result_len = 0; + // Size of each element in the concatenated vector. + IntTy result_elt_size = 0; + VectorTy **elt_ref, *elt; + for (IntTy i = 0; i < len; i++) { + elt_ref = vector_nth(vec, i); + elt = *elt_ref; + result_elt_size = elt->vec_elt_size; + result_len += vector_length(elt); + } + + // Concatenated vector. + VectorTy *result = vector_alloc(result_len, result_elt_size); + IntTy elt_len; + // A counter that tracks the index of elements in 'result'. + IntTy k = 0; + for (IntTy i = 0; i < len; i++) { + elt_ref = vector_nth(vec, i); + elt = *elt_ref; + elt_len = vector_length(elt); + + for (IntTy j = 0; j < elt_len; j++) { + void* k_elt = vector_nth(elt, j); + vector_inplace_update(result, k, k_elt); + k++; + } + } + + return result; +} + +static inline void vector_free(VectorTy *vec) { + free(vec->vec_data); + free(vec); + return; +} + +static inline VectorTy* vector_merge(VectorTy *vec1, VectorTy *vec2) { + if (vec1->vec_upper != vec2->vec_lower) { + printf("vector_merge: non-contiguous slices, (%lld,%lld), (%lld,%lld).", + vec1->vec_lower, vec1->vec_upper, vec2->vec_lower, vec2->vec_upper); + exit(1); + } + VectorTy *merged = ALLOC(sizeof(VectorTy)); + if (merged == NULL) { + printf("vector_merge: malloc failed: %ld", sizeof(VectorTy)); + exit(1); + } + merged->vec_lower = vec1->vec_lower; + merged->vec_upper = vec2->vec_upper; + merged->vec_elt_size = vec1->vec_elt_size; + merged->vec_data = vec1->vec_data; + return merged; +} + +void print_timing_array(VectorTy *times) { + printf("TIMES: ["); + double *d; + IntTy n = vector_length(times); + for(int i = 0; i < n; i++) { + d = vector_nth(times, i); + if (i == (n-1)) { + printf("%f",*d); + } + else { + printf("%f, ",*d); + } + } + printf("]\n"); +} + +double sum_timing_array(VectorTy *times) { + double *d; + double acc = 0; + for(int i = 0; i < vector_length(times); i++) { + d = vector_nth(times, i); + acc += *d; + } + return acc; +} + +// ------------------------------------- +// Linked lists +// ------------------------------------- + +typedef struct ListTy_struct { + IntTy ll_data_size; + void* ll_data; + struct ListTy_struct* ll_next; +} ListTy; + +static inline ListTy* list_alloc(IntTy data_size) { + // ListTy *ls = ALLOC(sizeof(ListTy)); + ListTy *ls = BUMPALLOC(sizeof(ListTy)); + ls->ll_data_size = data_size; + ls->ll_data = NULL; + ls->ll_next = NULL; + return ls; +} + +static inline BoolTy list_is_empty(ListTy *ls) { + return ls->ll_next == NULL; +} + +static inline ListTy* list_cons(void* elt, ListTy *ls) { + // void* data = ALLOC(ls->data_size); + void* data = BUMPALLOC(ls->ll_data_size); + if (data == NULL) { + printf("list_cons: malloc failed: %lld", ls->ll_data_size); + exit(1); + } + memcpy(data, elt, ls->ll_data_size); + // ListTy *res = ALLOC(sizeof(ListTy)); + ListTy *res = BUMPALLOC(sizeof(ListTy)); + res->ll_data_size = ls->ll_data_size; + res->ll_data = data; + res->ll_next = (ListTy*) ls; + return res; +} + +static inline void* list_head(ListTy *ls) { + return ls->ll_data; +} + +static inline ListTy* list_tail(ListTy *ls) { + return ls->ll_next; +} + +static inline void list_free(ListTy *ls) { + free(ls->ll_data); + free(ls); + return; +} + +static inline ListTy* list_copy(ListTy *ls) { + ListTy *ls2 = list_alloc(ls->ll_data_size); + if (ls->ll_data != NULL) { + void* data = BUMPALLOC(ls->ll_data_size); + memcpy(data, ls->ll_data, ls->ll_data_size); + ls2->ll_data = data; + } + ls2->ll_next = ls->ll_next; + return ls2; +} + +// ------------------------------------- +// Ppm Images +// ------------------------------------- + +typedef struct __Pixel_struct { + IntTy field0; + IntTy field1; + IntTy field2; +} __Pixel; + +void writePpm(char* filename, IntTy width, IntTy height, VectorTy *pixels); +void writePpm_loop(FILE *fp, IntTy idx, IntTy end, VectorTy *pixels); + +// Example: writePpm("gibbon_rgb_1000.ppm", 1000, 1000, pixels); +void writePpm(char* filename, IntTy width, IntTy height, VectorTy *pixels) +{ + FILE *fp; + fp = fopen(filename, "w+"); + fprintf(fp, "P3\n"); + fprintf(fp, "%lld %lld\n255\n", width, height); + IntTy len = vector_length(pixels); + writePpm_loop(fp, 0, len, pixels); + fclose(fp); + return; +} + +void writePpm_loop(FILE *fp, IntTy idx, IntTy end, VectorTy *pixels) +{ + BoolTy fltIf_5768_6575 = idx == end; + + if (fltIf_5768_6575) { + return; + } else { + __Pixel *tmp_112; + tmp_112 = (__Pixel *) vector_nth(pixels, idx); + __Pixel tup = *tmp_112; + IntTy x = tup.field0; + IntTy y = tup.field1; + IntTy z = tup.field2; + // write to file. + fprintf(fp, "%lld %lld %lld\n", x, y, z); + writePpm_loop(fp, (idx+1), end, pixels); + } +} + +/* -------------------------------------------------------------------------------- */ + +int main(int argc, char** argv) +{ + // parameters to parse: + // + // num iterations: How many times to repeat a benchmark. + // tree size: An integer passes to `build_tree()`. + + struct rlimit lim; + int code; + if ( (code = getrlimit(RLIMIT_STACK, &lim)) ) { + fprintf(stderr, " [gibbon rts] failed to getrlimit, code %d\n", code); + exit(1); + } + + // lim.rlim_cur = 1024LU * 1024LU * 1024LU; // 1GB stack. + lim.rlim_cur = 512LU * 1024LU * 1024LU; // 500MB stack. + // lim.rlim_max = lim.rlim_cur; // Normal users may only be able to decrease this. + + // WARNING: Haven't yet figured out why this doesn't work on MacOS... +#ifndef __APPLE__ + code = setrlimit(RLIMIT_STACK, &lim); + while (code) { + fprintf(stderr, " [gibbon rts] Failed to set stack size to %llu, code %d\n", (unsigned long long)lim.rlim_cur, code); + lim.rlim_cur /= 2; + // lim.rlim_max /= 2; + if(lim.rlim_cur < 100 * 1024) { + fprintf(stderr, " [gibbon rts] Failed setrlimit stack size to something reasonable; giving up.\n"); + break; // abort(); + } + int code = setrlimit(RLIMIT_STACK, &lim); + } +#endif + + int got_numargs = 0; // How many numeric arguments have we got. + + int i; + for (i = 1; i < argc; ++i) + { + if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) { + show_usage(argv); + exit(0); + } + else if (strcmp(argv[i], "--biginf-buffer-size") == 0 && i < argc - 1) + { + global_init_biginf_buf_size = atoll(argv[i + 1]); + i++; + } + else if (strcmp(argv[i], "--inf-buffer-size") == 0 && i < argc - 1) + { + global_init_inf_buf_size = atoll(argv[i + 1]); + i++; + } + else if ((strcmp(argv[i], "--bench-input") == 0)) { + if (i+1 >= argc) { + fprintf(stderr, "Not enough arguments after --bench-input, expected .\n"); + show_usage(argv); + exit(1); + } + global_benchfile_param = argv[i+1]; + i++; + } + else if ((strcmp(argv[i], "--array-input") == 0)) { + if (i+1 >= argc) { + fprintf(stderr, "Not enough arguments after --array-input, expected .\n"); + show_usage(argv); + exit(1); + } + global_arrayfile_param = argv[i+1]; + i++; + } + else if (strcmp(argv[i], "--array-input-length") == 0 && i < argc - 1) { + global_arrayfile_length_param = atoll(argv[i+1]); + i++; + } + else if (strcmp(argv[i], "--bench-prog") == 0 && i < argc - 1) { + int len = strlen(argv[i+1]); + global_bench_prog_param = (char*) malloc((len+1)*sizeof(char)); + strncpy(global_bench_prog_param,argv[i+1],len); + i++; + } + // If present, we expect the two arguments to be + else if (got_numargs >= 2) { + fprintf(stderr, "Extra arguments left over: "); + for(; i < argc; i++) fprintf(stderr, "%s ", argv[i]); + show_usage(argv); + exit(1); + } else { + if (got_numargs == 0) { + global_size_param = atoll(argv[i]); + got_numargs ++; + } else { + global_iters_param = atoll(argv[i]); + } + } + } + + // Initialize global_bench_prog_param to an empty string in case + // the runtime argument --bench-prog isn't passed. + if (global_bench_prog_param == NULL) { + global_bench_prog_param = (char*) malloc(1*sizeof(char)); + *global_bench_prog_param = '\n'; + } + + __main_expr(); + + return 0; +} + +// ----------------------------------------------------------------------------- +// Program starts here +// ----------------------------------------------------------------------------- + +typedef struct Prod_struct { } Prod; +typedef struct Int64Prod_struct { + IntTy field0; + } Int64Prod; +typedef struct Int64Int64Int64Int64CursorCursorProd_struct { + IntTy field0; + IntTy field1; + IntTy field2; + IntTy field3; + CursorTy field4; + CursorTy field5; + } Int64Int64Int64Int64CursorCursorProd; +typedef struct Int64Int64Int64CursorCursorProd_struct { + IntTy field0; + IntTy field1; + IntTy field2; + CursorTy field3; + CursorTy field4; + } Int64Int64Int64CursorCursorProd; +typedef struct BoolProd_struct { + BoolTy field0; + } BoolProd; +typedef struct TagCursorProd_struct { + TagTyPacked field0; + CursorTy field1; + } TagCursorProd; +typedef struct CursorProd_struct { + CursorTy field0; + } CursorProd; +IntTy sumRight(CursorTy m_48_719_958); +CursorTy build(IntTy x_54_725_967, IntTy sz_55_726_968, CursorTy m_56_727_969); +IntTy sumLeft(CursorTy m_57_728_979); +IntTy ratio(); +IntTy delta(); +IntTy size_338(CursorTy m_193_734_988); +CursorTy singleL_345(IntTy k1_120_740_994, IntTy x1_121_741_995, + CursorTy t1_122_742_996, CursorTy m_123_743_997); +CursorTy doubleL_346(IntTy k1_91_749_1004, IntTy x1_92_750_1005, + CursorTy t1_93_751_1006, CursorTy m0_94_752_1007); +CursorTy rotateL_339(IntTy k_145_758_1013, IntTy x_146_759_1014, + CursorTy l_147_760_1015, CursorTy r_148_761_1016); +CursorTy bin_344(IntTy k_130_767_1027, IntTy x_131_768_1028, + CursorTy l_132_769_1029, CursorTy r_133_770_1030); +CursorTy singleR_341(IntTy k1_110_771_1035, IntTy x1_111_772_1036, + CursorTy m_112_773_1037, CursorTy t3_113_774_1038); +CursorTy doubleR_342(IntTy k1_76_780_1045, IntTy x1_77_781_1046, + CursorTy m0_78_782_1047, CursorTy t4_79_783_1048); +CursorTy empty_343(); +CursorTy rotateR_340(IntTy k_135_789_1054, IntTy x_136_790_1055, + CursorTy l_137_791_1056, CursorTy r_138_792_1057); +CursorTy balance_337(IntTy k_155_798_1068, IntTy x_156_799_1069, + CursorTy l_157_800_1070, CursorTy r_158_801_1071); +CursorTy singleton_334(IntTy k_72_802_1092, IntTy x_73_803_1093); +CursorTy insert_336(IntTy kx_63_804_1096, IntTy x_64_805_1097, + CursorTy m_65_806_1098); +CursorTy _copy_without_ptrs_Map_v_335(CursorTy arg_652_812_1108); +CursorTy _copy_Map_v_335(CursorTy arg_641_823_1119); +unsigned char _traverse_Map_v_335(CursorTy arg_663_834_1130); +unsigned char _print_Map_v_335(CursorTy arg_674_842_1138); +CursorTy caseFn_694(IntTy x1_92_695_862_1158, IntTy k1_91_696_863_1159, + CursorTy t1_93_697_864_1160, CursorTy m1_99_698_865_1161, + IntTy k2_97_699_866_1162, IntTy x2_98_700_867_1163, + CursorTy t4_100_701_868_1164); +CursorTy caseFn_702(IntTy x1_77_703_874_1172, IntTy k1_76_704_875_1173, + CursorTy t4_79_705_876_1174, CursorTy m1_85_706_877_1175, + IntTy k2_82_707_878_1176, IntTy x2_83_708_879_1177, + CursorTy t1_84_709_880_1178); +IntTy sumRight(CursorTy m_48_719_958) +{ + TagTyPacked tag_1195 = *(TagTyPacked *) m_48_719_958; + CursorTy tail_1196 = m_48_719_958 + sizeof(IntTy); + + + switch_1198: + ; + switch (tag_1195) { + + case 0: + { + return 0; + break; + } + + case 1: + { + IntTy wildcard__1_49_720_959 = + ((Int64Int64Int64CursorCursorProd *) tail_1196)->field0; + IntTy wildcard__2_50_721_960 = + ((Int64Int64Int64CursorCursorProd *) tail_1196)->field1; + IntTy v_51_722_961 = + ((Int64Int64Int64CursorCursorProd *) tail_1196)->field2; + CursorTy l_52_723_962 = + ((Int64Int64Int64CursorCursorProd *) tail_1196)->field3; + CursorTy r_53_724_963 = + ((Int64Int64Int64CursorCursorProd *) tail_1196)->field4; + IntTy fltPrm_888_964 = sumRight(r_53_724_963); + IntTy fltPrm_887_965 = fltPrm_888_964 + v_51_722_961; + IntTy fltPrm_889_966 = sumRight(r_53_724_963); + IntTy flt_1197 = fltPrm_887_965 + fltPrm_889_966; + + return flt_1197; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1195"); + exit(1); + } + } +} +CursorTy build(IntTy x_54_725_967, IntTy sz_55_726_968, CursorTy m_56_727_969) +{ + BoolTy fltIf_890_970 = sz_55_726_968 == 0; + + if (fltIf_890_970) { + return m_56_727_969; + } else { + IntTy fltPrm_892_971 = sz_55_726_968 / 2; + IntTy fltAppE_891_972 = x_54_725_967 - fltPrm_892_971; + IntTy fltAppE_893_973 = sz_55_726_968 / 2; + IntTy fltPrm_896_974 = sz_55_726_968 / 2; + IntTy fltAppE_895_975 = x_54_725_967 + fltPrm_896_974; + IntTy fltAppE_897_976 = sz_55_726_968 / 2; + CursorTy fltAppE_898_977 = + insert_336(x_54_725_967, x_54_725_967, m_56_727_969); + CursorTy fltAppE_894_978 = + build(fltAppE_895_975, fltAppE_897_976, fltAppE_898_977); + + return build(fltAppE_891_972, fltAppE_893_973, fltAppE_894_978); + } +} +IntTy sumLeft(CursorTy m_57_728_979) +{ + TagTyPacked tag_1199 = *(TagTyPacked *) m_57_728_979; + CursorTy tail_1200 = m_57_728_979 + sizeof(IntTy); + + + switch_1202: + ; + switch (tag_1199) { + + case 0: + { + return 0; + break; + } + + case 1: + { + IntTy wildcard__9_58_729_980 = + ((Int64Int64Int64CursorCursorProd *) tail_1200)->field0; + IntTy wildcard__10_59_730_981 = + ((Int64Int64Int64CursorCursorProd *) tail_1200)->field1; + IntTy v_60_731_982 = + ((Int64Int64Int64CursorCursorProd *) tail_1200)->field2; + CursorTy l_61_732_983 = + ((Int64Int64Int64CursorCursorProd *) tail_1200)->field3; + CursorTy r_62_733_984 = + ((Int64Int64Int64CursorCursorProd *) tail_1200)->field4; + IntTy fltPrm_900_985 = sumLeft(l_61_732_983); + IntTy fltPrm_899_986 = fltPrm_900_985 + v_60_731_982; + IntTy fltPrm_901_987 = sumLeft(r_62_733_984); + IntTy flt_1201 = fltPrm_899_986 + fltPrm_901_987; + + return flt_1201; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1199"); + exit(1); + } + } +} +IntTy ratio() +{ + return 2; +} +IntTy delta() +{ + return 4; +} +IntTy size_338(CursorTy m_193_734_988) +{ + TagTyPacked tag_1203 = *(TagTyPacked *) m_193_734_988; + CursorTy tail_1204 = m_193_734_988 + sizeof(IntTy); + + + switch_1205: + ; + switch (tag_1203) { + + case 0: + { + return 0; + break; + } + + case 1: + { + IntTy sz_195_735_989 = + ((Int64Int64Int64CursorCursorProd *) tail_1204)->field0; + IntTy wildcard__18_196_736_990 = + ((Int64Int64Int64CursorCursorProd *) tail_1204)->field1; + IntTy wildcard__19_197_737_991 = + ((Int64Int64Int64CursorCursorProd *) tail_1204)->field2; + CursorTy wildcard__20_198_738_992 = + ((Int64Int64Int64CursorCursorProd *) tail_1204)->field3; + CursorTy wildcard__21_199_739_993 = + ((Int64Int64Int64CursorCursorProd *) tail_1204)->field4; + + return sz_195_735_989; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1203"); + exit(1); + } + } +} +CursorTy singleL_345(IntTy k1_120_740_994, IntTy x1_121_741_995, + CursorTy t1_122_742_996, CursorTy m_123_743_997) +{ + TagTyPacked tag_1206 = *(TagTyPacked *) m_123_743_997; + CursorTy tail_1207 = m_123_743_997 + sizeof(IntTy); + + + switch_1208: + ; + switch (tag_1206) { + + case 1: + { + IntTy wildcard__123_125_744_998 = + ((Int64Int64Int64CursorCursorProd *) tail_1207)->field0; + IntTy k2_126_745_999 = + ((Int64Int64Int64CursorCursorProd *) tail_1207)->field1; + IntTy x2_127_746_1000 = + ((Int64Int64Int64CursorCursorProd *) tail_1207)->field2; + CursorTy t2_128_747_1001 = + ((Int64Int64Int64CursorCursorProd *) tail_1207)->field3; + CursorTy t3_129_748_1002 = + ((Int64Int64Int64CursorCursorProd *) tail_1207)->field4; + CursorTy fltAppE_902_1003 = + bin_344(k1_120_740_994, x1_121_741_995, t1_122_742_996, t2_128_747_1001); + + return bin_344(k2_126_745_999, x2_127_746_1000, fltAppE_902_1003, + t3_129_748_1002); + break; + } + + case 0: + { + return empty_343(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1206"); + exit(1); + } + } +} +CursorTy doubleL_346(IntTy k1_91_749_1004, IntTy x1_92_750_1005, + CursorTy t1_93_751_1006, CursorTy m0_94_752_1007) +{ + TagTyPacked tag_1209 = *(TagTyPacked *) m0_94_752_1007; + CursorTy tail_1210 = m0_94_752_1007 + sizeof(IntTy); + + + switch_1211: + ; + switch (tag_1209) { + + case 1: + { + IntTy wildcard__143_96_753_1008 = + ((Int64Int64Int64CursorCursorProd *) tail_1210)->field0; + IntTy k2_97_754_1009 = + ((Int64Int64Int64CursorCursorProd *) tail_1210)->field1; + IntTy x2_98_755_1010 = + ((Int64Int64Int64CursorCursorProd *) tail_1210)->field2; + CursorTy m1_99_756_1011 = + ((Int64Int64Int64CursorCursorProd *) tail_1210)->field3; + CursorTy t4_100_757_1012 = + ((Int64Int64Int64CursorCursorProd *) tail_1210)->field4; + + return caseFn_694(x1_92_750_1005, k1_91_749_1004, t1_93_751_1006, + m1_99_756_1011, k2_97_754_1009, x2_98_755_1010, + t4_100_757_1012); + break; + } + + case 0: + { + return empty_343(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1209"); + exit(1); + } + } +} +CursorTy rotateL_339(IntTy k_145_758_1013, IntTy x_146_759_1014, + CursorTy l_147_760_1015, CursorTy r_148_761_1016) +{ + TagTyPacked tag_1212 = *(TagTyPacked *) r_148_761_1016; + CursorTy tail_1213 = r_148_761_1016 + sizeof(IntTy); + + + switch_1214: + ; + switch (tag_1212) { + + case 1: + { + IntTy wildcard__94_150_762_1017 = + ((Int64Int64Int64CursorCursorProd *) tail_1213)->field0; + IntTy wildcard__95_151_763_1018 = + ((Int64Int64Int64CursorCursorProd *) tail_1213)->field1; + IntTy wildcard__96_152_764_1019 = + ((Int64Int64Int64CursorCursorProd *) tail_1213)->field2; + CursorTy ly_153_765_1020 = + ((Int64Int64Int64CursorCursorProd *) tail_1213)->field3; + CursorTy ry_154_766_1021 = + ((Int64Int64Int64CursorCursorProd *) tail_1213)->field4; + IntTy fltPrm_904_1022 = size_338(ly_153_765_1020); + IntTy fltPrm_906_1023 = ratio(); + IntTy fltPrm_907_1024 = size_338(ry_154_766_1021); + IntTy fltPrm_905_1025 = fltPrm_906_1023 * fltPrm_907_1024; + BoolTy fltIf_903_1026 = fltPrm_904_1022 < fltPrm_905_1025; + + if (fltIf_903_1026) { + return singleL_345(k_145_758_1013, x_146_759_1014, + l_147_760_1015, r_148_761_1016); + } else { + return doubleL_346(k_145_758_1013, x_146_759_1014, + l_147_760_1015, r_148_761_1016); + } + break; + } + + case 0: + { + return empty_343(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1212"); + exit(1); + } + } +} +CursorTy bin_344(IntTy k_130_767_1027, IntTy x_131_768_1028, + CursorTy l_132_769_1029, CursorTy r_133_770_1030) +{ + IntTy fltPrm_910_1031 = size_338(l_132_769_1029); + IntTy fltPrm_911_1032 = size_338(r_133_770_1030); + IntTy fltPrm_909_1033 = fltPrm_910_1031 + fltPrm_911_1032; + IntTy fltPkd_908_1034 = fltPrm_909_1033 + 1; + PtrTy tailift_1215 = ALLOC(sizeof(Int64Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1215)->field0 = 1; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1215)->field1 = + fltPkd_908_1034; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1215)->field2 = + k_130_767_1027; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1215)->field3 = + x_131_768_1028; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1215)->field4 = + l_132_769_1029; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1215)->field5 = + r_133_770_1030; + return tailift_1215; +} +CursorTy singleR_341(IntTy k1_110_771_1035, IntTy x1_111_772_1036, + CursorTy m_112_773_1037, CursorTy t3_113_774_1038) +{ + TagTyPacked tag_1216 = *(TagTyPacked *) m_112_773_1037; + CursorTy tail_1217 = m_112_773_1037 + sizeof(IntTy); + + + switch_1218: + ; + switch (tag_1216) { + + case 1: + { + IntTy wildcard__133_115_775_1039 = + ((Int64Int64Int64CursorCursorProd *) tail_1217)->field0; + IntTy k2_116_776_1040 = + ((Int64Int64Int64CursorCursorProd *) tail_1217)->field1; + IntTy x2_117_777_1041 = + ((Int64Int64Int64CursorCursorProd *) tail_1217)->field2; + CursorTy t1_118_778_1042 = + ((Int64Int64Int64CursorCursorProd *) tail_1217)->field3; + CursorTy t2_119_779_1043 = + ((Int64Int64Int64CursorCursorProd *) tail_1217)->field4; + CursorTy fltAppE_912_1044 = + bin_344(k1_110_771_1035, x1_111_772_1036, t2_119_779_1043, t3_113_774_1038); + + return bin_344(k2_116_776_1040, x2_117_777_1041, t1_118_778_1042, + fltAppE_912_1044); + break; + } + + case 0: + { + return empty_343(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1216"); + exit(1); + } + } +} +CursorTy doubleR_342(IntTy k1_76_780_1045, IntTy x1_77_781_1046, + CursorTy m0_78_782_1047, CursorTy t4_79_783_1048) +{ + TagTyPacked tag_1219 = *(TagTyPacked *) m0_78_782_1047; + CursorTy tail_1220 = m0_78_782_1047 + sizeof(IntTy); + + + switch_1221: + ; + switch (tag_1219) { + + case 1: + { + IntTy wildcard__167_81_784_1049 = + ((Int64Int64Int64CursorCursorProd *) tail_1220)->field0; + IntTy k2_82_785_1050 = + ((Int64Int64Int64CursorCursorProd *) tail_1220)->field1; + IntTy x2_83_786_1051 = + ((Int64Int64Int64CursorCursorProd *) tail_1220)->field2; + CursorTy t1_84_787_1052 = + ((Int64Int64Int64CursorCursorProd *) tail_1220)->field3; + CursorTy m1_85_788_1053 = + ((Int64Int64Int64CursorCursorProd *) tail_1220)->field4; + + return caseFn_702(x1_77_781_1046, k1_76_780_1045, t4_79_783_1048, + m1_85_788_1053, k2_82_785_1050, x2_83_786_1051, + t1_84_787_1052); + break; + } + + case 0: + { + return empty_343(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1219"); + exit(1); + } + } +} +CursorTy empty_343() +{ + PtrTy tailift_1222 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) tailift_1222)->field0 = 0; + return tailift_1222; +} +CursorTy rotateR_340(IntTy k_135_789_1054, IntTy x_136_790_1055, + CursorTy l_137_791_1056, CursorTy r_138_792_1057) +{ + TagTyPacked tag_1223 = *(TagTyPacked *) l_137_791_1056; + CursorTy tail_1224 = l_137_791_1056 + sizeof(IntTy); + + + switch_1225: + ; + switch (tag_1223) { + + case 1: + { + IntTy wildcard__106_140_793_1058 = + ((Int64Int64Int64CursorCursorProd *) tail_1224)->field0; + IntTy wildcard__107_141_794_1059 = + ((Int64Int64Int64CursorCursorProd *) tail_1224)->field1; + IntTy wildcard__108_142_795_1060 = + ((Int64Int64Int64CursorCursorProd *) tail_1224)->field2; + CursorTy ly_143_796_1061 = + ((Int64Int64Int64CursorCursorProd *) tail_1224)->field3; + CursorTy ry_144_797_1062 = + ((Int64Int64Int64CursorCursorProd *) tail_1224)->field4; + IntTy fltPrm_914_1063 = size_338(ry_144_797_1062); + IntTy fltPrm_916_1064 = ratio(); + IntTy fltPrm_917_1065 = size_338(ly_143_796_1061); + IntTy fltPrm_915_1066 = fltPrm_916_1064 * fltPrm_917_1065; + BoolTy fltIf_913_1067 = fltPrm_914_1063 < fltPrm_915_1066; + + if (fltIf_913_1067) { + return singleR_341(k_135_789_1054, x_136_790_1055, + l_137_791_1056, r_138_792_1057); + } else { + return doubleR_342(k_135_789_1054, x_136_790_1055, + l_137_791_1056, r_138_792_1057); + } + break; + } + + case 0: + { + return empty_343(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1223"); + exit(1); + } + } +} +CursorTy balance_337(IntTy k_155_798_1068, IntTy x_156_799_1069, + CursorTy l_157_800_1070, CursorTy r_158_801_1071) +{ + IntTy fltPrm_920_1072 = size_338(l_157_800_1070); + IntTy fltPrm_921_1073 = size_338(r_158_801_1071); + IntTy fltPrm_919_1074 = fltPrm_920_1072 + fltPrm_921_1073; + BoolTy fltIf_918_1075 = fltPrm_919_1074 <= 1; + + if (fltIf_918_1075) { + IntTy fltPrm_923_1076 = size_338(l_157_800_1070); + IntTy fltPrm_924_1077 = size_338(r_158_801_1071); + IntTy fltPkd_922_1078 = fltPrm_923_1076 + fltPrm_924_1077; + PtrTy tailift_1226 = + ALLOC(sizeof(Int64Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1226)->field0 = 1; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1226)->field1 = + fltPkd_922_1078; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1226)->field2 = + k_155_798_1068; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1226)->field3 = + x_156_799_1069; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1226)->field4 = + l_157_800_1070; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1226)->field5 = + r_158_801_1071; + return tailift_1226; + } else { + IntTy fltPrm_926_1079 = size_338(r_158_801_1071); + IntTy fltPrm_928_1080 = delta(); + IntTy fltPrm_929_1081 = size_338(l_157_800_1070); + IntTy fltPrm_927_1082 = fltPrm_928_1080 * fltPrm_929_1081; + BoolTy fltIf_925_1083 = fltPrm_926_1079 >= fltPrm_927_1082; + + if (fltIf_925_1083) { + return rotateL_339(k_155_798_1068, x_156_799_1069, l_157_800_1070, + r_158_801_1071); + } else { + IntTy fltPrm_931_1084 = size_338(l_157_800_1070); + IntTy fltPrm_933_1085 = delta(); + IntTy fltPrm_934_1086 = size_338(r_158_801_1071); + IntTy fltPrm_932_1087 = fltPrm_933_1085 * fltPrm_934_1086; + BoolTy fltIf_930_1088 = fltPrm_931_1084 >= fltPrm_932_1087; + + if (fltIf_930_1088) { + return rotateR_340(k_155_798_1068, x_156_799_1069, + l_157_800_1070, r_158_801_1071); + } else { + IntTy fltPrm_936_1089 = size_338(l_157_800_1070); + IntTy fltPrm_937_1090 = size_338(r_158_801_1071); + IntTy fltPkd_935_1091 = fltPrm_936_1089 + fltPrm_937_1090; + PtrTy tailift_1227 = + ALLOC(sizeof(Int64Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1227)->field0 = + 1; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1227)->field1 = + fltPkd_935_1091; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1227)->field2 = + k_155_798_1068; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1227)->field3 = + x_156_799_1069; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1227)->field4 = + l_157_800_1070; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1227)->field5 = + r_158_801_1071; + return tailift_1227; + } + } + } +} +CursorTy singleton_334(IntTy k_72_802_1092, IntTy x_73_803_1093) +{ + PtrTy fltPkd_938_1094 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_938_1094)->field0 = 0; + + PtrTy fltPkd_939_1095 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_939_1095)->field0 = 0; + + PtrTy tailift_1228 = ALLOC(sizeof(Int64Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1228)->field0 = 1; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1228)->field1 = 1; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1228)->field2 = + k_72_802_1092; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1228)->field3 = + x_73_803_1093; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1228)->field4 = + fltPkd_938_1094; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1228)->field5 = + fltPkd_939_1095; + return tailift_1228; +} +CursorTy insert_336(IntTy kx_63_804_1096, IntTy x_64_805_1097, + CursorTy m_65_806_1098) +{ + TagTyPacked tag_1229 = *(TagTyPacked *) m_65_806_1098; + CursorTy tail_1230 = m_65_806_1098 + sizeof(IntTy); + + + switch_1232: + ; + switch (tag_1229) { + + case 0: + { + return singleton_334(kx_63_804_1096, x_64_805_1097); + break; + } + + case 1: + { + IntTy sz_67_807_1099 = + ((Int64Int64Int64CursorCursorProd *) tail_1230)->field0; + IntTy k_68_808_1100 = + ((Int64Int64Int64CursorCursorProd *) tail_1230)->field1; + IntTy v_69_809_1101 = + ((Int64Int64Int64CursorCursorProd *) tail_1230)->field2; + CursorTy l_70_810_1102 = + ((Int64Int64Int64CursorCursorProd *) tail_1230)->field3; + CursorTy r_71_811_1103 = + ((Int64Int64Int64CursorCursorProd *) tail_1230)->field4; + BoolTy fltIf_940_1104 = kx_63_804_1096 == k_68_808_1100; + + if (fltIf_940_1104) { + PtrTy tailift_1231 = + ALLOC(sizeof(Int64Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1231)->field0 = + 1; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1231)->field1 = + sz_67_807_1099; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1231)->field2 = + k_68_808_1100; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1231)->field3 = + x_64_805_1097; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1231)->field4 = + l_70_810_1102; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1231)->field5 = + r_71_811_1103; + return tailift_1231; + } else { + BoolTy fltIf_941_1105 = kx_63_804_1096 <= k_68_808_1100; + + if (fltIf_941_1105) { + CursorTy fltAppE_942_1106 = + insert_336(kx_63_804_1096, x_64_805_1097, l_70_810_1102); + + return balance_337(k_68_808_1100, v_69_809_1101, + fltAppE_942_1106, r_71_811_1103); + } else { + CursorTy fltAppE_943_1107 = + insert_336(kx_63_804_1096, x_64_805_1097, r_71_811_1103); + + return balance_337(k_68_808_1100, v_69_809_1101, + l_70_810_1102, fltAppE_943_1107); + } + } + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1229"); + exit(1); + } + } +} +CursorTy _copy_without_ptrs_Map_v_335(CursorTy arg_652_812_1108) +{ + TagTyPacked tag_1233 = *(TagTyPacked *) arg_652_812_1108; + CursorTy tail_1234 = arg_652_812_1108 + sizeof(IntTy); + + + switch_1237: + ; + switch (tag_1233) { + + case 0: + { + PtrTy tailift_1235 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) tailift_1235)->field0 = 0; + return tailift_1235; + break; + } + + case 1: + { + IntTy x_653_813_1109 = + ((Int64Int64Int64CursorCursorProd *) tail_1234)->field0; + IntTy x_654_814_1110 = + ((Int64Int64Int64CursorCursorProd *) tail_1234)->field1; + IntTy x_655_815_1111 = + ((Int64Int64Int64CursorCursorProd *) tail_1234)->field2; + CursorTy x_656_816_1112 = + ((Int64Int64Int64CursorCursorProd *) tail_1234)->field3; + CursorTy x_657_817_1113 = + ((Int64Int64Int64CursorCursorProd *) tail_1234)->field4; + CursorTy y_661_821_1117 = + _copy_without_ptrs_Map_v_335(x_656_816_1112); + CursorTy y_662_822_1118 = + _copy_without_ptrs_Map_v_335(x_657_817_1113); + PtrTy tailift_1236 = + ALLOC(sizeof(Int64Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1236)->field0 = 1; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1236)->field1 = + x_653_813_1109; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1236)->field2 = + x_654_814_1110; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1236)->field3 = + x_655_815_1111; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1236)->field4 = + y_661_821_1117; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1236)->field5 = + y_662_822_1118; + return tailift_1236; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1233"); + exit(1); + } + } +} +CursorTy _copy_Map_v_335(CursorTy arg_641_823_1119) +{ + TagTyPacked tag_1238 = *(TagTyPacked *) arg_641_823_1119; + CursorTy tail_1239 = arg_641_823_1119 + sizeof(IntTy); + + + switch_1242: + ; + switch (tag_1238) { + + case 0: + { + PtrTy tailift_1240 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) tailift_1240)->field0 = 0; + return tailift_1240; + break; + } + + case 1: + { + IntTy x_642_824_1120 = + ((Int64Int64Int64CursorCursorProd *) tail_1239)->field0; + IntTy x_643_825_1121 = + ((Int64Int64Int64CursorCursorProd *) tail_1239)->field1; + IntTy x_644_826_1122 = + ((Int64Int64Int64CursorCursorProd *) tail_1239)->field2; + CursorTy x_645_827_1123 = + ((Int64Int64Int64CursorCursorProd *) tail_1239)->field3; + CursorTy x_646_828_1124 = + ((Int64Int64Int64CursorCursorProd *) tail_1239)->field4; + CursorTy y_650_832_1128 = _copy_Map_v_335(x_645_827_1123); + CursorTy y_651_833_1129 = _copy_Map_v_335(x_646_828_1124); + PtrTy tailift_1241 = + ALLOC(sizeof(Int64Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1241)->field0 = 1; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1241)->field1 = + x_642_824_1120; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1241)->field2 = + x_643_825_1121; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1241)->field3 = + x_644_826_1122; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1241)->field4 = + y_650_832_1128; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1241)->field5 = + y_651_833_1129; + return tailift_1241; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1238"); + exit(1); + } + } +} +unsigned char _traverse_Map_v_335(CursorTy arg_663_834_1130) +{ + TagTyPacked tag_1243 = *(TagTyPacked *) arg_663_834_1130; + CursorTy tail_1244 = arg_663_834_1130 + sizeof(IntTy); + + + switch_1245: + ; + switch (tag_1243) { + + case 0: + { + return 0; + break; + } + + case 1: + { + IntTy x_664_835_1131 = + ((Int64Int64Int64CursorCursorProd *) tail_1244)->field0; + IntTy x_665_836_1132 = + ((Int64Int64Int64CursorCursorProd *) tail_1244)->field1; + IntTy x_666_837_1133 = + ((Int64Int64Int64CursorCursorProd *) tail_1244)->field2; + CursorTy x_667_838_1134 = + ((Int64Int64Int64CursorCursorProd *) tail_1244)->field3; + CursorTy x_668_839_1135 = + ((Int64Int64Int64CursorCursorProd *) tail_1244)->field4; + unsigned char y_672_840_1136 = _traverse_Map_v_335(x_667_838_1134); + unsigned char y_673_841_1137 = _traverse_Map_v_335(x_668_839_1135); + + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1243"); + exit(1); + } + } +} +unsigned char _print_Map_v_335(CursorTy arg_674_842_1138) +{ + TagTyPacked tag_1246 = *(TagTyPacked *) arg_674_842_1138; + CursorTy tail_1247 = arg_674_842_1138 + sizeof(IntTy); + + + switch_1248: + ; + switch (tag_1246) { + + case 0: + { + unsigned char wildcard_675_843_1139 = print_symbol(1191); + unsigned char wildcard_676_844_1140 = print_symbol(1190); + + return 0; + break; + } + + case 1: + { + IntTy x_677_845_1141 = + ((Int64Int64Int64CursorCursorProd *) tail_1247)->field0; + IntTy x_678_846_1142 = + ((Int64Int64Int64CursorCursorProd *) tail_1247)->field1; + IntTy x_679_847_1143 = + ((Int64Int64Int64CursorCursorProd *) tail_1247)->field2; + CursorTy x_680_848_1144 = + ((Int64Int64Int64CursorCursorProd *) tail_1247)->field3; + CursorTy x_681_849_1145 = + ((Int64Int64Int64CursorCursorProd *) tail_1247)->field4; + unsigned char wildcard_687_850_1146 = print_symbol(1192); + unsigned char wildcard_693_851_1147 = print_symbol(1193); + unsigned char y_682_852_1148 = printf("%lld", x_677_845_1141); + unsigned char wildcard_692_853_1149 = print_symbol(1193); + unsigned char y_683_854_1150 = printf("%lld", x_678_846_1142); + unsigned char wildcard_691_855_1151 = print_symbol(1193); + unsigned char y_684_856_1152 = printf("%lld", x_679_847_1143); + unsigned char wildcard_690_857_1153 = print_symbol(1193); + unsigned char y_685_858_1154 = _print_Map_v_335(x_680_848_1144); + unsigned char wildcard_689_859_1155 = print_symbol(1193); + unsigned char y_686_860_1156 = _print_Map_v_335(x_681_849_1145); + unsigned char wildcard_688_861_1157 = print_symbol(1190); + + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1246"); + exit(1); + } + } +} +CursorTy caseFn_694(IntTy x1_92_695_862_1158, IntTy k1_91_696_863_1159, + CursorTy t1_93_697_864_1160, CursorTy m1_99_698_865_1161, + IntTy k2_97_699_866_1162, IntTy x2_98_700_867_1163, + CursorTy t4_100_701_868_1164) +{ + TagTyPacked tag_1249 = *(TagTyPacked *) m1_99_698_865_1161; + CursorTy tail_1250 = m1_99_698_865_1161 + sizeof(IntTy); + + + switch_1251: + ; + switch (tag_1249) { + + case 1: + { + IntTy wildcard__144_101_869_1165 = + ((Int64Int64Int64CursorCursorProd *) tail_1250)->field0; + IntTy k3_102_870_1166 = + ((Int64Int64Int64CursorCursorProd *) tail_1250)->field1; + IntTy x3_103_871_1167 = + ((Int64Int64Int64CursorCursorProd *) tail_1250)->field2; + CursorTy t2_104_872_1168 = + ((Int64Int64Int64CursorCursorProd *) tail_1250)->field3; + CursorTy t3_105_873_1169 = + ((Int64Int64Int64CursorCursorProd *) tail_1250)->field4; + CursorTy fltAppE_944_1170 = + bin_344(k1_91_696_863_1159, x1_92_695_862_1158, t1_93_697_864_1160, t2_104_872_1168); + CursorTy fltAppE_945_1171 = + bin_344(k2_97_699_866_1162, x2_98_700_867_1163, t3_105_873_1169, t4_100_701_868_1164); + + return bin_344(k3_102_870_1166, x3_103_871_1167, fltAppE_944_1170, + fltAppE_945_1171); + break; + } + + case 0: + { + return empty_343(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1249"); + exit(1); + } + } +} +CursorTy caseFn_702(IntTy x1_77_703_874_1172, IntTy k1_76_704_875_1173, + CursorTy t4_79_705_876_1174, CursorTy m1_85_706_877_1175, + IntTy k2_82_707_878_1176, IntTy x2_83_708_879_1177, + CursorTy t1_84_709_880_1178) +{ + TagTyPacked tag_1252 = *(TagTyPacked *) m1_85_706_877_1175; + CursorTy tail_1253 = m1_85_706_877_1175 + sizeof(IntTy); + + + switch_1254: + ; + switch (tag_1252) { + + case 1: + { + IntTy wildcard__168_86_881_1179 = + ((Int64Int64Int64CursorCursorProd *) tail_1253)->field0; + IntTy k3_87_882_1180 = + ((Int64Int64Int64CursorCursorProd *) tail_1253)->field1; + IntTy x3_88_883_1181 = + ((Int64Int64Int64CursorCursorProd *) tail_1253)->field2; + CursorTy t2_89_884_1182 = + ((Int64Int64Int64CursorCursorProd *) tail_1253)->field3; + CursorTy t3_90_885_1183 = + ((Int64Int64Int64CursorCursorProd *) tail_1253)->field4; + CursorTy fltAppE_946_1184 = + bin_344(k2_82_707_878_1176, x2_83_708_879_1177, t1_84_709_880_1178, t2_89_884_1182); + CursorTy fltAppE_947_1185 = + bin_344(k1_76_704_875_1173, x1_77_703_874_1172, t3_90_885_1183, t4_79_705_876_1174); + + return bin_344(k3_87_882_1180, x3_88_883_1181, fltAppE_946_1184, + fltAppE_947_1185); + break; + } + + case 0: + { + return empty_343(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1252"); + exit(1); + } + } +} +int __main_expr() +{ + add_symbol(1188, "SUM RIGHT: "); + add_symbol(1189, "SUM LEFT: "); + add_symbol(1190, ")"); + add_symbol(1191, "(Tip_v_335"); + add_symbol(1192, "(Bin_v_335"); + add_symbol(1193, " "); + add_symbol(1194, "\n"); + + CursorTy fltAppE_886_948 = singleton_334(0, 0); + CursorTy m_37_710_949 = build(0, 10, fltAppE_886_948); + unsigned char wildcard__33_38_711_950 = print_symbol(1188); + IntTy timed_1186; + VectorTy *times_3 = vector_alloc(global_iters_param, sizeof(double)); + struct timespec begin_timed_1186; + struct timespec end_timed_1186; + + for (long long iters_timed_1186 = 0; iters_timed_1186 < global_iters_param; + iters_timed_1186++) { + if (iters_timed_1186 != global_iters_param - 1) + save_alloc_state(); + clock_gettime(CLOCK_MONOTONIC_RAW, &begin_timed_1186); + + IntTy timed_1186hack = sumRight(m_37_710_949); + + timed_1186 = timed_1186hack; + clock_gettime(CLOCK_MONOTONIC_RAW, &end_timed_1186); + if (iters_timed_1186 != global_iters_param - 1) + restore_alloc_state(); + + double itertime_0 = difftimespecs(&begin_timed_1186, &end_timed_1186); + + vector_inplace_update(times_3, iters_timed_1186, &itertime_0); + } + vector_inplace_sort(times_3, compare_doubles); + + double *tmp_4 = (double *) vector_nth(times_3, global_iters_param / 2); + double selftimed_2 = *tmp_4; + double batchtime_1 = sum_timing_array(times_3); + + print_timing_array(times_3); + printf("ITERS: %lld\n", global_iters_param); + printf("SIZE: %lld\n", global_size_param); + printf("BATCHTIME: %e\n", batchtime_1); + printf("SELFTIMED: %e\n", selftimed_2); + + unsigned char wildcard__29_40_713_952 = printf("%lld", timed_1186); + unsigned char wildcard__27_41_714_953 = print_symbol(1194); + unsigned char wildcard__25_42_715_954 = print_symbol(1189); + IntTy timed_1187; + VectorTy *times_8 = vector_alloc(global_iters_param, sizeof(double)); + struct timespec begin_timed_1187; + struct timespec end_timed_1187; + + for (long long iters_timed_1187 = 0; iters_timed_1187 < global_iters_param; + iters_timed_1187++) { + if (iters_timed_1187 != global_iters_param - 1) + save_alloc_state(); + clock_gettime(CLOCK_MONOTONIC_RAW, &begin_timed_1187); + + IntTy timed_1187hack = sumLeft(m_37_710_949); + + timed_1187 = timed_1187hack; + clock_gettime(CLOCK_MONOTONIC_RAW, &end_timed_1187); + if (iters_timed_1187 != global_iters_param - 1) + restore_alloc_state(); + + double itertime_5 = difftimespecs(&begin_timed_1187, &end_timed_1187); + + vector_inplace_update(times_8, iters_timed_1187, &itertime_5); + } + vector_inplace_sort(times_8, compare_doubles); + + double *tmp_9 = (double *) vector_nth(times_8, global_iters_param / 2); + double selftimed_7 = *tmp_9; + double batchtime_6 = sum_timing_array(times_8); + + print_timing_array(times_8); + printf("ITERS: %lld\n", global_iters_param); + printf("SIZE: %lld\n", global_size_param); + printf("BATCHTIME: %e\n", batchtime_6); + printf("SELFTIMED: %e\n", selftimed_7); + + unsigned char wildcard__21_44_717_956 = printf("%lld", timed_1187); + unsigned char wildcard__19_45_718_957 = print_symbol(1194); + + printf("'#()"); + printf("\n"); + free_symtable(); + return 0; +} \ No newline at end of file diff --git a/benchmarks/Layouts/LeftAndRight.hs b/benchmarks/Layouts/LeftAndRight.hs new file mode 100644 index 000000000..df4128aa1 --- /dev/null +++ b/benchmarks/Layouts/LeftAndRight.hs @@ -0,0 +1,34 @@ + +module LeftAndRight where +import Common +import Map + +sumRight :: Map Int -> Int +sumRight m = + case m of + Tip -> 0 + Bin _ _ v l r -> sumRight(r) + v + sumRight(l) + +sumLeft :: Map Int -> Int +sumLeft m = + case m of + Tip -> 0 + Bin _ _ v l r -> sumLeft(l) + v + sumLeft(r) + + +build :: Int -> Int -> Map Int -> Map Int +build x sz m = + if (sz == 0) then m + else (build (x - sz/2) (sz/2) (build (x + sz/2) (sz/2) (insert x x m))) + +gibbon_main = + let m = (build 0 (singleton 0 0)) + --_ = printsym (quote "SUM RIGHT: ") + s0 = iterate (sumRight m) + _ = printint (s0) + _ = printsym (quote "\n") + --_ = printsym (quote "SUM LEFT: ") + s1 = iterate (sumLeft m) + _ = printint (s1) + _ = printsym (quote "\n") + in () \ No newline at end of file diff --git a/benchmarks/Layouts/LeftAndRight.out b/benchmarks/Layouts/LeftAndRight.out new file mode 100644 index 000000000..72d3147d2 --- /dev/null +++ b/benchmarks/Layouts/LeftAndRight.out @@ -0,0 +1,13 @@ +TIMES: [0.000018] +ITERS: 1 +SIZE: 1 +BATCHTIME: 1.846400e-05 +SELFTIMED: 1.846400e-05 +0 +TIMES: [0.000016] +ITERS: 1 +SIZE: 1 +BATCHTIME: 1.567000e-05 +SELFTIMED: 1.567000e-05 +0 +'#() diff --git a/benchmarks/Layouts/Map.c b/benchmarks/Layouts/Map.c new file mode 100644 index 000000000..8a5e0dd13 --- /dev/null +++ b/benchmarks/Layouts/Map.c @@ -0,0 +1,2359 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// #include +#ifdef _WIN64 +#include +#endif +#include +#include +#include // For va_start etc +#include +#include +#include +#include +#ifdef _POINTER +#include +#endif +#ifdef _PARALLEL +#include +#include +#endif + +#define KB 1024lu +#define MB (KB * 1000lu) +#define GB (MB * 1000lu) + +#define REDIRECTION_TAG 255 +#define INDIRECTION_TAG 254 + +// Initial size of BigInfinite buffers +static long long global_init_biginf_buf_size = (4 * GB); + +// Initial size of Infinite buffers +static long long global_init_inf_buf_size = 1 * KB; + +// Maximum size of a chunk, see GitHub #110. +static long long global_inf_buf_max_chunk_size = 1 * GB; + +static long long global_size_param = 1; +static long long global_iters_param = 1; + +static char* global_benchfile_param = NULL; +static char* global_arrayfile_param = NULL; +// Number of lines in the arrayfile +static long long global_arrayfile_length_param = -1; + +// Sequential for now: +static const int num_workers = 1; + +// Count the number of regions allocated. +static long long global_region_count = 0; +static bool global_region_count_flag = false; + +#ifdef _PARALLEL +static inline void bump_global_region_count() { + __atomic_add_fetch(&global_region_count, 1, __ATOMIC_SEQ_CST); + return; +} +#else +static inline void bump_global_region_count() { + global_region_count++; + return; +} +#endif + +static inline void print_global_region_count() { + printf("REGION_COUNT: %lld\n", global_region_count); + return; +} + +#define REDIRECTION_NODE_SIZE 9 +#define MAX(a,b) (((a)>(b))?(a):(b)) +#define MIN(a,b) (((a)<(b))?(a):(b)) + +// https://www.cprogramming.com/snippets/source-code/find-the-number-of-cpu-cores-for-windows-mac-or-linux +static int get_num_processors() { +#ifdef _WIN64 + SYSTEM_INFO sysinfo; + GetSystemInfo(&sysinfo); + return sysinfo.dwNumberOfProcessors; +#else + return sysconf(_SC_NPROCESSORS_ONLN); +#endif +} + +// Requires -std=gnu11 +int dbgprintf(const char *format, ...) { + int code = 0; + va_list args; + va_start(args, format); +#ifdef _DEBUG + code = vprintf(format, args); +#endif + va_end(args); + return code; +} + + +// ----------------------------------------------------------------------------- +// Allocators +// ----------------------------------------------------------------------------- + + +// ------------------------------------- +// Bump allocation for linked-lists +// ------------------------------------- + + +#ifdef _BUMPALLOC +// #define _DEBUG +#warning "Using bump allocator." + +__thread char* bumpalloc_heap_ptr = (char*)NULL; +__thread char* bumpalloc_heap_ptr_end = (char*)NULL; + +char* saved_heap_ptr_stack[100]; +int num_saved_heap_ptr = 0; + +// For simplicity just use a single large slab: +static inline void INITBUMPALLOC() { + bumpalloc_heap_ptr = (char*)malloc(global_init_biginf_buf_size); + bumpalloc_heap_ptr_end = bumpalloc_heap_ptr + global_init_biginf_buf_size; +#ifdef _DEBUG + printf("Arena size for bump alloc: %lld\n", global_init_biginf_buf_size); + printf("BUMPALLOC/INITBUMPALLOC DONE: heap_ptr = %p\n", bumpalloc_heap_ptr); +#endif +} + +static inline void* BUMPALLOC(long long n) { + if (! bumpalloc_heap_ptr) { + INITBUMPALLOC(); + } + if (bumpalloc_heap_ptr + n < bumpalloc_heap_ptr_end) { + char* old= bumpalloc_heap_ptr; + bumpalloc_heap_ptr += n; + return old; + } else { + fprintf(stderr, "Warning: bump allocator ran out of memory."); + exit(1); + } +} + +// Snapshot the current heap pointer value across all threads. +void save_alloc_state() { + dbgprintf("Saving(%p): pos %d", heap_ptr, num_saved_heap_ptr); + saved_heap_ptr_stack[num_saved_heap_ptr] = heap_ptr; + num_saved_heap_ptr++; + dbgprintf("\n"); +} + +void restore_alloc_state() { + if(num_saved_heap_ptr <= 0) { + fprintf(stderr, "Bad call to restore_alloc_state! Saved stack empty!\ne"); + exit(1); + } + num_saved_heap_ptr--; + dbgprintf("Restoring(%p): pos %d, discarding %p", + saved_heap_ptr_stack[num_saved_heap_ptr], num_saved_heap_ptr, bumpalloc_heap_ptr); + bumpalloc_heap_ptr = saved_heap_ptr_stack[num_saved_heap_ptr]; +} + + +#else +// Regular malloc mode: +void INITBUMPALLOC() {} +void save_alloc_state() {} +void restore_alloc_state() {} + +#define BUMPALLOC(n) malloc(n) + +#endif // BUMPALLOC + + +// ------------------------------------- +// ALLOC and ALLOC_PACKED macros +// ------------------------------------- + + +/* + +If parallelism is enabled, we always use a malloc based allocator +since Boehm GC is not thread-safe in its default configuration. It can be +made thread-safe by building it with appropriate flags, but we don't do that. +Presently, all parallel pointer-based programs will leak memory. + +*/ + +#ifdef _PARALLEL +#define ALLOC(n) malloc(n) +#define ALLOC_PACKED_BIG(n) malloc(n) +char *ALLOC_COUNTED(size_t size) { + bump_global_region_count(); + return ALLOC(size); +} +#else + #ifdef _POINTER +#define ALLOC(n) GC_MALLOC(n) +#define ALLOC_PACKED_BIG(n) GC_MALLOC(n) +char *ALLOC_COUNTED(size_t size) { + bump_global_region_count(); + return GC_MALLOC(size); +} + #else +#define ALLOC(n) malloc(n) +#define ALLOC_PACKED_BIG(n) malloc(n) +char *ALLOC_COUNTED(size_t size) { + bump_global_region_count(); + return ALLOC(size); +} + #endif // _POINTER +#endif // _PARALLEL + + +// Could try alloca() here. Better yet, we could keep our own, +// separate stack and insert our own code to restore the pointer +// before any function that (may have) called ALLOC_SCOPED returns. + +// #define ALLOC_SCOPED() alloca(1024) +#define ALLOC_SCOPED(n) alloca(n) +// #define ALLOC_SCOPED() alloc_scoped() + +// Stack allocation is either too small or blows our stack. +// We need a way to make a giant stack if we want to use alloca. +// #define ALLOC_SCOPED() ALLOC(global_init_biginf_buf_size) + +// Our global pointer. No parallelism. +// static char* stack_scoped_region; +// char* alloc_scoped() { return stack_scoped_region; } + + + +// ------------------------------------- +// Basic types +// ------------------------------------- + +// Must be consistent with sizeOfTy defined in Gibbon.Language.Syntax. + +typedef unsigned char TagTyPacked; +typedef unsigned char TagTyBoxed; +typedef long long IntTy; +typedef char CharTy; +typedef float FloatTy; +typedef unsigned long long SymTy; +typedef bool BoolTy; +typedef char* PtrTy; +typedef char* CursorTy; + +// ------------------------------------- +// Arenas and dictionaries +// ------------------------------------- + +typedef struct mem_arena { + int ind; + char* mem; // TODO(vollmerm): make this a list of chunks? + void* reflist; +} mem_arena_t; + +typedef mem_arena_t* ArenaTy; + +ArenaTy alloc_arena() { + ArenaTy ar = ALLOC(sizeof(mem_arena_t)); + ar->ind = 0; + ar->mem = malloc(global_inf_buf_max_chunk_size); + ar->reflist = 0; + return ar; +} + +void free_arena(ArenaTy ar) { + free(ar->mem); + // TODO(vollmerm): free everything in ar->reflist + free(ar); +} + +CursorTy extend_arena(ArenaTy ar, int size) { + CursorTy ret = ar->mem + ar->ind; + ar->ind += size; + return ret; +} + +typedef struct dict_item { + struct dict_item * next; + int key; + void * ptrval; +} dict_item_t; + +dict_item_t * dict_alloc(ArenaTy ar) { + return (dict_item_t *) extend_arena(ar, sizeof(dict_item_t)); // ALLOC(sizeof(dict_item_t)); +} + +dict_item_t *dict_insert_ptr(ArenaTy ar, dict_item_t *ptr, SymTy key, PtrTy val) { + dict_item_t *ret = dict_alloc(ar); + ret->key = key; + ret->ptrval = val; + ret->next = ptr; + return ret; +} + +PtrTy dict_lookup_ptr(dict_item_t *ptr, SymTy key) { + while (ptr != 0) { + if (ptr->key == key) { + return ptr->ptrval; + } else { + ptr = ptr->next; + } + } + printf("Error, key %lld not found!\n",key); + exit(1); +} + +// ------------------------------------- +// Sets +// ------------------------------------- + + +struct set_elem { + int val; + UT_hash_handle hh; +}; + +typedef struct set_elem* SymSetTy; + +SymSetTy empty_set() { + return NULL; +} + +SymSetTy insert_set(SymSetTy set, int sym) { + SymSetTy s; + HASH_FIND_INT(set, &sym, s); /* sym already in the hash? */ + if (s==NULL) { + s = malloc(sizeof(struct set_elem)); + s->val = sym; + HASH_ADD_INT(set,val,s); + } + return set; +} + +BoolTy contains_set(SymSetTy set, int sym) { + SymSetTy s; + HASH_FIND_INT(set, &sym, s); + return (s!=NULL); +} + +// ------------------------------------- +// Sym Hash +// ------------------------------------- + +struct sym_hash_elem { + int key; + int val; + UT_hash_handle hh; +}; + +typedef struct sym_hash_elem* SymHashTy; + +typedef struct sym_hash_elem* IntHashTy; + +SymHashTy empty_hash() { + return NULL; +} + +SymHashTy insert_hash(SymHashTy hash, int k, int v) { + SymHashTy s; + // NOTE: not checking for duplicates! + // s = malloc(sizeof(struct sym_hash_elem)); + s = ALLOC(sizeof(struct sym_hash_elem)); + s->val = v; + s->key = k; + HASH_ADD_INT(hash,key,s); + + return hash; +} + +IntTy lookup_hash(SymHashTy hash, int k) { + SymHashTy s; + HASH_FIND_INT(hash,&k,s); + if (s==NULL) { + return k; // NOTE: return original key if val not found + // TODO(vollmerm): come up with something better to do here + } else { + return s->val; + } +} + +BoolTy contains_hash(SymHashTy hash, int sym) { + SymHashTy s; + HASH_FIND_INT(hash,&sym,s); + return (s!=NULL); +} + +// ------------------------------------- +// Helpers +// ------------------------------------- + +char* read_benchfile_param() { + if (global_benchfile_param == NULL) { + fprintf(stderr, "read_benchfile_param: benchmark input file was not set! Set using --bench-input.\n"); + exit(1); + } else + return global_benchfile_param; +} + +char* read_arrayfile_param() { + if (global_arrayfile_param == NULL) { + fprintf(stderr, "read_arrayfile_param: array input file was not set! Set using --array-input.\n"); + exit(1); + } else + return global_arrayfile_param; +} + +IntTy read_arrayfile_length_param() { + if (global_arrayfile_length_param == -1) { + fprintf(stderr, "read_arrayfile_length_param: array input file length was not set! Set using --array-input-length.\n"); + exit(1); + } else + return global_arrayfile_length_param; +} + + +// fun fact: __ prefix is actually reserved and this is an undefined behavior. +// These functions must be provided by the code generator. +int __main_expr(); + + +void show_usage(char** argv) +{ + printf("\n"); + printf("This binary was generated by the Gibbon compiler.\n"); + printf("\n"); + printf("Usage: %s [OPTS] [size] [iters]\n", argv[0]); + + printf("\n"); + printf("Options:\n"); + printf(" --buffer-size Set the buffer size (default %lld).\n", global_init_biginf_buf_size); + printf(" --bench-input Set the input file read for benchmarking. Applies only\n"); + printf(" IF the program was *compiled* with --bench-fun. \n"); + return; +} + +double avg(const double* arr, int n) +{ + double sum = 0.0; + for(int i=0; itv_sec - t0->tv_sec) + + ((double)(t1->tv_nsec - t0->tv_nsec) / 1000000000.0); +} + +int compare_doubles(const void *a, const void *b) +{ + const double *da = (const double *) a; + const double *db = (const double *) b; + return (*da > *db) - (*da < *db); +} + +// Exponentiation +IntTy expll(IntTy base, IntTy pow) { + if (base == 2) { + return (1 << pow); + } else { + IntTy i, result = 1; + for (i = 0; i < pow; i++) + result *= base; + return result; + } + } + +// ------------------------------------- +// Symbol table +// ------------------------------------- + +#define global_max_symbol_len 256 + +// Invariant: should always be equal to max(sym_table_keys) +static SymTy global_gensym_counter = 0; + +// Its value is updated by the flags parser. +static char *global_bench_prog_param; + +static SymTy newline_symbol = -1; +static SymTy space_symbol = -1; +static SymTy comma_symbol = -1; +static SymTy leftparen_symbol = -1; +static SymTy rightparen_symbol = -1; + +typedef struct SymTable_elem { + SymTy idx; /* key */ + char value[global_max_symbol_len]; + UT_hash_handle hh; /* makes this structure hashable */ +} SymTable_elem; + +// important! initialize to NULL +SymTable_elem *global_sym_table = NULL; + +void add_symbol(SymTy idx, char *value) { + struct SymTable_elem *s; + s = ALLOC(sizeof(struct SymTable_elem)); + s->idx = idx; + strcpy(s->value, value); + HASH_ADD(hh, global_sym_table, idx, sizeof(IntTy), s); + if (idx > global_gensym_counter) { + global_gensym_counter = idx; + } +} + +void set_newline(SymTy idx) { + newline_symbol = idx; + add_symbol(idx,"NEWLINE"); +} + +void set_space(SymTy idx) { + space_symbol = idx; + add_symbol(idx,"SPACE"); +} + +void set_comma(SymTy idx) { + comma_symbol = idx; + add_symbol(idx,"COMMA"); +} + +void set_leftparen(SymTy idx) { + leftparen_symbol = idx; + add_symbol(idx,"LEFTPAREN"); +} + +void set_rightparen(SymTy idx) { + rightparen_symbol = idx; + add_symbol(idx,"RIGHTPAREN"); +} + +IntTy print_symbol(SymTy idx) { + if (idx == comma_symbol) { + return printf(","); + } else if (idx == newline_symbol) { + return printf("\n"); + } else if (idx == space_symbol) { + return printf(" "); + } else if (idx == leftparen_symbol) { + return printf("("); + } else if (idx == rightparen_symbol) { + return printf(")"); + } else { + struct SymTable_elem *s; + HASH_FIND(hh, global_sym_table, &idx, sizeof(SymTy), s); + if (s == NULL) { + return printf("%lld", idx); + } else { + return printf("%s", s->value); + } + + } +} + +#ifdef _PARALLEL +SymTy gensym() { + SymTy idx = __atomic_add_fetch(&global_gensym_counter, 1, __ATOMIC_SEQ_CST); + return idx; +} +#else +SymTy gensym() { + global_gensym_counter += 1; + SymTy idx = global_gensym_counter; + return idx; +} +#endif + +void free_symtable() { + struct SymTable_elem *elt, *tmp; + HASH_ITER(hh, global_sym_table, elt, tmp) { + HASH_DEL(global_sym_table,elt); + } + free(elt); + free(tmp); +} + +/* + +---------------------------------------- +Garbage collection +---------------------------------------- + + Gibbon has "growing regions" i.e each logical region is backed by a doubly linked-list + of smaller chunks which grows as required. In addition to actual data, each chunk + stores some additional metadata (RegionFooter) to chain the chunks together in a list + and for garbage collection. The footer: + + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + serialized data | rf_reg_metadata_ptr | rf_seq_no | rf_size | rf_next | rf_prev + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + The metadata after the serialized data serves various purposes: + + - rf_reg_metadata_ptr: A pointer to a RegionTy struct that contains various metadata. + Of particular interest to us are the fields: + + = reg_id: A unique identifier for a region. + + = refcount and outset: Whenever an inter-region indirection is created, we record that information + using these two fields. Suppose we have an indirection from region A that points to some chunk + in region B. Then A's outset will store a pointer to that chunk's footer, and B's refcount will + be bumped by 1. Note that all there's only 1 refcount cell, and 1 outset per logical region, + and chunks only store a pointer to them. + + - rf_seq_no: The index of this particular chunk in the list. + + - rf_size: Used during bounds checking to calculate the size of the next region in + the linked list. + + - rf_next / rf_prev: Point to the next and previous chunk respectively. + + +There are two ways in which a region may be freed: + +(1) Whenever it goes out of scope + + The RTS tries to free a region whenever it goes out of scope. But this doesn't always succeed as + regions sometimes contain values that "escape". One reason why this'll happen is if there's an + indirection from A->B, and A lives longer than B. + In such a case, when B goes out of scope it's refcount won't be 0, and the RTS won't free it. + This brings us to (2). + +(2) + + When the RTS successfully frees a region, it decrements the refcounts of all the regions it + points to (via the outset). At the same time, if it encounters a region in the outset whoose + refcount becomes 0 after the decrement, it calls free_region on that. This way we can be sure + that all regions will eventually be garbage collected before the program exits. + + + +Why is it a doubly linked-list? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Due to way that bounds-checking works, the pointers in the outset may actually point to any +arbitrary chunk in the chain. However, we must call free_region on the first one to ensure that +all of them are GC'd. So we need pointers to traverse backward get to the first one. +'trav_to_first_chunk' accomplishes this. + + */ + +#define MAX_OUTSET_LENGTH 10 + +typedef struct RegionTy_struct { + SymTy reg_id; + uint reg_refcount; + CursorTy reg_heap; + uint reg_outset_len; + CursorTy reg_outset[MAX_OUTSET_LENGTH]; +} RegionTy; + +typedef struct RegionFooter_struct { + RegionTy *rf_reg_metadata_ptr; + + IntTy rf_seq_no; + IntTy rf_size; + struct RegionFooter_struct *rf_next; + struct RegionFooter_struct *rf_prev; +} RegionFooter; + +typedef struct ChunkTy_struct { + CursorTy chunk_start; + CursorTy chunk_end; +} ChunkTy; + +static inline void insert_into_outset(CursorTy ptr, RegionTy *reg) { + uint outset_len = reg->reg_outset_len; + // Check for duplicates. + for (uint i = 0; i < outset_len; i++) { + if (ptr == reg->reg_outset[i]) { + return; + } + } + // Otherwise, insert into the outset. + reg->reg_outset[outset_len] = ptr; + reg->reg_outset_len = outset_len + 1; + return; +} + +static inline void remove_from_outset(CursorTy ptr, RegionTy *reg) { + uint outset_len = reg->reg_outset_len; + CursorTy *outset = reg->reg_outset; + int i; + if (outset_len == 0) { + fprintf(stderr, "remove_from_outset: empty outset\n"); + exit(1); + } + // Position of 'ptr' in the outset. + int elt_idx = -1; + for (i = 0; i < outset_len; i++) { + if (ptr == outset[i]) { + elt_idx = i; + } + } + if (elt_idx == -1) { + fprintf(stderr, "remove_from_outset: element not found\n"); + exit(1); + } + // Move all elements ahead of 'elt_idx' back by one position. + for (i = elt_idx; i < outset_len; i++) { + outset[i] = outset[i+1]; + } + return; +} + +RegionTy *alloc_region(IntTy size) { + // Allocate the region metadata. + RegionTy *reg = ALLOC(sizeof(RegionTy)); + if (reg == NULL) { + printf("alloc_region: allocation failed: %ld", sizeof(RegionTy)); + exit(1); + } + + // Allocate the first chunk. + IntTy total_size = size + sizeof(RegionFooter); + CursorTy heap = ALLOC_PACKED_BIG(total_size); + if (heap == NULL) { + printf("alloc_region: malloc failed: %lld", total_size); + exit(1); + } + // Not heap+total_size, since we must keep space for the footer. + CursorTy heap_end = heap + size; + + // Initialize metadata fields. + reg->reg_id = gensym(); + reg->reg_refcount = 1; + reg->reg_heap = heap; + reg->reg_outset_len = 0; + +#ifdef _DEBUG + printf("Allocated a region(%lld): %lld bytes.\n", reg->reg_id, size); +#endif + + // Write the footer. + RegionFooter *footer = (RegionFooter *) heap_end; + footer->rf_reg_metadata_ptr = reg; + footer->rf_seq_no = 1; + footer->rf_size = size; + footer->rf_next = NULL; + footer->rf_prev = NULL; + + return reg; +} + +RegionTy *alloc_counted_region(IntTy size) { + // Bump the count. + bump_global_region_count(); + return alloc_region(size); +} + +ChunkTy alloc_chunk(CursorTy end_old_chunk) { + // Get size from current footer. + RegionFooter *footer = (RegionFooter *) end_old_chunk; + IntTy newsize = footer->rf_size * 2; + // See #110. + if (newsize > global_inf_buf_max_chunk_size) { + newsize = global_inf_buf_max_chunk_size; + } + IntTy total_size = newsize + sizeof(RegionFooter); + + // Allocate. + CursorTy start = ALLOC_PACKED_BIG(total_size); + if (start == NULL) { + printf("alloc_chunk: malloc failed: %lld", total_size); + exit(1); + } + CursorTy end = start + newsize; + + // Link the next chunk's footer. + footer->rf_next = (RegionFooter *) end; + + // Write the footer. + RegionFooter* new_footer = (RegionFooter *) end; + new_footer->rf_reg_metadata_ptr = footer->rf_reg_metadata_ptr; + new_footer->rf_seq_no = footer->rf_seq_no + 1; + new_footer->rf_size = newsize; + new_footer->rf_next = NULL; + new_footer->rf_prev = footer; + +#ifdef _DEBUG + RegionTy *reg = (RegionTy*) new_footer->rf_reg_metadata_ptr; + printf("alloc_chunk: allocated %lld bytes for region %lld.\n", total_size, reg->reg_id); +#endif + + return (ChunkTy) {start , end}; +} + +RegionFooter* trav_to_first_chunk(RegionFooter *footer) { + if (footer->rf_seq_no == 1) { + return footer; + } else if (footer->rf_prev == NULL) { + fprintf(stderr, "No previous chunk found at rf_seq_no: %lld", footer->rf_seq_no); + return NULL; + } else { + trav_to_first_chunk((RegionFooter *) footer->rf_prev); + } + return NULL; +} + +uint get_ref_count(CursorTy end_ptr) { + RegionFooter *footer = (RegionFooter *) end_ptr; + RegionTy *reg = (RegionTy *) footer->rf_reg_metadata_ptr; + return reg->reg_refcount; +} + +// B is the pointer, and A is the pointee (i.e B -> A). +// Bump A's refcount and update B's outset. +static inline void bump_ref_count(CursorTy end_b, CursorTy end_a) { + // Grab footers. + RegionFooter *footer_a = (RegionFooter *) end_a; + RegionFooter *footer_b = (RegionFooter *) end_b; + + // Grab metadata. + RegionTy *reg_a = (RegionTy *) footer_a->rf_reg_metadata_ptr; + RegionTy *reg_b = (RegionTy *) footer_b->rf_reg_metadata_ptr; + + // Bump A's refcount. + uint current_refcount, new_refcount; + current_refcount = reg_a->reg_refcount; + new_refcount = current_refcount + 1; + reg_a->reg_refcount = new_refcount; + +#ifdef _DEBUG + printf("bump_ref_count: %lld -> %lld\n", reg_b->reg_id, reg_a->reg_id); + printf("bump_ref_count: old-refcount=%d, old-outset-len=%d:\n", current_refcount, reg_b->reg_outset_len); + assert(current_refcount == reg_b->reg_outset_len+1); +#endif + + // Add A to B's outset. + insert_into_outset(end_a, reg_b); + +#ifdef _DEBUG + // printf("bump_ref_count: Added %p to %lld's outset, %p.\n", end_a, reg_b->reg_id, reg_b); + printf("bump_ref_count: new-refcount=%d, new-outset-len=%d\n", new_refcount, reg_b->reg_outset_len); + assert(new_refcount == reg_b->reg_outset_len+1); +#endif + + return; +} + +void free_region(CursorTy end_reg) { + // Grab footer and the metadata. + RegionFooter *footer = (RegionFooter *) end_reg; + RegionTy *reg = (RegionTy *) footer->rf_reg_metadata_ptr; + + // + RegionFooter *first_chunk_footer, *next_chunk_footer; + CursorTy first_chunk, next_chunk; + + // Decrement current reference count. + uint current_refcount, new_refcount; + current_refcount = reg->reg_refcount; + new_refcount = 0; + if (current_refcount != 0) { + new_refcount = current_refcount - 1; + reg->reg_refcount = new_refcount; + } + +#ifdef _DEBUG + printf("free_region(%lld): refcounts (1): old-refcount=%d, new-refcount=%d:\n", reg->reg_id, current_refcount, new_refcount); +#endif + + + // Free this region recount is 0. + if (new_refcount == 0) { + +#ifdef _DEBUG + printf("free_region(%lld): outset length: %d\n", reg->reg_id, reg->reg_outset_len); +#endif + + // Decrement refcounts, free regions with refcount==0 and also free + // elements of the outset. + if (reg->reg_outset_len != 0) { + uint outset_len = reg->reg_outset_len; + CursorTy *outset = reg->reg_outset; + RegionFooter *elt_footer; + RegionTy *elt_reg; + uint elt_current_refcount, elt_new_refcount; + CursorTy to_be_removed[MAX_OUTSET_LENGTH]; + uint to_be_removed_idx = 0; + for (int i = 0; i < outset_len; i++) { + elt_footer = (RegionFooter *) outset[i]; + elt_reg = (RegionTy *) elt_footer->rf_reg_metadata_ptr; +#ifdef _DEBUG + elt_current_refcount = elt_reg->reg_refcount; +#endif + elt_new_refcount = elt_current_refcount - 1; + elt_reg->reg_refcount = elt_new_refcount; +#ifdef _DEBUG + printf("free_region(%lld): old-refcount=%d, new-refcount=%d:\n", + elt_reg->reg_id, elt_current_refcount, elt_reg->reg_refcount); +#endif + if (elt_new_refcount == 0) { + // See [Why is it a doubly linked-list?] above + first_chunk_footer = trav_to_first_chunk(elt_footer); + if (first_chunk_footer != NULL) { + free_region((CursorTy) first_chunk_footer); + } + } + to_be_removed[to_be_removed_idx] = outset[i]; + to_be_removed_idx++; + } + // Remove elements from the outset. + for (uint i = 0; i < to_be_removed_idx; i++) { + remove_from_outset(to_be_removed[i], reg); + } + } + + +#ifdef _DEBUG + // Bookkeeping + IntTy num_freed_chunks = 0, total_bytesize = 0; +#endif + + // Free the chunks in this region. + first_chunk = end_reg - footer->rf_size; + first_chunk_footer = footer; + next_chunk = (char*) footer->rf_next; + +#ifdef _DEBUG + printf("free_region(%lld)\n", reg->reg_id); +#endif + +#ifdef _DEBUG + num_freed_chunks++; + total_bytesize = total_bytesize + first_chunk_footer->rf_size; +#endif + free(first_chunk); + + while (next_chunk != NULL) { + next_chunk_footer = (RegionFooter *) next_chunk; + #ifdef _DEBUG + num_freed_chunks++; + total_bytesize = total_bytesize + next_chunk_footer->rf_size; + #endif + free(next_chunk - next_chunk_footer->rf_size); + next_chunk = (char*) next_chunk_footer->rf_next; + } + +#ifdef _DEBUG + printf("free_region(%lld): Freed %lld bytes across %lld chunks.\n", + reg->reg_id, total_bytesize, num_freed_chunks); +#endif + + // Free the metadata. + free(reg); + + } else { +#ifdef _DEBUG + printf("free_region(%lld): non-zero refcount: %d.\n", + reg->reg_id, reg->reg_refcount); +#endif + } +} + +// Assume that all nodes with size information have tags >= 150. +BoolTy is_big(IntTy i, CursorTy cur) { + TagTyPacked tag = *(TagTyPacked *) cur; + if (tag >= 150) { + cur += 1; + IntTy size = *(IntTy *) cur; + if (size >= i) { + return true; + } else { + return false; + } + } + return false; +} + +// ------------------------------------- +// Vectors +// ------------------------------------- + +typedef struct VectorTy_struct { + // Bounds on the vector. + IntTy vec_lower, vec_upper; + + // Size of each element. + IntTy vec_elt_size; + + // Actual elements of the vector. + void* vec_data; +} VectorTy; + +VectorTy* vector_alloc(IntTy num, IntTy elt_size) { + VectorTy *vec = ALLOC(sizeof(VectorTy)); + if (vec == NULL) { + printf("alloc_vector: malloc failed: %ld", sizeof(VectorTy)); + exit(1); + } + void* data = ALLOC(num * elt_size); + if (data == NULL) { + printf("alloc_vector: malloc failed: %ld", sizeof(num * elt_size)); + exit(1); + } + vec->vec_lower = 0; + vec->vec_upper = num; + vec->vec_elt_size = elt_size; + vec->vec_data = data; + return vec; +} + +IntTy vector_length(VectorTy *vec) { + return (vec->vec_upper - vec->vec_lower); +} + +BoolTy vector_is_empty(VectorTy *vec) { + return (vector_length(vec) == 0); +} + +VectorTy* vector_slice(IntTy i, IntTy n, VectorTy *vec) { + IntTy lower = vec->vec_lower + i; + IntTy upper = vec->vec_lower + i + n; + if ((lower > vec->vec_upper)) { + printf("vector_slice: lower out of bounds, %lld > %lld", lower, vec->vec_upper); + exit(1); + } + if ((upper > vec->vec_upper)) { + printf("vector_slice: upper out of bounds: %lld > %lld", upper, vec->vec_upper); + exit(1); + } + VectorTy *vec2 = ALLOC(sizeof(VectorTy)); + if (vec == NULL) { + printf("vector_slice: malloc failed: %ld", sizeof(VectorTy)); + exit(1); + } + vec2->vec_lower = lower; + vec2->vec_upper = upper; + vec2->vec_elt_size = vec->vec_elt_size; + vec2->vec_data = vec->vec_data; + return vec2; +} + +// The callers must cast the return value. +static inline void* vector_nth(VectorTy *vec, IntTy i) { + // if (i < vec->lower || i > vec->upper) { + // printf("vector_nth index out of bounds: %lld (%lld,%lld) \n", i, vec->vec_lower, vec->vec_upper); + // exit(1); + // } + return (vec->vec_data + (vec->vec_elt_size * (vec->vec_lower + i))); +} + +static inline VectorTy* vector_inplace_update(VectorTy *vec, IntTy i, void* elt) { + void* dst = vector_nth(vec, i); + memcpy(dst, elt, vec->vec_elt_size); + return vec; +} + +static inline VectorTy* vector_copy(VectorTy *vec) { + IntTy len = vector_length(vec); + void *start = vector_nth(vec, 0); + VectorTy *vec2 = vector_alloc(len, vec->vec_elt_size); + memcpy(vec2->vec_data, start, len * vec->vec_elt_size); + return vec2; +} + +static inline VectorTy* vector_inplace_sort(VectorTy *vec, int (*compar)(const void *, const void*)) { + void *start = vector_nth(vec, 0); + qsort(start, vector_length(vec), vec->vec_elt_size, compar); + return vec; +} + +static inline VectorTy* vector_sort(VectorTy *vec, int (*compar)(const void *, const void*)) { + VectorTy *vec2 = vector_copy(vec); + vector_inplace_sort(vec2, compar); + return vec2; +} + +static inline VectorTy* vector_concat(VectorTy *vec) { + // Length of the input vector. + IntTy len = vector_length(vec); + // Length of the concatenated vector. + IntTy result_len = 0; + // Size of each element in the concatenated vector. + IntTy result_elt_size = 0; + VectorTy **elt_ref, *elt; + for (IntTy i = 0; i < len; i++) { + elt_ref = vector_nth(vec, i); + elt = *elt_ref; + result_elt_size = elt->vec_elt_size; + result_len += vector_length(elt); + } + + // Concatenated vector. + VectorTy *result = vector_alloc(result_len, result_elt_size); + IntTy elt_len; + // A counter that tracks the index of elements in 'result'. + IntTy k = 0; + for (IntTy i = 0; i < len; i++) { + elt_ref = vector_nth(vec, i); + elt = *elt_ref; + elt_len = vector_length(elt); + + for (IntTy j = 0; j < elt_len; j++) { + void* k_elt = vector_nth(elt, j); + vector_inplace_update(result, k, k_elt); + k++; + } + } + + return result; +} + +static inline void vector_free(VectorTy *vec) { + free(vec->vec_data); + free(vec); + return; +} + +static inline VectorTy* vector_merge(VectorTy *vec1, VectorTy *vec2) { + if (vec1->vec_upper != vec2->vec_lower) { + printf("vector_merge: non-contiguous slices, (%lld,%lld), (%lld,%lld).", + vec1->vec_lower, vec1->vec_upper, vec2->vec_lower, vec2->vec_upper); + exit(1); + } + VectorTy *merged = ALLOC(sizeof(VectorTy)); + if (merged == NULL) { + printf("vector_merge: malloc failed: %ld", sizeof(VectorTy)); + exit(1); + } + merged->vec_lower = vec1->vec_lower; + merged->vec_upper = vec2->vec_upper; + merged->vec_elt_size = vec1->vec_elt_size; + merged->vec_data = vec1->vec_data; + return merged; +} + +void print_timing_array(VectorTy *times) { + printf("TIMES: ["); + double *d; + IntTy n = vector_length(times); + for(int i = 0; i < n; i++) { + d = vector_nth(times, i); + if (i == (n-1)) { + printf("%f",*d); + } + else { + printf("%f, ",*d); + } + } + printf("]\n"); +} + +double sum_timing_array(VectorTy *times) { + double *d; + double acc = 0; + for(int i = 0; i < vector_length(times); i++) { + d = vector_nth(times, i); + acc += *d; + } + return acc; +} + +// ------------------------------------- +// Linked lists +// ------------------------------------- + +typedef struct ListTy_struct { + IntTy ll_data_size; + void* ll_data; + struct ListTy_struct* ll_next; +} ListTy; + +static inline ListTy* list_alloc(IntTy data_size) { + // ListTy *ls = ALLOC(sizeof(ListTy)); + ListTy *ls = BUMPALLOC(sizeof(ListTy)); + ls->ll_data_size = data_size; + ls->ll_data = NULL; + ls->ll_next = NULL; + return ls; +} + +static inline BoolTy list_is_empty(ListTy *ls) { + return ls->ll_next == NULL; +} + +static inline ListTy* list_cons(void* elt, ListTy *ls) { + // void* data = ALLOC(ls->data_size); + void* data = BUMPALLOC(ls->ll_data_size); + if (data == NULL) { + printf("list_cons: malloc failed: %lld", ls->ll_data_size); + exit(1); + } + memcpy(data, elt, ls->ll_data_size); + // ListTy *res = ALLOC(sizeof(ListTy)); + ListTy *res = BUMPALLOC(sizeof(ListTy)); + res->ll_data_size = ls->ll_data_size; + res->ll_data = data; + res->ll_next = (ListTy*) ls; + return res; +} + +static inline void* list_head(ListTy *ls) { + return ls->ll_data; +} + +static inline ListTy* list_tail(ListTy *ls) { + return ls->ll_next; +} + +static inline void list_free(ListTy *ls) { + free(ls->ll_data); + free(ls); + return; +} + +static inline ListTy* list_copy(ListTy *ls) { + ListTy *ls2 = list_alloc(ls->ll_data_size); + if (ls->ll_data != NULL) { + void* data = BUMPALLOC(ls->ll_data_size); + memcpy(data, ls->ll_data, ls->ll_data_size); + ls2->ll_data = data; + } + ls2->ll_next = ls->ll_next; + return ls2; +} + +// ------------------------------------- +// Ppm Images +// ------------------------------------- + +typedef struct __Pixel_struct { + IntTy field0; + IntTy field1; + IntTy field2; +} __Pixel; + +void writePpm(char* filename, IntTy width, IntTy height, VectorTy *pixels); +void writePpm_loop(FILE *fp, IntTy idx, IntTy end, VectorTy *pixels); + +// Example: writePpm("gibbon_rgb_1000.ppm", 1000, 1000, pixels); +void writePpm(char* filename, IntTy width, IntTy height, VectorTy *pixels) +{ + FILE *fp; + fp = fopen(filename, "w+"); + fprintf(fp, "P3\n"); + fprintf(fp, "%lld %lld\n255\n", width, height); + IntTy len = vector_length(pixels); + writePpm_loop(fp, 0, len, pixels); + fclose(fp); + return; +} + +void writePpm_loop(FILE *fp, IntTy idx, IntTy end, VectorTy *pixels) +{ + BoolTy fltIf_5768_6575 = idx == end; + + if (fltIf_5768_6575) { + return; + } else { + __Pixel *tmp_112; + tmp_112 = (__Pixel *) vector_nth(pixels, idx); + __Pixel tup = *tmp_112; + IntTy x = tup.field0; + IntTy y = tup.field1; + IntTy z = tup.field2; + // write to file. + fprintf(fp, "%lld %lld %lld\n", x, y, z); + writePpm_loop(fp, (idx+1), end, pixels); + } +} + +/* -------------------------------------------------------------------------------- */ + +int main(int argc, char** argv) +{ + // parameters to parse: + // + // num iterations: How many times to repeat a benchmark. + // tree size: An integer passes to `build_tree()`. + + struct rlimit lim; + int code; + if ( (code = getrlimit(RLIMIT_STACK, &lim)) ) { + fprintf(stderr, " [gibbon rts] failed to getrlimit, code %d\n", code); + exit(1); + } + + // lim.rlim_cur = 1024LU * 1024LU * 1024LU; // 1GB stack. + lim.rlim_cur = 512LU * 1024LU * 1024LU; // 500MB stack. + // lim.rlim_max = lim.rlim_cur; // Normal users may only be able to decrease this. + + // WARNING: Haven't yet figured out why this doesn't work on MacOS... +#ifndef __APPLE__ + code = setrlimit(RLIMIT_STACK, &lim); + while (code) { + fprintf(stderr, " [gibbon rts] Failed to set stack size to %llu, code %d\n", (unsigned long long)lim.rlim_cur, code); + lim.rlim_cur /= 2; + // lim.rlim_max /= 2; + if(lim.rlim_cur < 100 * 1024) { + fprintf(stderr, " [gibbon rts] Failed setrlimit stack size to something reasonable; giving up.\n"); + break; // abort(); + } + int code = setrlimit(RLIMIT_STACK, &lim); + } +#endif + + int got_numargs = 0; // How many numeric arguments have we got. + + int i; + for (i = 1; i < argc; ++i) + { + if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) { + show_usage(argv); + exit(0); + } + else if (strcmp(argv[i], "--biginf-buffer-size") == 0 && i < argc - 1) + { + global_init_biginf_buf_size = atoll(argv[i + 1]); + i++; + } + else if (strcmp(argv[i], "--inf-buffer-size") == 0 && i < argc - 1) + { + global_init_inf_buf_size = atoll(argv[i + 1]); + i++; + } + else if ((strcmp(argv[i], "--bench-input") == 0)) { + if (i+1 >= argc) { + fprintf(stderr, "Not enough arguments after --bench-input, expected .\n"); + show_usage(argv); + exit(1); + } + global_benchfile_param = argv[i+1]; + i++; + } + else if ((strcmp(argv[i], "--array-input") == 0)) { + if (i+1 >= argc) { + fprintf(stderr, "Not enough arguments after --array-input, expected .\n"); + show_usage(argv); + exit(1); + } + global_arrayfile_param = argv[i+1]; + i++; + } + else if (strcmp(argv[i], "--array-input-length") == 0 && i < argc - 1) { + global_arrayfile_length_param = atoll(argv[i+1]); + i++; + } + else if (strcmp(argv[i], "--bench-prog") == 0 && i < argc - 1) { + int len = strlen(argv[i+1]); + global_bench_prog_param = (char*) malloc((len+1)*sizeof(char)); + strncpy(global_bench_prog_param,argv[i+1],len); + i++; + } + // If present, we expect the two arguments to be + else if (got_numargs >= 2) { + fprintf(stderr, "Extra arguments left over: "); + for(; i < argc; i++) fprintf(stderr, "%s ", argv[i]); + show_usage(argv); + exit(1); + } else { + if (got_numargs == 0) { + global_size_param = atoll(argv[i]); + got_numargs ++; + } else { + global_iters_param = atoll(argv[i]); + } + } + } + + // Initialize global_bench_prog_param to an empty string in case + // the runtime argument --bench-prog isn't passed. + if (global_bench_prog_param == NULL) { + global_bench_prog_param = (char*) malloc(1*sizeof(char)); + *global_bench_prog_param = '\n'; + } + + __main_expr(); + + return 0; +} + +// ----------------------------------------------------------------------------- +// Program starts here +// ----------------------------------------------------------------------------- + +typedef struct Prod_struct { } Prod; +typedef struct Int64Prod_struct { + IntTy field0; + } Int64Prod; +typedef struct Int64Int64Int64VectorCursorCursorProd_struct { + IntTy field0; + IntTy field1; + IntTy field2; + VectorTy *field3; + CursorTy field4; + CursorTy field5; + } Int64Int64Int64VectorCursorCursorProd; +typedef struct Int64Int64VectorCursorCursorProd_struct { + IntTy field0; + IntTy field1; + VectorTy *field2; + CursorTy field3; + CursorTy field4; + } Int64Int64VectorCursorCursorProd; +typedef struct BoolProd_struct { + BoolTy field0; + } BoolProd; +typedef struct TagCursorProd_struct { + TagTyPacked field0; + CursorTy field1; + } TagCursorProd; +typedef struct CursorProd_struct { + CursorTy field0; + } CursorProd; +typedef struct VectorProd_struct { + VectorTy *field0; + } VectorProd; +IntTy ratio(); +IntTy delta(); +CursorTy singleton_480(IntTy k_344_858_1098, VectorTy *x_345_859_1099); +IntTy size_482(CursorTy m_330_860_1102); +CursorTy singleL_488(IntTy k1_248_866_1108, VectorTy *x1_249_867_1109, + CursorTy t1_250_868_1110, CursorTy m_251_869_1111); +CursorTy doubleL_489(IntTy k1_219_875_1118, VectorTy *x1_220_876_1119, + CursorTy t1_221_877_1120, CursorTy m0_222_878_1121); +CursorTy rotateL_483(IntTy k_273_884_1127, VectorTy *x_274_885_1128, + CursorTy l_275_886_1129, CursorTy r_276_887_1130); +CursorTy bin_487(IntTy k_258_893_1141, VectorTy *x_259_894_1142, + CursorTy l_260_895_1143, CursorTy r_261_896_1144); +CursorTy singleR_485(IntTy k1_238_897_1149, VectorTy *x1_239_898_1150, + CursorTy m_240_899_1151, CursorTy t3_241_900_1152); +CursorTy doubleR_486(IntTy k1_204_906_1159, VectorTy *x1_205_907_1160, + CursorTy m0_206_908_1161, CursorTy t4_207_909_1162); +CursorTy rotateR_484(IntTy k_263_915_1168, VectorTy *x_264_916_1169, + CursorTy l_265_917_1170, CursorTy r_266_918_1171); +CursorTy balance_481(IntTy k_283_924_1182, VectorTy *x_284_925_1183, + CursorTy l_285_926_1184, CursorTy r_286_927_1185); +CursorTy insert_478(IntTy kx_288_928_1206, VectorTy *x_289_929_1207, + CursorTy m_290_930_1208); +CursorTy empty_477(); +CursorTy _copy_without_ptrs_Map_v_479(CursorTy arg_786_936_1218); +CursorTy _copy_Map_v_479(CursorTy arg_775_947_1229); +unsigned char _traverse_Map_v_479(CursorTy arg_797_958_1240); +unsigned char _print_Map_v_479(CursorTy arg_808_966_1248); +CursorTy caseFn_828(VectorTy *x1_220_829_986_1268, IntTy k1_219_830_987_1269, + CursorTy t1_221_831_988_1270, CursorTy m1_227_832_989_1271, + IntTy k2_225_833_990_1272, VectorTy *x2_226_834_991_1273, + CursorTy t4_228_835_992_1274); +CursorTy caseFn_836(VectorTy *x1_205_837_998_1282, IntTy k1_204_838_999_1283, + CursorTy t4_207_839_1000_1284, + CursorTy m1_213_840_1001_1285, IntTy k2_210_841_1002_1286, + VectorTy *x2_211_842_1003_1287, + CursorTy t1_212_843_1004_1288); +IntTy ratio() +{ + return 2; +} +IntTy delta() +{ + return 4; +} +CursorTy singleton_480(IntTy k_344_858_1098, VectorTy *x_345_859_1099) +{ + PtrTy fltPkd_1024_1100 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_1024_1100)->field0 = 0; + + PtrTy fltPkd_1025_1101 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_1025_1101)->field0 = 0; + + PtrTy tailift_1302 = ALLOC(sizeof(Int64Int64Int64VectorCursorCursorProd)); + + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1302)->field0 = 1; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1302)->field1 = 1; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1302)->field2 = + k_344_858_1098; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1302)->field3 = + x_345_859_1099; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1302)->field4 = + fltPkd_1024_1100; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1302)->field5 = + fltPkd_1025_1101; + return tailift_1302; +} +IntTy size_482(CursorTy m_330_860_1102) +{ + TagTyPacked tag_1303 = *(TagTyPacked *) m_330_860_1102; + CursorTy tail_1304 = m_330_860_1102 + sizeof(IntTy); + + + switch_1305: + ; + switch (tag_1303) { + + case 0: + { + return 0; + break; + } + + case 1: + { + IntTy sz_332_861_1103 = + ((Int64Int64VectorCursorCursorProd *) tail_1304)->field0; + IntTy wildcard__18_333_862_1104 = + ((Int64Int64VectorCursorCursorProd *) tail_1304)->field1; + VectorTy *wildcard__19_334_863_1105 = + ((Int64Int64VectorCursorCursorProd *) tail_1304)->field2; + CursorTy wildcard__20_335_864_1106 = + ((Int64Int64VectorCursorCursorProd *) tail_1304)->field3; + CursorTy wildcard__21_336_865_1107 = + ((Int64Int64VectorCursorCursorProd *) tail_1304)->field4; + + return sz_332_861_1103; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1303"); + exit(1); + } + } +} +CursorTy singleL_488(IntTy k1_248_866_1108, VectorTy *x1_249_867_1109, + CursorTy t1_250_868_1110, CursorTy m_251_869_1111) +{ + TagTyPacked tag_1306 = *(TagTyPacked *) m_251_869_1111; + CursorTy tail_1307 = m_251_869_1111 + sizeof(IntTy); + + + switch_1308: + ; + switch (tag_1306) { + + case 1: + { + IntTy wildcard__123_253_870_1112 = + ((Int64Int64VectorCursorCursorProd *) tail_1307)->field0; + IntTy k2_254_871_1113 = + ((Int64Int64VectorCursorCursorProd *) tail_1307)->field1; + VectorTy *x2_255_872_1114 = + ((Int64Int64VectorCursorCursorProd *) tail_1307)->field2; + CursorTy t2_256_873_1115 = + ((Int64Int64VectorCursorCursorProd *) tail_1307)->field3; + CursorTy t3_257_874_1116 = + ((Int64Int64VectorCursorCursorProd *) tail_1307)->field4; + CursorTy fltAppE_1026_1117 = + bin_487(k1_248_866_1108, x1_249_867_1109, t1_250_868_1110, t2_256_873_1115); + + return bin_487(k2_254_871_1113, x2_255_872_1114, fltAppE_1026_1117, + t3_257_874_1116); + break; + } + + case 0: + { + return empty_477(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1306"); + exit(1); + } + } +} +CursorTy doubleL_489(IntTy k1_219_875_1118, VectorTy *x1_220_876_1119, + CursorTy t1_221_877_1120, CursorTy m0_222_878_1121) +{ + TagTyPacked tag_1309 = *(TagTyPacked *) m0_222_878_1121; + CursorTy tail_1310 = m0_222_878_1121 + sizeof(IntTy); + + + switch_1311: + ; + switch (tag_1309) { + + case 1: + { + IntTy wildcard__143_224_879_1122 = + ((Int64Int64VectorCursorCursorProd *) tail_1310)->field0; + IntTy k2_225_880_1123 = + ((Int64Int64VectorCursorCursorProd *) tail_1310)->field1; + VectorTy *x2_226_881_1124 = + ((Int64Int64VectorCursorCursorProd *) tail_1310)->field2; + CursorTy m1_227_882_1125 = + ((Int64Int64VectorCursorCursorProd *) tail_1310)->field3; + CursorTy t4_228_883_1126 = + ((Int64Int64VectorCursorCursorProd *) tail_1310)->field4; + + return caseFn_828(x1_220_876_1119, k1_219_875_1118, t1_221_877_1120, + m1_227_882_1125, k2_225_880_1123, x2_226_881_1124, + t4_228_883_1126); + break; + } + + case 0: + { + return empty_477(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1309"); + exit(1); + } + } +} +CursorTy rotateL_483(IntTy k_273_884_1127, VectorTy *x_274_885_1128, + CursorTy l_275_886_1129, CursorTy r_276_887_1130) +{ + TagTyPacked tag_1312 = *(TagTyPacked *) r_276_887_1130; + CursorTy tail_1313 = r_276_887_1130 + sizeof(IntTy); + + + switch_1314: + ; + switch (tag_1312) { + + case 1: + { + IntTy wildcard__94_278_888_1131 = + ((Int64Int64VectorCursorCursorProd *) tail_1313)->field0; + IntTy wildcard__95_279_889_1132 = + ((Int64Int64VectorCursorCursorProd *) tail_1313)->field1; + VectorTy *wildcard__96_280_890_1133 = + ((Int64Int64VectorCursorCursorProd *) tail_1313)->field2; + CursorTy ly_281_891_1134 = + ((Int64Int64VectorCursorCursorProd *) tail_1313)->field3; + CursorTy ry_282_892_1135 = + ((Int64Int64VectorCursorCursorProd *) tail_1313)->field4; + IntTy fltPrm_1028_1136 = size_482(ly_281_891_1134); + IntTy fltPrm_1030_1137 = ratio(); + IntTy fltPrm_1031_1138 = size_482(ry_282_892_1135); + IntTy fltPrm_1029_1139 = fltPrm_1030_1137 * fltPrm_1031_1138; + BoolTy fltIf_1027_1140 = fltPrm_1028_1136 < fltPrm_1029_1139; + + if (fltIf_1027_1140) { + return singleL_488(k_273_884_1127, x_274_885_1128, + l_275_886_1129, r_276_887_1130); + } else { + return doubleL_489(k_273_884_1127, x_274_885_1128, + l_275_886_1129, r_276_887_1130); + } + break; + } + + case 0: + { + return empty_477(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1312"); + exit(1); + } + } +} +CursorTy bin_487(IntTy k_258_893_1141, VectorTy *x_259_894_1142, + CursorTy l_260_895_1143, CursorTy r_261_896_1144) +{ + IntTy fltPrm_1034_1145 = size_482(l_260_895_1143); + IntTy fltPrm_1035_1146 = size_482(r_261_896_1144); + IntTy fltPrm_1033_1147 = fltPrm_1034_1145 + fltPrm_1035_1146; + IntTy fltPkd_1032_1148 = fltPrm_1033_1147 + 1; + PtrTy tailift_1315 = ALLOC(sizeof(Int64Int64Int64VectorCursorCursorProd)); + + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1315)->field0 = 1; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1315)->field1 = + fltPkd_1032_1148; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1315)->field2 = + k_258_893_1141; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1315)->field3 = + x_259_894_1142; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1315)->field4 = + l_260_895_1143; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1315)->field5 = + r_261_896_1144; + return tailift_1315; +} +CursorTy singleR_485(IntTy k1_238_897_1149, VectorTy *x1_239_898_1150, + CursorTy m_240_899_1151, CursorTy t3_241_900_1152) +{ + TagTyPacked tag_1316 = *(TagTyPacked *) m_240_899_1151; + CursorTy tail_1317 = m_240_899_1151 + sizeof(IntTy); + + + switch_1318: + ; + switch (tag_1316) { + + case 1: + { + IntTy wildcard__133_243_901_1153 = + ((Int64Int64VectorCursorCursorProd *) tail_1317)->field0; + IntTy k2_244_902_1154 = + ((Int64Int64VectorCursorCursorProd *) tail_1317)->field1; + VectorTy *x2_245_903_1155 = + ((Int64Int64VectorCursorCursorProd *) tail_1317)->field2; + CursorTy t1_246_904_1156 = + ((Int64Int64VectorCursorCursorProd *) tail_1317)->field3; + CursorTy t2_247_905_1157 = + ((Int64Int64VectorCursorCursorProd *) tail_1317)->field4; + CursorTy fltAppE_1036_1158 = + bin_487(k1_238_897_1149, x1_239_898_1150, t2_247_905_1157, t3_241_900_1152); + + return bin_487(k2_244_902_1154, x2_245_903_1155, t1_246_904_1156, + fltAppE_1036_1158); + break; + } + + case 0: + { + return empty_477(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1316"); + exit(1); + } + } +} +CursorTy doubleR_486(IntTy k1_204_906_1159, VectorTy *x1_205_907_1160, + CursorTy m0_206_908_1161, CursorTy t4_207_909_1162) +{ + TagTyPacked tag_1319 = *(TagTyPacked *) m0_206_908_1161; + CursorTy tail_1320 = m0_206_908_1161 + sizeof(IntTy); + + + switch_1321: + ; + switch (tag_1319) { + + case 1: + { + IntTy wildcard__167_209_910_1163 = + ((Int64Int64VectorCursorCursorProd *) tail_1320)->field0; + IntTy k2_210_911_1164 = + ((Int64Int64VectorCursorCursorProd *) tail_1320)->field1; + VectorTy *x2_211_912_1165 = + ((Int64Int64VectorCursorCursorProd *) tail_1320)->field2; + CursorTy t1_212_913_1166 = + ((Int64Int64VectorCursorCursorProd *) tail_1320)->field3; + CursorTy m1_213_914_1167 = + ((Int64Int64VectorCursorCursorProd *) tail_1320)->field4; + + return caseFn_836(x1_205_907_1160, k1_204_906_1159, t4_207_909_1162, + m1_213_914_1167, k2_210_911_1164, x2_211_912_1165, + t1_212_913_1166); + break; + } + + case 0: + { + return empty_477(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1319"); + exit(1); + } + } +} +CursorTy rotateR_484(IntTy k_263_915_1168, VectorTy *x_264_916_1169, + CursorTy l_265_917_1170, CursorTy r_266_918_1171) +{ + TagTyPacked tag_1322 = *(TagTyPacked *) l_265_917_1170; + CursorTy tail_1323 = l_265_917_1170 + sizeof(IntTy); + + + switch_1324: + ; + switch (tag_1322) { + + case 1: + { + IntTy wildcard__106_268_919_1172 = + ((Int64Int64VectorCursorCursorProd *) tail_1323)->field0; + IntTy wildcard__107_269_920_1173 = + ((Int64Int64VectorCursorCursorProd *) tail_1323)->field1; + VectorTy *wildcard__108_270_921_1174 = + ((Int64Int64VectorCursorCursorProd *) tail_1323)->field2; + CursorTy ly_271_922_1175 = + ((Int64Int64VectorCursorCursorProd *) tail_1323)->field3; + CursorTy ry_272_923_1176 = + ((Int64Int64VectorCursorCursorProd *) tail_1323)->field4; + IntTy fltPrm_1038_1177 = size_482(ry_272_923_1176); + IntTy fltPrm_1040_1178 = ratio(); + IntTy fltPrm_1041_1179 = size_482(ly_271_922_1175); + IntTy fltPrm_1039_1180 = fltPrm_1040_1178 * fltPrm_1041_1179; + BoolTy fltIf_1037_1181 = fltPrm_1038_1177 < fltPrm_1039_1180; + + if (fltIf_1037_1181) { + return singleR_485(k_263_915_1168, x_264_916_1169, + l_265_917_1170, r_266_918_1171); + } else { + return doubleR_486(k_263_915_1168, x_264_916_1169, + l_265_917_1170, r_266_918_1171); + } + break; + } + + case 0: + { + return empty_477(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1322"); + exit(1); + } + } +} +CursorTy balance_481(IntTy k_283_924_1182, VectorTy *x_284_925_1183, + CursorTy l_285_926_1184, CursorTy r_286_927_1185) +{ + IntTy fltPrm_1044_1186 = size_482(l_285_926_1184); + IntTy fltPrm_1045_1187 = size_482(r_286_927_1185); + IntTy fltPrm_1043_1188 = fltPrm_1044_1186 + fltPrm_1045_1187; + BoolTy fltIf_1042_1189 = fltPrm_1043_1188 <= 1; + + if (fltIf_1042_1189) { + IntTy fltPrm_1047_1190 = size_482(l_285_926_1184); + IntTy fltPrm_1048_1191 = size_482(r_286_927_1185); + IntTy fltPkd_1046_1192 = fltPrm_1047_1190 + fltPrm_1048_1191; + PtrTy tailift_1325 = + ALLOC(sizeof(Int64Int64Int64VectorCursorCursorProd)); + + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1325)->field0 = 1; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1325)->field1 = + fltPkd_1046_1192; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1325)->field2 = + k_283_924_1182; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1325)->field3 = + x_284_925_1183; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1325)->field4 = + l_285_926_1184; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1325)->field5 = + r_286_927_1185; + return tailift_1325; + } else { + IntTy fltPrm_1050_1193 = size_482(r_286_927_1185); + IntTy fltPrm_1052_1194 = delta(); + IntTy fltPrm_1053_1195 = size_482(l_285_926_1184); + IntTy fltPrm_1051_1196 = fltPrm_1052_1194 * fltPrm_1053_1195; + BoolTy fltIf_1049_1197 = fltPrm_1050_1193 >= fltPrm_1051_1196; + + if (fltIf_1049_1197) { + return rotateL_483(k_283_924_1182, x_284_925_1183, l_285_926_1184, + r_286_927_1185); + } else { + IntTy fltPrm_1055_1198 = size_482(l_285_926_1184); + IntTy fltPrm_1057_1199 = delta(); + IntTy fltPrm_1058_1200 = size_482(r_286_927_1185); + IntTy fltPrm_1056_1201 = fltPrm_1057_1199 * fltPrm_1058_1200; + BoolTy fltIf_1054_1202 = fltPrm_1055_1198 >= fltPrm_1056_1201; + + if (fltIf_1054_1202) { + return rotateR_484(k_283_924_1182, x_284_925_1183, + l_285_926_1184, r_286_927_1185); + } else { + IntTy fltPrm_1060_1203 = size_482(l_285_926_1184); + IntTy fltPrm_1061_1204 = size_482(r_286_927_1185); + IntTy fltPkd_1059_1205 = fltPrm_1060_1203 + fltPrm_1061_1204; + PtrTy tailift_1326 = + ALLOC(sizeof(Int64Int64Int64VectorCursorCursorProd)); + + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1326)->field0 = + 1; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1326)->field1 = + fltPkd_1059_1205; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1326)->field2 = + k_283_924_1182; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1326)->field3 = + x_284_925_1183; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1326)->field4 = + l_285_926_1184; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1326)->field5 = + r_286_927_1185; + return tailift_1326; + } + } + } +} +CursorTy insert_478(IntTy kx_288_928_1206, VectorTy *x_289_929_1207, + CursorTy m_290_930_1208) +{ + TagTyPacked tag_1327 = *(TagTyPacked *) m_290_930_1208; + CursorTy tail_1328 = m_290_930_1208 + sizeof(IntTy); + + + switch_1330: + ; + switch (tag_1327) { + + case 0: + { + return singleton_480(kx_288_928_1206, x_289_929_1207); + break; + } + + case 1: + { + IntTy sz_292_931_1209 = + ((Int64Int64VectorCursorCursorProd *) tail_1328)->field0; + IntTy k_293_932_1210 = + ((Int64Int64VectorCursorCursorProd *) tail_1328)->field1; + VectorTy *v_294_933_1211 = + ((Int64Int64VectorCursorCursorProd *) tail_1328)->field2; + CursorTy l_295_934_1212 = + ((Int64Int64VectorCursorCursorProd *) tail_1328)->field3; + CursorTy r_296_935_1213 = + ((Int64Int64VectorCursorCursorProd *) tail_1328)->field4; + BoolTy fltIf_1062_1214 = kx_288_928_1206 == k_293_932_1210; + + if (fltIf_1062_1214) { + PtrTy tailift_1329 = + ALLOC(sizeof(Int64Int64Int64VectorCursorCursorProd)); + + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1329)->field0 = + 1; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1329)->field1 = + sz_292_931_1209; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1329)->field2 = + k_293_932_1210; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1329)->field3 = + x_289_929_1207; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1329)->field4 = + l_295_934_1212; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1329)->field5 = + r_296_935_1213; + return tailift_1329; + } else { + BoolTy fltIf_1063_1215 = kx_288_928_1206 <= k_293_932_1210; + + if (fltIf_1063_1215) { + CursorTy fltAppE_1064_1216 = + insert_478(kx_288_928_1206, x_289_929_1207, l_295_934_1212); + + return balance_481(k_293_932_1210, v_294_933_1211, + fltAppE_1064_1216, r_296_935_1213); + } else { + CursorTy fltAppE_1065_1217 = + insert_478(kx_288_928_1206, x_289_929_1207, r_296_935_1213); + + return balance_481(k_293_932_1210, v_294_933_1211, + l_295_934_1212, fltAppE_1065_1217); + } + } + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1327"); + exit(1); + } + } +} +CursorTy empty_477() +{ + PtrTy tailift_1331 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) tailift_1331)->field0 = 0; + return tailift_1331; +} +CursorTy _copy_without_ptrs_Map_v_479(CursorTy arg_786_936_1218) +{ + TagTyPacked tag_1332 = *(TagTyPacked *) arg_786_936_1218; + CursorTy tail_1333 = arg_786_936_1218 + sizeof(IntTy); + + + switch_1336: + ; + switch (tag_1332) { + + case 0: + { + PtrTy tailift_1334 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) tailift_1334)->field0 = 0; + return tailift_1334; + break; + } + + case 1: + { + IntTy x_787_937_1219 = + ((Int64Int64VectorCursorCursorProd *) tail_1333)->field0; + IntTy x_788_938_1220 = + ((Int64Int64VectorCursorCursorProd *) tail_1333)->field1; + VectorTy *x_789_939_1221 = + ((Int64Int64VectorCursorCursorProd *) tail_1333)->field2; + CursorTy x_790_940_1222 = + ((Int64Int64VectorCursorCursorProd *) tail_1333)->field3; + CursorTy x_791_941_1223 = + ((Int64Int64VectorCursorCursorProd *) tail_1333)->field4; + CursorTy y_795_945_1227 = + _copy_without_ptrs_Map_v_479(x_790_940_1222); + CursorTy y_796_946_1228 = + _copy_without_ptrs_Map_v_479(x_791_941_1223); + PtrTy tailift_1335 = + ALLOC(sizeof(Int64Int64Int64VectorCursorCursorProd)); + + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1335)->field0 = + 1; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1335)->field1 = + x_787_937_1219; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1335)->field2 = + x_788_938_1220; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1335)->field3 = + x_789_939_1221; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1335)->field4 = + y_795_945_1227; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1335)->field5 = + y_796_946_1228; + return tailift_1335; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1332"); + exit(1); + } + } +} +CursorTy _copy_Map_v_479(CursorTy arg_775_947_1229) +{ + TagTyPacked tag_1337 = *(TagTyPacked *) arg_775_947_1229; + CursorTy tail_1338 = arg_775_947_1229 + sizeof(IntTy); + + + switch_1341: + ; + switch (tag_1337) { + + case 0: + { + PtrTy tailift_1339 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) tailift_1339)->field0 = 0; + return tailift_1339; + break; + } + + case 1: + { + IntTy x_776_948_1230 = + ((Int64Int64VectorCursorCursorProd *) tail_1338)->field0; + IntTy x_777_949_1231 = + ((Int64Int64VectorCursorCursorProd *) tail_1338)->field1; + VectorTy *x_778_950_1232 = + ((Int64Int64VectorCursorCursorProd *) tail_1338)->field2; + CursorTy x_779_951_1233 = + ((Int64Int64VectorCursorCursorProd *) tail_1338)->field3; + CursorTy x_780_952_1234 = + ((Int64Int64VectorCursorCursorProd *) tail_1338)->field4; + CursorTy y_784_956_1238 = _copy_Map_v_479(x_779_951_1233); + CursorTy y_785_957_1239 = _copy_Map_v_479(x_780_952_1234); + PtrTy tailift_1340 = + ALLOC(sizeof(Int64Int64Int64VectorCursorCursorProd)); + + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1340)->field0 = + 1; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1340)->field1 = + x_776_948_1230; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1340)->field2 = + x_777_949_1231; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1340)->field3 = + x_778_950_1232; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1340)->field4 = + y_784_956_1238; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1340)->field5 = + y_785_957_1239; + return tailift_1340; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1337"); + exit(1); + } + } +} +unsigned char _traverse_Map_v_479(CursorTy arg_797_958_1240) +{ + TagTyPacked tag_1342 = *(TagTyPacked *) arg_797_958_1240; + CursorTy tail_1343 = arg_797_958_1240 + sizeof(IntTy); + + + switch_1344: + ; + switch (tag_1342) { + + case 0: + { + return 0; + break; + } + + case 1: + { + IntTy x_798_959_1241 = + ((Int64Int64VectorCursorCursorProd *) tail_1343)->field0; + IntTy x_799_960_1242 = + ((Int64Int64VectorCursorCursorProd *) tail_1343)->field1; + VectorTy *x_800_961_1243 = + ((Int64Int64VectorCursorCursorProd *) tail_1343)->field2; + CursorTy x_801_962_1244 = + ((Int64Int64VectorCursorCursorProd *) tail_1343)->field3; + CursorTy x_802_963_1245 = + ((Int64Int64VectorCursorCursorProd *) tail_1343)->field4; + unsigned char y_806_964_1246 = _traverse_Map_v_479(x_801_962_1244); + unsigned char y_807_965_1247 = _traverse_Map_v_479(x_802_963_1245); + + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1342"); + exit(1); + } + } +} +unsigned char _print_Map_v_479(CursorTy arg_808_966_1248) +{ + TagTyPacked tag_1345 = *(TagTyPacked *) arg_808_966_1248; + CursorTy tail_1346 = arg_808_966_1248 + sizeof(IntTy); + + + switch_1347: + ; + switch (tag_1345) { + + case 0: + { + unsigned char wildcard_809_967_1249 = print_symbol(1299); + unsigned char wildcard_810_968_1250 = print_symbol(1298); + + return 0; + break; + } + + case 1: + { + IntTy x_811_969_1251 = + ((Int64Int64VectorCursorCursorProd *) tail_1346)->field0; + IntTy x_812_970_1252 = + ((Int64Int64VectorCursorCursorProd *) tail_1346)->field1; + VectorTy *x_813_971_1253 = + ((Int64Int64VectorCursorCursorProd *) tail_1346)->field2; + CursorTy x_814_972_1254 = + ((Int64Int64VectorCursorCursorProd *) tail_1346)->field3; + CursorTy x_815_973_1255 = + ((Int64Int64VectorCursorCursorProd *) tail_1346)->field4; + unsigned char wildcard_821_974_1256 = print_symbol(1300); + unsigned char wildcard_827_975_1257 = print_symbol(1301); + unsigned char y_816_976_1258 = printf("%lld", x_811_969_1251); + unsigned char wildcard_826_977_1259 = print_symbol(1301); + unsigned char y_817_978_1260 = printf("%lld", x_812_970_1252); + unsigned char wildcard_825_979_1261 = print_symbol(1301); + unsigned char y_818_980_1262 = print_symbol(1297); + unsigned char wildcard_824_981_1263 = print_symbol(1301); + unsigned char y_819_982_1264 = _print_Map_v_479(x_814_972_1254); + unsigned char wildcard_823_983_1265 = print_symbol(1301); + unsigned char y_820_984_1266 = _print_Map_v_479(x_815_973_1255); + unsigned char wildcard_822_985_1267 = print_symbol(1298); + + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1345"); + exit(1); + } + } +} +CursorTy caseFn_828(VectorTy *x1_220_829_986_1268, IntTy k1_219_830_987_1269, + CursorTy t1_221_831_988_1270, CursorTy m1_227_832_989_1271, + IntTy k2_225_833_990_1272, VectorTy *x2_226_834_991_1273, + CursorTy t4_228_835_992_1274) +{ + TagTyPacked tag_1348 = *(TagTyPacked *) m1_227_832_989_1271; + CursorTy tail_1349 = m1_227_832_989_1271 + sizeof(IntTy); + + + switch_1350: + ; + switch (tag_1348) { + + case 1: + { + IntTy wildcard__144_229_993_1275 = + ((Int64Int64VectorCursorCursorProd *) tail_1349)->field0; + IntTy k3_230_994_1276 = + ((Int64Int64VectorCursorCursorProd *) tail_1349)->field1; + VectorTy *x3_231_995_1277 = + ((Int64Int64VectorCursorCursorProd *) tail_1349)->field2; + CursorTy t2_232_996_1278 = + ((Int64Int64VectorCursorCursorProd *) tail_1349)->field3; + CursorTy t3_233_997_1279 = + ((Int64Int64VectorCursorCursorProd *) tail_1349)->field4; + CursorTy fltAppE_1066_1280 = + bin_487(k1_219_830_987_1269, x1_220_829_986_1268, t1_221_831_988_1270, t2_232_996_1278); + CursorTy fltAppE_1067_1281 = + bin_487(k2_225_833_990_1272, x2_226_834_991_1273, t3_233_997_1279, t4_228_835_992_1274); + + return bin_487(k3_230_994_1276, x3_231_995_1277, fltAppE_1066_1280, + fltAppE_1067_1281); + break; + } + + case 0: + { + return empty_477(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1348"); + exit(1); + } + } +} +CursorTy caseFn_836(VectorTy *x1_205_837_998_1282, IntTy k1_204_838_999_1283, + CursorTy t4_207_839_1000_1284, + CursorTy m1_213_840_1001_1285, IntTy k2_210_841_1002_1286, + VectorTy *x2_211_842_1003_1287, + CursorTy t1_212_843_1004_1288) +{ + TagTyPacked tag_1351 = *(TagTyPacked *) m1_213_840_1001_1285; + CursorTy tail_1352 = m1_213_840_1001_1285 + sizeof(IntTy); + + + switch_1353: + ; + switch (tag_1351) { + + case 1: + { + IntTy wildcard__168_214_1005_1289 = + ((Int64Int64VectorCursorCursorProd *) tail_1352)->field0; + IntTy k3_215_1006_1290 = + ((Int64Int64VectorCursorCursorProd *) tail_1352)->field1; + VectorTy *x3_216_1007_1291 = + ((Int64Int64VectorCursorCursorProd *) tail_1352)->field2; + CursorTy t2_217_1008_1292 = + ((Int64Int64VectorCursorCursorProd *) tail_1352)->field3; + CursorTy t3_218_1009_1293 = + ((Int64Int64VectorCursorCursorProd *) tail_1352)->field4; + CursorTy fltAppE_1068_1294 = + bin_487(k2_210_841_1002_1286, x2_211_842_1003_1287, t1_212_843_1004_1288, t2_217_1008_1292); + CursorTy fltAppE_1069_1295 = + bin_487(k1_204_838_999_1283, x1_205_837_998_1282, t3_218_1009_1293, t4_207_839_1000_1284); + + return bin_487(k3_215_1006_1290, x3_216_1007_1291, + fltAppE_1068_1294, fltAppE_1069_1295); + break; + } + + case 0: + { + return empty_477(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1351"); + exit(1); + } + } +} +int __main_expr() +{ + add_symbol(1297, "Vector"); + add_symbol(1298, ")"); + add_symbol(1299, "(Tip_v_479"); + add_symbol(1300, "(Bin_v_479"); + add_symbol(1301, " "); + + IntTy tmp_13 = sizeof(CharTy); + VectorTy *vec_179_187_844_1070 = vector_alloc(1, tmp_13); + CharTy tmp_12 = 'f'; + VectorTy *__188_845_1071 = vector_inplace_update(vec_179_187_844_1070, 0, + &tmp_12); + IntTy tmp_11 = sizeof(CharTy); + VectorTy *vec_180_189_846_1073 = vector_alloc(1, tmp_11); + CharTy tmp_10 = 'f'; + VectorTy *__190_847_1074 = vector_inplace_update(vec_180_189_846_1073, 0, + &tmp_10); + IntTy tmp_9 = sizeof(CharTy); + VectorTy *vec_181_191_848_1076 = vector_alloc(1, tmp_9); + CharTy tmp_8 = 'e'; + VectorTy *__192_849_1077 = vector_inplace_update(vec_181_191_848_1076, 0, + &tmp_8); + IntTy tmp_7 = sizeof(CharTy); + VectorTy *vec_182_193_850_1079 = vector_alloc(1, tmp_7); + CharTy tmp_6 = 'd'; + VectorTy *__194_851_1080 = vector_inplace_update(vec_182_193_850_1079, 0, + &tmp_6); + IntTy tmp_5 = sizeof(CharTy); + VectorTy *vec_183_195_852_1082 = vector_alloc(1, tmp_5); + CharTy tmp_4 = 'c'; + VectorTy *__196_853_1083 = vector_inplace_update(vec_183_195_852_1082, 0, + &tmp_4); + IntTy tmp_3 = sizeof(CharTy); + VectorTy *vec_184_197_854_1085 = vector_alloc(1, tmp_3); + CharTy tmp_2 = 'b'; + VectorTy *__198_855_1086 = vector_inplace_update(vec_184_197_854_1085, 0, + &tmp_2); + IntTy tmp_1 = sizeof(CharTy); + VectorTy *vec_185_199_856_1088 = vector_alloc(1, tmp_1); + CharTy tmp_0 = 'a'; + VectorTy *__200_857_1089 = vector_inplace_update(vec_185_199_856_1088, 0, + &tmp_0); + CursorTy fltAppE_1023_1091 = empty_477(); + CursorTy fltAppE_1021_1092 = + insert_478(0, vec_185_199_856_1088, fltAppE_1023_1091); + CursorTy fltAppE_1019_1093 = + insert_478(1, vec_184_197_854_1085, fltAppE_1021_1092); + CursorTy fltAppE_1017_1094 = + insert_478(2, vec_183_195_852_1082, fltAppE_1019_1093); + CursorTy fltAppE_1015_1095 = + insert_478(3, vec_182_193_850_1079, fltAppE_1017_1094); + CursorTy fltAppE_1013_1096 = + insert_478(4, vec_181_191_848_1076, fltAppE_1015_1095); + CursorTy fltAppE_1011_1097 = + insert_478(5, vec_180_189_846_1073, fltAppE_1013_1096); + CursorTy tmp_app_1296 = + insert_478(0, vec_179_187_844_1070, fltAppE_1011_1097); + + _print_Map_v_479(tmp_app_1296); + printf("\n"); + free_symtable(); + return 0; +} \ No newline at end of file diff --git a/benchmarks/Layouts/Map.hs b/benchmarks/Layouts/Map.hs new file mode 100644 index 000000000..99d5ea4fc --- /dev/null +++ b/benchmarks/Layouts/Map.hs @@ -0,0 +1,152 @@ +{-# LANGUAGE BlockArguments #-} +{-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE DataKinds #-} + +module Map where +import Common + +type Size = Int +data Map a = Tip + | Bin Size Int a (Map a) (Map a) + +-- Construction ----------------------- + +empty :: Map a +empty = Tip + +singleton :: Int -> a -> Map a +singleton k x = Bin 1 k x Tip Tip + + +-- Query ------------------------------ + +null :: Map a -> Bool +null m = case m of + Tip -> True + Bin _ _ _ _ _ -> False + +size :: Map a -> Size +size m = case m of + Tip -> 0 + Bin sz _ _ _ _ -> sz + +lookup :: Int -> Map a -> Maybe a +lookup k m = + case m of + Tip -> Nothing + Bin _ kx v l r -> + if k < kx then lookup k l + else if k > kx then lookup k r + else Just v + +member :: Int -> Map a -> Bool +member k m = case lookup k m of + Nothing -> False + Just _ -> True + +val :: Map a -> Maybe a +val m = + case m of + Tip -> Nothing + Bin _ _ v _ _ -> Just v + +left :: Map a -> Map a +left m = + case m of + Tip -> Tip + Bin _ _ _ l _ -> l + +right :: Map a -> Map a +right m = + case m of + Tip -> Tip + Bin _ _ _ _ r -> r + +-- Insertion -------------------------- + +insert :: Int -> a -> Map a -> Map a +insert kx x m = + case m of + Tip -> singleton kx x + Bin sz k v l r -> + if kx == k then Bin sz k x l r + else if kx <= k then + balance k v (insert kx x l) r + else + balance k v l (insert kx x r) + +delta :: Int +delta = 4 +ratio :: Int +ratio = 2 + +balance :: Int -> a -> Map a -> Map a -> Map a +balance k x l r = + if (size l) + (size r) <= 1 then Bin ((size l) + (size r)) k x l r + else if (size r) >= delta*(size l) then rotateL k x l r + else if (size l) >= delta*(size r) then rotateR k x l r + else Bin ((size l) + (size r)) k x l r + +rotateL :: Int -> b -> Map b -> Map b -> Map b +rotateL k x l r = + case r of + Bin _ _ _ ly ry -> + if (size ly) < ratio*(size ry) then singleL k x l r + else doubleL k x l r + Tip -> empty -- cry +--rotateL _ _ _ Tip = error "rotateL Tip" + +rotateR :: Int -> b -> Map b -> Map b -> Map b +rotateR k x l r = + case l of + Bin _ _ _ ly ry -> + if (size ry) < ratio*(size ly) then singleR k x l r + else doubleR k x l r + Tip -> empty --cry +--rotateR _ _ Tip _ = error "rotateR Tip" + +bin :: Int -> a -> Map a -> Map a -> Map a +bin k x l r = Bin ((size l) + (size r) + 1) k x l r + +singleL :: Int -> b -> Map b -> Map b -> Map b +singleL k1 x1 t1 m = + case m of + Bin _ k2 x2 t2 t3 -> bin k2 x2 (bin k1 x1 t1 t2) t3 + Tip -> empty --cry +--singleL :: Int -> b -> Map Int b -> Map Int b -> Map Int b +--singleL k1 x1 t1 (Bin _ k2 x2 t2 t3) = bin k2 x2 (bin k1 x1 t1 t2) t3 +--singleL _ _ _ Tip = error "singleL Tip" + +singleR :: Int -> b -> Map b -> Map b -> Map b +singleR k1 x1 m t3 = + case m of + Bin _ k2 x2 t1 t2 -> bin k2 x2 t1 (bin k1 x1 t2 t3) + Tip -> empty --cry +--singleR k1 x1 (Bin _ k2 x2 t1 t2) t3 = bin k2 x2 t1 (bin k1 x1 t2 t3) +--singleR _ _ Tip _ = error "singleR Tip" + +doubleL :: Int -> b -> Map b -> Map b -> Map b +doubleL k1 x1 t1 m0 = + case m0 of + Bin _ k2 x2 m1 t4 -> + case m1 of + Bin _ k3 x3 t2 t3 -> bin k3 x3 (bin k1 x1 t1 t2) (bin k2 x2 t3 t4) + Tip -> empty --cry + Tip _ _ _ _ -> empty --cry +--doubleL k1 x1 t1 (Bin _ k2 x2 (Bin _ k3 x3 t2 t3) t4) = bin k3 x3 (bin k1 x1 t1 t2) (bin k2 x2 t3 t4) +--doubleL _ _ _ _ = error "doubleL" + +doubleR :: Int -> b -> Map b -> Map b -> Map b +doubleR k1 x1 m0 t4 = + case m0 of + Bin _ k2 x2 t1 m1 -> + case m1 of + Bin _ k3 x3 t2 t3 -> bin k3 x3 (bin k2 x2 t1 t2) (bin k1 x1 t3 t4) + Tip -> empty + Tip -> empty --cry +--doubleR k1 x1 (Bin _ k2 x2 t1 (Bin _ k3 x3 t2 t3)) t4 = bin k3 x3 (bin k2 x2 t1 t2) (bin k1 x1 t3 t4) +--doubleR _ _ _ _ = error "doubleR" + +--gibbon_main = insert 0 'a' empty + +gibbon_main = insert 0 "f" (insert 5 "f" (insert 4 "e" (insert 3 "d" (insert 2 "c" (insert 1 "b" (insert 0 "a" empty)))))) \ No newline at end of file diff --git a/benchmarks/Layouts/Right.c b/benchmarks/Layouts/Right.c new file mode 100644 index 000000000..9e9dd23fa --- /dev/null +++ b/benchmarks/Layouts/Right.c @@ -0,0 +1,2443 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// #include +#ifdef _WIN64 +#include +#endif +#include +#include +#include // For va_start etc +#include +#include +#include +#include +#ifdef _POINTER +#include +#endif +#ifdef _PARALLEL +#include +#include +#endif + +#define KB 1024lu +#define MB (KB * 1000lu) +#define GB (MB * 1000lu) + +#define REDIRECTION_TAG 255 +#define INDIRECTION_TAG 254 + +// Initial size of BigInfinite buffers +static long long global_init_biginf_buf_size = (4 * GB); + +// Initial size of Infinite buffers +static long long global_init_inf_buf_size = 1 * KB; + +// Maximum size of a chunk, see GitHub #110. +static long long global_inf_buf_max_chunk_size = 1 * GB; + +static long long global_size_param = 1; +static long long global_iters_param = 1; + +static char* global_benchfile_param = NULL; +static char* global_arrayfile_param = NULL; +// Number of lines in the arrayfile +static long long global_arrayfile_length_param = -1; + +// Sequential for now: +static const int num_workers = 1; + +// Count the number of regions allocated. +static long long global_region_count = 0; +static bool global_region_count_flag = false; + +#ifdef _PARALLEL +static inline void bump_global_region_count() { + __atomic_add_fetch(&global_region_count, 1, __ATOMIC_SEQ_CST); + return; +} +#else +static inline void bump_global_region_count() { + global_region_count++; + return; +} +#endif + +static inline void print_global_region_count() { + printf("REGION_COUNT: %lld\n", global_region_count); + return; +} + +#define REDIRECTION_NODE_SIZE 9 +#define MAX(a,b) (((a)>(b))?(a):(b)) +#define MIN(a,b) (((a)<(b))?(a):(b)) + +// https://www.cprogramming.com/snippets/source-code/find-the-number-of-cpu-cores-for-windows-mac-or-linux +static int get_num_processors() { +#ifdef _WIN64 + SYSTEM_INFO sysinfo; + GetSystemInfo(&sysinfo); + return sysinfo.dwNumberOfProcessors; +#else + return sysconf(_SC_NPROCESSORS_ONLN); +#endif +} + +// Requires -std=gnu11 +int dbgprintf(const char *format, ...) { + int code = 0; + va_list args; + va_start(args, format); +#ifdef _DEBUG + code = vprintf(format, args); +#endif + va_end(args); + return code; +} + + +// ----------------------------------------------------------------------------- +// Allocators +// ----------------------------------------------------------------------------- + + +// ------------------------------------- +// Bump allocation for linked-lists +// ------------------------------------- + + +#ifdef _BUMPALLOC +// #define _DEBUG +#warning "Using bump allocator." + +__thread char* bumpalloc_heap_ptr = (char*)NULL; +__thread char* bumpalloc_heap_ptr_end = (char*)NULL; + +char* saved_heap_ptr_stack[100]; +int num_saved_heap_ptr = 0; + +// For simplicity just use a single large slab: +static inline void INITBUMPALLOC() { + bumpalloc_heap_ptr = (char*)malloc(global_init_biginf_buf_size); + bumpalloc_heap_ptr_end = bumpalloc_heap_ptr + global_init_biginf_buf_size; +#ifdef _DEBUG + printf("Arena size for bump alloc: %lld\n", global_init_biginf_buf_size); + printf("BUMPALLOC/INITBUMPALLOC DONE: heap_ptr = %p\n", bumpalloc_heap_ptr); +#endif +} + +static inline void* BUMPALLOC(long long n) { + if (! bumpalloc_heap_ptr) { + INITBUMPALLOC(); + } + if (bumpalloc_heap_ptr + n < bumpalloc_heap_ptr_end) { + char* old= bumpalloc_heap_ptr; + bumpalloc_heap_ptr += n; + return old; + } else { + fprintf(stderr, "Warning: bump allocator ran out of memory."); + exit(1); + } +} + +// Snapshot the current heap pointer value across all threads. +void save_alloc_state() { + dbgprintf("Saving(%p): pos %d", heap_ptr, num_saved_heap_ptr); + saved_heap_ptr_stack[num_saved_heap_ptr] = heap_ptr; + num_saved_heap_ptr++; + dbgprintf("\n"); +} + +void restore_alloc_state() { + if(num_saved_heap_ptr <= 0) { + fprintf(stderr, "Bad call to restore_alloc_state! Saved stack empty!\ne"); + exit(1); + } + num_saved_heap_ptr--; + dbgprintf("Restoring(%p): pos %d, discarding %p", + saved_heap_ptr_stack[num_saved_heap_ptr], num_saved_heap_ptr, bumpalloc_heap_ptr); + bumpalloc_heap_ptr = saved_heap_ptr_stack[num_saved_heap_ptr]; +} + + +#else +// Regular malloc mode: +void INITBUMPALLOC() {} +void save_alloc_state() {} +void restore_alloc_state() {} + +#define BUMPALLOC(n) malloc(n) + +#endif // BUMPALLOC + + +// ------------------------------------- +// ALLOC and ALLOC_PACKED macros +// ------------------------------------- + + +/* + +If parallelism is enabled, we always use a malloc based allocator +since Boehm GC is not thread-safe in its default configuration. It can be +made thread-safe by building it with appropriate flags, but we don't do that. +Presently, all parallel pointer-based programs will leak memory. + +*/ + +#ifdef _PARALLEL +#define ALLOC(n) malloc(n) +#define ALLOC_PACKED_BIG(n) malloc(n) +char *ALLOC_COUNTED(size_t size) { + bump_global_region_count(); + return ALLOC(size); +} +#else + #ifdef _POINTER +#define ALLOC(n) GC_MALLOC(n) +#define ALLOC_PACKED_BIG(n) GC_MALLOC(n) +char *ALLOC_COUNTED(size_t size) { + bump_global_region_count(); + return GC_MALLOC(size); +} + #else +#define ALLOC(n) malloc(n) +#define ALLOC_PACKED_BIG(n) malloc(n) +char *ALLOC_COUNTED(size_t size) { + bump_global_region_count(); + return ALLOC(size); +} + #endif // _POINTER +#endif // _PARALLEL + + +// Could try alloca() here. Better yet, we could keep our own, +// separate stack and insert our own code to restore the pointer +// before any function that (may have) called ALLOC_SCOPED returns. + +// #define ALLOC_SCOPED() alloca(1024) +#define ALLOC_SCOPED(n) alloca(n) +// #define ALLOC_SCOPED() alloc_scoped() + +// Stack allocation is either too small or blows our stack. +// We need a way to make a giant stack if we want to use alloca. +// #define ALLOC_SCOPED() ALLOC(global_init_biginf_buf_size) + +// Our global pointer. No parallelism. +// static char* stack_scoped_region; +// char* alloc_scoped() { return stack_scoped_region; } + + + +// ------------------------------------- +// Basic types +// ------------------------------------- + +// Must be consistent with sizeOfTy defined in Gibbon.Language.Syntax. + +typedef unsigned char TagTyPacked; +typedef unsigned char TagTyBoxed; +typedef long long IntTy; +typedef char CharTy; +typedef float FloatTy; +typedef unsigned long long SymTy; +typedef bool BoolTy; +typedef char* PtrTy; +typedef char* CursorTy; + +// ------------------------------------- +// Arenas and dictionaries +// ------------------------------------- + +typedef struct mem_arena { + int ind; + char* mem; // TODO(vollmerm): make this a list of chunks? + void* reflist; +} mem_arena_t; + +typedef mem_arena_t* ArenaTy; + +ArenaTy alloc_arena() { + ArenaTy ar = ALLOC(sizeof(mem_arena_t)); + ar->ind = 0; + ar->mem = malloc(global_inf_buf_max_chunk_size); + ar->reflist = 0; + return ar; +} + +void free_arena(ArenaTy ar) { + free(ar->mem); + // TODO(vollmerm): free everything in ar->reflist + free(ar); +} + +CursorTy extend_arena(ArenaTy ar, int size) { + CursorTy ret = ar->mem + ar->ind; + ar->ind += size; + return ret; +} + +typedef struct dict_item { + struct dict_item * next; + int key; + void * ptrval; +} dict_item_t; + +dict_item_t * dict_alloc(ArenaTy ar) { + return (dict_item_t *) extend_arena(ar, sizeof(dict_item_t)); // ALLOC(sizeof(dict_item_t)); +} + +dict_item_t *dict_insert_ptr(ArenaTy ar, dict_item_t *ptr, SymTy key, PtrTy val) { + dict_item_t *ret = dict_alloc(ar); + ret->key = key; + ret->ptrval = val; + ret->next = ptr; + return ret; +} + +PtrTy dict_lookup_ptr(dict_item_t *ptr, SymTy key) { + while (ptr != 0) { + if (ptr->key == key) { + return ptr->ptrval; + } else { + ptr = ptr->next; + } + } + printf("Error, key %lld not found!\n",key); + exit(1); +} + +// ------------------------------------- +// Sets +// ------------------------------------- + + +struct set_elem { + int val; + UT_hash_handle hh; +}; + +typedef struct set_elem* SymSetTy; + +SymSetTy empty_set() { + return NULL; +} + +SymSetTy insert_set(SymSetTy set, int sym) { + SymSetTy s; + HASH_FIND_INT(set, &sym, s); /* sym already in the hash? */ + if (s==NULL) { + s = malloc(sizeof(struct set_elem)); + s->val = sym; + HASH_ADD_INT(set,val,s); + } + return set; +} + +BoolTy contains_set(SymSetTy set, int sym) { + SymSetTy s; + HASH_FIND_INT(set, &sym, s); + return (s!=NULL); +} + +// ------------------------------------- +// Sym Hash +// ------------------------------------- + +struct sym_hash_elem { + int key; + int val; + UT_hash_handle hh; +}; + +typedef struct sym_hash_elem* SymHashTy; + +typedef struct sym_hash_elem* IntHashTy; + +SymHashTy empty_hash() { + return NULL; +} + +SymHashTy insert_hash(SymHashTy hash, int k, int v) { + SymHashTy s; + // NOTE: not checking for duplicates! + // s = malloc(sizeof(struct sym_hash_elem)); + s = ALLOC(sizeof(struct sym_hash_elem)); + s->val = v; + s->key = k; + HASH_ADD_INT(hash,key,s); + + return hash; +} + +IntTy lookup_hash(SymHashTy hash, int k) { + SymHashTy s; + HASH_FIND_INT(hash,&k,s); + if (s==NULL) { + return k; // NOTE: return original key if val not found + // TODO(vollmerm): come up with something better to do here + } else { + return s->val; + } +} + +BoolTy contains_hash(SymHashTy hash, int sym) { + SymHashTy s; + HASH_FIND_INT(hash,&sym,s); + return (s!=NULL); +} + +// ------------------------------------- +// Helpers +// ------------------------------------- + +char* read_benchfile_param() { + if (global_benchfile_param == NULL) { + fprintf(stderr, "read_benchfile_param: benchmark input file was not set! Set using --bench-input.\n"); + exit(1); + } else + return global_benchfile_param; +} + +char* read_arrayfile_param() { + if (global_arrayfile_param == NULL) { + fprintf(stderr, "read_arrayfile_param: array input file was not set! Set using --array-input.\n"); + exit(1); + } else + return global_arrayfile_param; +} + +IntTy read_arrayfile_length_param() { + if (global_arrayfile_length_param == -1) { + fprintf(stderr, "read_arrayfile_length_param: array input file length was not set! Set using --array-input-length.\n"); + exit(1); + } else + return global_arrayfile_length_param; +} + + +// fun fact: __ prefix is actually reserved and this is an undefined behavior. +// These functions must be provided by the code generator. +int __main_expr(); + + +void show_usage(char** argv) +{ + printf("\n"); + printf("This binary was generated by the Gibbon compiler.\n"); + printf("\n"); + printf("Usage: %s [OPTS] [size] [iters]\n", argv[0]); + + printf("\n"); + printf("Options:\n"); + printf(" --buffer-size Set the buffer size (default %lld).\n", global_init_biginf_buf_size); + printf(" --bench-input Set the input file read for benchmarking. Applies only\n"); + printf(" IF the program was *compiled* with --bench-fun. \n"); + return; +} + +double avg(const double* arr, int n) +{ + double sum = 0.0; + for(int i=0; itv_sec - t0->tv_sec) + + ((double)(t1->tv_nsec - t0->tv_nsec) / 1000000000.0); +} + +int compare_doubles(const void *a, const void *b) +{ + const double *da = (const double *) a; + const double *db = (const double *) b; + return (*da > *db) - (*da < *db); +} + +// Exponentiation +IntTy expll(IntTy base, IntTy pow) { + if (base == 2) { + return (1 << pow); + } else { + IntTy i, result = 1; + for (i = 0; i < pow; i++) + result *= base; + return result; + } + } + +// ------------------------------------- +// Symbol table +// ------------------------------------- + +#define global_max_symbol_len 256 + +// Invariant: should always be equal to max(sym_table_keys) +static SymTy global_gensym_counter = 0; + +// Its value is updated by the flags parser. +static char *global_bench_prog_param; + +static SymTy newline_symbol = -1; +static SymTy space_symbol = -1; +static SymTy comma_symbol = -1; +static SymTy leftparen_symbol = -1; +static SymTy rightparen_symbol = -1; + +typedef struct SymTable_elem { + SymTy idx; /* key */ + char value[global_max_symbol_len]; + UT_hash_handle hh; /* makes this structure hashable */ +} SymTable_elem; + +// important! initialize to NULL +SymTable_elem *global_sym_table = NULL; + +void add_symbol(SymTy idx, char *value) { + struct SymTable_elem *s; + s = ALLOC(sizeof(struct SymTable_elem)); + s->idx = idx; + strcpy(s->value, value); + HASH_ADD(hh, global_sym_table, idx, sizeof(IntTy), s); + if (idx > global_gensym_counter) { + global_gensym_counter = idx; + } +} + +void set_newline(SymTy idx) { + newline_symbol = idx; + add_symbol(idx,"NEWLINE"); +} + +void set_space(SymTy idx) { + space_symbol = idx; + add_symbol(idx,"SPACE"); +} + +void set_comma(SymTy idx) { + comma_symbol = idx; + add_symbol(idx,"COMMA"); +} + +void set_leftparen(SymTy idx) { + leftparen_symbol = idx; + add_symbol(idx,"LEFTPAREN"); +} + +void set_rightparen(SymTy idx) { + rightparen_symbol = idx; + add_symbol(idx,"RIGHTPAREN"); +} + +IntTy print_symbol(SymTy idx) { + if (idx == comma_symbol) { + return printf(","); + } else if (idx == newline_symbol) { + return printf("\n"); + } else if (idx == space_symbol) { + return printf(" "); + } else if (idx == leftparen_symbol) { + return printf("("); + } else if (idx == rightparen_symbol) { + return printf(")"); + } else { + struct SymTable_elem *s; + HASH_FIND(hh, global_sym_table, &idx, sizeof(SymTy), s); + if (s == NULL) { + return printf("%lld", idx); + } else { + return printf("%s", s->value); + } + + } +} + +#ifdef _PARALLEL +SymTy gensym() { + SymTy idx = __atomic_add_fetch(&global_gensym_counter, 1, __ATOMIC_SEQ_CST); + return idx; +} +#else +SymTy gensym() { + global_gensym_counter += 1; + SymTy idx = global_gensym_counter; + return idx; +} +#endif + +void free_symtable() { + struct SymTable_elem *elt, *tmp; + HASH_ITER(hh, global_sym_table, elt, tmp) { + HASH_DEL(global_sym_table,elt); + } + free(elt); + free(tmp); +} + +/* + +---------------------------------------- +Garbage collection +---------------------------------------- + + Gibbon has "growing regions" i.e each logical region is backed by a doubly linked-list + of smaller chunks which grows as required. In addition to actual data, each chunk + stores some additional metadata (RegionFooter) to chain the chunks together in a list + and for garbage collection. The footer: + + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + serialized data | rf_reg_metadata_ptr | rf_seq_no | rf_size | rf_next | rf_prev + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + The metadata after the serialized data serves various purposes: + + - rf_reg_metadata_ptr: A pointer to a RegionTy struct that contains various metadata. + Of particular interest to us are the fields: + + = reg_id: A unique identifier for a region. + + = refcount and outset: Whenever an inter-region indirection is created, we record that information + using these two fields. Suppose we have an indirection from region A that points to some chunk + in region B. Then A's outset will store a pointer to that chunk's footer, and B's refcount will + be bumped by 1. Note that all there's only 1 refcount cell, and 1 outset per logical region, + and chunks only store a pointer to them. + + - rf_seq_no: The index of this particular chunk in the list. + + - rf_size: Used during bounds checking to calculate the size of the next region in + the linked list. + + - rf_next / rf_prev: Point to the next and previous chunk respectively. + + +There are two ways in which a region may be freed: + +(1) Whenever it goes out of scope + + The RTS tries to free a region whenever it goes out of scope. But this doesn't always succeed as + regions sometimes contain values that "escape". One reason why this'll happen is if there's an + indirection from A->B, and A lives longer than B. + In such a case, when B goes out of scope it's refcount won't be 0, and the RTS won't free it. + This brings us to (2). + +(2) + + When the RTS successfully frees a region, it decrements the refcounts of all the regions it + points to (via the outset). At the same time, if it encounters a region in the outset whoose + refcount becomes 0 after the decrement, it calls free_region on that. This way we can be sure + that all regions will eventually be garbage collected before the program exits. + + + +Why is it a doubly linked-list? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Due to way that bounds-checking works, the pointers in the outset may actually point to any +arbitrary chunk in the chain. However, we must call free_region on the first one to ensure that +all of them are GC'd. So we need pointers to traverse backward get to the first one. +'trav_to_first_chunk' accomplishes this. + + */ + +#define MAX_OUTSET_LENGTH 10 + +typedef struct RegionTy_struct { + SymTy reg_id; + uint reg_refcount; + CursorTy reg_heap; + uint reg_outset_len; + CursorTy reg_outset[MAX_OUTSET_LENGTH]; +} RegionTy; + +typedef struct RegionFooter_struct { + RegionTy *rf_reg_metadata_ptr; + + IntTy rf_seq_no; + IntTy rf_size; + struct RegionFooter_struct *rf_next; + struct RegionFooter_struct *rf_prev; +} RegionFooter; + +typedef struct ChunkTy_struct { + CursorTy chunk_start; + CursorTy chunk_end; +} ChunkTy; + +static inline void insert_into_outset(CursorTy ptr, RegionTy *reg) { + uint outset_len = reg->reg_outset_len; + // Check for duplicates. + for (uint i = 0; i < outset_len; i++) { + if (ptr == reg->reg_outset[i]) { + return; + } + } + // Otherwise, insert into the outset. + reg->reg_outset[outset_len] = ptr; + reg->reg_outset_len = outset_len + 1; + return; +} + +static inline void remove_from_outset(CursorTy ptr, RegionTy *reg) { + uint outset_len = reg->reg_outset_len; + CursorTy *outset = reg->reg_outset; + int i; + if (outset_len == 0) { + fprintf(stderr, "remove_from_outset: empty outset\n"); + exit(1); + } + // Position of 'ptr' in the outset. + int elt_idx = -1; + for (i = 0; i < outset_len; i++) { + if (ptr == outset[i]) { + elt_idx = i; + } + } + if (elt_idx == -1) { + fprintf(stderr, "remove_from_outset: element not found\n"); + exit(1); + } + // Move all elements ahead of 'elt_idx' back by one position. + for (i = elt_idx; i < outset_len; i++) { + outset[i] = outset[i+1]; + } + return; +} + +RegionTy *alloc_region(IntTy size) { + // Allocate the region metadata. + RegionTy *reg = ALLOC(sizeof(RegionTy)); + if (reg == NULL) { + printf("alloc_region: allocation failed: %ld", sizeof(RegionTy)); + exit(1); + } + + // Allocate the first chunk. + IntTy total_size = size + sizeof(RegionFooter); + CursorTy heap = ALLOC_PACKED_BIG(total_size); + if (heap == NULL) { + printf("alloc_region: malloc failed: %lld", total_size); + exit(1); + } + // Not heap+total_size, since we must keep space for the footer. + CursorTy heap_end = heap + size; + + // Initialize metadata fields. + reg->reg_id = gensym(); + reg->reg_refcount = 1; + reg->reg_heap = heap; + reg->reg_outset_len = 0; + +#ifdef _DEBUG + printf("Allocated a region(%lld): %lld bytes.\n", reg->reg_id, size); +#endif + + // Write the footer. + RegionFooter *footer = (RegionFooter *) heap_end; + footer->rf_reg_metadata_ptr = reg; + footer->rf_seq_no = 1; + footer->rf_size = size; + footer->rf_next = NULL; + footer->rf_prev = NULL; + + return reg; +} + +RegionTy *alloc_counted_region(IntTy size) { + // Bump the count. + bump_global_region_count(); + return alloc_region(size); +} + +ChunkTy alloc_chunk(CursorTy end_old_chunk) { + // Get size from current footer. + RegionFooter *footer = (RegionFooter *) end_old_chunk; + IntTy newsize = footer->rf_size * 2; + // See #110. + if (newsize > global_inf_buf_max_chunk_size) { + newsize = global_inf_buf_max_chunk_size; + } + IntTy total_size = newsize + sizeof(RegionFooter); + + // Allocate. + CursorTy start = ALLOC_PACKED_BIG(total_size); + if (start == NULL) { + printf("alloc_chunk: malloc failed: %lld", total_size); + exit(1); + } + CursorTy end = start + newsize; + + // Link the next chunk's footer. + footer->rf_next = (RegionFooter *) end; + + // Write the footer. + RegionFooter* new_footer = (RegionFooter *) end; + new_footer->rf_reg_metadata_ptr = footer->rf_reg_metadata_ptr; + new_footer->rf_seq_no = footer->rf_seq_no + 1; + new_footer->rf_size = newsize; + new_footer->rf_next = NULL; + new_footer->rf_prev = footer; + +#ifdef _DEBUG + RegionTy *reg = (RegionTy*) new_footer->rf_reg_metadata_ptr; + printf("alloc_chunk: allocated %lld bytes for region %lld.\n", total_size, reg->reg_id); +#endif + + return (ChunkTy) {start , end}; +} + +RegionFooter* trav_to_first_chunk(RegionFooter *footer) { + if (footer->rf_seq_no == 1) { + return footer; + } else if (footer->rf_prev == NULL) { + fprintf(stderr, "No previous chunk found at rf_seq_no: %lld", footer->rf_seq_no); + return NULL; + } else { + trav_to_first_chunk((RegionFooter *) footer->rf_prev); + } + return NULL; +} + +uint get_ref_count(CursorTy end_ptr) { + RegionFooter *footer = (RegionFooter *) end_ptr; + RegionTy *reg = (RegionTy *) footer->rf_reg_metadata_ptr; + return reg->reg_refcount; +} + +// B is the pointer, and A is the pointee (i.e B -> A). +// Bump A's refcount and update B's outset. +static inline void bump_ref_count(CursorTy end_b, CursorTy end_a) { + // Grab footers. + RegionFooter *footer_a = (RegionFooter *) end_a; + RegionFooter *footer_b = (RegionFooter *) end_b; + + // Grab metadata. + RegionTy *reg_a = (RegionTy *) footer_a->rf_reg_metadata_ptr; + RegionTy *reg_b = (RegionTy *) footer_b->rf_reg_metadata_ptr; + + // Bump A's refcount. + uint current_refcount, new_refcount; + current_refcount = reg_a->reg_refcount; + new_refcount = current_refcount + 1; + reg_a->reg_refcount = new_refcount; + +#ifdef _DEBUG + printf("bump_ref_count: %lld -> %lld\n", reg_b->reg_id, reg_a->reg_id); + printf("bump_ref_count: old-refcount=%d, old-outset-len=%d:\n", current_refcount, reg_b->reg_outset_len); + assert(current_refcount == reg_b->reg_outset_len+1); +#endif + + // Add A to B's outset. + insert_into_outset(end_a, reg_b); + +#ifdef _DEBUG + // printf("bump_ref_count: Added %p to %lld's outset, %p.\n", end_a, reg_b->reg_id, reg_b); + printf("bump_ref_count: new-refcount=%d, new-outset-len=%d\n", new_refcount, reg_b->reg_outset_len); + assert(new_refcount == reg_b->reg_outset_len+1); +#endif + + return; +} + +void free_region(CursorTy end_reg) { + // Grab footer and the metadata. + RegionFooter *footer = (RegionFooter *) end_reg; + RegionTy *reg = (RegionTy *) footer->rf_reg_metadata_ptr; + + // + RegionFooter *first_chunk_footer, *next_chunk_footer; + CursorTy first_chunk, next_chunk; + + // Decrement current reference count. + uint current_refcount, new_refcount; + current_refcount = reg->reg_refcount; + new_refcount = 0; + if (current_refcount != 0) { + new_refcount = current_refcount - 1; + reg->reg_refcount = new_refcount; + } + +#ifdef _DEBUG + printf("free_region(%lld): refcounts (1): old-refcount=%d, new-refcount=%d:\n", reg->reg_id, current_refcount, new_refcount); +#endif + + + // Free this region recount is 0. + if (new_refcount == 0) { + +#ifdef _DEBUG + printf("free_region(%lld): outset length: %d\n", reg->reg_id, reg->reg_outset_len); +#endif + + // Decrement refcounts, free regions with refcount==0 and also free + // elements of the outset. + if (reg->reg_outset_len != 0) { + uint outset_len = reg->reg_outset_len; + CursorTy *outset = reg->reg_outset; + RegionFooter *elt_footer; + RegionTy *elt_reg; + uint elt_current_refcount, elt_new_refcount; + CursorTy to_be_removed[MAX_OUTSET_LENGTH]; + uint to_be_removed_idx = 0; + for (int i = 0; i < outset_len; i++) { + elt_footer = (RegionFooter *) outset[i]; + elt_reg = (RegionTy *) elt_footer->rf_reg_metadata_ptr; +#ifdef _DEBUG + elt_current_refcount = elt_reg->reg_refcount; +#endif + elt_new_refcount = elt_current_refcount - 1; + elt_reg->reg_refcount = elt_new_refcount; +#ifdef _DEBUG + printf("free_region(%lld): old-refcount=%d, new-refcount=%d:\n", + elt_reg->reg_id, elt_current_refcount, elt_reg->reg_refcount); +#endif + if (elt_new_refcount == 0) { + // See [Why is it a doubly linked-list?] above + first_chunk_footer = trav_to_first_chunk(elt_footer); + if (first_chunk_footer != NULL) { + free_region((CursorTy) first_chunk_footer); + } + } + to_be_removed[to_be_removed_idx] = outset[i]; + to_be_removed_idx++; + } + // Remove elements from the outset. + for (uint i = 0; i < to_be_removed_idx; i++) { + remove_from_outset(to_be_removed[i], reg); + } + } + + +#ifdef _DEBUG + // Bookkeeping + IntTy num_freed_chunks = 0, total_bytesize = 0; +#endif + + // Free the chunks in this region. + first_chunk = end_reg - footer->rf_size; + first_chunk_footer = footer; + next_chunk = (char*) footer->rf_next; + +#ifdef _DEBUG + printf("free_region(%lld)\n", reg->reg_id); +#endif + +#ifdef _DEBUG + num_freed_chunks++; + total_bytesize = total_bytesize + first_chunk_footer->rf_size; +#endif + free(first_chunk); + + while (next_chunk != NULL) { + next_chunk_footer = (RegionFooter *) next_chunk; + #ifdef _DEBUG + num_freed_chunks++; + total_bytesize = total_bytesize + next_chunk_footer->rf_size; + #endif + free(next_chunk - next_chunk_footer->rf_size); + next_chunk = (char*) next_chunk_footer->rf_next; + } + +#ifdef _DEBUG + printf("free_region(%lld): Freed %lld bytes across %lld chunks.\n", + reg->reg_id, total_bytesize, num_freed_chunks); +#endif + + // Free the metadata. + free(reg); + + } else { +#ifdef _DEBUG + printf("free_region(%lld): non-zero refcount: %d.\n", + reg->reg_id, reg->reg_refcount); +#endif + } +} + +// Assume that all nodes with size information have tags >= 150. +BoolTy is_big(IntTy i, CursorTy cur) { + TagTyPacked tag = *(TagTyPacked *) cur; + if (tag >= 150) { + cur += 1; + IntTy size = *(IntTy *) cur; + if (size >= i) { + return true; + } else { + return false; + } + } + return false; +} + +// ------------------------------------- +// Vectors +// ------------------------------------- + +typedef struct VectorTy_struct { + // Bounds on the vector. + IntTy vec_lower, vec_upper; + + // Size of each element. + IntTy vec_elt_size; + + // Actual elements of the vector. + void* vec_data; +} VectorTy; + +VectorTy* vector_alloc(IntTy num, IntTy elt_size) { + VectorTy *vec = ALLOC(sizeof(VectorTy)); + if (vec == NULL) { + printf("alloc_vector: malloc failed: %ld", sizeof(VectorTy)); + exit(1); + } + void* data = ALLOC(num * elt_size); + if (data == NULL) { + printf("alloc_vector: malloc failed: %ld", sizeof(num * elt_size)); + exit(1); + } + vec->vec_lower = 0; + vec->vec_upper = num; + vec->vec_elt_size = elt_size; + vec->vec_data = data; + return vec; +} + +IntTy vector_length(VectorTy *vec) { + return (vec->vec_upper - vec->vec_lower); +} + +BoolTy vector_is_empty(VectorTy *vec) { + return (vector_length(vec) == 0); +} + +VectorTy* vector_slice(IntTy i, IntTy n, VectorTy *vec) { + IntTy lower = vec->vec_lower + i; + IntTy upper = vec->vec_lower + i + n; + if ((lower > vec->vec_upper)) { + printf("vector_slice: lower out of bounds, %lld > %lld", lower, vec->vec_upper); + exit(1); + } + if ((upper > vec->vec_upper)) { + printf("vector_slice: upper out of bounds: %lld > %lld", upper, vec->vec_upper); + exit(1); + } + VectorTy *vec2 = ALLOC(sizeof(VectorTy)); + if (vec == NULL) { + printf("vector_slice: malloc failed: %ld", sizeof(VectorTy)); + exit(1); + } + vec2->vec_lower = lower; + vec2->vec_upper = upper; + vec2->vec_elt_size = vec->vec_elt_size; + vec2->vec_data = vec->vec_data; + return vec2; +} + +// The callers must cast the return value. +static inline void* vector_nth(VectorTy *vec, IntTy i) { + // if (i < vec->lower || i > vec->upper) { + // printf("vector_nth index out of bounds: %lld (%lld,%lld) \n", i, vec->vec_lower, vec->vec_upper); + // exit(1); + // } + return (vec->vec_data + (vec->vec_elt_size * (vec->vec_lower + i))); +} + +static inline VectorTy* vector_inplace_update(VectorTy *vec, IntTy i, void* elt) { + void* dst = vector_nth(vec, i); + memcpy(dst, elt, vec->vec_elt_size); + return vec; +} + +static inline VectorTy* vector_copy(VectorTy *vec) { + IntTy len = vector_length(vec); + void *start = vector_nth(vec, 0); + VectorTy *vec2 = vector_alloc(len, vec->vec_elt_size); + memcpy(vec2->vec_data, start, len * vec->vec_elt_size); + return vec2; +} + +static inline VectorTy* vector_inplace_sort(VectorTy *vec, int (*compar)(const void *, const void*)) { + void *start = vector_nth(vec, 0); + qsort(start, vector_length(vec), vec->vec_elt_size, compar); + return vec; +} + +static inline VectorTy* vector_sort(VectorTy *vec, int (*compar)(const void *, const void*)) { + VectorTy *vec2 = vector_copy(vec); + vector_inplace_sort(vec2, compar); + return vec2; +} + +static inline VectorTy* vector_concat(VectorTy *vec) { + // Length of the input vector. + IntTy len = vector_length(vec); + // Length of the concatenated vector. + IntTy result_len = 0; + // Size of each element in the concatenated vector. + IntTy result_elt_size = 0; + VectorTy **elt_ref, *elt; + for (IntTy i = 0; i < len; i++) { + elt_ref = vector_nth(vec, i); + elt = *elt_ref; + result_elt_size = elt->vec_elt_size; + result_len += vector_length(elt); + } + + // Concatenated vector. + VectorTy *result = vector_alloc(result_len, result_elt_size); + IntTy elt_len; + // A counter that tracks the index of elements in 'result'. + IntTy k = 0; + for (IntTy i = 0; i < len; i++) { + elt_ref = vector_nth(vec, i); + elt = *elt_ref; + elt_len = vector_length(elt); + + for (IntTy j = 0; j < elt_len; j++) { + void* k_elt = vector_nth(elt, j); + vector_inplace_update(result, k, k_elt); + k++; + } + } + + return result; +} + +static inline void vector_free(VectorTy *vec) { + free(vec->vec_data); + free(vec); + return; +} + +static inline VectorTy* vector_merge(VectorTy *vec1, VectorTy *vec2) { + if (vec1->vec_upper != vec2->vec_lower) { + printf("vector_merge: non-contiguous slices, (%lld,%lld), (%lld,%lld).", + vec1->vec_lower, vec1->vec_upper, vec2->vec_lower, vec2->vec_upper); + exit(1); + } + VectorTy *merged = ALLOC(sizeof(VectorTy)); + if (merged == NULL) { + printf("vector_merge: malloc failed: %ld", sizeof(VectorTy)); + exit(1); + } + merged->vec_lower = vec1->vec_lower; + merged->vec_upper = vec2->vec_upper; + merged->vec_elt_size = vec1->vec_elt_size; + merged->vec_data = vec1->vec_data; + return merged; +} + +void print_timing_array(VectorTy *times) { + printf("TIMES: ["); + double *d; + IntTy n = vector_length(times); + for(int i = 0; i < n; i++) { + d = vector_nth(times, i); + if (i == (n-1)) { + printf("%f",*d); + } + else { + printf("%f, ",*d); + } + } + printf("]\n"); +} + +double sum_timing_array(VectorTy *times) { + double *d; + double acc = 0; + for(int i = 0; i < vector_length(times); i++) { + d = vector_nth(times, i); + acc += *d; + } + return acc; +} + +// ------------------------------------- +// Linked lists +// ------------------------------------- + +typedef struct ListTy_struct { + IntTy ll_data_size; + void* ll_data; + struct ListTy_struct* ll_next; +} ListTy; + +static inline ListTy* list_alloc(IntTy data_size) { + // ListTy *ls = ALLOC(sizeof(ListTy)); + ListTy *ls = BUMPALLOC(sizeof(ListTy)); + ls->ll_data_size = data_size; + ls->ll_data = NULL; + ls->ll_next = NULL; + return ls; +} + +static inline BoolTy list_is_empty(ListTy *ls) { + return ls->ll_next == NULL; +} + +static inline ListTy* list_cons(void* elt, ListTy *ls) { + // void* data = ALLOC(ls->data_size); + void* data = BUMPALLOC(ls->ll_data_size); + if (data == NULL) { + printf("list_cons: malloc failed: %lld", ls->ll_data_size); + exit(1); + } + memcpy(data, elt, ls->ll_data_size); + // ListTy *res = ALLOC(sizeof(ListTy)); + ListTy *res = BUMPALLOC(sizeof(ListTy)); + res->ll_data_size = ls->ll_data_size; + res->ll_data = data; + res->ll_next = (ListTy*) ls; + return res; +} + +static inline void* list_head(ListTy *ls) { + return ls->ll_data; +} + +static inline ListTy* list_tail(ListTy *ls) { + return ls->ll_next; +} + +static inline void list_free(ListTy *ls) { + free(ls->ll_data); + free(ls); + return; +} + +static inline ListTy* list_copy(ListTy *ls) { + ListTy *ls2 = list_alloc(ls->ll_data_size); + if (ls->ll_data != NULL) { + void* data = BUMPALLOC(ls->ll_data_size); + memcpy(data, ls->ll_data, ls->ll_data_size); + ls2->ll_data = data; + } + ls2->ll_next = ls->ll_next; + return ls2; +} + +// ------------------------------------- +// Ppm Images +// ------------------------------------- + +typedef struct __Pixel_struct { + IntTy field0; + IntTy field1; + IntTy field2; +} __Pixel; + +void writePpm(char* filename, IntTy width, IntTy height, VectorTy *pixels); +void writePpm_loop(FILE *fp, IntTy idx, IntTy end, VectorTy *pixels); + +// Example: writePpm("gibbon_rgb_1000.ppm", 1000, 1000, pixels); +void writePpm(char* filename, IntTy width, IntTy height, VectorTy *pixels) +{ + FILE *fp; + fp = fopen(filename, "w+"); + fprintf(fp, "P3\n"); + fprintf(fp, "%lld %lld\n255\n", width, height); + IntTy len = vector_length(pixels); + writePpm_loop(fp, 0, len, pixels); + fclose(fp); + return; +} + +void writePpm_loop(FILE *fp, IntTy idx, IntTy end, VectorTy *pixels) +{ + BoolTy fltIf_5768_6575 = idx == end; + + if (fltIf_5768_6575) { + return; + } else { + __Pixel *tmp_112; + tmp_112 = (__Pixel *) vector_nth(pixels, idx); + __Pixel tup = *tmp_112; + IntTy x = tup.field0; + IntTy y = tup.field1; + IntTy z = tup.field2; + // write to file. + fprintf(fp, "%lld %lld %lld\n", x, y, z); + writePpm_loop(fp, (idx+1), end, pixels); + } +} + +/* -------------------------------------------------------------------------------- */ + +int main(int argc, char** argv) +{ + // parameters to parse: + // + // num iterations: How many times to repeat a benchmark. + // tree size: An integer passes to `build_tree()`. + + struct rlimit lim; + int code; + if ( (code = getrlimit(RLIMIT_STACK, &lim)) ) { + fprintf(stderr, " [gibbon rts] failed to getrlimit, code %d\n", code); + exit(1); + } + + // lim.rlim_cur = 1024LU * 1024LU * 1024LU; // 1GB stack. + lim.rlim_cur = 512LU * 1024LU * 1024LU; // 500MB stack. + // lim.rlim_max = lim.rlim_cur; // Normal users may only be able to decrease this. + + // WARNING: Haven't yet figured out why this doesn't work on MacOS... +#ifndef __APPLE__ + code = setrlimit(RLIMIT_STACK, &lim); + while (code) { + fprintf(stderr, " [gibbon rts] Failed to set stack size to %llu, code %d\n", (unsigned long long)lim.rlim_cur, code); + lim.rlim_cur /= 2; + // lim.rlim_max /= 2; + if(lim.rlim_cur < 100 * 1024) { + fprintf(stderr, " [gibbon rts] Failed setrlimit stack size to something reasonable; giving up.\n"); + break; // abort(); + } + int code = setrlimit(RLIMIT_STACK, &lim); + } +#endif + + int got_numargs = 0; // How many numeric arguments have we got. + + int i; + for (i = 1; i < argc; ++i) + { + if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) { + show_usage(argv); + exit(0); + } + else if (strcmp(argv[i], "--biginf-buffer-size") == 0 && i < argc - 1) + { + global_init_biginf_buf_size = atoll(argv[i + 1]); + i++; + } + else if (strcmp(argv[i], "--inf-buffer-size") == 0 && i < argc - 1) + { + global_init_inf_buf_size = atoll(argv[i + 1]); + i++; + } + else if ((strcmp(argv[i], "--bench-input") == 0)) { + if (i+1 >= argc) { + fprintf(stderr, "Not enough arguments after --bench-input, expected .\n"); + show_usage(argv); + exit(1); + } + global_benchfile_param = argv[i+1]; + i++; + } + else if ((strcmp(argv[i], "--array-input") == 0)) { + if (i+1 >= argc) { + fprintf(stderr, "Not enough arguments after --array-input, expected .\n"); + show_usage(argv); + exit(1); + } + global_arrayfile_param = argv[i+1]; + i++; + } + else if (strcmp(argv[i], "--array-input-length") == 0 && i < argc - 1) { + global_arrayfile_length_param = atoll(argv[i+1]); + i++; + } + else if (strcmp(argv[i], "--bench-prog") == 0 && i < argc - 1) { + int len = strlen(argv[i+1]); + global_bench_prog_param = (char*) malloc((len+1)*sizeof(char)); + strncpy(global_bench_prog_param,argv[i+1],len); + i++; + } + // If present, we expect the two arguments to be + else if (got_numargs >= 2) { + fprintf(stderr, "Extra arguments left over: "); + for(; i < argc; i++) fprintf(stderr, "%s ", argv[i]); + show_usage(argv); + exit(1); + } else { + if (got_numargs == 0) { + global_size_param = atoll(argv[i]); + got_numargs ++; + } else { + global_iters_param = atoll(argv[i]); + } + } + } + + // Initialize global_bench_prog_param to an empty string in case + // the runtime argument --bench-prog isn't passed. + if (global_bench_prog_param == NULL) { + global_bench_prog_param = (char*) malloc(1*sizeof(char)); + *global_bench_prog_param = '\n'; + } + + __main_expr(); + + return 0; +} + +// ----------------------------------------------------------------------------- +// Program starts here +// ----------------------------------------------------------------------------- + +typedef struct Prod_struct { } Prod; +typedef struct Int64Prod_struct { + IntTy field0; + } Int64Prod; +typedef struct Int64Int64Int64Int64CursorCursorProd_struct { + IntTy field0; + IntTy field1; + IntTy field2; + IntTy field3; + CursorTy field4; + CursorTy field5; + } Int64Int64Int64Int64CursorCursorProd; +typedef struct Int64Int64Int64CursorCursorProd_struct { + IntTy field0; + IntTy field1; + IntTy field2; + CursorTy field3; + CursorTy field4; + } Int64Int64Int64CursorCursorProd; +typedef struct BoolProd_struct { + BoolTy field0; + } BoolProd; +typedef struct TagCursorProd_struct { + TagTyPacked field0; + CursorTy field1; + } TagCursorProd; +typedef struct CursorProd_struct { + CursorTy field0; + } CursorProd; +IntTy sumRight(CursorTy m_34_689_917); +CursorTy build(IntTy x_40_695_926, IntTy sz_41_696_927, CursorTy m_42_697_928); +IntTy ratio(); +IntTy delta(); +IntTy size_316(CursorTy m_173_698_938); +CursorTy singleL_323(IntTy k1_100_704_944, IntTy x1_101_705_945, + CursorTy t1_102_706_946, CursorTy m_103_707_947); +CursorTy doubleL_324(IntTy k1_71_713_954, IntTy x1_72_714_955, + CursorTy t1_73_715_956, CursorTy m0_74_716_957); +CursorTy rotateL_317(IntTy k_125_722_963, IntTy x_126_723_964, + CursorTy l_127_724_965, CursorTy r_128_725_966); +CursorTy bin_322(IntTy k_110_731_977, IntTy x_111_732_978, + CursorTy l_112_733_979, CursorTy r_113_734_980); +CursorTy singleR_319(IntTy k1_90_735_985, IntTy x1_91_736_986, + CursorTy m_92_737_987, CursorTy t3_93_738_988); +CursorTy doubleR_320(IntTy k1_56_744_995, IntTy x1_57_745_996, + CursorTy m0_58_746_997, CursorTy t4_59_747_998); +CursorTy empty_321(); +CursorTy rotateR_318(IntTy k_115_753_1004, IntTy x_116_754_1005, + CursorTy l_117_755_1006, CursorTy r_118_756_1007); +CursorTy balance_315(IntTy k_135_762_1018, IntTy x_136_763_1019, + CursorTy l_137_764_1020, CursorTy r_138_765_1021); +CursorTy singleton_312(IntTy k_52_766_1042, IntTy x_53_767_1043); +CursorTy insert_314(IntTy kx_43_768_1046, IntTy x_44_769_1047, + CursorTy m_45_770_1048); +CursorTy _copy_without_ptrs_Map_v_313(CursorTy arg_624_776_1058); +CursorTy _copy_Map_v_313(CursorTy arg_613_787_1069); +unsigned char _traverse_Map_v_313(CursorTy arg_635_798_1080); +unsigned char _print_Map_v_313(CursorTy arg_646_806_1088); +CursorTy caseFn_666(IntTy x1_72_667_826_1108, IntTy k1_71_668_827_1109, + CursorTy t1_73_669_828_1110, CursorTy m1_79_670_829_1111, + IntTy k2_77_671_830_1112, IntTy x2_78_672_831_1113, + CursorTy t4_80_673_832_1114); +CursorTy caseFn_674(IntTy x1_57_675_838_1122, IntTy k1_56_676_839_1123, + CursorTy t4_59_677_840_1124, CursorTy m1_65_678_841_1125, + IntTy k2_62_679_842_1126, IntTy x2_63_680_843_1127, + CursorTy t1_64_681_844_1128); +IntTy sumRight(CursorTy m_34_689_917) +{ + TagTyPacked tag_1143 = *(TagTyPacked *) m_34_689_917; + CursorTy tail_1144 = m_34_689_917 + sizeof(IntTy); + + + switch_1146: + ; + switch (tag_1143) { + + case 0: + { + return 0; + break; + } + + case 1: + { + IntTy wildcard__1_35_690_918 = + ((Int64Int64Int64CursorCursorProd *) tail_1144)->field0; + IntTy wildcard__2_36_691_919 = + ((Int64Int64Int64CursorCursorProd *) tail_1144)->field1; + IntTy v_37_692_920 = + ((Int64Int64Int64CursorCursorProd *) tail_1144)->field2; + CursorTy l_38_693_921 = + ((Int64Int64Int64CursorCursorProd *) tail_1144)->field3; + CursorTy r_39_694_922 = + ((Int64Int64Int64CursorCursorProd *) tail_1144)->field4; + IntTy fltPrm_852_923 = sumRight(r_39_694_922); + IntTy fltPrm_851_924 = fltPrm_852_923 + v_37_692_920; + IntTy fltPrm_853_925 = sumRight(r_39_694_922); + IntTy flt_1145 = fltPrm_851_924 + fltPrm_853_925; + + return flt_1145; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1143"); + exit(1); + } + } +} +CursorTy build(IntTy x_40_695_926, IntTy sz_41_696_927, CursorTy m_42_697_928) +{ + BoolTy fltIf_854_929 = sz_41_696_927 == 0; + + if (fltIf_854_929) { + return m_42_697_928; + } else { + IntTy fltPrm_856_930 = sz_41_696_927 / 2; + IntTy fltAppE_855_931 = x_40_695_926 - fltPrm_856_930; + IntTy fltAppE_857_932 = sz_41_696_927 / 2; + IntTy fltPrm_860_933 = sz_41_696_927 / 2; + IntTy fltAppE_859_934 = x_40_695_926 + fltPrm_860_933; + IntTy fltAppE_861_935 = sz_41_696_927 / 2; + CursorTy fltAppE_862_936 = + insert_314(x_40_695_926, x_40_695_926, m_42_697_928); + CursorTy fltAppE_858_937 = + build(fltAppE_859_934, fltAppE_861_935, fltAppE_862_936); + + return build(fltAppE_855_931, fltAppE_857_932, fltAppE_858_937); + } +} +IntTy ratio() +{ + return 2; +} +IntTy delta() +{ + return 4; +} +IntTy size_316(CursorTy m_173_698_938) +{ + TagTyPacked tag_1147 = *(TagTyPacked *) m_173_698_938; + CursorTy tail_1148 = m_173_698_938 + sizeof(IntTy); + + + switch_1149: + ; + switch (tag_1147) { + + case 0: + { + return 0; + break; + } + + case 1: + { + IntTy sz_175_699_939 = + ((Int64Int64Int64CursorCursorProd *) tail_1148)->field0; + IntTy wildcard__18_176_700_940 = + ((Int64Int64Int64CursorCursorProd *) tail_1148)->field1; + IntTy wildcard__19_177_701_941 = + ((Int64Int64Int64CursorCursorProd *) tail_1148)->field2; + CursorTy wildcard__20_178_702_942 = + ((Int64Int64Int64CursorCursorProd *) tail_1148)->field3; + CursorTy wildcard__21_179_703_943 = + ((Int64Int64Int64CursorCursorProd *) tail_1148)->field4; + + return sz_175_699_939; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1147"); + exit(1); + } + } +} +CursorTy singleL_323(IntTy k1_100_704_944, IntTy x1_101_705_945, + CursorTy t1_102_706_946, CursorTy m_103_707_947) +{ + TagTyPacked tag_1150 = *(TagTyPacked *) m_103_707_947; + CursorTy tail_1151 = m_103_707_947 + sizeof(IntTy); + + + switch_1152: + ; + switch (tag_1150) { + + case 1: + { + IntTy wildcard__123_105_708_948 = + ((Int64Int64Int64CursorCursorProd *) tail_1151)->field0; + IntTy k2_106_709_949 = + ((Int64Int64Int64CursorCursorProd *) tail_1151)->field1; + IntTy x2_107_710_950 = + ((Int64Int64Int64CursorCursorProd *) tail_1151)->field2; + CursorTy t2_108_711_951 = + ((Int64Int64Int64CursorCursorProd *) tail_1151)->field3; + CursorTy t3_109_712_952 = + ((Int64Int64Int64CursorCursorProd *) tail_1151)->field4; + CursorTy fltAppE_863_953 = + bin_322(k1_100_704_944, x1_101_705_945, t1_102_706_946, t2_108_711_951); + + return bin_322(k2_106_709_949, x2_107_710_950, fltAppE_863_953, + t3_109_712_952); + break; + } + + case 0: + { + return empty_321(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1150"); + exit(1); + } + } +} +CursorTy doubleL_324(IntTy k1_71_713_954, IntTy x1_72_714_955, + CursorTy t1_73_715_956, CursorTy m0_74_716_957) +{ + TagTyPacked tag_1153 = *(TagTyPacked *) m0_74_716_957; + CursorTy tail_1154 = m0_74_716_957 + sizeof(IntTy); + + + switch_1155: + ; + switch (tag_1153) { + + case 1: + { + IntTy wildcard__143_76_717_958 = + ((Int64Int64Int64CursorCursorProd *) tail_1154)->field0; + IntTy k2_77_718_959 = + ((Int64Int64Int64CursorCursorProd *) tail_1154)->field1; + IntTy x2_78_719_960 = + ((Int64Int64Int64CursorCursorProd *) tail_1154)->field2; + CursorTy m1_79_720_961 = + ((Int64Int64Int64CursorCursorProd *) tail_1154)->field3; + CursorTy t4_80_721_962 = + ((Int64Int64Int64CursorCursorProd *) tail_1154)->field4; + + return caseFn_666(x1_72_714_955, k1_71_713_954, t1_73_715_956, + m1_79_720_961, k2_77_718_959, x2_78_719_960, + t4_80_721_962); + break; + } + + case 0: + { + return empty_321(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1153"); + exit(1); + } + } +} +CursorTy rotateL_317(IntTy k_125_722_963, IntTy x_126_723_964, + CursorTy l_127_724_965, CursorTy r_128_725_966) +{ + TagTyPacked tag_1156 = *(TagTyPacked *) r_128_725_966; + CursorTy tail_1157 = r_128_725_966 + sizeof(IntTy); + + + switch_1158: + ; + switch (tag_1156) { + + case 1: + { + IntTy wildcard__94_130_726_967 = + ((Int64Int64Int64CursorCursorProd *) tail_1157)->field0; + IntTy wildcard__95_131_727_968 = + ((Int64Int64Int64CursorCursorProd *) tail_1157)->field1; + IntTy wildcard__96_132_728_969 = + ((Int64Int64Int64CursorCursorProd *) tail_1157)->field2; + CursorTy ly_133_729_970 = + ((Int64Int64Int64CursorCursorProd *) tail_1157)->field3; + CursorTy ry_134_730_971 = + ((Int64Int64Int64CursorCursorProd *) tail_1157)->field4; + IntTy fltPrm_865_972 = size_316(ly_133_729_970); + IntTy fltPrm_867_973 = ratio(); + IntTy fltPrm_868_974 = size_316(ry_134_730_971); + IntTy fltPrm_866_975 = fltPrm_867_973 * fltPrm_868_974; + BoolTy fltIf_864_976 = fltPrm_865_972 < fltPrm_866_975; + + if (fltIf_864_976) { + return singleL_323(k_125_722_963, x_126_723_964, l_127_724_965, + r_128_725_966); + } else { + return doubleL_324(k_125_722_963, x_126_723_964, l_127_724_965, + r_128_725_966); + } + break; + } + + case 0: + { + return empty_321(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1156"); + exit(1); + } + } +} +CursorTy bin_322(IntTy k_110_731_977, IntTy x_111_732_978, + CursorTy l_112_733_979, CursorTy r_113_734_980) +{ + IntTy fltPrm_871_981 = size_316(l_112_733_979); + IntTy fltPrm_872_982 = size_316(r_113_734_980); + IntTy fltPrm_870_983 = fltPrm_871_981 + fltPrm_872_982; + IntTy fltPkd_869_984 = fltPrm_870_983 + 1; + PtrTy tailift_1159 = ALLOC(sizeof(Int64Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1159)->field0 = 1; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1159)->field1 = + fltPkd_869_984; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1159)->field2 = + k_110_731_977; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1159)->field3 = + x_111_732_978; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1159)->field4 = + l_112_733_979; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1159)->field5 = + r_113_734_980; + return tailift_1159; +} +CursorTy singleR_319(IntTy k1_90_735_985, IntTy x1_91_736_986, + CursorTy m_92_737_987, CursorTy t3_93_738_988) +{ + TagTyPacked tag_1160 = *(TagTyPacked *) m_92_737_987; + CursorTy tail_1161 = m_92_737_987 + sizeof(IntTy); + + + switch_1162: + ; + switch (tag_1160) { + + case 1: + { + IntTy wildcard__133_95_739_989 = + ((Int64Int64Int64CursorCursorProd *) tail_1161)->field0; + IntTy k2_96_740_990 = + ((Int64Int64Int64CursorCursorProd *) tail_1161)->field1; + IntTy x2_97_741_991 = + ((Int64Int64Int64CursorCursorProd *) tail_1161)->field2; + CursorTy t1_98_742_992 = + ((Int64Int64Int64CursorCursorProd *) tail_1161)->field3; + CursorTy t2_99_743_993 = + ((Int64Int64Int64CursorCursorProd *) tail_1161)->field4; + CursorTy fltAppE_873_994 = + bin_322(k1_90_735_985, x1_91_736_986, t2_99_743_993, t3_93_738_988); + + return bin_322(k2_96_740_990, x2_97_741_991, t1_98_742_992, + fltAppE_873_994); + break; + } + + case 0: + { + return empty_321(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1160"); + exit(1); + } + } +} +CursorTy doubleR_320(IntTy k1_56_744_995, IntTy x1_57_745_996, + CursorTy m0_58_746_997, CursorTy t4_59_747_998) +{ + TagTyPacked tag_1163 = *(TagTyPacked *) m0_58_746_997; + CursorTy tail_1164 = m0_58_746_997 + sizeof(IntTy); + + + switch_1165: + ; + switch (tag_1163) { + + case 1: + { + IntTy wildcard__167_61_748_999 = + ((Int64Int64Int64CursorCursorProd *) tail_1164)->field0; + IntTy k2_62_749_1000 = + ((Int64Int64Int64CursorCursorProd *) tail_1164)->field1; + IntTy x2_63_750_1001 = + ((Int64Int64Int64CursorCursorProd *) tail_1164)->field2; + CursorTy t1_64_751_1002 = + ((Int64Int64Int64CursorCursorProd *) tail_1164)->field3; + CursorTy m1_65_752_1003 = + ((Int64Int64Int64CursorCursorProd *) tail_1164)->field4; + + return caseFn_674(x1_57_745_996, k1_56_744_995, t4_59_747_998, + m1_65_752_1003, k2_62_749_1000, x2_63_750_1001, + t1_64_751_1002); + break; + } + + case 0: + { + return empty_321(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1163"); + exit(1); + } + } +} +CursorTy empty_321() +{ + PtrTy tailift_1166 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) tailift_1166)->field0 = 0; + return tailift_1166; +} +CursorTy rotateR_318(IntTy k_115_753_1004, IntTy x_116_754_1005, + CursorTy l_117_755_1006, CursorTy r_118_756_1007) +{ + TagTyPacked tag_1167 = *(TagTyPacked *) l_117_755_1006; + CursorTy tail_1168 = l_117_755_1006 + sizeof(IntTy); + + + switch_1169: + ; + switch (tag_1167) { + + case 1: + { + IntTy wildcard__106_120_757_1008 = + ((Int64Int64Int64CursorCursorProd *) tail_1168)->field0; + IntTy wildcard__107_121_758_1009 = + ((Int64Int64Int64CursorCursorProd *) tail_1168)->field1; + IntTy wildcard__108_122_759_1010 = + ((Int64Int64Int64CursorCursorProd *) tail_1168)->field2; + CursorTy ly_123_760_1011 = + ((Int64Int64Int64CursorCursorProd *) tail_1168)->field3; + CursorTy ry_124_761_1012 = + ((Int64Int64Int64CursorCursorProd *) tail_1168)->field4; + IntTy fltPrm_875_1013 = size_316(ry_124_761_1012); + IntTy fltPrm_877_1014 = ratio(); + IntTy fltPrm_878_1015 = size_316(ly_123_760_1011); + IntTy fltPrm_876_1016 = fltPrm_877_1014 * fltPrm_878_1015; + BoolTy fltIf_874_1017 = fltPrm_875_1013 < fltPrm_876_1016; + + if (fltIf_874_1017) { + return singleR_319(k_115_753_1004, x_116_754_1005, + l_117_755_1006, r_118_756_1007); + } else { + return doubleR_320(k_115_753_1004, x_116_754_1005, + l_117_755_1006, r_118_756_1007); + } + break; + } + + case 0: + { + return empty_321(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1167"); + exit(1); + } + } +} +CursorTy balance_315(IntTy k_135_762_1018, IntTy x_136_763_1019, + CursorTy l_137_764_1020, CursorTy r_138_765_1021) +{ + IntTy fltPrm_881_1022 = size_316(l_137_764_1020); + IntTy fltPrm_882_1023 = size_316(r_138_765_1021); + IntTy fltPrm_880_1024 = fltPrm_881_1022 + fltPrm_882_1023; + BoolTy fltIf_879_1025 = fltPrm_880_1024 <= 1; + + if (fltIf_879_1025) { + IntTy fltPrm_884_1026 = size_316(l_137_764_1020); + IntTy fltPrm_885_1027 = size_316(r_138_765_1021); + IntTy fltPkd_883_1028 = fltPrm_884_1026 + fltPrm_885_1027; + PtrTy tailift_1170 = + ALLOC(sizeof(Int64Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1170)->field0 = 1; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1170)->field1 = + fltPkd_883_1028; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1170)->field2 = + k_135_762_1018; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1170)->field3 = + x_136_763_1019; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1170)->field4 = + l_137_764_1020; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1170)->field5 = + r_138_765_1021; + return tailift_1170; + } else { + IntTy fltPrm_887_1029 = size_316(r_138_765_1021); + IntTy fltPrm_889_1030 = delta(); + IntTy fltPrm_890_1031 = size_316(l_137_764_1020); + IntTy fltPrm_888_1032 = fltPrm_889_1030 * fltPrm_890_1031; + BoolTy fltIf_886_1033 = fltPrm_887_1029 >= fltPrm_888_1032; + + if (fltIf_886_1033) { + return rotateL_317(k_135_762_1018, x_136_763_1019, l_137_764_1020, + r_138_765_1021); + } else { + IntTy fltPrm_892_1034 = size_316(l_137_764_1020); + IntTy fltPrm_894_1035 = delta(); + IntTy fltPrm_895_1036 = size_316(r_138_765_1021); + IntTy fltPrm_893_1037 = fltPrm_894_1035 * fltPrm_895_1036; + BoolTy fltIf_891_1038 = fltPrm_892_1034 >= fltPrm_893_1037; + + if (fltIf_891_1038) { + return rotateR_318(k_135_762_1018, x_136_763_1019, + l_137_764_1020, r_138_765_1021); + } else { + IntTy fltPrm_897_1039 = size_316(l_137_764_1020); + IntTy fltPrm_898_1040 = size_316(r_138_765_1021); + IntTy fltPkd_896_1041 = fltPrm_897_1039 + fltPrm_898_1040; + PtrTy tailift_1171 = + ALLOC(sizeof(Int64Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1171)->field0 = + 1; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1171)->field1 = + fltPkd_896_1041; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1171)->field2 = + k_135_762_1018; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1171)->field3 = + x_136_763_1019; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1171)->field4 = + l_137_764_1020; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1171)->field5 = + r_138_765_1021; + return tailift_1171; + } + } + } +} +CursorTy singleton_312(IntTy k_52_766_1042, IntTy x_53_767_1043) +{ + PtrTy fltPkd_899_1044 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_899_1044)->field0 = 0; + + PtrTy fltPkd_900_1045 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_900_1045)->field0 = 0; + + PtrTy tailift_1172 = ALLOC(sizeof(Int64Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1172)->field0 = 1; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1172)->field1 = 1; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1172)->field2 = + k_52_766_1042; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1172)->field3 = + x_53_767_1043; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1172)->field4 = + fltPkd_899_1044; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1172)->field5 = + fltPkd_900_1045; + return tailift_1172; +} +CursorTy insert_314(IntTy kx_43_768_1046, IntTy x_44_769_1047, + CursorTy m_45_770_1048) +{ + TagTyPacked tag_1173 = *(TagTyPacked *) m_45_770_1048; + CursorTy tail_1174 = m_45_770_1048 + sizeof(IntTy); + + + switch_1176: + ; + switch (tag_1173) { + + case 0: + { + return singleton_312(kx_43_768_1046, x_44_769_1047); + break; + } + + case 1: + { + IntTy sz_47_771_1049 = + ((Int64Int64Int64CursorCursorProd *) tail_1174)->field0; + IntTy k_48_772_1050 = + ((Int64Int64Int64CursorCursorProd *) tail_1174)->field1; + IntTy v_49_773_1051 = + ((Int64Int64Int64CursorCursorProd *) tail_1174)->field2; + CursorTy l_50_774_1052 = + ((Int64Int64Int64CursorCursorProd *) tail_1174)->field3; + CursorTy r_51_775_1053 = + ((Int64Int64Int64CursorCursorProd *) tail_1174)->field4; + BoolTy fltIf_901_1054 = kx_43_768_1046 == k_48_772_1050; + + if (fltIf_901_1054) { + PtrTy tailift_1175 = + ALLOC(sizeof(Int64Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1175)->field0 = + 1; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1175)->field1 = + sz_47_771_1049; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1175)->field2 = + k_48_772_1050; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1175)->field3 = + x_44_769_1047; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1175)->field4 = + l_50_774_1052; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1175)->field5 = + r_51_775_1053; + return tailift_1175; + } else { + BoolTy fltIf_902_1055 = kx_43_768_1046 <= k_48_772_1050; + + if (fltIf_902_1055) { + CursorTy fltAppE_903_1056 = + insert_314(kx_43_768_1046, x_44_769_1047, l_50_774_1052); + + return balance_315(k_48_772_1050, v_49_773_1051, + fltAppE_903_1056, r_51_775_1053); + } else { + CursorTy fltAppE_904_1057 = + insert_314(kx_43_768_1046, x_44_769_1047, r_51_775_1053); + + return balance_315(k_48_772_1050, v_49_773_1051, + l_50_774_1052, fltAppE_904_1057); + } + } + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1173"); + exit(1); + } + } +} +CursorTy _copy_without_ptrs_Map_v_313(CursorTy arg_624_776_1058) +{ + TagTyPacked tag_1177 = *(TagTyPacked *) arg_624_776_1058; + CursorTy tail_1178 = arg_624_776_1058 + sizeof(IntTy); + + + switch_1181: + ; + switch (tag_1177) { + + case 0: + { + PtrTy tailift_1179 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) tailift_1179)->field0 = 0; + return tailift_1179; + break; + } + + case 1: + { + IntTy x_625_777_1059 = + ((Int64Int64Int64CursorCursorProd *) tail_1178)->field0; + IntTy x_626_778_1060 = + ((Int64Int64Int64CursorCursorProd *) tail_1178)->field1; + IntTy x_627_779_1061 = + ((Int64Int64Int64CursorCursorProd *) tail_1178)->field2; + CursorTy x_628_780_1062 = + ((Int64Int64Int64CursorCursorProd *) tail_1178)->field3; + CursorTy x_629_781_1063 = + ((Int64Int64Int64CursorCursorProd *) tail_1178)->field4; + CursorTy y_633_785_1067 = + _copy_without_ptrs_Map_v_313(x_628_780_1062); + CursorTy y_634_786_1068 = + _copy_without_ptrs_Map_v_313(x_629_781_1063); + PtrTy tailift_1180 = + ALLOC(sizeof(Int64Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1180)->field0 = 1; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1180)->field1 = + x_625_777_1059; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1180)->field2 = + x_626_778_1060; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1180)->field3 = + x_627_779_1061; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1180)->field4 = + y_633_785_1067; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1180)->field5 = + y_634_786_1068; + return tailift_1180; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1177"); + exit(1); + } + } +} +CursorTy _copy_Map_v_313(CursorTy arg_613_787_1069) +{ + TagTyPacked tag_1182 = *(TagTyPacked *) arg_613_787_1069; + CursorTy tail_1183 = arg_613_787_1069 + sizeof(IntTy); + + + switch_1186: + ; + switch (tag_1182) { + + case 0: + { + PtrTy tailift_1184 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) tailift_1184)->field0 = 0; + return tailift_1184; + break; + } + + case 1: + { + IntTy x_614_788_1070 = + ((Int64Int64Int64CursorCursorProd *) tail_1183)->field0; + IntTy x_615_789_1071 = + ((Int64Int64Int64CursorCursorProd *) tail_1183)->field1; + IntTy x_616_790_1072 = + ((Int64Int64Int64CursorCursorProd *) tail_1183)->field2; + CursorTy x_617_791_1073 = + ((Int64Int64Int64CursorCursorProd *) tail_1183)->field3; + CursorTy x_618_792_1074 = + ((Int64Int64Int64CursorCursorProd *) tail_1183)->field4; + CursorTy y_622_796_1078 = _copy_Map_v_313(x_617_791_1073); + CursorTy y_623_797_1079 = _copy_Map_v_313(x_618_792_1074); + PtrTy tailift_1185 = + ALLOC(sizeof(Int64Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1185)->field0 = 1; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1185)->field1 = + x_614_788_1070; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1185)->field2 = + x_615_789_1071; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1185)->field3 = + x_616_790_1072; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1185)->field4 = + y_622_796_1078; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1185)->field5 = + y_623_797_1079; + return tailift_1185; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1182"); + exit(1); + } + } +} +unsigned char _traverse_Map_v_313(CursorTy arg_635_798_1080) +{ + TagTyPacked tag_1187 = *(TagTyPacked *) arg_635_798_1080; + CursorTy tail_1188 = arg_635_798_1080 + sizeof(IntTy); + + + switch_1189: + ; + switch (tag_1187) { + + case 0: + { + return 0; + break; + } + + case 1: + { + IntTy x_636_799_1081 = + ((Int64Int64Int64CursorCursorProd *) tail_1188)->field0; + IntTy x_637_800_1082 = + ((Int64Int64Int64CursorCursorProd *) tail_1188)->field1; + IntTy x_638_801_1083 = + ((Int64Int64Int64CursorCursorProd *) tail_1188)->field2; + CursorTy x_639_802_1084 = + ((Int64Int64Int64CursorCursorProd *) tail_1188)->field3; + CursorTy x_640_803_1085 = + ((Int64Int64Int64CursorCursorProd *) tail_1188)->field4; + unsigned char y_644_804_1086 = _traverse_Map_v_313(x_639_802_1084); + unsigned char y_645_805_1087 = _traverse_Map_v_313(x_640_803_1085); + + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1187"); + exit(1); + } + } +} +unsigned char _print_Map_v_313(CursorTy arg_646_806_1088) +{ + TagTyPacked tag_1190 = *(TagTyPacked *) arg_646_806_1088; + CursorTy tail_1191 = arg_646_806_1088 + sizeof(IntTy); + + + switch_1192: + ; + switch (tag_1190) { + + case 0: + { + unsigned char wildcard_647_807_1089 = print_symbol(1139); + unsigned char wildcard_648_808_1090 = print_symbol(1138); + + return 0; + break; + } + + case 1: + { + IntTy x_649_809_1091 = + ((Int64Int64Int64CursorCursorProd *) tail_1191)->field0; + IntTy x_650_810_1092 = + ((Int64Int64Int64CursorCursorProd *) tail_1191)->field1; + IntTy x_651_811_1093 = + ((Int64Int64Int64CursorCursorProd *) tail_1191)->field2; + CursorTy x_652_812_1094 = + ((Int64Int64Int64CursorCursorProd *) tail_1191)->field3; + CursorTy x_653_813_1095 = + ((Int64Int64Int64CursorCursorProd *) tail_1191)->field4; + unsigned char wildcard_659_814_1096 = print_symbol(1140); + unsigned char wildcard_665_815_1097 = print_symbol(1141); + unsigned char y_654_816_1098 = printf("%lld", x_649_809_1091); + unsigned char wildcard_664_817_1099 = print_symbol(1141); + unsigned char y_655_818_1100 = printf("%lld", x_650_810_1092); + unsigned char wildcard_663_819_1101 = print_symbol(1141); + unsigned char y_656_820_1102 = printf("%lld", x_651_811_1093); + unsigned char wildcard_662_821_1103 = print_symbol(1141); + unsigned char y_657_822_1104 = _print_Map_v_313(x_652_812_1094); + unsigned char wildcard_661_823_1105 = print_symbol(1141); + unsigned char y_658_824_1106 = _print_Map_v_313(x_653_813_1095); + unsigned char wildcard_660_825_1107 = print_symbol(1138); + + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1190"); + exit(1); + } + } +} +CursorTy caseFn_666(IntTy x1_72_667_826_1108, IntTy k1_71_668_827_1109, + CursorTy t1_73_669_828_1110, CursorTy m1_79_670_829_1111, + IntTy k2_77_671_830_1112, IntTy x2_78_672_831_1113, + CursorTy t4_80_673_832_1114) +{ + TagTyPacked tag_1193 = *(TagTyPacked *) m1_79_670_829_1111; + CursorTy tail_1194 = m1_79_670_829_1111 + sizeof(IntTy); + + + switch_1195: + ; + switch (tag_1193) { + + case 1: + { + IntTy wildcard__144_81_833_1115 = + ((Int64Int64Int64CursorCursorProd *) tail_1194)->field0; + IntTy k3_82_834_1116 = + ((Int64Int64Int64CursorCursorProd *) tail_1194)->field1; + IntTy x3_83_835_1117 = + ((Int64Int64Int64CursorCursorProd *) tail_1194)->field2; + CursorTy t2_84_836_1118 = + ((Int64Int64Int64CursorCursorProd *) tail_1194)->field3; + CursorTy t3_85_837_1119 = + ((Int64Int64Int64CursorCursorProd *) tail_1194)->field4; + CursorTy fltAppE_905_1120 = + bin_322(k1_71_668_827_1109, x1_72_667_826_1108, t1_73_669_828_1110, t2_84_836_1118); + CursorTy fltAppE_906_1121 = + bin_322(k2_77_671_830_1112, x2_78_672_831_1113, t3_85_837_1119, t4_80_673_832_1114); + + return bin_322(k3_82_834_1116, x3_83_835_1117, fltAppE_905_1120, + fltAppE_906_1121); + break; + } + + case 0: + { + return empty_321(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1193"); + exit(1); + } + } +} +CursorTy caseFn_674(IntTy x1_57_675_838_1122, IntTy k1_56_676_839_1123, + CursorTy t4_59_677_840_1124, CursorTy m1_65_678_841_1125, + IntTy k2_62_679_842_1126, IntTy x2_63_680_843_1127, + CursorTy t1_64_681_844_1128) +{ + TagTyPacked tag_1196 = *(TagTyPacked *) m1_65_678_841_1125; + CursorTy tail_1197 = m1_65_678_841_1125 + sizeof(IntTy); + + + switch_1198: + ; + switch (tag_1196) { + + case 1: + { + IntTy wildcard__168_66_845_1129 = + ((Int64Int64Int64CursorCursorProd *) tail_1197)->field0; + IntTy k3_67_846_1130 = + ((Int64Int64Int64CursorCursorProd *) tail_1197)->field1; + IntTy x3_68_847_1131 = + ((Int64Int64Int64CursorCursorProd *) tail_1197)->field2; + CursorTy t2_69_848_1132 = + ((Int64Int64Int64CursorCursorProd *) tail_1197)->field3; + CursorTy t3_70_849_1133 = + ((Int64Int64Int64CursorCursorProd *) tail_1197)->field4; + CursorTy fltAppE_907_1134 = + bin_322(k2_62_679_842_1126, x2_63_680_843_1127, t1_64_681_844_1128, t2_69_848_1132); + CursorTy fltAppE_908_1135 = + bin_322(k1_56_676_839_1123, x1_57_675_838_1122, t3_70_849_1133, t4_59_677_840_1124); + + return bin_322(k3_67_846_1130, x3_68_847_1131, fltAppE_907_1134, + fltAppE_908_1135); + break; + } + + case 0: + { + return empty_321(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1196"); + exit(1); + } + } +} +int __main_expr() +{ + add_symbol(1138, ")"); + add_symbol(1139, "(Tip_v_313"); + add_symbol(1140, "(Bin_v_313"); + add_symbol(1141, " "); + add_symbol(1142, "\n"); + + CursorTy fltAppE_850_909 = singleton_312(0, 0); + CursorTy m_25_682_910 = build(0, 10, fltAppE_850_909); + IntTy timed_1136; + VectorTy *times_3 = vector_alloc(global_iters_param, sizeof(double)); + struct timespec begin_timed_1136; + struct timespec end_timed_1136; + + for (long long iters_timed_1136 = 0; iters_timed_1136 < global_iters_param; + iters_timed_1136++) { + if (iters_timed_1136 != global_iters_param - 1) + save_alloc_state(); + clock_gettime(CLOCK_MONOTONIC_RAW, &begin_timed_1136); + + IntTy timed_1136hack = sumRight(m_25_682_910); + + timed_1136 = timed_1136hack; + clock_gettime(CLOCK_MONOTONIC_RAW, &end_timed_1136); + if (iters_timed_1136 != global_iters_param - 1) + restore_alloc_state(); + + double itertime_0 = difftimespecs(&begin_timed_1136, &end_timed_1136); + + vector_inplace_update(times_3, iters_timed_1136, &itertime_0); + } + vector_inplace_sort(times_3, compare_doubles); + + double *tmp_4 = (double *) vector_nth(times_3, global_iters_param / 2); + double selftimed_2 = *tmp_4; + double batchtime_1 = sum_timing_array(times_3); + + print_timing_array(times_3); + printf("ITERS: %lld\n", global_iters_param); + printf("SIZE: %lld\n", global_size_param); + printf("BATCHTIME: %e\n", batchtime_1); + printf("SELFTIMED: %e\n", selftimed_2); + + unsigned char wildcard__19_27_684_912 = printf("%lld", timed_1136); + unsigned char wildcard__17_28_685_913 = print_symbol(1142); + IntTy timed_1137; + VectorTy *times_8 = vector_alloc(global_iters_param, sizeof(double)); + struct timespec begin_timed_1137; + struct timespec end_timed_1137; + + for (long long iters_timed_1137 = 0; iters_timed_1137 < global_iters_param; + iters_timed_1137++) { + if (iters_timed_1137 != global_iters_param - 1) + save_alloc_state(); + clock_gettime(CLOCK_MONOTONIC_RAW, &begin_timed_1137); + + IntTy timed_1137hack = sumRight(m_25_682_910); + + timed_1137 = timed_1137hack; + clock_gettime(CLOCK_MONOTONIC_RAW, &end_timed_1137); + if (iters_timed_1137 != global_iters_param - 1) + restore_alloc_state(); + + double itertime_5 = difftimespecs(&begin_timed_1137, &end_timed_1137); + + vector_inplace_update(times_8, iters_timed_1137, &itertime_5); + } + vector_inplace_sort(times_8, compare_doubles); + + double *tmp_9 = (double *) vector_nth(times_8, global_iters_param / 2); + double selftimed_7 = *tmp_9; + double batchtime_6 = sum_timing_array(times_8); + + print_timing_array(times_8); + printf("ITERS: %lld\n", global_iters_param); + printf("SIZE: %lld\n", global_size_param); + printf("BATCHTIME: %e\n", batchtime_6); + printf("SELFTIMED: %e\n", selftimed_7); + + unsigned char wildcard__13_30_687_915 = printf("%lld", timed_1137); + unsigned char wildcard__11_31_688_916 = print_symbol(1142); + + printf("'#()"); + printf("\n"); + free_symtable(); + return 0; +} \ No newline at end of file diff --git a/benchmarks/Layouts/Right.hs b/benchmarks/Layouts/Right.hs new file mode 100644 index 000000000..b622ad2fb --- /dev/null +++ b/benchmarks/Layouts/Right.hs @@ -0,0 +1,28 @@ + +module Right where +import Common +import Map + +sumRight :: Map Int -> Int +sumRight m = + case m of + Tip -> 0 + Bin _ _ v l r -> sumRight(r) + v + sumRight(l) + + +build :: Int -> Int -> Map Int -> Map Int +build x sz m = + if (sz == 0) then m + else (build (x - sz/2) (sz/2) (build (x + sz/2) (sz/2) (insert x x m))) + +gibbon_main = + let m = (build 0 (singleton 0 0)) + --_ = printsym (quote "SUM RIGHT: ") + s0 = iterate (sumRight m) + _ = printint (s0) + _ = printsym (quote "\n") + --_ = printsym (quote "SUM RIGHT: ") + s1 = iterate (sumRight m) + _ = printint (s1) + _ = printsym (quote "\n") + in () \ No newline at end of file diff --git a/benchmarks/Layouts/Right.out b/benchmarks/Layouts/Right.out new file mode 100644 index 000000000..c66626851 --- /dev/null +++ b/benchmarks/Layouts/Right.out @@ -0,0 +1,13 @@ +TIMES: [0.000025] +ITERS: 1 +SIZE: 1 +BATCHTIME: 2.513700e-05 +SELFTIMED: 2.513700e-05 +0 +TIMES: [0.000014] +ITERS: 1 +SIZE: 1 +BATCHTIME: 1.380600e-05 +SELFTIMED: 1.380600e-05 +0 +'#() diff --git a/benchmarks/Layouts/RightAndLeft.hs b/benchmarks/Layouts/RightAndLeft.hs new file mode 100644 index 000000000..a779acfaa --- /dev/null +++ b/benchmarks/Layouts/RightAndLeft.hs @@ -0,0 +1,34 @@ + +module LeftAndRight where +import Common +import Map + +sumRight :: Map Int -> Int +sumRight m = + case m of + Tip -> 0 + Bin _ _ v l r -> sumRight(r) + v + sumRight(l) + +sumLeft :: Map Int -> Int +sumLeft m = + case m of + Tip -> 0 + Bin _ _ v l r -> sumLeft(l) + v + sumLeft(r) + + +build :: Int -> Int -> Map Int -> Map Int +build x sz m = + if (sz == 0) then m + else (build (x - sz/2) (sz/2) (build (x + sz/2) (sz/2) (insert x x m))) + +gibbon_main = + let m = (build 0 (singleton 0 0)) + --_ = printsym (quote "SUM RIGHT: ") + s0 = iterate (sumLeft m) + _ = printint (s0) + _ = printsym (quote "\n") + --_ = printsym (quote "SUM LEFT: ") + s1 = iterate (sumRight m) + _ = printint (s1) + _ = printsym (quote "\n") + in () \ No newline at end of file diff --git a/benchmarks/Layouts/RightAndLeft.out b/benchmarks/Layouts/RightAndLeft.out new file mode 100644 index 000000000..780bb1976 --- /dev/null +++ b/benchmarks/Layouts/RightAndLeft.out @@ -0,0 +1,13 @@ +TIMES: [0.000024] +ITERS: 1 +SIZE: 1 +BATCHTIME: 2.414500e-05 +SELFTIMED: 2.414500e-05 +0 +TIMES: [0.000016] +ITERS: 1 +SIZE: 1 +BATCHTIME: 1.605000e-05 +SELFTIMED: 1.605000e-05 +0 +'#() diff --git a/benchmarks/Layouts/_Left.c b/benchmarks/Layouts/_Left.c new file mode 100644 index 000000000..ffc0f7f77 --- /dev/null +++ b/benchmarks/Layouts/_Left.c @@ -0,0 +1,2443 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// #include +#ifdef _WIN64 +#include +#endif +#include +#include +#include // For va_start etc +#include +#include +#include +#include +#ifdef _POINTER +#include +#endif +#ifdef _PARALLEL +#include +#include +#endif + +#define KB 1024lu +#define MB (KB * 1000lu) +#define GB (MB * 1000lu) + +#define REDIRECTION_TAG 255 +#define INDIRECTION_TAG 254 + +// Initial size of BigInfinite buffers +static long long global_init_biginf_buf_size = (4 * GB); + +// Initial size of Infinite buffers +static long long global_init_inf_buf_size = 1 * KB; + +// Maximum size of a chunk, see GitHub #110. +static long long global_inf_buf_max_chunk_size = 1 * GB; + +static long long global_size_param = 1; +static long long global_iters_param = 1; + +static char* global_benchfile_param = NULL; +static char* global_arrayfile_param = NULL; +// Number of lines in the arrayfile +static long long global_arrayfile_length_param = -1; + +// Sequential for now: +static const int num_workers = 1; + +// Count the number of regions allocated. +static long long global_region_count = 0; +static bool global_region_count_flag = false; + +#ifdef _PARALLEL +static inline void bump_global_region_count() { + __atomic_add_fetch(&global_region_count, 1, __ATOMIC_SEQ_CST); + return; +} +#else +static inline void bump_global_region_count() { + global_region_count++; + return; +} +#endif + +static inline void print_global_region_count() { + printf("REGION_COUNT: %lld\n", global_region_count); + return; +} + +#define REDIRECTION_NODE_SIZE 9 +#define MAX(a,b) (((a)>(b))?(a):(b)) +#define MIN(a,b) (((a)<(b))?(a):(b)) + +// https://www.cprogramming.com/snippets/source-code/find-the-number-of-cpu-cores-for-windows-mac-or-linux +static int get_num_processors() { +#ifdef _WIN64 + SYSTEM_INFO sysinfo; + GetSystemInfo(&sysinfo); + return sysinfo.dwNumberOfProcessors; +#else + return sysconf(_SC_NPROCESSORS_ONLN); +#endif +} + +// Requires -std=gnu11 +int dbgprintf(const char *format, ...) { + int code = 0; + va_list args; + va_start(args, format); +#ifdef _DEBUG + code = vprintf(format, args); +#endif + va_end(args); + return code; +} + + +// ----------------------------------------------------------------------------- +// Allocators +// ----------------------------------------------------------------------------- + + +// ------------------------------------- +// Bump allocation for linked-lists +// ------------------------------------- + + +#ifdef _BUMPALLOC +// #define _DEBUG +#warning "Using bump allocator." + +__thread char* bumpalloc_heap_ptr = (char*)NULL; +__thread char* bumpalloc_heap_ptr_end = (char*)NULL; + +char* saved_heap_ptr_stack[100]; +int num_saved_heap_ptr = 0; + +// For simplicity just use a single large slab: +static inline void INITBUMPALLOC() { + bumpalloc_heap_ptr = (char*)malloc(global_init_biginf_buf_size); + bumpalloc_heap_ptr_end = bumpalloc_heap_ptr + global_init_biginf_buf_size; +#ifdef _DEBUG + printf("Arena size for bump alloc: %lld\n", global_init_biginf_buf_size); + printf("BUMPALLOC/INITBUMPALLOC DONE: heap_ptr = %p\n", bumpalloc_heap_ptr); +#endif +} + +static inline void* BUMPALLOC(long long n) { + if (! bumpalloc_heap_ptr) { + INITBUMPALLOC(); + } + if (bumpalloc_heap_ptr + n < bumpalloc_heap_ptr_end) { + char* old= bumpalloc_heap_ptr; + bumpalloc_heap_ptr += n; + return old; + } else { + fprintf(stderr, "Warning: bump allocator ran out of memory."); + exit(1); + } +} + +// Snapshot the current heap pointer value across all threads. +void save_alloc_state() { + dbgprintf("Saving(%p): pos %d", heap_ptr, num_saved_heap_ptr); + saved_heap_ptr_stack[num_saved_heap_ptr] = heap_ptr; + num_saved_heap_ptr++; + dbgprintf("\n"); +} + +void restore_alloc_state() { + if(num_saved_heap_ptr <= 0) { + fprintf(stderr, "Bad call to restore_alloc_state! Saved stack empty!\ne"); + exit(1); + } + num_saved_heap_ptr--; + dbgprintf("Restoring(%p): pos %d, discarding %p", + saved_heap_ptr_stack[num_saved_heap_ptr], num_saved_heap_ptr, bumpalloc_heap_ptr); + bumpalloc_heap_ptr = saved_heap_ptr_stack[num_saved_heap_ptr]; +} + + +#else +// Regular malloc mode: +void INITBUMPALLOC() {} +void save_alloc_state() {} +void restore_alloc_state() {} + +#define BUMPALLOC(n) malloc(n) + +#endif // BUMPALLOC + + +// ------------------------------------- +// ALLOC and ALLOC_PACKED macros +// ------------------------------------- + + +/* + +If parallelism is enabled, we always use a malloc based allocator +since Boehm GC is not thread-safe in its default configuration. It can be +made thread-safe by building it with appropriate flags, but we don't do that. +Presently, all parallel pointer-based programs will leak memory. + +*/ + +#ifdef _PARALLEL +#define ALLOC(n) malloc(n) +#define ALLOC_PACKED_BIG(n) malloc(n) +char *ALLOC_COUNTED(size_t size) { + bump_global_region_count(); + return ALLOC(size); +} +#else + #ifdef _POINTER +#define ALLOC(n) GC_MALLOC(n) +#define ALLOC_PACKED_BIG(n) GC_MALLOC(n) +char *ALLOC_COUNTED(size_t size) { + bump_global_region_count(); + return GC_MALLOC(size); +} + #else +#define ALLOC(n) malloc(n) +#define ALLOC_PACKED_BIG(n) malloc(n) +char *ALLOC_COUNTED(size_t size) { + bump_global_region_count(); + return ALLOC(size); +} + #endif // _POINTER +#endif // _PARALLEL + + +// Could try alloca() here. Better yet, we could keep our own, +// separate stack and insert our own code to restore the pointer +// before any function that (may have) called ALLOC_SCOPED returns. + +// #define ALLOC_SCOPED() alloca(1024) +#define ALLOC_SCOPED(n) alloca(n) +// #define ALLOC_SCOPED() alloc_scoped() + +// Stack allocation is either too small or blows our stack. +// We need a way to make a giant stack if we want to use alloca. +// #define ALLOC_SCOPED() ALLOC(global_init_biginf_buf_size) + +// Our global pointer. No parallelism. +// static char* stack_scoped_region; +// char* alloc_scoped() { return stack_scoped_region; } + + + +// ------------------------------------- +// Basic types +// ------------------------------------- + +// Must be consistent with sizeOfTy defined in Gibbon.Language.Syntax. + +typedef unsigned char TagTyPacked; +typedef unsigned char TagTyBoxed; +typedef long long IntTy; +typedef char CharTy; +typedef float FloatTy; +typedef unsigned long long SymTy; +typedef bool BoolTy; +typedef char* PtrTy; +typedef char* CursorTy; + +// ------------------------------------- +// Arenas and dictionaries +// ------------------------------------- + +typedef struct mem_arena { + int ind; + char* mem; // TODO(vollmerm): make this a list of chunks? + void* reflist; +} mem_arena_t; + +typedef mem_arena_t* ArenaTy; + +ArenaTy alloc_arena() { + ArenaTy ar = ALLOC(sizeof(mem_arena_t)); + ar->ind = 0; + ar->mem = malloc(global_inf_buf_max_chunk_size); + ar->reflist = 0; + return ar; +} + +void free_arena(ArenaTy ar) { + free(ar->mem); + // TODO(vollmerm): free everything in ar->reflist + free(ar); +} + +CursorTy extend_arena(ArenaTy ar, int size) { + CursorTy ret = ar->mem + ar->ind; + ar->ind += size; + return ret; +} + +typedef struct dict_item { + struct dict_item * next; + int key; + void * ptrval; +} dict_item_t; + +dict_item_t * dict_alloc(ArenaTy ar) { + return (dict_item_t *) extend_arena(ar, sizeof(dict_item_t)); // ALLOC(sizeof(dict_item_t)); +} + +dict_item_t *dict_insert_ptr(ArenaTy ar, dict_item_t *ptr, SymTy key, PtrTy val) { + dict_item_t *ret = dict_alloc(ar); + ret->key = key; + ret->ptrval = val; + ret->next = ptr; + return ret; +} + +PtrTy dict_lookup_ptr(dict_item_t *ptr, SymTy key) { + while (ptr != 0) { + if (ptr->key == key) { + return ptr->ptrval; + } else { + ptr = ptr->next; + } + } + printf("Error, key %lld not found!\n",key); + exit(1); +} + +// ------------------------------------- +// Sets +// ------------------------------------- + + +struct set_elem { + int val; + UT_hash_handle hh; +}; + +typedef struct set_elem* SymSetTy; + +SymSetTy empty_set() { + return NULL; +} + +SymSetTy insert_set(SymSetTy set, int sym) { + SymSetTy s; + HASH_FIND_INT(set, &sym, s); /* sym already in the hash? */ + if (s==NULL) { + s = malloc(sizeof(struct set_elem)); + s->val = sym; + HASH_ADD_INT(set,val,s); + } + return set; +} + +BoolTy contains_set(SymSetTy set, int sym) { + SymSetTy s; + HASH_FIND_INT(set, &sym, s); + return (s!=NULL); +} + +// ------------------------------------- +// Sym Hash +// ------------------------------------- + +struct sym_hash_elem { + int key; + int val; + UT_hash_handle hh; +}; + +typedef struct sym_hash_elem* SymHashTy; + +typedef struct sym_hash_elem* IntHashTy; + +SymHashTy empty_hash() { + return NULL; +} + +SymHashTy insert_hash(SymHashTy hash, int k, int v) { + SymHashTy s; + // NOTE: not checking for duplicates! + // s = malloc(sizeof(struct sym_hash_elem)); + s = ALLOC(sizeof(struct sym_hash_elem)); + s->val = v; + s->key = k; + HASH_ADD_INT(hash,key,s); + + return hash; +} + +IntTy lookup_hash(SymHashTy hash, int k) { + SymHashTy s; + HASH_FIND_INT(hash,&k,s); + if (s==NULL) { + return k; // NOTE: return original key if val not found + // TODO(vollmerm): come up with something better to do here + } else { + return s->val; + } +} + +BoolTy contains_hash(SymHashTy hash, int sym) { + SymHashTy s; + HASH_FIND_INT(hash,&sym,s); + return (s!=NULL); +} + +// ------------------------------------- +// Helpers +// ------------------------------------- + +char* read_benchfile_param() { + if (global_benchfile_param == NULL) { + fprintf(stderr, "read_benchfile_param: benchmark input file was not set! Set using --bench-input.\n"); + exit(1); + } else + return global_benchfile_param; +} + +char* read_arrayfile_param() { + if (global_arrayfile_param == NULL) { + fprintf(stderr, "read_arrayfile_param: array input file was not set! Set using --array-input.\n"); + exit(1); + } else + return global_arrayfile_param; +} + +IntTy read_arrayfile_length_param() { + if (global_arrayfile_length_param == -1) { + fprintf(stderr, "read_arrayfile_length_param: array input file length was not set! Set using --array-input-length.\n"); + exit(1); + } else + return global_arrayfile_length_param; +} + + +// fun fact: __ prefix is actually reserved and this is an undefined behavior. +// These functions must be provided by the code generator. +int __main_expr(); + + +void show_usage(char** argv) +{ + printf("\n"); + printf("This binary was generated by the Gibbon compiler.\n"); + printf("\n"); + printf("Usage: %s [OPTS] [size] [iters]\n", argv[0]); + + printf("\n"); + printf("Options:\n"); + printf(" --buffer-size Set the buffer size (default %lld).\n", global_init_biginf_buf_size); + printf(" --bench-input Set the input file read for benchmarking. Applies only\n"); + printf(" IF the program was *compiled* with --bench-fun. \n"); + return; +} + +double avg(const double* arr, int n) +{ + double sum = 0.0; + for(int i=0; itv_sec - t0->tv_sec) + + ((double)(t1->tv_nsec - t0->tv_nsec) / 1000000000.0); +} + +int compare_doubles(const void *a, const void *b) +{ + const double *da = (const double *) a; + const double *db = (const double *) b; + return (*da > *db) - (*da < *db); +} + +// Exponentiation +IntTy expll(IntTy base, IntTy pow) { + if (base == 2) { + return (1 << pow); + } else { + IntTy i, result = 1; + for (i = 0; i < pow; i++) + result *= base; + return result; + } + } + +// ------------------------------------- +// Symbol table +// ------------------------------------- + +#define global_max_symbol_len 256 + +// Invariant: should always be equal to max(sym_table_keys) +static SymTy global_gensym_counter = 0; + +// Its value is updated by the flags parser. +static char *global_bench_prog_param; + +static SymTy newline_symbol = -1; +static SymTy space_symbol = -1; +static SymTy comma_symbol = -1; +static SymTy leftparen_symbol = -1; +static SymTy rightparen_symbol = -1; + +typedef struct SymTable_elem { + SymTy idx; /* key */ + char value[global_max_symbol_len]; + UT_hash_handle hh; /* makes this structure hashable */ +} SymTable_elem; + +// important! initialize to NULL +SymTable_elem *global_sym_table = NULL; + +void add_symbol(SymTy idx, char *value) { + struct SymTable_elem *s; + s = ALLOC(sizeof(struct SymTable_elem)); + s->idx = idx; + strcpy(s->value, value); + HASH_ADD(hh, global_sym_table, idx, sizeof(IntTy), s); + if (idx > global_gensym_counter) { + global_gensym_counter = idx; + } +} + +void set_newline(SymTy idx) { + newline_symbol = idx; + add_symbol(idx,"NEWLINE"); +} + +void set_space(SymTy idx) { + space_symbol = idx; + add_symbol(idx,"SPACE"); +} + +void set_comma(SymTy idx) { + comma_symbol = idx; + add_symbol(idx,"COMMA"); +} + +void set_leftparen(SymTy idx) { + leftparen_symbol = idx; + add_symbol(idx,"LEFTPAREN"); +} + +void set_rightparen(SymTy idx) { + rightparen_symbol = idx; + add_symbol(idx,"RIGHTPAREN"); +} + +IntTy print_symbol(SymTy idx) { + if (idx == comma_symbol) { + return printf(","); + } else if (idx == newline_symbol) { + return printf("\n"); + } else if (idx == space_symbol) { + return printf(" "); + } else if (idx == leftparen_symbol) { + return printf("("); + } else if (idx == rightparen_symbol) { + return printf(")"); + } else { + struct SymTable_elem *s; + HASH_FIND(hh, global_sym_table, &idx, sizeof(SymTy), s); + if (s == NULL) { + return printf("%lld", idx); + } else { + return printf("%s", s->value); + } + + } +} + +#ifdef _PARALLEL +SymTy gensym() { + SymTy idx = __atomic_add_fetch(&global_gensym_counter, 1, __ATOMIC_SEQ_CST); + return idx; +} +#else +SymTy gensym() { + global_gensym_counter += 1; + SymTy idx = global_gensym_counter; + return idx; +} +#endif + +void free_symtable() { + struct SymTable_elem *elt, *tmp; + HASH_ITER(hh, global_sym_table, elt, tmp) { + HASH_DEL(global_sym_table,elt); + } + free(elt); + free(tmp); +} + +/* + +---------------------------------------- +Garbage collection +---------------------------------------- + + Gibbon has "growing regions" i.e each logical region is backed by a doubly linked-list + of smaller chunks which grows as required. In addition to actual data, each chunk + stores some additional metadata (RegionFooter) to chain the chunks together in a list + and for garbage collection. The footer: + + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + serialized data | rf_reg_metadata_ptr | rf_seq_no | rf_size | rf_next | rf_prev + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + The metadata after the serialized data serves various purposes: + + - rf_reg_metadata_ptr: A pointer to a RegionTy struct that contains various metadata. + Of particular interest to us are the fields: + + = reg_id: A unique identifier for a region. + + = refcount and outset: Whenever an inter-region indirection is created, we record that information + using these two fields. Suppose we have an indirection from region A that points to some chunk + in region B. Then A's outset will store a pointer to that chunk's footer, and B's refcount will + be bumped by 1. Note that all there's only 1 refcount cell, and 1 outset per logical region, + and chunks only store a pointer to them. + + - rf_seq_no: The index of this particular chunk in the list. + + - rf_size: Used during bounds checking to calculate the size of the next region in + the linked list. + + - rf_next / rf_prev: Point to the next and previous chunk respectively. + + +There are two ways in which a region may be freed: + +(1) Whenever it goes out of scope + + The RTS tries to free a region whenever it goes out of scope. But this doesn't always succeed as + regions sometimes contain values that "escape". One reason why this'll happen is if there's an + indirection from A->B, and A lives longer than B. + In such a case, when B goes out of scope it's refcount won't be 0, and the RTS won't free it. + This brings us to (2). + +(2) + + When the RTS successfully frees a region, it decrements the refcounts of all the regions it + points to (via the outset). At the same time, if it encounters a region in the outset whoose + refcount becomes 0 after the decrement, it calls free_region on that. This way we can be sure + that all regions will eventually be garbage collected before the program exits. + + + +Why is it a doubly linked-list? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Due to way that bounds-checking works, the pointers in the outset may actually point to any +arbitrary chunk in the chain. However, we must call free_region on the first one to ensure that +all of them are GC'd. So we need pointers to traverse backward get to the first one. +'trav_to_first_chunk' accomplishes this. + + */ + +#define MAX_OUTSET_LENGTH 10 + +typedef struct RegionTy_struct { + SymTy reg_id; + uint reg_refcount; + CursorTy reg_heap; + uint reg_outset_len; + CursorTy reg_outset[MAX_OUTSET_LENGTH]; +} RegionTy; + +typedef struct RegionFooter_struct { + RegionTy *rf_reg_metadata_ptr; + + IntTy rf_seq_no; + IntTy rf_size; + struct RegionFooter_struct *rf_next; + struct RegionFooter_struct *rf_prev; +} RegionFooter; + +typedef struct ChunkTy_struct { + CursorTy chunk_start; + CursorTy chunk_end; +} ChunkTy; + +static inline void insert_into_outset(CursorTy ptr, RegionTy *reg) { + uint outset_len = reg->reg_outset_len; + // Check for duplicates. + for (uint i = 0; i < outset_len; i++) { + if (ptr == reg->reg_outset[i]) { + return; + } + } + // Otherwise, insert into the outset. + reg->reg_outset[outset_len] = ptr; + reg->reg_outset_len = outset_len + 1; + return; +} + +static inline void remove_from_outset(CursorTy ptr, RegionTy *reg) { + uint outset_len = reg->reg_outset_len; + CursorTy *outset = reg->reg_outset; + int i; + if (outset_len == 0) { + fprintf(stderr, "remove_from_outset: empty outset\n"); + exit(1); + } + // Position of 'ptr' in the outset. + int elt_idx = -1; + for (i = 0; i < outset_len; i++) { + if (ptr == outset[i]) { + elt_idx = i; + } + } + if (elt_idx == -1) { + fprintf(stderr, "remove_from_outset: element not found\n"); + exit(1); + } + // Move all elements ahead of 'elt_idx' back by one position. + for (i = elt_idx; i < outset_len; i++) { + outset[i] = outset[i+1]; + } + return; +} + +RegionTy *alloc_region(IntTy size) { + // Allocate the region metadata. + RegionTy *reg = ALLOC(sizeof(RegionTy)); + if (reg == NULL) { + printf("alloc_region: allocation failed: %ld", sizeof(RegionTy)); + exit(1); + } + + // Allocate the first chunk. + IntTy total_size = size + sizeof(RegionFooter); + CursorTy heap = ALLOC_PACKED_BIG(total_size); + if (heap == NULL) { + printf("alloc_region: malloc failed: %lld", total_size); + exit(1); + } + // Not heap+total_size, since we must keep space for the footer. + CursorTy heap_end = heap + size; + + // Initialize metadata fields. + reg->reg_id = gensym(); + reg->reg_refcount = 1; + reg->reg_heap = heap; + reg->reg_outset_len = 0; + +#ifdef _DEBUG + printf("Allocated a region(%lld): %lld bytes.\n", reg->reg_id, size); +#endif + + // Write the footer. + RegionFooter *footer = (RegionFooter *) heap_end; + footer->rf_reg_metadata_ptr = reg; + footer->rf_seq_no = 1; + footer->rf_size = size; + footer->rf_next = NULL; + footer->rf_prev = NULL; + + return reg; +} + +RegionTy *alloc_counted_region(IntTy size) { + // Bump the count. + bump_global_region_count(); + return alloc_region(size); +} + +ChunkTy alloc_chunk(CursorTy end_old_chunk) { + // Get size from current footer. + RegionFooter *footer = (RegionFooter *) end_old_chunk; + IntTy newsize = footer->rf_size * 2; + // See #110. + if (newsize > global_inf_buf_max_chunk_size) { + newsize = global_inf_buf_max_chunk_size; + } + IntTy total_size = newsize + sizeof(RegionFooter); + + // Allocate. + CursorTy start = ALLOC_PACKED_BIG(total_size); + if (start == NULL) { + printf("alloc_chunk: malloc failed: %lld", total_size); + exit(1); + } + CursorTy end = start + newsize; + + // Link the next chunk's footer. + footer->rf_next = (RegionFooter *) end; + + // Write the footer. + RegionFooter* new_footer = (RegionFooter *) end; + new_footer->rf_reg_metadata_ptr = footer->rf_reg_metadata_ptr; + new_footer->rf_seq_no = footer->rf_seq_no + 1; + new_footer->rf_size = newsize; + new_footer->rf_next = NULL; + new_footer->rf_prev = footer; + +#ifdef _DEBUG + RegionTy *reg = (RegionTy*) new_footer->rf_reg_metadata_ptr; + printf("alloc_chunk: allocated %lld bytes for region %lld.\n", total_size, reg->reg_id); +#endif + + return (ChunkTy) {start , end}; +} + +RegionFooter* trav_to_first_chunk(RegionFooter *footer) { + if (footer->rf_seq_no == 1) { + return footer; + } else if (footer->rf_prev == NULL) { + fprintf(stderr, "No previous chunk found at rf_seq_no: %lld", footer->rf_seq_no); + return NULL; + } else { + trav_to_first_chunk((RegionFooter *) footer->rf_prev); + } + return NULL; +} + +uint get_ref_count(CursorTy end_ptr) { + RegionFooter *footer = (RegionFooter *) end_ptr; + RegionTy *reg = (RegionTy *) footer->rf_reg_metadata_ptr; + return reg->reg_refcount; +} + +// B is the pointer, and A is the pointee (i.e B -> A). +// Bump A's refcount and update B's outset. +static inline void bump_ref_count(CursorTy end_b, CursorTy end_a) { + // Grab footers. + RegionFooter *footer_a = (RegionFooter *) end_a; + RegionFooter *footer_b = (RegionFooter *) end_b; + + // Grab metadata. + RegionTy *reg_a = (RegionTy *) footer_a->rf_reg_metadata_ptr; + RegionTy *reg_b = (RegionTy *) footer_b->rf_reg_metadata_ptr; + + // Bump A's refcount. + uint current_refcount, new_refcount; + current_refcount = reg_a->reg_refcount; + new_refcount = current_refcount + 1; + reg_a->reg_refcount = new_refcount; + +#ifdef _DEBUG + printf("bump_ref_count: %lld -> %lld\n", reg_b->reg_id, reg_a->reg_id); + printf("bump_ref_count: old-refcount=%d, old-outset-len=%d:\n", current_refcount, reg_b->reg_outset_len); + assert(current_refcount == reg_b->reg_outset_len+1); +#endif + + // Add A to B's outset. + insert_into_outset(end_a, reg_b); + +#ifdef _DEBUG + // printf("bump_ref_count: Added %p to %lld's outset, %p.\n", end_a, reg_b->reg_id, reg_b); + printf("bump_ref_count: new-refcount=%d, new-outset-len=%d\n", new_refcount, reg_b->reg_outset_len); + assert(new_refcount == reg_b->reg_outset_len+1); +#endif + + return; +} + +void free_region(CursorTy end_reg) { + // Grab footer and the metadata. + RegionFooter *footer = (RegionFooter *) end_reg; + RegionTy *reg = (RegionTy *) footer->rf_reg_metadata_ptr; + + // + RegionFooter *first_chunk_footer, *next_chunk_footer; + CursorTy first_chunk, next_chunk; + + // Decrement current reference count. + uint current_refcount, new_refcount; + current_refcount = reg->reg_refcount; + new_refcount = 0; + if (current_refcount != 0) { + new_refcount = current_refcount - 1; + reg->reg_refcount = new_refcount; + } + +#ifdef _DEBUG + printf("free_region(%lld): refcounts (1): old-refcount=%d, new-refcount=%d:\n", reg->reg_id, current_refcount, new_refcount); +#endif + + + // Free this region recount is 0. + if (new_refcount == 0) { + +#ifdef _DEBUG + printf("free_region(%lld): outset length: %d\n", reg->reg_id, reg->reg_outset_len); +#endif + + // Decrement refcounts, free regions with refcount==0 and also free + // elements of the outset. + if (reg->reg_outset_len != 0) { + uint outset_len = reg->reg_outset_len; + CursorTy *outset = reg->reg_outset; + RegionFooter *elt_footer; + RegionTy *elt_reg; + uint elt_current_refcount, elt_new_refcount; + CursorTy to_be_removed[MAX_OUTSET_LENGTH]; + uint to_be_removed_idx = 0; + for (int i = 0; i < outset_len; i++) { + elt_footer = (RegionFooter *) outset[i]; + elt_reg = (RegionTy *) elt_footer->rf_reg_metadata_ptr; +#ifdef _DEBUG + elt_current_refcount = elt_reg->reg_refcount; +#endif + elt_new_refcount = elt_current_refcount - 1; + elt_reg->reg_refcount = elt_new_refcount; +#ifdef _DEBUG + printf("free_region(%lld): old-refcount=%d, new-refcount=%d:\n", + elt_reg->reg_id, elt_current_refcount, elt_reg->reg_refcount); +#endif + if (elt_new_refcount == 0) { + // See [Why is it a doubly linked-list?] above + first_chunk_footer = trav_to_first_chunk(elt_footer); + if (first_chunk_footer != NULL) { + free_region((CursorTy) first_chunk_footer); + } + } + to_be_removed[to_be_removed_idx] = outset[i]; + to_be_removed_idx++; + } + // Remove elements from the outset. + for (uint i = 0; i < to_be_removed_idx; i++) { + remove_from_outset(to_be_removed[i], reg); + } + } + + +#ifdef _DEBUG + // Bookkeeping + IntTy num_freed_chunks = 0, total_bytesize = 0; +#endif + + // Free the chunks in this region. + first_chunk = end_reg - footer->rf_size; + first_chunk_footer = footer; + next_chunk = (char*) footer->rf_next; + +#ifdef _DEBUG + printf("free_region(%lld)\n", reg->reg_id); +#endif + +#ifdef _DEBUG + num_freed_chunks++; + total_bytesize = total_bytesize + first_chunk_footer->rf_size; +#endif + free(first_chunk); + + while (next_chunk != NULL) { + next_chunk_footer = (RegionFooter *) next_chunk; + #ifdef _DEBUG + num_freed_chunks++; + total_bytesize = total_bytesize + next_chunk_footer->rf_size; + #endif + free(next_chunk - next_chunk_footer->rf_size); + next_chunk = (char*) next_chunk_footer->rf_next; + } + +#ifdef _DEBUG + printf("free_region(%lld): Freed %lld bytes across %lld chunks.\n", + reg->reg_id, total_bytesize, num_freed_chunks); +#endif + + // Free the metadata. + free(reg); + + } else { +#ifdef _DEBUG + printf("free_region(%lld): non-zero refcount: %d.\n", + reg->reg_id, reg->reg_refcount); +#endif + } +} + +// Assume that all nodes with size information have tags >= 150. +BoolTy is_big(IntTy i, CursorTy cur) { + TagTyPacked tag = *(TagTyPacked *) cur; + if (tag >= 150) { + cur += 1; + IntTy size = *(IntTy *) cur; + if (size >= i) { + return true; + } else { + return false; + } + } + return false; +} + +// ------------------------------------- +// Vectors +// ------------------------------------- + +typedef struct VectorTy_struct { + // Bounds on the vector. + IntTy vec_lower, vec_upper; + + // Size of each element. + IntTy vec_elt_size; + + // Actual elements of the vector. + void* vec_data; +} VectorTy; + +VectorTy* vector_alloc(IntTy num, IntTy elt_size) { + VectorTy *vec = ALLOC(sizeof(VectorTy)); + if (vec == NULL) { + printf("alloc_vector: malloc failed: %ld", sizeof(VectorTy)); + exit(1); + } + void* data = ALLOC(num * elt_size); + if (data == NULL) { + printf("alloc_vector: malloc failed: %ld", sizeof(num * elt_size)); + exit(1); + } + vec->vec_lower = 0; + vec->vec_upper = num; + vec->vec_elt_size = elt_size; + vec->vec_data = data; + return vec; +} + +IntTy vector_length(VectorTy *vec) { + return (vec->vec_upper - vec->vec_lower); +} + +BoolTy vector_is_empty(VectorTy *vec) { + return (vector_length(vec) == 0); +} + +VectorTy* vector_slice(IntTy i, IntTy n, VectorTy *vec) { + IntTy lower = vec->vec_lower + i; + IntTy upper = vec->vec_lower + i + n; + if ((lower > vec->vec_upper)) { + printf("vector_slice: lower out of bounds, %lld > %lld", lower, vec->vec_upper); + exit(1); + } + if ((upper > vec->vec_upper)) { + printf("vector_slice: upper out of bounds: %lld > %lld", upper, vec->vec_upper); + exit(1); + } + VectorTy *vec2 = ALLOC(sizeof(VectorTy)); + if (vec == NULL) { + printf("vector_slice: malloc failed: %ld", sizeof(VectorTy)); + exit(1); + } + vec2->vec_lower = lower; + vec2->vec_upper = upper; + vec2->vec_elt_size = vec->vec_elt_size; + vec2->vec_data = vec->vec_data; + return vec2; +} + +// The callers must cast the return value. +static inline void* vector_nth(VectorTy *vec, IntTy i) { + // if (i < vec->lower || i > vec->upper) { + // printf("vector_nth index out of bounds: %lld (%lld,%lld) \n", i, vec->vec_lower, vec->vec_upper); + // exit(1); + // } + return (vec->vec_data + (vec->vec_elt_size * (vec->vec_lower + i))); +} + +static inline VectorTy* vector_inplace_update(VectorTy *vec, IntTy i, void* elt) { + void* dst = vector_nth(vec, i); + memcpy(dst, elt, vec->vec_elt_size); + return vec; +} + +static inline VectorTy* vector_copy(VectorTy *vec) { + IntTy len = vector_length(vec); + void *start = vector_nth(vec, 0); + VectorTy *vec2 = vector_alloc(len, vec->vec_elt_size); + memcpy(vec2->vec_data, start, len * vec->vec_elt_size); + return vec2; +} + +static inline VectorTy* vector_inplace_sort(VectorTy *vec, int (*compar)(const void *, const void*)) { + void *start = vector_nth(vec, 0); + qsort(start, vector_length(vec), vec->vec_elt_size, compar); + return vec; +} + +static inline VectorTy* vector_sort(VectorTy *vec, int (*compar)(const void *, const void*)) { + VectorTy *vec2 = vector_copy(vec); + vector_inplace_sort(vec2, compar); + return vec2; +} + +static inline VectorTy* vector_concat(VectorTy *vec) { + // Length of the input vector. + IntTy len = vector_length(vec); + // Length of the concatenated vector. + IntTy result_len = 0; + // Size of each element in the concatenated vector. + IntTy result_elt_size = 0; + VectorTy **elt_ref, *elt; + for (IntTy i = 0; i < len; i++) { + elt_ref = vector_nth(vec, i); + elt = *elt_ref; + result_elt_size = elt->vec_elt_size; + result_len += vector_length(elt); + } + + // Concatenated vector. + VectorTy *result = vector_alloc(result_len, result_elt_size); + IntTy elt_len; + // A counter that tracks the index of elements in 'result'. + IntTy k = 0; + for (IntTy i = 0; i < len; i++) { + elt_ref = vector_nth(vec, i); + elt = *elt_ref; + elt_len = vector_length(elt); + + for (IntTy j = 0; j < elt_len; j++) { + void* k_elt = vector_nth(elt, j); + vector_inplace_update(result, k, k_elt); + k++; + } + } + + return result; +} + +static inline void vector_free(VectorTy *vec) { + free(vec->vec_data); + free(vec); + return; +} + +static inline VectorTy* vector_merge(VectorTy *vec1, VectorTy *vec2) { + if (vec1->vec_upper != vec2->vec_lower) { + printf("vector_merge: non-contiguous slices, (%lld,%lld), (%lld,%lld).", + vec1->vec_lower, vec1->vec_upper, vec2->vec_lower, vec2->vec_upper); + exit(1); + } + VectorTy *merged = ALLOC(sizeof(VectorTy)); + if (merged == NULL) { + printf("vector_merge: malloc failed: %ld", sizeof(VectorTy)); + exit(1); + } + merged->vec_lower = vec1->vec_lower; + merged->vec_upper = vec2->vec_upper; + merged->vec_elt_size = vec1->vec_elt_size; + merged->vec_data = vec1->vec_data; + return merged; +} + +void print_timing_array(VectorTy *times) { + printf("TIMES: ["); + double *d; + IntTy n = vector_length(times); + for(int i = 0; i < n; i++) { + d = vector_nth(times, i); + if (i == (n-1)) { + printf("%f",*d); + } + else { + printf("%f, ",*d); + } + } + printf("]\n"); +} + +double sum_timing_array(VectorTy *times) { + double *d; + double acc = 0; + for(int i = 0; i < vector_length(times); i++) { + d = vector_nth(times, i); + acc += *d; + } + return acc; +} + +// ------------------------------------- +// Linked lists +// ------------------------------------- + +typedef struct ListTy_struct { + IntTy ll_data_size; + void* ll_data; + struct ListTy_struct* ll_next; +} ListTy; + +static inline ListTy* list_alloc(IntTy data_size) { + // ListTy *ls = ALLOC(sizeof(ListTy)); + ListTy *ls = BUMPALLOC(sizeof(ListTy)); + ls->ll_data_size = data_size; + ls->ll_data = NULL; + ls->ll_next = NULL; + return ls; +} + +static inline BoolTy list_is_empty(ListTy *ls) { + return ls->ll_next == NULL; +} + +static inline ListTy* list_cons(void* elt, ListTy *ls) { + // void* data = ALLOC(ls->data_size); + void* data = BUMPALLOC(ls->ll_data_size); + if (data == NULL) { + printf("list_cons: malloc failed: %lld", ls->ll_data_size); + exit(1); + } + memcpy(data, elt, ls->ll_data_size); + // ListTy *res = ALLOC(sizeof(ListTy)); + ListTy *res = BUMPALLOC(sizeof(ListTy)); + res->ll_data_size = ls->ll_data_size; + res->ll_data = data; + res->ll_next = (ListTy*) ls; + return res; +} + +static inline void* list_head(ListTy *ls) { + return ls->ll_data; +} + +static inline ListTy* list_tail(ListTy *ls) { + return ls->ll_next; +} + +static inline void list_free(ListTy *ls) { + free(ls->ll_data); + free(ls); + return; +} + +static inline ListTy* list_copy(ListTy *ls) { + ListTy *ls2 = list_alloc(ls->ll_data_size); + if (ls->ll_data != NULL) { + void* data = BUMPALLOC(ls->ll_data_size); + memcpy(data, ls->ll_data, ls->ll_data_size); + ls2->ll_data = data; + } + ls2->ll_next = ls->ll_next; + return ls2; +} + +// ------------------------------------- +// Ppm Images +// ------------------------------------- + +typedef struct __Pixel_struct { + IntTy field0; + IntTy field1; + IntTy field2; +} __Pixel; + +void writePpm(char* filename, IntTy width, IntTy height, VectorTy *pixels); +void writePpm_loop(FILE *fp, IntTy idx, IntTy end, VectorTy *pixels); + +// Example: writePpm("gibbon_rgb_1000.ppm", 1000, 1000, pixels); +void writePpm(char* filename, IntTy width, IntTy height, VectorTy *pixels) +{ + FILE *fp; + fp = fopen(filename, "w+"); + fprintf(fp, "P3\n"); + fprintf(fp, "%lld %lld\n255\n", width, height); + IntTy len = vector_length(pixels); + writePpm_loop(fp, 0, len, pixels); + fclose(fp); + return; +} + +void writePpm_loop(FILE *fp, IntTy idx, IntTy end, VectorTy *pixels) +{ + BoolTy fltIf_5768_6575 = idx == end; + + if (fltIf_5768_6575) { + return; + } else { + __Pixel *tmp_112; + tmp_112 = (__Pixel *) vector_nth(pixels, idx); + __Pixel tup = *tmp_112; + IntTy x = tup.field0; + IntTy y = tup.field1; + IntTy z = tup.field2; + // write to file. + fprintf(fp, "%lld %lld %lld\n", x, y, z); + writePpm_loop(fp, (idx+1), end, pixels); + } +} + +/* -------------------------------------------------------------------------------- */ + +int main(int argc, char** argv) +{ + // parameters to parse: + // + // num iterations: How many times to repeat a benchmark. + // tree size: An integer passes to `build_tree()`. + + struct rlimit lim; + int code; + if ( (code = getrlimit(RLIMIT_STACK, &lim)) ) { + fprintf(stderr, " [gibbon rts] failed to getrlimit, code %d\n", code); + exit(1); + } + + // lim.rlim_cur = 1024LU * 1024LU * 1024LU; // 1GB stack. + lim.rlim_cur = 512LU * 1024LU * 1024LU; // 500MB stack. + // lim.rlim_max = lim.rlim_cur; // Normal users may only be able to decrease this. + + // WARNING: Haven't yet figured out why this doesn't work on MacOS... +#ifndef __APPLE__ + code = setrlimit(RLIMIT_STACK, &lim); + while (code) { + fprintf(stderr, " [gibbon rts] Failed to set stack size to %llu, code %d\n", (unsigned long long)lim.rlim_cur, code); + lim.rlim_cur /= 2; + // lim.rlim_max /= 2; + if(lim.rlim_cur < 100 * 1024) { + fprintf(stderr, " [gibbon rts] Failed setrlimit stack size to something reasonable; giving up.\n"); + break; // abort(); + } + int code = setrlimit(RLIMIT_STACK, &lim); + } +#endif + + int got_numargs = 0; // How many numeric arguments have we got. + + int i; + for (i = 1; i < argc; ++i) + { + if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) { + show_usage(argv); + exit(0); + } + else if (strcmp(argv[i], "--biginf-buffer-size") == 0 && i < argc - 1) + { + global_init_biginf_buf_size = atoll(argv[i + 1]); + i++; + } + else if (strcmp(argv[i], "--inf-buffer-size") == 0 && i < argc - 1) + { + global_init_inf_buf_size = atoll(argv[i + 1]); + i++; + } + else if ((strcmp(argv[i], "--bench-input") == 0)) { + if (i+1 >= argc) { + fprintf(stderr, "Not enough arguments after --bench-input, expected .\n"); + show_usage(argv); + exit(1); + } + global_benchfile_param = argv[i+1]; + i++; + } + else if ((strcmp(argv[i], "--array-input") == 0)) { + if (i+1 >= argc) { + fprintf(stderr, "Not enough arguments after --array-input, expected .\n"); + show_usage(argv); + exit(1); + } + global_arrayfile_param = argv[i+1]; + i++; + } + else if (strcmp(argv[i], "--array-input-length") == 0 && i < argc - 1) { + global_arrayfile_length_param = atoll(argv[i+1]); + i++; + } + else if (strcmp(argv[i], "--bench-prog") == 0 && i < argc - 1) { + int len = strlen(argv[i+1]); + global_bench_prog_param = (char*) malloc((len+1)*sizeof(char)); + strncpy(global_bench_prog_param,argv[i+1],len); + i++; + } + // If present, we expect the two arguments to be + else if (got_numargs >= 2) { + fprintf(stderr, "Extra arguments left over: "); + for(; i < argc; i++) fprintf(stderr, "%s ", argv[i]); + show_usage(argv); + exit(1); + } else { + if (got_numargs == 0) { + global_size_param = atoll(argv[i]); + got_numargs ++; + } else { + global_iters_param = atoll(argv[i]); + } + } + } + + // Initialize global_bench_prog_param to an empty string in case + // the runtime argument --bench-prog isn't passed. + if (global_bench_prog_param == NULL) { + global_bench_prog_param = (char*) malloc(1*sizeof(char)); + *global_bench_prog_param = '\n'; + } + + __main_expr(); + + return 0; +} + +// ----------------------------------------------------------------------------- +// Program starts here +// ----------------------------------------------------------------------------- + +typedef struct Prod_struct { } Prod; +typedef struct Int64Prod_struct { + IntTy field0; + } Int64Prod; +typedef struct Int64Int64Int64Int64CursorCursorProd_struct { + IntTy field0; + IntTy field1; + IntTy field2; + IntTy field3; + CursorTy field4; + CursorTy field5; + } Int64Int64Int64Int64CursorCursorProd; +typedef struct Int64Int64Int64CursorCursorProd_struct { + IntTy field0; + IntTy field1; + IntTy field2; + CursorTy field3; + CursorTy field4; + } Int64Int64Int64CursorCursorProd; +typedef struct BoolProd_struct { + BoolTy field0; + } BoolProd; +typedef struct TagCursorProd_struct { + TagTyPacked field0; + CursorTy field1; + } TagCursorProd; +typedef struct CursorProd_struct { + CursorTy field0; + } CursorProd; +IntTy sumLeft(CursorTy m_34_689_917); +CursorTy build(IntTy x_40_695_926, IntTy sz_41_696_927, CursorTy m_42_697_928); +IntTy ratio(); +IntTy delta(); +IntTy size_316(CursorTy m_173_698_938); +CursorTy singleL_323(IntTy k1_100_704_944, IntTy x1_101_705_945, + CursorTy t1_102_706_946, CursorTy m_103_707_947); +CursorTy doubleL_324(IntTy k1_71_713_954, IntTy x1_72_714_955, + CursorTy t1_73_715_956, CursorTy m0_74_716_957); +CursorTy rotateL_317(IntTy k_125_722_963, IntTy x_126_723_964, + CursorTy l_127_724_965, CursorTy r_128_725_966); +CursorTy bin_322(IntTy k_110_731_977, IntTy x_111_732_978, + CursorTy l_112_733_979, CursorTy r_113_734_980); +CursorTy singleR_319(IntTy k1_90_735_985, IntTy x1_91_736_986, + CursorTy m_92_737_987, CursorTy t3_93_738_988); +CursorTy doubleR_320(IntTy k1_56_744_995, IntTy x1_57_745_996, + CursorTy m0_58_746_997, CursorTy t4_59_747_998); +CursorTy empty_321(); +CursorTy rotateR_318(IntTy k_115_753_1004, IntTy x_116_754_1005, + CursorTy l_117_755_1006, CursorTy r_118_756_1007); +CursorTy balance_315(IntTy k_135_762_1018, IntTy x_136_763_1019, + CursorTy l_137_764_1020, CursorTy r_138_765_1021); +CursorTy singleton_312(IntTy k_52_766_1042, IntTy x_53_767_1043); +CursorTy insert_314(IntTy kx_43_768_1046, IntTy x_44_769_1047, + CursorTy m_45_770_1048); +CursorTy _copy_without_ptrs_Map_v_313(CursorTy arg_624_776_1058); +CursorTy _copy_Map_v_313(CursorTy arg_613_787_1069); +unsigned char _traverse_Map_v_313(CursorTy arg_635_798_1080); +unsigned char _print_Map_v_313(CursorTy arg_646_806_1088); +CursorTy caseFn_666(IntTy x1_72_667_826_1108, IntTy k1_71_668_827_1109, + CursorTy t1_73_669_828_1110, CursorTy m1_79_670_829_1111, + IntTy k2_77_671_830_1112, IntTy x2_78_672_831_1113, + CursorTy t4_80_673_832_1114); +CursorTy caseFn_674(IntTy x1_57_675_838_1122, IntTy k1_56_676_839_1123, + CursorTy t4_59_677_840_1124, CursorTy m1_65_678_841_1125, + IntTy k2_62_679_842_1126, IntTy x2_63_680_843_1127, + CursorTy t1_64_681_844_1128); +IntTy sumLeft(CursorTy m_34_689_917) +{ + TagTyPacked tag_1143 = *(TagTyPacked *) m_34_689_917; + CursorTy tail_1144 = m_34_689_917 + sizeof(IntTy); + + + switch_1146: + ; + switch (tag_1143) { + + case 0: + { + return 0; + break; + } + + case 1: + { + IntTy wildcard__1_35_690_918 = + ((Int64Int64Int64CursorCursorProd *) tail_1144)->field0; + IntTy wildcard__2_36_691_919 = + ((Int64Int64Int64CursorCursorProd *) tail_1144)->field1; + IntTy v_37_692_920 = + ((Int64Int64Int64CursorCursorProd *) tail_1144)->field2; + CursorTy l_38_693_921 = + ((Int64Int64Int64CursorCursorProd *) tail_1144)->field3; + CursorTy r_39_694_922 = + ((Int64Int64Int64CursorCursorProd *) tail_1144)->field4; + IntTy fltPrm_852_923 = sumLeft(l_38_693_921); + IntTy fltPrm_851_924 = fltPrm_852_923 + v_37_692_920; + IntTy fltPrm_853_925 = sumLeft(r_39_694_922); + IntTy flt_1145 = fltPrm_851_924 + fltPrm_853_925; + + return flt_1145; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1143"); + exit(1); + } + } +} +CursorTy build(IntTy x_40_695_926, IntTy sz_41_696_927, CursorTy m_42_697_928) +{ + BoolTy fltIf_854_929 = sz_41_696_927 == 0; + + if (fltIf_854_929) { + return m_42_697_928; + } else { + IntTy fltPrm_856_930 = sz_41_696_927 / 2; + IntTy fltAppE_855_931 = x_40_695_926 + fltPrm_856_930; + IntTy fltAppE_857_932 = sz_41_696_927 / 2; + IntTy fltPrm_860_933 = sz_41_696_927 / 2; + IntTy fltAppE_859_934 = x_40_695_926 - fltPrm_860_933; + IntTy fltAppE_861_935 = sz_41_696_927 / 2; + CursorTy fltAppE_862_936 = + insert_314(x_40_695_926, x_40_695_926, m_42_697_928); + CursorTy fltAppE_858_937 = + build(fltAppE_859_934, fltAppE_861_935, fltAppE_862_936); + + return build(fltAppE_855_931, fltAppE_857_932, fltAppE_858_937); + } +} +IntTy ratio() +{ + return 2; +} +IntTy delta() +{ + return 4; +} +IntTy size_316(CursorTy m_173_698_938) +{ + TagTyPacked tag_1147 = *(TagTyPacked *) m_173_698_938; + CursorTy tail_1148 = m_173_698_938 + sizeof(IntTy); + + + switch_1149: + ; + switch (tag_1147) { + + case 0: + { + return 0; + break; + } + + case 1: + { + IntTy sz_175_699_939 = + ((Int64Int64Int64CursorCursorProd *) tail_1148)->field0; + IntTy wildcard__18_176_700_940 = + ((Int64Int64Int64CursorCursorProd *) tail_1148)->field1; + IntTy wildcard__19_177_701_941 = + ((Int64Int64Int64CursorCursorProd *) tail_1148)->field2; + CursorTy wildcard__20_178_702_942 = + ((Int64Int64Int64CursorCursorProd *) tail_1148)->field3; + CursorTy wildcard__21_179_703_943 = + ((Int64Int64Int64CursorCursorProd *) tail_1148)->field4; + + return sz_175_699_939; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1147"); + exit(1); + } + } +} +CursorTy singleL_323(IntTy k1_100_704_944, IntTy x1_101_705_945, + CursorTy t1_102_706_946, CursorTy m_103_707_947) +{ + TagTyPacked tag_1150 = *(TagTyPacked *) m_103_707_947; + CursorTy tail_1151 = m_103_707_947 + sizeof(IntTy); + + + switch_1152: + ; + switch (tag_1150) { + + case 1: + { + IntTy wildcard__123_105_708_948 = + ((Int64Int64Int64CursorCursorProd *) tail_1151)->field0; + IntTy k2_106_709_949 = + ((Int64Int64Int64CursorCursorProd *) tail_1151)->field1; + IntTy x2_107_710_950 = + ((Int64Int64Int64CursorCursorProd *) tail_1151)->field2; + CursorTy t2_108_711_951 = + ((Int64Int64Int64CursorCursorProd *) tail_1151)->field3; + CursorTy t3_109_712_952 = + ((Int64Int64Int64CursorCursorProd *) tail_1151)->field4; + CursorTy fltAppE_863_953 = + bin_322(k1_100_704_944, x1_101_705_945, t1_102_706_946, t2_108_711_951); + + return bin_322(k2_106_709_949, x2_107_710_950, fltAppE_863_953, + t3_109_712_952); + break; + } + + case 0: + { + return empty_321(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1150"); + exit(1); + } + } +} +CursorTy doubleL_324(IntTy k1_71_713_954, IntTy x1_72_714_955, + CursorTy t1_73_715_956, CursorTy m0_74_716_957) +{ + TagTyPacked tag_1153 = *(TagTyPacked *) m0_74_716_957; + CursorTy tail_1154 = m0_74_716_957 + sizeof(IntTy); + + + switch_1155: + ; + switch (tag_1153) { + + case 1: + { + IntTy wildcard__143_76_717_958 = + ((Int64Int64Int64CursorCursorProd *) tail_1154)->field0; + IntTy k2_77_718_959 = + ((Int64Int64Int64CursorCursorProd *) tail_1154)->field1; + IntTy x2_78_719_960 = + ((Int64Int64Int64CursorCursorProd *) tail_1154)->field2; + CursorTy m1_79_720_961 = + ((Int64Int64Int64CursorCursorProd *) tail_1154)->field3; + CursorTy t4_80_721_962 = + ((Int64Int64Int64CursorCursorProd *) tail_1154)->field4; + + return caseFn_666(x1_72_714_955, k1_71_713_954, t1_73_715_956, + m1_79_720_961, k2_77_718_959, x2_78_719_960, + t4_80_721_962); + break; + } + + case 0: + { + return empty_321(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1153"); + exit(1); + } + } +} +CursorTy rotateL_317(IntTy k_125_722_963, IntTy x_126_723_964, + CursorTy l_127_724_965, CursorTy r_128_725_966) +{ + TagTyPacked tag_1156 = *(TagTyPacked *) r_128_725_966; + CursorTy tail_1157 = r_128_725_966 + sizeof(IntTy); + + + switch_1158: + ; + switch (tag_1156) { + + case 1: + { + IntTy wildcard__94_130_726_967 = + ((Int64Int64Int64CursorCursorProd *) tail_1157)->field0; + IntTy wildcard__95_131_727_968 = + ((Int64Int64Int64CursorCursorProd *) tail_1157)->field1; + IntTy wildcard__96_132_728_969 = + ((Int64Int64Int64CursorCursorProd *) tail_1157)->field2; + CursorTy ly_133_729_970 = + ((Int64Int64Int64CursorCursorProd *) tail_1157)->field3; + CursorTy ry_134_730_971 = + ((Int64Int64Int64CursorCursorProd *) tail_1157)->field4; + IntTy fltPrm_865_972 = size_316(ly_133_729_970); + IntTy fltPrm_867_973 = ratio(); + IntTy fltPrm_868_974 = size_316(ry_134_730_971); + IntTy fltPrm_866_975 = fltPrm_867_973 * fltPrm_868_974; + BoolTy fltIf_864_976 = fltPrm_865_972 < fltPrm_866_975; + + if (fltIf_864_976) { + return singleL_323(k_125_722_963, x_126_723_964, l_127_724_965, + r_128_725_966); + } else { + return doubleL_324(k_125_722_963, x_126_723_964, l_127_724_965, + r_128_725_966); + } + break; + } + + case 0: + { + return empty_321(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1156"); + exit(1); + } + } +} +CursorTy bin_322(IntTy k_110_731_977, IntTy x_111_732_978, + CursorTy l_112_733_979, CursorTy r_113_734_980) +{ + IntTy fltPrm_871_981 = size_316(l_112_733_979); + IntTy fltPrm_872_982 = size_316(r_113_734_980); + IntTy fltPrm_870_983 = fltPrm_871_981 + fltPrm_872_982; + IntTy fltPkd_869_984 = fltPrm_870_983 + 1; + PtrTy tailift_1159 = ALLOC(sizeof(Int64Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1159)->field0 = 1; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1159)->field1 = + fltPkd_869_984; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1159)->field2 = + k_110_731_977; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1159)->field3 = + x_111_732_978; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1159)->field4 = + l_112_733_979; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1159)->field5 = + r_113_734_980; + return tailift_1159; +} +CursorTy singleR_319(IntTy k1_90_735_985, IntTy x1_91_736_986, + CursorTy m_92_737_987, CursorTy t3_93_738_988) +{ + TagTyPacked tag_1160 = *(TagTyPacked *) m_92_737_987; + CursorTy tail_1161 = m_92_737_987 + sizeof(IntTy); + + + switch_1162: + ; + switch (tag_1160) { + + case 1: + { + IntTy wildcard__133_95_739_989 = + ((Int64Int64Int64CursorCursorProd *) tail_1161)->field0; + IntTy k2_96_740_990 = + ((Int64Int64Int64CursorCursorProd *) tail_1161)->field1; + IntTy x2_97_741_991 = + ((Int64Int64Int64CursorCursorProd *) tail_1161)->field2; + CursorTy t1_98_742_992 = + ((Int64Int64Int64CursorCursorProd *) tail_1161)->field3; + CursorTy t2_99_743_993 = + ((Int64Int64Int64CursorCursorProd *) tail_1161)->field4; + CursorTy fltAppE_873_994 = + bin_322(k1_90_735_985, x1_91_736_986, t2_99_743_993, t3_93_738_988); + + return bin_322(k2_96_740_990, x2_97_741_991, t1_98_742_992, + fltAppE_873_994); + break; + } + + case 0: + { + return empty_321(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1160"); + exit(1); + } + } +} +CursorTy doubleR_320(IntTy k1_56_744_995, IntTy x1_57_745_996, + CursorTy m0_58_746_997, CursorTy t4_59_747_998) +{ + TagTyPacked tag_1163 = *(TagTyPacked *) m0_58_746_997; + CursorTy tail_1164 = m0_58_746_997 + sizeof(IntTy); + + + switch_1165: + ; + switch (tag_1163) { + + case 1: + { + IntTy wildcard__167_61_748_999 = + ((Int64Int64Int64CursorCursorProd *) tail_1164)->field0; + IntTy k2_62_749_1000 = + ((Int64Int64Int64CursorCursorProd *) tail_1164)->field1; + IntTy x2_63_750_1001 = + ((Int64Int64Int64CursorCursorProd *) tail_1164)->field2; + CursorTy t1_64_751_1002 = + ((Int64Int64Int64CursorCursorProd *) tail_1164)->field3; + CursorTy m1_65_752_1003 = + ((Int64Int64Int64CursorCursorProd *) tail_1164)->field4; + + return caseFn_674(x1_57_745_996, k1_56_744_995, t4_59_747_998, + m1_65_752_1003, k2_62_749_1000, x2_63_750_1001, + t1_64_751_1002); + break; + } + + case 0: + { + return empty_321(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1163"); + exit(1); + } + } +} +CursorTy empty_321() +{ + PtrTy tailift_1166 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) tailift_1166)->field0 = 0; + return tailift_1166; +} +CursorTy rotateR_318(IntTy k_115_753_1004, IntTy x_116_754_1005, + CursorTy l_117_755_1006, CursorTy r_118_756_1007) +{ + TagTyPacked tag_1167 = *(TagTyPacked *) l_117_755_1006; + CursorTy tail_1168 = l_117_755_1006 + sizeof(IntTy); + + + switch_1169: + ; + switch (tag_1167) { + + case 1: + { + IntTy wildcard__106_120_757_1008 = + ((Int64Int64Int64CursorCursorProd *) tail_1168)->field0; + IntTy wildcard__107_121_758_1009 = + ((Int64Int64Int64CursorCursorProd *) tail_1168)->field1; + IntTy wildcard__108_122_759_1010 = + ((Int64Int64Int64CursorCursorProd *) tail_1168)->field2; + CursorTy ly_123_760_1011 = + ((Int64Int64Int64CursorCursorProd *) tail_1168)->field3; + CursorTy ry_124_761_1012 = + ((Int64Int64Int64CursorCursorProd *) tail_1168)->field4; + IntTy fltPrm_875_1013 = size_316(ry_124_761_1012); + IntTy fltPrm_877_1014 = ratio(); + IntTy fltPrm_878_1015 = size_316(ly_123_760_1011); + IntTy fltPrm_876_1016 = fltPrm_877_1014 * fltPrm_878_1015; + BoolTy fltIf_874_1017 = fltPrm_875_1013 < fltPrm_876_1016; + + if (fltIf_874_1017) { + return singleR_319(k_115_753_1004, x_116_754_1005, + l_117_755_1006, r_118_756_1007); + } else { + return doubleR_320(k_115_753_1004, x_116_754_1005, + l_117_755_1006, r_118_756_1007); + } + break; + } + + case 0: + { + return empty_321(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1167"); + exit(1); + } + } +} +CursorTy balance_315(IntTy k_135_762_1018, IntTy x_136_763_1019, + CursorTy l_137_764_1020, CursorTy r_138_765_1021) +{ + IntTy fltPrm_881_1022 = size_316(l_137_764_1020); + IntTy fltPrm_882_1023 = size_316(r_138_765_1021); + IntTy fltPrm_880_1024 = fltPrm_881_1022 + fltPrm_882_1023; + BoolTy fltIf_879_1025 = fltPrm_880_1024 <= 1; + + if (fltIf_879_1025) { + IntTy fltPrm_884_1026 = size_316(l_137_764_1020); + IntTy fltPrm_885_1027 = size_316(r_138_765_1021); + IntTy fltPkd_883_1028 = fltPrm_884_1026 + fltPrm_885_1027; + PtrTy tailift_1170 = + ALLOC(sizeof(Int64Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1170)->field0 = 1; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1170)->field1 = + fltPkd_883_1028; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1170)->field2 = + k_135_762_1018; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1170)->field3 = + x_136_763_1019; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1170)->field4 = + l_137_764_1020; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1170)->field5 = + r_138_765_1021; + return tailift_1170; + } else { + IntTy fltPrm_887_1029 = size_316(r_138_765_1021); + IntTy fltPrm_889_1030 = delta(); + IntTy fltPrm_890_1031 = size_316(l_137_764_1020); + IntTy fltPrm_888_1032 = fltPrm_889_1030 * fltPrm_890_1031; + BoolTy fltIf_886_1033 = fltPrm_887_1029 >= fltPrm_888_1032; + + if (fltIf_886_1033) { + return rotateL_317(k_135_762_1018, x_136_763_1019, l_137_764_1020, + r_138_765_1021); + } else { + IntTy fltPrm_892_1034 = size_316(l_137_764_1020); + IntTy fltPrm_894_1035 = delta(); + IntTy fltPrm_895_1036 = size_316(r_138_765_1021); + IntTy fltPrm_893_1037 = fltPrm_894_1035 * fltPrm_895_1036; + BoolTy fltIf_891_1038 = fltPrm_892_1034 >= fltPrm_893_1037; + + if (fltIf_891_1038) { + return rotateR_318(k_135_762_1018, x_136_763_1019, + l_137_764_1020, r_138_765_1021); + } else { + IntTy fltPrm_897_1039 = size_316(l_137_764_1020); + IntTy fltPrm_898_1040 = size_316(r_138_765_1021); + IntTy fltPkd_896_1041 = fltPrm_897_1039 + fltPrm_898_1040; + PtrTy tailift_1171 = + ALLOC(sizeof(Int64Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1171)->field0 = + 1; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1171)->field1 = + fltPkd_896_1041; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1171)->field2 = + k_135_762_1018; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1171)->field3 = + x_136_763_1019; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1171)->field4 = + l_137_764_1020; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1171)->field5 = + r_138_765_1021; + return tailift_1171; + } + } + } +} +CursorTy singleton_312(IntTy k_52_766_1042, IntTy x_53_767_1043) +{ + PtrTy fltPkd_899_1044 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_899_1044)->field0 = 0; + + PtrTy fltPkd_900_1045 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_900_1045)->field0 = 0; + + PtrTy tailift_1172 = ALLOC(sizeof(Int64Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1172)->field0 = 1; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1172)->field1 = 1; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1172)->field2 = + k_52_766_1042; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1172)->field3 = + x_53_767_1043; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1172)->field4 = + fltPkd_899_1044; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1172)->field5 = + fltPkd_900_1045; + return tailift_1172; +} +CursorTy insert_314(IntTy kx_43_768_1046, IntTy x_44_769_1047, + CursorTy m_45_770_1048) +{ + TagTyPacked tag_1173 = *(TagTyPacked *) m_45_770_1048; + CursorTy tail_1174 = m_45_770_1048 + sizeof(IntTy); + + + switch_1176: + ; + switch (tag_1173) { + + case 0: + { + return singleton_312(kx_43_768_1046, x_44_769_1047); + break; + } + + case 1: + { + IntTy sz_47_771_1049 = + ((Int64Int64Int64CursorCursorProd *) tail_1174)->field0; + IntTy k_48_772_1050 = + ((Int64Int64Int64CursorCursorProd *) tail_1174)->field1; + IntTy v_49_773_1051 = + ((Int64Int64Int64CursorCursorProd *) tail_1174)->field2; + CursorTy l_50_774_1052 = + ((Int64Int64Int64CursorCursorProd *) tail_1174)->field3; + CursorTy r_51_775_1053 = + ((Int64Int64Int64CursorCursorProd *) tail_1174)->field4; + BoolTy fltIf_901_1054 = kx_43_768_1046 == k_48_772_1050; + + if (fltIf_901_1054) { + PtrTy tailift_1175 = + ALLOC(sizeof(Int64Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1175)->field0 = + 1; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1175)->field1 = + sz_47_771_1049; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1175)->field2 = + k_48_772_1050; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1175)->field3 = + x_44_769_1047; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1175)->field4 = + l_50_774_1052; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1175)->field5 = + r_51_775_1053; + return tailift_1175; + } else { + BoolTy fltIf_902_1055 = kx_43_768_1046 <= k_48_772_1050; + + if (fltIf_902_1055) { + CursorTy fltAppE_903_1056 = + insert_314(kx_43_768_1046, x_44_769_1047, l_50_774_1052); + + return balance_315(k_48_772_1050, v_49_773_1051, + fltAppE_903_1056, r_51_775_1053); + } else { + CursorTy fltAppE_904_1057 = + insert_314(kx_43_768_1046, x_44_769_1047, r_51_775_1053); + + return balance_315(k_48_772_1050, v_49_773_1051, + l_50_774_1052, fltAppE_904_1057); + } + } + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1173"); + exit(1); + } + } +} +CursorTy _copy_without_ptrs_Map_v_313(CursorTy arg_624_776_1058) +{ + TagTyPacked tag_1177 = *(TagTyPacked *) arg_624_776_1058; + CursorTy tail_1178 = arg_624_776_1058 + sizeof(IntTy); + + + switch_1181: + ; + switch (tag_1177) { + + case 0: + { + PtrTy tailift_1179 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) tailift_1179)->field0 = 0; + return tailift_1179; + break; + } + + case 1: + { + IntTy x_625_777_1059 = + ((Int64Int64Int64CursorCursorProd *) tail_1178)->field0; + IntTy x_626_778_1060 = + ((Int64Int64Int64CursorCursorProd *) tail_1178)->field1; + IntTy x_627_779_1061 = + ((Int64Int64Int64CursorCursorProd *) tail_1178)->field2; + CursorTy x_628_780_1062 = + ((Int64Int64Int64CursorCursorProd *) tail_1178)->field3; + CursorTy x_629_781_1063 = + ((Int64Int64Int64CursorCursorProd *) tail_1178)->field4; + CursorTy y_633_785_1067 = + _copy_without_ptrs_Map_v_313(x_628_780_1062); + CursorTy y_634_786_1068 = + _copy_without_ptrs_Map_v_313(x_629_781_1063); + PtrTy tailift_1180 = + ALLOC(sizeof(Int64Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1180)->field0 = 1; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1180)->field1 = + x_625_777_1059; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1180)->field2 = + x_626_778_1060; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1180)->field3 = + x_627_779_1061; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1180)->field4 = + y_633_785_1067; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1180)->field5 = + y_634_786_1068; + return tailift_1180; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1177"); + exit(1); + } + } +} +CursorTy _copy_Map_v_313(CursorTy arg_613_787_1069) +{ + TagTyPacked tag_1182 = *(TagTyPacked *) arg_613_787_1069; + CursorTy tail_1183 = arg_613_787_1069 + sizeof(IntTy); + + + switch_1186: + ; + switch (tag_1182) { + + case 0: + { + PtrTy tailift_1184 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) tailift_1184)->field0 = 0; + return tailift_1184; + break; + } + + case 1: + { + IntTy x_614_788_1070 = + ((Int64Int64Int64CursorCursorProd *) tail_1183)->field0; + IntTy x_615_789_1071 = + ((Int64Int64Int64CursorCursorProd *) tail_1183)->field1; + IntTy x_616_790_1072 = + ((Int64Int64Int64CursorCursorProd *) tail_1183)->field2; + CursorTy x_617_791_1073 = + ((Int64Int64Int64CursorCursorProd *) tail_1183)->field3; + CursorTy x_618_792_1074 = + ((Int64Int64Int64CursorCursorProd *) tail_1183)->field4; + CursorTy y_622_796_1078 = _copy_Map_v_313(x_617_791_1073); + CursorTy y_623_797_1079 = _copy_Map_v_313(x_618_792_1074); + PtrTy tailift_1185 = + ALLOC(sizeof(Int64Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1185)->field0 = 1; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1185)->field1 = + x_614_788_1070; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1185)->field2 = + x_615_789_1071; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1185)->field3 = + x_616_790_1072; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1185)->field4 = + y_622_796_1078; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1185)->field5 = + y_623_797_1079; + return tailift_1185; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1182"); + exit(1); + } + } +} +unsigned char _traverse_Map_v_313(CursorTy arg_635_798_1080) +{ + TagTyPacked tag_1187 = *(TagTyPacked *) arg_635_798_1080; + CursorTy tail_1188 = arg_635_798_1080 + sizeof(IntTy); + + + switch_1189: + ; + switch (tag_1187) { + + case 0: + { + return 0; + break; + } + + case 1: + { + IntTy x_636_799_1081 = + ((Int64Int64Int64CursorCursorProd *) tail_1188)->field0; + IntTy x_637_800_1082 = + ((Int64Int64Int64CursorCursorProd *) tail_1188)->field1; + IntTy x_638_801_1083 = + ((Int64Int64Int64CursorCursorProd *) tail_1188)->field2; + CursorTy x_639_802_1084 = + ((Int64Int64Int64CursorCursorProd *) tail_1188)->field3; + CursorTy x_640_803_1085 = + ((Int64Int64Int64CursorCursorProd *) tail_1188)->field4; + unsigned char y_644_804_1086 = _traverse_Map_v_313(x_639_802_1084); + unsigned char y_645_805_1087 = _traverse_Map_v_313(x_640_803_1085); + + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1187"); + exit(1); + } + } +} +unsigned char _print_Map_v_313(CursorTy arg_646_806_1088) +{ + TagTyPacked tag_1190 = *(TagTyPacked *) arg_646_806_1088; + CursorTy tail_1191 = arg_646_806_1088 + sizeof(IntTy); + + + switch_1192: + ; + switch (tag_1190) { + + case 0: + { + unsigned char wildcard_647_807_1089 = print_symbol(1139); + unsigned char wildcard_648_808_1090 = print_symbol(1138); + + return 0; + break; + } + + case 1: + { + IntTy x_649_809_1091 = + ((Int64Int64Int64CursorCursorProd *) tail_1191)->field0; + IntTy x_650_810_1092 = + ((Int64Int64Int64CursorCursorProd *) tail_1191)->field1; + IntTy x_651_811_1093 = + ((Int64Int64Int64CursorCursorProd *) tail_1191)->field2; + CursorTy x_652_812_1094 = + ((Int64Int64Int64CursorCursorProd *) tail_1191)->field3; + CursorTy x_653_813_1095 = + ((Int64Int64Int64CursorCursorProd *) tail_1191)->field4; + unsigned char wildcard_659_814_1096 = print_symbol(1140); + unsigned char wildcard_665_815_1097 = print_symbol(1141); + unsigned char y_654_816_1098 = printf("%lld", x_649_809_1091); + unsigned char wildcard_664_817_1099 = print_symbol(1141); + unsigned char y_655_818_1100 = printf("%lld", x_650_810_1092); + unsigned char wildcard_663_819_1101 = print_symbol(1141); + unsigned char y_656_820_1102 = printf("%lld", x_651_811_1093); + unsigned char wildcard_662_821_1103 = print_symbol(1141); + unsigned char y_657_822_1104 = _print_Map_v_313(x_652_812_1094); + unsigned char wildcard_661_823_1105 = print_symbol(1141); + unsigned char y_658_824_1106 = _print_Map_v_313(x_653_813_1095); + unsigned char wildcard_660_825_1107 = print_symbol(1138); + + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1190"); + exit(1); + } + } +} +CursorTy caseFn_666(IntTy x1_72_667_826_1108, IntTy k1_71_668_827_1109, + CursorTy t1_73_669_828_1110, CursorTy m1_79_670_829_1111, + IntTy k2_77_671_830_1112, IntTy x2_78_672_831_1113, + CursorTy t4_80_673_832_1114) +{ + TagTyPacked tag_1193 = *(TagTyPacked *) m1_79_670_829_1111; + CursorTy tail_1194 = m1_79_670_829_1111 + sizeof(IntTy); + + + switch_1195: + ; + switch (tag_1193) { + + case 1: + { + IntTy wildcard__144_81_833_1115 = + ((Int64Int64Int64CursorCursorProd *) tail_1194)->field0; + IntTy k3_82_834_1116 = + ((Int64Int64Int64CursorCursorProd *) tail_1194)->field1; + IntTy x3_83_835_1117 = + ((Int64Int64Int64CursorCursorProd *) tail_1194)->field2; + CursorTy t2_84_836_1118 = + ((Int64Int64Int64CursorCursorProd *) tail_1194)->field3; + CursorTy t3_85_837_1119 = + ((Int64Int64Int64CursorCursorProd *) tail_1194)->field4; + CursorTy fltAppE_905_1120 = + bin_322(k1_71_668_827_1109, x1_72_667_826_1108, t1_73_669_828_1110, t2_84_836_1118); + CursorTy fltAppE_906_1121 = + bin_322(k2_77_671_830_1112, x2_78_672_831_1113, t3_85_837_1119, t4_80_673_832_1114); + + return bin_322(k3_82_834_1116, x3_83_835_1117, fltAppE_905_1120, + fltAppE_906_1121); + break; + } + + case 0: + { + return empty_321(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1193"); + exit(1); + } + } +} +CursorTy caseFn_674(IntTy x1_57_675_838_1122, IntTy k1_56_676_839_1123, + CursorTy t4_59_677_840_1124, CursorTy m1_65_678_841_1125, + IntTy k2_62_679_842_1126, IntTy x2_63_680_843_1127, + CursorTy t1_64_681_844_1128) +{ + TagTyPacked tag_1196 = *(TagTyPacked *) m1_65_678_841_1125; + CursorTy tail_1197 = m1_65_678_841_1125 + sizeof(IntTy); + + + switch_1198: + ; + switch (tag_1196) { + + case 1: + { + IntTy wildcard__168_66_845_1129 = + ((Int64Int64Int64CursorCursorProd *) tail_1197)->field0; + IntTy k3_67_846_1130 = + ((Int64Int64Int64CursorCursorProd *) tail_1197)->field1; + IntTy x3_68_847_1131 = + ((Int64Int64Int64CursorCursorProd *) tail_1197)->field2; + CursorTy t2_69_848_1132 = + ((Int64Int64Int64CursorCursorProd *) tail_1197)->field3; + CursorTy t3_70_849_1133 = + ((Int64Int64Int64CursorCursorProd *) tail_1197)->field4; + CursorTy fltAppE_907_1134 = + bin_322(k2_62_679_842_1126, x2_63_680_843_1127, t1_64_681_844_1128, t2_69_848_1132); + CursorTy fltAppE_908_1135 = + bin_322(k1_56_676_839_1123, x1_57_675_838_1122, t3_70_849_1133, t4_59_677_840_1124); + + return bin_322(k3_67_846_1130, x3_68_847_1131, fltAppE_907_1134, + fltAppE_908_1135); + break; + } + + case 0: + { + return empty_321(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1196"); + exit(1); + } + } +} +int __main_expr() +{ + add_symbol(1138, ")"); + add_symbol(1139, "(Tip_v_313"); + add_symbol(1140, "(Bin_v_313"); + add_symbol(1141, " "); + add_symbol(1142, "\n"); + + CursorTy fltAppE_850_909 = singleton_312(0, 0); + CursorTy m_25_682_910 = build(0, 512, fltAppE_850_909); + IntTy timed_1136; + VectorTy *times_3 = vector_alloc(global_iters_param, sizeof(double)); + struct timespec begin_timed_1136; + struct timespec end_timed_1136; + + for (long long iters_timed_1136 = 0; iters_timed_1136 < global_iters_param; + iters_timed_1136++) { + if (iters_timed_1136 != global_iters_param - 1) + save_alloc_state(); + clock_gettime(CLOCK_MONOTONIC_RAW, &begin_timed_1136); + + IntTy timed_1136hack = sumLeft(m_25_682_910); + + timed_1136 = timed_1136hack; + clock_gettime(CLOCK_MONOTONIC_RAW, &end_timed_1136); + if (iters_timed_1136 != global_iters_param - 1) + restore_alloc_state(); + + double itertime_0 = difftimespecs(&begin_timed_1136, &end_timed_1136); + + vector_inplace_update(times_3, iters_timed_1136, &itertime_0); + } + vector_inplace_sort(times_3, compare_doubles); + + double *tmp_4 = (double *) vector_nth(times_3, global_iters_param / 2); + double selftimed_2 = *tmp_4; + double batchtime_1 = sum_timing_array(times_3); + + print_timing_array(times_3); + printf("ITERS: %lld\n", global_iters_param); + printf("SIZE: %lld\n", global_size_param); + printf("BATCHTIME: %e\n", batchtime_1); + printf("SELFTIMED: %e\n", selftimed_2); + + unsigned char wildcard__19_27_684_912 = printf("%lld", timed_1136); + unsigned char wildcard__17_28_685_913 = print_symbol(1142); + IntTy timed_1137; + VectorTy *times_8 = vector_alloc(global_iters_param, sizeof(double)); + struct timespec begin_timed_1137; + struct timespec end_timed_1137; + + for (long long iters_timed_1137 = 0; iters_timed_1137 < global_iters_param; + iters_timed_1137++) { + if (iters_timed_1137 != global_iters_param - 1) + save_alloc_state(); + clock_gettime(CLOCK_MONOTONIC_RAW, &begin_timed_1137); + + IntTy timed_1137hack = sumLeft(m_25_682_910); + + timed_1137 = timed_1137hack; + clock_gettime(CLOCK_MONOTONIC_RAW, &end_timed_1137); + if (iters_timed_1137 != global_iters_param - 1) + restore_alloc_state(); + + double itertime_5 = difftimespecs(&begin_timed_1137, &end_timed_1137); + + vector_inplace_update(times_8, iters_timed_1137, &itertime_5); + } + vector_inplace_sort(times_8, compare_doubles); + + double *tmp_9 = (double *) vector_nth(times_8, global_iters_param / 2); + double selftimed_7 = *tmp_9; + double batchtime_6 = sum_timing_array(times_8); + + print_timing_array(times_8); + printf("ITERS: %lld\n", global_iters_param); + printf("SIZE: %lld\n", global_size_param); + printf("BATCHTIME: %e\n", batchtime_6); + printf("SELFTIMED: %e\n", selftimed_7); + + unsigned char wildcard__13_30_687_915 = printf("%lld", timed_1137); + unsigned char wildcard__11_31_688_916 = print_symbol(1142); + + printf("'#()"); + printf("\n"); + free_symtable(); + return 0; +} \ No newline at end of file diff --git a/benchmarks/Layouts/_Left.hs b/benchmarks/Layouts/_Left.hs new file mode 100644 index 000000000..458cc7085 --- /dev/null +++ b/benchmarks/Layouts/_Left.hs @@ -0,0 +1,28 @@ + +module Left where +import Common +import Map + +sumLeft :: Map Int -> Int +sumLeft m = + case m of + Tip -> 0 + Bin _ _ v l r -> sumLeft(l) + v + sumLeft(r) + + +build :: Int -> Int -> Map Int -> Map Int +build x sz m = + if (sz == 0) then m + else (build (x + sz/2) (sz/2) (build (x - sz/2) (sz/2) (insert x x m))) + +gibbon_main = + let m = (build 0 512 (singleton 0 0)) + --_ = printsym (quote "SUM RIGHT: ") + s0 = iterate (sumLeft m) + _ = printint (s0) + _ = printsym (quote "\n") + --_ = printsym (quote "SUM LEFT: ") + s1 = iterate (sumLeft m) + _ = printint (s1) + _ = printsym (quote "\n") + in () \ No newline at end of file diff --git a/benchmarks/Layouts/_LeftAndRight.c b/benchmarks/Layouts/_LeftAndRight.c new file mode 100644 index 000000000..bdd27807e --- /dev/null +++ b/benchmarks/Layouts/_LeftAndRight.c @@ -0,0 +1,2488 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// #include +#ifdef _WIN64 +#include +#endif +#include +#include +#include // For va_start etc +#include +#include +#include +#include +#ifdef _POINTER +#include +#endif +#ifdef _PARALLEL +#include +#include +#endif + +#define KB 1024lu +#define MB (KB * 1000lu) +#define GB (MB * 1000lu) + +#define REDIRECTION_TAG 255 +#define INDIRECTION_TAG 254 + +// Initial size of BigInfinite buffers +static long long global_init_biginf_buf_size = (4 * GB); + +// Initial size of Infinite buffers +static long long global_init_inf_buf_size = 1 * KB; + +// Maximum size of a chunk, see GitHub #110. +static long long global_inf_buf_max_chunk_size = 1 * GB; + +static long long global_size_param = 1; +static long long global_iters_param = 1; + +static char* global_benchfile_param = NULL; +static char* global_arrayfile_param = NULL; +// Number of lines in the arrayfile +static long long global_arrayfile_length_param = -1; + +// Sequential for now: +static const int num_workers = 1; + +// Count the number of regions allocated. +static long long global_region_count = 0; +static bool global_region_count_flag = false; + +#ifdef _PARALLEL +static inline void bump_global_region_count() { + __atomic_add_fetch(&global_region_count, 1, __ATOMIC_SEQ_CST); + return; +} +#else +static inline void bump_global_region_count() { + global_region_count++; + return; +} +#endif + +static inline void print_global_region_count() { + printf("REGION_COUNT: %lld\n", global_region_count); + return; +} + +#define REDIRECTION_NODE_SIZE 9 +#define MAX(a,b) (((a)>(b))?(a):(b)) +#define MIN(a,b) (((a)<(b))?(a):(b)) + +// https://www.cprogramming.com/snippets/source-code/find-the-number-of-cpu-cores-for-windows-mac-or-linux +static int get_num_processors() { +#ifdef _WIN64 + SYSTEM_INFO sysinfo; + GetSystemInfo(&sysinfo); + return sysinfo.dwNumberOfProcessors; +#else + return sysconf(_SC_NPROCESSORS_ONLN); +#endif +} + +// Requires -std=gnu11 +int dbgprintf(const char *format, ...) { + int code = 0; + va_list args; + va_start(args, format); +#ifdef _DEBUG + code = vprintf(format, args); +#endif + va_end(args); + return code; +} + + +// ----------------------------------------------------------------------------- +// Allocators +// ----------------------------------------------------------------------------- + + +// ------------------------------------- +// Bump allocation for linked-lists +// ------------------------------------- + + +#ifdef _BUMPALLOC +// #define _DEBUG +#warning "Using bump allocator." + +__thread char* bumpalloc_heap_ptr = (char*)NULL; +__thread char* bumpalloc_heap_ptr_end = (char*)NULL; + +char* saved_heap_ptr_stack[100]; +int num_saved_heap_ptr = 0; + +// For simplicity just use a single large slab: +static inline void INITBUMPALLOC() { + bumpalloc_heap_ptr = (char*)malloc(global_init_biginf_buf_size); + bumpalloc_heap_ptr_end = bumpalloc_heap_ptr + global_init_biginf_buf_size; +#ifdef _DEBUG + printf("Arena size for bump alloc: %lld\n", global_init_biginf_buf_size); + printf("BUMPALLOC/INITBUMPALLOC DONE: heap_ptr = %p\n", bumpalloc_heap_ptr); +#endif +} + +static inline void* BUMPALLOC(long long n) { + if (! bumpalloc_heap_ptr) { + INITBUMPALLOC(); + } + if (bumpalloc_heap_ptr + n < bumpalloc_heap_ptr_end) { + char* old= bumpalloc_heap_ptr; + bumpalloc_heap_ptr += n; + return old; + } else { + fprintf(stderr, "Warning: bump allocator ran out of memory."); + exit(1); + } +} + +// Snapshot the current heap pointer value across all threads. +void save_alloc_state() { + dbgprintf("Saving(%p): pos %d", heap_ptr, num_saved_heap_ptr); + saved_heap_ptr_stack[num_saved_heap_ptr] = heap_ptr; + num_saved_heap_ptr++; + dbgprintf("\n"); +} + +void restore_alloc_state() { + if(num_saved_heap_ptr <= 0) { + fprintf(stderr, "Bad call to restore_alloc_state! Saved stack empty!\ne"); + exit(1); + } + num_saved_heap_ptr--; + dbgprintf("Restoring(%p): pos %d, discarding %p", + saved_heap_ptr_stack[num_saved_heap_ptr], num_saved_heap_ptr, bumpalloc_heap_ptr); + bumpalloc_heap_ptr = saved_heap_ptr_stack[num_saved_heap_ptr]; +} + + +#else +// Regular malloc mode: +void INITBUMPALLOC() {} +void save_alloc_state() {} +void restore_alloc_state() {} + +#define BUMPALLOC(n) malloc(n) + +#endif // BUMPALLOC + + +// ------------------------------------- +// ALLOC and ALLOC_PACKED macros +// ------------------------------------- + + +/* + +If parallelism is enabled, we always use a malloc based allocator +since Boehm GC is not thread-safe in its default configuration. It can be +made thread-safe by building it with appropriate flags, but we don't do that. +Presently, all parallel pointer-based programs will leak memory. + +*/ + +#ifdef _PARALLEL +#define ALLOC(n) malloc(n) +#define ALLOC_PACKED_BIG(n) malloc(n) +char *ALLOC_COUNTED(size_t size) { + bump_global_region_count(); + return ALLOC(size); +} +#else + #ifdef _POINTER +#define ALLOC(n) GC_MALLOC(n) +#define ALLOC_PACKED_BIG(n) GC_MALLOC(n) +char *ALLOC_COUNTED(size_t size) { + bump_global_region_count(); + return GC_MALLOC(size); +} + #else +#define ALLOC(n) malloc(n) +#define ALLOC_PACKED_BIG(n) malloc(n) +char *ALLOC_COUNTED(size_t size) { + bump_global_region_count(); + return ALLOC(size); +} + #endif // _POINTER +#endif // _PARALLEL + + +// Could try alloca() here. Better yet, we could keep our own, +// separate stack and insert our own code to restore the pointer +// before any function that (may have) called ALLOC_SCOPED returns. + +// #define ALLOC_SCOPED() alloca(1024) +#define ALLOC_SCOPED(n) alloca(n) +// #define ALLOC_SCOPED() alloc_scoped() + +// Stack allocation is either too small or blows our stack. +// We need a way to make a giant stack if we want to use alloca. +// #define ALLOC_SCOPED() ALLOC(global_init_biginf_buf_size) + +// Our global pointer. No parallelism. +// static char* stack_scoped_region; +// char* alloc_scoped() { return stack_scoped_region; } + + + +// ------------------------------------- +// Basic types +// ------------------------------------- + +// Must be consistent with sizeOfTy defined in Gibbon.Language.Syntax. + +typedef unsigned char TagTyPacked; +typedef unsigned char TagTyBoxed; +typedef long long IntTy; +typedef char CharTy; +typedef float FloatTy; +typedef unsigned long long SymTy; +typedef bool BoolTy; +typedef char* PtrTy; +typedef char* CursorTy; + +// ------------------------------------- +// Arenas and dictionaries +// ------------------------------------- + +typedef struct mem_arena { + int ind; + char* mem; // TODO(vollmerm): make this a list of chunks? + void* reflist; +} mem_arena_t; + +typedef mem_arena_t* ArenaTy; + +ArenaTy alloc_arena() { + ArenaTy ar = ALLOC(sizeof(mem_arena_t)); + ar->ind = 0; + ar->mem = malloc(global_inf_buf_max_chunk_size); + ar->reflist = 0; + return ar; +} + +void free_arena(ArenaTy ar) { + free(ar->mem); + // TODO(vollmerm): free everything in ar->reflist + free(ar); +} + +CursorTy extend_arena(ArenaTy ar, int size) { + CursorTy ret = ar->mem + ar->ind; + ar->ind += size; + return ret; +} + +typedef struct dict_item { + struct dict_item * next; + int key; + void * ptrval; +} dict_item_t; + +dict_item_t * dict_alloc(ArenaTy ar) { + return (dict_item_t *) extend_arena(ar, sizeof(dict_item_t)); // ALLOC(sizeof(dict_item_t)); +} + +dict_item_t *dict_insert_ptr(ArenaTy ar, dict_item_t *ptr, SymTy key, PtrTy val) { + dict_item_t *ret = dict_alloc(ar); + ret->key = key; + ret->ptrval = val; + ret->next = ptr; + return ret; +} + +PtrTy dict_lookup_ptr(dict_item_t *ptr, SymTy key) { + while (ptr != 0) { + if (ptr->key == key) { + return ptr->ptrval; + } else { + ptr = ptr->next; + } + } + printf("Error, key %lld not found!\n",key); + exit(1); +} + +// ------------------------------------- +// Sets +// ------------------------------------- + + +struct set_elem { + int val; + UT_hash_handle hh; +}; + +typedef struct set_elem* SymSetTy; + +SymSetTy empty_set() { + return NULL; +} + +SymSetTy insert_set(SymSetTy set, int sym) { + SymSetTy s; + HASH_FIND_INT(set, &sym, s); /* sym already in the hash? */ + if (s==NULL) { + s = malloc(sizeof(struct set_elem)); + s->val = sym; + HASH_ADD_INT(set,val,s); + } + return set; +} + +BoolTy contains_set(SymSetTy set, int sym) { + SymSetTy s; + HASH_FIND_INT(set, &sym, s); + return (s!=NULL); +} + +// ------------------------------------- +// Sym Hash +// ------------------------------------- + +struct sym_hash_elem { + int key; + int val; + UT_hash_handle hh; +}; + +typedef struct sym_hash_elem* SymHashTy; + +typedef struct sym_hash_elem* IntHashTy; + +SymHashTy empty_hash() { + return NULL; +} + +SymHashTy insert_hash(SymHashTy hash, int k, int v) { + SymHashTy s; + // NOTE: not checking for duplicates! + // s = malloc(sizeof(struct sym_hash_elem)); + s = ALLOC(sizeof(struct sym_hash_elem)); + s->val = v; + s->key = k; + HASH_ADD_INT(hash,key,s); + + return hash; +} + +IntTy lookup_hash(SymHashTy hash, int k) { + SymHashTy s; + HASH_FIND_INT(hash,&k,s); + if (s==NULL) { + return k; // NOTE: return original key if val not found + // TODO(vollmerm): come up with something better to do here + } else { + return s->val; + } +} + +BoolTy contains_hash(SymHashTy hash, int sym) { + SymHashTy s; + HASH_FIND_INT(hash,&sym,s); + return (s!=NULL); +} + +// ------------------------------------- +// Helpers +// ------------------------------------- + +char* read_benchfile_param() { + if (global_benchfile_param == NULL) { + fprintf(stderr, "read_benchfile_param: benchmark input file was not set! Set using --bench-input.\n"); + exit(1); + } else + return global_benchfile_param; +} + +char* read_arrayfile_param() { + if (global_arrayfile_param == NULL) { + fprintf(stderr, "read_arrayfile_param: array input file was not set! Set using --array-input.\n"); + exit(1); + } else + return global_arrayfile_param; +} + +IntTy read_arrayfile_length_param() { + if (global_arrayfile_length_param == -1) { + fprintf(stderr, "read_arrayfile_length_param: array input file length was not set! Set using --array-input-length.\n"); + exit(1); + } else + return global_arrayfile_length_param; +} + + +// fun fact: __ prefix is actually reserved and this is an undefined behavior. +// These functions must be provided by the code generator. +int __main_expr(); + + +void show_usage(char** argv) +{ + printf("\n"); + printf("This binary was generated by the Gibbon compiler.\n"); + printf("\n"); + printf("Usage: %s [OPTS] [size] [iters]\n", argv[0]); + + printf("\n"); + printf("Options:\n"); + printf(" --buffer-size Set the buffer size (default %lld).\n", global_init_biginf_buf_size); + printf(" --bench-input Set the input file read for benchmarking. Applies only\n"); + printf(" IF the program was *compiled* with --bench-fun. \n"); + return; +} + +double avg(const double* arr, int n) +{ + double sum = 0.0; + for(int i=0; itv_sec - t0->tv_sec) + + ((double)(t1->tv_nsec - t0->tv_nsec) / 1000000000.0); +} + +int compare_doubles(const void *a, const void *b) +{ + const double *da = (const double *) a; + const double *db = (const double *) b; + return (*da > *db) - (*da < *db); +} + +// Exponentiation +IntTy expll(IntTy base, IntTy pow) { + if (base == 2) { + return (1 << pow); + } else { + IntTy i, result = 1; + for (i = 0; i < pow; i++) + result *= base; + return result; + } + } + +// ------------------------------------- +// Symbol table +// ------------------------------------- + +#define global_max_symbol_len 256 + +// Invariant: should always be equal to max(sym_table_keys) +static SymTy global_gensym_counter = 0; + +// Its value is updated by the flags parser. +static char *global_bench_prog_param; + +static SymTy newline_symbol = -1; +static SymTy space_symbol = -1; +static SymTy comma_symbol = -1; +static SymTy leftparen_symbol = -1; +static SymTy rightparen_symbol = -1; + +typedef struct SymTable_elem { + SymTy idx; /* key */ + char value[global_max_symbol_len]; + UT_hash_handle hh; /* makes this structure hashable */ +} SymTable_elem; + +// important! initialize to NULL +SymTable_elem *global_sym_table = NULL; + +void add_symbol(SymTy idx, char *value) { + struct SymTable_elem *s; + s = ALLOC(sizeof(struct SymTable_elem)); + s->idx = idx; + strcpy(s->value, value); + HASH_ADD(hh, global_sym_table, idx, sizeof(IntTy), s); + if (idx > global_gensym_counter) { + global_gensym_counter = idx; + } +} + +void set_newline(SymTy idx) { + newline_symbol = idx; + add_symbol(idx,"NEWLINE"); +} + +void set_space(SymTy idx) { + space_symbol = idx; + add_symbol(idx,"SPACE"); +} + +void set_comma(SymTy idx) { + comma_symbol = idx; + add_symbol(idx,"COMMA"); +} + +void set_leftparen(SymTy idx) { + leftparen_symbol = idx; + add_symbol(idx,"LEFTPAREN"); +} + +void set_rightparen(SymTy idx) { + rightparen_symbol = idx; + add_symbol(idx,"RIGHTPAREN"); +} + +IntTy print_symbol(SymTy idx) { + if (idx == comma_symbol) { + return printf(","); + } else if (idx == newline_symbol) { + return printf("\n"); + } else if (idx == space_symbol) { + return printf(" "); + } else if (idx == leftparen_symbol) { + return printf("("); + } else if (idx == rightparen_symbol) { + return printf(")"); + } else { + struct SymTable_elem *s; + HASH_FIND(hh, global_sym_table, &idx, sizeof(SymTy), s); + if (s == NULL) { + return printf("%lld", idx); + } else { + return printf("%s", s->value); + } + + } +} + +#ifdef _PARALLEL +SymTy gensym() { + SymTy idx = __atomic_add_fetch(&global_gensym_counter, 1, __ATOMIC_SEQ_CST); + return idx; +} +#else +SymTy gensym() { + global_gensym_counter += 1; + SymTy idx = global_gensym_counter; + return idx; +} +#endif + +void free_symtable() { + struct SymTable_elem *elt, *tmp; + HASH_ITER(hh, global_sym_table, elt, tmp) { + HASH_DEL(global_sym_table,elt); + } + free(elt); + free(tmp); +} + +/* + +---------------------------------------- +Garbage collection +---------------------------------------- + + Gibbon has "growing regions" i.e each logical region is backed by a doubly linked-list + of smaller chunks which grows as required. In addition to actual data, each chunk + stores some additional metadata (RegionFooter) to chain the chunks together in a list + and for garbage collection. The footer: + + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + serialized data | rf_reg_metadata_ptr | rf_seq_no | rf_size | rf_next | rf_prev + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + The metadata after the serialized data serves various purposes: + + - rf_reg_metadata_ptr: A pointer to a RegionTy struct that contains various metadata. + Of particular interest to us are the fields: + + = reg_id: A unique identifier for a region. + + = refcount and outset: Whenever an inter-region indirection is created, we record that information + using these two fields. Suppose we have an indirection from region A that points to some chunk + in region B. Then A's outset will store a pointer to that chunk's footer, and B's refcount will + be bumped by 1. Note that all there's only 1 refcount cell, and 1 outset per logical region, + and chunks only store a pointer to them. + + - rf_seq_no: The index of this particular chunk in the list. + + - rf_size: Used during bounds checking to calculate the size of the next region in + the linked list. + + - rf_next / rf_prev: Point to the next and previous chunk respectively. + + +There are two ways in which a region may be freed: + +(1) Whenever it goes out of scope + + The RTS tries to free a region whenever it goes out of scope. But this doesn't always succeed as + regions sometimes contain values that "escape". One reason why this'll happen is if there's an + indirection from A->B, and A lives longer than B. + In such a case, when B goes out of scope it's refcount won't be 0, and the RTS won't free it. + This brings us to (2). + +(2) + + When the RTS successfully frees a region, it decrements the refcounts of all the regions it + points to (via the outset). At the same time, if it encounters a region in the outset whoose + refcount becomes 0 after the decrement, it calls free_region on that. This way we can be sure + that all regions will eventually be garbage collected before the program exits. + + + +Why is it a doubly linked-list? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Due to way that bounds-checking works, the pointers in the outset may actually point to any +arbitrary chunk in the chain. However, we must call free_region on the first one to ensure that +all of them are GC'd. So we need pointers to traverse backward get to the first one. +'trav_to_first_chunk' accomplishes this. + + */ + +#define MAX_OUTSET_LENGTH 10 + +typedef struct RegionTy_struct { + SymTy reg_id; + uint reg_refcount; + CursorTy reg_heap; + uint reg_outset_len; + CursorTy reg_outset[MAX_OUTSET_LENGTH]; +} RegionTy; + +typedef struct RegionFooter_struct { + RegionTy *rf_reg_metadata_ptr; + + IntTy rf_seq_no; + IntTy rf_size; + struct RegionFooter_struct *rf_next; + struct RegionFooter_struct *rf_prev; +} RegionFooter; + +typedef struct ChunkTy_struct { + CursorTy chunk_start; + CursorTy chunk_end; +} ChunkTy; + +static inline void insert_into_outset(CursorTy ptr, RegionTy *reg) { + uint outset_len = reg->reg_outset_len; + // Check for duplicates. + for (uint i = 0; i < outset_len; i++) { + if (ptr == reg->reg_outset[i]) { + return; + } + } + // Otherwise, insert into the outset. + reg->reg_outset[outset_len] = ptr; + reg->reg_outset_len = outset_len + 1; + return; +} + +static inline void remove_from_outset(CursorTy ptr, RegionTy *reg) { + uint outset_len = reg->reg_outset_len; + CursorTy *outset = reg->reg_outset; + int i; + if (outset_len == 0) { + fprintf(stderr, "remove_from_outset: empty outset\n"); + exit(1); + } + // Position of 'ptr' in the outset. + int elt_idx = -1; + for (i = 0; i < outset_len; i++) { + if (ptr == outset[i]) { + elt_idx = i; + } + } + if (elt_idx == -1) { + fprintf(stderr, "remove_from_outset: element not found\n"); + exit(1); + } + // Move all elements ahead of 'elt_idx' back by one position. + for (i = elt_idx; i < outset_len; i++) { + outset[i] = outset[i+1]; + } + return; +} + +RegionTy *alloc_region(IntTy size) { + // Allocate the region metadata. + RegionTy *reg = ALLOC(sizeof(RegionTy)); + if (reg == NULL) { + printf("alloc_region: allocation failed: %ld", sizeof(RegionTy)); + exit(1); + } + + // Allocate the first chunk. + IntTy total_size = size + sizeof(RegionFooter); + CursorTy heap = ALLOC_PACKED_BIG(total_size); + if (heap == NULL) { + printf("alloc_region: malloc failed: %lld", total_size); + exit(1); + } + // Not heap+total_size, since we must keep space for the footer. + CursorTy heap_end = heap + size; + + // Initialize metadata fields. + reg->reg_id = gensym(); + reg->reg_refcount = 1; + reg->reg_heap = heap; + reg->reg_outset_len = 0; + +#ifdef _DEBUG + printf("Allocated a region(%lld): %lld bytes.\n", reg->reg_id, size); +#endif + + // Write the footer. + RegionFooter *footer = (RegionFooter *) heap_end; + footer->rf_reg_metadata_ptr = reg; + footer->rf_seq_no = 1; + footer->rf_size = size; + footer->rf_next = NULL; + footer->rf_prev = NULL; + + return reg; +} + +RegionTy *alloc_counted_region(IntTy size) { + // Bump the count. + bump_global_region_count(); + return alloc_region(size); +} + +ChunkTy alloc_chunk(CursorTy end_old_chunk) { + // Get size from current footer. + RegionFooter *footer = (RegionFooter *) end_old_chunk; + IntTy newsize = footer->rf_size * 2; + // See #110. + if (newsize > global_inf_buf_max_chunk_size) { + newsize = global_inf_buf_max_chunk_size; + } + IntTy total_size = newsize + sizeof(RegionFooter); + + // Allocate. + CursorTy start = ALLOC_PACKED_BIG(total_size); + if (start == NULL) { + printf("alloc_chunk: malloc failed: %lld", total_size); + exit(1); + } + CursorTy end = start + newsize; + + // Link the next chunk's footer. + footer->rf_next = (RegionFooter *) end; + + // Write the footer. + RegionFooter* new_footer = (RegionFooter *) end; + new_footer->rf_reg_metadata_ptr = footer->rf_reg_metadata_ptr; + new_footer->rf_seq_no = footer->rf_seq_no + 1; + new_footer->rf_size = newsize; + new_footer->rf_next = NULL; + new_footer->rf_prev = footer; + +#ifdef _DEBUG + RegionTy *reg = (RegionTy*) new_footer->rf_reg_metadata_ptr; + printf("alloc_chunk: allocated %lld bytes for region %lld.\n", total_size, reg->reg_id); +#endif + + return (ChunkTy) {start , end}; +} + +RegionFooter* trav_to_first_chunk(RegionFooter *footer) { + if (footer->rf_seq_no == 1) { + return footer; + } else if (footer->rf_prev == NULL) { + fprintf(stderr, "No previous chunk found at rf_seq_no: %lld", footer->rf_seq_no); + return NULL; + } else { + trav_to_first_chunk((RegionFooter *) footer->rf_prev); + } + return NULL; +} + +uint get_ref_count(CursorTy end_ptr) { + RegionFooter *footer = (RegionFooter *) end_ptr; + RegionTy *reg = (RegionTy *) footer->rf_reg_metadata_ptr; + return reg->reg_refcount; +} + +// B is the pointer, and A is the pointee (i.e B -> A). +// Bump A's refcount and update B's outset. +static inline void bump_ref_count(CursorTy end_b, CursorTy end_a) { + // Grab footers. + RegionFooter *footer_a = (RegionFooter *) end_a; + RegionFooter *footer_b = (RegionFooter *) end_b; + + // Grab metadata. + RegionTy *reg_a = (RegionTy *) footer_a->rf_reg_metadata_ptr; + RegionTy *reg_b = (RegionTy *) footer_b->rf_reg_metadata_ptr; + + // Bump A's refcount. + uint current_refcount, new_refcount; + current_refcount = reg_a->reg_refcount; + new_refcount = current_refcount + 1; + reg_a->reg_refcount = new_refcount; + +#ifdef _DEBUG + printf("bump_ref_count: %lld -> %lld\n", reg_b->reg_id, reg_a->reg_id); + printf("bump_ref_count: old-refcount=%d, old-outset-len=%d:\n", current_refcount, reg_b->reg_outset_len); + assert(current_refcount == reg_b->reg_outset_len+1); +#endif + + // Add A to B's outset. + insert_into_outset(end_a, reg_b); + +#ifdef _DEBUG + // printf("bump_ref_count: Added %p to %lld's outset, %p.\n", end_a, reg_b->reg_id, reg_b); + printf("bump_ref_count: new-refcount=%d, new-outset-len=%d\n", new_refcount, reg_b->reg_outset_len); + assert(new_refcount == reg_b->reg_outset_len+1); +#endif + + return; +} + +void free_region(CursorTy end_reg) { + // Grab footer and the metadata. + RegionFooter *footer = (RegionFooter *) end_reg; + RegionTy *reg = (RegionTy *) footer->rf_reg_metadata_ptr; + + // + RegionFooter *first_chunk_footer, *next_chunk_footer; + CursorTy first_chunk, next_chunk; + + // Decrement current reference count. + uint current_refcount, new_refcount; + current_refcount = reg->reg_refcount; + new_refcount = 0; + if (current_refcount != 0) { + new_refcount = current_refcount - 1; + reg->reg_refcount = new_refcount; + } + +#ifdef _DEBUG + printf("free_region(%lld): refcounts (1): old-refcount=%d, new-refcount=%d:\n", reg->reg_id, current_refcount, new_refcount); +#endif + + + // Free this region recount is 0. + if (new_refcount == 0) { + +#ifdef _DEBUG + printf("free_region(%lld): outset length: %d\n", reg->reg_id, reg->reg_outset_len); +#endif + + // Decrement refcounts, free regions with refcount==0 and also free + // elements of the outset. + if (reg->reg_outset_len != 0) { + uint outset_len = reg->reg_outset_len; + CursorTy *outset = reg->reg_outset; + RegionFooter *elt_footer; + RegionTy *elt_reg; + uint elt_current_refcount, elt_new_refcount; + CursorTy to_be_removed[MAX_OUTSET_LENGTH]; + uint to_be_removed_idx = 0; + for (int i = 0; i < outset_len; i++) { + elt_footer = (RegionFooter *) outset[i]; + elt_reg = (RegionTy *) elt_footer->rf_reg_metadata_ptr; +#ifdef _DEBUG + elt_current_refcount = elt_reg->reg_refcount; +#endif + elt_new_refcount = elt_current_refcount - 1; + elt_reg->reg_refcount = elt_new_refcount; +#ifdef _DEBUG + printf("free_region(%lld): old-refcount=%d, new-refcount=%d:\n", + elt_reg->reg_id, elt_current_refcount, elt_reg->reg_refcount); +#endif + if (elt_new_refcount == 0) { + // See [Why is it a doubly linked-list?] above + first_chunk_footer = trav_to_first_chunk(elt_footer); + if (first_chunk_footer != NULL) { + free_region((CursorTy) first_chunk_footer); + } + } + to_be_removed[to_be_removed_idx] = outset[i]; + to_be_removed_idx++; + } + // Remove elements from the outset. + for (uint i = 0; i < to_be_removed_idx; i++) { + remove_from_outset(to_be_removed[i], reg); + } + } + + +#ifdef _DEBUG + // Bookkeeping + IntTy num_freed_chunks = 0, total_bytesize = 0; +#endif + + // Free the chunks in this region. + first_chunk = end_reg - footer->rf_size; + first_chunk_footer = footer; + next_chunk = (char*) footer->rf_next; + +#ifdef _DEBUG + printf("free_region(%lld)\n", reg->reg_id); +#endif + +#ifdef _DEBUG + num_freed_chunks++; + total_bytesize = total_bytesize + first_chunk_footer->rf_size; +#endif + free(first_chunk); + + while (next_chunk != NULL) { + next_chunk_footer = (RegionFooter *) next_chunk; + #ifdef _DEBUG + num_freed_chunks++; + total_bytesize = total_bytesize + next_chunk_footer->rf_size; + #endif + free(next_chunk - next_chunk_footer->rf_size); + next_chunk = (char*) next_chunk_footer->rf_next; + } + +#ifdef _DEBUG + printf("free_region(%lld): Freed %lld bytes across %lld chunks.\n", + reg->reg_id, total_bytesize, num_freed_chunks); +#endif + + // Free the metadata. + free(reg); + + } else { +#ifdef _DEBUG + printf("free_region(%lld): non-zero refcount: %d.\n", + reg->reg_id, reg->reg_refcount); +#endif + } +} + +// Assume that all nodes with size information have tags >= 150. +BoolTy is_big(IntTy i, CursorTy cur) { + TagTyPacked tag = *(TagTyPacked *) cur; + if (tag >= 150) { + cur += 1; + IntTy size = *(IntTy *) cur; + if (size >= i) { + return true; + } else { + return false; + } + } + return false; +} + +// ------------------------------------- +// Vectors +// ------------------------------------- + +typedef struct VectorTy_struct { + // Bounds on the vector. + IntTy vec_lower, vec_upper; + + // Size of each element. + IntTy vec_elt_size; + + // Actual elements of the vector. + void* vec_data; +} VectorTy; + +VectorTy* vector_alloc(IntTy num, IntTy elt_size) { + VectorTy *vec = ALLOC(sizeof(VectorTy)); + if (vec == NULL) { + printf("alloc_vector: malloc failed: %ld", sizeof(VectorTy)); + exit(1); + } + void* data = ALLOC(num * elt_size); + if (data == NULL) { + printf("alloc_vector: malloc failed: %ld", sizeof(num * elt_size)); + exit(1); + } + vec->vec_lower = 0; + vec->vec_upper = num; + vec->vec_elt_size = elt_size; + vec->vec_data = data; + return vec; +} + +IntTy vector_length(VectorTy *vec) { + return (vec->vec_upper - vec->vec_lower); +} + +BoolTy vector_is_empty(VectorTy *vec) { + return (vector_length(vec) == 0); +} + +VectorTy* vector_slice(IntTy i, IntTy n, VectorTy *vec) { + IntTy lower = vec->vec_lower + i; + IntTy upper = vec->vec_lower + i + n; + if ((lower > vec->vec_upper)) { + printf("vector_slice: lower out of bounds, %lld > %lld", lower, vec->vec_upper); + exit(1); + } + if ((upper > vec->vec_upper)) { + printf("vector_slice: upper out of bounds: %lld > %lld", upper, vec->vec_upper); + exit(1); + } + VectorTy *vec2 = ALLOC(sizeof(VectorTy)); + if (vec == NULL) { + printf("vector_slice: malloc failed: %ld", sizeof(VectorTy)); + exit(1); + } + vec2->vec_lower = lower; + vec2->vec_upper = upper; + vec2->vec_elt_size = vec->vec_elt_size; + vec2->vec_data = vec->vec_data; + return vec2; +} + +// The callers must cast the return value. +static inline void* vector_nth(VectorTy *vec, IntTy i) { + // if (i < vec->lower || i > vec->upper) { + // printf("vector_nth index out of bounds: %lld (%lld,%lld) \n", i, vec->vec_lower, vec->vec_upper); + // exit(1); + // } + return (vec->vec_data + (vec->vec_elt_size * (vec->vec_lower + i))); +} + +static inline VectorTy* vector_inplace_update(VectorTy *vec, IntTy i, void* elt) { + void* dst = vector_nth(vec, i); + memcpy(dst, elt, vec->vec_elt_size); + return vec; +} + +static inline VectorTy* vector_copy(VectorTy *vec) { + IntTy len = vector_length(vec); + void *start = vector_nth(vec, 0); + VectorTy *vec2 = vector_alloc(len, vec->vec_elt_size); + memcpy(vec2->vec_data, start, len * vec->vec_elt_size); + return vec2; +} + +static inline VectorTy* vector_inplace_sort(VectorTy *vec, int (*compar)(const void *, const void*)) { + void *start = vector_nth(vec, 0); + qsort(start, vector_length(vec), vec->vec_elt_size, compar); + return vec; +} + +static inline VectorTy* vector_sort(VectorTy *vec, int (*compar)(const void *, const void*)) { + VectorTy *vec2 = vector_copy(vec); + vector_inplace_sort(vec2, compar); + return vec2; +} + +static inline VectorTy* vector_concat(VectorTy *vec) { + // Length of the input vector. + IntTy len = vector_length(vec); + // Length of the concatenated vector. + IntTy result_len = 0; + // Size of each element in the concatenated vector. + IntTy result_elt_size = 0; + VectorTy **elt_ref, *elt; + for (IntTy i = 0; i < len; i++) { + elt_ref = vector_nth(vec, i); + elt = *elt_ref; + result_elt_size = elt->vec_elt_size; + result_len += vector_length(elt); + } + + // Concatenated vector. + VectorTy *result = vector_alloc(result_len, result_elt_size); + IntTy elt_len; + // A counter that tracks the index of elements in 'result'. + IntTy k = 0; + for (IntTy i = 0; i < len; i++) { + elt_ref = vector_nth(vec, i); + elt = *elt_ref; + elt_len = vector_length(elt); + + for (IntTy j = 0; j < elt_len; j++) { + void* k_elt = vector_nth(elt, j); + vector_inplace_update(result, k, k_elt); + k++; + } + } + + return result; +} + +static inline void vector_free(VectorTy *vec) { + free(vec->vec_data); + free(vec); + return; +} + +static inline VectorTy* vector_merge(VectorTy *vec1, VectorTy *vec2) { + if (vec1->vec_upper != vec2->vec_lower) { + printf("vector_merge: non-contiguous slices, (%lld,%lld), (%lld,%lld).", + vec1->vec_lower, vec1->vec_upper, vec2->vec_lower, vec2->vec_upper); + exit(1); + } + VectorTy *merged = ALLOC(sizeof(VectorTy)); + if (merged == NULL) { + printf("vector_merge: malloc failed: %ld", sizeof(VectorTy)); + exit(1); + } + merged->vec_lower = vec1->vec_lower; + merged->vec_upper = vec2->vec_upper; + merged->vec_elt_size = vec1->vec_elt_size; + merged->vec_data = vec1->vec_data; + return merged; +} + +void print_timing_array(VectorTy *times) { + printf("TIMES: ["); + double *d; + IntTy n = vector_length(times); + for(int i = 0; i < n; i++) { + d = vector_nth(times, i); + if (i == (n-1)) { + printf("%f",*d); + } + else { + printf("%f, ",*d); + } + } + printf("]\n"); +} + +double sum_timing_array(VectorTy *times) { + double *d; + double acc = 0; + for(int i = 0; i < vector_length(times); i++) { + d = vector_nth(times, i); + acc += *d; + } + return acc; +} + +// ------------------------------------- +// Linked lists +// ------------------------------------- + +typedef struct ListTy_struct { + IntTy ll_data_size; + void* ll_data; + struct ListTy_struct* ll_next; +} ListTy; + +static inline ListTy* list_alloc(IntTy data_size) { + // ListTy *ls = ALLOC(sizeof(ListTy)); + ListTy *ls = BUMPALLOC(sizeof(ListTy)); + ls->ll_data_size = data_size; + ls->ll_data = NULL; + ls->ll_next = NULL; + return ls; +} + +static inline BoolTy list_is_empty(ListTy *ls) { + return ls->ll_next == NULL; +} + +static inline ListTy* list_cons(void* elt, ListTy *ls) { + // void* data = ALLOC(ls->data_size); + void* data = BUMPALLOC(ls->ll_data_size); + if (data == NULL) { + printf("list_cons: malloc failed: %lld", ls->ll_data_size); + exit(1); + } + memcpy(data, elt, ls->ll_data_size); + // ListTy *res = ALLOC(sizeof(ListTy)); + ListTy *res = BUMPALLOC(sizeof(ListTy)); + res->ll_data_size = ls->ll_data_size; + res->ll_data = data; + res->ll_next = (ListTy*) ls; + return res; +} + +static inline void* list_head(ListTy *ls) { + return ls->ll_data; +} + +static inline ListTy* list_tail(ListTy *ls) { + return ls->ll_next; +} + +static inline void list_free(ListTy *ls) { + free(ls->ll_data); + free(ls); + return; +} + +static inline ListTy* list_copy(ListTy *ls) { + ListTy *ls2 = list_alloc(ls->ll_data_size); + if (ls->ll_data != NULL) { + void* data = BUMPALLOC(ls->ll_data_size); + memcpy(data, ls->ll_data, ls->ll_data_size); + ls2->ll_data = data; + } + ls2->ll_next = ls->ll_next; + return ls2; +} + +// ------------------------------------- +// Ppm Images +// ------------------------------------- + +typedef struct __Pixel_struct { + IntTy field0; + IntTy field1; + IntTy field2; +} __Pixel; + +void writePpm(char* filename, IntTy width, IntTy height, VectorTy *pixels); +void writePpm_loop(FILE *fp, IntTy idx, IntTy end, VectorTy *pixels); + +// Example: writePpm("gibbon_rgb_1000.ppm", 1000, 1000, pixels); +void writePpm(char* filename, IntTy width, IntTy height, VectorTy *pixels) +{ + FILE *fp; + fp = fopen(filename, "w+"); + fprintf(fp, "P3\n"); + fprintf(fp, "%lld %lld\n255\n", width, height); + IntTy len = vector_length(pixels); + writePpm_loop(fp, 0, len, pixels); + fclose(fp); + return; +} + +void writePpm_loop(FILE *fp, IntTy idx, IntTy end, VectorTy *pixels) +{ + BoolTy fltIf_5768_6575 = idx == end; + + if (fltIf_5768_6575) { + return; + } else { + __Pixel *tmp_112; + tmp_112 = (__Pixel *) vector_nth(pixels, idx); + __Pixel tup = *tmp_112; + IntTy x = tup.field0; + IntTy y = tup.field1; + IntTy z = tup.field2; + // write to file. + fprintf(fp, "%lld %lld %lld\n", x, y, z); + writePpm_loop(fp, (idx+1), end, pixels); + } +} + +/* -------------------------------------------------------------------------------- */ + +int main(int argc, char** argv) +{ + // parameters to parse: + // + // num iterations: How many times to repeat a benchmark. + // tree size: An integer passes to `build_tree()`. + + struct rlimit lim; + int code; + if ( (code = getrlimit(RLIMIT_STACK, &lim)) ) { + fprintf(stderr, " [gibbon rts] failed to getrlimit, code %d\n", code); + exit(1); + } + + // lim.rlim_cur = 1024LU * 1024LU * 1024LU; // 1GB stack. + lim.rlim_cur = 512LU * 1024LU * 1024LU; // 500MB stack. + // lim.rlim_max = lim.rlim_cur; // Normal users may only be able to decrease this. + + // WARNING: Haven't yet figured out why this doesn't work on MacOS... +#ifndef __APPLE__ + code = setrlimit(RLIMIT_STACK, &lim); + while (code) { + fprintf(stderr, " [gibbon rts] Failed to set stack size to %llu, code %d\n", (unsigned long long)lim.rlim_cur, code); + lim.rlim_cur /= 2; + // lim.rlim_max /= 2; + if(lim.rlim_cur < 100 * 1024) { + fprintf(stderr, " [gibbon rts] Failed setrlimit stack size to something reasonable; giving up.\n"); + break; // abort(); + } + int code = setrlimit(RLIMIT_STACK, &lim); + } +#endif + + int got_numargs = 0; // How many numeric arguments have we got. + + int i; + for (i = 1; i < argc; ++i) + { + if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) { + show_usage(argv); + exit(0); + } + else if (strcmp(argv[i], "--biginf-buffer-size") == 0 && i < argc - 1) + { + global_init_biginf_buf_size = atoll(argv[i + 1]); + i++; + } + else if (strcmp(argv[i], "--inf-buffer-size") == 0 && i < argc - 1) + { + global_init_inf_buf_size = atoll(argv[i + 1]); + i++; + } + else if ((strcmp(argv[i], "--bench-input") == 0)) { + if (i+1 >= argc) { + fprintf(stderr, "Not enough arguments after --bench-input, expected .\n"); + show_usage(argv); + exit(1); + } + global_benchfile_param = argv[i+1]; + i++; + } + else if ((strcmp(argv[i], "--array-input") == 0)) { + if (i+1 >= argc) { + fprintf(stderr, "Not enough arguments after --array-input, expected .\n"); + show_usage(argv); + exit(1); + } + global_arrayfile_param = argv[i+1]; + i++; + } + else if (strcmp(argv[i], "--array-input-length") == 0 && i < argc - 1) { + global_arrayfile_length_param = atoll(argv[i+1]); + i++; + } + else if (strcmp(argv[i], "--bench-prog") == 0 && i < argc - 1) { + int len = strlen(argv[i+1]); + global_bench_prog_param = (char*) malloc((len+1)*sizeof(char)); + strncpy(global_bench_prog_param,argv[i+1],len); + i++; + } + // If present, we expect the two arguments to be + else if (got_numargs >= 2) { + fprintf(stderr, "Extra arguments left over: "); + for(; i < argc; i++) fprintf(stderr, "%s ", argv[i]); + show_usage(argv); + exit(1); + } else { + if (got_numargs == 0) { + global_size_param = atoll(argv[i]); + got_numargs ++; + } else { + global_iters_param = atoll(argv[i]); + } + } + } + + // Initialize global_bench_prog_param to an empty string in case + // the runtime argument --bench-prog isn't passed. + if (global_bench_prog_param == NULL) { + global_bench_prog_param = (char*) malloc(1*sizeof(char)); + *global_bench_prog_param = '\n'; + } + + __main_expr(); + + return 0; +} + +// ----------------------------------------------------------------------------- +// Program starts here +// ----------------------------------------------------------------------------- + +typedef struct Prod_struct { } Prod; +typedef struct Int64Prod_struct { + IntTy field0; + } Int64Prod; +typedef struct Int64Int64Int64Int64CursorCursorProd_struct { + IntTy field0; + IntTy field1; + IntTy field2; + IntTy field3; + CursorTy field4; + CursorTy field5; + } Int64Int64Int64Int64CursorCursorProd; +typedef struct Int64Int64Int64CursorCursorProd_struct { + IntTy field0; + IntTy field1; + IntTy field2; + CursorTy field3; + CursorTy field4; + } Int64Int64Int64CursorCursorProd; +typedef struct BoolProd_struct { + BoolTy field0; + } BoolProd; +typedef struct TagCursorProd_struct { + TagTyPacked field0; + CursorTy field1; + } TagCursorProd; +typedef struct CursorProd_struct { + CursorTy field0; + } CursorProd; +IntTy sumRight(CursorTy m_42_711_948); +CursorTy build(IntTy x_48_717_957, IntTy sz_49_718_958, CursorTy m_50_719_959); +IntTy sumLeft(CursorTy m_51_720_969); +IntTy ratio(); +IntTy delta(); +IntTy size_332(CursorTy m_187_726_978); +CursorTy singleL_339(IntTy k1_114_732_984, IntTy x1_115_733_985, + CursorTy t1_116_734_986, CursorTy m_117_735_987); +CursorTy doubleL_340(IntTy k1_85_741_994, IntTy x1_86_742_995, + CursorTy t1_87_743_996, CursorTy m0_88_744_997); +CursorTy rotateL_333(IntTy k_139_750_1003, IntTy x_140_751_1004, + CursorTy l_141_752_1005, CursorTy r_142_753_1006); +CursorTy bin_338(IntTy k_124_759_1017, IntTy x_125_760_1018, + CursorTy l_126_761_1019, CursorTy r_127_762_1020); +CursorTy singleR_335(IntTy k1_104_763_1025, IntTy x1_105_764_1026, + CursorTy m_106_765_1027, CursorTy t3_107_766_1028); +CursorTy doubleR_336(IntTy k1_70_772_1035, IntTy x1_71_773_1036, + CursorTy m0_72_774_1037, CursorTy t4_73_775_1038); +CursorTy empty_337(); +CursorTy rotateR_334(IntTy k_129_781_1044, IntTy x_130_782_1045, + CursorTy l_131_783_1046, CursorTy r_132_784_1047); +CursorTy balance_331(IntTy k_149_790_1058, IntTy x_150_791_1059, + CursorTy l_151_792_1060, CursorTy r_152_793_1061); +CursorTy singleton_328(IntTy k_66_794_1082, IntTy x_67_795_1083); +CursorTy insert_330(IntTy kx_57_796_1086, IntTy x_58_797_1087, + CursorTy m_59_798_1088); +CursorTy _copy_without_ptrs_Map_v_329(CursorTy arg_646_804_1098); +CursorTy _copy_Map_v_329(CursorTy arg_635_815_1109); +unsigned char _traverse_Map_v_329(CursorTy arg_657_826_1120); +unsigned char _print_Map_v_329(CursorTy arg_668_834_1128); +CursorTy caseFn_688(IntTy x1_86_689_854_1148, IntTy k1_85_690_855_1149, + CursorTy t1_87_691_856_1150, CursorTy m1_93_692_857_1151, + IntTy k2_91_693_858_1152, IntTy x2_92_694_859_1153, + CursorTy t4_94_695_860_1154); +CursorTy caseFn_696(IntTy x1_71_697_866_1162, IntTy k1_70_698_867_1163, + CursorTy t4_73_699_868_1164, CursorTy m1_79_700_869_1165, + IntTy k2_76_701_870_1166, IntTy x2_77_702_871_1167, + CursorTy t1_78_703_872_1168); +IntTy sumRight(CursorTy m_42_711_948) +{ + TagTyPacked tag_1183 = *(TagTyPacked *) m_42_711_948; + CursorTy tail_1184 = m_42_711_948 + sizeof(IntTy); + + + switch_1186: + ; + switch (tag_1183) { + + case 0: + { + return 0; + break; + } + + case 1: + { + IntTy wildcard__1_43_712_949 = + ((Int64Int64Int64CursorCursorProd *) tail_1184)->field0; + IntTy wildcard__2_44_713_950 = + ((Int64Int64Int64CursorCursorProd *) tail_1184)->field1; + IntTy v_45_714_951 = + ((Int64Int64Int64CursorCursorProd *) tail_1184)->field2; + CursorTy l_46_715_952 = + ((Int64Int64Int64CursorCursorProd *) tail_1184)->field3; + CursorTy r_47_716_953 = + ((Int64Int64Int64CursorCursorProd *) tail_1184)->field4; + IntTy fltPrm_880_954 = sumRight(r_47_716_953); + IntTy fltPrm_879_955 = fltPrm_880_954 + v_45_714_951; + IntTy fltPrm_881_956 = sumRight(l_46_715_952); + IntTy flt_1185 = fltPrm_879_955 + fltPrm_881_956; + + return flt_1185; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1183"); + exit(1); + } + } +} +CursorTy build(IntTy x_48_717_957, IntTy sz_49_718_958, CursorTy m_50_719_959) +{ + BoolTy fltIf_882_960 = sz_49_718_958 == 0; + + if (fltIf_882_960) { + return m_50_719_959; + } else { + IntTy fltPrm_884_961 = sz_49_718_958 / 2; + IntTy fltAppE_883_962 = x_48_717_957 - fltPrm_884_961; + IntTy fltAppE_885_963 = sz_49_718_958 / 2; + IntTy fltPrm_888_964 = sz_49_718_958 / 2; + IntTy fltAppE_887_965 = x_48_717_957 + fltPrm_888_964; + IntTy fltAppE_889_966 = sz_49_718_958 / 2; + CursorTy fltAppE_890_967 = + insert_330(x_48_717_957, x_48_717_957, m_50_719_959); + CursorTy fltAppE_886_968 = + build(fltAppE_887_965, fltAppE_889_966, fltAppE_890_967); + + return build(fltAppE_883_962, fltAppE_885_963, fltAppE_886_968); + } +} +IntTy sumLeft(CursorTy m_51_720_969) +{ + TagTyPacked tag_1187 = *(TagTyPacked *) m_51_720_969; + CursorTy tail_1188 = m_51_720_969 + sizeof(IntTy); + + + switch_1190: + ; + switch (tag_1187) { + + case 0: + { + return 0; + break; + } + + case 1: + { + IntTy wildcard__9_52_721_970 = + ((Int64Int64Int64CursorCursorProd *) tail_1188)->field0; + IntTy wildcard__10_53_722_971 = + ((Int64Int64Int64CursorCursorProd *) tail_1188)->field1; + IntTy v_54_723_972 = + ((Int64Int64Int64CursorCursorProd *) tail_1188)->field2; + CursorTy l_55_724_973 = + ((Int64Int64Int64CursorCursorProd *) tail_1188)->field3; + CursorTy r_56_725_974 = + ((Int64Int64Int64CursorCursorProd *) tail_1188)->field4; + IntTy fltPrm_892_975 = sumLeft(l_55_724_973); + IntTy fltPrm_891_976 = fltPrm_892_975 + v_54_723_972; + IntTy fltPrm_893_977 = sumLeft(r_56_725_974); + IntTy flt_1189 = fltPrm_891_976 + fltPrm_893_977; + + return flt_1189; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1187"); + exit(1); + } + } +} +IntTy ratio() +{ + return 2; +} +IntTy delta() +{ + return 4; +} +IntTy size_332(CursorTy m_187_726_978) +{ + TagTyPacked tag_1191 = *(TagTyPacked *) m_187_726_978; + CursorTy tail_1192 = m_187_726_978 + sizeof(IntTy); + + + switch_1193: + ; + switch (tag_1191) { + + case 0: + { + return 0; + break; + } + + case 1: + { + IntTy sz_189_727_979 = + ((Int64Int64Int64CursorCursorProd *) tail_1192)->field0; + IntTy wildcard__18_190_728_980 = + ((Int64Int64Int64CursorCursorProd *) tail_1192)->field1; + IntTy wildcard__19_191_729_981 = + ((Int64Int64Int64CursorCursorProd *) tail_1192)->field2; + CursorTy wildcard__20_192_730_982 = + ((Int64Int64Int64CursorCursorProd *) tail_1192)->field3; + CursorTy wildcard__21_193_731_983 = + ((Int64Int64Int64CursorCursorProd *) tail_1192)->field4; + + return sz_189_727_979; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1191"); + exit(1); + } + } +} +CursorTy singleL_339(IntTy k1_114_732_984, IntTy x1_115_733_985, + CursorTy t1_116_734_986, CursorTy m_117_735_987) +{ + TagTyPacked tag_1194 = *(TagTyPacked *) m_117_735_987; + CursorTy tail_1195 = m_117_735_987 + sizeof(IntTy); + + + switch_1196: + ; + switch (tag_1194) { + + case 1: + { + IntTy wildcard__123_119_736_988 = + ((Int64Int64Int64CursorCursorProd *) tail_1195)->field0; + IntTy k2_120_737_989 = + ((Int64Int64Int64CursorCursorProd *) tail_1195)->field1; + IntTy x2_121_738_990 = + ((Int64Int64Int64CursorCursorProd *) tail_1195)->field2; + CursorTy t2_122_739_991 = + ((Int64Int64Int64CursorCursorProd *) tail_1195)->field3; + CursorTy t3_123_740_992 = + ((Int64Int64Int64CursorCursorProd *) tail_1195)->field4; + CursorTy fltAppE_894_993 = + bin_338(k1_114_732_984, x1_115_733_985, t1_116_734_986, t2_122_739_991); + + return bin_338(k2_120_737_989, x2_121_738_990, fltAppE_894_993, + t3_123_740_992); + break; + } + + case 0: + { + return empty_337(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1194"); + exit(1); + } + } +} +CursorTy doubleL_340(IntTy k1_85_741_994, IntTy x1_86_742_995, + CursorTy t1_87_743_996, CursorTy m0_88_744_997) +{ + TagTyPacked tag_1197 = *(TagTyPacked *) m0_88_744_997; + CursorTy tail_1198 = m0_88_744_997 + sizeof(IntTy); + + + switch_1199: + ; + switch (tag_1197) { + + case 1: + { + IntTy wildcard__143_90_745_998 = + ((Int64Int64Int64CursorCursorProd *) tail_1198)->field0; + IntTy k2_91_746_999 = + ((Int64Int64Int64CursorCursorProd *) tail_1198)->field1; + IntTy x2_92_747_1000 = + ((Int64Int64Int64CursorCursorProd *) tail_1198)->field2; + CursorTy m1_93_748_1001 = + ((Int64Int64Int64CursorCursorProd *) tail_1198)->field3; + CursorTy t4_94_749_1002 = + ((Int64Int64Int64CursorCursorProd *) tail_1198)->field4; + + return caseFn_688(x1_86_742_995, k1_85_741_994, t1_87_743_996, + m1_93_748_1001, k2_91_746_999, x2_92_747_1000, + t4_94_749_1002); + break; + } + + case 0: + { + return empty_337(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1197"); + exit(1); + } + } +} +CursorTy rotateL_333(IntTy k_139_750_1003, IntTy x_140_751_1004, + CursorTy l_141_752_1005, CursorTy r_142_753_1006) +{ + TagTyPacked tag_1200 = *(TagTyPacked *) r_142_753_1006; + CursorTy tail_1201 = r_142_753_1006 + sizeof(IntTy); + + + switch_1202: + ; + switch (tag_1200) { + + case 1: + { + IntTy wildcard__94_144_754_1007 = + ((Int64Int64Int64CursorCursorProd *) tail_1201)->field0; + IntTy wildcard__95_145_755_1008 = + ((Int64Int64Int64CursorCursorProd *) tail_1201)->field1; + IntTy wildcard__96_146_756_1009 = + ((Int64Int64Int64CursorCursorProd *) tail_1201)->field2; + CursorTy ly_147_757_1010 = + ((Int64Int64Int64CursorCursorProd *) tail_1201)->field3; + CursorTy ry_148_758_1011 = + ((Int64Int64Int64CursorCursorProd *) tail_1201)->field4; + IntTy fltPrm_896_1012 = size_332(ly_147_757_1010); + IntTy fltPrm_898_1013 = ratio(); + IntTy fltPrm_899_1014 = size_332(ry_148_758_1011); + IntTy fltPrm_897_1015 = fltPrm_898_1013 * fltPrm_899_1014; + BoolTy fltIf_895_1016 = fltPrm_896_1012 < fltPrm_897_1015; + + if (fltIf_895_1016) { + return singleL_339(k_139_750_1003, x_140_751_1004, + l_141_752_1005, r_142_753_1006); + } else { + return doubleL_340(k_139_750_1003, x_140_751_1004, + l_141_752_1005, r_142_753_1006); + } + break; + } + + case 0: + { + return empty_337(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1200"); + exit(1); + } + } +} +CursorTy bin_338(IntTy k_124_759_1017, IntTy x_125_760_1018, + CursorTy l_126_761_1019, CursorTy r_127_762_1020) +{ + IntTy fltPrm_902_1021 = size_332(l_126_761_1019); + IntTy fltPrm_903_1022 = size_332(r_127_762_1020); + IntTy fltPrm_901_1023 = fltPrm_902_1021 + fltPrm_903_1022; + IntTy fltPkd_900_1024 = fltPrm_901_1023 + 1; + PtrTy tailift_1203 = ALLOC(sizeof(Int64Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1203)->field0 = 1; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1203)->field1 = + fltPkd_900_1024; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1203)->field2 = + k_124_759_1017; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1203)->field3 = + x_125_760_1018; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1203)->field4 = + l_126_761_1019; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1203)->field5 = + r_127_762_1020; + return tailift_1203; +} +CursorTy singleR_335(IntTy k1_104_763_1025, IntTy x1_105_764_1026, + CursorTy m_106_765_1027, CursorTy t3_107_766_1028) +{ + TagTyPacked tag_1204 = *(TagTyPacked *) m_106_765_1027; + CursorTy tail_1205 = m_106_765_1027 + sizeof(IntTy); + + + switch_1206: + ; + switch (tag_1204) { + + case 1: + { + IntTy wildcard__133_109_767_1029 = + ((Int64Int64Int64CursorCursorProd *) tail_1205)->field0; + IntTy k2_110_768_1030 = + ((Int64Int64Int64CursorCursorProd *) tail_1205)->field1; + IntTy x2_111_769_1031 = + ((Int64Int64Int64CursorCursorProd *) tail_1205)->field2; + CursorTy t1_112_770_1032 = + ((Int64Int64Int64CursorCursorProd *) tail_1205)->field3; + CursorTy t2_113_771_1033 = + ((Int64Int64Int64CursorCursorProd *) tail_1205)->field4; + CursorTy fltAppE_904_1034 = + bin_338(k1_104_763_1025, x1_105_764_1026, t2_113_771_1033, t3_107_766_1028); + + return bin_338(k2_110_768_1030, x2_111_769_1031, t1_112_770_1032, + fltAppE_904_1034); + break; + } + + case 0: + { + return empty_337(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1204"); + exit(1); + } + } +} +CursorTy doubleR_336(IntTy k1_70_772_1035, IntTy x1_71_773_1036, + CursorTy m0_72_774_1037, CursorTy t4_73_775_1038) +{ + TagTyPacked tag_1207 = *(TagTyPacked *) m0_72_774_1037; + CursorTy tail_1208 = m0_72_774_1037 + sizeof(IntTy); + + + switch_1209: + ; + switch (tag_1207) { + + case 1: + { + IntTy wildcard__167_75_776_1039 = + ((Int64Int64Int64CursorCursorProd *) tail_1208)->field0; + IntTy k2_76_777_1040 = + ((Int64Int64Int64CursorCursorProd *) tail_1208)->field1; + IntTy x2_77_778_1041 = + ((Int64Int64Int64CursorCursorProd *) tail_1208)->field2; + CursorTy t1_78_779_1042 = + ((Int64Int64Int64CursorCursorProd *) tail_1208)->field3; + CursorTy m1_79_780_1043 = + ((Int64Int64Int64CursorCursorProd *) tail_1208)->field4; + + return caseFn_696(x1_71_773_1036, k1_70_772_1035, t4_73_775_1038, + m1_79_780_1043, k2_76_777_1040, x2_77_778_1041, + t1_78_779_1042); + break; + } + + case 0: + { + return empty_337(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1207"); + exit(1); + } + } +} +CursorTy empty_337() +{ + PtrTy tailift_1210 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) tailift_1210)->field0 = 0; + return tailift_1210; +} +CursorTy rotateR_334(IntTy k_129_781_1044, IntTy x_130_782_1045, + CursorTy l_131_783_1046, CursorTy r_132_784_1047) +{ + TagTyPacked tag_1211 = *(TagTyPacked *) l_131_783_1046; + CursorTy tail_1212 = l_131_783_1046 + sizeof(IntTy); + + + switch_1213: + ; + switch (tag_1211) { + + case 1: + { + IntTy wildcard__106_134_785_1048 = + ((Int64Int64Int64CursorCursorProd *) tail_1212)->field0; + IntTy wildcard__107_135_786_1049 = + ((Int64Int64Int64CursorCursorProd *) tail_1212)->field1; + IntTy wildcard__108_136_787_1050 = + ((Int64Int64Int64CursorCursorProd *) tail_1212)->field2; + CursorTy ly_137_788_1051 = + ((Int64Int64Int64CursorCursorProd *) tail_1212)->field3; + CursorTy ry_138_789_1052 = + ((Int64Int64Int64CursorCursorProd *) tail_1212)->field4; + IntTy fltPrm_906_1053 = size_332(ry_138_789_1052); + IntTy fltPrm_908_1054 = ratio(); + IntTy fltPrm_909_1055 = size_332(ly_137_788_1051); + IntTy fltPrm_907_1056 = fltPrm_908_1054 * fltPrm_909_1055; + BoolTy fltIf_905_1057 = fltPrm_906_1053 < fltPrm_907_1056; + + if (fltIf_905_1057) { + return singleR_335(k_129_781_1044, x_130_782_1045, + l_131_783_1046, r_132_784_1047); + } else { + return doubleR_336(k_129_781_1044, x_130_782_1045, + l_131_783_1046, r_132_784_1047); + } + break; + } + + case 0: + { + return empty_337(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1211"); + exit(1); + } + } +} +CursorTy balance_331(IntTy k_149_790_1058, IntTy x_150_791_1059, + CursorTy l_151_792_1060, CursorTy r_152_793_1061) +{ + IntTy fltPrm_912_1062 = size_332(l_151_792_1060); + IntTy fltPrm_913_1063 = size_332(r_152_793_1061); + IntTy fltPrm_911_1064 = fltPrm_912_1062 + fltPrm_913_1063; + BoolTy fltIf_910_1065 = fltPrm_911_1064 <= 1; + + if (fltIf_910_1065) { + IntTy fltPrm_915_1066 = size_332(l_151_792_1060); + IntTy fltPrm_916_1067 = size_332(r_152_793_1061); + IntTy fltPkd_914_1068 = fltPrm_915_1066 + fltPrm_916_1067; + PtrTy tailift_1214 = + ALLOC(sizeof(Int64Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1214)->field0 = 1; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1214)->field1 = + fltPkd_914_1068; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1214)->field2 = + k_149_790_1058; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1214)->field3 = + x_150_791_1059; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1214)->field4 = + l_151_792_1060; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1214)->field5 = + r_152_793_1061; + return tailift_1214; + } else { + IntTy fltPrm_918_1069 = size_332(r_152_793_1061); + IntTy fltPrm_920_1070 = delta(); + IntTy fltPrm_921_1071 = size_332(l_151_792_1060); + IntTy fltPrm_919_1072 = fltPrm_920_1070 * fltPrm_921_1071; + BoolTy fltIf_917_1073 = fltPrm_918_1069 >= fltPrm_919_1072; + + if (fltIf_917_1073) { + return rotateL_333(k_149_790_1058, x_150_791_1059, l_151_792_1060, + r_152_793_1061); + } else { + IntTy fltPrm_923_1074 = size_332(l_151_792_1060); + IntTy fltPrm_925_1075 = delta(); + IntTy fltPrm_926_1076 = size_332(r_152_793_1061); + IntTy fltPrm_924_1077 = fltPrm_925_1075 * fltPrm_926_1076; + BoolTy fltIf_922_1078 = fltPrm_923_1074 >= fltPrm_924_1077; + + if (fltIf_922_1078) { + return rotateR_334(k_149_790_1058, x_150_791_1059, + l_151_792_1060, r_152_793_1061); + } else { + IntTy fltPrm_928_1079 = size_332(l_151_792_1060); + IntTy fltPrm_929_1080 = size_332(r_152_793_1061); + IntTy fltPkd_927_1081 = fltPrm_928_1079 + fltPrm_929_1080; + PtrTy tailift_1215 = + ALLOC(sizeof(Int64Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1215)->field0 = + 1; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1215)->field1 = + fltPkd_927_1081; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1215)->field2 = + k_149_790_1058; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1215)->field3 = + x_150_791_1059; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1215)->field4 = + l_151_792_1060; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1215)->field5 = + r_152_793_1061; + return tailift_1215; + } + } + } +} +CursorTy singleton_328(IntTy k_66_794_1082, IntTy x_67_795_1083) +{ + PtrTy fltPkd_930_1084 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_930_1084)->field0 = 0; + + PtrTy fltPkd_931_1085 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_931_1085)->field0 = 0; + + PtrTy tailift_1216 = ALLOC(sizeof(Int64Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1216)->field0 = 1; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1216)->field1 = 1; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1216)->field2 = + k_66_794_1082; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1216)->field3 = + x_67_795_1083; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1216)->field4 = + fltPkd_930_1084; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1216)->field5 = + fltPkd_931_1085; + return tailift_1216; +} +CursorTy insert_330(IntTy kx_57_796_1086, IntTy x_58_797_1087, + CursorTy m_59_798_1088) +{ + TagTyPacked tag_1217 = *(TagTyPacked *) m_59_798_1088; + CursorTy tail_1218 = m_59_798_1088 + sizeof(IntTy); + + + switch_1220: + ; + switch (tag_1217) { + + case 0: + { + return singleton_328(kx_57_796_1086, x_58_797_1087); + break; + } + + case 1: + { + IntTy sz_61_799_1089 = + ((Int64Int64Int64CursorCursorProd *) tail_1218)->field0; + IntTy k_62_800_1090 = + ((Int64Int64Int64CursorCursorProd *) tail_1218)->field1; + IntTy v_63_801_1091 = + ((Int64Int64Int64CursorCursorProd *) tail_1218)->field2; + CursorTy l_64_802_1092 = + ((Int64Int64Int64CursorCursorProd *) tail_1218)->field3; + CursorTy r_65_803_1093 = + ((Int64Int64Int64CursorCursorProd *) tail_1218)->field4; + BoolTy fltIf_932_1094 = kx_57_796_1086 == k_62_800_1090; + + if (fltIf_932_1094) { + PtrTy tailift_1219 = + ALLOC(sizeof(Int64Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1219)->field0 = + 1; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1219)->field1 = + sz_61_799_1089; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1219)->field2 = + k_62_800_1090; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1219)->field3 = + x_58_797_1087; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1219)->field4 = + l_64_802_1092; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1219)->field5 = + r_65_803_1093; + return tailift_1219; + } else { + BoolTy fltIf_933_1095 = kx_57_796_1086 <= k_62_800_1090; + + if (fltIf_933_1095) { + CursorTy fltAppE_934_1096 = + insert_330(kx_57_796_1086, x_58_797_1087, l_64_802_1092); + + return balance_331(k_62_800_1090, v_63_801_1091, + fltAppE_934_1096, r_65_803_1093); + } else { + CursorTy fltAppE_935_1097 = + insert_330(kx_57_796_1086, x_58_797_1087, r_65_803_1093); + + return balance_331(k_62_800_1090, v_63_801_1091, + l_64_802_1092, fltAppE_935_1097); + } + } + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1217"); + exit(1); + } + } +} +CursorTy _copy_without_ptrs_Map_v_329(CursorTy arg_646_804_1098) +{ + TagTyPacked tag_1221 = *(TagTyPacked *) arg_646_804_1098; + CursorTy tail_1222 = arg_646_804_1098 + sizeof(IntTy); + + + switch_1225: + ; + switch (tag_1221) { + + case 0: + { + PtrTy tailift_1223 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) tailift_1223)->field0 = 0; + return tailift_1223; + break; + } + + case 1: + { + IntTy x_647_805_1099 = + ((Int64Int64Int64CursorCursorProd *) tail_1222)->field0; + IntTy x_648_806_1100 = + ((Int64Int64Int64CursorCursorProd *) tail_1222)->field1; + IntTy x_649_807_1101 = + ((Int64Int64Int64CursorCursorProd *) tail_1222)->field2; + CursorTy x_650_808_1102 = + ((Int64Int64Int64CursorCursorProd *) tail_1222)->field3; + CursorTy x_651_809_1103 = + ((Int64Int64Int64CursorCursorProd *) tail_1222)->field4; + CursorTy y_655_813_1107 = + _copy_without_ptrs_Map_v_329(x_650_808_1102); + CursorTy y_656_814_1108 = + _copy_without_ptrs_Map_v_329(x_651_809_1103); + PtrTy tailift_1224 = + ALLOC(sizeof(Int64Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1224)->field0 = 1; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1224)->field1 = + x_647_805_1099; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1224)->field2 = + x_648_806_1100; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1224)->field3 = + x_649_807_1101; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1224)->field4 = + y_655_813_1107; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1224)->field5 = + y_656_814_1108; + return tailift_1224; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1221"); + exit(1); + } + } +} +CursorTy _copy_Map_v_329(CursorTy arg_635_815_1109) +{ + TagTyPacked tag_1226 = *(TagTyPacked *) arg_635_815_1109; + CursorTy tail_1227 = arg_635_815_1109 + sizeof(IntTy); + + + switch_1230: + ; + switch (tag_1226) { + + case 0: + { + PtrTy tailift_1228 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) tailift_1228)->field0 = 0; + return tailift_1228; + break; + } + + case 1: + { + IntTy x_636_816_1110 = + ((Int64Int64Int64CursorCursorProd *) tail_1227)->field0; + IntTy x_637_817_1111 = + ((Int64Int64Int64CursorCursorProd *) tail_1227)->field1; + IntTy x_638_818_1112 = + ((Int64Int64Int64CursorCursorProd *) tail_1227)->field2; + CursorTy x_639_819_1113 = + ((Int64Int64Int64CursorCursorProd *) tail_1227)->field3; + CursorTy x_640_820_1114 = + ((Int64Int64Int64CursorCursorProd *) tail_1227)->field4; + CursorTy y_644_824_1118 = _copy_Map_v_329(x_639_819_1113); + CursorTy y_645_825_1119 = _copy_Map_v_329(x_640_820_1114); + PtrTy tailift_1229 = + ALLOC(sizeof(Int64Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1229)->field0 = 1; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1229)->field1 = + x_636_816_1110; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1229)->field2 = + x_637_817_1111; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1229)->field3 = + x_638_818_1112; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1229)->field4 = + y_644_824_1118; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1229)->field5 = + y_645_825_1119; + return tailift_1229; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1226"); + exit(1); + } + } +} +unsigned char _traverse_Map_v_329(CursorTy arg_657_826_1120) +{ + TagTyPacked tag_1231 = *(TagTyPacked *) arg_657_826_1120; + CursorTy tail_1232 = arg_657_826_1120 + sizeof(IntTy); + + + switch_1233: + ; + switch (tag_1231) { + + case 0: + { + return 0; + break; + } + + case 1: + { + IntTy x_658_827_1121 = + ((Int64Int64Int64CursorCursorProd *) tail_1232)->field0; + IntTy x_659_828_1122 = + ((Int64Int64Int64CursorCursorProd *) tail_1232)->field1; + IntTy x_660_829_1123 = + ((Int64Int64Int64CursorCursorProd *) tail_1232)->field2; + CursorTy x_661_830_1124 = + ((Int64Int64Int64CursorCursorProd *) tail_1232)->field3; + CursorTy x_662_831_1125 = + ((Int64Int64Int64CursorCursorProd *) tail_1232)->field4; + unsigned char y_666_832_1126 = _traverse_Map_v_329(x_661_830_1124); + unsigned char y_667_833_1127 = _traverse_Map_v_329(x_662_831_1125); + + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1231"); + exit(1); + } + } +} +unsigned char _print_Map_v_329(CursorTy arg_668_834_1128) +{ + TagTyPacked tag_1234 = *(TagTyPacked *) arg_668_834_1128; + CursorTy tail_1235 = arg_668_834_1128 + sizeof(IntTy); + + + switch_1236: + ; + switch (tag_1234) { + + case 0: + { + unsigned char wildcard_669_835_1129 = print_symbol(1179); + unsigned char wildcard_670_836_1130 = print_symbol(1178); + + return 0; + break; + } + + case 1: + { + IntTy x_671_837_1131 = + ((Int64Int64Int64CursorCursorProd *) tail_1235)->field0; + IntTy x_672_838_1132 = + ((Int64Int64Int64CursorCursorProd *) tail_1235)->field1; + IntTy x_673_839_1133 = + ((Int64Int64Int64CursorCursorProd *) tail_1235)->field2; + CursorTy x_674_840_1134 = + ((Int64Int64Int64CursorCursorProd *) tail_1235)->field3; + CursorTy x_675_841_1135 = + ((Int64Int64Int64CursorCursorProd *) tail_1235)->field4; + unsigned char wildcard_681_842_1136 = print_symbol(1180); + unsigned char wildcard_687_843_1137 = print_symbol(1181); + unsigned char y_676_844_1138 = printf("%lld", x_671_837_1131); + unsigned char wildcard_686_845_1139 = print_symbol(1181); + unsigned char y_677_846_1140 = printf("%lld", x_672_838_1132); + unsigned char wildcard_685_847_1141 = print_symbol(1181); + unsigned char y_678_848_1142 = printf("%lld", x_673_839_1133); + unsigned char wildcard_684_849_1143 = print_symbol(1181); + unsigned char y_679_850_1144 = _print_Map_v_329(x_674_840_1134); + unsigned char wildcard_683_851_1145 = print_symbol(1181); + unsigned char y_680_852_1146 = _print_Map_v_329(x_675_841_1135); + unsigned char wildcard_682_853_1147 = print_symbol(1178); + + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1234"); + exit(1); + } + } +} +CursorTy caseFn_688(IntTy x1_86_689_854_1148, IntTy k1_85_690_855_1149, + CursorTy t1_87_691_856_1150, CursorTy m1_93_692_857_1151, + IntTy k2_91_693_858_1152, IntTy x2_92_694_859_1153, + CursorTy t4_94_695_860_1154) +{ + TagTyPacked tag_1237 = *(TagTyPacked *) m1_93_692_857_1151; + CursorTy tail_1238 = m1_93_692_857_1151 + sizeof(IntTy); + + + switch_1239: + ; + switch (tag_1237) { + + case 1: + { + IntTy wildcard__144_95_861_1155 = + ((Int64Int64Int64CursorCursorProd *) tail_1238)->field0; + IntTy k3_96_862_1156 = + ((Int64Int64Int64CursorCursorProd *) tail_1238)->field1; + IntTy x3_97_863_1157 = + ((Int64Int64Int64CursorCursorProd *) tail_1238)->field2; + CursorTy t2_98_864_1158 = + ((Int64Int64Int64CursorCursorProd *) tail_1238)->field3; + CursorTy t3_99_865_1159 = + ((Int64Int64Int64CursorCursorProd *) tail_1238)->field4; + CursorTy fltAppE_936_1160 = + bin_338(k1_85_690_855_1149, x1_86_689_854_1148, t1_87_691_856_1150, t2_98_864_1158); + CursorTy fltAppE_937_1161 = + bin_338(k2_91_693_858_1152, x2_92_694_859_1153, t3_99_865_1159, t4_94_695_860_1154); + + return bin_338(k3_96_862_1156, x3_97_863_1157, fltAppE_936_1160, + fltAppE_937_1161); + break; + } + + case 0: + { + return empty_337(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1237"); + exit(1); + } + } +} +CursorTy caseFn_696(IntTy x1_71_697_866_1162, IntTy k1_70_698_867_1163, + CursorTy t4_73_699_868_1164, CursorTy m1_79_700_869_1165, + IntTy k2_76_701_870_1166, IntTy x2_77_702_871_1167, + CursorTy t1_78_703_872_1168) +{ + TagTyPacked tag_1240 = *(TagTyPacked *) m1_79_700_869_1165; + CursorTy tail_1241 = m1_79_700_869_1165 + sizeof(IntTy); + + + switch_1242: + ; + switch (tag_1240) { + + case 1: + { + IntTy wildcard__168_80_873_1169 = + ((Int64Int64Int64CursorCursorProd *) tail_1241)->field0; + IntTy k3_81_874_1170 = + ((Int64Int64Int64CursorCursorProd *) tail_1241)->field1; + IntTy x3_82_875_1171 = + ((Int64Int64Int64CursorCursorProd *) tail_1241)->field2; + CursorTy t2_83_876_1172 = + ((Int64Int64Int64CursorCursorProd *) tail_1241)->field3; + CursorTy t3_84_877_1173 = + ((Int64Int64Int64CursorCursorProd *) tail_1241)->field4; + CursorTy fltAppE_938_1174 = + bin_338(k2_76_701_870_1166, x2_77_702_871_1167, t1_78_703_872_1168, t2_83_876_1172); + CursorTy fltAppE_939_1175 = + bin_338(k1_70_698_867_1163, x1_71_697_866_1162, t3_84_877_1173, t4_73_699_868_1164); + + return bin_338(k3_81_874_1170, x3_82_875_1171, fltAppE_938_1174, + fltAppE_939_1175); + break; + } + + case 0: + { + return empty_337(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1240"); + exit(1); + } + } +} +int __main_expr() +{ + add_symbol(1178, ")"); + add_symbol(1179, "(Tip_v_329"); + add_symbol(1180, "(Bin_v_329"); + add_symbol(1181, " "); + add_symbol(1182, "\n"); + + CursorTy fltAppE_878_940 = singleton_328(0, 0); + CursorTy m_33_704_941 = build(0, 512, fltAppE_878_940); + IntTy timed_1176; + VectorTy *times_3 = vector_alloc(global_iters_param, sizeof(double)); + struct timespec begin_timed_1176; + struct timespec end_timed_1176; + + for (long long iters_timed_1176 = 0; iters_timed_1176 < global_iters_param; + iters_timed_1176++) { + if (iters_timed_1176 != global_iters_param - 1) + save_alloc_state(); + clock_gettime(CLOCK_MONOTONIC_RAW, &begin_timed_1176); + + IntTy timed_1176hack = sumRight(m_33_704_941); + + timed_1176 = timed_1176hack; + clock_gettime(CLOCK_MONOTONIC_RAW, &end_timed_1176); + if (iters_timed_1176 != global_iters_param - 1) + restore_alloc_state(); + + double itertime_0 = difftimespecs(&begin_timed_1176, &end_timed_1176); + + vector_inplace_update(times_3, iters_timed_1176, &itertime_0); + } + vector_inplace_sort(times_3, compare_doubles); + + double *tmp_4 = (double *) vector_nth(times_3, global_iters_param / 2); + double selftimed_2 = *tmp_4; + double batchtime_1 = sum_timing_array(times_3); + + print_timing_array(times_3); + printf("ITERS: %lld\n", global_iters_param); + printf("SIZE: %lld\n", global_size_param); + printf("BATCHTIME: %e\n", batchtime_1); + printf("SELFTIMED: %e\n", selftimed_2); + + unsigned char wildcard__27_35_706_943 = printf("%lld", timed_1176); + unsigned char wildcard__25_36_707_944 = print_symbol(1182); + IntTy timed_1177; + VectorTy *times_8 = vector_alloc(global_iters_param, sizeof(double)); + struct timespec begin_timed_1177; + struct timespec end_timed_1177; + + for (long long iters_timed_1177 = 0; iters_timed_1177 < global_iters_param; + iters_timed_1177++) { + if (iters_timed_1177 != global_iters_param - 1) + save_alloc_state(); + clock_gettime(CLOCK_MONOTONIC_RAW, &begin_timed_1177); + + IntTy timed_1177hack = sumLeft(m_33_704_941); + + timed_1177 = timed_1177hack; + clock_gettime(CLOCK_MONOTONIC_RAW, &end_timed_1177); + if (iters_timed_1177 != global_iters_param - 1) + restore_alloc_state(); + + double itertime_5 = difftimespecs(&begin_timed_1177, &end_timed_1177); + + vector_inplace_update(times_8, iters_timed_1177, &itertime_5); + } + vector_inplace_sort(times_8, compare_doubles); + + double *tmp_9 = (double *) vector_nth(times_8, global_iters_param / 2); + double selftimed_7 = *tmp_9; + double batchtime_6 = sum_timing_array(times_8); + + print_timing_array(times_8); + printf("ITERS: %lld\n", global_iters_param); + printf("SIZE: %lld\n", global_size_param); + printf("BATCHTIME: %e\n", batchtime_6); + printf("SELFTIMED: %e\n", selftimed_7); + + unsigned char wildcard__21_38_709_946 = printf("%lld", timed_1177); + unsigned char wildcard__19_39_710_947 = print_symbol(1182); + + printf("'#()"); + printf("\n"); + free_symtable(); + return 0; +} \ No newline at end of file diff --git a/benchmarks/Layouts/_LeftAndRight.hs b/benchmarks/Layouts/_LeftAndRight.hs new file mode 100644 index 000000000..5f659efa6 --- /dev/null +++ b/benchmarks/Layouts/_LeftAndRight.hs @@ -0,0 +1,34 @@ + +module LeftAndRight where +import Common +import Map + +sumRight :: Map Int -> Int +sumRight m = + case m of + Tip -> 0 + Bin _ _ v l r -> sumRight(r) + v + sumRight(l) + +sumLeft :: Map Int -> Int +sumLeft m = + case m of + Tip -> 0 + Bin _ _ v l r -> sumLeft(l) + v + sumLeft(r) + + +build :: Int -> Int -> Map Int -> Map Int +build x sz m = + if (sz == 0) then m + else (build (x - sz/2) (sz/2) (build (x + sz/2) (sz/2) (insert x x m))) + +gibbon_main = + let m = (build 0 512 (singleton 0 0)) + --_ = printsym (quote "SUM RIGHT: ") + s0 = iterate (sumRight m) + _ = printint (s0) + _ = printsym (quote "\n") + --_ = printsym (quote "SUM LEFT: ") + s1 = iterate (sumLeft m) + _ = printint (s1) + _ = printsym (quote "\n") + in () \ No newline at end of file diff --git a/benchmarks/Layouts/_Right.c b/benchmarks/Layouts/_Right.c new file mode 100644 index 000000000..49c807d0e --- /dev/null +++ b/benchmarks/Layouts/_Right.c @@ -0,0 +1,2443 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// #include +#ifdef _WIN64 +#include +#endif +#include +#include +#include // For va_start etc +#include +#include +#include +#include +#ifdef _POINTER +#include +#endif +#ifdef _PARALLEL +#include +#include +#endif + +#define KB 1024lu +#define MB (KB * 1000lu) +#define GB (MB * 1000lu) + +#define REDIRECTION_TAG 255 +#define INDIRECTION_TAG 254 + +// Initial size of BigInfinite buffers +static long long global_init_biginf_buf_size = (4 * GB); + +// Initial size of Infinite buffers +static long long global_init_inf_buf_size = 1 * KB; + +// Maximum size of a chunk, see GitHub #110. +static long long global_inf_buf_max_chunk_size = 1 * GB; + +static long long global_size_param = 1; +static long long global_iters_param = 1; + +static char* global_benchfile_param = NULL; +static char* global_arrayfile_param = NULL; +// Number of lines in the arrayfile +static long long global_arrayfile_length_param = -1; + +// Sequential for now: +static const int num_workers = 1; + +// Count the number of regions allocated. +static long long global_region_count = 0; +static bool global_region_count_flag = false; + +#ifdef _PARALLEL +static inline void bump_global_region_count() { + __atomic_add_fetch(&global_region_count, 1, __ATOMIC_SEQ_CST); + return; +} +#else +static inline void bump_global_region_count() { + global_region_count++; + return; +} +#endif + +static inline void print_global_region_count() { + printf("REGION_COUNT: %lld\n", global_region_count); + return; +} + +#define REDIRECTION_NODE_SIZE 9 +#define MAX(a,b) (((a)>(b))?(a):(b)) +#define MIN(a,b) (((a)<(b))?(a):(b)) + +// https://www.cprogramming.com/snippets/source-code/find-the-number-of-cpu-cores-for-windows-mac-or-linux +static int get_num_processors() { +#ifdef _WIN64 + SYSTEM_INFO sysinfo; + GetSystemInfo(&sysinfo); + return sysinfo.dwNumberOfProcessors; +#else + return sysconf(_SC_NPROCESSORS_ONLN); +#endif +} + +// Requires -std=gnu11 +int dbgprintf(const char *format, ...) { + int code = 0; + va_list args; + va_start(args, format); +#ifdef _DEBUG + code = vprintf(format, args); +#endif + va_end(args); + return code; +} + + +// ----------------------------------------------------------------------------- +// Allocators +// ----------------------------------------------------------------------------- + + +// ------------------------------------- +// Bump allocation for linked-lists +// ------------------------------------- + + +#ifdef _BUMPALLOC +// #define _DEBUG +#warning "Using bump allocator." + +__thread char* bumpalloc_heap_ptr = (char*)NULL; +__thread char* bumpalloc_heap_ptr_end = (char*)NULL; + +char* saved_heap_ptr_stack[100]; +int num_saved_heap_ptr = 0; + +// For simplicity just use a single large slab: +static inline void INITBUMPALLOC() { + bumpalloc_heap_ptr = (char*)malloc(global_init_biginf_buf_size); + bumpalloc_heap_ptr_end = bumpalloc_heap_ptr + global_init_biginf_buf_size; +#ifdef _DEBUG + printf("Arena size for bump alloc: %lld\n", global_init_biginf_buf_size); + printf("BUMPALLOC/INITBUMPALLOC DONE: heap_ptr = %p\n", bumpalloc_heap_ptr); +#endif +} + +static inline void* BUMPALLOC(long long n) { + if (! bumpalloc_heap_ptr) { + INITBUMPALLOC(); + } + if (bumpalloc_heap_ptr + n < bumpalloc_heap_ptr_end) { + char* old= bumpalloc_heap_ptr; + bumpalloc_heap_ptr += n; + return old; + } else { + fprintf(stderr, "Warning: bump allocator ran out of memory."); + exit(1); + } +} + +// Snapshot the current heap pointer value across all threads. +void save_alloc_state() { + dbgprintf("Saving(%p): pos %d", heap_ptr, num_saved_heap_ptr); + saved_heap_ptr_stack[num_saved_heap_ptr] = heap_ptr; + num_saved_heap_ptr++; + dbgprintf("\n"); +} + +void restore_alloc_state() { + if(num_saved_heap_ptr <= 0) { + fprintf(stderr, "Bad call to restore_alloc_state! Saved stack empty!\ne"); + exit(1); + } + num_saved_heap_ptr--; + dbgprintf("Restoring(%p): pos %d, discarding %p", + saved_heap_ptr_stack[num_saved_heap_ptr], num_saved_heap_ptr, bumpalloc_heap_ptr); + bumpalloc_heap_ptr = saved_heap_ptr_stack[num_saved_heap_ptr]; +} + + +#else +// Regular malloc mode: +void INITBUMPALLOC() {} +void save_alloc_state() {} +void restore_alloc_state() {} + +#define BUMPALLOC(n) malloc(n) + +#endif // BUMPALLOC + + +// ------------------------------------- +// ALLOC and ALLOC_PACKED macros +// ------------------------------------- + + +/* + +If parallelism is enabled, we always use a malloc based allocator +since Boehm GC is not thread-safe in its default configuration. It can be +made thread-safe by building it with appropriate flags, but we don't do that. +Presently, all parallel pointer-based programs will leak memory. + +*/ + +#ifdef _PARALLEL +#define ALLOC(n) malloc(n) +#define ALLOC_PACKED_BIG(n) malloc(n) +char *ALLOC_COUNTED(size_t size) { + bump_global_region_count(); + return ALLOC(size); +} +#else + #ifdef _POINTER +#define ALLOC(n) GC_MALLOC(n) +#define ALLOC_PACKED_BIG(n) GC_MALLOC(n) +char *ALLOC_COUNTED(size_t size) { + bump_global_region_count(); + return GC_MALLOC(size); +} + #else +#define ALLOC(n) malloc(n) +#define ALLOC_PACKED_BIG(n) malloc(n) +char *ALLOC_COUNTED(size_t size) { + bump_global_region_count(); + return ALLOC(size); +} + #endif // _POINTER +#endif // _PARALLEL + + +// Could try alloca() here. Better yet, we could keep our own, +// separate stack and insert our own code to restore the pointer +// before any function that (may have) called ALLOC_SCOPED returns. + +// #define ALLOC_SCOPED() alloca(1024) +#define ALLOC_SCOPED(n) alloca(n) +// #define ALLOC_SCOPED() alloc_scoped() + +// Stack allocation is either too small or blows our stack. +// We need a way to make a giant stack if we want to use alloca. +// #define ALLOC_SCOPED() ALLOC(global_init_biginf_buf_size) + +// Our global pointer. No parallelism. +// static char* stack_scoped_region; +// char* alloc_scoped() { return stack_scoped_region; } + + + +// ------------------------------------- +// Basic types +// ------------------------------------- + +// Must be consistent with sizeOfTy defined in Gibbon.Language.Syntax. + +typedef unsigned char TagTyPacked; +typedef unsigned char TagTyBoxed; +typedef long long IntTy; +typedef char CharTy; +typedef float FloatTy; +typedef unsigned long long SymTy; +typedef bool BoolTy; +typedef char* PtrTy; +typedef char* CursorTy; + +// ------------------------------------- +// Arenas and dictionaries +// ------------------------------------- + +typedef struct mem_arena { + int ind; + char* mem; // TODO(vollmerm): make this a list of chunks? + void* reflist; +} mem_arena_t; + +typedef mem_arena_t* ArenaTy; + +ArenaTy alloc_arena() { + ArenaTy ar = ALLOC(sizeof(mem_arena_t)); + ar->ind = 0; + ar->mem = malloc(global_inf_buf_max_chunk_size); + ar->reflist = 0; + return ar; +} + +void free_arena(ArenaTy ar) { + free(ar->mem); + // TODO(vollmerm): free everything in ar->reflist + free(ar); +} + +CursorTy extend_arena(ArenaTy ar, int size) { + CursorTy ret = ar->mem + ar->ind; + ar->ind += size; + return ret; +} + +typedef struct dict_item { + struct dict_item * next; + int key; + void * ptrval; +} dict_item_t; + +dict_item_t * dict_alloc(ArenaTy ar) { + return (dict_item_t *) extend_arena(ar, sizeof(dict_item_t)); // ALLOC(sizeof(dict_item_t)); +} + +dict_item_t *dict_insert_ptr(ArenaTy ar, dict_item_t *ptr, SymTy key, PtrTy val) { + dict_item_t *ret = dict_alloc(ar); + ret->key = key; + ret->ptrval = val; + ret->next = ptr; + return ret; +} + +PtrTy dict_lookup_ptr(dict_item_t *ptr, SymTy key) { + while (ptr != 0) { + if (ptr->key == key) { + return ptr->ptrval; + } else { + ptr = ptr->next; + } + } + printf("Error, key %lld not found!\n",key); + exit(1); +} + +// ------------------------------------- +// Sets +// ------------------------------------- + + +struct set_elem { + int val; + UT_hash_handle hh; +}; + +typedef struct set_elem* SymSetTy; + +SymSetTy empty_set() { + return NULL; +} + +SymSetTy insert_set(SymSetTy set, int sym) { + SymSetTy s; + HASH_FIND_INT(set, &sym, s); /* sym already in the hash? */ + if (s==NULL) { + s = malloc(sizeof(struct set_elem)); + s->val = sym; + HASH_ADD_INT(set,val,s); + } + return set; +} + +BoolTy contains_set(SymSetTy set, int sym) { + SymSetTy s; + HASH_FIND_INT(set, &sym, s); + return (s!=NULL); +} + +// ------------------------------------- +// Sym Hash +// ------------------------------------- + +struct sym_hash_elem { + int key; + int val; + UT_hash_handle hh; +}; + +typedef struct sym_hash_elem* SymHashTy; + +typedef struct sym_hash_elem* IntHashTy; + +SymHashTy empty_hash() { + return NULL; +} + +SymHashTy insert_hash(SymHashTy hash, int k, int v) { + SymHashTy s; + // NOTE: not checking for duplicates! + // s = malloc(sizeof(struct sym_hash_elem)); + s = ALLOC(sizeof(struct sym_hash_elem)); + s->val = v; + s->key = k; + HASH_ADD_INT(hash,key,s); + + return hash; +} + +IntTy lookup_hash(SymHashTy hash, int k) { + SymHashTy s; + HASH_FIND_INT(hash,&k,s); + if (s==NULL) { + return k; // NOTE: return original key if val not found + // TODO(vollmerm): come up with something better to do here + } else { + return s->val; + } +} + +BoolTy contains_hash(SymHashTy hash, int sym) { + SymHashTy s; + HASH_FIND_INT(hash,&sym,s); + return (s!=NULL); +} + +// ------------------------------------- +// Helpers +// ------------------------------------- + +char* read_benchfile_param() { + if (global_benchfile_param == NULL) { + fprintf(stderr, "read_benchfile_param: benchmark input file was not set! Set using --bench-input.\n"); + exit(1); + } else + return global_benchfile_param; +} + +char* read_arrayfile_param() { + if (global_arrayfile_param == NULL) { + fprintf(stderr, "read_arrayfile_param: array input file was not set! Set using --array-input.\n"); + exit(1); + } else + return global_arrayfile_param; +} + +IntTy read_arrayfile_length_param() { + if (global_arrayfile_length_param == -1) { + fprintf(stderr, "read_arrayfile_length_param: array input file length was not set! Set using --array-input-length.\n"); + exit(1); + } else + return global_arrayfile_length_param; +} + + +// fun fact: __ prefix is actually reserved and this is an undefined behavior. +// These functions must be provided by the code generator. +int __main_expr(); + + +void show_usage(char** argv) +{ + printf("\n"); + printf("This binary was generated by the Gibbon compiler.\n"); + printf("\n"); + printf("Usage: %s [OPTS] [size] [iters]\n", argv[0]); + + printf("\n"); + printf("Options:\n"); + printf(" --buffer-size Set the buffer size (default %lld).\n", global_init_biginf_buf_size); + printf(" --bench-input Set the input file read for benchmarking. Applies only\n"); + printf(" IF the program was *compiled* with --bench-fun. \n"); + return; +} + +double avg(const double* arr, int n) +{ + double sum = 0.0; + for(int i=0; itv_sec - t0->tv_sec) + + ((double)(t1->tv_nsec - t0->tv_nsec) / 1000000000.0); +} + +int compare_doubles(const void *a, const void *b) +{ + const double *da = (const double *) a; + const double *db = (const double *) b; + return (*da > *db) - (*da < *db); +} + +// Exponentiation +IntTy expll(IntTy base, IntTy pow) { + if (base == 2) { + return (1 << pow); + } else { + IntTy i, result = 1; + for (i = 0; i < pow; i++) + result *= base; + return result; + } + } + +// ------------------------------------- +// Symbol table +// ------------------------------------- + +#define global_max_symbol_len 256 + +// Invariant: should always be equal to max(sym_table_keys) +static SymTy global_gensym_counter = 0; + +// Its value is updated by the flags parser. +static char *global_bench_prog_param; + +static SymTy newline_symbol = -1; +static SymTy space_symbol = -1; +static SymTy comma_symbol = -1; +static SymTy leftparen_symbol = -1; +static SymTy rightparen_symbol = -1; + +typedef struct SymTable_elem { + SymTy idx; /* key */ + char value[global_max_symbol_len]; + UT_hash_handle hh; /* makes this structure hashable */ +} SymTable_elem; + +// important! initialize to NULL +SymTable_elem *global_sym_table = NULL; + +void add_symbol(SymTy idx, char *value) { + struct SymTable_elem *s; + s = ALLOC(sizeof(struct SymTable_elem)); + s->idx = idx; + strcpy(s->value, value); + HASH_ADD(hh, global_sym_table, idx, sizeof(IntTy), s); + if (idx > global_gensym_counter) { + global_gensym_counter = idx; + } +} + +void set_newline(SymTy idx) { + newline_symbol = idx; + add_symbol(idx,"NEWLINE"); +} + +void set_space(SymTy idx) { + space_symbol = idx; + add_symbol(idx,"SPACE"); +} + +void set_comma(SymTy idx) { + comma_symbol = idx; + add_symbol(idx,"COMMA"); +} + +void set_leftparen(SymTy idx) { + leftparen_symbol = idx; + add_symbol(idx,"LEFTPAREN"); +} + +void set_rightparen(SymTy idx) { + rightparen_symbol = idx; + add_symbol(idx,"RIGHTPAREN"); +} + +IntTy print_symbol(SymTy idx) { + if (idx == comma_symbol) { + return printf(","); + } else if (idx == newline_symbol) { + return printf("\n"); + } else if (idx == space_symbol) { + return printf(" "); + } else if (idx == leftparen_symbol) { + return printf("("); + } else if (idx == rightparen_symbol) { + return printf(")"); + } else { + struct SymTable_elem *s; + HASH_FIND(hh, global_sym_table, &idx, sizeof(SymTy), s); + if (s == NULL) { + return printf("%lld", idx); + } else { + return printf("%s", s->value); + } + + } +} + +#ifdef _PARALLEL +SymTy gensym() { + SymTy idx = __atomic_add_fetch(&global_gensym_counter, 1, __ATOMIC_SEQ_CST); + return idx; +} +#else +SymTy gensym() { + global_gensym_counter += 1; + SymTy idx = global_gensym_counter; + return idx; +} +#endif + +void free_symtable() { + struct SymTable_elem *elt, *tmp; + HASH_ITER(hh, global_sym_table, elt, tmp) { + HASH_DEL(global_sym_table,elt); + } + free(elt); + free(tmp); +} + +/* + +---------------------------------------- +Garbage collection +---------------------------------------- + + Gibbon has "growing regions" i.e each logical region is backed by a doubly linked-list + of smaller chunks which grows as required. In addition to actual data, each chunk + stores some additional metadata (RegionFooter) to chain the chunks together in a list + and for garbage collection. The footer: + + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + serialized data | rf_reg_metadata_ptr | rf_seq_no | rf_size | rf_next | rf_prev + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + The metadata after the serialized data serves various purposes: + + - rf_reg_metadata_ptr: A pointer to a RegionTy struct that contains various metadata. + Of particular interest to us are the fields: + + = reg_id: A unique identifier for a region. + + = refcount and outset: Whenever an inter-region indirection is created, we record that information + using these two fields. Suppose we have an indirection from region A that points to some chunk + in region B. Then A's outset will store a pointer to that chunk's footer, and B's refcount will + be bumped by 1. Note that all there's only 1 refcount cell, and 1 outset per logical region, + and chunks only store a pointer to them. + + - rf_seq_no: The index of this particular chunk in the list. + + - rf_size: Used during bounds checking to calculate the size of the next region in + the linked list. + + - rf_next / rf_prev: Point to the next and previous chunk respectively. + + +There are two ways in which a region may be freed: + +(1) Whenever it goes out of scope + + The RTS tries to free a region whenever it goes out of scope. But this doesn't always succeed as + regions sometimes contain values that "escape". One reason why this'll happen is if there's an + indirection from A->B, and A lives longer than B. + In such a case, when B goes out of scope it's refcount won't be 0, and the RTS won't free it. + This brings us to (2). + +(2) + + When the RTS successfully frees a region, it decrements the refcounts of all the regions it + points to (via the outset). At the same time, if it encounters a region in the outset whoose + refcount becomes 0 after the decrement, it calls free_region on that. This way we can be sure + that all regions will eventually be garbage collected before the program exits. + + + +Why is it a doubly linked-list? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Due to way that bounds-checking works, the pointers in the outset may actually point to any +arbitrary chunk in the chain. However, we must call free_region on the first one to ensure that +all of them are GC'd. So we need pointers to traverse backward get to the first one. +'trav_to_first_chunk' accomplishes this. + + */ + +#define MAX_OUTSET_LENGTH 10 + +typedef struct RegionTy_struct { + SymTy reg_id; + uint reg_refcount; + CursorTy reg_heap; + uint reg_outset_len; + CursorTy reg_outset[MAX_OUTSET_LENGTH]; +} RegionTy; + +typedef struct RegionFooter_struct { + RegionTy *rf_reg_metadata_ptr; + + IntTy rf_seq_no; + IntTy rf_size; + struct RegionFooter_struct *rf_next; + struct RegionFooter_struct *rf_prev; +} RegionFooter; + +typedef struct ChunkTy_struct { + CursorTy chunk_start; + CursorTy chunk_end; +} ChunkTy; + +static inline void insert_into_outset(CursorTy ptr, RegionTy *reg) { + uint outset_len = reg->reg_outset_len; + // Check for duplicates. + for (uint i = 0; i < outset_len; i++) { + if (ptr == reg->reg_outset[i]) { + return; + } + } + // Otherwise, insert into the outset. + reg->reg_outset[outset_len] = ptr; + reg->reg_outset_len = outset_len + 1; + return; +} + +static inline void remove_from_outset(CursorTy ptr, RegionTy *reg) { + uint outset_len = reg->reg_outset_len; + CursorTy *outset = reg->reg_outset; + int i; + if (outset_len == 0) { + fprintf(stderr, "remove_from_outset: empty outset\n"); + exit(1); + } + // Position of 'ptr' in the outset. + int elt_idx = -1; + for (i = 0; i < outset_len; i++) { + if (ptr == outset[i]) { + elt_idx = i; + } + } + if (elt_idx == -1) { + fprintf(stderr, "remove_from_outset: element not found\n"); + exit(1); + } + // Move all elements ahead of 'elt_idx' back by one position. + for (i = elt_idx; i < outset_len; i++) { + outset[i] = outset[i+1]; + } + return; +} + +RegionTy *alloc_region(IntTy size) { + // Allocate the region metadata. + RegionTy *reg = ALLOC(sizeof(RegionTy)); + if (reg == NULL) { + printf("alloc_region: allocation failed: %ld", sizeof(RegionTy)); + exit(1); + } + + // Allocate the first chunk. + IntTy total_size = size + sizeof(RegionFooter); + CursorTy heap = ALLOC_PACKED_BIG(total_size); + if (heap == NULL) { + printf("alloc_region: malloc failed: %lld", total_size); + exit(1); + } + // Not heap+total_size, since we must keep space for the footer. + CursorTy heap_end = heap + size; + + // Initialize metadata fields. + reg->reg_id = gensym(); + reg->reg_refcount = 1; + reg->reg_heap = heap; + reg->reg_outset_len = 0; + +#ifdef _DEBUG + printf("Allocated a region(%lld): %lld bytes.\n", reg->reg_id, size); +#endif + + // Write the footer. + RegionFooter *footer = (RegionFooter *) heap_end; + footer->rf_reg_metadata_ptr = reg; + footer->rf_seq_no = 1; + footer->rf_size = size; + footer->rf_next = NULL; + footer->rf_prev = NULL; + + return reg; +} + +RegionTy *alloc_counted_region(IntTy size) { + // Bump the count. + bump_global_region_count(); + return alloc_region(size); +} + +ChunkTy alloc_chunk(CursorTy end_old_chunk) { + // Get size from current footer. + RegionFooter *footer = (RegionFooter *) end_old_chunk; + IntTy newsize = footer->rf_size * 2; + // See #110. + if (newsize > global_inf_buf_max_chunk_size) { + newsize = global_inf_buf_max_chunk_size; + } + IntTy total_size = newsize + sizeof(RegionFooter); + + // Allocate. + CursorTy start = ALLOC_PACKED_BIG(total_size); + if (start == NULL) { + printf("alloc_chunk: malloc failed: %lld", total_size); + exit(1); + } + CursorTy end = start + newsize; + + // Link the next chunk's footer. + footer->rf_next = (RegionFooter *) end; + + // Write the footer. + RegionFooter* new_footer = (RegionFooter *) end; + new_footer->rf_reg_metadata_ptr = footer->rf_reg_metadata_ptr; + new_footer->rf_seq_no = footer->rf_seq_no + 1; + new_footer->rf_size = newsize; + new_footer->rf_next = NULL; + new_footer->rf_prev = footer; + +#ifdef _DEBUG + RegionTy *reg = (RegionTy*) new_footer->rf_reg_metadata_ptr; + printf("alloc_chunk: allocated %lld bytes for region %lld.\n", total_size, reg->reg_id); +#endif + + return (ChunkTy) {start , end}; +} + +RegionFooter* trav_to_first_chunk(RegionFooter *footer) { + if (footer->rf_seq_no == 1) { + return footer; + } else if (footer->rf_prev == NULL) { + fprintf(stderr, "No previous chunk found at rf_seq_no: %lld", footer->rf_seq_no); + return NULL; + } else { + trav_to_first_chunk((RegionFooter *) footer->rf_prev); + } + return NULL; +} + +uint get_ref_count(CursorTy end_ptr) { + RegionFooter *footer = (RegionFooter *) end_ptr; + RegionTy *reg = (RegionTy *) footer->rf_reg_metadata_ptr; + return reg->reg_refcount; +} + +// B is the pointer, and A is the pointee (i.e B -> A). +// Bump A's refcount and update B's outset. +static inline void bump_ref_count(CursorTy end_b, CursorTy end_a) { + // Grab footers. + RegionFooter *footer_a = (RegionFooter *) end_a; + RegionFooter *footer_b = (RegionFooter *) end_b; + + // Grab metadata. + RegionTy *reg_a = (RegionTy *) footer_a->rf_reg_metadata_ptr; + RegionTy *reg_b = (RegionTy *) footer_b->rf_reg_metadata_ptr; + + // Bump A's refcount. + uint current_refcount, new_refcount; + current_refcount = reg_a->reg_refcount; + new_refcount = current_refcount + 1; + reg_a->reg_refcount = new_refcount; + +#ifdef _DEBUG + printf("bump_ref_count: %lld -> %lld\n", reg_b->reg_id, reg_a->reg_id); + printf("bump_ref_count: old-refcount=%d, old-outset-len=%d:\n", current_refcount, reg_b->reg_outset_len); + assert(current_refcount == reg_b->reg_outset_len+1); +#endif + + // Add A to B's outset. + insert_into_outset(end_a, reg_b); + +#ifdef _DEBUG + // printf("bump_ref_count: Added %p to %lld's outset, %p.\n", end_a, reg_b->reg_id, reg_b); + printf("bump_ref_count: new-refcount=%d, new-outset-len=%d\n", new_refcount, reg_b->reg_outset_len); + assert(new_refcount == reg_b->reg_outset_len+1); +#endif + + return; +} + +void free_region(CursorTy end_reg) { + // Grab footer and the metadata. + RegionFooter *footer = (RegionFooter *) end_reg; + RegionTy *reg = (RegionTy *) footer->rf_reg_metadata_ptr; + + // + RegionFooter *first_chunk_footer, *next_chunk_footer; + CursorTy first_chunk, next_chunk; + + // Decrement current reference count. + uint current_refcount, new_refcount; + current_refcount = reg->reg_refcount; + new_refcount = 0; + if (current_refcount != 0) { + new_refcount = current_refcount - 1; + reg->reg_refcount = new_refcount; + } + +#ifdef _DEBUG + printf("free_region(%lld): refcounts (1): old-refcount=%d, new-refcount=%d:\n", reg->reg_id, current_refcount, new_refcount); +#endif + + + // Free this region recount is 0. + if (new_refcount == 0) { + +#ifdef _DEBUG + printf("free_region(%lld): outset length: %d\n", reg->reg_id, reg->reg_outset_len); +#endif + + // Decrement refcounts, free regions with refcount==0 and also free + // elements of the outset. + if (reg->reg_outset_len != 0) { + uint outset_len = reg->reg_outset_len; + CursorTy *outset = reg->reg_outset; + RegionFooter *elt_footer; + RegionTy *elt_reg; + uint elt_current_refcount, elt_new_refcount; + CursorTy to_be_removed[MAX_OUTSET_LENGTH]; + uint to_be_removed_idx = 0; + for (int i = 0; i < outset_len; i++) { + elt_footer = (RegionFooter *) outset[i]; + elt_reg = (RegionTy *) elt_footer->rf_reg_metadata_ptr; +#ifdef _DEBUG + elt_current_refcount = elt_reg->reg_refcount; +#endif + elt_new_refcount = elt_current_refcount - 1; + elt_reg->reg_refcount = elt_new_refcount; +#ifdef _DEBUG + printf("free_region(%lld): old-refcount=%d, new-refcount=%d:\n", + elt_reg->reg_id, elt_current_refcount, elt_reg->reg_refcount); +#endif + if (elt_new_refcount == 0) { + // See [Why is it a doubly linked-list?] above + first_chunk_footer = trav_to_first_chunk(elt_footer); + if (first_chunk_footer != NULL) { + free_region((CursorTy) first_chunk_footer); + } + } + to_be_removed[to_be_removed_idx] = outset[i]; + to_be_removed_idx++; + } + // Remove elements from the outset. + for (uint i = 0; i < to_be_removed_idx; i++) { + remove_from_outset(to_be_removed[i], reg); + } + } + + +#ifdef _DEBUG + // Bookkeeping + IntTy num_freed_chunks = 0, total_bytesize = 0; +#endif + + // Free the chunks in this region. + first_chunk = end_reg - footer->rf_size; + first_chunk_footer = footer; + next_chunk = (char*) footer->rf_next; + +#ifdef _DEBUG + printf("free_region(%lld)\n", reg->reg_id); +#endif + +#ifdef _DEBUG + num_freed_chunks++; + total_bytesize = total_bytesize + first_chunk_footer->rf_size; +#endif + free(first_chunk); + + while (next_chunk != NULL) { + next_chunk_footer = (RegionFooter *) next_chunk; + #ifdef _DEBUG + num_freed_chunks++; + total_bytesize = total_bytesize + next_chunk_footer->rf_size; + #endif + free(next_chunk - next_chunk_footer->rf_size); + next_chunk = (char*) next_chunk_footer->rf_next; + } + +#ifdef _DEBUG + printf("free_region(%lld): Freed %lld bytes across %lld chunks.\n", + reg->reg_id, total_bytesize, num_freed_chunks); +#endif + + // Free the metadata. + free(reg); + + } else { +#ifdef _DEBUG + printf("free_region(%lld): non-zero refcount: %d.\n", + reg->reg_id, reg->reg_refcount); +#endif + } +} + +// Assume that all nodes with size information have tags >= 150. +BoolTy is_big(IntTy i, CursorTy cur) { + TagTyPacked tag = *(TagTyPacked *) cur; + if (tag >= 150) { + cur += 1; + IntTy size = *(IntTy *) cur; + if (size >= i) { + return true; + } else { + return false; + } + } + return false; +} + +// ------------------------------------- +// Vectors +// ------------------------------------- + +typedef struct VectorTy_struct { + // Bounds on the vector. + IntTy vec_lower, vec_upper; + + // Size of each element. + IntTy vec_elt_size; + + // Actual elements of the vector. + void* vec_data; +} VectorTy; + +VectorTy* vector_alloc(IntTy num, IntTy elt_size) { + VectorTy *vec = ALLOC(sizeof(VectorTy)); + if (vec == NULL) { + printf("alloc_vector: malloc failed: %ld", sizeof(VectorTy)); + exit(1); + } + void* data = ALLOC(num * elt_size); + if (data == NULL) { + printf("alloc_vector: malloc failed: %ld", sizeof(num * elt_size)); + exit(1); + } + vec->vec_lower = 0; + vec->vec_upper = num; + vec->vec_elt_size = elt_size; + vec->vec_data = data; + return vec; +} + +IntTy vector_length(VectorTy *vec) { + return (vec->vec_upper - vec->vec_lower); +} + +BoolTy vector_is_empty(VectorTy *vec) { + return (vector_length(vec) == 0); +} + +VectorTy* vector_slice(IntTy i, IntTy n, VectorTy *vec) { + IntTy lower = vec->vec_lower + i; + IntTy upper = vec->vec_lower + i + n; + if ((lower > vec->vec_upper)) { + printf("vector_slice: lower out of bounds, %lld > %lld", lower, vec->vec_upper); + exit(1); + } + if ((upper > vec->vec_upper)) { + printf("vector_slice: upper out of bounds: %lld > %lld", upper, vec->vec_upper); + exit(1); + } + VectorTy *vec2 = ALLOC(sizeof(VectorTy)); + if (vec == NULL) { + printf("vector_slice: malloc failed: %ld", sizeof(VectorTy)); + exit(1); + } + vec2->vec_lower = lower; + vec2->vec_upper = upper; + vec2->vec_elt_size = vec->vec_elt_size; + vec2->vec_data = vec->vec_data; + return vec2; +} + +// The callers must cast the return value. +static inline void* vector_nth(VectorTy *vec, IntTy i) { + // if (i < vec->lower || i > vec->upper) { + // printf("vector_nth index out of bounds: %lld (%lld,%lld) \n", i, vec->vec_lower, vec->vec_upper); + // exit(1); + // } + return (vec->vec_data + (vec->vec_elt_size * (vec->vec_lower + i))); +} + +static inline VectorTy* vector_inplace_update(VectorTy *vec, IntTy i, void* elt) { + void* dst = vector_nth(vec, i); + memcpy(dst, elt, vec->vec_elt_size); + return vec; +} + +static inline VectorTy* vector_copy(VectorTy *vec) { + IntTy len = vector_length(vec); + void *start = vector_nth(vec, 0); + VectorTy *vec2 = vector_alloc(len, vec->vec_elt_size); + memcpy(vec2->vec_data, start, len * vec->vec_elt_size); + return vec2; +} + +static inline VectorTy* vector_inplace_sort(VectorTy *vec, int (*compar)(const void *, const void*)) { + void *start = vector_nth(vec, 0); + qsort(start, vector_length(vec), vec->vec_elt_size, compar); + return vec; +} + +static inline VectorTy* vector_sort(VectorTy *vec, int (*compar)(const void *, const void*)) { + VectorTy *vec2 = vector_copy(vec); + vector_inplace_sort(vec2, compar); + return vec2; +} + +static inline VectorTy* vector_concat(VectorTy *vec) { + // Length of the input vector. + IntTy len = vector_length(vec); + // Length of the concatenated vector. + IntTy result_len = 0; + // Size of each element in the concatenated vector. + IntTy result_elt_size = 0; + VectorTy **elt_ref, *elt; + for (IntTy i = 0; i < len; i++) { + elt_ref = vector_nth(vec, i); + elt = *elt_ref; + result_elt_size = elt->vec_elt_size; + result_len += vector_length(elt); + } + + // Concatenated vector. + VectorTy *result = vector_alloc(result_len, result_elt_size); + IntTy elt_len; + // A counter that tracks the index of elements in 'result'. + IntTy k = 0; + for (IntTy i = 0; i < len; i++) { + elt_ref = vector_nth(vec, i); + elt = *elt_ref; + elt_len = vector_length(elt); + + for (IntTy j = 0; j < elt_len; j++) { + void* k_elt = vector_nth(elt, j); + vector_inplace_update(result, k, k_elt); + k++; + } + } + + return result; +} + +static inline void vector_free(VectorTy *vec) { + free(vec->vec_data); + free(vec); + return; +} + +static inline VectorTy* vector_merge(VectorTy *vec1, VectorTy *vec2) { + if (vec1->vec_upper != vec2->vec_lower) { + printf("vector_merge: non-contiguous slices, (%lld,%lld), (%lld,%lld).", + vec1->vec_lower, vec1->vec_upper, vec2->vec_lower, vec2->vec_upper); + exit(1); + } + VectorTy *merged = ALLOC(sizeof(VectorTy)); + if (merged == NULL) { + printf("vector_merge: malloc failed: %ld", sizeof(VectorTy)); + exit(1); + } + merged->vec_lower = vec1->vec_lower; + merged->vec_upper = vec2->vec_upper; + merged->vec_elt_size = vec1->vec_elt_size; + merged->vec_data = vec1->vec_data; + return merged; +} + +void print_timing_array(VectorTy *times) { + printf("TIMES: ["); + double *d; + IntTy n = vector_length(times); + for(int i = 0; i < n; i++) { + d = vector_nth(times, i); + if (i == (n-1)) { + printf("%f",*d); + } + else { + printf("%f, ",*d); + } + } + printf("]\n"); +} + +double sum_timing_array(VectorTy *times) { + double *d; + double acc = 0; + for(int i = 0; i < vector_length(times); i++) { + d = vector_nth(times, i); + acc += *d; + } + return acc; +} + +// ------------------------------------- +// Linked lists +// ------------------------------------- + +typedef struct ListTy_struct { + IntTy ll_data_size; + void* ll_data; + struct ListTy_struct* ll_next; +} ListTy; + +static inline ListTy* list_alloc(IntTy data_size) { + // ListTy *ls = ALLOC(sizeof(ListTy)); + ListTy *ls = BUMPALLOC(sizeof(ListTy)); + ls->ll_data_size = data_size; + ls->ll_data = NULL; + ls->ll_next = NULL; + return ls; +} + +static inline BoolTy list_is_empty(ListTy *ls) { + return ls->ll_next == NULL; +} + +static inline ListTy* list_cons(void* elt, ListTy *ls) { + // void* data = ALLOC(ls->data_size); + void* data = BUMPALLOC(ls->ll_data_size); + if (data == NULL) { + printf("list_cons: malloc failed: %lld", ls->ll_data_size); + exit(1); + } + memcpy(data, elt, ls->ll_data_size); + // ListTy *res = ALLOC(sizeof(ListTy)); + ListTy *res = BUMPALLOC(sizeof(ListTy)); + res->ll_data_size = ls->ll_data_size; + res->ll_data = data; + res->ll_next = (ListTy*) ls; + return res; +} + +static inline void* list_head(ListTy *ls) { + return ls->ll_data; +} + +static inline ListTy* list_tail(ListTy *ls) { + return ls->ll_next; +} + +static inline void list_free(ListTy *ls) { + free(ls->ll_data); + free(ls); + return; +} + +static inline ListTy* list_copy(ListTy *ls) { + ListTy *ls2 = list_alloc(ls->ll_data_size); + if (ls->ll_data != NULL) { + void* data = BUMPALLOC(ls->ll_data_size); + memcpy(data, ls->ll_data, ls->ll_data_size); + ls2->ll_data = data; + } + ls2->ll_next = ls->ll_next; + return ls2; +} + +// ------------------------------------- +// Ppm Images +// ------------------------------------- + +typedef struct __Pixel_struct { + IntTy field0; + IntTy field1; + IntTy field2; +} __Pixel; + +void writePpm(char* filename, IntTy width, IntTy height, VectorTy *pixels); +void writePpm_loop(FILE *fp, IntTy idx, IntTy end, VectorTy *pixels); + +// Example: writePpm("gibbon_rgb_1000.ppm", 1000, 1000, pixels); +void writePpm(char* filename, IntTy width, IntTy height, VectorTy *pixels) +{ + FILE *fp; + fp = fopen(filename, "w+"); + fprintf(fp, "P3\n"); + fprintf(fp, "%lld %lld\n255\n", width, height); + IntTy len = vector_length(pixels); + writePpm_loop(fp, 0, len, pixels); + fclose(fp); + return; +} + +void writePpm_loop(FILE *fp, IntTy idx, IntTy end, VectorTy *pixels) +{ + BoolTy fltIf_5768_6575 = idx == end; + + if (fltIf_5768_6575) { + return; + } else { + __Pixel *tmp_112; + tmp_112 = (__Pixel *) vector_nth(pixels, idx); + __Pixel tup = *tmp_112; + IntTy x = tup.field0; + IntTy y = tup.field1; + IntTy z = tup.field2; + // write to file. + fprintf(fp, "%lld %lld %lld\n", x, y, z); + writePpm_loop(fp, (idx+1), end, pixels); + } +} + +/* -------------------------------------------------------------------------------- */ + +int main(int argc, char** argv) +{ + // parameters to parse: + // + // num iterations: How many times to repeat a benchmark. + // tree size: An integer passes to `build_tree()`. + + struct rlimit lim; + int code; + if ( (code = getrlimit(RLIMIT_STACK, &lim)) ) { + fprintf(stderr, " [gibbon rts] failed to getrlimit, code %d\n", code); + exit(1); + } + + // lim.rlim_cur = 1024LU * 1024LU * 1024LU; // 1GB stack. + lim.rlim_cur = 512LU * 1024LU * 1024LU; // 500MB stack. + // lim.rlim_max = lim.rlim_cur; // Normal users may only be able to decrease this. + + // WARNING: Haven't yet figured out why this doesn't work on MacOS... +#ifndef __APPLE__ + code = setrlimit(RLIMIT_STACK, &lim); + while (code) { + fprintf(stderr, " [gibbon rts] Failed to set stack size to %llu, code %d\n", (unsigned long long)lim.rlim_cur, code); + lim.rlim_cur /= 2; + // lim.rlim_max /= 2; + if(lim.rlim_cur < 100 * 1024) { + fprintf(stderr, " [gibbon rts] Failed setrlimit stack size to something reasonable; giving up.\n"); + break; // abort(); + } + int code = setrlimit(RLIMIT_STACK, &lim); + } +#endif + + int got_numargs = 0; // How many numeric arguments have we got. + + int i; + for (i = 1; i < argc; ++i) + { + if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) { + show_usage(argv); + exit(0); + } + else if (strcmp(argv[i], "--biginf-buffer-size") == 0 && i < argc - 1) + { + global_init_biginf_buf_size = atoll(argv[i + 1]); + i++; + } + else if (strcmp(argv[i], "--inf-buffer-size") == 0 && i < argc - 1) + { + global_init_inf_buf_size = atoll(argv[i + 1]); + i++; + } + else if ((strcmp(argv[i], "--bench-input") == 0)) { + if (i+1 >= argc) { + fprintf(stderr, "Not enough arguments after --bench-input, expected .\n"); + show_usage(argv); + exit(1); + } + global_benchfile_param = argv[i+1]; + i++; + } + else if ((strcmp(argv[i], "--array-input") == 0)) { + if (i+1 >= argc) { + fprintf(stderr, "Not enough arguments after --array-input, expected .\n"); + show_usage(argv); + exit(1); + } + global_arrayfile_param = argv[i+1]; + i++; + } + else if (strcmp(argv[i], "--array-input-length") == 0 && i < argc - 1) { + global_arrayfile_length_param = atoll(argv[i+1]); + i++; + } + else if (strcmp(argv[i], "--bench-prog") == 0 && i < argc - 1) { + int len = strlen(argv[i+1]); + global_bench_prog_param = (char*) malloc((len+1)*sizeof(char)); + strncpy(global_bench_prog_param,argv[i+1],len); + i++; + } + // If present, we expect the two arguments to be + else if (got_numargs >= 2) { + fprintf(stderr, "Extra arguments left over: "); + for(; i < argc; i++) fprintf(stderr, "%s ", argv[i]); + show_usage(argv); + exit(1); + } else { + if (got_numargs == 0) { + global_size_param = atoll(argv[i]); + got_numargs ++; + } else { + global_iters_param = atoll(argv[i]); + } + } + } + + // Initialize global_bench_prog_param to an empty string in case + // the runtime argument --bench-prog isn't passed. + if (global_bench_prog_param == NULL) { + global_bench_prog_param = (char*) malloc(1*sizeof(char)); + *global_bench_prog_param = '\n'; + } + + __main_expr(); + + return 0; +} + +// ----------------------------------------------------------------------------- +// Program starts here +// ----------------------------------------------------------------------------- + +typedef struct Prod_struct { } Prod; +typedef struct Int64Prod_struct { + IntTy field0; + } Int64Prod; +typedef struct Int64Int64Int64Int64CursorCursorProd_struct { + IntTy field0; + IntTy field1; + IntTy field2; + IntTy field3; + CursorTy field4; + CursorTy field5; + } Int64Int64Int64Int64CursorCursorProd; +typedef struct Int64Int64Int64CursorCursorProd_struct { + IntTy field0; + IntTy field1; + IntTy field2; + CursorTy field3; + CursorTy field4; + } Int64Int64Int64CursorCursorProd; +typedef struct BoolProd_struct { + BoolTy field0; + } BoolProd; +typedef struct TagCursorProd_struct { + TagTyPacked field0; + CursorTy field1; + } TagCursorProd; +typedef struct CursorProd_struct { + CursorTy field0; + } CursorProd; +IntTy sumRight(CursorTy m_34_689_917); +CursorTy build(IntTy x_40_695_926, IntTy sz_41_696_927, CursorTy m_42_697_928); +IntTy ratio(); +IntTy delta(); +IntTy size_316(CursorTy m_173_698_938); +CursorTy singleL_323(IntTy k1_100_704_944, IntTy x1_101_705_945, + CursorTy t1_102_706_946, CursorTy m_103_707_947); +CursorTy doubleL_324(IntTy k1_71_713_954, IntTy x1_72_714_955, + CursorTy t1_73_715_956, CursorTy m0_74_716_957); +CursorTy rotateL_317(IntTy k_125_722_963, IntTy x_126_723_964, + CursorTy l_127_724_965, CursorTy r_128_725_966); +CursorTy bin_322(IntTy k_110_731_977, IntTy x_111_732_978, + CursorTy l_112_733_979, CursorTy r_113_734_980); +CursorTy singleR_319(IntTy k1_90_735_985, IntTy x1_91_736_986, + CursorTy m_92_737_987, CursorTy t3_93_738_988); +CursorTy doubleR_320(IntTy k1_56_744_995, IntTy x1_57_745_996, + CursorTy m0_58_746_997, CursorTy t4_59_747_998); +CursorTy empty_321(); +CursorTy rotateR_318(IntTy k_115_753_1004, IntTy x_116_754_1005, + CursorTy l_117_755_1006, CursorTy r_118_756_1007); +CursorTy balance_315(IntTy k_135_762_1018, IntTy x_136_763_1019, + CursorTy l_137_764_1020, CursorTy r_138_765_1021); +CursorTy singleton_312(IntTy k_52_766_1042, IntTy x_53_767_1043); +CursorTy insert_314(IntTy kx_43_768_1046, IntTy x_44_769_1047, + CursorTy m_45_770_1048); +CursorTy _copy_without_ptrs_Map_v_313(CursorTy arg_624_776_1058); +CursorTy _copy_Map_v_313(CursorTy arg_613_787_1069); +unsigned char _traverse_Map_v_313(CursorTy arg_635_798_1080); +unsigned char _print_Map_v_313(CursorTy arg_646_806_1088); +CursorTy caseFn_666(IntTy x1_72_667_826_1108, IntTy k1_71_668_827_1109, + CursorTy t1_73_669_828_1110, CursorTy m1_79_670_829_1111, + IntTy k2_77_671_830_1112, IntTy x2_78_672_831_1113, + CursorTy t4_80_673_832_1114); +CursorTy caseFn_674(IntTy x1_57_675_838_1122, IntTy k1_56_676_839_1123, + CursorTy t4_59_677_840_1124, CursorTy m1_65_678_841_1125, + IntTy k2_62_679_842_1126, IntTy x2_63_680_843_1127, + CursorTy t1_64_681_844_1128); +IntTy sumRight(CursorTy m_34_689_917) +{ + TagTyPacked tag_1143 = *(TagTyPacked *) m_34_689_917; + CursorTy tail_1144 = m_34_689_917 + sizeof(IntTy); + + + switch_1146: + ; + switch (tag_1143) { + + case 0: + { + return 0; + break; + } + + case 1: + { + IntTy wildcard__1_35_690_918 = + ((Int64Int64Int64CursorCursorProd *) tail_1144)->field0; + IntTy wildcard__2_36_691_919 = + ((Int64Int64Int64CursorCursorProd *) tail_1144)->field1; + IntTy v_37_692_920 = + ((Int64Int64Int64CursorCursorProd *) tail_1144)->field2; + CursorTy l_38_693_921 = + ((Int64Int64Int64CursorCursorProd *) tail_1144)->field3; + CursorTy r_39_694_922 = + ((Int64Int64Int64CursorCursorProd *) tail_1144)->field4; + IntTy fltPrm_852_923 = sumRight(r_39_694_922); + IntTy fltPrm_851_924 = fltPrm_852_923 + v_37_692_920; + IntTy fltPrm_853_925 = sumRight(l_38_693_921); + IntTy flt_1145 = fltPrm_851_924 + fltPrm_853_925; + + return flt_1145; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1143"); + exit(1); + } + } +} +CursorTy build(IntTy x_40_695_926, IntTy sz_41_696_927, CursorTy m_42_697_928) +{ + BoolTy fltIf_854_929 = sz_41_696_927 == 0; + + if (fltIf_854_929) { + return m_42_697_928; + } else { + IntTy fltPrm_856_930 = sz_41_696_927 / 2; + IntTy fltAppE_855_931 = x_40_695_926 - fltPrm_856_930; + IntTy fltAppE_857_932 = sz_41_696_927 / 2; + IntTy fltPrm_860_933 = sz_41_696_927 / 2; + IntTy fltAppE_859_934 = x_40_695_926 + fltPrm_860_933; + IntTy fltAppE_861_935 = sz_41_696_927 / 2; + CursorTy fltAppE_862_936 = + insert_314(x_40_695_926, x_40_695_926, m_42_697_928); + CursorTy fltAppE_858_937 = + build(fltAppE_859_934, fltAppE_861_935, fltAppE_862_936); + + return build(fltAppE_855_931, fltAppE_857_932, fltAppE_858_937); + } +} +IntTy ratio() +{ + return 2; +} +IntTy delta() +{ + return 4; +} +IntTy size_316(CursorTy m_173_698_938) +{ + TagTyPacked tag_1147 = *(TagTyPacked *) m_173_698_938; + CursorTy tail_1148 = m_173_698_938 + sizeof(IntTy); + + + switch_1149: + ; + switch (tag_1147) { + + case 0: + { + return 0; + break; + } + + case 1: + { + IntTy sz_175_699_939 = + ((Int64Int64Int64CursorCursorProd *) tail_1148)->field0; + IntTy wildcard__18_176_700_940 = + ((Int64Int64Int64CursorCursorProd *) tail_1148)->field1; + IntTy wildcard__19_177_701_941 = + ((Int64Int64Int64CursorCursorProd *) tail_1148)->field2; + CursorTy wildcard__20_178_702_942 = + ((Int64Int64Int64CursorCursorProd *) tail_1148)->field3; + CursorTy wildcard__21_179_703_943 = + ((Int64Int64Int64CursorCursorProd *) tail_1148)->field4; + + return sz_175_699_939; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1147"); + exit(1); + } + } +} +CursorTy singleL_323(IntTy k1_100_704_944, IntTy x1_101_705_945, + CursorTy t1_102_706_946, CursorTy m_103_707_947) +{ + TagTyPacked tag_1150 = *(TagTyPacked *) m_103_707_947; + CursorTy tail_1151 = m_103_707_947 + sizeof(IntTy); + + + switch_1152: + ; + switch (tag_1150) { + + case 1: + { + IntTy wildcard__123_105_708_948 = + ((Int64Int64Int64CursorCursorProd *) tail_1151)->field0; + IntTy k2_106_709_949 = + ((Int64Int64Int64CursorCursorProd *) tail_1151)->field1; + IntTy x2_107_710_950 = + ((Int64Int64Int64CursorCursorProd *) tail_1151)->field2; + CursorTy t2_108_711_951 = + ((Int64Int64Int64CursorCursorProd *) tail_1151)->field3; + CursorTy t3_109_712_952 = + ((Int64Int64Int64CursorCursorProd *) tail_1151)->field4; + CursorTy fltAppE_863_953 = + bin_322(k1_100_704_944, x1_101_705_945, t1_102_706_946, t2_108_711_951); + + return bin_322(k2_106_709_949, x2_107_710_950, fltAppE_863_953, + t3_109_712_952); + break; + } + + case 0: + { + return empty_321(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1150"); + exit(1); + } + } +} +CursorTy doubleL_324(IntTy k1_71_713_954, IntTy x1_72_714_955, + CursorTy t1_73_715_956, CursorTy m0_74_716_957) +{ + TagTyPacked tag_1153 = *(TagTyPacked *) m0_74_716_957; + CursorTy tail_1154 = m0_74_716_957 + sizeof(IntTy); + + + switch_1155: + ; + switch (tag_1153) { + + case 1: + { + IntTy wildcard__143_76_717_958 = + ((Int64Int64Int64CursorCursorProd *) tail_1154)->field0; + IntTy k2_77_718_959 = + ((Int64Int64Int64CursorCursorProd *) tail_1154)->field1; + IntTy x2_78_719_960 = + ((Int64Int64Int64CursorCursorProd *) tail_1154)->field2; + CursorTy m1_79_720_961 = + ((Int64Int64Int64CursorCursorProd *) tail_1154)->field3; + CursorTy t4_80_721_962 = + ((Int64Int64Int64CursorCursorProd *) tail_1154)->field4; + + return caseFn_666(x1_72_714_955, k1_71_713_954, t1_73_715_956, + m1_79_720_961, k2_77_718_959, x2_78_719_960, + t4_80_721_962); + break; + } + + case 0: + { + return empty_321(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1153"); + exit(1); + } + } +} +CursorTy rotateL_317(IntTy k_125_722_963, IntTy x_126_723_964, + CursorTy l_127_724_965, CursorTy r_128_725_966) +{ + TagTyPacked tag_1156 = *(TagTyPacked *) r_128_725_966; + CursorTy tail_1157 = r_128_725_966 + sizeof(IntTy); + + + switch_1158: + ; + switch (tag_1156) { + + case 1: + { + IntTy wildcard__94_130_726_967 = + ((Int64Int64Int64CursorCursorProd *) tail_1157)->field0; + IntTy wildcard__95_131_727_968 = + ((Int64Int64Int64CursorCursorProd *) tail_1157)->field1; + IntTy wildcard__96_132_728_969 = + ((Int64Int64Int64CursorCursorProd *) tail_1157)->field2; + CursorTy ly_133_729_970 = + ((Int64Int64Int64CursorCursorProd *) tail_1157)->field3; + CursorTy ry_134_730_971 = + ((Int64Int64Int64CursorCursorProd *) tail_1157)->field4; + IntTy fltPrm_865_972 = size_316(ly_133_729_970); + IntTy fltPrm_867_973 = ratio(); + IntTy fltPrm_868_974 = size_316(ry_134_730_971); + IntTy fltPrm_866_975 = fltPrm_867_973 * fltPrm_868_974; + BoolTy fltIf_864_976 = fltPrm_865_972 < fltPrm_866_975; + + if (fltIf_864_976) { + return singleL_323(k_125_722_963, x_126_723_964, l_127_724_965, + r_128_725_966); + } else { + return doubleL_324(k_125_722_963, x_126_723_964, l_127_724_965, + r_128_725_966); + } + break; + } + + case 0: + { + return empty_321(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1156"); + exit(1); + } + } +} +CursorTy bin_322(IntTy k_110_731_977, IntTy x_111_732_978, + CursorTy l_112_733_979, CursorTy r_113_734_980) +{ + IntTy fltPrm_871_981 = size_316(l_112_733_979); + IntTy fltPrm_872_982 = size_316(r_113_734_980); + IntTy fltPrm_870_983 = fltPrm_871_981 + fltPrm_872_982; + IntTy fltPkd_869_984 = fltPrm_870_983 + 1; + PtrTy tailift_1159 = ALLOC(sizeof(Int64Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1159)->field0 = 1; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1159)->field1 = + fltPkd_869_984; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1159)->field2 = + k_110_731_977; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1159)->field3 = + x_111_732_978; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1159)->field4 = + l_112_733_979; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1159)->field5 = + r_113_734_980; + return tailift_1159; +} +CursorTy singleR_319(IntTy k1_90_735_985, IntTy x1_91_736_986, + CursorTy m_92_737_987, CursorTy t3_93_738_988) +{ + TagTyPacked tag_1160 = *(TagTyPacked *) m_92_737_987; + CursorTy tail_1161 = m_92_737_987 + sizeof(IntTy); + + + switch_1162: + ; + switch (tag_1160) { + + case 1: + { + IntTy wildcard__133_95_739_989 = + ((Int64Int64Int64CursorCursorProd *) tail_1161)->field0; + IntTy k2_96_740_990 = + ((Int64Int64Int64CursorCursorProd *) tail_1161)->field1; + IntTy x2_97_741_991 = + ((Int64Int64Int64CursorCursorProd *) tail_1161)->field2; + CursorTy t1_98_742_992 = + ((Int64Int64Int64CursorCursorProd *) tail_1161)->field3; + CursorTy t2_99_743_993 = + ((Int64Int64Int64CursorCursorProd *) tail_1161)->field4; + CursorTy fltAppE_873_994 = + bin_322(k1_90_735_985, x1_91_736_986, t2_99_743_993, t3_93_738_988); + + return bin_322(k2_96_740_990, x2_97_741_991, t1_98_742_992, + fltAppE_873_994); + break; + } + + case 0: + { + return empty_321(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1160"); + exit(1); + } + } +} +CursorTy doubleR_320(IntTy k1_56_744_995, IntTy x1_57_745_996, + CursorTy m0_58_746_997, CursorTy t4_59_747_998) +{ + TagTyPacked tag_1163 = *(TagTyPacked *) m0_58_746_997; + CursorTy tail_1164 = m0_58_746_997 + sizeof(IntTy); + + + switch_1165: + ; + switch (tag_1163) { + + case 1: + { + IntTy wildcard__167_61_748_999 = + ((Int64Int64Int64CursorCursorProd *) tail_1164)->field0; + IntTy k2_62_749_1000 = + ((Int64Int64Int64CursorCursorProd *) tail_1164)->field1; + IntTy x2_63_750_1001 = + ((Int64Int64Int64CursorCursorProd *) tail_1164)->field2; + CursorTy t1_64_751_1002 = + ((Int64Int64Int64CursorCursorProd *) tail_1164)->field3; + CursorTy m1_65_752_1003 = + ((Int64Int64Int64CursorCursorProd *) tail_1164)->field4; + + return caseFn_674(x1_57_745_996, k1_56_744_995, t4_59_747_998, + m1_65_752_1003, k2_62_749_1000, x2_63_750_1001, + t1_64_751_1002); + break; + } + + case 0: + { + return empty_321(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1163"); + exit(1); + } + } +} +CursorTy empty_321() +{ + PtrTy tailift_1166 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) tailift_1166)->field0 = 0; + return tailift_1166; +} +CursorTy rotateR_318(IntTy k_115_753_1004, IntTy x_116_754_1005, + CursorTy l_117_755_1006, CursorTy r_118_756_1007) +{ + TagTyPacked tag_1167 = *(TagTyPacked *) l_117_755_1006; + CursorTy tail_1168 = l_117_755_1006 + sizeof(IntTy); + + + switch_1169: + ; + switch (tag_1167) { + + case 1: + { + IntTy wildcard__106_120_757_1008 = + ((Int64Int64Int64CursorCursorProd *) tail_1168)->field0; + IntTy wildcard__107_121_758_1009 = + ((Int64Int64Int64CursorCursorProd *) tail_1168)->field1; + IntTy wildcard__108_122_759_1010 = + ((Int64Int64Int64CursorCursorProd *) tail_1168)->field2; + CursorTy ly_123_760_1011 = + ((Int64Int64Int64CursorCursorProd *) tail_1168)->field3; + CursorTy ry_124_761_1012 = + ((Int64Int64Int64CursorCursorProd *) tail_1168)->field4; + IntTy fltPrm_875_1013 = size_316(ry_124_761_1012); + IntTy fltPrm_877_1014 = ratio(); + IntTy fltPrm_878_1015 = size_316(ly_123_760_1011); + IntTy fltPrm_876_1016 = fltPrm_877_1014 * fltPrm_878_1015; + BoolTy fltIf_874_1017 = fltPrm_875_1013 < fltPrm_876_1016; + + if (fltIf_874_1017) { + return singleR_319(k_115_753_1004, x_116_754_1005, + l_117_755_1006, r_118_756_1007); + } else { + return doubleR_320(k_115_753_1004, x_116_754_1005, + l_117_755_1006, r_118_756_1007); + } + break; + } + + case 0: + { + return empty_321(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1167"); + exit(1); + } + } +} +CursorTy balance_315(IntTy k_135_762_1018, IntTy x_136_763_1019, + CursorTy l_137_764_1020, CursorTy r_138_765_1021) +{ + IntTy fltPrm_881_1022 = size_316(l_137_764_1020); + IntTy fltPrm_882_1023 = size_316(r_138_765_1021); + IntTy fltPrm_880_1024 = fltPrm_881_1022 + fltPrm_882_1023; + BoolTy fltIf_879_1025 = fltPrm_880_1024 <= 1; + + if (fltIf_879_1025) { + IntTy fltPrm_884_1026 = size_316(l_137_764_1020); + IntTy fltPrm_885_1027 = size_316(r_138_765_1021); + IntTy fltPkd_883_1028 = fltPrm_884_1026 + fltPrm_885_1027; + PtrTy tailift_1170 = + ALLOC(sizeof(Int64Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1170)->field0 = 1; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1170)->field1 = + fltPkd_883_1028; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1170)->field2 = + k_135_762_1018; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1170)->field3 = + x_136_763_1019; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1170)->field4 = + l_137_764_1020; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1170)->field5 = + r_138_765_1021; + return tailift_1170; + } else { + IntTy fltPrm_887_1029 = size_316(r_138_765_1021); + IntTy fltPrm_889_1030 = delta(); + IntTy fltPrm_890_1031 = size_316(l_137_764_1020); + IntTy fltPrm_888_1032 = fltPrm_889_1030 * fltPrm_890_1031; + BoolTy fltIf_886_1033 = fltPrm_887_1029 >= fltPrm_888_1032; + + if (fltIf_886_1033) { + return rotateL_317(k_135_762_1018, x_136_763_1019, l_137_764_1020, + r_138_765_1021); + } else { + IntTy fltPrm_892_1034 = size_316(l_137_764_1020); + IntTy fltPrm_894_1035 = delta(); + IntTy fltPrm_895_1036 = size_316(r_138_765_1021); + IntTy fltPrm_893_1037 = fltPrm_894_1035 * fltPrm_895_1036; + BoolTy fltIf_891_1038 = fltPrm_892_1034 >= fltPrm_893_1037; + + if (fltIf_891_1038) { + return rotateR_318(k_135_762_1018, x_136_763_1019, + l_137_764_1020, r_138_765_1021); + } else { + IntTy fltPrm_897_1039 = size_316(l_137_764_1020); + IntTy fltPrm_898_1040 = size_316(r_138_765_1021); + IntTy fltPkd_896_1041 = fltPrm_897_1039 + fltPrm_898_1040; + PtrTy tailift_1171 = + ALLOC(sizeof(Int64Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1171)->field0 = + 1; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1171)->field1 = + fltPkd_896_1041; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1171)->field2 = + k_135_762_1018; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1171)->field3 = + x_136_763_1019; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1171)->field4 = + l_137_764_1020; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1171)->field5 = + r_138_765_1021; + return tailift_1171; + } + } + } +} +CursorTy singleton_312(IntTy k_52_766_1042, IntTy x_53_767_1043) +{ + PtrTy fltPkd_899_1044 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_899_1044)->field0 = 0; + + PtrTy fltPkd_900_1045 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_900_1045)->field0 = 0; + + PtrTy tailift_1172 = ALLOC(sizeof(Int64Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1172)->field0 = 1; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1172)->field1 = 1; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1172)->field2 = + k_52_766_1042; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1172)->field3 = + x_53_767_1043; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1172)->field4 = + fltPkd_899_1044; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1172)->field5 = + fltPkd_900_1045; + return tailift_1172; +} +CursorTy insert_314(IntTy kx_43_768_1046, IntTy x_44_769_1047, + CursorTy m_45_770_1048) +{ + TagTyPacked tag_1173 = *(TagTyPacked *) m_45_770_1048; + CursorTy tail_1174 = m_45_770_1048 + sizeof(IntTy); + + + switch_1176: + ; + switch (tag_1173) { + + case 0: + { + return singleton_312(kx_43_768_1046, x_44_769_1047); + break; + } + + case 1: + { + IntTy sz_47_771_1049 = + ((Int64Int64Int64CursorCursorProd *) tail_1174)->field0; + IntTy k_48_772_1050 = + ((Int64Int64Int64CursorCursorProd *) tail_1174)->field1; + IntTy v_49_773_1051 = + ((Int64Int64Int64CursorCursorProd *) tail_1174)->field2; + CursorTy l_50_774_1052 = + ((Int64Int64Int64CursorCursorProd *) tail_1174)->field3; + CursorTy r_51_775_1053 = + ((Int64Int64Int64CursorCursorProd *) tail_1174)->field4; + BoolTy fltIf_901_1054 = kx_43_768_1046 == k_48_772_1050; + + if (fltIf_901_1054) { + PtrTy tailift_1175 = + ALLOC(sizeof(Int64Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1175)->field0 = + 1; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1175)->field1 = + sz_47_771_1049; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1175)->field2 = + k_48_772_1050; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1175)->field3 = + x_44_769_1047; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1175)->field4 = + l_50_774_1052; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1175)->field5 = + r_51_775_1053; + return tailift_1175; + } else { + BoolTy fltIf_902_1055 = kx_43_768_1046 <= k_48_772_1050; + + if (fltIf_902_1055) { + CursorTy fltAppE_903_1056 = + insert_314(kx_43_768_1046, x_44_769_1047, l_50_774_1052); + + return balance_315(k_48_772_1050, v_49_773_1051, + fltAppE_903_1056, r_51_775_1053); + } else { + CursorTy fltAppE_904_1057 = + insert_314(kx_43_768_1046, x_44_769_1047, r_51_775_1053); + + return balance_315(k_48_772_1050, v_49_773_1051, + l_50_774_1052, fltAppE_904_1057); + } + } + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1173"); + exit(1); + } + } +} +CursorTy _copy_without_ptrs_Map_v_313(CursorTy arg_624_776_1058) +{ + TagTyPacked tag_1177 = *(TagTyPacked *) arg_624_776_1058; + CursorTy tail_1178 = arg_624_776_1058 + sizeof(IntTy); + + + switch_1181: + ; + switch (tag_1177) { + + case 0: + { + PtrTy tailift_1179 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) tailift_1179)->field0 = 0; + return tailift_1179; + break; + } + + case 1: + { + IntTy x_625_777_1059 = + ((Int64Int64Int64CursorCursorProd *) tail_1178)->field0; + IntTy x_626_778_1060 = + ((Int64Int64Int64CursorCursorProd *) tail_1178)->field1; + IntTy x_627_779_1061 = + ((Int64Int64Int64CursorCursorProd *) tail_1178)->field2; + CursorTy x_628_780_1062 = + ((Int64Int64Int64CursorCursorProd *) tail_1178)->field3; + CursorTy x_629_781_1063 = + ((Int64Int64Int64CursorCursorProd *) tail_1178)->field4; + CursorTy y_633_785_1067 = + _copy_without_ptrs_Map_v_313(x_628_780_1062); + CursorTy y_634_786_1068 = + _copy_without_ptrs_Map_v_313(x_629_781_1063); + PtrTy tailift_1180 = + ALLOC(sizeof(Int64Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1180)->field0 = 1; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1180)->field1 = + x_625_777_1059; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1180)->field2 = + x_626_778_1060; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1180)->field3 = + x_627_779_1061; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1180)->field4 = + y_633_785_1067; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1180)->field5 = + y_634_786_1068; + return tailift_1180; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1177"); + exit(1); + } + } +} +CursorTy _copy_Map_v_313(CursorTy arg_613_787_1069) +{ + TagTyPacked tag_1182 = *(TagTyPacked *) arg_613_787_1069; + CursorTy tail_1183 = arg_613_787_1069 + sizeof(IntTy); + + + switch_1186: + ; + switch (tag_1182) { + + case 0: + { + PtrTy tailift_1184 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) tailift_1184)->field0 = 0; + return tailift_1184; + break; + } + + case 1: + { + IntTy x_614_788_1070 = + ((Int64Int64Int64CursorCursorProd *) tail_1183)->field0; + IntTy x_615_789_1071 = + ((Int64Int64Int64CursorCursorProd *) tail_1183)->field1; + IntTy x_616_790_1072 = + ((Int64Int64Int64CursorCursorProd *) tail_1183)->field2; + CursorTy x_617_791_1073 = + ((Int64Int64Int64CursorCursorProd *) tail_1183)->field3; + CursorTy x_618_792_1074 = + ((Int64Int64Int64CursorCursorProd *) tail_1183)->field4; + CursorTy y_622_796_1078 = _copy_Map_v_313(x_617_791_1073); + CursorTy y_623_797_1079 = _copy_Map_v_313(x_618_792_1074); + PtrTy tailift_1185 = + ALLOC(sizeof(Int64Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1185)->field0 = 1; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1185)->field1 = + x_614_788_1070; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1185)->field2 = + x_615_789_1071; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1185)->field3 = + x_616_790_1072; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1185)->field4 = + y_622_796_1078; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1185)->field5 = + y_623_797_1079; + return tailift_1185; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1182"); + exit(1); + } + } +} +unsigned char _traverse_Map_v_313(CursorTy arg_635_798_1080) +{ + TagTyPacked tag_1187 = *(TagTyPacked *) arg_635_798_1080; + CursorTy tail_1188 = arg_635_798_1080 + sizeof(IntTy); + + + switch_1189: + ; + switch (tag_1187) { + + case 0: + { + return 0; + break; + } + + case 1: + { + IntTy x_636_799_1081 = + ((Int64Int64Int64CursorCursorProd *) tail_1188)->field0; + IntTy x_637_800_1082 = + ((Int64Int64Int64CursorCursorProd *) tail_1188)->field1; + IntTy x_638_801_1083 = + ((Int64Int64Int64CursorCursorProd *) tail_1188)->field2; + CursorTy x_639_802_1084 = + ((Int64Int64Int64CursorCursorProd *) tail_1188)->field3; + CursorTy x_640_803_1085 = + ((Int64Int64Int64CursorCursorProd *) tail_1188)->field4; + unsigned char y_644_804_1086 = _traverse_Map_v_313(x_639_802_1084); + unsigned char y_645_805_1087 = _traverse_Map_v_313(x_640_803_1085); + + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1187"); + exit(1); + } + } +} +unsigned char _print_Map_v_313(CursorTy arg_646_806_1088) +{ + TagTyPacked tag_1190 = *(TagTyPacked *) arg_646_806_1088; + CursorTy tail_1191 = arg_646_806_1088 + sizeof(IntTy); + + + switch_1192: + ; + switch (tag_1190) { + + case 0: + { + unsigned char wildcard_647_807_1089 = print_symbol(1139); + unsigned char wildcard_648_808_1090 = print_symbol(1138); + + return 0; + break; + } + + case 1: + { + IntTy x_649_809_1091 = + ((Int64Int64Int64CursorCursorProd *) tail_1191)->field0; + IntTy x_650_810_1092 = + ((Int64Int64Int64CursorCursorProd *) tail_1191)->field1; + IntTy x_651_811_1093 = + ((Int64Int64Int64CursorCursorProd *) tail_1191)->field2; + CursorTy x_652_812_1094 = + ((Int64Int64Int64CursorCursorProd *) tail_1191)->field3; + CursorTy x_653_813_1095 = + ((Int64Int64Int64CursorCursorProd *) tail_1191)->field4; + unsigned char wildcard_659_814_1096 = print_symbol(1140); + unsigned char wildcard_665_815_1097 = print_symbol(1141); + unsigned char y_654_816_1098 = printf("%lld", x_649_809_1091); + unsigned char wildcard_664_817_1099 = print_symbol(1141); + unsigned char y_655_818_1100 = printf("%lld", x_650_810_1092); + unsigned char wildcard_663_819_1101 = print_symbol(1141); + unsigned char y_656_820_1102 = printf("%lld", x_651_811_1093); + unsigned char wildcard_662_821_1103 = print_symbol(1141); + unsigned char y_657_822_1104 = _print_Map_v_313(x_652_812_1094); + unsigned char wildcard_661_823_1105 = print_symbol(1141); + unsigned char y_658_824_1106 = _print_Map_v_313(x_653_813_1095); + unsigned char wildcard_660_825_1107 = print_symbol(1138); + + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1190"); + exit(1); + } + } +} +CursorTy caseFn_666(IntTy x1_72_667_826_1108, IntTy k1_71_668_827_1109, + CursorTy t1_73_669_828_1110, CursorTy m1_79_670_829_1111, + IntTy k2_77_671_830_1112, IntTy x2_78_672_831_1113, + CursorTy t4_80_673_832_1114) +{ + TagTyPacked tag_1193 = *(TagTyPacked *) m1_79_670_829_1111; + CursorTy tail_1194 = m1_79_670_829_1111 + sizeof(IntTy); + + + switch_1195: + ; + switch (tag_1193) { + + case 1: + { + IntTy wildcard__144_81_833_1115 = + ((Int64Int64Int64CursorCursorProd *) tail_1194)->field0; + IntTy k3_82_834_1116 = + ((Int64Int64Int64CursorCursorProd *) tail_1194)->field1; + IntTy x3_83_835_1117 = + ((Int64Int64Int64CursorCursorProd *) tail_1194)->field2; + CursorTy t2_84_836_1118 = + ((Int64Int64Int64CursorCursorProd *) tail_1194)->field3; + CursorTy t3_85_837_1119 = + ((Int64Int64Int64CursorCursorProd *) tail_1194)->field4; + CursorTy fltAppE_905_1120 = + bin_322(k1_71_668_827_1109, x1_72_667_826_1108, t1_73_669_828_1110, t2_84_836_1118); + CursorTy fltAppE_906_1121 = + bin_322(k2_77_671_830_1112, x2_78_672_831_1113, t3_85_837_1119, t4_80_673_832_1114); + + return bin_322(k3_82_834_1116, x3_83_835_1117, fltAppE_905_1120, + fltAppE_906_1121); + break; + } + + case 0: + { + return empty_321(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1193"); + exit(1); + } + } +} +CursorTy caseFn_674(IntTy x1_57_675_838_1122, IntTy k1_56_676_839_1123, + CursorTy t4_59_677_840_1124, CursorTy m1_65_678_841_1125, + IntTy k2_62_679_842_1126, IntTy x2_63_680_843_1127, + CursorTy t1_64_681_844_1128) +{ + TagTyPacked tag_1196 = *(TagTyPacked *) m1_65_678_841_1125; + CursorTy tail_1197 = m1_65_678_841_1125 + sizeof(IntTy); + + + switch_1198: + ; + switch (tag_1196) { + + case 1: + { + IntTy wildcard__168_66_845_1129 = + ((Int64Int64Int64CursorCursorProd *) tail_1197)->field0; + IntTy k3_67_846_1130 = + ((Int64Int64Int64CursorCursorProd *) tail_1197)->field1; + IntTy x3_68_847_1131 = + ((Int64Int64Int64CursorCursorProd *) tail_1197)->field2; + CursorTy t2_69_848_1132 = + ((Int64Int64Int64CursorCursorProd *) tail_1197)->field3; + CursorTy t3_70_849_1133 = + ((Int64Int64Int64CursorCursorProd *) tail_1197)->field4; + CursorTy fltAppE_907_1134 = + bin_322(k2_62_679_842_1126, x2_63_680_843_1127, t1_64_681_844_1128, t2_69_848_1132); + CursorTy fltAppE_908_1135 = + bin_322(k1_56_676_839_1123, x1_57_675_838_1122, t3_70_849_1133, t4_59_677_840_1124); + + return bin_322(k3_67_846_1130, x3_68_847_1131, fltAppE_907_1134, + fltAppE_908_1135); + break; + } + + case 0: + { + return empty_321(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1196"); + exit(1); + } + } +} +int __main_expr() +{ + add_symbol(1138, ")"); + add_symbol(1139, "(Tip_v_313"); + add_symbol(1140, "(Bin_v_313"); + add_symbol(1141, " "); + add_symbol(1142, "\n"); + + CursorTy fltAppE_850_909 = singleton_312(0, 0); + CursorTy m_25_682_910 = build(0, 512, fltAppE_850_909); + IntTy timed_1136; + VectorTy *times_3 = vector_alloc(global_iters_param, sizeof(double)); + struct timespec begin_timed_1136; + struct timespec end_timed_1136; + + for (long long iters_timed_1136 = 0; iters_timed_1136 < global_iters_param; + iters_timed_1136++) { + if (iters_timed_1136 != global_iters_param - 1) + save_alloc_state(); + clock_gettime(CLOCK_MONOTONIC_RAW, &begin_timed_1136); + + IntTy timed_1136hack = sumRight(m_25_682_910); + + timed_1136 = timed_1136hack; + clock_gettime(CLOCK_MONOTONIC_RAW, &end_timed_1136); + if (iters_timed_1136 != global_iters_param - 1) + restore_alloc_state(); + + double itertime_0 = difftimespecs(&begin_timed_1136, &end_timed_1136); + + vector_inplace_update(times_3, iters_timed_1136, &itertime_0); + } + vector_inplace_sort(times_3, compare_doubles); + + double *tmp_4 = (double *) vector_nth(times_3, global_iters_param / 2); + double selftimed_2 = *tmp_4; + double batchtime_1 = sum_timing_array(times_3); + + print_timing_array(times_3); + printf("ITERS: %lld\n", global_iters_param); + printf("SIZE: %lld\n", global_size_param); + printf("BATCHTIME: %e\n", batchtime_1); + printf("SELFTIMED: %e\n", selftimed_2); + + unsigned char wildcard__19_27_684_912 = printf("%lld", timed_1136); + unsigned char wildcard__17_28_685_913 = print_symbol(1142); + IntTy timed_1137; + VectorTy *times_8 = vector_alloc(global_iters_param, sizeof(double)); + struct timespec begin_timed_1137; + struct timespec end_timed_1137; + + for (long long iters_timed_1137 = 0; iters_timed_1137 < global_iters_param; + iters_timed_1137++) { + if (iters_timed_1137 != global_iters_param - 1) + save_alloc_state(); + clock_gettime(CLOCK_MONOTONIC_RAW, &begin_timed_1137); + + IntTy timed_1137hack = sumRight(m_25_682_910); + + timed_1137 = timed_1137hack; + clock_gettime(CLOCK_MONOTONIC_RAW, &end_timed_1137); + if (iters_timed_1137 != global_iters_param - 1) + restore_alloc_state(); + + double itertime_5 = difftimespecs(&begin_timed_1137, &end_timed_1137); + + vector_inplace_update(times_8, iters_timed_1137, &itertime_5); + } + vector_inplace_sort(times_8, compare_doubles); + + double *tmp_9 = (double *) vector_nth(times_8, global_iters_param / 2); + double selftimed_7 = *tmp_9; + double batchtime_6 = sum_timing_array(times_8); + + print_timing_array(times_8); + printf("ITERS: %lld\n", global_iters_param); + printf("SIZE: %lld\n", global_size_param); + printf("BATCHTIME: %e\n", batchtime_6); + printf("SELFTIMED: %e\n", selftimed_7); + + unsigned char wildcard__13_30_687_915 = printf("%lld", timed_1137); + unsigned char wildcard__11_31_688_916 = print_symbol(1142); + + printf("'#()"); + printf("\n"); + free_symtable(); + return 0; +} \ No newline at end of file diff --git a/benchmarks/Layouts/_Right.hs b/benchmarks/Layouts/_Right.hs new file mode 100644 index 000000000..eb9484509 --- /dev/null +++ b/benchmarks/Layouts/_Right.hs @@ -0,0 +1,28 @@ + +module Right where +import Common +import Map + +sumRight :: Map Int -> Int +sumRight m = + case m of + Tip -> 0 + Bin _ _ v l r -> sumRight(r) + v + sumRight(l) + + +build :: Int -> Int -> Map Int -> Map Int +build x sz m = + if (sz == 0) then m + else (build (x - sz/2) (sz/2) (build (x + sz/2) (sz/2) (insert x x m))) + +gibbon_main = + let m = (build 0 512 (singleton 0 0)) + --_ = printsym (quote "SUM RIGHT: ") + s0 = iterate (sumRight m) + _ = printint (s0) + _ = printsym (quote "\n") + --_ = printsym (quote "SUM RIGHT: ") + s1 = iterate (sumRight m) + _ = printint (s1) + _ = printsym (quote "\n") + in () \ No newline at end of file diff --git a/benchmarks/Layouts/_RightAndLeft.c b/benchmarks/Layouts/_RightAndLeft.c new file mode 100644 index 000000000..f926c0df2 --- /dev/null +++ b/benchmarks/Layouts/_RightAndLeft.c @@ -0,0 +1,2488 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// #include +#ifdef _WIN64 +#include +#endif +#include +#include +#include // For va_start etc +#include +#include +#include +#include +#ifdef _POINTER +#include +#endif +#ifdef _PARALLEL +#include +#include +#endif + +#define KB 1024lu +#define MB (KB * 1000lu) +#define GB (MB * 1000lu) + +#define REDIRECTION_TAG 255 +#define INDIRECTION_TAG 254 + +// Initial size of BigInfinite buffers +static long long global_init_biginf_buf_size = (4 * GB); + +// Initial size of Infinite buffers +static long long global_init_inf_buf_size = 1 * KB; + +// Maximum size of a chunk, see GitHub #110. +static long long global_inf_buf_max_chunk_size = 1 * GB; + +static long long global_size_param = 1; +static long long global_iters_param = 1; + +static char* global_benchfile_param = NULL; +static char* global_arrayfile_param = NULL; +// Number of lines in the arrayfile +static long long global_arrayfile_length_param = -1; + +// Sequential for now: +static const int num_workers = 1; + +// Count the number of regions allocated. +static long long global_region_count = 0; +static bool global_region_count_flag = false; + +#ifdef _PARALLEL +static inline void bump_global_region_count() { + __atomic_add_fetch(&global_region_count, 1, __ATOMIC_SEQ_CST); + return; +} +#else +static inline void bump_global_region_count() { + global_region_count++; + return; +} +#endif + +static inline void print_global_region_count() { + printf("REGION_COUNT: %lld\n", global_region_count); + return; +} + +#define REDIRECTION_NODE_SIZE 9 +#define MAX(a,b) (((a)>(b))?(a):(b)) +#define MIN(a,b) (((a)<(b))?(a):(b)) + +// https://www.cprogramming.com/snippets/source-code/find-the-number-of-cpu-cores-for-windows-mac-or-linux +static int get_num_processors() { +#ifdef _WIN64 + SYSTEM_INFO sysinfo; + GetSystemInfo(&sysinfo); + return sysinfo.dwNumberOfProcessors; +#else + return sysconf(_SC_NPROCESSORS_ONLN); +#endif +} + +// Requires -std=gnu11 +int dbgprintf(const char *format, ...) { + int code = 0; + va_list args; + va_start(args, format); +#ifdef _DEBUG + code = vprintf(format, args); +#endif + va_end(args); + return code; +} + + +// ----------------------------------------------------------------------------- +// Allocators +// ----------------------------------------------------------------------------- + + +// ------------------------------------- +// Bump allocation for linked-lists +// ------------------------------------- + + +#ifdef _BUMPALLOC +// #define _DEBUG +#warning "Using bump allocator." + +__thread char* bumpalloc_heap_ptr = (char*)NULL; +__thread char* bumpalloc_heap_ptr_end = (char*)NULL; + +char* saved_heap_ptr_stack[100]; +int num_saved_heap_ptr = 0; + +// For simplicity just use a single large slab: +static inline void INITBUMPALLOC() { + bumpalloc_heap_ptr = (char*)malloc(global_init_biginf_buf_size); + bumpalloc_heap_ptr_end = bumpalloc_heap_ptr + global_init_biginf_buf_size; +#ifdef _DEBUG + printf("Arena size for bump alloc: %lld\n", global_init_biginf_buf_size); + printf("BUMPALLOC/INITBUMPALLOC DONE: heap_ptr = %p\n", bumpalloc_heap_ptr); +#endif +} + +static inline void* BUMPALLOC(long long n) { + if (! bumpalloc_heap_ptr) { + INITBUMPALLOC(); + } + if (bumpalloc_heap_ptr + n < bumpalloc_heap_ptr_end) { + char* old= bumpalloc_heap_ptr; + bumpalloc_heap_ptr += n; + return old; + } else { + fprintf(stderr, "Warning: bump allocator ran out of memory."); + exit(1); + } +} + +// Snapshot the current heap pointer value across all threads. +void save_alloc_state() { + dbgprintf("Saving(%p): pos %d", heap_ptr, num_saved_heap_ptr); + saved_heap_ptr_stack[num_saved_heap_ptr] = heap_ptr; + num_saved_heap_ptr++; + dbgprintf("\n"); +} + +void restore_alloc_state() { + if(num_saved_heap_ptr <= 0) { + fprintf(stderr, "Bad call to restore_alloc_state! Saved stack empty!\ne"); + exit(1); + } + num_saved_heap_ptr--; + dbgprintf("Restoring(%p): pos %d, discarding %p", + saved_heap_ptr_stack[num_saved_heap_ptr], num_saved_heap_ptr, bumpalloc_heap_ptr); + bumpalloc_heap_ptr = saved_heap_ptr_stack[num_saved_heap_ptr]; +} + + +#else +// Regular malloc mode: +void INITBUMPALLOC() {} +void save_alloc_state() {} +void restore_alloc_state() {} + +#define BUMPALLOC(n) malloc(n) + +#endif // BUMPALLOC + + +// ------------------------------------- +// ALLOC and ALLOC_PACKED macros +// ------------------------------------- + + +/* + +If parallelism is enabled, we always use a malloc based allocator +since Boehm GC is not thread-safe in its default configuration. It can be +made thread-safe by building it with appropriate flags, but we don't do that. +Presently, all parallel pointer-based programs will leak memory. + +*/ + +#ifdef _PARALLEL +#define ALLOC(n) malloc(n) +#define ALLOC_PACKED_BIG(n) malloc(n) +char *ALLOC_COUNTED(size_t size) { + bump_global_region_count(); + return ALLOC(size); +} +#else + #ifdef _POINTER +#define ALLOC(n) GC_MALLOC(n) +#define ALLOC_PACKED_BIG(n) GC_MALLOC(n) +char *ALLOC_COUNTED(size_t size) { + bump_global_region_count(); + return GC_MALLOC(size); +} + #else +#define ALLOC(n) malloc(n) +#define ALLOC_PACKED_BIG(n) malloc(n) +char *ALLOC_COUNTED(size_t size) { + bump_global_region_count(); + return ALLOC(size); +} + #endif // _POINTER +#endif // _PARALLEL + + +// Could try alloca() here. Better yet, we could keep our own, +// separate stack and insert our own code to restore the pointer +// before any function that (may have) called ALLOC_SCOPED returns. + +// #define ALLOC_SCOPED() alloca(1024) +#define ALLOC_SCOPED(n) alloca(n) +// #define ALLOC_SCOPED() alloc_scoped() + +// Stack allocation is either too small or blows our stack. +// We need a way to make a giant stack if we want to use alloca. +// #define ALLOC_SCOPED() ALLOC(global_init_biginf_buf_size) + +// Our global pointer. No parallelism. +// static char* stack_scoped_region; +// char* alloc_scoped() { return stack_scoped_region; } + + + +// ------------------------------------- +// Basic types +// ------------------------------------- + +// Must be consistent with sizeOfTy defined in Gibbon.Language.Syntax. + +typedef unsigned char TagTyPacked; +typedef unsigned char TagTyBoxed; +typedef long long IntTy; +typedef char CharTy; +typedef float FloatTy; +typedef unsigned long long SymTy; +typedef bool BoolTy; +typedef char* PtrTy; +typedef char* CursorTy; + +// ------------------------------------- +// Arenas and dictionaries +// ------------------------------------- + +typedef struct mem_arena { + int ind; + char* mem; // TODO(vollmerm): make this a list of chunks? + void* reflist; +} mem_arena_t; + +typedef mem_arena_t* ArenaTy; + +ArenaTy alloc_arena() { + ArenaTy ar = ALLOC(sizeof(mem_arena_t)); + ar->ind = 0; + ar->mem = malloc(global_inf_buf_max_chunk_size); + ar->reflist = 0; + return ar; +} + +void free_arena(ArenaTy ar) { + free(ar->mem); + // TODO(vollmerm): free everything in ar->reflist + free(ar); +} + +CursorTy extend_arena(ArenaTy ar, int size) { + CursorTy ret = ar->mem + ar->ind; + ar->ind += size; + return ret; +} + +typedef struct dict_item { + struct dict_item * next; + int key; + void * ptrval; +} dict_item_t; + +dict_item_t * dict_alloc(ArenaTy ar) { + return (dict_item_t *) extend_arena(ar, sizeof(dict_item_t)); // ALLOC(sizeof(dict_item_t)); +} + +dict_item_t *dict_insert_ptr(ArenaTy ar, dict_item_t *ptr, SymTy key, PtrTy val) { + dict_item_t *ret = dict_alloc(ar); + ret->key = key; + ret->ptrval = val; + ret->next = ptr; + return ret; +} + +PtrTy dict_lookup_ptr(dict_item_t *ptr, SymTy key) { + while (ptr != 0) { + if (ptr->key == key) { + return ptr->ptrval; + } else { + ptr = ptr->next; + } + } + printf("Error, key %lld not found!\n",key); + exit(1); +} + +// ------------------------------------- +// Sets +// ------------------------------------- + + +struct set_elem { + int val; + UT_hash_handle hh; +}; + +typedef struct set_elem* SymSetTy; + +SymSetTy empty_set() { + return NULL; +} + +SymSetTy insert_set(SymSetTy set, int sym) { + SymSetTy s; + HASH_FIND_INT(set, &sym, s); /* sym already in the hash? */ + if (s==NULL) { + s = malloc(sizeof(struct set_elem)); + s->val = sym; + HASH_ADD_INT(set,val,s); + } + return set; +} + +BoolTy contains_set(SymSetTy set, int sym) { + SymSetTy s; + HASH_FIND_INT(set, &sym, s); + return (s!=NULL); +} + +// ------------------------------------- +// Sym Hash +// ------------------------------------- + +struct sym_hash_elem { + int key; + int val; + UT_hash_handle hh; +}; + +typedef struct sym_hash_elem* SymHashTy; + +typedef struct sym_hash_elem* IntHashTy; + +SymHashTy empty_hash() { + return NULL; +} + +SymHashTy insert_hash(SymHashTy hash, int k, int v) { + SymHashTy s; + // NOTE: not checking for duplicates! + // s = malloc(sizeof(struct sym_hash_elem)); + s = ALLOC(sizeof(struct sym_hash_elem)); + s->val = v; + s->key = k; + HASH_ADD_INT(hash,key,s); + + return hash; +} + +IntTy lookup_hash(SymHashTy hash, int k) { + SymHashTy s; + HASH_FIND_INT(hash,&k,s); + if (s==NULL) { + return k; // NOTE: return original key if val not found + // TODO(vollmerm): come up with something better to do here + } else { + return s->val; + } +} + +BoolTy contains_hash(SymHashTy hash, int sym) { + SymHashTy s; + HASH_FIND_INT(hash,&sym,s); + return (s!=NULL); +} + +// ------------------------------------- +// Helpers +// ------------------------------------- + +char* read_benchfile_param() { + if (global_benchfile_param == NULL) { + fprintf(stderr, "read_benchfile_param: benchmark input file was not set! Set using --bench-input.\n"); + exit(1); + } else + return global_benchfile_param; +} + +char* read_arrayfile_param() { + if (global_arrayfile_param == NULL) { + fprintf(stderr, "read_arrayfile_param: array input file was not set! Set using --array-input.\n"); + exit(1); + } else + return global_arrayfile_param; +} + +IntTy read_arrayfile_length_param() { + if (global_arrayfile_length_param == -1) { + fprintf(stderr, "read_arrayfile_length_param: array input file length was not set! Set using --array-input-length.\n"); + exit(1); + } else + return global_arrayfile_length_param; +} + + +// fun fact: __ prefix is actually reserved and this is an undefined behavior. +// These functions must be provided by the code generator. +int __main_expr(); + + +void show_usage(char** argv) +{ + printf("\n"); + printf("This binary was generated by the Gibbon compiler.\n"); + printf("\n"); + printf("Usage: %s [OPTS] [size] [iters]\n", argv[0]); + + printf("\n"); + printf("Options:\n"); + printf(" --buffer-size Set the buffer size (default %lld).\n", global_init_biginf_buf_size); + printf(" --bench-input Set the input file read for benchmarking. Applies only\n"); + printf(" IF the program was *compiled* with --bench-fun. \n"); + return; +} + +double avg(const double* arr, int n) +{ + double sum = 0.0; + for(int i=0; itv_sec - t0->tv_sec) + + ((double)(t1->tv_nsec - t0->tv_nsec) / 1000000000.0); +} + +int compare_doubles(const void *a, const void *b) +{ + const double *da = (const double *) a; + const double *db = (const double *) b; + return (*da > *db) - (*da < *db); +} + +// Exponentiation +IntTy expll(IntTy base, IntTy pow) { + if (base == 2) { + return (1 << pow); + } else { + IntTy i, result = 1; + for (i = 0; i < pow; i++) + result *= base; + return result; + } + } + +// ------------------------------------- +// Symbol table +// ------------------------------------- + +#define global_max_symbol_len 256 + +// Invariant: should always be equal to max(sym_table_keys) +static SymTy global_gensym_counter = 0; + +// Its value is updated by the flags parser. +static char *global_bench_prog_param; + +static SymTy newline_symbol = -1; +static SymTy space_symbol = -1; +static SymTy comma_symbol = -1; +static SymTy leftparen_symbol = -1; +static SymTy rightparen_symbol = -1; + +typedef struct SymTable_elem { + SymTy idx; /* key */ + char value[global_max_symbol_len]; + UT_hash_handle hh; /* makes this structure hashable */ +} SymTable_elem; + +// important! initialize to NULL +SymTable_elem *global_sym_table = NULL; + +void add_symbol(SymTy idx, char *value) { + struct SymTable_elem *s; + s = ALLOC(sizeof(struct SymTable_elem)); + s->idx = idx; + strcpy(s->value, value); + HASH_ADD(hh, global_sym_table, idx, sizeof(IntTy), s); + if (idx > global_gensym_counter) { + global_gensym_counter = idx; + } +} + +void set_newline(SymTy idx) { + newline_symbol = idx; + add_symbol(idx,"NEWLINE"); +} + +void set_space(SymTy idx) { + space_symbol = idx; + add_symbol(idx,"SPACE"); +} + +void set_comma(SymTy idx) { + comma_symbol = idx; + add_symbol(idx,"COMMA"); +} + +void set_leftparen(SymTy idx) { + leftparen_symbol = idx; + add_symbol(idx,"LEFTPAREN"); +} + +void set_rightparen(SymTy idx) { + rightparen_symbol = idx; + add_symbol(idx,"RIGHTPAREN"); +} + +IntTy print_symbol(SymTy idx) { + if (idx == comma_symbol) { + return printf(","); + } else if (idx == newline_symbol) { + return printf("\n"); + } else if (idx == space_symbol) { + return printf(" "); + } else if (idx == leftparen_symbol) { + return printf("("); + } else if (idx == rightparen_symbol) { + return printf(")"); + } else { + struct SymTable_elem *s; + HASH_FIND(hh, global_sym_table, &idx, sizeof(SymTy), s); + if (s == NULL) { + return printf("%lld", idx); + } else { + return printf("%s", s->value); + } + + } +} + +#ifdef _PARALLEL +SymTy gensym() { + SymTy idx = __atomic_add_fetch(&global_gensym_counter, 1, __ATOMIC_SEQ_CST); + return idx; +} +#else +SymTy gensym() { + global_gensym_counter += 1; + SymTy idx = global_gensym_counter; + return idx; +} +#endif + +void free_symtable() { + struct SymTable_elem *elt, *tmp; + HASH_ITER(hh, global_sym_table, elt, tmp) { + HASH_DEL(global_sym_table,elt); + } + free(elt); + free(tmp); +} + +/* + +---------------------------------------- +Garbage collection +---------------------------------------- + + Gibbon has "growing regions" i.e each logical region is backed by a doubly linked-list + of smaller chunks which grows as required. In addition to actual data, each chunk + stores some additional metadata (RegionFooter) to chain the chunks together in a list + and for garbage collection. The footer: + + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + serialized data | rf_reg_metadata_ptr | rf_seq_no | rf_size | rf_next | rf_prev + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + The metadata after the serialized data serves various purposes: + + - rf_reg_metadata_ptr: A pointer to a RegionTy struct that contains various metadata. + Of particular interest to us are the fields: + + = reg_id: A unique identifier for a region. + + = refcount and outset: Whenever an inter-region indirection is created, we record that information + using these two fields. Suppose we have an indirection from region A that points to some chunk + in region B. Then A's outset will store a pointer to that chunk's footer, and B's refcount will + be bumped by 1. Note that all there's only 1 refcount cell, and 1 outset per logical region, + and chunks only store a pointer to them. + + - rf_seq_no: The index of this particular chunk in the list. + + - rf_size: Used during bounds checking to calculate the size of the next region in + the linked list. + + - rf_next / rf_prev: Point to the next and previous chunk respectively. + + +There are two ways in which a region may be freed: + +(1) Whenever it goes out of scope + + The RTS tries to free a region whenever it goes out of scope. But this doesn't always succeed as + regions sometimes contain values that "escape". One reason why this'll happen is if there's an + indirection from A->B, and A lives longer than B. + In such a case, when B goes out of scope it's refcount won't be 0, and the RTS won't free it. + This brings us to (2). + +(2) + + When the RTS successfully frees a region, it decrements the refcounts of all the regions it + points to (via the outset). At the same time, if it encounters a region in the outset whoose + refcount becomes 0 after the decrement, it calls free_region on that. This way we can be sure + that all regions will eventually be garbage collected before the program exits. + + + +Why is it a doubly linked-list? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Due to way that bounds-checking works, the pointers in the outset may actually point to any +arbitrary chunk in the chain. However, we must call free_region on the first one to ensure that +all of them are GC'd. So we need pointers to traverse backward get to the first one. +'trav_to_first_chunk' accomplishes this. + + */ + +#define MAX_OUTSET_LENGTH 10 + +typedef struct RegionTy_struct { + SymTy reg_id; + uint reg_refcount; + CursorTy reg_heap; + uint reg_outset_len; + CursorTy reg_outset[MAX_OUTSET_LENGTH]; +} RegionTy; + +typedef struct RegionFooter_struct { + RegionTy *rf_reg_metadata_ptr; + + IntTy rf_seq_no; + IntTy rf_size; + struct RegionFooter_struct *rf_next; + struct RegionFooter_struct *rf_prev; +} RegionFooter; + +typedef struct ChunkTy_struct { + CursorTy chunk_start; + CursorTy chunk_end; +} ChunkTy; + +static inline void insert_into_outset(CursorTy ptr, RegionTy *reg) { + uint outset_len = reg->reg_outset_len; + // Check for duplicates. + for (uint i = 0; i < outset_len; i++) { + if (ptr == reg->reg_outset[i]) { + return; + } + } + // Otherwise, insert into the outset. + reg->reg_outset[outset_len] = ptr; + reg->reg_outset_len = outset_len + 1; + return; +} + +static inline void remove_from_outset(CursorTy ptr, RegionTy *reg) { + uint outset_len = reg->reg_outset_len; + CursorTy *outset = reg->reg_outset; + int i; + if (outset_len == 0) { + fprintf(stderr, "remove_from_outset: empty outset\n"); + exit(1); + } + // Position of 'ptr' in the outset. + int elt_idx = -1; + for (i = 0; i < outset_len; i++) { + if (ptr == outset[i]) { + elt_idx = i; + } + } + if (elt_idx == -1) { + fprintf(stderr, "remove_from_outset: element not found\n"); + exit(1); + } + // Move all elements ahead of 'elt_idx' back by one position. + for (i = elt_idx; i < outset_len; i++) { + outset[i] = outset[i+1]; + } + return; +} + +RegionTy *alloc_region(IntTy size) { + // Allocate the region metadata. + RegionTy *reg = ALLOC(sizeof(RegionTy)); + if (reg == NULL) { + printf("alloc_region: allocation failed: %ld", sizeof(RegionTy)); + exit(1); + } + + // Allocate the first chunk. + IntTy total_size = size + sizeof(RegionFooter); + CursorTy heap = ALLOC_PACKED_BIG(total_size); + if (heap == NULL) { + printf("alloc_region: malloc failed: %lld", total_size); + exit(1); + } + // Not heap+total_size, since we must keep space for the footer. + CursorTy heap_end = heap + size; + + // Initialize metadata fields. + reg->reg_id = gensym(); + reg->reg_refcount = 1; + reg->reg_heap = heap; + reg->reg_outset_len = 0; + +#ifdef _DEBUG + printf("Allocated a region(%lld): %lld bytes.\n", reg->reg_id, size); +#endif + + // Write the footer. + RegionFooter *footer = (RegionFooter *) heap_end; + footer->rf_reg_metadata_ptr = reg; + footer->rf_seq_no = 1; + footer->rf_size = size; + footer->rf_next = NULL; + footer->rf_prev = NULL; + + return reg; +} + +RegionTy *alloc_counted_region(IntTy size) { + // Bump the count. + bump_global_region_count(); + return alloc_region(size); +} + +ChunkTy alloc_chunk(CursorTy end_old_chunk) { + // Get size from current footer. + RegionFooter *footer = (RegionFooter *) end_old_chunk; + IntTy newsize = footer->rf_size * 2; + // See #110. + if (newsize > global_inf_buf_max_chunk_size) { + newsize = global_inf_buf_max_chunk_size; + } + IntTy total_size = newsize + sizeof(RegionFooter); + + // Allocate. + CursorTy start = ALLOC_PACKED_BIG(total_size); + if (start == NULL) { + printf("alloc_chunk: malloc failed: %lld", total_size); + exit(1); + } + CursorTy end = start + newsize; + + // Link the next chunk's footer. + footer->rf_next = (RegionFooter *) end; + + // Write the footer. + RegionFooter* new_footer = (RegionFooter *) end; + new_footer->rf_reg_metadata_ptr = footer->rf_reg_metadata_ptr; + new_footer->rf_seq_no = footer->rf_seq_no + 1; + new_footer->rf_size = newsize; + new_footer->rf_next = NULL; + new_footer->rf_prev = footer; + +#ifdef _DEBUG + RegionTy *reg = (RegionTy*) new_footer->rf_reg_metadata_ptr; + printf("alloc_chunk: allocated %lld bytes for region %lld.\n", total_size, reg->reg_id); +#endif + + return (ChunkTy) {start , end}; +} + +RegionFooter* trav_to_first_chunk(RegionFooter *footer) { + if (footer->rf_seq_no == 1) { + return footer; + } else if (footer->rf_prev == NULL) { + fprintf(stderr, "No previous chunk found at rf_seq_no: %lld", footer->rf_seq_no); + return NULL; + } else { + trav_to_first_chunk((RegionFooter *) footer->rf_prev); + } + return NULL; +} + +uint get_ref_count(CursorTy end_ptr) { + RegionFooter *footer = (RegionFooter *) end_ptr; + RegionTy *reg = (RegionTy *) footer->rf_reg_metadata_ptr; + return reg->reg_refcount; +} + +// B is the pointer, and A is the pointee (i.e B -> A). +// Bump A's refcount and update B's outset. +static inline void bump_ref_count(CursorTy end_b, CursorTy end_a) { + // Grab footers. + RegionFooter *footer_a = (RegionFooter *) end_a; + RegionFooter *footer_b = (RegionFooter *) end_b; + + // Grab metadata. + RegionTy *reg_a = (RegionTy *) footer_a->rf_reg_metadata_ptr; + RegionTy *reg_b = (RegionTy *) footer_b->rf_reg_metadata_ptr; + + // Bump A's refcount. + uint current_refcount, new_refcount; + current_refcount = reg_a->reg_refcount; + new_refcount = current_refcount + 1; + reg_a->reg_refcount = new_refcount; + +#ifdef _DEBUG + printf("bump_ref_count: %lld -> %lld\n", reg_b->reg_id, reg_a->reg_id); + printf("bump_ref_count: old-refcount=%d, old-outset-len=%d:\n", current_refcount, reg_b->reg_outset_len); + assert(current_refcount == reg_b->reg_outset_len+1); +#endif + + // Add A to B's outset. + insert_into_outset(end_a, reg_b); + +#ifdef _DEBUG + // printf("bump_ref_count: Added %p to %lld's outset, %p.\n", end_a, reg_b->reg_id, reg_b); + printf("bump_ref_count: new-refcount=%d, new-outset-len=%d\n", new_refcount, reg_b->reg_outset_len); + assert(new_refcount == reg_b->reg_outset_len+1); +#endif + + return; +} + +void free_region(CursorTy end_reg) { + // Grab footer and the metadata. + RegionFooter *footer = (RegionFooter *) end_reg; + RegionTy *reg = (RegionTy *) footer->rf_reg_metadata_ptr; + + // + RegionFooter *first_chunk_footer, *next_chunk_footer; + CursorTy first_chunk, next_chunk; + + // Decrement current reference count. + uint current_refcount, new_refcount; + current_refcount = reg->reg_refcount; + new_refcount = 0; + if (current_refcount != 0) { + new_refcount = current_refcount - 1; + reg->reg_refcount = new_refcount; + } + +#ifdef _DEBUG + printf("free_region(%lld): refcounts (1): old-refcount=%d, new-refcount=%d:\n", reg->reg_id, current_refcount, new_refcount); +#endif + + + // Free this region recount is 0. + if (new_refcount == 0) { + +#ifdef _DEBUG + printf("free_region(%lld): outset length: %d\n", reg->reg_id, reg->reg_outset_len); +#endif + + // Decrement refcounts, free regions with refcount==0 and also free + // elements of the outset. + if (reg->reg_outset_len != 0) { + uint outset_len = reg->reg_outset_len; + CursorTy *outset = reg->reg_outset; + RegionFooter *elt_footer; + RegionTy *elt_reg; + uint elt_current_refcount, elt_new_refcount; + CursorTy to_be_removed[MAX_OUTSET_LENGTH]; + uint to_be_removed_idx = 0; + for (int i = 0; i < outset_len; i++) { + elt_footer = (RegionFooter *) outset[i]; + elt_reg = (RegionTy *) elt_footer->rf_reg_metadata_ptr; +#ifdef _DEBUG + elt_current_refcount = elt_reg->reg_refcount; +#endif + elt_new_refcount = elt_current_refcount - 1; + elt_reg->reg_refcount = elt_new_refcount; +#ifdef _DEBUG + printf("free_region(%lld): old-refcount=%d, new-refcount=%d:\n", + elt_reg->reg_id, elt_current_refcount, elt_reg->reg_refcount); +#endif + if (elt_new_refcount == 0) { + // See [Why is it a doubly linked-list?] above + first_chunk_footer = trav_to_first_chunk(elt_footer); + if (first_chunk_footer != NULL) { + free_region((CursorTy) first_chunk_footer); + } + } + to_be_removed[to_be_removed_idx] = outset[i]; + to_be_removed_idx++; + } + // Remove elements from the outset. + for (uint i = 0; i < to_be_removed_idx; i++) { + remove_from_outset(to_be_removed[i], reg); + } + } + + +#ifdef _DEBUG + // Bookkeeping + IntTy num_freed_chunks = 0, total_bytesize = 0; +#endif + + // Free the chunks in this region. + first_chunk = end_reg - footer->rf_size; + first_chunk_footer = footer; + next_chunk = (char*) footer->rf_next; + +#ifdef _DEBUG + printf("free_region(%lld)\n", reg->reg_id); +#endif + +#ifdef _DEBUG + num_freed_chunks++; + total_bytesize = total_bytesize + first_chunk_footer->rf_size; +#endif + free(first_chunk); + + while (next_chunk != NULL) { + next_chunk_footer = (RegionFooter *) next_chunk; + #ifdef _DEBUG + num_freed_chunks++; + total_bytesize = total_bytesize + next_chunk_footer->rf_size; + #endif + free(next_chunk - next_chunk_footer->rf_size); + next_chunk = (char*) next_chunk_footer->rf_next; + } + +#ifdef _DEBUG + printf("free_region(%lld): Freed %lld bytes across %lld chunks.\n", + reg->reg_id, total_bytesize, num_freed_chunks); +#endif + + // Free the metadata. + free(reg); + + } else { +#ifdef _DEBUG + printf("free_region(%lld): non-zero refcount: %d.\n", + reg->reg_id, reg->reg_refcount); +#endif + } +} + +// Assume that all nodes with size information have tags >= 150. +BoolTy is_big(IntTy i, CursorTy cur) { + TagTyPacked tag = *(TagTyPacked *) cur; + if (tag >= 150) { + cur += 1; + IntTy size = *(IntTy *) cur; + if (size >= i) { + return true; + } else { + return false; + } + } + return false; +} + +// ------------------------------------- +// Vectors +// ------------------------------------- + +typedef struct VectorTy_struct { + // Bounds on the vector. + IntTy vec_lower, vec_upper; + + // Size of each element. + IntTy vec_elt_size; + + // Actual elements of the vector. + void* vec_data; +} VectorTy; + +VectorTy* vector_alloc(IntTy num, IntTy elt_size) { + VectorTy *vec = ALLOC(sizeof(VectorTy)); + if (vec == NULL) { + printf("alloc_vector: malloc failed: %ld", sizeof(VectorTy)); + exit(1); + } + void* data = ALLOC(num * elt_size); + if (data == NULL) { + printf("alloc_vector: malloc failed: %ld", sizeof(num * elt_size)); + exit(1); + } + vec->vec_lower = 0; + vec->vec_upper = num; + vec->vec_elt_size = elt_size; + vec->vec_data = data; + return vec; +} + +IntTy vector_length(VectorTy *vec) { + return (vec->vec_upper - vec->vec_lower); +} + +BoolTy vector_is_empty(VectorTy *vec) { + return (vector_length(vec) == 0); +} + +VectorTy* vector_slice(IntTy i, IntTy n, VectorTy *vec) { + IntTy lower = vec->vec_lower + i; + IntTy upper = vec->vec_lower + i + n; + if ((lower > vec->vec_upper)) { + printf("vector_slice: lower out of bounds, %lld > %lld", lower, vec->vec_upper); + exit(1); + } + if ((upper > vec->vec_upper)) { + printf("vector_slice: upper out of bounds: %lld > %lld", upper, vec->vec_upper); + exit(1); + } + VectorTy *vec2 = ALLOC(sizeof(VectorTy)); + if (vec == NULL) { + printf("vector_slice: malloc failed: %ld", sizeof(VectorTy)); + exit(1); + } + vec2->vec_lower = lower; + vec2->vec_upper = upper; + vec2->vec_elt_size = vec->vec_elt_size; + vec2->vec_data = vec->vec_data; + return vec2; +} + +// The callers must cast the return value. +static inline void* vector_nth(VectorTy *vec, IntTy i) { + // if (i < vec->lower || i > vec->upper) { + // printf("vector_nth index out of bounds: %lld (%lld,%lld) \n", i, vec->vec_lower, vec->vec_upper); + // exit(1); + // } + return (vec->vec_data + (vec->vec_elt_size * (vec->vec_lower + i))); +} + +static inline VectorTy* vector_inplace_update(VectorTy *vec, IntTy i, void* elt) { + void* dst = vector_nth(vec, i); + memcpy(dst, elt, vec->vec_elt_size); + return vec; +} + +static inline VectorTy* vector_copy(VectorTy *vec) { + IntTy len = vector_length(vec); + void *start = vector_nth(vec, 0); + VectorTy *vec2 = vector_alloc(len, vec->vec_elt_size); + memcpy(vec2->vec_data, start, len * vec->vec_elt_size); + return vec2; +} + +static inline VectorTy* vector_inplace_sort(VectorTy *vec, int (*compar)(const void *, const void*)) { + void *start = vector_nth(vec, 0); + qsort(start, vector_length(vec), vec->vec_elt_size, compar); + return vec; +} + +static inline VectorTy* vector_sort(VectorTy *vec, int (*compar)(const void *, const void*)) { + VectorTy *vec2 = vector_copy(vec); + vector_inplace_sort(vec2, compar); + return vec2; +} + +static inline VectorTy* vector_concat(VectorTy *vec) { + // Length of the input vector. + IntTy len = vector_length(vec); + // Length of the concatenated vector. + IntTy result_len = 0; + // Size of each element in the concatenated vector. + IntTy result_elt_size = 0; + VectorTy **elt_ref, *elt; + for (IntTy i = 0; i < len; i++) { + elt_ref = vector_nth(vec, i); + elt = *elt_ref; + result_elt_size = elt->vec_elt_size; + result_len += vector_length(elt); + } + + // Concatenated vector. + VectorTy *result = vector_alloc(result_len, result_elt_size); + IntTy elt_len; + // A counter that tracks the index of elements in 'result'. + IntTy k = 0; + for (IntTy i = 0; i < len; i++) { + elt_ref = vector_nth(vec, i); + elt = *elt_ref; + elt_len = vector_length(elt); + + for (IntTy j = 0; j < elt_len; j++) { + void* k_elt = vector_nth(elt, j); + vector_inplace_update(result, k, k_elt); + k++; + } + } + + return result; +} + +static inline void vector_free(VectorTy *vec) { + free(vec->vec_data); + free(vec); + return; +} + +static inline VectorTy* vector_merge(VectorTy *vec1, VectorTy *vec2) { + if (vec1->vec_upper != vec2->vec_lower) { + printf("vector_merge: non-contiguous slices, (%lld,%lld), (%lld,%lld).", + vec1->vec_lower, vec1->vec_upper, vec2->vec_lower, vec2->vec_upper); + exit(1); + } + VectorTy *merged = ALLOC(sizeof(VectorTy)); + if (merged == NULL) { + printf("vector_merge: malloc failed: %ld", sizeof(VectorTy)); + exit(1); + } + merged->vec_lower = vec1->vec_lower; + merged->vec_upper = vec2->vec_upper; + merged->vec_elt_size = vec1->vec_elt_size; + merged->vec_data = vec1->vec_data; + return merged; +} + +void print_timing_array(VectorTy *times) { + printf("TIMES: ["); + double *d; + IntTy n = vector_length(times); + for(int i = 0; i < n; i++) { + d = vector_nth(times, i); + if (i == (n-1)) { + printf("%f",*d); + } + else { + printf("%f, ",*d); + } + } + printf("]\n"); +} + +double sum_timing_array(VectorTy *times) { + double *d; + double acc = 0; + for(int i = 0; i < vector_length(times); i++) { + d = vector_nth(times, i); + acc += *d; + } + return acc; +} + +// ------------------------------------- +// Linked lists +// ------------------------------------- + +typedef struct ListTy_struct { + IntTy ll_data_size; + void* ll_data; + struct ListTy_struct* ll_next; +} ListTy; + +static inline ListTy* list_alloc(IntTy data_size) { + // ListTy *ls = ALLOC(sizeof(ListTy)); + ListTy *ls = BUMPALLOC(sizeof(ListTy)); + ls->ll_data_size = data_size; + ls->ll_data = NULL; + ls->ll_next = NULL; + return ls; +} + +static inline BoolTy list_is_empty(ListTy *ls) { + return ls->ll_next == NULL; +} + +static inline ListTy* list_cons(void* elt, ListTy *ls) { + // void* data = ALLOC(ls->data_size); + void* data = BUMPALLOC(ls->ll_data_size); + if (data == NULL) { + printf("list_cons: malloc failed: %lld", ls->ll_data_size); + exit(1); + } + memcpy(data, elt, ls->ll_data_size); + // ListTy *res = ALLOC(sizeof(ListTy)); + ListTy *res = BUMPALLOC(sizeof(ListTy)); + res->ll_data_size = ls->ll_data_size; + res->ll_data = data; + res->ll_next = (ListTy*) ls; + return res; +} + +static inline void* list_head(ListTy *ls) { + return ls->ll_data; +} + +static inline ListTy* list_tail(ListTy *ls) { + return ls->ll_next; +} + +static inline void list_free(ListTy *ls) { + free(ls->ll_data); + free(ls); + return; +} + +static inline ListTy* list_copy(ListTy *ls) { + ListTy *ls2 = list_alloc(ls->ll_data_size); + if (ls->ll_data != NULL) { + void* data = BUMPALLOC(ls->ll_data_size); + memcpy(data, ls->ll_data, ls->ll_data_size); + ls2->ll_data = data; + } + ls2->ll_next = ls->ll_next; + return ls2; +} + +// ------------------------------------- +// Ppm Images +// ------------------------------------- + +typedef struct __Pixel_struct { + IntTy field0; + IntTy field1; + IntTy field2; +} __Pixel; + +void writePpm(char* filename, IntTy width, IntTy height, VectorTy *pixels); +void writePpm_loop(FILE *fp, IntTy idx, IntTy end, VectorTy *pixels); + +// Example: writePpm("gibbon_rgb_1000.ppm", 1000, 1000, pixels); +void writePpm(char* filename, IntTy width, IntTy height, VectorTy *pixels) +{ + FILE *fp; + fp = fopen(filename, "w+"); + fprintf(fp, "P3\n"); + fprintf(fp, "%lld %lld\n255\n", width, height); + IntTy len = vector_length(pixels); + writePpm_loop(fp, 0, len, pixels); + fclose(fp); + return; +} + +void writePpm_loop(FILE *fp, IntTy idx, IntTy end, VectorTy *pixels) +{ + BoolTy fltIf_5768_6575 = idx == end; + + if (fltIf_5768_6575) { + return; + } else { + __Pixel *tmp_112; + tmp_112 = (__Pixel *) vector_nth(pixels, idx); + __Pixel tup = *tmp_112; + IntTy x = tup.field0; + IntTy y = tup.field1; + IntTy z = tup.field2; + // write to file. + fprintf(fp, "%lld %lld %lld\n", x, y, z); + writePpm_loop(fp, (idx+1), end, pixels); + } +} + +/* -------------------------------------------------------------------------------- */ + +int main(int argc, char** argv) +{ + // parameters to parse: + // + // num iterations: How many times to repeat a benchmark. + // tree size: An integer passes to `build_tree()`. + + struct rlimit lim; + int code; + if ( (code = getrlimit(RLIMIT_STACK, &lim)) ) { + fprintf(stderr, " [gibbon rts] failed to getrlimit, code %d\n", code); + exit(1); + } + + // lim.rlim_cur = 1024LU * 1024LU * 1024LU; // 1GB stack. + lim.rlim_cur = 512LU * 1024LU * 1024LU; // 500MB stack. + // lim.rlim_max = lim.rlim_cur; // Normal users may only be able to decrease this. + + // WARNING: Haven't yet figured out why this doesn't work on MacOS... +#ifndef __APPLE__ + code = setrlimit(RLIMIT_STACK, &lim); + while (code) { + fprintf(stderr, " [gibbon rts] Failed to set stack size to %llu, code %d\n", (unsigned long long)lim.rlim_cur, code); + lim.rlim_cur /= 2; + // lim.rlim_max /= 2; + if(lim.rlim_cur < 100 * 1024) { + fprintf(stderr, " [gibbon rts] Failed setrlimit stack size to something reasonable; giving up.\n"); + break; // abort(); + } + int code = setrlimit(RLIMIT_STACK, &lim); + } +#endif + + int got_numargs = 0; // How many numeric arguments have we got. + + int i; + for (i = 1; i < argc; ++i) + { + if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) { + show_usage(argv); + exit(0); + } + else if (strcmp(argv[i], "--biginf-buffer-size") == 0 && i < argc - 1) + { + global_init_biginf_buf_size = atoll(argv[i + 1]); + i++; + } + else if (strcmp(argv[i], "--inf-buffer-size") == 0 && i < argc - 1) + { + global_init_inf_buf_size = atoll(argv[i + 1]); + i++; + } + else if ((strcmp(argv[i], "--bench-input") == 0)) { + if (i+1 >= argc) { + fprintf(stderr, "Not enough arguments after --bench-input, expected .\n"); + show_usage(argv); + exit(1); + } + global_benchfile_param = argv[i+1]; + i++; + } + else if ((strcmp(argv[i], "--array-input") == 0)) { + if (i+1 >= argc) { + fprintf(stderr, "Not enough arguments after --array-input, expected .\n"); + show_usage(argv); + exit(1); + } + global_arrayfile_param = argv[i+1]; + i++; + } + else if (strcmp(argv[i], "--array-input-length") == 0 && i < argc - 1) { + global_arrayfile_length_param = atoll(argv[i+1]); + i++; + } + else if (strcmp(argv[i], "--bench-prog") == 0 && i < argc - 1) { + int len = strlen(argv[i+1]); + global_bench_prog_param = (char*) malloc((len+1)*sizeof(char)); + strncpy(global_bench_prog_param,argv[i+1],len); + i++; + } + // If present, we expect the two arguments to be + else if (got_numargs >= 2) { + fprintf(stderr, "Extra arguments left over: "); + for(; i < argc; i++) fprintf(stderr, "%s ", argv[i]); + show_usage(argv); + exit(1); + } else { + if (got_numargs == 0) { + global_size_param = atoll(argv[i]); + got_numargs ++; + } else { + global_iters_param = atoll(argv[i]); + } + } + } + + // Initialize global_bench_prog_param to an empty string in case + // the runtime argument --bench-prog isn't passed. + if (global_bench_prog_param == NULL) { + global_bench_prog_param = (char*) malloc(1*sizeof(char)); + *global_bench_prog_param = '\n'; + } + + __main_expr(); + + return 0; +} + +// ----------------------------------------------------------------------------- +// Program starts here +// ----------------------------------------------------------------------------- + +typedef struct Prod_struct { } Prod; +typedef struct Int64Prod_struct { + IntTy field0; + } Int64Prod; +typedef struct Int64Int64Int64Int64CursorCursorProd_struct { + IntTy field0; + IntTy field1; + IntTy field2; + IntTy field3; + CursorTy field4; + CursorTy field5; + } Int64Int64Int64Int64CursorCursorProd; +typedef struct Int64Int64Int64CursorCursorProd_struct { + IntTy field0; + IntTy field1; + IntTy field2; + CursorTy field3; + CursorTy field4; + } Int64Int64Int64CursorCursorProd; +typedef struct BoolProd_struct { + BoolTy field0; + } BoolProd; +typedef struct TagCursorProd_struct { + TagTyPacked field0; + CursorTy field1; + } TagCursorProd; +typedef struct CursorProd_struct { + CursorTy field0; + } CursorProd; +IntTy sumRight(CursorTy m_42_711_948); +CursorTy build(IntTy x_48_717_957, IntTy sz_49_718_958, CursorTy m_50_719_959); +IntTy sumLeft(CursorTy m_51_720_969); +IntTy ratio(); +IntTy delta(); +IntTy size_332(CursorTy m_187_726_978); +CursorTy singleL_339(IntTy k1_114_732_984, IntTy x1_115_733_985, + CursorTy t1_116_734_986, CursorTy m_117_735_987); +CursorTy doubleL_340(IntTy k1_85_741_994, IntTy x1_86_742_995, + CursorTy t1_87_743_996, CursorTy m0_88_744_997); +CursorTy rotateL_333(IntTy k_139_750_1003, IntTy x_140_751_1004, + CursorTy l_141_752_1005, CursorTy r_142_753_1006); +CursorTy bin_338(IntTy k_124_759_1017, IntTy x_125_760_1018, + CursorTy l_126_761_1019, CursorTy r_127_762_1020); +CursorTy singleR_335(IntTy k1_104_763_1025, IntTy x1_105_764_1026, + CursorTy m_106_765_1027, CursorTy t3_107_766_1028); +CursorTy doubleR_336(IntTy k1_70_772_1035, IntTy x1_71_773_1036, + CursorTy m0_72_774_1037, CursorTy t4_73_775_1038); +CursorTy empty_337(); +CursorTy rotateR_334(IntTy k_129_781_1044, IntTy x_130_782_1045, + CursorTy l_131_783_1046, CursorTy r_132_784_1047); +CursorTy balance_331(IntTy k_149_790_1058, IntTy x_150_791_1059, + CursorTy l_151_792_1060, CursorTy r_152_793_1061); +CursorTy singleton_328(IntTy k_66_794_1082, IntTy x_67_795_1083); +CursorTy insert_330(IntTy kx_57_796_1086, IntTy x_58_797_1087, + CursorTy m_59_798_1088); +CursorTy _copy_without_ptrs_Map_v_329(CursorTy arg_646_804_1098); +CursorTy _copy_Map_v_329(CursorTy arg_635_815_1109); +unsigned char _traverse_Map_v_329(CursorTy arg_657_826_1120); +unsigned char _print_Map_v_329(CursorTy arg_668_834_1128); +CursorTy caseFn_688(IntTy x1_86_689_854_1148, IntTy k1_85_690_855_1149, + CursorTy t1_87_691_856_1150, CursorTy m1_93_692_857_1151, + IntTy k2_91_693_858_1152, IntTy x2_92_694_859_1153, + CursorTy t4_94_695_860_1154); +CursorTy caseFn_696(IntTy x1_71_697_866_1162, IntTy k1_70_698_867_1163, + CursorTy t4_73_699_868_1164, CursorTy m1_79_700_869_1165, + IntTy k2_76_701_870_1166, IntTy x2_77_702_871_1167, + CursorTy t1_78_703_872_1168); +IntTy sumRight(CursorTy m_42_711_948) +{ + TagTyPacked tag_1183 = *(TagTyPacked *) m_42_711_948; + CursorTy tail_1184 = m_42_711_948 + sizeof(IntTy); + + + switch_1186: + ; + switch (tag_1183) { + + case 0: + { + return 0; + break; + } + + case 1: + { + IntTy wildcard__1_43_712_949 = + ((Int64Int64Int64CursorCursorProd *) tail_1184)->field0; + IntTy wildcard__2_44_713_950 = + ((Int64Int64Int64CursorCursorProd *) tail_1184)->field1; + IntTy v_45_714_951 = + ((Int64Int64Int64CursorCursorProd *) tail_1184)->field2; + CursorTy l_46_715_952 = + ((Int64Int64Int64CursorCursorProd *) tail_1184)->field3; + CursorTy r_47_716_953 = + ((Int64Int64Int64CursorCursorProd *) tail_1184)->field4; + IntTy fltPrm_880_954 = sumRight(r_47_716_953); + IntTy fltPrm_879_955 = fltPrm_880_954 + v_45_714_951; + IntTy fltPrm_881_956 = sumRight(l_46_715_952); + IntTy flt_1185 = fltPrm_879_955 + fltPrm_881_956; + + return flt_1185; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1183"); + exit(1); + } + } +} +CursorTy build(IntTy x_48_717_957, IntTy sz_49_718_958, CursorTy m_50_719_959) +{ + BoolTy fltIf_882_960 = sz_49_718_958 == 0; + + if (fltIf_882_960) { + return m_50_719_959; + } else { + IntTy fltPrm_884_961 = sz_49_718_958 / 2; + IntTy fltAppE_883_962 = x_48_717_957 - fltPrm_884_961; + IntTy fltAppE_885_963 = sz_49_718_958 / 2; + IntTy fltPrm_888_964 = sz_49_718_958 / 2; + IntTy fltAppE_887_965 = x_48_717_957 + fltPrm_888_964; + IntTy fltAppE_889_966 = sz_49_718_958 / 2; + CursorTy fltAppE_890_967 = + insert_330(x_48_717_957, x_48_717_957, m_50_719_959); + CursorTy fltAppE_886_968 = + build(fltAppE_887_965, fltAppE_889_966, fltAppE_890_967); + + return build(fltAppE_883_962, fltAppE_885_963, fltAppE_886_968); + } +} +IntTy sumLeft(CursorTy m_51_720_969) +{ + TagTyPacked tag_1187 = *(TagTyPacked *) m_51_720_969; + CursorTy tail_1188 = m_51_720_969 + sizeof(IntTy); + + + switch_1190: + ; + switch (tag_1187) { + + case 0: + { + return 0; + break; + } + + case 1: + { + IntTy wildcard__9_52_721_970 = + ((Int64Int64Int64CursorCursorProd *) tail_1188)->field0; + IntTy wildcard__10_53_722_971 = + ((Int64Int64Int64CursorCursorProd *) tail_1188)->field1; + IntTy v_54_723_972 = + ((Int64Int64Int64CursorCursorProd *) tail_1188)->field2; + CursorTy l_55_724_973 = + ((Int64Int64Int64CursorCursorProd *) tail_1188)->field3; + CursorTy r_56_725_974 = + ((Int64Int64Int64CursorCursorProd *) tail_1188)->field4; + IntTy fltPrm_892_975 = sumLeft(l_55_724_973); + IntTy fltPrm_891_976 = fltPrm_892_975 + v_54_723_972; + IntTy fltPrm_893_977 = sumLeft(r_56_725_974); + IntTy flt_1189 = fltPrm_891_976 + fltPrm_893_977; + + return flt_1189; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1187"); + exit(1); + } + } +} +IntTy ratio() +{ + return 2; +} +IntTy delta() +{ + return 4; +} +IntTy size_332(CursorTy m_187_726_978) +{ + TagTyPacked tag_1191 = *(TagTyPacked *) m_187_726_978; + CursorTy tail_1192 = m_187_726_978 + sizeof(IntTy); + + + switch_1193: + ; + switch (tag_1191) { + + case 0: + { + return 0; + break; + } + + case 1: + { + IntTy sz_189_727_979 = + ((Int64Int64Int64CursorCursorProd *) tail_1192)->field0; + IntTy wildcard__18_190_728_980 = + ((Int64Int64Int64CursorCursorProd *) tail_1192)->field1; + IntTy wildcard__19_191_729_981 = + ((Int64Int64Int64CursorCursorProd *) tail_1192)->field2; + CursorTy wildcard__20_192_730_982 = + ((Int64Int64Int64CursorCursorProd *) tail_1192)->field3; + CursorTy wildcard__21_193_731_983 = + ((Int64Int64Int64CursorCursorProd *) tail_1192)->field4; + + return sz_189_727_979; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1191"); + exit(1); + } + } +} +CursorTy singleL_339(IntTy k1_114_732_984, IntTy x1_115_733_985, + CursorTy t1_116_734_986, CursorTy m_117_735_987) +{ + TagTyPacked tag_1194 = *(TagTyPacked *) m_117_735_987; + CursorTy tail_1195 = m_117_735_987 + sizeof(IntTy); + + + switch_1196: + ; + switch (tag_1194) { + + case 1: + { + IntTy wildcard__123_119_736_988 = + ((Int64Int64Int64CursorCursorProd *) tail_1195)->field0; + IntTy k2_120_737_989 = + ((Int64Int64Int64CursorCursorProd *) tail_1195)->field1; + IntTy x2_121_738_990 = + ((Int64Int64Int64CursorCursorProd *) tail_1195)->field2; + CursorTy t2_122_739_991 = + ((Int64Int64Int64CursorCursorProd *) tail_1195)->field3; + CursorTy t3_123_740_992 = + ((Int64Int64Int64CursorCursorProd *) tail_1195)->field4; + CursorTy fltAppE_894_993 = + bin_338(k1_114_732_984, x1_115_733_985, t1_116_734_986, t2_122_739_991); + + return bin_338(k2_120_737_989, x2_121_738_990, fltAppE_894_993, + t3_123_740_992); + break; + } + + case 0: + { + return empty_337(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1194"); + exit(1); + } + } +} +CursorTy doubleL_340(IntTy k1_85_741_994, IntTy x1_86_742_995, + CursorTy t1_87_743_996, CursorTy m0_88_744_997) +{ + TagTyPacked tag_1197 = *(TagTyPacked *) m0_88_744_997; + CursorTy tail_1198 = m0_88_744_997 + sizeof(IntTy); + + + switch_1199: + ; + switch (tag_1197) { + + case 1: + { + IntTy wildcard__143_90_745_998 = + ((Int64Int64Int64CursorCursorProd *) tail_1198)->field0; + IntTy k2_91_746_999 = + ((Int64Int64Int64CursorCursorProd *) tail_1198)->field1; + IntTy x2_92_747_1000 = + ((Int64Int64Int64CursorCursorProd *) tail_1198)->field2; + CursorTy m1_93_748_1001 = + ((Int64Int64Int64CursorCursorProd *) tail_1198)->field3; + CursorTy t4_94_749_1002 = + ((Int64Int64Int64CursorCursorProd *) tail_1198)->field4; + + return caseFn_688(x1_86_742_995, k1_85_741_994, t1_87_743_996, + m1_93_748_1001, k2_91_746_999, x2_92_747_1000, + t4_94_749_1002); + break; + } + + case 0: + { + return empty_337(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1197"); + exit(1); + } + } +} +CursorTy rotateL_333(IntTy k_139_750_1003, IntTy x_140_751_1004, + CursorTy l_141_752_1005, CursorTy r_142_753_1006) +{ + TagTyPacked tag_1200 = *(TagTyPacked *) r_142_753_1006; + CursorTy tail_1201 = r_142_753_1006 + sizeof(IntTy); + + + switch_1202: + ; + switch (tag_1200) { + + case 1: + { + IntTy wildcard__94_144_754_1007 = + ((Int64Int64Int64CursorCursorProd *) tail_1201)->field0; + IntTy wildcard__95_145_755_1008 = + ((Int64Int64Int64CursorCursorProd *) tail_1201)->field1; + IntTy wildcard__96_146_756_1009 = + ((Int64Int64Int64CursorCursorProd *) tail_1201)->field2; + CursorTy ly_147_757_1010 = + ((Int64Int64Int64CursorCursorProd *) tail_1201)->field3; + CursorTy ry_148_758_1011 = + ((Int64Int64Int64CursorCursorProd *) tail_1201)->field4; + IntTy fltPrm_896_1012 = size_332(ly_147_757_1010); + IntTy fltPrm_898_1013 = ratio(); + IntTy fltPrm_899_1014 = size_332(ry_148_758_1011); + IntTy fltPrm_897_1015 = fltPrm_898_1013 * fltPrm_899_1014; + BoolTy fltIf_895_1016 = fltPrm_896_1012 < fltPrm_897_1015; + + if (fltIf_895_1016) { + return singleL_339(k_139_750_1003, x_140_751_1004, + l_141_752_1005, r_142_753_1006); + } else { + return doubleL_340(k_139_750_1003, x_140_751_1004, + l_141_752_1005, r_142_753_1006); + } + break; + } + + case 0: + { + return empty_337(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1200"); + exit(1); + } + } +} +CursorTy bin_338(IntTy k_124_759_1017, IntTy x_125_760_1018, + CursorTy l_126_761_1019, CursorTy r_127_762_1020) +{ + IntTy fltPrm_902_1021 = size_332(l_126_761_1019); + IntTy fltPrm_903_1022 = size_332(r_127_762_1020); + IntTy fltPrm_901_1023 = fltPrm_902_1021 + fltPrm_903_1022; + IntTy fltPkd_900_1024 = fltPrm_901_1023 + 1; + PtrTy tailift_1203 = ALLOC(sizeof(Int64Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1203)->field0 = 1; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1203)->field1 = + fltPkd_900_1024; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1203)->field2 = + k_124_759_1017; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1203)->field3 = + x_125_760_1018; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1203)->field4 = + l_126_761_1019; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1203)->field5 = + r_127_762_1020; + return tailift_1203; +} +CursorTy singleR_335(IntTy k1_104_763_1025, IntTy x1_105_764_1026, + CursorTy m_106_765_1027, CursorTy t3_107_766_1028) +{ + TagTyPacked tag_1204 = *(TagTyPacked *) m_106_765_1027; + CursorTy tail_1205 = m_106_765_1027 + sizeof(IntTy); + + + switch_1206: + ; + switch (tag_1204) { + + case 1: + { + IntTy wildcard__133_109_767_1029 = + ((Int64Int64Int64CursorCursorProd *) tail_1205)->field0; + IntTy k2_110_768_1030 = + ((Int64Int64Int64CursorCursorProd *) tail_1205)->field1; + IntTy x2_111_769_1031 = + ((Int64Int64Int64CursorCursorProd *) tail_1205)->field2; + CursorTy t1_112_770_1032 = + ((Int64Int64Int64CursorCursorProd *) tail_1205)->field3; + CursorTy t2_113_771_1033 = + ((Int64Int64Int64CursorCursorProd *) tail_1205)->field4; + CursorTy fltAppE_904_1034 = + bin_338(k1_104_763_1025, x1_105_764_1026, t2_113_771_1033, t3_107_766_1028); + + return bin_338(k2_110_768_1030, x2_111_769_1031, t1_112_770_1032, + fltAppE_904_1034); + break; + } + + case 0: + { + return empty_337(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1204"); + exit(1); + } + } +} +CursorTy doubleR_336(IntTy k1_70_772_1035, IntTy x1_71_773_1036, + CursorTy m0_72_774_1037, CursorTy t4_73_775_1038) +{ + TagTyPacked tag_1207 = *(TagTyPacked *) m0_72_774_1037; + CursorTy tail_1208 = m0_72_774_1037 + sizeof(IntTy); + + + switch_1209: + ; + switch (tag_1207) { + + case 1: + { + IntTy wildcard__167_75_776_1039 = + ((Int64Int64Int64CursorCursorProd *) tail_1208)->field0; + IntTy k2_76_777_1040 = + ((Int64Int64Int64CursorCursorProd *) tail_1208)->field1; + IntTy x2_77_778_1041 = + ((Int64Int64Int64CursorCursorProd *) tail_1208)->field2; + CursorTy t1_78_779_1042 = + ((Int64Int64Int64CursorCursorProd *) tail_1208)->field3; + CursorTy m1_79_780_1043 = + ((Int64Int64Int64CursorCursorProd *) tail_1208)->field4; + + return caseFn_696(x1_71_773_1036, k1_70_772_1035, t4_73_775_1038, + m1_79_780_1043, k2_76_777_1040, x2_77_778_1041, + t1_78_779_1042); + break; + } + + case 0: + { + return empty_337(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1207"); + exit(1); + } + } +} +CursorTy empty_337() +{ + PtrTy tailift_1210 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) tailift_1210)->field0 = 0; + return tailift_1210; +} +CursorTy rotateR_334(IntTy k_129_781_1044, IntTy x_130_782_1045, + CursorTy l_131_783_1046, CursorTy r_132_784_1047) +{ + TagTyPacked tag_1211 = *(TagTyPacked *) l_131_783_1046; + CursorTy tail_1212 = l_131_783_1046 + sizeof(IntTy); + + + switch_1213: + ; + switch (tag_1211) { + + case 1: + { + IntTy wildcard__106_134_785_1048 = + ((Int64Int64Int64CursorCursorProd *) tail_1212)->field0; + IntTy wildcard__107_135_786_1049 = + ((Int64Int64Int64CursorCursorProd *) tail_1212)->field1; + IntTy wildcard__108_136_787_1050 = + ((Int64Int64Int64CursorCursorProd *) tail_1212)->field2; + CursorTy ly_137_788_1051 = + ((Int64Int64Int64CursorCursorProd *) tail_1212)->field3; + CursorTy ry_138_789_1052 = + ((Int64Int64Int64CursorCursorProd *) tail_1212)->field4; + IntTy fltPrm_906_1053 = size_332(ry_138_789_1052); + IntTy fltPrm_908_1054 = ratio(); + IntTy fltPrm_909_1055 = size_332(ly_137_788_1051); + IntTy fltPrm_907_1056 = fltPrm_908_1054 * fltPrm_909_1055; + BoolTy fltIf_905_1057 = fltPrm_906_1053 < fltPrm_907_1056; + + if (fltIf_905_1057) { + return singleR_335(k_129_781_1044, x_130_782_1045, + l_131_783_1046, r_132_784_1047); + } else { + return doubleR_336(k_129_781_1044, x_130_782_1045, + l_131_783_1046, r_132_784_1047); + } + break; + } + + case 0: + { + return empty_337(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1211"); + exit(1); + } + } +} +CursorTy balance_331(IntTy k_149_790_1058, IntTy x_150_791_1059, + CursorTy l_151_792_1060, CursorTy r_152_793_1061) +{ + IntTy fltPrm_912_1062 = size_332(l_151_792_1060); + IntTy fltPrm_913_1063 = size_332(r_152_793_1061); + IntTy fltPrm_911_1064 = fltPrm_912_1062 + fltPrm_913_1063; + BoolTy fltIf_910_1065 = fltPrm_911_1064 <= 1; + + if (fltIf_910_1065) { + IntTy fltPrm_915_1066 = size_332(l_151_792_1060); + IntTy fltPrm_916_1067 = size_332(r_152_793_1061); + IntTy fltPkd_914_1068 = fltPrm_915_1066 + fltPrm_916_1067; + PtrTy tailift_1214 = + ALLOC(sizeof(Int64Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1214)->field0 = 1; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1214)->field1 = + fltPkd_914_1068; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1214)->field2 = + k_149_790_1058; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1214)->field3 = + x_150_791_1059; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1214)->field4 = + l_151_792_1060; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1214)->field5 = + r_152_793_1061; + return tailift_1214; + } else { + IntTy fltPrm_918_1069 = size_332(r_152_793_1061); + IntTy fltPrm_920_1070 = delta(); + IntTy fltPrm_921_1071 = size_332(l_151_792_1060); + IntTy fltPrm_919_1072 = fltPrm_920_1070 * fltPrm_921_1071; + BoolTy fltIf_917_1073 = fltPrm_918_1069 >= fltPrm_919_1072; + + if (fltIf_917_1073) { + return rotateL_333(k_149_790_1058, x_150_791_1059, l_151_792_1060, + r_152_793_1061); + } else { + IntTy fltPrm_923_1074 = size_332(l_151_792_1060); + IntTy fltPrm_925_1075 = delta(); + IntTy fltPrm_926_1076 = size_332(r_152_793_1061); + IntTy fltPrm_924_1077 = fltPrm_925_1075 * fltPrm_926_1076; + BoolTy fltIf_922_1078 = fltPrm_923_1074 >= fltPrm_924_1077; + + if (fltIf_922_1078) { + return rotateR_334(k_149_790_1058, x_150_791_1059, + l_151_792_1060, r_152_793_1061); + } else { + IntTy fltPrm_928_1079 = size_332(l_151_792_1060); + IntTy fltPrm_929_1080 = size_332(r_152_793_1061); + IntTy fltPkd_927_1081 = fltPrm_928_1079 + fltPrm_929_1080; + PtrTy tailift_1215 = + ALLOC(sizeof(Int64Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1215)->field0 = + 1; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1215)->field1 = + fltPkd_927_1081; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1215)->field2 = + k_149_790_1058; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1215)->field3 = + x_150_791_1059; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1215)->field4 = + l_151_792_1060; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1215)->field5 = + r_152_793_1061; + return tailift_1215; + } + } + } +} +CursorTy singleton_328(IntTy k_66_794_1082, IntTy x_67_795_1083) +{ + PtrTy fltPkd_930_1084 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_930_1084)->field0 = 0; + + PtrTy fltPkd_931_1085 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_931_1085)->field0 = 0; + + PtrTy tailift_1216 = ALLOC(sizeof(Int64Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1216)->field0 = 1; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1216)->field1 = 1; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1216)->field2 = + k_66_794_1082; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1216)->field3 = + x_67_795_1083; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1216)->field4 = + fltPkd_930_1084; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1216)->field5 = + fltPkd_931_1085; + return tailift_1216; +} +CursorTy insert_330(IntTy kx_57_796_1086, IntTy x_58_797_1087, + CursorTy m_59_798_1088) +{ + TagTyPacked tag_1217 = *(TagTyPacked *) m_59_798_1088; + CursorTy tail_1218 = m_59_798_1088 + sizeof(IntTy); + + + switch_1220: + ; + switch (tag_1217) { + + case 0: + { + return singleton_328(kx_57_796_1086, x_58_797_1087); + break; + } + + case 1: + { + IntTy sz_61_799_1089 = + ((Int64Int64Int64CursorCursorProd *) tail_1218)->field0; + IntTy k_62_800_1090 = + ((Int64Int64Int64CursorCursorProd *) tail_1218)->field1; + IntTy v_63_801_1091 = + ((Int64Int64Int64CursorCursorProd *) tail_1218)->field2; + CursorTy l_64_802_1092 = + ((Int64Int64Int64CursorCursorProd *) tail_1218)->field3; + CursorTy r_65_803_1093 = + ((Int64Int64Int64CursorCursorProd *) tail_1218)->field4; + BoolTy fltIf_932_1094 = kx_57_796_1086 == k_62_800_1090; + + if (fltIf_932_1094) { + PtrTy tailift_1219 = + ALLOC(sizeof(Int64Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1219)->field0 = + 1; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1219)->field1 = + sz_61_799_1089; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1219)->field2 = + k_62_800_1090; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1219)->field3 = + x_58_797_1087; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1219)->field4 = + l_64_802_1092; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1219)->field5 = + r_65_803_1093; + return tailift_1219; + } else { + BoolTy fltIf_933_1095 = kx_57_796_1086 <= k_62_800_1090; + + if (fltIf_933_1095) { + CursorTy fltAppE_934_1096 = + insert_330(kx_57_796_1086, x_58_797_1087, l_64_802_1092); + + return balance_331(k_62_800_1090, v_63_801_1091, + fltAppE_934_1096, r_65_803_1093); + } else { + CursorTy fltAppE_935_1097 = + insert_330(kx_57_796_1086, x_58_797_1087, r_65_803_1093); + + return balance_331(k_62_800_1090, v_63_801_1091, + l_64_802_1092, fltAppE_935_1097); + } + } + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1217"); + exit(1); + } + } +} +CursorTy _copy_without_ptrs_Map_v_329(CursorTy arg_646_804_1098) +{ + TagTyPacked tag_1221 = *(TagTyPacked *) arg_646_804_1098; + CursorTy tail_1222 = arg_646_804_1098 + sizeof(IntTy); + + + switch_1225: + ; + switch (tag_1221) { + + case 0: + { + PtrTy tailift_1223 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) tailift_1223)->field0 = 0; + return tailift_1223; + break; + } + + case 1: + { + IntTy x_647_805_1099 = + ((Int64Int64Int64CursorCursorProd *) tail_1222)->field0; + IntTy x_648_806_1100 = + ((Int64Int64Int64CursorCursorProd *) tail_1222)->field1; + IntTy x_649_807_1101 = + ((Int64Int64Int64CursorCursorProd *) tail_1222)->field2; + CursorTy x_650_808_1102 = + ((Int64Int64Int64CursorCursorProd *) tail_1222)->field3; + CursorTy x_651_809_1103 = + ((Int64Int64Int64CursorCursorProd *) tail_1222)->field4; + CursorTy y_655_813_1107 = + _copy_without_ptrs_Map_v_329(x_650_808_1102); + CursorTy y_656_814_1108 = + _copy_without_ptrs_Map_v_329(x_651_809_1103); + PtrTy tailift_1224 = + ALLOC(sizeof(Int64Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1224)->field0 = 1; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1224)->field1 = + x_647_805_1099; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1224)->field2 = + x_648_806_1100; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1224)->field3 = + x_649_807_1101; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1224)->field4 = + y_655_813_1107; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1224)->field5 = + y_656_814_1108; + return tailift_1224; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1221"); + exit(1); + } + } +} +CursorTy _copy_Map_v_329(CursorTy arg_635_815_1109) +{ + TagTyPacked tag_1226 = *(TagTyPacked *) arg_635_815_1109; + CursorTy tail_1227 = arg_635_815_1109 + sizeof(IntTy); + + + switch_1230: + ; + switch (tag_1226) { + + case 0: + { + PtrTy tailift_1228 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) tailift_1228)->field0 = 0; + return tailift_1228; + break; + } + + case 1: + { + IntTy x_636_816_1110 = + ((Int64Int64Int64CursorCursorProd *) tail_1227)->field0; + IntTy x_637_817_1111 = + ((Int64Int64Int64CursorCursorProd *) tail_1227)->field1; + IntTy x_638_818_1112 = + ((Int64Int64Int64CursorCursorProd *) tail_1227)->field2; + CursorTy x_639_819_1113 = + ((Int64Int64Int64CursorCursorProd *) tail_1227)->field3; + CursorTy x_640_820_1114 = + ((Int64Int64Int64CursorCursorProd *) tail_1227)->field4; + CursorTy y_644_824_1118 = _copy_Map_v_329(x_639_819_1113); + CursorTy y_645_825_1119 = _copy_Map_v_329(x_640_820_1114); + PtrTy tailift_1229 = + ALLOC(sizeof(Int64Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1229)->field0 = 1; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1229)->field1 = + x_636_816_1110; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1229)->field2 = + x_637_817_1111; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1229)->field3 = + x_638_818_1112; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1229)->field4 = + y_644_824_1118; + ((Int64Int64Int64Int64CursorCursorProd *) tailift_1229)->field5 = + y_645_825_1119; + return tailift_1229; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1226"); + exit(1); + } + } +} +unsigned char _traverse_Map_v_329(CursorTy arg_657_826_1120) +{ + TagTyPacked tag_1231 = *(TagTyPacked *) arg_657_826_1120; + CursorTy tail_1232 = arg_657_826_1120 + sizeof(IntTy); + + + switch_1233: + ; + switch (tag_1231) { + + case 0: + { + return 0; + break; + } + + case 1: + { + IntTy x_658_827_1121 = + ((Int64Int64Int64CursorCursorProd *) tail_1232)->field0; + IntTy x_659_828_1122 = + ((Int64Int64Int64CursorCursorProd *) tail_1232)->field1; + IntTy x_660_829_1123 = + ((Int64Int64Int64CursorCursorProd *) tail_1232)->field2; + CursorTy x_661_830_1124 = + ((Int64Int64Int64CursorCursorProd *) tail_1232)->field3; + CursorTy x_662_831_1125 = + ((Int64Int64Int64CursorCursorProd *) tail_1232)->field4; + unsigned char y_666_832_1126 = _traverse_Map_v_329(x_661_830_1124); + unsigned char y_667_833_1127 = _traverse_Map_v_329(x_662_831_1125); + + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1231"); + exit(1); + } + } +} +unsigned char _print_Map_v_329(CursorTy arg_668_834_1128) +{ + TagTyPacked tag_1234 = *(TagTyPacked *) arg_668_834_1128; + CursorTy tail_1235 = arg_668_834_1128 + sizeof(IntTy); + + + switch_1236: + ; + switch (tag_1234) { + + case 0: + { + unsigned char wildcard_669_835_1129 = print_symbol(1179); + unsigned char wildcard_670_836_1130 = print_symbol(1178); + + return 0; + break; + } + + case 1: + { + IntTy x_671_837_1131 = + ((Int64Int64Int64CursorCursorProd *) tail_1235)->field0; + IntTy x_672_838_1132 = + ((Int64Int64Int64CursorCursorProd *) tail_1235)->field1; + IntTy x_673_839_1133 = + ((Int64Int64Int64CursorCursorProd *) tail_1235)->field2; + CursorTy x_674_840_1134 = + ((Int64Int64Int64CursorCursorProd *) tail_1235)->field3; + CursorTy x_675_841_1135 = + ((Int64Int64Int64CursorCursorProd *) tail_1235)->field4; + unsigned char wildcard_681_842_1136 = print_symbol(1180); + unsigned char wildcard_687_843_1137 = print_symbol(1181); + unsigned char y_676_844_1138 = printf("%lld", x_671_837_1131); + unsigned char wildcard_686_845_1139 = print_symbol(1181); + unsigned char y_677_846_1140 = printf("%lld", x_672_838_1132); + unsigned char wildcard_685_847_1141 = print_symbol(1181); + unsigned char y_678_848_1142 = printf("%lld", x_673_839_1133); + unsigned char wildcard_684_849_1143 = print_symbol(1181); + unsigned char y_679_850_1144 = _print_Map_v_329(x_674_840_1134); + unsigned char wildcard_683_851_1145 = print_symbol(1181); + unsigned char y_680_852_1146 = _print_Map_v_329(x_675_841_1135); + unsigned char wildcard_682_853_1147 = print_symbol(1178); + + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1234"); + exit(1); + } + } +} +CursorTy caseFn_688(IntTy x1_86_689_854_1148, IntTy k1_85_690_855_1149, + CursorTy t1_87_691_856_1150, CursorTy m1_93_692_857_1151, + IntTy k2_91_693_858_1152, IntTy x2_92_694_859_1153, + CursorTy t4_94_695_860_1154) +{ + TagTyPacked tag_1237 = *(TagTyPacked *) m1_93_692_857_1151; + CursorTy tail_1238 = m1_93_692_857_1151 + sizeof(IntTy); + + + switch_1239: + ; + switch (tag_1237) { + + case 1: + { + IntTy wildcard__144_95_861_1155 = + ((Int64Int64Int64CursorCursorProd *) tail_1238)->field0; + IntTy k3_96_862_1156 = + ((Int64Int64Int64CursorCursorProd *) tail_1238)->field1; + IntTy x3_97_863_1157 = + ((Int64Int64Int64CursorCursorProd *) tail_1238)->field2; + CursorTy t2_98_864_1158 = + ((Int64Int64Int64CursorCursorProd *) tail_1238)->field3; + CursorTy t3_99_865_1159 = + ((Int64Int64Int64CursorCursorProd *) tail_1238)->field4; + CursorTy fltAppE_936_1160 = + bin_338(k1_85_690_855_1149, x1_86_689_854_1148, t1_87_691_856_1150, t2_98_864_1158); + CursorTy fltAppE_937_1161 = + bin_338(k2_91_693_858_1152, x2_92_694_859_1153, t3_99_865_1159, t4_94_695_860_1154); + + return bin_338(k3_96_862_1156, x3_97_863_1157, fltAppE_936_1160, + fltAppE_937_1161); + break; + } + + case 0: + { + return empty_337(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1237"); + exit(1); + } + } +} +CursorTy caseFn_696(IntTy x1_71_697_866_1162, IntTy k1_70_698_867_1163, + CursorTy t4_73_699_868_1164, CursorTy m1_79_700_869_1165, + IntTy k2_76_701_870_1166, IntTy x2_77_702_871_1167, + CursorTy t1_78_703_872_1168) +{ + TagTyPacked tag_1240 = *(TagTyPacked *) m1_79_700_869_1165; + CursorTy tail_1241 = m1_79_700_869_1165 + sizeof(IntTy); + + + switch_1242: + ; + switch (tag_1240) { + + case 1: + { + IntTy wildcard__168_80_873_1169 = + ((Int64Int64Int64CursorCursorProd *) tail_1241)->field0; + IntTy k3_81_874_1170 = + ((Int64Int64Int64CursorCursorProd *) tail_1241)->field1; + IntTy x3_82_875_1171 = + ((Int64Int64Int64CursorCursorProd *) tail_1241)->field2; + CursorTy t2_83_876_1172 = + ((Int64Int64Int64CursorCursorProd *) tail_1241)->field3; + CursorTy t3_84_877_1173 = + ((Int64Int64Int64CursorCursorProd *) tail_1241)->field4; + CursorTy fltAppE_938_1174 = + bin_338(k2_76_701_870_1166, x2_77_702_871_1167, t1_78_703_872_1168, t2_83_876_1172); + CursorTy fltAppE_939_1175 = + bin_338(k1_70_698_867_1163, x1_71_697_866_1162, t3_84_877_1173, t4_73_699_868_1164); + + return bin_338(k3_81_874_1170, x3_82_875_1171, fltAppE_938_1174, + fltAppE_939_1175); + break; + } + + case 0: + { + return empty_337(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1240"); + exit(1); + } + } +} +int __main_expr() +{ + add_symbol(1178, ")"); + add_symbol(1179, "(Tip_v_329"); + add_symbol(1180, "(Bin_v_329"); + add_symbol(1181, " "); + add_symbol(1182, "\n"); + + CursorTy fltAppE_878_940 = singleton_328(0, 0); + CursorTy m_33_704_941 = build(0, 512, fltAppE_878_940); + IntTy timed_1176; + VectorTy *times_3 = vector_alloc(global_iters_param, sizeof(double)); + struct timespec begin_timed_1176; + struct timespec end_timed_1176; + + for (long long iters_timed_1176 = 0; iters_timed_1176 < global_iters_param; + iters_timed_1176++) { + if (iters_timed_1176 != global_iters_param - 1) + save_alloc_state(); + clock_gettime(CLOCK_MONOTONIC_RAW, &begin_timed_1176); + + IntTy timed_1176hack = sumLeft(m_33_704_941); + + timed_1176 = timed_1176hack; + clock_gettime(CLOCK_MONOTONIC_RAW, &end_timed_1176); + if (iters_timed_1176 != global_iters_param - 1) + restore_alloc_state(); + + double itertime_0 = difftimespecs(&begin_timed_1176, &end_timed_1176); + + vector_inplace_update(times_3, iters_timed_1176, &itertime_0); + } + vector_inplace_sort(times_3, compare_doubles); + + double *tmp_4 = (double *) vector_nth(times_3, global_iters_param / 2); + double selftimed_2 = *tmp_4; + double batchtime_1 = sum_timing_array(times_3); + + print_timing_array(times_3); + printf("ITERS: %lld\n", global_iters_param); + printf("SIZE: %lld\n", global_size_param); + printf("BATCHTIME: %e\n", batchtime_1); + printf("SELFTIMED: %e\n", selftimed_2); + + unsigned char wildcard__27_35_706_943 = printf("%lld", timed_1176); + unsigned char wildcard__25_36_707_944 = print_symbol(1182); + IntTy timed_1177; + VectorTy *times_8 = vector_alloc(global_iters_param, sizeof(double)); + struct timespec begin_timed_1177; + struct timespec end_timed_1177; + + for (long long iters_timed_1177 = 0; iters_timed_1177 < global_iters_param; + iters_timed_1177++) { + if (iters_timed_1177 != global_iters_param - 1) + save_alloc_state(); + clock_gettime(CLOCK_MONOTONIC_RAW, &begin_timed_1177); + + IntTy timed_1177hack = sumRight(m_33_704_941); + + timed_1177 = timed_1177hack; + clock_gettime(CLOCK_MONOTONIC_RAW, &end_timed_1177); + if (iters_timed_1177 != global_iters_param - 1) + restore_alloc_state(); + + double itertime_5 = difftimespecs(&begin_timed_1177, &end_timed_1177); + + vector_inplace_update(times_8, iters_timed_1177, &itertime_5); + } + vector_inplace_sort(times_8, compare_doubles); + + double *tmp_9 = (double *) vector_nth(times_8, global_iters_param / 2); + double selftimed_7 = *tmp_9; + double batchtime_6 = sum_timing_array(times_8); + + print_timing_array(times_8); + printf("ITERS: %lld\n", global_iters_param); + printf("SIZE: %lld\n", global_size_param); + printf("BATCHTIME: %e\n", batchtime_6); + printf("SELFTIMED: %e\n", selftimed_7); + + unsigned char wildcard__21_38_709_946 = printf("%lld", timed_1177); + unsigned char wildcard__19_39_710_947 = print_symbol(1182); + + printf("'#()"); + printf("\n"); + free_symtable(); + return 0; +} \ No newline at end of file diff --git a/benchmarks/Layouts/_RightAndLeft.hs b/benchmarks/Layouts/_RightAndLeft.hs new file mode 100644 index 000000000..cf5dd8950 --- /dev/null +++ b/benchmarks/Layouts/_RightAndLeft.hs @@ -0,0 +1,34 @@ + +module LeftAndRight where +import Common +import Map + +sumRight :: Map Int -> Int +sumRight m = + case m of + Tip -> 0 + Bin _ _ v l r -> sumRight(r) + v + sumRight(l) + +sumLeft :: Map Int -> Int +sumLeft m = + case m of + Tip -> 0 + Bin _ _ v l r -> sumLeft(l) + v + sumLeft(r) + + +build :: Int -> Int -> Map Int -> Map Int +build x sz m = + if (sz == 0) then m + else (build (x - sz/2) (sz/2) (build (x + sz/2) (sz/2) (insert x x m))) + +gibbon_main = + let m = (build 0 512 (singleton 0 0)) + --_ = printsym (quote "SUM RIGHT: ") + s0 = iterate (sumLeft m) + _ = printint (s0) + _ = printsym (quote "\n") + --_ = printsym (quote "SUM LEFT: ") + s1 = iterate (sumRight m) + _ = printint (s1) + _ = printsym (quote "\n") + in () \ No newline at end of file diff --git a/benchmarks/Layouts/build_layout.py b/benchmarks/Layouts/build_layout.py new file mode 100644 index 000000000..9dbcef595 --- /dev/null +++ b/benchmarks/Layouts/build_layout.py @@ -0,0 +1,50 @@ +from itertools import permutations + + +# Layout Parameters +NUM_STRUCTS_RANGE = range(1, 8) +SIZE_RANGE = range(2, 20) #bytes +SIZE_STEP = 1 +SIZE_FUNCT = "exp2" # "linear" "quadratic" "exp2" +META_ACCESS_PATTERNS = ["forward", "backward", "random"] + + +test_cases = [] + +for num in NUM_STRUCTS_RANGE: + for access_pattern in permutations(range(num)): + test_cases_of_n = [] + for size in range(len(SIZE_RANGE)): + for meta_access_pattern in range(len(META_ACCESS_PATTERNS)) + test_cases_of_n.append(TestCase(access_pattern)) + + for i in range(num): + for size in range(len(SIZE_RANGE)): + for meta_access_pattern in range(len(META_ACCESS_PATTERNS)) + test_cases_of_n[ + meta_access_pattern + size*len(META_ACCESS_PATTERNS) + ].append( + SIZE_RANGE[size], + META_ACCESS_PATTERNS[meta_access_pattern] + ) + test_cases = test_cases + test_cases_of_n + + + +class TestCase: + def __init__(self, access_pattern): + self.access_pattern = access_pattern + self.structs = [] + + def append(self, size, meta_access_pattern): + self.structs.append({ + "size": size, + "access_pattern": meta_access_pattern + }) + + def write(self): + with open("Layout.hs") as f: + f.write("module Layout where\n") + for s in range(len(structs)): + fwrite(f"data Field_{s} = ") + f.write("data Layout = ") \ No newline at end of file diff --git a/benchmarks/Layouts/evalLayouts.py b/benchmarks/Layouts/evalLayouts.py new file mode 100644 index 000000000..b0281570e --- /dev/null +++ b/benchmarks/Layouts/evalLayouts.py @@ -0,0 +1,70 @@ +import re +import argparse +import subprocess +import numpy as np +import matplotlib.pyplot as plt + + +# Get Arguements +#parser = argparse.ArgumentParser() +#parser.add_argument("size") +#args = parser.parse_args() + +files = ["Left", "Right", "LeftAndRight", "RightAndLeft"] +sizes = range(5,10) + +# Data Point Class +class Point: + + def __init__(self, dir, size, times): + self.dir = files[dir] + self.dir_idx = dir + self.size = size + self.avg = np.mean(times) + self.var = np.var(times) + + + +data = [] + +code = "" +for size in sizes: + for i in range(len(files)): + filename = files[i] + with open(f"{filename}.hs", "r") as f: + code = f.read() + code = re.sub("", f"{pow(2, size)}", code) + f.close() + with open(f"_{filename}.hs", "w") as f: + f.write(code) + f.close() + + proc = subprocess.run(["gibbon", "--to-exe", f"_{filename}.hs"]) + with open(f"{filename}.out", "w") as f: + proc = subprocess.call([f"./_{filename}.exe"], stdout=f) + f.close() + + with open(f"{filename}.out", "r") as f: + times = [] + for line in f: + match = re.search(r"TIMES: \[(?P[\d\.\d]+)\]", line) + if match: + times.append(float(match.groups("num")[0])) + data.append( + Point(i, size, times) + ) + +fig = plt.figure() +ax0 = fig.add_subplot(121, projection="3d") +ax0.set_title("Average Time") +ax0.bar3d([p.dir_idx for p in data], [p.size for p in data], 0, 1, 1, [p.avg for p in data], shade=True) +ax0.set_xticks(range(len(files))) +ax0.set_xticklabels(files) + +ax1 = fig.add_subplot(122, projection="3d") +ax1.set_title("Variance") +ax1.bar3d([p.dir_idx for p in data], [p.size for p in data], 0, 1, 1, [p.var for p in data], shade=True) +ax1.set_xticks(range(len(files))) +ax1.set_xticklabels(files) + +plt.show() \ No newline at end of file diff --git a/benchmarks/README.md b/benchmarks/README.md new file mode 100644 index 000000000..75b96abcc --- /dev/null +++ b/benchmarks/README.md @@ -0,0 +1,40 @@ +# Gibbon Benchmarks + +## CRDTs +- [ ] Set Type - Add, Remove, Merge +- [ ] Register Type - Set, Merge +- [ ] Ordered List - Insert, Remove, Merge + +## Benchmarking +**Things to control for:** +- Payload Size +- Document Size +- Merge Complexity (adding one 12 char block != adding 12 one char blocks) + +**Measurements:** + +Tests will be carried out (ideally) in their native language. Measurements can be written to an output file and then analyzed in python. We'll need to control for the network; a solution might be to use another intermeriate (like a file). It will undoubtedly be intersting to test on a live network of course. + +Name | Description | Network | Method +---- | ----------- | ------- | ------ +Streaming | High frequency, small simple payload | X | Stream individual updates into a remote document, measure time from sent -> response +Merging | Low Frequency, large complex payload | X | Execute a full handshake and exchange between two documents. The payload should have multiple discrete edits +Scaling | Test operations on documents of varying size | | Measure the time it takes to implement changes on documents of varying size. Both in # of uuids and raw content. +Granular | Test individual operations in isolation | | Measure the time it takes individual operations to complete. Use this as a baseline. + +**Evaluation** + +The Gibbon implementation will be compared to: +- A ghc version of the same code +- A C implementation of similair sophistication +- Yjs: a javascript implementation of the same algorithm, state of art CRDT library. + + +## Timeline +- Week [9/13/23]: Internal Libraries (Set and Map) & Benchmarking framework +- Week [9/20/23]: CRDT Set & Register (naive) - test benchmarking framework <- modules would be nice to have here +- Week [9/27/23]: CRDT Ordered List (naive) +- Week [10/4/23]: CRDT Set & Register (optimized) +- Week [10/11/23]: CRDT Ordered List (optimized) +- Week [10/18/23]: Agressive Benchmarking <- network primitives would be nice to have here +- Week [10/25/23]: XML \ No newline at end of file diff --git a/benchmarks/eval.py b/benchmarks/eval.py new file mode 100644 index 000000000..446965ed2 --- /dev/null +++ b/benchmarks/eval.py @@ -0,0 +1,37 @@ +import subprocess as sp +import time +import numpy as np + +TEST = "./modules/GibbonPureSet.exe" +VERSIONS = [TEST, "./modules/GHCPureSet", "./modules/GHCStdSet"] + +def runproc(filename: str): + start = time.time() + p = sp.call([filename], stdout=sp.DEVNULL, stderr=sp.STDOUT) + #p.wait() + return time.time() - start + + +results = {} +avgs = {} + +for version in VERSIONS: + results[version] = [] + +for i in range(100): + for version in VERSIONS: + results[version].append(runproc(version)) + +print("\n-- Results ------\n") +for version in VERSIONS: + avgs[version] = np.mean(results[version]) + print(f"{version}: {avgs[version]}ms") +print("\n-----------------\n") + +for version in VERSIONS: + if(version != TEST): + ratio = avgs[version]/avgs[TEST] + msg = "[X]" + if(ratio > 1): msg = "[🟢]" + + print(f"{msg} Gibbon offers a {ratio}x improvement over {version}") diff --git a/benchmarks/modules/Common.c b/benchmarks/modules/Common.c new file mode 100644 index 000000000..6503f9885 --- /dev/null +++ b/benchmarks/modules/Common.c @@ -0,0 +1,1390 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// #include +#ifdef _WIN64 +#include +#endif +#include +#include +#include // For va_start etc +#include +#include +#include +#include +#ifdef _POINTER +#include +#endif +#ifdef _PARALLEL +#include +#include +#endif + +#define KB 1024lu +#define MB (KB * 1000lu) +#define GB (MB * 1000lu) + +#define REDIRECTION_TAG 255 +#define INDIRECTION_TAG 254 + +// Initial size of BigInfinite buffers +static long long global_init_biginf_buf_size = (4 * GB); + +// Initial size of Infinite buffers +static long long global_init_inf_buf_size = 1 * KB; + +// Maximum size of a chunk, see GitHub #110. +static long long global_inf_buf_max_chunk_size = 1 * GB; + +static long long global_size_param = 1; +static long long global_iters_param = 1; + +static char* global_benchfile_param = NULL; +static char* global_arrayfile_param = NULL; +// Number of lines in the arrayfile +static long long global_arrayfile_length_param = -1; + +// Sequential for now: +static const int num_workers = 1; + +// Count the number of regions allocated. +static long long global_region_count = 0; +static bool global_region_count_flag = false; + +#ifdef _PARALLEL +static inline void bump_global_region_count() { + __atomic_add_fetch(&global_region_count, 1, __ATOMIC_SEQ_CST); + return; +} +#else +static inline void bump_global_region_count() { + global_region_count++; + return; +} +#endif + +static inline void print_global_region_count() { + printf("REGION_COUNT: %lld\n", global_region_count); + return; +} + +#define REDIRECTION_NODE_SIZE 9 +#define MAX(a,b) (((a)>(b))?(a):(b)) +#define MIN(a,b) (((a)<(b))?(a):(b)) + +// https://www.cprogramming.com/snippets/source-code/find-the-number-of-cpu-cores-for-windows-mac-or-linux +static int get_num_processors() { +#ifdef _WIN64 + SYSTEM_INFO sysinfo; + GetSystemInfo(&sysinfo); + return sysinfo.dwNumberOfProcessors; +#else + return sysconf(_SC_NPROCESSORS_ONLN); +#endif +} + +// Requires -std=gnu11 +int dbgprintf(const char *format, ...) { + int code = 0; + va_list args; + va_start(args, format); +#ifdef _DEBUG + code = vprintf(format, args); +#endif + va_end(args); + return code; +} + + +// ----------------------------------------------------------------------------- +// Allocators +// ----------------------------------------------------------------------------- + + +// ------------------------------------- +// Bump allocation for linked-lists +// ------------------------------------- + + +#ifdef _BUMPALLOC +// #define _DEBUG +#warning "Using bump allocator." + +__thread char* bumpalloc_heap_ptr = (char*)NULL; +__thread char* bumpalloc_heap_ptr_end = (char*)NULL; + +char* saved_heap_ptr_stack[100]; +int num_saved_heap_ptr = 0; + +// For simplicity just use a single large slab: +static inline void INITBUMPALLOC() { + bumpalloc_heap_ptr = (char*)malloc(global_init_biginf_buf_size); + bumpalloc_heap_ptr_end = bumpalloc_heap_ptr + global_init_biginf_buf_size; +#ifdef _DEBUG + printf("Arena size for bump alloc: %lld\n", global_init_biginf_buf_size); + printf("BUMPALLOC/INITBUMPALLOC DONE: heap_ptr = %p\n", bumpalloc_heap_ptr); +#endif +} + +static inline void* BUMPALLOC(long long n) { + if (! bumpalloc_heap_ptr) { + INITBUMPALLOC(); + } + if (bumpalloc_heap_ptr + n < bumpalloc_heap_ptr_end) { + char* old= bumpalloc_heap_ptr; + bumpalloc_heap_ptr += n; + return old; + } else { + fprintf(stderr, "Warning: bump allocator ran out of memory."); + exit(1); + } +} + +// Snapshot the current heap pointer value across all threads. +void save_alloc_state() { + dbgprintf("Saving(%p): pos %d", heap_ptr, num_saved_heap_ptr); + saved_heap_ptr_stack[num_saved_heap_ptr] = heap_ptr; + num_saved_heap_ptr++; + dbgprintf("\n"); +} + +void restore_alloc_state() { + if(num_saved_heap_ptr <= 0) { + fprintf(stderr, "Bad call to restore_alloc_state! Saved stack empty!\ne"); + exit(1); + } + num_saved_heap_ptr--; + dbgprintf("Restoring(%p): pos %d, discarding %p", + saved_heap_ptr_stack[num_saved_heap_ptr], num_saved_heap_ptr, bumpalloc_heap_ptr); + bumpalloc_heap_ptr = saved_heap_ptr_stack[num_saved_heap_ptr]; +} + + +#else +// Regular malloc mode: +void INITBUMPALLOC() {} +void save_alloc_state() {} +void restore_alloc_state() {} + +#define BUMPALLOC(n) malloc(n) + +#endif // BUMPALLOC + + +// ------------------------------------- +// ALLOC and ALLOC_PACKED macros +// ------------------------------------- + + +/* + +If parallelism is enabled, we always use a malloc based allocator +since Boehm GC is not thread-safe in its default configuration. It can be +made thread-safe by building it with appropriate flags, but we don't do that. +Presently, all parallel pointer-based programs will leak memory. + +*/ + +#ifdef _PARALLEL +#define ALLOC(n) malloc(n) +#define ALLOC_PACKED_BIG(n) malloc(n) +char *ALLOC_COUNTED(size_t size) { + bump_global_region_count(); + return ALLOC(size); +} +#else + #ifdef _POINTER +#define ALLOC(n) GC_MALLOC(n) +#define ALLOC_PACKED_BIG(n) GC_MALLOC(n) +char *ALLOC_COUNTED(size_t size) { + bump_global_region_count(); + return GC_MALLOC(size); +} + #else +#define ALLOC(n) malloc(n) +#define ALLOC_PACKED_BIG(n) malloc(n) +char *ALLOC_COUNTED(size_t size) { + bump_global_region_count(); + return ALLOC(size); +} + #endif // _POINTER +#endif // _PARALLEL + + +// Could try alloca() here. Better yet, we could keep our own, +// separate stack and insert our own code to restore the pointer +// before any function that (may have) called ALLOC_SCOPED returns. + +// #define ALLOC_SCOPED() alloca(1024) +#define ALLOC_SCOPED(n) alloca(n) +// #define ALLOC_SCOPED() alloc_scoped() + +// Stack allocation is either too small or blows our stack. +// We need a way to make a giant stack if we want to use alloca. +// #define ALLOC_SCOPED() ALLOC(global_init_biginf_buf_size) + +// Our global pointer. No parallelism. +// static char* stack_scoped_region; +// char* alloc_scoped() { return stack_scoped_region; } + + + +// ------------------------------------- +// Basic types +// ------------------------------------- + +// Must be consistent with sizeOfTy defined in Gibbon.Language.Syntax. + +typedef unsigned char TagTyPacked; +typedef unsigned char TagTyBoxed; +typedef long long IntTy; +typedef char CharTy; +typedef float FloatTy; +typedef unsigned long long SymTy; +typedef bool BoolTy; +typedef char* PtrTy; +typedef char* CursorTy; + +// ------------------------------------- +// Arenas and dictionaries +// ------------------------------------- + +typedef struct mem_arena { + int ind; + char* mem; // TODO(vollmerm): make this a list of chunks? + void* reflist; +} mem_arena_t; + +typedef mem_arena_t* ArenaTy; + +ArenaTy alloc_arena() { + ArenaTy ar = ALLOC(sizeof(mem_arena_t)); + ar->ind = 0; + ar->mem = malloc(global_inf_buf_max_chunk_size); + ar->reflist = 0; + return ar; +} + +void free_arena(ArenaTy ar) { + free(ar->mem); + // TODO(vollmerm): free everything in ar->reflist + free(ar); +} + +CursorTy extend_arena(ArenaTy ar, int size) { + CursorTy ret = ar->mem + ar->ind; + ar->ind += size; + return ret; +} + +typedef struct dict_item { + struct dict_item * next; + int key; + void * ptrval; +} dict_item_t; + +dict_item_t * dict_alloc(ArenaTy ar) { + return (dict_item_t *) extend_arena(ar, sizeof(dict_item_t)); // ALLOC(sizeof(dict_item_t)); +} + +dict_item_t *dict_insert_ptr(ArenaTy ar, dict_item_t *ptr, SymTy key, PtrTy val) { + dict_item_t *ret = dict_alloc(ar); + ret->key = key; + ret->ptrval = val; + ret->next = ptr; + return ret; +} + +PtrTy dict_lookup_ptr(dict_item_t *ptr, SymTy key) { + while (ptr != 0) { + if (ptr->key == key) { + return ptr->ptrval; + } else { + ptr = ptr->next; + } + } + printf("Error, key %lld not found!\n",key); + exit(1); +} + +// ------------------------------------- +// Sets +// ------------------------------------- + + +struct set_elem { + int val; + UT_hash_handle hh; +}; + +typedef struct set_elem* SymSetTy; + +SymSetTy empty_set() { + return NULL; +} + +SymSetTy insert_set(SymSetTy set, int sym) { + SymSetTy s; + HASH_FIND_INT(set, &sym, s); /* sym already in the hash? */ + if (s==NULL) { + s = malloc(sizeof(struct set_elem)); + s->val = sym; + HASH_ADD_INT(set,val,s); + } + return set; +} + +BoolTy contains_set(SymSetTy set, int sym) { + SymSetTy s; + HASH_FIND_INT(set, &sym, s); + return (s!=NULL); +} + +// ------------------------------------- +// Sym Hash +// ------------------------------------- + +struct sym_hash_elem { + int key; + int val; + UT_hash_handle hh; +}; + +typedef struct sym_hash_elem* SymHashTy; + +typedef struct sym_hash_elem* IntHashTy; + +SymHashTy empty_hash() { + return NULL; +} + +SymHashTy insert_hash(SymHashTy hash, int k, int v) { + SymHashTy s; + // NOTE: not checking for duplicates! + // s = malloc(sizeof(struct sym_hash_elem)); + s = ALLOC(sizeof(struct sym_hash_elem)); + s->val = v; + s->key = k; + HASH_ADD_INT(hash,key,s); + + return hash; +} + +IntTy lookup_hash(SymHashTy hash, int k) { + SymHashTy s; + HASH_FIND_INT(hash,&k,s); + if (s==NULL) { + return k; // NOTE: return original key if val not found + // TODO(vollmerm): come up with something better to do here + } else { + return s->val; + } +} + +BoolTy contains_hash(SymHashTy hash, int sym) { + SymHashTy s; + HASH_FIND_INT(hash,&sym,s); + return (s!=NULL); +} + +// ------------------------------------- +// Helpers +// ------------------------------------- + +char* read_benchfile_param() { + if (global_benchfile_param == NULL) { + fprintf(stderr, "read_benchfile_param: benchmark input file was not set! Set using --bench-input.\n"); + exit(1); + } else + return global_benchfile_param; +} + +char* read_arrayfile_param() { + if (global_arrayfile_param == NULL) { + fprintf(stderr, "read_arrayfile_param: array input file was not set! Set using --array-input.\n"); + exit(1); + } else + return global_arrayfile_param; +} + +IntTy read_arrayfile_length_param() { + if (global_arrayfile_length_param == -1) { + fprintf(stderr, "read_arrayfile_length_param: array input file length was not set! Set using --array-input-length.\n"); + exit(1); + } else + return global_arrayfile_length_param; +} + + +// fun fact: __ prefix is actually reserved and this is an undefined behavior. +// These functions must be provided by the code generator. +int __main_expr(); + + +void show_usage(char** argv) +{ + printf("\n"); + printf("This binary was generated by the Gibbon compiler.\n"); + printf("\n"); + printf("Usage: %s [OPTS] [size] [iters]\n", argv[0]); + + printf("\n"); + printf("Options:\n"); + printf(" --buffer-size Set the buffer size (default %lld).\n", global_init_biginf_buf_size); + printf(" --bench-input Set the input file read for benchmarking. Applies only\n"); + printf(" IF the program was *compiled* with --bench-fun. \n"); + return; +} + +double avg(const double* arr, int n) +{ + double sum = 0.0; + for(int i=0; itv_sec - t0->tv_sec) + + ((double)(t1->tv_nsec - t0->tv_nsec) / 1000000000.0); +} + +int compare_doubles(const void *a, const void *b) +{ + const double *da = (const double *) a; + const double *db = (const double *) b; + return (*da > *db) - (*da < *db); +} + +// Exponentiation +IntTy expll(IntTy base, IntTy pow) { + if (base == 2) { + return (1 << pow); + } else { + IntTy i, result = 1; + for (i = 0; i < pow; i++) + result *= base; + return result; + } + } + +// ------------------------------------- +// Symbol table +// ------------------------------------- + +#define global_max_symbol_len 256 + +// Invariant: should always be equal to max(sym_table_keys) +static SymTy global_gensym_counter = 0; + +// Its value is updated by the flags parser. +static char *global_bench_prog_param; + +static SymTy newline_symbol = -1; +static SymTy space_symbol = -1; +static SymTy comma_symbol = -1; +static SymTy leftparen_symbol = -1; +static SymTy rightparen_symbol = -1; + +typedef struct SymTable_elem { + SymTy idx; /* key */ + char value[global_max_symbol_len]; + UT_hash_handle hh; /* makes this structure hashable */ +} SymTable_elem; + +// important! initialize to NULL +SymTable_elem *global_sym_table = NULL; + +void add_symbol(SymTy idx, char *value) { + struct SymTable_elem *s; + s = ALLOC(sizeof(struct SymTable_elem)); + s->idx = idx; + strcpy(s->value, value); + HASH_ADD(hh, global_sym_table, idx, sizeof(IntTy), s); + if (idx > global_gensym_counter) { + global_gensym_counter = idx; + } +} + +void set_newline(SymTy idx) { + newline_symbol = idx; + add_symbol(idx,"NEWLINE"); +} + +void set_space(SymTy idx) { + space_symbol = idx; + add_symbol(idx,"SPACE"); +} + +void set_comma(SymTy idx) { + comma_symbol = idx; + add_symbol(idx,"COMMA"); +} + +void set_leftparen(SymTy idx) { + leftparen_symbol = idx; + add_symbol(idx,"LEFTPAREN"); +} + +void set_rightparen(SymTy idx) { + rightparen_symbol = idx; + add_symbol(idx,"RIGHTPAREN"); +} + +IntTy print_symbol(SymTy idx) { + if (idx == comma_symbol) { + return printf(","); + } else if (idx == newline_symbol) { + return printf("\n"); + } else if (idx == space_symbol) { + return printf(" "); + } else if (idx == leftparen_symbol) { + return printf("("); + } else if (idx == rightparen_symbol) { + return printf(")"); + } else { + struct SymTable_elem *s; + HASH_FIND(hh, global_sym_table, &idx, sizeof(SymTy), s); + if (s == NULL) { + return printf("%lld", idx); + } else { + return printf("%s", s->value); + } + + } +} + +#ifdef _PARALLEL +SymTy gensym() { + SymTy idx = __atomic_add_fetch(&global_gensym_counter, 1, __ATOMIC_SEQ_CST); + return idx; +} +#else +SymTy gensym() { + global_gensym_counter += 1; + SymTy idx = global_gensym_counter; + return idx; +} +#endif + +void free_symtable() { + struct SymTable_elem *elt, *tmp; + HASH_ITER(hh, global_sym_table, elt, tmp) { + HASH_DEL(global_sym_table,elt); + } + free(elt); + free(tmp); +} + +/* + +---------------------------------------- +Garbage collection +---------------------------------------- + + Gibbon has "growing regions" i.e each logical region is backed by a doubly linked-list + of smaller chunks which grows as required. In addition to actual data, each chunk + stores some additional metadata (RegionFooter) to chain the chunks together in a list + and for garbage collection. The footer: + + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + serialized data | rf_reg_metadata_ptr | rf_seq_no | rf_size | rf_next | rf_prev + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + The metadata after the serialized data serves various purposes: + + - rf_reg_metadata_ptr: A pointer to a RegionTy struct that contains various metadata. + Of particular interest to us are the fields: + + = reg_id: A unique identifier for a region. + + = refcount and outset: Whenever an inter-region indirection is created, we record that information + using these two fields. Suppose we have an indirection from region A that points to some chunk + in region B. Then A's outset will store a pointer to that chunk's footer, and B's refcount will + be bumped by 1. Note that all there's only 1 refcount cell, and 1 outset per logical region, + and chunks only store a pointer to them. + + - rf_seq_no: The index of this particular chunk in the list. + + - rf_size: Used during bounds checking to calculate the size of the next region in + the linked list. + + - rf_next / rf_prev: Point to the next and previous chunk respectively. + + +There are two ways in which a region may be freed: + +(1) Whenever it goes out of scope + + The RTS tries to free a region whenever it goes out of scope. But this doesn't always succeed as + regions sometimes contain values that "escape". One reason why this'll happen is if there's an + indirection from A->B, and A lives longer than B. + In such a case, when B goes out of scope it's refcount won't be 0, and the RTS won't free it. + This brings us to (2). + +(2) + + When the RTS successfully frees a region, it decrements the refcounts of all the regions it + points to (via the outset). At the same time, if it encounters a region in the outset whoose + refcount becomes 0 after the decrement, it calls free_region on that. This way we can be sure + that all regions will eventually be garbage collected before the program exits. + + + +Why is it a doubly linked-list? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Due to way that bounds-checking works, the pointers in the outset may actually point to any +arbitrary chunk in the chain. However, we must call free_region on the first one to ensure that +all of them are GC'd. So we need pointers to traverse backward get to the first one. +'trav_to_first_chunk' accomplishes this. + + */ + +#define MAX_OUTSET_LENGTH 10 + +typedef struct RegionTy_struct { + SymTy reg_id; + uint reg_refcount; + CursorTy reg_heap; + uint reg_outset_len; + CursorTy reg_outset[MAX_OUTSET_LENGTH]; +} RegionTy; + +typedef struct RegionFooter_struct { + RegionTy *rf_reg_metadata_ptr; + + IntTy rf_seq_no; + IntTy rf_size; + struct RegionFooter_struct *rf_next; + struct RegionFooter_struct *rf_prev; +} RegionFooter; + +typedef struct ChunkTy_struct { + CursorTy chunk_start; + CursorTy chunk_end; +} ChunkTy; + +static inline void insert_into_outset(CursorTy ptr, RegionTy *reg) { + uint outset_len = reg->reg_outset_len; + // Check for duplicates. + for (uint i = 0; i < outset_len; i++) { + if (ptr == reg->reg_outset[i]) { + return; + } + } + // Otherwise, insert into the outset. + reg->reg_outset[outset_len] = ptr; + reg->reg_outset_len = outset_len + 1; + return; +} + +static inline void remove_from_outset(CursorTy ptr, RegionTy *reg) { + uint outset_len = reg->reg_outset_len; + CursorTy *outset = reg->reg_outset; + int i; + if (outset_len == 0) { + fprintf(stderr, "remove_from_outset: empty outset\n"); + exit(1); + } + // Position of 'ptr' in the outset. + int elt_idx = -1; + for (i = 0; i < outset_len; i++) { + if (ptr == outset[i]) { + elt_idx = i; + } + } + if (elt_idx == -1) { + fprintf(stderr, "remove_from_outset: element not found\n"); + exit(1); + } + // Move all elements ahead of 'elt_idx' back by one position. + for (i = elt_idx; i < outset_len; i++) { + outset[i] = outset[i+1]; + } + return; +} + +RegionTy *alloc_region(IntTy size) { + // Allocate the region metadata. + RegionTy *reg = ALLOC(sizeof(RegionTy)); + if (reg == NULL) { + printf("alloc_region: allocation failed: %ld", sizeof(RegionTy)); + exit(1); + } + + // Allocate the first chunk. + IntTy total_size = size + sizeof(RegionFooter); + CursorTy heap = ALLOC_PACKED_BIG(total_size); + if (heap == NULL) { + printf("alloc_region: malloc failed: %lld", total_size); + exit(1); + } + // Not heap+total_size, since we must keep space for the footer. + CursorTy heap_end = heap + size; + + // Initialize metadata fields. + reg->reg_id = gensym(); + reg->reg_refcount = 1; + reg->reg_heap = heap; + reg->reg_outset_len = 0; + +#ifdef _DEBUG + printf("Allocated a region(%lld): %lld bytes.\n", reg->reg_id, size); +#endif + + // Write the footer. + RegionFooter *footer = (RegionFooter *) heap_end; + footer->rf_reg_metadata_ptr = reg; + footer->rf_seq_no = 1; + footer->rf_size = size; + footer->rf_next = NULL; + footer->rf_prev = NULL; + + return reg; +} + +RegionTy *alloc_counted_region(IntTy size) { + // Bump the count. + bump_global_region_count(); + return alloc_region(size); +} + +ChunkTy alloc_chunk(CursorTy end_old_chunk) { + // Get size from current footer. + RegionFooter *footer = (RegionFooter *) end_old_chunk; + IntTy newsize = footer->rf_size * 2; + // See #110. + if (newsize > global_inf_buf_max_chunk_size) { + newsize = global_inf_buf_max_chunk_size; + } + IntTy total_size = newsize + sizeof(RegionFooter); + + // Allocate. + CursorTy start = ALLOC_PACKED_BIG(total_size); + if (start == NULL) { + printf("alloc_chunk: malloc failed: %lld", total_size); + exit(1); + } + CursorTy end = start + newsize; + + // Link the next chunk's footer. + footer->rf_next = (RegionFooter *) end; + + // Write the footer. + RegionFooter* new_footer = (RegionFooter *) end; + new_footer->rf_reg_metadata_ptr = footer->rf_reg_metadata_ptr; + new_footer->rf_seq_no = footer->rf_seq_no + 1; + new_footer->rf_size = newsize; + new_footer->rf_next = NULL; + new_footer->rf_prev = footer; + +#ifdef _DEBUG + RegionTy *reg = (RegionTy*) new_footer->rf_reg_metadata_ptr; + printf("alloc_chunk: allocated %lld bytes for region %lld.\n", total_size, reg->reg_id); +#endif + + return (ChunkTy) {start , end}; +} + +RegionFooter* trav_to_first_chunk(RegionFooter *footer) { + if (footer->rf_seq_no == 1) { + return footer; + } else if (footer->rf_prev == NULL) { + fprintf(stderr, "No previous chunk found at rf_seq_no: %lld", footer->rf_seq_no); + return NULL; + } else { + trav_to_first_chunk((RegionFooter *) footer->rf_prev); + } + return NULL; +} + +uint get_ref_count(CursorTy end_ptr) { + RegionFooter *footer = (RegionFooter *) end_ptr; + RegionTy *reg = (RegionTy *) footer->rf_reg_metadata_ptr; + return reg->reg_refcount; +} + +// B is the pointer, and A is the pointee (i.e B -> A). +// Bump A's refcount and update B's outset. +static inline void bump_ref_count(CursorTy end_b, CursorTy end_a) { + // Grab footers. + RegionFooter *footer_a = (RegionFooter *) end_a; + RegionFooter *footer_b = (RegionFooter *) end_b; + + // Grab metadata. + RegionTy *reg_a = (RegionTy *) footer_a->rf_reg_metadata_ptr; + RegionTy *reg_b = (RegionTy *) footer_b->rf_reg_metadata_ptr; + + // Bump A's refcount. + uint current_refcount, new_refcount; + current_refcount = reg_a->reg_refcount; + new_refcount = current_refcount + 1; + reg_a->reg_refcount = new_refcount; + +#ifdef _DEBUG + printf("bump_ref_count: %lld -> %lld\n", reg_b->reg_id, reg_a->reg_id); + printf("bump_ref_count: old-refcount=%d, old-outset-len=%d:\n", current_refcount, reg_b->reg_outset_len); + assert(current_refcount == reg_b->reg_outset_len+1); +#endif + + // Add A to B's outset. + insert_into_outset(end_a, reg_b); + +#ifdef _DEBUG + // printf("bump_ref_count: Added %p to %lld's outset, %p.\n", end_a, reg_b->reg_id, reg_b); + printf("bump_ref_count: new-refcount=%d, new-outset-len=%d\n", new_refcount, reg_b->reg_outset_len); + assert(new_refcount == reg_b->reg_outset_len+1); +#endif + + return; +} + +void free_region(CursorTy end_reg) { + // Grab footer and the metadata. + RegionFooter *footer = (RegionFooter *) end_reg; + RegionTy *reg = (RegionTy *) footer->rf_reg_metadata_ptr; + + // + RegionFooter *first_chunk_footer, *next_chunk_footer; + CursorTy first_chunk, next_chunk; + + // Decrement current reference count. + uint current_refcount, new_refcount; + current_refcount = reg->reg_refcount; + new_refcount = 0; + if (current_refcount != 0) { + new_refcount = current_refcount - 1; + reg->reg_refcount = new_refcount; + } + +#ifdef _DEBUG + printf("free_region(%lld): refcounts (1): old-refcount=%d, new-refcount=%d:\n", reg->reg_id, current_refcount, new_refcount); +#endif + + + // Free this region recount is 0. + if (new_refcount == 0) { + +#ifdef _DEBUG + printf("free_region(%lld): outset length: %d\n", reg->reg_id, reg->reg_outset_len); +#endif + + // Decrement refcounts, free regions with refcount==0 and also free + // elements of the outset. + if (reg->reg_outset_len != 0) { + uint outset_len = reg->reg_outset_len; + CursorTy *outset = reg->reg_outset; + RegionFooter *elt_footer; + RegionTy *elt_reg; + uint elt_current_refcount, elt_new_refcount; + CursorTy to_be_removed[MAX_OUTSET_LENGTH]; + uint to_be_removed_idx = 0; + for (int i = 0; i < outset_len; i++) { + elt_footer = (RegionFooter *) outset[i]; + elt_reg = (RegionTy *) elt_footer->rf_reg_metadata_ptr; +#ifdef _DEBUG + elt_current_refcount = elt_reg->reg_refcount; +#endif + elt_new_refcount = elt_current_refcount - 1; + elt_reg->reg_refcount = elt_new_refcount; +#ifdef _DEBUG + printf("free_region(%lld): old-refcount=%d, new-refcount=%d:\n", + elt_reg->reg_id, elt_current_refcount, elt_reg->reg_refcount); +#endif + if (elt_new_refcount == 0) { + // See [Why is it a doubly linked-list?] above + first_chunk_footer = trav_to_first_chunk(elt_footer); + if (first_chunk_footer != NULL) { + free_region((CursorTy) first_chunk_footer); + } + } + to_be_removed[to_be_removed_idx] = outset[i]; + to_be_removed_idx++; + } + // Remove elements from the outset. + for (uint i = 0; i < to_be_removed_idx; i++) { + remove_from_outset(to_be_removed[i], reg); + } + } + + +#ifdef _DEBUG + // Bookkeeping + IntTy num_freed_chunks = 0, total_bytesize = 0; +#endif + + // Free the chunks in this region. + first_chunk = end_reg - footer->rf_size; + first_chunk_footer = footer; + next_chunk = (char*) footer->rf_next; + +#ifdef _DEBUG + printf("free_region(%lld)\n", reg->reg_id); +#endif + +#ifdef _DEBUG + num_freed_chunks++; + total_bytesize = total_bytesize + first_chunk_footer->rf_size; +#endif + free(first_chunk); + + while (next_chunk != NULL) { + next_chunk_footer = (RegionFooter *) next_chunk; + #ifdef _DEBUG + num_freed_chunks++; + total_bytesize = total_bytesize + next_chunk_footer->rf_size; + #endif + free(next_chunk - next_chunk_footer->rf_size); + next_chunk = (char*) next_chunk_footer->rf_next; + } + +#ifdef _DEBUG + printf("free_region(%lld): Freed %lld bytes across %lld chunks.\n", + reg->reg_id, total_bytesize, num_freed_chunks); +#endif + + // Free the metadata. + free(reg); + + } else { +#ifdef _DEBUG + printf("free_region(%lld): non-zero refcount: %d.\n", + reg->reg_id, reg->reg_refcount); +#endif + } +} + +// Assume that all nodes with size information have tags >= 150. +BoolTy is_big(IntTy i, CursorTy cur) { + TagTyPacked tag = *(TagTyPacked *) cur; + if (tag >= 150) { + cur += 1; + IntTy size = *(IntTy *) cur; + if (size >= i) { + return true; + } else { + return false; + } + } + return false; +} + +// ------------------------------------- +// Vectors +// ------------------------------------- + +typedef struct VectorTy_struct { + // Bounds on the vector. + IntTy vec_lower, vec_upper; + + // Size of each element. + IntTy vec_elt_size; + + // Actual elements of the vector. + void* vec_data; +} VectorTy; + +VectorTy* vector_alloc(IntTy num, IntTy elt_size) { + VectorTy *vec = ALLOC(sizeof(VectorTy)); + if (vec == NULL) { + printf("alloc_vector: malloc failed: %ld", sizeof(VectorTy)); + exit(1); + } + void* data = ALLOC(num * elt_size); + if (data == NULL) { + printf("alloc_vector: malloc failed: %ld", sizeof(num * elt_size)); + exit(1); + } + vec->vec_lower = 0; + vec->vec_upper = num; + vec->vec_elt_size = elt_size; + vec->vec_data = data; + return vec; +} + +IntTy vector_length(VectorTy *vec) { + return (vec->vec_upper - vec->vec_lower); +} + +BoolTy vector_is_empty(VectorTy *vec) { + return (vector_length(vec) == 0); +} + +VectorTy* vector_slice(IntTy i, IntTy n, VectorTy *vec) { + IntTy lower = vec->vec_lower + i; + IntTy upper = vec->vec_lower + i + n; + if ((lower > vec->vec_upper)) { + printf("vector_slice: lower out of bounds, %lld > %lld", lower, vec->vec_upper); + exit(1); + } + if ((upper > vec->vec_upper)) { + printf("vector_slice: upper out of bounds: %lld > %lld", upper, vec->vec_upper); + exit(1); + } + VectorTy *vec2 = ALLOC(sizeof(VectorTy)); + if (vec == NULL) { + printf("vector_slice: malloc failed: %ld", sizeof(VectorTy)); + exit(1); + } + vec2->vec_lower = lower; + vec2->vec_upper = upper; + vec2->vec_elt_size = vec->vec_elt_size; + vec2->vec_data = vec->vec_data; + return vec2; +} + +// The callers must cast the return value. +static inline void* vector_nth(VectorTy *vec, IntTy i) { + // if (i < vec->lower || i > vec->upper) { + // printf("vector_nth index out of bounds: %lld (%lld,%lld) \n", i, vec->vec_lower, vec->vec_upper); + // exit(1); + // } + return (vec->vec_data + (vec->vec_elt_size * (vec->vec_lower + i))); +} + +static inline VectorTy* vector_inplace_update(VectorTy *vec, IntTy i, void* elt) { + void* dst = vector_nth(vec, i); + memcpy(dst, elt, vec->vec_elt_size); + return vec; +} + +static inline VectorTy* vector_copy(VectorTy *vec) { + IntTy len = vector_length(vec); + void *start = vector_nth(vec, 0); + VectorTy *vec2 = vector_alloc(len, vec->vec_elt_size); + memcpy(vec2->vec_data, start, len * vec->vec_elt_size); + return vec2; +} + +static inline VectorTy* vector_inplace_sort(VectorTy *vec, int (*compar)(const void *, const void*)) { + void *start = vector_nth(vec, 0); + qsort(start, vector_length(vec), vec->vec_elt_size, compar); + return vec; +} + +static inline VectorTy* vector_sort(VectorTy *vec, int (*compar)(const void *, const void*)) { + VectorTy *vec2 = vector_copy(vec); + vector_inplace_sort(vec2, compar); + return vec2; +} + +static inline VectorTy* vector_concat(VectorTy *vec) { + // Length of the input vector. + IntTy len = vector_length(vec); + // Length of the concatenated vector. + IntTy result_len = 0; + // Size of each element in the concatenated vector. + IntTy result_elt_size = 0; + VectorTy **elt_ref, *elt; + for (IntTy i = 0; i < len; i++) { + elt_ref = vector_nth(vec, i); + elt = *elt_ref; + result_elt_size = elt->vec_elt_size; + result_len += vector_length(elt); + } + + // Concatenated vector. + VectorTy *result = vector_alloc(result_len, result_elt_size); + IntTy elt_len; + // A counter that tracks the index of elements in 'result'. + IntTy k = 0; + for (IntTy i = 0; i < len; i++) { + elt_ref = vector_nth(vec, i); + elt = *elt_ref; + elt_len = vector_length(elt); + + for (IntTy j = 0; j < elt_len; j++) { + void* k_elt = vector_nth(elt, j); + vector_inplace_update(result, k, k_elt); + k++; + } + } + + return result; +} + +static inline void vector_free(VectorTy *vec) { + free(vec->vec_data); + free(vec); + return; +} + +static inline VectorTy* vector_merge(VectorTy *vec1, VectorTy *vec2) { + if (vec1->vec_upper != vec2->vec_lower) { + printf("vector_merge: non-contiguous slices, (%lld,%lld), (%lld,%lld).", + vec1->vec_lower, vec1->vec_upper, vec2->vec_lower, vec2->vec_upper); + exit(1); + } + VectorTy *merged = ALLOC(sizeof(VectorTy)); + if (merged == NULL) { + printf("vector_merge: malloc failed: %ld", sizeof(VectorTy)); + exit(1); + } + merged->vec_lower = vec1->vec_lower; + merged->vec_upper = vec2->vec_upper; + merged->vec_elt_size = vec1->vec_elt_size; + merged->vec_data = vec1->vec_data; + return merged; +} + +void print_timing_array(VectorTy *times) { + printf("TIMES: ["); + double *d; + IntTy n = vector_length(times); + for(int i = 0; i < n; i++) { + d = vector_nth(times, i); + if (i == (n-1)) { + printf("%f",*d); + } + else { + printf("%f, ",*d); + } + } + printf("]\n"); +} + +double sum_timing_array(VectorTy *times) { + double *d; + double acc = 0; + for(int i = 0; i < vector_length(times); i++) { + d = vector_nth(times, i); + acc += *d; + } + return acc; +} + +// ------------------------------------- +// Linked lists +// ------------------------------------- + +typedef struct ListTy_struct { + IntTy ll_data_size; + void* ll_data; + struct ListTy_struct* ll_next; +} ListTy; + +static inline ListTy* list_alloc(IntTy data_size) { + // ListTy *ls = ALLOC(sizeof(ListTy)); + ListTy *ls = BUMPALLOC(sizeof(ListTy)); + ls->ll_data_size = data_size; + ls->ll_data = NULL; + ls->ll_next = NULL; + return ls; +} + +static inline BoolTy list_is_empty(ListTy *ls) { + return ls->ll_next == NULL; +} + +static inline ListTy* list_cons(void* elt, ListTy *ls) { + // void* data = ALLOC(ls->data_size); + void* data = BUMPALLOC(ls->ll_data_size); + if (data == NULL) { + printf("list_cons: malloc failed: %lld", ls->ll_data_size); + exit(1); + } + memcpy(data, elt, ls->ll_data_size); + // ListTy *res = ALLOC(sizeof(ListTy)); + ListTy *res = BUMPALLOC(sizeof(ListTy)); + res->ll_data_size = ls->ll_data_size; + res->ll_data = data; + res->ll_next = (ListTy*) ls; + return res; +} + +static inline void* list_head(ListTy *ls) { + return ls->ll_data; +} + +static inline ListTy* list_tail(ListTy *ls) { + return ls->ll_next; +} + +static inline void list_free(ListTy *ls) { + free(ls->ll_data); + free(ls); + return; +} + +static inline ListTy* list_copy(ListTy *ls) { + ListTy *ls2 = list_alloc(ls->ll_data_size); + if (ls->ll_data != NULL) { + void* data = BUMPALLOC(ls->ll_data_size); + memcpy(data, ls->ll_data, ls->ll_data_size); + ls2->ll_data = data; + } + ls2->ll_next = ls->ll_next; + return ls2; +} + +// ------------------------------------- +// Ppm Images +// ------------------------------------- + +typedef struct __Pixel_struct { + IntTy field0; + IntTy field1; + IntTy field2; +} __Pixel; + +void writePpm(char* filename, IntTy width, IntTy height, VectorTy *pixels); +void writePpm_loop(FILE *fp, IntTy idx, IntTy end, VectorTy *pixels); + +// Example: writePpm("gibbon_rgb_1000.ppm", 1000, 1000, pixels); +void writePpm(char* filename, IntTy width, IntTy height, VectorTy *pixels) +{ + FILE *fp; + fp = fopen(filename, "w+"); + fprintf(fp, "P3\n"); + fprintf(fp, "%lld %lld\n255\n", width, height); + IntTy len = vector_length(pixels); + writePpm_loop(fp, 0, len, pixels); + fclose(fp); + return; +} + +void writePpm_loop(FILE *fp, IntTy idx, IntTy end, VectorTy *pixels) +{ + BoolTy fltIf_5768_6575 = idx == end; + + if (fltIf_5768_6575) { + return; + } else { + __Pixel *tmp_112; + tmp_112 = (__Pixel *) vector_nth(pixels, idx); + __Pixel tup = *tmp_112; + IntTy x = tup.field0; + IntTy y = tup.field1; + IntTy z = tup.field2; + // write to file. + fprintf(fp, "%lld %lld %lld\n", x, y, z); + writePpm_loop(fp, (idx+1), end, pixels); + } +} + +/* -------------------------------------------------------------------------------- */ + +int main(int argc, char** argv) +{ + // parameters to parse: + // + // num iterations: How many times to repeat a benchmark. + // tree size: An integer passes to `build_tree()`. + + struct rlimit lim; + int code; + if ( (code = getrlimit(RLIMIT_STACK, &lim)) ) { + fprintf(stderr, " [gibbon rts] failed to getrlimit, code %d\n", code); + exit(1); + } + + // lim.rlim_cur = 1024LU * 1024LU * 1024LU; // 1GB stack. + lim.rlim_cur = 512LU * 1024LU * 1024LU; // 500MB stack. + // lim.rlim_max = lim.rlim_cur; // Normal users may only be able to decrease this. + + // WARNING: Haven't yet figured out why this doesn't work on MacOS... +#ifndef __APPLE__ + code = setrlimit(RLIMIT_STACK, &lim); + while (code) { + fprintf(stderr, " [gibbon rts] Failed to set stack size to %llu, code %d\n", (unsigned long long)lim.rlim_cur, code); + lim.rlim_cur /= 2; + // lim.rlim_max /= 2; + if(lim.rlim_cur < 100 * 1024) { + fprintf(stderr, " [gibbon rts] Failed setrlimit stack size to something reasonable; giving up.\n"); + break; // abort(); + } + int code = setrlimit(RLIMIT_STACK, &lim); + } +#endif + + int got_numargs = 0; // How many numeric arguments have we got. + + int i; + for (i = 1; i < argc; ++i) + { + if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) { + show_usage(argv); + exit(0); + } + else if (strcmp(argv[i], "--biginf-buffer-size") == 0 && i < argc - 1) + { + global_init_biginf_buf_size = atoll(argv[i + 1]); + i++; + } + else if (strcmp(argv[i], "--inf-buffer-size") == 0 && i < argc - 1) + { + global_init_inf_buf_size = atoll(argv[i + 1]); + i++; + } + else if ((strcmp(argv[i], "--bench-input") == 0)) { + if (i+1 >= argc) { + fprintf(stderr, "Not enough arguments after --bench-input, expected .\n"); + show_usage(argv); + exit(1); + } + global_benchfile_param = argv[i+1]; + i++; + } + else if ((strcmp(argv[i], "--array-input") == 0)) { + if (i+1 >= argc) { + fprintf(stderr, "Not enough arguments after --array-input, expected .\n"); + show_usage(argv); + exit(1); + } + global_arrayfile_param = argv[i+1]; + i++; + } + else if (strcmp(argv[i], "--array-input-length") == 0 && i < argc - 1) { + global_arrayfile_length_param = atoll(argv[i+1]); + i++; + } + else if (strcmp(argv[i], "--bench-prog") == 0 && i < argc - 1) { + int len = strlen(argv[i+1]); + global_bench_prog_param = (char*) malloc((len+1)*sizeof(char)); + strncpy(global_bench_prog_param,argv[i+1],len); + i++; + } + // If present, we expect the two arguments to be + else if (got_numargs >= 2) { + fprintf(stderr, "Extra arguments left over: "); + for(; i < argc; i++) fprintf(stderr, "%s ", argv[i]); + show_usage(argv); + exit(1); + } else { + if (got_numargs == 0) { + global_size_param = atoll(argv[i]); + got_numargs ++; + } else { + global_iters_param = atoll(argv[i]); + } + } + } + + // Initialize global_bench_prog_param to an empty string in case + // the runtime argument --bench-prog isn't passed. + if (global_bench_prog_param == NULL) { + global_bench_prog_param = (char*) malloc(1*sizeof(char)); + *global_bench_prog_param = '\n'; + } + + __main_expr(); + + return 0; +} + +// ----------------------------------------------------------------------------- +// Program starts here +// ----------------------------------------------------------------------------- + +int __main_expr() +{ } \ No newline at end of file diff --git a/benchmarks/modules/Common.hs b/benchmarks/modules/Common.hs new file mode 100644 index 000000000..d4078c33b --- /dev/null +++ b/benchmarks/modules/Common.hs @@ -0,0 +1,4 @@ +module Common where + + data Maybe a = Nothing + | Just a \ No newline at end of file diff --git a/benchmarks/modules/Layout.c b/benchmarks/modules/Layout.c new file mode 100644 index 000000000..ee9099927 --- /dev/null +++ b/benchmarks/modules/Layout.c @@ -0,0 +1,3184 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// #include +#ifdef _WIN64 +#include +#endif +#include +#include +#include // For va_start etc +#include +#include +#include +#include +#ifdef _POINTER +#include +#endif +#ifdef _PARALLEL +#include +#include +#endif + +#define KB 1024lu +#define MB (KB * 1000lu) +#define GB (MB * 1000lu) + +#define REDIRECTION_TAG 255 +#define INDIRECTION_TAG 254 + +// Initial size of BigInfinite buffers +static long long global_init_biginf_buf_size = (4 * GB); + +// Initial size of Infinite buffers +static long long global_init_inf_buf_size = 1 * KB; + +// Maximum size of a chunk, see GitHub #110. +static long long global_inf_buf_max_chunk_size = 1 * GB; + +static long long global_size_param = 1; +static long long global_iters_param = 1; + +static char* global_benchfile_param = NULL; +static char* global_arrayfile_param = NULL; +// Number of lines in the arrayfile +static long long global_arrayfile_length_param = -1; + +// Sequential for now: +static const int num_workers = 1; + +// Count the number of regions allocated. +static long long global_region_count = 0; +static bool global_region_count_flag = false; + +#ifdef _PARALLEL +static inline void bump_global_region_count() { + __atomic_add_fetch(&global_region_count, 1, __ATOMIC_SEQ_CST); + return; +} +#else +static inline void bump_global_region_count() { + global_region_count++; + return; +} +#endif + +static inline void print_global_region_count() { + printf("REGION_COUNT: %lld\n", global_region_count); + return; +} + +#define REDIRECTION_NODE_SIZE 9 +#define MAX(a,b) (((a)>(b))?(a):(b)) +#define MIN(a,b) (((a)<(b))?(a):(b)) + +// https://www.cprogramming.com/snippets/source-code/find-the-number-of-cpu-cores-for-windows-mac-or-linux +static int get_num_processors() { +#ifdef _WIN64 + SYSTEM_INFO sysinfo; + GetSystemInfo(&sysinfo); + return sysinfo.dwNumberOfProcessors; +#else + return sysconf(_SC_NPROCESSORS_ONLN); +#endif +} + +// Requires -std=gnu11 +int dbgprintf(const char *format, ...) { + int code = 0; + va_list args; + va_start(args, format); +#ifdef _DEBUG + code = vprintf(format, args); +#endif + va_end(args); + return code; +} + + +// ----------------------------------------------------------------------------- +// Allocators +// ----------------------------------------------------------------------------- + + +// ------------------------------------- +// Bump allocation for linked-lists +// ------------------------------------- + + +#ifdef _BUMPALLOC +// #define _DEBUG +#warning "Using bump allocator." + +__thread char* bumpalloc_heap_ptr = (char*)NULL; +__thread char* bumpalloc_heap_ptr_end = (char*)NULL; + +char* saved_heap_ptr_stack[100]; +int num_saved_heap_ptr = 0; + +// For simplicity just use a single large slab: +static inline void INITBUMPALLOC() { + bumpalloc_heap_ptr = (char*)malloc(global_init_biginf_buf_size); + bumpalloc_heap_ptr_end = bumpalloc_heap_ptr + global_init_biginf_buf_size; +#ifdef _DEBUG + printf("Arena size for bump alloc: %lld\n", global_init_biginf_buf_size); + printf("BUMPALLOC/INITBUMPALLOC DONE: heap_ptr = %p\n", bumpalloc_heap_ptr); +#endif +} + +static inline void* BUMPALLOC(long long n) { + if (! bumpalloc_heap_ptr) { + INITBUMPALLOC(); + } + if (bumpalloc_heap_ptr + n < bumpalloc_heap_ptr_end) { + char* old= bumpalloc_heap_ptr; + bumpalloc_heap_ptr += n; + return old; + } else { + fprintf(stderr, "Warning: bump allocator ran out of memory."); + exit(1); + } +} + +// Snapshot the current heap pointer value across all threads. +void save_alloc_state() { + dbgprintf("Saving(%p): pos %d", heap_ptr, num_saved_heap_ptr); + saved_heap_ptr_stack[num_saved_heap_ptr] = heap_ptr; + num_saved_heap_ptr++; + dbgprintf("\n"); +} + +void restore_alloc_state() { + if(num_saved_heap_ptr <= 0) { + fprintf(stderr, "Bad call to restore_alloc_state! Saved stack empty!\ne"); + exit(1); + } + num_saved_heap_ptr--; + dbgprintf("Restoring(%p): pos %d, discarding %p", + saved_heap_ptr_stack[num_saved_heap_ptr], num_saved_heap_ptr, bumpalloc_heap_ptr); + bumpalloc_heap_ptr = saved_heap_ptr_stack[num_saved_heap_ptr]; +} + + +#else +// Regular malloc mode: +void INITBUMPALLOC() {} +void save_alloc_state() {} +void restore_alloc_state() {} + +#define BUMPALLOC(n) malloc(n) + +#endif // BUMPALLOC + + +// ------------------------------------- +// ALLOC and ALLOC_PACKED macros +// ------------------------------------- + + +/* + +If parallelism is enabled, we always use a malloc based allocator +since Boehm GC is not thread-safe in its default configuration. It can be +made thread-safe by building it with appropriate flags, but we don't do that. +Presently, all parallel pointer-based programs will leak memory. + +*/ + +#ifdef _PARALLEL +#define ALLOC(n) malloc(n) +#define ALLOC_PACKED_BIG(n) malloc(n) +char *ALLOC_COUNTED(size_t size) { + bump_global_region_count(); + return ALLOC(size); +} +#else + #ifdef _POINTER +#define ALLOC(n) GC_MALLOC(n) +#define ALLOC_PACKED_BIG(n) GC_MALLOC(n) +char *ALLOC_COUNTED(size_t size) { + bump_global_region_count(); + return GC_MALLOC(size); +} + #else +#define ALLOC(n) malloc(n) +#define ALLOC_PACKED_BIG(n) malloc(n) +char *ALLOC_COUNTED(size_t size) { + bump_global_region_count(); + return ALLOC(size); +} + #endif // _POINTER +#endif // _PARALLEL + + +// Could try alloca() here. Better yet, we could keep our own, +// separate stack and insert our own code to restore the pointer +// before any function that (may have) called ALLOC_SCOPED returns. + +// #define ALLOC_SCOPED() alloca(1024) +#define ALLOC_SCOPED(n) alloca(n) +// #define ALLOC_SCOPED() alloc_scoped() + +// Stack allocation is either too small or blows our stack. +// We need a way to make a giant stack if we want to use alloca. +// #define ALLOC_SCOPED() ALLOC(global_init_biginf_buf_size) + +// Our global pointer. No parallelism. +// static char* stack_scoped_region; +// char* alloc_scoped() { return stack_scoped_region; } + + + +// ------------------------------------- +// Basic types +// ------------------------------------- + +// Must be consistent with sizeOfTy defined in Gibbon.Language.Syntax. + +typedef unsigned char TagTyPacked; +typedef unsigned char TagTyBoxed; +typedef long long IntTy; +typedef char CharTy; +typedef float FloatTy; +typedef unsigned long long SymTy; +typedef bool BoolTy; +typedef char* PtrTy; +typedef char* CursorTy; + +// ------------------------------------- +// Arenas and dictionaries +// ------------------------------------- + +typedef struct mem_arena { + int ind; + char* mem; // TODO(vollmerm): make this a list of chunks? + void* reflist; +} mem_arena_t; + +typedef mem_arena_t* ArenaTy; + +ArenaTy alloc_arena() { + ArenaTy ar = ALLOC(sizeof(mem_arena_t)); + ar->ind = 0; + ar->mem = malloc(global_inf_buf_max_chunk_size); + ar->reflist = 0; + return ar; +} + +void free_arena(ArenaTy ar) { + free(ar->mem); + // TODO(vollmerm): free everything in ar->reflist + free(ar); +} + +CursorTy extend_arena(ArenaTy ar, int size) { + CursorTy ret = ar->mem + ar->ind; + ar->ind += size; + return ret; +} + +typedef struct dict_item { + struct dict_item * next; + int key; + void * ptrval; +} dict_item_t; + +dict_item_t * dict_alloc(ArenaTy ar) { + return (dict_item_t *) extend_arena(ar, sizeof(dict_item_t)); // ALLOC(sizeof(dict_item_t)); +} + +dict_item_t *dict_insert_ptr(ArenaTy ar, dict_item_t *ptr, SymTy key, PtrTy val) { + dict_item_t *ret = dict_alloc(ar); + ret->key = key; + ret->ptrval = val; + ret->next = ptr; + return ret; +} + +PtrTy dict_lookup_ptr(dict_item_t *ptr, SymTy key) { + while (ptr != 0) { + if (ptr->key == key) { + return ptr->ptrval; + } else { + ptr = ptr->next; + } + } + printf("Error, key %lld not found!\n",key); + exit(1); +} + +// ------------------------------------- +// Sets +// ------------------------------------- + + +struct set_elem { + int val; + UT_hash_handle hh; +}; + +typedef struct set_elem* SymSetTy; + +SymSetTy empty_set() { + return NULL; +} + +SymSetTy insert_set(SymSetTy set, int sym) { + SymSetTy s; + HASH_FIND_INT(set, &sym, s); /* sym already in the hash? */ + if (s==NULL) { + s = malloc(sizeof(struct set_elem)); + s->val = sym; + HASH_ADD_INT(set,val,s); + } + return set; +} + +BoolTy contains_set(SymSetTy set, int sym) { + SymSetTy s; + HASH_FIND_INT(set, &sym, s); + return (s!=NULL); +} + +// ------------------------------------- +// Sym Hash +// ------------------------------------- + +struct sym_hash_elem { + int key; + int val; + UT_hash_handle hh; +}; + +typedef struct sym_hash_elem* SymHashTy; + +typedef struct sym_hash_elem* IntHashTy; + +SymHashTy empty_hash() { + return NULL; +} + +SymHashTy insert_hash(SymHashTy hash, int k, int v) { + SymHashTy s; + // NOTE: not checking for duplicates! + // s = malloc(sizeof(struct sym_hash_elem)); + s = ALLOC(sizeof(struct sym_hash_elem)); + s->val = v; + s->key = k; + HASH_ADD_INT(hash,key,s); + + return hash; +} + +IntTy lookup_hash(SymHashTy hash, int k) { + SymHashTy s; + HASH_FIND_INT(hash,&k,s); + if (s==NULL) { + return k; // NOTE: return original key if val not found + // TODO(vollmerm): come up with something better to do here + } else { + return s->val; + } +} + +BoolTy contains_hash(SymHashTy hash, int sym) { + SymHashTy s; + HASH_FIND_INT(hash,&sym,s); + return (s!=NULL); +} + +// ------------------------------------- +// Helpers +// ------------------------------------- + +char* read_benchfile_param() { + if (global_benchfile_param == NULL) { + fprintf(stderr, "read_benchfile_param: benchmark input file was not set! Set using --bench-input.\n"); + exit(1); + } else + return global_benchfile_param; +} + +char* read_arrayfile_param() { + if (global_arrayfile_param == NULL) { + fprintf(stderr, "read_arrayfile_param: array input file was not set! Set using --array-input.\n"); + exit(1); + } else + return global_arrayfile_param; +} + +IntTy read_arrayfile_length_param() { + if (global_arrayfile_length_param == -1) { + fprintf(stderr, "read_arrayfile_length_param: array input file length was not set! Set using --array-input-length.\n"); + exit(1); + } else + return global_arrayfile_length_param; +} + + +// fun fact: __ prefix is actually reserved and this is an undefined behavior. +// These functions must be provided by the code generator. +int __main_expr(); + + +void show_usage(char** argv) +{ + printf("\n"); + printf("This binary was generated by the Gibbon compiler.\n"); + printf("\n"); + printf("Usage: %s [OPTS] [size] [iters]\n", argv[0]); + + printf("\n"); + printf("Options:\n"); + printf(" --buffer-size Set the buffer size (default %lld).\n", global_init_biginf_buf_size); + printf(" --bench-input Set the input file read for benchmarking. Applies only\n"); + printf(" IF the program was *compiled* with --bench-fun. \n"); + return; +} + +double avg(const double* arr, int n) +{ + double sum = 0.0; + for(int i=0; itv_sec - t0->tv_sec) + + ((double)(t1->tv_nsec - t0->tv_nsec) / 1000000000.0); +} + +int compare_doubles(const void *a, const void *b) +{ + const double *da = (const double *) a; + const double *db = (const double *) b; + return (*da > *db) - (*da < *db); +} + +// Exponentiation +IntTy expll(IntTy base, IntTy pow) { + if (base == 2) { + return (1 << pow); + } else { + IntTy i, result = 1; + for (i = 0; i < pow; i++) + result *= base; + return result; + } + } + +// ------------------------------------- +// Symbol table +// ------------------------------------- + +#define global_max_symbol_len 256 + +// Invariant: should always be equal to max(sym_table_keys) +static SymTy global_gensym_counter = 0; + +// Its value is updated by the flags parser. +static char *global_bench_prog_param; + +static SymTy newline_symbol = -1; +static SymTy space_symbol = -1; +static SymTy comma_symbol = -1; +static SymTy leftparen_symbol = -1; +static SymTy rightparen_symbol = -1; + +typedef struct SymTable_elem { + SymTy idx; /* key */ + char value[global_max_symbol_len]; + UT_hash_handle hh; /* makes this structure hashable */ +} SymTable_elem; + +// important! initialize to NULL +SymTable_elem *global_sym_table = NULL; + +void add_symbol(SymTy idx, char *value) { + struct SymTable_elem *s; + s = ALLOC(sizeof(struct SymTable_elem)); + s->idx = idx; + strcpy(s->value, value); + HASH_ADD(hh, global_sym_table, idx, sizeof(IntTy), s); + if (idx > global_gensym_counter) { + global_gensym_counter = idx; + } +} + +void set_newline(SymTy idx) { + newline_symbol = idx; + add_symbol(idx,"NEWLINE"); +} + +void set_space(SymTy idx) { + space_symbol = idx; + add_symbol(idx,"SPACE"); +} + +void set_comma(SymTy idx) { + comma_symbol = idx; + add_symbol(idx,"COMMA"); +} + +void set_leftparen(SymTy idx) { + leftparen_symbol = idx; + add_symbol(idx,"LEFTPAREN"); +} + +void set_rightparen(SymTy idx) { + rightparen_symbol = idx; + add_symbol(idx,"RIGHTPAREN"); +} + +IntTy print_symbol(SymTy idx) { + if (idx == comma_symbol) { + return printf(","); + } else if (idx == newline_symbol) { + return printf("\n"); + } else if (idx == space_symbol) { + return printf(" "); + } else if (idx == leftparen_symbol) { + return printf("("); + } else if (idx == rightparen_symbol) { + return printf(")"); + } else { + struct SymTable_elem *s; + HASH_FIND(hh, global_sym_table, &idx, sizeof(SymTy), s); + if (s == NULL) { + return printf("%lld", idx); + } else { + return printf("%s", s->value); + } + + } +} + +#ifdef _PARALLEL +SymTy gensym() { + SymTy idx = __atomic_add_fetch(&global_gensym_counter, 1, __ATOMIC_SEQ_CST); + return idx; +} +#else +SymTy gensym() { + global_gensym_counter += 1; + SymTy idx = global_gensym_counter; + return idx; +} +#endif + +void free_symtable() { + struct SymTable_elem *elt, *tmp; + HASH_ITER(hh, global_sym_table, elt, tmp) { + HASH_DEL(global_sym_table,elt); + } + free(elt); + free(tmp); +} + +/* + +---------------------------------------- +Garbage collection +---------------------------------------- + + Gibbon has "growing regions" i.e each logical region is backed by a doubly linked-list + of smaller chunks which grows as required. In addition to actual data, each chunk + stores some additional metadata (RegionFooter) to chain the chunks together in a list + and for garbage collection. The footer: + + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + serialized data | rf_reg_metadata_ptr | rf_seq_no | rf_size | rf_next | rf_prev + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + The metadata after the serialized data serves various purposes: + + - rf_reg_metadata_ptr: A pointer to a RegionTy struct that contains various metadata. + Of particular interest to us are the fields: + + = reg_id: A unique identifier for a region. + + = refcount and outset: Whenever an inter-region indirection is created, we record that information + using these two fields. Suppose we have an indirection from region A that points to some chunk + in region B. Then A's outset will store a pointer to that chunk's footer, and B's refcount will + be bumped by 1. Note that all there's only 1 refcount cell, and 1 outset per logical region, + and chunks only store a pointer to them. + + - rf_seq_no: The index of this particular chunk in the list. + + - rf_size: Used during bounds checking to calculate the size of the next region in + the linked list. + + - rf_next / rf_prev: Point to the next and previous chunk respectively. + + +There are two ways in which a region may be freed: + +(1) Whenever it goes out of scope + + The RTS tries to free a region whenever it goes out of scope. But this doesn't always succeed as + regions sometimes contain values that "escape". One reason why this'll happen is if there's an + indirection from A->B, and A lives longer than B. + In such a case, when B goes out of scope it's refcount won't be 0, and the RTS won't free it. + This brings us to (2). + +(2) + + When the RTS successfully frees a region, it decrements the refcounts of all the regions it + points to (via the outset). At the same time, if it encounters a region in the outset whoose + refcount becomes 0 after the decrement, it calls free_region on that. This way we can be sure + that all regions will eventually be garbage collected before the program exits. + + + +Why is it a doubly linked-list? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Due to way that bounds-checking works, the pointers in the outset may actually point to any +arbitrary chunk in the chain. However, we must call free_region on the first one to ensure that +all of them are GC'd. So we need pointers to traverse backward get to the first one. +'trav_to_first_chunk' accomplishes this. + + */ + +#define MAX_OUTSET_LENGTH 10 + +typedef struct RegionTy_struct { + SymTy reg_id; + uint reg_refcount; + CursorTy reg_heap; + uint reg_outset_len; + CursorTy reg_outset[MAX_OUTSET_LENGTH]; +} RegionTy; + +typedef struct RegionFooter_struct { + RegionTy *rf_reg_metadata_ptr; + + IntTy rf_seq_no; + IntTy rf_size; + struct RegionFooter_struct *rf_next; + struct RegionFooter_struct *rf_prev; +} RegionFooter; + +typedef struct ChunkTy_struct { + CursorTy chunk_start; + CursorTy chunk_end; +} ChunkTy; + +static inline void insert_into_outset(CursorTy ptr, RegionTy *reg) { + uint outset_len = reg->reg_outset_len; + // Check for duplicates. + for (uint i = 0; i < outset_len; i++) { + if (ptr == reg->reg_outset[i]) { + return; + } + } + // Otherwise, insert into the outset. + reg->reg_outset[outset_len] = ptr; + reg->reg_outset_len = outset_len + 1; + return; +} + +static inline void remove_from_outset(CursorTy ptr, RegionTy *reg) { + uint outset_len = reg->reg_outset_len; + CursorTy *outset = reg->reg_outset; + int i; + if (outset_len == 0) { + fprintf(stderr, "remove_from_outset: empty outset\n"); + exit(1); + } + // Position of 'ptr' in the outset. + int elt_idx = -1; + for (i = 0; i < outset_len; i++) { + if (ptr == outset[i]) { + elt_idx = i; + } + } + if (elt_idx == -1) { + fprintf(stderr, "remove_from_outset: element not found\n"); + exit(1); + } + // Move all elements ahead of 'elt_idx' back by one position. + for (i = elt_idx; i < outset_len; i++) { + outset[i] = outset[i+1]; + } + return; +} + +RegionTy *alloc_region(IntTy size) { + // Allocate the region metadata. + RegionTy *reg = ALLOC(sizeof(RegionTy)); + if (reg == NULL) { + printf("alloc_region: allocation failed: %ld", sizeof(RegionTy)); + exit(1); + } + + // Allocate the first chunk. + IntTy total_size = size + sizeof(RegionFooter); + CursorTy heap = ALLOC_PACKED_BIG(total_size); + if (heap == NULL) { + printf("alloc_region: malloc failed: %lld", total_size); + exit(1); + } + // Not heap+total_size, since we must keep space for the footer. + CursorTy heap_end = heap + size; + + // Initialize metadata fields. + reg->reg_id = gensym(); + reg->reg_refcount = 1; + reg->reg_heap = heap; + reg->reg_outset_len = 0; + +#ifdef _DEBUG + printf("Allocated a region(%lld): %lld bytes.\n", reg->reg_id, size); +#endif + + // Write the footer. + RegionFooter *footer = (RegionFooter *) heap_end; + footer->rf_reg_metadata_ptr = reg; + footer->rf_seq_no = 1; + footer->rf_size = size; + footer->rf_next = NULL; + footer->rf_prev = NULL; + + return reg; +} + +RegionTy *alloc_counted_region(IntTy size) { + // Bump the count. + bump_global_region_count(); + return alloc_region(size); +} + +ChunkTy alloc_chunk(CursorTy end_old_chunk) { + // Get size from current footer. + RegionFooter *footer = (RegionFooter *) end_old_chunk; + IntTy newsize = footer->rf_size * 2; + // See #110. + if (newsize > global_inf_buf_max_chunk_size) { + newsize = global_inf_buf_max_chunk_size; + } + IntTy total_size = newsize + sizeof(RegionFooter); + + // Allocate. + CursorTy start = ALLOC_PACKED_BIG(total_size); + if (start == NULL) { + printf("alloc_chunk: malloc failed: %lld", total_size); + exit(1); + } + CursorTy end = start + newsize; + + // Link the next chunk's footer. + footer->rf_next = (RegionFooter *) end; + + // Write the footer. + RegionFooter* new_footer = (RegionFooter *) end; + new_footer->rf_reg_metadata_ptr = footer->rf_reg_metadata_ptr; + new_footer->rf_seq_no = footer->rf_seq_no + 1; + new_footer->rf_size = newsize; + new_footer->rf_next = NULL; + new_footer->rf_prev = footer; + +#ifdef _DEBUG + RegionTy *reg = (RegionTy*) new_footer->rf_reg_metadata_ptr; + printf("alloc_chunk: allocated %lld bytes for region %lld.\n", total_size, reg->reg_id); +#endif + + return (ChunkTy) {start , end}; +} + +RegionFooter* trav_to_first_chunk(RegionFooter *footer) { + if (footer->rf_seq_no == 1) { + return footer; + } else if (footer->rf_prev == NULL) { + fprintf(stderr, "No previous chunk found at rf_seq_no: %lld", footer->rf_seq_no); + return NULL; + } else { + trav_to_first_chunk((RegionFooter *) footer->rf_prev); + } + return NULL; +} + +uint get_ref_count(CursorTy end_ptr) { + RegionFooter *footer = (RegionFooter *) end_ptr; + RegionTy *reg = (RegionTy *) footer->rf_reg_metadata_ptr; + return reg->reg_refcount; +} + +// B is the pointer, and A is the pointee (i.e B -> A). +// Bump A's refcount and update B's outset. +static inline void bump_ref_count(CursorTy end_b, CursorTy end_a) { + // Grab footers. + RegionFooter *footer_a = (RegionFooter *) end_a; + RegionFooter *footer_b = (RegionFooter *) end_b; + + // Grab metadata. + RegionTy *reg_a = (RegionTy *) footer_a->rf_reg_metadata_ptr; + RegionTy *reg_b = (RegionTy *) footer_b->rf_reg_metadata_ptr; + + // Bump A's refcount. + uint current_refcount, new_refcount; + current_refcount = reg_a->reg_refcount; + new_refcount = current_refcount + 1; + reg_a->reg_refcount = new_refcount; + +#ifdef _DEBUG + printf("bump_ref_count: %lld -> %lld\n", reg_b->reg_id, reg_a->reg_id); + printf("bump_ref_count: old-refcount=%d, old-outset-len=%d:\n", current_refcount, reg_b->reg_outset_len); + assert(current_refcount == reg_b->reg_outset_len+1); +#endif + + // Add A to B's outset. + insert_into_outset(end_a, reg_b); + +#ifdef _DEBUG + // printf("bump_ref_count: Added %p to %lld's outset, %p.\n", end_a, reg_b->reg_id, reg_b); + printf("bump_ref_count: new-refcount=%d, new-outset-len=%d\n", new_refcount, reg_b->reg_outset_len); + assert(new_refcount == reg_b->reg_outset_len+1); +#endif + + return; +} + +void free_region(CursorTy end_reg) { + // Grab footer and the metadata. + RegionFooter *footer = (RegionFooter *) end_reg; + RegionTy *reg = (RegionTy *) footer->rf_reg_metadata_ptr; + + // + RegionFooter *first_chunk_footer, *next_chunk_footer; + CursorTy first_chunk, next_chunk; + + // Decrement current reference count. + uint current_refcount, new_refcount; + current_refcount = reg->reg_refcount; + new_refcount = 0; + if (current_refcount != 0) { + new_refcount = current_refcount - 1; + reg->reg_refcount = new_refcount; + } + +#ifdef _DEBUG + printf("free_region(%lld): refcounts (1): old-refcount=%d, new-refcount=%d:\n", reg->reg_id, current_refcount, new_refcount); +#endif + + + // Free this region recount is 0. + if (new_refcount == 0) { + +#ifdef _DEBUG + printf("free_region(%lld): outset length: %d\n", reg->reg_id, reg->reg_outset_len); +#endif + + // Decrement refcounts, free regions with refcount==0 and also free + // elements of the outset. + if (reg->reg_outset_len != 0) { + uint outset_len = reg->reg_outset_len; + CursorTy *outset = reg->reg_outset; + RegionFooter *elt_footer; + RegionTy *elt_reg; + uint elt_current_refcount, elt_new_refcount; + CursorTy to_be_removed[MAX_OUTSET_LENGTH]; + uint to_be_removed_idx = 0; + for (int i = 0; i < outset_len; i++) { + elt_footer = (RegionFooter *) outset[i]; + elt_reg = (RegionTy *) elt_footer->rf_reg_metadata_ptr; +#ifdef _DEBUG + elt_current_refcount = elt_reg->reg_refcount; +#endif + elt_new_refcount = elt_current_refcount - 1; + elt_reg->reg_refcount = elt_new_refcount; +#ifdef _DEBUG + printf("free_region(%lld): old-refcount=%d, new-refcount=%d:\n", + elt_reg->reg_id, elt_current_refcount, elt_reg->reg_refcount); +#endif + if (elt_new_refcount == 0) { + // See [Why is it a doubly linked-list?] above + first_chunk_footer = trav_to_first_chunk(elt_footer); + if (first_chunk_footer != NULL) { + free_region((CursorTy) first_chunk_footer); + } + } + to_be_removed[to_be_removed_idx] = outset[i]; + to_be_removed_idx++; + } + // Remove elements from the outset. + for (uint i = 0; i < to_be_removed_idx; i++) { + remove_from_outset(to_be_removed[i], reg); + } + } + + +#ifdef _DEBUG + // Bookkeeping + IntTy num_freed_chunks = 0, total_bytesize = 0; +#endif + + // Free the chunks in this region. + first_chunk = end_reg - footer->rf_size; + first_chunk_footer = footer; + next_chunk = (char*) footer->rf_next; + +#ifdef _DEBUG + printf("free_region(%lld)\n", reg->reg_id); +#endif + +#ifdef _DEBUG + num_freed_chunks++; + total_bytesize = total_bytesize + first_chunk_footer->rf_size; +#endif + free(first_chunk); + + while (next_chunk != NULL) { + next_chunk_footer = (RegionFooter *) next_chunk; + #ifdef _DEBUG + num_freed_chunks++; + total_bytesize = total_bytesize + next_chunk_footer->rf_size; + #endif + free(next_chunk - next_chunk_footer->rf_size); + next_chunk = (char*) next_chunk_footer->rf_next; + } + +#ifdef _DEBUG + printf("free_region(%lld): Freed %lld bytes across %lld chunks.\n", + reg->reg_id, total_bytesize, num_freed_chunks); +#endif + + // Free the metadata. + free(reg); + + } else { +#ifdef _DEBUG + printf("free_region(%lld): non-zero refcount: %d.\n", + reg->reg_id, reg->reg_refcount); +#endif + } +} + +// Assume that all nodes with size information have tags >= 150. +BoolTy is_big(IntTy i, CursorTy cur) { + TagTyPacked tag = *(TagTyPacked *) cur; + if (tag >= 150) { + cur += 1; + IntTy size = *(IntTy *) cur; + if (size >= i) { + return true; + } else { + return false; + } + } + return false; +} + +// ------------------------------------- +// Vectors +// ------------------------------------- + +typedef struct VectorTy_struct { + // Bounds on the vector. + IntTy vec_lower, vec_upper; + + // Size of each element. + IntTy vec_elt_size; + + // Actual elements of the vector. + void* vec_data; +} VectorTy; + +VectorTy* vector_alloc(IntTy num, IntTy elt_size) { + VectorTy *vec = ALLOC(sizeof(VectorTy)); + if (vec == NULL) { + printf("alloc_vector: malloc failed: %ld", sizeof(VectorTy)); + exit(1); + } + void* data = ALLOC(num * elt_size); + if (data == NULL) { + printf("alloc_vector: malloc failed: %ld", sizeof(num * elt_size)); + exit(1); + } + vec->vec_lower = 0; + vec->vec_upper = num; + vec->vec_elt_size = elt_size; + vec->vec_data = data; + return vec; +} + +IntTy vector_length(VectorTy *vec) { + return (vec->vec_upper - vec->vec_lower); +} + +BoolTy vector_is_empty(VectorTy *vec) { + return (vector_length(vec) == 0); +} + +VectorTy* vector_slice(IntTy i, IntTy n, VectorTy *vec) { + IntTy lower = vec->vec_lower + i; + IntTy upper = vec->vec_lower + i + n; + if ((lower > vec->vec_upper)) { + printf("vector_slice: lower out of bounds, %lld > %lld", lower, vec->vec_upper); + exit(1); + } + if ((upper > vec->vec_upper)) { + printf("vector_slice: upper out of bounds: %lld > %lld", upper, vec->vec_upper); + exit(1); + } + VectorTy *vec2 = ALLOC(sizeof(VectorTy)); + if (vec == NULL) { + printf("vector_slice: malloc failed: %ld", sizeof(VectorTy)); + exit(1); + } + vec2->vec_lower = lower; + vec2->vec_upper = upper; + vec2->vec_elt_size = vec->vec_elt_size; + vec2->vec_data = vec->vec_data; + return vec2; +} + +// The callers must cast the return value. +static inline void* vector_nth(VectorTy *vec, IntTy i) { + // if (i < vec->lower || i > vec->upper) { + // printf("vector_nth index out of bounds: %lld (%lld,%lld) \n", i, vec->vec_lower, vec->vec_upper); + // exit(1); + // } + return (vec->vec_data + (vec->vec_elt_size * (vec->vec_lower + i))); +} + +static inline VectorTy* vector_inplace_update(VectorTy *vec, IntTy i, void* elt) { + void* dst = vector_nth(vec, i); + memcpy(dst, elt, vec->vec_elt_size); + return vec; +} + +static inline VectorTy* vector_copy(VectorTy *vec) { + IntTy len = vector_length(vec); + void *start = vector_nth(vec, 0); + VectorTy *vec2 = vector_alloc(len, vec->vec_elt_size); + memcpy(vec2->vec_data, start, len * vec->vec_elt_size); + return vec2; +} + +static inline VectorTy* vector_inplace_sort(VectorTy *vec, int (*compar)(const void *, const void*)) { + void *start = vector_nth(vec, 0); + qsort(start, vector_length(vec), vec->vec_elt_size, compar); + return vec; +} + +static inline VectorTy* vector_sort(VectorTy *vec, int (*compar)(const void *, const void*)) { + VectorTy *vec2 = vector_copy(vec); + vector_inplace_sort(vec2, compar); + return vec2; +} + +static inline VectorTy* vector_concat(VectorTy *vec) { + // Length of the input vector. + IntTy len = vector_length(vec); + // Length of the concatenated vector. + IntTy result_len = 0; + // Size of each element in the concatenated vector. + IntTy result_elt_size = 0; + VectorTy **elt_ref, *elt; + for (IntTy i = 0; i < len; i++) { + elt_ref = vector_nth(vec, i); + elt = *elt_ref; + result_elt_size = elt->vec_elt_size; + result_len += vector_length(elt); + } + + // Concatenated vector. + VectorTy *result = vector_alloc(result_len, result_elt_size); + IntTy elt_len; + // A counter that tracks the index of elements in 'result'. + IntTy k = 0; + for (IntTy i = 0; i < len; i++) { + elt_ref = vector_nth(vec, i); + elt = *elt_ref; + elt_len = vector_length(elt); + + for (IntTy j = 0; j < elt_len; j++) { + void* k_elt = vector_nth(elt, j); + vector_inplace_update(result, k, k_elt); + k++; + } + } + + return result; +} + +static inline void vector_free(VectorTy *vec) { + free(vec->vec_data); + free(vec); + return; +} + +static inline VectorTy* vector_merge(VectorTy *vec1, VectorTy *vec2) { + if (vec1->vec_upper != vec2->vec_lower) { + printf("vector_merge: non-contiguous slices, (%lld,%lld), (%lld,%lld).", + vec1->vec_lower, vec1->vec_upper, vec2->vec_lower, vec2->vec_upper); + exit(1); + } + VectorTy *merged = ALLOC(sizeof(VectorTy)); + if (merged == NULL) { + printf("vector_merge: malloc failed: %ld", sizeof(VectorTy)); + exit(1); + } + merged->vec_lower = vec1->vec_lower; + merged->vec_upper = vec2->vec_upper; + merged->vec_elt_size = vec1->vec_elt_size; + merged->vec_data = vec1->vec_data; + return merged; +} + +void print_timing_array(VectorTy *times) { + printf("TIMES: ["); + double *d; + IntTy n = vector_length(times); + for(int i = 0; i < n; i++) { + d = vector_nth(times, i); + if (i == (n-1)) { + printf("%f",*d); + } + else { + printf("%f, ",*d); + } + } + printf("]\n"); +} + +double sum_timing_array(VectorTy *times) { + double *d; + double acc = 0; + for(int i = 0; i < vector_length(times); i++) { + d = vector_nth(times, i); + acc += *d; + } + return acc; +} + +// ------------------------------------- +// Linked lists +// ------------------------------------- + +typedef struct ListTy_struct { + IntTy ll_data_size; + void* ll_data; + struct ListTy_struct* ll_next; +} ListTy; + +static inline ListTy* list_alloc(IntTy data_size) { + // ListTy *ls = ALLOC(sizeof(ListTy)); + ListTy *ls = BUMPALLOC(sizeof(ListTy)); + ls->ll_data_size = data_size; + ls->ll_data = NULL; + ls->ll_next = NULL; + return ls; +} + +static inline BoolTy list_is_empty(ListTy *ls) { + return ls->ll_next == NULL; +} + +static inline ListTy* list_cons(void* elt, ListTy *ls) { + // void* data = ALLOC(ls->data_size); + void* data = BUMPALLOC(ls->ll_data_size); + if (data == NULL) { + printf("list_cons: malloc failed: %lld", ls->ll_data_size); + exit(1); + } + memcpy(data, elt, ls->ll_data_size); + // ListTy *res = ALLOC(sizeof(ListTy)); + ListTy *res = BUMPALLOC(sizeof(ListTy)); + res->ll_data_size = ls->ll_data_size; + res->ll_data = data; + res->ll_next = (ListTy*) ls; + return res; +} + +static inline void* list_head(ListTy *ls) { + return ls->ll_data; +} + +static inline ListTy* list_tail(ListTy *ls) { + return ls->ll_next; +} + +static inline void list_free(ListTy *ls) { + free(ls->ll_data); + free(ls); + return; +} + +static inline ListTy* list_copy(ListTy *ls) { + ListTy *ls2 = list_alloc(ls->ll_data_size); + if (ls->ll_data != NULL) { + void* data = BUMPALLOC(ls->ll_data_size); + memcpy(data, ls->ll_data, ls->ll_data_size); + ls2->ll_data = data; + } + ls2->ll_next = ls->ll_next; + return ls2; +} + +// ------------------------------------- +// Ppm Images +// ------------------------------------- + +typedef struct __Pixel_struct { + IntTy field0; + IntTy field1; + IntTy field2; +} __Pixel; + +void writePpm(char* filename, IntTy width, IntTy height, VectorTy *pixels); +void writePpm_loop(FILE *fp, IntTy idx, IntTy end, VectorTy *pixels); + +// Example: writePpm("gibbon_rgb_1000.ppm", 1000, 1000, pixels); +void writePpm(char* filename, IntTy width, IntTy height, VectorTy *pixels) +{ + FILE *fp; + fp = fopen(filename, "w+"); + fprintf(fp, "P3\n"); + fprintf(fp, "%lld %lld\n255\n", width, height); + IntTy len = vector_length(pixels); + writePpm_loop(fp, 0, len, pixels); + fclose(fp); + return; +} + +void writePpm_loop(FILE *fp, IntTy idx, IntTy end, VectorTy *pixels) +{ + BoolTy fltIf_5768_6575 = idx == end; + + if (fltIf_5768_6575) { + return; + } else { + __Pixel *tmp_112; + tmp_112 = (__Pixel *) vector_nth(pixels, idx); + __Pixel tup = *tmp_112; + IntTy x = tup.field0; + IntTy y = tup.field1; + IntTy z = tup.field2; + // write to file. + fprintf(fp, "%lld %lld %lld\n", x, y, z); + writePpm_loop(fp, (idx+1), end, pixels); + } +} + +/* -------------------------------------------------------------------------------- */ + +int main(int argc, char** argv) +{ + // parameters to parse: + // + // num iterations: How many times to repeat a benchmark. + // tree size: An integer passes to `build_tree()`. + + struct rlimit lim; + int code; + if ( (code = getrlimit(RLIMIT_STACK, &lim)) ) { + fprintf(stderr, " [gibbon rts] failed to getrlimit, code %d\n", code); + exit(1); + } + + // lim.rlim_cur = 1024LU * 1024LU * 1024LU; // 1GB stack. + lim.rlim_cur = 512LU * 1024LU * 1024LU; // 500MB stack. + // lim.rlim_max = lim.rlim_cur; // Normal users may only be able to decrease this. + + // WARNING: Haven't yet figured out why this doesn't work on MacOS... +#ifndef __APPLE__ + code = setrlimit(RLIMIT_STACK, &lim); + while (code) { + fprintf(stderr, " [gibbon rts] Failed to set stack size to %llu, code %d\n", (unsigned long long)lim.rlim_cur, code); + lim.rlim_cur /= 2; + // lim.rlim_max /= 2; + if(lim.rlim_cur < 100 * 1024) { + fprintf(stderr, " [gibbon rts] Failed setrlimit stack size to something reasonable; giving up.\n"); + break; // abort(); + } + int code = setrlimit(RLIMIT_STACK, &lim); + } +#endif + + int got_numargs = 0; // How many numeric arguments have we got. + + int i; + for (i = 1; i < argc; ++i) + { + if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) { + show_usage(argv); + exit(0); + } + else if (strcmp(argv[i], "--biginf-buffer-size") == 0 && i < argc - 1) + { + global_init_biginf_buf_size = atoll(argv[i + 1]); + i++; + } + else if (strcmp(argv[i], "--inf-buffer-size") == 0 && i < argc - 1) + { + global_init_inf_buf_size = atoll(argv[i + 1]); + i++; + } + else if ((strcmp(argv[i], "--bench-input") == 0)) { + if (i+1 >= argc) { + fprintf(stderr, "Not enough arguments after --bench-input, expected .\n"); + show_usage(argv); + exit(1); + } + global_benchfile_param = argv[i+1]; + i++; + } + else if ((strcmp(argv[i], "--array-input") == 0)) { + if (i+1 >= argc) { + fprintf(stderr, "Not enough arguments after --array-input, expected .\n"); + show_usage(argv); + exit(1); + } + global_arrayfile_param = argv[i+1]; + i++; + } + else if (strcmp(argv[i], "--array-input-length") == 0 && i < argc - 1) { + global_arrayfile_length_param = atoll(argv[i+1]); + i++; + } + else if (strcmp(argv[i], "--bench-prog") == 0 && i < argc - 1) { + int len = strlen(argv[i+1]); + global_bench_prog_param = (char*) malloc((len+1)*sizeof(char)); + strncpy(global_bench_prog_param,argv[i+1],len); + i++; + } + // If present, we expect the two arguments to be + else if (got_numargs >= 2) { + fprintf(stderr, "Extra arguments left over: "); + for(; i < argc; i++) fprintf(stderr, "%s ", argv[i]); + show_usage(argv); + exit(1); + } else { + if (got_numargs == 0) { + global_size_param = atoll(argv[i]); + got_numargs ++; + } else { + global_iters_param = atoll(argv[i]); + } + } + } + + // Initialize global_bench_prog_param to an empty string in case + // the runtime argument --bench-prog isn't passed. + if (global_bench_prog_param == NULL) { + global_bench_prog_param = (char*) malloc(1*sizeof(char)); + *global_bench_prog_param = '\n'; + } + + __main_expr(); + + return 0; +} + +// ----------------------------------------------------------------------------- +// Program starts here +// ----------------------------------------------------------------------------- + +typedef struct Prod_struct { } Prod; +typedef struct Int64Prod_struct { + IntTy field0; + } Int64Prod; +typedef struct Int64Int64Int64CursorCursorProd_struct { + IntTy field0; + IntTy field1; + IntTy field2; + CursorTy field3; + CursorTy field4; + } Int64Int64Int64CursorCursorProd; +typedef struct Int64Int64CursorCursorProd_struct { + IntTy field0; + IntTy field1; + CursorTy field2; + CursorTy field3; + } Int64Int64CursorCursorProd; +typedef struct BoolProd_struct { + BoolTy field0; + } BoolProd; +typedef struct TagCursorProd_struct { + TagTyPacked field0; + CursorTy field1; + } TagCursorProd; +typedef struct CursorProd_struct { + CursorTy field0; + } CursorProd; +CursorTy build(IntTy x_23_469_822, IntTy sz_24_470_823); +IntTy eval(IntTy x_25_471_829, CursorTy m_26_472_830); +CursorTy singleton(IntTy x_35_481_841); +CursorTy insert(IntTy x_36_482_844, CursorTy s_37_483_845); +IntTy depth(IntTy x_44_490_854, IntTy c_45_491_855, CursorTy s_46_492_856); +CursorTy right(CursorTy x_58_504_865); +CursorTy left(CursorTy x_63_509_870); +IntTy val(CursorTy x_68_514_875); +IntTy size(CursorTy s_73_519_880); +CursorTy balanceR(IntTy x_89_535_885, CursorTy l_90_536_886, + CursorTy r_91_537_887); +CursorTy balanceL(IntTy x_116_542_892, CursorTy l_117_543_893, + CursorTy r_118_544_894); +CursorTy _copy_without_ptrs_IntSet(CursorTy arg_380_549_899); +CursorTy _copy_IntSet(CursorTy arg_371_558_908); +unsigned char _traverse_IntSet(CursorTy arg_389_567_917); +unsigned char _print_IntSet(CursorTy arg_398_574_924); +CursorTy caseFn_415(IntTy x_89_416_591_941, CursorTy rr_95_417_592_942, + IntTy rx_93_418_593_943, IntTy rs_92_419_594_944, + CursorTy rl_94_420_595_945); +CursorTy caseFn_421(IntTy x_89_422_600_977, CursorTy r_91_423_601_978, + IntTy rx_93_424_602_979, CursorTy rl_94_425_603_980); +CursorTy caseFn_426(IntTy x_89_427_608_993, CursorTy r_91_428_609_994, + CursorTy rr_95_429_610_995, IntTy rx_93_430_611_996, + IntTy rs_92_431_612_997, CursorTy rl_94_432_613_998); +CursorTy caseFn_433(IntTy x_89_434_618_1003, CursorTy r_91_435_619_1004); +CursorTy caseFn_436(CursorTy l_90_437_624_1011, IntTy x_89_438_625_1012, + CursorTy r_91_439_626_1013, IntTy ls_108_440_627_1014); +CursorTy caseFn_441(IntTy x_116_442_632_1051, CursorTy ll_121_443_633_1052, + IntTy lx_120_444_634_1053, IntTy ls_119_445_635_1054, + CursorTy lr_122_446_636_1055, IntTy lls_123_447_637_1056); +CursorTy caseFn_448(CursorTy l_117_449_642_1079, IntTy x_116_450_643_1080, + IntTy lx_120_451_644_1081, CursorTy lr_122_452_645_1082); +CursorTy caseFn_453(CursorTy l_117_454_650_1094, IntTy x_116_455_651_1095, + CursorTy ll_121_456_652_1096, IntTy lx_120_457_653_1097, + IntTy ls_119_458_654_1098, CursorTy lr_122_459_655_1099); +CursorTy caseFn_460(CursorTy l_117_461_660_1104, IntTy x_116_462_661_1105); +CursorTy caseFn_463(CursorTy r_118_464_666_1112, CursorTy l_117_465_667_1113, + IntTy x_116_466_668_1114, IntTy rs_135_467_669_1115); +CursorTy build(IntTy x_23_469_822, IntTy sz_24_470_823) +{ + BoolTy fltIf_676_824 = x_23_469_822 == 0; + + if (fltIf_676_824) { + return singleton(0); + } else { + IntTy fltPrm_678_825 = sz_24_470_823 / 2; + IntTy fltAppE_677_826 = x_23_469_822 - fltPrm_678_825; + IntTy fltAppE_680_827 = x_23_469_822 - 1; + CursorTy fltAppE_679_828 = build(fltAppE_680_827, sz_24_470_823); + + return insert(fltAppE_677_826, fltAppE_679_828); + } +} +IntTy eval(IntTy x_25_471_829, CursorTy m_26_472_830) +{ + unsigned char wildcard__18_27_473_831 = print_symbol(1157); + unsigned char wildcard__16_28_474_832 = print_symbol(1155); + unsigned char wildcard__14_29_475_833 = printf("%lld", x_25_471_829); + unsigned char wildcard__12_30_476_834 = print_symbol(1154); + IntTy timed_1153; + VectorTy *times_3 = vector_alloc(global_iters_param, sizeof(double)); + struct timespec begin_timed_1153; + struct timespec end_timed_1153; + + for (long long iters_timed_1153 = 0; iters_timed_1153 < global_iters_param; + iters_timed_1153++) { + if (iters_timed_1153 != global_iters_param - 1) + save_alloc_state(); + clock_gettime(CLOCK_MONOTONIC_RAW, &begin_timed_1153); + + IntTy timed_1153hack = depth(x_25_471_829, 0, m_26_472_830); + + timed_1153 = timed_1153hack; + clock_gettime(CLOCK_MONOTONIC_RAW, &end_timed_1153); + if (iters_timed_1153 != global_iters_param - 1) + restore_alloc_state(); + + double itertime_0 = difftimespecs(&begin_timed_1153, &end_timed_1153); + + vector_inplace_update(times_3, iters_timed_1153, &itertime_0); + } + vector_inplace_sort(times_3, compare_doubles); + + double *tmp_4 = (double *) vector_nth(times_3, global_iters_param / 2); + double selftimed_2 = *tmp_4; + double batchtime_1 = sum_timing_array(times_3); + + print_timing_array(times_3); + printf("ITERS: %lld\n", global_iters_param); + printf("SIZE: %lld\n", global_size_param); + printf("BATCHTIME: %e\n", batchtime_1); + printf("SELFTIMED: %e\n", selftimed_2); + + unsigned char wildcard__8_32_478_836 = print_symbol(1156); + unsigned char wildcard__6_33_479_837 = printf("%lld", timed_1153); + unsigned char wildcard__4_34_480_838 = print_symbol(1154); + BoolTy fltIf_681_839 = timed_1153 < 0; + + if (fltIf_681_839) { + return 0; + } else { + IntTy fltAppE_682_840 = x_25_471_829 - 1; + + return eval(fltAppE_682_840, m_26_472_830); + } +} +CursorTy singleton(IntTy x_35_481_841) +{ + PtrTy fltPkd_683_842 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_683_842)->field0 = 1; + + PtrTy fltPkd_684_843 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_684_843)->field0 = 1; + + PtrTy tailift_1162 = ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1162)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1162)->field1 = 1; + ((Int64Int64Int64CursorCursorProd *) tailift_1162)->field2 = x_35_481_841; + ((Int64Int64Int64CursorCursorProd *) tailift_1162)->field3 = fltPkd_683_842; + ((Int64Int64Int64CursorCursorProd *) tailift_1162)->field4 = fltPkd_684_843; + return tailift_1162; +} +CursorTy insert(IntTy x_36_482_844, CursorTy s_37_483_845) +{ + TagTyPacked tag_1163 = *(TagTyPacked *) s_37_483_845; + CursorTy tail_1164 = s_37_483_845 + sizeof(IntTy); + + + switch_1165: + ; + switch (tag_1163) { + + case 1: + { + return singleton(x_36_482_844); + break; + } + + case 0: + { + IntTy sz_38_484_846 = + ((Int64Int64CursorCursorProd *) tail_1164)->field0; + IntTy v_39_485_847 = + ((Int64Int64CursorCursorProd *) tail_1164)->field1; + CursorTy l_40_486_848 = + ((Int64Int64CursorCursorProd *) tail_1164)->field2; + CursorTy r_41_487_849 = + ((Int64Int64CursorCursorProd *) tail_1164)->field3; + BoolTy fltIf_685_850 = x_36_482_844 == v_39_485_847; + + if (fltIf_685_850) { + return s_37_483_845; + } else { + BoolTy fltIf_686_851 = x_36_482_844 <= v_39_485_847; + + if (fltIf_686_851) { + CursorTy nl_42_488_852 = + insert(x_36_482_844, l_40_486_848); + + return balanceL(v_39_485_847, nl_42_488_852, r_41_487_849); + } else { + CursorTy nr_43_489_853 = + insert(x_36_482_844, r_41_487_849); + + return balanceR(v_39_485_847, l_40_486_848, nr_43_489_853); + } + } + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1163"); + exit(1); + } + } +} +IntTy depth(IntTy x_44_490_854, IntTy c_45_491_855, CursorTy s_46_492_856) +{ + TagTyPacked tag_1166 = *(TagTyPacked *) s_46_492_856; + CursorTy tail_1167 = s_46_492_856 + sizeof(IntTy); + + + switch_1170: + ; + switch (tag_1166) { + + case 1: + { + IntTy flt_1168 = 0 - 1; + + return flt_1168; + break; + } + + case 0: + { + IntTy wildcard__154_47_493_857 = + ((Int64Int64CursorCursorProd *) tail_1167)->field0; + IntTy v_48_494_858 = + ((Int64Int64CursorCursorProd *) tail_1167)->field1; + CursorTy l_49_495_859 = + ((Int64Int64CursorCursorProd *) tail_1167)->field2; + CursorTy r_50_496_860 = + ((Int64Int64CursorCursorProd *) tail_1167)->field3; + BoolTy fltIf_687_861 = x_44_490_854 == v_48_494_858; + + if (fltIf_687_861) { + IntTy flt_1169 = c_45_491_855 + 1; + + return flt_1169; + } else { + BoolTy fltIf_688_862 = x_44_490_854 <= v_48_494_858; + + if (fltIf_688_862) { + IntTy fltAppE_689_863 = c_45_491_855 + 1; + + return depth(x_44_490_854, fltAppE_689_863, l_49_495_859); + } else { + IntTy fltAppE_690_864 = c_45_491_855 + 1; + + return depth(x_44_490_854, fltAppE_690_864, r_50_496_860); + } + } + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1166"); + exit(1); + } + } +} +CursorTy right(CursorTy x_58_504_865) +{ + TagTyPacked tag_1171 = *(TagTyPacked *) x_58_504_865; + CursorTy tail_1172 = x_58_504_865 + sizeof(IntTy); + + + switch_1174: + ; + switch (tag_1171) { + + case 1: + { + PtrTy tailift_1173 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) tailift_1173)->field0 = 1; + return tailift_1173; + break; + } + + case 0: + { + IntTy wildcard__186_59_505_866 = + ((Int64Int64CursorCursorProd *) tail_1172)->field0; + IntTy wildcard__187_60_506_867 = + ((Int64Int64CursorCursorProd *) tail_1172)->field1; + CursorTy wildcard__188_61_507_868 = + ((Int64Int64CursorCursorProd *) tail_1172)->field2; + CursorTy r_62_508_869 = + ((Int64Int64CursorCursorProd *) tail_1172)->field3; + + return r_62_508_869; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1171"); + exit(1); + } + } +} +CursorTy left(CursorTy x_63_509_870) +{ + TagTyPacked tag_1175 = *(TagTyPacked *) x_63_509_870; + CursorTy tail_1176 = x_63_509_870 + sizeof(IntTy); + + + switch_1178: + ; + switch (tag_1175) { + + case 1: + { + PtrTy tailift_1177 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) tailift_1177)->field0 = 1; + return tailift_1177; + break; + } + + case 0: + { + IntTy wildcard__177_64_510_871 = + ((Int64Int64CursorCursorProd *) tail_1176)->field0; + IntTy wildcard__178_65_511_872 = + ((Int64Int64CursorCursorProd *) tail_1176)->field1; + CursorTy l_66_512_873 = + ((Int64Int64CursorCursorProd *) tail_1176)->field2; + CursorTy wildcard__179_67_513_874 = + ((Int64Int64CursorCursorProd *) tail_1176)->field3; + + return l_66_512_873; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1175"); + exit(1); + } + } +} +IntTy val(CursorTy x_68_514_875) +{ + TagTyPacked tag_1179 = *(TagTyPacked *) x_68_514_875; + CursorTy tail_1180 = x_68_514_875 + sizeof(IntTy); + + + switch_1181: + ; + switch (tag_1179) { + + case 1: + { + return 0; + break; + } + + case 0: + { + IntTy wildcard__168_69_515_876 = + ((Int64Int64CursorCursorProd *) tail_1180)->field0; + IntTy v_70_516_877 = + ((Int64Int64CursorCursorProd *) tail_1180)->field1; + CursorTy wildcard__169_71_517_878 = + ((Int64Int64CursorCursorProd *) tail_1180)->field2; + CursorTy wildcard__170_72_518_879 = + ((Int64Int64CursorCursorProd *) tail_1180)->field3; + + return v_70_516_877; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1179"); + exit(1); + } + } +} +IntTy size(CursorTy s_73_519_880) +{ + TagTyPacked tag_1182 = *(TagTyPacked *) s_73_519_880; + CursorTy tail_1183 = s_73_519_880 + sizeof(IntTy); + + + switch_1184: + ; + switch (tag_1182) { + + case 1: + { + return 0; + break; + } + + case 0: + { + IntTy sz_74_520_881 = + ((Int64Int64CursorCursorProd *) tail_1183)->field0; + IntTy wildcard__160_75_521_882 = + ((Int64Int64CursorCursorProd *) tail_1183)->field1; + CursorTy wildcard__161_76_522_883 = + ((Int64Int64CursorCursorProd *) tail_1183)->field2; + CursorTy wildcard__162_77_523_884 = + ((Int64Int64CursorCursorProd *) tail_1183)->field3; + + return sz_74_520_881; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1182"); + exit(1); + } + } +} +CursorTy balanceR(IntTy x_89_535_885, CursorTy l_90_536_886, + CursorTy r_91_537_887) +{ + TagTyPacked tag_1185 = *(TagTyPacked *) l_90_536_886; + CursorTy tail_1186 = l_90_536_886 + sizeof(IntTy); + + + switch_1187: + ; + switch (tag_1185) { + + case 1: + { + return caseFn_433(x_89_535_885, r_91_537_887); + break; + } + + case 0: + { + IntTy ls_108_538_888 = + ((Int64Int64CursorCursorProd *) tail_1186)->field0; + IntTy wildcard__116_109_539_889 = + ((Int64Int64CursorCursorProd *) tail_1186)->field1; + CursorTy wildcard__117_110_540_890 = + ((Int64Int64CursorCursorProd *) tail_1186)->field2; + CursorTy wildcard__118_111_541_891 = + ((Int64Int64CursorCursorProd *) tail_1186)->field3; + + return caseFn_436(l_90_536_886, x_89_535_885, r_91_537_887, + ls_108_538_888); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1185"); + exit(1); + } + } +} +CursorTy balanceL(IntTy x_116_542_892, CursorTy l_117_543_893, + CursorTy r_118_544_894) +{ + TagTyPacked tag_1188 = *(TagTyPacked *) r_118_544_894; + CursorTy tail_1189 = r_118_544_894 + sizeof(IntTy); + + + switch_1190: + ; + switch (tag_1188) { + + case 1: + { + return caseFn_460(l_117_543_893, x_116_542_892); + break; + } + + case 0: + { + IntTy rs_135_545_895 = + ((Int64Int64CursorCursorProd *) tail_1189)->field0; + IntTy wildcard__55_136_546_896 = + ((Int64Int64CursorCursorProd *) tail_1189)->field1; + CursorTy wildcard__56_137_547_897 = + ((Int64Int64CursorCursorProd *) tail_1189)->field2; + CursorTy wildcard__57_138_548_898 = + ((Int64Int64CursorCursorProd *) tail_1189)->field3; + + return caseFn_463(r_118_544_894, l_117_543_893, x_116_542_892, + rs_135_545_895); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1188"); + exit(1); + } + } +} +CursorTy _copy_without_ptrs_IntSet(CursorTy arg_380_549_899) +{ + TagTyPacked tag_1191 = *(TagTyPacked *) arg_380_549_899; + CursorTy tail_1192 = arg_380_549_899 + sizeof(IntTy); + + + switch_1195: + ; + switch (tag_1191) { + + case 0: + { + IntTy x_381_550_900 = + ((Int64Int64CursorCursorProd *) tail_1192)->field0; + IntTy x_382_551_901 = + ((Int64Int64CursorCursorProd *) tail_1192)->field1; + CursorTy x_383_552_902 = + ((Int64Int64CursorCursorProd *) tail_1192)->field2; + CursorTy x_384_553_903 = + ((Int64Int64CursorCursorProd *) tail_1192)->field3; + CursorTy y_387_556_906 = _copy_without_ptrs_IntSet(x_383_552_902); + CursorTy y_388_557_907 = _copy_without_ptrs_IntSet(x_384_553_903); + PtrTy tailift_1193 = ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1193)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1193)->field1 = + x_381_550_900; + ((Int64Int64Int64CursorCursorProd *) tailift_1193)->field2 = + x_382_551_901; + ((Int64Int64Int64CursorCursorProd *) tailift_1193)->field3 = + y_387_556_906; + ((Int64Int64Int64CursorCursorProd *) tailift_1193)->field4 = + y_388_557_907; + return tailift_1193; + break; + } + + case 1: + { + PtrTy tailift_1194 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) tailift_1194)->field0 = 1; + return tailift_1194; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1191"); + exit(1); + } + } +} +CursorTy _copy_IntSet(CursorTy arg_371_558_908) +{ + TagTyPacked tag_1196 = *(TagTyPacked *) arg_371_558_908; + CursorTy tail_1197 = arg_371_558_908 + sizeof(IntTy); + + + switch_1200: + ; + switch (tag_1196) { + + case 0: + { + IntTy x_372_559_909 = + ((Int64Int64CursorCursorProd *) tail_1197)->field0; + IntTy x_373_560_910 = + ((Int64Int64CursorCursorProd *) tail_1197)->field1; + CursorTy x_374_561_911 = + ((Int64Int64CursorCursorProd *) tail_1197)->field2; + CursorTy x_375_562_912 = + ((Int64Int64CursorCursorProd *) tail_1197)->field3; + CursorTy y_378_565_915 = _copy_IntSet(x_374_561_911); + CursorTy y_379_566_916 = _copy_IntSet(x_375_562_912); + PtrTy tailift_1198 = ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1198)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1198)->field1 = + x_372_559_909; + ((Int64Int64Int64CursorCursorProd *) tailift_1198)->field2 = + x_373_560_910; + ((Int64Int64Int64CursorCursorProd *) tailift_1198)->field3 = + y_378_565_915; + ((Int64Int64Int64CursorCursorProd *) tailift_1198)->field4 = + y_379_566_916; + return tailift_1198; + break; + } + + case 1: + { + PtrTy tailift_1199 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) tailift_1199)->field0 = 1; + return tailift_1199; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1196"); + exit(1); + } + } +} +unsigned char _traverse_IntSet(CursorTy arg_389_567_917) +{ + TagTyPacked tag_1201 = *(TagTyPacked *) arg_389_567_917; + CursorTy tail_1202 = arg_389_567_917 + sizeof(IntTy); + + + switch_1203: + ; + switch (tag_1201) { + + case 0: + { + IntTy x_390_568_918 = + ((Int64Int64CursorCursorProd *) tail_1202)->field0; + IntTy x_391_569_919 = + ((Int64Int64CursorCursorProd *) tail_1202)->field1; + CursorTy x_392_570_920 = + ((Int64Int64CursorCursorProd *) tail_1202)->field2; + CursorTy x_393_571_921 = + ((Int64Int64CursorCursorProd *) tail_1202)->field3; + unsigned char y_396_572_922 = _traverse_IntSet(x_392_570_920); + unsigned char y_397_573_923 = _traverse_IntSet(x_393_571_921); + + return 0; + break; + } + + case 1: + { + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1201"); + exit(1); + } + } +} +unsigned char _print_IntSet(CursorTy arg_398_574_924) +{ + TagTyPacked tag_1204 = *(TagTyPacked *) arg_398_574_924; + CursorTy tail_1205 = arg_398_574_924 + sizeof(IntTy); + + + switch_1206: + ; + switch (tag_1204) { + + case 0: + { + IntTy x_399_575_925 = + ((Int64Int64CursorCursorProd *) tail_1205)->field0; + IntTy x_400_576_926 = + ((Int64Int64CursorCursorProd *) tail_1205)->field1; + CursorTy x_401_577_927 = + ((Int64Int64CursorCursorProd *) tail_1205)->field2; + CursorTy x_402_578_928 = + ((Int64Int64CursorCursorProd *) tail_1205)->field3; + unsigned char wildcard_407_579_929 = print_symbol(1159); + unsigned char wildcard_412_580_930 = print_symbol(1161); + unsigned char y_403_581_931 = printf("%lld", x_399_575_925); + unsigned char wildcard_411_582_932 = print_symbol(1161); + unsigned char y_404_583_933 = printf("%lld", x_400_576_926); + unsigned char wildcard_410_584_934 = print_symbol(1161); + unsigned char y_405_585_935 = _print_IntSet(x_401_577_927); + unsigned char wildcard_409_586_936 = print_symbol(1161); + unsigned char y_406_587_937 = _print_IntSet(x_402_578_928); + unsigned char wildcard_408_588_938 = print_symbol(1158); + + return 0; + break; + } + + case 1: + { + unsigned char wildcard_413_589_939 = print_symbol(1160); + unsigned char wildcard_414_590_940 = print_symbol(1158); + + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1204"); + exit(1); + } + } +} +CursorTy caseFn_415(IntTy x_89_416_591_941, CursorTy rr_95_417_592_942, + IntTy rx_93_418_593_943, IntTy rs_92_419_594_944, + CursorTy rl_94_420_595_945) +{ + TagTyPacked tag_1207 = *(TagTyPacked *) rl_94_420_595_945; + CursorTy tail_1208 = rl_94_420_595_945 + sizeof(IntTy); + + + switch_1212: + ; + switch (tag_1207) { + + case 0: + { + IntTy rls_100_596_946 = + ((Int64Int64CursorCursorProd *) tail_1208)->field0; + IntTy rlx_101_597_947 = + ((Int64Int64CursorCursorProd *) tail_1208)->field1; + CursorTy rll_102_598_948 = + ((Int64Int64CursorCursorProd *) tail_1208)->field2; + CursorTy rlr_103_599_949 = + ((Int64Int64CursorCursorProd *) tail_1208)->field3; + IntTy fltPrm_692_950 = size(rl_94_420_595_945); + IntTy fltPrm_694_951 = size(rr_95_417_592_942); + IntTy fltPrm_693_952 = 2 * fltPrm_694_951; + BoolTy fltIf_691_953 = fltPrm_692_950 < fltPrm_693_952; + + if (fltIf_691_953) { + IntTy fltPkd_695_954 = 1 + rs_92_419_594_944; + IntTy fltPrm_698_955 = size(rl_94_420_595_945); + IntTy fltPkd_697_956 = 1 + fltPrm_698_955; + PtrTy fltPkd_699_957 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_699_957)->field0 = 1; + + PtrTy fltPkd_696_958 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) fltPkd_696_958)->field0 = + 0; + ((Int64Int64Int64CursorCursorProd *) fltPkd_696_958)->field1 = + fltPkd_697_956; + ((Int64Int64Int64CursorCursorProd *) fltPkd_696_958)->field2 = + x_89_416_591_941; + ((Int64Int64Int64CursorCursorProd *) fltPkd_696_958)->field3 = + fltPkd_699_957; + ((Int64Int64Int64CursorCursorProd *) fltPkd_696_958)->field4 = + rl_94_420_595_945; + + PtrTy tailift_1209 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1209)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1209)->field1 = + fltPkd_695_954; + ((Int64Int64Int64CursorCursorProd *) tailift_1209)->field2 = + rx_93_418_593_943; + ((Int64Int64Int64CursorCursorProd *) tailift_1209)->field3 = + fltPkd_696_958; + ((Int64Int64Int64CursorCursorProd *) tailift_1209)->field4 = + rr_95_417_592_942; + return tailift_1209; + } else { + IntTy fltPkd_700_959 = 1 + rs_92_419_594_944; + IntTy fltPkd_701_960 = val(rl_94_420_595_945); + CursorTy fltAppE_705_961 = left(rl_94_420_595_945); + IntTy fltPrm_704_962 = size(fltAppE_705_961); + IntTy fltPkd_703_963 = 1 + fltPrm_704_962; + PtrTy fltPkd_706_964 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_706_964)->field0 = 1; + + CursorTy fltPkd_707_965 = left(rl_94_420_595_945); + PtrTy fltPkd_702_966 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) fltPkd_702_966)->field0 = + 0; + ((Int64Int64Int64CursorCursorProd *) fltPkd_702_966)->field1 = + fltPkd_703_963; + ((Int64Int64Int64CursorCursorProd *) fltPkd_702_966)->field2 = + x_89_416_591_941; + ((Int64Int64Int64CursorCursorProd *) fltPkd_702_966)->field3 = + fltPkd_706_964; + ((Int64Int64Int64CursorCursorProd *) fltPkd_702_966)->field4 = + fltPkd_707_965; + + IntTy fltPrm_711_967 = size(rr_95_417_592_942); + IntTy fltPrm_710_968 = 1 + fltPrm_711_967; + CursorTy fltAppE_713_969 = right(rl_94_420_595_945); + IntTy fltPrm_712_970 = size(fltAppE_713_969); + IntTy fltPkd_709_971 = fltPrm_710_968 + fltPrm_712_970; + CursorTy fltPkd_714_972 = right(rl_94_420_595_945); + PtrTy fltPkd_708_973 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) fltPkd_708_973)->field0 = + 0; + ((Int64Int64Int64CursorCursorProd *) fltPkd_708_973)->field1 = + fltPkd_709_971; + ((Int64Int64Int64CursorCursorProd *) fltPkd_708_973)->field2 = + rx_93_418_593_943; + ((Int64Int64Int64CursorCursorProd *) fltPkd_708_973)->field3 = + fltPkd_714_972; + ((Int64Int64Int64CursorCursorProd *) fltPkd_708_973)->field4 = + rr_95_417_592_942; + + PtrTy tailift_1210 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1210)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1210)->field1 = + fltPkd_700_959; + ((Int64Int64Int64CursorCursorProd *) tailift_1210)->field2 = + fltPkd_701_960; + ((Int64Int64Int64CursorCursorProd *) tailift_1210)->field3 = + fltPkd_702_966; + ((Int64Int64Int64CursorCursorProd *) tailift_1210)->field4 = + fltPkd_708_973; + return tailift_1210; + } + break; + } + + case 1: + { + PtrTy fltPkd_716_974 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_716_974)->field0 = 1; + + PtrTy fltPkd_717_975 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_717_975)->field0 = 1; + + PtrTy fltPkd_715_976 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) fltPkd_715_976)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) fltPkd_715_976)->field1 = 1; + ((Int64Int64Int64CursorCursorProd *) fltPkd_715_976)->field2 = + x_89_416_591_941; + ((Int64Int64Int64CursorCursorProd *) fltPkd_715_976)->field3 = + fltPkd_716_974; + ((Int64Int64Int64CursorCursorProd *) fltPkd_715_976)->field4 = + fltPkd_717_975; + + PtrTy tailift_1211 = ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1211)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1211)->field1 = 3; + ((Int64Int64Int64CursorCursorProd *) tailift_1211)->field2 = + rx_93_418_593_943; + ((Int64Int64Int64CursorCursorProd *) tailift_1211)->field3 = + fltPkd_715_976; + ((Int64Int64Int64CursorCursorProd *) tailift_1211)->field4 = + rr_95_417_592_942; + return tailift_1211; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1207"); + exit(1); + } + } +} +CursorTy caseFn_421(IntTy x_89_422_600_977, CursorTy r_91_423_601_978, + IntTy rx_93_424_602_979, CursorTy rl_94_425_603_980) +{ + TagTyPacked tag_1213 = *(TagTyPacked *) rl_94_425_603_980; + CursorTy tail_1214 = rl_94_425_603_980 + sizeof(IntTy); + + + switch_1217: + ; + switch (tag_1213) { + + case 0: + { + IntTy rls_104_604_981 = + ((Int64Int64CursorCursorProd *) tail_1214)->field0; + IntTy rlx_105_605_982 = + ((Int64Int64CursorCursorProd *) tail_1214)->field1; + CursorTy rll_106_606_983 = + ((Int64Int64CursorCursorProd *) tail_1214)->field2; + CursorTy rlr_107_607_984 = + ((Int64Int64CursorCursorProd *) tail_1214)->field3; + IntTy fltPkd_718_985 = val(rl_94_425_603_980); + PtrTy fltPkd_720_986 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_720_986)->field0 = 1; + + PtrTy fltPkd_721_987 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_721_987)->field0 = 1; + + PtrTy fltPkd_719_988 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) fltPkd_719_988)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) fltPkd_719_988)->field1 = 1; + ((Int64Int64Int64CursorCursorProd *) fltPkd_719_988)->field2 = + x_89_422_600_977; + ((Int64Int64Int64CursorCursorProd *) fltPkd_719_988)->field3 = + fltPkd_720_986; + ((Int64Int64Int64CursorCursorProd *) fltPkd_719_988)->field4 = + fltPkd_721_987; + + PtrTy fltPkd_723_989 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_723_989)->field0 = 1; + + PtrTy fltPkd_724_990 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_724_990)->field0 = 1; + + PtrTy fltPkd_722_991 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) fltPkd_722_991)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) fltPkd_722_991)->field1 = 1; + ((Int64Int64Int64CursorCursorProd *) fltPkd_722_991)->field2 = + rx_93_424_602_979; + ((Int64Int64Int64CursorCursorProd *) fltPkd_722_991)->field3 = + fltPkd_723_989; + ((Int64Int64Int64CursorCursorProd *) fltPkd_722_991)->field4 = + fltPkd_724_990; + + PtrTy tailift_1215 = ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1215)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1215)->field1 = 3; + ((Int64Int64Int64CursorCursorProd *) tailift_1215)->field2 = + fltPkd_718_985; + ((Int64Int64Int64CursorCursorProd *) tailift_1215)->field3 = + fltPkd_719_988; + ((Int64Int64Int64CursorCursorProd *) tailift_1215)->field4 = + fltPkd_722_991; + return tailift_1215; + break; + } + + case 1: + { + PtrTy fltPkd_725_992 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_725_992)->field0 = 1; + + PtrTy tailift_1216 = ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1216)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1216)->field1 = 2; + ((Int64Int64Int64CursorCursorProd *) tailift_1216)->field2 = + x_89_422_600_977; + ((Int64Int64Int64CursorCursorProd *) tailift_1216)->field3 = + fltPkd_725_992; + ((Int64Int64Int64CursorCursorProd *) tailift_1216)->field4 = + r_91_423_601_978; + return tailift_1216; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1213"); + exit(1); + } + } +} +CursorTy caseFn_426(IntTy x_89_427_608_993, CursorTy r_91_428_609_994, + CursorTy rr_95_429_610_995, IntTy rx_93_430_611_996, + IntTy rs_92_431_612_997, CursorTy rl_94_432_613_998) +{ + TagTyPacked tag_1218 = *(TagTyPacked *) rr_95_429_610_995; + CursorTy tail_1219 = rr_95_429_610_995 + sizeof(IntTy); + + + switch_1220: + ; + switch (tag_1218) { + + case 0: + { + IntTy rrs_96_614_999 = + ((Int64Int64CursorCursorProd *) tail_1219)->field0; + IntTy rrx_97_615_1000 = + ((Int64Int64CursorCursorProd *) tail_1219)->field1; + CursorTy rrl_98_616_1001 = + ((Int64Int64CursorCursorProd *) tail_1219)->field2; + CursorTy rrr_99_617_1002 = + ((Int64Int64CursorCursorProd *) tail_1219)->field3; + + return caseFn_415(x_89_427_608_993, rr_95_429_610_995, + rx_93_430_611_996, rs_92_431_612_997, + rl_94_432_613_998); + break; + } + + case 1: + { + return caseFn_421(x_89_427_608_993, r_91_428_609_994, + rx_93_430_611_996, rl_94_432_613_998); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1218"); + exit(1); + } + } +} +CursorTy caseFn_433(IntTy x_89_434_618_1003, CursorTy r_91_435_619_1004) +{ + TagTyPacked tag_1221 = *(TagTyPacked *) r_91_435_619_1004; + CursorTy tail_1222 = r_91_435_619_1004 + sizeof(IntTy); + + + switch_1224: + ; + switch (tag_1221) { + + case 1: + { + PtrTy fltPkd_726_1005 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_726_1005)->field0 = 1; + + PtrTy fltPkd_727_1006 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_727_1006)->field0 = 1; + + PtrTy tailift_1223 = ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1223)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1223)->field1 = 1; + ((Int64Int64Int64CursorCursorProd *) tailift_1223)->field2 = + x_89_434_618_1003; + ((Int64Int64Int64CursorCursorProd *) tailift_1223)->field3 = + fltPkd_726_1005; + ((Int64Int64Int64CursorCursorProd *) tailift_1223)->field4 = + fltPkd_727_1006; + return tailift_1223; + break; + } + + case 0: + { + IntTy rs_92_620_1007 = + ((Int64Int64CursorCursorProd *) tail_1222)->field0; + IntTy rx_93_621_1008 = + ((Int64Int64CursorCursorProd *) tail_1222)->field1; + CursorTy rl_94_622_1009 = + ((Int64Int64CursorCursorProd *) tail_1222)->field2; + CursorTy rr_95_623_1010 = + ((Int64Int64CursorCursorProd *) tail_1222)->field3; + + return caseFn_426(x_89_434_618_1003, r_91_435_619_1004, + rr_95_623_1010, rx_93_621_1008, rs_92_620_1007, + rl_94_622_1009); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1221"); + exit(1); + } + } +} +CursorTy caseFn_436(CursorTy l_90_437_624_1011, IntTy x_89_438_625_1012, + CursorTy r_91_439_626_1013, IntTy ls_108_440_627_1014) +{ + TagTyPacked tag_1225 = *(TagTyPacked *) r_91_439_626_1013; + CursorTy tail_1226 = r_91_439_626_1013 + sizeof(IntTy); + + + switch_1231: + ; + switch (tag_1225) { + + case 1: + { + IntTy fltPkd_728_1015 = 1 + ls_108_440_627_1014; + PtrTy fltPkd_729_1016 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_729_1016)->field0 = 1; + + PtrTy tailift_1227 = ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1227)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1227)->field1 = + fltPkd_728_1015; + ((Int64Int64Int64CursorCursorProd *) tailift_1227)->field2 = + x_89_438_625_1012; + ((Int64Int64Int64CursorCursorProd *) tailift_1227)->field3 = + l_90_437_624_1011; + ((Int64Int64Int64CursorCursorProd *) tailift_1227)->field4 = + fltPkd_729_1016; + return tailift_1227; + break; + } + + case 0: + { + IntTy rs_112_628_1017 = + ((Int64Int64CursorCursorProd *) tail_1226)->field0; + IntTy rx_113_629_1018 = + ((Int64Int64CursorCursorProd *) tail_1226)->field1; + CursorTy rl_114_630_1019 = + ((Int64Int64CursorCursorProd *) tail_1226)->field2; + CursorTy rr_115_631_1020 = + ((Int64Int64CursorCursorProd *) tail_1226)->field3; + IntTy fltPrm_731_1021 = 3 * ls_108_440_627_1014; + BoolTy fltIf_730_1022 = rs_112_628_1017 > fltPrm_731_1021; + + if (fltIf_730_1022) { + IntTy fltPrm_733_1023 = size(rl_114_630_1019); + IntTy fltPrm_735_1024 = size(rr_115_631_1020); + IntTy fltPrm_734_1025 = 2 * fltPrm_735_1024; + BoolTy fltIf_732_1026 = fltPrm_733_1023 < fltPrm_734_1025; + + if (fltIf_732_1026) { + IntTy fltPrm_737_1027 = 1 + ls_108_440_627_1014; + IntTy fltPkd_736_1028 = fltPrm_737_1027 + rs_112_628_1017; + IntTy fltPrm_740_1029 = 1 + ls_108_440_627_1014; + IntTy fltPrm_741_1030 = size(rl_114_630_1019); + IntTy fltPkd_739_1031 = fltPrm_740_1029 + fltPrm_741_1030; + PtrTy fltPkd_738_1032 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) fltPkd_738_1032)->field0 = + 0; + ((Int64Int64Int64CursorCursorProd *) fltPkd_738_1032)->field1 = + fltPkd_739_1031; + ((Int64Int64Int64CursorCursorProd *) fltPkd_738_1032)->field2 = + x_89_438_625_1012; + ((Int64Int64Int64CursorCursorProd *) fltPkd_738_1032)->field3 = + l_90_437_624_1011; + ((Int64Int64Int64CursorCursorProd *) fltPkd_738_1032)->field4 = + rl_114_630_1019; + + PtrTy tailift_1228 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1228)->field0 = + 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1228)->field1 = + fltPkd_736_1028; + ((Int64Int64Int64CursorCursorProd *) tailift_1228)->field2 = + rx_113_629_1018; + ((Int64Int64Int64CursorCursorProd *) tailift_1228)->field3 = + fltPkd_738_1032; + ((Int64Int64Int64CursorCursorProd *) tailift_1228)->field4 = + rr_115_631_1020; + return tailift_1228; + } else { + IntTy fltPrm_743_1033 = 1 + ls_108_440_627_1014; + IntTy fltPkd_742_1034 = fltPrm_743_1033 + rs_112_628_1017; + IntTy fltPkd_744_1035 = val(rl_114_630_1019); + IntTy fltPrm_747_1036 = 1 + ls_108_440_627_1014; + CursorTy fltAppE_749_1037 = left(rl_114_630_1019); + IntTy fltPrm_748_1038 = size(fltAppE_749_1037); + IntTy fltPkd_746_1039 = fltPrm_747_1036 + fltPrm_748_1038; + CursorTy fltPkd_750_1040 = left(rl_114_630_1019); + PtrTy fltPkd_745_1041 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) fltPkd_745_1041)->field0 = + 0; + ((Int64Int64Int64CursorCursorProd *) fltPkd_745_1041)->field1 = + fltPkd_746_1039; + ((Int64Int64Int64CursorCursorProd *) fltPkd_745_1041)->field2 = + x_89_438_625_1012; + ((Int64Int64Int64CursorCursorProd *) fltPkd_745_1041)->field3 = + l_90_437_624_1011; + ((Int64Int64Int64CursorCursorProd *) fltPkd_745_1041)->field4 = + fltPkd_750_1040; + + IntTy fltPrm_754_1042 = size(rr_115_631_1020); + IntTy fltPrm_753_1043 = 1 + fltPrm_754_1042; + CursorTy fltAppE_756_1044 = right(rl_114_630_1019); + IntTy fltPrm_755_1045 = size(fltAppE_756_1044); + IntTy fltPkd_752_1046 = fltPrm_753_1043 + fltPrm_755_1045; + CursorTy fltPkd_757_1047 = right(rl_114_630_1019); + PtrTy fltPkd_751_1048 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) fltPkd_751_1048)->field0 = + 0; + ((Int64Int64Int64CursorCursorProd *) fltPkd_751_1048)->field1 = + fltPkd_752_1046; + ((Int64Int64Int64CursorCursorProd *) fltPkd_751_1048)->field2 = + rx_113_629_1018; + ((Int64Int64Int64CursorCursorProd *) fltPkd_751_1048)->field3 = + fltPkd_757_1047; + ((Int64Int64Int64CursorCursorProd *) fltPkd_751_1048)->field4 = + rr_115_631_1020; + + PtrTy tailift_1229 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1229)->field0 = + 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1229)->field1 = + fltPkd_742_1034; + ((Int64Int64Int64CursorCursorProd *) tailift_1229)->field2 = + fltPkd_744_1035; + ((Int64Int64Int64CursorCursorProd *) tailift_1229)->field3 = + fltPkd_745_1041; + ((Int64Int64Int64CursorCursorProd *) tailift_1229)->field4 = + fltPkd_751_1048; + return tailift_1229; + } + } else { + IntTy fltPrm_759_1049 = 1 + ls_108_440_627_1014; + IntTy fltPkd_758_1050 = fltPrm_759_1049 + rs_112_628_1017; + PtrTy tailift_1230 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1230)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1230)->field1 = + fltPkd_758_1050; + ((Int64Int64Int64CursorCursorProd *) tailift_1230)->field2 = + x_89_438_625_1012; + ((Int64Int64Int64CursorCursorProd *) tailift_1230)->field3 = + l_90_437_624_1011; + ((Int64Int64Int64CursorCursorProd *) tailift_1230)->field4 = + r_91_439_626_1013; + return tailift_1230; + } + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1225"); + exit(1); + } + } +} +CursorTy caseFn_441(IntTy x_116_442_632_1051, CursorTy ll_121_443_633_1052, + IntTy lx_120_444_634_1053, IntTy ls_119_445_635_1054, + CursorTy lr_122_446_636_1055, IntTy lls_123_447_637_1056) +{ + TagTyPacked tag_1232 = *(TagTyPacked *) lr_122_446_636_1055; + CursorTy tail_1233 = lr_122_446_636_1055 + sizeof(IntTy); + + + switch_1237: + ; + switch (tag_1232) { + + case 0: + { + IntTy lrs_127_638_1057 = + ((Int64Int64CursorCursorProd *) tail_1233)->field0; + IntTy lrx_128_639_1058 = + ((Int64Int64CursorCursorProd *) tail_1233)->field1; + CursorTy lrl_129_640_1059 = + ((Int64Int64CursorCursorProd *) tail_1233)->field2; + CursorTy lrr_130_641_1060 = + ((Int64Int64CursorCursorProd *) tail_1233)->field3; + IntTy fltPrm_761_1061 = 2 * lls_123_447_637_1056; + BoolTy fltIf_760_1062 = lrs_127_638_1057 < fltPrm_761_1061; + + if (fltIf_760_1062) { + IntTy fltPkd_762_1063 = 1 + ls_119_445_635_1054; + IntTy fltPkd_764_1064 = 1 + lrs_127_638_1057; + PtrTy fltPkd_765_1065 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_765_1065)->field0 = 1; + + PtrTy fltPkd_763_1066 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) fltPkd_763_1066)->field0 = + 0; + ((Int64Int64Int64CursorCursorProd *) fltPkd_763_1066)->field1 = + fltPkd_764_1064; + ((Int64Int64Int64CursorCursorProd *) fltPkd_763_1066)->field2 = + x_116_442_632_1051; + ((Int64Int64Int64CursorCursorProd *) fltPkd_763_1066)->field3 = + lr_122_446_636_1055; + ((Int64Int64Int64CursorCursorProd *) fltPkd_763_1066)->field4 = + fltPkd_765_1065; + + PtrTy tailift_1234 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1234)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1234)->field1 = + fltPkd_762_1063; + ((Int64Int64Int64CursorCursorProd *) tailift_1234)->field2 = + lx_120_444_634_1053; + ((Int64Int64Int64CursorCursorProd *) tailift_1234)->field3 = + ll_121_443_633_1052; + ((Int64Int64Int64CursorCursorProd *) tailift_1234)->field4 = + fltPkd_763_1066; + return tailift_1234; + } else { + IntTy fltPkd_766_1067 = 1 + ls_119_445_635_1054; + IntTy fltPrm_769_1068 = 1 + lls_123_447_637_1056; + IntTy fltPrm_770_1069 = size(lrl_129_640_1059); + IntTy fltPkd_768_1070 = fltPrm_769_1068 + fltPrm_770_1069; + PtrTy fltPkd_767_1071 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) fltPkd_767_1071)->field0 = + 0; + ((Int64Int64Int64CursorCursorProd *) fltPkd_767_1071)->field1 = + fltPkd_768_1070; + ((Int64Int64Int64CursorCursorProd *) fltPkd_767_1071)->field2 = + lx_120_444_634_1053; + ((Int64Int64Int64CursorCursorProd *) fltPkd_767_1071)->field3 = + ll_121_443_633_1052; + ((Int64Int64Int64CursorCursorProd *) fltPkd_767_1071)->field4 = + lrl_129_640_1059; + + IntTy fltPrm_773_1072 = size(lrr_130_641_1060); + IntTy fltPkd_772_1073 = 1 + fltPrm_773_1072; + PtrTy fltPkd_774_1074 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_774_1074)->field0 = 1; + + PtrTy fltPkd_771_1075 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) fltPkd_771_1075)->field0 = + 0; + ((Int64Int64Int64CursorCursorProd *) fltPkd_771_1075)->field1 = + fltPkd_772_1073; + ((Int64Int64Int64CursorCursorProd *) fltPkd_771_1075)->field2 = + x_116_442_632_1051; + ((Int64Int64Int64CursorCursorProd *) fltPkd_771_1075)->field3 = + lrr_130_641_1060; + ((Int64Int64Int64CursorCursorProd *) fltPkd_771_1075)->field4 = + fltPkd_774_1074; + + PtrTy tailift_1235 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1235)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1235)->field1 = + fltPkd_766_1067; + ((Int64Int64Int64CursorCursorProd *) tailift_1235)->field2 = + lrx_128_639_1058; + ((Int64Int64Int64CursorCursorProd *) tailift_1235)->field3 = + fltPkd_767_1071; + ((Int64Int64Int64CursorCursorProd *) tailift_1235)->field4 = + fltPkd_771_1075; + return tailift_1235; + } + break; + } + + case 1: + { + PtrTy fltPkd_776_1076 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_776_1076)->field0 = 1; + + PtrTy fltPkd_777_1077 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_777_1077)->field0 = 1; + + PtrTy fltPkd_775_1078 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) fltPkd_775_1078)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) fltPkd_775_1078)->field1 = 1; + ((Int64Int64Int64CursorCursorProd *) fltPkd_775_1078)->field2 = + x_116_442_632_1051; + ((Int64Int64Int64CursorCursorProd *) fltPkd_775_1078)->field3 = + fltPkd_776_1076; + ((Int64Int64Int64CursorCursorProd *) fltPkd_775_1078)->field4 = + fltPkd_777_1077; + + PtrTy tailift_1236 = ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1236)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1236)->field1 = 3; + ((Int64Int64Int64CursorCursorProd *) tailift_1236)->field2 = + lx_120_444_634_1053; + ((Int64Int64Int64CursorCursorProd *) tailift_1236)->field3 = + ll_121_443_633_1052; + ((Int64Int64Int64CursorCursorProd *) tailift_1236)->field4 = + fltPkd_775_1078; + return tailift_1236; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1232"); + exit(1); + } + } +} +CursorTy caseFn_448(CursorTy l_117_449_642_1079, IntTy x_116_450_643_1080, + IntTy lx_120_451_644_1081, CursorTy lr_122_452_645_1082) +{ + TagTyPacked tag_1238 = *(TagTyPacked *) lr_122_452_645_1082; + CursorTy tail_1239 = lr_122_452_645_1082 + sizeof(IntTy); + + + switch_1242: + ; + switch (tag_1238) { + + case 0: + { + IntTy lrs_131_646_1083 = + ((Int64Int64CursorCursorProd *) tail_1239)->field0; + IntTy lrx_132_647_1084 = + ((Int64Int64CursorCursorProd *) tail_1239)->field1; + CursorTy lrl_133_648_1085 = + ((Int64Int64CursorCursorProd *) tail_1239)->field2; + CursorTy lrr_134_649_1086 = + ((Int64Int64CursorCursorProd *) tail_1239)->field3; + PtrTy fltPkd_779_1087 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_779_1087)->field0 = 1; + + PtrTy fltPkd_780_1088 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_780_1088)->field0 = 1; + + PtrTy fltPkd_778_1089 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) fltPkd_778_1089)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) fltPkd_778_1089)->field1 = 1; + ((Int64Int64Int64CursorCursorProd *) fltPkd_778_1089)->field2 = + lx_120_451_644_1081; + ((Int64Int64Int64CursorCursorProd *) fltPkd_778_1089)->field3 = + fltPkd_779_1087; + ((Int64Int64Int64CursorCursorProd *) fltPkd_778_1089)->field4 = + fltPkd_780_1088; + + PtrTy fltPkd_782_1090 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_782_1090)->field0 = 1; + + PtrTy fltPkd_783_1091 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_783_1091)->field0 = 1; + + PtrTy fltPkd_781_1092 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) fltPkd_781_1092)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) fltPkd_781_1092)->field1 = 1; + ((Int64Int64Int64CursorCursorProd *) fltPkd_781_1092)->field2 = + x_116_450_643_1080; + ((Int64Int64Int64CursorCursorProd *) fltPkd_781_1092)->field3 = + fltPkd_782_1090; + ((Int64Int64Int64CursorCursorProd *) fltPkd_781_1092)->field4 = + fltPkd_783_1091; + + PtrTy tailift_1240 = ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1240)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1240)->field1 = 3; + ((Int64Int64Int64CursorCursorProd *) tailift_1240)->field2 = + lrx_132_647_1084; + ((Int64Int64Int64CursorCursorProd *) tailift_1240)->field3 = + fltPkd_778_1089; + ((Int64Int64Int64CursorCursorProd *) tailift_1240)->field4 = + fltPkd_781_1092; + return tailift_1240; + break; + } + + case 1: + { + PtrTy fltPkd_784_1093 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_784_1093)->field0 = 1; + + PtrTy tailift_1241 = ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1241)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1241)->field1 = 2; + ((Int64Int64Int64CursorCursorProd *) tailift_1241)->field2 = + x_116_450_643_1080; + ((Int64Int64Int64CursorCursorProd *) tailift_1241)->field3 = + l_117_449_642_1079; + ((Int64Int64Int64CursorCursorProd *) tailift_1241)->field4 = + fltPkd_784_1093; + return tailift_1241; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1238"); + exit(1); + } + } +} +CursorTy caseFn_453(CursorTy l_117_454_650_1094, IntTy x_116_455_651_1095, + CursorTy ll_121_456_652_1096, IntTy lx_120_457_653_1097, + IntTy ls_119_458_654_1098, CursorTy lr_122_459_655_1099) +{ + TagTyPacked tag_1243 = *(TagTyPacked *) ll_121_456_652_1096; + CursorTy tail_1244 = ll_121_456_652_1096 + sizeof(IntTy); + + + switch_1245: + ; + switch (tag_1243) { + + case 0: + { + IntTy lls_123_656_1100 = + ((Int64Int64CursorCursorProd *) tail_1244)->field0; + IntTy llx_124_657_1101 = + ((Int64Int64CursorCursorProd *) tail_1244)->field1; + CursorTy lll_125_658_1102 = + ((Int64Int64CursorCursorProd *) tail_1244)->field2; + CursorTy llr_126_659_1103 = + ((Int64Int64CursorCursorProd *) tail_1244)->field3; + + return caseFn_441(x_116_455_651_1095, ll_121_456_652_1096, + lx_120_457_653_1097, ls_119_458_654_1098, + lr_122_459_655_1099, lls_123_656_1100); + break; + } + + case 1: + { + return caseFn_448(l_117_454_650_1094, x_116_455_651_1095, + lx_120_457_653_1097, lr_122_459_655_1099); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1243"); + exit(1); + } + } +} +CursorTy caseFn_460(CursorTy l_117_461_660_1104, IntTy x_116_462_661_1105) +{ + TagTyPacked tag_1246 = *(TagTyPacked *) l_117_461_660_1104; + CursorTy tail_1247 = l_117_461_660_1104 + sizeof(IntTy); + + + switch_1249: + ; + switch (tag_1246) { + + case 1: + { + PtrTy fltPkd_785_1106 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_785_1106)->field0 = 1; + + PtrTy fltPkd_786_1107 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_786_1107)->field0 = 1; + + PtrTy tailift_1248 = ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1248)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1248)->field1 = 1; + ((Int64Int64Int64CursorCursorProd *) tailift_1248)->field2 = + x_116_462_661_1105; + ((Int64Int64Int64CursorCursorProd *) tailift_1248)->field3 = + fltPkd_785_1106; + ((Int64Int64Int64CursorCursorProd *) tailift_1248)->field4 = + fltPkd_786_1107; + return tailift_1248; + break; + } + + case 0: + { + IntTy ls_119_662_1108 = + ((Int64Int64CursorCursorProd *) tail_1247)->field0; + IntTy lx_120_663_1109 = + ((Int64Int64CursorCursorProd *) tail_1247)->field1; + CursorTy ll_121_664_1110 = + ((Int64Int64CursorCursorProd *) tail_1247)->field2; + CursorTy lr_122_665_1111 = + ((Int64Int64CursorCursorProd *) tail_1247)->field3; + + return caseFn_453(l_117_461_660_1104, x_116_462_661_1105, + ll_121_664_1110, lx_120_663_1109, ls_119_662_1108, + lr_122_665_1111); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1246"); + exit(1); + } + } +} +CursorTy caseFn_463(CursorTy r_118_464_666_1112, CursorTy l_117_465_667_1113, + IntTy x_116_466_668_1114, IntTy rs_135_467_669_1115) +{ + TagTyPacked tag_1250 = *(TagTyPacked *) l_117_465_667_1113; + CursorTy tail_1251 = l_117_465_667_1113 + sizeof(IntTy); + + + switch_1256: + ; + switch (tag_1250) { + + case 1: + { + IntTy fltPkd_787_1116 = 1 + rs_135_467_669_1115; + PtrTy fltPkd_788_1117 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_788_1117)->field0 = 1; + + PtrTy tailift_1252 = ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1252)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1252)->field1 = + fltPkd_787_1116; + ((Int64Int64Int64CursorCursorProd *) tailift_1252)->field2 = + x_116_466_668_1114; + ((Int64Int64Int64CursorCursorProd *) tailift_1252)->field3 = + fltPkd_788_1117; + ((Int64Int64Int64CursorCursorProd *) tailift_1252)->field4 = + r_118_464_666_1112; + return tailift_1252; + break; + } + + case 0: + { + IntTy ls_139_670_1118 = + ((Int64Int64CursorCursorProd *) tail_1251)->field0; + IntTy lx_140_671_1119 = + ((Int64Int64CursorCursorProd *) tail_1251)->field1; + CursorTy ll_141_672_1120 = + ((Int64Int64CursorCursorProd *) tail_1251)->field2; + CursorTy lr_142_673_1121 = + ((Int64Int64CursorCursorProd *) tail_1251)->field3; + IntTy fltPrm_790_1122 = 3 * rs_135_467_669_1115; + BoolTy fltIf_789_1123 = ls_139_670_1118 > fltPrm_790_1122; + + if (fltIf_789_1123) { + IntTy fltPrm_792_1124 = size(lr_142_673_1121); + IntTy fltPrm_794_1125 = size(ll_141_672_1120); + IntTy fltPrm_793_1126 = 2 * fltPrm_794_1125; + BoolTy fltIf_791_1127 = fltPrm_792_1124 < fltPrm_793_1126; + + if (fltIf_791_1127) { + IntTy fltPrm_796_1128 = 1 + ls_139_670_1118; + IntTy fltPkd_795_1129 = fltPrm_796_1128 + + rs_135_467_669_1115; + IntTy fltPrm_799_1130 = 1 + rs_135_467_669_1115; + IntTy fltPrm_800_1131 = size(lr_142_673_1121); + IntTy fltPkd_798_1132 = fltPrm_799_1130 + fltPrm_800_1131; + PtrTy fltPkd_797_1133 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) fltPkd_797_1133)->field0 = + 0; + ((Int64Int64Int64CursorCursorProd *) fltPkd_797_1133)->field1 = + fltPkd_798_1132; + ((Int64Int64Int64CursorCursorProd *) fltPkd_797_1133)->field2 = + x_116_466_668_1114; + ((Int64Int64Int64CursorCursorProd *) fltPkd_797_1133)->field3 = + lr_142_673_1121; + ((Int64Int64Int64CursorCursorProd *) fltPkd_797_1133)->field4 = + r_118_464_666_1112; + + PtrTy tailift_1253 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1253)->field0 = + 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1253)->field1 = + fltPkd_795_1129; + ((Int64Int64Int64CursorCursorProd *) tailift_1253)->field2 = + lx_140_671_1119; + ((Int64Int64Int64CursorCursorProd *) tailift_1253)->field3 = + ll_141_672_1120; + ((Int64Int64Int64CursorCursorProd *) tailift_1253)->field4 = + fltPkd_797_1133; + return tailift_1253; + } else { + IntTy fltPrm_802_1134 = 1 + ls_139_670_1118; + IntTy fltPkd_801_1135 = fltPrm_802_1134 + + rs_135_467_669_1115; + IntTy fltPkd_803_1136 = val(lr_142_673_1121); + IntTy fltPrm_807_1137 = size(ll_141_672_1120); + IntTy fltPrm_806_1138 = 1 + fltPrm_807_1137; + CursorTy fltAppE_809_1139 = left(lr_142_673_1121); + IntTy fltPrm_808_1140 = size(fltAppE_809_1139); + IntTy fltPkd_805_1141 = fltPrm_806_1138 + fltPrm_808_1140; + CursorTy fltPkd_810_1142 = left(lr_142_673_1121); + PtrTy fltPkd_804_1143 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) fltPkd_804_1143)->field0 = + 0; + ((Int64Int64Int64CursorCursorProd *) fltPkd_804_1143)->field1 = + fltPkd_805_1141; + ((Int64Int64Int64CursorCursorProd *) fltPkd_804_1143)->field2 = + lx_140_671_1119; + ((Int64Int64Int64CursorCursorProd *) fltPkd_804_1143)->field3 = + ll_141_672_1120; + ((Int64Int64Int64CursorCursorProd *) fltPkd_804_1143)->field4 = + fltPkd_810_1142; + + IntTy fltPrm_813_1144 = 1 + rs_135_467_669_1115; + CursorTy fltAppE_815_1145 = right(lr_142_673_1121); + IntTy fltPrm_814_1146 = size(fltAppE_815_1145); + IntTy fltPkd_812_1147 = fltPrm_813_1144 + fltPrm_814_1146; + CursorTy fltPkd_816_1148 = right(lr_142_673_1121); + PtrTy fltPkd_811_1149 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) fltPkd_811_1149)->field0 = + 0; + ((Int64Int64Int64CursorCursorProd *) fltPkd_811_1149)->field1 = + fltPkd_812_1147; + ((Int64Int64Int64CursorCursorProd *) fltPkd_811_1149)->field2 = + x_116_466_668_1114; + ((Int64Int64Int64CursorCursorProd *) fltPkd_811_1149)->field3 = + fltPkd_816_1148; + ((Int64Int64Int64CursorCursorProd *) fltPkd_811_1149)->field4 = + r_118_464_666_1112; + + PtrTy tailift_1254 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1254)->field0 = + 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1254)->field1 = + fltPkd_801_1135; + ((Int64Int64Int64CursorCursorProd *) tailift_1254)->field2 = + fltPkd_803_1136; + ((Int64Int64Int64CursorCursorProd *) tailift_1254)->field3 = + fltPkd_804_1143; + ((Int64Int64Int64CursorCursorProd *) tailift_1254)->field4 = + fltPkd_811_1149; + return tailift_1254; + } + } else { + IntTy fltPrm_818_1150 = 1 + ls_139_670_1118; + IntTy fltPkd_817_1151 = fltPrm_818_1150 + rs_135_467_669_1115; + PtrTy tailift_1255 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1255)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1255)->field1 = + fltPkd_817_1151; + ((Int64Int64Int64CursorCursorProd *) tailift_1255)->field2 = + x_116_466_668_1114; + ((Int64Int64Int64CursorCursorProd *) tailift_1255)->field3 = + l_117_465_667_1113; + ((Int64Int64Int64CursorCursorProd *) tailift_1255)->field4 = + r_118_464_666_1112; + return tailift_1255; + } + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1250"); + exit(1); + } + } +} +int __main_expr() +{ + add_symbol(1154, "]\n"); + add_symbol(1155, "ID: ["); + add_symbol(1156, "DEPTH: ["); + add_symbol(1157, "---\n"); + add_symbol(1158, ")"); + add_symbol(1159, "(PureSet"); + add_symbol(1160, "(EmptySet"); + add_symbol(1161, " "); + + IntTy fltAppE_674_820 = 16 / 2; + CursorTy fltAppE_675_821 = build(16, 16); + IntTy tmp_app_1152 = eval(fltAppE_674_820, fltAppE_675_821); + + printf("%lld", tmp_app_1152); + printf("\n"); + free_symtable(); + return 0; +} \ No newline at end of file diff --git a/benchmarks/modules/Layout.hs b/benchmarks/modules/Layout.hs new file mode 100644 index 000000000..ed5273487 --- /dev/null +++ b/benchmarks/modules/Layout.hs @@ -0,0 +1,26 @@ + +module Layout where +import Set + +build :: Int -> Int -> IntSet +build x sz = + if x == 0 then singleton 0 + else insert (x-(sz/2)) (build (x-1) sz) + +eval :: Int -> IntSet -> Int +eval x m = + let + _ = printsym (quote "---\n") + _ = printsym (quote "ID: [") + _ = printint (x) + _ = printsym (quote"]\n") + d = iterate (depth x 0 m) + _ = printsym (quote "DEPTH: [") + _ = printint (d) + _ = printsym (quote "]\n") + in if d < 0 then 0 + else eval (x-1) m + +gibbon_main = + let s = 16 + in eval (s/2) (build s s) \ No newline at end of file diff --git a/benchmarks/modules/Map.c b/benchmarks/modules/Map.c new file mode 100644 index 000000000..0251c7920 --- /dev/null +++ b/benchmarks/modules/Map.c @@ -0,0 +1,2357 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// #include +#ifdef _WIN64 +#include +#endif +#include +#include +#include // For va_start etc +#include +#include +#include +#include +#ifdef _POINTER +#include +#endif +#ifdef _PARALLEL +#include +#include +#endif + +#define KB 1024lu +#define MB (KB * 1000lu) +#define GB (MB * 1000lu) + +#define REDIRECTION_TAG 255 +#define INDIRECTION_TAG 254 + +// Initial size of BigInfinite buffers +static long long global_init_biginf_buf_size = (4 * GB); + +// Initial size of Infinite buffers +static long long global_init_inf_buf_size = 1 * KB; + +// Maximum size of a chunk, see GitHub #110. +static long long global_inf_buf_max_chunk_size = 1 * GB; + +static long long global_size_param = 1; +static long long global_iters_param = 1; + +static char* global_benchfile_param = NULL; +static char* global_arrayfile_param = NULL; +// Number of lines in the arrayfile +static long long global_arrayfile_length_param = -1; + +// Sequential for now: +static const int num_workers = 1; + +// Count the number of regions allocated. +static long long global_region_count = 0; +static bool global_region_count_flag = false; + +#ifdef _PARALLEL +static inline void bump_global_region_count() { + __atomic_add_fetch(&global_region_count, 1, __ATOMIC_SEQ_CST); + return; +} +#else +static inline void bump_global_region_count() { + global_region_count++; + return; +} +#endif + +static inline void print_global_region_count() { + printf("REGION_COUNT: %lld\n", global_region_count); + return; +} + +#define REDIRECTION_NODE_SIZE 9 +#define MAX(a,b) (((a)>(b))?(a):(b)) +#define MIN(a,b) (((a)<(b))?(a):(b)) + +// https://www.cprogramming.com/snippets/source-code/find-the-number-of-cpu-cores-for-windows-mac-or-linux +static int get_num_processors() { +#ifdef _WIN64 + SYSTEM_INFO sysinfo; + GetSystemInfo(&sysinfo); + return sysinfo.dwNumberOfProcessors; +#else + return sysconf(_SC_NPROCESSORS_ONLN); +#endif +} + +// Requires -std=gnu11 +int dbgprintf(const char *format, ...) { + int code = 0; + va_list args; + va_start(args, format); +#ifdef _DEBUG + code = vprintf(format, args); +#endif + va_end(args); + return code; +} + + +// ----------------------------------------------------------------------------- +// Allocators +// ----------------------------------------------------------------------------- + + +// ------------------------------------- +// Bump allocation for linked-lists +// ------------------------------------- + + +#ifdef _BUMPALLOC +// #define _DEBUG +#warning "Using bump allocator." + +__thread char* bumpalloc_heap_ptr = (char*)NULL; +__thread char* bumpalloc_heap_ptr_end = (char*)NULL; + +char* saved_heap_ptr_stack[100]; +int num_saved_heap_ptr = 0; + +// For simplicity just use a single large slab: +static inline void INITBUMPALLOC() { + bumpalloc_heap_ptr = (char*)malloc(global_init_biginf_buf_size); + bumpalloc_heap_ptr_end = bumpalloc_heap_ptr + global_init_biginf_buf_size; +#ifdef _DEBUG + printf("Arena size for bump alloc: %lld\n", global_init_biginf_buf_size); + printf("BUMPALLOC/INITBUMPALLOC DONE: heap_ptr = %p\n", bumpalloc_heap_ptr); +#endif +} + +static inline void* BUMPALLOC(long long n) { + if (! bumpalloc_heap_ptr) { + INITBUMPALLOC(); + } + if (bumpalloc_heap_ptr + n < bumpalloc_heap_ptr_end) { + char* old= bumpalloc_heap_ptr; + bumpalloc_heap_ptr += n; + return old; + } else { + fprintf(stderr, "Warning: bump allocator ran out of memory."); + exit(1); + } +} + +// Snapshot the current heap pointer value across all threads. +void save_alloc_state() { + dbgprintf("Saving(%p): pos %d", heap_ptr, num_saved_heap_ptr); + saved_heap_ptr_stack[num_saved_heap_ptr] = heap_ptr; + num_saved_heap_ptr++; + dbgprintf("\n"); +} + +void restore_alloc_state() { + if(num_saved_heap_ptr <= 0) { + fprintf(stderr, "Bad call to restore_alloc_state! Saved stack empty!\ne"); + exit(1); + } + num_saved_heap_ptr--; + dbgprintf("Restoring(%p): pos %d, discarding %p", + saved_heap_ptr_stack[num_saved_heap_ptr], num_saved_heap_ptr, bumpalloc_heap_ptr); + bumpalloc_heap_ptr = saved_heap_ptr_stack[num_saved_heap_ptr]; +} + + +#else +// Regular malloc mode: +void INITBUMPALLOC() {} +void save_alloc_state() {} +void restore_alloc_state() {} + +#define BUMPALLOC(n) malloc(n) + +#endif // BUMPALLOC + + +// ------------------------------------- +// ALLOC and ALLOC_PACKED macros +// ------------------------------------- + + +/* + +If parallelism is enabled, we always use a malloc based allocator +since Boehm GC is not thread-safe in its default configuration. It can be +made thread-safe by building it with appropriate flags, but we don't do that. +Presently, all parallel pointer-based programs will leak memory. + +*/ + +#ifdef _PARALLEL +#define ALLOC(n) malloc(n) +#define ALLOC_PACKED_BIG(n) malloc(n) +char *ALLOC_COUNTED(size_t size) { + bump_global_region_count(); + return ALLOC(size); +} +#else + #ifdef _POINTER +#define ALLOC(n) GC_MALLOC(n) +#define ALLOC_PACKED_BIG(n) GC_MALLOC(n) +char *ALLOC_COUNTED(size_t size) { + bump_global_region_count(); + return GC_MALLOC(size); +} + #else +#define ALLOC(n) malloc(n) +#define ALLOC_PACKED_BIG(n) malloc(n) +char *ALLOC_COUNTED(size_t size) { + bump_global_region_count(); + return ALLOC(size); +} + #endif // _POINTER +#endif // _PARALLEL + + +// Could try alloca() here. Better yet, we could keep our own, +// separate stack and insert our own code to restore the pointer +// before any function that (may have) called ALLOC_SCOPED returns. + +// #define ALLOC_SCOPED() alloca(1024) +#define ALLOC_SCOPED(n) alloca(n) +// #define ALLOC_SCOPED() alloc_scoped() + +// Stack allocation is either too small or blows our stack. +// We need a way to make a giant stack if we want to use alloca. +// #define ALLOC_SCOPED() ALLOC(global_init_biginf_buf_size) + +// Our global pointer. No parallelism. +// static char* stack_scoped_region; +// char* alloc_scoped() { return stack_scoped_region; } + + + +// ------------------------------------- +// Basic types +// ------------------------------------- + +// Must be consistent with sizeOfTy defined in Gibbon.Language.Syntax. + +typedef unsigned char TagTyPacked; +typedef unsigned char TagTyBoxed; +typedef long long IntTy; +typedef char CharTy; +typedef float FloatTy; +typedef unsigned long long SymTy; +typedef bool BoolTy; +typedef char* PtrTy; +typedef char* CursorTy; + +// ------------------------------------- +// Arenas and dictionaries +// ------------------------------------- + +typedef struct mem_arena { + int ind; + char* mem; // TODO(vollmerm): make this a list of chunks? + void* reflist; +} mem_arena_t; + +typedef mem_arena_t* ArenaTy; + +ArenaTy alloc_arena() { + ArenaTy ar = ALLOC(sizeof(mem_arena_t)); + ar->ind = 0; + ar->mem = malloc(global_inf_buf_max_chunk_size); + ar->reflist = 0; + return ar; +} + +void free_arena(ArenaTy ar) { + free(ar->mem); + // TODO(vollmerm): free everything in ar->reflist + free(ar); +} + +CursorTy extend_arena(ArenaTy ar, int size) { + CursorTy ret = ar->mem + ar->ind; + ar->ind += size; + return ret; +} + +typedef struct dict_item { + struct dict_item * next; + int key; + void * ptrval; +} dict_item_t; + +dict_item_t * dict_alloc(ArenaTy ar) { + return (dict_item_t *) extend_arena(ar, sizeof(dict_item_t)); // ALLOC(sizeof(dict_item_t)); +} + +dict_item_t *dict_insert_ptr(ArenaTy ar, dict_item_t *ptr, SymTy key, PtrTy val) { + dict_item_t *ret = dict_alloc(ar); + ret->key = key; + ret->ptrval = val; + ret->next = ptr; + return ret; +} + +PtrTy dict_lookup_ptr(dict_item_t *ptr, SymTy key) { + while (ptr != 0) { + if (ptr->key == key) { + return ptr->ptrval; + } else { + ptr = ptr->next; + } + } + printf("Error, key %lld not found!\n",key); + exit(1); +} + +// ------------------------------------- +// Sets +// ------------------------------------- + + +struct set_elem { + int val; + UT_hash_handle hh; +}; + +typedef struct set_elem* SymSetTy; + +SymSetTy empty_set() { + return NULL; +} + +SymSetTy insert_set(SymSetTy set, int sym) { + SymSetTy s; + HASH_FIND_INT(set, &sym, s); /* sym already in the hash? */ + if (s==NULL) { + s = malloc(sizeof(struct set_elem)); + s->val = sym; + HASH_ADD_INT(set,val,s); + } + return set; +} + +BoolTy contains_set(SymSetTy set, int sym) { + SymSetTy s; + HASH_FIND_INT(set, &sym, s); + return (s!=NULL); +} + +// ------------------------------------- +// Sym Hash +// ------------------------------------- + +struct sym_hash_elem { + int key; + int val; + UT_hash_handle hh; +}; + +typedef struct sym_hash_elem* SymHashTy; + +typedef struct sym_hash_elem* IntHashTy; + +SymHashTy empty_hash() { + return NULL; +} + +SymHashTy insert_hash(SymHashTy hash, int k, int v) { + SymHashTy s; + // NOTE: not checking for duplicates! + // s = malloc(sizeof(struct sym_hash_elem)); + s = ALLOC(sizeof(struct sym_hash_elem)); + s->val = v; + s->key = k; + HASH_ADD_INT(hash,key,s); + + return hash; +} + +IntTy lookup_hash(SymHashTy hash, int k) { + SymHashTy s; + HASH_FIND_INT(hash,&k,s); + if (s==NULL) { + return k; // NOTE: return original key if val not found + // TODO(vollmerm): come up with something better to do here + } else { + return s->val; + } +} + +BoolTy contains_hash(SymHashTy hash, int sym) { + SymHashTy s; + HASH_FIND_INT(hash,&sym,s); + return (s!=NULL); +} + +// ------------------------------------- +// Helpers +// ------------------------------------- + +char* read_benchfile_param() { + if (global_benchfile_param == NULL) { + fprintf(stderr, "read_benchfile_param: benchmark input file was not set! Set using --bench-input.\n"); + exit(1); + } else + return global_benchfile_param; +} + +char* read_arrayfile_param() { + if (global_arrayfile_param == NULL) { + fprintf(stderr, "read_arrayfile_param: array input file was not set! Set using --array-input.\n"); + exit(1); + } else + return global_arrayfile_param; +} + +IntTy read_arrayfile_length_param() { + if (global_arrayfile_length_param == -1) { + fprintf(stderr, "read_arrayfile_length_param: array input file length was not set! Set using --array-input-length.\n"); + exit(1); + } else + return global_arrayfile_length_param; +} + + +// fun fact: __ prefix is actually reserved and this is an undefined behavior. +// These functions must be provided by the code generator. +int __main_expr(); + + +void show_usage(char** argv) +{ + printf("\n"); + printf("This binary was generated by the Gibbon compiler.\n"); + printf("\n"); + printf("Usage: %s [OPTS] [size] [iters]\n", argv[0]); + + printf("\n"); + printf("Options:\n"); + printf(" --buffer-size Set the buffer size (default %lld).\n", global_init_biginf_buf_size); + printf(" --bench-input Set the input file read for benchmarking. Applies only\n"); + printf(" IF the program was *compiled* with --bench-fun. \n"); + return; +} + +double avg(const double* arr, int n) +{ + double sum = 0.0; + for(int i=0; itv_sec - t0->tv_sec) + + ((double)(t1->tv_nsec - t0->tv_nsec) / 1000000000.0); +} + +int compare_doubles(const void *a, const void *b) +{ + const double *da = (const double *) a; + const double *db = (const double *) b; + return (*da > *db) - (*da < *db); +} + +// Exponentiation +IntTy expll(IntTy base, IntTy pow) { + if (base == 2) { + return (1 << pow); + } else { + IntTy i, result = 1; + for (i = 0; i < pow; i++) + result *= base; + return result; + } + } + +// ------------------------------------- +// Symbol table +// ------------------------------------- + +#define global_max_symbol_len 256 + +// Invariant: should always be equal to max(sym_table_keys) +static SymTy global_gensym_counter = 0; + +// Its value is updated by the flags parser. +static char *global_bench_prog_param; + +static SymTy newline_symbol = -1; +static SymTy space_symbol = -1; +static SymTy comma_symbol = -1; +static SymTy leftparen_symbol = -1; +static SymTy rightparen_symbol = -1; + +typedef struct SymTable_elem { + SymTy idx; /* key */ + char value[global_max_symbol_len]; + UT_hash_handle hh; /* makes this structure hashable */ +} SymTable_elem; + +// important! initialize to NULL +SymTable_elem *global_sym_table = NULL; + +void add_symbol(SymTy idx, char *value) { + struct SymTable_elem *s; + s = ALLOC(sizeof(struct SymTable_elem)); + s->idx = idx; + strcpy(s->value, value); + HASH_ADD(hh, global_sym_table, idx, sizeof(IntTy), s); + if (idx > global_gensym_counter) { + global_gensym_counter = idx; + } +} + +void set_newline(SymTy idx) { + newline_symbol = idx; + add_symbol(idx,"NEWLINE"); +} + +void set_space(SymTy idx) { + space_symbol = idx; + add_symbol(idx,"SPACE"); +} + +void set_comma(SymTy idx) { + comma_symbol = idx; + add_symbol(idx,"COMMA"); +} + +void set_leftparen(SymTy idx) { + leftparen_symbol = idx; + add_symbol(idx,"LEFTPAREN"); +} + +void set_rightparen(SymTy idx) { + rightparen_symbol = idx; + add_symbol(idx,"RIGHTPAREN"); +} + +IntTy print_symbol(SymTy idx) { + if (idx == comma_symbol) { + return printf(","); + } else if (idx == newline_symbol) { + return printf("\n"); + } else if (idx == space_symbol) { + return printf(" "); + } else if (idx == leftparen_symbol) { + return printf("("); + } else if (idx == rightparen_symbol) { + return printf(")"); + } else { + struct SymTable_elem *s; + HASH_FIND(hh, global_sym_table, &idx, sizeof(SymTy), s); + if (s == NULL) { + return printf("%lld", idx); + } else { + return printf("%s", s->value); + } + + } +} + +#ifdef _PARALLEL +SymTy gensym() { + SymTy idx = __atomic_add_fetch(&global_gensym_counter, 1, __ATOMIC_SEQ_CST); + return idx; +} +#else +SymTy gensym() { + global_gensym_counter += 1; + SymTy idx = global_gensym_counter; + return idx; +} +#endif + +void free_symtable() { + struct SymTable_elem *elt, *tmp; + HASH_ITER(hh, global_sym_table, elt, tmp) { + HASH_DEL(global_sym_table,elt); + } + free(elt); + free(tmp); +} + +/* + +---------------------------------------- +Garbage collection +---------------------------------------- + + Gibbon has "growing regions" i.e each logical region is backed by a doubly linked-list + of smaller chunks which grows as required. In addition to actual data, each chunk + stores some additional metadata (RegionFooter) to chain the chunks together in a list + and for garbage collection. The footer: + + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + serialized data | rf_reg_metadata_ptr | rf_seq_no | rf_size | rf_next | rf_prev + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + The metadata after the serialized data serves various purposes: + + - rf_reg_metadata_ptr: A pointer to a RegionTy struct that contains various metadata. + Of particular interest to us are the fields: + + = reg_id: A unique identifier for a region. + + = refcount and outset: Whenever an inter-region indirection is created, we record that information + using these two fields. Suppose we have an indirection from region A that points to some chunk + in region B. Then A's outset will store a pointer to that chunk's footer, and B's refcount will + be bumped by 1. Note that all there's only 1 refcount cell, and 1 outset per logical region, + and chunks only store a pointer to them. + + - rf_seq_no: The index of this particular chunk in the list. + + - rf_size: Used during bounds checking to calculate the size of the next region in + the linked list. + + - rf_next / rf_prev: Point to the next and previous chunk respectively. + + +There are two ways in which a region may be freed: + +(1) Whenever it goes out of scope + + The RTS tries to free a region whenever it goes out of scope. But this doesn't always succeed as + regions sometimes contain values that "escape". One reason why this'll happen is if there's an + indirection from A->B, and A lives longer than B. + In such a case, when B goes out of scope it's refcount won't be 0, and the RTS won't free it. + This brings us to (2). + +(2) + + When the RTS successfully frees a region, it decrements the refcounts of all the regions it + points to (via the outset). At the same time, if it encounters a region in the outset whoose + refcount becomes 0 after the decrement, it calls free_region on that. This way we can be sure + that all regions will eventually be garbage collected before the program exits. + + + +Why is it a doubly linked-list? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Due to way that bounds-checking works, the pointers in the outset may actually point to any +arbitrary chunk in the chain. However, we must call free_region on the first one to ensure that +all of them are GC'd. So we need pointers to traverse backward get to the first one. +'trav_to_first_chunk' accomplishes this. + + */ + +#define MAX_OUTSET_LENGTH 10 + +typedef struct RegionTy_struct { + SymTy reg_id; + uint reg_refcount; + CursorTy reg_heap; + uint reg_outset_len; + CursorTy reg_outset[MAX_OUTSET_LENGTH]; +} RegionTy; + +typedef struct RegionFooter_struct { + RegionTy *rf_reg_metadata_ptr; + + IntTy rf_seq_no; + IntTy rf_size; + struct RegionFooter_struct *rf_next; + struct RegionFooter_struct *rf_prev; +} RegionFooter; + +typedef struct ChunkTy_struct { + CursorTy chunk_start; + CursorTy chunk_end; +} ChunkTy; + +static inline void insert_into_outset(CursorTy ptr, RegionTy *reg) { + uint outset_len = reg->reg_outset_len; + // Check for duplicates. + for (uint i = 0; i < outset_len; i++) { + if (ptr == reg->reg_outset[i]) { + return; + } + } + // Otherwise, insert into the outset. + reg->reg_outset[outset_len] = ptr; + reg->reg_outset_len = outset_len + 1; + return; +} + +static inline void remove_from_outset(CursorTy ptr, RegionTy *reg) { + uint outset_len = reg->reg_outset_len; + CursorTy *outset = reg->reg_outset; + int i; + if (outset_len == 0) { + fprintf(stderr, "remove_from_outset: empty outset\n"); + exit(1); + } + // Position of 'ptr' in the outset. + int elt_idx = -1; + for (i = 0; i < outset_len; i++) { + if (ptr == outset[i]) { + elt_idx = i; + } + } + if (elt_idx == -1) { + fprintf(stderr, "remove_from_outset: element not found\n"); + exit(1); + } + // Move all elements ahead of 'elt_idx' back by one position. + for (i = elt_idx; i < outset_len; i++) { + outset[i] = outset[i+1]; + } + return; +} + +RegionTy *alloc_region(IntTy size) { + // Allocate the region metadata. + RegionTy *reg = ALLOC(sizeof(RegionTy)); + if (reg == NULL) { + printf("alloc_region: allocation failed: %ld", sizeof(RegionTy)); + exit(1); + } + + // Allocate the first chunk. + IntTy total_size = size + sizeof(RegionFooter); + CursorTy heap = ALLOC_PACKED_BIG(total_size); + if (heap == NULL) { + printf("alloc_region: malloc failed: %lld", total_size); + exit(1); + } + // Not heap+total_size, since we must keep space for the footer. + CursorTy heap_end = heap + size; + + // Initialize metadata fields. + reg->reg_id = gensym(); + reg->reg_refcount = 1; + reg->reg_heap = heap; + reg->reg_outset_len = 0; + +#ifdef _DEBUG + printf("Allocated a region(%lld): %lld bytes.\n", reg->reg_id, size); +#endif + + // Write the footer. + RegionFooter *footer = (RegionFooter *) heap_end; + footer->rf_reg_metadata_ptr = reg; + footer->rf_seq_no = 1; + footer->rf_size = size; + footer->rf_next = NULL; + footer->rf_prev = NULL; + + return reg; +} + +RegionTy *alloc_counted_region(IntTy size) { + // Bump the count. + bump_global_region_count(); + return alloc_region(size); +} + +ChunkTy alloc_chunk(CursorTy end_old_chunk) { + // Get size from current footer. + RegionFooter *footer = (RegionFooter *) end_old_chunk; + IntTy newsize = footer->rf_size * 2; + // See #110. + if (newsize > global_inf_buf_max_chunk_size) { + newsize = global_inf_buf_max_chunk_size; + } + IntTy total_size = newsize + sizeof(RegionFooter); + + // Allocate. + CursorTy start = ALLOC_PACKED_BIG(total_size); + if (start == NULL) { + printf("alloc_chunk: malloc failed: %lld", total_size); + exit(1); + } + CursorTy end = start + newsize; + + // Link the next chunk's footer. + footer->rf_next = (RegionFooter *) end; + + // Write the footer. + RegionFooter* new_footer = (RegionFooter *) end; + new_footer->rf_reg_metadata_ptr = footer->rf_reg_metadata_ptr; + new_footer->rf_seq_no = footer->rf_seq_no + 1; + new_footer->rf_size = newsize; + new_footer->rf_next = NULL; + new_footer->rf_prev = footer; + +#ifdef _DEBUG + RegionTy *reg = (RegionTy*) new_footer->rf_reg_metadata_ptr; + printf("alloc_chunk: allocated %lld bytes for region %lld.\n", total_size, reg->reg_id); +#endif + + return (ChunkTy) {start , end}; +} + +RegionFooter* trav_to_first_chunk(RegionFooter *footer) { + if (footer->rf_seq_no == 1) { + return footer; + } else if (footer->rf_prev == NULL) { + fprintf(stderr, "No previous chunk found at rf_seq_no: %lld", footer->rf_seq_no); + return NULL; + } else { + trav_to_first_chunk((RegionFooter *) footer->rf_prev); + } + return NULL; +} + +uint get_ref_count(CursorTy end_ptr) { + RegionFooter *footer = (RegionFooter *) end_ptr; + RegionTy *reg = (RegionTy *) footer->rf_reg_metadata_ptr; + return reg->reg_refcount; +} + +// B is the pointer, and A is the pointee (i.e B -> A). +// Bump A's refcount and update B's outset. +static inline void bump_ref_count(CursorTy end_b, CursorTy end_a) { + // Grab footers. + RegionFooter *footer_a = (RegionFooter *) end_a; + RegionFooter *footer_b = (RegionFooter *) end_b; + + // Grab metadata. + RegionTy *reg_a = (RegionTy *) footer_a->rf_reg_metadata_ptr; + RegionTy *reg_b = (RegionTy *) footer_b->rf_reg_metadata_ptr; + + // Bump A's refcount. + uint current_refcount, new_refcount; + current_refcount = reg_a->reg_refcount; + new_refcount = current_refcount + 1; + reg_a->reg_refcount = new_refcount; + +#ifdef _DEBUG + printf("bump_ref_count: %lld -> %lld\n", reg_b->reg_id, reg_a->reg_id); + printf("bump_ref_count: old-refcount=%d, old-outset-len=%d:\n", current_refcount, reg_b->reg_outset_len); + assert(current_refcount == reg_b->reg_outset_len+1); +#endif + + // Add A to B's outset. + insert_into_outset(end_a, reg_b); + +#ifdef _DEBUG + // printf("bump_ref_count: Added %p to %lld's outset, %p.\n", end_a, reg_b->reg_id, reg_b); + printf("bump_ref_count: new-refcount=%d, new-outset-len=%d\n", new_refcount, reg_b->reg_outset_len); + assert(new_refcount == reg_b->reg_outset_len+1); +#endif + + return; +} + +void free_region(CursorTy end_reg) { + // Grab footer and the metadata. + RegionFooter *footer = (RegionFooter *) end_reg; + RegionTy *reg = (RegionTy *) footer->rf_reg_metadata_ptr; + + // + RegionFooter *first_chunk_footer, *next_chunk_footer; + CursorTy first_chunk, next_chunk; + + // Decrement current reference count. + uint current_refcount, new_refcount; + current_refcount = reg->reg_refcount; + new_refcount = 0; + if (current_refcount != 0) { + new_refcount = current_refcount - 1; + reg->reg_refcount = new_refcount; + } + +#ifdef _DEBUG + printf("free_region(%lld): refcounts (1): old-refcount=%d, new-refcount=%d:\n", reg->reg_id, current_refcount, new_refcount); +#endif + + + // Free this region recount is 0. + if (new_refcount == 0) { + +#ifdef _DEBUG + printf("free_region(%lld): outset length: %d\n", reg->reg_id, reg->reg_outset_len); +#endif + + // Decrement refcounts, free regions with refcount==0 and also free + // elements of the outset. + if (reg->reg_outset_len != 0) { + uint outset_len = reg->reg_outset_len; + CursorTy *outset = reg->reg_outset; + RegionFooter *elt_footer; + RegionTy *elt_reg; + uint elt_current_refcount, elt_new_refcount; + CursorTy to_be_removed[MAX_OUTSET_LENGTH]; + uint to_be_removed_idx = 0; + for (int i = 0; i < outset_len; i++) { + elt_footer = (RegionFooter *) outset[i]; + elt_reg = (RegionTy *) elt_footer->rf_reg_metadata_ptr; +#ifdef _DEBUG + elt_current_refcount = elt_reg->reg_refcount; +#endif + elt_new_refcount = elt_current_refcount - 1; + elt_reg->reg_refcount = elt_new_refcount; +#ifdef _DEBUG + printf("free_region(%lld): old-refcount=%d, new-refcount=%d:\n", + elt_reg->reg_id, elt_current_refcount, elt_reg->reg_refcount); +#endif + if (elt_new_refcount == 0) { + // See [Why is it a doubly linked-list?] above + first_chunk_footer = trav_to_first_chunk(elt_footer); + if (first_chunk_footer != NULL) { + free_region((CursorTy) first_chunk_footer); + } + } + to_be_removed[to_be_removed_idx] = outset[i]; + to_be_removed_idx++; + } + // Remove elements from the outset. + for (uint i = 0; i < to_be_removed_idx; i++) { + remove_from_outset(to_be_removed[i], reg); + } + } + + +#ifdef _DEBUG + // Bookkeeping + IntTy num_freed_chunks = 0, total_bytesize = 0; +#endif + + // Free the chunks in this region. + first_chunk = end_reg - footer->rf_size; + first_chunk_footer = footer; + next_chunk = (char*) footer->rf_next; + +#ifdef _DEBUG + printf("free_region(%lld)\n", reg->reg_id); +#endif + +#ifdef _DEBUG + num_freed_chunks++; + total_bytesize = total_bytesize + first_chunk_footer->rf_size; +#endif + free(first_chunk); + + while (next_chunk != NULL) { + next_chunk_footer = (RegionFooter *) next_chunk; + #ifdef _DEBUG + num_freed_chunks++; + total_bytesize = total_bytesize + next_chunk_footer->rf_size; + #endif + free(next_chunk - next_chunk_footer->rf_size); + next_chunk = (char*) next_chunk_footer->rf_next; + } + +#ifdef _DEBUG + printf("free_region(%lld): Freed %lld bytes across %lld chunks.\n", + reg->reg_id, total_bytesize, num_freed_chunks); +#endif + + // Free the metadata. + free(reg); + + } else { +#ifdef _DEBUG + printf("free_region(%lld): non-zero refcount: %d.\n", + reg->reg_id, reg->reg_refcount); +#endif + } +} + +// Assume that all nodes with size information have tags >= 150. +BoolTy is_big(IntTy i, CursorTy cur) { + TagTyPacked tag = *(TagTyPacked *) cur; + if (tag >= 150) { + cur += 1; + IntTy size = *(IntTy *) cur; + if (size >= i) { + return true; + } else { + return false; + } + } + return false; +} + +// ------------------------------------- +// Vectors +// ------------------------------------- + +typedef struct VectorTy_struct { + // Bounds on the vector. + IntTy vec_lower, vec_upper; + + // Size of each element. + IntTy vec_elt_size; + + // Actual elements of the vector. + void* vec_data; +} VectorTy; + +VectorTy* vector_alloc(IntTy num, IntTy elt_size) { + VectorTy *vec = ALLOC(sizeof(VectorTy)); + if (vec == NULL) { + printf("alloc_vector: malloc failed: %ld", sizeof(VectorTy)); + exit(1); + } + void* data = ALLOC(num * elt_size); + if (data == NULL) { + printf("alloc_vector: malloc failed: %ld", sizeof(num * elt_size)); + exit(1); + } + vec->vec_lower = 0; + vec->vec_upper = num; + vec->vec_elt_size = elt_size; + vec->vec_data = data; + return vec; +} + +IntTy vector_length(VectorTy *vec) { + return (vec->vec_upper - vec->vec_lower); +} + +BoolTy vector_is_empty(VectorTy *vec) { + return (vector_length(vec) == 0); +} + +VectorTy* vector_slice(IntTy i, IntTy n, VectorTy *vec) { + IntTy lower = vec->vec_lower + i; + IntTy upper = vec->vec_lower + i + n; + if ((lower > vec->vec_upper)) { + printf("vector_slice: lower out of bounds, %lld > %lld", lower, vec->vec_upper); + exit(1); + } + if ((upper > vec->vec_upper)) { + printf("vector_slice: upper out of bounds: %lld > %lld", upper, vec->vec_upper); + exit(1); + } + VectorTy *vec2 = ALLOC(sizeof(VectorTy)); + if (vec == NULL) { + printf("vector_slice: malloc failed: %ld", sizeof(VectorTy)); + exit(1); + } + vec2->vec_lower = lower; + vec2->vec_upper = upper; + vec2->vec_elt_size = vec->vec_elt_size; + vec2->vec_data = vec->vec_data; + return vec2; +} + +// The callers must cast the return value. +static inline void* vector_nth(VectorTy *vec, IntTy i) { + // if (i < vec->lower || i > vec->upper) { + // printf("vector_nth index out of bounds: %lld (%lld,%lld) \n", i, vec->vec_lower, vec->vec_upper); + // exit(1); + // } + return (vec->vec_data + (vec->vec_elt_size * (vec->vec_lower + i))); +} + +static inline VectorTy* vector_inplace_update(VectorTy *vec, IntTy i, void* elt) { + void* dst = vector_nth(vec, i); + memcpy(dst, elt, vec->vec_elt_size); + return vec; +} + +static inline VectorTy* vector_copy(VectorTy *vec) { + IntTy len = vector_length(vec); + void *start = vector_nth(vec, 0); + VectorTy *vec2 = vector_alloc(len, vec->vec_elt_size); + memcpy(vec2->vec_data, start, len * vec->vec_elt_size); + return vec2; +} + +static inline VectorTy* vector_inplace_sort(VectorTy *vec, int (*compar)(const void *, const void*)) { + void *start = vector_nth(vec, 0); + qsort(start, vector_length(vec), vec->vec_elt_size, compar); + return vec; +} + +static inline VectorTy* vector_sort(VectorTy *vec, int (*compar)(const void *, const void*)) { + VectorTy *vec2 = vector_copy(vec); + vector_inplace_sort(vec2, compar); + return vec2; +} + +static inline VectorTy* vector_concat(VectorTy *vec) { + // Length of the input vector. + IntTy len = vector_length(vec); + // Length of the concatenated vector. + IntTy result_len = 0; + // Size of each element in the concatenated vector. + IntTy result_elt_size = 0; + VectorTy **elt_ref, *elt; + for (IntTy i = 0; i < len; i++) { + elt_ref = vector_nth(vec, i); + elt = *elt_ref; + result_elt_size = elt->vec_elt_size; + result_len += vector_length(elt); + } + + // Concatenated vector. + VectorTy *result = vector_alloc(result_len, result_elt_size); + IntTy elt_len; + // A counter that tracks the index of elements in 'result'. + IntTy k = 0; + for (IntTy i = 0; i < len; i++) { + elt_ref = vector_nth(vec, i); + elt = *elt_ref; + elt_len = vector_length(elt); + + for (IntTy j = 0; j < elt_len; j++) { + void* k_elt = vector_nth(elt, j); + vector_inplace_update(result, k, k_elt); + k++; + } + } + + return result; +} + +static inline void vector_free(VectorTy *vec) { + free(vec->vec_data); + free(vec); + return; +} + +static inline VectorTy* vector_merge(VectorTy *vec1, VectorTy *vec2) { + if (vec1->vec_upper != vec2->vec_lower) { + printf("vector_merge: non-contiguous slices, (%lld,%lld), (%lld,%lld).", + vec1->vec_lower, vec1->vec_upper, vec2->vec_lower, vec2->vec_upper); + exit(1); + } + VectorTy *merged = ALLOC(sizeof(VectorTy)); + if (merged == NULL) { + printf("vector_merge: malloc failed: %ld", sizeof(VectorTy)); + exit(1); + } + merged->vec_lower = vec1->vec_lower; + merged->vec_upper = vec2->vec_upper; + merged->vec_elt_size = vec1->vec_elt_size; + merged->vec_data = vec1->vec_data; + return merged; +} + +void print_timing_array(VectorTy *times) { + printf("TIMES: ["); + double *d; + IntTy n = vector_length(times); + for(int i = 0; i < n; i++) { + d = vector_nth(times, i); + if (i == (n-1)) { + printf("%f",*d); + } + else { + printf("%f, ",*d); + } + } + printf("]\n"); +} + +double sum_timing_array(VectorTy *times) { + double *d; + double acc = 0; + for(int i = 0; i < vector_length(times); i++) { + d = vector_nth(times, i); + acc += *d; + } + return acc; +} + +// ------------------------------------- +// Linked lists +// ------------------------------------- + +typedef struct ListTy_struct { + IntTy ll_data_size; + void* ll_data; + struct ListTy_struct* ll_next; +} ListTy; + +static inline ListTy* list_alloc(IntTy data_size) { + // ListTy *ls = ALLOC(sizeof(ListTy)); + ListTy *ls = BUMPALLOC(sizeof(ListTy)); + ls->ll_data_size = data_size; + ls->ll_data = NULL; + ls->ll_next = NULL; + return ls; +} + +static inline BoolTy list_is_empty(ListTy *ls) { + return ls->ll_next == NULL; +} + +static inline ListTy* list_cons(void* elt, ListTy *ls) { + // void* data = ALLOC(ls->data_size); + void* data = BUMPALLOC(ls->ll_data_size); + if (data == NULL) { + printf("list_cons: malloc failed: %lld", ls->ll_data_size); + exit(1); + } + memcpy(data, elt, ls->ll_data_size); + // ListTy *res = ALLOC(sizeof(ListTy)); + ListTy *res = BUMPALLOC(sizeof(ListTy)); + res->ll_data_size = ls->ll_data_size; + res->ll_data = data; + res->ll_next = (ListTy*) ls; + return res; +} + +static inline void* list_head(ListTy *ls) { + return ls->ll_data; +} + +static inline ListTy* list_tail(ListTy *ls) { + return ls->ll_next; +} + +static inline void list_free(ListTy *ls) { + free(ls->ll_data); + free(ls); + return; +} + +static inline ListTy* list_copy(ListTy *ls) { + ListTy *ls2 = list_alloc(ls->ll_data_size); + if (ls->ll_data != NULL) { + void* data = BUMPALLOC(ls->ll_data_size); + memcpy(data, ls->ll_data, ls->ll_data_size); + ls2->ll_data = data; + } + ls2->ll_next = ls->ll_next; + return ls2; +} + +// ------------------------------------- +// Ppm Images +// ------------------------------------- + +typedef struct __Pixel_struct { + IntTy field0; + IntTy field1; + IntTy field2; +} __Pixel; + +void writePpm(char* filename, IntTy width, IntTy height, VectorTy *pixels); +void writePpm_loop(FILE *fp, IntTy idx, IntTy end, VectorTy *pixels); + +// Example: writePpm("gibbon_rgb_1000.ppm", 1000, 1000, pixels); +void writePpm(char* filename, IntTy width, IntTy height, VectorTy *pixels) +{ + FILE *fp; + fp = fopen(filename, "w+"); + fprintf(fp, "P3\n"); + fprintf(fp, "%lld %lld\n255\n", width, height); + IntTy len = vector_length(pixels); + writePpm_loop(fp, 0, len, pixels); + fclose(fp); + return; +} + +void writePpm_loop(FILE *fp, IntTy idx, IntTy end, VectorTy *pixels) +{ + BoolTy fltIf_5768_6575 = idx == end; + + if (fltIf_5768_6575) { + return; + } else { + __Pixel *tmp_112; + tmp_112 = (__Pixel *) vector_nth(pixels, idx); + __Pixel tup = *tmp_112; + IntTy x = tup.field0; + IntTy y = tup.field1; + IntTy z = tup.field2; + // write to file. + fprintf(fp, "%lld %lld %lld\n", x, y, z); + writePpm_loop(fp, (idx+1), end, pixels); + } +} + +/* -------------------------------------------------------------------------------- */ + +int main(int argc, char** argv) +{ + // parameters to parse: + // + // num iterations: How many times to repeat a benchmark. + // tree size: An integer passes to `build_tree()`. + + struct rlimit lim; + int code; + if ( (code = getrlimit(RLIMIT_STACK, &lim)) ) { + fprintf(stderr, " [gibbon rts] failed to getrlimit, code %d\n", code); + exit(1); + } + + // lim.rlim_cur = 1024LU * 1024LU * 1024LU; // 1GB stack. + lim.rlim_cur = 512LU * 1024LU * 1024LU; // 500MB stack. + // lim.rlim_max = lim.rlim_cur; // Normal users may only be able to decrease this. + + // WARNING: Haven't yet figured out why this doesn't work on MacOS... +#ifndef __APPLE__ + code = setrlimit(RLIMIT_STACK, &lim); + while (code) { + fprintf(stderr, " [gibbon rts] Failed to set stack size to %llu, code %d\n", (unsigned long long)lim.rlim_cur, code); + lim.rlim_cur /= 2; + // lim.rlim_max /= 2; + if(lim.rlim_cur < 100 * 1024) { + fprintf(stderr, " [gibbon rts] Failed setrlimit stack size to something reasonable; giving up.\n"); + break; // abort(); + } + int code = setrlimit(RLIMIT_STACK, &lim); + } +#endif + + int got_numargs = 0; // How many numeric arguments have we got. + + int i; + for (i = 1; i < argc; ++i) + { + if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) { + show_usage(argv); + exit(0); + } + else if (strcmp(argv[i], "--biginf-buffer-size") == 0 && i < argc - 1) + { + global_init_biginf_buf_size = atoll(argv[i + 1]); + i++; + } + else if (strcmp(argv[i], "--inf-buffer-size") == 0 && i < argc - 1) + { + global_init_inf_buf_size = atoll(argv[i + 1]); + i++; + } + else if ((strcmp(argv[i], "--bench-input") == 0)) { + if (i+1 >= argc) { + fprintf(stderr, "Not enough arguments after --bench-input, expected .\n"); + show_usage(argv); + exit(1); + } + global_benchfile_param = argv[i+1]; + i++; + } + else if ((strcmp(argv[i], "--array-input") == 0)) { + if (i+1 >= argc) { + fprintf(stderr, "Not enough arguments after --array-input, expected .\n"); + show_usage(argv); + exit(1); + } + global_arrayfile_param = argv[i+1]; + i++; + } + else if (strcmp(argv[i], "--array-input-length") == 0 && i < argc - 1) { + global_arrayfile_length_param = atoll(argv[i+1]); + i++; + } + else if (strcmp(argv[i], "--bench-prog") == 0 && i < argc - 1) { + int len = strlen(argv[i+1]); + global_bench_prog_param = (char*) malloc((len+1)*sizeof(char)); + strncpy(global_bench_prog_param,argv[i+1],len); + i++; + } + // If present, we expect the two arguments to be + else if (got_numargs >= 2) { + fprintf(stderr, "Extra arguments left over: "); + for(; i < argc; i++) fprintf(stderr, "%s ", argv[i]); + show_usage(argv); + exit(1); + } else { + if (got_numargs == 0) { + global_size_param = atoll(argv[i]); + got_numargs ++; + } else { + global_iters_param = atoll(argv[i]); + } + } + } + + // Initialize global_bench_prog_param to an empty string in case + // the runtime argument --bench-prog isn't passed. + if (global_bench_prog_param == NULL) { + global_bench_prog_param = (char*) malloc(1*sizeof(char)); + *global_bench_prog_param = '\n'; + } + + __main_expr(); + + return 0; +} + +// ----------------------------------------------------------------------------- +// Program starts here +// ----------------------------------------------------------------------------- + +typedef struct Prod_struct { } Prod; +typedef struct Int64Prod_struct { + IntTy field0; + } Int64Prod; +typedef struct Int64Int64Int64VectorCursorCursorProd_struct { + IntTy field0; + IntTy field1; + IntTy field2; + VectorTy *field3; + CursorTy field4; + CursorTy field5; + } Int64Int64Int64VectorCursorCursorProd; +typedef struct Int64Int64VectorCursorCursorProd_struct { + IntTy field0; + IntTy field1; + VectorTy *field2; + CursorTy field3; + CursorTy field4; + } Int64Int64VectorCursorCursorProd; +typedef struct BoolProd_struct { + BoolTy field0; + } BoolProd; +typedef struct TagCursorProd_struct { + TagTyPacked field0; + CursorTy field1; + } TagCursorProd; +typedef struct CursorProd_struct { + CursorTy field0; + } CursorProd; +typedef struct VectorProd_struct { + VectorTy *field0; + } VectorProd; +IntTy ratio(); +IntTy delta(); +CursorTy singleton_421(IntTy k_289_795_1035, VectorTy *x_290_796_1036); +IntTy size_423(CursorTy m_275_797_1039); +CursorTy singleL_429(IntTy k1_214_803_1045, VectorTy *x1_215_804_1046, + CursorTy t1_216_805_1047, CursorTy m_217_806_1048); +CursorTy doubleL_430(IntTy k1_185_812_1055, VectorTy *x1_186_813_1056, + CursorTy t1_187_814_1057, CursorTy m0_188_815_1058); +CursorTy rotateL_424(IntTy k_239_821_1064, VectorTy *x_240_822_1065, + CursorTy l_241_823_1066, CursorTy r_242_824_1067); +CursorTy bin_428(IntTy k_224_830_1078, VectorTy *x_225_831_1079, + CursorTy l_226_832_1080, CursorTy r_227_833_1081); +CursorTy singleR_426(IntTy k1_204_834_1086, VectorTy *x1_205_835_1087, + CursorTy m_206_836_1088, CursorTy t3_207_837_1089); +CursorTy doubleR_427(IntTy k1_170_843_1096, VectorTy *x1_171_844_1097, + CursorTy m0_172_845_1098, CursorTy t4_173_846_1099); +CursorTy rotateR_425(IntTy k_229_852_1105, VectorTy *x_230_853_1106, + CursorTy l_231_854_1107, CursorTy r_232_855_1108); +CursorTy balance_422(IntTy k_249_861_1119, VectorTy *x_250_862_1120, + CursorTy l_251_863_1121, CursorTy r_252_864_1122); +CursorTy insert_419(IntTy kx_254_865_1143, VectorTy *x_255_866_1144, + CursorTy m_256_867_1145); +CursorTy empty_418(); +CursorTy _copy_without_ptrs_Map_v_420(CursorTy arg_723_873_1155); +CursorTy _copy_Map_v_420(CursorTy arg_712_884_1166); +unsigned char _traverse_Map_v_420(CursorTy arg_734_895_1177); +unsigned char _print_Map_v_420(CursorTy arg_745_903_1185); +CursorTy caseFn_765(VectorTy *x1_186_766_923_1205, IntTy k1_185_767_924_1206, + CursorTy t1_187_768_925_1207, CursorTy m1_193_769_926_1208, + IntTy k2_191_770_927_1209, VectorTy *x2_192_771_928_1210, + CursorTy t4_194_772_929_1211); +CursorTy caseFn_773(VectorTy *x1_171_774_935_1219, IntTy k1_170_775_936_1220, + CursorTy t4_173_776_937_1221, CursorTy m1_179_777_938_1222, + IntTy k2_176_778_939_1223, VectorTy *x2_177_779_940_1224, + CursorTy t1_178_780_941_1225); +IntTy ratio() +{ + return 2; +} +IntTy delta() +{ + return 4; +} +CursorTy singleton_421(IntTy k_289_795_1035, VectorTy *x_290_796_1036) +{ + PtrTy fltPkd_961_1037 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_961_1037)->field0 = 0; + + PtrTy fltPkd_962_1038 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_962_1038)->field0 = 0; + + PtrTy tailift_1239 = ALLOC(sizeof(Int64Int64Int64VectorCursorCursorProd)); + + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1239)->field0 = 1; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1239)->field1 = 1; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1239)->field2 = + k_289_795_1035; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1239)->field3 = + x_290_796_1036; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1239)->field4 = + fltPkd_961_1037; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1239)->field5 = + fltPkd_962_1038; + return tailift_1239; +} +IntTy size_423(CursorTy m_275_797_1039) +{ + TagTyPacked tag_1240 = *(TagTyPacked *) m_275_797_1039; + CursorTy tail_1241 = m_275_797_1039 + sizeof(IntTy); + + + switch_1242: + ; + switch (tag_1240) { + + case 0: + { + return 0; + break; + } + + case 1: + { + IntTy sz_277_798_1040 = + ((Int64Int64VectorCursorCursorProd *) tail_1241)->field0; + IntTy wildcard__18_278_799_1041 = + ((Int64Int64VectorCursorCursorProd *) tail_1241)->field1; + VectorTy *wildcard__19_279_800_1042 = + ((Int64Int64VectorCursorCursorProd *) tail_1241)->field2; + CursorTy wildcard__20_280_801_1043 = + ((Int64Int64VectorCursorCursorProd *) tail_1241)->field3; + CursorTy wildcard__21_281_802_1044 = + ((Int64Int64VectorCursorCursorProd *) tail_1241)->field4; + + return sz_277_798_1040; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1240"); + exit(1); + } + } +} +CursorTy singleL_429(IntTy k1_214_803_1045, VectorTy *x1_215_804_1046, + CursorTy t1_216_805_1047, CursorTy m_217_806_1048) +{ + TagTyPacked tag_1243 = *(TagTyPacked *) m_217_806_1048; + CursorTy tail_1244 = m_217_806_1048 + sizeof(IntTy); + + + switch_1245: + ; + switch (tag_1243) { + + case 1: + { + IntTy wildcard__89_219_807_1049 = + ((Int64Int64VectorCursorCursorProd *) tail_1244)->field0; + IntTy k2_220_808_1050 = + ((Int64Int64VectorCursorCursorProd *) tail_1244)->field1; + VectorTy *x2_221_809_1051 = + ((Int64Int64VectorCursorCursorProd *) tail_1244)->field2; + CursorTy t2_222_810_1052 = + ((Int64Int64VectorCursorCursorProd *) tail_1244)->field3; + CursorTy t3_223_811_1053 = + ((Int64Int64VectorCursorCursorProd *) tail_1244)->field4; + CursorTy fltAppE_963_1054 = + bin_428(k1_214_803_1045, x1_215_804_1046, t1_216_805_1047, t2_222_810_1052); + + return bin_428(k2_220_808_1050, x2_221_809_1051, fltAppE_963_1054, + t3_223_811_1053); + break; + } + + case 0: + { + return empty_418(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1243"); + exit(1); + } + } +} +CursorTy doubleL_430(IntTy k1_185_812_1055, VectorTy *x1_186_813_1056, + CursorTy t1_187_814_1057, CursorTy m0_188_815_1058) +{ + TagTyPacked tag_1246 = *(TagTyPacked *) m0_188_815_1058; + CursorTy tail_1247 = m0_188_815_1058 + sizeof(IntTy); + + + switch_1248: + ; + switch (tag_1246) { + + case 1: + { + IntTy wildcard__109_190_816_1059 = + ((Int64Int64VectorCursorCursorProd *) tail_1247)->field0; + IntTy k2_191_817_1060 = + ((Int64Int64VectorCursorCursorProd *) tail_1247)->field1; + VectorTy *x2_192_818_1061 = + ((Int64Int64VectorCursorCursorProd *) tail_1247)->field2; + CursorTy m1_193_819_1062 = + ((Int64Int64VectorCursorCursorProd *) tail_1247)->field3; + CursorTy t4_194_820_1063 = + ((Int64Int64VectorCursorCursorProd *) tail_1247)->field4; + + return caseFn_765(x1_186_813_1056, k1_185_812_1055, t1_187_814_1057, + m1_193_819_1062, k2_191_817_1060, x2_192_818_1061, + t4_194_820_1063); + break; + } + + case 0: + { + return empty_418(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1246"); + exit(1); + } + } +} +CursorTy rotateL_424(IntTy k_239_821_1064, VectorTy *x_240_822_1065, + CursorTy l_241_823_1066, CursorTy r_242_824_1067) +{ + TagTyPacked tag_1249 = *(TagTyPacked *) r_242_824_1067; + CursorTy tail_1250 = r_242_824_1067 + sizeof(IntTy); + + + switch_1251: + ; + switch (tag_1249) { + + case 1: + { + IntTy wildcard__60_244_825_1068 = + ((Int64Int64VectorCursorCursorProd *) tail_1250)->field0; + IntTy wildcard__61_245_826_1069 = + ((Int64Int64VectorCursorCursorProd *) tail_1250)->field1; + VectorTy *wildcard__62_246_827_1070 = + ((Int64Int64VectorCursorCursorProd *) tail_1250)->field2; + CursorTy ly_247_828_1071 = + ((Int64Int64VectorCursorCursorProd *) tail_1250)->field3; + CursorTy ry_248_829_1072 = + ((Int64Int64VectorCursorCursorProd *) tail_1250)->field4; + IntTy fltPrm_965_1073 = size_423(ly_247_828_1071); + IntTy fltPrm_967_1074 = ratio(); + IntTy fltPrm_968_1075 = size_423(ry_248_829_1072); + IntTy fltPrm_966_1076 = fltPrm_967_1074 * fltPrm_968_1075; + BoolTy fltIf_964_1077 = fltPrm_965_1073 < fltPrm_966_1076; + + if (fltIf_964_1077) { + return singleL_429(k_239_821_1064, x_240_822_1065, + l_241_823_1066, r_242_824_1067); + } else { + return doubleL_430(k_239_821_1064, x_240_822_1065, + l_241_823_1066, r_242_824_1067); + } + break; + } + + case 0: + { + return empty_418(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1249"); + exit(1); + } + } +} +CursorTy bin_428(IntTy k_224_830_1078, VectorTy *x_225_831_1079, + CursorTy l_226_832_1080, CursorTy r_227_833_1081) +{ + IntTy fltPrm_971_1082 = size_423(l_226_832_1080); + IntTy fltPrm_972_1083 = size_423(r_227_833_1081); + IntTy fltPrm_970_1084 = fltPrm_971_1082 + fltPrm_972_1083; + IntTy fltPkd_969_1085 = fltPrm_970_1084 + 1; + PtrTy tailift_1252 = ALLOC(sizeof(Int64Int64Int64VectorCursorCursorProd)); + + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1252)->field0 = 1; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1252)->field1 = + fltPkd_969_1085; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1252)->field2 = + k_224_830_1078; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1252)->field3 = + x_225_831_1079; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1252)->field4 = + l_226_832_1080; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1252)->field5 = + r_227_833_1081; + return tailift_1252; +} +CursorTy singleR_426(IntTy k1_204_834_1086, VectorTy *x1_205_835_1087, + CursorTy m_206_836_1088, CursorTy t3_207_837_1089) +{ + TagTyPacked tag_1253 = *(TagTyPacked *) m_206_836_1088; + CursorTy tail_1254 = m_206_836_1088 + sizeof(IntTy); + + + switch_1255: + ; + switch (tag_1253) { + + case 1: + { + IntTy wildcard__99_209_838_1090 = + ((Int64Int64VectorCursorCursorProd *) tail_1254)->field0; + IntTy k2_210_839_1091 = + ((Int64Int64VectorCursorCursorProd *) tail_1254)->field1; + VectorTy *x2_211_840_1092 = + ((Int64Int64VectorCursorCursorProd *) tail_1254)->field2; + CursorTy t1_212_841_1093 = + ((Int64Int64VectorCursorCursorProd *) tail_1254)->field3; + CursorTy t2_213_842_1094 = + ((Int64Int64VectorCursorCursorProd *) tail_1254)->field4; + CursorTy fltAppE_973_1095 = + bin_428(k1_204_834_1086, x1_205_835_1087, t2_213_842_1094, t3_207_837_1089); + + return bin_428(k2_210_839_1091, x2_211_840_1092, t1_212_841_1093, + fltAppE_973_1095); + break; + } + + case 0: + { + return empty_418(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1253"); + exit(1); + } + } +} +CursorTy doubleR_427(IntTy k1_170_843_1096, VectorTy *x1_171_844_1097, + CursorTy m0_172_845_1098, CursorTy t4_173_846_1099) +{ + TagTyPacked tag_1256 = *(TagTyPacked *) m0_172_845_1098; + CursorTy tail_1257 = m0_172_845_1098 + sizeof(IntTy); + + + switch_1258: + ; + switch (tag_1256) { + + case 1: + { + IntTy wildcard__133_175_847_1100 = + ((Int64Int64VectorCursorCursorProd *) tail_1257)->field0; + IntTy k2_176_848_1101 = + ((Int64Int64VectorCursorCursorProd *) tail_1257)->field1; + VectorTy *x2_177_849_1102 = + ((Int64Int64VectorCursorCursorProd *) tail_1257)->field2; + CursorTy t1_178_850_1103 = + ((Int64Int64VectorCursorCursorProd *) tail_1257)->field3; + CursorTy m1_179_851_1104 = + ((Int64Int64VectorCursorCursorProd *) tail_1257)->field4; + + return caseFn_773(x1_171_844_1097, k1_170_843_1096, t4_173_846_1099, + m1_179_851_1104, k2_176_848_1101, x2_177_849_1102, + t1_178_850_1103); + break; + } + + case 0: + { + return empty_418(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1256"); + exit(1); + } + } +} +CursorTy rotateR_425(IntTy k_229_852_1105, VectorTy *x_230_853_1106, + CursorTy l_231_854_1107, CursorTy r_232_855_1108) +{ + TagTyPacked tag_1259 = *(TagTyPacked *) l_231_854_1107; + CursorTy tail_1260 = l_231_854_1107 + sizeof(IntTy); + + + switch_1261: + ; + switch (tag_1259) { + + case 1: + { + IntTy wildcard__72_234_856_1109 = + ((Int64Int64VectorCursorCursorProd *) tail_1260)->field0; + IntTy wildcard__73_235_857_1110 = + ((Int64Int64VectorCursorCursorProd *) tail_1260)->field1; + VectorTy *wildcard__74_236_858_1111 = + ((Int64Int64VectorCursorCursorProd *) tail_1260)->field2; + CursorTy ly_237_859_1112 = + ((Int64Int64VectorCursorCursorProd *) tail_1260)->field3; + CursorTy ry_238_860_1113 = + ((Int64Int64VectorCursorCursorProd *) tail_1260)->field4; + IntTy fltPrm_975_1114 = size_423(ry_238_860_1113); + IntTy fltPrm_977_1115 = ratio(); + IntTy fltPrm_978_1116 = size_423(ly_237_859_1112); + IntTy fltPrm_976_1117 = fltPrm_977_1115 * fltPrm_978_1116; + BoolTy fltIf_974_1118 = fltPrm_975_1114 < fltPrm_976_1117; + + if (fltIf_974_1118) { + return singleR_426(k_229_852_1105, x_230_853_1106, + l_231_854_1107, r_232_855_1108); + } else { + return doubleR_427(k_229_852_1105, x_230_853_1106, + l_231_854_1107, r_232_855_1108); + } + break; + } + + case 0: + { + return empty_418(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1259"); + exit(1); + } + } +} +CursorTy balance_422(IntTy k_249_861_1119, VectorTy *x_250_862_1120, + CursorTy l_251_863_1121, CursorTy r_252_864_1122) +{ + IntTy fltPrm_981_1123 = size_423(l_251_863_1121); + IntTy fltPrm_982_1124 = size_423(r_252_864_1122); + IntTy fltPrm_980_1125 = fltPrm_981_1123 + fltPrm_982_1124; + BoolTy fltIf_979_1126 = fltPrm_980_1125 <= 1; + + if (fltIf_979_1126) { + IntTy fltPrm_984_1127 = size_423(l_251_863_1121); + IntTy fltPrm_985_1128 = size_423(r_252_864_1122); + IntTy fltPkd_983_1129 = fltPrm_984_1127 + fltPrm_985_1128; + PtrTy tailift_1262 = + ALLOC(sizeof(Int64Int64Int64VectorCursorCursorProd)); + + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1262)->field0 = 1; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1262)->field1 = + fltPkd_983_1129; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1262)->field2 = + k_249_861_1119; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1262)->field3 = + x_250_862_1120; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1262)->field4 = + l_251_863_1121; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1262)->field5 = + r_252_864_1122; + return tailift_1262; + } else { + IntTy fltPrm_987_1130 = size_423(r_252_864_1122); + IntTy fltPrm_989_1131 = delta(); + IntTy fltPrm_990_1132 = size_423(l_251_863_1121); + IntTy fltPrm_988_1133 = fltPrm_989_1131 * fltPrm_990_1132; + BoolTy fltIf_986_1134 = fltPrm_987_1130 >= fltPrm_988_1133; + + if (fltIf_986_1134) { + return rotateL_424(k_249_861_1119, x_250_862_1120, l_251_863_1121, + r_252_864_1122); + } else { + IntTy fltPrm_992_1135 = size_423(l_251_863_1121); + IntTy fltPrm_994_1136 = delta(); + IntTy fltPrm_995_1137 = size_423(r_252_864_1122); + IntTy fltPrm_993_1138 = fltPrm_994_1136 * fltPrm_995_1137; + BoolTy fltIf_991_1139 = fltPrm_992_1135 >= fltPrm_993_1138; + + if (fltIf_991_1139) { + return rotateR_425(k_249_861_1119, x_250_862_1120, + l_251_863_1121, r_252_864_1122); + } else { + IntTy fltPrm_997_1140 = size_423(l_251_863_1121); + IntTy fltPrm_998_1141 = size_423(r_252_864_1122); + IntTy fltPkd_996_1142 = fltPrm_997_1140 + fltPrm_998_1141; + PtrTy tailift_1263 = + ALLOC(sizeof(Int64Int64Int64VectorCursorCursorProd)); + + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1263)->field0 = + 1; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1263)->field1 = + fltPkd_996_1142; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1263)->field2 = + k_249_861_1119; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1263)->field3 = + x_250_862_1120; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1263)->field4 = + l_251_863_1121; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1263)->field5 = + r_252_864_1122; + return tailift_1263; + } + } + } +} +CursorTy insert_419(IntTy kx_254_865_1143, VectorTy *x_255_866_1144, + CursorTy m_256_867_1145) +{ + TagTyPacked tag_1264 = *(TagTyPacked *) m_256_867_1145; + CursorTy tail_1265 = m_256_867_1145 + sizeof(IntTy); + + + switch_1267: + ; + switch (tag_1264) { + + case 0: + { + return singleton_421(kx_254_865_1143, x_255_866_1144); + break; + } + + case 1: + { + IntTy sz_258_868_1146 = + ((Int64Int64VectorCursorCursorProd *) tail_1265)->field0; + IntTy k_259_869_1147 = + ((Int64Int64VectorCursorCursorProd *) tail_1265)->field1; + VectorTy *v_260_870_1148 = + ((Int64Int64VectorCursorCursorProd *) tail_1265)->field2; + CursorTy l_261_871_1149 = + ((Int64Int64VectorCursorCursorProd *) tail_1265)->field3; + CursorTy r_262_872_1150 = + ((Int64Int64VectorCursorCursorProd *) tail_1265)->field4; + BoolTy fltIf_999_1151 = kx_254_865_1143 == k_259_869_1147; + + if (fltIf_999_1151) { + PtrTy tailift_1266 = + ALLOC(sizeof(Int64Int64Int64VectorCursorCursorProd)); + + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1266)->field0 = + 1; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1266)->field1 = + sz_258_868_1146; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1266)->field2 = + k_259_869_1147; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1266)->field3 = + x_255_866_1144; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1266)->field4 = + l_261_871_1149; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1266)->field5 = + r_262_872_1150; + return tailift_1266; + } else { + BoolTy fltIf_1000_1152 = kx_254_865_1143 <= k_259_869_1147; + + if (fltIf_1000_1152) { + CursorTy fltAppE_1001_1153 = + insert_419(kx_254_865_1143, x_255_866_1144, l_261_871_1149); + + return balance_422(k_259_869_1147, v_260_870_1148, + fltAppE_1001_1153, r_262_872_1150); + } else { + CursorTy fltAppE_1002_1154 = + insert_419(kx_254_865_1143, x_255_866_1144, r_262_872_1150); + + return balance_422(k_259_869_1147, v_260_870_1148, + l_261_871_1149, fltAppE_1002_1154); + } + } + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1264"); + exit(1); + } + } +} +CursorTy empty_418() +{ + PtrTy tailift_1268 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) tailift_1268)->field0 = 0; + return tailift_1268; +} +CursorTy _copy_without_ptrs_Map_v_420(CursorTy arg_723_873_1155) +{ + TagTyPacked tag_1269 = *(TagTyPacked *) arg_723_873_1155; + CursorTy tail_1270 = arg_723_873_1155 + sizeof(IntTy); + + + switch_1273: + ; + switch (tag_1269) { + + case 0: + { + PtrTy tailift_1271 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) tailift_1271)->field0 = 0; + return tailift_1271; + break; + } + + case 1: + { + IntTy x_724_874_1156 = + ((Int64Int64VectorCursorCursorProd *) tail_1270)->field0; + IntTy x_725_875_1157 = + ((Int64Int64VectorCursorCursorProd *) tail_1270)->field1; + VectorTy *x_726_876_1158 = + ((Int64Int64VectorCursorCursorProd *) tail_1270)->field2; + CursorTy x_727_877_1159 = + ((Int64Int64VectorCursorCursorProd *) tail_1270)->field3; + CursorTy x_728_878_1160 = + ((Int64Int64VectorCursorCursorProd *) tail_1270)->field4; + CursorTy y_732_882_1164 = + _copy_without_ptrs_Map_v_420(x_727_877_1159); + CursorTy y_733_883_1165 = + _copy_without_ptrs_Map_v_420(x_728_878_1160); + PtrTy tailift_1272 = + ALLOC(sizeof(Int64Int64Int64VectorCursorCursorProd)); + + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1272)->field0 = + 1; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1272)->field1 = + x_724_874_1156; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1272)->field2 = + x_725_875_1157; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1272)->field3 = + x_726_876_1158; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1272)->field4 = + y_732_882_1164; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1272)->field5 = + y_733_883_1165; + return tailift_1272; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1269"); + exit(1); + } + } +} +CursorTy _copy_Map_v_420(CursorTy arg_712_884_1166) +{ + TagTyPacked tag_1274 = *(TagTyPacked *) arg_712_884_1166; + CursorTy tail_1275 = arg_712_884_1166 + sizeof(IntTy); + + + switch_1278: + ; + switch (tag_1274) { + + case 0: + { + PtrTy tailift_1276 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) tailift_1276)->field0 = 0; + return tailift_1276; + break; + } + + case 1: + { + IntTy x_713_885_1167 = + ((Int64Int64VectorCursorCursorProd *) tail_1275)->field0; + IntTy x_714_886_1168 = + ((Int64Int64VectorCursorCursorProd *) tail_1275)->field1; + VectorTy *x_715_887_1169 = + ((Int64Int64VectorCursorCursorProd *) tail_1275)->field2; + CursorTy x_716_888_1170 = + ((Int64Int64VectorCursorCursorProd *) tail_1275)->field3; + CursorTy x_717_889_1171 = + ((Int64Int64VectorCursorCursorProd *) tail_1275)->field4; + CursorTy y_721_893_1175 = _copy_Map_v_420(x_716_888_1170); + CursorTy y_722_894_1176 = _copy_Map_v_420(x_717_889_1171); + PtrTy tailift_1277 = + ALLOC(sizeof(Int64Int64Int64VectorCursorCursorProd)); + + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1277)->field0 = + 1; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1277)->field1 = + x_713_885_1167; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1277)->field2 = + x_714_886_1168; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1277)->field3 = + x_715_887_1169; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1277)->field4 = + y_721_893_1175; + ((Int64Int64Int64VectorCursorCursorProd *) tailift_1277)->field5 = + y_722_894_1176; + return tailift_1277; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1274"); + exit(1); + } + } +} +unsigned char _traverse_Map_v_420(CursorTy arg_734_895_1177) +{ + TagTyPacked tag_1279 = *(TagTyPacked *) arg_734_895_1177; + CursorTy tail_1280 = arg_734_895_1177 + sizeof(IntTy); + + + switch_1281: + ; + switch (tag_1279) { + + case 0: + { + return 0; + break; + } + + case 1: + { + IntTy x_735_896_1178 = + ((Int64Int64VectorCursorCursorProd *) tail_1280)->field0; + IntTy x_736_897_1179 = + ((Int64Int64VectorCursorCursorProd *) tail_1280)->field1; + VectorTy *x_737_898_1180 = + ((Int64Int64VectorCursorCursorProd *) tail_1280)->field2; + CursorTy x_738_899_1181 = + ((Int64Int64VectorCursorCursorProd *) tail_1280)->field3; + CursorTy x_739_900_1182 = + ((Int64Int64VectorCursorCursorProd *) tail_1280)->field4; + unsigned char y_743_901_1183 = _traverse_Map_v_420(x_738_899_1181); + unsigned char y_744_902_1184 = _traverse_Map_v_420(x_739_900_1182); + + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1279"); + exit(1); + } + } +} +unsigned char _print_Map_v_420(CursorTy arg_745_903_1185) +{ + TagTyPacked tag_1282 = *(TagTyPacked *) arg_745_903_1185; + CursorTy tail_1283 = arg_745_903_1185 + sizeof(IntTy); + + + switch_1284: + ; + switch (tag_1282) { + + case 0: + { + unsigned char wildcard_746_904_1186 = print_symbol(1236); + unsigned char wildcard_747_905_1187 = print_symbol(1235); + + return 0; + break; + } + + case 1: + { + IntTy x_748_906_1188 = + ((Int64Int64VectorCursorCursorProd *) tail_1283)->field0; + IntTy x_749_907_1189 = + ((Int64Int64VectorCursorCursorProd *) tail_1283)->field1; + VectorTy *x_750_908_1190 = + ((Int64Int64VectorCursorCursorProd *) tail_1283)->field2; + CursorTy x_751_909_1191 = + ((Int64Int64VectorCursorCursorProd *) tail_1283)->field3; + CursorTy x_752_910_1192 = + ((Int64Int64VectorCursorCursorProd *) tail_1283)->field4; + unsigned char wildcard_758_911_1193 = print_symbol(1237); + unsigned char wildcard_764_912_1194 = print_symbol(1238); + unsigned char y_753_913_1195 = printf("%lld", x_748_906_1188); + unsigned char wildcard_763_914_1196 = print_symbol(1238); + unsigned char y_754_915_1197 = printf("%lld", x_749_907_1189); + unsigned char wildcard_762_916_1198 = print_symbol(1238); + unsigned char y_755_917_1199 = print_symbol(1234); + unsigned char wildcard_761_918_1200 = print_symbol(1238); + unsigned char y_756_919_1201 = _print_Map_v_420(x_751_909_1191); + unsigned char wildcard_760_920_1202 = print_symbol(1238); + unsigned char y_757_921_1203 = _print_Map_v_420(x_752_910_1192); + unsigned char wildcard_759_922_1204 = print_symbol(1235); + + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1282"); + exit(1); + } + } +} +CursorTy caseFn_765(VectorTy *x1_186_766_923_1205, IntTy k1_185_767_924_1206, + CursorTy t1_187_768_925_1207, CursorTy m1_193_769_926_1208, + IntTy k2_191_770_927_1209, VectorTy *x2_192_771_928_1210, + CursorTy t4_194_772_929_1211) +{ + TagTyPacked tag_1285 = *(TagTyPacked *) m1_193_769_926_1208; + CursorTy tail_1286 = m1_193_769_926_1208 + sizeof(IntTy); + + + switch_1287: + ; + switch (tag_1285) { + + case 1: + { + IntTy wildcard__110_195_930_1212 = + ((Int64Int64VectorCursorCursorProd *) tail_1286)->field0; + IntTy k3_196_931_1213 = + ((Int64Int64VectorCursorCursorProd *) tail_1286)->field1; + VectorTy *x3_197_932_1214 = + ((Int64Int64VectorCursorCursorProd *) tail_1286)->field2; + CursorTy t2_198_933_1215 = + ((Int64Int64VectorCursorCursorProd *) tail_1286)->field3; + CursorTy t3_199_934_1216 = + ((Int64Int64VectorCursorCursorProd *) tail_1286)->field4; + CursorTy fltAppE_1003_1217 = + bin_428(k1_185_767_924_1206, x1_186_766_923_1205, t1_187_768_925_1207, t2_198_933_1215); + CursorTy fltAppE_1004_1218 = + bin_428(k2_191_770_927_1209, x2_192_771_928_1210, t3_199_934_1216, t4_194_772_929_1211); + + return bin_428(k3_196_931_1213, x3_197_932_1214, fltAppE_1003_1217, + fltAppE_1004_1218); + break; + } + + case 0: + { + return empty_418(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1285"); + exit(1); + } + } +} +CursorTy caseFn_773(VectorTy *x1_171_774_935_1219, IntTy k1_170_775_936_1220, + CursorTy t4_173_776_937_1221, CursorTy m1_179_777_938_1222, + IntTy k2_176_778_939_1223, VectorTy *x2_177_779_940_1224, + CursorTy t1_178_780_941_1225) +{ + TagTyPacked tag_1288 = *(TagTyPacked *) m1_179_777_938_1222; + CursorTy tail_1289 = m1_179_777_938_1222 + sizeof(IntTy); + + + switch_1290: + ; + switch (tag_1288) { + + case 1: + { + IntTy wildcard__134_180_942_1226 = + ((Int64Int64VectorCursorCursorProd *) tail_1289)->field0; + IntTy k3_181_943_1227 = + ((Int64Int64VectorCursorCursorProd *) tail_1289)->field1; + VectorTy *x3_182_944_1228 = + ((Int64Int64VectorCursorCursorProd *) tail_1289)->field2; + CursorTy t2_183_945_1229 = + ((Int64Int64VectorCursorCursorProd *) tail_1289)->field3; + CursorTy t3_184_946_1230 = + ((Int64Int64VectorCursorCursorProd *) tail_1289)->field4; + CursorTy fltAppE_1005_1231 = + bin_428(k2_176_778_939_1223, x2_177_779_940_1224, t1_178_780_941_1225, t2_183_945_1229); + CursorTy fltAppE_1006_1232 = + bin_428(k1_170_775_936_1220, x1_171_774_935_1219, t3_184_946_1230, t4_173_776_937_1221); + + return bin_428(k3_181_943_1227, x3_182_944_1228, fltAppE_1005_1231, + fltAppE_1006_1232); + break; + } + + case 0: + { + return empty_418(); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1288"); + exit(1); + } + } +} +int __main_expr() +{ + add_symbol(1234, "Vector"); + add_symbol(1235, ")"); + add_symbol(1236, "(Tip_v_420"); + add_symbol(1237, "(Bin_v_420"); + add_symbol(1238, " "); + + IntTy tmp_13 = sizeof(CharTy); + VectorTy *vec_145_153_781_1007 = vector_alloc(1, tmp_13); + CharTy tmp_12 = 'f'; + VectorTy *__154_782_1008 = vector_inplace_update(vec_145_153_781_1007, 0, + &tmp_12); + IntTy tmp_11 = sizeof(CharTy); + VectorTy *vec_146_155_783_1010 = vector_alloc(1, tmp_11); + CharTy tmp_10 = 'f'; + VectorTy *__156_784_1011 = vector_inplace_update(vec_146_155_783_1010, 0, + &tmp_10); + IntTy tmp_9 = sizeof(CharTy); + VectorTy *vec_147_157_785_1013 = vector_alloc(1, tmp_9); + CharTy tmp_8 = 'e'; + VectorTy *__158_786_1014 = vector_inplace_update(vec_147_157_785_1013, 0, + &tmp_8); + IntTy tmp_7 = sizeof(CharTy); + VectorTy *vec_148_159_787_1016 = vector_alloc(1, tmp_7); + CharTy tmp_6 = 'd'; + VectorTy *__160_788_1017 = vector_inplace_update(vec_148_159_787_1016, 0, + &tmp_6); + IntTy tmp_5 = sizeof(CharTy); + VectorTy *vec_149_161_789_1019 = vector_alloc(1, tmp_5); + CharTy tmp_4 = 'c'; + VectorTy *__162_790_1020 = vector_inplace_update(vec_149_161_789_1019, 0, + &tmp_4); + IntTy tmp_3 = sizeof(CharTy); + VectorTy *vec_150_163_791_1022 = vector_alloc(1, tmp_3); + CharTy tmp_2 = 'b'; + VectorTy *__164_792_1023 = vector_inplace_update(vec_150_163_791_1022, 0, + &tmp_2); + IntTy tmp_1 = sizeof(CharTy); + VectorTy *vec_151_165_793_1025 = vector_alloc(1, tmp_1); + CharTy tmp_0 = 'a'; + VectorTy *__166_794_1026 = vector_inplace_update(vec_151_165_793_1025, 0, + &tmp_0); + CursorTy fltAppE_960_1028 = empty_418(); + CursorTy fltAppE_958_1029 = + insert_419(0, vec_151_165_793_1025, fltAppE_960_1028); + CursorTy fltAppE_956_1030 = + insert_419(1, vec_150_163_791_1022, fltAppE_958_1029); + CursorTy fltAppE_954_1031 = + insert_419(2, vec_149_161_789_1019, fltAppE_956_1030); + CursorTy fltAppE_952_1032 = + insert_419(3, vec_148_159_787_1016, fltAppE_954_1031); + CursorTy fltAppE_950_1033 = + insert_419(4, vec_147_157_785_1013, fltAppE_952_1032); + CursorTy fltAppE_948_1034 = + insert_419(5, vec_146_155_783_1010, fltAppE_950_1033); + CursorTy tmp_app_1233 = + insert_419(0, vec_145_153_781_1007, fltAppE_948_1034); + + _print_Map_v_420(tmp_app_1233); + printf("\n"); + free_symtable(); + return 0; +} \ No newline at end of file diff --git a/benchmarks/modules/Map.hs b/benchmarks/modules/Map.hs new file mode 100644 index 000000000..d975d5f75 --- /dev/null +++ b/benchmarks/modules/Map.hs @@ -0,0 +1,134 @@ +{-# LANGUAGE BlockArguments #-} +{-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE DataKinds #-} + +module Map where +import Common + +type Size = Int +data Map a = Tip + | Bin Size Int a (Map a) (Map a) + +-- Construction ----------------------- + +empty :: Map a +empty = Tip + +singleton :: Int -> a -> Map a +singleton k x = Bin 1 k x Tip Tip + + +-- Query ------------------------------ + +null :: Map a -> Bool +null m = case m of + Tip -> True + Bin _ _ _ _ _ -> False + +size :: Map a -> Size +size m = case m of + Tip -> 0 + Bin sz _ _ _ _ -> sz + +lookup :: Int -> Map a -> Maybe a +lookup k m = + case m of + Tip -> Nothing + Bin _ kx v l r -> + if k < kx then lookup k l + else if k > kx then lookup k r + else Just v + +member :: Int -> Map a -> Bool +member k m = case lookup k m of + Nothing -> False + Just _ -> True + +-- Insertion -------------------------- + +insert :: Int -> a -> Map a -> Map a +insert kx x m = + case m of + Tip -> singleton kx x + Bin sz k v l r -> + if kx == k then Bin sz k x l r + else if kx <= k then + balance k v (insert kx x l) r + else + balance k v l (insert kx x r) + +delta :: Int +delta = 4 +ratio :: Int +ratio = 2 + +balance :: Int -> a -> Map a -> Map a -> Map a +balance k x l r = + if (size l) + (size r) <= 1 then Bin ((size l) + (size r)) k x l r + else if (size r) >= delta*(size l) then rotateL k x l r + else if (size l) >= delta*(size r) then rotateR k x l r + else Bin ((size l) + (size r)) k x l r + +rotateL :: Int -> b -> Map b -> Map b -> Map b +rotateL k x l r = + case r of + Bin _ _ _ ly ry -> + if (size ly) < ratio*(size ry) then singleL k x l r + else doubleL k x l r + Tip -> empty -- cry +--rotateL _ _ _ Tip = error "rotateL Tip" + +rotateR :: Int -> b -> Map b -> Map b -> Map b +rotateR k x l r = + case l of + Bin _ _ _ ly ry -> + if (size ry) < ratio*(size ly) then singleR k x l r + else doubleR k x l r + Tip -> empty --cry +--rotateR _ _ Tip _ = error "rotateR Tip" + +bin :: Int -> a -> Map a -> Map a -> Map a +bin k x l r = Bin ((size l) + (size r) + 1) k x l r + +singleL :: Int -> b -> Map b -> Map b -> Map b +singleL k1 x1 t1 m = + case m of + Bin _ k2 x2 t2 t3 -> bin k2 x2 (bin k1 x1 t1 t2) t3 + Tip -> empty --cry +--singleL :: Int -> b -> Map Int b -> Map Int b -> Map Int b +--singleL k1 x1 t1 (Bin _ k2 x2 t2 t3) = bin k2 x2 (bin k1 x1 t1 t2) t3 +--singleL _ _ _ Tip = error "singleL Tip" + +singleR :: Int -> b -> Map b -> Map b -> Map b +singleR k1 x1 m t3 = + case m of + Bin _ k2 x2 t1 t2 -> bin k2 x2 t1 (bin k1 x1 t2 t3) + Tip -> empty --cry +--singleR k1 x1 (Bin _ k2 x2 t1 t2) t3 = bin k2 x2 t1 (bin k1 x1 t2 t3) +--singleR _ _ Tip _ = error "singleR Tip" + +doubleL :: Int -> b -> Map b -> Map b -> Map b +doubleL k1 x1 t1 m0 = + case m0 of + Bin _ k2 x2 m1 t4 -> + case m1 of + Bin _ k3 x3 t2 t3 -> bin k3 x3 (bin k1 x1 t1 t2) (bin k2 x2 t3 t4) + Tip -> empty --cry + Tip _ _ _ _ -> empty --cry +--doubleL k1 x1 t1 (Bin _ k2 x2 (Bin _ k3 x3 t2 t3) t4) = bin k3 x3 (bin k1 x1 t1 t2) (bin k2 x2 t3 t4) +--doubleL _ _ _ _ = error "doubleL" + +doubleR :: Int -> b -> Map b -> Map b -> Map b +doubleR k1 x1 m0 t4 = + case m0 of + Bin _ k2 x2 t1 m1 -> + case m1 of + Bin _ k3 x3 t2 t3 -> bin k3 x3 (bin k2 x2 t1 t2) (bin k1 x1 t3 t4) + Tip -> empty + Tip -> empty --cry +--doubleR k1 x1 (Bin _ k2 x2 t1 (Bin _ k3 x3 t2 t3)) t4 = bin k3 x3 (bin k2 x2 t1 t2) (bin k1 x1 t3 t4) +--doubleR _ _ _ _ = error "doubleR" + +--gibbon_main = insert 0 'a' empty + +gibbon_main = insert 0 "f" (insert 5 "f" (insert 4 "e" (insert 3 "d" (insert 2 "c" (insert 1 "b" (insert 0 "a" empty)))))) \ No newline at end of file diff --git a/benchmarks/modules/Set.c b/benchmarks/modules/Set.c new file mode 100644 index 000000000..e325bcda5 --- /dev/null +++ b/benchmarks/modules/Set.c @@ -0,0 +1,3105 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// #include +#ifdef _WIN64 +#include +#endif +#include +#include +#include // For va_start etc +#include +#include +#include +#include +#ifdef _POINTER +#include +#endif +#ifdef _PARALLEL +#include +#include +#endif + +#define KB 1024lu +#define MB (KB * 1000lu) +#define GB (MB * 1000lu) + +#define REDIRECTION_TAG 255 +#define INDIRECTION_TAG 254 + +// Initial size of BigInfinite buffers +static long long global_init_biginf_buf_size = (4 * GB); + +// Initial size of Infinite buffers +static long long global_init_inf_buf_size = 1 * KB; + +// Maximum size of a chunk, see GitHub #110. +static long long global_inf_buf_max_chunk_size = 1 * GB; + +static long long global_size_param = 1; +static long long global_iters_param = 1; + +static char* global_benchfile_param = NULL; +static char* global_arrayfile_param = NULL; +// Number of lines in the arrayfile +static long long global_arrayfile_length_param = -1; + +// Sequential for now: +static const int num_workers = 1; + +// Count the number of regions allocated. +static long long global_region_count = 0; +static bool global_region_count_flag = false; + +#ifdef _PARALLEL +static inline void bump_global_region_count() { + __atomic_add_fetch(&global_region_count, 1, __ATOMIC_SEQ_CST); + return; +} +#else +static inline void bump_global_region_count() { + global_region_count++; + return; +} +#endif + +static inline void print_global_region_count() { + printf("REGION_COUNT: %lld\n", global_region_count); + return; +} + +#define REDIRECTION_NODE_SIZE 9 +#define MAX(a,b) (((a)>(b))?(a):(b)) +#define MIN(a,b) (((a)<(b))?(a):(b)) + +// https://www.cprogramming.com/snippets/source-code/find-the-number-of-cpu-cores-for-windows-mac-or-linux +static int get_num_processors() { +#ifdef _WIN64 + SYSTEM_INFO sysinfo; + GetSystemInfo(&sysinfo); + return sysinfo.dwNumberOfProcessors; +#else + return sysconf(_SC_NPROCESSORS_ONLN); +#endif +} + +// Requires -std=gnu11 +int dbgprintf(const char *format, ...) { + int code = 0; + va_list args; + va_start(args, format); +#ifdef _DEBUG + code = vprintf(format, args); +#endif + va_end(args); + return code; +} + + +// ----------------------------------------------------------------------------- +// Allocators +// ----------------------------------------------------------------------------- + + +// ------------------------------------- +// Bump allocation for linked-lists +// ------------------------------------- + + +#ifdef _BUMPALLOC +// #define _DEBUG +#warning "Using bump allocator." + +__thread char* bumpalloc_heap_ptr = (char*)NULL; +__thread char* bumpalloc_heap_ptr_end = (char*)NULL; + +char* saved_heap_ptr_stack[100]; +int num_saved_heap_ptr = 0; + +// For simplicity just use a single large slab: +static inline void INITBUMPALLOC() { + bumpalloc_heap_ptr = (char*)malloc(global_init_biginf_buf_size); + bumpalloc_heap_ptr_end = bumpalloc_heap_ptr + global_init_biginf_buf_size; +#ifdef _DEBUG + printf("Arena size for bump alloc: %lld\n", global_init_biginf_buf_size); + printf("BUMPALLOC/INITBUMPALLOC DONE: heap_ptr = %p\n", bumpalloc_heap_ptr); +#endif +} + +static inline void* BUMPALLOC(long long n) { + if (! bumpalloc_heap_ptr) { + INITBUMPALLOC(); + } + if (bumpalloc_heap_ptr + n < bumpalloc_heap_ptr_end) { + char* old= bumpalloc_heap_ptr; + bumpalloc_heap_ptr += n; + return old; + } else { + fprintf(stderr, "Warning: bump allocator ran out of memory."); + exit(1); + } +} + +// Snapshot the current heap pointer value across all threads. +void save_alloc_state() { + dbgprintf("Saving(%p): pos %d", heap_ptr, num_saved_heap_ptr); + saved_heap_ptr_stack[num_saved_heap_ptr] = heap_ptr; + num_saved_heap_ptr++; + dbgprintf("\n"); +} + +void restore_alloc_state() { + if(num_saved_heap_ptr <= 0) { + fprintf(stderr, "Bad call to restore_alloc_state! Saved stack empty!\ne"); + exit(1); + } + num_saved_heap_ptr--; + dbgprintf("Restoring(%p): pos %d, discarding %p", + saved_heap_ptr_stack[num_saved_heap_ptr], num_saved_heap_ptr, bumpalloc_heap_ptr); + bumpalloc_heap_ptr = saved_heap_ptr_stack[num_saved_heap_ptr]; +} + + +#else +// Regular malloc mode: +void INITBUMPALLOC() {} +void save_alloc_state() {} +void restore_alloc_state() {} + +#define BUMPALLOC(n) malloc(n) + +#endif // BUMPALLOC + + +// ------------------------------------- +// ALLOC and ALLOC_PACKED macros +// ------------------------------------- + + +/* + +If parallelism is enabled, we always use a malloc based allocator +since Boehm GC is not thread-safe in its default configuration. It can be +made thread-safe by building it with appropriate flags, but we don't do that. +Presently, all parallel pointer-based programs will leak memory. + +*/ + +#ifdef _PARALLEL +#define ALLOC(n) malloc(n) +#define ALLOC_PACKED_BIG(n) malloc(n) +char *ALLOC_COUNTED(size_t size) { + bump_global_region_count(); + return ALLOC(size); +} +#else + #ifdef _POINTER +#define ALLOC(n) GC_MALLOC(n) +#define ALLOC_PACKED_BIG(n) GC_MALLOC(n) +char *ALLOC_COUNTED(size_t size) { + bump_global_region_count(); + return GC_MALLOC(size); +} + #else +#define ALLOC(n) malloc(n) +#define ALLOC_PACKED_BIG(n) malloc(n) +char *ALLOC_COUNTED(size_t size) { + bump_global_region_count(); + return ALLOC(size); +} + #endif // _POINTER +#endif // _PARALLEL + + +// Could try alloca() here. Better yet, we could keep our own, +// separate stack and insert our own code to restore the pointer +// before any function that (may have) called ALLOC_SCOPED returns. + +// #define ALLOC_SCOPED() alloca(1024) +#define ALLOC_SCOPED(n) alloca(n) +// #define ALLOC_SCOPED() alloc_scoped() + +// Stack allocation is either too small or blows our stack. +// We need a way to make a giant stack if we want to use alloca. +// #define ALLOC_SCOPED() ALLOC(global_init_biginf_buf_size) + +// Our global pointer. No parallelism. +// static char* stack_scoped_region; +// char* alloc_scoped() { return stack_scoped_region; } + + + +// ------------------------------------- +// Basic types +// ------------------------------------- + +// Must be consistent with sizeOfTy defined in Gibbon.Language.Syntax. + +typedef unsigned char TagTyPacked; +typedef unsigned char TagTyBoxed; +typedef long long IntTy; +typedef char CharTy; +typedef float FloatTy; +typedef unsigned long long SymTy; +typedef bool BoolTy; +typedef char* PtrTy; +typedef char* CursorTy; + +// ------------------------------------- +// Arenas and dictionaries +// ------------------------------------- + +typedef struct mem_arena { + int ind; + char* mem; // TODO(vollmerm): make this a list of chunks? + void* reflist; +} mem_arena_t; + +typedef mem_arena_t* ArenaTy; + +ArenaTy alloc_arena() { + ArenaTy ar = ALLOC(sizeof(mem_arena_t)); + ar->ind = 0; + ar->mem = malloc(global_inf_buf_max_chunk_size); + ar->reflist = 0; + return ar; +} + +void free_arena(ArenaTy ar) { + free(ar->mem); + // TODO(vollmerm): free everything in ar->reflist + free(ar); +} + +CursorTy extend_arena(ArenaTy ar, int size) { + CursorTy ret = ar->mem + ar->ind; + ar->ind += size; + return ret; +} + +typedef struct dict_item { + struct dict_item * next; + int key; + void * ptrval; +} dict_item_t; + +dict_item_t * dict_alloc(ArenaTy ar) { + return (dict_item_t *) extend_arena(ar, sizeof(dict_item_t)); // ALLOC(sizeof(dict_item_t)); +} + +dict_item_t *dict_insert_ptr(ArenaTy ar, dict_item_t *ptr, SymTy key, PtrTy val) { + dict_item_t *ret = dict_alloc(ar); + ret->key = key; + ret->ptrval = val; + ret->next = ptr; + return ret; +} + +PtrTy dict_lookup_ptr(dict_item_t *ptr, SymTy key) { + while (ptr != 0) { + if (ptr->key == key) { + return ptr->ptrval; + } else { + ptr = ptr->next; + } + } + printf("Error, key %lld not found!\n",key); + exit(1); +} + +// ------------------------------------- +// Sets +// ------------------------------------- + + +struct set_elem { + int val; + UT_hash_handle hh; +}; + +typedef struct set_elem* SymSetTy; + +SymSetTy empty_set() { + return NULL; +} + +SymSetTy insert_set(SymSetTy set, int sym) { + SymSetTy s; + HASH_FIND_INT(set, &sym, s); /* sym already in the hash? */ + if (s==NULL) { + s = malloc(sizeof(struct set_elem)); + s->val = sym; + HASH_ADD_INT(set,val,s); + } + return set; +} + +BoolTy contains_set(SymSetTy set, int sym) { + SymSetTy s; + HASH_FIND_INT(set, &sym, s); + return (s!=NULL); +} + +// ------------------------------------- +// Sym Hash +// ------------------------------------- + +struct sym_hash_elem { + int key; + int val; + UT_hash_handle hh; +}; + +typedef struct sym_hash_elem* SymHashTy; + +typedef struct sym_hash_elem* IntHashTy; + +SymHashTy empty_hash() { + return NULL; +} + +SymHashTy insert_hash(SymHashTy hash, int k, int v) { + SymHashTy s; + // NOTE: not checking for duplicates! + // s = malloc(sizeof(struct sym_hash_elem)); + s = ALLOC(sizeof(struct sym_hash_elem)); + s->val = v; + s->key = k; + HASH_ADD_INT(hash,key,s); + + return hash; +} + +IntTy lookup_hash(SymHashTy hash, int k) { + SymHashTy s; + HASH_FIND_INT(hash,&k,s); + if (s==NULL) { + return k; // NOTE: return original key if val not found + // TODO(vollmerm): come up with something better to do here + } else { + return s->val; + } +} + +BoolTy contains_hash(SymHashTy hash, int sym) { + SymHashTy s; + HASH_FIND_INT(hash,&sym,s); + return (s!=NULL); +} + +// ------------------------------------- +// Helpers +// ------------------------------------- + +char* read_benchfile_param() { + if (global_benchfile_param == NULL) { + fprintf(stderr, "read_benchfile_param: benchmark input file was not set! Set using --bench-input.\n"); + exit(1); + } else + return global_benchfile_param; +} + +char* read_arrayfile_param() { + if (global_arrayfile_param == NULL) { + fprintf(stderr, "read_arrayfile_param: array input file was not set! Set using --array-input.\n"); + exit(1); + } else + return global_arrayfile_param; +} + +IntTy read_arrayfile_length_param() { + if (global_arrayfile_length_param == -1) { + fprintf(stderr, "read_arrayfile_length_param: array input file length was not set! Set using --array-input-length.\n"); + exit(1); + } else + return global_arrayfile_length_param; +} + + +// fun fact: __ prefix is actually reserved and this is an undefined behavior. +// These functions must be provided by the code generator. +int __main_expr(); + + +void show_usage(char** argv) +{ + printf("\n"); + printf("This binary was generated by the Gibbon compiler.\n"); + printf("\n"); + printf("Usage: %s [OPTS] [size] [iters]\n", argv[0]); + + printf("\n"); + printf("Options:\n"); + printf(" --buffer-size Set the buffer size (default %lld).\n", global_init_biginf_buf_size); + printf(" --bench-input Set the input file read for benchmarking. Applies only\n"); + printf(" IF the program was *compiled* with --bench-fun. \n"); + return; +} + +double avg(const double* arr, int n) +{ + double sum = 0.0; + for(int i=0; itv_sec - t0->tv_sec) + + ((double)(t1->tv_nsec - t0->tv_nsec) / 1000000000.0); +} + +int compare_doubles(const void *a, const void *b) +{ + const double *da = (const double *) a; + const double *db = (const double *) b; + return (*da > *db) - (*da < *db); +} + +// Exponentiation +IntTy expll(IntTy base, IntTy pow) { + if (base == 2) { + return (1 << pow); + } else { + IntTy i, result = 1; + for (i = 0; i < pow; i++) + result *= base; + return result; + } + } + +// ------------------------------------- +// Symbol table +// ------------------------------------- + +#define global_max_symbol_len 256 + +// Invariant: should always be equal to max(sym_table_keys) +static SymTy global_gensym_counter = 0; + +// Its value is updated by the flags parser. +static char *global_bench_prog_param; + +static SymTy newline_symbol = -1; +static SymTy space_symbol = -1; +static SymTy comma_symbol = -1; +static SymTy leftparen_symbol = -1; +static SymTy rightparen_symbol = -1; + +typedef struct SymTable_elem { + SymTy idx; /* key */ + char value[global_max_symbol_len]; + UT_hash_handle hh; /* makes this structure hashable */ +} SymTable_elem; + +// important! initialize to NULL +SymTable_elem *global_sym_table = NULL; + +void add_symbol(SymTy idx, char *value) { + struct SymTable_elem *s; + s = ALLOC(sizeof(struct SymTable_elem)); + s->idx = idx; + strcpy(s->value, value); + HASH_ADD(hh, global_sym_table, idx, sizeof(IntTy), s); + if (idx > global_gensym_counter) { + global_gensym_counter = idx; + } +} + +void set_newline(SymTy idx) { + newline_symbol = idx; + add_symbol(idx,"NEWLINE"); +} + +void set_space(SymTy idx) { + space_symbol = idx; + add_symbol(idx,"SPACE"); +} + +void set_comma(SymTy idx) { + comma_symbol = idx; + add_symbol(idx,"COMMA"); +} + +void set_leftparen(SymTy idx) { + leftparen_symbol = idx; + add_symbol(idx,"LEFTPAREN"); +} + +void set_rightparen(SymTy idx) { + rightparen_symbol = idx; + add_symbol(idx,"RIGHTPAREN"); +} + +IntTy print_symbol(SymTy idx) { + if (idx == comma_symbol) { + return printf(","); + } else if (idx == newline_symbol) { + return printf("\n"); + } else if (idx == space_symbol) { + return printf(" "); + } else if (idx == leftparen_symbol) { + return printf("("); + } else if (idx == rightparen_symbol) { + return printf(")"); + } else { + struct SymTable_elem *s; + HASH_FIND(hh, global_sym_table, &idx, sizeof(SymTy), s); + if (s == NULL) { + return printf("%lld", idx); + } else { + return printf("%s", s->value); + } + + } +} + +#ifdef _PARALLEL +SymTy gensym() { + SymTy idx = __atomic_add_fetch(&global_gensym_counter, 1, __ATOMIC_SEQ_CST); + return idx; +} +#else +SymTy gensym() { + global_gensym_counter += 1; + SymTy idx = global_gensym_counter; + return idx; +} +#endif + +void free_symtable() { + struct SymTable_elem *elt, *tmp; + HASH_ITER(hh, global_sym_table, elt, tmp) { + HASH_DEL(global_sym_table,elt); + } + free(elt); + free(tmp); +} + +/* + +---------------------------------------- +Garbage collection +---------------------------------------- + + Gibbon has "growing regions" i.e each logical region is backed by a doubly linked-list + of smaller chunks which grows as required. In addition to actual data, each chunk + stores some additional metadata (RegionFooter) to chain the chunks together in a list + and for garbage collection. The footer: + + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + serialized data | rf_reg_metadata_ptr | rf_seq_no | rf_size | rf_next | rf_prev + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + The metadata after the serialized data serves various purposes: + + - rf_reg_metadata_ptr: A pointer to a RegionTy struct that contains various metadata. + Of particular interest to us are the fields: + + = reg_id: A unique identifier for a region. + + = refcount and outset: Whenever an inter-region indirection is created, we record that information + using these two fields. Suppose we have an indirection from region A that points to some chunk + in region B. Then A's outset will store a pointer to that chunk's footer, and B's refcount will + be bumped by 1. Note that all there's only 1 refcount cell, and 1 outset per logical region, + and chunks only store a pointer to them. + + - rf_seq_no: The index of this particular chunk in the list. + + - rf_size: Used during bounds checking to calculate the size of the next region in + the linked list. + + - rf_next / rf_prev: Point to the next and previous chunk respectively. + + +There are two ways in which a region may be freed: + +(1) Whenever it goes out of scope + + The RTS tries to free a region whenever it goes out of scope. But this doesn't always succeed as + regions sometimes contain values that "escape". One reason why this'll happen is if there's an + indirection from A->B, and A lives longer than B. + In such a case, when B goes out of scope it's refcount won't be 0, and the RTS won't free it. + This brings us to (2). + +(2) + + When the RTS successfully frees a region, it decrements the refcounts of all the regions it + points to (via the outset). At the same time, if it encounters a region in the outset whoose + refcount becomes 0 after the decrement, it calls free_region on that. This way we can be sure + that all regions will eventually be garbage collected before the program exits. + + + +Why is it a doubly linked-list? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Due to way that bounds-checking works, the pointers in the outset may actually point to any +arbitrary chunk in the chain. However, we must call free_region on the first one to ensure that +all of them are GC'd. So we need pointers to traverse backward get to the first one. +'trav_to_first_chunk' accomplishes this. + + */ + +#define MAX_OUTSET_LENGTH 10 + +typedef struct RegionTy_struct { + SymTy reg_id; + uint reg_refcount; + CursorTy reg_heap; + uint reg_outset_len; + CursorTy reg_outset[MAX_OUTSET_LENGTH]; +} RegionTy; + +typedef struct RegionFooter_struct { + RegionTy *rf_reg_metadata_ptr; + + IntTy rf_seq_no; + IntTy rf_size; + struct RegionFooter_struct *rf_next; + struct RegionFooter_struct *rf_prev; +} RegionFooter; + +typedef struct ChunkTy_struct { + CursorTy chunk_start; + CursorTy chunk_end; +} ChunkTy; + +static inline void insert_into_outset(CursorTy ptr, RegionTy *reg) { + uint outset_len = reg->reg_outset_len; + // Check for duplicates. + for (uint i = 0; i < outset_len; i++) { + if (ptr == reg->reg_outset[i]) { + return; + } + } + // Otherwise, insert into the outset. + reg->reg_outset[outset_len] = ptr; + reg->reg_outset_len = outset_len + 1; + return; +} + +static inline void remove_from_outset(CursorTy ptr, RegionTy *reg) { + uint outset_len = reg->reg_outset_len; + CursorTy *outset = reg->reg_outset; + int i; + if (outset_len == 0) { + fprintf(stderr, "remove_from_outset: empty outset\n"); + exit(1); + } + // Position of 'ptr' in the outset. + int elt_idx = -1; + for (i = 0; i < outset_len; i++) { + if (ptr == outset[i]) { + elt_idx = i; + } + } + if (elt_idx == -1) { + fprintf(stderr, "remove_from_outset: element not found\n"); + exit(1); + } + // Move all elements ahead of 'elt_idx' back by one position. + for (i = elt_idx; i < outset_len; i++) { + outset[i] = outset[i+1]; + } + return; +} + +RegionTy *alloc_region(IntTy size) { + // Allocate the region metadata. + RegionTy *reg = ALLOC(sizeof(RegionTy)); + if (reg == NULL) { + printf("alloc_region: allocation failed: %ld", sizeof(RegionTy)); + exit(1); + } + + // Allocate the first chunk. + IntTy total_size = size + sizeof(RegionFooter); + CursorTy heap = ALLOC_PACKED_BIG(total_size); + if (heap == NULL) { + printf("alloc_region: malloc failed: %lld", total_size); + exit(1); + } + // Not heap+total_size, since we must keep space for the footer. + CursorTy heap_end = heap + size; + + // Initialize metadata fields. + reg->reg_id = gensym(); + reg->reg_refcount = 1; + reg->reg_heap = heap; + reg->reg_outset_len = 0; + +#ifdef _DEBUG + printf("Allocated a region(%lld): %lld bytes.\n", reg->reg_id, size); +#endif + + // Write the footer. + RegionFooter *footer = (RegionFooter *) heap_end; + footer->rf_reg_metadata_ptr = reg; + footer->rf_seq_no = 1; + footer->rf_size = size; + footer->rf_next = NULL; + footer->rf_prev = NULL; + + return reg; +} + +RegionTy *alloc_counted_region(IntTy size) { + // Bump the count. + bump_global_region_count(); + return alloc_region(size); +} + +ChunkTy alloc_chunk(CursorTy end_old_chunk) { + // Get size from current footer. + RegionFooter *footer = (RegionFooter *) end_old_chunk; + IntTy newsize = footer->rf_size * 2; + // See #110. + if (newsize > global_inf_buf_max_chunk_size) { + newsize = global_inf_buf_max_chunk_size; + } + IntTy total_size = newsize + sizeof(RegionFooter); + + // Allocate. + CursorTy start = ALLOC_PACKED_BIG(total_size); + if (start == NULL) { + printf("alloc_chunk: malloc failed: %lld", total_size); + exit(1); + } + CursorTy end = start + newsize; + + // Link the next chunk's footer. + footer->rf_next = (RegionFooter *) end; + + // Write the footer. + RegionFooter* new_footer = (RegionFooter *) end; + new_footer->rf_reg_metadata_ptr = footer->rf_reg_metadata_ptr; + new_footer->rf_seq_no = footer->rf_seq_no + 1; + new_footer->rf_size = newsize; + new_footer->rf_next = NULL; + new_footer->rf_prev = footer; + +#ifdef _DEBUG + RegionTy *reg = (RegionTy*) new_footer->rf_reg_metadata_ptr; + printf("alloc_chunk: allocated %lld bytes for region %lld.\n", total_size, reg->reg_id); +#endif + + return (ChunkTy) {start , end}; +} + +RegionFooter* trav_to_first_chunk(RegionFooter *footer) { + if (footer->rf_seq_no == 1) { + return footer; + } else if (footer->rf_prev == NULL) { + fprintf(stderr, "No previous chunk found at rf_seq_no: %lld", footer->rf_seq_no); + return NULL; + } else { + trav_to_first_chunk((RegionFooter *) footer->rf_prev); + } + return NULL; +} + +uint get_ref_count(CursorTy end_ptr) { + RegionFooter *footer = (RegionFooter *) end_ptr; + RegionTy *reg = (RegionTy *) footer->rf_reg_metadata_ptr; + return reg->reg_refcount; +} + +// B is the pointer, and A is the pointee (i.e B -> A). +// Bump A's refcount and update B's outset. +static inline void bump_ref_count(CursorTy end_b, CursorTy end_a) { + // Grab footers. + RegionFooter *footer_a = (RegionFooter *) end_a; + RegionFooter *footer_b = (RegionFooter *) end_b; + + // Grab metadata. + RegionTy *reg_a = (RegionTy *) footer_a->rf_reg_metadata_ptr; + RegionTy *reg_b = (RegionTy *) footer_b->rf_reg_metadata_ptr; + + // Bump A's refcount. + uint current_refcount, new_refcount; + current_refcount = reg_a->reg_refcount; + new_refcount = current_refcount + 1; + reg_a->reg_refcount = new_refcount; + +#ifdef _DEBUG + printf("bump_ref_count: %lld -> %lld\n", reg_b->reg_id, reg_a->reg_id); + printf("bump_ref_count: old-refcount=%d, old-outset-len=%d:\n", current_refcount, reg_b->reg_outset_len); + assert(current_refcount == reg_b->reg_outset_len+1); +#endif + + // Add A to B's outset. + insert_into_outset(end_a, reg_b); + +#ifdef _DEBUG + // printf("bump_ref_count: Added %p to %lld's outset, %p.\n", end_a, reg_b->reg_id, reg_b); + printf("bump_ref_count: new-refcount=%d, new-outset-len=%d\n", new_refcount, reg_b->reg_outset_len); + assert(new_refcount == reg_b->reg_outset_len+1); +#endif + + return; +} + +void free_region(CursorTy end_reg) { + // Grab footer and the metadata. + RegionFooter *footer = (RegionFooter *) end_reg; + RegionTy *reg = (RegionTy *) footer->rf_reg_metadata_ptr; + + // + RegionFooter *first_chunk_footer, *next_chunk_footer; + CursorTy first_chunk, next_chunk; + + // Decrement current reference count. + uint current_refcount, new_refcount; + current_refcount = reg->reg_refcount; + new_refcount = 0; + if (current_refcount != 0) { + new_refcount = current_refcount - 1; + reg->reg_refcount = new_refcount; + } + +#ifdef _DEBUG + printf("free_region(%lld): refcounts (1): old-refcount=%d, new-refcount=%d:\n", reg->reg_id, current_refcount, new_refcount); +#endif + + + // Free this region recount is 0. + if (new_refcount == 0) { + +#ifdef _DEBUG + printf("free_region(%lld): outset length: %d\n", reg->reg_id, reg->reg_outset_len); +#endif + + // Decrement refcounts, free regions with refcount==0 and also free + // elements of the outset. + if (reg->reg_outset_len != 0) { + uint outset_len = reg->reg_outset_len; + CursorTy *outset = reg->reg_outset; + RegionFooter *elt_footer; + RegionTy *elt_reg; + uint elt_current_refcount, elt_new_refcount; + CursorTy to_be_removed[MAX_OUTSET_LENGTH]; + uint to_be_removed_idx = 0; + for (int i = 0; i < outset_len; i++) { + elt_footer = (RegionFooter *) outset[i]; + elt_reg = (RegionTy *) elt_footer->rf_reg_metadata_ptr; +#ifdef _DEBUG + elt_current_refcount = elt_reg->reg_refcount; +#endif + elt_new_refcount = elt_current_refcount - 1; + elt_reg->reg_refcount = elt_new_refcount; +#ifdef _DEBUG + printf("free_region(%lld): old-refcount=%d, new-refcount=%d:\n", + elt_reg->reg_id, elt_current_refcount, elt_reg->reg_refcount); +#endif + if (elt_new_refcount == 0) { + // See [Why is it a doubly linked-list?] above + first_chunk_footer = trav_to_first_chunk(elt_footer); + if (first_chunk_footer != NULL) { + free_region((CursorTy) first_chunk_footer); + } + } + to_be_removed[to_be_removed_idx] = outset[i]; + to_be_removed_idx++; + } + // Remove elements from the outset. + for (uint i = 0; i < to_be_removed_idx; i++) { + remove_from_outset(to_be_removed[i], reg); + } + } + + +#ifdef _DEBUG + // Bookkeeping + IntTy num_freed_chunks = 0, total_bytesize = 0; +#endif + + // Free the chunks in this region. + first_chunk = end_reg - footer->rf_size; + first_chunk_footer = footer; + next_chunk = (char*) footer->rf_next; + +#ifdef _DEBUG + printf("free_region(%lld)\n", reg->reg_id); +#endif + +#ifdef _DEBUG + num_freed_chunks++; + total_bytesize = total_bytesize + first_chunk_footer->rf_size; +#endif + free(first_chunk); + + while (next_chunk != NULL) { + next_chunk_footer = (RegionFooter *) next_chunk; + #ifdef _DEBUG + num_freed_chunks++; + total_bytesize = total_bytesize + next_chunk_footer->rf_size; + #endif + free(next_chunk - next_chunk_footer->rf_size); + next_chunk = (char*) next_chunk_footer->rf_next; + } + +#ifdef _DEBUG + printf("free_region(%lld): Freed %lld bytes across %lld chunks.\n", + reg->reg_id, total_bytesize, num_freed_chunks); +#endif + + // Free the metadata. + free(reg); + + } else { +#ifdef _DEBUG + printf("free_region(%lld): non-zero refcount: %d.\n", + reg->reg_id, reg->reg_refcount); +#endif + } +} + +// Assume that all nodes with size information have tags >= 150. +BoolTy is_big(IntTy i, CursorTy cur) { + TagTyPacked tag = *(TagTyPacked *) cur; + if (tag >= 150) { + cur += 1; + IntTy size = *(IntTy *) cur; + if (size >= i) { + return true; + } else { + return false; + } + } + return false; +} + +// ------------------------------------- +// Vectors +// ------------------------------------- + +typedef struct VectorTy_struct { + // Bounds on the vector. + IntTy vec_lower, vec_upper; + + // Size of each element. + IntTy vec_elt_size; + + // Actual elements of the vector. + void* vec_data; +} VectorTy; + +VectorTy* vector_alloc(IntTy num, IntTy elt_size) { + VectorTy *vec = ALLOC(sizeof(VectorTy)); + if (vec == NULL) { + printf("alloc_vector: malloc failed: %ld", sizeof(VectorTy)); + exit(1); + } + void* data = ALLOC(num * elt_size); + if (data == NULL) { + printf("alloc_vector: malloc failed: %ld", sizeof(num * elt_size)); + exit(1); + } + vec->vec_lower = 0; + vec->vec_upper = num; + vec->vec_elt_size = elt_size; + vec->vec_data = data; + return vec; +} + +IntTy vector_length(VectorTy *vec) { + return (vec->vec_upper - vec->vec_lower); +} + +BoolTy vector_is_empty(VectorTy *vec) { + return (vector_length(vec) == 0); +} + +VectorTy* vector_slice(IntTy i, IntTy n, VectorTy *vec) { + IntTy lower = vec->vec_lower + i; + IntTy upper = vec->vec_lower + i + n; + if ((lower > vec->vec_upper)) { + printf("vector_slice: lower out of bounds, %lld > %lld", lower, vec->vec_upper); + exit(1); + } + if ((upper > vec->vec_upper)) { + printf("vector_slice: upper out of bounds: %lld > %lld", upper, vec->vec_upper); + exit(1); + } + VectorTy *vec2 = ALLOC(sizeof(VectorTy)); + if (vec == NULL) { + printf("vector_slice: malloc failed: %ld", sizeof(VectorTy)); + exit(1); + } + vec2->vec_lower = lower; + vec2->vec_upper = upper; + vec2->vec_elt_size = vec->vec_elt_size; + vec2->vec_data = vec->vec_data; + return vec2; +} + +// The callers must cast the return value. +static inline void* vector_nth(VectorTy *vec, IntTy i) { + // if (i < vec->lower || i > vec->upper) { + // printf("vector_nth index out of bounds: %lld (%lld,%lld) \n", i, vec->vec_lower, vec->vec_upper); + // exit(1); + // } + return (vec->vec_data + (vec->vec_elt_size * (vec->vec_lower + i))); +} + +static inline VectorTy* vector_inplace_update(VectorTy *vec, IntTy i, void* elt) { + void* dst = vector_nth(vec, i); + memcpy(dst, elt, vec->vec_elt_size); + return vec; +} + +static inline VectorTy* vector_copy(VectorTy *vec) { + IntTy len = vector_length(vec); + void *start = vector_nth(vec, 0); + VectorTy *vec2 = vector_alloc(len, vec->vec_elt_size); + memcpy(vec2->vec_data, start, len * vec->vec_elt_size); + return vec2; +} + +static inline VectorTy* vector_inplace_sort(VectorTy *vec, int (*compar)(const void *, const void*)) { + void *start = vector_nth(vec, 0); + qsort(start, vector_length(vec), vec->vec_elt_size, compar); + return vec; +} + +static inline VectorTy* vector_sort(VectorTy *vec, int (*compar)(const void *, const void*)) { + VectorTy *vec2 = vector_copy(vec); + vector_inplace_sort(vec2, compar); + return vec2; +} + +static inline VectorTy* vector_concat(VectorTy *vec) { + // Length of the input vector. + IntTy len = vector_length(vec); + // Length of the concatenated vector. + IntTy result_len = 0; + // Size of each element in the concatenated vector. + IntTy result_elt_size = 0; + VectorTy **elt_ref, *elt; + for (IntTy i = 0; i < len; i++) { + elt_ref = vector_nth(vec, i); + elt = *elt_ref; + result_elt_size = elt->vec_elt_size; + result_len += vector_length(elt); + } + + // Concatenated vector. + VectorTy *result = vector_alloc(result_len, result_elt_size); + IntTy elt_len; + // A counter that tracks the index of elements in 'result'. + IntTy k = 0; + for (IntTy i = 0; i < len; i++) { + elt_ref = vector_nth(vec, i); + elt = *elt_ref; + elt_len = vector_length(elt); + + for (IntTy j = 0; j < elt_len; j++) { + void* k_elt = vector_nth(elt, j); + vector_inplace_update(result, k, k_elt); + k++; + } + } + + return result; +} + +static inline void vector_free(VectorTy *vec) { + free(vec->vec_data); + free(vec); + return; +} + +static inline VectorTy* vector_merge(VectorTy *vec1, VectorTy *vec2) { + if (vec1->vec_upper != vec2->vec_lower) { + printf("vector_merge: non-contiguous slices, (%lld,%lld), (%lld,%lld).", + vec1->vec_lower, vec1->vec_upper, vec2->vec_lower, vec2->vec_upper); + exit(1); + } + VectorTy *merged = ALLOC(sizeof(VectorTy)); + if (merged == NULL) { + printf("vector_merge: malloc failed: %ld", sizeof(VectorTy)); + exit(1); + } + merged->vec_lower = vec1->vec_lower; + merged->vec_upper = vec2->vec_upper; + merged->vec_elt_size = vec1->vec_elt_size; + merged->vec_data = vec1->vec_data; + return merged; +} + +void print_timing_array(VectorTy *times) { + printf("TIMES: ["); + double *d; + IntTy n = vector_length(times); + for(int i = 0; i < n; i++) { + d = vector_nth(times, i); + if (i == (n-1)) { + printf("%f",*d); + } + else { + printf("%f, ",*d); + } + } + printf("]\n"); +} + +double sum_timing_array(VectorTy *times) { + double *d; + double acc = 0; + for(int i = 0; i < vector_length(times); i++) { + d = vector_nth(times, i); + acc += *d; + } + return acc; +} + +// ------------------------------------- +// Linked lists +// ------------------------------------- + +typedef struct ListTy_struct { + IntTy ll_data_size; + void* ll_data; + struct ListTy_struct* ll_next; +} ListTy; + +static inline ListTy* list_alloc(IntTy data_size) { + // ListTy *ls = ALLOC(sizeof(ListTy)); + ListTy *ls = BUMPALLOC(sizeof(ListTy)); + ls->ll_data_size = data_size; + ls->ll_data = NULL; + ls->ll_next = NULL; + return ls; +} + +static inline BoolTy list_is_empty(ListTy *ls) { + return ls->ll_next == NULL; +} + +static inline ListTy* list_cons(void* elt, ListTy *ls) { + // void* data = ALLOC(ls->data_size); + void* data = BUMPALLOC(ls->ll_data_size); + if (data == NULL) { + printf("list_cons: malloc failed: %lld", ls->ll_data_size); + exit(1); + } + memcpy(data, elt, ls->ll_data_size); + // ListTy *res = ALLOC(sizeof(ListTy)); + ListTy *res = BUMPALLOC(sizeof(ListTy)); + res->ll_data_size = ls->ll_data_size; + res->ll_data = data; + res->ll_next = (ListTy*) ls; + return res; +} + +static inline void* list_head(ListTy *ls) { + return ls->ll_data; +} + +static inline ListTy* list_tail(ListTy *ls) { + return ls->ll_next; +} + +static inline void list_free(ListTy *ls) { + free(ls->ll_data); + free(ls); + return; +} + +static inline ListTy* list_copy(ListTy *ls) { + ListTy *ls2 = list_alloc(ls->ll_data_size); + if (ls->ll_data != NULL) { + void* data = BUMPALLOC(ls->ll_data_size); + memcpy(data, ls->ll_data, ls->ll_data_size); + ls2->ll_data = data; + } + ls2->ll_next = ls->ll_next; + return ls2; +} + +// ------------------------------------- +// Ppm Images +// ------------------------------------- + +typedef struct __Pixel_struct { + IntTy field0; + IntTy field1; + IntTy field2; +} __Pixel; + +void writePpm(char* filename, IntTy width, IntTy height, VectorTy *pixels); +void writePpm_loop(FILE *fp, IntTy idx, IntTy end, VectorTy *pixels); + +// Example: writePpm("gibbon_rgb_1000.ppm", 1000, 1000, pixels); +void writePpm(char* filename, IntTy width, IntTy height, VectorTy *pixels) +{ + FILE *fp; + fp = fopen(filename, "w+"); + fprintf(fp, "P3\n"); + fprintf(fp, "%lld %lld\n255\n", width, height); + IntTy len = vector_length(pixels); + writePpm_loop(fp, 0, len, pixels); + fclose(fp); + return; +} + +void writePpm_loop(FILE *fp, IntTy idx, IntTy end, VectorTy *pixels) +{ + BoolTy fltIf_5768_6575 = idx == end; + + if (fltIf_5768_6575) { + return; + } else { + __Pixel *tmp_112; + tmp_112 = (__Pixel *) vector_nth(pixels, idx); + __Pixel tup = *tmp_112; + IntTy x = tup.field0; + IntTy y = tup.field1; + IntTy z = tup.field2; + // write to file. + fprintf(fp, "%lld %lld %lld\n", x, y, z); + writePpm_loop(fp, (idx+1), end, pixels); + } +} + +/* -------------------------------------------------------------------------------- */ + +int main(int argc, char** argv) +{ + // parameters to parse: + // + // num iterations: How many times to repeat a benchmark. + // tree size: An integer passes to `build_tree()`. + + struct rlimit lim; + int code; + if ( (code = getrlimit(RLIMIT_STACK, &lim)) ) { + fprintf(stderr, " [gibbon rts] failed to getrlimit, code %d\n", code); + exit(1); + } + + // lim.rlim_cur = 1024LU * 1024LU * 1024LU; // 1GB stack. + lim.rlim_cur = 512LU * 1024LU * 1024LU; // 500MB stack. + // lim.rlim_max = lim.rlim_cur; // Normal users may only be able to decrease this. + + // WARNING: Haven't yet figured out why this doesn't work on MacOS... +#ifndef __APPLE__ + code = setrlimit(RLIMIT_STACK, &lim); + while (code) { + fprintf(stderr, " [gibbon rts] Failed to set stack size to %llu, code %d\n", (unsigned long long)lim.rlim_cur, code); + lim.rlim_cur /= 2; + // lim.rlim_max /= 2; + if(lim.rlim_cur < 100 * 1024) { + fprintf(stderr, " [gibbon rts] Failed setrlimit stack size to something reasonable; giving up.\n"); + break; // abort(); + } + int code = setrlimit(RLIMIT_STACK, &lim); + } +#endif + + int got_numargs = 0; // How many numeric arguments have we got. + + int i; + for (i = 1; i < argc; ++i) + { + if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) { + show_usage(argv); + exit(0); + } + else if (strcmp(argv[i], "--biginf-buffer-size") == 0 && i < argc - 1) + { + global_init_biginf_buf_size = atoll(argv[i + 1]); + i++; + } + else if (strcmp(argv[i], "--inf-buffer-size") == 0 && i < argc - 1) + { + global_init_inf_buf_size = atoll(argv[i + 1]); + i++; + } + else if ((strcmp(argv[i], "--bench-input") == 0)) { + if (i+1 >= argc) { + fprintf(stderr, "Not enough arguments after --bench-input, expected .\n"); + show_usage(argv); + exit(1); + } + global_benchfile_param = argv[i+1]; + i++; + } + else if ((strcmp(argv[i], "--array-input") == 0)) { + if (i+1 >= argc) { + fprintf(stderr, "Not enough arguments after --array-input, expected .\n"); + show_usage(argv); + exit(1); + } + global_arrayfile_param = argv[i+1]; + i++; + } + else if (strcmp(argv[i], "--array-input-length") == 0 && i < argc - 1) { + global_arrayfile_length_param = atoll(argv[i+1]); + i++; + } + else if (strcmp(argv[i], "--bench-prog") == 0 && i < argc - 1) { + int len = strlen(argv[i+1]); + global_bench_prog_param = (char*) malloc((len+1)*sizeof(char)); + strncpy(global_bench_prog_param,argv[i+1],len); + i++; + } + // If present, we expect the two arguments to be + else if (got_numargs >= 2) { + fprintf(stderr, "Extra arguments left over: "); + for(; i < argc; i++) fprintf(stderr, "%s ", argv[i]); + show_usage(argv); + exit(1); + } else { + if (got_numargs == 0) { + global_size_param = atoll(argv[i]); + got_numargs ++; + } else { + global_iters_param = atoll(argv[i]); + } + } + } + + // Initialize global_bench_prog_param to an empty string in case + // the runtime argument --bench-prog isn't passed. + if (global_bench_prog_param == NULL) { + global_bench_prog_param = (char*) malloc(1*sizeof(char)); + *global_bench_prog_param = '\n'; + } + + __main_expr(); + + return 0; +} + +// ----------------------------------------------------------------------------- +// Program starts here +// ----------------------------------------------------------------------------- + +typedef struct Prod_struct { } Prod; +typedef struct Int64Prod_struct { + IntTy field0; + } Int64Prod; +typedef struct Int64Int64Int64CursorCursorProd_struct { + IntTy field0; + IntTy field1; + IntTy field2; + CursorTy field3; + CursorTy field4; + } Int64Int64Int64CursorCursorProd; +typedef struct Int64Int64CursorCursorProd_struct { + IntTy field0; + IntTy field1; + CursorTy field2; + CursorTy field3; + } Int64Int64CursorCursorProd; +typedef struct BoolProd_struct { + BoolTy field0; + } BoolProd; +typedef struct TagCursorProd_struct { + TagTyPacked field0; + CursorTy field1; + } TagCursorProd; +typedef struct CursorProd_struct { + CursorTy field0; + } CursorProd; +CursorTy empty(); +IntTy sum(CursorTy s_194_596_921); +CursorTy right(CursorTy x_201_603_929); +CursorTy left(CursorTy x_206_608_934); +IntTy val(CursorTy x_211_613_939); +IntTy size(CursorTy s_216_618_944); +CursorTy balanceR(IntTy x_232_634_949, CursorTy l_233_635_950, + CursorTy r_234_636_951); +CursorTy balanceL(IntTy x_259_641_956, CursorTy l_260_642_957, + CursorTy r_261_643_958); +CursorTy insert(IntTy x_286_648_963, CursorTy s_287_649_964); +CursorTy singleton(IntTy x_294_656_973); +CursorTy _copy_without_ptrs_IntSet(CursorTy arg_508_657_976); +CursorTy _copy_IntSet(CursorTy arg_499_666_985); +unsigned char _traverse_IntSet(CursorTy arg_517_675_994); +unsigned char _print_IntSet(CursorTy arg_526_682_1001); +CursorTy caseFn_543(IntTy x_232_544_699_1018, CursorTy rr_238_545_700_1019, + IntTy rx_236_546_701_1020, IntTy rs_235_547_702_1021, + CursorTy rl_237_548_703_1022); +CursorTy caseFn_549(IntTy x_232_550_708_1054, CursorTy r_234_551_709_1055, + IntTy rx_236_552_710_1056, CursorTy rl_237_553_711_1057); +CursorTy caseFn_554(IntTy x_232_555_716_1070, CursorTy r_234_556_717_1071, + CursorTy rr_238_557_718_1072, IntTy rx_236_558_719_1073, + IntTy rs_235_559_720_1074, CursorTy rl_237_560_721_1075); +CursorTy caseFn_561(IntTy x_232_562_726_1080, CursorTy r_234_563_727_1081); +CursorTy caseFn_564(CursorTy l_233_565_732_1088, IntTy x_232_566_733_1089, + CursorTy r_234_567_734_1090, IntTy ls_251_568_735_1091); +CursorTy caseFn_569(IntTy x_259_570_740_1128, CursorTy ll_264_571_741_1129, + IntTy lx_263_572_742_1130, IntTy ls_262_573_743_1131, + CursorTy lr_265_574_744_1132, IntTy lls_266_575_745_1133); +CursorTy caseFn_576(CursorTy l_260_577_750_1156, IntTy x_259_578_751_1157, + IntTy lx_263_579_752_1158, CursorTy lr_265_580_753_1159); +CursorTy caseFn_581(CursorTy l_260_582_758_1171, IntTy x_259_583_759_1172, + CursorTy ll_264_584_760_1173, IntTy lx_263_585_761_1174, + IntTy ls_262_586_762_1175, CursorTy lr_265_587_763_1176); +CursorTy caseFn_588(CursorTy l_260_589_768_1181, IntTy x_259_590_769_1182); +CursorTy caseFn_591(CursorTy r_261_592_774_1189, CursorTy l_260_593_775_1190, + IntTy x_259_594_776_1191, IntTy rs_278_595_777_1192); +CursorTy empty() +{ + PtrTy tailift_1234 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) tailift_1234)->field0 = 1; + return tailift_1234; +} +IntTy sum(CursorTy s_194_596_921) +{ + TagTyPacked tag_1235 = *(TagTyPacked *) s_194_596_921; + CursorTy tail_1236 = s_194_596_921 + sizeof(IntTy); + + + switch_1238: + ; + switch (tag_1235) { + + case 1: + { + return 0; + break; + } + + case 0: + { + IntTy wildcard__188_195_597_922 = + ((Int64Int64CursorCursorProd *) tail_1236)->field0; + IntTy v_196_598_923 = + ((Int64Int64CursorCursorProd *) tail_1236)->field1; + CursorTy l_197_599_924 = + ((Int64Int64CursorCursorProd *) tail_1236)->field2; + CursorTy r_198_600_925 = + ((Int64Int64CursorCursorProd *) tail_1236)->field3; + IntTy fltPrm_785_926 = sum(l_197_599_924); + IntTy fltPrm_784_927 = v_196_598_923 + fltPrm_785_926; + IntTy fltPrm_786_928 = sum(r_198_600_925); + IntTy flt_1237 = fltPrm_784_927 + fltPrm_786_928; + + return flt_1237; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1235"); + exit(1); + } + } +} +CursorTy right(CursorTy x_201_603_929) +{ + TagTyPacked tag_1239 = *(TagTyPacked *) x_201_603_929; + CursorTy tail_1240 = x_201_603_929 + sizeof(IntTy); + + + switch_1242: + ; + switch (tag_1239) { + + case 1: + { + PtrTy tailift_1241 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) tailift_1241)->field0 = 1; + return tailift_1241; + break; + } + + case 0: + { + IntTy wildcard__178_202_604_930 = + ((Int64Int64CursorCursorProd *) tail_1240)->field0; + IntTy wildcard__179_203_605_931 = + ((Int64Int64CursorCursorProd *) tail_1240)->field1; + CursorTy wildcard__180_204_606_932 = + ((Int64Int64CursorCursorProd *) tail_1240)->field2; + CursorTy r_205_607_933 = + ((Int64Int64CursorCursorProd *) tail_1240)->field3; + + return r_205_607_933; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1239"); + exit(1); + } + } +} +CursorTy left(CursorTy x_206_608_934) +{ + TagTyPacked tag_1243 = *(TagTyPacked *) x_206_608_934; + CursorTy tail_1244 = x_206_608_934 + sizeof(IntTy); + + + switch_1246: + ; + switch (tag_1243) { + + case 1: + { + PtrTy tailift_1245 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) tailift_1245)->field0 = 1; + return tailift_1245; + break; + } + + case 0: + { + IntTy wildcard__169_207_609_935 = + ((Int64Int64CursorCursorProd *) tail_1244)->field0; + IntTy wildcard__170_208_610_936 = + ((Int64Int64CursorCursorProd *) tail_1244)->field1; + CursorTy l_209_611_937 = + ((Int64Int64CursorCursorProd *) tail_1244)->field2; + CursorTy wildcard__171_210_612_938 = + ((Int64Int64CursorCursorProd *) tail_1244)->field3; + + return l_209_611_937; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1243"); + exit(1); + } + } +} +IntTy val(CursorTy x_211_613_939) +{ + TagTyPacked tag_1247 = *(TagTyPacked *) x_211_613_939; + CursorTy tail_1248 = x_211_613_939 + sizeof(IntTy); + + + switch_1249: + ; + switch (tag_1247) { + + case 1: + { + return 0; + break; + } + + case 0: + { + IntTy wildcard__160_212_614_940 = + ((Int64Int64CursorCursorProd *) tail_1248)->field0; + IntTy v_213_615_941 = + ((Int64Int64CursorCursorProd *) tail_1248)->field1; + CursorTy wildcard__161_214_616_942 = + ((Int64Int64CursorCursorProd *) tail_1248)->field2; + CursorTy wildcard__162_215_617_943 = + ((Int64Int64CursorCursorProd *) tail_1248)->field3; + + return v_213_615_941; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1247"); + exit(1); + } + } +} +IntTy size(CursorTy s_216_618_944) +{ + TagTyPacked tag_1250 = *(TagTyPacked *) s_216_618_944; + CursorTy tail_1251 = s_216_618_944 + sizeof(IntTy); + + + switch_1252: + ; + switch (tag_1250) { + + case 1: + { + return 0; + break; + } + + case 0: + { + IntTy sz_217_619_945 = + ((Int64Int64CursorCursorProd *) tail_1251)->field0; + IntTy wildcard__152_218_620_946 = + ((Int64Int64CursorCursorProd *) tail_1251)->field1; + CursorTy wildcard__153_219_621_947 = + ((Int64Int64CursorCursorProd *) tail_1251)->field2; + CursorTy wildcard__154_220_622_948 = + ((Int64Int64CursorCursorProd *) tail_1251)->field3; + + return sz_217_619_945; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1250"); + exit(1); + } + } +} +CursorTy balanceR(IntTy x_232_634_949, CursorTy l_233_635_950, + CursorTy r_234_636_951) +{ + TagTyPacked tag_1253 = *(TagTyPacked *) l_233_635_950; + CursorTy tail_1254 = l_233_635_950 + sizeof(IntTy); + + + switch_1255: + ; + switch (tag_1253) { + + case 1: + { + return caseFn_561(x_232_634_949, r_234_636_951); + break; + } + + case 0: + { + IntTy ls_251_637_952 = + ((Int64Int64CursorCursorProd *) tail_1254)->field0; + IntTy wildcard__116_252_638_953 = + ((Int64Int64CursorCursorProd *) tail_1254)->field1; + CursorTy wildcard__117_253_639_954 = + ((Int64Int64CursorCursorProd *) tail_1254)->field2; + CursorTy wildcard__118_254_640_955 = + ((Int64Int64CursorCursorProd *) tail_1254)->field3; + + return caseFn_564(l_233_635_950, x_232_634_949, r_234_636_951, + ls_251_637_952); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1253"); + exit(1); + } + } +} +CursorTy balanceL(IntTy x_259_641_956, CursorTy l_260_642_957, + CursorTy r_261_643_958) +{ + TagTyPacked tag_1256 = *(TagTyPacked *) r_261_643_958; + CursorTy tail_1257 = r_261_643_958 + sizeof(IntTy); + + + switch_1258: + ; + switch (tag_1256) { + + case 1: + { + return caseFn_588(l_260_642_957, x_259_641_956); + break; + } + + case 0: + { + IntTy rs_278_644_959 = + ((Int64Int64CursorCursorProd *) tail_1257)->field0; + IntTy wildcard__55_279_645_960 = + ((Int64Int64CursorCursorProd *) tail_1257)->field1; + CursorTy wildcard__56_280_646_961 = + ((Int64Int64CursorCursorProd *) tail_1257)->field2; + CursorTy wildcard__57_281_647_962 = + ((Int64Int64CursorCursorProd *) tail_1257)->field3; + + return caseFn_591(r_261_643_958, l_260_642_957, x_259_641_956, + rs_278_644_959); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1256"); + exit(1); + } + } +} +CursorTy insert(IntTy x_286_648_963, CursorTy s_287_649_964) +{ + TagTyPacked tag_1259 = *(TagTyPacked *) s_287_649_964; + CursorTy tail_1260 = s_287_649_964 + sizeof(IntTy); + + + switch_1261: + ; + switch (tag_1259) { + + case 1: + { + return singleton(x_286_648_963); + break; + } + + case 0: + { + IntTy sz_288_650_965 = + ((Int64Int64CursorCursorProd *) tail_1260)->field0; + IntTy v_289_651_966 = + ((Int64Int64CursorCursorProd *) tail_1260)->field1; + CursorTy l_290_652_967 = + ((Int64Int64CursorCursorProd *) tail_1260)->field2; + CursorTy r_291_653_968 = + ((Int64Int64CursorCursorProd *) tail_1260)->field3; + BoolTy fltIf_787_969 = x_286_648_963 == v_289_651_966; + + if (fltIf_787_969) { + return s_287_649_964; + } else { + BoolTy fltIf_788_970 = x_286_648_963 <= v_289_651_966; + + if (fltIf_788_970) { + CursorTy nl_292_654_971 = + insert(x_286_648_963, l_290_652_967); + + return balanceL(v_289_651_966, nl_292_654_971, + r_291_653_968); + } else { + CursorTy nr_293_655_972 = + insert(x_286_648_963, r_291_653_968); + + return balanceR(v_289_651_966, l_290_652_967, + nr_293_655_972); + } + } + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1259"); + exit(1); + } + } +} +CursorTy singleton(IntTy x_294_656_973) +{ + PtrTy fltPkd_789_974 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_789_974)->field0 = 1; + + PtrTy fltPkd_790_975 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_790_975)->field0 = 1; + + PtrTy tailift_1262 = ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1262)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1262)->field1 = 1; + ((Int64Int64Int64CursorCursorProd *) tailift_1262)->field2 = x_294_656_973; + ((Int64Int64Int64CursorCursorProd *) tailift_1262)->field3 = fltPkd_789_974; + ((Int64Int64Int64CursorCursorProd *) tailift_1262)->field4 = fltPkd_790_975; + return tailift_1262; +} +CursorTy _copy_without_ptrs_IntSet(CursorTy arg_508_657_976) +{ + TagTyPacked tag_1263 = *(TagTyPacked *) arg_508_657_976; + CursorTy tail_1264 = arg_508_657_976 + sizeof(IntTy); + + + switch_1267: + ; + switch (tag_1263) { + + case 0: + { + IntTy x_509_658_977 = + ((Int64Int64CursorCursorProd *) tail_1264)->field0; + IntTy x_510_659_978 = + ((Int64Int64CursorCursorProd *) tail_1264)->field1; + CursorTy x_511_660_979 = + ((Int64Int64CursorCursorProd *) tail_1264)->field2; + CursorTy x_512_661_980 = + ((Int64Int64CursorCursorProd *) tail_1264)->field3; + CursorTy y_515_664_983 = _copy_without_ptrs_IntSet(x_511_660_979); + CursorTy y_516_665_984 = _copy_without_ptrs_IntSet(x_512_661_980); + PtrTy tailift_1265 = ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1265)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1265)->field1 = + x_509_658_977; + ((Int64Int64Int64CursorCursorProd *) tailift_1265)->field2 = + x_510_659_978; + ((Int64Int64Int64CursorCursorProd *) tailift_1265)->field3 = + y_515_664_983; + ((Int64Int64Int64CursorCursorProd *) tailift_1265)->field4 = + y_516_665_984; + return tailift_1265; + break; + } + + case 1: + { + PtrTy tailift_1266 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) tailift_1266)->field0 = 1; + return tailift_1266; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1263"); + exit(1); + } + } +} +CursorTy _copy_IntSet(CursorTy arg_499_666_985) +{ + TagTyPacked tag_1268 = *(TagTyPacked *) arg_499_666_985; + CursorTy tail_1269 = arg_499_666_985 + sizeof(IntTy); + + + switch_1272: + ; + switch (tag_1268) { + + case 0: + { + IntTy x_500_667_986 = + ((Int64Int64CursorCursorProd *) tail_1269)->field0; + IntTy x_501_668_987 = + ((Int64Int64CursorCursorProd *) tail_1269)->field1; + CursorTy x_502_669_988 = + ((Int64Int64CursorCursorProd *) tail_1269)->field2; + CursorTy x_503_670_989 = + ((Int64Int64CursorCursorProd *) tail_1269)->field3; + CursorTy y_506_673_992 = _copy_IntSet(x_502_669_988); + CursorTy y_507_674_993 = _copy_IntSet(x_503_670_989); + PtrTy tailift_1270 = ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1270)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1270)->field1 = + x_500_667_986; + ((Int64Int64Int64CursorCursorProd *) tailift_1270)->field2 = + x_501_668_987; + ((Int64Int64Int64CursorCursorProd *) tailift_1270)->field3 = + y_506_673_992; + ((Int64Int64Int64CursorCursorProd *) tailift_1270)->field4 = + y_507_674_993; + return tailift_1270; + break; + } + + case 1: + { + PtrTy tailift_1271 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) tailift_1271)->field0 = 1; + return tailift_1271; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1268"); + exit(1); + } + } +} +unsigned char _traverse_IntSet(CursorTy arg_517_675_994) +{ + TagTyPacked tag_1273 = *(TagTyPacked *) arg_517_675_994; + CursorTy tail_1274 = arg_517_675_994 + sizeof(IntTy); + + + switch_1275: + ; + switch (tag_1273) { + + case 0: + { + IntTy x_518_676_995 = + ((Int64Int64CursorCursorProd *) tail_1274)->field0; + IntTy x_519_677_996 = + ((Int64Int64CursorCursorProd *) tail_1274)->field1; + CursorTy x_520_678_997 = + ((Int64Int64CursorCursorProd *) tail_1274)->field2; + CursorTy x_521_679_998 = + ((Int64Int64CursorCursorProd *) tail_1274)->field3; + unsigned char y_524_680_999 = _traverse_IntSet(x_520_678_997); + unsigned char y_525_681_1000 = _traverse_IntSet(x_521_679_998); + + return 0; + break; + } + + case 1: + { + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1273"); + exit(1); + } + } +} +unsigned char _print_IntSet(CursorTy arg_526_682_1001) +{ + TagTyPacked tag_1276 = *(TagTyPacked *) arg_526_682_1001; + CursorTy tail_1277 = arg_526_682_1001 + sizeof(IntTy); + + + switch_1278: + ; + switch (tag_1276) { + + case 0: + { + IntTy x_527_683_1002 = + ((Int64Int64CursorCursorProd *) tail_1277)->field0; + IntTy x_528_684_1003 = + ((Int64Int64CursorCursorProd *) tail_1277)->field1; + CursorTy x_529_685_1004 = + ((Int64Int64CursorCursorProd *) tail_1277)->field2; + CursorTy x_530_686_1005 = + ((Int64Int64CursorCursorProd *) tail_1277)->field3; + unsigned char wildcard_535_687_1006 = print_symbol(1231); + unsigned char wildcard_540_688_1007 = print_symbol(1233); + unsigned char y_531_689_1008 = printf("%lld", x_527_683_1002); + unsigned char wildcard_539_690_1009 = print_symbol(1233); + unsigned char y_532_691_1010 = printf("%lld", x_528_684_1003); + unsigned char wildcard_538_692_1011 = print_symbol(1233); + unsigned char y_533_693_1012 = _print_IntSet(x_529_685_1004); + unsigned char wildcard_537_694_1013 = print_symbol(1233); + unsigned char y_534_695_1014 = _print_IntSet(x_530_686_1005); + unsigned char wildcard_536_696_1015 = print_symbol(1230); + + return 0; + break; + } + + case 1: + { + unsigned char wildcard_541_697_1016 = print_symbol(1232); + unsigned char wildcard_542_698_1017 = print_symbol(1230); + + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1276"); + exit(1); + } + } +} +CursorTy caseFn_543(IntTy x_232_544_699_1018, CursorTy rr_238_545_700_1019, + IntTy rx_236_546_701_1020, IntTy rs_235_547_702_1021, + CursorTy rl_237_548_703_1022) +{ + TagTyPacked tag_1279 = *(TagTyPacked *) rl_237_548_703_1022; + CursorTy tail_1280 = rl_237_548_703_1022 + sizeof(IntTy); + + + switch_1284: + ; + switch (tag_1279) { + + case 0: + { + IntTy rls_243_704_1023 = + ((Int64Int64CursorCursorProd *) tail_1280)->field0; + IntTy rlx_244_705_1024 = + ((Int64Int64CursorCursorProd *) tail_1280)->field1; + CursorTy rll_245_706_1025 = + ((Int64Int64CursorCursorProd *) tail_1280)->field2; + CursorTy rlr_246_707_1026 = + ((Int64Int64CursorCursorProd *) tail_1280)->field3; + IntTy fltPrm_792_1027 = size(rl_237_548_703_1022); + IntTy fltPrm_794_1028 = size(rr_238_545_700_1019); + IntTy fltPrm_793_1029 = 2 * fltPrm_794_1028; + BoolTy fltIf_791_1030 = fltPrm_792_1027 < fltPrm_793_1029; + + if (fltIf_791_1030) { + IntTy fltPkd_795_1031 = 1 + rs_235_547_702_1021; + IntTy fltPrm_798_1032 = size(rl_237_548_703_1022); + IntTy fltPkd_797_1033 = 1 + fltPrm_798_1032; + PtrTy fltPkd_799_1034 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_799_1034)->field0 = 1; + + PtrTy fltPkd_796_1035 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) fltPkd_796_1035)->field0 = + 0; + ((Int64Int64Int64CursorCursorProd *) fltPkd_796_1035)->field1 = + fltPkd_797_1033; + ((Int64Int64Int64CursorCursorProd *) fltPkd_796_1035)->field2 = + x_232_544_699_1018; + ((Int64Int64Int64CursorCursorProd *) fltPkd_796_1035)->field3 = + fltPkd_799_1034; + ((Int64Int64Int64CursorCursorProd *) fltPkd_796_1035)->field4 = + rl_237_548_703_1022; + + PtrTy tailift_1281 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1281)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1281)->field1 = + fltPkd_795_1031; + ((Int64Int64Int64CursorCursorProd *) tailift_1281)->field2 = + rx_236_546_701_1020; + ((Int64Int64Int64CursorCursorProd *) tailift_1281)->field3 = + fltPkd_796_1035; + ((Int64Int64Int64CursorCursorProd *) tailift_1281)->field4 = + rr_238_545_700_1019; + return tailift_1281; + } else { + IntTy fltPkd_800_1036 = 1 + rs_235_547_702_1021; + IntTy fltPkd_801_1037 = val(rl_237_548_703_1022); + CursorTy fltAppE_805_1038 = left(rl_237_548_703_1022); + IntTy fltPrm_804_1039 = size(fltAppE_805_1038); + IntTy fltPkd_803_1040 = 1 + fltPrm_804_1039; + PtrTy fltPkd_806_1041 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_806_1041)->field0 = 1; + + CursorTy fltPkd_807_1042 = left(rl_237_548_703_1022); + PtrTy fltPkd_802_1043 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) fltPkd_802_1043)->field0 = + 0; + ((Int64Int64Int64CursorCursorProd *) fltPkd_802_1043)->field1 = + fltPkd_803_1040; + ((Int64Int64Int64CursorCursorProd *) fltPkd_802_1043)->field2 = + x_232_544_699_1018; + ((Int64Int64Int64CursorCursorProd *) fltPkd_802_1043)->field3 = + fltPkd_806_1041; + ((Int64Int64Int64CursorCursorProd *) fltPkd_802_1043)->field4 = + fltPkd_807_1042; + + IntTy fltPrm_811_1044 = size(rr_238_545_700_1019); + IntTy fltPrm_810_1045 = 1 + fltPrm_811_1044; + CursorTy fltAppE_813_1046 = right(rl_237_548_703_1022); + IntTy fltPrm_812_1047 = size(fltAppE_813_1046); + IntTy fltPkd_809_1048 = fltPrm_810_1045 + fltPrm_812_1047; + CursorTy fltPkd_814_1049 = right(rl_237_548_703_1022); + PtrTy fltPkd_808_1050 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) fltPkd_808_1050)->field0 = + 0; + ((Int64Int64Int64CursorCursorProd *) fltPkd_808_1050)->field1 = + fltPkd_809_1048; + ((Int64Int64Int64CursorCursorProd *) fltPkd_808_1050)->field2 = + rx_236_546_701_1020; + ((Int64Int64Int64CursorCursorProd *) fltPkd_808_1050)->field3 = + fltPkd_814_1049; + ((Int64Int64Int64CursorCursorProd *) fltPkd_808_1050)->field4 = + rr_238_545_700_1019; + + PtrTy tailift_1282 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1282)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1282)->field1 = + fltPkd_800_1036; + ((Int64Int64Int64CursorCursorProd *) tailift_1282)->field2 = + fltPkd_801_1037; + ((Int64Int64Int64CursorCursorProd *) tailift_1282)->field3 = + fltPkd_802_1043; + ((Int64Int64Int64CursorCursorProd *) tailift_1282)->field4 = + fltPkd_808_1050; + return tailift_1282; + } + break; + } + + case 1: + { + PtrTy fltPkd_816_1051 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_816_1051)->field0 = 1; + + PtrTy fltPkd_817_1052 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_817_1052)->field0 = 1; + + PtrTy fltPkd_815_1053 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) fltPkd_815_1053)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) fltPkd_815_1053)->field1 = 1; + ((Int64Int64Int64CursorCursorProd *) fltPkd_815_1053)->field2 = + x_232_544_699_1018; + ((Int64Int64Int64CursorCursorProd *) fltPkd_815_1053)->field3 = + fltPkd_816_1051; + ((Int64Int64Int64CursorCursorProd *) fltPkd_815_1053)->field4 = + fltPkd_817_1052; + + PtrTy tailift_1283 = ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1283)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1283)->field1 = 3; + ((Int64Int64Int64CursorCursorProd *) tailift_1283)->field2 = + rx_236_546_701_1020; + ((Int64Int64Int64CursorCursorProd *) tailift_1283)->field3 = + fltPkd_815_1053; + ((Int64Int64Int64CursorCursorProd *) tailift_1283)->field4 = + rr_238_545_700_1019; + return tailift_1283; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1279"); + exit(1); + } + } +} +CursorTy caseFn_549(IntTy x_232_550_708_1054, CursorTy r_234_551_709_1055, + IntTy rx_236_552_710_1056, CursorTy rl_237_553_711_1057) +{ + TagTyPacked tag_1285 = *(TagTyPacked *) rl_237_553_711_1057; + CursorTy tail_1286 = rl_237_553_711_1057 + sizeof(IntTy); + + + switch_1289: + ; + switch (tag_1285) { + + case 0: + { + IntTy rls_247_712_1058 = + ((Int64Int64CursorCursorProd *) tail_1286)->field0; + IntTy rlx_248_713_1059 = + ((Int64Int64CursorCursorProd *) tail_1286)->field1; + CursorTy rll_249_714_1060 = + ((Int64Int64CursorCursorProd *) tail_1286)->field2; + CursorTy rlr_250_715_1061 = + ((Int64Int64CursorCursorProd *) tail_1286)->field3; + IntTy fltPkd_818_1062 = val(rl_237_553_711_1057); + PtrTy fltPkd_820_1063 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_820_1063)->field0 = 1; + + PtrTy fltPkd_821_1064 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_821_1064)->field0 = 1; + + PtrTy fltPkd_819_1065 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) fltPkd_819_1065)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) fltPkd_819_1065)->field1 = 1; + ((Int64Int64Int64CursorCursorProd *) fltPkd_819_1065)->field2 = + x_232_550_708_1054; + ((Int64Int64Int64CursorCursorProd *) fltPkd_819_1065)->field3 = + fltPkd_820_1063; + ((Int64Int64Int64CursorCursorProd *) fltPkd_819_1065)->field4 = + fltPkd_821_1064; + + PtrTy fltPkd_823_1066 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_823_1066)->field0 = 1; + + PtrTy fltPkd_824_1067 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_824_1067)->field0 = 1; + + PtrTy fltPkd_822_1068 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) fltPkd_822_1068)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) fltPkd_822_1068)->field1 = 1; + ((Int64Int64Int64CursorCursorProd *) fltPkd_822_1068)->field2 = + rx_236_552_710_1056; + ((Int64Int64Int64CursorCursorProd *) fltPkd_822_1068)->field3 = + fltPkd_823_1066; + ((Int64Int64Int64CursorCursorProd *) fltPkd_822_1068)->field4 = + fltPkd_824_1067; + + PtrTy tailift_1287 = ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1287)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1287)->field1 = 3; + ((Int64Int64Int64CursorCursorProd *) tailift_1287)->field2 = + fltPkd_818_1062; + ((Int64Int64Int64CursorCursorProd *) tailift_1287)->field3 = + fltPkd_819_1065; + ((Int64Int64Int64CursorCursorProd *) tailift_1287)->field4 = + fltPkd_822_1068; + return tailift_1287; + break; + } + + case 1: + { + PtrTy fltPkd_825_1069 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_825_1069)->field0 = 1; + + PtrTy tailift_1288 = ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1288)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1288)->field1 = 2; + ((Int64Int64Int64CursorCursorProd *) tailift_1288)->field2 = + x_232_550_708_1054; + ((Int64Int64Int64CursorCursorProd *) tailift_1288)->field3 = + fltPkd_825_1069; + ((Int64Int64Int64CursorCursorProd *) tailift_1288)->field4 = + r_234_551_709_1055; + return tailift_1288; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1285"); + exit(1); + } + } +} +CursorTy caseFn_554(IntTy x_232_555_716_1070, CursorTy r_234_556_717_1071, + CursorTy rr_238_557_718_1072, IntTy rx_236_558_719_1073, + IntTy rs_235_559_720_1074, CursorTy rl_237_560_721_1075) +{ + TagTyPacked tag_1290 = *(TagTyPacked *) rr_238_557_718_1072; + CursorTy tail_1291 = rr_238_557_718_1072 + sizeof(IntTy); + + + switch_1292: + ; + switch (tag_1290) { + + case 0: + { + IntTy rrs_239_722_1076 = + ((Int64Int64CursorCursorProd *) tail_1291)->field0; + IntTy rrx_240_723_1077 = + ((Int64Int64CursorCursorProd *) tail_1291)->field1; + CursorTy rrl_241_724_1078 = + ((Int64Int64CursorCursorProd *) tail_1291)->field2; + CursorTy rrr_242_725_1079 = + ((Int64Int64CursorCursorProd *) tail_1291)->field3; + + return caseFn_543(x_232_555_716_1070, rr_238_557_718_1072, + rx_236_558_719_1073, rs_235_559_720_1074, + rl_237_560_721_1075); + break; + } + + case 1: + { + return caseFn_549(x_232_555_716_1070, r_234_556_717_1071, + rx_236_558_719_1073, rl_237_560_721_1075); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1290"); + exit(1); + } + } +} +CursorTy caseFn_561(IntTy x_232_562_726_1080, CursorTy r_234_563_727_1081) +{ + TagTyPacked tag_1293 = *(TagTyPacked *) r_234_563_727_1081; + CursorTy tail_1294 = r_234_563_727_1081 + sizeof(IntTy); + + + switch_1296: + ; + switch (tag_1293) { + + case 1: + { + PtrTy fltPkd_826_1082 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_826_1082)->field0 = 1; + + PtrTy fltPkd_827_1083 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_827_1083)->field0 = 1; + + PtrTy tailift_1295 = ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1295)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1295)->field1 = 1; + ((Int64Int64Int64CursorCursorProd *) tailift_1295)->field2 = + x_232_562_726_1080; + ((Int64Int64Int64CursorCursorProd *) tailift_1295)->field3 = + fltPkd_826_1082; + ((Int64Int64Int64CursorCursorProd *) tailift_1295)->field4 = + fltPkd_827_1083; + return tailift_1295; + break; + } + + case 0: + { + IntTy rs_235_728_1084 = + ((Int64Int64CursorCursorProd *) tail_1294)->field0; + IntTy rx_236_729_1085 = + ((Int64Int64CursorCursorProd *) tail_1294)->field1; + CursorTy rl_237_730_1086 = + ((Int64Int64CursorCursorProd *) tail_1294)->field2; + CursorTy rr_238_731_1087 = + ((Int64Int64CursorCursorProd *) tail_1294)->field3; + + return caseFn_554(x_232_562_726_1080, r_234_563_727_1081, + rr_238_731_1087, rx_236_729_1085, rs_235_728_1084, + rl_237_730_1086); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1293"); + exit(1); + } + } +} +CursorTy caseFn_564(CursorTy l_233_565_732_1088, IntTy x_232_566_733_1089, + CursorTy r_234_567_734_1090, IntTy ls_251_568_735_1091) +{ + TagTyPacked tag_1297 = *(TagTyPacked *) r_234_567_734_1090; + CursorTy tail_1298 = r_234_567_734_1090 + sizeof(IntTy); + + + switch_1303: + ; + switch (tag_1297) { + + case 1: + { + IntTy fltPkd_828_1092 = 1 + ls_251_568_735_1091; + PtrTy fltPkd_829_1093 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_829_1093)->field0 = 1; + + PtrTy tailift_1299 = ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1299)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1299)->field1 = + fltPkd_828_1092; + ((Int64Int64Int64CursorCursorProd *) tailift_1299)->field2 = + x_232_566_733_1089; + ((Int64Int64Int64CursorCursorProd *) tailift_1299)->field3 = + l_233_565_732_1088; + ((Int64Int64Int64CursorCursorProd *) tailift_1299)->field4 = + fltPkd_829_1093; + return tailift_1299; + break; + } + + case 0: + { + IntTy rs_255_736_1094 = + ((Int64Int64CursorCursorProd *) tail_1298)->field0; + IntTy rx_256_737_1095 = + ((Int64Int64CursorCursorProd *) tail_1298)->field1; + CursorTy rl_257_738_1096 = + ((Int64Int64CursorCursorProd *) tail_1298)->field2; + CursorTy rr_258_739_1097 = + ((Int64Int64CursorCursorProd *) tail_1298)->field3; + IntTy fltPrm_831_1098 = 3 * ls_251_568_735_1091; + BoolTy fltIf_830_1099 = rs_255_736_1094 > fltPrm_831_1098; + + if (fltIf_830_1099) { + IntTy fltPrm_833_1100 = size(rl_257_738_1096); + IntTy fltPrm_835_1101 = size(rr_258_739_1097); + IntTy fltPrm_834_1102 = 2 * fltPrm_835_1101; + BoolTy fltIf_832_1103 = fltPrm_833_1100 < fltPrm_834_1102; + + if (fltIf_832_1103) { + IntTy fltPrm_837_1104 = 1 + ls_251_568_735_1091; + IntTy fltPkd_836_1105 = fltPrm_837_1104 + rs_255_736_1094; + IntTy fltPrm_840_1106 = 1 + ls_251_568_735_1091; + IntTy fltPrm_841_1107 = size(rl_257_738_1096); + IntTy fltPkd_839_1108 = fltPrm_840_1106 + fltPrm_841_1107; + PtrTy fltPkd_838_1109 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) fltPkd_838_1109)->field0 = + 0; + ((Int64Int64Int64CursorCursorProd *) fltPkd_838_1109)->field1 = + fltPkd_839_1108; + ((Int64Int64Int64CursorCursorProd *) fltPkd_838_1109)->field2 = + x_232_566_733_1089; + ((Int64Int64Int64CursorCursorProd *) fltPkd_838_1109)->field3 = + l_233_565_732_1088; + ((Int64Int64Int64CursorCursorProd *) fltPkd_838_1109)->field4 = + rl_257_738_1096; + + PtrTy tailift_1300 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1300)->field0 = + 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1300)->field1 = + fltPkd_836_1105; + ((Int64Int64Int64CursorCursorProd *) tailift_1300)->field2 = + rx_256_737_1095; + ((Int64Int64Int64CursorCursorProd *) tailift_1300)->field3 = + fltPkd_838_1109; + ((Int64Int64Int64CursorCursorProd *) tailift_1300)->field4 = + rr_258_739_1097; + return tailift_1300; + } else { + IntTy fltPrm_843_1110 = 1 + ls_251_568_735_1091; + IntTy fltPkd_842_1111 = fltPrm_843_1110 + rs_255_736_1094; + IntTy fltPkd_844_1112 = val(rl_257_738_1096); + IntTy fltPrm_847_1113 = 1 + ls_251_568_735_1091; + CursorTy fltAppE_849_1114 = left(rl_257_738_1096); + IntTy fltPrm_848_1115 = size(fltAppE_849_1114); + IntTy fltPkd_846_1116 = fltPrm_847_1113 + fltPrm_848_1115; + CursorTy fltPkd_850_1117 = left(rl_257_738_1096); + PtrTy fltPkd_845_1118 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) fltPkd_845_1118)->field0 = + 0; + ((Int64Int64Int64CursorCursorProd *) fltPkd_845_1118)->field1 = + fltPkd_846_1116; + ((Int64Int64Int64CursorCursorProd *) fltPkd_845_1118)->field2 = + x_232_566_733_1089; + ((Int64Int64Int64CursorCursorProd *) fltPkd_845_1118)->field3 = + l_233_565_732_1088; + ((Int64Int64Int64CursorCursorProd *) fltPkd_845_1118)->field4 = + fltPkd_850_1117; + + IntTy fltPrm_854_1119 = size(rr_258_739_1097); + IntTy fltPrm_853_1120 = 1 + fltPrm_854_1119; + CursorTy fltAppE_856_1121 = right(rl_257_738_1096); + IntTy fltPrm_855_1122 = size(fltAppE_856_1121); + IntTy fltPkd_852_1123 = fltPrm_853_1120 + fltPrm_855_1122; + CursorTy fltPkd_857_1124 = right(rl_257_738_1096); + PtrTy fltPkd_851_1125 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) fltPkd_851_1125)->field0 = + 0; + ((Int64Int64Int64CursorCursorProd *) fltPkd_851_1125)->field1 = + fltPkd_852_1123; + ((Int64Int64Int64CursorCursorProd *) fltPkd_851_1125)->field2 = + rx_256_737_1095; + ((Int64Int64Int64CursorCursorProd *) fltPkd_851_1125)->field3 = + fltPkd_857_1124; + ((Int64Int64Int64CursorCursorProd *) fltPkd_851_1125)->field4 = + rr_258_739_1097; + + PtrTy tailift_1301 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1301)->field0 = + 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1301)->field1 = + fltPkd_842_1111; + ((Int64Int64Int64CursorCursorProd *) tailift_1301)->field2 = + fltPkd_844_1112; + ((Int64Int64Int64CursorCursorProd *) tailift_1301)->field3 = + fltPkd_845_1118; + ((Int64Int64Int64CursorCursorProd *) tailift_1301)->field4 = + fltPkd_851_1125; + return tailift_1301; + } + } else { + IntTy fltPrm_859_1126 = 1 + ls_251_568_735_1091; + IntTy fltPkd_858_1127 = fltPrm_859_1126 + rs_255_736_1094; + PtrTy tailift_1302 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1302)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1302)->field1 = + fltPkd_858_1127; + ((Int64Int64Int64CursorCursorProd *) tailift_1302)->field2 = + x_232_566_733_1089; + ((Int64Int64Int64CursorCursorProd *) tailift_1302)->field3 = + l_233_565_732_1088; + ((Int64Int64Int64CursorCursorProd *) tailift_1302)->field4 = + r_234_567_734_1090; + return tailift_1302; + } + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1297"); + exit(1); + } + } +} +CursorTy caseFn_569(IntTy x_259_570_740_1128, CursorTy ll_264_571_741_1129, + IntTy lx_263_572_742_1130, IntTy ls_262_573_743_1131, + CursorTy lr_265_574_744_1132, IntTy lls_266_575_745_1133) +{ + TagTyPacked tag_1304 = *(TagTyPacked *) lr_265_574_744_1132; + CursorTy tail_1305 = lr_265_574_744_1132 + sizeof(IntTy); + + + switch_1309: + ; + switch (tag_1304) { + + case 0: + { + IntTy lrs_270_746_1134 = + ((Int64Int64CursorCursorProd *) tail_1305)->field0; + IntTy lrx_271_747_1135 = + ((Int64Int64CursorCursorProd *) tail_1305)->field1; + CursorTy lrl_272_748_1136 = + ((Int64Int64CursorCursorProd *) tail_1305)->field2; + CursorTy lrr_273_749_1137 = + ((Int64Int64CursorCursorProd *) tail_1305)->field3; + IntTy fltPrm_861_1138 = 2 * lls_266_575_745_1133; + BoolTy fltIf_860_1139 = lrs_270_746_1134 < fltPrm_861_1138; + + if (fltIf_860_1139) { + IntTy fltPkd_862_1140 = 1 + ls_262_573_743_1131; + IntTy fltPkd_864_1141 = 1 + lrs_270_746_1134; + PtrTy fltPkd_865_1142 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_865_1142)->field0 = 1; + + PtrTy fltPkd_863_1143 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) fltPkd_863_1143)->field0 = + 0; + ((Int64Int64Int64CursorCursorProd *) fltPkd_863_1143)->field1 = + fltPkd_864_1141; + ((Int64Int64Int64CursorCursorProd *) fltPkd_863_1143)->field2 = + x_259_570_740_1128; + ((Int64Int64Int64CursorCursorProd *) fltPkd_863_1143)->field3 = + lr_265_574_744_1132; + ((Int64Int64Int64CursorCursorProd *) fltPkd_863_1143)->field4 = + fltPkd_865_1142; + + PtrTy tailift_1306 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1306)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1306)->field1 = + fltPkd_862_1140; + ((Int64Int64Int64CursorCursorProd *) tailift_1306)->field2 = + lx_263_572_742_1130; + ((Int64Int64Int64CursorCursorProd *) tailift_1306)->field3 = + ll_264_571_741_1129; + ((Int64Int64Int64CursorCursorProd *) tailift_1306)->field4 = + fltPkd_863_1143; + return tailift_1306; + } else { + IntTy fltPkd_866_1144 = 1 + ls_262_573_743_1131; + IntTy fltPrm_869_1145 = 1 + lls_266_575_745_1133; + IntTy fltPrm_870_1146 = size(lrl_272_748_1136); + IntTy fltPkd_868_1147 = fltPrm_869_1145 + fltPrm_870_1146; + PtrTy fltPkd_867_1148 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) fltPkd_867_1148)->field0 = + 0; + ((Int64Int64Int64CursorCursorProd *) fltPkd_867_1148)->field1 = + fltPkd_868_1147; + ((Int64Int64Int64CursorCursorProd *) fltPkd_867_1148)->field2 = + lx_263_572_742_1130; + ((Int64Int64Int64CursorCursorProd *) fltPkd_867_1148)->field3 = + ll_264_571_741_1129; + ((Int64Int64Int64CursorCursorProd *) fltPkd_867_1148)->field4 = + lrl_272_748_1136; + + IntTy fltPrm_873_1149 = size(lrr_273_749_1137); + IntTy fltPkd_872_1150 = 1 + fltPrm_873_1149; + PtrTy fltPkd_874_1151 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_874_1151)->field0 = 1; + + PtrTy fltPkd_871_1152 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) fltPkd_871_1152)->field0 = + 0; + ((Int64Int64Int64CursorCursorProd *) fltPkd_871_1152)->field1 = + fltPkd_872_1150; + ((Int64Int64Int64CursorCursorProd *) fltPkd_871_1152)->field2 = + x_259_570_740_1128; + ((Int64Int64Int64CursorCursorProd *) fltPkd_871_1152)->field3 = + lrr_273_749_1137; + ((Int64Int64Int64CursorCursorProd *) fltPkd_871_1152)->field4 = + fltPkd_874_1151; + + PtrTy tailift_1307 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1307)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1307)->field1 = + fltPkd_866_1144; + ((Int64Int64Int64CursorCursorProd *) tailift_1307)->field2 = + lrx_271_747_1135; + ((Int64Int64Int64CursorCursorProd *) tailift_1307)->field3 = + fltPkd_867_1148; + ((Int64Int64Int64CursorCursorProd *) tailift_1307)->field4 = + fltPkd_871_1152; + return tailift_1307; + } + break; + } + + case 1: + { + PtrTy fltPkd_876_1153 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_876_1153)->field0 = 1; + + PtrTy fltPkd_877_1154 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_877_1154)->field0 = 1; + + PtrTy fltPkd_875_1155 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) fltPkd_875_1155)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) fltPkd_875_1155)->field1 = 1; + ((Int64Int64Int64CursorCursorProd *) fltPkd_875_1155)->field2 = + x_259_570_740_1128; + ((Int64Int64Int64CursorCursorProd *) fltPkd_875_1155)->field3 = + fltPkd_876_1153; + ((Int64Int64Int64CursorCursorProd *) fltPkd_875_1155)->field4 = + fltPkd_877_1154; + + PtrTy tailift_1308 = ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1308)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1308)->field1 = 3; + ((Int64Int64Int64CursorCursorProd *) tailift_1308)->field2 = + lx_263_572_742_1130; + ((Int64Int64Int64CursorCursorProd *) tailift_1308)->field3 = + ll_264_571_741_1129; + ((Int64Int64Int64CursorCursorProd *) tailift_1308)->field4 = + fltPkd_875_1155; + return tailift_1308; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1304"); + exit(1); + } + } +} +CursorTy caseFn_576(CursorTy l_260_577_750_1156, IntTy x_259_578_751_1157, + IntTy lx_263_579_752_1158, CursorTy lr_265_580_753_1159) +{ + TagTyPacked tag_1310 = *(TagTyPacked *) lr_265_580_753_1159; + CursorTy tail_1311 = lr_265_580_753_1159 + sizeof(IntTy); + + + switch_1314: + ; + switch (tag_1310) { + + case 0: + { + IntTy lrs_274_754_1160 = + ((Int64Int64CursorCursorProd *) tail_1311)->field0; + IntTy lrx_275_755_1161 = + ((Int64Int64CursorCursorProd *) tail_1311)->field1; + CursorTy lrl_276_756_1162 = + ((Int64Int64CursorCursorProd *) tail_1311)->field2; + CursorTy lrr_277_757_1163 = + ((Int64Int64CursorCursorProd *) tail_1311)->field3; + PtrTy fltPkd_879_1164 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_879_1164)->field0 = 1; + + PtrTy fltPkd_880_1165 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_880_1165)->field0 = 1; + + PtrTy fltPkd_878_1166 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) fltPkd_878_1166)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) fltPkd_878_1166)->field1 = 1; + ((Int64Int64Int64CursorCursorProd *) fltPkd_878_1166)->field2 = + lx_263_579_752_1158; + ((Int64Int64Int64CursorCursorProd *) fltPkd_878_1166)->field3 = + fltPkd_879_1164; + ((Int64Int64Int64CursorCursorProd *) fltPkd_878_1166)->field4 = + fltPkd_880_1165; + + PtrTy fltPkd_882_1167 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_882_1167)->field0 = 1; + + PtrTy fltPkd_883_1168 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_883_1168)->field0 = 1; + + PtrTy fltPkd_881_1169 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) fltPkd_881_1169)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) fltPkd_881_1169)->field1 = 1; + ((Int64Int64Int64CursorCursorProd *) fltPkd_881_1169)->field2 = + x_259_578_751_1157; + ((Int64Int64Int64CursorCursorProd *) fltPkd_881_1169)->field3 = + fltPkd_882_1167; + ((Int64Int64Int64CursorCursorProd *) fltPkd_881_1169)->field4 = + fltPkd_883_1168; + + PtrTy tailift_1312 = ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1312)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1312)->field1 = 3; + ((Int64Int64Int64CursorCursorProd *) tailift_1312)->field2 = + lrx_275_755_1161; + ((Int64Int64Int64CursorCursorProd *) tailift_1312)->field3 = + fltPkd_878_1166; + ((Int64Int64Int64CursorCursorProd *) tailift_1312)->field4 = + fltPkd_881_1169; + return tailift_1312; + break; + } + + case 1: + { + PtrTy fltPkd_884_1170 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_884_1170)->field0 = 1; + + PtrTy tailift_1313 = ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1313)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1313)->field1 = 2; + ((Int64Int64Int64CursorCursorProd *) tailift_1313)->field2 = + x_259_578_751_1157; + ((Int64Int64Int64CursorCursorProd *) tailift_1313)->field3 = + l_260_577_750_1156; + ((Int64Int64Int64CursorCursorProd *) tailift_1313)->field4 = + fltPkd_884_1170; + return tailift_1313; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1310"); + exit(1); + } + } +} +CursorTy caseFn_581(CursorTy l_260_582_758_1171, IntTy x_259_583_759_1172, + CursorTy ll_264_584_760_1173, IntTy lx_263_585_761_1174, + IntTy ls_262_586_762_1175, CursorTy lr_265_587_763_1176) +{ + TagTyPacked tag_1315 = *(TagTyPacked *) ll_264_584_760_1173; + CursorTy tail_1316 = ll_264_584_760_1173 + sizeof(IntTy); + + + switch_1317: + ; + switch (tag_1315) { + + case 0: + { + IntTy lls_266_764_1177 = + ((Int64Int64CursorCursorProd *) tail_1316)->field0; + IntTy llx_267_765_1178 = + ((Int64Int64CursorCursorProd *) tail_1316)->field1; + CursorTy lll_268_766_1179 = + ((Int64Int64CursorCursorProd *) tail_1316)->field2; + CursorTy llr_269_767_1180 = + ((Int64Int64CursorCursorProd *) tail_1316)->field3; + + return caseFn_569(x_259_583_759_1172, ll_264_584_760_1173, + lx_263_585_761_1174, ls_262_586_762_1175, + lr_265_587_763_1176, lls_266_764_1177); + break; + } + + case 1: + { + return caseFn_576(l_260_582_758_1171, x_259_583_759_1172, + lx_263_585_761_1174, lr_265_587_763_1176); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1315"); + exit(1); + } + } +} +CursorTy caseFn_588(CursorTy l_260_589_768_1181, IntTy x_259_590_769_1182) +{ + TagTyPacked tag_1318 = *(TagTyPacked *) l_260_589_768_1181; + CursorTy tail_1319 = l_260_589_768_1181 + sizeof(IntTy); + + + switch_1321: + ; + switch (tag_1318) { + + case 1: + { + PtrTy fltPkd_885_1183 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_885_1183)->field0 = 1; + + PtrTy fltPkd_886_1184 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_886_1184)->field0 = 1; + + PtrTy tailift_1320 = ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1320)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1320)->field1 = 1; + ((Int64Int64Int64CursorCursorProd *) tailift_1320)->field2 = + x_259_590_769_1182; + ((Int64Int64Int64CursorCursorProd *) tailift_1320)->field3 = + fltPkd_885_1183; + ((Int64Int64Int64CursorCursorProd *) tailift_1320)->field4 = + fltPkd_886_1184; + return tailift_1320; + break; + } + + case 0: + { + IntTy ls_262_770_1185 = + ((Int64Int64CursorCursorProd *) tail_1319)->field0; + IntTy lx_263_771_1186 = + ((Int64Int64CursorCursorProd *) tail_1319)->field1; + CursorTy ll_264_772_1187 = + ((Int64Int64CursorCursorProd *) tail_1319)->field2; + CursorTy lr_265_773_1188 = + ((Int64Int64CursorCursorProd *) tail_1319)->field3; + + return caseFn_581(l_260_589_768_1181, x_259_590_769_1182, + ll_264_772_1187, lx_263_771_1186, ls_262_770_1185, + lr_265_773_1188); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1318"); + exit(1); + } + } +} +CursorTy caseFn_591(CursorTy r_261_592_774_1189, CursorTy l_260_593_775_1190, + IntTy x_259_594_776_1191, IntTy rs_278_595_777_1192) +{ + TagTyPacked tag_1322 = *(TagTyPacked *) l_260_593_775_1190; + CursorTy tail_1323 = l_260_593_775_1190 + sizeof(IntTy); + + + switch_1328: + ; + switch (tag_1322) { + + case 1: + { + IntTy fltPkd_887_1193 = 1 + rs_278_595_777_1192; + PtrTy fltPkd_888_1194 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_888_1194)->field0 = 1; + + PtrTy tailift_1324 = ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1324)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1324)->field1 = + fltPkd_887_1193; + ((Int64Int64Int64CursorCursorProd *) tailift_1324)->field2 = + x_259_594_776_1191; + ((Int64Int64Int64CursorCursorProd *) tailift_1324)->field3 = + fltPkd_888_1194; + ((Int64Int64Int64CursorCursorProd *) tailift_1324)->field4 = + r_261_592_774_1189; + return tailift_1324; + break; + } + + case 0: + { + IntTy ls_282_778_1195 = + ((Int64Int64CursorCursorProd *) tail_1323)->field0; + IntTy lx_283_779_1196 = + ((Int64Int64CursorCursorProd *) tail_1323)->field1; + CursorTy ll_284_780_1197 = + ((Int64Int64CursorCursorProd *) tail_1323)->field2; + CursorTy lr_285_781_1198 = + ((Int64Int64CursorCursorProd *) tail_1323)->field3; + IntTy fltPrm_890_1199 = 3 * rs_278_595_777_1192; + BoolTy fltIf_889_1200 = ls_282_778_1195 > fltPrm_890_1199; + + if (fltIf_889_1200) { + IntTy fltPrm_892_1201 = size(lr_285_781_1198); + IntTy fltPrm_894_1202 = size(ll_284_780_1197); + IntTy fltPrm_893_1203 = 2 * fltPrm_894_1202; + BoolTy fltIf_891_1204 = fltPrm_892_1201 < fltPrm_893_1203; + + if (fltIf_891_1204) { + IntTy fltPrm_896_1205 = 1 + ls_282_778_1195; + IntTy fltPkd_895_1206 = fltPrm_896_1205 + + rs_278_595_777_1192; + IntTy fltPrm_899_1207 = 1 + rs_278_595_777_1192; + IntTy fltPrm_900_1208 = size(lr_285_781_1198); + IntTy fltPkd_898_1209 = fltPrm_899_1207 + fltPrm_900_1208; + PtrTy fltPkd_897_1210 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) fltPkd_897_1210)->field0 = + 0; + ((Int64Int64Int64CursorCursorProd *) fltPkd_897_1210)->field1 = + fltPkd_898_1209; + ((Int64Int64Int64CursorCursorProd *) fltPkd_897_1210)->field2 = + x_259_594_776_1191; + ((Int64Int64Int64CursorCursorProd *) fltPkd_897_1210)->field3 = + lr_285_781_1198; + ((Int64Int64Int64CursorCursorProd *) fltPkd_897_1210)->field4 = + r_261_592_774_1189; + + PtrTy tailift_1325 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1325)->field0 = + 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1325)->field1 = + fltPkd_895_1206; + ((Int64Int64Int64CursorCursorProd *) tailift_1325)->field2 = + lx_283_779_1196; + ((Int64Int64Int64CursorCursorProd *) tailift_1325)->field3 = + ll_284_780_1197; + ((Int64Int64Int64CursorCursorProd *) tailift_1325)->field4 = + fltPkd_897_1210; + return tailift_1325; + } else { + IntTy fltPrm_902_1211 = 1 + ls_282_778_1195; + IntTy fltPkd_901_1212 = fltPrm_902_1211 + + rs_278_595_777_1192; + IntTy fltPkd_903_1213 = val(lr_285_781_1198); + IntTy fltPrm_907_1214 = size(ll_284_780_1197); + IntTy fltPrm_906_1215 = 1 + fltPrm_907_1214; + CursorTy fltAppE_909_1216 = left(lr_285_781_1198); + IntTy fltPrm_908_1217 = size(fltAppE_909_1216); + IntTy fltPkd_905_1218 = fltPrm_906_1215 + fltPrm_908_1217; + CursorTy fltPkd_910_1219 = left(lr_285_781_1198); + PtrTy fltPkd_904_1220 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) fltPkd_904_1220)->field0 = + 0; + ((Int64Int64Int64CursorCursorProd *) fltPkd_904_1220)->field1 = + fltPkd_905_1218; + ((Int64Int64Int64CursorCursorProd *) fltPkd_904_1220)->field2 = + lx_283_779_1196; + ((Int64Int64Int64CursorCursorProd *) fltPkd_904_1220)->field3 = + ll_284_780_1197; + ((Int64Int64Int64CursorCursorProd *) fltPkd_904_1220)->field4 = + fltPkd_910_1219; + + IntTy fltPrm_913_1221 = 1 + rs_278_595_777_1192; + CursorTy fltAppE_915_1222 = right(lr_285_781_1198); + IntTy fltPrm_914_1223 = size(fltAppE_915_1222); + IntTy fltPkd_912_1224 = fltPrm_913_1221 + fltPrm_914_1223; + CursorTy fltPkd_916_1225 = right(lr_285_781_1198); + PtrTy fltPkd_911_1226 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) fltPkd_911_1226)->field0 = + 0; + ((Int64Int64Int64CursorCursorProd *) fltPkd_911_1226)->field1 = + fltPkd_912_1224; + ((Int64Int64Int64CursorCursorProd *) fltPkd_911_1226)->field2 = + x_259_594_776_1191; + ((Int64Int64Int64CursorCursorProd *) fltPkd_911_1226)->field3 = + fltPkd_916_1225; + ((Int64Int64Int64CursorCursorProd *) fltPkd_911_1226)->field4 = + r_261_592_774_1189; + + PtrTy tailift_1326 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1326)->field0 = + 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1326)->field1 = + fltPkd_901_1212; + ((Int64Int64Int64CursorCursorProd *) tailift_1326)->field2 = + fltPkd_903_1213; + ((Int64Int64Int64CursorCursorProd *) tailift_1326)->field3 = + fltPkd_904_1220; + ((Int64Int64Int64CursorCursorProd *) tailift_1326)->field4 = + fltPkd_911_1226; + return tailift_1326; + } + } else { + IntTy fltPrm_918_1227 = 1 + ls_282_778_1195; + IntTy fltPkd_917_1228 = fltPrm_918_1227 + rs_278_595_777_1192; + PtrTy tailift_1327 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1327)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1327)->field1 = + fltPkd_917_1228; + ((Int64Int64Int64CursorCursorProd *) tailift_1327)->field2 = + x_259_594_776_1191; + ((Int64Int64Int64CursorCursorProd *) tailift_1327)->field3 = + l_260_593_775_1190; + ((Int64Int64Int64CursorCursorProd *) tailift_1327)->field4 = + r_261_592_774_1189; + return tailift_1327; + } + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1322"); + exit(1); + } + } +} +int __main_expr() +{ + add_symbol(1230, ")"); + add_symbol(1231, "(PureSet"); + add_symbol(1232, "(EmptySet"); + add_symbol(1233, " "); + + CursorTy fltAppE_783_919 = empty(); + CursorTy fltAppE_782_920 = insert(0, fltAppE_783_919); + IntTy tmp_app_1229 = sum(fltAppE_782_920); + + printf("%lld", tmp_app_1229); + printf("\n"); + free_symtable(); + return 0; +} \ No newline at end of file diff --git a/benchmarks/modules/Set.hs b/benchmarks/modules/Set.hs new file mode 100644 index 000000000..6a61bac57 --- /dev/null +++ b/benchmarks/modules/Set.hs @@ -0,0 +1,140 @@ +{-# LANGUAGE BlockArguments #-} + +module Set where + +-- type size value left right +type Size = Int +data IntSet = PureSet Int Int IntSet IntSet + | EmptySet + +-- Construction -------------------------------------------- + +-- Create an empty set +empty :: IntSet +empty = EmptySet + +-- Create a set with an initialization element +singleton :: Int -> IntSet +singleton x = PureSet 1 x EmptySet EmptySet + +-- Insertion, Deletion -------------------------------------- +insert :: Int -> IntSet -> IntSet +insert x s = + case s of + EmptySet -> singleton x + PureSet sz v l r -> + if x == v then s + else if x <= v then + let nl = insert x l + in balanceL v nl r + else + let nr = insert x r + in balanceR v l nr + +balanceL :: Int -> IntSet -> IntSet -> IntSet +balanceL x l r = case r of + EmptySet -> case l of + EmptySet -> PureSet 1 x EmptySet EmptySet + PureSet ls lx ll lr -> + case ll of + PureSet lls llx lll llr -> case lr of + PureSet lrs lrx lrl lrr -> + if (lrs < 2*lls) then PureSet (1+ls) lx ll (PureSet (1+lrs) x lr EmptySet) + else PureSet (1+ls) lrx (PureSet (1+lls+size lrl) lx ll lrl) (PureSet (1+size lrr) x lrr EmptySet) + EmptySet -> PureSet 3 lx ll (PureSet 1 x EmptySet EmptySet) + EmptySet -> case lr of + PureSet lrs lrx lrl lrr -> PureSet 3 lrx (PureSet 1 lx EmptySet EmptySet) (PureSet 1 x EmptySet EmptySet) + EmptySet -> PureSet 2 x l EmptySet + + PureSet rs _ _ _ -> case l of + EmptySet -> PureSet (1+rs) x EmptySet r + + PureSet ls lx ll lr -> + if (ls > 3*rs) then + if ((size lr) < 2*(size ll)) then PureSet (1+ls+rs) lx ll (PureSet (1+rs+(size lr)) x lr r) + else PureSet (1+ls+rs) (val lr) (PureSet (1+(size ll)+(size (left lr))) lx ll (left lr)) (PureSet (1+rs+(size (right lr))) x (right lr) r) + else PureSet (1+ls+rs) x l r + +balanceR :: Int -> IntSet -> IntSet -> IntSet +balanceR x l r = case l of + EmptySet -> case r of + EmptySet -> PureSet 1 x EmptySet EmptySet + PureSet rs rx rl rr -> + case rr of + PureSet rrs rrx rrl rrr -> case rl of + PureSet rls rlx rll rlr -> + if ((size rl) < 2*(size rr)) then PureSet (1+rs) rx (PureSet (1+(size rl)) x EmptySet rl) rr + else PureSet (1+rs) (val rl) (PureSet (1+(size (left rl))) x EmptySet (left rl)) (PureSet (1+(size rr)+(size (right rl))) rx (right rl) rr) + EmptySet -> PureSet 3 rx (PureSet 1 x EmptySet EmptySet) rr + EmptySet -> case rl of + PureSet rls rlx rll rlr -> PureSet 3 (val rl) (PureSet 1 x EmptySet EmptySet) (PureSet 1 rx EmptySet EmptySet) + EmptySet -> PureSet 2 x EmptySet r + + PureSet ls _ _ _ -> case r of + EmptySet -> PureSet (1+ls) x l EmptySet + + PureSet rs rx rl rr -> + if (rs > 3*ls) then + if ((size rl) < 2*(size rr)) then PureSet (1+ls+rs) rx (PureSet (1+ls+(size rl)) x l rl) rr + else PureSet (1+ls+rs) (val rl) (PureSet (1+ls+(size (left rl))) x l (left rl)) (PureSet (1+(size rr)+(size (right rl))) rx (right rl) rr) + else PureSet (1+ls+rs) x l r + +-- Contents ------------------------------------------------ + +-- Check if the set is empty +null :: IntSet -> Bool +null s = + case s of + EmptySet -> True + PureSet _ _ _ _ -> False +-- Check if a set has an element +member :: Int -> IntSet -> Bool +member x s = + case s of + EmptySet -> False + PureSet _ v l r -> + if x == v then True + else if x <= v then member x l + else member x r + +depth :: Int -> Int -> IntSet -> Int +depth x c s = + case s of + EmptySet -> -1 + PureSet _ v l r -> + if x == v then c + 1 + else if x <= v then depth x (c+1) l + else depth x (c+1) r + +size :: IntSet -> Int +size s = case s of + EmptySet -> 0 + PureSet sz _ _ _ -> sz + +val :: IntSet -> Int +val x = case x of + EmptySet -> 0 + PureSet _ v _ _ -> v + +left :: IntSet -> IntSet +left x = case x of + EmptySet -> EmptySet + PureSet _ _ l _ -> l + +right :: IntSet -> IntSet +right x = case x of + EmptySet -> EmptySet + PureSet _ _ _ r -> r + +insert_num :: Int -> IntSet -> IntSet +insert_num x s = + if x == 0 then insert x s + else insert x (insert_num (x-1) s) + +sum :: IntSet -> Int +sum s = case s of + EmptySet -> 0 + PureSet _ v l r -> v + (sum l) + (sum r) + +--gibbon_main = sum (insert_num 100 (insert_num 100 empty)) +gibbon_main = sum (insert 0 empty) \ No newline at end of file diff --git a/benchmarks/modules/Set/GHCPureSet b/benchmarks/modules/Set/GHCPureSet new file mode 100755 index 000000000..eb071f69c Binary files /dev/null and b/benchmarks/modules/Set/GHCPureSet differ diff --git a/benchmarks/modules/Set/GHCPureSet.hs b/benchmarks/modules/Set/GHCPureSet.hs new file mode 100644 index 000000000..1b1ee7f08 --- /dev/null +++ b/benchmarks/modules/Set/GHCPureSet.hs @@ -0,0 +1,132 @@ +{-# LANGUAGE BlockArguments #-} + +module Main where + +-- type size value left right +type Size = Int +data IntSet = PureSet Int Int IntSet IntSet + | EmptySet + +-- Construction -------------------------------------------- + +-- Create an empty set +empty :: IntSet +empty = EmptySet + +-- Create a set with an initialization element +singleton :: Int -> IntSet +singleton x = PureSet 1 x EmptySet EmptySet + +-- Insertion, Deletion -------------------------------------- +insert :: Int -> IntSet -> IntSet +insert x s = + case s of + EmptySet -> singleton x + PureSet sz v l r -> + if x == v then s + else if x <= v then + let nl = insert x l + in balanceL v nl r + --in PureSet ((size r) + (size nl)) v nl r + else + let nr = (insert x r) + in balanceR v l nr + --in PureSet ((size nr) + (size l)) v l nr + +balanceL :: Int -> IntSet -> IntSet -> IntSet +balanceL x l r = case r of + EmptySet -> case l of + EmptySet -> PureSet 1 x EmptySet EmptySet + PureSet ls lx ll lr -> + case ll of + PureSet lls llx lll llr -> case lr of + PureSet lrs lrx lrl lrr -> + if (lrs < 2*lls) then PureSet (1+ls) lx ll (PureSet (1+lrs) x lr EmptySet) + else PureSet (1+ls) lrx (PureSet (1+lls+size lrl) lx ll lrl) (PureSet (1+size lrr) x lrr EmptySet) + EmptySet -> PureSet 3 lx ll (PureSet 1 x EmptySet EmptySet) + EmptySet -> case lr of + PureSet lrs lrx lrl lrr -> PureSet 3 lrx (PureSet 1 lx EmptySet EmptySet) (PureSet 1 x EmptySet EmptySet) + EmptySet -> PureSet 2 x l EmptySet + + PureSet rs _ _ _ -> case l of + EmptySet -> PureSet (1+rs) x EmptySet r + + PureSet ls lx ll lr -> + if (ls > 3*rs) then + if ((size lr) < 2*(size ll)) then PureSet (1+ls+rs) lx ll (PureSet (1+rs+(size lr)) x lr r) + else PureSet (1+ls+rs) (val lr) (PureSet (1+(size ll)+(size (left lr))) lx ll (left lr)) (PureSet (1+rs+(size (right lr))) x (right lr) r) + else PureSet (1+ls+rs) x l r + +balanceR :: Int -> IntSet -> IntSet -> IntSet +balanceR x l r = case l of + EmptySet -> case r of + EmptySet -> PureSet 1 x EmptySet EmptySet + PureSet rs rx rl rr -> + case rr of + PureSet rrs rrx rrl rrr -> case rl of + PureSet rls rlx rll rlr -> + if ((size rl) < 2*(size rr)) then PureSet (1+rs) rx (PureSet (1+(size rl)) x EmptySet rl) rr + else PureSet (1+rs) (val rl) (PureSet (1+(size (left rl))) x EmptySet (left rl)) (PureSet (1+(size rr)+(size (right rl))) rx (right rl) rr) + EmptySet -> PureSet 3 rx (PureSet 1 x EmptySet EmptySet) rr + EmptySet -> case rl of + PureSet rls rlx rll rlr -> PureSet 3 (val rl) (PureSet 1 x EmptySet EmptySet) (PureSet 1 rx EmptySet EmptySet) + EmptySet -> PureSet 2 x EmptySet r + + PureSet ls _ _ _ -> case r of + EmptySet -> PureSet (1+ls) x l EmptySet + + PureSet rs rx rl rr -> + if (rs > 3*ls) then + if ((size rl) < 2*(size rr)) then PureSet (1+ls+rs) rx (PureSet (1+ls+(size rl)) x l rl) rr + else PureSet (1+ls+rs) (val rl) (PureSet (1+ls+(size (left rl))) x l (left rl)) (PureSet (1+(size rr)+(size (right rl))) rx (right rl) rr) + else PureSet (1+ls+rs) x l r + +-- Contents ------------------------------------------------ + +-- Check if the set is empty +null :: IntSet -> Bool +null s = + case s of + EmptySet -> True + PureSet _ _ _ _ -> False +-- Check if a set has an element +member :: Int -> IntSet -> Bool +member x s = + case s of + EmptySet -> False + PureSet _ v l r -> + if x == v then True + else if x <= v then member x l + else member x r + +size :: IntSet -> Int +size s = case s of + EmptySet -> 0 + PureSet sz _ _ _ -> sz + +val :: IntSet -> Int +val x = case x of + EmptySet -> 0 + PureSet _ v _ _ -> v + +left :: IntSet -> IntSet +left x = case x of + EmptySet -> EmptySet + PureSet _ _ l _ -> l + +right :: IntSet -> IntSet +right x = case x of + EmptySet -> EmptySet + PureSet _ _ _ r -> r + +insert_num :: Int -> IntSet -> IntSet +insert_num x s = + if x == 0 then insert x s + else insert x (insert_num (x-1) s) + +sum :: IntSet -> Int +sum s = case s of + EmptySet -> 0 + PureSet _ v l r -> v + (Main.sum l) + (Main.sum r) + +main = putStrLn (show (Main.sum (insert_num 100 (insert_num 100 empty)))) \ No newline at end of file diff --git a/benchmarks/modules/Set/GHCStdSet b/benchmarks/modules/Set/GHCStdSet new file mode 100755 index 000000000..ca237cee5 Binary files /dev/null and b/benchmarks/modules/Set/GHCStdSet differ diff --git a/benchmarks/modules/Set/GHCStdSet.hs b/benchmarks/modules/Set/GHCStdSet.hs new file mode 100644 index 000000000..b171a095b --- /dev/null +++ b/benchmarks/modules/Set/GHCStdSet.hs @@ -0,0 +1,11 @@ + +module Main where +import Data.Set as Set +import Data.Set.Internal as Internal + +insert_num :: Int -> Set Int -> Set Int +insert_num x s = + if x == 0 then Set.insert x s + else insert x (insert_num (x-1) s) + +main = putStrLn (show (Set.foldr (+) 0 (insert_num 100 (insert_num 100 Set.empty)))) \ No newline at end of file diff --git a/benchmarks/modules/Set/GibbonPureSet.c b/benchmarks/modules/Set/GibbonPureSet.c new file mode 100644 index 000000000..c2c01eb80 --- /dev/null +++ b/benchmarks/modules/Set/GibbonPureSet.c @@ -0,0 +1,3120 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// #include +#ifdef _WIN64 +#include +#endif +#include +#include +#include // For va_start etc +#include +#include +#include +#include +#ifdef _POINTER +#include +#endif +#ifdef _PARALLEL +#include +#include +#endif + +#define KB 1024lu +#define MB (KB * 1000lu) +#define GB (MB * 1000lu) + +#define REDIRECTION_TAG 255 +#define INDIRECTION_TAG 254 + +// Initial size of BigInfinite buffers +static long long global_init_biginf_buf_size = (4 * GB); + +// Initial size of Infinite buffers +static long long global_init_inf_buf_size = 1 * KB; + +// Maximum size of a chunk, see GitHub #110. +static long long global_inf_buf_max_chunk_size = 1 * GB; + +static long long global_size_param = 1; +static long long global_iters_param = 1; + +static char* global_benchfile_param = NULL; +static char* global_arrayfile_param = NULL; +// Number of lines in the arrayfile +static long long global_arrayfile_length_param = -1; + +// Sequential for now: +static const int num_workers = 1; + +// Count the number of regions allocated. +static long long global_region_count = 0; +static bool global_region_count_flag = false; + +#ifdef _PARALLEL +static inline void bump_global_region_count() { + __atomic_add_fetch(&global_region_count, 1, __ATOMIC_SEQ_CST); + return; +} +#else +static inline void bump_global_region_count() { + global_region_count++; + return; +} +#endif + +static inline void print_global_region_count() { + printf("REGION_COUNT: %lld\n", global_region_count); + return; +} + +#define REDIRECTION_NODE_SIZE 9 +#define MAX(a,b) (((a)>(b))?(a):(b)) +#define MIN(a,b) (((a)<(b))?(a):(b)) + +// https://www.cprogramming.com/snippets/source-code/find-the-number-of-cpu-cores-for-windows-mac-or-linux +static int get_num_processors() { +#ifdef _WIN64 + SYSTEM_INFO sysinfo; + GetSystemInfo(&sysinfo); + return sysinfo.dwNumberOfProcessors; +#else + return sysconf(_SC_NPROCESSORS_ONLN); +#endif +} + +// Requires -std=gnu11 +int dbgprintf(const char *format, ...) { + int code = 0; + va_list args; + va_start(args, format); +#ifdef _DEBUG + code = vprintf(format, args); +#endif + va_end(args); + return code; +} + + +// ----------------------------------------------------------------------------- +// Allocators +// ----------------------------------------------------------------------------- + + +// ------------------------------------- +// Bump allocation for linked-lists +// ------------------------------------- + + +#ifdef _BUMPALLOC +// #define _DEBUG +#warning "Using bump allocator." + +__thread char* bumpalloc_heap_ptr = (char*)NULL; +__thread char* bumpalloc_heap_ptr_end = (char*)NULL; + +char* saved_heap_ptr_stack[100]; +int num_saved_heap_ptr = 0; + +// For simplicity just use a single large slab: +static inline void INITBUMPALLOC() { + bumpalloc_heap_ptr = (char*)malloc(global_init_biginf_buf_size); + bumpalloc_heap_ptr_end = bumpalloc_heap_ptr + global_init_biginf_buf_size; +#ifdef _DEBUG + printf("Arena size for bump alloc: %lld\n", global_init_biginf_buf_size); + printf("BUMPALLOC/INITBUMPALLOC DONE: heap_ptr = %p\n", bumpalloc_heap_ptr); +#endif +} + +static inline void* BUMPALLOC(long long n) { + if (! bumpalloc_heap_ptr) { + INITBUMPALLOC(); + } + if (bumpalloc_heap_ptr + n < bumpalloc_heap_ptr_end) { + char* old= bumpalloc_heap_ptr; + bumpalloc_heap_ptr += n; + return old; + } else { + fprintf(stderr, "Warning: bump allocator ran out of memory."); + exit(1); + } +} + +// Snapshot the current heap pointer value across all threads. +void save_alloc_state() { + dbgprintf("Saving(%p): pos %d", heap_ptr, num_saved_heap_ptr); + saved_heap_ptr_stack[num_saved_heap_ptr] = heap_ptr; + num_saved_heap_ptr++; + dbgprintf("\n"); +} + +void restore_alloc_state() { + if(num_saved_heap_ptr <= 0) { + fprintf(stderr, "Bad call to restore_alloc_state! Saved stack empty!\ne"); + exit(1); + } + num_saved_heap_ptr--; + dbgprintf("Restoring(%p): pos %d, discarding %p", + saved_heap_ptr_stack[num_saved_heap_ptr], num_saved_heap_ptr, bumpalloc_heap_ptr); + bumpalloc_heap_ptr = saved_heap_ptr_stack[num_saved_heap_ptr]; +} + + +#else +// Regular malloc mode: +void INITBUMPALLOC() {} +void save_alloc_state() {} +void restore_alloc_state() {} + +#define BUMPALLOC(n) malloc(n) + +#endif // BUMPALLOC + + +// ------------------------------------- +// ALLOC and ALLOC_PACKED macros +// ------------------------------------- + + +/* + +If parallelism is enabled, we always use a malloc based allocator +since Boehm GC is not thread-safe in its default configuration. It can be +made thread-safe by building it with appropriate flags, but we don't do that. +Presently, all parallel pointer-based programs will leak memory. + +*/ + +#ifdef _PARALLEL +#define ALLOC(n) malloc(n) +#define ALLOC_PACKED_BIG(n) malloc(n) +char *ALLOC_COUNTED(size_t size) { + bump_global_region_count(); + return ALLOC(size); +} +#else + #ifdef _POINTER +#define ALLOC(n) GC_MALLOC(n) +#define ALLOC_PACKED_BIG(n) GC_MALLOC(n) +char *ALLOC_COUNTED(size_t size) { + bump_global_region_count(); + return GC_MALLOC(size); +} + #else +#define ALLOC(n) malloc(n) +#define ALLOC_PACKED_BIG(n) malloc(n) +char *ALLOC_COUNTED(size_t size) { + bump_global_region_count(); + return ALLOC(size); +} + #endif // _POINTER +#endif // _PARALLEL + + +// Could try alloca() here. Better yet, we could keep our own, +// separate stack and insert our own code to restore the pointer +// before any function that (may have) called ALLOC_SCOPED returns. + +// #define ALLOC_SCOPED() alloca(1024) +#define ALLOC_SCOPED(n) alloca(n) +// #define ALLOC_SCOPED() alloc_scoped() + +// Stack allocation is either too small or blows our stack. +// We need a way to make a giant stack if we want to use alloca. +// #define ALLOC_SCOPED() ALLOC(global_init_biginf_buf_size) + +// Our global pointer. No parallelism. +// static char* stack_scoped_region; +// char* alloc_scoped() { return stack_scoped_region; } + + + +// ------------------------------------- +// Basic types +// ------------------------------------- + +// Must be consistent with sizeOfTy defined in Gibbon.Language.Syntax. + +typedef unsigned char TagTyPacked; +typedef unsigned char TagTyBoxed; +typedef long long IntTy; +typedef char CharTy; +typedef float FloatTy; +typedef unsigned long long SymTy; +typedef bool BoolTy; +typedef char* PtrTy; +typedef char* CursorTy; + +// ------------------------------------- +// Arenas and dictionaries +// ------------------------------------- + +typedef struct mem_arena { + int ind; + char* mem; // TODO(vollmerm): make this a list of chunks? + void* reflist; +} mem_arena_t; + +typedef mem_arena_t* ArenaTy; + +ArenaTy alloc_arena() { + ArenaTy ar = ALLOC(sizeof(mem_arena_t)); + ar->ind = 0; + ar->mem = malloc(global_inf_buf_max_chunk_size); + ar->reflist = 0; + return ar; +} + +void free_arena(ArenaTy ar) { + free(ar->mem); + // TODO(vollmerm): free everything in ar->reflist + free(ar); +} + +CursorTy extend_arena(ArenaTy ar, int size) { + CursorTy ret = ar->mem + ar->ind; + ar->ind += size; + return ret; +} + +typedef struct dict_item { + struct dict_item * next; + int key; + void * ptrval; +} dict_item_t; + +dict_item_t * dict_alloc(ArenaTy ar) { + return (dict_item_t *) extend_arena(ar, sizeof(dict_item_t)); // ALLOC(sizeof(dict_item_t)); +} + +dict_item_t *dict_insert_ptr(ArenaTy ar, dict_item_t *ptr, SymTy key, PtrTy val) { + dict_item_t *ret = dict_alloc(ar); + ret->key = key; + ret->ptrval = val; + ret->next = ptr; + return ret; +} + +PtrTy dict_lookup_ptr(dict_item_t *ptr, SymTy key) { + while (ptr != 0) { + if (ptr->key == key) { + return ptr->ptrval; + } else { + ptr = ptr->next; + } + } + printf("Error, key %lld not found!\n",key); + exit(1); +} + +// ------------------------------------- +// Sets +// ------------------------------------- + + +struct set_elem { + int val; + UT_hash_handle hh; +}; + +typedef struct set_elem* SymSetTy; + +SymSetTy empty_set() { + return NULL; +} + +SymSetTy insert_set(SymSetTy set, int sym) { + SymSetTy s; + HASH_FIND_INT(set, &sym, s); /* sym already in the hash? */ + if (s==NULL) { + s = malloc(sizeof(struct set_elem)); + s->val = sym; + HASH_ADD_INT(set,val,s); + } + return set; +} + +BoolTy contains_set(SymSetTy set, int sym) { + SymSetTy s; + HASH_FIND_INT(set, &sym, s); + return (s!=NULL); +} + +// ------------------------------------- +// Sym Hash +// ------------------------------------- + +struct sym_hash_elem { + int key; + int val; + UT_hash_handle hh; +}; + +typedef struct sym_hash_elem* SymHashTy; + +typedef struct sym_hash_elem* IntHashTy; + +SymHashTy empty_hash() { + return NULL; +} + +SymHashTy insert_hash(SymHashTy hash, int k, int v) { + SymHashTy s; + // NOTE: not checking for duplicates! + // s = malloc(sizeof(struct sym_hash_elem)); + s = ALLOC(sizeof(struct sym_hash_elem)); + s->val = v; + s->key = k; + HASH_ADD_INT(hash,key,s); + + return hash; +} + +IntTy lookup_hash(SymHashTy hash, int k) { + SymHashTy s; + HASH_FIND_INT(hash,&k,s); + if (s==NULL) { + return k; // NOTE: return original key if val not found + // TODO(vollmerm): come up with something better to do here + } else { + return s->val; + } +} + +BoolTy contains_hash(SymHashTy hash, int sym) { + SymHashTy s; + HASH_FIND_INT(hash,&sym,s); + return (s!=NULL); +} + +// ------------------------------------- +// Helpers +// ------------------------------------- + +char* read_benchfile_param() { + if (global_benchfile_param == NULL) { + fprintf(stderr, "read_benchfile_param: benchmark input file was not set! Set using --bench-input.\n"); + exit(1); + } else + return global_benchfile_param; +} + +char* read_arrayfile_param() { + if (global_arrayfile_param == NULL) { + fprintf(stderr, "read_arrayfile_param: array input file was not set! Set using --array-input.\n"); + exit(1); + } else + return global_arrayfile_param; +} + +IntTy read_arrayfile_length_param() { + if (global_arrayfile_length_param == -1) { + fprintf(stderr, "read_arrayfile_length_param: array input file length was not set! Set using --array-input-length.\n"); + exit(1); + } else + return global_arrayfile_length_param; +} + + +// fun fact: __ prefix is actually reserved and this is an undefined behavior. +// These functions must be provided by the code generator. +int __main_expr(); + + +void show_usage(char** argv) +{ + printf("\n"); + printf("This binary was generated by the Gibbon compiler.\n"); + printf("\n"); + printf("Usage: %s [OPTS] [size] [iters]\n", argv[0]); + + printf("\n"); + printf("Options:\n"); + printf(" --buffer-size Set the buffer size (default %lld).\n", global_init_biginf_buf_size); + printf(" --bench-input Set the input file read for benchmarking. Applies only\n"); + printf(" IF the program was *compiled* with --bench-fun. \n"); + return; +} + +double avg(const double* arr, int n) +{ + double sum = 0.0; + for(int i=0; itv_sec - t0->tv_sec) + + ((double)(t1->tv_nsec - t0->tv_nsec) / 1000000000.0); +} + +int compare_doubles(const void *a, const void *b) +{ + const double *da = (const double *) a; + const double *db = (const double *) b; + return (*da > *db) - (*da < *db); +} + +// Exponentiation +IntTy expll(IntTy base, IntTy pow) { + if (base == 2) { + return (1 << pow); + } else { + IntTy i, result = 1; + for (i = 0; i < pow; i++) + result *= base; + return result; + } + } + +// ------------------------------------- +// Symbol table +// ------------------------------------- + +#define global_max_symbol_len 256 + +// Invariant: should always be equal to max(sym_table_keys) +static SymTy global_gensym_counter = 0; + +// Its value is updated by the flags parser. +static char *global_bench_prog_param; + +static SymTy newline_symbol = -1; +static SymTy space_symbol = -1; +static SymTy comma_symbol = -1; +static SymTy leftparen_symbol = -1; +static SymTy rightparen_symbol = -1; + +typedef struct SymTable_elem { + SymTy idx; /* key */ + char value[global_max_symbol_len]; + UT_hash_handle hh; /* makes this structure hashable */ +} SymTable_elem; + +// important! initialize to NULL +SymTable_elem *global_sym_table = NULL; + +void add_symbol(SymTy idx, char *value) { + struct SymTable_elem *s; + s = ALLOC(sizeof(struct SymTable_elem)); + s->idx = idx; + strcpy(s->value, value); + HASH_ADD(hh, global_sym_table, idx, sizeof(IntTy), s); + if (idx > global_gensym_counter) { + global_gensym_counter = idx; + } +} + +void set_newline(SymTy idx) { + newline_symbol = idx; + add_symbol(idx,"NEWLINE"); +} + +void set_space(SymTy idx) { + space_symbol = idx; + add_symbol(idx,"SPACE"); +} + +void set_comma(SymTy idx) { + comma_symbol = idx; + add_symbol(idx,"COMMA"); +} + +void set_leftparen(SymTy idx) { + leftparen_symbol = idx; + add_symbol(idx,"LEFTPAREN"); +} + +void set_rightparen(SymTy idx) { + rightparen_symbol = idx; + add_symbol(idx,"RIGHTPAREN"); +} + +IntTy print_symbol(SymTy idx) { + if (idx == comma_symbol) { + return printf(","); + } else if (idx == newline_symbol) { + return printf("\n"); + } else if (idx == space_symbol) { + return printf(" "); + } else if (idx == leftparen_symbol) { + return printf("("); + } else if (idx == rightparen_symbol) { + return printf(")"); + } else { + struct SymTable_elem *s; + HASH_FIND(hh, global_sym_table, &idx, sizeof(SymTy), s); + if (s == NULL) { + return printf("%lld", idx); + } else { + return printf("%s", s->value); + } + + } +} + +#ifdef _PARALLEL +SymTy gensym() { + SymTy idx = __atomic_add_fetch(&global_gensym_counter, 1, __ATOMIC_SEQ_CST); + return idx; +} +#else +SymTy gensym() { + global_gensym_counter += 1; + SymTy idx = global_gensym_counter; + return idx; +} +#endif + +void free_symtable() { + struct SymTable_elem *elt, *tmp; + HASH_ITER(hh, global_sym_table, elt, tmp) { + HASH_DEL(global_sym_table,elt); + } + free(elt); + free(tmp); +} + +/* + +---------------------------------------- +Garbage collection +---------------------------------------- + + Gibbon has "growing regions" i.e each logical region is backed by a doubly linked-list + of smaller chunks which grows as required. In addition to actual data, each chunk + stores some additional metadata (RegionFooter) to chain the chunks together in a list + and for garbage collection. The footer: + + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + serialized data | rf_reg_metadata_ptr | rf_seq_no | rf_size | rf_next | rf_prev + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + The metadata after the serialized data serves various purposes: + + - rf_reg_metadata_ptr: A pointer to a RegionTy struct that contains various metadata. + Of particular interest to us are the fields: + + = reg_id: A unique identifier for a region. + + = refcount and outset: Whenever an inter-region indirection is created, we record that information + using these two fields. Suppose we have an indirection from region A that points to some chunk + in region B. Then A's outset will store a pointer to that chunk's footer, and B's refcount will + be bumped by 1. Note that all there's only 1 refcount cell, and 1 outset per logical region, + and chunks only store a pointer to them. + + - rf_seq_no: The index of this particular chunk in the list. + + - rf_size: Used during bounds checking to calculate the size of the next region in + the linked list. + + - rf_next / rf_prev: Point to the next and previous chunk respectively. + + +There are two ways in which a region may be freed: + +(1) Whenever it goes out of scope + + The RTS tries to free a region whenever it goes out of scope. But this doesn't always succeed as + regions sometimes contain values that "escape". One reason why this'll happen is if there's an + indirection from A->B, and A lives longer than B. + In such a case, when B goes out of scope it's refcount won't be 0, and the RTS won't free it. + This brings us to (2). + +(2) + + When the RTS successfully frees a region, it decrements the refcounts of all the regions it + points to (via the outset). At the same time, if it encounters a region in the outset whoose + refcount becomes 0 after the decrement, it calls free_region on that. This way we can be sure + that all regions will eventually be garbage collected before the program exits. + + + +Why is it a doubly linked-list? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Due to way that bounds-checking works, the pointers in the outset may actually point to any +arbitrary chunk in the chain. However, we must call free_region on the first one to ensure that +all of them are GC'd. So we need pointers to traverse backward get to the first one. +'trav_to_first_chunk' accomplishes this. + + */ + +#define MAX_OUTSET_LENGTH 10 + +typedef struct RegionTy_struct { + SymTy reg_id; + uint reg_refcount; + CursorTy reg_heap; + uint reg_outset_len; + CursorTy reg_outset[MAX_OUTSET_LENGTH]; +} RegionTy; + +typedef struct RegionFooter_struct { + RegionTy *rf_reg_metadata_ptr; + + IntTy rf_seq_no; + IntTy rf_size; + struct RegionFooter_struct *rf_next; + struct RegionFooter_struct *rf_prev; +} RegionFooter; + +typedef struct ChunkTy_struct { + CursorTy chunk_start; + CursorTy chunk_end; +} ChunkTy; + +static inline void insert_into_outset(CursorTy ptr, RegionTy *reg) { + uint outset_len = reg->reg_outset_len; + // Check for duplicates. + for (uint i = 0; i < outset_len; i++) { + if (ptr == reg->reg_outset[i]) { + return; + } + } + // Otherwise, insert into the outset. + reg->reg_outset[outset_len] = ptr; + reg->reg_outset_len = outset_len + 1; + return; +} + +static inline void remove_from_outset(CursorTy ptr, RegionTy *reg) { + uint outset_len = reg->reg_outset_len; + CursorTy *outset = reg->reg_outset; + int i; + if (outset_len == 0) { + fprintf(stderr, "remove_from_outset: empty outset\n"); + exit(1); + } + // Position of 'ptr' in the outset. + int elt_idx = -1; + for (i = 0; i < outset_len; i++) { + if (ptr == outset[i]) { + elt_idx = i; + } + } + if (elt_idx == -1) { + fprintf(stderr, "remove_from_outset: element not found\n"); + exit(1); + } + // Move all elements ahead of 'elt_idx' back by one position. + for (i = elt_idx; i < outset_len; i++) { + outset[i] = outset[i+1]; + } + return; +} + +RegionTy *alloc_region(IntTy size) { + // Allocate the region metadata. + RegionTy *reg = ALLOC(sizeof(RegionTy)); + if (reg == NULL) { + printf("alloc_region: allocation failed: %ld", sizeof(RegionTy)); + exit(1); + } + + // Allocate the first chunk. + IntTy total_size = size + sizeof(RegionFooter); + CursorTy heap = ALLOC_PACKED_BIG(total_size); + if (heap == NULL) { + printf("alloc_region: malloc failed: %lld", total_size); + exit(1); + } + // Not heap+total_size, since we must keep space for the footer. + CursorTy heap_end = heap + size; + + // Initialize metadata fields. + reg->reg_id = gensym(); + reg->reg_refcount = 1; + reg->reg_heap = heap; + reg->reg_outset_len = 0; + +#ifdef _DEBUG + printf("Allocated a region(%lld): %lld bytes.\n", reg->reg_id, size); +#endif + + // Write the footer. + RegionFooter *footer = (RegionFooter *) heap_end; + footer->rf_reg_metadata_ptr = reg; + footer->rf_seq_no = 1; + footer->rf_size = size; + footer->rf_next = NULL; + footer->rf_prev = NULL; + + return reg; +} + +RegionTy *alloc_counted_region(IntTy size) { + // Bump the count. + bump_global_region_count(); + return alloc_region(size); +} + +ChunkTy alloc_chunk(CursorTy end_old_chunk) { + // Get size from current footer. + RegionFooter *footer = (RegionFooter *) end_old_chunk; + IntTy newsize = footer->rf_size * 2; + // See #110. + if (newsize > global_inf_buf_max_chunk_size) { + newsize = global_inf_buf_max_chunk_size; + } + IntTy total_size = newsize + sizeof(RegionFooter); + + // Allocate. + CursorTy start = ALLOC_PACKED_BIG(total_size); + if (start == NULL) { + printf("alloc_chunk: malloc failed: %lld", total_size); + exit(1); + } + CursorTy end = start + newsize; + + // Link the next chunk's footer. + footer->rf_next = (RegionFooter *) end; + + // Write the footer. + RegionFooter* new_footer = (RegionFooter *) end; + new_footer->rf_reg_metadata_ptr = footer->rf_reg_metadata_ptr; + new_footer->rf_seq_no = footer->rf_seq_no + 1; + new_footer->rf_size = newsize; + new_footer->rf_next = NULL; + new_footer->rf_prev = footer; + +#ifdef _DEBUG + RegionTy *reg = (RegionTy*) new_footer->rf_reg_metadata_ptr; + printf("alloc_chunk: allocated %lld bytes for region %lld.\n", total_size, reg->reg_id); +#endif + + return (ChunkTy) {start , end}; +} + +RegionFooter* trav_to_first_chunk(RegionFooter *footer) { + if (footer->rf_seq_no == 1) { + return footer; + } else if (footer->rf_prev == NULL) { + fprintf(stderr, "No previous chunk found at rf_seq_no: %lld", footer->rf_seq_no); + return NULL; + } else { + trav_to_first_chunk((RegionFooter *) footer->rf_prev); + } + return NULL; +} + +uint get_ref_count(CursorTy end_ptr) { + RegionFooter *footer = (RegionFooter *) end_ptr; + RegionTy *reg = (RegionTy *) footer->rf_reg_metadata_ptr; + return reg->reg_refcount; +} + +// B is the pointer, and A is the pointee (i.e B -> A). +// Bump A's refcount and update B's outset. +static inline void bump_ref_count(CursorTy end_b, CursorTy end_a) { + // Grab footers. + RegionFooter *footer_a = (RegionFooter *) end_a; + RegionFooter *footer_b = (RegionFooter *) end_b; + + // Grab metadata. + RegionTy *reg_a = (RegionTy *) footer_a->rf_reg_metadata_ptr; + RegionTy *reg_b = (RegionTy *) footer_b->rf_reg_metadata_ptr; + + // Bump A's refcount. + uint current_refcount, new_refcount; + current_refcount = reg_a->reg_refcount; + new_refcount = current_refcount + 1; + reg_a->reg_refcount = new_refcount; + +#ifdef _DEBUG + printf("bump_ref_count: %lld -> %lld\n", reg_b->reg_id, reg_a->reg_id); + printf("bump_ref_count: old-refcount=%d, old-outset-len=%d:\n", current_refcount, reg_b->reg_outset_len); + assert(current_refcount == reg_b->reg_outset_len+1); +#endif + + // Add A to B's outset. + insert_into_outset(end_a, reg_b); + +#ifdef _DEBUG + // printf("bump_ref_count: Added %p to %lld's outset, %p.\n", end_a, reg_b->reg_id, reg_b); + printf("bump_ref_count: new-refcount=%d, new-outset-len=%d\n", new_refcount, reg_b->reg_outset_len); + assert(new_refcount == reg_b->reg_outset_len+1); +#endif + + return; +} + +void free_region(CursorTy end_reg) { + // Grab footer and the metadata. + RegionFooter *footer = (RegionFooter *) end_reg; + RegionTy *reg = (RegionTy *) footer->rf_reg_metadata_ptr; + + // + RegionFooter *first_chunk_footer, *next_chunk_footer; + CursorTy first_chunk, next_chunk; + + // Decrement current reference count. + uint current_refcount, new_refcount; + current_refcount = reg->reg_refcount; + new_refcount = 0; + if (current_refcount != 0) { + new_refcount = current_refcount - 1; + reg->reg_refcount = new_refcount; + } + +#ifdef _DEBUG + printf("free_region(%lld): refcounts (1): old-refcount=%d, new-refcount=%d:\n", reg->reg_id, current_refcount, new_refcount); +#endif + + + // Free this region recount is 0. + if (new_refcount == 0) { + +#ifdef _DEBUG + printf("free_region(%lld): outset length: %d\n", reg->reg_id, reg->reg_outset_len); +#endif + + // Decrement refcounts, free regions with refcount==0 and also free + // elements of the outset. + if (reg->reg_outset_len != 0) { + uint outset_len = reg->reg_outset_len; + CursorTy *outset = reg->reg_outset; + RegionFooter *elt_footer; + RegionTy *elt_reg; + uint elt_current_refcount, elt_new_refcount; + CursorTy to_be_removed[MAX_OUTSET_LENGTH]; + uint to_be_removed_idx = 0; + for (int i = 0; i < outset_len; i++) { + elt_footer = (RegionFooter *) outset[i]; + elt_reg = (RegionTy *) elt_footer->rf_reg_metadata_ptr; +#ifdef _DEBUG + elt_current_refcount = elt_reg->reg_refcount; +#endif + elt_new_refcount = elt_current_refcount - 1; + elt_reg->reg_refcount = elt_new_refcount; +#ifdef _DEBUG + printf("free_region(%lld): old-refcount=%d, new-refcount=%d:\n", + elt_reg->reg_id, elt_current_refcount, elt_reg->reg_refcount); +#endif + if (elt_new_refcount == 0) { + // See [Why is it a doubly linked-list?] above + first_chunk_footer = trav_to_first_chunk(elt_footer); + if (first_chunk_footer != NULL) { + free_region((CursorTy) first_chunk_footer); + } + } + to_be_removed[to_be_removed_idx] = outset[i]; + to_be_removed_idx++; + } + // Remove elements from the outset. + for (uint i = 0; i < to_be_removed_idx; i++) { + remove_from_outset(to_be_removed[i], reg); + } + } + + +#ifdef _DEBUG + // Bookkeeping + IntTy num_freed_chunks = 0, total_bytesize = 0; +#endif + + // Free the chunks in this region. + first_chunk = end_reg - footer->rf_size; + first_chunk_footer = footer; + next_chunk = (char*) footer->rf_next; + +#ifdef _DEBUG + printf("free_region(%lld)\n", reg->reg_id); +#endif + +#ifdef _DEBUG + num_freed_chunks++; + total_bytesize = total_bytesize + first_chunk_footer->rf_size; +#endif + free(first_chunk); + + while (next_chunk != NULL) { + next_chunk_footer = (RegionFooter *) next_chunk; + #ifdef _DEBUG + num_freed_chunks++; + total_bytesize = total_bytesize + next_chunk_footer->rf_size; + #endif + free(next_chunk - next_chunk_footer->rf_size); + next_chunk = (char*) next_chunk_footer->rf_next; + } + +#ifdef _DEBUG + printf("free_region(%lld): Freed %lld bytes across %lld chunks.\n", + reg->reg_id, total_bytesize, num_freed_chunks); +#endif + + // Free the metadata. + free(reg); + + } else { +#ifdef _DEBUG + printf("free_region(%lld): non-zero refcount: %d.\n", + reg->reg_id, reg->reg_refcount); +#endif + } +} + +// Assume that all nodes with size information have tags >= 150. +BoolTy is_big(IntTy i, CursorTy cur) { + TagTyPacked tag = *(TagTyPacked *) cur; + if (tag >= 150) { + cur += 1; + IntTy size = *(IntTy *) cur; + if (size >= i) { + return true; + } else { + return false; + } + } + return false; +} + +// ------------------------------------- +// Vectors +// ------------------------------------- + +typedef struct VectorTy_struct { + // Bounds on the vector. + IntTy vec_lower, vec_upper; + + // Size of each element. + IntTy vec_elt_size; + + // Actual elements of the vector. + void* vec_data; +} VectorTy; + +VectorTy* vector_alloc(IntTy num, IntTy elt_size) { + VectorTy *vec = ALLOC(sizeof(VectorTy)); + if (vec == NULL) { + printf("alloc_vector: malloc failed: %ld", sizeof(VectorTy)); + exit(1); + } + void* data = ALLOC(num * elt_size); + if (data == NULL) { + printf("alloc_vector: malloc failed: %ld", sizeof(num * elt_size)); + exit(1); + } + vec->vec_lower = 0; + vec->vec_upper = num; + vec->vec_elt_size = elt_size; + vec->vec_data = data; + return vec; +} + +IntTy vector_length(VectorTy *vec) { + return (vec->vec_upper - vec->vec_lower); +} + +BoolTy vector_is_empty(VectorTy *vec) { + return (vector_length(vec) == 0); +} + +VectorTy* vector_slice(IntTy i, IntTy n, VectorTy *vec) { + IntTy lower = vec->vec_lower + i; + IntTy upper = vec->vec_lower + i + n; + if ((lower > vec->vec_upper)) { + printf("vector_slice: lower out of bounds, %lld > %lld", lower, vec->vec_upper); + exit(1); + } + if ((upper > vec->vec_upper)) { + printf("vector_slice: upper out of bounds: %lld > %lld", upper, vec->vec_upper); + exit(1); + } + VectorTy *vec2 = ALLOC(sizeof(VectorTy)); + if (vec == NULL) { + printf("vector_slice: malloc failed: %ld", sizeof(VectorTy)); + exit(1); + } + vec2->vec_lower = lower; + vec2->vec_upper = upper; + vec2->vec_elt_size = vec->vec_elt_size; + vec2->vec_data = vec->vec_data; + return vec2; +} + +// The callers must cast the return value. +static inline void* vector_nth(VectorTy *vec, IntTy i) { + // if (i < vec->lower || i > vec->upper) { + // printf("vector_nth index out of bounds: %lld (%lld,%lld) \n", i, vec->vec_lower, vec->vec_upper); + // exit(1); + // } + return (vec->vec_data + (vec->vec_elt_size * (vec->vec_lower + i))); +} + +static inline VectorTy* vector_inplace_update(VectorTy *vec, IntTy i, void* elt) { + void* dst = vector_nth(vec, i); + memcpy(dst, elt, vec->vec_elt_size); + return vec; +} + +static inline VectorTy* vector_copy(VectorTy *vec) { + IntTy len = vector_length(vec); + void *start = vector_nth(vec, 0); + VectorTy *vec2 = vector_alloc(len, vec->vec_elt_size); + memcpy(vec2->vec_data, start, len * vec->vec_elt_size); + return vec2; +} + +static inline VectorTy* vector_inplace_sort(VectorTy *vec, int (*compar)(const void *, const void*)) { + void *start = vector_nth(vec, 0); + qsort(start, vector_length(vec), vec->vec_elt_size, compar); + return vec; +} + +static inline VectorTy* vector_sort(VectorTy *vec, int (*compar)(const void *, const void*)) { + VectorTy *vec2 = vector_copy(vec); + vector_inplace_sort(vec2, compar); + return vec2; +} + +static inline VectorTy* vector_concat(VectorTy *vec) { + // Length of the input vector. + IntTy len = vector_length(vec); + // Length of the concatenated vector. + IntTy result_len = 0; + // Size of each element in the concatenated vector. + IntTy result_elt_size = 0; + VectorTy **elt_ref, *elt; + for (IntTy i = 0; i < len; i++) { + elt_ref = vector_nth(vec, i); + elt = *elt_ref; + result_elt_size = elt->vec_elt_size; + result_len += vector_length(elt); + } + + // Concatenated vector. + VectorTy *result = vector_alloc(result_len, result_elt_size); + IntTy elt_len; + // A counter that tracks the index of elements in 'result'. + IntTy k = 0; + for (IntTy i = 0; i < len; i++) { + elt_ref = vector_nth(vec, i); + elt = *elt_ref; + elt_len = vector_length(elt); + + for (IntTy j = 0; j < elt_len; j++) { + void* k_elt = vector_nth(elt, j); + vector_inplace_update(result, k, k_elt); + k++; + } + } + + return result; +} + +static inline void vector_free(VectorTy *vec) { + free(vec->vec_data); + free(vec); + return; +} + +static inline VectorTy* vector_merge(VectorTy *vec1, VectorTy *vec2) { + if (vec1->vec_upper != vec2->vec_lower) { + printf("vector_merge: non-contiguous slices, (%lld,%lld), (%lld,%lld).", + vec1->vec_lower, vec1->vec_upper, vec2->vec_lower, vec2->vec_upper); + exit(1); + } + VectorTy *merged = ALLOC(sizeof(VectorTy)); + if (merged == NULL) { + printf("vector_merge: malloc failed: %ld", sizeof(VectorTy)); + exit(1); + } + merged->vec_lower = vec1->vec_lower; + merged->vec_upper = vec2->vec_upper; + merged->vec_elt_size = vec1->vec_elt_size; + merged->vec_data = vec1->vec_data; + return merged; +} + +void print_timing_array(VectorTy *times) { + printf("TIMES: ["); + double *d; + IntTy n = vector_length(times); + for(int i = 0; i < n; i++) { + d = vector_nth(times, i); + if (i == (n-1)) { + printf("%f",*d); + } + else { + printf("%f, ",*d); + } + } + printf("]\n"); +} + +double sum_timing_array(VectorTy *times) { + double *d; + double acc = 0; + for(int i = 0; i < vector_length(times); i++) { + d = vector_nth(times, i); + acc += *d; + } + return acc; +} + +// ------------------------------------- +// Linked lists +// ------------------------------------- + +typedef struct ListTy_struct { + IntTy ll_data_size; + void* ll_data; + struct ListTy_struct* ll_next; +} ListTy; + +static inline ListTy* list_alloc(IntTy data_size) { + // ListTy *ls = ALLOC(sizeof(ListTy)); + ListTy *ls = BUMPALLOC(sizeof(ListTy)); + ls->ll_data_size = data_size; + ls->ll_data = NULL; + ls->ll_next = NULL; + return ls; +} + +static inline BoolTy list_is_empty(ListTy *ls) { + return ls->ll_next == NULL; +} + +static inline ListTy* list_cons(void* elt, ListTy *ls) { + // void* data = ALLOC(ls->data_size); + void* data = BUMPALLOC(ls->ll_data_size); + if (data == NULL) { + printf("list_cons: malloc failed: %lld", ls->ll_data_size); + exit(1); + } + memcpy(data, elt, ls->ll_data_size); + // ListTy *res = ALLOC(sizeof(ListTy)); + ListTy *res = BUMPALLOC(sizeof(ListTy)); + res->ll_data_size = ls->ll_data_size; + res->ll_data = data; + res->ll_next = (ListTy*) ls; + return res; +} + +static inline void* list_head(ListTy *ls) { + return ls->ll_data; +} + +static inline ListTy* list_tail(ListTy *ls) { + return ls->ll_next; +} + +static inline void list_free(ListTy *ls) { + free(ls->ll_data); + free(ls); + return; +} + +static inline ListTy* list_copy(ListTy *ls) { + ListTy *ls2 = list_alloc(ls->ll_data_size); + if (ls->ll_data != NULL) { + void* data = BUMPALLOC(ls->ll_data_size); + memcpy(data, ls->ll_data, ls->ll_data_size); + ls2->ll_data = data; + } + ls2->ll_next = ls->ll_next; + return ls2; +} + +// ------------------------------------- +// Ppm Images +// ------------------------------------- + +typedef struct __Pixel_struct { + IntTy field0; + IntTy field1; + IntTy field2; +} __Pixel; + +void writePpm(char* filename, IntTy width, IntTy height, VectorTy *pixels); +void writePpm_loop(FILE *fp, IntTy idx, IntTy end, VectorTy *pixels); + +// Example: writePpm("gibbon_rgb_1000.ppm", 1000, 1000, pixels); +void writePpm(char* filename, IntTy width, IntTy height, VectorTy *pixels) +{ + FILE *fp; + fp = fopen(filename, "w+"); + fprintf(fp, "P3\n"); + fprintf(fp, "%lld %lld\n255\n", width, height); + IntTy len = vector_length(pixels); + writePpm_loop(fp, 0, len, pixels); + fclose(fp); + return; +} + +void writePpm_loop(FILE *fp, IntTy idx, IntTy end, VectorTy *pixels) +{ + BoolTy fltIf_5768_6575 = idx == end; + + if (fltIf_5768_6575) { + return; + } else { + __Pixel *tmp_112; + tmp_112 = (__Pixel *) vector_nth(pixels, idx); + __Pixel tup = *tmp_112; + IntTy x = tup.field0; + IntTy y = tup.field1; + IntTy z = tup.field2; + // write to file. + fprintf(fp, "%lld %lld %lld\n", x, y, z); + writePpm_loop(fp, (idx+1), end, pixels); + } +} + +/* -------------------------------------------------------------------------------- */ + +int main(int argc, char** argv) +{ + // parameters to parse: + // + // num iterations: How many times to repeat a benchmark. + // tree size: An integer passes to `build_tree()`. + + struct rlimit lim; + int code; + if ( (code = getrlimit(RLIMIT_STACK, &lim)) ) { + fprintf(stderr, " [gibbon rts] failed to getrlimit, code %d\n", code); + exit(1); + } + + // lim.rlim_cur = 1024LU * 1024LU * 1024LU; // 1GB stack. + lim.rlim_cur = 512LU * 1024LU * 1024LU; // 500MB stack. + // lim.rlim_max = lim.rlim_cur; // Normal users may only be able to decrease this. + + // WARNING: Haven't yet figured out why this doesn't work on MacOS... +#ifndef __APPLE__ + code = setrlimit(RLIMIT_STACK, &lim); + while (code) { + fprintf(stderr, " [gibbon rts] Failed to set stack size to %llu, code %d\n", (unsigned long long)lim.rlim_cur, code); + lim.rlim_cur /= 2; + // lim.rlim_max /= 2; + if(lim.rlim_cur < 100 * 1024) { + fprintf(stderr, " [gibbon rts] Failed setrlimit stack size to something reasonable; giving up.\n"); + break; // abort(); + } + int code = setrlimit(RLIMIT_STACK, &lim); + } +#endif + + int got_numargs = 0; // How many numeric arguments have we got. + + int i; + for (i = 1; i < argc; ++i) + { + if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) { + show_usage(argv); + exit(0); + } + else if (strcmp(argv[i], "--biginf-buffer-size") == 0 && i < argc - 1) + { + global_init_biginf_buf_size = atoll(argv[i + 1]); + i++; + } + else if (strcmp(argv[i], "--inf-buffer-size") == 0 && i < argc - 1) + { + global_init_inf_buf_size = atoll(argv[i + 1]); + i++; + } + else if ((strcmp(argv[i], "--bench-input") == 0)) { + if (i+1 >= argc) { + fprintf(stderr, "Not enough arguments after --bench-input, expected .\n"); + show_usage(argv); + exit(1); + } + global_benchfile_param = argv[i+1]; + i++; + } + else if ((strcmp(argv[i], "--array-input") == 0)) { + if (i+1 >= argc) { + fprintf(stderr, "Not enough arguments after --array-input, expected .\n"); + show_usage(argv); + exit(1); + } + global_arrayfile_param = argv[i+1]; + i++; + } + else if (strcmp(argv[i], "--array-input-length") == 0 && i < argc - 1) { + global_arrayfile_length_param = atoll(argv[i+1]); + i++; + } + else if (strcmp(argv[i], "--bench-prog") == 0 && i < argc - 1) { + int len = strlen(argv[i+1]); + global_bench_prog_param = (char*) malloc((len+1)*sizeof(char)); + strncpy(global_bench_prog_param,argv[i+1],len); + i++; + } + // If present, we expect the two arguments to be + else if (got_numargs >= 2) { + fprintf(stderr, "Extra arguments left over: "); + for(; i < argc; i++) fprintf(stderr, "%s ", argv[i]); + show_usage(argv); + exit(1); + } else { + if (got_numargs == 0) { + global_size_param = atoll(argv[i]); + got_numargs ++; + } else { + global_iters_param = atoll(argv[i]); + } + } + } + + // Initialize global_bench_prog_param to an empty string in case + // the runtime argument --bench-prog isn't passed. + if (global_bench_prog_param == NULL) { + global_bench_prog_param = (char*) malloc(1*sizeof(char)); + *global_bench_prog_param = '\n'; + } + + __main_expr(); + + return 0; +} + +// ----------------------------------------------------------------------------- +// Program starts here +// ----------------------------------------------------------------------------- + +typedef struct Prod_struct { } Prod; +typedef struct Int64Prod_struct { + IntTy field0; + } Int64Prod; +typedef struct Int64Int64Int64CursorCursorProd_struct { + IntTy field0; + IntTy field1; + IntTy field2; + CursorTy field3; + CursorTy field4; + } Int64Int64Int64CursorCursorProd; +typedef struct Int64Int64CursorCursorProd_struct { + IntTy field0; + IntTy field1; + CursorTy field2; + CursorTy field3; + } Int64Int64CursorCursorProd; +typedef struct BoolProd_struct { + BoolTy field0; + } BoolProd; +typedef struct TagCursorProd_struct { + TagTyPacked field0; + CursorTy field1; + } TagCursorProd; +typedef struct CursorProd_struct { + CursorTy field0; + } CursorProd; +CursorTy empty(); +IntTy sum(CursorTy s_194_600_930); +CursorTy insert_num(IntTy x_199_605_938, CursorTy s_200_606_939); +CursorTy right(CursorTy x_201_607_943); +CursorTy left(CursorTy x_206_612_948); +IntTy val(CursorTy x_211_617_953); +IntTy size(CursorTy s_216_622_958); +CursorTy balanceR(IntTy x_232_638_963, CursorTy l_233_639_964, + CursorTy r_234_640_965); +CursorTy balanceL(IntTy x_259_645_970, CursorTy l_260_646_971, + CursorTy r_261_647_972); +CursorTy insert(IntTy x_286_652_977, CursorTy s_287_653_978); +CursorTy singleton(IntTy x_294_660_987); +CursorTy _copy_without_ptrs_IntSet(CursorTy arg_512_661_990); +CursorTy _copy_IntSet(CursorTy arg_503_670_999); +unsigned char _traverse_IntSet(CursorTy arg_521_679_1008); +unsigned char _print_IntSet(CursorTy arg_530_686_1015); +CursorTy caseFn_547(IntTy x_232_548_703_1032, CursorTy rr_238_549_704_1033, + IntTy rx_236_550_705_1034, IntTy rs_235_551_706_1035, + CursorTy rl_237_552_707_1036); +CursorTy caseFn_553(IntTy x_232_554_712_1068, CursorTy r_234_555_713_1069, + IntTy rx_236_556_714_1070, CursorTy rl_237_557_715_1071); +CursorTy caseFn_558(IntTy x_232_559_720_1084, CursorTy r_234_560_721_1085, + CursorTy rr_238_561_722_1086, IntTy rx_236_562_723_1087, + IntTy rs_235_563_724_1088, CursorTy rl_237_564_725_1089); +CursorTy caseFn_565(IntTy x_232_566_730_1094, CursorTy r_234_567_731_1095); +CursorTy caseFn_568(CursorTy l_233_569_736_1102, IntTy x_232_570_737_1103, + CursorTy r_234_571_738_1104, IntTy ls_251_572_739_1105); +CursorTy caseFn_573(IntTy x_259_574_744_1142, CursorTy ll_264_575_745_1143, + IntTy lx_263_576_746_1144, IntTy ls_262_577_747_1145, + CursorTy lr_265_578_748_1146, IntTy lls_266_579_749_1147); +CursorTy caseFn_580(CursorTy l_260_581_754_1170, IntTy x_259_582_755_1171, + IntTy lx_263_583_756_1172, CursorTy lr_265_584_757_1173); +CursorTy caseFn_585(CursorTy l_260_586_762_1185, IntTy x_259_587_763_1186, + CursorTy ll_264_588_764_1187, IntTy lx_263_589_765_1188, + IntTy ls_262_590_766_1189, CursorTy lr_265_591_767_1190); +CursorTy caseFn_592(CursorTy l_260_593_772_1195, IntTy x_259_594_773_1196); +CursorTy caseFn_595(CursorTy r_261_596_778_1203, CursorTy l_260_597_779_1204, + IntTy x_259_598_780_1205, IntTy rs_278_599_781_1206); +CursorTy empty() +{ + PtrTy tailift_1248 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) tailift_1248)->field0 = 1; + return tailift_1248; +} +IntTy sum(CursorTy s_194_600_930) +{ + TagTyPacked tag_1249 = *(TagTyPacked *) s_194_600_930; + CursorTy tail_1250 = s_194_600_930 + sizeof(IntTy); + + + switch_1252: + ; + switch (tag_1249) { + + case 1: + { + return 0; + break; + } + + case 0: + { + IntTy wildcard__188_195_601_931 = + ((Int64Int64CursorCursorProd *) tail_1250)->field0; + IntTy v_196_602_932 = + ((Int64Int64CursorCursorProd *) tail_1250)->field1; + CursorTy l_197_603_933 = + ((Int64Int64CursorCursorProd *) tail_1250)->field2; + CursorTy r_198_604_934 = + ((Int64Int64CursorCursorProd *) tail_1250)->field3; + IntTy fltPrm_790_935 = sum(l_197_603_933); + IntTy fltPrm_789_936 = v_196_602_932 + fltPrm_790_935; + IntTy fltPrm_791_937 = sum(r_198_604_934); + IntTy flt_1251 = fltPrm_789_936 + fltPrm_791_937; + + return flt_1251; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1249"); + exit(1); + } + } +} +CursorTy insert_num(IntTy x_199_605_938, CursorTy s_200_606_939) +{ + BoolTy fltIf_792_940 = x_199_605_938 == 0; + + if (fltIf_792_940) { + return insert(x_199_605_938, s_200_606_939); + } else { + IntTy fltAppE_794_941 = x_199_605_938 - 1; + CursorTy fltAppE_793_942 = insert_num(fltAppE_794_941, s_200_606_939); + + return insert(x_199_605_938, fltAppE_793_942); + } +} +CursorTy right(CursorTy x_201_607_943) +{ + TagTyPacked tag_1253 = *(TagTyPacked *) x_201_607_943; + CursorTy tail_1254 = x_201_607_943 + sizeof(IntTy); + + + switch_1256: + ; + switch (tag_1253) { + + case 1: + { + PtrTy tailift_1255 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) tailift_1255)->field0 = 1; + return tailift_1255; + break; + } + + case 0: + { + IntTy wildcard__178_202_608_944 = + ((Int64Int64CursorCursorProd *) tail_1254)->field0; + IntTy wildcard__179_203_609_945 = + ((Int64Int64CursorCursorProd *) tail_1254)->field1; + CursorTy wildcard__180_204_610_946 = + ((Int64Int64CursorCursorProd *) tail_1254)->field2; + CursorTy r_205_611_947 = + ((Int64Int64CursorCursorProd *) tail_1254)->field3; + + return r_205_611_947; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1253"); + exit(1); + } + } +} +CursorTy left(CursorTy x_206_612_948) +{ + TagTyPacked tag_1257 = *(TagTyPacked *) x_206_612_948; + CursorTy tail_1258 = x_206_612_948 + sizeof(IntTy); + + + switch_1260: + ; + switch (tag_1257) { + + case 1: + { + PtrTy tailift_1259 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) tailift_1259)->field0 = 1; + return tailift_1259; + break; + } + + case 0: + { + IntTy wildcard__169_207_613_949 = + ((Int64Int64CursorCursorProd *) tail_1258)->field0; + IntTy wildcard__170_208_614_950 = + ((Int64Int64CursorCursorProd *) tail_1258)->field1; + CursorTy l_209_615_951 = + ((Int64Int64CursorCursorProd *) tail_1258)->field2; + CursorTy wildcard__171_210_616_952 = + ((Int64Int64CursorCursorProd *) tail_1258)->field3; + + return l_209_615_951; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1257"); + exit(1); + } + } +} +IntTy val(CursorTy x_211_617_953) +{ + TagTyPacked tag_1261 = *(TagTyPacked *) x_211_617_953; + CursorTy tail_1262 = x_211_617_953 + sizeof(IntTy); + + + switch_1263: + ; + switch (tag_1261) { + + case 1: + { + return 0; + break; + } + + case 0: + { + IntTy wildcard__160_212_618_954 = + ((Int64Int64CursorCursorProd *) tail_1262)->field0; + IntTy v_213_619_955 = + ((Int64Int64CursorCursorProd *) tail_1262)->field1; + CursorTy wildcard__161_214_620_956 = + ((Int64Int64CursorCursorProd *) tail_1262)->field2; + CursorTy wildcard__162_215_621_957 = + ((Int64Int64CursorCursorProd *) tail_1262)->field3; + + return v_213_619_955; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1261"); + exit(1); + } + } +} +IntTy size(CursorTy s_216_622_958) +{ + TagTyPacked tag_1264 = *(TagTyPacked *) s_216_622_958; + CursorTy tail_1265 = s_216_622_958 + sizeof(IntTy); + + + switch_1266: + ; + switch (tag_1264) { + + case 1: + { + return 0; + break; + } + + case 0: + { + IntTy sz_217_623_959 = + ((Int64Int64CursorCursorProd *) tail_1265)->field0; + IntTy wildcard__152_218_624_960 = + ((Int64Int64CursorCursorProd *) tail_1265)->field1; + CursorTy wildcard__153_219_625_961 = + ((Int64Int64CursorCursorProd *) tail_1265)->field2; + CursorTy wildcard__154_220_626_962 = + ((Int64Int64CursorCursorProd *) tail_1265)->field3; + + return sz_217_623_959; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1264"); + exit(1); + } + } +} +CursorTy balanceR(IntTy x_232_638_963, CursorTy l_233_639_964, + CursorTy r_234_640_965) +{ + TagTyPacked tag_1267 = *(TagTyPacked *) l_233_639_964; + CursorTy tail_1268 = l_233_639_964 + sizeof(IntTy); + + + switch_1269: + ; + switch (tag_1267) { + + case 1: + { + return caseFn_565(x_232_638_963, r_234_640_965); + break; + } + + case 0: + { + IntTy ls_251_641_966 = + ((Int64Int64CursorCursorProd *) tail_1268)->field0; + IntTy wildcard__116_252_642_967 = + ((Int64Int64CursorCursorProd *) tail_1268)->field1; + CursorTy wildcard__117_253_643_968 = + ((Int64Int64CursorCursorProd *) tail_1268)->field2; + CursorTy wildcard__118_254_644_969 = + ((Int64Int64CursorCursorProd *) tail_1268)->field3; + + return caseFn_568(l_233_639_964, x_232_638_963, r_234_640_965, + ls_251_641_966); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1267"); + exit(1); + } + } +} +CursorTy balanceL(IntTy x_259_645_970, CursorTy l_260_646_971, + CursorTy r_261_647_972) +{ + TagTyPacked tag_1270 = *(TagTyPacked *) r_261_647_972; + CursorTy tail_1271 = r_261_647_972 + sizeof(IntTy); + + + switch_1272: + ; + switch (tag_1270) { + + case 1: + { + return caseFn_592(l_260_646_971, x_259_645_970); + break; + } + + case 0: + { + IntTy rs_278_648_973 = + ((Int64Int64CursorCursorProd *) tail_1271)->field0; + IntTy wildcard__55_279_649_974 = + ((Int64Int64CursorCursorProd *) tail_1271)->field1; + CursorTy wildcard__56_280_650_975 = + ((Int64Int64CursorCursorProd *) tail_1271)->field2; + CursorTy wildcard__57_281_651_976 = + ((Int64Int64CursorCursorProd *) tail_1271)->field3; + + return caseFn_595(r_261_647_972, l_260_646_971, x_259_645_970, + rs_278_648_973); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1270"); + exit(1); + } + } +} +CursorTy insert(IntTy x_286_652_977, CursorTy s_287_653_978) +{ + TagTyPacked tag_1273 = *(TagTyPacked *) s_287_653_978; + CursorTy tail_1274 = s_287_653_978 + sizeof(IntTy); + + + switch_1275: + ; + switch (tag_1273) { + + case 1: + { + return singleton(x_286_652_977); + break; + } + + case 0: + { + IntTy sz_288_654_979 = + ((Int64Int64CursorCursorProd *) tail_1274)->field0; + IntTy v_289_655_980 = + ((Int64Int64CursorCursorProd *) tail_1274)->field1; + CursorTy l_290_656_981 = + ((Int64Int64CursorCursorProd *) tail_1274)->field2; + CursorTy r_291_657_982 = + ((Int64Int64CursorCursorProd *) tail_1274)->field3; + BoolTy fltIf_795_983 = x_286_652_977 == v_289_655_980; + + if (fltIf_795_983) { + return s_287_653_978; + } else { + BoolTy fltIf_796_984 = x_286_652_977 <= v_289_655_980; + + if (fltIf_796_984) { + CursorTy nl_292_658_985 = + insert(x_286_652_977, l_290_656_981); + + return balanceL(v_289_655_980, nl_292_658_985, + r_291_657_982); + } else { + CursorTy nr_293_659_986 = + insert(x_286_652_977, r_291_657_982); + + return balanceR(v_289_655_980, l_290_656_981, + nr_293_659_986); + } + } + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1273"); + exit(1); + } + } +} +CursorTy singleton(IntTy x_294_660_987) +{ + PtrTy fltPkd_797_988 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_797_988)->field0 = 1; + + PtrTy fltPkd_798_989 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_798_989)->field0 = 1; + + PtrTy tailift_1276 = ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1276)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1276)->field1 = 1; + ((Int64Int64Int64CursorCursorProd *) tailift_1276)->field2 = x_294_660_987; + ((Int64Int64Int64CursorCursorProd *) tailift_1276)->field3 = fltPkd_797_988; + ((Int64Int64Int64CursorCursorProd *) tailift_1276)->field4 = fltPkd_798_989; + return tailift_1276; +} +CursorTy _copy_without_ptrs_IntSet(CursorTy arg_512_661_990) +{ + TagTyPacked tag_1277 = *(TagTyPacked *) arg_512_661_990; + CursorTy tail_1278 = arg_512_661_990 + sizeof(IntTy); + + + switch_1281: + ; + switch (tag_1277) { + + case 0: + { + IntTy x_513_662_991 = + ((Int64Int64CursorCursorProd *) tail_1278)->field0; + IntTy x_514_663_992 = + ((Int64Int64CursorCursorProd *) tail_1278)->field1; + CursorTy x_515_664_993 = + ((Int64Int64CursorCursorProd *) tail_1278)->field2; + CursorTy x_516_665_994 = + ((Int64Int64CursorCursorProd *) tail_1278)->field3; + CursorTy y_519_668_997 = _copy_without_ptrs_IntSet(x_515_664_993); + CursorTy y_520_669_998 = _copy_without_ptrs_IntSet(x_516_665_994); + PtrTy tailift_1279 = ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1279)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1279)->field1 = + x_513_662_991; + ((Int64Int64Int64CursorCursorProd *) tailift_1279)->field2 = + x_514_663_992; + ((Int64Int64Int64CursorCursorProd *) tailift_1279)->field3 = + y_519_668_997; + ((Int64Int64Int64CursorCursorProd *) tailift_1279)->field4 = + y_520_669_998; + return tailift_1279; + break; + } + + case 1: + { + PtrTy tailift_1280 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) tailift_1280)->field0 = 1; + return tailift_1280; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1277"); + exit(1); + } + } +} +CursorTy _copy_IntSet(CursorTy arg_503_670_999) +{ + TagTyPacked tag_1282 = *(TagTyPacked *) arg_503_670_999; + CursorTy tail_1283 = arg_503_670_999 + sizeof(IntTy); + + + switch_1286: + ; + switch (tag_1282) { + + case 0: + { + IntTy x_504_671_1000 = + ((Int64Int64CursorCursorProd *) tail_1283)->field0; + IntTy x_505_672_1001 = + ((Int64Int64CursorCursorProd *) tail_1283)->field1; + CursorTy x_506_673_1002 = + ((Int64Int64CursorCursorProd *) tail_1283)->field2; + CursorTy x_507_674_1003 = + ((Int64Int64CursorCursorProd *) tail_1283)->field3; + CursorTy y_510_677_1006 = _copy_IntSet(x_506_673_1002); + CursorTy y_511_678_1007 = _copy_IntSet(x_507_674_1003); + PtrTy tailift_1284 = ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1284)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1284)->field1 = + x_504_671_1000; + ((Int64Int64Int64CursorCursorProd *) tailift_1284)->field2 = + x_505_672_1001; + ((Int64Int64Int64CursorCursorProd *) tailift_1284)->field3 = + y_510_677_1006; + ((Int64Int64Int64CursorCursorProd *) tailift_1284)->field4 = + y_511_678_1007; + return tailift_1284; + break; + } + + case 1: + { + PtrTy tailift_1285 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) tailift_1285)->field0 = 1; + return tailift_1285; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1282"); + exit(1); + } + } +} +unsigned char _traverse_IntSet(CursorTy arg_521_679_1008) +{ + TagTyPacked tag_1287 = *(TagTyPacked *) arg_521_679_1008; + CursorTy tail_1288 = arg_521_679_1008 + sizeof(IntTy); + + + switch_1289: + ; + switch (tag_1287) { + + case 0: + { + IntTy x_522_680_1009 = + ((Int64Int64CursorCursorProd *) tail_1288)->field0; + IntTy x_523_681_1010 = + ((Int64Int64CursorCursorProd *) tail_1288)->field1; + CursorTy x_524_682_1011 = + ((Int64Int64CursorCursorProd *) tail_1288)->field2; + CursorTy x_525_683_1012 = + ((Int64Int64CursorCursorProd *) tail_1288)->field3; + unsigned char y_528_684_1013 = _traverse_IntSet(x_524_682_1011); + unsigned char y_529_685_1014 = _traverse_IntSet(x_525_683_1012); + + return 0; + break; + } + + case 1: + { + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1287"); + exit(1); + } + } +} +unsigned char _print_IntSet(CursorTy arg_530_686_1015) +{ + TagTyPacked tag_1290 = *(TagTyPacked *) arg_530_686_1015; + CursorTy tail_1291 = arg_530_686_1015 + sizeof(IntTy); + + + switch_1292: + ; + switch (tag_1290) { + + case 0: + { + IntTy x_531_687_1016 = + ((Int64Int64CursorCursorProd *) tail_1291)->field0; + IntTy x_532_688_1017 = + ((Int64Int64CursorCursorProd *) tail_1291)->field1; + CursorTy x_533_689_1018 = + ((Int64Int64CursorCursorProd *) tail_1291)->field2; + CursorTy x_534_690_1019 = + ((Int64Int64CursorCursorProd *) tail_1291)->field3; + unsigned char wildcard_539_691_1020 = print_symbol(1245); + unsigned char wildcard_544_692_1021 = print_symbol(1247); + unsigned char y_535_693_1022 = printf("%lld", x_531_687_1016); + unsigned char wildcard_543_694_1023 = print_symbol(1247); + unsigned char y_536_695_1024 = printf("%lld", x_532_688_1017); + unsigned char wildcard_542_696_1025 = print_symbol(1247); + unsigned char y_537_697_1026 = _print_IntSet(x_533_689_1018); + unsigned char wildcard_541_698_1027 = print_symbol(1247); + unsigned char y_538_699_1028 = _print_IntSet(x_534_690_1019); + unsigned char wildcard_540_700_1029 = print_symbol(1244); + + return 0; + break; + } + + case 1: + { + unsigned char wildcard_545_701_1030 = print_symbol(1246); + unsigned char wildcard_546_702_1031 = print_symbol(1244); + + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1290"); + exit(1); + } + } +} +CursorTy caseFn_547(IntTy x_232_548_703_1032, CursorTy rr_238_549_704_1033, + IntTy rx_236_550_705_1034, IntTy rs_235_551_706_1035, + CursorTy rl_237_552_707_1036) +{ + TagTyPacked tag_1293 = *(TagTyPacked *) rl_237_552_707_1036; + CursorTy tail_1294 = rl_237_552_707_1036 + sizeof(IntTy); + + + switch_1298: + ; + switch (tag_1293) { + + case 0: + { + IntTy rls_243_708_1037 = + ((Int64Int64CursorCursorProd *) tail_1294)->field0; + IntTy rlx_244_709_1038 = + ((Int64Int64CursorCursorProd *) tail_1294)->field1; + CursorTy rll_245_710_1039 = + ((Int64Int64CursorCursorProd *) tail_1294)->field2; + CursorTy rlr_246_711_1040 = + ((Int64Int64CursorCursorProd *) tail_1294)->field3; + IntTy fltPrm_800_1041 = size(rl_237_552_707_1036); + IntTy fltPrm_802_1042 = size(rr_238_549_704_1033); + IntTy fltPrm_801_1043 = 2 * fltPrm_802_1042; + BoolTy fltIf_799_1044 = fltPrm_800_1041 < fltPrm_801_1043; + + if (fltIf_799_1044) { + IntTy fltPkd_803_1045 = 1 + rs_235_551_706_1035; + IntTy fltPrm_806_1046 = size(rl_237_552_707_1036); + IntTy fltPkd_805_1047 = 1 + fltPrm_806_1046; + PtrTy fltPkd_807_1048 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_807_1048)->field0 = 1; + + PtrTy fltPkd_804_1049 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) fltPkd_804_1049)->field0 = + 0; + ((Int64Int64Int64CursorCursorProd *) fltPkd_804_1049)->field1 = + fltPkd_805_1047; + ((Int64Int64Int64CursorCursorProd *) fltPkd_804_1049)->field2 = + x_232_548_703_1032; + ((Int64Int64Int64CursorCursorProd *) fltPkd_804_1049)->field3 = + fltPkd_807_1048; + ((Int64Int64Int64CursorCursorProd *) fltPkd_804_1049)->field4 = + rl_237_552_707_1036; + + PtrTy tailift_1295 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1295)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1295)->field1 = + fltPkd_803_1045; + ((Int64Int64Int64CursorCursorProd *) tailift_1295)->field2 = + rx_236_550_705_1034; + ((Int64Int64Int64CursorCursorProd *) tailift_1295)->field3 = + fltPkd_804_1049; + ((Int64Int64Int64CursorCursorProd *) tailift_1295)->field4 = + rr_238_549_704_1033; + return tailift_1295; + } else { + IntTy fltPkd_808_1050 = 1 + rs_235_551_706_1035; + IntTy fltPkd_809_1051 = val(rl_237_552_707_1036); + CursorTy fltAppE_813_1052 = left(rl_237_552_707_1036); + IntTy fltPrm_812_1053 = size(fltAppE_813_1052); + IntTy fltPkd_811_1054 = 1 + fltPrm_812_1053; + PtrTy fltPkd_814_1055 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_814_1055)->field0 = 1; + + CursorTy fltPkd_815_1056 = left(rl_237_552_707_1036); + PtrTy fltPkd_810_1057 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) fltPkd_810_1057)->field0 = + 0; + ((Int64Int64Int64CursorCursorProd *) fltPkd_810_1057)->field1 = + fltPkd_811_1054; + ((Int64Int64Int64CursorCursorProd *) fltPkd_810_1057)->field2 = + x_232_548_703_1032; + ((Int64Int64Int64CursorCursorProd *) fltPkd_810_1057)->field3 = + fltPkd_814_1055; + ((Int64Int64Int64CursorCursorProd *) fltPkd_810_1057)->field4 = + fltPkd_815_1056; + + IntTy fltPrm_819_1058 = size(rr_238_549_704_1033); + IntTy fltPrm_818_1059 = 1 + fltPrm_819_1058; + CursorTy fltAppE_821_1060 = right(rl_237_552_707_1036); + IntTy fltPrm_820_1061 = size(fltAppE_821_1060); + IntTy fltPkd_817_1062 = fltPrm_818_1059 + fltPrm_820_1061; + CursorTy fltPkd_822_1063 = right(rl_237_552_707_1036); + PtrTy fltPkd_816_1064 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) fltPkd_816_1064)->field0 = + 0; + ((Int64Int64Int64CursorCursorProd *) fltPkd_816_1064)->field1 = + fltPkd_817_1062; + ((Int64Int64Int64CursorCursorProd *) fltPkd_816_1064)->field2 = + rx_236_550_705_1034; + ((Int64Int64Int64CursorCursorProd *) fltPkd_816_1064)->field3 = + fltPkd_822_1063; + ((Int64Int64Int64CursorCursorProd *) fltPkd_816_1064)->field4 = + rr_238_549_704_1033; + + PtrTy tailift_1296 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1296)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1296)->field1 = + fltPkd_808_1050; + ((Int64Int64Int64CursorCursorProd *) tailift_1296)->field2 = + fltPkd_809_1051; + ((Int64Int64Int64CursorCursorProd *) tailift_1296)->field3 = + fltPkd_810_1057; + ((Int64Int64Int64CursorCursorProd *) tailift_1296)->field4 = + fltPkd_816_1064; + return tailift_1296; + } + break; + } + + case 1: + { + PtrTy fltPkd_824_1065 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_824_1065)->field0 = 1; + + PtrTy fltPkd_825_1066 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_825_1066)->field0 = 1; + + PtrTy fltPkd_823_1067 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) fltPkd_823_1067)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) fltPkd_823_1067)->field1 = 1; + ((Int64Int64Int64CursorCursorProd *) fltPkd_823_1067)->field2 = + x_232_548_703_1032; + ((Int64Int64Int64CursorCursorProd *) fltPkd_823_1067)->field3 = + fltPkd_824_1065; + ((Int64Int64Int64CursorCursorProd *) fltPkd_823_1067)->field4 = + fltPkd_825_1066; + + PtrTy tailift_1297 = ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1297)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1297)->field1 = 3; + ((Int64Int64Int64CursorCursorProd *) tailift_1297)->field2 = + rx_236_550_705_1034; + ((Int64Int64Int64CursorCursorProd *) tailift_1297)->field3 = + fltPkd_823_1067; + ((Int64Int64Int64CursorCursorProd *) tailift_1297)->field4 = + rr_238_549_704_1033; + return tailift_1297; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1293"); + exit(1); + } + } +} +CursorTy caseFn_553(IntTy x_232_554_712_1068, CursorTy r_234_555_713_1069, + IntTy rx_236_556_714_1070, CursorTy rl_237_557_715_1071) +{ + TagTyPacked tag_1299 = *(TagTyPacked *) rl_237_557_715_1071; + CursorTy tail_1300 = rl_237_557_715_1071 + sizeof(IntTy); + + + switch_1303: + ; + switch (tag_1299) { + + case 0: + { + IntTy rls_247_716_1072 = + ((Int64Int64CursorCursorProd *) tail_1300)->field0; + IntTy rlx_248_717_1073 = + ((Int64Int64CursorCursorProd *) tail_1300)->field1; + CursorTy rll_249_718_1074 = + ((Int64Int64CursorCursorProd *) tail_1300)->field2; + CursorTy rlr_250_719_1075 = + ((Int64Int64CursorCursorProd *) tail_1300)->field3; + IntTy fltPkd_826_1076 = val(rl_237_557_715_1071); + PtrTy fltPkd_828_1077 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_828_1077)->field0 = 1; + + PtrTy fltPkd_829_1078 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_829_1078)->field0 = 1; + + PtrTy fltPkd_827_1079 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) fltPkd_827_1079)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) fltPkd_827_1079)->field1 = 1; + ((Int64Int64Int64CursorCursorProd *) fltPkd_827_1079)->field2 = + x_232_554_712_1068; + ((Int64Int64Int64CursorCursorProd *) fltPkd_827_1079)->field3 = + fltPkd_828_1077; + ((Int64Int64Int64CursorCursorProd *) fltPkd_827_1079)->field4 = + fltPkd_829_1078; + + PtrTy fltPkd_831_1080 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_831_1080)->field0 = 1; + + PtrTy fltPkd_832_1081 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_832_1081)->field0 = 1; + + PtrTy fltPkd_830_1082 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) fltPkd_830_1082)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) fltPkd_830_1082)->field1 = 1; + ((Int64Int64Int64CursorCursorProd *) fltPkd_830_1082)->field2 = + rx_236_556_714_1070; + ((Int64Int64Int64CursorCursorProd *) fltPkd_830_1082)->field3 = + fltPkd_831_1080; + ((Int64Int64Int64CursorCursorProd *) fltPkd_830_1082)->field4 = + fltPkd_832_1081; + + PtrTy tailift_1301 = ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1301)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1301)->field1 = 3; + ((Int64Int64Int64CursorCursorProd *) tailift_1301)->field2 = + fltPkd_826_1076; + ((Int64Int64Int64CursorCursorProd *) tailift_1301)->field3 = + fltPkd_827_1079; + ((Int64Int64Int64CursorCursorProd *) tailift_1301)->field4 = + fltPkd_830_1082; + return tailift_1301; + break; + } + + case 1: + { + PtrTy fltPkd_833_1083 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_833_1083)->field0 = 1; + + PtrTy tailift_1302 = ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1302)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1302)->field1 = 2; + ((Int64Int64Int64CursorCursorProd *) tailift_1302)->field2 = + x_232_554_712_1068; + ((Int64Int64Int64CursorCursorProd *) tailift_1302)->field3 = + fltPkd_833_1083; + ((Int64Int64Int64CursorCursorProd *) tailift_1302)->field4 = + r_234_555_713_1069; + return tailift_1302; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1299"); + exit(1); + } + } +} +CursorTy caseFn_558(IntTy x_232_559_720_1084, CursorTy r_234_560_721_1085, + CursorTy rr_238_561_722_1086, IntTy rx_236_562_723_1087, + IntTy rs_235_563_724_1088, CursorTy rl_237_564_725_1089) +{ + TagTyPacked tag_1304 = *(TagTyPacked *) rr_238_561_722_1086; + CursorTy tail_1305 = rr_238_561_722_1086 + sizeof(IntTy); + + + switch_1306: + ; + switch (tag_1304) { + + case 0: + { + IntTy rrs_239_726_1090 = + ((Int64Int64CursorCursorProd *) tail_1305)->field0; + IntTy rrx_240_727_1091 = + ((Int64Int64CursorCursorProd *) tail_1305)->field1; + CursorTy rrl_241_728_1092 = + ((Int64Int64CursorCursorProd *) tail_1305)->field2; + CursorTy rrr_242_729_1093 = + ((Int64Int64CursorCursorProd *) tail_1305)->field3; + + return caseFn_547(x_232_559_720_1084, rr_238_561_722_1086, + rx_236_562_723_1087, rs_235_563_724_1088, + rl_237_564_725_1089); + break; + } + + case 1: + { + return caseFn_553(x_232_559_720_1084, r_234_560_721_1085, + rx_236_562_723_1087, rl_237_564_725_1089); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1304"); + exit(1); + } + } +} +CursorTy caseFn_565(IntTy x_232_566_730_1094, CursorTy r_234_567_731_1095) +{ + TagTyPacked tag_1307 = *(TagTyPacked *) r_234_567_731_1095; + CursorTy tail_1308 = r_234_567_731_1095 + sizeof(IntTy); + + + switch_1310: + ; + switch (tag_1307) { + + case 1: + { + PtrTy fltPkd_834_1096 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_834_1096)->field0 = 1; + + PtrTy fltPkd_835_1097 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_835_1097)->field0 = 1; + + PtrTy tailift_1309 = ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1309)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1309)->field1 = 1; + ((Int64Int64Int64CursorCursorProd *) tailift_1309)->field2 = + x_232_566_730_1094; + ((Int64Int64Int64CursorCursorProd *) tailift_1309)->field3 = + fltPkd_834_1096; + ((Int64Int64Int64CursorCursorProd *) tailift_1309)->field4 = + fltPkd_835_1097; + return tailift_1309; + break; + } + + case 0: + { + IntTy rs_235_732_1098 = + ((Int64Int64CursorCursorProd *) tail_1308)->field0; + IntTy rx_236_733_1099 = + ((Int64Int64CursorCursorProd *) tail_1308)->field1; + CursorTy rl_237_734_1100 = + ((Int64Int64CursorCursorProd *) tail_1308)->field2; + CursorTy rr_238_735_1101 = + ((Int64Int64CursorCursorProd *) tail_1308)->field3; + + return caseFn_558(x_232_566_730_1094, r_234_567_731_1095, + rr_238_735_1101, rx_236_733_1099, rs_235_732_1098, + rl_237_734_1100); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1307"); + exit(1); + } + } +} +CursorTy caseFn_568(CursorTy l_233_569_736_1102, IntTy x_232_570_737_1103, + CursorTy r_234_571_738_1104, IntTy ls_251_572_739_1105) +{ + TagTyPacked tag_1311 = *(TagTyPacked *) r_234_571_738_1104; + CursorTy tail_1312 = r_234_571_738_1104 + sizeof(IntTy); + + + switch_1317: + ; + switch (tag_1311) { + + case 1: + { + IntTy fltPkd_836_1106 = 1 + ls_251_572_739_1105; + PtrTy fltPkd_837_1107 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_837_1107)->field0 = 1; + + PtrTy tailift_1313 = ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1313)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1313)->field1 = + fltPkd_836_1106; + ((Int64Int64Int64CursorCursorProd *) tailift_1313)->field2 = + x_232_570_737_1103; + ((Int64Int64Int64CursorCursorProd *) tailift_1313)->field3 = + l_233_569_736_1102; + ((Int64Int64Int64CursorCursorProd *) tailift_1313)->field4 = + fltPkd_837_1107; + return tailift_1313; + break; + } + + case 0: + { + IntTy rs_255_740_1108 = + ((Int64Int64CursorCursorProd *) tail_1312)->field0; + IntTy rx_256_741_1109 = + ((Int64Int64CursorCursorProd *) tail_1312)->field1; + CursorTy rl_257_742_1110 = + ((Int64Int64CursorCursorProd *) tail_1312)->field2; + CursorTy rr_258_743_1111 = + ((Int64Int64CursorCursorProd *) tail_1312)->field3; + IntTy fltPrm_839_1112 = 3 * ls_251_572_739_1105; + BoolTy fltIf_838_1113 = rs_255_740_1108 > fltPrm_839_1112; + + if (fltIf_838_1113) { + IntTy fltPrm_841_1114 = size(rl_257_742_1110); + IntTy fltPrm_843_1115 = size(rr_258_743_1111); + IntTy fltPrm_842_1116 = 2 * fltPrm_843_1115; + BoolTy fltIf_840_1117 = fltPrm_841_1114 < fltPrm_842_1116; + + if (fltIf_840_1117) { + IntTy fltPrm_845_1118 = 1 + ls_251_572_739_1105; + IntTy fltPkd_844_1119 = fltPrm_845_1118 + rs_255_740_1108; + IntTy fltPrm_848_1120 = 1 + ls_251_572_739_1105; + IntTy fltPrm_849_1121 = size(rl_257_742_1110); + IntTy fltPkd_847_1122 = fltPrm_848_1120 + fltPrm_849_1121; + PtrTy fltPkd_846_1123 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) fltPkd_846_1123)->field0 = + 0; + ((Int64Int64Int64CursorCursorProd *) fltPkd_846_1123)->field1 = + fltPkd_847_1122; + ((Int64Int64Int64CursorCursorProd *) fltPkd_846_1123)->field2 = + x_232_570_737_1103; + ((Int64Int64Int64CursorCursorProd *) fltPkd_846_1123)->field3 = + l_233_569_736_1102; + ((Int64Int64Int64CursorCursorProd *) fltPkd_846_1123)->field4 = + rl_257_742_1110; + + PtrTy tailift_1314 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1314)->field0 = + 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1314)->field1 = + fltPkd_844_1119; + ((Int64Int64Int64CursorCursorProd *) tailift_1314)->field2 = + rx_256_741_1109; + ((Int64Int64Int64CursorCursorProd *) tailift_1314)->field3 = + fltPkd_846_1123; + ((Int64Int64Int64CursorCursorProd *) tailift_1314)->field4 = + rr_258_743_1111; + return tailift_1314; + } else { + IntTy fltPrm_851_1124 = 1 + ls_251_572_739_1105; + IntTy fltPkd_850_1125 = fltPrm_851_1124 + rs_255_740_1108; + IntTy fltPkd_852_1126 = val(rl_257_742_1110); + IntTy fltPrm_855_1127 = 1 + ls_251_572_739_1105; + CursorTy fltAppE_857_1128 = left(rl_257_742_1110); + IntTy fltPrm_856_1129 = size(fltAppE_857_1128); + IntTy fltPkd_854_1130 = fltPrm_855_1127 + fltPrm_856_1129; + CursorTy fltPkd_858_1131 = left(rl_257_742_1110); + PtrTy fltPkd_853_1132 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) fltPkd_853_1132)->field0 = + 0; + ((Int64Int64Int64CursorCursorProd *) fltPkd_853_1132)->field1 = + fltPkd_854_1130; + ((Int64Int64Int64CursorCursorProd *) fltPkd_853_1132)->field2 = + x_232_570_737_1103; + ((Int64Int64Int64CursorCursorProd *) fltPkd_853_1132)->field3 = + l_233_569_736_1102; + ((Int64Int64Int64CursorCursorProd *) fltPkd_853_1132)->field4 = + fltPkd_858_1131; + + IntTy fltPrm_862_1133 = size(rr_258_743_1111); + IntTy fltPrm_861_1134 = 1 + fltPrm_862_1133; + CursorTy fltAppE_864_1135 = right(rl_257_742_1110); + IntTy fltPrm_863_1136 = size(fltAppE_864_1135); + IntTy fltPkd_860_1137 = fltPrm_861_1134 + fltPrm_863_1136; + CursorTy fltPkd_865_1138 = right(rl_257_742_1110); + PtrTy fltPkd_859_1139 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) fltPkd_859_1139)->field0 = + 0; + ((Int64Int64Int64CursorCursorProd *) fltPkd_859_1139)->field1 = + fltPkd_860_1137; + ((Int64Int64Int64CursorCursorProd *) fltPkd_859_1139)->field2 = + rx_256_741_1109; + ((Int64Int64Int64CursorCursorProd *) fltPkd_859_1139)->field3 = + fltPkd_865_1138; + ((Int64Int64Int64CursorCursorProd *) fltPkd_859_1139)->field4 = + rr_258_743_1111; + + PtrTy tailift_1315 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1315)->field0 = + 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1315)->field1 = + fltPkd_850_1125; + ((Int64Int64Int64CursorCursorProd *) tailift_1315)->field2 = + fltPkd_852_1126; + ((Int64Int64Int64CursorCursorProd *) tailift_1315)->field3 = + fltPkd_853_1132; + ((Int64Int64Int64CursorCursorProd *) tailift_1315)->field4 = + fltPkd_859_1139; + return tailift_1315; + } + } else { + IntTy fltPrm_867_1140 = 1 + ls_251_572_739_1105; + IntTy fltPkd_866_1141 = fltPrm_867_1140 + rs_255_740_1108; + PtrTy tailift_1316 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1316)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1316)->field1 = + fltPkd_866_1141; + ((Int64Int64Int64CursorCursorProd *) tailift_1316)->field2 = + x_232_570_737_1103; + ((Int64Int64Int64CursorCursorProd *) tailift_1316)->field3 = + l_233_569_736_1102; + ((Int64Int64Int64CursorCursorProd *) tailift_1316)->field4 = + r_234_571_738_1104; + return tailift_1316; + } + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1311"); + exit(1); + } + } +} +CursorTy caseFn_573(IntTy x_259_574_744_1142, CursorTy ll_264_575_745_1143, + IntTy lx_263_576_746_1144, IntTy ls_262_577_747_1145, + CursorTy lr_265_578_748_1146, IntTy lls_266_579_749_1147) +{ + TagTyPacked tag_1318 = *(TagTyPacked *) lr_265_578_748_1146; + CursorTy tail_1319 = lr_265_578_748_1146 + sizeof(IntTy); + + + switch_1323: + ; + switch (tag_1318) { + + case 0: + { + IntTy lrs_270_750_1148 = + ((Int64Int64CursorCursorProd *) tail_1319)->field0; + IntTy lrx_271_751_1149 = + ((Int64Int64CursorCursorProd *) tail_1319)->field1; + CursorTy lrl_272_752_1150 = + ((Int64Int64CursorCursorProd *) tail_1319)->field2; + CursorTy lrr_273_753_1151 = + ((Int64Int64CursorCursorProd *) tail_1319)->field3; + IntTy fltPrm_869_1152 = 2 * lls_266_579_749_1147; + BoolTy fltIf_868_1153 = lrs_270_750_1148 < fltPrm_869_1152; + + if (fltIf_868_1153) { + IntTy fltPkd_870_1154 = 1 + ls_262_577_747_1145; + IntTy fltPkd_872_1155 = 1 + lrs_270_750_1148; + PtrTy fltPkd_873_1156 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_873_1156)->field0 = 1; + + PtrTy fltPkd_871_1157 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) fltPkd_871_1157)->field0 = + 0; + ((Int64Int64Int64CursorCursorProd *) fltPkd_871_1157)->field1 = + fltPkd_872_1155; + ((Int64Int64Int64CursorCursorProd *) fltPkd_871_1157)->field2 = + x_259_574_744_1142; + ((Int64Int64Int64CursorCursorProd *) fltPkd_871_1157)->field3 = + lr_265_578_748_1146; + ((Int64Int64Int64CursorCursorProd *) fltPkd_871_1157)->field4 = + fltPkd_873_1156; + + PtrTy tailift_1320 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1320)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1320)->field1 = + fltPkd_870_1154; + ((Int64Int64Int64CursorCursorProd *) tailift_1320)->field2 = + lx_263_576_746_1144; + ((Int64Int64Int64CursorCursorProd *) tailift_1320)->field3 = + ll_264_575_745_1143; + ((Int64Int64Int64CursorCursorProd *) tailift_1320)->field4 = + fltPkd_871_1157; + return tailift_1320; + } else { + IntTy fltPkd_874_1158 = 1 + ls_262_577_747_1145; + IntTy fltPrm_877_1159 = 1 + lls_266_579_749_1147; + IntTy fltPrm_878_1160 = size(lrl_272_752_1150); + IntTy fltPkd_876_1161 = fltPrm_877_1159 + fltPrm_878_1160; + PtrTy fltPkd_875_1162 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) fltPkd_875_1162)->field0 = + 0; + ((Int64Int64Int64CursorCursorProd *) fltPkd_875_1162)->field1 = + fltPkd_876_1161; + ((Int64Int64Int64CursorCursorProd *) fltPkd_875_1162)->field2 = + lx_263_576_746_1144; + ((Int64Int64Int64CursorCursorProd *) fltPkd_875_1162)->field3 = + ll_264_575_745_1143; + ((Int64Int64Int64CursorCursorProd *) fltPkd_875_1162)->field4 = + lrl_272_752_1150; + + IntTy fltPrm_881_1163 = size(lrr_273_753_1151); + IntTy fltPkd_880_1164 = 1 + fltPrm_881_1163; + PtrTy fltPkd_882_1165 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_882_1165)->field0 = 1; + + PtrTy fltPkd_879_1166 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) fltPkd_879_1166)->field0 = + 0; + ((Int64Int64Int64CursorCursorProd *) fltPkd_879_1166)->field1 = + fltPkd_880_1164; + ((Int64Int64Int64CursorCursorProd *) fltPkd_879_1166)->field2 = + x_259_574_744_1142; + ((Int64Int64Int64CursorCursorProd *) fltPkd_879_1166)->field3 = + lrr_273_753_1151; + ((Int64Int64Int64CursorCursorProd *) fltPkd_879_1166)->field4 = + fltPkd_882_1165; + + PtrTy tailift_1321 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1321)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1321)->field1 = + fltPkd_874_1158; + ((Int64Int64Int64CursorCursorProd *) tailift_1321)->field2 = + lrx_271_751_1149; + ((Int64Int64Int64CursorCursorProd *) tailift_1321)->field3 = + fltPkd_875_1162; + ((Int64Int64Int64CursorCursorProd *) tailift_1321)->field4 = + fltPkd_879_1166; + return tailift_1321; + } + break; + } + + case 1: + { + PtrTy fltPkd_884_1167 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_884_1167)->field0 = 1; + + PtrTy fltPkd_885_1168 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_885_1168)->field0 = 1; + + PtrTy fltPkd_883_1169 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) fltPkd_883_1169)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) fltPkd_883_1169)->field1 = 1; + ((Int64Int64Int64CursorCursorProd *) fltPkd_883_1169)->field2 = + x_259_574_744_1142; + ((Int64Int64Int64CursorCursorProd *) fltPkd_883_1169)->field3 = + fltPkd_884_1167; + ((Int64Int64Int64CursorCursorProd *) fltPkd_883_1169)->field4 = + fltPkd_885_1168; + + PtrTy tailift_1322 = ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1322)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1322)->field1 = 3; + ((Int64Int64Int64CursorCursorProd *) tailift_1322)->field2 = + lx_263_576_746_1144; + ((Int64Int64Int64CursorCursorProd *) tailift_1322)->field3 = + ll_264_575_745_1143; + ((Int64Int64Int64CursorCursorProd *) tailift_1322)->field4 = + fltPkd_883_1169; + return tailift_1322; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1318"); + exit(1); + } + } +} +CursorTy caseFn_580(CursorTy l_260_581_754_1170, IntTy x_259_582_755_1171, + IntTy lx_263_583_756_1172, CursorTy lr_265_584_757_1173) +{ + TagTyPacked tag_1324 = *(TagTyPacked *) lr_265_584_757_1173; + CursorTy tail_1325 = lr_265_584_757_1173 + sizeof(IntTy); + + + switch_1328: + ; + switch (tag_1324) { + + case 0: + { + IntTy lrs_274_758_1174 = + ((Int64Int64CursorCursorProd *) tail_1325)->field0; + IntTy lrx_275_759_1175 = + ((Int64Int64CursorCursorProd *) tail_1325)->field1; + CursorTy lrl_276_760_1176 = + ((Int64Int64CursorCursorProd *) tail_1325)->field2; + CursorTy lrr_277_761_1177 = + ((Int64Int64CursorCursorProd *) tail_1325)->field3; + PtrTy fltPkd_887_1178 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_887_1178)->field0 = 1; + + PtrTy fltPkd_888_1179 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_888_1179)->field0 = 1; + + PtrTy fltPkd_886_1180 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) fltPkd_886_1180)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) fltPkd_886_1180)->field1 = 1; + ((Int64Int64Int64CursorCursorProd *) fltPkd_886_1180)->field2 = + lx_263_583_756_1172; + ((Int64Int64Int64CursorCursorProd *) fltPkd_886_1180)->field3 = + fltPkd_887_1178; + ((Int64Int64Int64CursorCursorProd *) fltPkd_886_1180)->field4 = + fltPkd_888_1179; + + PtrTy fltPkd_890_1181 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_890_1181)->field0 = 1; + + PtrTy fltPkd_891_1182 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_891_1182)->field0 = 1; + + PtrTy fltPkd_889_1183 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) fltPkd_889_1183)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) fltPkd_889_1183)->field1 = 1; + ((Int64Int64Int64CursorCursorProd *) fltPkd_889_1183)->field2 = + x_259_582_755_1171; + ((Int64Int64Int64CursorCursorProd *) fltPkd_889_1183)->field3 = + fltPkd_890_1181; + ((Int64Int64Int64CursorCursorProd *) fltPkd_889_1183)->field4 = + fltPkd_891_1182; + + PtrTy tailift_1326 = ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1326)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1326)->field1 = 3; + ((Int64Int64Int64CursorCursorProd *) tailift_1326)->field2 = + lrx_275_759_1175; + ((Int64Int64Int64CursorCursorProd *) tailift_1326)->field3 = + fltPkd_886_1180; + ((Int64Int64Int64CursorCursorProd *) tailift_1326)->field4 = + fltPkd_889_1183; + return tailift_1326; + break; + } + + case 1: + { + PtrTy fltPkd_892_1184 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_892_1184)->field0 = 1; + + PtrTy tailift_1327 = ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1327)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1327)->field1 = 2; + ((Int64Int64Int64CursorCursorProd *) tailift_1327)->field2 = + x_259_582_755_1171; + ((Int64Int64Int64CursorCursorProd *) tailift_1327)->field3 = + l_260_581_754_1170; + ((Int64Int64Int64CursorCursorProd *) tailift_1327)->field4 = + fltPkd_892_1184; + return tailift_1327; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1324"); + exit(1); + } + } +} +CursorTy caseFn_585(CursorTy l_260_586_762_1185, IntTy x_259_587_763_1186, + CursorTy ll_264_588_764_1187, IntTy lx_263_589_765_1188, + IntTy ls_262_590_766_1189, CursorTy lr_265_591_767_1190) +{ + TagTyPacked tag_1329 = *(TagTyPacked *) ll_264_588_764_1187; + CursorTy tail_1330 = ll_264_588_764_1187 + sizeof(IntTy); + + + switch_1331: + ; + switch (tag_1329) { + + case 0: + { + IntTy lls_266_768_1191 = + ((Int64Int64CursorCursorProd *) tail_1330)->field0; + IntTy llx_267_769_1192 = + ((Int64Int64CursorCursorProd *) tail_1330)->field1; + CursorTy lll_268_770_1193 = + ((Int64Int64CursorCursorProd *) tail_1330)->field2; + CursorTy llr_269_771_1194 = + ((Int64Int64CursorCursorProd *) tail_1330)->field3; + + return caseFn_573(x_259_587_763_1186, ll_264_588_764_1187, + lx_263_589_765_1188, ls_262_590_766_1189, + lr_265_591_767_1190, lls_266_768_1191); + break; + } + + case 1: + { + return caseFn_580(l_260_586_762_1185, x_259_587_763_1186, + lx_263_589_765_1188, lr_265_591_767_1190); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1329"); + exit(1); + } + } +} +CursorTy caseFn_592(CursorTy l_260_593_772_1195, IntTy x_259_594_773_1196) +{ + TagTyPacked tag_1332 = *(TagTyPacked *) l_260_593_772_1195; + CursorTy tail_1333 = l_260_593_772_1195 + sizeof(IntTy); + + + switch_1335: + ; + switch (tag_1332) { + + case 1: + { + PtrTy fltPkd_893_1197 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_893_1197)->field0 = 1; + + PtrTy fltPkd_894_1198 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_894_1198)->field0 = 1; + + PtrTy tailift_1334 = ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1334)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1334)->field1 = 1; + ((Int64Int64Int64CursorCursorProd *) tailift_1334)->field2 = + x_259_594_773_1196; + ((Int64Int64Int64CursorCursorProd *) tailift_1334)->field3 = + fltPkd_893_1197; + ((Int64Int64Int64CursorCursorProd *) tailift_1334)->field4 = + fltPkd_894_1198; + return tailift_1334; + break; + } + + case 0: + { + IntTy ls_262_774_1199 = + ((Int64Int64CursorCursorProd *) tail_1333)->field0; + IntTy lx_263_775_1200 = + ((Int64Int64CursorCursorProd *) tail_1333)->field1; + CursorTy ll_264_776_1201 = + ((Int64Int64CursorCursorProd *) tail_1333)->field2; + CursorTy lr_265_777_1202 = + ((Int64Int64CursorCursorProd *) tail_1333)->field3; + + return caseFn_585(l_260_593_772_1195, x_259_594_773_1196, + ll_264_776_1201, lx_263_775_1200, ls_262_774_1199, + lr_265_777_1202); + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1332"); + exit(1); + } + } +} +CursorTy caseFn_595(CursorTy r_261_596_778_1203, CursorTy l_260_597_779_1204, + IntTy x_259_598_780_1205, IntTy rs_278_599_781_1206) +{ + TagTyPacked tag_1336 = *(TagTyPacked *) l_260_597_779_1204; + CursorTy tail_1337 = l_260_597_779_1204 + sizeof(IntTy); + + + switch_1342: + ; + switch (tag_1336) { + + case 1: + { + IntTy fltPkd_895_1207 = 1 + rs_278_599_781_1206; + PtrTy fltPkd_896_1208 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_896_1208)->field0 = 1; + + PtrTy tailift_1338 = ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1338)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1338)->field1 = + fltPkd_895_1207; + ((Int64Int64Int64CursorCursorProd *) tailift_1338)->field2 = + x_259_598_780_1205; + ((Int64Int64Int64CursorCursorProd *) tailift_1338)->field3 = + fltPkd_896_1208; + ((Int64Int64Int64CursorCursorProd *) tailift_1338)->field4 = + r_261_596_778_1203; + return tailift_1338; + break; + } + + case 0: + { + IntTy ls_282_782_1209 = + ((Int64Int64CursorCursorProd *) tail_1337)->field0; + IntTy lx_283_783_1210 = + ((Int64Int64CursorCursorProd *) tail_1337)->field1; + CursorTy ll_284_784_1211 = + ((Int64Int64CursorCursorProd *) tail_1337)->field2; + CursorTy lr_285_785_1212 = + ((Int64Int64CursorCursorProd *) tail_1337)->field3; + IntTy fltPrm_898_1213 = 3 * rs_278_599_781_1206; + BoolTy fltIf_897_1214 = ls_282_782_1209 > fltPrm_898_1213; + + if (fltIf_897_1214) { + IntTy fltPrm_900_1215 = size(lr_285_785_1212); + IntTy fltPrm_902_1216 = size(ll_284_784_1211); + IntTy fltPrm_901_1217 = 2 * fltPrm_902_1216; + BoolTy fltIf_899_1218 = fltPrm_900_1215 < fltPrm_901_1217; + + if (fltIf_899_1218) { + IntTy fltPrm_904_1219 = 1 + ls_282_782_1209; + IntTy fltPkd_903_1220 = fltPrm_904_1219 + + rs_278_599_781_1206; + IntTy fltPrm_907_1221 = 1 + rs_278_599_781_1206; + IntTy fltPrm_908_1222 = size(lr_285_785_1212); + IntTy fltPkd_906_1223 = fltPrm_907_1221 + fltPrm_908_1222; + PtrTy fltPkd_905_1224 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) fltPkd_905_1224)->field0 = + 0; + ((Int64Int64Int64CursorCursorProd *) fltPkd_905_1224)->field1 = + fltPkd_906_1223; + ((Int64Int64Int64CursorCursorProd *) fltPkd_905_1224)->field2 = + x_259_598_780_1205; + ((Int64Int64Int64CursorCursorProd *) fltPkd_905_1224)->field3 = + lr_285_785_1212; + ((Int64Int64Int64CursorCursorProd *) fltPkd_905_1224)->field4 = + r_261_596_778_1203; + + PtrTy tailift_1339 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1339)->field0 = + 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1339)->field1 = + fltPkd_903_1220; + ((Int64Int64Int64CursorCursorProd *) tailift_1339)->field2 = + lx_283_783_1210; + ((Int64Int64Int64CursorCursorProd *) tailift_1339)->field3 = + ll_284_784_1211; + ((Int64Int64Int64CursorCursorProd *) tailift_1339)->field4 = + fltPkd_905_1224; + return tailift_1339; + } else { + IntTy fltPrm_910_1225 = 1 + ls_282_782_1209; + IntTy fltPkd_909_1226 = fltPrm_910_1225 + + rs_278_599_781_1206; + IntTy fltPkd_911_1227 = val(lr_285_785_1212); + IntTy fltPrm_915_1228 = size(ll_284_784_1211); + IntTy fltPrm_914_1229 = 1 + fltPrm_915_1228; + CursorTy fltAppE_917_1230 = left(lr_285_785_1212); + IntTy fltPrm_916_1231 = size(fltAppE_917_1230); + IntTy fltPkd_913_1232 = fltPrm_914_1229 + fltPrm_916_1231; + CursorTy fltPkd_918_1233 = left(lr_285_785_1212); + PtrTy fltPkd_912_1234 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) fltPkd_912_1234)->field0 = + 0; + ((Int64Int64Int64CursorCursorProd *) fltPkd_912_1234)->field1 = + fltPkd_913_1232; + ((Int64Int64Int64CursorCursorProd *) fltPkd_912_1234)->field2 = + lx_283_783_1210; + ((Int64Int64Int64CursorCursorProd *) fltPkd_912_1234)->field3 = + ll_284_784_1211; + ((Int64Int64Int64CursorCursorProd *) fltPkd_912_1234)->field4 = + fltPkd_918_1233; + + IntTy fltPrm_921_1235 = 1 + rs_278_599_781_1206; + CursorTy fltAppE_923_1236 = right(lr_285_785_1212); + IntTy fltPrm_922_1237 = size(fltAppE_923_1236); + IntTy fltPkd_920_1238 = fltPrm_921_1235 + fltPrm_922_1237; + CursorTy fltPkd_924_1239 = right(lr_285_785_1212); + PtrTy fltPkd_919_1240 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) fltPkd_919_1240)->field0 = + 0; + ((Int64Int64Int64CursorCursorProd *) fltPkd_919_1240)->field1 = + fltPkd_920_1238; + ((Int64Int64Int64CursorCursorProd *) fltPkd_919_1240)->field2 = + x_259_598_780_1205; + ((Int64Int64Int64CursorCursorProd *) fltPkd_919_1240)->field3 = + fltPkd_924_1239; + ((Int64Int64Int64CursorCursorProd *) fltPkd_919_1240)->field4 = + r_261_596_778_1203; + + PtrTy tailift_1340 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1340)->field0 = + 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1340)->field1 = + fltPkd_909_1226; + ((Int64Int64Int64CursorCursorProd *) tailift_1340)->field2 = + fltPkd_911_1227; + ((Int64Int64Int64CursorCursorProd *) tailift_1340)->field3 = + fltPkd_912_1234; + ((Int64Int64Int64CursorCursorProd *) tailift_1340)->field4 = + fltPkd_919_1240; + return tailift_1340; + } + } else { + IntTy fltPrm_926_1241 = 1 + ls_282_782_1209; + IntTy fltPkd_925_1242 = fltPrm_926_1241 + rs_278_599_781_1206; + PtrTy tailift_1341 = + ALLOC(sizeof(Int64Int64Int64CursorCursorProd)); + + ((Int64Int64Int64CursorCursorProd *) tailift_1341)->field0 = 0; + ((Int64Int64Int64CursorCursorProd *) tailift_1341)->field1 = + fltPkd_925_1242; + ((Int64Int64Int64CursorCursorProd *) tailift_1341)->field2 = + x_259_598_780_1205; + ((Int64Int64Int64CursorCursorProd *) tailift_1341)->field3 = + l_260_597_779_1204; + ((Int64Int64Int64CursorCursorProd *) tailift_1341)->field4 = + r_261_596_778_1203; + return tailift_1341; + } + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_1336"); + exit(1); + } + } +} +int __main_expr() +{ + add_symbol(1244, ")"); + add_symbol(1245, "(PureSet"); + add_symbol(1246, "(EmptySet"); + add_symbol(1247, " "); + + CursorTy fltAppE_788_927 = empty(); + CursorTy fltAppE_787_928 = insert_num(100, fltAppE_788_927); + CursorTy fltAppE_786_929 = insert_num(100, fltAppE_787_928); + IntTy tmp_app_1243 = sum(fltAppE_786_929); + + printf("%lld", tmp_app_1243); + printf("\n"); + free_symtable(); + return 0; +} \ No newline at end of file diff --git a/benchmarks/modules/Set/PureSet b/benchmarks/modules/Set/PureSet new file mode 100755 index 000000000..e340189f2 Binary files /dev/null and b/benchmarks/modules/Set/PureSet differ diff --git a/benchmarks/modules/Set/PureSet.c b/benchmarks/modules/Set/PureSet.c new file mode 100644 index 000000000..82e50b4a2 --- /dev/null +++ b/benchmarks/modules/Set/PureSet.c @@ -0,0 +1,1723 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// #include +#ifdef _WIN64 +#include +#endif +#include +#include +#include // For va_start etc +#include +#include +#include +#include +#ifdef _POINTER +#include +#endif +#ifdef _PARALLEL +#include +#include +#endif + +#define KB 1024lu +#define MB (KB * 1000lu) +#define GB (MB * 1000lu) + +#define REDIRECTION_TAG 255 +#define INDIRECTION_TAG 254 + +// Initial size of BigInfinite buffers +static long long global_init_biginf_buf_size = (4 * GB); + +// Initial size of Infinite buffers +static long long global_init_inf_buf_size = 1 * KB; + +// Maximum size of a chunk, see GitHub #110. +static long long global_inf_buf_max_chunk_size = 1 * GB; + +static long long global_size_param = 1; +static long long global_iters_param = 1; + +static char* global_benchfile_param = NULL; +static char* global_arrayfile_param = NULL; +// Number of lines in the arrayfile +static long long global_arrayfile_length_param = -1; + +// Sequential for now: +static const int num_workers = 1; + +// Count the number of regions allocated. +static long long global_region_count = 0; +static bool global_region_count_flag = false; + +#ifdef _PARALLEL +static inline void bump_global_region_count() { + __atomic_add_fetch(&global_region_count, 1, __ATOMIC_SEQ_CST); + return; +} +#else +static inline void bump_global_region_count() { + global_region_count++; + return; +} +#endif + +static inline void print_global_region_count() { + printf("REGION_COUNT: %lld\n", global_region_count); + return; +} + +#define REDIRECTION_NODE_SIZE 9 +#define MAX(a,b) (((a)>(b))?(a):(b)) +#define MIN(a,b) (((a)<(b))?(a):(b)) + +// https://www.cprogramming.com/snippets/source-code/find-the-number-of-cpu-cores-for-windows-mac-or-linux +static int get_num_processors() { +#ifdef _WIN64 + SYSTEM_INFO sysinfo; + GetSystemInfo(&sysinfo); + return sysinfo.dwNumberOfProcessors; +#else + return sysconf(_SC_NPROCESSORS_ONLN); +#endif +} + +// Requires -std=gnu11 +int dbgprintf(const char *format, ...) { + int code = 0; + va_list args; + va_start(args, format); +#ifdef _DEBUG + code = vprintf(format, args); +#endif + va_end(args); + return code; +} + + +// ----------------------------------------------------------------------------- +// Allocators +// ----------------------------------------------------------------------------- + + +// ------------------------------------- +// Bump allocation for linked-lists +// ------------------------------------- + + +#ifdef _BUMPALLOC +// #define _DEBUG +#warning "Using bump allocator." + +__thread char* bumpalloc_heap_ptr = (char*)NULL; +__thread char* bumpalloc_heap_ptr_end = (char*)NULL; + +char* saved_heap_ptr_stack[100]; +int num_saved_heap_ptr = 0; + +// For simplicity just use a single large slab: +static inline void INITBUMPALLOC() { + bumpalloc_heap_ptr = (char*)malloc(global_init_biginf_buf_size); + bumpalloc_heap_ptr_end = bumpalloc_heap_ptr + global_init_biginf_buf_size; +#ifdef _DEBUG + printf("Arena size for bump alloc: %lld\n", global_init_biginf_buf_size); + printf("BUMPALLOC/INITBUMPALLOC DONE: heap_ptr = %p\n", bumpalloc_heap_ptr); +#endif +} + +static inline void* BUMPALLOC(long long n) { + if (! bumpalloc_heap_ptr) { + INITBUMPALLOC(); + } + if (bumpalloc_heap_ptr + n < bumpalloc_heap_ptr_end) { + char* old= bumpalloc_heap_ptr; + bumpalloc_heap_ptr += n; + return old; + } else { + fprintf(stderr, "Warning: bump allocator ran out of memory."); + exit(1); + } +} + +// Snapshot the current heap pointer value across all threads. +void save_alloc_state() { + dbgprintf("Saving(%p): pos %d", heap_ptr, num_saved_heap_ptr); + saved_heap_ptr_stack[num_saved_heap_ptr] = heap_ptr; + num_saved_heap_ptr++; + dbgprintf("\n"); +} + +void restore_alloc_state() { + if(num_saved_heap_ptr <= 0) { + fprintf(stderr, "Bad call to restore_alloc_state! Saved stack empty!\ne"); + exit(1); + } + num_saved_heap_ptr--; + dbgprintf("Restoring(%p): pos %d, discarding %p", + saved_heap_ptr_stack[num_saved_heap_ptr], num_saved_heap_ptr, bumpalloc_heap_ptr); + bumpalloc_heap_ptr = saved_heap_ptr_stack[num_saved_heap_ptr]; +} + + +#else +// Regular malloc mode: +void INITBUMPALLOC() {} +void save_alloc_state() {} +void restore_alloc_state() {} + +#define BUMPALLOC(n) malloc(n) + +#endif // BUMPALLOC + + +// ------------------------------------- +// ALLOC and ALLOC_PACKED macros +// ------------------------------------- + + +/* + +If parallelism is enabled, we always use a malloc based allocator +since Boehm GC is not thread-safe in its default configuration. It can be +made thread-safe by building it with appropriate flags, but we don't do that. +Presently, all parallel pointer-based programs will leak memory. + +*/ + +#ifdef _PARALLEL +#define ALLOC(n) malloc(n) +#define ALLOC_PACKED_BIG(n) malloc(n) +char *ALLOC_COUNTED(size_t size) { + bump_global_region_count(); + return ALLOC(size); +} +#else + #ifdef _POINTER +#define ALLOC(n) GC_MALLOC(n) +#define ALLOC_PACKED_BIG(n) GC_MALLOC(n) +char *ALLOC_COUNTED(size_t size) { + bump_global_region_count(); + return GC_MALLOC(size); +} + #else +#define ALLOC(n) malloc(n) +#define ALLOC_PACKED_BIG(n) malloc(n) +char *ALLOC_COUNTED(size_t size) { + bump_global_region_count(); + return ALLOC(size); +} + #endif // _POINTER +#endif // _PARALLEL + + +// Could try alloca() here. Better yet, we could keep our own, +// separate stack and insert our own code to restore the pointer +// before any function that (may have) called ALLOC_SCOPED returns. + +// #define ALLOC_SCOPED() alloca(1024) +#define ALLOC_SCOPED(n) alloca(n) +// #define ALLOC_SCOPED() alloc_scoped() + +// Stack allocation is either too small or blows our stack. +// We need a way to make a giant stack if we want to use alloca. +// #define ALLOC_SCOPED() ALLOC(global_init_biginf_buf_size) + +// Our global pointer. No parallelism. +// static char* stack_scoped_region; +// char* alloc_scoped() { return stack_scoped_region; } + + + +// ------------------------------------- +// Basic types +// ------------------------------------- + +// Must be consistent with sizeOfTy defined in Gibbon.Language.Syntax. + +typedef unsigned char TagTyPacked; +typedef unsigned char TagTyBoxed; +typedef long long IntTy; +typedef char CharTy; +typedef float FloatTy; +typedef unsigned long long SymTy; +typedef bool BoolTy; +typedef char* PtrTy; +typedef char* CursorTy; + +// ------------------------------------- +// Arenas and dictionaries +// ------------------------------------- + +typedef struct mem_arena { + int ind; + char* mem; // TODO(vollmerm): make this a list of chunks? + void* reflist; +} mem_arena_t; + +typedef mem_arena_t* ArenaTy; + +ArenaTy alloc_arena() { + ArenaTy ar = ALLOC(sizeof(mem_arena_t)); + ar->ind = 0; + ar->mem = malloc(global_inf_buf_max_chunk_size); + ar->reflist = 0; + return ar; +} + +void free_arena(ArenaTy ar) { + free(ar->mem); + // TODO(vollmerm): free everything in ar->reflist + free(ar); +} + +CursorTy extend_arena(ArenaTy ar, int size) { + CursorTy ret = ar->mem + ar->ind; + ar->ind += size; + return ret; +} + +typedef struct dict_item { + struct dict_item * next; + int key; + void * ptrval; +} dict_item_t; + +dict_item_t * dict_alloc(ArenaTy ar) { + return (dict_item_t *) extend_arena(ar, sizeof(dict_item_t)); // ALLOC(sizeof(dict_item_t)); +} + +dict_item_t *dict_insert_ptr(ArenaTy ar, dict_item_t *ptr, SymTy key, PtrTy val) { + dict_item_t *ret = dict_alloc(ar); + ret->key = key; + ret->ptrval = val; + ret->next = ptr; + return ret; +} + +PtrTy dict_lookup_ptr(dict_item_t *ptr, SymTy key) { + while (ptr != 0) { + if (ptr->key == key) { + return ptr->ptrval; + } else { + ptr = ptr->next; + } + } + printf("Error, key %lld not found!\n",key); + exit(1); +} + +// ------------------------------------- +// Sets +// ------------------------------------- + + +struct set_elem { + int val; + UT_hash_handle hh; +}; + +typedef struct set_elem* SymSetTy; + +SymSetTy empty_set() { + return NULL; +} + +SymSetTy insert_set(SymSetTy set, int sym) { + SymSetTy s; + HASH_FIND_INT(set, &sym, s); /* sym already in the hash? */ + if (s==NULL) { + s = malloc(sizeof(struct set_elem)); + s->val = sym; + HASH_ADD_INT(set,val,s); + } + return set; +} + +BoolTy contains_set(SymSetTy set, int sym) { + SymSetTy s; + HASH_FIND_INT(set, &sym, s); + return (s!=NULL); +} + +// ------------------------------------- +// Sym Hash +// ------------------------------------- + +struct sym_hash_elem { + int key; + int val; + UT_hash_handle hh; +}; + +typedef struct sym_hash_elem* SymHashTy; + +typedef struct sym_hash_elem* IntHashTy; + +SymHashTy empty_hash() { + return NULL; +} + +SymHashTy insert_hash(SymHashTy hash, int k, int v) { + SymHashTy s; + // NOTE: not checking for duplicates! + // s = malloc(sizeof(struct sym_hash_elem)); + s = ALLOC(sizeof(struct sym_hash_elem)); + s->val = v; + s->key = k; + HASH_ADD_INT(hash,key,s); + + return hash; +} + +IntTy lookup_hash(SymHashTy hash, int k) { + SymHashTy s; + HASH_FIND_INT(hash,&k,s); + if (s==NULL) { + return k; // NOTE: return original key if val not found + // TODO(vollmerm): come up with something better to do here + } else { + return s->val; + } +} + +BoolTy contains_hash(SymHashTy hash, int sym) { + SymHashTy s; + HASH_FIND_INT(hash,&sym,s); + return (s!=NULL); +} + +// ------------------------------------- +// Helpers +// ------------------------------------- + +char* read_benchfile_param() { + if (global_benchfile_param == NULL) { + fprintf(stderr, "read_benchfile_param: benchmark input file was not set! Set using --bench-input.\n"); + exit(1); + } else + return global_benchfile_param; +} + +char* read_arrayfile_param() { + if (global_arrayfile_param == NULL) { + fprintf(stderr, "read_arrayfile_param: array input file was not set! Set using --array-input.\n"); + exit(1); + } else + return global_arrayfile_param; +} + +IntTy read_arrayfile_length_param() { + if (global_arrayfile_length_param == -1) { + fprintf(stderr, "read_arrayfile_length_param: array input file length was not set! Set using --array-input-length.\n"); + exit(1); + } else + return global_arrayfile_length_param; +} + + +// fun fact: __ prefix is actually reserved and this is an undefined behavior. +// These functions must be provided by the code generator. +int __main_expr(); + + +void show_usage(char** argv) +{ + printf("\n"); + printf("This binary was generated by the Gibbon compiler.\n"); + printf("\n"); + printf("Usage: %s [OPTS] [size] [iters]\n", argv[0]); + + printf("\n"); + printf("Options:\n"); + printf(" --buffer-size Set the buffer size (default %lld).\n", global_init_biginf_buf_size); + printf(" --bench-input Set the input file read for benchmarking. Applies only\n"); + printf(" IF the program was *compiled* with --bench-fun. \n"); + return; +} + +double avg(const double* arr, int n) +{ + double sum = 0.0; + for(int i=0; itv_sec - t0->tv_sec) + + ((double)(t1->tv_nsec - t0->tv_nsec) / 1000000000.0); +} + +int compare_doubles(const void *a, const void *b) +{ + const double *da = (const double *) a; + const double *db = (const double *) b; + return (*da > *db) - (*da < *db); +} + +// Exponentiation +IntTy expll(IntTy base, IntTy pow) { + if (base == 2) { + return (1 << pow); + } else { + IntTy i, result = 1; + for (i = 0; i < pow; i++) + result *= base; + return result; + } + } + +// ------------------------------------- +// Symbol table +// ------------------------------------- + +#define global_max_symbol_len 256 + +// Invariant: should always be equal to max(sym_table_keys) +static SymTy global_gensym_counter = 0; + +// Its value is updated by the flags parser. +static char *global_bench_prog_param; + +static SymTy newline_symbol = -1; +static SymTy space_symbol = -1; +static SymTy comma_symbol = -1; +static SymTy leftparen_symbol = -1; +static SymTy rightparen_symbol = -1; + +typedef struct SymTable_elem { + SymTy idx; /* key */ + char value[global_max_symbol_len]; + UT_hash_handle hh; /* makes this structure hashable */ +} SymTable_elem; + +// important! initialize to NULL +SymTable_elem *global_sym_table = NULL; + +void add_symbol(SymTy idx, char *value) { + struct SymTable_elem *s; + s = ALLOC(sizeof(struct SymTable_elem)); + s->idx = idx; + strcpy(s->value, value); + HASH_ADD(hh, global_sym_table, idx, sizeof(IntTy), s); + if (idx > global_gensym_counter) { + global_gensym_counter = idx; + } +} + +void set_newline(SymTy idx) { + newline_symbol = idx; + add_symbol(idx,"NEWLINE"); +} + +void set_space(SymTy idx) { + space_symbol = idx; + add_symbol(idx,"SPACE"); +} + +void set_comma(SymTy idx) { + comma_symbol = idx; + add_symbol(idx,"COMMA"); +} + +void set_leftparen(SymTy idx) { + leftparen_symbol = idx; + add_symbol(idx,"LEFTPAREN"); +} + +void set_rightparen(SymTy idx) { + rightparen_symbol = idx; + add_symbol(idx,"RIGHTPAREN"); +} + +IntTy print_symbol(SymTy idx) { + if (idx == comma_symbol) { + return printf(","); + } else if (idx == newline_symbol) { + return printf("\n"); + } else if (idx == space_symbol) { + return printf(" "); + } else if (idx == leftparen_symbol) { + return printf("("); + } else if (idx == rightparen_symbol) { + return printf(")"); + } else { + struct SymTable_elem *s; + HASH_FIND(hh, global_sym_table, &idx, sizeof(SymTy), s); + if (s == NULL) { + return printf("%lld", idx); + } else { + return printf("%s", s->value); + } + + } +} + +#ifdef _PARALLEL +SymTy gensym() { + SymTy idx = __atomic_add_fetch(&global_gensym_counter, 1, __ATOMIC_SEQ_CST); + return idx; +} +#else +SymTy gensym() { + global_gensym_counter += 1; + SymTy idx = global_gensym_counter; + return idx; +} +#endif + +void free_symtable() { + struct SymTable_elem *elt, *tmp; + HASH_ITER(hh, global_sym_table, elt, tmp) { + HASH_DEL(global_sym_table,elt); + } + free(elt); + free(tmp); +} + +/* + +---------------------------------------- +Garbage collection +---------------------------------------- + + Gibbon has "growing regions" i.e each logical region is backed by a doubly linked-list + of smaller chunks which grows as required. In addition to actual data, each chunk + stores some additional metadata (RegionFooter) to chain the chunks together in a list + and for garbage collection. The footer: + + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + serialized data | rf_reg_metadata_ptr | rf_seq_no | rf_size | rf_next | rf_prev + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + The metadata after the serialized data serves various purposes: + + - rf_reg_metadata_ptr: A pointer to a RegionTy struct that contains various metadata. + Of particular interest to us are the fields: + + = reg_id: A unique identifier for a region. + + = refcount and outset: Whenever an inter-region indirection is created, we record that information + using these two fields. Suppose we have an indirection from region A that points to some chunk + in region B. Then A's outset will store a pointer to that chunk's footer, and B's refcount will + be bumped by 1. Note that all there's only 1 refcount cell, and 1 outset per logical region, + and chunks only store a pointer to them. + + - rf_seq_no: The index of this particular chunk in the list. + + - rf_size: Used during bounds checking to calculate the size of the next region in + the linked list. + + - rf_next / rf_prev: Point to the next and previous chunk respectively. + + +There are two ways in which a region may be freed: + +(1) Whenever it goes out of scope + + The RTS tries to free a region whenever it goes out of scope. But this doesn't always succeed as + regions sometimes contain values that "escape". One reason why this'll happen is if there's an + indirection from A->B, and A lives longer than B. + In such a case, when B goes out of scope it's refcount won't be 0, and the RTS won't free it. + This brings us to (2). + +(2) + + When the RTS successfully frees a region, it decrements the refcounts of all the regions it + points to (via the outset). At the same time, if it encounters a region in the outset whoose + refcount becomes 0 after the decrement, it calls free_region on that. This way we can be sure + that all regions will eventually be garbage collected before the program exits. + + + +Why is it a doubly linked-list? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Due to way that bounds-checking works, the pointers in the outset may actually point to any +arbitrary chunk in the chain. However, we must call free_region on the first one to ensure that +all of them are GC'd. So we need pointers to traverse backward get to the first one. +'trav_to_first_chunk' accomplishes this. + + */ + +#define MAX_OUTSET_LENGTH 10 + +typedef struct RegionTy_struct { + SymTy reg_id; + uint reg_refcount; + CursorTy reg_heap; + uint reg_outset_len; + CursorTy reg_outset[MAX_OUTSET_LENGTH]; +} RegionTy; + +typedef struct RegionFooter_struct { + RegionTy *rf_reg_metadata_ptr; + + IntTy rf_seq_no; + IntTy rf_size; + struct RegionFooter_struct *rf_next; + struct RegionFooter_struct *rf_prev; +} RegionFooter; + +typedef struct ChunkTy_struct { + CursorTy chunk_start; + CursorTy chunk_end; +} ChunkTy; + +static inline void insert_into_outset(CursorTy ptr, RegionTy *reg) { + uint outset_len = reg->reg_outset_len; + // Check for duplicates. + for (uint i = 0; i < outset_len; i++) { + if (ptr == reg->reg_outset[i]) { + return; + } + } + // Otherwise, insert into the outset. + reg->reg_outset[outset_len] = ptr; + reg->reg_outset_len = outset_len + 1; + return; +} + +static inline void remove_from_outset(CursorTy ptr, RegionTy *reg) { + uint outset_len = reg->reg_outset_len; + CursorTy *outset = reg->reg_outset; + int i; + if (outset_len == 0) { + fprintf(stderr, "remove_from_outset: empty outset\n"); + exit(1); + } + // Position of 'ptr' in the outset. + int elt_idx = -1; + for (i = 0; i < outset_len; i++) { + if (ptr == outset[i]) { + elt_idx = i; + } + } + if (elt_idx == -1) { + fprintf(stderr, "remove_from_outset: element not found\n"); + exit(1); + } + // Move all elements ahead of 'elt_idx' back by one position. + for (i = elt_idx; i < outset_len; i++) { + outset[i] = outset[i+1]; + } + return; +} + +RegionTy *alloc_region(IntTy size) { + // Allocate the region metadata. + RegionTy *reg = ALLOC(sizeof(RegionTy)); + if (reg == NULL) { + printf("alloc_region: allocation failed: %ld", sizeof(RegionTy)); + exit(1); + } + + // Allocate the first chunk. + IntTy total_size = size + sizeof(RegionFooter); + CursorTy heap = ALLOC_PACKED_BIG(total_size); + if (heap == NULL) { + printf("alloc_region: malloc failed: %lld", total_size); + exit(1); + } + // Not heap+total_size, since we must keep space for the footer. + CursorTy heap_end = heap + size; + + // Initialize metadata fields. + reg->reg_id = gensym(); + reg->reg_refcount = 1; + reg->reg_heap = heap; + reg->reg_outset_len = 0; + +#ifdef _DEBUG + printf("Allocated a region(%lld): %lld bytes.\n", reg->reg_id, size); +#endif + + // Write the footer. + RegionFooter *footer = (RegionFooter *) heap_end; + footer->rf_reg_metadata_ptr = reg; + footer->rf_seq_no = 1; + footer->rf_size = size; + footer->rf_next = NULL; + footer->rf_prev = NULL; + + return reg; +} + +RegionTy *alloc_counted_region(IntTy size) { + // Bump the count. + bump_global_region_count(); + return alloc_region(size); +} + +ChunkTy alloc_chunk(CursorTy end_old_chunk) { + // Get size from current footer. + RegionFooter *footer = (RegionFooter *) end_old_chunk; + IntTy newsize = footer->rf_size * 2; + // See #110. + if (newsize > global_inf_buf_max_chunk_size) { + newsize = global_inf_buf_max_chunk_size; + } + IntTy total_size = newsize + sizeof(RegionFooter); + + // Allocate. + CursorTy start = ALLOC_PACKED_BIG(total_size); + if (start == NULL) { + printf("alloc_chunk: malloc failed: %lld", total_size); + exit(1); + } + CursorTy end = start + newsize; + + // Link the next chunk's footer. + footer->rf_next = (RegionFooter *) end; + + // Write the footer. + RegionFooter* new_footer = (RegionFooter *) end; + new_footer->rf_reg_metadata_ptr = footer->rf_reg_metadata_ptr; + new_footer->rf_seq_no = footer->rf_seq_no + 1; + new_footer->rf_size = newsize; + new_footer->rf_next = NULL; + new_footer->rf_prev = footer; + +#ifdef _DEBUG + RegionTy *reg = (RegionTy*) new_footer->rf_reg_metadata_ptr; + printf("alloc_chunk: allocated %lld bytes for region %lld.\n", total_size, reg->reg_id); +#endif + + return (ChunkTy) {start , end}; +} + +RegionFooter* trav_to_first_chunk(RegionFooter *footer) { + if (footer->rf_seq_no == 1) { + return footer; + } else if (footer->rf_prev == NULL) { + fprintf(stderr, "No previous chunk found at rf_seq_no: %lld", footer->rf_seq_no); + return NULL; + } else { + trav_to_first_chunk((RegionFooter *) footer->rf_prev); + } + return NULL; +} + +uint get_ref_count(CursorTy end_ptr) { + RegionFooter *footer = (RegionFooter *) end_ptr; + RegionTy *reg = (RegionTy *) footer->rf_reg_metadata_ptr; + return reg->reg_refcount; +} + +// B is the pointer, and A is the pointee (i.e B -> A). +// Bump A's refcount and update B's outset. +static inline void bump_ref_count(CursorTy end_b, CursorTy end_a) { + // Grab footers. + RegionFooter *footer_a = (RegionFooter *) end_a; + RegionFooter *footer_b = (RegionFooter *) end_b; + + // Grab metadata. + RegionTy *reg_a = (RegionTy *) footer_a->rf_reg_metadata_ptr; + RegionTy *reg_b = (RegionTy *) footer_b->rf_reg_metadata_ptr; + + // Bump A's refcount. + uint current_refcount, new_refcount; + current_refcount = reg_a->reg_refcount; + new_refcount = current_refcount + 1; + reg_a->reg_refcount = new_refcount; + +#ifdef _DEBUG + printf("bump_ref_count: %lld -> %lld\n", reg_b->reg_id, reg_a->reg_id); + printf("bump_ref_count: old-refcount=%d, old-outset-len=%d:\n", current_refcount, reg_b->reg_outset_len); + assert(current_refcount == reg_b->reg_outset_len+1); +#endif + + // Add A to B's outset. + insert_into_outset(end_a, reg_b); + +#ifdef _DEBUG + // printf("bump_ref_count: Added %p to %lld's outset, %p.\n", end_a, reg_b->reg_id, reg_b); + printf("bump_ref_count: new-refcount=%d, new-outset-len=%d\n", new_refcount, reg_b->reg_outset_len); + assert(new_refcount == reg_b->reg_outset_len+1); +#endif + + return; +} + +void free_region(CursorTy end_reg) { + // Grab footer and the metadata. + RegionFooter *footer = (RegionFooter *) end_reg; + RegionTy *reg = (RegionTy *) footer->rf_reg_metadata_ptr; + + // + RegionFooter *first_chunk_footer, *next_chunk_footer; + CursorTy first_chunk, next_chunk; + + // Decrement current reference count. + uint current_refcount, new_refcount; + current_refcount = reg->reg_refcount; + new_refcount = 0; + if (current_refcount != 0) { + new_refcount = current_refcount - 1; + reg->reg_refcount = new_refcount; + } + +#ifdef _DEBUG + printf("free_region(%lld): refcounts (1): old-refcount=%d, new-refcount=%d:\n", reg->reg_id, current_refcount, new_refcount); +#endif + + + // Free this region recount is 0. + if (new_refcount == 0) { + +#ifdef _DEBUG + printf("free_region(%lld): outset length: %d\n", reg->reg_id, reg->reg_outset_len); +#endif + + // Decrement refcounts, free regions with refcount==0 and also free + // elements of the outset. + if (reg->reg_outset_len != 0) { + uint outset_len = reg->reg_outset_len; + CursorTy *outset = reg->reg_outset; + RegionFooter *elt_footer; + RegionTy *elt_reg; + uint elt_current_refcount, elt_new_refcount; + CursorTy to_be_removed[MAX_OUTSET_LENGTH]; + uint to_be_removed_idx = 0; + for (int i = 0; i < outset_len; i++) { + elt_footer = (RegionFooter *) outset[i]; + elt_reg = (RegionTy *) elt_footer->rf_reg_metadata_ptr; +#ifdef _DEBUG + elt_current_refcount = elt_reg->reg_refcount; +#endif + elt_new_refcount = elt_current_refcount - 1; + elt_reg->reg_refcount = elt_new_refcount; +#ifdef _DEBUG + printf("free_region(%lld): old-refcount=%d, new-refcount=%d:\n", + elt_reg->reg_id, elt_current_refcount, elt_reg->reg_refcount); +#endif + if (elt_new_refcount == 0) { + // See [Why is it a doubly linked-list?] above + first_chunk_footer = trav_to_first_chunk(elt_footer); + if (first_chunk_footer != NULL) { + free_region((CursorTy) first_chunk_footer); + } + } + to_be_removed[to_be_removed_idx] = outset[i]; + to_be_removed_idx++; + } + // Remove elements from the outset. + for (uint i = 0; i < to_be_removed_idx; i++) { + remove_from_outset(to_be_removed[i], reg); + } + } + + +#ifdef _DEBUG + // Bookkeeping + IntTy num_freed_chunks = 0, total_bytesize = 0; +#endif + + // Free the chunks in this region. + first_chunk = end_reg - footer->rf_size; + first_chunk_footer = footer; + next_chunk = (char*) footer->rf_next; + +#ifdef _DEBUG + printf("free_region(%lld)\n", reg->reg_id); +#endif + +#ifdef _DEBUG + num_freed_chunks++; + total_bytesize = total_bytesize + first_chunk_footer->rf_size; +#endif + free(first_chunk); + + while (next_chunk != NULL) { + next_chunk_footer = (RegionFooter *) next_chunk; + #ifdef _DEBUG + num_freed_chunks++; + total_bytesize = total_bytesize + next_chunk_footer->rf_size; + #endif + free(next_chunk - next_chunk_footer->rf_size); + next_chunk = (char*) next_chunk_footer->rf_next; + } + +#ifdef _DEBUG + printf("free_region(%lld): Freed %lld bytes across %lld chunks.\n", + reg->reg_id, total_bytesize, num_freed_chunks); +#endif + + // Free the metadata. + free(reg); + + } else { +#ifdef _DEBUG + printf("free_region(%lld): non-zero refcount: %d.\n", + reg->reg_id, reg->reg_refcount); +#endif + } +} + +// Assume that all nodes with size information have tags >= 150. +BoolTy is_big(IntTy i, CursorTy cur) { + TagTyPacked tag = *(TagTyPacked *) cur; + if (tag >= 150) { + cur += 1; + IntTy size = *(IntTy *) cur; + if (size >= i) { + return true; + } else { + return false; + } + } + return false; +} + +// ------------------------------------- +// Vectors +// ------------------------------------- + +typedef struct VectorTy_struct { + // Bounds on the vector. + IntTy vec_lower, vec_upper; + + // Size of each element. + IntTy vec_elt_size; + + // Actual elements of the vector. + void* vec_data; +} VectorTy; + +VectorTy* vector_alloc(IntTy num, IntTy elt_size) { + VectorTy *vec = ALLOC(sizeof(VectorTy)); + if (vec == NULL) { + printf("alloc_vector: malloc failed: %ld", sizeof(VectorTy)); + exit(1); + } + void* data = ALLOC(num * elt_size); + if (data == NULL) { + printf("alloc_vector: malloc failed: %ld", sizeof(num * elt_size)); + exit(1); + } + vec->vec_lower = 0; + vec->vec_upper = num; + vec->vec_elt_size = elt_size; + vec->vec_data = data; + return vec; +} + +IntTy vector_length(VectorTy *vec) { + return (vec->vec_upper - vec->vec_lower); +} + +BoolTy vector_is_empty(VectorTy *vec) { + return (vector_length(vec) == 0); +} + +VectorTy* vector_slice(IntTy i, IntTy n, VectorTy *vec) { + IntTy lower = vec->vec_lower + i; + IntTy upper = vec->vec_lower + i + n; + if ((lower > vec->vec_upper)) { + printf("vector_slice: lower out of bounds, %lld > %lld", lower, vec->vec_upper); + exit(1); + } + if ((upper > vec->vec_upper)) { + printf("vector_slice: upper out of bounds: %lld > %lld", upper, vec->vec_upper); + exit(1); + } + VectorTy *vec2 = ALLOC(sizeof(VectorTy)); + if (vec == NULL) { + printf("vector_slice: malloc failed: %ld", sizeof(VectorTy)); + exit(1); + } + vec2->vec_lower = lower; + vec2->vec_upper = upper; + vec2->vec_elt_size = vec->vec_elt_size; + vec2->vec_data = vec->vec_data; + return vec2; +} + +// The callers must cast the return value. +static inline void* vector_nth(VectorTy *vec, IntTy i) { + // if (i < vec->lower || i > vec->upper) { + // printf("vector_nth index out of bounds: %lld (%lld,%lld) \n", i, vec->vec_lower, vec->vec_upper); + // exit(1); + // } + return (vec->vec_data + (vec->vec_elt_size * (vec->vec_lower + i))); +} + +static inline VectorTy* vector_inplace_update(VectorTy *vec, IntTy i, void* elt) { + void* dst = vector_nth(vec, i); + memcpy(dst, elt, vec->vec_elt_size); + return vec; +} + +static inline VectorTy* vector_copy(VectorTy *vec) { + IntTy len = vector_length(vec); + void *start = vector_nth(vec, 0); + VectorTy *vec2 = vector_alloc(len, vec->vec_elt_size); + memcpy(vec2->vec_data, start, len * vec->vec_elt_size); + return vec2; +} + +static inline VectorTy* vector_inplace_sort(VectorTy *vec, int (*compar)(const void *, const void*)) { + void *start = vector_nth(vec, 0); + qsort(start, vector_length(vec), vec->vec_elt_size, compar); + return vec; +} + +static inline VectorTy* vector_sort(VectorTy *vec, int (*compar)(const void *, const void*)) { + VectorTy *vec2 = vector_copy(vec); + vector_inplace_sort(vec2, compar); + return vec2; +} + +static inline VectorTy* vector_concat(VectorTy *vec) { + // Length of the input vector. + IntTy len = vector_length(vec); + // Length of the concatenated vector. + IntTy result_len = 0; + // Size of each element in the concatenated vector. + IntTy result_elt_size = 0; + VectorTy **elt_ref, *elt; + for (IntTy i = 0; i < len; i++) { + elt_ref = vector_nth(vec, i); + elt = *elt_ref; + result_elt_size = elt->vec_elt_size; + result_len += vector_length(elt); + } + + // Concatenated vector. + VectorTy *result = vector_alloc(result_len, result_elt_size); + IntTy elt_len; + // A counter that tracks the index of elements in 'result'. + IntTy k = 0; + for (IntTy i = 0; i < len; i++) { + elt_ref = vector_nth(vec, i); + elt = *elt_ref; + elt_len = vector_length(elt); + + for (IntTy j = 0; j < elt_len; j++) { + void* k_elt = vector_nth(elt, j); + vector_inplace_update(result, k, k_elt); + k++; + } + } + + return result; +} + +static inline void vector_free(VectorTy *vec) { + free(vec->vec_data); + free(vec); + return; +} + +static inline VectorTy* vector_merge(VectorTy *vec1, VectorTy *vec2) { + if (vec1->vec_upper != vec2->vec_lower) { + printf("vector_merge: non-contiguous slices, (%lld,%lld), (%lld,%lld).", + vec1->vec_lower, vec1->vec_upper, vec2->vec_lower, vec2->vec_upper); + exit(1); + } + VectorTy *merged = ALLOC(sizeof(VectorTy)); + if (merged == NULL) { + printf("vector_merge: malloc failed: %ld", sizeof(VectorTy)); + exit(1); + } + merged->vec_lower = vec1->vec_lower; + merged->vec_upper = vec2->vec_upper; + merged->vec_elt_size = vec1->vec_elt_size; + merged->vec_data = vec1->vec_data; + return merged; +} + +void print_timing_array(VectorTy *times) { + printf("TIMES: ["); + double *d; + IntTy n = vector_length(times); + for(int i = 0; i < n; i++) { + d = vector_nth(times, i); + if (i == (n-1)) { + printf("%f",*d); + } + else { + printf("%f, ",*d); + } + } + printf("]\n"); +} + +double sum_timing_array(VectorTy *times) { + double *d; + double acc = 0; + for(int i = 0; i < vector_length(times); i++) { + d = vector_nth(times, i); + acc += *d; + } + return acc; +} + +// ------------------------------------- +// Linked lists +// ------------------------------------- + +typedef struct ListTy_struct { + IntTy ll_data_size; + void* ll_data; + struct ListTy_struct* ll_next; +} ListTy; + +static inline ListTy* list_alloc(IntTy data_size) { + // ListTy *ls = ALLOC(sizeof(ListTy)); + ListTy *ls = BUMPALLOC(sizeof(ListTy)); + ls->ll_data_size = data_size; + ls->ll_data = NULL; + ls->ll_next = NULL; + return ls; +} + +static inline BoolTy list_is_empty(ListTy *ls) { + return ls->ll_next == NULL; +} + +static inline ListTy* list_cons(void* elt, ListTy *ls) { + // void* data = ALLOC(ls->data_size); + void* data = BUMPALLOC(ls->ll_data_size); + if (data == NULL) { + printf("list_cons: malloc failed: %lld", ls->ll_data_size); + exit(1); + } + memcpy(data, elt, ls->ll_data_size); + // ListTy *res = ALLOC(sizeof(ListTy)); + ListTy *res = BUMPALLOC(sizeof(ListTy)); + res->ll_data_size = ls->ll_data_size; + res->ll_data = data; + res->ll_next = (ListTy*) ls; + return res; +} + +static inline void* list_head(ListTy *ls) { + return ls->ll_data; +} + +static inline ListTy* list_tail(ListTy *ls) { + return ls->ll_next; +} + +static inline void list_free(ListTy *ls) { + free(ls->ll_data); + free(ls); + return; +} + +static inline ListTy* list_copy(ListTy *ls) { + ListTy *ls2 = list_alloc(ls->ll_data_size); + if (ls->ll_data != NULL) { + void* data = BUMPALLOC(ls->ll_data_size); + memcpy(data, ls->ll_data, ls->ll_data_size); + ls2->ll_data = data; + } + ls2->ll_next = ls->ll_next; + return ls2; +} + +// ------------------------------------- +// Ppm Images +// ------------------------------------- + +typedef struct __Pixel_struct { + IntTy field0; + IntTy field1; + IntTy field2; +} __Pixel; + +void writePpm(char* filename, IntTy width, IntTy height, VectorTy *pixels); +void writePpm_loop(FILE *fp, IntTy idx, IntTy end, VectorTy *pixels); + +// Example: writePpm("gibbon_rgb_1000.ppm", 1000, 1000, pixels); +void writePpm(char* filename, IntTy width, IntTy height, VectorTy *pixels) +{ + FILE *fp; + fp = fopen(filename, "w+"); + fprintf(fp, "P3\n"); + fprintf(fp, "%lld %lld\n255\n", width, height); + IntTy len = vector_length(pixels); + writePpm_loop(fp, 0, len, pixels); + fclose(fp); + return; +} + +void writePpm_loop(FILE *fp, IntTy idx, IntTy end, VectorTy *pixels) +{ + BoolTy fltIf_5768_6575 = idx == end; + + if (fltIf_5768_6575) { + return; + } else { + __Pixel *tmp_112; + tmp_112 = (__Pixel *) vector_nth(pixels, idx); + __Pixel tup = *tmp_112; + IntTy x = tup.field0; + IntTy y = tup.field1; + IntTy z = tup.field2; + // write to file. + fprintf(fp, "%lld %lld %lld\n", x, y, z); + writePpm_loop(fp, (idx+1), end, pixels); + } +} + +/* -------------------------------------------------------------------------------- */ + +int main(int argc, char** argv) +{ + // parameters to parse: + // + // num iterations: How many times to repeat a benchmark. + // tree size: An integer passes to `build_tree()`. + + struct rlimit lim; + int code; + if ( (code = getrlimit(RLIMIT_STACK, &lim)) ) { + fprintf(stderr, " [gibbon rts] failed to getrlimit, code %d\n", code); + exit(1); + } + + // lim.rlim_cur = 1024LU * 1024LU * 1024LU; // 1GB stack. + lim.rlim_cur = 512LU * 1024LU * 1024LU; // 500MB stack. + // lim.rlim_max = lim.rlim_cur; // Normal users may only be able to decrease this. + + // WARNING: Haven't yet figured out why this doesn't work on MacOS... +#ifndef __APPLE__ + code = setrlimit(RLIMIT_STACK, &lim); + while (code) { + fprintf(stderr, " [gibbon rts] Failed to set stack size to %llu, code %d\n", (unsigned long long)lim.rlim_cur, code); + lim.rlim_cur /= 2; + // lim.rlim_max /= 2; + if(lim.rlim_cur < 100 * 1024) { + fprintf(stderr, " [gibbon rts] Failed setrlimit stack size to something reasonable; giving up.\n"); + break; // abort(); + } + int code = setrlimit(RLIMIT_STACK, &lim); + } +#endif + + int got_numargs = 0; // How many numeric arguments have we got. + + int i; + for (i = 1; i < argc; ++i) + { + if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) { + show_usage(argv); + exit(0); + } + else if (strcmp(argv[i], "--biginf-buffer-size") == 0 && i < argc - 1) + { + global_init_biginf_buf_size = atoll(argv[i + 1]); + i++; + } + else if (strcmp(argv[i], "--inf-buffer-size") == 0 && i < argc - 1) + { + global_init_inf_buf_size = atoll(argv[i + 1]); + i++; + } + else if ((strcmp(argv[i], "--bench-input") == 0)) { + if (i+1 >= argc) { + fprintf(stderr, "Not enough arguments after --bench-input, expected .\n"); + show_usage(argv); + exit(1); + } + global_benchfile_param = argv[i+1]; + i++; + } + else if ((strcmp(argv[i], "--array-input") == 0)) { + if (i+1 >= argc) { + fprintf(stderr, "Not enough arguments after --array-input, expected .\n"); + show_usage(argv); + exit(1); + } + global_arrayfile_param = argv[i+1]; + i++; + } + else if (strcmp(argv[i], "--array-input-length") == 0 && i < argc - 1) { + global_arrayfile_length_param = atoll(argv[i+1]); + i++; + } + else if (strcmp(argv[i], "--bench-prog") == 0 && i < argc - 1) { + int len = strlen(argv[i+1]); + global_bench_prog_param = (char*) malloc((len+1)*sizeof(char)); + strncpy(global_bench_prog_param,argv[i+1],len); + i++; + } + // If present, we expect the two arguments to be + else if (got_numargs >= 2) { + fprintf(stderr, "Extra arguments left over: "); + for(; i < argc; i++) fprintf(stderr, "%s ", argv[i]); + show_usage(argv); + exit(1); + } else { + if (got_numargs == 0) { + global_size_param = atoll(argv[i]); + got_numargs ++; + } else { + global_iters_param = atoll(argv[i]); + } + } + } + + // Initialize global_bench_prog_param to an empty string in case + // the runtime argument --bench-prog isn't passed. + if (global_bench_prog_param == NULL) { + global_bench_prog_param = (char*) malloc(1*sizeof(char)); + *global_bench_prog_param = '\n'; + } + + __main_expr(); + + return 0; +} + +// ----------------------------------------------------------------------------- +// Program starts here +// ----------------------------------------------------------------------------- + +typedef struct Prod_struct { } Prod; +typedef struct Int64Prod_struct { + IntTy field0; + } Int64Prod; +typedef struct Int64Int64CursorCursorProd_struct { + IntTy field0; + IntTy field1; + CursorTy field2; + CursorTy field3; + } Int64Int64CursorCursorProd; +typedef struct Int64CursorCursorProd_struct { + IntTy field0; + CursorTy field1; + CursorTy field2; + } Int64CursorCursorProd; +typedef struct BoolProd_struct { + BoolTy field0; + } BoolProd; +typedef struct TagCursorProd_struct { + TagTyPacked field0; + CursorTy field1; + } TagCursorProd; +typedef struct CursorProd_struct { + CursorTy field0; + } CursorProd; +CursorTy empty(); +CursorTy insert_num(IntTy x_44_168_244, CursorTy s_45_169_245); +CursorTy insert(IntTy x_66_184_249, CursorTy s_67_185_250); +CursorTy singleton(IntTy x_71_189_258); +CursorTy _copy_without_ptrs_IntSet(CursorTy arg_135_190_261); +CursorTy _copy_IntSet(CursorTy arg_128_197_268); +unsigned char _traverse_IntSet(CursorTy arg_142_204_275); +unsigned char _print_IntSet(CursorTy arg_149_210_281); +CursorTy empty() +{ + PtrTy tailift_300 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) tailift_300)->field0 = 1; + return tailift_300; +} +CursorTy insert_num(IntTy x_44_168_244, CursorTy s_45_169_245) +{ + BoolTy fltIf_234_246 = x_44_168_244 == 0; + + if (fltIf_234_246) { + return insert(x_44_168_244, s_45_169_245); + } else { + IntTy fltAppE_236_247 = x_44_168_244 - 1; + CursorTy fltAppE_235_248 = insert_num(fltAppE_236_247, s_45_169_245); + + return insert(x_44_168_244, fltAppE_235_248); + } +} +CursorTy insert(IntTy x_66_184_249, CursorTy s_67_185_250) +{ + TagTyPacked tag_301 = *(TagTyPacked *) s_67_185_250; + CursorTy tail_302 = s_67_185_250 + sizeof(IntTy); + + + switch_305: + ; + switch (tag_301) { + + case 1: + { + return singleton(x_66_184_249); + break; + } + + case 0: + { + IntTy v_68_186_251 = ((Int64CursorCursorProd *) tail_302)->field0; + CursorTy l_69_187_252 = + ((Int64CursorCursorProd *) tail_302)->field1; + CursorTy r_70_188_253 = + ((Int64CursorCursorProd *) tail_302)->field2; + BoolTy fltIf_237_254 = x_66_184_249 == v_68_186_251; + + if (fltIf_237_254) { + return s_67_185_250; + } else { + BoolTy fltIf_238_255 = x_66_184_249 <= v_68_186_251; + + if (fltIf_238_255) { + CursorTy fltPkd_239_256 = + insert(x_66_184_249, l_69_187_252); + PtrTy tailift_303 = + ALLOC(sizeof(Int64Int64CursorCursorProd)); + + ((Int64Int64CursorCursorProd *) tailift_303)->field0 = 0; + ((Int64Int64CursorCursorProd *) tailift_303)->field1 = + v_68_186_251; + ((Int64Int64CursorCursorProd *) tailift_303)->field2 = + fltPkd_239_256; + ((Int64Int64CursorCursorProd *) tailift_303)->field3 = + r_70_188_253; + return tailift_303; + } else { + CursorTy fltPkd_240_257 = + insert(x_66_184_249, r_70_188_253); + PtrTy tailift_304 = + ALLOC(sizeof(Int64Int64CursorCursorProd)); + + ((Int64Int64CursorCursorProd *) tailift_304)->field0 = 0; + ((Int64Int64CursorCursorProd *) tailift_304)->field1 = + v_68_186_251; + ((Int64Int64CursorCursorProd *) tailift_304)->field2 = + l_69_187_252; + ((Int64Int64CursorCursorProd *) tailift_304)->field3 = + fltPkd_240_257; + return tailift_304; + } + } + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_301"); + exit(1); + } + } +} +CursorTy singleton(IntTy x_71_189_258) +{ + PtrTy fltPkd_241_259 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_241_259)->field0 = 1; + + PtrTy fltPkd_242_260 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) fltPkd_242_260)->field0 = 1; + + PtrTy tailift_306 = ALLOC(sizeof(Int64Int64CursorCursorProd)); + + ((Int64Int64CursorCursorProd *) tailift_306)->field0 = 0; + ((Int64Int64CursorCursorProd *) tailift_306)->field1 = x_71_189_258; + ((Int64Int64CursorCursorProd *) tailift_306)->field2 = fltPkd_241_259; + ((Int64Int64CursorCursorProd *) tailift_306)->field3 = fltPkd_242_260; + return tailift_306; +} +CursorTy _copy_without_ptrs_IntSet(CursorTy arg_135_190_261) +{ + TagTyPacked tag_307 = *(TagTyPacked *) arg_135_190_261; + CursorTy tail_308 = arg_135_190_261 + sizeof(IntTy); + + + switch_311: + ; + switch (tag_307) { + + case 0: + { + IntTy x_136_191_262 = ((Int64CursorCursorProd *) tail_308)->field0; + CursorTy x_137_192_263 = + ((Int64CursorCursorProd *) tail_308)->field1; + CursorTy x_138_193_264 = + ((Int64CursorCursorProd *) tail_308)->field2; + CursorTy y_140_195_266 = _copy_without_ptrs_IntSet(x_137_192_263); + CursorTy y_141_196_267 = _copy_without_ptrs_IntSet(x_138_193_264); + PtrTy tailift_309 = ALLOC(sizeof(Int64Int64CursorCursorProd)); + + ((Int64Int64CursorCursorProd *) tailift_309)->field0 = 0; + ((Int64Int64CursorCursorProd *) tailift_309)->field1 = + x_136_191_262; + ((Int64Int64CursorCursorProd *) tailift_309)->field2 = + y_140_195_266; + ((Int64Int64CursorCursorProd *) tailift_309)->field3 = + y_141_196_267; + return tailift_309; + break; + } + + case 1: + { + PtrTy tailift_310 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) tailift_310)->field0 = 1; + return tailift_310; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_307"); + exit(1); + } + } +} +CursorTy _copy_IntSet(CursorTy arg_128_197_268) +{ + TagTyPacked tag_312 = *(TagTyPacked *) arg_128_197_268; + CursorTy tail_313 = arg_128_197_268 + sizeof(IntTy); + + + switch_316: + ; + switch (tag_312) { + + case 0: + { + IntTy x_129_198_269 = ((Int64CursorCursorProd *) tail_313)->field0; + CursorTy x_130_199_270 = + ((Int64CursorCursorProd *) tail_313)->field1; + CursorTy x_131_200_271 = + ((Int64CursorCursorProd *) tail_313)->field2; + CursorTy y_133_202_273 = _copy_IntSet(x_130_199_270); + CursorTy y_134_203_274 = _copy_IntSet(x_131_200_271); + PtrTy tailift_314 = ALLOC(sizeof(Int64Int64CursorCursorProd)); + + ((Int64Int64CursorCursorProd *) tailift_314)->field0 = 0; + ((Int64Int64CursorCursorProd *) tailift_314)->field1 = + x_129_198_269; + ((Int64Int64CursorCursorProd *) tailift_314)->field2 = + y_133_202_273; + ((Int64Int64CursorCursorProd *) tailift_314)->field3 = + y_134_203_274; + return tailift_314; + break; + } + + case 1: + { + PtrTy tailift_315 = ALLOC(sizeof(Int64Prod)); + + ((Int64Prod *) tailift_315)->field0 = 1; + return tailift_315; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_312"); + exit(1); + } + } +} +unsigned char _traverse_IntSet(CursorTy arg_142_204_275) +{ + TagTyPacked tag_317 = *(TagTyPacked *) arg_142_204_275; + CursorTy tail_318 = arg_142_204_275 + sizeof(IntTy); + + + switch_319: + ; + switch (tag_317) { + + case 0: + { + IntTy x_143_205_276 = ((Int64CursorCursorProd *) tail_318)->field0; + CursorTy x_144_206_277 = + ((Int64CursorCursorProd *) tail_318)->field1; + CursorTy x_145_207_278 = + ((Int64CursorCursorProd *) tail_318)->field2; + unsigned char y_147_208_279 = _traverse_IntSet(x_144_206_277); + unsigned char y_148_209_280 = _traverse_IntSet(x_145_207_278); + + return 0; + break; + } + + case 1: + { + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_317"); + exit(1); + } + } +} +unsigned char _print_IntSet(CursorTy arg_149_210_281) +{ + TagTyPacked tag_320 = *(TagTyPacked *) arg_149_210_281; + CursorTy tail_321 = arg_149_210_281 + sizeof(IntTy); + + + switch_322: + ; + switch (tag_320) { + + case 0: + { + IntTy x_150_211_282 = ((Int64CursorCursorProd *) tail_321)->field0; + CursorTy x_151_212_283 = + ((Int64CursorCursorProd *) tail_321)->field1; + CursorTy x_152_213_284 = + ((Int64CursorCursorProd *) tail_321)->field2; + unsigned char wildcard_156_214_285 = print_symbol(297); + unsigned char wildcard_160_215_286 = print_symbol(299); + unsigned char y_153_216_287 = printf("%lld", x_150_211_282); + unsigned char wildcard_159_217_288 = print_symbol(299); + unsigned char y_154_218_289 = _print_IntSet(x_151_212_283); + unsigned char wildcard_158_219_290 = print_symbol(299); + unsigned char y_155_220_291 = _print_IntSet(x_152_213_284); + unsigned char wildcard_157_221_292 = print_symbol(296); + + return 0; + break; + } + + case 1: + { + unsigned char wildcard_161_222_293 = print_symbol(298); + unsigned char wildcard_162_223_294 = print_symbol(296); + + return 0; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tag_320"); + exit(1); + } + } +} +int __main_expr() +{ + add_symbol(296, ")"); + add_symbol(297, "(PureSet"); + add_symbol(298, "(EmptySet"); + add_symbol(299, " "); + + CursorTy fltAppE_233_243 = empty(); + CursorTy tmp_app_295 = insert_num(1000, fltAppE_233_243); + + _print_IntSet(tmp_app_295); + printf("\n"); + free_symtable(); + return 0; +} \ No newline at end of file diff --git a/benchmarks/modules/graph_layout.py b/benchmarks/modules/graph_layout.py new file mode 100644 index 000000000..3cd25ed00 --- /dev/null +++ b/benchmarks/modules/graph_layout.py @@ -0,0 +1,50 @@ +import matplotlib.pyplot as plt +import numpy as np +import re + +ids = [] +depths = [] +times = [] + +with open("run.log", "r") as f: + line = f.readline() + i = -1 + while (line): + if (re.search(r"---", line)): + i = i + 1 + ids.append(0) + depths.append(0) + times.append(0) + else: + match = re.search(r"ID: \[(?P-*\d+)\]", line) + if(match): + ids[i] = int(match.groups("num")[0]) + else: + match = re.search(r"TIMES: \[(?P[\d\.]+)\]", line) + if(match): + times[i] = float(match.groups("num")[0]) + else: + match = re.search(r"DEPTH: \[(?P\d+)\]", line) + if(match): + depths[i] = int(match.groups("num")[0]) + + line = f.readline() + +#print("ids: ") +#print(ids) +#print("\ndepths:") +#print(depths) +#print("\ntimes:") +#print(times) + +fig = plt.figure() +ax = fig.add_subplot(projection="3d") +ax.scatter(ids[::727], depths[::727], times[::727]) +#for i in range(0, len(ids), 11): + + +ax.set_xlabel("index") +ax.set_ylabel("depth") +ax.set_zlabel("time to access") + +plt.show() \ No newline at end of file diff --git a/benchmarks/modules/run.log b/benchmarks/modules/run.log new file mode 100644 index 000000000..0b11ab34b --- /dev/null +++ b/benchmarks/modules/run.log @@ -0,0 +1,137 @@ +--- +ID: [8] +TIMES: [0.000000] +ITERS: 1 +SIZE: 1 +BATCHTIME: 1.400000e-07 +SELFTIMED: 1.400000e-07 +DEPTH: [5] +--- +ID: [7] +TIMES: [0.000000] +ITERS: 1 +SIZE: 1 +BATCHTIME: 9.000000e-08 +SELFTIMED: 9.000000e-08 +DEPTH: [4] +--- +ID: [6] +TIMES: [0.000000] +ITERS: 1 +SIZE: 1 +BATCHTIME: 7.000000e-08 +SELFTIMED: 7.000000e-08 +DEPTH: [3] +--- +ID: [5] +TIMES: [0.000000] +ITERS: 1 +SIZE: 1 +BATCHTIME: 8.000000e-08 +SELFTIMED: 8.000000e-08 +DEPTH: [4] +--- +ID: [4] +TIMES: [0.000000] +ITERS: 1 +SIZE: 1 +BATCHTIME: 6.000000e-08 +SELFTIMED: 6.000000e-08 +DEPTH: [2] +--- +ID: [3] +TIMES: [0.000000] +ITERS: 1 +SIZE: 1 +BATCHTIME: 8.000000e-08 +SELFTIMED: 8.000000e-08 +DEPTH: [4] +--- +ID: [2] +TIMES: [0.000000] +ITERS: 1 +SIZE: 1 +BATCHTIME: 7.000000e-08 +SELFTIMED: 7.000000e-08 +DEPTH: [3] +--- +ID: [1] +TIMES: [0.000000] +ITERS: 1 +SIZE: 1 +BATCHTIME: 7.000000e-08 +SELFTIMED: 7.000000e-08 +DEPTH: [4] +--- +ID: [0] +TIMES: [0.000000] +ITERS: 1 +SIZE: 1 +BATCHTIME: 7.000000e-08 +SELFTIMED: 7.000000e-08 +DEPTH: [1] +--- +ID: [-1] +TIMES: [0.000000] +ITERS: 1 +SIZE: 1 +BATCHTIME: 8.000000e-08 +SELFTIMED: 8.000000e-08 +DEPTH: [4] +--- +ID: [-2] +TIMES: [0.000000] +ITERS: 1 +SIZE: 1 +BATCHTIME: 7.000000e-08 +SELFTIMED: 7.000000e-08 +DEPTH: [3] +--- +ID: [-3] +TIMES: [0.000000] +ITERS: 1 +SIZE: 1 +BATCHTIME: 7.000000e-08 +SELFTIMED: 7.000000e-08 +DEPTH: [4] +--- +ID: [-4] +TIMES: [0.000000] +ITERS: 1 +SIZE: 1 +BATCHTIME: 6.000000e-08 +SELFTIMED: 6.000000e-08 +DEPTH: [2] +--- +ID: [-5] +TIMES: [0.000000] +ITERS: 1 +SIZE: 1 +BATCHTIME: 6.000000e-08 +SELFTIMED: 6.000000e-08 +DEPTH: [4] +--- +ID: [-6] +TIMES: [0.000000] +ITERS: 1 +SIZE: 1 +BATCHTIME: 7.000000e-08 +SELFTIMED: 7.000000e-08 +DEPTH: [3] +--- +ID: [-7] +TIMES: [0.000000] +ITERS: 1 +SIZE: 1 +BATCHTIME: 6.000000e-08 +SELFTIMED: 6.000000e-08 +DEPTH: [4] +--- +ID: [-8] +TIMES: [0.000000] +ITERS: 1 +SIZE: 1 +BATCHTIME: 9.000000e-08 +SELFTIMED: 9.000000e-08 +DEPTH: [-1] +0 diff --git a/benchmarks/tests/test_set b/benchmarks/tests/test_set new file mode 100755 index 000000000..49d6e8608 Binary files /dev/null and b/benchmarks/tests/test_set differ diff --git a/benchmarks/tests/test_set.c b/benchmarks/tests/test_set.c new file mode 100644 index 000000000..6503f9885 --- /dev/null +++ b/benchmarks/tests/test_set.c @@ -0,0 +1,1390 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// #include +#ifdef _WIN64 +#include +#endif +#include +#include +#include // For va_start etc +#include +#include +#include +#include +#ifdef _POINTER +#include +#endif +#ifdef _PARALLEL +#include +#include +#endif + +#define KB 1024lu +#define MB (KB * 1000lu) +#define GB (MB * 1000lu) + +#define REDIRECTION_TAG 255 +#define INDIRECTION_TAG 254 + +// Initial size of BigInfinite buffers +static long long global_init_biginf_buf_size = (4 * GB); + +// Initial size of Infinite buffers +static long long global_init_inf_buf_size = 1 * KB; + +// Maximum size of a chunk, see GitHub #110. +static long long global_inf_buf_max_chunk_size = 1 * GB; + +static long long global_size_param = 1; +static long long global_iters_param = 1; + +static char* global_benchfile_param = NULL; +static char* global_arrayfile_param = NULL; +// Number of lines in the arrayfile +static long long global_arrayfile_length_param = -1; + +// Sequential for now: +static const int num_workers = 1; + +// Count the number of regions allocated. +static long long global_region_count = 0; +static bool global_region_count_flag = false; + +#ifdef _PARALLEL +static inline void bump_global_region_count() { + __atomic_add_fetch(&global_region_count, 1, __ATOMIC_SEQ_CST); + return; +} +#else +static inline void bump_global_region_count() { + global_region_count++; + return; +} +#endif + +static inline void print_global_region_count() { + printf("REGION_COUNT: %lld\n", global_region_count); + return; +} + +#define REDIRECTION_NODE_SIZE 9 +#define MAX(a,b) (((a)>(b))?(a):(b)) +#define MIN(a,b) (((a)<(b))?(a):(b)) + +// https://www.cprogramming.com/snippets/source-code/find-the-number-of-cpu-cores-for-windows-mac-or-linux +static int get_num_processors() { +#ifdef _WIN64 + SYSTEM_INFO sysinfo; + GetSystemInfo(&sysinfo); + return sysinfo.dwNumberOfProcessors; +#else + return sysconf(_SC_NPROCESSORS_ONLN); +#endif +} + +// Requires -std=gnu11 +int dbgprintf(const char *format, ...) { + int code = 0; + va_list args; + va_start(args, format); +#ifdef _DEBUG + code = vprintf(format, args); +#endif + va_end(args); + return code; +} + + +// ----------------------------------------------------------------------------- +// Allocators +// ----------------------------------------------------------------------------- + + +// ------------------------------------- +// Bump allocation for linked-lists +// ------------------------------------- + + +#ifdef _BUMPALLOC +// #define _DEBUG +#warning "Using bump allocator." + +__thread char* bumpalloc_heap_ptr = (char*)NULL; +__thread char* bumpalloc_heap_ptr_end = (char*)NULL; + +char* saved_heap_ptr_stack[100]; +int num_saved_heap_ptr = 0; + +// For simplicity just use a single large slab: +static inline void INITBUMPALLOC() { + bumpalloc_heap_ptr = (char*)malloc(global_init_biginf_buf_size); + bumpalloc_heap_ptr_end = bumpalloc_heap_ptr + global_init_biginf_buf_size; +#ifdef _DEBUG + printf("Arena size for bump alloc: %lld\n", global_init_biginf_buf_size); + printf("BUMPALLOC/INITBUMPALLOC DONE: heap_ptr = %p\n", bumpalloc_heap_ptr); +#endif +} + +static inline void* BUMPALLOC(long long n) { + if (! bumpalloc_heap_ptr) { + INITBUMPALLOC(); + } + if (bumpalloc_heap_ptr + n < bumpalloc_heap_ptr_end) { + char* old= bumpalloc_heap_ptr; + bumpalloc_heap_ptr += n; + return old; + } else { + fprintf(stderr, "Warning: bump allocator ran out of memory."); + exit(1); + } +} + +// Snapshot the current heap pointer value across all threads. +void save_alloc_state() { + dbgprintf("Saving(%p): pos %d", heap_ptr, num_saved_heap_ptr); + saved_heap_ptr_stack[num_saved_heap_ptr] = heap_ptr; + num_saved_heap_ptr++; + dbgprintf("\n"); +} + +void restore_alloc_state() { + if(num_saved_heap_ptr <= 0) { + fprintf(stderr, "Bad call to restore_alloc_state! Saved stack empty!\ne"); + exit(1); + } + num_saved_heap_ptr--; + dbgprintf("Restoring(%p): pos %d, discarding %p", + saved_heap_ptr_stack[num_saved_heap_ptr], num_saved_heap_ptr, bumpalloc_heap_ptr); + bumpalloc_heap_ptr = saved_heap_ptr_stack[num_saved_heap_ptr]; +} + + +#else +// Regular malloc mode: +void INITBUMPALLOC() {} +void save_alloc_state() {} +void restore_alloc_state() {} + +#define BUMPALLOC(n) malloc(n) + +#endif // BUMPALLOC + + +// ------------------------------------- +// ALLOC and ALLOC_PACKED macros +// ------------------------------------- + + +/* + +If parallelism is enabled, we always use a malloc based allocator +since Boehm GC is not thread-safe in its default configuration. It can be +made thread-safe by building it with appropriate flags, but we don't do that. +Presently, all parallel pointer-based programs will leak memory. + +*/ + +#ifdef _PARALLEL +#define ALLOC(n) malloc(n) +#define ALLOC_PACKED_BIG(n) malloc(n) +char *ALLOC_COUNTED(size_t size) { + bump_global_region_count(); + return ALLOC(size); +} +#else + #ifdef _POINTER +#define ALLOC(n) GC_MALLOC(n) +#define ALLOC_PACKED_BIG(n) GC_MALLOC(n) +char *ALLOC_COUNTED(size_t size) { + bump_global_region_count(); + return GC_MALLOC(size); +} + #else +#define ALLOC(n) malloc(n) +#define ALLOC_PACKED_BIG(n) malloc(n) +char *ALLOC_COUNTED(size_t size) { + bump_global_region_count(); + return ALLOC(size); +} + #endif // _POINTER +#endif // _PARALLEL + + +// Could try alloca() here. Better yet, we could keep our own, +// separate stack and insert our own code to restore the pointer +// before any function that (may have) called ALLOC_SCOPED returns. + +// #define ALLOC_SCOPED() alloca(1024) +#define ALLOC_SCOPED(n) alloca(n) +// #define ALLOC_SCOPED() alloc_scoped() + +// Stack allocation is either too small or blows our stack. +// We need a way to make a giant stack if we want to use alloca. +// #define ALLOC_SCOPED() ALLOC(global_init_biginf_buf_size) + +// Our global pointer. No parallelism. +// static char* stack_scoped_region; +// char* alloc_scoped() { return stack_scoped_region; } + + + +// ------------------------------------- +// Basic types +// ------------------------------------- + +// Must be consistent with sizeOfTy defined in Gibbon.Language.Syntax. + +typedef unsigned char TagTyPacked; +typedef unsigned char TagTyBoxed; +typedef long long IntTy; +typedef char CharTy; +typedef float FloatTy; +typedef unsigned long long SymTy; +typedef bool BoolTy; +typedef char* PtrTy; +typedef char* CursorTy; + +// ------------------------------------- +// Arenas and dictionaries +// ------------------------------------- + +typedef struct mem_arena { + int ind; + char* mem; // TODO(vollmerm): make this a list of chunks? + void* reflist; +} mem_arena_t; + +typedef mem_arena_t* ArenaTy; + +ArenaTy alloc_arena() { + ArenaTy ar = ALLOC(sizeof(mem_arena_t)); + ar->ind = 0; + ar->mem = malloc(global_inf_buf_max_chunk_size); + ar->reflist = 0; + return ar; +} + +void free_arena(ArenaTy ar) { + free(ar->mem); + // TODO(vollmerm): free everything in ar->reflist + free(ar); +} + +CursorTy extend_arena(ArenaTy ar, int size) { + CursorTy ret = ar->mem + ar->ind; + ar->ind += size; + return ret; +} + +typedef struct dict_item { + struct dict_item * next; + int key; + void * ptrval; +} dict_item_t; + +dict_item_t * dict_alloc(ArenaTy ar) { + return (dict_item_t *) extend_arena(ar, sizeof(dict_item_t)); // ALLOC(sizeof(dict_item_t)); +} + +dict_item_t *dict_insert_ptr(ArenaTy ar, dict_item_t *ptr, SymTy key, PtrTy val) { + dict_item_t *ret = dict_alloc(ar); + ret->key = key; + ret->ptrval = val; + ret->next = ptr; + return ret; +} + +PtrTy dict_lookup_ptr(dict_item_t *ptr, SymTy key) { + while (ptr != 0) { + if (ptr->key == key) { + return ptr->ptrval; + } else { + ptr = ptr->next; + } + } + printf("Error, key %lld not found!\n",key); + exit(1); +} + +// ------------------------------------- +// Sets +// ------------------------------------- + + +struct set_elem { + int val; + UT_hash_handle hh; +}; + +typedef struct set_elem* SymSetTy; + +SymSetTy empty_set() { + return NULL; +} + +SymSetTy insert_set(SymSetTy set, int sym) { + SymSetTy s; + HASH_FIND_INT(set, &sym, s); /* sym already in the hash? */ + if (s==NULL) { + s = malloc(sizeof(struct set_elem)); + s->val = sym; + HASH_ADD_INT(set,val,s); + } + return set; +} + +BoolTy contains_set(SymSetTy set, int sym) { + SymSetTy s; + HASH_FIND_INT(set, &sym, s); + return (s!=NULL); +} + +// ------------------------------------- +// Sym Hash +// ------------------------------------- + +struct sym_hash_elem { + int key; + int val; + UT_hash_handle hh; +}; + +typedef struct sym_hash_elem* SymHashTy; + +typedef struct sym_hash_elem* IntHashTy; + +SymHashTy empty_hash() { + return NULL; +} + +SymHashTy insert_hash(SymHashTy hash, int k, int v) { + SymHashTy s; + // NOTE: not checking for duplicates! + // s = malloc(sizeof(struct sym_hash_elem)); + s = ALLOC(sizeof(struct sym_hash_elem)); + s->val = v; + s->key = k; + HASH_ADD_INT(hash,key,s); + + return hash; +} + +IntTy lookup_hash(SymHashTy hash, int k) { + SymHashTy s; + HASH_FIND_INT(hash,&k,s); + if (s==NULL) { + return k; // NOTE: return original key if val not found + // TODO(vollmerm): come up with something better to do here + } else { + return s->val; + } +} + +BoolTy contains_hash(SymHashTy hash, int sym) { + SymHashTy s; + HASH_FIND_INT(hash,&sym,s); + return (s!=NULL); +} + +// ------------------------------------- +// Helpers +// ------------------------------------- + +char* read_benchfile_param() { + if (global_benchfile_param == NULL) { + fprintf(stderr, "read_benchfile_param: benchmark input file was not set! Set using --bench-input.\n"); + exit(1); + } else + return global_benchfile_param; +} + +char* read_arrayfile_param() { + if (global_arrayfile_param == NULL) { + fprintf(stderr, "read_arrayfile_param: array input file was not set! Set using --array-input.\n"); + exit(1); + } else + return global_arrayfile_param; +} + +IntTy read_arrayfile_length_param() { + if (global_arrayfile_length_param == -1) { + fprintf(stderr, "read_arrayfile_length_param: array input file length was not set! Set using --array-input-length.\n"); + exit(1); + } else + return global_arrayfile_length_param; +} + + +// fun fact: __ prefix is actually reserved and this is an undefined behavior. +// These functions must be provided by the code generator. +int __main_expr(); + + +void show_usage(char** argv) +{ + printf("\n"); + printf("This binary was generated by the Gibbon compiler.\n"); + printf("\n"); + printf("Usage: %s [OPTS] [size] [iters]\n", argv[0]); + + printf("\n"); + printf("Options:\n"); + printf(" --buffer-size Set the buffer size (default %lld).\n", global_init_biginf_buf_size); + printf(" --bench-input Set the input file read for benchmarking. Applies only\n"); + printf(" IF the program was *compiled* with --bench-fun. \n"); + return; +} + +double avg(const double* arr, int n) +{ + double sum = 0.0; + for(int i=0; itv_sec - t0->tv_sec) + + ((double)(t1->tv_nsec - t0->tv_nsec) / 1000000000.0); +} + +int compare_doubles(const void *a, const void *b) +{ + const double *da = (const double *) a; + const double *db = (const double *) b; + return (*da > *db) - (*da < *db); +} + +// Exponentiation +IntTy expll(IntTy base, IntTy pow) { + if (base == 2) { + return (1 << pow); + } else { + IntTy i, result = 1; + for (i = 0; i < pow; i++) + result *= base; + return result; + } + } + +// ------------------------------------- +// Symbol table +// ------------------------------------- + +#define global_max_symbol_len 256 + +// Invariant: should always be equal to max(sym_table_keys) +static SymTy global_gensym_counter = 0; + +// Its value is updated by the flags parser. +static char *global_bench_prog_param; + +static SymTy newline_symbol = -1; +static SymTy space_symbol = -1; +static SymTy comma_symbol = -1; +static SymTy leftparen_symbol = -1; +static SymTy rightparen_symbol = -1; + +typedef struct SymTable_elem { + SymTy idx; /* key */ + char value[global_max_symbol_len]; + UT_hash_handle hh; /* makes this structure hashable */ +} SymTable_elem; + +// important! initialize to NULL +SymTable_elem *global_sym_table = NULL; + +void add_symbol(SymTy idx, char *value) { + struct SymTable_elem *s; + s = ALLOC(sizeof(struct SymTable_elem)); + s->idx = idx; + strcpy(s->value, value); + HASH_ADD(hh, global_sym_table, idx, sizeof(IntTy), s); + if (idx > global_gensym_counter) { + global_gensym_counter = idx; + } +} + +void set_newline(SymTy idx) { + newline_symbol = idx; + add_symbol(idx,"NEWLINE"); +} + +void set_space(SymTy idx) { + space_symbol = idx; + add_symbol(idx,"SPACE"); +} + +void set_comma(SymTy idx) { + comma_symbol = idx; + add_symbol(idx,"COMMA"); +} + +void set_leftparen(SymTy idx) { + leftparen_symbol = idx; + add_symbol(idx,"LEFTPAREN"); +} + +void set_rightparen(SymTy idx) { + rightparen_symbol = idx; + add_symbol(idx,"RIGHTPAREN"); +} + +IntTy print_symbol(SymTy idx) { + if (idx == comma_symbol) { + return printf(","); + } else if (idx == newline_symbol) { + return printf("\n"); + } else if (idx == space_symbol) { + return printf(" "); + } else if (idx == leftparen_symbol) { + return printf("("); + } else if (idx == rightparen_symbol) { + return printf(")"); + } else { + struct SymTable_elem *s; + HASH_FIND(hh, global_sym_table, &idx, sizeof(SymTy), s); + if (s == NULL) { + return printf("%lld", idx); + } else { + return printf("%s", s->value); + } + + } +} + +#ifdef _PARALLEL +SymTy gensym() { + SymTy idx = __atomic_add_fetch(&global_gensym_counter, 1, __ATOMIC_SEQ_CST); + return idx; +} +#else +SymTy gensym() { + global_gensym_counter += 1; + SymTy idx = global_gensym_counter; + return idx; +} +#endif + +void free_symtable() { + struct SymTable_elem *elt, *tmp; + HASH_ITER(hh, global_sym_table, elt, tmp) { + HASH_DEL(global_sym_table,elt); + } + free(elt); + free(tmp); +} + +/* + +---------------------------------------- +Garbage collection +---------------------------------------- + + Gibbon has "growing regions" i.e each logical region is backed by a doubly linked-list + of smaller chunks which grows as required. In addition to actual data, each chunk + stores some additional metadata (RegionFooter) to chain the chunks together in a list + and for garbage collection. The footer: + + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + serialized data | rf_reg_metadata_ptr | rf_seq_no | rf_size | rf_next | rf_prev + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + The metadata after the serialized data serves various purposes: + + - rf_reg_metadata_ptr: A pointer to a RegionTy struct that contains various metadata. + Of particular interest to us are the fields: + + = reg_id: A unique identifier for a region. + + = refcount and outset: Whenever an inter-region indirection is created, we record that information + using these two fields. Suppose we have an indirection from region A that points to some chunk + in region B. Then A's outset will store a pointer to that chunk's footer, and B's refcount will + be bumped by 1. Note that all there's only 1 refcount cell, and 1 outset per logical region, + and chunks only store a pointer to them. + + - rf_seq_no: The index of this particular chunk in the list. + + - rf_size: Used during bounds checking to calculate the size of the next region in + the linked list. + + - rf_next / rf_prev: Point to the next and previous chunk respectively. + + +There are two ways in which a region may be freed: + +(1) Whenever it goes out of scope + + The RTS tries to free a region whenever it goes out of scope. But this doesn't always succeed as + regions sometimes contain values that "escape". One reason why this'll happen is if there's an + indirection from A->B, and A lives longer than B. + In such a case, when B goes out of scope it's refcount won't be 0, and the RTS won't free it. + This brings us to (2). + +(2) + + When the RTS successfully frees a region, it decrements the refcounts of all the regions it + points to (via the outset). At the same time, if it encounters a region in the outset whoose + refcount becomes 0 after the decrement, it calls free_region on that. This way we can be sure + that all regions will eventually be garbage collected before the program exits. + + + +Why is it a doubly linked-list? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Due to way that bounds-checking works, the pointers in the outset may actually point to any +arbitrary chunk in the chain. However, we must call free_region on the first one to ensure that +all of them are GC'd. So we need pointers to traverse backward get to the first one. +'trav_to_first_chunk' accomplishes this. + + */ + +#define MAX_OUTSET_LENGTH 10 + +typedef struct RegionTy_struct { + SymTy reg_id; + uint reg_refcount; + CursorTy reg_heap; + uint reg_outset_len; + CursorTy reg_outset[MAX_OUTSET_LENGTH]; +} RegionTy; + +typedef struct RegionFooter_struct { + RegionTy *rf_reg_metadata_ptr; + + IntTy rf_seq_no; + IntTy rf_size; + struct RegionFooter_struct *rf_next; + struct RegionFooter_struct *rf_prev; +} RegionFooter; + +typedef struct ChunkTy_struct { + CursorTy chunk_start; + CursorTy chunk_end; +} ChunkTy; + +static inline void insert_into_outset(CursorTy ptr, RegionTy *reg) { + uint outset_len = reg->reg_outset_len; + // Check for duplicates. + for (uint i = 0; i < outset_len; i++) { + if (ptr == reg->reg_outset[i]) { + return; + } + } + // Otherwise, insert into the outset. + reg->reg_outset[outset_len] = ptr; + reg->reg_outset_len = outset_len + 1; + return; +} + +static inline void remove_from_outset(CursorTy ptr, RegionTy *reg) { + uint outset_len = reg->reg_outset_len; + CursorTy *outset = reg->reg_outset; + int i; + if (outset_len == 0) { + fprintf(stderr, "remove_from_outset: empty outset\n"); + exit(1); + } + // Position of 'ptr' in the outset. + int elt_idx = -1; + for (i = 0; i < outset_len; i++) { + if (ptr == outset[i]) { + elt_idx = i; + } + } + if (elt_idx == -1) { + fprintf(stderr, "remove_from_outset: element not found\n"); + exit(1); + } + // Move all elements ahead of 'elt_idx' back by one position. + for (i = elt_idx; i < outset_len; i++) { + outset[i] = outset[i+1]; + } + return; +} + +RegionTy *alloc_region(IntTy size) { + // Allocate the region metadata. + RegionTy *reg = ALLOC(sizeof(RegionTy)); + if (reg == NULL) { + printf("alloc_region: allocation failed: %ld", sizeof(RegionTy)); + exit(1); + } + + // Allocate the first chunk. + IntTy total_size = size + sizeof(RegionFooter); + CursorTy heap = ALLOC_PACKED_BIG(total_size); + if (heap == NULL) { + printf("alloc_region: malloc failed: %lld", total_size); + exit(1); + } + // Not heap+total_size, since we must keep space for the footer. + CursorTy heap_end = heap + size; + + // Initialize metadata fields. + reg->reg_id = gensym(); + reg->reg_refcount = 1; + reg->reg_heap = heap; + reg->reg_outset_len = 0; + +#ifdef _DEBUG + printf("Allocated a region(%lld): %lld bytes.\n", reg->reg_id, size); +#endif + + // Write the footer. + RegionFooter *footer = (RegionFooter *) heap_end; + footer->rf_reg_metadata_ptr = reg; + footer->rf_seq_no = 1; + footer->rf_size = size; + footer->rf_next = NULL; + footer->rf_prev = NULL; + + return reg; +} + +RegionTy *alloc_counted_region(IntTy size) { + // Bump the count. + bump_global_region_count(); + return alloc_region(size); +} + +ChunkTy alloc_chunk(CursorTy end_old_chunk) { + // Get size from current footer. + RegionFooter *footer = (RegionFooter *) end_old_chunk; + IntTy newsize = footer->rf_size * 2; + // See #110. + if (newsize > global_inf_buf_max_chunk_size) { + newsize = global_inf_buf_max_chunk_size; + } + IntTy total_size = newsize + sizeof(RegionFooter); + + // Allocate. + CursorTy start = ALLOC_PACKED_BIG(total_size); + if (start == NULL) { + printf("alloc_chunk: malloc failed: %lld", total_size); + exit(1); + } + CursorTy end = start + newsize; + + // Link the next chunk's footer. + footer->rf_next = (RegionFooter *) end; + + // Write the footer. + RegionFooter* new_footer = (RegionFooter *) end; + new_footer->rf_reg_metadata_ptr = footer->rf_reg_metadata_ptr; + new_footer->rf_seq_no = footer->rf_seq_no + 1; + new_footer->rf_size = newsize; + new_footer->rf_next = NULL; + new_footer->rf_prev = footer; + +#ifdef _DEBUG + RegionTy *reg = (RegionTy*) new_footer->rf_reg_metadata_ptr; + printf("alloc_chunk: allocated %lld bytes for region %lld.\n", total_size, reg->reg_id); +#endif + + return (ChunkTy) {start , end}; +} + +RegionFooter* trav_to_first_chunk(RegionFooter *footer) { + if (footer->rf_seq_no == 1) { + return footer; + } else if (footer->rf_prev == NULL) { + fprintf(stderr, "No previous chunk found at rf_seq_no: %lld", footer->rf_seq_no); + return NULL; + } else { + trav_to_first_chunk((RegionFooter *) footer->rf_prev); + } + return NULL; +} + +uint get_ref_count(CursorTy end_ptr) { + RegionFooter *footer = (RegionFooter *) end_ptr; + RegionTy *reg = (RegionTy *) footer->rf_reg_metadata_ptr; + return reg->reg_refcount; +} + +// B is the pointer, and A is the pointee (i.e B -> A). +// Bump A's refcount and update B's outset. +static inline void bump_ref_count(CursorTy end_b, CursorTy end_a) { + // Grab footers. + RegionFooter *footer_a = (RegionFooter *) end_a; + RegionFooter *footer_b = (RegionFooter *) end_b; + + // Grab metadata. + RegionTy *reg_a = (RegionTy *) footer_a->rf_reg_metadata_ptr; + RegionTy *reg_b = (RegionTy *) footer_b->rf_reg_metadata_ptr; + + // Bump A's refcount. + uint current_refcount, new_refcount; + current_refcount = reg_a->reg_refcount; + new_refcount = current_refcount + 1; + reg_a->reg_refcount = new_refcount; + +#ifdef _DEBUG + printf("bump_ref_count: %lld -> %lld\n", reg_b->reg_id, reg_a->reg_id); + printf("bump_ref_count: old-refcount=%d, old-outset-len=%d:\n", current_refcount, reg_b->reg_outset_len); + assert(current_refcount == reg_b->reg_outset_len+1); +#endif + + // Add A to B's outset. + insert_into_outset(end_a, reg_b); + +#ifdef _DEBUG + // printf("bump_ref_count: Added %p to %lld's outset, %p.\n", end_a, reg_b->reg_id, reg_b); + printf("bump_ref_count: new-refcount=%d, new-outset-len=%d\n", new_refcount, reg_b->reg_outset_len); + assert(new_refcount == reg_b->reg_outset_len+1); +#endif + + return; +} + +void free_region(CursorTy end_reg) { + // Grab footer and the metadata. + RegionFooter *footer = (RegionFooter *) end_reg; + RegionTy *reg = (RegionTy *) footer->rf_reg_metadata_ptr; + + // + RegionFooter *first_chunk_footer, *next_chunk_footer; + CursorTy first_chunk, next_chunk; + + // Decrement current reference count. + uint current_refcount, new_refcount; + current_refcount = reg->reg_refcount; + new_refcount = 0; + if (current_refcount != 0) { + new_refcount = current_refcount - 1; + reg->reg_refcount = new_refcount; + } + +#ifdef _DEBUG + printf("free_region(%lld): refcounts (1): old-refcount=%d, new-refcount=%d:\n", reg->reg_id, current_refcount, new_refcount); +#endif + + + // Free this region recount is 0. + if (new_refcount == 0) { + +#ifdef _DEBUG + printf("free_region(%lld): outset length: %d\n", reg->reg_id, reg->reg_outset_len); +#endif + + // Decrement refcounts, free regions with refcount==0 and also free + // elements of the outset. + if (reg->reg_outset_len != 0) { + uint outset_len = reg->reg_outset_len; + CursorTy *outset = reg->reg_outset; + RegionFooter *elt_footer; + RegionTy *elt_reg; + uint elt_current_refcount, elt_new_refcount; + CursorTy to_be_removed[MAX_OUTSET_LENGTH]; + uint to_be_removed_idx = 0; + for (int i = 0; i < outset_len; i++) { + elt_footer = (RegionFooter *) outset[i]; + elt_reg = (RegionTy *) elt_footer->rf_reg_metadata_ptr; +#ifdef _DEBUG + elt_current_refcount = elt_reg->reg_refcount; +#endif + elt_new_refcount = elt_current_refcount - 1; + elt_reg->reg_refcount = elt_new_refcount; +#ifdef _DEBUG + printf("free_region(%lld): old-refcount=%d, new-refcount=%d:\n", + elt_reg->reg_id, elt_current_refcount, elt_reg->reg_refcount); +#endif + if (elt_new_refcount == 0) { + // See [Why is it a doubly linked-list?] above + first_chunk_footer = trav_to_first_chunk(elt_footer); + if (first_chunk_footer != NULL) { + free_region((CursorTy) first_chunk_footer); + } + } + to_be_removed[to_be_removed_idx] = outset[i]; + to_be_removed_idx++; + } + // Remove elements from the outset. + for (uint i = 0; i < to_be_removed_idx; i++) { + remove_from_outset(to_be_removed[i], reg); + } + } + + +#ifdef _DEBUG + // Bookkeeping + IntTy num_freed_chunks = 0, total_bytesize = 0; +#endif + + // Free the chunks in this region. + first_chunk = end_reg - footer->rf_size; + first_chunk_footer = footer; + next_chunk = (char*) footer->rf_next; + +#ifdef _DEBUG + printf("free_region(%lld)\n", reg->reg_id); +#endif + +#ifdef _DEBUG + num_freed_chunks++; + total_bytesize = total_bytesize + first_chunk_footer->rf_size; +#endif + free(first_chunk); + + while (next_chunk != NULL) { + next_chunk_footer = (RegionFooter *) next_chunk; + #ifdef _DEBUG + num_freed_chunks++; + total_bytesize = total_bytesize + next_chunk_footer->rf_size; + #endif + free(next_chunk - next_chunk_footer->rf_size); + next_chunk = (char*) next_chunk_footer->rf_next; + } + +#ifdef _DEBUG + printf("free_region(%lld): Freed %lld bytes across %lld chunks.\n", + reg->reg_id, total_bytesize, num_freed_chunks); +#endif + + // Free the metadata. + free(reg); + + } else { +#ifdef _DEBUG + printf("free_region(%lld): non-zero refcount: %d.\n", + reg->reg_id, reg->reg_refcount); +#endif + } +} + +// Assume that all nodes with size information have tags >= 150. +BoolTy is_big(IntTy i, CursorTy cur) { + TagTyPacked tag = *(TagTyPacked *) cur; + if (tag >= 150) { + cur += 1; + IntTy size = *(IntTy *) cur; + if (size >= i) { + return true; + } else { + return false; + } + } + return false; +} + +// ------------------------------------- +// Vectors +// ------------------------------------- + +typedef struct VectorTy_struct { + // Bounds on the vector. + IntTy vec_lower, vec_upper; + + // Size of each element. + IntTy vec_elt_size; + + // Actual elements of the vector. + void* vec_data; +} VectorTy; + +VectorTy* vector_alloc(IntTy num, IntTy elt_size) { + VectorTy *vec = ALLOC(sizeof(VectorTy)); + if (vec == NULL) { + printf("alloc_vector: malloc failed: %ld", sizeof(VectorTy)); + exit(1); + } + void* data = ALLOC(num * elt_size); + if (data == NULL) { + printf("alloc_vector: malloc failed: %ld", sizeof(num * elt_size)); + exit(1); + } + vec->vec_lower = 0; + vec->vec_upper = num; + vec->vec_elt_size = elt_size; + vec->vec_data = data; + return vec; +} + +IntTy vector_length(VectorTy *vec) { + return (vec->vec_upper - vec->vec_lower); +} + +BoolTy vector_is_empty(VectorTy *vec) { + return (vector_length(vec) == 0); +} + +VectorTy* vector_slice(IntTy i, IntTy n, VectorTy *vec) { + IntTy lower = vec->vec_lower + i; + IntTy upper = vec->vec_lower + i + n; + if ((lower > vec->vec_upper)) { + printf("vector_slice: lower out of bounds, %lld > %lld", lower, vec->vec_upper); + exit(1); + } + if ((upper > vec->vec_upper)) { + printf("vector_slice: upper out of bounds: %lld > %lld", upper, vec->vec_upper); + exit(1); + } + VectorTy *vec2 = ALLOC(sizeof(VectorTy)); + if (vec == NULL) { + printf("vector_slice: malloc failed: %ld", sizeof(VectorTy)); + exit(1); + } + vec2->vec_lower = lower; + vec2->vec_upper = upper; + vec2->vec_elt_size = vec->vec_elt_size; + vec2->vec_data = vec->vec_data; + return vec2; +} + +// The callers must cast the return value. +static inline void* vector_nth(VectorTy *vec, IntTy i) { + // if (i < vec->lower || i > vec->upper) { + // printf("vector_nth index out of bounds: %lld (%lld,%lld) \n", i, vec->vec_lower, vec->vec_upper); + // exit(1); + // } + return (vec->vec_data + (vec->vec_elt_size * (vec->vec_lower + i))); +} + +static inline VectorTy* vector_inplace_update(VectorTy *vec, IntTy i, void* elt) { + void* dst = vector_nth(vec, i); + memcpy(dst, elt, vec->vec_elt_size); + return vec; +} + +static inline VectorTy* vector_copy(VectorTy *vec) { + IntTy len = vector_length(vec); + void *start = vector_nth(vec, 0); + VectorTy *vec2 = vector_alloc(len, vec->vec_elt_size); + memcpy(vec2->vec_data, start, len * vec->vec_elt_size); + return vec2; +} + +static inline VectorTy* vector_inplace_sort(VectorTy *vec, int (*compar)(const void *, const void*)) { + void *start = vector_nth(vec, 0); + qsort(start, vector_length(vec), vec->vec_elt_size, compar); + return vec; +} + +static inline VectorTy* vector_sort(VectorTy *vec, int (*compar)(const void *, const void*)) { + VectorTy *vec2 = vector_copy(vec); + vector_inplace_sort(vec2, compar); + return vec2; +} + +static inline VectorTy* vector_concat(VectorTy *vec) { + // Length of the input vector. + IntTy len = vector_length(vec); + // Length of the concatenated vector. + IntTy result_len = 0; + // Size of each element in the concatenated vector. + IntTy result_elt_size = 0; + VectorTy **elt_ref, *elt; + for (IntTy i = 0; i < len; i++) { + elt_ref = vector_nth(vec, i); + elt = *elt_ref; + result_elt_size = elt->vec_elt_size; + result_len += vector_length(elt); + } + + // Concatenated vector. + VectorTy *result = vector_alloc(result_len, result_elt_size); + IntTy elt_len; + // A counter that tracks the index of elements in 'result'. + IntTy k = 0; + for (IntTy i = 0; i < len; i++) { + elt_ref = vector_nth(vec, i); + elt = *elt_ref; + elt_len = vector_length(elt); + + for (IntTy j = 0; j < elt_len; j++) { + void* k_elt = vector_nth(elt, j); + vector_inplace_update(result, k, k_elt); + k++; + } + } + + return result; +} + +static inline void vector_free(VectorTy *vec) { + free(vec->vec_data); + free(vec); + return; +} + +static inline VectorTy* vector_merge(VectorTy *vec1, VectorTy *vec2) { + if (vec1->vec_upper != vec2->vec_lower) { + printf("vector_merge: non-contiguous slices, (%lld,%lld), (%lld,%lld).", + vec1->vec_lower, vec1->vec_upper, vec2->vec_lower, vec2->vec_upper); + exit(1); + } + VectorTy *merged = ALLOC(sizeof(VectorTy)); + if (merged == NULL) { + printf("vector_merge: malloc failed: %ld", sizeof(VectorTy)); + exit(1); + } + merged->vec_lower = vec1->vec_lower; + merged->vec_upper = vec2->vec_upper; + merged->vec_elt_size = vec1->vec_elt_size; + merged->vec_data = vec1->vec_data; + return merged; +} + +void print_timing_array(VectorTy *times) { + printf("TIMES: ["); + double *d; + IntTy n = vector_length(times); + for(int i = 0; i < n; i++) { + d = vector_nth(times, i); + if (i == (n-1)) { + printf("%f",*d); + } + else { + printf("%f, ",*d); + } + } + printf("]\n"); +} + +double sum_timing_array(VectorTy *times) { + double *d; + double acc = 0; + for(int i = 0; i < vector_length(times); i++) { + d = vector_nth(times, i); + acc += *d; + } + return acc; +} + +// ------------------------------------- +// Linked lists +// ------------------------------------- + +typedef struct ListTy_struct { + IntTy ll_data_size; + void* ll_data; + struct ListTy_struct* ll_next; +} ListTy; + +static inline ListTy* list_alloc(IntTy data_size) { + // ListTy *ls = ALLOC(sizeof(ListTy)); + ListTy *ls = BUMPALLOC(sizeof(ListTy)); + ls->ll_data_size = data_size; + ls->ll_data = NULL; + ls->ll_next = NULL; + return ls; +} + +static inline BoolTy list_is_empty(ListTy *ls) { + return ls->ll_next == NULL; +} + +static inline ListTy* list_cons(void* elt, ListTy *ls) { + // void* data = ALLOC(ls->data_size); + void* data = BUMPALLOC(ls->ll_data_size); + if (data == NULL) { + printf("list_cons: malloc failed: %lld", ls->ll_data_size); + exit(1); + } + memcpy(data, elt, ls->ll_data_size); + // ListTy *res = ALLOC(sizeof(ListTy)); + ListTy *res = BUMPALLOC(sizeof(ListTy)); + res->ll_data_size = ls->ll_data_size; + res->ll_data = data; + res->ll_next = (ListTy*) ls; + return res; +} + +static inline void* list_head(ListTy *ls) { + return ls->ll_data; +} + +static inline ListTy* list_tail(ListTy *ls) { + return ls->ll_next; +} + +static inline void list_free(ListTy *ls) { + free(ls->ll_data); + free(ls); + return; +} + +static inline ListTy* list_copy(ListTy *ls) { + ListTy *ls2 = list_alloc(ls->ll_data_size); + if (ls->ll_data != NULL) { + void* data = BUMPALLOC(ls->ll_data_size); + memcpy(data, ls->ll_data, ls->ll_data_size); + ls2->ll_data = data; + } + ls2->ll_next = ls->ll_next; + return ls2; +} + +// ------------------------------------- +// Ppm Images +// ------------------------------------- + +typedef struct __Pixel_struct { + IntTy field0; + IntTy field1; + IntTy field2; +} __Pixel; + +void writePpm(char* filename, IntTy width, IntTy height, VectorTy *pixels); +void writePpm_loop(FILE *fp, IntTy idx, IntTy end, VectorTy *pixels); + +// Example: writePpm("gibbon_rgb_1000.ppm", 1000, 1000, pixels); +void writePpm(char* filename, IntTy width, IntTy height, VectorTy *pixels) +{ + FILE *fp; + fp = fopen(filename, "w+"); + fprintf(fp, "P3\n"); + fprintf(fp, "%lld %lld\n255\n", width, height); + IntTy len = vector_length(pixels); + writePpm_loop(fp, 0, len, pixels); + fclose(fp); + return; +} + +void writePpm_loop(FILE *fp, IntTy idx, IntTy end, VectorTy *pixels) +{ + BoolTy fltIf_5768_6575 = idx == end; + + if (fltIf_5768_6575) { + return; + } else { + __Pixel *tmp_112; + tmp_112 = (__Pixel *) vector_nth(pixels, idx); + __Pixel tup = *tmp_112; + IntTy x = tup.field0; + IntTy y = tup.field1; + IntTy z = tup.field2; + // write to file. + fprintf(fp, "%lld %lld %lld\n", x, y, z); + writePpm_loop(fp, (idx+1), end, pixels); + } +} + +/* -------------------------------------------------------------------------------- */ + +int main(int argc, char** argv) +{ + // parameters to parse: + // + // num iterations: How many times to repeat a benchmark. + // tree size: An integer passes to `build_tree()`. + + struct rlimit lim; + int code; + if ( (code = getrlimit(RLIMIT_STACK, &lim)) ) { + fprintf(stderr, " [gibbon rts] failed to getrlimit, code %d\n", code); + exit(1); + } + + // lim.rlim_cur = 1024LU * 1024LU * 1024LU; // 1GB stack. + lim.rlim_cur = 512LU * 1024LU * 1024LU; // 500MB stack. + // lim.rlim_max = lim.rlim_cur; // Normal users may only be able to decrease this. + + // WARNING: Haven't yet figured out why this doesn't work on MacOS... +#ifndef __APPLE__ + code = setrlimit(RLIMIT_STACK, &lim); + while (code) { + fprintf(stderr, " [gibbon rts] Failed to set stack size to %llu, code %d\n", (unsigned long long)lim.rlim_cur, code); + lim.rlim_cur /= 2; + // lim.rlim_max /= 2; + if(lim.rlim_cur < 100 * 1024) { + fprintf(stderr, " [gibbon rts] Failed setrlimit stack size to something reasonable; giving up.\n"); + break; // abort(); + } + int code = setrlimit(RLIMIT_STACK, &lim); + } +#endif + + int got_numargs = 0; // How many numeric arguments have we got. + + int i; + for (i = 1; i < argc; ++i) + { + if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) { + show_usage(argv); + exit(0); + } + else if (strcmp(argv[i], "--biginf-buffer-size") == 0 && i < argc - 1) + { + global_init_biginf_buf_size = atoll(argv[i + 1]); + i++; + } + else if (strcmp(argv[i], "--inf-buffer-size") == 0 && i < argc - 1) + { + global_init_inf_buf_size = atoll(argv[i + 1]); + i++; + } + else if ((strcmp(argv[i], "--bench-input") == 0)) { + if (i+1 >= argc) { + fprintf(stderr, "Not enough arguments after --bench-input, expected .\n"); + show_usage(argv); + exit(1); + } + global_benchfile_param = argv[i+1]; + i++; + } + else if ((strcmp(argv[i], "--array-input") == 0)) { + if (i+1 >= argc) { + fprintf(stderr, "Not enough arguments after --array-input, expected .\n"); + show_usage(argv); + exit(1); + } + global_arrayfile_param = argv[i+1]; + i++; + } + else if (strcmp(argv[i], "--array-input-length") == 0 && i < argc - 1) { + global_arrayfile_length_param = atoll(argv[i+1]); + i++; + } + else if (strcmp(argv[i], "--bench-prog") == 0 && i < argc - 1) { + int len = strlen(argv[i+1]); + global_bench_prog_param = (char*) malloc((len+1)*sizeof(char)); + strncpy(global_bench_prog_param,argv[i+1],len); + i++; + } + // If present, we expect the two arguments to be + else if (got_numargs >= 2) { + fprintf(stderr, "Extra arguments left over: "); + for(; i < argc; i++) fprintf(stderr, "%s ", argv[i]); + show_usage(argv); + exit(1); + } else { + if (got_numargs == 0) { + global_size_param = atoll(argv[i]); + got_numargs ++; + } else { + global_iters_param = atoll(argv[i]); + } + } + } + + // Initialize global_bench_prog_param to an empty string in case + // the runtime argument --bench-prog isn't passed. + if (global_bench_prog_param == NULL) { + global_bench_prog_param = (char*) malloc(1*sizeof(char)); + *global_bench_prog_param = '\n'; + } + + __main_expr(); + + return 0; +} + +// ----------------------------------------------------------------------------- +// Program starts here +// ----------------------------------------------------------------------------- + +int __main_expr() +{ } \ No newline at end of file diff --git a/gibbon-compiler/.gitignore b/gibbon-compiler/.gitignore index 02f2565fa..b30392163 100644 --- a/gibbon-compiler/.gitignore +++ b/gibbon-compiler/.gitignore @@ -32,3 +32,4 @@ demo/*.c demo/*.exe gibbon-compiler/examples/parallel/data/*.txt *.log.hs +*.log diff --git a/gibbon-compiler/build.log b/gibbon-compiler/build.log new file mode 100644 index 000000000..cb9f8de35 --- /dev/null +++ b/gibbon-compiler/build.log @@ -0,0 +1,8 @@ +Build profile: -w ghc-9.2.8 -O1 +In order, the following will be built (use -v for more details): + - gibbon-0.3 (lib) (file src/Gibbon/Language/Syntax.hs changed) + - gibbon-0.3 (exe:test-gibbon-examples) (dependency rebuilt) + - gibbon-0.3 (exe:gibbon) (dependency rebuilt) +Preprocessing library for gibbon-0.3.. +Building library for gibbon-0.3.. +[16 of 61] Compiling Gibbon.NewL2.Syntax ( src/Gibbon/NewL2/Syntax.hs, /home/timmy/git/gibbon/dist-newstyle/build/x86_64-linux/ghc-9.2.8/gibbon-0.3/build/Gibbon/NewL2/Syntax.o, /home/timmy/git/gibbon/dist-newstyle/build/x86_64-linux/ghc-9.2.8/gibbon-0.3/build/Gibbon/NewL2/Syntax.dyn_o ) [Gibbon.Language.Syntax changed] diff --git a/gibbon-compiler/compile.log b/gibbon-compiler/compile.log new file mode 100644 index 000000000..7db011525 --- /dev/null +++ b/gibbon-compiler/compile.log @@ -0,0 +1,7 @@ +Build profile: -w ghc-9.2.8 -O1 +In order, the following will be built (use -v for more details): + - gibbon-0.3 (lib) (file src/Gibbon/HaskellFrontend.hs changed) + - gibbon-0.3 (exe:test-gibbon-examples) (dependency rebuilt) + - gibbon-0.3 (exe:gibbon) (dependency rebuilt) +Preprocessing library for gibbon-0.3.. +Building library for gibbon-0.3.. diff --git a/gibbon-compiler/examples/add1.hs b/gibbon-compiler/examples/add1.hs index b31d41695..d7bf4a5b7 100644 --- a/gibbon-compiler/examples/add1.hs +++ b/gibbon-compiler/examples/add1.hs @@ -1,9 +1,10 @@ +module Add where data Tree = Leaf Int | Node Tree Tree add1 :: Tree -> Tree add1 t = case t of Leaf x -> Leaf (x + 1) - Node x1 x2 -> Node (add1 x1) (add1 x2) + Node x1 x2 -> Node (Add.add1 x1) (Add.add1 x2) -main :: Tree -main = add1 (Node (Leaf 1) (Leaf 2)) +gibbon_main :: Tree +gibbon_main = Add.add1 (Node (Leaf 1) (Leaf 2)) diff --git a/gibbon-compiler/examples/imports/AddTree.hs b/gibbon-compiler/examples/imports/AddTree.hs new file mode 100644 index 000000000..9acdf78cc --- /dev/null +++ b/gibbon-compiler/examples/imports/AddTree.hs @@ -0,0 +1,8 @@ +module AddTree where + data Tree = Node Tree Tree | Leaf Int + + sum :: Tree -> Int + sum t = + case t of + Leaf v -> v + Node l r -> (sum l) + (sum r) \ No newline at end of file diff --git a/gibbon-compiler/examples/imports/Addone.hs b/gibbon-compiler/examples/imports/Addone.hs new file mode 100644 index 000000000..c073e31d9 --- /dev/null +++ b/gibbon-compiler/examples/imports/Addone.hs @@ -0,0 +1,15 @@ +module Addone where + import AddTree + + add :: Tree -> Tree + add t = case t of + Leaf x -> Leaf (x + 1) + Node x1 x2 -> Node (add x1) (add x2) + + sub :: Tree -> Tree + sub t = case t of + Leaf x -> Leaf (x - 1) + Node x1 x2 -> Node (sub x1) (sub x2) + + gibbon_main :: Tree + gibbon_main = add (Node (Leaf 1) (Leaf 2)) diff --git a/gibbon-compiler/examples/imports/Addtwo.hs b/gibbon-compiler/examples/imports/Addtwo.hs new file mode 100644 index 000000000..9b022b537 --- /dev/null +++ b/gibbon-compiler/examples/imports/Addtwo.hs @@ -0,0 +1,15 @@ +module Addtwo where + import AddTree + + add :: Tree -> Tree + add t = case t of + Leaf x -> Leaf (x + 2) + Node x1 x2 -> Node (add x1) (add x2) + + sub :: Tree -> Tree + sub t = case t of + Leaf x -> Leaf (x - 2) + Node x1 x2 -> Node (sub x1) (sub x2) + + gibbon_main :: Tree + gibbon_main = add (Node (Leaf 1) (Leaf 2)) diff --git a/gibbon-compiler/examples/imports/AllThreeImportModifications.ans b/gibbon-compiler/examples/imports/AllThreeImportModifications.ans new file mode 100644 index 000000000..f11c82a4c --- /dev/null +++ b/gibbon-compiler/examples/imports/AllThreeImportModifications.ans @@ -0,0 +1 @@ +9 \ No newline at end of file diff --git a/gibbon-compiler/examples/imports/AllThreeImportModifications.hs b/gibbon-compiler/examples/imports/AllThreeImportModifications.hs new file mode 100644 index 000000000..472ad4f79 --- /dev/null +++ b/gibbon-compiler/examples/imports/AllThreeImportModifications.hs @@ -0,0 +1,6 @@ +module AllThreeImportModifications where + import qualified Addtwo as T (add) + import qualified Addone as O (add) + import AddTree as Tree (sum, Node, Leaf) + + gibbon_main = sum (T.add (O.add (Tree.Node (Tree.Leaf 1) (Tree.Leaf 2)))) \ No newline at end of file diff --git a/gibbon-compiler/examples/imports/ImportAliased.ans b/gibbon-compiler/examples/imports/ImportAliased.ans new file mode 100644 index 000000000..f11c82a4c --- /dev/null +++ b/gibbon-compiler/examples/imports/ImportAliased.ans @@ -0,0 +1 @@ +9 \ No newline at end of file diff --git a/gibbon-compiler/examples/imports/ImportAliased.hs b/gibbon-compiler/examples/imports/ImportAliased.hs new file mode 100644 index 000000000..e976a39b8 --- /dev/null +++ b/gibbon-compiler/examples/imports/ImportAliased.hs @@ -0,0 +1,6 @@ +module ImportAliased where + import qualified Addtwo as T + import qualified Addone as O + import AddTree as Tree + + gibbon_main = sum (T.add (O.add (Tree.Node (Tree.Leaf 1) (Tree.Leaf 2)))) \ No newline at end of file diff --git a/gibbon-compiler/examples/imports/ImportQualified.ans b/gibbon-compiler/examples/imports/ImportQualified.ans new file mode 100644 index 000000000..f11c82a4c --- /dev/null +++ b/gibbon-compiler/examples/imports/ImportQualified.ans @@ -0,0 +1 @@ +9 \ No newline at end of file diff --git a/gibbon-compiler/examples/imports/ImportQualified.hs b/gibbon-compiler/examples/imports/ImportQualified.hs new file mode 100644 index 000000000..7b1e36334 --- /dev/null +++ b/gibbon-compiler/examples/imports/ImportQualified.hs @@ -0,0 +1,6 @@ +module ImportQualified where + import qualified Addtwo + import qualified Addone + import AddTree + + gibbon_main = sum (Addtwo.add (Addone.add (Node (Leaf 1) (Leaf 2)))) \ No newline at end of file diff --git a/gibbon-compiler/examples/imports/ImportQualifiedAndSpecified.ans b/gibbon-compiler/examples/imports/ImportQualifiedAndSpecified.ans new file mode 100644 index 000000000..7813681f5 --- /dev/null +++ b/gibbon-compiler/examples/imports/ImportQualifiedAndSpecified.ans @@ -0,0 +1 @@ +5 \ No newline at end of file diff --git a/gibbon-compiler/examples/imports/ImportQualifiedAndSpecified.hs b/gibbon-compiler/examples/imports/ImportQualifiedAndSpecified.hs new file mode 100644 index 000000000..61755a076 --- /dev/null +++ b/gibbon-compiler/examples/imports/ImportQualifiedAndSpecified.hs @@ -0,0 +1,6 @@ +module ImportQualifiedAndSpecified where + import qualified Addtwo (add) + import qualified Addone (sub) + import AddTree + + gibbon_main = sum (Addtwo.add (Addone.sub (Node (Leaf 1) (Leaf 2)))) \ No newline at end of file diff --git a/gibbon-compiler/examples/imports/ImportSpecified.ans b/gibbon-compiler/examples/imports/ImportSpecified.ans new file mode 100644 index 000000000..7813681f5 --- /dev/null +++ b/gibbon-compiler/examples/imports/ImportSpecified.ans @@ -0,0 +1 @@ +5 \ No newline at end of file diff --git a/gibbon-compiler/examples/imports/ImportSpecified.hs b/gibbon-compiler/examples/imports/ImportSpecified.hs new file mode 100644 index 000000000..735426c15 --- /dev/null +++ b/gibbon-compiler/examples/imports/ImportSpecified.hs @@ -0,0 +1,6 @@ +module ImportSpecified where + import Addtwo (add) + import Addone (sub) + import AddTree + + gibbon_main = sum (add (sub (Node (Leaf 1) (Leaf 2)))) \ No newline at end of file diff --git a/gibbon-compiler/examples/imports/failing.md b/gibbon-compiler/examples/imports/failing.md new file mode 100644 index 000000000..cf4309c80 --- /dev/null +++ b/gibbon-compiler/examples/imports/failing.md @@ -0,0 +1,61 @@ +# Poly +### `/poly/Poly1.hs` + +Problem seems to be with the type names, numbers and Nothing, Cons, Nil, Right all match + +``` +< '#(10 #t 11 #f 2 4 (Poly1_Nothing_77_v_323) (Poly1_Right_76_v_342 20) (Poly1_Right_76_v_334 1) 12 #f 0 3 (Poly1_Cons_74_v_329 1 (Poly1_Cons_74_v_329 2 (Poly1_Nil_73_v_329))) (Poly1_Cons_74_v_329 1 (Poly1_Cons_74_v_329 2 (Poly1_Nil_73_v_329))) (Poly1_Right_76_v_334 1) (Poly1_Cons_74_v_329 11 (Poly1_Cons_74_v_329 12 (Poly1_Nil_73_v_329)))) +--- +> '#(10 #t 11 #f 2 4 (Nothing_v_295 ) (Right_v_315 20) (Right_v_306 1) 12 #f 0 3 (Cons_v_301 1(Cons_v_301 2(Nil_v_301 ))) (Cons_v_301 1(Cons_v_301 2(Nil_v_301 ))) (Right_v_306 1) (Cons_v_301 11(Cons_v_301 12(Nil_v_301 )))) +\ No newline at end of file +``` + +# Eval l/r +### `eval_l.hs` + +### `eval_r.hs` + +these are failing to properly import a module in interp mode this seems to stem from the fact the the imported file does not have a module declaration,,, so internally it renames with "Main" but the true Main module expects "Eval" b/c that's the name in the import statement. + +solving this by having the Main module tell each imported module how to name themselves ... this I think could get convoluted b/c a module decalred internally as A could be imported as B ... perhaps a subjective design decision but this seems to work + +# ArrowTy +### `layout1ContentSearch.hs` +``` +Couldn't match type 'ArrowTy [VectorTy (MetaTv $839)] + IntTy' with 'IntTy' + Expected type: IntTy + Actual type: ArrowTy [VectorTy (MetaTv $839)] IntTy + In the expression: + VarE "Gibbon_Vector_length_132" in Var "GenerateLayout1_mkBlogs_layout1_107" +``` + +This all seems to come from a similair pattern but it looks like the bug doesn't have anything to do with the error. The issue is scope: `Gibbon_Vector_length_132` is some global name but there is a `length` that is one of the function arguements. The rename pass matches length to the global function, causing the error. My solution was to force the global name to be qualified within the scope where `length` exists. So the global `Gibbon.Vector.length` can be accessed if qualified, but simple reference to `length` will use the function arguement `length` + +### `layout1ContentSearchRunPipeline.hs` + +### `layout1FilterBlogs.hs` + +### `layout1TagSearch.hs` + +### `layout2ContentSearch.hs` + +### `layout2FilterBlogs.hs` + +### `layout2TagSearch.hs` + +### `layout3ContentSearch.hs` + +### `layout3FilterBlogs.hs` + +### `layout3TagSearch.hs` + +### `layout4ContentSearch.hs` + +### `layout4FilterBlogs.hs` + +### `layout4TagSearch.hs` + +### `layout5ContentSearch.hs` + +### `layout5FilterBlogs.hs` \ No newline at end of file diff --git a/gibbon-compiler/examples/imports/import_tests.md b/gibbon-compiler/examples/imports/import_tests.md new file mode 100644 index 000000000..c1e3ea8bd --- /dev/null +++ b/gibbon-compiler/examples/imports/import_tests.md @@ -0,0 +1,9 @@ +# Import Features +- no modifiers +- qualified +- specified +- aliased +- qualified & specified +- qualified & aliased +- specified & aliased +- qualified & specified & aliased \ No newline at end of file diff --git a/gibbon-compiler/examples/imports/Bar.hs b/gibbon-compiler/examples/imports/no-modifiers/Bar.hs similarity index 100% rename from gibbon-compiler/examples/imports/Bar.hs rename to gibbon-compiler/examples/imports/no-modifiers/Bar.hs diff --git a/gibbon-compiler/examples/imports/Baz.hs b/gibbon-compiler/examples/imports/no-modifiers/Baz.hs similarity index 100% rename from gibbon-compiler/examples/imports/Baz.hs rename to gibbon-compiler/examples/imports/no-modifiers/Baz.hs diff --git a/gibbon-compiler/examples/imports/Foo.ans b/gibbon-compiler/examples/imports/no-modifiers/Foo.ans similarity index 100% rename from gibbon-compiler/examples/imports/Foo.ans rename to gibbon-compiler/examples/imports/no-modifiers/Foo.ans diff --git a/gibbon-compiler/examples/imports/Foo.hs b/gibbon-compiler/examples/imports/no-modifiers/Foo.hs similarity index 100% rename from gibbon-compiler/examples/imports/Foo.hs rename to gibbon-compiler/examples/imports/no-modifiers/Foo.hs diff --git a/gibbon-compiler/examples/maybe/TestMaybe.hs b/gibbon-compiler/examples/maybe/TestMaybe.hs new file mode 100644 index 000000000..f82ef31b8 --- /dev/null +++ b/gibbon-compiler/examples/maybe/TestMaybe.hs @@ -0,0 +1,21 @@ +module TestMaybe where + +import Gibbon.Prelude +import Gibbon.Maybe + + +gibbon_main = + let val :: Maybe Int + val = Just 10 + tell_just = isJust val + tell_not = isNothing val + _ = printsym ( quote "is val just: " ) + _ = printsym ( quote "NEWLINE" ) + _ = printbool tell_just + _ = printsym ( quote "NEWLINE" ) + _ = printsym ( quote "is val nothing: " ) + _ = printsym ( quote "NEWLINE" ) + _ = printbool tell_not + _ = printsym ( quote "NEWLINE" ) + in () + diff --git a/gibbon-compiler/examples/poly/Poly1.ans b/gibbon-compiler/examples/poly/Poly1.ans index 1ac14e9b9..e179b89d9 100644 --- a/gibbon-compiler/examples/poly/Poly1.ans +++ b/gibbon-compiler/examples/poly/Poly1.ans @@ -1 +1 @@ -'#(10 #t 11 #f 2 4 (Nothing_v_406) (Right_v_426 20) (Right_v_417 1) 12 #f 0 3 (Cons_v_412 1 (Cons_v_412 2 (Nil_v_412))) (Cons_v_412 1 (Cons_v_412 2 (Nil_v_412))) (Right_v_417 1) (Cons_v_412 11 (Cons_v_412 12 (Nil_v_412)))) +'#(10 #t 11 #f 2 4 (Nothing99_v434) (Right98_v453 20) (Right98_v445 1) 12 #f 0 3 (Cons96_v440 1 (Cons96_v440 2 (Nil95_v440))) (Cons96_v440 1 (Cons96_v440 2 (Nil95_v440))) (Right98_v445 1) (Cons96_v440 11 (Cons96_v440 12 (Nil95_v440)))) \ No newline at end of file diff --git a/gibbon-compiler/examples/test_153.ans b/gibbon-compiler/examples/test_153.ans index f0808973d..7af4c5f73 100644 --- a/gibbon-compiler/examples/test_153.ans +++ b/gibbon-compiler/examples/test_153.ans @@ -1 +1 @@ -'#('#(2 3) (B_v_13 4 5)) +'#('#(2 3) (B5_v17 4 5)) diff --git a/gibbon-compiler/examples/test_164.ans b/gibbon-compiler/examples/test_164.ans index 6a191db12..6af50b27f 100644 --- a/gibbon-compiler/examples/test_164.ans +++ b/gibbon-compiler/examples/test_164.ans @@ -1 +1 @@ -(Cons_v_64 3 (Cons_v_64 5 (Cons_v_64 7 (Nil_v_64)))) +(Cons19_v68 3 (Cons19_v68 5 (Cons19_v68 7 (Nil18_v68)))) \ No newline at end of file diff --git a/gibbon-compiler/examples/test_166.ans b/gibbon-compiler/examples/test_166.ans index a082d182f..fcb3ff9e2 100644 --- a/gibbon-compiler/examples/test_166.ans +++ b/gibbon-compiler/examples/test_166.ans @@ -1 +1 @@ -(Node_v_79 10 10 10 10 10 10 10 10 (Cell_v_79 5 5 5 5 5 5 5 5) (Cell_v_79 2 2 2 2 2 2 2 2)) +(Node16_v86 10 10 10 10 10 10 10 10 (Cell15_v86 5 5 5 5 5 5 5 5) (Cell15_v86 2 2 2 2 2 2 2 2)) \ No newline at end of file diff --git a/gibbon-compiler/examples/test_191.ans b/gibbon-compiler/examples/test_191.ans index 1828a9fee..18f4f2b04 100644 --- a/gibbon-compiler/examples/test_191.ans +++ b/gibbon-compiler/examples/test_191.ans @@ -1 +1 @@ -(Cons 12 ->i (I 2) (Cons 12 ->i (I 1) (Nil)))'#() +(Cons26 12 ->i (I28 2) (Cons26 12 ->i (I28 1) (Nil27)))'#() \ No newline at end of file diff --git a/gibbon-compiler/examples/test_parse.hs b/gibbon-compiler/examples/test_parse.hs index b1aa1b14f..f7327699e 100644 --- a/gibbon-compiler/examples/test_parse.hs +++ b/gibbon-compiler/examples/test_parse.hs @@ -12,18 +12,19 @@ data Foo = MkFoo gibbon_main = let - pts0 :: Vector (Float, Float, Float) - pts0 = readArrayFile Nothing + --pts0 :: Vector (Float, Float, Float) + --pts0 = readArrayFile Nothing - pts1 :: Vector (Float, Float, Float) - pts1 = readArrayFile (Nothing) + --pts1 :: Vector (Float, Float, Float) + --pts1 = readArrayFile (Nothing) pts2 :: Vector (Float, Float) pts2 = readArrayFile (Just ("/dir/abc.txt", 10)) - pakd1 :: Foo - pakd1 = readPackedFile @Foo Nothing + --pakd1 :: Foo + --pakd1 = readPackedFile @Foo Nothing pakd2 :: Foo - pakd2 = readPackedFile (Just "/dir/tree.gpkd") + --pakd2 = readPackedFile (Just "/dir/tree.gpkd") + pakd2 = readPackedFile (Just "./test_numprocs.hs") in () diff --git a/gibbon-compiler/examples/test_printpacked.ans b/gibbon-compiler/examples/test_printpacked.ans index 07209292f..55c61c8f0 100644 --- a/gibbon-compiler/examples/test_printpacked.ans +++ b/gibbon-compiler/examples/test_printpacked.ans @@ -1,4 +1,4 @@ -(Node (Node (Leaf 1)(Leaf 1))(Node (Leaf 1)(Leaf 1))) - ->i (Node (Node (Leaf 1)(Leaf 1))(Node (Leaf 1)(Leaf 1))) +(Node32 (Node32 (Leaf31 1)(Leaf31 1))(Node32 (Leaf31 1)(Leaf31 1))) + ->i (Node32 (Node32 (Leaf31 1)(Leaf31 1))(Node32 (Leaf31 1)(Leaf31 1))) 1 '#() \ No newline at end of file diff --git a/gibbon-compiler/gibbon.cabal b/gibbon-compiler/gibbon.cabal index a1b0c7196..9ea8bf5f3 100644 --- a/gibbon-compiler/gibbon.cabal +++ b/gibbon-compiler/gibbon.cabal @@ -28,6 +28,7 @@ flag LLVM_ENABLED library exposed-modules: Gibbon.Common Gibbon.Compiler + Gibbon.Bundler Gibbon.DynFlags Gibbon.Pretty Gibbon.SExpFrontend @@ -60,6 +61,7 @@ library Gibbon.NewL2.FromOldL2 -- compiler passes, roughly in the order they're run + Gibbon.Passes.FreshBundle Gibbon.Passes.Freshen Gibbon.Passes.Flatten Gibbon.Passes.InlineTriv diff --git a/gibbon-compiler/solve_ilp_-34.py b/gibbon-compiler/solve_ilp_-34.py new file mode 100644 index 000000000..25e74d77b --- /dev/null +++ b/gibbon-compiler/solve_ilp_-34.py @@ -0,0 +1,22 @@ +from docplex.mp.model import Model +model_2 = Model() +x_00 = model_2.integer_var(lb=0, ub=1, name="x_00") +x_11 = model_2.integer_var(lb=0, ub=1, name="x_11") +cost3 = model_2.integer_var(name="cost3") +x_minus_y11 = (x_00 - x_11) +cost5 = (x_minus_y11 == -1) +cost6 = (x_minus_y11 <= -1) +cost7 = (x_minus_y11 == 1) +cost8 = (x_minus_y11 >= 1) +cost9 = (x_minus_y11 != -1) +cost10 = (x_minus_y11 != 1) +model_2.add(cost5 <= (cost3 == 0)) +model_2.add((cost6 & cost9) <= (cost3 == 100)) +model_2.add(cost7 <= (cost3 == 200)) +model_2.add((cost8 & cost10) <= (cost3 == 300)) +min4 = cost3 * 50 +model_2.add(x_00 != x_11) +model_2.minimize(min4 + 0) +soln12 = model_2.solve() +print("({},{})".format(0, soln12.get_value(x_00))) +print("({},{})".format(1, soln12.get_value(x_11))) \ No newline at end of file diff --git a/gibbon-compiler/solve_ilp_-49.py b/gibbon-compiler/solve_ilp_-49.py new file mode 100644 index 000000000..25e74d77b --- /dev/null +++ b/gibbon-compiler/solve_ilp_-49.py @@ -0,0 +1,22 @@ +from docplex.mp.model import Model +model_2 = Model() +x_00 = model_2.integer_var(lb=0, ub=1, name="x_00") +x_11 = model_2.integer_var(lb=0, ub=1, name="x_11") +cost3 = model_2.integer_var(name="cost3") +x_minus_y11 = (x_00 - x_11) +cost5 = (x_minus_y11 == -1) +cost6 = (x_minus_y11 <= -1) +cost7 = (x_minus_y11 == 1) +cost8 = (x_minus_y11 >= 1) +cost9 = (x_minus_y11 != -1) +cost10 = (x_minus_y11 != 1) +model_2.add(cost5 <= (cost3 == 0)) +model_2.add((cost6 & cost9) <= (cost3 == 100)) +model_2.add(cost7 <= (cost3 == 200)) +model_2.add((cost8 & cost10) <= (cost3 == 300)) +min4 = cost3 * 50 +model_2.add(x_00 != x_11) +model_2.minimize(min4 + 0) +soln12 = model_2.solve() +print("({},{})".format(0, soln12.get_value(x_00))) +print("({},{})".format(1, soln12.get_value(x_11))) \ No newline at end of file diff --git a/gibbon-compiler/solve_ilp_14.py b/gibbon-compiler/solve_ilp_14.py new file mode 100644 index 000000000..25e74d77b --- /dev/null +++ b/gibbon-compiler/solve_ilp_14.py @@ -0,0 +1,22 @@ +from docplex.mp.model import Model +model_2 = Model() +x_00 = model_2.integer_var(lb=0, ub=1, name="x_00") +x_11 = model_2.integer_var(lb=0, ub=1, name="x_11") +cost3 = model_2.integer_var(name="cost3") +x_minus_y11 = (x_00 - x_11) +cost5 = (x_minus_y11 == -1) +cost6 = (x_minus_y11 <= -1) +cost7 = (x_minus_y11 == 1) +cost8 = (x_minus_y11 >= 1) +cost9 = (x_minus_y11 != -1) +cost10 = (x_minus_y11 != 1) +model_2.add(cost5 <= (cost3 == 0)) +model_2.add((cost6 & cost9) <= (cost3 == 100)) +model_2.add(cost7 <= (cost3 == 200)) +model_2.add((cost8 & cost10) <= (cost3 == 300)) +min4 = cost3 * 50 +model_2.add(x_00 != x_11) +model_2.minimize(min4 + 0) +soln12 = model_2.solve() +print("({},{})".format(0, soln12.get_value(x_00))) +print("({},{})".format(1, soln12.get_value(x_11))) \ No newline at end of file diff --git a/gibbon-compiler/src/Gibbon/Bundler.hs b/gibbon-compiler/src/Gibbon/Bundler.hs new file mode 100644 index 000000000..2fdcf0276 --- /dev/null +++ b/gibbon-compiler/src/Gibbon/Bundler.hs @@ -0,0 +1,54 @@ +-- | Union all the modules in a program bundle in to a single program +module Gibbon.Bundler (bundleModules) where +import qualified Data.Foldable as F +import qualified Data.Set as S +import Gibbon.L0.Syntax as L0 +import Gibbon.Common +import Data.Map as M + + + +-- | Main bundler, runs all imported modules through a union that combines +-- their function defintions and data definitions with main's +-- Names should be globally unique at this point +bundleModules :: ProgBundle0 -> PassM Prog0 +bundleModules bundle = do + let (ProgBundle modules main) = bundle + let (ProgModule _ (Prog main_defs main_funs main_exp) _) = main + let (defs, funs) = F.foldr _bundleModule (main_defs, main_funs) modules + return $ Prog defs funs main_exp + +-- | Bundle fold function +-- builds the full program by folding definitons and functions into the main +_bundleModule :: ProgModule0 -> (DDefs0, FunDefs0) -> (DDefs0, FunDefs0) +_bundleModule (ProgModule mod_name (Prog {ddefs, fundefs}) _) (defs1, funs1) = + -- conflict checking,,, extract definition and function names + let ddef_names1 = M.keysSet defs1 + ddef_names2 = M.keysSet ddefs + fn_names1 = M.keysSet funs1 + fn_names2 = M.keysSet fundefs + em1 = S.intersection ddef_names1 ddef_names2 + em2 = S.intersection fn_names1 fn_names2 + conflicts1 = F.foldr (\d acc -> + if (ddefs M.! d) /= (defs1 M.! d) + then d : acc + else acc) + [] em1 + conflicts2 = F.foldr (\f acc -> + if (fundefs M.! f) /= (funs1 M.! f) + then dbgTraceIt + (sdoc ((fundefs M.! f), (funs1 M.! f))) + (f : acc) + else acc) + [] em2 + in case (conflicts1, conflicts2) of + ([], []) -> + (M.union ddefs defs1, M.union fundefs funs1) + (_x:_xs, _) -> + error $ + "Conflicting definitions of " ++ + show conflicts1 ++ " found in " ++ mod_name + (_, _x:_xs) -> + error $ + "Conflicting definitions of " ++ + show (S.toList em2) ++ " found in " ++ mod_name diff --git a/gibbon-compiler/src/Gibbon/Common.hs b/gibbon-compiler/src/Gibbon/Common.hs index c4dab877e..75c320f90 100644 --- a/gibbon-compiler/src/Gibbon/Common.hs +++ b/gibbon-compiler/src/Gibbon/Common.hs @@ -148,7 +148,7 @@ newUniq = state (\x -> (x, x+1)) -- | Generate a unique symbol by attaching a numeric suffix. gensym :: MonadState Int m => Var -> m Var -gensym v = state (\n -> (cleanFunName v `varAppend` "_" `varAppend` toVar (show n), n + 1)) +gensym v = state (\n -> (cleanFunName v `varAppend` toVar (show n), n + 1)) gensym_tag :: MonadState Int m => Var -> String -> m Var gensym_tag v str = state (\n -> (cleanFunName v `varAppend` toVar (show n ++ str) , n + 1)) @@ -356,10 +356,11 @@ abbrv n x = then str else L.take (n-3) str ++ "..." -lookup3 :: (Eq k, Show k, Show a, Show b) => k -> [(k,a,b)] -> (k,a,b) +lookup3 :: HasCallStack => (Eq k, Show k, Show a, Show b) => k -> [(k,a,b)] -> (k,a,b) lookup3 k ls = go ls where - go [] = error$ "lookup3: key "++show k++" not found in list:\n "++L.take 80 (show ls) + --go [] = error$ "lookup3: key "++show k++" not found in list:\n "++L.take 80 (show ls) + go [] = error$ "lookup3: key "++show k++" not found in list:\n "++ (show ls) go ((k1,a1,b1):r) | k1 == k = (k1,a1,b1) | otherwise = go r diff --git a/gibbon-compiler/src/Gibbon/Compiler.hs b/gibbon-compiler/src/Gibbon/Compiler.hs index 6c2e8290d..0ef86335b 100644 --- a/gibbon-compiler/src/Gibbon/Compiler.hs +++ b/gibbon-compiler/src/Gibbon/Compiler.hs @@ -4,6 +4,9 @@ {-# LANGUAGE CPP #-} {-# OPTIONS_GHC -fno-warn-name-shadowing #-} {-# OPTIONS_GHC -fno-warn-unused-binds #-} +{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-} +{-# HLINT ignore "Redundant return" #-} +{-# HLINT ignore "Redundant pure" #-} -- | The compiler pipeline, assembled from several passes. @@ -53,6 +56,7 @@ import Gibbon.L1.Interp() import Gibbon.L2.Interp ( Store, emptyStore ) -- import Gibbon.TargetInterp (Val (..), execProg) +import Gibbon.Bundler (bundleModules) -- Compiler passes import qualified Gibbon.L0.Typecheck as L0 import qualified Gibbon.L0.Specialize2 as L0 @@ -60,6 +64,7 @@ import qualified Gibbon.L0.ElimNewtype as L0 import qualified Gibbon.L1.Typecheck as L1 import qualified Gibbon.L2.Typecheck as L2 import qualified Gibbon.L3.Typecheck as L3 +import Gibbon.Passes.FreshBundle (freshBundleNames) import Gibbon.Passes.Freshen (freshNames) import Gibbon.Passes.Flatten (flattenL1, flattenL2, flattenL3) import Gibbon.Passes.InlineTriv (inlineTriv) @@ -207,8 +212,11 @@ data CompileState a = CompileState , result :: Maybe (Value a) -- ^ Result of evaluating output of prior pass, if available. } +------------------------------------------------------------------------------- -- | Compiler entrypoint, given a full configuration and a list of -- files to process, do the thing. +-- +------------------------------------------------------------------------------- compile :: Config -> FilePath -> IO () compile config@Config{mode,input,verbosity,backend,cfile} fp0 = do -- set the env var DEBUG, to verbosity, when > 1 @@ -217,34 +225,56 @@ compile config@Config{mode,input,verbosity,backend,cfile} fp0 = do -- Use absolute path dir <- getCurrentDirectory let fp1 = dir fp0 - -- Parse the input file - ((l0, cnt0), fp) <- parseInput config input fp1 + -- Parse the input file & imports + -- get the bundle of modules + ((l0_bundle, cnt0), fp) <- parseInput config input fp1 let config' = config { srcFile = Just fp } - let initTypeChecked :: L0.Prog0 - initTypeChecked = - -- We typecheck first to turn the appropriate VarE's into FunRefE's. + ----------------------------------------------------------------------------- + -- do an early typecheck, before running through the passes or into the interpreter + -- perform the minimum transformations for a whole-progrm type-check (freshBundle, bundle, fresh, tc) + + ----------------------------------------------------------------------------- + let initTypeChecked' :: PassM L0.Prog0 + initTypeChecked' = do + bundle <- freshBundleNames l0_bundle + bundle' <- bundleModules bundle + bundle'' <- freshNames bundle' + bundle''' <- L0.tcProg bundle'' + pure bundle''' + let initTypeChecked = fst $ runPassM config 0 initTypeChecked' + {- fst $ runPassM defaultConfig cnt0 - (freshNames l0 >>= - (\fresh -> dbgTrace 5 ("\nFreshen:\n"++sepline++ "\n" ++pprender fresh) (L0.tcProg fresh))) + (freshBundleNames l0_bundle >>= + (\bundled -> dbgTrace 5 ("\nFreshen:\n" ++ sepline ++ "\n" ++ pprender bundled) + (L0.tcProg (fst $ runPassM defaultConfig 1 + (freshNames (fst $ runPassM defaultConfig 0 + (bundleModules bundled) + )) + )) + ) + ) + -} case mode of + -- run via the interpreter on the whole program Interp1 -> do - dbgTrace passChatterLvl ("\nParsed:\n"++sepline++ "\n" ++ sdoc l0) (pure ()) + dbgTrace passChatterLvl ("\nParsed:\n"++sepline++ "\n" ++ sdoc l0_bundle) (pure ()) dbgTrace passChatterLvl ("\nTypechecked:\n"++sepline++ "\n" ++ pprender initTypeChecked) (pure ()) runConf <- getRunConfig [] (_s1,val,_stdout) <- gInterpProg () runConf initTypeChecked print val + ToParse -> dbgPrintLn 0 $ pprender l0_bundle - ToParse -> dbgPrintLn 0 $ pprender l0 - + -- run via the passes _ -> do dbgPrintLn passChatterLvl $ " [compiler] pipeline starting, parsed program: "++ if dbgLvl >= passChatterLvl+1 - then "\n"++sepline ++ "\n" ++ sdoc l0 - else show (length (sdoc l0)) ++ " characters." + then "\n"++sepline ++ "\n" ++ sdoc l0_bundle + else show (length (sdoc l0_bundle)) ++ " characters." + -- (Stage 1) Run the program through the interpreter initResult <- withPrintInterpProg initTypeChecked @@ -253,7 +283,7 @@ compile config@Config{mode,input,verbosity,backend,cfile} fp0 = do let outfile = getOutfile backend fp cfile -- run the initial program through the compiler pipeline - let stM = passes config' l0 + let stM = passes config' l0_bundle l4 <- evalStateT stM (CompileState {cnt=cnt0, result=initResult}) case mode of @@ -321,34 +351,34 @@ setDebugEnvVar verbosity = hPutStrLn stderr$ " ! We set DEBUG based on command-line verbose arg: "++show l -parseInput :: Config -> Input -> FilePath -> IO ((L0.Prog0, Int), FilePath) +parseInput :: Config -> Input -> FilePath -> IO ((L0.ProgBundle0, Int), FilePath) parseInput cfg ip fp = do - (l0, f) <- - case ip of - Haskell -> (, fp) <$> HS.parseFile cfg fp - SExpr -> (, fp) <$> SExp.parseFile fp - Unspecified -> - case takeExtension fp of - ".hs" -> (, fp) <$> HS.parseFile cfg fp - ".sexp" -> (, fp) <$> SExp.parseFile fp - ".rkt" -> (, fp) <$> SExp.parseFile fp - ".gib" -> (, fp) <$> SExp.parseFile fp - oth -> do - -- A silly hack just out of sheer laziness vis-a-vis tab completion: - let f1 = fp ++ ".gib" - f2 = fp ++ "gib" - f1' <- doesFileExist f1 - f2' <- doesFileExist f2 - if (f1' && oth == "") || (f2' && oth == ".") - then (,f2) <$> SExp.parseFile f1 - else error $ mconcat - [ "compile: unrecognized file extension: " - , show oth - , " Please specify compile input format." - ] + --(l0, f) <- (, fp) <$> HS.parseFile cfg fp + (l0, f) <- case ip of + Haskell -> (, fp) <$> HS.parseFile cfg fp + SExpr -> (, fp) <$> SExp.parseFile fp + Unspecified -> + case takeExtension fp of + ".hs" -> (, fp) <$> HS.parseFile cfg fp + ".sexp" -> (, fp) <$> SExp.parseFile fp + ".rkt" -> (, fp) <$> SExp.parseFile fp + ".gib" -> (, fp) <$> SExp.parseFile fp + oth -> do + -- A silly hack just out of sheer laziness vis-a-vis tab completion: + let f1 = fp ++ ".gib" + f2 = fp ++ "gib" + f1' <- doesFileExist f1 + f2' <- doesFileExist f2 + if (f1' && oth == "") || (f2' && oth == ".") + then (,f2) <$> SExp.parseFile f1 + else error $ mconcat + [ "compile: unrecognized file extension: " + , show oth + , " Please specify compile input format." + ] let l0' = do parsed <- l0 -- dbgTraceIt (sdoc parsed) (pure ()) - HS.desugarLinearExts parsed + HS.desugarBundleLinearExts parsed (l0'', cnt) <- pure $ runPassM defaultConfig 0 l0' pure ((l0'', cnt), f) @@ -631,8 +661,8 @@ addRedirectionCon p@Prog{ddefs} = do return $ p { ddefs = ddefs' } -- | The main compiler pipeline -passes :: (Show v) => Config -> L0.Prog0 -> StateT (CompileState v) IO L4.Prog -passes config@Config{dynflags} l0 = do +passes :: (Show v) => Config -> L0.ProgBundle0 -> StateT (CompileState v) IO L4.Prog +passes config@Config{dynflags} l0_bundle = do let isPacked = gopt Opt_Packed dynflags biginf = gopt Opt_BigInfiniteRegions dynflags gibbon1 = gopt Opt_Gibbon1 dynflags @@ -640,6 +670,14 @@ passes config@Config{dynflags} l0 = do parallel = gopt Opt_Parallel dynflags should_fuse = gopt Opt_Fusion dynflags tcProg3 = L3.tcProg isPacked + + -- generate unique names functions and data types + l0_bundle' <- go "freshBundle" freshBundleNames l0_bundle + + -- bundle modules + -- what does cnt do? -> the 0 in the following statement + let l0 = fst $ runPassM defaultConfig 0 (bundleModules l0_bundle') + l0 <- go "freshen" freshNames l0 l0 <- goE0 "typecheck" L0.tcProg l0 l0 <- go "elimNewtypes" L0.elimNewtypes l0 diff --git a/gibbon-compiler/src/Gibbon/HaskellFrontend.hs b/gibbon-compiler/src/Gibbon/HaskellFrontend.hs index 8192da933..a0f50d02a 100644 --- a/gibbon-compiler/src/Gibbon/HaskellFrontend.hs +++ b/gibbon-compiler/src/Gibbon/HaskellFrontend.hs @@ -1,13 +1,20 @@ {-# LANGUAGE LambdaCase #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE RecordWildCards #-} +{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-} +{-# HLINT ignore "Use let" #-} module Gibbon.HaskellFrontend - ( parseFile, primMap, multiArgsToOne, desugarLinearExts ) where + ( parseFile + , primMap + , multiArgsToOne + , desugarBundleLinearExts + , desugarLinearExts + ) where import Control.Monad import Data.Foldable ( foldrM, foldl' ) -import Data.Maybe (catMaybes, isJust) +import Data.Maybe (catMaybes) import qualified Data.Map as M import qualified Data.Set as S import Data.IORef @@ -16,7 +23,8 @@ import Language.Haskell.Exts.Parser import Language.Haskell.Exts.Syntax as H import Language.Haskell.Exts.Pretty import Language.Haskell.Exts.SrcLoc -import Language.Haskell.Exts.CPP +import Language.Haskell.Exts.CPP + ( parseFileContentsWithCommentsAndCPP, defaultCpphsOptions ) import System.Environment ( getEnvironment ) import System.Directory import System.FilePath @@ -28,6 +36,13 @@ import Gibbon.L0.Syntax as L0 import Gibbon.Common import Gibbon.DynFlags +import qualified Data.List as L +import Prelude as P + +import qualified Control.Applicative as L +--import BenchRunner (main) + + -------------------------------------------------------------------------------- {- @@ -56,20 +71,21 @@ it expects A.B.D to be at A/B/A/B/D.hs. [1] https://downloads.haskell.org/ghc/8.6.4/docs/html/users_guide/separate_compilation.html?#the-search-path -} - - -parseFile :: Config -> FilePath -> IO (PassM Prog0) +parseFile :: Config -> FilePath -> IO (PassM ProgBundle0) parseFile cfg path = do - pstate0_ref <- newIORef emptyParseState - parseFile' cfg pstate0_ref [] path - + pstate0_ref <- newIORef emptyParseState + parseFile' cfg pstate0_ref [] path "Main" -data ParseState = ParseState - { imported :: M.Map (String, FilePath) Prog0 } +data ParseState = + ParseState + { imported :: M.Map (String, FilePath) ProgBundle0 + } emptyParseState :: ParseState emptyParseState = ParseState M.empty +-- should be a sperate recursive function that builds the dependency tree, and then another that parses the actual programs + parseMode :: ParseMode parseMode = defaultParseMode { extensions = [ EnableExtension ScopedTypeVariables , EnableExtension CPP @@ -78,16 +94,21 @@ parseMode = defaultParseMode { extensions = [ EnableExtension ScopedTypeVariable ++ (extensions defaultParseMode) } -parseFile' :: Config -> IORef ParseState -> [String] -> FilePath -> IO (PassM Prog0) -parseFile' cfg pstate_ref import_route path = do - when (gopt Opt_GhcTc (dynflags cfg)) $ - typecheckWithGhc cfg path +------------------------------------------------------------------------------- +-- parse a file, call desugar, and return the desugared bundle +-- will recurse down through import headers and fold the bundles together +------------------------------------------------------------------------------- +parseFile' :: + Config -> IORef ParseState -> [String] -> FilePath -> String -> IO (PassM ProgBundle0) +parseFile' cfg pstate_ref import_route path mod_name = do + when (gopt Opt_GhcTc (dynflags cfg)) $ typecheckWithGhc cfg path str <- readFile path let cleaned = removeLinearArrows str -- let parsed = parseModuleWithMode parseMode cleaned parsed <- parseFileContentsWithCommentsAndCPP defaultCpphsOptions parseMode cleaned case parsed of - ParseOk (hs,_comments) -> desugarModule cfg pstate_ref import_route (takeDirectory path) hs + ParseOk (hs, _comments) -> + desugarModule cfg pstate_ref import_route (takeDirectory path) hs mod_name ParseFailed loc er -> do error ("haskell-src-exts failed: " ++ er ++ ", at " ++ prettyPrint loc) @@ -157,59 +178,50 @@ data TopLevel type TopTyEnv = TyEnv TyScheme type TypeSynEnv = M.Map TyCon Ty0 -desugarModule :: (Show a, Pretty a) - => Config -> IORef ParseState -> [String] -> FilePath -> Module a -> IO (PassM Prog0) -desugarModule cfg pstate_ref import_route dir (Module _ head_mb _pragmas imports decls) = do +-- | Merge a list of modules into a program bundle +mergeBundle :: ProgBundle0 -> [ProgModule0] -> [ProgModule0] +mergeBundle (ProgBundle x main) bundle = + foldr (\v acc -> if already_has v then acc else acc ++ [v]) bundle (x ++ [main]) + where + already_imported = L.map (\(ProgModule name _ _) -> name) bundle + already_has :: ProgModule0 -> Bool + already_has (ProgModule name _ _) = L.elem name already_imported + + +-- | Recursively desugars modules and their imports +-- stacks into a ProgBundle: a bundle of modules and their main module +-- each module contains information about it's name, functions & definitions, and import metadata + +desugarModule :: + Config + -> IORef ParseState + -> [String] + -> FilePath + -> Module SrcSpanInfo + -> String + -> IO (PassM ProgBundle0) +desugarModule cfg pstate_ref import_route dir (Module _ head_mb _pragmas imports decls) imported_name = do let type_syns = foldl collectTypeSynonyms M.empty decls - -- Since top-level functions and their types can't be declared in - -- single top-level declaration we first collect types and then collect - -- definitions. funtys = foldr (collectTopTy type_syns) M.empty decls - imported_progs :: [PassM Prog0] <- mapM (processImport cfg pstate_ref (mod_name : import_route) dir) imports + imported_progs :: [PassM ProgBundle0] <- + mapM (processImport cfg pstate_ref (modname : import_route) dir) imports let prog = do + imported_progs' <- mapM id imported_progs toplevels <- catMaybes <$> mapM (collectTopLevel type_syns funtys) decls let (defs,_vars,funs,inlines,main) = foldr classify init_acc toplevels funs' = foldr (\v acc -> M.update (\fn@(FunDef{funMeta}) -> Just (fn { funMeta = funMeta { funInline = Inline }})) v acc) funs inlines - imported_progs' <- mapM id imported_progs - let (defs0,funs0) = - foldr - (\Prog{ddefs,fundefs} (defs1,funs1) -> - let ddef_names1 = M.keysSet defs1 - ddef_names2 = M.keysSet ddefs - fn_names1 = M.keysSet funs1 - fn_names2 = M.keysSet fundefs - em1 = S.intersection ddef_names1 ddef_names2 - em2 = S.intersection fn_names1 fn_names2 - conflicts1 = foldr - (\d acc -> - if (ddefs M.! d) /= (defs1 M.! d) - then d : acc - else acc) - [] - em1 - conflicts2 = foldr - (\f acc -> - if (fundefs M.! f) /= (funs1 M.! f) - then dbgTraceIt (sdoc ((fundefs M.! f), (funs1 M.! f))) (f : acc) - else acc) - [] - em2 - in case (conflicts1, conflicts2) of - ([], []) -> (M.union ddefs defs1, M.union fundefs funs1) - (_x:_xs,_) -> error $ "Conflicting definitions of " ++ show conflicts1 ++ " found in " ++ mod_name - (_,_x:_xs) -> error $ "Conflicting definitions of " ++ show (S.toList em2) ++ " found in " ++ mod_name) - (defs, funs') - imported_progs' - pure (Prog defs0 funs0 main) + let bundle = foldr mergeBundle [] imported_progs' + pure $ ProgBundle bundle (ProgModule modname (Prog defs funs' main) imports) pure prog where init_acc = (M.empty, M.empty, M.empty, S.empty, Nothing) - mod_name = moduleName head_mb - + modname = moduleName head_mb moduleName :: Maybe (ModuleHead a) -> String - moduleName Nothing = "Main" + moduleName Nothing = if imported_name == "Main" then imported_name + else error "Imported module does not have a module declaration" moduleName (Just (ModuleHead _ mod_name1 _warnings _exports)) = - mnameToStr mod_name1 + if imported_name == (mnameToStr mod_name1) || imported_name == "Main" then (mnameToStr mod_name1) + else error "Imported module does not match it's module declaration" classify thing (defs,vars,funs,inlines,main) = case thing of @@ -219,9 +231,9 @@ desugarModule cfg pstate_ref import_route dir (Module _ head_mb _pragmas imports case main of Nothing -> (defs, vars, funs, inlines, m) Just _ -> error $ "A module cannot have two main expressions." - ++ show mod_name + ++ show modname HInline v -> (defs,vars,funs,S.insert v inlines,main) -desugarModule _ _ _ _ m = error $ "desugarModule: " ++ prettyPrint m +desugarModule _ _ _ _ m _ = error $ "desugarModule: " ++ prettyPrint m stdlibModules :: [String] stdlibModules = @@ -234,36 +246,54 @@ stdlibModules = , "Gibbon.ByteString" ] -processImport :: Config -> IORef ParseState -> [String] -> FilePath -> ImportDecl a -> IO (PassM Prog0) -processImport cfg pstate_ref import_route dir decl@ImportDecl{..} +-- TIMMY - top level comment describing what this does +processImport :: + Config + -> IORef ParseState + -> [String] + -> FilePath + -> ImportDecl a + -> IO (PassM ProgBundle0) +processImport cfg pstate_ref import_route dir ImportDecl {..} -- When compiling with Gibbon, we should *NOT* inline things defined in Gibbon.Prim. - | mod_name == "Gibbon.Prim" = pure (pure (Prog M.empty M.empty Nothing)) - | otherwise = do + | mod_name == "Gibbon.Prim" = do + (ParseState imported') <- readIORef pstate_ref + case M.lookup (mod_name, "") imported' of + Just prog -> do pure $ pure prog + Nothing -> pure (pure (ProgBundle L.empty (ProgModule "Gibbon.Prim" (Prog M.empty M.empty Nothing) L.empty) )) + | otherwise = do when (mod_name `elem` import_route) $ - error $ "Circular dependency detected. Import path: "++ show (mod_name : import_route) - when (importQualified) $ error $ "Qualified imports not supported yet. Offending import: " ++ prettyPrint decl - when (isJust importAs) $ error $ "Module aliases not supported yet. Offending import: " ++ prettyPrint decl - when (isJust importSpecs) $ error $ "Selective imports not supported yet. Offending import: " ++ prettyPrint decl + error $ + "Circular dependency detected. Import path: " ++ + show (mod_name : import_route) + --when (isJust importAs) $ + -- error $ + -- "Module aliases not supported yet. Offending import: " ++ prettyPrint decl + --when (isJust importSpecs) $ + -- error $ + -- "Selective imports not supported yet. Offending import: " ++ + -- prettyPrint decl (ParseState imported) <- readIORef pstate_ref mod_fp <- if mod_name `elem` stdlibModules then stdlibImportPath mod_name else modImportPath importModule dir dbgTrace 5 ("Looking at " ++ mod_name) (pure ()) dbgTrace 5 ("Previously imported: " ++ show (M.keysSet imported)) (pure ()) - prog <- case M.lookup (mod_name, mod_fp) imported of - Just prog -> do - dbgTrace 5 ("Already imported " ++ mod_name) (pure ()) - pure prog - Nothing -> do - dbgTrace 5 ("Importing " ++ mod_name ++ " from " ++ mod_fp) (pure ()) - prog0 <- parseFile' cfg pstate_ref import_route mod_fp - (ParseState imported') <- readIORef pstate_ref - let (prog0',_) = defaultRunPassM prog0 - let imported'' = M.insert (mod_name, mod_fp) prog0' imported' - let pstate' = ParseState { imported = imported'' } - writeIORef pstate_ref pstate' - pure prog0' - + prog <- + case M.lookup (mod_name, mod_fp) imported of + Just prog -> do + dbgTrace 5 ("Already imported " ++ mod_name) (pure ()) + pure prog + Nothing -> do + dbgTrace 5 ("Importing " ++ mod_name ++ " from " ++ mod_fp) (pure ()) + -- parse import file + prog0 <- parseFile' cfg pstate_ref import_route mod_fp mod_name + (ParseState imported') <- readIORef pstate_ref + let (prog0', _) = defaultRunPassM prog0 + let imported'' = M.insert (mod_name, mod_fp) prog0' imported' + let pstate' = ParseState {imported = imported''} + writeIORef pstate_ref pstate' + pure prog0' pure (pure prog) where mod_name = mnameToStr importModule @@ -364,9 +394,15 @@ desugarType type_syns ty = case M.lookup con type_syns of Nothing -> PackedTy con [] Just ty' -> ty' - TyFun _ t1 t2 -> let t1' = desugarType type_syns t1 - t2' = desugarType type_syns t2 - in ArrowTy [t1'] t2' + -- now that we have modules we need to parse qualified type names as well + TyCon _ (Qual _ (ModuleName _ modl) (Ident _ con)) -> + case M.lookup (modl ++ "." ++ con) type_syns of + Nothing -> PackedTy (modl ++ "." ++ con) [] + Just ty' -> ty' + TyFun _ t1 t2 -> + let t1' = desugarType type_syns t1 + t2' = desugarType type_syns t2 + in ArrowTy [t1'] t2' TyParen _ ty1 -> desugarType type_syns ty1 TyApp _ tycon arg -> let ty' = desugarType type_syns tycon in @@ -499,8 +535,10 @@ desugarExp type_syns toplevel e = -- | (qnameToStr f) == "error" -> pure $ PrimAppE (ErrorP (litToString lit Paren _ e2 -> desugarExp type_syns toplevel e2 H.Var _ qv -> do + -- where the expression name is parsed (for all expressions) let str = qnameToStr qv v = (toVar str) + -- v = (toVar ("timmy-" ++ str)) if str == "alloc_pdict" then do kty <- newMetaTy @@ -878,21 +916,31 @@ desugarExp type_syns toplevel e = _ -> error ("desugarExp: Unsupported expression: " ++ prettyPrint e) -desugarFun :: (Show a, Pretty a) => TypeSynEnv -> TopTyEnv -> TopTyEnv -> Decl a -> PassM (Var, [Var], TyScheme, Exp0) +-- parse function declarations +desugarFun :: + (Show a, Pretty a) + => TypeSynEnv + -> TopTyEnv + -> TopTyEnv + -> Decl a + -> PassM (Var, [Var], TyScheme, Exp0) desugarFun type_syns toplevel env decl = case decl of FunBind _ [Match _ fname pats (UnGuardedRhs _ bod) _where] -> do + -- where it sets the name ^^ could pass in module name here let fname_str = nameToStr fname fname_var = toVar (fname_str) (vars, arg_tys,bindss) <- unzip3 <$> mapM (desugarPatWithTy type_syns) pats let binds = concat bindss args = vars - fun_ty <- case M.lookup fname_var env of - Nothing -> do - ret_ty <- newMetaTy - let funty = ArrowTy arg_tys ret_ty - pure $ (ForAll [] funty) - Just ty -> pure ty + fun_ty <- + case M.lookup fname_var env of + Nothing -> do + ret_ty <- newMetaTy + let funty = ArrowTy arg_tys ret_ty + pure $ (ForAll [] funty) + Just ty -> pure ty + -- where it parses expressions \/\/ could parse module calls here bod' <- desugarExp type_syns toplevel bod pure $ (fname_var, args, unCurryTopTy fun_ty, (mkLets binds bod')) _ -> error $ "desugarFun: Found a function with multiple RHS, " ++ prettyPrint decl @@ -1070,11 +1118,16 @@ desugarAlt type_syns toplevel alt = Alt _ pat _ _ -> error $ "desugarExp: Unsupported pattern in case: " ++ prettyPrint pat where desugarCase ps conName rhs = do - ps' <- mapM (\x -> case x of - PVar _ v -> (pure . toVar . nameToStr) v - PWildCard _ -> gensym "wildcard_" - _ -> error $ "desugarExp: Non-variable pattern in case." ++ show x) - ps + ps' <- + mapM + (\x -> + case x of + PVar _ v -> (pure . toVar . nameToStr) v + PWildCard _ -> gensym "wildcard_" + -- should parse PTuple + _ -> + error $ "desugarExp: Non-variable pattern in case." ++ show x) + ps rhs' <- desugarExp type_syns toplevel rhs ps'' <- mapM (\v -> (v,) <$> newMetaTy) ps' pure (conName, ps'', rhs') @@ -1276,24 +1329,30 @@ verifyBenchEAssumptions bench_allowed ex = not_allowed = verifyBenchEAssumptions False -------------------------------------------------------------------------------- - -desugarLinearExts :: Prog0 -> PassM Prog0 -desugarLinearExts (Prog ddefs fundefs main) = do - main' <- case main of - Nothing -> pure Nothing - Just (e,ty) -> do - let ty' = goty ty - e' <- go e - pure $ Just (e', ty') - fundefs' <- mapM (\fn -> do - bod <- go (funBody fn) - let (ForAll tyvars ty) = (funTy fn) - ty' = goty ty - pure $ fn { funBody = bod - , funTy = (ForAll tyvars ty') - }) - fundefs - pure (Prog ddefs fundefs' main') +desugarBundleLinearExts :: ProgBundle0 -> PassM ProgBundle0 +desugarBundleLinearExts (ProgBundle bundle main) = do + bundle' <- mapM desugarLinearExts bundle + main' <- desugarLinearExts main + pure $ ProgBundle bundle' main' + +desugarLinearExts :: ProgModule0 -> PassM ProgModule0 +desugarLinearExts (ProgModule name (Prog ddefs fundefs main) imports) = do + main' <- + case main of + Nothing -> pure Nothing + Just (e, ty) -> do + let ty' = goty ty + e' <- go e + pure $ Just (e', ty') + fundefs' <- + mapM + (\fn -> do + bod <- go (funBody fn) + let (ForAll tyvars ty) = (funTy fn) + ty' = goty ty + pure $ fn {funBody = bod, funTy = (ForAll tyvars ty')}) + fundefs + pure $ ProgModule name (Prog ddefs fundefs' main') imports where goty :: Ty0 -> Ty0 goty ty = diff --git a/gibbon-compiler/src/Gibbon/L0/Syntax.hs b/gibbon-compiler/src/Gibbon/L0/Syntax.hs index 80d91c322..e7848b663 100644 --- a/gibbon-compiler/src/Gibbon/L0/Syntax.hs +++ b/gibbon-compiler/src/Gibbon/L0/Syntax.hs @@ -26,6 +26,7 @@ import qualified Data.Map as M import Gibbon.Common as C import Gibbon.Language hiding (UrTy(..)) + -------------------------------------------------------------------------------- -- In L0, type information may be held in locations, as locations don't exist @@ -34,7 +35,13 @@ type DDefs0 = DDefs Ty0 type DDef0 = DDef Ty0 type FunDef0 = FunDef Exp0 type FunDefs0 = FunDefs Exp0 -type Prog0 = Prog Exp0 + +type Prog0 = Prog Exp0 + +------------------------------------------------------------------------------- + +type ProgModule0 = ProgModule Exp0 +type ProgBundle0 = ProgBundle Exp0 -------------------------------------------------------------------------------- diff --git a/gibbon-compiler/src/Gibbon/L0/Typecheck.hs b/gibbon-compiler/src/Gibbon/L0/Typecheck.hs index 947a9e54b..1b22eb7c8 100644 --- a/gibbon-compiler/src/Gibbon/L0/Typecheck.hs +++ b/gibbon-compiler/src/Gibbon/L0/Typecheck.hs @@ -34,13 +34,24 @@ newtype TcM a = TcM (ExceptT Doc PassM a) instance MonadFail TcM where fail = error -runTcM :: TcM a -> PassM (Either Doc a) +runTcM :: TcM a -> PassM (Either Doc a) runTcM (TcM tc) = runExceptT tc -err :: Doc -> TcM a +err :: Doc -> TcM a err d = throwError ("L0.Typecheck: " $$ nest 4 d) -tcProg :: Prog0 -> PassM Prog0 +tcProgBundle :: ProgBundle0 -> PassM ProgBundle0 +tcProgBundle (ProgBundle bundle main) = do + bundle' <- mapM tcProgModule bundle + main' <- tcProgModule main + pure $ ProgBundle bundle' main' + +tcProgModule :: ProgModule0 -> PassM ProgModule0 +tcProgModule (ProgModule modname prog imports) = do + prog' <- tcProg prog + pure $ ProgModule modname prog' imports + +tcProg :: Prog0 -> PassM Prog0 tcProg prg@Prog{ddefs,fundefs,mainExp} = do let init_fenv = M.map funTy fundefs fundefs_tc <- mapM (tcFun ddefs init_fenv) fundefs @@ -68,7 +79,7 @@ tcProg prg@Prog{ddefs,fundefs,mainExp} = do pure prg { fundefs = fundefs' , mainExp = mainExp' } -tcFun :: DDefs0 -> Gamma -> FunDef0 -> PassM FunDef0 +tcFun :: DDefs0 -> Gamma -> FunDef0 -> PassM FunDef0 tcFun ddefs fenv fn@FunDef{funArgs,funTy,funBody, funName} = do res <- runTcM $ do let (ForAll tyvars (ArrowTy gvn_arg_tys gvn_retty)) = funTy @@ -83,7 +94,7 @@ tcFun ddefs fenv fn@FunDef{funArgs,funTy,funBody, funName} = do Left er -> error $ render er ++ " in " ++ show funName Right fn1 -> pure fn1 -tcExps :: DDefs0 -> Subst -> Gamma -> Gamma -> [TyVar] +tcExps :: DDefs0 -> Subst -> Gamma -> Gamma -> [TyVar] -> [(Bool, Exp0)] -> TcM (Subst, [Ty0], [Exp0]) tcExps ddefs sbst venv fenv bound_tyvars ls = do (sbsts,tys,exps) <- unzip3 <$> mapM go ls @@ -92,7 +103,7 @@ tcExps ddefs sbst venv fenv bound_tyvars ls = do go (is_main, e) = tcExp ddefs sbst venv fenv bound_tyvars is_main e -- -tcExp :: DDefs0 -> Subst -> Gamma -> Gamma -> [TyVar] +tcExp :: DDefs0 -> Subst -> Gamma -> Gamma -> [TyVar] -> Bool -> Exp0 -> TcM (Subst, Ty0, Exp0) tcExp ddefs sbst venv fenv bound_tyvars is_main ex = (\(a,b,c) -> (a,b,c)) <$> case ex of @@ -139,7 +150,7 @@ tcExp ddefs sbst venv fenv bound_tyvars is_main ex = (\(a,b,c) -> (a,b,c)) <$> PrimAppE pr args -> do (s1, arg_tys, args_tc) <- tcExps ddefs sbst venv fenv bound_tyvars (zip (repeat is_main) args) let arg_tys' = map (zonkTy s1) arg_tys - checkLen :: Int -> TcM () + checkLen :: Int -> TcM () checkLen n = if length args == n then pure () @@ -637,7 +648,7 @@ tcExp ddefs sbst venv fenv bound_tyvars is_main ex = (\(a,b,c) -> (a,b,c)) <$> pure (a', args', c) ) (dataCons ddf) else pure [x] - ) brs :: TcM [(DataCon, [(Var, Ty0)], Exp0)] + ) brs :: TcM [(DataCon, [(Var, Ty0)], Exp0)] let tycons_brs = map (getTyOfDataCon ddefs . fst3) brs' case L.nub tycons_brs of [one] -> if one == tycon @@ -753,7 +764,7 @@ tcExp ddefs sbst venv fenv bound_tyvars is_main ex = (\(a,b,c) -> (a,b,c)) <$> exp_doc = "In the expression: " <+> doc ex -tcCases :: DDefs0 -> Subst -> Gamma -> Gamma -> [TyVar] +tcCases :: DDefs0 -> Subst -> Gamma -> Gamma -> [TyVar] -> DDef0 -> [(DataCon, [(Var, Ty0)], Exp0)] -> Bool -> Exp0 -> TcM (Subst, Ty0, [(DataCon, [(Var, Ty0)], Exp0)]) tcCases ddefs sbst venv fenv bound_tyvars ddf brs is_main ex = do @@ -779,20 +790,20 @@ tcCases ddefs sbst venv fenv bound_tyvars ddf brs is_main ex = do pure (s3, head tys',exps) where -- pairs [1,2,3,4,5] = [(1,2), (2,3) (4,5)] - pairs :: [a] -> [(a,a)] + pairs :: [a] -> [(a,a)] pairs [] = [] pairs [_] = [] pairs (x:y:xs) = (x,y) : pairs (y:xs) -- | Instantiate the topmost for-alls of the argument type with meta -- type variables. -instantiate :: TyScheme -> TcM ([Ty0], Ty0) +instantiate :: TyScheme -> TcM ([Ty0], Ty0) instantiate (ForAll tvs ty) = do tvs' <- mapM (const newMetaTy) tvs let ty' = substTyVar (M.fromList $ zip tvs tvs') ty pure (tvs', ty') -generalize :: Gamma -> Subst -> [TyVar] -> Ty0 -> TcM (Subst, TyScheme) +generalize :: Gamma -> Subst -> [TyVar] -> Ty0 -> TcM (Subst, TyScheme) generalize env s bound_tyvars ty = do new_bndrs <- mapM (\(Meta i) -> do @@ -809,11 +820,11 @@ generalize env s bound_tyvars ty = do env_tvs = metaTvsInTySchemes (M.elems env) res_tvs = metaTvsInTy ty - meta_tvs :: [MetaTv] + meta_tvs :: [MetaTv] meta_tvs = res_tvs L.\\ env_tvs -- -instDataConTy :: DDefs0 -> DataCon -> TcM ([Ty0], [Ty0], Ty0) +instDataConTy :: DDefs0 -> DataCon -> TcM ([Ty0], [Ty0], Ty0) instDataConTy ddefs dcon = do let tycon = getTyOfDataCon ddefs dcon ddf = lookupDDef ddefs tycon @@ -861,7 +872,7 @@ newtype Subst = Subst (M.Map MetaTv Ty0) instance Semigroup Subst where -- (Subst s1) <> (Subst s2) = -- let mp = M.map (zonkTy (Subst s1)) s2 `M.union` s1 in Subst mp - (<>) :: Subst -> Subst -> Subst + (<>) :: Subst -> Subst -> Subst (Subst s1) <> (Subst s2) = let s2' = M.map (zonkTy (Subst s1)) s2 mp = M.unionWith combine s2' s1 @@ -870,7 +881,7 @@ instance Semigroup Subst where -- | Combine substitutions. In case of substitutions with intersecting keys, -- we will take the narrower type of the two. e.g. combine [($1, $2)] [($1, IntTy)] -- should be [($1, IntTy)]. Map.union does a left biased union so it will result in [($1, $2)] -combine :: Ty0 -> Ty0 -> Ty0 +combine :: Ty0 -> Ty0 -> Ty0 combine v1 v2 | v1 == v2 = v1 | otherwise = case (v1, v2) of (MetaTv _, _) -> v2 @@ -881,7 +892,7 @@ combine v1 v2 | v1 == v2 = v1 (PackedTy a1 v1s, PackedTy a2 v2s) -> if a1 == a2 then PackedTy a1 (zipWith combine v1s v2s) else error $ "PackedTy doesn't match "++ sdoc v1 ++ " with " ++ sdoc v2 - _ -> error $ "Failed to combine = " ++ sdoc v1 ++ " with " ++ sdoc v2 + _ -> error $ "Failed to combine = " ++ sdoc (show v1) ++ " with " ++ sdoc (show v2) emptySubst :: Subst @@ -918,11 +929,11 @@ zonkTy s@(Subst mp) ty = zonkTyScheme :: Subst -> TyScheme -> TyScheme zonkTyScheme s (ForAll tvs ty) = ForAll tvs (zonkTy s ty) -zonkTyEnv :: Subst -> Gamma -> Gamma +zonkTyEnv :: Subst -> Gamma -> Gamma zonkTyEnv s env = M.map (zonkTyScheme s) env -- Apply a substitution to an expression i.e substitue all types in it. -zonkExp :: Subst -> Exp0 -> Exp0 +zonkExp :: Subst -> Exp0 -> Exp0 zonkExp s ex = case ex of VarE{} -> ex @@ -999,7 +1010,7 @@ zonkExp s ex = go = zonkExp s -- Substitute tyvars with types in a ddef. -substTyVarDDef :: DDef0 -> [Ty0] -> TcM DDef0 +substTyVarDDef :: DDef0 -> [Ty0] -> TcM DDef0 substTyVarDDef d@DDef{tyArgs,dataCons} tys = if length tyArgs /= length tys then err $ text "substTyVarDDef: tyArgs don't match the tyapps, in " @@ -1017,7 +1028,7 @@ substTyVarDDef d@DDef{tyArgs,dataCons} tys = , dataCons = dcons' } -- Substitue all tyvars in an expression. -substTyVarExp :: M.Map TyVar Ty0 -> Exp0 -> Exp0 +substTyVarExp :: M.Map TyVar Ty0 -> Exp0 -> Exp0 substTyVarExp s ex = case ex of VarE{} -> ex @@ -1064,7 +1075,7 @@ substTyVarExp s ex = where go = substTyVarExp s -substTyVarPrim :: M.Map TyVar Ty0 -> Prim Ty0 -> Prim Ty0 +substTyVarPrim :: M.Map TyVar Ty0 -> Prim Ty0 -> Prim Ty0 substTyVarPrim mp pr = case pr of VAllocP elty -> VAllocP (substTyVar mp elty) @@ -1095,7 +1106,7 @@ substTyVarPrim mp pr = _ -> pr -tyVarToMetaTyl :: [Ty0] -> TcM (M.Map TyVar Ty0, [Ty0]) +tyVarToMetaTyl :: [Ty0] -> TcM (M.Map TyVar Ty0, [Ty0]) tyVarToMetaTyl tys = foldlM (\(env', acc) ty -> do @@ -1106,7 +1117,7 @@ tyVarToMetaTyl tys = -- | Replace the specified quantified type variables by -- given meta type variables. -tyVarToMetaTy :: Ty0 -> TcM (M.Map TyVar Ty0, Ty0) +tyVarToMetaTy :: Ty0 -> TcM (M.Map TyVar Ty0, Ty0) tyVarToMetaTy = go M.empty where go :: M.Map TyVar Ty0 -> Ty0 -> TcM (M.Map TyVar Ty0, Ty0) @@ -1153,7 +1164,7 @@ tyVarToMetaTy = go M.empty -- Unification -------------------------------------------------------------------------------- -unify :: Exp0 -> Ty0 -> Ty0 -> TcM Subst +unify :: Exp0 -> Ty0 -> Ty0 -> TcM Subst unify ex ty1 ty2 | ty1 == ty2 = --dbgTraceIt (sdoc ty1 ++ "/" ++ sdoc ty2) $ pure emptySubst @@ -1192,7 +1203,7 @@ unify ex ty1 ty2 $$ nest 2 (doc ex) -unifyl :: Exp0 -> [Ty0] -> [Ty0] -> TcM Subst +unifyl :: Exp0 -> [Ty0] -> [Ty0] -> TcM Subst unifyl _ [] [] = pure emptySubst unifyl e (a:as) (b:bs) = do -- N.B. We must apply s1 over the rest of the list before unifying it, i.e. @@ -1207,7 +1218,7 @@ unifyl e as bs = err $ text "Couldn't unify:" <+> doc as <+> text "and" <+> doc $$ text "In the expression: " $$ nest 2 (doc e) -unifyVar :: Exp0 -> MetaTv -> Ty0 -> TcM Subst +unifyVar :: Exp0 -> MetaTv -> Ty0 -> TcM Subst unifyVar ex a t | occursCheck a t = err $ text "Occurs check: cannot construct the inifinite type: " $$ nest 2 (doc a <+> text " ~ " <+> doc t) @@ -1216,14 +1227,14 @@ unifyVar ex a t | otherwise = pure $ Subst (M.singleton a t) -occursCheck :: MetaTv -> Ty0 -> Bool +occursCheck :: MetaTv -> Ty0 -> Bool occursCheck a t = a `elem` metaTvsInTy t -------------------------------------------------------------------------------- -- Other helpers -------------------------------------------------------------------------------- -ensureEqualTy :: Exp0 -> Ty0 -> Ty0 -> TcM () +ensureEqualTy :: Exp0 -> Ty0 -> Ty0 -> TcM () ensureEqualTy ex ty1 ty2 | ty1 == ty2 = pure () | otherwise = err $ text "Couldn't match expected type:" <+> doc ty1 diff --git a/gibbon-compiler/src/Gibbon/L1/Interp.hs b/gibbon-compiler/src/Gibbon/L1/Interp.hs index bad9dae4f..b9d45b8ec 100644 --- a/gibbon-compiler/src/Gibbon/L1/Interp.hs +++ b/gibbon-compiler/src/Gibbon/L1/Interp.hs @@ -297,6 +297,9 @@ applyPrim rc p args = (PrintSym, [VInt n]) -> do tell $ string8 (show n) pure $ VProd [] + (PrintChar, [c]) -> do + tell $ string8 (show c) + pure $ VProd [] oth -> error $ "unhandled prim or wrong number of arguments: "++show oth where diff --git a/gibbon-compiler/src/Gibbon/Language/Syntax.hs b/gibbon-compiler/src/Gibbon/Language/Syntax.hs index 040055886..d08688fe0 100644 --- a/gibbon-compiler/src/Gibbon/Language/Syntax.hs +++ b/gibbon-compiler/src/Gibbon/Language/Syntax.hs @@ -10,44 +10,100 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE UndecidableInstances #-} +{-# LANGUAGE InstanceSigs #-} module Gibbon.Language.Syntax - ( -- * Datatype definitions - DDefs, DataCon, TyCon, Tag, IsBoxed, DDef(..) - , lookupDDef, getConOrdering, getTyOfDataCon, lookupDataCon, lkp - , lookupDataCon', insertDD, emptyDD, fromListDD, isVoidDDef - - -- * Function definitions - , FunctionTy(..), FunDefs, FunDef(..), FunMeta(..), FunRec(..), FunInline(..) - , insertFD, fromListFD, initFunEnv - - -- * Programs - , Prog(..), progToEnv, getFunTy - - -- * Environments - , TyEnv, Env2(..), emptyEnv2 - , extendVEnv, extendsVEnv, lookupVEnv, extendFEnv, lookupFEnv - - -- * Expresssions and thier types - , PreExp(..), Prim(..), UrTy(..) - - -- * Functors for recursion-schemes - , PreExpF(..), PrimF(..), UrTyF(..) - - -- * Generic operations - , FreeVars(..), Expression(..), Binds, Flattenable(..) - , Simplifiable(..), SimplifiableExt(..), Typeable(..) - , Substitutable(..), SubstitutableExt(..), Renamable(..) - - -- * Helpers for writing instances - , HasSimplifiable, HasSimplifiableExt, HasSubstitutable, HasSubstitutableExt - , HasRenamable, HasOut, HasShow, HasEq, HasGeneric, HasNFData - - , -- * Interpreter - Interp(..), InterpExt(..), InterpProg(..), Value(..), ValEnv, InterpLog, - InterpM, runInterpM, execAndPrint - + ( DDefs + , DataCon + , TyCon + , Tag + , IsBoxed + , DDef(..) + , lookupDDef + , getConOrdering + , getTyOfDataCon + , lookupDataCon + , lkp + , lookupDataCon' + , insertDD + , emptyDD + , fromListDD + , isVoidDDef + +-- * Function definitions + , FunctionTy(..) + , FunDefs + , FunDef(..) + , FunMeta(..) + , FunRec(..) + , FunInline(..) + , insertFD + , fromListFD + , initFunEnv + +-- * Programs + , Prog(..) + , ProgModule(..) + , ProgBundle(..) + , progToEnv + , getFunTy + +-- * Environments + , TyEnv + , Env2(..) + , emptyEnv2 + , extendVEnv + , extendsVEnv + , lookupVEnv + , extendFEnv + , lookupFEnv + , lookupVEnv' + +-- * Expresssions and thier types + , PreExp(..) + , Prim(..) + , UrTy(..) + +-- * Functors for recursion-schemes + , PreExpF(..) + , PrimF(..) + , UrTyF(..) + +-- * Generic operations + , FreeVars(..) + , Expression(..) + , Binds + , Flattenable(..) + , Simplifiable(..) + , SimplifiableExt(..) + , Typeable(..) + , Substitutable(..) + , SubstitutableExt(..) + , Renamable(..) + +-- * Helpers for writing instances + , HasSimplifiable + , HasSimplifiableExt + , HasSubstitutable + , HasSubstitutableExt + , HasRenamable + , HasOut + , HasShow + , HasEq + , HasGeneric + , HasNFData + -- * Interpreter + , Interp(..) + , InterpExt(..) + , InterpProg(..) + , Value(..) + , ValEnv + , InterpLog + , InterpM + , runInterpM + , execAndPrint ) where import Control.DeepSeq @@ -63,12 +119,16 @@ import qualified Data.Set as S import Data.Word ( Word8 ) import Data.Kind ( Type ) import Text.PrettyPrint.GenericPretty +import Text.PrettyPrint (text) + import Data.Functor.Foldable.TH import qualified Data.ByteString.Lazy.Char8 as B import Data.ByteString.Builder (Builder) import System.IO.Unsafe (unsafePerformIO) import Gibbon.Common +import Language.Haskell.Exts (ImportDecl, SrcSpanInfo) + -------------------------------------------------------------------------------- -- Data type definitions @@ -241,6 +301,8 @@ data Prog ex = Prog { ddefs :: DDefs (TyOf ex) , mainExp :: Maybe (ex, (TyOf ex)) } +------------------------------------------------------------------------------- + -- Since 'FunDef' is defined using a type family, we cannot use the deriving clause. -- Ryan Scott recommended using singletons-like alternative outlined here: -- https://lpaste.net/365181 @@ -250,7 +312,46 @@ deriving instance (Show (TyOf ex), Show ex, Show (ArrowTy (TyOf ex))) => Show (P deriving instance (Eq (TyOf ex), Eq ex, Eq (ArrowTy (TyOf ex))) => Eq (Prog ex) deriving instance (Ord (TyOf ex), Ord ex, Ord (ArrowTy (TyOf ex))) => Ord (Prog ex) deriving instance Generic (Prog ex) -deriving instance (NFData (TyOf ex), NFData (ArrowTy (TyOf ex)), NFData ex, Generic (ArrowTy (TyOf ex))) => NFData (Prog ex) + +deriving instance + (NFData (TyOf ex), NFData (ArrowTy (TyOf ex)), NFData ex, + Generic (ArrowTy (TyOf ex))) => + NFData (Prog ex) + +------------------------------------------------------------------------------- +-- Module Bundles +-- Before modules get bundled into a single program, they're stored as +-- a tuple of the discrte Prog and it's import declarations +------------------------------------------------------------------------------- + + +data ProgModule ex = ProgModule String (Prog ex) [ImportDecl SrcSpanInfo] +data ProgBundle ex = ProgBundle [ProgModule ex] (ProgModule ex) + +deriving instance + (Show (TyOf ex), Show ex, Show (ArrowTy (TyOf ex))) => + Show (ProgModule ex) +deriving instance Generic (ProgModule ex) +instance Out (ImportDecl SrcSpanInfo) where + doc = text . show + docPrec n v = docPrec n (show v) +instance (NFData (TyOf ex), NFData (ArrowTy (TyOf ex)), NFData ex, Generic (ArrowTy (TyOf ex))) => NFData (ProgModule ex) where + rnf (ProgModule _ prog _) = rnf prog + +deriving instance (Out (Prog ex)) => Out (ProgModule ex) +deriving instance + (Show (TyOf ex), Show ex, Show (ArrowTy (TyOf ex))) => + Show (ProgBundle ex) + +deriving instance + (NFData (TyOf ex), NFData (ArrowTy (TyOf ex)), NFData ex, + Generic (ArrowTy (TyOf ex))) => + NFData (ProgBundle ex) + +deriving instance Generic (ProgBundle ex) +deriving instance (Out (ProgModule ex)) => Out (ProgBundle ex) + + -- | Abstract some of the differences of top level program types, by -- having a common way to extract an initial environment. The diff --git a/gibbon-compiler/src/Gibbon/Passes/FreshBundle.hs b/gibbon-compiler/src/Gibbon/Passes/FreshBundle.hs new file mode 100644 index 000000000..6659ecc19 --- /dev/null +++ b/gibbon-compiler/src/Gibbon/Passes/FreshBundle.hs @@ -0,0 +1,379 @@ +{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-} +{-# HLINT ignore "Fuse foldr/map" #-} + + -- | Create unique names for functions and data types across all modules + -- replace all references with their unique counters parts + -- includes parsing import headers and resolving imported names +module Gibbon.Passes.FreshBundle (freshBundleNames) where +import qualified Data.Map as M +import qualified Data.List as L +import Gibbon.Common +import Gibbon.L0.Syntax +import Language.Haskell.Exts (Name, ImportDecl (ImportDecl), SrcSpanInfo, ImportSpec (..), CName, ModuleName (ModuleName)) +import Language.Haskell.Exts.Syntax (CName(..)) +import Language.Haskell.Exts (Name(..)) +import Language.Haskell.Exts (ImportSpecList(..)) +import GHC.Stack (HasCallStack) + +type VarEnv = M.Map Var Var + + + -- | Go through all the modules and create a global environment of uniques + -- run through each of the modules again and replace references with their unique counterparts, including imported references +freshBundleNames :: ProgBundle0 -> PassM ProgBundle0 +freshBundleNames bundle = do + -- build global map of uniques + -- {legal reference} => unique + (uniquedefenv, uniquefunenv, uniqueconstenv) <- buildGlobalEnv bundle + + let ProgBundle modules main = bundle + -- run through modules, fresh names + modules' <- mapM (\v -> freshModule v bundle uniquedefenv uniquefunenv uniqueconstenv) modules + main' <- freshModule main bundle uniquedefenv uniquefunenv uniqueconstenv + -- update keys + modules'' <- mapM (\v -> freshModuleKeys v uniquedefenv uniquefunenv) modules' + main'' <- freshModuleKeys main' uniquedefenv uniquefunenv + pure $ ProgBundle modules'' main'' + +-- helper functions ----------------------------------------------------------- + +-- | Update the function and data type keys in each module +freshModuleKeys :: ProgModule0 -> VarEnv -> VarEnv -> PassM ProgModule0 +freshModuleKeys (ProgModule name (Prog defs funs main) imports) uniquedefenv uniquefunenv = do + let funs' = M.mapKeys (\k -> findFreshedName (varAppend (toVar (name ++ ".")) k) uniquefunenv) funs + let defs' = M.mapKeys (\k -> findFreshedName (varAppend (toVar (name ++ ".")) k) uniquedefenv) defs + pure $ ProgModule name (Prog defs' funs' main) imports + +-- | Find the imported module from the import header +findImportedModule :: ImportDecl SrcSpanInfo -> M.Map String ProgModule0 -> ProgModule0 +findImportedModule modl modmap = do + let (ImportDecl _ (ModuleName _ name) _ _ _ _ _ _) = modl + case M.lookup name modmap of + Just found -> found + Nothing -> error $ "Could not find module " ++ name ++ " in imported modules: " ++ (show (M.keys modmap)) + +-- | Transform all references to their unique counterparts +freshModule :: ProgModule0 -> ProgBundle0 -> VarEnv -> VarEnv -> VarEnv -> PassM ProgModule0 +freshModule (ProgModule modname (Prog defs funs main) imports) (ProgBundle bundle _) uniquedefenv uniquefunenv uniqueconstrenv = + do + defs' <- traverse (\v -> freshDDef v defenv'' constrenv'') defs + funs' <- traverse (\v -> freshFun v defenv'' funenv'' constrenv'') funs + main' <- case main of + Nothing -> return Nothing + Just (m,ty) -> do m' <- findFreshInExp m defenv'' funenv'' constrenv'' + return $ Just (m',ty) + return $ ProgModule modname (Prog defs' funs' main') imports + where + modname' = toVar (modname ++ ".") + constrs = L.map (\(constrName, _) -> toVar constrName) + (foldr (\(DDef _ _ dataCons) acc -> acc ++ dataCons) [] (M.elems defs)) + -- add qualified and unqualified names to the env + modmap = M.fromList $ L.zip (L.map (\(ProgModule m _ _) -> m) bundle) bundle + funenv = foldr (\f acc -> M.insert (varAppend modname' f) (findFreshedName (varAppend modname' f) uniquefunenv) acc) M.empty (M.keys funs) + defenv = foldr (\d acc -> M.insert (varAppend modname' d) (findFreshedName (varAppend modname' d) uniquedefenv) acc) M.empty (M.keys defs) + constrenv = foldr(\c acc -> M.insert (varAppend modname' c) (findFreshedName (varAppend modname' c) uniqueconstrenv) acc) M.empty constrs + funenv' = foldr (\f acc -> M.insert f (findFreshedName (varAppend modname' f) uniquefunenv) acc) funenv (M.keys funs) + defenv' = foldr (\d acc -> M.insert d (findFreshedName (varAppend modname' d) uniquedefenv) acc) defenv (M.keys defs) + constrenv' = foldr (\c acc -> M.insert c (findFreshedName (varAppend modname' c) uniqueconstrenv) acc) constrenv constrs + (defenv'', funenv'', constrenv'') = + foldr (\(d, f, c) (dacc, facc, cacc) -> (M.union d dacc, M.union f facc, M.union c cacc)) (defenv', funenv', constrenv') + $ map (\i -> getImportedEnv (findImportedModule i modmap) i uniquedefenv uniquefunenv uniqueconstrenv) imports + +-- | Transform references in data definitions to uniques +freshDDef :: HasCallStack => DDef Ty0 -> VarEnv -> VarEnv -> PassM (DDef Ty0) +freshDDef DDef{tyName,tyArgs,dataCons} defenv constrenv = do + let dataCons' = L.map (\(dataCon, vs) -> (fromVar (findFreshedName (toVar dataCon) constrenv), vs)) dataCons + let dataCons'' = L.map (\v -> findFreshInDataCons v defenv) dataCons' + let tyName' = findFreshedName tyName defenv + pure $ DDef tyName' tyArgs dataCons'' + +-- | Transform references in function definitions to uniques +freshFun :: FunDef Exp0 -> VarEnv -> VarEnv -> VarEnv -> PassM (FunDef Exp0) +freshFun (FunDef nam nargs funty bod meta) defenv funenv constrenv = + do + let nam' = findFreshedName nam funenv + funty' <- findFreshInTyScheme funty defenv + let funenv' = foldr (\v acc -> M.insert v v acc ) funenv nargs + bod' <- findFreshInExp bod defenv funenv' constrenv + pure $ FunDef nam' nargs funty' bod' meta + +findFreshInTyScheme :: TyScheme -> VarEnv -> PassM TyScheme +findFreshInTyScheme (ForAll tvs ty) defenv = do + pure $ ForAll tvs $ findFreshInTy ty defenv + +findFreshInTy :: Ty0 -> VarEnv -> Ty0 +findFreshInTy ty defenv = + case ty of + IntTy -> ty + CharTy -> ty + FloatTy -> ty + SymTy0 -> ty + BoolTy -> ty + ArenaTy -> ty + SymSetTy -> ty + SymHashTy -> ty + MetaTv{} -> ty + TyVar _ -> ty + ProdTy tys -> ProdTy $ L.map (\v -> findFreshInTy v defenv) tys + SymDictTy v t -> SymDictTy v $ findFreshInTy t defenv + PDictTy k v -> do + let k' = findFreshInTy k defenv + let v' = findFreshInTy v defenv + PDictTy k' v' + ArrowTy tys t -> do + let tys' = L.map (\v -> findFreshInTy v defenv) tys + let t' = findFreshInTy t defenv + ArrowTy tys' t' + PackedTy tycon tys -> PackedTy (fromVar (findFreshedName (toVar tycon) defenv)) $ L.map (\v -> findFreshInTy v defenv) tys + VectorTy el_t -> VectorTy $ findFreshInTy el_t defenv + ListTy el_t -> ListTy $ findFreshInTy el_t defenv + IntHashTy -> ty + +findFreshInDataCons :: (DataCon, [(IsBoxed, Ty0)]) -> VarEnv -> (DataCon, [(IsBoxed, Ty0)]) +findFreshInDataCons (con, tys) defenv = + do + let tys' = L.map (\(boxed, ty) -> (boxed, (findFreshInTy ty defenv))) tys + (con, tys') + +-- | Find unique names in expressions +findFreshInExp :: Exp0 -> VarEnv -> VarEnv -> VarEnv -> PassM Exp0 +findFreshInExp expr defenv funenv constrenv = + case expr of + LitE i -> return $ LitE i + CharE c -> return $ CharE c + FloatE i -> return $ FloatE i + LitSymE v -> return $ LitSymE v + --VarE v -> return $ VarE (varAppend (toVar "seen-") v) + VarE v -> return $ VarE (tryToFindFreshedName v funenv) + + AppE v locs ls -> do + let v' = findFreshedName v funenv + ls' <- traverse (\e -> findFreshInExp e defenv funenv constrenv) ls + return $ AppE v' locs ls' + + PrimAppE p es -> do + es' <- traverse (\v -> findFreshInExp v defenv funenv constrenv) es + return $ PrimAppE p es' + + LetE (v,_locs,ty, e1) e2 -> do + let ty' = findFreshInTy ty defenv + let funenv' = M.insert v v funenv + e1' <- findFreshInExp e1 defenv funenv' constrenv + e2' <- findFreshInExp e2 defenv funenv' constrenv + return $ LetE (v, [], ty', e1') e2' + + IfE e1 e2 e3 -> do + e1' <- findFreshInExp e1 defenv funenv constrenv + e2' <- findFreshInExp e2 defenv funenv constrenv + e3' <- findFreshInExp e3 defenv funenv constrenv + return $ IfE e1' e2' e3' + + ProjE i e -> do + e' <- findFreshInExp e defenv funenv constrenv + return $ ProjE i e' + + MkProdE es -> do + es' <- traverse (\v -> findFreshInExp v defenv funenv constrenv) es + return $ MkProdE es' + + CaseE e mp -> do + e' <- findFreshInExp e defenv funenv constrenv + mp' <- mapM (\(c,prs,ae) -> do + let c' = case c of + "_default" -> c + _ -> (fromVar (findFreshedName (toVar c) constrenv)) + ae' <- findFreshInExp ae defenv funenv constrenv + return (c', prs, ae')) mp + return $ CaseE e' mp' + + DataConE loc c es -> do + let c' = (fromVar (findFreshedName (toVar c) constrenv)) + es' <- traverse (\v -> findFreshInExp v defenv funenv constrenv) es + return $ DataConE loc c' es' + + TimeIt e t b -> do + e' <- findFreshInExp e defenv funenv constrenv + return $ TimeIt e' t b + WithArenaE v e -> do + e' <- findFreshInExp e defenv funenv constrenv + return $ WithArenaE v e' + SpawnE v locs ls -> do + ls' <- traverse (\e -> findFreshInExp e defenv funenv constrenv) ls + return $ SpawnE v locs ls' + SyncE -> return $ SyncE + MapE (v, d, ve) e -> do + e' <- findFreshInExp e defenv funenv constrenv + ve' <- findFreshInExp ve defenv funenv constrenv + return $ MapE (v, d, ve') e' + FoldE (v1, d1, e1) (v2, d2, e2) e3 -> do + e1' <- findFreshInExp e1 defenv funenv constrenv + e2' <- findFreshInExp e2 defenv funenv constrenv + e3' <- findFreshInExp e3 defenv funenv constrenv + return $ FoldE (v1, d1, e1') (v2, d2, e2') e3' + Ext ext -> case ext of + LambdaE args bod -> do + bod' <- findFreshInExp bod defenv funenv constrenv + return $ Ext $ LambdaE args bod' + PolyAppE a b -> do + return $ Ext $ PolyAppE a b + FunRefE tyapps f -> do + return $ Ext $ FunRefE tyapps f + BenchE fn tyapps args b -> do + args' <- mapM (\arg -> findFreshInExp arg defenv funenv constrenv) args + return $ Ext $ BenchE fn tyapps args' b + ParE0 ls -> do + ls' <- mapM (\l -> findFreshInExp l defenv funenv constrenv) ls + return $ Ext $ ParE0 ls' + PrintPacked ty arg -> do + let ty' = findFreshInTy ty defenv + arg' <- findFreshInExp arg defenv funenv constrenv + return $ Ext $ PrintPacked ty' arg' + CopyPacked ty arg -> do + let ty' = findFreshInTy ty defenv + arg' <- findFreshInExp arg defenv funenv constrenv + return $ Ext $ CopyPacked ty' arg' + TravPacked ty arg -> do + let ty' = findFreshInTy ty defenv + arg' <- findFreshInExp arg defenv funenv constrenv + return $ Ext $ TravPacked ty' arg' + L p e -> do + e' <- findFreshInExp e defenv funenv constrenv + return $ Ext $ L p e' + LinearExt a -> do + return $ Ext $ LinearExt a + +-- | Parse import header and map references to unique names +getImportedEnv :: ProgModule0 -> ImportDecl SrcSpanInfo -> VarEnv -> VarEnv -> VarEnv -> (VarEnv, VarEnv, VarEnv) +getImportedEnv (ProgModule _ (Prog defs funs _) _) imp uniquedefenv uniquefunenv uniqueconstrenv = do + let ImportDecl _ (ModuleName _ impname) qual _ _ _ as specs = imp + let impname' = toVar (impname ++ ".") + let qualname = case as of + Just (ModuleName _ n) -> toVar $ n ++ "." + Nothing -> toVar $ impname ++ "." + let constrs = L.map (\(constrName, _) -> toVar constrName) + (foldr (\(DDef _ _ dataCons) acc -> acc ++ dataCons) [] (M.elems defs)) + let impenv :: (VarEnv, VarEnv, VarEnv) + impenv = case specs of + Just (ImportSpecList _ _ speclist) -> do + let specednames = foldr (\v acc -> (parseSpec v) ++ acc) [] speclist + let funs' = foldr (\k acc -> case M.lookup (varAppend impname' k) uniquefunenv of + Nothing -> acc + Just found -> do + let acc' = M.insert (varAppend qualname k) found acc + if qual then acc' + else M.insert k found acc' + ) M.empty specednames + let defs' = foldr (\k acc -> case M.lookup (varAppend impname' k) uniquedefenv of + Nothing -> acc + Just found -> do + let acc' = M.insert (varAppend qualname k) found acc + if qual then acc' + else M.insert k found acc' + ) M.empty specednames + let constrs' = foldr (\k acc -> case M.lookup (varAppend impname' k) uniqueconstrenv of + Nothing -> acc + Just found -> do + let acc' = M.insert (varAppend qualname k) found acc + if qual then acc' + else M.insert k found acc' + ) M.empty specednames + (defs', funs', constrs') + Nothing -> do + let funs' = foldr (\k acc -> do + let found = findFreshedName (varAppend impname' k) uniquefunenv + let acc' = M.insert (varAppend qualname k) found acc + if qual then acc' + else M.insert k found acc' + ) M.empty (M.keys funs) + let defs' = foldr (\k acc -> do + let found = findFreshedName (varAppend impname' k) uniquedefenv + let acc' = M.insert (varAppend qualname k) found acc + if qual then acc' + else M.insert k found acc' + ) M.empty (M.keys defs) + let constrs' = foldr (\k acc -> case M.lookup (varAppend impname' k) uniqueconstrenv of + Nothing -> acc + Just found -> do + let acc' = M.insert (varAppend qualname k) found acc + if qual then acc' + else M.insert k found acc' + ) M.empty constrs + (defs', funs', constrs') + impenv + +-- simple helper functions to convert `Name`s and `CNames`s to Vars +name2var :: Name SrcSpanInfo -> Var +name2var name = case name of + Ident _ str -> toVar str + Symbol _ str -> toVar str +cname2var :: CName SrcSpanInfo -> Var +cname2var name = case name of + VarName _ str -> name2var str + ConName _ str -> name2var str + +-- parse the import header speclist +parseSpec :: ImportSpec SrcSpanInfo -> [Var] +parseSpec imp = + case imp of + -- imported a variable + IVar _ nm -> [name2var nm] + -- a class, datatype, or type + IAbs _ _ nm -> [name2var nm] + -- a class with all it's methods, or a datatype with all it's constructors + IThingAll _ nm -> [name2var nm] + -- a class with some of it's methods, or a datatype with some of it's constructors + IThingWith _ nm thgs -> [name2var nm] ++ map cname2var thgs + +-- check for conflicts while merging +safeMergeDefs :: (VarEnv, VarEnv, VarEnv) -> (VarEnv, VarEnv, VarEnv) -> (VarEnv, VarEnv, VarEnv) +safeMergeDefs (ddefs, fdefs, constrs) (dacc, facc, cacc) = do + if M.size dx > 0 then error $ "Conflicts while merging data definitions: " ++ (show dx) + else if M.size fx > 0 then error $ "Conflicts while merging function definitions: " ++ (show fx) + else if M.size cx > 0 then error $ "Conflicts while merging constructor definitions: " ++ (show cx) + else (M.union ddefs dacc, M.union fdefs facc, M.union constrs cacc) + where + dx = M.intersection ddefs dacc + fx = M.intersection fdefs facc + cx = M.intersection constrs cacc + +-- construct global registry of uniques +-- returns Map {qualified name} => {globally unique name} +buildGlobalEnv :: ProgBundle0 -> PassM (VarEnv, VarEnv, VarEnv) +buildGlobalEnv (ProgBundle modules main) = do + (ddefenv, fdefenv, constrenv) <- _buildGlobalEnv main -- generate uniques in main module + names <- mapM _buildGlobalEnv modules -- generate uniques in imported modules + pure $ foldr safeMergeDefs (ddefenv, fdefenv, constrenv) names -- union + +-- generate map of qualified names to uniques for a module +_buildGlobalEnv :: ProgModule0 -> PassM (VarEnv, VarEnv, VarEnv) +_buildGlobalEnv (ProgModule modname (Prog ddefs fdefs _) _) = + do + freshfdefs <- mapM gensym fdefs' -- generate uniques + freshddefs <- mapM gensym ddefs' + freshconstrs <- mapM gensym constrs' + let fdefenv = M.fromList $ zip (L.map (\v -> varAppend modname' v) fdefs') freshfdefs -- map qualified names to uniques + let ddefenv = M.fromList $ zip (L.map (\v -> varAppend modname' v) ddefs') freshddefs + let constrenv = M.fromList $ zip (L.map (\v -> varAppend modname' v) constrs') freshconstrs + pure (ddefenv, fdefenv, constrenv) + where + modname' = toVar (modname ++ ".") + constrs = L.map (\(constrName, _) -> toVar constrName) + (foldr (\(DDef _ _ dataCons) acc -> acc ++ dataCons) [] (M.elems ddefs)) + fdefs' = M.keys fdefs -- create qualified names + ddefs' = M.keys ddefs + constrs' = constrs + +-- helper functions +-- try to find the name, but don't cry if you can't,,, used for VarEs +tryToFindFreshedName :: Var -> VarEnv -> Var +tryToFindFreshedName name e = + do case M.lookup name e of + Just freshname -> freshname --toVar ((fromVar freshname) ++ " : " ++ (show e)) + Nothing -> name + +-- map a legal reference to a unique name +findFreshedName :: HasCallStack => Var -> VarEnv -> Var +findFreshedName name e = + case M.lookup name e of + Just freshname -> freshname + Nothing -> error $ "could not find name: " ++ (fromVar name) ++ "\n in env: " ++ (show e) diff --git a/gibbon-compiler/src/Gibbon/Pretty.hs b/gibbon-compiler/src/Gibbon/Pretty.hs index 44defae28..3dec0360e 100644 --- a/gibbon-compiler/src/Gibbon/Pretty.hs +++ b/gibbon-compiler/src/Gibbon/Pretty.hs @@ -3,6 +3,7 @@ {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE ConstraintKinds #-} +{-# LANGUAGE InstanceSigs #-} module Gibbon.Pretty ( Pretty(..), PPStyle(..), HasPretty, render, pprintHsWithEnv, pprender ) where @@ -66,6 +67,28 @@ instance HasPretty ex => Pretty (Prog ex) where PPInternal -> ddefsDoc $+$ funsDoc $+$ meDoc PPHaskell -> ghc_compat_prefix False $+$ ddefsDoc $+$ funsDoc $+$ meDoc $+$ ghc_compat_suffix False +instance HasPretty ex => Pretty (ProgModule ex) where + pprintWithStyle sty (ProgModule _ prog _) = + let (Prog ddefs funs me) = prog + meDoc = case me of + Nothing -> empty + -- Uh, we need versions of hasBenchE for L0, L2 and L3 too : + -- Assume False for now. + Just (e,ty) -> renderMain False (pprintWithStyle sty e) (pprintWithStyle sty ty) + ddefsDoc = vcat $ map (pprintWithStyle sty) $ M.elems ddefs + funsDoc = vcat $ map (pprintWithStyle sty) $ M.elems funs + in case sty of + PPInternal -> ddefsDoc $+$ funsDoc $+$ meDoc + PPHaskell -> ghc_compat_prefix False $+$ ddefsDoc $+$ funsDoc $+$ meDoc $+$ ghc_compat_suffix False + +instance HasPretty ex => Pretty (ProgBundle ex) where + pprintWithStyle sty (ProgBundle bundle main) = + let mainDoc = pprintWithStyle sty main + bundleDoc = vcat $ map (pprintWithStyle sty) $ bundle + in case sty of + PPInternal -> mainDoc $+$ bundleDoc + PPHaskell -> ghc_compat_prefix False $+$ mainDoc $+$ bundleDoc $+$ ghc_compat_suffix False + renderMain :: Bool -> Doc -> Doc -> Doc renderMain has_bench m ty = if has_bench diff --git a/gibbon-compiler/src/Gibbon/SExpFrontend.hs b/gibbon-compiler/src/Gibbon/SExpFrontend.hs index e9c42cdd1..205286b44 100644 --- a/gibbon-compiler/src/Gibbon/SExpFrontend.hs +++ b/gibbon-compiler/src/Gibbon/SExpFrontend.hs @@ -184,10 +184,11 @@ tagDataCons ddefs = go allCons -- | Convert from raw, unstructured S-Expression into the L1 program datatype we expect. -parseSExp :: [Sexp] -> PassM Prog0 +parseSExp :: [Sexp] -> PassM ProgBundle0 parseSExp ses = do prog@Prog {ddefs} <- go ses [] [] [] Nothing - mapMExprs (tagDataCons ddefs) prog + prog' <- mapMExprs (tagDataCons ddefs) prog + pure $ ProgBundle [] (ProgModule "Main" prog' []) where -- WARNING: top-level constant definitions are INLINED everywhere. @@ -723,7 +724,7 @@ handleRequire baseFile (l:ls) = return $ l:ls' -- ^ Parse a file to an L1 program. Return also the gensym counter. -parseFile :: FilePath -> IO (PassM Prog0) +parseFile :: FilePath -> IO (PassM ProgBundle0) parseFile file = do txt <- fmap bracketHacks $ -- fmap stripHashLang $ diff --git a/gibbon-compiler/tests/test-gibbon-examples.yaml b/gibbon-compiler/tests/test-gibbon-examples.yaml index 87c578122..9189cb633 100644 --- a/gibbon-compiler/tests/test-gibbon-examples.yaml +++ b/gibbon-compiler/tests/test-gibbon-examples.yaml @@ -330,9 +330,25 @@ tests: - name: Tuples.hs answer-file: examples/Tuples.hs.ans - - name: Foo.hs + - name: AllThreeImportModifications.hs dir: examples/imports/ - answer-file: examples/imports/Foo.ans + answer-file: examples/imports/AllThreeImportModifications.ans + + - name: ImportQualifiedAndSpecified.hs + dir: examples/imports/ + answer-file: examples/imports/ImportQualifiedAndSpecified.ans + + - name: ImportAliased.hs + dir: examples/imports/ + answer-file: examples/imports/ImportAliased.ans + + - name: ImportQualified.hs + dir: examples/imports/ + answer-file: examples/imports/ImportQualified.ans + + - name: ImportSpecified.hs + dir: examples/imports/ + answer-file: examples/imports/ImportSpecified.ans - name: NeedsClosure.hs dir: examples/poly diff --git a/gibbon-ghc-integration/examples/BinTree.c b/gibbon-ghc-integration/examples/BinTree.c new file mode 100644 index 000000000..e125a2ab7 --- /dev/null +++ b/gibbon-ghc-integration/examples/BinTree.c @@ -0,0 +1,1952 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// #include +#ifdef _WIN64 +#include +#endif +#include +#include +#include // For va_start etc +#include +#include +#include +#include +#ifdef _POINTER +#include +#endif +#ifdef _PARALLEL +#include +#include +#endif + +#define KB 1024lu +#define MB (KB * 1000lu) +#define GB (MB * 1000lu) + +#define REDIRECTION_TAG 255 +#define INDIRECTION_TAG 254 + +// Initial size of BigInfinite buffers +static long long global_init_biginf_buf_size = (4 * GB); + +// Initial size of Infinite buffers +static long long global_init_inf_buf_size = 1 * KB; + +// Maximum size of a chunk, see GitHub #110. +static long long global_inf_buf_max_chunk_size = 1 * GB; + +static long long global_size_param = 1; +static long long global_iters_param = 1; + +static char* global_benchfile_param = NULL; +static char* global_arrayfile_param = NULL; +// Number of lines in the arrayfile +static long long global_arrayfile_length_param = -1; + +// Sequential for now: +static const int num_workers = 1; + +// Count the number of regions allocated. +static long long global_region_count = 0; +static bool global_region_count_flag = false; + +#ifdef _PARALLEL +static inline void bump_global_region_count() { + __atomic_add_fetch(&global_region_count, 1, __ATOMIC_SEQ_CST); + return; +} +#else +static inline void bump_global_region_count() { + global_region_count++; + return; +} +#endif + +static inline void print_global_region_count() { + printf("REGION_COUNT: %lld\n", global_region_count); + return; +} + +#define REDIRECTION_NODE_SIZE 9 +#define MAX(a,b) (((a)>(b))?(a):(b)) +#define MIN(a,b) (((a)<(b))?(a):(b)) + +// https://www.cprogramming.com/snippets/source-code/find-the-number-of-cpu-cores-for-windows-mac-or-linux +static int get_num_processors() { +#ifdef _WIN64 + SYSTEM_INFO sysinfo; + GetSystemInfo(&sysinfo); + return sysinfo.dwNumberOfProcessors; +#else + return sysconf(_SC_NPROCESSORS_ONLN); +#endif +} + +// Requires -std=gnu11 +int dbgprintf(const char *format, ...) { + int code = 0; + va_list args; + va_start(args, format); +#ifdef _DEBUG + code = vprintf(format, args); +#endif + va_end(args); + return code; +} + + +// ----------------------------------------------------------------------------- +// Allocators +// ----------------------------------------------------------------------------- + + +// ------------------------------------- +// Bump allocation for linked-lists +// ------------------------------------- + + +#ifdef _BUMPALLOC +// #define _DEBUG +#warning "Using bump allocator." + +__thread char* bumpalloc_heap_ptr = (char*)NULL; +__thread char* bumpalloc_heap_ptr_end = (char*)NULL; + +char* saved_heap_ptr_stack[100]; +int num_saved_heap_ptr = 0; + +// For simplicity just use a single large slab: +static inline void INITBUMPALLOC() { + bumpalloc_heap_ptr = (char*)malloc(global_init_biginf_buf_size); + bumpalloc_heap_ptr_end = bumpalloc_heap_ptr + global_init_biginf_buf_size; +#ifdef _DEBUG + printf("Arena size for bump alloc: %lld\n", global_init_biginf_buf_size); + printf("BUMPALLOC/INITBUMPALLOC DONE: heap_ptr = %p\n", bumpalloc_heap_ptr); +#endif +} + +static inline void* BUMPALLOC(long long n) { + if (! bumpalloc_heap_ptr) { + INITBUMPALLOC(); + } + if (bumpalloc_heap_ptr + n < bumpalloc_heap_ptr_end) { + char* old= bumpalloc_heap_ptr; + bumpalloc_heap_ptr += n; + return old; + } else { + fprintf(stderr, "Warning: bump allocator ran out of memory."); + exit(1); + } +} + +// Snapshot the current heap pointer value across all threads. +void save_alloc_state() { + dbgprintf("Saving(%p): pos %d", heap_ptr, num_saved_heap_ptr); + saved_heap_ptr_stack[num_saved_heap_ptr] = heap_ptr; + num_saved_heap_ptr++; + dbgprintf("\n"); +} + +void restore_alloc_state() { + if(num_saved_heap_ptr <= 0) { + fprintf(stderr, "Bad call to restore_alloc_state! Saved stack empty!\ne"); + exit(1); + } + num_saved_heap_ptr--; + dbgprintf("Restoring(%p): pos %d, discarding %p", + saved_heap_ptr_stack[num_saved_heap_ptr], num_saved_heap_ptr, bumpalloc_heap_ptr); + bumpalloc_heap_ptr = saved_heap_ptr_stack[num_saved_heap_ptr]; +} + + +#else +// Regular malloc mode: +void INITBUMPALLOC() {} +void save_alloc_state() {} +void restore_alloc_state() {} + +#define BUMPALLOC(n) malloc(n) + +#endif // BUMPALLOC + + +// ------------------------------------- +// ALLOC and ALLOC_PACKED macros +// ------------------------------------- + + +/* + +If parallelism is enabled, we always use a malloc based allocator +since Boehm GC is not thread-safe in its default configuration. It can be +made thread-safe by building it with appropriate flags, but we don't do that. +Presently, all parallel pointer-based programs will leak memory. + +*/ + +#ifdef _PARALLEL +#define ALLOC(n) malloc(n) +#define ALLOC_PACKED_BIG(n) malloc(n) +char *ALLOC_COUNTED(size_t size) { + bump_global_region_count(); + return ALLOC(size); +} +#else + #ifdef _POINTER +#define ALLOC(n) GC_MALLOC(n) +#define ALLOC_PACKED_BIG(n) GC_MALLOC(n) +char *ALLOC_COUNTED(size_t size) { + bump_global_region_count(); + return GC_MALLOC(size); +} + #else +#define ALLOC(n) malloc(n) +#define ALLOC_PACKED_BIG(n) malloc(n) +char *ALLOC_COUNTED(size_t size) { + bump_global_region_count(); + return ALLOC(size); +} + #endif // _POINTER +#endif // _PARALLEL + + +// Could try alloca() here. Better yet, we could keep our own, +// separate stack and insert our own code to restore the pointer +// before any function that (may have) called ALLOC_SCOPED returns. + +// #define ALLOC_SCOPED() alloca(1024) +#define ALLOC_SCOPED(n) alloca(n) +// #define ALLOC_SCOPED() alloc_scoped() + +// Stack allocation is either too small or blows our stack. +// We need a way to make a giant stack if we want to use alloca. +// #define ALLOC_SCOPED() ALLOC(global_init_biginf_buf_size) + +// Our global pointer. No parallelism. +// static char* stack_scoped_region; +// char* alloc_scoped() { return stack_scoped_region; } + + + +// ------------------------------------- +// Basic types +// ------------------------------------- + +// Must be consistent with sizeOfTy defined in Gibbon.Language.Syntax. + +typedef unsigned char TagTyPacked; +typedef unsigned char TagTyBoxed; +typedef long long IntTy; +typedef char CharTy; +typedef float FloatTy; +typedef unsigned long long SymTy; +typedef bool BoolTy; +typedef char* PtrTy; +typedef char* CursorTy; + +// ------------------------------------- +// Arenas and dictionaries +// ------------------------------------- + +typedef struct mem_arena { + int ind; + char* mem; // TODO(vollmerm): make this a list of chunks? + void* reflist; +} mem_arena_t; + +typedef mem_arena_t* ArenaTy; + +ArenaTy alloc_arena() { + ArenaTy ar = ALLOC(sizeof(mem_arena_t)); + ar->ind = 0; + ar->mem = malloc(global_inf_buf_max_chunk_size); + ar->reflist = 0; + return ar; +} + +void free_arena(ArenaTy ar) { + free(ar->mem); + // TODO(vollmerm): free everything in ar->reflist + free(ar); +} + +CursorTy extend_arena(ArenaTy ar, int size) { + CursorTy ret = ar->mem + ar->ind; + ar->ind += size; + return ret; +} + +typedef struct dict_item { + struct dict_item * next; + int key; + void * ptrval; +} dict_item_t; + +dict_item_t * dict_alloc(ArenaTy ar) { + return (dict_item_t *) extend_arena(ar, sizeof(dict_item_t)); // ALLOC(sizeof(dict_item_t)); +} + +dict_item_t *dict_insert_ptr(ArenaTy ar, dict_item_t *ptr, SymTy key, PtrTy val) { + dict_item_t *ret = dict_alloc(ar); + ret->key = key; + ret->ptrval = val; + ret->next = ptr; + return ret; +} + +PtrTy dict_lookup_ptr(dict_item_t *ptr, SymTy key) { + while (ptr != 0) { + if (ptr->key == key) { + return ptr->ptrval; + } else { + ptr = ptr->next; + } + } + printf("Error, key %lld not found!\n",key); + exit(1); +} + +// ------------------------------------- +// Sets +// ------------------------------------- + + +struct set_elem { + int val; + UT_hash_handle hh; +}; + +typedef struct set_elem* SymSetTy; + +SymSetTy empty_set() { + return NULL; +} + +SymSetTy insert_set(SymSetTy set, int sym) { + SymSetTy s; + HASH_FIND_INT(set, &sym, s); /* sym already in the hash? */ + if (s==NULL) { + s = malloc(sizeof(struct set_elem)); + s->val = sym; + HASH_ADD_INT(set,val,s); + } + return set; +} + +BoolTy contains_set(SymSetTy set, int sym) { + SymSetTy s; + HASH_FIND_INT(set, &sym, s); + return (s!=NULL); +} + +// ------------------------------------- +// Sym Hash +// ------------------------------------- + +struct sym_hash_elem { + int key; + int val; + UT_hash_handle hh; +}; + +typedef struct sym_hash_elem* SymHashTy; + +typedef struct sym_hash_elem* IntHashTy; + +SymHashTy empty_hash() { + return NULL; +} + +SymHashTy insert_hash(SymHashTy hash, int k, int v) { + SymHashTy s; + // NOTE: not checking for duplicates! + // s = malloc(sizeof(struct sym_hash_elem)); + s = ALLOC(sizeof(struct sym_hash_elem)); + s->val = v; + s->key = k; + HASH_ADD_INT(hash,key,s); + + return hash; +} + +IntTy lookup_hash(SymHashTy hash, int k) { + SymHashTy s; + HASH_FIND_INT(hash,&k,s); + if (s==NULL) { + return k; // NOTE: return original key if val not found + // TODO(vollmerm): come up with something better to do here + } else { + return s->val; + } +} + +BoolTy contains_hash(SymHashTy hash, int sym) { + SymHashTy s; + HASH_FIND_INT(hash,&sym,s); + return (s!=NULL); +} + +// ------------------------------------- +// Helpers +// ------------------------------------- + +char* read_benchfile_param() { + if (global_benchfile_param == NULL) { + fprintf(stderr, "read_benchfile_param: benchmark input file was not set! Set using --bench-input.\n"); + exit(1); + } else + return global_benchfile_param; +} + +char* read_arrayfile_param() { + if (global_arrayfile_param == NULL) { + fprintf(stderr, "read_arrayfile_param: array input file was not set! Set using --array-input.\n"); + exit(1); + } else + return global_arrayfile_param; +} + +IntTy read_arrayfile_length_param() { + if (global_arrayfile_length_param == -1) { + fprintf(stderr, "read_arrayfile_length_param: array input file length was not set! Set using --array-input-length.\n"); + exit(1); + } else + return global_arrayfile_length_param; +} + + +// fun fact: __ prefix is actually reserved and this is an undefined behavior. +// These functions must be provided by the code generator. +int __main_expr(); + + +void show_usage(char** argv) +{ + printf("\n"); + printf("This binary was generated by the Gibbon compiler.\n"); + printf("\n"); + printf("Usage: %s [OPTS] [size] [iters]\n", argv[0]); + + printf("\n"); + printf("Options:\n"); + printf(" --buffer-size Set the buffer size (default %lld).\n", global_init_biginf_buf_size); + printf(" --bench-input Set the input file read for benchmarking. Applies only\n"); + printf(" IF the program was *compiled* with --bench-fun. \n"); + return; +} + +double avg(const double* arr, int n) +{ + double sum = 0.0; + for(int i=0; itv_sec - t0->tv_sec) + + ((double)(t1->tv_nsec - t0->tv_nsec) / 1000000000.0); +} + +int compare_doubles(const void *a, const void *b) +{ + const double *da = (const double *) a; + const double *db = (const double *) b; + return (*da > *db) - (*da < *db); +} + +// Exponentiation +IntTy expll(IntTy base, IntTy pow) { + if (base == 2) { + return (1 << pow); + } else { + IntTy i, result = 1; + for (i = 0; i < pow; i++) + result *= base; + return result; + } + } + +// ------------------------------------- +// Symbol table +// ------------------------------------- + +#define global_max_symbol_len 256 + +// Invariant: should always be equal to max(sym_table_keys) +static SymTy global_gensym_counter = 0; + +// Its value is updated by the flags parser. +static char *global_bench_prog_param; + +static SymTy newline_symbol = -1; +static SymTy space_symbol = -1; +static SymTy comma_symbol = -1; +static SymTy leftparen_symbol = -1; +static SymTy rightparen_symbol = -1; + +typedef struct SymTable_elem { + SymTy idx; /* key */ + char value[global_max_symbol_len]; + UT_hash_handle hh; /* makes this structure hashable */ +} SymTable_elem; + +// important! initialize to NULL +SymTable_elem *global_sym_table = NULL; + +void add_symbol(SymTy idx, char *value) { + struct SymTable_elem *s; + s = ALLOC(sizeof(struct SymTable_elem)); + s->idx = idx; + strcpy(s->value, value); + HASH_ADD(hh, global_sym_table, idx, sizeof(IntTy), s); + if (idx > global_gensym_counter) { + global_gensym_counter = idx; + } +} + +void set_newline(SymTy idx) { + newline_symbol = idx; + add_symbol(idx,"NEWLINE"); +} + +void set_space(SymTy idx) { + space_symbol = idx; + add_symbol(idx,"SPACE"); +} + +void set_comma(SymTy idx) { + comma_symbol = idx; + add_symbol(idx,"COMMA"); +} + +void set_leftparen(SymTy idx) { + leftparen_symbol = idx; + add_symbol(idx,"LEFTPAREN"); +} + +void set_rightparen(SymTy idx) { + rightparen_symbol = idx; + add_symbol(idx,"RIGHTPAREN"); +} + +IntTy print_symbol(SymTy idx) { + if (idx == comma_symbol) { + return printf(","); + } else if (idx == newline_symbol) { + return printf("\n"); + } else if (idx == space_symbol) { + return printf(" "); + } else if (idx == leftparen_symbol) { + return printf("("); + } else if (idx == rightparen_symbol) { + return printf(")"); + } else { + struct SymTable_elem *s; + HASH_FIND(hh, global_sym_table, &idx, sizeof(SymTy), s); + if (s == NULL) { + return printf("%lld", idx); + } else { + return printf("%s", s->value); + } + + } +} + +#ifdef _PARALLEL +SymTy gensym() { + SymTy idx = __atomic_add_fetch(&global_gensym_counter, 1, __ATOMIC_SEQ_CST); + return idx; +} +#else +SymTy gensym() { + global_gensym_counter += 1; + SymTy idx = global_gensym_counter; + return idx; +} +#endif + +void free_symtable() { + struct SymTable_elem *elt, *tmp; + HASH_ITER(hh, global_sym_table, elt, tmp) { + HASH_DEL(global_sym_table,elt); + } + free(elt); + free(tmp); +} + +/* + +---------------------------------------- +Garbage collection +---------------------------------------- + + Gibbon has "growing regions" i.e each logical region is backed by a doubly linked-list + of smaller chunks which grows as required. In addition to actual data, each chunk + stores some additional metadata (RegionFooter) to chain the chunks together in a list + and for garbage collection. The footer: + + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + serialized data | rf_reg_metadata_ptr | rf_seq_no | rf_size | rf_next | rf_prev + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + The metadata after the serialized data serves various purposes: + + - rf_reg_metadata_ptr: A pointer to a RegionTy struct that contains various metadata. + Of particular interest to us are the fields: + + = reg_id: A unique identifier for a region. + + = refcount and outset: Whenever an inter-region indirection is created, we record that information + using these two fields. Suppose we have an indirection from region A that points to some chunk + in region B. Then A's outset will store a pointer to that chunk's footer, and B's refcount will + be bumped by 1. Note that all there's only 1 refcount cell, and 1 outset per logical region, + and chunks only store a pointer to them. + + - rf_seq_no: The index of this particular chunk in the list. + + - rf_size: Used during bounds checking to calculate the size of the next region in + the linked list. + + - rf_next / rf_prev: Point to the next and previous chunk respectively. + + +There are two ways in which a region may be freed: + +(1) Whenever it goes out of scope + + The RTS tries to free a region whenever it goes out of scope. But this doesn't always succeed as + regions sometimes contain values that "escape". One reason why this'll happen is if there's an + indirection from A->B, and A lives longer than B. + In such a case, when B goes out of scope it's refcount won't be 0, and the RTS won't free it. + This brings us to (2). + +(2) + + When the RTS successfully frees a region, it decrements the refcounts of all the regions it + points to (via the outset). At the same time, if it encounters a region in the outset whoose + refcount becomes 0 after the decrement, it calls free_region on that. This way we can be sure + that all regions will eventually be garbage collected before the program exits. + + + +Why is it a doubly linked-list? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Due to way that bounds-checking works, the pointers in the outset may actually point to any +arbitrary chunk in the chain. However, we must call free_region on the first one to ensure that +all of them are GC'd. So we need pointers to traverse backward get to the first one. +'trav_to_first_chunk' accomplishes this. + + */ + +#define MAX_OUTSET_LENGTH 10 + +typedef struct RegionTy_struct { + SymTy reg_id; + uint reg_refcount; + CursorTy reg_heap; + uint reg_outset_len; + CursorTy reg_outset[MAX_OUTSET_LENGTH]; +} RegionTy; + +typedef struct RegionFooter_struct { + RegionTy *rf_reg_metadata_ptr; + + IntTy rf_seq_no; + IntTy rf_size; + struct RegionFooter_struct *rf_next; + struct RegionFooter_struct *rf_prev; +} RegionFooter; + +typedef struct ChunkTy_struct { + CursorTy chunk_start; + CursorTy chunk_end; +} ChunkTy; + +static inline void insert_into_outset(CursorTy ptr, RegionTy *reg) { + uint outset_len = reg->reg_outset_len; + // Check for duplicates. + for (uint i = 0; i < outset_len; i++) { + if (ptr == reg->reg_outset[i]) { + return; + } + } + // Otherwise, insert into the outset. + reg->reg_outset[outset_len] = ptr; + reg->reg_outset_len = outset_len + 1; + return; +} + +static inline void remove_from_outset(CursorTy ptr, RegionTy *reg) { + uint outset_len = reg->reg_outset_len; + CursorTy *outset = reg->reg_outset; + int i; + if (outset_len == 0) { + fprintf(stderr, "remove_from_outset: empty outset\n"); + exit(1); + } + // Position of 'ptr' in the outset. + int elt_idx = -1; + for (i = 0; i < outset_len; i++) { + if (ptr == outset[i]) { + elt_idx = i; + } + } + if (elt_idx == -1) { + fprintf(stderr, "remove_from_outset: element not found\n"); + exit(1); + } + // Move all elements ahead of 'elt_idx' back by one position. + for (i = elt_idx; i < outset_len; i++) { + outset[i] = outset[i+1]; + } + return; +} + +RegionTy *alloc_region(IntTy size) { + // Allocate the region metadata. + RegionTy *reg = ALLOC(sizeof(RegionTy)); + if (reg == NULL) { + printf("alloc_region: allocation failed: %ld", sizeof(RegionTy)); + exit(1); + } + + // Allocate the first chunk. + IntTy total_size = size + sizeof(RegionFooter); + CursorTy heap = ALLOC_PACKED_BIG(total_size); + if (heap == NULL) { + printf("alloc_region: malloc failed: %lld", total_size); + exit(1); + } + // Not heap+total_size, since we must keep space for the footer. + CursorTy heap_end = heap + size; + + // Initialize metadata fields. + reg->reg_id = gensym(); + reg->reg_refcount = 1; + reg->reg_heap = heap; + reg->reg_outset_len = 0; + +#ifdef _DEBUG + printf("Allocated a region(%lld): %lld bytes.\n", reg->reg_id, size); +#endif + + // Write the footer. + RegionFooter *footer = (RegionFooter *) heap_end; + footer->rf_reg_metadata_ptr = reg; + footer->rf_seq_no = 1; + footer->rf_size = size; + footer->rf_next = NULL; + footer->rf_prev = NULL; + + return reg; +} + +RegionTy *alloc_counted_region(IntTy size) { + // Bump the count. + bump_global_region_count(); + return alloc_region(size); +} + +ChunkTy alloc_chunk(CursorTy end_old_chunk) { + // Get size from current footer. + RegionFooter *footer = (RegionFooter *) end_old_chunk; + IntTy newsize = footer->rf_size * 2; + // See #110. + if (newsize > global_inf_buf_max_chunk_size) { + newsize = global_inf_buf_max_chunk_size; + } + IntTy total_size = newsize + sizeof(RegionFooter); + + // Allocate. + CursorTy start = ALLOC_PACKED_BIG(total_size); + if (start == NULL) { + printf("alloc_chunk: malloc failed: %lld", total_size); + exit(1); + } + CursorTy end = start + newsize; + + // Link the next chunk's footer. + footer->rf_next = (RegionFooter *) end; + + // Write the footer. + RegionFooter* new_footer = (RegionFooter *) end; + new_footer->rf_reg_metadata_ptr = footer->rf_reg_metadata_ptr; + new_footer->rf_seq_no = footer->rf_seq_no + 1; + new_footer->rf_size = newsize; + new_footer->rf_next = NULL; + new_footer->rf_prev = footer; + +#ifdef _DEBUG + RegionTy *reg = (RegionTy*) new_footer->rf_reg_metadata_ptr; + printf("alloc_chunk: allocated %lld bytes for region %lld.\n", total_size, reg->reg_id); +#endif + + return (ChunkTy) {start , end}; +} + +RegionFooter* trav_to_first_chunk(RegionFooter *footer) { + if (footer->rf_seq_no == 1) { + return footer; + } else if (footer->rf_prev == NULL) { + fprintf(stderr, "No previous chunk found at rf_seq_no: %lld", footer->rf_seq_no); + return NULL; + } else { + trav_to_first_chunk((RegionFooter *) footer->rf_prev); + } + return NULL; +} + +uint get_ref_count(CursorTy end_ptr) { + RegionFooter *footer = (RegionFooter *) end_ptr; + RegionTy *reg = (RegionTy *) footer->rf_reg_metadata_ptr; + return reg->reg_refcount; +} + +// B is the pointer, and A is the pointee (i.e B -> A). +// Bump A's refcount and update B's outset. +static inline void bump_ref_count(CursorTy end_b, CursorTy end_a) { + // Grab footers. + RegionFooter *footer_a = (RegionFooter *) end_a; + RegionFooter *footer_b = (RegionFooter *) end_b; + + // Grab metadata. + RegionTy *reg_a = (RegionTy *) footer_a->rf_reg_metadata_ptr; + RegionTy *reg_b = (RegionTy *) footer_b->rf_reg_metadata_ptr; + + // Bump A's refcount. + uint current_refcount, new_refcount; + current_refcount = reg_a->reg_refcount; + new_refcount = current_refcount + 1; + reg_a->reg_refcount = new_refcount; + +#ifdef _DEBUG + printf("bump_ref_count: %lld -> %lld\n", reg_b->reg_id, reg_a->reg_id); + printf("bump_ref_count: old-refcount=%d, old-outset-len=%d:\n", current_refcount, reg_b->reg_outset_len); + assert(current_refcount == reg_b->reg_outset_len+1); +#endif + + // Add A to B's outset. + insert_into_outset(end_a, reg_b); + +#ifdef _DEBUG + // printf("bump_ref_count: Added %p to %lld's outset, %p.\n", end_a, reg_b->reg_id, reg_b); + printf("bump_ref_count: new-refcount=%d, new-outset-len=%d\n", new_refcount, reg_b->reg_outset_len); + assert(new_refcount == reg_b->reg_outset_len+1); +#endif + + return; +} + +void free_region(CursorTy end_reg) { + // Grab footer and the metadata. + RegionFooter *footer = (RegionFooter *) end_reg; + RegionTy *reg = (RegionTy *) footer->rf_reg_metadata_ptr; + + // + RegionFooter *first_chunk_footer, *next_chunk_footer; + CursorTy first_chunk, next_chunk; + + // Decrement current reference count. + uint current_refcount, new_refcount; + current_refcount = reg->reg_refcount; + new_refcount = 0; + if (current_refcount != 0) { + new_refcount = current_refcount - 1; + reg->reg_refcount = new_refcount; + } + +#ifdef _DEBUG + printf("free_region(%lld): refcounts (1): old-refcount=%d, new-refcount=%d:\n", reg->reg_id, current_refcount, new_refcount); +#endif + + + // Free this region recount is 0. + if (new_refcount == 0) { + +#ifdef _DEBUG + printf("free_region(%lld): outset length: %d\n", reg->reg_id, reg->reg_outset_len); +#endif + + // Decrement refcounts, free regions with refcount==0 and also free + // elements of the outset. + if (reg->reg_outset_len != 0) { + uint outset_len = reg->reg_outset_len; + CursorTy *outset = reg->reg_outset; + RegionFooter *elt_footer; + RegionTy *elt_reg; + uint elt_current_refcount, elt_new_refcount; + CursorTy to_be_removed[MAX_OUTSET_LENGTH]; + uint to_be_removed_idx = 0; + for (int i = 0; i < outset_len; i++) { + elt_footer = (RegionFooter *) outset[i]; + elt_reg = (RegionTy *) elt_footer->rf_reg_metadata_ptr; +#ifdef _DEBUG + elt_current_refcount = elt_reg->reg_refcount; +#endif + elt_new_refcount = elt_current_refcount - 1; + elt_reg->reg_refcount = elt_new_refcount; +#ifdef _DEBUG + printf("free_region(%lld): old-refcount=%d, new-refcount=%d:\n", + elt_reg->reg_id, elt_current_refcount, elt_reg->reg_refcount); +#endif + if (elt_new_refcount == 0) { + // See [Why is it a doubly linked-list?] above + first_chunk_footer = trav_to_first_chunk(elt_footer); + if (first_chunk_footer != NULL) { + free_region((CursorTy) first_chunk_footer); + } + } + to_be_removed[to_be_removed_idx] = outset[i]; + to_be_removed_idx++; + } + // Remove elements from the outset. + for (uint i = 0; i < to_be_removed_idx; i++) { + remove_from_outset(to_be_removed[i], reg); + } + } + + +#ifdef _DEBUG + // Bookkeeping + IntTy num_freed_chunks = 0, total_bytesize = 0; +#endif + + // Free the chunks in this region. + first_chunk = end_reg - footer->rf_size; + first_chunk_footer = footer; + next_chunk = (char*) footer->rf_next; + +#ifdef _DEBUG + printf("free_region(%lld)\n", reg->reg_id); +#endif + +#ifdef _DEBUG + num_freed_chunks++; + total_bytesize = total_bytesize + first_chunk_footer->rf_size; +#endif + free(first_chunk); + + while (next_chunk != NULL) { + next_chunk_footer = (RegionFooter *) next_chunk; + #ifdef _DEBUG + num_freed_chunks++; + total_bytesize = total_bytesize + next_chunk_footer->rf_size; + #endif + free(next_chunk - next_chunk_footer->rf_size); + next_chunk = (char*) next_chunk_footer->rf_next; + } + +#ifdef _DEBUG + printf("free_region(%lld): Freed %lld bytes across %lld chunks.\n", + reg->reg_id, total_bytesize, num_freed_chunks); +#endif + + // Free the metadata. + free(reg); + + } else { +#ifdef _DEBUG + printf("free_region(%lld): non-zero refcount: %d.\n", + reg->reg_id, reg->reg_refcount); +#endif + } +} + +// Assume that all nodes with size information have tags >= 150. +BoolTy is_big(IntTy i, CursorTy cur) { + TagTyPacked tag = *(TagTyPacked *) cur; + if (tag >= 150) { + cur += 1; + IntTy size = *(IntTy *) cur; + if (size >= i) { + return true; + } else { + return false; + } + } + return false; +} + +// ------------------------------------- +// Vectors +// ------------------------------------- + +typedef struct VectorTy_struct { + // Bounds on the vector. + IntTy vec_lower, vec_upper; + + // Size of each element. + IntTy vec_elt_size; + + // Actual elements of the vector. + void* vec_data; +} VectorTy; + +VectorTy* vector_alloc(IntTy num, IntTy elt_size) { + VectorTy *vec = ALLOC(sizeof(VectorTy)); + if (vec == NULL) { + printf("alloc_vector: malloc failed: %ld", sizeof(VectorTy)); + exit(1); + } + void* data = ALLOC(num * elt_size); + if (data == NULL) { + printf("alloc_vector: malloc failed: %ld", sizeof(num * elt_size)); + exit(1); + } + vec->vec_lower = 0; + vec->vec_upper = num; + vec->vec_elt_size = elt_size; + vec->vec_data = data; + return vec; +} + +IntTy vector_length(VectorTy *vec) { + return (vec->vec_upper - vec->vec_lower); +} + +BoolTy vector_is_empty(VectorTy *vec) { + return (vector_length(vec) == 0); +} + +VectorTy* vector_slice(IntTy i, IntTy n, VectorTy *vec) { + IntTy lower = vec->vec_lower + i; + IntTy upper = vec->vec_lower + i + n; + if ((lower > vec->vec_upper)) { + printf("vector_slice: lower out of bounds, %lld > %lld", lower, vec->vec_upper); + exit(1); + } + if ((upper > vec->vec_upper)) { + printf("vector_slice: upper out of bounds: %lld > %lld", upper, vec->vec_upper); + exit(1); + } + VectorTy *vec2 = ALLOC(sizeof(VectorTy)); + if (vec == NULL) { + printf("vector_slice: malloc failed: %ld", sizeof(VectorTy)); + exit(1); + } + vec2->vec_lower = lower; + vec2->vec_upper = upper; + vec2->vec_elt_size = vec->vec_elt_size; + vec2->vec_data = vec->vec_data; + return vec2; +} + +// The callers must cast the return value. +static inline void* vector_nth(VectorTy *vec, IntTy i) { + // if (i < vec->lower || i > vec->upper) { + // printf("vector_nth index out of bounds: %lld (%lld,%lld) \n", i, vec->vec_lower, vec->vec_upper); + // exit(1); + // } + return (vec->vec_data + (vec->vec_elt_size * (vec->vec_lower + i))); +} + +static inline VectorTy* vector_inplace_update(VectorTy *vec, IntTy i, void* elt) { + void* dst = vector_nth(vec, i); + memcpy(dst, elt, vec->vec_elt_size); + return vec; +} + +static inline VectorTy* vector_copy(VectorTy *vec) { + IntTy len = vector_length(vec); + void *start = vector_nth(vec, 0); + VectorTy *vec2 = vector_alloc(len, vec->vec_elt_size); + memcpy(vec2->vec_data, start, len * vec->vec_elt_size); + return vec2; +} + +static inline VectorTy* vector_inplace_sort(VectorTy *vec, int (*compar)(const void *, const void*)) { + void *start = vector_nth(vec, 0); + qsort(start, vector_length(vec), vec->vec_elt_size, compar); + return vec; +} + +static inline VectorTy* vector_sort(VectorTy *vec, int (*compar)(const void *, const void*)) { + VectorTy *vec2 = vector_copy(vec); + vector_inplace_sort(vec2, compar); + return vec2; +} + +static inline VectorTy* vector_concat(VectorTy *vec) { + // Length of the input vector. + IntTy len = vector_length(vec); + // Length of the concatenated vector. + IntTy result_len = 0; + // Size of each element in the concatenated vector. + IntTy result_elt_size = 0; + VectorTy **elt_ref, *elt; + for (IntTy i = 0; i < len; i++) { + elt_ref = vector_nth(vec, i); + elt = *elt_ref; + result_elt_size = elt->vec_elt_size; + result_len += vector_length(elt); + } + + // Concatenated vector. + VectorTy *result = vector_alloc(result_len, result_elt_size); + IntTy elt_len; + // A counter that tracks the index of elements in 'result'. + IntTy k = 0; + for (IntTy i = 0; i < len; i++) { + elt_ref = vector_nth(vec, i); + elt = *elt_ref; + elt_len = vector_length(elt); + + for (IntTy j = 0; j < elt_len; j++) { + void* k_elt = vector_nth(elt, j); + vector_inplace_update(result, k, k_elt); + k++; + } + } + + return result; +} + +static inline void vector_free(VectorTy *vec) { + free(vec->vec_data); + free(vec); + return; +} + +static inline VectorTy* vector_merge(VectorTy *vec1, VectorTy *vec2) { + if (vec1->vec_upper != vec2->vec_lower) { + printf("vector_merge: non-contiguous slices, (%lld,%lld), (%lld,%lld).", + vec1->vec_lower, vec1->vec_upper, vec2->vec_lower, vec2->vec_upper); + exit(1); + } + VectorTy *merged = ALLOC(sizeof(VectorTy)); + if (merged == NULL) { + printf("vector_merge: malloc failed: %ld", sizeof(VectorTy)); + exit(1); + } + merged->vec_lower = vec1->vec_lower; + merged->vec_upper = vec2->vec_upper; + merged->vec_elt_size = vec1->vec_elt_size; + merged->vec_data = vec1->vec_data; + return merged; +} + +void print_timing_array(VectorTy *times) { + printf("TIMES: ["); + double *d; + IntTy n = vector_length(times); + for(int i = 0; i < n; i++) { + d = vector_nth(times, i); + if (i == (n-1)) { + printf("%f",*d); + } + else { + printf("%f, ",*d); + } + } + printf("]\n"); +} + +double sum_timing_array(VectorTy *times) { + double *d; + double acc = 0; + for(int i = 0; i < vector_length(times); i++) { + d = vector_nth(times, i); + acc += *d; + } + return acc; +} + +// ------------------------------------- +// Linked lists +// ------------------------------------- + +typedef struct ListTy_struct { + IntTy ll_data_size; + void* ll_data; + struct ListTy_struct* ll_next; +} ListTy; + +static inline ListTy* list_alloc(IntTy data_size) { + // ListTy *ls = ALLOC(sizeof(ListTy)); + ListTy *ls = BUMPALLOC(sizeof(ListTy)); + ls->ll_data_size = data_size; + ls->ll_data = NULL; + ls->ll_next = NULL; + return ls; +} + +static inline BoolTy list_is_empty(ListTy *ls) { + return ls->ll_next == NULL; +} + +static inline ListTy* list_cons(void* elt, ListTy *ls) { + // void* data = ALLOC(ls->data_size); + void* data = BUMPALLOC(ls->ll_data_size); + if (data == NULL) { + printf("list_cons: malloc failed: %lld", ls->ll_data_size); + exit(1); + } + memcpy(data, elt, ls->ll_data_size); + // ListTy *res = ALLOC(sizeof(ListTy)); + ListTy *res = BUMPALLOC(sizeof(ListTy)); + res->ll_data_size = ls->ll_data_size; + res->ll_data = data; + res->ll_next = (ListTy*) ls; + return res; +} + +static inline void* list_head(ListTy *ls) { + return ls->ll_data; +} + +static inline ListTy* list_tail(ListTy *ls) { + return ls->ll_next; +} + +static inline void list_free(ListTy *ls) { + free(ls->ll_data); + free(ls); + return; +} + +static inline ListTy* list_copy(ListTy *ls) { + ListTy *ls2 = list_alloc(ls->ll_data_size); + if (ls->ll_data != NULL) { + void* data = BUMPALLOC(ls->ll_data_size); + memcpy(data, ls->ll_data, ls->ll_data_size); + ls2->ll_data = data; + } + ls2->ll_next = ls->ll_next; + return ls2; +} + +// ------------------------------------- +// Ppm Images +// ------------------------------------- + +typedef struct __Pixel_struct { + IntTy field0; + IntTy field1; + IntTy field2; +} __Pixel; + +void writePpm(char* filename, IntTy width, IntTy height, VectorTy *pixels); +void writePpm_loop(FILE *fp, IntTy idx, IntTy end, VectorTy *pixels); + +// Example: writePpm("gibbon_rgb_1000.ppm", 1000, 1000, pixels); +void writePpm(char* filename, IntTy width, IntTy height, VectorTy *pixels) +{ + FILE *fp; + fp = fopen(filename, "w+"); + fprintf(fp, "P3\n"); + fprintf(fp, "%lld %lld\n255\n", width, height); + IntTy len = vector_length(pixels); + writePpm_loop(fp, 0, len, pixels); + fclose(fp); + return; +} + +void writePpm_loop(FILE *fp, IntTy idx, IntTy end, VectorTy *pixels) +{ + BoolTy fltIf_5768_6575 = idx == end; + + if (fltIf_5768_6575) { + return; + } else { + __Pixel *tmp_112; + tmp_112 = (__Pixel *) vector_nth(pixels, idx); + __Pixel tup = *tmp_112; + IntTy x = tup.field0; + IntTy y = tup.field1; + IntTy z = tup.field2; + // write to file. + fprintf(fp, "%lld %lld %lld\n", x, y, z); + writePpm_loop(fp, (idx+1), end, pixels); + } +} + +/* -------------------------------------------------------------------------------- */ + +int main(int argc, char** argv) +{ + // parameters to parse: + // + // num iterations: How many times to repeat a benchmark. + // tree size: An integer passes to `build_tree()`. + + struct rlimit lim; + int code; + if ( (code = getrlimit(RLIMIT_STACK, &lim)) ) { + fprintf(stderr, " [gibbon rts] failed to getrlimit, code %d\n", code); + exit(1); + } + + // lim.rlim_cur = 1024LU * 1024LU * 1024LU; // 1GB stack. + lim.rlim_cur = 512LU * 1024LU * 1024LU; // 500MB stack. + // lim.rlim_max = lim.rlim_cur; // Normal users may only be able to decrease this. + + // WARNING: Haven't yet figured out why this doesn't work on MacOS... +#ifndef __APPLE__ + code = setrlimit(RLIMIT_STACK, &lim); + while (code) { + fprintf(stderr, " [gibbon rts] Failed to set stack size to %llu, code %d\n", (unsigned long long)lim.rlim_cur, code); + lim.rlim_cur /= 2; + // lim.rlim_max /= 2; + if(lim.rlim_cur < 100 * 1024) { + fprintf(stderr, " [gibbon rts] Failed setrlimit stack size to something reasonable; giving up.\n"); + break; // abort(); + } + int code = setrlimit(RLIMIT_STACK, &lim); + } +#endif + + int got_numargs = 0; // How many numeric arguments have we got. + + int i; + for (i = 1; i < argc; ++i) + { + if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) { + show_usage(argv); + exit(0); + } + else if (strcmp(argv[i], "--biginf-buffer-size") == 0 && i < argc - 1) + { + global_init_biginf_buf_size = atoll(argv[i + 1]); + i++; + } + else if (strcmp(argv[i], "--inf-buffer-size") == 0 && i < argc - 1) + { + global_init_inf_buf_size = atoll(argv[i + 1]); + i++; + } + else if ((strcmp(argv[i], "--bench-input") == 0)) { + if (i+1 >= argc) { + fprintf(stderr, "Not enough arguments after --bench-input, expected .\n"); + show_usage(argv); + exit(1); + } + global_benchfile_param = argv[i+1]; + i++; + } + else if ((strcmp(argv[i], "--array-input") == 0)) { + if (i+1 >= argc) { + fprintf(stderr, "Not enough arguments after --array-input, expected .\n"); + show_usage(argv); + exit(1); + } + global_arrayfile_param = argv[i+1]; + i++; + } + else if (strcmp(argv[i], "--array-input-length") == 0 && i < argc - 1) { + global_arrayfile_length_param = atoll(argv[i+1]); + i++; + } + else if (strcmp(argv[i], "--bench-prog") == 0 && i < argc - 1) { + int len = strlen(argv[i+1]); + global_bench_prog_param = (char*) malloc((len+1)*sizeof(char)); + strncpy(global_bench_prog_param,argv[i+1],len); + i++; + } + // If present, we expect the two arguments to be + else if (got_numargs >= 2) { + fprintf(stderr, "Extra arguments left over: "); + for(; i < argc; i++) fprintf(stderr, "%s ", argv[i]); + show_usage(argv); + exit(1); + } else { + if (got_numargs == 0) { + global_size_param = atoll(argv[i]); + got_numargs ++; + } else { + global_iters_param = atoll(argv[i]); + } + } + } + + // Initialize global_bench_prog_param to an empty string in case + // the runtime argument --bench-prog isn't passed. + if (global_bench_prog_param == NULL) { + global_bench_prog_param = (char*) malloc(1*sizeof(char)); + *global_bench_prog_param = '\n'; + } + + __main_expr(); + + return 0; +} + +// ----------------------------------------------------------------------------- +// Program starts here +// ----------------------------------------------------------------------------- + +typedef struct Prod_struct { } Prod; +typedef struct Int64CursorProd_struct { + IntTy field0; + CursorTy field1; + } Int64CursorProd; +typedef struct BoolCursorProd_struct { + BoolTy field0; + CursorTy field1; + } BoolCursorProd; +typedef struct TagCursorProd_struct { + TagTyPacked field0; + CursorTy field1; + } TagCursorProd; +typedef struct CursorProd_struct { + CursorTy field0; + } CursorProd; +typedef struct CursorCursorProd_struct { + CursorTy field0; + CursorTy field1; + } CursorCursorProd; +typedef struct CursorCursorCursorCursorProd_struct { + CursorTy field0; + CursorTy field1; + CursorTy field2; + CursorTy field3; + } CursorCursorCursorCursorProd; +CursorCursorCursorCursorProd _copy_without_ptrs_Tree_v_41(CursorTy end_r_334, + CursorTy end_r_335, + CursorTy loc_333, + CursorTy arg_76_130_180); +CursorCursorCursorCursorProd _copy_Tree_v_41(CursorTy end_r_338, + CursorTy end_r_339, + CursorTy loc_337, + CursorTy arg_65_141_191); +CursorProd _traverse_Tree_v_41(CursorTy end_r_341, CursorTy arg_87_152_202); +CursorProd _print_Tree_v_41(CursorTy end_r_343, CursorTy arg_98_160_210); +CursorCursorCursorCursorProd +_add_size_and_rel_offsets_Tree_v_41(CursorTy end_r_346, CursorTy end_r_347, + CursorTy loc_345, CursorTy arg_319); +CursorCursorCursorCursorProd _copy_without_ptrs_Tree_v_41(CursorTy end_r_334, + CursorTy end_r_335, + CursorTy loc_333, + CursorTy arg_76_130_180) +{ + CursorTy loc_367 = loc_333 + 1; + CursorTy loc_368 = loc_367 + 8; + TagTyPacked tmpval_733 = *(TagTyPacked *) arg_76_130_180; + CursorTy tmpcur_734 = arg_76_130_180 + 1; + + + switch_789: + ; + switch (tmpval_733) { + + case 0: + { + IntTy tmpval_735 = *(IntTy *) tmpcur_734; + CursorTy tmpcur_736 = tmpcur_734 + sizeof(IntTy); + BoolTy tmpval_737 = *(BoolTy *) tmpcur_736; + CursorTy tmpcur_738 = tmpcur_736 + sizeof(BoolTy); + CursorTy jump_450 = tmpcur_736 + 1; + CursorTy jump_449 = tmpcur_734 + 8; + + *(TagTyPacked *) loc_333 = 0; + + CursorTy writetag_530 = loc_333 + 1; + + *(IntTy *) writetag_530 = tmpval_735; + + CursorTy writecur_531 = writetag_530 + sizeof(IntTy); + + *(BoolTy *) writecur_531 = tmpval_737; + + CursorTy writecur_532 = writecur_531 + sizeof(BoolTy); + + return (CursorCursorCursorCursorProd) {end_r_335, jump_450, loc_333, + writecur_532}; + break; + } + + case 1: + { + IntTy tmpval_743 = *(IntTy *) tmpcur_734; + CursorTy tmpcur_744 = tmpcur_734 + sizeof(IntTy); + CursorTy jump_452 = tmpcur_734 + 8; + CursorCursorCursorCursorProd tmp_struct_0 = + _copy_without_ptrs_Tree_v_41(end_r_334, end_r_335, loc_368, tmpcur_744); + CursorTy pvrtmp_745 = tmp_struct_0.field0; + CursorTy pvrtmp_746 = tmp_struct_0.field1; + CursorTy pvrtmp_747 = tmp_struct_0.field2; + CursorTy pvrtmp_748 = tmp_struct_0.field3; + CursorCursorCursorCursorProd tmp_struct_1 = + _copy_without_ptrs_Tree_v_41(end_r_334, pvrtmp_745, pvrtmp_748, pvrtmp_746); + CursorTy pvrtmp_753 = tmp_struct_1.field0; + CursorTy pvrtmp_754 = tmp_struct_1.field1; + CursorTy pvrtmp_755 = tmp_struct_1.field2; + CursorTy pvrtmp_756 = tmp_struct_1.field3; + + *(TagTyPacked *) loc_333 = 1; + + CursorTy writetag_538 = loc_333 + 1; + + *(IntTy *) writetag_538 = tmpval_743; + + CursorTy writecur_539 = writetag_538 + sizeof(IntTy); + + return (CursorCursorCursorCursorProd) {pvrtmp_753, pvrtmp_754, + loc_333, pvrtmp_756}; + break; + } + + case INDIRECTION_TAG: + { + CursorTy tmpcur_765 = *(CursorTy *) tmpcur_734; + CursorTy tmpaftercur_766 = tmpcur_734 + 8; + CursorTy jump_487 = tmpcur_734 + 8; + CursorCursorCursorCursorProd tmp_struct_2 = + _copy_without_ptrs_Tree_v_41(end_r_334, end_r_335, loc_333, tmpcur_765); + CursorTy pvrtmp_767 = tmp_struct_2.field0; + CursorTy pvrtmp_768 = tmp_struct_2.field1; + CursorTy pvrtmp_769 = tmp_struct_2.field2; + CursorTy pvrtmp_770 = tmp_struct_2.field3; + + return (CursorCursorCursorCursorProd) {pvrtmp_767, jump_487, + pvrtmp_769, pvrtmp_770}; + break; + } + + case REDIRECTION_TAG: + { + CursorTy tmpcur_777 = *(CursorTy *) tmpcur_734; + CursorTy tmpaftercur_778 = tmpcur_734 + 8; + CursorCursorCursorCursorProd tmp_struct_3 = + _copy_without_ptrs_Tree_v_41(end_r_334, end_r_335, loc_333, tmpcur_777); + CursorTy pvrtmp_779 = tmp_struct_3.field0; + CursorTy pvrtmp_780 = tmp_struct_3.field1; + CursorTy pvrtmp_781 = tmp_struct_3.field2; + CursorTy pvrtmp_782 = tmp_struct_3.field3; + + return (CursorCursorCursorCursorProd) {pvrtmp_779, pvrtmp_780, + pvrtmp_781, pvrtmp_782}; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tmpval_733"); + exit(1); + } + } +} +CursorCursorCursorCursorProd _copy_Tree_v_41(CursorTy end_r_338, + CursorTy end_r_339, + CursorTy loc_337, + CursorTy arg_65_141_191) +{ + if (loc_337 + 32 > end_r_339) { + ChunkTy new_chunk_8 = alloc_chunk(end_r_339); + CursorTy chunk_start_9 = new_chunk_8.chunk_start; + CursorTy chunk_end_10 = new_chunk_8.chunk_end; + + end_r_339 = chunk_end_10; + *(TagTyPacked *) loc_337 = 255; + + CursorTy redir = loc_337 + 1; + + *(CursorTy *) redir = chunk_start_9; + loc_337 = chunk_start_9; + } + + CursorTy loc_393 = loc_337 + 1; + CursorTy loc_394 = loc_393 + 8; + TagTyPacked tmpval_790 = *(TagTyPacked *) arg_65_141_191; + CursorTy tmpcur_791 = arg_65_141_191 + 1; + + + switch_846: + ; + switch (tmpval_790) { + + case 0: + { + IntTy tmpval_792 = *(IntTy *) tmpcur_791; + CursorTy tmpcur_793 = tmpcur_791 + sizeof(IntTy); + BoolTy tmpval_794 = *(BoolTy *) tmpcur_793; + CursorTy tmpcur_795 = tmpcur_793 + sizeof(BoolTy); + CursorTy jump_457 = tmpcur_793 + 1; + CursorTy jump_456 = tmpcur_791 + 8; + + *(TagTyPacked *) loc_337 = 0; + + CursorTy writetag_552 = loc_337 + 1; + + *(IntTy *) writetag_552 = tmpval_792; + + CursorTy writecur_553 = writetag_552 + sizeof(IntTy); + + *(BoolTy *) writecur_553 = tmpval_794; + + CursorTy writecur_554 = writecur_553 + sizeof(BoolTy); + + return (CursorCursorCursorCursorProd) {end_r_339, jump_457, loc_337, + writecur_554}; + break; + } + + case 1: + { + IntTy tmpval_800 = *(IntTy *) tmpcur_791; + CursorTy tmpcur_801 = tmpcur_791 + sizeof(IntTy); + CursorTy jump_459 = tmpcur_791 + 8; + CursorCursorCursorCursorProd tmp_struct_4 = + _copy_Tree_v_41(end_r_338, end_r_339, loc_394, tmpcur_801); + CursorTy pvrtmp_802 = tmp_struct_4.field0; + CursorTy pvrtmp_803 = tmp_struct_4.field1; + CursorTy pvrtmp_804 = tmp_struct_4.field2; + CursorTy pvrtmp_805 = tmp_struct_4.field3; + CursorCursorCursorCursorProd tmp_struct_5 = + _copy_Tree_v_41(end_r_338, pvrtmp_802, pvrtmp_805, pvrtmp_803); + CursorTy pvrtmp_810 = tmp_struct_5.field0; + CursorTy pvrtmp_811 = tmp_struct_5.field1; + CursorTy pvrtmp_812 = tmp_struct_5.field2; + CursorTy pvrtmp_813 = tmp_struct_5.field3; + + *(TagTyPacked *) loc_337 = 1; + + CursorTy writetag_560 = loc_337 + 1; + + *(IntTy *) writetag_560 = tmpval_800; + + CursorTy writecur_561 = writetag_560 + sizeof(IntTy); + + return (CursorCursorCursorCursorProd) {pvrtmp_810, pvrtmp_811, + loc_337, pvrtmp_813}; + break; + } + + case INDIRECTION_TAG: + { + CursorTy tmpcur_822 = *(CursorTy *) tmpcur_791; + CursorTy tmpaftercur_823 = tmpcur_791 + 8; + CursorTy jump_493 = tmpcur_791 + 8; + CursorCursorCursorCursorProd tmp_struct_6 = + _copy_Tree_v_41(end_r_338, end_r_339, loc_337, tmpcur_822); + CursorTy pvrtmp_824 = tmp_struct_6.field0; + CursorTy pvrtmp_825 = tmp_struct_6.field1; + CursorTy pvrtmp_826 = tmp_struct_6.field2; + CursorTy pvrtmp_827 = tmp_struct_6.field3; + + return (CursorCursorCursorCursorProd) {pvrtmp_824, jump_493, + pvrtmp_826, pvrtmp_827}; + break; + } + + case REDIRECTION_TAG: + { + CursorTy tmpcur_834 = *(CursorTy *) tmpcur_791; + CursorTy tmpaftercur_835 = tmpcur_791 + 8; + CursorCursorCursorCursorProd tmp_struct_7 = + _copy_Tree_v_41(end_r_338, end_r_339, loc_337, tmpcur_834); + CursorTy pvrtmp_836 = tmp_struct_7.field0; + CursorTy pvrtmp_837 = tmp_struct_7.field1; + CursorTy pvrtmp_838 = tmp_struct_7.field2; + CursorTy pvrtmp_839 = tmp_struct_7.field3; + + return (CursorCursorCursorCursorProd) {pvrtmp_836, pvrtmp_837, + pvrtmp_838, pvrtmp_839}; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tmpval_790"); + exit(1); + } + } +} +CursorProd _traverse_Tree_v_41(CursorTy end_r_341, CursorTy arg_87_152_202) +{ + TagTyPacked tmpval_847 = *(TagTyPacked *) arg_87_152_202; + CursorTy tmpcur_848 = arg_87_152_202 + 1; + + + switch_863: + ; + switch (tmpval_847) { + + case 0: + { + IntTy tmpval_849 = *(IntTy *) tmpcur_848; + CursorTy tmpcur_850 = tmpcur_848 + sizeof(IntTy); + BoolTy tmpval_851 = *(BoolTy *) tmpcur_850; + CursorTy tmpcur_852 = tmpcur_850 + sizeof(BoolTy); + CursorTy jump_464 = tmpcur_850 + 1; + CursorTy jump_463 = tmpcur_848 + 8; + + return (CursorProd) {jump_464}; + break; + } + + case 1: + { + IntTy tmpval_853 = *(IntTy *) tmpcur_848; + CursorTy tmpcur_854 = tmpcur_848 + sizeof(IntTy); + CursorTy jump_466 = tmpcur_848 + 8; + CursorProd tmp_struct_11 = + _traverse_Tree_v_41(end_r_341, tmpcur_854); + CursorTy pvrtmp_855 = tmp_struct_11.field0; + CursorProd tmp_struct_12 = + _traverse_Tree_v_41(end_r_341, pvrtmp_855); + CursorTy pvrtmp_856 = tmp_struct_12.field0; + + return (CursorProd) {pvrtmp_856}; + break; + } + + case INDIRECTION_TAG: + { + CursorTy tmpcur_857 = *(CursorTy *) tmpcur_848; + CursorTy tmpaftercur_858 = tmpcur_848 + 8; + CursorTy jump_499 = tmpcur_848 + 8; + CursorProd tmp_struct_13 = + _traverse_Tree_v_41(end_r_341, tmpcur_857); + CursorTy pvrtmp_859 = tmp_struct_13.field0; + + return (CursorProd) {jump_499}; + break; + } + + case REDIRECTION_TAG: + { + CursorTy tmpcur_860 = *(CursorTy *) tmpcur_848; + CursorTy tmpaftercur_861 = tmpcur_848 + 8; + CursorProd tmp_struct_14 = + _traverse_Tree_v_41(end_r_341, tmpcur_860); + CursorTy pvrtmp_862 = tmp_struct_14.field0; + + return (CursorProd) {pvrtmp_862}; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tmpval_847"); + exit(1); + } + } +} +CursorProd _print_Tree_v_41(CursorTy end_r_343, CursorTy arg_98_160_210) +{ + TagTyPacked tmpval_864 = *(TagTyPacked *) arg_98_160_210; + CursorTy tmpcur_865 = arg_98_160_210 + 1; + + + switch_880: + ; + switch (tmpval_864) { + + case 0: + { + IntTy tmpval_866 = *(IntTy *) tmpcur_865; + CursorTy tmpcur_867 = tmpcur_865 + sizeof(IntTy); + BoolTy tmpval_868 = *(BoolTy *) tmpcur_867; + CursorTy tmpcur_869 = tmpcur_867 + sizeof(BoolTy); + CursorTy jump_471 = tmpcur_867 + 1; + CursorTy jump_470 = tmpcur_865 + 8; + unsigned char wildcard_103_163_213 = print_symbol(729); + unsigned char wildcard_106_164_214 = print_symbol(732); + unsigned char y_101_165_215 = printf("%lld", tmpval_866); + unsigned char wildcard_105_166_216 = print_symbol(732); + unsigned char y_102_167_217 = printf("%d", tmpval_868); + unsigned char wildcard_104_168_218 = print_symbol(727); + + return (CursorProd) {jump_471}; + break; + } + + case 1: + { + IntTy tmpval_870 = *(IntTy *) tmpcur_865; + CursorTy tmpcur_871 = tmpcur_865 + sizeof(IntTy); + CursorTy jump_473 = tmpcur_865 + 8; + unsigned char wildcard_113_172_222 = print_symbol(728); + unsigned char wildcard_117_173_223 = print_symbol(732); + unsigned char y_110_174_224 = printf("%lld", tmpval_870); + unsigned char wildcard_116_175_225 = print_symbol(732); + CursorProd tmp_struct_15 = _print_Tree_v_41(end_r_343, tmpcur_871); + CursorTy pvrtmp_872 = tmp_struct_15.field0; + unsigned char wildcard_115_177_227 = print_symbol(732); + CursorProd tmp_struct_16 = _print_Tree_v_41(end_r_343, pvrtmp_872); + CursorTy pvrtmp_873 = tmp_struct_16.field0; + unsigned char wildcard_114_179_229 = print_symbol(727); + + return (CursorProd) {pvrtmp_873}; + break; + } + + case INDIRECTION_TAG: + { + CursorTy tmpcur_874 = *(CursorTy *) tmpcur_865; + CursorTy tmpaftercur_875 = tmpcur_865 + 8; + CursorTy jump_505 = tmpcur_865 + 8; + unsigned char wildcard_508 = print_symbol(731); + CursorProd tmp_struct_17 = _print_Tree_v_41(end_r_343, tmpcur_874); + CursorTy pvrtmp_876 = tmp_struct_17.field0; + + return (CursorProd) {jump_505}; + break; + } + + case REDIRECTION_TAG: + { + CursorTy tmpcur_877 = *(CursorTy *) tmpcur_865; + CursorTy tmpaftercur_878 = tmpcur_865 + 8; + unsigned char wildcard_508 = print_symbol(730); + CursorProd tmp_struct_18 = _print_Tree_v_41(end_r_343, tmpcur_877); + CursorTy pvrtmp_879 = tmp_struct_18.field0; + + return (CursorProd) {pvrtmp_879}; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tmpval_864"); + exit(1); + } + } +} +CursorCursorCursorCursorProd _add_size_and_rel_offsets_Tree_v_41(CursorTy end_r_346, + CursorTy end_r_347, + CursorTy loc_345, + CursorTy arg_319) +{ + if (loc_345 + 32 > end_r_347) { + ChunkTy new_chunk_23 = alloc_chunk(end_r_347); + CursorTy chunk_start_24 = new_chunk_23.chunk_start; + CursorTy chunk_end_25 = new_chunk_23.chunk_end; + + end_r_347 = chunk_end_25; + *(TagTyPacked *) loc_345 = 255; + + CursorTy redir = loc_345 + 1; + + *(CursorTy *) redir = chunk_start_24; + loc_345 = chunk_start_24; + } + + CursorTy loc_441 = loc_345 + 1; + CursorTy loc_442 = loc_441 + 8; + TagTyPacked tmpval_881 = *(TagTyPacked *) arg_319; + CursorTy tmpcur_882 = arg_319 + 1; + + + switch_937: + ; + switch (tmpval_881) { + + case 0: + { + IntTy tmpval_883 = *(IntTy *) tmpcur_882; + CursorTy tmpcur_884 = tmpcur_882 + sizeof(IntTy); + BoolTy tmpval_885 = *(BoolTy *) tmpcur_884; + CursorTy tmpcur_886 = tmpcur_884 + sizeof(BoolTy); + CursorTy jump_478 = tmpcur_884 + 1; + CursorTy jump_477 = tmpcur_882 + 8; + + *(TagTyPacked *) loc_345 = 0; + + CursorTy writetag_600 = loc_345 + 1; + + *(IntTy *) writetag_600 = tmpval_883; + + CursorTy writecur_601 = writetag_600 + sizeof(IntTy); + + *(BoolTy *) writecur_601 = tmpval_885; + + CursorTy writecur_602 = writecur_601 + sizeof(BoolTy); + + return (CursorCursorCursorCursorProd) {end_r_347, jump_478, loc_345, + writecur_602}; + break; + } + + case 1: + { + IntTy tmpval_891 = *(IntTy *) tmpcur_882; + CursorTy tmpcur_892 = tmpcur_882 + sizeof(IntTy); + CursorTy jump_480 = tmpcur_882 + 8; + CursorCursorCursorCursorProd tmp_struct_19 = + _add_size_and_rel_offsets_Tree_v_41(end_r_346, end_r_347, loc_442, tmpcur_892); + CursorTy pvrtmp_893 = tmp_struct_19.field0; + CursorTy pvrtmp_894 = tmp_struct_19.field1; + CursorTy pvrtmp_895 = tmp_struct_19.field2; + CursorTy pvrtmp_896 = tmp_struct_19.field3; + CursorCursorCursorCursorProd tmp_struct_20 = + _add_size_and_rel_offsets_Tree_v_41(end_r_346, pvrtmp_893, pvrtmp_896, pvrtmp_894); + CursorTy pvrtmp_901 = tmp_struct_20.field0; + CursorTy pvrtmp_902 = tmp_struct_20.field1; + CursorTy pvrtmp_903 = tmp_struct_20.field2; + CursorTy pvrtmp_904 = tmp_struct_20.field3; + + *(TagTyPacked *) loc_345 = 1; + + CursorTy writetag_608 = loc_345 + 1; + + *(IntTy *) writetag_608 = tmpval_891; + + CursorTy writecur_609 = writetag_608 + sizeof(IntTy); + + return (CursorCursorCursorCursorProd) {pvrtmp_901, pvrtmp_902, + loc_345, pvrtmp_904}; + break; + } + + case INDIRECTION_TAG: + { + CursorTy tmpcur_913 = *(CursorTy *) tmpcur_882; + CursorTy tmpaftercur_914 = tmpcur_882 + 8; + CursorTy jump_511 = tmpcur_882 + 8; + CursorCursorCursorCursorProd tmp_struct_21 = + _add_size_and_rel_offsets_Tree_v_41(end_r_346, end_r_347, loc_345, tmpcur_913); + CursorTy pvrtmp_915 = tmp_struct_21.field0; + CursorTy pvrtmp_916 = tmp_struct_21.field1; + CursorTy pvrtmp_917 = tmp_struct_21.field2; + CursorTy pvrtmp_918 = tmp_struct_21.field3; + + return (CursorCursorCursorCursorProd) {pvrtmp_915, jump_511, + pvrtmp_917, pvrtmp_918}; + break; + } + + case REDIRECTION_TAG: + { + CursorTy tmpcur_925 = *(CursorTy *) tmpcur_882; + CursorTy tmpaftercur_926 = tmpcur_882 + 8; + CursorCursorCursorCursorProd tmp_struct_22 = + _add_size_and_rel_offsets_Tree_v_41(end_r_346, end_r_347, loc_345, tmpcur_925); + CursorTy pvrtmp_927 = tmp_struct_22.field0; + CursorTy pvrtmp_928 = tmp_struct_22.field1; + CursorTy pvrtmp_929 = tmp_struct_22.field2; + CursorTy pvrtmp_930 = tmp_struct_22.field3; + + return (CursorCursorCursorCursorProd) {pvrtmp_927, pvrtmp_928, + pvrtmp_929, pvrtmp_930}; + break; + } + + default: + { + printf("%s\n", "Unknown tag in: tmpval_881"); + exit(1); + } + } +} +int __main_expr() +{ + add_symbol(727, ")"); + add_symbol(728, "(Node_v_41"); + add_symbol(729, "(Leaf_v_41"); + add_symbol(730, " ->r "); + add_symbol(731, " ->i "); + add_symbol(732, " "); +} \ No newline at end of file