From d4d74ed37c47be2931a3d7555412f268aaeab689 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Wed, 4 Nov 2020 09:23:34 -0800 Subject: [PATCH] Fixed switch with constant value and fallthroughs --- IDEHelper/Backend/BeMCContext.cpp | 42 +++++++++++++++++--------- IDEHelper/Compiler/BfStmtEvaluator.cpp | 6 +++- 2 files changed, 32 insertions(+), 16 deletions(-) diff --git a/IDEHelper/Backend/BeMCContext.cpp b/IDEHelper/Backend/BeMCContext.cpp index 9181f0bb..e9acf154 100644 --- a/IDEHelper/Backend/BeMCContext.cpp +++ b/IDEHelper/Backend/BeMCContext.cpp @@ -3744,7 +3744,7 @@ BeMCOperand BeMCContext::AllocVirtualReg(BeType* type, int refCount, bool mustBe if (mDebugging) { - if (mcOperand.mVRegIdx == 14) + if (mcOperand.mVRegIdx == 6) { NOP; } @@ -8611,23 +8611,35 @@ void BeMCContext::DoActualization() if (vregInfo->mIsExpr) { - // Create a new reg with the expression, and then load the value into the old non-expressionized reg - // This has the advantage of fixing any other references to this expr, too - auto scratchReg = AllocVirtualReg(vregInfo->mType, 2, false); - auto scratchVRegInfo = mVRegInfo[scratchReg.mVRegIdx]; + if (vregInfo->IsDirectRelToAny()) + { + AllocInst(BeMCInstKind_Mov, BeMCOperand::FromVReg(vregIdx), vregInfo->mRelTo, instIdx++ + 1); - scratchVRegInfo->mIsExpr = true; - scratchVRegInfo->mRelTo = vregInfo->mRelTo; - scratchVRegInfo->mRelOffset = vregInfo->mRelOffset; - scratchVRegInfo->mRelOffsetScale = vregInfo->mRelOffsetScale; + vregInfo->mIsExpr = false; + vregInfo->mRelTo = BeMCOperand(); + vregInfo->mRelOffset = BeMCOperand(); + vregInfo->mRelOffsetScale = 1; + } + else + { + // Create a new reg with the expression, and then load the value into the old non-expressionized reg + // This has the advantage of fixing any other references to this expr, too + auto scratchReg = AllocVirtualReg(vregInfo->mType, 2, false); + auto scratchVRegInfo = mVRegInfo[scratchReg.mVRegIdx]; - vregInfo->mIsExpr = false; - vregInfo->mRelTo = BeMCOperand(); - vregInfo->mRelOffset = BeMCOperand(); - vregInfo->mRelOffsetScale = 1; + scratchVRegInfo->mIsExpr = true; + scratchVRegInfo->mRelTo = vregInfo->mRelTo; + scratchVRegInfo->mRelOffset = vregInfo->mRelOffset; + scratchVRegInfo->mRelOffsetScale = vregInfo->mRelOffsetScale; - CreateDefineVReg(scratchReg, instIdx++ + 1); - AllocInst(BeMCInstKind_Mov, BeMCOperand::FromVReg(vregIdx), scratchReg, instIdx++ + 1); + vregInfo->mIsExpr = false; + vregInfo->mRelTo = BeMCOperand(); + vregInfo->mRelOffset = BeMCOperand(); + vregInfo->mRelOffsetScale = 1; + + CreateDefineVReg(scratchReg, instIdx++ + 1); + AllocInst(BeMCInstKind_Mov, BeMCOperand::FromVReg(vregIdx), scratchReg, instIdx++ + 1); + } } } } diff --git a/IDEHelper/Compiler/BfStmtEvaluator.cpp b/IDEHelper/Compiler/BfStmtEvaluator.cpp index 7fba147a..c61689cc 100644 --- a/IDEHelper/Compiler/BfStmtEvaluator.cpp +++ b/IDEHelper/Compiler/BfStmtEvaluator.cpp @@ -4311,6 +4311,8 @@ void BfModule::Visit(BfSwitchStatement* switchStmt) auto startingLocalVarId = mCurMethodState->GetRootMethodState()->mCurLocalVarId; + bool prevHadFallthrough = false; + Dictionary handledCases; for (BfSwitchCase* switchCase : switchStmt->mSwitchCases) { @@ -4596,7 +4598,7 @@ void BfModule::Visit(BfSwitchStatement* switchStmt) auto prevInsertBlock = mBfIRBuilder->GetInsertBlock(); - SetAndRestoreValue prevIgnoreWrites(mBfIRBuilder->mIgnoreWrites, true, !mayHaveMatch); + SetAndRestoreValue prevIgnoreWrites(mBfIRBuilder->mIgnoreWrites, true, !mayHaveMatch && !prevHadFallthrough); mBfIRBuilder->AddBlock(caseBlock); mBfIRBuilder->SetInsertPoint(caseBlock); @@ -4677,6 +4679,8 @@ void BfModule::Visit(BfSwitchStatement* switchStmt) prevIgnoreWrites.Restore(); mBfIRBuilder->SetInsertPoint(prevInsertBlock); + + prevHadFallthrough = mCurMethodState->mDeferredLocalAssignData->mHadFallthrough; blockIdx++; }