blob: b6a864b5adb739a9443c1a12c4d7208743fc8595 [file] [log] [blame]
/* Copyright (c) 2024 LunarG, Inc.
*
* 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 "inject_function_pass.h"
#include "module.h"
namespace gpuav {
namespace spirv {
InjectFunctionPass::InjectFunctionPass(Module& module) : Pass(module) { module.use_bda_ = true; }
bool InjectFunctionPass::Run() {
// Can safely loop function list as there is no injecting of new Functions until linking time
for (const auto& function : module_.functions_) {
for (auto block_it = function->blocks_.begin(); block_it != function->blocks_.end(); ++block_it) {
if ((*block_it)->loop_header_) {
continue; // Currently can't properly handle injecting CFG logic into a loop header block
}
auto& block_instructions = (*block_it)->instructions_;
for (auto inst_it = block_instructions.begin(); inst_it != block_instructions.end(); ++inst_it) {
// Every instruction is analyzed by the specific pass and lets us know if we need to inject a function or not
if (!RequiresInstrumentation(*function, *(inst_it->get()))) continue;
if (module_.max_instrumentations_count_ != 0 && instrumentations_count_ >= module_.max_instrumentations_count_) {
return true; // hit limit
}
instrumentations_count_++;
// Add any debug information to pass into the function call
InjectionData injection_data;
injection_data.stage_info_id = GetStageInfo(*function, block_it, inst_it);
const uint32_t inst_position = target_instruction_->position_index_;
auto inst_position_constant = module_.type_manager_.CreateConstantUInt32(inst_position);
injection_data.inst_position_id = inst_position_constant.Id();
// inst_it is updated to the instruction after the new function call, it will not add/remove any Blocks
CreateFunctionCall(**block_it, &inst_it, injection_data);
Reset();
}
}
}
return instrumentations_count_ != 0;
}
} // namespace spirv
} // namespace gpuav