Skip to content

Commit fa75e88

Browse files
rmacnak-googleCommit Queue
authored andcommitted
[vm] Avoid massive vtables for IL instructions.
Implement type checks for leaf IL instructions using the instruction tag instead of per-type virtual functions, which scale quadratically with the number of IL instructions. out/ReleaseX64/exe.stripped/gen_snapshot 7601248 -> 6890640 (-9.3%) TEST=ci Change-Id: I3d9c84c67e6ab0f3020ebb02068451e6f1c150f7 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/388043 Reviewed-by: Alexander Aprelev <aam@google.com> Commit-Queue: Ryan Macnak <rmacnak@google.com>
1 parent b2e74ab commit fa75e88

File tree

9 files changed

+48
-24
lines changed

9 files changed

+48
-24
lines changed

runtime/vm/compiler/backend/code_statistics.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ CombinedCodeStatistics::CombinedCodeStatistics() {
1919
entries_[i].bytes = 0; \
2020
entries_[i++].count = 0;
2121

22-
FOR_EACH_INSTRUCTION(DO)
22+
FOR_EACH_CONCRETE_INSTRUCTION(DO)
2323

2424
#undef DO
2525

@@ -28,7 +28,7 @@ CombinedCodeStatistics::CombinedCodeStatistics() {
2828
entries_[i].bytes = 0; \
2929
entries_[i++].count = 0;
3030

31-
FOR_EACH_INSTRUCTION(DO)
31+
FOR_EACH_CONCRETE_INSTRUCTION(DO)
3232

3333
#undef DO
3434

runtime/vm/compiler/backend/code_statistics.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,11 @@ class CombinedCodeStatistics {
2020
// clang-format off
2121
enum EntryCounter {
2222
#define DO(type, attrs) kTag##type,
23-
FOR_EACH_INSTRUCTION(DO)
23+
FOR_EACH_CONCRETE_INSTRUCTION(DO)
2424
#undef DO
2525

2626
#define DO(type, attrs) kTag##type##SlowPath,
27-
FOR_EACH_INSTRUCTION(DO)
27+
FOR_EACH_CONCRETE_INSTRUCTION(DO)
2828
#undef DO
2929

3030
kTagAssertAssignableParameterCheck,

runtime/vm/compiler/backend/constant_propagator.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ class ConstantPropagator : public FlowGraphVisitor {
7575
virtual void VisitBlocks() { UNREACHABLE(); }
7676

7777
#define DECLARE_VISIT(type, attrs) virtual void Visit##type(type##Instr* instr);
78-
FOR_EACH_INSTRUCTION(DECLARE_VISIT)
78+
FOR_EACH_CONCRETE_INSTRUCTION(DECLARE_VISIT)
7979

8080
#undef DECLARE_VISIT
8181
// Structure tracking visit counts for phis. Used to detect infinite loops.

runtime/vm/compiler/backend/il.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1261,7 +1261,7 @@ bool GraphEntryInstr::IsCompiledForOsr() const {
12611261
visitor->Visit##ShortName(this); \
12621262
}
12631263

1264-
FOR_EACH_INSTRUCTION(DEFINE_ACCEPT)
1264+
FOR_EACH_CONCRETE_INSTRUCTION(DEFINE_ACCEPT)
12651265

12661266
#undef DEFINE_ACCEPT
12671267

@@ -1617,7 +1617,7 @@ bool Instruction::HasUnmatchedInputRepresentations() const {
16171617

16181618
const intptr_t Instruction::kInstructionAttrs[Instruction::kNumInstructions] = {
16191619
#define INSTR_ATTRS(type, attrs) InstrAttrs::attrs,
1620-
FOR_EACH_INSTRUCTION(INSTR_ATTRS)
1620+
FOR_EACH_CONCRETE_INSTRUCTION(INSTR_ATTRS)
16211621
#undef INSTR_ATTRS
16221622
};
16231623

runtime/vm/compiler/backend/il.h

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -402,11 +402,9 @@ struct InstrAttrs {
402402
};
403403
};
404404

405-
#define FOR_EACH_INSTRUCTION(M) \
405+
#define FOR_EACH_LEAF_INSTRUCTION(M) \
406406
M(GraphEntry, kNoGC) \
407-
M(JoinEntry, kNoGC) \
408407
M(TargetEntry, kNoGC) \
409-
M(FunctionEntry, kNoGC) \
410408
M(NativeEntry, kNoGC) \
411409
M(OsrEntry, kNoGC) \
412410
M(IndirectEntry, kNoGC) \
@@ -495,14 +493,11 @@ struct InstrAttrs {
495493
M(CheckSmi, kNoGC) \
496494
M(CheckNull, kNoGC) \
497495
M(CheckCondition, kNoGC) \
498-
M(Constant, kNoGC) \
499496
M(UnboxedConstant, kNoGC) \
500497
M(CheckEitherNonSmi, kNoGC) \
501498
M(BinaryDoubleOp, kNoGC) \
502499
M(DoubleTestOp, kNoGC) \
503500
M(MathMinMax, kNoGC) \
504-
M(Box, _) \
505-
M(Unbox, kNoGC) \
506501
M(BoxInt64, _) \
507502
M(UnboxInt64, kNoGC) \
508503
M(CaseInsensitiveCompare, kNoGC) \
@@ -549,6 +544,17 @@ struct InstrAttrs {
549544
M(SimdOp, kNoGC) \
550545
M(Suspend, _)
551546

547+
#define FOR_EACH_STEM_INSTRUCTION(M) \
548+
M(FunctionEntry, kNoGC) \
549+
M(JoinEntry, kNoGC) \
550+
M(Constant, kNoGC) \
551+
M(Box, _) \
552+
M(Unbox, kNoGC)
553+
554+
#define FOR_EACH_CONCRETE_INSTRUCTION(M) \
555+
FOR_EACH_STEM_INSTRUCTION(M) \
556+
FOR_EACH_LEAF_INSTRUCTION(M)
557+
552558
#define FOR_EACH_ABSTRACT_INSTRUCTION(M) \
553559
M(Allocation, _) \
554560
M(ArrayAllocation, _) \
@@ -564,7 +570,7 @@ struct InstrAttrs {
564570
M(UnboxInteger, _)
565571

566572
#define FORWARD_DECLARATION(type, attrs) class type##Instr;
567-
FOR_EACH_INSTRUCTION(FORWARD_DECLARATION)
573+
FOR_EACH_CONCRETE_INSTRUCTION(FORWARD_DECLARATION)
568574
FOR_EACH_ABSTRACT_INSTRUCTION(FORWARD_DECLARATION)
569575
#undef FORWARD_DECLARATION
570576

@@ -961,7 +967,7 @@ class ValueListIterable {
961967
class Instruction : public ZoneAllocated {
962968
public:
963969
#define DECLARE_TAG(type, attrs) k##type,
964-
enum Tag { FOR_EACH_INSTRUCTION(DECLARE_TAG) kNumInstructions };
970+
enum Tag { FOR_EACH_CONCRETE_INSTRUCTION(DECLARE_TAG) kNumInstructions };
965971
#undef DECLARE_TAG
966972

967973
static const intptr_t kInstructionAttrs[kNumInstructions];
@@ -1170,8 +1176,26 @@ class Instruction : public ZoneAllocated {
11701176
DECLARE_INSTRUCTION_TYPE_CHECK(Definition, Definition)
11711177
DECLARE_INSTRUCTION_TYPE_CHECK(BlockEntryWithInitialDefs,
11721178
BlockEntryWithInitialDefs)
1173-
FOR_EACH_INSTRUCTION(INSTRUCTION_TYPE_CHECK)
11741179
FOR_EACH_ABSTRACT_INSTRUCTION(INSTRUCTION_TYPE_CHECK)
1180+
FOR_EACH_STEM_INSTRUCTION(INSTRUCTION_TYPE_CHECK)
1181+
1182+
#undef DECLARE_INSTRUCTION_TYPE_CHECK
1183+
#undef INSTRUCTION_TYPE_CHECK
1184+
1185+
#define DECLARE_INSTRUCTION_TYPE_CHECK(Name, Type) \
1186+
bool Is##Name() const { return (As##Name() != nullptr); } \
1187+
Type* As##Name() { \
1188+
auto const_this = static_cast<const Instruction*>(this); \
1189+
return const_cast<Type*>(const_this->As##Name()); \
1190+
} \
1191+
const Type* As##Name() const { \
1192+
if (tag() == k##Name) return reinterpret_cast<const Type*>(this); \
1193+
return nullptr; \
1194+
}
1195+
#define INSTRUCTION_TYPE_CHECK(Name, Attrs) \
1196+
DECLARE_INSTRUCTION_TYPE_CHECK(Name, Name##Instr)
1197+
1198+
FOR_EACH_LEAF_INSTRUCTION(INSTRUCTION_TYPE_CHECK)
11751199

11761200
#undef INSTRUCTION_TYPE_CHECK
11771201
#undef DECLARE_INSTRUCTION_TYPE_CHECK
@@ -11811,7 +11835,7 @@ class InstructionVisitor : public ValueObject {
1181111835
#define DECLARE_VISIT_INSTRUCTION(ShortName, Attrs) \
1181211836
virtual void Visit##ShortName(ShortName##Instr* instr) {}
1181311837

11814-
FOR_EACH_INSTRUCTION(DECLARE_VISIT_INSTRUCTION)
11838+
FOR_EACH_CONCRETE_INSTRUCTION(DECLARE_VISIT_INSTRUCTION)
1181511839

1181611840
#undef DECLARE_VISIT_INSTRUCTION
1181711841

runtime/vm/compiler/backend/il_printer.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,15 +181,15 @@ class IlTestPrinter : public AllStatic {
181181
#define DECLARE_VISIT_INSTRUCTION(ShortName, Attrs) \
182182
WriteDescriptor<ShortName##Instr>(#ShortName);
183183

184-
FOR_EACH_INSTRUCTION(DECLARE_VISIT_INSTRUCTION)
184+
FOR_EACH_CONCRETE_INSTRUCTION(DECLARE_VISIT_INSTRUCTION)
185185

186186
#undef DECLARE_VISIT_INSTRUCTION
187187
}
188188

189189
#define DECLARE_VISIT_INSTRUCTION(ShortName, Attrs) \
190190
virtual void Visit##ShortName(ShortName##Instr* instr) { Write(instr); }
191191

192-
FOR_EACH_INSTRUCTION(DECLARE_VISIT_INSTRUCTION)
192+
FOR_EACH_CONCRETE_INSTRUCTION(DECLARE_VISIT_INSTRUCTION)
193193

194194
#undef DECLARE_VISIT_INSTRUCTION
195195

runtime/vm/compiler/backend/il_serializer.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1074,7 +1074,7 @@ Instruction* FlowGraphDeserializer::ReadTrait<Instruction*>::Read(
10741074
#define READ_INSTRUCTION(type, attrs) \
10751075
case Instruction::k##type: \
10761076
return new (d->zone()) type##Instr(d);
1077-
FOR_EACH_INSTRUCTION(READ_INSTRUCTION)
1077+
FOR_EACH_CONCRETE_INSTRUCTION(READ_INSTRUCTION)
10781078
#undef READ_INSTRUCTION
10791079
case Instruction::kNumInstructions:
10801080
return nullptr;

runtime/vm/compiler/backend/il_test_helper.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ Instruction* ILMatcher::MatchInternal(std::vector<MatchCode> match_codes,
410410
} \
411411
return cursor; \
412412
}
413-
FOR_EACH_INSTRUCTION(EMIT_CASE)
413+
FOR_EACH_CONCRETE_INSTRUCTION(EMIT_CASE)
414414
FOR_EACH_ABSTRACT_INSTRUCTION(EMIT_CASE)
415415
#undef EMIT_CASE
416416
default:
@@ -452,7 +452,7 @@ const char* ILMatcher::MatchOpCodeToCString(MatchOpCode opcode) {
452452
return "kMatchAndMove" #Instruction; \
453453
case kMatchAndMoveOptional##Instruction: \
454454
return "kMatchAndMoveOptional" #Instruction;
455-
FOR_EACH_INSTRUCTION(EMIT_CASE)
455+
FOR_EACH_CONCRETE_INSTRUCTION(EMIT_CASE)
456456
FOR_EACH_ABSTRACT_INSTRUCTION(EMIT_CASE)
457457
#undef EMIT_CASE
458458
default:

runtime/vm/compiler/backend/il_test_helper.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ enum MatchOpCode {
136136
#define DEFINE_MATCH_OPCODES(Instruction, _) \
137137
kMatch##Instruction, kMatchAndMove##Instruction, \
138138
kMatchAndMoveOptional##Instruction,
139-
FOR_EACH_INSTRUCTION(DEFINE_MATCH_OPCODES)
139+
FOR_EACH_CONCRETE_INSTRUCTION(DEFINE_MATCH_OPCODES)
140140
FOR_EACH_ABSTRACT_INSTRUCTION(DEFINE_MATCH_OPCODES)
141141
#undef DEFINE_MATCH_OPCODES
142142

@@ -180,7 +180,7 @@ class MatchCode {
180180
: opcode_(opcode), capture_(reinterpret_cast<Instruction**>(capture)) { \
181181
RELEASE_ASSERT(opcode == kMatch##Type || opcode == kMatchAndMove##Type); \
182182
}
183-
FOR_EACH_INSTRUCTION(DEFINE_TYPED_CONSTRUCTOR)
183+
FOR_EACH_CONCRETE_INSTRUCTION(DEFINE_TYPED_CONSTRUCTOR)
184184
FOR_EACH_ABSTRACT_INSTRUCTION(DEFINE_TYPED_CONSTRUCTOR)
185185
#undef DEFINE_TYPED_CONSTRUCTOR
186186

0 commit comments

Comments
 (0)