Giter Site home page Giter Site logo

manticoreproject / manticore Goto Github PK

View Code? Open in Web Editor NEW
68.0 11.0 7.0 19.76 MB

Parallel ML compiler

Home Page: http://manticore.cs.uchicago.edu

License: MIT License

Makefile 0.57% M4 0.85% Shell 0.36% Standard ML 67.22% C 8.77% C++ 2.51% Assembly 0.21% CSS 0.04% Emacs Lisp 0.02% HTML 0.04% Haskell 10.44% Objective-C 2.04% Objective-C++ 3.91% Lex 0.28% TeX 2.72% Dockerfile 0.02%
parallel sml manticore compiler

manticore's Issues

Unboxing an uncurried function

From the old "curried vs uncurried" bug report, when compiling with -sequential, which also turns on unboxing, we get the following broken BOM after unboxing

➤ ../../../bin/pmlc -sequential -Cbom.check-all=true curried_vs_uncurried.pml 
***** Bogus BOM in Main after unbox *****
** type mismatch in Apply _t<BB80>#1.1 in h_uncurried<C6AA>#2.2
==   expected  int
==   but found [int]
** type mismatch in Apply _t<BA8F>#1.1 in h_uncurried<C6AA>#2.2
==   expected  int
==   but found [int]
broken BOM dumped to broken-BOM
bom/check-bom.sml:544.11-544.28: Fail: broken BOM

Here's the program:

fun theFunction x i = 
    let fun g x accum =
            case x
                of x::xs => h xs (accum + x)
                 | nil => accum
        and h x accum =
             case x
                of y::nil => g x accum
                 | x::xs => h xs (accum + x)
                 | nil => accum
    in  g x 0 end

val _ = print("Result = " ^ Int.toString (theFunction (List.tabulate(100, fn _ => 1)) 1000 ) ^ "\n")

Manticore Nix package incompatible with SML/NJ >= 110.81

@kavon Hello! I am facing an issue with building manticore using Nix using SML/NJ v110.84 on x86_64. (Failing build log)

The error is being encountered with code in amd64-gen-fn.sml

[compiling driver/(x86_64-linux.cm):../codegen/(sources.cm):(wrapper.cm):(group.cm):amd64/amd64-gen-fn.sml]
codegen/amd64/amd64-gen-fn.sml:110.33-118.7 Error: value type in structure doesn't match signature spec
    name: signBit
  spec:   int -> AMD64MLTree.rexp
  actual: int -> Label.label
codegen/amd64/amd64-gen-fn.sml:110.33-118.7 Error: value type in structure doesn't match signature spec
    name: negateSignBit
  spec:   int -> AMD64MLTree.rexp
  actual: int -> Label.label
Error: Compiler bug: ModuleUtil: getStr: bad entity
Compilation failed.
make[2]: *** [Makefile:83: pmlc.x86-linux] Error 1
make[2]: Leaving directory '/nix/store/5zy5w8jjm8vzaqjhhqpn9z7mpncmk01m-manticore-2017.08.22/repo_checkout/src/tools/mc'
make[1]: *** [Makefile:39: build] Error 2
make[1]: Leaving directory '/nix/store/5zy5w8jjm8vzaqjhhqpn9z7mpncmk01m-manticore-2017.08.22/repo_checkout/src'
make: *** [Makefile:58: build] Error 2
builder for '/nix/store/g21hjshf6pha15fdqmg6k34id718gijn-manticore-2017.08.22.drv' failed with exit code 2
error: build of '/nix/store/g21hjshf6pha15fdqmg6k34id718gijn-manticore-2017.08.22.drv' failed

The same build succeeds with SML/NJ v110.79. (Working build log) -

[compiling driver/(x86_64-linux.cm):../codegen/(sources.cm):(wrapper.cm):(group.cm):amd64/amd64-gen-fn.sml]
codegen/amd64/amd64-gen-fn.sml:102.23-104.30 Warning: match nonexhaustive
          32 => ...
          64 => ...
  
codegen/amd64/amd64-gen-fn.sml:87.17-89.24 Warning: match nonexhaustive
          32 => ...
          64 => ...

