Browse Source

isle: expand enums in ISLE (#3586)

* x64: expand FloatCC enum in ISLE
* isle: regenerate manifests
* isle: generate all enum fields in `clif.isle`

This expands the `gen_isle` function to write all of the immediate
`enum`s out explicitly in `clif.isle`. Non-`enum` immediates are still
`extern primitive`.

* Only compile `enum_values` with `rebuild-isle` feature
* Only compile `gen_enum_isle` with `rebuild-isle` feature
pull/3597/head
Andrew Brown 3 years ago
committed by GitHub
parent
commit
86611d3bbc
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 11
      cranelift/codegen/meta/src/cdsl/operands.rs
  2. 56
      cranelift/codegen/meta/src/gen_inst.rs
  3. 73
      cranelift/codegen/src/clif.isle
  4. 2
      cranelift/codegen/src/isa/aarch64/lower/isle/generated_code.manifest
  5. 2
      cranelift/codegen/src/isa/x64/lower/isle/generated_code.manifest

11
cranelift/codegen/meta/src/cdsl/operands.rs

@ -111,6 +111,17 @@ pub(crate) enum OperandKindFields {
TypeVar(TypeVar),
}
impl OperandKindFields {
/// Return the [EnumValues] for this field if it is an `enum`.
#[cfg(feature = "rebuild-isle")]
pub(crate) fn enum_values(&self) -> Option<&EnumValues> {
match self {
OperandKindFields::ImmEnum(map) => Some(map),
_ => None,
}
}
}
#[derive(Clone, Debug)]
pub(crate) struct OperandKind {
/// String representation of the Rust type mapping to this OperandKind.

56
cranelift/codegen/meta/src/gen_inst.rs

@ -1087,9 +1087,11 @@ fn gen_inst_builder(inst: &Instruction, format: &InstructionFormat, fmt: &mut Fo
#[cfg(feature = "rebuild-isle")]
fn gen_isle(formats: &[&InstructionFormat], instructions: &AllInstructions, fmt: &mut Formatter) {
use std::collections::BTreeSet;
use std::collections::{BTreeMap, BTreeSet};
use std::fmt::Write;
use crate::cdsl::formats::FormatField;
fmt.multi_line(
r#"
;; GENERATED BY `gen_isle`. DO NOT EDIT!!!
@ -1101,23 +1103,42 @@ fn gen_isle(formats: &[&InstructionFormat], instructions: &AllInstructions, fmt:
);
fmt.empty_line();
// Generate all the extern type declarations we need for various immediates.
fmt.line(";;;; Extern type declarations for immediates ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;");
fmt.empty_line();
let imm_tys: BTreeSet<_> = formats
// Collect and deduplicate the immediate types from the instruction fields.
let rust_name = |f: &FormatField| f.kind.rust_type.rsplit("::").next().unwrap();
let fields = |f: &FormatField| f.kind.fields.clone();
let immediate_types: BTreeMap<_, _> = formats
.iter()
.flat_map(|f| {
f.imm_fields
.iter()
.map(|i| i.kind.rust_type.rsplit("::").next().unwrap())
.map(|i| (rust_name(i), fields(i)))
.collect::<Vec<_>>()
})
.collect();
for ty in imm_tys {
// Separate the `enum` immediates (e.g., `FloatCC`) from other kinds of
// immediates.
let (enums, others): (BTreeMap<_, _>, BTreeMap<_, _>) = immediate_types
.iter()
.partition(|(_, field)| field.enum_values().is_some());
// Generate all the extern type declarations we need for the non-`enum`
// immediates.
fmt.line(";;;; Extern type declarations for immediates ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;");
fmt.empty_line();
for ty in others.keys() {
fmtln!(fmt, "(type {} (primitive {}))", ty, ty);
}
fmt.empty_line();
// Generate the `enum` immediates, expanding all of the available variants
// into ISLE.
for (name, field) in enums {
let field = field.enum_values().expect("only enums considered here");
let variants = field.values().cloned().collect();
gen_isle_enum(name, variants, fmt)
}
// Generate all of the value arrays we need for `InstructionData` as well as
// the constructors and extractors for them.
fmt.line(";;;; Value Arrays ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;");
@ -1323,6 +1344,27 @@ fn gen_isle(formats: &[&InstructionFormat], instructions: &AllInstructions, fmt:
}
}
/// Generate an `enum` immediate in ISLE.
#[cfg(feature = "rebuild-isle")]
fn gen_isle_enum(name: &str, mut variants: Vec<&str>, fmt: &mut Formatter) {
variants.sort();
let prefix = format!(";;;; Enumerated Immediate: {} ", name);
fmtln!(fmt, "{:;<80}", prefix);
fmt.empty_line();
fmtln!(fmt, "(type {} extern", name);
fmt.indent(|fmt| {
fmt.line("(enum");
fmt.indent(|fmt| {
for variant in variants {
fmtln!(fmt, "{}", variant);
}
});
fmt.line(")");
});
fmt.line(")");
fmt.empty_line();
}
/// Generate a Builder trait with methods for all instructions.
fn gen_builder(
instructions: &AllInstructions,

73
cranelift/codegen/src/clif.isle

@ -6,10 +6,8 @@
;;;; Extern type declarations for immediates ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(type AtomicRmwOp (primitive AtomicRmwOp))
(type Block (primitive Block))
(type Constant (primitive Constant))
(type FloatCC (primitive FloatCC))
(type FuncRef (primitive FuncRef))
(type GlobalValue (primitive GlobalValue))
(type Heap (primitive Heap))
@ -17,18 +15,85 @@
(type Ieee64 (primitive Ieee64))
(type Imm64 (primitive Imm64))
(type Immediate (primitive Immediate))
(type IntCC (primitive IntCC))
(type JumpTable (primitive JumpTable))
(type MemFlags (primitive MemFlags))
(type Offset32 (primitive Offset32))
(type SigRef (primitive SigRef))
(type StackSlot (primitive StackSlot))
(type Table (primitive Table))
(type TrapCode (primitive TrapCode))
(type Uimm32 (primitive Uimm32))
(type Uimm8 (primitive Uimm8))
(type bool (primitive bool))
;;;; Enumerated Immediate: AtomicRmwOp ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(type AtomicRmwOp extern
(enum
Add
And
Nand
Or
Smax
Smin
Sub
Umax
Umin
Xchg
Xor
)
)
;;;; Enumerated Immediate: FloatCC ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(type FloatCC extern
(enum
Equal
GreaterThan
GreaterThanOrEqual
LessThan
LessThanOrEqual
NotEqual
Ordered
OrderedNotEqual
Unordered
UnorderedOrEqual
UnorderedOrGreaterThan
UnorderedOrGreaterThanOrEqual
UnorderedOrLessThan
UnorderedOrLessThanOrEqual
)
)
;;;; Enumerated Immediate: IntCC ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(type IntCC extern
(enum
Equal
NotEqual
NotOverflow
Overflow
SignedGreaterThan
SignedGreaterThanOrEqual
SignedLessThan
SignedLessThanOrEqual
UnsignedGreaterThan
UnsignedGreaterThanOrEqual
UnsignedLessThan
UnsignedLessThanOrEqual
)
)
;;;; Enumerated Immediate: TrapCode ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(type TrapCode extern
(enum
HeapOutOfBounds
IntegerDivisionByZero
IntegerOverflow
StackOverflow
)
)
;;;; Value Arrays ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ISLE representation of `[Value; 2]`.

2
cranelift/codegen/src/isa/aarch64/lower/isle/generated_code.manifest

@ -1,4 +1,4 @@
src/clif.isle 9c0563583e5500de00ec5e226edc0547ac3ea789c8d76f1da0401c80ec619320fdc9a6f17fd76bbcac74a5894f85385c1f51c900c2b83bc9906d03d0f29bf5cb
src/clif.isle be1359b4b6b153f378517c1dd95cd80f4a6bed0c7b86eaba11c088fd71b7bfe80a3c868ace245b2da0bfbbd6ded262ea9576c8e0eeacbf89d03c34a17a709602
src/prelude.isle 9bd1fcb6a3604a24cf2e05e6b7eb04dcb3b9dc8fa9a2f1c8f29c25b6e3bf7f679b3b1b72dff87501497b72bc30fc92fd755b898db7e03f380235fae931b6a74b
src/isa/aarch64/inst.isle 6e042ec14166fceae4b7133f681fdf604e20a2997e1d60f797e40acd683ccb34e33376189f6b7ed2f5eb441dc61d592cad2592256dfea51296330752181b9403
src/isa/aarch64/lower.isle 64a725771537f69c445f44c728e04bffd8a715d6a4d87a5a2bf2e89714ee290b7497c5ca8b335bdddd775f6734be03318ff9aa67e2e4068949ebae06b0902b3f

2
cranelift/codegen/src/isa/x64/lower/isle/generated_code.manifest

@ -1,4 +1,4 @@
src/clif.isle 9c0563583e5500de00ec5e226edc0547ac3ea789c8d76f1da0401c80ec619320fdc9a6f17fd76bbcac74a5894f85385c1f51c900c2b83bc9906d03d0f29bf5cb
src/clif.isle be1359b4b6b153f378517c1dd95cd80f4a6bed0c7b86eaba11c088fd71b7bfe80a3c868ace245b2da0bfbbd6ded262ea9576c8e0eeacbf89d03c34a17a709602
src/prelude.isle 9bd1fcb6a3604a24cf2e05e6b7eb04dcb3b9dc8fa9a2f1c8f29c25b6e3bf7f679b3b1b72dff87501497b72bc30fc92fd755b898db7e03f380235fae931b6a74b
src/isa/x64/inst.isle b151120df3c356ac697122a8557becd8857eb725851506e844edeb85d831d461322a96d280ad84f9a23518e1e4efb607aebc0e249004148675e4cc19e89f0655
src/isa/x64/lower.isle c9b408df0a089fb4f207838973ac775b0f9b56c86f056867c28e6bae317873d3844f74f713f9acd6fed98d3d11a2f9d19d392fe5049169dad33b1fc703b9b766

Loading…
Cancel
Save