diff options
| author | Drahflow <drahflow@gmx.de> | 2015-06-18 13:54:48 +0200 |
|---|---|---|
| committer | Drahflow <drahflow@gmx.de> | 2015-06-18 13:54:48 +0200 |
| commit | 380911d0b8e8a92df6205d4ee180caa95eb2acb8 (patch) | |
| tree | dc1dcb97d33e3a3b49569955b2a174a476a16740 | |
| parent | bb395ab8e0cdacb6b381f576ff4cae431290da19 (diff) | |
Optimize rep on inline-created functions
... also finally make label resolution recursive
| -rw-r--r-- | compiler/elymasAsmLib.ey | 2 | ||||
| -rw-r--r-- | compiler/elymasAsmOps.ey | 41 | ||||
| -rw-r--r-- | compiler/elymasGlobal.ey | 2 | ||||
| -rw-r--r-- | elymas/lib/sys/opt.ey | 141 | ||||
| -rw-r--r-- | elymas/lib/sys/so.ey | 2 |
5 files changed, 167 insertions, 21 deletions
diff --git a/compiler/elymasAsmLib.ey b/compiler/elymasAsmLib.ey index 2075c74..da98d77 100644 --- a/compiler/elymasAsmLib.ey +++ b/compiler/elymasAsmLib.ey @@ -86,7 +86,7 @@ [ ] =linkHoles } /linkResolve deff - { [ } "[[" deff + { :labelRecord [ } "[[" deff { ] :labelResolve stringResolve } "]]" deff { %00 %00 %00 %00 %00 %60 %00 %00 } /HEAPBASE deff diff --git a/compiler/elymasAsmOps.ey b/compiler/elymasAsmOps.ey index 06efb82..f3fe043 100644 --- a/compiler/elymasAsmOps.ey +++ b/compiler/elymasAsmOps.ey @@ -127,48 +127,57 @@ { %66 } /width16 deff # label handling -< { defv }' /put deff > ==labels -[ ] ==labelHoles +< + < { defv }' /put deff > ==labels + [ ] ==labelHoles { =labelHoles }' =*setLabelHoles + < > ==outer +> ==labelStack { ==l - ] _ len l labels .put [ -011 len dearray + ] _ len l labelStack .labels .put [ -011 len dearray } /label deff { ==l ] _ len ==offset - labelHoles [ { - labels l . offset 1 add sub + labelStack .labelHoles [ { + labelStack .labels l . offset 1 add sub _ 128 lt not { "8 bit relative label out of range: " l cat die } rep _ 128 neg ge not { "8 bit relative label out of range: " l cat die } rep - imm8 offset -102 =[] } ] cat =labelHoles + imm8 offset -102 =[] } ] cat labelStack .setLabelHoles [ -011 len dearray %00 } /labelRel8 deff { ==l ] _ len ==offset - labelHoles [ { - labels l . offset 2 add sub + labelStack .labelHoles [ { + labelStack .labels l . offset 2 add sub _ 32768 lt not { "16 bit relative label out of range: " l cat die } rep _ 32768 neg ge not { "16 bit relative label out of range: " l cat die } rep - imm16 offset [ 0 1 ] add 2 dearray -204314 =[] =[] } ] cat =labelHoles + imm16 offset [ 0 1 ] add 2 dearray -204314 =[] =[] } ] cat labelStack .setLabelHoles [ -011 len dearray %00 %00 } /labelRel16 deff { ==l ] _ len ==offset - labelHoles [ { - labels l . offset 4 add sub + labelStack .labelHoles [ { + labelStack .labels l . offset 4 add sub _ 2147483648 lt not { "32 bit relative label out of range: " l cat die } rep _ 2147483648 neg ge not { "32 bit relative label out of range" l cat die } rep - imm32 offset [ 0 1 2 3 ] add 4 dearray -408518628738 =[] =[] =[] =[] } ] cat =labelHoles + imm32 offset [ 0 1 2 3 ] add 4 dearray -408518628738 =[] =[] =[] =[] } ] cat labelStack .setLabelHoles [ -011 len dearray %00 %00 %00 %00 } /labelRel32 deff -{ ==opcodes - labelHoles { opcodes -01 * } each +{ + < + < { defv }' /put deff > ==labels + [ ] ==labelHoles { =labelHoles }' =*setLabelHoles + labelStack ==outer + > =labelStack +} /labelRecord deff - < { defv }' /put deff > =labels - [ ] =labelHoles +{ ==opcodes + labelStack .labelHoles { opcodes -01 * } each + labelStack .outer =labelStack opcodes } /labelResolve deff diff --git a/compiler/elymasGlobal.ey b/compiler/elymasGlobal.ey index a948b53..7afd660 100644 --- a/compiler/elymasGlobal.ey +++ b/compiler/elymasGlobal.ey @@ -6,7 +6,7 @@ assembler .|label "@" deff "%" _ : -01 deff - { [ } "[[" deff + { :labelRecord [ } "[[" deff { ] :labelResolve ::stringResolve } "]]" deff # elymas functions, stack based ABI 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 |
