Skip to content

Commit 372cc14

Browse files
committed
Making Typeof-Br/Cm fast-path more generic
1 parent 5bfc37b commit 372cc14

File tree

3 files changed

+106
-90
lines changed

3 files changed

+106
-90
lines changed

lib/Backend/Lower.cpp

Lines changed: 99 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -24315,113 +24315,122 @@ Lowerer::TryGenerateFastBrOrCmTypeOf(IR::Instr *instr, IR::Instr **prev, bool is
2431524315

2431624316
if (typeOfDst && instrSrc1 && instrSrc2)
2431724317
{
24318-
IR::RegOpnd *typeOpnd = nullptr;
24319-
IR::RegOpnd *idOpnd = nullptr;
24320-
if (instrSrc1->m_sym == typeOfDst->m_sym)
24318+
do
2432124319
{
24322-
typeOpnd = instrSrc1;
24323-
idOpnd = instrSrc2;
24324-
}
24325-
else if (instrSrc2->m_sym == typeOfDst->m_sym)
24326-
{
24327-
typeOpnd = instrSrc2;
24328-
idOpnd = instrSrc1;
24329-
}
24330-
else
24331-
{
24332-
// Neither source turned out to be the typeOpnd
24333-
return false;
24334-
}
24320+
IR::RegOpnd *typeOpnd = nullptr;
24321+
IR::RegOpnd *idOpnd = nullptr;
24322+
if (instrSrc1->m_sym == typeOfDst->m_sym)
24323+
{
24324+
typeOpnd = instrSrc1;
24325+
idOpnd = instrSrc2;
24326+
}
24327+
else if (instrSrc2->m_sym == typeOfDst->m_sym)
24328+
{
24329+
typeOpnd = instrSrc2;
24330+
idOpnd = instrSrc1;
24331+
}
24332+
else
24333+
{
24334+
// Neither source turned out to be the typeOpnd
24335+
break;
24336+
}
2433524337

24336-
if (!typeOpnd->m_isTempLastUse)
24337-
{
24338-
return false;
24339-
}
24338+
if (!typeOpnd->m_isTempLastUse)
24339+
{
24340+
break;
24341+
}
2434024342

24341-
if (!(idOpnd->m_sym->m_isSingleDef && idOpnd->m_sym->m_isStrConst))
24342-
{
24343-
return false;
24344-
}
24343+
if (!(idOpnd->m_sym->m_isSingleDef && idOpnd->m_sym->m_isStrConst))
24344+
{
24345+
return false;
24346+
}
2434524347

24346-
// The second argument to [Cm|Br]TypeOf is the typeid.
24347-
IR::IntConstOpnd *typeIdOpnd = nullptr;
24348+
// The second argument to [Cm|Br]TypeOf is the typeid.
24349+
IR::IntConstOpnd *typeIdOpnd = nullptr;
2434824350

24349-
Assert(idOpnd->m_sym->m_isSingleDef);
24350-
Assert(idOpnd->m_sym->m_instrDef->GetSrc1()->IsAddrOpnd());
24351+
Assert(idOpnd->m_sym->m_isSingleDef);
24352+
Assert(idOpnd->m_sym->m_instrDef->GetSrc1()->IsAddrOpnd());
2435124353

24352-
// We can't optimize non-javascript type strings.
24353-
JITJavascriptString *typeNameJsString = JITJavascriptString::FromVar(idOpnd->m_sym->m_instrDef->GetSrc1()->AsAddrOpnd()->m_localAddress);
24354-
const char16 *typeName = typeNameJsString->GetString();
24354+
// We can't optimize non-javascript type strings.
24355+
JITJavascriptString *typeNameJsString = JITJavascriptString::FromVar(idOpnd->m_sym->m_instrDef->GetSrc1()->AsAddrOpnd()->m_localAddress);
24356+
const char16 *typeName = typeNameJsString->GetString();
2435524357

24356-
Js::InternalString typeNameString(typeName, typeNameJsString->GetLength());
24357-
if (Js::InternalStringComparer::Equals(typeNameString, Js::Type::UndefinedTypeNameString))
24358-
{
24359-
typeIdOpnd = IR::IntConstOpnd::New(Js::TypeIds_Undefined, TyInt32, instr->m_func);
24360-
}
24361-
else if (Js::InternalStringComparer::Equals(typeNameString, Js::Type::ObjectTypeNameString))
24362-
{
24363-
typeIdOpnd = IR::IntConstOpnd::New(Js::TypeIds_Object, TyInt32, instr->m_func);
24364-
}
24365-
else if (Js::InternalStringComparer::Equals(typeNameString, Js::Type::BooleanTypeNameString))
24366-
{
24367-
typeIdOpnd = IR::IntConstOpnd::New(Js::TypeIds_Boolean, TyInt32, instr->m_func);
24368-
}
24369-
else if (Js::InternalStringComparer::Equals(typeNameString, Js::Type::NumberTypeNameString))
24370-
{
24371-
typeIdOpnd = IR::IntConstOpnd::New(Js::TypeIds_Number, TyInt32, instr->m_func);
24372-
}
24373-
else if (Js::InternalStringComparer::Equals(typeNameString, Js::Type::StringTypeNameString))
24374-
{
24375-
typeIdOpnd = IR::IntConstOpnd::New(Js::TypeIds_String, TyInt32, instr->m_func);
24376-
}
24377-
else if (Js::InternalStringComparer::Equals(typeNameString, Js::Type::FunctionTypeNameString))
24378-
{
24379-
typeIdOpnd = IR::IntConstOpnd::New(Js::TypeIds_Function, TyInt32, instr->m_func);
24380-
}
24381-
else
24382-
{
24383-
return false;
24384-
}
24358+
Js::InternalString typeNameString(typeName, typeNameJsString->GetLength());
24359+
if (Js::InternalStringComparer::Equals(typeNameString, Js::Type::UndefinedTypeNameString))
24360+
{
24361+
typeIdOpnd = IR::IntConstOpnd::New(Js::TypeIds_Undefined, TyInt32, instr->m_func);
24362+
}
24363+
else if (Js::InternalStringComparer::Equals(typeNameString, Js::Type::ObjectTypeNameString))
24364+
{
24365+
typeIdOpnd = IR::IntConstOpnd::New(Js::TypeIds_Object, TyInt32, instr->m_func);
24366+
}
24367+
else if (Js::InternalStringComparer::Equals(typeNameString, Js::Type::BooleanTypeNameString))
24368+
{
24369+
typeIdOpnd = IR::IntConstOpnd::New(Js::TypeIds_Boolean, TyInt32, instr->m_func);
24370+
}
24371+
else if (Js::InternalStringComparer::Equals(typeNameString, Js::Type::NumberTypeNameString))
24372+
{
24373+
typeIdOpnd = IR::IntConstOpnd::New(Js::TypeIds_Number, TyInt32, instr->m_func);
24374+
}
24375+
else if (Js::InternalStringComparer::Equals(typeNameString, Js::Type::StringTypeNameString))
24376+
{
24377+
typeIdOpnd = IR::IntConstOpnd::New(Js::TypeIds_String, TyInt32, instr->m_func);
24378+
}
24379+
else if (Js::InternalStringComparer::Equals(typeNameString, Js::Type::FunctionTypeNameString))
24380+
{
24381+
typeIdOpnd = IR::IntConstOpnd::New(Js::TypeIds_Function, TyInt32, instr->m_func);
24382+
}
24383+
else
24384+
{
24385+
return false;
24386+
}
2438524387

24386-
if (skippedLoads)
24387-
{
24388-
//validate none of dst of Ld_A overlaps with typeof src or dst
24389-
IR::Opnd* typeOfSrc = typeOf->GetSrc1();
24390-
instrLd = typeOf->GetNextRealInstr();
24391-
while (instrLd != instr)
24388+
if (skippedLoads)
2439224389
{
24393-
if (instrLd->GetDst()->IsEqual(typeOfDst) || instrLd->GetDst()->IsEqual(typeOfSrc))
24390+
//validate none of dst of Ld_A overlaps with typeof src or dst
24391+
IR::Opnd* typeOfSrc = typeOf->GetSrc1();
24392+
instrLd = typeOf->GetNextRealInstr();
24393+
while (instrLd != instr)
2439424394
{
24395-
return false;
24395+
if (instrLd->GetDst()->IsEqual(typeOfDst) || instrLd->GetDst()->IsEqual(typeOfSrc))
24396+
{
24397+
return false;
24398+
}
24399+
instrLd = instrLd->GetNextRealInstr();
2439624400
}
24397-
instrLd = instrLd->GetNextRealInstr();
24401+
typeOf->Unlink();
24402+
instr->InsertBefore(typeOf);
24403+
}
24404+
// The first argument to [Cm|Br]TypeOf is the first arg to the TypeOf instruction.
24405+
IR::Opnd *objectOpnd = typeOf->GetSrc1();
24406+
Assert(objectOpnd->IsRegOpnd());
24407+
24408+
// Now emit this instruction and remove the ldstr and typeOf.
24409+
*prev = typeOf->m_prev;
24410+
*pfNoLower = false;
24411+
if (instr->IsBranchInstr())
24412+
{
24413+
GenerateFastBrTypeOf(instr, objectOpnd->AsRegOpnd(), typeIdOpnd, typeOf, pfNoLower, isNeqOp);
24414+
}
24415+
else
24416+
{
24417+
GenerateFastCmTypeOf(instr, objectOpnd->AsRegOpnd(), typeIdOpnd, typeOf, pfNoLower, isNeqOp);
2439824418
}
24399-
typeOf->Unlink();
24400-
instr->InsertBefore(typeOf);
24401-
}
24402-
// The first argument to [Cm|Br]TypeOf is the first arg to the TypeOf instruction.
24403-
IR::Opnd *objectOpnd = typeOf->GetSrc1();
24404-
Assert(objectOpnd->IsRegOpnd());
24405-
24406-
// Now emit this instruction and remove the ldstr and typeOf.
24407-
*prev = typeOf->m_prev;
24408-
*pfNoLower = false;
24409-
if (instr->IsBranchInstr())
24410-
{
24411-
GenerateFastBrTypeOf(instr, objectOpnd->AsRegOpnd(), typeIdOpnd, typeOf, pfNoLower, isNeqOp);
24412-
}
24413-
else
24414-
{
24415-
GenerateFastCmTypeOf(instr, objectOpnd->AsRegOpnd(), typeIdOpnd, typeOf, pfNoLower, isNeqOp);
24416-
}
2441724419

24418-
return true;
24420+
return true;
24421+
} while (false);
2441924422
}
2442024423
}
2442124424

