143 lines
4.3 KiB
C++
143 lines
4.3 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
|
*/
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#include "jit/IonAnalysis.h"
|
|
#include "jit/MIRGenerator.h"
|
|
#include "jit/MIRGraph.h"
|
|
#include "jit/ValueNumbering.h"
|
|
|
|
#include "jsapi-tests/testJitMinimalFunc.h"
|
|
#include "jsapi-tests/tests.h"
|
|
|
|
using namespace js;
|
|
using namespace js::jit;
|
|
|
|
BEGIN_TEST(testJitDCEinGVN_ins)
|
|
{
|
|
MinimalFunc func;
|
|
MBasicBlock* block = func.createEntryBlock();
|
|
|
|
// mul0 = p * p
|
|
// mul1 = mul0 * mul0
|
|
// return p
|
|
MParameter* p = func.createParameter();
|
|
block->add(p);
|
|
MMul* mul0 = MMul::New(func.alloc, p, p, MIRType::Double);
|
|
block->add(mul0);
|
|
if (!mul0->typePolicy()->adjustInputs(func.alloc, mul0))
|
|
return false;
|
|
MMul* mul1 = MMul::New(func.alloc, mul0, mul0, MIRType::Double);
|
|
block->add(mul1);
|
|
if (!mul1->typePolicy()->adjustInputs(func.alloc, mul1))
|
|
return false;
|
|
MReturn* ret = MReturn::New(func.alloc, p);
|
|
block->end(ret);
|
|
|
|
if (!func.runGVN())
|
|
return false;
|
|
|
|
// mul0 and mul1 should be deleted.
|
|
for (MInstructionIterator ins = block->begin(); ins != block->end(); ins++) {
|
|
CHECK(!ins->isMul() || (ins->getOperand(0) != p && ins->getOperand(1) != p));
|
|
CHECK(!ins->isMul() || (ins->getOperand(0) != mul0 && ins->getOperand(1) != mul0));
|
|
}
|
|
return true;
|
|
}
|
|
END_TEST(testJitDCEinGVN_ins)
|
|
|
|
BEGIN_TEST(testJitDCEinGVN_phi)
|
|
{
|
|
MinimalFunc func;
|
|
MBasicBlock* block = func.createEntryBlock();
|
|
MBasicBlock* thenBlock1 = func.createBlock(block);
|
|
MBasicBlock* thenBlock2 = func.createBlock(block);
|
|
MBasicBlock* elifBlock = func.createBlock(block);
|
|
MBasicBlock* elseBlock = func.createBlock(block);
|
|
MBasicBlock* joinBlock = func.createBlock(block);
|
|
|
|
// if (p) {
|
|
// x = 1.0;
|
|
// y = 3.0;
|
|
// } else if (q) {
|
|
// x = 2.0;
|
|
// y = 4.0;
|
|
// } else {
|
|
// x = 1.0;
|
|
// y = 5.0;
|
|
// }
|
|
// x = phi(1.0, 2.0, 1.0);
|
|
// y = phi(3.0, 4.0, 5.0);
|
|
// z = x * y;
|
|
// return y;
|
|
|
|
MConstant* c1 = MConstant::New(func.alloc, DoubleValue(1.0));
|
|
block->add(c1);
|
|
MPhi* x = MPhi::New(func.alloc);
|
|
MPhi* y = MPhi::New(func.alloc);
|
|
|
|
// if (p) {
|
|
MParameter* p = func.createParameter();
|
|
block->add(p);
|
|
block->end(MTest::New(func.alloc, p, thenBlock1, elifBlock));
|
|
|
|
// x = 1.0
|
|
// y = 3.0;
|
|
MOZ_RELEASE_ASSERT(x->addInputSlow(c1));
|
|
MConstant* c3 = MConstant::New(func.alloc, DoubleValue(3.0));
|
|
thenBlock1->add(c3);
|
|
MOZ_RELEASE_ASSERT(y->addInputSlow(c3));
|
|
thenBlock1->end(MGoto::New(func.alloc, joinBlock));
|
|
MOZ_ALWAYS_TRUE(joinBlock->addPredecessor(func.alloc, thenBlock1));
|
|
|
|
// } else if (q) {
|
|
MParameter* q = func.createParameter();
|
|
elifBlock->add(q);
|
|
elifBlock->end(MTest::New(func.alloc, q, thenBlock2, elseBlock));
|
|
|
|
// x = 2.0
|
|
// y = 4.0;
|
|
MConstant* c2 = MConstant::New(func.alloc, DoubleValue(2.0));
|
|
thenBlock2->add(c2);
|
|
MOZ_RELEASE_ASSERT(x->addInputSlow(c2));
|
|
MConstant* c4 = MConstant::New(func.alloc, DoubleValue(4.0));
|
|
thenBlock2->add(c4);
|
|
MOZ_RELEASE_ASSERT(y->addInputSlow(c4));
|
|
thenBlock2->end(MGoto::New(func.alloc, joinBlock));
|
|
MOZ_ALWAYS_TRUE(joinBlock->addPredecessor(func.alloc, thenBlock2));
|
|
|
|
// } else {
|
|
// x = 1.0
|
|
// y = 5.0;
|
|
// }
|
|
MOZ_RELEASE_ASSERT(x->addInputSlow(c1));
|
|
MConstant* c5 = MConstant::New(func.alloc, DoubleValue(5.0));
|
|
elseBlock->add(c5);
|
|
MOZ_RELEASE_ASSERT(y->addInputSlow(c5));
|
|
elseBlock->end(MGoto::New(func.alloc, joinBlock));
|
|
MOZ_ALWAYS_TRUE(joinBlock->addPredecessor(func.alloc, elseBlock));
|
|
|
|
// x = phi(1.0, 2.0, 1.0)
|
|
// y = phi(3.0, 4.0, 5.0)
|
|
// z = x * y
|
|
// return y
|
|
joinBlock->addPhi(x);
|
|
joinBlock->addPhi(y);
|
|
MMul* z = MMul::New(func.alloc, x, y, MIRType::Double);
|
|
joinBlock->add(z);
|
|
MReturn* ret = MReturn::New(func.alloc, y);
|
|
joinBlock->end(ret);
|
|
|
|
if (!func.runGVN())
|
|
return false;
|
|
|
|
// c1 should be deleted.
|
|
for (MInstructionIterator ins = block->begin(); ins != block->end(); ins++) {
|
|
CHECK(!ins->isConstant() || (ins->toConstant()->numberToDouble() != 1.0));
|
|
}
|
|
return true;
|
|
}
|
|
END_TEST(testJitDCEinGVN_phi)
|