Closed Bug 1391611 Opened 7 years ago Closed 7 years ago

Devirtualize MNode::kind()

Categories

(Core :: JavaScript Engine: JIT, enhancement)

enhancement
Not set
normal

Tracking

()

RESOLVED FIXED
mozilla57
Tracking Status
firefox57 --- fixed

People

(Reporter: jandem, Assigned: jandem)

References

(Blocks 1 open bug)

Details

Attachments

(2 files, 1 obsolete file)

Attached patch PatchSplinter Review
MNode::kind is a pretty hot virtual function to determine isResumePoint() or isDefinition(). We can devirtualize it by making MNode::block_ a tagged pointer - the low bit can store the kind. I also |= delete|'d these functions on the MDefinition and MResumePoint derived classes, this caught a place where we called isResumePoint() on an MDefinition (this is always false).
Attachment #8898759 - Flags: review?(nicolas.b.pierron)
Comment on attachment 8898759 [details] [diff] [review] Patch Review of attachment 8898759 [details] [diff] [review]: ----------------------------------------------------------------- ::: js/src/jit/MIR.h @@ +343,3 @@ > } > MBasicBlock* block() const { > + return reinterpret_cast<MBasicBlock*>(blockAndKind_ & ~KindMask); Is this really worth it? I would expect resume point to access the block()->info() pointer frequently. @@ +527,5 @@ > } > > + // Calling isDefinition or isResumePoint on MDefinition is unnecessary. > + bool isDefinition() const = delete; > + bool isResumePoint() const = delete; Nice!
Attachment #8898759 - Flags: review?(nicolas.b.pierron) → review+
(In reply to Nicolas B. Pierron [:nbp] from comment #1) > Is this really worth it? > > I would expect resume point to access the block()->info() pointer frequently. I just added some logging and ran Octane. MNode::kind() was called about 10.1 million times, MNode::block() 11.5 million times. So block() is called a bit more, but getting rid of the virtual call for kind() outweighs the unmasking there IMO.
One more thing that I forgot. Can you specialize MDefinition::block() to avoid the un-masking as and assert that the low bots are already 0.
Attached patch Followup (obsolete) — Splinter Review
What do you think of this one? It optimizes block() on both MDefinition and MResumePoint to be a bit more efficient than MNode::block().
Attachment #8898796 - Flags: review?(nicolas.b.pierron)
Attached patch FollowupSplinter Review
The right one.
Attachment #8898796 - Attachment is obsolete: true
Attachment #8898796 - Flags: review?(nicolas.b.pierron)
Attachment #8898797 - Flags: review?(nicolas.b.pierron)
Comment on attachment 8898797 [details] [diff] [review] Followup Review of attachment 8898797 [details] [diff] [review]: ----------------------------------------------------------------- ::: js/src/jit/MIR.h @@ +338,5 @@ > + MOZ_ASSERT(isResumePoint()); > + static_assert(unsigned(Kind::ResumePoint) == 1, "Code below relies on low bit being 1"); > + // Use a subtraction: if the caller does block()->foo, the compiler > + // will be able to fold it with the load. > + return reinterpret_cast<MBasicBlock*>(blockAndKind_ - 1); Whoa, this is indeed nicer!
Attachment #8898797 - Flags: review?(nicolas.b.pierron) → review+
Blocks: 1245279
Status: ASSIGNED → RESOLVED
Closed: 7 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla57
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: