Extend number of usable variables in assembler block to 32

This commit is contained in:
drmortalwombat 2024-10-05 13:42:39 +02:00
parent 056b49e1d1
commit dadd8eb41c
3 changed files with 60 additions and 16 deletions

View File

@ -210,6 +210,15 @@ void IntegerValueRange::SetLimit(int64 minValue, int64 maxValue)
mMaxValue = maxValue; mMaxValue = maxValue;
} }
void IntegerValueRange::SetBounds(State minState, int64 minValue, State maxState, int64 maxValue)
{
mMinState = minState;
mMinValue = minValue;
mMaxState = maxState;
mMaxValue = maxValue;
}
void IntegerValueRange::Expand(const IntegerValueRange& range) void IntegerValueRange::Expand(const IntegerValueRange& range)
{ {
if (range.mMinState == S_BOUND && mMinState == S_BOUND && range.mMinValue < mMinValue) if (range.mMinState == S_BOUND && mMinState == S_BOUND && range.mMinValue < mMinValue)
@ -2515,8 +2524,22 @@ bool InterInstruction::ReferencesTemp(int temp) const
InterInstruction* InterInstruction::Clone(void) const InterInstruction* InterInstruction::Clone(void) const
{ {
InterInstruction* ins = new InterInstruction(mLocation, mCode); InterInstruction* ins = new InterInstruction(mLocation, mCode);
*ins = *this; ins->mDst = mDst;
ins->mConst = mConst;
ins->mOperator = mOperator;
ins->mNumOperands = mNumOperands;
for (int i = 0; i < mNumOperands; i++)
ins->mSrc[i] = mSrc[i];
ins->mInUse = mInUse;
ins->mInvariant = mInvariant;
ins->mVolatile = mVolatile;
ins->mExpensive = mExpensive;
ins->mSingleAssignment = mSingleAssignment;
ins->mNoSideEffects = mNoSideEffects;
ins->mConstExpr = mConstExpr;
ins->mRemove = false; ins->mRemove = false;
ins->mAliasing = mAliasing;
return ins; return ins;
} }
@ -3898,7 +3921,7 @@ bool InterOperand::IsEqual(const InterOperand& op) const
} }
InterInstruction::InterInstruction(const Location& loc, InterCode code) InterInstruction::InterInstruction(const Location& loc, InterCode code)
: mLocation(loc), mCode(code) : mLocation(loc), mCode(code), mSrc(mOps)
{ {
mOperator = IA_NONE; mOperator = IA_NONE;
@ -3929,7 +3952,10 @@ InterInstruction::InterInstruction(const Location& loc, InterCode code)
case IC_RETURN: case IC_RETURN:
mNumOperands = 0; mNumOperands = 0;
break; break;
case IC_ASSEMBLER:
mSrc = new InterOperand[32];
mNumOperands = 1;
break;
default: default:
mNumOperands = 3; mNumOperands = 3;
break; break;
@ -6148,7 +6174,7 @@ void InterCodeBasicBlock::GenerateTraces(bool expand, bool compact)
mInstructions.Pop(); mInstructions.Pop();
for (i = 0; i < mTrueJump->mInstructions.Size(); i++) for (i = 0; i < mTrueJump->mInstructions.Size(); i++)
mInstructions.Push(new InterInstruction(* (mTrueJump->mInstructions[i]) )); mInstructions.Push(mTrueJump->mInstructions[i]->Clone());
mFalseJump = mTrueJump->mFalseJump; mFalseJump = mTrueJump->mFalseJump;
mTrueJump = mTrueJump->mTrueJump; mTrueJump = mTrueJump->mTrueJump;
@ -15512,7 +15538,7 @@ bool InterCodeBasicBlock::SingleTailLoopOptimization(const NumberSet& aliasedPar
InterInstruction* si = FindSourceInstruction(mLoopPrefix, ai->mDst.mTemp); InterInstruction* si = FindSourceInstruction(mLoopPrefix, ai->mDst.mTemp);
if (si && si->mCode == IC_CONSTANT) if (si && si->mCode == IC_CONSTANT)
{ {
int64 num = (ci->mSrc[0].mIntConst - si->mSrc[0].mIntConst) / ai->mSrc[0].mIntConst; int64 num = (ci->mSrc[0].mIntConst - si->mConst.mIntConst) / ai->mSrc[0].mIntConst;
if (num > 255 && num < 32768) if (num > 255 && num < 32768)
{ {
ai->mSrc[0].mIntConst = 1; ai->mSrc[0].mIntConst = 1;
@ -15583,14 +15609,19 @@ bool InterCodeBasicBlock::SingleTailLoopOptimization(const NumberSet& aliasedPar
i++; i++;
if (i + 1 == body.Size()) if (i + 1 == body.Size())
{ {
int64 num = ci->mSrc[0].mRange.mMaxValue;
InterInstruction* si = FindSourceInstruction(mLoopPrefix, ai->mDst.mTemp); InterInstruction* si = FindSourceInstruction(mLoopPrefix, ai->mDst.mTemp);
if (si && si->mCode == IC_CONSTANT && si->mSrc[0].mIntConst == 0) if (si && si->mCode == IC_CONSTANT && si->mConst.mIntConst >= 0)
{ {
InterInstruction* mins = new InterInstruction(si->mLocation, IC_LOAD_TEMPORARY); int64 num = ci->mSrc[0].mRange.mMaxValue - si->mConst.mIntConst;
mins->mSrc[0] = ci->mSrc[0]; IntegerValueRange::State bound = ci->mSrc[0].mRange.mMaxState;
InterInstruction* mins = new InterInstruction(si->mLocation, IC_BINARY_OPERATOR);
mins->mOperator = IA_SUB;
mins->mSrc[0] = si->mConst;
mins->mSrc[1] = ci->mSrc[0];
mins->mDst = ai->mDst; mins->mDst = ai->mDst;
mins->mDst.mRange.SetBounds(IntegerValueRange::S_BOUND, 1, bound, num);
mLoopPrefix->mInstructions.Insert(mLoopPrefix->mInstructions.Size() - 1, mins); mLoopPrefix->mInstructions.Insert(mLoopPrefix->mInstructions.Size() - 1, mins);
ai->mOperator = IA_SUB; ai->mOperator = IA_SUB;
@ -15600,9 +15631,18 @@ bool InterCodeBasicBlock::SingleTailLoopOptimization(const NumberSet& aliasedPar
ci->mSrc[0].mIntConst = 0; ci->mSrc[0].mIntConst = 0;
ci->mSrc[0].mRange.SetLimit(0, 0); ci->mSrc[0].mRange.SetLimit(0, 0);
ai->mSrc[1].mRange.SetLimit(1, num); for (int k = 0; k < body.Size(); k++)
ai->mDst.mRange.SetLimit(0, num - 1); {
ci->mSrc[1].mRange.SetLimit(0, num - 1); if (body[k]->mEntryValueRange.Size())
body[k]->mEntryValueRange[ai->mSrc[1].mTemp].SetBounds(IntegerValueRange::S_BOUND, 1, bound, num);
}
if (mEntryValueRange.Size())
mEntryValueRange[ai->mSrc[1].mTemp].SetBounds(IntegerValueRange::S_BOUND, 1, bound, num);
ai->mSrc[1].mRange.SetBounds(IntegerValueRange::S_BOUND, 1, bound, num);
ai->mDst.mRange.SetBounds(IntegerValueRange::S_BOUND, 0, bound, num - 1);
ci->mSrc[1].mRange.SetBounds(IntegerValueRange::S_BOUND, 0, bound, num - 1);
modified = true; modified = true;
} }
@ -22825,7 +22865,7 @@ void InterCodeProcedure::Close(void)
{ {
GrowingTypeArray tstack(IT_NONE); GrowingTypeArray tstack(IT_NONE);
CheckFunc = !strcmp(mIdent->mString, "main"); CheckFunc = !strcmp(mIdent->mString, "bar");
CheckCase = false; CheckCase = false;
mEntryBlock = mBlocks[0]; mEntryBlock = mBlocks[0];

View File

@ -177,6 +177,7 @@ public:
void LimitWeak(const IntegerValueRange& range); void LimitWeak(const IntegerValueRange& range);
void MergeUnknown(const IntegerValueRange& range); void MergeUnknown(const IntegerValueRange& range);
void SetLimit(int64 minValue, int64 maxValue); void SetLimit(int64 minValue, int64 maxValue);
void SetBounds(State minState, int64 minValue, State maxState, int64 maxValue);
void SetConstant(int64 value); void SetConstant(int64 value);
bool IsBound(void) const; bool IsBound(void) const;
@ -311,15 +312,18 @@ class InterInstruction
public: public:
Location mLocation; Location mLocation;
InterCode mCode; InterCode mCode;
InterOperand mSrc[12]; InterOperand * mSrc;
InterOperand mDst; InterOperand mDst;
InterOperand mConst; InterOperand mConst;
InterOperator mOperator; InterOperator mOperator;
InterOperand mOps[4];
int mNumOperands; int mNumOperands;
bool mInUse, mInvariant, mVolatile, mExpensive, mSingleAssignment, mNoSideEffects, mConstExpr, mRemove, mAliasing; bool mInUse, mInvariant, mVolatile, mExpensive, mSingleAssignment, mNoSideEffects, mConstExpr, mRemove, mAliasing;
InterInstruction(const Location& loc, InterCode code); InterInstruction(const Location& loc, InterCode code);
InterInstruction(const InterInstruction&) = delete;
InterInstruction& operator=(const InterInstruction&) = delete;
bool IsEqual(const InterInstruction* ins) const; bool IsEqual(const InterInstruction* ins) const;
bool IsEqualSource(const InterInstruction* ins) const; bool IsEqualSource(const InterInstruction* ins) const;

View File

@ -4281,7 +4281,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
lins->mSrc[0].mOperandSize = vdec->mSize; lins->mSrc[0].mOperandSize = vdec->mSize;
block->Append(lins); block->Append(lins);
if (jins->mNumOperands >= 12) if (jins->mNumOperands >= 32)
mErrors->Error(exp->mLocation, EERR_ASSEMBLER_LIMIT, "Maximum number of variables in assembler block exceeded", vdec->mIdent); mErrors->Error(exp->mLocation, EERR_ASSEMBLER_LIMIT, "Maximum number of variables in assembler block exceeded", vdec->mIdent);
else else
{ {