/src/hermes/include/hermes/IR/IRBuilder.h
Line | Count | Source |
1 | | /* |
2 | | * Copyright (c) Meta Platforms, Inc. and affiliates. |
3 | | * |
4 | | * This source code is licensed under the MIT license found in the |
5 | | * LICENSE file in the root directory of this source tree. |
6 | | */ |
7 | | |
8 | | #ifndef HERMES_IR_IRBUILDER_H |
9 | | #define HERMES_IR_IRBUILDER_H |
10 | | |
11 | | #include <string> |
12 | | #include <utility> |
13 | | |
14 | | #include "llvh/ADT/SmallVector.h" |
15 | | #include "llvh/ADT/StringRef.h" |
16 | | |
17 | | #include "hermes/AST/Context.h" |
18 | | #include "hermes/FrontEndDefs/Builtins.h" |
19 | | #include "hermes/IR/IR.h" |
20 | | #include "hermes/IR/Instrs.h" |
21 | | #include "hermes/Optimizer/Wasm/WasmIntrinsics.h" |
22 | | |
23 | | namespace hermes { |
24 | | |
25 | | /// The IRBuilder is used for creating IR. The builder APIs is split into two |
26 | | /// parts. First, APIs for creating blocks and functions. These APIs are |
27 | | /// stateless and do not affect the second kind of APIs which are used for |
28 | | /// creating new instructions. The Instruction creation APIS are stateful and |
29 | | /// follow an insertion point that can be saved, restored and manipulated. |
30 | | class IRBuilder { |
31 | | IRBuilder(const IRBuilder &) = delete; |
32 | | void operator=(const IRBuilder &) = delete; |
33 | | |
34 | | /// The module is the root of the program that we are building. |
35 | | Module *M; |
36 | | /// This is where the next instruction will be inserted. |
37 | | BasicBlock::iterator InsertionPoint{}; |
38 | | // The iterator must point into this block: |
39 | | BasicBlock *Block{}; |
40 | | |
41 | | SMLoc Location{}; |
42 | | ScopeDesc *CurrentSourceLevelScope{}; |
43 | | |
44 | | public: |
45 | 2.05k | explicit IRBuilder(Module *Mod) : M(Mod), InsertionPoint(nullptr) {} |
46 | | explicit IRBuilder(Function *F) |
47 | 23.0k | : M(F->getParent()), InsertionPoint(nullptr) {} |
48 | | |
49 | | //--------------------------------------------------------------------------// |
50 | | // Stateless APIs. // |
51 | | //--------------------------------------------------------------------------// |
52 | | |
53 | | enum class PropEnumerable { No = 0, Yes = 1 }; |
54 | | |
55 | 1.21k | Module *getModule() { |
56 | 1.21k | return M; |
57 | 1.21k | } |
58 | | |
59 | | /// Create a new BasicBlock and add it to a function \p Parent. |
60 | | BasicBlock *createBasicBlock(Function *Parent); |
61 | | |
62 | | /// Create a new Function and add it to the Module. |
63 | | /// \param OriginalName the original name specified by the user. |
64 | | /// \param insertBefore Another function in the module where this function |
65 | | /// should be inserted before. If null, appends to the end of the module. |
66 | | Function *createFunction( |
67 | | ScopeDesc *scopeDesc, |
68 | | Identifier OriginalName, |
69 | | Function::DefinitionKind definitionKind, |
70 | | bool strictMode, |
71 | | SourceVisibility sourceVisibility = SourceVisibility::Default, |
72 | | SMRange sourceRange = SMRange{}, |
73 | | bool isGlobal = false, |
74 | | Function *insertBefore = nullptr); |
75 | | |
76 | | /// Create a new Function and add it to the Module. |
77 | | Function *createFunction( |
78 | | ScopeDesc *scopeDesc, |
79 | | llvh::StringRef OriginalName, |
80 | | Function::DefinitionKind definitionKind, |
81 | | bool strictMode, |
82 | | SourceVisibility sourceVisibility = SourceVisibility::Default, |
83 | | SMRange sourceRange = SMRange{}, |
84 | | bool isGlobal = false, |
85 | | Function *insertBefore = nullptr); |
86 | | |
87 | | /// Create a new AsyncFunction and add it to the Module. |
88 | | /// \param OriginalName the original name specified by the user. |
89 | | /// \param insertBefore Another function in the module where this function |
90 | | /// should be inserted before. If null, appends to the end of the module. |
91 | | AsyncFunction *createAsyncFunction( |
92 | | ScopeDesc *scopeDesc, |
93 | | Identifier OriginalName, |
94 | | Function::DefinitionKind definitionKind, |
95 | | bool strictMode, |
96 | | SourceVisibility sourceVisibility, |
97 | | SMRange sourceRange = SMRange{}, |
98 | | Function *insertBefore = nullptr); |
99 | | |
100 | | /// Create a new GeneratorFunction and add it to the Module. |
101 | | /// \param OriginalName the original name specified by the user. |
102 | | /// \param insertBefore Another function in the module where this function |
103 | | /// should be inserted before. If null, appends to the end of the module. |
104 | | GeneratorFunction *createGeneratorFunction( |
105 | | ScopeDesc *scopeDesc, |
106 | | Identifier OriginalName, |
107 | | Function::DefinitionKind definitionKind, |
108 | | bool strictMode, |
109 | | SourceVisibility sourceVisibility, |
110 | | SMRange sourceRange = SMRange{}, |
111 | | Function *insertBefore = nullptr); |
112 | | |
113 | | /// Create a new GeneratorInnerFunction and add it to the Module. |
114 | | /// \param OriginalName the original name specified by the user. |
115 | | /// \param insertBefore Another function in the module where this function |
116 | | /// should be inserted before. If null, appends to the end of the module. |
117 | | GeneratorInnerFunction *createGeneratorInnerFunction( |
118 | | ScopeDesc *scopeDesc, |
119 | | Identifier OriginalName, |
120 | | Function::DefinitionKind definitionKind, |
121 | | bool strictMode, |
122 | | SMRange sourceRange = SMRange{}, |
123 | | Function *insertBefore = nullptr); |
124 | | |
125 | | /// Create the top level function representing the global scope. |
126 | | Function *createTopLevelFunction( |
127 | | ScopeDesc *scopeDesc, |
128 | | bool strictMode, |
129 | | SourceVisibility sourceVisibility = SourceVisibility::Default, |
130 | | SMRange sourceRange = SMRange{}); |
131 | | |
132 | | /// Create a new global object property. |
133 | | GlobalObjectProperty *createGlobalObjectProperty( |
134 | | Identifier name, |
135 | | bool declared); |
136 | | /// Create a new global object property. |
137 | | GlobalObjectProperty *createGlobalObjectProperty( |
138 | | llvh::StringRef name, |
139 | | bool declared); |
140 | | |
141 | | /// Add a new non-this parameter to function \p Parent. |
142 | | Parameter *createParameter(Function *Parent, Identifier Name); |
143 | | |
144 | | /// Add a new non-this parameter to function \p Parent. |
145 | | Parameter *createParameter(Function *Parent, llvh::StringRef Name); |
146 | | |
147 | | /// Add the 'this' parameter to function \p Parent. |
148 | | /// Must only be done once per function. |
149 | | Parameter *createThisParameter(Function *Parent); |
150 | | |
151 | | /// Add a new variable to scope \p Parent. |
152 | | Variable *createVariable( |
153 | | ScopeDesc *Parent, |
154 | | Variable::DeclKind declKind, |
155 | | Identifier Name); |
156 | | |
157 | | /// Add a new variable to scope \p Parent. |
158 | | Variable *createVariable( |
159 | | ScopeDesc *Parent, |
160 | | Variable::DeclKind declKind, |
161 | | llvh::StringRef Name); |
162 | | |
163 | | /// Create a new literal number of value \p value. |
164 | | LiteralNumber *getLiteralNumber(double value); |
165 | | |
166 | | /// Create a new literal positive zero. |
167 | | LiteralNumber *getLiteralPositiveZero(); |
168 | | |
169 | | /// Create a new literal negative zero. |
170 | | LiteralNumber *getLiteralNegativeZero(); |
171 | | |
172 | | /// Create a new literal NaN. |
173 | | LiteralNumber *getLiteralNaN(); |
174 | | |
175 | | /// Create a new literal BitInt of value \p value. |
176 | | LiteralBigInt *getLiteralBigInt(UniqueString *value); |
177 | | |
178 | | /// Create a new literal string of value \p value. |
179 | | LiteralString *getLiteralString(llvh::StringRef value); |
180 | | |
181 | | /// Create a new literal string of value \p value. |
182 | | LiteralString *getLiteralString(Identifier value); |
183 | | |
184 | | /// Create a new literal bool of value \p value. |
185 | | LiteralBool *getLiteralBool(bool value); |
186 | | |
187 | | /// Create a new literal 'empty'. |
188 | | LiteralEmpty *getLiteralEmpty(); |
189 | | |
190 | | /// Create a new literal 'undefined'. |
191 | | LiteralUndefined *getLiteralUndefined(); |
192 | | |
193 | | /// Create a new literal null. |
194 | | LiteralNull *getLiteralNull(); |
195 | | |
196 | | /// Return the GlobalObject value. |
197 | | GlobalObject *getGlobalObject(); |
198 | | |
199 | | /// Return the EmptySentinel value. |
200 | | EmptySentinel *getEmptySentinel(); |
201 | | |
202 | | /// Convert llvh::StringRef to Identifier. |
203 | | Identifier createIdentifier(llvh::StringRef str); |
204 | | |
205 | | //--------------------------------------------------------------------------// |
206 | | // Statefull APIs. // |
207 | | //--------------------------------------------------------------------------// |
208 | | |
209 | | private: |
210 | | /// Insert the newly created instruction \p Inst into the basic block without |
211 | | /// touching its location or statement index. |
212 | | void justInsert(Instruction *Inst); |
213 | | |
214 | | /// Insert the newly created instruction \p Inst into the basic block and |
215 | | /// populate its location and statement index. |
216 | | void insert(Instruction *Inst); |
217 | | |
218 | | public: |
219 | | /// Set the insertion point of the builder. The next instruction will be |
220 | | /// inserted at the end of \p BB. |
221 | | void setInsertionBlock(BasicBlock *BB); |
222 | | |
223 | | /// Return the current insertion block. |
224 | | BasicBlock *getInsertionBlock(); |
225 | | |
226 | | /// Return the current function. |
227 | 3.96M | Function *getFunction() { |
228 | 3.96M | assert(Block && "Builder has no current function"); |
229 | 3.96M | return Block->getParent(); |
230 | 3.96M | } |
231 | | |
232 | | /// Set the insertion point of the builder. The next instruction will be |
233 | | /// inserted after \p IP. |
234 | | void setInsertionPointAfter(Instruction *IP); |
235 | | |
236 | | /// Set the insertion point of the builder. The next instruction will be |
237 | | /// inserted where the current \p IP is (thereby pushing it down). |
238 | | void setInsertionPoint(Instruction *IP); |
239 | | |
240 | | /// \returns true if the insertion point is set. |
241 | | bool isInsertionPointValid(); |
242 | | |
243 | | /// Clear the insertion point. New instructions must not be created until the |
244 | | /// insertion point it set. |
245 | | void resetInsertionPoint(); |
246 | | |
247 | 5.59M | void setLocation(SMLoc loc) { |
248 | 5.59M | Location = loc; |
249 | 5.59M | } |
250 | 2.18k | void clearLocation() { |
251 | 2.18k | Location = SMLoc{}; |
252 | 2.18k | } |
253 | 1.31M | SMLoc getLocation() const { |
254 | 1.31M | return Location; |
255 | 1.31M | } |
256 | | |
257 | 2.85M | void setCurrentSourceLevelScope(ScopeDesc *sourceLevelScope) { |
258 | 2.85M | CurrentSourceLevelScope = sourceLevelScope; |
259 | 2.85M | } |
260 | | |
261 | | /// Move instruction \p inst from its block to the insertion point in the |
262 | | /// current block. If the instruction is a terminator, correctly update the |
263 | | /// phi-nodes that refer to the old block and point then to the current one. |
264 | | void transferInstructionToCurrentBlock(Instruction *inst); |
265 | | |
266 | | //--------------------------------------------------------------------------// |
267 | | // Instruction Creation methods // |
268 | | //--------------------------------------------------------------------------// |
269 | | |
270 | | /// Insert a clone of the instruction at the current insertion point. The |
271 | | /// location and statement index are preserved but the operands are recreated. |
272 | | /// \param source the original instruction. |
273 | | /// \param operands the (updated) operands to use in the new instruction. |
274 | | Instruction *cloneInst( |
275 | | const Instruction *source, |
276 | | llvh::ArrayRef<Value *> operands); |
277 | | |
278 | | BranchInst *createBranchInst(BasicBlock *Destination); |
279 | | |
280 | | CondBranchInst * |
281 | | createCondBranchInst(Value *Cond, BasicBlock *T, BasicBlock *F); |
282 | | |
283 | | ReturnInst *createReturnInst(Value *Val); |
284 | | |
285 | | AllocStackInst *createAllocStackInst(llvh::StringRef varName); |
286 | | |
287 | | AllocStackInst *createAllocStackInst(Identifier varName); |
288 | | |
289 | | AsNumberInst *createAsNumberInst(Value *val); |
290 | | |
291 | | AsNumericInst *createAsNumericInst(Value *val); |
292 | | |
293 | | AsInt32Inst *createAsInt32Inst(Value *val); |
294 | | |
295 | | AddEmptyStringInst *createAddEmptyStringInst(Value *val); |
296 | | |
297 | | ThrowIfHasRestrictedGlobalPropertyInst * |
298 | | createThrowIfHasRestrictedGlobalPropertyInst(llvh::StringRef property); |
299 | | |
300 | | CreateScopeInst *createCreateScopeInst(ScopeDesc *scopeDesc); |
301 | | |
302 | | CreateInnerScopeInst *createCreateInnerScopeInst( |
303 | | ScopeCreationInst *parentScope, |
304 | | ScopeDesc *scopeDesc); |
305 | | |
306 | | CreateFunctionInst *createCreateFunctionInst( |
307 | | Function *code, |
308 | | ScopeCreationInst *environment); |
309 | | |
310 | | LoadStackInst *createLoadStackInst(AllocStackInst *ptr); |
311 | | |
312 | | LoadFrameInst *createLoadFrameInst(Variable *ptr, ScopeCreationInst *scope); |
313 | | |
314 | | StoreStackInst *createStoreStackInst(Value *storedValue, AllocStackInst *ptr); |
315 | | |
316 | | StoreFrameInst *createStoreFrameInst( |
317 | | Value *storedValue, |
318 | | Variable *ptr, |
319 | | ScopeCreationInst *scope); |
320 | | |
321 | | CallInst *createCallInst( |
322 | | LiteralString *textifiedCallee, |
323 | | Value *callee, |
324 | | Value *thisValue, |
325 | | ArrayRef<Value *> args); |
326 | | |
327 | | HBCCallNInst *createHBCCallNInst( |
328 | | LiteralString *textifiedCallee, |
329 | | Value *callee, |
330 | | Value *thisValue, |
331 | | ArrayRef<Value *> args); |
332 | | |
333 | | ConstructInst *createConstructInst( |
334 | | Value *constructor, |
335 | | Value *newTarget, |
336 | | ArrayRef<Value *> args); |
337 | | |
338 | | CatchInst *createCatchInst(); |
339 | | |
340 | | ThrowInst *createThrowInst(Value *thrownValue); |
341 | | |
342 | | CheckHasInstanceInst *createCheckHasInstanceInst( |
343 | | AllocStackInst *result, |
344 | | Value *left, |
345 | | Value *right, |
346 | | BasicBlock *onTrue, |
347 | | BasicBlock *onFalse); |
348 | | |
349 | | TryStartInst *createTryStartInst( |
350 | | BasicBlock *tryBodyBlock, |
351 | | BasicBlock *catchTargetBlock); |
352 | | |
353 | | TryEndInst *createTryEndInst(); |
354 | | |
355 | | DeletePropertyInst *createDeletePropertyInst(Value *object, Value *property); |
356 | | |
357 | | LoadPropertyInst *createLoadPropertyInst(Value *object, Value *property); |
358 | | TryLoadGlobalPropertyInst *createTryLoadGlobalPropertyInst( |
359 | | LiteralString *property); |
360 | | TryLoadGlobalPropertyInst *createTryLoadGlobalPropertyInst( |
361 | | GlobalObjectProperty *property); |
362 | | |
363 | | StorePropertyInst * |
364 | | createStorePropertyInst(Value *storedValue, Value *object, Value *property); |
365 | | TryStoreGlobalPropertyInst *createTryStoreGlobalPropertyInst( |
366 | | Value *storedValue, |
367 | | LiteralString *property); |
368 | | TryStoreGlobalPropertyInst *createTryStoreGlobalPropertyInst( |
369 | | Value *storedValue, |
370 | | GlobalObjectProperty *property); |
371 | | StoreOwnPropertyInst *createStoreOwnPropertyInst( |
372 | | Value *storedValue, |
373 | | Value *object, |
374 | | Value *property, |
375 | | PropEnumerable isEnumerable); |
376 | | StoreNewOwnPropertyInst *createStoreNewOwnPropertyInst( |
377 | | Value *storedValue, |
378 | | Value *object, |
379 | | Literal *property, |
380 | | PropEnumerable isEnumerable); |
381 | | |
382 | | StoreGetterSetterInst *createStoreGetterSetterInst( |
383 | | Value *storedGetter, |
384 | | Value *storedSetter, |
385 | | Value *object, |
386 | | Value *property, |
387 | | PropEnumerable isEnumerable); |
388 | | DeletePropertyInst *createDeletePropertyInst( |
389 | | Value *object, |
390 | | llvh::StringRef property); |
391 | | |
392 | | LoadPropertyInst *createLoadPropertyInst( |
393 | | Value *object, |
394 | | llvh::StringRef property); |
395 | | TryLoadGlobalPropertyInst *createTryLoadGlobalPropertyInst( |
396 | | llvh::StringRef property); |
397 | | |
398 | | StorePropertyInst *createStorePropertyInst( |
399 | | Value *storedValue, |
400 | | Value *object, |
401 | | llvh::StringRef property); |
402 | | |
403 | | DeletePropertyInst *createDeletePropertyInst( |
404 | | Value *object, |
405 | | Identifier property); |
406 | | |
407 | | LoadPropertyInst *createLoadPropertyInst(Value *object, Identifier property); |
408 | | TryLoadGlobalPropertyInst *createTryLoadGlobalPropertyInst( |
409 | | Identifier property); |
410 | | |
411 | | StorePropertyInst *createStorePropertyInst( |
412 | | Value *storedValue, |
413 | | Value *object, |
414 | | Identifier property); |
415 | | TryStoreGlobalPropertyInst *createTryStoreGlobalPropertyInst( |
416 | | Value *storedValue, |
417 | | Identifier property); |
418 | | |
419 | | AllocObjectInst *createAllocObjectInst( |
420 | | uint32_t size, |
421 | | Value *parent = nullptr); |
422 | | |
423 | | AllocArrayInst *createAllocArrayInst( |
424 | | LiteralNumber *sizeHint, |
425 | | AllocArrayInst::ArrayValueList val_list); |
426 | | |
427 | | AllocArrayInst *createAllocArrayInst( |
428 | | AllocArrayInst::ArrayValueList val_list, |
429 | | unsigned sizeHint); |
430 | | |
431 | | CreateArgumentsInst *createCreateArgumentsInst(); |
432 | | |
433 | | GetNewTargetInst *createGetNewTargetInst(); |
434 | | |
435 | | ThrowIfEmptyInst *createThrowIfEmptyInst(Value *checkedValue); |
436 | | |
437 | | HBCGetGlobalObjectInst *createHBCGetGlobalObjectInst(); |
438 | | |
439 | | CreateRegExpInst *createRegExpInst(Identifier pattern, Identifier flags); |
440 | | |
441 | | UnaryOperatorInst *createUnaryOperatorInst( |
442 | | Value *value, |
443 | | UnaryOperatorInst::OpKind opKind); |
444 | | |
445 | | DirectEvalInst *createDirectEvalInst(Value *operand, LiteralBool *isStrict); |
446 | | |
447 | | SwitchInst *createSwitchInst( |
448 | | Value *input, |
449 | | BasicBlock *defaultBlock, |
450 | | const SwitchInst::ValueListType &values, |
451 | | const SwitchInst::BasicBlockListType &blocks); |
452 | | |
453 | | PhiInst *createPhiInst( |
454 | | const PhiInst::ValueListType &values, |
455 | | const PhiInst::BasicBlockListType &blocks); |
456 | | |
457 | | PhiInst *createPhiInst(); |
458 | | |
459 | | BinaryOperatorInst *createBinaryOperatorInst( |
460 | | Value *left, |
461 | | Value *right, |
462 | | BinaryOperatorInst::OpKind opKind); |
463 | | |
464 | | GetPNamesInst *createGetPNamesInst( |
465 | | Value *iteratorAddr, |
466 | | Value *baseAddr, |
467 | | Value *indexAddr, |
468 | | Value *sizeAddr, |
469 | | BasicBlock *onEmpty, |
470 | | BasicBlock *onSome); |
471 | | |
472 | | GetNextPNameInst *createGetNextPNameInst( |
473 | | Value *propertyAddr, |
474 | | Value *baseAddr, |
475 | | Value *indexAddr, |
476 | | Value *sizeAddr, |
477 | | Value *iteratorAddr, |
478 | | BasicBlock *onLast, |
479 | | BasicBlock *onSome); |
480 | | |
481 | | MovInst *createMovInst(Value *input); |
482 | | |
483 | | ImplicitMovInst *createImplicitMovInst(Value *input); |
484 | | |
485 | | CoerceThisNSInst *createCoerceThisNSInst(Value *input); |
486 | | |
487 | | DebuggerInst *createDebuggerInst(); |
488 | | |
489 | | SaveAndYieldInst *createSaveAndYieldInst( |
490 | | Value *result, |
491 | | BasicBlock *nextBlock); |
492 | | |
493 | | CreateGeneratorInst *createCreateGeneratorInst( |
494 | | Function *innerFn, |
495 | | ScopeCreationInst *environment); |
496 | | |
497 | | StartGeneratorInst *createStartGeneratorInst(); |
498 | | |
499 | | ResumeGeneratorInst *createResumeGeneratorInst(Value *isReturn); |
500 | | |
501 | | //--------------------------------------------------------------------------// |
502 | | // Target specific insertions // |
503 | | //--------------------------------------------------------------------------// |
504 | | |
505 | | HBCResolveEnvironment *createHBCResolveEnvironment( |
506 | | ScopeDesc *originScopeDesc, |
507 | | ScopeDesc *targetScopeDesc); |
508 | | HBCStoreToEnvironmentInst * |
509 | | createHBCStoreToEnvironmentInst(Value *env, Value *toPut, Variable *var); |
510 | | HBCLoadFromEnvironmentInst *createHBCLoadFromEnvironmentInst( |
511 | | Value *env, |
512 | | Variable *var); |
513 | | |
514 | | SwitchImmInst *createSwitchImmInst( |
515 | | Value *input, |
516 | | BasicBlock *defaultBlock, |
517 | | LiteralNumber *minValue, |
518 | | LiteralNumber *size, |
519 | | const SwitchImmInst::ValueListType &values, |
520 | | const SwitchImmInst::BasicBlockListType &blocks); |
521 | | |
522 | | HBCLoadConstInst *createHBCLoadConstInst(Literal *value); |
523 | | |
524 | | HBCLoadParamInst *createHBCLoadParamInst(LiteralNumber *value); |
525 | | |
526 | | HBCCreateEnvironmentInst *createHBCCreateEnvironmentInst( |
527 | | ScopeDesc *scopeDesc); |
528 | | |
529 | | HBCCreateInnerEnvironmentInst *createHBCCreateInnerEnvironmentInst( |
530 | | ScopeCreationInst *parentScope, |
531 | | ScopeDesc *scopeDesc); |
532 | | |
533 | | HBCGetThisNSInst *createHBCGetThisNSInst(); |
534 | | |
535 | | HBCGetArgumentsPropByValInst *createHBCGetArgumentsPropByValInst( |
536 | | Value *index, |
537 | | AllocStackInst *lazyReg); |
538 | | |
539 | | HBCGetArgumentsLengthInst *createHBCGetArgumentsLengthInst( |
540 | | AllocStackInst *lazyReg); |
541 | | |
542 | | HBCReifyArgumentsInst *createHBCReifyArgumentsInst(AllocStackInst *lazyReg); |
543 | | |
544 | | HBCCreateThisInst *createHBCCreateThisInst(Value *prototype, Value *closure); |
545 | | |
546 | | HBCConstructInst *createHBCConstructInst( |
547 | | Value *closure, |
548 | | Value *newTarget, |
549 | | Value *thisValue, |
550 | | ArrayRef<Value *> arguments); |
551 | | HBCGetConstructedObjectInst *createHBCGetConstructedObjectInst( |
552 | | HBCCreateThisInst *thisValue, |
553 | | HBCConstructInst *constructorReturnValue); |
554 | | HBCProfilePointInst *createHBCProfilePointInst(uint16_t pointIndex); |
555 | | |
556 | | CallBuiltinInst *createCallBuiltinInst( |
557 | | BuiltinMethod::Enum builtinIndex, |
558 | | ArrayRef<Value *> arguments); |
559 | | |
560 | | CallBuiltinInst *createCallBuiltinInstWithNewTarget( |
561 | | BuiltinMethod::Enum builtinIndex, |
562 | | Value *newTarget, |
563 | | ArrayRef<Value *> arguments); |
564 | | |
565 | | GetBuiltinClosureInst *createGetBuiltinClosureInst( |
566 | | BuiltinMethod::Enum builtinIndex); |
567 | | |
568 | | #ifdef HERMES_RUN_WASM |
569 | | CallIntrinsicInst *createCallIntrinsicInst( |
570 | | WasmIntrinsics::Enum intrinsicsIndex, |
571 | | ArrayRef<Value *> arguments); |
572 | | #endif |
573 | | |
574 | | HBCCallDirectInst *createHBCCallDirectInst( |
575 | | LiteralString *textifiedCallee, |
576 | | Function *callee, |
577 | | Value *thisValue, |
578 | | ArrayRef<Value *> arguments); |
579 | | |
580 | | HBCCreateFunctionInst *createHBCCreateFunctionInst( |
581 | | Function *function, |
582 | | Value *env); |
583 | | HBCSpillMovInst *createHBCSpillMovInst(Instruction *value); |
584 | | |
585 | | HBCCreateGeneratorInst *createHBCCreateGeneratorInst( |
586 | | Function *function, |
587 | | Value *env); |
588 | | |
589 | | HBCAllocObjectFromBufferInst *createHBCAllocObjectFromBufferInst( |
590 | | HBCAllocObjectFromBufferInst::ObjectPropertyMap prop_map, |
591 | | uint32_t size); |
592 | | |
593 | | CompareBranchInst *createCompareBranchInst( |
594 | | Value *left, |
595 | | Value *right, |
596 | | BinaryOperatorInst::OpKind opKind, |
597 | | BasicBlock *trueBlock, |
598 | | BasicBlock *falseBlock); |
599 | | |
600 | | IteratorBeginInst *createIteratorBeginInst(AllocStackInst *sourceOrNext); |
601 | | |
602 | | IteratorNextInst *createIteratorNextInst( |
603 | | AllocStackInst *iterator, |
604 | | AllocStackInst *sourceOrNext); |
605 | | |
606 | | IteratorCloseInst *createIteratorCloseInst( |
607 | | AllocStackInst *iterator, |
608 | | bool ignoreInnerException); |
609 | | |
610 | | UnreachableInst *createUnreachableInst(); |
611 | | |
612 | | /// This is an RAII object that saves and restores the source location of the |
613 | | /// IRBuilder. |
614 | | class ScopedLocationChange { |
615 | | ScopedLocationChange(const ScopedLocationChange &) = delete; |
616 | | void operator=(const ScopedLocationChange &) = delete; |
617 | | |
618 | | IRBuilder &builder_; |
619 | | SMLoc oldLocation_; |
620 | | |
621 | | public: |
622 | | /// Save the builder source location when constructing the object. |
623 | | explicit ScopedLocationChange(IRBuilder &builder, SMLoc location) |
624 | 1.31M | : builder_(builder), oldLocation_(builder.getLocation()) { |
625 | 1.31M | builder_.setLocation(location); |
626 | 1.31M | } |
627 | | |
628 | | /// Resotre source location when the object is destroyed. |
629 | 1.31M | ~ScopedLocationChange() { |
630 | 1.31M | builder_.setLocation(oldLocation_); |
631 | 1.31M | } |
632 | | }; |
633 | | |
634 | | //--------------------------------------------------------------------------// |
635 | | // Insertion point Save and Restore // |
636 | | //--------------------------------------------------------------------------// |
637 | | |
638 | | /// This is an RAII object that saves and restores the insertion point of the |
639 | | /// IRBuilder. |
640 | | class SaveRestore { |
641 | | SaveRestore(const SaveRestore &) = delete; |
642 | | void operator=(const SaveRestore &) = delete; |
643 | | |
644 | | IRBuilder &Builder; |
645 | | BasicBlock *BB; |
646 | | SMLoc Location; |
647 | | |
648 | | public: |
649 | | // Save the builder insertion point when constructing the object. |
650 | | explicit SaveRestore(IRBuilder &builder) |
651 | 2.18k | : Builder(builder), |
652 | 2.18k | BB(builder.getInsertionBlock()), |
653 | 2.18k | Location(builder.getLocation()) { |
654 | 2.18k | builder.clearLocation(); |
655 | 2.18k | } |
656 | | |
657 | | // Restore insertion point when the object is destroyed. |
658 | 2.18k | ~SaveRestore() { |
659 | 2.18k | Builder.setInsertionBlock(BB); |
660 | 2.18k | Builder.setLocation(Location); |
661 | 2.18k | } |
662 | | }; |
663 | | |
664 | | /// This is an RAII object that destroys instructions when it is destroyed. |
665 | | class InstructionDestroyer { |
666 | | InstructionDestroyer(const InstructionDestroyer &) = delete; |
667 | | void operator=(const InstructionDestroyer &) = delete; |
668 | | |
669 | | llvh::SmallVector<Instruction *, 8> list{}; |
670 | | |
671 | | public: |
672 | 66.3k | explicit InstructionDestroyer() = default; |
673 | | |
674 | | /// \returns true if the instruction \p A is already in the destruction |
675 | | /// queue. Notice that this is an O(n) search and should only be used for |
676 | | /// debugging. |
677 | 195k | bool hasInstruction(Instruction *A) { |
678 | 195k | return std::find(list.begin(), list.end(), A) != list.end(); |
679 | 195k | } |
680 | | |
681 | | /// Add the instruction \p A to the list of instructions to delete. |
682 | 195k | void add(Instruction *A) { |
683 | 195k | #ifndef NDEBUG |
684 | 195k | assert(!hasInstruction(A) && "Instruction already in list!"); |
685 | 195k | #endif |
686 | 195k | list.push_back(A); |
687 | 195k | } |
688 | | |
689 | 66.3k | ~InstructionDestroyer() { |
690 | 195k | for (auto *I : list) { |
691 | 195k | I->eraseFromParent(); |
692 | 195k | } |
693 | 66.3k | } |
694 | | }; |
695 | | }; |
696 | | |
697 | | } // end namespace hermes |
698 | | |
699 | | #endif |