/*
 * Copyright (C) 2021 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "B3CanonicalizePrePostIncrements.h"

#include "B3BackwardsDominators.h"
#include "B3BasicBlockInlines.h"
#include "B3BlockInsertionSet.h"
#include "B3Dominators.h"
#include "B3InsertionSetInlines.h"
#include "B3PhaseScope.h"
#include "B3ProcedureInlines.h"
#include "B3ValueInlines.h"
#include "B3ValueKeyInlines.h"
#include <wtf/HashMap.h>
#include <wtf/IndexSet.h>
#include <wtf/StdLibExtras.h>

#if ENABLE(B3_JIT)

namespace JSC { namespace B3 {

bool canonicalizePrePostIncrements(Procedure& proc)
{
    if (!isARM64())
        return false;
    PhaseScope phaseScope(proc, "canonicalizePrePostIncrements");
    using Arg = Air::Arg;

    unsigned index { 0 };
    InsertionSet insertionSet { proc };
    BlockInsertionSet blockInsertionSet { proc };

    Dominators& dominators = proc.dominators();
    BackwardsDominators& backwardsDominators = proc.backwardsDominators();

    IndexSet<Value*> ignoredValues;
    HashMap<Value*, Vector<MemoryValue*>> baseToLoads;
    HashMap<MemoryValue*, Value*> preIndexLoadCandidates;
    HashMap<MemoryValue*, Value*> postIndexLoadCandidates;
    HashMap<ValueKey, Vector<Value*>> baseOffsetToAddresses;

    HashMap<Value*, Vector<MemoryValue*>> baseToStores;
    HashMap<MemoryValue*, Value*> postIndexStoreCandidates;

    auto tryAddPrePostIndexCandidate = [&] (Value* value) {
        switch (value->opcode()) {
        case Load: {
            // Pre-Index Pattern:
            //     address = Add(base, offset)
            //     ...
            //     memory = Load(base, offset)
            // Post-Index Pattern:
            //     memory = Load(base, 0)
            //     ...
            //     address = Add(base, offset)
            auto tryAddpreIndexLoadCandidates = [&] () {
                MemoryValue* memory = value->as<MemoryValue>();
                if (memory->type() != Int32 && memory->type() != Int64)
                    return;
                if (memory->offset()) {
                    if (!Arg::isValidIncrementIndexForm(memory->offset()))
                        return;
                    ValueKey baseOffsetkey = ValueKey(memory->child(0), static_cast<int64_t>(memory->offset()));
                    if (!baseOffsetToAddresses.contains(baseOffsetkey))
                        return;
                    for (Value* address : baseOffsetToAddresses.get(baseOffsetkey))
                        preIndexLoadCandidates.add(memory, address);
                } else
                    baseToLoads.add(memory->child(0), Vector<MemoryValue*>()).iterator->value.append(memory);
            };

            tryAddpreIndexLoadCandidates();
            break;
        }

        case Store: {
            // Pre-Index Pattern:
            //     address = Add(base, offset)
            //     memory = Store(value, base, offset)
            // Post-Index Pattern:
            //     memory = Store(value, base, 0)
            //     ...
            //     address = Add(base, offset)
            auto tryUpdateBaseToStores = [&] () {
                MemoryValue* memory = value->as<MemoryValue>();
                if (memory->child(0)->type() != Int32 && memory->child(0)->type() != Int64)
                    return;
                if (memory->child(0)->hasInt() || memory->offset())
                    return;
                baseToStores.add(memory->child(1), Vector<MemoryValue*>()).iterator->value.append(memory);
            };

            tryUpdateBaseToStores();
            break;
        }

        case Add: {
            Value* left = value->child(0);
            Value* right = value->child(1);

            auto tryAddpostIndexCandidates = [&] () {
                if (!right->hasIntPtr() || value->type() != Int64)
                    return;
                intptr_t offset = right->asIntPtr();
                Value::OffsetType smallOffset = static_cast<Value::OffsetType>(offset);
                if (smallOffset != offset || !Arg::isValidIncrementIndexForm(smallOffset))
                    return;
                // so far this Add value is a valid address candidate for both prefix and postfix pattern
                ValueKey baseOffsetkey = ValueKey(left, static_cast<int64_t>(smallOffset));
                baseOffsetToAddresses.add(baseOffsetkey, Vector<Value*>()).iterator->value.append(value);
                if (baseToLoads.contains(left)) {
                    for (MemoryValue* memory : baseToLoads.get(left))
                        postIndexLoadCandidates.add(memory, value);
                }
                if (baseToStores.contains(left)) {
                    for (MemoryValue* memory : baseToStores.get(left))
                        postIndexStoreCandidates.add(memory, value);
                }
            };

            tryAddpostIndexCandidates();
            break;
        }

        default:
            break;
        }
    };

    for (BasicBlock* basicBlock : proc.blocksInPreOrder()) {
        for (index = 0; index < basicBlock->size(); ++index)
            tryAddPrePostIndexCandidate(basicBlock->at(index));
    }

    auto controlEquivalent = [&] (Value* v1, Value* v2) -> bool {
        return (dominators.dominates(v1->owner, v2->owner) && backwardsDominators.dominates(v2->owner, v1->owner))
            || (dominators.dominates(v2->owner, v1->owner) && backwardsDominators.dominates(v1->owner, v2->owner));
    };

    // This search is expensive. However, due to the greedy pattern
    // matching, no better method can be proposed at present.
    auto valueIndexInBasicBlock = [&] (Value* value) -> unsigned {
        unsigned index = 0;
        BasicBlock* block = value->owner;
        for (index = 0; index < block->size(); ++index) {
            if (block->at(index) == value)
                return index;
        }
        return index;
    };

    for (auto pair : preIndexLoadCandidates) {
        MemoryValue* memory = pair.key;
        Value* address = pair.value;
        if (ignoredValues.contains(memory) || ignoredValues.contains(address) || !controlEquivalent(memory, address))
            continue;
        // address = Add(base, offset)       address = Add(base, offset)
        // ...                          -->  newMemory = Load(base, offset)
        // ...                               ...
        // memory = Load(base, offset)       memory = Identity(newMemory)
        unsigned insertionIndex = valueIndexInBasicBlock(address) + 1;
        MemoryValue* newMemory = insertionSet.insert<MemoryValue>(insertionIndex, Load, memory->type(), address->origin(), memory->lastChild());
        newMemory->setOffset(memory->offset());
        memory->replaceWithIdentity(newMemory);
        insertionSet.execute(address->owner);

        ignoredValues.add(memory);
        ignoredValues.add(address);
    }

    auto detectPostIndex = [&] (const HashMap<MemoryValue*, Value*>& candidates) {
        for (auto pair : candidates) {
            MemoryValue* memory = pair.key;
            Value* address = pair.value;
            if (ignoredValues.contains(memory) || ignoredValues.contains(address) || !controlEquivalent(memory, address))
                continue;

            unsigned insertionIndex = valueIndexInBasicBlock(memory);
            Value* newOffset = insertionSet.insert<Const64Value>(insertionIndex, memory->origin(), address->child(1)->asInt());
            Value* newAddress = insertionSet.insert<Value>(insertionIndex, Add, memory->origin(), address->child(0), newOffset);
            address->replaceWithIdentity(newAddress);
            insertionSet.execute(memory->owner);

            ignoredValues.add(memory);
            ignoredValues.add(address);
        }
    };

    // ...                                  newOffset = Constant
    // ...                                  newAddress = Add(base, newOffset)
    // memory = Load(base, 0)               memory = Load(base, 0)
    // ...                            -->   ...
    // address = Add(base, offset)          address = Identity(newAddress)
    detectPostIndex(postIndexLoadCandidates);

    // ...                                  newOffset = Constant
    // ...                                  newAddress = Add(base, newOffset)
    // memory = Store(value, base, 0)       memory = Store(value, base, 0)
    // ...                            -->   ...
    // address = Add(base, offset)          address = Identity(newAddress)
    detectPostIndex(postIndexStoreCandidates);
    return true;
}

} } // namespace JSC::B3

#endif // ENABLE(B3_JIT)
