1747ad3c4Slazypassion //! Result and error types representing the outcome of compiling a function. 2747ad3c4Slazypassion 3ff37c9d8SBenjamin Bouvier use crate::{ir::Function, verifier::VerifierErrors}; 40889323aSSSD use alloc::string::String; 5*2f7dbd61SChris Fallin use regalloc2::checker::CheckerErrors; 6747ad3c4Slazypassion 7747ad3c4Slazypassion /// A compilation error. 8747ad3c4Slazypassion /// 9747ad3c4Slazypassion /// When Cranelift fails to compile a function, it will return one of these error codes. 10a0318f36SChris Fallin #[derive(Debug)] 11747ad3c4Slazypassion pub enum CodegenError { 12747ad3c4Slazypassion /// A list of IR verifier errors. 13747ad3c4Slazypassion /// 14747ad3c4Slazypassion /// This always represents a bug, either in the code that generated IR for Cranelift, or a bug 15747ad3c4Slazypassion /// in Cranelift itself. 1603fdbadfSbjorn3 Verifier(VerifierErrors), 17747ad3c4Slazypassion 18747ad3c4Slazypassion /// An implementation limit was exceeded. 19747ad3c4Slazypassion /// 20747ad3c4Slazypassion /// Cranelift can compile very large and complicated functions, but the [implementation has 21747ad3c4Slazypassion /// limits][limits] that cause compilation to fail when they are exceeded. 22747ad3c4Slazypassion /// 23a92a31d8SAlex Crichton /// [limits]: https://github.com/bytecodealliance/wasmtime/blob/main/cranelift/docs/ir.md#implementation-limits 24747ad3c4Slazypassion ImplLimitExceeded, 25747ad3c4Slazypassion 26747ad3c4Slazypassion /// The code size for the function is too large. 27747ad3c4Slazypassion /// 28747ad3c4Slazypassion /// Different target ISAs may impose a limit on the size of a compiled function. If that limit 29747ad3c4Slazypassion /// is exceeded, compilation fails. 30747ad3c4Slazypassion CodeTooLarge, 312fb7e9f3SPeter Huene 32698dc9c4SBenjamin Bouvier /// Something is not supported by the code generator. This might be an indication that a 33698dc9c4SBenjamin Bouvier /// feature is used without explicitly enabling it, or that something is temporarily 34698dc9c4SBenjamin Bouvier /// unsupported by a given target backend. 35698dc9c4SBenjamin Bouvier Unsupported(String), 36698dc9c4SBenjamin Bouvier 372fb7e9f3SPeter Huene /// A failure to map Cranelift register representation to a DWARF register representation. 382fb7e9f3SPeter Huene #[cfg(feature = "unwind")] 392fb7e9f3SPeter Huene RegisterMappingError(crate::isa::unwind::systemv::RegisterMappingError), 40a0318f36SChris Fallin 41a0318f36SChris Fallin /// Register allocator internal error discovered by the symbolic checker. 42a0318f36SChris Fallin Regalloc(CheckerErrors), 43747ad3c4Slazypassion } 44747ad3c4Slazypassion 45747ad3c4Slazypassion /// A convenient alias for a `Result` that uses `CodegenError` as the error type. 46747ad3c4Slazypassion pub type CodegenResult<T> = Result<T, CodegenError>; 4703fdbadfSbjorn3 4882f3ad4fSbjorn3 // This is manually implementing Error and Display instead of using thiserror to reduce the amount 4982f3ad4fSbjorn3 // of dependencies used by Cranelift. 500889323aSSSD impl core::error::Error for CodegenError { source(&self) -> Option<&(dyn core::error::Error + 'static)>510889323aSSSD fn source(&self) -> Option<&(dyn core::error::Error + 'static)> { 5203fdbadfSbjorn3 match self { 5303fdbadfSbjorn3 CodegenError::Verifier(source) => Some(source), 5403fdbadfSbjorn3 CodegenError::ImplLimitExceeded { .. } 5503fdbadfSbjorn3 | CodegenError::CodeTooLarge { .. } 5603fdbadfSbjorn3 | CodegenError::Unsupported { .. } => None, 5703fdbadfSbjorn3 #[cfg(feature = "unwind")] 5803fdbadfSbjorn3 CodegenError::RegisterMappingError { .. } => None, 59a0318f36SChris Fallin CodegenError::Regalloc(..) => None, 6003fdbadfSbjorn3 } 6103fdbadfSbjorn3 } 6203fdbadfSbjorn3 } 6303fdbadfSbjorn3 640889323aSSSD impl core::fmt::Display for CodegenError { fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result650889323aSSSD fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { 6603fdbadfSbjorn3 match self { 6703fdbadfSbjorn3 CodegenError::Verifier(_) => write!(f, "Verifier errors"), 6803fdbadfSbjorn3 CodegenError::ImplLimitExceeded => write!(f, "Implementation limit exceeded"), 6903fdbadfSbjorn3 CodegenError::CodeTooLarge => write!(f, "Code for function is too large"), 70a0442ea0SHamir Mahal CodegenError::Unsupported(feature) => write!(f, "Unsupported feature: {feature}"), 7103fdbadfSbjorn3 #[cfg(feature = "unwind")] 7203fdbadfSbjorn3 CodegenError::RegisterMappingError(_0) => write!(f, "Register mapping error"), 73a0442ea0SHamir Mahal CodegenError::Regalloc(errors) => write!(f, "Regalloc validation errors: {errors:?}"), 7403fdbadfSbjorn3 } 7503fdbadfSbjorn3 } 7603fdbadfSbjorn3 } 7703fdbadfSbjorn3 7803fdbadfSbjorn3 impl From<VerifierErrors> for CodegenError { from(source: VerifierErrors) -> Self7903fdbadfSbjorn3 fn from(source: VerifierErrors) -> Self { 8003fdbadfSbjorn3 CodegenError::Verifier { 0: source } 8103fdbadfSbjorn3 } 8203fdbadfSbjorn3 } 83ff37c9d8SBenjamin Bouvier 84ff37c9d8SBenjamin Bouvier /// Compilation error, with the accompanying function to help printing it. 85ff37c9d8SBenjamin Bouvier pub struct CompileError<'a> { 86ff37c9d8SBenjamin Bouvier /// Underlying `CodegenError` that triggered the error. 87ff37c9d8SBenjamin Bouvier pub inner: CodegenError, 88ff37c9d8SBenjamin Bouvier /// Function we tried to compile, for display purposes. 89ff37c9d8SBenjamin Bouvier pub func: &'a Function, 90ff37c9d8SBenjamin Bouvier } 91ff37c9d8SBenjamin Bouvier 92ff37c9d8SBenjamin Bouvier // By default, have `CompileError` be displayed as the internal error, and let consumers care if 93ff37c9d8SBenjamin Bouvier // they want to use the func field for adding details. 94ff37c9d8SBenjamin Bouvier impl<'a> core::fmt::Debug for CompileError<'a> { fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result95ff37c9d8SBenjamin Bouvier fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 96ff37c9d8SBenjamin Bouvier self.inner.fmt(f) 97ff37c9d8SBenjamin Bouvier } 98ff37c9d8SBenjamin Bouvier } 99ff37c9d8SBenjamin Bouvier 100ff37c9d8SBenjamin Bouvier /// A convenient alias for a `Result` that uses `CompileError` as the error type. 101ff37c9d8SBenjamin Bouvier pub type CompileResult<'a, T> = Result<T, CompileError<'a>>; 102