uint32_t
StructuredLoopToSelectionReductionOpportunity::FindOrCreateFunctionVariable(
    uint32_t pointer_type_id) {
  // The pointer type of a function variable must have Function storage class.
  assert(context_->get_type_mgr()
             ->GetType(pointer_type_id)
             ->AsPointer()
             ->storage_class() == SpvStorageClassFunction);

  // Go through the instructions in the function's first block until we find a
  // suitable variable, or go past all the variables.
  BasicBlock::iterator iter = enclosing_function_->begin()->begin();
  for (;; ++iter) {
    // We will either find a suitable variable, or find a non-variable
    // instruction; we won't exhaust all instructions.
    assert(iter != enclosing_function_->begin()->end());
    if (iter->opcode() != SpvOpVariable) {
      // If we see a non-variable, we have gone through all the variables.
      break;
    }
    if (iter->type_id() == pointer_type_id) {
      return iter->result_id();
    }
  }
  // At this point, iter refers to the first non-function instruction of the
  // function's entry block.
  const uint32_t variable_id = context_->TakeNextId();
  std::unique_ptr<Instruction> variable_inst(new Instruction(
      context_, SpvOpVariable, pointer_type_id, variable_id,
      {{SPV_OPERAND_TYPE_STORAGE_CLASS, {SpvStorageClassFunction}}}));
  iter->InsertBefore(std::move(variable_inst));
  return variable_id;
}