Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BPF target support #79608

Merged
merged 14 commits into from
Jun 6, 2021
1 change: 1 addition & 0 deletions compiler/rustc_codegen_cranelift/src/toolchain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
LinkerFlavor::Msvc => "link.exe",
LinkerFlavor::Lld(_) => "lld",
LinkerFlavor::PtxLinker => "rust-ptx-linker",
LinkerFlavor::BpfLinker => "bpf-linker",
}),
flavor,
)),
Expand Down
6 changes: 6 additions & 0 deletions compiler/rustc_codegen_llvm/src/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,7 @@ impl AsmBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
InlineAsmArch::Mips | InlineAsmArch::Mips64 => {}
InlineAsmArch::SpirV => {}
InlineAsmArch::Wasm32 => {}
InlineAsmArch::Bpf => {}
}
}
if !options.contains(InlineAsmOptions::NOMEM) {
Expand Down Expand Up @@ -593,6 +594,8 @@ fn reg_to_llvm(reg: InlineAsmRegOrRegClass, layout: Option<&TyAndLayout<'tcx>>)
InlineAsmRegClass::X86(X86InlineAsmRegClass::zmm_reg) => "v",
InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg) => "^Yk",
InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => "r",
InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::reg) => "r",
InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::wreg) => "w",
InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => {
bug!("LLVM backend does not support SPIR-V")
}
Expand Down Expand Up @@ -661,6 +664,7 @@ fn modifier_to_llvm(
},
InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg) => None,
InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => None,
InlineAsmRegClass::Bpf(_) => None,
InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => {
bug!("LLVM backend does not support SPIR-V")
}
Expand Down Expand Up @@ -708,6 +712,8 @@ fn dummy_output_type(cx: &CodegenCx<'ll, 'tcx>, reg: InlineAsmRegClass) -> &'ll
| InlineAsmRegClass::X86(X86InlineAsmRegClass::zmm_reg) => cx.type_f32(),
InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg) => cx.type_i16(),
InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => cx.type_i32(),
InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::reg) => cx.type_i64(),
InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::wreg) => cx.type_i32(),
InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => {
bug!("LLVM backend does not support SPIR-V")
}
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_codegen_ssa/src/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -989,6 +989,7 @@ fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
LinkerFlavor::Msvc => "link.exe",
LinkerFlavor::Lld(_) => "lld",
LinkerFlavor::PtxLinker => "rust-ptx-linker",
LinkerFlavor::BpfLinker => "bpf-linker",
}),
flavor,
)),
Expand Down
129 changes: 129 additions & 0 deletions compiler/rustc_codegen_ssa/src/back/linker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ impl LinkerInfo {
LinkerFlavor::PtxLinker => {
Box::new(PtxLinker { cmd, sess, info: self }) as Box<dyn Linker>
}

LinkerFlavor::BpfLinker => {
Box::new(BpfLinker { cmd, sess, info: self }) as Box<dyn Linker>
}
}
}
}
Expand Down Expand Up @@ -1431,3 +1435,128 @@ impl<'a> Linker for PtxLinker<'a> {

fn linker_plugin_lto(&mut self) {}
}

pub struct BpfLinker<'a> {
cmd: Command,
sess: &'a Session,
info: &'a LinkerInfo,
}

impl<'a> Linker for BpfLinker<'a> {
fn cmd(&mut self) -> &mut Command {
&mut self.cmd
}

fn set_output_kind(&mut self, _output_kind: LinkOutputKind, _out_filename: &Path) {}

fn link_rlib(&mut self, path: &Path) {
self.cmd.arg(path);
}

fn link_whole_rlib(&mut self, path: &Path) {
self.cmd.arg(path);
}

fn include_path(&mut self, path: &Path) {
self.cmd.arg("-L").arg(path);
}

fn debuginfo(&mut self, _strip: Strip) {
self.cmd.arg("--debug");
}

fn add_object(&mut self, path: &Path) {
self.cmd.arg(path);
}

fn optimize(&mut self) {
self.cmd.arg(match self.sess.opts.optimize {
OptLevel::No => "-O0",
OptLevel::Less => "-O1",
OptLevel::Default => "-O2",
OptLevel::Aggressive => "-O3",
OptLevel::Size => "-Os",
OptLevel::SizeMin => "-Oz",
});
}

fn output_filename(&mut self, path: &Path) {
self.cmd.arg("-o").arg(path);
}

fn finalize(&mut self) {
self.cmd.arg("--cpu").arg(match self.sess.opts.cg.target_cpu {
Some(ref s) => s,
None => &self.sess.target.options.cpu,
});
self.cmd.arg("--cpu-features").arg(match &self.sess.opts.cg.target_feature {
feat if !feat.is_empty() => feat,
_ => &self.sess.target.options.features,
});
}

fn link_dylib(&mut self, _lib: Symbol, _verbatim: bool, _as_needed: bool) {
panic!("external dylibs not supported")
}

fn link_rust_dylib(&mut self, _lib: Symbol, _path: &Path) {
panic!("external dylibs not supported")
}

fn link_staticlib(&mut self, _lib: Symbol, _verbatim: bool) {
panic!("staticlibs not supported")
}

fn link_whole_staticlib(&mut self, _lib: Symbol, _verbatim: bool, _search_path: &[PathBuf]) {
panic!("staticlibs not supported")
}

fn framework_path(&mut self, _path: &Path) {
panic!("frameworks not supported")
}

fn link_framework(&mut self, _framework: Symbol, _as_needed: bool) {
panic!("frameworks not supported")
}

fn full_relro(&mut self) {}

fn partial_relro(&mut self) {}

fn no_relro(&mut self) {}

fn gc_sections(&mut self, _keep_metadata: bool) {}

fn no_gc_sections(&mut self) {}

fn pgo_gen(&mut self) {}

fn no_crt_objects(&mut self) {}

fn no_default_libraries(&mut self) {}

fn control_flow_guard(&mut self) {}

fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType) {
let path = tmpdir.join("symbols");
let res: io::Result<()> = try {
let mut f = BufWriter::new(File::create(&path)?);
for sym in self.info.exports[&crate_type].iter() {
writeln!(f, "{}", sym)?;
}
};
if let Err(e) = res {
self.sess.fatal(&format!("failed to write symbols file: {}", e));
} else {
self.cmd.arg("--export-symbols").arg(&path);
}
}

