DFGPredictionPropagationPhase.cpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759
  1. /*
  2. * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. * 1. Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * 2. Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. *
  13. * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
  14. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  15. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  16. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
  17. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  18. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  19. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  20. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  21. * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  22. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  23. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  24. */
  25. #include "config.h"
  26. #include "DFGPredictionPropagationPhase.h"
  27. #if ENABLE(DFG_JIT)
  28. #include "DFGGraph.h"
  29. #include "DFGPhase.h"
  30. #include "Operations.h"
  31. namespace JSC { namespace DFG {
  32. SpeculatedType resultOfToPrimitive(SpeculatedType type)
  33. {
  34. if (type & SpecObject) {
  35. // Objects get turned into strings. So if the input has hints of objectness,
  36. // the output will have hinsts of stringiness.
  37. return mergeSpeculations(type & ~SpecObject, SpecString);
  38. }
  39. return type;
  40. }
  41. class PredictionPropagationPhase : public Phase {
  42. public:
  43. PredictionPropagationPhase(Graph& graph)
  44. : Phase(graph, "prediction propagation")
  45. {
  46. }
  47. bool run()
  48. {
  49. ASSERT(m_graph.m_form == ThreadedCPS);
  50. ASSERT(m_graph.m_unificationState == GloballyUnified);
  51. #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
  52. m_count = 0;
  53. #endif
  54. // 1) propagate predictions
  55. do {
  56. m_changed = false;
  57. // Forward propagation is near-optimal for both topologically-sorted and
  58. // DFS-sorted code.
  59. propagateForward();
  60. if (!m_changed)
  61. break;
  62. // Backward propagation reduces the likelihood that pathological code will
  63. // cause slowness. Loops (especially nested ones) resemble backward flow.
  64. // This pass captures two cases: (1) it detects if the forward fixpoint
  65. // found a sound solution and (2) short-circuits backward flow.
  66. m_changed = false;
  67. propagateBackward();
  68. } while (m_changed);
  69. // 2) repropagate predictions while doing double voting.
  70. do {
  71. m_changed = false;
  72. doRoundOfDoubleVoting();
  73. if (!m_changed)
  74. break;
  75. m_changed = false;
  76. propagateForward();
  77. } while (m_changed);
  78. return true;
  79. }
  80. private:
  81. bool setPrediction(SpeculatedType prediction)
  82. {
  83. ASSERT(m_currentNode->hasResult());
  84. // setPrediction() is used when we know that there is no way that we can change
  85. // our minds about what the prediction is going to be. There is no semantic
  86. // difference between setPrediction() and mergeSpeculation() other than the
  87. // increased checking to validate this property.
  88. ASSERT(m_currentNode->prediction() == SpecNone || m_currentNode->prediction() == prediction);
  89. return m_currentNode->predict(prediction);
  90. }
  91. bool mergePrediction(SpeculatedType prediction)
  92. {
  93. ASSERT(m_currentNode->hasResult());
  94. return m_currentNode->predict(prediction);
  95. }
  96. SpeculatedType speculatedDoubleTypeForPrediction(SpeculatedType value)
  97. {
  98. if (!isNumberSpeculation(value))
  99. return SpecDouble;
  100. if (value & SpecDoubleNaN)
  101. return SpecDouble;
  102. return SpecDoubleReal;
  103. }
  104. SpeculatedType speculatedDoubleTypeForPredictions(SpeculatedType left, SpeculatedType right)
  105. {
  106. return speculatedDoubleTypeForPrediction(mergeSpeculations(left, right));
  107. }
  108. void propagate(Node* node)
  109. {
  110. NodeType op = node->op();
  111. #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
  112. dataLog(" ", Graph::opName(op), " ", m_currentNode, ": ", NodeFlagsDump(node->flags()), " ");
  113. #endif
  114. bool changed = false;
  115. switch (op) {
  116. case JSConstant:
  117. case WeakJSConstant: {
  118. changed |= setPrediction(speculationFromValue(m_graph.valueOfJSConstant(node)));
  119. break;
  120. }
  121. case GetLocal: {
  122. VariableAccessData* variableAccessData = node->variableAccessData();
  123. SpeculatedType prediction = variableAccessData->prediction();
  124. if (prediction)
  125. changed |= mergePrediction(prediction);
  126. break;
  127. }
  128. case SetLocal: {
  129. VariableAccessData* variableAccessData = node->variableAccessData();
  130. changed |= variableAccessData->predict(node->child1()->prediction());
  131. break;
  132. }
  133. case BitAnd:
  134. case BitOr:
  135. case BitXor:
  136. case BitRShift:
  137. case BitLShift:
  138. case BitURShift:
  139. case ArithIMul: {
  140. changed |= setPrediction(SpecInt32);
  141. break;
  142. }
  143. case ValueToInt32: {
  144. changed |= setPrediction(SpecInt32);
  145. break;
  146. }
  147. case ArrayPop:
  148. case ArrayPush:
  149. case RegExpExec:
  150. case RegExpTest:
  151. case GetById:
  152. case GetByIdFlush:
  153. case GetMyArgumentByValSafe:
  154. case GetByOffset:
  155. case Call:
  156. case Construct:
  157. case GetGlobalVar:
  158. case GetScopedVar:
  159. case Resolve:
  160. case ResolveBase:
  161. case ResolveBaseStrictPut:
  162. case ResolveGlobal: {
  163. changed |= setPrediction(node->getHeapPrediction());
  164. break;
  165. }
  166. case StringCharCodeAt: {
  167. changed |= setPrediction(SpecInt32);
  168. break;
  169. }
  170. case UInt32ToNumber: {
  171. if (nodeCanSpeculateInteger(node->arithNodeFlags()))
  172. changed |= mergePrediction(SpecInt32);
  173. else
  174. changed |= mergePrediction(SpecNumber);
  175. break;
  176. }
  177. case ValueAdd: {
  178. SpeculatedType left = node->child1()->prediction();
  179. SpeculatedType right = node->child2()->prediction();
  180. if (left && right) {
  181. if (isNumberSpeculationExpectingDefined(left) && isNumberSpeculationExpectingDefined(right)) {
  182. if (m_graph.addSpeculationMode(node) != DontSpeculateInteger)
  183. changed |= mergePrediction(SpecInt32);
  184. else
  185. changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
  186. } else if (!(left & SpecNumber) || !(right & SpecNumber)) {
  187. // left or right is definitely something other than a number.
  188. changed |= mergePrediction(SpecString);
  189. } else
  190. changed |= mergePrediction(SpecString | SpecInt32 | SpecDouble);
  191. }
  192. break;
  193. }
  194. case ArithAdd: {
  195. SpeculatedType left = node->child1()->prediction();
  196. SpeculatedType right = node->child2()->prediction();
  197. if (left && right) {
  198. if (m_graph.addSpeculationMode(node) != DontSpeculateInteger)
  199. changed |= mergePrediction(SpecInt32);
  200. else
  201. changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
  202. }
  203. break;
  204. }
  205. case ArithSub: {
  206. SpeculatedType left = node->child1()->prediction();
  207. SpeculatedType right = node->child2()->prediction();
  208. if (left && right) {
  209. if (m_graph.addSpeculationMode(node) != DontSpeculateInteger)
  210. changed |= mergePrediction(SpecInt32);
  211. else
  212. changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
  213. }
  214. break;
  215. }
  216. case ArithNegate:
  217. if (node->child1()->prediction()) {
  218. if (m_graph.negateShouldSpeculateInteger(node))
  219. changed |= mergePrediction(SpecInt32);
  220. else
  221. changed |= mergePrediction(speculatedDoubleTypeForPrediction(node->child1()->prediction()));
  222. }
  223. break;
  224. case ArithMin:
  225. case ArithMax: {
  226. SpeculatedType left = node->child1()->prediction();
  227. SpeculatedType right = node->child2()->prediction();
  228. if (left && right) {
  229. if (Node::shouldSpeculateIntegerForArithmetic(node->child1().node(), node->child2().node())
  230. && nodeCanSpeculateInteger(node->arithNodeFlags()))
  231. changed |= mergePrediction(SpecInt32);
  232. else
  233. changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
  234. }
  235. break;
  236. }
  237. case ArithMul: {
  238. SpeculatedType left = node->child1()->prediction();
  239. SpeculatedType right = node->child2()->prediction();
  240. if (left && right) {
  241. if (m_graph.mulShouldSpeculateInteger(node))
  242. changed |= mergePrediction(SpecInt32);
  243. else
  244. changed |= mergePrediction(speculatedDoubleTypeForPredictions(left, right));
  245. }
  246. break;
  247. }
  248. case ArithDiv: {
  249. SpeculatedType left = node->child1()->prediction();
  250. SpeculatedType right = node->child2()->prediction();
  251. if (left && right) {
  252. if (Node::shouldSpeculateIntegerForArithmetic(node->child1().node(), node->child2().node())
  253. && nodeCanSpeculateInteger(node->arithNodeFlags()))
  254. changed |= mergePrediction(SpecInt32);
  255. else
  256. changed |= mergePrediction(SpecDouble);
  257. }
  258. break;
  259. }
  260. case ArithMod: {
  261. SpeculatedType left = node->child1()->prediction();
  262. SpeculatedType right = node->child2()->prediction();
  263. if (left && right) {
  264. if (Node::shouldSpeculateIntegerForArithmetic(node->child1().node(), node->child2().node())
  265. && nodeCanSpeculateInteger(node->arithNodeFlags()))
  266. changed |= mergePrediction(SpecInt32);
  267. else
  268. changed |= mergePrediction(SpecDouble);
  269. }
  270. break;
  271. }
  272. case ArithSqrt: {
  273. changed |= setPrediction(SpecDouble);
  274. break;
  275. }
  276. case ArithAbs: {
  277. SpeculatedType child = node->child1()->prediction();
  278. if (isInt32SpeculationForArithmetic(child)
  279. && nodeCanSpeculateInteger(node->arithNodeFlags()))
  280. changed |= mergePrediction(SpecInt32);
  281. else
  282. changed |= mergePrediction(speculatedDoubleTypeForPrediction(child));
  283. break;
  284. }
  285. case LogicalNot:
  286. case CompareLess:
  287. case CompareLessEq:
  288. case CompareGreater:
  289. case CompareGreaterEq:
  290. case CompareEq:
  291. case CompareEqConstant:
  292. case CompareStrictEq:
  293. case CompareStrictEqConstant:
  294. case InstanceOf:
  295. case IsUndefined:
  296. case IsBoolean:
  297. case IsNumber:
  298. case IsString:
  299. case IsObject:
  300. case IsFunction: {
  301. changed |= setPrediction(SpecBoolean);
  302. break;
  303. }
  304. case TypeOf: {
  305. changed |= setPrediction(SpecString);
  306. break;
  307. }
  308. case GetByVal: {
  309. if (node->child1()->shouldSpeculateFloat32Array()
  310. || node->child1()->shouldSpeculateFloat64Array())
  311. changed |= mergePrediction(SpecDouble);
  312. else
  313. changed |= mergePrediction(node->getHeapPrediction());
  314. break;
  315. }
  316. case GetMyArgumentsLengthSafe: {
  317. changed |= setPrediction(SpecInt32);
  318. break;
  319. }
  320. case GetScopeRegisters:
  321. case GetButterfly:
  322. case GetIndexedPropertyStorage:
  323. case AllocatePropertyStorage:
  324. case ReallocatePropertyStorage: {
  325. changed |= setPrediction(SpecOther);
  326. break;
  327. }
  328. case ConvertThis: {
  329. SpeculatedType prediction = node->child1()->prediction();
  330. if (prediction) {
  331. if (prediction & ~SpecObject) {
  332. prediction &= SpecObject;
  333. prediction = mergeSpeculations(prediction, SpecObjectOther);
  334. }
  335. changed |= mergePrediction(prediction);
  336. }
  337. break;
  338. }
  339. case GetMyScope:
  340. case SkipTopScope:
  341. case SkipScope: {
  342. changed |= setPrediction(SpecObjectOther);
  343. break;
  344. }
  345. case GetCallee: {
  346. changed |= setPrediction(SpecFunction);
  347. break;
  348. }
  349. case CreateThis:
  350. case NewObject: {
  351. changed |= setPrediction(SpecFinalObject);
  352. break;
  353. }
  354. case NewArray:
  355. case NewArrayWithSize:
  356. case NewArrayBuffer: {
  357. changed |= setPrediction(SpecArray);
  358. break;
  359. }
  360. case NewRegexp:
  361. case CreateActivation: {
  362. changed |= setPrediction(SpecObjectOther);
  363. break;
  364. }
  365. case StringFromCharCode: {
  366. changed |= setPrediction(SpecString);
  367. changed |= node->child1()->mergeFlags(NodeUsedAsNumber | NodeUsedAsInt);
  368. break;
  369. }
  370. case StringCharAt:
  371. case ToString:
  372. case MakeRope: {
  373. changed |= setPrediction(SpecString);
  374. break;
  375. }
  376. case ToPrimitive: {
  377. SpeculatedType child = node->child1()->prediction();
  378. if (child)
  379. changed |= mergePrediction(resultOfToPrimitive(child));
  380. break;
  381. }
  382. case NewStringObject: {
  383. changed |= setPrediction(SpecStringObject);
  384. break;
  385. }
  386. case CreateArguments: {
  387. changed |= setPrediction(SpecArguments);
  388. break;
  389. }
  390. case NewFunction: {
  391. SpeculatedType child = node->child1()->prediction();
  392. if (child & SpecEmpty)
  393. changed |= mergePrediction((child & ~SpecEmpty) | SpecFunction);
  394. else
  395. changed |= mergePrediction(child);
  396. break;
  397. }
  398. case NewFunctionNoCheck:
  399. case NewFunctionExpression: {
  400. changed |= setPrediction(SpecFunction);
  401. break;
  402. }
  403. case PutByValAlias:
  404. case GetArrayLength:
  405. case Int32ToDouble:
  406. case ForwardInt32ToDouble:
  407. case DoubleAsInt32:
  408. case GetLocalUnlinked:
  409. case GetMyArgumentsLength:
  410. case GetMyArgumentByVal:
  411. case PhantomPutStructure:
  412. case PhantomArguments:
  413. case CheckArray:
  414. case Arrayify:
  415. case ArrayifyToStructure:
  416. case MovHint:
  417. case MovHintAndCheck:
  418. case ZombieHint: {
  419. // This node should never be visible at this stage of compilation. It is
  420. // inserted by fixup(), which follows this phase.
  421. CRASH();
  422. break;
  423. }
  424. case Phi:
  425. // Phis should not be visible here since we're iterating the all-but-Phi's
  426. // part of basic blocks.
  427. CRASH();
  428. break;
  429. case GetScope:
  430. changed |= setPrediction(SpecObjectOther);
  431. break;
  432. case Identity:
  433. changed |= mergePrediction(node->child1()->prediction());
  434. break;
  435. #ifndef NDEBUG
  436. // These get ignored because they don't return anything.
  437. case PutByVal:
  438. case PutScopedVar:
  439. case Return:
  440. case Throw:
  441. case PutById:
  442. case PutByIdDirect:
  443. case PutByOffset:
  444. case SetCallee:
  445. case SetMyScope:
  446. case DFG::Jump:
  447. case Branch:
  448. case Breakpoint:
  449. case CheckHasInstance:
  450. case ThrowReferenceError:
  451. case ForceOSRExit:
  452. case SetArgument:
  453. case CheckStructure:
  454. case CheckExecutable:
  455. case ForwardCheckStructure:
  456. case StructureTransitionWatchpoint:
  457. case ForwardStructureTransitionWatchpoint:
  458. case CheckFunction:
  459. case PutStructure:
  460. case TearOffActivation:
  461. case TearOffArguments:
  462. case CheckArgumentsNotCreated:
  463. case GlobalVarWatchpoint:
  464. case GarbageValue:
  465. case AllocationProfileWatchpoint:
  466. case Phantom:
  467. case PutGlobalVar:
  468. case PutGlobalVarCheck:
  469. case CheckWatchdogTimer:
  470. break;
  471. // These gets ignored because it doesn't do anything.
  472. case InlineStart:
  473. case Nop:
  474. case CountExecution:
  475. case PhantomLocal:
  476. case Flush:
  477. break;
  478. case LastNodeType:
  479. CRASH();
  480. break;
  481. #else
  482. default:
  483. break;
  484. #endif
  485. }
  486. #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
  487. dataLog(SpeculationDump(node->prediction()), "\n");
  488. #endif
  489. m_changed |= changed;
  490. }
  491. void propagateForward()
  492. {
  493. #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
  494. dataLogF("Propagating predictions forward [%u]\n", ++m_count);
  495. #endif
  496. for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
  497. BasicBlock* block = m_graph.m_blocks[blockIndex].get();
  498. if (!block)
  499. continue;
  500. ASSERT(block->isReachable);
  501. for (unsigned i = 0; i < block->size(); ++i) {
  502. m_currentNode = block->at(i);
  503. propagate(m_currentNode);
  504. }
  505. }
  506. }
  507. void propagateBackward()
  508. {
  509. #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
  510. dataLogF("Propagating predictions backward [%u]\n", ++m_count);
  511. #endif
  512. for (BlockIndex blockIndex = m_graph.m_blocks.size(); blockIndex--;) {
  513. BasicBlock* block = m_graph.m_blocks[blockIndex].get();
  514. if (!block)
  515. continue;
  516. ASSERT(block->isReachable);
  517. for (unsigned i = block->size(); i--;) {
  518. m_currentNode = block->at(i);
  519. propagate(m_currentNode);
  520. }
  521. }
  522. }
  523. void doDoubleVoting(Node* node)
  524. {
  525. switch (node->op()) {
  526. case ValueAdd:
  527. case ArithAdd:
  528. case ArithSub: {
  529. SpeculatedType left = node->child1()->prediction();
  530. SpeculatedType right = node->child2()->prediction();
  531. DoubleBallot ballot;
  532. if (isNumberSpeculationExpectingDefined(left) && isNumberSpeculationExpectingDefined(right)
  533. && !m_graph.addShouldSpeculateInteger(node))
  534. ballot = VoteDouble;
  535. else
  536. ballot = VoteValue;
  537. m_graph.voteNode(node->child1(), ballot);
  538. m_graph.voteNode(node->child2(), ballot);
  539. break;
  540. }
  541. case ArithMul: {
  542. SpeculatedType left = node->child1()->prediction();
  543. SpeculatedType right = node->child2()->prediction();
  544. DoubleBallot ballot;
  545. if (isNumberSpeculation(left) && isNumberSpeculation(right)
  546. && !m_graph.mulShouldSpeculateInteger(node))
  547. ballot = VoteDouble;
  548. else
  549. ballot = VoteValue;
  550. m_graph.voteNode(node->child1(), ballot);
  551. m_graph.voteNode(node->child2(), ballot);
  552. break;
  553. }
  554. case ArithMin:
  555. case ArithMax:
  556. case ArithMod:
  557. case ArithDiv: {
  558. SpeculatedType left = node->child1()->prediction();
  559. SpeculatedType right = node->child2()->prediction();
  560. DoubleBallot ballot;
  561. if (isNumberSpeculation(left) && isNumberSpeculation(right)
  562. && !(Node::shouldSpeculateIntegerForArithmetic(node->child1().node(), node->child2().node()) && node->canSpeculateInteger()))
  563. ballot = VoteDouble;
  564. else
  565. ballot = VoteValue;
  566. m_graph.voteNode(node->child1(), ballot);
  567. m_graph.voteNode(node->child2(), ballot);
  568. break;
  569. }
  570. case ArithAbs:
  571. DoubleBallot ballot;
  572. if (!(node->child1()->shouldSpeculateIntegerForArithmetic() && node->canSpeculateInteger()))
  573. ballot = VoteDouble;
  574. else
  575. ballot = VoteValue;
  576. m_graph.voteNode(node->child1(), ballot);
  577. break;
  578. case ArithSqrt:
  579. m_graph.voteNode(node->child1(), VoteDouble);
  580. break;
  581. case SetLocal: {
  582. SpeculatedType prediction = node->child1()->prediction();
  583. if (isDoubleSpeculation(prediction))
  584. node->variableAccessData()->vote(VoteDouble);
  585. else if (!isNumberSpeculation(prediction) || isInt32Speculation(prediction))
  586. node->variableAccessData()->vote(VoteValue);
  587. break;
  588. }
  589. case PutByVal:
  590. case PutByValAlias: {
  591. Edge child1 = m_graph.varArgChild(node, 0);
  592. Edge child2 = m_graph.varArgChild(node, 1);
  593. Edge child3 = m_graph.varArgChild(node, 2);
  594. m_graph.voteNode(child1, VoteValue);
  595. m_graph.voteNode(child2, VoteValue);
  596. switch (node->arrayMode().type()) {
  597. case Array::Double:
  598. m_graph.voteNode(child3, VoteDouble);
  599. break;
  600. default:
  601. m_graph.voteNode(child3, VoteValue);
  602. break;
  603. }
  604. break;
  605. }
  606. default:
  607. m_graph.voteChildren(node, VoteValue);
  608. break;
  609. }
  610. }
  611. void doRoundOfDoubleVoting()
  612. {
  613. #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
  614. dataLogF("Voting on double uses of locals [%u]\n", m_count);
  615. #endif
  616. for (unsigned i = 0; i < m_graph.m_variableAccessData.size(); ++i)
  617. m_graph.m_variableAccessData[i].find()->clearVotes();
  618. for (BlockIndex blockIndex = 0; blockIndex < m_graph.m_blocks.size(); ++blockIndex) {
  619. BasicBlock* block = m_graph.m_blocks[blockIndex].get();
  620. if (!block)
  621. continue;
  622. ASSERT(block->isReachable);
  623. for (unsigned i = 0; i < block->size(); ++i) {
  624. m_currentNode = block->at(i);
  625. doDoubleVoting(m_currentNode);
  626. }
  627. }
  628. for (unsigned i = 0; i < m_graph.m_variableAccessData.size(); ++i) {
  629. VariableAccessData* variableAccessData = &m_graph.m_variableAccessData[i];
  630. if (!variableAccessData->isRoot())
  631. continue;
  632. m_changed |= variableAccessData->tallyVotesForShouldUseDoubleFormat();
  633. }
  634. for (unsigned i = 0; i < m_graph.m_argumentPositions.size(); ++i)
  635. m_changed |= m_graph.m_argumentPositions[i].mergeArgumentPredictionAwareness();
  636. for (unsigned i = 0; i < m_graph.m_variableAccessData.size(); ++i) {
  637. VariableAccessData* variableAccessData = &m_graph.m_variableAccessData[i];
  638. if (!variableAccessData->isRoot())
  639. continue;
  640. m_changed |= variableAccessData->makePredictionForDoubleFormat();
  641. }
  642. }
  643. Node* m_currentNode;
  644. bool m_changed;
  645. #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
  646. unsigned m_count;
  647. #endif
  648. };
  649. bool performPredictionPropagation(Graph& graph)
  650. {
  651. SamplingRegion samplingRegion("DFG Prediction Propagation Phase");
  652. return runPhase<PredictionPropagationPhase>(graph);
  653. }
  654. } } // namespace JSC::DFG
  655. #endif // ENABLE(DFG_JIT)