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_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 BPFCallingConv.td
alessandrod marked this conversation as resolved.
Show resolved Hide resolved
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(64);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIU when alu32 feature is enabled, the 32-bit values are expected to be passed in the w* registers, which I think means that we want to conditionally extend to 32 bits here when that feature is enabled.

Perhaps you could always extend to just 32 bits and let LLVM handle extending to 64 bits if alu32 is not enabled?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes good point, I've done that.

}
}

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(64);
}
}

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