Any help on why this is failing would be greatly appreciated!

String literals in assembly file

➤ ../bin/pmlc -sequential -mlrisc literal.pml 
literal.s:2131:9: error: invalid escape sequence (unrecognized character) in '.asciz' directive
        .asciz  "mlrisc\'s string literal bug"
                ^
error compiling generated assembly code

from the following program

val _ = print "mlrisc's string literal bug"

On Ubuntu 18.04, likely using clang to compile.

Odd issue in alt-ret-tuple

See the comment in alt-ret-tuple.pml from the regression suite for details. I'm not sure what's going on actually. Referenced in commit 9ad955a

Bad 8-bit registers

Opening issue related to this bug, since the workaround below was removed from trunk:

    (* MLRISC is incorrectly naming some of the 8-bit registers, so as a simple
     * workaround, we are just going to find/replace them in the output text file
     *)
    fun replace8BitRegisters asmFile = let
	  val cmd = "sed -i \"s/%ah/%spl/g; s/%ch/%bpl/g; s/%dh/%sil/g; s/%bh/%dil/g\" " ^ asmFile
	  in
	    ignore (OS.Process.system cmd)
	  end

Large list literals (nucleic)

From the nucleic benchmark's TODO, there seems to be an issue with allocating a large list in the heap from a literal. I believe this is a problem regardless of what backend is used.

I think this program hits a segfault because it tries to allocate too much in
the local heap (aka, a lot of allocation within one function). In particular,
take a look at how huge the list literals are in this program.

In addition, it seems compiling this program can cause LLC to hang for a
very long time (over 2 minutes).

I see two solutions:

(1) Try adding a test to see how much allocation is checked for by
    add-alloc-checks in CFG. If the value is too high, maybe we should split
    the block or insert an additional heap test.

(2) [preferred] move the data stored in the list constant into a file, and
    read it in line-by-line to build the list up.

See the TODO file in: https://github.com/ManticoreProject/benchmark/tree/master/benchmarks/programs/seq-nucleic

Wrapping captures in the context of an unused return cont

Before wrap-captures we have

