Skip to content

Commit e4c27ae

Browse files
authored
pulley: Add macro instructions for function prologue/epilogue (bytecodealliance#9864)
* pulley: Add macro instructions for function prologue/epilogue This commit adds two new instructions to Pulley to combine the operations of setting up a frame, allocating stack, and saving clobbered registers. This is all combined into a single instruction which is relatively large but is much smaller than each of these individual operations exploded out. This is a size win on `spidermonkey.cwasm` by about 1M and locally in a small `fib.wat` test this is also a good speedup by reducing the number of instructions executed. * Review comments and update test expectations
1 parent 4178766 commit e4c27ae

File tree

14 files changed

+391
-231
lines changed

14 files changed

+391
-231
lines changed

cranelift/bitset/src/scalar.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -556,14 +556,17 @@ pub trait ScalarBitSetStorage:
556556
macro_rules! impl_storage {
557557
( $int:ty ) => {
558558
impl ScalarBitSetStorage for $int {
559+
#[inline]
559560
fn leading_zeros(self) -> u8 {
560561
u8::try_from(self.leading_zeros()).unwrap()
561562
}
562563

564+
#[inline]
563565
fn trailing_zeros(self) -> u8 {
564566
u8::try_from(self.trailing_zeros()).unwrap()
565567
}
566568

569+
#[inline]
567570
fn count_ones(self) -> u8 {
568571
u8::try_from(self.count_ones()).unwrap()
569572
}

cranelift/codegen/meta/src/pulley.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,10 @@ impl Inst<'_> {
6969
Operand::Binop { dst, src1, src2 }
7070
}
7171
("dst", ty) => Operand::Writable { name, ty },
72+
(name, "RegSet < XReg >") => Operand::Normal {
73+
name,
74+
ty: "XRegSet",
75+
},
7276
(name, ty) => Operand::Normal { name, ty },
7377
})
7478
.chain(if self.name.contains("Trap") {
@@ -120,10 +124,17 @@ pub fn generate_rust(filename: &str, out_dir: &Path) -> Result<(), Error> {
120124
if i > 0 {
121125
format_string.push_str(",");
122126
}
127+
128+
if ty == "XRegSet" {
129+
format_string.push_str(" {");
130+
format_string.push_str(name);
131+
format_string.push_str(":?}");
132+
continue;
133+
}
134+
123135
format_string.push_str(" {");
124136
format_string.push_str(name);
125137
format_string.push_str("}");
126-
127138
if ty.contains("Reg") {
128139
if name == "dst" {
129140
locals.push_str(&format!("let {name} = reg_name(*{name}.to_reg());\n"));
@@ -176,6 +187,13 @@ pub fn generate_rust(filename: &str, out_dir: &Path) -> Result<(), Error> {
176187
let mut defs = Vec::new();
177188
for op in inst.operands() {
178189
match op {
190+
// `{Push,Pop}Frame{Save,Restore}` doesn't participate in
191+
// register allocation.
192+
Operand::Normal {
193+
name: _,
194+
ty: "XRegSet",
195+
} if *name == "PushFrameSave" || *name == "PopFrameRestore" => {}
196+
179197
Operand::Normal { name, ty } => {
180198
if ty.contains("Reg") {
181199
uses.push(name);

0 commit comments

Comments
 (0)