Skip to content

Commit

Permalink
[aot] Store the addresses of aot constants in an array instead of usi…
Browse files Browse the repository at this point in the history
…ng a switch statement on wasm to save space. (#45669)

Co-authored-by: vargaz <vargaz@users.noreply.github.com>
  • Loading branch information
monojenkins and vargaz authored Dec 7, 2020
1 parent 86bdbf7 commit 51fc11f
Showing 1 changed file with 54 additions and 4 deletions.
58 changes: 54 additions & 4 deletions src/mono/mono/mini/mini-llvm.c
Original file line number Diff line number Diff line change
Expand Up @@ -2945,11 +2945,9 @@ static void
emit_init_aotconst (MonoLLVMModule *module)
{
LLVMModuleRef lmodule = module->lmodule;
LLVMValueRef func, switch_ins;
LLVMBasicBlockRef entry_bb, fail_bb, bb;
LLVMBasicBlockRef *bbs = NULL;
LLVMValueRef func;
LLVMBasicBlockRef entry_bb;
LLVMBuilderRef builder = LLVMCreateBuilder ();
char *name;

func = LLVMAddFunction (lmodule, module->init_aotconst_symbol, LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), IntPtrType (), FALSE));
LLVMSetLinkage (func, LLVMExternalLinkage);
Expand All @@ -2959,6 +2957,57 @@ emit_init_aotconst (MonoLLVMModule *module)

entry_bb = LLVMAppendBasicBlock (func, "ENTRY");

LLVMPositionBuilderAtEnd (builder, entry_bb);

#ifdef TARGET_WASM
/* Emit a table of aotconst addresses instead of a switch statement to save space */

LLVMValueRef aotconsts;
LLVMTypeRef aotconst_addr_type = LLVMPointerType (module->ptr_type, 0);
int table_size = module->max_got_offset + 1;
LLVMTypeRef aotconst_arr_type = LLVMArrayType (aotconst_addr_type, table_size);

LLVMValueRef aotconst_dummy = LLVMAddGlobal (module->lmodule, module->ptr_type, "aotconst_dummy");
LLVMSetInitializer (aotconst_dummy, LLVMConstNull (module->ptr_type));
LLVMSetVisibility (aotconst_dummy, LLVMHiddenVisibility);
LLVMSetLinkage (aotconst_dummy, LLVMInternalLinkage);

aotconsts = LLVMAddGlobal (module->lmodule, aotconst_arr_type, "aotconsts");
LLVMValueRef *aotconst_init = g_new0 (LLVMValueRef, table_size);
for (int i = 0; i < table_size; ++i) {
LLVMValueRef aotconst = (LLVMValueRef)g_hash_table_lookup (module->aotconst_vars, GINT_TO_POINTER (i));
if (aotconst)
aotconst_init [i] = LLVMConstBitCast (aotconst, aotconst_addr_type);
else
aotconst_init [i] = LLVMConstBitCast (aotconst_dummy, aotconst_addr_type);
}
LLVMSetInitializer (aotconsts, LLVMConstArray (aotconst_addr_type, aotconst_init, table_size));
LLVMSetVisibility (aotconsts, LLVMHiddenVisibility);
LLVMSetLinkage (aotconsts, LLVMInternalLinkage);

LLVMBasicBlockRef exit_bb = LLVMAppendBasicBlock (func, "EXIT_BB");
LLVMBasicBlockRef main_bb = LLVMAppendBasicBlock (func, "BB");

LLVMValueRef cmp = LLVMBuildICmp (builder, LLVMIntSGE, LLVMGetParam (func, 0), LLVMConstInt (LLVMInt32Type (), table_size, FALSE), "");
LLVMBuildCondBr (builder, cmp, exit_bb, main_bb);

LLVMPositionBuilderAtEnd (builder, main_bb);

LLVMValueRef indexes [2];
indexes [0] = LLVMConstInt (LLVMInt32Type (), 0, FALSE);
indexes [1] = LLVMGetParam (func, 0);
LLVMValueRef aotconst_addr = LLVMBuildLoad (builder, LLVMBuildGEP (builder, aotconsts, indexes, 2, ""), "");
LLVMBuildStore (builder, LLVMBuildIntToPtr (builder, LLVMGetParam (func, 1), module->ptr_type, ""), aotconst_addr);
LLVMBuildBr (builder, exit_bb);

LLVMPositionBuilderAtEnd (builder, exit_bb);
LLVMBuildRetVoid (builder);
#else
LLVMValueRef switch_ins;
LLVMBasicBlockRef fail_bb, bb;
LLVMBasicBlockRef *bbs = NULL;
char *name;

bbs = g_new0 (LLVMBasicBlockRef, module->max_got_offset + 1);
for (int i = 0; i < module->max_got_offset + 1; ++i) {
name = g_strdup_printf ("BB_%d", i);
Expand All @@ -2985,6 +3034,7 @@ emit_init_aotconst (MonoLLVMModule *module)
switch_ins = LLVMBuildSwitch (builder, LLVMGetParam (func, 0), fail_bb, 0);
for (int i = 0; i < module->max_got_offset + 1; ++i)
LLVMAddCase (switch_ins, LLVMConstInt (LLVMInt32Type (), i, FALSE), bbs [i]);
#endif

LLVMDisposeBuilder (builder);
}
Expand Down

0 comments on commit 51fc11f

Please sign in to comment.