5#ifndef V8_COMPILER_STRING_BUILDER_OPTIMIZER_H_
6#define V8_COMPILER_STRING_BUILDER_OPTIMIZER_H_
10#include <unordered_map>
30class JSGraphAssembler;
33class SourcePositionTable;
221 bool BlockShouldFinalizeStringBuilders(
BasicBlock* block);
239 bool IsStringBuilderEnd(
Node* node);
244 bool IsNonLoopPhiStringBuilderEnd(
Node* node);
247 bool IsStringBuilderConcatInput(
Node* node);
249 bool ConcatIsInStringBuilder(
Node* node);
253 bool IsFirstConcatInStringBuilder(
Node* node);
273 kConfirmedInStringBuilder,
276 kEndStringBuilderLoopPhi,
288 static constexpr int kInvalidId = -1;
291 if (node->id() > status_.size()) {
292 return Status{kInvalidId, State::kInvalid};
294 return status_[node->id()];
300 if (node->id() >= status_.size()) {
304 constexpr double growth_factor = 1.1;
305 status_.resize(node->id() * growth_factor,
306 Status{kInvalidId, State::kUnvisited});
308 status_[node->id()] =
Status{id, state};
311 int id = state == State::kInvalid ? kInvalidId : GetStatus(node).id;
312 status_[node->id()] =
Status{id, state};
322 nullptr, kInvalidId,
false, OneOrTwoByteAnalysis::State::kUnknown};
325 bool StringBuilderIsValid(StringBuilder string_builder) {
326 return string_builder.
start !=
nullptr && string_builder.
id != kInvalidId &&
327 string_builder.has_loop_phi;
332 return node->opcode() == IrOpcode::kPhi &&
333 schedule()->block(node)->IsLoopHeader();
336 DCHECK(IsLoopPhi(loop_phi));
340 int GetStringBuilderIdForConcat(
Node* node);
341 void ReplaceConcatInputIfNeeded(
Node* node,
int input_idx);
342 bool CheckNodeUses(
Node* node,
Node* concat_child, Status status);
343 bool CheckPreviousNodeUses(
Node* child, Status status,
344 int input_if_loop_phi = 0);
345 int GetPhiPredecessorsCommonId(
Node* node);
347 void FinalizeStringBuilders();
351 static constexpr bool kAllowAnyStringOnTheRhs =
false;
357 unsigned int string_builder_count_ = 0;
ZoneVector< State > states_
State OneOrTwoByte(Node *node)
static State ConcatResultIsOneOrTwoByte(State a, State b)
OneOrTwoByteAnalysis(TFGraph *graph, Zone *zone, JSHeapBroker *broker)
std::optional< std::pair< int64_t, int64_t > > TryGetRange(Node *node)
void UpdateStatus(Node *node, State state)
JSHeapBroker * broker() const
ZoneVector< StringBuilder > string_builders_
void SetStatus(Node *node, State state, int id=kInvalidId)
bool IsLoopPhi(Node *node) const
ZoneVector< BasicBlock * > loop_headers_
JSGraph * jsgraph() const
ZoneVector< std::optional< ZoneVector< Node * > > > blocks_to_trimmings_map_
bool LoopContains(Node *loop_phi, Node *node)
ZoneVector< Status > status_
Schedule * schedule() const
Status GetStatus(Node *node) const
JSHeapBroker *const broker_
Schedule const *const schedule_
#define DCHECK_IMPLIES(v1, v2)
#define DCHECK_NE(v1, v2)
#define DCHECK(condition)
#define V8_EXPORT_PRIVATE
OneOrTwoByteAnalysis::State one_or_two_bytes