2442224425
if (instrSrc1 && instrSrc1->GetStackSym()->IsSingleDef() && instrSrc2 && instrSrc2->GetStackSym()->IsSingleDef() &&
24423-
instrSrc1->GetStackSym()->GetInstrDef()->m_opcode == Js::OpCode::Typeof &&
24424-
instrSrc2->GetStackSym()->GetInstrDef()->m_opcode == Js::OpCode::Typeof)
24426+
(
24427+
((instrSrc1->GetStackSym()->GetInstrDef()->m_opcode == Js::OpCode::Typeof) &&
24428+
((instrSrc2->GetStackSym()->GetInstrDef()->m_opcode == Js::OpCode::Typeof) || instrSrc2->GetStackSym()->GetIsStrConst()))
24429+
||
24430+
((instrSrc2->GetStackSym()->GetInstrDef()->m_opcode == Js::OpCode::Typeof) &&
24431+
((instrSrc1->GetStackSym()->GetInstrDef()->m_opcode == Js::OpCode::Typeof) || instrSrc1->GetStackSym()->GetIsStrConst()))
24432+
)
24433+
)
2442524434
{
2442624435
*pfNoLower = true;
2442724436
if (instr->IsBranchInstr())

lib/Backend/Sym.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,12 @@ StackSym::SetIsStrConst()
381381
this->m_isNotNumber = true;
382382
}
383383

384+
bool
385+
StackSym::GetIsStrConst()
386+
{
387+
return this->m_isStrConst;
388+
}
389+
384390
Js::RegSlot
385391
StackSym::GetByteCodeRegSlot() const
386392
{

lib/Backend/Sym.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ class StackSym: public Sym
128128
void SetIsFloatConst();
129129
void SetIsSimd128Const();
130130
void SetIsStrConst();
131+
bool GetIsStrConst();
131132

132133
intptr_t GetLiteralConstValue_PostGlobOpt() const;
133134
IR::Opnd * GetConstOpnd() const;

0 commit comments

Comments
 (0)