mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-17 08:57:34 +00:00
[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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@253901 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
236067a61b
commit
5aafb6def5
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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">;
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user