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; }
LLVMValueRef gen_string(compile_t* c, ast_t* ast) { const char* name = ast_name(ast); genned_string_t k; k.string = name; size_t index = HASHMAP_UNKNOWN; genned_string_t* string = genned_strings_get(&c->strings, &k, &index); if(string != NULL) return string->global; ast_t* type = ast_type(ast); pony_assert(is_literal(type, "String")); reach_type_t* t = reach_type(c->reach, type); compile_type_t* c_t = (compile_type_t*)t->c_type; size_t len = ast_name_len(ast); LLVMValueRef args[4]; args[0] = c_t->desc; args[1] = LLVMConstInt(c->intptr, len, false); args[2] = LLVMConstInt(c->intptr, len + 1, false); args[3] = codegen_string(c, name, len); LLVMValueRef inst = LLVMConstNamedStruct(c_t->structure, args, 4); LLVMValueRef g_inst = LLVMAddGlobal(c->module, c_t->structure, ""); LLVMSetInitializer(g_inst, inst); LLVMSetGlobalConstant(g_inst, true); LLVMSetLinkage(g_inst, LLVMPrivateLinkage); LLVMSetUnnamedAddr(g_inst, true); string = POOL_ALLOC(genned_string_t); string->string = name; string->global = g_inst; genned_strings_putindex(&c->strings, string, index); return g_inst; }