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