SpirvFunction.cpp 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. //===--- SpirvFunction.cpp - SPIR-V Function Implementation ------*- C++ -*-==//
  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. #include "clang/SPIRV/SpirvFunction.h"
  10. #include "BlockReadableOrder.h"
  11. #include "clang/SPIRV/SpirvBasicBlock.h"
  12. #include "clang/SPIRV/SpirvVisitor.h"
  13. namespace clang {
  14. namespace spirv {
  15. SpirvFunction::SpirvFunction(QualType returnType, SpirvType *functionType,
  16. spv::FunctionControlMask control,
  17. SourceLocation loc, llvm::StringRef name)
  18. : functionId(0), astReturnType(returnType), returnType(nullptr),
  19. returnTypeId(0), fnType(functionType), fnTypeId(0),
  20. functionControl(control), functionLoc(loc), functionName(name) {}
  21. bool SpirvFunction::invokeVisitor(Visitor *visitor, bool reverseOrder) {
  22. if (!visitor->visit(this, Visitor::Phase::Init))
  23. return false;
  24. for (auto *param : parameters)
  25. visitor->visit(param);
  26. // Collect basic blocks in a human-readable order that satisfies SPIR-V
  27. // validation rules.
  28. std::vector<SpirvBasicBlock *> orderedBlocks;
  29. if (!basicBlocks.empty()) {
  30. BlockReadableOrderVisitor([&orderedBlocks](SpirvBasicBlock *block) {
  31. orderedBlocks.push_back(block);
  32. }).visit(basicBlocks.front());
  33. }
  34. SpirvBasicBlock *firstBB = orderedBlocks.empty() ? nullptr : orderedBlocks[0];
  35. if (reverseOrder)
  36. std::reverse(orderedBlocks.begin(), orderedBlocks.end());
  37. for (auto *bb : orderedBlocks) {
  38. // The first basic block of the function should first visit the function
  39. // variables.
  40. if (bb == firstBB) {
  41. if (!bb->invokeVisitor(visitor, variables, reverseOrder))
  42. return false;
  43. }
  44. // The rest of the basic blocks in the function do not need to visit
  45. // function variables.
  46. else {
  47. if (!bb->invokeVisitor(visitor, {}, reverseOrder))
  48. return false;
  49. }
  50. }
  51. if (!visitor->visit(this, Visitor::Phase::Done))
  52. return false;
  53. return true;
  54. }
  55. void SpirvFunction::addParameter(SpirvFunctionParameter *param) {
  56. assert(param && "cannot add null function parameter");
  57. parameters.push_back(param);
  58. }
  59. void SpirvFunction::addVariable(SpirvVariable *var) {
  60. assert(var && "cannot add null variable to function");
  61. variables.push_back(var);
  62. }
  63. void SpirvFunction::addBasicBlock(SpirvBasicBlock *bb) {
  64. assert(bb && "cannot add null basic block to function");
  65. basicBlocks.push_back(bb);
  66. }
  67. } // end namespace spirv
  68. } // end namespace clang