mirror of
https://github.com/EmbarkStudios/rust-gpu.git
synced 2024-11-25 00:04:11 +00:00
Inline calls that look like f(&s.x) (#777)
This commit is contained in:
parent
c10a1ca756
commit
902c51c242
@ -218,6 +218,25 @@ fn should_inline(
|
||||
|| disallowed_return_types.contains(&function.def.as_ref().unwrap().result_type.unwrap())
|
||||
}
|
||||
|
||||
// This should be more general, but a very common problem is passing an OpAccessChain to an
|
||||
// OpFunctionCall (i.e. `f(&s.x)`, or more commonly, `s.x.f()` where `f` takes `&self`), so detect
|
||||
// that case and inline the call.
|
||||
fn args_invalid(function: &Function, call: &Instruction) -> bool {
|
||||
for inst in function.all_inst_iter() {
|
||||
if inst.class.opcode == Op::AccessChain {
|
||||
let inst_result = inst.result_id.unwrap();
|
||||
if call
|
||||
.operands
|
||||
.iter()
|
||||
.any(|op| *op == Operand::IdRef(inst_result))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
// Steps:
|
||||
// Move OpVariable decls
|
||||
// Rewrite return
|
||||
@ -292,12 +311,12 @@ impl Inliner<'_, '_> {
|
||||
.unwrap(),
|
||||
)
|
||||
})
|
||||
.find(|(_, _, f)| {
|
||||
.find(|(_, inst, f)| {
|
||||
should_inline(
|
||||
self.disallowed_argument_types,
|
||||
self.disallowed_return_types,
|
||||
f,
|
||||
)
|
||||
) || args_invalid(caller, inst)
|
||||
});
|
||||
let (call_index, call_inst, callee) = match call {
|
||||
None => return false,
|
||||
|
16
tests/ui/lang/core/ref/member_ref_arg.rs
Normal file
16
tests/ui/lang/core/ref/member_ref_arg.rs
Normal file
@ -0,0 +1,16 @@
|
||||
// build-pass
|
||||
|
||||
use spirv_std as _;
|
||||
|
||||
struct S {
|
||||
x: u32,
|
||||
y: u32,
|
||||
}
|
||||
|
||||
fn f(x: &u32) {}
|
||||
|
||||
#[spirv(fragment)]
|
||||
pub fn main() {
|
||||
let s = S { x: 2, y: 2 };
|
||||
f(&s.x);
|
||||
}
|
Loading…
Reference in New Issue
Block a user