Add __forceinline storage specifier

This commit is contained in:
drmortalwombat 2024-10-02 18:27:20 +02:00
parent 6af50f5eae
commit f6c78d57ef
10 changed files with 56 additions and 12 deletions

View File

@ -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++)

View File

@ -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

View File

@ -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,

View File

@ -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)
{

View File

@ -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();

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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"))

View File

@ -58,6 +58,7 @@ enum Token
TK_EXPORT,
TK_ZEROPAGE,
TK_NOINLINE,
TK_FORCEINLINE,
TK_STRIPED,
TK_DYNSTACK,