BlockReadableOrder.h 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. //===--- BlockReadableOrder.h - Visit blocks in human readable order ------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // The SPIR-V spec requires code blocks to appear in an order satisfying the
  11. // dominator-tree direction (ie, dominator before the dominated). This is,
  12. // actually, easy to achieve: any pre-order CFG traversal algorithm will do it.
  13. // Because such algorithms visit a block only after traversing some path to it
  14. // from the root, they necessarily visit the block's immediate dominator first.
  15. //
  16. // But not every graph-traversal algorithm outputs blocks in an order that
  17. // appears logical to human readers. The problem is that unrelated branches may
  18. // be interspersed with each other, and merge blocks may come before some of the
  19. // branches being merged.
  20. //
  21. // A good, human-readable order of blocks may be achieved by performing
  22. // depth-first search but delaying continue and merge nodes until after all
  23. // their branches have been visited. This is implemented below by the
  24. // BlockReadableOrderVisitor.
  25. //
  26. //===----------------------------------------------------------------------===//
  27. #ifndef LLVM_CLANG_LIB_SPIRV_BLOCKREADABLEORDER_H
  28. #define LLVM_CLANG_LIB_SPIRV_BLOCKREADABLEORDER_H
  29. #include "clang/SPIRV/Structure.h"
  30. #include "llvm/ADT/DenseSet.h"
  31. namespace clang {
  32. namespace spirv {
  33. /// \brief A basic block visitor traversing basic blocks in a human readable
  34. /// order and calling a pre-set callback on each basic block.
  35. class BlockReadableOrderVisitor {
  36. public:
  37. explicit BlockReadableOrderVisitor(std::function<void(BasicBlock *)> cb)
  38. : callback(cb) {}
  39. /// \brief Recursively visits all blocks reachable from the given starting
  40. /// basic block in a depth-first manner and calls the callback passed-in
  41. /// during construction on each basic block.
  42. void visit(BasicBlock *block);
  43. private:
  44. std::function<void(BasicBlock *)> callback;
  45. llvm::DenseSet<BasicBlock *> doneBlocks; ///< Blocks already visited
  46. llvm::DenseSet<BasicBlock *> todoBlocks; ///< Blocks to be visited later
  47. };
  48. } // end namespace spirv
  49. } // end namespace clang
  50. #endif