Skip to content

Commit cabaa78

Browse files
mkustermanncommit-bot@chromium.org
authored andcommitted
[VM] Generalize generic bounds check elimination
When eliminating bounds checks using loop information the length of GenericBoundsCheckInstr is directly compared to the loop bound. Instead we should compare the original definitions, ignoring any boxing/unboxing. This allows the elimination of more bounds checks. Issue #35154 Cq-Include-Trybots: luci.dart.try:vm-canary-linux-debug-try, vm-dartkb-linux-debug-x64-try, vm-dartkb-linux-release-x64-try, vm-kernel-asan-linux-release-x64-try, vm-kernel-checked-linux-release-x64-try, vm-kernel-linux-debug-ia32-try, vm-kernel-linux-debug-simdbc64-try, vm-kernel-linux-debug-x64-try, vm-kernel-linux-product-x64-try, vm-kernel-linux-release-ia32-try, vm-kernel-linux-release-simarm-try, vm-kernel-linux-release-simarm64-try, vm-kernel-linux-release-simdbc64-try, vm-kernel-linux-release-x64-try, vm-kernel-optcounter-threshold-linux-release-ia32-try, vm-kernel-optcounter-threshold-linux-release-x64-try, vm-kernel-precomp-android-release-arm-try, vm-kernel-precomp-bare-linux-release-simarm-try, vm-kernel-precomp-bare-linux-release-simarm64-try, vm-kernel-precomp-bare-linux-release-x64-try, vm-kernel-precomp-linux-debug-x64-try, vm-kernel-precomp-linux-product-x64-try, vm-kernel-precomp-linux-release-simarm-try, vm-kernel-precomp-linux-release-simarm64-try, vm-kernel-precomp-linux-release-x64-try, vm-kernel-precomp-obfuscate-linux-release-x64-try, vm-kernel-precomp-win-release-simarm64-try, vm-kernel-precomp-win-release-x64-try, vm-kernel-reload-linux-debug-x64-try, vm-kernel-reload-linux-release-x64-try, vm-kernel-reload-rollback-linux-debug-x64-try, vm-kernel-reload-rollback-linux-release-x64-try, vm-kernel-win-debug-ia32-try, vm-kernel-win-debug-x64-try, vm-kernel-win-product-x64-try, vm-kernel-win-release-ia32-try, vm-kernel-win-release-x64-try Change-Id: Ie10880f833f3b55d0804a03c4be9bd9d1ad52f66 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/97331 Commit-Queue: Martin Kustermann <[email protected]> Reviewed-by: Aart Bik <[email protected]> Reviewed-by: Vyacheslav Egorov <[email protected]>
1 parent 16eefa4 commit cabaa78

File tree

4 files changed

+37
-26
lines changed

4 files changed

+37
-26
lines changed

runtime/vm/compiler/backend/il.cc

+14
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,20 @@ Definition* Definition::OriginalDefinition() {
520520
return defn;
521521
}
522522

