1
- use std:: borrow:: Cow ;
1
+ use std:: borrow:: { Borrow , Cow } ;
2
2
use std:: ops:: Deref ;
3
3
use std:: { iter, ptr} ;
4
4
@@ -37,18 +37,16 @@ use crate::type_::Type;
37
37
use crate :: type_of:: LayoutLlvmExt ;
38
38
use crate :: value:: Value ;
39
39
40
-
41
- pub ( crate ) type SBuilder < ' a , ' ll > = GenericBuilder < ' a , ' ll , SimpleCx < ' ll > > ;
42
-
43
40
#[ must_use]
44
- pub ( crate ) struct GenericBuilder < ' a , ' ll , CX > {
41
+ pub ( crate ) struct GenericBuilder < ' a , ' ll , CX : Borrow < SimpleCx < ' ll > > > {
45
42
pub llbuilder : & ' ll mut llvm:: Builder < ' ll > ,
46
43
pub cx : & ' a CX ,
47
44
}
48
45
46
+ pub ( crate ) type SBuilder < ' a , ' ll > = GenericBuilder < ' a , ' ll , SimpleCx < ' ll > > ;
49
47
pub ( crate ) type Builder < ' a , ' ll , ' tcx > = GenericBuilder < ' a , ' ll , CodegenCx < ' ll , ' tcx > > ;
50
48
51
- impl < ' a , ' ll , CX > Drop for GenericBuilder < ' a , ' ll , CX > {
49
+ impl < ' a , ' ll , CX : Borrow < SimpleCx < ' ll > > > Drop for GenericBuilder < ' a , ' ll , CX > {
52
50
fn drop ( & mut self ) {
53
51
unsafe {
54
52
llvm:: LLVMDisposeBuilder ( & mut * ( self . llbuilder as * mut _ ) ) ;
@@ -57,22 +55,49 @@ impl<'a, 'll, CX> Drop for GenericBuilder<'a, 'll, CX> {
57
55
}
58
56
59
57
impl < ' a , ' ll > SBuilder < ' a , ' ll > {
60
- fn build ( cx : & ' a SimpleCx < ' ll > , llbb : & ' ll BasicBlock ) -> SBuilder < ' a , ' ll > {
61
- let bx = SBuilder :: with_scx ( cx) ;
62
- unsafe {
63
- llvm:: LLVMPositionBuilderAtEnd ( bx. llbuilder , llbb) ;
58
+ // This impl might allow moving more functions over to the generic builder?
59
+ //fn cx(&self) -> &SimpleCx<'ll> {
60
+ // self.cx
61
+ //}
62
+
63
+ fn call (
64
+ & mut self ,
65
+ llty : & ' ll Type ,
66
+ llfn : & ' ll Value ,
67
+ args : & [ & ' ll Value ] ,
68
+ funclet : Option < & Funclet < ' ll > > ,
69
+ ) -> & ' ll Value {
70
+ debug ! ( "call {:?} with args ({:?})" , llfn, args) ;
71
+
72
+ let args = self . check_call ( "call" , llty, llfn, args) ;
73
+ let funclet_bundle = funclet. map ( |funclet| funclet. bundle ( ) ) ;
74
+ let mut bundles: SmallVec < [ _ ; 2 ] > = SmallVec :: new ( ) ;
75
+ if let Some ( funclet_bundle) = funclet_bundle {
76
+ bundles. push ( funclet_bundle) ;
64
77
}
65
- bx
78
+
79
+ let call = unsafe {
80
+ llvm:: LLVMBuildCallWithOperandBundles (
81
+ self . llbuilder ,
82
+ llty,
83
+ llfn,
84
+ args. as_ptr ( ) as * const & llvm:: Value ,
85
+ args. len ( ) as c_uint ,
86
+ bundles. as_ptr ( ) ,
87
+ bundles. len ( ) as c_uint ,
88
+ c"" . as_ptr ( ) ,
89
+ )
90
+ } ;
91
+ call
66
92
}
67
- }
68
93
69
- impl < ' a , ' ll > SBuilder < ' a , ' ll > {
70
94
fn with_scx ( scx : & ' a SimpleCx < ' ll > ) -> Self {
71
95
// Create a fresh builder from the simple context.
72
96
let llbuilder = unsafe { llvm:: LLVMCreateBuilderInContext ( scx. llcx ) } ;
73
97
SBuilder { llbuilder, cx : scx }
74
98
}
75
-
99
+ }
100
+ impl < ' a , ' ll , CX : Borrow < SimpleCx < ' ll > > > GenericBuilder < ' a , ' ll , CX > {
76
101
pub ( crate ) fn bitcast ( & mut self , val : & ' ll Value , dest_ty : & ' ll Type ) -> & ' ll Value {
77
102
unsafe { llvm:: LLVMBuildBitCast ( self . llbuilder , val, dest_ty, UNNAMED ) }
78
103
}
@@ -88,6 +113,15 @@ impl<'a, 'll> SBuilder<'a, 'll> {
88
113
llvm:: LLVMBuildRet ( self . llbuilder , v) ;
89
114
}
90
115
}
116
+ }
117
+ impl < ' a , ' ll > SBuilder < ' a , ' ll > {
118
+ fn build ( cx : & ' a SimpleCx < ' ll > , llbb : & ' ll BasicBlock ) -> SBuilder < ' a , ' ll > {
119
+ let bx = SBuilder :: with_scx ( cx) ;
120
+ unsafe {
121
+ llvm:: LLVMPositionBuilderAtEnd ( bx. llbuilder , llbb) ;
122
+ }
123
+ bx
124
+ }
91
125
92
126
fn check_call < ' b > (
93
127
& mut self ,
@@ -129,39 +163,6 @@ impl<'a, 'll> SBuilder<'a, 'll> {
129
163
130
164
Cow :: Owned ( casted_args)
131
165
}
132
-
133
- // This is a simplified version of the call when using the full Builder.
134
- // It can not use any tcx related arguments
135
- fn call (
136
- & mut self ,
137
- llty : & ' ll Type ,
138
- llfn : & ' ll Value ,
139
- args : & [ & ' ll Value ] ,
140
- funclet : Option < & Funclet < ' ll > > ,
141
- ) -> & ' ll Value {
142
- debug ! ( "call {:?} with args ({:?})" , llfn, args) ;
143
-
144
- let args = self . check_call ( "call" , llty, llfn, args) ;
145
- let funclet_bundle = funclet. map ( |funclet| funclet. bundle ( ) ) ;
146
- let mut bundles: SmallVec < [ _ ; 2 ] > = SmallVec :: new ( ) ;
147
- if let Some ( funclet_bundle) = funclet_bundle {
148
- bundles. push ( funclet_bundle) ;
149
- }
150
-
151
- let call = unsafe {
152
- llvm:: LLVMBuildCallWithOperandBundles (
153
- self . llbuilder ,
154
- llty,
155
- llfn,
156
- args. as_ptr ( ) as * const & llvm:: Value ,
157
- args. len ( ) as c_uint ,
158
- bundles. as_ptr ( ) ,
159
- bundles. len ( ) as c_uint ,
160
- c"" . as_ptr ( ) ,
161
- )
162
- } ;
163
- call
164
- }
165
166
}
166
167
167
168
/// Empty string, to be used where LLVM expects an instruction name, indicating
@@ -1334,6 +1335,14 @@ impl<'ll> StaticBuilderMethods for Builder<'_, 'll, '_> {
1334
1335
}
1335
1336
1336
1337
impl < ' a , ' ll , ' tcx > Builder < ' a , ' ll , ' tcx > {
1338
+ fn build ( cx : & ' a CodegenCx < ' ll , ' tcx > , llbb : & ' ll BasicBlock ) -> Builder < ' a , ' ll , ' tcx > {
1339
+ let bx = Builder :: with_cx ( cx) ;
1340
+ unsafe {
1341
+ llvm:: LLVMPositionBuilderAtEnd ( bx. llbuilder , llbb) ;
1342
+ }
1343
+ bx
1344
+ }
1345
+
1337
1346
fn with_cx ( cx : & ' a CodegenCx < ' ll , ' tcx > ) -> Self {
1338
1347
// Create a fresh builder from the crate context.
1339
1348
let llbuilder = unsafe { llvm:: LLVMCreateBuilderInContext ( cx. llcx ) } ;
@@ -1343,13 +1352,16 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
1343
1352
pub ( crate ) fn llfn ( & self ) -> & ' ll Value {
1344
1353
unsafe { llvm:: LLVMGetBasicBlockParent ( self . llbb ( ) ) }
1345
1354
}
1355
+ }
1346
1356
1357
+ impl < ' a , ' ll , CX : Borrow < SimpleCx < ' ll > > > GenericBuilder < ' a , ' ll , CX > {
1347
1358
fn position_at_start ( & mut self , llbb : & ' ll BasicBlock ) {
1348
1359
unsafe {
1349
1360
llvm:: LLVMRustPositionBuilderAtStart ( self . llbuilder , llbb) ;
1350
1361
}
1351
1362
}
1352
-
1363
+ }
1364
+ impl < ' a , ' ll , ' tcx > Builder < ' a , ' ll , ' tcx > {
1353
1365
fn align_metadata ( & mut self , load : & ' ll Value , align : Align ) {
1354
1366
unsafe {
1355
1367
let md = [ llvm:: LLVMValueAsMetadata ( self . cx . const_u64 ( align. bytes ( ) ) ) ] ;
@@ -1371,7 +1383,8 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
1371
1383
self . set_metadata ( inst, llvm:: MD_unpredictable , md) ;
1372
1384
}
1373
1385
}
1374
-
1386
+ }
1387
+ impl < ' a , ' ll , CX : Borrow < SimpleCx < ' ll > > > GenericBuilder < ' a , ' ll , CX > {
1375
1388
pub ( crate ) fn minnum ( & mut self , lhs : & ' ll Value , rhs : & ' ll Value ) -> & ' ll Value {
1376
1389
unsafe { llvm:: LLVMRustBuildMinNum ( self . llbuilder , lhs, rhs) }
1377
1390
}
@@ -1472,7 +1485,9 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
1472
1485
let ret = unsafe { llvm:: LLVMBuildCatchRet ( self . llbuilder , funclet. cleanuppad ( ) , unwind) } ;
1473
1486
ret. expect ( "LLVM does not have support for catchret" )
1474
1487
}
1488
+ }
1475
1489
1490
+ impl < ' a , ' ll , ' tcx > Builder < ' a , ' ll , ' tcx > {
1476
1491
fn check_call < ' b > (
1477
1492
& mut self ,
1478
1493
typ : & str ,
@@ -1513,11 +1528,13 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
1513
1528
1514
1529
Cow :: Owned ( casted_args)
1515
1530
}
1516
-
1531
+ }
1532
+ impl < ' a , ' ll , CX : Borrow < SimpleCx < ' ll > > > GenericBuilder < ' a , ' ll , CX > {
1517
1533
pub ( crate ) fn va_arg ( & mut self , list : & ' ll Value , ty : & ' ll Type ) -> & ' ll Value {
1518
1534
unsafe { llvm:: LLVMBuildVAArg ( self . llbuilder , list, ty, UNNAMED ) }
1519
1535
}
1520
-
1536
+ }
1537
+ impl < ' a , ' ll , ' tcx > Builder < ' a , ' ll , ' tcx > {
1521
1538
pub ( crate ) fn call_intrinsic ( & mut self , intrinsic : & str , args : & [ & ' ll Value ] ) -> & ' ll Value {
1522
1539
let ( ty, f) = self . cx . get_intrinsic ( intrinsic) ;
1523
1540
self . call ( ty, None , None , f, args, None , None )
@@ -1535,7 +1552,8 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
1535
1552
1536
1553
self . call_intrinsic ( intrinsic, & [ self . cx . const_u64 ( size) , ptr] ) ;
1537
1554
}
1538
-
1555
+ }
1556
+ impl < ' a , ' ll , CX : Borrow < SimpleCx < ' ll > > > GenericBuilder < ' a , ' ll , CX > {
1539
1557
pub ( crate ) fn phi (
1540
1558
& mut self ,
1541
1559
ty : & ' ll Type ,
@@ -1555,7 +1573,8 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
1555
1573
llvm:: LLVMAddIncoming ( phi, & val, & bb, 1 as c_uint ) ;
1556
1574
}
1557
1575
}
1558
-
1576
+ }
1577
+ impl < ' a , ' ll , ' tcx > Builder < ' a , ' ll , ' tcx > {
1559
1578
fn fptoint_sat ( & mut self , signed : bool , val : & ' ll Value , dest_ty : & ' ll Type ) -> & ' ll Value {
1560
1579
let src_ty = self . cx . val_ty ( val) ;
1561
1580
let ( float_ty, int_ty, vector_length) = if self . cx . type_kind ( src_ty) == TypeKind :: Vector {
0 commit comments