| 365 | } |
| 366 | |
| 367 | BasicBlock* LoopPeeling::CreateBlockBefore(BasicBlock* bb) { |
| 368 | analysis::DefUseManager* def_use_mgr = context_->get_def_use_mgr(); |
| 369 | CFG& cfg = *context_->cfg(); |
| 370 | assert(cfg.preds(bb->id()).size() == 1 && "More than one predecessor"); |
| 371 | |
| 372 | uint32_t new_id = context_->TakeNextId(); |
| 373 | if (new_id == 0) { |
| 374 | return nullptr; |
| 375 | } |
| 376 | std::unique_ptr<BasicBlock> new_bb = |
| 377 | MakeUnique<BasicBlock>(std::unique_ptr<Instruction>( |
| 378 | new Instruction(context_, spv::Op::OpLabel, 0, new_id, {}))); |
| 379 | // Update the loop descriptor. |
| 380 | Loop* in_loop = (*loop_utils_.GetLoopDescriptor())[bb]; |
| 381 | if (in_loop) { |
| 382 | in_loop->AddBasicBlock(new_bb.get()); |
| 383 | loop_utils_.GetLoopDescriptor()->SetBasicBlockToLoop(new_bb->id(), in_loop); |
| 384 | } |
| 385 | |
| 386 | context_->set_instr_block(new_bb->GetLabelInst(), new_bb.get()); |
| 387 | def_use_mgr->AnalyzeInstDefUse(new_bb->GetLabelInst()); |
| 388 | |
| 389 | BasicBlock* bb_pred = cfg.block(cfg.preds(bb->id())[0]); |
| 390 | bb_pred->tail()->ForEachInId([bb, &new_bb](uint32_t* id) { |
| 391 | if (*id == bb->id()) { |
| 392 | *id = new_bb->id(); |
| 393 | } |
| 394 | }); |
| 395 | cfg.RemoveEdge(bb_pred->id(), bb->id()); |
| 396 | cfg.AddEdge(bb_pred->id(), new_bb->id()); |
| 397 | def_use_mgr->AnalyzeInstUse(&*bb_pred->tail()); |
| 398 | |
| 399 | // Update the incoming branch. |
| 400 | bb->ForEachPhiInst([&new_bb, def_use_mgr](Instruction* phi) { |
| 401 | phi->SetInOperand(1, {new_bb->id()}); |
| 402 | def_use_mgr->AnalyzeInstUse(phi); |
| 403 | }); |
| 404 | InstructionBuilder( |
| 405 | context_, new_bb.get(), |
| 406 | IRContext::kAnalysisDefUse | IRContext::kAnalysisInstrToBlockMapping) |
| 407 | .AddBranch(bb->id()); |
| 408 | cfg.RegisterBlock(new_bb.get()); |
| 409 | |
| 410 | // Add the basic block to the function. |
| 411 | Function::iterator it = loop_utils_.GetFunction()->FindBlock(bb->id()); |
| 412 | assert(it != loop_utils_.GetFunction()->end() && |
| 413 | "Basic block not found in the function."); |
| 414 | BasicBlock* ret = new_bb.get(); |
| 415 | loop_utils_.GetFunction()->AddBasicBlock(std::move(new_bb), it); |
| 416 | return ret; |
| 417 | } |
| 418 | |
| 419 | BasicBlock* LoopPeeling::ProtectLoop(Loop* loop, Instruction* condition, |
| 420 | BasicBlock* if_merge) { |
nothing calls this directly
no test coverage detected