mirror of
https://github.com/dlang/dmd.git
synced 2025-04-26 13:10:12 +03:00
progress on dealing with common subexpressions (#20987)
This commit is contained in:
parent
35f1146a1b
commit
1e75778d19
6 changed files with 121 additions and 15 deletions
|
@ -56,7 +56,9 @@ nothrow:
|
||||||
*/
|
*/
|
||||||
void loadFromEA(ref code cs, reg_t reg, uint szw, uint szr)
|
void loadFromEA(ref code cs, reg_t reg, uint szw, uint szr)
|
||||||
{
|
{
|
||||||
if (reg & 32) // if floating point register
|
cs.Iop = INSTR.nop;
|
||||||
|
assert(reg != NOREG);
|
||||||
|
if (mask(reg) & INSTR.FLOATREGS) // if floating point store
|
||||||
{
|
{
|
||||||
if (cs.reg != NOREG)
|
if (cs.reg != NOREG)
|
||||||
{
|
{
|
||||||
|
@ -120,7 +122,10 @@ void loadFromEA(ref code cs, reg_t reg, uint szw, uint szr)
|
||||||
*/
|
*/
|
||||||
void storeToEA(ref code cs, reg_t reg, uint sz)
|
void storeToEA(ref code cs, reg_t reg, uint sz)
|
||||||
{
|
{
|
||||||
if (reg & 32) // if floating point store
|
//debug printf("storeToEA(reg: %d, sz: %d)\n", reg, sz);
|
||||||
|
cs.Iop = INSTR.nop;
|
||||||
|
assert(reg != NOREG);
|
||||||
|
if (mask(reg) & INSTR.FLOATREGS) // if floating point store
|
||||||
{
|
{
|
||||||
if (cs.reg != NOREG)
|
if (cs.reg != NOREG)
|
||||||
{
|
{
|
||||||
|
@ -1071,7 +1076,7 @@ void getlvalue(ref CodeBuilder cdb,ref code pcs,elem* e,regm_t keepmsk,RM rm = R
|
||||||
* such variables.
|
* such variables.
|
||||||
*/
|
*/
|
||||||
if (tyxmmreg(ty) && !(s.Sregm & XMMREGS) ||
|
if (tyxmmreg(ty) && !(s.Sregm & XMMREGS) ||
|
||||||
!tyxmmreg(ty) && (s.Sregm & XMMREGS))
|
!tyxmmreg(ty) && (s.Sregm & XMMREGS)) // TODO AArch64
|
||||||
cgreg_unregister(s.Sregm);
|
cgreg_unregister(s.Sregm);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
|
|
@ -30,6 +30,7 @@ import dmd.backend.cc;
|
||||||
import dmd.backend.cdef;
|
import dmd.backend.cdef;
|
||||||
import dmd.backend.cgcse;
|
import dmd.backend.cgcse;
|
||||||
import dmd.backend.code;
|
import dmd.backend.code;
|
||||||
|
import dmd.backend.arm.cod1 : loadFromEA, storeToEA;
|
||||||
import dmd.backend.arm.disasmarm : encodeHFD;
|
import dmd.backend.arm.disasmarm : encodeHFD;
|
||||||
import dmd.backend.x86.cgcod : disassemble;
|
import dmd.backend.x86.cgcod : disassemble;
|
||||||
import dmd.backend.x86.code_x86;
|
import dmd.backend.x86.code_x86;
|
||||||
|
@ -207,9 +208,90 @@ COND conditionCode(elem* e)
|
||||||
// cod3_ptrchk
|
// cod3_ptrchk
|
||||||
// cod3_useBP
|
// cod3_useBP
|
||||||
// cse_simple
|
// cse_simple
|
||||||
// gen_storecse
|
|
||||||
// gen_testcse
|
/**************************
|
||||||
// gen_loadcse
|
* Store `reg` to the common subexpression save area in index `slot`.
|
||||||
|
* Params:
|
||||||
|
* cdb = where to write code to
|
||||||
|
* tym = type of value that's in `reg`
|
||||||
|
* reg = register to save
|
||||||
|
* slot = index into common subexpression save area
|
||||||
|
*/
|
||||||
|
@trusted
|
||||||
|
void gen_storecse(ref CodeBuilder cdb, tym_t tym, reg_t reg, size_t slot)
|
||||||
|
{
|
||||||
|
//printf("gen_storecse() tym: %s reg: %d slot: %d\n", tym_str(tym), reg, cast(int)slot);
|
||||||
|
// MOV slot[BP],reg
|
||||||
|
if (tyvector(tym)) // TODO AArch64
|
||||||
|
{
|
||||||
|
assert(0);
|
||||||
|
//const aligned = tyvector(tym) ? STACKALIGN >= 16 : true;
|
||||||
|
//const op = xmmstore(tym, aligned);
|
||||||
|
//cdb.genc1(op,modregxrm(2, reg - XMM0, BPRM),FL.cs,cast(targ_size_t)slot);
|
||||||
|
//return;
|
||||||
|
}
|
||||||
|
code cs;
|
||||||
|
cs.IFL1 = FL.cs;
|
||||||
|
cs.Iflags = CFoff;
|
||||||
|
cs.reg = NOREG;
|
||||||
|
cs.index = NOREG;
|
||||||
|
cs.base = 29; // SP? BPRM? TODO AArch64
|
||||||
|
cs.Sextend = 0;
|
||||||
|
cs.IEV1.Vsym = null;
|
||||||
|
cs.IEV1.Voffset = slot;
|
||||||
|
storeToEA(cs, reg, tysize(tym));
|
||||||
|
assert(cs.Iop);
|
||||||
|
cdb.gen(&cs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@trusted
|
||||||
|
void gen_testcse(ref CodeBuilder cdb, tym_t tym, uint sz, size_t slot)
|
||||||
|
{
|
||||||
|
printf("gen_testcse()\n");
|
||||||
|
// CMP slot[BP],0
|
||||||
|
static if (0)
|
||||||
|
{
|
||||||
|
/* Since on the AArch64 this would have to allocate a register,
|
||||||
|
that should probably be done by the caller TODO AArch64
|
||||||
|
*/
|
||||||
|
assert(0);
|
||||||
|
cdb.genc(sz == 1 ? 0x80 : 0x81,modregrm(2,7,BPRM),
|
||||||
|
FL.cs,cast(targ_uns)slot, FL.const_,cast(targ_uns) 0);
|
||||||
|
if ((I64 || I32) && sz == 2)
|
||||||
|
cdb.last().Iflags |= CFopsize;
|
||||||
|
if (I64 && sz == 8)
|
||||||
|
code_orrex(cdb.last(), REX_W);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@trusted
|
||||||
|
void gen_loadcse(ref CodeBuilder cdb, tym_t tym, reg_t reg, size_t slot)
|
||||||
|
{
|
||||||
|
//printf("gen_loadcse() tym: %s reg: %d slot: %d\n", tym_str(tym), reg, cast(int)slot);
|
||||||
|
// MOV reg,slot[BP]
|
||||||
|
if (tyvector(tym)) // TODO AArch64
|
||||||
|
{
|
||||||
|
assert(0);
|
||||||
|
//const aligned = tyvector(tym) ? STACKALIGN >= 16 : true;
|
||||||
|
//const op = xmmload(tym, aligned);
|
||||||
|
//cdb.genc1(op,modregxrm(2, reg - XMM0, BPRM),FL.cs,cast(targ_size_t)slot);
|
||||||
|
//return;
|
||||||
|
}
|
||||||
|
code cs;
|
||||||
|
cs.IFL1 = FL.cs;
|
||||||
|
cs.Iflags = CFoff;
|
||||||
|
cs.reg = NOREG;
|
||||||
|
cs.index = NOREG;
|
||||||
|
cs.base = 29; // SP? BPRM? TODO AArch64
|
||||||
|
cs.Sextend = 0;
|
||||||
|
cs.IEV1.Vsym = null;
|
||||||
|
cs.IEV1.Voffset = slot;
|
||||||
|
uint szr = tysize(tym);
|
||||||
|
uint szw = szr == 8 ? 8 : 4;
|
||||||
|
loadFromEA(cs, reg, szw, szr);
|
||||||
|
cdb.gen(&cs);
|
||||||
|
}
|
||||||
|
|
||||||
// cdframeptr
|
// cdframeptr
|
||||||
// cdgot
|
// cdgot
|
||||||
// load_localgot
|
// load_localgot
|
||||||
|
@ -1143,6 +1225,7 @@ void assignaddrc(code* c)
|
||||||
ulong offset;
|
ulong offset;
|
||||||
reg_t Rn, Rt;
|
reg_t Rn, Rt;
|
||||||
uint base = cgstate.EBPtoESP;
|
uint base = cgstate.EBPtoESP;
|
||||||
|
code* csave = c;
|
||||||
|
|
||||||
for (; c; c = code_next(c))
|
for (; c; c = code_next(c))
|
||||||
{
|
{
|
||||||
|
@ -1230,7 +1313,7 @@ void assignaddrc(code* c)
|
||||||
s = c.IEV1.Vsym;
|
s = c.IEV1.Vsym;
|
||||||
uint sz = 8;
|
uint sz = 8;
|
||||||
uint ins = c.Iop;
|
uint ins = c.Iop;
|
||||||
// if (c.IFL1 != FL.unde)
|
if (0 && c.IFL1 != FL.unde)
|
||||||
{
|
{
|
||||||
printf("FL: %s ", fl_str(c.IFL1));
|
printf("FL: %s ", fl_str(c.IFL1));
|
||||||
disassemble(ins);
|
disassemble(ins);
|
||||||
|
@ -1431,10 +1514,16 @@ printf("offset: %lld localsize: %lld REGSIZE*2: %d\n", offset, localsize, REGSIZ
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
printf("FL: %s\n", fl_str(c.IFL1));
|
if (0) printf("FL: %s\n", fl_str(c.IFL1));
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
static if (0)
|
||||||
|
for (c = csave; c; c = code_next(c))
|
||||||
|
{
|
||||||
|
printf("Iop %08x ", c.Iop);
|
||||||
|
disassemble(c.Iop);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************
|
/**************************
|
||||||
|
|
|
@ -55,8 +55,8 @@ nothrow:
|
||||||
@trusted
|
@trusted
|
||||||
void cdeq(ref CGstate cg, ref CodeBuilder cdb,elem* e,ref regm_t pretregs)
|
void cdeq(ref CGstate cg, ref CodeBuilder cdb,elem* e,ref regm_t pretregs)
|
||||||
{
|
{
|
||||||
printf("cdeq(e = %p, pretregs = %s)\n",e,regm_str(pretregs));
|
//printf("cdeq(e = %p, pretregs = %s)\n",e,regm_str(pretregs));
|
||||||
elem_print(e);
|
//elem_print(e);
|
||||||
|
|
||||||
reg_t reg;
|
reg_t reg;
|
||||||
code cs;
|
code cs;
|
||||||
|
@ -362,7 +362,7 @@ void cdaddass(ref CGstate cg, ref CodeBuilder cdb,elem* e,ref regm_t pretregs)
|
||||||
scodelem(cgstate,cdb,e.E2,retregs,0,true); // get rvalue
|
scodelem(cgstate,cdb,e.E2,retregs,0,true); // get rvalue
|
||||||
getlvalue(cdb,cs,e1,retregs); // get lvalue
|
getlvalue(cdb,cs,e1,retregs); // get lvalue
|
||||||
reg_t reg1;
|
reg_t reg1;
|
||||||
if (cs.reg)
|
if (cs.reg != NOREG)
|
||||||
reg1 = cs.reg;
|
reg1 = cs.reg;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -1173,7 +1173,7 @@ struct INSTR
|
||||||
// STRH Rt,[Xn,#offset]
|
// STRH Rt,[Xn,#offset]
|
||||||
uint size = 1;
|
uint size = 1;
|
||||||
uint imm12 = offset & 0xFFF;
|
uint imm12 = offset & 0xFFF;
|
||||||
return ldst_pos(0, 0, 0, imm12, Rn, Rt);
|
return ldst_pos(1, 0, 0, imm12, Rn, Rt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* STR (immediate) Unsigned offset
|
/* STR (immediate) Unsigned offset
|
||||||
|
|
|
@ -2095,7 +2095,7 @@ private void comsub(ref CodeBuilder cdb,elem* e, ref regm_t pretregs)
|
||||||
uint byte_,sz;
|
uint byte_,sz;
|
||||||
|
|
||||||
//printf("comsub(e = %p, pretregs = %s)\n",e,regm_str(pretregs));
|
//printf("comsub(e = %p, pretregs = %s)\n",e,regm_str(pretregs));
|
||||||
elem_debug(e);
|
//elem_debug(e);
|
||||||
|
|
||||||
debug
|
debug
|
||||||
{
|
{
|
||||||
|
@ -2203,7 +2203,7 @@ private void comsub(ref CodeBuilder cdb,elem* e, ref regm_t pretregs)
|
||||||
cse.flags |= CSEload;
|
cse.flags |= CSEload;
|
||||||
if (pretregs == mPSW) // if result in CCs only
|
if (pretregs == mPSW) // if result in CCs only
|
||||||
{
|
{
|
||||||
if (config.fpxmmregs && (tyxmmreg(cse.e.Ety) || tyvector(cse.e.Ety)))
|
if (0 && config.fpxmmregs && (tyxmmreg(cse.e.Ety) || tyvector(cse.e.Ety))) // TODO AArch64
|
||||||
{
|
{
|
||||||
retregs = XMMREGS;
|
retregs = XMMREGS;
|
||||||
reg = allocreg(cdb,retregs,tym);
|
reg = allocreg(cdb,retregs,tym);
|
||||||
|
|
|
@ -2686,6 +2686,10 @@ bool cse_simple(code* c, elem* e)
|
||||||
@trusted
|
@trusted
|
||||||
void gen_storecse(ref CodeBuilder cdb, tym_t tym, reg_t reg, size_t slot)
|
void gen_storecse(ref CodeBuilder cdb, tym_t tym, reg_t reg, size_t slot)
|
||||||
{
|
{
|
||||||
|
if (cgstate.AArch64)
|
||||||
|
return dmd.backend.arm.cod3.gen_storecse(cdb,tym,reg,slot);
|
||||||
|
|
||||||
|
//printf("gen_storecse()\n");
|
||||||
// MOV slot[BP],reg
|
// MOV slot[BP],reg
|
||||||
if (isXMMreg(reg) && config.fpxmmregs) // watch out for ES
|
if (isXMMreg(reg) && config.fpxmmregs) // watch out for ES
|
||||||
{
|
{
|
||||||
|
@ -2708,6 +2712,10 @@ void gen_storecse(ref CodeBuilder cdb, tym_t tym, reg_t reg, size_t slot)
|
||||||
@trusted
|
@trusted
|
||||||
void gen_testcse(ref CodeBuilder cdb, tym_t tym, uint sz, size_t slot)
|
void gen_testcse(ref CodeBuilder cdb, tym_t tym, uint sz, size_t slot)
|
||||||
{
|
{
|
||||||
|
if (cgstate.AArch64)
|
||||||
|
return dmd.backend.arm.cod3.gen_testcse(cdb,tym,sz,slot);
|
||||||
|
|
||||||
|
//printf("gen_testcse()\n");
|
||||||
// CMP slot[BP],0
|
// CMP slot[BP],0
|
||||||
cdb.genc(sz == 1 ? 0x80 : 0x81,modregrm(2,7,BPRM),
|
cdb.genc(sz == 1 ? 0x80 : 0x81,modregrm(2,7,BPRM),
|
||||||
FL.cs,cast(targ_uns)slot, FL.const_,cast(targ_uns) 0);
|
FL.cs,cast(targ_uns)slot, FL.const_,cast(targ_uns) 0);
|
||||||
|
@ -2720,6 +2728,10 @@ void gen_testcse(ref CodeBuilder cdb, tym_t tym, uint sz, size_t slot)
|
||||||
@trusted
|
@trusted
|
||||||
void gen_loadcse(ref CodeBuilder cdb, tym_t tym, reg_t reg, size_t slot)
|
void gen_loadcse(ref CodeBuilder cdb, tym_t tym, reg_t reg, size_t slot)
|
||||||
{
|
{
|
||||||
|
if (cgstate.AArch64)
|
||||||
|
return dmd.backend.arm.cod3.gen_loadcse(cdb,tym,reg,slot);
|
||||||
|
|
||||||
|
//printf("gen_loadcse()\n");
|
||||||
// MOV reg,slot[BP]
|
// MOV reg,slot[BP]
|
||||||
if (isXMMreg(reg) && config.fpxmmregs)
|
if (isXMMreg(reg) && config.fpxmmregs)
|
||||||
{
|
{
|
||||||
|
@ -3973,7 +3985,7 @@ private void epilog_restoreregs(ref CGstate cg, ref CodeBuilder cdb, regm_t topo
|
||||||
void prolog_genvarargs(ref CGstate cg, ref CodeBuilder cdb, Symbol* sv)
|
void prolog_genvarargs(ref CGstate cg, ref CodeBuilder cdb, Symbol* sv)
|
||||||
{
|
{
|
||||||
if (cg.AArch64)
|
if (cg.AArch64)
|
||||||
return dmd.backend.arm.cod3.prolog_genvarargs(cg, cdb, sv);
|
return dmd.backend.arm.cod3.prolog_genvarargs(cg, cdb, sv);
|
||||||
|
|
||||||
/* Generate code to move any arguments passed in registers into
|
/* Generate code to move any arguments passed in registers into
|
||||||
* the stack variable __va_argsave,
|
* the stack variable __va_argsave,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue