diff --git a/Dna.Example/Program.cs b/Dna.Example/Program.cs index d4e2a4b..f331099 100644 --- a/Dna.Example/Program.cs +++ b/Dna.Example/Program.cs @@ -691,7 +691,19 @@ LlvmUtilities.LLVMParseCommandLineOptions(new string[] { "-memdep-block-scan-lim for (int i = 0; i < 1; i++) { - LLVMInteropApi.Test(unicornTraceModule, ptr); + var result = LLVMInteropApi.Test(unicornTraceModule, ptr); + Console.WriteLine(""); + Console.WriteLine(result.Kind); + + var idk2 = result.ChildCount; + var idk3 = result.EntryRegion; + var idk4 = result.Id; + var idk5 = result.HeadBasicBlock; + var idk6 = result.EntryRegion; + var idk7 = result.Owner; + var idk1 = result.BasicBlock; + var idk8 = result.PredecessorCount; + var idk9 = result.SuccessorCount; LlvmUtilities.LLVMParseCommandLineOptions(new string[] { "test", "-memdep-block-scan-limit=10000000", diff --git a/Dna.LLVMInterop/API/ExportDef.h b/Dna.LLVMInterop/API/ExportDef.h new file mode 100644 index 0000000..f76cf91 --- /dev/null +++ b/Dna.LLVMInterop/API/ExportDef.h @@ -0,0 +1,5 @@ +#pragma once + +namespace Dna::API { + #define DNA_EXPORT extern "C" __declspec(dllexport) + } \ No newline at end of file diff --git a/Dna.LLVMInterop/ExportedApi.h b/Dna.LLVMInterop/API/ExportedAPI.h similarity index 92% rename from Dna.LLVMInterop/ExportedApi.h rename to Dna.LLVMInterop/API/ExportedAPI.h index 72b1b9c..9d99106 100644 --- a/Dna.LLVMInterop/ExportedApi.h +++ b/Dna.LLVMInterop/API/ExportedAPI.h @@ -47,6 +47,8 @@ #include "Utilities/magic_enum.hpp" +#include + using namespace llvm::sl; void DumpRegion(llvm::sl::Region* region) @@ -90,7 +92,7 @@ void DumpStructuredFunction(const llvm::sl::StructuredFunction& sfunc) DumpRegion(rootRegion); } -extern "C" __declspec(dllexport) void OptimizeModule(llvm::Module * module, Dna::Passes::tReadBinaryContents readBinaryContents) +extern "C" __declspec(dllexport) llvm::sl::Region* OptimizeModule(llvm::Module * module, Dna::Passes::tReadBinaryContents readBinaryContents) { printf("received llvm module."); @@ -200,4 +202,23 @@ extern "C" __declspec(dllexport) void OptimizeModule(llvm::Module * module, Dna: printf("got structured function."); DumpStructuredFunction(*structuredFunction); + + auto root = structuredFunction->getBody(); + + auto kind = root->get_kind(); + + auto str = magic_enum::enum_name(kind); + + printf("foo \n"); + std::printf( + "%.*s", + static_cast(str.length()), + str.data()); + + + auto childCt = root->getChildSize(); + + printf("The value of a : %zu", childCt); + + return root; } \ No newline at end of file diff --git a/Dna.LLVMInterop/API/OptimizationAPI/OptimizationAPI.h b/Dna.LLVMInterop/API/OptimizationAPI/OptimizationAPI.h new file mode 100644 index 0000000..0519ecb --- /dev/null +++ b/Dna.LLVMInterop/API/OptimizationAPI/OptimizationAPI.h @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Dna.LLVMInterop/API/RegionAPI/BaseRegionAPI.h b/Dna.LLVMInterop/API/RegionAPI/BaseRegionAPI.h new file mode 100644 index 0000000..aaafa76 --- /dev/null +++ b/Dna.LLVMInterop/API/RegionAPI/BaseRegionAPI.h @@ -0,0 +1,68 @@ +#pragma once + +#include "Passes/generator_jit_sl_function.h" +#include "API/ExportDef.h" +#include "Utilities/magic_enum.hpp" +using namespace llvm::sl; + +namespace Dna::API { + extern "C" __declspec(dllexport) uint32_t RegionGetKind(Region* region) + { + return region->get_kind(); + } + + DNA_EXPORT Region* RegionGetOwnerRegion(Region* region) + { + return region->getOwnerRegion(); + } + + DNA_EXPORT const Region* RegionGetEntryRegionBlock(Region* region) + { + return region->getEntryRegionBlock(); + } + + DNA_EXPORT size_t RegionGetId(Region* region) + { + return region->get_id(); + } + + DNA_EXPORT size_t RegionGetPredCount(Region* region) + { + return region->pred_size(); + } + + DNA_EXPORT Region* RegionGetPred(Region* region, size_t index) + { + return region->get_pred(index); + } + + DNA_EXPORT size_t RegionGetSuccCount(Region* region) + { + return region->succ_size(); + } + + DNA_EXPORT Region* RegionGetSucc(Region* region, size_t index) + { + return region->get_succ(index); + } + + DNA_EXPORT llvm::BasicBlock* RegionGetLLVMBasicBlock(Region* region) + { + return region->get_bb(); + } + + DNA_EXPORT llvm::BasicBlock* RegionGetHeadLLVMBasicBlock(Region* region) + { + return region->get_head_bb(); + } + + DNA_EXPORT size_t RegionGetChildCount(Region* region) + { + region->getChildSize(); + } + + DNA_EXPORT Region* RegionGetChild(Region* region, size_t index) + { + return region->getChild(index); + } +} \ No newline at end of file diff --git a/Dna.LLVMInterop/API/RegionAPI/ComplexRegionAPI.h b/Dna.LLVMInterop/API/RegionAPI/ComplexRegionAPI.h new file mode 100644 index 0000000..d3236c8 --- /dev/null +++ b/Dna.LLVMInterop/API/RegionAPI/ComplexRegionAPI.h @@ -0,0 +1,13 @@ +#pragma once + +#include "Passes/generator_jit_sl_function.h" +#include "API/ExportDef.h" +using namespace llvm::sl; + +namespace Dna::API { + DNA_EXPORT Region* ComplexRegionGetHead(RegionComplex* region) + { + return region->getHead(); + } + +} \ No newline at end of file diff --git a/Dna.LLVMInterop/API/RegionAPI/IfThenElseRegionAPI.h b/Dna.LLVMInterop/API/RegionAPI/IfThenElseRegionAPI.h new file mode 100644 index 0000000..bf61d4b --- /dev/null +++ b/Dna.LLVMInterop/API/RegionAPI/IfThenElseRegionAPI.h @@ -0,0 +1,13 @@ +#pragma once + +#include "Passes/generator_jit_sl_function.h" +#include "API/ExportDef.h" +using namespace llvm::sl; + +namespace Dna::API { + DNA_EXPORT Region* IfThenElseRegionGetElse(RegionIfThenElse* region) + { + return region->getElse(); + } + +} \ No newline at end of file diff --git a/Dna.LLVMInterop/API/RegionAPI/IfThenRegionAPI.h b/Dna.LLVMInterop/API/RegionAPI/IfThenRegionAPI.h new file mode 100644 index 0000000..6c585dd --- /dev/null +++ b/Dna.LLVMInterop/API/RegionAPI/IfThenRegionAPI.h @@ -0,0 +1,22 @@ +#pragma once + +#include "Passes/generator_jit_sl_function.h" +#include "API/ExportDef.h" +using namespace llvm::sl; + +namespace Dna::API { + DNA_EXPORT Region* IfThenRegionGetThen(RegionIfThen* region) + { + return region->getThen(); + } + + DNA_EXPORT bool IfThenRegionGetIsNegated(RegionIfThen* region) + { + return region->isNegated(); + } + + DNA_EXPORT llvm::Instruction* IfThenRegionGetLLVMTerminatorInstruction(RegionIfThen* region) + { + return region->get_terminator_inst(); + } +} \ No newline at end of file diff --git a/Dna.LLVMInterop/API/RegionAPI/RegionAPI.h b/Dna.LLVMInterop/API/RegionAPI/RegionAPI.h new file mode 100644 index 0000000..20c970c --- /dev/null +++ b/Dna.LLVMInterop/API/RegionAPI/RegionAPI.h @@ -0,0 +1,7 @@ +#pragma once` + +#include "BaseRegionAPI.h" +#include "ComplexRegionAPI.h" +#include "IfThenRegionAPI.h" +#include "IfThenElseRegionAPI.h" +#include "ReturnRegionAPI.h" \ No newline at end of file diff --git a/Dna.LLVMInterop/API/RegionAPI/ReturnRegionAPI.h b/Dna.LLVMInterop/API/RegionAPI/ReturnRegionAPI.h new file mode 100644 index 0000000..5905bc8 --- /dev/null +++ b/Dna.LLVMInterop/API/RegionAPI/ReturnRegionAPI.h @@ -0,0 +1,12 @@ +#pragma once + +#include "Passes/generator_jit_sl_function.h" +#include "API/ExportDef.h" +using namespace llvm::sl; + +namespace Dna::API { + DNA_EXPORT llvm::ReturnInst* ReturnRegionGetLLVMReturnInstruction(RegionReturn* region) + { + return region->get_return_inst(); + } +} \ No newline at end of file diff --git a/Dna.LLVMInterop/Dna.LLVMInterop.vcxproj b/Dna.LLVMInterop/Dna.LLVMInterop.vcxproj index 3cafabf..bb9802f 100644 --- a/Dna.LLVMInterop/Dna.LLVMInterop.vcxproj +++ b/Dna.LLVMInterop/Dna.LLVMInterop.vcxproj @@ -157,8 +157,16 @@ + + + + + + + + + - diff --git a/Dna.LLVMInterop/Dna.LLVMInterop.vcxproj.filters b/Dna.LLVMInterop/Dna.LLVMInterop.vcxproj.filters index 20866f5..d2a52ff 100644 --- a/Dna.LLVMInterop/Dna.LLVMInterop.vcxproj.filters +++ b/Dna.LLVMInterop/Dna.LLVMInterop.vcxproj.filters @@ -16,9 +16,6 @@ Arch\X86 - - API - Passes @@ -52,6 +49,33 @@ Utilities + + API + + + API\RegionAPI + + + API\RegionAPI + + + API\RegionAPI + + + API\RegionAPI + + + API\RegionAPI + + + API\OptimizationAPI + + + API + + + API\RegionAPI + @@ -93,6 +117,12 @@ {dc5b4ba6-84b8-49f6-b289-87600b5945b1} + + {06c71f36-bfee-4518-822e-152c6ef0275b} + + + {a9052d1b-7687-4796-96e4-3b6df6841c81} + diff --git a/Dna.LLVMInterop/Passes/generator_jit_ast_compute.cpp b/Dna.LLVMInterop/Passes/generator_jit_ast_compute.cpp index a758f1f..2c0edb1 100644 --- a/Dna.LLVMInterop/Passes/generator_jit_ast_compute.cpp +++ b/Dna.LLVMInterop/Passes/generator_jit_ast_compute.cpp @@ -744,6 +744,8 @@ StructuredFunction::StructuredFunction( // Destructor. StructuredFunction::~StructuredFunction() { + printf("destructor."); + return; while (!m_region_list.empty()) { Region *n = m_region_list.front(); m_region_list.pop_front(); @@ -1507,6 +1509,7 @@ StructuredControlFlowPass::StructuredControlFlowPass() // Destructor. StructuredControlFlowPass::~StructuredControlFlowPass() { + return; for (auto it : m_structured_function_map) { delete it.second; } diff --git a/Dna.LLVMInterop/Passes/generator_jit_sl_function.h b/Dna.LLVMInterop/Passes/generator_jit_sl_function.h index 171131b..b039af7 100644 --- a/Dna.LLVMInterop/Passes/generator_jit_sl_function.h +++ b/Dna.LLVMInterop/Passes/generator_jit_sl_function.h @@ -122,7 +122,10 @@ protected: } /// Destructor. - virtual ~Region() {} + virtual ~Region() + { + printf("destroyed."); + } public: /// Get the kind of the region. diff --git a/Dna.LLVMInterop/dllmain.cpp b/Dna.LLVMInterop/dllmain.cpp index 36dcd72..b678ec1 100644 --- a/Dna.LLVMInterop/dllmain.cpp +++ b/Dna.LLVMInterop/dllmain.cpp @@ -6,6 +6,6 @@ #include #include "llvm/Transforms/Scalar/SimpleLoopUnswitch.h" #include "llvm/Transforms/Utils/LowerSwitch.h" -#include +#include #include "Passes/ClassifyingAliasAnalysisPass.h" #include diff --git a/Dna/LLVMInterop/LLVMInteropApi.cs b/Dna/LLVMInterop/LLVMInteropApi.cs index 498db0c..039396f 100644 --- a/Dna/LLVMInterop/LLVMInteropApi.cs +++ b/Dna/LLVMInterop/LLVMInteropApi.cs @@ -1,4 +1,6 @@ -using LLVMSharp.Interop; +using Dna.LLVMInterop.Native; +using Dna.LLVMInterop.Wrapper; +using LLVMSharp.Interop; using System; using System.Collections.Generic; using System.Linq; @@ -11,9 +13,11 @@ namespace Dna.LLVMInterop { public static class LLVMInteropApi { - public unsafe static void Test(LLVMModuleRef module, IntPtr readBinaryContents) + public unsafe static Region Test(LLVMModuleRef module, IntPtr readBinaryContents) { - NativeLLVMInterop.VerifyModule(module, readBinaryContents); + nint ptr = NativeLLVMInterop.OptimizeModule(module, readBinaryContents); + + return Region.CreateRegion(ptr); } } } diff --git a/Dna/LLVMInterop/Native/NativeComplexRegionApi.cs b/Dna/LLVMInterop/Native/NativeComplexRegionApi.cs new file mode 100644 index 0000000..d4099ab --- /dev/null +++ b/Dna/LLVMInterop/Native/NativeComplexRegionApi.cs @@ -0,0 +1,17 @@ +using ELFSharp.MachO; +using LLVMSharp.Interop; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +namespace Dna.LLVMInterop.Native +{ + public class NativeComplexRegionApi + { + [DllImport("Dna.LLVMInterop", CallingConvention = CallingConvention.Cdecl, EntryPoint = "ComplexRegionGetHead")] + public unsafe static extern nint ComplexRegionGetHead(nint region); + } +} diff --git a/Dna/LLVMInterop/Native/NativeIfThenElseRegionApi.cs b/Dna/LLVMInterop/Native/NativeIfThenElseRegionApi.cs new file mode 100644 index 0000000..0004092 --- /dev/null +++ b/Dna/LLVMInterop/Native/NativeIfThenElseRegionApi.cs @@ -0,0 +1,16 @@ +using ELFSharp.MachO; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +namespace Dna.LLVMInterop.Native +{ + public static class NativeIfThenElseRegionApi + { + [DllImport("Dna.LLVMInterop", CallingConvention = CallingConvention.Cdecl, EntryPoint = "IfThenElseRegionGetElse")] + public unsafe static extern nint IfThenElseRegionGetElse(nint region); + } +} diff --git a/Dna/LLVMInterop/Native/NativeIfThenRegionApi.cs b/Dna/LLVMInterop/Native/NativeIfThenRegionApi.cs new file mode 100644 index 0000000..45fdb17 --- /dev/null +++ b/Dna/LLVMInterop/Native/NativeIfThenRegionApi.cs @@ -0,0 +1,22 @@ +using ELFSharp.MachO; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +namespace Dna.LLVMInterop.Native +{ + public class NativeIfThenRegionApi + { + [DllImport("Dna.LLVMInterop", CallingConvention = CallingConvention.Cdecl, EntryPoint = "IfThenRegionGetThen")] + public unsafe static extern nint IfThenRegionGetThen(nint region); + + [DllImport("Dna.LLVMInterop", CallingConvention = CallingConvention.Cdecl, EntryPoint = "IfThenRegionGetIsNegated")] + public unsafe static extern bool IfThenRegionGetIsNegated(nint region); + + [DllImport("Dna.LLVMInterop", CallingConvention = CallingConvention.Cdecl, EntryPoint = "IfThenRegionGetLLVMTerminatorInstruction")] + public unsafe static extern nint IfThenRegionGetLLVMTerminatorInstruction(nint region); + } +} diff --git a/Dna/LLVMInterop/Native/NativeRegionApi.cs b/Dna/LLVMInterop/Native/NativeRegionApi.cs index 8a05b0c..5da2469 100644 --- a/Dna/LLVMInterop/Native/NativeRegionApi.cs +++ b/Dna/LLVMInterop/Native/NativeRegionApi.cs @@ -72,36 +72,36 @@ namespace Dna.LLVMInterop.Native public unsafe static extern RegionKind RegionGetKind(nint region); [DllImport("Dna.LLVMInterop", CallingConvention = CallingConvention.Cdecl, EntryPoint = "RegionGetOwnerRegion")] - public unsafe static extern bool GetOwnerRegion(nint region, out nint ownerRegion); + public unsafe static extern nint RegionGetOwnerRegion(nint region); - [DllImport("Dna.LLVMInterop", CallingConvention = CallingConvention.Cdecl, EntryPoint = "RegionGetKind")] + [DllImport("Dna.LLVMInterop", CallingConvention = CallingConvention.Cdecl, EntryPoint = "RegionGetEntryRegionBlock")] public unsafe static extern nint RegionGetEntryRegionBlock(nint region); - [DllImport("Dna.LLVMInterop", CallingConvention = CallingConvention.Cdecl, EntryPoint = "RegionGetKind")] + [DllImport("Dna.LLVMInterop", CallingConvention = CallingConvention.Cdecl, EntryPoint = "RegionGetId")] public unsafe static extern ulong RegionGetId(nint region); - [DllImport("Dna.LLVMInterop", CallingConvention = CallingConvention.Cdecl, EntryPoint = "RegionGetKind")] + [DllImport("Dna.LLVMInterop", CallingConvention = CallingConvention.Cdecl, EntryPoint = "RegionGetPredCount")] public unsafe static extern ulong RegionGetPredCount(nint region); - [DllImport("Dna.LLVMInterop", CallingConvention = CallingConvention.Cdecl, EntryPoint = "RegionGetKind")] - public unsafe static extern nint RegionGetPred(nint region); + [DllImport("Dna.LLVMInterop", CallingConvention = CallingConvention.Cdecl, EntryPoint = "RegionGetPred")] + public unsafe static extern nint RegionGetPred(nint region, ulong index); - [DllImport("Dna.LLVMInterop", CallingConvention = CallingConvention.Cdecl, EntryPoint = "RegionGetKind")] + [DllImport("Dna.LLVMInterop", CallingConvention = CallingConvention.Cdecl, EntryPoint = "RegionGetSuccCount")] public unsafe static extern ulong RegionGetSuccCount(nint region); - [DllImport("Dna.LLVMInterop", CallingConvention = CallingConvention.Cdecl, EntryPoint = "RegionGetKind")] - public unsafe static extern nint RegionGetSucc(nint region); + [DllImport("Dna.LLVMInterop", CallingConvention = CallingConvention.Cdecl, EntryPoint = "RegionGetSucc")] + public unsafe static extern nint RegionGetSucc(nint region, ulong index); - [DllImport("Dna.LLVMInterop", CallingConvention = CallingConvention.Cdecl, EntryPoint = "RegionGetKind")] + [DllImport("Dna.LLVMInterop", CallingConvention = CallingConvention.Cdecl, EntryPoint = "RegionGetLLVMBasicBlock")] public unsafe static extern nint RegionGetLLVMBasicBlock(nint region); - [DllImport("Dna.LLVMInterop", CallingConvention = CallingConvention.Cdecl, EntryPoint = "RegionGetKind")] + [DllImport("Dna.LLVMInterop", CallingConvention = CallingConvention.Cdecl, EntryPoint = "RegionGetHeadLLVMBasicBlock")] public unsafe static extern nint RegionGetHeadLLVMBasicBlock(nint region); - [DllImport("Dna.LLVMInterop", CallingConvention = CallingConvention.Cdecl, EntryPoint = "RegionGetKind")] + [DllImport("Dna.LLVMInterop", CallingConvention = CallingConvention.Cdecl, EntryPoint = "RegionGetChildCount")] public unsafe static extern ulong RegionGetChildCount(nint region); - [DllImport("Dna.LLVMInterop", CallingConvention = CallingConvention.Cdecl, EntryPoint = "RegionGetKind")] - public unsafe static extern nint RegionGetChild(nint region); + [DllImport("Dna.LLVMInterop", CallingConvention = CallingConvention.Cdecl, EntryPoint = "RegionGetChild")] + public unsafe static extern nint RegionGetChild(nint region, ulong id); } } diff --git a/Dna/LLVMInterop/Native/NativeReturnRegionApi.cs b/Dna/LLVMInterop/Native/NativeReturnRegionApi.cs new file mode 100644 index 0000000..61ea6a9 --- /dev/null +++ b/Dna/LLVMInterop/Native/NativeReturnRegionApi.cs @@ -0,0 +1,16 @@ +using ELFSharp.MachO; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +namespace Dna.LLVMInterop.Native +{ + public class NativeReturnRegionApi + { + [DllImport("Dna.LLVMInterop", CallingConvention = CallingConvention.Cdecl, EntryPoint = "ReturnRegionGetLLVMReturnInstruction")] + public unsafe static extern nint ReturnRegionGetLLVMReturnInstruction(nint region); + } +} diff --git a/Dna/LLVMInterop/NativeLLVMInterop.cs b/Dna/LLVMInterop/NativeLLVMInterop.cs index 03c71ef..28caaf1 100644 --- a/Dna/LLVMInterop/NativeLLVMInterop.cs +++ b/Dna/LLVMInterop/NativeLLVMInterop.cs @@ -13,7 +13,7 @@ namespace Dna.LLVMInterop [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate ulong dgReadBinaryContents(ulong rva, uint size); - [DllImport("Dna.LLVMInterop", CallingConvention = CallingConvention.Cdecl, EntryPoint = "OptimizeModule")] - public unsafe static extern void VerifyModule(LLVMOpaqueModule* M, IntPtr readBinaryContents); + [DllImport("Dna.LLVMInterop", CallingConvention = CallingConvention.Cdecl)] + public unsafe static extern IntPtr OptimizeModule(LLVMOpaqueModule* M, IntPtr readBinaryContents); } } diff --git a/Dna/LLVMInterop/Wrapper/BlockRegion.cs b/Dna/LLVMInterop/Wrapper/BlockRegion.cs new file mode 100644 index 0000000..a97b8cd --- /dev/null +++ b/Dna/LLVMInterop/Wrapper/BlockRegion.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Dna.LLVMInterop.Wrapper +{ + public class BlockRegion : Region + { + public BlockRegion(nint handle) : base(handle) + { + } + } +} diff --git a/Dna/LLVMInterop/Wrapper/BreakRegion.cs b/Dna/LLVMInterop/Wrapper/BreakRegion.cs new file mode 100644 index 0000000..0278d81 --- /dev/null +++ b/Dna/LLVMInterop/Wrapper/BreakRegion.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Dna.LLVMInterop.Wrapper +{ + public class BreakRegion : ComplexRegion + { + public BreakRegion(nint handle) : base(handle) + { + + } + } +} diff --git a/Dna/LLVMInterop/Wrapper/ComplexRegion.cs b/Dna/LLVMInterop/Wrapper/ComplexRegion.cs new file mode 100644 index 0000000..5f7f323 --- /dev/null +++ b/Dna/LLVMInterop/Wrapper/ComplexRegion.cs @@ -0,0 +1,21 @@ +using Dna.LLVMInterop.Native; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Dna.LLVMInterop.Wrapper +{ + public abstract unsafe class ComplexRegion : Region + { + public Region Head => NativeComplexRegionApi.ComplexRegionGetHead(handle); + + public ComplexRegion(nint handle) : base(handle) + { + + } + + public static implicit operator ComplexRegion(nint value) => (ComplexRegion)(value); + } +} diff --git a/Dna/LLVMInterop/Wrapper/ContinueRegion.cs b/Dna/LLVMInterop/Wrapper/ContinueRegion.cs new file mode 100644 index 0000000..51c87dc --- /dev/null +++ b/Dna/LLVMInterop/Wrapper/ContinueRegion.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Dna.LLVMInterop.Wrapper +{ + public class ContinueRegion : Region + { + public ContinueRegion(nint handle) : base(handle) + { + + } + } +} diff --git a/Dna/LLVMInterop/Wrapper/IfThenElseRegion.cs b/Dna/LLVMInterop/Wrapper/IfThenElseRegion.cs new file mode 100644 index 0000000..8b7b29e --- /dev/null +++ b/Dna/LLVMInterop/Wrapper/IfThenElseRegion.cs @@ -0,0 +1,19 @@ +using Dna.LLVMInterop.Native; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Dna.LLVMInterop.Wrapper +{ + public class IfThenElseRegion : IfThenRegion + { + public Region Else => NativeIfThenElseRegionApi.IfThenElseRegionGetElse(handle); + + public IfThenElseRegion(nint handle) : base(handle) + { + + } + } +} diff --git a/Dna/LLVMInterop/Wrapper/IfThenRegion.cs b/Dna/LLVMInterop/Wrapper/IfThenRegion.cs new file mode 100644 index 0000000..de7b5dc --- /dev/null +++ b/Dna/LLVMInterop/Wrapper/IfThenRegion.cs @@ -0,0 +1,24 @@ +using Dna.LLVMInterop.Native; +using LLVMSharp.Interop; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Dna.LLVMInterop.Wrapper +{ + public class IfThenRegion : ComplexRegion + { + public Region Then => NativeIfThenRegionApi.IfThenRegionGetThen(handle); + + public bool IsNegated => NativeIfThenRegionApi.IfThenRegionGetIsNegated(handle); + + public LLVMValueRef TerminatorInstruction => new LLVMValueRef(NativeIfThenRegionApi.IfThenRegionGetLLVMTerminatorInstruction(handle)); + + public IfThenRegion(nint handle) : base(handle) + { + + } + } +} diff --git a/Dna/LLVMInterop/Wrapper/NaturalLoopRegion.cs b/Dna/LLVMInterop/Wrapper/NaturalLoopRegion.cs new file mode 100644 index 0000000..2076d49 --- /dev/null +++ b/Dna/LLVMInterop/Wrapper/NaturalLoopRegion.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Dna.LLVMInterop.Wrapper +{ + public class NaturalLoopRegion : ComplexRegion + { + public NaturalLoopRegion(nint handle) : base(handle) + { + + } + } +} diff --git a/Dna/LLVMInterop/Wrapper/Region.cs b/Dna/LLVMInterop/Wrapper/Region.cs new file mode 100644 index 0000000..799018a --- /dev/null +++ b/Dna/LLVMInterop/Wrapper/Region.cs @@ -0,0 +1,125 @@ +using Dna.LLVMInterop.Native; +using LLVMSharp.Interop; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Dna.LLVMInterop.Wrapper +{ + public unsafe abstract class Region : IEquatable + { + protected readonly nint handle; + + public RegionKind Kind => NativeRegionApi.RegionGetKind(handle); + + public ComplexRegion? Owner + { + get + { + var regionPtr = NativeRegionApi.RegionGetOwnerRegion(handle); + return regionPtr == nint.Zero ? null : (ComplexRegion)CreateRegion(regionPtr); + } + } + + public Region EntryRegion => NativeRegionApi.RegionGetEntryRegionBlock(handle); + + public ulong Id => NativeRegionApi.RegionGetId(handle); + + public ulong PredecessorCount => NativeRegionApi.RegionGetPredCount(handle); + + public IEnumerable Predecessors => GetPredecessors(); + + public ulong SuccessorCount => NativeRegionApi.RegionGetPredCount(handle); + + public IEnumerable Successors => GetSuccessors(); + + public LLVMBasicBlockRef BasicBlock => new LLVMBasicBlockRef(NativeRegionApi.RegionGetLLVMBasicBlock(handle)); + + public LLVMBasicBlockRef HeadBasicBlock => new LLVMBasicBlockRef(NativeRegionApi.RegionGetHeadLLVMBasicBlock(handle)); + + public ulong ChildCount => NativeRegionApi.RegionGetChildCount(handle); + + public Region(nint handle) + { + this.handle = handle; + } + + private IEnumerable GetPredecessors() + { + for (ulong i = 0; i < PredecessorCount; i++) + { + yield return GetPredecessor(i); + } + + yield break; + } + + public Region GetPredecessor(ulong index) + { + return NativeRegionApi.RegionGetPred(handle, index); + } + + private IEnumerable GetSuccessors() + { + for (ulong i = 0; i < SuccessorCount; i++) + { + yield return GetSuccessor(i); + } + + yield break; + } + + public Region GetSuccessor(ulong index) + { + return NativeRegionApi.RegionGetSucc(handle, index); + } + + private IEnumerable GetChildren() + { + for (ulong i = 0; i < ChildCount; i++) + { + yield return GetChild(i); + } + + yield break; + } + + public Region GetChild(ulong index) + { + return NativeRegionApi.RegionGetChild(handle, index); + } + + public static Region CreateRegion(nint ptr) + { + var kind = NativeRegionApi.RegionGetKind(ptr); + + return kind switch + { + RegionKind.Block => new BlockRegion(ptr), + RegionKind.Sequence => new SequenceRegion(ptr), + RegionKind.IfThen => new IfThenRegion(ptr), + RegionKind.IfThenElse => new IfThenElseRegion(ptr), + RegionKind.NaturalLoop => new NaturalLoopRegion(ptr), + RegionKind.Break => new BreakRegion(ptr), + RegionKind.Continue => new ContinueRegion(ptr), + RegionKind.Return => new ReturnRegion(ptr), + RegionKind.Switch => new SwitchRegion(ptr), + _ => throw new InvalidOperationException($"Region kind {kind} is not supported."), + }; + } + + public override bool Equals(object? obj) => (obj is Region other) && Equals(other); + + public bool Equals(Region other) => this == other; + + public override int GetHashCode() => handle.GetHashCode(); + + public static bool operator ==(Region left, Region right) => left.handle == right.handle; + + public static bool operator !=(Region left, Region right) => !(left == right); + + public static implicit operator Region(nint value) => CreateRegion(value); + } +} diff --git a/Dna/LLVMInterop/Wrapper/ReturnRegion.cs b/Dna/LLVMInterop/Wrapper/ReturnRegion.cs new file mode 100644 index 0000000..c18368f --- /dev/null +++ b/Dna/LLVMInterop/Wrapper/ReturnRegion.cs @@ -0,0 +1,20 @@ +using Dna.LLVMInterop.Native; +using LLVMSharp.Interop; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Dna.LLVMInterop.Wrapper +{ + public unsafe class ReturnRegion : ComplexRegion + { + public LLVMValueRef ReturnInstruction => new LLVMValueRef(NativeReturnRegionApi.ReturnRegionGetLLVMReturnInstruction(handle)); + + public ReturnRegion(nint handle) : base(handle) + { + + } + } +} diff --git a/Dna/LLVMInterop/Wrapper/SequenceRegion.cs b/Dna/LLVMInterop/Wrapper/SequenceRegion.cs new file mode 100644 index 0000000..461273a --- /dev/null +++ b/Dna/LLVMInterop/Wrapper/SequenceRegion.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Dna.LLVMInterop.Wrapper +{ + internal class SequenceRegion : ComplexRegion + { + public SequenceRegion(nint handle) : base(handle) + { + + } + } +} diff --git a/Dna/LLVMInterop/Wrapper/SwitchRegion.cs b/Dna/LLVMInterop/Wrapper/SwitchRegion.cs new file mode 100644 index 0000000..07d7d19 --- /dev/null +++ b/Dna/LLVMInterop/Wrapper/SwitchRegion.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Dna.LLVMInterop.Wrapper +{ + public class SwitchRegion : ComplexRegion + { + public SwitchRegion(nint handle) : base(handle) + { + } + } +}