blob: e04870ed2fdd93101a7d5bce17da412f942536f3 [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"
Ben Murdoch014dc512016-03-22 12:00:34 +000010#include "src/compiler/graph-reducer.h"
Rubin Xu2894c6a2019-02-07 16:01:35 +000011#include "src/deoptimize-reason.h"
Ben Murdoch014dc512016-03-22 12:00:34 +000012
13namespace v8 {
14namespace internal {
Ben Murdoch62ed6312017-06-06 11:06:27 +010015
16// Forward declarations.
Ben Murdoch62ed6312017-06-06 11:06:27 +010017class Factory;
Rubin Xu2894c6a2019-02-07 16:01:35 +000018class VectorSlotPair;
Ben Murdoch62ed6312017-06-06 11:06:27 +010019
Ben Murdoch014dc512016-03-22 12:00:34 +000020namespace compiler {
21
22// Forward declarations.
Rubin Xu2894c6a2019-02-07 16:01:35 +000023class CallFrequency;
Ben Murdoch014dc512016-03-22 12:00:34 +000024class CommonOperatorBuilder;
Rubin Xu2894c6a2019-02-07 16:01:35 +000025class CompilationDependencies;
26struct FieldAccess;
Ben Murdoch014dc512016-03-22 12:00:34 +000027class JSGraph;
Rubin Xu2894c6a2019-02-07 16:01:35 +000028class JSHeapBroker;
Ben Murdoch014dc512016-03-22 12:00:34 +000029class JSOperatorBuilder;
Ben Murdochf91f0612016-11-29 16:50:11 +000030class SimplifiedOperatorBuilder;
Ben Murdoch014dc512016-03-22 12:00:34 +000031
Ben Murdoch62ed6312017-06-06 11:06:27 +010032// Performs strength reduction on {JSConstruct} and {JSCall} nodes,
Ben Murdoch014dc512016-03-22 12:00:34 +000033// which might allow inlining or other optimizations to be performed afterwards.
Rubin Xu2894c6a2019-02-07 16:01:35 +000034class V8_EXPORT_PRIVATE JSCallReducer final : public AdvancedReducer {
Ben Murdoch014dc512016-03-22 12:00:34 +000035 public:
36 // Flags that control the mode of operation.
Rubin Xu2894c6a2019-02-07 16:01:35 +000037 enum Flag { kNoFlags = 0u, kBailoutOnUninitialized = 1u << 0 };
Ben Murdoch014dc512016-03-22 12:00:34 +000038 typedef base::Flags<Flag> Flags;
39
Rubin Xu2894c6a2019-02-07 16:01:35 +000040 JSCallReducer(Editor* editor, JSGraph* jsgraph, JSHeapBroker* js_heap_broker,
41 Flags flags, Handle<Context> native_context,
Ben Murdoch62ed6312017-06-06 11:06:27 +010042 CompilationDependencies* dependencies)
Ben Murdochf3b273f2017-01-17 12:11:28 +000043 : AdvancedReducer(editor),
44 jsgraph_(jsgraph),
Rubin Xu2894c6a2019-02-07 16:01:35 +000045 js_heap_broker_(js_heap_broker),
Ben Murdochf3b273f2017-01-17 12:11:28 +000046 flags_(flags),
Ben Murdoch62ed6312017-06-06 11:06:27 +010047 native_context_(native_context),
48 dependencies_(dependencies) {}
Ben Murdoch014dc512016-03-22 12:00:34 +000049
Rubin Xu2894c6a2019-02-07 16:01:35 +000050 const char* reducer_name() const override { return "JSCallReducer"; }
51
Ben Murdoch014dc512016-03-22 12:00:34 +000052 Reduction Reduce(Node* node) final;
53
Rubin Xu2894c6a2019-02-07 16:01:35 +000054 // Processes the waitlist gathered while the reducer was running,
55 // and does a final attempt to reduce the nodes in the waitlist.
56 void Finalize() final;
57
Ben Murdoch014dc512016-03-22 12:00:34 +000058 private:
59 Reduction ReduceArrayConstructor(Node* node);
Rubin Xu2894c6a2019-02-07 16:01:35 +000060 Reduction ReduceBooleanConstructor(Node* node);
61 Reduction ReduceCallApiFunction(Node* node,
62 Handle<SharedFunctionInfo> shared);
Ben Murdoch014dc512016-03-22 12:00:34 +000063 Reduction ReduceFunctionPrototypeApply(Node* node);
Rubin Xu2894c6a2019-02-07 16:01:35 +000064 Reduction ReduceFunctionPrototypeBind(Node* node);
Ben Murdoch014dc512016-03-22 12:00:34 +000065 Reduction ReduceFunctionPrototypeCall(Node* node);
Ben Murdoch62ed6312017-06-06 11:06:27 +010066 Reduction ReduceFunctionPrototypeHasInstance(Node* node);
Rubin Xu2894c6a2019-02-07 16:01:35 +000067 Reduction ReduceObjectConstructor(Node* node);
68 Reduction ReduceObjectGetPrototype(Node* node, Node* object);
69 Reduction ReduceObjectGetPrototypeOf(Node* node);
70 Reduction ReduceObjectIs(Node* node);
Ben Murdochc8c1d9e2017-03-08 14:04:23 +000071 Reduction ReduceObjectPrototypeGetProto(Node* node);
Rubin Xu2894c6a2019-02-07 16:01:35 +000072 Reduction ReduceObjectPrototypeHasOwnProperty(Node* node);
73 Reduction ReduceObjectPrototypeIsPrototypeOf(Node* node);
74 Reduction ReduceObjectCreate(Node* node);
75 Reduction ReduceReflectApply(Node* node);
76 Reduction ReduceReflectConstruct(Node* node);
77 Reduction ReduceReflectGet(Node* node);
78 Reduction ReduceReflectGetPrototypeOf(Node* node);
79 Reduction ReduceReflectHas(Node* node);
80 Reduction ReduceArrayForEach(Node* node, Handle<SharedFunctionInfo> shared);
81 enum class ArrayReduceDirection { kLeft, kRight };
82 Reduction ReduceArrayReduce(Node* node, ArrayReduceDirection direction,
83 Handle<SharedFunctionInfo> shared);
84 Reduction ReduceArrayMap(Node* node, Handle<SharedFunctionInfo> shared);
85 Reduction ReduceArrayFilter(Node* node, Handle<SharedFunctionInfo> shared);
86 enum class ArrayFindVariant { kFind, kFindIndex };
87 Reduction ReduceArrayFind(Node* node, ArrayFindVariant variant,
88 Handle<SharedFunctionInfo> shared);
89 Reduction ReduceArrayEvery(Node* node, Handle<SharedFunctionInfo> shared);
90 enum class SearchVariant { kIncludes, kIndexOf };
91 Reduction ReduceArrayIndexOfIncludes(SearchVariant search_variant,
92 Node* node);
93 Reduction ReduceArraySome(Node* node, Handle<SharedFunctionInfo> shared);
94 Reduction ReduceArrayPrototypePush(Node* node);
95 Reduction ReduceArrayPrototypePop(Node* node);
96 Reduction ReduceArrayPrototypeShift(Node* node);
97 Reduction ReduceArrayPrototypeSlice(Node* node);
98 Reduction ReduceArrayIsArray(Node* node);
99 enum class ArrayIteratorKind { kArray, kTypedArray };
100 Reduction ReduceArrayIterator(Node* node, IterationKind kind);
101 Reduction ReduceArrayIteratorPrototypeNext(Node* node);
102 Reduction ReduceFastArrayIteratorNext(InstanceType type, Node* node,
103 IterationKind kind);
104
105 Reduction ReduceCallOrConstructWithArrayLikeOrSpread(
106 Node* node, int arity, CallFrequency const& frequency,
107 VectorSlotPair const& feedback);
Ben Murdoch62ed6312017-06-06 11:06:27 +0100108 Reduction ReduceJSConstruct(Node* node);
Rubin Xu2894c6a2019-02-07 16:01:35 +0000109 Reduction ReduceJSConstructWithArrayLike(Node* node);
Ben Murdoch62ed6312017-06-06 11:06:27 +0100110 Reduction ReduceJSConstructWithSpread(Node* node);
111 Reduction ReduceJSCall(Node* node);
Rubin Xu2894c6a2019-02-07 16:01:35 +0000112 Reduction ReduceJSCall(Node* node, Handle<SharedFunctionInfo> shared);
113 Reduction ReduceJSCallWithArrayLike(Node* node);
Ben Murdoch62ed6312017-06-06 11:06:27 +0100114 Reduction ReduceJSCallWithSpread(Node* node);
Rubin Xu2894c6a2019-02-07 16:01:35 +0000115 Reduction ReduceRegExpPrototypeTest(Node* node);
116 Reduction ReduceReturnReceiver(Node* node);
117 Reduction ReduceStringPrototypeIndexOf(Node* node);
118 Reduction ReduceStringPrototypeSubstring(Node* node);
119 Reduction ReduceStringPrototypeSlice(Node* node);
120 Reduction ReduceStringPrototypeSubstr(Node* node);
121 Reduction ReduceStringPrototypeStringAt(
122 const Operator* string_access_operator, Node* node);
123 Reduction ReduceStringPrototypeCharAt(Node* node);
Ben Murdoch62ed6312017-06-06 11:06:27 +0100124
Rubin Xu2894c6a2019-02-07 16:01:35 +0000125#ifdef V8_INTL_SUPPORT
126 Reduction ReduceStringPrototypeToLowerCaseIntl(Node* node);
127 Reduction ReduceStringPrototypeToUpperCaseIntl(Node* node);
128#endif // V8_INTL_SUPPORT
Ben Murdoch62ed6312017-06-06 11:06:27 +0100129
Rubin Xu2894c6a2019-02-07 16:01:35 +0000130 Reduction ReduceStringFromCharCode(Node* node);
131 Reduction ReduceStringFromCodePoint(Node* node);
132 Reduction ReduceStringPrototypeIterator(Node* node);
133 Reduction ReduceStringIteratorPrototypeNext(Node* node);
134 Reduction ReduceStringPrototypeConcat(Node* node,
135 Handle<SharedFunctionInfo> shared);
136
137 Reduction ReduceAsyncFunctionPromiseCreate(Node* node);
138 Reduction ReduceAsyncFunctionPromiseRelease(Node* node);
139 Reduction ReducePromiseConstructor(Node* node);
140 Reduction ReducePromiseInternalConstructor(Node* node);
141 Reduction ReducePromiseInternalReject(Node* node);
142 Reduction ReducePromiseInternalResolve(Node* node);
143 Reduction ReducePromisePrototypeCatch(Node* node);
144 Reduction ReducePromisePrototypeFinally(Node* node);
145 Reduction ReducePromisePrototypeThen(Node* node);
146 Reduction ReducePromiseResolveTrampoline(Node* node);
147
148 Reduction ReduceTypedArrayConstructor(Node* node,
149 Handle<SharedFunctionInfo> shared);
150 Reduction ReduceTypedArrayPrototypeToStringTag(Node* node);
151
152 Reduction ReduceSoftDeoptimize(Node* node, DeoptimizeReason reason);
153
154 Reduction ReduceMathUnary(Node* node, const Operator* op);
155 Reduction ReduceMathBinary(Node* node, const Operator* op);
156 Reduction ReduceMathImul(Node* node);
157 Reduction ReduceMathClz32(Node* node);
158 Reduction ReduceMathMinMax(Node* node, const Operator* op, Node* empty_value);
159
160 Reduction ReduceNumberIsFinite(Node* node);
161 Reduction ReduceNumberIsInteger(Node* node);
162 Reduction ReduceNumberIsSafeInteger(Node* node);
163 Reduction ReduceNumberIsNaN(Node* node);
164
165 Reduction ReduceGlobalIsFinite(Node* node);
166 Reduction ReduceGlobalIsNaN(Node* node);
167
168 Reduction ReduceMapPrototypeHas(Node* node);
169 Reduction ReduceMapPrototypeGet(Node* node);
170 Reduction ReduceCollectionIteration(Node* node,
171 CollectionKind collection_kind,
172 IterationKind iteration_kind);
173 Reduction ReduceCollectionPrototypeSize(Node* node,
174 CollectionKind collection_kind);
175 Reduction ReduceCollectionIteratorPrototypeNext(
176 Node* node, int entry_size, Handle<HeapObject> empty_collection,
177 InstanceType collection_iterator_instance_type_first,
178 InstanceType collection_iterator_instance_type_last);
179
180 Reduction ReduceArrayBufferIsView(Node* node);
181 Reduction ReduceArrayBufferViewAccessor(Node* node,
182 InstanceType instance_type,
183 FieldAccess const& access);
184
185 Reduction ReduceDataViewPrototypeGet(Node* node,
186 ExternalArrayType element_type);
187 Reduction ReduceDataViewPrototypeSet(Node* node,
188 ExternalArrayType element_type);
189
190 Reduction ReduceDatePrototypeGetTime(Node* node);
191 Reduction ReduceDateNow(Node* node);
192 Reduction ReduceNumberParseInt(Node* node);
193
194 Reduction ReduceNumberConstructor(Node* node);
195
196 // Returns the updated {to} node, and updates control and effect along the
197 // way.
198 Node* DoFilterPostCallbackWork(ElementsKind kind, Node** control,
199 Node** effect, Node* a, Node* to,
200 Node* element, Node* callback_value);
201
202 // If {fncallback} is not callable, throw a TypeError.
203 // {control} is altered, and new nodes {check_fail} and {check_throw} are
204 // returned. {check_fail} is the control branch where IsCallable failed,
205 // and {check_throw} is the call to throw a TypeError in that
206 // branch.
207 void WireInCallbackIsCallableCheck(Node* fncallback, Node* context,
208 Node* check_frame_state, Node* effect,
209 Node** control, Node** check_fail,
210 Node** check_throw);
211 void RewirePostCallbackExceptionEdges(Node* check_throw, Node* on_exception,
212 Node* effect, Node** check_fail,
213 Node** control);
214
215 // Begin the central loop of a higher-order array builtin. A Loop is wired
216 // into {control}, an EffectPhi into {effect}, and the array index {k} is
217 // threaded into a Phi, which is returned. It's helpful to save the
218 // value of {control} as the loop node, and of {effect} as the corresponding
219 // EffectPhi after function return.
220 Node* WireInLoopStart(Node* k, Node** control, Node** effect);
221 void WireInLoopEnd(Node* loop, Node* eloop, Node* vloop, Node* k,
222 Node* control, Node* effect);
223
224 // Load receiver[k], first bounding k by receiver array length.
225 // k is thusly changed, and the effect is changed as well.
226 Node* SafeLoadElement(ElementsKind kind, Node* receiver, Node* control,
227 Node** effect, Node** k,
228 const VectorSlotPair& feedback);
229
230 Node* CreateArtificialFrameState(Node* node, Node* outer_frame_state,
231 int parameter_count, BailoutId bailout_id,
232 FrameStateType frame_state_type,
233 Handle<SharedFunctionInfo> shared);
Ben Murdoch014dc512016-03-22 12:00:34 +0000234
Ben Murdoch014dc512016-03-22 12:00:34 +0000235 Graph* graph() const;
Ben Murdoch014dc512016-03-22 12:00:34 +0000236 JSGraph* jsgraph() const { return jsgraph_; }
Rubin Xu2894c6a2019-02-07 16:01:35 +0000237 JSHeapBroker* js_heap_broker() const { return js_heap_broker_; }
Ben Murdoch014dc512016-03-22 12:00:34 +0000238 Isolate* isolate() const;
Ben Murdoch62ed6312017-06-06 11:06:27 +0100239 Factory* factory() const;
Ben Murdochc8c1d9e2017-03-08 14:04:23 +0000240 Handle<Context> native_context() const { return native_context_; }
Rubin Xu2894c6a2019-02-07 16:01:35 +0000241 Handle<JSGlobalProxy> global_proxy() const;
Ben Murdoch014dc512016-03-22 12:00:34 +0000242 CommonOperatorBuilder* common() const;
243 JSOperatorBuilder* javascript() const;
Ben Murdochf91f0612016-11-29 16:50:11 +0000244 SimplifiedOperatorBuilder* simplified() const;
Rubin Xu2894c6a2019-02-07 16:01:35 +0000245 Flags flags() const { return flags_; }
Ben Murdoch62ed6312017-06-06 11:06:27 +0100246 CompilationDependencies* dependencies() const { return dependencies_; }
Ben Murdoch014dc512016-03-22 12:00:34 +0000247
248 JSGraph* const jsgraph_;
Rubin Xu2894c6a2019-02-07 16:01:35 +0000249 JSHeapBroker* const js_heap_broker_;
Ben Murdoch014dc512016-03-22 12:00:34 +0000250 Flags const flags_;
Ben Murdochc8c1d9e2017-03-08 14:04:23 +0000251 Handle<Context> const native_context_;
Ben Murdoch62ed6312017-06-06 11:06:27 +0100252 CompilationDependencies* const dependencies_;
Rubin Xu2894c6a2019-02-07 16:01:35 +0000253 std::set<Node*> waitlist_;
Ben Murdoch014dc512016-03-22 12:00:34 +0000254};
255
Ben Murdoch014dc512016-03-22 12:00:34 +0000256} // namespace compiler
257} // namespace internal
258} // namespace v8
259
260#endif // V8_COMPILER_JS_CALL_REDUCER_H_