Don't generate code to call DECORATE cast functions

- All the cast functions do is return their parameter, so skip the
  function call and use the parameter directly.
This commit is contained in:
Randy Heit 2016-02-29 22:26:05 -06:00
parent 92f74634d6
commit 7c9fd12fc0
2 changed files with 50 additions and 0 deletions

View file

@ -858,6 +858,7 @@ public:
FxExpression *Resolve(FCompileContext&);
ExpEmit Emit(VMFunctionBuilder *build);
ExpEmit Emit(VMFunctionBuilder *build, bool tailcall);
bool CheckEmitCast(VMFunctionBuilder *build, bool returnit, ExpEmit &reg);
unsigned GetArgCount() const { return ArgList == NULL ? 0 : ArgList->Size(); }
VMFunction *GetVMFunction() const { return Function->Variants[0].Implementation; }
bool IsDirectFunction();

View file

@ -3356,6 +3356,14 @@ ExpEmit FxVMFunctionCall::Emit(VMFunctionBuilder *build, bool tailcall)
assert(build->Registers[REGT_POINTER].GetMostUsed() >= 3);
int count = GetArgCount();
if (count == 1)
{
ExpEmit reg;
if (CheckEmitCast(build, tailcall, reg))
{
return reg;
}
}
// Emit code to pass implied parameters
if (Function->Flags & VARF_Method)
{
@ -3399,6 +3407,47 @@ ExpEmit FxVMFunctionCall::Emit(VMFunctionBuilder *build, bool tailcall)
}
}
//==========================================================================
//
// If calling one of the casting kludge functions, don't bother calling the
// function; just use the parameter directly. Returns true if this was a
// kludge function, false otherwise.
//
//==========================================================================
bool FxVMFunctionCall::CheckEmitCast(VMFunctionBuilder *build, bool returnit, ExpEmit &reg)
{
FName funcname = Function->SymbolName;
if (funcname == NAME___decorate_internal_int__ ||
funcname == NAME___decorate_internal_bool__ ||
funcname == NAME___decorate_internal_state__)
{
FxExpression *arg = (*ArgList)[0];
if (returnit)
{
if (arg->isConstant() &&
(funcname == NAME___decorate_internal_int__ ||
funcname == NAME___decorate_internal_bool__))
{ // Use immediate version for integers in range
build->EmitRetInt(0, true, static_cast<FxConstant *>(arg)->GetValue().Int);
}
else
{
ExpEmit where = arg->Emit(build);
build->Emit(OP_RET, RET_FINAL, where.RegType | (where.Konst ? REGT_KONST : 0), where.RegNum);
where.Free(build);
}
reg = ExpEmit();
}
else
{
reg = arg->Emit(build);
}
return true;
}
return false;
}
//==========================================================================
//
//