/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "x86_memory_gen.h"
#include "code_generator.h"
#include "driver/compiler_options.h"

namespace art {
namespace x86 {

/**
 * Replace instructions with memory operand forms.
 */
class MemoryOperandVisitor : public HGraphVisitor {
 public:
  MemoryOperandVisitor(HGraph* graph, bool do_implicit_null_checks)
      : HGraphVisitor(graph),
        do_implicit_null_checks_(do_implicit_null_checks) {}

 private:
  void VisitBoundsCheck(HBoundsCheck* check) override {
    // Replace the length by the array itself, so that we can do compares to memory.
    HArrayLength* array_len = check->InputAt(1)->AsArrayLength();

    // We only want to replace an ArrayLength.
    if (array_len == nullptr) {
      return;
    }

    HInstruction* array = array_len->InputAt(0);
    DCHECK_EQ(array->GetType(), DataType::Type::kReference);

    // Don't apply this optimization when the array is nullptr.
    if (array->IsConstant() || (array->IsNullCheck() && array->InputAt(0)->IsConstant())) {
      return;
    }

    // Is there a null check that could be an implicit check?
    if (array->IsNullCheck() && do_implicit_null_checks_) {
      // The ArrayLen may generate the implicit null check.  Can the
      // bounds check do so as well?
      if (array_len->GetNextDisregardingMoves() != check) {
        // No, it won't.  Leave as is.
        return;
      }
    }

    // Can we suppress the ArrayLength and generate at BoundCheck?
    if (array_len->HasOnlyOneNonEnvironmentUse()) {
      array_len->MarkEmittedAtUseSite();
      // We need the ArrayLength just before the BoundsCheck.
      array_len->MoveBefore(check);
    }
  }

  bool do_implicit_null_checks_;
};

X86MemoryOperandGeneration::X86MemoryOperandGeneration(HGraph* graph,
                                                       CodeGenerator* codegen,
                                                       OptimizingCompilerStats* stats)
    : HOptimization(graph, kX86MemoryOperandGenerationPassName, stats),
      do_implicit_null_checks_(codegen->GetCompilerOptions().GetImplicitNullChecks()) {
}

bool X86MemoryOperandGeneration::Run() {
  MemoryOperandVisitor visitor(graph_, do_implicit_null_checks_);
  visitor.VisitInsertionOrder();
  return true;
}

}  // namespace x86
}  // namespace art
