aboutsummaryrefslogtreecommitdiff
path: root/elymas
diff options
context:
space:
mode:
authorDrahflow <drahflow@gmx.de>2015-06-18 13:54:48 +0200
committerDrahflow <drahflow@gmx.de>2015-06-18 13:54:48 +0200
commit380911d0b8e8a92df6205d4ee180caa95eb2acb8 (patch)
treedc1dcb97d33e3a3b49569955b2a174a476a16740 /elymas
parentbb395ab8e0cdacb6b381f576ff4cae431290da19 (diff)
Optimize rep on inline-created functions
... also finally make label resolution recursive
Diffstat (limited to 'elymas')
-rw-r--r--elymas/lib/sys/opt.ey141
-rw-r--r--elymas/lib/sys/so.ey2
2 files changed, 140 insertions, 3 deletions
diff --git a/elymas/lib/sys/opt.ey b/elymas/lib/sys/opt.ey
index 2ad40b8..de88359 100644
--- a/elymas/lib/sys/opt.ey
+++ b/elymas/lib/sys/opt.ey
@@ -20,7 +20,7 @@
sysasmops -01 .
} ? *
} ":" defq
- { [ } "[[" deff
+ { :labelRecord [ } "[[" deff
{ ] :labelResolve } "]]" deff
sysasmops .|label "@" deff
@@ -142,12 +142,20 @@
[
8 /r15 :subqImm8Reg
/r15 :popqMem
+ 0 /rdi :movqImmReg
+ %48 16 /rdi :cmpbImmMemDisp8
+ ] ==:customFunctionObjectCreationHeaderPattern
+
+ [
+ 8 /r15 :subqImm8Reg
+ /r15 :popqMem
] ==:customFunctionHeaderPattern
/NOP ==:NOP
/PUSH ==:PUSH
/CALL ==:CALL
/CALLSCOPED ==:CALLSCOPED
+ /FUNCTIONCREATE ==:FUNCTIONCREATE
/STATIC ==:STATIC
/STATICTYPED ==:STATICTYPED
/STATICWRITE ==:STATICWRITE
@@ -160,6 +168,8 @@
/STRINGSTAR ==:STRINGSTAR
/CONDITIONALTAIL ==:CONDITIONALTAIL
/ARRAYCLEAR ==:ARRAYCLEAR
+ /RAWCONSTREP ==:RAWCONSTREP
+ /RAWCONSTREPTHISSCOPE ==:RAWCONSTREPTHISSCOPE
{ =*f ==t
t { f } { 0 } ? *
@@ -1620,7 +1630,8 @@
# handle untyped function
executedObject sys .capturedScope {
-- # ignore concrete scope
- [ UNTYPEDSCOPEDSTAR ] i logic =[]
+ [ UNTYPEDSCOPEDSTAR ] i logic =[] # TODO: scope will stay constant, optimize further
+ /UNTYPEDSCOPEDSTAR_suboptimal dump
} {
[ NOP ] i 1 sub logic =[]
[ CALL executedObject ::rawCodeAddress ] i logic =[]
@@ -1649,6 +1660,65 @@
1 logic len range { ==i i logic * ==entry 0 entry * ==action i 1 sub logic * ==last
[
{ 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 =[]
+ /RAWCONSTREP_optimized dump
+ } ? *
+ } ? *
+ }
+ { "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 * "rep" | ::rawCodeAddress eq }' andif
+ { 0 last * FUNCTIONCREATE eq }' andif
+ }' {
+ 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 =[]
+ [ RAWCONSTREPTHISSCOPE functionBody 16 add ] i logic =[]
+ /RAWCONSTREP_on_FUNCTIONCREATE dump
+ }
+ ] conds
+ } each
+ } /rewriteTrivialRep 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
}' {
@@ -1939,6 +2009,12 @@
[ PUSH pushedConstant ] emitLogic
}
+ { customFunctionObjectCreationHeaderPattern callTargetMatch }' {
+ [ calledAddress 9 add _ 8 add range peek each ] 256 math .unbase ==functionBody # function code object address
+
+ [ FUNCTIONCREATE calledAddress functionBody ] emitLogic
+ }
+
{ customFunctionHeaderPattern callTargetMatch }' {
[ CALL calledAddress ] emitLogic
}
@@ -1984,6 +2060,7 @@
} rep
rewriteConstantDot
rewriteTrivialStar
+ rewriteTrivialRep
rewriteConstantStar
rewriteConstantQuestionStar
rewriteArrayClear
@@ -2089,6 +2166,15 @@
1 entry 16 sub emitReference
}
+ { action FUNCTIONCREATE eq }' {
+ [
+ 1 entry /rax :movqImmReg
+ /rax :callqReg
+ ] emitOpcodes
+
+ 1 entry 16 sub emitReference
+ }
+
{ action CALLSCOPED eq }' {
[
8 /r15 :subqImm8Reg
@@ -2271,6 +2357,57 @@
]] emitOpcodes
}
+ { action RAWCONSTREP eq }' {
+ [[
+ 8 /r15 :subqImm8Reg
+ /rax :popqReg
+ 63 /rax :btrqImm8Reg
+ /unboxedInt :jcLbl8
+ 8 /rax /rax :movqMemDisp8Reg
+ @unboxedInt
+ /rax /r15 :movqRegMem
+
+ @repLoop
+ 0 /r15 :cmpqImm8Mem
+ /repFinished :jzLbl8
+ 1 /r15 :subqImm8Mem
+ 1 entry /rax :movqImmReg
+ /rax :callqReg
+ /repLoop :jmpLbl8
+ @repFinished
+ 8 /r15 :addqImm8Reg
+ ]] emitOpcodes
+
+ 1 entry 16 sub emitReference
+ }
+
+ { action RAWCONSTREPTHISSCOPE eq }' {
+ [[
+ 16 /r15 :subqImm8Reg
+ /r14 8 /r15 :movqRegMemDisp8
+ /rax :popqReg
+ 63 /rax :btrqImm8Reg
+ /unboxedInt :jcLbl8
+ 8 /rax /rax :movqMemDisp8Reg
+ @unboxedInt
+ /rax /r15 :movqRegMem
+
+ @repLoop
+ 0 /r15 :cmpqImm8Mem
+ /repFinished :jzLbl8
+ 8 /r15 /r14 :movqMemDisp8Reg
+ 1 /r15 :subqImm8Mem
+ 1 entry /rax :movqImmReg
+ /rax :callqReg
+ /repLoop :jmpLbl8
+ @repFinished
+ 8 /r15 /r14 :movqMemDisp8Reg
+ 16 /r15 :addqImm8Reg
+ ]] emitOpcodes
+
+ 1 entry 16 sub emitReference
+ }
+
{ 1 }' {
|entry dump
"invalid intermediate code during optimize" die
diff --git a/elymas/lib/sys/so.ey b/elymas/lib/sys/so.ey
index 0203f18..521da85 100644
--- a/elymas/lib/sys/so.ey
+++ b/elymas/lib/sys/so.ey
@@ -10,7 +10,7 @@
sys .asm .|peek =*:peek
sys .asm .|poke =*:poke
- { [ } "[[" deff
+ { :labelRecord [ } "[[" deff
{ ] :labelResolve } "]]" deff
# hex decoding