This commit is contained in:
Ashley Hauck 2020-11-18 13:54:22 +01:00 committed by GitHub
parent c1c72517c8
commit bedbc4dc0f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 1134 additions and 85 deletions

6
Cargo.lock generated
View File

@ -1952,12 +1952,12 @@ dependencies = [
[[package]]
name = "rspirv"
version = "0.7.0"
source = "git+https://github.com/gfx-rs/rspirv.git?rev=f11f8797bd4df2d1d22cf10767b39a5119c57551#f11f8797bd4df2d1d22cf10767b39a5119c57551"
source = "git+https://github.com/gfx-rs/rspirv.git?rev=01ca0d2e5b667a0e4ff1bc1804511e38f9a08759#01ca0d2e5b667a0e4ff1bc1804511e38f9a08759"
dependencies = [
"derive_more",
"fxhash",
"num-traits",
"spirv_headers 1.5.0 (git+https://github.com/gfx-rs/rspirv.git?rev=f11f8797bd4df2d1d22cf10767b39a5119c57551)",
"spirv_headers 1.5.0 (git+https://github.com/gfx-rs/rspirv.git?rev=01ca0d2e5b667a0e4ff1bc1804511e38f9a08759)",
]
[[package]]
@ -2210,7 +2210,7 @@ dependencies = [
[[package]]
name = "spirv_headers"
version = "1.5.0"
source = "git+https://github.com/gfx-rs/rspirv.git?rev=f11f8797bd4df2d1d22cf10767b39a5119c57551#f11f8797bd4df2d1d22cf10767b39a5119c57551"
source = "git+https://github.com/gfx-rs/rspirv.git?rev=01ca0d2e5b667a0e4ff1bc1804511e38f9a08759#01ca0d2e5b667a0e4ff1bc1804511e38f9a08759"
dependencies = [
"bitflags",
"num-traits",

View File

@ -28,7 +28,7 @@ use-compiled-tools = ["spirv-tools/use-compiled-tools"]
[dependencies]
bimap = "0.5"
rspirv = { git = "https://github.com/gfx-rs/rspirv.git", rev = "f11f8797bd4df2d1d22cf10767b39a5119c57551" }
rspirv = { git = "https://github.com/gfx-rs/rspirv.git", rev = "01ca0d2e5b667a0e4ff1bc1804511e38f9a08759" }
spirv-tools = { version = "0.1.0", default-features = false }
tar = "0.4.30"
topological-sort = "0.1"

View File

@ -1,24 +1,23 @@
mod builder_methods;
mod ext_inst;
mod intrinsics;
mod spirv_asm;
pub use ext_inst::ExtInst;
pub use spirv_asm::InstructionTable;
use crate::abi::ConvSpirvType;
use crate::builder_spirv::{BuilderCursor, SpirvValue, SpirvValueExt};
use crate::codegen_cx::CodegenCx;
use crate::spirv_type::SpirvType;
use rspirv::spirv::{StorageClass, Word};
use rustc_ast::ast::{InlineAsmOptions, InlineAsmTemplatePiece};
use rustc_codegen_ssa::mir::operand::OperandValue;
use rustc_codegen_ssa::mir::place::PlaceRef;
use rustc_codegen_ssa::traits::{
AbiBuilderMethods, ArgAbiMethods, AsmBuilderMethods, BackendTypes, BuilderMethods,
CoverageInfoBuilderMethods, DebugInfoBuilderMethods, HasCodegen, InlineAsmOperandRef,
StaticBuilderMethods,
AbiBuilderMethods, ArgAbiMethods, BackendTypes, BuilderMethods, CoverageInfoBuilderMethods,
DebugInfoBuilderMethods, HasCodegen, StaticBuilderMethods,
};
use rustc_errors::DiagnosticBuilder;
use rustc_hir::LlvmInlineAsmInner;
use rustc_middle::mir::coverage::{
CodeRegion, CounterValueReference, ExpressionOperandId, InjectedExpressionId, Op,
};
@ -343,28 +342,6 @@ impl<'a, 'tcx> AbiBuilderMethods<'tcx> for Builder<'a, 'tcx> {
}
}
impl<'a, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'tcx> {
fn codegen_llvm_inline_asm(
&mut self,
_ia: &LlvmInlineAsmInner,
_outputs: Vec<PlaceRef<'tcx, Self::Value>>,
_inputs: Vec<Self::Value>,
_span: Span,
) -> bool {
self.err("LLVM asm not supported");
true
}
fn codegen_inline_asm(
&mut self,
_template: &[InlineAsmTemplatePiece],
_operands: &[InlineAsmOperandRef<'tcx, Self>],
_options: InlineAsmOptions,
_line_spans: &[Span],
) {
self.err("asm not supported")
}
}
impl<'a, 'tcx> StaticBuilderMethods for Builder<'a, 'tcx> {
fn get_static(&mut self, def_id: DefId) -> Self::Value {
self.cx.get_static(def_id)

File diff suppressed because it is too large Load Diff

View File

@ -10,7 +10,7 @@ use rustc_middle::bug;
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
use rustc_middle::mir::mono::{Linkage, MonoItem, Visibility};
use rustc_middle::ty::layout::FnAbiExt;
use rustc_middle::ty::{Instance, ParamEnv, Ty, TypeFoldable};
use rustc_middle::ty::{Instance, ParamEnv, TypeFoldable};
use rustc_span::def_id::DefId;
use rustc_span::Span;
use rustc_target::abi::call::FnAbi;
@ -43,14 +43,10 @@ impl<'tcx> CodegenCx<'tcx> {
return func;
}
let sym = self.tcx.symbol_name(instance).name;
// Because we've already declared everything with predefine_fn, if we hit this branch, we're guaranteed to be
// importing this function from elsewhere. So, slap an extern on it.
let human_name = format!("{}", instance);
let linkage = Some(LinkageType::Import);
let attrs = attrs_to_spirv(self.tcx.codegen_fn_attrs(instance.def_id()));
let fn_abi = FnAbi::of_instance(self, instance, &[]);
let llfn = self.declare_fn_ext(sym, Some(&human_name), linkage, attrs, &fn_abi);
let llfn = self.declare_fn_ext(instance, linkage);
self.instances.borrow_mut().insert(instance, llfn);
@ -61,14 +57,10 @@ impl<'tcx> CodegenCx<'tcx> {
// MiscMethods::get_fn -> get_fn_ext -> declare_fn_ext
// MiscMethods::get_fn_addr -> get_fn_ext -> declare_fn_ext
// PreDefineMethods::predefine_fn -> declare_fn_ext
fn declare_fn_ext(
&self,
name: &str,
human_name: Option<&str>,
linkage: Option<LinkageType>,
control: FunctionControl,
fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
) -> SpirvValue {
fn declare_fn_ext(&self, instance: Instance<'tcx>, linkage: Option<LinkageType>) -> SpirvValue {
let symbol_name = self.tcx.symbol_name(instance).name;
let control = attrs_to_spirv(self.tcx.codegen_fn_attrs(instance.def_id()));
let fn_abi = FnAbi::of_instance(self, instance, &[]);
let function_type = fn_abi.spirv_type(self);
let (return_type, argument_types) = match self.lookup_type(function_type) {
SpirvType::Function {
@ -78,7 +70,7 @@ impl<'tcx> CodegenCx<'tcx> {
other => bug!("fn_abi type {}", other.debug(function_type, self)),
};
if crate::is_blocklisted_fn(name) {
if crate::is_blocklisted_fn(symbol_name) {
// This can happen if we call a blocklisted function in another crate.
let result = self.undef(function_type);
// TODO: Span info here
@ -99,16 +91,31 @@ impl<'tcx> CodegenCx<'tcx> {
.insert(fn_id, parameter_values);
}
emit.end_function().unwrap();
match human_name {
Some(human_name) => emit.name(fn_id, human_name),
None => emit.name(fn_id, name),
}
let human_name = format!("{}", instance);
emit.name(fn_id, &human_name);
drop(emit); // set_linkage uses emit
if let Some(linkage) = linkage {
self.set_linkage(fn_id, name.to_owned(), linkage);
self.set_linkage(fn_id, symbol_name.to_owned(), linkage);
}
fn_id.with_type(function_type)
let declared = fn_id.with_type(function_type);
for attr in parse_attrs(self, self.tcx.get_attrs(instance.def_id())) {
match attr {
SpirvAttribute::Entry(entry) => {
self.entry_stub(&instance, &fn_abi, declared, human_name.clone(), entry)
}
SpirvAttribute::ReallyUnsafeIgnoreBitcasts => {
self.really_unsafe_ignore_bitcasts
.borrow_mut()
.insert(declared);
}
_ => {}
}
}
declared
}
pub fn get_static(&self, def_id: DefId) -> SpirvValue {
@ -175,11 +182,6 @@ impl<'tcx> PreDefineMethods<'tcx> for CodegenCx<'tcx> {
let span = self.tcx.def_span(def_id);
let g = self.declare_global(span, spvty);
// unsafe {
// llvm::LLVMRustSetLinkage(g, base::linkage_to_llvm(linkage));
// llvm::LLVMRustSetVisibility(g, base::visibility_to_llvm(visibility));
// }
self.instances.borrow_mut().insert(instance, g);
if let Some(linkage) = linkage {
self.set_linkage(g.def_cx(self), symbol_name.to_string(), linkage);
@ -191,10 +193,8 @@ impl<'tcx> PreDefineMethods<'tcx> for CodegenCx<'tcx> {
instance: Instance<'tcx>,
linkage: Linkage,
_visibility: Visibility,
symbol_name: &str,
_symbol_name: &str,
) {
let fn_abi = FnAbi::of_instance(self, instance, &[]);
let human_name = format!("{}", instance);
let linkage2 = match linkage {
Linkage::External => Some(LinkageType::Export),
Linkage::Internal => None,
@ -203,25 +203,7 @@ impl<'tcx> PreDefineMethods<'tcx> for CodegenCx<'tcx> {
other
)),
};
let rust_attrs = self.tcx.codegen_fn_attrs(instance.def_id());
let spv_attrs = attrs_to_spirv(rust_attrs);
let declared =
self.declare_fn_ext(symbol_name, Some(&human_name), linkage2, spv_attrs, &fn_abi);
for attr in parse_attrs(self, self.tcx.get_attrs(instance.def_id())) {
match attr {
SpirvAttribute::Entry(entry) => {
self.entry_stub(&instance, &fn_abi, declared, human_name.clone(), entry)
}
SpirvAttribute::ReallyUnsafeIgnoreBitcasts => {
self.really_unsafe_ignore_bitcasts
.borrow_mut()
.insert(declared);
}
_ => {}
}
}
let declared = self.declare_fn_ext(instance, linkage2);
self.instances.borrow_mut().insert(instance, declared);
}

View File

@ -3,7 +3,7 @@ mod declare;
mod entry;
mod type_;
use crate::builder::ExtInst;
use crate::builder::{ExtInst, InstructionTable};
use crate::builder_spirv::{BuilderCursor, BuilderSpirv, SpirvValue, SpirvValueKind};
use crate::finalizing_passes::export_zombies;
use crate::spirv_type::{SpirvType, SpirvTypePrinter, TypeCache};
@ -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 instruction_table: InstructionTable,
pub really_unsafe_ignore_bitcasts: RefCell<HashSet<SpirvValue>>,
pub zombie_undefs_for_system_constant_pointers: RefCell<HashMap<Word, Word>>,
/// Some runtimes (e.g. intel-compute-runtime) disallow atomics on i8 and i16, even though it's allowed by the spec.
@ -100,6 +101,7 @@ impl<'tcx> CodegenCx<'tcx> {
zombie_values: Default::default(),
kernel_mode,
sym,
instruction_table: InstructionTable::new(),
really_unsafe_ignore_bitcasts: Default::default(),
zombie_undefs_for_system_constant_pointers: Default::default(),
i8_i16_atomics_allowed: false,
@ -263,7 +265,7 @@ impl<'tcx> MiscMethods<'tcx> for CodegenCx<'tcx> {
}
fn get_fn_addr(&self, instance: Instance<'tcx>) -> Self::Value {
let function = self.get_fn_ext(instance);
let function = self.get_fn(instance);
self.make_constant_pointer(function)
}

View File

@ -34,6 +34,69 @@ OpFunctionEnd"#,
);
}
#[test]
fn asm() {
dis_fn(
r#"
fn asm() {
unsafe {
asm!(
"%int = OpTypeInt 32 0",
"%scope = OpConstant %int 2",
"%semantics = OpConstant %int 8452",
"OpMemoryBarrier %scope %semantics",
);
}
}
#[allow(unused_attributes)]
#[spirv(fragment)]
pub fn main() {
asm();
}
"#,
"asm",
// note: the OpConstants get hoisted out to global in the linker merge pass
r#"%1 = OpFunction %2 None %3
%4 = OpLabel
OpMemoryBarrier %5 %6
OpReturn
OpFunctionEnd"#,
);
}
#[test]
fn asm_add_two_ints() {
dis_fn(
r#"
fn add_two_ints(x: u32, y: u32) -> u32 {
let result;
unsafe {
asm!(
"{0} = OpIAdd typeof{0} {1} {2}",
out(reg) result,
in(reg) x,
in(reg) y,
);
}
result
}
#[allow(unused_attributes)]
#[spirv(fragment)]
pub fn main() {
add_two_ints(2, 3);
}
"#,
"add_two_ints",
r#"%1 = OpFunction %2 None %3
%4 = OpFunctionParameter %2
%5 = OpFunctionParameter %2
%6 = OpLabel
%7 = OpIAdd %2 %4 %5
OpReturnValue %7
OpFunctionEnd"#,
);
}
// TODO: Implement strings to make this compile
#[test]
#[ignore]

View File

@ -49,7 +49,7 @@ spirv-std = { path = "../../crates/spirv-std" }
"#;
static SRC_PREFIX: &str = r#"#![no_std]
#![feature(lang_items, register_attr)]
#![feature(lang_items, register_attr, asm)]
#![register_attr(spirv)]
use core::panic::PanicInfo;
#[allow(unused_imports)]

View File

@ -1 +1 @@
nightly-2020-11-13
nightly-2020-11-15

View File

@ -1,6 +1,6 @@
setlocal
rustup toolchain install nightly-2020-11-13 --component rust-src rustc-dev llvm-tools-preview
rustup toolchain install nightly-2020-11-15 --component rust-src rustc-dev llvm-tools-preview
git submodule init
git submodule update

View File

@ -1,6 +1,6 @@
#!/usr/bin/env bash
rustup toolchain install nightly-2020-11-13 --component rust-src rustc-dev llvm-tools-preview
rustup toolchain install nightly-2020-11-15 --component rust-src rustc-dev llvm-tools-preview
git submodule init
git submodule update