mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
[rust] enter_ssa uses new diagnostic type
This commit is contained in:
Generated
+1
@@ -549,6 +549,7 @@ name = "forget_ssa"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"forget_diagnostics",
|
||||
"forget_hir",
|
||||
"forget_utils",
|
||||
"indexmap 2.0.0",
|
||||
|
||||
@@ -40,6 +40,32 @@ impl<'a> Instruction<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn try_each_identifier_store<F, E>(&mut self, mut f: F) -> Result<(), E>
|
||||
where
|
||||
F: FnMut(&mut LValue<'a>) -> Result<(), E>,
|
||||
{
|
||||
match &mut self.value {
|
||||
InstructionValue::DeclareContext(instr) => {
|
||||
f(&mut instr.lvalue)?;
|
||||
}
|
||||
InstructionValue::DeclareLocal(instr) => {
|
||||
f(&mut instr.lvalue)?;
|
||||
}
|
||||
InstructionValue::StoreLocal(instr) => {
|
||||
f(&mut instr.lvalue)?;
|
||||
}
|
||||
InstructionValue::Array(_)
|
||||
| InstructionValue::Binary(_)
|
||||
| InstructionValue::LoadContext(_)
|
||||
| InstructionValue::LoadGlobal(_)
|
||||
| InstructionValue::LoadLocal(_)
|
||||
| InstructionValue::Primitive(_)
|
||||
| InstructionValue::Function(_)
|
||||
| InstructionValue::Tombstone => {}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn each_identifier_load<F>(&mut self, mut f: F) -> ()
|
||||
where
|
||||
F: FnMut(&mut IdentifierOperand<'a>) -> (),
|
||||
|
||||
@@ -15,6 +15,7 @@ repository.workspace = true
|
||||
[dependencies]
|
||||
forget_hir = { workspace = true }
|
||||
forget_utils = { workspace = true }
|
||||
forget_diagnostics = { workspace = true }
|
||||
bumpalo = { workspace = true }
|
||||
indexmap = { workspace = true }
|
||||
miette = { workspace = true }
|
||||
|
||||
@@ -2,18 +2,14 @@ use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
|
||||
use bumpalo::collections::{CollectIn, Vec};
|
||||
use forget_diagnostics::{invariant, Diagnostic};
|
||||
use forget_hir::{
|
||||
BasicBlock, BlockId, Blocks, Environment, Function, Identifier, IdentifierData, IdentifierId,
|
||||
IdentifierOperand, Instruction, InstructionValue, LValue, MutableRange, Phi,
|
||||
};
|
||||
use indexmap::{IndexMap, IndexSet};
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
#[error("Error constructing SSA form")]
|
||||
pub struct SSAError;
|
||||
|
||||
pub fn enter_ssa<'a>(env: &Environment<'a>, fun: &mut Function<'a>) -> Result<(), SSAError> {
|
||||
pub fn enter_ssa<'a>(env: &Environment<'a>, fun: &mut Function<'a>) -> Result<(), Diagnostic> {
|
||||
assert!(fun.context.is_empty());
|
||||
enter_ssa_impl(env, fun, None)
|
||||
}
|
||||
@@ -22,7 +18,7 @@ pub fn enter_ssa_impl<'a>(
|
||||
env: &Environment<'a>,
|
||||
fun: &mut Function<'a>,
|
||||
context_defs: Option<IndexMap<IdentifierId, Identifier<'a>>>,
|
||||
) -> Result<(), SSAError> {
|
||||
) -> Result<(), Diagnostic> {
|
||||
let blocks = &fun.body.blocks;
|
||||
let instructions = &mut fun.body.instructions;
|
||||
let mut builder = Builder::new(env, fun.body.entry, blocks);
|
||||
@@ -48,11 +44,11 @@ fn visit_instructions<'a, 'e, 'f>(
|
||||
env: &Environment<'a>,
|
||||
builder: &mut Builder<'a, 'e, 'f>,
|
||||
instructions: &mut Vec<'a, Instruction<'a>>,
|
||||
) -> Result<(), SSAError> {
|
||||
) -> Result<(), Diagnostic> {
|
||||
builder.each_block(|block, builder| {
|
||||
for instr_ix in &block.instructions {
|
||||
let instr = &mut instructions[usize::from(*instr_ix)];
|
||||
instr.each_identifier_store(|store| builder.visit_store(store));
|
||||
instr.try_each_identifier_store(|store| builder.visit_store(store))?;
|
||||
instr.each_identifier_load(|load| builder.visit_load(load));
|
||||
|
||||
if let InstructionValue::Function(fun) = &mut instr.value {
|
||||
@@ -143,24 +139,27 @@ impl<'a, 'e, 'f> Builder<'a, 'e, 'f> {
|
||||
self.env.next_identifier_id()
|
||||
}
|
||||
|
||||
fn visit_store(&mut self, lvalue: &mut LValue<'a>) -> () {
|
||||
fn visit_store(&mut self, lvalue: &mut LValue<'a>) -> Result<(), Diagnostic> {
|
||||
let old_identifier = &lvalue.identifier.identifier;
|
||||
// TODO: use Result (?)
|
||||
assert!(
|
||||
!self.unknown.contains(&old_identifier.id),
|
||||
"EnterSSA: Expected identifier to be defined before being used. Identifier {old_identifier:?} is undefined."
|
||||
);
|
||||
invariant(!self.unknown.contains(&old_identifier.id), || {
|
||||
Diagnostic::invariant(
|
||||
"EnterSSA: Expected identifier to be defined before being used",
|
||||
None,
|
||||
)
|
||||
})?;
|
||||
|
||||
if self.context.contains(&old_identifier.id) {
|
||||
let new_identifier = self.get_id_at(self.current, old_identifier);
|
||||
lvalue.identifier.identifier = new_identifier;
|
||||
return;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let new_identifier = self.make_identifier(old_identifier);
|
||||
let state = self.states.get_mut(&self.current).unwrap();
|
||||
state.defs.insert(old_identifier.id, new_identifier.clone());
|
||||
lvalue.identifier.identifier = new_identifier;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn visit_param(&mut self, param: &mut IdentifierOperand<'a>) -> () {
|
||||
@@ -258,9 +257,9 @@ impl<'a, 'e, 'f> Builder<'a, 'e, 'f> {
|
||||
}
|
||||
}
|
||||
|
||||
fn each_block<F>(&mut self, mut f: F) -> Result<(), SSAError>
|
||||
fn each_block<F>(&mut self, mut f: F) -> Result<(), Diagnostic>
|
||||
where
|
||||
F: FnMut(&BasicBlock<'a>, &mut Self) -> Result<(), SSAError>,
|
||||
F: FnMut(&BasicBlock<'a>, &mut Self) -> Result<(), Diagnostic>,
|
||||
{
|
||||
let mut visited = IndexSet::new();
|
||||
let block_ids: Vec<_> = self.blocks.keys().cloned().collect_in(self.env.allocator);
|
||||
|
||||
Reference in New Issue
Block a user