// 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 com.android.tools.r8.graph.AppInfo;
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 AppInfo appInfo;

  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, AppInfo appInfo) {
    this.field = field;
    this.code = code;
    this.root = root;
    this.appInfo = appInfo;
  }

  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, true, appInfo),
              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, true, appInfo));
      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;
  }
}
