diff --git a/lib/cretonne/meta/cretonne/__init__.py b/lib/cretonne/meta/cretonne/__init__.py index a8865e1966..6672d6d869 100644 --- a/lib/cretonne/meta/cretonne/__init__.py +++ b/lib/cretonne/meta/cretonne/__init__.py @@ -707,6 +707,11 @@ class InstructionFormat(object): self.members.append(member) yield k + def __str__(self): + args = ', '.join('{}: {}'.format(m, k) if m else str(k) + for m, k in zip(self.members, self.kinds)) + return '{}({})'.format(self.name, args) + def __getattr__(self, attr): # type: (str) -> FormatField """ diff --git a/lib/cretonne/meta/gen_instr.py b/lib/cretonne/meta/gen_instr.py index 8a7e813223..bb14d36375 100644 --- a/lib/cretonne/meta/gen_instr.py +++ b/lib/cretonne/meta/gen_instr.py @@ -19,6 +19,7 @@ def gen_formats(fmt): fmt.line('#[derive(Copy, Clone, PartialEq, Eq, Debug)]') with fmt.indented('pub enum InstructionFormat {', '}'): for f in cretonne.InstructionFormat.all_formats: + fmt.doc_comment(str(f)) fmt.line(f.name + ',') fmt.line() @@ -172,6 +173,7 @@ def gen_opcodes(groups, fmt): fmt.line('#[derive(Copy, Clone, PartialEq, Eq, Debug)]') instrs = [] with fmt.indented('pub enum Opcode {', '}'): + fmt.doc_comment('An invalid opcode.') fmt.line('NotAnOpcode,') for g in groups: for i in g.instructions: @@ -364,6 +366,7 @@ def gen_format_constructor(iform, fmt): proto = '{}({})'.format(iform.name, ', '.join(args)) proto += " -> (Inst, &'f mut DataFlowGraph)" + fmt.doc_comment(str(iform)) fmt.line('#[allow(non_snake_case)]') with fmt.indented('fn {} {{'.format(proto), '}'): # Generate the instruction data. diff --git a/lib/cretonne/meta/gen_settings.py b/lib/cretonne/meta/gen_settings.py index c3c4710ea3..8e35d05909 100644 --- a/lib/cretonne/meta/gen_settings.py +++ b/lib/cretonne/meta/gen_settings.py @@ -16,10 +16,12 @@ def gen_enum_types(sgrp, fmt): if not isinstance(setting, EnumSetting): continue ty = camel_case(setting.name) + fmt.doc_comment('Values for {}.'.format(setting)) fmt.line('#[derive(Debug, PartialEq, Eq)]') - fmt.line( - 'pub enum {} {{ {} }}' - .format(ty, ", ".join(camel_case(v) for v in setting.values))) + with fmt.indented('pub enum {} {{'.format(ty), '}'): + for v in setting.values: + fmt.doc_comment('`{}`.'.format(v)) + fmt.line(camel_case(v) + ',') def gen_getter(setting, sgrp, fmt): @@ -70,7 +72,7 @@ def gen_getters(sgrp, fmt): """ fmt.doc_comment("User-defined settings.") with fmt.indented('impl Flags {', '}'): - # Dynamic numbered predicate getter. + fmt.doc_comment('Dynamic numbered predicate getter.') with fmt.indented( 'pub fn numbered_predicate(&self, p: usize) -> bool {', '}'): fmt.line( @@ -187,6 +189,7 @@ def gen_constructor(sgrp, parent, fmt): if sgrp.parent: p = sgrp.parent args = '{}: &{}::Flags, {}'.format(p.name, p.qual_mod, args) + fmt.doc_comment('Create flags {} settings group.'.format(sgrp.name)) with fmt.indented( 'pub fn new({}) -> Flags {{'.format(args), '}'): fmt.line('let bvec = builder.state_for("{}");'.format(sgrp.name)) diff --git a/lib/cretonne/src/cfg.rs b/lib/cretonne/src/cfg.rs index 76ccc27965..f68d8bcbf4 100644 --- a/lib/cretonne/src/cfg.rs +++ b/lib/cretonne/src/cfg.rs @@ -33,19 +33,12 @@ pub type BasicBlock = (Ebb, Inst); /// A container for the successors and predecessors of some Ebb. #[derive(Debug, Clone, Default)] pub struct CFGNode { + /// EBBs that are the targets of branches and jumps in this EBB. pub successors: Vec, + /// Basic blocks that can branch or jump to this EBB. pub predecessors: Vec, } -impl CFGNode { - pub fn new() -> CFGNode { - CFGNode { - successors: Vec::new(), - predecessors: Vec::new(), - } - } -} - /// The Control Flow Graph maintains a mapping of ebbs to their predecessors /// and successors where predecessors are basic blocks and successors are /// extended basic blocks. @@ -88,10 +81,12 @@ impl ControlFlowGraph { self.data[to].predecessors.push(from); } + /// Get the CFG predecessor basic blocks to `ebb`. pub fn get_predecessors(&self, ebb: Ebb) -> &Vec { &self.data[ebb].predecessors } + /// Get the CFG successors to `ebb`. pub fn get_successors(&self, ebb: Ebb) -> &Vec { &self.data[ebb].successors } diff --git a/lib/cretonne/src/dominator_tree.rs b/lib/cretonne/src/dominator_tree.rs index c81e579f6b..e331f5657b 100644 --- a/lib/cretonne/src/dominator_tree.rs +++ b/lib/cretonne/src/dominator_tree.rs @@ -1,10 +1,11 @@ -/// ! A Dominator Tree represented as mappings of Ebbs to their immediate dominator. +//! A Dominator Tree represented as mappings of Ebbs to their immediate dominator. use cfg::*; use ir::Ebb; use ir::entities::NO_INST; use entity_map::EntityMap; +/// The dominator tree for a single function. pub struct DominatorTree { data: EntityMap>, } diff --git a/lib/cretonne/src/ir/condcodes.rs b/lib/cretonne/src/ir/condcodes.rs index 692ecda96f..dfa6b054f5 100644 --- a/lib/cretonne/src/ir/condcodes.rs +++ b/lib/cretonne/src/ir/condcodes.rs @@ -29,15 +29,25 @@ pub trait CondCode: Copy { /// difference. #[derive(Clone, Copy, PartialEq, Eq, Debug)] pub enum IntCC { + /// `==`. Equal, + /// `!=`. NotEqual, + /// Signed `<`. SignedLessThan, + /// Signed `>=`. SignedGreaterThanOrEqual, + /// Signed `>`. SignedGreaterThan, + /// Signed `<=`. SignedLessThanOrEqual, + /// Unsigned `<`. UnsignedLessThan, + /// Unsigned `>=`. UnsignedGreaterThanOrEqual, + /// Unsigned `>`. UnsignedGreaterThan, + /// Unsigned `<=`. UnsignedLessThanOrEqual, } @@ -131,24 +141,38 @@ impl FromStr for IntCC { /// except the impossible `!UN & !EQ & !LT & !GT` and the always true `UN | EQ | LT | GT`. #[derive(Clone, Copy, PartialEq, Eq, Debug)] pub enum FloatCC { - Ordered, // EQ | LT | GT - Unordered, // UN + /// EQ | LT | GT + Ordered, + /// UN + Unordered, - Equal, // EQ - // The C '!=' operator is the inverse of '==': NotEqual. - NotEqual, // UN | LT | GT - OrderedNotEqual, // LT | GT - UnorderedOrEqual, // UN | EQ + /// EQ + Equal, + /// The C '!=' operator is the inverse of '==': `NotEqual`. + /// UN | LT | GT + NotEqual, + /// LT | GT + OrderedNotEqual, + /// UN | EQ + UnorderedOrEqual, - LessThan, // LT - LessThanOrEqual, // LT | EQ - GreaterThan, // GT - GreaterThanOrEqual, // GT | EQ + /// LT + LessThan, + /// LT | EQ + LessThanOrEqual, + /// GT + GreaterThan, + /// GT | EQ + GreaterThanOrEqual, - UnorderedOrLessThan, // UN | LT - UnorderedOrLessThanOrEqual, // UN | LT | EQ - UnorderedOrGreaterThan, // UN | GT - UnorderedOrGreaterThanOrEqual, // UN | GT | EQ + /// UN | LT + UnorderedOrLessThan, + /// UN | LT | EQ + UnorderedOrLessThanOrEqual, + /// UN | GT + UnorderedOrGreaterThan, + /// UN | GT | EQ + UnorderedOrGreaterThanOrEqual, } impl CondCode for FloatCC { diff --git a/lib/cretonne/src/ir/entities.rs b/lib/cretonne/src/ir/entities.rs index bd8913e5bf..384e4d3ae9 100644 --- a/lib/cretonne/src/ir/entities.rs +++ b/lib/cretonne/src/ir/entities.rs @@ -98,16 +98,16 @@ impl Default for Inst { #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] pub struct Value(u32); -// Value references can either reference an instruction directly, or they can refer to the extended -// value table. +/// Value references can either reference an instruction directly, or they can refer to the +/// extended value table. pub enum ExpandedValue { - // This is the first value produced by the referenced instruction. + /// This is the first value produced by the referenced instruction. Direct(Inst), - // This value is described in the extended value table. + /// This value is described in the extended value table. Table(usize), - // This is NO_VALUE. + /// This is NO_VALUE. None, } @@ -135,19 +135,23 @@ impl Value { None } } + /// Create a `Direct` value corresponding to the first value produced by `i`. pub fn new_direct(i: Inst) -> Value { let encoding = i.index() * 2; assert!(encoding < u32::MAX as usize); Value(encoding as u32) } + /// Create a `Table` value referring to entry `i` in the `DataFlowGraph.extended_values` table. + /// This constructor should not be used directly. Use the public `DataFlowGraph` methods to + /// manipulate values. pub fn new_table(index: usize) -> Value { let encoding = index * 2 + 1; assert!(encoding < u32::MAX as usize); Value(encoding as u32) } - // Expand the internal representation into something useful. + /// Expand the internal representation into something useful. pub fn expand(&self) -> ExpandedValue { use self::ExpandedValue::*; if *self == NO_VALUE { @@ -312,12 +316,19 @@ impl Default for SigRef { pub enum AnyEntity { /// The whole function. Function, + /// An extended basic block. Ebb(Ebb), + /// An instruction. Inst(Inst), + /// An SSA value. Value(Value), + /// A stack slot. StackSlot(StackSlot), + /// A jump table. JumpTable(JumpTable), + /// An external function. FuncRef(FuncRef), + /// A function call signature. SigRef(SigRef), } diff --git a/lib/cretonne/src/ir/extfunc.rs b/lib/cretonne/src/ir/extfunc.rs index 6f89d5d307..a47ff4ad7a 100644 --- a/lib/cretonne/src/ir/extfunc.rs +++ b/lib/cretonne/src/ir/extfunc.rs @@ -14,11 +14,14 @@ use ir::{Type, FunctionName, SigRef}; /// details that are needed to call a function correctly. #[derive(Clone, PartialEq, Eq, Debug)] pub struct Signature { + /// Types of the arguments passed to the function. pub argument_types: Vec, + /// Types returned from the function. pub return_types: Vec, } impl Signature { + /// Create a new blank signature. pub fn new() -> Signature { Signature { argument_types: Vec::new(), @@ -59,13 +62,16 @@ impl Display for Signature { /// how the argument is passed. #[derive(Copy, Clone, PartialEq, Eq, Debug)] pub struct ArgumentType { + /// Type of the argument value. pub value_type: Type, + /// Method for extending argument to a full register. pub extension: ArgumentExtension, /// Place this argument in a register if possible. pub inreg: bool, } impl ArgumentType { + /// Create an argument type with default flags. pub fn new(vt: Type) -> ArgumentType { ArgumentType { value_type: vt, @@ -109,7 +115,9 @@ pub enum ArgumentExtension { /// Information about a function that can be called directly with a direct `call` instruction. #[derive(Clone, Debug)] pub struct ExtFuncData { + /// Name of the external function. pub name: FunctionName, + /// Call signature of function. pub signature: SigRef, } diff --git a/lib/cretonne/src/ir/funcname.rs b/lib/cretonne/src/ir/funcname.rs index 0f6f106365..d84b25ac2b 100644 --- a/lib/cretonne/src/ir/funcname.rs +++ b/lib/cretonne/src/ir/funcname.rs @@ -14,6 +14,7 @@ use std::ascii::AsciiExt; pub struct FunctionName(String); impl FunctionName { + /// Create new function name equal to `s`. pub fn new>(s: S) -> FunctionName { FunctionName(s.into()) } diff --git a/lib/cretonne/src/ir/immediates.rs b/lib/cretonne/src/ir/immediates.rs index 0395d13f26..e2fc0c446d 100644 --- a/lib/cretonne/src/ir/immediates.rs +++ b/lib/cretonne/src/ir/immediates.rs @@ -17,6 +17,7 @@ use std::str::FromStr; pub struct Imm64(i64); impl Imm64 { + /// Create a new `Imm64` representing the signed number `x`. pub fn new(x: i64) -> Imm64 { Imm64(x) } @@ -374,6 +375,7 @@ fn parse_float(s: &str, w: u8, t: u8) -> Result { } impl Ieee32 { + /// Create a new `Ieee32` representing the number `x`. pub fn new(x: f32) -> Ieee32 { Ieee32(x) } @@ -403,6 +405,7 @@ impl FromStr for Ieee32 { } impl Ieee64 { + /// Create a new `Ieee64` representing the number `x`. pub fn new(x: f64) -> Ieee64 { Ieee64(x) } diff --git a/lib/cretonne/src/ir/instructions.rs b/lib/cretonne/src/ir/instructions.rs index 103dcd4fe5..f601169beb 100644 --- a/lib/cretonne/src/ir/instructions.rs +++ b/lib/cretonne/src/ir/instructions.rs @@ -93,6 +93,7 @@ impl FromStr for Opcode { /// 16 bytes on 64-bit architectures. If more space is needed to represent an instruction, use a /// `Box` to store the additional information out of line. #[derive(Clone, Debug)] +#[allow(missing_docs)] pub enum InstructionData { Nullary { opcode: Opcode, ty: Type }, Unary { @@ -226,14 +227,17 @@ pub enum InstructionData { pub struct VariableArgs(Vec); impl VariableArgs { + /// Create an empty argument list. pub fn new() -> VariableArgs { VariableArgs(Vec::new()) } + /// Add an argument to the end. pub fn push(&mut self, v: Value) { self.0.push(v) } + /// Check if the list is empty. pub fn is_empty(&self) -> bool { self.0.is_empty() } @@ -276,6 +280,7 @@ impl Default for VariableArgs { /// Payload data for `vconst`. #[derive(Clone, Debug)] pub struct UnaryImmVectorData { + /// Raw vector data. pub imm: ImmVector, } @@ -292,6 +297,7 @@ impl Display for UnaryImmVectorData { /// Payload data for ternary instructions with multiple results, such as `iadd_carry`. #[derive(Clone, Debug)] pub struct TernaryOverflowData { + /// Value arguments. pub args: [Value; 3], } @@ -305,7 +311,9 @@ impl Display for TernaryOverflowData { /// in the allowed InstructionData size. #[derive(Clone, Debug)] pub struct JumpData { + /// Jump destination EBB. pub destination: Ebb, + /// Arguments passed to destination EBB. pub varargs: VariableArgs, } @@ -323,8 +331,11 @@ impl Display for JumpData { /// in the allowed InstructionData size. #[derive(Clone, Debug)] pub struct BranchData { + /// Value argument controlling the branch. pub arg: Value, + /// Branch destination EBB. pub destination: Ebb, + /// Arguments passed to destination EBB. pub varargs: VariableArgs, } @@ -353,6 +364,8 @@ pub struct CallData { pub struct IndirectCallData { /// Callee function. pub arg: Value, + + /// Signature of the callee function. pub sig_ref: SigRef, /// Dynamically sized array containing call argument values. @@ -362,7 +375,7 @@ pub struct IndirectCallData { /// Payload of a return instruction. #[derive(Clone, Debug)] pub struct ReturnData { - // Dynamically sized array containing return values. + /// Dynamically sized array containing return values. pub varargs: VariableArgs, } diff --git a/lib/cretonne/src/isa/mod.rs b/lib/cretonne/src/isa/mod.rs index 67d5a91c29..5705fe3a55 100644 --- a/lib/cretonne/src/isa/mod.rs +++ b/lib/cretonne/src/isa/mod.rs @@ -87,6 +87,7 @@ impl settings::Configurable for Builder { } } +/// Methods that are specialized to a target ISA. pub trait TargetIsa { /// Get the name of this ISA. fn name(&self) -> &'static str; diff --git a/lib/cretonne/src/isa/riscv/mod.rs b/lib/cretonne/src/isa/riscv/mod.rs index cdc49f6973..06a9c890d0 100644 --- a/lib/cretonne/src/isa/riscv/mod.rs +++ b/lib/cretonne/src/isa/riscv/mod.rs @@ -16,6 +16,7 @@ struct Isa { cpumode: &'static [shared_enc_tables::Level1Entry], } +/// Get an ISA builder for creating RISC-V targets. pub fn isa_builder() -> IsaBuilder { IsaBuilder { setup: settings::builder(), diff --git a/lib/cretonne/src/lib.rs b/lib/cretonne/src/lib.rs index ae25157248..aef83bd433 100644 --- a/lib/cretonne/src/lib.rs +++ b/lib/cretonne/src/lib.rs @@ -1,14 +1,12 @@ +//! Cretonne code generation library. -// ====------------------------------------------------------------------------------------==== // -// -// Cretonne code generation library. -// -// ====------------------------------------------------------------------------------------==== // +#![deny(missing_docs)] pub use verifier::verify_function; pub use write::write_function; pub use legalizer::legalize_function; +/// Version number of the cretonne crate. pub const VERSION: &'static str = env!("CARGO_PKG_VERSION"); pub mod ir; diff --git a/lib/cretonne/src/settings.rs b/lib/cretonne/src/settings.rs index 37d09d2ba8..291211b1b3 100644 --- a/lib/cretonne/src/settings.rs +++ b/lib/cretonne/src/settings.rs @@ -144,6 +144,7 @@ pub enum Error { BadValue, } +/// A result returned when changing a setting. pub type Result = result::Result; /// Implementation details for generated code. @@ -156,10 +157,15 @@ pub mod detail { /// An instruction group template. pub struct Template { + /// Name of the instruction group. pub name: &'static str, + /// List of setting descriptors. pub descriptors: &'static [Descriptor], + /// Union of all enumerators. pub enumerators: &'static [&'static str], + /// Hash table of settings. pub hash_table: &'static [u16], + /// Default values. pub defaults: &'static [u8], } @@ -227,7 +233,10 @@ pub mod detail { #[derive(Clone, Copy)] pub enum Detail { /// A boolean setting only uses one bit, numbered from LSB. - Bool { bit: u8 }, + Bool { + /// 0-7. + bit: u8, + }, /// A numerical setting uses the whole byte. Num, diff --git a/lib/cretonne/src/verifier.rs b/lib/cretonne/src/verifier.rs index 2b544967e2..9e044a738a 100644 --- a/lib/cretonne/src/verifier.rs +++ b/lib/cretonne/src/verifier.rs @@ -61,7 +61,9 @@ use std::result; /// A verifier error. #[derive(Debug, PartialEq, Eq)] pub struct Error { + /// The entity causing the verifier error. pub location: AnyEntity, + /// Error message. pub message: String, } @@ -71,6 +73,7 @@ impl Display for Error { } } +/// Verifier result. pub type Result = result::Result; // Create an `Err` variant of `Result` from a location and `format!` args. @@ -90,11 +93,12 @@ macro_rules! err { }; } +/// Verify `func`. pub fn verify_function(func: &Function) -> Result<()> { Verifier::new(func).run() } -pub struct Verifier<'a> { +struct Verifier<'a> { func: &'a Function, } @@ -165,7 +169,7 @@ impl<'a> Verifier<'a> { #[cfg(test)] mod tests { - use super::*; + use super::{Verifier, Error}; use ir::Function; use ir::instructions::{InstructionData, Opcode}; use ir::types;