properly splatting bytes in emit_small_memset

This commit is contained in:
MaxGraey
2021-05-13 22:02:17 +03:00
614 changed files with 40658 additions and 7141 deletions

View File

@@ -1,7 +1,7 @@
[package]
authors = ["The Cranelift Project Developers"]
name = "cranelift-frontend"
version = "0.72.0"
version = "0.73.0"
description = "Cranelift IR builder helper"
license = "Apache-2.0 WITH LLVM-exception"
documentation = "https://docs.rs/cranelift-frontend"
@@ -11,8 +11,8 @@ readme = "README.md"
edition = "2018"
[dependencies]
cranelift-codegen = { path = "../codegen", version = "0.72.0", default-features = false }
target-lexicon = "0.11"
cranelift-codegen = { path = "../codegen", version = "0.73.0", default-features = false }
target-lexicon = "0.12"
log = { version = "0.4.6", default-features = false }
hashbrown = { version = "0.9.1", optional = true }
smallvec = { version = "1.6.1" }

View File

@@ -640,6 +640,7 @@ impl<'a> FunctionBuilder<'a> {
dest_align: u8,
src_align: u8,
non_overlapping: bool,
mut flags: MemFlags,
) {
// Currently the result of guess work, not actual profiling.
const THRESHOLD: u64 = 4;
@@ -676,7 +677,6 @@ impl<'a> FunctionBuilder<'a> {
return;
}
let mut flags = MemFlags::new();
flags.set_aligned();
// Load all of the memory first. This is necessary in case `dest` overlaps.
@@ -732,6 +732,7 @@ impl<'a> FunctionBuilder<'a> {
ch: u8,
size: u64,
buffer_align: u8,
mut flags: MemFlags,
) {
// Currently the result of guess work, not actual profiling.
const THRESHOLD: u64 = 4;
@@ -763,7 +764,6 @@ impl<'a> FunctionBuilder<'a> {
let size = self.ins().iconst(config.pointer_type(), size as i64);
self.call_memset(config, buffer, ch, size);
} else {
let mut flags = MemFlags::new();
flags.set_aligned();
let ch = u64::from(ch);
@@ -851,7 +851,9 @@ mod tests {
use alloc::string::ToString;
use cranelift_codegen::entity::EntityRef;
use cranelift_codegen::ir::types::*;
use cranelift_codegen::ir::{AbiParam, ExternalName, Function, InstBuilder, Signature};
use cranelift_codegen::ir::{
AbiParam, ExternalName, Function, InstBuilder, MemFlags, Signature,
};
use cranelift_codegen::isa::CallConv;
use cranelift_codegen::settings;
use cranelift_codegen::verifier::verify_function;
@@ -1063,7 +1065,16 @@ block0:
let src = builder.use_var(x);
let dest = builder.use_var(y);
let size = 8;
builder.emit_small_memory_copy(target.frontend_config(), dest, src, size, 8, 8, true);
builder.emit_small_memory_copy(
target.frontend_config(),
dest,
src,
size,
8,
8,
true,
MemFlags::new(),
);
builder.ins().return_(&[dest]);
builder.seal_all_blocks();
@@ -1121,7 +1132,16 @@ block0:
let src = builder.use_var(x);
let dest = builder.use_var(y);
let size = 8192;
builder.emit_small_memory_copy(target.frontend_config(), dest, src, size, 8, 8, true);
builder.emit_small_memory_copy(
target.frontend_config(),
dest,
src,
size,
8,
8,
true,
MemFlags::new(),
);
builder.ins().return_(&[dest]);
builder.seal_all_blocks();
@@ -1179,7 +1199,7 @@ block0:
let dest = builder.use_var(y);
let size = 8;
builder.emit_small_memset(target.frontend_config(), dest, 1, size, 8);
builder.emit_small_memset(target.frontend_config(), dest, 1, size, 8, MemFlags::new());
builder.ins().return_(&[dest]);
builder.seal_all_blocks();
@@ -1232,7 +1252,7 @@ block0:
let dest = builder.use_var(y);
let size = 8192;
builder.emit_small_memset(target.frontend_config(), dest, 1, size, 8);
builder.emit_small_memset(target.frontend_config(), dest, 1, size, 8, MemFlags::new());
builder.ins().return_(&[dest]);
builder.seal_all_blocks();

View File

@@ -5,7 +5,7 @@
//! In: Jhala R., De Bosschere K. (eds) Compiler Construction. CC 2013.
//! Lecture Notes in Computer Science, vol 7791. Springer, Berlin, Heidelberg
//!
//! https://link.springer.com/content/pdf/10.1007/978-3-642-37051-9_6.pdf
//! <https://link.springer.com/content/pdf/10.1007/978-3-642-37051-9_6.pdf>
use crate::Variable;
use alloc::vec::Vec;

View File

@@ -273,6 +273,7 @@ impl Switch {
.icmp_imm(IntCC::UnsignedGreaterThan, discr, u32::max_value() as i64);
bx.ins().brnz(bigger_than_u32, otherwise, &[]);
bx.ins().jump(new_block, &[]);
bx.seal_block(new_block);
bx.switch_to_block(new_block);
// Cast to u32, as br_table is not implemented for integers bigger than 32bits.
@@ -542,38 +543,47 @@ block4:
#[test]
fn switch_seal_generated_blocks() {
let keys = [0, 1, 2, 10, 11, 12, 20, 30, 40, 50];
let cases = &[vec![0, 1, 2], vec![0, 1, 2, 10, 11, 12, 20, 30, 40, 50]];
let mut func = Function::new();
let mut builder_ctx = FunctionBuilderContext::new();
let mut builder = FunctionBuilder::new(&mut func, &mut builder_ctx);
let root_block = builder.create_block();
let default_block = builder.create_block();
let mut switch = Switch::new();
let case_blocks = keys
.iter()
.map(|key| {
let block = builder.create_block();
switch.set_entry(*key, block);
block
})
.collect::<Vec<_>>();
builder.seal_block(root_block);
builder.switch_to_block(root_block);
let val = builder.ins().iconst(types::I32, 1);
switch.emit(&mut builder, val, default_block);
for &block in case_blocks.iter().chain(std::iter::once(&default_block)) {
builder.seal_block(block);
builder.switch_to_block(block);
builder.ins().return_(&[]);
for case in cases {
for typ in &[types::I8, types::I16, types::I32, types::I64, types::I128] {
eprintln!("Testing {:?} with keys: {:?}", typ, case);
do_case(case, *typ);
}
}
builder.finalize(); // Will panic if some blocks are not sealed
fn do_case(keys: &[u128], typ: Type) {
let mut func = Function::new();
let mut builder_ctx = FunctionBuilderContext::new();
let mut builder = FunctionBuilder::new(&mut func, &mut builder_ctx);
let root_block = builder.create_block();
let default_block = builder.create_block();
let mut switch = Switch::new();
let case_blocks = keys
.iter()
.map(|key| {
let block = builder.create_block();
switch.set_entry(*key, block);
block
})
.collect::<Vec<_>>();
builder.seal_block(root_block);
builder.switch_to_block(root_block);
let val = builder.ins().iconst(typ, 1);
switch.emit(&mut builder, val, default_block);
for &block in case_blocks.iter().chain(std::iter::once(&default_block)) {
builder.seal_block(block);
builder.switch_to_block(block);
builder.ins().return_(&[]);
}
builder.finalize(); // Will panic if some blocks are not sealed
}
}
#[test]