LCOV - code coverage report
Current view: top level - js/src/jit - EagerSimdUnbox.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 8 62 12.9 %
Date: 2017-07-14 16:53:18 Functions: 1 3 33.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
       2             :  * vim: set ts=8 sts=4 et sw=4 tw=99:
       3             :  * This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #include "jit/EagerSimdUnbox.h"
       8             : 
       9             : #include "jit/MIR.h"
      10             : #include "jit/MIRGenerator.h"
      11             : #include "jit/MIRGraph.h"
      12             : 
      13             : namespace js {
      14             : namespace jit {
      15             : 
      16             : // Do not optimize any Phi instruction which has conflicting Unbox operations,
      17             : // as this might imply some intended polymorphism.
      18             : static bool
      19           0 : CanUnboxSimdPhi(const JitCompartment* jitCompartment, MPhi* phi, SimdType unboxType)
      20             : {
      21           0 :     MOZ_ASSERT(phi->type() == MIRType::Object);
      22             : 
      23             :     // If we are unboxing, we are more than likely to have boxed this SIMD type
      24             :     // once in baseline, otherwise, we cannot create a MSimdBox as we have no
      25             :     // template object to use.
      26           0 :     if (!jitCompartment->maybeGetSimdTemplateObjectFor(unboxType))
      27           0 :         return false;
      28             : 
      29           0 :     MResumePoint* entry = phi->block()->entryResumePoint();
      30           0 :     MIRType mirType = SimdTypeToMIRType(unboxType);
      31           0 :     for (MUseIterator i(phi->usesBegin()), e(phi->usesEnd()); i != e; i++) {
      32             :         // If we cannot recover the Simd object at the entry of the basic block,
      33             :         // then we would have to box the content anyways.
      34           0 :         if ((*i)->consumer() == entry && !entry->isRecoverableOperand(*i))
      35           0 :             return false;
      36             : 
      37           0 :         if (!(*i)->consumer()->isDefinition())
      38           0 :             continue;
      39             : 
      40           0 :         MDefinition* def = (*i)->consumer()->toDefinition();
      41           0 :         if (def->isSimdUnbox() && def->toSimdUnbox()->type() != mirType)
      42           0 :             return false;
      43             :     }
      44             : 
      45           0 :     return true;
      46             : }
      47             : 
      48             : static void
      49           0 : UnboxSimdPhi(const JitCompartment* jitCompartment, MIRGraph& graph, MPhi* phi, SimdType unboxType)
      50             : {
      51           0 :     TempAllocator& alloc = graph.alloc();
      52             : 
      53             :     // Unbox and replace all operands.
      54           0 :     for (size_t i = 0, e = phi->numOperands(); i < e; i++) {
      55           0 :         MDefinition* op = phi->getOperand(i);
      56           0 :         MSimdUnbox* unbox = MSimdUnbox::New(alloc, op, unboxType);
      57           0 :         op->block()->insertAtEnd(unbox);
      58           0 :         phi->replaceOperand(i, unbox);
      59             :     }
      60             : 
      61             :     // Change the MIRType of the Phi.
      62           0 :     MIRType mirType = SimdTypeToMIRType(unboxType);
      63           0 :     phi->setResultType(mirType);
      64             : 
      65           0 :     MBasicBlock* phiBlock = phi->block();
      66           0 :     MInstruction* atRecover = phiBlock->safeInsertTop(nullptr, MBasicBlock::IgnoreRecover);
      67           0 :     MInstruction* at = phiBlock->safeInsertTop(atRecover);
      68             : 
      69             :     // Note, we capture the uses-list now, as new instructions are not visited.
      70           0 :     MUseIterator i(phi->usesBegin()), e(phi->usesEnd());
      71             : 
      72             :     // Add a MSimdBox, and replace all the Phi uses with it.
      73           0 :     JSObject* templateObject = jitCompartment->maybeGetSimdTemplateObjectFor(unboxType);
      74           0 :     InlineTypedObject* inlineTypedObject = &templateObject->as<InlineTypedObject>();
      75           0 :     MSimdBox* recoverBox = MSimdBox::New(alloc, nullptr, phi, inlineTypedObject, unboxType, gc::DefaultHeap);
      76           0 :     recoverBox->setRecoveredOnBailout();
      77           0 :     phiBlock->insertBefore(atRecover, recoverBox);
      78             : 
      79           0 :     MSimdBox* box = nullptr;
      80           0 :     while (i != e) {
      81           0 :         MUse* use = *i++;
      82           0 :         MNode* ins = use->consumer();
      83             : 
      84           0 :         if ((ins->isDefinition() && ins->toDefinition()->isRecoveredOnBailout()) ||
      85           0 :             (ins->isResumePoint() && ins->toResumePoint()->isRecoverableOperand(use)))
      86             :         {
      87           0 :             use->replaceProducer(recoverBox);
      88           0 :             continue;
      89             :         }
      90             : 
      91           0 :         if (!box) {
      92           0 :             box = MSimdBox::New(alloc, nullptr, phi, inlineTypedObject, unboxType, gc::DefaultHeap);
      93           0 :             phiBlock->insertBefore(at, box);
      94             :         }
      95             : 
      96           0 :         use->replaceProducer(box);
      97             :     }
      98           0 : }
      99             : 
     100             : bool
     101           8 : EagerSimdUnbox(MIRGenerator* mir, MIRGraph& graph)
     102             : {
     103           8 :     const JitCompartment* jitCompartment = GetJitContext()->compartment->jitCompartment();
     104         461 :     for (PostorderIterator block = graph.poBegin(); block != graph.poEnd(); block++) {
     105         453 :         if (mir->shouldCancel("Eager Simd Unbox"))
     106           0 :             return false;
     107             : 
     108        2987 :         for (MInstructionReverseIterator ins = block->rbegin(); ins != block->rend(); ins++) {
     109        2534 :             if (!ins->isSimdUnbox())
     110        2534 :                 continue;
     111             : 
     112           0 :             MSimdUnbox* unbox = ins->toSimdUnbox();
     113           0 :             if (!unbox->input()->isPhi())
     114           0 :                 continue;
     115             : 
     116           0 :             MPhi* phi = unbox->input()->toPhi();
     117           0 :             if (!CanUnboxSimdPhi(jitCompartment, phi, unbox->simdType()))
     118           0 :                 continue;
     119             : 
     120           0 :             UnboxSimdPhi(jitCompartment, graph, phi, unbox->simdType());
     121             :         }
     122             :     }
     123             : 
     124           8 :     return true;
     125             : }
     126             : 
     127             : } /* namespace jit */
     128             : } /* namespace js */

Generated by: LCOV version 1.13