Skip to content

Commit 2f18af8

Browse files
committed
[Test] Allowed referring to block arguments.
1 parent 6dc4dee commit 2f18af8

File tree

5 files changed

+75
-1
lines changed

5 files changed

+75
-1
lines changed

docs/SIL.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3959,6 +3959,10 @@ The following types of test arguments are supported:
39593959
@trace[uint] <-- the ``debug_value [trace]`` at index ``uint``
39603960
@{function}.{trace} <-- the indicated trace in the indicated function
39613961
Example: @function[bar].trace
3962+
- argument: @argument <-_ the first argument of the current block
3963+
@argument[uint] <-- the argument at index ``uint`` of the current block
3964+
@{block}.{argument} <-- the indicated argument in the indicated block
3965+
@{function}.{argument} <-- the indicated argument in the entry block of the indicated function
39623966
- instruction: @instruction <-- the instruction after* the test_specification instruction
39633967
@instruction[+uint] <-- the instruction ``uint`` instructions after* the test_specification instruction
39643968
@instruction[-uint] <-- the instruction ``uint`` instructions before* the test_specification instruction

include/swift/SILOptimizer/Utils/ParseTestSpecification.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#define SWIFT_SIL_PARSETESTSPECIFICATION
1919

2020
#include "swift/Basic/TaggedUnion.h"
21+
#include "swift/SIL/SILArgument.h"
2122
#include "swift/SIL/SILInstruction.h"
2223
#include "swift/SIL/SILValue.h"
2324
#include "llvm/ADT/StringRef.h"
@@ -31,6 +32,7 @@ using llvm::StringRef;
3132
namespace swift {
3233

3334
class SILFunction;
35+
class SILArgument;
3436

3537
namespace test {
3638

@@ -42,6 +44,7 @@ struct Argument {
4244
Value,
4345
Operand,
4446
Instruction,
47+
BlockArgument,
4548
Block,
4649
Function,
4750
};
@@ -51,6 +54,7 @@ struct Argument {
5154
SILValue, // ValueArgument
5255
Operand *, // OperandArgument
5356
SILInstruction *, // InstructionArgument
57+
SILArgument *, // BlockArgumentArgument
5458
SILBasicBlock *, // BlockArgument
5559
SILFunction * // FunctionArgument
5660
>;
@@ -89,6 +93,11 @@ struct InstructionArgument
8993
InstructionArgument(SILInstruction *stored) : Super(stored) {}
9094
};
9195

96+
struct BlockArgumentArgument
97+
: ConcreteArgument<SILArgument *, Argument::Kind::BlockArgument> {
98+
BlockArgumentArgument(SILArgument *stored) : Super(stored) {}
99+
};
100+
92101
struct BlockArgument
93102
: ConcreteArgument<SILBasicBlock *, Argument::Kind::Block> {
94103
BlockArgument(SILBasicBlock *stored) : Super(stored) {}
@@ -146,6 +155,9 @@ struct Arguments {
146155
auto *instruction = cast<InstructionArgument>(argument).getValue();
147156
auto *svi = cast<SingleValueInstruction>(instruction);
148157
return svi;
158+
} else if (isa<BlockArgumentArgument>(argument)) {
159+
auto *arg = cast<BlockArgumentArgument>(argument).getValue();
160+
return arg;
149161
}
150162
return cast<ValueArgument>(argument).getValue();
151163
}
@@ -155,6 +167,9 @@ struct Arguments {
155167
SILInstruction *takeInstruction() {
156168
return cast<InstructionArgument>(takeArgument()).getValue();
157169
}
170+
SILArgument *takeBlockArgument() {
171+
return cast<BlockArgumentArgument>(takeArgument()).getValue();
172+
}
158173
SILBasicBlock *takeBlock() {
159174
return cast<BlockArgument>(takeArgument()).getValue();
160175
}

lib/SILOptimizer/UtilityPasses/ParseTestSpecification.cpp

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,31 @@ class ParseArgumentSpecification {
342342
return OperandArgument{operand};
343343
}
344344

345+
SILArgument *parseBlockArgumentComponent(SILBasicBlock *block) {
346+
if (!consumePrefix("argument"))
347+
return nullptr;
348+
// If this is a bare @argument reference, it refers to the first argument
349+
// of the block containing the test_specification.
350+
if (!block) {
351+
block = context->getParent();
352+
}
353+
if (empty()) {
354+
return block->getArgument(0);
355+
}
356+
if (auto subscript = parseSubscript()) {
357+
auto index = subscript->get<unsigned long long>();
358+
return block->getArgument(index);
359+
}
360+
llvm_unreachable("bad suffix after 'argument'!?");
361+
}
362+
363+
Optional<Argument> parseBlockArgumentReference(SILBasicBlock *block) {
364+
auto *argument = parseBlockArgumentComponent(block);
365+
if (!argument)
366+
return llvm::None;
367+
return BlockArgumentArgument{argument};
368+
}
369+
345370
using InstructionContext = TaggedUnion<SILFunction *, SILBasicBlock *>;
346371

347372
SILInstruction *
@@ -424,8 +449,10 @@ class ParseArgumentSpecification {
424449
return llvm::None;
425450
if (!consumePrefix("."))
426451
return BlockArgument{block};
427-
if (auto arg = parseInstructionReference({block}))
452+
if (auto arg = parseBlockArgumentReference(block))
428453
return *arg;
454+
if (auto inst = parseInstructionReference({block}))
455+
return *inst;
429456
llvm_unreachable("unhandled suffix after 'block'!?");
430457
}
431458

@@ -465,6 +492,8 @@ class ParseArgumentSpecification {
465492
return llvm::None;
466493
if (!consumePrefix("."))
467494
return FunctionArgument{function};
495+
if (auto arg = parseBlockArgumentReference(function->getEntryBlock()))
496+
return *arg;
468497
if (auto arg = parseInstructionReference({function}))
469498
return *arg;
470499
if (auto arg = parseTraceReference(function))
@@ -482,6 +511,8 @@ class ParseArgumentSpecification {
482511
if (auto arg =
483512
parseOperandReference(getInstruction(context->getFunction(), 0)))
484513
return *arg;
514+
if (auto arg = parseBlockArgumentReference(nullptr))
515+
return *arg;
485516
if (auto arg = parseInstructionReference(llvm::None))
486517
return *arg;
487518
if (auto arg = parseBlockReference(nullptr))

lib/SILOptimizer/UtilityPasses/UnitTestRunner.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ class UnitTest {
108108

109109
// Arguments:
110110
// - string: list of characters, each of which specifies subsequent arguments
111+
// - A: (block) argument
111112
// - F: function
112113
// - B: block
113114
// - I: instruction
@@ -129,6 +130,12 @@ struct TestSpecificationTest : UnitTest {
129130
auto expectedFields = arguments.takeString();
130131
for (auto expectedField : expectedFields) {
131132
switch (expectedField) {
133+
case 'A': {
134+
auto *argument = arguments.takeBlockArgument();
135+
llvm::errs() << "argument:\n";
136+
argument->dump();
137+
break;
138+
}
132139
case 'F': {
133140
auto *function = arguments.takeFunction();
134141
llvm::errs() << "function: " << function->getName() << "\n";

test/SILOptimizer/unit_test.sil

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,23 @@ exit:
133133
return %retval : $()
134134
}
135135

136+
struct X {}
137+
138+
// CHECK-LABEL: begin running test 1 of {{[^,]+}} on test_arg_arg_parsing: test-specification-parsing
139+
// CHECK: argument:
140+
// CHECK: %0 = argument of bb0 : $X
141+
// CHECK: argument:
142+
// CHECK: %0 = argument of bb0 : $X
143+
// CHECK: argument:
144+
// CHECK: %0 = argument of bb0 : $X
145+
// CHECK-LABEL: end running test 1 of {{[^,]+}} on test_arg_arg_parsing: test-specification-parsing
146+
sil [ossa] @test_arg_arg_parsing : $(X) -> () {
147+
entry(%instance : $X):
148+
test_specification "test-specification-parsing AAA @argument @block.argument @function.argument[0]"
149+
%retval = tuple ()
150+
return %retval : $()
151+
}
152+
136153
class C {}
137154

138155
sil [ossa] @getC : $@convention(thin) () -> @owned C

0 commit comments

Comments
 (0)