Skip to content

Commit 5f06d85

Browse files
committed
code_llvm: print source locations
Supplements the printing of LLVM IR with source location information
1 parent eb133ab commit 5f06d85

File tree

7 files changed

+290
-203
lines changed

7 files changed

+290
-203
lines changed

src/Makefile

+4-3
Original file line numberDiff line numberDiff line change
@@ -183,10 +183,11 @@ $(BUILDDIR)/julia_flisp.boot: $(addprefix $(SRCDIR)/,jlfrontend.scm flisp/aliase
183183

184184
# additional dependency links
185185
$(BUILDDIR)/ast.o $(BUILDDIR)/ast.dbg.obj: $(BUILDDIR)/julia_flisp.boot.inc $(SRCDIR)/flisp/*.h
186-
$(BUILDDIR)/codegen.o $(BUILDDIR)/codegen.dbg.obj: $(addprefix $(SRCDIR)/,intrinsics.cpp jitlayers.h intrinsics.h codegen_internal.h cgutils.cpp ccall.cpp abi_*.cpp)
186+
$(BUILDDIR)/codegen.o $(BUILDDIR)/codegen.dbg.obj: $(addprefix $(SRCDIR)/,\
187+
intrinsics.cpp jitlayers.h intrinsics.h debuginfo.h codegen_shared.h cgutils.cpp ccall.cpp abi_*.cpp)
187188
$(BUILDDIR)/anticodegen.o $(BUILDDIR)/anticodegen.dbg.obj: $(SRCDIR)/intrinsics.h
188-
$(BUILDDIR)/debuginfo.o $(BUILDDIR)/debuginfo.dbg.obj: $(SRCDIR)/codegen_internal.h
189-
$(BUILDDIR)/disasm.o $(BUILDDIR)/disasm.dbg.obj: $(SRCDIR)/codegen_internal.h
189+
$(BUILDDIR)/debuginfo.o $(BUILDDIR)/debuginfo.dbg.obj: $(SRCDIR)/debuginfo.h
190+
$(BUILDDIR)/disasm.o $(BUILDDIR)/disasm.dbg.obj: $(SRCDIR)/debuginfo.h
190191
$(BUILDDIR)/jitlayers.o $(BUILDDIR)/jitlayers.dbg.obj: $(SRCDIR)/jitlayers.h
191192
$(BUILDDIR)/builtins.o $(BUILDDIR)/builtins.dbg.obj: $(SRCDIR)/table.c
192193
$(BUILDDIR)/gc.o $(BUILDDIR)/gc.dbg.obj: $(SRCDIR)/gc.h

src/codegen.cpp

+4-153
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ namespace llvm {
9999
#include "julia.h"
100100
#include "julia_internal.h"
101101
#include "jitlayers.h"
102-
#include "codegen_internal.h"
102+
#include "codegen_shared.h"
103103

104104
// LLVM version compatibility macros
105105
legacy::PassManager *jl_globalPM;
@@ -1586,168 +1586,20 @@ void *jl_get_llvmf_decl(jl_method_instance_t *linfo, size_t world, bool getwrapp
15861586
}
15871587
}
15881588

1589-
1590-
// print an llvm IR acquired from jl_get_llvmf
1591-
// warning: this takes ownership of, and destroys, f->getParent()
1592-
extern "C" JL_DLLEXPORT
1593-
const jl_value_t *jl_dump_function_ir(void *f, bool strip_ir_metadata, bool dump_module)
1594-
{
1595-
std::string code;
1596-
llvm::raw_string_ostream stream(code);
1597-
1598-
Function *llvmf = dyn_cast_or_null<Function>((Function*)f);
1599-
if (!llvmf || (!llvmf->isDeclaration() && !llvmf->getParent()))
1600-
jl_error("jl_dump_function_ir: Expected Function* in a temporary Module");
1601-
1602-
JL_LOCK(&codegen_lock); // Might GC
1603-
if (!llvmf->getParent()) {
1604-
// print the function declaration as-is
1605-
llvmf->print(stream);
1606-
delete llvmf;
1607-
}
1608-
else {
1609-
Module *m = llvmf->getParent();
1610-
if (strip_ir_metadata) {
1611-
// strip metadata from all instructions in the module
1612-
for (Module::iterator I = m->begin(), E = m->end(); I != E; ++I) {
1613-
Function *f2 = &*I;
1614-
Function::BasicBlockListType::iterator f2_bb = f2->getBasicBlockList().begin();
1615-
// iterate over all basic blocks in the function
1616-
for (; f2_bb != f2->getBasicBlockList().end(); ++f2_bb) {
1617-
BasicBlock::InstListType::iterator f2_il = (*f2_bb).getInstList().begin();
1618-
// iterate over instructions in basic block
1619-
for (; f2_il != (*f2_bb).getInstList().end(); ) {
1620-
Instruction *inst = &*f2_il++;
1621-
// remove dbg.declare and dbg.value calls
1622-
if (isa<DbgDeclareInst>(inst) || isa<DbgValueInst>(inst)) {
1623-
inst->eraseFromParent();
1624-
continue;
1625-
}
1626-
1627-
SmallVector<std::pair<unsigned, MDNode*>, 4> MDForInst;
1628-
inst->getAllMetadata(MDForInst);
1629-
SmallVector<std::pair<unsigned, MDNode*>, 4>::iterator md_iter = MDForInst.begin();
1630-
1631-
// iterate over all metadata kinds and set to NULL to remove
1632-
for (; md_iter != MDForInst.end(); ++md_iter) {
1633-
inst->setMetadata((*md_iter).first, NULL);
1634-
}
1635-
}
1636-
}
1637-
}
1638-
}
1639-
if (dump_module) {
1640-
m->print(stream, NULL);
1641-
}
1642-
else {
1643-
llvmf->print(stream);
1644-
}
1645-
delete m;
1646-
}
1647-
JL_UNLOCK(&codegen_lock); // Might GC
1648-
1649-
return jl_pchar_to_string(stream.str().data(), stream.str().size());
1650-
}
1651-
1652-
// This isn't particularly fast, but it's only used for interactive mode
1653-
static uint64_t compute_obj_symsize(const object::ObjectFile *obj, uint64_t offset)
1654-
{
1655-
// Scan the object file for the closest symbols above and below offset in the .text section
1656-
uint64_t lo = 0;
1657-
uint64_t hi = 0;
1658-
bool setlo = false;
1659-
for (const object::SectionRef &Section : obj->sections()) {
1660-
uint64_t SAddr, SSize;
1661-
if (!Section.isText()) continue;
1662-
SAddr = Section.getAddress();
1663-
SSize = Section.getSize();
1664-
if (offset < SAddr || offset >= SAddr + SSize) continue;
1665-
assert(hi == 0);
1666-
1667-
// test for lower and upper symbol bounds relative to other symbols
1668-
hi = SAddr + SSize;
1669-
object::section_iterator ESection = obj->section_end();
1670-
for (const object::SymbolRef &Sym : obj->symbols()) {
1671-
uint64_t Addr;
1672-
object::section_iterator Sect = ESection;
1673-
auto SectOrError = Sym.getSection();
1674-
assert(SectOrError);
1675-
Sect = SectOrError.get();
1676-
if (Sect == ESection) continue;
1677-
if (Sect != Section) continue;
1678-
auto AddrOrError = Sym.getAddress();
1679-
assert(AddrOrError);
1680-
Addr = AddrOrError.get();
1681-
if (Addr <= offset && Addr >= lo) {
1682-
// test for lower bound on symbol
1683-
lo = Addr;
1684-
setlo = true;
1685-
}
1686-
if (Addr > offset && Addr < hi) {
1687-
// test for upper bound on symbol
1688-
hi = Addr;
1689-
}
1690-
}
1691-
}
1692-
if (setlo)
1693-
return hi - lo;
1694-
return 0;
1695-
}
1696-
1697-
// print a native disassembly for f (an LLVM function)
1589+
// get a native disassembly for f (an LLVM function)
16981590
// warning: this takes ownership of, and destroys, f
16991591
extern "C" JL_DLLEXPORT
1700-
const jl_value_t *jl_dump_function_asm(void *f, int raw_mc, const char* asm_variant="att")
1592+
const jl_value_t *jl_dump_function_asm(void *f, int raw_mc, const char* asm_variant)
17011593
{
1702-
jl_ptls_t ptls = jl_get_ptls_states();
1703-
std::string code;
1704-
llvm::raw_string_ostream stream(code);
1705-
17061594
Function *llvmf = dyn_cast_or_null<Function>((Function*)f);
17071595
if (!llvmf)
17081596
jl_error("jl_dump_function_asm: Expected Function*");
1709-
1710-
// Dump assembly code
1711-
uint64_t symsize = 0;
1712-
int64_t slide = 0, section_slide = 0;
17131597
uint64_t fptr = getAddressForFunction(llvmf->getName());
17141598
// Look in the system image as well
17151599
if (fptr == 0)
17161600
fptr = (uintptr_t)jl_ExecutionEngine->getPointerToGlobalIfAvailable(llvmf);
17171601
delete llvmf;
1718-
1719-
llvm::DIContext *context = NULL;
1720-
llvm::DIContext *&objcontext = context;
1721-
const object::ObjectFile *object = NULL;
1722-
assert(fptr != 0);
1723-
if (!jl_DI_for_fptr(fptr, &symsize, &slide, &section_slide, &object, &context)) {
1724-
if (!jl_dylib_DI_for_fptr(fptr, &object, &objcontext, &slide, &section_slide, false,
1725-
NULL, NULL, NULL, NULL)) {
1726-
jl_printf(JL_STDERR, "WARNING: Unable to find function pointer\n");
1727-
return jl_pchar_to_string("", 0);
1728-
}
1729-
}
1730-
if (symsize == 0 && object != NULL)
1731-
symsize = compute_obj_symsize(object, fptr + slide + section_slide);
1732-
if (symsize == 0) {
1733-
jl_printf(JL_STDERR, "WARNING: Could not determine size of symbol\n");
1734-
return jl_pchar_to_string("", 0);
1735-
}
1736-
1737-
if (raw_mc) {
1738-
return (jl_value_t*)jl_pchar_to_array((char*)fptr, symsize);
1739-
}
1740-
1741-
int8_t gc_state = jl_gc_safe_enter(ptls);
1742-
jl_dump_asm_internal(fptr, symsize, slide,
1743-
object, objcontext,
1744-
stream,
1745-
asm_variant
1746-
);
1747-
1748-
jl_gc_safe_leave(ptls, gc_state);
1749-
1750-
return jl_pchar_to_string(stream.str().data(), stream.str().size());
1602+
return jl_dump_fptr_asm(fptr, raw_mc, asm_variant);
17511603
}
17521604

17531605
// Logging for code coverage and memory allocation
@@ -6951,7 +6803,6 @@ extern "C" void *jl_init_llvm(void)
69516803
EngineBuilder eb((std::unique_ptr<Module>(engine_module)));
69526804
std::string ErrorStr;
69536805
eb .setEngineKind(EngineKind::JIT)
6954-
.setMCJITMemoryManager(std::unique_ptr<RTDyldMemoryManager>{createRTDyldMemoryManager()})
69556806
.setTargetOptions(options)
69566807
// Generate simpler code for JIT
69576808
.setRelocationModel(Reloc::Static)

src/codegen_internal.h

-27
This file was deleted.

src/debuginfo.cpp

+8-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ using llvm_file_magic = sys::fs::file_magic;
3434

3535
#include "julia.h"
3636
#include "julia_internal.h"
37-
#include "codegen_internal.h"
37+
#include "debuginfo.h"
3838
#if defined(_OS_LINUX_)
3939
# include <link.h>
4040
#endif
@@ -89,6 +89,13 @@ void jl_add_linfo_in_flight(StringRef name, jl_method_instance_t *linfo, const D
8989
linfo_in_flight[mangle(name, DL)] = linfo;
9090
}
9191

92+
93+
#ifdef _OS_WINDOWS_
94+
#if defined(_CPU_X86_64_)
95+
void *lookupWriteAddressFor(RTDyldMemoryManager *memmgr, void *rt_addr);
96+
#endif
97+
#endif
98+
9299
#if defined(_OS_WINDOWS_)
93100
static void create_PRUNTIME_FUNCTION(uint8_t *Code, size_t Size, StringRef fnname,
94101
uint8_t *Section, size_t Allocated, uint8_t *UnwindData)

src/debuginfo.h

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// This file is a part of Julia. License is MIT: https://julialang.org/license
2+
3+
// Declarations for debuginfo.cpp
4+
5+
extern int jl_DI_for_fptr(uint64_t fptr, uint64_t *symsize, int64_t *slide, int64_t *section_slide,
6+
const object::ObjectFile **object,
7+
llvm::DIContext **context);
8+
9+
extern bool jl_dylib_DI_for_fptr(size_t pointer, const object::ObjectFile **object, llvm::DIContext **context,
10+
int64_t *slide, int64_t *section_slide,
11+
bool onlySysImg, bool *isSysImg, void **saddr, char **name, char **filename);

0 commit comments

Comments
 (0)