From 78a13a9cb2bf5128de21d5de902fd272408a7e29 Mon Sep 17 00:00:00 2001 From: Meow King Date: Thu, 8 Aug 2024 16:47:43 +0800 Subject: [PATCH] feat: target module --- CMakeLists.txt | 32 +++++++- docs/source/index.rst | 1 + justfile | 4 +- src/llvm/Core/miscClasses.cpp | 25 +++++- src/llvm/Target.cpp | 148 +++++++++++++++++++++++++++++++++- src/llvm/Target.h | 122 ++++++++++++++++++++++++++++ src/llvm/TargetMachine.cpp | 2 +- src/llvm/types_priv.h | 11 ++- 8 files changed, 334 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9f125bc..028d59c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -97,12 +97,40 @@ else() llvm_map_components_to_libnames(llvm_libs core transformutils analysis support target bitwriter bitreader - aarch64disassembler amdgpudisassembler armdisassembler avrdisassembler bpfdisassembler hexagondisassembler lanaidisassembler loongarchdisassembler mcdisassembler mipsdisassembler msp430disassembler powerpcdisassembler riscvdisassembler sparcdisassembler systemzdisassembler vedisassembler webassemblydisassembler x86disassembler xcoredisassembler + + # Disassembler & Target + + aarch64disassembler amdgpudisassembler armdisassembler avrdisassembler bpfdisassembler + hexagondisassembler lanaidisassembler loongarchdisassembler mcdisassembler + mipsdisassembler msp430disassembler powerpcdisassembler riscvdisassembler + sparcdisassembler systemzdisassembler vedisassembler webassemblydisassembler + x86disassembler xcoredisassembler + + # Target + + aarch64info amdgpuinfo arminfo avrinfo bpfinfo hexagoninfo lanaiinfo loongarchinfo + mipsinfo msp430info nvptxinfo powerpcinfo riscvinfo sparcinfo systemzinfo veinfo + webassemblyinfo x86info xcoreinfo + + aarch64desc amdgpudesc armdesc avrdesc bpfdesc hexagondesc lanaidesc loongarchdesc + mipsdesc msp430desc nvptxdesc powerpcdesc riscvdesc sparcdesc systemzdesc vedesc + webassemblydesc x86desc xcoredesc + + aarch64codegen amdgpucodegen armcodegen avrcodegen bpfcodegen codegen codegentypes + hexagoncodegen lanaicodegen loongarchcodegen mipscodegen msp430codegen nativecodegen + nvptxcodegen powerpccodegen riscvcodegen sparccodegen systemzcodegen vecodegen + webassemblycodegen x86codegen xcorecodegen + + aarch64asmparser amdgpuasmparser armasmparser asmparser avrasmparser bpfasmparser + hexagonasmparser lanaiasmparser loongarchasmparser mcparser mipsasmparser mirparser + msp430asmparser powerpcasmparser riscvasmparser sparcasmparser systemzasmparser + targetparser veasmparser webassemblyasmparser x86asmparser + ) endif() -message(INFO " ${llvm_libs}") +# message(INFO " ${llvm_libs}") target_link_libraries(llvmpym_ext PRIVATE ${llvm_libs} fmt::fmt) diff --git a/docs/source/index.rst b/docs/source/index.rst index 7c430d5..9692149 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -77,6 +77,7 @@ Status "``Analysis.h``", "``core``, ``analysis``", "``ErrorHandling.h``", "``error_handling``" "``Support.h``", "``support``" + "``Target.h``", "``target``, ``core``" "``TargetMachine.h``", "``target_machine``" "``BitReader.h``", "``bit_reader``, ``core``" "``BitWriter.h``", "``core``" diff --git a/justfile b/justfile index 717fc28..c76228d 100644 --- a/justfile +++ b/justfile @@ -48,6 +48,8 @@ find-components build_dir symbol: list-llvm-components: '{{LLVM-CONFIG}}' --components | tr " " "\n" | less - + +search-components component: + @llvm-config --components | tr ' ' '\n' | grep '{{component}}' | paste -sd ' ' - diff --git a/src/llvm/Core/miscClasses.cpp b/src/llvm/Core/miscClasses.cpp index d2cf1fd..07fcb2c 100644 --- a/src/llvm/Core/miscClasses.cpp +++ b/src/llvm/Core/miscClasses.cpp @@ -98,12 +98,15 @@ void bindOtherClasses(nb::module_ &m) { nb::class_> (m, "MemoryBuffer", "MemoryBuffer"); - // no need to create PymPassManagerBase binding + auto PassManagerBaseClass = + nb::class_> + (m, "PassManager", "PassManager"); auto PassManagerClass = - nb::class_> + nb::class_ (m, "PassManager", "PassManager"); - auto FunctionPassManagerClass = nb::class_ - (m, "FunctionPassManager", "FunctionPassManager"); + auto FunctionPassManagerClass = + nb::class_ + (m, "FunctionPassManager", "FunctionPassManager"); MetadataClass .def("__repr__", @@ -158,6 +161,13 @@ void bindOtherClasses(nb::module_ &m) { }, "context"_a); + PassManagerBaseClass + .def("add_target_library_info", + [](PymPassManagerBase &self, PymTargetLibraryInfo &tli) { + return LLVMAddTargetLibraryInfo(tli.get(), self.get()); + }, + "target_lib_info"_a); + PassManagerClass .def("__repr__", @@ -1439,6 +1449,13 @@ void bindOtherClasses(nb::module_ &m) { return &self; }) .def("__exit__", [](PymModule &self, nb::args args, nb::kwargs kwargs) {}) + .def_prop_rw("data_layout", + [](PymModule &self) { + return PymTargetData(LLVMGetModuleDataLayout(self.get())); + }, + [](PymModule &self, PymTargetData &td) { + return LLVMSetModuleDataLayout(self.get(), td.get()); + }) .def_prop_ro("first_global_variable", [](PymModule &m) -> optional { auto res = LLVMGetFirstGlobal(m.get()); diff --git a/src/llvm/Target.cpp b/src/llvm/Target.cpp index 6c22a64..63587a9 100644 --- a/src/llvm/Target.cpp +++ b/src/llvm/Target.cpp @@ -3,6 +3,7 @@ #include #include #include "types_priv.h" +#include "utils_priv.h" namespace nb = nanobind; using namespace nb::literals; @@ -10,6 +11,151 @@ using namespace nb::literals; void populateTarget(nb::module_ &m) { auto TargetDataClass = nb::class_> - (m, "TargetData", "TargetData"); + (m, "TargetData", "TargetData"); + + auto TargetLibraryInfoClass = + nb::class_> + (m, "TargetData", "TargetData"); + + + nb::enum_(m, "ByteOrdering", "ByteOrdering") + .value("BigEndian", LLVMByteOrdering::LLVMBigEndian) + .value("LittleEndian", LLVMByteOrdering::LLVMLittleEndian); + + + PYM_TARGET_FOR_EACH_INIT_TARGET_INFO(); + PYM_TARGET_FOR_EACH_INIT_TARGET(); + PYM_TARGET_FOR_EACH_INIT_TARGET_MC(); + PYM_ASM_PRINTER_FOR_EACH_INIT_ASM_PRINTER(); + PYM_TARGET_FOR_EACH_INIT_ASM_PARSER(); + PYM_DISASSEMBLER_FOR_EACH_INIT_DISASSEMBLER(); + + m.def("init_all_target_infos", &LLVMInitializeAllTargetInfos); + m.def("init_all_targets", &LLVMInitializeAllTargets); + m.def("init_all_target_m_cs", &LLVMInitializeAllTargetMCs); + m.def("init_all_asm_printers", &LLVMInitializeAllAsmPrinters); + m.def("init_all_asm_parsers", &LLVMInitializeAllAsmParsers); + m.def("init_all_disassemblers", &LLVMInitializeAllDisassemblers); + + m.def("init_native_target", + []() { + return LLVMInitializeNativeTarget() != 0; + }, + "The main program should call this function to" + "initialize the native target corresponding to the host. This is useful" + "for JIT applications to ensure that the target gets linked in correctly."); + + m.def("init_native_asm_parser", + []() { + return LLVMInitializeNativeAsmParser() != 0; + }); + + m.def("init_native_asm_printer", + []() { + return LLVMInitializeNativeAsmPrinter() != 0; + }); + + m.def("init_native_disassembler", + []() { + return LLVMInitializeNativeDisassembler() != 0; + }); + + TargetDataClass + .def("__str__", + [](PymTargetData &self) { + auto res = LLVMCopyStringRepOfTargetData(self.get()); + RETURN_MESSAGE(res); + }) + .def_prop_ro("byte_order", + [](PymTargetData &self) { + return LLVMByteOrder(self.get()); + }) + .def_prop_ro("ptr_size", + [](PymTargetData &self) { + return LLVMPointerSize(self.get()); + }) + .def_prop_ro("int_ptr", + [](PymTargetData &self) { + return PymTypePointer(LLVMIntPtrType(self.get())); + }, + "Returns the integer type that is the same size as a pointer " + "on a target.") + .def("__init__", + [](PymTargetData *td, const char *stringRep) { + new (td) PymTargetData(LLVMCreateTargetData(stringRep)); + }, + "string_rep"_a) + .def("get_ptr_size_for_addr_space", + [](PymTargetData &self, unsigned AS) { + return LLVMPointerSizeForAS(self.get(), AS); + }, + "as"_a) + .def("get_int_ptr_for_addr_space", + [](PymTargetData &self, unsigned AS) { + return PymTypePointer(LLVMIntPtrTypeForAS(self.get(), AS)); + }, + "as"_a) + .def("get_int_ptr_for_addr_space_in_context", + [](PymTargetData &self, PymContext &context, unsigned AS) { + auto res = LLVMIntPtrTypeForASInContext(context.get(), self.get(), AS); + return PymTypePointer(res); + }, + "context"_a, "as"_a) + .def("size_of_type_in_bits", + [](PymTargetData &self, PymType &t) { + return LLVMSizeOfTypeInBits(self.get(), t.get()); + }, + "type"_a, + "Computes the size of a type in bytes for a target.") + .def("store_size_of_type", + [](PymTargetData &self, PymType &t) { + return LLVMStoreSizeOfType(self.get(), t.get()); + }, + "type"_a, + "Computes the storage size of a type in bytes for a target.") + .def("abi_size_of_type", + [](PymTargetData &self, PymType &t) { + return LLVMABISizeOfType(self.get(), t.get()); + }, + "type"_a, + "Computes the ABI size of a type in bytes for a target.") + .def("abi_alignment_of_type", + [](PymTargetData &self, PymType &t) { + return LLVMABIAlignmentOfType(self.get(), t.get()); + }, + "type"_a, + "Computes the ABI alignment of a type in bytes for a target.") + .def("call_frame_alignment_of_type", + [](PymTargetData &self, PymType &t) { + return LLVMCallFrameAlignmentOfType(self.get(), t.get()); + }, + "type"_a, + "Computes the call frame alignment of a type in bytes for a target.") + .def("preferred_alignment_of_type", + [](PymTargetData &self, PymType &t) { + return LLVMPreferredAlignmentOfType(self.get(), t.get()); + }, + "type"_a, + "Computes the preferred alignment of a type in bytes for a target.") + .def("preferred_alignment_of_global", + [](PymTargetData &self, PymGlobalVariable &gv) { + return LLVMPreferredAlignmentOfGlobal(self.get(), gv.get()); + }, + "gv"_a, + "Computes the preferred alignment of a global variable in bytes for a target.") + .def("element_at_offset", + [](PymTargetData &self, PymTypeStruct &st, unsigned long long offset) { + return LLVMElementAtOffset(self.get(), st.get(), offset); + }, + "st"_a, "offset"_a, + "Computes the structure element that contains the byte offset for a target.") + .def("offset_of_element", + [](PymTargetData &self, PymTypeStruct &st, unsigned element) { + return LLVMOffsetOfElement(self.get(), st.get(), element); + }, + "st"_a, "element"_a, + "Computes the byte offset of the indexed struct element for a target."); + } diff --git a/src/llvm/Target.h b/src/llvm/Target.h index 432aa56..d46dd17 100644 --- a/src/llvm/Target.h +++ b/src/llvm/Target.h @@ -3,6 +3,128 @@ #include +#define PYM_TARGET_INIT_TARGET_INFO(TargetName, LowerCase) \ + m.def("init_" #LowerCase "_target_info", &LLVMInitialize##TargetName##TargetInfo); + +#define PYM_TARGET_INIT_TARGET(TargetName, LowerCase) \ + m.def("init_" #LowerCase, &LLVMInitialize##TargetName##Target); + +#define PYM_TARGET_INIT_TARGET_MC(TargetName, LowerCase) \ + m.def("init_" #LowerCase "_mc", &LLVMInitialize##TargetName##TargetMC); + +#define PYM_ASM_PRINTER_INIT_ASM_PRINTER(TargetName, LowerCase) \ + m.def("init_" #LowerCase "_asm_printer", &LLVMInitialize##TargetName##AsmPrinter); + +#define PYM_ASM_PARSER_INIT_ASM_PARSER(TargetName, LowerCase) \ + m.def("init_" #LowerCase "_asm_parser", &LLVMInitialize##TargetName##AsmParser); + +#define PYM_DISASSEMBLER_INIT_DISASSEMBLER(TargetName, LowerCase) \ + m.def("init_" #LowerCase "_disassembler", &LLVMInitialize##TargetName##Disassembler); + +#define PYM_TARGET_FOR_EACH(macro) \ + macro(AArch64, aarch64) \ + macro(AMDGPU, amdgpu) \ + macro(ARM, arm) \ + macro(AVR, avr) \ + macro(BPF, bpf) \ + macro(Hexagon, hexagon) \ + macro(Lanai, lanai) \ + macro(LoongArch, loongarch) \ + macro(Mips, mips) \ + macro(MSP430, msp430) \ + macro(NVPTX, nvptx) \ + macro(PowerPC, powerpc) \ + macro(RISCV, riscv) \ + macro(Sparc, sparc) \ + macro(SystemZ, systemz) \ + macro(VE, ve) \ + macro(WebAssembly, webassembly) \ + macro(X86, x86) \ + macro(XCore, xcore) + + +#define PYM_ASM_PRINTER_FOR_EACH(macro) \ + macro(AArch64, aarch64) \ + macro(AMDGPU, amdgpu) \ + macro(ARM, arm) \ + macro(AVR, avr) \ + macro(BPF, bpf) \ + macro(Hexagon, hexagon) \ + macro(Lanai, lanai) \ + macro(LoongArch, loongarch) \ + macro(Mips, mips) \ + macro(MSP430, msp430) \ + macro(NVPTX, nvptx) \ + macro(PowerPC, powerpc) \ + macro(RISCV, riscv) \ + macro(Sparc, sparc) \ + macro(SystemZ, systemz) \ + macro(VE, ve) \ + macro(WebAssembly, webassembly) \ + macro(X86, x86) \ + macro(XCore, xcore) + + +#define PYM_DISASSEMBLER_FOR_EACH(macro) \ + macro(AArch64, aarch64) \ + macro(AMDGPU, amdgpu) \ + macro(ARM, arm) \ + macro(AVR, avr) \ + macro(BPF, bpf) \ + macro(Hexagon, hexagon) \ + macro(Lanai, lanai) \ + macro(LoongArch, loongarch) \ + macro(Mips, mips) \ + macro(MSP430, msp430) \ + macro(NVPTX, nvptx) \ + macro(PowerPC, powerpc) \ + macro(RISCV, riscv) \ + macro(Sparc, sparc) \ + macro(SystemZ, systemz) \ + macro(VE, ve) \ + macro(WebAssembly, webassembly) \ + macro(X86, x86) \ + macro(XCore, xcore) + +#define PYM_ASM_PARSER_FOR_EACH(macro) \ + macro(AArch64, aarch64) \ + macro(AMDGPU, amdgpu) \ + macro(ARM, arm) \ + macro(AVR, avr) \ + macro(BPF, bpf) \ + macro(Hexagon, hexagon) \ + macro(Lanai, lanai) \ + macro(LoongArch, loongarch) \ + macro(Mips, mips) \ + macro(MSP430, msp430) \ + macro(PowerPC, powerpc) \ + macro(RISCV, riscv) \ + macro(Sparc, sparc) \ + macro(SystemZ, systemz) \ + macro(VE, ve) \ + macro(WebAssembly, webassembly) \ + macro(X86, x86) + + +#define PYM_TARGET_FOR_EACH_INIT_TARGET_INFO() \ + PYM_TARGET_FOR_EACH(PYM_TARGET_INIT_TARGET_INFO) + +#define PYM_TARGET_FOR_EACH_INIT_TARGET() \ + PYM_TARGET_FOR_EACH(PYM_TARGET_INIT_TARGET_INFO) + +#define PYM_TARGET_FOR_EACH_INIT_TARGET_MC() \ + PYM_TARGET_FOR_EACH(PYM_TARGET_INIT_TARGET_MC) + +#define PYM_ASM_PRINTER_FOR_EACH_INIT_ASM_PRINTER() \ + PYM_ASM_PRINTER_FOR_EACH(PYM_ASM_PRINTER_INIT_ASM_PRINTER) + +#define PYM_TARGET_FOR_EACH_INIT_ASM_PARSER() \ + PYM_ASM_PARSER_FOR_EACH(PYM_ASM_PARSER_INIT_ASM_PARSER) + +#define PYM_DISASSEMBLER_FOR_EACH_INIT_DISASSEMBLER() \ + PYM_ASM_PARSER_FOR_EACH(PYM_DISASSEMBLER_INIT_DISASSEMBLER) + + void populateTarget(nanobind::module_ &m); diff --git a/src/llvm/TargetMachine.cpp b/src/llvm/TargetMachine.cpp index 3a682ca..eb1bdd8 100644 --- a/src/llvm/TargetMachine.cpp +++ b/src/llvm/TargetMachine.cpp @@ -254,7 +254,7 @@ void populateTargetMachine(nanobind::module_ &m) { }, "module"_a, "codegen"_a) .def("add_analysis_passes", - [](PymTargetMachine &self, PymPassManager &pm) { + [](PymTargetMachine &self, PymPassManagerBase &pm) { return LLVMAddAnalysisPasses(self.get(), pm.get()); }, "pm"_a, diff --git a/src/llvm/types_priv.h b/src/llvm/types_priv.h index c45ce6d..e138e65 100644 --- a/src/llvm/types_priv.h +++ b/src/llvm/types_priv.h @@ -295,7 +295,9 @@ enum class PymLLVMFastMathFlags { \ BIND_PYLLVMOBJECT_(PymTargetData, LLVMTargetDataRef, PymTargetDataObject) \ \ - BIND_PYLLVMOBJECT_(PymDisasmContext, LLVMDisasmContextRef, PymDisasmContextObject) + BIND_PYLLVMOBJECT_(PymDisasmContext, LLVMDisasmContextRef, PymDisasmContextObject) \ +\ + BIND_PYLLVMOBJECT_(PymTargetLibraryInfo, LLVMTargetLibraryInfoRef, PymTargetLibraryInfoObject) // Core -------------------------------------------------------- @@ -328,7 +330,6 @@ PY_FOR_EACH_TYPE_CLASS_RELASIONSHIP(DEFINE_DIRECT_SUB_CLASS) DEFINE_PY_WRAPPER_CLASS(PymIntrinsic, unsigned) - DEFINE_DIRECT_SUB_CLASS(PymPassManagerBase, PymPassManager); DEFINE_DIRECT_SUB_CLASS(PymPassManagerBase, PymFunctionPassManager); @@ -374,6 +375,10 @@ DEFINE_ITERATOR_CLASS(PymNamedMDNodeIterator, PymNamedMDNode, LLVMGetNextNamedMe DEFINE_ITERATOR_CLASS(PymFunctionIterator, PymFunction, LLVMGetNextFunction) +// Target + +DEFINE_PY_WRAPPER_CLASS(PymTargetLibraryInfo, LLVMTargetLibraryInfoRef) + // TargetMachine --------------------------------------------------------- @@ -381,5 +386,7 @@ DEFINE_PY_WRAPPER_CLASS(PymTarget, LLVMTargetRef) DEFINE_ITERATOR_CLASS(PymTargetIterator, PymTarget, LLVMGetNextTarget) +// TODO split the file to boost the compilation process + #endif