/*
* Copyright ( C ) 2014 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 "locations.h"
#include <type_traits>
#include "code_generator.h"
#include "nodes.h"
namespace art HIDDEN {
// Verify that Location is trivially copyable.
static_assert(std::is_trivially_copyable<Location>::value, "Location should be trivially copyable" );
ALWAYS_INLINE inline LocationSummary::CallData::CallData(ArenaAllocator* allocator)
: stack_mask(allocator, /*start_bits=*/ 0, /*expandable=*/ true, kArenaAllocLocationSummary),
has_custom_slow_path_calling_convention(false ),
register_mask(0 ),
live_registers(RegisterSet::Empty()),
custom_slow_path_caller_saves(RegisterSet::Empty()) {}
ALWAYS_INLINE inline LocationSummary::LocationSummary(HInstruction* instruction,
CallKind call_kind,
bool intrinsified,
ArenaAllocator* allocator,
size_t input_count)
: temps_(allocator->Adapter(kArenaAllocLocationSummary)),
call_data_(nullptr),
call_kind_(call_kind),
intrinsified_(intrinsified),
output_overlaps_(Location::kOutputOverlap),
input_count_(dchecked_integral_cast<uint32_t>(input_count)) {
instruction->SetLocations(this );
if (CanCall()) {
call_data_ = new (allocator) CallData(allocator);
}
}
LocationSummary* LocationSummary::CreateImpl(ArenaAllocator* allocator,
HInstruction* instruction,
CallKind call_kind,
bool intrinsified,
size_t input_count) {
size_t size = offsetof(LocationSummary, inputs_) + input_count * sizeof (inputs_[0 ]);
void * storage = allocator->Alloc(size, kArenaAllocLocationSummary);
LocationSummary* locations =
new (storage) LocationSummary(instruction, call_kind, intrinsified, allocator, input_count);
// Inputs array is zero-initialized, all entries are invalid.
static_assert(Location::kInvalid == 0 );
DCHECK(std::all_of(locations->Inputs().begin(),
locations->Inputs().end(),
[](Location loc) { return loc.IsInvalid(); }));
return locations;
}
Location Location::RegisterOrConstant(HInstruction* instruction) {
return instruction->IsConstant()
? Location::ConstantLocation(instruction)
: Location::RequiresCoreRegister();
}
Location Location::RegisterOrInt32Constant(HInstruction* instruction) {
HConstant* constant = instruction->AsConstantOrNull();
if (constant != nullptr) {
int64_t value = CodeGenerator::GetInt64ValueOf(constant);
if (IsInt<32 >(value)) {
return Location::ConstantLocation(constant);
}
}
return Location::RequiresCoreRegister();
}
Location Location::FpuRegisterOrInt32Constant(HInstruction* instruction) {
HConstant* constant = instruction->AsConstantOrNull();
if (constant != nullptr) {
int64_t value = CodeGenerator::GetInt64ValueOf(constant);
if (IsInt<32 >(value)) {
return Location::ConstantLocation(constant);
}
}
return Location::RequiresFpuRegister();
}
Location Location::ByteRegisterOrConstant(int reg, HInstruction* instruction) {
return instruction->IsConstant()
? Location::ConstantLocation(instruction)
: Location::CoreRegister(reg);
}
Location Location::FpuRegisterOrConstant(HInstruction* instruction) {
return instruction->IsConstant()
? Location::ConstantLocation(instruction)
: Location::RequiresFpuRegister();
}
void Location::DCheckInstructionIsConstant(HInstruction* instruction) {
DCHECK(instruction != nullptr);
DCHECK(instruction->IsConstant());
DCHECK_EQ(reinterpret_cast <uintptr_t>(instruction),
reinterpret_cast <uintptr_t>(instruction->AsConstant()));
}
std::ostream& operator <<(std::ostream& os, const Location& location) {
os << location.DebugString();
if (location.IsCoreRegister() || location.IsFpuRegister() || location.IsVecRegister()) {
os << location.reg();
} else if (location.IsRegisterPair()) {
os << location.low() << ":" << location.high();
} else if (location.IsStackSlot() || location.IsDoubleStackSlot() || location.IsSIMDStackSlot()) {
os << location.GetStackIndex();
}
return os;
}
} // namespace art
Messung V0.5 in Prozent C=89 H=97 G=93
¤ Dauer der Verarbeitung: 0.11 Sekunden
(vorverarbeitet am 2026-06-29)
¤
*© Formatika GbR, Deutschland