tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

testJitDCEinGVN.cpp (4264B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
      2 * vim: set ts=8 sts=2 et sw=2 tw=80:
      3 */
      4 /* This Source Code Form is subject to the terms of the Mozilla Public
      5 * License, v. 2.0. If a copy of the MPL was not distributed with this
      6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      7 
      8 #include "jit/IonAnalysis.h"
      9 #include "jit/MIRGenerator.h"
     10 #include "jit/MIRGraph.h"
     11 #include "jit/ValueNumbering.h"
     12 
     13 #include "jsapi-tests/testJitMinimalFunc.h"
     14 #include "jsapi-tests/tests.h"
     15 
     16 using namespace js;
     17 using namespace js::jit;
     18 
     19 BEGIN_TEST(testJitDCEinGVN_ins) {
     20  MinimalFunc func;
     21  MBasicBlock* block = func.createEntryBlock();
     22 
     23  // mul0 = p * p
     24  // mul1 = mul0 * mul0
     25  // return p
     26  MParameter* p = func.createParameter();
     27  block->add(p);
     28  MMul* mul0 = MMul::New(func.alloc, p, p, MIRType::Double);
     29  block->add(mul0);
     30  if (!mul0->typePolicy()->adjustInputs(func.alloc, mul0)) {
     31    return false;
     32  }
     33  MMul* mul1 = MMul::New(func.alloc, mul0, mul0, MIRType::Double);
     34  block->add(mul1);
     35  if (!mul1->typePolicy()->adjustInputs(func.alloc, mul1)) {
     36    return false;
     37  }
     38  MReturn* ret = MReturn::New(func.alloc, p);
     39  block->end(ret);
     40 
     41  if (!func.runGVN()) {
     42    return false;
     43  }
     44 
     45  // mul0 and mul1 should be deleted.
     46  for (MInstructionIterator ins = block->begin(); ins != block->end(); ins++) {
     47    CHECK(!ins->isMul() ||
     48          (ins->getOperand(0) != p && ins->getOperand(1) != p));
     49    CHECK(!ins->isMul() ||
     50          (ins->getOperand(0) != mul0 && ins->getOperand(1) != mul0));
     51  }
     52  return true;
     53 }
     54 END_TEST(testJitDCEinGVN_ins)
     55 
     56 BEGIN_TEST(testJitDCEinGVN_phi) {
     57  MinimalFunc func;
     58  MBasicBlock* block = func.createEntryBlock();
     59  MBasicBlock* thenBlock1 = func.createBlock(block);
     60  MBasicBlock* thenBlock2 = func.createBlock(block);
     61  MBasicBlock* elifBlock = func.createBlock(block);
     62  MBasicBlock* elseBlock = func.createBlock(block);
     63  MBasicBlock* joinBlock = func.createBlock(block);
     64 
     65  // if (p) {
     66  //   x = 1.0;
     67  //   y = 3.0;
     68  // } else if (q) {
     69  //   x = 2.0;
     70  //   y = 4.0;
     71  // } else {
     72  //   x = 1.0;
     73  //   y = 5.0;
     74  // }
     75  // x = phi(1.0, 2.0, 1.0);
     76  // y = phi(3.0, 4.0, 5.0);
     77  // z = x * y;
     78  // return y;
     79 
     80  MConstant* c1 = MConstant::NewDouble(func.alloc, 1.0);
     81  block->add(c1);
     82  MPhi* x = MPhi::New(func.alloc);
     83  MPhi* y = MPhi::New(func.alloc);
     84 
     85  // if (p) {
     86  MParameter* p = func.createParameter();
     87  block->add(p);
     88  block->end(MTest::New(func.alloc, p, thenBlock1, elifBlock));
     89 
     90  //   x = 1.0
     91  //   y = 3.0;
     92  MOZ_RELEASE_ASSERT(x->addInputSlow(c1));
     93  MConstant* c3 = MConstant::NewDouble(func.alloc, 3.0);
     94  thenBlock1->add(c3);
     95  MOZ_RELEASE_ASSERT(y->addInputSlow(c3));
     96  thenBlock1->end(MGoto::New(func.alloc, joinBlock));
     97  MOZ_ALWAYS_TRUE(joinBlock->addPredecessor(func.alloc, thenBlock1));
     98 
     99  // } else if (q) {
    100  MParameter* q = func.createParameter();
    101  elifBlock->add(q);
    102  elifBlock->end(MTest::New(func.alloc, q, thenBlock2, elseBlock));
    103 
    104  //   x = 2.0
    105  //   y = 4.0;
    106  MConstant* c2 = MConstant::NewDouble(func.alloc, 2.0);
    107  thenBlock2->add(c2);
    108  MOZ_RELEASE_ASSERT(x->addInputSlow(c2));
    109  MConstant* c4 = MConstant::NewDouble(func.alloc, 4.0);
    110  thenBlock2->add(c4);
    111  MOZ_RELEASE_ASSERT(y->addInputSlow(c4));
    112  thenBlock2->end(MGoto::New(func.alloc, joinBlock));
    113  MOZ_ALWAYS_TRUE(joinBlock->addPredecessor(func.alloc, thenBlock2));
    114 
    115  // } else {
    116  //   x = 1.0
    117  //   y = 5.0;
    118  // }
    119  MOZ_RELEASE_ASSERT(x->addInputSlow(c1));
    120  MConstant* c5 = MConstant::NewDouble(func.alloc, 5.0);
    121  elseBlock->add(c5);
    122  MOZ_RELEASE_ASSERT(y->addInputSlow(c5));
    123  elseBlock->end(MGoto::New(func.alloc, joinBlock));
    124  MOZ_ALWAYS_TRUE(joinBlock->addPredecessor(func.alloc, elseBlock));
    125 
    126  // x = phi(1.0, 2.0, 1.0)
    127  // y = phi(3.0, 4.0, 5.0)
    128  // z = x * y
    129  // return y
    130  joinBlock->addPhi(x);
    131  joinBlock->addPhi(y);
    132  MMul* z = MMul::New(func.alloc, x, y, MIRType::Double);
    133  joinBlock->add(z);
    134  MReturn* ret = MReturn::New(func.alloc, y);
    135  joinBlock->end(ret);
    136 
    137  if (!func.runGVN()) {
    138    return false;
    139  }
    140 
    141  // c1 should be deleted.
    142  for (MInstructionIterator ins = block->begin(); ins != block->end(); ins++) {
    143    CHECK(!ins->isConstant() || (ins->toConstant()->numberToDouble() != 1.0));
    144  }
    145  return true;
    146 }
    147 END_TEST(testJitDCEinGVN_phi)