Skip to content

Commit

Permalink
ggas64: optimizations: indexing
Browse files Browse the repository at this point in the history
- enable IR_OPT_ADDRCISC optimizations
- use complex addressing (base + offset*multiplier) optimization for indexes
  • Loading branch information
SARG-FB committed Dec 11, 2023
1 parent 7d39093 commit 7b8d0b0
Show file tree
Hide file tree
Showing 5 changed files with 695 additions and 10 deletions.
3 changes: 2 additions & 1 deletion changelog.txt
Expand Up @@ -17,7 +17,8 @@ Version 1.20.0
- gas64: optimizations: simplify some operations where one operand is zero (0) (SARG)
- gas64: optimizations: storage of registers with branching (SARG)
- gas64: optimizations: Replace some CMP instructions with TEST instruction (SARG)
- gas64: optimizations: multiplication for small constants -1,-2,3,5,6,10 (SARG)
- gas64: optimizations: multiplication for small constants -1,-2,3,5,6,9,10 (SARG)
- gas64: optimizations: enable IR_OPT_ADDRCISC optimizations to use complex addressing (base + offset*multiplier) optimization for indexes (SARG)
- fbc headers: add ./inc/fberror.bi for runtime library error constants
- rtlib: ./inc/fbc-int/string.bi - for string descriptor and low level string functions

Expand Down
68 changes: 59 additions & 9 deletions src/compiler/ir-gas64.bas
Expand Up @@ -2048,7 +2048,7 @@ private sub _init( )

irhlInit( )
'' IR_OPT_CPUSELFBOPS disabled, to prevent AST from producing self-ops.
irSetOption(IR_OPT_CPUBOPFLAGS or IR_OPT_MISSINGOPS or IR_OPT_CPUSELFBOPS)' or IR_OPT_ADDRCISC)'
irSetOption(IR_OPT_CPUBOPFLAGS or IR_OPT_MISSINGOPS or IR_OPT_CPUSELFBOPS or IR_OPT_ADDRCISC)'

