Skip to content

Commit

Permalink
Reduce data section usage by attempting to store smaller offsets when…
Browse files Browse the repository at this point in the history
… compiling `get_local_var` (FuelLabs#4430)

## Description
The idea is to store the word offset to the the `local` (from
`base_reg`) if the byte offset is too large and requires that it goes
into the data section. We can then multiply the word offset by 8 using
`MULI` to get the byte offset.

## Checklist

- [ ] I have linked to any relevant issues.
- [ ] I have commented my code, particularly in hard-to-understand
areas.
- [ ] I have updated the documentation where relevant (API docs, the
reference, and the Sway book).
- [ ] I have added tests that prove my fix is effective or that my
feature works.
- [ ] I have added (or requested a maintainer to add) the necessary
`Breaking*` or `New Feature` labels where relevant.
- [ ] I have done my best to ensure that my PR adheres to [the Fuel Labs
Code Review
Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md).
- [ ] I have requested a review from the relevant team or maintainers.

---------

Co-authored-by: João Matos <[email protected]>
  • Loading branch information
mohammadfawaz and tritao authored Apr 12, 2023
1 parent 800089e commit ed0f800
Showing 1 changed file with 44 additions and 9 deletions.
53 changes: 44 additions & 9 deletions sway-core/src/asm_generation/fuel/fuel_asm_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -843,20 +843,55 @@ impl<'ir> FuelAsmBuilder<'ir> {
let owning_span = self.md_mgr.val_to_span(self.context, *instr_val);
match self.ptr_map.get(local_var) {
Some(Storage::Stack(word_offs)) => {
let offset = word_offs * 8;
if offset == 0 {
if *word_offs == 0 {
self.reg_map
.insert(*instr_val, self.locals_base_reg().clone());
} else {
let instr_reg = self.reg_seqr.next();
let base_reg = self.locals_base_reg().clone();
self.immediate_to_reg(
offset,
instr_reg.clone(),
Some(&base_reg),
"get offset to local",
owning_span,
);
let byte_offs = *word_offs * 8;

// If the byte offset requires a data section entry, then convert the word
// offset to a register first (without any base). Then, multiply the result by
// 8 to get the byte offset. The result can then be manually added to
// `base_reg`.
//
// Otherwise, just convert the byte offset directly to a register.
if byte_offs > compiler_constants::EIGHTEEN_BITS {
self.immediate_to_reg(
*word_offs,
instr_reg.clone(),
None,
"get word offset to local from base",
owning_span.clone(),
);
self.cur_bytecode.push(Op {
opcode: Either::Left(VirtualOp::MULI(
instr_reg.clone(),
instr_reg.clone(),
VirtualImmediate12 { value: 8u16 },
)),
comment: "get byte offset to local from base".into(),
owning_span: owning_span.clone(),
});
self.cur_bytecode.push(Op {
opcode: Either::Left(VirtualOp::ADD(
instr_reg.clone(),
base_reg.clone(),
instr_reg.clone(),
)),
comment: "get absolute byte offset to local".into(),
owning_span,
});
} else {
self.immediate_to_reg(
byte_offs,
instr_reg.clone(),
Some(&base_reg),
"get offset to local",
owning_span,
);
}
self.reg_map.insert(*instr_val, instr_reg);
}
Ok(())
Expand Down

0 comments on commit ed0f800

Please sign in to comment.