blob: fe5af04aa8630662abb2278485449bfac96d5ffd [file] [log] [blame]
Ben Murdoch014dc512016-03-22 12:00:34 +00001// Copyright 2015 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef V8_COMPILER_JS_CALL_REDUCER_H_
6#define V8_COMPILER_JS_CALL_REDUCER_H_
7
8#include "src/base/flags.h"
Rubin Xu2894c6a2019-02-07 16:01:35 +00009#include "src/compiler/frame-states.h"
Rubin Xu6e1e26a2021-02-10 00:04:48 +000010#include "src/compiler/globals.h"
Ben Murdoch014dc512016-03-22 12:00:34 +000011#include "src/compiler/graph-reducer.h"
Rubin Xu6e1e26a2021-02-10 00:04:48 +000012#include "src/compiler/node-properties.h"
13#include "src/deoptimizer/deoptimize-reason.h"
Ben Murdoch014dc512016-03-22 12:00:34 +000014
15namespace v8 {
16namespace internal {
Ben Murdoch62ed6312017-06-06 11:06:27 +010017
18// Forward declarations.
Ben Murdoch62ed6312017-06-06 11:06:27 +010019class Factory;
Rubin Xu6e1e26a2021-02-10 00:04:48 +000020class JSGlobalProxy;
Ben Murdoch62ed6312017-06-06 11:06:27 +010021
Ben Murdoch014dc512016-03-22 12:00:34 +000022namespace compiler {
23
24// Forward declarations.
Rubin Xu2894c6a2019-02-07 16:01:35 +000025class CallFrequency;
Ben Murdoch014dc512016-03-22 12:00:34 +000026class CommonOperatorBuilder;
Rubin Xu2894c6a2019-02-07 16:01:35 +000027class CompilationDependencies;
Rubin Xu6e1e26a2021-02-10 00:04:48 +000028struct FeedbackSource;
Rubin Xu2894c6a2019-02-07 16:01:35 +000029struct FieldAccess;
Rubin Xu6e1e26a2021-02-10 00:04:48 +000030class JSCallReducerAssembler;
Ben Murdoch014dc512016-03-22 12:00:34 +000031class JSGraph;
Rubin Xu2894c6a2019-02-07 16:01:35 +000032class JSHeapBroker;
Ben Murdoch014dc512016-03-22 12:00:34 +000033class JSOperatorBuilder;
Rubin Xu6e1e26a2021-02-10 00:04:48 +000034class MapInference;
35class NodeProperties;
Ben Murdochf91f0612016-11-29 16:50:11 +000036class SimplifiedOperatorBuilder;
Ben Murdoch014dc512016-03-22 12:00:34 +000037
Ben Murdoch62ed6312017-06-06 11:06:27 +010038// Performs strength reduction on {JSConstruct} and {JSCall} nodes,
Ben Murdoch014dc512016-03-22 12:00:34 +000039// which might allow inlining or other optimizations to be performed afterwards.
Rubin Xu2894c6a2019-02-07 16:01:35 +000040class V8_EXPORT_PRIVATE JSCallReducer final : public AdvancedReducer {
Ben Murdoch014dc512016-03-22 12:00:34 +000041 public:
42 // Flags that control the mode of operation.
Rubin Xu6e1e26a2021-02-10 00:04:48 +000043 enum Flag {
44 kNoFlags = 0u,
45 kBailoutOnUninitialized = 1u << 0,
46 };
47 using Flags = base::Flags<Flag>;
Ben Murdoch014dc512016-03-22 12:00:34 +000048
Rubin Xu6e1e26a2021-02-10 00:04:48 +000049 JSCallReducer(Editor* editor, JSGraph* jsgraph, JSHeapBroker* broker,
50 Zone* temp_zone, Flags flags,
Ben Murdoch62ed6312017-06-06 11:06:27 +010051 CompilationDependencies* dependencies)
Ben Murdochf3b273f2017-01-17 12:11:28 +000052 : AdvancedReducer(editor),
53 jsgraph_(jsgraph),
Rubin Xu6e1e26a2021-02-10 00:04:48 +000054 broker_(broker),
55 temp_zone_(temp_zone),
Ben Murdochf3b273f2017-01-17 12:11:28 +000056 flags_(flags),
Ben Murdoch62ed6312017-06-06 11:06:27 +010057 dependencies_(dependencies) {}
Ben Murdoch014dc512016-03-22 12:00:34 +000058
Rubin Xu2894c6a2019-02-07 16:01:35 +000059 const char* reducer_name() const override { return "JSCallReducer"; }
60
Ben Murdoch014dc512016-03-22 12:00:34 +000061 Reduction Reduce(Node* node) final;
62
Rubin Xu2894c6a2019-02-07 16:01:35 +000063 // Processes the waitlist gathered while the reducer was running,
64 // and does a final attempt to reduce the nodes in the waitlist.
65 void Finalize() final;
66
Rubin Xu6e1e26a2021-02-10 00:04:48 +000067 // JSCallReducer outsources much work to a graph assembler.
68 void RevisitForGraphAssembler(Node* node) { Revisit(node); }
69 Zone* ZoneForGraphAssembler() const { return temp_zone(); }
70 JSGraph* JSGraphForGraphAssembler() const { return jsgraph(); }
71
Ben Murdoch014dc512016-03-22 12:00:34 +000072 private:
Rubin Xu2894c6a2019-02-07 16:01:35 +000073 Reduction ReduceBooleanConstructor(Node* node);
74 Reduction ReduceCallApiFunction(Node* node,
Rubin Xu6e1e26a2021-02-10 00:04:48 +000075 const SharedFunctionInfoRef& shared);
Ben Murdoch014dc512016-03-22 12:00:34 +000076 Reduction ReduceFunctionPrototypeApply(Node* node);
Rubin Xu2894c6a2019-02-07 16:01:35 +000077 Reduction ReduceFunctionPrototypeBind(Node* node);
Ben Murdoch014dc512016-03-22 12:00:34 +000078 Reduction ReduceFunctionPrototypeCall(Node* node);
Ben Murdoch62ed6312017-06-06 11:06:27 +010079 Reduction ReduceFunctionPrototypeHasInstance(Node* node);
Rubin Xu2894c6a2019-02-07 16:01:35 +000080 Reduction ReduceObjectConstructor(Node* node);
81 Reduction ReduceObjectGetPrototype(Node* node, Node* object);
82 Reduction ReduceObjectGetPrototypeOf(Node* node);
83 Reduction ReduceObjectIs(Node* node);
Ben Murdochc8c1d9e2017-03-08 14:04:23 +000084 Reduction ReduceObjectPrototypeGetProto(Node* node);
Rubin Xu2894c6a2019-02-07 16:01:35 +000085 Reduction ReduceObjectPrototypeHasOwnProperty(Node* node);
86 Reduction ReduceObjectPrototypeIsPrototypeOf(Node* node);
87 Reduction ReduceObjectCreate(Node* node);
88 Reduction ReduceReflectApply(Node* node);
89 Reduction ReduceReflectConstruct(Node* node);
90 Reduction ReduceReflectGet(Node* node);
91 Reduction ReduceReflectGetPrototypeOf(Node* node);
92 Reduction ReduceReflectHas(Node* node);
Rubin Xu6e1e26a2021-02-10 00:04:48 +000093
94 Reduction ReduceArrayConstructor(Node* node);
95 Reduction ReduceArrayEvery(Node* node, const SharedFunctionInfoRef& shared);
96 Reduction ReduceArrayFilter(Node* node, const SharedFunctionInfoRef& shared);
97 Reduction ReduceArrayFindIndex(Node* node,
98 const SharedFunctionInfoRef& shared);
99 Reduction ReduceArrayFind(Node* node, const SharedFunctionInfoRef& shared);
100 Reduction ReduceArrayForEach(Node* node, const SharedFunctionInfoRef& shared);
101 Reduction ReduceArrayIncludes(Node* node);
102 Reduction ReduceArrayIndexOf(Node* node);
103 Reduction ReduceArrayIsArray(Node* node);
104 Reduction ReduceArrayMap(Node* node, const SharedFunctionInfoRef& shared);
Rubin Xu2894c6a2019-02-07 16:01:35 +0000105 Reduction ReduceArrayPrototypePop(Node* node);
Rubin Xu6e1e26a2021-02-10 00:04:48 +0000106 Reduction ReduceArrayPrototypePush(Node* node);
Rubin Xu2894c6a2019-02-07 16:01:35 +0000107 Reduction ReduceArrayPrototypeShift(Node* node);
108 Reduction ReduceArrayPrototypeSlice(Node* node);
Rubin Xu6e1e26a2021-02-10 00:04:48 +0000109 Reduction ReduceArrayReduce(Node* node, const SharedFunctionInfoRef& shared);
110 Reduction ReduceArrayReduceRight(Node* node,
111 const SharedFunctionInfoRef& shared);
112 Reduction ReduceArraySome(Node* node, const SharedFunctionInfoRef& shared);
113
114 enum class ArrayIteratorKind { kArrayLike, kTypedArray };
115 Reduction ReduceArrayIterator(Node* node, ArrayIteratorKind array_kind,
116 IterationKind iteration_kind);
Rubin Xu2894c6a2019-02-07 16:01:35 +0000117 Reduction ReduceArrayIteratorPrototypeNext(Node* node);
118 Reduction ReduceFastArrayIteratorNext(InstanceType type, Node* node,
119 IterationKind kind);
120
121 Reduction ReduceCallOrConstructWithArrayLikeOrSpread(
Rubin Xu6e1e26a2021-02-10 00:04:48 +0000122 Node* node, int arraylike_or_spread_index, CallFrequency const& frequency,
123 FeedbackSource const& feedback, SpeculationMode speculation_mode,
124 CallFeedbackRelation feedback_relation);
Ben Murdoch62ed6312017-06-06 11:06:27 +0100125 Reduction ReduceJSConstruct(Node* node);
Rubin Xu2894c6a2019-02-07 16:01:35 +0000126 Reduction ReduceJSConstructWithArrayLike(Node* node);
Ben Murdoch62ed6312017-06-06 11:06:27 +0100127 Reduction ReduceJSConstructWithSpread(Node* node);
128 Reduction ReduceJSCall(Node* node);
Rubin Xu6e1e26a2021-02-10 00:04:48 +0000129 Reduction ReduceJSCall(Node* node, const SharedFunctionInfoRef& shared);
Rubin Xu2894c6a2019-02-07 16:01:35 +0000130 Reduction ReduceJSCallWithArrayLike(Node* node);
Ben Murdoch62ed6312017-06-06 11:06:27 +0100131 Reduction ReduceJSCallWithSpread(Node* node);
Rubin Xu2894c6a2019-02-07 16:01:35 +0000132 Reduction ReduceRegExpPrototypeTest(Node* node);
133 Reduction ReduceReturnReceiver(Node* node);
134 Reduction ReduceStringPrototypeIndexOf(Node* node);
135 Reduction ReduceStringPrototypeSubstring(Node* node);
136 Reduction ReduceStringPrototypeSlice(Node* node);
137 Reduction ReduceStringPrototypeSubstr(Node* node);
138 Reduction ReduceStringPrototypeStringAt(
139 const Operator* string_access_operator, Node* node);
140 Reduction ReduceStringPrototypeCharAt(Node* node);
Rubin Xu6e1e26a2021-02-10 00:04:48 +0000141 Reduction ReduceStringPrototypeStartsWith(Node* node);
Ben Murdoch62ed6312017-06-06 11:06:27 +0100142
Rubin Xu2894c6a2019-02-07 16:01:35 +0000143#ifdef V8_INTL_SUPPORT
144 Reduction ReduceStringPrototypeToLowerCaseIntl(Node* node);
145 Reduction ReduceStringPrototypeToUpperCaseIntl(Node* node);
146#endif // V8_INTL_SUPPORT
Ben Murdoch62ed6312017-06-06 11:06:27 +0100147
Rubin Xu2894c6a2019-02-07 16:01:35 +0000148 Reduction ReduceStringFromCharCode(Node* node);
149 Reduction ReduceStringFromCodePoint(Node* node);
150 Reduction ReduceStringPrototypeIterator(Node* node);
151 Reduction ReduceStringIteratorPrototypeNext(Node* node);
Rubin Xu6e1e26a2021-02-10 00:04:48 +0000152 Reduction ReduceStringPrototypeConcat(Node* node);
Rubin Xu2894c6a2019-02-07 16:01:35 +0000153
Rubin Xu2894c6a2019-02-07 16:01:35 +0000154 Reduction ReducePromiseConstructor(Node* node);
155 Reduction ReducePromiseInternalConstructor(Node* node);
156 Reduction ReducePromiseInternalReject(Node* node);
157 Reduction ReducePromiseInternalResolve(Node* node);
158 Reduction ReducePromisePrototypeCatch(Node* node);
159 Reduction ReducePromisePrototypeFinally(Node* node);
160 Reduction ReducePromisePrototypeThen(Node* node);
161 Reduction ReducePromiseResolveTrampoline(Node* node);
162
163 Reduction ReduceTypedArrayConstructor(Node* node,
Rubin Xu6e1e26a2021-02-10 00:04:48 +0000164 const SharedFunctionInfoRef& shared);
Rubin Xu2894c6a2019-02-07 16:01:35 +0000165 Reduction ReduceTypedArrayPrototypeToStringTag(Node* node);
166
Rubin Xu6e1e26a2021-02-10 00:04:48 +0000167 Reduction ReduceForInsufficientFeedback(Node* node, DeoptimizeReason reason);
Rubin Xu2894c6a2019-02-07 16:01:35 +0000168
169 Reduction ReduceMathUnary(Node* node, const Operator* op);
170 Reduction ReduceMathBinary(Node* node, const Operator* op);
171 Reduction ReduceMathImul(Node* node);
172 Reduction ReduceMathClz32(Node* node);
173 Reduction ReduceMathMinMax(Node* node, const Operator* op, Node* empty_value);
174
175 Reduction ReduceNumberIsFinite(Node* node);
176 Reduction ReduceNumberIsInteger(Node* node);
177 Reduction ReduceNumberIsSafeInteger(Node* node);
178 Reduction ReduceNumberIsNaN(Node* node);
179
180 Reduction ReduceGlobalIsFinite(Node* node);
181 Reduction ReduceGlobalIsNaN(Node* node);
182
183 Reduction ReduceMapPrototypeHas(Node* node);
184 Reduction ReduceMapPrototypeGet(Node* node);
185 Reduction ReduceCollectionIteration(Node* node,
186 CollectionKind collection_kind,
187 IterationKind iteration_kind);
188 Reduction ReduceCollectionPrototypeSize(Node* node,
189 CollectionKind collection_kind);
190 Reduction ReduceCollectionIteratorPrototypeNext(
191 Node* node, int entry_size, Handle<HeapObject> empty_collection,
192 InstanceType collection_iterator_instance_type_first,
193 InstanceType collection_iterator_instance_type_last);
194
195 Reduction ReduceArrayBufferIsView(Node* node);
196 Reduction ReduceArrayBufferViewAccessor(Node* node,
197 InstanceType instance_type,
198 FieldAccess const& access);
199
Rubin Xu6e1e26a2021-02-10 00:04:48 +0000200 enum class DataViewAccess { kGet, kSet };
201 Reduction ReduceDataViewAccess(Node* node, DataViewAccess access,
202 ExternalArrayType element_type);
Rubin Xu2894c6a2019-02-07 16:01:35 +0000203
204 Reduction ReduceDatePrototypeGetTime(Node* node);
205 Reduction ReduceDateNow(Node* node);
206 Reduction ReduceNumberParseInt(Node* node);
207
208 Reduction ReduceNumberConstructor(Node* node);
Rubin Xu6e1e26a2021-02-10 00:04:48 +0000209 Reduction ReduceBigIntAsUintN(Node* node);
Rubin Xu2894c6a2019-02-07 16:01:35 +0000210
Rubin Xu6e1e26a2021-02-10 00:04:48 +0000211 // The pendant to ReplaceWithValue when using GraphAssembler-based reductions.
212 Reduction ReplaceWithSubgraph(JSCallReducerAssembler* gasm, Node* subgraph);
Rubin Xu2894c6a2019-02-07 16:01:35 +0000213
Rubin Xu6e1e26a2021-02-10 00:04:48 +0000214 // Helper to verify promise receiver maps are as expected.
215 // On bailout from a reduction, be sure to return inference.NoChange().
216 bool DoPromiseChecks(MapInference* inference);
Rubin Xu2894c6a2019-02-07 16:01:35 +0000217
Rubin Xu6e1e26a2021-02-10 00:04:48 +0000218 Node* CreateClosureFromBuiltinSharedFunctionInfo(SharedFunctionInfoRef shared,
219 Node* context, Node* effect,
220 Node* control);
Rubin Xu2894c6a2019-02-07 16:01:35 +0000221
Rubin Xu6e1e26a2021-02-10 00:04:48 +0000222 void CheckIfElementsKind(Node* receiver_elements_kind, ElementsKind kind,
223 Node* control, Node** if_true, Node** if_false);
224 Node* LoadReceiverElementsKind(Node* receiver, Effect* effect,
225 Control control);
Rubin Xu2894c6a2019-02-07 16:01:35 +0000226
Rubin Xu6e1e26a2021-02-10 00:04:48 +0000227 bool IsBuiltinOrApiFunction(JSFunctionRef target_ref) const;
Ben Murdoch014dc512016-03-22 12:00:34 +0000228
Ben Murdoch014dc512016-03-22 12:00:34 +0000229 Graph* graph() const;
Ben Murdoch014dc512016-03-22 12:00:34 +0000230 JSGraph* jsgraph() const { return jsgraph_; }
Rubin Xu6e1e26a2021-02-10 00:04:48 +0000231 JSHeapBroker* broker() const { return broker_; }
232 Zone* temp_zone() const { return temp_zone_; }
Ben Murdoch014dc512016-03-22 12:00:34 +0000233 Isolate* isolate() const;
Ben Murdoch62ed6312017-06-06 11:06:27 +0100234 Factory* factory() const;
Rubin Xu6e1e26a2021-02-10 00:04:48 +0000235 NativeContextRef native_context() const;
Ben Murdoch014dc512016-03-22 12:00:34 +0000236 CommonOperatorBuilder* common() const;
237 JSOperatorBuilder* javascript() const;
Ben Murdochf91f0612016-11-29 16:50:11 +0000238 SimplifiedOperatorBuilder* simplified() const;
Rubin Xu2894c6a2019-02-07 16:01:35 +0000239 Flags flags() const { return flags_; }
Ben Murdoch62ed6312017-06-06 11:06:27 +0100240 CompilationDependencies* dependencies() const { return dependencies_; }
Rubin Xu6e1e26a2021-02-10 00:04:48 +0000241 bool should_disallow_heap_access() const;
Ben Murdoch014dc512016-03-22 12:00:34 +0000242
243 JSGraph* const jsgraph_;
Rubin Xu6e1e26a2021-02-10 00:04:48 +0000244 JSHeapBroker* const broker_;
245 Zone* const temp_zone_;
Ben Murdoch014dc512016-03-22 12:00:34 +0000246 Flags const flags_;
Ben Murdoch62ed6312017-06-06 11:06:27 +0100247 CompilationDependencies* const dependencies_;
Rubin Xu2894c6a2019-02-07 16:01:35 +0000248 std::set<Node*> waitlist_;
Ben Murdoch014dc512016-03-22 12:00:34 +0000249};
250
Ben Murdoch014dc512016-03-22 12:00:34 +0000251} // namespace compiler
252} // namespace internal
253} // namespace v8
254
255#endif // V8_COMPILER_JS_CALL_REDUCER_H_