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

Unified Diff: src/hydrogen-instructions.cc

Issue 9156001: Improved range analysis for bitwise operations. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 8 years, 11 months 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 | « src/hydrogen-instructions.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/hydrogen-instructions.cc
===================================================================
--- src/hydrogen-instructions.cc (revision 10356)
+++ src/hydrogen-instructions.cc (working copy)
@@ -108,16 +108,62 @@
}
-int32_t Range::Mask() const {
- if (lower_ == upper_) return lower_;
- if (lower_ >= 0) {
- int32_t res = 1;
- while (res < upper_) {
- res = (res << 1) | 1;
- }
- return res;
+class BitRange {
+ public:
+ BitRange() : known_(0), bits_(0) { }
+ BitRange(int32_t known, int32_t bits)
+ : known_(known), bits_(bits & known) { }
+
+ static void SetFromRange(BitRange* bits, int32_t lower, int32_t upper) {
+ // Find a mask for the most significant bits that are the same for all
+ // values in the range.
+ int32_t same = ~(lower ^ upper);
+ // Flood zeros to any bits lower than the most significant zero.
+ same &= (same >> 1);
+ same &= (same >> 2);
+ same &= (same >> 4);
+ same &= (same >> 8);
+ same &= (same >> 16);
+
+ bits->known_ = same;
+ bits->bits_ = lower & same;
}
- return 0xffffffff;
+
+ void ExtendRange(int32_t* lower, int32_t* upper) {
+ int32_t limit1 = (~known_ & 0x80000000) | bits_;
+ int32_t limit2 = (~known_ & 0x7fffffff) | bits_;
+ *lower = Min(*lower, Min(limit1, limit2));
+ *upper = Max(*upper, Max(limit1, limit2));
+ }
+
+ static BitRange And(BitRange a, BitRange b) {
+ int32_t known = a.known_ & b.known_;
+ // Zeros in either operand become known.
+ known |= (a.known_ & ~a.bits_);
+ known |= (b.known_ & ~b.bits_);
+ return BitRange(known, a.bits_ & b.bits_);
+ }
+
+ static BitRange Or(BitRange a, BitRange b) {
+ int32_t known = a.known_ & b.known_;
+ // Ones in either operand become known.
+ known |= (a.known_ & a.bits_);
+ known |= (b.known_ & b.bits_);
+ return BitRange(known, a.bits_ | b.bits_);
+ }
+
+ static BitRange Xor(BitRange a, BitRange b) {
+ return BitRange(a.known_ & b.known_, a.bits_ ^ b.bits_);
+ }
+
+ private:
+ int32_t known_; // A mask of known bits.
+ int32_t bits_; // Values of known bits, zero elsewhere.
+};
+
+
+void Range::ToBitRange(BitRange* bits) const {
+ BitRange::SetFromRange(bits, lower_, upper_);
}
@@ -1243,19 +1289,36 @@
Range* HBitwise::InferRange() {
- if (op() == Token::BIT_XOR) return HValue::InferRange();
- int32_t left_mask = (left()->range() != NULL)
- ? left()->range()->Mask()
- : 0xffffffff;
- int32_t right_mask = (right()->range() != NULL)
- ? right()->range()->Mask()
- : 0xffffffff;
- int32_t result_mask = (op() == Token::BIT_AND)
- ? left_mask & right_mask
- : left_mask | right_mask;
- return (result_mask >= 0)
- ? new Range(0, result_mask)
- : HValue::InferRange();
+ if (representation().IsInteger32()) {
+ BitRange left_bits, right_bits;
+
+ if (left()->range() != NULL)
+ left()->range()->ToBitRange(&left_bits);
+
+ if (right()->range() != NULL)
+ right()->range()->ToBitRange(&right_bits);
+
+ BitRange result;
+ switch (op()) {
+ case Token::BIT_AND:
+ result = BitRange::And(left_bits, right_bits);
+ break;
+ case Token::BIT_OR:
+ result = BitRange::Or(left_bits, right_bits);
+ break;
+ case Token::BIT_XOR:
+ result = BitRange::Xor(left_bits, right_bits);
+ break;
+ default:
+ UNREACHABLE();
+ }
+
+ int32_t lower = kMaxInt, upper = kMinInt; // 'empty' range.
+ result.ExtendRange(&lower, &upper);
fschneider 2012/02/28 13:26:52 I'd simplify this by propagating the inputs kMaxIn
sra1 2013/06/11 05:19:15 This looks a little strange but let me explain. T
fschneider 2013/06/11 10:22:37 Thanks for the explanation. The code just looked s
+ return new Range(lower, upper);
+ } else {
+ return HValue::InferRange();
+ }
}
« no previous file with comments | « src/hydrogen-instructions.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698