11//! LLVM AOT backend compilation
2+ //!
3+ //! Compiles HIR modules to native executables using LLVM's optimizing compiler.
4+ //! This backend produces highly optimized machine code suitable for production use.
25
36use colored:: Colorize ;
7+ use log:: { debug, error, info} ;
48use std:: path:: PathBuf ;
59use zyntax_compiler:: hir:: HirModule ;
610
711/// Compile HIR module with LLVM AOT backend
12+ #[ cfg( feature = "llvm-backend" ) ]
13+ pub fn compile_llvm (
14+ module : HirModule ,
15+ output : Option < PathBuf > ,
16+ opt_level : u8 ,
17+ verbose : bool ,
18+ ) -> Result < ( ) , Box < dyn std:: error:: Error > > {
19+ use inkwell:: context:: Context ;
20+ use inkwell:: targets:: {
21+ CodeModel , FileType , InitializationConfig , RelocMode , Target , TargetMachine ,
22+ } ;
23+ use inkwell:: OptimizationLevel ;
24+ use zyntax_compiler:: llvm_backend:: LLVMBackend ;
25+
26+ let output_path = output. unwrap_or_else ( || PathBuf :: from ( "a.out" ) ) ;
27+
28+ if verbose {
29+ info ! ( "Initializing LLVM backend..." ) ;
30+ }
31+
32+ // Initialize LLVM targets
33+ Target :: initialize_native ( & InitializationConfig :: default ( ) )
34+ . map_err ( |e| format ! ( "Failed to initialize LLVM target: {}" , e) ) ?;
35+
36+ // Create LLVM context and backend
37+ let context = Context :: create ( ) ;
38+ let mut backend = LLVMBackend :: new ( & context, "zyntax_aot" ) ;
39+
40+ if verbose {
41+ info ! ( "Compiling HIR to LLVM IR..." ) ;
42+ }
43+
44+ // Compile HIR module to LLVM IR
45+ let llvm_ir = backend
46+ . compile_module ( & module)
47+ . map_err ( |e| format ! ( "Compilation failed: {}" , e) ) ?;
48+
49+ if verbose {
50+ info ! ( "Generated {} bytes of LLVM IR" , llvm_ir. len( ) ) ;
51+ }
52+
53+ // Get target triple for the host machine
54+ let triple = TargetMachine :: get_default_triple ( ) ;
55+ let target = Target :: from_triple ( & triple)
56+ . map_err ( |e| format ! ( "Failed to get target: {}" , e) ) ?;
57+
58+ // Map optimization level
59+ let llvm_opt = match opt_level {
60+ 0 => OptimizationLevel :: None ,
61+ 1 => OptimizationLevel :: Less ,
62+ 2 => OptimizationLevel :: Default ,
63+ _ => OptimizationLevel :: Aggressive ,
64+ } ;
65+
66+ if verbose {
67+ info ! (
68+ "Target: {}, Optimization: {:?}" ,
69+ triple. as_str( ) . to_str( ) . unwrap_or( "unknown" ) ,
70+ llvm_opt
71+ ) ;
72+ }
73+
74+ // Create target machine
75+ let target_machine = target
76+ . create_target_machine (
77+ & triple,
78+ "generic" ,
79+ "" ,
80+ llvm_opt,
81+ RelocMode :: Default ,
82+ CodeModel :: Default ,
83+ )
84+ . ok_or ( "Failed to create target machine" ) ?;
85+
86+ // Write object file
87+ let obj_path = output_path. with_extension ( "o" ) ;
88+
89+ if verbose {
90+ info ! ( "Writing object file to {:?}..." , obj_path) ;
91+ }
92+
93+ target_machine
94+ . write_to_file ( backend. module ( ) , FileType :: Object , & obj_path)
95+ . map_err ( |e| format ! ( "Failed to write object file: {}" , e) ) ?;
96+
97+ // Link to create executable
98+ if verbose {
99+ info ! ( "Linking executable..." ) ;
100+ }
101+
102+ let status = std:: process:: Command :: new ( "cc" )
103+ . arg ( & obj_path)
104+ . arg ( "-o" )
105+ . arg ( & output_path)
106+ . status ( )
107+ . map_err ( |e| format ! ( "Failed to run linker: {}" , e) ) ?;
108+
109+ if !status. success ( ) {
110+ return Err ( format ! ( "Linker failed with status: {}" , status) . into ( ) ) ;
111+ }
112+
113+ // Clean up object file
114+ let _ = std:: fs:: remove_file ( & obj_path) ;
115+
116+ println ! (
117+ "{} Successfully compiled to {}" ,
118+ "success:" . green( ) . bold( ) ,
119+ output_path. display( )
120+ ) ;
121+
122+ Ok ( ( ) )
123+ }
124+
125+ /// Compile HIR module with LLVM AOT backend (stub when feature not enabled)
126+ #[ cfg( not( feature = "llvm-backend" ) ) ]
8127pub fn compile_llvm (
9128 _module : HirModule ,
10129 output : Option < PathBuf > ,
@@ -13,9 +132,129 @@ pub fn compile_llvm(
13132) -> Result < ( ) , Box < dyn std:: error:: Error > > {
14133 let output_path = output. unwrap_or_else ( || PathBuf :: from ( "a.out" ) ) ;
15134
16- // TODO: Implement LLVM backend compilation
17- eprintln ! ( "{} LLVM backend not yet implemented" , "error:" . red( ) ) ;
18- eprintln ! ( "Output would be: {}" , output_path. display( ) ) ;
135+ error ! ( "LLVM backend not enabled" ) ;
136+ error ! ( "Rebuild with: cargo build --release --features llvm-backend" ) ;
137+ debug ! ( "Output would be: {}" , output_path. display( ) ) ;
138+
139+ Err ( "LLVM backend not enabled. Rebuild with --features llvm-backend" . into ( ) )
140+ }
141+
142+ /// Compile and run with LLVM JIT backend
143+ #[ cfg( feature = "llvm-backend" ) ]
144+ pub fn compile_and_run_llvm (
145+ module : HirModule ,
146+ opt_level : u8 ,
147+ verbose : bool ,
148+ ) -> Result < i64 , Box < dyn std:: error:: Error > > {
149+ use inkwell:: context:: Context ;
150+ use inkwell:: OptimizationLevel ;
151+ use zyntax_compiler:: llvm_jit_backend:: LLVMJitBackend ;
152+
153+ if verbose {
154+ info ! ( "Initializing LLVM JIT backend..." ) ;
155+ }
156+
157+ // Create LLVM context
158+ let context = Context :: create ( ) ;
159+
160+ // Map optimization level
161+ let llvm_opt = match opt_level {
162+ 0 => OptimizationLevel :: None ,
163+ 1 => OptimizationLevel :: Less ,
164+ 2 => OptimizationLevel :: Default ,
165+ _ => OptimizationLevel :: Aggressive ,
166+ } ;
167+
168+ // Create JIT backend
169+ let mut backend = LLVMJitBackend :: with_opt_level ( & context, llvm_opt)
170+ . map_err ( |e| format ! ( "Failed to create JIT backend: {}" , e) ) ?;
171+
172+ if verbose {
173+ info ! ( "Compiling module with LLVM JIT..." ) ;
174+ }
175+
176+ // Compile module
177+ backend
178+ . compile_module ( & module)
179+ . map_err ( |e| format ! ( "JIT compilation failed: {}" , e) ) ?;
180+
181+ // Find main function
182+ let ( main_id, main_fn) = module
183+ . functions
184+ . iter ( )
185+ . find ( |( _, func) | {
186+ func. name
187+ . resolve_global ( )
188+ . map ( |name| name == "main" )
189+ . unwrap_or ( false )
190+ } )
191+ . ok_or ( "No 'main' function found in module" ) ?;
192+
193+ let main_id = * main_id;
194+
195+ // Get function pointer
196+ let fn_ptr = backend
197+ . get_function_pointer ( main_id)
198+ . ok_or ( "Failed to get main function pointer" ) ?;
199+
200+ if verbose {
201+ debug ! ( "Executing main() at {:?}..." , fn_ptr) ;
202+ }
203+
204+ // Execute main function
205+ let result = unsafe {
206+ if main_fn. signature . returns . is_empty ( ) {
207+ let f: fn ( ) = std:: mem:: transmute ( fn_ptr) ;
208+ f ( ) ;
209+ 0
210+ } else {
211+ match & main_fn. signature . returns [ 0 ] {
212+ zyntax_compiler:: hir:: HirType :: I32 => {
213+ let f: fn ( ) -> i32 = std:: mem:: transmute ( fn_ptr) ;
214+ f ( ) as i64
215+ }
216+ zyntax_compiler:: hir:: HirType :: I64 => {
217+ let f: fn ( ) -> i64 = std:: mem:: transmute ( fn_ptr) ;
218+ f ( )
219+ }
220+ zyntax_compiler:: hir:: HirType :: F32 => {
221+ let f: fn ( ) -> f32 = std:: mem:: transmute ( fn_ptr) ;
222+ f ( ) as i64
223+ }
224+ zyntax_compiler:: hir:: HirType :: F64 => {
225+ let f: fn ( ) -> f64 = std:: mem:: transmute ( fn_ptr) ;
226+ f ( ) as i64
227+ }
228+ zyntax_compiler:: hir:: HirType :: Void => {
229+ let f: fn ( ) = std:: mem:: transmute ( fn_ptr) ;
230+ f ( ) ;
231+ 0
232+ }
233+ _ => {
234+ return Err ( format ! (
235+ "Unsupported return type: {:?}" ,
236+ main_fn. signature. returns[ 0 ]
237+ )
238+ . into ( ) ) ;
239+ }
240+ }
241+ }
242+ } ;
243+
244+ println ! ( "{} main() returned: {}" , "result:" . green( ) . bold( ) , result) ;
245+
246+ Ok ( result)
247+ }
248+
249+ /// Compile and run with LLVM JIT backend (stub when feature not enabled)
250+ #[ cfg( not( feature = "llvm-backend" ) ) ]
251+ pub fn compile_and_run_llvm (
252+ _module : HirModule ,
253+ _opt_level : u8 ,
254+ _verbose : bool ,
255+ ) -> Result < i64 , Box < dyn std:: error:: Error > > {
256+ error ! ( "LLVM JIT backend not enabled" ) ;
257+ error ! ( "Rebuild with: cargo build --release --features llvm-backend" ) ;
19258
20- Err ( "LLVM backend not implemented " . into ( ) )
259+ Err ( "LLVM backend not enabled. Rebuild with --features llvm-backend " . into ( ) )
21260}
0 commit comments