Add restricted pointer attribute to newly allocated memory

This commit is contained in:
drmortalwombat 2023-10-13 11:18:16 +02:00
parent 2027ac5d4c
commit ecf8e69cf2
6 changed files with 306 additions and 28 deletions

View File

@ -10,7 +10,7 @@ static const char AndBeyond[] = "And Beyond";
static const char And[] = "And"; static const char And[] = "And";
static const char HelloWorldAndBeyond[] = "Hello World And Beyond"; static const char HelloWorldAndBeyond[] = "Hello World And Beyond";
void test_create(void) __noinline void test_create(void)
{ {
string s1(); string s1();
string s2(HelloWorld); string s2(HelloWorld);
@ -22,7 +22,7 @@ void test_create(void)
assert(s4.size() == 1 && s4[0] == 'a'); assert(s4.size() == 1 && s4[0] == 'a');
} }
void test_concat(void) __noinline void test_concat(void)
{ {
string s1(); string s1();
string s2(HelloWorld); string s2(HelloWorld);
@ -51,7 +51,7 @@ __noinline void test_find(void)
assert(s1.find(' ', 6) == 11); assert(s1.find(' ', 6) == 11);
} }
void test_assign(void) __noinline void test_assign(void)
{ {
string s1(HelloWorld); string s1(HelloWorld);
string s2(AndBeyond); string s2(AndBeyond);
@ -77,9 +77,12 @@ void test_assign(void)
assert(!strcmp(s3.tocstr(), HelloWorld)); assert(!strcmp(s3.tocstr(), HelloWorld));
} }
static char * test;
int main(void) int main(void)
{ {
char * p = new char; test = new char;
unsigned avail = heapfree(); unsigned avail = heapfree();
test_create(); test_create();
@ -94,5 +97,7 @@ int main(void)
test_assign(); test_assign();
assert(avail == heapfree()); assert(avail == heapfree());
delete test;
return 0; return 0;
} }

View File

