more common subexpression implementation (#20988)

This commit is contained in:
Walter Bright 2025-03-14 00:15:48 -07:00 committed by GitHub
parent 1e75778d19
commit 49dc576b9d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 34 additions and 34 deletions

View file

@ -244,26 +244,6 @@ void gen_storecse(ref CodeBuilder cdb, tym_t tym, reg_t reg, size_t slot)
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)
{

View file

@ -2093,6 +2093,7 @@ private void comsub(ref CodeBuilder cdb,elem* e, ref regm_t pretregs)
regm_t regm,emask;
reg_t reg;
uint byte_,sz;
const AArch64 = cgstate.AArch64;
//printf("comsub(e = %p, pretregs = %s)\n",e,regm_str(pretregs));
//elem_debug(e);
@ -2114,16 +2115,18 @@ private void comsub(ref CodeBuilder cdb,elem* e, ref regm_t pretregs)
* have the right contents.
*/
emask = 0;
for (uint i = 0; i < cgstate.regcon.cse.value.length; i++)
foreach (i, ref v; cgstate.regcon.cse.value[])
{
//dbg_printf("regcon.cse.value[%d] = %p\n",i,cgstate.regcon.cse.value[i]);
if (cgstate.regcon.cse.value[i] == e) // if contents are right
emask |= mask(i); // turn on bit for reg
//printf("regcon.cse.value[%d] = %p\n",cast(int)i,v);
if (v == e) // if contents match
emask |= mask(cast(uint)i); // turn on bit for reg
}
emask &= cgstate.regcon.cse.mval; // make sure all bits are valid
if (emask & XMMREGS && pretregs == mPSW)
{ }
if (AArch64)
{ }
else if (emask & XMMREGS && pretregs == mPSW)
{ }
else if (tyxmmreg(e.Ety) && config.fpxmmregs)
{
if (pretregs & (mST0 | mST01))
@ -2158,7 +2161,8 @@ private void comsub(ref CodeBuilder cdb,elem* e, ref regm_t pretregs)
sz = _tysize[tym];
byte_ = sz == 1;
if (sz <= REGSIZE || (tyxmmreg(tym) && config.fpxmmregs)) // if data will fit in one register
if (sz <= REGSIZE ||
(!AArch64 && tyxmmreg(tym) && config.fpxmmregs)) // if data will fit in one register
{
/* First see if it is already in a correct register */
@ -2184,6 +2188,17 @@ private void comsub(ref CodeBuilder cdb,elem* e, ref regm_t pretregs)
if (cse.flags & CSEsimple)
{
if (AArch64)
{
retregs = pretregs;
if (!(retregs & cgstate.allregs | INSTR.FLOATREGS))
retregs = cgstate.allregs | INSTR.FLOATREGS;
reg = allocreg(cdb,retregs,tym);
code* cr = &cse.csimple;
cr.reg = reg;
cdb.gen(cr);
goto L10;
}
retregs = pretregs;
if (byte_ && !(retregs & BYTEREGS))
retregs = BYTEREGS;
@ -2201,9 +2216,9 @@ private void comsub(ref CodeBuilder cdb,elem* e, ref regm_t pretregs)
{
cgstate.reflocal = true;
cse.flags |= CSEload;
if (pretregs == mPSW) // if result in CCs only
if (pretregs == mPSW && !AArch64) // if result in CCs only
{
if (0 && config.fpxmmregs && (tyxmmreg(cse.e.Ety) || tyvector(cse.e.Ety))) // TODO AArch64
if (config.fpxmmregs && (tyxmmreg(cse.e.Ety) || tyvector(cse.e.Ety)))
{
retregs = XMMREGS;
reg = allocreg(cdb,retregs,tym);
@ -2221,7 +2236,7 @@ private void comsub(ref CodeBuilder cdb,elem* e, ref regm_t pretregs)
else
{
retregs = pretregs;
if (byte_ && !(retregs & BYTEREGS))
if (!AArch64 && byte_ && !(retregs & BYTEREGS))
retregs = BYTEREGS;
reg = allocreg(cdb,retregs,tym);
gen_loadcse(cdb, cse.e.Ety, reg, cse.slot);

View file

@ -2619,12 +2619,20 @@ Lcant:
}
/*************************************************
* Generate code segment to be used later to restore a cse
* Generate instruction to be used later to restore a cse
* Params:
* c = fill in with instruction
* e = examined to see if it can be restored with a simple instruction
* Returns:
* true means it can be so used and c is filled in
*/
@trusted
bool cse_simple(code* c, elem* e)
{
if (cgstate.AArch64)
return false; // TODO AArch64
regm_t regm;
reg_t reg;
int sz = tysize(e.Ety);
@ -2712,9 +2720,6 @@ 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),