Mark SROA with mixed registers with a flag

make two new type flags for SROA `mTYxmmgpr` and `mTYgprxmm`
This commit is contained in:
سليمان السهمي (Suleyman Sahmi) 2019-06-18 21:28:04 +00:00 committed by Nils Lankila
parent d7081a3666
commit 31c9754c33
3 changed files with 44 additions and 10 deletions

View file

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

View file

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

View file

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