@ -5,6 +5,7 @@
#include <math.h> #include <math.h>
static bool CheckFunc; static bool CheckFunc;
static bool CheckCase;
int InterTypeSize[] = { int InterTypeSize[] = {
0, 0,
@ -445,7 +446,9 @@ bool InterCodeBasicBlock::CollidingMem(const InterOperand& op1, InterType type1,
{ {
if (op1.mMemory == IM_INDIRECT) if (op1.mMemory == IM_INDIRECT)
{ {
if (op2.mMemory == IM_GLOBAL) if (op1.mRestricted)
return false;
else if (op2.mMemory == IM_GLOBAL)
return mProc->mModule->mGlobalVars[op2.mVarIndex]->mAliased; return mProc->mModule->mGlobalVars[op2.mVarIndex]->mAliased;
else if (op2.mMemory == IM_FPARAM || op2.mMemory == IM_FFRAME) else if (op2.mMemory == IM_FPARAM || op2.mMemory == IM_FFRAME)
return false; return false;
@ -456,7 +459,9 @@ bool InterCodeBasicBlock::CollidingMem(const InterOperand& op1, InterType type1,
} }
else if (op2.mMemory == IM_INDIRECT) else if (op2.mMemory == IM_INDIRECT)
{ {
if (op1.mMemory == IM_GLOBAL) if (op2.mRestricted)
return false;
else if (op1.mMemory == IM_GLOBAL)
return mProc->mModule->mGlobalVars[op1.mVarIndex]->mAliased; return mProc->mModule->mGlobalVars[op1.mVarIndex]->mAliased;
else if (op1.mMemory == IM_FPARAM || op1.mMemory == IM_FFRAME) else if (op1.mMemory == IM_FPARAM || op1.mMemory == IM_FFRAME)
return false; return false;
@ -487,6 +492,8 @@ bool InterCodeBasicBlock::CollidingMem(const InterOperand& op1, InterType type1,
return op1.mIntConst < op2.mIntConst + op2.mOperandSize && op2.mIntConst < op1.mIntConst + op1.mOperandSize; return op1.mIntConst < op2.mIntConst + op2.mOperandSize && op2.mIntConst < op1.mIntConst + op1.mOperandSize;
else if (op1.mLinkerObject && op2.mLinkerObject && op1.mLinkerObject != op2.mLinkerObject) else if (op1.mLinkerObject && op2.mLinkerObject && op1.mLinkerObject != op2.mLinkerObject)
return false; return false;
else if (op1.mRestricted && op2.mRestricted && op1.mRestricted != op2.mRestricted)
return false;
else else
return CollidingMemType(type1, type2); return CollidingMemType(type1, type2);
default: default:
@ -1235,12 +1242,12 @@ void ValueSet::InsertValue(InterInstruction * ins)
static bool HasSideEffect(InterCode code) static bool HasSideEffect(InterCode code)
{ {
return code == IC_CALL || code == IC_CALL_NATIVE || code == IC_ASSEMBLER || code == IC_MALLOC || code == IC_FREE; return code == IC_CALL || code == IC_CALL_NATIVE || code == IC_ASSEMBLER || code == IC_DISPATCH /* || code == IC_MALLOC || code == IC_FREE */;
} }
static bool IsObservable(InterCode code) static bool IsObservable(InterCode code)
{ {
return code == IC_CALL || code == IC_CALL_NATIVE || code == IC_ASSEMBLER || code == IC_STORE || code == IC_COPY || code == IC_STRCPY || code == IC_MALLOC || code == IC_FREE; return code == IC_CALL || code == IC_CALL_NATIVE || code == IC_ASSEMBLER || code == IC_DISPATCH || code == IC_STORE || code == IC_COPY || code == IC_STRCPY || code == IC_MALLOC || code == IC_FREE;
} }
static bool IsMoveable(InterCode code) static bool IsMoveable(InterCode code)
@ -2900,7 +2907,7 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr
InterOperand::InterOperand(void) InterOperand::InterOperand(void)
: mTemp(INVALID_TEMPORARY), mType(IT_NONE), mFinal(false), mIntConst(0), mFloatConst(0), mVarIndex(-1), mOperandSize(0), mLinkerObject(nullptr), mMemory(IM_NONE), mStride(1) : mTemp(INVALID_TEMPORARY), mType(IT_NONE), mFinal(false), mIntConst(0), mFloatConst(0), mVarIndex(-1), mOperandSize(0), mLinkerObject(nullptr), mMemory(IM_NONE), mStride(1), mRestricted(0)
{} {}
bool InterOperand::IsNotUByte(void) const bool InterOperand::IsNotUByte(void) const
@ -2967,6 +2974,7 @@ void InterOperand::ForwardMem(const InterOperand& op)
mType = op.mType; mType = op.mType;
mRange = op.mRange; mRange = op.mRange;
mStride = op.mStride; mStride = op.mStride;
mRestricted = op.mRestricted;
mFinal = false; mFinal = false;
} }
@ -4335,7 +4343,12 @@ void InterOperand::Disassemble(FILE* file, InterCodeProcedure* proc)
fprintf(file, "R%d(%c)", mTemp, typechars[mType]); fprintf(file, "R%d(%c)", mTemp, typechars[mType]);
if (mType == IT_POINTER && mMemory == IM_INDIRECT) if (mType == IT_POINTER && mMemory == IM_INDIRECT)
{
fprintf(file, "+%d", int(mIntConst)); fprintf(file, "+%d", int(mIntConst));
}
if (mRestricted)
fprintf(file, "{%d}", mRestricted);
if (mRange.mMinState >= IntegerValueRange::S_WEAK || mRange.mMaxState >= IntegerValueRange::S_WEAK) if (mRange.mMinState >= IntegerValueRange::S_WEAK || mRange.mMaxState >= IntegerValueRange::S_WEAK)
{ {
@ -4811,6 +4824,22 @@ void InterCodeBasicBlock::GenerateTraces(bool expand, bool compact)
// Limit number of contractions // Limit number of contractions
for (int i = 0; i < 100; i++) for (int i = 0; i < 100; i++)
{ {
int sz = mInstructions.Size();
if (mFalseJump && sz > 0 && mInstructions[sz - 1]->mCode == IC_BRANCH && mInstructions[sz - 1]->mSrc[0].mType == IT_BOOL && mInstructions[sz - 1]->mSrc[0].mTemp < 0)
{
mInstructions[sz - 1]->mCode = IC_JUMP;
mInstructions[sz - 1]->mNumOperands = 0;
if (!mInstructions[sz - 1]->mSrc[0].mIntConst)
{
mTrueJump->mNumEntries--;
mTrueJump = mFalseJump;
}
else
mFalseJump->mNumEntries--;
mFalseJump = nullptr;
}
if (mTrueJump && mTrueJump->mInstructions.Size() == 1 && mTrueJump->mInstructions[0]->mCode == IC_JUMP && !mTrueJump->mLoopHead && mTrueJump->mTraceIndex != mIndex) if (mTrueJump && mTrueJump->mInstructions.Size() == 1 && mTrueJump->mInstructions[0]->mCode == IC_JUMP && !mTrueJump->mLoopHead && mTrueJump->mTraceIndex != mIndex)
{ {
mTrueJump->mTraceIndex = mIndex; mTrueJump->mTraceIndex = mIndex;
@ -5123,6 +5152,7 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction * ins, const GrowingI
break; break;
} }
} }
break; break;
case IC_LOAD: case IC_LOAD:
@ -5149,6 +5179,7 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction * ins, const GrowingI
break; break;
} }
} }
OptimizeAddress(ins, tvalue, 1); OptimizeAddress(ins, tvalue, 1);
break; break;
case IC_COPY: case IC_COPY:
@ -6204,6 +6235,10 @@ void InterCodeBasicBlock::SimplifyIntegerRangeRelops(void)
{ {
constFalse = true; constFalse = true;
} }
else if (cins->mSrc[1].IsUnsigned() && cins->mSrc[1].mRange.mMaxValue == 0)
{
constFalse = true;
}
else if (cins->mSrc[1].IsUnsigned() && cins->mSrc[0].IsUnsigned()) else if (cins->mSrc[1].IsUnsigned() && cins->mSrc[0].IsUnsigned())
{ {
if (cins->mSrc[1].mRange.mMinValue > cins->mSrc[0].mRange.mMaxValue) if (cins->mSrc[1].mRange.mMinValue > cins->mSrc[0].mRange.mMaxValue)
@ -10172,6 +10207,7 @@ bool InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray&
{ {
ins->mCode = IC_LOAD_TEMPORARY; ins->mCode = IC_LOAD_TEMPORARY;
ins->mSrc[0] = lins->mDst; ins->mSrc[0] = lins->mDst;
ins->mSrc[0].mRestricted = ins->mDst.mRestricted = lins->mDst.mRestricted;
ins->mNumOperands = 1; ins->mNumOperands = 1;
assert(ins->mSrc[0].mTemp >= 0); assert(ins->mSrc[0].mTemp >= 0);
changed = true; changed = true;
@ -10189,6 +10225,7 @@ bool InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray&
{ {
ins->mCode = IC_LOAD_TEMPORARY; ins->mCode = IC_LOAD_TEMPORARY;
ins->mSrc[0] = lins->mSrc[0]; ins->mSrc[0] = lins->mSrc[0];
ins->mSrc[0].mRestricted = ins->mDst.mRestricted = lins->mSrc[0].mRestricted;
ins->mDst.mRange.Limit(ins->mSrc[0].mRange); ins->mDst.mRange.Limit(ins->mSrc[0].mRange);
ins->mNumOperands = 1; ins->mNumOperands = 1;
assert(ins->mSrc[0].mTemp >= 0); assert(ins->mSrc[0].mTemp >= 0);
@ -10252,6 +10289,7 @@ bool InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray&
assert(lins->mDst.mTemp >= 0); assert(lins->mDst.mTemp >= 0);
ins->mCode = IC_LOAD_TEMPORARY; ins->mCode = IC_LOAD_TEMPORARY;
ins->mSrc[0] = lins->mDst; ins->mSrc[0] = lins->mDst;
ins->mSrc[0].mRestricted = ins->mDst.mRestricted = lins->mDst.mRestricted;
ins->mDst.mRange.Limit(ins->mSrc[0].mRange); ins->mDst.mRange.Limit(ins->mSrc[0].mRange);
ins->mNumOperands = 1; ins->mNumOperands = 1;
changed = true; changed = true;
@ -10396,6 +10434,8 @@ void InterCodeBasicBlock::LocalRenameRegister(const GrowingIntArray& renameTable
} }
} }
RenameValueRanges(mEntryRenameTable, num);
for (i = 0; i < mInstructions.Size(); i++) for (i = 0; i < mInstructions.Size(); i++)
{ {
mInstructions[i]->LocalRenameRegister(mExitRenameTable, num); mInstructions[i]->LocalRenameRegister(mExitRenameTable, num);
@ -10440,11 +10480,29 @@ void InterCodeBasicBlock::GlobalRenameRegister(const GrowingIntArray& renameTabl
mInstructions[i]->GlobalRenameRegister(renameTable, temporaries); mInstructions[i]->GlobalRenameRegister(renameTable, temporaries);
} }
RenameValueRanges(renameTable, temporaries.Size());
if (mTrueJump) mTrueJump->GlobalRenameRegister(renameTable, temporaries); if (mTrueJump) mTrueJump->GlobalRenameRegister(renameTable, temporaries);
if (mFalseJump) mFalseJump->GlobalRenameRegister(renameTable, temporaries); if (mFalseJump) mFalseJump->GlobalRenameRegister(renameTable, temporaries);
} }
} }
void InterCodeBasicBlock::RenameValueRanges(const GrowingIntArray& renameTable, int numTemps)
{
if (mEntryValueRange.Size() > 0)
{
mLocalValueRange = mEntryValueRange;
mEntryValueRange.SetSize(numTemps, true);
for (int i = 0; i < mLocalValueRange.Size(); i++)
{
if (renameTable[i] >= 0)
{
mEntryValueRange[renameTable[i]].Limit(mLocalValueRange[i]);
}
}
}
}
void InterCodeBasicBlock::BuildCollisionTable(NumberSet* collisionSets) void InterCodeBasicBlock::BuildCollisionTable(NumberSet* collisionSets)
{ {
if (!mVisited) if (!mVisited)
@ -13235,6 +13293,139 @@ bool InterCodeBasicBlock::CheapInlining(int & numTemps)
return changed; return changed;
} }
void InterCodeBasicBlock::RemoveUnusedMallocs(void)
{
if (!mVisited)
{
mVisited = true;
for (int i = 0; i < mInstructions.Size(); i++)
{
InterInstruction* mins = mInstructions[i];
if (mins->mCode == IC_MALLOC)
{
int mtemp = mins->mDst.mTemp;
bool used = false;
int j = i + 1;
while (j < mInstructions.Size() && !used)
{
InterInstruction* fins = mInstructions[j];
if (fins->mCode == IC_FREE && fins->mSrc[0].mTemp == mtemp)
break;
if (fins->ReferencesTemp(mtemp))
{
if (fins->mCode != IC_STORE || fins->mSrc[1].mTemp != mtemp)
used = true;
}
j++;
}
if (j < mInstructions.Size() && !used)
{
mins->mCode = IC_NONE; mins->mNumOperands = 0;
for (int k = i + 1; k <= j; k++)
{
InterInstruction* lins = mInstructions[k];
if (lins->UsesTemp(mtemp))
{
lins->mCode = IC_NONE;
lins->mNumOperands = 0;
}
}
}
}
}
if (mTrueJump) mTrueJump->RemoveUnusedMallocs();
if (mFalseJump) mFalseJump->RemoveUnusedMallocs();
}
}
void InterCodeBasicBlock::PropagateMemoryAliasingInfo(const GrowingInstructionPtrArray& tvalue)
{
if (!mVisited)
{
GrowingInstructionPtrArray ltvalue(tvalue);
if (mLoopHead)
{
if (mNumEntries == 2 && (mTrueJump == this || mFalseJump == this))
{
for (int i = 0; i < ltvalue.Size(); i++)
{
if (ltvalue[i])
{
for (int j = 0; j < mInstructions.Size(); j++)
{
if (mInstructions[j]->mDst.mTemp == i)
{
if (mInstructions[j]->mCode == IC_LEA && mInstructions[j]->mSrc[1].mTemp == i)
;
else
{
ltvalue[i] = nullptr;
break;
}
}
}
}
}
}
else
ltvalue.Clear();
}
else if (mNumEntries > 0)
{
if (mNumEntered > 0)
{
for (int i = 0; i < ltvalue.Size(); i++)
{
if (mMergeTValues[i] != ltvalue[i])
ltvalue[i] = nullptr;
}
}
mNumEntered++;
if (mNumEntered < mNumEntries)
{
mMergeTValues = ltvalue;
return;
}
}
mVisited = true;
for (int i = 0; i < mInstructions.Size(); i++)
{
InterInstruction* ins = mInstructions[i];
for (int j = 0; j < ins->mNumOperands; j++)
{
if (ins->mSrc[j].mTemp > 0 && ltvalue[ins->mSrc[j].mTemp] && ins->mSrc[j].mType == IT_POINTER)
ins->mSrc[j].mRestricted = ltvalue[ins->mSrc[j].mTemp]->mDst.mRestricted;
}
if (ins->mDst.mTemp >= 0)
{
if (ins->mDst.mRestricted)
ltvalue[ins->mDst.mTemp] = ins;
else
ltvalue[ins->mDst.mTemp] = nullptr;
}
if (ins->mCode == IC_LEA)
ins->mDst.mRestricted = ins->mSrc[1].mRestricted;
else if (ins->mCode == IC_LOAD_TEMPORARY)
ins->mDst.mRestricted = ins->mSrc[0].mRestricted;
}
if (mTrueJump) mTrueJump->PropagateMemoryAliasingInfo(ltvalue);
if (mFalseJump) mFalseJump->PropagateMemoryAliasingInfo(ltvalue);
}
}
void InterCodeBasicBlock::PushMoveOutOfLoop(void) void InterCodeBasicBlock::PushMoveOutOfLoop(void)
{ {
@ -16570,7 +16761,8 @@ InterCodeProcedure::InterCodeProcedure(InterCodeModule * mod, const Location & l
mInterrupt(false), mHardwareInterrupt(false), mCompiled(false), mInterruptCalled(false), mDynamicStack(false), mAssembled(false), mInterrupt(false), mHardwareInterrupt(false), mCompiled(false), mInterruptCalled(false), mDynamicStack(false), mAssembled(false),
mSaveTempsLinkerObject(nullptr), mValueReturn(false), mFramePointer(false), mSaveTempsLinkerObject(nullptr), mValueReturn(false), mFramePointer(false),
mCheckUnreachable(true), mReturnType(IT_NONE), mCheapInline(false), mCheckUnreachable(true), mReturnType(IT_NONE), mCheapInline(false),
mDeclaration(nullptr), mGlobalsChecked(false), mDispatchedCall(false) mDeclaration(nullptr), mGlobalsChecked(false), mDispatchedCall(false),
mNumRestricted(1)
{ {
mID = mModule->mProcedures.Size(); mID = mModule->mProcedures.Size();
mModule->mProcedures.Push(this); mModule->mProcedures.Push(this);
@ -16636,6 +16828,11 @@ int InterCodeProcedure::AddTemporary(InterType type)
return temp; return temp;
} }
int InterCodeProcedure::AddRestricted(void)
{
return mNumRestricted++;
}
void InterCodeProcedure::CheckBlocks(void) void InterCodeProcedure::CheckBlocks(void)
{ {
ResetVisited(); ResetVisited();
@ -16699,6 +16896,10 @@ void InterCodeProcedure::BuildTraces(bool expand, bool dominators, bool compact)
mBlocks[i]->mNumEntries = 0; mBlocks[i]->mNumEntries = 0;
mEntryBlock->CollectEntries(); mEntryBlock->CollectEntries();
ResetEntryBlocks();
ResetVisited();
mEntryBlock->CollectEntryBlocks(nullptr);
ResetVisited(); ResetVisited();
for (int i = 0; i < mBlocks.Size(); i++) for (int i = 0; i < mBlocks.Size(); i++)
mBlocks[i]->mDominator = nullptr; mBlocks[i]->mDominator = nullptr;
@ -16875,6 +17076,17 @@ void InterCodeProcedure::CheckUsedDefinedTemps(void)
#endif #endif
} }
void InterCodeProcedure::PropagateMemoryAliasingInfo(void)
{
GrowingInstructionPtrArray tvalue(nullptr);
ResetVisited();
mEntryBlock->PropagateMemoryAliasingInfo(tvalue);
Disassemble("PropagateMemoryAliasingInfo");
}
void InterCodeProcedure::WarnUsedUndefinedVariables(void) void InterCodeProcedure::WarnUsedUndefinedVariables(void)
{ {
ResetEntryBlocks(); ResetEntryBlocks();
@ -17350,6 +17562,8 @@ void InterCodeProcedure::LoadStoreForwarding(InterMemory paramMemory)
bool changed; bool changed;
do { do {
PropagateMemoryAliasingInfo();
GrowingInstructionPtrArray gipa(nullptr); GrowingInstructionPtrArray gipa(nullptr);
ResetVisited(); ResetVisited();
changed = mEntryBlock->LoadStoreForwarding(gipa, mModule->mGlobalVars); changed = mEntryBlock->LoadStoreForwarding(gipa, mModule->mGlobalVars);
@ -17358,11 +17572,15 @@ void InterCodeProcedure::LoadStoreForwarding(InterMemory paramMemory)
RemoveUnusedStoreInstructions(paramMemory); RemoveUnusedStoreInstructions(paramMemory);
GlobalConstantPropagation();
RemoveUnusedMallocs();
TempForwarding(); TempForwarding();
RemoveUnusedInstructions(); RemoveUnusedInstructions();
DisassembleDebug("Load/Store forwarding"); DisassembleDebug("Load/Store forwarding");
} while (changed); } while (changed);
} }
void InterCodeProcedure::CombineIndirectAddressing(void) void InterCodeProcedure::CombineIndirectAddressing(void)
@ -17434,7 +17652,8 @@ void InterCodeProcedure::Close(void)
{ {
GrowingTypeArray tstack(IT_NONE); GrowingTypeArray tstack(IT_NONE);
CheckFunc = !strcmp(mIdent->mString, "main"); CheckFunc = !strcmp(mIdent->mString, "atoi");
CheckCase = false;
mEntryBlock = mBlocks[0]; mEntryBlock = mBlocks[0];
@ -17589,6 +17808,8 @@ void InterCodeProcedure::Close(void)
BuildDataFlowSets(); BuildDataFlowSets();
LoadStoreForwarding(paramMemory);
ResetVisited(); ResetVisited();
mEntryBlock->OptimizeIntervalCompare(); mEntryBlock->OptimizeIntervalCompare();
@ -17725,6 +17946,9 @@ void InterCodeProcedure::Close(void)
Disassemble("gcp-"); Disassemble("gcp-");
#endif #endif
BuildTraces(false);
DisassembleDebug("Rebuilt traces");
BuildDataFlowSets(); BuildDataFlowSets();
TempForwarding(); TempForwarding();
@ -17762,16 +17986,12 @@ void InterCodeProcedure::Close(void)
ResetVisited(); ResetVisited();
mEntryBlock->SimplifyIntegerRangeRelops(); mEntryBlock->SimplifyIntegerRangeRelops();
DisassembleDebug("Simplified range limited relational ops"); DisassembleDebug("Simplified range limited relational ops 1");
#endif #endif
BuildTraces(false); BuildTraces(false);
DisassembleDebug("Rebuilt traces"); DisassembleDebug("Rebuilt traces");
ResetEntryBlocks();
ResetVisited();
mEntryBlock->CollectEntryBlocks(nullptr);
#if 1 #if 1
SimplifyIntegerNumeric(activeSet); SimplifyIntegerNumeric(activeSet);
@ -17844,9 +18064,6 @@ void InterCodeProcedure::Close(void)
#endif #endif
BuildTraces(false); BuildTraces(false);
ResetEntryBlocks();
ResetVisited();
mEntryBlock->CollectEntryBlocks(nullptr);
#if 1 #if 1
SingleBlockLoopPointerSplit(activeSet); SingleBlockLoopPointerSplit(activeSet);
@ -17927,7 +18144,7 @@ void InterCodeProcedure::Close(void)
ResetVisited(); ResetVisited();
mEntryBlock->SimplifyIntegerRangeRelops(); mEntryBlock->SimplifyIntegerRangeRelops();
DisassembleDebug("Simplified range limited relational ops"); DisassembleDebug("Simplified range limited relational ops 2");
#endif #endif
#if 1 #if 1
@ -17980,6 +18197,10 @@ void InterCodeProcedure::Close(void)
LoadStoreForwarding(paramMemory); LoadStoreForwarding(paramMemory);
CheckCase = true;
RebuildIntegerRangeSet();
#if 1 #if 1
BuildLoopPrefix(); BuildLoopPrefix();
DisassembleDebug("added dominators"); DisassembleDebug("added dominators");
@ -18046,6 +18267,8 @@ void InterCodeProcedure::Close(void)
mEntryBlock->CollectEntryBlocks(nullptr); mEntryBlock->CollectEntryBlocks(nullptr);
BuildTraces(false); BuildTraces(false);
BuildDataFlowSets();
BuildTraces(false);
#endif #endif
PropagateConstOperationsUp(); PropagateConstOperationsUp();
@ -18057,6 +18280,11 @@ void InterCodeProcedure::Close(void)
#endif #endif
ResetVisited();
mEntryBlock->SimplifyIntegerRangeRelops();
DisassembleDebug("Simplified range limited relational ops 3");
#if 1 #if 1
BuildDataFlowSets(); BuildDataFlowSets();
@ -18111,7 +18339,7 @@ void InterCodeProcedure::Close(void)
ResetVisited(); ResetVisited();
mEntryBlock->SingleBlockLoopOptimisation(mParamAliasedSet, mModule->mGlobalVars); mEntryBlock->SingleBlockLoopOptimisation(mParamAliasedSet, mModule->mGlobalVars);
DisassembleDebug("single block loop opt 3"); DisassembleDebug("single block loop opt 4");
BuildDataFlowSets(); BuildDataFlowSets();
@ -18130,6 +18358,8 @@ void InterCodeProcedure::Close(void)
TempForwarding(); TempForwarding();
} while (GlobalConstantPropagation()); } while (GlobalConstantPropagation());
BuildTraces(false);
DisassembleDebug("Rebuilt traces");
PeepholeOptimization(); PeepholeOptimization();
TempForwarding(); TempForwarding();
@ -18158,8 +18388,14 @@ void InterCodeProcedure::Close(void)
CombineIndirectAddressing(); CombineIndirectAddressing();
#if 1 #if 1
for (int i = 0; i < 4; i++) for (int i = 0; i < 8; i++)
{ {
BuildTraces(false);
LoadStoreForwarding(paramMemory);
RebuildIntegerRangeSet();
PeepholeOptimization(); PeepholeOptimization();
DisassembleDebug("Peephole Temp Check"); DisassembleDebug("Peephole Temp Check");
@ -18793,6 +19029,12 @@ bool InterCodeProcedure::GlobalConstantPropagation(void)
return mEntryBlock->PropagateConstTemps(ctemps); return mEntryBlock->PropagateConstTemps(ctemps);
} }
void InterCodeProcedure::RemoveUnusedMallocs(void)
{
ResetVisited();
mEntryBlock->RemoveUnusedMallocs();
}
void InterCodeProcedure::HoistCommonConditionalPath(void) void InterCodeProcedure::HoistCommonConditionalPath(void)
{ {
for(;;) for(;;)

View File

@ -265,7 +265,7 @@ public:
bool mFinal; bool mFinal;
int64 mIntConst; int64 mIntConst;
double mFloatConst; double mFloatConst;
int mVarIndex, mOperandSize, mStride; int mVarIndex, mOperandSize, mStride, mRestricted;
LinkerObject * mLinkerObject; LinkerObject * mLinkerObject;
InterMemory mMemory; InterMemory mMemory;
IntegerValueRange mRange; IntegerValueRange mRange;
@ -457,6 +457,7 @@ public:
void LocalRenameRegister(const GrowingIntArray& renameTable, int& num); void LocalRenameRegister(const GrowingIntArray& renameTable, int& num);
void BuildGlobalRenameRegisterTable(const GrowingIntArray& renameTable, GrowingIntArray& globalRenameTable); void BuildGlobalRenameRegisterTable(const GrowingIntArray& renameTable, GrowingIntArray& globalRenameTable);
void GlobalRenameRegister(const GrowingIntArray& renameTable, GrowingTypeArray& temporaries); void GlobalRenameRegister(const GrowingIntArray& renameTable, GrowingTypeArray& temporaries);
void RenameValueRanges(const GrowingIntArray& renameTable, int numTemps);
void CheckValueUsage(InterInstruction * ins, const GrowingInstructionPtrArray& tvalue, const GrowingVariableArray& staticVars, FastNumberSet& fsingle); void CheckValueUsage(InterInstruction * ins, const GrowingInstructionPtrArray& tvalue, const GrowingVariableArray& staticVars, FastNumberSet& fsingle);
void PerformTempForwarding(const TempForwardingTable& forwardingTable, bool reverse, bool checkloops); void PerformTempForwarding(const TempForwardingTable& forwardingTable, bool reverse, bool checkloops);
@ -556,6 +557,9 @@ public:
void InnerLoopOptimization(const NumberSet& aliasedParams); void InnerLoopOptimization(const NumberSet& aliasedParams);
void PushMoveOutOfLoop(void); void PushMoveOutOfLoop(void);
void PropagateMemoryAliasingInfo(const GrowingInstructionPtrArray& tvalue);
void RemoveUnusedMallocs(void);
bool CollectSingleHeadLoopBody(InterCodeBasicBlock* head, InterCodeBasicBlock* tail, GrowingArray<InterCodeBasicBlock*>& body); bool CollectSingleHeadLoopBody(InterCodeBasicBlock* head, InterCodeBasicBlock* tail, GrowingArray<InterCodeBasicBlock*>& body);
bool SingleTailLoopOptimization(const NumberSet& aliasedParams, const GrowingVariableArray& staticVars); bool SingleTailLoopOptimization(const NumberSet& aliasedParams, const GrowingVariableArray& staticVars);
@ -603,7 +607,7 @@ public:
GrowingInterCodeBasicBlockPtrArray mBlocks; GrowingInterCodeBasicBlockPtrArray mBlocks;
GrowingTypeArray mTemporaries; GrowingTypeArray mTemporaries;
GrowingIntArray mTempOffset, mTempSizes; GrowingIntArray mTempOffset, mTempSizes;
int mTempSize, mCommonFrameSize, mCallerSavedTemps, mFreeCallerSavedTemps, mFastCallBase; int mTempSize, mCommonFrameSize, mCallerSavedTemps, mFreeCallerSavedTemps, mFastCallBase, mNumRestricted;
bool mLeafProcedure, mNativeProcedure, mCallsFunctionPointer, mHasDynamicStack, mHasInlineAssembler, mCallsByteCode, mFastCallProcedure; bool mLeafProcedure, mNativeProcedure, mCallsFunctionPointer, mHasDynamicStack, mHasInlineAssembler, mCallsByteCode, mFastCallProcedure;
bool mInterrupt, mHardwareInterrupt, mCompiled, mInterruptCalled, mValueReturn, mFramePointer, mDynamicStack, mAssembled; bool mInterrupt, mHardwareInterrupt, mCompiled, mInterruptCalled, mValueReturn, mFramePointer, mDynamicStack, mAssembled;
bool mDispatchedCall; bool mDispatchedCall;
@ -633,6 +637,7 @@ public:
~InterCodeProcedure(void); ~InterCodeProcedure(void);
int AddTemporary(InterType type); int AddTemporary(InterType type);
int AddRestricted(void);
void Close(void); void Close(void);
@ -682,10 +687,12 @@ protected:
void CombineIndirectAddressing(void); void CombineIndirectAddressing(void);
void SingleTailLoopOptimization(InterMemory paramMemory); void SingleTailLoopOptimization(InterMemory paramMemory);
void HoistCommonConditionalPath(void); void HoistCommonConditionalPath(void);
void RemoveUnusedMallocs(void);
void MergeBasicBlocks(void); void MergeBasicBlocks(void);
void CheckUsedDefinedTemps(void); void CheckUsedDefinedTemps(void);
void WarnUsedUndefinedVariables(void); void WarnUsedUndefinedVariables(void);
void PropagateMemoryAliasingInfo(void);
void PeepholeOptimization(void); void PeepholeOptimization(void);

View File

@ -2916,6 +2916,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
ins->mSrc[0].mTemp = vl.mTemp; ins->mSrc[0].mTemp = vl.mTemp;
ins->mDst.mType = IT_POINTER; ins->mDst.mType = IT_POINTER;
ins->mDst.mTemp = proc->AddTemporary(ins->mDst.mType); ins->mDst.mTemp = proc->AddTemporary(ins->mDst.mType);
ins->mDst.mRestricted = proc->AddRestricted();
block->Append(ins); block->Append(ins);
return ExValue(exp->mDecType, ins->mDst.mTemp, 0); return ExValue(exp->mDecType, ins->mDst.mTemp, 0);
@ -3141,6 +3142,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
ins->mNumOperands = 1; ins->mNumOperands = 1;
ins->mDst.mType = IT_POINTER; ins->mDst.mType = IT_POINTER;
ins->mDst.mTemp = proc->AddTemporary(ins->mDst.mType); ins->mDst.mTemp = proc->AddTemporary(ins->mDst.mType);
ins->mDst.mRestricted = proc->AddRestricted();
block->Append(ins); block->Append(ins);
return ExValue(TheVoidPointerTypeDeclaration, ins->mDst.mTemp); return ExValue(TheVoidPointerTypeDeclaration, ins->mDst.mTemp);

View File

@ -32138,7 +32138,7 @@ bool NativeCodeBasicBlock::OptimizeGenericLoop(NativeCodeProcedure* proc)
ExpandingArray<NativeCodeBasicBlock*> lblocks; ExpandingArray<NativeCodeBasicBlock*> lblocks;
proc->ResetPatched(); proc->ResetPatched();
if (CollectGenericLoop(proc, lblocks)) if (CollectSingleEntryGenericLoop(proc, lblocks))
{ {
int yreg = -1, xreg = -1, areg = -1; int yreg = -1, xreg = -1, areg = -1;
int zyreg[NUM_REGS], zxreg[NUM_REGS], zareg[NUM_REGS]; int zyreg[NUM_REGS], zxreg[NUM_REGS], zareg[NUM_REGS];
@ -32777,6 +32777,28 @@ bool NativeCodeBasicBlock::CollectGenericLoop(NativeCodeProcedure* proc, Expandi
return lblocks.Size() > 0; return lblocks.Size() > 0;
} }
bool NativeCodeBasicBlock::CollectSingleEntryGenericLoop(NativeCodeProcedure* proc, ExpandingArray<NativeCodeBasicBlock*>& lblocks)
{
if (CollectGenericLoop(proc, lblocks))
{
for (int i = 0; i < lblocks.Size(); i++)
{
NativeCodeBasicBlock* block = lblocks[i];
if (block != this)
{
for (int j = 0; j < block->mEntryBlocks.Size(); j++)
if (!lblocks.Contains(block->mEntryBlocks[j]))
return false;
}
}
return true;
}
else
return false;
}
bool NativeCodeBasicBlock::OptimizeFindLoop(NativeCodeProcedure* proc) bool NativeCodeBasicBlock::OptimizeFindLoop(NativeCodeProcedure* proc)
{ {
bool changed = false; bool changed = false;
@ -41426,7 +41448,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
{ {
mInterProc = proc; mInterProc = proc;
CheckFunc = !strcmp(mInterProc->mIdent->mString, "fill_row"); CheckFunc = !strcmp(mInterProc->mIdent->mString, "atoi");
int nblocks = proc->mBlocks.Size(); int nblocks = proc->mBlocks.Size();
tblocks = new NativeCodeBasicBlock * [nblocks]; tblocks = new NativeCodeBasicBlock * [nblocks];
@ -42276,7 +42298,6 @@ void NativeCodeProcedure::Optimize(void)
if (mEntryBlock->RemoveDoubleZPStore()) if (mEntryBlock->RemoveDoubleZPStore())
changed = true; changed = true;
} }
if (step == 3 || step == 5 || step == 9) if (step == 3 || step == 5 || step == 9)
{ {
ResetVisited(); ResetVisited();

View File

@ -307,6 +307,7 @@ public:
bool OptimizeGenericLoop(NativeCodeProcedure* proc); bool OptimizeGenericLoop(NativeCodeProcedure* proc);
bool CollectGenericLoop(NativeCodeProcedure* proc, ExpandingArray<NativeCodeBasicBlock*>& lblocks); bool CollectGenericLoop(NativeCodeProcedure* proc, ExpandingArray<NativeCodeBasicBlock*>& lblocks);
bool CollectSingleEntryGenericLoop(NativeCodeProcedure* proc, ExpandingArray<NativeCodeBasicBlock*>& lblocks);
void CollectReachable(ExpandingArray<NativeCodeBasicBlock*>& lblock); void CollectReachable(ExpandingArray<NativeCodeBasicBlock*>& lblock);
bool OptimizeFindLoop(NativeCodeProcedure* proc); bool OptimizeFindLoop(NativeCodeProcedure* proc);