[WebAssembly] Rematerialize constants rather than hold them live in registers.

Teach the register stackifier to rematerialize constants that have multiple
uses instead of leaving them in registers. In the WebAssembly encoding, it's
the same code size to materialize most constants as it is to read a value
from a register.

llvm-svn: 258142
diff --git a/llvm/test/CodeGen/WebAssembly/cfg-stackify.ll b/llvm/test/CodeGen/WebAssembly/cfg-stackify.ll
index f0e5f44..196bed0 100644
--- a/llvm/test/CodeGen/WebAssembly/cfg-stackify.ll
+++ b/llvm/test/CodeGen/WebAssembly/cfg-stackify.ll
@@ -147,7 +147,8 @@
 ; CHECK-NEXT: end_block{{$}}
 ; CHECK: .LBB3_5:
 ; CHECK-NEXT: end_block{{$}}
-; CHECK: return ${{[0-9]+}}{{$}}
+; CHECK: i32.const $push{{[0-9]+}}=, 0{{$}}
+; CHECK-NEXT: return $pop{{[0-9]+}}{{$}}
 ; OPT-LABEL: doublediamond:
 ; OPT: block{{$}}
 ; OPT-NEXT: block{{$}}
@@ -157,7 +158,8 @@
 ; OPT: br 1{{$}}
 ; OPT: .LBB3_4:
 ; OPT: .LBB3_5:
-; OPT: return ${{[0-9]+}}{{$}}
+; OPT: i32.const $push{{[0-9]+}}=, 0{{$}}
+; OPT-NEXT: return $pop{{[0-9]+}}{{$}}
 define i32 @doublediamond(i32 %a, i32 %b, i32* %p) {
 entry:
   %c = icmp eq i32 %a, 0
@@ -211,7 +213,8 @@
 ; CHECK: br 1{{$}}
 ; CHECK: .LBB5_2:
 ; CHECK: .LBB5_3:
-; CHECK: return ${{[0-9]+}}{{$}}
+; CHECK: i32.const $push{{[0-9]+}}=, 0{{$}}
+; CHECK-NEXT: return $pop{{[0-9]+}}{{$}}
 ; OPT-LABEL: diamond:
 ; OPT: block{{$}}
 ; OPT: block{{$}}
@@ -219,7 +222,8 @@
 ; OPT: br 1{{$}}
 ; OPT: .LBB5_2:
 ; OPT: .LBB5_3:
-; OPT: return ${{[0-9]+}}{{$}}
+; OPT: i32.const $push{{[0-9]+}}=, 0{{$}}
+; OPT-NEXT: return $pop{{[0-9]+}}{{$}}
 define i32 @diamond(i32* %p, i32 %a) {
 entry:
   %c = icmp eq i32 %a, 0
@@ -275,14 +279,16 @@
 ; CHECK: loop{{$}}
 ; CHECK: br_if $pop{{[0-9]+}}, 0{{$}}
 ; CHECK-NEXT: end_loop{{$}}
-; CHECK: return ${{[0-9]+}}{{$}}
+; CHECK: i32.const $push{{[0-9]+}}=, 0{{$}}
+; CHECK-NEXT: return $pop{{[0-9]+}}{{$}}
 ; OPT-LABEL: simple_loop:
 ; OPT-NOT: br
 ; OPT: .LBB8_1:
 ; OPT: loop{{$}}
 ; OPT: br_if {{[^,]*}}, 0{{$}}
 ; OPT-NEXT: end_loop{{$}}
-; OPT: return ${{[0-9]+}}{{$}}
+; OPT: i32.const $push{{[0-9]+}}=, 0{{$}}
+; OPT-NEXT: return $pop{{[0-9]+}}{{$}}
 define i32 @simple_loop(i32* %p, i32 %a) {
 entry:
   %c = icmp eq i32 %a, 0
@@ -340,7 +346,8 @@
 ; CHECK: .LBB10_2:
 ; CHECK: br_if $1, 0{{$}}
 ; CHECK: .LBB10_4:
-; CHECK: return ${{[0-9]+}}{{$}}
+; CHECK: i32.const $push{{[0-9]+}}=, 0{{$}}
+; CHECK-NEXT: return $pop{{[0-9]+}}{{$}}
 ; OPT-LABEL: ifelse_earlyexits:
 ; OPT: block{{$}}
 ; OPT: block{{$}}
@@ -349,7 +356,8 @@
 ; OPT: br 1{{$}}
 ; OPT: .LBB10_3:
 ; OPT: .LBB10_4:
-; OPT: return ${{[0-9]+}}{{$}}
+; OPT: i32.const $push{{[0-9]+}}=, 0{{$}}
+; OPT-NEXT: return $pop{{[0-9]+}}{{$}}
 define i32 @ifelse_earlyexits(i32 %a, i32 %b, i32* %p) {
 entry:
   %c = icmp eq i32 %a, 0
@@ -733,6 +741,7 @@
 ; CHECK-NEXT:  .LBB17_3:
 ; CHECK-NEXT:  end_block{{$}}
 ; CHECK-NEXT:  loop{{$}}
+; CHECK-NEXT:  i32.const $push{{[^,]*}}, 0{{$}}
 ; CHECK-NEXT:  br_if    {{[^,]*}}, 0{{$}}
 ; CHECK-NEXT:  br       2{{$}}
 ; CHECK-NEXT:  .LBB17_4:
@@ -747,6 +756,7 @@
 ; OPT-NEXT:  .LBB17_3:
 ; OPT-NEXT:  end_block{{$}}
 ; OPT-NEXT:  loop{{$}}
+; OPT-NEXT:  i32.const $push{{[^,]*}}, 0{{$}}
 ; OPT-NEXT:  br_if    {{[^,]*}}, 0{{$}}
 ; OPT-NEXT:  br       2{{$}}
 ; OPT-NEXT:  .LBB17_4:
@@ -938,7 +948,7 @@
 ; CHECK-NEXT:  block{{$}}
 ; CHECK-NEXT:  block{{$}}
 ; CHECK-NEXT:  block{{$}}
-; CHECK-NEXT:  br_if        {{[^,]*}}, 0{{$}}
+; CHECK:       br_if        {{[^,]*}}, 0{{$}}
 ; CHECK-NEXT:  block{{$}}
 ; CHECK-NOT:   block
 ; CHECK:       br_if        {{[^,]*}}, 0{{$}}
@@ -969,12 +979,12 @@
 ; OPT-LABEL: test11:
 ; OPT:       block{{$}}
 ; OPT-NEXT:  block{{$}}
-; OPT-NEXT:  br_if        $0, 0{{$}}
+; OPT:       br_if        $0, 0{{$}}
 ; OPT-NEXT:  block{{$}}
 ; OPT-NOT:   block
 ; OPT:       br_if        $0, 0{{$}}
 ; OPT-NOT:   block
-; OPT:       br_if        $0, 2{{$}}
+; OPT:       br_if        {{[^,]*}}, 2{{$}}
 ; OPT-NEXT:  .LBB20_3:
 ; OPT-NEXT:  end_block{{$}}
 ; OPT-NOT:   block
@@ -984,13 +994,13 @@
 ; OPT-NOT:   block
 ; OPT:       block{{$}}
 ; OPT-NOT:   block
-; OPT:       br_if        $pop9, 0{{$}}
+; OPT:       br_if        $pop{{[0-9]+}}, 0{{$}}
 ; OPT-NOT:   block
 ; OPT:       return{{$}}
 ; OPT-NEXT:  .LBB20_6:
 ; OPT-NEXT:  end_block{{$}}
 ; OPT-NOT:   block
-; OPT:       br_if        $0, 0{{$}}
+; OPT:       br_if        $pop{{[0-9]+}}, 0{{$}}
 ; OPT-NOT:   block
 ; OPT:       return{{$}}
 ; OPT-NEXT:  .LBB20_8:
@@ -1109,7 +1119,7 @@
 ; optnone to disable optimizations to test this case.
 
 ; CHECK-LABEL: test13:
-; CHECK-NEXT:  local i32{{$}}
+; CHECK-NEXT:  .local i32{{$}}
 ; CHECK:       block{{$}}
 ; CHECK:       br_if $pop4, 0{{$}}
 ; CHECK-NEXT:  return{{$}}
@@ -1124,7 +1134,7 @@
 ; CHECK-NEXT:  end_block{{$}}
 ; CHECK-NEXT:  unreachable{{$}}
 ; OPT-LABEL: test13:
-; OPT-NEXT:  local i32{{$}}
+; OPT-NEXT:  .local i32{{$}}
 ; OPT:       block{{$}}
 ; OPT:       br_if $pop4, 0{{$}}
 ; OPT-NEXT:  return{{$}}
@@ -1159,15 +1169,16 @@
 ; before the loop for the second.
 
 ; CHECK-LABEL: test14:
-; CHECK-NEXT:     local       i32{{$}}
-; CHECK-NEXT:     i32.const   $0=, 0{{$}}
 ; CHECK-NEXT: .LBB23_1:{{$}}
 ; CHECK-NEXT:     loop{{$}}
-; CHECK-NEXT:     br_if       $0, 0{{$}}
+; CHECK-NEXT:     i32.const   $push0=, 0{{$}}
+; CHECK-NEXT:     br_if       $pop0, 0{{$}}
 ; CHECK-NEXT: .LBB23_2:{{$}}
 ; CHECK-NEXT:     end_loop{{$}}
 ; CHECK-NEXT:     loop{{$}}
-; CHECK-NEXT:     br_if       $0, 0{{$}}
+; CHECK-NEXT:     i32.const   $push1=, 0{{$}}
+; CHECK-NEXT:     i32.const   $push2=, 0{{$}}
+; CHECK-NEXT:     br_if       $pop2, 0{{$}}
 ; CHECK-NEXT:     end_loop{{$}}
 ; CHECK-NEXT:     return{{$}}
 define void @test14() {
diff --git a/llvm/test/CodeGen/WebAssembly/dead-vreg.ll b/llvm/test/CodeGen/WebAssembly/dead-vreg.ll
index 29a4199..190a085 100644
--- a/llvm/test/CodeGen/WebAssembly/dead-vreg.ll
+++ b/llvm/test/CodeGen/WebAssembly/dead-vreg.ll
@@ -8,7 +8,7 @@
 define void @foo(i32* nocapture %a, i32 %w, i32 %h) {
 ; CHECK-LABEL: foo:
 ; CHECK-NEXT: .param i32, i32, i32{{$}}
-; CHECK-NEXT: .local i32, i32, i32, i32, i32, i32, i32{{$}}
+; CHECK-NEXT: .local i32, i32, i32, i32, i32, i32{{$}}
 entry:
   %cmp.19 = icmp sgt i32 %h, 0
   br i1 %cmp.19, label %for.cond.1.preheader.lr.ph, label %for.end.7
diff --git a/llvm/test/CodeGen/WebAssembly/func.ll b/llvm/test/CodeGen/WebAssembly/func.ll
index 9857dad..b7122a3 100644
--- a/llvm/test/CodeGen/WebAssembly/func.ll
+++ b/llvm/test/CodeGen/WebAssembly/func.ll
@@ -44,7 +44,8 @@
 ; CHECK-LABEL: f4:
 ; CHECK-NEXT: .param i32{{$}}
 ; CHECK-NEXT: .result i32{{$}}
-; CHECK-NEXT: local
+; CHECK-NOT: local
+; CHECK: .size f4,
 define i32 @f4(i32 %x) {
 entry:
    %c = trunc i32 %x to i1
diff --git a/llvm/test/CodeGen/WebAssembly/load-store-i1.ll b/llvm/test/CodeGen/WebAssembly/load-store-i1.ll
index 47e2e8c..fb90d00 100644
--- a/llvm/test/CodeGen/WebAssembly/load-store-i1.ll
+++ b/llvm/test/CodeGen/WebAssembly/load-store-i1.ll
@@ -15,10 +15,11 @@
 }
 
 ; CHECK-LABEL: load_s_i1_i32:
-; CHECK:      i32.const $[[NUM1:[0-9]+]]=, 31{{$}}
-; CHECK-NEXT: i32.load8_u $push[[NUM0:[0-9]+]]=, 0($0){{$}}
-; CHECK-NEXT: shl $push[[NUM2:[0-9]+]]=, $pop[[NUM0]], $[[NUM1]]{{$}}
-; CHECK-NEXT: shr_s $push[[NUM3:[0-9]+]]=, $pop[[NUM2]], $[[NUM1]]{{$}}
+; CHECK:      i32.load8_u $push[[NUM0:[0-9]+]]=, 0($0){{$}}
+; CHECK-NEXT: i32.const $push[[NUM1:[0-9]+]]=, 31{{$}}
+; CHECK-NEXT: shl $push[[NUM2:[0-9]+]]=, $pop[[NUM0]], $pop[[NUM1]]{{$}}
+; CHECK-NEXT: i32.const $push[[NUM4:[0-9]+]]=, 31{{$}}
+; CHECK-NEXT: shr_s $push[[NUM3:[0-9]+]]=, $pop[[NUM2]], $pop[[NUM4]]{{$}}
 ; CHECK-NEXT: return $pop[[NUM3]]{{$}}
 define i32 @load_s_i1_i32(i1* %p) {
   %v = load i1, i1* %p
@@ -36,10 +37,11 @@
 }
 
 ; CHECK-LABEL: load_s_i1_i64:
-; CHECK:      i64.const $[[NUM1:[0-9]+]]=, 63{{$}}
-; CHECK-NEXT: i64.load8_u $push[[NUM0:[0-9]+]]=, 0($0){{$}}
-; CHECK-NEXT: shl $push[[NUM2:[0-9]+]]=, $pop[[NUM0]], $[[NUM1]]{{$}}
-; CHECK-NEXT: shr_s $push[[NUM3:[0-9]+]]=, $pop[[NUM2]], $[[NUM1]]{{$}}
+; CHECK:      i64.load8_u $push[[NUM0:[0-9]+]]=, 0($0){{$}}
+; CHECK-NEXT: i64.const $push[[NUM1:[0-9]+]]=, 63{{$}}
+; CHECK-NEXT: shl $push[[NUM2:[0-9]+]]=, $pop[[NUM0]], $pop[[NUM1]]{{$}}
+; CHECK-NEXT: i64.const $push[[NUM4:[0-9]+]]=, 63{{$}}
+; CHECK-NEXT: shr_s $push[[NUM3:[0-9]+]]=, $pop[[NUM2]], $pop[[NUM4]]{{$}}
 ; CHECK-NEXT: return $pop[[NUM3]]{{$}}
 define i64 @load_s_i1_i64(i1* %p) {
   %v = load i1, i1* %p
diff --git a/llvm/test/CodeGen/WebAssembly/offset.ll b/llvm/test/CodeGen/WebAssembly/offset.ll
index 828f402..ba0f72c 100644
--- a/llvm/test/CodeGen/WebAssembly/offset.ll
+++ b/llvm/test/CodeGen/WebAssembly/offset.ll
@@ -266,8 +266,9 @@
 }
 
 ; CHECK-LABEL: store_i32_to_numeric_address:
-; CHECK: i32.const $0=, 0{{$}}
-; CHECK: i32.store $discard=, 42($0), $0{{$}}
+; CHECK-NEXT: i32.const $push0=, 0{{$}}
+; CHECK-NEXT: i32.const $push1=, 0{{$}}
+; CHECK-NEXT: i32.store $discard=, 42($pop0), $pop1{{$}}
 define void @store_i32_to_numeric_address() {
   %s = inttoptr i32 42 to i32*
   store i32 0, i32* %s
@@ -275,8 +276,9 @@
 }
 
 ; CHECK-LABEL: store_i32_to_global_address:
-; CHECK: i32.const $0=, 0{{$}}
-; CHECK: i32.store $discard=, gv($0), $0{{$}}
+; CHECK: i32.const $push0=, 0{{$}}
+; CHECK: i32.const $push1=, 0{{$}}
+; CHECK: i32.store $discard=, gv($pop0), $pop1{{$}}
 define void @store_i32_to_global_address() {
   store i32 0, i32* @gv
   ret void
diff --git a/llvm/test/CodeGen/WebAssembly/reg-stackify.ll b/llvm/test/CodeGen/WebAssembly/reg-stackify.ll
index f8cae7f..8a9d399 100644
--- a/llvm/test/CodeGen/WebAssembly/reg-stackify.ll
+++ b/llvm/test/CodeGen/WebAssembly/reg-stackify.ll
@@ -52,24 +52,27 @@
 ; CHECK-LABEL: stack_uses:
 ; CHECK-NEXT: .param i32, i32, i32, i32{{$}}
 ; CHECK-NEXT: .result i32{{$}}
-; CHECK-NEXT: .local i32, i32{{$}}
-; CHECK-NEXT: i32.const   $5=, 2{{$}}
-; CHECK-NEXT: i32.const   $4=, 1{{$}}
 ; CHECK-NEXT: block{{$}}
-; CHECK-NEXT: i32.lt_s    $push0=, $0, $4{{$}}
-; CHECK-NEXT: i32.lt_s    $push1=, $1, $5{{$}}
-; CHECK-NEXT: i32.xor     $push4=, $pop0, $pop1{{$}}
-; CHECK-NEXT: i32.lt_s    $push2=, $2, $4{{$}}
-; CHECK-NEXT: i32.lt_s    $push3=, $3, $5{{$}}
-; CHECK-NEXT: i32.xor     $push5=, $pop2, $pop3{{$}}
-; CHECK-NEXT: i32.xor     $push6=, $pop4, $pop5{{$}}
-; CHECK-NEXT: i32.ne      $push7=, $pop6, $4{{$}}
-; CHECK-NEXT: br_if       $pop7, 0{{$}}
-; CHECK-NEXT: i32.const   $push8=, 0{{$}}
-; CHECK-NEXT: return      $pop8{{$}}
+; CHECK-NEXT: i32.const   $push13=, 1{{$}}
+; CHECK-NEXT: i32.lt_s    $push0=, $0, $pop13{{$}}
+; CHECK-NEXT: i32.const   $push1=, 2{{$}}
+; CHECK-NEXT: i32.lt_s    $push2=, $1, $pop1{{$}}
+; CHECK-NEXT: i32.xor     $push5=, $pop0, $pop2{{$}}
+; CHECK-NEXT: i32.const   $push12=, 1{{$}}
+; CHECK-NEXT: i32.lt_s    $push3=, $2, $pop12{{$}}
+; CHECK-NEXT: i32.const   $push11=, 2{{$}}
+; CHECK-NEXT: i32.lt_s    $push4=, $3, $pop11{{$}}
+; CHECK-NEXT: i32.xor     $push6=, $pop3, $pop4{{$}}
+; CHECK-NEXT: i32.xor     $push7=, $pop5, $pop6{{$}}
+; CHECK-NEXT: i32.const   $push10=, 1{{$}}
+; CHECK-NEXT: i32.ne      $push8=, $pop7, $pop10{{$}}
+; CHECK-NEXT: br_if       $pop8, 0{{$}}
+; CHECK-NEXT: i32.const   $push9=, 0{{$}}
+; CHECK-NEXT: return      $pop9{{$}}
 ; CHECK-NEXT: .LBB4_2:
 ; CHECK-NEXT: end_block{{$}}
-; CHECK-NEXT: return      $4{{$}}
+; CHECK-NEXT: i32.const   $push14=, 1{{$}}
+; CHECK-NEXT: return      $pop14{{$}}
 define i32 @stack_uses(i32 %x, i32 %y, i32 %z, i32 %w) {
 entry:
   %c = icmp sle i32 %x, 0
diff --git a/llvm/test/CodeGen/WebAssembly/signext-zeroext.ll b/llvm/test/CodeGen/WebAssembly/signext-zeroext.ll
index f6f5636..27e524b 100644
--- a/llvm/test/CodeGen/WebAssembly/signext-zeroext.ll
+++ b/llvm/test/CodeGen/WebAssembly/signext-zeroext.ll
@@ -8,10 +8,10 @@
 ; CHECK-LABEL: z2s_func:
 ; CHECK-NEXT: .param i32{{$}}
 ; CHECK-NEXT: .result i32{{$}}
-; CHECK-NEXT: .local i32{{$}}
-; CHECK-NEXT: i32.const $[[NUM0:[0-9]+]]=, 24{{$}}
-; CHECK-NEXT: i32.shl $push[[NUM2:[0-9]+]]=, $0, $[[NUM0]]{{$}}
-; CHECK-NEXT: i32.shr_s $push[[NUM3:[0-9]+]]=, $pop[[NUM2]], $[[NUM0]]{{$}}
+; CHECK-NEXT: i32.const $push[[NUM0:[0-9]+]]=, 24{{$}}
+; CHECK-NEXT: i32.shl $push[[NUM2:[0-9]+]]=, $0, $pop[[NUM0]]{{$}}
+; CHECK-NEXT: i32.const $push[[NUM1:[0-9]+]]=, 24{{$}}
+; CHECK-NEXT: i32.shr_s $push[[NUM3:[0-9]+]]=, $pop[[NUM2]], $pop[[NUM1]]{{$}}
 ; CHECK-NEXT: return $pop[[NUM3]]{{$}}
 define signext i8 @z2s_func(i8 zeroext %t) {
   ret i8 %t
@@ -44,13 +44,15 @@
 ; CHECK-LABEL: s2z_call:
 ; CHECK-NEXT: .param i32{{$}}
 ; CHECK-NEXT: .result i32{{$}}
-; CHECK-NEXT: .local i32{{$}}
-; CHECK-NEXT: i32.const $[[NUM0:[0-9]+]]=, 24{{$}}
-; CHECK-NEXT: i32.shl $push[[NUM1:[0-9]+]]=, $0, $[[NUM0]]{{$}}
-; CHECK-NEXT: i32.shr_s $push[[NUM2:[0-9]+]]=, $pop[[NUM1]], $[[NUM0]]{{$}}
+; CHECK-NEXT: i32.const $push[[NUM0:[0-9]+]]=, 24{{$}}
+; CHECK-NEXT: i32.shl $push[[NUM1:[0-9]+]]=, $0, $pop[[NUM0]]{{$}}
+; CHECK-NEXT: i32.const $push[[NUM6:[0-9]+]]=, 24{{$}}
+; CHECK-NEXT: i32.shr_s $push[[NUM2:[0-9]+]]=, $pop[[NUM1]], $pop[[NUM6]]{{$}}
 ; CHECK-NEXT: call $push[[NUM3:[0-9]]]=, s2z_func@FUNCTION, $pop[[NUM2]]{{$}}
-; CHECK-NEXT: i32.shl $push[[NUM4:[0-9]+]]=, $pop[[NUM3]], $[[NUM0]]{{$}}
-; CHECK-NEXT: i32.shr_s $push[[NUM5:[0-9]+]]=, $pop[[NUM4]], $[[NUM0]]{{$}}
+; CHECK-NEXT: i32.const $push[[NUM7:[0-9]+]]=, 24{{$}}
+; CHECK-NEXT: i32.shl $push[[NUM4:[0-9]+]]=, $pop[[NUM3]], $pop[[NUM7]]{{$}}
+; CHECK-NEXT: i32.const $push[[NUM8:[0-9]+]]=, 24{{$}}
+; CHECK-NEXT: i32.shr_s $push[[NUM5:[0-9]+]]=, $pop[[NUM4]], $pop[[NUM8]]{{$}}
 ; CHECK-NEXT: return $pop[[NUM5]]{{$}}
 define i32 @s2z_call(i32 %t) {
   %s = trunc i32 %t to i8
diff --git a/llvm/test/CodeGen/WebAssembly/store-results.ll b/llvm/test/CodeGen/WebAssembly/store-results.ll
index ae74133..5fa424a 100644
--- a/llvm/test/CodeGen/WebAssembly/store-results.ll
+++ b/llvm/test/CodeGen/WebAssembly/store-results.ll
@@ -26,7 +26,7 @@
 @pos = global %class.Vec3 zeroinitializer, align 4
 
 ; CHECK-LABEL: foo:
-; CHECK: i32.store $discard=, pos($0), $0{{$}}
+; CHECK: i32.store $discard=, pos($pop{{[0-9]+}}), $pop{{[0-9]+}}{{$}}
 define void @foo() {
 for.body.i:
   br label %for.body5.i
@@ -44,7 +44,7 @@
 }
 
 ; CHECK-LABEL: bar:
-; CHECK: i32.store $discard=, pos($0), $0{{$}}
+; CHECK: i32.store $discard=, pos($pop{{[0-9]+}}), $pop{{[0-9]+}}{{$}}
 define void @bar() {
 for.body.i:
   br label %for.body5.i