Skip to main content

dxil_reader/
module.rs

1//! LLVM 3.7 IR as DXIL stores it, read from the bitstream tree: the type table, module values (globals, functions,
2//! constants), metadata, value names and function bodies. Only what DXIL programs use is decoded; any other record in a
3//! function body is refused by name. The blocks of a function body that say nothing a reader of the program's behaviour needs (its metadata and its
4//! use-list order) are the only things skipped, and of the metadata attached to its instructions only `dx.precise` is
5//! read ([`Instruction::precise`]).
6use crate::bitstream::{Block, Record};
7use crate::{Result, error};
8
9const MODULE: u64 = 8;
10const PARAMATTR: u64 = 9;
11const PARAMATTR_GROUP: u64 = 10;
12const CONSTANTS: u64 = 11;
13const FUNCTION: u64 = 12;
14const VALUE_SYMTAB: u64 = 14;
15const METADATA: u64 = 15;
16const METADATA_ATTACHMENT: u64 = 16;
17const TYPES: u64 = 17;
18const USELIST: u64 = 18;
19const BLOCKINFO: u64 = 0;
20
21/// Values a module may hold (globals, constants and function-body values together).
22const MAX_VALUES: usize = 1 << 22;
23const MAX_TYPES: usize = 1 << 16;
24
25/// An index into [`Module::types`].
26pub type TypeId = usize;
27/// An index into the values: the module's [`Module::values`], then a function body's own [`Function::locals`].
28pub type ValueId = usize;
29/// An index into [`Module::metadata`].
30pub type MetadataId = usize;
31
32/// A type of the module's type table.
33#[derive(Clone, Debug, PartialEq, Eq)]
34pub enum Type {
35    /// `void`.
36    Void,
37    /// `label`, the type of a basic block.
38    Label,
39    /// `metadata`.
40    Metadata,
41    /// `half`.
42    Half,
43    /// `float`.
44    Float,
45    /// `double`.
46    Double,
47    /// An integer of this many bits (1 to 64).
48    Integer(u32),
49    /// A pointer to the type, in this LLVM address space (the `TYPE_CODE_POINTER` record's second operand). Pointers to
50    /// one type in two spaces are two types.
51    Pointer(TypeId, u32),
52    /// An array of this many elements of the type.
53    Array(u64, TypeId),
54    /// A vector of this many lanes of the type.
55    Vector(u64, TypeId),
56    /// A structure.
57    Struct {
58        /// Its name, where it has one.
59        name: Option<String>,
60        /// The types of its fields, in order.
61        elements: Vec<TypeId>,
62    },
63    /// A named structure without a body.
64    Opaque(Option<String>),
65    /// A function type.
66    Function {
67        /// Whether it takes a variable argument list.
68        vararg: bool,
69        /// The return type.
70        ret: TypeId,
71        /// The parameter types.
72        params: Vec<TypeId>,
73    },
74}
75
76/// A module-level constant.
77#[derive(Clone, Debug, PartialEq)]
78pub enum Constant {
79    /// The null value of the constant's type (zero).
80    Null,
81    /// An undefined value.
82    Undef,
83    /// An integer's bits, sign-extended from its width.
84    Integer(i64),
85    /// A float's bits (half, float or double by its type).
86    Float(u64),
87    /// An array, structure or vector of other constants (value ids).
88    Aggregate(Vec<ValueId>),
89    /// A constant array or vector of numbers, as stored (the bits of each element).
90    Data(Vec<u64>),
91    /// A string constant, as stored.
92    String(Vec<u8>),
93    /// A constant `getelementptr`: the base (a global) and its indices (module constants).
94    Gep {
95        /// The base global.
96        base: ValueId,
97        /// The index constants.
98        indices: Vec<ValueId>,
99    },
100    /// A constant cast of a module value (to the type of the constant).
101    Cast {
102        /// The cast.
103        op: CastOp,
104        /// The value cast.
105        value: ValueId,
106    },
107    /// A constant binary operation on module values.
108    Binary {
109        /// The operation.
110        op: BinaryOp,
111        /// The left operand.
112        lhs: ValueId,
113        /// The right operand.
114        rhs: ValueId,
115    },
116}
117
118/// A value the module numbers.
119#[derive(Clone, Debug, PartialEq)]
120pub enum Value {
121    /// A function, defined or declared.
122    Function {
123        /// Its function type.
124        ty: TypeId,
125        /// Whether it is only declared (it has no body).
126        declaration: bool,
127    },
128    /// A global variable.
129    Global {
130        /// The global's type: a pointer to `value_ty`.
131        ty: TypeId,
132        /// The type of the value it holds.
133        value_ty: TypeId,
134        /// Its initial value (a module constant), if it has one.
135        init: Option<ValueId>,
136        /// Whether it is a constant (read only).
137        constant: bool,
138        /// LLVM's address space: 0 the default, 3 group shared. No other space occurs in the programs of the games read.
139        address_space: u32,
140    },
141    /// A constant.
142    Constant(Constant),
143    /// A function argument or an instruction's result.
144    Local,
145}
146
147/// A metadata record.
148#[derive(Clone, Debug, PartialEq)]
149pub enum Metadata {
150    /// A metadata string, as stored (not checked to be UTF-8 here).
151    String(Vec<u8>),
152    /// A value as metadata.
153    Value {
154        /// The value's type.
155        ty: TypeId,
156        /// The value.
157        value: ValueId,
158    },
159    /// Operands; `None` is a null operand.
160    Node(Vec<Option<MetadataId>>),
161}
162
163/// A binary operator code (LLVM's `BinaryOpcodes`).
164#[derive(Clone, Copy, Debug, PartialEq, Eq)]
165pub enum BinaryOp {
166    /// Addition.
167    Add,
168    /// Subtraction.
169    Sub,
170    /// Multiplication.
171    Mul,
172    /// Unsigned division.
173    UDiv,
174    /// Signed division.
175    SDiv,
176    /// Unsigned remainder.
177    URem,
178    /// Signed remainder.
179    SRem,
180    /// Shift left.
181    Shl,
182    /// Logical shift right.
183    LShr,
184    /// Arithmetic shift right.
185    AShr,
186    /// Bitwise and.
187    And,
188    /// Bitwise or.
189    Or,
190    /// Bitwise exclusive or.
191    Xor,
192}
193/// A cast opcode (LLVM's `CastOpcodes`).
194#[derive(Clone, Copy, Debug, PartialEq, Eq)]
195pub enum CastOp {
196    /// Truncate an integer.
197    Trunc,
198    /// Zero-extend an integer.
199    ZExt,
200    /// Sign-extend an integer.
201    SExt,
202    /// Float to unsigned integer.
203    FpToUi,
204    /// Float to signed integer.
205    FpToSi,
206    /// Unsigned integer to float.
207    UiToFp,
208    /// Signed integer to float.
209    SiToFp,
210    /// Truncate a float.
211    FpTrunc,
212    /// Extend a float.
213    FpExt,
214    /// Pointer to integer.
215    PtrToInt,
216    /// Integer to pointer.
217    IntToPtr,
218    /// Reinterpret the bits as another type.
219    BitCast,
220}
221
222/// An instruction, with the value ids (absolute) and block numbers it names.
223#[derive(Clone, Debug, PartialEq)]
224pub enum Op {
225    /// Integer opcodes apply to integers; for floating types Add, Sub, Mul, (S)Div, (S)Rem are the float forms.
226    Binary {
227        /// The operation.
228        op: BinaryOp,
229        /// The left operand.
230        lhs: ValueId,
231        /// The right operand.
232        rhs: ValueId,
233    },
234    /// A conversion.
235    Cast {
236        /// The conversion.
237        op: CastOp,
238        /// The value converted; the instruction's result type is the target.
239        value: ValueId,
240    },
241    /// A comparison by its LLVM predicate (0..15 float, 32..41 integer).
242    Compare {
243        /// The predicate.
244        predicate: u64,
245        /// The left operand.
246        lhs: ValueId,
247        /// The right operand.
248        rhs: ValueId,
249    },
250    /// `select`: one of two values by a condition.
251    Select {
252        /// The condition (an `i1`).
253        condition: ValueId,
254        /// The value when the condition is true.
255        then: ValueId,
256        /// The value when it is false.
257        otherwise: ValueId,
258    },
259    /// A field or element of an aggregate.
260    ExtractValue {
261        /// The aggregate.
262        aggregate: ValueId,
263        /// The indices into it, outermost first.
264        indices: Vec<u64>,
265    },
266    /// An aggregate with one field or element replaced.
267    InsertValue {
268        /// The aggregate.
269        aggregate: ValueId,
270        /// The new field or element.
271        value: ValueId,
272        /// The indices of the replaced one, outermost first.
273        indices: Vec<u64>,
274    },
275    /// One lane of a vector.
276    ExtractElement {
277        /// The vector.
278        vector: ValueId,
279        /// The lane number.
280        index: ValueId,
281    },
282    /// A vector with one lane replaced.
283    InsertElement {
284        /// The vector.
285        vector: ValueId,
286        /// The new lane.
287        value: ValueId,
288        /// The lane number.
289        index: ValueId,
290    },
291    /// The lanes of two vectors the mask (a constant vector of lane numbers) picks.
292    ShuffleVector {
293        /// The first vector.
294        first: ValueId,
295        /// The second vector.
296        second: ValueId,
297        /// The constant vector of lane numbers.
298        mask: ValueId,
299    },
300    /// A call.
301    Call {
302        /// The callee.
303        function: ValueId,
304        /// The arguments, one per parameter.
305        args: Vec<ValueId>,
306    },
307    /// The value from the predecessor block control came from: (value, block) pairs.
308    Phi {
309        /// The (value, predecessor block) pairs.
310        incoming: Vec<(ValueId, usize)>,
311    },
312    /// `ret`, with the value returned where there is one.
313    Return(Option<ValueId>),
314    /// An unconditional branch.
315    Branch {
316        /// The block branched to.
317        target: usize,
318    },
319    /// A conditional branch.
320    CondBranch {
321        /// The condition (an `i1`).
322        condition: ValueId,
323        /// The block when it is true.
324        then: usize,
325        /// The block when it is false.
326        otherwise: usize,
327    },
328    /// A multi-way branch: the value, the default block and the (case constant, block) pairs.
329    Switch {
330        /// The value switched on.
331        value: ValueId,
332        /// The block when no case matches.
333        default: usize,
334        /// The (case constant, block) pairs.
335        cases: Vec<(ValueId, usize)>,
336    },
337    /// `unreachable`.
338    Unreachable,
339    /// A local variable of this type (the result is a pointer to it).
340    Alloca {
341        /// The type of the variable.
342        ty: TypeId,
343    },
344    /// A load.
345    Load {
346        /// The pointer loaded from; the result type is the loaded type.
347        pointer: ValueId,
348    },
349    /// A store.
350    Store {
351        /// The pointer stored to.
352        pointer: ValueId,
353        /// The value stored.
354        value: ValueId,
355    },
356    /// `getelementptr`: the base pointer and its indices (the first steps over the pointer itself).
357    Gep {
358        /// The base pointer.
359        base: ValueId,
360        /// The indices.
361        indices: Vec<ValueId>,
362    },
363    /// `atomicrmw`: the operation (LLVM's code: 0 xchg, 1 add, 2 sub, 3 and, 4 nand, 5 or, 6 xor, 7 max, 8 min, 9 umax,
364    /// 10 umin); the result is the value the pointer held.
365    AtomicRmw {
366        /// The pointer.
367        pointer: ValueId,
368        /// The value operated with.
369        value: ValueId,
370        /// The operation code.
371        op: u64,
372    },
373    /// `cmpxchg`: the result is the pair (the value the pointer held, whether it was swapped).
374    CmpXchg {
375        /// The pointer.
376        pointer: ValueId,
377        /// The value compared with.
378        compare: ValueId,
379        /// The new value stored where the comparison holds.
380        value: ValueId,
381    },
382    /// `fence`: ordering between invocations, which a lockstep reading does not have.
383    Fence,
384}
385
386impl Op {
387    /// The values the operation reads (a call's arguments, not its callee; a phi's incoming values).
388    pub fn operands(&self) -> Vec<ValueId> {
389        match self {
390            Op::Binary { lhs, rhs, .. } | Op::Compare { lhs, rhs, .. } => vec![*lhs, *rhs],
391            Op::Cast { value, .. } => vec![*value],
392            Op::Select {
393                condition,
394                then,
395                otherwise,
396            } => vec![*condition, *then, *otherwise],
397            Op::ExtractValue { aggregate, .. } => vec![*aggregate],
398            Op::InsertValue { aggregate, value, .. } => vec![*aggregate, *value],
399            Op::ExtractElement { vector, index } => vec![*vector, *index],
400            Op::InsertElement { vector, value, index } => vec![*vector, *value, *index],
401            Op::ShuffleVector { first, second, mask } => vec![*first, *second, *mask],
402            Op::Call { args, .. } => args.clone(),
403            Op::Phi { incoming } => incoming.iter().map(|(v, _)| *v).collect(),
404            Op::Return(value) => value.iter().copied().collect(),
405            Op::CondBranch { condition, .. } => vec![*condition],
406            Op::Switch { value, cases, .. } => std::iter::once(*value)
407                .chain(cases.iter().map(|(c, _)| *c))
408                .collect(),
409            Op::Load { pointer } => vec![*pointer],
410            Op::Store { pointer, value } | Op::AtomicRmw { pointer, value, .. } => vec![*pointer, *value],
411            Op::Gep { base, indices } => std::iter::once(*base).chain(indices.iter().copied()).collect(),
412            Op::CmpXchg {
413                pointer,
414                compare,
415                value,
416            } => vec![*pointer, *compare, *value],
417            Op::Branch { .. } | Op::Unreachable | Op::Alloca { .. } | Op::Fence => Vec::new(),
418        }
419    }
420
421    /// The basic blocks the operation names (a branch's targets, a phi's predecessors).
422    pub fn blocks(&self) -> Vec<usize> {
423        match self {
424            Op::Branch { target } => vec![*target],
425            Op::CondBranch { then, otherwise, .. } => vec![*then, *otherwise],
426            Op::Switch { default, cases, .. } => std::iter::once(*default)
427                .chain(cases.iter().map(|(_, b)| *b))
428                .collect(),
429            Op::Phi { incoming } => incoming.iter().map(|(_, b)| *b).collect(),
430            _ => Vec::new(),
431        }
432    }
433}
434
435/// An instruction of a function body.
436#[derive(Clone, Debug, PartialEq)]
437pub struct Instruction {
438    /// What it does.
439    pub op: Op,
440    /// The result's value id and type, when the instruction produces one.
441    pub result: Option<(ValueId, TypeId)>,
442    /// The basic block it belongs to.
443    pub block: usize,
444    /// Bit offset of its record.
445    pub at: usize,
446    /// The instruction carries the `dx.precise` attachment, which the compiler writes for HLSL's `precise`: the value
447    /// is not to be fused or reassociated. In skate.'s stock programs it is on calls only: 88,541 `tertiary` (mad),
448    /// 13,005 `loadInput`, 3,546 `unary`, 1,421 `dot3`, 331 `legacyF16ToF32`, 307 `binary`, 213 `dot4` and 105 `dot2`,
449    /// in vertex programs (107,109 instructions in 3,185 of 3,341) and compute programs (360 in 12), in no pixel
450    /// program; none of Elden Ring's has it.
451    pub precise: bool,
452}
453
454/// A function body.
455#[derive(Clone, Debug, PartialEq)]
456pub struct Function {
457    /// The function's module value id.
458    pub value: ValueId,
459    /// The number of basic blocks.
460    pub blocks: usize,
461    /// The instructions of all blocks, in order.
462    pub instructions: Vec<Instruction>,
463    /// The body's own values (arguments, constants, instruction results) and their types; their ids start at
464    /// `first`, after the module's values.
465    pub first: ValueId,
466    /// The values of the body.
467    pub locals: Vec<Value>,
468    /// The types of [`Function::locals`].
469    pub local_types: Vec<TypeId>,
470}
471
472/// A module: its types, values, metadata and function bodies.
473#[derive(Clone, Debug, Default, PartialEq)]
474pub struct Module {
475    /// The type table.
476    pub types: Vec<Type>,
477    /// The module's values by id (globals, functions, module constants); a function body's own values continue the
478    /// numbering in its [`Function`].
479    pub values: Vec<Value>,
480    /// Each value's type.
481    pub value_types: Vec<TypeId>,
482    /// The symbol table: the name of the values that have one.
483    pub names: Vec<(ValueId, String)>,
484    /// The metadata records, by [`MetadataId`].
485    pub metadata: Vec<Metadata>,
486    /// The bit of the bitcode each metadata record (by id) starts at, for the locations of reflection errors.
487    pub metadata_at: Vec<usize>,
488    /// The named metadata (`dx.entryPoints`, ...): the name and the records it lists.
489    pub named_metadata: Vec<(String, Vec<MetadataId>)>,
490    /// The bit each named metadata record (by index in `named_metadata`) starts at.
491    pub named_metadata_at: Vec<usize>,
492    /// The bit of the bitcode the module block starts at: where a record the module lacks would be.
493    pub at: usize,
494    /// The function bodies, in the order of their definitions.
495    pub functions: Vec<Function>,
496    /// The id of the module's `dx.precise` metadata kind (the kind [`Instruction::precise`] reads), where it names one.
497    pub precise_kind: Option<u64>,
498}
499
500fn op(r: &Record, i: usize) -> Result<u64> {
501    r.operands
502        .get(i)
503        .copied()
504        .ok_or_else(|| error(r.at, format!("record {} lacks operand {i}", r.code)))
505}
506fn text(ops: &[u64], at: usize) -> Result<Vec<u8>> {
507    ops.iter()
508        .map(|&c| u8::try_from(c).map_err(|_| error(at, "character above 255")))
509        .collect()
510}
511fn utf8(bytes: Vec<u8>, at: usize) -> Result<String> {
512    String::from_utf8(bytes).map_err(|_| error(at, "name is not UTF-8"))
513}
514fn signed_vbr(v: u64) -> i64 {
515    if v & 1 == 0 {
516        i64::try_from(v >> 1).unwrap_or(i64::MAX)
517    } else if v == 1 {
518        i64::MIN
519    } else {
520        i64::try_from(v >> 1).map_or(i64::MIN, i64::wrapping_neg)
521    }
522}
523
524impl Module {
525    fn ty(&self, id: u64, at: usize) -> Result<TypeId> {
526        let id = usize::try_from(id).map_err(|_| error(at, "type id"))?;
527        if id < self.types.len() {
528            Ok(id)
529        } else {
530            Err(error(at, format!("type {id} undefined")))
531        }
532    }
533    /// The type `id`, which an earlier record has already checked against the table (an error where it has not).
534    fn type_at(&self, id: TypeId, at: usize) -> Result<&Type> {
535        self.types
536            .get(id)
537            .ok_or_else(|| error(at, format!("type {id} of {} types", self.types.len())))
538    }
539    /// The id of the type `ty`, appended to the table where it is not there yet.
540    fn intern(&mut self, ty: Type) -> TypeId {
541        match self.types.iter().position(|x| *x == ty) {
542            Some(p) => p,
543            None => {
544                self.types.push(ty);
545                self.types.len().saturating_sub(1)
546            }
547        }
548    }
549    /// The module's name for a value, where its symbol table has one.
550    pub fn name(&self, value: ValueId) -> Option<&str> {
551        self.names
552            .iter()
553            .find(|(v, _)| *v == value)
554            .map(|(_, n)| n.as_str())
555    }
556    fn push(&mut self, value: Value, ty: TypeId, at: usize) -> Result<ValueId> {
557        if self.values.len() >= MAX_VALUES {
558            return Err(error(at, "too many values"));
559        }
560        self.values.push(value);
561        self.value_types.push(ty);
562        Ok(self.values.len().saturating_sub(1))
563    }
564
565    fn read_types(&mut self, block: &Block) -> Result<()> {
566        let mut struct_name: Option<String> = None;
567        for r in block.records() {
568            if self.types.len() >= MAX_TYPES {
569                return Err(error(r.at, "too many types"));
570            }
571            let t = match r.code {
572                1 => continue, // NUMENTRY
573                2 => Type::Void,
574                3 => Type::Float,
575                4 => Type::Double,
576                5 => Type::Label,
577                6 => Type::Opaque(struct_name.take()),
578                7 => Type::Integer(
579                    u32::try_from(op(r, 0)?)
580                        .ok()
581                        .filter(|w| (1..=64).contains(w))
582                        .ok_or_else(|| error(r.at, "integer width"))?,
583                ),
584                8 => Type::Pointer(
585                    self.ty(op(r, 0)?, r.at)?,
586                    u32::try_from(op(r, 1)?).map_err(|_| error(r.at, "pointer address space"))?,
587                ),
588                10 => Type::Half,
589                11 => Type::Array(op(r, 0)?, self.ty(op(r, 1)?, r.at)?),
590                12 => Type::Vector(op(r, 0)?, self.ty(op(r, 1)?, r.at)?),
591                16 => Type::Metadata,
592                18 | 20 => Type::Struct {
593                    name: if r.code == 20 { struct_name.take() } else { None },
594                    elements: r
595                        .operands
596                        .get(1..)
597                        .unwrap_or_default()
598                        .iter()
599                        .map(|&t| self.ty(t, r.at))
600                        .collect::<Result<_>>()?,
601                },
602                19 => {
603                    struct_name = Some(utf8(text(&r.operands, r.at)?, r.at)?);
604                    continue;
605                }
606                21 => Type::Function {
607                    vararg: op(r, 0)? != 0,
608                    ret: self.ty(op(r, 1)?, r.at)?,
609                    params: r
610                        .operands
611                        .get(2..)
612                        .unwrap_or_default()
613                        .iter()
614                        .map(|&t| self.ty(t, r.at))
615                        .collect::<Result<_>>()?,
616                },
617                other => return Err(error(r.at, format!("type record {other}"))),
618            };
619            self.types.push(t);
620        }
621        Ok(())
622    }
623
624    /// Read a constants block, appending its values. Value ids inside aggregates are absolute.
625    fn read_constants(&mut self, block: &Block) -> Result<()> {
626        let mut ty: Option<TypeId> = None;
627        for r in block.records() {
628            let id = |v: u64| usize::try_from(v).map_err(|_| error(r.at, "value id"));
629            if r.code == 1 {
630                ty = Some(self.ty(op(r, 0)?, r.at)?);
631                continue;
632            }
633            let t = ty.ok_or_else(|| error(r.at, "constant before SETTYPE"))?;
634            let c = match r.code {
635                2 => Constant::Null,
636                3 => Constant::Undef,
637                4 => Constant::Integer(signed_vbr(op(r, 0)?)),
638                6 => Constant::Float(op(r, 0)?),
639                7 => Constant::Aggregate(
640                    r.operands
641                        .iter()
642                        .map(|&v| usize::try_from(v).map_err(|_| error(r.at, "value id")))
643                        .collect::<Result<_>>()?,
644                ),
645                8 | 9 => Constant::String(text(&r.operands, r.at)?),
646                22 => Constant::Data(r.operands.clone()),
647                // CE_GEP and CE_INBOUNDS_GEP: [source type,] then (type, value) pairs, the first the base
648                12 | 20 => {
649                    let ops = r
650                        .operands
651                        .get(usize::from(r.operands.len() % 2 == 1)..)
652                        .unwrap_or_default();
653                    let (pairs, rest) = ops.as_chunks::<2>();
654                    let ([_, base], true) = (
655                        pairs.first().unwrap_or(&[0, 0]),
656                        rest.is_empty() && !pairs.is_empty(),
657                    ) else {
658                        return Err(error(r.at, "constant getelementptr operands"));
659                    };
660                    Constant::Gep {
661                        base: id(*base)?,
662                        indices: pairs
663                            .iter()
664                            .skip(1)
665                            .map(|[_, index]| id(*index))
666                            .collect::<Result<_>>()?,
667                    }
668                }
669                // CE_BINOP: [opcode, lhs, rhs, flags?]
670                10 => Constant::Binary {
671                    op: binary(op(r, 0)?, r.at)?,
672                    lhs: id(op(r, 1)?)?,
673                    rhs: id(op(r, 2)?)?,
674                },
675                // CE_CAST: [opcode, operand type, operand]
676                11 => Constant::Cast {
677                    op: cast(op(r, 0)?, r.at)?,
678                    value: id(op(r, 2)?)?,
679                },
680                other => {
681                    return Err(error(
682                        r.at,
683                        format!("constant record {other} (constant expressions are not supported)"),
684                    ));
685                }
686            };
687            self.push(Value::Constant(c), t, r.at)?;
688        }
689        Ok(())
690    }
691
692    fn read_metadata(&mut self, block: &Block) -> Result<()> {
693        let mut name: Option<String> = None;
694        let md = |v: u64, at: usize| usize::try_from(v).map_err(|_| error(at, "metadata id"));
695        for r in block.records() {
696            match r.code {
697                1 => {
698                    self.metadata.push(Metadata::String(text(&r.operands, r.at)?));
699                    self.metadata_at.push(r.at);
700                }
701                2 => {
702                    self.metadata.push(Metadata::Value {
703                        ty: self.ty(op(r, 0)?, r.at)?,
704                        value: md(op(r, 1)?, r.at)?,
705                    });
706                    self.metadata_at.push(r.at);
707                }
708                3 | 5 => {
709                    self.metadata.push(Metadata::Node(
710                        r.operands
711                            .iter()
712                            .map(|&v| {
713                                if v == 0 {
714                                    Ok(None)
715                                } else {
716                                    md(v.saturating_sub(1), r.at).map(Some)
717                                }
718                            })
719                            .collect::<Result<_>>()?,
720                    ));
721                    self.metadata_at.push(r.at);
722                }
723                4 => name = Some(utf8(text(&r.operands, r.at)?, r.at)?),
724                10 => {
725                    let n = name
726                        .take()
727                        .ok_or_else(|| error(r.at, "named node without a name"))?;
728                    let nodes = r.operands.iter().map(|&v| md(v, r.at)).collect::<Result<_>>()?;
729                    self.named_metadata.push((n, nodes));
730                    self.named_metadata_at.push(r.at);
731                }
732                6 => {
733                    // KIND: [kind id, name]
734                    if text(r.operands.get(1..).unwrap_or_default(), r.at)? == b"dx.precise" {
735                        self.precise_kind = Some(op(r, 0)?);
736                    }
737                }
738                other => return Err(error(r.at, format!("metadata record {other}"))),
739            }
740        }
741        Ok(())
742    }
743
744    fn read_symbols(&mut self, block: &Block, base: usize) -> Result<()> {
745        for r in block.records() {
746            match r.code {
747                1 | 3 => {
748                    let value = usize::try_from(op(r, 0)?).map_err(|_| error(r.at, "value id"))?;
749                    let skip = if r.code == 3 { 2 } else { 1 };
750                    let n = utf8(text(r.operands.get(skip..).unwrap_or_default(), r.at)?, r.at)?;
751                    let id = base.checked_add(value).ok_or_else(|| error(r.at, "value id"))?;
752                    self.names.push((id, n));
753                }
754                2 => {} // basic-block names
755                other => return Err(error(r.at, format!("symbol record {other}"))),
756            }
757        }
758        Ok(())
759    }
760}
761
762/// Function-body decoding state: relative value numbering (module version 1).
763struct Body<'m> {
764    m: &'m mut Module,
765    block: usize,
766    blocks: usize,
767}
768impl Body<'_> {
769    fn next(&self) -> usize {
770        self.m.values.len()
771    }
772    /// A relative operand (absolute = next - operand), with its explicit type following when it is a forward
773    /// reference (a value defined later in the function's layout). Returns the value id and its type, and advances `i`.
774    fn value_type(&self, r: &Record, i: &mut usize) -> Result<(ValueId, TypeId)> {
775        let id = self.absolute(op(r, *i)?, r.at)?;
776        *i = i.saturating_add(1);
777        if id < self.next() {
778            let t = self
779                .m
780                .value_types
781                .get(id)
782                .copied()
783                .ok_or_else(|| error(r.at, format!("value {id} has no type")))?;
784            Ok((id, t))
785        } else {
786            let t = self.m.ty(op(r, *i)?, r.at)?;
787            *i = i.saturating_add(1);
788            Ok((id, t))
789        }
790    }
791    /// A relative operand whose type is known from another operand: a forward reference carries none.
792    fn value(&self, r: &Record, i: &mut usize) -> Result<ValueId> {
793        let id = self.absolute(op(r, *i)?, r.at)?;
794        *i = i.saturating_add(1);
795        Ok(id)
796    }
797    /// The absolute id a relative operand names: the next id minus the operand, in 32 bits as LLVM writes it (a value
798    /// defined later is a forward reference, which wraps).
799    fn absolute(&self, relative: u64, at: usize) -> Result<ValueId> {
800        let relative = u32::try_from(relative)
801            .map_err(|_| error(at, format!("relative value id {relative} wider than 32 bits")))?;
802        let next = u32::try_from(self.next()).map_err(|_| error(at, "too many values"))?;
803        Ok(next.wrapping_sub(relative) as usize)
804    }
805    /// The type of a value defined before this point, or of a forward reference by the type given.
806    fn pointer_to(&mut self, t: TypeId) -> TypeId {
807        self.m.intern(Type::Pointer(t, 0))
808    }
809    /// The index a constant integer value stands for, if it is one defined in the module or this function.
810    fn constant_index(&self, v: ValueId) -> Option<usize> {
811        match self.m.values.get(v) {
812            Some(Value::Constant(Constant::Integer(i))) => usize::try_from(*i).ok(),
813            Some(Value::Constant(Constant::Null)) => Some(0),
814            _ => None,
815        }
816    }
817    fn result(&mut self, ty: TypeId, at: usize) -> Result<Option<(ValueId, TypeId)>> {
818        if *self.m.type_at(ty, at)? == Type::Void {
819            return Ok(None);
820        }
821        Ok(Some((self.m.push(Value::Local, ty, at)?, ty)))
822    }
823}
824
825fn binary(code: u64, at: usize) -> Result<BinaryOp> {
826    Ok(match code {
827        0 => BinaryOp::Add,
828        1 => BinaryOp::Sub,
829        2 => BinaryOp::Mul,
830        3 => BinaryOp::UDiv,
831        4 => BinaryOp::SDiv,
832        5 => BinaryOp::URem,
833        6 => BinaryOp::SRem,
834        7 => BinaryOp::Shl,
835        8 => BinaryOp::LShr,
836        9 => BinaryOp::AShr,
837        10 => BinaryOp::And,
838        11 => BinaryOp::Or,
839        12 => BinaryOp::Xor,
840        other => return Err(error(at, format!("binary opcode {other}"))),
841    })
842}
843fn cast(code: u64, at: usize) -> Result<CastOp> {
844    Ok(match code {
845        0 => CastOp::Trunc,
846        1 => CastOp::ZExt,
847        2 => CastOp::SExt,
848        3 => CastOp::FpToUi,
849        4 => CastOp::FpToSi,
850        5 => CastOp::UiToFp,
851        6 => CastOp::SiToFp,
852        7 => CastOp::FpTrunc,
853        8 => CastOp::FpExt,
854        9 => CastOp::PtrToInt,
855        10 => CastOp::IntToPtr,
856        11 => CastOp::BitCast,
857        other => return Err(error(at, format!("cast opcode {other}"))),
858    })
859}
860/// The name of a function-body record code this reader refuses.
861fn refused(code: u64) -> &'static str {
862    match code {
863        4 | 30 => "getelementptr (old form)",
864        13 => "invoke",
865        41 => "load (atomic)",
866        23 => "va_arg",
867        24 | 42 | 45 => "store (atomic)",
868        31 => "indirectbr",
869        37 => "cmpxchg (old form)",
870        59 => "atomicrmw (new form)",
871        39 => "resume",
872        40 | 47 => "landingpad",
873        _ => "unknown instruction record",
874    }
875}
876
877/// Marks the instructions a function's attachment block gives the `dx.precise` kind: its records are `[instruction,
878/// (kind, node)...]` (an even number of operands is an attachment of the function itself, which is skipped).
879fn mark_precise(kind: Option<u64>, block: &Block, instructions: &mut [Instruction]) -> Result<()> {
880    let Some(kind) = kind else {
881        return Ok(());
882    };
883    for r in block
884        .records()
885        .filter(|r| r.code == 11 && r.operands.len() % 2 == 1)
886    {
887        let at = usize::try_from(op(r, 0)?).map_err(|_| error(r.at, "attachment instruction"))?;
888        if r.operands
889            .get(1..)
890            .unwrap_or_default()
891            .chunks(2)
892            .any(|pair| pair.first() == Some(&kind))
893        {
894            instructions
895                .get_mut(at)
896                .ok_or_else(|| {
897                    error(
898                        r.at,
899                        format!("an attachment names instruction {at} of a shorter body"),
900                    )
901                })?
902                .precise = true;
903        }
904    }
905    Ok(())
906}
907
908impl Module {
909    fn read_function(&mut self, block: &Block, value: ValueId) -> Result<Function> {
910        let fty = match self.value_types.get(value).and_then(|&t| self.types.get(t)) {
911            Some(Type::Pointer(t, _)) => *t,
912            _ => return Err(error(block.at, "function value is not a function pointer")),
913        };
914        let params = match self.type_at(fty, block.at)? {
915            Type::Function { params, .. } => params.clone(),
916            _ => return Err(error(block.at, "function type")),
917        };
918        let base = self.values.len();
919        for p in params {
920            self.push(Value::Local, p, block.at)?;
921        }
922        let mut body = Body {
923            m: self,
924            block: 0,
925            blocks: 0,
926        };
927        let mut instructions = Vec::new();
928        for e in &block.elements {
929            let r = match e {
930                crate::bitstream::Element::Block(b) => {
931                    match b.id {
932                        CONSTANTS => body.m.read_constants(b)?,
933                        VALUE_SYMTAB => body.m.read_symbols(b, 0)?,
934                        METADATA_ATTACHMENT => mark_precise(body.m.precise_kind, b, &mut instructions)?,
935                        METADATA | USELIST => {}
936                        other => return Err(error(b.at, format!("block {other} in a function"))),
937                    }
938                    continue;
939                }
940                crate::bitstream::Element::Record(r) => r,
941            };
942            let mut i = 0;
943            let (op, ty): (Op, Option<TypeId>) = match r.code {
944                1 => {
945                    body.blocks = usize::try_from(op(r, 0)?)
946                        .ok()
947                        .filter(|&n| n > 0 && n <= 1 << 16)
948                        .ok_or_else(|| error(r.at, "basic block count"))?;
949                    continue;
950                }
951                33 | 35 => continue, // debug locations
952                2 => {
953                    let (lhs, t) = body.value_type(r, &mut i)?;
954                    let rhs = body.value(r, &mut i)?;
955                    let o = binary(op(r, i)?, r.at)?;
956                    (Op::Binary { op: o, lhs, rhs }, Some(t))
957                }
958                3 => {
959                    let value = body.value(r, &mut i)?;
960                    let to = body.m.ty(op(r, i)?, r.at)?;
961                    let o = cast(op(r, i.saturating_add(1))?, r.at)?;
962                    (Op::Cast { op: o, value }, Some(to))
963                }
964                9 | 28 => {
965                    let (lhs, t) = body.value_type(r, &mut i)?;
966                    let rhs = body.value(r, &mut i)?;
967                    let predicate = op(r, i)?;
968                    let bool_ty = match body.m.type_at(t, r.at)? {
969                        Type::Vector(..) => {
970                            return Err(error(r.at, "vector comparison"));
971                        }
972                        _ => body
973                            .m
974                            .types
975                            .iter()
976                            .position(|x| *x == Type::Integer(1))
977                            .ok_or_else(|| error(r.at, "no i1 type for a comparison"))?,
978                    };
979                    (Op::Compare { predicate, lhs, rhs }, Some(bool_ty))
980                }
981                29 => {
982                    let (then, t) = body.value_type(r, &mut i)?;
983                    let otherwise = body.value(r, &mut i)?;
984                    let condition = body.value(r, &mut i)?;
985                    (
986                        Op::Select {
987                            condition,
988                            then,
989                            otherwise,
990                        },
991                        Some(t),
992                    )
993                }
994                26 => {
995                    let (aggregate, mut t) = body.value_type(r, &mut i)?;
996                    let indices = r.operands.get(i..).unwrap_or_default().to_vec();
997                    for &k in &indices {
998                        t = match body.m.type_at(t, r.at)? {
999                            Type::Struct { elements, .. } => *usize::try_from(k)
1000                                .ok()
1001                                .and_then(|k| elements.get(k))
1002                                .ok_or_else(|| error(r.at, "extractvalue index"))?,
1003                            Type::Array(n, e) if k < *n => *e,
1004                            _ => return Err(error(r.at, "extractvalue index")),
1005                        };
1006                    }
1007                    (Op::ExtractValue { aggregate, indices }, Some(t))
1008                }
1009                6 => {
1010                    let (vector, t) = body.value_type(r, &mut i)?;
1011                    let (index, _) = body.value_type(r, &mut i)?;
1012                    let Type::Vector(_, element) = *body.m.type_at(t, r.at)? else {
1013                        return Err(error(r.at, "extractelement of something that is not a vector"));
1014                    };
1015                    (Op::ExtractElement { vector, index }, Some(element))
1016                }
1017                7 => {
1018                    let (vector, t) = body.value_type(r, &mut i)?;
1019                    let value = body.value(r, &mut i)?;
1020                    let (index, _) = body.value_type(r, &mut i)?;
1021                    (Op::InsertElement { vector, value, index }, Some(t))
1022                }
1023                8 => {
1024                    let (first, t) = body.value_type(r, &mut i)?;
1025                    let second = body.value(r, &mut i)?;
1026                    let (mask, mask_ty) = body.value_type(r, &mut i)?;
1027                    let (Type::Vector(_, element), Type::Vector(lanes, _)) = (
1028                        body.m.type_at(t, r.at)?.clone(),
1029                        body.m.type_at(mask_ty, r.at)?.clone(),
1030                    ) else {
1031                        return Err(error(r.at, "shufflevector of something that is not a vector"));
1032                    };
1033                    let result = body
1034                        .m
1035                        .types
1036                        .iter()
1037                        .position(|x| *x == Type::Vector(lanes, element))
1038                        .ok_or_else(|| error(r.at, "no type for the shuffled vector"))?;
1039                    (Op::ShuffleVector { first, second, mask }, Some(result))
1040                }
1041                27 => {
1042                    let (aggregate, t) = body.value_type(r, &mut i)?;
1043                    let value = body.value(r, &mut i)?;
1044                    let indices = r.operands.get(i..).unwrap_or_default().to_vec();
1045                    (
1046                        Op::InsertValue {
1047                            aggregate,
1048                            value,
1049                            indices,
1050                        },
1051                        Some(t),
1052                    )
1053                }
1054                34 => {
1055                    i = 1; // paramattrs
1056                    let cc = op(r, i)?;
1057                    i = i.saturating_add(1);
1058                    if cc & (1 << 17) != 0 {
1059                        i = i.saturating_add(1); // fast-math flags
1060                    }
1061                    let explicit = if cc & (1 << 15) != 0 {
1062                        let t = body.m.ty(op(r, i)?, r.at)?;
1063                        i = i.saturating_add(1);
1064                        Some(t)
1065                    } else {
1066                        None
1067                    };
1068                    let (function, callee_ty) = body.value_type(r, &mut i)?;
1069                    let fty = match (explicit, body.m.type_at(callee_ty, r.at)?) {
1070                        (Some(t), _) => t,
1071                        (None, Type::Pointer(t, _)) => *t,
1072                        _ => return Err(error(r.at, "callee is not a function pointer")),
1073                    };
1074                    let (ret, params, vararg) = match body.m.type_at(fty, r.at)? {
1075                        Type::Function { ret, params, vararg } => (*ret, params.clone(), *vararg),
1076                        _ => return Err(error(r.at, "call through a non-function type")),
1077                    };
1078                    if vararg {
1079                        return Err(error(r.at, "vararg call"));
1080                    }
1081                    let mut args = Vec::with_capacity(params.len());
1082                    for p in &params {
1083                        // a fixed parameter carries no type, even for a value defined later in the layout
1084                        let a = body.value(r, &mut i)?;
1085                        if a < body.next() && body.m.value_types.get(a) != Some(p) {
1086                            return Err(error(r.at, "call argument type"));
1087                        }
1088                        args.push(a);
1089                    }
1090                    if i != r.operands.len() {
1091                        return Err(error(r.at, "call operands left over"));
1092                    }
1093                    (Op::Call { function, args }, Some(ret))
1094                }
1095                16 => {
1096                    let t = body.m.ty(op(r, 0)?, r.at)?;
1097                    let pairs = r.operands.get(1..).unwrap_or_default();
1098                    if pairs.is_empty() || pairs.len() % 2 != 0 {
1099                        return Err(error(r.at, "phi operands"));
1100                    }
1101                    let next = i64::try_from(body.next()).map_err(|_| error(r.at, "too many values"))?;
1102                    let mut incoming = Vec::with_capacity(pairs.len() / 2);
1103                    for pair in pairs.as_chunks::<2>().0 {
1104                        // Signed and relative to the phi itself; it may name a value defined later.
1105                        let id = next
1106                            .checked_sub(signed_vbr(pair[0]))
1107                            .and_then(|v| usize::try_from(v).ok())
1108                            .ok_or_else(|| error(r.at, "phi value"))?;
1109                        let block = usize::try_from(pair[1])
1110                            .ok()
1111                            .filter(|&b| b < body.blocks)
1112                            .ok_or_else(|| error(r.at, "phi block"))?;
1113                        incoming.push((id, block));
1114                    }
1115                    (Op::Phi { incoming }, Some(t))
1116                }
1117                10 => {
1118                    if r.operands.is_empty() {
1119                        (Op::Return(None), None)
1120                    } else {
1121                        (Op::Return(Some(body.value(r, &mut i)?)), None)
1122                    }
1123                }
1124                11 => {
1125                    let target = |v: u64| -> Result<usize> {
1126                        usize::try_from(v)
1127                            .ok()
1128                            .filter(|&b| b < body.blocks)
1129                            .ok_or_else(|| error(r.at, "branch target"))
1130                    };
1131                    if r.operands.len() == 1 {
1132                        (
1133                            Op::Branch {
1134                                target: target(op(r, 0)?)?,
1135                            },
1136                            None,
1137                        )
1138                    } else {
1139                        let then = target(op(r, 0)?)?;
1140                        let otherwise = target(op(r, 1)?)?;
1141                        i = 2;
1142                        let condition = body.value(r, &mut i)?;
1143                        (
1144                            Op::CondBranch {
1145                                condition,
1146                                then,
1147                                otherwise,
1148                            },
1149                            None,
1150                        )
1151                    }
1152                }
1153                12 => {
1154                    // [type, value, default block, (case constant, block)*]; case constants are absolute ids
1155                    let block = |v: u64| -> Result<usize> {
1156                        usize::try_from(v)
1157                            .ok()
1158                            .filter(|&b| b < body.blocks)
1159                            .ok_or_else(|| error(r.at, "switch target"))
1160                    };
1161                    i = 1;
1162                    let value = body.value(r, &mut i)?;
1163                    let default = block(op(r, i)?)?;
1164                    let pairs = r.operands.get(i.saturating_add(1)..).unwrap_or_default();
1165                    if pairs.len() % 2 != 0 {
1166                        return Err(error(r.at, "switch cases"));
1167                    }
1168                    let cases = pairs
1169                        .as_chunks::<2>()
1170                        .0
1171                        .iter()
1172                        .map(|p| {
1173                            Ok((
1174                                usize::try_from(p[0]).map_err(|_| error(r.at, "case value"))?,
1175                                block(p[1])?,
1176                            ))
1177                        })
1178                        .collect::<Result<Vec<_>>>()?;
1179                    (
1180                        Op::Switch {
1181                            value,
1182                            default,
1183                            cases,
1184                        },
1185                        None,
1186                    )
1187                }
1188                15 => (Op::Unreachable, None),
1189                19 => {
1190                    // [allocated type, size type, size (absolute id), alignment]
1191                    let ty = body.m.ty(op(r, 0)?, r.at)?;
1192                    (Op::Alloca { ty }, Some(body.pointer_to(ty)))
1193                }
1194                20 => {
1195                    let (pointer, pt) = body.value_type(r, &mut i)?;
1196                    let _ = pt;
1197                    let ty = body.m.ty(op(r, i)?, r.at)?;
1198                    (Op::Load { pointer }, Some(ty))
1199                }
1200                44 => {
1201                    let (pointer, _) = body.value_type(r, &mut i)?;
1202                    let (value, _) = body.value_type(r, &mut i)?;
1203                    (Op::Store { pointer, value }, None)
1204                }
1205                // atomicrmw (LLVM 3.7): [pointer with its type, value, operation, volatile, ordering, scope]
1206                38 => {
1207                    let (pointer, _) = body.value_type(r, &mut i)?;
1208                    let value = body.value(r, &mut i)?;
1209                    let op = op(r, i)?;
1210                    let ty = body.m.value_types.get(value).copied();
1211                    let ty = match ty {
1212                        Some(t) if value < body.next() => t,
1213                        _ => return Err(error(r.at, "an atomicrmw of a value defined later")),
1214                    };
1215                    (Op::AtomicRmw { pointer, value, op }, Some(ty))
1216                }
1217                // cmpxchg: [pointer with its type, compare with its type, new value, volatile, orderings, ...]; the
1218                // result is a structure of the value and a flag
1219                46 => {
1220                    let (pointer, _) = body.value_type(r, &mut i)?;
1221                    let (compare, ty) = body.value_type(r, &mut i)?;
1222                    let value = body.value(r, &mut i)?;
1223                    let flag = body
1224                        .m
1225                        .types
1226                        .iter()
1227                        .position(|t| *t == Type::Integer(1))
1228                        .ok_or_else(|| error(r.at, "a cmpxchg without a boolean type"))?;
1229                    let pair = Type::Struct {
1230                        name: None,
1231                        elements: vec![ty, flag],
1232                    };
1233                    let result = body.m.intern(pair);
1234                    (
1235                        Op::CmpXchg {
1236                            pointer,
1237                            compare,
1238                            value,
1239                        },
1240                        Some(result),
1241                    )
1242                }
1243                36 => (Op::Fence, None),
1244                43 => {
1245                    // [inbounds, source element type, then each operand with its type when a forward reference]
1246                    i = 2;
1247                    let source = body.m.ty(op(r, 1)?, r.at)?;
1248                    let (base, _) = body.value_type(r, &mut i)?;
1249                    let mut indices = Vec::new();
1250                    while i < r.operands.len() {
1251                        indices.push(body.value_type(r, &mut i)?.0);
1252                    }
1253                    // the result points at what the indices reach: the first steps over the pointer, the rest into
1254                    // arrays, vectors and structures
1255                    let mut t = source;
1256                    for &index in indices.iter().skip(1) {
1257                        t = match body.m.type_at(t, r.at)?.clone() {
1258                            Type::Array(_, e) | Type::Vector(_, e) => e,
1259                            Type::Struct { elements, .. } => {
1260                                let k = match body.constant_index(index) {
1261                                    Some(k) => k,
1262                                    None => {
1263                                        return Err(error(r.at, "a structure index that is not constant"));
1264                                    }
1265                                };
1266                                *elements
1267                                    .get(k)
1268                                    .ok_or_else(|| error(r.at, "getelementptr structure index"))?
1269                            }
1270                            _ => return Err(error(r.at, "getelementptr into a scalar")),
1271                        };
1272                    }
1273                    (Op::Gep { base, indices }, Some(body.pointer_to(t)))
1274                }
1275                other => {
1276                    return Err(error(
1277                        r.at,
1278                        format!("instruction {} (record {other}) is not supported", refused(other)),
1279                    ));
1280                }
1281            };
1282            let result = match ty {
1283                Some(t) => body.result(t, r.at)?,
1284                None => None,
1285            };
1286            let terminator = matches!(
1287                op,
1288                Op::Return(_)
1289                    | Op::Branch { .. }
1290                    | Op::CondBranch { .. }
1291                    | Op::Switch { .. }
1292                    | Op::Unreachable
1293            );
1294            instructions.push(Instruction {
1295                op,
1296                result,
1297                block: body.block,
1298                at: r.at,
1299                precise: false,
1300            });
1301            if terminator {
1302                body.block = body.block.saturating_add(1);
1303            }
1304        }
1305        if body.block != body.blocks {
1306            return Err(error(block.at, "basic blocks without terminators"));
1307        }
1308        let end = body.next();
1309        let blocks = body.blocks;
1310        // everything an instruction names is something the function has: a value (an earlier one, or a later one a phi
1311        // or a loop reads), a basic block, and a callee taking the arguments it is given
1312        for inst in &instructions {
1313            if inst.block >= blocks {
1314                return Err(error(inst.at, "an instruction after the last terminator"));
1315            }
1316            if let Some(v) = inst.op.operands().into_iter().find(|v| *v >= end) {
1317                return Err(error(inst.at, format!("value {v} of {end} values")));
1318            }
1319            if let Some(b) = inst.op.blocks().into_iter().find(|b| *b >= blocks) {
1320                return Err(error(inst.at, format!("basic block {b} of {blocks}")));
1321            }
1322            if let Op::Call { function, args } = &inst.op {
1323                if *function >= end {
1324                    return Err(error(inst.at, format!("callee {function} of {end} values")));
1325                }
1326                if let Some(Value::Function { ty, .. }) = self.values.get(*function)
1327                    && let Some(Type::Function {
1328                        vararg: false,
1329                        params,
1330                        ..
1331                    }) = self.types.get(*ty)
1332                    && params.len() != args.len()
1333                {
1334                    return Err(error(
1335                        inst.at,
1336                        format!(
1337                            "a call of {} arguments to a function of {} parameters",
1338                            args.len(),
1339                            params.len()
1340                        ),
1341                    ));
1342                }
1343            }
1344        }
1345        let locals = self.values.split_off(base);
1346        let local_types = self.value_types.split_off(base);
1347        Ok(Function {
1348            value,
1349            blocks,
1350            instructions,
1351            first: base,
1352            locals,
1353            local_types,
1354        })
1355    }
1356
1357    /// Read a module from the bitcode's top-level blocks.
1358    pub fn read(top: &[Block]) -> Result<Self> {
1359        let module = match top {
1360            [m] if m.id == MODULE => m,
1361            _ => return Err(error(0, "bitcode is not one module block")),
1362        };
1363        let mut m = Module {
1364            at: module.at,
1365            ..Module::default()
1366        };
1367        let mut bodies: Vec<ValueId> = Vec::new();
1368        let mut version = None;
1369        for e in &module.elements {
1370            match e {
1371                crate::bitstream::Element::Record(r) => match r.code {
1372                    1 => version = Some(op(r, 0)?),
1373                    2..=6 | 11 | 13 | 16 => {} // triple, datalayout, asm, section, deplib, gc, source file
1374                    7 => {
1375                        // GLOBALVAR: [type, flags (bit 0 constant, bit 1 explicit type, from bit 2 the address space),
1376                        // initial value + 1 or 0, ...]
1377                        let t = m.ty(op(r, 0)?, r.at)?;
1378                        let flags = op(r, 1)?;
1379                        let address_space =
1380                            u32::try_from(flags >> 2).map_err(|_| error(r.at, "address space"))?;
1381                        let (ty, value_ty) = if flags & 2 != 0 {
1382                            let pointer = m.intern(Type::Pointer(t, address_space));
1383                            (pointer, t)
1384                        } else {
1385                            match m.type_at(t, r.at)? {
1386                                Type::Pointer(inner, _) => (t, *inner),
1387                                _ => return Err(error(r.at, "a global whose type is not a pointer")),
1388                            }
1389                        };
1390                        let init = match op(r, 2)? {
1391                            0 => None,
1392                            n => Some(
1393                                usize::try_from(n.saturating_sub(1))
1394                                    .map_err(|_| error(r.at, "initial value id"))?,
1395                            ),
1396                        };
1397                        m.push(
1398                            Value::Global {
1399                                ty,
1400                                value_ty,
1401                                init,
1402                                constant: flags & 1 != 0,
1403                                address_space,
1404                            },
1405                            ty,
1406                            r.at,
1407                        )?;
1408                    }
1409                    8 => {
1410                        // FUNCTION: [function type, cc, isproto, ...]
1411                        let t = m.ty(op(r, 0)?, r.at)?;
1412                        let pointer = m.intern(Type::Pointer(t, 0));
1413                        let declaration = op(r, 2)? != 0;
1414                        let v = m.push(Value::Function { ty: t, declaration }, pointer, r.at)?;
1415                        if !declaration {
1416                            bodies.push(v);
1417                        }
1418                    }
1419                    other => return Err(error(r.at, format!("module record {other}"))),
1420                },
1421                crate::bitstream::Element::Block(b) => match b.id {
1422                    BLOCKINFO | PARAMATTR | PARAMATTR_GROUP | USELIST => {}
1423                    TYPES => m.read_types(b)?,
1424                    CONSTANTS => m.read_constants(b)?,
1425                    METADATA => m.read_metadata(b)?,
1426                    VALUE_SYMTAB => m.read_symbols(b, 0)?,
1427                    FUNCTION => {
1428                        if version != Some(1) {
1429                            return Err(error(b.at, "only relative value ids (module version 1)"));
1430                        }
1431                        // Bodies are stored in the order of their definitions (a hull program has two).
1432                        if bodies.is_empty() {
1433                            return Err(error(b.at, "function body without a definition"));
1434                        }
1435                        let value = bodies.remove(0);
1436                        // A body's values are its own; the next body numbers from the module's values again.
1437                        let f = m.read_function(b, value)?;
1438                        m.functions.push(f);
1439                    }
1440                    other => return Err(error(b.at, format!("module block {other}"))),
1441                },
1442            }
1443        }
1444        if !bodies.is_empty() {
1445            return Err(error(module.at, "a defined function has no body"));
1446        }
1447        Ok(m)
1448    }
1449}