| 258 | // Both of the above optimisations save CPU cycles during expression evaluation. |
| 259 | |
| 260 | int ExprDecomposer::PushThenEntry(const IfNode& node, bool reuse_bitmap) { |
| 261 | int local_bitmap_idx; |
| 262 | |
| 263 | if (reuse_bitmap) { |
| 264 | // we also need stack in addition to reuse_bitmap flag since we |
| 265 | // can also enter other if-else nodes when we visit the condition-node |
| 266 | // (which themselves might be nested) before we visit then-node |
| 267 | DCHECK_EQ(if_entries_stack_.empty(), false) << "PushThenEntry: stack is empty"; |
| 268 | DCHECK_EQ(if_entries_stack_.top()->entry_type_, kStackEntryElse) |
| 269 | << "PushThenEntry: top of stack is not of type entry_else"; |
| 270 | auto top = if_entries_stack_.top().get(); |
| 271 | |
| 272 | // inside a nested else statement (i.e if-else-if). use the parent's bitmap. |
| 273 | local_bitmap_idx = top->local_bitmap_idx_; |
| 274 | |
| 275 | // clear the is_terminal bit in the current top entry (else). |
| 276 | top->is_terminal_else_ = false; |
| 277 | } else { |
| 278 | // alloc a new bitmap. |
| 279 | local_bitmap_idx = annotator_.AddLocalBitMap(); |
| 280 | } |
| 281 | |
| 282 | // push new entry to the stack. |
| 283 | std::unique_ptr<IfStackEntry> entry(new IfStackEntry( |
| 284 | node, kStackEntryThen, false /*is_terminal_else*/, local_bitmap_idx)); |
| 285 | if_entries_stack_.emplace(std::move(entry)); |
| 286 | return local_bitmap_idx; |
| 287 | } |
| 288 | |
| 289 | void ExprDecomposer::PopThenEntry(const IfNode& node) { |
| 290 | DCHECK_EQ(if_entries_stack_.empty(), false) << "PopThenEntry: found empty stack"; |