-
Notifications
You must be signed in to change notification settings - Fork 58
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
[WIP] Structured items #46
Conversation
I think the biggest thing missing is basically a impl Context {
pub fn lift_type(&mut self, raw: &Instruction) -> TypeToken;
pub fn lift_extension(&mut self, raw: &Instruction) -> Extension;
pub fn lift_operand(&mut self, <something>) -> Operand;
..etc
} |
Looking at this some more... I'm able to generate the lift() functions that process and match operands, aka: pub fn lift_memory_model(
&mut self,
raw: &mr::Instruction,
) -> Result<structs::MemoryModel, LiftError> {
if raw.class.opcode as u32 != 14u32 {
return Err(LiftError::OpCode);
}
let mut operands = raw.operands.iter();
Ok(structs::MemoryModel {
addressing_model: (match operands.next() {
Some(&mr::Operand::AddressingModel(ref value)) => Some(value.clone()),
Some(_) => Err(OperandError::Wrong)?,
None => None,
})
.ok_or(OperandError::Missing)?,
memory_model: (match operands.next() {
Some(&mr::Operand::MemoryModel(ref value)) => Some(value.clone()),
Some(_) => Err(OperandError::Wrong)?,
None => None,
})
.ok_or(OperandError::Missing)?,
})
} My problem is that we need to enforce the semantics that is in the spec but nowhere to be seen in the schema, e.g.:
In the schema they are just { "kind" : "IdRef", "name" : "'Entry Point'" },
{ "kind" : "LiteralString", "name" : "'Name'" },
{ "kind" : "IdRef", "quantifier" : "*", "name" : "'Interface'" } So there appears to be incomplete information in the schema to build the proper structured API. We have 2 ways to proceed from here:
@antiagainst do you have a feel on which approach would work best for us? ^ |
@antiagainst I'm going with approach (2) currently, i.e.: match operand.name.trim_matches('\'') {
"Length" => quote! { ConstantToken },
"Entry Point" => quote! { FunctionToken },
"Interface" => quote! { VariableToken },
_ => quote! { TypeToken },
} So far, it seems to me that naming is fairly consistent and repetitive, so adding such a match is still a big win over manually writing the code. Another issue I'm facing is that content in SPIRV appears to not be sequential. An OpEntryPoint point to OpFunction, for example. This is annoying because we want to be populating our context graph with function/instruction/constant/etc tokens, and we can use one unless we processed it first. I'll try to see if we can process all the functions first, before going for the mode setting ops, and whether this is big issue within a function/block as well. |
Yes the JSON grammar was not a full-fledged encoding of the syntax validation rules. (My bad initially defining it that way; it was more meaning to be supporting a data driven approach in SPIRV-Tools.) And you pointed out the most noticeable one: IdRef. I initially thought about adding more sub cases to it but never got to it. Generally I'm in favor of more autogen. (You can know that which all the codegen stuff I've in this project; although codegen means another thing in compiler so we should probably rename it. ;-P) So matching names as a start sounds good to me. I think a more principled solution would be to enhance the SPIR-V JSON grammar to encode this info. (I'm actually needing other stuff that is not in the upstream; category is added by me for this repo specifically and so you see we are not using an upstream grammar here, which is bad because need to manually merge with each version update.) |
There are a few places that SPIR-V has forward references. The sections before types and global values are all "metadata" instructions; meaning they attach additional information to some other instruction. So frequently they do forward referencing, esp. entry point, execution mode, debugging instruction, annotations. (We can also have |
This is obviously incomplete, WIP, etc, but at least it's at the point where it compiles. I don't think having more stuff piled up on top would be a good way to merge later. @antiagainst - do you think you could review this and consider landing if it's done in the preferred way? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome, overall LGTM! Thanks @kvark for handling this! :)
I'd suggest to keep CLs small and focused in the future so that it's easier and faster to write and review. Also the commits left in history would be standalone enough for easy reverting if something goes wrong. :)
codegen/sr.rs
Outdated
} else { | ||
let kind = Ident::new(kind, Span::call_site()); | ||
quote! { spirv::#kind } | ||
match kind { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is just refining existing implementation and not related to the new feature we are implementing here, right? In the future, it would be nice to have separate PRs.
codegen/sr.rs
Outdated
} | ||
} | ||
|
||
pub fn gen_sr_structs_and_lifts(grammar: &structs::Grammar) -> (String, String) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we have some comments regarding this function?
(I wasn't doing good on this previously given it's just me playing with this repo. Now it's intended to be developed by more people so some documentation could really save newcomers efforts in understanding existing codebase. :)
@@ -20,6 +20,7 @@ travis-ci = { repository = "gfx-rs/rspirv" } | |||
num = "0.2" | |||
derive_more = "0.7" | |||
clippy = { version = "0.0", optional = true } | |||
fxhash = "0.2" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: can you sort these dependencies alphabetically?
self.types.push(t); | ||
TypeToken::new(self.types.len() - 1) | ||
} | ||
pub fn #func_name #param_list -> Token<Type> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here too. It would be nice to have a separate CL for this change and the autogen touched files.
type FastHashMap<K, V> = HashMap<K, V, BuildHasherDefault<FxHasher>>; | ||
type Index = u32; | ||
|
||
/// A structure holding some kind of a structured SPIRV data that can be |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: SPIR-V is the formal spelling. Unless we are in code where we cannot use -, let's use the formal name when possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
... some kind of SPIR-V constructs that can ...
@@ -0,0 +1,7 @@ | |||
use spirv; | |||
use super::{ | |||
context::Token, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Format
} | ||
|
||
impl Module { | ||
pub fn from_data(module: &mr::Module) -> Result<Self, ConvertionError> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: from_data_representation
|
||
|
||
#[derive(Clone, Debug)] | ||
pub enum OperandError { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we have documentation for public APIs?
@@ -0,0 +1,7 @@ | |||
use spirv; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
structs
is not a very descriptive name for this module. It's too general and it implies data representation (which is another representation). Can we have a better one? What about op
?
rspirv/sr/autogen_instruction.rs
Outdated
ExtInst { | ||
set: spirv::Word, | ||
set: Token<Type>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't all these be Token<Instruction>
?
@antiagainst This PR becomes increasingly difficult to advance without either of #49 or #55 to be merged. |
Just wanted to double check here. So this PR is not expected to be reviewed but expected to be split into smaller ones right? |
@antiagainst correct. It's technically in the "Draft" status, which isn't ready for review. |
Cool, thanks! |
This PR has been stale for about a year, mind if we close it? |
The PR contains core missing pieces of #5: rich instructions and top-level items, such as
Module
.