Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Public Types | Public Member Functions | List of all members
dart::UnboxIntegerInstr Class Reference

#include <il.h>

Inheritance diagram for dart::UnboxIntegerInstr:
dart::UnboxInstr dart::TemplateDefinition< 1, NoThrow, Pure > dart::UnboxInt64Instr dart::UnboxInteger32Instr dart::UnboxInt32Instr dart::UnboxUint32Instr

Public Types

enum  TruncationMode { kTruncate , kNoTruncation }
 
- Public Types inherited from dart::TemplateDefinition< 1, NoThrow, Pure >
using BaseClass = typename Pure< Definition, PureDefinition >::Base
 

Public Member Functions

 UnboxIntegerInstr (Representation representation, TruncationMode truncation_mode, Value *value, intptr_t deopt_id, SpeculativeMode speculative_mode)
 
bool is_truncating () const
 
void mark_truncating ()
 
virtual bool ComputeCanDeoptimize () const
 
virtual bool AttributesEqual (const Instruction &other) const
 
virtual DefinitionCanonicalize (FlowGraph *flow_graph)
 
virtual void InferRange (RangeAnalysis *analysis, Range *range)
 
- Public Member Functions inherited from dart::UnboxInstr
Valuevalue () const
 
virtual SpeculativeMode SpeculativeModeOfInput (intptr_t index) const
 
virtual Representation representation () const
 
DefinitionCanonicalize (FlowGraph *flow_graph)
 
virtual intptr_t DeoptimizationTarget () const
 
virtual TokenPosition token_pos () const
 
 DECLARE_INSTRUCTION_SERIALIZABLE_FIELDS (UnboxInstr, TemplateDefinition, FIELD_LIST) protected
 
void set_speculative_mode (SpeculativeMode value)
 
- Public Member Functions inherited from dart::TemplateDefinition< 1, NoThrow, Pure >
 TemplateDefinition (intptr_t deopt_id=DeoptId::kNone)
 
 TemplateDefinition (const InstructionSource &source, intptr_t deopt_id=DeoptId::kNone)
 
virtual intptr_t InputCount () const
 
virtual ValueInputAt (intptr_t i) const
 
virtual bool MayThrow () const
 

Additional Inherited Members

- Static Public Member Functions inherited from dart::UnboxInstr
static UnboxInstrCreate (Representation to, Value *value, intptr_t deopt_id, SpeculativeMode speculative_mode=kGuardInputs)
 
- Protected Attributes inherited from dart::TemplateDefinition< 1, NoThrow, Pure >
EmbeddedArray< Value *, Ninputs_
 

Detailed Description

Definition at line 8712 of file il.h.

Member Enumeration Documentation

◆ TruncationMode

Enumerator
kTruncate 
kNoTruncation 

Definition at line 8714 of file il.h.

Constructor & Destructor Documentation

◆ UnboxIntegerInstr()

dart::UnboxIntegerInstr::UnboxIntegerInstr ( Representation  representation,
TruncationMode  truncation_mode,
Value value,
intptr_t  deopt_id,
SpeculativeMode  speculative_mode 
)
inline

Definition at line 8716 of file il.h.

8721 : UnboxInstr(representation, value, deopt_id, speculative_mode),
8722 is_truncating_(truncation_mode == kTruncate) {}
virtual Representation representation() const
Definition il.h:8655
Value * value() const
Definition il.h:8630

Member Function Documentation

◆ AttributesEqual()

virtual bool dart::UnboxIntegerInstr::AttributesEqual ( const Instruction other) const
inlinevirtual

Reimplemented from dart::UnboxInstr.

Definition at line 8730 of file il.h.

8730 {
8731 auto const other_unbox = other.AsUnboxInteger();
8732 return UnboxInstr::AttributesEqual(other) &&
8733 (other_unbox->is_truncating_ == is_truncating_);
8734 }
virtual bool AttributesEqual(const Instruction &other) const
Definition il.h:8659

◆ Canonicalize()

Definition * dart::UnboxIntegerInstr::Canonicalize ( FlowGraph flow_graph)
virtual

Definition at line 3367 of file il.cc.

