I’m interested in taking SR-340 <Issues · apple/swift-issues · GitHub; issue:
"parseSILInstruction is horrible and makes me cry every time I see it. It is a method that is ~1900 lines with a huge switch in it. We should refactor it into a visitor structure. In fact it is large enough that we should consider moving it into its own file if it is possible."
Here is the first draft of the myl idea, how it could be approached:
1. We will define an abstract method on ValueBase class:
Sounds great, but SIL is an implementation detail of the compiler and not formally part of the language spec. swift-dev would be a better venue for this discussion.
-Joe
···
On Jan 13, 2016, at 1:07 PM, Sergey Bolshedvorsky via swift-evolution <swift-evolution@swift.org> wrote:
Hi everyone,
I’m interested in taking SR-340 <Issues · apple/swift-issues · GitHub; issue:
"parseSILInstruction is horrible and makes me cry every time I see it. It is a method that is ~1900 lines with a huge switch in it. We should refactor it into a visitor structure. In fact it is large enough that we should consider moving it into its own file if it is possible."
Here is the first draft of the myl idea, how it could be approached:
1. We will define an abstract method on ValueBase class:
I’m interested in taking SR-340 <Issues · apple/swift-issues · GitHub; issue:
"parseSILInstruction is horrible and makes me cry every time I see it. It is a method that is ~1900 lines with a huge switch in it. We should refactor it into a visitor structure. In fact it is large enough that we should consider moving it into its own file if it is possible."
Here is the first draft of the myl idea, how it could be approached:
1. We will define an abstract method on ValueBase class:
Hey, Sergey. It definitely makes sense to refactor this, but I don't think putting methods on SILInstruction is the way to go about it. There's no reason most clients of SIL need to know anything about parsing; from a separation-of-concerns perspective it belongs in a separate header and very likely a separate component (i.e. not lib/SIL/).
If this were Swift, we could use an extension, but alas. :-)
That said, I'm not a heavy user of SIL, so someone else from the Swift team with more of a stake should comment.
Jordan
···
On Jan 13, 2016, at 13:27, Sergey Bolshedvorsky via swift-dev <swift-dev@swift.org> wrote:
Hi everyone,
I’m interested in taking SR-340 <Issues · apple/swift-issues · GitHub; issue:
"parseSILInstruction is horrible and makes me cry every time I see it. It is a method that is ~1900 lines with a huge switch in it. We should refactor it into a visitor structure. In fact it is large enough that we should consider moving it into its own file if it is possible."
Here is the first draft of the myl idea, how it could be approached:
1. We will define an abstract method on ValueBase class:
Also, the SIL instruction parser does not actually have an instance of an instruction to perform virtual dispatch on. Nor should we introduce the concept of “wireframe” instructions just for the convenience of the parser. Redundancy between cases here should be addressed with normal redundancy elimination techniques, i.e. macros and templates.
John.
···
On Jan 13, 2016, at 3:25 PM, Jordan Rose via swift-dev <swift-dev@swift.org> wrote:
Hey, Sergey. It definitely makes sense to refactor this, but I don't think putting methods on SILInstruction is the way to go about it. There's no reason most clients of SIL need to know anything about parsing; from a separation-of-concerns perspective it belongs in a separate header and very likely a separate component (i.e. not lib/SIL/).
If this were Swift, we could use an extension, but alas. :-)
That said, I'm not a heavy user of SIL, so someone else from the Swift team with more of a stake should comment.
Hey, Sergey. It definitely makes sense to refactor this, but I don't think putting methods on SILInstruction is the way to go about it. There's no reason most clients of SIL need to know anything about parsing; from a separation-of-concerns perspective it belongs in a separate header and very likely a separate component (i.e. not lib/SIL/).
If this were Swift, we could use an extension, but alas. :-)
That said, I'm not a heavy user of SIL, so someone else from the Swift team with more of a stake should comment.
I agree with you completely.
Also, the SIL instruction parser does not actually have an instance of an instruction to perform virtual dispatch on. Nor should we introduce the concept of “wireframe” instructions just for the convenience of the parser. Redundancy between cases here should be addressed with normal redundancy elimination techniques, i.e. macros and templates.
The way to do this is to have a visitor parser that takes in a ValueKind and maps it to the parser routine to use.
Michael
···
On Jan 13, 2016, at 3:35 PM, John McCall via swift-dev <swift-dev@swift.org> wrote:
On Jan 13, 2016, at 3:25 PM, Jordan Rose via swift-dev <swift-dev@swift.org> wrote:
Hey, Sergey. It definitely makes sense to refactor this, but I don't think putting methods on SILInstruction is the way to go about it. There's no reason most clients of SIL need to know anything about parsing; from a separation-of-concerns perspective it belongs in a separate header and very likely a separate component (i.e. not lib/SIL/).
If this were Swift, we could use an extension, but alas. :-)
That said, I'm not a heavy user of SIL, so someone else from the Swift team with more of a stake should comment.
I agree with you completely.
Also, the SIL instruction parser does not actually have an instance of an instruction to perform virtual dispatch on. Nor should we introduce the concept of “wireframe” instructions just for the convenience of the parser. Redundancy between cases here should be addressed with normal redundancy elimination techniques, i.e. macros and templates.
The way to do this is to have a visitor parser that takes in a ValueKind and maps it to the parser routine to use.
Let me rephrase. IIRC the way that this code is written is it first deserializes the value kind. Imagine if we had a visitor that was composed with the parser whose visitor methods would perform the relevant parsing.
···
On Jan 13, 2016, at 9:08 PM, Michael Gottesman via swift-dev <swift-dev@swift.org> wrote:
On Jan 13, 2016, at 3:35 PM, John McCall via swift-dev <swift-dev@swift.org> wrote:
On Jan 13, 2016, at 3:25 PM, Jordan Rose via swift-dev <swift-dev@swift.org> wrote:
switch (Opcode) {
case ValueKind::SILArgument:
return handleValueKindSILArgument(Opcode);
break;
case ValueKind::AllocBoxInst:
return handleValueKindAllocBoxInst(Opcode);
break;
case ValueKind::ApplyInst:
return handleValueKindApplyInst(Opcode);
break;
// ...
}
}
SILParser::handleValueKindSILArgument(ValueKind Opcode) {
// Handle ValueKind::SILArgument case here
}
SILParser::handleValueKindAllocBoxInst(ValueKind Opcode) {
// Handle ValueKind::AllocBoxInst case here
}
SILParser::handleValueKindApplyInst(ValueKind Opcode) {
// Handle ValueKind::ApplyInst case here
}
By the way, I’ve noticed that some instructions are getting parsed by parser routines already: parseSILFunctionRef or parseCallInstruction.
Sergey
···
Sent from my iPhone
On 14 Jan 2016, at 06:00, Michael Gottesman via swift-dev <swift-dev@swift.org> wrote:
On Jan 13, 2016, at 9:08 PM, Michael Gottesman via swift-dev <swift-dev@swift.org> wrote:
On Jan 13, 2016, at 3:35 PM, John McCall via swift-dev <swift-dev@swift.org> wrote:
On Jan 13, 2016, at 3:25 PM, Jordan Rose via swift-dev <swift-dev@swift.org> wrote:
Hey, Sergey. It definitely makes sense to refactor this, but I don't think putting methods on SILInstruction is the way to go about it. There's no reason most clients of SIL need to know anything about parsing; from a separation-of-concerns perspective it belongs in a separate header and very likely a separate component (i.e. not lib/SIL/).
If this were Swift, we could use an extension, but alas. :-)
That said, I'm not a heavy user of SIL, so someone else from the Swift team with more of a stake should comment.
I agree with you completely.
Also, the SIL instruction parser does not actually have an instance of an instruction to perform virtual dispatch on. Nor should we introduce the concept of “wireframe” instructions just for the convenience of the parser. Redundancy between cases here should be addressed with normal redundancy elimination techniques, i.e. macros and templates.
The way to do this is to have a visitor parser that takes in a ValueKind and maps it to the parser routine to use.
Let me rephrase. IIRC the way that this code is written is it first deserializes the value kind. Imagine if we had a visitor that was composed with the parser whose visitor methods would perform the relevant parsing.
switch (Opcode) {
case ValueKind::SILArgument:
return handleValueKindSILArgument(Opcode);
break;
case ValueKind::AllocBoxInst:
return handleValueKindAllocBoxInst(Opcode);
break;
case ValueKind::ApplyInst:
return handleValueKindApplyInst(Opcode);
break;
// ...
}
}
SILParser::handleValueKindSILArgument(ValueKind Opcode) {
// Handle ValueKind::SILArgument case here
}
SILParser::handleValueKindAllocBoxInst(ValueKind Opcode) {
// Handle ValueKind::AllocBoxInst case here
}
SILParser::handleValueKindApplyInst(ValueKind Opcode) {
// Handle ValueKind::ApplyInst case here
}
By the way, I’ve noticed that some instructions are getting parsed by parser routines already: parseSILFunctionRef or parseCallInstruction.
Sergey
Sent from my iPhone
On 14 Jan 2016, at 06:00, Michael Gottesman via swift-dev <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote:
On Jan 13, 2016, at 9:08 PM, Michael Gottesman via swift-dev <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote:
On Jan 13, 2016, at 3:35 PM, John McCall via swift-dev <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote:
On Jan 13, 2016, at 3:25 PM, Jordan Rose via swift-dev <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote:
Hey, Sergey. It definitely makes sense to refactor this, but I don't think putting methods on SILInstruction is the way to go about it. There's no reason most clients of SIL need to know anything about parsing; from a separation-of-concerns perspective it belongs in a separate header and very likely a separate component (i.e. not lib/SIL/).
If this were Swift, we could use an extension, but alas. :-)
That said, I'm not a heavy user of SIL, so someone else from the Swift team with more of a stake should comment.
I agree with you completely.
Also, the SIL instruction parser does not actually have an instance of an instruction to perform virtual dispatch on. Nor should we introduce the concept of “wireframe” instructions just for the convenience of the parser. Redundancy between cases here should be addressed with normal redundancy elimination techniques, i.e. macros and templates.
The way to do this is to have a visitor parser that takes in a ValueKind and maps it to the parser routine to use.
Let me rephrase. IIRC the way that this code is written is it first deserializes the value kind. Imagine if we had a visitor that was composed with the parser whose visitor methods would perform the relevant parsing.
There is going to be a new class with all visit methods:
namespace {
class SILInstructionParser
: public SILVisitor<SILInstructionParser, ValueBase> {
public:
SILParser &P;
SILInstructionParser(SILParser &P): P(P) {}
// ValueBase visitSILArgument(ValueBase opcode) {
// llvm_unreachable("not an instruction");
// }
//
// ValueBase visitSILUndef(ValueBase opcode) {
// llvm_unreachable("not an instruction");
// }
};
} // end anonymous namespace
And there is going to be a new method on SILVisitor, what will map opcode to the SILInstructionParser methods, something similar to:
ValueRetTy visit(ValueBase *V) {
switch (V->getKind()) { #define VALUE(CLASS, PARENT) \
case ValueKind::CLASS: \
return asImpl().visit#class(static_cast<CLASS*>(V)); #include "swift/SIL/SILNodes.def"
}
llvm_unreachable("Not reachable, all cases handled");
}
Is there a way how I can run only preprocessor, something similar to -E option for GCC?
I’m getting build error with my changes and I would like to see the output for the SILVisitor class.
Sergey
···
On 14 Jan 2016, at 19:27, Michael Gottesman <mgottesman@apple.com> wrote:
No I mean like this:
1. Add a visitor in SILVisitor.h that just switches on value base.
2. Define a composition class with SILParser:
switch (Opcode) {
case ValueKind::SILArgument:
return handleValueKindSILArgument(Opcode);
break;
case ValueKind::AllocBoxInst:
return handleValueKindAllocBoxInst(Opcode);
break;
case ValueKind::ApplyInst:
return handleValueKindApplyInst(Opcode);
break;
// ...
}
}
SILParser::handleValueKindSILArgument(ValueKind Opcode) {
// Handle ValueKind::SILArgument case here
}
SILParser::handleValueKindAllocBoxInst(ValueKind Opcode) {
// Handle ValueKind::AllocBoxInst case here
}
SILParser::handleValueKindApplyInst(ValueKind Opcode) {
// Handle ValueKind::ApplyInst case here
}
By the way, I’ve noticed that some instructions are getting parsed by parser routines already: parseSILFunctionRef or parseCallInstruction.
Sergey
Sent from my iPhone
On 14 Jan 2016, at 06:00, Michael Gottesman via swift-dev <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote:
On Jan 13, 2016, at 9:08 PM, Michael Gottesman via swift-dev <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote:
On Jan 13, 2016, at 3:35 PM, John McCall via swift-dev <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote:
On Jan 13, 2016, at 3:25 PM, Jordan Rose via swift-dev <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote:
Hey, Sergey. It definitely makes sense to refactor this, but I don't think putting methods on SILInstruction is the way to go about it. There's no reason most clients of SIL need to know anything about parsing; from a separation-of-concerns perspective it belongs in a separate header and very likely a separate component (i.e. not lib/SIL/).
If this were Swift, we could use an extension, but alas. :-)
That said, I'm not a heavy user of SIL, so someone else from the Swift team with more of a stake should comment.
I agree with you completely.
Also, the SIL instruction parser does not actually have an instance of an instruction to perform virtual dispatch on. Nor should we introduce the concept of “wireframe” instructions just for the convenience of the parser. Redundancy between cases here should be addressed with normal redundancy elimination techniques, i.e. macros and templates.
The way to do this is to have a visitor parser that takes in a ValueKind and maps it to the parser routine to use.
Let me rephrase. IIRC the way that this code is written is it first deserializes the value kind. Imagine if we had a visitor that was composed with the parser whose visitor methods would perform the relevant parsing.
There is going to be a new class with all visit methods:
namespace {
class SILInstructionParser
: public SILVisitor<SILInstructionParser, ValueBase> {
public:
SILParser &P;
SILInstructionParser(SILParser &P): P(P) {}
// ValueBase visitSILArgument(ValueBase opcode) {
// llvm_unreachable("not an instruction");
// }
//
// ValueBase visitSILUndef(ValueBase opcode) {
// llvm_unreachable("not an instruction");
// }
};
} // end anonymous namespace
And there is going to be a new method on SILVisitor, what will map opcode to the SILInstructionParser methods, something similar to:
ValueRetTy visit(ValueBase *V) {
switch (V->getKind()) { #define VALUE(CLASS, PARENT) \
case ValueKind::CLASS: \
return asImpl().visit#class(static_cast<CLASS*>(V)); #include "swift/SIL/SILNodes.def"
}
llvm_unreachable("Not reachable, all cases handled");
}
Is there a way how I can run only preprocessor, something similar to -E option for GCC?
-E should work on any Unix-like C compiler.
Using an x-macro expansion like the above in the SILInstructionParser implementation makes sense; I don’t think there’s any point in adding it to SILVisitor, though.
John.
···
On Jan 17, 2016, at 9:02 AM, Sergey Bolshedvorsky via swift-dev <swift-dev@swift.org> wrote:
I’m getting build error with my changes and I would like to see the output for the SILVisitor class.
Sergey
On 14 Jan 2016, at 19:27, Michael Gottesman <mgottesman@apple.com <mailto:mgottesman@apple.com>> wrote:
No I mean like this:
1. Add a visitor in SILVisitor.h that just switches on value base.
2. Define a composition class with SILParser:
switch (Opcode) {
case ValueKind::SILArgument:
return handleValueKindSILArgument(Opcode);
break;
case ValueKind::AllocBoxInst:
return handleValueKindAllocBoxInst(Opcode);
break;
case ValueKind::ApplyInst:
return handleValueKindApplyInst(Opcode);
break;
// ...
}
}
SILParser::handleValueKindSILArgument(ValueKind Opcode) {
// Handle ValueKind::SILArgument case here
}
SILParser::handleValueKindAllocBoxInst(ValueKind Opcode) {
// Handle ValueKind::AllocBoxInst case here
}
SILParser::handleValueKindApplyInst(ValueKind Opcode) {
// Handle ValueKind::ApplyInst case here
}
By the way, I’ve noticed that some instructions are getting parsed by parser routines already: parseSILFunctionRef or parseCallInstruction.
Sergey
Sent from my iPhone
On 14 Jan 2016, at 06:00, Michael Gottesman via swift-dev <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote:
On Jan 13, 2016, at 9:08 PM, Michael Gottesman via swift-dev <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote:
On Jan 13, 2016, at 3:35 PM, John McCall via swift-dev <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote:
On Jan 13, 2016, at 3:25 PM, Jordan Rose via swift-dev <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote:
Hey, Sergey. It definitely makes sense to refactor this, but I don't think putting methods on SILInstruction is the way to go about it. There's no reason most clients of SIL need to know anything about parsing; from a separation-of-concerns perspective it belongs in a separate header and very likely a separate component (i.e. not lib/SIL/).
If this were Swift, we could use an extension, but alas. :-)
That said, I'm not a heavy user of SIL, so someone else from the Swift team with more of a stake should comment.
I agree with you completely.
Also, the SIL instruction parser does not actually have an instance of an instruction to perform virtual dispatch on. Nor should we introduce the concept of “wireframe” instructions just for the convenience of the parser. Redundancy between cases here should be addressed with normal redundancy elimination techniques, i.e. macros and templates.
The way to do this is to have a visitor parser that takes in a ValueKind and maps it to the parser routine to use.
Let me rephrase. IIRC the way that this code is written is it first deserializes the value kind. Imagine if we had a visitor that was composed with the parser whose visitor methods would perform the relevant parsing.