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) 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 (

View file

@ -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);
}
} }
/************************** /**************************

View file

@ -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
{ {

View file

@ -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

View file

@ -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);

View file

@ -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,