523+
Definition* Definition::OriginalDefinitionIgnoreBoxingAndConstraints() {
524+
Definition* def = this;
525+
while (true) {
526+
Definition* orig;
527+
if (def->IsConstraint() || def->IsBox() || def->IsUnbox()) {
528+
orig = def->InputAt(0)->definition();
529+
} else {
530+
orig = def->OriginalDefinition();
531+
}
532+
if (orig == def) return def;
533+
def = orig;
534+
}
535+
}
536+
523537
const ICData* Instruction::GetICData(
524538
const ZoneGrowableArray<const ICData*>& ic_data_array) const {
525539
// The deopt_id can be outside the range of the IC data array for

runtime/vm/compiler/backend/il.h

+8
Original file line numberDiff line numberDiff line change
@@ -1938,8 +1938,16 @@ class Definition : public Instruction {
19381938

19391939
virtual void SetIdentity(AliasIdentity identity) { UNREACHABLE(); }
19401940

1941+
// Find the original definition of [this] by following through any
1942+
// redefinition and check instructions.
19411943
Definition* OriginalDefinition();
19421944

1945+
// Find the original definition of [this].
1946+
//
1947+
// This is an extension of [OriginalDefinition] which also follows through any
1948+
// boxing/unboxing and constraint instructions.
1949+
Definition* OriginalDefinitionIgnoreBoxingAndConstraints();
1950+
19431951
virtual Definition* AsDefinition() { return this; }
19441952

19451953
protected:

runtime/vm/compiler/backend/loops.cc

+10-22
Original file line numberDiff line numberDiff line change
@@ -132,22 +132,6 @@ static bool IsConstant(Definition* def, int64_t* val) {
132132
return false;
133133
}
134134

135-
// Helper method to trace back to original true definition, now
136-
// also ignoring constraints and (un)boxing operations, since
137-
// these are not relevant to the induction behavior.
138-
static Definition* OriginalDefinition(Definition* def) {
139-
while (true) {
140-
Definition* orig;
141-
if (def->IsConstraint() || def->IsBox() || def->IsUnbox()) {
142-
orig = def->InputAt(0)->definition();
143-
} else {
144-
orig = def->OriginalDefinition();
145-
}
146-
if (orig == def) return def;
147-
def = orig;
148-
}
149-
}
150-
151135
void InductionVarAnalysis::VisitHierarchy(LoopInfo* loop) {
152136
for (; loop != nullptr; loop = loop->next_) {
153137
VisitLoop(loop);
@@ -273,7 +257,7 @@ void InductionVarAnalysis::Classify(LoopInfo* loop, Definition* def) {
273257
} else if (def->IsUnaryIntegerOp()) {
274258
induc = TransferUnary(loop, def);
275259
} else {
276-
Definition* orig = OriginalDefinition(def);
260+
Definition* orig = def->OriginalDefinitionIgnoreBoxingAndConstraints();
277261
if (orig != def) {
278262
induc = Lookup(loop, orig); // pass-through
279263
}
@@ -316,7 +300,7 @@ void InductionVarAnalysis::ClassifySCC(LoopInfo* loop) {
316300
} else if (def->IsConstraint()) {
317301
update = SolveConstraint(loop, def, init);
318302
} else {
319-
Definition* orig = OriginalDefinition(def);
303+
Definition* orig = def->OriginalDefinitionIgnoreBoxingAndConstraints();
320304
if (orig != def) {
321305
update = LookupCycle(orig); // pass-through
322306
}
@@ -370,10 +354,14 @@ void InductionVarAnalysis::ClassifyControl(LoopInfo* loop) {
370354
// Comparison against linear constant stride induction?
371355
// Express the comparison such that induction appears left.
372356
int64_t stride = 0;
373-
InductionVar* x =
374-
Lookup(loop, OriginalDefinition(compare->left()->definition()));
375-
InductionVar* y =
376-
Lookup(loop, OriginalDefinition(compare->right()->definition()));
357+
auto left = compare->left()
358+
->definition()
359+
->OriginalDefinitionIgnoreBoxingAndConstraints();
360+
auto right = compare->right()
361+
->definition()
362+
->OriginalDefinitionIgnoreBoxingAndConstraints();
363+
InductionVar* x = Lookup(loop, left);
364+
InductionVar* y = Lookup(loop, right);
377365
if (InductionVar::IsLinear(x, &stride) && InductionVar::IsInvariant(y)) {
378366
// ok as is
379367
} else if (InductionVar::IsInvariant(x) &&

runtime/vm/compiler/backend/range_analysis.cc

+5-4
Original file line numberDiff line numberDiff line change
@@ -1321,11 +1321,12 @@ void RangeAnalysis::EliminateRedundantBoundsChecks() {
13211321

13221322
for (intptr_t i = 0; i < bounds_checks_.length(); i++) {
13231323
// Is this a non-speculative check bound?
1324-
GenericCheckBoundInstr* aot_check =
1325-
bounds_checks_[i]->AsGenericCheckBound();
1324+
auto aot_check = bounds_checks_[i]->AsGenericCheckBound();
13261325
if (aot_check != nullptr) {
1327-
RangeBoundary array_length =
1328-
RangeBoundary::FromDefinition(aot_check->length()->definition());
1326+
auto length = aot_check->length()
1327+
->definition()
1328+
->OriginalDefinitionIgnoreBoxingAndConstraints();
1329+
auto array_length = RangeBoundary::FromDefinition(length);
13291330
if (aot_check->IsRedundant(array_length)) {
13301331
aot_check->ReplaceUsesWith(aot_check->index()->definition());
13311332
aot_check->RemoveFromGraph();

0 commit comments

Comments
 (0)