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