13f30b6202dd5ad6ff66959131d216405850ed152Yang Ni/* 23f30b6202dd5ad6ff66959131d216405850ed152Yang Ni * Copyright 2017, The Android Open Source Project 33f30b6202dd5ad6ff66959131d216405850ed152Yang Ni * 43f30b6202dd5ad6ff66959131d216405850ed152Yang Ni * Licensed under the Apache License, Version 2.0 (the "License"); 53f30b6202dd5ad6ff66959131d216405850ed152Yang Ni * you may not use this file except in compliance with the License. 63f30b6202dd5ad6ff66959131d216405850ed152Yang Ni * You may obtain a copy of the License at 73f30b6202dd5ad6ff66959131d216405850ed152Yang Ni * 83f30b6202dd5ad6ff66959131d216405850ed152Yang Ni * http://www.apache.org/licenses/LICENSE-2.0 93f30b6202dd5ad6ff66959131d216405850ed152Yang Ni * 103f30b6202dd5ad6ff66959131d216405850ed152Yang Ni * Unless required by applicable law or agreed to in writing, software 113f30b6202dd5ad6ff66959131d216405850ed152Yang Ni * distributed under the License is distributed on an "AS IS" BASIS, 123f30b6202dd5ad6ff66959131d216405850ed152Yang Ni * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133f30b6202dd5ad6ff66959131d216405850ed152Yang Ni * See the License for the specific language governing permissions and 143f30b6202dd5ad6ff66959131d216405850ed152Yang Ni * limitations under the License. 153f30b6202dd5ad6ff66959131d216405850ed152Yang Ni */ 163f30b6202dd5ad6ff66959131d216405850ed152Yang Ni 173f30b6202dd5ad6ff66959131d216405850ed152Yang Ni#include "pass_queue.h" 183f30b6202dd5ad6ff66959131d216405850ed152Yang Ni 193f30b6202dd5ad6ff66959131d216405850ed152Yang Ni#include "module.h" 203f30b6202dd5ad6ff66959131d216405850ed152Yang Ni 213f30b6202dd5ad6ff66959131d216405850ed152Yang Ninamespace android { 223f30b6202dd5ad6ff66959131d216405850ed152Yang Ninamespace spirit { 233f30b6202dd5ad6ff66959131d216405850ed152Yang Ni 243f30b6202dd5ad6ff66959131d216405850ed152Yang Nibool PassQueue::append(Pass *pass) { 253f30b6202dd5ad6ff66959131d216405850ed152Yang Ni mPasses.push_back(pass); 263f30b6202dd5ad6ff66959131d216405850ed152Yang Ni mPassSet.insert(pass); 273f30b6202dd5ad6ff66959131d216405850ed152Yang Ni return true; 283f30b6202dd5ad6ff66959131d216405850ed152Yang Ni} 293f30b6202dd5ad6ff66959131d216405850ed152Yang Ni 303f30b6202dd5ad6ff66959131d216405850ed152Yang NiModule *PassQueue::run(Module *module, int *error) { 313f30b6202dd5ad6ff66959131d216405850ed152Yang Ni if (mPasses.empty()) { 323f30b6202dd5ad6ff66959131d216405850ed152Yang Ni return module; 333f30b6202dd5ad6ff66959131d216405850ed152Yang Ni } 343f30b6202dd5ad6ff66959131d216405850ed152Yang Ni 353f30b6202dd5ad6ff66959131d216405850ed152Yang Ni // A unique ptr to keep intermediate modules from leaking 363f30b6202dd5ad6ff66959131d216405850ed152Yang Ni std::unique_ptr<Module> tempModule; 373f30b6202dd5ad6ff66959131d216405850ed152Yang Ni 383f30b6202dd5ad6ff66959131d216405850ed152Yang Ni for (auto pass : mPasses) { 393f30b6202dd5ad6ff66959131d216405850ed152Yang Ni int intermediateError = 0; 403f30b6202dd5ad6ff66959131d216405850ed152Yang Ni Module* newModule = pass->run(module, &intermediateError); 413f30b6202dd5ad6ff66959131d216405850ed152Yang Ni // Some passes modify the input module in place, while others create a new 423f30b6202dd5ad6ff66959131d216405850ed152Yang Ni // module. Release memory only when it is necessary. 433f30b6202dd5ad6ff66959131d216405850ed152Yang Ni if (newModule != module) { 443f30b6202dd5ad6ff66959131d216405850ed152Yang Ni tempModule.reset(newModule); 453f30b6202dd5ad6ff66959131d216405850ed152Yang Ni } 463f30b6202dd5ad6ff66959131d216405850ed152Yang Ni module = newModule; 473f30b6202dd5ad6ff66959131d216405850ed152Yang Ni if (intermediateError) { 483f30b6202dd5ad6ff66959131d216405850ed152Yang Ni if (error) { 493f30b6202dd5ad6ff66959131d216405850ed152Yang Ni *error = intermediateError; 503f30b6202dd5ad6ff66959131d216405850ed152Yang Ni } 513f30b6202dd5ad6ff66959131d216405850ed152Yang Ni return nullptr; 523f30b6202dd5ad6ff66959131d216405850ed152Yang Ni } 533f30b6202dd5ad6ff66959131d216405850ed152Yang Ni if (!module || !module->resolveIds()) { 543f30b6202dd5ad6ff66959131d216405850ed152Yang Ni if (error) { 553f30b6202dd5ad6ff66959131d216405850ed152Yang Ni *error = -1; 563f30b6202dd5ad6ff66959131d216405850ed152Yang Ni } 573f30b6202dd5ad6ff66959131d216405850ed152Yang Ni return nullptr; 583f30b6202dd5ad6ff66959131d216405850ed152Yang Ni } 593f30b6202dd5ad6ff66959131d216405850ed152Yang Ni } 603f30b6202dd5ad6ff66959131d216405850ed152Yang Ni 613f30b6202dd5ad6ff66959131d216405850ed152Yang Ni if (tempModule == nullptr) { 623f30b6202dd5ad6ff66959131d216405850ed152Yang Ni return module; 633f30b6202dd5ad6ff66959131d216405850ed152Yang Ni } 643f30b6202dd5ad6ff66959131d216405850ed152Yang Ni 653f30b6202dd5ad6ff66959131d216405850ed152Yang Ni return tempModule.release(); 663f30b6202dd5ad6ff66959131d216405850ed152Yang Ni} 673f30b6202dd5ad6ff66959131d216405850ed152Yang Ni 683f30b6202dd5ad6ff66959131d216405850ed152Yang Nistd::vector<uint32_t> PassQueue::run(const std::vector<uint32_t> &spirvWords, 693f30b6202dd5ad6ff66959131d216405850ed152Yang Ni int *error) { 703f30b6202dd5ad6ff66959131d216405850ed152Yang Ni if (mPasses.empty()) { 713f30b6202dd5ad6ff66959131d216405850ed152Yang Ni return spirvWords; 723f30b6202dd5ad6ff66959131d216405850ed152Yang Ni } 733f30b6202dd5ad6ff66959131d216405850ed152Yang Ni 743e5fbb6faf66488ba49c9d2396350ae567dba315Yang Ni Module *module = Deserialize<Module>(spirvWords); 753f30b6202dd5ad6ff66959131d216405850ed152Yang Ni if (!module || !module->resolveIds()) { 763f30b6202dd5ad6ff66959131d216405850ed152Yang Ni return std::vector<uint32_t>(); 773f30b6202dd5ad6ff66959131d216405850ed152Yang Ni } 783f30b6202dd5ad6ff66959131d216405850ed152Yang Ni 793f30b6202dd5ad6ff66959131d216405850ed152Yang Ni return runAndSerialize(module, error); 803f30b6202dd5ad6ff66959131d216405850ed152Yang Ni} 813f30b6202dd5ad6ff66959131d216405850ed152Yang Ni 823f30b6202dd5ad6ff66959131d216405850ed152Yang Nistd::vector<uint32_t> PassQueue::runAndSerialize(Module *module, int *error) { 833f30b6202dd5ad6ff66959131d216405850ed152Yang Ni const int n = mPasses.size(); 843f30b6202dd5ad6ff66959131d216405850ed152Yang Ni if (n < 1) { 853e5fbb6faf66488ba49c9d2396350ae567dba315Yang Ni return Serialize<Module>(module); 863f30b6202dd5ad6ff66959131d216405850ed152Yang Ni } 873f30b6202dd5ad6ff66959131d216405850ed152Yang Ni 883f30b6202dd5ad6ff66959131d216405850ed152Yang Ni // A unique ptr to keep intermediate modules from leaking 893f30b6202dd5ad6ff66959131d216405850ed152Yang Ni std::unique_ptr<Module> tempModule; 903f30b6202dd5ad6ff66959131d216405850ed152Yang Ni 913f30b6202dd5ad6ff66959131d216405850ed152Yang Ni for (int i = 0; i < n - 1; i++) { 923f30b6202dd5ad6ff66959131d216405850ed152Yang Ni int intermediateError = 0; 933f30b6202dd5ad6ff66959131d216405850ed152Yang Ni Module *newModule = mPasses[i]->run(module, &intermediateError); 943f30b6202dd5ad6ff66959131d216405850ed152Yang Ni // Some passes modify the input module in place, while others create a new 953f30b6202dd5ad6ff66959131d216405850ed152Yang Ni // module. Release memory only when it is necessary. 963f30b6202dd5ad6ff66959131d216405850ed152Yang Ni if (newModule != module) { 973f30b6202dd5ad6ff66959131d216405850ed152Yang Ni tempModule.reset(newModule); 983f30b6202dd5ad6ff66959131d216405850ed152Yang Ni } 993f30b6202dd5ad6ff66959131d216405850ed152Yang Ni module = newModule; 1003f30b6202dd5ad6ff66959131d216405850ed152Yang Ni if (intermediateError) { 1013f30b6202dd5ad6ff66959131d216405850ed152Yang Ni if (error) { 1023f30b6202dd5ad6ff66959131d216405850ed152Yang Ni *error = intermediateError; 1033f30b6202dd5ad6ff66959131d216405850ed152Yang Ni } 1043f30b6202dd5ad6ff66959131d216405850ed152Yang Ni return std::vector<uint32_t>(); 1053f30b6202dd5ad6ff66959131d216405850ed152Yang Ni } 1063f30b6202dd5ad6ff66959131d216405850ed152Yang Ni if (!module || !module->resolveIds()) { 1073f30b6202dd5ad6ff66959131d216405850ed152Yang Ni if (error) { 1083f30b6202dd5ad6ff66959131d216405850ed152Yang Ni *error = -1; 1093f30b6202dd5ad6ff66959131d216405850ed152Yang Ni } 1103f30b6202dd5ad6ff66959131d216405850ed152Yang Ni return std::vector<uint32_t>(); 1113f30b6202dd5ad6ff66959131d216405850ed152Yang Ni } 1123f30b6202dd5ad6ff66959131d216405850ed152Yang Ni } 1133f30b6202dd5ad6ff66959131d216405850ed152Yang Ni return mPasses[n - 1]->runAndSerialize(module, error); 1143f30b6202dd5ad6ff66959131d216405850ed152Yang Ni} 1153f30b6202dd5ad6ff66959131d216405850ed152Yang Ni 1163f30b6202dd5ad6ff66959131d216405850ed152Yang Ni} // namespace spirit 1173f30b6202dd5ad6ff66959131d216405850ed152Yang Ni} // namespace android 118