1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283 |
- //===--- SpirvFunction.cpp - SPIR-V Function Implementation ------*- C++ -*-==//
- //
- // The LLVM Compiler Infrastructure
- //
- // This file is distributed under the University of Illinois Open Source
- // License. See LICENSE.TXT for details.
- //
- //===----------------------------------------------------------------------===//
- #include "clang/SPIRV/SpirvFunction.h"
- #include "BlockReadableOrder.h"
- #include "clang/SPIRV/SpirvBasicBlock.h"
- #include "clang/SPIRV/SpirvVisitor.h"
- namespace clang {
- namespace spirv {
- SpirvFunction::SpirvFunction(QualType returnType, SpirvType *functionType,
- spv::FunctionControlMask control,
- SourceLocation loc, llvm::StringRef name)
- : functionId(0), astReturnType(returnType), returnType(nullptr),
- returnTypeId(0), fnType(functionType), fnTypeId(0),
- functionControl(control), functionLoc(loc), functionName(name) {}
- bool SpirvFunction::invokeVisitor(Visitor *visitor, bool reverseOrder) {
- if (!visitor->visit(this, Visitor::Phase::Init))
- return false;
- for (auto *param : parameters)
- visitor->visit(param);
- // Collect basic blocks in a human-readable order that satisfies SPIR-V
- // validation rules.
- std::vector<SpirvBasicBlock *> orderedBlocks;
- if (!basicBlocks.empty()) {
- BlockReadableOrderVisitor([&orderedBlocks](SpirvBasicBlock *block) {
- orderedBlocks.push_back(block);
- }).visit(basicBlocks.front());
- }
- SpirvBasicBlock *firstBB = orderedBlocks.empty() ? nullptr : orderedBlocks[0];
- if (reverseOrder)
- std::reverse(orderedBlocks.begin(), orderedBlocks.end());
- for (auto *bb : orderedBlocks) {
- // The first basic block of the function should first visit the function
- // variables.
- if (bb == firstBB) {
- if (!bb->invokeVisitor(visitor, variables, reverseOrder))
- return false;
- }
- // The rest of the basic blocks in the function do not need to visit
- // function variables.
- else {
- if (!bb->invokeVisitor(visitor, {}, reverseOrder))
- return false;
- }
- }
- if (!visitor->visit(this, Visitor::Phase::Done))
- return false;
- return true;
- }
- void SpirvFunction::addParameter(SpirvFunctionParameter *param) {
- assert(param && "cannot add null function parameter");
- parameters.push_back(param);
- }
- void SpirvFunction::addVariable(SpirvVariable *var) {
- assert(var && "cannot add null variable to function");
- variables.push_back(var);
- }
- void SpirvFunction::addBasicBlock(SpirvBasicBlock *bb) {
- assert(bb && "cannot add null basic block to function");
- basicBlocks.push_back(bb);
- }
- } // end namespace spirv
- } // end namespace clang
|