3367 {
3368 if (!HasUses() && !CanDeoptimize()) return nullptr;
3369
3370 // Fold away Unbox<rep>(v) if v has a target representation already.
3371 Definition* value_defn = value()->definition();
3372 if (value_defn->representation() == representation()) {
3373 return value_defn;
3374 }
3375
3376 // Do not attempt to fold this instruction if we have not matched
3377 // input/output representations yet.
3378 if (HasUnmatchedInputRepresentations()) {
3379 return this;
3380 }
3381
3382 // Fold away UnboxInteger<rep_to>(BoxInteger<rep_from>(v)).
3383 BoxIntegerInstr* box_defn = value()->definition()->AsBoxInteger();
3384 if (box_defn != nullptr && !box_defn->HasUnmatchedInputRepresentations()) {
3385 Representation from_representation =
3386 box_defn->value()->definition()->representation();
3387 if (from_representation == representation()) {
3388 return box_defn->value()->definition();
3389 } else {
3390 // Only operate on explicit unboxed operands.
3391 IntConverterInstr* converter = new IntConverterInstr(
3392 from_representation, representation(),
3393 box_defn->value()->CopyWithType(),
3394 (representation() == kUnboxedInt32) ? GetDeoptId() : DeoptId::kNone);
3395 // TODO(vegorov): marking resulting converter as truncating when
3396 // unboxing can't deoptimize is a workaround for the missing
3397 // deoptimization environment when we insert converter after
3398 // EliminateEnvironments and there is a mismatch between predicates
3399 // UnboxIntConverterInstr::CanDeoptimize and UnboxInt32::CanDeoptimize.
3400 if ((representation() == kUnboxedInt32) &&
3401 (is_truncating() || !CanDeoptimize())) {
3402 converter->mark_truncating();
3403 }
3404 flow_graph->InsertBefore(this, converter, env(), FlowGraph::kValue);
3405 return converter;
3406 }
3407 }
3408
3409 if ((SpeculativeModeOfInput(0) == kGuardInputs) && !ComputeCanDeoptimize()) {
3410 // Remember if we ever learn out input doesn't require checking, as
3411 // the input Value might be later changed that would make us forget.
3412 set_speculative_mode(kNotSpeculative);
3413 }
3414
3415 if (value()->BindsToConstant()) {
3416 const auto& obj = value()->BoundConstant();
3417 if (obj.IsInteger()) {
3418 if (representation() == kUnboxedInt64) {
3419 return flow_graph->GetConstant(obj, representation());
3420 }
3421 const int64_t intval = Integer::Cast(obj).AsInt64Value();
3423 return flow_graph->GetConstant(obj, representation());
3424 }
3425 if (is_truncating()) {
3426 const int64_t result = Evaluator::TruncateTo(intval, representation());
3427 return flow_graph->GetConstant(
3428 Integer::ZoneHandle(flow_graph->zone(),
3430 representation());
3431 }
3432 }
3433 }
3434
3435 return this;
3436}
static int64_t TruncateTo(int64_t v, Representation r)
Definition evaluator.cc:81
virtual Representation representation() const
Definition il.h:1254
static IntegerPtr NewCanonical(const String &str)
Definition object.cc:23078
static Object & ZoneHandle()
Definition object.h:419
void set_speculative_mode(SpeculativeMode value)
Definition il.h:8693
virtual SpeculativeMode SpeculativeModeOfInput(intptr_t index) const
Definition il.h:8651
bool is_truncating() const
Definition il.h:8724
virtual bool ComputeCanDeoptimize() const
Definition il.cc:2031
const Object & BoundConstant() const
Definition il.cc:1199
Definition * definition() const
Definition il.h:103
GAsyncResult * result
static constexpr const char * kNone
Representation
Definition locations.h:66
Definition __init__.py:1
static bool IsRepresentable(Representation rep, int64_t value)
Definition locations.cc:72

◆ ComputeCanDeoptimize()

bool dart::UnboxIntegerInstr::ComputeCanDeoptimize ( ) const
virtual

Reimplemented from dart::UnboxInstr.

Definition at line 2031 of file il.cc.

2031 {
2032 if (SpeculativeModeOfInputs() == kNotSpeculative) {
2033 return false;
2034 }
2035 if (!value()->Type()->IsInt()) {
2036 return true;
2037 }
2038 if (representation() == kUnboxedInt64 || is_truncating()) {
2039 return false;
2040 }
2041 const intptr_t rep_bitsize =
2043 if (value()->Type()->ToCid() == kSmiCid &&
2044 compiler::target::kSmiBits <= rep_bitsize) {
2045 return false;
2046 }
2047 return !RangeUtils::IsWithin(value()->definition()->range(),
2050}
static bool IsWithin(const Range *range, int64_t min, int64_t max)
constexpr intptr_t kBitsPerByte
Definition globals.h:463
static constexpr size_t ValueSize(Representation rep)
Definition locations.h:112
static int64_t MaxValue(Representation rep)
Definition locations.cc:62
static int64_t MinValue(Representation rep)
Definition locations.cc:49

◆ InferRange()

void dart::UnboxIntegerInstr::InferRange ( RangeAnalysis analysis,
Range range 
)
virtual

Definition at line 3075 of file range_analysis.cc.

3075 {
3076 auto* const value_range = value()->Type()->ToCid() == kSmiCid
3077 ? analysis->GetSmiRange(value())
3078 : value()->definition()->range();
3079 const Range to_range = Range::Full(representation());
3080
3081 if (Range::IsUnknown(value_range)) {
3082 *range = to_range;
3083 } else if (value_range->IsWithin(&to_range)) {
3084 *range = *value_range;
3085 } else if (is_truncating()) {
3086 // If truncating, then in most cases any non-representable values means
3087 // no assumption can be made about the truncated value.
3088 *range = to_range;
3089 } else {
3090 // When not truncating, then unboxing deoptimizes if the value is outside
3091 // the range representation.
3092 *range = value_range->Intersect(&to_range);
3093 }
3095}
Range * range() const
Definition il.h:2618
static bool IsUnknown(const Range *other)
static Range Full(RangeBoundary::RangeSize size)
CompileType * Type()
#define ASSERT_VALID_RANGE_FOR_REPRESENTATION(instr, range, representation)

◆ is_truncating()

bool dart::UnboxIntegerInstr::is_truncating ( ) const
inline

Definition at line 8724 of file il.h.

8724{ return is_truncating_; }

◆ mark_truncating()

void dart::UnboxIntegerInstr::mark_truncating ( )
inline

Definition at line 8726 of file il.h.

8726{ is_truncating_ = true; }

The documentation for this class was generated from the following files: