Preserve value symtabs in exactly the order they come in

* Sometimes these are sorted, but that seems to be a recent dxc change.
This commit is contained in:
baldurk
2021-09-06 17:46:10 +01:00
parent 731c81e3c7
commit 1f68db5c08
3 changed files with 102 additions and 13 deletions
@@ -837,6 +837,32 @@ Program::Program(const byte *bytes, size_t length)
size_t v = (size_t)symtab.ops[0];
if(v < m_Values.size())
{
rdcstr str = symtab.getString(1);
if(!m_ValueSymtabOrder.empty())
{
const Value &prevValue = m_Values[m_ValueSymtabOrder.back()];
switch(prevValue.type)
{
case ValueType::GlobalVar:
{
m_SortedSymtab &= prevValue.global->name < str;
break;
}
case ValueType::Function:
{
m_SortedSymtab &= prevValue.function->name < str;
break;
}
case ValueType::Alias:
{
m_SortedSymtab &= prevValue.alias->name < str;
break;
}
default: break;
}
}
switch(m_Values[v].type)
{
case ValueType::Unknown:
@@ -845,27 +871,31 @@ Program::Program(const byte *bytes, size_t length)
case ValueType::Metadata:
case ValueType::Literal:
case ValueType::BasicBlock:
{
RDCERR("Unexpected global symbol referring to %d", m_Values[v].type);
break;
}
case ValueType::GlobalVar:
{
GlobalVar *global = (GlobalVar *)m_Values[v].global;
global->name = symtab.getString(1);
global->name = str;
break;
}
case ValueType::Function:
{
Function *function = (Function *)m_Values[v].function;
function->name = symtab.getString(1);
function->name = str;
break;
}
case ValueType::Alias:
{
Alias *alias = (Alias *)m_Values[v].alias;
alias->name = symtab.getString(1);
alias->name = str;
break;
}
}
m_ValueSymtabOrder.push_back(v);
}
else
{
@@ -1103,28 +1133,53 @@ Program::Program(const byte *bytes, size_t length)
}
const Value &v = m_Values[idx];
rdcstr str = symtab.getString(1);
if(!f.valueSymtabOrder.empty())
{
const Value &prevValue = m_Values[f.valueSymtabOrder.back()];
switch(prevValue.type)
{
case ValueType::Constant:
{
f.sortedSymtab &= prevValue.constant->str < str;
break;
}
case ValueType::Instruction:
{
f.sortedSymtab &= prevValue.instruction->name < str;
break;
}
case ValueType::BasicBlock:
{
f.sortedSymtab &= prevValue.block->name < str;
break;
}
default: break;
}
}
switch(v.type)
{
case ValueType::Unknown:
case ValueType::Constant:
{
Constant *constant = (Constant *)v.constant;
constant->str = symtab.getString(1);
constant->str = str;
break;
}
case ValueType::Instruction:
{
Instruction *instruction = (Instruction *)v.instruction;
instruction->name = symtab.getString(1);
instruction->name = str;
break;
}
case ValueType::BasicBlock:
{
Block *block = (Block *)v.block;
block->name = symtab.getString(1);
block->name = str;
break;
}
case ValueType::Unknown:
case ValueType::GlobalVar:
case ValueType::Function:
case ValueType::Alias:
@@ -1133,6 +1188,8 @@ Program::Program(const byte *bytes, size_t length)
RDCERR("Unexpected local symbol referring to %d", v.type);
break;
}
f.valueSymtabOrder.push_back(idx);
}
else if(IS_KNOWN(symtab.id, ValueSymtabRecord::BBENTRY))
{
@@ -600,6 +600,9 @@ struct Function
rdcarray<Instruction> instructions;
rdcarray<Value> values;
rdcarray<size_t> valueSymtabOrder;
bool sortedSymtab = true;
rdcarray<Block> blocks;
rdcarray<Constant> constants;
rdcarray<Metadata> metadata;
@@ -676,6 +679,9 @@ protected:
rdcarray<rdcstr> m_Kinds;
rdcarray<size_t> m_ValueSymtabOrder;
bool m_SortedSymtab = true;
rdcarray<Type> m_Types;
const Type *m_VoidType = NULL;
const Type *m_BoolType = NULL;
@@ -482,12 +482,13 @@ bytebuf DXIL::ProgramEditor::EncodeProgram() const
writer.EndBlock();
}
if(!m_ValueSymtabOrder.empty())
{
writer.BeginBlock(LLVMBC::KnownBlock::VALUE_SYMTAB_BLOCK);
rdcarray<rdcpair<size_t, const rdcstr *>> entries;
for(size_t s = 0; s < m_Values.size(); s++)
for(size_t s : m_ValueSymtabOrder)
{
const rdcstr *str = NULL;
switch(m_Values[s].type)
@@ -502,11 +503,6 @@ bytebuf DXIL::ProgramEditor::EncodeProgram() const
entries.push_back({s, str});
}
// sort the entries by string in order
std::sort(entries.begin(), entries.end(),
[](const rdcpair<size_t, const rdcstr *> &a,
const rdcpair<size_t, const rdcstr *> &b) { return *a.second < *b.second; });
// we use a special function to record the entry so it can take the string as-is to check it for
// validity
for(const rdcpair<size_t, const rdcstr *> &it : entries)
@@ -1062,6 +1058,36 @@ bytebuf DXIL::ProgramEditor::EncodeProgram() const
debugLoc = inst.debugLoc;
}
if(!f.valueSymtabOrder.empty())
{
writer.BeginBlock(LLVMBC::KnownBlock::VALUE_SYMTAB_BLOCK);
rdcarray<rdcpair<size_t, const rdcstr *>> entries;
for(size_t s : f.valueSymtabOrder)
{
const rdcstr *str = NULL;
switch(values[s].type)
{
case ValueType::Instruction: str = &values[s].instruction->name; break;
case ValueType::Constant: str = &values[s].constant->str; break;
case ValueType::BasicBlock: str = &values[s].block->name; break;
default: break;
}
if(str)
entries.push_back({s, str});
}
// we use a special function to record the entry so it can take the string as-is to check it
// for
// validity
for(const rdcpair<size_t, const rdcstr *> &it : entries)
writer.RecordSymTabEntry(it.first, *it.second);
writer.EndBlock();
}
if(needMetaAttach)
{
writer.BeginBlock(LLVMBC::KnownBlock::METADATA_ATTACHMENT);