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;
|
||||
|
||||
mNumBlocks = proc->mBlocks.Size();
|
||||
mNumBlocks = proc->mNumBlocks;
|
||||
|
||||
tblocks = new ByteCodeBasicBlock * [mNumBlocks];
|
||||
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_BANK_INLAY = (1ULL << 33);
|
||||
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_ASSEMBLER = (1ULL << 37);
|
||||
|
@ -127,6 +128,7 @@ static const uint64 DTF_DEPRECATED = (1ULL << 50);
|
|||
static const uint64 DTF_FUNC_NO_RETURN = (1ULL << 51);
|
||||
|
||||
|
||||
|
||||
class Declaration;
|
||||
|
||||
enum ScopeLevel
|
||||
|
|
|
@ -43,6 +43,7 @@ enum ErrorID
|
|||
EWARN_INVALID_VALUE_RANGE,
|
||||
EWARN_DEFAULT_COPY_DEPRECATED,
|
||||
EWARN_INSUFFICIENT_MEMORY,
|
||||
EWARN_FUNCTION_NOT_INLINED,
|
||||
|
||||
EERR_GENERIC = 3000,
|
||||
EERR_FILE_NOT_FOUND,
|
||||
|
|
|
@ -161,7 +161,7 @@ int GlobalAnalyzer::CallerInvokes(Declaration* called)
|
|||
int GlobalAnalyzer::CallerInvokes(Declaration* caller, Declaration* called)
|
||||
{
|
||||
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);
|
||||
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);
|
||||
|
||||
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;
|
||||
if (f->mLocalSize < 100)
|
||||
{
|
||||
|
|
|
@ -5844,7 +5844,7 @@ InterCodeBasicBlock::InterCodeBasicBlock(InterCodeProcedure * proc)
|
|||
mUnreachable = false;
|
||||
mValueRangeValid = false;
|
||||
|
||||
mIndex = proc->mBlocks.Size();
|
||||
mIndex = proc->mNumBlocks++;
|
||||
proc->mBlocks.Push(this);
|
||||
}
|
||||
|
||||
|
@ -7441,6 +7441,8 @@ bool InterCodeBasicBlock::EarlyBranchElimination(const GrowingInstructionPtrArra
|
|||
if (cins->mConst.mType == IT_BOOL)
|
||||
{
|
||||
mInstructions[sz - 1]->mCode = IC_JUMP;
|
||||
mInstructions[sz - 1]->mNumOperands = 0;
|
||||
|
||||
if (cins->mConst.mIntConst)
|
||||
mFalseJump->mNumEntries--;
|
||||
else
|
||||
|
@ -21668,7 +21670,7 @@ void InterCodeBasicBlock::WarnUnreachable(void)
|
|||
|
||||
|
||||
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),
|
||||
mValueForwardingTable(nullptr), mLocalVars(nullptr), mParamVars(nullptr), mModule(mod),
|
||||
mIdent(ident), mLinkerObject(linkerObject),
|
||||
|
@ -21809,7 +21811,10 @@ void InterCodeProcedure::EarlyBranchElimination(void)
|
|||
|
||||
ResetVisited();
|
||||
while (mEntryBlock->EarlyBranchElimination(ctemps))
|
||||
{}
|
||||
{
|
||||
BuildTraces(true);
|
||||
TrimBlocks();
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
int numTemps = mTemporaries.Size();
|
||||
|
|
|
@ -690,6 +690,7 @@ protected:
|
|||
void ResetEntryBlocks(void);
|
||||
public:
|
||||
InterCodeBasicBlock * mEntryBlock;
|
||||
int mNumBlocks;
|
||||
GrowingInterCodeBasicBlockPtrArray mBlocks;
|
||||
GrowingTypeArray mTemporaries;
|
||||
GrowingIntArray mTempOffset, mTempSizes;
|
||||
|
@ -748,6 +749,7 @@ public:
|
|||
protected:
|
||||
void BuildLocalAliasTable(void);
|
||||
void BuildTraces(bool expand, bool dominators = true, bool compact = false);
|
||||
void TrimBlocks(void);
|
||||
void EarlyBranchElimination(void);
|
||||
void BuildDataFlowSets(void);
|
||||
void RenameTemporaries(void);
|
||||
|
|
|
@ -1797,7 +1797,7 @@ void InterCodeGenerator::CopyStruct(InterCodeProcedure* proc, Expression* exp, I
|
|||
if (!ccdec->mLinkerObject)
|
||||
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;
|
||||
|
||||
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)
|
||||
{
|
||||
DestructStack* destack = nullptr;
|
||||
|
@ -3781,7 +3784,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
|
||||
bool canInline = exp->mLeft->mType == EX_CONSTANT &&
|
||||
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) &&
|
||||
exp->mType != EX_VCALL;
|
||||
bool doInline = false, inlineConstexpr = false;
|
||||
|
@ -3831,8 +3834,11 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
}
|
||||
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 = Dereference(proc, exp, block, inlineMapper, vl);
|
||||
|
|
|
@ -4699,6 +4699,11 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
|
|||
storageFlags |= DTF_PREVENT_INLINE;
|
||||
mScanner->NextToken();
|
||||
}
|
||||
else if (mScanner->mToken == TK_FORCEINLINE)
|
||||
{
|
||||
storageFlags |= DTF_FORCE_INLINE | DTF_REQUEST_INLINE;
|
||||
mScanner->NextToken();
|
||||
}
|
||||
else if (mScanner->mToken == TK_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;
|
||||
}
|
||||
|
@ -5436,7 +5441,7 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
|
|||
}
|
||||
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;
|
||||
|
@ -11372,6 +11377,7 @@ void Parser::ParseTemplateDeclarationBody(Declaration * tdec, Declaration * pthi
|
|||
|
||||
ConsumeTokenIf(TK_INLINE);
|
||||
ConsumeTokenIf(TK_NOINLINE);
|
||||
ConsumeTokenIf(TK_FORCEINLINE);
|
||||
ConsumeTokenIf(TK_CONSTEXPR);
|
||||
|
||||
Declaration* bdec = ParseBaseTypeDeclaration(0, true);
|
||||
|
|
|
@ -60,6 +60,7 @@ const char* TokenNames[] =
|
|||
"__export",
|
||||
"__zeropage",
|
||||
"__noinline",
|
||||
"__forceinline",
|
||||
"__striped",
|
||||
"__dynstack",
|
||||
|
||||
|
@ -1798,6 +1799,8 @@ void Scanner::NextRawToken(void)
|
|||
mToken = TK_ZEROPAGE;
|
||||
else if (!strcmp(tkident, "__noinline"))
|
||||
mToken = TK_NOINLINE;
|
||||
else if (!strcmp(tkident, "__forceinline"))
|
||||
mToken = TK_FORCEINLINE;
|
||||
else if (!strcmp(tkident, "__striped"))
|
||||
mToken = TK_STRIPED;
|
||||
else if (!strcmp(tkident, "__dynstack"))
|
||||
|
|
|
@ -58,6 +58,7 @@ enum Token
|
|||
TK_EXPORT,
|
||||
TK_ZEROPAGE,
|
||||
TK_NOINLINE,
|
||||
TK_FORCEINLINE,
|
||||
TK_STRIPED,
|
||||
TK_DYNSTACK,
|
||||
|
||||
|
|
Loading…
Reference in New Issue