summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_smir/src/stable_mir
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 02:49:50 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 02:49:50 +0000
commit9835e2ae736235810b4ea1c162ca5e65c547e770 (patch)
tree3fcebf40ed70e581d776a8a4c65923e8ec20e026 /compiler/rustc_smir/src/stable_mir
parentReleasing progress-linux version 1.70.0+dfsg2-1~progress7.99u1. (diff)
downloadrustc-9835e2ae736235810b4ea1c162ca5e65c547e770.tar.xz
rustc-9835e2ae736235810b4ea1c162ca5e65c547e770.zip
Merging upstream version 1.71.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_smir/src/stable_mir')
-rw-r--r--compiler/rustc_smir/src/stable_mir/mir/body.rs83
-rw-r--r--compiler/rustc_smir/src/stable_mir/mod.rs66
-rw-r--r--compiler/rustc_smir/src/stable_mir/ty.rs15
3 files changed, 153 insertions, 11 deletions
diff --git a/compiler/rustc_smir/src/stable_mir/mir/body.rs b/compiler/rustc_smir/src/stable_mir/mir/body.rs
index c504065c9..6328c35aa 100644
--- a/compiler/rustc_smir/src/stable_mir/mir/body.rs
+++ b/compiler/rustc_smir/src/stable_mir/mir/body.rs
@@ -1,6 +1,9 @@
+use crate::stable_mir::ty::Ty;
+
#[derive(Clone, Debug)]
pub struct Body {
pub blocks: Vec<BasicBlock>,
+ pub locals: Vec<Ty>,
}
#[derive(Clone, Debug)]
@@ -26,30 +29,99 @@ pub enum Terminator {
Drop {
place: Place,
target: usize,
- unwind: Option<usize>,
+ unwind: UnwindAction,
},
Call {
func: Operand,
args: Vec<Operand>,
destination: Place,
target: Option<usize>,
- cleanup: Option<usize>,
+ unwind: UnwindAction,
},
Assert {
cond: Operand,
expected: bool,
- msg: String,
+ msg: AssertMessage,
target: usize,
- cleanup: Option<usize>,
+ unwind: UnwindAction,
},
+ GeneratorDrop,
+}
+
+#[derive(Clone, Debug)]
+pub enum UnwindAction {
+ Continue,
+ Unreachable,
+ Terminate,
+ Cleanup(usize),
+}
+
+#[derive(Clone, Debug)]
+pub enum AssertMessage {
+ BoundsCheck { len: Operand, index: Operand },
+ Overflow(BinOp, Operand, Operand),
+ OverflowNeg(Operand),
+ DivisionByZero(Operand),
+ RemainderByZero(Operand),
+ ResumedAfterReturn(GeneratorKind),
+ ResumedAfterPanic(GeneratorKind),
+ MisalignedPointerDereference { required: Operand, found: Operand },
+}
+
+#[derive(Clone, Debug)]
+pub enum BinOp {
+ Add,
+ Sub,
+ Mul,
+ Div,
+ Rem,
+ BitXor,
+ BitAnd,
+ BitOr,
+ Shl,
+ Shr,
+ Eq,
+ Lt,
+ Le,
+ Ne,
+ Ge,
+ Gt,
+ Offset,
+}
+
+#[derive(Clone, Debug)]
+pub enum UnOp {
+ Not,
+ Neg,
+}
+
+#[derive(Clone, Debug)]
+pub enum GeneratorKind {
+ Async(AsyncGeneratorKind),
+ Gen,
+}
+
+#[derive(Clone, Debug)]
+pub enum AsyncGeneratorKind {
+ Block,
+ Closure,
+ Fn,
}
#[derive(Clone, Debug)]
pub enum Statement {
- Assign(Place, Operand),
+ Assign(Place, Rvalue),
Nop,
}
+// FIXME this is incomplete
+#[derive(Clone, Debug)]
+pub enum Rvalue {
+ Use(Operand),
+ CheckedBinaryOp(BinOp, Operand, Operand),
+ UnaryOp(UnOp, Operand),
+}
+
#[derive(Clone, Debug)]
pub enum Operand {
Copy(Place),
@@ -60,6 +132,7 @@ pub enum Operand {
#[derive(Clone, Debug)]
pub struct Place {
pub local: usize,
+ pub projection: String,
}
#[derive(Clone, Debug)]
diff --git a/compiler/rustc_smir/src/stable_mir/mod.rs b/compiler/rustc_smir/src/stable_mir/mod.rs
index 1d2efb5ea..612777b9c 100644
--- a/compiler/rustc_smir/src/stable_mir/mod.rs
+++ b/compiler/rustc_smir/src/stable_mir/mod.rs
@@ -11,7 +11,14 @@
//! There shouldn't be any direct references to internal compiler constructs in this module.
//! If you need an internal construct, consider using `rustc_internal` or `rustc_smir`.
+use std::cell::Cell;
+
+use crate::rustc_smir::Tables;
+
+use self::ty::{Ty, TyKind};
+
pub mod mir;
+pub mod ty;
/// Use String for now but we should replace it.
pub type Symbol = String;
@@ -41,7 +48,7 @@ pub struct CrateItem(pub(crate) DefId);
impl CrateItem {
pub fn body(&self) -> mir::Body {
- crate::rustc_smir::mir_body(self)
+ with(|cx| cx.mir_body(self))
}
}
@@ -49,25 +56,72 @@ impl CrateItem {
/// crate defines that. This is usually `main`, but could be
/// `start` if the crate is a no-std crate.
pub fn entry_fn() -> Option<CrateItem> {
- crate::rustc_smir::entry_fn()
+ with(|cx| cx.entry_fn())
}
/// Access to the local crate.
pub fn local_crate() -> Crate {
- crate::rustc_smir::local_crate()
+ with(|cx| cx.local_crate())
}
/// Try to find a crate with the given name.
pub fn find_crate(name: &str) -> Option<Crate> {
- crate::rustc_smir::find_crate(name)
+ with(|cx| cx.find_crate(name))
}
/// Try to find a crate with the given name.
pub fn external_crates() -> Vec<Crate> {
- crate::rustc_smir::external_crates()
+ with(|cx| cx.external_crates())
}
/// Retrieve all items in the local crate that have a MIR associated with them.
pub fn all_local_items() -> CrateItems {
- crate::rustc_smir::all_local_items()
+ with(|cx| cx.all_local_items())
+}
+
+pub trait Context {
+ fn entry_fn(&mut self) -> Option<CrateItem>;
+ /// Retrieve all items of the local crate that have a MIR associated with them.
+ fn all_local_items(&mut self) -> CrateItems;
+ fn mir_body(&mut self, item: &CrateItem) -> mir::Body;
+ /// Get information about the local crate.
+ fn local_crate(&self) -> Crate;
+ /// Retrieve a list of all external crates.
+ fn external_crates(&self) -> Vec<Crate>;
+
+ /// Find a crate with the given name.
+ fn find_crate(&self, name: &str) -> Option<Crate>;
+
+ /// Obtain the representation of a type.
+ fn ty_kind(&mut self, ty: Ty) -> TyKind;
+
+ /// HACK: Until we have fully stable consumers, we need an escape hatch
+ /// to get `DefId`s out of `CrateItem`s.
+ fn rustc_tables(&mut self, f: &mut dyn FnMut(&mut Tables<'_>));
+}
+
+thread_local! {
+ /// A thread local variable that stores a pointer to the tables mapping between TyCtxt
+ /// datastructures and stable MIR datastructures.
+ static TLV: Cell<*mut ()> = const { Cell::new(std::ptr::null_mut()) };
+}
+
+pub fn run(mut context: impl Context, f: impl FnOnce()) {
+ assert!(TLV.get().is_null());
+ fn g<'a>(mut context: &mut (dyn Context + 'a), f: impl FnOnce()) {
+ TLV.set(&mut context as *mut &mut _ as _);
+ f();
+ TLV.replace(std::ptr::null_mut());
+ }
+ g(&mut context, f);
+}
+
+/// Loads the current context and calls a function with it.
+/// Do not nest these, as that will ICE.
+pub(crate) fn with<R>(f: impl FnOnce(&mut dyn Context) -> R) -> R {
+ let ptr = TLV.replace(std::ptr::null_mut()) as *mut &mut dyn Context;
+ assert!(!ptr.is_null());
+ let ret = f(unsafe { *ptr });
+ TLV.set(ptr as _);
+ ret
}
diff --git a/compiler/rustc_smir/src/stable_mir/ty.rs b/compiler/rustc_smir/src/stable_mir/ty.rs
new file mode 100644
index 000000000..f27801b0f
--- /dev/null
+++ b/compiler/rustc_smir/src/stable_mir/ty.rs
@@ -0,0 +1,15 @@
+use super::with;
+
+#[derive(Copy, Clone, Debug)]
+pub struct Ty(pub usize);
+
+impl Ty {
+ pub fn kind(&self) -> TyKind {
+ with(|context| context.ty_kind(*self))
+ }
+}
+
+pub enum TyKind {
+ Bool,
+ Tuple(Vec<Ty>),
+}