Store values rather than indices for aliases/symtab to allow rebasing

This commit is contained in:
baldurk
2021-09-20 17:57:09 +01:00
parent 9efdf6920a
commit d15f264c81
3 changed files with 66 additions and 161 deletions
+42 -121
View File
@@ -145,6 +145,9 @@ void ParseConstant(const LLVMBC::BlockOrRecord &constant, const Type *&curType,
c.type = curType;
if(c.type->type == Type::Vector)
{
// only handle 4-wide vectors right now
RDCASSERT(constant.ops.size() <= 4);
// inline vectors
for(size_t m = 0; m < constant.ops.size(); m++)
{
@@ -491,7 +494,7 @@ Program::Program(const byte *bytes, size_t length)
Alias a;
a.type = &m_Types[(size_t)rootchild.ops[0]];
a.valID = rootchild.ops[1];
a.val = m_Values[(size_t)rootchild.ops[1]];
// ignore rest of properties, assert that if present they are 0
for(size_t p = 2; p < rootchild.ops.size(); p++)
@@ -851,72 +854,22 @@ Program::Program(const byte *bytes, size_t length)
continue;
}
size_t v = (size_t)symtab.ops[0];
if(v < m_Values.size())
size_t vidx = (size_t)symtab.ops[0];
if(vidx < m_Values.size())
{
const Value &v = m_Values[vidx];
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;
}
}
GetValueSymtabString(v) = str;
switch(m_Values[v].type)
{
case ValueType::Unknown:
case ValueType::Constant:
case ValueType::Instruction:
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 = str;
break;
}
case ValueType::Function:
{
Function *function = (Function *)m_Values[v].function;
function->name = str;
break;
}
case ValueType::Alias:
{
Alias *alias = (Alias *)m_Values[v].alias;
alias->name = str;
break;
}
}
if(!m_ValueSymtabOrder.empty())
m_SortedSymtab &= GetValueSymtabString(m_ValueSymtabOrder.back()) < str;
m_ValueSymtabOrder.push_back(v);
}
else
{
RDCERR("Value %llu referenced out of bounds", v);
RDCERR("Value %zu referenced out of bounds", vidx);
}
}
}
@@ -1152,75 +1105,24 @@ Program::Program(const byte *bytes, size_t length)
const Value &v = m_Values[idx];
rdcstr str = symtab.getString(1);
GetValueSymtabString(v) = str;
if(!f.valueSymtabOrder.empty())
{
size_t vidx = f.valueSymtabOrder.back();
if(vidx & 0x80000000U)
{
f.sortedSymtab &= f.blocks[vidx & ~0x80000000U].name < str;
}
else
{
const Value &prevValue = m_Values[vidx];
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;
}
}
}
f.sortedSymtab &= GetValueSymtabString(f.valueSymtabOrder.back()) < str;
switch(v.type)
{
case ValueType::Constant:
{
Constant *constant = (Constant *)v.constant;
constant->str = str;
break;
}
case ValueType::Instruction:
{
Instruction *instruction = (Instruction *)v.instruction;
instruction->name = str;
break;
}
case ValueType::BasicBlock:
{
Block *block = (Block *)v.block;
block->name = str;
break;
}
case ValueType::Unknown:
case ValueType::GlobalVar:
case ValueType::Function:
case ValueType::Alias:
case ValueType::Metadata:
case ValueType::Literal:
RDCERR("Unexpected local symbol referring to %d", v.type);
break;
}
f.valueSymtabOrder.push_back(idx);
f.valueSymtabOrder.push_back(v);
}
else if(IS_KNOWN(symtab.id, ValueSymtabRecord::BBENTRY))
{
f.blocks[(size_t)symtab.ops[0]].name = symtab.getString(1);
Value v(&f.blocks[(size_t)symtab.ops[0]]);
rdcstr str = symtab.getString(1);
f.valueSymtabOrder.push_back(0x80000000U | (size_t)symtab.ops[0]);
GetValueSymtabString(v) = str;
if(!f.valueSymtabOrder.empty())
f.sortedSymtab &= GetValueSymtabString(f.valueSymtabOrder.back()) < str;
f.valueSymtabOrder.push_back(v);
}
else
{
@@ -2386,6 +2288,25 @@ Program::Program(const byte *bytes, size_t length)
RDCASSERT(functionDecls.empty());
}
rdcstr &Program::GetValueSymtabString(const Value &v)
{
static rdcstr err;
switch(v.type)
{
case ValueType::Constant: return (rdcstr &)v.constant->str;
case ValueType::Instruction: return (rdcstr &)v.instruction->name;
case ValueType::BasicBlock: return (rdcstr &)v.block->name;
case ValueType::GlobalVar: return (rdcstr &)v.global->name;
case ValueType::Function: return (rdcstr &)v.function->name;
case ValueType::Alias: return (rdcstr &)v.alias->name;
case ValueType::Unknown:
case ValueType::Metadata:
case ValueType::Literal: RDCERR("Unexpected value symtab entry referring to %d", v.type); break;
}
return err;
}
uint32_t Program::GetOrAssignMetaID(Metadata *m)
{
if(m->id != ~0U)
@@ -208,7 +208,7 @@ struct Alias
{
rdcstr name;
const Type *type = NULL;
uint64_t valID = 0;
Value val;
};
// this enum is ordered to match the serialised order of these attributes
@@ -617,7 +617,7 @@ struct Function
rdcarray<Instruction> instructions;
rdcarray<Value> values;
rdcarray<size_t> valueSymtabOrder;
rdcarray<Value> valueSymtabOrder;
bool sortedSymtab = true;
rdcarray<Block> blocks;
@@ -673,6 +673,8 @@ protected:
bool ParseDebugMetaRecord(const LLVMBC::BlockOrRecord &metaRecord, Metadata &meta);
rdcstr GetDebugVarName(const DIBase *d);
rdcstr &GetValueSymtabString(const Value &v);
uint32_t GetOrAssignMetaID(Metadata *m);
uint32_t GetOrAssignMetaID(DebugLocation &l);
const Type *GetVoidType();
@@ -696,7 +698,7 @@ protected:
rdcarray<rdcstr> m_Kinds;
rdcarray<size_t> m_ValueSymtabOrder;
rdcarray<Value> m_ValueSymtabOrder;
bool m_SortedSymtab = true;
rdcarray<Type> m_Types;
@@ -510,7 +510,7 @@ bytebuf DXIL::ProgramEditor::EncodeProgram() const
uint64_t typeIndex = getTypeID(a.type);
writer.Record(LLVMBC::ModuleRecord::ALIAS, {
typeIndex, a.valID,
typeIndex, getValueID(a.val),
// linkage
0U,
// visibility
@@ -579,28 +579,21 @@ bytebuf DXIL::ProgramEditor::EncodeProgram() const
{
writer.BeginBlock(LLVMBC::KnownBlock::VALUE_SYMTAB_BLOCK);
rdcarray<rdcpair<size_t, const rdcstr *>> entries;
for(size_t s : m_ValueSymtabOrder)
for(Value v : m_ValueSymtabOrder)
{
const rdcstr *str = NULL;
switch(m_Values[s].type)
switch(v.type)
{
case ValueType::GlobalVar: str = &m_Values[s].global->name; break;
case ValueType::Function: str = &m_Values[s].function->name; break;
case ValueType::Alias: str = &m_Values[s].alias->name; break;
case ValueType::GlobalVar: str = &v.global->name; break;
case ValueType::Function: str = &v.function->name; break;
case ValueType::Alias: str = &v.alias->name; break;
default: break;
}
if(str)
entries.push_back({s, str});
writer.RecordSymTabEntry(getValueID(v), *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();
}
@@ -1155,37 +1148,26 @@ bytebuf DXIL::ProgramEditor::EncodeProgram() const
{
writer.BeginBlock(LLVMBC::KnownBlock::VALUE_SYMTAB_BLOCK);
rdcarray<rdcpair<size_t, const rdcstr *>> entries;
for(size_t s : f.valueSymtabOrder)
for(Value v : f.valueSymtabOrder)
{
const rdcstr *str = NULL;
if(s & 0x80000000U)
switch(v.type)
{
str = &f.blocks[s & ~0x80000000U].name;
}
else
{
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;
}
case ValueType::Instruction: str = &v.instruction->name; break;
case ValueType::Constant: str = &v.constant->str; break;
case ValueType::BasicBlock: str = &v.block->name; break;
default: break;
}
if(str)
entries.push_back({s, str});
{
if(v.type == ValueType::BasicBlock)
writer.RecordSymTabEntry(v.block - f.blocks.begin(), *str, true);
else
writer.RecordSymTabEntry(getValueID(v), *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 & ~0x80000000U, *it.second,
it.first & 0x80000000U ? true : false);
writer.EndBlock();
}