5#ifndef V8_MAGLEV_MAGLEV_INLINING_H_
6#define V8_MAGLEV_MAGLEV_INLINING_H_
27 void Run(
bool is_tracing_maglev_graphs_enabled) {
32 v8_flags.max_maglev_inlined_bytecode_size_cumulative) {
37 if (!call_site)
break;
40 if (
result.IsFail())
continue;
43 if (is_tracing_maglev_graphs_enabled &&
v8_flags.print_maglev_graphs &&
44 v8_flags.trace_maglev_inlining_verbose) {
45 std::cout <<
"\nAfter inlining "
53 if (is_tracing_maglev_graphs_enabled &&
v8_flags.print_maglev_graphs &&
54 !
v8_flags.trace_maglev_inlining_verbose) {
55 std::cout <<
"\nAfter inlining" << std::endl;
69 v8_flags.maglev_inlining_following_eager_order
71 [](
auto* site) { return site != nullptr; })
72 : std::ranges::max_element(
76 if (info1 == nullptr || info2 == nullptr) {
77 return info2 != nullptr;
96 if (!call_block || call_block->
is_dead()) {
102 if (
v8_flags.trace_maglev_inlining) {
103 std::cout <<
" non-eager inlining " << shared << std::endl;
109 &rem_handlers_in_call_block, call_node->exception_handler_info());
111 call_block->
Split(call_node, zone());
118 graph_->add_inlined_bytecode_size(bytecode.length());
128 caller_deopt_frame, inner_unit, call_node->
closure().
node(),
133 std::vector<BasicBlock*> saved_bb = TruncateGraphAt(call_block);
143 if (
result.IsDoneWithAbort()) {
146 for (
auto node : rem_nodes_in_call_block) {
147 node->set_owner(
nullptr);
150 for (
auto bb : saved_bb) {
153 RemovePredecessorFollowing(control_node, call_block);
157 RemoveUnreachableBlocks();
163 EnsureTagged(inner_graph_builder,
result.value());
170 control_node, rem_nodes_in_call_block);
173 std::move(rem_handlers_in_call_block));
178 [call_block, final_block](
BasicBlock* successor) {
179 UpdatePredecessorsOf(successor, call_block, final_block);
183 for (
auto bb : saved_bb) {
189 alloc->ForceEscaping();
191 alloc->set_is_returned_value_from_inline_call();
194 call_node->OverwriteWithIdentityTo(returned_value);
205 std::find(
graph_->blocks().begin(),
graph_->blocks().end(), block);
207 size_t index = std::distance(
graph_->blocks().begin(), it);
208 std::vector<BasicBlock*> saved_bb(
graph_->blocks().begin() + index + 1,
210 graph_->blocks().resize(index);
214 template <
class Node,
typename... Args>
216 std::initializer_list<ValueNode*> inputs,
220 DCHECK(!node->properties().can_eager_deopt());
221 DCHECK(!node->properties().can_lazy_deopt());
223 RegisterNode(builder, node);
235 switch (node->value_representation()) {
237 return AddNodeAtBlockEnd<Int32ToNumber>(builder, {node});
239 return AddNodeAtBlockEnd<Uint32ToNumber>(builder, {node});
241 return AddNodeAtBlockEnd<Float64ToTagged>(
244 return AddNodeAtBlockEnd<HoleyFloat64ToTagged>(
248 return AddNodeAtBlockEnd<IntPtrToNumber>(builder, {node});
256 if (!block->has_state()) {
257 DCHECK_EQ(block->predecessor(), prev_pred);
258 block->set_predecessor(new_pred);
261 for (
int i = 0;
i < block->predecessor_count();
i++) {
262 if (block->predecessor_at(
i) == prev_pred) {
263 block->state()->set_predecessor_at(
i, new_pred);
286 std::vector<bool> reachable_blocks(
graph_->max_block_id(),
false);
287 std::vector<BasicBlock*> worklist;
291 worklist.push_back(initial_bb);
292 reachable_blocks[initial_bb->
id()] =
true;
295 while (!worklist.empty()) {
299 for (
auto handler : current->exception_handlers()) {
300 if (!handler->HasExceptionHandler())
continue;
301 if (handler->ShouldLazyDeopt())
continue;
302 BasicBlock* catch_block = handler->catch_block();
303 if (!reachable_blocks[catch_block->
id()]) {
304 reachable_blocks[catch_block->
id()] =
true;
305 worklist.push_back(catch_block);
309 current->ForEachSuccessor([&](
BasicBlock* succ) {
310 if (!reachable_blocks[succ->
id()]) {
311 reachable_blocks[succ->
id()] =
true;
312 worklist.push_back(succ);
319 if (!reachable_blocks[bb->
id()])
return true;
void TruncateAt(ThreadedListBase *rem, T *v)
void Append(ThreadedListBase &&list)
void push_back(const T &value)
BasicBlock * backedge_predecessor() const
static void ForEachSuccessorFollowing(ControlNode *control, Func &&functor)
void ForEachSuccessor(Func &&functor) const
BasicBlock * predecessor_at(int i) const
ExceptionHandlerInfo::List & exception_handlers()
ControlNode * reset_control_node()
int predecessor_count() const
MergePointInterpreterFrameState * state() const
ZoneVector< Node * > Split(Node *node, Zone *zone)
compiler::SharedFunctionInfoRef shared_function_info() const
SourcePosition GetSourcePosition() const
const MaglevCompilationUnit & GetCompilationUnit() const
ZoneVector< MaglevCallSiteInfo * > & inlineable_calls()
ZoneVector< OptimizedCompilationInfo::InlinedFunctionHolder > & inlined_functions()
int total_inlined_bytecode_size() const
compiler::JSHeapBroker * broker() const
static MaglevCompilationUnit * NewInner(Zone *zone, const MaglevCompilationUnit *caller, compiler::SharedFunctionInfoRef shared_function_info, compiler::FeedbackCellRef feedback_cell)
ZoneVector< Node * > & node_buffer()
ReduceResult BuildInlineFunction(SourcePosition call_site_position, ValueNode *context, ValueNode *function, ValueNode *new_target)
MaglevGraphLabeller * graph_labeller() const
DeoptFrame * AddInlinedArgumentsToDeoptFrame(DeoptFrame *deopt_frame, const MaglevCompilationUnit *unit, ValueNode *closure, base::Vector< ValueNode * > args)
BasicBlock * FinishInlinedBlockForCaller(ControlNode *control_node, ZoneVector< Node * > rem_nodes_in_call_block)
bool has_graph_labeller() const
void set_current_block(BasicBlock *block)
void RegisterNode(const NodeBase *node, const MaglevCompilationUnit *unit, BytecodeOffset bytecode_offset, SourcePosition position)
std::vector< BasicBlock * > TruncateGraphAt(BasicBlock *block)
MaybeReduceResult BuildInlineFunction(MaglevCallSiteInfo *call_site)
void RemoveUnreachableBlocks()
ValueNode * EnsureTagged(MaglevGraphBuilder &builder, ValueNode *node)
void Run(bool is_tracing_maglev_graphs_enabled)
compiler::JSHeapBroker * broker() const
MaglevCompilationInfo * compilation_info_
MaglevCallSiteInfo * ChooseNextCallSite()
void RemovePredecessorFollowing(ControlNode *control, BasicBlock *call_block)
MaglevInliner(MaglevCompilationInfo *compilation_info, Graph *graph)
static void UpdatePredecessorsOf(BasicBlock *block, BasicBlock *prev_pred, BasicBlock *new_pred)
ValueNode * AddNodeAtBlockEnd(MaglevGraphBuilder &builder, std::initializer_list< ValueNode * > inputs, Args &&... args)
void RegisterNode(MaglevGraphBuilder &builder, Node *node)
static MaybeReduceResult Fail()
void TurnLoopIntoRegularBlock()
void RemovePredecessorAt(int predecessor_id)
static Derived * New(Zone *zone, std::initializer_list< ValueNode * > inputs, Args &&... args)
static ReduceResult Done()
base::Vector< const DirectHandle< Object > > args
ZoneVector< RpoNumber > & result
void PrintGraph(std::ostream &os, MaglevCompilationInfo *compilation_info, Graph *const graph)
V8_EXPORT_PRIVATE FlagValues v8_flags
#define DCHECK_NOT_NULL(val)
#define CHECK_NE(lhs, rhs)
#define DCHECK(condition)
#define DCHECK_EQ(v1, v2)
CallKnownJSFunction * generic_call_node
MaglevCallerDetails caller_details
compiler::FeedbackCellRef feedback_cell
base::Vector< ValueNode * > arguments