mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 19:48:20 +02:00
Improved sub rewrite, fixed potential load aliasing issues
This commit is contained in:
parent
289d5026c2
commit
ba436231cb
2 changed files with 52 additions and 28 deletions
|
@ -5387,6 +5387,20 @@ X64CPURegister BeMCContext::GetFullRegister(X64CPURegister reg)
|
||||||
return ResizeRegister(reg, 8);
|
return ResizeRegister(reg, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool BeMCContext::HasLoad(const BeMCOperand& operand)
|
||||||
|
{
|
||||||
|
if (operand.mKind == BeMCOperandKind_VRegLoad)
|
||||||
|
return true;
|
||||||
|
if (operand.mKind != BeMCOperandKind_VReg)
|
||||||
|
return false;
|
||||||
|
auto vregInfo = mVRegInfo[operand.mVRegIdx];
|
||||||
|
if (HasLoad(vregInfo->mRelTo))
|
||||||
|
return true;
|
||||||
|
if (HasLoad(vregInfo->mRelOffset))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool BeMCContext::IsAddress(BeMCOperand& operand)
|
bool BeMCContext::IsAddress(BeMCOperand& operand)
|
||||||
{
|
{
|
||||||
if (operand.mKind == BeMCOperandKind_VRegAddr)
|
if (operand.mKind == BeMCOperandKind_VRegAddr)
|
||||||
|
@ -8932,6 +8946,21 @@ bool BeMCContext::DoLegalization()
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((inst->mKind == BeMCInstKind_Sub) && (OperandsEqual(inst->mResult, inst->mArg1)))
|
||||||
|
{
|
||||||
|
// From: b = Sub a, b
|
||||||
|
// To: Neg b
|
||||||
|
// Add b, a
|
||||||
|
AllocInst(BeMCInstKind_Add, inst->mResult, inst->mArg0, instIdx + 1);
|
||||||
|
inst->mKind = BeMCInstKind_Neg;
|
||||||
|
inst->mArg0 = inst->mResult;
|
||||||
|
inst->mArg1 = BeMCOperand();
|
||||||
|
inst->mResult = BeMCOperand();
|
||||||
|
isFinalRun = false;
|
||||||
|
instIdx++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Check operands
|
// Check operands
|
||||||
if ((!inst->IsPsuedo()) && (arg0Type != NULL) && (!arg0Type->IsNonVectorComposite()))
|
if ((!inst->IsPsuedo()) && (arg0Type != NULL) && (!arg0Type->IsNonVectorComposite()))
|
||||||
{
|
{
|
||||||
|
@ -9031,7 +9060,18 @@ bool BeMCContext::DoLegalization()
|
||||||
BeMCOperand savedOperand = BeMCOperand::FromVReg(remappedOperand.mVRegIdx);
|
BeMCOperand savedOperand = BeMCOperand::FromVReg(remappedOperand.mVRegIdx);
|
||||||
BeMCOperand newOperand;
|
BeMCOperand newOperand;
|
||||||
|
|
||||||
if (origOperand.mKind == BeMCOperandKind_VRegLoad)
|
bool replaceLoad = origOperand.mKind == BeMCOperandKind_VRegLoad;
|
||||||
|
|
||||||
|
// If we have a load on both the target and a load on a failed arg then do *not* keep the load-ness of the replaced arg
|
||||||
|
if ((replaceLoad) &&
|
||||||
|
((inst->mArg0 == origOperand) || (inst->mArg1 == origOperand)) &&
|
||||||
|
(HasLoad(inst->mResult)) && (HasLoad((origOperand))))
|
||||||
|
{
|
||||||
|
// This can not only fix further 'bad operand' passes, it can fix aliasing problems
|
||||||
|
replaceLoad = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (replaceLoad)
|
||||||
{
|
{
|
||||||
// Loads keep their load-ness
|
// Loads keep their load-ness
|
||||||
savedOperand = BeMCOperand::FromVReg(remappedOperand.mVRegIdx);
|
savedOperand = BeMCOperand::FromVReg(remappedOperand.mVRegIdx);
|
||||||
|
@ -9309,28 +9349,11 @@ bool BeMCContext::DoLegalization()
|
||||||
{
|
{
|
||||||
bool handled = false;
|
bool handled = false;
|
||||||
if (OperandsEqual(inst->mResult, inst->mArg1))
|
if (OperandsEqual(inst->mResult, inst->mArg1))
|
||||||
{
|
|
||||||
if (inst->mKind == BeMCInstKind_Sub)
|
|
||||||
{
|
|
||||||
// From: b = Sub a, b
|
|
||||||
// To: Neg b
|
|
||||||
// Add b, a
|
|
||||||
AllocInst(BeMCInstKind_Add, inst->mResult, inst->mArg0, instIdx + 1);
|
|
||||||
inst->mKind = BeMCInstKind_Neg;
|
|
||||||
inst->mArg0 = inst->mResult;
|
|
||||||
inst->mArg1 = BeMCOperand();
|
|
||||||
inst->mResult = BeMCOperand();
|
|
||||||
handled = true;
|
|
||||||
|
|
||||||
instIdx--; // Rerun on the Neg
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
// We need a scratch reg for this
|
// We need a scratch reg for this
|
||||||
ReplaceWithNewVReg(inst->mArg1, instIdx, true);
|
ReplaceWithNewVReg(inst->mArg1, instIdx, true);
|
||||||
IntroduceVRegs(inst->mArg1, mcBlock, instIdx, instIdx + 2);
|
IntroduceVRegs(inst->mArg1, mcBlock, instIdx, instIdx + 2);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (!handled)
|
if (!handled)
|
||||||
{
|
{
|
||||||
|
@ -16237,7 +16260,7 @@ void BeMCContext::Generate(BeFunction* function)
|
||||||
mDbgPreferredRegs[32] = X64Reg_R8;*/
|
mDbgPreferredRegs[32] = X64Reg_R8;*/
|
||||||
|
|
||||||
//mDbgPreferredRegs[8] = X64Reg_RAX;
|
//mDbgPreferredRegs[8] = X64Reg_RAX;
|
||||||
mDebugging = (function->mName == "?Main@TestProgram@BeefTest@bf@@SAXPEAV?$Array1@PEAVString@System@bf@@@System@3@@Z");
|
mDebugging = (function->mName == "?MyFunction@MyStruct@BeefTest5@bf@@QEAAXAEAI@Z");
|
||||||
// || (function->mName == "?MethodA@TestProgram@BeefTest@bf@@CAXXZ");
|
// || (function->mName == "?MethodA@TestProgram@BeefTest@bf@@CAXXZ");
|
||||||
// || (function->mName == "?Hey@Blurg@bf@@SAXXZ")
|
// || (function->mName == "?Hey@Blurg@bf@@SAXXZ")
|
||||||
// ;
|
// ;
|
||||||
|
|
|
@ -1433,6 +1433,7 @@ public:
|
||||||
X64CPURegister ResizeRegister(X64CPURegister reg, int numBits);
|
X64CPURegister ResizeRegister(X64CPURegister reg, int numBits);
|
||||||
X64CPURegister ResizeRegister(X64CPURegister reg, BeType* type);
|
X64CPURegister ResizeRegister(X64CPURegister reg, BeType* type);
|
||||||
X64CPURegister GetFullRegister(X64CPURegister reg);
|
X64CPURegister GetFullRegister(X64CPURegister reg);
|
||||||
|
bool HasLoad(const BeMCOperand& operand);
|
||||||
bool IsAddress(BeMCOperand& operand);
|
bool IsAddress(BeMCOperand& operand);
|
||||||
bool IsAddressable(BeMCOperand& operand);
|
bool IsAddressable(BeMCOperand& operand);
|
||||||
bool IsVRegExpr(BeMCOperand& operand);
|
bool IsVRegExpr(BeMCOperand& operand);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue