Skip to content

Commit

Permalink
[WebAssembly] Make expression-stack pushing explicit
Browse files Browse the repository at this point in the history
Modelling of the expression stack is evolving. This patch takes another
step by making pushes explicit.

Differential Revision: http://reviews.llvm.org/D14338

llvm-svn: 252334
  • Loading branch information
Dan Gohman committed Nov 6, 2015
1 parent 55ea67c commit 4b96d8d
Show file tree
Hide file tree
Showing 16 changed files with 210 additions and 198 deletions.
26 changes: 19 additions & 7 deletions llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
Expand Up @@ -269,33 +269,39 @@ void WebAssemblyAsmPrinter::EmitInstruction(const MachineInstr *MI) {

switch (MI->getOpcode()) {
case TargetOpcode::COPY:
OS << "get_local " << regToString(MI->getOperand(1));
OS << "get_local push, " << regToString(MI->getOperand(1));
break;
case WebAssembly::GLOBAL:
// TODO: wasm64
OS << "i32.const " << toSymbol(MI->getOperand(1).getGlobal()->getName());
OS << "i32.const push, " << toSymbol(MI->getOperand(1).getGlobal()->getName());
break;
case WebAssembly::ARGUMENT_I32:
case WebAssembly::ARGUMENT_I64:
case WebAssembly::ARGUMENT_F32:
case WebAssembly::ARGUMENT_F64:
OS << "get_local " << argToString(MI->getOperand(1));
OS << "get_local push, " << argToString(MI->getOperand(1));
break;
case WebAssembly::Const_I32:
OS << "i32.const " << MI->getOperand(1).getImm();
OS << "i32.const push, " << MI->getOperand(1).getImm();
break;
case WebAssembly::Const_I64:
OS << "i64.const " << MI->getOperand(1).getImm();
OS << "i64.const push, " << MI->getOperand(1).getImm();
break;
case WebAssembly::Const_F32:
OS << "f32.const " << toString(MI->getOperand(1).getFPImm()->getValueAPF());
OS << "f32.const push, " << toString(MI->getOperand(1).getFPImm()->getValueAPF());
break;
case WebAssembly::Const_F64:
OS << "f64.const " << toString(MI->getOperand(1).getFPImm()->getValueAPF());
OS << "f64.const push, " << toString(MI->getOperand(1).getFPImm()->getValueAPF());
break;
default: {
OS << OpcodeName(TII, MI);
bool NeedComma = false;
bool DefsPushed = false;
if (NumDefs != 0 && !MI->isCall()) {
OS << " push";
NeedComma = true;
DefsPushed = true;
}
for (const MachineOperand &MO : MI->uses()) {
if (MO.isReg() && MO.isImplicit())
continue;
Expand All @@ -322,6 +328,12 @@ void WebAssemblyAsmPrinter::EmitInstruction(const MachineInstr *MI) {
OS << toSymbol(MO.getMBB()->getSymbol()->getName());
break;
}
if (NumDefs != 0 && !DefsPushed) {
// Special-case for calls; print the push after the callee.
assert(MI->isCall());
OS << ", push";
DefsPushed = true;
}
}
break;
}
Expand Down
22 changes: 11 additions & 11 deletions llvm/test/CodeGen/WebAssembly/call.ll
Expand Up @@ -16,7 +16,7 @@ declare void @void_nullary()
; CHECK-LABEL: call_i32_nullary:
; CHECK-NEXT: .result i32
; CHECK-NEXT: .local i32
; CHECK-NEXT: call $i32_nullary
; CHECK-NEXT: call $i32_nullary, push{{$}}
; CHECK-NEXT: set_local 0, pop
; CHECK-NEXT: return (get_local 0)
define i32 @call_i32_nullary() {
Expand All @@ -27,7 +27,7 @@ define i32 @call_i32_nullary() {
; CHECK-LABEL: call_i64_nullary:
; CHECK-NEXT: .result i64
; CHECK-NEXT: .local i64
; CHECK-NEXT: call $i64_nullary
; CHECK-NEXT: call $i64_nullary, push{{$}}
; CHECK-NEXT: set_local 0, pop
; CHECK-NEXT: return (get_local 0)
define i64 @call_i64_nullary() {
Expand All @@ -38,7 +38,7 @@ define i64 @call_i64_nullary() {
; CHECK-LABEL: call_float_nullary:
; CHECK-NEXT: .result f32
; CHECK-NEXT: .local f32
; CHECK-NEXT: call $float_nullary
; CHECK-NEXT: call $float_nullary, push{{$}}
; CHECK-NEXT: set_local 0, pop
; CHECK-NEXT: return (get_local 0)
define float @call_float_nullary() {
Expand All @@ -49,7 +49,7 @@ define float @call_float_nullary() {
; CHECK-LABEL: call_double_nullary:
; CHECK-NEXT: .result f64
; CHECK-NEXT: .local f64
; CHECK-NEXT: call $double_nullary
; CHECK-NEXT: call $double_nullary, push{{$}}
; CHECK-NEXT: set_local 0, pop
; CHECK-NEXT: return (get_local 0)
define double @call_double_nullary() {
Expand All @@ -58,7 +58,7 @@ define double @call_double_nullary() {
}

; CHECK-LABEL: call_void_nullary:
; CHECK-NEXT: call $void_nullary
; CHECK-NEXT: call $void_nullary{{$}}
; CHECK-NEXT: return
define void @call_void_nullary() {
call void @void_nullary()
Expand All @@ -71,7 +71,7 @@ define void @call_void_nullary() {
; CHECK-NEXT: .local i32, i32
; CHECK-NEXT: get_local 0
; CHECK-NEXT: set_local 1, pop
; CHECK-NEXT: call $i32_unary, (get_local 1)
; CHECK-NEXT: call $i32_unary, push, (get_local 1){{$}}
; CHECK-NEXT: set_local 2, pop
; CHECK-NEXT: return (get_local 2)
define i32 @call_i32_unary(i32 %a) {
Expand All @@ -88,7 +88,7 @@ define i32 @call_i32_unary(i32 %a) {
; CHECK-NEXT: set_local 2, pop
; CHECK-NEXT: get_local 0
; CHECK-NEXT: set_local 3, pop
; CHECK-NEXT: call $i32_binary, (get_local 3), (get_local 2)
; CHECK-NEXT: call $i32_binary, push, (get_local 3), (get_local 2){{$}}
; CHECK-NEXT: set_local 4, pop
; CHECK-NEXT: return (get_local 4)
define i32 @call_i32_binary(i32 %a, i32 %b) {
Expand All @@ -101,7 +101,7 @@ define i32 @call_i32_binary(i32 %a, i32 %b) {
; CHECK-NEXT: .local i32
; CHECK-NEXT: get_local 0
; CHECK-NEXT: set_local 1, pop
; CHECK-NEXT: call_indirect (get_local 1)
; CHECK-NEXT: call_indirect (get_local 1){{$}}
; CHECK-NEXT: return
define void @call_indirect_void(void ()* %callee) {
call void %callee()
Expand All @@ -114,7 +114,7 @@ define void @call_indirect_void(void ()* %callee) {
; CHECK-NEXT: .local i32, i32
; CHECK-NEXT: get_local 0
; CHECK-NEXT: set_local 1, pop
; CHECK-NEXT: call_indirect (get_local 1)
; CHECK-NEXT: call_indirect (get_local 1), push{{$}}
; CHECK-NEXT: set_local 2, pop
; CHECK-NEXT: return (get_local 2)
define i32 @call_indirect_i32(i32 ()* %callee) {
Expand All @@ -123,15 +123,15 @@ define i32 @call_indirect_i32(i32 ()* %callee) {
}

; CHECK-LABEL: tail_call_void_nullary:
; CHECK-NEXT: call $void_nullary
; CHECK-NEXT: call $void_nullary{{$}}
; CHECK-NEXT: return{{$}}
define void @tail_call_void_nullary() {
tail call void @void_nullary()
ret void
}

; CHECK-LABEL: fastcc_tail_call_void_nullary:
; CHECK-NEXT: call $void_nullary
; CHECK-NEXT: call $void_nullary{{$}}
; CHECK-NEXT: return{{$}}
define void @fastcc_tail_call_void_nullary() {
tail call fastcc void @void_nullary()
Expand Down
44 changes: 22 additions & 22 deletions llvm/test/CodeGen/WebAssembly/comparisons_f32.ll
Expand Up @@ -15,11 +15,11 @@ target triple = "wasm32-unknown-unknown"
; CHECK-NEXT: set_local 2, pop{{$}}
; CHECK-NEXT: get_local 1{{$}}
; CHECK-NEXT: set_local 3, pop{{$}}
; CHECK-NEXT: eq (get_local 3), (get_local 3){{$}}
; CHECK-NEXT: eq push, (get_local 3), (get_local 3){{$}}
; CHECK-NEXT: set_local 4, pop{{$}}
; CHECK-NEXT: eq (get_local 2), (get_local 2){{$}}
; CHECK-NEXT: eq push, (get_local 2), (get_local 2){{$}}
; CHECK-NEXT: set_local 5, pop{{$}}
; CHECK-NEXT: and (get_local 5), (get_local 4){{$}}
; CHECK-NEXT: and push, (get_local 5), (get_local 4){{$}}
; CHECK-NEXT: set_local 6, pop{{$}}
; CHECK-NEXT: return (get_local 6){{$}}
define i32 @ord_f32(float %x, float %y) {
Expand All @@ -37,11 +37,11 @@ define i32 @ord_f32(float %x, float %y) {
; CHECK-NEXT: set_local 2, pop{{$}}
; CHECK-NEXT: get_local 1{{$}}
; CHECK-NEXT: set_local 3, pop{{$}}
; CHECK-NEXT: ne (get_local 3), (get_local 3){{$}}
; CHECK-NEXT: ne push, (get_local 3), (get_local 3){{$}}
; CHECK-NEXT: set_local 4, pop{{$}}
; CHECK-NEXT: ne (get_local 2), (get_local 2){{$}}
; CHECK-NEXT: ne push, (get_local 2), (get_local 2){{$}}
; CHECK-NEXT: set_local 5, pop{{$}}
; CHECK-NEXT: or (get_local 5), (get_local 4){{$}}
; CHECK-NEXT: or push, (get_local 5), (get_local 4){{$}}
; CHECK-NEXT: set_local 6, pop{{$}}
; CHECK-NEXT: return (get_local 6){{$}}
define i32 @uno_f32(float %x, float %y) {
Expand All @@ -59,7 +59,7 @@ define i32 @uno_f32(float %x, float %y) {
; CHECK-NEXT: set_local 2, pop{{$}}
; CHECK-NEXT: get_local 0{{$}}
; CHECK-NEXT: set_local 3, pop{{$}}
; CHECK-NEXT: eq (get_local 3), (get_local 2){{$}}
; CHECK-NEXT: eq push, (get_local 3), (get_local 2){{$}}
; CHECK-NEXT: set_local 4, pop{{$}}
; CHECK-NEXT: return (get_local 4){{$}}
define i32 @oeq_f32(float %x, float %y) {
Expand All @@ -69,7 +69,7 @@ define i32 @oeq_f32(float %x, float %y) {
}

; CHECK-LABEL: une_f32:
; CHECK: ne (get_local 3), (get_local 2){{$}}
; CHECK: ne push, (get_local 3), (get_local 2){{$}}
; CHECK-NEXT: set_local 4, pop{{$}}
define i32 @une_f32(float %x, float %y) {
%a = fcmp une float %x, %y
Expand All @@ -78,7 +78,7 @@ define i32 @une_f32(float %x, float %y) {
}

; CHECK-LABEL: olt_f32:
; CHECK: lt (get_local 3), (get_local 2){{$}}
; CHECK: lt push, (get_local 3), (get_local 2){{$}}
; CHECK-NEXT: set_local 4, pop{{$}}
define i32 @olt_f32(float %x, float %y) {
%a = fcmp olt float %x, %y
Expand All @@ -87,7 +87,7 @@ define i32 @olt_f32(float %x, float %y) {
}

; CHECK-LABEL: ole_f32:
; CHECK: le (get_local 3), (get_local 2){{$}}
; CHECK: le push, (get_local 3), (get_local 2){{$}}
; CHECK-NEXT: set_local 4, pop{{$}}
define i32 @ole_f32(float %x, float %y) {
%a = fcmp ole float %x, %y
Expand All @@ -96,7 +96,7 @@ define i32 @ole_f32(float %x, float %y) {
}

; CHECK-LABEL: ogt_f32:
; CHECK: gt (get_local 3), (get_local 2){{$}}
; CHECK: gt push, (get_local 3), (get_local 2){{$}}
; CHECK-NEXT: set_local 4, pop{{$}}
define i32 @ogt_f32(float %x, float %y) {
%a = fcmp ogt float %x, %y
Expand All @@ -105,7 +105,7 @@ define i32 @ogt_f32(float %x, float %y) {
}

; CHECK-LABEL: oge_f32:
; CHECK: ge (get_local 3), (get_local 2){{$}}
; CHECK: ge push, (get_local 3), (get_local 2){{$}}
; CHECK-NEXT: set_local 4, pop{{$}}
define i32 @oge_f32(float %x, float %y) {
%a = fcmp oge float %x, %y
Expand All @@ -124,15 +124,15 @@ define i32 @oge_f32(float %x, float %y) {
; CHECK-NEXT: set_local 2, pop{{$}}
; CHECK-NEXT: get_local 0{{$}}
; CHECK-NEXT: set_local 3, pop{{$}}
; CHECK-NEXT: eq (get_local 3), (get_local 2){{$}}
; CHECK-NEXT: eq push, (get_local 3), (get_local 2){{$}}
; CHECK-NEXT: set_local 4, pop{{$}}
; CHECK-NEXT: ne (get_local 2), (get_local 2){{$}}
; CHECK-NEXT: ne push, (get_local 2), (get_local 2){{$}}
; CHECK-NEXT: set_local 5, pop{{$}}
; CHECK-NEXT: ne (get_local 3), (get_local 3){{$}}
; CHECK-NEXT: ne push, (get_local 3), (get_local 3){{$}}
; CHECK-NEXT: set_local 6, pop{{$}}
; CHECK-NEXT: or (get_local 6), (get_local 5){{$}}
; CHECK-NEXT: or push, (get_local 6), (get_local 5){{$}}
; CHECK-NEXT: set_local 7, pop{{$}}
; CHECK-NEXT: or (get_local 4), (get_local 7){{$}}
; CHECK-NEXT: or push, (get_local 4), (get_local 7){{$}}
; CHECK-NEXT: set_local 8, pop{{$}}
; CHECK-NEXT: return (get_local 8){{$}}
define i32 @ueq_f32(float %x, float %y) {
Expand All @@ -142,7 +142,7 @@ define i32 @ueq_f32(float %x, float %y) {
}

; CHECK-LABEL: one_f32:
; CHECK: ne (get_local 3), (get_local 2){{$}}
; CHECK: ne push, (get_local 3), (get_local 2){{$}}
; CHECK-NEXT: set_local 4, pop{{$}}
define i32 @one_f32(float %x, float %y) {
%a = fcmp one float %x, %y
Expand All @@ -151,7 +151,7 @@ define i32 @one_f32(float %x, float %y) {
}

; CHECK-LABEL: ult_f32:
; CHECK: lt (get_local 3), (get_local 2){{$}}
; CHECK: lt push, (get_local 3), (get_local 2){{$}}
; CHECK-NEXT: set_local 4, pop{{$}}
define i32 @ult_f32(float %x, float %y) {
%a = fcmp ult float %x, %y
Expand All @@ -160,7 +160,7 @@ define i32 @ult_f32(float %x, float %y) {
}

; CHECK-LABEL: ule_f32:
; CHECK: le (get_local 3), (get_local 2){{$}}
; CHECK: le push, (get_local 3), (get_local 2){{$}}
; CHECK-NEXT: set_local 4, pop{{$}}
define i32 @ule_f32(float %x, float %y) {
%a = fcmp ule float %x, %y
Expand All @@ -169,7 +169,7 @@ define i32 @ule_f32(float %x, float %y) {
}

; CHECK-LABEL: ugt_f32:
; CHECK: gt (get_local 3), (get_local 2){{$}}
; CHECK: gt push, (get_local 3), (get_local 2){{$}}
; CHECK-NEXT: set_local 4, pop{{$}}
define i32 @ugt_f32(float %x, float %y) {
%a = fcmp ugt float %x, %y
Expand All @@ -178,7 +178,7 @@ define i32 @ugt_f32(float %x, float %y) {
}

; CHECK-LABEL: uge_f32:
; CHECK: ge (get_local 3), (get_local 2){{$}}
; CHECK: ge push, (get_local 3), (get_local 2){{$}}
; CHECK-NEXT: set_local 4, pop{{$}}
define i32 @uge_f32(float %x, float %y) {
%a = fcmp uge float %x, %y
Expand Down

0 comments on commit 4b96d8d

Please sign in to comment.