fun contFib_uncurried<C6EA>#4.4 (unboxP<C6F5>#9:int,param<C6F6>#4.4:cont(any) / retK<C6F7>#0:cont(int),_exh<C6F8>#4:cont(any)) =
(* ... *)
  cont currentContinuation<C717>#1 (ccArg<C718>#1:any) =
      let c<C712>#1:[int] = ([int])ccArg<C718>#1
      let _t<C713>#1:int = #0(c<C70B>#1)
      let _t<C714>#1:int = #0(c<C712>#1)
      let _t<C715>#1:int = I32Add(_t<C713>#1,_t<C714>#1)
      let res<C716>#1:[int] = alloc (_t<C715>#1)
      throw param<C6F6>#4.4 res<C716>#1
  (**** End currentContinuation<C717>#1 ****)
  apply contFib_uncurried<C6EA>#4.4 (_t<C70D>#1,currentContinuation<C717>#1 / letJoinK<C85D>#1,_exh<C6F8>#4)

Note that contFib_uncurried does not return. We're currently generating the following wrapping

fun manipK2<C93C>#1 (currentContinuation<C939>#1:cont(any) / landingPadK<C93A>#1.1:cont(int,any),deadExnK<C93B>#0:cont(any)) =
    cont invokeRetk<C93D>#0 (param<C93E>#1:any) =
        let t<C93F>#1:int = 1:int
        throw landingPadK<C93A>#1.1 (t<C93F>#1,param<C93E>#1)
    (* ... *)
    
cont setjmpLandingPad<C933>#1 (regularRet<C934>#1:int,arg<C935>#2:any) =
    let t<C938>#1:int = 0:int
    if I32NEq(regularRet<C934>#1,t<C938>#1) then
      let arg<C936>#1:int = (int)arg<C935>#2  (* invalid cast! *)
      throw retK<C6F7>#2.2 arg<C936>#1        (* this return never will happen *)
    else
      let arg<C937>#1:any = (any)arg<C935>#2
      throw currentContinuation<C717>#1.1 arg<C937>#1

callec (manipK2<C93C>#1 / setjmpLandingPad<C933>#1,deadExh<C941>#1)

Previously this was just a bit inefficient, but it's also incorrect since
an we don't know how to match up the types even if a return did occur (the
unboxing of the int).

It's better to just omit the landing pad in this case and just generate:

callec (manipK2<C93C>#1 / currentContinuation<C717>#1,deadExh<C941>#1)

so that C717 turns into a return cont, instead of a join cont.

Accessing to a nested array causes segmentation fault

When I write a parallel sorting program, I found that the following code causes segmentation fault both on my mac and linux.

fun copy a b e d j =
    if e < b then ()
    else let val v = Array.sub (Array.sub (a, 0), b)
         in Array.update (Array.sub (d, 0), j, v);
            copy a (b+1) e d (j+1)
         end

fun sort a b e =
    if e <= b then () else
    let val q = Int.quot (b + e, 2)
    in sort a b q;
       sort a (q+1) e;
       copy a b e a b
    end

val a = Array.array (1, Array.array (1024, 0))
val _ = sort a 0 1023

I checked out the repository and compiled the compiler as follows:

git clone https://github.com/ManticoreProject/manticore.git
git checkout 757fbcc4d   # to make clear which revision I used
autoconf -Iconfig
autoheader -Iconfig
./configure --prefix=$PWD/dest
mkdir -p dest/bin dest/lib
make install

I saved the above code in bug.pml and executed it as follows:

$ dest/bin/pmlc -o bug bug.pml
$ ./bug
Segmentation fault

Uncurrying mutually recursive funs

The new seq-deriv benchmark program crashes Manticore with:

➤ ../../../../../bin/pmlc -sequential mc-seq.mlb 
../../smlnj-lib/Util/hash-table-fn.sml:85.31-85.40: Fail: UncurriedFns

This failure is raised from the uncurrying pass in BOM. Here's the program:

(* adapted from the Larceny benchmark

;;; DERIV -- Symbolic derivation.

;;; Returns the wrong answer for quotients.
;;; Fortunately these aren't used in the benchmark.
*)


datatype expr
  = Add of expr list
  | Sub of expr list
  | Mul of expr list
  | Div of expr list
  | Num of int
  | X

structure Benchmark = struct

val hd = List.hd
val tl = List.tl
val map = List.map
val app = List.app
val foldl = List.foldl

fun prnt p = (case p
  of X => print "x"
   | Num a => print (Int.toString a)
   | Add xs => prntLst "+" xs
   | Sub xs => prntLst "-" xs
   | Mul xs => prntLst "*" xs
   | Div xs => prntLst "/" xs
  (* end case *))
and prntLst symb xs = (print "("; print symb;
                       app prnt xs; print ")\n")

fun equal p = (case p
  of (X, X) => true
   | (Num a, Num b) => a = b
   | (Add xs, Add ys) => chkLists (xs, ys)
   | (Sub xs, Sub ys) => chkLists (xs, ys)
   | (Mul xs, Mul ys) => chkLists (xs, ys)
   | (Div xs, Div ys) => chkLists (xs, ys)
   | _ => false
  (* end case *))
and chkLists p = ListPair.foldlEq chk true p
and chk (a, b, acc) = acc andalso equal (a, b)

fun deriv a = (case a
  of X => Num 1
   | Num _ => Num 0
   | Add es => Add (map deriv es)
   | Sub es  => Sub (map deriv es)
   | Mul es  => Mul [
            a,
            Add (map (fn x => Div [deriv x, x]) es)
            ]

   | Div (x :: y :: nil) => Sub [
        Div [deriv x, y],
        Div [x, Mul [y, y, deriv y]]
      ]
   | _ => raise Fail "No derivation method available"
  (* end case *))


fun go (ans, exp) = let
  val computed = deriv exp
  in
    if equal (ans, computed)
    then ()
    else (prnt computed ; raise Fail "wrong answer!")
  end

end


structure Main =
  struct

  	val iterations = 2000000

    fun main _ = let

      fun mkExp a b =
        Add [
          Mul [Num 3, X, X],
          Mul [a, X, X],
          Mul [b, X],
          Num 5
        ]

      fun mkAns a b =
        Add [
          Mul [
            Mul [Num 3, X, X],
            Add [
              Div [Num 0, Num 3],
              Div [Num 1, X],
              Div [Num 1, X]
            ]
          ],
          Mul [
            Mul [a, X, X],
            Add [
              Div [Num 0, a],
              Div [Num 1, X],
              Div [Num 1, X]
            ]
          ],
          Mul [
            Mul [b, X],
            Add [
              Div [Num 0, b],
              Div [Num 1, X]
            ]
          ],
          Num 0
        ]

      val a = Num 5
      val b = Num 7
      val exp = mkExp a b
      val ans = mkAns a b

      fun doit () = Benchmark.go (ans, exp)

      fun lp 0 = ()
      	| lp n = (doit(); lp (n-1))

      fun start () = lp iterations

  	in
      	start ()
  	end

end

val _ = Main.main (CommandLine.name (), CommandLine.arguments ())

See the file here: https://smlnj-gitlab.cs.uchicago.edu/manticore/benchmarks/blob/704571634ff114d06cff9f7d87256eab627536a2/benchmarks/programs/seq-deriv/prog.pml

Stack slot alignment

it seems that the alignment of stack slots setup by the prologue does not match the LLVM code generator's expectations. From the ffi-fib benchmark on all stack-based variants:

Thread 2 "a.out" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffff63ff700 (LWP 28269)]
go_cfg3CDE_49A0 () at mc-seq.s:732
732		movapd	%xmm1, 40(%rsp)         # 16-byte Spill

Case simplify produces invalid BOM

Seems there's a bug in case simplify? I'm using d5dfda2

➤ ../trunk-pmlc/bin/pmlc -Cbom.check-all=true fib-datatype.pml 
***** Bogus BOM in Main after case-simplify *****
** invalid cast:(_t<D762>#2:int) = (int)left<F8FC>#5:any
** invalid cast:(_t<D773>#1:int) = (int)right<F8FD>#7:any
** type mismatch in return from fib<F8FA>#3.3
==   expected  any
==   but found int
** type mismatch in return from fib<F8FA>#3.3
==   expected  any
==   but found int
** invalid cast:(_t<D751>#1:int) = (int)right<F8FD>#7:any
** type mismatch in return from fib<F8FA>#3.3
==   expected  any
==   but found int
** type mismatch in return from fib<F8FA>#3.3
==   expected  any
==   but found int
** invalid cast:(_t<D78A>#1:int) = (int)ans<F90E>#3:any
broken BOM dumped to broken-BOM
bom/check-bom.sml:544.11-544.28: Fail: broken BOM

See fib-datatype.pml below:

datatype fib_result
  = Zero
  | One
  | Val of int

fun add a b = (case (a, b)
  of (Zero, b) => b
   | (a, Zero) => a
   | (One, One) => Val 2
   | (One, Val b) => Val (b+1)
   | (Val a, One) => Val (a+1)
   | (Val a, Val b) => Val (a+b)
  (* end case *))

fun show a = (case a
  of Zero => "0"
   | One => "1"
   | Val a => Int.toString a
  (* end case *))

fun fib n = (case n
  of 0 => Zero
   | 1 => One
   | _ => let
        val left = fib (n-1)
        val right = fib (n-2)
      in
        add left right
      end
  (* end case *))

val i2s = Int.toString

val n = 30  (* https://oeis.org/A000045/list *)
val ans = fib n

val _ = print ("fib(" ^ i2s n ^ ") = " ^ show ans ^ "\n")

Compilation failure on SMLNJ 110.95

smlnj 110.95 (probably 110.94 too, as it switched the type of source-file positions from Position.int to Int.int) can't build the latest revision of manticore:

[compiling driver/(x86_64-linux.cm):../codegen/(sources.cm):(wrapper.cm):(group.cm):../common/(sources.cm):error.sml]
common/error.sml:137.39-137.59 Error: operator and operand do not agree [tycon mismatch]
  operator domain: (Int64.int * Int64.int) option *
                   (Int64.int * Int64.int) option
  operand:         span option * span option
  in expression:
    lt ((fn <pat> => <exp>) e1,(fn <pat> => <exp>) e2)
Compilation failed.

It works with the following change:

diff --git a/src/tools/mc/common/error.sml b/src/tools/mc/common/error.sml
index e880c5f18..370ce05eb 100644
--- a/src/tools/mc/common/error.sml
+++ b/src/tools/mc/common/error.sml
@@ -129,9 +129,9 @@ structure Error :> sig
 	  fun lt (NONE, NONE) = false
 	    | lt (NONE, _) = true
 	    | lt (_, NONE) = false
-	    | lt (SOME(l1, r1), SOME(l2, r2)) = (case Position.compare(l1, l2)
+	    | lt (SOME(l1, r1), SOME(l2, r2)) = (case Int.compare(l1, l2)
 		 of LESS => true
-		  | EQUAL => (Position.compare(r1, r2) = LESS)
+		  | EQUAL => (Int.compare(r1, r2) = LESS)
 		  | GREATER => false
 		(* end case *))
 	  fun cmp (e1 : error, e2 : error) = lt(#pos e1, #pos e2)

I'm not sure if it's the right approach as it would break compilation with smlnj versions before 110.94 (and I didn't see any pragmas/etc for backwards-compatibility of this sort; though I'm really new to SML and might've missed it).
What's your usual approach to this?

CPS inliner issue with recursive function being mapped

Greetings from Sweden and Chalmers University of Technology!

I may have found something when exploring parallel arrays in Manticore. Here is a piece of code that works perfectly fine:

fun f n = if n <= 0 then 0 else 1 + f (n - 1)
val xs = [ 1, 2, 3 ]
val _ = map f xs

Here is a similar program with a parallel array and PArray.map instead of a list and the regular map:

(* f same as before *)
val xs = PArray.fromRope (Rope.tabulateSequential (fn x => x) (1, 3))
val _ = PArray.map (fn x => f x) xs

That code also works. But watch what happens when I eta-reduce the mapped function:

val _ = PArray.map f xs

The code doesn't compile anymore:

$ pmlc eta.pml
***** Bogus CPS in Main after inline *****
** unbound variable f<11431>#4.4
** unbound variable f<11431>#4.4 in Apply
** unbound variable f<11431>#4.4
** unbound variable f<11431>#4.4 in Apply
broken CPS dumped to broken-CPS

The dumped file is 1.7 MB, but I can't really extract any useful information from it.

It also turns out that everything works fine if f is not recursive:

fun f n = if n <= 0 then 0 else 1
val xs = PArray.fromRope (Rope.tabulateSequential (fn x => x) (1, 3))
val _ = PArray.map f xs

I'm not an expert, but there seems to be something going on here. What do you think?

Runaway Memory Usage

The following benchmark program (seq-mazefun) executes pretty quickly in MLton, but after compiling with Manticore it has runaway memory usage. Of course this causes GC thrashing so the program doesn't seem to terminate before hitting the swapfile.

There must be some bug causing some data to stay live according to the GC longer than it should.

(* from the Larceny benchmark suite

;;; MAZEFUN -- Constructs a maze in a purely functional way,
;;; written by Marc Feeley.
;;; ported to SML by Kavon Farvardin

*)

datatype maze_elm
  = Pt of int * int
  | Empty

structure Benchmark = struct

  val hd = List.hd
  val tl = List.tl
  val concat = List.concat
  val length = List.length
  val null = List.null
  val foldr = List.foldr

  fun tup1 (x, _) = x
  fun tup2 (_, x) = x

  (* operations on maze elms *)
  fun fst e = (case e
    of Pt (x, _) => x
     | _ => raise Fail "not a point"
     (* end case *))

  fun snd e = (case e
    of Pt (_, x) => x
     | _ => raise Fail "not a point"
     (* end case *))

  fun mazeElmEqual p = (case p
    of (Pt (x, y), Pt (a, b)) => x = a andalso y = b
     | (Empty, Empty) => true
     | _ => false
     (* end case *))

  fun mazeElmToString p = (case p
    of Pt _ => " _"
     | Empty => " *"
    (* end case *))

  fun printStringMat mat =
    app (fn lst => (app print lst; print "\n")) mat
(***********)

  (* the args to f are flipped,
     i.e. acc is on the left in Scheme *)
  fun foldl f id xs = let
    fun lp (xs, acc) = (case xs
      of nil => acc
       | x :: xs => lp(xs, f (acc, x))
      (* end case *))
    in
      lp (xs, id)
    end

  fun for lo hi f = let
      fun lp lo =
        if lo < hi
          then f lo :: lp (lo + 1)
          else nil
    in
      lp lo
    end

  fun listRead lst i =
    if i = 0
      then hd lst
      else listRead (tl lst) (i-1)

  fun listWrite lst i new =
    if i = 0
      then new :: tl lst
      else hd lst :: listWrite (tl lst) (i-1) new

  fun listRemovePos lst i =
    if i = 0
      then tl lst
      else hd lst :: listRemovePos (tl lst) (i-1)

  fun member x = List.exists (fn y => mazeElmEqual (x, y))

  fun hasDuplicates lst = (case lst
    of nil => false
     | x :: xs => member x xs orelse hasDuplicates xs
    (* end case *))

  fun makeMatrix n m init =
    for 0 n (fn i =>
      for 0 m (fn j =>
        init i j
      )
    )

  fun matrixRead mat i j = listRead (listRead mat i) j

  fun matrixWrite mat i j new =
    listWrite mat i (listWrite (listRead mat i) j new)

  fun matrixSize mat = (length mat, length (hd mat))

  fun matrixMap f mat = map (fn lst => map f lst) mat

  fun nextRandom cur =
    ((cur * 3581) + 12751) mod 131072

  fun shuffle lst = let
    fun shuf lst rand =
      if null lst
        then nil
        else let
          val newRand = nextRandom rand
          val i = newRand mod (length lst)
        in
          listRead lst i
            :: shuf (listRemovePos lst i) newRand
        end
  in
    shuf lst 0 (* <- the seed *)
  end

  fun odd n = n mod 2 = 1
  fun even n = n mod 2 = 0

  fun caveToMaze cave = matrixMap mazeElmToString cave

  fun pierce pos cave = matrixWrite cave (fst pos) (snd pos) pos

  fun neighboringCavities pos cave = let
      val size = matrixSize cave
      val n = tup1 size
      val m = tup2 size
      val i = fst pos
      val j = snd pos

      fun notEmpty (i, j) = (case matrixRead cave i j
        of Empty => false
         | _ => true
         (* end case *))
    in
      concat [
        if i > 0 andalso notEmpty (i-1, j)
          then [Pt (i-1, j)]
          else nil,
        if i < n-1 andalso notEmpty (i+1, j)
          then [Pt (i+1, j)]
          else nil,
        if j > 0 andalso notEmpty (i, j-1)
          then [Pt (i, j-1)]
          else nil,
        if j < m-1 andalso notEmpty (i, j+1)
          then [Pt (i, j+1)]
          else nil
      ]
    end

  and changeCavity cave pos newID = let
      fun change cave pos newID oldID = let
        val i = fst pos
        val j = snd pos
        val cavityID = matrixRead cave i j
      in
        if mazeElmEqual (cavityID, oldID)
          then foldl (fn (c, nc) =>
                        change c nc newID oldID)
                     (matrixWrite cave i j newID)
                     (neighboringCavities pos cave)
          else cave
      end
    in
      change cave pos newID (matrixRead cave (fst pos) (snd pos))
    end

  and tryToPierce pos cave = let
    val ncs = neighboringCavities pos cave
  in
    if hasDuplicates
        (map (fn nc => matrixRead cave (fst nc) (snd nc)) ncs)
      then cave
      else pierce
              pos
              (foldl (fn (c, nc) => changeCavity c nc pos)
                     cave
                     ncs)
  end

  and pierceRandomly possibleHoles cave = (case possibleHoles
    of nil => cave
     | hole :: rest => pierceRandomly rest (tryToPierce hole cave)
    (* end case *))

  fun makeMaze n m = if not (odd n andalso odd m)
    then raise Fail "n and m must be odd"
    else let
      fun init i j = if even i andalso even j
                      then Pt (i, j)
                      else Empty

      val cave = makeMatrix n m init

      val possibleHoles = concat (
            for 0 n (fn i => concat (
              for 0 m (fn j =>
                if even i andalso even j
                  then nil
                  else [Pt (i, j)]
              ))
            ))

    in
      caveToMaze (pierceRandomly (shuffle possibleHoles) cave)
    end


  fun go (n, m) =
    printStringMat (makeMaze n m)

end


structure Main =
  struct

    val iterations = 1

    val n = 11
    val m = 11

    fun main _ = let

      fun doit () = Benchmark.go (n, m)

      fun lp 0 = ()
      	| lp n = (doit(); lp (n-1))

      fun start () = lp iterations

  	in
      	start ()
  	end

end

val _ = Main.main (CommandLine.name (), CommandLine.arguments ())

Linked Frame GC Race

Caught this in the benchmarks directory's parallel cml-merge when the message size was set very high.

==================
WARNING: ThreadSanitizer: data race (pid=3448)
  Read of size 8 at 0x7f78c4652ea8 by thread T5:
    #0 majorGCscanLINKFRAMEpointer ../../gc/major-gc-scan.c:66 (a.out+0x20437)
    #1 ScanMajorToSpace ../../gc/major-gc.c:503 (a.out+0x1e3a4)
    #2 PromoteObj ../../gc/major-gc.c:420 (a.out+0x1e000)
    #3 <null> <null> (a.out+0x4ab15)
    #4 IdleVProc ../../vproc/vproc.c:673 (a.out+0x3f950)
    #5 NewVProc ../../vproc/vproc.c:394 (a.out+0x3ecd5)
    #6 InitWithLocation ../../cpu/topology.c:106 (a.out+0x4a3f3)
    #7 <null> <null> (libtsan.so.0+0x296ad)

  Previous write of size 8 at 0x7f78c4652ea8 by thread T3:
    #0 ForwardObjMajor ../../gc/major-gc.c:52 (a.out+0x1cd17)
    #1 majorGCscanBITPATpointer ../../gc/major-gc-scan.c:148 (a.out+0x207b0)
    #2 ScanMajorToSpace ../../gc/major-gc.c:503 (a.out+0x1e3a4)
    #3 MajorGC ../../gc/major-gc.c:322 (a.out+0x1d8ad)
    #4 MinorGC ../../gc/minor-gc.c:527 (a.out+0x18822)
    #5 RunManticore ../../vproc/apply.c:115 (a.out+0x43d29)
    #6 IdleVProc ../../vproc/vproc.c:673 (a.out+0x3f950)
    #7 NewVProc ../../vproc/vproc.c:394 (a.out+0x3ecd5)
    #8 InitWithLocation ../../cpu/topology.c:106 (a.out+0x4a3f3)
    #9 <null> <null> (libtsan.so.0+0x296ad)

  Thread T5 (tid=3469, running) created by main thread at:
    #0 pthread_create <null> (libtsan.so.0+0x2bcee)
    #1 ThreadCreate ../../include/os-threads.h:30 (a.out+0x49918)
    #2 SpawnAt ../../cpu/topology.c:118 (a.out+0x4a49b)
    #3 VProcInit ../../vproc/vproc.c:218 (a.out+0x3df67)
    #4 main ../../misc/main.c:121 (a.out+0x414c5)

  Thread T3 (tid=3465, running) created by main thread at:
    #0 pthread_create <null> (libtsan.so.0+0x2bcee)
    #1 ThreadCreate ../../include/os-threads.h:30 (a.out+0x49918)
    #2 SpawnAt ../../cpu/topology.c:118 (a.out+0x4a49b)
    #3 VProcInit ../../vproc/vproc.c:218 (a.out+0x3df67)
    #4 main ../../misc/main.c:121 (a.out+0x414c5)

Eta-reduce pass

There's a CPS eta-reduce pass already written in the partial_abort_stm branch, which is run just before eta-expand.

It might be worth the effort to pull this optimization over to trunk, though I'm not sure what motivated @lematt1991 to implement this, i.e., is it meant to improve general programs, or clean-up some STM-specific transform?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.