aboutsummaryrefslogtreecommitdiff
path: root/elymas
diff options
context:
space:
mode:
authorDrahflow <drahflow@gmx.de>2015-06-18 17:42:48 +0200
committerDrahflow <drahflow@gmx.de>2015-06-18 17:42:48 +0200
commitc76fc8ff9059e935af0dcef07846818980413159 (patch)
treeeb70393762b3477b526337544383838595011e9a /elymas
parent9d4b5bb1115bc0f51954a2d236acb00ce95c88d5 (diff)
Optimize { ... } each
Diffstat (limited to 'elymas')
-rw-r--r--elymas/lib/sys/opt.ey148
1 files changed, 148 insertions, 0 deletions
diff --git a/elymas/lib/sys/opt.ey b/elymas/lib/sys/opt.ey
index e1ae466..ca3f37a 100644
--- a/elymas/lib/sys/opt.ey
+++ b/elymas/lib/sys/opt.ey
@@ -170,6 +170,7 @@
/ARRAYCLEAR ==:ARRAYCLEAR
/RAWCONSTREP ==:RAWCONSTREP
/RAWCONSTREPTHISSCOPE ==:RAWCONSTREPTHISSCOPE
+ /RAWCONSTEACHTHISSCOPE ==:RAWCONSTEACHTHISSCOPE
/INLINEQUESTIONSTARTHISSCOPE ==:INLINEQUESTIONSTARTHISSCOPE
/INLINEQUESTIONSTARUNSCOPEDCONST ==:INLINEQUESTIONSTARUNSCOPEDCONST
@@ -1750,6 +1751,64 @@
{ _ ==logic
1 logic len range { ==i i logic * ==entry 0 entry * ==action i 1 sub logic * ==last
[
+#FIXME handle constant cases, too
+# { action CALL eq
+# { 1 entry * "rep" | ::rawCodeAddress eq }' andif
+# { 0 last * PUSH eq }' andif
+# }' {
+# 1 last * ::rawObject ==executedObject
+# executedObject sys .typed .type ==type
+#
+# type [
+# { last dump "failed to optimize 'execution' of integer typed object" die }
+# { } # TODO let's not optimize repeated string executions for now
+# { "failed to optimize 'execution' of float typed object" die }
+# { "objects of type 3 should not appear" die }
+# { "failed to optimize 'execution' of extension area" die }
+# {
+# # TODO think about handling typed functions
+# executedObject sys .typed .inputs len { } {
+# # handle untyped function
+# executedObject sys .capturedScope {
+# -- # ignore concrete scope
+# # [ UNTYPEDSCOPEDREP ] i logic =[]
+# /TODO_UNTYPEDSCOPEDREP_needed dump
+# } {
+# [ NOP ] i 1 sub logic =[]
+# [ RAWCONSTREP executedObject ::rawCodeAddress ] i logic =[]
+# } ? *
+# } ? *
+# }
+# { "failed to optimize 'execution' of raw function opcodes object" die }
+# { } # TODO let's not optimize repeated array executions for now
+# { "failed to optimize 'execution' of function type descriptor" die }
+# { } # TODO optimize scope execution one day
+# { "failed to optimize 'execution' of name table" die }
+# { "objects of type 11 should not appear" die }
+# { } # TODO optimize coroutine execution one day
+# { "objects of type 13 should not appear" die }
+# { "objects of type 14 should not appear" die }
+# { "objects of type 15 should not appear" die }
+# ] * *
+# }
+#
+ { action CALL eq
+ { 1 entry * "each" | ::rawCodeAddress eq }' andif
+ { 0 last * FUNCTIONCREATE eq }' andif
+ }' { # FIXME consider detecting the containter type iterated over and specialize
+ 2 last * ==functionBody
+
+ # the captured scope of the function is the same one rep is called in, no need to change scope
+ [ NOP ] i 1 sub logic =[]
+ [ RAWCONSTEACHTHISSCOPE functionBody 16 add 1 last * ] i logic =[]
+ }
+ ] conds
+ } each
+ } /rewriteTrivialEach deffst
+
+ { _ ==logic
+ 1 logic len range { ==i i logic * ==entry 0 entry * ==action i 1 sub logic * ==last
+ [
{ action CALL eq
{ 1 entry * "*" | ::rawCodeAddress eq }' andif
{ 0 last * STATICTYPED eq }' andif
@@ -2115,6 +2174,7 @@
rewriteConstantDot
rewriteTrivialStar
rewriteTrivialRep
+ rewriteTrivialEach
rewriteConstantStar
rewriteInlineQuestionStar
rewriteConstantQuestionStar
@@ -2462,6 +2522,94 @@
1 entry 16 sub emitReference
}
+ { action RAWCONSTEACHTHISSCOPE eq }' {
+ [[
+ 32 /r15 :subqImm8Reg
+
+ /rax :popqReg
+
+ 7 /rax /cl :movbMemDisp8Reg
+ %F0 /cl :andbImmReg
+ %70 /cl :cmpbImmReg
+ /eachArray :jzLbl8
+ %10 /cl :cmpbImmReg
+ /eachString :jzLbl8
+
+ # revert to original code for complicated (e.g. scope) cases
+ /rax :pushqReg
+ 2 entry /rax :movqImmReg
+ /rax :callqReg
+ |each ::rawCodeAddress /rax :movqImmReg
+ /rax :callqReg
+ /end :jmpLbl32
+
+ @eachArray
+ /rax 24 /r15 :movqRegMemDisp8
+
+ 8 /rax /rcx :leaqMemDisp8Reg
+ /rcx /r15 :movqRegMem
+
+ /rax /edx :movlMemReg
+ 1 /rdx /rax /rcx :leaqMemIndexScaleReg
+ /rcx 8 /r15 :movqRegMemDisp8
+
+ # /r15 -> current array element
+ # 8 /r15 -> address after last array element
+ # 16 /r15 -> current scope
+ # 24 /r15 -> array object (to keep the GC away)
+
+ /r14 16 /r15 :movqRegMemDisp8
+ @loop
+ 16 /r15 /r14 :movqMemDisp8Reg
+ /r15 /rax :movqMemReg
+ 8 /r15 /rax :cmpqMemDisp8Reg
+ /end :jnbLbl8
+
+ /rax :pushqMem # push array element
+ 1 entry /rax :movqImmReg
+ /rax :callqReg
+
+ 8 /r15 :addqImm8Mem
+ /loop :jmpLbl8
+
+ @eachString
+ /rax 24 /r15 :movqRegMemDisp8
+
+ 16 /rax /rcx :movqMemDisp8Reg
+ /rcx /rcx :testqRegReg
+ /end :jzLbl8
+ /rcx 8 /r15 :movqRegMemDisp8
+ 24 /rax /rcx :leaqMemDisp8Reg
+ /rcx /r15 :movqRegMem
+
+ # /r15 -> current string element
+ # 8 /r15 -> count remaining
+ # 16 /r15 -> current scope
+ # 24 /r15 -> string object (to keep the GC away)
+
+ /r14 16 /r15 :movqRegMemDisp8
+ @stringLoop
+ /r15 /rdx :movqMemReg
+ /rdx /rdx :movzxMem8Reg64
+ 63 /rdx :btsqImm8Reg
+ /rdx :pushqReg
+ 1 entry /rax :movqImmReg
+ /rax :callqReg
+
+ 16 /r15 /r14 :movqMemDisp8Reg
+ 1 /r15 :addqImm8Mem
+ 1 8 /r15 :subqImm8MemDisp8
+ /stringLoop :jnzLbl8
+
+ @end
+
+ 32 /r15 :addqImm8Reg
+ ]] emitOpcodes
+
+ 1 entry 16 sub emitReference
+ 2 entry 16 sub emitReference
+ }
+
{ action INLINEQUESTIONSTARTHISSCOPE eq }' {
[[
/rax :popqReg