@@ -44,6 +44,17 @@ pub struct LLVMBackendOptions {
4444 pub debug_symbols : bool ,
4545}
4646
47+ #[ cfg( feature = "llvm" ) ]
48+ pub fn get_host_target_triple ( ) -> String {
49+ unsafe {
50+ let raw = llvm_sys:: target_machine:: LLVMGetDefaultTargetTriple ( ) ;
51+ let cstr = std:: ffi:: CStr :: from_ptr ( raw) ;
52+ let s = cstr. to_string_lossy ( ) . into_owned ( ) ;
53+ llvm_sys:: core:: LLVMDisposeMessage ( raw) ;
54+ s
55+ }
56+ }
57+
4758pub struct LLVMBackend ;
4859
4960impl LLVMBackend {
@@ -54,12 +65,14 @@ impl LLVMBackend {
5465 options : & LLVMBackendOptions ,
5566 out_path : & Path ,
5667 ) -> Result < ( ) , LLVMCodegenError > {
57- Self :: emit_to_file (
58- ir_module,
59- options,
60- out_path,
61- llvm_sys:: target_machine:: LLVMCodeGenFileType :: LLVMObjectFile ,
62- )
68+ unsafe {
69+ Self :: emit_to_file (
70+ ir_module,
71+ options,
72+ out_path,
73+ llvm_sys:: target_machine:: LLVMCodeGenFileType :: LLVMObjectFile ,
74+ )
75+ }
6376 }
6477
6578 /// Compiles a TechScript IR Module to a native assembly file (`.s` or `.asm`) at the given output path.
@@ -69,12 +82,14 @@ impl LLVMBackend {
6982 options : & LLVMBackendOptions ,
7083 out_path : & Path ,
7184 ) -> Result < ( ) , LLVMCodegenError > {
72- Self :: emit_to_file (
73- ir_module,
74- options,
75- out_path,
76- llvm_sys:: target_machine:: LLVMCodeGenFileType :: LLVMAssemblyFile ,
77- )
85+ unsafe {
86+ Self :: emit_to_file (
87+ ir_module,
88+ options,
89+ out_path,
90+ llvm_sys:: target_machine:: LLVMCodeGenFileType :: LLVMAssemblyFile ,
91+ )
92+ }
7893 }
7994
8095 /// Emits textual LLVM IR representation (`.ll`) at the given output path.
@@ -117,7 +132,6 @@ impl LLVMBackend {
117132 use crate :: context:: CodegenContext ;
118133 use llvm_sys:: target:: * ;
119134 use llvm_sys:: target_machine:: * ;
120- use llvm_sys:: transforms:: pass_manager_builder:: * ;
121135 use std:: ffi:: { CStr , CString } ;
122136
123137 // 1. Initialize LLVM targets
@@ -172,48 +186,37 @@ impl LLVMBackend {
172186
173187 // Set module target triple and data layout
174188 let layout = LLVMCreateTargetDataLayout ( target_machine) ;
175- let layout_str = LLVMCopyStringRepOfTargetData ( layout) ;
176- LLVMSetDataLayout ( ctx. module , layout_str) ;
177- LLVMSetTarget ( ctx. module , triple_cstr. as_ptr ( ) ) ;
189+ let layout_str = llvm_sys :: target :: LLVMCopyStringRepOfTargetData ( layout) ;
190+ llvm_sys :: core :: LLVMSetDataLayout ( ctx. module , layout_str) ;
191+ llvm_sys :: core :: LLVMSetTarget ( ctx. module , triple_cstr. as_ptr ( ) ) ;
178192
179193 // 5. Setup Pass Manager Optimizations
180- let opt_level_u32 = match options. opt_level {
181- LLVMCodeGenOptLevel :: LLVMCodeGenLevelNone => 0 ,
182- LLVMCodeGenOptLevel :: LLVMCodeGenLevelLess => 1 ,
183- LLVMCodeGenOptLevel :: LLVMCodeGenLevelDefault => 2 ,
184- LLVMCodeGenOptLevel :: LLVMCodeGenLevelAggressive => 3 ,
185- } ;
194+ let pb_options = llvm_sys:: transforms:: pass_builder:: LLVMCreatePassBuilderOptions ( ) ;
186195
187- let pm_builder = LLVMPassManagerBuilderCreate ( ) ;
188- LLVMPassManagerBuilderSetOptLevel ( pm_builder, opt_level_u32) ;
189- LLVMPassManagerBuilderSetSizeLevel ( pm_builder, if opt_level_u32 == 2 { 1 } else { 0 } ) ; // Os equivalent
190- LLVMPassManagerBuilderUseInlinerWithThreshold (
191- pm_builder,
192- if opt_level_u32 > 0 { 275 } else { 0 } ,
193- ) ;
194-
195- let mpm = llvm_sys:: core:: LLVMCreatePassManager ( ) ;
196- LLVMPassManagerBuilderPopulateModulePassManager ( pm_builder, mpm) ;
197-
198- let fpm = llvm_sys:: core:: LLVMCreateFunctionPassManagerForModule ( ctx. module ) ;
199- LLVMPassManagerBuilderPopulateFunctionPassManager ( pm_builder, fpm) ;
200-
201- LLVMPassManagerBuilderDispose ( pm_builder) ;
202-
203- // Run function-level optimizations
204- llvm_sys:: core:: LLVMInitializeFunctionPassManager ( fpm) ;
205- let mut func = llvm_sys:: core:: LLVMGetFirstFunction ( ctx. module ) ;
206- while !func. is_null ( ) {
207- llvm_sys:: core:: LLVMRunFunctionPassManager ( fpm, func) ;
208- func = llvm_sys:: core:: LLVMGetNextFunction ( func) ;
196+ let passes = match options. opt_level {
197+ LLVMCodeGenOptLevel :: LLVMCodeGenLevelNone => "default<O0>" ,
198+ LLVMCodeGenOptLevel :: LLVMCodeGenLevelLess => "default<O1>" ,
199+ LLVMCodeGenOptLevel :: LLVMCodeGenLevelDefault => "default<O2>" ,
200+ LLVMCodeGenOptLevel :: LLVMCodeGenLevelAggressive => "default<O3>" ,
201+ } ;
202+ let passes_cstr = CString :: new ( passes) . unwrap ( ) ;
203+
204+ if let LLVMCodeGenOptLevel :: LLVMCodeGenLevelNone = options. opt_level {
205+ // No extra options
206+ } else {
207+ llvm_sys:: transforms:: pass_builder:: LLVMPassBuilderOptionsSetInlinerThreshold (
208+ pb_options, 275 ,
209+ ) ;
209210 }
210- llvm_sys:: core:: LLVMFinalizeFunctionPassManager ( fpm) ;
211211
212- // Run module-level optimizations
213- llvm_sys:: core:: LLVMRunPassManager ( mpm, ctx. module ) ;
212+ llvm_sys:: transforms:: pass_builder:: LLVMRunPasses (
213+ ctx. module ,
214+ passes_cstr. as_ptr ( ) ,
215+ target_machine,
216+ pb_options,
217+ ) ;
214218
215- llvm_sys:: core:: LLVMDisposePassManager ( fpm) ;
216- llvm_sys:: core:: LLVMDisposePassManager ( mpm) ;
219+ llvm_sys:: transforms:: pass_builder:: LLVMDisposePassBuilderOptions ( pb_options) ;
217220
218221 // 6. Emit target file (object or assembly)
219222 let out_str = CString :: new ( out_path. to_string_lossy ( ) . to_string ( ) ) . unwrap ( ) ;
@@ -228,8 +231,7 @@ impl LLVMBackend {
228231 ) ;
229232
230233 // Clean up target layouts and machines
231- LLVMDisposeTargetString ( layout_str) ;
232- LLVMDisposeTargetData ( layout) ;
234+ llvm_sys:: target:: LLVMDisposeTargetData ( layout) ;
233235 LLVMDisposeTargetMachine ( target_machine) ;
234236
235237 if status != 0 {
0 commit comments