[WebAssembly] Add mem.* builtin functions.

This corresponds to r323222 in LLVM. The new names are not yet
finalized, so use them at your own risk.

llvm-svn: 323224
This commit is contained in:
Dan Gohman 2018-01-23 17:04:04 +00:00
parent 6ff241fc99
commit 4f637e0ccc
4 changed files with 42 additions and 7 deletions

View File

@ -16,8 +16,16 @@
// The format of this database matches clang/Basic/Builtins.def. // The format of this database matches clang/Basic/Builtins.def.
// Note that current_memory is not "c" (readnone) because it must be sequenced // Query the current memory size, and increase the current memory size.
// Note that mem.size is not "c" (readnone) because it must be sequenced
// with respect to grow_memory calls. // with respect to grow_memory calls.
// These are the new proposed names, which aren't yet official. Use at your own
// risk.
BUILTIN(__builtin_wasm_mem_size, "zIi", "n")
BUILTIN(__builtin_wasm_mem_grow, "zIiz", "n")
// These are the existing names, which are currently official, but expected
// to be deprecated in the future. They also lack the immediate field.
BUILTIN(__builtin_wasm_current_memory, "z", "n") BUILTIN(__builtin_wasm_current_memory, "z", "n")
BUILTIN(__builtin_wasm_grow_memory, "zz", "n") BUILTIN(__builtin_wasm_grow_memory, "zz", "n")

View File

@ -10495,6 +10495,21 @@ Value *CodeGenFunction::EmitNVPTXBuiltinExpr(unsigned BuiltinID,
Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID, Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID,
const CallExpr *E) { const CallExpr *E) {
switch (BuiltinID) { switch (BuiltinID) {
case WebAssembly::BI__builtin_wasm_mem_size: {
llvm::Type *ResultType = ConvertType(E->getType());
Value *I = EmitScalarExpr(E->getArg(0));
Value *Callee = CGM.getIntrinsic(Intrinsic::wasm_mem_size, ResultType);
return Builder.CreateCall(Callee, I);
}
case WebAssembly::BI__builtin_wasm_mem_grow: {
llvm::Type *ResultType = ConvertType(E->getType());
Value *Args[] = {
EmitScalarExpr(E->getArg(0)),
EmitScalarExpr(E->getArg(1))
};
Value *Callee = CGM.getIntrinsic(Intrinsic::wasm_mem_grow, ResultType);
return Builder.CreateCall(Callee, Args);
}
case WebAssembly::BI__builtin_wasm_current_memory: { case WebAssembly::BI__builtin_wasm_current_memory: {
llvm::Type *ResultType = ConvertType(E->getType()); llvm::Type *ResultType = ConvertType(E->getType());
Value *Callee = CGM.getIntrinsic(Intrinsic::wasm_current_memory, ResultType); Value *Callee = CGM.getIntrinsic(Intrinsic::wasm_current_memory, ResultType);

View File

@ -3,25 +3,37 @@
// RUN: %clang_cc1 -triple wasm64-unknown-unknown -O3 -emit-llvm -o - %s \ // RUN: %clang_cc1 -triple wasm64-unknown-unknown -O3 -emit-llvm -o - %s \
// RUN: | FileCheck %s -check-prefix=WEBASSEMBLY64 // RUN: | FileCheck %s -check-prefix=WEBASSEMBLY64
__SIZE_TYPE__ f1(void) { __SIZE_TYPE__ f0(void) {
return __builtin_wasm_mem_size(0);
// WEBASSEMBLY32: call {{i.*}} @llvm.wasm.mem.size.i32(i32 0)
// WEBASSEMBLY64: call {{i.*}} @llvm.wasm.mem.size.i64(i32 0)
}
__SIZE_TYPE__ f1(__SIZE_TYPE__ delta) {
return __builtin_wasm_mem_grow(0, delta);
// WEBASSEMBLY32: call i32 @llvm.wasm.mem.grow.i32(i32 0, i32 %{{.*}})
// WEBASSEMBLY64: call i64 @llvm.wasm.mem.grow.i64(i32 0, i64 %{{.*}})
}
__SIZE_TYPE__ f2(void) {
return __builtin_wasm_current_memory(); return __builtin_wasm_current_memory();
// WEBASSEMBLY32: call {{i.*}} @llvm.wasm.current.memory.i32() // WEBASSEMBLY32: call {{i.*}} @llvm.wasm.current.memory.i32()
// WEBASSEMBLY64: call {{i.*}} @llvm.wasm.current.memory.i64() // WEBASSEMBLY64: call {{i.*}} @llvm.wasm.current.memory.i64()
} }
__SIZE_TYPE__ f2(__SIZE_TYPE__ delta) { __SIZE_TYPE__ f3(__SIZE_TYPE__ delta) {
return __builtin_wasm_grow_memory(delta); return __builtin_wasm_grow_memory(delta);
// WEBASSEMBLY32: call i32 @llvm.wasm.grow.memory.i32(i32 %{{.*}}) // WEBASSEMBLY32: call i32 @llvm.wasm.grow.memory.i32(i32 %{{.*}})
// WEBASSEMBLY64: call i64 @llvm.wasm.grow.memory.i64(i64 %{{.*}}) // WEBASSEMBLY64: call i64 @llvm.wasm.grow.memory.i64(i64 %{{.*}})
} }
void f3(unsigned int tag, void *obj) { void f4(unsigned int tag, void *obj) {
return __builtin_wasm_throw(tag, obj); return __builtin_wasm_throw(tag, obj);
// WEBASSEMBLY32: call void @llvm.wasm.throw(i32 %{{.*}}, i8* %{{.*}}) // WEBASSEMBLY32: call void @llvm.wasm.throw(i32 %{{.*}}, i8* %{{.*}})
// WEBASSEMBLY64: call void @llvm.wasm.throw(i32 %{{.*}}, i8* %{{.*}}) // WEBASSEMBLY64: call void @llvm.wasm.throw(i32 %{{.*}}, i8* %{{.*}})
} }
void f4() { void f5(void) {
return __builtin_wasm_rethrow(); return __builtin_wasm_rethrow();
// WEBASSEMBLY32: call void @llvm.wasm.rethrow() // WEBASSEMBLY32: call void @llvm.wasm.rethrow()
// WEBASSEMBLY64: call void @llvm.wasm.rethrow() // WEBASSEMBLY64: call void @llvm.wasm.rethrow()

View File

@ -24,7 +24,7 @@ typedef struct {
// Single-element structs should be returned as the one element. // Single-element structs should be returned as the one element.
// WEBASSEMBLY32: define i32 @f2() // WEBASSEMBLY32: define i32 @f2()
// WEBASSEMBLY64: define i32 @f2() // WEBASSEMBLY64: define i32 @f2()
s2 f2() { s2 f2(void) {
s2 foo; s2 foo;
return foo; return foo;
} }
@ -36,7 +36,7 @@ typedef struct {
// Structs should be returned sret and not simplified by the frontend. // Structs should be returned sret and not simplified by the frontend.
// WEBASSEMBLY32: define void @f3(%struct.s3* noalias sret %agg.result) // WEBASSEMBLY32: define void @f3(%struct.s3* noalias sret %agg.result)
// WEBASSEMBLY64: define void @f3(%struct.s3* noalias sret %agg.result) // WEBASSEMBLY64: define void @f3(%struct.s3* noalias sret %agg.result)
s3 f3() { s3 f3(void) {
s3 foo; s3 foo;
return foo; return foo;
} }