really_unsafe_ignore_bitcasts

This commit is contained in:
khyperia 2020-09-30 15:49:01 +02:00
parent 98dfc0cf5e
commit 127cc1bb99
5 changed files with 33 additions and 9 deletions

View File

@ -1014,7 +1014,12 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
SpirvType::Pointer { .. } => (),
other => panic!("pointercast called on non-pointer dest type: {:?}", other),
}
if val.ty == dest_ty {
if val.ty == dest_ty
|| self
.really_unsafe_ignore_bitcasts
.borrow()
.contains(&self.current_fn)
{
val
} else {
let result = self

View File

@ -289,7 +289,7 @@ impl<'tcx> PreDefineMethods<'tcx> for CodegenCx<'tcx> {
) {
let fn_abi = FnAbi::of_instance(self, instance, &[]);
let human_name = format!("{}", instance);
let linkage = match linkage {
let linkage2 = match linkage {
Linkage::External => Some(LinkageType::Export),
Linkage::Internal => None,
other => panic!("TODO: Linkage type not supported yet: {:?}", other),
@ -298,15 +298,23 @@ impl<'tcx> PreDefineMethods<'tcx> for CodegenCx<'tcx> {
let spv_attrs = attrs_to_spirv(rust_attrs);
let declared =
self.declare_fn_ext(symbol_name, Some(&human_name), linkage, spv_attrs, &fn_abi);
self.declare_fn_ext(symbol_name, Some(&human_name), linkage2, spv_attrs, &fn_abi);
for attr in self.tcx.get_attrs(instance.def_id()) {
if let Some(SpirvAttribute::Entry(execution_model)) = parse_attr(self, attr) {
if execution_model == ExecutionModel::Kernel {
self.kernel_entry_stub(declared, human_name.clone(), execution_model);
} else {
self.entry_stub(declared, human_name.clone(), execution_model);
match parse_attr(self, attr) {
Some(SpirvAttribute::Entry(execution_model)) => {
if execution_model == ExecutionModel::Kernel {
self.kernel_entry_stub(declared, human_name.clone(), execution_model);
} else {
self.entry_stub(declared, human_name.clone(), execution_model);
}
}
Some(SpirvAttribute::ReallyUnsafeIgnoreBitcasts) => {
self.really_unsafe_ignore_bitcasts
.borrow_mut()
.insert(declared);
}
_ => {}
}
}

View File

@ -29,7 +29,7 @@ use rustc_target::abi::call::FnAbi;
use rustc_target::abi::{HasDataLayout, TargetDataLayout};
use rustc_target::spec::{HasTargetSpec, Target};
use std::cell::RefCell;
use std::collections::HashMap;
use std::collections::{HashMap, HashSet};
use std::iter::once;
pub struct CodegenCx<'tcx> {
@ -50,6 +50,7 @@ pub struct CodegenCx<'tcx> {
pub kernel_mode: bool,
/// Cache of all the builtin symbols we need
pub sym: Box<Symbols>,
pub really_unsafe_ignore_bitcasts: RefCell<HashSet<SpirvValue>>,
/// Functions created in get_fn_addr
/// left: the OpUndef value. right: the function value.
function_pointers: RefCell<BiHashMap<SpirvValue, SpirvValue>>,
@ -74,6 +75,7 @@ impl<'tcx> CodegenCx<'tcx> {
zombie_values: Default::default(),
kernel_mode,
sym,
really_unsafe_ignore_bitcasts: Default::default(),
function_pointers: Default::default(),
i8_i16_atomics_allowed: false,
}

View File

@ -14,6 +14,7 @@ pub struct Symbols {
pub shader: Symbol,
pub storage_class: Symbol,
pub entry: Symbol,
pub really_unsafe_ignore_bitcasts: Symbol,
storage_classes: HashMap<Symbol, StorageClass>,
execution_models: HashMap<Symbol, ExecutionModel>,
@ -80,6 +81,7 @@ impl Symbols {
shader: Symbol::intern("shader"),
storage_class: Symbol::intern("storage_class"),
entry: Symbol::intern("entry"),
really_unsafe_ignore_bitcasts: Symbol::intern("really_unsafe_ignore_bitcasts"),
storage_classes: make_storage_classes(),
execution_models: make_execution_models(),
}
@ -97,6 +99,7 @@ impl Symbols {
pub enum SpirvAttribute {
StorageClass(StorageClass),
Entry(ExecutionModel),
ReallyUnsafeIgnoreBitcasts,
}
// Note that we could mark the attr as used via cx.tcx.sess.mark_attr_used(attr), but unused reporting already happens
@ -167,6 +170,8 @@ pub fn parse_attr<'tcx>(cx: &CodegenCx<'tcx>, attr: &Attribute) -> Option<SpirvA
.span_err(attr.span, "entry must have value: #[spirv(entry = \"..\")]");
None
}
} else if arg.has_name(cx.sym.really_unsafe_ignore_bitcasts) {
Some(SpirvAttribute::ReallyUnsafeIgnoreBitcasts)
} else {
cx.tcx
.sess

View File

@ -6,6 +6,8 @@ macro_rules! pointer_addrspace_write {
(false) => {};
(true) => {
#[inline]
#[allow(unused_attributes)]
#[spirv(really_unsafe_ignore_bitcasts)]
pub fn store(&mut self, v: T) {
*self.x = v
}
@ -22,6 +24,8 @@ macro_rules! pointer_addrspace {
impl<'a, T: Copy> $type_name<'a, T> {
#[inline]
#[allow(unused_attributes)]
#[spirv(really_unsafe_ignore_bitcasts)]
pub fn load(&self) -> T {
*self.x
}