Repository: apple/swift
File: include/swift/SIL/NodeDatastructures.h (C/C++)

Code before:
  InstructionWorklist(SILInstruction *initialInstruction)
      : InstructionWorklist(initialInstruction->getFunction()) {
    push(initialInstruction);
  }

  /// Pops the last added element from the worklist or returns null, if the
  /// worklist is empty.
  SILInstruction *pop() {
    if (worklist.empty())
      return nullptr;
    return worklist.pop_back_val();
  }

  /// Pushes \p instruction onto the worklist if \p instruction has never been
  /// push before.
  bool pushIfNotVisited(SILInstruction *instruction) {
    if (visited.insert(instruction)) {
      worklist.push_back(instruction);
      return true;
    }
    return false;
  }

  /// Pushes each user in \p users onto the worklist if that instruction has
  /// never been pushed before. Retures true if any instruction was added.
  bool pushUsersIfNotVisited(ValueBase::UserRange users) {
    bool visited = false;
    for (auto *user : users) {
      visited |= pushIfNotVisited(user);
    }
    return visited;
  }

  /// Like `pushIfNotVisited`, but requires that \p instruction has never been
  /// on the worklist before.
  void push(SILInstruction *instruction) {
    assert(!visited.contains(instruction));
    visited.insert(instruction);
    worklist.push_back(instruction);
  }

  /// Like `pop`, but marks the returned instruction as "unvisited". This means,
  /// that the instruction can be pushed onto the worklist again.
  SILInstruction *popAndForget() {
    if (worklist.empty())
      return nullptr;
    SILInstruction *instruction = worklist.pop_back_val();
    visited.erase(instruction);
    return instruction;
  }


Review comment (suggestion):
Question. Why not templatize this on collections. Then it can be used also for ArrayRef, SmallVector/etc.

Code after:
  InstructionWorklist(SILInstruction *initialInstruction)
      : InstructionWorklist(initialInstruction->getFunction()) {
    push(initialInstruction);
  }

  /// Pops the last added element from the worklist or returns null, if the
  /// worklist is empty.
  SILInstruction *pop() {
    if (worklist.empty())
      return nullptr;
    return worklist.pop_back_val();
  }

  /// Pushes \p instruction onto the worklist if \p instruction has never been
  /// push before.
  bool pushIfNotVisited(SILInstruction *instruction) {
    if (visited.insert(instruction)) {
      worklist.push_back(instruction);
      return true;
    }
    return false;
  }

  /// Pushes each instruction in \p instructions onto the worklist if that
  /// instruction has never been pushed before. Returns true if any instruction
  /// was added.
  template <typename Collection>
  bool pushInstructionsIfNotVisited(Collection &&instructions) {
    bool visited = false;
    for (auto *instruction : instructions) {
      visited |= pushIfNotVisited(instruction);
    }
    return visited;
  }

  /// Like `pushIfNotVisited`, but requires that \p instruction has never been
  /// on the worklist before.
  void push(SILInstruction *instruction) {
    assert(!visited.contains(instruction));
    visited.insert(instruction);
    worklist.push_back(instruction);
  }

  /// Like `pop`, but marks the returned instruction as "unvisited". This means,
  /// that the instruction can be pushed onto the worklist again.
  SILInstruction *popAndForget() {
    if (worklist.empty())
      return nullptr;
    SILInstruction *instruction = worklist.pop_back_val();
    visited.erase(instruction);
    return instruction;