rustc_codegen_llvm/llvm/
conversions.rs

1//! Conversions from backend-independent data types to/from LLVM FFI types.
2
3use rustc_codegen_ssa::common::{AtomicRmwBinOp, IntPredicate, RealPredicate, TypeKind};
4use rustc_middle::ty::AtomicOrdering;
5use rustc_session::config::DebugInfo;
6use rustc_target::spec::SymbolVisibility;
7
8use crate::llvm;
9
10/// Helper trait for converting backend-independent types to LLVM-specific
11/// types, for FFI purposes.
12///
13/// FIXME(#147327): These trait/method names were chosen to avoid churn in
14/// existing code, but are not great and could probably be made clearer.
15pub(crate) trait FromGeneric<T> {
16    fn from_generic(other: T) -> Self;
17}
18
19/// Helper trait for converting LLVM-specific types to backend-independent
20/// types, for FFI purposes.
21///
22/// FIXME(#147327): These trait/method names were chosen to avoid churn in
23/// existing code, but are not great and could probably be made clearer.
24pub(crate) trait ToGeneric<T> {
25    fn to_generic(&self) -> T;
26}
27
28impl FromGeneric<SymbolVisibility> for llvm::Visibility {
29    fn from_generic(visibility: SymbolVisibility) -> Self {
30        match visibility {
31            SymbolVisibility::Hidden => Self::Hidden,
32            SymbolVisibility::Protected => Self::Protected,
33            SymbolVisibility::Interposable => Self::Default,
34        }
35    }
36}
37
38impl FromGeneric<IntPredicate> for llvm::IntPredicate {
39    fn from_generic(int_pred: IntPredicate) -> Self {
40        match int_pred {
41            IntPredicate::IntEQ => Self::IntEQ,
42            IntPredicate::IntNE => Self::IntNE,
43            IntPredicate::IntUGT => Self::IntUGT,
44            IntPredicate::IntUGE => Self::IntUGE,
45            IntPredicate::IntULT => Self::IntULT,
46            IntPredicate::IntULE => Self::IntULE,
47            IntPredicate::IntSGT => Self::IntSGT,
48            IntPredicate::IntSGE => Self::IntSGE,
49            IntPredicate::IntSLT => Self::IntSLT,
50            IntPredicate::IntSLE => Self::IntSLE,
51        }
52    }
53}
54
55impl FromGeneric<RealPredicate> for llvm::RealPredicate {
56    fn from_generic(real_pred: RealPredicate) -> Self {
57        match real_pred {
58            RealPredicate::RealPredicateFalse => Self::RealPredicateFalse,
59            RealPredicate::RealOEQ => Self::RealOEQ,
60            RealPredicate::RealOGT => Self::RealOGT,
61            RealPredicate::RealOGE => Self::RealOGE,
62            RealPredicate::RealOLT => Self::RealOLT,
63            RealPredicate::RealOLE => Self::RealOLE,
64            RealPredicate::RealONE => Self::RealONE,
65            RealPredicate::RealORD => Self::RealORD,
66            RealPredicate::RealUNO => Self::RealUNO,
67            RealPredicate::RealUEQ => Self::RealUEQ,
68            RealPredicate::RealUGT => Self::RealUGT,
69            RealPredicate::RealUGE => Self::RealUGE,
70            RealPredicate::RealULT => Self::RealULT,
71            RealPredicate::RealULE => Self::RealULE,
72            RealPredicate::RealUNE => Self::RealUNE,
73            RealPredicate::RealPredicateTrue => Self::RealPredicateTrue,
74        }
75    }
76}
77
78impl FromGeneric<AtomicRmwBinOp> for llvm::AtomicRmwBinOp {
79    fn from_generic(op: AtomicRmwBinOp) -> Self {
80        match op {
81            AtomicRmwBinOp::AtomicXchg => Self::AtomicXchg,
82            AtomicRmwBinOp::AtomicAdd => Self::AtomicAdd,
83            AtomicRmwBinOp::AtomicSub => Self::AtomicSub,
84            AtomicRmwBinOp::AtomicAnd => Self::AtomicAnd,
85            AtomicRmwBinOp::AtomicNand => Self::AtomicNand,
86            AtomicRmwBinOp::AtomicOr => Self::AtomicOr,
87            AtomicRmwBinOp::AtomicXor => Self::AtomicXor,
88            AtomicRmwBinOp::AtomicMax => Self::AtomicMax,
89            AtomicRmwBinOp::AtomicMin => Self::AtomicMin,
90            AtomicRmwBinOp::AtomicUMax => Self::AtomicUMax,
91            AtomicRmwBinOp::AtomicUMin => Self::AtomicUMin,
92        }
93    }
94}
95
96impl FromGeneric<AtomicOrdering> for llvm::AtomicOrdering {
97    fn from_generic(ordering: AtomicOrdering) -> Self {
98        match ordering {
99            AtomicOrdering::Relaxed => Self::Monotonic,
100            AtomicOrdering::Acquire => Self::Acquire,
101            AtomicOrdering::Release => Self::Release,
102            AtomicOrdering::AcqRel => Self::AcquireRelease,
103            AtomicOrdering::SeqCst => Self::SequentiallyConsistent,
104        }
105    }
106}
107
108impl FromGeneric<DebugInfo> for llvm::debuginfo::DebugEmissionKind {
109    fn from_generic(kind: DebugInfo) -> Self {
110        // We should be setting LLVM's emission kind to `LineTablesOnly` if
111        // we are compiling with "limited" debuginfo. However, some of the
112        // existing tools relied on slightly more debuginfo being generated than
113        // would be the case with `LineTablesOnly`, and we did not want to break
114        // these tools in a "drive-by fix", without a good idea or plan about
115        // what limited debuginfo should exactly look like. So for now we are
116        // instead adding a new debuginfo option "line-tables-only" so as to
117        // not break anything and to allow users to have 'limited' debug info.
118        //
119        // See https://github.com/rust-lang/rust/issues/60020 for details.
120        match kind {
121            DebugInfo::None => Self::NoDebug,
122            DebugInfo::LineDirectivesOnly => Self::DebugDirectivesOnly,
123            DebugInfo::LineTablesOnly => Self::LineTablesOnly,
124            DebugInfo::Limited | DebugInfo::Full => Self::FullDebug,
125        }
126    }
127}
128
129impl ToGeneric<TypeKind> for llvm::TypeKind {
130    fn to_generic(&self) -> TypeKind {
131        match self {
132            Self::Void => TypeKind::Void,
133            Self::Half => TypeKind::Half,
134            Self::Float => TypeKind::Float,
135            Self::Double => TypeKind::Double,
136            Self::X86_FP80 => TypeKind::X86_FP80,
137            Self::FP128 => TypeKind::FP128,
138            Self::PPC_FP128 => TypeKind::PPC_FP128,
139            Self::Label => TypeKind::Label,
140            Self::Integer => TypeKind::Integer,
141            Self::Function => TypeKind::Function,
142            Self::Struct => TypeKind::Struct,
143            Self::Array => TypeKind::Array,
144            Self::Pointer => TypeKind::Pointer,
145            Self::Vector => TypeKind::Vector,
146            Self::Metadata => TypeKind::Metadata,
147            Self::Token => TypeKind::Token,
148            Self::ScalableVector => TypeKind::ScalableVector,
149            Self::BFloat => TypeKind::BFloat,
150            Self::X86_AMX => TypeKind::X86_AMX,
151        }
152    }
153}