]> git.lizzy.rs Git - rust.git/blob - src/librustc_codegen_ssa/common.rs
Rollup merge of #66045 - mzabaluev:unwrap-infallible, r=dtolnay
[rust.git] / src / librustc_codegen_ssa / common.rs
1 #![allow(non_camel_case_types, non_snake_case)]
2
3 use rustc::session::Session;
4 use rustc::ty::{Ty, TyCtxt};
5 use rustc_errors::struct_span_err;
6 use rustc_span::Span;
7
8 use crate::base;
9 use crate::traits::*;
10 use rustc::middle::lang_items::LangItem;
11 use rustc_hir::def_id::DefId;
12
13 use crate::traits::BuilderMethods;
14 use rustc_hir as hir;
15
16 use rustc_error_codes::*;
17
18 pub enum IntPredicate {
19     IntEQ,
20     IntNE,
21     IntUGT,
22     IntUGE,
23     IntULT,
24     IntULE,
25     IntSGT,
26     IntSGE,
27     IntSLT,
28     IntSLE,
29 }
30
31 #[allow(dead_code)]
32 pub enum RealPredicate {
33     RealPredicateFalse,
34     RealOEQ,
35     RealOGT,
36     RealOGE,
37     RealOLT,
38     RealOLE,
39     RealONE,
40     RealORD,
41     RealUNO,
42     RealUEQ,
43     RealUGT,
44     RealUGE,
45     RealULT,
46     RealULE,
47     RealUNE,
48     RealPredicateTrue,
49 }
50
51 pub enum AtomicRmwBinOp {
52     AtomicXchg,
53     AtomicAdd,
54     AtomicSub,
55     AtomicAnd,
56     AtomicNand,
57     AtomicOr,
58     AtomicXor,
59     AtomicMax,
60     AtomicMin,
61     AtomicUMax,
62     AtomicUMin,
63 }
64
65 pub enum AtomicOrdering {
66     #[allow(dead_code)]
67     NotAtomic,
68     Unordered,
69     Monotonic,
70     // Consume,  // Not specified yet.
71     Acquire,
72     Release,
73     AcquireRelease,
74     SequentiallyConsistent,
75 }
76
77 pub enum SynchronizationScope {
78     // FIXME: figure out if this variant is needed at all.
79     #[allow(dead_code)]
80     Other,
81     SingleThread,
82     CrossThread,
83 }
84
85 #[derive(Copy, Clone, PartialEq, Debug)]
86 pub enum TypeKind {
87     Void,
88     Half,
89     Float,
90     Double,
91     X86_FP80,
92     FP128,
93     PPC_FP128,
94     Label,
95     Integer,
96     Function,
97     Struct,
98     Array,
99     Pointer,
100     Vector,
101     Metadata,
102     X86_MMX,
103     Token,
104 }
105
106 // FIXME(mw): Anything that is produced via DepGraph::with_task() must implement
107 //            the HashStable trait. Normally DepGraph::with_task() calls are
108 //            hidden behind queries, but CGU creation is a special case in two
109 //            ways: (1) it's not a query and (2) CGU are output nodes, so their
110 //            Fingerprints are not actually needed. It remains to be clarified
111 //            how exactly this case will be handled in the red/green system but
112 //            for now we content ourselves with providing a no-op HashStable
113 //            implementation for CGUs.
114 mod temp_stable_hash_impls {
115     use crate::ModuleCodegen;
116     use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
117
118     impl<HCX, M> HashStable<HCX> for ModuleCodegen<M> {
119         fn hash_stable(&self, _: &mut HCX, _: &mut StableHasher) {
120             // do nothing
121         }
122     }
123 }
124
125 pub fn langcall(tcx: TyCtxt<'_>, span: Option<Span>, msg: &str, li: LangItem) -> DefId {
126     tcx.lang_items().require(li).unwrap_or_else(|s| {
127         let msg = format!("{} {}", msg, s);
128         match span {
129             Some(span) => tcx.sess.span_fatal(span, &msg[..]),
130             None => tcx.sess.fatal(&msg[..]),
131         }
132     })
133 }
134
135 // To avoid UB from LLVM, these two functions mask RHS with an
136 // appropriate mask unconditionally (i.e., the fallback behavior for
137 // all shifts). For 32- and 64-bit types, this matches the semantics
138 // of Java. (See related discussion on #1877 and #10183.)
139
140 pub fn build_unchecked_lshift<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
141     bx: &mut Bx,
142     lhs: Bx::Value,
143     rhs: Bx::Value,
144 ) -> Bx::Value {
145     let rhs = base::cast_shift_expr_rhs(bx, hir::BinOpKind::Shl, lhs, rhs);
146     // #1877, #10183: Ensure that input is always valid
147     let rhs = shift_mask_rhs(bx, rhs);
148     bx.shl(lhs, rhs)
149 }
150
151 pub fn build_unchecked_rshift<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
152     bx: &mut Bx,
153     lhs_t: Ty<'tcx>,
154     lhs: Bx::Value,
155     rhs: Bx::Value,
156 ) -> Bx::Value {
157     let rhs = base::cast_shift_expr_rhs(bx, hir::BinOpKind::Shr, lhs, rhs);
158     // #1877, #10183: Ensure that input is always valid
159     let rhs = shift_mask_rhs(bx, rhs);
160     let is_signed = lhs_t.is_signed();
161     if is_signed { bx.ashr(lhs, rhs) } else { bx.lshr(lhs, rhs) }
162 }
163
164 fn shift_mask_rhs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
165     bx: &mut Bx,
166     rhs: Bx::Value,
167 ) -> Bx::Value {
168     let rhs_llty = bx.val_ty(rhs);
169     let shift_val = shift_mask_val(bx, rhs_llty, rhs_llty, false);
170     bx.and(rhs, shift_val)
171 }
172
173 pub fn shift_mask_val<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
174     bx: &mut Bx,
175     llty: Bx::Type,
176     mask_llty: Bx::Type,
177     invert: bool,
178 ) -> Bx::Value {
179     let kind = bx.type_kind(llty);
180     match kind {
181         TypeKind::Integer => {
182             // i8/u8 can shift by at most 7, i16/u16 by at most 15, etc.
183             let val = bx.int_width(llty) - 1;
184             if invert {
185                 bx.const_int(mask_llty, !val as i64)
186             } else {
187                 bx.const_uint(mask_llty, val)
188             }
189         }
190         TypeKind::Vector => {
191             let mask =
192                 shift_mask_val(bx, bx.element_type(llty), bx.element_type(mask_llty), invert);
193             bx.vector_splat(bx.vector_length(mask_llty), mask)
194         }
195         _ => bug!("shift_mask_val: expected Integer or Vector, found {:?}", kind),
196     }
197 }
198
199 pub fn span_invalid_monomorphization_error(a: &Session, b: Span, c: &str) {
200     struct_span_err!(a, b, E0511, "{}", c).emit();
201 }