MCPcopy Create free account
hub / github.com/Rust-GPU/rust-gpu / collect_access_chains

Function collect_access_chains

crates/rustc_codegen_spirv/src/linker/mem2reg.rs:216–287  ·  view source on GitHub ↗
(
    pointer_to_pointee: &FxHashMap<Word, Word>,
    constants: &FxHashMap<Word, u32>,
    blocks: &[Block],
    base_var: Word,
    base_var_ty: Word,
)

Source from the content-addressed store, hash-verified

214}
215
216fn collect_access_chains(
217 pointer_to_pointee: &FxHashMap<Word, Word>,
218 constants: &FxHashMap<Word, u32>,
219 blocks: &[Block],
220 base_var: Word,
221 base_var_ty: Word,
222) -> Option<FxHashMap<Word, VarInfo>> {
223 fn construct_access_chain_info(
224 pointer_to_pointee: &FxHashMap<Word, Word>,
225 constants: &FxHashMap<Word, u32>,
226 inst: &Instruction,
227 base: &VarInfo,
228 ) -> Option<VarInfo> {
229 Some(VarInfo {
230 ty: *pointer_to_pointee.get(&inst.result_type.unwrap()).unwrap(),
231 indices: {
232 let mut base_indicies = base.indices.clone();
233 for op in inst.operands.iter().skip(1) {
234 base_indicies.push(*constants.get(&op.id_ref_any().unwrap())?);
235 }
236 base_indicies
237 },
238 })
239 }
240
241 let mut variables = FxHashMap::default();
242 variables.insert(
243 base_var,
244 VarInfo {
245 ty: base_var_ty,
246 indices: vec![],
247 },
248 );
249 // Loop in case a previous block references a later AccessChain
250 loop {
251 let mut changed = false;
252 for inst in blocks.iter().flat_map(|b| &b.instructions) {
253 for (index, op) in inst.operands.iter().enumerate() {
254 if let Operand::IdRef(id) = op {
255 if variables.contains_key(id) {
256 match inst.class.opcode {
257 // Only allow store if pointer is the lhs, not rhs
258 Op::Store if index == 0 => {}
259 Op::Load
260 | Op::AccessChain
261 | Op::InBoundsAccessChain
262 | Op::CopyMemory => {}
263 _ => return None,
264 }
265 }
266 }
267 }
268 if let Op::AccessChain | Op::InBoundsAccessChain = inst.class.opcode {
269 if let Some(base) = variables.get(&inst.operands[0].id_ref_any().unwrap()) {
270 let info =
271 construct_access_chain_info(pointer_to_pointee, constants, inst, base)?;
272 match variables.entry(inst.result_id.unwrap()) {
273 hash_map::Entry::Vacant(entry) => {

Callers 1

insert_phis_allFunction · 0.85

Calls 4

insertMethod · 0.80
iterMethod · 0.80
getMethod · 0.45

Tested by

no test coverage detected