aboutsummaryrefslogtreecommitdiff
path: root/elymas
diff options
context:
space:
mode:
Diffstat (limited to 'elymas')
-rw-r--r--elymas/lib/sys/opt.ey158
1 files changed, 115 insertions, 43 deletions
diff --git a/elymas/lib/sys/opt.ey b/elymas/lib/sys/opt.ey
index 861a0fe..4ee5cca 100644
--- a/elymas/lib/sys/opt.ey
+++ b/elymas/lib/sys/opt.ey
@@ -702,13 +702,15 @@
} each
} /rewriteArithmeticsOptimistic deffst
- { ==logic
+ { ==logic /CANARY
[ ] ==knownStack
{
[ knownStack _ len dearray ==ret ] =knownStack ret # TODO: make a real array pop
} /knownPop deffst
- [ ] ==sideEffects
+ [ ] ==scopeReads
+ [ ] ==stackReads
+ [ ] ==scopeWrites
0 ==actualImprovement
0 ==consumedInputStack
@@ -723,7 +725,9 @@
0 =actualImprovement
0 =consumedInputStack
[ ] =knownStack
- [ ] =sideEffects
+ [ ] =scopeWrites
+ [ ] =scopeReads
+ [ ] =stackReads
i 1 add =traceStart
} =*restartTracing
@@ -747,32 +751,72 @@
{
knownStack len { knownPop }' {
- [ /INPUT consumedInputStack _ 1 add =consumedInputStack NOREGISTER ]
+ [ /INPUT consumedInputStack _ 1 add =consumedInputStack NOREGISTER ] ==read
+ stackReads [ read ] cat =stackReads
+ read
}' ? *
} /consume deffst
{ i logic len lt } {
- i logic * ==entry
- 0 entry * ==action
+ i logic * =*entry
+ 0 entry ==action
# "Known Stack: " dump
# knownStack dump
- # "Handling: " dump
- # entry dump
+ "Handling: " dump
+ |entry dump
[
{ action NOP eq } { }
{ action PUSH eq } {
- knownStack [ entry ] cat =knownStack
+ knownStack [ |entry ] cat =knownStack
}
- { action STATICTYPED eq { 4 entry * sys .typed .type 0 eq }' andif } {
- knownStack [ [ entry _ len dearray NOREGISTER ] ] cat =knownStack
+ { action STATICTYPED eq { 4 entry sys .typed .type 0 eq }' andif } {
+ 1 neg ==priorWrite 0 ==i { i scopeWrites len lt } {
+ i scopeWrites * =*write
+ 0 write STATICWRITE neq { |write dump "scopeWrites contains unexpected element type" die } rep
+ 1 write 1 entry eq { 2 write 2 entry eq }' andif { 3 write 3 entry eq }' andif { i =priorWrite } rep
+ i 1 add =i
+ } loop
+
+ priorWrite 0 ge {
+ 4 priorWrite scopeWrites * * ==source
+ knownStack [ source ] cat =knownStack
+ } {
+ 1 neg ==priorRead 0 ==i { i scopeReads len lt } {
+ i scopeReads * =*read
+ 0 read STATICTYPED neq { |read dump "scopeReads contains unexpected element type" die } rep
+ 1 read 1 entry eq { 2 read 2 entry eq }' andif { 3 read 3 entry eq }' andif { i =priorRead } rep
+ i 1 add =i
+ } loop
+
+ priorRead 0 ge {
+ priorRead scopeReads * ==read
+ knownStack [ read ] cat =knownStack
+ } {
+ [ |entry _ len dearray NOREGISTER ] ==read
+ knownStack [ read ] cat =knownStack
+ scopeReads [ read ] cat =scopeReads
+ } ? *
+ } ? *
}
{ action STATICWRITE eq } {
consume ==value
- sideEffects [ [ entry _ len dearray value ] ] cat =sideEffects
+
+ 1 neg ==priorWrite 0 ==i { i scopeWrites len lt } {
+ i scopeWrites * =*write
+ 0 write STATICWRITE neq { |write dump "scopeWrites contains unexpected element type" die } rep
+ 1 write 1 entry eq { 2 write 2 entry eq }' andif { 3 write 3 entry eq }' andif { i =priorWrite } rep
+ i 1 add =i
+ } loop
+
+ priorWrite 0 ge {
+ [ |entry _ len dearray value ] priorWrite scopeWrites =[]
+ } {
+ scopeWrites [ [ |entry _ len dearray value ] ] cat =scopeWrites
+ } ? *
}
- { action CALL eq { 1 entry * "*" | ::rawCodeAddress eq }' andif { knownStack len }' andif } {
+ { action CALL eq { 1 entry "*" | ::rawCodeAddress eq }' andif { knownStack len }' andif } {
knownPop ==top
0 top * PUSH eq {
1 top * ==called
@@ -789,12 +833,14 @@
] conds
} { "Star on non-constant object" restartTracing } ? *
}
- { 1 } { "Unhandled logic entry type" restartTracing entry dump }
+ { 1 } { "Unhandled logic entry type" restartTracing |entry dump }
] conds
i 1 add =i
} loop
+ _ dump /starting_assembly dump
+
0 ==registerUsed
[ /rcx /rdx /rbx /rbp /rsi /rdi ] ==availableRegisters
[ availableRegisters len { 0 } rep ] ==usedRegisters
@@ -831,6 +877,9 @@
/dil ==rdi
> ==lowByte
+ [ ] ==inputsChecked
+ [ ] ==scopeReadsChecked
+
[ ] ==traceConditions
[
consumedInputStack { consumedInputStack 8 mul /rsp :addqImm8Reg } { } ? *
@@ -858,11 +907,16 @@
} /canProduceLargeInts deffst
{ =*entry
+ "Compiling..." dump
+ |entry dump
+ { } ==?registerDeallocations # shall be returned
[
+ { |entry hasRegister { |entry getRegister NOREGISTER neq }' andif } { } # entry already compiled
{ 0 entry PUSH eq } { } # don't put constant into a register
{ 0 entry /INPUT eq } {
nextRegister _ ==target 2 |entry =[]
+ { target freeRegister NOREGISTER 2 |entry =[] } registerDeallocations ; =registerDeallocations
traceConditions [
1 entry 8 mul /rsp target :movqMemDisp8Reg
@@ -892,10 +946,12 @@
{ 0 entry STATICWRITE eq } {
4 entry compileExpression
+ registerDeallocations ; =registerDeallocations # reuse source register for ourselves (a bit)
}
{ 0 entry STATICTYPED eq } {
nextRegister _ ==target 5 |entry =[]
+ { target freeRegister NOREGISTER 5 |entry =[] } registerDeallocations ; =registerDeallocations
traceCode [
2 entry {
@@ -930,9 +986,10 @@
}
{ 0 entry /LOGICFUNCTION eq { 1 entry /EQ eq }' andif } {
- 2 entry _ compileExpression =*left
- 3 entry _ compileExpression =*right
+ 2 entry _ =*left compileExpression =*?deallocLeft
+ 3 entry _ =*right compileExpression =*?deallocRight
nextRegister _ ==target 4 |entry =[]
+ { target freeRegister NOREGISTER 4 |entry =[] } registerDeallocations ; =registerDeallocations
[
{ 0 right PUSH eq { 1 right isIntValue }' andif { 1 right getIntValue %7F le }' andif } {
@@ -946,20 +1003,21 @@
1 right getIntValue reg :cmpqImm8Reg
lowByte target . :seteReg
] cat =traceCode
-
- reg freeRegister
}
{ 1 } { "EQ: unhandled left type" abortTracing }
] conds
}
{ 1 } { "EQ: unhandled right type" abortTracing }
] conds
+
+ deallocLeft deallocRight
}
{ 0 entry /LOGICFUNCTION eq { 1 entry /OR eq }' andif } {
- 2 entry _ compileExpression =*left
- 3 entry _ compileExpression =*right
+ 2 entry _ =*left compileExpression =*?deallocLeft
+ 3 entry _ =*right compileExpression =*?deallocRight
nextRegister _ ==target 4 |entry =[]
+ { target freeRegister NOREGISTER 4 |entry =[] } registerDeallocations ; =registerDeallocations
[
{ |right hasRegister } {
@@ -977,26 +1035,29 @@
/al :setneReg
/al lowByte target . :orbRegReg
] cat =traceCode
-
- rreg freeRegister
- lreg freeRegister
}
{ 1 } { "OR: unhandled left type" abortTracing }
] conds
}
{ 1 } { "OR: unhandled right type" abortTracing }
] conds
+
+ deallocLeft deallocRight
}
{ 1 } { |entry dump "Invalid entry while compiling trace code" die }
] conds
+
+ registerDeallocations
} /compileExpression deffst
- sideEffects |compileExpression each
- sideEffects { =*entry
+ scopeReads { compileExpression -- } each # do not deallocate, keep the values in registers to permit later writes
+ stackReads { compileExpression -- } each # do not deallocate, keep the cleaned values in registers
+ scopeWrites { _ =*entry compileExpression =*?registerDeallocations
[
{ 0 entry STATICWRITE eq } {
4 entry =*source
NOREGISTER ==reg
+ nextRegister ==tmpreg
[
{ 0 source PUSH eq } {
@@ -1010,14 +1071,15 @@
|source canProduceLargeInts {
traceCode [
reg /rax :movqRegReg
+ reg tmpreg :movqRegReg
32 /rax :shrqImm8Reg
[
- 63 reg :btsqImm8Reg
+ 63 tmpreg :btsqImm8Reg
0 :jmpRel8
] len :jnzRel8
- 63 reg :btsqImm8Reg
+ 63 tmpreg :btsqImm8Reg
[
availableRegisters { :pushqReg } each
@@ -1025,7 +1087,7 @@
/rax :callqReg
availableRegisters reverse { :popqReg } each
reg 8 /rax :movqRegMemDisp8
- /rax reg :movqRegReg
+ /rax tmpreg :movqRegReg
] len :jmpRel8
availableRegisters { :pushqReg } each
@@ -1033,15 +1095,16 @@
/rax :callqReg
availableRegisters reverse { :popqReg } each
reg 8 /rax :movqRegMemDisp8
- /rax reg :movqRegReg
+ /rax tmpreg :movqRegReg
] cat =traceCode
} {
traceCode [
- 63 reg :btsqImm8Reg
+ reg tmpreg :movqRegReg
+ 63 tmpreg :btsqImm8Reg
] cat =traceCode
} ? *
}
- { 1 } { |source dump "Invalid value source in sideEffects" die }
+ { 1 } { |source dump "Invalid value source in scopeWrites" die }
] conds
2 entry {
@@ -1052,39 +1115,42 @@
3 entry {
traceCode [
- reg :pushqReg
- 24 /rax reg :movqMemDisp8Reg # load extension area pointer
+ tmpreg :pushqReg
+ 24 /rax tmpreg :movqMemDisp8Reg # load extension area pointer
/rax /eax :movlMemReg # load scope length
/rax :negqReg # prepare for substraction
- 1 entry 1 /rax reg :popqMemIndexScaleDisp32 # load entry from stack
+ 1 entry 1 /rax tmpreg :popqMemIndexScaleDisp32 # load entry from stack
] cat =traceCode
} {
traceCode [
- reg 1 entry /rax :movqRegMemDisp32
+ tmpreg 1 entry /rax :movqRegMemDisp32
] cat =traceCode
} ? *
} {
3 entry {
traceCode [
- reg :pushqReg
- 24 /r14 reg :movqMemDisp8Reg # load extension area pointer
+ tmpreg :pushqReg
+ 24 /r14 tmpreg :movqMemDisp8Reg # load extension area pointer
/r14 /eax :movlMemReg # load scope length
/rax :negqReg # prepare for substraction
- 1 entry 1 /rax reg :popqMemIndexScaleDisp32 # load entry from stack
+ 1 entry 1 /rax tmpreg :popqMemIndexScaleDisp32 # load entry from stack
] cat =traceCode
} {
traceCode [
- reg 1 entry /r14 :movqRegMemDisp32
+ tmpreg 1 entry /r14 :movqRegMemDisp32
] cat =traceCode
} ? *
} ? *
+
+ tmpreg freeRegister
}
- { 1 } { "Invalid entry type in sideEffects" die }
+ { 1 } { "Invalid entry type in scopeWrites" die }
] conds
+
+ registerDeallocations
} each
- knownStack |compileExpression each
- knownStack { =*entry
+ knownStack { _ =*entry compileExpression =*?registerDeallocations
[
{ 0 entry PUSH eq } {
traceCode [
@@ -1133,12 +1199,17 @@
}
{ 1 } { |entry dump "Invalid entry while assembling trace code" die }
] conds
+
+ registerDeallocations
} each
} rep
+ _ dump /assembly_finished dump
+
aborted not actualImprovement and {
"Improved integer trace" dump
- sideEffects dump
+ scopeReads dump
+ scopeWrites dump
knownStack dump
[
0 traceStart range { logic * } each
@@ -1147,6 +1218,7 @@
] =logic
} rep
+ dump /we_are_done dump
logic
} /rewriteIntegerTrace deffst