Merge remote-tracking branch 'origin/master' into middleware

This commit is contained in:
losfair
2020-06-13 00:55:47 +08:00
105 changed files with 3100 additions and 1137 deletions

View File

@ -110,10 +110,12 @@ impl FuncTranslator {
let entry = self.ctx.append_basic_block(func, "entry");
let start_of_code = self.ctx.append_basic_block(func, "start_of_code");
let return_ = self.ctx.append_basic_block(func, "return");
let alloca_builder = self.ctx.create_builder();
let cache_builder = self.ctx.create_builder();
let builder = self.ctx.create_builder();
cache_builder.position_at_end(entry);
let br = cache_builder.build_unconditional_branch(start_of_code);
alloca_builder.position_before(&br);
cache_builder.position_before(&br);
builder.position_at_end(start_of_code);
@ -139,14 +141,23 @@ impl FuncTranslator {
} else {
1
};
let mut is_first_alloca = true;
let mut insert_alloca = |ty, name| {
let alloca = alloca_builder.build_alloca(ty, name);
if is_first_alloca {
alloca_builder.position_at(entry, &alloca.as_instruction_value().unwrap());
is_first_alloca = false;
}
alloca
};
for idx in 0..wasm_fn_type.params().len() {
let ty = wasm_fn_type.params()[idx];
let ty = type_to_llvm(&intrinsics, ty)?;
let value = func
.get_nth_param((idx as u32).checked_add(first_param).unwrap())
.unwrap();
// TODO: don't interleave allocas and stores.
let alloca = cache_builder.build_alloca(ty, "param");
let alloca = insert_alloca(ty, "param");
cache_builder.build_store(alloca, value);
params.push(alloca);
}
@ -160,9 +171,8 @@ impl FuncTranslator {
.map_err(to_wasm_error)?;
let ty = wptype_to_type(ty).map_err(to_compile_error)?;
let ty = type_to_llvm(&intrinsics, ty)?;
// TODO: don't interleave allocas and stores.
for _ in 0..count {
let alloca = cache_builder.build_alloca(ty, "local");
let alloca = insert_alloca(ty, "local");
cache_builder.build_store(alloca, const_zero(ty));
locals.push(alloca);
}
@ -174,6 +184,7 @@ impl FuncTranslator {
let mut fcg = LLVMFunctionCodeGenerator {
context: &self.ctx,
builder,
alloca_builder,
intrinsics: &intrinsics,
state,
function: func,
@ -608,7 +619,7 @@ impl<'ctx, 'a> LLVMFunctionCodeGenerator<'ctx, 'a> {
let divisor_is_zero = self.builder.build_int_compare(
IntPredicate::EQ,
right,
int_type.const_int(0, false),
int_type.const_zero(),
"divisor_is_zero",
);
let should_trap = self.builder.build_or(
@ -633,10 +644,7 @@ impl<'ctx, 'a> LLVMFunctionCodeGenerator<'ctx, 'a> {
self.intrinsics.expect_i1,
&[
should_trap.as_basic_value_enum(),
self.intrinsics
.i1_ty
.const_int(0, false)
.as_basic_value_enum(),
self.intrinsics.i1_ty.const_zero().as_basic_value_enum(),
],
"should_trap_expect",
)
@ -671,7 +679,7 @@ impl<'ctx, 'a> LLVMFunctionCodeGenerator<'ctx, 'a> {
let should_trap = self.builder.build_int_compare(
IntPredicate::EQ,
value,
int_type.const_int(0, false),
int_type.const_zero(),
"divisor_is_zero",
);
@ -681,10 +689,7 @@ impl<'ctx, 'a> LLVMFunctionCodeGenerator<'ctx, 'a> {
self.intrinsics.expect_i1,
&[
should_trap.as_basic_value_enum(),
self.intrinsics
.i1_ty
.const_int(0, false)
.as_basic_value_enum(),
self.intrinsics.i1_ty.const_zero().as_basic_value_enum(),
],
"should_trap_expect",
)
@ -1179,7 +1184,7 @@ fn emit_stack_map<'ctx>(
.const_int(stackmap_id as u64, false)
.as_basic_value_enum(),
);
params.push(intrinsics.i32_ty.const_int(0, false).as_basic_value_enum());
params.push(intrinsics.i32_ty.const_zero().as_basic_value_enum());
let locals: Vec<_> = locals.iter().map(|x| x.as_basic_value_enum()).collect();
let mut value_semantics: Vec<ValueSemantic> =
@ -1226,7 +1231,7 @@ fn finalize_opcode_stack_map<'ctx>(
.i64_ty
.const_int(stackmap_id as u64, false)
.as_basic_value_enum(),
intrinsics.i32_ty.const_int(0, false).as_basic_value_enum(),
intrinsics.i32_ty.const_zero().as_basic_value_enum(),
],
"opcode_stack_map_end",
);
@ -1245,6 +1250,7 @@ fn finalize_opcode_stack_map<'ctx>(
pub struct LLVMFunctionCodeGenerator<'ctx, 'a> {
context: &'ctx Context,
builder: Builder<'ctx>,
alloca_builder: Builder<'ctx>,
intrinsics: &'a Intrinsics<'ctx>,
state: State<'ctx>,
function: FunctionValue<'ctx>,
@ -1390,7 +1396,7 @@ impl<'ctx, 'a> LLVMFunctionCodeGenerator<'ctx, 'a> {
);
let signal_mem = ctx.signal_mem();
let iv = self.builder
.build_store(signal_mem, self.context.i8_type().const_int(0 as u64, false));
.build_store(signal_mem, self.context.i8_type().const_zero());
// Any 'store' can be made volatile.
iv.set_volatile(true).unwrap();
finalize_opcode_stack_map(
@ -1617,14 +1623,13 @@ impl<'ctx, 'a> LLVMFunctionCodeGenerator<'ctx, 'a> {
let current_block = self.builder.get_insert_block().ok_or_else(|| {
CompileError::Codegen("not currently in a block".to_string())
})?;
self.builder.build_unconditional_branch(*frame.code_after());
for phi in frame.phis().to_vec().iter().rev() {
let (value, info) = self.state.pop1_extra()?;
let value = self.apply_pending_canonicalization(value, info);
phi.add_incoming(&[(&value, current_block)])
}
let frame = self.state.frame_at_depth(0)?;
self.builder.build_unconditional_branch(*frame.code_after());
}
let (if_else_block, if_else_state) = if let ControlFrame::IfElse {
@ -1696,19 +1701,7 @@ impl<'ctx, 'a> LLVMFunctionCodeGenerator<'ctx, 'a> {
self.state.push1(phi.as_basic_value());
} else {
let basic_ty = phi.as_basic_value().get_type();
let placeholder_value = match basic_ty {
BasicTypeEnum::IntType(int_ty) => {
int_ty.const_int(0, false).as_basic_value_enum()
}
BasicTypeEnum::FloatType(float_ty) => {
float_ty.const_float(0.0).as_basic_value_enum()
}
_ => {
return Err(CompileError::Codegen(
"Operator::End phi type unimplemented".to_string(),
));
}
};
let placeholder_value = const_zero(basic_ty);
self.state.push1(placeholder_value);
phi.as_instruction().erase_from_basic_block();
}
@ -1721,15 +1714,13 @@ impl<'ctx, 'a> LLVMFunctionCodeGenerator<'ctx, 'a> {
.ok_or_else(|| CompileError::Codegen("not currently in a block".to_string()))?;
let frame = self.state.outermost_frame()?;
self.builder.build_unconditional_branch(*frame.br_dest());
for phi in frame.phis().to_vec().iter().rev() {
let (arg, info) = self.state.pop1_extra()?;
let arg = self.apply_pending_canonicalization(arg, info);
phi.add_incoming(&[(&arg, current_block)]);
}
let frame = self.state.outermost_frame()?;
self.builder.build_unconditional_branch(*frame.br_dest());
self.state.reachable = false;
}
@ -2090,8 +2081,7 @@ impl<'ctx, 'a> LLVMFunctionCodeGenerator<'ctx, 'a> {
});
let params = abi::args_to_call(
// TODO: should be an alloca_builder.
&self.builder,
&self.alloca_builder,
func_type,
callee_vmctx.into_pointer_value(),
&func.get_type().get_element_type().into_function_type(),
@ -2334,8 +2324,7 @@ impl<'ctx, 'a> LLVMFunctionCodeGenerator<'ctx, 'a> {
});
let params = abi::args_to_call(
// TODO: should be an alloca_builder.
&self.builder,
&self.alloca_builder,
func_type,
ctx_ptr.into_pointer_value(),
&llvm_func_type,