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