Skip to content

Commit cedd78a

Browse files
authored
Merge pull request #25 from Tcode-Motion/fix-llvm-backend-clippy-10737392408395134552
Fix `techscript_llvm_backend` build failures and exhaustive match errors
2 parents 3f88f78 + 8bdae75 commit cedd78a

5 files changed

Lines changed: 87 additions & 81 deletions

File tree

cli/src/pipeline.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,8 @@ pub enum ExecutionBackend {
3737
/// Helper to resolve target triple.
3838
pub fn get_host_target_triple() -> String {
3939
#[cfg(feature = "llvm")]
40-
unsafe {
41-
let raw = llvm_sys::target_machine::LLVMGetDefaultTargetTriple();
42-
let cstr = std::ffi::CStr::from_ptr(raw);
43-
let s = cstr.to_string_lossy().into_owned();
44-
llvm_sys::core::LLVMDisposeMessage(raw);
45-
s
40+
{
41+
techscript_llvm_backend::get_host_target_triple()
4642
}
4743
#[cfg(not(feature = "llvm"))]
4844
{

compiler/llvm_backend/src/codegen.rs

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use std::collections::HashMap;
1010
use std::ffi::CString;
1111
use techscript_ast::LiteralVal;
1212
use techscript_ir::types::{BlockId, GlobalId, IRType, ValueId};
13-
use techscript_ir::{BasicBlock, Function, Instruction, Module, Op, TerminatorKind, Value};
13+
use techscript_ir::{Function, Instruction, Module, Op, TerminatorKind, Value};
1414
use techscript_syntax::TokenKind;
1515

1616
use crate::context::CodegenContext;
@@ -44,7 +44,7 @@ impl<'a> CodegenEngine<'a> {
4444
llvm_ty,
4545
CString::new(name.as_str()).unwrap().as_ptr(),
4646
);
47-
self.ctx.register_value(*global_id, global_var);
47+
self.ctx.register_global(*global_id, global_var);
4848
self.global_names.insert(*global_id, name.clone());
4949
}
5050

@@ -95,7 +95,7 @@ impl<'a> CodegenEngine<'a> {
9595
// Register function parameter variables
9696
for (idx, &(local_id, _, _)) in func.params.iter().enumerate() {
9797
let param_val = LLVMGetParam(llvm_func, idx as u32);
98-
self.ctx.register_value(local_id, param_val);
98+
self.ctx.register_local(local_id, param_val);
9999
}
100100

101101
// Allocate basic blocks
@@ -124,6 +124,10 @@ impl<'a> CodegenEngine<'a> {
124124
let dest_block = self.ctx.get_block(*dest).unwrap();
125125
LLVMBuildBr(self.ctx.builder, dest_block);
126126
}
127+
TerminatorKind::Throw(_) => {
128+
// TODO: Implement exception handling or unwind
129+
LLVMBuildUnreachable(self.ctx.builder);
130+
}
127131
TerminatorKind::ConditionalJump {
128132
cond,
129133
then_block,
@@ -695,14 +699,17 @@ impl<'a> CodegenEngine<'a> {
695699
// Handle direct calls to global/user/standard functions
696700
let mut resolved_func = None;
697701
if let Value::Global(global_id) = callee {
698-
if let Some(global_name) = self.global_names.get(global_id) {
699-
resolved_func = self.resolve_function_by_name(global_name);
702+
let name = self.global_names.get(global_id).cloned();
703+
if let Some(n) = name {
704+
resolved_func = self.resolve_function_by_name(&n);
700705
}
701706
} else if let Value::Temp(temp_id) = callee {
707+
let mut name = None;
702708
if let Some(global_id) = self.temp_to_global.get(temp_id) {
703-
if let Some(global_name) = self.global_names.get(global_id) {
704-
resolved_func = self.resolve_function_by_name(global_name);
705-
}
709+
name = self.global_names.get(global_id).cloned();
710+
}
711+
if let Some(n) = name {
712+
resolved_func = self.resolve_function_by_name(&n);
706713
}
707714
}
708715

@@ -1030,6 +1037,7 @@ impl<'a> CodegenEngine<'a> {
10301037
map_val
10311038
}
10321039
Op::Cast { value, target_type } => {
1040+
let _double_ty = double_ty; // avoid unused warning
10331041
let val_val = self.codegen_val(value)?;
10341042
let boxed_val = self.box_val(val_val)?;
10351043
let tag = match target_type {
@@ -1050,7 +1058,7 @@ impl<'a> CodegenEngine<'a> {
10501058
CString::new("cast").unwrap().as_ptr(),
10511059
)
10521060
}
1053-
Op::NoOp => return Ok(()),
1061+
Op::Try { .. } | Op::EndTry | Op::MakeDslBlock { .. } | Op::NoOp => return Ok(()),
10541062
};
10551063

10561064
if let Some(res_id) = inst.result {
@@ -1068,14 +1076,14 @@ impl<'a> CodegenEngine<'a> {
10681076
.ok_or_else(|| format!("ValueId {:?} not found", id)),
10691077
Value::Local(id) => self
10701078
.ctx
1071-
.get_value(*id)
1079+
.get_local(*id)
10721080
.ok_or_else(|| format!("LocalId {:?} not found", id)),
10731081
Value::Global(id) => self
10741082
.ctx
1075-
.get_value(*id)
1083+
.get_global(*id)
10761084
.ok_or_else(|| format!("GlobalId {:?} not found", id)),
10771085
Value::Const(lit) => self.codegen_literal(lit),
1078-
Value::Null => Ok(LLVMConstNull(LLVMPointerType(
1086+
Value::Null | Value::DslBlock { .. } => Ok(LLVMConstNull(LLVMPointerType(
10791087
LLVMInt8TypeInContext(self.ctx.context),
10801088
0,
10811089
))),
@@ -1106,7 +1114,7 @@ impl<'a> CodegenEngine<'a> {
11061114
name.as_ptr(),
11071115
))
11081116
}
1109-
LiteralVal::Null => Ok(LLVMConstNull(LLVMPointerType(
1117+
LiteralVal::None => Ok(LLVMConstNull(LLVMPointerType(
11101118
LLVMInt8TypeInContext(self.ctx.context),
11111119
0,
11121120
))),
@@ -1274,7 +1282,7 @@ impl TypeInfo for Value {
12741282
LiteralVal::Float(_) => IRType::Float64,
12751283
LiteralVal::Bool(_) => IRType::Bool,
12761284
LiteralVal::Str(_) => IRType::String,
1277-
LiteralVal::Null => IRType::Any,
1285+
LiteralVal::None => IRType::Any,
12781286
},
12791287
_ => IRType::Any,
12801288
}

compiler/llvm_backend/src/jit.rs

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,9 @@
66

77
use llvm_sys::core::*;
88
use llvm_sys::orc2::*;
9-
use llvm_sys::prelude::*;
9+
use llvm_sys::orc2::lljit::*;
1010
use std::collections::HashMap;
1111
use std::ffi::CString;
12-
use std::os::raw::c_void;
1312
use std::ptr;
1413

1514
use crate::codegen::CodegenEngine;
@@ -32,7 +31,7 @@ impl LLVMJitEngine {
3231
return Err("Failed to create LLVMOrcLLJITRef".to_string());
3332
}
3433

35-
let ts_ctx = LLVMOrcCreateThreadSafeContext();
34+
let ts_ctx = LLVMOrcCreateNewThreadSafeContext();
3635

3736
Ok(Self {
3837
jit,
@@ -54,17 +53,17 @@ impl LLVMJitEngine {
5453

5554
// 2. Set target triple and data layout matching LLJIT
5655
let jd = LLVMOrcLLJITGetMainJITDylib(self.jit);
57-
let layout = LLVMOrcLLJITGetDataLayout(self.jit);
58-
let layout_str = LLVMCopyStringRepOfTargetData(layout);
59-
LLVMSetDataLayout(ctx.module, layout_str);
60-
LLVMDisposeTargetString(layout_str);
56+
let layout_str = LLVMOrcLLJITGetDataLayoutStr(self.jit);
57+
llvm_sys::core::LLVMSetDataLayout(ctx.module, layout_str);
58+
// Do not dispose layout_str directly as LLVMOrcLLJITGetDataLayoutStr returns a borrowed const char*
59+
// string tied to the DataLayout of the JIT instance.
6160

6261
// 3. Set host target triple
63-
let host_triple = LLVMOrcLLJITGetExecutionSession(self.jit); // session triple fallback
62+
let _host_triple = LLVMOrcLLJITGetExecutionSession(self.jit); // session triple fallback
6463
// We can just keep the default LLVM target triple
6564

6665
// 4. Wrap Module in ThreadSafeModule
67-
let tsm = LLVMOrcCreateThreadSafeModule(ctx.module, self.ts_ctx);
66+
let tsm = LLVMOrcCreateNewThreadSafeModule(ctx.module, self.ts_ctx);
6867

6968
// Relinquish ownership of ctx.module because LLVMOrcCreateThreadSafeModule takes it
7069
ctx.module = ptr::null_mut();
@@ -112,7 +111,7 @@ impl LLVMJitEngine {
112111
impl Drop for LLVMJitEngine {
113112
fn drop(&mut self) {
114113
unsafe {
115-
LLVMOrcLLJITDispose(self.jit);
114+
LLVMOrcDisposeLLJIT(self.jit);
116115
LLVMOrcDisposeThreadSafeContext(self.ts_ctx);
117116
}
118117
}

compiler/llvm_backend/src/lib.rs

Lines changed: 53 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
4758
pub struct LLVMBackend;
4859

4960
impl 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 {

compiler/llvm_backend/src/type_map.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ pub unsafe fn to_llvm_type(context: LLVMContextRef, ty: &IRType) -> LLVMTypeRef
2525
IRType::Struct(_) => LLVMPointerType(LLVMInt8TypeInContext(context), 0),
2626
IRType::Enum(_) => LLVMPointerType(LLVMInt8TypeInContext(context), 0),
2727
IRType::Model(_) => LLVMPointerType(LLVMInt8TypeInContext(context), 0),
28+
IRType::DslBlock(_) => LLVMPointerType(LLVMInt8TypeInContext(context), 0),
2829
IRType::Any => LLVMPointerType(LLVMInt8TypeInContext(context), 0),
2930
}
3031
}

0 commit comments

Comments
 (0)