blob: 4acbeba1203ee27455380894c9f3cbc74735de85 [file] [log] [blame]
// Copyright 2023 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.
#include "src/tint/writer/msl/ir/generator_impl_ir.h"
#include "src/tint/ir/validate.h"
#include "src/tint/switch.h"
#include "src/tint/transform/manager.h"
#include "src/tint/type/bool.h"
#include "src/tint/type/f16.h"
#include "src/tint/type/f32.h"
#include "src/tint/type/i32.h"
#include "src/tint/type/u32.h"
#include "src/tint/type/void.h"
#include "src/tint/utils/scoped_assignment.h"
namespace tint::writer::msl {
namespace {
void Sanitize(ir::Module* module) {
transform::Manager manager;
transform::DataMap data;
transform::DataMap outputs;
manager.Run(module, data, outputs);
}
} // namespace
// Helper for calling TINT_UNIMPLEMENTED() from a Switch(object_ptr) default case.
#define UNHANDLED_CASE(object_ptr) \
TINT_UNIMPLEMENTED(Writer, diagnostics_) \
<< "unhandled case in Switch(): " << (object_ptr ? object_ptr->TypeInfo().name : "<null>")
GeneratorImplIr::GeneratorImplIr(ir::Module* module) : IRTextGenerator(module) {}
GeneratorImplIr::~GeneratorImplIr() = default;
bool GeneratorImplIr::Generate() {
auto valid = ir::Validate(*ir_);
if (!valid) {
diagnostics_ = valid.Failure();
return false;
}
// Run the IR transformations to prepare for MSL emission.
Sanitize(ir_);
{
TINT_SCOPED_ASSIGNMENT(current_buffer_, &preamble_buffer_);
line() << "#include <metal_stdlib>";
line();
line() << "using namespace metal;";
}
// Emit module-scope declarations.
if (ir_->root_block) {
// EmitRootBlock(ir_->root_block);
}
// Emit functions.
for (auto* func : ir_->functions) {
EmitFunction(func);
}
if (diagnostics_.contains_errors()) {
return false;
}
return true;
}
void GeneratorImplIr::EmitFunction(ir::Function* func) {
{
auto out = line();
EmitType(out, func->ReturnType());
out << " " << ir_->NameOf(func).Name() << "() {";
}
line() << "}";
}
void GeneratorImplIr::EmitType(utils::StringStream& out, const type::Type* ty) {
tint::Switch(
ty, //
[&](const type::Bool*) { out << "bool"; }, //
[&](const type::Void*) { out << "void"; }, //
[&](const type::F32*) { out << "float"; }, //
[&](const type::F16*) { out << "half"; }, //
[&](const type::I32*) { out << "int"; }, //
[&](const type::U32*) { out << "uint"; }, //
[&](Default) { UNHANDLED_CASE(ty); });
}
} // namespace tint::writer::msl