' dtypeName(FB_DATATYPE_INTEGER) = dtypeName(FB_DATATYPE_LONGINT)
'dtypeName(FB_DATATYPE_UINT ) = dtypeName(FB_DATATYPE_ULONGINT)
Expand Down Expand Up @@ -3103,6 +3103,56 @@ private sub prepare_idx(byval v1 as IRVREG ptr, byref op1 as string, byref op3 a

dim as string regtempo
'asm_info("prepare_op v1->sym="+str(v1->sym)+" "+str(v1->vidx->sym))

if v1->mult<>0 then
if v1->vidx->sym=0 then
if v1->vidx->reg<>-1 then
regtempo=*regstrq(reg_findreal(v1->vidx->reg))
else
regtempo=*regstrq(reg_findreal(v1->vidx->vidx->reg))
asm_code("mov "+regtempo+", "+"["+regtempo+"]")
end if
else
regtempo=*reg_tempo()
if symbIsStatic(v1->vidx->sym) Or symbisshared(v1->vidx->sym) then
if v1->vidx->typ=IR_VREGTYPE_IDX then
asm_code("lea "+regtempo+", "+*symbGetMangledName(v1->vidx->sym)+"[rip+"+Str(v1->vidx->ofs)+"]")
elseif v1->vidx->typ=IR_VREGTYPE_VAR then
asm_code("mov "+regtempo+", "+*symbGetMangledName(v1->vidx->sym)+"[rip+"+Str(v1->vidx->ofs)+"]")
else
asm_error("prepare_IDX case v1->vidx->typ not handled 00")
end if
if v1->vidx->vidx then
asm_code("mov "+regtempo+", ["+regtempo+"+"+*regstrq(reg_findreal(v1->vidx->vidx->reg))+"]")
end if
else
asm_code("mov "+regtempo+", "+Str(v1->vidx->ofs)+"[rbp]")
end if
end if

select case as const v1->mult
Case 2,4,8
regtempo=regtempo+"*"+str(v1->mult)
case 3,5,9
asm_code("lea "+regtempo+", "+"["+regtempo+"+"+regtempo+"*"+str(v1->mult-1)+"]")
End Select

if v1->sym=0 then
op1=str(v1->ofs)+"["+regtempo+"]"
elseif symbIsStatic(v1->sym) Or symbisshared(v1->sym) then
dim as string regtempo2
regtempo2=*reg_tempo()
asm_code("lea "+regtempo2+", "+*symbGetMangledName(v1->sym)+"[rip+"+Str(v1->ofs)+"]")
asm_code("lea "+regtempo2+", "+"["+regtempo2+"+"+regtempo+"]")
op1="["+regtempo2+"]"
else
op1=Str(v1->ofs)+"[rbp+"+regtempo+"]"
end if

return
end if


if v1->sym=0 then
''format (ofs= )[datatype] vidx=<reg> /// vidx=<var varname ofs
if v1->vidx->sym=0 then
Expand All @@ -3114,20 +3164,20 @@ private sub prepare_idx(byval v1 as IRVREG ptr, byref op1 as string, byref op3 a
else
''2 levels of deref
regtempo=*regstrq(reg_findreal(v1->vidx->vidx->reg))
op3="mov "+regtempo+", "+"["+regtempo+"]"
asm_code("mov "+regtempo+", "+"["+regtempo+"]")
op1=Str(v1->ofs)+"["+regtempo+"]"
return
end if
else
''with vidx=<var varname ofs
regtempo=*reg_tempo()
if symbIsStatic(v1->vidx->sym) Or symbisshared(v1->vidx->sym) then
op3="lea "+regtempo+", "+*symbGetMangledName(v1->vidx->sym)+"[rip+"+Str(v1->vidx->ofs)+"]"
op3+=newline2+"mov "+regtempo+", "+"["+regtempo+"] #NO"
asm_code("lea "+regtempo+", "+*symbGetMangledName(v1->vidx->sym)+"[rip+"+Str(v1->vidx->ofs)+"]")
asm_code("mov "+regtempo+", "+"["+regtempo+"]") ' #NO"
op1=Str(v1->ofs)+"["+regtempo+"]"
return
else
op3="mov "+regtempo+", "+Str(v1->vidx->ofs)+"[rbp]"
asm_code("mov "+regtempo+", "+Str(v1->vidx->ofs)+"[rbp]")
op1=Str(v1->ofs)+"["+regtempo+"]"
return
end if
Expand All @@ -3137,18 +3187,18 @@ private sub prepare_idx(byval v1 as IRVREG ptr, byref op1 as string, byref op3 a
''format varname ofs1= [dt] vidx=<reg> /// vidx=<var varname ofs
regtempo=*reg_tempo()
if symbIsStatic(v1->sym) Or symbisshared(v1->sym) then
op3="lea "+regtempo+", "+*symbGetMangledName(v1->sym)+"[rip+"+Str(v1->ofs)+"] #NO"
asm_code("lea "+regtempo+", "+*symbGetMangledName(v1->sym)+"[rip+"+Str(v1->ofs)+"]")' #NO"
else
op3="lea "+regtempo+", "+Str(v1->ofs)+"[rbp]"
asm_code("lea "+regtempo+", "+Str(v1->ofs)+"[rbp]")
end if
if v1->vidx->typ=IR_VREGTYPE_REG then
op1="["+regtempo+"+"+*regstrq(reg_findreal(v1->vidx->reg))+"]"
return
elseif v1->vidx->typ=IR_VREGTYPE_VAR then
if symbIsStatic(v1->vidx->sym) Or symbisshared(v1->vidx->sym) then
op3+=newline2+"add "+regtempo+", "+*symbGetMangledName(v1->vidx->sym)+"[rip+"+Str(v1->vidx->ofs)+"]"
asm_code("add "+regtempo+", "+*symbGetMangledName(v1->vidx->sym)+"[rip+"+Str(v1->vidx->ofs)+"]")
else
op3+=newline2+"add "+regtempo+","+Str(v1->vidx->ofs)+"[rbp]"
asm_code("add "+regtempo+","+Str(v1->vidx->ofs)+"[rbp]")
end if
op1="["+regtempo+"]"
return
Expand Down
1 change: 1 addition & 0 deletions src/compiler/ir.bas
Expand Up @@ -184,6 +184,7 @@ function irhlAllocVrIdx _
vr->sym = symbol
vr->ofs = ofs
vr->vidx = vidx
vr->mult = mult

function = vr
end function
Expand Down

0 comments on commit 7b8d0b0

Please sign in to comment.