Commit 516b7809 authored by Igor Sheludko's avatar Igor Sheludko Committed by Commit Bot

[csa] Add statically typed CSA::BuildFastLoop()

... and the following helper methods:
- IntPtrOrSmiConstant
- IntPtrOrSmiXXX
- Increment
- Decrement

Bug: v8:9708
Change-Id: I9da8bba4da2012a873fd3f23972c678ff80eec21
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1798623Reviewed-by: 's avatarLeszek Swirski <leszeks@chromium.org>
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#63689}
parent 8d710631
......@@ -396,34 +396,22 @@ TNode<BInt> CodeStubAssembler::BIntConstant(int value) {
#endif
}
Node* CodeStubAssembler::IntPtrOrSmiConstant(int value, ParameterMode mode) {
if (mode == SMI_PARAMETERS) {
return SmiConstant(value);
} else {
DCHECK_EQ(INTPTR_PARAMETERS, mode);
return IntPtrConstant(value);
}
template <>
TNode<Smi> CodeStubAssembler::IntPtrOrSmiConstant<Smi>(int value) {
return SmiConstant(value);
}
TNode<BoolT> CodeStubAssembler::IntPtrOrSmiEqual(Node* left, Node* right,
ParameterMode mode) {
if (mode == SMI_PARAMETERS) {
return SmiEqual(CAST(left), CAST(right));
} else {
DCHECK_EQ(INTPTR_PARAMETERS, mode);
return IntPtrEqual(UncheckedCast<IntPtrT>(left),
UncheckedCast<IntPtrT>(right));
}
template <>
TNode<IntPtrT> CodeStubAssembler::IntPtrOrSmiConstant<IntPtrT>(int value) {
return IntPtrConstant(value);
}
TNode<BoolT> CodeStubAssembler::IntPtrOrSmiNotEqual(Node* left, Node* right,
ParameterMode mode) {
Node* CodeStubAssembler::IntPtrOrSmiConstant(int value, ParameterMode mode) {
if (mode == SMI_PARAMETERS) {
return SmiNotEqual(CAST(left), CAST(right));
return SmiConstant(value);
} else {
DCHECK_EQ(INTPTR_PARAMETERS, mode);
return WordNotEqual(UncheckedCast<IntPtrT>(left),
UncheckedCast<IntPtrT>(right));
return IntPtrConstant(value);
}
}
......@@ -8398,14 +8386,15 @@ void CodeStubAssembler::DecrementCounter(StatsCounter* counter, int delta) {
}
}
void CodeStubAssembler::Increment(Variable* variable, int value,
ParameterMode mode) {
DCHECK_IMPLIES(mode == INTPTR_PARAMETERS,
variable->rep() == MachineType::PointerRepresentation());
DCHECK_IMPLIES(mode == SMI_PARAMETERS, CanBeTaggedSigned(variable->rep()));
variable->Bind(IntPtrOrSmiAdd(variable->value(),
IntPtrOrSmiConstant(value, mode), mode));
template <typename TIndex>
void CodeStubAssembler::Increment(TVariable<TIndex>* variable, int value) {
*variable =
IntPtrOrSmiAdd(variable->value(), IntPtrOrSmiConstant<TIndex>(value));
}
template void CodeStubAssembler::Increment<Smi>(TVariable<Smi>* variable,
int value);
template void CodeStubAssembler::Increment<IntPtrT>(
TVariable<IntPtrT>* variable, int value);
void CodeStubAssembler::Use(Label* label) {
GotoIf(Word32Equal(Int32Constant(0), Int32Constant(1)), label);
......@@ -11278,8 +11267,27 @@ Node* CodeStubAssembler::BuildFastLoop(
ParameterMode parameter_mode, IndexAdvanceMode advance_mode) {
CSA_SLOW_ASSERT(this, MatchesParameterMode(start_index, parameter_mode));
CSA_SLOW_ASSERT(this, MatchesParameterMode(end_index, parameter_mode));
MachineRepresentation index_rep = ParameterRepresentation(parameter_mode);
VARIABLE(var, index_rep, start_index);
if (parameter_mode == SMI_PARAMETERS) {
return BuildFastLoop(vars, ReinterpretCast<Smi>(start_index),
ReinterpretCast<Smi>(end_index), body, increment,
advance_mode);
} else {
DCHECK_EQ(INTPTR_PARAMETERS, parameter_mode);
return BuildFastLoop(vars, ReinterpretCast<IntPtrT>(start_index),
ReinterpretCast<IntPtrT>(end_index), body, increment,
advance_mode);
}
}
template <typename TIndex>
TNode<TIndex> CodeStubAssembler::BuildFastLoop(const VariableList& vars,
TNode<TIndex> start_index,
TNode<TIndex> end_index,
const FastLoopBody& body,
int increment,
IndexAdvanceMode advance_mode) {
TVARIABLE(TIndex, var, start_index);
VariableList vars_copy(vars.begin(), vars.end(), zone());
vars_copy.push_back(&var);
Label loop(this, vars_copy);
......@@ -11291,8 +11299,7 @@ Node* CodeStubAssembler::BuildFastLoop(
// to force the loop header check at the end of the loop and branch forward to
// it from the pre-header). The extra branch is slower in the case that the
// loop actually iterates.
TNode<BoolT> first_check =
IntPtrOrSmiEqual(var.value(), end_index, parameter_mode);
TNode<BoolT> first_check = IntPtrOrSmiEqual(var.value(), end_index);
int32_t first_check_val;
if (ToInt32Constant(first_check, &first_check_val)) {
if (first_check_val) return var.value();
......@@ -11304,14 +11311,13 @@ Node* CodeStubAssembler::BuildFastLoop(
BIND(&loop);
{
if (advance_mode == IndexAdvanceMode::kPre) {
Increment(&var, increment, parameter_mode);
Increment(&var, increment);
}
body(var.value());
if (advance_mode == IndexAdvanceMode::kPost) {
Increment(&var, increment, parameter_mode);
Increment(&var, increment);
}
Branch(IntPtrOrSmiNotEqual(var.value(), end_index, parameter_mode), &loop,
&after_loop);
Branch(IntPtrOrSmiNotEqual(var.value(), end_index), &loop, &after_loop);
}
BIND(&after_loop);
return var.value();
......
......@@ -443,18 +443,45 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
Node* MatchesParameterMode(Node* value, ParameterMode mode);
#define PARAMETER_BINOP(OpName, IntPtrOpName, SmiOpName) \
Node* OpName(Node* a, Node* b, ParameterMode mode) { \
if (mode == SMI_PARAMETERS) { \
return SmiOpName(CAST(a), CAST(b)); \
} else { \
DCHECK_EQ(INTPTR_PARAMETERS, mode); \
return IntPtrOpName(a, b); \
} \
#define PARAMETER_BINOP(OpName, IntPtrOpName, SmiOpName) \
/* TODO(v8:9708): remove once all uses are ported. */ \
Node* OpName(Node* a, Node* b, ParameterMode mode) { \
if (mode == SMI_PARAMETERS) { \
return SmiOpName(CAST(a), CAST(b)); \
} else { \
DCHECK_EQ(INTPTR_PARAMETERS, mode); \
return IntPtrOpName(UncheckedCast<IntPtrT>(a), \
UncheckedCast<IntPtrT>(b)); \
} \
} \
TNode<Smi> OpName(TNode<Smi> a, TNode<Smi> b) { return SmiOpName(a, b); } \
TNode<IntPtrT> OpName(TNode<IntPtrT> a, TNode<IntPtrT> b) { \
return IntPtrOpName(a, b); \
}
// TODO(v8:9708): Define BInt operations once all uses are ported.
PARAMETER_BINOP(IntPtrOrSmiMin, IntPtrMin, SmiMin)
PARAMETER_BINOP(IntPtrOrSmiAdd, IntPtrAdd, SmiAdd)
PARAMETER_BINOP(IntPtrOrSmiSub, IntPtrSub, SmiSub)
#undef PARAMETER_BINOP
#define PARAMETER_BINOP(OpName, IntPtrOpName, SmiOpName) \
/* TODO(v8:9708): remove once all uses are ported. */ \
TNode<BoolT> OpName(Node* a, Node* b, ParameterMode mode) { \
if (mode == SMI_PARAMETERS) { \
return SmiOpName(CAST(a), CAST(b)); \
} else { \
DCHECK_EQ(INTPTR_PARAMETERS, mode); \
return IntPtrOpName(UncheckedCast<IntPtrT>(a), \
UncheckedCast<IntPtrT>(b)); \
} \
} \
TNode<BoolT> OpName(TNode<Smi> a, TNode<Smi> b) { return SmiOpName(a, b); } \
TNode<BoolT> OpName(TNode<IntPtrT> a, TNode<IntPtrT> b) { \
return IntPtrOpName(a, b); \
}
// TODO(v8:9708): Define BInt operations once all uses are ported.
PARAMETER_BINOP(IntPtrOrSmiEqual, IntPtrEqual, SmiEqual)
PARAMETER_BINOP(IntPtrOrSmiNotEqual, WordNotEqual, SmiNotEqual)
PARAMETER_BINOP(IntPtrOrSmiLessThan, IntPtrLessThan, SmiLessThan)
PARAMETER_BINOP(IntPtrOrSmiLessThanOrEqual, IntPtrLessThanOrEqual,
SmiLessThanOrEqual)
......@@ -507,9 +534,10 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
TNode<BInt> BIntConstant(int value);
template <typename TIndex>
TNode<TIndex> IntPtrOrSmiConstant(int value);
// TODO(v8:9708): remove once all uses are ported.
Node* IntPtrOrSmiConstant(int value, ParameterMode mode);
TNode<BoolT> IntPtrOrSmiEqual(Node* left, Node* right, ParameterMode mode);
TNode<BoolT> IntPtrOrSmiNotEqual(Node* left, Node* right, ParameterMode mode);
bool IsIntPtrOrSmiConstantZero(Node* test, ParameterMode mode);
bool TryGetIntPtrOrSmiConstantValue(Node* maybe_constant, int* value,
......@@ -2799,8 +2827,26 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
void IncrementCounter(StatsCounter* counter, int delta);
void DecrementCounter(StatsCounter* counter, int delta);
template <typename TIndex>
void Increment(TVariable<TIndex>* variable, int value = 1);
template <typename TIndex>
void Decrement(TVariable<TIndex>* variable, int value = 1) {
Increment(variable, -value);
}
// TODO(v8:9708): remove once all uses are ported.
void Increment(Variable* variable, int value = 1,
ParameterMode mode = INTPTR_PARAMETERS);
ParameterMode mode = INTPTR_PARAMETERS) {
if (mode == SMI_PARAMETERS) {
return Increment(static_cast<TVariable<Smi>*>(variable), value);
} else {
DCHECK(mode == INTPTR_PARAMETERS);
return Increment(static_cast<TVariable<IntPtrT>*>(variable), value);
}
}
// TODO(v8:9708): remove once all uses are ported.
void Decrement(Variable* variable, int value = 1,
ParameterMode mode = INTPTR_PARAMETERS) {
Increment(variable, -value, mode);
......@@ -3282,13 +3328,31 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
enum class IndexAdvanceMode { kPre, kPost };
// TODO(v8:9708): typify index parameter.
using FastLoopBody = std::function<void(Node* index)>;
template <typename TIndex>
TNode<TIndex> BuildFastLoop(
const VariableList& var_list, TNode<TIndex> start_index,
TNode<TIndex> end_index, const FastLoopBody& body, int increment,
IndexAdvanceMode advance_mode = IndexAdvanceMode::kPre);
template <typename TIndex>
TNode<TIndex> BuildFastLoop(
TNode<TIndex> start_index, TNode<TIndex> end_index,
const FastLoopBody& body, int increment,
IndexAdvanceMode advance_mode = IndexAdvanceMode::kPre) {
return BuildFastLoop(VariableList(0, zone()), start_index, end_index, body,
increment, advance_mode);
}
// TODO(v8:9708): remove once all uses are ported.
Node* BuildFastLoop(const VariableList& var_list, Node* start_index,
Node* end_index, const FastLoopBody& body, int increment,
ParameterMode parameter_mode,
IndexAdvanceMode advance_mode = IndexAdvanceMode::kPre);
// TODO(v8:9708): remove once all uses are ported.
Node* BuildFastLoop(Node* start_index, Node* end_index,
const FastLoopBody& body, int increment,
ParameterMode parameter_mode,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment