Skip to content

Commit f8f5301

Browse files
committed
Customize Function and BasicBlock to carry both a SPIR-V ID and an index, for O(1) access.
1 parent 006718d commit f8f5301

File tree

7 files changed

+197
-214
lines changed

7 files changed

+197
-214
lines changed

crates/rustc_codegen_spirv/src/builder/builder_methods.rs

Lines changed: 35 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ use crate::maybe_pqp_cg_ssa as rustc_codegen_ssa;
33

44
use super::Builder;
55
use crate::abi::ConvSpirvType;
6-
use crate::builder_spirv::{BuilderCursor, SpirvConst, SpirvValue, SpirvValueExt, SpirvValueKind};
6+
use crate::builder_spirv::{
7+
SpirvBlockCursor, SpirvConst, SpirvValue, SpirvValueExt, SpirvValueKind,
8+
};
79
use crate::codegen_cx::CodegenCx;
810
use crate::custom_insts::{CustomInst, CustomOp};
911
use crate::spirv_type::SpirvType;
@@ -166,8 +168,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
166168
| MemorySemantics::ACQUIRE_RELEASE
167169
}
168170
AtomicOrdering::SeqCst => {
169-
let emit = self.emit();
170-
let memory_model = emit.module_ref().memory_model.as_ref().unwrap();
171+
let builder = self.emit();
172+
let memory_model = builder.module_ref().memory_model.as_ref().unwrap();
171173
if memory_model.operands[1].unwrap_memory_model() == MemoryModel::Vulkan {
172174
invalid_seq_cst = true;
173175
}
@@ -750,9 +752,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
750752
let ptr_id = ptr.def(self);
751753

752754
let maybe_original_access_chain = {
753-
let emit = self.emit();
754-
let module = emit.module_ref();
755-
let current_func_blocks = emit
755+
let builder = self.emit();
756+
let module = builder.module_ref();
757+
let current_func_blocks = builder
756758
.selected_function()
757759
.and_then(|func_idx| Some(&module.functions.get(func_idx)?.blocks[..]))
758760
.unwrap_or_default();
@@ -830,21 +832,21 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
830832
indices: Vec<Word>,
831833
is_inbounds: bool,
832834
) -> SpirvValue {
833-
let mut emit = self.emit();
835+
let mut builder = self.emit();
834836

835837
let non_zero_ptr_base_index =
836838
ptr_base_index.filter(|&idx| self.builder.lookup_const_scalar(idx) != Some(0));
837839
if let Some(ptr_base_index) = non_zero_ptr_base_index {
838840
let result = if is_inbounds {
839-
emit.in_bounds_ptr_access_chain(
841+
builder.in_bounds_ptr_access_chain(
840842
result_type,
841843
None,
842844
pointer,
843845
ptr_base_index.def(self),
844846
indices,
845847
)
846848
} else {
847-
emit.ptr_access_chain(
849+
builder.ptr_access_chain(
848850
result_type,
849851
None,
850852
pointer,
@@ -857,9 +859,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
857859
result
858860
} else {
859861
if is_inbounds {
860-
emit.in_bounds_access_chain(result_type, None, pointer, indices)
862+
builder.in_bounds_access_chain(result_type, None, pointer, indices)
861863
} else {
862-
emit.access_chain(result_type, None, pointer, indices)
864+
builder.access_chain(result_type, None, pointer, indices)
863865
}
864866
.unwrap()
865867
}
@@ -1091,21 +1093,9 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
10911093

10921094
#[instrument(level = "trace", skip(cx))]
10931095
fn build(cx: &'a Self::CodegenCx, llbb: Self::BasicBlock) -> Self {
1094-
let cursor = cx.builder.select_block_by_id(llbb);
1095-
// FIXME(eddyb) change `Self::Function` to be more like a function index.
1096-
let current_fn = {
1097-
let emit = cx.emit_with_cursor(cursor);
1098-
let selected_function = emit.selected_function().unwrap();
1099-
let selected_function = &emit.module_ref().functions[selected_function];
1100-
let def_inst = selected_function.def.as_ref().unwrap();
1101-
let def = def_inst.result_id.unwrap();
1102-
let ty = def_inst.operands[1].unwrap_id_ref();
1103-
def.with_type(ty)
1104-
};
11051096
Self {
11061097
cx,
1107-
cursor,
1108-
current_fn,
1098+
current_block: llbb,
11091099
current_span: Default::default(),
11101100
}
11111101
}
@@ -1201,17 +1191,18 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
12011191
llfn: Self::Function,
12021192
_name: &str,
12031193
) -> Self::BasicBlock {
1204-
let cursor_fn = cx.builder.select_function_by_id(llfn.def_cx(cx));
1205-
cx.emit_with_cursor(cursor_fn).begin_block(None).unwrap()
1194+
let mut builder = cx.builder.builder_for_fn(llfn);
1195+
let id = builder.begin_block(None).unwrap();
1196+
let index_in_builder = builder.selected_block().unwrap();
1197+
SpirvBlockCursor {
1198+
parent_fn: llfn,
1199+
id,
1200+
index_in_builder,
1201+
}
12061202
}
12071203

1208-
fn append_sibling_block(&mut self, _name: &str) -> Self::BasicBlock {
1209-
self.emit_with_cursor(BuilderCursor {
1210-
function: self.cursor.function,
1211-
block: None,
1212-
})
1213-
.begin_block(None)
1214-
.unwrap()
1204+
fn append_sibling_block(&mut self, name: &str) -> Self::BasicBlock {
1205+
Self::append_block(self.cx, self.current_block.parent_fn, name)
12151206
}
12161207

12171208
fn switch_to_block(&mut self, llbb: Self::BasicBlock) {
@@ -1239,7 +1230,7 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
12391230
}
12401231

12411232
fn br(&mut self, dest: Self::BasicBlock) {
1242-
self.emit().branch(dest).unwrap();
1233+
self.emit().branch(dest.id).unwrap();
12431234
}
12441235

12451236
fn cond_br(
@@ -1257,7 +1248,7 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
12571248
Some(SpirvConst::Scalar(0)) => self.br(else_llbb),
12581249
_ => {
12591250
self.emit()
1260-
.branch_conditional(cond, then_llbb, else_llbb, empty())
1251+
.branch_conditional(cond, then_llbb.id, else_llbb.id, empty())
12611252
.unwrap();
12621253
}
12631254
}
@@ -1330,9 +1321,11 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
13301321
)),
13311322
};
13321323
let cases = cases
1333-
.map(|(i, b)| (construct_case(self, signed, i), b))
1324+
.map(|(i, b)| (construct_case(self, signed, i), b.id))
13341325
.collect::<Vec<_>>();
1335-
self.emit().switch(v.def(self), else_llbb, cases).unwrap();
1326+
self.emit()
1327+
.switch(v.def(self), else_llbb.id, cases)
1328+
.unwrap();
13361329
}
13371330

13381331
fn invoke(
@@ -1349,7 +1342,7 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
13491342
) -> Self::Value {
13501343
// Exceptions don't exist, jump directly to then block
13511344
let result = self.call(llty, fn_attrs, fn_abi, llfn, args, funclet, instance);
1352-
self.emit().branch(then).unwrap();
1345+
self.emit().branch(then.id).unwrap();
13531346
result
13541347
}
13551348

@@ -2741,16 +2734,16 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
27412734
.with_type(agg_val.ty)
27422735
}
27432736

2744-
fn set_personality_fn(&mut self, _personality: Self::Value) {
2737+
fn set_personality_fn(&mut self, _personality: Self::Function) {
27452738
todo!()
27462739
}
27472740

27482741
// These are used by everyone except msvc
2749-
fn cleanup_landing_pad(&mut self, _pers_fn: Self::Value) -> (Self::Value, Self::Value) {
2742+
fn cleanup_landing_pad(&mut self, _pers_fn: Self::Function) -> (Self::Value, Self::Value) {
27502743
todo!()
27512744
}
27522745

2753-
fn filter_landing_pad(&mut self, _pers_fn: Self::Value) -> (Self::Value, Self::Value) {
2746+
fn filter_landing_pad(&mut self, _pers_fn: Self::Function) -> (Self::Value, Self::Value) {
27542747
todo!()
27552748
}
27562749

@@ -2979,16 +2972,6 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
29792972
// be fixed upstream, so we never see any "function pointer" values being
29802973
// created just to perform direct calls.
29812974
let (callee_val, result_type, argument_types) = match self.lookup_type(callee.ty) {
2982-
// HACK(eddyb) this seems to be needed, but it's not what `get_fn_addr`
2983-
// produces, are these coming from inside `rustc_codegen_spirv`?
2984-
SpirvType::Function {
2985-
return_type,
2986-
arguments,
2987-
} => {
2988-
assert_ty_eq!(self, callee_ty, callee.ty);
2989-
(callee.def(self), return_type, arguments)
2990-
}
2991-
29922975
SpirvType::Pointer { pointee } => match self.lookup_type(pointee) {
29932976
SpirvType::Function {
29942977
return_type,
@@ -3014,7 +2997,7 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
30142997
},
30152998

30162999
_ => bug!(
3017-
"call expected function or `fn` pointer type, got `{}`",
3000+
"call expected `fn` pointer type, got `{}`",
30183001
self.debug_type(callee.ty)
30193002
),
30203003
};

crates/rustc_codegen_spirv/src/builder/mod.rs

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ pub use spirv_asm::InstructionTable;
1212
// HACK(eddyb) avoids rewriting all of the imports (see `lib.rs` and `build.rs`).
1313
use crate::maybe_pqp_cg_ssa as rustc_codegen_ssa;
1414

15-
use crate::builder_spirv::{BuilderCursor, SpirvValue, SpirvValueExt};
15+
use crate::builder_spirv::{SpirvValue, SpirvValueExt};
1616
use crate::codegen_cx::CodegenCx;
1717
use crate::spirv_type::SpirvType;
1818
use rspirv::spirv::Word;
@@ -40,8 +40,7 @@ use std::ops::{Deref, Range};
4040

4141
pub struct Builder<'a, 'tcx> {
4242
cx: &'a CodegenCx<'tcx>,
43-
cursor: BuilderCursor,
44-
current_fn: <Self as BackendTypes>::Function,
43+
current_block: <Self as BackendTypes>::BasicBlock,
4544
current_span: Option<Span>,
4645
}
4746

@@ -52,7 +51,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
5251
// (sadly it requires making `&CodegeCx`'s types/consts more like SPIR-T,
5352
// and completely disjoint from mutably building functions).
5453
pub fn emit(&mut self) -> std::cell::RefMut<'a, rspirv::dr::Builder> {
55-
self.cx.emit_with_cursor(self.cursor)
54+
self.cx.builder.builder_for_block(self.current_block)
5655
}
5756

5857
pub fn zombie(&self, word: Word, reason: &str) {
@@ -212,15 +211,16 @@ impl<'a, 'tcx> ArgAbiBuilderMethods<'tcx> for Builder<'a, 'tcx> {
212211
idx: &mut usize,
213212
dst: PlaceRef<'tcx, Self::Value>,
214213
) {
215-
fn next(bx: &Builder<'_, '_>, idx: &mut usize) -> SpirvValue {
216-
let val = bx.function_parameter_values.borrow()[&bx.current_fn.def(bx)][*idx];
214+
fn next(bx: &mut Builder<'_, '_>, idx: &mut usize) -> SpirvValue {
215+
let val = bx.get_param(*idx);
217216
*idx += 1;
218217
val
219218
}
220219
match arg_abi.mode {
221220
PassMode::Ignore => {}
222221
PassMode::Direct(_) => {
223-
self.store_arg(arg_abi, next(self, idx), dst);
222+
let arg = next(self, idx);
223+
self.store_arg(arg_abi, arg, dst);
224224
}
225225
PassMode::Pair(..) => {
226226
OperandValue::Pair(next(self, idx), next(self, idx)).store(self, dst);
@@ -257,7 +257,13 @@ impl<'a, 'tcx> ArgAbiBuilderMethods<'tcx> for Builder<'a, 'tcx> {
257257

258258
impl AbiBuilderMethods for Builder<'_, '_> {
259259
fn get_param(&mut self, index: usize) -> Self::Value {
260-
self.function_parameter_values.borrow()[&self.current_fn.def(self)][index]
260+
let builder = self.emit();
261+
let param =
262+
&builder.module_ref().functions[builder.selected_function().unwrap()].parameters[index];
263+
param
264+
.result_id
265+
.unwrap()
266+
.with_type(param.result_type.unwrap())
261267
}
262268
}
263269

crates/rustc_codegen_spirv/src/builder/spirv_asm.rs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use crate::maybe_pqp_cg_ssa as rustc_codegen_ssa;
33

44
use super::Builder;
55
use crate::abi::ConvSpirvType;
6-
use crate::builder_spirv::{BuilderCursor, SpirvValue};
6+
use crate::builder_spirv::SpirvValue;
77
use crate::codegen_cx::CodegenCx;
88
use crate::spirv_type::SpirvType;
99
use rspirv::dr;
@@ -418,12 +418,11 @@ impl<'cx, 'tcx> Builder<'cx, 'tcx> {
418418
// OpVariable with Function storage class should be emitted inside the function,
419419
// however, all other OpVariables should appear in the global scope instead.
420420
if inst.operands[0].unwrap_storage_class() == StorageClass::Function {
421-
self.emit_with_cursor(BuilderCursor {
422-
block: Some(0),
423-
..self.cursor
424-
})
425-
.insert_into_block(dr::InsertPoint::Begin, inst)
426-
.unwrap();
421+
let mut builder = self.emit();
422+
builder.select_block(Some(0)).unwrap();
423+
builder
424+
.insert_into_block(dr::InsertPoint::Begin, inst)
425+
.unwrap();
427426
} else {
428427
self.emit_global()
429428
.insert_types_global_values(dr::InsertPoint::End, inst);

0 commit comments

Comments
 (0)