GHashTable *method_depth;
MonoCompile **cfgs;
int cfgs_size;
- GHashTable *patch_to_plt_entry;
+ GHashTable **patch_to_plt_entry;
GHashTable *plt_offset_to_entry;
GHashTable *patch_to_got_offset;
GHashTable **patch_to_got_offset_by_type;
if (!is_plt_patch (patch_info))
return NULL;
- res = g_hash_table_lookup (acfg->patch_to_plt_entry, patch_info);
+ if (!acfg->patch_to_plt_entry [patch_info->type])
+ acfg->patch_to_plt_entry [patch_info->type] = g_hash_table_new (mono_patch_info_hash, mono_patch_info_equal);
+ res = g_hash_table_lookup (acfg->patch_to_plt_entry [patch_info->type], patch_info);
// FIXME: This breaks the calculation of final_got_size
if (!acfg->llvm && patch_info->type == MONO_PATCH_INFO_METHOD && (patch_info->data.method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED)) {
else
res->llvm_symbol = g_strdup_printf ("%s_llvm", res->symbol);
- g_hash_table_insert (acfg->patch_to_plt_entry, new_ji, res);
+ g_hash_table_insert (acfg->patch_to_plt_entry [new_ji->type], new_ji, res);
g_hash_table_insert (acfg->plt_offset_to_entry, GUINT_TO_POINTER (res->plt_offset), res);
acfg->method_indexes = g_hash_table_new (NULL, NULL);
acfg->method_depth = g_hash_table_new (NULL, NULL);
acfg->plt_offset_to_entry = g_hash_table_new (NULL, NULL);
- acfg->patch_to_plt_entry = g_hash_table_new (mono_patch_info_hash, mono_patch_info_equal);
+ acfg->patch_to_plt_entry = g_new0 (GHashTable*, MONO_PATCH_INFO_NUM);
acfg->patch_to_got_offset = g_hash_table_new (mono_patch_info_hash, mono_patch_info_equal);
acfg->patch_to_got_offset_by_type = g_new0 (GHashTable*, MONO_PATCH_INFO_NUM);
for (i = 0; i < MONO_PATCH_INFO_NUM; ++i)
g_hash_table_destroy (acfg->method_indexes);
g_hash_table_destroy (acfg->method_depth);
g_hash_table_destroy (acfg->plt_offset_to_entry);
- g_hash_table_destroy (acfg->patch_to_plt_entry);
+ for (i = 0; i < MONO_PATCH_INFO_NUM; ++i) {
+ if (acfg->patch_to_plt_entry [i])
+ g_hash_table_destroy (acfg->patch_to_plt_entry [i]);
+ }
+ g_free (acfg->patch_to_plt_entry);
g_hash_table_destroy (acfg->patch_to_got_offset);
g_hash_table_destroy (acfg->method_to_cfg);
g_hash_table_destroy (acfg->token_info_hash);
LLVMValueRef got_var;
const char *got_symbol;
GHashTable *plt_entries;
+ char **bb_names;
+ GPtrArray *used;
} MonoLLVMModule;
/*
static LLVMBasicBlockRef
get_bb (EmitContext *ctx, MonoBasicBlock *bb)
{
- char bb_name [128];
+ char bb_name_buf [128];
+ char *bb_name;
if (ctx->bblocks [bb->block_num].bblock == NULL) {
if (bb->flags & BB_EXCEPTION_HANDLER) {
int clause_index = (mono_get_block_region_notry (ctx->cfg, bb->region) >> 8) - 1;
- sprintf (bb_name, "EH_CLAUSE%d_BB%d", clause_index, bb->block_num);
+ sprintf (bb_name_buf, "EH_CLAUSE%d_BB%d", clause_index, bb->block_num);
+ bb_name = bb_name_buf;
+ } else if (bb->block_num < 256) {
+ if (!ctx->lmodule->bb_names)
+ ctx->lmodule->bb_names = g_new0 (char*, 256);
+ if (!ctx->lmodule->bb_names [bb->block_num]) {
+ char *n;
+
+ n = g_strdup_printf ("BB%d", bb->block_num);
+ mono_memory_barrier ();
+ ctx->lmodule->bb_names [bb->block_num] = n;
+ }
+ bb_name = ctx->lmodule->bb_names [bb->block_num];
} else {
- sprintf (bb_name, "BB%d", bb->block_num);
+ sprintf (bb_name_buf, "BB%d", bb->block_num);
+ bb_name = bb_name_buf;
}
ctx->bblocks [bb->block_num].bblock = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
* Put the global into the 'llvm.used' array to prevent it from being optimized away.
*/
static void
-mark_as_used (LLVMModuleRef module, LLVMValueRef global)
+mark_as_used (MonoLLVMModule *lmodule, LLVMValueRef global)
{
+ if (!lmodule->used)
+ lmodule->used = g_ptr_array_sized_new (16);
+ g_ptr_array_add (lmodule->used, global);
+}
+
+static void
+emit_llvm_used (MonoLLVMModule *lmodule)
+{
+ LLVMModuleRef module = lmodule->module;
LLVMTypeRef used_type;
- LLVMValueRef used, used_elem;
+ LLVMValueRef used, *used_elem;
+ int i;
- used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), 1);
+ if (!lmodule->used)
+ return;
+
+ used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), lmodule->used->len);
used = LLVMAddGlobal (module, used_type, "llvm.used");
- used_elem = LLVMConstBitCast (global, LLVMPointerType (LLVMInt8Type (), 0));
- LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), &used_elem, 1));
+ used_elem = g_new0 (LLVMValueRef, lmodule->used->len);
+ for (i = 0; i < lmodule->used->len; ++i)
+ used_elem [i] = LLVMConstBitCast (g_ptr_array_index (lmodule->used, i), LLVMPointerType (LLVMInt8Type (), 0));
+ LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), used_elem, lmodule->used->len));
LLVMSetLinkage (used, LLVMAppendingLinkage);
LLVMSetSection (used, "llvm.metadata");
}
ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
- phi_values = g_ptr_array_new ();
+ phi_values = g_ptr_array_sized_new (256);
/*
* This signals whenever the vreg was defined by a phi node with no input vars
* (i.e. all its input bblocks end with NOT_REACHABLE).
/* Whenever the bblock is unreachable */
ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
- bblock_list = g_ptr_array_new ();
+ bblock_list = g_ptr_array_sized_new (256);
ctx->values = values;
ctx->region_to_handler = g_hash_table_new (NULL, NULL);
if (cfg->verbose_level > 1)
mono_llvm_dump_value (method);
- mark_as_used (module, method);
+ mark_as_used (ctx->lmodule, method);
if (cfg->compile_aot) {
LLVMValueRef md_args [16];
mono_llvm_replace_uses_of (aot_module.got_var, real_got);
- mark_as_used (aot_module.module, real_got);
+ mark_as_used (&aot_module, real_got);
/* Delete the dummy got so it doesn't become a global */
LLVMDeleteGlobal (aot_module.got_var);
+ emit_llvm_used (&aot_module);
+
#if 0
{
char *verifier_err;