From 2bcfdcc06c8a0da4298563857662993c5d255149 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Sun, 23 Feb 2020 07:41:06 -0800 Subject: [PATCH] Improved spaceship- const evaluation, subtraction optimization --- IDEHelper/Compiler/BfExprEvaluator.cpp | 68 ++++++++++++++++++-------- IDEHelper/Tests/src/Spaceship.bf | 21 ++++++++ 2 files changed, 68 insertions(+), 21 deletions(-) create mode 100644 IDEHelper/Tests/src/Spaceship.bf diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index 5692c570..1303712a 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -18514,33 +18514,59 @@ void BfExprEvaluator::PerformBinaryOperation(BfType* resultType, BfIRValue convL case BfBinaryOp_Compare: { auto intType = mModule->GetPrimitiveType(BfTypeCode_IntPtr); + if ((convLeftValue.IsConst()) && (convRightValue.IsConst())) + { + auto cmpLtVal = mModule->mBfIRBuilder->CreateCmpLT(convLeftValue, convRightValue, resultType->IsSignedInt()); + auto ltConstant = mModule->mBfIRBuilder->GetConstant(cmpLtVal); + if (ltConstant->mBool) + { + mResult = BfTypedValue(mModule->GetConstValue(-1, mModule->GetPrimitiveType(BfTypeCode_IntPtr)), intType); + } + else + { + auto cmpGtVal = mModule->mBfIRBuilder->CreateCmpGT(convLeftValue, convRightValue, resultType->IsSignedInt()); + auto rtConstant = mModule->mBfIRBuilder->GetConstant(cmpGtVal); + if (rtConstant->mBool) + mResult = BfTypedValue(mModule->GetConstValue(1, mModule->GetPrimitiveType(BfTypeCode_IntPtr)), intType); + else + mResult = BfTypedValue(mModule->GetConstValue(0, mModule->GetPrimitiveType(BfTypeCode_IntPtr)), intType); + } + } + else if ((resultType->IsIntegral()) && (resultType->mSize < intType->mSize)) + { + auto leftIntValue = mModule->mBfIRBuilder->CreateNumericCast(convLeftValue, resultType->IsSignedInt(), BfTypeCode_IntPtr); + auto rightIntValue = mModule->mBfIRBuilder->CreateNumericCast(convRightValue, resultType->IsSignedInt(), BfTypeCode_IntPtr); + mResult = BfTypedValue(mModule->mBfIRBuilder->CreateSub(leftIntValue, rightIntValue), intType); + } + else + { + BfIRBlock checkGtBlock = mModule->mBfIRBuilder->CreateBlock("cmpCheckGt"); + BfIRBlock eqBlock = mModule->mBfIRBuilder->CreateBlock("cmpEq"); + BfIRBlock endBlock = mModule->mBfIRBuilder->CreateBlock("cmpEnd"); - BfIRBlock checkGtBlock = mModule->mBfIRBuilder->CreateBlock("cmpCheckGt"); - BfIRBlock eqBlock = mModule->mBfIRBuilder->CreateBlock("cmpEq"); - BfIRBlock endBlock = mModule->mBfIRBuilder->CreateBlock("cmpEnd"); + auto startBlock = mModule->mBfIRBuilder->GetInsertBlock(); - auto startBlock = mModule->mBfIRBuilder->GetInsertBlock(); + auto cmpLtVal = mModule->mBfIRBuilder->CreateCmpLT(convLeftValue, convRightValue, resultType->IsSignedInt()); + mModule->mBfIRBuilder->CreateCondBr(cmpLtVal, endBlock, checkGtBlock); - auto cmpLtVal = mModule->mBfIRBuilder->CreateCmpLT(convLeftValue, convRightValue, resultType->IsSignedInt()); - mModule->mBfIRBuilder->CreateCondBr(cmpLtVal, endBlock, checkGtBlock); + mModule->mBfIRBuilder->AddBlock(checkGtBlock); + mModule->mBfIRBuilder->SetInsertPoint(checkGtBlock); + auto cmpGtVal = mModule->mBfIRBuilder->CreateCmpGT(convLeftValue, convRightValue, resultType->IsSignedInt()); + mModule->mBfIRBuilder->CreateCondBr(cmpGtVal, endBlock, eqBlock); - mModule->mBfIRBuilder->AddBlock(checkGtBlock); - mModule->mBfIRBuilder->SetInsertPoint(checkGtBlock); - auto cmpGtVal = mModule->mBfIRBuilder->CreateCmpGT(convLeftValue, convRightValue, resultType->IsSignedInt()); - mModule->mBfIRBuilder->CreateCondBr(cmpGtVal, endBlock, eqBlock); + mModule->mBfIRBuilder->AddBlock(eqBlock); + mModule->mBfIRBuilder->SetInsertPoint(eqBlock); + mModule->mBfIRBuilder->CreateBr(endBlock); - mModule->mBfIRBuilder->AddBlock(eqBlock); - mModule->mBfIRBuilder->SetInsertPoint(eqBlock); - mModule->mBfIRBuilder->CreateBr(endBlock); + mModule->mBfIRBuilder->AddBlock(endBlock); + mModule->mBfIRBuilder->SetInsertPoint(endBlock); + auto phiVal = mModule->mBfIRBuilder->CreatePhi(mModule->mBfIRBuilder->MapType(intType), 3); + mModule->mBfIRBuilder->AddPhiIncoming(phiVal, mModule->mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, -1), startBlock); + mModule->mBfIRBuilder->AddPhiIncoming(phiVal, mModule->mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, 1), checkGtBlock); + mModule->mBfIRBuilder->AddPhiIncoming(phiVal, mModule->mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, 0), eqBlock); - mModule->mBfIRBuilder->AddBlock(endBlock); - mModule->mBfIRBuilder->SetInsertPoint(endBlock); - auto phiVal = mModule->mBfIRBuilder->CreatePhi(mModule->mBfIRBuilder->MapType(intType), 3); - mModule->mBfIRBuilder->AddPhiIncoming(phiVal, mModule->mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, -1), startBlock); - mModule->mBfIRBuilder->AddPhiIncoming(phiVal, mModule->mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, 1), checkGtBlock); - mModule->mBfIRBuilder->AddPhiIncoming(phiVal, mModule->mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, 0), eqBlock); - - mResult = BfTypedValue(phiVal, intType); + mResult = BfTypedValue(phiVal, intType); + } } break; default: diff --git a/IDEHelper/Tests/src/Spaceship.bf b/IDEHelper/Tests/src/Spaceship.bf new file mode 100644 index 00000000..9121a4b8 --- /dev/null +++ b/IDEHelper/Tests/src/Spaceship.bf @@ -0,0 +1,21 @@ +using System; + +namespace Tests +{ + class Spaceship + { + const bool sLess0 = 1.0 <=> 2.0 < 0; + + [Test] + public static void TestBasics() + { + Test.Assert(1 <=> 2 < 0); + Test.Assert(1.0 <=> 2.0 < 0); + + int8 i8a = -120; + int8 i8b = 100; + + Test.Assert(i8a <=> i8b < 0); + } + } +}