[WebAssembly] Don't use set_local instructions explicitly.
authorDan Gohman <dan433584@gmail.com>
Mon, 23 Nov 2015 19:30:43 +0000 (19:30 +0000)
committerDan Gohman <dan433584@gmail.com>
Mon, 23 Nov 2015 19:30:43 +0000 (19:30 +0000)
The current approach to using get_local and set_local is to use them
implicitly, as register uses and defs. Introduce new copy instructions
which are themselves no-ops except for the get_local and set_local
that they imply, so that we use get_local and set_local consistently.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@253905 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/WebAssembly/WebAssemblyInstrInfo.cpp
lib/Target/WebAssembly/WebAssemblyInstrInfo.td
test/CodeGen/WebAssembly/phi.ll

index 97e8487..2f1d5eb 100644 (file)
@@ -37,19 +37,19 @@ void WebAssemblyInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
   const TargetRegisterClass *RC =
       MBB.getParent()->getRegInfo().getRegClass(SrcReg);
 
-  unsigned SetLocalOpcode;
+  unsigned CopyLocalOpcode;
   if (RC == &WebAssembly::I32RegClass)
-    SetLocalOpcode = WebAssembly::SET_LOCAL_I32;
+    CopyLocalOpcode = WebAssembly::COPY_LOCAL_I32;
   else if (RC == &WebAssembly::I64RegClass)
-    SetLocalOpcode = WebAssembly::SET_LOCAL_I64;
+    CopyLocalOpcode = WebAssembly::COPY_LOCAL_I64;
   else if (RC == &WebAssembly::F32RegClass)
-    SetLocalOpcode = WebAssembly::SET_LOCAL_F32;
+    CopyLocalOpcode = WebAssembly::COPY_LOCAL_F32;
   else if (RC == &WebAssembly::F64RegClass)
-    SetLocalOpcode = WebAssembly::SET_LOCAL_F64;
+    CopyLocalOpcode = WebAssembly::COPY_LOCAL_F64;
   else
     llvm_unreachable("Unexpected register class");
 
-  BuildMI(MBB, I, DL, get(SetLocalOpcode), DestReg)
+  BuildMI(MBB, I, DL, get(CopyLocalOpcode), DestReg)
       .addReg(SrcReg, KillSrc ? RegState::Kill : 0);
 }
 
index 1fa7902..5922f95 100644 (file)
@@ -98,6 +98,14 @@ multiclass LOCAL<WebAssemblyRegClass vt> {
   // TODO: set_local returns its operand value
   def SET_LOCAL_#vt : I<(outs), (ins i32imm:$regno, vt:$src), [],
                         "set_local\t$regno, $src">;
+
+  // 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">;
 }
 defm : LOCAL<I32>;
 defm : LOCAL<I64>;
index 8db0958..13ce6da 100644 (file)
@@ -26,9 +26,9 @@ done:
 
 ; CHECK-LABEL: test1:
 ; CHECK: BB1_1:
-; CHECK: set_local $[[NUM0:[0-9]+]], $[[NUM1:[0-9]+]]{{$}}
-; CHECK: set_local $[[NUM1]], $[[NUM2:[0-9]+]]{{$}}
-; CHECK: set_local $[[NUM2]], $[[NUM0]]{{$}}
+; CHECK: copy_local $[[NUM0:[0-9]+]], $[[NUM1:[0-9]+]]{{$}}
+; CHECK: copy_local $[[NUM1]], $[[NUM2:[0-9]+]]{{$}}
+; CHECK: copy_local $[[NUM2]], $[[NUM0]]{{$}}
 define i32 @test1(i32 %n) {
 entry:
   br label %loop