Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(231)

Unified Diff: runtime/vm/intermediate_language.h

Issue 504143003: Support Int32 representation for selected binary operations. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: runtime/vm/intermediate_language.h
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h
index 61ed474da6b8b3409762ef04b32d86d5f80b420a..52f2c53ee47e7566bdde53aa5401f3323b96ff89 100644
--- a/runtime/vm/intermediate_language.h
+++ b/runtime/vm/intermediate_language.h
@@ -20,6 +20,7 @@ DECLARE_FLAG(bool, throw_on_javascript_int_overflow);
class BitVector;
class BlockEntryInstr;
+class BoxIntNInstr;
class BufferFormatter;
class CatchBlockEntryInstr;
class ComparisonInstr;
@@ -35,6 +36,7 @@ class ParsedFunction;
class Range;
class RangeAnalysis;
class RangeBoundary;
+class UnboxIntNInstr;
// CompileType describes type of the value produced by the definition.
//
@@ -468,10 +470,12 @@ class EmbeddedArray<T, 0> {
M(AllocateUninitializedContext) \
M(CloneContext) \
M(BinarySmiOp) \
+ M(BinaryInt32Op) \
M(UnarySmiOp) \
M(UnaryDoubleOp) \
M(CheckStackOverflow) \
M(SmiToDouble) \
+ M(Int32ToDouble) \
M(DoubleToInteger) \
M(DoubleToSmi) \
M(DoubleToDouble) \
@@ -549,6 +553,8 @@ class EmbeddedArray<T, 0> {
M(UnaryUint32Op) \
M(BoxUint32) \
M(UnboxUint32) \
+ M(BoxInt32) \
+ M(UnboxInt32) \
M(UnboxedIntConverter) \
@@ -603,6 +609,9 @@ class Instruction : public ZoneAllocated {
bool IsDefinition() { return (AsDefinition() != NULL); }
virtual Definition* AsDefinition() { return NULL; }
+ virtual BoxIntNInstr* AsBoxIntN() { return NULL; }
+ virtual UnboxIntNInstr* AsUnboxIntN() { return NULL; }
+
virtual intptr_t token_pos() const { return Scanner::kNoSourcePos; }
virtual intptr_t InputCount() const = 0;
@@ -898,7 +907,11 @@ FOR_EACH_INSTRUCTION(INSTRUCTION_TYPE_CHECK)
friend class BinaryUint32OpInstr;
friend class UnaryUint32OpInstr;
friend class ShiftUint32OpInstr;
+ friend class UnboxIntNInstr;
+ friend class UnboxInt32Instr;
friend class UnboxUint32Instr;
+ friend class BinaryInt32OpInstr;
+ friend class UnboxedIntConverterInstr;
virtual void RawSetInputAt(intptr_t i, Value* value) = 0;
@@ -1627,6 +1640,13 @@ class Definition : public Instruction {
IsUnboxInteger();
}
+ bool IsInt32Definition() {
+ return IsBinaryInt32Op() ||
+ IsBoxInt32() ||
+ IsUnboxInt32() ||
+ IsUnboxedIntConverter();
+ }
+
// Compute compile type for this definition. It is safe to use this
// approximation even before type propagator was run (e.g. during graph
// building).
@@ -1657,6 +1677,8 @@ class Definition : public Instruction {
return (input_use_list_ != NULL) || (env_use_list_ != NULL);
}
bool HasOnlyUse(Value* use) const;
+ bool HasOnlyInputUse(Value* use) const;
+
Value* input_use_list() const { return input_use_list_; }
void set_input_use_list(Value* head) { input_use_list_ = head; }
@@ -2415,10 +2437,11 @@ class ConstantInstr : public TemplateDefinition<0> {
// for other unboxing instructions.
class UnboxedConstantInstr : public ConstantInstr {
public:
- explicit UnboxedConstantInstr(const Object& value);
+ explicit UnboxedConstantInstr(const Object& value,
+ Representation representation);
virtual Representation representation() const {
- return kUnboxedDouble;
+ return representation_;
}
// Either NULL or the address of the unboxed constant.
@@ -2427,6 +2450,7 @@ class UnboxedConstantInstr : public ConstantInstr {
DECLARE_INSTRUCTION(UnboxedConstant)
private:
+ const Representation representation_;
uword constant_address_; // Either NULL or points to the untagged constant.
DISALLOW_COPY_AND_ASSIGN(UnboxedConstantInstr);
@@ -4665,6 +4689,8 @@ class BoxIntegerInstr : public TemplateDefinition<1> {
virtual bool MayThrow() const { return false; }
+ virtual Definition* Canonicalize(FlowGraph* flow_graph);
+
private:
bool is_smi_;
@@ -4841,6 +4867,8 @@ class UnboxIntegerInstr : public TemplateDefinition<1> {
virtual bool MayThrow() const { return false; }
+ virtual Definition* Canonicalize(FlowGraph* flow_graph);
+
private:
DISALLOW_COPY_AND_ASSIGN(UnboxIntegerInstr);
};
@@ -6876,6 +6904,12 @@ class BinarySmiOpInstr : public TemplateDefinition<2> {
virtual bool MayThrow() const { return false; }
+ virtual intptr_t DeoptimizationTarget() const {
+ // Direct access since this instruction cannot deoptimize, and the deopt-id
+ // was inherited from another instruction that could deoptimize.
+ return deopt_id_;
+ }
+
private:
const Token::Kind op_kind_;
bool overflow_;
@@ -6886,6 +6920,97 @@ class BinarySmiOpInstr : public TemplateDefinition<2> {
};
+class BinaryInt32OpInstr : public TemplateDefinition<2> {
+ public:
+ BinaryInt32OpInstr(Token::Kind op_kind,
+ Value* left,
+ Value* right,
+ intptr_t deopt_id)
+ : op_kind_(op_kind),
+ overflow_(true),
+ is_truncating_(false) {
+ SetInputAt(0, left);
+ SetInputAt(1, right);
+ // Override generated deopt-id.
+ deopt_id_ = deopt_id;
+ }
+
+ static bool IsSupported(Token::Kind op, Value* left, Value* right) {
+#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_ARM)
srdjan 2014/08/27 16:17:13 You could move this into intermediate_language_xxx
Vyacheslav Egorov (Google) 2014/08/28 20:48:37 Agreed. However I did not for two reasons: 1) Thi
+ switch (op) {
+ case Token::kADD:
+ case Token::kSUB:
+ case Token::kMUL:
+ case Token::kBIT_AND:
+ case Token::kBIT_OR:
+ case Token::kBIT_XOR:
+ return true;
+
+ case Token::kSHL:
+ case Token::kSHR:
+ return right->BindsToConstant();
+
+ default:
+ return false;
+ }
+#else
+ return false;
+#endif
+ }
+
+ Value* left() const { return inputs_[0]; }
+ Value* right() const { return inputs_[1]; }
+
+ Token::Kind op_kind() const { return op_kind_; }
+
+ void set_overflow(bool overflow) { overflow_ = overflow; }
+
+ void set_is_truncating(bool value) { is_truncating_ = value; }
+ bool IsTruncating() const { return is_truncating_ || !overflow_; }
+
+ void PrintTo(BufferFormatter* f) const;
+ virtual void PrintOperandsTo(BufferFormatter* f) const;
+
+ DECLARE_INSTRUCTION(BinaryInt32Op)
+ virtual CompileType ComputeType() const;
+
+ virtual bool CanDeoptimize() const;
+
+ virtual bool AllowsCSE() const { return true; }
+ virtual EffectSet Effects() const { return EffectSet::None(); }
+ virtual EffectSet Dependencies() const { return EffectSet::None(); }
+ virtual bool AttributesEqual(Instruction* other) const;
+
+ virtual void InferRange(RangeAnalysis* analysis, Range* range);
+
+ virtual Definition* Canonicalize(FlowGraph* flow_graph);
+
+ virtual Representation representation() const {
+ return kUnboxedInt32;
+ }
+
+ virtual Representation RequiredInputRepresentation(intptr_t idx) const {
+ ASSERT(idx == 0 || idx == 1);
srdjan 2014/08/27 16:17:13 parentheses
Vyacheslav Egorov (Google) 2014/08/28 20:48:37 Done.
+ return kUnboxedInt32;
+ }
+
+ virtual intptr_t DeoptimizationTarget() const {
+ // Direct access since this instruction cannot deoptimize, and the deopt-id
+ // was inherited from another instruction that could deoptimize.
+ return deopt_id_;
+ }
+
+ virtual bool MayThrow() const { return false; }
+
+ private:
+ const Token::Kind op_kind_;
+ bool overflow_;
+ bool is_truncating_;
+
+ DISALLOW_COPY_AND_ASSIGN(BinaryInt32OpInstr);
+};
+
+
// Handles both Smi operations: BIT_OR and NEGATE.
class UnarySmiOpInstr : public TemplateDefinition<1> {
public:
@@ -7006,6 +7131,7 @@ class CheckStackOverflowInstr : public TemplateInstruction<0> {
};
+// TODO(vegorov): remove this instruction in favor of Int32ToDouble.
class SmiToDoubleInstr : public TemplateDefinition<1> {
public:
SmiToDoubleInstr(Value* value, intptr_t token_pos)
@@ -7041,6 +7167,40 @@ class SmiToDoubleInstr : public TemplateDefinition<1> {
};
+class Int32ToDoubleInstr : public TemplateDefinition<1> {
+ public:
+ explicit Int32ToDoubleInstr(Value* value) {
+ SetInputAt(0, value);
+ }
+
+ Value* value() const { return inputs_[0]; }
+
+ DECLARE_INSTRUCTION(Int32ToDouble)
+ virtual CompileType ComputeType() const;
+
+ virtual Representation RequiredInputRepresentation(intptr_t index) const {
+ ASSERT(index == 0);
+ return kUnboxedInt32;
+ }
+
+ virtual Representation representation() const {
+ return kUnboxedDouble;
+ }
+
+ virtual bool CanDeoptimize() const { return false; }
+
+ virtual bool AllowsCSE() const { return true; }
+ virtual EffectSet Effects() const { return EffectSet::None(); }
+ virtual EffectSet Dependencies() const { return EffectSet::None(); }
+ virtual bool AttributesEqual(Instruction* other) const { return true; }
+
+ virtual bool MayThrow() const { return false; }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(Int32ToDoubleInstr);
+};
+
+
class DoubleToIntegerInstr : public TemplateDefinition<1> {
public:
DoubleToIntegerInstr(Value* value, InstanceCallInstr* instance_call)
@@ -7800,13 +7960,18 @@ class UnaryUint32OpInstr : public TemplateDefinition<1> {
};
-class BoxUint32Instr : public TemplateDefinition<1> {
+class BoxIntNInstr : public TemplateDefinition<1> {
public:
- explicit BoxUint32Instr(Value* value) {
+ BoxIntNInstr(Representation representation, Value* value)
+ : representation_(representation) {
SetInputAt(0, value);
}
Value* value() const { return inputs_[0]; }
+ virtual bool ValueFitsSmi() const;
+
+ virtual CompileType ComputeType() const;
+ virtual bool RecomputeType();
virtual bool CanDeoptimize() const { return false; }
@@ -7816,69 +7981,148 @@ class BoxUint32Instr : public TemplateDefinition<1> {
virtual Representation RequiredInputRepresentation(intptr_t idx) const {
ASSERT(idx == 0);
- return kUnboxedUint32;
+ return representation_;
}
- DECLARE_INSTRUCTION(BoxUint32)
- virtual CompileType ComputeType() const;
-
virtual bool AllowsCSE() const { return true; }
virtual EffectSet Effects() const { return EffectSet::None(); }
virtual EffectSet Dependencies() const { return EffectSet::None(); }
- virtual bool AttributesEqual(Instruction* other) const { return true; }
+ virtual bool AttributesEqual(Instruction* other) const {
+ return other->AsBoxIntN()->representation_ == representation_;
+ }
virtual bool MayThrow() const { return false; }
+ virtual Definition* Canonicalize(FlowGraph* flow_graph);
+
+ virtual BoxIntNInstr* AsBoxIntN() { return this; }
+
+ private:
+ const Representation representation_;
+
+ DISALLOW_COPY_AND_ASSIGN(BoxIntNInstr);
+};
+
+
+class BoxUint32Instr : public BoxIntNInstr {
+ public:
+ explicit BoxUint32Instr(Value* value)
+ : BoxIntNInstr(kUnboxedUint32, value) { }
+
+ DECLARE_INSTRUCTION(BoxUint32)
+
private:
DISALLOW_COPY_AND_ASSIGN(BoxUint32Instr);
};
-class UnboxUint32Instr : public TemplateDefinition<1> {
+class BoxInt32Instr : public BoxIntNInstr {
+ public:
+ explicit BoxInt32Instr(Value* value)
+ : BoxIntNInstr(kUnboxedInt32, value) { }
+
+ virtual void InferRange(RangeAnalysis* analysis, Range* range);
+
+ DECLARE_INSTRUCTION(BoxInt32)
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(BoxInt32Instr);
+};
+
+
+class UnboxIntNInstr : public TemplateDefinition<1> {
public:
- UnboxUint32Instr(Value* value, intptr_t deopt_id) {
+ UnboxIntNInstr(Representation representation,
+ Value* value,
+ intptr_t deopt_id)
+ : representation_(representation) {
SetInputAt(0, value);
deopt_id_ = deopt_id;
}
Value* value() const { return inputs_[0]; }
- virtual bool CanDeoptimize() const {
- return (value()->Type()->ToCid() != kSmiCid)
- && (value()->Type()->ToCid() != kMintCid);
- }
-
virtual Representation representation() const {
- return kUnboxedUint32;
+ return representation_;
}
-
- DECLARE_INSTRUCTION(UnboxUint32)
virtual CompileType ComputeType() const;
virtual bool AllowsCSE() const { return true; }
virtual EffectSet Effects() const { return EffectSet::None(); }
virtual EffectSet Dependencies() const { return EffectSet::None(); }
- virtual bool AttributesEqual(Instruction* other) const { return true; }
+ virtual bool AttributesEqual(Instruction* other) const {
+ return other->AsUnboxIntN()->representation_ == representation_;
+ }
virtual bool MayThrow() const { return false; }
+ virtual Definition* Canonicalize(FlowGraph* flow_graph);
+
+ virtual UnboxIntNInstr* AsUnboxIntN() { return this; }
+
+ private:
+ const Representation representation_;
+
+ DISALLOW_COPY_AND_ASSIGN(UnboxIntNInstr);
+};
+
+
+class UnboxUint32Instr : public UnboxIntNInstr {
+ public:
+ UnboxUint32Instr(Value* value, intptr_t deopt_id)
+ : UnboxIntNInstr(kUnboxedUint32, value, deopt_id) {
+ }
+
+ virtual bool CanDeoptimize() const {
+ return (value()->Type()->ToCid() != kSmiCid)
+ && (value()->Type()->ToCid() != kMintCid);
+ }
+
+ DECLARE_INSTRUCTION(UnboxUint32)
+
private:
DISALLOW_COPY_AND_ASSIGN(UnboxUint32Instr);
};
+class UnboxInt32Instr : public UnboxIntNInstr {
+ public:
+ UnboxInt32Instr(Value* value, intptr_t deopt_id)
+ : UnboxIntNInstr(kUnboxedInt32, value, deopt_id) {
+ }
+
+ virtual bool CanDeoptimize() const;
+
+ virtual void InferRange(RangeAnalysis* analysis, Range* range);
+
+ virtual Definition* Canonicalize(FlowGraph* flow_graph);
+
+ DECLARE_INSTRUCTION(UnboxInt32)
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(UnboxInt32Instr);
+};
+
+
class UnboxedIntConverterInstr : public TemplateDefinition<1> {
public:
UnboxedIntConverterInstr(Representation from,
Representation to,
- Value* value)
+ Value* value,
+ intptr_t deopt_id)
: from_representation_(from),
to_representation_(to) {
ASSERT(from != to);
- ASSERT((from == kUnboxedMint) || (from == kUnboxedUint32));
- ASSERT((to == kUnboxedMint) || (to == kUnboxedUint32));
+ ASSERT((from == kUnboxedMint) ||
+ (from == kUnboxedUint32) ||
+ (from == kUnboxedInt32));
+ ASSERT((to == kUnboxedMint) ||
+ (to == kUnboxedUint32) ||
+ (to == kUnboxedInt32));
+ ASSERT((to != kUnboxedInt32) || (deopt_id != Isolate::kNoDeoptId));
SetInputAt(0, value);
+ deopt_id_ = deopt_id;
}
Value* value() const { return inputs_[0]; }
@@ -7886,7 +8130,9 @@ class UnboxedIntConverterInstr : public TemplateDefinition<1> {
Representation from() const { return from_representation_; }
Representation to() const { return to_representation_; }
- virtual bool CanDeoptimize() const { return false; }
+ Definition* Canonicalize(FlowGraph* flow_graph);
+
+ virtual bool CanDeoptimize() const;
virtual Representation representation() const {
return to();
@@ -7907,6 +8153,10 @@ class UnboxedIntConverterInstr : public TemplateDefinition<1> {
virtual bool MayThrow() const { return false; }
+ virtual void InferRange(RangeAnalysis* analysis, Range* range);
+
+ virtual void PrintOperandsTo(BufferFormatter* f) const;
+
DECLARE_INSTRUCTION(UnboxedIntConverter);
private:
@@ -8143,6 +8393,16 @@ class FlowGraphVisitor : public ValueObject {
};
+// Helper macros for platform ports.
+#define DEFINE_UNIMPLEMENTED_INSTRUCTION(Name) \
+ LocationSummary* Name::MakeLocationSummary( \
+ Isolate* isolate, bool opt) const { \
+ UNIMPLEMENTED(); \
+ return NULL; \
+ } \
+ void Name::EmitNativeCode(FlowGraphCompiler* compiler) { UNIMPLEMENTED(); }
+
+
} // namespace dart
#endif // VM_INTERMEDIATE_LANGUAGE_H_

Powered by Google App Engine
This is Rietveld 408576698