@@ -6,13 +6,9 @@ use hugr::{
6
6
HugrView , Node ,
7
7
} ;
8
8
use inkwell:: {
9
- builder:: Builder ,
10
- context:: Context ,
11
- module:: { Linkage , Module } ,
12
- types:: { AnyType , BasicType , BasicTypeEnum , FunctionType } ,
13
- values:: { BasicValueEnum , CallSiteValue , FunctionValue , GlobalValue } ,
9
+ builder:: Builder , context:: Context , debug_info:: { AsDIScope , DICompileUnit , DIScope , DebugInfoBuilder } , module:: { Linkage , Module } , types:: { AnyType , BasicType , BasicTypeEnum , FunctionType } , values:: { BasicValueEnum , CallSiteValue , FunctionValue , GlobalValue }
14
10
} ;
15
- use std:: { collections:: HashSet , rc:: Rc } ;
11
+ use std:: { collections:: { HashMap , HashSet } , rc:: Rc } ;
16
12
17
13
use crate :: types:: { HugrFuncType , HugrSumType , HugrType , TypingSession } ;
18
14
@@ -32,6 +28,8 @@ pub use func::{EmitFuncContext, RowPromise};
32
28
pub use namer:: Namer ;
33
29
pub use ops:: emit_value;
34
30
31
+ type DI < ' c > = ( Rc < DebugInfoBuilder < ' c > > , DICompileUnit < ' c > ) ;
32
+
35
33
/// A trait used to abstract over emission.
36
34
///
37
35
/// In particular a `Box<dyn EmitOp>` is returned by
@@ -74,7 +72,7 @@ impl<'c, H> EmitModuleContext<'c, H> {
74
72
/// Convert a [HugrFuncType] into an LLVM [FunctionType].
75
73
pub fn llvm_func_type( & self , [ self . extensions( ) ] , hugr_type: & HugrFuncType ) -> Result <FunctionType <' c>>;
76
74
/// Convert a hugr [HugrSumType] into an LLVM [LLVMSumType].
77
- pub fn llvm_sum_type( & self , [ self . extensions( ) ] , sum_ty: HugrSumType ) -> Result <LLVMSumType <' c>>;
75
+ pub fn llvm_sum_type( & self , [ self . extensions( ) ] , sum_ty: & HugrSumType ) -> Result <LLVMSumType <' c>>;
78
76
}
79
77
80
78
to self . namer {
@@ -242,7 +240,7 @@ impl<'c, H> EmitModuleContext<'c, H> {
242
240
}
243
241
}
244
242
245
- type EmissionSet < ' c , H > = HashSet < FatNode < ' c , FuncDefn , H > > ;
243
+ type EmissionSet < ' c , H > = HashMap < FatNode < ' c , FuncDefn , H > , DIScope < ' c > > ;
246
244
247
245
/// Emits [HugrView]s into an LLVM [Module].
248
246
pub struct EmitHugr < ' c , H > {
@@ -294,14 +292,20 @@ impl<'c, H: HugrView> EmitHugr<'c, H> {
294
292
///
295
293
/// If any LLVM IR declaration which is to be emitted already exists in the
296
294
/// [Module] and it differs from what would be emitted, then we fail.
297
- pub fn emit_func ( mut self , node : FatNode < ' c , FuncDefn , H > ) -> Result < Self > {
298
- let mut worklist: EmissionSet < ' c , H > = [ node] . into_iter ( ) . collect ( ) ;
295
+ pub fn emit_func ( mut self , node : FatNode < ' c , FuncDefn , H > , di : DI < ' c > ) -> Result < Self > {
296
+ let mut worklist: EmissionSet < ' c , H > = [ ( node, di . 1 . clone ( ) . as_debug_info_scope ( ) ) ] . into_iter ( ) . collect ( ) ;
299
297
let pop =
300
- |wl : & mut EmissionSet < ' c , H > | wl. iter ( ) . next ( ) . cloned ( ) . map ( |x| wl. take ( & x) . unwrap ( ) ) ;
298
+ |wl : & mut EmissionSet < ' c , H > | {
299
+ let & k = wl. keys ( ) . next ( ) ?;
300
+ wl. remove_entry ( & k)
301
+ } ;
301
302
302
- while let Some ( x) = pop ( & mut worklist) {
303
- let ( new_self, new_tasks) = self . emit_func_impl ( x) ?;
304
- self = new_self;
303
+ while let Some ( ( node, scope) ) = pop ( & mut worklist) {
304
+ if self . emitted . insert ( node, scope. clone ( ) ) . is_some ( ) {
305
+ continue ;
306
+ }
307
+ let ( new_self, new_tasks) = func:: emit_func ( self . module_context , node, di. 0 . clone ( ) , scope) ?;
308
+ self . module_context = new_self;
305
309
worklist. extend ( new_tasks. into_iter ( ) ) ;
306
310
}
307
311
Ok ( self )
@@ -314,11 +318,29 @@ impl<'c, H: HugrView> EmitHugr<'c, H> {
314
318
/// emission of ops with static edges from them. So [FuncDefn] are the only
315
319
/// interesting children.
316
320
pub fn emit_module ( mut self , node : FatNode < ' c , hugr:: ops:: Module , H > ) -> Result < Self > {
321
+ let ( di_builder, di_compile_unit) = self . module ( ) . create_debug_info_builder (
322
+ true , // allow_unresolved
323
+ inkwell:: debug_info:: DWARFSourceLanguage :: C , // language
324
+ "filename" , // filename
325
+ "directory" , // directory
326
+ "producer" , // produer
327
+ false , // is_optimised
328
+ "" , //flags
329
+ 0 , // runtime_ver
330
+ "" , //split_name
331
+ inkwell:: debug_info:: DWARFEmissionKind :: Full ,
332
+ 0 , // dwo_id
333
+ false , // split_debug_inlining
334
+ false , //debug_info_for_profiling
335
+ "" , // sysroot
336
+ "" ) ; // sdk
337
+ let di_builder = Rc :: new ( di_builder) ;
317
338
for c in node. children ( ) {
318
339
match c. as_ref ( ) {
319
340
OpType :: FuncDefn ( ref fd) => {
320
341
let fat_ot = c. into_ot ( fd) ;
321
- self = self . emit_func ( fat_ot) ?;
342
+
343
+ self = self . emit_func ( fat_ot, ( di_builder. clone ( ) , di_compile_unit) ) ?;
322
344
}
323
345
// FuncDecls are allowed, but we don't need to do anything here.
324
346
OpType :: FuncDecl ( _) => ( ) ,
@@ -330,35 +352,6 @@ impl<'c, H: HugrView> EmitHugr<'c, H> {
330
352
Ok ( self )
331
353
}
332
354
333
- fn emit_func_impl (
334
- mut self ,
335
- node : FatNode < ' c , FuncDefn , H > ,
336
- ) -> Result < ( Self , EmissionSet < ' c , H > ) > {
337
- if !self . emitted . insert ( node) {
338
- return Ok ( ( self , EmissionSet :: default ( ) ) ) ;
339
- }
340
- let func = self . module_context . get_func_defn ( node) ?;
341
- let mut func_ctx = EmitFuncContext :: new ( self . module_context , func) ?;
342
- let ret_rmb = func_ctx. new_row_mail_box ( node. signature . body ( ) . output . iter ( ) , "ret" ) ?;
343
- ops:: emit_dataflow_parent (
344
- & mut func_ctx,
345
- EmitOpArgs {
346
- node,
347
- inputs : func. get_params ( ) ,
348
- outputs : ret_rmb. promise ( ) ,
349
- } ,
350
- ) ?;
351
- let builder = func_ctx. builder ( ) ;
352
- match & ret_rmb. read :: < Vec < _ > > ( builder, [ ] ) ?[ ..] {
353
- [ ] => builder. build_return ( None ) ?,
354
- [ x] => builder. build_return ( Some ( x) ) ?,
355
- xs => builder. build_aggregate_return ( xs) ?,
356
- } ;
357
- let ( mctx, todos) = func_ctx. finish ( ) ?;
358
- self . module_context = mctx;
359
- Ok ( ( self , todos) )
360
- }
361
-
362
355
/// Consumes the `EmitHugr` and returns the internal [Module].
363
356
pub fn finish ( self ) -> Module < ' c > {
364
357
self . module_context . finish ( )
0 commit comments