Add option to validate after each pass (#2462)

* New command-line option to opt: --validate-after-all
 * Pass manager will validate after each pass it runs
This commit is contained in:
alan-baker 2019-03-26 14:38:59 -04:00 коммит произвёл GitHub
Родитель fb0753640a
Коммит 42e6f1aa62
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
5 изменённых файлов: 56 добавлений и 1 удалений

Просмотреть файл

@ -199,6 +199,9 @@ class Optimizer {
// |out| output stream.
Optimizer& SetTimeReport(std::ostream* out);
// Sets the option to validate the module after each pass.
Optimizer& SetValidateAfterAll(bool validate);
private:
struct Impl; // Opaque struct for holding internal data.
std::unique_ptr<Impl> impl_; // Unique pointer to internal data.

Просмотреть файл

@ -507,6 +507,8 @@ bool Optimizer::Run(const uint32_t* original_binary,
context->set_max_id_bound(opt_options->max_id_bound_);
impl_->pass_manager.SetValidatorOptions(&opt_options->val_options_);
impl_->pass_manager.SetTargetEnv(impl_->target_env);
auto status = impl_->pass_manager.Run(context.get());
if (status == opt::Pass::Status::SuccessWithChange ||
(status == opt::Pass::Status::SuccessWithoutChange &&
@ -529,6 +531,11 @@ Optimizer& Optimizer::SetTimeReport(std::ostream* out) {
return *this;
}
Optimizer& Optimizer::SetValidateAfterAll(bool validate) {
impl_->pass_manager.SetValidateAfterAll(validate);
return *this;
}
Optimizer::PassToken CreateNullPass() {
return MakeUnique<Optimizer::PassToken::Impl>(MakeUnique<opt::NullPass>());
}

Просмотреть файл

@ -51,6 +51,20 @@ Pass::Status PassManager::Run(IRContext* context) {
if (one_status == Pass::Status::Failure) return one_status;
if (one_status == Pass::Status::SuccessWithChange) status = one_status;
if (validate_after_all_) {
spvtools::SpirvTools tools(target_env_);
tools.SetMessageConsumer(consumer());
std::vector<uint32_t> binary;
context->module()->ToBinary(&binary, true);
if (!tools.Validate(binary.data(), binary.size(), val_options_)) {
std::string msg = "Validation failed after pass ";
msg += pass->name();
spv_position_t null_pos{0, 0, 0};
consumer()(SPV_MSG_INTERNAL_ERROR, "", null_pos, msg.c_str());
return Pass::Status::Failure;
}
}
// Reset the pass to free any memory used by the pass.
pass.reset(nullptr);
}

Просмотреть файл

@ -43,7 +43,10 @@ class PassManager {
PassManager()
: consumer_(nullptr),
print_all_stream_(nullptr),
time_report_stream_(nullptr) {}
time_report_stream_(nullptr),
target_env_(SPV_ENV_UNIVERSAL_1_2),
val_options_(nullptr),
validate_after_all_(false) {}
// Sets the message consumer to the given |consumer|.
void SetMessageConsumer(MessageConsumer c) { consumer_ = std::move(c); }
@ -89,6 +92,24 @@ class PassManager {
return *this;
}
// Sets the target environment for validation.
PassManager& SetTargetEnv(spv_target_env env) {
target_env_ = env;
return *this;
}
// Sets the validation options.
PassManager& SetValidatorOptions(spv_validator_options options) {
val_options_ = options;
return *this;
}
// Sets the option to validate after each pass.
PassManager& SetValidateAfterAll(bool validate) {
validate_after_all_ = validate;
return *this;
}
private:
// Consumer for messages.
MessageConsumer consumer_;
@ -100,6 +121,12 @@ class PassManager {
// The output stream to write the resource utilization of each pass. If this
// is null, no output is generated.
std::ostream* time_report_stream_;
// The target environment.
spv_target_env target_env_;
// The validator options (used when validating each pass).
spv_validator_options val_options_;
// Controls whether validation occurs after every pass.
bool validate_after_all_;
};
inline void PassManager::AddPass(std::unique_ptr<Pass> pass) {

Просмотреть файл

@ -384,6 +384,8 @@ Options (in lexicographical order):
Current workarounds: Avoid OpUnreachable in loops.
--unify-const
Remove the duplicated constants.
--validate-after-all
Validate the module after each pass is performed.
-h, --help
Print this help.
--version
@ -628,6 +630,8 @@ OptStatus ParseFlags(int argc, const char** argv,
optimizer->SetTargetEnv(SPV_ENV_WEBGPU_0);
optimizer->RegisterWebGPUPasses();
} else if (0 == strcmp(cur_arg, "--validate-after-all")) {
optimizer->SetValidateAfterAll(true);
} else {
// Some passes used to accept the form '--pass arg', canonicalize them
// to '--pass=arg'.