5#ifndef V8_COMPILER_GRAPH_ASSEMBLER_H_
6#define V8_COMPILER_GRAPH_ASSEMBLER_H_
31#define PURE_ASSEMBLER_MACH_UNOP_LIST(V) \
32 V(BitcastFloat32ToInt32) \
33 V(BitcastFloat64ToInt64) \
34 V(BitcastInt32ToFloat32) \
35 V(BitcastWord32ToWord64) \
36 V(BitcastInt64ToFloat64) \
37 V(ChangeFloat32ToFloat64) \
38 V(ChangeFloat64ToInt32) \
39 V(ChangeFloat64ToInt64) \
40 V(ChangeFloat64ToUint32) \
41 V(ChangeFloat64ToUint64) \
42 V(ChangeInt32ToFloat64) \
43 V(ChangeInt32ToInt64) \
44 V(ChangeInt64ToFloat64) \
45 V(ChangeUint32ToFloat64) \
46 V(ChangeUint32ToUint64) \
48 V(Float64ExtractHighWord32) \
49 V(Float64ExtractLowWord32) \
50 V(Float64SilenceNaN) \
51 V(RoundFloat64ToInt32) \
52 V(RoundInt32ToFloat32) \
53 V(TruncateFloat64ToFloat32) \
54 V(TruncateFloat64ToWord32) \
55 V(TruncateInt64ToInt32) \
56 V(TryTruncateFloat64ToInt64) \
57 V(TryTruncateFloat64ToUint64) \
58 V(TryTruncateFloat64ToInt32) \
59 V(TryTruncateFloat64ToUint32) \
60 V(Word32ReverseBytes) \
63#define PURE_ASSEMBLER_MACH_BINOP_LIST(V, T) \
67 V(Float64InsertHighWord32) \
68 V(Float64InsertLowWord32) \
70 V(Float64LessThanOrEqual) \
77 T(Int32LessThanOrEqual, BoolT, Int32T, Int32T) \
86 T(Uint32LessThan, BoolT, Uint32T, Uint32T) \
87 T(Uint32LessThanOrEqual, BoolT, Uint32T, Uint32T) \
88 T(Uint64LessThan, BoolT, Uint64T, Uint64T) \
89 T(Uint64LessThanOrEqual, BoolT, Uint64T, Uint64T) \
91 T(Word32And, Word32T, Word32T, Word32T) \
92 T(Word32Equal, BoolT, Word32T, Word32T) \
93 T(Word32Or, Word32T, Word32T, Word32T) \
95 V(Word32SarShiftOutZeros) \
97 T(Word32Shr, Word32T, Word32T, Word32T) \
103 V(Word64SarShiftOutZeros) \
111 V(WordSarShiftOutZeros) \
116#define CHECKED_ASSEMBLER_MACH_BINOP_LIST(V) \
117 V(Int32AddWithOverflow) \
118 V(Int64AddWithOverflow) \
121 V(Int32MulWithOverflow) \
122 V(Int64MulWithOverflow) \
123 V(Int32SubWithOverflow) \
124 V(Int64SubWithOverflow) \
132#define JSGRAPH_SINGLETON_CONSTANT_LIST(V) \
133 V(AllocateInOldGenerationStub, InstructionStream) \
134 V(AllocateInYoungGenerationStub, InstructionStream) \
135 IF_WASM(V, WasmAllocateInYoungGenerationStub, InstructionStream) \
136 IF_WASM(V, WasmAllocateInOldGenerationStub, InstructionStream) \
139 V(EmptyString, String) \
140 V(ExternalObjectMap, Map) \
142 V(FixedArrayMap, Map) \
143 V(FixedDoubleArrayMap, Map) \
144 V(WeakFixedArrayMap, Map) \
145 V(HeapNumberMap, Map) \
146 V(MinusOne, Number) \
148 V(NoContext, Object) \
152 V(ToNumberBuiltin, InstructionStream) \
153 V(PlainPrimitiveToNumberBuiltin, InstructionStream) \
155 V(Undefined, Undefined) \
165template <
size_t VarCount>
167 template <
typename T>
168 using Array = std::array<T, VarCount>;
179 template <
typename T>
190template <
size_t VarCount>
191class GraphAssemblerLabel {
193 template <
typename T>
202 template <
typename T>
247template <
typename T,
typename Enable,
typename... Us>
251template <
typename T,
typename... Us>
253 T,
std::enable_if_t<std::conjunction_v<std::is_assignable<T&, Us>...>>,
259template <
typename T,
typename U>
265template <
typename... Vars>
269template <
typename... Reps>
284 std::optional<NodeChangedCallback> node_changed_callback = std::nullopt,
285 bool mark_loop_exits =
false);
290 void InitializeEffectControl(
Node* effect,
Node* control);
293 template <
typename... Reps>
298 type, loop_nesting_level_, std::move(reps_array));
308 template <
typename... Reps>
310 return MakeLabelFor(GraphAssemblerLabelType::kNonDeferred, reps...);
314 template <
typename... Reps>
316 return MakeLabelFor(GraphAssemblerLabelType::kLoop, reps...);
320 template <
typename... Reps>
322 return MakeLabelFor(GraphAssemblerLabelType::kDeferred, reps...);
326 Node* IntPtrConstant(intptr_t value);
328 Node* Int32Constant(int32_t value);
330 Node* Int64Constant(int64_t value);
331 Node* Uint64Constant(uint64_t value);
332 Node* UniqueIntPtrConstant(intptr_t value);
333 Node* Float64Constant(
double value);
337 Node* Projection(
int index,
Node* value,
Node* ctrl =
nullptr);
339 Node* Parameter(
int index);
341 Node* LoadFramePointer();
343 Node* LoadRootRegister();
345#if V8_ENABLE_WEBASSEMBLY
346 Node* LoadStackPointer();
350 Node* LoadHeapNumberValue(
Node* heap_number);
352#define PURE_UNOP_DECL(Name) Node* Name(Node* input);
356#define BINOP_DECL(Name) Node* Name(Node* left, Node* right);
357#define BINOP_DECL_TNODE(Name, Result, Left, Right) \
358 TNode<Result> Name(SloppyTNode<Left> left, SloppyTNode<Right> right);
362#undef BINOP_DECL_TNODE
363 TNode<BoolT> UintPtrLessThan(TNode<UintPtrT> left, TNode<UintPtrT> right);
364 TNode<BoolT> UintPtrLessThanOrEqual(TNode<UintPtrT> left,
365 TNode<UintPtrT> right);
366 TNode<UintPtrT> UintPtrAdd(TNode<UintPtrT> left, TNode<UintPtrT> right);
367 TNode<UintPtrT> UintPtrSub(TNode<UintPtrT> left, TNode<UintPtrT> right);
368 TNode<UintPtrT> UintPtrDiv(TNode<UintPtrT> left, TNode<UintPtrT> right);
369 TNode<UintPtrT> ChangeUint32ToUintPtr(SloppyTNode<Uint32T> value);
372 Node* PackMapWord(TNode<Map> map);
373 TNode<Map> UnpackMapWord(Node* map_word);
375 TNode<Map> LoadMap(Node*
object);
383 Node* UnreachableWithoutConnectToEnd();
385 Node* IntPtrEqual(Node* left, Node* right);
386 Node* TaggedEqual(Node* left, Node* right);
388 Node* SmiSub(Node* left, Node* right);
389 Node* SmiLessThan(Node* left, Node* right);
391 Node* Float64RoundDown(Node* value);
392 Node* Float64RoundTruncate(Node* value);
393 Node* TruncateFloat64ToInt64(Node* value, TruncateKind
kind);
395 Node* BitcastWordToTagged(Node* value);
396 Node* BitcastWordToTaggedSigned(Node* value);
397 Node* BitcastTaggedToWord(Node* value);
398 Node* BitcastTaggedToWordForTagAndSmiBits(Node* value);
399 Node* BitcastMaybeObjectToWord(Node* value);
401 Node* TypeGuard(Type type, Node* value);
402 template <
typename T>
408 TNode<RawPtrT> StackSlot(
int size,
int alignment,
bool is_tagged =
false);
410 Node* AdaptLocalArgument(
Node* argument);
439 template <
typename... Args>
442 template <
typename... Args>
444 void TailCall(
const CallDescriptor* call_descriptor,
int inputs_size,
448 template <
size_t VarCount>
451 template <
typename... Vars>
460 template <
typename... Vars>
465 template <
typename... Vars>
470 template <
typename... Vars>
475 template <
typename... Vars>
485 template <
typename... Vars>
495 template <
typename... Vars>
501 template <
typename... Vars>
506 template <
typename... Vars>
516 return control() !=
nullptr;
521 if (node->op()->EffectOutputCount() > 0) {
524 if (node->op()->ControlOutputCount() > 0) {
533 template <
typename T>
538 void ConnectUnreachableToEnd();
547 inline_reducers_.push_back(reducer);
558 template <
typename... Vars>
583 : previous_loop_nesting_level_(gasm->loop_nesting_level_),
589 gasm_->loop_nesting_level_--;
590 DCHECK_EQ(
gasm_->loop_nesting_level_, previous_loop_nesting_level_);
600 : internal_scope_(gasm),
602 loop_header_label_(gasm->MakeLoopLabel(Reps...)) {
607 gasm_->loop_nesting_level_);
612 gasm_->loop_nesting_level_);
613 gasm_->loop_headers_.pop_back();
617 return &loop_header_label_;
646 template <
typename... Vars>
669 int loop_nesting_level_ = 0;
677template <
size_t VarCount>
681 return bindings_[
index];
684template <
typename... Vars>
691 const int merged_count =
static_cast<int>(
label->merged_count_);
693 const size_t var_count =
label->Count();
694 NodeArray var_array{vars...};
712 for (
size_t i = 0;
i < var_count;
i++) {
719 if (
label->IsLoop()) {
720 if (merged_count == 0) {
729 for (
size_t i = 0;
i < var_count;
i++) {
732 var_array[
i], var_array[
i],
label->control_);
739 for (
size_t i = 0;
i < var_count;
i++) {
740 label->bindings_[
i]->ReplaceInput(1, var_array[
i]);
747 if (merged_count == 0) {
751 for (
size_t i = 0;
i < var_count;
i++) {
752 label->bindings_[
i] = var_array[
i];
754 }
else if (merged_count == 1) {
759 effect(),
label->control_);
760 for (
size_t i = 0;
i < var_count;
i++) {
763 var_array[
i],
label->control_);
770 common()->Merge(merged_count + 1));
773 label->effect_->ReplaceInput(merged_count,
effect());
776 common()->EffectPhi(merged_count + 1));
778 for (
size_t i = 0;
i < var_count;
i++) {
780 label->bindings_[
i]->ReplaceInput(merged_count, var_array[
i]);
784 common()->Phi(
label->representations_[
i], merged_count + 1));
795 label->merged_count_++;
798template <
size_t VarCount>
810 if (
label->merged_count_ > 1 ||
label->IsLoop()) {
813 for (
size_t i = 0;
i <
label->Count();
i++) {
823template <
typename... Vars>
828 if (if_true->IsDeferred() != if_false->IsDeferred()) {
836template <
typename... Vars>
845template <
typename... Vars>
854template <
typename... Vars>
862template <
typename... Vars>
882template <
typename... Vars>
893template <
typename... Vars>
906template <
typename... Vars>
919template <
typename... Vars>
928template <
typename... Vars>
936template <
typename... Args>
943template <
typename... Args>
949 return Call(op, size, args_array);
959 std::optional<NodeChangedCallback> node_changed_callback = std::nullopt,
960 bool mark_loop_exits =
false)
965 outermost_catch_scope_(
CatchScope::Outermost(zone)),
966 catch_scope_(&outermost_catch_scope_) {
967 outermost_catch_scope_.set_gasm(
this);
974 Node* CEntryStubConstant(
int result_size);
976#define SINGLETON_CONST_DECL(Name, Type) TNode<Type> Name##Constant();
978#undef SINGLETON_CONST_DECL
980#define SINGLETON_CONST_TEST_DECL(Name, ...) \
981 TNode<Boolean> Is##Name(TNode<Object> value);
983#undef SINGLETON_CONST_TEST_DECL
985 Node* Allocate(AllocationType allocation, Node* size);
986 TNode<Map> LoadMap(TNode<HeapObject>
object);
987 Node* LoadField(FieldAccess
const&, Node*
object);
988 template <
typename T>
997 template <
typename T>
1008 Node* ClearPendingMessage();
1010 void TransitionAndStoreElement(
MapRef double_map,
MapRef fast_map,
1036 Node* CheckNumberFitsInt32(Node* value,
const FeedbackSource& feedback = {});
1037 Node* CheckIf(Node* cond, DeoptimizeReason reason,
1038 const FeedbackSource& feedback = {});
1039 Node*
Assert(Node* cond,
const char* condition_string =
"",
1040 const char* file =
"",
int line = -1);
1041 void Assert(TNode<Word32T> cond,
const char* condition_string =
"",
1042 const char* file =
"",
int line = -1);
1043 TNode<Boolean> NumberIsFloat64Hole(TNode<Number> value);
1044 TNode<Boolean> ToBoolean(TNode<Object> value);
1045 TNode<Object> ConvertTaggedHoleToUndefined(TNode<Object> value);
1046 TNode<FixedArrayBase> MaybeGrowFastElements(ElementsKind
kind,
1047 const FeedbackSource& feedback,
1048 TNode<JSArray> array,
1049 TNode<FixedArrayBase> elements,
1051 TNode<Number> old_length);
1052 Node* StringCharCodeAt(TNode<String>
string, TNode<Number>
position);
1053 TNode<String> StringFromSingleCharCode(TNode<Number> code);
1054 TNode<Object> DoubleArrayMax(TNode<JSArray> array);
1055 TNode<Object> DoubleArrayMin(TNode<JSArray> array);
1061 TNode<Number> ArrayBufferViewByteLength(
1062 TNode<JSArrayBufferView> array_buffer_view, InstanceType instance_type,
1063 std::set<ElementsKind> elements_kinds_candidates, TNode<Context> context);
1067 TNode<Word32T> ArrayBufferDetachedBit(TNode<HeapObject> buffer);
1068 TNode<Word32T> ArrayBufferViewDetachedBit(
1069 TNode<JSArrayBufferView> array_buffer_view);
1075 TNode<Number> TypedArrayLength(
1076 TNode<JSTypedArray> typed_array,
1077 std::set<ElementsKind> elements_kinds_candidates, TNode<Context> context);
1080 void CheckIfTypedArrayWasDetachedOrOutOfBounds(
1081 TNode<JSTypedArray> typed_array,
1082 std::set<ElementsKind> elements_kinds_candidates,
1083 const FeedbackSource& feedback);
1084 TNode<Uint32T> LookupByteShiftForElementsKind(TNode<Uint32T> elements_kind);
1085 TNode<Uint32T> LookupByteSizeForElementsKind(TNode<Uint32T> elements_kind);
1087 TNode<Object> JSCallRuntime1(
1088 Runtime::FunctionId function_id, TNode<Object> arg0,
1089 TNode<Context> context, std::optional<FrameState> frame_state,
1090 Operator::Properties properties = Operator::kNoProperties);
1091 TNode<Object> JSCallRuntime2(Runtime::FunctionId function_id,
1092 TNode<Object> arg0, TNode<Object> arg1,
1093 TNode<Context> context, FrameState frame_state);
1094 Node* Chained(
const Operator* op, Node* input);
1100 return jsgraph()->simplified();
1104 template <
typename T,
typename U>
1108 graph()->NewNode(common()->EnterMachineGraph(use_info), input));
1111 template <
typename T,
typename U>
1115 return AddNode<T>(
graph()->NewNode(
1116 common()->ExitMachineGraph(output_representation, output_type), input));
1133 if_exception_nodes_(zone) {
1135 gasm_->catch_scope_ =
this;
1143 return {zone, gasm};
1163 return !if_exception_nodes_.empty();
1168 if_exception_nodes_.push_back(if_exception);
1174 DCHECK(has_exceptional_control_flow());
1176 const int size =
static_cast<int>(if_exception_nodes_.size());
1180 Node* e = if_exception_nodes_.at(0);
1187 Node* merge =
gasm_->graph()->NewNode(
gasm_->common()->Merge(size),
1188 size, if_exception_nodes_.data());
1192 if_exception_nodes_.push_back(merge);
1193 const int size_with_merge =
1194 static_cast<int>(if_exception_nodes_.size());
1196 Node* ephi =
gasm_->graph()->NewNode(
gasm_->common()->EffectPhi(size),
1198 if_exception_nodes_.data());
1200 gasm_->common()->Phi(MachineRepresentation::kTagged, size),
1201 size_with_merge, if_exception_nodes_.data());
1202 if_exception_nodes_.pop_back();
1205 *effect_out =
Effect(ephi);
1206 *control_out =
Control(merge);
1213 bool has_handler_ =
false;
1228 if (catch_scope()->has_handler()) {
1232 Node* if_exception =
1233 graph()->NewNode(common()->IfException(), effect(), control());
1234 catch_scope()->RegisterIfExceptionNode(if_exception);
1237 AddNode(
graph()->NewNode(common()->IfSuccess(), control()));
1253 negate_cond_(negate_cond),
1254 initial_effect_(gasm->effect()),
1255 initial_control_(gasm->control()) {}
1259 hint_ = BranchHint::kTrue;
1264 hint_ = BranchHint::kFalse;
1285 DCHECK(then_body_ || else_body_);
1287 if (negate_cond_) std::swap(then_body_, else_body_);
1289 auto if_true = (hint_ == BranchHint::kFalse) ?
gasm_->MakeDeferredLabel()
1290 :
gasm_->MakeLabel();
1291 auto if_false = (hint_ == BranchHint::kTrue) ?
gasm_->MakeDeferredLabel()
1292 :
gasm_->MakeLabel();
1293 auto merge =
gasm_->MakeLabel();
1294 gasm_->Branch(cond_, &if_true, &if_false);
1296 gasm_->Bind(&if_true);
1297 if (then_body_) then_body_();
1298 if (
gasm_->HasActiveBlock())
gasm_->Goto(&merge);
1300 gasm_->Bind(&if_false);
1301 if (else_body_) else_body_();
1302 if (
gasm_->HasActiveBlock())
gasm_->Goto(&merge);
1304 gasm_->Bind(&merge);
1324 template <
typename T,
typename Cond>
1330 :
gasm_(gasm), cond_(cond), negate_cond_(negate_cond) {}
1334 hint_ = BranchHint::kTrue;
1340 hint_ = BranchHint::kFalse;
1357 if (negate_cond_) std::swap(then_body_, else_body_);
1359 auto if_true = (hint_ == BranchHint::kFalse) ?
gasm_->MakeDeferredLabel()
1360 :
gasm_->MakeLabel();
1361 auto if_false = (hint_ == BranchHint::kTrue) ?
gasm_->MakeDeferredLabel()
1362 :
gasm_->MakeLabel();
1363 auto merge =
gasm_->MakeLabel(PhiMachineRepresentationOf<T>);
1364 if constexpr (std::is_same_v<Cond, Word32T>) {
1365 gasm_->MachineBranch(cond_, &if_true, &if_false, hint_);
1367 static_assert(std::is_same_v<Cond, Boolean>);
1368 if (hint_ != BranchHint::kNone) {
1369 gasm_->BranchWithHint(cond_, &if_true, &if_false, hint_);
1371 gasm_->Branch(cond_, &if_true, &if_false);
1375 gasm_->Bind(&if_true);
1376 TNode<T> then_result = then_body_();
1377 if (
gasm_->HasActiveBlock())
gasm_->Goto(&merge, then_result);
1379 gasm_->Bind(&if_false);
1380 TNode<T> else_result = else_body_();
1381 if (
gasm_->HasActiveBlock()) {
1382 gasm_->Goto(&merge, else_result);
1385 gasm_->Bind(&merge);
1386 return merge.template PhiAt<T>(0);
1391 MachineRepresentation::kTagged;
1401 template <
typename T>
1403 return {
this, cond,
false};
1405 template <
typename T>
1407 return {
this, cond,
true};
1409 template <
typename T>
1411 return {
this, cond,
false};
1413 template <
typename T>
1418 graph()->NewNode(common()->Select(T::kMachineRepresentation, hint,
1419 BranchSemantics::kMachine),
1420 cond, true_value, false_value)));
1424 Operator const* PlainPrimitiveToNumberOperator();
#define Assert(condition)
Isolate * isolate() const
static TNode UncheckedCast(compiler::Node *node)
const Operator * Call(const CallDescriptor *call_descriptor)
GraphAssemblerLabel(GraphAssemblerLabelType type, int loop_nesting_level, Array< MachineRepresentation > reps)
Node * PhiAt(size_t index)
const GraphAssemblerLabelType type_
typename Helper::template Array< T > Array
static constexpr bool kIsDynamic
const Array< MachineRepresentation > representations_
TNode< T > PhiAt(size_t index)
Array< Node * > bindings_
const int loop_nesting_level_
GraphAssembler *const gasm_
LoopScopeInternal(GraphAssembler *gasm)
const int previous_loop_nesting_level_
GraphAssembler *const gasm_
const LoopScopeInternal internal_scope_
LoopScope(GraphAssembler *gasm)
GraphAssemblerLabel< sizeof...(Reps)> * loop_header_label()
RestoreEffectControlScope(GraphAssembler *gasm)
~RestoreEffectControlScope()
GraphAssembler *const gasm_
detail::GraphAssemblerLabelForReps< Reps... > MakeLabel(Reps... reps)
void MergeState(detail::GraphAssemblerLabelForVars< Vars... > *label, Vars... vars)
void AddInlineReducer(Reducer *reducer)
virtual SimplifiedOperatorBuilder * simplified()
GraphAssemblerDynamicLabel MakeLabelFor(GraphAssemblerLabelType type, base::SmallVector< MachineRepresentation, 4 > reps)
void BranchWithHint(Node *condition, detail::GraphAssemblerLabelForVars< Vars... > *if_true, detail::GraphAssemblerLabelForVars< Vars... > *if_false, BranchHint hint, Vars...)
void BranchImpl(BranchSemantics semantics, Node *condition, GraphAssemblerLabel< sizeof...(Vars)> *if_true, GraphAssemblerLabel< sizeof...(Vars)> *if_false, BranchHint hint, Vars...)
V8_INLINE void UpdateEffectControlWith(Node *node)
std::optional< NodeChangedCallback > node_changed_callback_
ZoneVector< Reducer * > inline_reducers_
MachineGraph * mcgraph() const
MachineOperatorBuilder * machine() const
bool HasActiveBlock() const
constexpr bool Is64() const
detail::GraphAssemblerLabelForReps< Reps... > MakeLoopLabel(Reps... reps)
bool inline_reductions_blocked_
TNode< T > AddNode(Node *node)
const bool mark_loop_exits_
ZoneVector< Node ** > loop_headers_
TNode< Object > Call(const CallDescriptor *call_descriptor, int inputs_size, Node **inputs)
detail::GraphAssemblerLabelForReps< Reps... > MakeDeferredLabel(Reps... reps)
void GotoIf(Node *condition, detail::GraphAssemblerLabelForVars< Vars... > *label, BranchHint hint, Vars...)
void MachineBranch(TNode< Word32T > condition, GraphAssemblerLabel< sizeof...(Vars)> *if_true, GraphAssemblerLabel< sizeof...(Vars)> *if_false, BranchHint hint, Vars...)
TNode< T > TypeGuard(Type type, TNode< T > value)
BranchSemantics default_branch_semantics_
CommonOperatorBuilder * common() const
void JSBranch(TNode< Boolean > condition, GraphAssemblerLabel< sizeof...(Vars)> *if_true, GraphAssemblerLabel< sizeof...(Vars)> *if_false, BranchHint hint, Vars...)
void Bind(GraphAssemblerLabel< VarCount > *label)
void GotoIfNot(Node *condition, detail::GraphAssemblerLabelForVars< Vars... > *label, BranchHint hint, Vars...)
void Branch(Node *condition, detail::GraphAssemblerLabelForVars< Vars... > *if_true, detail::GraphAssemblerLabelForVars< Vars... > *if_false, Vars...)
void Goto(detail::GraphAssemblerLabelForVars< Vars... > *label, Vars...)
detail::GraphAssemblerLabelForReps< Reps... > MakeLabelFor(GraphAssemblerLabelType type, Reps... reps)
Node * AddNode(Node *node)
NodeVector if_exception_nodes_
void set_gasm(JSGraphAssembler *v)
void MergeExceptionalPaths(TNode< Object > *exception_out, Effect *effect_out, Control *control_out)
void RegisterIfExceptionNode(Node *if_exception)
CatchScope * parent() const
CatchScope(Zone *zone, JSGraphAssembler *gasm)
void set_has_handler(bool v)
bool is_outermost() const
static CatchScope Outermost(Zone *zone)
static CatchScope Inner(Zone *zone, JSGraphAssembler *gasm)
bool has_exceptional_control_flow() const
IfBuilder0 & Else(const VoidGenerator0 &body)
IfBuilder0 & operator=(const IfBuilder0 &)=delete
const TNode< Boolean > cond_
JSGraphAssembler *const gasm_
IfBuilder0 & ExpectTrue()
IfBuilder0 & ExpectFalse()
VoidGenerator0 then_body_
IfBuilder0(JSGraphAssembler *gasm, TNode< Boolean > cond, bool negate_cond)
const Effect initial_effect_
VoidGenerator0 else_body_
IfBuilder0 & Then(const VoidGenerator0 &body)
const Control initial_control_
IfBuilder0(const IfBuilder0 &)=delete
JSGraphAssembler *const gasm_
If1BodyFunction then_body_
V8_WARN_UNUSED_RESULT TNode< T > Value()
V8_WARN_UNUSED_RESULT IfBuilder1 & ExpectFalse()
V8_WARN_UNUSED_RESULT IfBuilder1 & ExpectTrue()
std::function< TNode< T >()> If1BodyFunction
IfBuilder1(JSGraphAssembler *gasm, TNode< Cond > cond, bool negate_cond)
const TNode< Cond > cond_
If1BodyFunction else_body_
V8_WARN_UNUSED_RESULT IfBuilder1 & Else(const If1BodyFunction &body)
V8_WARN_UNUSED_RESULT IfBuilder1 & Then(const If1BodyFunction &body)
std::function< TNode< Object >()> NodeGenerator0
JSGraphAssembler(JSHeapBroker *broker, JSGraph *jsgraph, Zone *zone, BranchSemantics branch_semantics, std::optional< NodeChangedCallback > node_changed_callback=std::nullopt, bool mark_loop_exits=false)
CatchScope outermost_catch_scope_
std::function< void()> VoidGenerator0
TNode< Object > MayThrow(const NodeGenerator0 &body)
Node * outermost_handler_
TNode< T > LoadField(FieldAccess const &access, TNode< HeapObject > object)
TNode< T > ExitMachineGraph(TNode< U > input, MachineRepresentation output_representation, Type output_type)
SetOncePointer< Operator const > to_number_operator_
TNode< T > LoadElement(ElementAccess const &access, TNode< HeapObject > object, TNode< Number > index)
IfBuilder1< T, Word32T > MachineSelectIf(TNode< Word32T > cond)
IfBuilder1< T, Boolean > SelectIf(TNode< Boolean > cond)
Isolate * isolate() const
CatchScope * catch_scope() const
IfBuilder1< T, Boolean > SelectIfNot(TNode< Boolean > cond)
CatchScope * catch_scope_
TNode< Number > NumberDivide(TNode< Number > lhs, TNode< Number > rhs)
TNode< Number > NumberFloor(TNode< Number > value)
TNode< T > MachineSelect(TNode< Word32T > cond, TNode< T > true_value, TNode< T > false_value, BranchHint hint=BranchHint::kNone)
JSOperatorBuilder * javascript() const
TNode< T > EnterMachineGraph(TNode< U > input, UseInfo use_info)
IfBuilder0 IfNot(TNode< Boolean > cond)
JSGraph * jsgraph() const
JSHeapBroker * broker() const
IfBuilder0 If(TNode< Boolean > cond)
Node * outermost_handler() const
SimplifiedOperatorBuilder * simplified() override
static void ChangeOp(Node *node, const Operator *new_op)
static Type GetType(const Node *node)
static bool IsTyped(const Node *node)
static void MergeControlToEnd(TFGraph *graph, CommonOperatorBuilder *common, Node *node)
static void SetType(Node *node, Type type)
int ControlInputCount() const
int EffectInputCount() const
Node * NewNode(const Operator *op, int input_count, Node *const *inputs, bool incomplete=false)
static Type Union(Type type1, Type type2, Zone *zone)
TypeCheckKind type_check() const
JSHeapBroker *const broker_
base::Vector< const DirectHandle< Object > > args
MaybeDirectHandle< Object > * exception_out
#define PURE_UNOP_DECL(Name)
#define BINOP_DECL_TNODE(Name, Result, Left, Right)
#define SINGLETON_CONST_TEST_DECL(Name,...)
#define PURE_ASSEMBLER_MACH_BINOP_LIST(V, T)
#define CHECKED_ASSEMBLER_MACH_BINOP_LIST(V)
#define SINGLETON_CONST_DECL(Name, Type)
#define PURE_ASSEMBLER_MACH_UNOP_LIST(V)
#define JSGRAPH_SINGLETON_CONSTANT_LIST(V)
ZoneVector< RpoNumber > & result
typename GraphAssemblerLabelForXHelper< MachineRepresentation, void, Reps... >::Type GraphAssemblerLabelForReps
typename GraphAssemblerLabelForXHelper< Node *, void, Vars... >::Type GraphAssemblerLabelForVars
constexpr size_t kGraphAssemblerLabelDynamicCount
GraphAssemblerLabel< detail::kGraphAssemblerLabelDynamicCount > GraphAssemblerDynamicLabel
std::function< void(Node *)> NodeChangedCallback
NumberConstant(std::numeric_limits< double >::quiet_NaN())) DEFINE_GETTER(EmptyStateValues
constexpr int kSystemPointerSize
void Terminate(Isolate *isolate)
i::Address Load(i::Address address)
BytecodeSequenceNode * parent_
#define DCHECK_NOT_NULL(val)
#define DCHECK(condition)
#define DCHECK_LT(v1, v2)
#define DCHECK_EQ(v1, v2)
#define DCHECK_GT(v1, v2)
#define V8_EXPORT_PRIVATE
static Array< Node * > InitNodeArray(const Array< MachineRepresentation > &reps)
static Array< Node * > InitNodeArray(const Array< MachineRepresentation > &reps)
static constexpr bool kIsDynamic
std::array< T, VarCount > Array
#define V8_WARN_UNUSED_RESULT