242 {
245 BlockEntryInstr* call_block = call_->
GetBlock();
246
247
248 BlockEntryInstr* callee_exit = nullptr;
249 Instruction* callee_last_instruction = nullptr;
250
251 if (exits_.
length() == 0) {
252
253
254
255
256
257
258 TargetEntryInstr* false_block =
new (
Z) TargetEntryInstr(
262 false_block->LinkTo(call_->
next());
263 call_block->ReplaceAsPredecessorWith(false_block);
264
266 BranchInstr* branch =
new (
Z) BranchInstr(
267 new (
Z) StrictCompareInstr(InstructionSource(), Token::kEQ_STRICT,
268 new (
Z)
Value(true_const),
269 new (
Z)
Value(true_const),
false,
273
275 callee_entry->ReplaceAsPredecessorWith(true_target);
276
277 *branch->true_successor_address() = true_target;
278 *branch->false_successor_address() = false_block;
279
281 call_block->set_last_instruction(branch);
282
283
284
286
287
288 for (intptr_t
i = 0, n = callee_entry->dominated_blocks().length();
i < n;
290 BlockEntryInstr* block = callee_entry->dominated_blocks()[
i];
291 true_target->AddDominatedBlock(block);
292 }
293 for (intptr_t
i = 0, n = call_block->dominated_blocks().length();
i < n;
295 BlockEntryInstr* block = call_block->dominated_blocks()[
i];
296 false_block->AddDominatedBlock(block);
297 }
298 call_block->ClearDominatedBlocks();
299 call_block->AddDominatedBlock(true_target);
300 call_block->AddDominatedBlock(false_block);
301
302 } else {
303 Definition* callee_result = JoinReturns(
304 &callee_exit, &callee_last_instruction, call_block->try_index());
305 if (callee_result != nullptr) {
307 }
308 if (callee_last_instruction == callee_entry) {
309
310
311
313 } else {
315 callee_last_instruction->LinkTo(call_->
next());
316 }
317 if (callee_exit != callee_entry) {
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340 call_block->ReplaceAsPredecessorWith(callee_exit);
341
342
343 callee_entry->ReplaceAsPredecessorWith(call_block);
344
345
346
347 ASSERT(callee_exit->dominated_blocks().is_empty());
348 for (intptr_t
i = 0;
i < call_block->dominated_blocks().
length(); ++
i) {
349 BlockEntryInstr* block = call_block->dominated_blocks()[
i];
350 callee_exit->AddDominatedBlock(block);
351 }
352
353
354 call_block->ClearDominatedBlocks();
355 for (intptr_t
i = 0;
i < callee_entry->dominated_blocks().
length(); ++
i) {
356 BlockEntryInstr* block = callee_entry->dominated_blocks()[
i];
357 call_block->AddDominatedBlock(block);
358 }
359 }
360
361
362 callee_entry->UnuseAllInputs();
363 }
364
365
366 if (callee_entry->PredecessorCount() > 0) {
367 callee_entry->PredecessorAt(0)->AsGraphEntry()->UnuseAllInputs();
368 }
370}
static const Bool & True()
static TargetEntryInstr * ToTargetEntry(Zone *zone, BlockEntryInstr *target)
intptr_t GetNextDeoptId()
static CompilerState & Current()
void ReplaceUsesWith(Definition *other)
ConstantInstr * GetConstant(const Object &object, Representation representation=kTagged)
intptr_t allocate_block_id()
Instruction * next() const
void InheritDeoptTargetAfter(FlowGraph *flow_graph, Definition *call, Definition *result)
void LinkTo(Instruction *next)
void InheritDeoptTarget(Zone *zone, Instruction *other)
virtual BlockEntryInstr * GetBlock()
Instruction * AppendInstruction(Instruction *tail)
Instruction * previous() const