mirror of
https://github.com/dlang/dmd.git
synced 2025-04-26 21:21:48 +03:00
Mark SROA with mixed registers with a flag
make two new type flags for SROA `mTYxmmgpr` and `mTYgprxmm`
This commit is contained in:
parent
d7081a3666
commit
31c9754c33
3 changed files with 44 additions and 10 deletions
|
@ -3483,7 +3483,8 @@ elem * elstruct(elem *e, goal_t goal)
|
|||
|
||||
L1:
|
||||
if (ty == TYstruct)
|
||||
{ // This needs to match what TypeFunction::retStyle() does
|
||||
{
|
||||
// This needs to match what TypeFunction::retStyle() does
|
||||
if (config.exe == EX_WIN64)
|
||||
{
|
||||
//if (t.Ttag.Sstruct.Sflags & STRnotpod)
|
||||
|
@ -3508,6 +3509,10 @@ elem * elstruct(elem *e, goal_t goal)
|
|||
tym = TYcdouble;
|
||||
else
|
||||
tym = TYucent;
|
||||
if ((0 == tyfloating(targ1.Tty)) ^ (0 == tyfloating(targ2.Tty)))
|
||||
{
|
||||
tym |= tyfloating(targ1.Tty) ? mTYxmmgpr : mTYgprxmm;
|
||||
}
|
||||
}
|
||||
assert(tym != TYstruct);
|
||||
}
|
||||
|
@ -6040,6 +6045,8 @@ private elem *elToPair(elem *e)
|
|||
*/
|
||||
tym_t ty0;
|
||||
tym_t ty = e.Ety;
|
||||
if (ty & (mTYxmmgpr | mTYgprxmm))
|
||||
break; // register allocation doesn't support it yet.
|
||||
switch (tybasic(ty))
|
||||
{
|
||||
case TYcfloat: ty0 = TYfloat | (ty & ~mTYbasic); goto L1;
|
||||
|
@ -6066,6 +6073,8 @@ private elem *elToPair(elem *e)
|
|||
*/
|
||||
tym_t ty0;
|
||||
tym_t ty = e.Ety;
|
||||
if (ty & (mTYxmmgpr | mTYgprxmm))
|
||||
break; // register allocation doesn't support it yet.
|
||||
switch (tybasic(ty))
|
||||
{
|
||||
case TYcfloat: ty0 = TYfloat | (ty & ~mTYbasic); goto L2;
|
||||
|
|
|
@ -2999,25 +2999,36 @@ int FuncParamRegs_alloc(ref FuncParamRegs fpr, type* t, tym_t ty, reg_t* preg1,
|
|||
type* t2 = null;
|
||||
tym_t ty2 = TYMAX;
|
||||
|
||||
tym_t tyb = tybasic(ty);
|
||||
// SROA with mixed registers
|
||||
if (ty & mTYxmmgpr)
|
||||
{
|
||||
ty = TYdouble;
|
||||
ty2 = TYllong;
|
||||
}
|
||||
else if (ty & mTYgprxmm)
|
||||
{
|
||||
ty = TYllong;
|
||||
ty2 = TYdouble;
|
||||
}
|
||||
|
||||
// Treat array of 1 the same as its element type
|
||||
// (Don't put volatile parameters in registers)
|
||||
if (tyb == TYarray && tybasic(t.Tty) == TYarray && t.Tdim == 1 && !(t.Tty & mTYvolatile)
|
||||
if (tybasic(ty) == TYarray && tybasic(t.Tty) == TYarray && t.Tdim == 1 && !(t.Tty & mTYvolatile)
|
||||
&& type_size(t.Tnext) > 1)
|
||||
{
|
||||
t = t.Tnext;
|
||||
tyb = tybasic(t.Tty);
|
||||
ty = t.Tty;
|
||||
}
|
||||
|
||||
if (tyb == TYstruct && type_zeroSize(t, fpr.tyf))
|
||||
if (tybasic(ty) == TYstruct && type_zeroSize(t, fpr.tyf))
|
||||
return 0; // don't allocate into registers
|
||||
|
||||
++fpr.i;
|
||||
|
||||
// If struct just wraps another type
|
||||
if (tyb == TYstruct && tybasic(t.Tty) == TYstruct)
|
||||
// If struct or array
|
||||
if (tyaggregate(ty))
|
||||
{
|
||||
assert(t);
|
||||
if (config.exe == EX_WIN64)
|
||||
{
|
||||
/* Structs occupy a general purpose register, regardless of the struct
|
||||
|
@ -3079,7 +3090,7 @@ int FuncParamRegs_alloc(ref FuncParamRegs fpr, type* t, tym_t ty, reg_t* preg1,
|
|||
}
|
||||
}
|
||||
|
||||
for (int j = 0; j < 2; j++)
|
||||
foreach (j; 0 .. 2)
|
||||
{
|
||||
if (fpr.regcnt < fpr.numintegerregs)
|
||||
{
|
||||
|
@ -3115,7 +3126,7 @@ int FuncParamRegs_alloc(ref FuncParamRegs fpr, type* t, tym_t ty, reg_t* preg1,
|
|||
return 0;
|
||||
|
||||
Lnext:
|
||||
if (!t2)
|
||||
if (tybasic(ty2) == TYMAX)
|
||||
break;
|
||||
preg = preg2;
|
||||
t = t2;
|
||||
|
@ -3443,7 +3454,17 @@ void cdfunc(ref CodeBuilder cdb, elem* e, regm_t* pretregs)
|
|||
|
||||
tym_t ty1 = tybasic(ep.Ety);
|
||||
tym_t ty2 = ty1;
|
||||
if (ty1 == TYstruct)
|
||||
if (ep.Ety & mTYgprxmm)
|
||||
{
|
||||
ty1 = TYllong;
|
||||
ty2 = TYdouble;
|
||||
}
|
||||
else if (ep.Ety & mTYxmmgpr)
|
||||
{
|
||||
ty1 = TYdouble;
|
||||
ty2 = TYllong;
|
||||
}
|
||||
else if (ty1 == TYstruct)
|
||||
{
|
||||
type* targ1 = ep.ET.Ttag.Sstruct.Sarg1type;
|
||||
type* targ2 = ep.ET.Ttag.Sstruct.Sarg2type;
|
||||
|
|
|
@ -188,6 +188,10 @@ enum
|
|||
mTYshared = 0x00100000, // shared data
|
||||
mTYnothrow = 0x00200000, // nothrow function
|
||||
|
||||
// SROA types
|
||||
mTYxmmgpr = 0x00400000, // first slice in XMM register, the other in GPR
|
||||
mTYgprxmm = 0x00800000, // first slice in GPR register, the other in XMM
|
||||
|
||||
// Used only by C/C++ compiler
|
||||
//#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_DRAGONFLYBSD || TARGET_SOLARIS
|
||||
mTYnoret = 0x01000000, // function has no return
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue