Add __forceinline storage specifier
This commit is contained in:
parent
6af50f5eae
commit
f6c78d57ef
|
@ -6548,7 +6548,7 @@ void ByteCodeProcedure::Compile(ByteCodeGenerator* generator, InterCodeProcedure
|
||||||
{
|
{
|
||||||
mID = proc->mID;
|
mID = proc->mID;
|
||||||
|
|
||||||
mNumBlocks = proc->mBlocks.Size();
|
mNumBlocks = proc->mNumBlocks;
|
||||||
|
|
||||||
tblocks = new ByteCodeBasicBlock * [mNumBlocks];
|
tblocks = new ByteCodeBasicBlock * [mNumBlocks];
|
||||||
for (int i = 0; i < mNumBlocks; i++)
|
for (int i = 0; i < mNumBlocks; i++)
|
||||||
|
|
|
@ -104,6 +104,7 @@ static const uint64 DTF_CONSTEXPR = (1ULL << 31);
|
||||||
static const uint64 DTF_AUTO_TEMPLATE = (1ULL << 32);
|
static const uint64 DTF_AUTO_TEMPLATE = (1ULL << 32);
|
||||||
static const uint64 DTF_BANK_INLAY = (1ULL << 33);
|
static const uint64 DTF_BANK_INLAY = (1ULL << 33);
|
||||||
static const uint64 DTF_PURE_VIRTUAL = (1ULL << 34);
|
static const uint64 DTF_PURE_VIRTUAL = (1ULL << 34);
|
||||||
|
static const uint64 DTF_FORCE_INLINE = (1ULL << 35);
|
||||||
|
|
||||||
static const uint64 DTF_FUNC_VARIABLE = (1ULL << 36);
|
static const uint64 DTF_FUNC_VARIABLE = (1ULL << 36);
|
||||||
static const uint64 DTF_FUNC_ASSEMBLER = (1ULL << 37);
|
static const uint64 DTF_FUNC_ASSEMBLER = (1ULL << 37);
|
||||||
|
@ -127,6 +128,7 @@ static const uint64 DTF_DEPRECATED = (1ULL << 50);
|
||||||
static const uint64 DTF_FUNC_NO_RETURN = (1ULL << 51);
|
static const uint64 DTF_FUNC_NO_RETURN = (1ULL << 51);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Declaration;
|
class Declaration;
|
||||||
|
|
||||||
enum ScopeLevel
|
enum ScopeLevel
|
||||||
|
|
|
@ -43,6 +43,7 @@ enum ErrorID
|
||||||
EWARN_INVALID_VALUE_RANGE,
|
EWARN_INVALID_VALUE_RANGE,
|
||||||
EWARN_DEFAULT_COPY_DEPRECATED,
|
EWARN_DEFAULT_COPY_DEPRECATED,
|
||||||
EWARN_INSUFFICIENT_MEMORY,
|
EWARN_INSUFFICIENT_MEMORY,
|
||||||
|
EWARN_FUNCTION_NOT_INLINED,
|
||||||
|
|
||||||
EERR_GENERIC = 3000,
|
EERR_GENERIC = 3000,
|
||||||
EERR_FILE_NOT_FOUND,
|
EERR_FILE_NOT_FOUND,
|
||||||
|
|
|
@ -161,7 +161,7 @@ int GlobalAnalyzer::CallerInvokes(Declaration* called)
|
||||||
int GlobalAnalyzer::CallerInvokes(Declaration* caller, Declaration* called)
|
int GlobalAnalyzer::CallerInvokes(Declaration* caller, Declaration* called)
|
||||||
{
|
{
|
||||||
int n = 1;
|
int n = 1;
|
||||||
if (caller->mType == DT_CONST_FUNCTION && (caller->mFlags & (DTF_INLINE | DTF_REQUEST_INLINE)) && !(caller->mFlags & DTF_PREVENT_INLINE) && !(caller->mFlags & DTF_FUNC_RECURSIVE) && !(caller->mFlags & DTF_FUNC_VARIABLE) && !(caller->mFlags & DTF_EXPORT))
|
if (caller->mType == DT_CONST_FUNCTION && (caller->mFlags & (DTF_INLINE | DTF_FORCE_INLINE | DTF_REQUEST_INLINE)) && !(caller->mFlags & DTF_PREVENT_INLINE) && !(caller->mFlags & DTF_FUNC_RECURSIVE) && !(caller->mFlags & DTF_FUNC_VARIABLE) && !(caller->mFlags & DTF_EXPORT))
|
||||||
n = CallerInvokes(caller);
|
n = CallerInvokes(caller);
|
||||||
return n > 1 ? n : 1;
|
return n > 1 ? n : 1;
|
||||||
}
|
}
|
||||||
|
@ -206,7 +206,7 @@ void GlobalAnalyzer::AutoInline(void)
|
||||||
// printf("CHECK INLINING %s (%d) %d * (%d - 1)\n", f->mIdent->mString, f->mComplexity, cost, invokes);
|
// printf("CHECK INLINING %s (%d) %d * (%d - 1)\n", f->mIdent->mString, f->mComplexity, cost, invokes);
|
||||||
|
|
||||||
bool doinline = false;
|
bool doinline = false;
|
||||||
if ((f->mCompilerOptions & COPT_OPTIMIZE_INLINE) && (f->mFlags & DTF_REQUEST_INLINE))
|
if ((f->mCompilerOptions & COPT_OPTIMIZE_INLINE) && (f->mFlags & DTF_REQUEST_INLINE) || (f->mFlags & DTF_FORCE_INLINE))
|
||||||
doinline = true;
|
doinline = true;
|
||||||
if (f->mLocalSize < 100)
|
if (f->mLocalSize < 100)
|
||||||
{
|
{
|
||||||
|
|
|
@ -5844,7 +5844,7 @@ InterCodeBasicBlock::InterCodeBasicBlock(InterCodeProcedure * proc)
|
||||||
mUnreachable = false;
|
mUnreachable = false;
|
||||||
mValueRangeValid = false;
|
mValueRangeValid = false;
|
||||||
|
|
||||||
mIndex = proc->mBlocks.Size();
|
mIndex = proc->mNumBlocks++;
|
||||||
proc->mBlocks.Push(this);
|
proc->mBlocks.Push(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7441,6 +7441,8 @@ bool InterCodeBasicBlock::EarlyBranchElimination(const GrowingInstructionPtrArra
|
||||||
if (cins->mConst.mType == IT_BOOL)
|
if (cins->mConst.mType == IT_BOOL)
|
||||||
{
|
{
|
||||||
mInstructions[sz - 1]->mCode = IC_JUMP;
|
mInstructions[sz - 1]->mCode = IC_JUMP;
|
||||||
|
mInstructions[sz - 1]->mNumOperands = 0;
|
||||||
|
|
||||||
if (cins->mConst.mIntConst)
|
if (cins->mConst.mIntConst)
|
||||||
mFalseJump->mNumEntries--;
|
mFalseJump->mNumEntries--;
|
||||||
else
|
else
|
||||||
|
@ -21668,7 +21670,7 @@ void InterCodeBasicBlock::WarnUnreachable(void)
|
||||||
|
|
||||||
|
|
||||||
InterCodeProcedure::InterCodeProcedure(InterCodeModule * mod, const Location & location, const Ident* ident, LinkerObject * linkerObject)
|
InterCodeProcedure::InterCodeProcedure(InterCodeModule * mod, const Location & location, const Ident* ident, LinkerObject * linkerObject)
|
||||||
: mTemporaries(IT_NONE), mBlocks(nullptr), mLocation(location), mTempOffset(-1), mTempSizes(0),
|
: mTemporaries(IT_NONE), mBlocks(nullptr), mLocation(location), mTempOffset(-1), mTempSizes(0), mNumBlocks(0),
|
||||||
mRenameTable(-1), mRenameUnionTable(-1), mGlobalRenameTable(-1),
|
mRenameTable(-1), mRenameUnionTable(-1), mGlobalRenameTable(-1),
|
||||||
mValueForwardingTable(nullptr), mLocalVars(nullptr), mParamVars(nullptr), mModule(mod),
|
mValueForwardingTable(nullptr), mLocalVars(nullptr), mParamVars(nullptr), mModule(mod),
|
||||||
mIdent(ident), mLinkerObject(linkerObject),
|
mIdent(ident), mLinkerObject(linkerObject),
|
||||||
|
@ -21809,7 +21811,10 @@ void InterCodeProcedure::EarlyBranchElimination(void)
|
||||||
|
|
||||||
ResetVisited();
|
ResetVisited();
|
||||||
while (mEntryBlock->EarlyBranchElimination(ctemps))
|
while (mEntryBlock->EarlyBranchElimination(ctemps))
|
||||||
{}
|
{
|
||||||
|
BuildTraces(true);
|
||||||
|
TrimBlocks();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterCodeProcedure::BuildTraces(bool expand, bool dominators, bool compact)
|
void InterCodeProcedure::BuildTraces(bool expand, bool dominators, bool compact)
|
||||||
|
@ -21847,6 +21852,24 @@ void InterCodeProcedure::BuildTraces(bool expand, bool dominators, bool compact)
|
||||||
mEntryBlock->BuildDominatorTree(nullptr);
|
mEntryBlock->BuildDominatorTree(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InterCodeProcedure::TrimBlocks(void)
|
||||||
|
{
|
||||||
|
int j = 1;
|
||||||
|
for (int i = 1; i < mBlocks.Size(); i++)
|
||||||
|
{
|
||||||
|
InterCodeBasicBlock* block = mBlocks[i];
|
||||||
|
if (block->mNumEntries > 0)
|
||||||
|
{
|
||||||
|
block->mIndex = j;
|
||||||
|
mBlocks[j++] = block;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
delete block;
|
||||||
|
}
|
||||||
|
mBlocks.SetSize(j, false);
|
||||||
|
mNumBlocks = j;
|
||||||
|
}
|
||||||
|
|
||||||
void InterCodeProcedure::BuildDataFlowSets(void)
|
void InterCodeProcedure::BuildDataFlowSets(void)
|
||||||
{
|
{
|
||||||
int numTemps = mTemporaries.Size();
|
int numTemps = mTemporaries.Size();
|
||||||
|
|
|
@ -690,6 +690,7 @@ protected:
|
||||||
void ResetEntryBlocks(void);
|
void ResetEntryBlocks(void);
|
||||||
public:
|
public:
|
||||||
InterCodeBasicBlock * mEntryBlock;
|
InterCodeBasicBlock * mEntryBlock;
|
||||||
|
int mNumBlocks;
|
||||||
GrowingInterCodeBasicBlockPtrArray mBlocks;
|
GrowingInterCodeBasicBlockPtrArray mBlocks;
|
||||||
GrowingTypeArray mTemporaries;
|
GrowingTypeArray mTemporaries;
|
||||||
GrowingIntArray mTempOffset, mTempSizes;
|
GrowingIntArray mTempOffset, mTempSizes;
|
||||||
|
@ -748,6 +749,7 @@ public:
|
||||||
protected:
|
protected:
|
||||||
void BuildLocalAliasTable(void);
|
void BuildLocalAliasTable(void);
|
||||||
void BuildTraces(bool expand, bool dominators = true, bool compact = false);
|
void BuildTraces(bool expand, bool dominators = true, bool compact = false);
|
||||||
|
void TrimBlocks(void);
|
||||||
void EarlyBranchElimination(void);
|
void EarlyBranchElimination(void);
|
||||||
void BuildDataFlowSets(void);
|
void BuildDataFlowSets(void);
|
||||||
void RenameTemporaries(void);
|
void RenameTemporaries(void);
|
||||||
|
|
|
@ -1797,7 +1797,7 @@ void InterCodeGenerator::CopyStruct(InterCodeProcedure* proc, Expression* exp, I
|
||||||
if (!ccdec->mLinkerObject)
|
if (!ccdec->mLinkerObject)
|
||||||
this->TranslateProcedure(proc->mModule, ccdec->mValue, ccdec);
|
this->TranslateProcedure(proc->mModule, ccdec->mValue, ccdec);
|
||||||
|
|
||||||
bool canInline = (mCompilerOptions & COPT_OPTIMIZE_INLINE) && !(inlineMapper && inlineMapper->mDepth > 10);
|
bool canInline = ((mCompilerOptions & COPT_OPTIMIZE_INLINE) || (ccdec->mFlags & DTF_FORCE_INLINE)) && !(inlineMapper && inlineMapper->mDepth > 10);
|
||||||
bool doInline = false;
|
bool doInline = false;
|
||||||
|
|
||||||
if (canInline)
|
if (canInline)
|
||||||
|
@ -1812,6 +1812,9 @@ void InterCodeGenerator::CopyStruct(InterCodeProcedure* proc, Expression* exp, I
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((ccdec->mFlags & DTF_FORCE_INLINE) && !doInline)
|
||||||
|
mErrors->Error(exp->mLocation, EWARN_FUNCTION_NOT_INLINED, "Function with __forceinline not inlined", ccdec->mQualIdent);
|
||||||
|
|
||||||
if (doInline)
|
if (doInline)
|
||||||
{
|
{
|
||||||
DestructStack* destack = nullptr;
|
DestructStack* destack = nullptr;
|
||||||
|
@ -3781,7 +3784,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
|
|
||||||
bool canInline = exp->mLeft->mType == EX_CONSTANT &&
|
bool canInline = exp->mLeft->mType == EX_CONSTANT &&
|
||||||
exp->mLeft->mDecValue->mType == DT_CONST_FUNCTION &&
|
exp->mLeft->mDecValue->mType == DT_CONST_FUNCTION &&
|
||||||
(mCompilerOptions & COPT_OPTIMIZE_INLINE) &&
|
((mCompilerOptions & COPT_OPTIMIZE_INLINE) || (exp->mLeft->mDecValue->mFlags & DTF_FORCE_INLINE)) &&
|
||||||
!(inlineMapper && inlineMapper->mDepth > 10) &&
|
!(inlineMapper && inlineMapper->mDepth > 10) &&
|
||||||
exp->mType != EX_VCALL;
|
exp->mType != EX_VCALL;
|
||||||
bool doInline = false, inlineConstexpr = false;
|
bool doInline = false, inlineConstexpr = false;
|
||||||
|
@ -3831,7 +3834,10 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Expression * funcexp = exp->mLeft;
|
Expression* funcexp = exp->mLeft;
|
||||||
|
|
||||||
|
if (funcexp->mType == EX_CONSTANT && (funcexp->mDecValue->mFlags & DTF_FORCE_INLINE))
|
||||||
|
mErrors->Error(exp->mLocation, EWARN_FUNCTION_NOT_INLINED, "Function with __forceinline not inlined", funcexp->mDecValue->mQualIdent);
|
||||||
|
|
||||||
vl = TranslateExpression(procType, proc, block, funcexp, destack, gotos, breakBlock, continueBlock, inlineMapper);
|
vl = TranslateExpression(procType, proc, block, funcexp, destack, gotos, breakBlock, continueBlock, inlineMapper);
|
||||||
|
|
||||||
|
|
|
@ -4699,6 +4699,11 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
|
||||||
storageFlags |= DTF_PREVENT_INLINE;
|
storageFlags |= DTF_PREVENT_INLINE;
|
||||||
mScanner->NextToken();
|
mScanner->NextToken();
|
||||||
}
|
}
|
||||||
|
else if (mScanner->mToken == TK_FORCEINLINE)
|
||||||
|
{
|
||||||
|
storageFlags |= DTF_FORCE_INLINE | DTF_REQUEST_INLINE;
|
||||||
|
mScanner->NextToken();
|
||||||
|
}
|
||||||
else if (mScanner->mToken == TK_INLINE)
|
else if (mScanner->mToken == TK_INLINE)
|
||||||
{
|
{
|
||||||
storageFlags |= DTF_REQUEST_INLINE;
|
storageFlags |= DTF_REQUEST_INLINE;
|
||||||
|
@ -5341,7 +5346,7 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pdec->mFlags |= ndec->mFlags & (DTF_REQUEST_INLINE | DTF_PREVENT_INLINE);
|
pdec->mFlags |= ndec->mFlags & (DTF_REQUEST_INLINE | DTF_PREVENT_INLINE | DTF_FORCE_INLINE);
|
||||||
|
|
||||||
ndec = pdec;
|
ndec = pdec;
|
||||||
}
|
}
|
||||||
|
@ -5436,7 +5441,7 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
|
||||||
}
|
}
|
||||||
else if (pthis)
|
else if (pthis)
|
||||||
{
|
{
|
||||||
ndec->mFlags |= storageFlags & (DTF_STATIC | DTF_PREVENT_INLINE);
|
ndec->mFlags |= storageFlags & (DTF_STATIC | DTF_PREVENT_INLINE | DTF_FORCE_INLINE);
|
||||||
}
|
}
|
||||||
|
|
||||||
ndec->mOffset = 0;
|
ndec->mOffset = 0;
|
||||||
|
@ -11372,6 +11377,7 @@ void Parser::ParseTemplateDeclarationBody(Declaration * tdec, Declaration * pthi
|
||||||
|
|
||||||
ConsumeTokenIf(TK_INLINE);
|
ConsumeTokenIf(TK_INLINE);
|
||||||
ConsumeTokenIf(TK_NOINLINE);
|
ConsumeTokenIf(TK_NOINLINE);
|
||||||
|
ConsumeTokenIf(TK_FORCEINLINE);
|
||||||
ConsumeTokenIf(TK_CONSTEXPR);
|
ConsumeTokenIf(TK_CONSTEXPR);
|
||||||
|
|
||||||
Declaration* bdec = ParseBaseTypeDeclaration(0, true);
|
Declaration* bdec = ParseBaseTypeDeclaration(0, true);
|
||||||
|
|
|
@ -60,6 +60,7 @@ const char* TokenNames[] =
|
||||||
"__export",
|
"__export",
|
||||||
"__zeropage",
|
"__zeropage",
|
||||||
"__noinline",
|
"__noinline",
|
||||||
|
"__forceinline",
|
||||||
"__striped",
|
"__striped",
|
||||||
"__dynstack",
|
"__dynstack",
|
||||||
|
|
||||||
|
@ -1798,6 +1799,8 @@ void Scanner::NextRawToken(void)
|
||||||
mToken = TK_ZEROPAGE;
|
mToken = TK_ZEROPAGE;
|
||||||
else if (!strcmp(tkident, "__noinline"))
|
else if (!strcmp(tkident, "__noinline"))
|
||||||
mToken = TK_NOINLINE;
|
mToken = TK_NOINLINE;
|
||||||
|
else if (!strcmp(tkident, "__forceinline"))
|
||||||
|
mToken = TK_FORCEINLINE;
|
||||||
else if (!strcmp(tkident, "__striped"))
|
else if (!strcmp(tkident, "__striped"))
|
||||||
mToken = TK_STRIPED;
|
mToken = TK_STRIPED;
|
||||||
else if (!strcmp(tkident, "__dynstack"))
|
else if (!strcmp(tkident, "__dynstack"))
|
||||||
|
|
|
@ -58,6 +58,7 @@ enum Token
|
||||||
TK_EXPORT,
|
TK_EXPORT,
|
||||||
TK_ZEROPAGE,
|
TK_ZEROPAGE,
|
||||||
TK_NOINLINE,
|
TK_NOINLINE,
|
||||||
|
TK_FORCEINLINE,
|
||||||
TK_STRIPED,
|
TK_STRIPED,
|
||||||
TK_DYNSTACK,
|
TK_DYNSTACK,
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue