parse bitcode
This commit is contained in:
parent
a379ba9cf1
commit
7094d59372
@ -157,6 +157,9 @@ pub extern fn NativityLLVMModuleSetTargetMachineDataLayout(module: *LLVM.Module,
|
|||||||
pub extern fn NativityLLVMModuleSetTargetTriple(module: *LLVM.Module, target_triple_ptr: [*]const u8, target_triple_len: usize) void;
|
pub extern fn NativityLLVMModuleSetTargetTriple(module: *LLVM.Module, target_triple_ptr: [*]const u8, target_triple_len: usize) void;
|
||||||
pub extern fn NativityLLVMTypeAssertEqual(a: *LLVM.Type, b: *LLVM.Type) void;
|
pub extern fn NativityLLVMTypeAssertEqual(a: *LLVM.Type, b: *LLVM.Type) void;
|
||||||
|
|
||||||
|
pub extern fn LLVMCreateMemoryBufferWithMemoryRange(InputData: [*]const u8, InputDataLength: usize, BufferName: ?[*:0]const u8, RequiresNullTerminator: c_int) *LLVM.MemoryBuffer;
|
||||||
|
pub extern fn LLVMParseBitcodeInContext2(context: *LLVM.Context, memory_buffer: *LLVM.MemoryBuffer, out_module: **LLVM.Module) c_int;
|
||||||
|
|
||||||
pub extern fn LLVMInitializeAArch64TargetInfo() void;
|
pub extern fn LLVMInitializeAArch64TargetInfo() void;
|
||||||
pub extern fn LLVMInitializeAMDGPUTargetInfo() void;
|
pub extern fn LLVMInitializeAMDGPUTargetInfo() void;
|
||||||
pub extern fn LLVMInitializeARMTargetInfo() void;
|
pub extern fn LLVMInitializeARMTargetInfo() void;
|
||||||
|
@ -886,41 +886,41 @@ pub fn make() void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Prune
|
// TODO: Prune
|
||||||
// if (do_codegen) {
|
if (do_codegen) {
|
||||||
// for (threads) |*thread| {
|
for (threads) |*thread| {
|
||||||
// thread.add_thread_work(Job{
|
thread.add_thread_work(Job{
|
||||||
// .id = switch (codegen_backend) {
|
.id = switch (codegen_backend) {
|
||||||
// .llvm => .llvm_codegen_thread_module,
|
.llvm => .llvm_codegen_thread_module,
|
||||||
// },
|
},
|
||||||
// });
|
});
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// while (true) {
|
while (true) {
|
||||||
// var to_do: u64 = 0;
|
var to_do: u64 = 0;
|
||||||
// for (threads) |*thread| {
|
for (threads) |*thread| {
|
||||||
// const jobs_to_do = thread.task_system.job.to_do - thread.task_system.job.completed;
|
const jobs_to_do = thread.task_system.job.to_do - thread.task_system.job.completed;
|
||||||
// const asks_to_do = thread.task_system.ask.to_do - thread.task_system.ask.completed;
|
const asks_to_do = thread.task_system.ask.to_do - thread.task_system.ask.completed;
|
||||||
// assert(asks_to_do == 0);
|
assert(asks_to_do == 0);
|
||||||
//
|
|
||||||
// to_do += jobs_to_do;
|
to_do += jobs_to_do;
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// if (to_do == 0) {
|
if (to_do == 0) {
|
||||||
// break;
|
break;
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// var modules_present = PinnedArray(usize){};
|
var modules_present = PinnedArray(usize){};
|
||||||
// for (threads, 0..) |*thread, i| {
|
for (threads, 0..) |*thread, i| {
|
||||||
// if (thread.functions.length > 0) {
|
if (thread.functions.length > 0) {
|
||||||
// _ = modules_present.append(i);
|
_ = modules_present.append(i);
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// switch (modules_present.length) {
|
switch (modules_present.length) {
|
||||||
// 0 => unreachable,
|
0 => unreachable,
|
||||||
// 1 => unreachable,
|
1 => {},
|
||||||
// 2 => {
|
2 => {
|
||||||
// const first = modules_present.slice()[0];
|
// const first = modules_present.slice()[0];
|
||||||
// const second = modules_present.slice()[1];
|
// const second = modules_present.slice()[1];
|
||||||
// const destination = threads[first].llvm.module;
|
// const destination = threads[first].llvm.module;
|
||||||
@ -946,12 +946,12 @@ pub fn make() void {
|
|||||||
// var message: []const u8 = undefined;
|
// var message: []const u8 = undefined;
|
||||||
// destination.toString(&message.ptr, &message.len);
|
// destination.toString(&message.ptr, &message.len);
|
||||||
// std.debug.print("============\n===========\n{s}\n", .{message});
|
// std.debug.print("============\n===========\n{s}\n", .{message});
|
||||||
// },
|
},
|
||||||
// else => unreachable,
|
else => unreachable,
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
// while (true) {}
|
while (true) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn intern_identifier(pool: *PinnedHashMap(u32, []const u8), identifier: []const u8) u32 {
|
fn intern_identifier(pool: *PinnedHashMap(u32, []const u8), identifier: []const u8) u32 {
|
||||||
@ -1252,109 +1252,113 @@ fn thread_callback(thread_index: u32) void {
|
|||||||
},
|
},
|
||||||
.llvm_codegen_thread_module => {
|
.llvm_codegen_thread_module => {
|
||||||
if (thread.functions.length > 0) {
|
if (thread.functions.length > 0) {
|
||||||
const debug_info = true;
|
const context = LLVM.Context.create();
|
||||||
|
const result = context.parse_bitcode("foo");
|
||||||
const ExternalRef = struct{
|
_ = result; // autofix
|
||||||
gsr: GlobalSymbolReference,
|
exit(0);
|
||||||
thread: u16,
|
// const debug_info = true;
|
||||||
};
|
//
|
||||||
var external_hashmap = PinnedHashMap(ExternalRef, *LLVM.Value.Constant.Function){};
|
// const ExternalRef = struct{
|
||||||
|
// gsr: GlobalSymbolReference,
|
||||||
for (thread.external_functions.slice()) |*nat_function| {
|
// thread: u16,
|
||||||
_ = llvm_get_function(thread, nat_function, true);
|
// };
|
||||||
}
|
// var external_hashmap = PinnedHashMap(ExternalRef, *LLVM.Value.Constant.Function){};
|
||||||
|
//
|
||||||
_ = &external_hashmap; // autofix
|
// for (thread.external_functions.slice()) |*nat_function| {
|
||||||
for (thread.functions.slice()) |*nat_function| {
|
// _ = llvm_get_function(thread, nat_function, true);
|
||||||
_ = llvm_get_function(thread, &nat_function.declaration, false);
|
// }
|
||||||
}
|
//
|
||||||
|
// _ = &external_hashmap; // autofix
|
||||||
for (thread.functions.slice()) |*nat_function| {
|
// for (thread.functions.slice()) |*nat_function| {
|
||||||
const function = nat_function.declaration.llvm.?;
|
// _ = llvm_get_function(thread, &nat_function.declaration, false);
|
||||||
const nat_entry_basic_block = thread.basic_blocks.get(nat_function.entry_block);
|
// }
|
||||||
assert(nat_entry_basic_block.predecessors.length == 0);
|
//
|
||||||
const entry_block_name = "entry_block_name";
|
// for (thread.functions.slice()) |*nat_function| {
|
||||||
const entry_block = thread.llvm.context.createBasicBlock(entry_block_name, entry_block_name.len, function, null);
|
// const function = nat_function.declaration.llvm.?;
|
||||||
thread.llvm.builder.setInsertPoint(entry_block);
|
// const nat_entry_basic_block = thread.basic_blocks.get(nat_function.entry_block);
|
||||||
|
// assert(nat_entry_basic_block.predecessors.length == 0);
|
||||||
for (nat_entry_basic_block.instructions.slice()) |instruction| {
|
// const entry_block_name = "entry_block_name";
|
||||||
const value: *LLVM.Value = switch (instruction.id) {
|
// const entry_block = thread.llvm.context.createBasicBlock(entry_block_name, entry_block_name.len, function, null);
|
||||||
.ret => block: {
|
// thread.llvm.builder.setInsertPoint(entry_block);
|
||||||
const return_instruction = thread.returns.get(@enumFromInt(instruction.index));
|
//
|
||||||
const return_value = llvm_get_value(thread, return_instruction.value);
|
// for (nat_entry_basic_block.instructions.slice()) |instruction| {
|
||||||
const ret = thread.llvm.builder.createRet(return_value);
|
// const value: *LLVM.Value = switch (instruction.id) {
|
||||||
break :block ret.toValue();
|
// .ret => block: {
|
||||||
},
|
// const return_instruction = thread.returns.get(@enumFromInt(instruction.index));
|
||||||
.call => block: {
|
// const return_value = llvm_get_value(thread, return_instruction.value);
|
||||||
const call = thread.calls.get(@enumFromInt(instruction.index));
|
// const ret = thread.llvm.builder.createRet(return_value);
|
||||||
const callee = if (call.value.sema.thread == thread.get_index()) switch (call.value.sema.id) {
|
// break :block ret.toValue();
|
||||||
.global_symbol => blk: {
|
// },
|
||||||
const global_symbol: GlobalSymbolReference = @bitCast(call.value.sema.index);
|
// .call => block: {
|
||||||
break :blk switch (global_symbol.id) {
|
// const call = thread.calls.get(@enumFromInt(instruction.index));
|
||||||
.function_declaration => b: {
|
// const callee = if (call.value.sema.thread == thread.get_index()) switch (call.value.sema.id) {
|
||||||
const external_function = thread.external_functions.slice()[global_symbol.index];
|
// .global_symbol => blk: {
|
||||||
break :b external_function.llvm.?;
|
// const global_symbol: GlobalSymbolReference = @bitCast(call.value.sema.index);
|
||||||
},
|
// break :blk switch (global_symbol.id) {
|
||||||
else => |t| @panic(@tagName(t)),
|
// .function_declaration => b: {
|
||||||
};
|
// const external_function = thread.external_functions.slice()[global_symbol.index];
|
||||||
},
|
// break :b external_function.llvm.?;
|
||||||
else => |t| @panic(@tagName(t)),
|
// },
|
||||||
} else exit(1);
|
// else => |t| @panic(@tagName(t)),
|
||||||
const function_type = callee.getType();
|
// };
|
||||||
|
// },
|
||||||
const arguments: []const *LLVM.Value = &.{};
|
// else => |t| @panic(@tagName(t)),
|
||||||
const call_i = thread.llvm.builder.createCall(function_type, callee.toValue(), arguments.ptr, arguments.len, "", "".len, null);
|
// } else exit(1);
|
||||||
break :block call_i.toValue();
|
// const function_type = callee.getType();
|
||||||
},
|
//
|
||||||
else => |t| @panic(@tagName(t)),
|
// const arguments: []const *LLVM.Value = &.{};
|
||||||
};
|
// const call_i = thread.llvm.builder.createCall(function_type, callee.toValue(), arguments.ptr, arguments.len, "", "".len, null);
|
||||||
|
// break :block call_i.toValue();
|
||||||
instruction.llvm = value;
|
// },
|
||||||
}
|
// else => |t| @panic(@tagName(t)),
|
||||||
|
// };
|
||||||
if (debug_info) {
|
//
|
||||||
const file_index = nat_function.declaration.file;
|
// instruction.llvm = value;
|
||||||
const llvm_file = thread.debug_info_file_map.get_pointer(file_index).?;
|
// }
|
||||||
const subprogram = function.getSubprogram();
|
//
|
||||||
llvm_file.builder.finalizeSubprogram(subprogram, function);
|
// if (debug_info) {
|
||||||
}
|
// const file_index = nat_function.declaration.file;
|
||||||
|
// const llvm_file = thread.debug_info_file_map.get_pointer(file_index).?;
|
||||||
const verify_function = true;
|
// const subprogram = function.getSubprogram();
|
||||||
if (verify_function) {
|
// llvm_file.builder.finalizeSubprogram(subprogram, function);
|
||||||
var message: []const u8 = undefined;
|
// }
|
||||||
const verification_success = function.verify(&message.ptr, &message.len);
|
//
|
||||||
if (!verification_success) {
|
// const verify_function = true;
|
||||||
var function_msg: []const u8 = undefined;
|
// if (verify_function) {
|
||||||
function.toString(&function_msg.ptr, &function_msg.len);
|
// var message: []const u8 = undefined;
|
||||||
write(function_msg);
|
// const verification_success = function.verify(&message.ptr, &message.len);
|
||||||
write("\n");
|
// if (!verification_success) {
|
||||||
exit_with_error(message);
|
// var function_msg: []const u8 = undefined;
|
||||||
}
|
// function.toString(&function_msg.ptr, &function_msg.len);
|
||||||
}
|
// write(function_msg);
|
||||||
}
|
// write("\n");
|
||||||
|
// exit_with_error(message);
|
||||||
if (debug_info) {
|
// }
|
||||||
const file_index = thread.functions.slice()[0].declaration.file;
|
// }
|
||||||
const llvm_file = thread.debug_info_file_map.get_pointer(file_index).?;
|
// }
|
||||||
llvm_file.builder.finalize();
|
//
|
||||||
}
|
// if (debug_info) {
|
||||||
|
// const file_index = thread.functions.slice()[0].declaration.file;
|
||||||
const verify_module = true;
|
// const llvm_file = thread.debug_info_file_map.get_pointer(file_index).?;
|
||||||
if (verify_module) {
|
// llvm_file.builder.finalize();
|
||||||
var verification_message: []const u8 = undefined;
|
// }
|
||||||
const verification_success = thread.llvm.module.verify(&verification_message.ptr, &verification_message.len);
|
//
|
||||||
if (!verification_success) {
|
// const verify_module = true;
|
||||||
const print_module = true;
|
// if (verify_module) {
|
||||||
if (print_module) {
|
// var verification_message: []const u8 = undefined;
|
||||||
var module_content: []const u8 = undefined;
|
// const verification_success = thread.llvm.module.verify(&verification_message.ptr, &verification_message.len);
|
||||||
thread.llvm.module.toString(&module_content.ptr, &module_content.len);
|
// if (!verification_success) {
|
||||||
write(module_content);
|
// const print_module = true;
|
||||||
write("\n");
|
// if (print_module) {
|
||||||
}
|
// var module_content: []const u8 = undefined;
|
||||||
|
// thread.llvm.module.toString(&module_content.ptr, &module_content.len);
|
||||||
exit_with_error(verification_message);
|
// write(module_content);
|
||||||
}
|
// write("\n");
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
|
// exit_with_error(verification_message);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -1939,6 +1943,17 @@ pub const LLVM = struct {
|
|||||||
const getAttributeFromString = bindings.NativityLLVMContextGetAttributeFromString;
|
const getAttributeFromString = bindings.NativityLLVMContextGetAttributeFromString;
|
||||||
const getAttributeFromType = bindings.NativityLLVMContextGetAttributeFromType;
|
const getAttributeFromType = bindings.NativityLLVMContextGetAttributeFromType;
|
||||||
const getAttributeSet = bindings.NativityLLVMContextGetAttributeSet;
|
const getAttributeSet = bindings.NativityLLVMContextGetAttributeSet;
|
||||||
|
|
||||||
|
|
||||||
|
pub fn parse_bitcode(context: *LLVM.Context, bytes: []const u8) ?*LLVM.Module {
|
||||||
|
const memory_buffer = bindings.LLVMCreateMemoryBufferWithMemoryRange(bytes.ptr, bytes.len, null, 0);
|
||||||
|
var out_module: *LLVM.Module = undefined;
|
||||||
|
if (bindings.LLVMParseBitcodeInContext2(context, memory_buffer, &out_module) != 0) {
|
||||||
|
return out_module;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const Module = opaque {
|
pub const Module = opaque {
|
||||||
@ -2579,6 +2594,8 @@ pub const LLVM = struct {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub const MemoryBuffer = opaque{};
|
||||||
|
|
||||||
pub const Value = opaque {
|
pub const Value = opaque {
|
||||||
const setName = bindings.NativityLLVMValueSetName;
|
const setName = bindings.NativityLLVMValueSetName;
|
||||||
const getType = bindings.NativityLLVMValueGetType;
|
const getType = bindings.NativityLLVMValueGetType;
|
||||||
|
@ -153,9 +153,8 @@ pub fn DynamicBoundedArray(comptime T: type) type {
|
|||||||
|
|
||||||
const pinned_array_page_size = 2 * 1024 * 1024;
|
const pinned_array_page_size = 2 * 1024 * 1024;
|
||||||
const pinned_array_max_size = std.math.maxInt(u32) - pinned_array_page_size;
|
const pinned_array_max_size = std.math.maxInt(u32) - pinned_array_page_size;
|
||||||
const pinned_array_default_granularity = pinned_array_page_size;
|
|
||||||
|
|
||||||
const small_granularity = 0x1000;
|
const small_granularity = std.mem.page_size;
|
||||||
const large_granularity = 2 * 1024 * 1024;
|
const large_granularity = 2 * 1024 * 1024;
|
||||||
// This must be used with big arrays, which are not resizeable (can't be cleared)
|
// This must be used with big arrays, which are not resizeable (can't be cleared)
|
||||||
pub fn PinnedArray(comptime T: type) type {
|
pub fn PinnedArray(comptime T: type) type {
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
import "file.nat";
|
|
||||||
|
|
||||||
fn [cc(.c)] main [export]() s32
|
fn [cc(.c)] main [export]() s32
|
||||||
{
|
{
|
||||||
return file.foo();
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include "llvm/IR/Module.h"
|
#include "llvm/IR/Module.h"
|
||||||
#include "llvm/IR/Verifier.h"
|
#include "llvm/IR/Verifier.h"
|
||||||
#include "llvm/IR/DIBuilder.h"
|
#include "llvm/IR/DIBuilder.h"
|
||||||
|
#include "llvm/Bitcode/BitcodeReader.h"
|
||||||
|
|
||||||
#include "llvm/ExecutionEngine/Orc/ThreadSafeModule.h"
|
#include "llvm/ExecutionEngine/Orc/ThreadSafeModule.h"
|
||||||
|
|
||||||
@ -22,8 +23,6 @@
|
|||||||
|
|
||||||
|
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
using llvm::orc::ThreadSafeContext;
|
|
||||||
using llvm::orc::ThreadSafeModule;
|
|
||||||
|
|
||||||
extern "C" LLVMContext* NativityLLVMCreateContext()
|
extern "C" LLVMContext* NativityLLVMCreateContext()
|
||||||
{
|
{
|
||||||
@ -1077,13 +1076,6 @@ extern "C" CallInst* NativityLLVMBuilderCreateMemcpy(IRBuilder<>& builder, Value
|
|||||||
return memcpy;
|
return memcpy;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" bool NativityLLVMLinkModules(Module& destination, Module* source)
|
|
||||||
{
|
|
||||||
auto src = std::unique_ptr<Module>(source);
|
|
||||||
bool result = Linker::linkModules(destination, std::move(src));
|
|
||||||
// Invert the condition because LLVM boolean concept is lame
|
|
||||||
return !result;
|
|
||||||
}
|
|
||||||
extern "C" void NativityLLVMTypeAssertEqual(Type* a, Type* b)
|
extern "C" void NativityLLVMTypeAssertEqual(Type* a, Type* b)
|
||||||
{
|
{
|
||||||
assert(a == b);
|
assert(a == b);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user