Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(104)

Unified Diff: pkg/compiler/lib/src/ssa/codegen.dart

Issue 2507883002: Bit width analysis for avoiding conversion of bitops to unsigned. (Closed)
Patch Set: Fix warnings Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/compiler/lib/src/ssa/codegen.dart
diff --git a/pkg/compiler/lib/src/ssa/codegen.dart b/pkg/compiler/lib/src/ssa/codegen.dart
index c882259fbdd51f9eb75271f782de0f219773e067..cd9d7c099fe3ba4e2bb35c46b0fbb9546353d57d 100644
--- a/pkg/compiler/lib/src/ssa/codegen.dart
+++ b/pkg/compiler/lib/src/ssa/codegen.dart
@@ -2,6 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+import 'dart:math' as math;
import '../common.dart';
import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem;
import '../common/tasks.dart' show CompilerTask;
@@ -210,8 +211,59 @@ class SsaCodeGenerator implements HVisitor, HBlockInformationVisitor {
return false;
}
+ // Returns the number of bits occupied by the value computed by [instruction].
+ // Returns `32` if the value is negative or does not fit in a smaller number
+ // of bits.
+ int bitWidth(HInstruction instruction) {
+ const int MAX = 32;
+ int constant(HInstruction insn) {
+ if (insn is HConstant && insn.isConstantInteger()) {
+ IntConstantValue constant = insn.constant;
+ return constant.primitiveValue;
+ }
+ return null;
+ }
+
+ if (instruction.isConstantInteger()) {
+ int value = constant(instruction);
+ if (value < 0) return MAX;
+ if (value > ((1 << 31) - 1)) return MAX;
+ return value.bitLength;
+ }
+ if (instruction is HBitAnd) {
+ return math.min(bitWidth(instruction.left), bitWidth(instruction.right));
+ }
+ if (instruction is HBitOr || instruction is HBitXor) {
+ HBinaryBitOp bitOp = instruction;
+ int leftWidth = bitWidth(bitOp.left);
+ if (leftWidth == MAX) return MAX;
+ return math.max(leftWidth, bitWidth(bitOp.right));
+ }
+ if (instruction is HShiftLeft) {
+ int shiftCount = constant(instruction.right);
+ if (shiftCount == null || shiftCount < 0 || shiftCount > 31) return MAX;
+ int leftWidth = bitWidth(instruction.left);
+ int width = leftWidth + shiftCount;
+ return math.min(width, MAX);
+ }
+ if (instruction is HShiftRight) {
+ int shiftCount = constant(instruction.right);
+ if (shiftCount == null || shiftCount < 0 || shiftCount > 31) return MAX;
+ int leftWidth = bitWidth(instruction.left);
+ if (leftWidth >= MAX) return MAX;
+ return math.max(leftWidth - shiftCount, 0);
+ }
+ if (instruction is HAdd) {
+ return math.min(
+ 1 + math.max(bitWidth(instruction.left), bitWidth(instruction.right)),
+ MAX);
+ }
+ return MAX;
+ }
+
bool requiresUintConversion(instruction) {
if (instruction.isUInt31(compiler)) return false;
+ if (bitWidth(instruction) <= 31) return false;
// If the result of a bit-operation is only used by other bit
// operations, we do not have to convert to an unsigned integer.
return hasNonBitOpUser(instruction, new Set<HPhi>());
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698