Пример #1
0
int main()
{
	LLVMContextRef context = LLVMGetGlobalContext();
	LLVMModuleRef module = LLVMModuleCreateWithName("test-101");
	LLVMBuilderRef builder = LLVMCreateBuilder();
	// LLVMInt32Type()
	// LLVMFunctionType(rtnType, paramType, parmCnt, isVarArg)
	// LLVMAddFunction(module, name, functionType)
	LLVMTypeRef main = LLVMFunctionType(LLVMInt32Type(), NULL, 0, 0);
	LLVMValueRef mainFn = LLVMAddFunction(module, "main", main);
	LLVMBasicBlockRef mainBlk = LLVMAppendBasicBlock(mainFn, "entry");
	LLVMPositionBuilderAtEnd(builder, mainBlk);
	LLVMValueRef str =
	    LLVMBuildGlobalStringPtr(builder, "Hello World!", "str");
	LLVMTypeRef args[1];
	args[0] = LLVMPointerType(LLVMInt8Type(), 0);
	LLVMTypeRef puts = LLVMFunctionType(LLVMInt32Type(), args, 1, 0);
	LLVMValueRef putsFn = LLVMAddFunction(module, "puts", puts);

	LLVMBuildCall(builder, putsFn, &str, 1, "");

	LLVMBuildRet(builder, LLVMConstInt(LLVMInt32Type(), 0, 0));

	LLVMDumpModule(module);

	return 0;
}
Пример #2
0
JITFunctionInfo *JITImpl::
getJITFunctionOrStubImpl(JITCoreInfo &coreInfo, uint32_t pc)
{
  JITFunctionInfo *&info = coreInfo.functionMap[pc];
  if (info)
    return info;
  LLVMBasicBlockRef savedInsertPoint = LLVMGetInsertBlock(builder);
  LLVMValueRef f = LLVMAddFunction(module, "", jitFunctionType);
  LLVMSetFunctionCallConv(f, LLVMFastCallConv);
  LLVMBasicBlockRef entryBB = LLVMAppendBasicBlock(f, "entry");
  LLVMPositionBuilderAtEnd(builder, entryBB);
  LLVMValueRef args[] = {
    LLVMGetParam(f, 0)
  };
  LLVMValueRef call =
    LLVMBuildCall(builder, functions.jitStubImpl, args, 1, "");
  LLVMBuildRet(builder, call);
  if (DEBUG_JIT) {
    LLVMDumpValue(f);
    LLVMVerifyFunction(f, LLVMAbortProcessAction);
  }
  JITInstructionFunction_t code =
    reinterpret_cast<JITInstructionFunction_t>(
     LLVMGetPointerToGlobal(executionEngine, f));
  info = new JITFunctionInfo(pc, f, code, true);
  LLVMPositionBuilderAtEnd(builder, savedInsertPoint);
  return info;
}
Пример #3
0
LLVMCompiledProgram LLVM_compile(ASTNode *node)
{
  char *error = NULL; // Used to retrieve messages from functions
  LLVMLinkInJIT();
  LLVMInitializeNativeTarget();
  LLVMModuleRef mod = LLVMModuleCreateWithName("calc_module");
  LLVMTypeRef program_args[] = { };
  LLVMValueRef program = LLVMAddFunction(mod, "program", LLVMFunctionType(LLVMInt32Type(), program_args, 0, 0));
  LLVMSetFunctionCallConv(program, LLVMCCallConv);

  LLVMBuilderRef builder = LLVMCreateBuilder();
  LLVMBasicBlockRef entry = LLVMAppendBasicBlock(program, "entry");

  LLVMPositionBuilderAtEnd(builder, entry);

  LLVMValueRef res = LLVM_visit(node, builder);

  LLVMBuildRet(builder, res);
  LLVMVerifyModule(mod, LLVMAbortProcessAction, &error);
  LLVMDisposeMessage(error); // Handler == LLVMAbortProcessAction -> No need to check errors

  LLVMDisposeBuilder(builder);

  return (LLVMCompiledProgram) { .module = mod, .function = program };
}
Пример #4
0
static LLVMValueRef
add_printf_test(struct gallivm_state *gallivm)
{
   LLVMModuleRef module = gallivm->module;
   LLVMTypeRef args[1] = { LLVMIntTypeInContext(gallivm->context, 32) };
   LLVMValueRef func = LLVMAddFunction(module, "test_printf", LLVMFunctionType(LLVMVoidTypeInContext(gallivm->context), args, 1, 0));
   LLVMBuilderRef builder = gallivm->builder;
   LLVMBasicBlockRef block = LLVMAppendBasicBlockInContext(gallivm->context, func, "entry");

   LLVMSetFunctionCallConv(func, LLVMCCallConv);

   LLVMPositionBuilderAtEnd(builder, block);
   lp_build_printf(gallivm, "hello, world\n");
   lp_build_printf(gallivm, "print 5 6: %d %d\n", LLVMConstInt(LLVMInt32TypeInContext(gallivm->context), 5, 0),
				LLVMConstInt(LLVMInt32TypeInContext(gallivm->context), 6, 0));

   /* Also test lp_build_assert().  This should not fail. */
   lp_build_assert(gallivm, LLVMConstInt(LLVMInt32TypeInContext(gallivm->context), 1, 0), "assert(1)");

   LLVMBuildRetVoid(builder);

   gallivm_verify_function(gallivm, func);

   return func;
}
Пример #5
0
Файл: Heap.c Проект: YuKill/ftc
static void createPushHeapFunction() {
    // Saving last BasicBlock;
    LLVMBasicBlockRef OldBB = LLVMGetInsertBlock(Builder);

    LLVMTypeRef ParamType    = LLVMPointerType(RAType, 0);
    LLVMTypeRef FunctionType = LLVMFunctionType(LLVMVoidType(), &ParamType, 1, 0);

    LLVMValueRef      Function = LLVMAddFunction(Module, "push.heap", FunctionType);
    LLVMBasicBlockRef Entry    = LLVMAppendBasicBlock(Function, "entry");
    LLVMPositionBuilderAtEnd(Builder, Entry);

    // Function Body
    LLVMValueRef HeapMalloc  = LLVMBuildMalloc(Builder, HeapType, "heap.malloc");

    LLVMValueRef ExPtrIdx[]   = { getSConstInt(0), getSConstInt(0) };
    LLVMValueRef LastPtrIdx[] = { getSConstInt(0), getSConstInt(1) };

    LLVMValueRef ExPtr   = LLVMBuildInBoundsGEP(Builder, HeapMalloc, ExPtrIdx, 2, "heap.exec");
    LLVMValueRef LastPtr = LLVMBuildInBoundsGEP(Builder, HeapMalloc, LastPtrIdx, 2, "heap.last");

    LLVMBuildStore(Builder, LLVMGetParam(Function, 0), ExPtr);
    LLVMBuildStore(Builder, LLVMBuildLoad(Builder, HeapHead, "ld.heap.head"), LastPtr);

    LLVMBuildStore(Builder, HeapMalloc, HeapHead);

    LLVMBuildRetVoid(Builder);

    // Restoring last BasicBlock
    LLVMPositionBuilderAtEnd(Builder, OldBB);
}
Пример #6
0
static LLVMValueRef
add_test(LLVMModuleRef module, const char *name, lp_func_t lp_func)
{
   LLVMTypeRef v4sf = LLVMVectorType(LLVMFloatType(), 4);
   LLVMTypeRef args[1] = { v4sf };
   LLVMValueRef func = LLVMAddFunction(module, name, LLVMFunctionType(v4sf, args, 1, 0));
   LLVMValueRef arg1 = LLVMGetParam(func, 0);
   LLVMBuilderRef builder = LLVMCreateBuilder();
   LLVMBasicBlockRef block = LLVMAppendBasicBlock(func, "entry");
   LLVMValueRef ret;
   struct lp_build_context bld;

   bld.builder = builder;
   bld.type.floating = 1;
   bld.type.width = 32;
   bld.type.length = 4;

   LLVMSetFunctionCallConv(func, LLVMCCallConv);

   LLVMPositionBuilderAtEnd(builder, block);

   ret = lp_func(&bld, arg1);

   LLVMBuildRet(builder, ret);
   LLVMDisposeBuilder(builder);
   return func;
}
Пример #7
0
static void make_rdtscp(compile_t* c)
{
  if(target_is_x86(c->opt->triple))
  {
    // i64 @llvm.x86.rdtscp(i8*)
    LLVMTypeRef f_type = LLVMFunctionType(c->i64, &c->void_ptr, 1, false);
    LLVMValueRef rdtscp = LLVMAddFunction(c->module, "llvm.x86.rdtscp",
      f_type);

    // i64 @internal.x86.rdtscp(i32*)
    LLVMTypeRef i32_ptr = LLVMPointerType(c->i32, 0);
    f_type = LLVMFunctionType(c->i64, &i32_ptr, 1, false);
    LLVMValueRef fun = codegen_addfun(c, "internal.x86.rdtscp", f_type);
    LLVMSetFunctionCallConv(fun, LLVMCCallConv);
    codegen_startfun(c, fun, NULL, NULL);

    // Cast i32* to i8* and call the intrinsic.
    LLVMValueRef arg = LLVMGetParam(fun, 0);
    arg = LLVMBuildBitCast(c->builder, arg, c->void_ptr, "");
    LLVMValueRef result = LLVMBuildCall(c->builder, rdtscp, &arg, 1, "");
    LLVMBuildRet(c->builder, result);

    codegen_finishfun(c);
  } else {
    (void)c;
  }
}
Пример #8
0
LLVMValueRef codegen_addfun(compile_t* c, const char* name, LLVMTypeRef type)
{
  // Add the function and set the calling convention.
  LLVMValueRef fun = LLVMAddFunction(c->module, name, type);
  LLVMSetFunctionCallConv(fun, c->callconv);

  LLVMValueRef arg = LLVMGetFirstParam(fun);
  uint32_t i = 1;

  while(arg != NULL)
  {
    LLVMTypeRef type = LLVMTypeOf(arg);

    if(LLVMGetTypeKind(type) == LLVMPointerTypeKind)
    {
      LLVMTypeRef elem = LLVMGetElementType(type);

      if(LLVMGetTypeKind(elem) == LLVMStructTypeKind)
      {
        size_t size = (size_t)LLVMABISizeOfType(c->target_data, elem);
        LLVMSetDereferenceable(fun, i, size);
      }
    }

    arg = LLVMGetNextParam(arg);
    i++;
  }

  return fun;
}
Пример #9
0
static void handle_line(char **tokens, int ntokens) {
  char *name = tokens[0];
  LLVMValueRef param;
  LLVMValueRef res;

  LLVMModuleRef M = LLVMModuleCreateWithName(name);

  LLVMTypeRef I64ty = LLVMInt64Type();
  LLVMTypeRef I64Ptrty = LLVMPointerType(I64ty, 0);
  LLVMTypeRef Fty = LLVMFunctionType(I64ty, &I64Ptrty, 1, 0);

  LLVMValueRef F = LLVMAddFunction(M, name, Fty);
  LLVMBuilderRef builder = LLVMCreateBuilder();
  LLVMPositionBuilderAtEnd(builder, LLVMAppendBasicBlock(F, "entry"));

  LLVMGetParams(F, &param);
  LLVMSetValueName(param, "in");

  res = build_from_tokens(tokens + 1, ntokens - 1, builder, param);
  if (res) {
    char *irstr = LLVMPrintModuleToString(M);
    puts(irstr);
    LLVMDisposeMessage(irstr);
  }

  LLVMDisposeBuilder(builder);

  LLVMDisposeModule(M);
}
Пример #10
0
struct vm_state *
vm_state_create(const char *module_name)
{
   struct vm_state *vm;

   LLVMTypeRef function_type;
   LLVMValueRef function_value;
   LLVMBasicBlockRef entry_block;

   vm = calloc(1, sizeof(struct vm_state));
   if (vm == NULL) {
      fprintf(stderr, "Memory allocation request failed.\n");
      exit(EXIT_FAILURE);
   }

   vm->module = LLVMModuleCreateWithName(module_name);
   vm->builder = LLVMCreateBuilder();

   function_type = LLVMFunctionType(LLVMVoidType(), NULL, 0, 0);
   function_value = LLVMAddFunction(vm->module, "main", function_type);

   entry_block = LLVMAppendBasicBlock(function_value, "entry");
   LLVMPositionBuilderAtEnd(vm->builder, entry_block);

   vm->symtab = symbol_table_create();
   return vm;
}
Пример #11
0
int main(int argc, char const *argv[]) {
    LLVMModuleRef mod = LLVMModuleCreateWithName("sum");

    LLVMTypeRef param_types[] = { LLVMInt32Type(), LLVMInt32Type() };
    LLVMTypeRef ret_type = LLVMFunctionType(LLVMInt32Type(), /* ret type */
                                            param_types, /* arg types */
                                            2, /* arg count */
                                            0 /* is variadic */);
    LLVMValueRef sum = LLVMAddFunction(mod, "sum", ret_type);

    LLVMBasicBlockRef entry = LLVMAppendBasicBlock(sum, "entry");
    
    LLVMBuilderRef builder = LLVMCreateBuilder();
    LLVMPositionBuilderAtEnd(builder, entry);
    LLVMValueRef tmp = LLVMBuildAdd(builder, 
                            LLVMGetParam(sum, 0), 
                            LLVMGetParam(sum, 1), "tmp");
    LLVMBuildRet(builder, tmp);

    char *error = NULL;
    LLVMVerifyModule(mod, LLVMAbortProcessAction, &error);
    LLVMDisposeMessage(error);

    LLVMExecutionEngineRef engine;
    error = NULL;
    LLVMLinkInJIT();
    LLVMInitializeNativeTarget();
    if (LLVMCreateExecutionEngineForModule(&engine, mod, &error) != 0) {
        fprintf(stderr, "failed to create execution engine\n");
        abort();
    }
    if (error) {
        fprintf(stderr, "error: %s\n", error);
        LLVMDisposeMessage(error);
        exit(EXIT_FAILURE);
    }

    if (argc < 3) {
        fprintf(stderr, "usage: %s x y\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    long long x = strtoll(argv[1], NULL, 10);
    long long y = strtoll(argv[2], NULL, 10);

    LLVMGenericValueRef args[] = {
        LLVMCreateGenericValueOfInt(LLVMInt32Type(), x, 0),
        LLVMCreateGenericValueOfInt(LLVMInt32Type(), y, 0),
    };
    LLVMGenericValueRef res = LLVMRunFunction(engine, sum,  2, args);
    printf("%d\n", (int)LLVMGenericValueToInt(res, 0));

    // write bitcode to file
    if (LLVMWriteBitcodeToFile(mod, "sum.bc") != 0) {
        fprintf(stderr, "error writing bitcode to file\n");
    }

    LLVMDisposeBuilder(builder);
    LLVMDisposeExecutionEngine(engine);
}
Пример #12
0
static LLVMValueRef
CreateFibFunction(LLVMModuleRef M, LLVMContextRef Context)
{
	LLVMBuilderRef B = LLVMCreateBuilderInContext(Context);

	// Create the fib function and insert it into module M. This function is said
	// to return an int and take an int parameter.
	LLVMTypeRef  ParamTypes[] = {LLVMInt32TypeInContext(Context)};
	LLVMTypeRef  ReturnType   = LLVMInt32TypeInContext(Context);
	LLVMTypeRef  FunctionTy   = LLVMFunctionType(ReturnType, ParamTypes, 1, 0);
	LLVMValueRef FibF         = LLVMAddFunction(M, "fib", FunctionTy);

	// Add a basic block to the function.
	LLVMBasicBlockRef BB = LLVMAppendBasicBlockInContext(Context, FibF, "EntryBlock");

	// Get pointers to the constants.
	LLVMValueRef One = LLVMConstInt(LLVMInt32TypeInContext(Context), 1, 0);
	LLVMValueRef Two = LLVMConstInt(LLVMInt32TypeInContext(Context), 2, 0);

	// Get pointer to the integer argument of the add1 function...
	LLVMValueRef ArgX = LLVMGetFirstParam(FibF); // Get the arg.
	LLVMSetValueName(ArgX, "AnArg");             // Give it a nice symbolic name for fun.

	// Create the true_block.
	LLVMBasicBlockRef RetBB = LLVMAppendBasicBlockInContext(Context, FibF, "return");

	// Create an exit block.
	LLVMBasicBlockRef RecurseBB = LLVMAppendBasicBlockInContext(Context, FibF, "recurse");

	// Create the "if (arg <= 2) goto exitbb"
	LLVMPositionBuilderAtEnd(B, BB);
	LLVMValueRef CondInst = LLVMBuildICmp(B, LLVMIntSLE, ArgX, Two, "cond");
	LLVMBuildCondBr(B, CondInst, RetBB, RecurseBB);

	// Create: ret int 1
	LLVMPositionBuilderAtEnd(B, RetBB);
	LLVMBuildRet(B, One);

	// create fib(x-1)
	LLVMPositionBuilderAtEnd(B, RecurseBB);
	LLVMValueRef Sub       = LLVMBuildSub(B, ArgX, One, "arg");
	LLVMValueRef CallFibX1 = LLVMBuildCall(B, FibF, &Sub, 1, "fibx1");
	LLVMSetTailCall(CallFibX1, 1);

	// create fib(x-2)
	LLVMPositionBuilderAtEnd(B, RecurseBB);
	Sub                    = LLVMBuildSub(B, ArgX, Two, "arg");
	LLVMValueRef CallFibX2 = LLVMBuildCall(B, FibF, &Sub, 1, "fibx2");
	LLVMSetTailCall(CallFibX2, 1);

	// fib(x-1)+fib(x-2)
	LLVMPositionBuilderAtEnd(B, RecurseBB);
	LLVMValueRef Sum = LLVMBuildAdd(B, CallFibX1, CallFibX2, "addresult");

	// Create the return instruction and add it to the basic block
	LLVMPositionBuilderAtEnd(B, RecurseBB);
	LLVMBuildRet(B, Sum);

	return FibF;
}
Пример #13
0
static LLVMValueRef
add_blend_test(struct gallivm_state *gallivm,
               const struct pipe_blend_state *blend,
               struct lp_type type)
{
   LLVMModuleRef module = gallivm->module;
   LLVMContextRef context = gallivm->context;
   LLVMTypeRef vec_type;
   LLVMTypeRef args[5];
   LLVMValueRef func;
   LLVMValueRef src_ptr;
   LLVMValueRef src1_ptr;
   LLVMValueRef dst_ptr;
   LLVMValueRef const_ptr;
   LLVMValueRef res_ptr;
   LLVMBasicBlockRef block;
   LLVMBuilderRef builder;
   const enum pipe_format format = PIPE_FORMAT_R8G8B8A8_UNORM;
   const unsigned rt = 0;
   const unsigned char swizzle[4] = { 0, 1, 2, 3 };
   LLVMValueRef src;
   LLVMValueRef src1;
   LLVMValueRef dst;
   LLVMValueRef con;
   LLVMValueRef res;

   vec_type = lp_build_vec_type(gallivm, type);

   args[4] = args[3] = args[2] = args[1] = args[0] = LLVMPointerType(vec_type, 0);
   func = LLVMAddFunction(module, "test", LLVMFunctionType(LLVMVoidTypeInContext(context), args, 5, 0));
   LLVMSetFunctionCallConv(func, LLVMCCallConv);
   src_ptr = LLVMGetParam(func, 0);
   src1_ptr = LLVMGetParam(func, 1);
   dst_ptr = LLVMGetParam(func, 2);
   const_ptr = LLVMGetParam(func, 3);
   res_ptr = LLVMGetParam(func, 4);

   block = LLVMAppendBasicBlockInContext(context, func, "entry");
   builder = gallivm->builder;
   LLVMPositionBuilderAtEnd(builder, block);

   src = LLVMBuildLoad(builder, src_ptr, "src");
   src1 = LLVMBuildLoad(builder, src1_ptr, "src1");
   dst = LLVMBuildLoad(builder, dst_ptr, "dst");
   con = LLVMBuildLoad(builder, const_ptr, "const");

   res = lp_build_blend_aos(gallivm, blend, format, type, rt, src, NULL,
                            src1, NULL, dst, NULL, con, NULL, swizzle, 4);

   lp_build_name(res, "res");

   LLVMBuildStore(builder, res, res_ptr);

   LLVMBuildRetVoid(builder);;

   gallivm_verify_function(gallivm, func);

   return func;
}
Пример #14
0
static LLVMValueRef declare_ffi_vararg(compile_t* c, const char* f_name,
  reach_type_t* t)
{
  LLVMTypeRef r_type = ffi_return_type(c, t, false);
  LLVMTypeRef f_type = LLVMFunctionType(r_type, NULL, 0, true);
  LLVMValueRef func = LLVMAddFunction(c->module, f_name, f_type);

  return func;
}
Пример #15
0
int main (void) {
    LLVMModuleRef module = LLVMModuleCreateWithName("kal");
    LLVMBuilderRef builder = LLVMCreateBuilder();
//	LLVMInitializeNativeTarget();

	LLVMTypeRef funcType = LLVMFunctionType(LLVMVoidType(), NULL, 0, 0);
	LLVMValueRef func = LLVMAddFunction(module, "main", funcType);
	LLVMSetLinkage(func, LLVMExternalLinkage);
	LLVMBasicBlockRef block = LLVMAppendBasicBlock(func, "entry");
	LLVMPositionBuilderAtEnd(builder, block);

	LLVMValueRef cond = LLVMBuildICmp(builder, LLVMIntNE, LLVMConstInt(LLVMInt32Type(), 2, 0), LLVMConstInt(LLVMInt32Type(), 1, 0), "ifcond");

	LLVMValueRef owning_block = LLVMGetBasicBlockParent(LLVMGetInsertBlock(builder));	//TODO: WRONG??
	//LLVMValueRef owning_block = LLVMBasicBlockAsValue(LLVMGetPreviousBasicBlock(LLVMGetInsertBlock(builder)));
	// 2. Generate new blocks for cases.
	LLVMBasicBlockRef then_ref = LLVMAppendBasicBlock(owning_block, "then");
	LLVMBasicBlockRef else_ref = LLVMAppendBasicBlock(owning_block, "else");
	LLVMBasicBlockRef merge_ref = LLVMAppendBasicBlock(owning_block, "ifmerge");

	// 3. Branch conditionally on then or else.
	LLVMBuildCondBr(builder, cond, then_ref, else_ref);

	// 4. Build then branch prologue.
	LLVMPositionBuilderAtEnd(builder, then_ref);

	LLVMValueRef hi1 = LLVMBuildXor(builder, LLVMGetUndef(LLVMInt32Type()), LLVMGetUndef(LLVMInt32Type()), "subtmp");

	// 5. Connect then branch to merge block.
	LLVMBuildBr(builder, merge_ref);

	then_ref = LLVMGetInsertBlock(builder);

	// 6. Build else branch prologue.
	LLVMPositionBuilderAtEnd(builder, else_ref);

	LLVMValueRef hi2 = LLVMBuildXor(builder, LLVMGetUndef(LLVMInt32Type()), LLVMGetUndef(LLVMInt32Type()), "subtmp2");

	// 7. Connect else branch to merge block.
	LLVMBuildBr(builder, merge_ref);

	else_ref = LLVMGetInsertBlock(builder);
	// 8. Position ourselves after the merge block.
	LLVMPositionBuilderAtEnd(builder, merge_ref);
	// 9. Build the phi node.
//	LLVMValueRef phi = LLVMBuildPhi(builder, LLVMDoubleType(), "phi");
	// 10. Add incoming edges.
//	LLVMAddIncoming(phi, &hi1, &then_ref, 1);
//	LLVMAddIncoming(phi, &hi2, &else_ref, 1);

	LLVMDumpModule(module);
	LLVMDisposeBuilder(builder);
	LLVMDisposeModule(module);

	return 0;
}
Пример #16
0
static LLVMValueRef declare_ffi_vararg(compile_t* c, const char* f_name,
  gentype_t* g, bool err)
{
  LLVMTypeRef f_type = LLVMFunctionType(g->use_type, NULL, 0, true);
  LLVMValueRef func = LLVMAddFunction(c->module, f_name, f_type);

  if(!err)
    LLVMAddFunctionAttr(func, LLVMNoUnwindAttribute);

  return func;
}
static LLVMValueRef
add_conv_test(struct gallivm_state *gallivm,
              struct lp_type src_type, unsigned num_srcs,
              struct lp_type dst_type, unsigned num_dsts)
{
   LLVMModuleRef module = gallivm->module;
   LLVMContextRef context = gallivm->context;
   LLVMBuilderRef builder = gallivm->builder;
   LLVMTypeRef args[2];
   LLVMValueRef func;
   LLVMValueRef src_ptr;
   LLVMValueRef dst_ptr;
   LLVMBasicBlockRef block;
   LLVMValueRef src[LP_MAX_VECTOR_LENGTH];
   LLVMValueRef dst[LP_MAX_VECTOR_LENGTH];
   unsigned i;

   args[0] = LLVMPointerType(lp_build_vec_type(gallivm, src_type), 0);
   args[1] = LLVMPointerType(lp_build_vec_type(gallivm, dst_type), 0);

   func = LLVMAddFunction(module, "test",
                          LLVMFunctionType(LLVMVoidTypeInContext(context),
                                           args, 2, 0));
   LLVMSetFunctionCallConv(func, LLVMCCallConv);
   src_ptr = LLVMGetParam(func, 0);
   dst_ptr = LLVMGetParam(func, 1);

   block = LLVMAppendBasicBlockInContext(context, func, "entry");
   LLVMPositionBuilderAtEnd(builder, block);

   for(i = 0; i < num_srcs; ++i) {
      LLVMValueRef index = LLVMConstInt(LLVMInt32TypeInContext(context), i, 0);
      LLVMValueRef ptr = LLVMBuildGEP(builder, src_ptr, &index, 1, "");
      src[i] = LLVMBuildLoad(builder, ptr, "");
   }

   lp_build_conv(gallivm, src_type, dst_type, src, num_srcs, dst, num_dsts);

   for(i = 0; i < num_dsts; ++i) {
      LLVMValueRef index = LLVMConstInt(LLVMInt32TypeInContext(context), i, 0);
      LLVMValueRef ptr = LLVMBuildGEP(builder, dst_ptr, &index, 1, "");
      LLVMBuildStore(builder, dst[i], ptr);
   }

   LLVMBuildRetVoid(builder);;

   gallivm_verify_function(gallivm, func);

   return func;
}
Пример #18
0
SCM make_llvm_function(SCM scm_llvm, SCM scm_return_type, SCM scm_name, SCM scm_argument_types)
{
  SCM retval;
  struct llvm_module_t *llvm = get_llvm(scm_llvm);
  struct llvm_function_t *self;
  self = (struct llvm_function_t *)scm_gc_calloc(sizeof(struct llvm_function_t), "llvm function");
  SCM_NEWSMOB(retval, llvm_function_tag, self);
  self->builder = LLVMCreateBuilder();
  char *name = scm_to_locale_string(scm_name);
  self->function = LLVMAddFunction(llvm->module, name, function_type(scm_return_type, scm_argument_types));
  LLVMSetFunctionCallConv(self->function, LLVMCCallConv);
  free(name);
  return retval;
}
Пример #19
0
/**
 * lp_build_assert.
 *
 * Build an assertion in LLVM IR by building a function call to the
 * lp_assert() function above.
 *
 * \param condition should be an 'i1' or 'i32' value
 * \param msg  a string to print if the assertion fails.
 */
LLVMValueRef
lp_build_assert(LLVMBuilderRef builder, LLVMValueRef condition,
                const char *msg)
{
   LLVMModuleRef module;
   LLVMTypeRef arg_types[2];
   LLVMValueRef msg_string, assert_func, params[2], r;

   module = LLVMGetGlobalParent(LLVMGetBasicBlockParent(
                            LLVMGetInsertBlock(builder)));

   msg_string = lp_build_const_string_variable(module, msg, strlen(msg) + 1);

   arg_types[0] = LLVMInt32Type();
   arg_types[1] = LLVMPointerType(LLVMInt8Type(), 0);

   /* lookup the lp_assert function */
   assert_func = LLVMGetNamedFunction(module, "lp_assert");

   /* Create the assertion function if not found */
   if (!assert_func) {
      LLVMTypeRef func_type =
         LLVMFunctionType(LLVMVoidType(), arg_types, 2, 0);

      assert_func = LLVMAddFunction(module, "lp_assert", func_type);
      LLVMSetFunctionCallConv(assert_func, LLVMCCallConv);
      LLVMSetLinkage(assert_func, LLVMExternalLinkage);
      LLVMAddGlobalMapping(lp_build_engine, assert_func,
                           func_to_pointer((func_pointer)lp_assert));
   }
   assert(assert_func);

   /* build function call param list */
   params[0] = LLVMBuildZExt(builder, condition, arg_types[0], "");
   params[1] = LLVMBuildBitCast(builder, msg_string, arg_types[1], "");

   /* check arg types */
   assert(LLVMTypeOf(params[0]) == arg_types[0]);
   assert(LLVMTypeOf(params[1]) == arg_types[1]);

   r = LLVMBuildCall(builder, assert_func, params, 2, "");

   return r;
}
Пример #20
0
LLVMValueRef codegen_addfun(compile_t* c, const char* name, LLVMTypeRef type,
  bool pony_abi)
{
  // Add the function and set the calling convention and the linkage type.
  LLVMValueRef fun = LLVMAddFunction(c->module, name, type);
  LLVMSetFunctionCallConv(fun, c->callconv);
  LLVMSetLinkage(fun, c->linkage);
  LLVMSetUnnamedAddr(fun, true);

  if(pony_abi)
  {
    LLVMValueRef md = LLVMMDNodeInContext(c->context, NULL, 0);
    LLVMSetMetadataStr(fun, "pony.abi", md);
  }

  LLVMValueRef arg = LLVMGetFirstParam(fun);
  uint32_t i = 1;

  while(arg != NULL)
  {
    LLVMTypeRef type = LLVMTypeOf(arg);

    if(LLVMGetTypeKind(type) == LLVMPointerTypeKind)
    {
      LLVMTypeRef elem = LLVMGetElementType(type);

      if(LLVMGetTypeKind(elem) == LLVMStructTypeKind)
      {
        size_t size = (size_t)LLVMABISizeOfType(c->target_data, elem);
#if PONY_LLVM >= 309
        LLVM_DECLARE_ATTRIBUTEREF(deref_attr, dereferenceable, size);
        LLVMAddAttributeAtIndex(fun, i, deref_attr);
#else
        LLVMSetDereferenceable(fun, i, size);
#endif
      }
    }

    arg = LLVMGetNextParam(arg);
    i++;
  }

  return fun;
}
Пример #21
0
static LLVMValueRef declare_ffi_vararg(compile_t* c, const char* f_name,
  reach_type_t* t, bool err)
{
  LLVMTypeRef f_type = LLVMFunctionType(t->use_type, NULL, 0, true);
  LLVMValueRef func = LLVMAddFunction(c->module, f_name, f_type);

  if(!err)
  {
#if PONY_LLVM >= 309
    LLVM_DECLARE_ATTRIBUTEREF(nounwind_attr, nounwind, 0);

    LLVMAddAttributeAtIndex(func, LLVMAttributeFunctionIndex, nounwind_attr);
#else
    LLVMAddFunctionAttr(func, LLVMNoUnwindAttribute);
#endif
  }

  return func;
}
Пример #22
0
SCM llvm_build_call(SCM scm_function, SCM scm_llvm, SCM scm_return_type, SCM scm_function_name, SCM scm_argument_types, SCM scm_values)
{
  SCM retval;
  struct llvm_function_t *function = get_llvm_function(scm_function);
  struct llvm_module_t *llvm = get_llvm(scm_llvm);
  char *function_name = scm_to_locale_string(scm_function_name);
  LLVMValueRef function_pointer = LLVMAddFunction(llvm->module, function_name, function_type(scm_return_type, scm_argument_types));
  free(function_name);
  // LLVMAddFunctionAttr(function_pointer, LLVMExternalLinkage);
  int n_values = scm_ilength(scm_values);
  LLVMValueRef *values = scm_gc_malloc_pointerless(n_values * sizeof(LLVMValueRef), "llvm-build-call");
  for (int i=0; i<n_values; i++) {
    values[i] = get_llvm_value(scm_car(scm_values))->value;
    scm_values = scm_cdr(scm_values);
  };
  struct llvm_value_t *result = (struct llvm_value_t *)scm_gc_calloc(sizeof(struct llvm_value_t), "llvmvalue");
  SCM_NEWSMOB(retval, llvm_value_tag, result);
  result->value = LLVMBuildCall(function->builder, function_pointer, values, n_values, "x");
  return retval;
}
Пример #23
0
JITInstructionFunction_t JITImpl::getFunctionThunk(JITFunctionInfo &info)
{
  LLVMValueRef f = LLVMAddFunction(module, "", jitFunctionType);
  LLVMValueRef thread = LLVMGetParam(f, 0);
  LLVMBasicBlockRef entryBB = LLVMAppendBasicBlock(f, "entry");
  LLVMPositionBuilderAtEnd(builder, entryBB);
  LLVMValueRef args[] = {
    thread
  };
  LLVMValueRef call = LLVMBuildCall(builder, info.value, args, 1, "");
  LLVMSetTailCall(call, true);
  LLVMSetInstructionCallConv(call, LLVMFastCallConv);
  LLVMBuildRet(builder, call);
  if (DEBUG_JIT) {
    LLVMDumpValue(f);
    LLVMVerifyFunction(f, LLVMAbortProcessAction);
  }
  return reinterpret_cast<JITInstructionFunction_t>(
    LLVMGetPointerToGlobal(executionEngine, f));
}
Пример #24
0
/**
 * lp_build_printf.
 *
 * Build printf call in LLVM IR. The output goes to stdout.
 * The additional variable arguments need to have type
 * LLVMValueRef.
 */
LLVMValueRef
lp_build_printf(struct gallivm_state *gallivm, const char *fmt, ...)
{
   va_list arglist;
   int i = 0;
   int argcount = lp_get_printf_arg_count(fmt);
   LLVMBuilderRef builder = gallivm->builder;
   LLVMContextRef context = gallivm->context;
   LLVMModuleRef module = gallivm->module;
   LLVMValueRef params[50];
   LLVMValueRef fmtarg = lp_build_const_string_variable(module, context,
                                                        fmt, strlen(fmt) + 1);
   LLVMValueRef int0 = lp_build_const_int32(gallivm, 0);
   LLVMValueRef index[2];
   LLVMValueRef func_printf = LLVMGetNamedFunction(module, "printf");

   assert(Elements(params) >= argcount + 1);

   index[0] = index[1] = int0;

   if (!func_printf) {
      LLVMTypeRef printf_type = LLVMFunctionType(LLVMIntTypeInContext(context, 32), NULL, 0, 1);
      func_printf = LLVMAddFunction(module, "printf", printf_type);
   }

   params[0] = LLVMBuildGEP(builder, fmtarg, index, 2, "");

   va_start(arglist, fmt);
   for (i = 1; i <= argcount; i++) {
      LLVMValueRef val = va_arg(arglist, LLVMValueRef);
      LLVMTypeRef type = LLVMTypeOf(val);
      /* printf wants doubles, so lets convert so that
       * we can actually print them */
      if (LLVMGetTypeKind(type) == LLVMFloatTypeKind)
         val = LLVMBuildFPExt(builder, val, LLVMDoubleTypeInContext(context), "");
      params[i] = val;
   }
   va_end(arglist);

   return LLVMBuildCall(builder, func_printf, params, argcount + 1, "");
}
Пример #25
0
LLVMValueRef
lp_declare_intrinsic(LLVMModuleRef module,
                     const char *name,
                     LLVMTypeRef ret_type,
                     LLVMTypeRef *arg_types,
                     unsigned num_args)
{
   LLVMTypeRef function_type;
   LLVMValueRef function;

   assert(!LLVMGetNamedFunction(module, name));

   function_type = LLVMFunctionType(ret_type, arg_types, num_args, 0);
   function = LLVMAddFunction(module, name, function_type);

   LLVMSetFunctionCallConv(function, LLVMCCallConv);
   LLVMSetLinkage(function, LLVMExternalLinkage);

   assert(LLVMIsDeclaration(function));

   return function;
}
Пример #26
0
static LLVMValueRef declare_ffi(compile_t* c, const char* f_name,
  reach_type_t* t, ast_t* args, bool intrinsic)
{
  ast_t* last_arg = ast_childlast(args);

  if((last_arg != NULL) && (ast_id(last_arg) == TK_ELLIPSIS))
    return declare_ffi_vararg(c, f_name, t);

  int count = (int)ast_childcount(args);
  size_t buf_size = count * sizeof(LLVMTypeRef);
  LLVMTypeRef* f_params = (LLVMTypeRef*)ponyint_pool_alloc_size(buf_size);
  count = 0;

  ast_t* arg = ast_child(args);

  deferred_reification_t* reify = c->frame->reify;

  while(arg != NULL)
  {
    ast_t* p_type = ast_type(arg);

    if(p_type == NULL)
      p_type = ast_childidx(arg, 1);

    p_type = deferred_reify(reify, p_type, c->opt);
    reach_type_t* pt = reach_type(c->reach, p_type);
    pony_assert(pt != NULL);
    f_params[count++] = ((compile_type_t*)pt->c_type)->use_type;
    ast_free_unattached(p_type);
    arg = ast_sibling(arg);
  }

  LLVMTypeRef r_type = ffi_return_type(c, t, intrinsic);
  LLVMTypeRef f_type = LLVMFunctionType(r_type, f_params, count, false);
  LLVMValueRef func = LLVMAddFunction(c->module, f_name, f_type);

  ponyint_pool_free_size(buf_size, f_params);
  return func;
}
/*
 * Build LLVM function that exercises the unary operator builder.
 */
static LLVMValueRef
build_unary_test_func(struct gallivm_state *gallivm,
                      const struct unary_test_t *test)
{
   struct lp_type type = lp_type_float_vec(32, lp_native_vector_width);
   LLVMContextRef context = gallivm->context;
   LLVMModuleRef module = gallivm->module;
   LLVMTypeRef vf32t = lp_build_vec_type(gallivm, type);
   LLVMTypeRef args[2] = { LLVMPointerType(vf32t, 0), LLVMPointerType(vf32t, 0) };
   LLVMValueRef func = LLVMAddFunction(module, test->name,
                                       LLVMFunctionType(LLVMVoidTypeInContext(context),
                                                        args, Elements(args), 0));
   LLVMValueRef arg0 = LLVMGetParam(func, 0);
   LLVMValueRef arg1 = LLVMGetParam(func, 1);
   LLVMBuilderRef builder = gallivm->builder;
   LLVMBasicBlockRef block = LLVMAppendBasicBlockInContext(context, func, "entry");
   LLVMValueRef ret;

   struct lp_build_context bld;

   lp_build_context_init(&bld, gallivm, type);

   LLVMSetFunctionCallConv(func, LLVMCCallConv);

   LLVMPositionBuilderAtEnd(builder, block);
   
   arg1 = LLVMBuildLoad(builder, arg1, "");

   ret = test->builder(&bld, arg1);
   
   LLVMBuildStore(builder, ret, arg0);

   LLVMBuildRetVoid(builder);

   gallivm_verify_function(gallivm, func);

   return func;
}
Пример #28
0
static LLVMValueRef zephir_get_add_function(zephir_context *context)
{
	LLVMValueRef    function;
	LLVMTypeRef arg_tys[3];

	function = LLVMGetNamedFunction(context->module, "add_function");
	if (!function) {

		arg_tys[0] = context->types.zval_pointer_type;
		arg_tys[1] = context->types.zval_pointer_type;
		arg_tys[2] = context->types.zval_pointer_type;
		function = LLVMAddFunction(context->module, "add_function", LLVMFunctionType(LLVMVoidType(), arg_tys, 3, 0));
		if (!function) {
			zend_error(E_ERROR, "Cannot register add_function");
		}

		LLVMAddGlobalMapping(context->engine, function, add_function);
		LLVMSetFunctionCallConv(function, LLVMCCallConv);
		LLVMAddFunctionAttr(function, LLVMNoUnwindAttribute);
	}

	return function;
}
Пример #29
0
LLVMValueRef codegen_addfun(compile_t* c, const char* name, LLVMTypeRef type)
{
  // Add the function and set the calling convention.
  LLVMValueRef fun = LLVMAddFunction(c->module, name, type);

  if(!c->opt->library)
    LLVMSetFunctionCallConv(fun, GEN_CALLCONV);

  LLVMValueRef arg = LLVMGetFirstParam(fun);
  uint32_t i = 1;

  while(arg != NULL)
  {
    LLVMTypeRef type = LLVMTypeOf(arg);

    if(LLVMGetTypeKind(type) == LLVMPointerTypeKind)
    {
      LLVMTypeRef elem = LLVMGetElementType(type);

      if(LLVMGetTypeKind(elem) == LLVMStructTypeKind)
      {
        uint64_t size = LLVMABISizeOfType(c->target_data, elem);
        LLVMSetDereferenceable(fun, i, size);
      }

      // Set the noalias attribute on all arguments. This is fortran-like
      // semantics for parameter aliasing, similar to C restrict.
      if(!c->opt->no_restrict)
        LLVMAddAttribute(arg, LLVMNoAliasAttribute);
    }

    arg = LLVMGetNextParam(arg);
    i++;
  }

  return fun;
}
Пример #30
0
oFunctionOverloadRef _oFunctionOverloadRegisterNative(oThreadContextRef ctx,
                                                      oSignatureRef sig,
                                                      oArrayRef attributes,
                                                      pointer fn) {
    oFunctionOverloadRef overload;
	char* un;
    
    // Allocate in shared heap
    overload = (oFunctionOverloadRef)o_bootstrap_object_alloc(ctx->runtime, ctx->runtime->builtInTypes.functionOverload, sizeof(oFunctionOverload));
    if(overload == NULL) {
        ctx->error = ctx->runtime->builtInErrors.outOfMemory;
        return NULL;
    }

	if(attributes) {
		overload->attributes = _oHeapCopyObjectShared(ctx, attributes);
		if(overload->attributes == NULL) {
			return NULL;
		}
	}

    overload->signature = _oHeapCopyObjectShared(ctx, sig);
    if(overload->signature == NULL) {
        return NULL;
    }

    overload->code = fn;
	un = oGenUniqueName(ctx);
    if(un == NULL) {
        ctx->error = ctx->runtime->builtInErrors.outOfMemory;
        return NULL;
    }
	overload->llvmFunction = LLVMAddFunction(ctx->runtime->llvmModule, un, llvmTypeForSignature(ctx, sig));
	oFree(un);
	LLVMAddGlobalMapping(ctx->runtime->llvmEE, overload->llvmFunction, fn);
    return overload;
}