diff options
author | Andrzej Janik <[email protected]> | 2020-04-15 00:45:05 +0200 |
---|---|---|
committer | Andrzej Janik <[email protected]> | 2020-04-15 00:45:05 +0200 |
commit | 47b06ebcb6a3352aa97f63b76512020c2ec2d465 (patch) | |
tree | 94012f1fb96c52c22aa108ad894c7d169d202f65 | |
parent | 12e0509b09f3e46326541e1ced4319a902ab2f91 (diff) | |
download | ZLUDA-47b06ebcb6a3352aa97f63b76512020c2ec2d465.tar.gz ZLUDA-47b06ebcb6a3352aa97f63b76512020c2ec2d465.zip |
Remap string identifies to numeric identifiers
-rw-r--r-- | ptx/src/ptx.lalrpop | 2 | ||||
-rw-r--r-- | ptx/src/translate.rs | 233 |
2 files changed, 217 insertions, 18 deletions
diff --git a/ptx/src/ptx.lalrpop b/ptx/src/ptx.lalrpop index b051b79..52c4c2c 100644 --- a/ptx/src/ptx.lalrpop +++ b/ptx/src/ptx.lalrpop @@ -403,6 +403,8 @@ Operand: ast::Operand<'input> = { let offset = offset.unwrap_with(errors); ast::Operand::RegOffset(r, offset) }, + // TODO: start parsing whole constants sub-language: + // https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#constants <o:Num> => { let offset = o.parse::<i128>(); let offset = offset.unwrap_with(errors); diff --git a/ptx/src/translate.rs b/ptx/src/translate.rs index 3f7ce9d..15782bf 100644 --- a/ptx/src/translate.rs +++ b/ptx/src/translate.rs @@ -1,6 +1,5 @@ use crate::ast;
use rspirv::dr;
-use std::collections::hash_map::Entry;
use std::collections::HashMap;
#[derive(PartialEq, Eq, Hash, Clone, Copy)]
@@ -59,7 +58,9 @@ impl TypeWordMap { struct IdWordMap<'a>(HashMap<&'a str, spirv::Word>);
impl<'a> IdWordMap<'a> {
- fn new() -> Self { IdWordMap(HashMap::new()) }
+ fn new() -> Self {
+ IdWordMap(HashMap::new())
+ }
}
impl<'a> IdWordMap<'a> {
@@ -128,7 +129,7 @@ fn emit_function<'a>( builder.begin_block(Some(id))?;
}
ast::Statement::Variable(var) => panic!(),
- ast::Statement::Instruction(_,_) => panic!(),
+ ast::Statement::Instruction(_, _) => panic!(),
}
}
builder.ret()?;
@@ -136,22 +137,218 @@ fn emit_function<'a>( Ok(())
}
+// TODO: support scopes
+fn normalize_identifiers<'a>(func: Vec<ast::Statement<'a>>) -> Vec<Statement> {
+ let mut result = Vec::with_capacity(func.len());
+ let mut id: u32 = 0;
+ let mut known_ids = HashMap::new();
+ let mut get_or_add = |key| {
+ *known_ids.entry(key).or_insert_with(|| {
+ id += 1;
+ id
+ })
+ };
+ for s in func {
+ if let Some(s) = Statement::from_ast(s, &mut get_or_add) {
+ result.push(s);
+ }
+ }
+ result
+}
+
+fn ssa_legalize(func: Vec<Statement>) -> Vec<Statement> {
+ vec![]
+}
+
enum Statement {
- Label,
- Instruction(Instruction),
- Phi(Vec<spirv::Word>)
+ Label(u32),
+ Instruction(Option<PredAt>, Instruction),
+ Phi(Vec<spirv::Word>),
+}
+
+impl Statement {
+ fn from_ast<'a, F: FnMut(&'a str) -> u32>(s: ast::Statement<'a>, f: &mut F) -> Option<Self> {
+ match s {
+ ast::Statement::Label(name) => Some(Statement::Label(f(name))),
+ ast::Statement::Instruction(p, i) => Some(Statement::Instruction(
+ p.map(|p| PredAt::from_ast(p, f)),
+ Instruction::from_ast(i, f),
+ )),
+ ast::Statement::Variable(_) => None,
+ }
+ }
+}
+
+struct PredAt {
+ pub not: bool,
+ pub label: u32,
+}
+
+impl PredAt {
+ fn from_ast<'a, F: FnMut(&'a str) -> u32>(p: ast::PredAt<'a>, f: &mut F) -> Self {
+ PredAt {
+ not: p.not,
+ label: f(p.label),
+ }
+ }
}
enum Instruction {
- Ld,
- Mov,
- Mul,
- Add,
- Setp,
- Not,
- Bra,
- Cvt,
- Shl,
- At,
- Ret,
-}
\ No newline at end of file + Ld(ast::LdData, Arg2),
+ Mov(ast::MovData, Arg2Mov),
+ Mul(ast::MulData, Arg3),
+ Add(ast::AddData, Arg3),
+ Setp(ast::SetpData, Arg4),
+ SetpBool(ast::SetpBoolData, Arg5),
+ Not(ast::NotData, Arg2),
+ Bra(ast::BraData, Arg1),
+ Cvt(ast::CvtData, Arg2),
+ Shl(ast::ShlData, Arg3),
+ St(ast::StData, Arg2),
+ At(ast::AtData, Arg1),
+ Ret(ast::RetData),
+}
+
+impl Instruction {
+ fn from_ast<'a, F: FnMut(&'a str) -> u32>(i: ast::Instruction<'a>, f: &mut F) -> Self {
+ match i {
+ ast::Instruction::Ld(d, a) => Instruction::Ld(d, Arg2::from_ast(a, f)),
+ ast::Instruction::Mov(d, a) => Instruction::Mov(d, Arg2Mov::from_ast(a, f)),
+ ast::Instruction::Mul(d, a) => Instruction::Mul(d, Arg3::from_ast(a, f)),
+ ast::Instruction::Add(d, a) => Instruction::Add(d, Arg3::from_ast(a, f)),
+ ast::Instruction::Setp(d, a) => Instruction::Setp(d, Arg4::from_ast(a, f)),
+ ast::Instruction::SetpBool(d, a) => Instruction::SetpBool(d, Arg5::from_ast(a, f)),
+ ast::Instruction::Not(d, a) => Instruction::Not(d, Arg2::from_ast(a, f)),
+ ast::Instruction::Bra(d, a) => Instruction::Bra(d, Arg1::from_ast(a, f)),
+ ast::Instruction::Cvt(d, a) => Instruction::Cvt(d, Arg2::from_ast(a, f)),
+ ast::Instruction::Shl(d, a) => Instruction::Shl(d, Arg3::from_ast(a, f)),
+ ast::Instruction::St(d, a) => Instruction::St(d, Arg2::from_ast(a, f)),
+ ast::Instruction::At(d, a) => Instruction::At(d, Arg1::from_ast(a, f)),
+ ast::Instruction::Ret(d) => Instruction::Ret(d),
+ }
+ }
+}
+
+pub struct Arg1 {
+ pub dst: u32,
+}
+
+impl Arg1 {
+ fn from_ast<'a, F: FnMut(&'a str) -> u32>(a: ast::Arg1<'a>, f: &mut F) -> Self {
+ Arg1 { dst: f(a.dst) }
+ }
+}
+
+pub struct Arg2 {
+ pub dst: u32,
+ pub src: Operand,
+}
+
+impl Arg2 {
+ fn from_ast<'a, F: FnMut(&'a str) -> u32>(a: ast::Arg2<'a>, f: &mut F) -> Self {
+ Arg2 {
+ dst: f(a.dst),
+ src: Operand::from_ast(a.src, f),
+ }
+ }
+}
+
+pub struct Arg2Mov {
+ pub dst: u32,
+ pub src: MovOperand,
+}
+
+impl Arg2Mov {
+ fn from_ast<'a, F: FnMut(&'a str) -> u32>(a: ast::Arg2Mov<'a>, f: &mut F) -> Self {
+ Arg2Mov {
+ dst: f(a.dst),
+ src: MovOperand::from_ast(a.src, f),
+ }
+ }
+}
+
+pub struct Arg3 {
+ pub dst: u32,
+ pub src1: Operand,
+ pub src2: Operand,
+}
+
+impl Arg3 {
+ fn from_ast<'a, F: FnMut(&'a str) -> u32>(a: ast::Arg3<'a>, f: &mut F) -> Self {
+ Arg3 {
+ dst: f(a.dst),
+ src1: Operand::from_ast(a.src1, f),
+ src2: Operand::from_ast(a.src2, f),
+ }
+ }
+}
+
+pub struct Arg4 {
+ pub dst1: u32,
+ pub dst2: Option<u32>,
+ pub src1: Operand,
+ pub src2: Operand,
+}
+
+impl Arg4 {
+ fn from_ast<'a, F: FnMut(&'a str) -> u32>(a: ast::Arg4<'a>, f: &mut F) -> Self {
+ Arg4 {
+ dst1: f(a.dst1),
+ dst2: a.dst2.map(|i| f(i)),
+ src1: Operand::from_ast(a.src1, f),
+ src2: Operand::from_ast(a.src2, f),
+ }
+ }
+}
+
+pub struct Arg5 {
+ pub dst1: u32,
+ pub dst2: Option<u32>,
+ pub src1: Operand,
+ pub src2: Operand,
+ pub src3: Operand,
+}
+
+impl Arg5 {
+ fn from_ast<'a, F: FnMut(&'a str) -> u32>(a: ast::Arg5<'a>, f: &mut F) -> Self {
+ Arg5 {
+ dst1: f(a.dst1),
+ dst2: a.dst2.map(|i| f(i)),
+ src1: Operand::from_ast(a.src1, f),
+ src2: Operand::from_ast(a.src2, f),
+ src3: Operand::from_ast(a.src3, f),
+ }
+ }
+}
+
+pub enum Operand {
+ Reg(u32),
+ RegOffset(u32, i32),
+ Imm(i128),
+}
+
+impl Operand {
+ fn from_ast<'a, F: FnMut(&'a str) -> u32>(a: ast::Operand<'a>, f: &mut F) -> Self {
+ match a {
+ ast::Operand::Reg(i) => Operand::Reg(f(i)),
+ ast::Operand::RegOffset(i, o) => Operand::RegOffset(f(i), o),
+ ast::Operand::Imm(v) => Operand::Imm(v),
+ }
+ }
+}
+
+pub enum MovOperand {
+ Op(Operand),
+ Vec(String, String),
+}
+
+impl MovOperand {
+ fn from_ast<'a, F: FnMut(&'a str) -> u32>(a: ast::MovOperand<'a>, f: &mut F) -> Self {
+ match a {
+ ast::MovOperand::Op(o) => MovOperand::Op(Operand::from_ast(o, f)),
+ ast::MovOperand::Vec(var, idx) => {
+ MovOperand::Vec(var.to_owned(), idx.to_string())
+ }
+ }
+ }
+}
|