mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-06-25 07:53:32 +00:00
This also refactors break detection. Bug: tint:3 Change-Id: I3a3e01c8d76d7c6fc2a14b3dbff136acd487e802 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/21220 Reviewed-by: dan sinclair <dsinclair@google.com>
214 lines
6.7 KiB
C++
214 lines
6.7 KiB
C++
// Copyright 2020 The Tint Authors.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
#ifndef SRC_READER_SPIRV_CONSTRUCT_H_
|
|
#define SRC_READER_SPIRV_CONSTRUCT_H_
|
|
|
|
#include <cstdint>
|
|
#include <memory>
|
|
#include <ostream>
|
|
#include <sstream>
|
|
#include <vector>
|
|
|
|
namespace tint {
|
|
namespace reader {
|
|
namespace spirv {
|
|
|
|
/// A structured construct, consisting of a set of basic blocks.
|
|
/// A construct is a span of blocks in the computed block order,
|
|
/// and will appear contiguously in the WGSL source.
|
|
struct Construct {
|
|
/// Enumeration for the kinds of structured constructs.
|
|
enum Kind {
|
|
/// The whole function.
|
|
kFunction,
|
|
/// A SPIR-V selection construct, header ending in OpBrancConditional
|
|
kIfSelection,
|
|
/// A SPIR-V selection construct, header ending in OpSwitch
|
|
kSwitchSelection,
|
|
/// A SPIR-V loop construct
|
|
kLoop,
|
|
/// A SPIR-V continue construct
|
|
kContinue,
|
|
};
|
|
|
|
/// Constructor
|
|
/// @param the_parent parent construct
|
|
/// @param the_depth construct nesting depth
|
|
/// @param the_kind construct kind
|
|
/// @param the_begin_id block id of the first block in the construct
|
|
/// @param the_end_id block id of the first block after the construct, or 0
|
|
/// @param the_begin_pos block order position of the_begin_id
|
|
/// @param the_end_pos block order position of the_end_id or a too-large value
|
|
Construct(const Construct* the_parent,
|
|
int the_depth,
|
|
Kind the_kind,
|
|
uint32_t the_begin_id,
|
|
uint32_t the_end_id,
|
|
uint32_t the_begin_pos,
|
|
uint32_t the_end_pos);
|
|
|
|
/// @param pos a block position
|
|
/// @returns true if the given block position is inside this construct.
|
|
bool ContainsPos(uint32_t pos) const {
|
|
return begin_pos <= pos && pos < end_pos;
|
|
}
|
|
|
|
/// The nearest enclosing construct (other than itself), or nullptr if
|
|
/// this construct represents the entire function.
|
|
const Construct* const parent = nullptr;
|
|
/// The nearest enclosing loop construct, if one exists. A construct
|
|
/// encloses itself.
|
|
const Construct* const enclosing_loop = nullptr;
|
|
/// The nearest enclosing continue construct, if one exists. A construct
|
|
/// encloses itself.
|
|
const Construct* const enclosing_continue = nullptr;
|
|
/// The nearest enclosing loop construct or continue construct or
|
|
/// switch-selection construct, if one exists. The signficance is
|
|
/// that a high level language "break" will branch to the merge block
|
|
/// of such an enclosing construct.
|
|
/// A construct encloses itself.
|
|
const Construct* const enclosing_loop_or_continue_or_switch = nullptr;
|
|
|
|
/// Control flow nesting depth. The entry block is at nesting depth 0.
|
|
const int depth = 0;
|
|
/// The construct kind
|
|
const Kind kind = kFunction;
|
|
/// The id of the first block in this structure.
|
|
const uint32_t begin_id = 0;
|
|
/// 0 for kFunction, or the id of the block immediately after this construct
|
|
/// in the computed block order.
|
|
const uint32_t end_id = 0;
|
|
/// The position of block |begin_id| in the computed block order.
|
|
const uint32_t begin_pos = 0;
|
|
/// The position of block |end_id| in the block order, or the number of
|
|
/// block order elements if |end_id| is 0.
|
|
const uint32_t end_pos = 0;
|
|
};
|
|
|
|
using ConstructList = std::vector<std::unique_ptr<Construct>>;
|
|
|
|
/// Converts a construct kind to a string.
|
|
/// @param kind the construct kind to convert
|
|
/// @returns the string representation
|
|
inline std::string ToString(Construct::Kind kind) {
|
|
switch (kind) {
|
|
case Construct::kFunction:
|
|
return "Function";
|
|
case Construct::kIfSelection:
|
|
return "IfSelection";
|
|
case Construct::kSwitchSelection:
|
|
return "SwitchSelection";
|
|
case Construct::kLoop:
|
|
return "Loop";
|
|
case Construct::kContinue:
|
|
return "Continue";
|
|
}
|
|
return "NONE";
|
|
}
|
|
|
|
/// Converts a construct into a short summary string.
|
|
/// @param c the construct, which can be null
|
|
/// @returns a short summary string
|
|
inline std::string ToStringBrief(const Construct* c) {
|
|
if (c) {
|
|
std::stringstream ss;
|
|
ss << ToString(c->kind) << "@" << c->begin_id;
|
|
return ss.str();
|
|
}
|
|
return "null";
|
|
}
|
|
|
|
/// Emits a construct to a stream.
|
|
/// @param o the stream
|
|
/// @param c the structured construct
|
|
/// @returns the stream
|
|
inline std::ostream& operator<<(std::ostream& o, const Construct& c) {
|
|
o << "Construct{ " << ToString(c.kind) << " [" << c.begin_pos << ","
|
|
<< c.end_pos << ")"
|
|
<< " begin_id:" << c.begin_id << " end_id:" << c.end_id
|
|
<< " depth:" << c.depth;
|
|
|
|
o << " parent:" << ToStringBrief(c.parent);
|
|
|
|
if (c.enclosing_loop) {
|
|
o << " in-l:" << ToStringBrief(c.enclosing_loop);
|
|
}
|
|
|
|
if (c.enclosing_continue) {
|
|
o << " in-c:" << ToStringBrief(c.enclosing_continue);
|
|
}
|
|
|
|
if ((c.enclosing_loop_or_continue_or_switch != c.enclosing_loop) &&
|
|
(c.enclosing_loop_or_continue_or_switch != c.enclosing_continue)) {
|
|
o << " in-c-l-s:" << ToStringBrief(c.enclosing_loop_or_continue_or_switch);
|
|
}
|
|
|
|
o << " }";
|
|
return o;
|
|
}
|
|
|
|
/// Emits a construct to a stream.
|
|
/// @param o the stream
|
|
/// @param c the structured construct
|
|
/// @returns the stream
|
|
inline std::ostream& operator<<(std::ostream& o,
|
|
const std::unique_ptr<Construct>& c) {
|
|
return o << *(c.get());
|
|
}
|
|
|
|
/// Converts a construct to a string.
|
|
/// @param c the construct
|
|
/// @returns the string representation
|
|
inline std::string ToString(const Construct& c) {
|
|
std::stringstream ss;
|
|
ss << c;
|
|
return ss.str();
|
|
}
|
|
|
|
/// Converts a unique pointer to a construct to a string.
|
|
/// @param c the construct
|
|
/// @returns the string representation
|
|
inline std::string ToString(const std::unique_ptr<Construct>& c) {
|
|
return ToString(*(c.get()));
|
|
}
|
|
|
|
/// Emits a construct list to a stream.
|
|
/// @param o the stream
|
|
/// @param cl the construct list
|
|
/// @returns the stream
|
|
inline std::ostream& operator<<(std::ostream& o, const ConstructList& cl) {
|
|
o << "ConstructList{\n";
|
|
for (const auto& c : cl) {
|
|
o << " " << c << "\n";
|
|
}
|
|
o << "}";
|
|
return o;
|
|
}
|
|
|
|
/// Converts a construct list to a string.
|
|
/// @param cl the construct list
|
|
/// @returns the string representation
|
|
inline std::string ToString(const ConstructList& cl) {
|
|
std::stringstream ss;
|
|
ss << cl;
|
|
return ss.str();
|
|
}
|
|
|
|
} // namespace spirv
|
|
} // namespace reader
|
|
} // namespace tint
|
|
|
|
#endif // SRC_READER_SPIRV_CONSTRUCT_H_
|