#include "src/tint/lang/core/ir/validator.h"
#include <algorithm>
#include <cstdint>
#include <memory>
#include <string>
#include <string_view>
#include <utility>
#include "src/tint/lang/core/intrinsic/table.h"
#include "src/tint/lang/core/ir/access.h"
#include "src/tint/lang/core/ir/binary.h"
#include "src/tint/lang/core/ir/bitcast.h"
#include "src/tint/lang/core/ir/block_param.h"
#include "src/tint/lang/core/ir/break_if.h"
#include "src/tint/lang/core/ir/constant.h"
#include "src/tint/lang/core/ir/construct.h"
#include "src/tint/lang/core/ir/continue.h"
#include "src/tint/lang/core/ir/control_instruction.h"
#include "src/tint/lang/core/ir/convert.h"
#include "src/tint/lang/core/ir/core_builtin_call.h"
#include "src/tint/lang/core/ir/disassembler.h"
#include "src/tint/lang/core/ir/discard.h"
#include "src/tint/lang/core/ir/exit_if.h"
#include "src/tint/lang/core/ir/exit_loop.h"
#include "src/tint/lang/core/ir/exit_switch.h"
#include "src/tint/lang/core/ir/function.h"
#include "src/tint/lang/core/ir/function_param.h"
#include "src/tint/lang/core/ir/if.h"
#include "src/tint/lang/core/ir/instruction.h"
#include "src/tint/lang/core/ir/instruction_result.h"
#include "src/tint/lang/core/ir/let.h"
#include "src/tint/lang/core/ir/load.h"
#include "src/tint/lang/core/ir/load_vector_element.h"
#include "src/tint/lang/core/ir/loop.h"
#include "src/tint/lang/core/ir/member_builtin_call.h"
#include "src/tint/lang/core/ir/multi_in_block.h"
#include "src/tint/lang/core/ir/next_iteration.h"
#include "src/tint/lang/core/ir/return.h"
#include "src/tint/lang/core/ir/store.h"
#include "src/tint/lang/core/ir/store_vector_element.h"
#include "src/tint/lang/core/ir/switch.h"
#include "src/tint/lang/core/ir/swizzle.h"
#include "src/tint/lang/core/ir/terminate_invocation.h"
#include "src/tint/lang/core/ir/unary.h"
#include "src/tint/lang/core/ir/unreachable.h"
#include "src/tint/lang/core/ir/unused.h"
#include "src/tint/lang/core/ir/user_call.h"
#include "src/tint/lang/core/ir/var.h"
#include "src/tint/lang/core/type/bool.h"
#include "src/tint/lang/core/type/i8.h"
#include "src/tint/lang/core/type/memory_view.h"
#include "src/tint/lang/core/type/pointer.h"
#include "src/tint/lang/core/type/reference.h"
#include "src/tint/lang/core/type/type.h"
#include "src/tint/lang/core/type/u8.h"
#include "src/tint/lang/core/type/vector.h"
#include "src/tint/lang/core/type/void.h"
#include "src/tint/utils/containers/hashset.h"
#include "src/tint/utils/containers/predicates.h"
#include "src/tint/utils/containers/reverse.h"
#include "src/tint/utils/containers/transform.h"
#include "src/tint/utils/diagnostic/diagnostic.h"
#include "src/tint/utils/ice/ice.h"
#include "src/tint/utils/macros/defer.h"
#include "src/tint/utils/result/result.h"
#include "src/tint/utils/rtti/castable.h"
#include "src/tint/utils/rtti/switch.h"
#include "src/tint/utils/text/styled_text.h"
#include "src/tint/utils/text/text_style.h"
#define TINT_DUMP_IR_WHEN_VALIDATING …
#if TINT_DUMP_IR_WHEN_VALIDATING
#include <iostream>
#include "src/tint/utils/text/styled_text_printer.h"
#endif
usingnamespacetint::core::fluent_types;
namespace tint::core::ir {
namespace {
const Block* ParentBlockOf(const Block* block) { … }
bool TransitivelyHolds(const Block* block, const Instruction* inst) { … }
class Validator { … };
Validator::Validator(const Module& mod, Capabilities capabilities)
: … { … }
Validator::~Validator() = default;
Disassembler& Validator::Disassemble() { … }
Result<SuccessType> Validator::Run() { … }
void Validator::CheckForOrphanedInstructions() { … }
void Validator::CheckForNonFragmentDiscards() { … }
void Validator::RunStructuralSoundnessChecks() { … }
diag::Diagnostic& Validator::AddError(const Instruction* inst) { … }
diag::Diagnostic& Validator::AddError(const Instruction* inst, size_t idx) { … }
diag::Diagnostic& Validator::AddResultError(const Instruction* inst, size_t idx) { … }
diag::Diagnostic& Validator::AddError(const Block* blk) { … }
diag::Diagnostic& Validator::AddError(const BlockParam* param) { … }
diag::Diagnostic& Validator::AddError(const Function* func) { … }
diag::Diagnostic& Validator::AddError(const FunctionParam* param) { … }
diag::Diagnostic& Validator::AddNote(const Instruction* inst) { … }
diag::Diagnostic& Validator::AddNote(const Function* func) { … }
diag::Diagnostic& Validator::AddOperandNote(const Instruction* inst, size_t idx) { … }
diag::Diagnostic& Validator::AddResultNote(const Instruction* inst, size_t idx) { … }
diag::Diagnostic& Validator::AddNote(const Block* blk) { … }
diag::Diagnostic& Validator::AddError(Source src) { … }
diag::Diagnostic& Validator::AddNote(Source src) { … }
void Validator::AddDeclarationNote(const CastableBase* decl) { … }
void Validator::AddDeclarationNote(const Block* block) { … }
void Validator::AddDeclarationNote(const BlockParam* param) { … }
void Validator::AddDeclarationNote(const Function* fn) { … }
void Validator::AddDeclarationNote(const FunctionParam* param) { … }
void Validator::AddDeclarationNote(const Instruction* inst) { … }
void Validator::AddDeclarationNote(const InstructionResult* res) { … }
StyledText Validator::NameOf(const CastableBase* decl) { … }
StyledText Validator::NameOf(const type::Type* ty) { … }
StyledText Validator::NameOf(const Value* value) { … }
StyledText Validator::NameOf(const Instruction* inst) { … }
StyledText Validator::NameOf(const Block* block) { … }
bool Validator::CheckResult(const Instruction* inst, size_t idx) { … }
bool Validator::CheckResults(const ir::Instruction* inst, std::optional<size_t> count = { … }
bool Validator::CheckOperand(const Instruction* inst, size_t idx) { … }
bool Validator::CheckOperands(const ir::Instruction* inst,
size_t min_count,
std::optional<size_t> max_count) { … }
bool Validator::CheckOperands(const ir::Instruction* inst, std::optional<size_t> count = { … }
bool Validator::CheckResultsAndOperandRange(const ir::Instruction* inst,
size_t num_results,
size_t min_operands,
std::optional<size_t> max_operands = { … }
bool Validator::CheckResultsAndOperands(const ir::Instruction* inst,
size_t num_results,
size_t num_operands) { … }
void Validator::CheckOperandNotNull(const Instruction* inst, const ir::Value* operand, size_t idx) { … }
void Validator::CheckType(const core::type::Type* root,
std::function<diag::Diagnostic&()> diag,
Capabilities ignore_caps) { … }
void Validator::CheckRootBlock(const Block* blk) { … }
void Validator::CheckFunction(const Function* func) { … }
void Validator::ProcessTasks() { … }
void Validator::QueueBlock(const Block* blk) { … }
void Validator::BeginBlock(const Block* blk) { … }
void Validator::EndBlock() { … }
void Validator::QueueInstructions(const Instruction* inst) { … }
void Validator::CheckInstruction(const Instruction* inst) { … }
void Validator::CheckVar(const Var* var) { … }
void Validator::CheckLet(const Let* let) { … }
void Validator::CheckCall(const Call* call) { … }
void Validator::CheckBitcast(const Bitcast* bitcast) { … }
void Validator::CheckBuiltinCall(const BuiltinCall* call) { … }
void Validator::CheckMemberBuiltinCall(const MemberBuiltinCall* call) { … }
void Validator::CheckConstruct(const Construct* construct) { … }
void Validator::CheckConvert(const Convert* convert) { … }
void Validator::CheckDiscard(const tint::core::ir::Discard* discard) { … }
void Validator::CheckUserCall(const UserCall* call) { … }
void Validator::CheckAccess(const Access* a) { … }
void Validator::CheckBinary(const Binary* b) { … }
void Validator::CheckUnary(const Unary* u) { … }
void Validator::CheckIf(const If* if_) { … }
void Validator::CheckLoop(const Loop* l) { … }
void Validator::CheckLoopBody(const Loop* loop) { … }
void Validator::CheckLoopContinuing(const Loop* loop) { … }
void Validator::CheckSwitch(const Switch* s) { … }
void Validator::CheckSwizzle(const Swizzle* s) { … }
void Validator::CheckTerminator(const Terminator* b) { … }
void Validator::CheckBreakIf(const BreakIf* b) { … }
void Validator::CheckContinue(const Continue* c) { … }
void Validator::CheckExit(const Exit* e) { … }
void Validator::CheckNextIteration(const NextIteration* n) { … }
void Validator::CheckExitIf(const ExitIf* e) { … }
void Validator::CheckReturn(const Return* ret) { … }
void Validator::CheckControlsAllowingIf(const Exit* exit, const Instruction* control) { … }
void Validator::CheckExitSwitch(const ExitSwitch* s) { … }
void Validator::CheckExitLoop(const ExitLoop* l) { … }
void Validator::CheckLoad(const Load* l) { … }
void Validator::CheckStore(const Store* s) { … }
void Validator::CheckLoadVectorElement(const LoadVectorElement* l) { … }
void Validator::CheckStoreVectorElement(const StoreVectorElement* s) { … }
void Validator::CheckOperandsMatchTarget(const Instruction* source_inst,
size_t source_operand_offset,
size_t source_operand_count,
const CastableBase* target,
VectorRef<const Value*> target_values) { … }
const core::type::Type* Validator::GetVectorPtrElementType(const Instruction* inst, size_t idx) { … }
}
Result<SuccessType> Validate(const Module& mod, Capabilities capabilities) { … }
Result<SuccessType> ValidateAndDumpIfNeeded([[maybe_unused]] const Module& ir,
[[maybe_unused]] const char* msg,
[[maybe_unused]] Capabilities capabilities) { … }
}