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

Method gep_help

crates/rustc_codegen_spirv/src/builder/mod.rs:122–182  ·  view source on GitHub ↗
(
        &mut self,
        ty: Word,
        ptr: SpirvValue,
        indices: &[SpirvValue],
        is_inbounds: bool,
    )

Source from the content-addressed store, hash-verified

120 }
121
122 pub fn gep_help(
123 &mut self,
124 ty: Word,
125 ptr: SpirvValue,
126 indices: &[SpirvValue],
127 is_inbounds: bool,
128 ) -> SpirvValue {
129 // The first index is an offset to the pointer, the rest are actual members.
130 // https://llvm.org/docs/GetElementPtr.html
131 // "An OpAccessChain instruction is the equivalent of an LLVM getelementptr instruction where the first index element is zero."
132 // https://github.com/gpuweb/gpuweb/issues/33
133 let mut result_indices = Vec::with_capacity(indices.len() - 1);
134 let mut result_pointee_type = match self.lookup_type(ptr.ty) {
135 SpirvType::Pointer { pointee } => {
136 assert_ty_eq!(self, ty, pointee);
137 pointee
138 }
139 other_type => self.fatal(&format!(
140 "GEP first deref not implemented for type {other_type:?}"
141 )),
142 };
143 for index in indices.iter().cloned().skip(1) {
144 result_indices.push(index.def(self));
145 result_pointee_type = match self.lookup_type(result_pointee_type) {
146 SpirvType::Array { element, .. } | SpirvType::RuntimeArray { element } => element,
147 _ => self.fatal(&format!(
148 "GEP not implemented for type {}",
149 self.debug_type(result_pointee_type)
150 )),
151 };
152 }
153 let result_type = SpirvType::Pointer {
154 pointee: result_pointee_type,
155 }
156 .def(self.span(), self);
157
158 let ptr_id = ptr.def(self);
159 if let Some((original_ptr, mut original_indices)) = self.find_access_chain(ptr_id) {
160 // Transform the following:
161 // OpAccessChain original_ptr [a, b, c]
162 // OpPtrAccessChain ptr base [d, e, f]
163 // into
164 // OpAccessChain original_ptr [a, b, c + base, d, e, f]
165 // to remove the need for OpPtrAccessChain
166 let last = original_indices.last_mut().unwrap();
167 *last = self
168 .add(last.with_type(indices[0].ty), indices[0])
169 .def(self);
170 original_indices.append(&mut result_indices);
171 let zero = self.constant_int(indices[0].ty, 0);
172 self.emit_access_chain(
173 result_type,
174 original_ptr,
175 zero,
176 original_indices,
177 is_inbounds,
178 )
179 } else {

Callers 2

gepMethod · 0.80
inbounds_gepMethod · 0.80

Calls 9

lookup_typeMethod · 0.80
fatalMethod · 0.80
iterMethod · 0.80
spanMethod · 0.80
find_access_chainMethod · 0.80
with_typeMethod · 0.80
constant_intMethod · 0.80
emit_access_chainMethod · 0.80
defMethod · 0.45

Tested by

no test coverage detected