Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
locations.cc
Go to the documentation of this file.
1// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
6#include <limits>
7
8#include "vm/class_id.h"
11#include "vm/log.h"
12#include "vm/stack_frame.h"
13
14namespace dart {
15
17 if (rep == kTagged) return compiler::kObjectBytes;
18
19 // Untagged addresses are either loaded from and stored to word size native
20 // fields or generated from already-extended tagged addresses when
21 // compressed pointers are enabled.
22 if (rep == kUntagged) return compiler::kWordBytes;
23
24 if (IsUnboxedInteger(rep)) {
25 switch (ValueSize(rep)) {
26 case 8:
28 ASSERT_EQUAL(compiler::target::kWordSize, 8);
30 case 4:
33 case 2:
36 case 1:
39 }
40 }
41
44}
45
46#define REP_MIN_VALUE_CLAUSE(name, ___, ____, type) \
47 case k##name: \
48 return static_cast<int64_t>(std::numeric_limits<type>::min());
57#undef REP_MIN_VALUE_CLAUSE
58
59#define REP_MAX_VALUE_CLAUSE(name, ___, ____, type) \
60 case k##name: \
61 return static_cast<int64_t>(std::numeric_limits<type>::max());
70#undef REP_MAX_VALUE_CLAUSE
71
74 const intptr_t bit_size = ValueSize(rep) * kBitsPerByte;
75 return IsUnsignedInteger(rep) ? Utils::IsUint(bit_size, value)
76 : Utils::IsInt(bit_size, value);
77}
78
80 classid_t cid) {
82 // Normalize typed data cids to the internal cid for the switch statement.
85 }
86 switch (cid) {
87#define ARRAY_CASE(Name) case k##Name##Cid:
89#undef ARRAY_CASE
90 case kRecordCid:
91 case kTypeArgumentsCid:
92 return kTagged;
93 case kTypedDataInt8ArrayCid:
94 return kUnboxedInt8;
95 case kOneByteStringCid:
96 case kTypedDataUint8ArrayCid:
97 case kTypedDataUint8ClampedArrayCid:
98 case kExternalTypedDataUint8ArrayCid:
99 case kExternalTypedDataUint8ClampedArrayCid:
100 return kUnboxedUint8;
101 case kTypedDataInt16ArrayCid:
102 return kUnboxedInt16;
103 case kTwoByteStringCid:
104 case kTypedDataUint16ArrayCid:
105 return kUnboxedUint16;
106 case kTypedDataInt32ArrayCid:
107 return kUnboxedInt32;
108 case kTypedDataUint32ArrayCid:
109 return kUnboxedUint32;
110 case kTypedDataInt64ArrayCid:
111 case kTypedDataUint64ArrayCid:
112 return kUnboxedInt64;
113 case kTypedDataFloat32ArrayCid:
114 return kUnboxedFloat;
115 case kTypedDataFloat64ArrayCid:
116 return kUnboxedDouble;
117 case kTypedDataInt32x4ArrayCid:
118 return kUnboxedInt32x4;
119 case kTypedDataFloat32x4ArrayCid:
120 return kUnboxedFloat32x4;
121 case kTypedDataFloat64x2ArrayCid:
122 return kUnboxedFloat64x2;
123 default:
124 FATAL("Unexpected array cid %u", cid);
125 return kTagged;
126 }
127}
128
130 switch (repr) {
131#define REPR_CASE(Name, PrintName, __, ___) \
132 case k##Name: \
133 return #PrintName;
135#undef KIND_CASE
136 default:
137 UNREACHABLE();
138 }
139 return nullptr;
140}
141
142intptr_t RegisterSet::RegisterCount(intptr_t registers) {
143 // Brian Kernighan's algorithm for counting the bits set.
144 intptr_t count = 0;
145 while (registers != 0) {
146 ++count;
147 // Clear the least significant bit set.
148 registers &= (static_cast<uintptr_t>(registers) - 1);
149 }
150 return count;
151}
152
154 for (intptr_t i = 0; i < kNumberOfCpuRegisters; i++) {
155 Register r = static_cast<Register>(i);
156 if (ContainsRegister(r)) {
158 IsTagged(r) ? "tagged" : "untagged");
159 }
160 }
161
162 for (intptr_t i = 0; i < kNumberOfFpuRegisters; i++) {
163 FpuRegister r = static_cast<FpuRegister>(i);
164 if (ContainsFpuRegister(r)) {
166 }
167 }
168}
169
171 intptr_t input_count,
172 intptr_t temp_count,
173 LocationSummary::ContainsCall contains_call)
174 : num_inputs_(input_count),
175 num_temps_(temp_count),
176 output_location_(), // out(0)->IsInvalid() unless later set.
177 stack_bitmap_(nullptr),
178 contains_call_(contains_call),
179 live_registers_() {
180#if defined(DEBUG)
181 writable_inputs_ = 0;
182#endif
183 input_locations_ = zone->Alloc<Location>(num_inputs_);
184 temp_locations_ = zone->Alloc<Location>(num_temps_);
185}
186
188 Zone* zone,
189 intptr_t input_count,
190 Location out,
191 LocationSummary::ContainsCall contains_call) {
192 LocationSummary* summary =
193 new (zone) LocationSummary(zone, input_count, 0, contains_call);
194 for (intptr_t i = 0; i < input_count; i++) {
195 summary->set_in(i, Location::RequiresRegister());
196 }
197 summary->set_out(0, out);
198 return summary;
199}
200
201static bool ValidOutputForAlwaysCalls(const Location& loc) {
202 return loc.IsMachineRegister() || loc.IsInvalid() || loc.IsPairLocation();
203}
204
205void LocationSummary::set_in(intptr_t index, Location loc) {
206 ASSERT(index >= 0);
207 ASSERT(index < num_inputs_);
208#if defined(DEBUG)
209 // See FlowGraphAllocator::ProcessOneInstruction for explanation of these
210 // restrictions.
211 if (always_calls()) {
212 if (loc.IsUnallocated()) {
213 ASSERT(loc.policy() == Location::kAny ||
215 } else if (loc.IsPairLocation()) {
216 ASSERT(!loc.AsPairLocation()->At(0).IsUnallocated() ||
217 loc.AsPairLocation()->At(0).policy() == Location::kAny ||
219 ASSERT(!loc.AsPairLocation()->At(1).IsUnallocated() ||
220 loc.AsPairLocation()->At(1).policy() == Location::kAny ||
222 }
223 if (index == 0 && out(0).IsUnallocated() &&
224 out(0).policy() == Location::kSameAsFirstInput) {
226 }
227 }
228#endif
229 input_locations_[index] = loc;
230}
231
232void LocationSummary::set_out(intptr_t index, Location loc) {
233 ASSERT(index == 0);
236 num_inputs_ > 0 && ValidOutputForAlwaysCalls(in(0))));
237 output_location_ = loc;
238}
239
240Location Location::ToSpRelative(intptr_t fp_to_sp_delta) const {
241 if (IsPairLocation()) {
242 auto pair = AsPairLocation();
243 return Pair(pair->At(0).ToSpRelative(fp_to_sp_delta),
244 pair->At(1).ToSpRelative(fp_to_sp_delta));
245 }
246
247 if (HasStackIndex()) {
248 ASSERT(base_reg() == FPREG);
251 EncodeStackIndex(stack_index() - fp_to_sp_delta));
252 return Location(kind(), payload);
253 }
254
255 return *this;
256}
257
259 const auto fp_to_entry_sp_delta =
260 (compiler::target::frame_layout.param_end_from_fp + 1) -
261 compiler::target::frame_layout.last_param_from_entry_sp;
262 return ToSpRelative(fp_to_entry_sp_delta);
263}
264
266 const auto fp_to_caller_sp_delta =
267 (compiler::target::frame_layout.param_end_from_fp + 1);
268 return ToSpRelative(fp_to_caller_sp_delta);
269}
270
272 PairLocation* pair_location = new PairLocation();
273 ASSERT((reinterpret_cast<intptr_t>(pair_location) & kLocationTagMask) == 0);
274 pair_location->SetAt(0, first);
275 pair_location->SetAt(1, second);
276 Location loc(reinterpret_cast<uword>(pair_location) | kPairLocationTag);
277 return loc;
278}
279
282 return reinterpret_cast<PairLocation*>(value_ & ~kLocationTagMask);
283}
284
285Location Location::Component(intptr_t i) const {
286 return AsPairLocation()->At(i);
287}
288
290 ConstantInstr* constant = value->definition()->AsConstant();
291 return ((constant != nullptr) &&
293 ? Location::Constant(constant)
295}
296
298 intptr_t min_value,
299 intptr_t max_value) {
300 ConstantInstr* constant = value->definition()->AsConstant();
301 if (constant == nullptr) {
303 }
304 if (!compiler::Assembler::IsSafeSmi(constant->value())) {
306 }
307 const intptr_t smi_value = value->BoundSmiConstant();
308 if (smi_value < min_value || smi_value > max_value) {
310 }
311 return Location::Constant(constant);
312}
313
315 ConstantInstr* constant = value->definition()->AsConstant();
316 return ((constant != nullptr) &&
318 ? Location::Constant(constant)
320}
321
323 intptr_t min_value,
324 intptr_t max_value) {
325 ConstantInstr* constant = value->definition()->AsConstant();
326 if (constant == nullptr) {
328 }
329 if (!compiler::Assembler::IsSafeSmi(constant->value())) {
331 }
332 const intptr_t smi_value = value->BoundSmiConstant();
333 if (smi_value < min_value || smi_value > max_value) {
335 }
336 return Location::Constant(constant);
337}
338
340 ASSERT(((1 << reg) & kDartAvailableCpuRegs) != 0);
341 ConstantInstr* constant = value->definition()->AsConstant();
342 return ((constant != nullptr) &&
344 ? Location::Constant(constant)
346}
347
349 ASSERT(((1 << reg) & kDartAvailableCpuRegs) != 0);
350 ConstantInstr* constant = value->definition()->AsConstant();
351 return ((constant != nullptr) &&
353 ? Location::Constant(constant)
355}
356
358 ConstantInstr* constant = value->definition()->AsConstant();
359 return ((constant != nullptr) &&
361 ? Location::Constant(constant)
362 : Location::Any();
363}
364
368
370 return stack_index() * compiler::target::kWordSize;
371}
372
374 return constant_instruction()->value();
375}
376
377const char* Location::Name() const {
378 switch (kind()) {
379 case kInvalid:
380 return "?";
381 case kRegister:
383 case kFpuRegister:
385 case kStackSlot:
386 return "S";
387 case kDoubleStackSlot:
388 return "DS";
389 case kQuadStackSlot:
390 return "QS";
391 case kUnallocated:
392 switch (policy()) {
393 case kAny:
394 return "A";
395 case kPrefersRegister:
396 return "P";
398 return "R";
400 return "DR";
402 return "WR";
404 return "0";
405 case kRequiresStack:
406 return "RS";
407 }
408 UNREACHABLE();
409 default:
410 if (IsConstant()) {
411 return "C";
412 } else {
414 return "2P";
415 }
416 }
417 return "?";
418}
419
422 return;
423 }
424 if (kind() == kStackSlot || kind() == kDoubleStackSlot ||
425 kind() == kQuadStackSlot) {
426 const char* suffix = "";
427 if (kind() == kDoubleStackSlot) {
428 suffix = " f64";
429 } else if (kind() == kQuadStackSlot) {
430 suffix = " f128";
431 }
432 f->Printf("%s[%" Pd "]%s", base_reg() == FPREG ? "fp" : "sp", stack_index(),
433 suffix);
434 } else if (IsPairLocation()) {
435 f->AddString("(");
436 AsPairLocation()->At(0).PrintTo(f);
437 f->AddString(", ");
438 AsPairLocation()->At(1).PrintTo(f);
439 f->AddString(")");
440 } else {
441 f->Printf("%s", Name());
442 }
443}
444
445const char* Location::ToCString() const {
446 char buffer[1024];
447 BufferFormatter bf(buffer, 1024);
448 PrintTo(&bf);
450}
451
452void Location::Print() const {
453 if (kind() == kStackSlot || kind() == kDoubleStackSlot ||
454 kind() == kQuadStackSlot) {
455 const char* suffix = "";
456 if (kind() == kDoubleStackSlot) {
457 suffix = " f64";
458 } else if (kind() == kQuadStackSlot) {
459 suffix = " f128";
460 }
461 THR_Print("%s[%" Pd "] %s", base_reg() == FPREG ? "fp" : "sp",
462 stack_index(), suffix);
463 } else {
464 THR_Print("%s", Name());
465 }
466}
467
469 if (IsPairLocation()) {
471 ASSERT(!pair->At(0).IsPairLocation());
472 ASSERT(!pair->At(1).IsPairLocation());
473 return Location::Pair(pair->At(0).Copy(), pair->At(1).Copy());
474 } else {
475 // Copy by value.
476 return *this;
477 }
478}
479
483
487
491
493 Definition* def,
494 intptr_t* cpu_reg_slots,
495 intptr_t* fpu_reg_slots) {
496 if (loc.IsRegister()) {
497 intptr_t index = cpu_reg_slots[loc.reg()];
498 ASSERT(index >= 0);
499 return Location::StackSlot(
500 compiler::target::frame_layout.FrameSlotForVariableIndex(-index),
501 FPREG);
502 } else if (loc.IsFpuRegister()) {
503 intptr_t index = fpu_reg_slots[loc.fpu_reg()];
504 ASSERT(index >= 0);
505 switch (def->representation()) {
506 case kUnboxedDouble: // SlowPathEnvironmentFor sees _one_ register
507 case kUnboxedFloat: // both for doubles and floats.
509 compiler::target::frame_layout.FrameSlotForVariableIndex(-index),
510 FPREG);
511
512 case kUnboxedFloat32x4:
513 case kUnboxedInt32x4:
514 case kUnboxedFloat64x2:
516 compiler::target::frame_layout.FrameSlotForVariableIndex(-index),
517 FPREG);
518
519 default:
520 UNREACHABLE();
521 }
522 } else if (loc.IsPairLocation()) {
523 ASSERT(def->representation() == kUnboxedInt64);
524 PairLocation* value_pair = loc.AsPairLocation();
525 intptr_t index_lo;
526 intptr_t index_hi;
527
528 if (value_pair->At(0).IsRegister()) {
529 index_lo = compiler::target::frame_layout.FrameSlotForVariableIndex(
530 -cpu_reg_slots[value_pair->At(0).reg()]);
531 } else {
532 ASSERT(value_pair->At(0).IsStackSlot());
533 index_lo = value_pair->At(0).stack_index();
534 }
535
536 if (value_pair->At(1).IsRegister()) {
537 index_hi = compiler::target::frame_layout.FrameSlotForVariableIndex(
538 -cpu_reg_slots[value_pair->At(1).reg()]);
539 } else {
540 ASSERT(value_pair->At(1).IsStackSlot());
541 index_hi = value_pair->At(1).stack_index();
542 }
543
544 return Location::Pair(Location::StackSlot(index_lo, FPREG),
545 Location::StackSlot(index_hi, FPREG));
546 } else if (loc.IsInvalid() && def->IsMaterializeObject()) {
547 def->AsMaterializeObject()->RemapRegisters(cpu_reg_slots, fpu_reg_slots);
548 return loc;
549 }
550
551 return loc;
552}
553
556 return;
557 }
558 if (input_count() > 0) {
559 f->AddString(" (");
560 for (intptr_t i = 0; i < input_count(); i++) {
561 if (i != 0) f->AddString(", ");
562 in(i).PrintTo(f);
563 }
564 f->AddString(")");
565 }
566
567 if (temp_count() > 0) {
568 f->AddString(" [");
569 for (intptr_t i = 0; i < temp_count(); i++) {
570 if (i != 0) f->AddString(", ");
571 temp(i).PrintTo(f);
572 }
573 f->AddString("]");
574 }
575
576 if (!out(0).IsInvalid()) {
577 f->AddString(" => ");
578 out(0).PrintTo(f);
579 }
580
581 if (always_calls()) f->AddString(" C");
582}
583
584#if defined(DEBUG)
585void LocationSummary::DiscoverWritableInputs() {
586 if (!HasCallOnSlowPath()) {
587 return;
588 }
589
590 for (intptr_t i = 0; i < input_count(); i++) {
591 if (in(i).IsUnallocated() &&
592 (in(i).policy() == Location::kWritableRegister)) {
593 writable_inputs_ |= 1 << i;
594 }
595 }
596}
597
598void LocationSummary::CheckWritableInputs() {
600 for (intptr_t i = 0; i < input_count(); i++) {
601 if ((writable_inputs_ & (1 << i)) != 0) {
602 // Writable registers have to be manually preserved because
603 // with the right representation because register allocator does not know
604 // how they are used within the instruction template.
605 ASSERT(in(i).IsMachineRegister());
607 }
608 }
609}
610#endif
611
612} // namespace dart
int count
#define UNREACHABLE()
Definition assert.h:248
#define ASSERT_EQUAL(expected, actual)
Definition assert.h:309
#define CLASS_LIST_ARRAYS(V)
Definition class_id.h:128
static constexpr uword encode(Register value)
Definition bitfield.h:167
const Object & value() const
Definition il.h:4212
virtual Representation representation() const
Definition il.h:1254
Location temp(intptr_t index) const
Definition locations.h:882
Location out(intptr_t index) const
Definition locations.h:903
LocationSummary(Zone *zone, intptr_t input_count, intptr_t temp_count, LocationSummary::ContainsCall contains_call)
Definition locations.cc:170
static LocationSummary * Make(Zone *zone, intptr_t input_count, Location out, ContainsCall contains_call)
Definition locations.cc:187
intptr_t input_count() const
Definition locations.h:864
intptr_t temp_count() const
Definition locations.h:880
RegisterSet * live_registers()
Definition locations.h:941
void set_out(intptr_t index, Location loc)
Definition locations.cc:232
bool always_calls() const
Definition locations.h:918
Location in(intptr_t index) const
Definition locations.h:866
void set_in(intptr_t index, Location loc)
Definition locations.cc:205
void PrintTo(BaseTextBuffer *f) const
Definition locations.cc:554
static Location StackSlot(intptr_t stack_index, Register base)
Definition locations.h:447
bool IsInvalid() const
Definition locations.h:289
void Print() const
Definition locations.cc:452
Location ToCallerSpRelative() const
Definition locations.cc:265
static Location QuadStackSlot(intptr_t stack_index, Register base)
Definition locations.h:469
const char * Name() const
Definition locations.cc:377
bool IsFpuRegister() const
Definition locations.h:414
ConstantInstr * constant_instruction() const
Definition locations.h:309
bool IsRegister() const
Definition locations.h:402
static Location Pair(Location first, Location second)
Definition locations.cc:271
intptr_t ToStackSlotOffset() const
Definition locations.cc:369
Location ToEntrySpRelative() const
Definition locations.cc:258
Register reg() const
Definition locations.h:404
const char * ToCString() const
Definition locations.cc:445
static Location DoubleStackSlot(intptr_t stack_index, Register base)
Definition locations.h:458
static uword EncodeStackIndex(intptr_t stack_index)
Definition locations.h:441
intptr_t stack_index() const
Definition locations.h:485
Policy policy() const
Definition locations.h:389
Location Copy() const
Definition locations.cc:468
Location Component(intptr_t i) const
Definition locations.cc:285
static Location WritableRegister()
Definition locations.h:376
Kind kind() const
Definition locations.h:523
bool IsConstant() const
Definition locations.h:292
Register base_reg() const
Definition locations.h:480
static Location RegisterLocation(Register reg)
Definition locations.h:398
static Location Any()
Definition locations.h:352
PairLocation * AsPairLocation() const
Definition locations.cc:280
static Location RequiresRegister()
Definition locations.h:365
bool IsPairLocation() const
Definition locations.h:316
void PrintTo(BaseTextBuffer *f) const
Definition locations.cc:420
bool IsUnallocated() const
Definition locations.h:341
bool IsMachineRegister() const
Definition locations.h:434
bool IsStackSlot() const
Definition locations.h:456
FpuRegister fpu_reg() const
Definition locations.h:416
const Object & constant() const
Definition locations.cc:373
Location ToSpRelative(intptr_t fp_to_sp_delta) const
Definition locations.cc:240
bool HasStackIndex() const
Definition locations.h:491
static Location Constant(const ConstantInstr *obj, int pair_index=0)
Definition locations.h:294
void SetAt(intptr_t i, Location loc)
Definition locations.h:624
Location At(intptr_t i) const
Definition locations.h:618
static const char * FpuRegisterName(FpuRegister reg)
Definition constants.h:54
static const char * RegisterName(Register reg)
Definition constants.h:46
bool ContainsFpuRegister(FpuRegister fpu_reg) const
Definition locations.h:804
static intptr_t RegisterCount(intptr_t registers)
Definition locations.cc:142
bool ContainsRegister(Register reg) const
Definition locations.h:800
bool IsTagged(Register reg) const
Definition locations.h:796
Zone * zone() const
static Thread * Current()
Definition thread.h:361
static bool IsInt(intptr_t N, T value)
Definition utils.h:298
static bool IsUint(intptr_t N, T value)
Definition utils.h:313
char * MakeCopyOfString(const char *str)
Definition zone.cc:270
ElementType * Alloc(intptr_t length)
static bool IsSafeSmi(const Object &object)
static bool IsSafe(const Object &object)
#define THR_Print(format,...)
Definition log.h:20
#define ASSERT(E)
#define FATAL(error)
static const uint8_t buffer[]
uint8_t value
constexpr bool FLAG_support_il_printer
Definition flag_list.h:48
#define REP_MIN_VALUE_CLAUSE(name, ___, ____, type)
Definition locations.cc:46
#define REPR_CASE(Name, PrintName, __, ___)
#define REP_MAX_VALUE_CLAUSE(name, ___, ____, type)
Definition locations.cc:59
#define ARRAY_CASE(Name)
#define FOR_EACH_REPRESENTATION_KIND(M)
Definition locations.h:61
#define FOR_EACH_INTEGER_REPRESENTATION_KIND(M)
Definition locations.h:31
bool Contains(const Container &container, const Value &value)
constexpr OperandSize kWordBytes
constexpr int64_t kMaxInt64
Definition globals.h:486
const int kNumTypedDataCidRemainders
Definition class_id.h:265
constexpr int64_t kMinInt64
Definition globals.h:485
Location LocationAnyOrConstant(Value *value)
Definition locations.cc:357
Location LocationRegisterOrConstant(Value *value)
Definition locations.cc:289
bool IsTypedDataBaseClassId(intptr_t index)
Definition class_id.h:429
const Register kExceptionObjectReg
const int kTypedDataCidRemainderInternal
Definition class_id.h:261
Location LocationExceptionLocation()
Definition locations.cc:484
int32_t classid_t
Definition globals.h:524
Representation
Definition locations.h:66
constexpr intptr_t kBitsPerByte
Definition globals.h:463
uintptr_t uword
Definition globals.h:501
const Register ARGS_DESC_REG
@ kNumberOfCpuRegisters
Location LocationFixedRegisterOrConstant(Value *value, Register reg)
Definition locations.cc:339
const int kNumberOfFpuRegisters
Location LocationWritableRegisterOrSmiConstant(Value *value, intptr_t min_value, intptr_t max_value)
Definition locations.cc:322
Location LocationArgumentsDescriptorLocation()
Definition locations.cc:480
Location LocationRemapForSlowPath(Location loc, Definition *def, intptr_t *cpu_reg_slots, intptr_t *fpu_reg_slots)
Definition locations.cc:492
static const ClassId kFirstTypedDataCid
Definition class_id.h:377
constexpr RegList kDartAvailableCpuRegs
const Register FPREG
const intptr_t cid
compiler::Address LocationToStackSlotAddress(Location loc)
Definition locations.cc:365
Location LocationStackTraceLocation()
Definition locations.cc:488
Location LocationWritableRegisterOrConstant(Value *value)
Definition locations.cc:314
const Register kStackTraceObjectReg
Location LocationFixedRegisterOrSmiConstant(Value *value, Register reg)
Definition locations.cc:348
Location LocationRegisterOrSmiConstant(Value *value, intptr_t min_value, intptr_t max_value)
Definition locations.cc:297
static bool ValidOutputForAlwaysCalls(const Location &loc)
Definition locations.cc:201
const Register SPREG
#define Pd
Definition globals.h:408
static constexpr size_t ValueSize(Representation rep)
Definition locations.h:112
static constexpr bool IsUnboxedInteger(Representation rep)
Definition locations.h:92
static bool IsRepresentable(Representation rep, int64_t value)
Definition locations.cc:72
static int64_t MaxValue(Representation rep)
Definition locations.cc:62
static compiler::OperandSize OperandSize(Representation rep)
Definition locations.cc:16
static int64_t MinValue(Representation rep)
Definition locations.cc:49
static const char * ToCString(Representation rep)
Definition locations.cc:129
static bool IsUnsignedInteger(Representation rep)
Definition locations.h:126
static Representation RepresentationOfArrayElement(classid_t cid)
Definition locations.cc:79