Removes premature constant folding in CodeAssembler
Many binary operations defiend in CodeAssembler check for constants in the inputs and apply simplification if applicable. This is now performed by the MachineOperatorReducer in a uniform way. To avoid code duplication, the premature optimizations in CodeAssembler have been removed in this CL. Bug: v8:10021 Change-Id: I9b99f05e4f9ab31ff933f22d62674ee80efee8ac Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1995277 Reviewed-by: Maya Lekova <mslekova@chromium.org> Commit-Queue: Nico Hartmann <nicohartmann@chromium.org> Cr-Commit-Position: refs/heads/master@{#65707}
This commit is contained in:
parent
2806dd786a
commit
f2503feeb6
@ -512,83 +512,6 @@ TNode<WordT> CodeAssembler::WordPoisonOnSpeculation(SloppyTNode<WordT> value) {
|
||||
CODE_ASSEMBLER_BINARY_OP_LIST(DEFINE_CODE_ASSEMBLER_BINARY_OP)
|
||||
#undef DEFINE_CODE_ASSEMBLER_BINARY_OP
|
||||
|
||||
TNode<WordT> CodeAssembler::IntPtrAdd(SloppyTNode<WordT> left,
|
||||
SloppyTNode<WordT> 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) {
|
||||
return IntPtrConstant(left_constant + right_constant);
|
||||
}
|
||||
if (left_constant == 0) {
|
||||
return right;
|
||||
}
|
||||
} else if (is_right_constant) {
|
||||
if (right_constant == 0) {
|
||||
return left;
|
||||
}
|
||||
}
|
||||
return UncheckedCast<WordT>(raw_assembler()->IntPtrAdd(left, right));
|
||||
}
|
||||
|
||||
TNode<IntPtrT> CodeAssembler::IntPtrDiv(TNode<IntPtrT> left,
|
||||
TNode<IntPtrT> 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_right_constant) {
|
||||
if (is_left_constant) {
|
||||
return IntPtrConstant(left_constant / right_constant);
|
||||
}
|
||||
if (base::bits::IsPowerOfTwo(right_constant)) {
|
||||
return WordSar(left, base::bits::WhichPowerOfTwo(right_constant));
|
||||
}
|
||||
}
|
||||
return UncheckedCast<IntPtrT>(raw_assembler()->IntPtrDiv(left, right));
|
||||
}
|
||||
|
||||
TNode<WordT> CodeAssembler::IntPtrSub(SloppyTNode<WordT> left,
|
||||
SloppyTNode<WordT> 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) {
|
||||
return IntPtrConstant(left_constant - right_constant);
|
||||
}
|
||||
} else if (is_right_constant) {
|
||||
if (right_constant == 0) {
|
||||
return left;
|
||||
}
|
||||
}
|
||||
return UncheckedCast<IntPtrT>(raw_assembler()->IntPtrSub(left, right));
|
||||
}
|
||||
|
||||
TNode<WordT> CodeAssembler::IntPtrMul(SloppyTNode<WordT> left,
|
||||
SloppyTNode<WordT> 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) {
|
||||
return IntPtrConstant(left_constant * right_constant);
|
||||
}
|
||||
if (base::bits::IsPowerOfTwo(left_constant)) {
|
||||
return WordShl(right, base::bits::WhichPowerOfTwo(left_constant));
|
||||
}
|
||||
} else if (is_right_constant) {
|
||||
if (base::bits::IsPowerOfTwo(right_constant)) {
|
||||
return WordShl(left, base::bits::WhichPowerOfTwo(right_constant));
|
||||
}
|
||||
}
|
||||
return UncheckedCast<IntPtrT>(raw_assembler()->IntPtrMul(left, right));
|
||||
}
|
||||
|
||||
TNode<WordT> CodeAssembler::WordShl(SloppyTNode<WordT> value, int shift) {
|
||||
return (shift != 0) ? WordShl(value, IntPtrConstant(shift)) : value;
|
||||
}
|
||||
@ -609,319 +532,6 @@ TNode<Word32T> CodeAssembler::Word32Sar(SloppyTNode<Word32T> value, int shift) {
|
||||
return (shift != 0) ? Word32Sar(value, Int32Constant(shift)) : value;
|
||||
}
|
||||
|
||||
TNode<WordT> CodeAssembler::WordOr(SloppyTNode<WordT> left,
|
||||
SloppyTNode<WordT> 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) {
|
||||
return IntPtrConstant(left_constant | right_constant);
|
||||
}
|
||||
if (left_constant == 0) {
|
||||
return right;
|
||||
}
|
||||
} else if (is_right_constant) {
|
||||
if (right_constant == 0) {
|
||||
return left;
|
||||
}
|
||||
}
|
||||
return UncheckedCast<WordT>(raw_assembler()->WordOr(left, right));
|
||||
}
|
||||
|
||||
TNode<WordT> CodeAssembler::WordAnd(SloppyTNode<WordT> left,
|
||||
SloppyTNode<WordT> 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) {
|
||||
return IntPtrConstant(left_constant & right_constant);
|
||||
}
|
||||
}
|
||||
return UncheckedCast<WordT>(raw_assembler()->WordAnd(left, right));
|
||||
}
|
||||
|
||||
TNode<WordT> CodeAssembler::WordXor(SloppyTNode<WordT> left,
|
||||
SloppyTNode<WordT> 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) {
|
||||
return IntPtrConstant(left_constant ^ right_constant);
|
||||
}
|
||||
}
|
||||
return UncheckedCast<WordT>(raw_assembler()->WordXor(left, right));
|
||||
}
|
||||
|
||||
TNode<WordT> CodeAssembler::WordShl(SloppyTNode<WordT> left,
|
||||
SloppyTNode<IntegralT> 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) {
|
||||
return IntPtrConstant(static_cast<uintptr_t>(left_constant)
|
||||
<< right_constant);
|
||||
}
|
||||
} else if (is_right_constant) {
|
||||
if (right_constant == 0) {
|
||||
return left;
|
||||
}
|
||||
}
|
||||
return UncheckedCast<WordT>(raw_assembler()->WordShl(left, right));
|
||||
}
|
||||
|
||||
TNode<WordT> CodeAssembler::WordShr(SloppyTNode<WordT> left,
|
||||
SloppyTNode<IntegralT> 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) {
|
||||
return IntPtrConstant(static_cast<uintptr_t>(left_constant) >>
|
||||
right_constant);
|
||||
}
|
||||
} else if (is_right_constant) {
|
||||
if (right_constant == 0) {
|
||||
return left;
|
||||
}
|
||||
}
|
||||
return UncheckedCast<WordT>(raw_assembler()->WordShr(left, right));
|
||||
}
|
||||
|
||||
TNode<WordT> CodeAssembler::WordSar(SloppyTNode<WordT> left,
|
||||
SloppyTNode<IntegralT> 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) {
|
||||
return IntPtrConstant(left_constant >> right_constant);
|
||||
}
|
||||
} else if (is_right_constant) {
|
||||
if (right_constant == 0) {
|
||||
return left;
|
||||
}
|
||||
}
|
||||
return UncheckedCast<WordT>(raw_assembler()->WordSar(left, right));
|
||||
}
|
||||
|
||||
TNode<Word32T> CodeAssembler::Word32Or(SloppyTNode<Word32T> left,
|
||||
SloppyTNode<Word32T> right) {
|
||||
int32_t left_constant;
|
||||
bool is_left_constant = ToInt32Constant(left, &left_constant);
|
||||
int32_t right_constant;
|
||||
bool is_right_constant = ToInt32Constant(right, &right_constant);
|
||||
if (is_left_constant) {
|
||||
if (is_right_constant) {
|
||||
return Int32Constant(left_constant | right_constant);
|
||||
}
|
||||
if (left_constant == 0) {
|
||||
return right;
|
||||
}
|
||||
} else if (is_right_constant) {
|
||||
if (right_constant == 0) {
|
||||
return left;
|
||||
}
|
||||
}
|
||||
return UncheckedCast<Word32T>(raw_assembler()->Word32Or(left, right));
|
||||
}
|
||||
|
||||
TNode<Word32T> CodeAssembler::Word32And(SloppyTNode<Word32T> left,
|
||||
SloppyTNode<Word32T> right) {
|
||||
int32_t left_constant;
|
||||
bool is_left_constant = ToInt32Constant(left, &left_constant);
|
||||
int32_t right_constant;
|
||||
bool is_right_constant = ToInt32Constant(right, &right_constant);
|
||||
if (is_left_constant) {
|
||||
if (is_right_constant) {
|
||||
return Int32Constant(left_constant & right_constant);
|
||||
}
|
||||
}
|
||||
return UncheckedCast<Word32T>(raw_assembler()->Word32And(left, right));
|
||||
}
|
||||
|
||||
TNode<Word32T> CodeAssembler::Word32Xor(SloppyTNode<Word32T> left,
|
||||
SloppyTNode<Word32T> right) {
|
||||
int32_t left_constant;
|
||||
bool is_left_constant = ToInt32Constant(left, &left_constant);
|
||||
int32_t right_constant;
|
||||
bool is_right_constant = ToInt32Constant(right, &right_constant);
|
||||
if (is_left_constant) {
|
||||
if (is_right_constant) {
|
||||
return Int32Constant(left_constant ^ right_constant);
|
||||
}
|
||||
}
|
||||
return UncheckedCast<Word32T>(raw_assembler()->Word32Xor(left, right));
|
||||
}
|
||||
|
||||
TNode<Word32T> CodeAssembler::Word32Shl(SloppyTNode<Word32T> left,
|
||||
SloppyTNode<Word32T> right) {
|
||||
int32_t left_constant;
|
||||
bool is_left_constant = ToInt32Constant(left, &left_constant);
|
||||
int32_t right_constant;
|
||||
bool is_right_constant = ToInt32Constant(right, &right_constant);
|
||||
if (is_left_constant) {
|
||||
if (is_right_constant) {
|
||||
return Int32Constant(left_constant << right_constant);
|
||||
}
|
||||
} else if (is_right_constant) {
|
||||
if (right_constant == 0) {
|
||||
return left;
|
||||
}
|
||||
}
|
||||
return UncheckedCast<Word32T>(raw_assembler()->Word32Shl(left, right));
|
||||
}
|
||||
|
||||
TNode<Word32T> CodeAssembler::Word32Shr(SloppyTNode<Word32T> left,
|
||||
SloppyTNode<Word32T> right) {
|
||||
int32_t left_constant;
|
||||
bool is_left_constant = ToInt32Constant(left, &left_constant);
|
||||
int32_t right_constant;
|
||||
bool is_right_constant = ToInt32Constant(right, &right_constant);
|
||||
if (is_left_constant) {
|
||||
if (is_right_constant) {
|
||||
return Int32Constant(static_cast<uint32_t>(left_constant) >>
|
||||
right_constant);
|
||||
}
|
||||
} else if (is_right_constant) {
|
||||
if (right_constant == 0) {
|
||||
return left;
|
||||
}
|
||||
}
|
||||
return UncheckedCast<Word32T>(raw_assembler()->Word32Shr(left, right));
|
||||
}
|
||||
|
||||
TNode<Word32T> CodeAssembler::Word32Sar(SloppyTNode<Word32T> left,
|
||||
SloppyTNode<Word32T> right) {
|
||||
int32_t left_constant;
|
||||
bool is_left_constant = ToInt32Constant(left, &left_constant);
|
||||
int32_t right_constant;
|
||||
bool is_right_constant = ToInt32Constant(right, &right_constant);
|
||||
if (is_left_constant) {
|
||||
if (is_right_constant) {
|
||||
return Int32Constant(left_constant >> right_constant);
|
||||
}
|
||||
} else if (is_right_constant) {
|
||||
if (right_constant == 0) {
|
||||
return left;
|
||||
}
|
||||
}
|
||||
return UncheckedCast<Word32T>(raw_assembler()->Word32Sar(left, right));
|
||||
}
|
||||
|
||||
TNode<Word64T> CodeAssembler::Word64Or(SloppyTNode<Word64T> left,
|
||||
SloppyTNode<Word64T> right) {
|
||||
int64_t left_constant;
|
||||
bool is_left_constant = ToInt64Constant(left, &left_constant);
|
||||
int64_t right_constant;
|
||||
bool is_right_constant = ToInt64Constant(right, &right_constant);
|
||||
if (is_left_constant) {
|
||||
if (is_right_constant) {
|
||||
return Int64Constant(left_constant | right_constant);
|
||||
}
|
||||
if (left_constant == 0) {
|
||||
return right;
|
||||
}
|
||||
} else if (is_right_constant) {
|
||||
if (right_constant == 0) {
|
||||
return left;
|
||||
}
|
||||
}
|
||||
return UncheckedCast<Word64T>(raw_assembler()->Word64Or(left, right));
|
||||
}
|
||||
|
||||
TNode<Word64T> CodeAssembler::Word64And(SloppyTNode<Word64T> left,
|
||||
SloppyTNode<Word64T> right) {
|
||||
int64_t left_constant;
|
||||
bool is_left_constant = ToInt64Constant(left, &left_constant);
|
||||
int64_t right_constant;
|
||||
bool is_right_constant = ToInt64Constant(right, &right_constant);
|
||||
if (is_left_constant) {
|
||||
if (is_right_constant) {
|
||||
return Int64Constant(left_constant & right_constant);
|
||||
}
|
||||
}
|
||||
return UncheckedCast<Word64T>(raw_assembler()->Word64And(left, right));
|
||||
}
|
||||
|
||||
TNode<Word64T> CodeAssembler::Word64Xor(SloppyTNode<Word64T> left,
|
||||
SloppyTNode<Word64T> right) {
|
||||
int64_t left_constant;
|
||||
bool is_left_constant = ToInt64Constant(left, &left_constant);
|
||||
int64_t right_constant;
|
||||
bool is_right_constant = ToInt64Constant(right, &right_constant);
|
||||
if (is_left_constant) {
|
||||
if (is_right_constant) {
|
||||
return Int64Constant(left_constant ^ right_constant);
|
||||
}
|
||||
}
|
||||
return UncheckedCast<Word64T>(raw_assembler()->Word64Xor(left, right));
|
||||
}
|
||||
|
||||
TNode<Word64T> CodeAssembler::Word64Shl(SloppyTNode<Word64T> left,
|
||||
SloppyTNode<Word64T> right) {
|
||||
int64_t left_constant;
|
||||
bool is_left_constant = ToInt64Constant(left, &left_constant);
|
||||
int64_t right_constant;
|
||||
bool is_right_constant = ToInt64Constant(right, &right_constant);
|
||||
if (is_left_constant) {
|
||||
if (is_right_constant) {
|
||||
return Int64Constant(left_constant << right_constant);
|
||||
}
|
||||
} else if (is_right_constant) {
|
||||
if (right_constant == 0) {
|
||||
return left;
|
||||
}
|
||||
}
|
||||
return UncheckedCast<Word64T>(raw_assembler()->Word64Shl(left, right));
|
||||
}
|
||||
|
||||
TNode<Word64T> CodeAssembler::Word64Shr(SloppyTNode<Word64T> left,
|
||||
SloppyTNode<Word64T> right) {
|
||||
int64_t left_constant;
|
||||
bool is_left_constant = ToInt64Constant(left, &left_constant);
|
||||
int64_t right_constant;
|
||||
bool is_right_constant = ToInt64Constant(right, &right_constant);
|
||||
if (is_left_constant) {
|
||||
if (is_right_constant) {
|
||||
return Int64Constant(static_cast<uint64_t>(left_constant) >>
|
||||
right_constant);
|
||||
}
|
||||
} else if (is_right_constant) {
|
||||
if (right_constant == 0) {
|
||||
return left;
|
||||
}
|
||||
}
|
||||
return UncheckedCast<Word64T>(raw_assembler()->Word64Shr(left, right));
|
||||
}
|
||||
|
||||
TNode<Word64T> CodeAssembler::Word64Sar(SloppyTNode<Word64T> left,
|
||||
SloppyTNode<Word64T> right) {
|
||||
int64_t left_constant;
|
||||
bool is_left_constant = ToInt64Constant(left, &left_constant);
|
||||
int64_t right_constant;
|
||||
bool is_right_constant = ToInt64Constant(right, &right_constant);
|
||||
if (is_left_constant) {
|
||||
if (is_right_constant) {
|
||||
return Int64Constant(left_constant >> right_constant);
|
||||
}
|
||||
} else if (is_right_constant) {
|
||||
if (right_constant == 0) {
|
||||
return left;
|
||||
}
|
||||
}
|
||||
return UncheckedCast<Word64T>(raw_assembler()->Word64Sar(left, right));
|
||||
}
|
||||
|
||||
#define CODE_ASSEMBLER_COMPARE(Name, ArgT, VarT, ToConstant, op) \
|
||||
TNode<BoolT> CodeAssembler::Name(TNode<ArgT> left, TNode<ArgT> right) { \
|
||||
VarT lhs, rhs; \
|
||||
|
@ -249,6 +249,10 @@ class CodeAssemblerParameterizedLabel;
|
||||
V(Float64Min, Float64T, Float64T, Float64T) \
|
||||
V(Float64InsertLowWord32, Float64T, Float64T, Word32T) \
|
||||
V(Float64InsertHighWord32, Float64T, Float64T, Word32T) \
|
||||
V(IntPtrAdd, WordT, WordT, WordT) \
|
||||
V(IntPtrSub, WordT, WordT, WordT) \
|
||||
V(IntPtrMul, WordT, WordT, WordT) \
|
||||
V(IntPtrDiv, IntPtrT, IntPtrT, IntPtrT) \
|
||||
V(IntPtrAddWithOverflow, PAIR_TYPE(IntPtrT, BoolT), IntPtrT, IntPtrT) \
|
||||
V(IntPtrSubWithOverflow, PAIR_TYPE(IntPtrT, BoolT), IntPtrT, IntPtrT) \
|
||||
V(Int32Add, Word32T, Word32T, Word32T) \
|
||||
@ -259,9 +263,27 @@ class CodeAssemblerParameterizedLabel;
|
||||
V(Int32MulWithOverflow, PAIR_TYPE(Int32T, BoolT), Int32T, Int32T) \
|
||||
V(Int32Div, Int32T, Int32T, Int32T) \
|
||||
V(Int32Mod, Int32T, Int32T, Int32T) \
|
||||
V(WordOr, WordT, WordT, WordT) \
|
||||
V(WordAnd, WordT, WordT, WordT) \
|
||||
V(WordXor, WordT, WordT, WordT) \
|
||||
V(WordRor, WordT, WordT, IntegralT) \
|
||||
V(WordShl, WordT, WordT, IntegralT) \
|
||||
V(WordShr, WordT, WordT, IntegralT) \
|
||||
V(WordSar, WordT, WordT, IntegralT) \
|
||||
V(Word32Or, Word32T, Word32T, Word32T) \
|
||||
V(Word32And, Word32T, Word32T, Word32T) \
|
||||
V(Word32Xor, Word32T, Word32T, Word32T) \
|
||||
V(Word32Ror, Word32T, Word32T, Word32T) \
|
||||
V(Word64Ror, Word64T, Word64T, Word64T)
|
||||
V(Word32Shl, Word32T, Word32T, Word32T) \
|
||||
V(Word32Shr, Word32T, Word32T, Word32T) \
|
||||
V(Word32Sar, Word32T, Word32T, Word32T) \
|
||||
V(Word64And, Word64T, Word64T, Word64T) \
|
||||
V(Word64Or, Word64T, Word64T, Word64T) \
|
||||
V(Word64Xor, Word64T, Word64T, Word64T) \
|
||||
V(Word64Ror, Word64T, Word64T, Word64T) \
|
||||
V(Word64Shl, Word64T, Word64T, Word64T) \
|
||||
V(Word64Shr, Word64T, Word64T, Word64T) \
|
||||
V(Word64Sar, Word64T, Word64T, Word64T)
|
||||
|
||||
TNode<Float64T> Float64Add(TNode<Float64T> a, TNode<Float64T> b);
|
||||
|
||||
@ -825,10 +847,6 @@ class V8_EXPORT_PRIVATE CodeAssembler {
|
||||
Int32Mul(static_cast<Node*>(left), static_cast<Node*>(right)));
|
||||
}
|
||||
|
||||
TNode<WordT> IntPtrAdd(SloppyTNode<WordT> left, SloppyTNode<WordT> right);
|
||||
TNode<IntPtrT> IntPtrDiv(TNode<IntPtrT> left, TNode<IntPtrT> right);
|
||||
TNode<WordT> IntPtrSub(SloppyTNode<WordT> left, SloppyTNode<WordT> right);
|
||||
TNode<WordT> IntPtrMul(SloppyTNode<WordT> left, SloppyTNode<WordT> right);
|
||||
TNode<IntPtrT> IntPtrAdd(TNode<IntPtrT> left, TNode<IntPtrT> right) {
|
||||
return Signed(
|
||||
IntPtrAdd(static_cast<Node*>(left), static_cast<Node*>(right)));
|
||||
@ -872,37 +890,6 @@ class V8_EXPORT_PRIVATE CodeAssembler {
|
||||
TNode<Word32T> Word32Shr(SloppyTNode<Word32T> value, int shift);
|
||||
TNode<Word32T> Word32Sar(SloppyTNode<Word32T> value, int shift);
|
||||
|
||||
TNode<WordT> WordOr(SloppyTNode<WordT> left, SloppyTNode<WordT> right);
|
||||
TNode<WordT> WordAnd(SloppyTNode<WordT> left, SloppyTNode<WordT> right);
|
||||
TNode<WordT> WordXor(SloppyTNode<WordT> left, SloppyTNode<WordT> right);
|
||||
TNode<WordT> WordShl(SloppyTNode<WordT> left, SloppyTNode<IntegralT> right);
|
||||
TNode<WordT> WordShr(SloppyTNode<WordT> left, SloppyTNode<IntegralT> right);
|
||||
TNode<WordT> WordSar(SloppyTNode<WordT> left, SloppyTNode<IntegralT> right);
|
||||
TNode<Word32T> Word32Or(SloppyTNode<Word32T> left,
|
||||
SloppyTNode<Word32T> right);
|
||||
TNode<Word32T> Word32And(SloppyTNode<Word32T> left,
|
||||
SloppyTNode<Word32T> right);
|
||||
TNode<Word32T> Word32Xor(SloppyTNode<Word32T> left,
|
||||
SloppyTNode<Word32T> right);
|
||||
TNode<Word32T> Word32Shl(SloppyTNode<Word32T> left,
|
||||
SloppyTNode<Word32T> right);
|
||||
TNode<Word32T> Word32Shr(SloppyTNode<Word32T> left,
|
||||
SloppyTNode<Word32T> right);
|
||||
TNode<Word32T> Word32Sar(SloppyTNode<Word32T> left,
|
||||
SloppyTNode<Word32T> right);
|
||||
TNode<Word64T> Word64Or(SloppyTNode<Word64T> left,
|
||||
SloppyTNode<Word64T> right);
|
||||
TNode<Word64T> Word64And(SloppyTNode<Word64T> left,
|
||||
SloppyTNode<Word64T> right);
|
||||
TNode<Word64T> Word64Xor(SloppyTNode<Word64T> left,
|
||||
SloppyTNode<Word64T> right);
|
||||
TNode<Word64T> Word64Shl(SloppyTNode<Word64T> left,
|
||||
SloppyTNode<Word64T> right);
|
||||
TNode<Word64T> Word64Shr(SloppyTNode<Word64T> left,
|
||||
SloppyTNode<Word64T> right);
|
||||
TNode<Word64T> Word64Sar(SloppyTNode<Word64T> left,
|
||||
SloppyTNode<Word64T> right);
|
||||
|
||||
// Unary
|
||||
#define DECLARE_CODE_ASSEMBLER_UNARY_OP(name, ResType, ArgType) \
|
||||
TNode<ResType> name(SloppyTNode<ArgType> a);
|
||||
|
@ -108,8 +108,6 @@ v8_source_set("unittests_sources") {
|
||||
"compiler/branch-elimination-unittest.cc",
|
||||
"compiler/bytecode-analysis-unittest.cc",
|
||||
"compiler/checkpoint-elimination-unittest.cc",
|
||||
"compiler/code-assembler-unittest.cc",
|
||||
"compiler/code-assembler-unittest.h",
|
||||
"compiler/common-operator-reducer-unittest.cc",
|
||||
"compiler/common-operator-unittest.cc",
|
||||
"compiler/compiler-test-utils.h",
|
||||
|
@ -1,308 +0,0 @@
|
||||
// Copyright 2017 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "test/unittests/compiler/code-assembler-unittest.h"
|
||||
|
||||
#include "src/codegen/code-factory.h"
|
||||
#include "src/codegen/interface-descriptors.h"
|
||||
#include "src/compiler/node.h"
|
||||
#include "src/execution/isolate.h"
|
||||
#include "src/objects/objects-inl.h"
|
||||
#include "test/unittests/compiler/compiler-test-utils.h"
|
||||
#include "test/unittests/compiler/node-test-utils.h"
|
||||
|
||||
using ::testing::_;
|
||||
using ::testing::Eq;
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
namespace compiler {
|
||||
|
||||
CodeAssemblerTestState::CodeAssemblerTestState(CodeAssemblerTest* test)
|
||||
: CodeAssemblerState(test->isolate(), test->zone(), VoidDescriptor{},
|
||||
Code::STUB, "test",
|
||||
PoisoningMitigationLevel::kPoisonCriticalOnly) {}
|
||||
|
||||
TARGET_TEST_F(CodeAssemblerTest, IntPtrAdd) {
|
||||
CodeAssemblerTestState state(this);
|
||||
CodeAssemblerForTest m(&state);
|
||||
{
|
||||
Node* a = m.Parameter(0);
|
||||
TNode<IntPtrT> b = m.IntPtrConstant(1);
|
||||
TNode<WordT> add = m.IntPtrAdd(a, b);
|
||||
EXPECT_THAT(add, IsIntPtrAdd(Eq(a), Eq(b)));
|
||||
}
|
||||
// x + 0 => x
|
||||
{
|
||||
Node* a = m.Parameter(0);
|
||||
TNode<IntPtrT> b = m.IntPtrConstant(0);
|
||||
TNode<WordT> add = m.IntPtrAdd(a, b);
|
||||
EXPECT_THAT(add, a);
|
||||
}
|
||||
// 0 + x => x
|
||||
{
|
||||
Node* a = m.Parameter(0);
|
||||
TNode<IntPtrT> b = m.IntPtrConstant(0);
|
||||
TNode<WordT> add = m.IntPtrAdd(b, a);
|
||||
EXPECT_THAT(add, a);
|
||||
}
|
||||
// CONST_a + CONST_b => CONST_c
|
||||
{
|
||||
TNode<IntPtrT> a = m.IntPtrConstant(22);
|
||||
TNode<IntPtrT> b = m.IntPtrConstant(33);
|
||||
TNode<IntPtrT> c = m.IntPtrAdd(a, b);
|
||||
EXPECT_THAT(c, IsIntPtrConstant(55));
|
||||
}
|
||||
}
|
||||
|
||||
TARGET_TEST_F(CodeAssemblerTest, IntPtrSub) {
|
||||
CodeAssemblerTestState state(this);
|
||||
CodeAssemblerForTest m(&state);
|
||||
{
|
||||
Node* a = m.Parameter(0);
|
||||
TNode<IntPtrT> b = m.IntPtrConstant(1);
|
||||
TNode<WordT> sub = m.IntPtrSub(a, b);
|
||||
EXPECT_THAT(sub, IsIntPtrSub(Eq(a), Eq(b)));
|
||||
}
|
||||
// x - 0 => x
|
||||
{
|
||||
Node* a = m.Parameter(0);
|
||||
TNode<IntPtrT> b = m.IntPtrConstant(0);
|
||||
TNode<WordT> c = m.IntPtrSub(a, b);
|
||||
EXPECT_THAT(c, a);
|
||||
}
|
||||
// CONST_a - CONST_b => CONST_c
|
||||
{
|
||||
TNode<IntPtrT> a = m.IntPtrConstant(100);
|
||||
TNode<IntPtrT> b = m.IntPtrConstant(1);
|
||||
TNode<IntPtrT> c = m.IntPtrSub(a, b);
|
||||
EXPECT_THAT(c, IsIntPtrConstant(99));
|
||||
}
|
||||
}
|
||||
|
||||
TARGET_TEST_F(CodeAssemblerTest, IntPtrMul) {
|
||||
CodeAssemblerTestState state(this);
|
||||
CodeAssemblerForTest m(&state);
|
||||
{
|
||||
Node* a = m.Parameter(0);
|
||||
TNode<IntPtrT> b = m.IntPtrConstant(100);
|
||||
TNode<WordT> mul = m.IntPtrMul(a, b);
|
||||
EXPECT_THAT(mul, IsIntPtrMul(Eq(a), Eq(b)));
|
||||
}
|
||||
// x * 1 => x
|
||||
{
|
||||
Node* a = m.Parameter(0);
|
||||
TNode<IntPtrT> b = m.IntPtrConstant(1);
|
||||
TNode<WordT> mul = m.IntPtrMul(a, b);
|
||||
EXPECT_THAT(mul, a);
|
||||
}
|
||||
// 1 * x => x
|
||||
{
|
||||
Node* a = m.Parameter(0);
|
||||
TNode<IntPtrT> b = m.IntPtrConstant(1);
|
||||
TNode<WordT> mul = m.IntPtrMul(b, a);
|
||||
EXPECT_THAT(mul, a);
|
||||
}
|
||||
// CONST_a * CONST_b => CONST_c
|
||||
{
|
||||
TNode<IntPtrT> a = m.IntPtrConstant(100);
|
||||
TNode<IntPtrT> b = m.IntPtrConstant(5);
|
||||
TNode<IntPtrT> c = m.IntPtrMul(a, b);
|
||||
EXPECT_THAT(c, IsIntPtrConstant(500));
|
||||
}
|
||||
// x * 2^CONST => x << CONST
|
||||
{
|
||||
Node* a = m.Parameter(0);
|
||||
TNode<IntPtrT> b = m.IntPtrConstant(1 << 3);
|
||||
TNode<WordT> c = m.IntPtrMul(a, b);
|
||||
EXPECT_THAT(c, IsWordShl(a, IsIntPtrConstant(3)));
|
||||
}
|
||||
// 2^CONST * x => x << CONST
|
||||
{
|
||||
TNode<IntPtrT> a = m.IntPtrConstant(1 << 3);
|
||||
Node* b = m.Parameter(0);
|
||||
TNode<WordT> c = m.IntPtrMul(a, b);
|
||||
EXPECT_THAT(c, IsWordShl(b, IsIntPtrConstant(3)));
|
||||
}
|
||||
}
|
||||
|
||||
TARGET_TEST_F(CodeAssemblerTest, IntPtrDiv) {
|
||||
CodeAssemblerTestState state(this);
|
||||
CodeAssemblerForTest m(&state);
|
||||
{
|
||||
TNode<IntPtrT> a = m.UncheckedCast<IntPtrT>(m.Parameter(0));
|
||||
TNode<IntPtrT> b = m.IntPtrConstant(100);
|
||||
TNode<IntPtrT> div = m.IntPtrDiv(a, b);
|
||||
EXPECT_THAT(div, IsIntPtrDiv(Matcher<Node*>(a), Matcher<Node*>(b)));
|
||||
}
|
||||
// x / 1 => x
|
||||
{
|
||||
TNode<IntPtrT> a = m.UncheckedCast<IntPtrT>(m.Parameter(0));
|
||||
TNode<IntPtrT> b = m.IntPtrConstant(1);
|
||||
TNode<IntPtrT> div = m.IntPtrDiv(a, b);
|
||||
EXPECT_THAT(div, a);
|
||||
}
|
||||
// CONST_a / CONST_b => CONST_c
|
||||
{
|
||||
TNode<IntPtrT> a = m.IntPtrConstant(100);
|
||||
TNode<IntPtrT> b = m.IntPtrConstant(5);
|
||||
TNode<IntPtrT> div = m.IntPtrDiv(a, b);
|
||||
EXPECT_THAT(div, IsIntPtrConstant(20));
|
||||
}
|
||||
{
|
||||
TNode<IntPtrT> a = m.IntPtrConstant(100);
|
||||
TNode<IntPtrT> b = m.IntPtrConstant(5);
|
||||
TNode<IntPtrT> div = m.IntPtrDiv(a, b);
|
||||
EXPECT_THAT(div, IsIntPtrConstant(20));
|
||||
}
|
||||
// x / 2^CONST => x >> CONST
|
||||
{
|
||||
TNode<IntPtrT> a = m.UncheckedCast<IntPtrT>(m.Parameter(0));
|
||||
TNode<IntPtrT> b = m.IntPtrConstant(1 << 3);
|
||||
TNode<IntPtrT> div = m.IntPtrDiv(a, b);
|
||||
EXPECT_THAT(div, IsWordSar(Matcher<Node*>(a), IsIntPtrConstant(3)));
|
||||
}
|
||||
}
|
||||
|
||||
TARGET_TEST_F(CodeAssemblerTest, WordShl) {
|
||||
CodeAssemblerTestState state(this);
|
||||
CodeAssemblerForTest m(&state);
|
||||
{
|
||||
Node* a = m.Parameter(0);
|
||||
TNode<WordT> add = m.WordShl(a, 10);
|
||||
EXPECT_THAT(add, IsWordShl(a, IsIntPtrConstant(10)));
|
||||
}
|
||||
// x << 0 => x
|
||||
{
|
||||
Node* a = m.Parameter(0);
|
||||
TNode<WordT> add = m.WordShl(a, 0);
|
||||
EXPECT_THAT(add, a);
|
||||
}
|
||||
// CONST_a << CONST_b => CONST_c
|
||||
{
|
||||
TNode<IntPtrT> a = m.IntPtrConstant(1024);
|
||||
TNode<WordT> shl = m.WordShl(a, 2);
|
||||
EXPECT_THAT(shl, IsIntPtrConstant(4096));
|
||||
}
|
||||
}
|
||||
|
||||
TARGET_TEST_F(CodeAssemblerTest, WordShr) {
|
||||
CodeAssemblerTestState state(this);
|
||||
CodeAssemblerForTest m(&state);
|
||||
{
|
||||
Node* a = m.Parameter(0);
|
||||
TNode<WordT> shr = m.WordShr(a, 10);
|
||||
EXPECT_THAT(shr, IsWordShr(a, IsIntPtrConstant(10)));
|
||||
}
|
||||
// x >> 0 => x
|
||||
{
|
||||
Node* a = m.Parameter(0);
|
||||
TNode<WordT> shr = m.WordShr(a, 0);
|
||||
EXPECT_THAT(shr, a);
|
||||
}
|
||||
// +CONST_a >> CONST_b => CONST_c
|
||||
{
|
||||
TNode<IntPtrT> a = m.IntPtrConstant(4096);
|
||||
TNode<IntPtrT> shr = m.WordShr(a, 2);
|
||||
EXPECT_THAT(shr, IsIntPtrConstant(1024));
|
||||
}
|
||||
// -CONST_a >> CONST_b => CONST_c
|
||||
{
|
||||
TNode<IntPtrT> a = m.IntPtrConstant(-1234);
|
||||
TNode<IntPtrT> shr = m.WordShr(a, 2);
|
||||
EXPECT_THAT(shr, IsIntPtrConstant(static_cast<uintptr_t>(-1234) >> 2));
|
||||
}
|
||||
}
|
||||
|
||||
TARGET_TEST_F(CodeAssemblerTest, WordSar) {
|
||||
CodeAssemblerTestState state(this);
|
||||
CodeAssemblerForTest m(&state);
|
||||
{
|
||||
Node* a = m.Parameter(0);
|
||||
TNode<WordT> sar = m.WordSar(a, m.IntPtrConstant(10));
|
||||
EXPECT_THAT(sar, IsWordSar(a, IsIntPtrConstant(10)));
|
||||
}
|
||||
// x >>> 0 => x
|
||||
{
|
||||
Node* a = m.Parameter(0);
|
||||
TNode<WordT> sar = m.WordSar(a, m.IntPtrConstant(0));
|
||||
EXPECT_THAT(sar, a);
|
||||
}
|
||||
// +CONST_a >>> CONST_b => CONST_c
|
||||
{
|
||||
TNode<IntPtrT> a = m.IntPtrConstant(4096);
|
||||
TNode<IntPtrT> sar = m.WordSar(a, m.IntPtrConstant(2));
|
||||
EXPECT_THAT(sar, IsIntPtrConstant(1024));
|
||||
}
|
||||
// -CONST_a >>> CONST_b => CONST_c
|
||||
{
|
||||
TNode<IntPtrT> a = m.IntPtrConstant(-1234);
|
||||
TNode<IntPtrT> sar = m.WordSar(a, m.IntPtrConstant(2));
|
||||
EXPECT_THAT(sar, IsIntPtrConstant(static_cast<intptr_t>(-1234) >> 2));
|
||||
}
|
||||
}
|
||||
|
||||
TARGET_TEST_F(CodeAssemblerTest, WordOr) {
|
||||
CodeAssemblerTestState state(this);
|
||||
CodeAssemblerForTest m(&state);
|
||||
{
|
||||
Node* a = m.Parameter(0);
|
||||
TNode<WordT> z = m.WordOr(a, m.IntPtrConstant(8));
|
||||
EXPECT_THAT(z, IsWordOr(a, IsIntPtrConstant(8)));
|
||||
}
|
||||
// x | 0 => x
|
||||
{
|
||||
Node* a = m.Parameter(0);
|
||||
TNode<WordT> z = m.WordOr(a, m.IntPtrConstant(0));
|
||||
EXPECT_THAT(z, a);
|
||||
}
|
||||
// 0 | x => x
|
||||
{
|
||||
Node* a = m.Parameter(0);
|
||||
TNode<WordT> z = m.WordOr(m.IntPtrConstant(0), a);
|
||||
EXPECT_THAT(z, a);
|
||||
}
|
||||
// CONST_a | CONST_b => CONST_c
|
||||
{
|
||||
TNode<IntPtrT> a = m.IntPtrConstant(3);
|
||||
TNode<WordT> b = m.WordOr(a, m.IntPtrConstant(7));
|
||||
EXPECT_THAT(b, IsIntPtrConstant(7));
|
||||
}
|
||||
}
|
||||
|
||||
TARGET_TEST_F(CodeAssemblerTest, WordAnd) {
|
||||
CodeAssemblerTestState state(this);
|
||||
CodeAssemblerForTest m(&state);
|
||||
{
|
||||
Node* a = m.Parameter(0);
|
||||
TNode<WordT> z = m.WordAnd(a, m.IntPtrConstant(8));
|
||||
EXPECT_THAT(z, IsWordAnd(a, IsIntPtrConstant(8)));
|
||||
}
|
||||
// CONST_a & CONST_b => CONST_c
|
||||
{
|
||||
TNode<IntPtrT> a = m.IntPtrConstant(3);
|
||||
TNode<IntPtrT> b = m.WordAnd(a, m.IntPtrConstant(7));
|
||||
EXPECT_THAT(b, IsIntPtrConstant(3));
|
||||
}
|
||||
}
|
||||
|
||||
TARGET_TEST_F(CodeAssemblerTest, WordXor) {
|
||||
CodeAssemblerTestState state(this);
|
||||
CodeAssemblerForTest m(&state);
|
||||
{
|
||||
Node* a = m.Parameter(0);
|
||||
TNode<WordT> z = m.WordXor(a, m.IntPtrConstant(8));
|
||||
EXPECT_THAT(z, IsWordXor(a, IsIntPtrConstant(8)));
|
||||
}
|
||||
// CONST_a ^ CONST_b => CONST_c
|
||||
{
|
||||
TNode<IntPtrT> a = m.IntPtrConstant(3);
|
||||
TNode<WordT> b = m.WordXor(a, m.IntPtrConstant(7));
|
||||
EXPECT_THAT(b, IsIntPtrConstant(4));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace compiler
|
||||
} // namespace internal
|
||||
} // namespace v8
|
@ -1,37 +0,0 @@
|
||||
// Copyright 2017 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef V8_UNITTESTS_COMPILER_CODE_ASSEMBLER_UNITTEST_H_
|
||||
#define V8_UNITTESTS_COMPILER_CODE_ASSEMBLER_UNITTEST_H_
|
||||
|
||||
#include "src/compiler/code-assembler.h"
|
||||
#include "test/unittests/test-utils.h"
|
||||
#include "testing/gmock-support.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
namespace compiler {
|
||||
|
||||
class CodeAssemblerTest : public TestWithIsolateAndZone {
|
||||
public:
|
||||
CodeAssemblerTest() = default;
|
||||
~CodeAssemblerTest() override = default;
|
||||
};
|
||||
|
||||
class CodeAssemblerTestState : public CodeAssemblerState {
|
||||
public:
|
||||
explicit CodeAssemblerTestState(CodeAssemblerTest* test);
|
||||
};
|
||||
|
||||
class CodeAssemblerForTest : public CodeAssembler {
|
||||
public:
|
||||
explicit CodeAssemblerForTest(CodeAssemblerTestState* state)
|
||||
: CodeAssembler(state) {}
|
||||
};
|
||||
|
||||
} // namespace compiler
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
||||
#endif // V8_UNITTESTS_COMPILER_CODE_ASSEMBLER_UNITTEST_H_
|
Loading…
Reference in New Issue
Block a user