fn subsystem(&mut self, _subsystem: &str) {}

fn group_start(&mut self) {}

fn group_end(&mut self) {}

fn linker_plugin_lto(&mut self) {}
}
4 changes: 4 additions & 0 deletions compiler/rustc_codegen_ssa/src/target_features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,8 @@ const WASM_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
("nontrapping-fptoint", Some(sym::wasm_target_feature)),
];

const BPF_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[("alu32", Some(sym::bpf_target_feature))];

/// When rustdoc is running, provide a list of all known features so that all their respective
/// primitives may be documented.
///
Expand All @@ -224,6 +226,7 @@ pub fn all_known_features() -> impl Iterator<Item = (&'static str, Option<Symbol
.chain(MIPS_ALLOWED_FEATURES.iter())
.chain(RISCV_ALLOWED_FEATURES.iter())
.chain(WASM_ALLOWED_FEATURES.iter())
.chain(BPF_ALLOWED_FEATURES.iter())
.cloned()
}

Expand All @@ -237,6 +240,7 @@ pub fn supported_target_features(sess: &Session) -> &'static [(&'static str, Opt
"powerpc" | "powerpc64" => POWERPC_ALLOWED_FEATURES,
"riscv32" | "riscv64" => RISCV_ALLOWED_FEATURES,
"wasm32" | "wasm64" => WASM_ALLOWED_FEATURES,
"bpf" => BPF_ALLOWED_FEATURES,
_ => &[],
}
}
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_feature/src/active.rs
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ declare_features! (
(active, f16c_target_feature, "1.36.0", Some(44839), None),
(active, riscv_target_feature, "1.45.0", Some(44839), None),
(active, ermsb_target_feature, "1.49.0", Some(44839), None),
(active, bpf_target_feature, "1.54.0", Some(44839), None),

// -------------------------------------------------------------------------
// feature-group-end: actual feature gates (target features)
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_llvm/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ fn main() {
"nvptx",
"hexagon",
"riscv",
"bpf",
];

let required_components = &[
Expand Down
8 changes: 8 additions & 0 deletions compiler/rustc_llvm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,4 +167,12 @@ pub fn initialize_available_targets() {
LLVMInitializeWebAssemblyAsmPrinter,
LLVMInitializeWebAssemblyAsmParser
);
init_target!(
llvm_component = "bpf",
LLVMInitializeBPFTargetInfo,
LLVMInitializeBPFTarget,
LLVMInitializeBPFTargetMC,
LLVMInitializeBPFAsmPrinter,
LLVMInitializeBPFAsmParser
);
}
2 changes: 2 additions & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,7 @@ symbols! {
box_free,
box_patterns,
box_syntax,
bpf_target_feature,
braced_empty_structs,
branch,
breakpoint,
Expand Down Expand Up @@ -1332,6 +1333,7 @@ symbols! {
wrapping_add,
wrapping_mul,
wrapping_sub,
wreg,
write_bytes,
xmm_reg,
ymm_reg,
Expand Down
31 changes: 31 additions & 0 deletions compiler/rustc_target/src/abi/call/bpf.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// see https://github.com/llvm/llvm-project/blob/main/llvm/lib/Target/BPF/BPFCallingConv.td
use crate::abi::call::{ArgAbi, FnAbi};

fn classify_ret<Ty>(ret: &mut ArgAbi<'_, Ty>) {
if ret.layout.is_aggregate() || ret.layout.size.bits() > 64 {
ret.make_indirect();
} else {
ret.extend_integer_width_to(32);
}
}

fn classify_arg<Ty>(arg: &mut ArgAbi<'_, Ty>) {
if arg.layout.is_aggregate() || arg.layout.size.bits() > 64 {
arg.make_indirect();
} else {
arg.extend_integer_width_to(32);
}
}

pub fn compute_abi_info<Ty>(fn_abi: &mut FnAbi<'_, Ty>) {
if !fn_abi.ret.is_ignore() {
classify_ret(&mut fn_abi.ret);
}

for arg in &mut fn_abi.args {
if arg.is_ignore() {
continue;
}
classify_arg(arg);
}
}
2 changes: 2 additions & 0 deletions compiler/rustc_target/src/abi/call/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ mod aarch64;
mod amdgpu;
mod arm;
mod avr;
mod bpf;
mod hexagon;
mod mips;
mod mips64;
Expand Down Expand Up @@ -654,6 +655,7 @@ impl<'a, Ty> FnAbi<'a, Ty> {
}
}
"asmjs" => wasm::compute_c_abi_info(cx, self),
"bpf" => bpf::compute_abi_info(self),
a => return Err(format!("unrecognized arch \"{}\" in target specification", a)),
}

Expand Down
Loading