Skip to content

Convert panics to compiler errors #66

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 16, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ members = [
]

[patch.crates-io]
rspirv = { git = "https://github.com/gfx-rs/rspirv.git", rev = "1addc7d33ae1460ffa683e2e6311e466ac876c23" }
rspirv = { git = "https://github.com/gfx-rs/rspirv.git", rev = "f11f8797bd4df2d1d22cf10767b39a5119c57551" }
65 changes: 23 additions & 42 deletions rspirv-linker/src/capability_computation.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use rspirv::dr::{Module, Operand};
use rspirv::dr::Module;
use rspirv::spirv::{Capability, Op};
use std::collections::HashSet;

Expand All @@ -12,32 +12,26 @@ fn compute_capabilities(module: &Module) -> HashSet<Capability> {
for inst in module.all_inst_iter() {
set.extend(inst.class.capabilities);
match inst.class.opcode {
Op::TypeInt => match inst.operands[0] {
Operand::LiteralInt32(width) => match width {
8 => {
set.insert(Capability::Int8);
}
16 => {
set.insert(Capability::Int16);
}
64 => {
set.insert(Capability::Int64);
}
_ => {}
},
_ => panic!(),
Op::TypeInt => match inst.operands[0].unwrap_literal_int32() {
8 => {
set.insert(Capability::Int8);
}
16 => {
set.insert(Capability::Int16);
}
64 => {
set.insert(Capability::Int64);
}
_ => {}
},
Op::TypeFloat => match inst.operands[0] {
Operand::LiteralInt32(width) => match width {
16 => {
set.insert(Capability::Float16);
}
64 => {
set.insert(Capability::Float64);
}
_ => {}
},
_ => panic!(),
Op::TypeFloat => match inst.operands[0].unwrap_literal_int32() {
16 => {
set.insert(Capability::Float16);
}
64 => {
set.insert(Capability::Float64);
}
_ => {}
},
_ => {}
}
Expand All @@ -53,33 +47,20 @@ fn compute_capabilities(module: &Module) -> HashSet<Capability> {

fn remove_capabilities(module: &mut Module, set: &HashSet<Capability>) {
module.capabilities.retain(|inst| {
inst.class.opcode != Op::Capability
|| set.contains(match &inst.operands[0] {
Operand::Capability(s) => s,
_ => panic!(),
})
inst.class.opcode != Op::Capability || set.contains(&inst.operands[0].unwrap_capability())
});
}

pub fn remove_extra_extensions(module: &mut Module) {
// TODO: Make this more generalized once this gets more advanced.
let has_intel_integer_cap = module.capabilities.iter().any(|inst| {
inst.class.opcode == Op::Capability
&& match inst.operands[0] {
Operand::Capability(s) => s == Capability::IntegerFunctions2INTEL,
_ => panic!(),
}
&& inst.operands[0].unwrap_capability() == Capability::IntegerFunctions2INTEL
});
if !has_intel_integer_cap {
module.extensions.retain(|inst| {
inst.class.opcode != Op::Extension
|| match &inst.operands[0] {
Operand::LiteralString(s) if s == "SPV_INTEL_shader_integer_functions2" => {
false
}
Operand::LiteralString(_) => true,
_ => panic!(),
}
|| inst.operands[0].unwrap_literal_string() != "SPV_INTEL_shader_integer_functions2"
})
}
}
5 changes: 2 additions & 3 deletions rspirv-linker/src/dce.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use crate::operand_idref;
use rspirv::dr::{Instruction, Module};
use rspirv::spirv::Word;
use std::collections::HashSet;
Expand Down Expand Up @@ -50,7 +49,7 @@ fn root(inst: &Instruction, rooted: &mut HashSet<Word>) -> bool {
any |= rooted.insert(id);
}
for op in &inst.operands {
if let Some(id) = operand_idref(op) {
if let Some(id) = op.id_ref_any() {
any |= rooted.insert(id);
}
}
Expand All @@ -65,7 +64,7 @@ fn is_rooted(inst: &Instruction, rooted: &HashSet<Word>) -> bool {
// referenced by roots
inst.operands
.iter()
.any(|op| operand_idref(op).map_or(false, |w| rooted.contains(&w)))
.any(|op| op.id_ref_any().map_or(false, |w| rooted.contains(&w)))
}
}

Expand Down
3 changes: 1 addition & 2 deletions rspirv-linker/src/def_analyzer.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use crate::operand_idref;
use rspirv::dr::{Instruction, Module, Operand};
use std::collections::HashMap;

Expand Down Expand Up @@ -40,7 +39,7 @@ impl<'a> DefAnalyzer<'a> {
///
/// Panics when provided an operand that doesn't reference an id, or that id is missing.
pub fn op_def(&self, operand: &Operand) -> Instruction {
self.def(operand_idref(operand).expect("Expected ID"))
self.def(operand.id_ref_any().expect("Expected ID"))
.unwrap()
.clone()
}
Expand Down
16 changes: 4 additions & 12 deletions rspirv-linker/src/duplicates.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use crate::{operand_idref, operand_idref_mut};
use rspirv::binary::Assemble;
use rspirv::dr::{Instruction, Module, Operand};
use rspirv::spirv::{Op, Word};
Expand All @@ -9,21 +8,14 @@ pub fn remove_duplicate_extensions(module: &mut Module) {

module.extensions.retain(|inst| {
inst.class.opcode != Op::Extension
|| set.insert(match &inst.operands[0] {
Operand::LiteralString(s) => s.clone(),
_ => panic!(),
})
|| set.insert(inst.operands[0].unwrap_literal_string().to_string())
});
}

pub fn remove_duplicate_capablities(module: &mut Module) {
let mut set = HashSet::new();
module.capabilities.retain(|inst| {
inst.class.opcode != Op::Capability
|| set.insert(match inst.operands[0] {
Operand::Capability(s) => s,
_ => panic!(),
})
inst.class.opcode != Op::Capability || set.insert(inst.operands[0].unwrap_capability())
});
}

Expand Down Expand Up @@ -80,7 +72,7 @@ fn gather_annotations(annotations: &[Instruction]) -> HashMap<Word, Vec<u32>> {
let mut map = HashMap::new();
for inst in annotations {
if inst.class.opcode == Op::Decorate || inst.class.opcode == Op::MemberDecorate {
match map.entry(operand_idref(&inst.operands[0]).unwrap()) {
match map.entry(inst.operands[0].id_ref_any().unwrap()) {
hash_map::Entry::Vacant(entry) => {
entry.insert(vec![make_annotation_key(inst)]);
}
Expand Down Expand Up @@ -142,7 +134,7 @@ fn rewrite_inst_with_rules(inst: &mut Instruction, rules: &HashMap<u32, u32>) {
*id = rules.get(id).copied().unwrap_or(*id);
}
for op in &mut inst.operands {
if let Some(id) = operand_idref_mut(op) {
if let Some(id) = op.id_ref_any_mut() {
*id = rules.get(id).copied().unwrap_or(*id);
}
}
Expand Down
43 changes: 13 additions & 30 deletions rspirv-linker/src/import_export_link.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::ty::trans_aggregate_type;
use crate::{operand_idref, operand_idref_mut, print_type, DefAnalyzer, LinkerError, Result};
use rspirv::dr::{Instruction, Module, Operand};
use crate::{print_type, DefAnalyzer, LinkerError, Result};
use rspirv::dr::{Instruction, Module};
use rspirv::spirv::{Capability, Decoration, LinkageType, Op, Word};
use std::collections::{HashMap, HashSet};

Expand Down Expand Up @@ -60,22 +60,11 @@ fn find_import_export_pairs_and_killed_params(

fn get_linkage_inst(inst: &Instruction) -> Option<(Word, &str, LinkageType)> {
if inst.class.opcode == Op::Decorate
&& inst.operands[1] == Operand::Decoration(Decoration::LinkageAttributes)
&& inst.operands[1].unwrap_decoration() == Decoration::LinkageAttributes
{
let id = match inst.operands[0] {
Operand::IdRef(i) => i,
_ => panic!("Expected IdRef"),
};

let name = match &inst.operands[2] {
Operand::LiteralString(s) => s,
_ => panic!("Expected LiteralString"),
};

let linkage_ty = match inst.operands[3] {
Operand::LinkageType(t) => t,
_ => panic!("Expected LinkageType"),
};
let id = inst.operands[0].unwrap_id_ref();
let name = inst.operands[2].unwrap_literal_string();
let linkage_ty = inst.operands[3].unwrap_linkage_type();
Some((id, name, linkage_ty))
} else {
None
Expand All @@ -91,13 +80,7 @@ fn get_type_for_link(defs: &DefAnalyzer, id: Word) -> Word {
Op::Variable => def_inst.result_type.unwrap(),
// Note: the result_type of OpFunction is the return type, not the function type. The
// function type is in operands[1].
Op::Function => {
if let Operand::IdRef(id) = def_inst.operands[1] {
id
} else {
panic!("Expected IdRef");
}
}
Op::Function => def_inst.operands[1].unwrap_id_ref(),
_ => panic!("Unexpected op"),
}
}
Expand Down Expand Up @@ -159,7 +142,7 @@ fn replace_all_uses_with(module: &mut Module, rules: &HashMap<u32, u32>) {
}

inst.operands.iter_mut().for_each(|op| {
if let Some(w) = operand_idref_mut(op) {
if let Some(w) = op.id_ref_any_mut() {
if let Some(&rewrite) = rules.get(w) {
*w = rewrite;
}
Expand All @@ -182,13 +165,13 @@ fn kill_linkage_instructions(module: &mut Module, rewrite_rules: &HashMap<u32, u

module.annotations.retain(|inst| {
inst.class.opcode != Op::Decorate
|| inst.operands[1] != Operand::Decoration(Decoration::LinkageAttributes)
|| inst.operands[1].unwrap_decoration() != Decoration::LinkageAttributes
});

// drop OpCapability Linkage
module.capabilities.retain(|inst| {
inst.class.opcode != Op::Capability
|| inst.operands[0] != Operand::Capability(Capability::Linkage)
|| inst.operands[0].unwrap_capability() != Capability::Linkage
})
}

Expand All @@ -199,21 +182,21 @@ fn import_kill_annotations_and_debug(
) {
module.annotations.retain(|inst| {
inst.operands.is_empty()
|| operand_idref(&inst.operands[0]).map_or(true, |id| {
|| inst.operands[0].id_ref_any().map_or(true, |id| {
!rewrite_rules.contains_key(&id) && !killed_parameters.contains(&id)
})
});
module.debugs.retain(|inst| {
inst.operands.is_empty()
|| operand_idref(&inst.operands[0]).map_or(true, |id| {
|| inst.operands[0].id_ref_any().map_or(true, |id| {
!rewrite_rules.contains_key(&id) && !killed_parameters.contains(&id)
})
});
// need to remove OpGroupDecorate members that mention this id
for inst in &mut module.annotations {
if inst.class.opcode == Op::GroupDecorate {
inst.operands.retain(|op| {
operand_idref(op).map_or(true, |id| {
op.id_ref_any().map_or(true, |id| {
!rewrite_rules.contains_key(&id) && !killed_parameters.contains(&id)
})
})
Expand Down
Loading