1use crate::context::Context;
2use crate::llvm::global::Global;
3use crate::llvm::types::LLVMType;
4use crate::llvm::value::array::ArrayValue;
5use crate::llvm::value::bool::BoolValue;
6use crate::llvm::value::fucntion::FunctionValue;
7use crate::llvm::value::pointer::PointerValue;
8use crate::llvm::value::pstruct::StructValue;
9use crate::llvm::value::reference::ReferenceValue;
10use crate::llvm::value::LLVMValue;
11use llvm_sys::core::{
12 LLVMBuildAdd, LLVMBuildAlloca, LLVMBuildAnd, LLVMBuildArrayAlloca, LLVMBuildBr, LLVMBuildCall2,
13 LLVMBuildCondBr, LLVMBuildExtractValue, LLVMBuildFAdd, LLVMBuildFMul, LLVMBuildFNeg,
14 LLVMBuildGEP2, LLVMBuildGlobalString, LLVMBuildGlobalStringPtr, LLVMBuildICmp,
15 LLVMBuildInBoundsGEP2, LLVMBuildInsertValue, LLVMBuildLoad2, LLVMBuildMul, LLVMBuildNeg,
16 LLVMBuildNot, LLVMBuildOr, LLVMBuildRet, LLVMBuildRetVoid, LLVMBuildSDiv, LLVMBuildStore,
17 LLVMBuildStructGEP2, LLVMBuildSub, LLVMBuildUnreachable, LLVMBuildZExt, LLVMConstArray2,
18 LLVMConstIntToPtr, LLVMDisposeBuilder, LLVMGetArrayLength2, LLVMInt8Type, LLVMPointerType,
19 LLVMPositionBuilderAtEnd,
20};
21use llvm_sys::prelude::{LLVMBasicBlockRef, LLVMBuilderRef, LLVMValueRef};
22use llvm_sys::LLVMIntPredicate::{
23 LLVMIntEQ, LLVMIntNE, LLVMIntSGE, LLVMIntSGT, LLVMIntSLE, LLVMIntSLT,
24};
25use std::cell::RefCell;
26use std::collections::HashMap;
27use std::ffi::{c_uint, CString};
28
29#[derive(Clone, Debug)]
30pub struct IRBuilder {
31 inner: LLVMBuilderRef,
32 strings: RefCell<HashMap<String, LLVMValue>>,
33 }
37unsafe impl Send for IRBuilder {}
38unsafe impl Sync for IRBuilder {}
39impl IRBuilder {
40 pub(crate) fn new(builder: LLVMBuilderRef) -> Self {
41 Self {
42 inner: builder,
43 strings: HashMap::new().into(),
44 }
45 }
46
47 pub fn get_llvm_builder(&self) -> LLVMBuilderRef {
48 self.inner
49 }
50
51 pub fn build_return_void(&self) {
52 unsafe {
53 LLVMBuildRetVoid(self.inner);
54 }
55 }
56 pub fn build_return(&self, value: LLVMValue) {
57 if value.is_unit() {
58 self.build_return_void();
59 return;
60 }
61 unsafe {
62 LLVMBuildRet(self.inner, value.as_llvm_value_ref());
63 }
64 }
65
66 pub fn build_global_string_ptr(
67 &self,
68 name: impl AsRef<str>,
69 value: impl AsRef<str>,
70 ) -> LLVMValue {
71 let name = name.as_ref();
72 let name = CString::new(name).unwrap();
73 let str = value.as_ref();
74 let str = CString::new(str).unwrap();
75 let r = unsafe { LLVMBuildGlobalStringPtr(self.inner, str.as_ptr(), name.as_ptr()) };
76 r.into()
77 }
78 pub fn build_global_string(&self, name: impl AsRef<str>, value: impl AsRef<str>) -> LLVMValue {
79 let name0 = name.as_ref();
80 let name = CString::new(name0).unwrap();
81 let str0 = value.as_ref();
82 if self.strings.borrow().contains_key(str0) {
83 return self.strings.borrow().get(str0).unwrap().clone();
84 }
85 let str = CString::new(str0).unwrap();
86 let r = unsafe { LLVMBuildGlobalString(self.inner, str.as_ptr(), name.as_ptr()) };
87 let s = LLVMValue::String(r);
88 self.strings
89 .borrow_mut()
90 .insert(str0.to_string(), s.clone());
91 s
92 }
93 pub fn build_alloca(&self, name: impl AsRef<str>, ty: &LLVMType) -> LLVMValue {
94 let name0 = name.as_ref();
95 let name = CString::new(name0).unwrap();
96 let local = unsafe { LLVMBuildAlloca(self.inner, ty.as_llvm_type_ref(), name.as_ptr()) };
97 LLVMValue::Reference(ReferenceValue::new(local, ty.get_undef()))
98 }
99
100 pub fn build_array(&self, el_ty: LLVMType, arr: Vec<LLVMValue>) -> LLVMValue {
101 let name = CString::new("").unwrap();
102 let array_address = unsafe {
103 LLVMBuildArrayAlloca(
104 self.inner,
105 el_ty.as_llvm_type_ref(),
106 Global::const_i64(arr.len() as i64).get_reference(),
107 name.as_ptr(),
108 )
109 };
110 let mut constant_vals = arr
111 .iter()
112 .map(|v| v.as_llvm_value_ref())
113 .collect::<Vec<_>>();
114 let constant_array = unsafe {
115 LLVMConstArray2(
116 el_ty.as_llvm_type_ref(),
117 constant_vals.as_mut_ptr(),
118 arr.len() as u64,
119 )
120 };
121 unsafe {
122 LLVMBuildStore(self.inner, constant_array, array_address);
123 }
124 LLVMValue::Array(ArrayValue::new(array_address, el_ty, arr.len()))
125 }
126 pub fn build_struct_get(&self, val: &StructValue, idx: usize) -> LLVMValue {
127 let name = CString::new("").unwrap();
128 let r = unsafe {
129 LLVMBuildExtractValue(
130 self.inner,
131 val.get_reference(),
132 idx as c_uint,
133 name.as_ptr(),
134 )
135 };
136 let field_type = val.simply_get_field_by_index(idx).unwrap();
137 match field_type {
138 LLVMValue::String(_) => LLVMValue::String(r),
139 LLVMValue::Struct(mut v) => {
140 v.set_reference(r);
141 v.into()
142 }
143 LLVMValue::Pointer(pointer_value) => {
144 let mut pointer_value = pointer_value.clone();
145 pointer_value.set_reference(r);
146 pointer_value.into()
147 }
148 LLVMValue::Function(f) => {
149 let mut function_value = f.clone();
150 function_value.set_reference(r);
151 function_value.into()
152 }
153 LLVMValue::Reference(reference_value) => {
154 let mut reference_value = reference_value.clone();
155 reference_value.set_reference(r);
156 reference_value.into()
157 }
158 _ => r.into(),
159 }
160 }
161
162 pub fn build_struct_insert(&self, val: LLVMValue, idx: usize, value: &LLVMValue) -> LLVMValue {
163 let name = CString::new("").unwrap();
164 let new_struct = unsafe {
165 LLVMBuildInsertValue(
166 self.inner,
167 val.as_llvm_value_ref(),
168 value.as_llvm_value_ref(),
169 idx as c_uint,
170 name.as_ptr(),
171 )
172 };
173 let struct_value = val.as_struct().unwrap();
174 LLVMValue::Struct(struct_value.with_field(new_struct, idx, value.clone()))
175 }
176 pub fn build_i64_to_ptr(&self, val: LLVMValue) -> LLVMValue {
177 let target = unsafe { LLVMPointerType(LLVMInt8Type(), 0) };
178 unsafe { LLVMConstIntToPtr(val.as_llvm_value_ref(), target) }.into()
179 }
180 pub fn build_struct_gep(&self, ty: &LLVMType, val: LLVMValue, idx: usize) -> LLVMValue {
181 let name = CString::new("").unwrap();
182 let r = unsafe {
183 LLVMBuildStructGEP2(
184 self.inner,
185 ty.as_llvm_type_ref(),
186 val.as_llvm_value_ref(),
187 idx as c_uint,
188 name.as_ptr(),
189 )
190 };
191 let ty = ty.get_struct_field_type(idx);
192 match &ty {
193 LLVMType::String(_) => ReferenceValue::new(r, ty.get_undef()).into(),
194 LLVMType::Struct(_, _, _) => ReferenceValue::new(r, ty.get_undef()).into(),
195 LLVMType::Pointer(element_type, _) => {
196 ReferenceValue::new(r, element_type.get_undef()).into()
197 }
198 LLVMType::Function(_, _, _) => ReferenceValue::new(r, ty.get_undef()).into(),
199 LLVMType::Ref(element_type, _) => {
200 ReferenceValue::new(r, element_type.get_undef()).into()
201 }
202 _ => ReferenceValue::new(r, ty.get_undef()).into(),
203 }
204 }
205 pub fn build_unreachable(&self) {
206 unsafe {
207 LLVMBuildUnreachable(self.inner);
208 }
209 }
210 pub fn build_store(&self, ptr: LLVMValueRef, val: LLVMValue) {
211 unsafe { LLVMBuildStore(self.inner, val.as_llvm_value_ref(), ptr) };
212 }
213 pub fn build_load(&self, ty: LLVMType, ptr: LLVMValueRef) -> LLVMValue {
214 let name = CString::new("").unwrap();
215 let val = unsafe {
216 LLVMBuildLoad2(
217 self.inner,
218 ty.as_llvm_type_ref(), ptr,
220 name.as_ptr(),
221 )
222 };
223 unsafe {
224 match ty {
225 LLVMType::Pointer(_, _) => PointerValue::new(val, ty.get_undef()).into(),
226 LLVMType::String(_) => LLVMValue::String(val),
227 LLVMType::Array(element_type, array_type) => {
228 let length = LLVMGetArrayLength2(array_type);
229 ArrayValue::new(val, *element_type, length as usize).into()
230 }
231 LLVMType::Struct(name, fields, _) => {
232 let mut field_index = HashMap::new();
233 for (i, (name, _)) in fields.iter().enumerate() {
234 field_index.insert(name.clone(), i);
235 }
236 StructValue::new(
237 val,
238 name,
239 field_index,
240 fields.iter().map(|(_, ty)| ty.get_undef()).collect(),
241 )
242 .into()
243 }
244 _ => val.into(),
245 }
246 }
247 }
248 pub fn build_array_get(&self, ty: LLVMType, ptr: LLVMValue, index: LLVMValue) -> LLVMValue {
249 let name = CString::new("").unwrap();
251 let mut indices = [index.as_llvm_value_ref()];
252 let r = unsafe {
253 let ptr0 = LLVMBuildGEP2(
254 self.inner,
255 ty.as_llvm_type_ref(),
256 ptr.as_llvm_value_ref(),
257 indices.as_mut_ptr(),
258 1,
259 name.as_ptr(),
260 );
261 LLVMBuildLoad2(self.inner, ty.as_llvm_type_ref(), ptr0, name.as_ptr())
262 };
263 r.into()
264 }
265 pub fn build_array_get_in_bounds(
266 &self,
267 ty: LLVMType,
268 ptr: LLVMValue,
269 index: LLVMValue,
270 ) -> LLVMValue {
271 let name = CString::new("").unwrap();
273 let mut indices = [index.as_llvm_value_ref()];
274 let r = unsafe {
275 let ptr0 = LLVMBuildInBoundsGEP2(
276 self.inner,
277 ty.as_llvm_type_ref(),
278 ptr.as_llvm_value_ref(),
279 indices.as_mut_ptr(),
280 1,
281 name.as_ptr(),
282 );
283 LLVMBuildLoad2(self.inner, ty.as_llvm_type_ref(), ptr0, name.as_ptr())
284 };
285 match ty {
286 LLVMType::Pointer(_, _) => PointerValue::new(r, ty.get_undef()).into(),
287 LLVMType::String(_) => LLVMValue::String(r),
288 _ => r.into(),
289 }
290 }
291 pub fn build_array_gep(&self, ty: LLVMType, ptr: LLVMValue, index: LLVMValue) -> LLVMValue {
292 let name = CString::new("").unwrap();
294 let mut indices = [index.as_llvm_value_ref()];
295 let r = unsafe {
296 LLVMBuildGEP2(
297 self.inner,
298 ty.as_llvm_type_ref(),
299 ptr.as_llvm_value_ref(),
300 indices.as_mut_ptr(),
301 1,
302 name.as_ptr(),
303 )
304 };
305 ReferenceValue::new(r, ty.get_undef()).into()
306 }
307 pub fn position_at_end(&self, block: LLVMBasicBlockRef) {
308 unsafe { LLVMPositionBuilderAtEnd(self.inner, block) };
309 }
310 pub fn build_br(&self, block: LLVMBasicBlockRef) {
311 unsafe { LLVMBuildBr(self.inner, block) };
312 }
313 pub fn build_cond_br(
314 &self,
315 condition: &BoolValue,
316 then_block: LLVMBasicBlockRef,
317 else_block: LLVMBasicBlockRef,
318 ) {
319 unsafe {
320 LLVMBuildCondBr(
321 self.inner,
322 condition.get_reference(),
323 then_block,
324 else_block,
325 );
326 }
327 }
328
329 pub fn build_add(&self, l: LLVMValue, r: LLVMValue) -> LLVMValue {
330 let name = CString::new("").unwrap();
331 let r = unsafe {
332 LLVMBuildAdd(
333 self.inner,
334 l.as_llvm_value_ref(),
335 r.as_llvm_value_ref(),
336 name.as_ptr(),
337 )
338 };
339 let r = r.into();
340 r
341 }
342 pub fn build_fadd(&self, l: LLVMValue, r: LLVMValue) -> LLVMValue {
343 let name = CString::new("").unwrap();
344 unsafe {
345 LLVMBuildFAdd(
346 self.inner,
347 l.as_llvm_value_ref(),
348 r.as_llvm_value_ref(),
349 name.as_ptr(),
350 )
351 }
352 .into()
353 }
354 pub fn build_fmul(&self, l: LLVMValue, r: LLVMValue) -> LLVMValue {
355 let name = CString::new("").unwrap();
356 unsafe {
357 LLVMBuildFMul(
358 self.inner,
359 l.as_llvm_value_ref(),
360 r.as_llvm_value_ref(),
361 name.as_ptr(),
362 )
363 }
364 .into()
365 }
366 pub fn build_mul(&self, l: LLVMValue, r: LLVMValue) -> LLVMValue {
367 let name = CString::new("").unwrap();
368 let r = unsafe {
369 LLVMBuildMul(
370 self.inner,
371 l.as_llvm_value_ref(),
372 r.as_llvm_value_ref(),
373 name.as_ptr(),
374 )
375 };
376 r.into()
377 }
378 pub fn build_sub(&self, l: LLVMValue, r: LLVMValue) -> LLVMValue {
379 let name = CString::new("").unwrap();
380 let r = unsafe {
381 LLVMBuildSub(
382 self.inner,
383 l.as_llvm_value_ref(),
384 r.as_llvm_value_ref(),
385 name.as_ptr(),
386 )
387 };
388 r.into()
389 }
390 pub fn build_div(&self, l: LLVMValueRef, r: LLVMValueRef) -> LLVMValue {
391 let name = CString::new("").unwrap();
392 unsafe { LLVMBuildSDiv(self.inner, l, r, name.as_ptr()) }.into()
393 }
394 pub fn build_fsub(&self, l: LLVMValue, r: LLVMValue) -> LLVMValue {
395 let name = CString::new("").unwrap();
396 unsafe {
397 llvm_sys::core::LLVMBuildFSub(
398 self.inner,
399 l.as_llvm_value_ref(),
400 r.as_llvm_value_ref(),
401 name.as_ptr(),
402 )
403 }
404 .into()
405 }
406 pub fn build_fdiv(&self, l: LLVMValue, r: LLVMValue) -> LLVMValue {
407 let name = CString::new("").unwrap();
408 unsafe {
409 llvm_sys::core::LLVMBuildFDiv(
410 self.inner,
411 l.as_llvm_value_ref(),
412 r.as_llvm_value_ref(),
413 name.as_ptr(),
414 )
415 }
416 .into()
417 }
418 pub fn build_si_to_fp(&self, val: LLVMValue, dest_ty: LLVMType) -> LLVMValue {
419 let name = CString::new("").unwrap();
420 unsafe {
421 llvm_sys::core::LLVMBuildSIToFP(
422 self.inner,
423 val.as_llvm_value_ref(),
424 dest_ty.as_llvm_type_ref(),
425 name.as_ptr(),
426 )
427 }
428 .into()
429 }
430 pub fn build_fp_to_si(&self, val: LLVMValue, dest_ty: LLVMType) -> LLVMValue {
431 let name = CString::new("").unwrap();
432 unsafe {
433 llvm_sys::core::LLVMBuildFPToSI(
434 self.inner,
435 val.as_llvm_value_ref(),
436 dest_ty.as_llvm_type_ref(),
437 name.as_ptr(),
438 )
439 }
440 .into()
441 }
442 pub fn build_eq(&self, l: LLVMValueRef, r: LLVMValueRef) -> BoolValue {
443 let name = CString::new("").unwrap();
444 let r = unsafe { LLVMBuildICmp(self.inner, LLVMIntEQ, l, r, name.as_ptr()) };
445 BoolValue::new(r)
446 }
447 pub fn build_neq(&self, l: LLVMValue, r: LLVMValue) -> LLVMValue {
448 let name = CString::new("").unwrap();
449 unsafe {
450 LLVMBuildICmp(
451 self.inner,
452 LLVMIntNE,
453 l.as_llvm_value_ref(),
454 r.as_llvm_value_ref(),
455 name.as_ptr(),
456 )
457 }
458 .into()
459 }
460 pub fn build_greater(&self, l: LLVMValue, r: LLVMValue) -> LLVMValue {
461 let name = CString::new("").unwrap();
462 unsafe {
463 LLVMBuildICmp(
464 self.inner,
465 LLVMIntSGT,
466 l.as_llvm_value_ref(),
467 r.as_llvm_value_ref(),
468 name.as_ptr(),
469 )
470 }
471 .into()
472 }
473 pub fn build_less(&self, l: LLVMValue, r: LLVMValue) -> LLVMValue {
474 let name = CString::new("").unwrap();
475 unsafe {
476 LLVMBuildICmp(
477 self.inner,
478 LLVMIntSLT,
479 l.as_llvm_value_ref(),
480 r.as_llvm_value_ref(),
481 name.as_ptr(),
482 )
483 }
484 .into()
485 }
486 pub fn build_call(
487 &self,
488 ctx: &Context,
489 function: &FunctionValue,
490 params: &mut [LLVMValue],
491 var_name: impl AsRef<str>,
492 ) -> LLVMValue {
493 let dec = function
494 .get_llvm_type(ctx)
495 .get_element_type()
496 .as_llvm_type_ref();
497 let var_name = CString::new(var_name.as_ref()).unwrap();
498 let mut params = params
499 .iter()
500 .map(|e| e.as_llvm_value_ref())
501 .collect::<Vec<LLVMValueRef>>();
502 let call_res = unsafe {
503 LLVMBuildCall2(
504 self.inner,
505 dec,
506 function.get_reference(),
507 params.as_mut_ptr(),
508 params.len() as c_uint,
509 var_name.as_ptr(),
510 )
511 };
512 let return_value = function.get_return_value();
513 if return_value.is_struct() {
514 let mut struct_value = return_value.as_struct().unwrap().clone();
515 struct_value.set_reference(call_res);
516 return struct_value.clone().into();
517 }
518 match return_value {
519 LLVMValue::String(_) => LLVMValue::String(call_res),
520 LLVMValue::Pointer(pointer_value) => {
521 let mut pointer_value = pointer_value.clone();
522 pointer_value.set_reference(call_res);
523 pointer_value.into()
524 }
525 LLVMValue::Struct(mut v) => {
526 v.set_reference(call_res);
527 v.into()
528 }
529 _ => call_res.into(),
530 }
531 }
532 pub fn build_call_fn_ptr(
533 &self,
534 fn_type: LLVMType,
535 ptr: LLVMValue,
536 params: &mut [LLVMValue],
537 var_name: impl AsRef<str>,
538 ) -> LLVMValue {
539 let name = CString::new(var_name.as_ref()).unwrap();
540 let mut params = params
541 .iter()
542 .map(|e| e.as_llvm_value_ref())
543 .collect::<Vec<LLVMValueRef>>();
544 unsafe {
545 LLVMBuildCall2(
546 self.inner,
547 fn_type.as_llvm_type_ref(),
548 ptr.as_llvm_value_ref(),
549 params.as_mut_ptr(),
550 params.len() as c_uint,
551 name.as_ptr(),
552 )
553 }
554 .into()
555 }
556 pub fn build_zext(&self, value: LLVMValue, ty: LLVMType) -> LLVMValue {
557 let name = CString::new("").unwrap();
558 unsafe {
559 LLVMBuildZExt(
560 self.inner,
561 value.as_llvm_value_ref(),
562 ty.as_llvm_type_ref(),
563 name.as_ptr(),
564 )
565 }
566 .into()
567 }
568 pub fn build_extract_value(&self, ctx: &Context, val: &StructValue, idx: usize) -> LLVMValue {
569 let name = CString::new("").unwrap();
570 let r = unsafe {
571 LLVMBuildExtractValue(
572 self.inner,
573 val.get_reference(),
574 idx as c_uint,
575 name.as_ptr(),
576 )
577 };
578
579 let field_type = val.get_field_by_index(ctx, idx).unwrap();
580 match field_type {
581 LLVMValue::String(_) => LLVMValue::String(r),
582 LLVMValue::Struct(mut v) => {
583 v.set_reference(r);
584 v.into()
585 }
586 LLVMValue::Pointer(pointer_value) => {
587 let mut pointer_value = pointer_value.clone();
588 pointer_value.set_reference(r);
589 pointer_value.into()
590 }
591 LLVMValue::Function(f) => {
592 let mut function_value = f.clone();
593 function_value.set_reference(r);
594 function_value.into()
595 }
596 _ => r.into(),
597 }
598 }
599 pub fn build_less_equal(&self, l: LLVMValue, r: LLVMValue) -> LLVMValue {
600 let name = CString::new("").unwrap();
601 unsafe {
602 LLVMBuildICmp(
603 self.inner,
604 LLVMIntSLE,
605 l.as_llvm_value_ref(),
606 r.as_llvm_value_ref(),
607 name.as_ptr(),
608 )
609 }
610 .into()
611 }
612
613 pub fn build_greater_equal(&self, l: LLVMValue, r: LLVMValue) -> LLVMValue {
614 let name = CString::new("").unwrap();
615 unsafe {
616 LLVMBuildICmp(
617 self.inner,
618 LLVMIntSGE,
619 l.as_llvm_value_ref(),
620 r.as_llvm_value_ref(),
621 name.as_ptr(),
622 )
623 }
624 .into()
625 }
626
627 pub fn build_and(&self, l: LLVMValue, r: LLVMValue) -> LLVMValue {
628 let name = CString::new("").unwrap();
629 unsafe {
630 LLVMBuildAnd(
631 self.inner,
632 l.as_llvm_value_ref(),
633 r.as_llvm_value_ref(),
634 name.as_ptr(),
635 )
636 }
637 .into()
638 }
639
640 pub fn build_or(&self, l: LLVMValue, r: LLVMValue) -> LLVMValue {
641 let name = CString::new("").unwrap();
642 unsafe {
643 LLVMBuildOr(
644 self.inner,
645 l.as_llvm_value_ref(),
646 r.as_llvm_value_ref(),
647 name.as_ptr(),
648 )
649 }
650 .into()
651 }
652
653 pub fn build_fneg(&self, val: LLVMValue) -> LLVMValue {
654 let name = CString::new("").unwrap();
655 unsafe { LLVMBuildFNeg(self.inner, val.as_llvm_value_ref(), name.as_ptr()) }.into()
656 }
657
658 pub fn build_neg(&self, val: LLVMValue) -> LLVMValue {
659 let name = CString::new("").unwrap();
660 unsafe { LLVMBuildNeg(self.inner, val.as_llvm_value_ref(), name.as_ptr()) }.into()
661 }
662
663 pub fn build_fcmp(
664 &self,
665 pred: llvm_sys::LLVMRealPredicate,
666 l: LLVMValue,
667 r: LLVMValue,
668 ) -> LLVMValue {
669 let name = CString::new("").unwrap();
670 unsafe {
671 llvm_sys::core::LLVMBuildFCmp(
672 self.inner,
673 pred,
674 l.as_llvm_value_ref(),
675 r.as_llvm_value_ref(),
676 name.as_ptr(),
677 )
678 }
679 .into()
680 }
681
682 pub fn build_fcmp_oeq(&self, l: LLVMValue, r: LLVMValue) -> LLVMValue {
683 self.build_fcmp(llvm_sys::LLVMRealPredicate::LLVMRealOEQ, l, r)
684 }
685
686 pub fn build_fcmp_one(&self, l: LLVMValue, r: LLVMValue) -> LLVMValue {
687 self.build_fcmp(llvm_sys::LLVMRealPredicate::LLVMRealONE, l, r)
688 }
689
690 pub fn build_fcmp_ogt(&self, l: LLVMValue, r: LLVMValue) -> LLVMValue {
691 self.build_fcmp(llvm_sys::LLVMRealPredicate::LLVMRealOGT, l, r)
692 }
693
694 pub fn build_fcmp_oge(&self, l: LLVMValue, r: LLVMValue) -> LLVMValue {
695 self.build_fcmp(llvm_sys::LLVMRealPredicate::LLVMRealOGE, l, r)
696 }
697
698 pub fn build_fcmp_olt(&self, l: LLVMValue, r: LLVMValue) -> LLVMValue {
699 self.build_fcmp(llvm_sys::LLVMRealPredicate::LLVMRealOLT, l, r)
700 }
701
702 pub fn build_fcmp_ole(&self, l: LLVMValue, r: LLVMValue) -> LLVMValue {
703 self.build_fcmp(llvm_sys::LLVMRealPredicate::LLVMRealOLE, l, r)
704 }
705
706 pub fn build_not(&self, val: LLVMValue) -> LLVMValue {
707 let name = CString::new("").unwrap();
708 unsafe { LLVMBuildNot(self.inner, val.as_llvm_value_ref(), name.as_ptr()) }.into()
709 }
710}
711
712impl Drop for IRBuilder {
713 fn drop(&mut self) {
714 unsafe { LLVMDisposeBuilder(self.inner) };
715 }
716}