176716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray/*
276716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray * Copyright (C) 2014 The Android Open Source Project
376716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray *
476716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray * Licensed under the Apache License, Version 2.0 (the "License");
576716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray * you may not use this file except in compliance with the License.
676716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray * You may obtain a copy of the License at
776716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray *
876716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray *      http://www.apache.org/licenses/LICENSE-2.0
976716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray *
1076716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray * Unless required by applicable law or agreed to in writing, software
1176716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray * distributed under the License is distributed on an "AS IS" BASIS,
1276716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1376716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray * See the License for the specific language governing permissions and
1476716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray * limitations under the License.
1576716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray */
1676716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray
1776716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray#ifndef ART_COMPILER_OPTIMIZING_LOCATIONS_H_
1876716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray#define ART_COMPILER_OPTIMIZING_LOCATIONS_H_
1976716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray
2076716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray#include "base/bit_field.h"
2176716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray#include "utils/allocation.h"
2276716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray#include "utils/growable_array.h"
2376716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray#include "utils/managed_register.h"
2476716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray
2576716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffraynamespace art {
2676716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray
2796f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffrayclass HConstant;
2876716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffrayclass HInstruction;
2976716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray
3076716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray/**
3176716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray * A Location is an abstraction over the potential location
3276716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray * of an instruction. It could be in register or stack.
3376716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray */
3476716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffrayclass Location : public ValueObject {
3576716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray public:
3676716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  enum Kind {
3776716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    kInvalid = 0,
3896f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray    kConstant = 1,
3996f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray    kStackSlot = 2,  // Word size slot.
4096f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray    kDoubleStackSlot = 3,  // 64bit stack slot.
4196f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray    kRegister = 4,
4276716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    // On 32bits architectures, quick can pass a long where the
4376716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    // low bits are in the last parameter register, and the high
4476716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    // bits are in a stack slot. The kQuickParameter kind is for
4576716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    // handling this special case.
4696f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray    kQuickParameter = 5,
4776716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray
4876716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    // Unallocated location represents a location that is not fixed and can be
4976716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    // allocated by a register allocator.  Each unallocated location has
5076716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    // a policy that specifies what kind of location is suitable. Payload
5176716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    // contains register allocation policy.
5296f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray    kUnallocated = 6,
5376716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  };
5476716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray
5576716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  Location() : value_(kInvalid) {
5696f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray    // Verify that non-tagged location kinds do not interfere with kConstantTag.
5796f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray    COMPILE_ASSERT((kInvalid & kLocationTagMask) != kConstant, TagError);
5896f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray    COMPILE_ASSERT((kUnallocated & kLocationTagMask) != kConstant, TagError);
5996f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray    COMPILE_ASSERT((kStackSlot & kLocationTagMask) != kConstant, TagError);
6096f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray    COMPILE_ASSERT((kDoubleStackSlot & kLocationTagMask) != kConstant, TagError);
6196f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray    COMPILE_ASSERT((kRegister & kLocationTagMask) != kConstant, TagError);
6296f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray    COMPILE_ASSERT((kConstant & kLocationTagMask) == kConstant, TagError);
6396f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray    COMPILE_ASSERT((kQuickParameter & kLocationTagMask) == kConstant, TagError);
6496f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray
6576716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    DCHECK(!IsValid());
6676716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  }
6776716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray
6876716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  Location(const Location& other) : ValueObject(), value_(other.value_) {}
6976716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray
7076716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  Location& operator=(const Location& other) {
7176716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    value_ = other.value_;
7276716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    return *this;
7376716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  }
7476716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray
7596f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  bool IsConstant() const {
7696f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray    return (value_ & kLocationTagMask) == kConstant;
7796f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  }
7896f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray
7996f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  static Location ConstantLocation(HConstant* constant) {
8096f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray    DCHECK(constant != nullptr);
8196f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray    return Location(kConstant | reinterpret_cast<uword>(constant));
8296f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  }
8396f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray
8496f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  HConstant* GetConstant() const {
8596f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray    DCHECK(IsConstant());
8696f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray    return reinterpret_cast<HConstant*>(value_ & ~kLocationTagMask);
8796f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  }
8896f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray
8976716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  bool IsValid() const {
9076716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    return value_ != kInvalid;
9176716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  }
9276716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray
9376716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  bool IsInvalid() const {
9476716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    return !IsValid();
9576716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  }
9676716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray
9776716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  // Empty location. Used if there the location should be ignored.
9876716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  static Location NoLocation() {
9976716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    return Location();
10076716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  }
10176716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray
10276716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  // Register locations.
10376716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  static Location RegisterLocation(ManagedRegister reg) {
10476716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    return Location(kRegister, reg.RegId());
10576716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  }
10676716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray
10776716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  bool IsRegister() const {
10876716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    return GetKind() == kRegister;
10976716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  }
11076716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray
11176716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  ManagedRegister reg() const {
11276716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    DCHECK(IsRegister());
11376716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    return static_cast<ManagedRegister>(GetPayload());
11476716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  }
11576716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray
11676716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  static uword EncodeStackIndex(intptr_t stack_index) {
11776716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    DCHECK(-kStackIndexBias <= stack_index);
11876716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    DCHECK(stack_index < kStackIndexBias);
11976716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    return static_cast<uword>(kStackIndexBias + stack_index);
12076716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  }
12176716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray
12276716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  static Location StackSlot(intptr_t stack_index) {
12376716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    uword payload = EncodeStackIndex(stack_index);
12476716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    Location loc(kStackSlot, payload);
12576716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    // Ensure that sign is preserved.
12676716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    DCHECK_EQ(loc.GetStackIndex(), stack_index);
12776716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    return loc;
12876716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  }
12976716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray
13076716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  bool IsStackSlot() const {
13176716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    return GetKind() == kStackSlot;
13276716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  }
13376716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray
13476716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  static Location DoubleStackSlot(intptr_t stack_index) {
13576716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    uword payload = EncodeStackIndex(stack_index);
13676716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    Location loc(kDoubleStackSlot, payload);
13776716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    // Ensure that sign is preserved.
13876716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    DCHECK_EQ(loc.GetStackIndex(), stack_index);
13976716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    return loc;
14076716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  }
14176716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray
14276716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  bool IsDoubleStackSlot() const {
14376716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    return GetKind() == kDoubleStackSlot;
14476716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  }
14576716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray
14676716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  intptr_t GetStackIndex() const {
14776716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    DCHECK(IsStackSlot() || IsDoubleStackSlot());
14876716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    // Decode stack index manually to preserve sign.
14976716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    return GetPayload() - kStackIndexBias;
15076716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  }
15176716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray
15276716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  intptr_t GetHighStackIndex(uintptr_t word_size) const {
15376716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    DCHECK(IsDoubleStackSlot());
15476716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    // Decode stack index manually to preserve sign.
15576716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    return GetPayload() - kStackIndexBias + word_size;
15676716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  }
15776716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray
15876716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  static Location QuickParameter(uint32_t parameter_index) {
15976716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    return Location(kQuickParameter, parameter_index);
16076716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  }
16176716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray
16276716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  uint32_t GetQuickParameterIndex() const {
16376716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    DCHECK(IsQuickParameter());
16476716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    return GetPayload();
16576716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  }
16676716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray
16776716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  bool IsQuickParameter() const {
16876716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    return GetKind() == kQuickParameter;
16976716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  }
17076716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray
17176716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  arm::ArmManagedRegister AsArm() const;
17276716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  x86::X86ManagedRegister AsX86() const;
1739cf35523764d829ae0470dae2d5dd99be469c841Nicolas Geoffray  x86_64::X86_64ManagedRegister AsX86_64() const;
17476716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray
17576716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  Kind GetKind() const {
17676716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    return KindField::Decode(value_);
17776716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  }
17876716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray
17976716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  bool Equals(Location other) const {
18076716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    return value_ == other.value_;
18176716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  }
18276716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray
18376716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  const char* DebugString() const {
18476716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    switch (GetKind()) {
18596f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray      case kInvalid: return "I";
18676716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray      case kRegister: return "R";
18776716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray      case kStackSlot: return "S";
18876716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray      case kDoubleStackSlot: return "DS";
18976716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray      case kQuickParameter: return "Q";
19076716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray      case kUnallocated: return "U";
19196f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray      case kConstant: return "C";
19276716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    }
19376716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    return "?";
19476716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  }
19576716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray
19676716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  // Unallocated locations.
19776716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  enum Policy {
19876716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    kAny,
19976716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    kRequiresRegister,
20076716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    kSameAsFirstInput,
20176716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  };
20276716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray
20376716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  bool IsUnallocated() const {
20476716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    return GetKind() == kUnallocated;
20576716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  }
20676716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray
20776716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  static Location UnallocatedLocation(Policy policy) {
20876716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    return Location(kUnallocated, PolicyField::Encode(policy));
20976716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  }
21076716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray
21176716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  // Any free register is suitable to replace this unallocated location.
21276716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  static Location Any() {
21376716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    return UnallocatedLocation(kAny);
21476716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  }
21576716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray
21676716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  static Location RequiresRegister() {
21776716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    return UnallocatedLocation(kRequiresRegister);
21876716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  }
21976716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray
22096f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  static Location RegisterOrConstant(HInstruction* instruction);
22196f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray
22276716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  // The location of the first input to the instruction will be
22376716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  // used to replace this unallocated location.
22476716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  static Location SameAsFirstInput() {
22576716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    return UnallocatedLocation(kSameAsFirstInput);
22676716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  }
22776716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray
22876716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  Policy GetPolicy() const {
22976716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    DCHECK(IsUnallocated());
23076716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    return PolicyField::Decode(GetPayload());
23176716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  }
23276716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray
23376716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  uword GetEncoding() const {
23476716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    return GetPayload();
23576716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  }
23676716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray
23776716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray private:
23876716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  // Number of bits required to encode Kind value.
23976716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  static constexpr uint32_t kBitsForKind = 4;
24076716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  static constexpr uint32_t kBitsForPayload = kWordSize * kBitsPerByte - kBitsForKind;
24196f89a290eb67d7bf4b1636798fa28df14309cc7Nicolas Geoffray  static constexpr uword kLocationTagMask = 0x3;
24276716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray
24376716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  explicit Location(uword value) : value_(value) {}
24476716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray
24576716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  Location(Kind kind, uword payload)
24676716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray      : value_(KindField::Encode(kind) | PayloadField::Encode(payload)) {}
24776716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray
24876716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  uword GetPayload() const {
24976716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    return PayloadField::Decode(value_);
25076716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  }
25176716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray
25276716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  typedef BitField<Kind, 0, kBitsForKind> KindField;
25376716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  typedef BitField<uword, kBitsForKind, kBitsForPayload> PayloadField;
25476716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray
25576716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  // Layout for kUnallocated locations payload.
25676716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  typedef BitField<Policy, 0, 3> PolicyField;
25776716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray
25876716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  // Layout for stack slots.
25976716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  static const intptr_t kStackIndexBias =
26076716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray      static_cast<intptr_t>(1) << (kBitsForPayload - 1);
26176716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray
26276716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  // Location either contains kind and payload fields or a tagged handle for
26376716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  // a constant locations. Values of enumeration Kind are selected in such a
26476716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  // way that none of them can be interpreted as a kConstant tag.
26576716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  uword value_;
26676716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray};
26776716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray
26876716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray/**
26976716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray * The code generator computes LocationSummary for each instruction so that
27076716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray * the instruction itself knows what code to generate: where to find the inputs
27176716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray * and where to place the result.
27276716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray *
27376716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray * The intent is to have the code for generating the instruction independent of
27476716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray * register allocation. A register allocator just has to provide a LocationSummary.
27576716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray */
27676716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffrayclass LocationSummary : public ArenaObject {
27776716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray public:
27876716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  explicit LocationSummary(HInstruction* instruction);
27976716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray
28076716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  void SetInAt(uint32_t at, Location location) {
28176716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    inputs_.Put(at, location);
28276716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  }
28376716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray
28476716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  Location InAt(uint32_t at) const {
28576716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    return inputs_.Get(at);
28676716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  }
28776716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray
28876716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  size_t GetInputCount() const {
28976716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    return inputs_.Size();
29076716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  }
29176716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray
29276716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  void SetOut(Location location) {
29376716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    output_ = Location(location);
29476716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  }
29576716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray
29676716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  void AddTemp(Location location) {
29776716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    temps_.Add(location);
29876716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  }
29976716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray
30076716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  Location GetTemp(uint32_t at) const {
30176716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    return temps_.Get(at);
30276716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  }
30376716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray
30476716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  void SetTempAt(uint32_t at, Location location) {
30576716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    temps_.Put(at, location);
30676716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  }
30776716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray
30876716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  size_t GetTempCount() const {
30976716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray    return temps_.Size();
31076716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  }
31176716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray
31276716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  Location Out() const { return output_; }
31376716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray
31476716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray private:
31576716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  GrowableArray<Location> inputs_;
31676716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  GrowableArray<Location> temps_;
31776716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  Location output_;
31876716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray
31976716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray  DISALLOW_COPY_AND_ASSIGN(LocationSummary);
32076716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray};
32176716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray
32276716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray}  // namespace art
32376716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray
32476716a69a0e51b3516227e8b7e365e4b9490618cNicolas Geoffray#endif  // ART_COMPILER_OPTIMIZING_LOCATIONS_H_
325