@@ -1986,6 +1986,20 @@ impl Function {
1986
1986
self . insn_types [ replacement. 0 ] = self . infer_type ( replacement) ;
1987
1987
self . make_equal_to ( insn_id, replacement) ;
1988
1988
}
1989
+ Insn :: NewRange { low, high, flag, state } => {
1990
+ let low_is_fix = self . is_a ( low, types:: Fixnum ) ;
1991
+ let high_is_fix = self . is_a ( high, types:: Fixnum ) ;
1992
+
1993
+ if low_is_fix || high_is_fix {
1994
+ let low_fix = self . coerce_to_fixnum ( block, low, state) ;
1995
+ let high_fix = self . coerce_to_fixnum ( block, high, state) ;
1996
+ let replacement = self . push_insn ( block, Insn :: NewRangeFixnum { low : low_fix, high : high_fix, flag, state } ) ;
1997
+ self . make_equal_to ( insn_id, replacement) ;
1998
+ self . insn_types [ replacement. 0 ] = self . infer_type ( replacement) ;
1999
+ } else {
2000
+ self . push_insn_id ( block, insn_id) ;
2001
+ } ;
2002
+ }
1989
2003
_ => { self . push_insn_id ( block, insn_id) ; }
1990
2004
}
1991
2005
}
@@ -2194,52 +2208,6 @@ impl Function {
2194
2208
. unwrap_or ( insn_id)
2195
2209
}
2196
2210
2197
- fn optimize_ranges ( & mut self ) {
2198
- for block in self . rpo ( ) {
2199
- let old_insns = std:: mem:: take ( & mut self . blocks [ block. 0 ] . insns ) ;
2200
- assert ! ( self . blocks[ block. 0 ] . insns. is_empty( ) ) ;
2201
-
2202
- for insn_id in old_insns {
2203
- match self . find ( insn_id) {
2204
- Insn :: NewRange { low, high, flag, state } => {
2205
-
2206
- // The NewRange rewrite triggers mostly on literals because that is the
2207
- // case we can easily prove Fixnum statically and cheaply guard the other
2208
- // side.
2209
- let low_is_fix = self . is_a ( low, types:: Fixnum ) ;
2210
- let high_is_fix = self . is_a ( high, types:: Fixnum ) ;
2211
-
2212
- if low_is_fix && high_is_fix {
2213
- // Both statically fixnum => specialize directly
2214
- let repl = self . push_insn ( block, Insn :: NewRangeFixnum { low, high, flag, state } ) ;
2215
- self . make_equal_to ( insn_id, repl) ;
2216
- self . insn_types [ repl. 0 ] = self . infer_type ( repl) ;
2217
- } else if low_is_fix {
2218
- // Only left is fixnum => guard right
2219
- let high_fix = self . coerce_to_fixnum ( block, high, state) ;
2220
- let repl = self . push_insn ( block, Insn :: NewRangeFixnum { low, high : high_fix, flag, state } ) ;
2221
- self . make_equal_to ( insn_id, repl) ;
2222
- self . insn_types [ repl. 0 ] = self . infer_type ( repl) ;
2223
- } else if high_is_fix {
2224
- // Only right is fixnum => guard left
2225
- let low_fix = self . coerce_to_fixnum ( block, low, state) ;
2226
- let repl = self . push_insn ( block, Insn :: NewRangeFixnum { low : low_fix, high, flag, state } ) ;
2227
- self . make_equal_to ( insn_id, repl) ;
2228
- self . insn_types [ repl. 0 ] = self . infer_type ( repl) ;
2229
- } else {
2230
- // Keep generic op
2231
- self . push_insn_id ( block, insn_id) ;
2232
- }
2233
- }
2234
- _ => {
2235
- self . push_insn_id ( block, insn_id) ;
2236
- }
2237
- }
2238
- }
2239
- }
2240
- self . infer_types ( ) ;
2241
- }
2242
-
2243
2211
/// Use type information left by `infer_types` to fold away operations that can be evaluated at compile-time.
2244
2212
///
2245
2213
/// It can fold fixnum math, truthiness tests, and branches with constant conditionals.
@@ -2635,8 +2603,6 @@ impl Function {
2635
2603
#[ cfg( debug_assertions) ] self . assert_validates ( ) ;
2636
2604
self . optimize_c_calls ( ) ;
2637
2605
#[ cfg( debug_assertions) ] self . assert_validates ( ) ;
2638
- self . optimize_ranges ( ) ;
2639
- #[ cfg( debug_assertions) ] self . assert_validates ( ) ;
2640
2606
self . fold_constants ( ) ;
2641
2607
#[ cfg( debug_assertions) ] self . assert_validates ( ) ;
2642
2608
self . clean_cfg ( ) ;
@@ -7253,41 +7219,50 @@ mod opt_tests {
7253
7219
}
7254
7220
7255
7221
#[ test]
7256
- fn test_optimize_range_fixnum_inclusive_literals ( ) {
7222
+ fn test_optimize_new_range_fixnum_inclusive_literals ( ) {
7257
7223
eval ( "
7258
7224
def test()
7259
- (1..2)
7225
+ a = 2
7226
+ (1..a)
7260
7227
end
7261
7228
test; test
7262
7229
" ) ;
7263
7230
assert_snapshot ! ( hir_string( "test" ) , @r"
7264
7231
fn test@<compiled>:3:
7265
7232
bb0(v0:BasicObject):
7266
- v4:RangeExact[VALUE(0x1000)] = Const Value(VALUE(0x1000))
7233
+ v1:NilClass = Const Value(nil)
7234
+ v5:Fixnum[2] = Const Value(2)
7235
+ v8:Fixnum[1] = Const Value(1)
7236
+ v16:RangeExact = NewRangeFixnum v8 NewRangeInclusive v5
7267
7237
CheckInterrupts
7268
- Return v4
7238
+ Return v16
7269
7239
" ) ;
7270
7240
}
7271
7241
7242
+
7272
7243
#[ test]
7273
- fn test_optimize_range_fixnum_exclusive_literals ( ) {
7244
+ fn test_optimize_new_range_fixnum_exclusive_literals ( ) {
7274
7245
eval ( "
7275
7246
def test()
7276
- (1...2)
7247
+ a = 2
7248
+ (1...a)
7277
7249
end
7278
7250
test; test
7279
7251
" ) ;
7280
7252
assert_snapshot ! ( hir_string( "test" ) , @r"
7281
7253
fn test@<compiled>:3:
7282
7254
bb0(v0:BasicObject):
7283
- v4:RangeExact[VALUE(0x1000)] = Const Value(VALUE(0x1000))
7255
+ v1:NilClass = Const Value(nil)
7256
+ v5:Fixnum[2] = Const Value(2)
7257
+ v8:Fixnum[1] = Const Value(1)
7258
+ v16:RangeExact = NewRangeFixnum v8 NewRangeExclusive v5
7284
7259
CheckInterrupts
7285
- Return v4
7260
+ Return v16
7286
7261
" ) ;
7287
7262
}
7288
7263
7289
7264
#[ test]
7290
- fn test_optimize_range_fixnum_inclusive_high_guarded ( ) {
7265
+ fn test_optimize_new_range_fixnum_inclusive_high_guarded ( ) {
7291
7266
eval ( "
7292
7267
def test(a)
7293
7268
(1..a)
@@ -7306,7 +7281,7 @@ mod opt_tests {
7306
7281
}
7307
7282
7308
7283
#[ test]
7309
- fn test_optimize_range_fixnum_exclusive_high_guarded ( ) {
7284
+ fn test_optimize_new_range_fixnum_exclusive_high_guarded ( ) {
7310
7285
eval ( "
7311
7286
def test(a)
7312
7287
(1...a)
@@ -7325,7 +7300,7 @@ mod opt_tests {
7325
7300
}
7326
7301
7327
7302
#[ test]
7328
- fn test_optimize_range_fixnum_inclusive_low_guarded ( ) {
7303
+ fn test_optimize_new_range_fixnum_inclusive_low_guarded ( ) {
7329
7304
eval ( "
7330
7305
def test(a)
7331
7306
(a..10)
@@ -7344,7 +7319,7 @@ mod opt_tests {
7344
7319
}
7345
7320
7346
7321
#[ test]
7347
- fn test_optimize_range_fixnum_exclusive_low_guarded ( ) {
7322
+ fn test_optimize_new_range_fixnum_exclusive_low_guarded ( ) {
7348
7323
eval ( "
7349
7324
def test(a)
7350
7325
(a...10)
0 commit comments