properly splatting bytes in emit_small_memset
This commit is contained in:
@@ -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" }
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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]
|
||||
|
||||
Reference in New Issue
Block a user