mirror of
https://github.com/vosen/ZLUDA.git
synced 2025-04-28 21:47:57 +03:00
Fix builtins generation, mark ld/st as aligned (#22)
Two changes: * Fixes to builtins generation that I forgot to include in #21 * Marking of ld/st as aligned - this gives a big performance boost in GeekBench SFFT
This commit is contained in:
parent
a3cfa24593
commit
63af70a01f
1 changed files with 41 additions and 40 deletions
|
@ -1364,12 +1364,13 @@ fn fix_builtins(
|
||||||
value: ast::ImmediateValue::U64(0),
|
value: ast::ImmediateValue::U64(0),
|
||||||
}));
|
}));
|
||||||
} else {
|
} else {
|
||||||
let src_type = match numeric_id_defs.special_registers.get(details.arg.src) {
|
let sreg_and_type = match numeric_id_defs.special_registers.get(details.arg.src)
|
||||||
|
{
|
||||||
Some(reg) => get_sreg_id_scalar_type(numeric_id_defs, reg),
|
Some(reg) => get_sreg_id_scalar_type(numeric_id_defs, reg),
|
||||||
None => None,
|
None => None,
|
||||||
};
|
};
|
||||||
let (sreg_src, scalar_typ, vector_width) = match src_type {
|
let (sreg_src, scalar_typ, vector_width) = match sreg_and_type {
|
||||||
Some(x) => x,
|
Some(sreg_and_type) => sreg_and_type,
|
||||||
None => {
|
None => {
|
||||||
result.push(Statement::LoadVar(details));
|
result.push(Statement::LoadVar(details));
|
||||||
continue;
|
continue;
|
||||||
|
@ -1409,11 +1410,9 @@ fn get_sreg_id_scalar_type(
|
||||||
) -> Option<(spirv::Word, ast::ScalarType, u8)> {
|
) -> Option<(spirv::Word, ast::ScalarType, u8)> {
|
||||||
match sreg.normalized_sreg_and_type() {
|
match sreg.normalized_sreg_and_type() {
|
||||||
Some((normalized_sreg, typ, vec_width)) => Some((
|
Some((normalized_sreg, typ, vec_width)) => Some((
|
||||||
numeric_id_defs.special_registers.replace(
|
numeric_id_defs
|
||||||
numeric_id_defs.current_id,
|
.special_registers
|
||||||
sreg,
|
.get_or_add(numeric_id_defs.current_id, normalized_sreg),
|
||||||
normalized_sreg,
|
|
||||||
),
|
|
||||||
typ,
|
typ,
|
||||||
vec_width,
|
vec_width,
|
||||||
)),
|
)),
|
||||||
|
@ -2790,13 +2789,28 @@ fn emit_function_body_ops(
|
||||||
}
|
}
|
||||||
let result_type =
|
let result_type =
|
||||||
map.get_or_add(builder, SpirvType::from(ast::Type::from(data.typ.clone())));
|
map.get_or_add(builder, SpirvType::from(ast::Type::from(data.typ.clone())));
|
||||||
builder.load(result_type, Some(arg.dst), arg.src, None, [])?;
|
builder.load(
|
||||||
|
result_type,
|
||||||
|
Some(arg.dst),
|
||||||
|
arg.src,
|
||||||
|
Some(spirv::MemoryAccess::ALIGNED),
|
||||||
|
[dr::Operand::LiteralInt32(
|
||||||
|
ast::Type::from(data.typ.clone()).size_of() as u32,
|
||||||
|
)],
|
||||||
|
)?;
|
||||||
}
|
}
|
||||||
ast::Instruction::St(data, arg) => {
|
ast::Instruction::St(data, arg) => {
|
||||||
if data.qualifier != ast::LdStQualifier::Weak {
|
if data.qualifier != ast::LdStQualifier::Weak {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
builder.store(arg.src1, arg.src2, None, &[])?;
|
builder.store(
|
||||||
|
arg.src1,
|
||||||
|
arg.src2,
|
||||||
|
Some(spirv::MemoryAccess::ALIGNED),
|
||||||
|
[dr::Operand::LiteralInt32(
|
||||||
|
ast::Type::from(data.typ.clone()).size_of() as u32,
|
||||||
|
)],
|
||||||
|
)?;
|
||||||
}
|
}
|
||||||
// SPIR-V does not support ret as guaranteed-converged
|
// SPIR-V does not support ret as guaranteed-converged
|
||||||
ast::Instruction::Ret(_) => builder.ret()?,
|
ast::Instruction::Ret(_) => builder.ret()?,
|
||||||
|
@ -4755,11 +4769,26 @@ impl SpecialRegistersMap {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn builtins<'a>(&'a self) -> impl Iterator<Item = (PtxSpecialRegister, spirv::Word)> + 'a {
|
fn builtins<'a>(&'a self) -> impl Iterator<Item = (PtxSpecialRegister, spirv::Word)> + 'a {
|
||||||
self.reg_to_id.iter().map(|(reg, id)| (*reg, *id))
|
self.reg_to_id.iter().filter_map(|(sreg, id)| {
|
||||||
|
if sreg.normalized_sreg_and_type().is_none() {
|
||||||
|
Some((*sreg, *id))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn interface(&self) -> Vec<spirv::Word> {
|
fn interface(&self) -> Vec<spirv::Word> {
|
||||||
self.id_to_reg.iter().map(|(id, _)| *id).collect::<Vec<_>>()
|
self.reg_to_id
|
||||||
|
.iter()
|
||||||
|
.filter_map(|(sreg, id)| {
|
||||||
|
if sreg.normalized_sreg_and_type().is_none() {
|
||||||
|
Some(*id)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get(&self, id: spirv::Word) -> Option<PtxSpecialRegister> {
|
fn get(&self, id: spirv::Word) -> Option<PtxSpecialRegister> {
|
||||||
|
@ -4778,34 +4807,6 @@ impl SpecialRegistersMap {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn replace(
|
|
||||||
&mut self,
|
|
||||||
current_id: &mut spirv::Word,
|
|
||||||
old: PtxSpecialRegister,
|
|
||||||
new: PtxSpecialRegister,
|
|
||||||
) -> spirv::Word {
|
|
||||||
match self.reg_to_id.entry(old) {
|
|
||||||
hash_map::Entry::Occupied(e) => {
|
|
||||||
let id = e.remove();
|
|
||||||
self.reg_to_id.insert(new, id);
|
|
||||||
id
|
|
||||||
}
|
|
||||||
hash_map::Entry::Vacant(e) => {
|
|
||||||
drop(e);
|
|
||||||
match self.reg_to_id.entry(new) {
|
|
||||||
hash_map::Entry::Occupied(e) => *e.get(),
|
|
||||||
hash_map::Entry::Vacant(e) => {
|
|
||||||
let numeric_id = *current_id;
|
|
||||||
*current_id += 1;
|
|
||||||
e.insert(numeric_id);
|
|
||||||
self.id_to_reg.insert(numeric_id, new);
|
|
||||||
numeric_id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct GlobalStringIdResolver<'input> {
|
struct GlobalStringIdResolver<'input> {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue