Improve struct copy alias analysis

This commit is contained in:
drmortalwombat 2023-04-06 17:14:53 +02:00
parent 7803e2ecc4
commit 97bb7981a3
9 changed files with 177 additions and 61 deletions

View File

@ -21,6 +21,9 @@ rem @echo off
@call :test recursiontest.c @call :test recursiontest.c
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error
@call :test copyinitmove.c
@if %errorlevel% neq 0 goto :error
@call :test fastcalltest.c @call :test fastcalltest.c
@if %errorlevel% neq 0 goto :error @if %errorlevel% neq 0 goto :error

27
autotest/copyinitmove.c Normal file
View File

@ -0,0 +1,27 @@
int val(char * c)
{
return c[0];
}
void set(char * c, int a)
{
c[0] = a;
}
int main(void)
{
int sum0 = 0, sum1 = 0, sum2 = 0, sum3 = 0;
for(int i=0; i<10; i++)
{
char t[10] = {1};
sum0 += val(t);
sum2 += t[0];
set(t, i);
sum1 += val(t);
sum3 += t[0];
}
return (sum1 - 45) | (sum0 - 10) | (sum3 - 45) | (sum2 - 10);
}

View File

@ -84,8 +84,9 @@ static const uint64 DTF_FUNC_ANALYZING = (1ULL << 35);
static const uint64 DTF_FUNC_CONSTEXPR = (1ULL << 36); static const uint64 DTF_FUNC_CONSTEXPR = (1ULL << 36);
static const uint64 DTF_FUNC_INTRSAVE = (1ULL << 37); static const uint64 DTF_FUNC_INTRSAVE = (1ULL << 37);
static const uint64 DTF_FUNC_INTRCALLED = (1ULL << 38); static const uint64 DTF_FUNC_INTRCALLED = (1ULL << 38);
static const uint64 DTF_FUNC_PURE = (1ULL << 39);
static const uint64 DTF_VAR_ALIASING = (1ULL << 39); static const uint64 DTF_VAR_ALIASING = (1ULL << 48);
class Declaration; class Declaration;

View File

@ -271,7 +271,8 @@ void GlobalAnalyzer::AnalyzeProcedure(Expression* exp, Declaration* dec)
{ {
if (mCompilerOptions & COPT_OPTIMIZE_CONST_EXPRESSIONS) if (mCompilerOptions & COPT_OPTIMIZE_CONST_EXPRESSIONS)
dec->mFlags |= DTF_FUNC_CONSTEXPR; dec->mFlags |= DTF_FUNC_CONSTEXPR;
Analyze(exp, dec); dec->mFlags |= DTF_FUNC_PURE;
Analyze(exp, dec, false);
} }
else else
mErrors->Error(dec->mLocation, EERR_UNDEFINED_OBJECT, "Calling undefined function", dec->mIdent); mErrors->Error(dec->mLocation, EERR_UNDEFINED_OBJECT, "Calling undefined function", dec->mIdent);
@ -333,12 +334,12 @@ void GlobalAnalyzer::AnalyzeGlobalVariable(Declaration* dec)
if (dec->mValue) if (dec->mValue)
{ {
Analyze(dec->mValue, dec); Analyze(dec->mValue, dec, false);
} }
} }
} }
Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec) Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, bool lhs)
{ {
Declaration* ldec, * rdec; Declaration* ldec, * rdec;
@ -358,13 +359,13 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec)
while (mdec) while (mdec)
{ {
if (mdec->mValue) if (mdec->mValue)
RegisterProc(Analyze(mdec->mValue, mdec)); RegisterProc(Analyze(mdec->mValue, mdec, false));
mdec = mdec->mNext; mdec = mdec->mNext;
} }
} }
else if (exp->mDecValue->mType == DT_CONST_POINTER) else if (exp->mDecValue->mType == DT_CONST_POINTER)
{ {
RegisterProc(Analyze(exp->mDecValue->mValue, procDec)); RegisterProc(Analyze(exp->mDecValue->mValue, procDec, false));
} }
else if (exp->mDecValue->mType == DT_CONST_ADDRESS) else if (exp->mDecValue->mType == DT_CONST_ADDRESS)
{ {
@ -386,6 +387,9 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec)
if (!(type->mFlags & DTF_CONST)) if (!(type->mFlags & DTF_CONST))
procDec->mFlags &= ~DTF_FUNC_CONSTEXPR; procDec->mFlags &= ~DTF_FUNC_CONSTEXPR;
if (lhs)
procDec->mFlags &= ~DTF_FUNC_PURE;
AnalyzeGlobalVariable(exp->mDecValue); AnalyzeGlobalVariable(exp->mDecValue);
} }
else else
@ -399,54 +403,66 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec)
return exp->mDecValue; return exp->mDecValue;
case EX_INITIALIZATION: case EX_INITIALIZATION:
case EX_ASSIGNMENT: case EX_ASSIGNMENT:
ldec = Analyze(exp->mLeft, procDec); ldec = Analyze(exp->mLeft, procDec, true);
rdec = Analyze(exp->mRight, procDec); rdec = Analyze(exp->mRight, procDec, false);
RegisterProc(rdec); RegisterProc(rdec);
return ldec; return ldec;
case EX_BINARY: case EX_BINARY:
ldec = Analyze(exp->mLeft, procDec); ldec = Analyze(exp->mLeft, procDec, lhs);
rdec = Analyze(exp->mRight, procDec); rdec = Analyze(exp->mRight, procDec, lhs);
return ldec; return ldec;
case EX_RELATIONAL: case EX_RELATIONAL:
ldec = Analyze(exp->mLeft, procDec); ldec = Analyze(exp->mLeft, procDec, false);
rdec = Analyze(exp->mRight, procDec); rdec = Analyze(exp->mRight, procDec, false);
return TheBoolTypeDeclaration; return TheBoolTypeDeclaration;
case EX_PREINCDEC: case EX_PREINCDEC:
return Analyze(exp->mLeft, procDec); return Analyze(exp->mLeft, procDec, true);
case EX_PREFIX: case EX_PREFIX:
ldec = Analyze(exp->mLeft, procDec);
if (exp->mToken == TK_BINARY_AND) if (exp->mToken == TK_BINARY_AND)
{ {
ldec = Analyze(exp->mLeft, procDec, true);
if (ldec->mType == DT_VARIABLE) if (ldec->mType == DT_VARIABLE)
ldec->mFlags |= DTF_VAR_ALIASING; ldec->mFlags |= DTF_VAR_ALIASING;
} }
else if (exp->mToken == TK_MUL) else if (exp->mToken == TK_MUL)
{ {
ldec = Analyze(exp->mLeft, procDec, false);
procDec->mFlags &= ~DTF_FUNC_CONSTEXPR; procDec->mFlags &= ~DTF_FUNC_CONSTEXPR;
if (lhs)
procDec->mFlags &= ~DTF_FUNC_PURE;
return exp->mDecType; return exp->mDecType;
} }
break; break;
case EX_POSTFIX: case EX_POSTFIX:
break; break;
case EX_POSTINCDEC: case EX_POSTINCDEC:
return Analyze(exp->mLeft, procDec); return Analyze(exp->mLeft, procDec, true);
case EX_INDEX: case EX_INDEX:
ldec = Analyze(exp->mLeft, procDec); ldec = Analyze(exp->mLeft, procDec, lhs);
if (ldec->mType == DT_VARIABLE || ldec->mType == DT_ARGUMENT) if (ldec->mType == DT_VARIABLE || ldec->mType == DT_ARGUMENT)
{
ldec = ldec->mBase; ldec = ldec->mBase;
rdec = Analyze(exp->mRight, procDec); if (ldec->mType == DT_TYPE_POINTER)
{
if (lhs)
procDec->mFlags &= ~DTF_FUNC_PURE;
procDec->mFlags &= ~DTF_FUNC_CONSTEXPR;
}
}
rdec = Analyze(exp->mRight, procDec, false);
if (ldec->mBase) if (ldec->mBase)
return ldec->mBase; return ldec->mBase;
break; break;
case EX_QUALIFY: case EX_QUALIFY:
Analyze(exp->mLeft, procDec); Analyze(exp->mLeft, procDec, lhs);
return exp->mDecValue->mBase; return exp->mDecValue->mBase;
case EX_CALL: case EX_CALL:
case EX_INLINE: case EX_INLINE:
ldec = Analyze(exp->mLeft, procDec); ldec = Analyze(exp->mLeft, procDec, false);
if ((ldec->mFlags & DTF_INTRINSIC) && !ldec->mValue) if ((ldec->mFlags & DTF_INTRINSIC) && !ldec->mValue)
{ {
@ -460,6 +476,8 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec)
if (procDec->mFlags & DTF_INTERRUPT) if (procDec->mFlags & DTF_INTERRUPT)
mErrors->Error(exp->mLocation, EWARN_NOT_INTERRUPT_SAFE, "Calling non interrupt safe function", ldec->mIdent); mErrors->Error(exp->mLocation, EWARN_NOT_INTERRUPT_SAFE, "Calling non interrupt safe function", ldec->mIdent);
} }
if (!(GetProcFlags(ldec) & DTF_FUNC_PURE))
procDec->mFlags &= ~DTF_FUNC_PURE;
} }
if (exp->mRight) if (exp->mRight)
@ -478,35 +496,35 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec)
else else
rex = nullptr; rex = nullptr;
} }
RegisterProc(Analyze(exp->mRight, procDec)); RegisterProc(Analyze(exp->mRight, procDec, false));
} }
break; break;
case EX_LIST: case EX_LIST:
RegisterProc(Analyze(exp->mLeft, procDec)); RegisterProc(Analyze(exp->mLeft, procDec, false));
return Analyze(exp->mRight, procDec); return Analyze(exp->mRight, procDec, false);
case EX_RETURN: case EX_RETURN:
if (exp->mLeft) if (exp->mLeft)
RegisterProc(Analyze(exp->mLeft, procDec)); RegisterProc(Analyze(exp->mLeft, procDec, false));
break; break;
case EX_SEQUENCE: case EX_SEQUENCE:
do do
{ {
if (exp->mLeft) if (exp->mLeft)
ldec = Analyze(exp->mLeft, procDec); ldec = Analyze(exp->mLeft, procDec, false);
exp = exp->mRight; exp = exp->mRight;
} while (exp); } while (exp);
break; break;
case EX_WHILE: case EX_WHILE:
procDec->mFlags &= ~DTF_FUNC_CONSTEXPR; procDec->mFlags &= ~DTF_FUNC_CONSTEXPR;
ldec = Analyze(exp->mLeft, procDec); ldec = Analyze(exp->mLeft, procDec, false);
rdec = Analyze(exp->mRight, procDec); rdec = Analyze(exp->mRight, procDec, false);
break; break;
case EX_IF: case EX_IF:
ldec = Analyze(exp->mLeft, procDec); ldec = Analyze(exp->mLeft, procDec, false);
rdec = Analyze(exp->mRight->mLeft, procDec); rdec = Analyze(exp->mRight->mLeft, procDec, false);
if (exp->mRight->mRight) if (exp->mRight->mRight)
rdec = Analyze(exp->mRight->mRight, procDec); rdec = Analyze(exp->mRight->mRight, procDec, false);
break; break;
case EX_ELSE: case EX_ELSE:
break; break;
@ -514,16 +532,16 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec)
procDec->mFlags &= ~DTF_FUNC_CONSTEXPR; procDec->mFlags &= ~DTF_FUNC_CONSTEXPR;
if (exp->mLeft->mRight) if (exp->mLeft->mRight)
ldec = Analyze(exp->mLeft->mRight, procDec); ldec = Analyze(exp->mLeft->mRight, procDec, false);
if (exp->mLeft->mLeft->mLeft) if (exp->mLeft->mLeft->mLeft)
ldec = Analyze(exp->mLeft->mLeft->mLeft, procDec); ldec = Analyze(exp->mLeft->mLeft->mLeft, procDec, false);
rdec = Analyze(exp->mRight, procDec); rdec = Analyze(exp->mRight, procDec, false);
if (exp->mLeft->mLeft->mRight) if (exp->mLeft->mLeft->mRight)
ldec = Analyze(exp->mLeft->mLeft->mRight, procDec); ldec = Analyze(exp->mLeft->mLeft->mRight, procDec, false);
break; break;
case EX_DO: case EX_DO:
ldec = Analyze(exp->mLeft, procDec); ldec = Analyze(exp->mLeft, procDec, false);
rdec = Analyze(exp->mRight, procDec); rdec = Analyze(exp->mRight, procDec, false);
break; break;
case EX_BREAK: case EX_BREAK:
case EX_CONTINUE: case EX_CONTINUE:
@ -532,33 +550,34 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec)
case EX_TYPE: case EX_TYPE:
break; break;
case EX_TYPECAST: case EX_TYPECAST:
return Analyze(exp->mRight, procDec); return Analyze(exp->mRight, procDec, false);
break; break;
case EX_LOGICAL_AND: case EX_LOGICAL_AND:
ldec = Analyze(exp->mLeft, procDec); ldec = Analyze(exp->mLeft, procDec, false);
rdec = Analyze(exp->mRight, procDec); rdec = Analyze(exp->mRight, procDec, false);
break; break;
case EX_LOGICAL_OR: case EX_LOGICAL_OR:
ldec = Analyze(exp->mLeft, procDec); ldec = Analyze(exp->mLeft, procDec, false);
rdec = Analyze(exp->mRight, procDec); rdec = Analyze(exp->mRight, procDec, false);
break; break;
case EX_LOGICAL_NOT: case EX_LOGICAL_NOT:
ldec = Analyze(exp->mLeft, procDec); ldec = Analyze(exp->mLeft, procDec, false);
break; break;
case EX_ASSEMBLER: case EX_ASSEMBLER:
procDec->mFlags |= DTF_FUNC_ASSEMBLER; procDec->mFlags |= DTF_FUNC_ASSEMBLER;
procDec->mFlags &= ~DTF_FUNC_CONSTEXPR; procDec->mFlags &= ~DTF_FUNC_CONSTEXPR;
procDec->mFlags &= ~DTF_FUNC_PURE;
AnalyzeAssembler(exp, procDec); AnalyzeAssembler(exp, procDec);
break; break;
case EX_UNDEFINED: case EX_UNDEFINED:
break; break;
case EX_SWITCH: case EX_SWITCH:
ldec = Analyze(exp->mLeft, procDec); ldec = Analyze(exp->mLeft, procDec, false);
exp = exp->mRight; exp = exp->mRight;
while (exp) while (exp)
{ {
if (exp->mLeft->mRight) if (exp->mLeft->mRight)
rdec = Analyze(exp->mLeft->mRight, procDec); rdec = Analyze(exp->mLeft->mRight, procDec, false);
exp = exp->mRight; exp = exp->mRight;
} }
break; break;
@ -567,9 +586,9 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec)
case EX_DEFAULT: case EX_DEFAULT:
break; break;
case EX_CONDITIONAL: case EX_CONDITIONAL:
ldec = Analyze(exp->mLeft, procDec); ldec = Analyze(exp->mLeft, procDec, false);
RegisterProc(Analyze(exp->mRight->mLeft, procDec)); RegisterProc(Analyze(exp->mRight->mLeft, procDec, false));
RegisterProc(Analyze(exp->mRight->mRight, procDec)); RegisterProc(Analyze(exp->mRight->mRight, procDec, false));
break; break;
} }

View File

@ -27,7 +27,7 @@ protected:
GrowingArray<Declaration*> mCalledFunctions, mCallingFunctions, mVariableFunctions, mFunctions; GrowingArray<Declaration*> mCalledFunctions, mCallingFunctions, mVariableFunctions, mFunctions;
Declaration* Analyze(Expression* exp, Declaration* procDec); Declaration* Analyze(Expression* exp, Declaration* procDec, bool lhs);
uint64 GetProcFlags(Declaration* to) const; uint64 GetProcFlags(Declaration* to) const;
void RegisterCall(Declaration* from, Declaration* to); void RegisterCall(Declaration* from, Declaration* to);

View File

@ -479,6 +479,18 @@ static bool CollidingMem(const InterInstruction* ins1, const InterInstruction* i
return false; return false;
} }
static bool DestroyingMem(const InterInstruction* lins, const InterInstruction* sins, const GrowingVariableArray& staticVars)
{
if (sins->mCode == IC_LOAD)
return false;
else if (sins->mCode == IC_STORE)
return CollidingMem(sins->mSrc[1], sins->mSrc[0].mType, lins, staticVars);
else if (sins->mCode == IC_COPY || sins->mCode == IC_STRCPY)
return CollidingMem(sins->mSrc[1], IT_NONE, lins, staticVars);
else
return false;
}
static bool SameMem(const InterOperand& op1, const InterOperand& op2) static bool SameMem(const InterOperand& op1, const InterOperand& op2)
{ {
if (op1.mMemory != op2.mMemory || op1.mType != op2.mType || op1.mIntConst != op2.mIntConst) if (op1.mMemory != op2.mMemory || op1.mType != op2.mType || op1.mIntConst != op2.mIntConst)
@ -1014,7 +1026,7 @@ static void LoadConstantFold(InterInstruction* ins, InterInstruction* ains, cons
{ {
union { float f; unsigned int v; } cc; union { float f; unsigned int v; } cc;
cc.v = (int)data[0 * stride] | (data[1 * stride] << 8) | (data[2 * stride] << 16) | (data[3 * stride] << 24); cc.v = (int)data[0 * stride] | (data[1 * stride] << 8) | (data[2 * stride] << 16) | (data[3 * stride] << 24);
ins->mConst.mFloatConst = cc.v; ins->mConst.mFloatConst = cc.f;
} break; } break;
} }
@ -3325,6 +3337,20 @@ bool InterInstruction::RemoveUnusedStoreInstructions(const GrowingVariableArray&
} }
} }
} }
else if (mCode == IC_CONSTANT)
{
if (mConst.mType == IT_POINTER)
{
if (mConst.mMemory == IM_LOCAL)
{
requiredVars += mConst.mVarIndex;
}
else if (mConst.mMemory == paramMemory)
{
requiredParams += mConst.mVarIndex;
}
}
}
else if (mCode == IC_COPY) else if (mCode == IC_COPY)
{ {
if (mSrc[1].mMemory == IM_LOCAL) if (mSrc[1].mMemory == IM_LOCAL)
@ -5347,7 +5373,7 @@ void InterCodeBasicBlock::CollectConstTemps(GrowingInstructionPtrArray& ctemps,
} }
} }
bool InterCodeBasicBlock::PropagateVariableCopy(const GrowingInstructionPtrArray& ctemps, const GrowingVariableArray& staticVars) bool InterCodeBasicBlock::PropagateVariableCopy(const GrowingInstructionPtrArray& ctemps, const GrowingVariableArray& staticVars, const NumberSet& aliasedLocals, const NumberSet& aliasedParams)
{ {
bool changed = false; bool changed = false;
@ -5397,7 +5423,7 @@ bool InterCodeBasicBlock::PropagateVariableCopy(const GrowingInstructionPtrArray
case IC_STORE: case IC_STORE:
j = 0; j = 0;
for(int k=0; k<ltemps.Size(); k++) for (int k = 0; k < ltemps.Size(); k++)
{ {
if (!CollidingMem(ltemps[k], ins, staticVars)) if (!CollidingMem(ltemps[k], ins, staticVars))
{ {
@ -5428,13 +5454,33 @@ bool InterCodeBasicBlock::PropagateVariableCopy(const GrowingInstructionPtrArray
ltemps.SetSize(j); ltemps.SetSize(j);
ltemps.Push(ins); ltemps.Push(ins);
break; break;
case IC_CALL:
case IC_CALL_NATIVE:
if (!ins->mNoSideEffects)
{
j = 0;
for (int k = 0; k < ltemps.Size(); k++)
{
if (ltemps[k]->mSrc[0].mTemp < 0 && ltemps[k]->mSrc[0].mMemory == IM_LOCAL && aliasedLocals[ltemps[k]->mSrc[0].mVarIndex] ||
ltemps[k]->mSrc[1].mTemp < 0 && ltemps[k]->mSrc[1].mMemory == IM_LOCAL && aliasedLocals[ltemps[k]->mSrc[1].mVarIndex] ||
ltemps[k]->mSrc[0].mTemp < 0 && (ltemps[k]->mSrc[0].mMemory == IM_PARAM || ltemps[k]->mSrc[0].mMemory == IM_FPARAM) && aliasedParams[ltemps[k]->mSrc[0].mVarIndex] ||
ltemps[k]->mSrc[1].mTemp < 0 && (ltemps[k]->mSrc[1].mMemory == IM_PARAM || ltemps[k]->mSrc[1].mMemory == IM_FPARAM) && aliasedParams[ltemps[k]->mSrc[1].mVarIndex])
{
}
else
ltemps[j++] = ltemps[k];
}
ltemps.SetSize(j);
}
break;
} }
} }
if (mTrueJump && mTrueJump->PropagateVariableCopy(ltemps, staticVars)) if (mTrueJump && mTrueJump->PropagateVariableCopy(ltemps, staticVars, aliasedLocals, aliasedParams))
changed = true; changed = true;
if (mFalseJump && mFalseJump->PropagateVariableCopy(ltemps, staticVars)) if (mFalseJump && mFalseJump->PropagateVariableCopy(ltemps, staticVars, aliasedLocals, aliasedParams))
changed = true; changed = true;
} }
@ -9162,7 +9208,7 @@ bool InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray&
j = 0; j = 0;
while (j < mLoadStoreInstructions.Size()) while (j < mLoadStoreInstructions.Size())
{ {
if (!CollidingMem(ins, mLoadStoreInstructions[j], staticVars)) if (!DestroyingMem(mLoadStoreInstructions[j], ins, staticVars))
mLoadStoreInstructions[k++] = mLoadStoreInstructions[j]; mLoadStoreInstructions[k++] = mLoadStoreInstructions[j];
j++; j++;
} }
@ -9172,7 +9218,18 @@ bool InterCodeBasicBlock::LoadStoreForwarding(const GrowingInstructionPtrArray&
if (!ins->mVolatile) if (!ins->mVolatile)
nins = ins; nins = ins;
} }
else if (ins->mCode == IC_COPY || ins->mCode == IC_STRCPY) else if (ins->mCode == IC_COPY)
{
int j = 0, k = 0;
while (j < mLoadStoreInstructions.Size())
{
if (!DestroyingMem(mLoadStoreInstructions[j], ins, staticVars))
mLoadStoreInstructions[k++] = mLoadStoreInstructions[j];
j++;
}
mLoadStoreInstructions.SetSize(k);
}
else if (ins->mCode == IC_STRCPY)
flushMem = true; flushMem = true;
else if (ins->mCode == IC_LEA || ins->mCode == IC_UNARY_OPERATOR || ins->mCode == IC_BINARY_OPERATOR || ins->mCode == IC_RELATIONAL_OPERATOR || ins->mCode == IC_CONVERSION_OPERATOR) else if (ins->mCode == IC_LEA || ins->mCode == IC_UNARY_OPERATOR || ins->mCode == IC_BINARY_OPERATOR || ins->mCode == IC_RELATIONAL_OPERATOR || ins->mCode == IC_CONVERSION_OPERATOR)
{ {
@ -15514,7 +15571,7 @@ void InterCodeProcedure::Close(void)
{ {
GrowingInstructionPtrArray cipa(nullptr); GrowingInstructionPtrArray cipa(nullptr);
ResetVisited(); ResetVisited();
changed = mEntryBlock->PropagateVariableCopy(cipa, mModule->mGlobalVars); changed = mEntryBlock->PropagateVariableCopy(cipa, mModule->mGlobalVars, mLocalAliasedSet, mParamAliasedSet);
RemoveUnusedStoreInstructions(paramMemory); RemoveUnusedStoreInstructions(paramMemory);
} while (changed); } while (changed);

View File

@ -405,7 +405,7 @@ public:
void CollectConstTemps(GrowingInstructionPtrArray& ctemps, NumberSet& assignedTemps); void CollectConstTemps(GrowingInstructionPtrArray& ctemps, NumberSet& assignedTemps);
bool PropagateConstTemps(const GrowingInstructionPtrArray& ctemps); bool PropagateConstTemps(const GrowingInstructionPtrArray& ctemps);
bool PropagateVariableCopy(const GrowingInstructionPtrArray& ctemps, const GrowingVariableArray& staticVars); bool PropagateVariableCopy(const GrowingInstructionPtrArray& ctemps, const GrowingVariableArray& staticVars, const NumberSet & aliasedLocals, const NumberSet & aliasedParams);
void BuildLocalTempSets(int num); void BuildLocalTempSets(int num);
void BuildGlobalProvidedTempSet(const NumberSet & fromProvidedTemps, const NumberSet& potentialProvidedTemps); void BuildGlobalProvidedTempSet(const NumberSet & fromProvidedTemps, const NumberSet& potentialProvidedTemps);

View File

@ -1198,6 +1198,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
InterInstruction * ins = new InterInstruction(exp->mLocation, IC_CONSTANT); InterInstruction * ins = new InterInstruction(exp->mLocation, IC_CONSTANT);
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->mConst.mType = IT_POINTER;
ins->mConst.mOperandSize = dec->mSize; ins->mConst.mOperandSize = dec->mSize;
ins->mConst.mIntConst = dec->mOffset; ins->mConst.mIntConst = dec->mOffset;
@ -1283,6 +1284,11 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
if (exp->mType != EX_INITIALIZATION && (vl.mType->mFlags & DTF_CONST)) if (exp->mType != EX_INITIALIZATION && (vl.mType->mFlags & DTF_CONST))
mErrors->Error(exp->mLocation, EERR_CONST_ASSIGN, "Cannot assign to const type"); mErrors->Error(exp->mLocation, EERR_CONST_ASSIGN, "Cannot assign to const type");
if (exp->mType == EX_INITIALIZATION && exp->mRight->mType == EX_CONSTANT && exp->mRight->mDecValue && exp->mRight->mDecValue->mLinkerObject)
{
exp->mRight->mDecValue->mLinkerObject->mFlags |= LOBJF_CONST;
}
if (vl.mType->mType == DT_TYPE_STRUCT || vl.mType->mType == DT_TYPE_ARRAY || vl.mType->mType == DT_TYPE_UNION) if (vl.mType->mType == DT_TYPE_STRUCT || vl.mType->mType == DT_TYPE_ARRAY || vl.mType->mType == DT_TYPE_UNION)
{ {
vr = Dereference(proc, exp, block, vr, 1); vr = Dereference(proc, exp, block, vr, 1);
@ -2579,12 +2585,15 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
block->Append(defins[i]); block->Append(defins[i]);
InterInstruction * cins = new InterInstruction(exp->mLocation, IC_CALL); InterInstruction * cins = new InterInstruction(exp->mLocation, IC_CALL);
if (exp->mLeft->mDecValue && exp->mLeft->mDecValue->mFlags & DTF_NATIVE) if (exp->mLeft->mDecValue && (exp->mLeft->mDecValue->mFlags & DTF_NATIVE))
cins->mCode = IC_CALL_NATIVE; cins->mCode = IC_CALL_NATIVE;
else else
cins->mCode = IC_CALL; cins->mCode = IC_CALL;
if (exp->mLeft->mType == EX_CONSTANT && exp->mLeft->mDecValue->mFlags & DTF_FUNC_CONSTEXPR) if (exp->mLeft->mDecValue && (exp->mLeft->mDecValue->mFlags & DTF_FUNC_PURE))
cins->mNoSideEffects = true;
if (exp->mLeft->mType == EX_CONSTANT && (exp->mLeft->mDecValue->mFlags & DTF_FUNC_CONSTEXPR))
cins->mConstExpr = true; cins->mConstExpr = true;
cins->mSrc[0].mType = IT_POINTER; cins->mSrc[0].mType = IT_POINTER;

View File

@ -24480,9 +24480,9 @@ bool NativeCodeBasicBlock::EliminateUpper16BitSum(NativeCodeProcedure* nproc)
nproc->ResetPatched(); nproc->ResetPatched();
if (Check16BitSum(this, i, i + 3, mIns[i + 2].mAddress)) if (Check16BitSum(this, i, i + 3, mIns[i + 2].mAddress))
{ {
mIns[i + 0].mType = ASMIT_NOP; mIns[i + 0].mMode == ASMIM_IMPLIED; mIns[i + 0].mType = ASMIT_NOP; mIns[i + 0].mMode = ASMIM_IMPLIED;
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode == ASMIM_IMPLIED; mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode == ASMIM_IMPLIED; mIns[i + 2].mType = ASMIT_NOP; mIns[i + 2].mMode = ASMIM_IMPLIED;
changed = true; changed = true;
} }
} }