[WebAssembly] Don't use set_local instructions explicitly.

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.

llvm-svn: 253905
This commit is contained in:
Dan Gohman 2015-11-23 19:30:43 +00:00
parent 941ad90146
commit aa0a4bd05b
3 changed files with 17 additions and 9 deletions

View File

@ -37,19 +37,19 @@ void WebAssemblyInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
const TargetRegisterClass *RC = const TargetRegisterClass *RC =
MBB.getParent()->getRegInfo().getRegClass(SrcReg); MBB.getParent()->getRegInfo().getRegClass(SrcReg);
unsigned SetLocalOpcode; unsigned CopyLocalOpcode;
if (RC == &WebAssembly::I32RegClass) if (RC == &WebAssembly::I32RegClass)
SetLocalOpcode = WebAssembly::SET_LOCAL_I32; CopyLocalOpcode = WebAssembly::COPY_LOCAL_I32;
else if (RC == &WebAssembly::I64RegClass) else if (RC == &WebAssembly::I64RegClass)
SetLocalOpcode = WebAssembly::SET_LOCAL_I64; CopyLocalOpcode = WebAssembly::COPY_LOCAL_I64;
else if (RC == &WebAssembly::F32RegClass) else if (RC == &WebAssembly::F32RegClass)
SetLocalOpcode = WebAssembly::SET_LOCAL_F32; CopyLocalOpcode = WebAssembly::COPY_LOCAL_F32;
else if (RC == &WebAssembly::F64RegClass) else if (RC == &WebAssembly::F64RegClass)
SetLocalOpcode = WebAssembly::SET_LOCAL_F64; CopyLocalOpcode = WebAssembly::COPY_LOCAL_F64;
else else
llvm_unreachable("Unexpected register class"); 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); .addReg(SrcReg, KillSrc ? RegState::Kill : 0);
} }

View File

@ -98,6 +98,14 @@ multiclass LOCAL<WebAssemblyRegClass vt> {
// TODO: set_local returns its operand value // TODO: set_local returns its operand value
def SET_LOCAL_#vt : I<(outs), (ins i32imm:$regno, vt:$src), [], def SET_LOCAL_#vt : I<(outs), (ins i32imm:$regno, vt:$src), [],
"set_local\t$regno, $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<I32>;
defm : LOCAL<I64>; defm : LOCAL<I64>;

View File

@ -26,9 +26,9 @@ done:
; CHECK-LABEL: test1: ; CHECK-LABEL: test1:
; CHECK: BB1_1: ; CHECK: BB1_1:
; CHECK: set_local $[[NUM0:[0-9]+]], $[[NUM1:[0-9]+]]{{$}} ; CHECK: copy_local $[[NUM0:[0-9]+]], $[[NUM1:[0-9]+]]{{$}}
; CHECK: set_local $[[NUM1]], $[[NUM2:[0-9]+]]{{$}} ; CHECK: copy_local $[[NUM1]], $[[NUM2:[0-9]+]]{{$}}
; CHECK: set_local $[[NUM2]], $[[NUM0]]{{$}} ; CHECK: copy_local $[[NUM2]], $[[NUM0]]{{$}}
define i32 @test1(i32 %n) { define i32 @test1(i32 %n) {
entry: entry:
br label %loop br label %loop