Optimize struct copies
This commit is contained in:
parent
75301fa12d
commit
1d4eb70414
|
@ -41,7 +41,6 @@ void Errors::Error(const Location& loc, ErrorID eid, const char* msg, const char
|
|||
fprintf(stderr, "%s(%d, %d) : %s %d: %s '%s' != '%s'\n", loc.mFileName, loc.mLine, loc.mColumn, level, eid, msg, info1, info2);
|
||||
|
||||
if (loc.mFrom)
|
||||
|
||||
Error(*(loc.mFrom), EINFO_EXPANDED, "While expanding here");
|
||||
|
||||
if (mErrorCount > 10 || eid >= EFATAL_GENERIC)
|
||||
|
@ -49,4 +48,3 @@ void Errors::Error(const Location& loc, ErrorID eid, const char* msg, const char
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ enum ErrorID
|
|||
{
|
||||
EINFO_GENERIC = 1000,
|
||||
EINFO_EXPANDED = 1001,
|
||||
EINFO_ORIGINAL_DEFINITION = 1002,
|
||||
|
||||
EWARN_GENERIC = 2000,
|
||||
EWARN_CONSTANT_TRUNCATED,
|
||||
|
|
|
@ -737,6 +737,24 @@ static bool SameInstruction(const InterInstruction* ins1, const InterInstruction
|
|||
return false;
|
||||
}
|
||||
|
||||
static void SwapInstructions(InterInstruction* it, InterInstruction* ib)
|
||||
{
|
||||
for (int i = 0; i < ib->mNumOperands; i++)
|
||||
{
|
||||
if (ib->mSrc[i].mTemp >= 0 && ib->mSrc[i].mFinal)
|
||||
{
|
||||
for (int j = 0; j < it->mNumOperands; j++)
|
||||
{
|
||||
if (it->mSrc[j].mTemp == ib->mSrc[i].mTemp)
|
||||
{
|
||||
it->mSrc[j].mFinal = true;
|
||||
ib->mSrc[i].mFinal = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool InterCodeBasicBlock::CanSwapInstructions(const InterInstruction* ins0, const InterInstruction* ins1) const
|
||||
{
|
||||
// Cannot swap branches
|
||||
|
@ -4520,15 +4538,22 @@ void InterOperand::Disassemble(FILE* file, InterCodeProcedure* proc)
|
|||
else if (mType == IT_POINTER)
|
||||
{
|
||||
const char* vname = "";
|
||||
bool aliased = false;
|
||||
|
||||
if (mMemory == IM_LOCAL)
|
||||
{
|
||||
if (!proc->mLocalVars[mVarIndex])
|
||||
vname = "null";
|
||||
else if (!proc->mLocalVars[mVarIndex]->mIdent)
|
||||
{
|
||||
vname = "";
|
||||
aliased = proc->mLocalVars[mVarIndex]->mAliased;
|
||||
}
|
||||
else
|
||||
{
|
||||
vname = proc->mLocalVars[mVarIndex]->mIdent->mString;
|
||||
aliased = proc->mLocalVars[mVarIndex]->mAliased;
|
||||
}
|
||||
}
|
||||
else if (mMemory == IM_PROCEDURE)
|
||||
{
|
||||
|
@ -4549,11 +4574,20 @@ void InterOperand::Disassemble(FILE* file, InterCodeProcedure* proc)
|
|||
else if (!proc->mModule->mGlobalVars[mVarIndex])
|
||||
vname = "null";
|
||||
else if (!proc->mModule->mGlobalVars[mVarIndex]->mIdent)
|
||||
{
|
||||
vname = "";
|
||||
aliased = proc->mModule->mGlobalVars[mVarIndex]->mAliased;
|
||||
}
|
||||
else
|
||||
{
|
||||
vname = proc->mModule->mGlobalVars[mVarIndex]->mIdent->mString;
|
||||
aliased = proc->mModule->mGlobalVars[mVarIndex]->mAliased;
|
||||
}
|
||||
}
|
||||
|
||||
if (aliased)
|
||||
fprintf(file, "V(%d '%s' A)+%d ", mVarIndex, vname, int(mIntConst));
|
||||
else
|
||||
fprintf(file, "V(%d '%s')+%d ", mVarIndex, vname, int(mIntConst));
|
||||
}
|
||||
else if (IsIntegerType(mType) || mType == IT_BOOL)
|
||||
|
@ -5938,6 +5972,47 @@ void InterCodeBasicBlock::CollectLocalAddressTemps(GrowingIntArray& localTable,
|
|||
}
|
||||
}
|
||||
|
||||
void InterCodeBasicBlock::RecheckLocalAliased(void)
|
||||
{
|
||||
if (!mVisited)
|
||||
{
|
||||
mVisited = true;
|
||||
|
||||
for (int i = 0; i < mInstructions.Size(); i++)
|
||||
{
|
||||
InterVariable* v = nullptr;
|
||||
|
||||
InterInstruction* ins = mInstructions[i];
|
||||
if (ins->mCode == IC_LEA)
|
||||
{
|
||||
if (ins->mSrc[1].mTemp < 0)
|
||||
{
|
||||
if (ins->mSrc[1].mMemory == IM_LOCAL)
|
||||
v = mProc->mLocalVars[ins->mSrc[1].mVarIndex];
|
||||
else if (ins->mSrc[1].mMemory == IM_PARAM || ins->mSrc[1].mMemory == IM_FPARAM)
|
||||
v = mProc->mParamVars[ins->mSrc[1].mVarIndex];
|
||||
}
|
||||
}
|
||||
else if (ins->mCode == IC_CONSTANT && ins->mDst.mType == IT_POINTER)
|
||||
{
|
||||
if (ins->mConst.mMemory == IM_LOCAL)
|
||||
v = mProc->mLocalVars[ins->mConst.mVarIndex];
|
||||
else if (ins->mConst.mMemory == IM_PARAM || ins->mConst.mMemory == IM_FPARAM)
|
||||
v = mProc->mParamVars[ins->mConst.mVarIndex];
|
||||
}
|
||||
|
||||
if (v)
|
||||
{
|
||||
if (!v->mNotAliased)
|
||||
v->mAliased = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (mTrueJump) mTrueJump->RecheckLocalAliased();
|
||||
if (mFalseJump) mFalseJump->RecheckLocalAliased();
|
||||
}
|
||||
}
|
||||
|
||||
void InterCodeBasicBlock::MarkAliasedLocalTemps(const GrowingIntArray& localTable, NumberSet& aliasedLocals, const GrowingIntArray& paramTable, NumberSet& aliasedParams)
|
||||
{
|
||||
int i;
|
||||
|
@ -10450,6 +10525,26 @@ bool InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray&
|
|||
|
||||
mVisited = true;
|
||||
|
||||
#if 1
|
||||
// move loads up as far as possible to avoid false aliasing
|
||||
for (int i = 1; i < mInstructions.Size(); i++)
|
||||
{
|
||||
InterInstruction* ins(mInstructions[i]);
|
||||
if (ins->mCode == IC_LOAD)
|
||||
{
|
||||
int j = i;
|
||||
while (j > 0 && CanSwapInstructions(mInstructions[j - 1], ins))
|
||||
{
|
||||
SwapInstructions(mInstructions[j - 1], ins);
|
||||
mInstructions[j] = mInstructions[j - 1];
|
||||
j--;
|
||||
}
|
||||
if (i != j)
|
||||
mInstructions[j] = ins;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < mInstructions.Size(); i++)
|
||||
{
|
||||
InterInstruction* ins(mInstructions[i]);
|
||||
|
@ -10497,10 +10592,25 @@ bool InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray&
|
|||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
j = 0;
|
||||
while (j < mLoadStoreInstructions.Size() && !(mLoadStoreInstructions[j]->mCode == IC_COPY && SameMemSegment(mLoadStoreInstructions[j]->mSrc[1], ins->mSrc[0])))
|
||||
j++;
|
||||
if (j < mLoadStoreInstructions.Size())
|
||||
{
|
||||
InterInstruction* cins = mLoadStoreInstructions[j];
|
||||
|
||||
int64 offset = ins->mSrc->mIntConst - cins->mSrc[1].mIntConst;
|
||||
ins->mSrc[0] = cins->mSrc[0];
|
||||
ins->mSrc[0].mIntConst += offset;
|
||||
changed = true;
|
||||
}
|
||||
else
|
||||
nins = ins;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (ins->mCode == IC_STORE)
|
||||
{
|
||||
int j = 0, k = 0;
|
||||
|
@ -10539,6 +10649,52 @@ bool InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray&
|
|||
j++;
|
||||
}
|
||||
mLoadStoreInstructions.SetSize(k);
|
||||
#if 1
|
||||
uint64 fillmask = 0;
|
||||
if (ins->mSrc[0].mOperandSize < 64 && ins->mSrc[0].mStride == 1 && ins->mSrc[1].mStride == 1)
|
||||
{
|
||||
for (int j = 0; j < mLoadStoreInstructions.Size(); j++)
|
||||
{
|
||||
InterInstruction* sins = mLoadStoreInstructions[j];
|
||||
if (sins->mCode == IC_STORE && SameMemSegment(ins->mSrc[0], sins->mSrc[1]))
|
||||
{
|
||||
int64 offset = sins->mSrc[1].mIntConst - ins->mSrc[0].mIntConst;
|
||||
if (offset >= 0 && offset < ins->mSrc[0].mOperandSize)
|
||||
{
|
||||
for (int k = 0; k < InterTypeSize[sins->mSrc[0].mType]; k++)
|
||||
fillmask |= 1ULL << (k + offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fillmask + 1 == (1ULL << ins->mSrc[0].mOperandSize))
|
||||
{
|
||||
int n = 0;
|
||||
for (int j = 0; j < mLoadStoreInstructions.Size(); j++)
|
||||
{
|
||||
InterInstruction* sins = mLoadStoreInstructions[j];
|
||||
if (sins->mCode == IC_STORE && SameMemSegment(ins->mSrc[0], sins->mSrc[1]))
|
||||
{
|
||||
int64 offset = sins->mSrc->mIntConst - ins->mSrc[0].mIntConst;
|
||||
if (offset >= 0 && offset < ins->mSrc[0].mOperandSize)
|
||||
{
|
||||
InterInstruction* tins = sins->Clone();
|
||||
tins->mSrc[1] = ins->mSrc[1];
|
||||
tins->mSrc[1].mIntConst = sins->mSrc[1].mIntConst - ins->mSrc[0].mIntConst + ins->mSrc[1].mIntConst;
|
||||
n++;
|
||||
mInstructions.Insert(i + n, tins);
|
||||
}
|
||||
}
|
||||
}
|
||||
ins->mCode = IC_NONE;
|
||||
ins->mNumOperands = 0;
|
||||
}
|
||||
else if (!ins->mVolatile && ins->mSrc[0].mStride == 1 && ins->mSrc[1].mStride == 1)
|
||||
nins = ins;
|
||||
}
|
||||
else if (!ins->mVolatile && ins->mSrc[0].mStride == 1 && ins->mSrc[1].mStride == 1)
|
||||
nins = ins;
|
||||
#endif
|
||||
}
|
||||
else if (ins->mCode == IC_STRCPY)
|
||||
flushMem = true;
|
||||
|
@ -10591,25 +10747,39 @@ bool InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray&
|
|||
int j = 0, k = 0;
|
||||
while (j < mLoadStoreInstructions.Size())
|
||||
{
|
||||
InterOperand* op = nullptr;
|
||||
|
||||
if (mLoadStoreInstructions[j]->mCode == IC_LOAD)
|
||||
op = mLoadStoreInstructions[j]->mSrc + 0;
|
||||
else if (mLoadStoreInstructions[j]->mCode == IC_STORE)
|
||||
op = mLoadStoreInstructions[j]->mSrc + 1;
|
||||
int opmask = 0;
|
||||
|
||||
InterInstruction* lins = mLoadStoreInstructions[j];
|
||||
|
||||
if (lins->mCode == IC_LOAD)
|
||||
opmask = 1;
|
||||
else if (lins->mCode == IC_STORE)
|
||||
opmask = 2;
|
||||
else if (lins->mCode == IC_COPY)
|
||||
opmask = 3;
|
||||
|
||||
bool flush = false;
|
||||
if (op)
|
||||
for(int k=0; k<lins->mNumOperands; k++)
|
||||
{
|
||||
if (op->mTemp >= 0)
|
||||
if ((1 << k) & opmask)
|
||||
{
|
||||
InterOperand& op(lins->mSrc[k]);
|
||||
|
||||
if (op.mTemp >= 0)
|
||||
flush = proc->mStoresIndirect;
|
||||
else if (op->mMemory == IM_FFRAME || op->mMemory == IM_FRAME)
|
||||
else if (op.mMemory == IM_FFRAME || op.mMemory == IM_FRAME)
|
||||
flush = true;
|
||||
else if (op->mMemory == IM_GLOBAL)
|
||||
flush = proc->ModifiesGlobal(op->mVarIndex);
|
||||
else if (op.mMemory == IM_GLOBAL)
|
||||
flush = proc->ModifiesGlobal(op.mVarIndex);
|
||||
else if (op.mMemory == IM_LOCAL && !mProc->mLocalVars[op.mVarIndex]->mAliased)
|
||||
flush = false;
|
||||
else if ((op.mMemory == IM_PARAM || op.mMemory == IM_FPARAM) && !mProc->mParamVars[op.mVarIndex]->mAliased)
|
||||
flush = false;
|
||||
else
|
||||
flush = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!flush)
|
||||
mLoadStoreInstructions[k++] = mLoadStoreInstructions[j];
|
||||
|
@ -10625,7 +10795,7 @@ bool InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray&
|
|||
|
||||
while (j < mLoadStoreInstructions.Size())
|
||||
{
|
||||
if (flushMem && (mLoadStoreInstructions[j]->mCode == IC_LOAD || mLoadStoreInstructions[j]->mCode == IC_STORE))
|
||||
if (flushMem && (mLoadStoreInstructions[j]->mCode == IC_LOAD || mLoadStoreInstructions[j]->mCode == IC_STORE || mLoadStoreInstructions[j]->mCode == IC_COPY))
|
||||
;
|
||||
else if (t < 0)
|
||||
mLoadStoreInstructions[k++] = mLoadStoreInstructions[j];
|
||||
|
@ -10656,6 +10826,26 @@ bool InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray&
|
|||
mLoadStoreInstructions.Push(nins);
|
||||
}
|
||||
|
||||
#if 1
|
||||
// move loads down as far as possible to avoid false aliasing
|
||||
for (int i = mInstructions.Size() - 2; i >= 0; i--)
|
||||
{
|
||||
InterInstruction* ins(mInstructions[i]);
|
||||
if (ins->mCode == IC_LOAD)
|
||||
{
|
||||
int j = i;
|
||||
while (j + 1 < mInstructions.Size() && CanSwapInstructions(ins, mInstructions[j + 1]))
|
||||
{
|
||||
SwapInstructions(ins, mInstructions[j + 1]);
|
||||
mInstructions[j] = mInstructions[j + 1];
|
||||
j++;
|
||||
}
|
||||
if (i != j)
|
||||
mInstructions[j] = ins;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (mTrueJump && mTrueJump->LoadStoreForwarding(mLoadStoreInstructions, staticVars))
|
||||
changed = true;
|
||||
if (mFalseJump && mFalseJump->LoadStoreForwarding(mLoadStoreInstructions, staticVars))
|
||||
|
@ -15048,24 +15238,6 @@ void InterCodeBasicBlock::CompactInstructions(void)
|
|||
}
|
||||
}
|
||||
|
||||
static void SwapInstructions(InterInstruction* it, InterInstruction* ib)
|
||||
{
|
||||
for (int i = 0; i < ib->mNumOperands; i++)
|
||||
{
|
||||
if (ib->mSrc[i].mTemp >= 0 && ib->mSrc[i].mFinal)
|
||||
{
|
||||
for (int j = 0; j < it->mNumOperands; j++)
|
||||
{
|
||||
if (it->mSrc[j].mTemp == ib->mSrc[i].mTemp)
|
||||
{
|
||||
it->mSrc[j].mFinal = true;
|
||||
ib->mSrc[i].mFinal = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void InterCodeBasicBlock::CheckFinalLocal(void)
|
||||
{
|
||||
#if _DEBUG
|
||||
|
@ -18259,7 +18431,7 @@ void InterCodeProcedure::Close(void)
|
|||
{
|
||||
GrowingTypeArray tstack(IT_NONE);
|
||||
|
||||
CheckFunc = !strcmp(mIdent->mString, "drawCube");
|
||||
CheckFunc = !strcmp(mIdent->mString, "fill");
|
||||
CheckCase = false;
|
||||
|
||||
mEntryBlock = mBlocks[0];
|
||||
|
@ -18413,10 +18585,14 @@ void InterCodeProcedure::Close(void)
|
|||
if (i < mLocalAliasedSet.Size() && mLocalAliasedSet[i])
|
||||
mLocalVars[i]->mAliased = true;
|
||||
|
||||
RecheckLocalAliased();
|
||||
|
||||
BuildDataFlowSets();
|
||||
|
||||
LoadStoreForwarding(paramMemory);
|
||||
|
||||
RecheckLocalAliased();
|
||||
|
||||
ResetVisited();
|
||||
mEntryBlock->OptimizeIntervalCompare();
|
||||
|
||||
|
@ -18520,6 +18696,8 @@ void InterCodeProcedure::Close(void)
|
|||
|
||||
LoadStoreForwarding(paramMemory);
|
||||
|
||||
RecheckLocalAliased();
|
||||
|
||||
ResetVisited();
|
||||
mEntryBlock->FollowJumps();
|
||||
|
||||
|
@ -19676,6 +19854,37 @@ void InterCodeProcedure::RemoveUnusedMallocs(void)
|
|||
mEntryBlock->RemoveUnusedMallocs();
|
||||
}
|
||||
|
||||
void InterCodeProcedure::RecheckLocalAliased(void)
|
||||
{
|
||||
for (int i = 0; i < mLocalVars.Size(); i++)
|
||||
{
|
||||
InterVariable* v = mLocalVars[i];
|
||||
if (v)
|
||||
{
|
||||
if (v->mAliased)
|
||||
v->mAliased = false;
|
||||
else
|
||||
v->mNotAliased = true;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < mParamVars.Size(); i++)
|
||||
{
|
||||
InterVariable* v = mParamVars[i];
|
||||
if (v)
|
||||
{
|
||||
if (v->mAliased)
|
||||
v->mAliased = false;
|
||||
else
|
||||
v->mNotAliased = true;
|
||||
}
|
||||
}
|
||||
ResetVisited();
|
||||
mEntryBlock->RecheckLocalAliased();
|
||||
|
||||
DisassembleDebug("RecheckLocalAliased");
|
||||
}
|
||||
|
||||
|
||||
void InterCodeProcedure::HoistCommonConditionalPath(void)
|
||||
{
|
||||
for(;;)
|
||||
|
|
|
@ -19,10 +19,10 @@ enum InterCode
|
|||
IC_UNARY_OPERATOR,
|
||||
IC_RELATIONAL_OPERATOR,
|
||||
IC_CONVERSION_OPERATOR,
|
||||
IC_STORE,
|
||||
IC_LOAD,
|
||||
IC_STORE, // store src[0] into src[1]
|
||||
IC_LOAD, // load from src[0]
|
||||
IC_LEA,
|
||||
IC_COPY,
|
||||
IC_COPY, // Copy from src[0] to src[1]
|
||||
IC_STRCPY,
|
||||
IC_MALLOC,
|
||||
IC_FREE,
|
||||
|
@ -247,7 +247,7 @@ public:
|
|||
class InterVariable
|
||||
{
|
||||
public:
|
||||
bool mUsed, mAliased, mTemp;
|
||||
bool mUsed, mAliased, mTemp, mNotAliased;
|
||||
int mIndex, mSize, mOffset, mTempIndex, mByteIndex;
|
||||
int mNumReferences;
|
||||
const Ident * mIdent;
|
||||
|
@ -255,7 +255,7 @@ public:
|
|||
Declaration * mDeclaration;
|
||||
|
||||
InterVariable(void)
|
||||
: mUsed(false), mAliased(false), mTemp(false), mIndex(-1), mSize(0), mOffset(0), mIdent(nullptr), mLinkerObject(nullptr), mTempIndex(-1), mDeclaration(nullptr)
|
||||
: mUsed(false), mAliased(false), mTemp(false), mNotAliased(false), mIndex(-1), mSize(0), mOffset(0), mIdent(nullptr), mLinkerObject(nullptr), mTempIndex(-1), mDeclaration(nullptr)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
@ -415,6 +415,7 @@ public:
|
|||
|
||||
void CollectLocalAddressTemps(GrowingIntArray& localTable, GrowingIntArray& paramTable, int & nlocals, int & nparams);
|
||||
void MarkAliasedLocalTemps(const GrowingIntArray& localTable, NumberSet& aliasedLocals, const GrowingIntArray& paramTable, NumberSet& aliasedParams);
|
||||
void RecheckLocalAliased(void);
|
||||
|
||||
void CollectLocalUsedTemps(int numTemps);
|
||||
bool PropagateNonLocalUsedConstTemps(void);
|
||||
|
@ -707,6 +708,7 @@ protected:
|
|||
void SingleTailLoopOptimization(InterMemory paramMemory);
|
||||
void HoistCommonConditionalPath(void);
|
||||
void RemoveUnusedMallocs(void);
|
||||
void RecheckLocalAliased(void);
|
||||
|
||||
void MergeBasicBlocks(void);
|
||||
void CheckUsedDefinedTemps(void);
|
||||
|
|
|
@ -642,6 +642,12 @@ void Linker::Link(void)
|
|||
for(int i=0; i<lsec->mSections.Size(); i++)
|
||||
lrgn->PlaceStackSection(lsec, lsec->mSections[i]);
|
||||
|
||||
if (lsec->mStart < lrgn->mEnd)
|
||||
{
|
||||
Location loc;
|
||||
mErrors->Error(loc, ERRR_INSUFFICIENT_MEMORY, "Static stack usage exceeds stack segment");
|
||||
}
|
||||
|
||||
lsec->mEnd = lsec->mStart;
|
||||
lsec->mStart = lrgn->mEnd;
|
||||
|
||||
|
|
|
@ -6200,7 +6200,7 @@ bool NativeCodeBasicBlock::LoadLoadOpStoreIndirectValue(InterCodeProcedure* proc
|
|||
{
|
||||
int size = InterTypeSize[wins->mSrc[0].mType];
|
||||
|
||||
if (wins->mSrc[0].mFinal)
|
||||
if (!wins->mSrc[0].mFinal)
|
||||
{
|
||||
if (wins->mSrc[0].mTemp == rins1->mSrc[0].mTemp || wins->mSrc[0].mTemp == rins0->mSrc[0].mTemp)
|
||||
return false;
|
||||
|
@ -36323,6 +36323,7 @@ bool NativeCodeBasicBlock::PeepHoleOptimizer(NativeCodeProcedure* proc, int pass
|
|||
mIns[i + 0].mType = ASMIT_AND;
|
||||
mIns[i + 0].mMode = ASMIM_IMMEDIATE;
|
||||
mIns[i + 0].mAddress = 0xfe;
|
||||
mIns[i + 0].mLive |= mIns[i + 1].mLive & LIVE_CPU_REG_C;
|
||||
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
|
||||
progress = true;
|
||||
}
|
||||
|
@ -42041,7 +42042,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc)
|
|||
{
|
||||
mInterProc = proc;
|
||||
|
||||
CheckFunc = !strcmp(mInterProc->mIdent->mString, "enemies_move_show");
|
||||
CheckFunc = !strcmp(mInterProc->mIdent->mString, "particle_move");
|
||||
|
||||
int nblocks = proc->mBlocks.Size();
|
||||
tblocks = new NativeCodeBasicBlock * [nblocks];
|
||||
|
|
|
@ -118,7 +118,10 @@ void Parser::AddMemberFunction(Declaration* dec, Declaration* mdec)
|
|||
|
||||
}
|
||||
else
|
||||
{
|
||||
mErrors->Error(mdec->mLocation, EERR_DUPLICATE_DEFINITION, "Duplicate struct member declaration", mdec->mIdent);
|
||||
mErrors->Error(gdec->mLocation, EINFO_ORIGINAL_DEFINITION, "Original definition");
|
||||
}
|
||||
}
|
||||
else
|
||||
dec->mScope->Insert(mdec->mIdent, mdec);
|
||||
|
@ -162,6 +165,7 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt, Declaratio
|
|||
else
|
||||
{
|
||||
mErrors->Error(mScanner->mLocation, EERR_DUPLICATE_DEFINITION, "Error duplicate struct declaration", structName);
|
||||
mErrors->Error(pdec->mLocation, EINFO_ORIGINAL_DEFINITION, "Original definition");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -337,8 +341,12 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt, Declaratio
|
|||
if (pdec)
|
||||
mdec = pdec;
|
||||
|
||||
if (dec->mScope->Insert(mdec->mIdent, mdec))
|
||||
Declaration* odec = dec->mScope->Insert(mdec->mIdent, mdec);
|
||||
if (odec)
|
||||
{
|
||||
mErrors->Error(mdec->mLocation, EERR_DUPLICATE_DEFINITION, "Duplicate struct member declaration", mdec->mIdent);
|
||||
mErrors->Error(odec->mLocation, EINFO_ORIGINAL_DEFINITION, "Original definition");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -445,8 +453,12 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt, Declaratio
|
|||
if (offset > dec->mSize)
|
||||
dec->mSize = offset;
|
||||
|
||||
if (dec->mScope->Insert(mdec->mIdent, mdec))
|
||||
Declaration* odec = dec->mScope->Insert(mdec->mIdent, mdec);
|
||||
if (odec)
|
||||
{
|
||||
mErrors->Error(mdec->mLocation, EERR_DUPLICATE_DEFINITION, "Duplicate struct member declaration", mdec->mIdent);
|
||||
mErrors->Error(odec->mLocation, EINFO_ORIGINAL_DEFINITION, "Original definition");
|
||||
}
|
||||
|
||||
if (dec->mConst)
|
||||
{
|
||||
|
@ -849,8 +861,12 @@ Declaration* Parser::ParseBaseTypeDeclaration(uint64 flags, bool qualified, Decl
|
|||
dec->mIdent = mScanner->mTokenIdent;
|
||||
dec->mQualIdent = mScope->Mangle(dec->mIdent);
|
||||
|
||||
if (mScope->Insert(dec->mIdent, dec))
|
||||
Declaration* odec = mScope->Insert(dec->mIdent, dec);
|
||||
if (odec)
|
||||
{
|
||||
mErrors->Error(dec->mLocation, EERR_DUPLICATE_DEFINITION, "Duplicate name", dec->mIdent);
|
||||
mErrors->Error(odec->mLocation, EINFO_ORIGINAL_DEFINITION, "Original definition");
|
||||
}
|
||||
mScanner->NextToken();
|
||||
}
|
||||
|
||||
|
@ -871,8 +887,12 @@ Declaration* Parser::ParseBaseTypeDeclaration(uint64 flags, bool qualified, Decl
|
|||
{
|
||||
cdec->mIdent = mScanner->mTokenIdent;
|
||||
cdec->mQualIdent = mScope->Mangle(cdec->mIdent);
|
||||
if (mScope->Insert(cdec->mIdent, cdec) != nullptr)
|
||||
Declaration* odec = mScope->Insert(cdec->mIdent, cdec);
|
||||
if (odec)
|
||||
{
|
||||
mErrors->Error(mScanner->mLocation, EERR_DUPLICATE_DEFINITION, "Duplicate declaration", mScanner->mTokenIdent->mString);
|
||||
mErrors->Error(odec->mLocation, EINFO_ORIGINAL_DEFINITION, "Original definition");
|
||||
}
|
||||
mScanner->NextToken();
|
||||
}
|
||||
if (mScanner->mToken == TK_ASSIGN)
|
||||
|
@ -3663,7 +3683,10 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
|
|||
mScope->UseScope(dec->mScope);
|
||||
}
|
||||
else
|
||||
{
|
||||
mErrors->Error(mScanner->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Not a class or namespace");
|
||||
mErrors->Error(dec->mLocation, EINFO_ORIGINAL_DEFINITION, "Original definition");
|
||||
}
|
||||
}
|
||||
|
||||
return dec;
|
||||
|
@ -3952,7 +3975,10 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
|
|||
if (mScanner->mToken == TK_OPEN_BRACE)
|
||||
{
|
||||
if (cdec->mFlags & DTF_DEFINED)
|
||||
mErrors->Error(cdec->mLocation, EERR_DUPLICATE_DEFINITION, "Function already has a body");
|
||||
{
|
||||
mErrors->Error(mScanner->mLocation, EERR_DUPLICATE_DEFINITION, "Function already has a body");
|
||||
mErrors->Error(cdec->mLocation, EINFO_ORIGINAL_DEFINITION, "Original definition");
|
||||
}
|
||||
|
||||
cdec->mCompilerOptions = mCompilerOptions;
|
||||
cdec->mBase->mCompilerOptions = mCompilerOptions;
|
||||
|
@ -4023,7 +4049,10 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
|
|||
}
|
||||
|
||||
if (cdec->mFlags & DTF_DEFINED)
|
||||
mErrors->Error(cdec->mLocation, EERR_DUPLICATE_DEFINITION, "Function already has a body");
|
||||
{
|
||||
mErrors->Error(mScanner->mLocation, EERR_DUPLICATE_DEFINITION, "Function already has a body");
|
||||
mErrors->Error(cdec->mLocation, EINFO_ORIGINAL_DEFINITION, "Original definition");
|
||||
}
|
||||
|
||||
cdec->mCompilerOptions = mCompilerOptions;
|
||||
cdec->mBase->mCompilerOptions = mCompilerOptions;
|
||||
|
@ -4255,7 +4284,10 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
|
|||
#endif
|
||||
|
||||
if (ldec && ldec != pdec)
|
||||
{
|
||||
mErrors->Error(ndec->mLocation, EERR_DUPLICATE_DEFINITION, "Duplicate definition");
|
||||
mErrors->Error(ldec->mLocation, EINFO_ORIGINAL_DEFINITION, "Original definition");
|
||||
}
|
||||
}
|
||||
else if (ptempl && mTemplateScope && pthis)
|
||||
{
|
||||
|
@ -4371,7 +4403,10 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
|
|||
else if (ndec->mBase->mType == DT_TYPE_POINTER && pdec->mBase->mType == DT_TYPE_ARRAY && ndec->mBase->mBase->IsSame(pdec->mBase->mBase))
|
||||
;
|
||||
else
|
||||
{
|
||||
mErrors->Error(ndec->mLocation, EERR_DECLARATION_DIFFERS, "Variable declaration differs", ndec->mIdent);
|
||||
mErrors->Error(pdec->mLocation, EINFO_ORIGINAL_DEFINITION, "Original definition");
|
||||
}
|
||||
}
|
||||
|
||||
pdec->mFlags |= ndec->mFlags & DTF_ZEROPAGE;
|
||||
|
@ -4599,7 +4634,10 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
|
|||
if (ndec->mBase->mType == DT_TYPE_FUNCTION)
|
||||
{
|
||||
if ((ndec->mFlags & DTF_DEFINED) && !(ndec->mFlags & DTF_REQUEST_INLINE))
|
||||
{
|
||||
mErrors->Error(mScanner->mLocation, EERR_DUPLICATE_DEFINITION, "Duplicate function definition", ndec->mQualIdent);
|
||||
mErrors->Error(ndec->mLocation, EINFO_ORIGINAL_DEFINITION, "Original definition");
|
||||
}
|
||||
|
||||
ndec->mCompilerOptions = mCompilerOptions;
|
||||
ndec->mBase->mCompilerOptions = mCompilerOptions;
|
||||
|
@ -11690,7 +11728,10 @@ void Parser::ParseNamespace(void)
|
|||
{
|
||||
Declaration* ns = mScope->Insert(ident, dec);
|
||||
if (ns)
|
||||
{
|
||||
mErrors->Error(mScanner->mLocation, EERR_DUPLICATE_DEFINITION, "Duplicate definition", ident);
|
||||
mErrors->Error(ns->mLocation, EINFO_ORIGINAL_DEFINITION, "Original definition");
|
||||
}
|
||||
}
|
||||
else
|
||||
mErrors->Error(mScanner->mLocation, ERRO_NOT_A_NAMESPACE, "Not a namespace", ident);
|
||||
|
|
Loading…
Reference in New Issue