@@ -65,44 +65,36 @@ pub fn trans_if(bcx: @mut Block,
65
65
66
66
let _icx = push_ctxt( "trans_if" ) ;
67
67
68
- match cond . node {
69
- // `if true` and `if false` can be trans'd more efficiently,
70
- // by dropping branches that are known to be impossible.
71
- ast : : expr_lit ( @ ref l ) => match l . node {
72
- ast : : lit_bool ( true ) => {
73
- // if true { .. } [else { .. }]
74
- let then_bcx_in = scope_block ( bcx , thn . info ( ) , "if_true_then" ) ;
75
- let then_bcx_out = trans_block ( then_bcx_in , thn , dest ) ;
76
- let then_bcx_out = trans_block_cleanups ( then_bcx_out ,
77
- block_cleanups ( then_bcx_in ) ) ;
78
- Br ( bcx, then_bcx_in . llbb ) ;
79
- return then_bcx_out ;
68
+ let Result { bcx , val : cond_val } =
69
+ expr :: trans_to_datum ( bcx , cond ) . to_result ( ) ;
70
+
71
+ let cond_val = bool_to_i1 ( bcx , cond_val ) ;
72
+
73
+ // Drop branches that are known to be impossible
74
+ if is_const ( cond_val ) && !is_undef ( cond_val ) {
75
+ if const_to_uint ( cond_val ) == 1 {
76
+ // if true { .. } [else { .. }]
77
+ return do with_scope ( bcx , thn . info ( ) , "if_true_then" ) |bcx| {
78
+ let bcx_out = trans_block ( bcx, thn , dest ) ;
79
+ trans_block_cleanups ( bcx_out , block_cleanups ( bcx ) )
80
80
}
81
- ast:: lit_bool( false ) => {
82
- match els {
83
- // if false { .. } else { .. }
84
- Some ( elexpr) => {
85
- let ( else_bcx_in, else_bcx_out) =
86
- trans_if_else( bcx, elexpr, dest, "if_false_else" ) ;
87
- Br ( bcx, else_bcx_in. llbb) ;
88
- return else_bcx_out;
81
+ } else {
82
+ match els {
83
+ // if false { .. } else { .. }
84
+ Some ( elexpr) => {
85
+ return do with_scope( bcx, elexpr. info( ) , "if_false_then" ) |bcx| {
86
+ let bcx_out = trans_if_else( bcx, elexpr, dest) ;
87
+ trans_block_cleanups( bcx_out, block_cleanups( bcx) )
89
88
}
90
- // if false { .. }
91
- None => return bcx,
92
89
}
90
+ // if false { .. }
91
+ None => return bcx,
93
92
}
94
- _ => { }
95
- } ,
96
- _ => { }
93
+ }
97
94
}
98
95
99
- let Result { bcx, val : cond_val} =
100
- expr:: trans_to_datum( bcx, cond) . to_result( ) ;
101
-
102
96
let then_bcx_in = scope_block( bcx, thn. info( ) , "then" ) ;
103
97
104
- let cond_val = bool_to_i1( bcx, cond_val) ;
105
-
106
98
let then_bcx_out = trans_block( then_bcx_in, thn, dest) ;
107
99
let then_bcx_out = trans_block_cleanups( then_bcx_out,
108
100
block_cleanups( then_bcx_in) ) ;
@@ -113,7 +105,8 @@ pub fn trans_if(bcx: @mut Block,
113
105
// 'else' context
114
106
let ( else_bcx_in, next_bcx) = match els {
115
107
Some ( elexpr) => {
116
- let ( else_bcx_in, else_bcx_out) = trans_if_else( bcx, elexpr, dest, "else" ) ;
108
+ let else_bcx_in = scope_block( bcx, elexpr. info( ) , "else" ) ;
109
+ let else_bcx_out = trans_if_else( else_bcx_in, elexpr, dest) ;
117
110
( else_bcx_in, join_blocks( bcx, [ then_bcx_out, else_bcx_out] ) )
118
111
}
119
112
_ => {
@@ -131,9 +124,8 @@ pub fn trans_if(bcx: @mut Block,
131
124
return next_bcx;
132
125
133
126
// trans `else [ if { .. } ... | { .. } ]`
134
- fn trans_if_else( bcx: @mut Block , elexpr: @ast:: expr,
135
- dest: expr:: Dest , scope_name: & str) -> ( @mut Block , @mut Block ) {
136
- let else_bcx_in = scope_block( bcx, elexpr. info( ) , scope_name) ;
127
+ fn trans_if_else( else_bcx_in: @mut Block , elexpr: @ast:: expr,
128
+ dest: expr:: Dest ) -> @mut Block {
137
129
let else_bcx_out = match elexpr. node {
138
130
ast : : expr_if( _, _, _) => {
139
131
let elseif_blk = ast_util:: block_from_expr( elexpr) ;
@@ -143,11 +135,9 @@ pub fn trans_if(bcx: @mut Block,
143
135
trans_block( else_bcx_in, blk, dest)
144
136
}
145
137
// would be nice to have a constraint on ifs
146
- _ => bcx . tcx( ) . sess. bug( "strange alternative in if" )
138
+ _ => else_bcx_in . tcx( ) . sess. bug( "strange alternative in if" )
147
139
} ;
148
- let else_bcx_out = trans_block_cleanups( else_bcx_out,
149
- block_cleanups( else_bcx_in) ) ;
150
- ( else_bcx_in, else_bcx_out)
140
+ trans_block_cleanups( else_bcx_out, block_cleanups( else_bcx_in) )
151
141
}
152
142
}
153
143
0 commit comments