]> git.lizzy.rs Git - rust.git/blob - src/librustc_codegen_llvm/builder.rs
Rollup merge of #55343 - Keruspe:remap-debuginfo-release, r=alexcrichton
[rust.git] / src / librustc_codegen_llvm / builder.rs
1 // Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 use llvm::{AtomicRmwBinOp, AtomicOrdering, SynchronizationScope, AsmDialect};
12 use llvm::{IntPredicate, RealPredicate, False, OperandBundleDef};
13 use llvm::{self, BasicBlock};
14 use common::*;
15 use type_::Type;
16 use value::Value;
17 use libc::{c_uint, c_char};
18 use rustc::ty::TyCtxt;
19 use rustc::ty::layout::{Align, Size};
20 use rustc::session::{config, Session};
21 use rustc_data_structures::small_c_str::SmallCStr;
22
23 use std::borrow::Cow;
24 use std::ops::Range;
25 use std::ptr;
26
27 // All Builders must have an llfn associated with them
28 #[must_use]
29 pub struct Builder<'a, 'll: 'a, 'tcx: 'll> {
30     pub llbuilder: &'ll mut llvm::Builder<'ll>,
31     pub cx: &'a CodegenCx<'ll, 'tcx>,
32 }
33
34 impl Drop for Builder<'a, 'll, 'tcx> {
35     fn drop(&mut self) {
36         unsafe {
37             llvm::LLVMDisposeBuilder(&mut *(self.llbuilder as *mut _));
38         }
39     }
40 }
41
42 // This is a really awful way to get a zero-length c-string, but better (and a
43 // lot more efficient) than doing str::as_c_str("", ...) every time.
44 fn noname() -> *const c_char {
45     static CNULL: c_char = 0;
46     &CNULL
47 }
48
49 bitflags! {
50     pub struct MemFlags: u8 {
51         const VOLATILE = 1 << 0;
52         const NONTEMPORAL = 1 << 1;
53         const UNALIGNED = 1 << 2;
54     }
55 }
56
57 impl Builder<'a, 'll, 'tcx> {
58     pub fn new_block<'b>(cx: &'a CodegenCx<'ll, 'tcx>, llfn: &'ll Value, name: &'b str) -> Self {
59         let bx = Builder::with_cx(cx);
60         let llbb = unsafe {
61             let name = SmallCStr::new(name);
62             llvm::LLVMAppendBasicBlockInContext(
63                 cx.llcx,
64                 llfn,
65                 name.as_ptr()
66             )
67         };
68         bx.position_at_end(llbb);
69         bx
70     }
71
72     pub fn with_cx(cx: &'a CodegenCx<'ll, 'tcx>) -> Self {
73         // Create a fresh builder from the crate context.
74         let llbuilder = unsafe {
75             llvm::LLVMCreateBuilderInContext(cx.llcx)
76         };
77         Builder {
78             llbuilder,
79             cx,
80         }
81     }
82
83     pub fn build_sibling_block<'b>(&self, name: &'b str) -> Builder<'a, 'll, 'tcx> {
84         Builder::new_block(self.cx, self.llfn(), name)
85     }
86
87     pub fn sess(&self) -> &Session {
88         self.cx.sess()
89     }
90
91     pub fn tcx(&self) -> TyCtxt<'a, 'tcx, 'tcx> {
92         self.cx.tcx
93     }
94
95     pub fn llfn(&self) -> &'ll Value {
96         unsafe {
97             llvm::LLVMGetBasicBlockParent(self.llbb())
98         }
99     }
100
101     pub fn llbb(&self) -> &'ll BasicBlock {
102         unsafe {
103             llvm::LLVMGetInsertBlock(self.llbuilder)
104         }
105     }
106
107     fn count_insn(&self, category: &str) {
108         if self.cx.sess().codegen_stats() {
109             self.cx.stats.borrow_mut().n_llvm_insns += 1;
110         }
111         if self.cx.sess().count_llvm_insns() {
112             *self.cx.stats
113                     .borrow_mut()
114                     .llvm_insns
115                     .entry(category.to_string())
116                     .or_insert(0) += 1;
117         }
118     }
119
120     pub fn set_value_name(&self, value: &'ll Value, name: &str) {
121         let cname = SmallCStr::new(name);
122         unsafe {
123             llvm::LLVMSetValueName(value, cname.as_ptr());
124         }
125     }
126
127     pub fn position_at_end(&self, llbb: &'ll BasicBlock) {
128         unsafe {
129             llvm::LLVMPositionBuilderAtEnd(self.llbuilder, llbb);
130         }
131     }
132
133     pub fn position_at_start(&self, llbb: &'ll BasicBlock) {
134         unsafe {
135             llvm::LLVMRustPositionBuilderAtStart(self.llbuilder, llbb);
136         }
137     }
138
139     pub fn ret_void(&self) {
140         self.count_insn("retvoid");
141         unsafe {
142             llvm::LLVMBuildRetVoid(self.llbuilder);
143         }
144     }
145
146     pub fn ret(&self, v: &'ll Value) {
147         self.count_insn("ret");
148         unsafe {
149             llvm::LLVMBuildRet(self.llbuilder, v);
150         }
151     }
152
153     pub fn br(&self, dest: &'ll BasicBlock) {
154         self.count_insn("br");
155         unsafe {
156             llvm::LLVMBuildBr(self.llbuilder, dest);
157         }
158     }
159
160     pub fn cond_br(
161         &self,
162         cond: &'ll Value,
163         then_llbb: &'ll BasicBlock,
164         else_llbb: &'ll BasicBlock,
165     ) {
166         self.count_insn("condbr");
167         unsafe {
168             llvm::LLVMBuildCondBr(self.llbuilder, cond, then_llbb, else_llbb);
169         }
170     }
171
172     pub fn switch(
173         &self,
174         v: &'ll Value,
175         else_llbb: &'ll BasicBlock,
176         num_cases: usize,
177     ) -> &'ll Value {
178         unsafe {
179             llvm::LLVMBuildSwitch(self.llbuilder, v, else_llbb, num_cases as c_uint)
180         }
181     }
182
183     pub fn invoke(&self,
184                   llfn: &'ll Value,
185                   args: &[&'ll Value],
186                   then: &'ll BasicBlock,
187                   catch: &'ll BasicBlock,
188                   bundle: Option<&OperandBundleDef<'ll>>) -> &'ll Value {
189         self.count_insn("invoke");
190
191         debug!("Invoke {:?} with args ({:?})",
192                llfn,
193                args);
194
195         let args = self.check_call("invoke", llfn, args);
196         let bundle = bundle.map(|b| &*b.raw);
197
198         unsafe {
199             llvm::LLVMRustBuildInvoke(self.llbuilder,
200                                       llfn,
201                                       args.as_ptr(),
202                                       args.len() as c_uint,
203                                       then,
204                                       catch,
205                                       bundle,
206                                       noname())
207         }
208     }
209
210     pub fn unreachable(&self) {
211         self.count_insn("unreachable");
212         unsafe {
213             llvm::LLVMBuildUnreachable(self.llbuilder);
214         }
215     }
216
217     /* Arithmetic */
218     pub fn add(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
219         self.count_insn("add");
220         unsafe {
221             llvm::LLVMBuildAdd(self.llbuilder, lhs, rhs, noname())
222         }
223     }
224
225     pub fn fadd(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
226         self.count_insn("fadd");
227         unsafe {
228             llvm::LLVMBuildFAdd(self.llbuilder, lhs, rhs, noname())
229         }
230     }
231
232     pub fn fadd_fast(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
233         self.count_insn("fadd");
234         unsafe {
235             let instr = llvm::LLVMBuildFAdd(self.llbuilder, lhs, rhs, noname());
236             llvm::LLVMRustSetHasUnsafeAlgebra(instr);
237             instr
238         }
239     }
240
241     pub fn sub(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
242         self.count_insn("sub");
243         unsafe {
244             llvm::LLVMBuildSub(self.llbuilder, lhs, rhs, noname())
245         }
246     }
247
248     pub fn fsub(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
249         self.count_insn("fsub");
250         unsafe {
251             llvm::LLVMBuildFSub(self.llbuilder, lhs, rhs, noname())
252         }
253     }
254
255     pub fn fsub_fast(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
256         self.count_insn("fsub");
257         unsafe {
258             let instr = llvm::LLVMBuildFSub(self.llbuilder, lhs, rhs, noname());
259             llvm::LLVMRustSetHasUnsafeAlgebra(instr);
260             instr
261         }
262     }
263
264     pub fn mul(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
265         self.count_insn("mul");
266         unsafe {
267             llvm::LLVMBuildMul(self.llbuilder, lhs, rhs, noname())
268         }
269     }
270
271     pub fn fmul(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
272         self.count_insn("fmul");
273         unsafe {
274             llvm::LLVMBuildFMul(self.llbuilder, lhs, rhs, noname())
275         }
276     }
277
278     pub fn fmul_fast(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
279         self.count_insn("fmul");
280         unsafe {
281             let instr = llvm::LLVMBuildFMul(self.llbuilder, lhs, rhs, noname());
282             llvm::LLVMRustSetHasUnsafeAlgebra(instr);
283             instr
284         }
285     }
286
287
288     pub fn udiv(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
289         self.count_insn("udiv");
290         unsafe {
291             llvm::LLVMBuildUDiv(self.llbuilder, lhs, rhs, noname())
292         }
293     }
294
295     pub fn exactudiv(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
296         self.count_insn("exactudiv");
297         unsafe {
298             llvm::LLVMBuildExactUDiv(self.llbuilder, lhs, rhs, noname())
299         }
300     }
301
302     pub fn sdiv(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
303         self.count_insn("sdiv");
304         unsafe {
305             llvm::LLVMBuildSDiv(self.llbuilder, lhs, rhs, noname())
306         }
307     }
308
309     pub fn exactsdiv(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
310         self.count_insn("exactsdiv");
311         unsafe {
312             llvm::LLVMBuildExactSDiv(self.llbuilder, lhs, rhs, noname())
313         }
314     }
315
316     pub fn fdiv(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
317         self.count_insn("fdiv");
318         unsafe {
319             llvm::LLVMBuildFDiv(self.llbuilder, lhs, rhs, noname())
320         }
321     }
322
323     pub fn fdiv_fast(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
324         self.count_insn("fdiv");
325         unsafe {
326             let instr = llvm::LLVMBuildFDiv(self.llbuilder, lhs, rhs, noname());
327             llvm::LLVMRustSetHasUnsafeAlgebra(instr);
328             instr
329         }
330     }
331
332     pub fn urem(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
333         self.count_insn("urem");
334         unsafe {
335             llvm::LLVMBuildURem(self.llbuilder, lhs, rhs, noname())
336         }
337     }
338
339     pub fn srem(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
340         self.count_insn("srem");
341         unsafe {
342             llvm::LLVMBuildSRem(self.llbuilder, lhs, rhs, noname())
343         }
344     }
345
346     pub fn frem(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
347         self.count_insn("frem");
348         unsafe {
349             llvm::LLVMBuildFRem(self.llbuilder, lhs, rhs, noname())
350         }
351     }
352
353     pub fn frem_fast(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
354         self.count_insn("frem");
355         unsafe {
356             let instr = llvm::LLVMBuildFRem(self.llbuilder, lhs, rhs, noname());
357             llvm::LLVMRustSetHasUnsafeAlgebra(instr);
358             instr
359         }
360     }
361
362     pub fn shl(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
363         self.count_insn("shl");
364         unsafe {
365             llvm::LLVMBuildShl(self.llbuilder, lhs, rhs, noname())
366         }
367     }
368
369     pub fn lshr(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
370         self.count_insn("lshr");
371         unsafe {
372             llvm::LLVMBuildLShr(self.llbuilder, lhs, rhs, noname())
373         }
374     }
375
376     pub fn ashr(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
377         self.count_insn("ashr");
378         unsafe {
379             llvm::LLVMBuildAShr(self.llbuilder, lhs, rhs, noname())
380         }
381     }
382
383     pub fn and(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
384         self.count_insn("and");
385         unsafe {
386             llvm::LLVMBuildAnd(self.llbuilder, lhs, rhs, noname())
387         }
388     }
389
390     pub fn or(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
391         self.count_insn("or");
392         unsafe {
393             llvm::LLVMBuildOr(self.llbuilder, lhs, rhs, noname())
394         }
395     }
396
397     pub fn xor(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
398         self.count_insn("xor");
399         unsafe {
400             llvm::LLVMBuildXor(self.llbuilder, lhs, rhs, noname())
401         }
402     }
403
404     pub fn neg(&self, v: &'ll Value) -> &'ll Value {
405         self.count_insn("neg");
406         unsafe {
407             llvm::LLVMBuildNeg(self.llbuilder, v, noname())
408         }
409     }
410
411     pub fn fneg(&self, v: &'ll Value) -> &'ll Value {
412         self.count_insn("fneg");
413         unsafe {
414             llvm::LLVMBuildFNeg(self.llbuilder, v, noname())
415         }
416     }
417
418     pub fn not(&self, v: &'ll Value) -> &'ll Value {
419         self.count_insn("not");
420         unsafe {
421             llvm::LLVMBuildNot(self.llbuilder, v, noname())
422         }
423     }
424
425     pub fn alloca(&self, ty: &'ll Type, name: &str, align: Align) -> &'ll Value {
426         let bx = Builder::with_cx(self.cx);
427         bx.position_at_start(unsafe {
428             llvm::LLVMGetFirstBasicBlock(self.llfn())
429         });
430         bx.dynamic_alloca(ty, name, align)
431     }
432
433     pub fn dynamic_alloca(&self, ty: &'ll Type, name: &str, align: Align) -> &'ll Value {
434         self.count_insn("alloca");
435         unsafe {
436             let alloca = if name.is_empty() {
437                 llvm::LLVMBuildAlloca(self.llbuilder, ty, noname())
438             } else {
439                 let name = SmallCStr::new(name);
440                 llvm::LLVMBuildAlloca(self.llbuilder, ty,
441                                       name.as_ptr())
442             };
443             llvm::LLVMSetAlignment(alloca, align.abi() as c_uint);
444             alloca
445         }
446     }
447
448     pub fn array_alloca(&self,
449                         ty: &'ll Type,
450                         len: &'ll Value,
451                         name: &str,
452                         align: Align) -> &'ll Value {
453         self.count_insn("alloca");
454         unsafe {
455             let alloca = if name.is_empty() {
456                 llvm::LLVMBuildArrayAlloca(self.llbuilder, ty, len, noname())
457             } else {
458                 let name = SmallCStr::new(name);
459                 llvm::LLVMBuildArrayAlloca(self.llbuilder, ty, len,
460                                            name.as_ptr())
461             };
462             llvm::LLVMSetAlignment(alloca, align.abi() as c_uint);
463             alloca
464         }
465     }
466
467     pub fn load(&self, ptr: &'ll Value, align: Align) -> &'ll Value {
468         self.count_insn("load");
469         unsafe {
470             let load = llvm::LLVMBuildLoad(self.llbuilder, ptr, noname());
471             llvm::LLVMSetAlignment(load, align.abi() as c_uint);
472             load
473         }
474     }
475
476     pub fn volatile_load(&self, ptr: &'ll Value) -> &'ll Value {
477         self.count_insn("load.volatile");
478         unsafe {
479             let insn = llvm::LLVMBuildLoad(self.llbuilder, ptr, noname());
480             llvm::LLVMSetVolatile(insn, llvm::True);
481             insn
482         }
483     }
484
485     pub fn atomic_load(&self, ptr: &'ll Value, order: AtomicOrdering, align: Align) -> &'ll Value {
486         self.count_insn("load.atomic");
487         unsafe {
488             let load = llvm::LLVMRustBuildAtomicLoad(self.llbuilder, ptr, noname(), order);
489             // FIXME(eddyb) Isn't it UB to use `pref` instead of `abi` here?
490             // However, 64-bit atomic loads on `i686-apple-darwin` appear to
491             // require `___atomic_load` with ABI-alignment, so it's staying.
492             llvm::LLVMSetAlignment(load, align.pref() as c_uint);
493             load
494         }
495     }
496
497
498     pub fn range_metadata(&self, load: &'ll Value, range: Range<u128>) {
499         if self.sess().target.target.arch == "amdgpu" {
500             // amdgpu/LLVM does something weird and thinks a i64 value is
501             // split into a v2i32, halving the bitwidth LLVM expects,
502             // tripping an assertion. So, for now, just disable this
503             // optimization.
504             return;
505         }
506
507         unsafe {
508             let llty = val_ty(load);
509             let v = [
510                 C_uint_big(llty, range.start),
511                 C_uint_big(llty, range.end)
512             ];
513
514             llvm::LLVMSetMetadata(load, llvm::MD_range as c_uint,
515                                   llvm::LLVMMDNodeInContext(self.cx.llcx,
516                                                             v.as_ptr(),
517                                                             v.len() as c_uint));
518         }
519     }
520
521     pub fn nonnull_metadata(&self, load: &'ll Value) {
522         unsafe {
523             llvm::LLVMSetMetadata(load, llvm::MD_nonnull as c_uint,
524                                   llvm::LLVMMDNodeInContext(self.cx.llcx, ptr::null(), 0));
525         }
526     }
527
528     pub fn store(&self, val: &'ll Value, ptr: &'ll Value, align: Align) -> &'ll Value {
529         self.store_with_flags(val, ptr, align, MemFlags::empty())
530     }
531
532     pub fn store_with_flags(
533         &self,
534         val: &'ll Value,
535         ptr: &'ll Value,
536         align: Align,
537         flags: MemFlags,
538     ) -> &'ll Value {
539         debug!("Store {:?} -> {:?} ({:?})", val, ptr, flags);
540         self.count_insn("store");
541         let ptr = self.check_store(val, ptr);
542         unsafe {
543             let store = llvm::LLVMBuildStore(self.llbuilder, val, ptr);
544             let align = if flags.contains(MemFlags::UNALIGNED) {
545                 1
546             } else {
547                 align.abi() as c_uint
548             };
549             llvm::LLVMSetAlignment(store, align);
550             if flags.contains(MemFlags::VOLATILE) {
551                 llvm::LLVMSetVolatile(store, llvm::True);
552             }
553             if flags.contains(MemFlags::NONTEMPORAL) {
554                 // According to LLVM [1] building a nontemporal store must
555                 // *always* point to a metadata value of the integer 1.
556                 //
557                 // [1]: http://llvm.org/docs/LangRef.html#store-instruction
558                 let one = C_i32(self.cx, 1);
559                 let node = llvm::LLVMMDNodeInContext(self.cx.llcx, &one, 1);
560                 llvm::LLVMSetMetadata(store, llvm::MD_nontemporal as c_uint, node);
561             }
562             store
563         }
564     }
565
566     pub fn atomic_store(&self, val: &'ll Value, ptr: &'ll Value,
567                         order: AtomicOrdering, align: Align) {
568         debug!("Store {:?} -> {:?}", val, ptr);
569         self.count_insn("store.atomic");
570         let ptr = self.check_store(val, ptr);
571         unsafe {
572             let store = llvm::LLVMRustBuildAtomicStore(self.llbuilder, val, ptr, order);
573             // FIXME(eddyb) Isn't it UB to use `pref` instead of `abi` here?
574             // Also see `atomic_load` for more context.
575             llvm::LLVMSetAlignment(store, align.pref() as c_uint);
576         }
577     }
578
579     pub fn gep(&self, ptr: &'ll Value, indices: &[&'ll Value]) -> &'ll Value {
580         self.count_insn("gep");
581         unsafe {
582             llvm::LLVMBuildGEP(self.llbuilder, ptr, indices.as_ptr(),
583                                indices.len() as c_uint, noname())
584         }
585     }
586
587     pub fn inbounds_gep(&self, ptr: &'ll Value, indices: &[&'ll Value]) -> &'ll Value {
588         self.count_insn("inboundsgep");
589         unsafe {
590             llvm::LLVMBuildInBoundsGEP(
591                 self.llbuilder, ptr, indices.as_ptr(), indices.len() as c_uint, noname())
592         }
593     }
594
595     pub fn struct_gep(&self, ptr: &'ll Value, idx: u64) -> &'ll Value {
596         self.count_insn("structgep");
597         assert_eq!(idx as c_uint as u64, idx);
598         unsafe {
599             llvm::LLVMBuildStructGEP(self.llbuilder, ptr, idx as c_uint, noname())
600         }
601     }
602
603     /* Casts */
604     pub fn trunc(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
605         self.count_insn("trunc");
606         unsafe {
607             llvm::LLVMBuildTrunc(self.llbuilder, val, dest_ty, noname())
608         }
609     }
610
611     pub fn zext(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
612         self.count_insn("zext");
613         unsafe {
614             llvm::LLVMBuildZExt(self.llbuilder, val, dest_ty, noname())
615         }
616     }
617
618     pub fn sext(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
619         self.count_insn("sext");
620         unsafe {
621             llvm::LLVMBuildSExt(self.llbuilder, val, dest_ty, noname())
622         }
623     }
624
625     pub fn fptoui(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
626         self.count_insn("fptoui");
627         unsafe {
628             llvm::LLVMBuildFPToUI(self.llbuilder, val, dest_ty, noname())
629         }
630     }
631
632     pub fn fptosi(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
633         self.count_insn("fptosi");
634         unsafe {
635             llvm::LLVMBuildFPToSI(self.llbuilder, val, dest_ty,noname())
636         }
637     }
638
639     pub fn uitofp(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
640         self.count_insn("uitofp");
641         unsafe {
642             llvm::LLVMBuildUIToFP(self.llbuilder, val, dest_ty, noname())
643         }
644     }
645
646     pub fn sitofp(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
647         self.count_insn("sitofp");
648         unsafe {
649             llvm::LLVMBuildSIToFP(self.llbuilder, val, dest_ty, noname())
650         }
651     }
652
653     pub fn fptrunc(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
654         self.count_insn("fptrunc");
655         unsafe {
656             llvm::LLVMBuildFPTrunc(self.llbuilder, val, dest_ty, noname())
657         }
658     }
659
660     pub fn fpext(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
661         self.count_insn("fpext");
662         unsafe {
663             llvm::LLVMBuildFPExt(self.llbuilder, val, dest_ty, noname())
664         }
665     }
666
667     pub fn ptrtoint(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
668         self.count_insn("ptrtoint");
669         unsafe {
670             llvm::LLVMBuildPtrToInt(self.llbuilder, val, dest_ty, noname())
671         }
672     }
673
674     pub fn inttoptr(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
675         self.count_insn("inttoptr");
676         unsafe {
677             llvm::LLVMBuildIntToPtr(self.llbuilder, val, dest_ty, noname())
678         }
679     }
680
681     pub fn bitcast(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
682         self.count_insn("bitcast");
683         unsafe {
684             llvm::LLVMBuildBitCast(self.llbuilder, val, dest_ty, noname())
685         }
686     }
687
688     pub fn pointercast(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
689         self.count_insn("pointercast");
690         unsafe {
691             llvm::LLVMBuildPointerCast(self.llbuilder, val, dest_ty, noname())
692         }
693     }
694
695     pub fn intcast(&self, val: &'ll Value, dest_ty: &'ll Type, is_signed: bool) -> &'ll Value {
696         self.count_insn("intcast");
697         unsafe {
698             llvm::LLVMRustBuildIntCast(self.llbuilder, val, dest_ty, is_signed)
699         }
700     }
701
702     /* Comparisons */
703     pub fn icmp(&self, op: IntPredicate, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
704         self.count_insn("icmp");
705         unsafe {
706             llvm::LLVMBuildICmp(self.llbuilder, op as c_uint, lhs, rhs, noname())
707         }
708     }
709
710     pub fn fcmp(&self, op: RealPredicate, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
711         self.count_insn("fcmp");
712         unsafe {
713             llvm::LLVMBuildFCmp(self.llbuilder, op as c_uint, lhs, rhs, noname())
714         }
715     }
716
717     /* Miscellaneous instructions */
718     pub fn empty_phi(&self, ty: &'ll Type) -> &'ll Value {
719         self.count_insn("emptyphi");
720         unsafe {
721             llvm::LLVMBuildPhi(self.llbuilder, ty, noname())
722         }
723     }
724
725     pub fn phi(&self, ty: &'ll Type, vals: &[&'ll Value], bbs: &[&'ll BasicBlock]) -> &'ll Value {
726         assert_eq!(vals.len(), bbs.len());
727         let phi = self.empty_phi(ty);
728         self.count_insn("addincoming");
729         unsafe {
730             llvm::LLVMAddIncoming(phi, vals.as_ptr(),
731                                   bbs.as_ptr(),
732                                   vals.len() as c_uint);
733             phi
734         }
735     }
736
737     pub fn inline_asm_call(&self, asm: *const c_char, cons: *const c_char,
738                            inputs: &[&'ll Value], output: &'ll Type,
739                            volatile: bool, alignstack: bool,
740                            dia: AsmDialect) -> Option<&'ll Value> {
741         self.count_insn("inlineasm");
742
743         let volatile = if volatile { llvm::True }
744                        else        { llvm::False };
745         let alignstack = if alignstack { llvm::True }
746                          else          { llvm::False };
747
748         let argtys = inputs.iter().map(|v| {
749             debug!("Asm Input Type: {:?}", *v);
750             val_ty(*v)
751         }).collect::<Vec<_>>();
752
753         debug!("Asm Output Type: {:?}", output);
754         let fty = Type::func(&argtys[..], output);
755         unsafe {
756             // Ask LLVM to verify that the constraints are well-formed.
757             let constraints_ok = llvm::LLVMRustInlineAsmVerify(fty, cons);
758             debug!("Constraint verification result: {:?}", constraints_ok);
759             if constraints_ok {
760                 let v = llvm::LLVMRustInlineAsm(
761                     fty, asm, cons, volatile, alignstack, dia);
762                 Some(self.call(v, inputs, None))
763             } else {
764                 // LLVM has detected an issue with our constraints, bail out
765                 None
766             }
767         }
768     }
769
770     pub fn call(&self, llfn: &'ll Value, args: &[&'ll Value],
771                 bundle: Option<&OperandBundleDef<'ll>>) -> &'ll Value {
772         self.count_insn("call");
773
774         debug!("Call {:?} with args ({:?})",
775                llfn,
776                args);
777
778         let args = self.check_call("call", llfn, args);
779         let bundle = bundle.map(|b| &*b.raw);
780
781         unsafe {
782             llvm::LLVMRustBuildCall(self.llbuilder, llfn, args.as_ptr(),
783                                     args.len() as c_uint, bundle, noname())
784         }
785     }
786
787     pub fn minnum(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
788         self.count_insn("minnum");
789         unsafe {
790             let instr = llvm::LLVMRustBuildMinNum(self.llbuilder, lhs, rhs);
791             instr.expect("LLVMRustBuildMinNum is not available in LLVM version < 6.0")
792         }
793     }
794     pub fn maxnum(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
795         self.count_insn("maxnum");
796         unsafe {
797             let instr = llvm::LLVMRustBuildMaxNum(self.llbuilder, lhs, rhs);
798             instr.expect("LLVMRustBuildMaxNum is not available in LLVM version < 6.0")
799         }
800     }
801
802     pub fn select(
803         &self, cond: &'ll Value,
804         then_val: &'ll Value,
805         else_val: &'ll Value,
806     ) -> &'ll Value {
807         self.count_insn("select");
808         unsafe {
809             llvm::LLVMBuildSelect(self.llbuilder, cond, then_val, else_val, noname())
810         }
811     }
812
813     #[allow(dead_code)]
814     pub fn va_arg(&self, list: &'ll Value, ty: &'ll Type) -> &'ll Value {
815         self.count_insn("vaarg");
816         unsafe {
817             llvm::LLVMBuildVAArg(self.llbuilder, list, ty, noname())
818         }
819     }
820
821     pub fn extract_element(&self, vec: &'ll Value, idx: &'ll Value) -> &'ll Value {
822         self.count_insn("extractelement");
823         unsafe {
824             llvm::LLVMBuildExtractElement(self.llbuilder, vec, idx, noname())
825         }
826     }
827
828     pub fn insert_element(
829         &self, vec: &'ll Value,
830         elt: &'ll Value,
831         idx: &'ll Value,
832     ) -> &'ll Value {
833         self.count_insn("insertelement");
834         unsafe {
835             llvm::LLVMBuildInsertElement(self.llbuilder, vec, elt, idx, noname())
836         }
837     }
838
839     pub fn shuffle_vector(&self, v1: &'ll Value, v2: &'ll Value, mask: &'ll Value) -> &'ll Value {
840         self.count_insn("shufflevector");
841         unsafe {
842             llvm::LLVMBuildShuffleVector(self.llbuilder, v1, v2, mask, noname())
843         }
844     }
845
846     pub fn vector_splat(&self, num_elts: usize, elt: &'ll Value) -> &'ll Value {
847         unsafe {
848             let elt_ty = val_ty(elt);
849             let undef = llvm::LLVMGetUndef(Type::vector(elt_ty, num_elts as u64));
850             let vec = self.insert_element(undef, elt, C_i32(self.cx, 0));
851             let vec_i32_ty = Type::vector(Type::i32(self.cx), num_elts as u64);
852             self.shuffle_vector(vec, undef, C_null(vec_i32_ty))
853         }
854     }
855
856     pub fn vector_reduce_fadd_fast(&self, acc: &'ll Value, src: &'ll Value) -> &'ll Value {
857         self.count_insn("vector.reduce.fadd_fast");
858         unsafe {
859             // FIXME: add a non-fast math version once
860             // https://bugs.llvm.org/show_bug.cgi?id=36732
861             // is fixed.
862             let instr = llvm::LLVMRustBuildVectorReduceFAdd(self.llbuilder, acc, src)
863                 .expect("LLVMRustBuildVectorReduceFAdd is not available in LLVM version < 5.0");
864             llvm::LLVMRustSetHasUnsafeAlgebra(instr);
865             instr
866         }
867     }
868     pub fn vector_reduce_fmul_fast(&self, acc: &'ll Value, src: &'ll Value) -> &'ll Value {
869         self.count_insn("vector.reduce.fmul_fast");
870         unsafe {
871             // FIXME: add a non-fast math version once
872             // https://bugs.llvm.org/show_bug.cgi?id=36732
873             // is fixed.
874             let instr = llvm::LLVMRustBuildVectorReduceFMul(self.llbuilder, acc, src)
875                 .expect("LLVMRustBuildVectorReduceFMul is not available in LLVM version < 5.0");
876             llvm::LLVMRustSetHasUnsafeAlgebra(instr);
877             instr
878         }
879     }
880     pub fn vector_reduce_add(&self, src: &'ll Value) -> &'ll Value {
881         self.count_insn("vector.reduce.add");
882         unsafe {
883             let instr = llvm::LLVMRustBuildVectorReduceAdd(self.llbuilder, src);
884             instr.expect("LLVMRustBuildVectorReduceAdd is not available in LLVM version < 5.0")
885         }
886     }
887     pub fn vector_reduce_mul(&self, src: &'ll Value) -> &'ll Value {
888         self.count_insn("vector.reduce.mul");
889         unsafe {
890             let instr = llvm::LLVMRustBuildVectorReduceMul(self.llbuilder, src);
891             instr.expect("LLVMRustBuildVectorReduceMul is not available in LLVM version < 5.0")
892         }
893     }
894     pub fn vector_reduce_and(&self, src: &'ll Value) -> &'ll Value {
895         self.count_insn("vector.reduce.and");
896         unsafe {
897             let instr = llvm::LLVMRustBuildVectorReduceAnd(self.llbuilder, src);
898             instr.expect("LLVMRustBuildVectorReduceAnd is not available in LLVM version < 5.0")
899         }
900     }
901     pub fn vector_reduce_or(&self, src: &'ll Value) -> &'ll Value {
902         self.count_insn("vector.reduce.or");
903         unsafe {
904             let instr = llvm::LLVMRustBuildVectorReduceOr(self.llbuilder, src);
905             instr.expect("LLVMRustBuildVectorReduceOr is not available in LLVM version < 5.0")
906         }
907     }
908     pub fn vector_reduce_xor(&self, src: &'ll Value) -> &'ll Value {
909         self.count_insn("vector.reduce.xor");
910         unsafe {
911             let instr = llvm::LLVMRustBuildVectorReduceXor(self.llbuilder, src);
912             instr.expect("LLVMRustBuildVectorReduceXor is not available in LLVM version < 5.0")
913         }
914     }
915     pub fn vector_reduce_fmin(&self, src: &'ll Value) -> &'ll Value {
916         self.count_insn("vector.reduce.fmin");
917         unsafe {
918             let instr = llvm::LLVMRustBuildVectorReduceFMin(self.llbuilder, src, /*NoNaNs:*/ false);
919             instr.expect("LLVMRustBuildVectorReduceFMin is not available in LLVM version < 5.0")
920         }
921     }
922     pub fn vector_reduce_fmax(&self, src: &'ll Value) -> &'ll Value {
923         self.count_insn("vector.reduce.fmax");
924         unsafe {
925             let instr = llvm::LLVMRustBuildVectorReduceFMax(self.llbuilder, src, /*NoNaNs:*/ false);
926             instr.expect("LLVMRustBuildVectorReduceFMax is not available in LLVM version < 5.0")
927         }
928     }
929     pub fn vector_reduce_fmin_fast(&self, src: &'ll Value) -> &'ll Value {
930         self.count_insn("vector.reduce.fmin_fast");
931         unsafe {
932             let instr = llvm::LLVMRustBuildVectorReduceFMin(self.llbuilder, src, /*NoNaNs:*/ true)
933                 .expect("LLVMRustBuildVectorReduceFMin is not available in LLVM version < 5.0");
934             llvm::LLVMRustSetHasUnsafeAlgebra(instr);
935             instr
936         }
937     }
938     pub fn vector_reduce_fmax_fast(&self, src: &'ll Value) -> &'ll Value {
939         self.count_insn("vector.reduce.fmax_fast");
940         unsafe {
941             let instr = llvm::LLVMRustBuildVectorReduceFMax(self.llbuilder, src, /*NoNaNs:*/ true)
942                 .expect("LLVMRustBuildVectorReduceFMax is not available in LLVM version < 5.0");
943             llvm::LLVMRustSetHasUnsafeAlgebra(instr);
944             instr
945         }
946     }
947     pub fn vector_reduce_min(&self, src: &'ll Value, is_signed: bool) -> &'ll Value {
948         self.count_insn("vector.reduce.min");
949         unsafe {
950             let instr = llvm::LLVMRustBuildVectorReduceMin(self.llbuilder, src, is_signed);
951             instr.expect("LLVMRustBuildVectorReduceMin is not available in LLVM version < 5.0")
952         }
953     }
954     pub fn vector_reduce_max(&self, src: &'ll Value, is_signed: bool) -> &'ll Value {
955         self.count_insn("vector.reduce.max");
956         unsafe {
957             let instr = llvm::LLVMRustBuildVectorReduceMax(self.llbuilder, src, is_signed);
958             instr.expect("LLVMRustBuildVectorReduceMax is not available in LLVM version < 5.0")
959         }
960     }
961
962     pub fn extract_value(&self, agg_val: &'ll Value, idx: u64) -> &'ll Value {
963         self.count_insn("extractvalue");
964         assert_eq!(idx as c_uint as u64, idx);
965         unsafe {
966             llvm::LLVMBuildExtractValue(self.llbuilder, agg_val, idx as c_uint, noname())
967         }
968     }
969
970     pub fn insert_value(&self, agg_val: &'ll Value, elt: &'ll Value,
971                        idx: u64) -> &'ll Value {
972         self.count_insn("insertvalue");
973         assert_eq!(idx as c_uint as u64, idx);
974         unsafe {
975             llvm::LLVMBuildInsertValue(self.llbuilder, agg_val, elt, idx as c_uint,
976                                        noname())
977         }
978     }
979
980     pub fn landing_pad(&self, ty: &'ll Type, pers_fn: &'ll Value,
981                        num_clauses: usize) -> &'ll Value {
982         self.count_insn("landingpad");
983         unsafe {
984             llvm::LLVMBuildLandingPad(self.llbuilder, ty, pers_fn,
985                                       num_clauses as c_uint, noname())
986         }
987     }
988
989     pub fn add_clause(&self, landing_pad: &'ll Value, clause: &'ll Value) {
990         unsafe {
991             llvm::LLVMAddClause(landing_pad, clause);
992         }
993     }
994
995     pub fn set_cleanup(&self, landing_pad: &'ll Value) {
996         self.count_insn("setcleanup");
997         unsafe {
998             llvm::LLVMSetCleanup(landing_pad, llvm::True);
999         }
1000     }
1001
1002     pub fn resume(&self, exn: &'ll Value) -> &'ll Value {
1003         self.count_insn("resume");
1004         unsafe {
1005             llvm::LLVMBuildResume(self.llbuilder, exn)
1006         }
1007     }
1008
1009     pub fn cleanup_pad(&self,
1010                        parent: Option<&'ll Value>,
1011                        args: &[&'ll Value]) -> &'ll Value {
1012         self.count_insn("cleanuppad");
1013         let name = const_cstr!("cleanuppad");
1014         let ret = unsafe {
1015             llvm::LLVMRustBuildCleanupPad(self.llbuilder,
1016                                           parent,
1017                                           args.len() as c_uint,
1018                                           args.as_ptr(),
1019                                           name.as_ptr())
1020         };
1021         ret.expect("LLVM does not have support for cleanuppad")
1022     }
1023
1024     pub fn cleanup_ret(
1025         &self, cleanup: &'ll Value,
1026         unwind: Option<&'ll BasicBlock>,
1027     ) -> &'ll Value {
1028         self.count_insn("cleanupret");
1029         let ret = unsafe {
1030             llvm::LLVMRustBuildCleanupRet(self.llbuilder, cleanup, unwind)
1031         };
1032         ret.expect("LLVM does not have support for cleanupret")
1033     }
1034
1035     pub fn catch_pad(&self,
1036                      parent: &'ll Value,
1037                      args: &[&'ll Value]) -> &'ll Value {
1038         self.count_insn("catchpad");
1039         let name = const_cstr!("catchpad");
1040         let ret = unsafe {
1041             llvm::LLVMRustBuildCatchPad(self.llbuilder, parent,
1042                                         args.len() as c_uint, args.as_ptr(),
1043                                         name.as_ptr())
1044         };
1045         ret.expect("LLVM does not have support for catchpad")
1046     }
1047
1048     pub fn catch_ret(&self, pad: &'ll Value, unwind: &'ll BasicBlock) -> &'ll Value {
1049         self.count_insn("catchret");
1050         let ret = unsafe {
1051             llvm::LLVMRustBuildCatchRet(self.llbuilder, pad, unwind)
1052         };
1053         ret.expect("LLVM does not have support for catchret")
1054     }
1055
1056     pub fn catch_switch(
1057         &self,
1058         parent: Option<&'ll Value>,
1059         unwind: Option<&'ll BasicBlock>,
1060         num_handlers: usize,
1061     ) -> &'ll Value {
1062         self.count_insn("catchswitch");
1063         let name = const_cstr!("catchswitch");
1064         let ret = unsafe {
1065             llvm::LLVMRustBuildCatchSwitch(self.llbuilder, parent, unwind,
1066                                            num_handlers as c_uint,
1067                                            name.as_ptr())
1068         };
1069         ret.expect("LLVM does not have support for catchswitch")
1070     }
1071
1072     pub fn add_handler(&self, catch_switch: &'ll Value, handler: &'ll BasicBlock) {
1073         unsafe {
1074             llvm::LLVMRustAddHandler(catch_switch, handler);
1075         }
1076     }
1077
1078     pub fn set_personality_fn(&self, personality: &'ll Value) {
1079         unsafe {
1080             llvm::LLVMSetPersonalityFn(self.llfn(), personality);
1081         }
1082     }
1083
1084     // Atomic Operations
1085     pub fn atomic_cmpxchg(
1086         &self,
1087         dst: &'ll Value,
1088         cmp: &'ll Value,
1089         src: &'ll Value,
1090         order: AtomicOrdering,
1091         failure_order: AtomicOrdering,
1092         weak: llvm::Bool,
1093     ) -> &'ll Value {
1094         unsafe {
1095             llvm::LLVMRustBuildAtomicCmpXchg(self.llbuilder, dst, cmp, src,
1096                                              order, failure_order, weak)
1097         }
1098     }
1099     pub fn atomic_rmw(
1100         &self,
1101         op: AtomicRmwBinOp,
1102         dst: &'ll Value,
1103         src: &'ll Value,
1104         order: AtomicOrdering,
1105     ) -> &'ll Value {
1106         unsafe {
1107             llvm::LLVMBuildAtomicRMW(self.llbuilder, op, dst, src, order, False)
1108         }
1109     }
1110
1111     pub fn atomic_fence(&self, order: AtomicOrdering, scope: SynchronizationScope) {
1112         unsafe {
1113             llvm::LLVMRustBuildAtomicFence(self.llbuilder, order, scope);
1114         }
1115     }
1116
1117     pub fn add_case(&self, s: &'ll Value, on_val: &'ll Value, dest: &'ll BasicBlock) {
1118         unsafe {
1119             llvm::LLVMAddCase(s, on_val, dest)
1120         }
1121     }
1122
1123     pub fn add_incoming_to_phi(&self, phi: &'ll Value, val: &'ll Value, bb: &'ll BasicBlock) {
1124         self.count_insn("addincoming");
1125         unsafe {
1126             llvm::LLVMAddIncoming(phi, &val, &bb, 1 as c_uint);
1127         }
1128     }
1129
1130     pub fn set_invariant_load(&self, load: &'ll Value) {
1131         unsafe {
1132             llvm::LLVMSetMetadata(load, llvm::MD_invariant_load as c_uint,
1133                                   llvm::LLVMMDNodeInContext(self.cx.llcx, ptr::null(), 0));
1134         }
1135     }
1136
1137     /// Returns the ptr value that should be used for storing `val`.
1138     fn check_store<'b>(&self,
1139                        val: &'ll Value,
1140                        ptr: &'ll Value) -> &'ll Value {
1141         let dest_ptr_ty = val_ty(ptr);
1142         let stored_ty = val_ty(val);
1143         let stored_ptr_ty = stored_ty.ptr_to();
1144
1145         assert_eq!(dest_ptr_ty.kind(), llvm::TypeKind::Pointer);
1146
1147         if dest_ptr_ty == stored_ptr_ty {
1148             ptr
1149         } else {
1150             debug!("Type mismatch in store. \
1151                     Expected {:?}, got {:?}; inserting bitcast",
1152                    dest_ptr_ty, stored_ptr_ty);
1153             self.bitcast(ptr, stored_ptr_ty)
1154         }
1155     }
1156
1157     /// Returns the args that should be used for a call to `llfn`.
1158     fn check_call<'b>(&self,
1159                       typ: &str,
1160                       llfn: &'ll Value,
1161                       args: &'b [&'ll Value]) -> Cow<'b, [&'ll Value]> {
1162         let mut fn_ty = val_ty(llfn);
1163         // Strip off pointers
1164         while fn_ty.kind() == llvm::TypeKind::Pointer {
1165             fn_ty = fn_ty.element_type();
1166         }
1167
1168         assert!(fn_ty.kind() == llvm::TypeKind::Function,
1169                 "builder::{} not passed a function, but {:?}", typ, fn_ty);
1170
1171         let param_tys = fn_ty.func_params();
1172
1173         let all_args_match = param_tys.iter()
1174             .zip(args.iter().map(|&v| val_ty(v)))
1175             .all(|(expected_ty, actual_ty)| *expected_ty == actual_ty);
1176
1177         if all_args_match {
1178             return Cow::Borrowed(args);
1179         }
1180
1181         let casted_args: Vec<_> = param_tys.into_iter()
1182             .zip(args.iter())
1183             .enumerate()
1184             .map(|(i, (expected_ty, &actual_val))| {
1185                 let actual_ty = val_ty(actual_val);
1186                 if expected_ty != actual_ty {
1187                     debug!("Type mismatch in function call of {:?}. \
1188                             Expected {:?} for param {}, got {:?}; injecting bitcast",
1189                            llfn, expected_ty, i, actual_ty);
1190                     self.bitcast(actual_val, expected_ty)
1191                 } else {
1192                     actual_val
1193                 }
1194             })
1195             .collect();
1196
1197         Cow::Owned(casted_args)
1198     }
1199
1200     pub fn lifetime_start(&self, ptr: &'ll Value, size: Size) {
1201         self.call_lifetime_intrinsic("llvm.lifetime.start", ptr, size);
1202     }
1203
1204     pub fn lifetime_end(&self, ptr: &'ll Value, size: Size) {
1205         self.call_lifetime_intrinsic("llvm.lifetime.end", ptr, size);
1206     }
1207
1208     /// If LLVM lifetime intrinsic support is enabled (i.e. optimizations
1209     /// on), and `ptr` is nonzero-sized, then extracts the size of `ptr`
1210     /// and the intrinsic for `lt` and passes them to `emit`, which is in
1211     /// charge of generating code to call the passed intrinsic on whatever
1212     /// block of generated code is targeted for the intrinsic.
1213     ///
1214     /// If LLVM lifetime intrinsic support is disabled (i.e.  optimizations
1215     /// off) or `ptr` is zero-sized, then no-op (does not call `emit`).
1216     fn call_lifetime_intrinsic(&self, intrinsic: &str, ptr: &'ll Value, size: Size) {
1217         if self.cx.sess().opts.optimize == config::OptLevel::No {
1218             return;
1219         }
1220
1221         let size = size.bytes();
1222         if size == 0 {
1223             return;
1224         }
1225
1226         let lifetime_intrinsic = self.cx.get_intrinsic(intrinsic);
1227
1228         let ptr = self.pointercast(ptr, Type::i8p(self.cx));
1229         self.call(lifetime_intrinsic, &[C_u64(self.cx, size), ptr], None);
1230     }
1231 }