mirror of
https://github.com/EmbarkStudios/rust-gpu.git
synced 2025-02-16 17:04:16 +00:00
Get closer to testing NO_DCE in CI (#321)
* Get closer to testing NO_DCE in CI The only remaining validation issues are due to the SROA pass not being implemented yet * Revert mistakenly included change
This commit is contained in:
parent
c70cee8f97
commit
a653c61b64
@ -4,7 +4,7 @@
|
||||
use crate::codegen_cx::CodegenCx;
|
||||
use crate::spirv_type::SpirvType;
|
||||
use crate::symbols::{parse_attrs, SpirvAttribute};
|
||||
use rspirv::spirv::{StorageClass, Word};
|
||||
use rspirv::spirv::{Capability, StorageClass, Word};
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::ty::layout::{FnAbiExt, TyAndLayout};
|
||||
use rustc_middle::ty::{GeneratorSubsts, PolyFnSig, Ty, TyKind, TypeAndMut};
|
||||
@ -33,6 +33,7 @@ impl<'tcx> RecursivePointeeCache<'tcx> {
|
||||
fn begin(
|
||||
&self,
|
||||
cx: &CodegenCx<'tcx>,
|
||||
span: Span,
|
||||
pointee: PointeeTy<'tcx>,
|
||||
storage_class: StorageClass,
|
||||
) -> Option<Word> {
|
||||
@ -52,6 +53,18 @@ impl<'tcx> RecursivePointeeCache<'tcx> {
|
||||
let new_id = cx.emit_global().id();
|
||||
cx.emit_global().type_forward_pointer(new_id, storage_class);
|
||||
entry.insert(PointeeDefState::DefiningWithForward(new_id));
|
||||
if !cx.builder.has_capability(Capability::Addresses)
|
||||
&& !cx
|
||||
.builder
|
||||
.has_capability(Capability::PhysicalStorageBufferAddresses)
|
||||
{
|
||||
cx.zombie_with_span(
|
||||
new_id,
|
||||
span,
|
||||
"OpTypeForwardPointer without OpCapability \
|
||||
Addresses or PhysicalStorageBufferAddresses",
|
||||
);
|
||||
}
|
||||
Some(new_id)
|
||||
}
|
||||
// State: This is the third or more time we've seen this type, and we've already emitted an
|
||||
@ -459,7 +472,7 @@ fn trans_scalar<'tcx>(
|
||||
if let Some(predefined_result) =
|
||||
cx.type_cache
|
||||
.recursive_pointee_cache
|
||||
.begin(cx, pointee_ty, storage_class)
|
||||
.begin(cx, span, pointee_ty, storage_class)
|
||||
{
|
||||
predefined_result
|
||||
} else {
|
||||
|
@ -216,6 +216,15 @@ impl<'tcx> CodegenCx<'tcx> {
|
||||
self.emit_global()
|
||||
.variable(ty, None, StorageClass::Function, Some(initializer));
|
||||
|
||||
// In all likelihood, this zombie message will get overwritten in SpirvValue::def_with_span
|
||||
// to the use site of this constant. However, if this constant happens to never get used, we
|
||||
// still want to zobmie it, so zombie here.
|
||||
self.zombie_even_in_user_code(
|
||||
global_var,
|
||||
span,
|
||||
"Cannot use this pointer directly, it must be dereferenced first",
|
||||
);
|
||||
|
||||
SpirvValue {
|
||||
kind: SpirvValueKind::ConstantPointer {
|
||||
initializer,
|
||||
|
@ -189,12 +189,16 @@ impl SpirvType {
|
||||
storage_class,
|
||||
pointee,
|
||||
} => {
|
||||
// Note: pointers to functions are always illegal in SPIR-V. However, the type of a
|
||||
// pointer to a function is sometimes used in e.g. get_fn_addr, which creates a
|
||||
// `SpirvValueKind::ConstantPointer`. So, pointers to functions are made illegal by
|
||||
// the fact it's impossible to create a pointer to function *value*, so the type
|
||||
// existing is fine.
|
||||
cx.emit_global().type_pointer(None, storage_class, pointee)
|
||||
let result = cx.emit_global().type_pointer(None, storage_class, pointee);
|
||||
// no pointers to functions
|
||||
if let Self::Function { .. } = cx.lookup_type(pointee) {
|
||||
cx.zombie_even_in_user_code(
|
||||
result,
|
||||
def_span,
|
||||
"function pointer types are not allowed",
|
||||
)
|
||||
}
|
||||
result
|
||||
}
|
||||
Self::Function {
|
||||
return_type,
|
||||
@ -229,7 +233,7 @@ impl SpirvType {
|
||||
|
||||
/// `def_with_id` is used by the `RecursivePointeeCache` to handle `OpTypeForwardPointer`: when
|
||||
/// emitting the subsequent `OpTypePointer`, the ID is already known and must be re-used.
|
||||
pub fn def_with_id(self, cx: &CodegenCx<'_>, _def_span: Span, id: Word) -> Word {
|
||||
pub fn def_with_id(self, cx: &CodegenCx<'_>, def_span: Span, id: Word) -> Word {
|
||||
if let Some(cached) = cx.type_cache.get(&self) {
|
||||
assert_eq!(cached, id);
|
||||
return cached;
|
||||
@ -238,9 +242,20 @@ impl SpirvType {
|
||||
Self::Pointer {
|
||||
storage_class,
|
||||
pointee,
|
||||
} => cx
|
||||
.emit_global()
|
||||
.type_pointer(Some(id), storage_class, pointee),
|
||||
} => {
|
||||
let result = cx
|
||||
.emit_global()
|
||||
.type_pointer(Some(id), storage_class, pointee);
|
||||
// no pointers to functions
|
||||
if let Self::Function { .. } = cx.lookup_type(pointee) {
|
||||
cx.zombie_even_in_user_code(
|
||||
result,
|
||||
def_span,
|
||||
"function pointer types are not allowed",
|
||||
)
|
||||
}
|
||||
result
|
||||
}
|
||||
ref other => cx
|
||||
.tcx
|
||||
.sess
|
||||
|
@ -1,4 +1,23 @@
|
||||
use super::{dis_fn, val, val_vulkan};
|
||||
use std::ffi::OsStr;
|
||||
|
||||
struct SetEnvVar<'a> {
|
||||
k: &'a OsStr,
|
||||
}
|
||||
|
||||
impl<'a> SetEnvVar<'a> {
|
||||
fn new(k: &'a impl AsRef<OsStr>, v: impl AsRef<OsStr>) -> Self {
|
||||
let k = k.as_ref();
|
||||
std::env::set_var(k, v);
|
||||
Self { k }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Drop for SetEnvVar<'a> {
|
||||
fn drop(&mut self) {
|
||||
std::env::remove_var(self.k)
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn hello_world() {
|
||||
@ -10,6 +29,19 @@ pub fn main() {
|
||||
"#);
|
||||
}
|
||||
|
||||
#[test]
|
||||
// blocked on: https://github.com/EmbarkStudios/rust-gpu/issues/69
|
||||
#[ignore]
|
||||
fn no_dce() {
|
||||
let _var = SetEnvVar::new(&"NO_DCE", "1");
|
||||
val(r#"
|
||||
#[allow(unused_attributes)]
|
||||
#[spirv(fragment)]
|
||||
pub fn no_dce() {
|
||||
}
|
||||
"#);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn add_two_ints() {
|
||||
dis_fn(
|
||||
|
Loading…
Reference in New Issue
Block a user