/*
 * 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"

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(), Primitive::kPrimNot);

    // 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()) {
}

void X86MemoryOperandGeneration::Run() {
  MemoryOperandVisitor visitor(graph_, do_implicit_null_checks_);
  visitor.VisitInsertionOrder();
}

}  // namespace x86
}  // namespace art
