@@ -13,10 +13,13 @@ use crate::{
1313} ;
1414use cstr:: cstr;
1515use llvm_sys:: {
16- core:: { LLVMAddFunction , LLVMFunctionType , LLVMSetFunctionCallConv , LLVMSetLinkage } ,
16+ core:: {
17+ LLVMAddFunction , LLVMFunctionType , LLVMGetNamedFunction , LLVMSetFunctionCallConv ,
18+ LLVMSetLinkage ,
19+ } ,
1720 LLVMCallConv , LLVMLinkage ,
1821} ;
19- use std:: ffi:: CString ;
22+ use std:: { ffi:: CString , ptr :: null_mut } ;
2023
2124pub unsafe fn create_func_heads ( ctx : & mut BackendCtx ) -> Result < ( ) , BackendError > {
2225 for ( func_ref, func) in ctx. ir_module . funcs . iter ( ) {
@@ -62,19 +65,37 @@ pub unsafe fn create_func_heads(ctx: &mut BackendCtx) -> Result<(), BackendError
6265 } ;
6366
6467 let name = CString :: new ( func. mangled_name . as_bytes ( ) ) . unwrap ( ) ;
65- let skeleton = LLVMAddFunction (
66- ctx. backend_module . get ( ) ,
67- name. as_ptr ( ) ,
68- function_type. pointer ,
69- ) ;
70- LLVMSetFunctionCallConv ( skeleton, LLVMCallConv :: LLVMCCallConv as u32 ) ;
7168
72- let nounwind = create_enum_attribute ( cstr ! ( "nounwind" ) , 0 ) ;
73- add_func_attribute ( skeleton, nounwind) ;
69+ let existing = if func. is_foreign || func. is_exposed {
70+ LLVMGetNamedFunction ( ctx. backend_module . get ( ) , name. as_ptr ( ) )
71+ } else {
72+ null_mut ( )
73+ } ;
74+
75+ let skeleton = if existing. is_null ( ) {
76+ let skeleton = LLVMAddFunction (
77+ ctx. backend_module . get ( ) ,
78+ name. as_ptr ( ) ,
79+ function_type. pointer ,
80+ ) ;
81+
82+ LLVMSetFunctionCallConv ( skeleton, LLVMCallConv :: LLVMCCallConv as u32 ) ;
7483
75- if !func. is_foreign && !func. is_exposed {
76- LLVMSetLinkage ( skeleton, LLVMLinkage :: LLVMPrivateLinkage ) ;
77- }
84+ let nounwind = create_enum_attribute ( cstr ! ( "nounwind" ) , 0 ) ;
85+ add_func_attribute ( skeleton, nounwind) ;
86+
87+ if !func. is_foreign && !func. is_exposed {
88+ LLVMSetLinkage ( skeleton, LLVMLinkage :: LLVMPrivateLinkage ) ;
89+ }
90+
91+ skeleton
92+ } else {
93+ if func. is_foreign || func. is_exposed {
94+ LLVMSetLinkage ( existing, LLVMLinkage :: LLVMExternalLinkage ) ;
95+ }
96+
97+ existing
98+ } ;
7899
79100 ctx. func_skeletons . insert (
80101 func_ref,
0 commit comments