| 661 | } |
| 662 | |
| 663 | bool IdIsAvailableAtUse(opt::IRContext* context, |
| 664 | opt::Instruction* use_instruction, |
| 665 | uint32_t use_input_operand_index, uint32_t id) { |
| 666 | assert(context->get_instr_block(use_instruction) && |
| 667 | "|use_instruction| must be in a basic block"); |
| 668 | |
| 669 | auto defining_instruction = context->get_def_use_mgr()->GetDef(id); |
| 670 | auto enclosing_function = |
| 671 | context->get_instr_block(use_instruction)->GetParent(); |
| 672 | // If the id a function parameter, it needs to be associated with the |
| 673 | // function containing the use. |
| 674 | if (defining_instruction->opcode() == spv::Op::OpFunctionParameter) { |
| 675 | return InstructionIsFunctionParameter(defining_instruction, |
| 676 | enclosing_function); |
| 677 | } |
| 678 | if (!context->get_instr_block(id)) { |
| 679 | // The id must be at global scope. |
| 680 | return true; |
| 681 | } |
| 682 | if (defining_instruction == use_instruction) { |
| 683 | // It is not OK for a definition to use itself. |
| 684 | return false; |
| 685 | } |
| 686 | if (!context->IsReachable(*context->get_instr_block(use_instruction)) || |
| 687 | !context->IsReachable(*context->get_instr_block(id))) { |
| 688 | // Skip unreachable blocks. |
| 689 | return false; |
| 690 | } |
| 691 | auto dominator_analysis = context->GetDominatorAnalysis(enclosing_function); |
| 692 | if (use_instruction->opcode() == spv::Op::OpPhi) { |
| 693 | // In the case where the use is an operand to OpPhi, it is actually the |
| 694 | // *parent* block associated with the operand that must be dominated by |
| 695 | // the synonym. |
| 696 | auto parent_block = |
| 697 | use_instruction->GetSingleWordInOperand(use_input_operand_index + 1); |
| 698 | return dominator_analysis->Dominates( |
| 699 | context->get_instr_block(defining_instruction)->id(), parent_block); |
| 700 | } |
| 701 | return dominator_analysis->Dominates(defining_instruction, use_instruction); |
| 702 | } |
| 703 | |
| 704 | bool IdIsAvailableBeforeInstruction(opt::IRContext* context, |
| 705 | opt::Instruction* instruction, |
no test coverage detected