Index: src/compiler/code-assembler.cc |
diff --git a/src/compiler/code-assembler.cc b/src/compiler/code-assembler.cc |
index 4844355abb08e61a694f9ae669e201477a21cf67..e136f80558ee995445194e7cdf0869d0a4325a56 100644 |
--- a/src/compiler/code-assembler.cc |
+++ b/src/compiler/code-assembler.cc |
@@ -209,6 +209,10 @@ bool CodeAssembler::ToSmiConstant(Node* node, Smi*& out_value) { |
} |
bool CodeAssembler::ToIntPtrConstant(Node* node, intptr_t& out_value) { |
+ if (node->opcode() == IrOpcode::kBitcastWordToTaggedSigned || |
+ node->opcode() == IrOpcode::kBitcastWordToTagged) { |
+ node = node->InputAt(0); |
+ } |
IntPtrMatcher m(node); |
if (m.HasValue()) out_value = m.Value(); |
return m.HasValue(); |
@@ -269,6 +273,51 @@ Node* CodeAssembler::LoadStackPointer() { |
CODE_ASSEMBLER_BINARY_OP_LIST(DEFINE_CODE_ASSEMBLER_BINARY_OP) |
#undef DEFINE_CODE_ASSEMBLER_BINARY_OP |
+Node* CodeAssembler::IntPtrAdd(Node* left, Node* right) { |
+ intptr_t left_constant; |
+ bool is_left_constant = ToIntPtrConstant(left, left_constant); |
+ intptr_t right_constant; |
+ bool is_right_constant = ToIntPtrConstant(right, right_constant); |
+ if (is_left_constant) { |
+ if (is_right_constant) { |
+ intptr_t sum = left_constant + right_constant; |
+ if (sum >= std::numeric_limits<int32_t>::min() && |
Igor Sheludko
2016/12/28 15:57:05
I think we can always return the sum.
danno
2016/12/28 16:05:33
Done.
|
+ sum <= std::numeric_limits<int32_t>::max()) { |
+ return IntPtrConstant(sum); |
+ } |
+ } |
+ if (left_constant == 0) { |
+ return right; |
+ } |
+ } else if (is_right_constant) { |
+ if (right_constant == 0) { |
+ return left; |
+ } |
+ } |
+ return raw_assembler()->IntPtrAdd(left, right); |
+} |
+ |
+Node* CodeAssembler::IntPtrSub(Node* left, Node* right) { |
+ intptr_t left_constant; |
+ bool is_left_constant = ToIntPtrConstant(left, left_constant); |
+ intptr_t right_constant; |
+ bool is_right_constant = ToIntPtrConstant(right, right_constant); |
+ if (is_left_constant) { |
+ if (is_right_constant) { |
+ intptr_t diff = left_constant - right_constant; |
+ if (diff >= std::numeric_limits<int32_t>::min() && |
Igor Sheludko
2016/12/28 15:57:05
Same here.
danno
2016/12/28 16:05:33
Done.
|
+ diff <= std::numeric_limits<int32_t>::max()) { |
+ return IntPtrConstant(diff); |
+ } |
+ } |
+ } else if (is_right_constant) { |
+ if (right_constant == 0) { |
+ return left; |
+ } |
+ } |
+ return raw_assembler()->IntPtrSub(left, right); |
+} |
+ |
Node* CodeAssembler::WordShl(Node* value, int shift) { |
return (shift != 0) ? raw_assembler()->WordShl(value, IntPtrConstant(shift)) |
: value; |