Improve struct copy alias analysis
This commit is contained in:
parent
7803e2ecc4
commit
97bb7981a3
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue