// Recursively generates LLVM code for the literal integer AST node. // // node - The node to generate an LLVM value for. // module - The compilation unit this node is a part of. // value - A pointer to where the LLVM value should be returned. // // Returns 0 if successful, otherwise returns -1. int qip_ast_int_literal_codegen(qip_ast_node *node, qip_module *module, LLVMValueRef *value) { LLVMContextRef context = LLVMGetModuleContext(module->llvm_module); *value = LLVMConstInt(LLVMInt64TypeInContext(context), node->int_literal.value, true); return 0; }
static LLVMValueRef llvm_load_const_buffer( struct lp_build_tgsi_context * bld_base, LLVMValueRef OffsetValue, unsigned ConstantAddressSpace) { LLVMValueRef offset[2] = { LLVMConstInt(LLVMInt64TypeInContext(bld_base->base.gallivm->context), 0, false), OffsetValue }; LLVMTypeRef const_ptr_type = LLVMPointerType(LLVMArrayType(LLVMVectorType(bld_base->base.elem_type, 4), 1024), ConstantAddressSpace); LLVMValueRef const_ptr = LLVMBuildIntToPtr(bld_base->base.gallivm->builder, lp_build_const_int32(bld_base->base.gallivm, 0), const_ptr_type, ""); LLVMValueRef ptr = LLVMBuildGEP(bld_base->base.gallivm->builder, const_ptr, offset, 2, ""); return LLVMBuildLoad(bld_base->base.gallivm->builder, ptr, ""); }
LLVMTypeRef ty_class_indirect() { if(indirect_struct_type) return indirect_struct_type; indirect_struct_type = LLVMStructCreateNamed(utl_get_current_context(), "__egl_class_indirect"); LLVMTypeRef tys[] = { LLVMInt32TypeInContext(utl_get_current_context()), LLVMPointerType(LLVMPointerType(LLVMInt8TypeInContext(utl_get_current_context()), 0), 0), LLVMPointerType(LLVMInt64TypeInContext(utl_get_current_context()), 0), LLVMPointerType(LLVMPointerType(LLVMInt8TypeInContext(utl_get_current_context()), 0), 0) }; LLVMStructSetBody(indirect_struct_type, tys, 4, 0); return indirect_struct_type; }
static void update_cache_access(struct gallivm_state *gallivm, LLVMValueRef ptr, unsigned count, unsigned index) { LLVMBuilderRef builder = gallivm->builder; LLVMValueRef member_ptr, cache_access; assert(index == LP_BUILD_FORMAT_CACHE_MEMBER_ACCESS_TOTAL || index == LP_BUILD_FORMAT_CACHE_MEMBER_ACCESS_MISS); member_ptr = lp_build_struct_get_ptr(gallivm, ptr, index, ""); cache_access = LLVMBuildLoad(builder, member_ptr, "cache_access"); cache_access = LLVMBuildAdd(builder, cache_access, LLVMConstInt(LLVMInt64TypeInContext(gallivm->context), count, 0), ""); LLVMBuildStore(builder, cache_access, member_ptr); }
LLVMTypeRef ett_llvm_type(EagleComplexType *type) { switch(type->type) { case ETVoid: return LLVMVoidTypeInContext(utl_get_current_context()); case ETFloat: return LLVMFloatTypeInContext(utl_get_current_context()); case ETDouble: return LLVMDoubleTypeInContext(utl_get_current_context()); case ETInt1: return LLVMInt1TypeInContext(utl_get_current_context()); case ETGeneric: // In practice this doesn't matter case ETAny: case ETInt8: case ETUInt8: return LLVMInt8TypeInContext(utl_get_current_context()); case ETInt16: case ETUInt16: return LLVMInt16TypeInContext(utl_get_current_context()); case ETInt32: case ETUInt32: return LLVMInt32TypeInContext(utl_get_current_context()); case ETInt64: case ETUInt64: return LLVMInt64TypeInContext(utl_get_current_context()); case ETCString: return LLVMPointerType(LLVMInt8TypeInContext(utl_get_current_context()), 0); case ETEnum: return LLVMInt64TypeInContext(utl_get_current_context()); case ETGenerator: { if(generator_type) return generator_type; LLVMTypeRef ptmp[2]; ptmp[0] = LLVMPointerType(LLVMInt8TypeInContext(utl_get_current_context()), 0); ptmp[1] = LLVMPointerType(LLVMInt8TypeInContext(utl_get_current_context()), 0); generator_type = LLVMStructCreateNamed(utl_get_current_context(), "__egl_gen_strct"); LLVMStructSetBody(generator_type, ptmp, 2, 0); return generator_type; } case ETClass: case ETStruct: { EagleStructType *st = (EagleStructType *)type; LLVMTypeRef loaded = LLVMGetTypeByName(the_module, st->name); if(loaded) return loaded; return NULL; // LLVMTypeRef ty = LLVMStructTypeInContext(utl_get_current_context(), } case ETInterface: { return LLVMInt8TypeInContext(utl_get_current_context()); } case ETPointer: { EaglePointerType *pt = (EaglePointerType *)type; if(pt->counted || pt->weak) { LLVMTypeRef ptmp[2]; ptmp[0] = LLVMPointerType(LLVMInt8TypeInContext(utl_get_current_context()), 0); ptmp[1] = LLVMInt1TypeInContext(utl_get_current_context()); LLVMTypeRef tys[6]; tys[0] = LLVMInt64TypeInContext(utl_get_current_context()); tys[1] = LLVMInt16TypeInContext(utl_get_current_context()); tys[2] = LLVMInt16TypeInContext(utl_get_current_context()); tys[3] = LLVMPointerType(LLVMInt8TypeInContext(utl_get_current_context()), 0); tys[4] = LLVMPointerType(LLVMFunctionType(LLVMVoidTypeInContext(utl_get_current_context()), ptmp, 2, 0), 0); tys[5] = ett_llvm_type(pt->to); return LLVMPointerType(ty_get_counted(LLVMStructTypeInContext(utl_get_current_context(), tys, 6, 0)), 0); } return LLVMPointerType(ett_llvm_type(((EaglePointerType *)type)->to), 0); } case ETArray: { EagleArrayType *at = (EagleArrayType *)type; if(at->ct < 0) return LLVMPointerType(ett_llvm_type(at->of), 0); else return LLVMArrayType(ett_llvm_type(at->of), at->ct); } case ETFunction: { EagleFunctionType *ft = (EagleFunctionType *)type; if(ET_IS_CLOSURE(type)) { LLVMTypeRef tys[2]; tys[0] = LLVMPointerType(LLVMInt8TypeInContext(utl_get_current_context()), 0); tys[1] = LLVMPointerType(LLVMInt8TypeInContext(utl_get_current_context()), 0); return LLVMStructTypeInContext(utl_get_current_context(), tys, 2, 0); } LLVMTypeRef *tys = malloc(sizeof(LLVMTypeRef) * ft->pct); int i; for(i = 0; i < ft->pct; i++) tys[i] = ett_llvm_type(ft->params[i]); LLVMTypeRef out = LLVMFunctionType(ett_llvm_type(ft->retType), tys, ft->pct, 0); free(tys); return out; } default: return NULL; } }
static void lp_jit_create_types(struct lp_fragment_shader_variant *lp) { struct gallivm_state *gallivm = lp->gallivm; LLVMContextRef lc = gallivm->context; LLVMTypeRef viewport_type, texture_type, sampler_type; /* struct lp_jit_viewport */ { LLVMTypeRef elem_types[LP_JIT_VIEWPORT_NUM_FIELDS]; elem_types[LP_JIT_VIEWPORT_MIN_DEPTH] = elem_types[LP_JIT_VIEWPORT_MAX_DEPTH] = LLVMFloatTypeInContext(lc); viewport_type = LLVMStructTypeInContext(lc, elem_types, Elements(elem_types), 0); LP_CHECK_MEMBER_OFFSET(struct lp_jit_viewport, min_depth, gallivm->target, viewport_type, LP_JIT_VIEWPORT_MIN_DEPTH); LP_CHECK_MEMBER_OFFSET(struct lp_jit_viewport, max_depth, gallivm->target, viewport_type, LP_JIT_VIEWPORT_MAX_DEPTH); LP_CHECK_STRUCT_SIZE(struct lp_jit_viewport, gallivm->target, viewport_type); } /* struct lp_jit_texture */ { LLVMTypeRef elem_types[LP_JIT_TEXTURE_NUM_FIELDS]; elem_types[LP_JIT_TEXTURE_WIDTH] = elem_types[LP_JIT_TEXTURE_HEIGHT] = elem_types[LP_JIT_TEXTURE_DEPTH] = elem_types[LP_JIT_TEXTURE_FIRST_LEVEL] = elem_types[LP_JIT_TEXTURE_LAST_LEVEL] = LLVMInt32TypeInContext(lc); elem_types[LP_JIT_TEXTURE_BASE] = LLVMPointerType(LLVMInt8TypeInContext(lc), 0); elem_types[LP_JIT_TEXTURE_ROW_STRIDE] = elem_types[LP_JIT_TEXTURE_IMG_STRIDE] = elem_types[LP_JIT_TEXTURE_MIP_OFFSETS] = LLVMArrayType(LLVMInt32TypeInContext(lc), LP_MAX_TEXTURE_LEVELS); texture_type = LLVMStructTypeInContext(lc, elem_types, Elements(elem_types), 0); LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, width, gallivm->target, texture_type, LP_JIT_TEXTURE_WIDTH); LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, height, gallivm->target, texture_type, LP_JIT_TEXTURE_HEIGHT); LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, depth, gallivm->target, texture_type, LP_JIT_TEXTURE_DEPTH); LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, first_level, gallivm->target, texture_type, LP_JIT_TEXTURE_FIRST_LEVEL); LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, last_level, gallivm->target, texture_type, LP_JIT_TEXTURE_LAST_LEVEL); LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, base, gallivm->target, texture_type, LP_JIT_TEXTURE_BASE); LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, row_stride, gallivm->target, texture_type, LP_JIT_TEXTURE_ROW_STRIDE); LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, img_stride, gallivm->target, texture_type, LP_JIT_TEXTURE_IMG_STRIDE); LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, mip_offsets, gallivm->target, texture_type, LP_JIT_TEXTURE_MIP_OFFSETS); LP_CHECK_STRUCT_SIZE(struct lp_jit_texture, gallivm->target, texture_type); } /* struct lp_jit_sampler */ { LLVMTypeRef elem_types[LP_JIT_SAMPLER_NUM_FIELDS]; elem_types[LP_JIT_SAMPLER_MIN_LOD] = elem_types[LP_JIT_SAMPLER_MAX_LOD] = elem_types[LP_JIT_SAMPLER_LOD_BIAS] = LLVMFloatTypeInContext(lc); elem_types[LP_JIT_SAMPLER_BORDER_COLOR] = LLVMArrayType(LLVMFloatTypeInContext(lc), 4); sampler_type = LLVMStructTypeInContext(lc, elem_types, Elements(elem_types), 0); LP_CHECK_MEMBER_OFFSET(struct lp_jit_sampler, min_lod, gallivm->target, sampler_type, LP_JIT_SAMPLER_MIN_LOD); LP_CHECK_MEMBER_OFFSET(struct lp_jit_sampler, max_lod, gallivm->target, sampler_type, LP_JIT_SAMPLER_MAX_LOD); LP_CHECK_MEMBER_OFFSET(struct lp_jit_sampler, lod_bias, gallivm->target, sampler_type, LP_JIT_SAMPLER_LOD_BIAS); LP_CHECK_MEMBER_OFFSET(struct lp_jit_sampler, border_color, gallivm->target, sampler_type, LP_JIT_SAMPLER_BORDER_COLOR); LP_CHECK_STRUCT_SIZE(struct lp_jit_sampler, gallivm->target, sampler_type); } /* struct lp_jit_context */ { LLVMTypeRef elem_types[LP_JIT_CTX_COUNT]; LLVMTypeRef context_type; elem_types[LP_JIT_CTX_CONSTANTS] = LLVMArrayType(LLVMPointerType(LLVMFloatTypeInContext(lc), 0), LP_MAX_TGSI_CONST_BUFFERS); elem_types[LP_JIT_CTX_NUM_CONSTANTS] = LLVMArrayType(LLVMInt32TypeInContext(lc), LP_MAX_TGSI_CONST_BUFFERS); elem_types[LP_JIT_CTX_ALPHA_REF] = LLVMFloatTypeInContext(lc); elem_types[LP_JIT_CTX_STENCIL_REF_FRONT] = elem_types[LP_JIT_CTX_STENCIL_REF_BACK] = LLVMInt32TypeInContext(lc); elem_types[LP_JIT_CTX_U8_BLEND_COLOR] = LLVMPointerType(LLVMInt8TypeInContext(lc), 0); elem_types[LP_JIT_CTX_F_BLEND_COLOR] = LLVMPointerType(LLVMFloatTypeInContext(lc), 0); elem_types[LP_JIT_CTX_VIEWPORTS] = LLVMPointerType(viewport_type, 0); elem_types[LP_JIT_CTX_TEXTURES] = LLVMArrayType(texture_type, PIPE_MAX_SHADER_SAMPLER_VIEWS); elem_types[LP_JIT_CTX_SAMPLERS] = LLVMArrayType(sampler_type, PIPE_MAX_SAMPLERS); context_type = LLVMStructTypeInContext(lc, elem_types, Elements(elem_types), 0); LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, constants, gallivm->target, context_type, LP_JIT_CTX_CONSTANTS); LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, num_constants, gallivm->target, context_type, LP_JIT_CTX_NUM_CONSTANTS); LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, alpha_ref_value, gallivm->target, context_type, LP_JIT_CTX_ALPHA_REF); LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, stencil_ref_front, gallivm->target, context_type, LP_JIT_CTX_STENCIL_REF_FRONT); LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, stencil_ref_back, gallivm->target, context_type, LP_JIT_CTX_STENCIL_REF_BACK); LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, u8_blend_color, gallivm->target, context_type, LP_JIT_CTX_U8_BLEND_COLOR); LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, f_blend_color, gallivm->target, context_type, LP_JIT_CTX_F_BLEND_COLOR); LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, viewports, gallivm->target, context_type, LP_JIT_CTX_VIEWPORTS); LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, textures, gallivm->target, context_type, LP_JIT_CTX_TEXTURES); LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, samplers, gallivm->target, context_type, LP_JIT_CTX_SAMPLERS); LP_CHECK_STRUCT_SIZE(struct lp_jit_context, gallivm->target, context_type); lp->jit_context_ptr_type = LLVMPointerType(context_type, 0); } /* struct lp_jit_thread_data */ { LLVMTypeRef elem_types[LP_JIT_THREAD_DATA_COUNT]; LLVMTypeRef thread_data_type; elem_types[LP_JIT_THREAD_DATA_COUNTER] = LLVMInt64TypeInContext(lc); elem_types[LP_JIT_THREAD_DATA_RASTER_STATE_VIEWPORT_INDEX] = LLVMInt32TypeInContext(lc); thread_data_type = LLVMStructTypeInContext(lc, elem_types, Elements(elem_types), 0); lp->jit_thread_data_ptr_type = LLVMPointerType(thread_data_type, 0); } if (gallivm_debug & GALLIVM_DEBUG_IR) { LLVMDumpModule(gallivm->module); } }
static void init_runtime(compile_t* c) { c->str_builtin = stringtab("$0"); c->str_Bool = stringtab("Bool"); c->str_I8 = stringtab("I8"); c->str_I16 = stringtab("I16"); c->str_I32 = stringtab("I32"); c->str_I64 = stringtab("I64"); c->str_I128 = stringtab("I128"); c->str_ILong = stringtab("ILong"); c->str_ISize = stringtab("ISize"); c->str_U8 = stringtab("U8"); c->str_U16 = stringtab("U16"); c->str_U32 = stringtab("U32"); c->str_U64 = stringtab("U64"); c->str_U128 = stringtab("U128"); c->str_ULong = stringtab("ULong"); c->str_USize = stringtab("USize"); c->str_F32 = stringtab("F32"); c->str_F64 = stringtab("F64"); c->str_Pointer = stringtab("Pointer"); c->str_Maybe = stringtab("MaybePointer"); c->str_DoNotOptimise = stringtab("DoNotOptimise"); c->str_Array = stringtab("Array"); c->str_String = stringtab("String"); c->str_Platform = stringtab("Platform"); c->str_Main = stringtab("Main"); c->str_Env = stringtab("Env"); c->str_add = stringtab("add"); c->str_sub = stringtab("sub"); c->str_mul = stringtab("mul"); c->str_div = stringtab("div"); c->str_mod = stringtab("mod"); c->str_neg = stringtab("neg"); c->str_add_unsafe = stringtab("add_unsafe"); c->str_sub_unsafe = stringtab("sub_unsafe"); c->str_mul_unsafe = stringtab("mul_unsafe"); c->str_div_unsafe = stringtab("div_unsafe"); c->str_mod_unsafe = stringtab("mod_unsafe"); c->str_neg_unsafe = stringtab("neg_unsafe"); c->str_and = stringtab("op_and"); c->str_or = stringtab("op_or"); c->str_xor = stringtab("op_xor"); c->str_not = stringtab("op_not"); c->str_shl = stringtab("shl"); c->str_shr = stringtab("shr"); c->str_shl_unsafe = stringtab("shl_unsafe"); c->str_shr_unsafe = stringtab("shr_unsafe"); c->str_eq = stringtab("eq"); c->str_ne = stringtab("ne"); c->str_lt = stringtab("lt"); c->str_le = stringtab("le"); c->str_ge = stringtab("ge"); c->str_gt = stringtab("gt"); c->str_eq_unsafe = stringtab("eq_unsafe"); c->str_ne_unsafe = stringtab("ne_unsafe"); c->str_lt_unsafe = stringtab("lt_unsafe"); c->str_le_unsafe = stringtab("le_unsafe"); c->str_ge_unsafe = stringtab("ge_unsafe"); c->str_gt_unsafe = stringtab("gt_unsafe"); c->str_this = stringtab("this"); c->str_create = stringtab("create"); c->str__create = stringtab("_create"); c->str__init = stringtab("_init"); c->str__final = stringtab("_final"); c->str__event_notify = stringtab("_event_notify"); c->str__serialise_space = stringtab("_serialise_space"); c->str__serialise = stringtab("_serialise"); c->str__deserialise = stringtab("_deserialise"); LLVMTypeRef type; LLVMTypeRef params[5]; LLVMValueRef value; c->void_type = LLVMVoidTypeInContext(c->context); c->i1 = LLVMInt1TypeInContext(c->context); c->i8 = LLVMInt8TypeInContext(c->context); c->i16 = LLVMInt16TypeInContext(c->context); c->i32 = LLVMInt32TypeInContext(c->context); c->i64 = LLVMInt64TypeInContext(c->context); c->i128 = LLVMIntTypeInContext(c->context, 128); c->f32 = LLVMFloatTypeInContext(c->context); c->f64 = LLVMDoubleTypeInContext(c->context); c->intptr = LLVMIntPtrTypeInContext(c->context, c->target_data); // i8* c->void_ptr = LLVMPointerType(c->i8, 0); // forward declare object c->object_type = LLVMStructCreateNamed(c->context, "__object"); c->object_ptr = LLVMPointerType(c->object_type, 0); // padding required in an actor between the descriptor and fields c->actor_pad = LLVMArrayType(c->i8, PONY_ACTOR_PAD_SIZE); // message params[0] = c->i32; // size params[1] = c->i32; // id c->msg_type = LLVMStructCreateNamed(c->context, "__message"); c->msg_ptr = LLVMPointerType(c->msg_type, 0); LLVMStructSetBody(c->msg_type, params, 2, false); // trace // void (*)(i8*, __object*) params[0] = c->void_ptr; params[1] = c->object_ptr; c->trace_type = LLVMFunctionType(c->void_type, params, 2, false); c->trace_fn = LLVMPointerType(c->trace_type, 0); // serialise // void (*)(i8*, __object*, i8*, intptr, i32) params[0] = c->void_ptr; params[1] = c->object_ptr; params[2] = c->void_ptr; params[3] = c->intptr; params[4] = c->i32; c->serialise_type = LLVMFunctionType(c->void_type, params, 5, false); c->serialise_fn = LLVMPointerType(c->serialise_type, 0); // serialise_space // i64 (__object*) params[0] = c->object_ptr; c->custom_serialise_space_fn = LLVMPointerType( LLVMFunctionType(c->i64, params, 1, false), 0); // custom_deserialise // void (*)(__object*, void*) params[0] = c->object_ptr; params[1] = c->void_ptr; c->custom_deserialise_fn = LLVMPointerType( LLVMFunctionType(c->void_type, params, 2, false), 0); // dispatch // void (*)(i8*, __object*, $message*) params[0] = c->void_ptr; params[1] = c->object_ptr; params[2] = c->msg_ptr; c->dispatch_type = LLVMFunctionType(c->void_type, params, 3, false); c->dispatch_fn = LLVMPointerType(c->dispatch_type, 0); // void (*)(__object*) params[0] = c->object_ptr; c->final_fn = LLVMPointerType( LLVMFunctionType(c->void_type, params, 1, false), 0); // descriptor, opaque version // We need this in order to build our own structure. const char* desc_name = genname_descriptor(NULL); c->descriptor_type = LLVMStructCreateNamed(c->context, desc_name); c->descriptor_ptr = LLVMPointerType(c->descriptor_type, 0); // field descriptor // Also needed to build a descriptor structure. params[0] = c->i32; params[1] = c->descriptor_ptr; c->field_descriptor = LLVMStructTypeInContext(c->context, params, 2, false); // descriptor, filled in gendesc_basetype(c, c->descriptor_type); // define object params[0] = c->descriptor_ptr; LLVMStructSetBody(c->object_type, params, 1, false); #if PONY_LLVM >= 309 LLVM_DECLARE_ATTRIBUTEREF(nounwind_attr, nounwind, 0); LLVM_DECLARE_ATTRIBUTEREF(readnone_attr, readnone, 0); LLVM_DECLARE_ATTRIBUTEREF(readonly_attr, readonly, 0); LLVM_DECLARE_ATTRIBUTEREF(inacc_or_arg_mem_attr, inaccessiblemem_or_argmemonly, 0); LLVM_DECLARE_ATTRIBUTEREF(noalias_attr, noalias, 0); LLVM_DECLARE_ATTRIBUTEREF(noreturn_attr, noreturn, 0); LLVM_DECLARE_ATTRIBUTEREF(deref_actor_attr, dereferenceable, PONY_ACTOR_PAD_SIZE + (target_is_ilp32(c->opt->triple) ? 4 : 8)); LLVM_DECLARE_ATTRIBUTEREF(align_pool_attr, align, ponyint_pool_size(0)); LLVM_DECLARE_ATTRIBUTEREF(align_heap_attr, align, HEAP_MIN); LLVM_DECLARE_ATTRIBUTEREF(deref_or_null_alloc_attr, dereferenceable_or_null, HEAP_MIN); LLVM_DECLARE_ATTRIBUTEREF(deref_alloc_small_attr, dereferenceable, HEAP_MIN); LLVM_DECLARE_ATTRIBUTEREF(deref_alloc_large_attr, dereferenceable, HEAP_MAX << 1); #endif // i8* pony_ctx() type = LLVMFunctionType(c->void_ptr, NULL, 0, false); value = LLVMAddFunction(c->module, "pony_ctx", type); #if PONY_LLVM >= 309 LLVMAddAttributeAtIndex(value, LLVMAttributeFunctionIndex, nounwind_attr); LLVMAddAttributeAtIndex(value, LLVMAttributeFunctionIndex, readnone_attr); #else LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); LLVMAddFunctionAttr(value, LLVMReadNoneAttribute); #endif // __object* pony_create(i8*, __Desc*) params[0] = c->void_ptr; params[1] = c->descriptor_ptr; type = LLVMFunctionType(c->object_ptr, params, 2, false); value = LLVMAddFunction(c->module, "pony_create", type); #if PONY_LLVM >= 309 LLVMAddAttributeAtIndex(value, LLVMAttributeFunctionIndex, nounwind_attr); LLVMAddAttributeAtIndex(value, LLVMAttributeFunctionIndex, inacc_or_arg_mem_attr); LLVMAddAttributeAtIndex(value, LLVMAttributeReturnIndex, noalias_attr); LLVMAddAttributeAtIndex(value, LLVMAttributeReturnIndex, deref_actor_attr); LLVMAddAttributeAtIndex(value, LLVMAttributeReturnIndex, align_pool_attr); #else LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); # if PONY_LLVM >= 308 LLVMSetInaccessibleMemOrArgMemOnly(value); # endif LLVMSetReturnNoAlias(value); LLVMSetDereferenceable(value, 0, PONY_ACTOR_PAD_SIZE + (target_is_ilp32(c->opt->triple) ? 4 : 8)); #endif // void ponyint_destroy(__object*) params[0] = c->object_ptr; type = LLVMFunctionType(c->void_type, params, 1, false); value = LLVMAddFunction(c->module, "ponyint_destroy", type); #if PONY_LLVM >= 309 LLVMAddAttributeAtIndex(value, LLVMAttributeFunctionIndex, nounwind_attr); LLVMAddAttributeAtIndex(value, LLVMAttributeFunctionIndex, inacc_or_arg_mem_attr); #else LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); # if PONY_LLVM >= 308 LLVMSetInaccessibleMemOrArgMemOnly(value); # endif #endif // void pony_sendv(i8*, __object*, $message*, $message*) params[0] = c->void_ptr; params[1] = c->object_ptr; params[2] = c->msg_ptr; params[3] = c->msg_ptr; type = LLVMFunctionType(c->void_type, params, 4, false); value = LLVMAddFunction(c->module, "pony_sendv", type); #if PONY_LLVM >= 309 LLVMAddAttributeAtIndex(value, LLVMAttributeFunctionIndex, nounwind_attr); LLVMAddAttributeAtIndex(value, LLVMAttributeFunctionIndex, inacc_or_arg_mem_attr); #else LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); # if PONY_LLVM >= 308 LLVMSetInaccessibleMemOrArgMemOnly(value); # endif #endif // void pony_sendv_single(i8*, __object*, $message*, $message*) params[0] = c->void_ptr; params[1] = c->object_ptr; params[2] = c->msg_ptr; params[3] = c->msg_ptr; type = LLVMFunctionType(c->void_type, params, 4, false); value = LLVMAddFunction(c->module, "pony_sendv_single", type); #if PONY_LLVM >= 309 LLVMAddAttributeAtIndex(value, LLVMAttributeFunctionIndex, nounwind_attr); LLVMAddAttributeAtIndex(value, LLVMAttributeFunctionIndex, inacc_or_arg_mem_attr); #else LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); # if PONY_LLVM >= 308 LLVMSetInaccessibleMemOrArgMemOnly(value); # endif #endif // i8* pony_alloc(i8*, intptr) params[0] = c->void_ptr; params[1] = c->intptr; type = LLVMFunctionType(c->void_ptr, params, 2, false); value = LLVMAddFunction(c->module, "pony_alloc", type); #if PONY_LLVM >= 309 LLVMAddAttributeAtIndex(value, LLVMAttributeFunctionIndex, nounwind_attr); LLVMAddAttributeAtIndex(value, LLVMAttributeFunctionIndex, inacc_or_arg_mem_attr); LLVMAddAttributeAtIndex(value, LLVMAttributeReturnIndex, noalias_attr); LLVMAddAttributeAtIndex(value, LLVMAttributeReturnIndex, deref_or_null_alloc_attr); LLVMAddAttributeAtIndex(value, LLVMAttributeReturnIndex, align_heap_attr); #else LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); # if PONY_LLVM >= 308 LLVMSetInaccessibleMemOrArgMemOnly(value); # endif LLVMSetReturnNoAlias(value); LLVMSetDereferenceableOrNull(value, 0, HEAP_MIN); #endif // i8* pony_alloc_small(i8*, i32) params[0] = c->void_ptr; params[1] = c->i32; type = LLVMFunctionType(c->void_ptr, params, 2, false); value = LLVMAddFunction(c->module, "pony_alloc_small", type); #if PONY_LLVM >= 309 LLVMAddAttributeAtIndex(value, LLVMAttributeFunctionIndex, nounwind_attr); LLVMAddAttributeAtIndex(value, LLVMAttributeFunctionIndex, inacc_or_arg_mem_attr); LLVMAddAttributeAtIndex(value, LLVMAttributeReturnIndex, noalias_attr); LLVMAddAttributeAtIndex(value, LLVMAttributeReturnIndex, deref_alloc_small_attr); LLVMAddAttributeAtIndex(value, LLVMAttributeReturnIndex, align_heap_attr); #else LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); # if PONY_LLVM >= 308 LLVMSetInaccessibleMemOrArgMemOnly(value); # endif LLVMSetReturnNoAlias(value); LLVMSetDereferenceable(value, 0, HEAP_MIN); #endif // i8* pony_alloc_large(i8*, intptr) params[0] = c->void_ptr; params[1] = c->intptr; type = LLVMFunctionType(c->void_ptr, params, 2, false); value = LLVMAddFunction(c->module, "pony_alloc_large", type); #if PONY_LLVM >= 309 LLVMAddAttributeAtIndex(value, LLVMAttributeFunctionIndex, nounwind_attr); LLVMAddAttributeAtIndex(value, LLVMAttributeFunctionIndex, inacc_or_arg_mem_attr); LLVMAddAttributeAtIndex(value, LLVMAttributeReturnIndex, noalias_attr); LLVMAddAttributeAtIndex(value, LLVMAttributeReturnIndex, deref_alloc_large_attr); LLVMAddAttributeAtIndex(value, LLVMAttributeReturnIndex, align_heap_attr); #else LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); # if PONY_LLVM >= 308 LLVMSetInaccessibleMemOrArgMemOnly(value); # endif LLVMSetReturnNoAlias(value); LLVMSetDereferenceable(value, 0, HEAP_MAX << 1); #endif // i8* pony_realloc(i8*, i8*, intptr) params[0] = c->void_ptr; params[1] = c->void_ptr; params[2] = c->intptr; type = LLVMFunctionType(c->void_ptr, params, 3, false); value = LLVMAddFunction(c->module, "pony_realloc", type); #if PONY_LLVM >= 309 LLVMAddAttributeAtIndex(value, LLVMAttributeFunctionIndex, nounwind_attr); LLVMAddAttributeAtIndex(value, LLVMAttributeFunctionIndex, inacc_or_arg_mem_attr); LLVMAddAttributeAtIndex(value, LLVMAttributeReturnIndex, noalias_attr); LLVMAddAttributeAtIndex(value, LLVMAttributeReturnIndex, deref_or_null_alloc_attr); LLVMAddAttributeAtIndex(value, LLVMAttributeReturnIndex, align_heap_attr); #else LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); # if PONY_LLVM >= 308 LLVMSetInaccessibleMemOrArgMemOnly(value); # endif LLVMSetReturnNoAlias(value); LLVMSetDereferenceableOrNull(value, 0, HEAP_MIN); #endif // i8* pony_alloc_final(i8*, intptr) params[0] = c->void_ptr; params[1] = c->intptr; type = LLVMFunctionType(c->void_ptr, params, 2, false); value = LLVMAddFunction(c->module, "pony_alloc_final", type); #if PONY_LLVM >= 309 LLVMAddAttributeAtIndex(value, LLVMAttributeFunctionIndex, nounwind_attr); LLVMAddAttributeAtIndex(value, LLVMAttributeFunctionIndex, inacc_or_arg_mem_attr); LLVMAddAttributeAtIndex(value, LLVMAttributeReturnIndex, noalias_attr); LLVMAddAttributeAtIndex(value, LLVMAttributeReturnIndex, deref_or_null_alloc_attr); LLVMAddAttributeAtIndex(value, LLVMAttributeReturnIndex, align_heap_attr); #else LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); # if PONY_LLVM >= 308 LLVMSetInaccessibleMemOrArgMemOnly(value); # endif LLVMSetReturnNoAlias(value); LLVMSetDereferenceableOrNull(value, 0, HEAP_MIN); #endif // i8* pony_alloc_small_final(i8*, i32) params[0] = c->void_ptr; params[1] = c->i32; type = LLVMFunctionType(c->void_ptr, params, 2, false); value = LLVMAddFunction(c->module, "pony_alloc_small_final", type); #if PONY_LLVM >= 309 LLVMAddAttributeAtIndex(value, LLVMAttributeFunctionIndex, nounwind_attr); LLVMAddAttributeAtIndex(value, LLVMAttributeFunctionIndex, inacc_or_arg_mem_attr); LLVMAddAttributeAtIndex(value, LLVMAttributeReturnIndex, noalias_attr); LLVMAddAttributeAtIndex(value, LLVMAttributeReturnIndex, deref_alloc_small_attr); LLVMAddAttributeAtIndex(value, LLVMAttributeReturnIndex, align_heap_attr); #else LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); # if PONY_LLVM >= 308 LLVMSetInaccessibleMemOrArgMemOnly(value); # endif LLVMSetReturnNoAlias(value); LLVMSetDereferenceable(value, 0, HEAP_MIN); #endif // i8* pony_alloc_large_final(i8*, intptr) params[0] = c->void_ptr; params[1] = c->intptr; type = LLVMFunctionType(c->void_ptr, params, 2, false); value = LLVMAddFunction(c->module, "pony_alloc_large_final", type); #if PONY_LLVM >= 309 LLVMAddAttributeAtIndex(value, LLVMAttributeFunctionIndex, nounwind_attr); LLVMAddAttributeAtIndex(value, LLVMAttributeFunctionIndex, inacc_or_arg_mem_attr); LLVMAddAttributeAtIndex(value, LLVMAttributeReturnIndex, noalias_attr); LLVMAddAttributeAtIndex(value, LLVMAttributeReturnIndex, deref_alloc_large_attr); LLVMAddAttributeAtIndex(value, LLVMAttributeReturnIndex, align_heap_attr); #else LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); # if PONY_LLVM >= 308 LLVMSetInaccessibleMemOrArgMemOnly(value); # endif LLVMSetReturnNoAlias(value); LLVMSetDereferenceable(value, 0, HEAP_MAX << 1); #endif // $message* pony_alloc_msg(i32, i32) params[0] = c->i32; params[1] = c->i32; type = LLVMFunctionType(c->msg_ptr, params, 2, false); value = LLVMAddFunction(c->module, "pony_alloc_msg", type); #if PONY_LLVM >= 309 LLVMAddAttributeAtIndex(value, LLVMAttributeFunctionIndex, nounwind_attr); LLVMAddAttributeAtIndex(value, LLVMAttributeFunctionIndex, inacc_or_arg_mem_attr); LLVMAddAttributeAtIndex(value, LLVMAttributeReturnIndex, noalias_attr); LLVMAddAttributeAtIndex(value, LLVMAttributeReturnIndex, align_pool_attr); #else LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); # if PONY_LLVM >= 308 LLVMSetInaccessibleMemOrArgMemOnly(value); # endif LLVMSetReturnNoAlias(value); #endif // void pony_trace(i8*, i8*) params[0] = c->void_ptr; params[1] = c->void_ptr; type = LLVMFunctionType(c->void_type, params, 2, false); value = LLVMAddFunction(c->module, "pony_trace", type); #if PONY_LLVM >= 309 LLVMAddAttributeAtIndex(value, LLVMAttributeFunctionIndex, nounwind_attr); LLVMAddAttributeAtIndex(value, LLVMAttributeFunctionIndex, inacc_or_arg_mem_attr); LLVMAddAttributeAtIndex(value, 2, readnone_attr); #else LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); # if PONY_LLVM >= 308 LLVMSetInaccessibleMemOrArgMemOnly(value); # endif value = LLVMGetParam(value, 1); LLVMAddAttribute(value, LLVMReadNoneAttribute); #endif // void pony_traceknown(i8*, __object*, __Desc*, i32) params[0] = c->void_ptr; params[1] = c->object_ptr; params[2] = c->descriptor_ptr; params[3] = c->i32; type = LLVMFunctionType(c->void_type, params, 4, false); value = LLVMAddFunction(c->module, "pony_traceknown", type); #if PONY_LLVM >= 309 LLVMAddAttributeAtIndex(value, LLVMAttributeFunctionIndex, nounwind_attr); LLVMAddAttributeAtIndex(value, LLVMAttributeFunctionIndex, inacc_or_arg_mem_attr); LLVMAddAttributeAtIndex(value, 2, readonly_attr); #else LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); # if PONY_LLVM >= 308 LLVMSetInaccessibleMemOrArgMemOnly(value); # endif value = LLVMGetParam(value, 1); LLVMAddAttribute(value, LLVMReadOnlyAttribute); #endif // void pony_traceunknown(i8*, __object*, i32) params[0] = c->void_ptr; params[1] = c->object_ptr; params[2] = c->i32; type = LLVMFunctionType(c->void_type, params, 3, false); value = LLVMAddFunction(c->module, "pony_traceunknown", type); #if PONY_LLVM >= 309 LLVMAddAttributeAtIndex(value, LLVMAttributeFunctionIndex, nounwind_attr); LLVMAddAttributeAtIndex(value, LLVMAttributeFunctionIndex, inacc_or_arg_mem_attr); LLVMAddAttributeAtIndex(value, 2, readonly_attr); #else LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); # if PONY_LLVM >= 308 LLVMSetInaccessibleMemOrArgMemOnly(value); # endif value = LLVMGetParam(value, 1); LLVMAddAttribute(value, LLVMReadOnlyAttribute); #endif // void pony_gc_send(i8*) params[0] = c->void_ptr; type = LLVMFunctionType(c->void_type, params, 1, false); value = LLVMAddFunction(c->module, "pony_gc_send", type); #if PONY_LLVM >= 309 LLVMAddAttributeAtIndex(value, LLVMAttributeFunctionIndex, nounwind_attr); LLVMAddAttributeAtIndex(value, LLVMAttributeFunctionIndex, inacc_or_arg_mem_attr); #else LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); # if PONY_LLVM >= 308 LLVMSetInaccessibleMemOrArgMemOnly(value); # endif #endif // void pony_gc_recv(i8*) params[0] = c->void_ptr; type = LLVMFunctionType(c->void_type, params, 1, false); value = LLVMAddFunction(c->module, "pony_gc_recv", type); #if PONY_LLVM >= 309 LLVMAddAttributeAtIndex(value, LLVMAttributeFunctionIndex, nounwind_attr); LLVMAddAttributeAtIndex(value, LLVMAttributeFunctionIndex, inacc_or_arg_mem_attr); #else LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); # if PONY_LLVM >= 308 LLVMSetInaccessibleMemOrArgMemOnly(value); # endif #endif // void pony_send_done(i8*) params[0] = c->void_ptr; type = LLVMFunctionType(c->void_type, params, 1, false); value = LLVMAddFunction(c->module, "pony_send_done", type); #if PONY_LLVM >= 309 LLVMAddAttributeAtIndex(value, LLVMAttributeFunctionIndex, nounwind_attr); #else LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); #endif // void pony_recv_done(i8*) params[0] = c->void_ptr; type = LLVMFunctionType(c->void_type, params, 1, false); value = LLVMAddFunction(c->module, "pony_recv_done", type); #if PONY_LLVM >= 309 LLVMAddAttributeAtIndex(value, LLVMAttributeFunctionIndex, nounwind_attr); #else LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); #endif // void pony_serialise_reserve(i8*, i8*, intptr) params[0] = c->void_ptr; params[1] = c->void_ptr; params[2] = c->intptr; type = LLVMFunctionType(c->void_type, params, 3, false); value = LLVMAddFunction(c->module, "pony_serialise_reserve", type); #if PONY_LLVM >= 309 LLVMAddAttributeAtIndex(value, LLVMAttributeFunctionIndex, nounwind_attr); LLVMAddAttributeAtIndex(value, LLVMAttributeFunctionIndex, inacc_or_arg_mem_attr); LLVMAddAttributeAtIndex(value, 2, readnone_attr); #else LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); # if PONY_LLVM >= 308 LLVMSetInaccessibleMemOrArgMemOnly(value); # endif value = LLVMGetParam(value, 1); LLVMAddAttribute(value, LLVMReadNoneAttribute); #endif // intptr pony_serialise_offset(i8*, i8*) params[0] = c->void_ptr; params[1] = c->void_ptr; type = LLVMFunctionType(c->intptr, params, 2, false); value = LLVMAddFunction(c->module, "pony_serialise_offset", type); #if PONY_LLVM >= 309 LLVMAddAttributeAtIndex(value, LLVMAttributeFunctionIndex, nounwind_attr); LLVMAddAttributeAtIndex(value, LLVMAttributeFunctionIndex, inacc_or_arg_mem_attr); LLVMAddAttributeAtIndex(value, 2, readonly_attr); #else LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); # if PONY_LLVM >= 308 LLVMSetInaccessibleMemOrArgMemOnly(value); # endif value = LLVMGetParam(value, 1); LLVMAddAttribute(value, LLVMReadOnlyAttribute); #endif // i8* pony_deserialise_offset(i8*, __desc*, intptr) params[0] = c->void_ptr; params[1] = c->descriptor_ptr; params[2] = c->intptr; type = LLVMFunctionType(c->void_ptr, params, 3, false); value = LLVMAddFunction(c->module, "pony_deserialise_offset", type); #if PONY_LLVM >= 309 LLVMAddAttributeAtIndex(value, LLVMAttributeFunctionIndex, inacc_or_arg_mem_attr); #elif PONY_LLVM == 308 LLVMSetInaccessibleMemOrArgMemOnly(value); #endif // i8* pony_deserialise_block(i8*, intptr, intptr) params[0] = c->void_ptr; params[1] = c->intptr; params[2] = c->intptr; type = LLVMFunctionType(c->void_ptr, params, 3, false); value = LLVMAddFunction(c->module, "pony_deserialise_block", type); #if PONY_LLVM >= 309 LLVMAddAttributeAtIndex(value, LLVMAttributeFunctionIndex, inacc_or_arg_mem_attr); LLVMAddAttributeAtIndex(value, LLVMAttributeReturnIndex, noalias_attr); #else # if PONY_LLVM >= 308 LLVMSetInaccessibleMemOrArgMemOnly(value); # endif LLVMSetReturnNoAlias(value); #endif // i32 pony_init(i32, i8**) params[0] = c->i32; params[1] = LLVMPointerType(c->void_ptr, 0); type = LLVMFunctionType(c->i32, params, 2, false); value = LLVMAddFunction(c->module, "pony_init", type); #if PONY_LLVM >= 309 LLVMAddAttributeAtIndex(value, LLVMAttributeFunctionIndex, nounwind_attr); LLVMAddAttributeAtIndex(value, LLVMAttributeFunctionIndex, inacc_or_arg_mem_attr); #else LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); # if PONY_LLVM >= 308 LLVMSetInaccessibleMemOrArgMemOnly(value); # endif #endif // void pony_become(i8*, __object*) params[0] = c->void_ptr; params[1] = c->object_ptr; type = LLVMFunctionType(c->void_type, params, 2, false); value = LLVMAddFunction(c->module, "pony_become", type); #if PONY_LLVM >= 309 LLVMAddAttributeAtIndex(value, LLVMAttributeFunctionIndex, nounwind_attr); LLVMAddAttributeAtIndex(value, LLVMAttributeFunctionIndex, inacc_or_arg_mem_attr); #else LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); # if PONY_LLVM >= 308 LLVMSetInaccessibleMemOrArgMemOnly(value); # endif #endif // i32 pony_start(i32, i32) params[0] = c->i32; params[1] = c->i32; type = LLVMFunctionType(c->i32, params, 2, false); value = LLVMAddFunction(c->module, "pony_start", type); #if PONY_LLVM >= 309 LLVMAddAttributeAtIndex(value, LLVMAttributeFunctionIndex, nounwind_attr); LLVMAddAttributeAtIndex(value, LLVMAttributeFunctionIndex, inacc_or_arg_mem_attr); #else LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); # if PONY_LLVM >= 308 LLVMSetInaccessibleMemOrArgMemOnly(value); # endif #endif // i32 pony_get_exitcode() type = LLVMFunctionType(c->i32, NULL, 0, false); value = LLVMAddFunction(c->module, "pony_get_exitcode", type); #if PONY_LLVM >= 309 LLVMAddAttributeAtIndex(value, LLVMAttributeFunctionIndex, nounwind_attr); LLVMAddAttributeAtIndex(value, LLVMAttributeFunctionIndex, readonly_attr); #else LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); LLVMAddFunctionAttr(value, LLVMReadOnlyAttribute); #endif // void pony_throw() type = LLVMFunctionType(c->void_type, NULL, 0, false); value = LLVMAddFunction(c->module, "pony_throw", type); #if PONY_LLVM >= 309 LLVMAddAttributeAtIndex(value, LLVMAttributeFunctionIndex, noreturn_attr); #else LLVMAddFunctionAttr(value, LLVMNoReturnAttribute); #endif // i32 pony_personality_v0(...) type = LLVMFunctionType(c->i32, NULL, 0, true); c->personality = LLVMAddFunction(c->module, "pony_personality_v0", type); // i32 memcmp(i8*, i8*, intptr) params[0] = c->void_ptr; params[1] = c->void_ptr; params[2] = c->intptr; type = LLVMFunctionType(c->i32, params, 3, false); value = LLVMAddFunction(c->module, "memcmp", type); #if PONY_LLVM >= 309 LLVMAddAttributeAtIndex(value, LLVMAttributeFunctionIndex, nounwind_attr); LLVMAddAttributeAtIndex(value, LLVMAttributeFunctionIndex, readonly_attr); LLVMAddAttributeAtIndex(value, 1, readonly_attr); LLVMAddAttributeAtIndex(value, 2, readonly_attr); #else LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); LLVMAddFunctionAttr(value, LLVMReadOnlyAttribute); LLVMValueRef param = LLVMGetParam(value, 0); LLVMAddAttribute(param, LLVMReadOnlyAttribute); param = LLVMGetParam(value, 1); LLVMAddAttribute(param, LLVMReadOnlyAttribute); #endif }
static void init_runtime(compile_t* c) { c->str_1 = stringtab("$1"); c->str_Bool = stringtab("Bool"); c->str_I8 = stringtab("I8"); c->str_I16 = stringtab("I16"); c->str_I32 = stringtab("I32"); c->str_I64 = stringtab("I64"); c->str_I128 = stringtab("I128"); c->str_U8 = stringtab("U8"); c->str_U16 = stringtab("U16"); c->str_U32 = stringtab("U32"); c->str_U64 = stringtab("U64"); c->str_U128 = stringtab("U128"); c->str_F32 = stringtab("F32"); c->str_F64 = stringtab("F64"); c->str_Pointer = stringtab("Pointer"); c->str_Array = stringtab("Array"); c->str_Platform = stringtab("Platform"); c->str_add = stringtab("add"); c->str_sub = stringtab("sub"); c->str_mul = stringtab("mul"); c->str_div = stringtab("div"); c->str_mod = stringtab("mod"); c->str_neg = stringtab("neg"); c->str_and = stringtab("op_and"); c->str_or = stringtab("op_or"); c->str_xor = stringtab("op_xor"); c->str_not = stringtab("op_not"); c->str_shl = stringtab("shl"); c->str_shr = stringtab("shr"); c->str_eq = stringtab("eq"); c->str_ne = stringtab("ne"); c->str_lt = stringtab("lt"); c->str_le = stringtab("le"); c->str_ge = stringtab("ge"); c->str_gt = stringtab("gt"); LLVMTypeRef type; LLVMTypeRef params[4]; LLVMValueRef value; c->void_type = LLVMVoidTypeInContext(c->context); c->i1 = LLVMInt1TypeInContext(c->context); c->i8 = LLVMInt8TypeInContext(c->context); c->i16 = LLVMInt16TypeInContext(c->context); c->i32 = LLVMInt32TypeInContext(c->context); c->i64 = LLVMInt64TypeInContext(c->context); c->i128 = LLVMIntTypeInContext(c->context, 128); c->f32 = LLVMFloatTypeInContext(c->context); c->f64 = LLVMDoubleTypeInContext(c->context); c->intptr = LLVMIntPtrTypeInContext(c->context, c->target_data); // i8* c->void_ptr = LLVMPointerType(c->i8, 0); // forward declare object c->object_type = LLVMStructCreateNamed(c->context, "$object"); c->object_ptr = LLVMPointerType(c->object_type, 0); // padding required in an actor between the descriptor and fields c->actor_pad = LLVMArrayType(c->i8, PONY_ACTOR_PAD_SIZE); // message params[0] = c->i32; // size params[1] = c->i32; // id c->msg_type = LLVMStructCreateNamed(c->context, "$message"); c->msg_ptr = LLVMPointerType(c->msg_type, 0); LLVMStructSetBody(c->msg_type, params, 2, false); // trace // void (*)($object*) params[0] = c->object_ptr; c->trace_type = LLVMFunctionType(c->void_type, params, 1, false); c->trace_fn = LLVMPointerType(c->trace_type, 0); // dispatch // void (*)($object*, $message*) params[0] = c->object_ptr; params[1] = c->msg_ptr; c->dispatch_type = LLVMFunctionType(c->void_type, params, 2, false); c->dispatch_fn = LLVMPointerType(c->dispatch_type, 0); // void (*)($object*) params[0] = c->object_ptr; c->final_fn = LLVMPointerType( LLVMFunctionType(c->void_type, params, 1, false), 0); // descriptor, opaque version // We need this in order to build our own structure. const char* desc_name = genname_descriptor(NULL); c->descriptor_type = LLVMStructCreateNamed(c->context, desc_name); c->descriptor_ptr = LLVMPointerType(c->descriptor_type, 0); // field descriptor // Also needed to build a descriptor structure. params[0] = c->i32; params[1] = c->descriptor_ptr; c->field_descriptor = LLVMStructTypeInContext(c->context, params, 2, false); // descriptor, filled in c->descriptor_type = gendesc_type(c, NULL); // define object params[0] = c->descriptor_ptr; LLVMStructSetBody(c->object_type, params, 1, false); // $object* pony_create($desc*) params[0] = c->descriptor_ptr; type = LLVMFunctionType(c->object_ptr, params, 1, false); value = LLVMAddFunction(c->module, "pony_create", type); LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); LLVMSetReturnNoAlias(value); // void pony_destroy($object*) params[0] = c->object_ptr; type = LLVMFunctionType(c->void_type, params, 1, false); value = LLVMAddFunction(c->module, "pony_destroy", type); LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); //LLVMSetReturnNoAlias(value); // void pony_sendv($object*, $message*); params[0] = c->object_ptr; params[1] = c->msg_ptr; type = LLVMFunctionType(c->void_type, params, 2, false); value = LLVMAddFunction(c->module, "pony_sendv", type); LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); // i8* pony_alloc(i64) params[0] = c->i64; type = LLVMFunctionType(c->void_ptr, params, 1, false); value = LLVMAddFunction(c->module, "pony_alloc", type); LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); LLVMSetReturnNoAlias(value); // i8* pony_realloc(i8*, i64) params[0] = c->void_ptr; params[1] = c->i64; type = LLVMFunctionType(c->void_ptr, params, 2, false); value = LLVMAddFunction(c->module, "pony_realloc", type); LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); LLVMSetReturnNoAlias(value); // i8* pony_alloc_final(i64, c->final_fn) params[0] = c->i64; params[1] = c->final_fn; type = LLVMFunctionType(c->void_ptr, params, 2, false); value = LLVMAddFunction(c->module, "pony_alloc_final", type); LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); LLVMSetReturnNoAlias(value); // $message* pony_alloc_msg(i32, i32) params[0] = c->i32; params[1] = c->i32; type = LLVMFunctionType(c->msg_ptr, params, 2, false); value = LLVMAddFunction(c->module, "pony_alloc_msg", type); LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); LLVMSetReturnNoAlias(value); // void pony_trace(i8*) params[0] = c->void_ptr; type = LLVMFunctionType(c->void_type, params, 1, false); value = LLVMAddFunction(c->module, "pony_trace", type); LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); // void pony_traceactor($object*) params[0] = c->object_ptr; type = LLVMFunctionType(c->void_type, params, 1, false); value = LLVMAddFunction(c->module, "pony_traceactor", type); LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); // void pony_traceobject($object*, trace_fn) params[0] = c->object_ptr; params[1] = c->trace_fn; type = LLVMFunctionType(c->void_type, params, 2, false); value = LLVMAddFunction(c->module, "pony_traceobject", type); LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); // void pony_traceunknown($object*) params[0] = c->object_ptr; type = LLVMFunctionType(c->void_type, params, 1, false); value = LLVMAddFunction(c->module, "pony_traceunknown", type); LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); // void pony_trace_tag_or_actor($object*) params[0] = c->object_ptr; type = LLVMFunctionType(c->void_type, params, 1, false); value = LLVMAddFunction(c->module, "pony_trace_tag_or_actor", type); LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); // void pony_gc_send() type = LLVMFunctionType(c->void_type, NULL, 0, false); value = LLVMAddFunction(c->module, "pony_gc_send", type); LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); // void pony_gc_recv() type = LLVMFunctionType(c->void_type, NULL, 0, false); value = LLVMAddFunction(c->module, "pony_gc_recv", type); LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); // void pony_send_done() type = LLVMFunctionType(c->void_type, NULL, 0, false); value = LLVMAddFunction(c->module, "pony_send_done", type); LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); // void pony_recv_done() type = LLVMFunctionType(c->void_type, NULL, 0, false); value = LLVMAddFunction(c->module, "pony_recv_done", type); LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); // i32 pony_init(i32, i8**) params[0] = c->i32; params[1] = LLVMPointerType(c->void_ptr, 0); type = LLVMFunctionType(c->i32, params, 2, false); value = LLVMAddFunction(c->module, "pony_init", type); LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); // void pony_become($object*) params[0] = c->object_ptr; type = LLVMFunctionType(c->void_type, params, 1, false); value = LLVMAddFunction(c->module, "pony_become", type); LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); // i32 pony_start(i32) params[0] = c->i32; type = LLVMFunctionType(c->i32, params, 1, false); value = LLVMAddFunction(c->module, "pony_start", type); LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); // void pony_throw() type = LLVMFunctionType(c->void_type, NULL, 0, false); LLVMAddFunction(c->module, "pony_throw", type); // i32 pony_personality_v0(...) type = LLVMFunctionType(c->i32, NULL, 0, true); c->personality = LLVMAddFunction(c->module, "pony_personality_v0", type); // i8* memcpy(...) type = LLVMFunctionType(c->void_ptr, NULL, 0, true); value = LLVMAddFunction(c->module, "memcpy", type); LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); // i8* memmove(...) type = LLVMFunctionType(c->void_ptr, NULL, 0, true); value = LLVMAddFunction(c->module, "memmove", type); LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); }
/* * Do a cached lookup. * * Returns (vectors of) 4x8 rgba aos value */ LLVMValueRef lp_build_fetch_cached_texels(struct gallivm_state *gallivm, const struct util_format_description *format_desc, unsigned n, LLVMValueRef base_ptr, LLVMValueRef offset, LLVMValueRef i, LLVMValueRef j, LLVMValueRef cache) { LLVMBuilderRef builder = gallivm->builder; unsigned count, low_bit, log2size; LLVMValueRef color, offset_stored, addr, ptr_addrtrunc, tmp; LLVMValueRef ij_index, hash_index, hash_mask, block_index; LLVMTypeRef i8t = LLVMInt8TypeInContext(gallivm->context); LLVMTypeRef i32t = LLVMInt32TypeInContext(gallivm->context); LLVMTypeRef i64t = LLVMInt64TypeInContext(gallivm->context); struct lp_type type; struct lp_build_context bld32; memset(&type, 0, sizeof type); type.width = 32; type.length = n; assert(format_desc->block.width == 4); assert(format_desc->block.height == 4); lp_build_context_init(&bld32, gallivm, type); /* * compute hash - we use direct mapped cache, the hash function could * be better but it needs to be simple * per-element: * compare offset with offset stored at tag (hash) * if not equal decode/store block, update tag * extract color from cache * assemble result vector */ /* TODO: not ideal with 32bit pointers... */ low_bit = util_logbase2(format_desc->block.bits / 8); log2size = util_logbase2(LP_BUILD_FORMAT_CACHE_SIZE); addr = LLVMBuildPtrToInt(builder, base_ptr, i64t, ""); ptr_addrtrunc = LLVMBuildPtrToInt(builder, base_ptr, i32t, ""); ptr_addrtrunc = lp_build_broadcast_scalar(&bld32, ptr_addrtrunc); /* For the hash function, first mask off the unused lowest bits. Then just do some xor with address bits - only use lower 32bits */ ptr_addrtrunc = LLVMBuildAdd(builder, offset, ptr_addrtrunc, ""); ptr_addrtrunc = LLVMBuildLShr(builder, ptr_addrtrunc, lp_build_const_int_vec(gallivm, type, low_bit), ""); /* This only really makes sense for size 64,128,256 */ hash_index = ptr_addrtrunc; ptr_addrtrunc = LLVMBuildLShr(builder, ptr_addrtrunc, lp_build_const_int_vec(gallivm, type, 2*log2size), ""); hash_index = LLVMBuildXor(builder, ptr_addrtrunc, hash_index, ""); tmp = LLVMBuildLShr(builder, hash_index, lp_build_const_int_vec(gallivm, type, log2size), ""); hash_index = LLVMBuildXor(builder, hash_index, tmp, ""); hash_mask = lp_build_const_int_vec(gallivm, type, LP_BUILD_FORMAT_CACHE_SIZE - 1); hash_index = LLVMBuildAnd(builder, hash_index, hash_mask, ""); ij_index = LLVMBuildShl(builder, i, lp_build_const_int_vec(gallivm, type, 2), ""); ij_index = LLVMBuildAdd(builder, ij_index, j, ""); block_index = LLVMBuildShl(builder, hash_index, lp_build_const_int_vec(gallivm, type, 4), ""); block_index = LLVMBuildAdd(builder, ij_index, block_index, ""); if (n > 1) { color = LLVMGetUndef(LLVMVectorType(i32t, n)); for (count = 0; count < n; count++) { LLVMValueRef index, cond, colorx; LLVMValueRef block_indexx, hash_indexx, addrx, offsetx, ptr_addrx; struct lp_build_if_state if_ctx; index = lp_build_const_int32(gallivm, count); offsetx = LLVMBuildExtractElement(builder, offset, index, ""); addrx = LLVMBuildZExt(builder, offsetx, i64t, ""); addrx = LLVMBuildAdd(builder, addrx, addr, ""); block_indexx = LLVMBuildExtractElement(builder, block_index, index, ""); hash_indexx = LLVMBuildLShr(builder, block_indexx, lp_build_const_int32(gallivm, 4), ""); offset_stored = lookup_tag_data(gallivm, cache, hash_indexx); cond = LLVMBuildICmp(builder, LLVMIntNE, offset_stored, addrx, ""); lp_build_if(&if_ctx, gallivm, cond); { ptr_addrx = LLVMBuildIntToPtr(builder, addrx, LLVMPointerType(i8t, 0), ""); update_cached_block(gallivm, format_desc, ptr_addrx, hash_indexx, cache); #if LP_BUILD_FORMAT_CACHE_DEBUG update_cache_access(gallivm, cache, 1, LP_BUILD_FORMAT_CACHE_MEMBER_ACCESS_MISS); #endif } lp_build_endif(&if_ctx); colorx = lookup_cached_pixel(gallivm, cache, block_indexx); color = LLVMBuildInsertElement(builder, color, colorx, lp_build_const_int32(gallivm, count), ""); } } else { LLVMValueRef cond; struct lp_build_if_state if_ctx; tmp = LLVMBuildZExt(builder, offset, i64t, ""); addr = LLVMBuildAdd(builder, tmp, addr, ""); offset_stored = lookup_tag_data(gallivm, cache, hash_index); cond = LLVMBuildICmp(builder, LLVMIntNE, offset_stored, addr, ""); lp_build_if(&if_ctx, gallivm, cond); { tmp = LLVMBuildIntToPtr(builder, addr, LLVMPointerType(i8t, 0), ""); update_cached_block(gallivm, format_desc, tmp, hash_index, cache); #if LP_BUILD_FORMAT_CACHE_DEBUG update_cache_access(gallivm, cache, 1, LP_BUILD_FORMAT_CACHE_MEMBER_ACCESS_MISS); #endif } lp_build_endif(&if_ctx); color = lookup_cached_pixel(gallivm, cache, block_index); } #if LP_BUILD_FORMAT_CACHE_DEBUG update_cache_access(gallivm, cache, n, LP_BUILD_FORMAT_CACHE_MEMBER_ACCESS_TOTAL); #endif return LLVMBuildBitCast(builder, color, LLVMVectorType(i8t, n * 4), ""); }
static void update_cached_block(struct gallivm_state *gallivm, const struct util_format_description *format_desc, LLVMValueRef ptr_addr, LLVMValueRef hash_index, LLVMValueRef cache) { LLVMBuilderRef builder = gallivm->builder; LLVMTypeRef i8t = LLVMInt8TypeInContext(gallivm->context); LLVMTypeRef pi8t = LLVMPointerType(i8t, 0); LLVMTypeRef i32t = LLVMInt32TypeInContext(gallivm->context); LLVMTypeRef i32x4 = LLVMVectorType(LLVMInt32TypeInContext(gallivm->context), 4); LLVMValueRef function; LLVMValueRef tag_value, tmp_ptr; LLVMValueRef col[4]; unsigned i, j; /* * Use format_desc->fetch_rgba_8unorm() for each pixel in the block. * This doesn't actually make any sense whatsoever, someone would need * to write a function doing this for all pixels in a block (either as * an external c function or with generated code). Don't ask. */ { /* * Function to call looks like: * fetch(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j) */ LLVMTypeRef ret_type; LLVMTypeRef arg_types[4]; LLVMTypeRef function_type; assert(format_desc->fetch_rgba_8unorm); ret_type = LLVMVoidTypeInContext(gallivm->context); arg_types[0] = pi8t; arg_types[1] = pi8t; arg_types[2] = i32t; arg_types[3] = i32t; function_type = LLVMFunctionType(ret_type, arg_types, ARRAY_SIZE(arg_types), 0); /* make const pointer for the C fetch_rgba_8unorm function */ function = lp_build_const_int_pointer(gallivm, func_to_pointer((func_pointer) format_desc->fetch_rgba_8unorm)); /* cast the callee pointer to the function's type */ function = LLVMBuildBitCast(builder, function, LLVMPointerType(function_type, 0), "cast callee"); } tmp_ptr = lp_build_array_alloca(gallivm, i32x4, lp_build_const_int32(gallivm, 16), "tmp_decode_store"); tmp_ptr = LLVMBuildBitCast(builder, tmp_ptr, pi8t, ""); /* * Invoke format_desc->fetch_rgba_8unorm() for each pixel. * This is going to be really really slow. * Note: the block store format is actually * x0y0x0y1x0y2x0y3 x1y0x1y1x1y2x1y3 ... */ for (i = 0; i < 4; ++i) { for (j = 0; j < 4; ++j) { LLVMValueRef args[4]; LLVMValueRef dst_offset = lp_build_const_int32(gallivm, (i * 4 + j) * 4); /* * Note we actually supply a pointer to the start of the block, * not the start of the texture. */ args[0] = LLVMBuildGEP(gallivm->builder, tmp_ptr, &dst_offset, 1, ""); args[1] = ptr_addr; args[2] = LLVMConstInt(i32t, i, 0); args[3] = LLVMConstInt(i32t, j, 0); LLVMBuildCall(builder, function, args, ARRAY_SIZE(args), ""); } } /* Finally store the block - pointless mem copy + update tag. */ tmp_ptr = LLVMBuildBitCast(builder, tmp_ptr, LLVMPointerType(i32x4, 0), ""); for (i = 0; i < 4; ++i) { LLVMValueRef tmp_offset = lp_build_const_int32(gallivm, i); LLVMValueRef ptr = LLVMBuildGEP(gallivm->builder, tmp_ptr, &tmp_offset, 1, ""); col[i] = LLVMBuildLoad(builder, ptr, ""); } tag_value = LLVMBuildPtrToInt(gallivm->builder, ptr_addr, LLVMInt64TypeInContext(gallivm->context), ""); store_cached_block(gallivm, col, tag_value, hash_index, cache); }
static void init_runtime(compile_t* c) { c->str_builtin = stringtab("$0"); c->str_Bool = stringtab("Bool"); c->str_I8 = stringtab("I8"); c->str_I16 = stringtab("I16"); c->str_I32 = stringtab("I32"); c->str_I64 = stringtab("I64"); c->str_I128 = stringtab("I128"); c->str_ILong = stringtab("ILong"); c->str_ISize = stringtab("ISize"); c->str_U8 = stringtab("U8"); c->str_U16 = stringtab("U16"); c->str_U32 = stringtab("U32"); c->str_U64 = stringtab("U64"); c->str_U128 = stringtab("U128"); c->str_ULong = stringtab("ULong"); c->str_USize = stringtab("USize"); c->str_F32 = stringtab("F32"); c->str_F64 = stringtab("F64"); c->str_Pointer = stringtab("Pointer"); c->str_Maybe = stringtab("MaybePointer"); c->str_DoNotOptimise = stringtab("DoNotOptimise"); c->str_Array = stringtab("Array"); c->str_String = stringtab("String"); c->str_Platform = stringtab("Platform"); c->str_Main = stringtab("Main"); c->str_Env = stringtab("Env"); c->str_add = stringtab("add"); c->str_sub = stringtab("sub"); c->str_mul = stringtab("mul"); c->str_div = stringtab("div"); c->str_mod = stringtab("mod"); c->str_neg = stringtab("neg"); c->str_and = stringtab("op_and"); c->str_or = stringtab("op_or"); c->str_xor = stringtab("op_xor"); c->str_not = stringtab("op_not"); c->str_shl = stringtab("shl"); c->str_shr = stringtab("shr"); c->str_eq = stringtab("eq"); c->str_ne = stringtab("ne"); c->str_lt = stringtab("lt"); c->str_le = stringtab("le"); c->str_ge = stringtab("ge"); c->str_gt = stringtab("gt"); c->str_this = stringtab("this"); c->str_create = stringtab("create"); c->str__create = stringtab("_create"); c->str__init = stringtab("_init"); c->str__final = stringtab("_final"); c->str__event_notify = stringtab("_event_notify"); LLVMTypeRef type; LLVMTypeRef params[5]; LLVMValueRef value; c->void_type = LLVMVoidTypeInContext(c->context); c->ibool = LLVMInt8TypeInContext(c->context); c->i1 = LLVMInt1TypeInContext(c->context); c->i8 = LLVMInt8TypeInContext(c->context); c->i16 = LLVMInt16TypeInContext(c->context); c->i32 = LLVMInt32TypeInContext(c->context); c->i64 = LLVMInt64TypeInContext(c->context); c->i128 = LLVMIntTypeInContext(c->context, 128); c->f32 = LLVMFloatTypeInContext(c->context); c->f64 = LLVMDoubleTypeInContext(c->context); c->intptr = LLVMIntPtrTypeInContext(c->context, c->target_data); // i8* c->void_ptr = LLVMPointerType(c->i8, 0); // forward declare object c->object_type = LLVMStructCreateNamed(c->context, "__object"); c->object_ptr = LLVMPointerType(c->object_type, 0); // padding required in an actor between the descriptor and fields c->actor_pad = LLVMArrayType(c->i8, PONY_ACTOR_PAD_SIZE); // message params[0] = c->i32; // size params[1] = c->i32; // id c->msg_type = LLVMStructCreateNamed(c->context, "__message"); c->msg_ptr = LLVMPointerType(c->msg_type, 0); LLVMStructSetBody(c->msg_type, params, 2, false); // trace // void (*)(i8*, __object*) params[0] = c->void_ptr; params[1] = c->object_ptr; c->trace_type = LLVMFunctionType(c->void_type, params, 2, false); c->trace_fn = LLVMPointerType(c->trace_type, 0); // serialise // void (*)(i8*, __object*, i8*, intptr, i32) params[0] = c->void_ptr; params[1] = c->object_ptr; params[2] = c->void_ptr; params[3] = c->intptr; params[4] = c->i32; c->serialise_type = LLVMFunctionType(c->void_type, params, 5, false); c->serialise_fn = LLVMPointerType(c->serialise_type, 0); // dispatch // void (*)(i8*, __object*, $message*) params[0] = c->void_ptr; params[1] = c->object_ptr; params[2] = c->msg_ptr; c->dispatch_type = LLVMFunctionType(c->void_type, params, 3, false); c->dispatch_fn = LLVMPointerType(c->dispatch_type, 0); // void (*)(__object*) params[0] = c->object_ptr; c->final_fn = LLVMPointerType( LLVMFunctionType(c->void_type, params, 1, false), 0); // descriptor, opaque version // We need this in order to build our own structure. const char* desc_name = genname_descriptor(NULL); c->descriptor_type = LLVMStructCreateNamed(c->context, desc_name); c->descriptor_ptr = LLVMPointerType(c->descriptor_type, 0); // field descriptor // Also needed to build a descriptor structure. params[0] = c->i32; params[1] = c->descriptor_ptr; c->field_descriptor = LLVMStructTypeInContext(c->context, params, 2, false); // descriptor, filled in gendesc_basetype(c, c->descriptor_type); // define object params[0] = c->descriptor_ptr; LLVMStructSetBody(c->object_type, params, 1, false); // $i8* pony_ctx() type = LLVMFunctionType(c->void_ptr, NULL, 0, false); value = LLVMAddFunction(c->module, "pony_ctx", type); LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); LLVMAddFunctionAttr(value, LLVMReadNoneAttribute); // __object* pony_create(i8*, __Desc*) params[0] = c->void_ptr; params[1] = c->descriptor_ptr; type = LLVMFunctionType(c->object_ptr, params, 2, false); value = LLVMAddFunction(c->module, "pony_create", type); LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); LLVMSetReturnNoAlias(value); LLVMSetDereferenceable(value, 0, PONY_ACTOR_PAD_SIZE); // void ponyint_destroy(__object*) params[0] = c->object_ptr; type = LLVMFunctionType(c->void_type, params, 1, false); value = LLVMAddFunction(c->module, "ponyint_destroy", type); LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); // void pony_sendv(i8*, __object*, $message*); params[0] = c->void_ptr; params[1] = c->object_ptr; params[2] = c->msg_ptr; type = LLVMFunctionType(c->void_type, params, 3, false); value = LLVMAddFunction(c->module, "pony_sendv", type); LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); // i8* pony_alloc(i8*, intptr) params[0] = c->void_ptr; params[1] = c->intptr; type = LLVMFunctionType(c->void_ptr, params, 2, false); value = LLVMAddFunction(c->module, "pony_alloc", type); LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); LLVMSetReturnNoAlias(value); #if PONY_LLVM >= 307 LLVMSetDereferenceableOrNull(value, 0, HEAP_MIN); #endif // i8* pony_alloc_small(i8*, i32) params[0] = c->void_ptr; params[1] = c->i32; type = LLVMFunctionType(c->void_ptr, params, 2, false); value = LLVMAddFunction(c->module, "pony_alloc_small", type); LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); LLVMSetReturnNoAlias(value); LLVMSetDereferenceable(value, 0, HEAP_MIN); // i8* pony_alloc_large(i8*, intptr) params[0] = c->void_ptr; params[1] = c->intptr; type = LLVMFunctionType(c->void_ptr, params, 2, false); value = LLVMAddFunction(c->module, "pony_alloc_large", type); LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); LLVMSetReturnNoAlias(value); LLVMSetDereferenceable(value, 0, HEAP_MAX + 1); // i8* pony_realloc(i8*, i8*, intptr) params[0] = c->void_ptr; params[1] = c->void_ptr; params[2] = c->intptr; type = LLVMFunctionType(c->void_ptr, params, 3, false); value = LLVMAddFunction(c->module, "pony_realloc", type); LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); LLVMSetReturnNoAlias(value); #if PONY_LLVM >= 307 LLVMSetDereferenceableOrNull(value, 0, HEAP_MIN); #endif // i8* pony_alloc_final(i8*, intptr, c->final_fn) params[0] = c->void_ptr; params[1] = c->intptr; params[2] = c->final_fn; type = LLVMFunctionType(c->void_ptr, params, 3, false); value = LLVMAddFunction(c->module, "pony_alloc_final", type); LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); LLVMSetReturnNoAlias(value); #if PONY_LLVM >= 307 LLVMSetDereferenceableOrNull(value, 0, HEAP_MIN); #endif // $message* pony_alloc_msg(i32, i32) params[0] = c->i32; params[1] = c->i32; type = LLVMFunctionType(c->msg_ptr, params, 2, false); value = LLVMAddFunction(c->module, "pony_alloc_msg", type); LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); LLVMSetReturnNoAlias(value); // void pony_trace(i8*, i8*) params[0] = c->void_ptr; params[1] = c->void_ptr; type = LLVMFunctionType(c->void_type, params, 2, false); value = LLVMAddFunction(c->module, "pony_trace", type); LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); // i8* pony_traceobject(i8*, __object*, __Desc*, i32) params[0] = c->void_ptr; params[1] = c->object_ptr; params[2] = c->descriptor_ptr; params[3] = c->i32; type = LLVMFunctionType(c->void_ptr, params, 4, false); value = LLVMAddFunction(c->module, "pony_traceknown", type); LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); // i8* pony_traceunknown(i8*, __object*, i32) params[0] = c->void_ptr; params[1] = c->object_ptr; params[2] = c->i32; type = LLVMFunctionType(c->void_ptr, params, 3, false); value = LLVMAddFunction(c->module, "pony_traceunknown", type); LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); // void pony_gc_send(i8*) params[0] = c->void_ptr; type = LLVMFunctionType(c->void_type, params, 1, false); value = LLVMAddFunction(c->module, "pony_gc_send", type); LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); // void pony_gc_recv(i8*) params[0] = c->void_ptr; type = LLVMFunctionType(c->void_type, params, 1, false); value = LLVMAddFunction(c->module, "pony_gc_recv", type); LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); // void pony_send_done(i8*) params[0] = c->void_ptr; type = LLVMFunctionType(c->void_type, params, 1, false); value = LLVMAddFunction(c->module, "pony_send_done", type); LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); // void pony_recv_done(i8*) params[0] = c->void_ptr; type = LLVMFunctionType(c->void_type, params, 1, false); value = LLVMAddFunction(c->module, "pony_recv_done", type); LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); // void pony_serialise_reserve(i8*, i8*, intptr) params[0] = c->void_ptr; params[1] = c->void_ptr; params[2] = c->intptr; type = LLVMFunctionType(c->void_type, params, 3, false); value = LLVMAddFunction(c->module, "pony_serialise_reserve", type); LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); // intptr pony_serialise_offset(i8*, i8*) params[0] = c->void_ptr; params[1] = c->void_ptr; type = LLVMFunctionType(c->intptr, params, 2, false); value = LLVMAddFunction(c->module, "pony_serialise_offset", type); LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); // i8* pony_deserialise_offset(i8*, __desc*, intptr) params[0] = c->void_ptr; params[1] = c->descriptor_ptr; params[2] = c->intptr; type = LLVMFunctionType(c->void_ptr, params, 3, false); value = LLVMAddFunction(c->module, "pony_deserialise_offset", type); // i8* pony_deserialise_block(i8*, intptr, intptr) params[0] = c->void_ptr; params[1] = c->intptr; params[2] = c->intptr; type = LLVMFunctionType(c->void_ptr, params, 3, false); value = LLVMAddFunction(c->module, "pony_deserialise_block", type); // i32 pony_init(i32, i8**) params[0] = c->i32; params[1] = LLVMPointerType(c->void_ptr, 0); type = LLVMFunctionType(c->i32, params, 2, false); value = LLVMAddFunction(c->module, "pony_init", type); LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); // void pony_become(i8*, __object*) params[0] = c->void_ptr; params[1] = c->object_ptr; type = LLVMFunctionType(c->void_type, params, 2, false); value = LLVMAddFunction(c->module, "pony_become", type); LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); // i32 pony_start(i32) params[0] = c->i32; type = LLVMFunctionType(c->i32, params, 1, false); value = LLVMAddFunction(c->module, "pony_start", type); LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); // void pony_throw() type = LLVMFunctionType(c->void_type, NULL, 0, false); LLVMAddFunction(c->module, "pony_throw", type); // i32 pony_personality_v0(...) type = LLVMFunctionType(c->i32, NULL, 0, true); c->personality = LLVMAddFunction(c->module, "pony_personality_v0", type); // void llvm.memcpy.*(i8*, i8*, i32/64, i32, i1) params[0] = c->void_ptr; params[1] = c->void_ptr; params[3] = c->i32; params[4] = c->i1; if(target_is_ilp32(c->opt->triple)) { params[2] = c->i32; type = LLVMFunctionType(c->void_type, params, 5, false); value = LLVMAddFunction(c->module, "llvm.memcpy.p0i8.p0i8.i32", type); } else { params[2] = c->i64; type = LLVMFunctionType(c->void_type, params, 5, false); value = LLVMAddFunction(c->module, "llvm.memcpy.p0i8.p0i8.i64", type); } LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); // void llvm.memmove.*(i8*, i8*, i32/64, i32, i1) params[0] = c->void_ptr; params[1] = c->void_ptr; params[3] = c->i32; params[4] = c->i1; if(target_is_ilp32(c->opt->triple)) { params[2] = c->i32; type = LLVMFunctionType(c->void_type, params, 5, false); value = LLVMAddFunction(c->module, "llvm.memmove.p0i8.p0i8.i32", type); } else { params[2] = c->i64; type = LLVMFunctionType(c->void_type, params, 5, false); value = LLVMAddFunction(c->module, "llvm.memmove.p0i8.p0i8.i64", type); } LLVMAddFunctionAttr(value, LLVMNoUnwindAttribute); }