diff --git a/basis/compiler/cfg/write-barrier/write-barrier-tests.factor b/basis/compiler/cfg/write-barrier/write-barrier-tests.factor new file mode 100644 index 0000000000..7a4b1c488f --- /dev/null +++ b/basis/compiler/cfg/write-barrier/write-barrier-tests.factor @@ -0,0 +1,72 @@ +USING: compiler.cfg.write-barrier compiler.cfg.instructions +compiler.cfg.registers cpu.architecture arrays tools.test ; +IN: compiler.cfg.write-barrier.tests + +[ + { + T{ ##peek f V int-regs 4 D 0 f } + T{ ##copy f V int-regs 6 V int-regs 4 f } + T{ ##allot f V int-regs 7 24 array V int-regs 8 f } + T{ ##load-immediate f V int-regs 9 8 f } + T{ ##set-slot-imm f V int-regs 9 V int-regs 7 1 3 f } + T{ ##set-slot-imm f V int-regs 6 V int-regs 7 2 3 f } + T{ ##replace f V int-regs 7 D 0 f } + } +] [ + { + T{ ##peek f V int-regs 4 D 0 } + T{ ##copy f V int-regs 6 V int-regs 4 } + T{ ##allot f V int-regs 7 24 array V int-regs 8 } + T{ ##load-immediate f V int-regs 9 8 } + T{ ##set-slot-imm f V int-regs 9 V int-regs 7 1 3 } + T{ ##write-barrier f V int-regs 7 V int-regs 10 V int-regs 11 } + T{ ##set-slot-imm f V int-regs 6 V int-regs 7 2 3 } + T{ ##write-barrier f V int-regs 7 V int-regs 12 V int-regs 13 } + T{ ##replace f V int-regs 7 D 0 } + } eliminate-write-barriers +] unit-test + +[ + { + T{ ##load-immediate f V int-regs 4 24 } + T{ ##peek f V int-regs 5 D -1 } + T{ ##peek f V int-regs 6 D -2 } + T{ ##set-slot-imm f V int-regs 5 V int-regs 6 3 2 } + T{ ##write-barrier f V int-regs 6 V int-regs 7 V int-regs 8 } + } +] [ + { + T{ ##load-immediate f V int-regs 4 24 } + T{ ##peek f V int-regs 5 D -1 } + T{ ##peek f V int-regs 6 D -2 } + T{ ##set-slot-imm f V int-regs 5 V int-regs 6 3 2 } + T{ ##write-barrier f V int-regs 6 V int-regs 7 V int-regs 8 } + } eliminate-write-barriers +] unit-test + +[ + { + T{ ##peek f V int-regs 19 D -3 } + T{ ##peek f V int-regs 22 D -2 } + T{ ##copy f V int-regs 23 V int-regs 19 } + T{ ##set-slot-imm f V int-regs 22 V int-regs 23 3 2 } + T{ ##write-barrier f V int-regs 23 V int-regs 24 V int-regs 25 } + T{ ##copy f V int-regs 26 V int-regs 19 } + T{ ##peek f V int-regs 28 D -1 } + T{ ##copy f V int-regs 29 V int-regs 19 } + T{ ##set-slot-imm f V int-regs 28 V int-regs 29 4 2 } + } +] [ + { + T{ ##peek f V int-regs 19 D -3 } + T{ ##peek f V int-regs 22 D -2 } + T{ ##copy f V int-regs 23 V int-regs 19 } + T{ ##set-slot-imm f V int-regs 22 V int-regs 23 3 2 } + T{ ##write-barrier f V int-regs 23 V int-regs 24 V int-regs 25 } + T{ ##copy f V int-regs 26 V int-regs 19 } + T{ ##peek f V int-regs 28 D -1 } + T{ ##copy f V int-regs 29 V int-regs 19 } + T{ ##set-slot-imm f V int-regs 28 V int-regs 29 4 2 } + T{ ##write-barrier f V int-regs 29 V int-regs 30 V int-regs 3 } + } eliminate-write-barriers +] unit-test diff --git a/basis/compiler/cfg/write-barrier/write-barrier.factor b/basis/compiler/cfg/write-barrier/write-barrier.factor new file mode 100644 index 0000000000..f7e81c8b5c --- /dev/null +++ b/basis/compiler/cfg/write-barrier/write-barrier.factor @@ -0,0 +1,43 @@ +! Copyright (C) 2008 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +USING: kernel accessors namespaces assocs sets sequences locals +compiler.cfg compiler.cfg.instructions +compiler.cfg.instructions.syntax compiler.cfg.copy-prop ; +IN: compiler.cfg.write-barrier + +! Eliminate redundant write barrier hits. + +! Objects which have already been marked, as well as +! freshly-allocated objects +SYMBOL: safe + +! Objects which have been mutated +SYMBOL: mutated + +GENERIC: eliminate-write-barrier ( insn -- insn' ) + +M: ##allot eliminate-write-barrier + dup dst>> safe get conjoin ; + +M: ##write-barrier eliminate-write-barrier + dup src>> resolve dup + [ safe get key? not ] + [ mutated get key? ] bi and + [ safe get conjoin ] [ 2drop f ] if ; + +M: ##copy eliminate-write-barrier + dup record-copy ; + +M: ##set-slot eliminate-write-barrier + dup obj>> resolve mutated get conjoin ; + +M: ##set-slot-imm eliminate-write-barrier + dup obj>> resolve mutated get conjoin ; + +M: insn eliminate-write-barrier ; + +: eliminate-write-barriers ( insns -- insns' ) + H{ } clone safe set + H{ } clone mutated set + H{ } clone copies set + [ eliminate-write-barrier ] map sift ;