summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td
diff options
context:
space:
mode:
authorDan Gohman <dan433584@gmail.com>2016-10-24 19:49:43 +0000
committerDan Gohman <dan433584@gmail.com>2016-10-24 19:49:43 +0000
commit4fc4e42dea2547f40d3672ccf473fc2fbbdfc903 (patch)
treeebcc8d0e10c97409e41a89e296db5aca2f0ce7fc /llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td
parentc3e0ce8f8527d340c168d7361c1c59d8df544ecb (diff)
downloadbcm5719-llvm-4fc4e42dea2547f40d3672ccf473fc2fbbdfc903.tar.gz
bcm5719-llvm-4fc4e42dea2547f40d3672ccf473fc2fbbdfc903.zip
[WebAssembly] Add an option to make get_local/set_local explicit.
This patch adds a pass, controlled by an option and off by default for now, for making implicit get_local/set_local explicit. This simplifies emitting wasm with MC. Differential Revision: https://reviews.llvm.org/D25836 llvm-svn: 285009
Diffstat (limited to 'llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td')
-rw-r--r--llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td68
1 files changed, 50 insertions, 18 deletions
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td
index a316a74fdd2..f774e90d22f 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td
@@ -71,6 +71,9 @@ let OperandNamespace = "WebAssembly" in {
let OperandType = "OPERAND_BASIC_BLOCK" in
def bb_op : Operand<OtherVT>;
+let OperandType = "OPERAND_LOCAL" in
+def local_op : Operand<i32>;
+
let OperandType = "OPERAND_I32IMM" in
def i32imm_op : Operand<i32>;
@@ -133,20 +136,42 @@ let Defs = [ARGUMENTS] in {
// are implied by virtual register uses and defs.
multiclass LOCAL<WebAssemblyRegClass vt> {
let hasSideEffects = 0 in {
- // COPY_LOCAL is not an actual instruction in wasm, but since we allow
- // get_local and set_local to be implicit, we can have a COPY_LOCAL which
- // is actually a no-op because all the work is done in the implied
- // get_local and set_local.
- let isAsCheapAsAMove = 1 in
- def COPY_LOCAL_#vt : I<(outs vt:$res), (ins vt:$src), [],
- "copy_local\t$res, $src">;
-
- // TEE_LOCAL is similar to COPY_LOCAL, but writes two copies of its result.
- // Typically this would be used to stackify one result and write the other
- // result to a local.
- let isAsCheapAsAMove = 1 in
- def TEE_LOCAL_#vt : I<(outs vt:$res, vt:$also), (ins vt:$src), [],
- "tee_local\t$res, $also, $src">;
+ // COPY is not an actual instruction in wasm, but since we allow get_local and
+ // set_local to be implicit during most of codegen, we can have a COPY which
+ // is actually a no-op because all the work is done in the implied get_local
+ // and set_local. COPYs are eliminated (and replaced with
+ // get_local/set_local) in the ExplicitLocals pass.
+ let isAsCheapAsAMove = 1, isCodeGenOnly = 1 in
+ def COPY_#vt : I<(outs vt:$res), (ins vt:$src), [], "copy_local\t$res, $src">;
+
+ // TEE is similar to COPY, but writes two copies of its result. Typically
+ // this would be used to stackify one result and write the other result to a
+ // local.
+ let isAsCheapAsAMove = 1, isCodeGenOnly = 1 in
+ def TEE_#vt : I<(outs vt:$res, vt:$also), (ins vt:$src), [],
+ "tee_local\t$res, $also, $src">;
+
+ // This is the actual get_local instruction in wasm. These are made explicit
+ // by the ExplicitLocals pass. It has mayLoad because it reads from a wasm
+ // local, which is a side effect not otherwise modeled in LLVM.
+ let mayLoad = 1, isAsCheapAsAMove = 1 in
+ def GET_LOCAL_#vt : I<(outs vt:$res), (ins local_op:$local), [],
+ "get_local\t$res, $local", 0x14>;
+
+ // This is the actual set_local instruction in wasm. These are made explicit
+ // by the ExplicitLocals pass. It has mayStore because it writes to a wasm
+ // local, which is a side effect not otherwise modeled in LLVM.
+ let mayStore = 1, isAsCheapAsAMove = 1 in
+ def SET_LOCAL_#vt : I<(outs), (ins local_op:$local, vt:$src), [],
+ "set_local\t$local, $src", 0x15>;
+
+ // This is the actual tee_local instruction in wasm. TEEs are turned into
+ // TEE_LOCALs by the ExplicitLocals pass. It has mayStore for the same reason
+ // as SET_LOCAL.
+ let mayStore = 1, isAsCheapAsAMove = 1 in
+ def TEE_LOCAL_#vt : I<(outs vt:$res), (ins local_op:$local, vt:$src), [],
+ "tee_local\t$res, $local, $src", 0x19>;
+
} // hasSideEffects = 0
}
defm : LOCAL<I32>;
@@ -155,19 +180,26 @@ defm : LOCAL<F32>;
defm : LOCAL<F64>;
defm : LOCAL<V128>, Requires<[HasSIMD128]>;
+// Set TSFlags{0} to 1 to indicate that the variable_ops are immediates.
+// Set TSFlags{2} to 1 to indicate that the immediates are ValTypes.
+def DECLARE_LOCALS : I<(outs), (ins variable_ops), [], ".local \t"> {
+ let TSFlags{0} = 1;
+ let TSFlags{2} = 1;
+}
+
let isMoveImm = 1, isAsCheapAsAMove = 1, isReMaterializable = 1 in {
def CONST_I32 : I<(outs I32:$res), (ins i32imm_op:$imm),
[(set I32:$res, imm:$imm)],
- "i32.const\t$res, $imm">;
+ "i32.const\t$res, $imm", 0x10>;
def CONST_I64 : I<(outs I64:$res), (ins i64imm_op:$imm),
[(set I64:$res, imm:$imm)],
- "i64.const\t$res, $imm">;
+ "i64.const\t$res, $imm", 0x11>;
def CONST_F32 : I<(outs F32:$res), (ins f32imm_op:$imm),
[(set F32:$res, fpimm:$imm)],
- "f32.const\t$res, $imm">;
+ "f32.const\t$res, $imm", 0x13>;
def CONST_F64 : I<(outs F64:$res), (ins f64imm_op:$imm),
[(set F64:$res, fpimm:$imm)],
- "f64.const\t$res, $imm">;
+ "f64.const\t$res, $imm", 0x12>;
} // isMoveImm = 1, isAsCheapAsAMove = 1, isReMaterializable = 1
} // Defs = [ARGUMENTS]
OpenPOWER on IntegriCloud