/src/hermes/lib/IR/IRBuilder.cpp
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 | | #include "llvh/Support/Casting.h" |
9 | | #include "llvh/Support/ErrorHandling.h" |
10 | | |
11 | | #include "hermes/AST/Context.h" |
12 | | #include "hermes/IR/IR.h" |
13 | | #include "hermes/IR/IRBuilder.h" |
14 | | |
15 | | using namespace hermes; |
16 | | |
17 | 119k | BasicBlock *IRBuilder::createBasicBlock(Function *Parent) { |
18 | 119k | assert(Parent && "Invalid insertion point"); |
19 | 119k | return new BasicBlock(Parent); |
20 | 119k | } |
21 | | |
22 | | Function *IRBuilder::createFunction( |
23 | | ScopeDesc *scopeDesc, |
24 | | Identifier OriginalName, |
25 | | Function::DefinitionKind definitionKind, |
26 | | bool strictMode, |
27 | | SourceVisibility sourceVisibility, |
28 | | SMRange sourceRange, |
29 | | bool isGlobal, |
30 | 23.2k | Function *insertBefore) { |
31 | | // Function must have a name. If the source doesn't provide the function name, |
32 | | // Hermes will try to infer the name from the name of a variable or property |
33 | | // it is assigned to. If there was no inference, an empty string is used. |
34 | 23.2k | if (!OriginalName.isValid()) { |
35 | 21.8k | OriginalName = createIdentifier(""); |
36 | 21.8k | } |
37 | 23.2k | return new Function( |
38 | 23.2k | M, |
39 | 23.2k | scopeDesc, |
40 | 23.2k | OriginalName, |
41 | 23.2k | definitionKind, |
42 | 23.2k | strictMode, |
43 | 23.2k | sourceVisibility, |
44 | 23.2k | isGlobal, |
45 | 23.2k | sourceRange, |
46 | 23.2k | insertBefore); |
47 | 23.2k | } |
48 | | |
49 | | GeneratorFunction *IRBuilder::createGeneratorFunction( |
50 | | ScopeDesc *scopeDesc, |
51 | | Identifier OriginalName, |
52 | | Function::DefinitionKind definitionKind, |
53 | | bool strictMode, |
54 | | SourceVisibility sourceVisibility, |
55 | | SMRange sourceRange, |
56 | 0 | Function *insertBefore) { |
57 | 0 | if (!OriginalName.isValid()) { |
58 | | // Function must have a name, even it's empty. |
59 | | // Eventually we will give it a properly inferred name. |
60 | 0 | OriginalName = createIdentifier(""); |
61 | 0 | } |
62 | 0 | return new GeneratorFunction( |
63 | 0 | M, |
64 | 0 | scopeDesc, |
65 | 0 | OriginalName, |
66 | 0 | definitionKind, |
67 | 0 | strictMode, |
68 | 0 | sourceVisibility, |
69 | 0 | /* isGlobal */ false, |
70 | 0 | sourceRange, |
71 | 0 | insertBefore); |
72 | 0 | } |
73 | | |
74 | | GeneratorInnerFunction *IRBuilder::createGeneratorInnerFunction( |
75 | | ScopeDesc *scopeDesc, |
76 | | Identifier OriginalName, |
77 | | Function::DefinitionKind definitionKind, |
78 | | bool strictMode, |
79 | | SMRange sourceRange, |
80 | 0 | Function *insertBefore) { |
81 | 0 | if (!OriginalName.isValid()) { |
82 | | // Function must have a name, even it's empty. |
83 | | // Eventually we will give it a properly inferred name. |
84 | 0 | OriginalName = createIdentifier(""); |
85 | 0 | } |
86 | 0 | return new GeneratorInnerFunction( |
87 | 0 | M, |
88 | 0 | scopeDesc, |
89 | 0 | OriginalName, |
90 | 0 | definitionKind, |
91 | 0 | strictMode, |
92 | 0 | /* isGlobal */ false, |
93 | 0 | sourceRange, |
94 | 0 | insertBefore); |
95 | 0 | } |
96 | | |
97 | | Function *IRBuilder::createTopLevelFunction( |
98 | | ScopeDesc *scopeDesc, |
99 | | bool strictMode, |
100 | | SourceVisibility sourceVisibility, |
101 | 147 | SMRange sourceRange) { |
102 | | // Notice that this synthesized name is not a legal javascript name and |
103 | | // can't collide with functions in the processed program. |
104 | 147 | return createFunction( |
105 | 147 | scopeDesc, |
106 | 147 | "global", |
107 | 147 | Function::DefinitionKind::ES5Function, |
108 | 147 | strictMode, |
109 | 147 | sourceVisibility, |
110 | 147 | sourceRange, |
111 | 147 | true); |
112 | 147 | } |
113 | | |
114 | | Function *IRBuilder::createFunction( |
115 | | ScopeDesc *scopeDesc, |
116 | | llvh::StringRef OriginalName, |
117 | | Function::DefinitionKind definitionKind, |
118 | | bool strictMode, |
119 | | SourceVisibility sourceVisibility, |
120 | | SMRange sourceRange, |
121 | | bool isGlobal, |
122 | 147 | Function *insertBefore) { |
123 | 147 | Identifier OrigIden = |
124 | 147 | OriginalName.empty() ? Identifier{} : createIdentifier(OriginalName); |
125 | 147 | return createFunction( |
126 | 147 | scopeDesc, |
127 | 147 | OrigIden, |
128 | 147 | definitionKind, |
129 | 147 | strictMode, |
130 | 147 | sourceVisibility, |
131 | 147 | sourceRange, |
132 | 147 | isGlobal, |
133 | 147 | insertBefore); |
134 | 147 | } |
135 | | |
136 | | AsyncFunction *IRBuilder::createAsyncFunction( |
137 | | ScopeDesc *scopeDesc, |
138 | | Identifier OriginalName, |
139 | | Function::DefinitionKind definitionKind, |
140 | | bool strictMode, |
141 | | SourceVisibility sourceVisibility, |
142 | | SMRange sourceRange, |
143 | 0 | Function *insertBefore) { |
144 | 0 | if (!OriginalName.isValid()) { |
145 | | // Function must have a name, even it's empty. |
146 | | // Eventually we will give it a properly inferred name. |
147 | 0 | OriginalName = createIdentifier(""); |
148 | 0 | } |
149 | 0 | return new AsyncFunction( |
150 | 0 | M, |
151 | 0 | scopeDesc, |
152 | 0 | OriginalName, |
153 | 0 | definitionKind, |
154 | 0 | strictMode, |
155 | 0 | sourceVisibility, |
156 | 0 | /* isGlobal */ false, |
157 | 0 | sourceRange, |
158 | 0 | insertBefore); |
159 | 0 | } |
160 | | |
161 | | GlobalObjectProperty *IRBuilder::createGlobalObjectProperty( |
162 | | Identifier name, |
163 | 9.88k | bool declared) { |
164 | 9.88k | return M->addGlobalProperty(name, declared); |
165 | 9.88k | } |
166 | | GlobalObjectProperty *IRBuilder::createGlobalObjectProperty( |
167 | | llvh::StringRef name, |
168 | 0 | bool declared) { |
169 | 0 | return createGlobalObjectProperty( |
170 | 0 | M->getContext().getIdentifier(name), declared); |
171 | 0 | } |
172 | | |
173 | 23.0k | Parameter *IRBuilder::createParameter(Function *Parent, Identifier Name) { |
174 | 23.0k | return new Parameter(Parent, Name, false); |
175 | 23.0k | } |
176 | | |
177 | 0 | Parameter *IRBuilder::createParameter(Function *Parent, llvh::StringRef Name) { |
178 | 0 | return createParameter(Parent, createIdentifier(Name)); |
179 | 0 | } |
180 | | |
181 | 23.1k | Parameter *IRBuilder::createThisParameter(Function *Parent) { |
182 | 23.1k | return new Parameter(Parent, createIdentifier("this"), true); |
183 | 23.1k | } |
184 | | |
185 | | Variable *IRBuilder::createVariable( |
186 | | ScopeDesc *Parent, |
187 | | Variable::DeclKind declKind, |
188 | 23.0k | Identifier Name) { |
189 | 23.0k | return new Variable(Parent, declKind, Name); |
190 | 23.0k | } |
191 | | |
192 | | Variable *IRBuilder::createVariable( |
193 | | ScopeDesc *Parent, |
194 | | Variable::DeclKind declKind, |
195 | 0 | llvh::StringRef Name) { |
196 | 0 | return createVariable(Parent, declKind, createIdentifier(Name)); |
197 | 0 | } |
198 | | |
199 | 676k | LiteralNumber *IRBuilder::getLiteralNumber(double value) { |
200 | 676k | return M->getLiteralNumber(value); |
201 | 676k | } |
202 | | |
203 | | // FIXME: use proper language semantics. |
204 | 2 | LiteralNumber *IRBuilder::getLiteralPositiveZero() { |
205 | 2 | return M->getLiteralNumber(+0.0); |
206 | 2 | } |
207 | | |
208 | 0 | LiteralNumber *IRBuilder::getLiteralNegativeZero() { |
209 | 0 | return M->getLiteralNumber(-0.0); |
210 | 0 | } |
211 | | |
212 | 0 | LiteralNumber *IRBuilder::getLiteralNaN() { |
213 | 0 | return M->getLiteralNumber(std::numeric_limits<double>::quiet_NaN()); |
214 | 0 | } |
215 | | |
216 | 99 | LiteralBigInt *IRBuilder::getLiteralBigInt(UniqueString *value) { |
217 | 99 | return M->getLiteralBigInt(value); |
218 | 99 | } |
219 | | |
220 | 283k | LiteralString *IRBuilder::getLiteralString(llvh::StringRef value) { |
221 | 283k | Identifier Iden = createIdentifier(value); |
222 | 283k | return getLiteralString(Iden); |
223 | 283k | } |
224 | | |
225 | 318k | LiteralString *IRBuilder::getLiteralString(Identifier value) { |
226 | 318k | return M->getLiteralString(value); |
227 | 318k | } |
228 | | |
229 | 323k | LiteralBool *IRBuilder::getLiteralBool(bool value) { |
230 | 323k | return M->getLiteralBool(value); |
231 | 323k | } |
232 | | |
233 | 23.1k | LiteralEmpty *IRBuilder::getLiteralEmpty() { |
234 | 23.1k | return M->getLiteralEmpty(); |
235 | 23.1k | } |
236 | | |
237 | 73.8k | LiteralUndefined *IRBuilder::getLiteralUndefined() { |
238 | 73.8k | return M->getLiteralUndefined(); |
239 | 73.8k | } |
240 | | |
241 | 1.36k | LiteralNull *IRBuilder::getLiteralNull() { |
242 | 1.36k | return M->getLiteralNull(); |
243 | 1.36k | } |
244 | | |
245 | 318k | GlobalObject *IRBuilder::getGlobalObject() { |
246 | 318k | return M->getGlobalObject(); |
247 | 318k | } |
248 | | |
249 | 0 | EmptySentinel *IRBuilder::getEmptySentinel() { |
250 | 0 | return M->getEmptySentinel(); |
251 | 0 | } |
252 | | |
253 | 328k | Identifier IRBuilder::createIdentifier(llvh::StringRef str) { |
254 | 328k | return M->getContext().getIdentifier(str); |
255 | 328k | } |
256 | | |
257 | 62.7k | BranchInst *IRBuilder::createBranchInst(BasicBlock *Destination) { |
258 | 62.7k | auto *BI = new BranchInst(getInsertionBlock(), Destination); |
259 | 62.7k | insert(BI); |
260 | 62.7k | return BI; |
261 | 62.7k | } |
262 | | |
263 | | CondBranchInst * |
264 | 7.62k | IRBuilder::createCondBranchInst(Value *Cond, BasicBlock *T, BasicBlock *F) { |
265 | 7.62k | auto *CBI = new CondBranchInst(getInsertionBlock(), Cond, T, F); |
266 | 7.62k | insert(CBI); |
267 | 7.62k | return CBI; |
268 | 7.62k | } |
269 | | |
270 | 46.2k | ReturnInst *IRBuilder::createReturnInst(Value *Val) { |
271 | 46.2k | auto *RI = new ReturnInst(Val); |
272 | 46.2k | insert(RI); |
273 | 46.2k | return RI; |
274 | 46.2k | } |
275 | | |
276 | 1.64k | CatchInst *IRBuilder::createCatchInst() { |
277 | 1.64k | auto *CI = new CatchInst(); |
278 | 1.64k | insert(CI); |
279 | 1.64k | return CI; |
280 | 1.64k | } |
281 | | |
282 | 775 | ThrowInst *IRBuilder::createThrowInst(Value *thrownValue) { |
283 | 775 | auto *TI = new ThrowInst(thrownValue); |
284 | 775 | insert(TI); |
285 | 775 | return TI; |
286 | 775 | } |
287 | | |
288 | | CheckHasInstanceInst *IRBuilder::createCheckHasInstanceInst( |
289 | | AllocStackInst *result, |
290 | | Value *left, |
291 | | Value *right, |
292 | | BasicBlock *onTrue, |
293 | 0 | BasicBlock *onFalse) { |
294 | 0 | auto *TI = new CheckHasInstanceInst(result, left, right, onTrue, onFalse); |
295 | 0 | insert(TI); |
296 | 0 | return TI; |
297 | 0 | } |
298 | | |
299 | | TryStartInst *IRBuilder::createTryStartInst( |
300 | | BasicBlock *tryBodyBlock, |
301 | 1.64k | BasicBlock *catchTargetBlock) { |
302 | 1.64k | auto *I = new TryStartInst(tryBodyBlock, catchTargetBlock); |
303 | 1.64k | insert(I); |
304 | 1.64k | return I; |
305 | 1.64k | } |
306 | | |
307 | 1.64k | TryEndInst *IRBuilder::createTryEndInst() { |
308 | 1.64k | auto *I = new TryEndInst(); |
309 | 1.64k | insert(I); |
310 | 1.64k | return I; |
311 | 1.64k | } |
312 | | |
313 | 9 | AllocStackInst *IRBuilder::createAllocStackInst(llvh::StringRef varName) { |
314 | 9 | Identifier Iden = createIdentifier(varName); |
315 | 9 | return createAllocStackInst(Iden); |
316 | 9 | } |
317 | | |
318 | 5.03k | AllocStackInst *IRBuilder::createAllocStackInst(Identifier varName) { |
319 | 5.03k | auto *AHI = new AllocStackInst(varName); |
320 | 5.03k | insert(AHI); |
321 | 5.03k | return AHI; |
322 | 5.03k | } |
323 | | |
324 | 474 | AsNumberInst *IRBuilder::createAsNumberInst(Value *val) { |
325 | 474 | auto *ANI = new AsNumberInst(val); |
326 | 474 | insert(ANI); |
327 | 474 | return ANI; |
328 | 474 | } |
329 | | |
330 | 1 | AsNumericInst *IRBuilder::createAsNumericInst(Value *val) { |
331 | 1 | auto *ANI = new AsNumericInst(val); |
332 | 1 | insert(ANI); |
333 | 1 | return ANI; |
334 | 1 | } |
335 | | |
336 | 0 | AsInt32Inst *IRBuilder::createAsInt32Inst(Value *val) { |
337 | 0 | auto *AII = new AsInt32Inst(val); |
338 | 0 | insert(AII); |
339 | 0 | return AII; |
340 | 0 | } |
341 | | |
342 | 0 | AddEmptyStringInst *IRBuilder::createAddEmptyStringInst(Value *val) { |
343 | 0 | auto *I = new AddEmptyStringInst(val); |
344 | 0 | insert(I); |
345 | 0 | return I; |
346 | 0 | } |
347 | | |
348 | | ThrowIfHasRestrictedGlobalPropertyInst * |
349 | | IRBuilder::createThrowIfHasRestrictedGlobalPropertyInst( |
350 | 0 | llvh::StringRef property) { |
351 | 0 | auto *HRGP = |
352 | 0 | new ThrowIfHasRestrictedGlobalPropertyInst(getLiteralString(property)); |
353 | 0 | insert(HRGP); |
354 | 0 | return HRGP; |
355 | 0 | } |
356 | | |
357 | 23.1k | CreateScopeInst *IRBuilder::createCreateScopeInst(ScopeDesc *scopeDesc) { |
358 | 23.1k | auto CII = new CreateScopeInst(scopeDesc); |
359 | 23.1k | insert(CII); |
360 | 23.1k | return CII; |
361 | 23.1k | } |
362 | | |
363 | | CreateInnerScopeInst *IRBuilder::createCreateInnerScopeInst( |
364 | | ScopeCreationInst *parentScope, |
365 | 0 | ScopeDesc *scopeDesc) { |
366 | 0 | auto CISI = new CreateInnerScopeInst(parentScope, scopeDesc); |
367 | 0 | insert(CISI); |
368 | 0 | return CISI; |
369 | 0 | } |
370 | | |
371 | | CreateFunctionInst *IRBuilder::createCreateFunctionInst( |
372 | | Function *code, |
373 | 23.1k | ScopeCreationInst *environment) { |
374 | 23.1k | auto CFI = new CreateFunctionInst(code, environment); |
375 | 23.1k | insert(CFI); |
376 | 23.1k | return CFI; |
377 | 23.1k | } |
378 | | |
379 | | LoadFrameInst *IRBuilder::createLoadFrameInst( |
380 | | Variable *ptr, |
381 | 14.0k | ScopeCreationInst *scope) { |
382 | 14.0k | auto LI = new LoadFrameInst(ptr, scope); |
383 | 14.0k | insert(LI); |
384 | 14.0k | return LI; |
385 | 14.0k | } |
386 | | |
387 | 5.12k | LoadStackInst *IRBuilder::createLoadStackInst(AllocStackInst *ptr) { |
388 | 5.12k | auto LI = new LoadStackInst(ptr); |
389 | 5.12k | insert(LI); |
390 | 5.12k | return LI; |
391 | 5.12k | } |
392 | | |
393 | | StoreFrameInst *IRBuilder::createStoreFrameInst( |
394 | | Value *storedValue, |
395 | | Variable *ptr, |
396 | 23.4k | ScopeCreationInst *scope) { |
397 | 23.4k | auto SI = new StoreFrameInst(storedValue, ptr, scope); |
398 | 23.4k | insert(SI); |
399 | 23.4k | return SI; |
400 | 23.4k | } |
401 | | |
402 | | StoreStackInst *IRBuilder::createStoreStackInst( |
403 | | Value *storedValue, |
404 | 280k | AllocStackInst *ptr) { |
405 | 280k | auto SI = new StoreStackInst(storedValue, ptr); |
406 | 280k | insert(SI); |
407 | 280k | return SI; |
408 | 280k | } |
409 | | |
410 | | CallInst *IRBuilder::createCallInst( |
411 | | LiteralString *textifiedCallee, |
412 | | Value *callee, |
413 | | Value *thisValue, |
414 | 4.58k | ArrayRef<Value *> args) { |
415 | 4.58k | LiteralUndefined *newTarget = getLiteralUndefined(); |
416 | 4.58k | auto CI = new CallInst(textifiedCallee, callee, newTarget, thisValue, args); |
417 | 4.58k | insert(CI); |
418 | 4.58k | return CI; |
419 | 4.58k | } |
420 | | |
421 | | HBCCallNInst *IRBuilder::createHBCCallNInst( |
422 | | LiteralString *textifiedCallee, |
423 | | Value *callee, |
424 | | Value *thisValue, |
425 | 0 | ArrayRef<Value *> args) { |
426 | 0 | LiteralUndefined *newTarget = getLiteralUndefined(); |
427 | 0 | auto CI = |
428 | 0 | new HBCCallNInst(textifiedCallee, callee, newTarget, thisValue, args); |
429 | 0 | insert(CI); |
430 | 0 | return CI; |
431 | 0 | } |
432 | | |
433 | | ConstructInst *IRBuilder::createConstructInst( |
434 | | Value *constructor, |
435 | | Value *newTarget, |
436 | 70 | ArrayRef<Value *> args) { |
437 | 70 | LiteralUndefined *thisValue = getLiteralUndefined(); |
438 | 70 | auto *inst = new ConstructInst(constructor, newTarget, thisValue, args); |
439 | 70 | insert(inst); |
440 | 70 | return inst; |
441 | 70 | } |
442 | | |
443 | | LoadPropertyInst *IRBuilder::createLoadPropertyInst( |
444 | | Value *object, |
445 | 13.8k | Value *property) { |
446 | 13.8k | auto LPI = new LoadPropertyInst(object, property); |
447 | 13.8k | insert(LPI); |
448 | 13.8k | return LPI; |
449 | 13.8k | } |
450 | | |
451 | | TryLoadGlobalPropertyInst *IRBuilder::createTryLoadGlobalPropertyInst( |
452 | 295k | LiteralString *property) { |
453 | 295k | auto *inst = new TryLoadGlobalPropertyInst(getGlobalObject(), property); |
454 | 295k | insert(inst); |
455 | 295k | return inst; |
456 | 295k | } |
457 | | |
458 | | TryLoadGlobalPropertyInst *IRBuilder::createTryLoadGlobalPropertyInst( |
459 | 295k | GlobalObjectProperty *property) { |
460 | 295k | return createTryLoadGlobalPropertyInst(property->getName()); |
461 | 295k | } |
462 | | |
463 | | DeletePropertyInst *IRBuilder::createDeletePropertyInst( |
464 | | Value *object, |
465 | 18.6k | Value *property) { |
466 | 18.6k | auto DPI = new DeletePropertyInst(object, property); |
467 | 18.6k | insert(DPI); |
468 | 18.6k | return DPI; |
469 | 18.6k | } |
470 | | |
471 | | StorePropertyInst *IRBuilder::createStorePropertyInst( |
472 | | Value *storedValue, |
473 | | Value *object, |
474 | 4.19k | Value *property) { |
475 | 4.19k | auto SPI = new StorePropertyInst(storedValue, object, property); |
476 | 4.19k | insert(SPI); |
477 | 4.19k | return SPI; |
478 | 4.19k | } |
479 | | TryStoreGlobalPropertyInst *IRBuilder::createTryStoreGlobalPropertyInst( |
480 | | Value *storedValue, |
481 | 0 | LiteralString *property) { |
482 | 0 | auto *inst = |
483 | 0 | new TryStoreGlobalPropertyInst(storedValue, getGlobalObject(), property); |
484 | 0 | insert(inst); |
485 | 0 | return inst; |
486 | 0 | } |
487 | | TryStoreGlobalPropertyInst *IRBuilder::createTryStoreGlobalPropertyInst( |
488 | | Value *storedValue, |
489 | 0 | GlobalObjectProperty *property) { |
490 | 0 | return createTryStoreGlobalPropertyInst(storedValue, property->getName()); |
491 | 0 | } |
492 | | |
493 | | StoreOwnPropertyInst *IRBuilder::createStoreOwnPropertyInst( |
494 | | Value *storedValue, |
495 | | Value *object, |
496 | | Value *property, |
497 | 247k | PropEnumerable isEnumerable) { |
498 | 247k | auto SPI = new StoreOwnPropertyInst( |
499 | 247k | storedValue, |
500 | 247k | object, |
501 | 247k | property, |
502 | 247k | getLiteralBool(isEnumerable == PropEnumerable::Yes)); |
503 | 247k | insert(SPI); |
504 | 247k | return SPI; |
505 | 247k | } |
506 | | StoreNewOwnPropertyInst *IRBuilder::createStoreNewOwnPropertyInst( |
507 | | Value *storedValue, |
508 | | Value *object, |
509 | | Literal *property, |
510 | 0 | PropEnumerable isEnumerable) { |
511 | 0 | auto *inst = new StoreNewOwnPropertyInst( |
512 | 0 | storedValue, |
513 | 0 | object, |
514 | 0 | property, |
515 | 0 | getLiteralBool(isEnumerable == PropEnumerable::Yes)); |
516 | 0 | insert(inst); |
517 | 0 | return inst; |
518 | 0 | } |
519 | | |
520 | | StoreGetterSetterInst *IRBuilder::createStoreGetterSetterInst( |
521 | | Value *storedGetter, |
522 | | Value *storedSetter, |
523 | | Value *object, |
524 | | Value *property, |
525 | 0 | PropEnumerable isEnumerable) { |
526 | 0 | auto *SGSI = new StoreGetterSetterInst( |
527 | 0 | storedGetter, |
528 | 0 | storedSetter, |
529 | 0 | object, |
530 | 0 | property, |
531 | 0 | getLiteralBool(isEnumerable == PropEnumerable::Yes)); |
532 | 0 | insert(SGSI); |
533 | 0 | return SGSI; |
534 | 0 | } |
535 | | |
536 | | DeletePropertyInst *IRBuilder::createDeletePropertyInst( |
537 | | Value *object, |
538 | 0 | llvh::StringRef property) { |
539 | 0 | Identifier Iden = createIdentifier(property); |
540 | 0 | return createDeletePropertyInst(object, Iden); |
541 | 0 | } |
542 | | |
543 | | LoadPropertyInst *IRBuilder::createLoadPropertyInst( |
544 | | Value *object, |
545 | 1 | llvh::StringRef property) { |
546 | 1 | Identifier Iden = createIdentifier(property); |
547 | 1 | return createLoadPropertyInst(object, Iden); |
548 | 1 | } |
549 | | |
550 | | TryLoadGlobalPropertyInst *IRBuilder::createTryLoadGlobalPropertyInst( |
551 | 1 | llvh::StringRef property) { |
552 | 1 | return createTryLoadGlobalPropertyInst(createIdentifier(property)); |
553 | 1 | } |
554 | | |
555 | | StorePropertyInst *IRBuilder::createStorePropertyInst( |
556 | | Value *storedValue, |
557 | | Value *object, |
558 | 0 | llvh::StringRef property) { |
559 | 0 | Identifier Iden = createIdentifier(property); |
560 | 0 | return createStorePropertyInst(storedValue, object, Iden); |
561 | 0 | } |
562 | | |
563 | | LoadPropertyInst *IRBuilder::createLoadPropertyInst( |
564 | | Value *object, |
565 | 1 | Identifier property) { |
566 | 1 | auto L = getLiteralString(property); |
567 | 1 | return createLoadPropertyInst(object, L); |
568 | 1 | } |
569 | | |
570 | | TryLoadGlobalPropertyInst *IRBuilder::createTryLoadGlobalPropertyInst( |
571 | 1 | Identifier property) { |
572 | 1 | auto *inst = new TryLoadGlobalPropertyInst( |
573 | 1 | getGlobalObject(), getLiteralString(property)); |
574 | 1 | insert(inst); |
575 | 1 | return inst; |
576 | 1 | } |
577 | | |
578 | | DeletePropertyInst *IRBuilder::createDeletePropertyInst( |
579 | | Value *object, |
580 | 0 | Identifier property) { |
581 | 0 | auto L = getLiteralString(property); |
582 | 0 | return createDeletePropertyInst(object, L); |
583 | 0 | } |
584 | | |
585 | | StorePropertyInst *IRBuilder::createStorePropertyInst( |
586 | | Value *storedValue, |
587 | | Value *object, |
588 | 0 | Identifier property) { |
589 | 0 | auto L = getLiteralString(property); |
590 | 0 | return createStorePropertyInst(storedValue, object, L); |
591 | 0 | } |
592 | | |
593 | | TryStoreGlobalPropertyInst *IRBuilder::createTryStoreGlobalPropertyInst( |
594 | | Value *storedValue, |
595 | 0 | Identifier property) { |
596 | 0 | auto *inst = new TryStoreGlobalPropertyInst( |
597 | 0 | storedValue, getGlobalObject(), getLiteralString(property)); |
598 | 0 | insert(inst); |
599 | 0 | return inst; |
600 | 0 | } |
601 | | |
602 | | AllocObjectInst *IRBuilder::createAllocObjectInst( |
603 | | uint32_t size, |
604 | 0 | Value *parent) { |
605 | 0 | auto AOI = new AllocObjectInst( |
606 | 0 | M->getLiteralNumber(size), parent ? parent : getEmptySentinel()); |
607 | 0 | insert(AOI); |
608 | 0 | return AOI; |
609 | 0 | } |
610 | | |
611 | | AllocArrayInst *IRBuilder::createAllocArrayInst( |
612 | | LiteralNumber *sizeHint, |
613 | 67 | AllocArrayInst::ArrayValueList val_list) { |
614 | 67 | auto AAI = new AllocArrayInst(val_list, sizeHint); |
615 | 67 | insert(AAI); |
616 | 67 | return AAI; |
617 | 67 | } |
618 | | |
619 | | AllocArrayInst *IRBuilder::createAllocArrayInst( |
620 | | AllocArrayInst::ArrayValueList val_list, |
621 | 67 | unsigned sizeHint) { |
622 | 67 | return createAllocArrayInst(this->getLiteralNumber(sizeHint), val_list); |
623 | 67 | } |
624 | | |
625 | 23.1k | CreateArgumentsInst *IRBuilder::createCreateArgumentsInst() { |
626 | 23.1k | auto CAI = new CreateArgumentsInst(); |
627 | 23.1k | insert(CAI); |
628 | 23.1k | return CAI; |
629 | 23.1k | } |
630 | | |
631 | 19 | GetNewTargetInst *IRBuilder::createGetNewTargetInst() { |
632 | 19 | auto *inst = new GetNewTargetInst(); |
633 | 19 | insert(inst); |
634 | 19 | return inst; |
635 | 19 | } |
636 | | |
637 | 0 | ThrowIfEmptyInst *IRBuilder::createThrowIfEmptyInst(Value *checkedValue) { |
638 | 0 | auto *inst = new ThrowIfEmptyInst(checkedValue); |
639 | 0 | insert(inst); |
640 | 0 | return inst; |
641 | 0 | } |
642 | | |
643 | 318k | HBCGetGlobalObjectInst *IRBuilder::createHBCGetGlobalObjectInst() { |
644 | 318k | auto inst = new HBCGetGlobalObjectInst(); |
645 | 318k | insert(inst); |
646 | 318k | return inst; |
647 | 318k | } |
648 | | |
649 | | CreateRegExpInst *IRBuilder::createRegExpInst( |
650 | | Identifier pattern, |
651 | 1.43k | Identifier flags) { |
652 | 1.43k | auto res = |
653 | 1.43k | new CreateRegExpInst(getLiteralString(pattern), getLiteralString(flags)); |
654 | 1.43k | insert(res); |
655 | 1.43k | return res; |
656 | 1.43k | } |
657 | | |
658 | | UnaryOperatorInst *IRBuilder::createUnaryOperatorInst( |
659 | | Value *value, |
660 | 8.20k | UnaryOperatorInst::OpKind opKind) { |
661 | 8.20k | auto UOI = new UnaryOperatorInst(value, opKind); |
662 | 8.20k | insert(UOI); |
663 | 8.20k | return UOI; |
664 | 8.20k | } |
665 | | |
666 | | BinaryOperatorInst *IRBuilder::createBinaryOperatorInst( |
667 | | Value *left, |
668 | | Value *right, |
669 | 161k | BinaryOperatorInst::OpKind opKind) { |
670 | 161k | auto BOI = new BinaryOperatorInst(left, right, opKind); |
671 | 161k | insert(BOI); |
672 | 161k | return BOI; |
673 | 161k | } |
674 | | |
675 | | SwitchInst *IRBuilder::createSwitchInst( |
676 | | Value *input, |
677 | | BasicBlock *defaultBlock, |
678 | | const SwitchInst::ValueListType &values, |
679 | 0 | const SwitchInst::BasicBlockListType &blocks) { |
680 | 0 | auto SI = new SwitchInst(input, defaultBlock, values, blocks); |
681 | 0 | insert(SI); |
682 | 0 | return SI; |
683 | 0 | } |
684 | | |
685 | 0 | PhiInst *IRBuilder::createPhiInst() { |
686 | 0 | PhiInst::ValueListType values; |
687 | 0 | PhiInst::BasicBlockListType blocks; |
688 | |
|
689 | 0 | return createPhiInst(values, blocks); |
690 | 0 | } |
691 | | |
692 | | PhiInst *IRBuilder::createPhiInst( |
693 | | const PhiInst::ValueListType &values, |
694 | 3.40k | const PhiInst::BasicBlockListType &blocks) { |
695 | 3.40k | auto PI = new PhiInst(values, blocks); |
696 | 3.40k | insert(PI); |
697 | 3.40k | return PI; |
698 | 3.40k | } |
699 | | |
700 | | GetPNamesInst *IRBuilder::createGetPNamesInst( |
701 | | Value *iteratorAddr, |
702 | | Value *baseAddr, |
703 | | Value *indexAddr, |
704 | | Value *sizeAddr, |
705 | | BasicBlock *onEmpty, |
706 | 9 | BasicBlock *onSome) { |
707 | 9 | auto GP = new GetPNamesInst( |
708 | 9 | getInsertionBlock(), |
709 | 9 | iteratorAddr, |
710 | 9 | baseAddr, |
711 | 9 | indexAddr, |
712 | 9 | sizeAddr, |
713 | 9 | onEmpty, |
714 | 9 | onSome); |
715 | 9 | insert(GP); |
716 | 9 | return GP; |
717 | 9 | } |
718 | | |
719 | | GetNextPNameInst *IRBuilder::createGetNextPNameInst( |
720 | | Value *propertyAddr, |
721 | | Value *baseAddr, |
722 | | Value *indexAddr, |
723 | | Value *sizeAddr, |
724 | | Value *iteratorAddr, |
725 | | BasicBlock *onLast, |
726 | 9 | BasicBlock *onSome) { |
727 | 9 | auto GNP = new GetNextPNameInst( |
728 | 9 | getInsertionBlock(), |
729 | 9 | propertyAddr, |
730 | 9 | baseAddr, |
731 | 9 | indexAddr, |
732 | 9 | sizeAddr, |
733 | 9 | iteratorAddr, |
734 | 9 | onLast, |
735 | 9 | onSome); |
736 | 9 | insert(GNP); |
737 | 9 | return GNP; |
738 | 9 | } |
739 | | |
740 | 542k | MovInst *IRBuilder::createMovInst(Value *input) { |
741 | 542k | auto MI = new MovInst(input); |
742 | 542k | insert(MI); |
743 | 542k | return MI; |
744 | 542k | } |
745 | | |
746 | 14.7k | ImplicitMovInst *IRBuilder::createImplicitMovInst(Value *input) { |
747 | 14.7k | auto IMI = new ImplicitMovInst(input); |
748 | 14.7k | insert(IMI); |
749 | 14.7k | return IMI; |
750 | 14.7k | } |
751 | | |
752 | 0 | CoerceThisNSInst *IRBuilder::createCoerceThisNSInst(Value *input) { |
753 | 0 | auto *inst = new CoerceThisNSInst(input); |
754 | 0 | insert(inst); |
755 | 0 | return inst; |
756 | 0 | } |
757 | | |
758 | 40 | DebuggerInst *IRBuilder::createDebuggerInst() { |
759 | 40 | auto DI = new DebuggerInst(); |
760 | 40 | insert(DI); |
761 | 40 | return DI; |
762 | 40 | } |
763 | | |
764 | | SaveAndYieldInst *IRBuilder::createSaveAndYieldInst( |
765 | | Value *result, |
766 | 0 | BasicBlock *nextBlock) { |
767 | 0 | auto *I = new SaveAndYieldInst(result, nextBlock); |
768 | 0 | insert(I); |
769 | 0 | return I; |
770 | 0 | } |
771 | | |
772 | | CreateGeneratorInst *IRBuilder::createCreateGeneratorInst( |
773 | | Function *innerFn, |
774 | 0 | ScopeCreationInst *environment) { |
775 | 0 | auto *I = new CreateGeneratorInst(innerFn, environment); |
776 | 0 | insert(I); |
777 | 0 | return I; |
778 | 0 | } |
779 | | |
780 | 0 | StartGeneratorInst *IRBuilder::createStartGeneratorInst() { |
781 | 0 | auto *I = new StartGeneratorInst(); |
782 | 0 | insert(I); |
783 | 0 | return I; |
784 | 0 | } |
785 | | |
786 | 0 | ResumeGeneratorInst *IRBuilder::createResumeGeneratorInst(Value *isReturn) { |
787 | 0 | auto *I = new ResumeGeneratorInst(isReturn); |
788 | 0 | insert(I); |
789 | 0 | return I; |
790 | 0 | } |
791 | | |
792 | | HBCResolveEnvironment *IRBuilder::createHBCResolveEnvironment( |
793 | | ScopeDesc *originScopeDesc, |
794 | 595 | ScopeDesc *targetScopeDesc) { |
795 | 595 | auto RSC = new HBCResolveEnvironment(originScopeDesc, targetScopeDesc); |
796 | 595 | insert(RSC); |
797 | 595 | return RSC; |
798 | 595 | } |
799 | | |
800 | | HBCStoreToEnvironmentInst *IRBuilder::createHBCStoreToEnvironmentInst( |
801 | | Value *env, |
802 | | Value *toPut, |
803 | 23.4k | Variable *var) { |
804 | 23.4k | auto PSI = new HBCStoreToEnvironmentInst(env, toPut, var); |
805 | 23.4k | insert(PSI); |
806 | 23.4k | return PSI; |
807 | 23.4k | } |
808 | | |
809 | | HBCLoadFromEnvironmentInst *IRBuilder::createHBCLoadFromEnvironmentInst( |
810 | | Value *env, |
811 | 14.0k | Variable *var) { |
812 | 14.0k | auto GSI = new HBCLoadFromEnvironmentInst(env, var); |
813 | 14.0k | insert(GSI); |
814 | 14.0k | return GSI; |
815 | 14.0k | } |
816 | | |
817 | | SwitchImmInst *IRBuilder::createSwitchImmInst( |
818 | | Value *input, |
819 | | BasicBlock *defaultBlock, |
820 | | LiteralNumber *minValue, |
821 | | LiteralNumber *size, |
822 | | const SwitchImmInst::ValueListType &values, |
823 | 0 | const SwitchImmInst::BasicBlockListType &blocks) { |
824 | 0 | auto inst = |
825 | 0 | new SwitchImmInst(input, defaultBlock, minValue, size, values, blocks); |
826 | 0 | insert(inst); |
827 | 0 | return inst; |
828 | 0 | } |
829 | | |
830 | | DirectEvalInst *IRBuilder::createDirectEvalInst( |
831 | | Value *operand, |
832 | 0 | LiteralBool *isStrict) { |
833 | 0 | auto *inst = new DirectEvalInst(operand, isStrict); |
834 | 0 | insert(inst); |
835 | 0 | return inst; |
836 | 0 | } |
837 | | |
838 | 611k | HBCLoadConstInst *IRBuilder::createHBCLoadConstInst(Literal *value) { |
839 | 611k | auto inst = new HBCLoadConstInst(value); |
840 | 611k | insert(inst); |
841 | 611k | return inst; |
842 | 611k | } |
843 | | |
844 | 23.0k | HBCLoadParamInst *IRBuilder::createHBCLoadParamInst(LiteralNumber *value) { |
845 | 23.0k | auto inst = new HBCLoadParamInst(value); |
846 | 23.0k | insert(inst); |
847 | 23.0k | return inst; |
848 | 23.0k | } |
849 | | |
850 | | HBCCreateEnvironmentInst *IRBuilder::createHBCCreateEnvironmentInst( |
851 | 23.1k | ScopeDesc *scopeDesc) { |
852 | 23.1k | auto inst = new HBCCreateEnvironmentInst(scopeDesc); |
853 | 23.1k | insert(inst); |
854 | 23.1k | return inst; |
855 | 23.1k | } |
856 | | |
857 | | HBCCreateInnerEnvironmentInst *IRBuilder::createHBCCreateInnerEnvironmentInst( |
858 | | ScopeCreationInst *parentScope, |
859 | 0 | ScopeDesc *scopeDesc) { |
860 | 0 | auto inst = new HBCCreateInnerEnvironmentInst(parentScope, scopeDesc); |
861 | 0 | insert(inst); |
862 | 0 | return inst; |
863 | 0 | } |
864 | | |
865 | 19 | HBCGetThisNSInst *IRBuilder::createHBCGetThisNSInst() { |
866 | 19 | auto inst = new HBCGetThisNSInst(); |
867 | 19 | insert(inst); |
868 | 19 | return inst; |
869 | 19 | } |
870 | | HBCGetArgumentsPropByValInst *IRBuilder::createHBCGetArgumentsPropByValInst( |
871 | | Value *index, |
872 | 1 | AllocStackInst *lazyReg) { |
873 | 1 | auto inst = new HBCGetArgumentsPropByValInst(index, lazyReg); |
874 | 1 | insert(inst); |
875 | 1 | return inst; |
876 | 1 | } |
877 | | HBCGetArgumentsLengthInst *IRBuilder::createHBCGetArgumentsLengthInst( |
878 | 0 | AllocStackInst *lazyReg) { |
879 | 0 | auto inst = new HBCGetArgumentsLengthInst(lazyReg); |
880 | 0 | insert(inst); |
881 | 0 | return inst; |
882 | 0 | } |
883 | | HBCReifyArgumentsInst *IRBuilder::createHBCReifyArgumentsInst( |
884 | 13 | AllocStackInst *lazyReg) { |
885 | 13 | auto inst = new HBCReifyArgumentsInst(lazyReg); |
886 | 13 | insert(inst); |
887 | 13 | return inst; |
888 | 13 | } |
889 | | HBCCreateThisInst *IRBuilder::createHBCCreateThisInst( |
890 | | Value *prototype, |
891 | 70 | Value *closure) { |
892 | 70 | auto inst = new HBCCreateThisInst(prototype, closure); |
893 | 70 | insert(inst); |
894 | 70 | return inst; |
895 | 70 | } |
896 | | HBCConstructInst *IRBuilder::createHBCConstructInst( |
897 | | Value *closure, |
898 | | Value *newTarget, |
899 | | Value *thisValue, |
900 | 70 | ArrayRef<Value *> arguments) { |
901 | 70 | auto inst = new HBCConstructInst(closure, newTarget, thisValue, arguments); |
902 | 70 | insert(inst); |
903 | 70 | return inst; |
904 | 70 | } |
905 | | HBCGetConstructedObjectInst *IRBuilder::createHBCGetConstructedObjectInst( |
906 | | HBCCreateThisInst *thisValue, |
907 | 70 | HBCConstructInst *constructorReturnValue) { |
908 | 70 | auto inst = |
909 | 70 | new HBCGetConstructedObjectInst(thisValue, constructorReturnValue); |
910 | 70 | insert(inst); |
911 | 70 | return inst; |
912 | 70 | } |
913 | | |
914 | 0 | HBCProfilePointInst *IRBuilder::createHBCProfilePointInst(uint16_t pointIndex) { |
915 | 0 | auto inst = new HBCProfilePointInst(pointIndex); |
916 | 0 | insert(inst); |
917 | 0 | return inst; |
918 | 0 | } |
919 | | |
920 | | CallBuiltinInst *IRBuilder::createCallBuiltinInst( |
921 | | BuiltinMethod::Enum builtinIndex, |
922 | 14.7k | ArrayRef<Value *> arguments) { |
923 | 14.7k | LiteralUndefined *undefined = getLiteralUndefined(); |
924 | 14.7k | LiteralUndefined *newTarget = undefined; |
925 | 14.7k | LiteralUndefined *thisValue = undefined; |
926 | 14.7k | auto *inst = new CallBuiltinInst( |
927 | 14.7k | getLiteralNumber(builtinIndex), newTarget, thisValue, arguments); |
928 | 14.7k | insert(inst); |
929 | 14.7k | return inst; |
930 | 14.7k | } |
931 | | |
932 | | GetBuiltinClosureInst *IRBuilder::createGetBuiltinClosureInst( |
933 | 0 | BuiltinMethod::Enum builtinIndex) { |
934 | 0 | auto *inst = new GetBuiltinClosureInst(getLiteralNumber(builtinIndex)); |
935 | 0 | insert(inst); |
936 | 0 | return inst; |
937 | 0 | } |
938 | | |
939 | | #ifdef HERMES_RUN_WASM |
940 | | CallIntrinsicInst *IRBuilder::createCallIntrinsicInst( |
941 | | WasmIntrinsics::Enum intrinsicsIndex, |
942 | | ArrayRef<Value *> arguments) { |
943 | | auto *inst = |
944 | | new CallIntrinsicInst(getLiteralNumber(intrinsicsIndex), arguments); |
945 | | insert(inst); |
946 | | return inst; |
947 | | } |
948 | | #endif |
949 | | |
950 | | HBCCallDirectInst *IRBuilder::createHBCCallDirectInst( |
951 | | LiteralString *textifiedCallee, |
952 | | Function *callee, |
953 | | Value *thisValue, |
954 | 0 | ArrayRef<Value *> arguments) { |
955 | 0 | LiteralUndefined *newTarget = getLiteralUndefined(); |
956 | 0 | auto *inst = new HBCCallDirectInst( |
957 | 0 | textifiedCallee, callee, newTarget, thisValue, arguments); |
958 | 0 | insert(inst); |
959 | 0 | return inst; |
960 | 0 | } |
961 | | |
962 | | HBCCreateFunctionInst *IRBuilder::createHBCCreateFunctionInst( |
963 | | Function *function, |
964 | 23.1k | Value *env) { |
965 | 23.1k | auto inst = new HBCCreateFunctionInst(function, env); |
966 | 23.1k | insert(inst); |
967 | 23.1k | return inst; |
968 | 23.1k | } |
969 | | |
970 | 946k | HBCSpillMovInst *IRBuilder::createHBCSpillMovInst(Instruction *value) { |
971 | 946k | auto *inst = new HBCSpillMovInst(value); |
972 | 946k | insert(inst); |
973 | 946k | return inst; |
974 | 946k | } |
975 | | |
976 | | HBCCreateGeneratorInst *IRBuilder::createHBCCreateGeneratorInst( |
977 | | Function *function, |
978 | 0 | Value *env) { |
979 | 0 | auto *inst = new HBCCreateGeneratorInst(function, env); |
980 | 0 | insert(inst); |
981 | 0 | return inst; |
982 | 0 | } |
983 | | |
984 | | HBCAllocObjectFromBufferInst *IRBuilder::createHBCAllocObjectFromBufferInst( |
985 | | HBCAllocObjectFromBufferInst::ObjectPropertyMap prop_map, |
986 | 0 | uint32_t size) { |
987 | 0 | auto *inst = |
988 | 0 | new HBCAllocObjectFromBufferInst(M->getLiteralNumber(size), prop_map); |
989 | 0 | insert(inst); |
990 | 0 | return inst; |
991 | 0 | } |
992 | | |
993 | | CompareBranchInst *IRBuilder::createCompareBranchInst( |
994 | | Value *left, |
995 | | Value *right, |
996 | | BinaryOperatorInst::OpKind opKind, |
997 | | BasicBlock *trueBlock, |
998 | 0 | BasicBlock *falseBlock) { |
999 | 0 | auto *inst = |
1000 | 0 | new CompareBranchInst(left, right, opKind, trueBlock, falseBlock); |
1001 | 0 | insert(inst); |
1002 | 0 | return inst; |
1003 | 0 | } |
1004 | | |
1005 | | IteratorBeginInst *IRBuilder::createIteratorBeginInst( |
1006 | 819 | AllocStackInst *sourceOrNext) { |
1007 | 819 | auto *I = new IteratorBeginInst(sourceOrNext); |
1008 | 819 | insert(I); |
1009 | 819 | return I; |
1010 | 819 | } |
1011 | | |
1012 | | IteratorNextInst *IRBuilder::createIteratorNextInst( |
1013 | | AllocStackInst *iterator, |
1014 | 902 | AllocStackInst *sourceOrNext) { |
1015 | 902 | auto *I = new IteratorNextInst(iterator, sourceOrNext); |
1016 | 902 | insert(I); |
1017 | 902 | return I; |
1018 | 902 | } |
1019 | | |
1020 | | IteratorCloseInst *IRBuilder::createIteratorCloseInst( |
1021 | | AllocStackInst *iterator, |
1022 | 1.59k | bool ignoreInnerException) { |
1023 | 1.59k | auto *I = |
1024 | 1.59k | new IteratorCloseInst(iterator, getLiteralBool(ignoreInnerException)); |
1025 | 1.59k | insert(I); |
1026 | 1.59k | return I; |
1027 | 1.59k | } |
1028 | | |
1029 | 0 | UnreachableInst *IRBuilder::createUnreachableInst() { |
1030 | 0 | auto *I = new UnreachableInst(); |
1031 | 0 | insert(I); |
1032 | 0 | return I; |
1033 | 0 | } |
1034 | | |
1035 | 3.83M | inline void IRBuilder::justInsert(Instruction *Inst) { |
1036 | 3.83M | assert(!Inst->getParent() && "Instr that's already inserted elsewhere"); |
1037 | 3.83M | Inst->setParent(Block); |
1038 | 3.83M | Block->getInstList().insert(InsertionPoint, Inst); |
1039 | 3.83M | } |
1040 | | |
1041 | 3.83M | void IRBuilder::insert(Instruction *Inst) { |
1042 | | // Set the statement of the new instruction based on the current function's |
1043 | | // statement counter. |
1044 | 3.83M | OptValue<uint32_t> statementOpt = getFunction()->getStatementCount(); |
1045 | 3.83M | uint32_t statement; |
1046 | 3.83M | if (LLVM_LIKELY(statementOpt.hasValue())) { |
1047 | 1.28M | statement = *statementOpt; |
1048 | 2.55M | } else { |
1049 | | // If we've cleared the statement count, |
1050 | | // then just set the new instruction's statement to the statement of the |
1051 | | // instruction we're inserting at (0 if it doesn't exist). |
1052 | 2.55M | statement = InsertionPoint != Block->getInstList().end() |
1053 | 2.55M | ? InsertionPoint->getStatementIndex() |
1054 | 2.55M | : 0; |
1055 | 2.55M | } |
1056 | 3.83M | Inst->setStatementIndex(statement); |
1057 | | |
1058 | 3.83M | Inst->setLocation(Location); |
1059 | 3.83M | Inst->setSourceLevelScope(CurrentSourceLevelScope); |
1060 | | |
1061 | 3.83M | return justInsert(Inst); |
1062 | 3.83M | } |
1063 | | |
1064 | 166k | void IRBuilder::setInsertionBlock(BasicBlock *BB) { |
1065 | 166k | if (BB) { |
1066 | 166k | InsertionPoint = BB->end(); |
1067 | 166k | Block = BB; |
1068 | 166k | } else { |
1069 | 147 | InsertionPoint = BasicBlock::iterator(nullptr); |
1070 | 147 | Block = nullptr; |
1071 | 147 | } |
1072 | 166k | } |
1073 | | |
1074 | 127k | BasicBlock *IRBuilder::getInsertionBlock() { |
1075 | 127k | return Block; |
1076 | 127k | } |
1077 | | |
1078 | 6 | void IRBuilder::setInsertionPointAfter(Instruction *IP) { |
1079 | 6 | InsertionPoint = IP->getIterator(); |
1080 | 6 | InsertionPoint++; |
1081 | 6 | Block = IP->getParent(); |
1082 | 6 | } |
1083 | | |
1084 | 2.32M | void IRBuilder::setInsertionPoint(Instruction *IP) { |
1085 | 2.32M | InsertionPoint = IP->getIterator(); |
1086 | 2.32M | Block = IP->getParent(); |
1087 | 2.32M | } |
1088 | | |
1089 | 0 | bool IRBuilder::isInsertionPointValid() { |
1090 | 0 | return InsertionPoint.getNodePtr(); |
1091 | 0 | } |
1092 | | |
1093 | 0 | void IRBuilder::resetInsertionPoint() { |
1094 | 0 | InsertionPoint = BasicBlock::iterator(); |
1095 | 0 | Block = nullptr; |
1096 | 0 | } |
1097 | | |
1098 | 0 | void IRBuilder::transferInstructionToCurrentBlock(Instruction *inst) { |
1099 | 0 | auto *oldBlock = inst->getParent(); |
1100 | 0 | inst->removeFromParent(); |
1101 | 0 | inst->setParent(Block); |
1102 | 0 | Block->getInstList().insert(InsertionPoint, inst); |
1103 | |
|
1104 | 0 | if (oldBlock == Block || !llvh::isa<TerminatorInst>(inst)) |
1105 | 0 | return; |
1106 | | |
1107 | | // If we moved the terminator, we want to update all successors' phi-nodes. |
1108 | 0 | for (auto *use : oldBlock->getUsers()) { |
1109 | 0 | auto *phi = llvh::dyn_cast<PhiInst>(use); |
1110 | 0 | if (!phi) |
1111 | 0 | continue; |
1112 | 0 | for (unsigned i = 0, e = phi->getNumOperands(); i != e; ++i) { |
1113 | 0 | if (phi->getOperand(i) == oldBlock) |
1114 | 0 | phi->setOperand(Block, i); |
1115 | 0 | } |
1116 | 0 | } |
1117 | 0 | } |
1118 | | |
1119 | | Instruction *IRBuilder::cloneInst( |
1120 | | const Instruction *source, |
1121 | 0 | llvh::ArrayRef<Value *> operands) { |
1122 | 0 | Instruction *inst; |
1123 | 0 | switch (source->getKind()) { |
1124 | 0 | #define INCLUDE_ALL_INSTRS |
1125 | 0 | #define DEF_VALUE(name, parent) \ |
1126 | 0 | case ValueKind::name##Kind: \ |
1127 | 0 | inst = new name(cast<name>(source), operands); \ |
1128 | 0 | break; |
1129 | | |
1130 | 0 | #include "hermes/IR/Instrs.def" |
1131 | 0 | #undef INCLUDE_ALL_INSTRS |
1132 | 0 | default: |
1133 | 0 | llvm_unreachable("invalid kind"); |
1134 | 0 | } |
1135 | | |
1136 | 0 | inst->setSourceLevelScope(CurrentSourceLevelScope); |
1137 | 0 | justInsert(inst); |
1138 | 0 | return inst; |
1139 | 0 | } |