summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Gohman <dan433584@gmail.com>2015-11-23 19:12:37 +0000
committerDan Gohman <dan433584@gmail.com>2015-11-23 19:12:37 +0000
commitf6857223c9fd534825cd8307b9cb37ada230ec83 (patch)
tree13a36c07f79e25ff0d38e247abd05afa0e46cce9
parent8e8b4fb678016640be0284f6aa73b8806fb76aec (diff)
downloadbcm5719-llvm-f6857223c9fd534825cd8307b9cb37ada230ec83.tar.gz
bcm5719-llvm-f6857223c9fd534825cd8307b9cb37ada230ec83.zip
[WebAssembly] Always print loop end labels
WebAssembly is currently using labels to end scopes, so for example a loop scope looks like this: BB0_0: loop BB0_1 ... BB0_1: with BB0_0 being the label of the first block not in the loop. This requires that the label be printed even when it's only reachable via fallthrough. To arrange this, insert a no-op LOOP_END instruction in such cases at the end of the loop. llvm-svn: 253901
-rw-r--r--llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp4
-rw-r--r--llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp12
-rw-r--r--llvm/lib/Target/WebAssembly/WebAssemblyInstrControl.td5
-rw-r--r--llvm/test/CodeGen/WebAssembly/cfg-stackify.ll3
4 files changed, 23 insertions, 1 deletions
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
index c452e1dd024..f7f37ee8c89 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
@@ -221,6 +221,10 @@ void WebAssemblyAsmPrinter::EmitInstruction(const MachineInstr *MI) {
// These represent values which are live into the function entry, so there's
// no instruction to emit.
break;
+ case WebAssembly::LOOP_END:
+ // This is a no-op which just exists to tell AsmPrinter.cpp that there's a
+ // fallthrough which nevertheless requires a label for the destination here.
+ break;
default: {
WebAssemblyMCInstLower MCInstLowering(OutContext, *this);
MCInst TmpInst;
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp
index 78e15f036b2..2ec1ea5f65a 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp
@@ -289,11 +289,21 @@ static void PlaceMarkers(MachineFunction &MF, const MachineLoopInfo &MLI,
MachineBasicBlock *Bottom = Loop->getBottomBlock();
auto Iter = next(MachineFunction::iterator(Bottom));
if (Iter == MF.end()) {
- MF.push_back(MF.CreateMachineBasicBlock());
+ MachineBasicBlock *Label = MF.CreateMachineBasicBlock();
+ // Give it a fake predecessor so that AsmPrinter prints its label.
+ Label->addSuccessor(Label);
+ MF.push_back(Label);
Iter = next(MachineFunction::iterator(Bottom));
}
BuildMI(MBB, MBB.begin(), DebugLoc(), TII.get(WebAssembly::LOOP))
.addMBB(&*Iter);
+
+ // Emit a special no-op telling the asm printer that we need a label
+ // to close the loop scope, even though the destination is only
+ // reachable by fallthrough.
+ if (!Bottom->back().isBarrier())
+ BuildMI(*Bottom, Bottom->end(), DebugLoc(),
+ TII.get(WebAssembly::LOOP_END));
}
// Place the BLOCK for MBB if MBB is branched to from above.
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrControl.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrControl.td
index 92393d435c2..7fa4c5613e9 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrControl.td
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrControl.td
@@ -39,6 +39,11 @@ def TABLESWITCH_I64 : I<(outs), (ins I64:$index, variable_ops),
def BLOCK : I<(outs), (ins bb_op:$dst), [], "block \t$dst">;
def LOOP : I<(outs), (ins bb_op:$dst), [], "loop \t$dst">;
+// No-op to indicate to the AsmPrinter that a loop ends here, so a
+// basic block label is needed even if it wouldn't otherwise appear so.
+let isTerminator = 1, hasCtrlDep = 1 in
+def LOOP_END : I<(outs), (ins), []>;
+
multiclass RETURN<WebAssemblyRegClass vt> {
def RETURN_#vt : I<(outs), (ins vt:$val), [(WebAssemblyreturn vt:$val)],
"return \t$val">;
diff --git a/llvm/test/CodeGen/WebAssembly/cfg-stackify.ll b/llvm/test/CodeGen/WebAssembly/cfg-stackify.ll
index cac98199215..e62a8c88ef9 100644
--- a/llvm/test/CodeGen/WebAssembly/cfg-stackify.ll
+++ b/llvm/test/CodeGen/WebAssembly/cfg-stackify.ll
@@ -186,6 +186,7 @@ entry:
; CHECK: BB7_1:
; CHECK: i32.store $0, $pop{{[0-9]+}}{{$}}
; CHECK: br BB7_1{{$}}
+; CHECK: BB7_2:
define i32 @minimal_loop(i32* %p) {
entry:
store volatile i32 0, i32* %p
@@ -200,6 +201,7 @@ loop:
; CHECK: BB8_1:
; CHECK: loop BB8_2{{$}}
; CHECK: br_if $pop{{[0-9]+}}, BB8_1{{$}}
+; CHECK: BB8_2:
; CHECK: return ${{[0-9]+}}{{$}}
define i32 @simple_loop(i32* %p, i32 %a) {
entry:
@@ -285,6 +287,7 @@ exit:
; CHECK: BB11_5:
; CHECK: BB11_6:
; CHECK: br BB11_1{{$}}
+; CHECK: BB11_7:
define i32 @doublediamond_in_a_loop(i32 %a, i32 %b, i32* %p) {
entry:
br label %header
OpenPOWER on IntegriCloud