Changeset 244579 in webkit
- Timestamp:
- Apr 23, 2019, 7:14:23 PM (7 years ago)
- Location:
- trunk
- Files:
-
- 1 added
- 3 edited
-
JSTests/ChangeLog (modified) (1 diff)
-
JSTests/stress/licm-should-handle-if-a-hoist-causes-a-provable-osr-exit.js (added)
-
Source/JavaScriptCore/ChangeLog (modified) (1 diff)
-
Source/JavaScriptCore/dfg/DFGLICMPhase.cpp (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/JSTests/ChangeLog
r244480 r244579 1 2019-04-23 Saam Barati <sbarati@apple.com> 2 3 LICM incorrectly assumes it'll never insert a node which provably OSR exits 4 https://bugs.webkit.org/show_bug.cgi?id=196721 5 <rdar://problem/49556479> 6 7 Reviewed by Filip Pizlo. 8 9 * stress/licm-should-handle-if-a-hoist-causes-a-provable-osr-exit.js: Added. 10 (foo): 11 1 12 2019-04-19 Saam Barati <sbarati@apple.com> 2 13 -
trunk/Source/JavaScriptCore/ChangeLog
r244578 r244579 1 2019-04-23 Saam Barati <sbarati@apple.com> 2 3 LICM incorrectly assumes it'll never insert a node which provably OSR exits 4 https://bugs.webkit.org/show_bug.cgi?id=196721 5 <rdar://problem/49556479> 6 7 Reviewed by Filip Pizlo. 8 9 Previously, we assumed LICM could never hoist code that caused us 10 to provably OSR exit. This is a bad assumption, as we may very well 11 hoist such code. Obviously hoisting such code is not ideal. We shouldn't 12 hoist something we provably know will OSR exit. However, this is super rare, 13 and the phase is written in such a way where it's easier to gracefully 14 handle this case than to prevent us from hoisting such code. 15 16 If we wanted to ensure we never hoisted code that would provably exit, we'd 17 have to teach the phase to know when it inserted code that provably exits. I 18 saw two ways to do that: 19 1: Save and restore the AI state before actually hoisting. 20 2: Write an analysis that can determine if such a node would exit. 21 22 (1) is bad because it costs in memory and compile time. (2) will inevitably 23 have bugs as running into this condition is rare. 24 25 So instead of (1) or (2), I opted to have LICM gracefully handle when 26 it causes a provable exit. When we encounter this, we mark all blocks 27 in the loop as !cfaHasVisited and !cfaDidFinish. 28 29 * dfg/DFGLICMPhase.cpp: 30 (JSC::DFG::LICMPhase::attemptHoist): 31 1 32 2019-04-23 Yusuke Suzuki <ysuzuki@apple.com> 2 33 -
trunk/Source/JavaScriptCore/dfg/DFGLICMPhase.cpp
r242276 r244579 243 243 244 244 m_state.initializeTo(data.preHeader); 245 ASSERT(m_state.isValid()); 245 246 NodeOrigin originalOrigin = node->origin; 246 247 bool canSpeculateBlindly = !m_graph.hasGlobalExitSite(originalOrigin.semantic, HoistingFailed); … … 264 265 265 266 auto updateAbstractState = [&] { 267 auto invalidate = [&] (const NaturalLoop* loop) { 268 LoopData& data = m_data[loop->index()]; 269 data.preHeader->cfaDidFinish = false; 270 271 for (unsigned bodyIndex = loop->size(); bodyIndex--;) { 272 BasicBlock* block = loop->at(bodyIndex); 273 if (block != data.preHeader) 274 block->cfaHasVisited = false; 275 block->cfaDidFinish = false; 276 } 277 }; 278 266 279 // We can trust what AI proves about edge proof statuses when hoisting to the preheader. 267 280 m_state.trustEdgeProofs(); 268 for (unsigned i = 0; i < hoistedNodes.size(); ++i) 269 m_interpreter.execute(hoistedNodes[i]); 281 for (unsigned i = 0; i < hoistedNodes.size(); ++i) { 282 if (!m_interpreter.execute(hoistedNodes[i])) { 283 invalidate(loop); 284 return; 285 } 286 } 287 270 288 // However, when walking various inner loops below, the proof status of 271 289 // an edge may be trivially true, even if it's not true in the preheader … … 301 319 continue; 302 320 m_state.initializeTo(subPreHeader); 303 for (unsigned i = 0; i < hoistedNodes.size(); ++i) 304 m_interpreter.execute(hoistedNodes[i]); 321 for (unsigned i = 0; i < hoistedNodes.size(); ++i) { 322 if (!m_interpreter.execute(hoistedNodes[i])) { 323 invalidate(subLoop); 324 break; 325 } 326 } 305 327 } 306 328 };
Note:
See TracChangeset
for help on using the changeset viewer.