(module: &Module, cx: &Context)
| 246 | } |
| 247 | |
| 248 | unsafe fn internalize_pass(module: &Module, cx: &Context) { |
| 249 | // collect the values of all the declared kernels |
| 250 | let num_operands = |
| 251 | LLVMGetNamedMetadataNumOperands(module, "nvvm.annotations\0".as_ptr().cast()) as usize; |
| 252 | let mut operands = Vec::with_capacity(num_operands); |
| 253 | LLVMGetNamedMetadataOperands( |
| 254 | module, |
| 255 | "nvvm.annotations\0".as_ptr().cast(), |
| 256 | operands.as_mut_ptr(), |
| 257 | ); |
| 258 | operands.set_len(num_operands); |
| 259 | let mut kernels = Vec::with_capacity(num_operands); |
| 260 | let kernel_str = LLVMMDStringInContext(cx, "kernel".as_ptr().cast(), 6); |
| 261 | |
| 262 | for mdnode in operands { |
| 263 | let num_operands = LLVMGetMDNodeNumOperands(mdnode) as usize; |
| 264 | let mut operands = Vec::with_capacity(num_operands); |
| 265 | LLVMGetMDNodeOperands(mdnode, operands.as_mut_ptr()); |
| 266 | operands.set_len(num_operands); |
| 267 | |
| 268 | if operands.get(1) == Some(&kernel_str) { |
| 269 | kernels.push(operands[0]); |
| 270 | } |
| 271 | } |
| 272 | |
| 273 | // see what functions are marked as externally visible by the user. |
| 274 | let num_operands = |
| 275 | LLVMGetNamedMetadataNumOperands(module, "cg_nvvm_used\0".as_ptr().cast()) as usize; |
| 276 | let mut operands = Vec::with_capacity(num_operands); |
| 277 | LLVMGetNamedMetadataOperands( |
| 278 | module, |
| 279 | "cg_nvvm_used\0".as_ptr().cast(), |
| 280 | operands.as_mut_ptr(), |
| 281 | ); |
| 282 | operands.set_len(num_operands); |
| 283 | let mut used_funcs = Vec::with_capacity(num_operands); |
| 284 | |
| 285 | for mdnode in operands { |
| 286 | let num_operands = LLVMGetMDNodeNumOperands(mdnode) as usize; |
| 287 | let mut operands = Vec::with_capacity(num_operands); |
| 288 | LLVMGetMDNodeOperands(mdnode, operands.as_mut_ptr()); |
| 289 | operands.set_len(num_operands); |
| 290 | |
| 291 | used_funcs.push(operands[0]); |
| 292 | } |
| 293 | |
| 294 | let iter = FunctionIter::new(&module); |
| 295 | for func in iter { |
| 296 | let is_kernel = kernels.contains(&func); |
| 297 | let is_decl = LLVMIsDeclaration(func) == True; |
| 298 | let is_used = used_funcs.contains(&func); |
| 299 | |
| 300 | if !is_decl && !is_kernel { |
| 301 | LLVMRustSetLinkage(func, Linkage::InternalLinkage); |
| 302 | LLVMRustSetVisibility(func, Visibility::Default); |
| 303 | } |
| 304 | |
| 305 | // explicitly set it to external just in case the codegen set them to internal for some reason |
no test coverage detected