Closed Bug 1650233 Opened 4 years ago Closed 4 years ago

Improve Array escape analysis / scalar replacement enough to handle Warp

Categories

(Core :: JavaScript Engine: JIT, enhancement, P1)

enhancement

Tracking

()

RESOLVED FIXED
88 Branch
Tracking Status
firefox88 --- fixed

People

(Reporter: evilpie, Assigned: iain)

References

(Blocks 2 open bugs)

Details

Attachments

(1 file, 1 obsolete file)

Warp generates MIR that is a lot less optimized than what IonBuilder would produce. To obvious examples are MGuardToClass and MGuardShape instruction. These are easy to optimize.

The harder problem is that all MStoreElement and MLoadElement instructions have the NeedsHoleCheck flag set. IsElementEscaped immediately de optimizes in that case, even for cases where we already know that the access is not going to be a hole.
I started drafting a workaround for this. We look for a dominating MSetInitializedLength instructions for the load. Currently this only works in the same block. I think we also need to make sure no explicit hole was written to the index, but I am not sure yet how to do that.

This actually already works for examples like: var x = [1, 2, 3]; x[0], because for JSOp::InitElemArray the MStoreElement instruction right has holeCheck = false.

Depends on D81919

Assignee: nobody → evilpies
Severity: -- → N/A
Status: NEW → ASSIGNED
Priority: -- → P1
Attachment #9161095 - Attachment is obsolete: true

I am not actively working on this at the moment.

Assignee: evilpies → nobody
Status: ASSIGNED → NEW
Blocks: 1697691

The main obstacle here is that without TI, every LoadElement and StoreElement has needsHoleCheck marked unless it is a StoreElement from an InitElem.

We can handle most cases by observing that LoadElement can only observe a hole if a magic hole value has been stored to the array. This can only be done with StoreHoleValueElement, which we don't support in IsElementEscaped. (Note that the constructor for MStoreElement asserts that the value being stored is not a hole.) Therefore, we can omit the hole check for loads.

This gives us support for every case in ion/recover-arrays.js except for arrayCond. That's probably good enough for now.

Assignee: nobody → iireland
Status: NEW → ASSIGNED

I have a patch that (I think) fixes almost all of ion/recover-arrays.js (which is currently disabled). The one exception is arrayCond, which stores to an element after the array is initialized.

We could add an analysis to track which elements have been initialized for StoreElement, but I think it might be cleaner to instead use a fuse-based approach. We only care about holes here if Object.prototype or Array.prototype has an indexed property; if we use a very limited constraint system to invalidate this script if the prototype is modified, then IIUC we wouldn't have to worry about hole checks. I think there's a nice way to implement this with CacheIR by having the baseline stub load the fuse and check it, and transpile that to a no-op plus a constraint.

Either way, I don't think we have to fix StoreElement hole checks right away. I opened bug 1697691.

Pushed by iireland@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/0c3efc0015ec Make ScalarReplacement work for arrays in Warp r=nbp
Status: ASSIGNED → RESOLVED
Closed: 4 years ago
Resolution: --- → FIXED
Target Milestone: --- → 88 Branch
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: