// Copyright (c) 2018, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

package com.android.tools.r8.ir.optimize.classinliner;

import static com.android.tools.r8.ir.analysis.type.Nullability.maybeNull;

import com.android.tools.r8.graph.AppInfo;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.ir.analysis.type.TypeLatticeElement;
import com.android.tools.r8.ir.code.BasicBlock;
import com.android.tools.r8.ir.code.ConstNumber;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.Instruction;
import com.android.tools.r8.ir.code.InstructionListIterator;
import com.android.tools.r8.ir.code.Phi;
import com.android.tools.r8.ir.code.Phi.RegisterReadType;
import com.android.tools.r8.ir.code.Value;
import java.util.ArrayList;
import java.util.IdentityHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

// Describes and caches what values are supposed to be used instead of field reads.
final class FieldValueHelper {
  private final DexField field;
  private final IRCode code;
  private final Instruction root;
  private final AppView<? extends AppInfo> appView;

  private Value defaultValue = null;
  private final Map<BasicBlock, Value> ins = new IdentityHashMap<>();
  private final Map<BasicBlock, Value> outs = new IdentityHashMap<>();

  FieldValueHelper(
      DexField field, IRCode code, Instruction root, AppView<? extends AppInfo> appView) {
    this.field = field;
    this.code = code;
    this.root = root;
    this.appView = appView;
  }

  void replaceValue(Value oldValue, Value newValue) {
    for (Entry<BasicBlock, Value> entry : ins.entrySet()) {
      if (entry.getValue() == oldValue) {
        entry.setValue(newValue);
      }
    }
    for (Entry<BasicBlock, Value> entry : outs.entrySet()) {
      if (entry.getValue() == oldValue) {
        entry.setValue(newValue);
      }
    }
  }

  Value getValueForFieldRead(BasicBlock block, Instruction valueUser) {
    assert valueUser != null;
    Value value = getValueDefinedInTheBlock(block, valueUser);
    return value != null ? value : getOrCreateInValue(block);
  }

  private Value getOrCreateOutValue(BasicBlock block) {
    Value value = outs.get(block);
    if (value != null) {
      return value;
    }

    value = getValueDefinedInTheBlock(block, null);
    if (value == null) {
      // No value defined in the block.
      value = getOrCreateInValue(block);
    }

    assert value != null;
    outs.put(block, value);
    return value;
  }

  private Value getOrCreateInValue(BasicBlock block) {
    Value value = ins.get(block);
    if (value != null) {
      return value;
    }

    List<BasicBlock> predecessors = block.getPredecessors();
    if (predecessors.size() == 1) {
      value = getOrCreateOutValue(predecessors.get(0));
      ins.put(block, value);
    } else {
      // Create phi, add it to the block, cache in ins map for future use.
      Phi phi =
          new Phi(
              code.valueNumberGenerator.next(),
              block,
              TypeLatticeElement.fromDexType(field.type, maybeNull(), appView),
              null,
              RegisterReadType.NORMAL);
      ins.put(block, phi);

      List<Value> operands = new ArrayList<>();
      for (BasicBlock predecessor : block.getPredecessors()) {
        operands.add(getOrCreateOutValue(predecessor));
      }
      // Add phi, but don't remove trivial phis; since we cache the phi
      // we just created for future use we should delay removing trivial
      // phis until we are done with replacing fields reads.
      phi.addOperands(operands, false);
      value = phi;
    }

    assert value != null;
    return value;
  }

  private Value getValueDefinedInTheBlock(BasicBlock block, Instruction stopAt) {
    InstructionListIterator iterator = stopAt == null ?
        block.listIterator(block.getInstructions().size()) : block.listIterator(stopAt);

    Instruction valueProducingInsn = null;
    while (iterator.hasPrevious()) {
      Instruction instruction = iterator.previous();
      assert instruction != null;

      if (instruction == root ||
          (instruction.isInstancePut() &&
              instruction.asInstancePut().getField() == field &&
              instruction.asInstancePut().object() == root.outValue())) {
        valueProducingInsn = instruction;
        break;
      }
    }

    if (valueProducingInsn == null) {
      return null;
    }
    if (valueProducingInsn.isInstancePut()) {
      return valueProducingInsn.asInstancePut().value();
    }

    assert root == valueProducingInsn;
    if (defaultValue == null) {
      // If we met newInstance it means that default value is supposed to be used.
      defaultValue =
          code.createValue(TypeLatticeElement.fromDexType(field.type, maybeNull(), appView));
      ConstNumber defaultValueInsn = new ConstNumber(defaultValue, 0);
      defaultValueInsn.setPosition(root.getPosition());
      LinkedList<Instruction> instructions = block.getInstructions();
      instructions.add(instructions.indexOf(root) + 1, defaultValueInsn);
      defaultValueInsn.setBlock(block);
    }
    return defaultValue;
  }
}
