/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
 * vim: set ts=8 sts=4 et sw=4 tw=99:
 */
/* 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;
    x->addInputSlow(c1);
    MConstant* c3 = MConstant::New(func.alloc, DoubleValue(3.0));
    thenBlock1->add(c3);
    y->addInputSlow(c3);
    thenBlock1->end(MGoto::New(func.alloc, joinBlock));
    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);
    x->addInputSlow(c2);
    MConstant* c4 = MConstant::New(func.alloc, DoubleValue(4.0));
    thenBlock2->add(c4);
    y->addInputSlow(c4);
    thenBlock2->end(MGoto::New(func.alloc, joinBlock));
    joinBlock->addPredecessor(func.alloc, thenBlock2);

    // } else {
    //   x = 1.0
    //   y = 5.0;
    // }
    x->addInputSlow(c1);
    MConstant* c5 = MConstant::New(func.alloc, DoubleValue(5.0));
    elseBlock->add(c5);
    y->addInputSlow(c5);
    elseBlock->end(MGoto::New(func.alloc, joinBlock));
    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()->value().toNumber() != 1.0));
    }
    return true;
}
END_TEST(testJitDCEinGVN_phi)
