Add whitelist filtering for debug comments in SPIRV-Remap.

This commit is contained in:
ahagan 2022-04-26 23:36:57 -04:00
parent e3bca2add6
commit b5aae62731
4 changed files with 72 additions and 15 deletions

View File

@ -160,15 +160,30 @@ namespace spv {
} }
// Is this an opcode we should remove when using --strip? // Is this an opcode we should remove when using --strip?
bool spirvbin_t::isStripOp(spv::Op opCode) const bool spirvbin_t::isStripOp(spv::Op opCode, unsigned start) const
{ {
switch (opCode) { switch (opCode) {
case spv::OpSource: case spv::OpSource:
case spv::OpSourceExtension: case spv::OpSourceExtension:
case spv::OpName: case spv::OpName:
case spv::OpMemberName: case spv::OpMemberName:
case spv::OpLine: return true; case spv::OpLine :
default: return false; {
const spv::Id target = asId(start + 1);
const std::string name = literalString(start + 2);
std::vector<std::string>::const_iterator it;
for (it = stripWhiteList.begin(); it < stripWhiteList.end(); it++)
{
if (name.find(*it) != std::string::npos) {
return false;
}
}
return true;
}
default :
return false;
} }
} }
@ -372,7 +387,7 @@ namespace spv {
process( process(
[&](spv::Op opCode, unsigned start) { [&](spv::Op opCode, unsigned start) {
// remember opcodes we want to strip later // remember opcodes we want to strip later
if (isStripOp(opCode)) if (isStripOp(opCode, start))
stripInst(start); stripInst(start);
return true; return true;
}, },
@ -1494,8 +1509,10 @@ namespace spv {
} }
// remap from a memory image // remap from a memory image
void spirvbin_t::remap(std::vector<std::uint32_t>& in_spv, std::uint32_t opts) void spirvbin_t::remap(std::vector<std::uint32_t>& in_spv, const std::vector<std::string>& whiteListStrings,
std::uint32_t opts)
{ {
stripWhiteList = whiteListStrings;
spv.swap(in_spv); spv.swap(in_spv);
remap(opts); remap(opts);
spv.swap(in_spv); spv.swap(in_spv);

View File

@ -118,7 +118,8 @@ public:
virtual ~spirvbin_t() { } virtual ~spirvbin_t() { }
// remap on an existing binary in memory // remap on an existing binary in memory
void remap(std::vector<std::uint32_t>& spv, std::uint32_t opts = DO_EVERYTHING); void remap(std::vector<std::uint32_t>& spv, const std::vector<std::string>& whiteListStrings,
std::uint32_t opts = DO_EVERYTHING);
// Type for error/log handler functions // Type for error/log handler functions
typedef std::function<void(const std::string&)> errorfn_t; typedef std::function<void(const std::string&)> errorfn_t;
@ -180,6 +181,8 @@ private:
unsigned typeSizeInWords(spv::Id id) const; unsigned typeSizeInWords(spv::Id id) const;
unsigned idTypeSizeInWords(spv::Id id) const; unsigned idTypeSizeInWords(spv::Id id) const;
bool isStripOp(spv::Op opCode, unsigned start) const;
spv::Id& asId(unsigned word) { return spv[word]; } spv::Id& asId(unsigned word) { return spv[word]; }
const spv::Id& asId(unsigned word) const { return spv[word]; } const spv::Id& asId(unsigned word) const { return spv[word]; }
spv::Op asOpCode(unsigned word) const { return opOpCode(spv[word]); } spv::Op asOpCode(unsigned word) const { return opOpCode(spv[word]); }
@ -249,6 +252,8 @@ private:
std::vector<spirword_t> spv; // SPIR words std::vector<spirword_t> spv; // SPIR words
std::vector<std::string> stripWhiteList;
namemap_t nameMap; // ID names from OpName namemap_t nameMap; // ID names from OpName
// Since we want to also do binary ops, we can't use std::vector<bool>. we could use // Since we want to also do binary ops, we can't use std::vector<bool>. we could use

View File

@ -105,6 +105,32 @@ namespace {
} }
} }
// Read strings from a file
void read(std::vector<std::string>& strings, const std::string& inFilename, int verbosity)
{
std::ifstream fp;
if (verbosity > 0)
logHandler(std::string(" reading: ") + inFilename);
strings.clear();
fp.open(inFilename, std::fstream::in);
if (fp.fail())
errHandler("error opening file for read: ");
std::string line;
while (std::getline(fp, line))
{
// Ignore empty lines and lines starting with the comment marker '#'.
if (line.length() == 0 || line[0] == '#') {
continue;
}
strings.push_back(line);
}
}
void write(std::vector<SpvWord>& spv, const std::string& outFile, int verbosity) void write(std::vector<SpvWord>& spv, const std::string& outFile, int verbosity)
{ {
if (outFile.empty()) if (outFile.empty())
@ -144,6 +170,7 @@ namespace {
<< " [--dce (all|types|funcs)]" << " [--dce (all|types|funcs)]"
<< " [--opt (all|loadstore)]" << " [--opt (all|loadstore)]"
<< " [--strip-all | --strip all | -s]" << " [--strip-all | --strip all | -s]"
<< " [--strip-white-list]"
<< " [--do-everything]" << " [--do-everything]"
<< " --input | -i file1 [file2...] --output|-o DESTDIR" << " --input | -i file1 [file2...] --output|-o DESTDIR"
<< std::endl; << std::endl;
@ -156,16 +183,18 @@ namespace {
// grind through each SPIR in turn // grind through each SPIR in turn
void execute(const std::vector<std::string>& inputFile, const std::string& outputDir, void execute(const std::vector<std::string>& inputFile, const std::string& outputDir,
int opts, int verbosity) const std::string& whiteListFile, int opts, int verbosity)
{ {
std::vector<std::string> whiteListStrings;
if(!whiteListFile.empty())
read(whiteListStrings, whiteListFile, verbosity);
for (auto it = inputFile.cbegin(); it != inputFile.cend(); ++it) { for (auto it = inputFile.cbegin(); it != inputFile.cend(); ++it) {
const std::string &filename = *it; const std::string &filename = *it;
std::vector<SpvWord> spv; std::vector<SpvWord> spv;
read(spv, filename, verbosity); read(spv, filename, verbosity);
spv::spirvbin_t(verbosity).remap(spv, opts); spv::spirvbin_t(verbosity).remap(spv, whiteListStrings, opts);
const std::string outfile = outputDir + path_sep_char() + basename(filename); const std::string outfile = outputDir + path_sep_char() + basename(filename);
write(spv, outfile, verbosity); write(spv, outfile, verbosity);
} }
@ -176,6 +205,7 @@ namespace {
// Parse command line options // Parse command line options
void parseCmdLine(int argc, char** argv, std::vector<std::string>& inputFile, void parseCmdLine(int argc, char** argv, std::vector<std::string>& inputFile,
std::string& outputDir, std::string& outputDir,
std::string& stripWhiteListFile,
int& options, int& options,
int& verbosity) int& verbosity)
{ {
@ -245,6 +275,9 @@ namespace {
options = options | spv::spirvbin_t::STRIP; options = options | spv::spirvbin_t::STRIP;
++a; ++a;
} }
} else if (arg == "--strip-white-list") {
++a;
stripWhiteListFile = argv[a++];
} else if (arg == "--dce") { } else if (arg == "--dce") {
// Parse comma (or colon, etc) separated list of things to dce // Parse comma (or colon, etc) separated list of things to dce
++a; ++a;
@ -315,6 +348,7 @@ int main(int argc, char** argv)
{ {
std::vector<std::string> inputFile; std::vector<std::string> inputFile;
std::string outputDir; std::string outputDir;
std::string whiteListFile;
int opts; int opts;
int verbosity; int verbosity;
@ -329,13 +363,13 @@ int main(int argc, char** argv)
if (argc < 2) if (argc < 2)
usage(argv[0]); usage(argv[0]);
parseCmdLine(argc, argv, inputFile, outputDir, opts, verbosity); parseCmdLine(argc, argv, inputFile, outputDir, whiteListFile, opts, verbosity);
if (outputDir.empty()) if (outputDir.empty())
usage(argv[0], "Output directory required"); usage(argv[0], "Output directory required");
// Main operations: read, remap, and write. // Main operations: read, remap, and write.
execute(inputFile, outputDir, opts, verbosity); execute(inputFile, outputDir, whiteListFile, opts, verbosity);
// If we get here, everything went OK! Nothing more to be done. // If we get here, everything went OK! Nothing more to be done.
} }

View File

@ -367,11 +367,12 @@ public:
if (success && (controls & EShMsgSpvRules)) { if (success && (controls & EShMsgSpvRules)) {
spv::SpvBuildLogger logger; spv::SpvBuildLogger logger;
std::vector<std::string> whiteListStrings;
std::vector<uint32_t> spirv_binary; std::vector<uint32_t> spirv_binary;
glslang::GlslangToSpv(*program.getIntermediate(stage), glslang::GlslangToSpv(*program.getIntermediate(stage),
spirv_binary, &logger, &options()); spirv_binary, &logger, &options());
spv::spirvbin_t(0 /*verbosity*/).remap(spirv_binary, remapOptions); spv::spirvbin_t(0 /*verbosity*/).remap(spirv_binary, whiteListStrings, remapOptions);
std::ostringstream disassembly_stream; std::ostringstream disassembly_stream;
spv::Parameterize(); spv::Parameterize();
@ -394,9 +395,9 @@ public:
{ {
if ((controls & EShMsgSpvRules)) { if ((controls & EShMsgSpvRules)) {
std::vector<uint32_t> spirv_binary(code); // scratch copy std::vector<uint32_t> spirv_binary(code); // scratch copy
std::vector<std::string> whiteListStrings;
spv::spirvbin_t(0 /*verbosity*/).remap(spirv_binary, whiteListStrings, remapOptions);
spv::spirvbin_t(0 /*verbosity*/).remap(spirv_binary, remapOptions);
std::ostringstream disassembly_stream; std::ostringstream disassembly_stream;
spv::Parameterize(); spv::Parameterize();
spv::Disassemble(disassembly_stream, spirv_binary); spv::Disassemble(disassembly_stream, spirv_binary);