mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-13 07:57:58 +00:00
- added an optimization to FxBoolCast that it doesn't force the source value to a 0/1 integer if not explicitly needed. When doing comparisons we do not care about actual values, we only want to know if it is 0 or not.
- added the above for the 'if' condition. It works for integers, floats and pointers and will save 3 instructions if the condition is a non-boolean that can be implicitly casted to bool.
This commit is contained in:
parent
5b952b116a
commit
da56e5908d
2 changed files with 49 additions and 26 deletions
|
@ -434,11 +434,12 @@ ExpEmit FxConstant::Emit(VMFunctionBuilder *build)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
FxBoolCast::FxBoolCast(FxExpression *x)
|
FxBoolCast::FxBoolCast(FxExpression *x, bool needvalue)
|
||||||
: FxExpression(EFX_BoolCast, x->ScriptPosition)
|
: FxExpression(EFX_BoolCast, x->ScriptPosition)
|
||||||
{
|
{
|
||||||
basex = x;
|
basex = x;
|
||||||
ValueType = TypeBool;
|
ValueType = TypeBool;
|
||||||
|
NeedValue = needvalue;
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -499,9 +500,11 @@ ExpEmit FxBoolCast::Emit(VMFunctionBuilder *build)
|
||||||
ExpEmit from = basex->Emit(build);
|
ExpEmit from = basex->Emit(build);
|
||||||
assert(!from.Konst);
|
assert(!from.Konst);
|
||||||
assert(basex->ValueType->GetRegType() == REGT_INT || basex->ValueType->GetRegType() == REGT_FLOAT || basex->ValueType->GetRegType() == REGT_POINTER);
|
assert(basex->ValueType->GetRegType() == REGT_INT || basex->ValueType->GetRegType() == REGT_FLOAT || basex->ValueType->GetRegType() == REGT_POINTER);
|
||||||
|
|
||||||
|
if (NeedValue)
|
||||||
|
{
|
||||||
ExpEmit to(build, REGT_INT);
|
ExpEmit to(build, REGT_INT);
|
||||||
from.Free(build);
|
from.Free(build);
|
||||||
|
|
||||||
// Preload result with 0.
|
// Preload result with 0.
|
||||||
build->Emit(OP_LI, to.RegNum, 0);
|
build->Emit(OP_LI, to.RegNum, 0);
|
||||||
|
|
||||||
|
@ -522,8 +525,12 @@ ExpEmit FxBoolCast::Emit(VMFunctionBuilder *build)
|
||||||
|
|
||||||
// Reload result with 1 if the comparison fell through.
|
// Reload result with 1 if the comparison fell through.
|
||||||
build->Emit(OP_LI, to.RegNum, 1);
|
build->Emit(OP_LI, to.RegNum, 1);
|
||||||
|
|
||||||
return to;
|
return to;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return from;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -5871,7 +5878,7 @@ FxExpression *FxIfStatement::Resolve(FCompileContext &ctx)
|
||||||
|
|
||||||
if (Condition->ValueType != TypeBool)
|
if (Condition->ValueType != TypeBool)
|
||||||
{
|
{
|
||||||
Condition = new FxBoolCast(Condition);
|
Condition = new FxBoolCast(Condition, false);
|
||||||
SAFE_RESOLVE(Condition, ctx);
|
SAFE_RESOLVE(Condition, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5914,7 +5921,7 @@ ExpEmit FxIfStatement::Emit(VMFunctionBuilder *build)
|
||||||
// This is pretty much copied from FxConditional, except we don't
|
// This is pretty much copied from FxConditional, except we don't
|
||||||
// keep any results.
|
// keep any results.
|
||||||
ExpEmit cond = Condition->Emit(build);
|
ExpEmit cond = Condition->Emit(build);
|
||||||
assert(cond.RegType == REGT_INT && !cond.Konst);
|
assert(cond.RegType != REGT_STRING && !cond.Konst);
|
||||||
|
|
||||||
if (WhenTrue != NULL)
|
if (WhenTrue != NULL)
|
||||||
{
|
{
|
||||||
|
@ -5933,7 +5940,22 @@ ExpEmit FxIfStatement::Emit(VMFunctionBuilder *build)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test condition.
|
// Test condition.
|
||||||
|
|
||||||
|
switch (cond.RegType)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case REGT_INT:
|
||||||
build->Emit(OP_EQ_K, condcheck, cond.RegNum, build->GetConstantInt(0));
|
build->Emit(OP_EQ_K, condcheck, cond.RegNum, build->GetConstantInt(0));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case REGT_FLOAT:
|
||||||
|
build->Emit(OP_EQF_K, condcheck, cond.RegNum, build->GetConstantFloat(0));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case REGT_POINTER:
|
||||||
|
build->Emit(OP_EQA_K, condcheck, cond.RegNum, build->GetConstantAddress(nullptr, ATAG_GENERIC));
|
||||||
|
break;
|
||||||
|
}
|
||||||
jumpspot = build->Emit(OP_JMP, 0);
|
jumpspot = build->Emit(OP_JMP, 0);
|
||||||
cond.Free(build);
|
cond.Free(build);
|
||||||
|
|
||||||
|
|
|
@ -457,10 +457,11 @@ public:
|
||||||
class FxBoolCast : public FxExpression
|
class FxBoolCast : public FxExpression
|
||||||
{
|
{
|
||||||
FxExpression *basex;
|
FxExpression *basex;
|
||||||
|
bool NeedValue;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
FxBoolCast(FxExpression *x);
|
FxBoolCast(FxExpression *x, bool needvalue = true);
|
||||||
~FxBoolCast();
|
~FxBoolCast();
|
||||||
FxExpression *Resolve(FCompileContext&);
|
FxExpression *Resolve(FCompileContext&);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue