Skip to content

Commit 79cfa06

Browse files
committed
[MERGE chakra-core#4946 @MikeHolman] profile elem accesses and emit fastpaths for cache types we've seen
Merge pull request chakra-core#4946 from MikeHolman:elemprofile Perf runs have shown a few scattered improvements of 2-4% across different Speedometer 2 tests (overall improves by ~0.8%). Also looks like it improves ARES-6 ML and Air tests by about 5% each.
2 parents 1a6bcac + 8e494b4 commit 79cfa06

13 files changed

Lines changed: 925 additions & 520 deletions

lib/Backend/Lower.cpp

Lines changed: 300 additions & 69 deletions
Large diffs are not rendered by default.

lib/Backend/Lower.h

Lines changed: 66 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -409,23 +409,24 @@ class Lowerer
409409
}
410410

411411
private:
412-
IR::IndirOpnd * GenerateFastElemICommon(
413-
IR::Instr * ldElem,
414-
bool isStore,
415-
IR::IndirOpnd * indirOpnd,
416-
IR::LabelInstr * labelHelper,
417-
IR::LabelInstr * labelCantUseArray,
418-
IR::LabelInstr *labelFallthrough,
419-
bool * pIsTypedArrayElement,
420-
bool * pIsStringIndex,
421-
bool *emitBailoutRef,
422-
IR::Opnd** maskOpnd,
423-
IR::LabelInstr **pLabelSegmentLengthIncreased = nullptr,
424-
bool checkArrayLengthOverflow = true,
425-
bool forceGenerateFastPath = false,
426-
bool returnLength = false,
427-
IR::LabelInstr *bailOutLabelInstr = nullptr,
428-
bool * indirOpndOverflowed = nullptr);
412+
IR::IndirOpnd* GenerateFastElemICommon(
413+
_In_ IR::Instr* elemInstr,
414+
_In_ bool isStore,
415+
_In_ IR::IndirOpnd* indirOpnd,
416+
_In_ IR::LabelInstr* labelHelper,
417+
_In_ IR::LabelInstr* labelCantUseArray,
418+
_In_opt_ IR::LabelInstr* labelFallthrough,
419+
_Out_ bool* pIsTypedArrayElement,
420+
_Out_ bool* pIsStringIndex,
421+
_Out_opt_ bool* emitBailoutRef,
422+
_Outptr_opt_result_maybenull_ IR::Opnd** maskOpnd,
423+
_Outptr_opt_result_maybenull_ IR::LabelInstr** pLabelSegmentLengthIncreased = nullptr,
424+
_In_ bool checkArrayLengthOverflow = true,
425+
_In_ bool forceGenerateFastPath = false,
426+
_In_ bool returnLength = false,
427+
_In_opt_ IR::LabelInstr* bailOutLabelInstr = nullptr,
428+
_Out_opt_ bool* indirOpndOverflowed = nullptr,
429+
_In_ Js::FldInfoFlags flags = Js::FldInfo_NoInfo);
429430

430431
IR::IndirOpnd * GenerateFastElemIIntIndexCommon(
431432
IR::Instr * ldElem,
@@ -444,11 +445,55 @@ class Lowerer
444445
IR::LabelInstr *bailOutLabelInstr = nullptr,
445446
bool * indirOpndOverflowed = nullptr);
446447

447-
IR::IndirOpnd * GenerateFastElemIStringIndexCommon(IR::Instr * ldElem, bool isStore, IR::IndirOpnd * indirOpnd, IR::LabelInstr * labelHelper);
448-
IR::IndirOpnd * GenerateFastElemISymbolIndexCommon(IR::Instr * ldElem, bool isStore, IR::IndirOpnd * indirOpnd, IR::LabelInstr * labelHelper);
448+
IR::IndirOpnd* GenerateFastElemIStringIndexCommon(
449+
_In_ IR::Instr* elemInstr,
450+
_In_ bool isStore,
451+
_In_ IR::IndirOpnd* indirOpnd,
452+
_In_ IR::LabelInstr* labelHelper,
453+
_In_ Js::FldInfoFlags flags);
454+
455+
IR::IndirOpnd* GenerateFastElemISymbolIndexCommon(
456+
_In_ IR::Instr* elemInstr,
457+
_In_ bool isStore,
458+
_In_ IR::IndirOpnd* indirOpnd,
459+
_In_ IR::LabelInstr* labelHelper,
460+
_In_ Js::FldInfoFlags flags);
461+
462+
IR::IndirOpnd* GenerateFastElemISymbolOrStringIndexCommon(
463+
_In_ IR::Instr* instrInsert,
464+
_In_ IR::RegOpnd* indexOpnd,
465+
_In_ IR::RegOpnd* baseOpnd,
466+
_In_ const uint32 inlineCacheOffset,
467+
_In_ const uint32 hitRateOffset,
468+
_In_ IR::LabelInstr* labelHelper,
469+
_In_ Js::FldInfoFlags flags);
470+
471+
void GenerateLookUpInIndexCache(
472+
_In_ IR::Instr* instrInsert,
473+
_In_ IR::RegOpnd* indexOpnd,
474+
_In_ IR::RegOpnd* baseOpnd,
475+
_In_opt_ IR::RegOpnd* opndSlotArray,
476+
_In_opt_ IR::RegOpnd* opndSlotIndex,
477+
_In_ const uint32 inlineCacheOffset,
478+
_In_ const uint32 hitRateOffset,
479+
_In_ IR::LabelInstr* labelHelper,
480+
_In_ Js::FldInfoFlags flags = Js::FldInfo_NoInfo);
481+
482+
template <bool CheckLocal, bool CheckInlineSlot, bool DoAdd>
483+
void GenerateLookUpInIndexCacheHelper(
484+
_In_ IR::Instr* instrInsert,
485+
_In_ IR::RegOpnd* baseOpnd,
486+
_In_opt_ IR::RegOpnd* opndSlotArray,
487+
_In_opt_ IR::RegOpnd* opndSlotIndex,
488+
_In_ IR::RegOpnd* objectTypeOpnd,
489+
_In_ IR::RegOpnd* inlineCacheOpnd,
490+
_In_ IR::LabelInstr* doneLabel,
491+
_In_ IR::LabelInstr* helperLabel,
492+
_Outptr_ IR::LabelInstr** nextLabel,
493+
_Outptr_ IR::BranchInstr** branchToPatch,
494+
_Inout_ IR::RegOpnd** taggedTypeOpnd);
495+
449496
void GenerateFastIsInSymbolOrStringIndex(IR::Instr * instrInsert, IR::RegOpnd *indexOpnd, IR::RegOpnd *baseOpnd, IR::Opnd *dest, uint32 inlineCacheOffset, const uint32 hitRateOffset, IR::LabelInstr * labelHelper, IR::LabelInstr * labelDone);
450-
IR::IndirOpnd * GenerateFastElemISymbolOrStringIndexCommon(IR::Instr * instrInsert, IR::RegOpnd *indexOpnd, IR::RegOpnd *baseOpnd, const uint32 inlineCacheOffset, const uint32 hitRateOffset, IR::LabelInstr * labelHelper);
451-
void GenerateLookUpInIndexCache(IR::Instr * instrInsert, IR::RegOpnd *indexOpnd, IR::RegOpnd *baseOpnd, IR::RegOpnd *opndSlotArray, IR::RegOpnd *opndSlotIndex, const uint32 inlineCacheOffset, const uint32 hitRateOffset, IR::LabelInstr * labelHelper);
452497
bool GenerateFastLdElemI(IR::Instr *& ldElem, bool *instrIsInHelperBlockRef);
453498
bool GenerateFastStElemI(IR::Instr *& StElem, bool *instrIsInHelperBlockRef);
454499
bool GenerateFastLdLen(IR::Instr *ldLen, bool *instrIsInHelperBlockRef);

lib/JITIDL/JITTypes.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -251,15 +251,15 @@ typedef struct LdElemIDL
251251
{
252252
unsigned short arrayType;
253253
unsigned short elemType;
254+
byte flags;
254255
byte bits;
255-
IDL_PAD1(0)
256256
} LdElemIDL;
257257

258258
typedef struct StElemIDL
259259
{
260260
unsigned short arrayType;
261+
byte flags;
261262
byte bits;
262-
IDL_PAD1(0)
263263
} StElemIDL;
264264

265265
typedef struct ProfileDataIDL

lib/Runtime/Language/DynamicProfileInfo.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,10 +161,12 @@ namespace Js
161161
{
162162
ldElemInfo[i].arrayType = ValueType::Uninitialized;
163163
ldElemInfo[i].elemType = ValueType::Uninitialized;
164+
ldElemInfo[i].flags = Js::FldInfo_NoInfo;
164165
}
165166
for (ProfileId i = 0; i < functionBody->GetProfiledStElemCount(); ++i)
166167
{
167168
stElemInfo[i].arrayType = ValueType::Uninitialized;
169+
stElemInfo[i].flags = Js::FldInfo_NoInfo;
168170
}
169171
for (uint i = 0; i < functionBody->GetProfiledFldCount(); ++i)
170172
{
@@ -986,6 +988,21 @@ namespace Js
986988
stElemInfo[stElemId].wasProfiled = true;
987989
}
988990

991+
void LdElemInfo::Merge(const LdElemInfo &other)
992+
{
993+
arrayType = arrayType.Merge(other.arrayType);
994+
elemType = elemType.Merge(other.elemType);
995+
flags = DynamicProfileInfo::MergeFldInfoFlags(flags, other.flags);
996+
bits |= other.bits;
997+
}
998+
999+
void StElemInfo::Merge(const StElemInfo &other)
1000+
{
1001+
arrayType = arrayType.Merge(other.arrayType);
1002+
flags = DynamicProfileInfo::MergeFldInfoFlags(flags, other.flags);
1003+
bits |= other.bits;
1004+
}
1005+
9891006
ArrayCallSiteInfo * DynamicProfileInfo::GetArrayCallSiteInfo(FunctionBody *functionBody, ProfileId index) const
9901007
{
9911008
Assert(index < functionBody->GetProfiledArrayCallSiteCount());

lib/Runtime/Language/DynamicProfileInfo.h

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,7 @@ namespace Js
218218
{
219219
ValueType arrayType;
220220
ValueType elemType;
221+
FldInfoFlags flags;
221222

222223
union
223224
{
@@ -230,17 +231,12 @@ namespace Js
230231
byte bits;
231232
};
232233

233-
LdElemInfo() : bits(0)
234+
LdElemInfo() : bits(0), flags(FldInfo_NoInfo)
234235
{
235236
wasProfiled = true;
236237
}
237238

238-
void Merge(const LdElemInfo &other)
239-
{
240-
arrayType = arrayType.Merge(other.arrayType);
241-
elemType = elemType.Merge(other.elemType);
242-
bits |= other.bits;
243-
}
239+
void Merge(const LdElemInfo &other);
244240

245241
ValueType GetArrayType() const
246242
{
@@ -271,6 +267,7 @@ namespace Js
271267
struct StElemInfo
272268
{
273269
ValueType arrayType;
270+
FldInfoFlags flags;
274271

275272
union
276273
{
@@ -287,16 +284,12 @@ namespace Js
287284
byte bits;
288285
};
289286

290-
StElemInfo() : bits(0)
287+
StElemInfo() : bits(0), flags(FldInfo_NoInfo)
291288
{
292289
wasProfiled = true;
293290
}
294291

295-
void Merge(const StElemInfo &other)
296-
{
297-
arrayType = arrayType.Merge(other.arrayType);
298-
bits |= other.bits;
299-
}
292+
void Merge(const StElemInfo &other);
300293

301294
ValueType GetArrayType() const
302295
{

0 commit comments

Comments
 (0)