[mono/mono] f8e9706a: [llvm] Add some micro optimizations to the LLVM/AOT code.

"Zoltan Varga ([email protected])" <[email protected]> Mon, 18 Nov 2013 06:53:38 +0000
Newsgroups gmane.comp.gnome.mono.patches
Message-ID <0000014269fc6566-ffd04d10-d379-48c2-9ada-1643c181442a-000000@email.amazonses.com>
   Branch: refs/heads/master
     Home: https://github.com/mono/mono
  Compare: https://github.com/mono/mono/compare/5106e3a56d72...f8e9706a451c

   Commit: f8e9706a451c65bf28aeb5820d0ab4ca9b916221
   Author: Zoltan Varga <[email protected]> (vargaz)
     Date: 2013-11-18 06:52:32 GMT
      URL: https://github.com/mono/mono/commit/f8e9706a451c65bf28aeb5820d0ab4ca9b916221

[llvm] Add some micro optimizations to the LLVM/AOT code.

Changed paths:
  M mono/mini/aot-compiler.c
  M mono/mini/mini-llvm.c

Modified: mono/mini/aot-compiler.c
===================================================================
@@ -165,7 +165,7 @@ struct _ReadOnlyValue {
 	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;
@@ -2906,7 +2906,9 @@ struct _ReadOnlyValue {
 	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)) {
@@ -2936,7 +2938,7 @@ struct _ReadOnlyValue {
 		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);
 
@@ -8530,7 +8532,7 @@ struct _ReadOnlyValue {
 	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)
@@ -8582,7 +8584,11 @@ struct _ReadOnlyValue {
 	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);

Modified: mono/mini/mini-llvm.c
===================================================================
@@ -35,6 +35,8 @@
 	LLVMValueRef got_var;
 	const char *got_symbol;
 	GHashTable *plt_entries;
+	char **bb_names;
+	GPtrArray *used;
 } MonoLLVMModule;
 
 /*
@@ -845,14 +847,28 @@
 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);
@@ -1669,15 +1685,30 @@
  * 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");
 }
@@ -4217,7 +4248,7 @@
 	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).
@@ -4226,7 +4257,7 @@
 	/* 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);
@@ -4517,7 +4548,7 @@
 	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];
@@ -5185,11 +5216,13 @@
 
 	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;


_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches