progress on dealing with common subexpressions (#20987)

This commit is contained in:
Walter Bright 2025-03-13 22:38:53 -07:00 committed by GitHub
parent 35f1146a1b
commit 1e75778d19
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 121 additions and 15 deletions

View file

@ -56,7 +56,9 @@ nothrow:
*/
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)
{
@ -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)
{
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)
{
@ -1071,7 +1076,7 @@ void getlvalue(ref CodeBuilder cdb,ref code pcs,elem* e,regm_t keepmsk,RM rm = R
* such variables.
*/
if (tyxmmreg(ty) && !(s.Sregm & XMMREGS) ||
!tyxmmreg(ty) && (s.Sregm & XMMREGS))
!tyxmmreg(ty) && (s.Sregm & XMMREGS)) // TODO AArch64
cgreg_unregister(s.Sregm);
if (

View file

@ -30,6 +30,7 @@ import dmd.backend.cc;
import dmd.backend.cdef;
import dmd.backend.cgcse;
import dmd.backend.code;
import dmd.backend.arm.cod1 : loadFromEA, storeToEA;
import dmd.backend.arm.disasmarm : encodeHFD;
import dmd.backend.x86.cgcod : disassemble;
import dmd.backend.x86.code_x86;
@ -207,9 +208,90 @@ COND conditionCode(elem* e)
// cod3_ptrchk
// cod3_useBP
// 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
// cdgot
// load_localgot
@ -1143,6 +1225,7 @@ void assignaddrc(code* c)
ulong offset;
reg_t Rn, Rt;
uint base = cgstate.EBPtoESP;
code* csave = c;
for (; c; c = code_next(c))
{
@ -1230,7 +1313,7 @@ void assignaddrc(code* c)
s = c.IEV1.Vsym;
uint sz = 8;
uint ins = c.Iop;
// if (c.IFL1 != FL.unde)
if (0 && c.IFL1 != FL.unde)
{
printf("FL: %s ", fl_str(c.IFL1));
disassemble(ins);
@ -1431,10 +1514,16 @@ printf("offset: %lld localsize: %lld REGSIZE*2: %d\n", offset, localsize, REGSIZ
break;
default:
printf("FL: %s\n", fl_str(c.IFL1));
if (0) printf("FL: %s\n", fl_str(c.IFL1));
assert(0);
}
}
static if (0)
for (c = csave; c; c = code_next(c))
{
printf("Iop %08x ", c.Iop);
disassemble(c.Iop);
}
}
/**************************

View file

@ -55,8 +55,8 @@ nothrow:
@trusted
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));
elem_print(e);
//printf("cdeq(e = %p, pretregs = %s)\n",e,regm_str(pretregs));
//elem_print(e);
reg_t reg;
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
getlvalue(cdb,cs,e1,retregs); // get lvalue
reg_t reg1;
if (cs.reg)
if (cs.reg != NOREG)
reg1 = cs.reg;
else
{

View file

@ -1173,7 +1173,7 @@ struct INSTR
// STRH Rt,[Xn,#offset]
uint size = 1;
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

View file

@ -2095,7 +2095,7 @@ private void comsub(ref CodeBuilder cdb,elem* e, ref regm_t pretregs)
uint byte_,sz;
//printf("comsub(e = %p, pretregs = %s)\n",e,regm_str(pretregs));
elem_debug(e);
//elem_debug(e);
debug
{
@ -2203,7 +2203,7 @@ private void comsub(ref CodeBuilder cdb,elem* e, ref regm_t pretregs)
cse.flags |= CSEload;
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;
reg = allocreg(cdb,retregs,tym);

View file

@ -2686,6 +2686,10 @@ bool cse_simple(code* c, elem* e)
@trusted
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
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
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
cdb.genc(sz == 1 ? 0x80 : 0x81,modregrm(2,7,BPRM),
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
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]
if (isXMMreg(reg) && config.fpxmmregs)
{