// 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.definitelyNotNull;
import static com.android.tools.r8.ir.analysis.type.Nullability.maybeNull;

import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.ir.analysis.type.TypeElement;
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.InstructionIterator;
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.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<?> 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<?> appView) {
    this.field = field;
    this.code = code;
    this.root = root;
    this.appView = appView;
    // Verify that `root` is not aliased.
    assert root.hasOutValue();
    assert root.outValue() == root.outValue().getAliasedValue();
  }

  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,
              TypeElement.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);

      TypeElement phiType = phi.computePhiType(appView);
      assert phiType.lessThanOrEqual(phi.getType(), appView);
      phi.setType(phiType);

      value = phi;
    }

    assert value != null;
    return value;
  }

  private Value getValueDefinedInTheBlock(BasicBlock block, Instruction stopAt) {
    InstructionIterator iterator =
        stopAt == null ? block.iterator(block.getInstructions().size()) : block.iterator(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().getAliasedValue() == root.outValue())) {
        valueProducingInsn = instruction;
        break;
      }
    }

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

    assert root == valueProducingInsn;
    if (defaultValue == null) {
      InstructionListIterator it = block.listIterator(code, root);
      // If we met newInstance it means that default value is supposed to be used.
      if (field.type.isPrimitiveType()) {
        defaultValue =
            code.createValue(TypeElement.fromDexType(field.type, definitelyNotNull(), appView));
        ConstNumber defaultValueInsn = new ConstNumber(defaultValue, 0);
        defaultValueInsn.setPosition(root.getPosition());
        it.add(defaultValueInsn);
      } else {
        defaultValue = it.insertConstNullInstruction(code, appView.options());
      }
    }
    return defaultValue;
  }
}
