mirror of
https://github.com/LLVMParty/llvm-nanobind
synced 2026-06-21 13:43:38 +00:00
Reformat tests
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
---
|
||||
BasedOnStyle: LLVM
|
||||
SortIncludes: Never
|
||||
+105
-98
@@ -16,129 +16,136 @@
|
||||
* - LLVMDeleteBasicBlock()
|
||||
*/
|
||||
|
||||
#include <llvm-c/Core.h>
|
||||
#include <llvm-c/Analysis.h>
|
||||
#include <cstdio>
|
||||
#include <llvm-c/Analysis.h>
|
||||
#include <llvm-c/Core.h>
|
||||
|
||||
int main() {
|
||||
LLVMContextRef ctx = LLVMContextCreate();
|
||||
LLVMModuleRef mod = LLVMModuleCreateWithNameInContext("test_basic_block", ctx);
|
||||
LLVMContextRef ctx = LLVMContextCreate();
|
||||
LLVMModuleRef mod =
|
||||
LLVMModuleCreateWithNameInContext("test_basic_block", ctx);
|
||||
|
||||
LLVMTypeRef i32 = LLVMInt32TypeInContext(ctx);
|
||||
LLVMTypeRef void_ty = LLVMVoidTypeInContext(ctx);
|
||||
LLVMTypeRef i32 = LLVMInt32TypeInContext(ctx);
|
||||
LLVMTypeRef void_ty = LLVMVoidTypeInContext(ctx);
|
||||
|
||||
// Create a function to hold basic blocks
|
||||
LLVMTypeRef func_ty = LLVMFunctionType(void_ty, nullptr, 0, 0);
|
||||
LLVMValueRef func = LLVMAddFunction(mod, "test_func", func_ty);
|
||||
// Create a function to hold basic blocks
|
||||
LLVMTypeRef func_ty = LLVMFunctionType(void_ty, nullptr, 0, 0);
|
||||
LLVMValueRef func = LLVMAddFunction(mod, "test_func", func_ty);
|
||||
|
||||
// Append basic blocks
|
||||
LLVMBasicBlockRef entry = LLVMAppendBasicBlockInContext(ctx, func, "entry");
|
||||
LLVMBasicBlockRef middle = LLVMAppendBasicBlockInContext(ctx, func, "middle");
|
||||
LLVMBasicBlockRef exit_bb = LLVMAppendBasicBlockInContext(ctx, func, "exit");
|
||||
// Append basic blocks
|
||||
LLVMBasicBlockRef entry = LLVMAppendBasicBlockInContext(ctx, func, "entry");
|
||||
LLVMBasicBlockRef middle = LLVMAppendBasicBlockInContext(ctx, func, "middle");
|
||||
LLVMBasicBlockRef exit_bb = LLVMAppendBasicBlockInContext(ctx, func, "exit");
|
||||
|
||||
// Get block names
|
||||
const char *entry_name = LLVMGetBasicBlockName(entry);
|
||||
const char *middle_name = LLVMGetBasicBlockName(middle);
|
||||
const char *exit_name = LLVMGetBasicBlockName(exit_bb);
|
||||
// Get block names
|
||||
const char *entry_name = LLVMGetBasicBlockName(entry);
|
||||
const char *middle_name = LLVMGetBasicBlockName(middle);
|
||||
const char *exit_name = LLVMGetBasicBlockName(exit_bb);
|
||||
|
||||
// Get parent function
|
||||
LLVMValueRef entry_parent = LLVMGetBasicBlockParent(entry);
|
||||
// Get parent function
|
||||
LLVMValueRef entry_parent = LLVMGetBasicBlockParent(entry);
|
||||
|
||||
// Get entry basic block
|
||||
LLVMBasicBlockRef func_entry = LLVMGetEntryBasicBlock(func);
|
||||
// Get entry basic block
|
||||
LLVMBasicBlockRef func_entry = LLVMGetEntryBasicBlock(func);
|
||||
|
||||
// Count basic blocks
|
||||
unsigned bb_count = LLVMCountBasicBlocks(func);
|
||||
// Count basic blocks
|
||||
unsigned bb_count = LLVMCountBasicBlocks(func);
|
||||
|
||||
// Create a builder to add instructions
|
||||
LLVMBuilderRef builder = LLVMCreateBuilderInContext(ctx);
|
||||
// Create a builder to add instructions
|
||||
LLVMBuilderRef builder = LLVMCreateBuilderInContext(ctx);
|
||||
|
||||
// Add instructions to entry block
|
||||
LLVMPositionBuilderAtEnd(builder, entry);
|
||||
LLVMBuildBr(builder, middle);
|
||||
// Add instructions to entry block
|
||||
LLVMPositionBuilderAtEnd(builder, entry);
|
||||
LLVMBuildBr(builder, middle);
|
||||
|
||||
// Add instructions to middle block
|
||||
LLVMPositionBuilderAtEnd(builder, middle);
|
||||
LLVMBuildBr(builder, exit_bb);
|
||||
// Add instructions to middle block
|
||||
LLVMPositionBuilderAtEnd(builder, middle);
|
||||
LLVMBuildBr(builder, exit_bb);
|
||||
|
||||
// Add instructions to exit block
|
||||
LLVMPositionBuilderAtEnd(builder, exit_bb);
|
||||
LLVMBuildRetVoid(builder);
|
||||
// Add instructions to exit block
|
||||
LLVMPositionBuilderAtEnd(builder, exit_bb);
|
||||
LLVMBuildRetVoid(builder);
|
||||
|
||||
// Get first/last instructions
|
||||
LLVMValueRef entry_first = LLVMGetFirstInstruction(entry);
|
||||
LLVMValueRef entry_last = LLVMGetLastInstruction(entry);
|
||||
LLVMValueRef exit_terminator = LLVMGetBasicBlockTerminator(exit_bb);
|
||||
// Get first/last instructions
|
||||
LLVMValueRef entry_first = LLVMGetFirstInstruction(entry);
|
||||
LLVMValueRef entry_last = LLVMGetLastInstruction(entry);
|
||||
LLVMValueRef exit_terminator = LLVMGetBasicBlockTerminator(exit_bb);
|
||||
|
||||
// Create unattached block
|
||||
LLVMBasicBlockRef unattached = LLVMCreateBasicBlockInContext(ctx, "unattached");
|
||||
// Create unattached block
|
||||
LLVMBasicBlockRef unattached =
|
||||
LLVMCreateBasicBlockInContext(ctx, "unattached");
|
||||
|
||||
// Attach unattached block to function
|
||||
LLVMAppendExistingBasicBlock(func, unattached);
|
||||
LLVMPositionBuilderAtEnd(builder, unattached);
|
||||
LLVMBuildUnreachable(builder);
|
||||
// Attach unattached block to function
|
||||
LLVMAppendExistingBasicBlock(func, unattached);
|
||||
LLVMPositionBuilderAtEnd(builder, unattached);
|
||||
LLVMBuildUnreachable(builder);
|
||||
|
||||
// Block count after adding unattached
|
||||
unsigned bb_count_after = LLVMCountBasicBlocks(func);
|
||||
// Block count after adding unattached
|
||||
unsigned bb_count_after = LLVMCountBasicBlocks(func);
|
||||
|
||||
// Move blocks around: move unattached before exit
|
||||
LLVMMoveBasicBlockBefore(unattached, exit_bb);
|
||||
// Move blocks around: move unattached before exit
|
||||
LLVMMoveBasicBlockBefore(unattached, exit_bb);
|
||||
|
||||
// Iterate through blocks
|
||||
int block_index = 0;
|
||||
printf("; Test: test_basic_block\n");
|
||||
printf(";\n");
|
||||
printf("; Basic block info:\n");
|
||||
printf("; entry name: %s\n", entry_name);
|
||||
printf("; middle name: %s\n", middle_name);
|
||||
printf("; exit name: %s\n", exit_name);
|
||||
printf(";\n");
|
||||
printf("; Parent checks:\n");
|
||||
printf("; entry parent is func: %s\n", entry_parent == func ? "yes" : "no");
|
||||
printf("; func entry block is entry: %s\n", func_entry == entry ? "yes" : "no");
|
||||
printf(";\n");
|
||||
printf("; Block counts:\n");
|
||||
printf("; initial count: %u\n", bb_count);
|
||||
printf("; after adding unattached: %u\n", bb_count_after);
|
||||
printf(";\n");
|
||||
printf("; Instruction checks:\n");
|
||||
printf("; entry has first instruction: %s\n", entry_first != nullptr ? "yes" : "no");
|
||||
printf("; entry first == last (single inst): %s\n", entry_first == entry_last ? "yes" : "no");
|
||||
printf("; exit has terminator: %s\n", exit_terminator != nullptr ? "yes" : "no");
|
||||
printf(";\n");
|
||||
printf("; Block iteration (after move):\n");
|
||||
for (LLVMBasicBlockRef bb = LLVMGetFirstBasicBlock(func); bb; bb = LLVMGetNextBasicBlock(bb)) {
|
||||
printf("; [%d] %s\n", block_index++, LLVMGetBasicBlockName(bb));
|
||||
}
|
||||
// Iterate through blocks
|
||||
int block_index = 0;
|
||||
printf("; Test: test_basic_block\n");
|
||||
printf(";\n");
|
||||
printf("; Basic block info:\n");
|
||||
printf("; entry name: %s\n", entry_name);
|
||||
printf("; middle name: %s\n", middle_name);
|
||||
printf("; exit name: %s\n", exit_name);
|
||||
printf(";\n");
|
||||
printf("; Parent checks:\n");
|
||||
printf("; entry parent is func: %s\n", entry_parent == func ? "yes" : "no");
|
||||
printf("; func entry block is entry: %s\n",
|
||||
func_entry == entry ? "yes" : "no");
|
||||
printf(";\n");
|
||||
printf("; Block counts:\n");
|
||||
printf("; initial count: %u\n", bb_count);
|
||||
printf("; after adding unattached: %u\n", bb_count_after);
|
||||
printf(";\n");
|
||||
printf("; Instruction checks:\n");
|
||||
printf("; entry has first instruction: %s\n",
|
||||
entry_first != nullptr ? "yes" : "no");
|
||||
printf("; entry first == last (single inst): %s\n",
|
||||
entry_first == entry_last ? "yes" : "no");
|
||||
printf("; exit has terminator: %s\n",
|
||||
exit_terminator != nullptr ? "yes" : "no");
|
||||
printf(";\n");
|
||||
printf("; Block iteration (after move):\n");
|
||||
for (LLVMBasicBlockRef bb = LLVMGetFirstBasicBlock(func); bb;
|
||||
bb = LLVMGetNextBasicBlock(bb)) {
|
||||
printf("; [%d] %s\n", block_index++, LLVMGetBasicBlockName(bb));
|
||||
}
|
||||
|
||||
// Get last block
|
||||
LLVMBasicBlockRef last_bb = LLVMGetLastBasicBlock(func);
|
||||
printf(";\n");
|
||||
printf("; Last block: %s\n", LLVMGetBasicBlockName(last_bb));
|
||||
// Get last block
|
||||
LLVMBasicBlockRef last_bb = LLVMGetLastBasicBlock(func);
|
||||
printf(";\n");
|
||||
printf("; Last block: %s\n", LLVMGetBasicBlockName(last_bb));
|
||||
|
||||
LLVMDisposeBuilder(builder);
|
||||
LLVMDisposeBuilder(builder);
|
||||
|
||||
// Verify module
|
||||
char *error = nullptr;
|
||||
if (LLVMVerifyModule(mod, LLVMReturnStatusAction, &error)) {
|
||||
fprintf(stderr, "; Verification failed: %s\n", error);
|
||||
LLVMDisposeMessage(error);
|
||||
LLVMDisposeModule(mod);
|
||||
LLVMContextDispose(ctx);
|
||||
return 1;
|
||||
}
|
||||
// Verify module
|
||||
char *error = nullptr;
|
||||
if (LLVMVerifyModule(mod, LLVMReturnStatusAction, &error)) {
|
||||
fprintf(stderr, "; Verification failed: %s\n", error);
|
||||
LLVMDisposeMessage(error);
|
||||
|
||||
printf("\n");
|
||||
|
||||
// Print module IR
|
||||
char *ir = LLVMPrintModuleToString(mod);
|
||||
printf("%s", ir);
|
||||
LLVMDisposeMessage(ir);
|
||||
|
||||
// Cleanup
|
||||
LLVMDisposeModule(mod);
|
||||
LLVMContextDispose(ctx);
|
||||
return 1;
|
||||
}
|
||||
LLVMDisposeMessage(error);
|
||||
|
||||
return 0;
|
||||
printf("\n");
|
||||
|
||||
// Print module IR
|
||||
char *ir = LLVMPrintModuleToString(mod);
|
||||
printf("%s", ir);
|
||||
LLVMDisposeMessage(ir);
|
||||
|
||||
// Cleanup
|
||||
LLVMDisposeModule(mod);
|
||||
LLVMContextDispose(ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -10,131 +10,136 @@
|
||||
* - LLVMBuildMul(), LLVMBuildNSWMul(), LLVMBuildNUWMul()
|
||||
* - LLVMBuildSDiv(), LLVMBuildUDiv(), LLVMBuildExactSDiv()
|
||||
* - LLVMBuildSRem(), LLVMBuildURem()
|
||||
* - LLVMBuildFAdd(), LLVMBuildFSub(), LLVMBuildFMul(), LLVMBuildFDiv(), LLVMBuildFRem()
|
||||
* - LLVMBuildFAdd(), LLVMBuildFSub(), LLVMBuildFMul(), LLVMBuildFDiv(),
|
||||
* LLVMBuildFRem()
|
||||
* - LLVMBuildShl(), LLVMBuildLShr(), LLVMBuildAShr()
|
||||
* - LLVMBuildAnd(), LLVMBuildOr(), LLVMBuildXor()
|
||||
* - LLVMBuildNeg(), LLVMBuildNSWNeg(), LLVMBuildFNeg(), LLVMBuildNot()
|
||||
*/
|
||||
|
||||
#include <llvm-c/Core.h>
|
||||
#include <llvm-c/Analysis.h>
|
||||
#include <cstdio>
|
||||
#include <llvm-c/Analysis.h>
|
||||
#include <llvm-c/Core.h>
|
||||
|
||||
int main() {
|
||||
LLVMContextRef ctx = LLVMContextCreate();
|
||||
LLVMModuleRef mod = LLVMModuleCreateWithNameInContext("test_builder_arithmetic", ctx);
|
||||
LLVMContextRef ctx = LLVMContextCreate();
|
||||
LLVMModuleRef mod =
|
||||
LLVMModuleCreateWithNameInContext("test_builder_arithmetic", ctx);
|
||||
|
||||
LLVMTypeRef i32 = LLVMInt32TypeInContext(ctx);
|
||||
LLVMTypeRef i64 = LLVMInt64TypeInContext(ctx);
|
||||
LLVMTypeRef f64 = LLVMDoubleTypeInContext(ctx);
|
||||
LLVMTypeRef i32 = LLVMInt32TypeInContext(ctx);
|
||||
LLVMTypeRef i64 = LLVMInt64TypeInContext(ctx);
|
||||
LLVMTypeRef f64 = LLVMDoubleTypeInContext(ctx);
|
||||
|
||||
// Integer arithmetic function: i32 int_arith(i32, i32)
|
||||
LLVMTypeRef int_params[] = {i32, i32};
|
||||
LLVMTypeRef int_func_ty = LLVMFunctionType(i32, int_params, 2, 0);
|
||||
LLVMValueRef int_func = LLVMAddFunction(mod, "int_arith", int_func_ty);
|
||||
// Integer arithmetic function: i32 int_arith(i32, i32)
|
||||
LLVMTypeRef int_params[] = {i32, i32};
|
||||
LLVMTypeRef int_func_ty = LLVMFunctionType(i32, int_params, 2, 0);
|
||||
LLVMValueRef int_func = LLVMAddFunction(mod, "int_arith", int_func_ty);
|
||||
|
||||
LLVMValueRef a = LLVMGetParam(int_func, 0);
|
||||
LLVMValueRef b = LLVMGetParam(int_func, 1);
|
||||
LLVMSetValueName2(a, "a", 1);
|
||||
LLVMSetValueName2(b, "b", 1);
|
||||
LLVMValueRef a = LLVMGetParam(int_func, 0);
|
||||
LLVMValueRef b = LLVMGetParam(int_func, 1);
|
||||
LLVMSetValueName2(a, "a", 1);
|
||||
LLVMSetValueName2(b, "b", 1);
|
||||
|
||||
LLVMBasicBlockRef int_entry = LLVMAppendBasicBlockInContext(ctx, int_func, "entry");
|
||||
LLVMBuilderRef builder = LLVMCreateBuilderInContext(ctx);
|
||||
LLVMPositionBuilderAtEnd(builder, int_entry);
|
||||
LLVMBasicBlockRef int_entry =
|
||||
LLVMAppendBasicBlockInContext(ctx, int_func, "entry");
|
||||
LLVMBuilderRef builder = LLVMCreateBuilderInContext(ctx);
|
||||
LLVMPositionBuilderAtEnd(builder, int_entry);
|
||||
|
||||
// Basic arithmetic
|
||||
LLVMValueRef add = LLVMBuildAdd(builder, a, b, "add");
|
||||
LLVMValueRef sub = LLVMBuildSub(builder, a, b, "sub");
|
||||
LLVMValueRef mul = LLVMBuildMul(builder, a, b, "mul");
|
||||
LLVMValueRef sdiv = LLVMBuildSDiv(builder, a, b, "sdiv");
|
||||
LLVMValueRef udiv = LLVMBuildUDiv(builder, a, b, "udiv");
|
||||
LLVMValueRef srem = LLVMBuildSRem(builder, a, b, "srem");
|
||||
LLVMValueRef urem = LLVMBuildURem(builder, a, b, "urem");
|
||||
// Basic arithmetic
|
||||
LLVMValueRef add = LLVMBuildAdd(builder, a, b, "add");
|
||||
LLVMValueRef sub = LLVMBuildSub(builder, a, b, "sub");
|
||||
LLVMValueRef mul = LLVMBuildMul(builder, a, b, "mul");
|
||||
LLVMValueRef sdiv = LLVMBuildSDiv(builder, a, b, "sdiv");
|
||||
LLVMValueRef udiv = LLVMBuildUDiv(builder, a, b, "udiv");
|
||||
LLVMValueRef srem = LLVMBuildSRem(builder, a, b, "srem");
|
||||
LLVMValueRef urem = LLVMBuildURem(builder, a, b, "urem");
|
||||
|
||||
// With overflow flags
|
||||
LLVMValueRef nsw_add = LLVMBuildNSWAdd(builder, a, b, "nsw_add");
|
||||
LLVMValueRef nuw_add = LLVMBuildNUWAdd(builder, a, b, "nuw_add");
|
||||
LLVMValueRef nsw_sub = LLVMBuildNSWSub(builder, a, b, "nsw_sub");
|
||||
LLVMValueRef nuw_sub = LLVMBuildNUWSub(builder, a, b, "nuw_sub");
|
||||
LLVMValueRef nsw_mul = LLVMBuildNSWMul(builder, a, b, "nsw_mul");
|
||||
LLVMValueRef nuw_mul = LLVMBuildNUWMul(builder, a, b, "nuw_mul");
|
||||
LLVMValueRef exact_sdiv = LLVMBuildExactSDiv(builder, a, b, "exact_sdiv");
|
||||
// With overflow flags
|
||||
LLVMValueRef nsw_add = LLVMBuildNSWAdd(builder, a, b, "nsw_add");
|
||||
LLVMValueRef nuw_add = LLVMBuildNUWAdd(builder, a, b, "nuw_add");
|
||||
LLVMValueRef nsw_sub = LLVMBuildNSWSub(builder, a, b, "nsw_sub");
|
||||
LLVMValueRef nuw_sub = LLVMBuildNUWSub(builder, a, b, "nuw_sub");
|
||||
LLVMValueRef nsw_mul = LLVMBuildNSWMul(builder, a, b, "nsw_mul");
|
||||
LLVMValueRef nuw_mul = LLVMBuildNUWMul(builder, a, b, "nuw_mul");
|
||||
LLVMValueRef exact_sdiv = LLVMBuildExactSDiv(builder, a, b, "exact_sdiv");
|
||||
|
||||
// Bitwise operations
|
||||
LLVMValueRef and_op = LLVMBuildAnd(builder, a, b, "and");
|
||||
LLVMValueRef or_op = LLVMBuildOr(builder, a, b, "or");
|
||||
LLVMValueRef xor_op = LLVMBuildXor(builder, a, b, "xor");
|
||||
// Bitwise operations
|
||||
LLVMValueRef and_op = LLVMBuildAnd(builder, a, b, "and");
|
||||
LLVMValueRef or_op = LLVMBuildOr(builder, a, b, "or");
|
||||
LLVMValueRef xor_op = LLVMBuildXor(builder, a, b, "xor");
|
||||
|
||||
// Shift operations
|
||||
LLVMValueRef shl = LLVMBuildShl(builder, a, b, "shl");
|
||||
LLVMValueRef lshr = LLVMBuildLShr(builder, a, b, "lshr");
|
||||
LLVMValueRef ashr = LLVMBuildAShr(builder, a, b, "ashr");
|
||||
// Shift operations
|
||||
LLVMValueRef shl = LLVMBuildShl(builder, a, b, "shl");
|
||||
LLVMValueRef lshr = LLVMBuildLShr(builder, a, b, "lshr");
|
||||
LLVMValueRef ashr = LLVMBuildAShr(builder, a, b, "ashr");
|
||||
|
||||
// Unary operations
|
||||
LLVMValueRef neg = LLVMBuildNeg(builder, a, "neg");
|
||||
LLVMValueRef nsw_neg = LLVMBuildNSWNeg(builder, a, "nsw_neg");
|
||||
LLVMValueRef not_op = LLVMBuildNot(builder, a, "not");
|
||||
// Unary operations
|
||||
LLVMValueRef neg = LLVMBuildNeg(builder, a, "neg");
|
||||
LLVMValueRef nsw_neg = LLVMBuildNSWNeg(builder, a, "nsw_neg");
|
||||
LLVMValueRef not_op = LLVMBuildNot(builder, a, "not");
|
||||
|
||||
// Return something to make function complete
|
||||
LLVMBuildRet(builder, add);
|
||||
// Return something to make function complete
|
||||
LLVMBuildRet(builder, add);
|
||||
|
||||
// Floating point arithmetic function: f64 float_arith(f64, f64)
|
||||
LLVMTypeRef fp_params[] = {f64, f64};
|
||||
LLVMTypeRef fp_func_ty = LLVMFunctionType(f64, fp_params, 2, 0);
|
||||
LLVMValueRef fp_func = LLVMAddFunction(mod, "float_arith", fp_func_ty);
|
||||
// Floating point arithmetic function: f64 float_arith(f64, f64)
|
||||
LLVMTypeRef fp_params[] = {f64, f64};
|
||||
LLVMTypeRef fp_func_ty = LLVMFunctionType(f64, fp_params, 2, 0);
|
||||
LLVMValueRef fp_func = LLVMAddFunction(mod, "float_arith", fp_func_ty);
|
||||
|
||||
LLVMValueRef x = LLVMGetParam(fp_func, 0);
|
||||
LLVMValueRef y = LLVMGetParam(fp_func, 1);
|
||||
LLVMSetValueName2(x, "x", 1);
|
||||
LLVMSetValueName2(y, "y", 1);
|
||||
LLVMValueRef x = LLVMGetParam(fp_func, 0);
|
||||
LLVMValueRef y = LLVMGetParam(fp_func, 1);
|
||||
LLVMSetValueName2(x, "x", 1);
|
||||
LLVMSetValueName2(y, "y", 1);
|
||||
|
||||
LLVMBasicBlockRef fp_entry = LLVMAppendBasicBlockInContext(ctx, fp_func, "entry");
|
||||
LLVMPositionBuilderAtEnd(builder, fp_entry);
|
||||
LLVMBasicBlockRef fp_entry =
|
||||
LLVMAppendBasicBlockInContext(ctx, fp_func, "entry");
|
||||
LLVMPositionBuilderAtEnd(builder, fp_entry);
|
||||
|
||||
// Floating point operations
|
||||
LLVMValueRef fadd = LLVMBuildFAdd(builder, x, y, "fadd");
|
||||
LLVMValueRef fsub = LLVMBuildFSub(builder, x, y, "fsub");
|
||||
LLVMValueRef fmul = LLVMBuildFMul(builder, x, y, "fmul");
|
||||
LLVMValueRef fdiv = LLVMBuildFDiv(builder, x, y, "fdiv");
|
||||
LLVMValueRef frem = LLVMBuildFRem(builder, x, y, "frem");
|
||||
LLVMValueRef fneg = LLVMBuildFNeg(builder, x, "fneg");
|
||||
// Floating point operations
|
||||
LLVMValueRef fadd = LLVMBuildFAdd(builder, x, y, "fadd");
|
||||
LLVMValueRef fsub = LLVMBuildFSub(builder, x, y, "fsub");
|
||||
LLVMValueRef fmul = LLVMBuildFMul(builder, x, y, "fmul");
|
||||
LLVMValueRef fdiv = LLVMBuildFDiv(builder, x, y, "fdiv");
|
||||
LLVMValueRef frem = LLVMBuildFRem(builder, x, y, "frem");
|
||||
LLVMValueRef fneg = LLVMBuildFNeg(builder, x, "fneg");
|
||||
|
||||
LLVMBuildRet(builder, fadd);
|
||||
LLVMBuildRet(builder, fadd);
|
||||
|
||||
LLVMDisposeBuilder(builder);
|
||||
LLVMDisposeBuilder(builder);
|
||||
|
||||
// Verify module
|
||||
char *error = nullptr;
|
||||
if (LLVMVerifyModule(mod, LLVMReturnStatusAction, &error)) {
|
||||
fprintf(stderr, "; Verification failed: %s\n", error);
|
||||
LLVMDisposeMessage(error);
|
||||
LLVMDisposeModule(mod);
|
||||
LLVMContextDispose(ctx);
|
||||
return 1;
|
||||
}
|
||||
// Verify module
|
||||
char *error = nullptr;
|
||||
if (LLVMVerifyModule(mod, LLVMReturnStatusAction, &error)) {
|
||||
fprintf(stderr, "; Verification failed: %s\n", error);
|
||||
LLVMDisposeMessage(error);
|
||||
|
||||
// Print diagnostic comments
|
||||
printf("; Test: test_builder_arithmetic\n");
|
||||
printf(";\n");
|
||||
printf("; Integer operations demonstrated:\n");
|
||||
printf("; add, sub, mul, sdiv, udiv, srem, urem\n");
|
||||
printf("; nsw_add, nuw_add, nsw_sub, nuw_sub, nsw_mul, nuw_mul, exact_sdiv\n");
|
||||
printf("; and, or, xor, shl, lshr, ashr\n");
|
||||
printf("; neg, nsw_neg, not\n");
|
||||
printf(";\n");
|
||||
printf("; Floating point operations demonstrated:\n");
|
||||
printf("; fadd, fsub, fmul, fdiv, frem, fneg\n");
|
||||
printf("\n");
|
||||
|
||||
// Print module IR
|
||||
char *ir = LLVMPrintModuleToString(mod);
|
||||
printf("%s", ir);
|
||||
LLVMDisposeMessage(ir);
|
||||
|
||||
// Cleanup
|
||||
LLVMDisposeModule(mod);
|
||||
LLVMContextDispose(ctx);
|
||||
return 1;
|
||||
}
|
||||
LLVMDisposeMessage(error);
|
||||
|
||||
return 0;
|
||||
// Print diagnostic comments
|
||||
printf("; Test: test_builder_arithmetic\n");
|
||||
printf(";\n");
|
||||
printf("; Integer operations demonstrated:\n");
|
||||
printf("; add, sub, mul, sdiv, udiv, srem, urem\n");
|
||||
printf(
|
||||
"; nsw_add, nuw_add, nsw_sub, nuw_sub, nsw_mul, nuw_mul, exact_sdiv\n");
|
||||
printf("; and, or, xor, shl, lshr, ashr\n");
|
||||
printf("; neg, nsw_neg, not\n");
|
||||
printf(";\n");
|
||||
printf("; Floating point operations demonstrated:\n");
|
||||
printf("; fadd, fsub, fmul, fdiv, frem, fneg\n");
|
||||
printf("\n");
|
||||
|
||||
// Print module IR
|
||||
char *ir = LLVMPrintModuleToString(mod);
|
||||
printf("%s", ir);
|
||||
LLVMDisposeMessage(ir);
|
||||
|
||||
// Cleanup
|
||||
LLVMDisposeModule(mod);
|
||||
LLVMContextDispose(ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+146
-133
@@ -12,174 +12,187 @@
|
||||
* - LLVMBuildIntCast2()
|
||||
*/
|
||||
|
||||
#include <llvm-c/Core.h>
|
||||
#include <llvm-c/Analysis.h>
|
||||
#include <cstdio>
|
||||
#include <llvm-c/Analysis.h>
|
||||
#include <llvm-c/Core.h>
|
||||
|
||||
int main() {
|
||||
LLVMContextRef ctx = LLVMContextCreate();
|
||||
LLVMModuleRef mod = LLVMModuleCreateWithNameInContext("test_builder_casts", ctx);
|
||||
LLVMContextRef ctx = LLVMContextCreate();
|
||||
LLVMModuleRef mod =
|
||||
LLVMModuleCreateWithNameInContext("test_builder_casts", ctx);
|
||||
|
||||
LLVMTypeRef i8 = LLVMInt8TypeInContext(ctx);
|
||||
LLVMTypeRef i16 = LLVMInt16TypeInContext(ctx);
|
||||
LLVMTypeRef i32 = LLVMInt32TypeInContext(ctx);
|
||||
LLVMTypeRef i64 = LLVMInt64TypeInContext(ctx);
|
||||
LLVMTypeRef f32 = LLVMFloatTypeInContext(ctx);
|
||||
LLVMTypeRef f64 = LLVMDoubleTypeInContext(ctx);
|
||||
LLVMTypeRef ptr = LLVMPointerTypeInContext(ctx, 0);
|
||||
LLVMTypeRef void_ty = LLVMVoidTypeInContext(ctx);
|
||||
LLVMTypeRef i8 = LLVMInt8TypeInContext(ctx);
|
||||
LLVMTypeRef i16 = LLVMInt16TypeInContext(ctx);
|
||||
LLVMTypeRef i32 = LLVMInt32TypeInContext(ctx);
|
||||
LLVMTypeRef i64 = LLVMInt64TypeInContext(ctx);
|
||||
LLVMTypeRef f32 = LLVMFloatTypeInContext(ctx);
|
||||
LLVMTypeRef f64 = LLVMDoubleTypeInContext(ctx);
|
||||
LLVMTypeRef ptr = LLVMPointerTypeInContext(ctx, 0);
|
||||
LLVMTypeRef void_ty = LLVMVoidTypeInContext(ctx);
|
||||
|
||||
LLVMBuilderRef builder = LLVMCreateBuilderInContext(ctx);
|
||||
LLVMBuilderRef builder = LLVMCreateBuilderInContext(ctx);
|
||||
|
||||
// ==========================================
|
||||
// Function 1: Integer casts
|
||||
// ==========================================
|
||||
LLVMTypeRef int_cast_params[] = {i64};
|
||||
LLVMTypeRef int_cast_ty = LLVMFunctionType(i8, int_cast_params, 1, 0);
|
||||
LLVMValueRef int_cast_func = LLVMAddFunction(mod, "integer_casts", int_cast_ty);
|
||||
LLVMValueRef i64_val = LLVMGetParam(int_cast_func, 0);
|
||||
LLVMSetValueName2(i64_val, "val", 3);
|
||||
// ==========================================
|
||||
// Function 1: Integer casts
|
||||
// ==========================================
|
||||
LLVMTypeRef int_cast_params[] = {i64};
|
||||
LLVMTypeRef int_cast_ty = LLVMFunctionType(i8, int_cast_params, 1, 0);
|
||||
LLVMValueRef int_cast_func =
|
||||
LLVMAddFunction(mod, "integer_casts", int_cast_ty);
|
||||
LLVMValueRef i64_val = LLVMGetParam(int_cast_func, 0);
|
||||
LLVMSetValueName2(i64_val, "val", 3);
|
||||
|
||||
LLVMBasicBlockRef int_entry = LLVMAppendBasicBlockInContext(ctx, int_cast_func, "entry");
|
||||
LLVMPositionBuilderAtEnd(builder, int_entry);
|
||||
LLVMBasicBlockRef int_entry =
|
||||
LLVMAppendBasicBlockInContext(ctx, int_cast_func, "entry");
|
||||
LLVMPositionBuilderAtEnd(builder, int_entry);
|
||||
|
||||
// Truncate i64 -> i32 -> i16 -> i8
|
||||
LLVMValueRef trunc_32 = LLVMBuildTrunc(builder, i64_val, i32, "trunc_32");
|
||||
LLVMValueRef trunc_16 = LLVMBuildTrunc(builder, trunc_32, i16, "trunc_16");
|
||||
LLVMValueRef trunc_8 = LLVMBuildTrunc(builder, trunc_16, i8, "trunc_8");
|
||||
// Truncate i64 -> i32 -> i16 -> i8
|
||||
LLVMValueRef trunc_32 = LLVMBuildTrunc(builder, i64_val, i32, "trunc_32");
|
||||
LLVMValueRef trunc_16 = LLVMBuildTrunc(builder, trunc_32, i16, "trunc_16");
|
||||
LLVMValueRef trunc_8 = LLVMBuildTrunc(builder, trunc_16, i8, "trunc_8");
|
||||
|
||||
// Zero extend i8 -> i16 -> i32 -> i64
|
||||
LLVMValueRef zext_16 = LLVMBuildZExt(builder, trunc_8, i16, "zext_16");
|
||||
LLVMValueRef zext_32 = LLVMBuildZExt(builder, zext_16, i32, "zext_32");
|
||||
LLVMValueRef zext_64 = LLVMBuildZExt(builder, zext_32, i64, "zext_64");
|
||||
// Zero extend i8 -> i16 -> i32 -> i64
|
||||
LLVMValueRef zext_16 = LLVMBuildZExt(builder, trunc_8, i16, "zext_16");
|
||||
LLVMValueRef zext_32 = LLVMBuildZExt(builder, zext_16, i32, "zext_32");
|
||||
LLVMValueRef zext_64 = LLVMBuildZExt(builder, zext_32, i64, "zext_64");
|
||||
|
||||
// Sign extend i8 -> i16 -> i32 -> i64
|
||||
LLVMValueRef sext_16 = LLVMBuildSExt(builder, trunc_8, i16, "sext_16");
|
||||
LLVMValueRef sext_32 = LLVMBuildSExt(builder, sext_16, i32, "sext_32");
|
||||
LLVMValueRef sext_64 = LLVMBuildSExt(builder, sext_32, i64, "sext_64");
|
||||
// Sign extend i8 -> i16 -> i32 -> i64
|
||||
LLVMValueRef sext_16 = LLVMBuildSExt(builder, trunc_8, i16, "sext_16");
|
||||
LLVMValueRef sext_32 = LLVMBuildSExt(builder, sext_16, i32, "sext_32");
|
||||
LLVMValueRef sext_64 = LLVMBuildSExt(builder, sext_32, i64, "sext_64");
|
||||
|
||||
// IntCast2 (auto-selects trunc/zext/sext)
|
||||
LLVMValueRef intcast_unsigned = LLVMBuildIntCast2(builder, i64_val, i32, 0, "intcast_unsigned");
|
||||
LLVMValueRef intcast_signed = LLVMBuildIntCast2(builder, trunc_8, i32, 1, "intcast_signed");
|
||||
// IntCast2 (auto-selects trunc/zext/sext)
|
||||
LLVMValueRef intcast_unsigned =
|
||||
LLVMBuildIntCast2(builder, i64_val, i32, 0, "intcast_unsigned");
|
||||
LLVMValueRef intcast_signed =
|
||||
LLVMBuildIntCast2(builder, trunc_8, i32, 1, "intcast_signed");
|
||||
|
||||
LLVMBuildRet(builder, trunc_8);
|
||||
LLVMBuildRet(builder, trunc_8);
|
||||
|
||||
// ==========================================
|
||||
// Function 2: Float casts
|
||||
// ==========================================
|
||||
LLVMTypeRef fp_cast_params[] = {f64};
|
||||
LLVMTypeRef fp_cast_ty = LLVMFunctionType(f32, fp_cast_params, 1, 0);
|
||||
LLVMValueRef fp_cast_func = LLVMAddFunction(mod, "float_casts", fp_cast_ty);
|
||||
LLVMValueRef f64_val = LLVMGetParam(fp_cast_func, 0);
|
||||
LLVMSetValueName2(f64_val, "val", 3);
|
||||
// ==========================================
|
||||
// Function 2: Float casts
|
||||
// ==========================================
|
||||
LLVMTypeRef fp_cast_params[] = {f64};
|
||||
LLVMTypeRef fp_cast_ty = LLVMFunctionType(f32, fp_cast_params, 1, 0);
|
||||
LLVMValueRef fp_cast_func = LLVMAddFunction(mod, "float_casts", fp_cast_ty);
|
||||
LLVMValueRef f64_val = LLVMGetParam(fp_cast_func, 0);
|
||||
LLVMSetValueName2(f64_val, "val", 3);
|
||||
|
||||
LLVMBasicBlockRef fp_entry = LLVMAppendBasicBlockInContext(ctx, fp_cast_func, "entry");
|
||||
LLVMPositionBuilderAtEnd(builder, fp_entry);
|
||||
LLVMBasicBlockRef fp_entry =
|
||||
LLVMAppendBasicBlockInContext(ctx, fp_cast_func, "entry");
|
||||
LLVMPositionBuilderAtEnd(builder, fp_entry);
|
||||
|
||||
// FP truncate f64 -> f32
|
||||
LLVMValueRef fptrunc = LLVMBuildFPTrunc(builder, f64_val, f32, "fptrunc");
|
||||
// FP truncate f64 -> f32
|
||||
LLVMValueRef fptrunc = LLVMBuildFPTrunc(builder, f64_val, f32, "fptrunc");
|
||||
|
||||
// FP extend f32 -> f64
|
||||
LLVMValueRef fpext = LLVMBuildFPExt(builder, fptrunc, f64, "fpext");
|
||||
// FP extend f32 -> f64
|
||||
LLVMValueRef fpext = LLVMBuildFPExt(builder, fptrunc, f64, "fpext");
|
||||
|
||||
LLVMBuildRet(builder, fptrunc);
|
||||
LLVMBuildRet(builder, fptrunc);
|
||||
|
||||
// ==========================================
|
||||
// Function 3: Int <-> Float casts
|
||||
// ==========================================
|
||||
LLVMTypeRef mixed_params[] = {i32, f64};
|
||||
LLVMTypeRef mixed_ty = LLVMFunctionType(void_ty, mixed_params, 2, 0);
|
||||
LLVMValueRef mixed_func = LLVMAddFunction(mod, "int_float_casts", mixed_ty);
|
||||
LLVMValueRef int_param = LLVMGetParam(mixed_func, 0);
|
||||
LLVMValueRef fp_param = LLVMGetParam(mixed_func, 1);
|
||||
LLVMSetValueName2(int_param, "i", 1);
|
||||
LLVMSetValueName2(fp_param, "f", 1);
|
||||
// ==========================================
|
||||
// Function 3: Int <-> Float casts
|
||||
// ==========================================
|
||||
LLVMTypeRef mixed_params[] = {i32, f64};
|
||||
LLVMTypeRef mixed_ty = LLVMFunctionType(void_ty, mixed_params, 2, 0);
|
||||
LLVMValueRef mixed_func = LLVMAddFunction(mod, "int_float_casts", mixed_ty);
|
||||
LLVMValueRef int_param = LLVMGetParam(mixed_func, 0);
|
||||
LLVMValueRef fp_param = LLVMGetParam(mixed_func, 1);
|
||||
LLVMSetValueName2(int_param, "i", 1);
|
||||
LLVMSetValueName2(fp_param, "f", 1);
|
||||
|
||||
LLVMBasicBlockRef mixed_entry = LLVMAppendBasicBlockInContext(ctx, mixed_func, "entry");
|
||||
LLVMPositionBuilderAtEnd(builder, mixed_entry);
|
||||
LLVMBasicBlockRef mixed_entry =
|
||||
LLVMAppendBasicBlockInContext(ctx, mixed_func, "entry");
|
||||
LLVMPositionBuilderAtEnd(builder, mixed_entry);
|
||||
|
||||
// Int -> Float
|
||||
LLVMValueRef uitofp = LLVMBuildUIToFP(builder, int_param, f64, "uitofp");
|
||||
LLVMValueRef sitofp = LLVMBuildSIToFP(builder, int_param, f64, "sitofp");
|
||||
// Int -> Float
|
||||
LLVMValueRef uitofp = LLVMBuildUIToFP(builder, int_param, f64, "uitofp");
|
||||
LLVMValueRef sitofp = LLVMBuildSIToFP(builder, int_param, f64, "sitofp");
|
||||
|
||||
// Float -> Int
|
||||
LLVMValueRef fptoui = LLVMBuildFPToUI(builder, fp_param, i32, "fptoui");
|
||||
LLVMValueRef fptosi = LLVMBuildFPToSI(builder, fp_param, i32, "fptosi");
|
||||
// Float -> Int
|
||||
LLVMValueRef fptoui = LLVMBuildFPToUI(builder, fp_param, i32, "fptoui");
|
||||
LLVMValueRef fptosi = LLVMBuildFPToSI(builder, fp_param, i32, "fptosi");
|
||||
|
||||
LLVMBuildRetVoid(builder);
|
||||
LLVMBuildRetVoid(builder);
|
||||
|
||||
// ==========================================
|
||||
// Function 4: Pointer casts
|
||||
// ==========================================
|
||||
LLVMTypeRef ptr_params[] = {ptr, i64};
|
||||
LLVMTypeRef ptr_ty = LLVMFunctionType(void_ty, ptr_params, 2, 0);
|
||||
LLVMValueRef ptr_func = LLVMAddFunction(mod, "pointer_casts", ptr_ty);
|
||||
LLVMValueRef ptr_param = LLVMGetParam(ptr_func, 0);
|
||||
LLVMValueRef int_for_ptr = LLVMGetParam(ptr_func, 1);
|
||||
LLVMSetValueName2(ptr_param, "p", 1);
|
||||
LLVMSetValueName2(int_for_ptr, "addr", 4);
|
||||
// ==========================================
|
||||
// Function 4: Pointer casts
|
||||
// ==========================================
|
||||
LLVMTypeRef ptr_params[] = {ptr, i64};
|
||||
LLVMTypeRef ptr_ty = LLVMFunctionType(void_ty, ptr_params, 2, 0);
|
||||
LLVMValueRef ptr_func = LLVMAddFunction(mod, "pointer_casts", ptr_ty);
|
||||
LLVMValueRef ptr_param = LLVMGetParam(ptr_func, 0);
|
||||
LLVMValueRef int_for_ptr = LLVMGetParam(ptr_func, 1);
|
||||
LLVMSetValueName2(ptr_param, "p", 1);
|
||||
LLVMSetValueName2(int_for_ptr, "addr", 4);
|
||||
|
||||
LLVMBasicBlockRef ptr_entry = LLVMAppendBasicBlockInContext(ctx, ptr_func, "entry");
|
||||
LLVMPositionBuilderAtEnd(builder, ptr_entry);
|
||||
LLVMBasicBlockRef ptr_entry =
|
||||
LLVMAppendBasicBlockInContext(ctx, ptr_func, "entry");
|
||||
LLVMPositionBuilderAtEnd(builder, ptr_entry);
|
||||
|
||||
// Pointer -> Int
|
||||
LLVMValueRef ptrtoint = LLVMBuildPtrToInt(builder, ptr_param, i64, "ptrtoint");
|
||||
// Pointer -> Int
|
||||
LLVMValueRef ptrtoint =
|
||||
LLVMBuildPtrToInt(builder, ptr_param, i64, "ptrtoint");
|
||||
|
||||
// Int -> Pointer
|
||||
LLVMValueRef inttoptr = LLVMBuildIntToPtr(builder, int_for_ptr, ptr, "inttoptr");
|
||||
// Int -> Pointer
|
||||
LLVMValueRef inttoptr =
|
||||
LLVMBuildIntToPtr(builder, int_for_ptr, ptr, "inttoptr");
|
||||
|
||||
LLVMBuildRetVoid(builder);
|
||||
LLVMBuildRetVoid(builder);
|
||||
|
||||
// ==========================================
|
||||
// Function 5: Bitcast
|
||||
// ==========================================
|
||||
LLVMTypeRef vec_i32 = LLVMVectorType(i32, 4);
|
||||
LLVMTypeRef vec_f32 = LLVMVectorType(f32, 4);
|
||||
// ==========================================
|
||||
// Function 5: Bitcast
|
||||
// ==========================================
|
||||
LLVMTypeRef vec_i32 = LLVMVectorType(i32, 4);
|
||||
LLVMTypeRef vec_f32 = LLVMVectorType(f32, 4);
|
||||
|
||||
LLVMTypeRef bitcast_params[] = {vec_i32};
|
||||
LLVMTypeRef bitcast_ty = LLVMFunctionType(vec_f32, bitcast_params, 1, 0);
|
||||
LLVMValueRef bitcast_func = LLVMAddFunction(mod, "bitcast_example", bitcast_ty);
|
||||
LLVMValueRef vec_param = LLVMGetParam(bitcast_func, 0);
|
||||
LLVMSetValueName2(vec_param, "v", 1);
|
||||
LLVMTypeRef bitcast_params[] = {vec_i32};
|
||||
LLVMTypeRef bitcast_ty = LLVMFunctionType(vec_f32, bitcast_params, 1, 0);
|
||||
LLVMValueRef bitcast_func =
|
||||
LLVMAddFunction(mod, "bitcast_example", bitcast_ty);
|
||||
LLVMValueRef vec_param = LLVMGetParam(bitcast_func, 0);
|
||||
LLVMSetValueName2(vec_param, "v", 1);
|
||||
|
||||
LLVMBasicBlockRef bitcast_entry = LLVMAppendBasicBlockInContext(ctx, bitcast_func, "entry");
|
||||
LLVMPositionBuilderAtEnd(builder, bitcast_entry);
|
||||
LLVMBasicBlockRef bitcast_entry =
|
||||
LLVMAppendBasicBlockInContext(ctx, bitcast_func, "entry");
|
||||
LLVMPositionBuilderAtEnd(builder, bitcast_entry);
|
||||
|
||||
LLVMValueRef bitcast = LLVMBuildBitCast(builder, vec_param, vec_f32, "bitcast");
|
||||
LLVMBuildRet(builder, bitcast);
|
||||
LLVMValueRef bitcast =
|
||||
LLVMBuildBitCast(builder, vec_param, vec_f32, "bitcast");
|
||||
LLVMBuildRet(builder, bitcast);
|
||||
|
||||
LLVMDisposeBuilder(builder);
|
||||
LLVMDisposeBuilder(builder);
|
||||
|
||||
// Verify module
|
||||
char *error = nullptr;
|
||||
if (LLVMVerifyModule(mod, LLVMReturnStatusAction, &error)) {
|
||||
fprintf(stderr, "; Verification failed: %s\n", error);
|
||||
LLVMDisposeMessage(error);
|
||||
LLVMDisposeModule(mod);
|
||||
LLVMContextDispose(ctx);
|
||||
return 1;
|
||||
}
|
||||
// Verify module
|
||||
char *error = nullptr;
|
||||
if (LLVMVerifyModule(mod, LLVMReturnStatusAction, &error)) {
|
||||
fprintf(stderr, "; Verification failed: %s\n", error);
|
||||
LLVMDisposeMessage(error);
|
||||
|
||||
// Print diagnostic comments
|
||||
printf("; Test: test_builder_casts\n");
|
||||
printf(";\n");
|
||||
printf("; Cast operations demonstrated:\n");
|
||||
printf("; Integer: trunc, zext, sext, intcast2\n");
|
||||
printf("; Float: fptrunc, fpext\n");
|
||||
printf("; Int<->Float: uitofp, sitofp, fptoui, fptosi\n");
|
||||
printf("; Pointer: ptrtoint, inttoptr\n");
|
||||
printf("; Reinterpret: bitcast\n");
|
||||
printf("\n");
|
||||
|
||||
// Print module IR
|
||||
char *ir = LLVMPrintModuleToString(mod);
|
||||
printf("%s", ir);
|
||||
LLVMDisposeMessage(ir);
|
||||
|
||||
// Cleanup
|
||||
LLVMDisposeModule(mod);
|
||||
LLVMContextDispose(ctx);
|
||||
return 1;
|
||||
}
|
||||
LLVMDisposeMessage(error);
|
||||
|
||||
return 0;
|
||||
// Print diagnostic comments
|
||||
printf("; Test: test_builder_casts\n");
|
||||
printf(";\n");
|
||||
printf("; Cast operations demonstrated:\n");
|
||||
printf("; Integer: trunc, zext, sext, intcast2\n");
|
||||
printf("; Float: fptrunc, fpext\n");
|
||||
printf("; Int<->Float: uitofp, sitofp, fptoui, fptosi\n");
|
||||
printf("; Pointer: ptrtoint, inttoptr\n");
|
||||
printf("; Reinterpret: bitcast\n");
|
||||
printf("\n");
|
||||
|
||||
// Print module IR
|
||||
char *ir = LLVMPrintModuleToString(mod);
|
||||
printf("%s", ir);
|
||||
LLVMDisposeMessage(ir);
|
||||
|
||||
// Cleanup
|
||||
LLVMDisposeModule(mod);
|
||||
LLVMContextDispose(ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+210
-170
@@ -9,205 +9,245 @@
|
||||
* - LLVMGetICmpPredicate(), LLVMGetFCmpPredicate()
|
||||
*/
|
||||
|
||||
#include <llvm-c/Core.h>
|
||||
#include <llvm-c/Analysis.h>
|
||||
#include <cstdio>
|
||||
#include <llvm-c/Analysis.h>
|
||||
#include <llvm-c/Core.h>
|
||||
|
||||
const char* int_pred_name(LLVMIntPredicate pred) {
|
||||
switch (pred) {
|
||||
case LLVMIntEQ: return "eq";
|
||||
case LLVMIntNE: return "ne";
|
||||
case LLVMIntUGT: return "ugt";
|
||||
case LLVMIntUGE: return "uge";
|
||||
case LLVMIntULT: return "ult";
|
||||
case LLVMIntULE: return "ule";
|
||||
case LLVMIntSGT: return "sgt";
|
||||
case LLVMIntSGE: return "sge";
|
||||
case LLVMIntSLT: return "slt";
|
||||
case LLVMIntSLE: return "sle";
|
||||
default: return "unknown";
|
||||
}
|
||||
const char *int_pred_name(LLVMIntPredicate pred) {
|
||||
switch (pred) {
|
||||
case LLVMIntEQ:
|
||||
return "eq";
|
||||
case LLVMIntNE:
|
||||
return "ne";
|
||||
case LLVMIntUGT:
|
||||
return "ugt";
|
||||
case LLVMIntUGE:
|
||||
return "uge";
|
||||
case LLVMIntULT:
|
||||
return "ult";
|
||||
case LLVMIntULE:
|
||||
return "ule";
|
||||
case LLVMIntSGT:
|
||||
return "sgt";
|
||||
case LLVMIntSGE:
|
||||
return "sge";
|
||||
case LLVMIntSLT:
|
||||
return "slt";
|
||||
case LLVMIntSLE:
|
||||
return "sle";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
const char* real_pred_name(LLVMRealPredicate pred) {
|
||||
switch (pred) {
|
||||
case LLVMRealPredicateFalse: return "false";
|
||||
case LLVMRealOEQ: return "oeq";
|
||||
case LLVMRealOGT: return "ogt";
|
||||
case LLVMRealOGE: return "oge";
|
||||
case LLVMRealOLT: return "olt";
|
||||
case LLVMRealOLE: return "ole";
|
||||
case LLVMRealONE: return "one";
|
||||
case LLVMRealORD: return "ord";
|
||||
case LLVMRealUNO: return "uno";
|
||||
case LLVMRealUEQ: return "ueq";
|
||||
case LLVMRealUGT: return "ugt";
|
||||
case LLVMRealUGE: return "uge";
|
||||
case LLVMRealULT: return "ult";
|
||||
case LLVMRealULE: return "ule";
|
||||
case LLVMRealUNE: return "une";
|
||||
case LLVMRealPredicateTrue: return "true";
|
||||
default: return "unknown";
|
||||
}
|
||||
const char *real_pred_name(LLVMRealPredicate pred) {
|
||||
switch (pred) {
|
||||
case LLVMRealPredicateFalse:
|
||||
return "false";
|
||||
case LLVMRealOEQ:
|
||||
return "oeq";
|
||||
case LLVMRealOGT:
|
||||
return "ogt";
|
||||
case LLVMRealOGE:
|
||||
return "oge";
|
||||
case LLVMRealOLT:
|
||||
return "olt";
|
||||
case LLVMRealOLE:
|
||||
return "ole";
|
||||
case LLVMRealONE:
|
||||
return "one";
|
||||
case LLVMRealORD:
|
||||
return "ord";
|
||||
case LLVMRealUNO:
|
||||
return "uno";
|
||||
case LLVMRealUEQ:
|
||||
return "ueq";
|
||||
case LLVMRealUGT:
|
||||
return "ugt";
|
||||
case LLVMRealUGE:
|
||||
return "uge";
|
||||
case LLVMRealULT:
|
||||
return "ult";
|
||||
case LLVMRealULE:
|
||||
return "ule";
|
||||
case LLVMRealUNE:
|
||||
return "une";
|
||||
case LLVMRealPredicateTrue:
|
||||
return "true";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
LLVMContextRef ctx = LLVMContextCreate();
|
||||
LLVMModuleRef mod = LLVMModuleCreateWithNameInContext("test_builder_cmp", ctx);
|
||||
LLVMContextRef ctx = LLVMContextCreate();
|
||||
LLVMModuleRef mod =
|
||||
LLVMModuleCreateWithNameInContext("test_builder_cmp", ctx);
|
||||
|
||||
LLVMTypeRef i1 = LLVMInt1TypeInContext(ctx);
|
||||
LLVMTypeRef i32 = LLVMInt32TypeInContext(ctx);
|
||||
LLVMTypeRef f64 = LLVMDoubleTypeInContext(ctx);
|
||||
LLVMTypeRef void_ty = LLVMVoidTypeInContext(ctx);
|
||||
LLVMTypeRef i1 = LLVMInt1TypeInContext(ctx);
|
||||
LLVMTypeRef i32 = LLVMInt32TypeInContext(ctx);
|
||||
LLVMTypeRef f64 = LLVMDoubleTypeInContext(ctx);
|
||||
LLVMTypeRef void_ty = LLVMVoidTypeInContext(ctx);
|
||||
|
||||
LLVMBuilderRef builder = LLVMCreateBuilderInContext(ctx);
|
||||
LLVMBuilderRef builder = LLVMCreateBuilderInContext(ctx);
|
||||
|
||||
// ==========================================
|
||||
// Function 1: Integer comparisons
|
||||
// ==========================================
|
||||
LLVMTypeRef icmp_params[] = {i32, i32};
|
||||
LLVMTypeRef icmp_ty = LLVMFunctionType(void_ty, icmp_params, 2, 0);
|
||||
LLVMValueRef icmp_func = LLVMAddFunction(mod, "int_comparisons", icmp_ty);
|
||||
LLVMValueRef a = LLVMGetParam(icmp_func, 0);
|
||||
LLVMValueRef b = LLVMGetParam(icmp_func, 1);
|
||||
LLVMSetValueName2(a, "a", 1);
|
||||
LLVMSetValueName2(b, "b", 1);
|
||||
// ==========================================
|
||||
// Function 1: Integer comparisons
|
||||
// ==========================================
|
||||
LLVMTypeRef icmp_params[] = {i32, i32};
|
||||
LLVMTypeRef icmp_ty = LLVMFunctionType(void_ty, icmp_params, 2, 0);
|
||||
LLVMValueRef icmp_func = LLVMAddFunction(mod, "int_comparisons", icmp_ty);
|
||||
LLVMValueRef a = LLVMGetParam(icmp_func, 0);
|
||||
LLVMValueRef b = LLVMGetParam(icmp_func, 1);
|
||||
LLVMSetValueName2(a, "a", 1);
|
||||
LLVMSetValueName2(b, "b", 1);
|
||||
|
||||
LLVMBasicBlockRef icmp_entry = LLVMAppendBasicBlockInContext(ctx, icmp_func, "entry");
|
||||
LLVMPositionBuilderAtEnd(builder, icmp_entry);
|
||||
LLVMBasicBlockRef icmp_entry =
|
||||
LLVMAppendBasicBlockInContext(ctx, icmp_func, "entry");
|
||||
LLVMPositionBuilderAtEnd(builder, icmp_entry);
|
||||
|
||||
// All integer predicates
|
||||
LLVMValueRef icmp_eq = LLVMBuildICmp(builder, LLVMIntEQ, a, b, "eq");
|
||||
LLVMValueRef icmp_ne = LLVMBuildICmp(builder, LLVMIntNE, a, b, "ne");
|
||||
LLVMValueRef icmp_ugt = LLVMBuildICmp(builder, LLVMIntUGT, a, b, "ugt");
|
||||
LLVMValueRef icmp_uge = LLVMBuildICmp(builder, LLVMIntUGE, a, b, "uge");
|
||||
LLVMValueRef icmp_ult = LLVMBuildICmp(builder, LLVMIntULT, a, b, "ult");
|
||||
LLVMValueRef icmp_ule = LLVMBuildICmp(builder, LLVMIntULE, a, b, "ule");
|
||||
LLVMValueRef icmp_sgt = LLVMBuildICmp(builder, LLVMIntSGT, a, b, "sgt");
|
||||
LLVMValueRef icmp_sge = LLVMBuildICmp(builder, LLVMIntSGE, a, b, "sge");
|
||||
LLVMValueRef icmp_slt = LLVMBuildICmp(builder, LLVMIntSLT, a, b, "slt");
|
||||
LLVMValueRef icmp_sle = LLVMBuildICmp(builder, LLVMIntSLE, a, b, "sle");
|
||||
// All integer predicates
|
||||
LLVMValueRef icmp_eq = LLVMBuildICmp(builder, LLVMIntEQ, a, b, "eq");
|
||||
LLVMValueRef icmp_ne = LLVMBuildICmp(builder, LLVMIntNE, a, b, "ne");
|
||||
LLVMValueRef icmp_ugt = LLVMBuildICmp(builder, LLVMIntUGT, a, b, "ugt");
|
||||
LLVMValueRef icmp_uge = LLVMBuildICmp(builder, LLVMIntUGE, a, b, "uge");
|
||||
LLVMValueRef icmp_ult = LLVMBuildICmp(builder, LLVMIntULT, a, b, "ult");
|
||||
LLVMValueRef icmp_ule = LLVMBuildICmp(builder, LLVMIntULE, a, b, "ule");
|
||||
LLVMValueRef icmp_sgt = LLVMBuildICmp(builder, LLVMIntSGT, a, b, "sgt");
|
||||
LLVMValueRef icmp_sge = LLVMBuildICmp(builder, LLVMIntSGE, a, b, "sge");
|
||||
LLVMValueRef icmp_slt = LLVMBuildICmp(builder, LLVMIntSLT, a, b, "slt");
|
||||
LLVMValueRef icmp_sle = LLVMBuildICmp(builder, LLVMIntSLE, a, b, "sle");
|
||||
|
||||
LLVMBuildRetVoid(builder);
|
||||
LLVMBuildRetVoid(builder);
|
||||
|
||||
// ==========================================
|
||||
// Function 2: Float comparisons
|
||||
// ==========================================
|
||||
LLVMTypeRef fcmp_params[] = {f64, f64};
|
||||
LLVMTypeRef fcmp_ty = LLVMFunctionType(void_ty, fcmp_params, 2, 0);
|
||||
LLVMValueRef fcmp_func = LLVMAddFunction(mod, "float_comparisons", fcmp_ty);
|
||||
LLVMValueRef x = LLVMGetParam(fcmp_func, 0);
|
||||
LLVMValueRef y = LLVMGetParam(fcmp_func, 1);
|
||||
LLVMSetValueName2(x, "x", 1);
|
||||
LLVMSetValueName2(y, "y", 1);
|
||||
// ==========================================
|
||||
// Function 2: Float comparisons
|
||||
// ==========================================
|
||||
LLVMTypeRef fcmp_params[] = {f64, f64};
|
||||
LLVMTypeRef fcmp_ty = LLVMFunctionType(void_ty, fcmp_params, 2, 0);
|
||||
LLVMValueRef fcmp_func = LLVMAddFunction(mod, "float_comparisons", fcmp_ty);
|
||||
LLVMValueRef x = LLVMGetParam(fcmp_func, 0);
|
||||
LLVMValueRef y = LLVMGetParam(fcmp_func, 1);
|
||||
LLVMSetValueName2(x, "x", 1);
|
||||
LLVMSetValueName2(y, "y", 1);
|
||||
|
||||
LLVMBasicBlockRef fcmp_entry = LLVMAppendBasicBlockInContext(ctx, fcmp_func, "entry");
|
||||
LLVMPositionBuilderAtEnd(builder, fcmp_entry);
|
||||
LLVMBasicBlockRef fcmp_entry =
|
||||
LLVMAppendBasicBlockInContext(ctx, fcmp_func, "entry");
|
||||
LLVMPositionBuilderAtEnd(builder, fcmp_entry);
|
||||
|
||||
// Ordered comparisons (false if either is NaN)
|
||||
LLVMValueRef fcmp_oeq = LLVMBuildFCmp(builder, LLVMRealOEQ, x, y, "oeq");
|
||||
LLVMValueRef fcmp_ogt = LLVMBuildFCmp(builder, LLVMRealOGT, x, y, "ogt");
|
||||
LLVMValueRef fcmp_oge = LLVMBuildFCmp(builder, LLVMRealOGE, x, y, "oge");
|
||||
LLVMValueRef fcmp_olt = LLVMBuildFCmp(builder, LLVMRealOLT, x, y, "olt");
|
||||
LLVMValueRef fcmp_ole = LLVMBuildFCmp(builder, LLVMRealOLE, x, y, "ole");
|
||||
LLVMValueRef fcmp_one = LLVMBuildFCmp(builder, LLVMRealONE, x, y, "one");
|
||||
LLVMValueRef fcmp_ord = LLVMBuildFCmp(builder, LLVMRealORD, x, y, "ord");
|
||||
// Ordered comparisons (false if either is NaN)
|
||||
LLVMValueRef fcmp_oeq = LLVMBuildFCmp(builder, LLVMRealOEQ, x, y, "oeq");
|
||||
LLVMValueRef fcmp_ogt = LLVMBuildFCmp(builder, LLVMRealOGT, x, y, "ogt");
|
||||
LLVMValueRef fcmp_oge = LLVMBuildFCmp(builder, LLVMRealOGE, x, y, "oge");
|
||||
LLVMValueRef fcmp_olt = LLVMBuildFCmp(builder, LLVMRealOLT, x, y, "olt");
|
||||
LLVMValueRef fcmp_ole = LLVMBuildFCmp(builder, LLVMRealOLE, x, y, "ole");
|
||||
LLVMValueRef fcmp_one = LLVMBuildFCmp(builder, LLVMRealONE, x, y, "one");
|
||||
LLVMValueRef fcmp_ord = LLVMBuildFCmp(builder, LLVMRealORD, x, y, "ord");
|
||||
|
||||
// Unordered comparisons (true if either is NaN)
|
||||
LLVMValueRef fcmp_uno = LLVMBuildFCmp(builder, LLVMRealUNO, x, y, "uno");
|
||||
LLVMValueRef fcmp_ueq = LLVMBuildFCmp(builder, LLVMRealUEQ, x, y, "ueq");
|
||||
LLVMValueRef fcmp_ugt = LLVMBuildFCmp(builder, LLVMRealUGT, x, y, "ugt");
|
||||
LLVMValueRef fcmp_uge = LLVMBuildFCmp(builder, LLVMRealUGE, x, y, "uge");
|
||||
LLVMValueRef fcmp_ult = LLVMBuildFCmp(builder, LLVMRealULT, x, y, "ult");
|
||||
LLVMValueRef fcmp_ule = LLVMBuildFCmp(builder, LLVMRealULE, x, y, "ule");
|
||||
LLVMValueRef fcmp_une = LLVMBuildFCmp(builder, LLVMRealUNE, x, y, "une");
|
||||
// Unordered comparisons (true if either is NaN)
|
||||
LLVMValueRef fcmp_uno = LLVMBuildFCmp(builder, LLVMRealUNO, x, y, "uno");
|
||||
LLVMValueRef fcmp_ueq = LLVMBuildFCmp(builder, LLVMRealUEQ, x, y, "ueq");
|
||||
LLVMValueRef fcmp_ugt = LLVMBuildFCmp(builder, LLVMRealUGT, x, y, "ugt");
|
||||
LLVMValueRef fcmp_uge = LLVMBuildFCmp(builder, LLVMRealUGE, x, y, "uge");
|
||||
LLVMValueRef fcmp_ult = LLVMBuildFCmp(builder, LLVMRealULT, x, y, "ult");
|
||||
LLVMValueRef fcmp_ule = LLVMBuildFCmp(builder, LLVMRealULE, x, y, "ule");
|
||||
LLVMValueRef fcmp_une = LLVMBuildFCmp(builder, LLVMRealUNE, x, y, "une");
|
||||
|
||||
// Always true/false
|
||||
LLVMValueRef fcmp_true = LLVMBuildFCmp(builder, LLVMRealPredicateTrue, x, y, "always_true");
|
||||
LLVMValueRef fcmp_false = LLVMBuildFCmp(builder, LLVMRealPredicateFalse, x, y, "always_false");
|
||||
// Always true/false
|
||||
LLVMValueRef fcmp_true =
|
||||
LLVMBuildFCmp(builder, LLVMRealPredicateTrue, x, y, "always_true");
|
||||
LLVMValueRef fcmp_false =
|
||||
LLVMBuildFCmp(builder, LLVMRealPredicateFalse, x, y, "always_false");
|
||||
|
||||
LLVMBuildRetVoid(builder);
|
||||
LLVMBuildRetVoid(builder);
|
||||
|
||||
// ==========================================
|
||||
// Function 3: Select instruction
|
||||
// ==========================================
|
||||
LLVMTypeRef sel_params[] = {i1, i32, i32};
|
||||
LLVMTypeRef sel_ty = LLVMFunctionType(i32, sel_params, 3, 0);
|
||||
LLVMValueRef sel_func = LLVMAddFunction(mod, "select_example", sel_ty);
|
||||
LLVMValueRef cond = LLVMGetParam(sel_func, 0);
|
||||
LLVMValueRef true_val = LLVMGetParam(sel_func, 1);
|
||||
LLVMValueRef false_val = LLVMGetParam(sel_func, 2);
|
||||
LLVMSetValueName2(cond, "cond", 4);
|
||||
LLVMSetValueName2(true_val, "true_val", 8);
|
||||
LLVMSetValueName2(false_val, "false_val", 9);
|
||||
// ==========================================
|
||||
// Function 3: Select instruction
|
||||
// ==========================================
|
||||
LLVMTypeRef sel_params[] = {i1, i32, i32};
|
||||
LLVMTypeRef sel_ty = LLVMFunctionType(i32, sel_params, 3, 0);
|
||||
LLVMValueRef sel_func = LLVMAddFunction(mod, "select_example", sel_ty);
|
||||
LLVMValueRef cond = LLVMGetParam(sel_func, 0);
|
||||
LLVMValueRef true_val = LLVMGetParam(sel_func, 1);
|
||||
LLVMValueRef false_val = LLVMGetParam(sel_func, 2);
|
||||
LLVMSetValueName2(cond, "cond", 4);
|
||||
LLVMSetValueName2(true_val, "true_val", 8);
|
||||
LLVMSetValueName2(false_val, "false_val", 9);
|
||||
|
||||
LLVMBasicBlockRef sel_entry = LLVMAppendBasicBlockInContext(ctx, sel_func, "entry");
|
||||
LLVMPositionBuilderAtEnd(builder, sel_entry);
|
||||
LLVMBasicBlockRef sel_entry =
|
||||
LLVMAppendBasicBlockInContext(ctx, sel_func, "entry");
|
||||
LLVMPositionBuilderAtEnd(builder, sel_entry);
|
||||
|
||||
LLVMValueRef selected = LLVMBuildSelect(builder, cond, true_val, false_val, "selected");
|
||||
LLVMBuildRet(builder, selected);
|
||||
LLVMValueRef selected =
|
||||
LLVMBuildSelect(builder, cond, true_val, false_val, "selected");
|
||||
LLVMBuildRet(builder, selected);
|
||||
|
||||
// ==========================================
|
||||
// Function 4: Select with comparison
|
||||
// ==========================================
|
||||
LLVMTypeRef max_params[] = {i32, i32};
|
||||
LLVMTypeRef max_ty = LLVMFunctionType(i32, max_params, 2, 0);
|
||||
LLVMValueRef max_func = LLVMAddFunction(mod, "max", max_ty);
|
||||
LLVMValueRef m_a = LLVMGetParam(max_func, 0);
|
||||
LLVMValueRef m_b = LLVMGetParam(max_func, 1);
|
||||
LLVMSetValueName2(m_a, "a", 1);
|
||||
LLVMSetValueName2(m_b, "b", 1);
|
||||
// ==========================================
|
||||
// Function 4: Select with comparison
|
||||
// ==========================================
|
||||
LLVMTypeRef max_params[] = {i32, i32};
|
||||
LLVMTypeRef max_ty = LLVMFunctionType(i32, max_params, 2, 0);
|
||||
LLVMValueRef max_func = LLVMAddFunction(mod, "max", max_ty);
|
||||
LLVMValueRef m_a = LLVMGetParam(max_func, 0);
|
||||
LLVMValueRef m_b = LLVMGetParam(max_func, 1);
|
||||
LLVMSetValueName2(m_a, "a", 1);
|
||||
LLVMSetValueName2(m_b, "b", 1);
|
||||
|
||||
LLVMBasicBlockRef max_entry = LLVMAppendBasicBlockInContext(ctx, max_func, "entry");
|
||||
LLVMPositionBuilderAtEnd(builder, max_entry);
|
||||
LLVMBasicBlockRef max_entry =
|
||||
LLVMAppendBasicBlockInContext(ctx, max_func, "entry");
|
||||
LLVMPositionBuilderAtEnd(builder, max_entry);
|
||||
|
||||
LLVMValueRef cmp_gt = LLVMBuildICmp(builder, LLVMIntSGT, m_a, m_b, "a_gt_b");
|
||||
LLVMValueRef max_result = LLVMBuildSelect(builder, cmp_gt, m_a, m_b, "max");
|
||||
LLVMBuildRet(builder, max_result);
|
||||
LLVMValueRef cmp_gt = LLVMBuildICmp(builder, LLVMIntSGT, m_a, m_b, "a_gt_b");
|
||||
LLVMValueRef max_result = LLVMBuildSelect(builder, cmp_gt, m_a, m_b, "max");
|
||||
LLVMBuildRet(builder, max_result);
|
||||
|
||||
LLVMDisposeBuilder(builder);
|
||||
LLVMDisposeBuilder(builder);
|
||||
|
||||
// Verify module
|
||||
char *error = nullptr;
|
||||
if (LLVMVerifyModule(mod, LLVMReturnStatusAction, &error)) {
|
||||
fprintf(stderr, "; Verification failed: %s\n", error);
|
||||
LLVMDisposeMessage(error);
|
||||
LLVMDisposeModule(mod);
|
||||
LLVMContextDispose(ctx);
|
||||
return 1;
|
||||
}
|
||||
// Verify module
|
||||
char *error = nullptr;
|
||||
if (LLVMVerifyModule(mod, LLVMReturnStatusAction, &error)) {
|
||||
fprintf(stderr, "; Verification failed: %s\n", error);
|
||||
LLVMDisposeMessage(error);
|
||||
|
||||
// Print diagnostic comments
|
||||
printf("; Test: test_builder_cmp\n");
|
||||
printf(";\n");
|
||||
printf("; Integer comparison predicates:\n");
|
||||
printf("; eq, ne (equality)\n");
|
||||
printf("; ugt, uge, ult, ule (unsigned)\n");
|
||||
printf("; sgt, sge, slt, sle (signed)\n");
|
||||
printf(";\n");
|
||||
printf("; Float comparison predicates:\n");
|
||||
printf("; Ordered: oeq, ogt, oge, olt, ole, one, ord\n");
|
||||
printf("; Unordered: uno, ueq, ugt, uge, ult, ule, une\n");
|
||||
printf("; Constant: true, false\n");
|
||||
printf(";\n");
|
||||
printf("; Predicate extraction:\n");
|
||||
printf("; icmp_eq predicate: %s\n", int_pred_name(LLVMGetICmpPredicate(icmp_eq)));
|
||||
printf("; icmp_slt predicate: %s\n", int_pred_name(LLVMGetICmpPredicate(icmp_slt)));
|
||||
printf("; fcmp_oeq predicate: %s\n", real_pred_name(LLVMGetFCmpPredicate(fcmp_oeq)));
|
||||
printf("; fcmp_uno predicate: %s\n", real_pred_name(LLVMGetFCmpPredicate(fcmp_uno)));
|
||||
printf(";\n");
|
||||
printf("; Select instruction: cond ? true_val : false_val\n");
|
||||
printf("\n");
|
||||
|
||||
// Print module IR
|
||||
char *ir = LLVMPrintModuleToString(mod);
|
||||
printf("%s", ir);
|
||||
LLVMDisposeMessage(ir);
|
||||
|
||||
// Cleanup
|
||||
LLVMDisposeModule(mod);
|
||||
LLVMContextDispose(ctx);
|
||||
return 1;
|
||||
}
|
||||
LLVMDisposeMessage(error);
|
||||
|
||||
return 0;
|
||||
// Print diagnostic comments
|
||||
printf("; Test: test_builder_cmp\n");
|
||||
printf(";\n");
|
||||
printf("; Integer comparison predicates:\n");
|
||||
printf("; eq, ne (equality)\n");
|
||||
printf("; ugt, uge, ult, ule (unsigned)\n");
|
||||
printf("; sgt, sge, slt, sle (signed)\n");
|
||||
printf(";\n");
|
||||
printf("; Float comparison predicates:\n");
|
||||
printf("; Ordered: oeq, ogt, oge, olt, ole, one, ord\n");
|
||||
printf("; Unordered: uno, ueq, ugt, uge, ult, ule, une\n");
|
||||
printf("; Constant: true, false\n");
|
||||
printf(";\n");
|
||||
printf("; Predicate extraction:\n");
|
||||
printf("; icmp_eq predicate: %s\n",
|
||||
int_pred_name(LLVMGetICmpPredicate(icmp_eq)));
|
||||
printf("; icmp_slt predicate: %s\n",
|
||||
int_pred_name(LLVMGetICmpPredicate(icmp_slt)));
|
||||
printf("; fcmp_oeq predicate: %s\n",
|
||||
real_pred_name(LLVMGetFCmpPredicate(fcmp_oeq)));
|
||||
printf("; fcmp_uno predicate: %s\n",
|
||||
real_pred_name(LLVMGetFCmpPredicate(fcmp_uno)));
|
||||
printf(";\n");
|
||||
printf("; Select instruction: cond ? true_val : false_val\n");
|
||||
printf("\n");
|
||||
|
||||
// Print module IR
|
||||
char *ir = LLVMPrintModuleToString(mod);
|
||||
printf("%s", ir);
|
||||
LLVMDisposeMessage(ir);
|
||||
|
||||
// Cleanup
|
||||
LLVMDisposeModule(mod);
|
||||
LLVMContextDispose(ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+164
-138
@@ -13,176 +13,202 @@
|
||||
* - LLVMGetNumSuccessors(), LLVMGetSuccessor()
|
||||
*/
|
||||
|
||||
#include <llvm-c/Core.h>
|
||||
#include <llvm-c/Analysis.h>
|
||||
#include <cstdio>
|
||||
#include <llvm-c/Analysis.h>
|
||||
#include <llvm-c/Core.h>
|
||||
|
||||
int main() {
|
||||
LLVMContextRef ctx = LLVMContextCreate();
|
||||
LLVMModuleRef mod = LLVMModuleCreateWithNameInContext("test_builder_control_flow", ctx);
|
||||
LLVMContextRef ctx = LLVMContextCreate();
|
||||
LLVMModuleRef mod =
|
||||
LLVMModuleCreateWithNameInContext("test_builder_control_flow", ctx);
|
||||
|
||||
LLVMTypeRef i32 = LLVMInt32TypeInContext(ctx);
|
||||
LLVMTypeRef i1 = LLVMInt1TypeInContext(ctx);
|
||||
LLVMTypeRef void_ty = LLVMVoidTypeInContext(ctx);
|
||||
LLVMTypeRef i32 = LLVMInt32TypeInContext(ctx);
|
||||
LLVMTypeRef i1 = LLVMInt1TypeInContext(ctx);
|
||||
LLVMTypeRef void_ty = LLVMVoidTypeInContext(ctx);
|
||||
|
||||
LLVMBuilderRef builder = LLVMCreateBuilderInContext(ctx);
|
||||
LLVMBuilderRef builder = LLVMCreateBuilderInContext(ctx);
|
||||
|
||||
// ==========================================
|
||||
// Function 1: void return
|
||||
// ==========================================
|
||||
LLVMTypeRef void_func_ty = LLVMFunctionType(void_ty, nullptr, 0, 0);
|
||||
LLVMValueRef void_func = LLVMAddFunction(mod, "return_void", void_func_ty);
|
||||
LLVMBasicBlockRef void_entry = LLVMAppendBasicBlockInContext(ctx, void_func, "entry");
|
||||
LLVMPositionBuilderAtEnd(builder, void_entry);
|
||||
LLVMBuildRetVoid(builder);
|
||||
// ==========================================
|
||||
// Function 1: void return
|
||||
// ==========================================
|
||||
LLVMTypeRef void_func_ty = LLVMFunctionType(void_ty, nullptr, 0, 0);
|
||||
LLVMValueRef void_func = LLVMAddFunction(mod, "return_void", void_func_ty);
|
||||
LLVMBasicBlockRef void_entry =
|
||||
LLVMAppendBasicBlockInContext(ctx, void_func, "entry");
|
||||
LLVMPositionBuilderAtEnd(builder, void_entry);
|
||||
LLVMBuildRetVoid(builder);
|
||||
|
||||
// ==========================================
|
||||
// Function 2: value return
|
||||
// ==========================================
|
||||
LLVMTypeRef ret_params[] = {i32};
|
||||
LLVMTypeRef ret_func_ty = LLVMFunctionType(i32, ret_params, 1, 0);
|
||||
LLVMValueRef ret_func = LLVMAddFunction(mod, "return_value", ret_func_ty);
|
||||
LLVMValueRef ret_param = LLVMGetParam(ret_func, 0);
|
||||
LLVMSetValueName2(ret_param, "x", 1);
|
||||
// ==========================================
|
||||
// Function 2: value return
|
||||
// ==========================================
|
||||
LLVMTypeRef ret_params[] = {i32};
|
||||
LLVMTypeRef ret_func_ty = LLVMFunctionType(i32, ret_params, 1, 0);
|
||||
LLVMValueRef ret_func = LLVMAddFunction(mod, "return_value", ret_func_ty);
|
||||
LLVMValueRef ret_param = LLVMGetParam(ret_func, 0);
|
||||
LLVMSetValueName2(ret_param, "x", 1);
|
||||
|
||||
LLVMBasicBlockRef ret_entry = LLVMAppendBasicBlockInContext(ctx, ret_func, "entry");
|
||||
LLVMPositionBuilderAtEnd(builder, ret_entry);
|
||||
LLVMBuildRet(builder, ret_param);
|
||||
LLVMBasicBlockRef ret_entry =
|
||||
LLVMAppendBasicBlockInContext(ctx, ret_func, "entry");
|
||||
LLVMPositionBuilderAtEnd(builder, ret_entry);
|
||||
LLVMBuildRet(builder, ret_param);
|
||||
|
||||
// ==========================================
|
||||
// Function 3: unconditional branch
|
||||
// ==========================================
|
||||
LLVMValueRef br_func = LLVMAddFunction(mod, "unconditional_branch", void_func_ty);
|
||||
LLVMBasicBlockRef br_entry = LLVMAppendBasicBlockInContext(ctx, br_func, "entry");
|
||||
LLVMBasicBlockRef br_target = LLVMAppendBasicBlockInContext(ctx, br_func, "target");
|
||||
// ==========================================
|
||||
// Function 3: unconditional branch
|
||||
// ==========================================
|
||||
LLVMValueRef br_func =
|
||||
LLVMAddFunction(mod, "unconditional_branch", void_func_ty);
|
||||
LLVMBasicBlockRef br_entry =
|
||||
LLVMAppendBasicBlockInContext(ctx, br_func, "entry");
|
||||
LLVMBasicBlockRef br_target =
|
||||
LLVMAppendBasicBlockInContext(ctx, br_func, "target");
|
||||
|
||||
LLVMPositionBuilderAtEnd(builder, br_entry);
|
||||
LLVMValueRef br_inst = LLVMBuildBr(builder, br_target);
|
||||
LLVMPositionBuilderAtEnd(builder, br_entry);
|
||||
LLVMValueRef br_inst = LLVMBuildBr(builder, br_target);
|
||||
|
||||
LLVMPositionBuilderAtEnd(builder, br_target);
|
||||
LLVMBuildRetVoid(builder);
|
||||
LLVMPositionBuilderAtEnd(builder, br_target);
|
||||
LLVMBuildRetVoid(builder);
|
||||
|
||||
// ==========================================
|
||||
// Function 4: conditional branch
|
||||
// ==========================================
|
||||
LLVMTypeRef cond_params[] = {i1};
|
||||
LLVMTypeRef cond_func_ty = LLVMFunctionType(i32, cond_params, 1, 0);
|
||||
LLVMValueRef cond_func = LLVMAddFunction(mod, "conditional_branch", cond_func_ty);
|
||||
LLVMValueRef cond_param = LLVMGetParam(cond_func, 0);
|
||||
LLVMSetValueName2(cond_param, "cond", 4);
|
||||
// ==========================================
|
||||
// Function 4: conditional branch
|
||||
// ==========================================
|
||||
LLVMTypeRef cond_params[] = {i1};
|
||||
LLVMTypeRef cond_func_ty = LLVMFunctionType(i32, cond_params, 1, 0);
|
||||
LLVMValueRef cond_func =
|
||||
LLVMAddFunction(mod, "conditional_branch", cond_func_ty);
|
||||
LLVMValueRef cond_param = LLVMGetParam(cond_func, 0);
|
||||
LLVMSetValueName2(cond_param, "cond", 4);
|
||||
|
||||
LLVMBasicBlockRef cond_entry = LLVMAppendBasicBlockInContext(ctx, cond_func, "entry");
|
||||
LLVMBasicBlockRef cond_true = LLVMAppendBasicBlockInContext(ctx, cond_func, "if_true");
|
||||
LLVMBasicBlockRef cond_false = LLVMAppendBasicBlockInContext(ctx, cond_func, "if_false");
|
||||
LLVMBasicBlockRef cond_entry =
|
||||
LLVMAppendBasicBlockInContext(ctx, cond_func, "entry");
|
||||
LLVMBasicBlockRef cond_true =
|
||||
LLVMAppendBasicBlockInContext(ctx, cond_func, "if_true");
|
||||
LLVMBasicBlockRef cond_false =
|
||||
LLVMAppendBasicBlockInContext(ctx, cond_func, "if_false");
|
||||
|
||||
LLVMPositionBuilderAtEnd(builder, cond_entry);
|
||||
LLVMValueRef cond_br = LLVMBuildCondBr(builder, cond_param, cond_true, cond_false);
|
||||
LLVMPositionBuilderAtEnd(builder, cond_entry);
|
||||
LLVMValueRef cond_br =
|
||||
LLVMBuildCondBr(builder, cond_param, cond_true, cond_false);
|
||||
|
||||
LLVMPositionBuilderAtEnd(builder, cond_true);
|
||||
LLVMBuildRet(builder, LLVMConstInt(i32, 1, 0));
|
||||
LLVMPositionBuilderAtEnd(builder, cond_true);
|
||||
LLVMBuildRet(builder, LLVMConstInt(i32, 1, 0));
|
||||
|
||||
LLVMPositionBuilderAtEnd(builder, cond_false);
|
||||
LLVMBuildRet(builder, LLVMConstInt(i32, 0, 0));
|
||||
LLVMPositionBuilderAtEnd(builder, cond_false);
|
||||
LLVMBuildRet(builder, LLVMConstInt(i32, 0, 0));
|
||||
|
||||
// ==========================================
|
||||
// Function 5: switch statement
|
||||
// ==========================================
|
||||
LLVMTypeRef switch_params[] = {i32};
|
||||
LLVMTypeRef switch_func_ty = LLVMFunctionType(i32, switch_params, 1, 0);
|
||||
LLVMValueRef switch_func = LLVMAddFunction(mod, "switch_example", switch_func_ty);
|
||||
LLVMValueRef switch_param = LLVMGetParam(switch_func, 0);
|
||||
LLVMSetValueName2(switch_param, "val", 3);
|
||||
// ==========================================
|
||||
// Function 5: switch statement
|
||||
// ==========================================
|
||||
LLVMTypeRef switch_params[] = {i32};
|
||||
LLVMTypeRef switch_func_ty = LLVMFunctionType(i32, switch_params, 1, 0);
|
||||
LLVMValueRef switch_func =
|
||||
LLVMAddFunction(mod, "switch_example", switch_func_ty);
|
||||
LLVMValueRef switch_param = LLVMGetParam(switch_func, 0);
|
||||
LLVMSetValueName2(switch_param, "val", 3);
|
||||
|
||||
LLVMBasicBlockRef switch_entry = LLVMAppendBasicBlockInContext(ctx, switch_func, "entry");
|
||||
LLVMBasicBlockRef case_0 = LLVMAppendBasicBlockInContext(ctx, switch_func, "case_0");
|
||||
LLVMBasicBlockRef case_1 = LLVMAppendBasicBlockInContext(ctx, switch_func, "case_1");
|
||||
LLVMBasicBlockRef case_2 = LLVMAppendBasicBlockInContext(ctx, switch_func, "case_2");
|
||||
LLVMBasicBlockRef default_case = LLVMAppendBasicBlockInContext(ctx, switch_func, "default");
|
||||
LLVMBasicBlockRef switch_entry =
|
||||
LLVMAppendBasicBlockInContext(ctx, switch_func, "entry");
|
||||
LLVMBasicBlockRef case_0 =
|
||||
LLVMAppendBasicBlockInContext(ctx, switch_func, "case_0");
|
||||
LLVMBasicBlockRef case_1 =
|
||||
LLVMAppendBasicBlockInContext(ctx, switch_func, "case_1");
|
||||
LLVMBasicBlockRef case_2 =
|
||||
LLVMAppendBasicBlockInContext(ctx, switch_func, "case_2");
|
||||
LLVMBasicBlockRef default_case =
|
||||
LLVMAppendBasicBlockInContext(ctx, switch_func, "default");
|
||||
|
||||
LLVMPositionBuilderAtEnd(builder, switch_entry);
|
||||
LLVMValueRef switch_inst = LLVMBuildSwitch(builder, switch_param, default_case, 3);
|
||||
LLVMAddCase(switch_inst, LLVMConstInt(i32, 0, 0), case_0);
|
||||
LLVMAddCase(switch_inst, LLVMConstInt(i32, 1, 0), case_1);
|
||||
LLVMAddCase(switch_inst, LLVMConstInt(i32, 2, 0), case_2);
|
||||
LLVMPositionBuilderAtEnd(builder, switch_entry);
|
||||
LLVMValueRef switch_inst =
|
||||
LLVMBuildSwitch(builder, switch_param, default_case, 3);
|
||||
LLVMAddCase(switch_inst, LLVMConstInt(i32, 0, 0), case_0);
|
||||
LLVMAddCase(switch_inst, LLVMConstInt(i32, 1, 0), case_1);
|
||||
LLVMAddCase(switch_inst, LLVMConstInt(i32, 2, 0), case_2);
|
||||
|
||||
LLVMPositionBuilderAtEnd(builder, case_0);
|
||||
LLVMBuildRet(builder, LLVMConstInt(i32, 100, 0));
|
||||
LLVMPositionBuilderAtEnd(builder, case_0);
|
||||
LLVMBuildRet(builder, LLVMConstInt(i32, 100, 0));
|
||||
|
||||
LLVMPositionBuilderAtEnd(builder, case_1);
|
||||
LLVMBuildRet(builder, LLVMConstInt(i32, 200, 0));
|
||||
LLVMPositionBuilderAtEnd(builder, case_1);
|
||||
LLVMBuildRet(builder, LLVMConstInt(i32, 200, 0));
|
||||
|
||||
LLVMPositionBuilderAtEnd(builder, case_2);
|
||||
LLVMBuildRet(builder, LLVMConstInt(i32, 300, 0));
|
||||
LLVMPositionBuilderAtEnd(builder, case_2);
|
||||
LLVMBuildRet(builder, LLVMConstInt(i32, 300, 0));
|
||||
|
||||
LLVMPositionBuilderAtEnd(builder, default_case);
|
||||
LLVMBuildRet(builder, LLVMConstInt(i32, -1, 1));
|
||||
LLVMPositionBuilderAtEnd(builder, default_case);
|
||||
LLVMBuildRet(builder, LLVMConstInt(i32, -1, 1));
|
||||
|
||||
// ==========================================
|
||||
// Function 6: function call
|
||||
// ==========================================
|
||||
LLVMValueRef call_func = LLVMAddFunction(mod, "call_example", ret_func_ty);
|
||||
LLVMValueRef call_param = LLVMGetParam(call_func, 0);
|
||||
LLVMSetValueName2(call_param, "n", 1);
|
||||
// ==========================================
|
||||
// Function 6: function call
|
||||
// ==========================================
|
||||
LLVMValueRef call_func = LLVMAddFunction(mod, "call_example", ret_func_ty);
|
||||
LLVMValueRef call_param = LLVMGetParam(call_func, 0);
|
||||
LLVMSetValueName2(call_param, "n", 1);
|
||||
|
||||
LLVMBasicBlockRef call_entry = LLVMAppendBasicBlockInContext(ctx, call_func, "entry");
|
||||
LLVMPositionBuilderAtEnd(builder, call_entry);
|
||||
LLVMBasicBlockRef call_entry =
|
||||
LLVMAppendBasicBlockInContext(ctx, call_func, "entry");
|
||||
LLVMPositionBuilderAtEnd(builder, call_entry);
|
||||
|
||||
LLVMValueRef args[] = {call_param};
|
||||
LLVMValueRef call_result = LLVMBuildCall2(builder, ret_func_ty, ret_func, args, 1, "result");
|
||||
LLVMBuildRet(builder, call_result);
|
||||
LLVMValueRef args[] = {call_param};
|
||||
LLVMValueRef call_result =
|
||||
LLVMBuildCall2(builder, ret_func_ty, ret_func, args, 1, "result");
|
||||
LLVMBuildRet(builder, call_result);
|
||||
|
||||
// ==========================================
|
||||
// Function 7: unreachable
|
||||
// ==========================================
|
||||
LLVMValueRef unreach_func = LLVMAddFunction(mod, "unreachable_example", void_func_ty);
|
||||
LLVMBasicBlockRef unreach_entry = LLVMAppendBasicBlockInContext(ctx, unreach_func, "entry");
|
||||
LLVMPositionBuilderAtEnd(builder, unreach_entry);
|
||||
LLVMBuildUnreachable(builder);
|
||||
// ==========================================
|
||||
// Function 7: unreachable
|
||||
// ==========================================
|
||||
LLVMValueRef unreach_func =
|
||||
LLVMAddFunction(mod, "unreachable_example", void_func_ty);
|
||||
LLVMBasicBlockRef unreach_entry =
|
||||
LLVMAppendBasicBlockInContext(ctx, unreach_func, "entry");
|
||||
LLVMPositionBuilderAtEnd(builder, unreach_entry);
|
||||
LLVMBuildUnreachable(builder);
|
||||
|
||||
// Check insert block
|
||||
LLVMBasicBlockRef current_block = LLVMGetInsertBlock(builder);
|
||||
// Check insert block
|
||||
LLVMBasicBlockRef current_block = LLVMGetInsertBlock(builder);
|
||||
|
||||
LLVMDisposeBuilder(builder);
|
||||
LLVMDisposeBuilder(builder);
|
||||
|
||||
// Verify module
|
||||
char *error = nullptr;
|
||||
if (LLVMVerifyModule(mod, LLVMReturnStatusAction, &error)) {
|
||||
fprintf(stderr, "; Verification failed: %s\n", error);
|
||||
LLVMDisposeMessage(error);
|
||||
LLVMDisposeModule(mod);
|
||||
LLVMContextDispose(ctx);
|
||||
return 1;
|
||||
}
|
||||
// Verify module
|
||||
char *error = nullptr;
|
||||
if (LLVMVerifyModule(mod, LLVMReturnStatusAction, &error)) {
|
||||
fprintf(stderr, "; Verification failed: %s\n", error);
|
||||
LLVMDisposeMessage(error);
|
||||
|
||||
// Print diagnostic comments
|
||||
printf("; Test: test_builder_control_flow\n");
|
||||
printf(";\n");
|
||||
printf("; Control flow operations demonstrated:\n");
|
||||
printf("; ret void, ret value\n");
|
||||
printf("; br (unconditional)\n");
|
||||
printf("; br (conditional)\n");
|
||||
printf("; switch with 3 cases + default\n");
|
||||
printf("; call\n");
|
||||
printf("; unreachable\n");
|
||||
printf(";\n");
|
||||
printf("; Branch analysis:\n");
|
||||
printf("; unconditional br is conditional: %s\n", LLVMIsConditional(br_inst) ? "yes" : "no");
|
||||
printf("; conditional br is conditional: %s\n", LLVMIsConditional(cond_br) ? "yes" : "no");
|
||||
printf("; unconditional br num successors: %u\n", LLVMGetNumSuccessors(br_inst));
|
||||
printf("; conditional br num successors: %u\n", LLVMGetNumSuccessors(cond_br));
|
||||
printf(";\n");
|
||||
printf("; Current insert block: %s\n", LLVMGetBasicBlockName(current_block));
|
||||
printf("\n");
|
||||
|
||||
// Print module IR
|
||||
char *ir = LLVMPrintModuleToString(mod);
|
||||
printf("%s", ir);
|
||||
LLVMDisposeMessage(ir);
|
||||
|
||||
// Cleanup
|
||||
LLVMDisposeModule(mod);
|
||||
LLVMContextDispose(ctx);
|
||||
return 1;
|
||||
}
|
||||
LLVMDisposeMessage(error);
|
||||
|
||||
return 0;
|
||||
// Print diagnostic comments
|
||||
printf("; Test: test_builder_control_flow\n");
|
||||
printf(";\n");
|
||||
printf("; Control flow operations demonstrated:\n");
|
||||
printf("; ret void, ret value\n");
|
||||
printf("; br (unconditional)\n");
|
||||
printf("; br (conditional)\n");
|
||||
printf("; switch with 3 cases + default\n");
|
||||
printf("; call\n");
|
||||
printf("; unreachable\n");
|
||||
printf(";\n");
|
||||
printf("; Branch analysis:\n");
|
||||
printf("; unconditional br is conditional: %s\n",
|
||||
LLVMIsConditional(br_inst) ? "yes" : "no");
|
||||
printf("; conditional br is conditional: %s\n",
|
||||
LLVMIsConditional(cond_br) ? "yes" : "no");
|
||||
printf("; unconditional br num successors: %u\n",
|
||||
LLVMGetNumSuccessors(br_inst));
|
||||
printf("; conditional br num successors: %u\n",
|
||||
LLVMGetNumSuccessors(cond_br));
|
||||
printf(";\n");
|
||||
printf("; Current insert block: %s\n", LLVMGetBasicBlockName(current_block));
|
||||
printf("\n");
|
||||
|
||||
// Print module IR
|
||||
char *ir = LLVMPrintModuleToString(mod);
|
||||
printf("%s", ir);
|
||||
LLVMDisposeMessage(ir);
|
||||
|
||||
// Cleanup
|
||||
LLVMDisposeModule(mod);
|
||||
LLVMContextDispose(ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+115
-98
@@ -10,130 +10,147 @@
|
||||
* - LLVMGetAlignment(), LLVMSetAlignment()
|
||||
*/
|
||||
|
||||
#include <llvm-c/Core.h>
|
||||
#include <llvm-c/Analysis.h>
|
||||
#include <cstdio>
|
||||
#include <llvm-c/Analysis.h>
|
||||
#include <llvm-c/Core.h>
|
||||
|
||||
int main() {
|
||||
LLVMContextRef ctx = LLVMContextCreate();
|
||||
LLVMModuleRef mod = LLVMModuleCreateWithNameInContext("test_builder_memory", ctx);
|
||||
LLVMContextRef ctx = LLVMContextCreate();
|
||||
LLVMModuleRef mod =
|
||||
LLVMModuleCreateWithNameInContext("test_builder_memory", ctx);
|
||||
|
||||
LLVMTypeRef i32 = LLVMInt32TypeInContext(ctx);
|
||||
LLVMTypeRef i64 = LLVMInt64TypeInContext(ctx);
|
||||
LLVMTypeRef ptr = LLVMPointerTypeInContext(ctx, 0);
|
||||
LLVMTypeRef void_ty = LLVMVoidTypeInContext(ctx);
|
||||
LLVMTypeRef i32 = LLVMInt32TypeInContext(ctx);
|
||||
LLVMTypeRef i64 = LLVMInt64TypeInContext(ctx);
|
||||
LLVMTypeRef ptr = LLVMPointerTypeInContext(ctx, 0);
|
||||
LLVMTypeRef void_ty = LLVMVoidTypeInContext(ctx);
|
||||
|
||||
// Array type for array alloca test
|
||||
LLVMTypeRef arr_ty = LLVMArrayType2(i32, 10);
|
||||
// Array type for array alloca test
|
||||
LLVMTypeRef arr_ty = LLVMArrayType2(i32, 10);
|
||||
|
||||
// Struct type for struct GEP test
|
||||
LLVMTypeRef struct_elems[] = {i32, i64, i32};
|
||||
LLVMTypeRef struct_ty = LLVMStructTypeInContext(ctx, struct_elems, 3, 0);
|
||||
// Struct type for struct GEP test
|
||||
LLVMTypeRef struct_elems[] = {i32, i64, i32};
|
||||
LLVMTypeRef struct_ty = LLVMStructTypeInContext(ctx, struct_elems, 3, 0);
|
||||
|
||||
// Function: void memory_ops()
|
||||
LLVMTypeRef func_ty = LLVMFunctionType(void_ty, nullptr, 0, 0);
|
||||
LLVMValueRef func = LLVMAddFunction(mod, "memory_ops", func_ty);
|
||||
// Function: void memory_ops()
|
||||
LLVMTypeRef func_ty = LLVMFunctionType(void_ty, nullptr, 0, 0);
|
||||
LLVMValueRef func = LLVMAddFunction(mod, "memory_ops", func_ty);
|
||||
|
||||
LLVMBasicBlockRef entry = LLVMAppendBasicBlockInContext(ctx, func, "entry");
|
||||
LLVMBuilderRef builder = LLVMCreateBuilderInContext(ctx);
|
||||
LLVMPositionBuilderAtEnd(builder, entry);
|
||||
LLVMBasicBlockRef entry = LLVMAppendBasicBlockInContext(ctx, func, "entry");
|
||||
LLVMBuilderRef builder = LLVMCreateBuilderInContext(ctx);
|
||||
LLVMPositionBuilderAtEnd(builder, entry);
|
||||
|
||||
// Basic alloca
|
||||
LLVMValueRef alloca_i32 = LLVMBuildAlloca(builder, i32, "local_i32");
|
||||
// Basic alloca
|
||||
LLVMValueRef alloca_i32 = LLVMBuildAlloca(builder, i32, "local_i32");
|
||||
|
||||
// Alloca with explicit alignment
|
||||
LLVMValueRef alloca_aligned = LLVMBuildAlloca(builder, i64, "local_aligned");
|
||||
LLVMSetAlignment(alloca_aligned, 16);
|
||||
// Alloca with explicit alignment
|
||||
LLVMValueRef alloca_aligned = LLVMBuildAlloca(builder, i64, "local_aligned");
|
||||
LLVMSetAlignment(alloca_aligned, 16);
|
||||
|
||||
// Array alloca (dynamic size)
|
||||
LLVMValueRef array_size = LLVMConstInt(i32, 5, 0);
|
||||
LLVMValueRef array_alloca = LLVMBuildArrayAlloca(builder, i32, array_size, "dynamic_array");
|
||||
// Array alloca (dynamic size)
|
||||
LLVMValueRef array_size = LLVMConstInt(i32, 5, 0);
|
||||
LLVMValueRef array_alloca =
|
||||
LLVMBuildArrayAlloca(builder, i32, array_size, "dynamic_array");
|
||||
|
||||
// Static array alloca
|
||||
LLVMValueRef static_array = LLVMBuildAlloca(builder, arr_ty, "static_array");
|
||||
// Static array alloca
|
||||
LLVMValueRef static_array = LLVMBuildAlloca(builder, arr_ty, "static_array");
|
||||
|
||||
// Struct alloca
|
||||
LLVMValueRef struct_alloca = LLVMBuildAlloca(builder, struct_ty, "local_struct");
|
||||
// Struct alloca
|
||||
LLVMValueRef struct_alloca =
|
||||
LLVMBuildAlloca(builder, struct_ty, "local_struct");
|
||||
|
||||
// Store and load
|
||||
LLVMValueRef val = LLVMConstInt(i32, 42, 0);
|
||||
LLVMValueRef store = LLVMBuildStore(builder, val, alloca_i32);
|
||||
LLVMValueRef load = LLVMBuildLoad2(builder, i32, alloca_i32, "loaded");
|
||||
// Store and load
|
||||
LLVMValueRef val = LLVMConstInt(i32, 42, 0);
|
||||
LLVMValueRef store = LLVMBuildStore(builder, val, alloca_i32);
|
||||
LLVMValueRef load = LLVMBuildLoad2(builder, i32, alloca_i32, "loaded");
|
||||
|
||||
// Volatile load/store
|
||||
LLVMValueRef volatile_store = LLVMBuildStore(builder, val, alloca_i32);
|
||||
LLVMSetVolatile(volatile_store, 1);
|
||||
LLVMValueRef volatile_load = LLVMBuildLoad2(builder, i32, alloca_i32, "volatile_loaded");
|
||||
LLVMSetVolatile(volatile_load, 1);
|
||||
// Volatile load/store
|
||||
LLVMValueRef volatile_store = LLVMBuildStore(builder, val, alloca_i32);
|
||||
LLVMSetVolatile(volatile_store, 1);
|
||||
LLVMValueRef volatile_load =
|
||||
LLVMBuildLoad2(builder, i32, alloca_i32, "volatile_loaded");
|
||||
LLVMSetVolatile(volatile_load, 1);
|
||||
|
||||
// Load with alignment
|
||||
LLVMValueRef aligned_load = LLVMBuildLoad2(builder, i64, alloca_aligned, "aligned_loaded");
|
||||
LLVMSetAlignment(aligned_load, 16);
|
||||
// Load with alignment
|
||||
LLVMValueRef aligned_load =
|
||||
LLVMBuildLoad2(builder, i64, alloca_aligned, "aligned_loaded");
|
||||
LLVMSetAlignment(aligned_load, 16);
|
||||
|
||||
// GEP into array (static)
|
||||
LLVMValueRef indices[] = {LLVMConstInt(i64, 0, 0), LLVMConstInt(i64, 3, 0)};
|
||||
LLVMValueRef gep = LLVMBuildGEP2(builder, arr_ty, static_array, indices, 2, "arr_elem");
|
||||
// GEP into array (static)
|
||||
LLVMValueRef indices[] = {LLVMConstInt(i64, 0, 0), LLVMConstInt(i64, 3, 0)};
|
||||
LLVMValueRef gep =
|
||||
LLVMBuildGEP2(builder, arr_ty, static_array, indices, 2, "arr_elem");
|
||||
|
||||
// Inbounds GEP
|
||||
LLVMValueRef inbounds_gep = LLVMBuildInBoundsGEP2(builder, arr_ty, static_array, indices, 2, "arr_elem_inbounds");
|
||||
// Inbounds GEP
|
||||
LLVMValueRef inbounds_gep = LLVMBuildInBoundsGEP2(
|
||||
builder, arr_ty, static_array, indices, 2, "arr_elem_inbounds");
|
||||
|
||||
// Struct GEP
|
||||
LLVMValueRef struct_gep_0 = LLVMBuildStructGEP2(builder, struct_ty, struct_alloca, 0, "field_0");
|
||||
LLVMValueRef struct_gep_1 = LLVMBuildStructGEP2(builder, struct_ty, struct_alloca, 1, "field_1");
|
||||
LLVMValueRef struct_gep_2 = LLVMBuildStructGEP2(builder, struct_ty, struct_alloca, 2, "field_2");
|
||||
// Struct GEP
|
||||
LLVMValueRef struct_gep_0 =
|
||||
LLVMBuildStructGEP2(builder, struct_ty, struct_alloca, 0, "field_0");
|
||||
LLVMValueRef struct_gep_1 =
|
||||
LLVMBuildStructGEP2(builder, struct_ty, struct_alloca, 1, "field_1");
|
||||
LLVMValueRef struct_gep_2 =
|
||||
LLVMBuildStructGEP2(builder, struct_ty, struct_alloca, 2, "field_2");
|
||||
|
||||
// Store to struct fields
|
||||
LLVMBuildStore(builder, LLVMConstInt(i32, 100, 0), struct_gep_0);
|
||||
LLVMBuildStore(builder, LLVMConstInt(i64, 200, 0), struct_gep_1);
|
||||
LLVMBuildStore(builder, LLVMConstInt(i32, 300, 0), struct_gep_2);
|
||||
// Store to struct fields
|
||||
LLVMBuildStore(builder, LLVMConstInt(i32, 100, 0), struct_gep_0);
|
||||
LLVMBuildStore(builder, LLVMConstInt(i64, 200, 0), struct_gep_1);
|
||||
LLVMBuildStore(builder, LLVMConstInt(i32, 300, 0), struct_gep_2);
|
||||
|
||||
// Load from struct fields
|
||||
LLVMValueRef field_0_val = LLVMBuildLoad2(builder, i32, struct_gep_0, "field_0_val");
|
||||
LLVMValueRef field_1_val = LLVMBuildLoad2(builder, i64, struct_gep_1, "field_1_val");
|
||||
// Load from struct fields
|
||||
LLVMValueRef field_0_val =
|
||||
LLVMBuildLoad2(builder, i32, struct_gep_0, "field_0_val");
|
||||
LLVMValueRef field_1_val =
|
||||
LLVMBuildLoad2(builder, i64, struct_gep_1, "field_1_val");
|
||||
|
||||
LLVMBuildRetVoid(builder);
|
||||
LLVMBuildRetVoid(builder);
|
||||
|
||||
LLVMDisposeBuilder(builder);
|
||||
LLVMDisposeBuilder(builder);
|
||||
|
||||
// Verify module
|
||||
char *error = nullptr;
|
||||
if (LLVMVerifyModule(mod, LLVMReturnStatusAction, &error)) {
|
||||
fprintf(stderr, "; Verification failed: %s\n", error);
|
||||
LLVMDisposeMessage(error);
|
||||
LLVMDisposeModule(mod);
|
||||
LLVMContextDispose(ctx);
|
||||
return 1;
|
||||
}
|
||||
// Verify module
|
||||
char *error = nullptr;
|
||||
if (LLVMVerifyModule(mod, LLVMReturnStatusAction, &error)) {
|
||||
fprintf(stderr, "; Verification failed: %s\n", error);
|
||||
LLVMDisposeMessage(error);
|
||||
|
||||
// Print diagnostic comments
|
||||
printf("; Test: test_builder_memory\n");
|
||||
printf(";\n");
|
||||
printf("; Memory operations demonstrated:\n");
|
||||
printf("; alloca (i32, i64 with alignment, dynamic array, static array, struct)\n");
|
||||
printf("; store (basic, volatile)\n");
|
||||
printf("; load (basic, volatile, aligned)\n");
|
||||
printf("; GEP (array indexing, inbounds)\n");
|
||||
printf("; struct GEP (field access)\n");
|
||||
printf(";\n");
|
||||
printf("; Alignment checks:\n");
|
||||
printf("; alloca_aligned alignment: %u\n", LLVMGetAlignment(alloca_aligned));
|
||||
printf("; aligned_load alignment: %u\n", LLVMGetAlignment(aligned_load));
|
||||
printf(";\n");
|
||||
printf("; Volatile checks:\n");
|
||||
printf("; volatile_store is volatile: %s\n", LLVMGetVolatile(volatile_store) ? "yes" : "no");
|
||||
printf("; volatile_load is volatile: %s\n", LLVMGetVolatile(volatile_load) ? "yes" : "no");
|
||||
printf("; regular store is volatile: %s\n", LLVMGetVolatile(store) ? "yes" : "no");
|
||||
printf("\n");
|
||||
|
||||
// Print module IR
|
||||
char *ir = LLVMPrintModuleToString(mod);
|
||||
printf("%s", ir);
|
||||
LLVMDisposeMessage(ir);
|
||||
|
||||
// Cleanup
|
||||
LLVMDisposeModule(mod);
|
||||
LLVMContextDispose(ctx);
|
||||
return 1;
|
||||
}
|
||||
LLVMDisposeMessage(error);
|
||||
|
||||
return 0;
|
||||
// Print diagnostic comments
|
||||
printf("; Test: test_builder_memory\n");
|
||||
printf(";\n");
|
||||
printf("; Memory operations demonstrated:\n");
|
||||
printf("; alloca (i32, i64 with alignment, dynamic array, static array, "
|
||||
"struct)\n");
|
||||
printf("; store (basic, volatile)\n");
|
||||
printf("; load (basic, volatile, aligned)\n");
|
||||
printf("; GEP (array indexing, inbounds)\n");
|
||||
printf("; struct GEP (field access)\n");
|
||||
printf(";\n");
|
||||
printf("; Alignment checks:\n");
|
||||
printf("; alloca_aligned alignment: %u\n",
|
||||
LLVMGetAlignment(alloca_aligned));
|
||||
printf("; aligned_load alignment: %u\n", LLVMGetAlignment(aligned_load));
|
||||
printf(";\n");
|
||||
printf("; Volatile checks:\n");
|
||||
printf("; volatile_store is volatile: %s\n",
|
||||
LLVMGetVolatile(volatile_store) ? "yes" : "no");
|
||||
printf("; volatile_load is volatile: %s\n",
|
||||
LLVMGetVolatile(volatile_load) ? "yes" : "no");
|
||||
printf("; regular store is volatile: %s\n",
|
||||
LLVMGetVolatile(store) ? "yes" : "no");
|
||||
printf("\n");
|
||||
|
||||
// Print module IR
|
||||
char *ir = LLVMPrintModuleToString(mod);
|
||||
printf("%s", ir);
|
||||
LLVMDisposeMessage(ir);
|
||||
|
||||
// Cleanup
|
||||
LLVMDisposeModule(mod);
|
||||
LLVMContextDispose(ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+177
-177
@@ -9,220 +9,220 @@
|
||||
* - LLVMGetUndef(), LLVMGetPoison()
|
||||
* - LLVMConstPointerNull()
|
||||
* - LLVMConstStringInContext2()
|
||||
* - LLVMConstArray2(), LLVMConstStructInContext(), LLVMConstNamedStruct(), LLVMConstVector()
|
||||
* - LLVMConstArray2(), LLVMConstStructInContext(), LLVMConstNamedStruct(),
|
||||
* LLVMConstVector()
|
||||
* - LLVMConstIntGetZExtValue(), LLVMConstIntGetSExtValue()
|
||||
* - LLVMIsConstant(), LLVMIsNull(), LLVMIsUndef(), LLVMIsPoison()
|
||||
*/
|
||||
|
||||
#include <llvm-c/Core.h>
|
||||
#include <llvm-c/Analysis.h>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <llvm-c/Analysis.h>
|
||||
#include <llvm-c/Core.h>
|
||||
|
||||
int main() {
|
||||
LLVMContextRef ctx = LLVMContextCreate();
|
||||
LLVMModuleRef mod = LLVMModuleCreateWithNameInContext("test_constants", ctx);
|
||||
LLVMContextRef ctx = LLVMContextCreate();
|
||||
LLVMModuleRef mod = LLVMModuleCreateWithNameInContext("test_constants", ctx);
|
||||
|
||||
LLVMTypeRef i1 = LLVMInt1TypeInContext(ctx);
|
||||
LLVMTypeRef i8 = LLVMInt8TypeInContext(ctx);
|
||||
LLVMTypeRef i32 = LLVMInt32TypeInContext(ctx);
|
||||
LLVMTypeRef i64 = LLVMInt64TypeInContext(ctx);
|
||||
LLVMTypeRef i128 = LLVMInt128TypeInContext(ctx);
|
||||
LLVMTypeRef f32 = LLVMFloatTypeInContext(ctx);
|
||||
LLVMTypeRef f64 = LLVMDoubleTypeInContext(ctx);
|
||||
LLVMTypeRef ptr = LLVMPointerTypeInContext(ctx, 0);
|
||||
LLVMTypeRef i1 = LLVMInt1TypeInContext(ctx);
|
||||
LLVMTypeRef i8 = LLVMInt8TypeInContext(ctx);
|
||||
LLVMTypeRef i32 = LLVMInt32TypeInContext(ctx);
|
||||
LLVMTypeRef i64 = LLVMInt64TypeInContext(ctx);
|
||||
LLVMTypeRef i128 = LLVMInt128TypeInContext(ctx);
|
||||
LLVMTypeRef f32 = LLVMFloatTypeInContext(ctx);
|
||||
LLVMTypeRef f64 = LLVMDoubleTypeInContext(ctx);
|
||||
LLVMTypeRef ptr = LLVMPointerTypeInContext(ctx, 0);
|
||||
|
||||
// ==========================================
|
||||
// Integer constants
|
||||
// ==========================================
|
||||
LLVMValueRef const_0 = LLVMConstInt(i32, 0, 0);
|
||||
LLVMValueRef const_42 = LLVMConstInt(i32, 42, 0);
|
||||
LLVMValueRef const_neg1 = LLVMConstInt(i32, -1, 1); // Sign extend
|
||||
LLVMValueRef const_max_u32 = LLVMConstInt(i32, 0xFFFFFFFF, 0);
|
||||
LLVMValueRef const_i64 = LLVMConstInt(i64, 0x123456789ABCDEF0ULL, 0);
|
||||
// ==========================================
|
||||
// Integer constants
|
||||
// ==========================================
|
||||
LLVMValueRef const_0 = LLVMConstInt(i32, 0, 0);
|
||||
LLVMValueRef const_42 = LLVMConstInt(i32, 42, 0);
|
||||
LLVMValueRef const_neg1 = LLVMConstInt(i32, -1, 1); // Sign extend
|
||||
LLVMValueRef const_max_u32 = LLVMConstInt(i32, 0xFFFFFFFF, 0);
|
||||
LLVMValueRef const_i64 = LLVMConstInt(i64, 0x123456789ABCDEF0ULL, 0);
|
||||
|
||||
// Arbitrary precision integer (128-bit)
|
||||
uint64_t words[] = {0xFFFFFFFFFFFFFFFFULL, 0x0000000000000001ULL};
|
||||
LLVMValueRef const_i128 = LLVMConstIntOfArbitraryPrecision(i128, 2, words);
|
||||
// Arbitrary precision integer (128-bit)
|
||||
uint64_t words[] = {0xFFFFFFFFFFFFFFFFULL, 0x0000000000000001ULL};
|
||||
LLVMValueRef const_i128 = LLVMConstIntOfArbitraryPrecision(i128, 2, words);
|
||||
|
||||
// ==========================================
|
||||
// Floating point constants
|
||||
// ==========================================
|
||||
LLVMValueRef const_pi = LLVMConstReal(f64, 3.14159265358979323846);
|
||||
LLVMValueRef const_e = LLVMConstReal(f64, 2.71828182845904523536);
|
||||
LLVMValueRef const_f32 = LLVMConstReal(f32, 1.5f);
|
||||
// ==========================================
|
||||
// Floating point constants
|
||||
// ==========================================
|
||||
LLVMValueRef const_pi = LLVMConstReal(f64, 3.14159265358979323846);
|
||||
LLVMValueRef const_e = LLVMConstReal(f64, 2.71828182845904523536);
|
||||
LLVMValueRef const_f32 = LLVMConstReal(f32, 1.5f);
|
||||
|
||||
// From string
|
||||
LLVMValueRef const_from_str = LLVMConstRealOfString(f64, "1.234567890123456789");
|
||||
// From string
|
||||
LLVMValueRef const_from_str =
|
||||
LLVMConstRealOfString(f64, "1.234567890123456789");
|
||||
|
||||
// ==========================================
|
||||
// Special values
|
||||
// ==========================================
|
||||
LLVMValueRef null_i32 = LLVMConstNull(i32);
|
||||
LLVMValueRef null_ptr = LLVMConstPointerNull(ptr);
|
||||
LLVMValueRef all_ones = LLVMConstAllOnes(i32);
|
||||
LLVMValueRef undef_i32 = LLVMGetUndef(i32);
|
||||
LLVMValueRef poison_i32 = LLVMGetPoison(i32);
|
||||
// ==========================================
|
||||
// Special values
|
||||
// ==========================================
|
||||
LLVMValueRef null_i32 = LLVMConstNull(i32);
|
||||
LLVMValueRef null_ptr = LLVMConstPointerNull(ptr);
|
||||
LLVMValueRef all_ones = LLVMConstAllOnes(i32);
|
||||
LLVMValueRef undef_i32 = LLVMGetUndef(i32);
|
||||
LLVMValueRef poison_i32 = LLVMGetPoison(i32);
|
||||
|
||||
// ==========================================
|
||||
// String constant
|
||||
// ==========================================
|
||||
const char *str = "Hello, LLVM!";
|
||||
LLVMValueRef const_string = LLVMConstStringInContext2(ctx, str, strlen(str), 0); // null terminated
|
||||
LLVMValueRef const_string_no_null = LLVMConstStringInContext2(ctx, str, strlen(str), 1); // not null terminated
|
||||
// ==========================================
|
||||
// String constant
|
||||
// ==========================================
|
||||
const char *str = "Hello, LLVM!";
|
||||
LLVMValueRef const_string =
|
||||
LLVMConstStringInContext2(ctx, str, strlen(str), 0); // null terminated
|
||||
LLVMValueRef const_string_no_null = LLVMConstStringInContext2(
|
||||
ctx, str, strlen(str), 1); // not null terminated
|
||||
|
||||
// ==========================================
|
||||
// Array constant
|
||||
// ==========================================
|
||||
LLVMValueRef arr_elems[] = {
|
||||
LLVMConstInt(i32, 1, 0),
|
||||
LLVMConstInt(i32, 2, 0),
|
||||
LLVMConstInt(i32, 3, 0),
|
||||
LLVMConstInt(i32, 4, 0),
|
||||
LLVMConstInt(i32, 5, 0)
|
||||
};
|
||||
LLVMValueRef const_array = LLVMConstArray2(i32, arr_elems, 5);
|
||||
// ==========================================
|
||||
// Array constant
|
||||
// ==========================================
|
||||
LLVMValueRef arr_elems[] = {LLVMConstInt(i32, 1, 0), LLVMConstInt(i32, 2, 0),
|
||||
LLVMConstInt(i32, 3, 0), LLVMConstInt(i32, 4, 0),
|
||||
LLVMConstInt(i32, 5, 0)};
|
||||
LLVMValueRef const_array = LLVMConstArray2(i32, arr_elems, 5);
|
||||
|
||||
// ==========================================
|
||||
// Anonymous struct constant
|
||||
// ==========================================
|
||||
LLVMValueRef struct_elems[] = {
|
||||
LLVMConstInt(i32, 100, 0),
|
||||
LLVMConstReal(f64, 3.14),
|
||||
LLVMConstInt(i64, 999, 0)
|
||||
};
|
||||
LLVMValueRef const_struct = LLVMConstStructInContext(ctx, struct_elems, 3, 0);
|
||||
LLVMValueRef const_packed_struct = LLVMConstStructInContext(ctx, struct_elems, 3, 1);
|
||||
// ==========================================
|
||||
// Anonymous struct constant
|
||||
// ==========================================
|
||||
LLVMValueRef struct_elems[] = {LLVMConstInt(i32, 100, 0),
|
||||
LLVMConstReal(f64, 3.14),
|
||||
LLVMConstInt(i64, 999, 0)};
|
||||
LLVMValueRef const_struct = LLVMConstStructInContext(ctx, struct_elems, 3, 0);
|
||||
LLVMValueRef const_packed_struct =
|
||||
LLVMConstStructInContext(ctx, struct_elems, 3, 1);
|
||||
|
||||
// ==========================================
|
||||
// Named struct constant
|
||||
// ==========================================
|
||||
LLVMTypeRef named_struct_ty = LLVMStructCreateNamed(ctx, "Point");
|
||||
LLVMTypeRef point_elems[] = {i32, i32};
|
||||
LLVMStructSetBody(named_struct_ty, point_elems, 2, 0);
|
||||
// ==========================================
|
||||
// Named struct constant
|
||||
// ==========================================
|
||||
LLVMTypeRef named_struct_ty = LLVMStructCreateNamed(ctx, "Point");
|
||||
LLVMTypeRef point_elems[] = {i32, i32};
|
||||
LLVMStructSetBody(named_struct_ty, point_elems, 2, 0);
|
||||
|
||||
LLVMValueRef point_vals[] = {
|
||||
LLVMConstInt(i32, 10, 0),
|
||||
LLVMConstInt(i32, 20, 0)
|
||||
};
|
||||
LLVMValueRef const_named_struct = LLVMConstNamedStruct(named_struct_ty, point_vals, 2);
|
||||
LLVMValueRef point_vals[] = {LLVMConstInt(i32, 10, 0),
|
||||
LLVMConstInt(i32, 20, 0)};
|
||||
LLVMValueRef const_named_struct =
|
||||
LLVMConstNamedStruct(named_struct_ty, point_vals, 2);
|
||||
|
||||
// ==========================================
|
||||
// Vector constant
|
||||
// ==========================================
|
||||
LLVMValueRef vec_elems[] = {
|
||||
LLVMConstInt(i32, 1, 0),
|
||||
LLVMConstInt(i32, 2, 0),
|
||||
LLVMConstInt(i32, 3, 0),
|
||||
LLVMConstInt(i32, 4, 0)
|
||||
};
|
||||
LLVMValueRef const_vector = LLVMConstVector(vec_elems, 4);
|
||||
// ==========================================
|
||||
// Vector constant
|
||||
// ==========================================
|
||||
LLVMValueRef vec_elems[] = {LLVMConstInt(i32, 1, 0), LLVMConstInt(i32, 2, 0),
|
||||
LLVMConstInt(i32, 3, 0), LLVMConstInt(i32, 4, 0)};
|
||||
LLVMValueRef const_vector = LLVMConstVector(vec_elems, 4);
|
||||
|
||||
// ==========================================
|
||||
// Add globals to expose constants in output
|
||||
// ==========================================
|
||||
LLVMValueRef g;
|
||||
// ==========================================
|
||||
// Add globals to expose constants in output
|
||||
// ==========================================
|
||||
LLVMValueRef g;
|
||||
|
||||
g = LLVMAddGlobal(mod, i32, "const_42");
|
||||
LLVMSetInitializer(g, const_42);
|
||||
LLVMSetGlobalConstant(g, 1);
|
||||
g = LLVMAddGlobal(mod, i32, "const_42");
|
||||
LLVMSetInitializer(g, const_42);
|
||||
LLVMSetGlobalConstant(g, 1);
|
||||
|
||||
g = LLVMAddGlobal(mod, i32, "const_neg1");
|
||||
LLVMSetInitializer(g, const_neg1);
|
||||
LLVMSetGlobalConstant(g, 1);
|
||||
g = LLVMAddGlobal(mod, i32, "const_neg1");
|
||||
LLVMSetInitializer(g, const_neg1);
|
||||
LLVMSetGlobalConstant(g, 1);
|
||||
|
||||
g = LLVMAddGlobal(mod, i64, "const_i64");
|
||||
LLVMSetInitializer(g, const_i64);
|
||||
LLVMSetGlobalConstant(g, 1);
|
||||
g = LLVMAddGlobal(mod, i64, "const_i64");
|
||||
LLVMSetInitializer(g, const_i64);
|
||||
LLVMSetGlobalConstant(g, 1);
|
||||
|
||||
g = LLVMAddGlobal(mod, i128, "const_i128");
|
||||
LLVMSetInitializer(g, const_i128);
|
||||
LLVMSetGlobalConstant(g, 1);
|
||||
g = LLVMAddGlobal(mod, i128, "const_i128");
|
||||
LLVMSetInitializer(g, const_i128);
|
||||
LLVMSetGlobalConstant(g, 1);
|
||||
|
||||
g = LLVMAddGlobal(mod, f64, "const_pi");
|
||||
LLVMSetInitializer(g, const_pi);
|
||||
LLVMSetGlobalConstant(g, 1);
|
||||
g = LLVMAddGlobal(mod, f64, "const_pi");
|
||||
LLVMSetInitializer(g, const_pi);
|
||||
LLVMSetGlobalConstant(g, 1);
|
||||
|
||||
g = LLVMAddGlobal(mod, i32, "all_ones");
|
||||
LLVMSetInitializer(g, all_ones);
|
||||
LLVMSetGlobalConstant(g, 1);
|
||||
g = LLVMAddGlobal(mod, i32, "all_ones");
|
||||
LLVMSetInitializer(g, all_ones);
|
||||
LLVMSetGlobalConstant(g, 1);
|
||||
|
||||
g = LLVMAddGlobal(mod, i32, "undef_val");
|
||||
LLVMSetInitializer(g, undef_i32);
|
||||
g = LLVMAddGlobal(mod, i32, "undef_val");
|
||||
LLVMSetInitializer(g, undef_i32);
|
||||
|
||||
g = LLVMAddGlobal(mod, i32, "poison_val");
|
||||
LLVMSetInitializer(g, poison_i32);
|
||||
g = LLVMAddGlobal(mod, i32, "poison_val");
|
||||
LLVMSetInitializer(g, poison_i32);
|
||||
|
||||
// Get array type for const_string
|
||||
LLVMTypeRef str_arr_ty = LLVMArrayType2(i8, strlen(str) + 1);
|
||||
g = LLVMAddGlobal(mod, str_arr_ty, "hello_string");
|
||||
LLVMSetInitializer(g, const_string);
|
||||
LLVMSetGlobalConstant(g, 1);
|
||||
// Get array type for const_string
|
||||
LLVMTypeRef str_arr_ty = LLVMArrayType2(i8, strlen(str) + 1);
|
||||
g = LLVMAddGlobal(mod, str_arr_ty, "hello_string");
|
||||
LLVMSetInitializer(g, const_string);
|
||||
LLVMSetGlobalConstant(g, 1);
|
||||
|
||||
LLVMTypeRef arr_ty = LLVMArrayType2(i32, 5);
|
||||
g = LLVMAddGlobal(mod, arr_ty, "const_array");
|
||||
LLVMSetInitializer(g, const_array);
|
||||
LLVMSetGlobalConstant(g, 1);
|
||||
LLVMTypeRef arr_ty = LLVMArrayType2(i32, 5);
|
||||
g = LLVMAddGlobal(mod, arr_ty, "const_array");
|
||||
LLVMSetInitializer(g, const_array);
|
||||
LLVMSetGlobalConstant(g, 1);
|
||||
|
||||
// Struct types for globals
|
||||
LLVMTypeRef anon_struct_elems[] = {i32, f64, i64};
|
||||
LLVMTypeRef anon_struct_ty = LLVMStructTypeInContext(ctx, anon_struct_elems, 3, 0);
|
||||
g = LLVMAddGlobal(mod, anon_struct_ty, "const_struct");
|
||||
LLVMSetInitializer(g, const_struct);
|
||||
LLVMSetGlobalConstant(g, 1);
|
||||
// Struct types for globals
|
||||
LLVMTypeRef anon_struct_elems[] = {i32, f64, i64};
|
||||
LLVMTypeRef anon_struct_ty =
|
||||
LLVMStructTypeInContext(ctx, anon_struct_elems, 3, 0);
|
||||
g = LLVMAddGlobal(mod, anon_struct_ty, "const_struct");
|
||||
LLVMSetInitializer(g, const_struct);
|
||||
LLVMSetGlobalConstant(g, 1);
|
||||
|
||||
g = LLVMAddGlobal(mod, named_struct_ty, "const_point");
|
||||
LLVMSetInitializer(g, const_named_struct);
|
||||
LLVMSetGlobalConstant(g, 1);
|
||||
g = LLVMAddGlobal(mod, named_struct_ty, "const_point");
|
||||
LLVMSetInitializer(g, const_named_struct);
|
||||
LLVMSetGlobalConstant(g, 1);
|
||||
|
||||
LLVMTypeRef vec_ty = LLVMVectorType(i32, 4);
|
||||
g = LLVMAddGlobal(mod, vec_ty, "const_vector");
|
||||
LLVMSetInitializer(g, const_vector);
|
||||
LLVMSetGlobalConstant(g, 1);
|
||||
LLVMTypeRef vec_ty = LLVMVectorType(i32, 4);
|
||||
g = LLVMAddGlobal(mod, vec_ty, "const_vector");
|
||||
LLVMSetInitializer(g, const_vector);
|
||||
LLVMSetGlobalConstant(g, 1);
|
||||
|
||||
// Verify module
|
||||
char *error = nullptr;
|
||||
if (LLVMVerifyModule(mod, LLVMReturnStatusAction, &error)) {
|
||||
fprintf(stderr, "; Verification failed: %s\n", error);
|
||||
LLVMDisposeMessage(error);
|
||||
LLVMDisposeModule(mod);
|
||||
LLVMContextDispose(ctx);
|
||||
return 1;
|
||||
}
|
||||
// Verify module
|
||||
char *error = nullptr;
|
||||
if (LLVMVerifyModule(mod, LLVMReturnStatusAction, &error)) {
|
||||
fprintf(stderr, "; Verification failed: %s\n", error);
|
||||
LLVMDisposeMessage(error);
|
||||
|
||||
// Print diagnostic comments
|
||||
printf("; Test: test_constants\n");
|
||||
printf(";\n");
|
||||
printf("; Integer constants:\n");
|
||||
printf("; const_0 value (zext): %llu\n", LLVMConstIntGetZExtValue(const_0));
|
||||
printf("; const_42 value (zext): %llu\n", LLVMConstIntGetZExtValue(const_42));
|
||||
printf("; const_neg1 value (sext): %lld\n", LLVMConstIntGetSExtValue(const_neg1));
|
||||
printf("; const_max_u32 value (zext): %llu\n", LLVMConstIntGetZExtValue(const_max_u32));
|
||||
printf(";\n");
|
||||
printf("; Value checks:\n");
|
||||
printf("; const_42 is constant: %s\n", LLVMIsConstant(const_42) ? "yes" : "no");
|
||||
printf("; null_i32 is null: %s\n", LLVMIsNull(null_i32) ? "yes" : "no");
|
||||
printf("; null_ptr is null: %s\n", LLVMIsNull(null_ptr) ? "yes" : "no");
|
||||
printf("; undef_i32 is undef: %s\n", LLVMIsUndef(undef_i32) ? "yes" : "no");
|
||||
printf("; poison_i32 is poison: %s\n", LLVMIsPoison(poison_i32) ? "yes" : "no");
|
||||
printf("; const_42 is undef: %s\n", LLVMIsUndef(const_42) ? "yes" : "no");
|
||||
printf(";\n");
|
||||
printf("; Aggregate constants:\n");
|
||||
printf("; array with 5 i32 elements\n");
|
||||
printf("; struct with {i32, f64, i64}\n");
|
||||
printf("; named struct Point with {i32, i32}\n");
|
||||
printf("; vector with 4 x i32\n");
|
||||
printf("\n");
|
||||
|
||||
// Print module IR
|
||||
char *ir = LLVMPrintModuleToString(mod);
|
||||
printf("%s", ir);
|
||||
LLVMDisposeMessage(ir);
|
||||
|
||||
// Cleanup
|
||||
LLVMDisposeModule(mod);
|
||||
LLVMContextDispose(ctx);
|
||||
return 1;
|
||||
}
|
||||
LLVMDisposeMessage(error);
|
||||
|
||||
return 0;
|
||||
// Print diagnostic comments
|
||||
printf("; Test: test_constants\n");
|
||||
printf(";\n");
|
||||
printf("; Integer constants:\n");
|
||||
printf("; const_0 value (zext): %llu\n", LLVMConstIntGetZExtValue(const_0));
|
||||
printf("; const_42 value (zext): %llu\n",
|
||||
LLVMConstIntGetZExtValue(const_42));
|
||||
printf("; const_neg1 value (sext): %lld\n",
|
||||
LLVMConstIntGetSExtValue(const_neg1));
|
||||
printf("; const_max_u32 value (zext): %llu\n",
|
||||
LLVMConstIntGetZExtValue(const_max_u32));
|
||||
printf(";\n");
|
||||
printf("; Value checks:\n");
|
||||
printf("; const_42 is constant: %s\n",
|
||||
LLVMIsConstant(const_42) ? "yes" : "no");
|
||||
printf("; null_i32 is null: %s\n", LLVMIsNull(null_i32) ? "yes" : "no");
|
||||
printf("; null_ptr is null: %s\n", LLVMIsNull(null_ptr) ? "yes" : "no");
|
||||
printf("; undef_i32 is undef: %s\n", LLVMIsUndef(undef_i32) ? "yes" : "no");
|
||||
printf("; poison_i32 is poison: %s\n",
|
||||
LLVMIsPoison(poison_i32) ? "yes" : "no");
|
||||
printf("; const_42 is undef: %s\n", LLVMIsUndef(const_42) ? "yes" : "no");
|
||||
printf(";\n");
|
||||
printf("; Aggregate constants:\n");
|
||||
printf("; array with 5 i32 elements\n");
|
||||
printf("; struct with {i32, f64, i64}\n");
|
||||
printf("; named struct Point with {i32, i32}\n");
|
||||
printf("; vector with 4 x i32\n");
|
||||
printf("\n");
|
||||
|
||||
// Print module IR
|
||||
char *ir = LLVMPrintModuleToString(mod);
|
||||
printf("%s", ir);
|
||||
LLVMDisposeMessage(ir);
|
||||
|
||||
// Cleanup
|
||||
LLVMDisposeModule(mod);
|
||||
LLVMContextDispose(ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+147
-129
@@ -10,164 +10,182 @@
|
||||
* - PHI nodes alternative: using alloca/load/store pattern
|
||||
*/
|
||||
|
||||
#include <llvm-c/Core.h>
|
||||
#include <llvm-c/Analysis.h>
|
||||
#include <cstdio>
|
||||
#include <llvm-c/Analysis.h>
|
||||
#include <llvm-c/Core.h>
|
||||
|
||||
int main() {
|
||||
LLVMContextRef ctx = LLVMContextCreate();
|
||||
LLVMModuleRef mod = LLVMModuleCreateWithNameInContext("test_factorial", ctx);
|
||||
LLVMContextRef ctx = LLVMContextCreate();
|
||||
LLVMModuleRef mod = LLVMModuleCreateWithNameInContext("test_factorial", ctx);
|
||||
|
||||
// Set target for more realistic output
|
||||
LLVMSetTarget(mod, "x86_64-unknown-linux-gnu");
|
||||
// Set target for more realistic output
|
||||
LLVMSetTarget(mod, "x86_64-unknown-linux-gnu");
|
||||
|
||||
LLVMTypeRef i64 = LLVMInt64TypeInContext(ctx);
|
||||
LLVMTypeRef i1 = LLVMInt1TypeInContext(ctx);
|
||||
LLVMTypeRef i64 = LLVMInt64TypeInContext(ctx);
|
||||
LLVMTypeRef i1 = LLVMInt1TypeInContext(ctx);
|
||||
|
||||
LLVMBuilderRef builder = LLVMCreateBuilderInContext(ctx);
|
||||
LLVMBuilderRef builder = LLVMCreateBuilderInContext(ctx);
|
||||
|
||||
// ==========================================
|
||||
// Function: i64 factorial(i64 n)
|
||||
// Iterative implementation using alloca/load/store
|
||||
// ==========================================
|
||||
LLVMTypeRef fact_params[] = {i64};
|
||||
LLVMTypeRef fact_ty = LLVMFunctionType(i64, fact_params, 1, 0);
|
||||
LLVMValueRef fact_func = LLVMAddFunction(mod, "factorial", fact_ty);
|
||||
// ==========================================
|
||||
// Function: i64 factorial(i64 n)
|
||||
// Iterative implementation using alloca/load/store
|
||||
// ==========================================
|
||||
LLVMTypeRef fact_params[] = {i64};
|
||||
LLVMTypeRef fact_ty = LLVMFunctionType(i64, fact_params, 1, 0);
|
||||
LLVMValueRef fact_func = LLVMAddFunction(mod, "factorial", fact_ty);
|
||||
|
||||
LLVMValueRef n = LLVMGetParam(fact_func, 0);
|
||||
LLVMSetValueName2(n, "n", 1);
|
||||
LLVMValueRef n = LLVMGetParam(fact_func, 0);
|
||||
LLVMSetValueName2(n, "n", 1);
|
||||
|
||||
// Basic blocks
|
||||
LLVMBasicBlockRef entry = LLVMAppendBasicBlockInContext(ctx, fact_func, "entry");
|
||||
LLVMBasicBlockRef loop_cond = LLVMAppendBasicBlockInContext(ctx, fact_func, "loop_cond");
|
||||
LLVMBasicBlockRef loop_body = LLVMAppendBasicBlockInContext(ctx, fact_func, "loop_body");
|
||||
LLVMBasicBlockRef exit_bb = LLVMAppendBasicBlockInContext(ctx, fact_func, "exit");
|
||||
// Basic blocks
|
||||
LLVMBasicBlockRef entry =
|
||||
LLVMAppendBasicBlockInContext(ctx, fact_func, "entry");
|
||||
LLVMBasicBlockRef loop_cond =
|
||||
LLVMAppendBasicBlockInContext(ctx, fact_func, "loop_cond");
|
||||
LLVMBasicBlockRef loop_body =
|
||||
LLVMAppendBasicBlockInContext(ctx, fact_func, "loop_body");
|
||||
LLVMBasicBlockRef exit_bb =
|
||||
LLVMAppendBasicBlockInContext(ctx, fact_func, "exit");
|
||||
|
||||
// Entry block: initialize result=1, i=1
|
||||
LLVMPositionBuilderAtEnd(builder, entry);
|
||||
LLVMValueRef result_ptr = LLVMBuildAlloca(builder, i64, "result");
|
||||
LLVMValueRef i_ptr = LLVMBuildAlloca(builder, i64, "i");
|
||||
// Entry block: initialize result=1, i=1
|
||||
LLVMPositionBuilderAtEnd(builder, entry);
|
||||
LLVMValueRef result_ptr = LLVMBuildAlloca(builder, i64, "result");
|
||||
LLVMValueRef i_ptr = LLVMBuildAlloca(builder, i64, "i");
|
||||
|
||||
LLVMBuildStore(builder, LLVMConstInt(i64, 1, 0), result_ptr);
|
||||
LLVMBuildStore(builder, LLVMConstInt(i64, 1, 0), i_ptr);
|
||||
LLVMBuildBr(builder, loop_cond);
|
||||
LLVMBuildStore(builder, LLVMConstInt(i64, 1, 0), result_ptr);
|
||||
LLVMBuildStore(builder, LLVMConstInt(i64, 1, 0), i_ptr);
|
||||
LLVMBuildBr(builder, loop_cond);
|
||||
|
||||
// Loop condition: while (i <= n)
|
||||
LLVMPositionBuilderAtEnd(builder, loop_cond);
|
||||
LLVMValueRef i_val = LLVMBuildLoad2(builder, i64, i_ptr, "i_val");
|
||||
LLVMValueRef cmp = LLVMBuildICmp(builder, LLVMIntSLE, i_val, n, "cmp");
|
||||
LLVMBuildCondBr(builder, cmp, loop_body, exit_bb);
|
||||
// Loop condition: while (i <= n)
|
||||
LLVMPositionBuilderAtEnd(builder, loop_cond);
|
||||
LLVMValueRef i_val = LLVMBuildLoad2(builder, i64, i_ptr, "i_val");
|
||||
LLVMValueRef cmp = LLVMBuildICmp(builder, LLVMIntSLE, i_val, n, "cmp");
|
||||
LLVMBuildCondBr(builder, cmp, loop_body, exit_bb);
|
||||
|
||||
// Loop body: result *= i; i++
|
||||
LLVMPositionBuilderAtEnd(builder, loop_body);
|
||||
LLVMValueRef result_val = LLVMBuildLoad2(builder, i64, result_ptr, "result_val");
|
||||
LLVMValueRef i_val2 = LLVMBuildLoad2(builder, i64, i_ptr, "i_val2");
|
||||
// Loop body: result *= i; i++
|
||||
LLVMPositionBuilderAtEnd(builder, loop_body);
|
||||
LLVMValueRef result_val =
|
||||
LLVMBuildLoad2(builder, i64, result_ptr, "result_val");
|
||||
LLVMValueRef i_val2 = LLVMBuildLoad2(builder, i64, i_ptr, "i_val2");
|
||||
|
||||
LLVMValueRef new_result = LLVMBuildMul(builder, result_val, i_val2, "new_result");
|
||||
LLVMBuildStore(builder, new_result, result_ptr);
|
||||
LLVMValueRef new_result =
|
||||
LLVMBuildMul(builder, result_val, i_val2, "new_result");
|
||||
LLVMBuildStore(builder, new_result, result_ptr);
|
||||
|
||||
LLVMValueRef new_i = LLVMBuildAdd(builder, i_val2, LLVMConstInt(i64, 1, 0), "new_i");
|
||||
LLVMBuildStore(builder, new_i, i_ptr);
|
||||
LLVMValueRef new_i =
|
||||
LLVMBuildAdd(builder, i_val2, LLVMConstInt(i64, 1, 0), "new_i");
|
||||
LLVMBuildStore(builder, new_i, i_ptr);
|
||||
|
||||
LLVMBuildBr(builder, loop_cond);
|
||||
LLVMBuildBr(builder, loop_cond);
|
||||
|
||||
// Exit: return result
|
||||
LLVMPositionBuilderAtEnd(builder, exit_bb);
|
||||
LLVMValueRef final_result = LLVMBuildLoad2(builder, i64, result_ptr, "final_result");
|
||||
LLVMBuildRet(builder, final_result);
|
||||
// Exit: return result
|
||||
LLVMPositionBuilderAtEnd(builder, exit_bb);
|
||||
LLVMValueRef final_result =
|
||||
LLVMBuildLoad2(builder, i64, result_ptr, "final_result");
|
||||
LLVMBuildRet(builder, final_result);
|
||||
|
||||
// ==========================================
|
||||
// Function: i64 factorial_recursive(i64 n)
|
||||
// Recursive implementation for comparison
|
||||
// ==========================================
|
||||
LLVMValueRef fact_rec_func = LLVMAddFunction(mod, "factorial_recursive", fact_ty);
|
||||
LLVMValueRef n_rec = LLVMGetParam(fact_rec_func, 0);
|
||||
LLVMSetValueName2(n_rec, "n", 1);
|
||||
// ==========================================
|
||||
// Function: i64 factorial_recursive(i64 n)
|
||||
// Recursive implementation for comparison
|
||||
// ==========================================
|
||||
LLVMValueRef fact_rec_func =
|
||||
LLVMAddFunction(mod, "factorial_recursive", fact_ty);
|
||||
LLVMValueRef n_rec = LLVMGetParam(fact_rec_func, 0);
|
||||
LLVMSetValueName2(n_rec, "n", 1);
|
||||
|
||||
LLVMBasicBlockRef rec_entry = LLVMAppendBasicBlockInContext(ctx, fact_rec_func, "entry");
|
||||
LLVMBasicBlockRef base_case = LLVMAppendBasicBlockInContext(ctx, fact_rec_func, "base_case");
|
||||
LLVMBasicBlockRef recursive = LLVMAppendBasicBlockInContext(ctx, fact_rec_func, "recursive");
|
||||
LLVMBasicBlockRef rec_entry =
|
||||
LLVMAppendBasicBlockInContext(ctx, fact_rec_func, "entry");
|
||||
LLVMBasicBlockRef base_case =
|
||||
LLVMAppendBasicBlockInContext(ctx, fact_rec_func, "base_case");
|
||||
LLVMBasicBlockRef recursive =
|
||||
LLVMAppendBasicBlockInContext(ctx, fact_rec_func, "recursive");
|
||||
|
||||
// Entry: if n <= 1 goto base_case else goto recursive
|
||||
LLVMPositionBuilderAtEnd(builder, rec_entry);
|
||||
LLVMValueRef is_base = LLVMBuildICmp(builder, LLVMIntSLE, n_rec,
|
||||
LLVMConstInt(i64, 1, 0), "is_base");
|
||||
LLVMBuildCondBr(builder, is_base, base_case, recursive);
|
||||
// Entry: if n <= 1 goto base_case else goto recursive
|
||||
LLVMPositionBuilderAtEnd(builder, rec_entry);
|
||||
LLVMValueRef is_base = LLVMBuildICmp(builder, LLVMIntSLE, n_rec,
|
||||
LLVMConstInt(i64, 1, 0), "is_base");
|
||||
LLVMBuildCondBr(builder, is_base, base_case, recursive);
|
||||
|
||||
// Base case: return 1
|
||||
LLVMPositionBuilderAtEnd(builder, base_case);
|
||||
LLVMBuildRet(builder, LLVMConstInt(i64, 1, 0));
|
||||
// Base case: return 1
|
||||
LLVMPositionBuilderAtEnd(builder, base_case);
|
||||
LLVMBuildRet(builder, LLVMConstInt(i64, 1, 0));
|
||||
|
||||
// Recursive: return n * factorial_recursive(n-1)
|
||||
LLVMPositionBuilderAtEnd(builder, recursive);
|
||||
LLVMValueRef n_minus_1 = LLVMBuildSub(builder, n_rec, LLVMConstInt(i64, 1, 0), "n_minus_1");
|
||||
LLVMValueRef rec_args[] = {n_minus_1};
|
||||
LLVMValueRef rec_result = LLVMBuildCall2(builder, fact_ty, fact_rec_func, rec_args, 1, "rec_result");
|
||||
LLVMValueRef final_rec = LLVMBuildMul(builder, n_rec, rec_result, "final_rec");
|
||||
LLVMBuildRet(builder, final_rec);
|
||||
// Recursive: return n * factorial_recursive(n-1)
|
||||
LLVMPositionBuilderAtEnd(builder, recursive);
|
||||
LLVMValueRef n_minus_1 =
|
||||
LLVMBuildSub(builder, n_rec, LLVMConstInt(i64, 1, 0), "n_minus_1");
|
||||
LLVMValueRef rec_args[] = {n_minus_1};
|
||||
LLVMValueRef rec_result = LLVMBuildCall2(builder, fact_ty, fact_rec_func,
|
||||
rec_args, 1, "rec_result");
|
||||
LLVMValueRef final_rec =
|
||||
LLVMBuildMul(builder, n_rec, rec_result, "final_rec");
|
||||
LLVMBuildRet(builder, final_rec);
|
||||
|
||||
// ==========================================
|
||||
// Function: i64 main()
|
||||
// Calls factorial(5) and returns the result
|
||||
// ==========================================
|
||||
LLVMTypeRef main_ty = LLVMFunctionType(i64, nullptr, 0, 0);
|
||||
LLVMValueRef main_func = LLVMAddFunction(mod, "main", main_ty);
|
||||
// ==========================================
|
||||
// Function: i64 main()
|
||||
// Calls factorial(5) and returns the result
|
||||
// ==========================================
|
||||
LLVMTypeRef main_ty = LLVMFunctionType(i64, nullptr, 0, 0);
|
||||
LLVMValueRef main_func = LLVMAddFunction(mod, "main", main_ty);
|
||||
|
||||
LLVMBasicBlockRef main_entry = LLVMAppendBasicBlockInContext(ctx, main_func, "entry");
|
||||
LLVMPositionBuilderAtEnd(builder, main_entry);
|
||||
LLVMBasicBlockRef main_entry =
|
||||
LLVMAppendBasicBlockInContext(ctx, main_func, "entry");
|
||||
LLVMPositionBuilderAtEnd(builder, main_entry);
|
||||
|
||||
LLVMValueRef main_args[] = {LLVMConstInt(i64, 5, 0)};
|
||||
LLVMValueRef fact_result = LLVMBuildCall2(builder, fact_ty, fact_func, main_args, 1, "fact_result");
|
||||
LLVMBuildRet(builder, fact_result);
|
||||
LLVMValueRef main_args[] = {LLVMConstInt(i64, 5, 0)};
|
||||
LLVMValueRef fact_result =
|
||||
LLVMBuildCall2(builder, fact_ty, fact_func, main_args, 1, "fact_result");
|
||||
LLVMBuildRet(builder, fact_result);
|
||||
|
||||
LLVMDisposeBuilder(builder);
|
||||
LLVMDisposeBuilder(builder);
|
||||
|
||||
// Verify module
|
||||
char *error = nullptr;
|
||||
if (LLVMVerifyModule(mod, LLVMReturnStatusAction, &error)) {
|
||||
fprintf(stderr, "; Verification failed: %s\n", error);
|
||||
LLVMDisposeMessage(error);
|
||||
LLVMDisposeModule(mod);
|
||||
LLVMContextDispose(ctx);
|
||||
return 1;
|
||||
}
|
||||
// Verify module
|
||||
char *error = nullptr;
|
||||
if (LLVMVerifyModule(mod, LLVMReturnStatusAction, &error)) {
|
||||
fprintf(stderr, "; Verification failed: %s\n", error);
|
||||
LLVMDisposeMessage(error);
|
||||
|
||||
// Print diagnostic comments
|
||||
printf("; Test: test_factorial\n");
|
||||
printf("; Integration test: Iterative and recursive factorial\n");
|
||||
printf(";\n");
|
||||
printf("; factorial(i64 n) -> i64:\n");
|
||||
printf("; Iterative implementation using alloca/load/store\n");
|
||||
printf("; Blocks: entry -> loop_cond -> loop_body -> exit\n");
|
||||
printf(";\n");
|
||||
printf("; factorial_recursive(i64 n) -> i64:\n");
|
||||
printf("; Recursive implementation\n");
|
||||
printf("; Blocks: entry -> base_case / recursive\n");
|
||||
printf(";\n");
|
||||
printf("; main() -> i64:\n");
|
||||
printf("; Calls factorial(5), expected result: 120\n");
|
||||
printf(";\n");
|
||||
printf("; Function info:\n");
|
||||
|
||||
size_t len;
|
||||
for (LLVMValueRef fn = LLVMGetFirstFunction(mod); fn; fn = LLVMGetNextFunction(fn)) {
|
||||
const char *name = LLVMGetValueName2(fn, &len);
|
||||
unsigned bb_count = LLVMCountBasicBlocks(fn);
|
||||
unsigned param_count = LLVMCountParams(fn);
|
||||
printf("; %s: %u params, %u blocks\n", name, param_count, bb_count);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
|
||||
// Print module IR
|
||||
char *ir = LLVMPrintModuleToString(mod);
|
||||
printf("%s", ir);
|
||||
LLVMDisposeMessage(ir);
|
||||
|
||||
// Cleanup
|
||||
LLVMDisposeModule(mod);
|
||||
LLVMContextDispose(ctx);
|
||||
return 1;
|
||||
}
|
||||
LLVMDisposeMessage(error);
|
||||
|
||||
return 0;
|
||||
// Print diagnostic comments
|
||||
printf("; Test: test_factorial\n");
|
||||
printf("; Integration test: Iterative and recursive factorial\n");
|
||||
printf(";\n");
|
||||
printf("; factorial(i64 n) -> i64:\n");
|
||||
printf("; Iterative implementation using alloca/load/store\n");
|
||||
printf("; Blocks: entry -> loop_cond -> loop_body -> exit\n");
|
||||
printf(";\n");
|
||||
printf("; factorial_recursive(i64 n) -> i64:\n");
|
||||
printf("; Recursive implementation\n");
|
||||
printf("; Blocks: entry -> base_case / recursive\n");
|
||||
printf(";\n");
|
||||
printf("; main() -> i64:\n");
|
||||
printf("; Calls factorial(5), expected result: 120\n");
|
||||
printf(";\n");
|
||||
printf("; Function info:\n");
|
||||
|
||||
size_t len;
|
||||
for (LLVMValueRef fn = LLVMGetFirstFunction(mod); fn;
|
||||
fn = LLVMGetNextFunction(fn)) {
|
||||
const char *name = LLVMGetValueName2(fn, &len);
|
||||
unsigned bb_count = LLVMCountBasicBlocks(fn);
|
||||
unsigned param_count = LLVMCountParams(fn);
|
||||
printf("; %s: %u params, %u blocks\n", name, param_count, bb_count);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
|
||||
// Print module IR
|
||||
char *ir = LLVMPrintModuleToString(mod);
|
||||
printf("%s", ir);
|
||||
LLVMDisposeMessage(ir);
|
||||
|
||||
// Cleanup
|
||||
LLVMDisposeModule(mod);
|
||||
LLVMContextDispose(ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+167
-150
@@ -14,177 +14,194 @@
|
||||
* - LLVMGetReturnType(), LLVMCountParamTypes()
|
||||
*/
|
||||
|
||||
#include <llvm-c/Core.h>
|
||||
#include <llvm-c/Analysis.h>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <llvm-c/Analysis.h>
|
||||
#include <llvm-c/Core.h>
|
||||
|
||||
const char* linkage_name(LLVMLinkage linkage) {
|
||||
switch (linkage) {
|
||||
case LLVMExternalLinkage: return "external";
|
||||
case LLVMAvailableExternallyLinkage: return "available_externally";
|
||||
case LLVMLinkOnceAnyLinkage: return "linkonce";
|
||||
case LLVMLinkOnceODRLinkage: return "linkonce_odr";
|
||||
case LLVMWeakAnyLinkage: return "weak";
|
||||
case LLVMWeakODRLinkage: return "weak_odr";
|
||||
case LLVMAppendingLinkage: return "appending";
|
||||
case LLVMInternalLinkage: return "internal";
|
||||
case LLVMPrivateLinkage: return "private";
|
||||
case LLVMExternalWeakLinkage: return "extern_weak";
|
||||
case LLVMCommonLinkage: return "common";
|
||||
default: return "unknown";
|
||||
}
|
||||
const char *linkage_name(LLVMLinkage linkage) {
|
||||
switch (linkage) {
|
||||
case LLVMExternalLinkage:
|
||||
return "external";
|
||||
case LLVMAvailableExternallyLinkage:
|
||||
return "available_externally";
|
||||
case LLVMLinkOnceAnyLinkage:
|
||||
return "linkonce";
|
||||
case LLVMLinkOnceODRLinkage:
|
||||
return "linkonce_odr";
|
||||
case LLVMWeakAnyLinkage:
|
||||
return "weak";
|
||||
case LLVMWeakODRLinkage:
|
||||
return "weak_odr";
|
||||
case LLVMAppendingLinkage:
|
||||
return "appending";
|
||||
case LLVMInternalLinkage:
|
||||
return "internal";
|
||||
case LLVMPrivateLinkage:
|
||||
return "private";
|
||||
case LLVMExternalWeakLinkage:
|
||||
return "extern_weak";
|
||||
case LLVMCommonLinkage:
|
||||
return "common";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
LLVMContextRef ctx = LLVMContextCreate();
|
||||
LLVMModuleRef mod = LLVMModuleCreateWithNameInContext("test_function", ctx);
|
||||
LLVMContextRef ctx = LLVMContextCreate();
|
||||
LLVMModuleRef mod = LLVMModuleCreateWithNameInContext("test_function", ctx);
|
||||
|
||||
LLVMTypeRef i32 = LLVMInt32TypeInContext(ctx);
|
||||
LLVMTypeRef i64 = LLVMInt64TypeInContext(ctx);
|
||||
LLVMTypeRef void_ty = LLVMVoidTypeInContext(ctx);
|
||||
LLVMTypeRef ptr = LLVMPointerTypeInContext(ctx, 0);
|
||||
LLVMTypeRef i32 = LLVMInt32TypeInContext(ctx);
|
||||
LLVMTypeRef i64 = LLVMInt64TypeInContext(ctx);
|
||||
LLVMTypeRef void_ty = LLVMVoidTypeInContext(ctx);
|
||||
LLVMTypeRef ptr = LLVMPointerTypeInContext(ctx, 0);
|
||||
|
||||
// Function 1: void foo()
|
||||
LLVMTypeRef foo_ty = LLVMFunctionType(void_ty, nullptr, 0, 0);
|
||||
LLVMValueRef foo = LLVMAddFunction(mod, "foo", foo_ty);
|
||||
// Function 1: void foo()
|
||||
LLVMTypeRef foo_ty = LLVMFunctionType(void_ty, nullptr, 0, 0);
|
||||
LLVMValueRef foo = LLVMAddFunction(mod, "foo", foo_ty);
|
||||
|
||||
// Function 2: i32 bar(i32, i32)
|
||||
LLVMTypeRef bar_params[] = {i32, i32};
|
||||
LLVMTypeRef bar_ty = LLVMFunctionType(i32, bar_params, 2, 0);
|
||||
LLVMValueRef bar = LLVMAddFunction(mod, "bar", bar_ty);
|
||||
// Function 2: i32 bar(i32, i32)
|
||||
LLVMTypeRef bar_params[] = {i32, i32};
|
||||
LLVMTypeRef bar_ty = LLVMFunctionType(i32, bar_params, 2, 0);
|
||||
LLVMValueRef bar = LLVMAddFunction(mod, "bar", bar_ty);
|
||||
|
||||
// Set parameter names
|
||||
LLVMValueRef bar_param0 = LLVMGetParam(bar, 0);
|
||||
LLVMValueRef bar_param1 = LLVMGetParam(bar, 1);
|
||||
LLVMSetValueName2(bar_param0, "x", 1);
|
||||
LLVMSetValueName2(bar_param1, "y", 1);
|
||||
// Set parameter names
|
||||
LLVMValueRef bar_param0 = LLVMGetParam(bar, 0);
|
||||
LLVMValueRef bar_param1 = LLVMGetParam(bar, 1);
|
||||
LLVMSetValueName2(bar_param0, "x", 1);
|
||||
LLVMSetValueName2(bar_param1, "y", 1);
|
||||
|
||||
// Function 3: i64 baz(ptr, i32, i64) with internal linkage
|
||||
// Internal linkage requires a body, so we add a simple one
|
||||
LLVMTypeRef baz_params[] = {ptr, i32, i64};
|
||||
LLVMTypeRef baz_ty = LLVMFunctionType(i64, baz_params, 3, 0);
|
||||
LLVMValueRef baz = LLVMAddFunction(mod, "baz", baz_ty);
|
||||
LLVMSetLinkage(baz, LLVMInternalLinkage);
|
||||
|
||||
// Add a basic block with return to make it a valid definition
|
||||
LLVMBasicBlockRef baz_entry = LLVMAppendBasicBlockInContext(ctx, baz, "entry");
|
||||
LLVMBuilderRef builder = LLVMCreateBuilderInContext(ctx);
|
||||
LLVMPositionBuilderAtEnd(builder, baz_entry);
|
||||
LLVMBuildRet(builder, LLVMConstInt(i64, 0, 0));
|
||||
LLVMDisposeBuilder(builder);
|
||||
// Function 3: i64 baz(ptr, i32, i64) with internal linkage
|
||||
// Internal linkage requires a body, so we add a simple one
|
||||
LLVMTypeRef baz_params[] = {ptr, i32, i64};
|
||||
LLVMTypeRef baz_ty = LLVMFunctionType(i64, baz_params, 3, 0);
|
||||
LLVMValueRef baz = LLVMAddFunction(mod, "baz", baz_ty);
|
||||
LLVMSetLinkage(baz, LLVMInternalLinkage);
|
||||
|
||||
// Function 4: varargs function - i32 printf(ptr, ...)
|
||||
LLVMTypeRef printf_params[] = {ptr};
|
||||
LLVMTypeRef printf_ty = LLVMFunctionType(i32, printf_params, 1, 1);
|
||||
LLVMValueRef printf_fn = LLVMAddFunction(mod, "printf", printf_ty);
|
||||
// Add a basic block with return to make it a valid definition
|
||||
LLVMBasicBlockRef baz_entry =
|
||||
LLVMAppendBasicBlockInContext(ctx, baz, "entry");
|
||||
LLVMBuilderRef builder = LLVMCreateBuilderInContext(ctx);
|
||||
LLVMPositionBuilderAtEnd(builder, baz_entry);
|
||||
LLVMBuildRet(builder, LLVMConstInt(i64, 0, 0));
|
||||
LLVMDisposeBuilder(builder);
|
||||
|
||||
// Function 5: Function with fastcc calling convention
|
||||
LLVMTypeRef fastcc_params[] = {i32};
|
||||
LLVMTypeRef fastcc_ty = LLVMFunctionType(i32, fastcc_params, 1, 0);
|
||||
LLVMValueRef fastcc_fn = LLVMAddFunction(mod, "fastcc_func", fastcc_ty);
|
||||
LLVMSetFunctionCallConv(fastcc_fn, LLVMFastCallConv);
|
||||
// Function 4: varargs function - i32 printf(ptr, ...)
|
||||
LLVMTypeRef printf_params[] = {ptr};
|
||||
LLVMTypeRef printf_ty = LLVMFunctionType(i32, printf_params, 1, 1);
|
||||
LLVMValueRef printf_fn = LLVMAddFunction(mod, "printf", printf_ty);
|
||||
|
||||
// Function 6: Will be deleted
|
||||
LLVMTypeRef delete_ty = LLVMFunctionType(void_ty, nullptr, 0, 0);
|
||||
LLVMValueRef delete_fn = LLVMAddFunction(mod, "to_be_deleted", delete_ty);
|
||||
// Function 5: Function with fastcc calling convention
|
||||
LLVMTypeRef fastcc_params[] = {i32};
|
||||
LLVMTypeRef fastcc_ty = LLVMFunctionType(i32, fastcc_params, 1, 0);
|
||||
LLVMValueRef fastcc_fn = LLVMAddFunction(mod, "fastcc_func", fastcc_ty);
|
||||
LLVMSetFunctionCallConv(fastcc_fn, LLVMFastCallConv);
|
||||
|
||||
// Get function by name
|
||||
LLVMValueRef found_bar = LLVMGetNamedFunction(mod, "bar");
|
||||
// Function 6: Will be deleted
|
||||
LLVMTypeRef delete_ty = LLVMFunctionType(void_ty, nullptr, 0, 0);
|
||||
LLVMValueRef delete_fn = LLVMAddFunction(mod, "to_be_deleted", delete_ty);
|
||||
|
||||
// Count functions before deletion
|
||||
int count_before = 0;
|
||||
for (LLVMValueRef fn = LLVMGetFirstFunction(mod); fn; fn = LLVMGetNextFunction(fn)) {
|
||||
count_before++;
|
||||
}
|
||||
// Get function by name
|
||||
LLVMValueRef found_bar = LLVMGetNamedFunction(mod, "bar");
|
||||
|
||||
// Delete the function
|
||||
LLVMDeleteFunction(delete_fn);
|
||||
// Count functions before deletion
|
||||
int count_before = 0;
|
||||
for (LLVMValueRef fn = LLVMGetFirstFunction(mod); fn;
|
||||
fn = LLVMGetNextFunction(fn)) {
|
||||
count_before++;
|
||||
}
|
||||
|
||||
// Count functions after deletion
|
||||
int count_after = 0;
|
||||
for (LLVMValueRef fn = LLVMGetFirstFunction(mod); fn; fn = LLVMGetNextFunction(fn)) {
|
||||
count_after++;
|
||||
}
|
||||
// Delete the function
|
||||
LLVMDeleteFunction(delete_fn);
|
||||
|
||||
// Verify module
|
||||
char *error = nullptr;
|
||||
if (LLVMVerifyModule(mod, LLVMReturnStatusAction, &error)) {
|
||||
fprintf(stderr, "; Verification failed: %s\n", error);
|
||||
LLVMDisposeMessage(error);
|
||||
LLVMDisposeModule(mod);
|
||||
LLVMContextDispose(ctx);
|
||||
return 1;
|
||||
}
|
||||
// Count functions after deletion
|
||||
int count_after = 0;
|
||||
for (LLVMValueRef fn = LLVMGetFirstFunction(mod); fn;
|
||||
fn = LLVMGetNextFunction(fn)) {
|
||||
count_after++;
|
||||
}
|
||||
|
||||
// Verify module
|
||||
char *error = nullptr;
|
||||
if (LLVMVerifyModule(mod, LLVMReturnStatusAction, &error)) {
|
||||
fprintf(stderr, "; Verification failed: %s\n", error);
|
||||
LLVMDisposeMessage(error);
|
||||
|
||||
// Print diagnostic comments
|
||||
printf("; Test: test_function\n");
|
||||
printf(";\n");
|
||||
|
||||
// foo info
|
||||
size_t name_len;
|
||||
const char *foo_name = LLVMGetValueName2(foo, &name_len);
|
||||
printf("; Function 'foo':\n");
|
||||
printf("; name: %s\n", foo_name);
|
||||
printf("; param count: %u\n", LLVMCountParams(foo));
|
||||
printf("; linkage: %s\n", linkage_name(LLVMGetLinkage(foo)));
|
||||
printf("; calling conv: %u (C=0)\n", LLVMGetFunctionCallConv(foo));
|
||||
|
||||
// bar info
|
||||
const char *bar_name = LLVMGetValueName2(bar, &name_len);
|
||||
printf(";\n");
|
||||
printf("; Function 'bar':\n");
|
||||
printf("; name: %s\n", bar_name);
|
||||
printf("; param count: %u\n", LLVMCountParams(bar));
|
||||
printf("; found by name: %s\n", found_bar == bar ? "yes" : "no");
|
||||
|
||||
// Get param names
|
||||
const char *p0_name = LLVMGetValueName2(bar_param0, &name_len);
|
||||
const char *p1_name = LLVMGetValueName2(bar_param1, &name_len);
|
||||
printf("; param 0 name: %s\n", p0_name);
|
||||
printf("; param 1 name: %s\n", p1_name);
|
||||
|
||||
// baz info
|
||||
printf(";\n");
|
||||
printf("; Function 'baz':\n");
|
||||
printf("; param count: %u\n", LLVMCountParams(baz));
|
||||
printf("; linkage: %s\n", linkage_name(LLVMGetLinkage(baz)));
|
||||
|
||||
// printf info
|
||||
printf(";\n");
|
||||
printf("; Function 'printf':\n");
|
||||
printf("; param count: %u\n", LLVMCountParams(printf_fn));
|
||||
printf("; is vararg: %s\n", LLVMIsFunctionVarArg(printf_ty) ? "yes" : "no");
|
||||
|
||||
// fastcc info
|
||||
printf(";\n");
|
||||
printf("; Function 'fastcc_func':\n");
|
||||
printf("; calling conv: %u (FastCall=8)\n", LLVMGetFunctionCallConv(fastcc_fn));
|
||||
|
||||
// Function counts
|
||||
printf(";\n");
|
||||
printf("; Function count before deletion: %d\n", count_before);
|
||||
printf("; Function count after deletion: %d\n", count_after);
|
||||
|
||||
// List all functions
|
||||
printf(";\n");
|
||||
printf("; All functions:\n");
|
||||
for (LLVMValueRef fn = LLVMGetFirstFunction(mod); fn; fn = LLVMGetNextFunction(fn)) {
|
||||
const char *fn_name = LLVMGetValueName2(fn, &name_len);
|
||||
printf("; - %s\n", fn_name);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
|
||||
// Print module IR
|
||||
char *ir = LLVMPrintModuleToString(mod);
|
||||
printf("%s", ir);
|
||||
LLVMDisposeMessage(ir);
|
||||
|
||||
// Cleanup
|
||||
LLVMDisposeModule(mod);
|
||||
LLVMContextDispose(ctx);
|
||||
return 1;
|
||||
}
|
||||
LLVMDisposeMessage(error);
|
||||
|
||||
return 0;
|
||||
// Print diagnostic comments
|
||||
printf("; Test: test_function\n");
|
||||
printf(";\n");
|
||||
|
||||
// foo info
|
||||
size_t name_len;
|
||||
const char *foo_name = LLVMGetValueName2(foo, &name_len);
|
||||
printf("; Function 'foo':\n");
|
||||
printf("; name: %s\n", foo_name);
|
||||
printf("; param count: %u\n", LLVMCountParams(foo));
|
||||
printf("; linkage: %s\n", linkage_name(LLVMGetLinkage(foo)));
|
||||
printf("; calling conv: %u (C=0)\n", LLVMGetFunctionCallConv(foo));
|
||||
|
||||
// bar info
|
||||
const char *bar_name = LLVMGetValueName2(bar, &name_len);
|
||||
printf(";\n");
|
||||
printf("; Function 'bar':\n");
|
||||
printf("; name: %s\n", bar_name);
|
||||
printf("; param count: %u\n", LLVMCountParams(bar));
|
||||
printf("; found by name: %s\n", found_bar == bar ? "yes" : "no");
|
||||
|
||||
// Get param names
|
||||
const char *p0_name = LLVMGetValueName2(bar_param0, &name_len);
|
||||
const char *p1_name = LLVMGetValueName2(bar_param1, &name_len);
|
||||
printf("; param 0 name: %s\n", p0_name);
|
||||
printf("; param 1 name: %s\n", p1_name);
|
||||
|
||||
// baz info
|
||||
printf(";\n");
|
||||
printf("; Function 'baz':\n");
|
||||
printf("; param count: %u\n", LLVMCountParams(baz));
|
||||
printf("; linkage: %s\n", linkage_name(LLVMGetLinkage(baz)));
|
||||
|
||||
// printf info
|
||||
printf(";\n");
|
||||
printf("; Function 'printf':\n");
|
||||
printf("; param count: %u\n", LLVMCountParams(printf_fn));
|
||||
printf("; is vararg: %s\n", LLVMIsFunctionVarArg(printf_ty) ? "yes" : "no");
|
||||
|
||||
// fastcc info
|
||||
printf(";\n");
|
||||
printf("; Function 'fastcc_func':\n");
|
||||
printf("; calling conv: %u (FastCall=8)\n",
|
||||
LLVMGetFunctionCallConv(fastcc_fn));
|
||||
|
||||
// Function counts
|
||||
printf(";\n");
|
||||
printf("; Function count before deletion: %d\n", count_before);
|
||||
printf("; Function count after deletion: %d\n", count_after);
|
||||
|
||||
// List all functions
|
||||
printf(";\n");
|
||||
printf("; All functions:\n");
|
||||
for (LLVMValueRef fn = LLVMGetFirstFunction(mod); fn;
|
||||
fn = LLVMGetNextFunction(fn)) {
|
||||
const char *fn_name = LLVMGetValueName2(fn, &name_len);
|
||||
printf("; - %s\n", fn_name);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
|
||||
// Print module IR
|
||||
char *ir = LLVMPrintModuleToString(mod);
|
||||
printf("%s", ir);
|
||||
LLVMDisposeMessage(ir);
|
||||
|
||||
// Cleanup
|
||||
LLVMDisposeModule(mod);
|
||||
LLVMContextDispose(ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+198
-175
@@ -17,209 +17,232 @@
|
||||
* - LLVMSetExternallyInitialized(), LLVMIsExternallyInitialized()
|
||||
*/
|
||||
|
||||
#include <llvm-c/Core.h>
|
||||
#include <llvm-c/Analysis.h>
|
||||
#include <cstdio>
|
||||
#include <llvm-c/Analysis.h>
|
||||
#include <llvm-c/Core.h>
|
||||
|
||||
const char* linkage_name(LLVMLinkage linkage) {
|
||||
switch (linkage) {
|
||||
case LLVMExternalLinkage: return "external";
|
||||
case LLVMAvailableExternallyLinkage: return "available_externally";
|
||||
case LLVMLinkOnceAnyLinkage: return "linkonce";
|
||||
case LLVMLinkOnceODRLinkage: return "linkonce_odr";
|
||||
case LLVMWeakAnyLinkage: return "weak";
|
||||
case LLVMWeakODRLinkage: return "weak_odr";
|
||||
case LLVMAppendingLinkage: return "appending";
|
||||
case LLVMInternalLinkage: return "internal";
|
||||
case LLVMPrivateLinkage: return "private";
|
||||
case LLVMExternalWeakLinkage: return "extern_weak";
|
||||
case LLVMCommonLinkage: return "common";
|
||||
default: return "unknown";
|
||||
}
|
||||
const char *linkage_name(LLVMLinkage linkage) {
|
||||
switch (linkage) {
|
||||
case LLVMExternalLinkage:
|
||||
return "external";
|
||||
case LLVMAvailableExternallyLinkage:
|
||||
return "available_externally";
|
||||
case LLVMLinkOnceAnyLinkage:
|
||||
return "linkonce";
|
||||
case LLVMLinkOnceODRLinkage:
|
||||
return "linkonce_odr";
|
||||
case LLVMWeakAnyLinkage:
|
||||
return "weak";
|
||||
case LLVMWeakODRLinkage:
|
||||
return "weak_odr";
|
||||
case LLVMAppendingLinkage:
|
||||
return "appending";
|
||||
case LLVMInternalLinkage:
|
||||
return "internal";
|
||||
case LLVMPrivateLinkage:
|
||||
return "private";
|
||||
case LLVMExternalWeakLinkage:
|
||||
return "extern_weak";
|
||||
case LLVMCommonLinkage:
|
||||
return "common";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
const char* visibility_name(LLVMVisibility vis) {
|
||||
switch (vis) {
|
||||
case LLVMDefaultVisibility: return "default";
|
||||
case LLVMHiddenVisibility: return "hidden";
|
||||
case LLVMProtectedVisibility: return "protected";
|
||||
default: return "unknown";
|
||||
}
|
||||
const char *visibility_name(LLVMVisibility vis) {
|
||||
switch (vis) {
|
||||
case LLVMDefaultVisibility:
|
||||
return "default";
|
||||
case LLVMHiddenVisibility:
|
||||
return "hidden";
|
||||
case LLVMProtectedVisibility:
|
||||
return "protected";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
LLVMContextRef ctx = LLVMContextCreate();
|
||||
LLVMModuleRef mod = LLVMModuleCreateWithNameInContext("test_globals", ctx);
|
||||
LLVMContextRef ctx = LLVMContextCreate();
|
||||
LLVMModuleRef mod = LLVMModuleCreateWithNameInContext("test_globals", ctx);
|
||||
|
||||
LLVMTypeRef i8 = LLVMInt8TypeInContext(ctx);
|
||||
LLVMTypeRef i32 = LLVMInt32TypeInContext(ctx);
|
||||
LLVMTypeRef i64 = LLVMInt64TypeInContext(ctx);
|
||||
LLVMTypeRef f64 = LLVMDoubleTypeInContext(ctx);
|
||||
LLVMTypeRef ptr = LLVMPointerTypeInContext(ctx, 0);
|
||||
LLVMTypeRef i8 = LLVMInt8TypeInContext(ctx);
|
||||
LLVMTypeRef i32 = LLVMInt32TypeInContext(ctx);
|
||||
LLVMTypeRef i64 = LLVMInt64TypeInContext(ctx);
|
||||
LLVMTypeRef f64 = LLVMDoubleTypeInContext(ctx);
|
||||
LLVMTypeRef ptr = LLVMPointerTypeInContext(ctx, 0);
|
||||
|
||||
// ==========================================
|
||||
// Basic global variable
|
||||
// ==========================================
|
||||
LLVMValueRef global_counter = LLVMAddGlobal(mod, i32, "counter");
|
||||
LLVMSetInitializer(global_counter, LLVMConstInt(i32, 0, 0));
|
||||
// ==========================================
|
||||
// Basic global variable
|
||||
// ==========================================
|
||||
LLVMValueRef global_counter = LLVMAddGlobal(mod, i32, "counter");
|
||||
LLVMSetInitializer(global_counter, LLVMConstInt(i32, 0, 0));
|
||||
|
||||
// ==========================================
|
||||
// Constant global
|
||||
// ==========================================
|
||||
LLVMValueRef global_const = LLVMAddGlobal(mod, i32, "magic_number");
|
||||
LLVMSetInitializer(global_const, LLVMConstInt(i32, 42, 0));
|
||||
LLVMSetGlobalConstant(global_const, 1);
|
||||
// ==========================================
|
||||
// Constant global
|
||||
// ==========================================
|
||||
LLVMValueRef global_const = LLVMAddGlobal(mod, i32, "magic_number");
|
||||
LLVMSetInitializer(global_const, LLVMConstInt(i32, 42, 0));
|
||||
LLVMSetGlobalConstant(global_const, 1);
|
||||
|
||||
// ==========================================
|
||||
// Global with alignment
|
||||
// ==========================================
|
||||
LLVMValueRef global_aligned = LLVMAddGlobal(mod, i64, "aligned_var");
|
||||
LLVMSetInitializer(global_aligned, LLVMConstInt(i64, 0, 0));
|
||||
LLVMSetAlignment(global_aligned, 16);
|
||||
// ==========================================
|
||||
// Global with alignment
|
||||
// ==========================================
|
||||
LLVMValueRef global_aligned = LLVMAddGlobal(mod, i64, "aligned_var");
|
||||
LLVMSetInitializer(global_aligned, LLVMConstInt(i64, 0, 0));
|
||||
LLVMSetAlignment(global_aligned, 16);
|
||||
|
||||
// ==========================================
|
||||
// Global with linkage
|
||||
// ==========================================
|
||||
LLVMValueRef global_internal = LLVMAddGlobal(mod, i32, "internal_var");
|
||||
LLVMSetInitializer(global_internal, LLVMConstInt(i32, 100, 0));
|
||||
LLVMSetLinkage(global_internal, LLVMInternalLinkage);
|
||||
// ==========================================
|
||||
// Global with linkage
|
||||
// ==========================================
|
||||
LLVMValueRef global_internal = LLVMAddGlobal(mod, i32, "internal_var");
|
||||
LLVMSetInitializer(global_internal, LLVMConstInt(i32, 100, 0));
|
||||
LLVMSetLinkage(global_internal, LLVMInternalLinkage);
|
||||
|
||||
LLVMValueRef global_private = LLVMAddGlobal(mod, i32, "private_var");
|
||||
LLVMSetInitializer(global_private, LLVMConstInt(i32, 200, 0));
|
||||
LLVMSetLinkage(global_private, LLVMPrivateLinkage);
|
||||
LLVMValueRef global_private = LLVMAddGlobal(mod, i32, "private_var");
|
||||
LLVMSetInitializer(global_private, LLVMConstInt(i32, 200, 0));
|
||||
LLVMSetLinkage(global_private, LLVMPrivateLinkage);
|
||||
|
||||
LLVMValueRef global_weak = LLVMAddGlobal(mod, i32, "weak_var");
|
||||
LLVMSetInitializer(global_weak, LLVMConstInt(i32, 300, 0));
|
||||
LLVMSetLinkage(global_weak, LLVMWeakAnyLinkage);
|
||||
LLVMValueRef global_weak = LLVMAddGlobal(mod, i32, "weak_var");
|
||||
LLVMSetInitializer(global_weak, LLVMConstInt(i32, 300, 0));
|
||||
LLVMSetLinkage(global_weak, LLVMWeakAnyLinkage);
|
||||
|
||||
// ==========================================
|
||||
// Global with visibility
|
||||
// ==========================================
|
||||
LLVMValueRef global_hidden = LLVMAddGlobal(mod, i32, "hidden_var");
|
||||
LLVMSetInitializer(global_hidden, LLVMConstInt(i32, 0, 0));
|
||||
LLVMSetVisibility(global_hidden, LLVMHiddenVisibility);
|
||||
// ==========================================
|
||||
// Global with visibility
|
||||
// ==========================================
|
||||
LLVMValueRef global_hidden = LLVMAddGlobal(mod, i32, "hidden_var");
|
||||
LLVMSetInitializer(global_hidden, LLVMConstInt(i32, 0, 0));
|
||||
LLVMSetVisibility(global_hidden, LLVMHiddenVisibility);
|
||||
|
||||
// ==========================================
|
||||
// Global with section
|
||||
// ==========================================
|
||||
LLVMValueRef global_section = LLVMAddGlobal(mod, i32, "section_var");
|
||||
LLVMSetInitializer(global_section, LLVMConstInt(i32, 0, 0));
|
||||
LLVMSetSection(global_section, ".mydata");
|
||||
// ==========================================
|
||||
// Global with section
|
||||
// ==========================================
|
||||
LLVMValueRef global_section = LLVMAddGlobal(mod, i32, "section_var");
|
||||
LLVMSetInitializer(global_section, LLVMConstInt(i32, 0, 0));
|
||||
LLVMSetSection(global_section, ".mydata");
|
||||
|
||||
// ==========================================
|
||||
// Thread-local global
|
||||
// ==========================================
|
||||
LLVMValueRef global_tls = LLVMAddGlobal(mod, i32, "tls_var");
|
||||
LLVMSetInitializer(global_tls, LLVMConstInt(i32, 0, 0));
|
||||
LLVMSetThreadLocal(global_tls, 1);
|
||||
// ==========================================
|
||||
// Thread-local global
|
||||
// ==========================================
|
||||
LLVMValueRef global_tls = LLVMAddGlobal(mod, i32, "tls_var");
|
||||
LLVMSetInitializer(global_tls, LLVMConstInt(i32, 0, 0));
|
||||
LLVMSetThreadLocal(global_tls, 1);
|
||||
|
||||
// ==========================================
|
||||
// Externally initialized global (no initializer)
|
||||
// ==========================================
|
||||
LLVMValueRef global_extern = LLVMAddGlobal(mod, i32, "extern_var");
|
||||
LLVMSetExternallyInitialized(global_extern, 1);
|
||||
// ==========================================
|
||||
// Externally initialized global (no initializer)
|
||||
// ==========================================
|
||||
LLVMValueRef global_extern = LLVMAddGlobal(mod, i32, "extern_var");
|
||||
LLVMSetExternallyInitialized(global_extern, 1);
|
||||
|
||||
// ==========================================
|
||||
// Global in address space
|
||||
// ==========================================
|
||||
LLVMValueRef global_addrspace = LLVMAddGlobalInAddressSpace(mod, i32, "addrspace_var", 1);
|
||||
LLVMSetInitializer(global_addrspace, LLVMConstInt(i32, 0, 0));
|
||||
// ==========================================
|
||||
// Global in address space
|
||||
// ==========================================
|
||||
LLVMValueRef global_addrspace =
|
||||
LLVMAddGlobalInAddressSpace(mod, i32, "addrspace_var", 1);
|
||||
LLVMSetInitializer(global_addrspace, LLVMConstInt(i32, 0, 0));
|
||||
|
||||
// ==========================================
|
||||
// Global to be deleted
|
||||
// ==========================================
|
||||
LLVMValueRef global_delete = LLVMAddGlobal(mod, i32, "to_be_deleted");
|
||||
LLVMSetInitializer(global_delete, LLVMConstInt(i32, 999, 0));
|
||||
// ==========================================
|
||||
// Global to be deleted
|
||||
// ==========================================
|
||||
LLVMValueRef global_delete = LLVMAddGlobal(mod, i32, "to_be_deleted");
|
||||
LLVMSetInitializer(global_delete, LLVMConstInt(i32, 999, 0));
|
||||
|
||||
// Count globals before deletion
|
||||
int count_before = 0;
|
||||
for (LLVMValueRef g = LLVMGetFirstGlobal(mod); g; g = LLVMGetNextGlobal(g)) {
|
||||
count_before++;
|
||||
}
|
||||
// Count globals before deletion
|
||||
int count_before = 0;
|
||||
for (LLVMValueRef g = LLVMGetFirstGlobal(mod); g; g = LLVMGetNextGlobal(g)) {
|
||||
count_before++;
|
||||
}
|
||||
|
||||
// Delete the global
|
||||
LLVMDeleteGlobal(global_delete);
|
||||
// Delete the global
|
||||
LLVMDeleteGlobal(global_delete);
|
||||
|
||||
// Count globals after deletion
|
||||
int count_after = 0;
|
||||
for (LLVMValueRef g = LLVMGetFirstGlobal(mod); g; g = LLVMGetNextGlobal(g)) {
|
||||
count_after++;
|
||||
}
|
||||
// Count globals after deletion
|
||||
int count_after = 0;
|
||||
for (LLVMValueRef g = LLVMGetFirstGlobal(mod); g; g = LLVMGetNextGlobal(g)) {
|
||||
count_after++;
|
||||
}
|
||||
|
||||
// Get global by name
|
||||
LLVMValueRef found_counter = LLVMGetNamedGlobal(mod, "counter");
|
||||
LLVMValueRef found_nonexist = LLVMGetNamedGlobal(mod, "nonexistent");
|
||||
// Get global by name
|
||||
LLVMValueRef found_counter = LLVMGetNamedGlobal(mod, "counter");
|
||||
LLVMValueRef found_nonexist = LLVMGetNamedGlobal(mod, "nonexistent");
|
||||
|
||||
// Get initializer
|
||||
LLVMValueRef init = LLVMGetInitializer(global_const);
|
||||
// Get initializer
|
||||
LLVMValueRef init = LLVMGetInitializer(global_const);
|
||||
|
||||
// Verify module
|
||||
char *error = nullptr;
|
||||
if (LLVMVerifyModule(mod, LLVMReturnStatusAction, &error)) {
|
||||
fprintf(stderr, "; Verification failed: %s\n", error);
|
||||
LLVMDisposeMessage(error);
|
||||
LLVMDisposeModule(mod);
|
||||
LLVMContextDispose(ctx);
|
||||
return 1;
|
||||
}
|
||||
// Verify module
|
||||
char *error = nullptr;
|
||||
if (LLVMVerifyModule(mod, LLVMReturnStatusAction, &error)) {
|
||||
fprintf(stderr, "; Verification failed: %s\n", error);
|
||||
LLVMDisposeMessage(error);
|
||||
|
||||
// Print diagnostic comments
|
||||
printf("; Test: test_globals\n");
|
||||
printf(";\n");
|
||||
printf("; Global variable properties:\n");
|
||||
printf(";\n");
|
||||
printf("; counter:\n");
|
||||
printf("; is constant: %s\n", LLVMIsGlobalConstant(global_counter) ? "yes" : "no");
|
||||
printf("; linkage: %s\n", linkage_name(LLVMGetLinkage(global_counter)));
|
||||
printf(";\n");
|
||||
printf("; magic_number:\n");
|
||||
printf("; is constant: %s\n", LLVMIsGlobalConstant(global_const) ? "yes" : "no");
|
||||
printf("; has initializer: %s\n", init != nullptr ? "yes" : "no");
|
||||
printf("; initializer value: %llu\n", LLVMConstIntGetZExtValue(init));
|
||||
printf(";\n");
|
||||
printf("; aligned_var:\n");
|
||||
printf("; alignment: %u\n", LLVMGetAlignment(global_aligned));
|
||||
printf(";\n");
|
||||
printf("; internal_var:\n");
|
||||
printf("; linkage: %s\n", linkage_name(LLVMGetLinkage(global_internal)));
|
||||
printf(";\n");
|
||||
printf("; hidden_var:\n");
|
||||
printf("; visibility: %s\n", visibility_name(LLVMGetVisibility(global_hidden)));
|
||||
printf(";\n");
|
||||
printf("; section_var:\n");
|
||||
printf("; section: %s\n", LLVMGetSection(global_section));
|
||||
printf(";\n");
|
||||
printf("; tls_var:\n");
|
||||
printf("; is thread local: %s\n", LLVMIsThreadLocal(global_tls) ? "yes" : "no");
|
||||
printf(";\n");
|
||||
printf("; extern_var:\n");
|
||||
printf("; is externally initialized: %s\n", LLVMIsExternallyInitialized(global_extern) ? "yes" : "no");
|
||||
printf(";\n");
|
||||
printf("; Lookup tests:\n");
|
||||
printf("; found 'counter': %s\n", found_counter != nullptr ? "yes" : "no");
|
||||
printf("; found 'nonexistent': %s\n", found_nonexist != nullptr ? "yes" : "no");
|
||||
printf(";\n");
|
||||
printf("; Global counts:\n");
|
||||
printf("; before deletion: %d\n", count_before);
|
||||
printf("; after deletion: %d\n", count_after);
|
||||
printf(";\n");
|
||||
printf("; All globals:\n");
|
||||
for (LLVMValueRef g = LLVMGetFirstGlobal(mod); g; g = LLVMGetNextGlobal(g)) {
|
||||
size_t len;
|
||||
const char *name = LLVMGetValueName2(g, &len);
|
||||
printf("; - %s\n", name);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
// Print module IR
|
||||
char *ir = LLVMPrintModuleToString(mod);
|
||||
printf("%s", ir);
|
||||
LLVMDisposeMessage(ir);
|
||||
|
||||
// Cleanup
|
||||
LLVMDisposeModule(mod);
|
||||
LLVMContextDispose(ctx);
|
||||
return 1;
|
||||
}
|
||||
LLVMDisposeMessage(error);
|
||||
|
||||
return 0;
|
||||
// Print diagnostic comments
|
||||
printf("; Test: test_globals\n");
|
||||
printf(";\n");
|
||||
printf("; Global variable properties:\n");
|
||||
printf(";\n");
|
||||
printf("; counter:\n");
|
||||
printf("; is constant: %s\n",
|
||||
LLVMIsGlobalConstant(global_counter) ? "yes" : "no");
|
||||
printf("; linkage: %s\n", linkage_name(LLVMGetLinkage(global_counter)));
|
||||
printf(";\n");
|
||||
printf("; magic_number:\n");
|
||||
printf("; is constant: %s\n",
|
||||
LLVMIsGlobalConstant(global_const) ? "yes" : "no");
|
||||
printf("; has initializer: %s\n", init != nullptr ? "yes" : "no");
|
||||
printf("; initializer value: %llu\n", LLVMConstIntGetZExtValue(init));
|
||||
printf(";\n");
|
||||
printf("; aligned_var:\n");
|
||||
printf("; alignment: %u\n", LLVMGetAlignment(global_aligned));
|
||||
printf(";\n");
|
||||
printf("; internal_var:\n");
|
||||
printf("; linkage: %s\n", linkage_name(LLVMGetLinkage(global_internal)));
|
||||
printf(";\n");
|
||||
printf("; hidden_var:\n");
|
||||
printf("; visibility: %s\n",
|
||||
visibility_name(LLVMGetVisibility(global_hidden)));
|
||||
printf(";\n");
|
||||
printf("; section_var:\n");
|
||||
printf("; section: %s\n", LLVMGetSection(global_section));
|
||||
printf(";\n");
|
||||
printf("; tls_var:\n");
|
||||
printf("; is thread local: %s\n",
|
||||
LLVMIsThreadLocal(global_tls) ? "yes" : "no");
|
||||
printf(";\n");
|
||||
printf("; extern_var:\n");
|
||||
printf("; is externally initialized: %s\n",
|
||||
LLVMIsExternallyInitialized(global_extern) ? "yes" : "no");
|
||||
printf(";\n");
|
||||
printf("; Lookup tests:\n");
|
||||
printf("; found 'counter': %s\n", found_counter != nullptr ? "yes" : "no");
|
||||
printf("; found 'nonexistent': %s\n",
|
||||
found_nonexist != nullptr ? "yes" : "no");
|
||||
printf(";\n");
|
||||
printf("; Global counts:\n");
|
||||
printf("; before deletion: %d\n", count_before);
|
||||
printf("; after deletion: %d\n", count_after);
|
||||
printf(";\n");
|
||||
printf("; All globals:\n");
|
||||
for (LLVMValueRef g = LLVMGetFirstGlobal(mod); g; g = LLVMGetNextGlobal(g)) {
|
||||
size_t len;
|
||||
const char *name = LLVMGetValueName2(g, &len);
|
||||
printf("; - %s\n", name);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
// Print module IR
|
||||
char *ir = LLVMPrintModuleToString(mod);
|
||||
printf("%s", ir);
|
||||
LLVMDisposeMessage(ir);
|
||||
|
||||
// Cleanup
|
||||
LLVMDisposeModule(mod);
|
||||
LLVMContextDispose(ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+67
-63
@@ -13,85 +13,89 @@
|
||||
* - LLVMDisposeModule()
|
||||
*/
|
||||
|
||||
#include <llvm-c/Core.h>
|
||||
#include <llvm-c/Analysis.h>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <llvm-c/Analysis.h>
|
||||
#include <llvm-c/Core.h>
|
||||
#include <string>
|
||||
|
||||
int main() {
|
||||
LLVMContextRef ctx = LLVMContextCreate();
|
||||
LLVMContextRef ctx = LLVMContextCreate();
|
||||
|
||||
// Create module
|
||||
LLVMModuleRef mod = LLVMModuleCreateWithNameInContext("test_module", ctx);
|
||||
// Create module
|
||||
LLVMModuleRef mod = LLVMModuleCreateWithNameInContext("test_module", ctx);
|
||||
|
||||
// Get initial module identifier (copy to string before modifying)
|
||||
size_t id_len;
|
||||
const char *id_ptr = LLVMGetModuleIdentifier(mod, &id_len);
|
||||
std::string initial_id(id_ptr, id_len);
|
||||
// Get initial module identifier (copy to string before modifying)
|
||||
size_t id_len;
|
||||
const char *id_ptr = LLVMGetModuleIdentifier(mod, &id_len);
|
||||
std::string initial_id(id_ptr, id_len);
|
||||
|
||||
// Set new module identifier
|
||||
LLVMSetModuleIdentifier(mod, "renamed_module", strlen("renamed_module"));
|
||||
id_ptr = LLVMGetModuleIdentifier(mod, &id_len);
|
||||
std::string new_id(id_ptr, id_len);
|
||||
// Set new module identifier
|
||||
LLVMSetModuleIdentifier(mod, "renamed_module", strlen("renamed_module"));
|
||||
id_ptr = LLVMGetModuleIdentifier(mod, &id_len);
|
||||
std::string new_id(id_ptr, id_len);
|
||||
|
||||
// Get/set source filename (copy to string before modifying)
|
||||
size_t src_len;
|
||||
const char *src_ptr = LLVMGetSourceFileName(mod, &src_len);
|
||||
std::string initial_src(src_ptr, src_len);
|
||||
LLVMSetSourceFileName(mod, "test_source.c", strlen("test_source.c"));
|
||||
src_ptr = LLVMGetSourceFileName(mod, &src_len);
|
||||
std::string new_src(src_ptr, src_len);
|
||||
// Get/set source filename (copy to string before modifying)
|
||||
size_t src_len;
|
||||
const char *src_ptr = LLVMGetSourceFileName(mod, &src_len);
|
||||
std::string initial_src(src_ptr, src_len);
|
||||
LLVMSetSourceFileName(mod, "test_source.c", strlen("test_source.c"));
|
||||
src_ptr = LLVMGetSourceFileName(mod, &src_len);
|
||||
std::string new_src(src_ptr, src_len);
|
||||
|
||||
// Get/set data layout (copy to string before modifying)
|
||||
std::string initial_layout = LLVMGetDataLayoutStr(mod);
|
||||
LLVMSetDataLayout(mod, "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128");
|
||||
std::string new_layout = LLVMGetDataLayoutStr(mod);
|
||||
// Get/set data layout (copy to string before modifying)
|
||||
std::string initial_layout = LLVMGetDataLayoutStr(mod);
|
||||
LLVMSetDataLayout(
|
||||
mod,
|
||||
"e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128");
|
||||
std::string new_layout = LLVMGetDataLayoutStr(mod);
|
||||
|
||||
// Get/set target triple (copy to string before modifying)
|
||||
std::string initial_target = LLVMGetTarget(mod);
|
||||
LLVMSetTarget(mod, "x86_64-unknown-linux-gnu");
|
||||
std::string new_target = LLVMGetTarget(mod);
|
||||
// Get/set target triple (copy to string before modifying)
|
||||
std::string initial_target = LLVMGetTarget(mod);
|
||||
LLVMSetTarget(mod, "x86_64-unknown-linux-gnu");
|
||||
std::string new_target = LLVMGetTarget(mod);
|
||||
|
||||
// Clone module
|
||||
LLVMModuleRef cloned = LLVMCloneModule(mod);
|
||||
id_ptr = LLVMGetModuleIdentifier(cloned, &id_len);
|
||||
std::string cloned_id(id_ptr, id_len);
|
||||
// Clone module
|
||||
LLVMModuleRef cloned = LLVMCloneModule(mod);
|
||||
id_ptr = LLVMGetModuleIdentifier(cloned, &id_len);
|
||||
std::string cloned_id(id_ptr, id_len);
|
||||
|
||||
// Verify module
|
||||
char *error = nullptr;
|
||||
if (LLVMVerifyModule(mod, LLVMReturnStatusAction, &error)) {
|
||||
fprintf(stderr, "; Verification failed: %s\n", error);
|
||||
LLVMDisposeMessage(error);
|
||||
LLVMDisposeModule(cloned);
|
||||
LLVMDisposeModule(mod);
|
||||
LLVMContextDispose(ctx);
|
||||
return 1;
|
||||
}
|
||||
// Verify module
|
||||
char *error = nullptr;
|
||||
if (LLVMVerifyModule(mod, LLVMReturnStatusAction, &error)) {
|
||||
fprintf(stderr, "; Verification failed: %s\n", error);
|
||||
LLVMDisposeMessage(error);
|
||||
|
||||
// Print diagnostic comments
|
||||
printf("; Test: test_module\n");
|
||||
printf("; Initial module ID: %s\n", initial_id.c_str());
|
||||
printf("; New module ID: %s\n", new_id.c_str());
|
||||
printf("; Initial source filename: %s\n", initial_src.c_str());
|
||||
printf("; New source filename: %s\n", new_src.c_str());
|
||||
printf("; Initial data layout: %s\n", initial_layout.empty() ? "(empty)" : initial_layout.c_str());
|
||||
printf("; New data layout: %s\n", new_layout.c_str());
|
||||
printf("; Initial target: %s\n", initial_target.empty() ? "(empty)" : initial_target.c_str());
|
||||
printf("; New target: %s\n", new_target.c_str());
|
||||
printf("; Cloned module ID: %s\n", cloned_id.c_str());
|
||||
printf("\n");
|
||||
|
||||
// Print module IR
|
||||
char *ir = LLVMPrintModuleToString(mod);
|
||||
printf("%s", ir);
|
||||
LLVMDisposeMessage(ir);
|
||||
|
||||
// Cleanup
|
||||
LLVMDisposeModule(cloned);
|
||||
LLVMDisposeModule(mod);
|
||||
LLVMContextDispose(ctx);
|
||||
return 1;
|
||||
}
|
||||
LLVMDisposeMessage(error);
|
||||
|
||||
return 0;
|
||||
// Print diagnostic comments
|
||||
printf("; Test: test_module\n");
|
||||
printf("; Initial module ID: %s\n", initial_id.c_str());
|
||||
printf("; New module ID: %s\n", new_id.c_str());
|
||||
printf("; Initial source filename: %s\n", initial_src.c_str());
|
||||
printf("; New source filename: %s\n", new_src.c_str());
|
||||
printf("; Initial data layout: %s\n",
|
||||
initial_layout.empty() ? "(empty)" : initial_layout.c_str());
|
||||
printf("; New data layout: %s\n", new_layout.c_str());
|
||||
printf("; Initial target: %s\n",
|
||||
initial_target.empty() ? "(empty)" : initial_target.c_str());
|
||||
printf("; New target: %s\n", new_target.c_str());
|
||||
printf("; Cloned module ID: %s\n", cloned_id.c_str());
|
||||
printf("\n");
|
||||
|
||||
// Print module IR
|
||||
char *ir = LLVMPrintModuleToString(mod);
|
||||
printf("%s", ir);
|
||||
LLVMDisposeMessage(ir);
|
||||
|
||||
// Cleanup
|
||||
LLVMDisposeModule(cloned);
|
||||
LLVMDisposeModule(mod);
|
||||
LLVMContextDispose(ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+130
-120
@@ -8,154 +8,164 @@
|
||||
* - LLVMCountIncoming(), LLVMGetIncomingValue(), LLVMGetIncomingBlock()
|
||||
*/
|
||||
|
||||
#include <llvm-c/Core.h>
|
||||
#include <llvm-c/Analysis.h>
|
||||
#include <cstdio>
|
||||
#include <llvm-c/Analysis.h>
|
||||
#include <llvm-c/Core.h>
|
||||
|
||||
int main() {
|
||||
LLVMContextRef ctx = LLVMContextCreate();
|
||||
LLVMModuleRef mod = LLVMModuleCreateWithNameInContext("test_phi", ctx);
|
||||
LLVMContextRef ctx = LLVMContextCreate();
|
||||
LLVMModuleRef mod = LLVMModuleCreateWithNameInContext("test_phi", ctx);
|
||||
|
||||
LLVMTypeRef i1 = LLVMInt1TypeInContext(ctx);
|
||||
LLVMTypeRef i32 = LLVMInt32TypeInContext(ctx);
|
||||
LLVMTypeRef i1 = LLVMInt1TypeInContext(ctx);
|
||||
LLVMTypeRef i32 = LLVMInt32TypeInContext(ctx);
|
||||
|
||||
LLVMBuilderRef builder = LLVMCreateBuilderInContext(ctx);
|
||||
LLVMBuilderRef builder = LLVMCreateBuilderInContext(ctx);
|
||||
|
||||
// ==========================================
|
||||
// Function: simple diamond pattern with PHI
|
||||
// i32 diamond(i1 cond, i32 a, i32 b)
|
||||
// ==========================================
|
||||
LLVMTypeRef diamond_params[] = {i1, i32, i32};
|
||||
LLVMTypeRef diamond_ty = LLVMFunctionType(i32, diamond_params, 3, 0);
|
||||
LLVMValueRef diamond_func = LLVMAddFunction(mod, "diamond", diamond_ty);
|
||||
// ==========================================
|
||||
// Function: simple diamond pattern with PHI
|
||||
// i32 diamond(i1 cond, i32 a, i32 b)
|
||||
// ==========================================
|
||||
LLVMTypeRef diamond_params[] = {i1, i32, i32};
|
||||
LLVMTypeRef diamond_ty = LLVMFunctionType(i32, diamond_params, 3, 0);
|
||||
LLVMValueRef diamond_func = LLVMAddFunction(mod, "diamond", diamond_ty);
|
||||
|
||||
LLVMValueRef cond = LLVMGetParam(diamond_func, 0);
|
||||
LLVMValueRef a = LLVMGetParam(diamond_func, 1);
|
||||
LLVMValueRef b = LLVMGetParam(diamond_func, 2);
|
||||
LLVMSetValueName2(cond, "cond", 4);
|
||||
LLVMSetValueName2(a, "a", 1);
|
||||
LLVMSetValueName2(b, "b", 1);
|
||||
LLVMValueRef cond = LLVMGetParam(diamond_func, 0);
|
||||
LLVMValueRef a = LLVMGetParam(diamond_func, 1);
|
||||
LLVMValueRef b = LLVMGetParam(diamond_func, 2);
|
||||
LLVMSetValueName2(cond, "cond", 4);
|
||||
LLVMSetValueName2(a, "a", 1);
|
||||
LLVMSetValueName2(b, "b", 1);
|
||||
|
||||
LLVMBasicBlockRef entry = LLVMAppendBasicBlockInContext(ctx, diamond_func, "entry");
|
||||
LLVMBasicBlockRef if_true = LLVMAppendBasicBlockInContext(ctx, diamond_func, "if_true");
|
||||
LLVMBasicBlockRef if_false = LLVMAppendBasicBlockInContext(ctx, diamond_func, "if_false");
|
||||
LLVMBasicBlockRef merge = LLVMAppendBasicBlockInContext(ctx, diamond_func, "merge");
|
||||
LLVMBasicBlockRef entry =
|
||||
LLVMAppendBasicBlockInContext(ctx, diamond_func, "entry");
|
||||
LLVMBasicBlockRef if_true =
|
||||
LLVMAppendBasicBlockInContext(ctx, diamond_func, "if_true");
|
||||
LLVMBasicBlockRef if_false =
|
||||
LLVMAppendBasicBlockInContext(ctx, diamond_func, "if_false");
|
||||
LLVMBasicBlockRef merge =
|
||||
LLVMAppendBasicBlockInContext(ctx, diamond_func, "merge");
|
||||
|
||||
// Entry: conditional branch
|
||||
LLVMPositionBuilderAtEnd(builder, entry);
|
||||
LLVMBuildCondBr(builder, cond, if_true, if_false);
|
||||
// Entry: conditional branch
|
||||
LLVMPositionBuilderAtEnd(builder, entry);
|
||||
LLVMBuildCondBr(builder, cond, if_true, if_false);
|
||||
|
||||
// True branch: compute a * 2
|
||||
LLVMPositionBuilderAtEnd(builder, if_true);
|
||||
LLVMValueRef a_doubled = LLVMBuildMul(builder, a, LLVMConstInt(i32, 2, 0), "a_doubled");
|
||||
LLVMBuildBr(builder, merge);
|
||||
// True branch: compute a * 2
|
||||
LLVMPositionBuilderAtEnd(builder, if_true);
|
||||
LLVMValueRef a_doubled =
|
||||
LLVMBuildMul(builder, a, LLVMConstInt(i32, 2, 0), "a_doubled");
|
||||
LLVMBuildBr(builder, merge);
|
||||
|
||||
// False branch: compute b + 1
|
||||
LLVMPositionBuilderAtEnd(builder, if_false);
|
||||
LLVMValueRef b_inc = LLVMBuildAdd(builder, b, LLVMConstInt(i32, 1, 0), "b_inc");
|
||||
LLVMBuildBr(builder, merge);
|
||||
// False branch: compute b + 1
|
||||
LLVMPositionBuilderAtEnd(builder, if_false);
|
||||
LLVMValueRef b_inc =
|
||||
LLVMBuildAdd(builder, b, LLVMConstInt(i32, 1, 0), "b_inc");
|
||||
LLVMBuildBr(builder, merge);
|
||||
|
||||
// Merge: PHI node to select result
|
||||
LLVMPositionBuilderAtEnd(builder, merge);
|
||||
LLVMValueRef phi = LLVMBuildPhi(builder, i32, "result");
|
||||
// Merge: PHI node to select result
|
||||
LLVMPositionBuilderAtEnd(builder, merge);
|
||||
LLVMValueRef phi = LLVMBuildPhi(builder, i32, "result");
|
||||
|
||||
// Add incoming values
|
||||
LLVMValueRef incoming_vals[] = {a_doubled, b_inc};
|
||||
LLVMBasicBlockRef incoming_blocks[] = {if_true, if_false};
|
||||
LLVMAddIncoming(phi, incoming_vals, incoming_blocks, 2);
|
||||
// Add incoming values
|
||||
LLVMValueRef incoming_vals[] = {a_doubled, b_inc};
|
||||
LLVMBasicBlockRef incoming_blocks[] = {if_true, if_false};
|
||||
LLVMAddIncoming(phi, incoming_vals, incoming_blocks, 2);
|
||||
|
||||
LLVMBuildRet(builder, phi);
|
||||
LLVMBuildRet(builder, phi);
|
||||
|
||||
// ==========================================
|
||||
// Function: loop with PHI (sum 1 to n)
|
||||
// i32 sum_to_n(i32 n)
|
||||
// ==========================================
|
||||
LLVMTypeRef sum_params[] = {i32};
|
||||
LLVMTypeRef sum_ty = LLVMFunctionType(i32, sum_params, 1, 0);
|
||||
LLVMValueRef sum_func = LLVMAddFunction(mod, "sum_to_n", sum_ty);
|
||||
// ==========================================
|
||||
// Function: loop with PHI (sum 1 to n)
|
||||
// i32 sum_to_n(i32 n)
|
||||
// ==========================================
|
||||
LLVMTypeRef sum_params[] = {i32};
|
||||
LLVMTypeRef sum_ty = LLVMFunctionType(i32, sum_params, 1, 0);
|
||||
LLVMValueRef sum_func = LLVMAddFunction(mod, "sum_to_n", sum_ty);
|
||||
|
||||
LLVMValueRef n = LLVMGetParam(sum_func, 0);
|
||||
LLVMSetValueName2(n, "n", 1);
|
||||
LLVMValueRef n = LLVMGetParam(sum_func, 0);
|
||||
LLVMSetValueName2(n, "n", 1);
|
||||
|
||||
LLVMBasicBlockRef sum_entry = LLVMAppendBasicBlockInContext(ctx, sum_func, "entry");
|
||||
LLVMBasicBlockRef loop = LLVMAppendBasicBlockInContext(ctx, sum_func, "loop");
|
||||
LLVMBasicBlockRef exit_bb = LLVMAppendBasicBlockInContext(ctx, sum_func, "exit");
|
||||
LLVMBasicBlockRef sum_entry =
|
||||
LLVMAppendBasicBlockInContext(ctx, sum_func, "entry");
|
||||
LLVMBasicBlockRef loop = LLVMAppendBasicBlockInContext(ctx, sum_func, "loop");
|
||||
LLVMBasicBlockRef exit_bb =
|
||||
LLVMAppendBasicBlockInContext(ctx, sum_func, "exit");
|
||||
|
||||
// Entry: branch to loop
|
||||
LLVMPositionBuilderAtEnd(builder, sum_entry);
|
||||
LLVMBuildBr(builder, loop);
|
||||
// Entry: branch to loop
|
||||
LLVMPositionBuilderAtEnd(builder, sum_entry);
|
||||
LLVMBuildBr(builder, loop);
|
||||
|
||||
// Loop header with PHIs
|
||||
LLVMPositionBuilderAtEnd(builder, loop);
|
||||
LLVMValueRef i_phi = LLVMBuildPhi(builder, i32, "i");
|
||||
LLVMValueRef sum_phi = LLVMBuildPhi(builder, i32, "sum");
|
||||
// Loop header with PHIs
|
||||
LLVMPositionBuilderAtEnd(builder, loop);
|
||||
LLVMValueRef i_phi = LLVMBuildPhi(builder, i32, "i");
|
||||
LLVMValueRef sum_phi = LLVMBuildPhi(builder, i32, "sum");
|
||||
|
||||
// Loop body: sum += i; i++
|
||||
LLVMValueRef new_sum = LLVMBuildAdd(builder, sum_phi, i_phi, "new_sum");
|
||||
LLVMValueRef new_i = LLVMBuildAdd(builder, i_phi, LLVMConstInt(i32, 1, 0), "new_i");
|
||||
// Loop body: sum += i; i++
|
||||
LLVMValueRef new_sum = LLVMBuildAdd(builder, sum_phi, i_phi, "new_sum");
|
||||
LLVMValueRef new_i =
|
||||
LLVMBuildAdd(builder, i_phi, LLVMConstInt(i32, 1, 0), "new_i");
|
||||
|
||||
// Loop condition: i <= n
|
||||
LLVMValueRef loop_cond = LLVMBuildICmp(builder, LLVMIntSLE, new_i, n, "loop_cond");
|
||||
LLVMBuildCondBr(builder, loop_cond, loop, exit_bb);
|
||||
// Loop condition: i <= n
|
||||
LLVMValueRef loop_cond =
|
||||
LLVMBuildICmp(builder, LLVMIntSLE, new_i, n, "loop_cond");
|
||||
LLVMBuildCondBr(builder, loop_cond, loop, exit_bb);
|
||||
|
||||
// Add incoming values to PHIs
|
||||
// From entry: i=1, sum=0
|
||||
LLVMValueRef i_incoming_vals[] = {LLVMConstInt(i32, 1, 0), new_i};
|
||||
LLVMBasicBlockRef i_incoming_blocks[] = {sum_entry, loop};
|
||||
LLVMAddIncoming(i_phi, i_incoming_vals, i_incoming_blocks, 2);
|
||||
// Add incoming values to PHIs
|
||||
// From entry: i=1, sum=0
|
||||
LLVMValueRef i_incoming_vals[] = {LLVMConstInt(i32, 1, 0), new_i};
|
||||
LLVMBasicBlockRef i_incoming_blocks[] = {sum_entry, loop};
|
||||
LLVMAddIncoming(i_phi, i_incoming_vals, i_incoming_blocks, 2);
|
||||
|
||||
LLVMValueRef sum_incoming_vals[] = {LLVMConstInt(i32, 0, 0), new_sum};
|
||||
LLVMBasicBlockRef sum_incoming_blocks[] = {sum_entry, loop};
|
||||
LLVMAddIncoming(sum_phi, sum_incoming_vals, sum_incoming_blocks, 2);
|
||||
LLVMValueRef sum_incoming_vals[] = {LLVMConstInt(i32, 0, 0), new_sum};
|
||||
LLVMBasicBlockRef sum_incoming_blocks[] = {sum_entry, loop};
|
||||
LLVMAddIncoming(sum_phi, sum_incoming_vals, sum_incoming_blocks, 2);
|
||||
|
||||
// Exit: return sum
|
||||
LLVMPositionBuilderAtEnd(builder, exit_bb);
|
||||
LLVMBuildRet(builder, new_sum);
|
||||
// Exit: return sum
|
||||
LLVMPositionBuilderAtEnd(builder, exit_bb);
|
||||
LLVMBuildRet(builder, new_sum);
|
||||
|
||||
LLVMDisposeBuilder(builder);
|
||||
LLVMDisposeBuilder(builder);
|
||||
|
||||
// Verify module
|
||||
char *error = nullptr;
|
||||
if (LLVMVerifyModule(mod, LLVMReturnStatusAction, &error)) {
|
||||
fprintf(stderr, "; Verification failed: %s\n", error);
|
||||
LLVMDisposeMessage(error);
|
||||
LLVMDisposeModule(mod);
|
||||
LLVMContextDispose(ctx);
|
||||
return 1;
|
||||
}
|
||||
// Verify module
|
||||
char *error = nullptr;
|
||||
if (LLVMVerifyModule(mod, LLVMReturnStatusAction, &error)) {
|
||||
fprintf(stderr, "; Verification failed: %s\n", error);
|
||||
LLVMDisposeMessage(error);
|
||||
|
||||
// Print diagnostic comments
|
||||
printf("; Test: test_phi\n");
|
||||
printf(";\n");
|
||||
printf("; Diamond pattern PHI:\n");
|
||||
printf("; phi incoming count: %u\n", LLVMCountIncoming(phi));
|
||||
|
||||
// Get incoming values and blocks
|
||||
for (unsigned i = 0; i < LLVMCountIncoming(phi); i++) {
|
||||
LLVMValueRef val = LLVMGetIncomingValue(phi, i);
|
||||
LLVMBasicBlockRef blk = LLVMGetIncomingBlock(phi, i);
|
||||
size_t len;
|
||||
const char *val_name = LLVMGetValueName2(val, &len);
|
||||
const char *blk_name = LLVMGetBasicBlockName(blk);
|
||||
printf("; incoming[%u]: value=%s, block=%s\n", i, val_name, blk_name);
|
||||
}
|
||||
|
||||
printf(";\n");
|
||||
printf("; Loop PHIs:\n");
|
||||
printf("; i_phi incoming count: %u\n", LLVMCountIncoming(i_phi));
|
||||
printf("; sum_phi incoming count: %u\n", LLVMCountIncoming(sum_phi));
|
||||
|
||||
printf("\n");
|
||||
|
||||
// Print module IR
|
||||
char *ir = LLVMPrintModuleToString(mod);
|
||||
printf("%s", ir);
|
||||
LLVMDisposeMessage(ir);
|
||||
|
||||
// Cleanup
|
||||
LLVMDisposeModule(mod);
|
||||
LLVMContextDispose(ctx);
|
||||
return 1;
|
||||
}
|
||||
LLVMDisposeMessage(error);
|
||||
|
||||
return 0;
|
||||
// Print diagnostic comments
|
||||
printf("; Test: test_phi\n");
|
||||
printf(";\n");
|
||||
printf("; Diamond pattern PHI:\n");
|
||||
printf("; phi incoming count: %u\n", LLVMCountIncoming(phi));
|
||||
|
||||
// Get incoming values and blocks
|
||||
for (unsigned i = 0; i < LLVMCountIncoming(phi); i++) {
|
||||
LLVMValueRef val = LLVMGetIncomingValue(phi, i);
|
||||
LLVMBasicBlockRef blk = LLVMGetIncomingBlock(phi, i);
|
||||
size_t len;
|
||||
const char *val_name = LLVMGetValueName2(val, &len);
|
||||
const char *blk_name = LLVMGetBasicBlockName(blk);
|
||||
printf("; incoming[%u]: value=%s, block=%s\n", i, val_name, blk_name);
|
||||
}
|
||||
|
||||
printf(";\n");
|
||||
printf("; Loop PHIs:\n");
|
||||
printf("; i_phi incoming count: %u\n", LLVMCountIncoming(i_phi));
|
||||
printf("; sum_phi incoming count: %u\n", LLVMCountIncoming(sum_phi));
|
||||
|
||||
printf("\n");
|
||||
|
||||
// Print module IR
|
||||
char *ir = LLVMPrintModuleToString(mod);
|
||||
printf("%s", ir);
|
||||
LLVMDisposeMessage(ir);
|
||||
|
||||
// Cleanup
|
||||
LLVMDisposeModule(mod);
|
||||
LLVMContextDispose(ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+178
-162
@@ -9,205 +9,221 @@
|
||||
* - A complete point_add function
|
||||
*/
|
||||
|
||||
#include <llvm-c/Core.h>
|
||||
#include <llvm-c/Analysis.h>
|
||||
#include <cstdio>
|
||||
#include <llvm-c/Analysis.h>
|
||||
#include <llvm-c/Core.h>
|
||||
|
||||
int main() {
|
||||
LLVMContextRef ctx = LLVMContextCreate();
|
||||
LLVMModuleRef mod = LLVMModuleCreateWithNameInContext("test_struct", ctx);
|
||||
LLVMContextRef ctx = LLVMContextCreate();
|
||||
LLVMModuleRef mod = LLVMModuleCreateWithNameInContext("test_struct", ctx);
|
||||
|
||||
LLVMTypeRef i32 = LLVMInt32TypeInContext(ctx);
|
||||
LLVMTypeRef void_ty = LLVMVoidTypeInContext(ctx);
|
||||
LLVMTypeRef ptr = LLVMPointerTypeInContext(ctx, 0);
|
||||
LLVMTypeRef i32 = LLVMInt32TypeInContext(ctx);
|
||||
LLVMTypeRef void_ty = LLVMVoidTypeInContext(ctx);
|
||||
LLVMTypeRef ptr = LLVMPointerTypeInContext(ctx, 0);
|
||||
|
||||
LLVMBuilderRef builder = LLVMCreateBuilderInContext(ctx);
|
||||
LLVMBuilderRef builder = LLVMCreateBuilderInContext(ctx);
|
||||
|
||||
// ==========================================
|
||||
// Define Point struct: { i32 x, i32 y }
|
||||
// ==========================================
|
||||
LLVMTypeRef point_ty = LLVMStructCreateNamed(ctx, "Point");
|
||||
LLVMTypeRef point_fields[] = {i32, i32};
|
||||
LLVMStructSetBody(point_ty, point_fields, 2, 0);
|
||||
// ==========================================
|
||||
// Define Point struct: { i32 x, i32 y }
|
||||
// ==========================================
|
||||
LLVMTypeRef point_ty = LLVMStructCreateNamed(ctx, "Point");
|
||||
LLVMTypeRef point_fields[] = {i32, i32};
|
||||
LLVMStructSetBody(point_ty, point_fields, 2, 0);
|
||||
|
||||
// ==========================================
|
||||
// Function: void point_init(Point* p, i32 x, i32 y)
|
||||
// ==========================================
|
||||
LLVMTypeRef init_params[] = {ptr, i32, i32};
|
||||
LLVMTypeRef init_ty = LLVMFunctionType(void_ty, init_params, 3, 0);
|
||||
LLVMValueRef init_func = LLVMAddFunction(mod, "point_init", init_ty);
|
||||
// ==========================================
|
||||
// Function: void point_init(Point* p, i32 x, i32 y)
|
||||
// ==========================================
|
||||
LLVMTypeRef init_params[] = {ptr, i32, i32};
|
||||
LLVMTypeRef init_ty = LLVMFunctionType(void_ty, init_params, 3, 0);
|
||||
LLVMValueRef init_func = LLVMAddFunction(mod, "point_init", init_ty);
|
||||
|
||||
LLVMValueRef p = LLVMGetParam(init_func, 0);
|
||||
LLVMValueRef x = LLVMGetParam(init_func, 1);
|
||||
LLVMValueRef y = LLVMGetParam(init_func, 2);
|
||||
LLVMSetValueName2(p, "p", 1);
|
||||
LLVMSetValueName2(x, "x", 1);
|
||||
LLVMSetValueName2(y, "y", 1);
|
||||
LLVMValueRef p = LLVMGetParam(init_func, 0);
|
||||
LLVMValueRef x = LLVMGetParam(init_func, 1);
|
||||
LLVMValueRef y = LLVMGetParam(init_func, 2);
|
||||
LLVMSetValueName2(p, "p", 1);
|
||||
LLVMSetValueName2(x, "x", 1);
|
||||
LLVMSetValueName2(y, "y", 1);
|
||||
|
||||
LLVMBasicBlockRef init_entry = LLVMAppendBasicBlockInContext(ctx, init_func, "entry");
|
||||
LLVMPositionBuilderAtEnd(builder, init_entry);
|
||||
LLVMBasicBlockRef init_entry =
|
||||
LLVMAppendBasicBlockInContext(ctx, init_func, "entry");
|
||||
LLVMPositionBuilderAtEnd(builder, init_entry);
|
||||
|
||||
// Store x to p->x (field 0)
|
||||
LLVMValueRef x_ptr = LLVMBuildStructGEP2(builder, point_ty, p, 0, "x_ptr");
|
||||
LLVMBuildStore(builder, x, x_ptr);
|
||||
// Store x to p->x (field 0)
|
||||
LLVMValueRef x_ptr = LLVMBuildStructGEP2(builder, point_ty, p, 0, "x_ptr");
|
||||
LLVMBuildStore(builder, x, x_ptr);
|
||||
|
||||
// Store y to p->y (field 1)
|
||||
LLVMValueRef y_ptr = LLVMBuildStructGEP2(builder, point_ty, p, 1, "y_ptr");
|
||||
LLVMBuildStore(builder, y, y_ptr);
|
||||
// Store y to p->y (field 1)
|
||||
LLVMValueRef y_ptr = LLVMBuildStructGEP2(builder, point_ty, p, 1, "y_ptr");
|
||||
LLVMBuildStore(builder, y, y_ptr);
|
||||
|
||||
LLVMBuildRetVoid(builder);
|
||||
LLVMBuildRetVoid(builder);
|
||||
|
||||
// ==========================================
|
||||
// Function: void point_add(Point* a, Point* b, Point* result)
|
||||
// ==========================================
|
||||
LLVMTypeRef add_params[] = {ptr, ptr, ptr};
|
||||
LLVMTypeRef add_ty = LLVMFunctionType(void_ty, add_params, 3, 0);
|
||||
LLVMValueRef add_func = LLVMAddFunction(mod, "point_add", add_ty);
|
||||
// ==========================================
|
||||
// Function: void point_add(Point* a, Point* b, Point* result)
|
||||
// ==========================================
|
||||
LLVMTypeRef add_params[] = {ptr, ptr, ptr};
|
||||
LLVMTypeRef add_ty = LLVMFunctionType(void_ty, add_params, 3, 0);
|
||||
LLVMValueRef add_func = LLVMAddFunction(mod, "point_add", add_ty);
|
||||
|
||||
LLVMValueRef a = LLVMGetParam(add_func, 0);
|
||||
LLVMValueRef b = LLVMGetParam(add_func, 1);
|
||||
LLVMValueRef result = LLVMGetParam(add_func, 2);
|
||||
LLVMSetValueName2(a, "a", 1);
|
||||
LLVMSetValueName2(b, "b", 1);
|
||||
LLVMSetValueName2(result, "result", 6);
|
||||
LLVMValueRef a = LLVMGetParam(add_func, 0);
|
||||
LLVMValueRef b = LLVMGetParam(add_func, 1);
|
||||
LLVMValueRef result = LLVMGetParam(add_func, 2);
|
||||
LLVMSetValueName2(a, "a", 1);
|
||||
LLVMSetValueName2(b, "b", 1);
|
||||
LLVMSetValueName2(result, "result", 6);
|
||||
|
||||
LLVMBasicBlockRef add_entry = LLVMAppendBasicBlockInContext(ctx, add_func, "entry");
|
||||
LLVMPositionBuilderAtEnd(builder, add_entry);
|
||||
LLVMBasicBlockRef add_entry =
|
||||
LLVMAppendBasicBlockInContext(ctx, add_func, "entry");
|
||||
LLVMPositionBuilderAtEnd(builder, add_entry);
|
||||
|
||||
// Load a->x and a->y
|
||||
LLVMValueRef a_x_ptr = LLVMBuildStructGEP2(builder, point_ty, a, 0, "a_x_ptr");
|
||||
LLVMValueRef a_y_ptr = LLVMBuildStructGEP2(builder, point_ty, a, 1, "a_y_ptr");
|
||||
LLVMValueRef a_x = LLVMBuildLoad2(builder, i32, a_x_ptr, "a_x");
|
||||
LLVMValueRef a_y = LLVMBuildLoad2(builder, i32, a_y_ptr, "a_y");
|
||||
// Load a->x and a->y
|
||||
LLVMValueRef a_x_ptr =
|
||||
LLVMBuildStructGEP2(builder, point_ty, a, 0, "a_x_ptr");
|
||||
LLVMValueRef a_y_ptr =
|
||||
LLVMBuildStructGEP2(builder, point_ty, a, 1, "a_y_ptr");
|
||||
LLVMValueRef a_x = LLVMBuildLoad2(builder, i32, a_x_ptr, "a_x");
|
||||
LLVMValueRef a_y = LLVMBuildLoad2(builder, i32, a_y_ptr, "a_y");
|
||||
|
||||
// Load b->x and b->y
|
||||
LLVMValueRef b_x_ptr = LLVMBuildStructGEP2(builder, point_ty, b, 0, "b_x_ptr");
|
||||
LLVMValueRef b_y_ptr = LLVMBuildStructGEP2(builder, point_ty, b, 1, "b_y_ptr");
|
||||
LLVMValueRef b_x = LLVMBuildLoad2(builder, i32, b_x_ptr, "b_x");
|
||||
LLVMValueRef b_y = LLVMBuildLoad2(builder, i32, b_y_ptr, "b_y");
|
||||
// Load b->x and b->y
|
||||
LLVMValueRef b_x_ptr =
|
||||
LLVMBuildStructGEP2(builder, point_ty, b, 0, "b_x_ptr");
|
||||
LLVMValueRef b_y_ptr =
|
||||
LLVMBuildStructGEP2(builder, point_ty, b, 1, "b_y_ptr");
|
||||
LLVMValueRef b_x = LLVMBuildLoad2(builder, i32, b_x_ptr, "b_x");
|
||||
LLVMValueRef b_y = LLVMBuildLoad2(builder, i32, b_y_ptr, "b_y");
|
||||
|
||||
// Compute sum
|
||||
LLVMValueRef sum_x = LLVMBuildAdd(builder, a_x, b_x, "sum_x");
|
||||
LLVMValueRef sum_y = LLVMBuildAdd(builder, a_y, b_y, "sum_y");
|
||||
// Compute sum
|
||||
LLVMValueRef sum_x = LLVMBuildAdd(builder, a_x, b_x, "sum_x");
|
||||
LLVMValueRef sum_y = LLVMBuildAdd(builder, a_y, b_y, "sum_y");
|
||||
|
||||
// Store to result
|
||||
LLVMValueRef result_x_ptr = LLVMBuildStructGEP2(builder, point_ty, result, 0, "result_x_ptr");
|
||||
LLVMValueRef result_y_ptr = LLVMBuildStructGEP2(builder, point_ty, result, 1, "result_y_ptr");
|
||||
LLVMBuildStore(builder, sum_x, result_x_ptr);
|
||||
LLVMBuildStore(builder, sum_y, result_y_ptr);
|
||||
// Store to result
|
||||
LLVMValueRef result_x_ptr =
|
||||
LLVMBuildStructGEP2(builder, point_ty, result, 0, "result_x_ptr");
|
||||
LLVMValueRef result_y_ptr =
|
||||
LLVMBuildStructGEP2(builder, point_ty, result, 1, "result_y_ptr");
|
||||
LLVMBuildStore(builder, sum_x, result_x_ptr);
|
||||
LLVMBuildStore(builder, sum_y, result_y_ptr);
|
||||
|
||||
LLVMBuildRetVoid(builder);
|
||||
LLVMBuildRetVoid(builder);
|
||||
|
||||
// ==========================================
|
||||
// Function: i32 point_manhattan_distance(Point* p)
|
||||
// Returns |x| + |y| (simplified: just x + y for demo)
|
||||
// ==========================================
|
||||
LLVMTypeRef dist_params[] = {ptr};
|
||||
LLVMTypeRef dist_ty = LLVMFunctionType(i32, dist_params, 1, 0);
|
||||
LLVMValueRef dist_func = LLVMAddFunction(mod, "point_manhattan", dist_ty);
|
||||
// ==========================================
|
||||
// Function: i32 point_manhattan_distance(Point* p)
|
||||
// Returns |x| + |y| (simplified: just x + y for demo)
|
||||
// ==========================================
|
||||
LLVMTypeRef dist_params[] = {ptr};
|
||||
LLVMTypeRef dist_ty = LLVMFunctionType(i32, dist_params, 1, 0);
|
||||
LLVMValueRef dist_func = LLVMAddFunction(mod, "point_manhattan", dist_ty);
|
||||
|
||||
LLVMValueRef dist_p = LLVMGetParam(dist_func, 0);
|
||||
LLVMSetValueName2(dist_p, "p", 1);
|
||||
LLVMValueRef dist_p = LLVMGetParam(dist_func, 0);
|
||||
LLVMSetValueName2(dist_p, "p", 1);
|
||||
|
||||
LLVMBasicBlockRef dist_entry = LLVMAppendBasicBlockInContext(ctx, dist_func, "entry");
|
||||
LLVMPositionBuilderAtEnd(builder, dist_entry);
|
||||
LLVMBasicBlockRef dist_entry =
|
||||
LLVMAppendBasicBlockInContext(ctx, dist_func, "entry");
|
||||
LLVMPositionBuilderAtEnd(builder, dist_entry);
|
||||
|
||||
LLVMValueRef px_ptr = LLVMBuildStructGEP2(builder, point_ty, dist_p, 0, "px_ptr");
|
||||
LLVMValueRef py_ptr = LLVMBuildStructGEP2(builder, point_ty, dist_p, 1, "py_ptr");
|
||||
LLVMValueRef px = LLVMBuildLoad2(builder, i32, px_ptr, "px");
|
||||
LLVMValueRef py = LLVMBuildLoad2(builder, i32, py_ptr, "py");
|
||||
LLVMValueRef dist = LLVMBuildAdd(builder, px, py, "dist");
|
||||
LLVMBuildRet(builder, dist);
|
||||
LLVMValueRef px_ptr =
|
||||
LLVMBuildStructGEP2(builder, point_ty, dist_p, 0, "px_ptr");
|
||||
LLVMValueRef py_ptr =
|
||||
LLVMBuildStructGEP2(builder, point_ty, dist_p, 1, "py_ptr");
|
||||
LLVMValueRef px = LLVMBuildLoad2(builder, i32, px_ptr, "px");
|
||||
LLVMValueRef py = LLVMBuildLoad2(builder, i32, py_ptr, "py");
|
||||
LLVMValueRef dist = LLVMBuildAdd(builder, px, py, "dist");
|
||||
LLVMBuildRet(builder, dist);
|
||||
|
||||
// ==========================================
|
||||
// Function: i32 test_points()
|
||||
// Creates two points, adds them, returns manhattan distance
|
||||
// ==========================================
|
||||
LLVMTypeRef test_ty = LLVMFunctionType(i32, nullptr, 0, 0);
|
||||
LLVMValueRef test_func = LLVMAddFunction(mod, "test_points", test_ty);
|
||||
// ==========================================
|
||||
// Function: i32 test_points()
|
||||
// Creates two points, adds them, returns manhattan distance
|
||||
// ==========================================
|
||||
LLVMTypeRef test_ty = LLVMFunctionType(i32, nullptr, 0, 0);
|
||||
LLVMValueRef test_func = LLVMAddFunction(mod, "test_points", test_ty);
|
||||
|
||||
LLVMBasicBlockRef test_entry = LLVMAppendBasicBlockInContext(ctx, test_func, "entry");
|
||||
LLVMPositionBuilderAtEnd(builder, test_entry);
|
||||
LLVMBasicBlockRef test_entry =
|
||||
LLVMAppendBasicBlockInContext(ctx, test_func, "entry");
|
||||
LLVMPositionBuilderAtEnd(builder, test_entry);
|
||||
|
||||
// Allocate three Points
|
||||
LLVMValueRef p1 = LLVMBuildAlloca(builder, point_ty, "p1");
|
||||
LLVMValueRef p2 = LLVMBuildAlloca(builder, point_ty, "p2");
|
||||
LLVMValueRef p3 = LLVMBuildAlloca(builder, point_ty, "p3");
|
||||
// Allocate three Points
|
||||
LLVMValueRef p1 = LLVMBuildAlloca(builder, point_ty, "p1");
|
||||
LLVMValueRef p2 = LLVMBuildAlloca(builder, point_ty, "p2");
|
||||
LLVMValueRef p3 = LLVMBuildAlloca(builder, point_ty, "p3");
|
||||
|
||||
// Initialize p1 = (3, 4)
|
||||
LLVMValueRef init_args1[] = {p1, LLVMConstInt(i32, 3, 0), LLVMConstInt(i32, 4, 0)};
|
||||
LLVMBuildCall2(builder, init_ty, init_func, init_args1, 3, "");
|
||||
// Initialize p1 = (3, 4)
|
||||
LLVMValueRef init_args1[] = {p1, LLVMConstInt(i32, 3, 0),
|
||||
LLVMConstInt(i32, 4, 0)};
|
||||
LLVMBuildCall2(builder, init_ty, init_func, init_args1, 3, "");
|
||||
|
||||
// Initialize p2 = (1, 2)
|
||||
LLVMValueRef init_args2[] = {p2, LLVMConstInt(i32, 1, 0), LLVMConstInt(i32, 2, 0)};
|
||||
LLVMBuildCall2(builder, init_ty, init_func, init_args2, 3, "");
|
||||
// Initialize p2 = (1, 2)
|
||||
LLVMValueRef init_args2[] = {p2, LLVMConstInt(i32, 1, 0),
|
||||
LLVMConstInt(i32, 2, 0)};
|
||||
LLVMBuildCall2(builder, init_ty, init_func, init_args2, 3, "");
|
||||
|
||||
// Add p1 + p2 -> p3
|
||||
LLVMValueRef add_args[] = {p1, p2, p3};
|
||||
LLVMBuildCall2(builder, add_ty, add_func, add_args, 3, "");
|
||||
// Add p1 + p2 -> p3
|
||||
LLVMValueRef add_args[] = {p1, p2, p3};
|
||||
LLVMBuildCall2(builder, add_ty, add_func, add_args, 3, "");
|
||||
|
||||
// Get manhattan distance of p3
|
||||
LLVMValueRef dist_args[] = {p3};
|
||||
LLVMValueRef final_dist = LLVMBuildCall2(builder, dist_ty, dist_func, dist_args, 1, "final_dist");
|
||||
// Get manhattan distance of p3
|
||||
LLVMValueRef dist_args[] = {p3};
|
||||
LLVMValueRef final_dist =
|
||||
LLVMBuildCall2(builder, dist_ty, dist_func, dist_args, 1, "final_dist");
|
||||
|
||||
LLVMBuildRet(builder, final_dist);
|
||||
LLVMBuildRet(builder, final_dist);
|
||||
|
||||
// ==========================================
|
||||
// Global constant Point
|
||||
// ==========================================
|
||||
LLVMValueRef origin_vals[] = {LLVMConstInt(i32, 0, 0), LLVMConstInt(i32, 0, 0)};
|
||||
LLVMValueRef origin_const = LLVMConstNamedStruct(point_ty, origin_vals, 2);
|
||||
LLVMValueRef origin_global = LLVMAddGlobal(mod, point_ty, "origin");
|
||||
LLVMSetInitializer(origin_global, origin_const);
|
||||
LLVMSetGlobalConstant(origin_global, 1);
|
||||
// ==========================================
|
||||
// Global constant Point
|
||||
// ==========================================
|
||||
LLVMValueRef origin_vals[] = {LLVMConstInt(i32, 0, 0),
|
||||
LLVMConstInt(i32, 0, 0)};
|
||||
LLVMValueRef origin_const = LLVMConstNamedStruct(point_ty, origin_vals, 2);
|
||||
LLVMValueRef origin_global = LLVMAddGlobal(mod, point_ty, "origin");
|
||||
LLVMSetInitializer(origin_global, origin_const);
|
||||
LLVMSetGlobalConstant(origin_global, 1);
|
||||
|
||||
LLVMDisposeBuilder(builder);
|
||||
LLVMDisposeBuilder(builder);
|
||||
|
||||
// Verify module
|
||||
char *error = nullptr;
|
||||
if (LLVMVerifyModule(mod, LLVMReturnStatusAction, &error)) {
|
||||
fprintf(stderr, "; Verification failed: %s\n", error);
|
||||
LLVMDisposeMessage(error);
|
||||
LLVMDisposeModule(mod);
|
||||
LLVMContextDispose(ctx);
|
||||
return 1;
|
||||
}
|
||||
// Verify module
|
||||
char *error = nullptr;
|
||||
if (LLVMVerifyModule(mod, LLVMReturnStatusAction, &error)) {
|
||||
fprintf(stderr, "; Verification failed: %s\n", error);
|
||||
LLVMDisposeMessage(error);
|
||||
|
||||
// Print diagnostic comments
|
||||
printf("; Test: test_struct\n");
|
||||
printf("; Integration test: Point struct manipulation\n");
|
||||
printf(";\n");
|
||||
printf("; Struct definition:\n");
|
||||
printf("; %%Point = type { i32, i32 } ; x, y fields\n");
|
||||
printf(";\n");
|
||||
printf("; Functions:\n");
|
||||
printf("; point_init(Point*, i32, i32) -> void\n");
|
||||
printf("; point_add(Point*, Point*, Point*) -> void\n");
|
||||
printf("; point_manhattan(Point*) -> i32\n");
|
||||
printf("; test_points() -> i32\n");
|
||||
printf(";\n");
|
||||
printf("; test_points creates:\n");
|
||||
printf("; p1 = (3, 4)\n");
|
||||
printf("; p2 = (1, 2)\n");
|
||||
printf("; p3 = p1 + p2 = (4, 6)\n");
|
||||
printf("; returns manhattan(p3) = 4 + 6 = 10\n");
|
||||
printf(";\n");
|
||||
printf("; Struct type info:\n");
|
||||
printf("; name: %s\n", LLVMGetStructName(point_ty));
|
||||
printf("; num elements: %u\n", LLVMCountStructElementTypes(point_ty));
|
||||
printf("; is packed: %s\n", LLVMIsPackedStruct(point_ty) ? "yes" : "no");
|
||||
printf("; is opaque: %s\n", LLVMIsOpaqueStruct(point_ty) ? "yes" : "no");
|
||||
printf("\n");
|
||||
|
||||
// Print module IR
|
||||
char *ir = LLVMPrintModuleToString(mod);
|
||||
printf("%s", ir);
|
||||
LLVMDisposeMessage(ir);
|
||||
|
||||
// Cleanup
|
||||
LLVMDisposeModule(mod);
|
||||
LLVMContextDispose(ctx);
|
||||
return 1;
|
||||
}
|
||||
LLVMDisposeMessage(error);
|
||||
|
||||
return 0;
|
||||
// Print diagnostic comments
|
||||
printf("; Test: test_struct\n");
|
||||
printf("; Integration test: Point struct manipulation\n");
|
||||
printf(";\n");
|
||||
printf("; Struct definition:\n");
|
||||
printf("; %%Point = type { i32, i32 } ; x, y fields\n");
|
||||
printf(";\n");
|
||||
printf("; Functions:\n");
|
||||
printf("; point_init(Point*, i32, i32) -> void\n");
|
||||
printf("; point_add(Point*, Point*, Point*) -> void\n");
|
||||
printf("; point_manhattan(Point*) -> i32\n");
|
||||
printf("; test_points() -> i32\n");
|
||||
printf(";\n");
|
||||
printf("; test_points creates:\n");
|
||||
printf("; p1 = (3, 4)\n");
|
||||
printf("; p2 = (1, 2)\n");
|
||||
printf("; p3 = p1 + p2 = (4, 6)\n");
|
||||
printf("; returns manhattan(p3) = 4 + 6 = 10\n");
|
||||
printf(";\n");
|
||||
printf("; Struct type info:\n");
|
||||
printf("; name: %s\n", LLVMGetStructName(point_ty));
|
||||
printf("; num elements: %u\n", LLVMCountStructElementTypes(point_ty));
|
||||
printf("; is packed: %s\n", LLVMIsPackedStruct(point_ty) ? "yes" : "no");
|
||||
printf("; is opaque: %s\n", LLVMIsOpaqueStruct(point_ty) ? "yes" : "no");
|
||||
printf("\n");
|
||||
|
||||
// Print module IR
|
||||
char *ir = LLVMPrintModuleToString(mod);
|
||||
printf("%s", ir);
|
||||
LLVMDisposeMessage(ir);
|
||||
|
||||
// Cleanup
|
||||
LLVMDisposeModule(mod);
|
||||
LLVMContextDispose(ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+194
-148
@@ -4,9 +4,11 @@
|
||||
*
|
||||
* LLVM-C APIs covered:
|
||||
* - LLVMInt1TypeInContext(), LLVMInt8TypeInContext(), LLVMInt16TypeInContext()
|
||||
* - LLVMInt32TypeInContext(), LLVMInt64TypeInContext(), LLVMInt128TypeInContext()
|
||||
* - LLVMInt32TypeInContext(), LLVMInt64TypeInContext(),
|
||||
* LLVMInt128TypeInContext()
|
||||
* - LLVMIntTypeInContext()
|
||||
* - LLVMHalfTypeInContext(), LLVMFloatTypeInContext(), LLVMDoubleTypeInContext()
|
||||
* - LLVMHalfTypeInContext(), LLVMFloatTypeInContext(),
|
||||
* LLVMDoubleTypeInContext()
|
||||
* - LLVMVoidTypeInContext()
|
||||
* - LLVMPointerTypeInContext()
|
||||
* - LLVMArrayType2()
|
||||
@@ -18,174 +20,218 @@
|
||||
* - LLVMTypeIsSized()
|
||||
*/
|
||||
|
||||
#include <llvm-c/Core.h>
|
||||
#include <llvm-c/Analysis.h>
|
||||
#include <cstdio>
|
||||
#include <llvm-c/Analysis.h>
|
||||
#include <llvm-c/Core.h>
|
||||
|
||||
const char* type_kind_name(LLVMTypeKind kind) {
|
||||
switch (kind) {
|
||||
case LLVMVoidTypeKind: return "void";
|
||||
case LLVMHalfTypeKind: return "half";
|
||||
case LLVMFloatTypeKind: return "float";
|
||||
case LLVMDoubleTypeKind: return "double";
|
||||
case LLVMX86_FP80TypeKind: return "x86_fp80";
|
||||
case LLVMFP128TypeKind: return "fp128";
|
||||
case LLVMPPC_FP128TypeKind: return "ppc_fp128";
|
||||
case LLVMLabelTypeKind: return "label";
|
||||
case LLVMIntegerTypeKind: return "integer";
|
||||
case LLVMFunctionTypeKind: return "function";
|
||||
case LLVMStructTypeKind: return "struct";
|
||||
case LLVMArrayTypeKind: return "array";
|
||||
case LLVMPointerTypeKind: return "pointer";
|
||||
case LLVMVectorTypeKind: return "vector";
|
||||
case LLVMMetadataTypeKind: return "metadata";
|
||||
case LLVMTokenTypeKind: return "token";
|
||||
case LLVMScalableVectorTypeKind: return "scalable_vector";
|
||||
case LLVMBFloatTypeKind: return "bfloat";
|
||||
case LLVMX86_AMXTypeKind: return "x86_amx";
|
||||
case LLVMTargetExtTypeKind: return "target_ext";
|
||||
default: return "unknown";
|
||||
}
|
||||
const char *type_kind_name(LLVMTypeKind kind) {
|
||||
switch (kind) {
|
||||
case LLVMVoidTypeKind:
|
||||
return "void";
|
||||
case LLVMHalfTypeKind:
|
||||
return "half";
|
||||
case LLVMFloatTypeKind:
|
||||
return "float";
|
||||
case LLVMDoubleTypeKind:
|
||||
return "double";
|
||||
case LLVMX86_FP80TypeKind:
|
||||
return "x86_fp80";
|
||||
case LLVMFP128TypeKind:
|
||||
return "fp128";
|
||||
case LLVMPPC_FP128TypeKind:
|
||||
return "ppc_fp128";
|
||||
case LLVMLabelTypeKind:
|
||||
return "label";
|
||||
case LLVMIntegerTypeKind:
|
||||
return "integer";
|
||||
case LLVMFunctionTypeKind:
|
||||
return "function";
|
||||
case LLVMStructTypeKind:
|
||||
return "struct";
|
||||
case LLVMArrayTypeKind:
|
||||
return "array";
|
||||
case LLVMPointerTypeKind:
|
||||
return "pointer";
|
||||
case LLVMVectorTypeKind:
|
||||
return "vector";
|
||||
case LLVMMetadataTypeKind:
|
||||
return "metadata";
|
||||
case LLVMTokenTypeKind:
|
||||
return "token";
|
||||
case LLVMScalableVectorTypeKind:
|
||||
return "scalable_vector";
|
||||
case LLVMBFloatTypeKind:
|
||||
return "bfloat";
|
||||
case LLVMX86_AMXTypeKind:
|
||||
return "x86_amx";
|
||||
case LLVMTargetExtTypeKind:
|
||||
return "target_ext";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
LLVMContextRef ctx = LLVMContextCreate();
|
||||
LLVMModuleRef mod = LLVMModuleCreateWithNameInContext("test_types", ctx);
|
||||
LLVMContextRef ctx = LLVMContextCreate();
|
||||
LLVMModuleRef mod = LLVMModuleCreateWithNameInContext("test_types", ctx);
|
||||
|
||||
// Integer types
|
||||
LLVMTypeRef i1 = LLVMInt1TypeInContext(ctx);
|
||||
LLVMTypeRef i8 = LLVMInt8TypeInContext(ctx);
|
||||
LLVMTypeRef i16 = LLVMInt16TypeInContext(ctx);
|
||||
LLVMTypeRef i32 = LLVMInt32TypeInContext(ctx);
|
||||
LLVMTypeRef i64 = LLVMInt64TypeInContext(ctx);
|
||||
LLVMTypeRef i128 = LLVMInt128TypeInContext(ctx);
|
||||
LLVMTypeRef i256 = LLVMIntTypeInContext(ctx, 256);
|
||||
// Integer types
|
||||
LLVMTypeRef i1 = LLVMInt1TypeInContext(ctx);
|
||||
LLVMTypeRef i8 = LLVMInt8TypeInContext(ctx);
|
||||
LLVMTypeRef i16 = LLVMInt16TypeInContext(ctx);
|
||||
LLVMTypeRef i32 = LLVMInt32TypeInContext(ctx);
|
||||
LLVMTypeRef i64 = LLVMInt64TypeInContext(ctx);
|
||||
LLVMTypeRef i128 = LLVMInt128TypeInContext(ctx);
|
||||
LLVMTypeRef i256 = LLVMIntTypeInContext(ctx, 256);
|
||||
|
||||
// Floating point types
|
||||
LLVMTypeRef f16 = LLVMHalfTypeInContext(ctx);
|
||||
LLVMTypeRef bf16 = LLVMBFloatTypeInContext(ctx);
|
||||
LLVMTypeRef f32 = LLVMFloatTypeInContext(ctx);
|
||||
LLVMTypeRef f64 = LLVMDoubleTypeInContext(ctx);
|
||||
// Floating point types
|
||||
LLVMTypeRef f16 = LLVMHalfTypeInContext(ctx);
|
||||
LLVMTypeRef bf16 = LLVMBFloatTypeInContext(ctx);
|
||||
LLVMTypeRef f32 = LLVMFloatTypeInContext(ctx);
|
||||
LLVMTypeRef f64 = LLVMDoubleTypeInContext(ctx);
|
||||
|
||||
// Void type
|
||||
LLVMTypeRef void_ty = LLVMVoidTypeInContext(ctx);
|
||||
// Void type
|
||||
LLVMTypeRef void_ty = LLVMVoidTypeInContext(ctx);
|
||||
|
||||
// Pointer type (opaque pointer)
|
||||
LLVMTypeRef ptr = LLVMPointerTypeInContext(ctx, 0);
|
||||
// Pointer type (opaque pointer)
|
||||
LLVMTypeRef ptr = LLVMPointerTypeInContext(ctx, 0);
|
||||
|
||||
// Array type
|
||||
LLVMTypeRef arr_i32_10 = LLVMArrayType2(i32, 10);
|
||||
// Array type
|
||||
LLVMTypeRef arr_i32_10 = LLVMArrayType2(i32, 10);
|
||||
|
||||
// Vector type
|
||||
LLVMTypeRef vec_i32_4 = LLVMVectorType(i32, 4);
|
||||
// Vector type
|
||||
LLVMTypeRef vec_i32_4 = LLVMVectorType(i32, 4);
|
||||
|
||||
// Function type: i32(i32, i32)
|
||||
LLVMTypeRef func_params[] = {i32, i32};
|
||||
LLVMTypeRef func_ty = LLVMFunctionType(i32, func_params, 2, 0);
|
||||
// Function type: i32(i32, i32)
|
||||
LLVMTypeRef func_params[] = {i32, i32};
|
||||
LLVMTypeRef func_ty = LLVMFunctionType(i32, func_params, 2, 0);
|
||||
|
||||
// Function type with varargs: i32(i32, ...)
|
||||
LLVMTypeRef vararg_params[] = {i32};
|
||||
LLVMTypeRef vararg_func_ty = LLVMFunctionType(i32, vararg_params, 1, 1);
|
||||
// Function type with varargs: i32(i32, ...)
|
||||
LLVMTypeRef vararg_params[] = {i32};
|
||||
LLVMTypeRef vararg_func_ty = LLVMFunctionType(i32, vararg_params, 1, 1);
|
||||
|
||||
// Anonymous struct type: {i32, f64}
|
||||
LLVMTypeRef struct_elems[] = {i32, f64};
|
||||
LLVMTypeRef anon_struct = LLVMStructTypeInContext(ctx, struct_elems, 2, 0);
|
||||
// Anonymous struct type: {i32, f64}
|
||||
LLVMTypeRef struct_elems[] = {i32, f64};
|
||||
LLVMTypeRef anon_struct = LLVMStructTypeInContext(ctx, struct_elems, 2, 0);
|
||||
|
||||
// Packed anonymous struct type: <{i8, i32}>
|
||||
LLVMTypeRef packed_elems[] = {i8, i32};
|
||||
LLVMTypeRef packed_struct = LLVMStructTypeInContext(ctx, packed_elems, 2, 1);
|
||||
// Packed anonymous struct type: <{i8, i32}>
|
||||
LLVMTypeRef packed_elems[] = {i8, i32};
|
||||
LLVMTypeRef packed_struct = LLVMStructTypeInContext(ctx, packed_elems, 2, 1);
|
||||
|
||||
// Named struct type
|
||||
LLVMTypeRef named_struct = LLVMStructCreateNamed(ctx, "MyStruct");
|
||||
LLVMTypeRef named_elems[] = {i32, ptr, f64};
|
||||
LLVMStructSetBody(named_struct, named_elems, 3, 0);
|
||||
// Named struct type
|
||||
LLVMTypeRef named_struct = LLVMStructCreateNamed(ctx, "MyStruct");
|
||||
LLVMTypeRef named_elems[] = {i32, ptr, f64};
|
||||
LLVMStructSetBody(named_struct, named_elems, 3, 0);
|
||||
|
||||
// Opaque struct (no body set)
|
||||
LLVMTypeRef opaque_struct = LLVMStructCreateNamed(ctx, "OpaqueStruct");
|
||||
// Opaque struct (no body set)
|
||||
LLVMTypeRef opaque_struct = LLVMStructCreateNamed(ctx, "OpaqueStruct");
|
||||
|
||||
// Add global variables to make types visible in output
|
||||
LLVMAddGlobal(mod, i32, "global_i32");
|
||||
LLVMAddGlobal(mod, arr_i32_10, "global_arr");
|
||||
LLVMAddGlobal(mod, vec_i32_4, "global_vec");
|
||||
LLVMAddGlobal(mod, anon_struct, "global_anon_struct");
|
||||
LLVMAddGlobal(mod, packed_struct, "global_packed_struct");
|
||||
LLVMAddGlobal(mod, named_struct, "global_named_struct");
|
||||
// Add global variables to make types visible in output
|
||||
LLVMAddGlobal(mod, i32, "global_i32");
|
||||
LLVMAddGlobal(mod, arr_i32_10, "global_arr");
|
||||
LLVMAddGlobal(mod, vec_i32_4, "global_vec");
|
||||
LLVMAddGlobal(mod, anon_struct, "global_anon_struct");
|
||||
LLVMAddGlobal(mod, packed_struct, "global_packed_struct");
|
||||
LLVMAddGlobal(mod, named_struct, "global_named_struct");
|
||||
|
||||
// Add a function declaration to show function type
|
||||
LLVMAddFunction(mod, "example_func", func_ty);
|
||||
LLVMAddFunction(mod, "example_vararg_func", vararg_func_ty);
|
||||
// Add a function declaration to show function type
|
||||
LLVMAddFunction(mod, "example_func", func_ty);
|
||||
LLVMAddFunction(mod, "example_vararg_func", vararg_func_ty);
|
||||
|
||||
// Verify module
|
||||
char *error = nullptr;
|
||||
if (LLVMVerifyModule(mod, LLVMReturnStatusAction, &error)) {
|
||||
fprintf(stderr, "; Verification failed: %s\n", error);
|
||||
LLVMDisposeMessage(error);
|
||||
LLVMDisposeModule(mod);
|
||||
LLVMContextDispose(ctx);
|
||||
return 1;
|
||||
}
|
||||
// Verify module
|
||||
char *error = nullptr;
|
||||
if (LLVMVerifyModule(mod, LLVMReturnStatusAction, &error)) {
|
||||
fprintf(stderr, "; Verification failed: %s\n", error);
|
||||
LLVMDisposeMessage(error);
|
||||
|
||||
// Print diagnostic comments
|
||||
printf("; Test: test_types\n");
|
||||
printf(";\n");
|
||||
printf("; Integer types:\n");
|
||||
printf("; i1 width: %u, kind: %s\n", LLVMGetIntTypeWidth(i1), type_kind_name(LLVMGetTypeKind(i1)));
|
||||
printf("; i8 width: %u, kind: %s\n", LLVMGetIntTypeWidth(i8), type_kind_name(LLVMGetTypeKind(i8)));
|
||||
printf("; i16 width: %u, kind: %s\n", LLVMGetIntTypeWidth(i16), type_kind_name(LLVMGetTypeKind(i16)));
|
||||
printf("; i32 width: %u, kind: %s\n", LLVMGetIntTypeWidth(i32), type_kind_name(LLVMGetTypeKind(i32)));
|
||||
printf("; i64 width: %u, kind: %s\n", LLVMGetIntTypeWidth(i64), type_kind_name(LLVMGetTypeKind(i64)));
|
||||
printf("; i128 width: %u, kind: %s\n", LLVMGetIntTypeWidth(i128), type_kind_name(LLVMGetTypeKind(i128)));
|
||||
printf("; i256 width: %u, kind: %s\n", LLVMGetIntTypeWidth(i256), type_kind_name(LLVMGetTypeKind(i256)));
|
||||
printf(";\n");
|
||||
printf("; Floating point types:\n");
|
||||
printf("; half kind: %s\n", type_kind_name(LLVMGetTypeKind(f16)));
|
||||
printf("; bfloat kind: %s\n", type_kind_name(LLVMGetTypeKind(bf16)));
|
||||
printf("; float kind: %s\n", type_kind_name(LLVMGetTypeKind(f32)));
|
||||
printf("; double kind: %s\n", type_kind_name(LLVMGetTypeKind(f64)));
|
||||
printf(";\n");
|
||||
printf("; Other types:\n");
|
||||
printf("; void kind: %s, sized: %s\n", type_kind_name(LLVMGetTypeKind(void_ty)), LLVMTypeIsSized(void_ty) ? "yes" : "no");
|
||||
printf("; pointer kind: %s, sized: %s\n", type_kind_name(LLVMGetTypeKind(ptr)), LLVMTypeIsSized(ptr) ? "yes" : "no");
|
||||
printf("; array kind: %s, sized: %s\n", type_kind_name(LLVMGetTypeKind(arr_i32_10)), LLVMTypeIsSized(arr_i32_10) ? "yes" : "no");
|
||||
printf("; vector kind: %s, sized: %s\n", type_kind_name(LLVMGetTypeKind(vec_i32_4)), LLVMTypeIsSized(vec_i32_4) ? "yes" : "no");
|
||||
printf("; function kind: %s, sized: %s\n", type_kind_name(LLVMGetTypeKind(func_ty)), LLVMTypeIsSized(func_ty) ? "yes" : "no");
|
||||
printf(";\n");
|
||||
printf("; Struct types:\n");
|
||||
printf("; anon_struct kind: %s, packed: %s\n", type_kind_name(LLVMGetTypeKind(anon_struct)), LLVMIsPackedStruct(anon_struct) ? "yes" : "no");
|
||||
printf("; packed_struct kind: %s, packed: %s\n", type_kind_name(LLVMGetTypeKind(packed_struct)), LLVMIsPackedStruct(packed_struct) ? "yes" : "no");
|
||||
|
||||
const char *named_struct_name = LLVMGetStructName(named_struct);
|
||||
printf("; named_struct name: %s, opaque: %s\n", named_struct_name, LLVMIsOpaqueStruct(named_struct) ? "yes" : "no");
|
||||
|
||||
const char *opaque_struct_name = LLVMGetStructName(opaque_struct);
|
||||
printf("; opaque_struct name: %s, opaque: %s\n", opaque_struct_name, LLVMIsOpaqueStruct(opaque_struct) ? "yes" : "no");
|
||||
|
||||
// Print type strings
|
||||
printf(";\n");
|
||||
printf("; Type strings:\n");
|
||||
char *i32_str = LLVMPrintTypeToString(i32);
|
||||
printf("; i32: %s\n", i32_str);
|
||||
LLVMDisposeMessage(i32_str);
|
||||
|
||||
char *arr_str = LLVMPrintTypeToString(arr_i32_10);
|
||||
printf("; [10 x i32]: %s\n", arr_str);
|
||||
LLVMDisposeMessage(arr_str);
|
||||
|
||||
char *func_str = LLVMPrintTypeToString(func_ty);
|
||||
printf("; func type: %s\n", func_str);
|
||||
LLVMDisposeMessage(func_str);
|
||||
|
||||
printf("\n");
|
||||
|
||||
// Print module IR
|
||||
char *ir = LLVMPrintModuleToString(mod);
|
||||
printf("%s", ir);
|
||||
LLVMDisposeMessage(ir);
|
||||
|
||||
// Cleanup
|
||||
LLVMDisposeModule(mod);
|
||||
LLVMContextDispose(ctx);
|
||||
return 1;
|
||||
}
|
||||
LLVMDisposeMessage(error);
|
||||
|
||||
return 0;
|
||||
// Print diagnostic comments
|
||||
printf("; Test: test_types\n");
|
||||
printf(";\n");
|
||||
printf("; Integer types:\n");
|
||||
printf("; i1 width: %u, kind: %s\n", LLVMGetIntTypeWidth(i1),
|
||||
type_kind_name(LLVMGetTypeKind(i1)));
|
||||
printf("; i8 width: %u, kind: %s\n", LLVMGetIntTypeWidth(i8),
|
||||
type_kind_name(LLVMGetTypeKind(i8)));
|
||||
printf("; i16 width: %u, kind: %s\n", LLVMGetIntTypeWidth(i16),
|
||||
type_kind_name(LLVMGetTypeKind(i16)));
|
||||
printf("; i32 width: %u, kind: %s\n", LLVMGetIntTypeWidth(i32),
|
||||
type_kind_name(LLVMGetTypeKind(i32)));
|
||||
printf("; i64 width: %u, kind: %s\n", LLVMGetIntTypeWidth(i64),
|
||||
type_kind_name(LLVMGetTypeKind(i64)));
|
||||
printf("; i128 width: %u, kind: %s\n", LLVMGetIntTypeWidth(i128),
|
||||
type_kind_name(LLVMGetTypeKind(i128)));
|
||||
printf("; i256 width: %u, kind: %s\n", LLVMGetIntTypeWidth(i256),
|
||||
type_kind_name(LLVMGetTypeKind(i256)));
|
||||
printf(";\n");
|
||||
printf("; Floating point types:\n");
|
||||
printf("; half kind: %s\n", type_kind_name(LLVMGetTypeKind(f16)));
|
||||
printf("; bfloat kind: %s\n", type_kind_name(LLVMGetTypeKind(bf16)));
|
||||
printf("; float kind: %s\n", type_kind_name(LLVMGetTypeKind(f32)));
|
||||
printf("; double kind: %s\n", type_kind_name(LLVMGetTypeKind(f64)));
|
||||
printf(";\n");
|
||||
printf("; Other types:\n");
|
||||
printf("; void kind: %s, sized: %s\n",
|
||||
type_kind_name(LLVMGetTypeKind(void_ty)),
|
||||
LLVMTypeIsSized(void_ty) ? "yes" : "no");
|
||||
printf("; pointer kind: %s, sized: %s\n",
|
||||
type_kind_name(LLVMGetTypeKind(ptr)),
|
||||
LLVMTypeIsSized(ptr) ? "yes" : "no");
|
||||
printf("; array kind: %s, sized: %s\n",
|
||||
type_kind_name(LLVMGetTypeKind(arr_i32_10)),
|
||||
LLVMTypeIsSized(arr_i32_10) ? "yes" : "no");
|
||||
printf("; vector kind: %s, sized: %s\n",
|
||||
type_kind_name(LLVMGetTypeKind(vec_i32_4)),
|
||||
LLVMTypeIsSized(vec_i32_4) ? "yes" : "no");
|
||||
printf("; function kind: %s, sized: %s\n",
|
||||
type_kind_name(LLVMGetTypeKind(func_ty)),
|
||||
LLVMTypeIsSized(func_ty) ? "yes" : "no");
|
||||
printf(";\n");
|
||||
printf("; Struct types:\n");
|
||||
printf("; anon_struct kind: %s, packed: %s\n",
|
||||
type_kind_name(LLVMGetTypeKind(anon_struct)),
|
||||
LLVMIsPackedStruct(anon_struct) ? "yes" : "no");
|
||||
printf("; packed_struct kind: %s, packed: %s\n",
|
||||
type_kind_name(LLVMGetTypeKind(packed_struct)),
|
||||
LLVMIsPackedStruct(packed_struct) ? "yes" : "no");
|
||||
|
||||
const char *named_struct_name = LLVMGetStructName(named_struct);
|
||||
printf("; named_struct name: %s, opaque: %s\n", named_struct_name,
|
||||
LLVMIsOpaqueStruct(named_struct) ? "yes" : "no");
|
||||
|
||||
const char *opaque_struct_name = LLVMGetStructName(opaque_struct);
|
||||
printf("; opaque_struct name: %s, opaque: %s\n", opaque_struct_name,
|
||||
LLVMIsOpaqueStruct(opaque_struct) ? "yes" : "no");
|
||||
|
||||
// Print type strings
|
||||
printf(";\n");
|
||||
printf("; Type strings:\n");
|
||||
char *i32_str = LLVMPrintTypeToString(i32);
|
||||
printf("; i32: %s\n", i32_str);
|
||||
LLVMDisposeMessage(i32_str);
|
||||
|
||||
char *arr_str = LLVMPrintTypeToString(arr_i32_10);
|
||||
printf("; [10 x i32]: %s\n", arr_str);
|
||||
LLVMDisposeMessage(arr_str);
|
||||
|
||||
char *func_str = LLVMPrintTypeToString(func_ty);
|
||||
printf("; func type: %s\n", func_str);
|
||||
LLVMDisposeMessage(func_str);
|
||||
|
||||
printf("\n");
|
||||
|
||||
// Print module IR
|
||||
char *ir = LLVMPrintModuleToString(mod);
|
||||
printf("%s", ir);
|
||||
LLVMDisposeMessage(ir);
|
||||
|
||||
// Cleanup
|
||||
LLVMDisposeModule(mod);
|
||||
LLVMContextDispose(ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user