Skip to content

Commit

Permalink
Add function signature to code_native and code_llvm (#50630)
Browse files Browse the repository at this point in the history
When getting LLVM IR from `@code_llvm`, it's sometimes necessary to know
exactly which `f` is being compiled. This prints the type signature of a
function in front of `code_llvm` and `code_native` to assist in that
process.

<details>
<summary>Example</summary>

```julia
julia> @code_llvm zeros(64)
```

```llvm
; Function Signature: zeros(Int64)
;  @ array.jl:629 within `zeros`
define nonnull {}* @julia_zeros_121(i64 signext %"dims[1]::Int64") #0 {
top:
;  @ array.jl:629 within `zeros` @ array.jl:631 @ array.jl:634
; ┌ @ boot.jl:484 within `Array` @ boot.jl:475
   %0 = call nonnull {}* inttoptr (i64 140604991500960 to {}* ({}*, i64)*)({}* inttoptr (i64 140604630439728 to {}*), i64 %"dims[1]::Int64")
; └
;  @ array.jl:629 within `zeros` @ array.jl:631 @ array.jl:635
; ┌ @ array.jl:392 within `fill!`
; │┌ @ abstractarray.jl:318 within `eachindex`
; ││┌ @ abstractarray.jl:134 within `axes1`
; │││┌ @ abstractarray.jl:98 within `axes`
; ││││┌ @ array.jl:191 within `size`
       %1 = bitcast {}* %0 to { i8*, i64, i16, i16, i32 }*
       %.length_ptr = getelementptr inbounds { i8*, i64, i16, i16, i32 }, { i8*, i64, i16, i16, i32 }* %1, i64 0, i32 1
       %.length = load i64, i64* %.length_ptr, align 8
; │└└└└
; │┌ @ range.jl:897 within `iterate`
; ││┌ @ range.jl:674 within `isempty`
; │││┌ @ operators.jl:378 within `>`
; ││││┌ @ int.jl:83 within `<`
       %.not.not = icmp eq i64 %.length, 0
; │└└└└
   br i1 %.not.not, label %L30, label %L13.preheader

L13.preheader:                                    ; preds = %top
   %2 = bitcast {}* %0 to i8**
   %.data1013 = load i8*, i8** %2, align 8
; │ @ array.jl:394 within `fill!`
   %3 = shl nuw i64 %.length, 3
; │ @ array.jl:393 within `fill!`
; │┌ @ array.jl:1019 within `setindex!`
    call void @llvm.memset.p0i8.i64(i8* nonnull align 8 %.data1013, i8 0, i64 %3, i1 false)
; └└
;  @ array.jl:629 within `zeros`
  br label %L30

L30:                                              ; preds = %L13.preheader, %top
  ret {}* %0
}
```
</details>
  • Loading branch information
staticfloat authored Jul 23, 2023
2 parents 092231c + 90c0e19 commit 3d944dd
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 0 deletions.
8 changes: 8 additions & 0 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7447,6 +7447,14 @@ static jl_llvm_functions_t
declarations.functionObject = needsparams ? "jl_fptr_sparam" : "jl_fptr_args";
}

if (ctx.emission_context.debug_level >= 2 && lam->def.method && jl_is_method(lam->def.method) && lam->specTypes != (jl_value_t*)jl_emptytuple_type) {
ios_t sigbuf;
ios_mem(&sigbuf, 0);
jl_static_show_func_sig((JL_STREAM*) &sigbuf, (jl_value_t*)lam->specTypes);
f->addFnAttr("julia.fsig", StringRef(sigbuf.buf, sigbuf.size));
ios_close(&sigbuf);
}

AttrBuilder FnAttrs(ctx.builder.getContext(), f->getAttributes().getFnAttrs());
AttrBuilder RetAttrs(ctx.builder.getContext(), f->getAttributes().getRetAttrs());

Expand Down
4 changes: 4 additions & 0 deletions src/disasm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,10 @@ class LineNumberAnnotatedWriter : public AssemblyAnnotationWriter {
void LineNumberAnnotatedWriter::emitFunctionAnnot(
const Function *F, formatted_raw_ostream &Out)
{
if (F->hasFnAttribute("julia.fsig")) {
auto sig = F->getFnAttribute("julia.fsig").getValueAsString();
Out << "; Function Signature: " << sig << "\n";
}
InstrLoc = nullptr;
DISubprogram *FuncLoc = F->getSubprogram();
if (!FuncLoc) {
Expand Down

0 comments on commit 3d944dd

Please sign in to comment.