diff options
| author | Drahflow <drahflow@gmx.de> | 2015-06-18 17:42:48 +0200 |
|---|---|---|
| committer | Drahflow <drahflow@gmx.de> | 2015-06-18 17:42:48 +0200 |
| commit | c76fc8ff9059e935af0dcef07846818980413159 (patch) | |
| tree | eb70393762b3477b526337544383838595011e9a | |
| parent | 9d4b5bb1115bc0f51954a2d236acb00ce95c88d5 (diff) | |
Optimize { ... } each
| -rw-r--r-- | elymas/lib/sys/opt.ey | 148 |
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 |
