fn emit_loop_stmt(
        &mut self,
        env: ParamEnv,
        kind: hir::LoopKind,
        body: NodeId,
        body_blk: HybridBlock,
        exit_blk: HybridBlock,
    ) -> Result<()> {
        // Emit the loop initialization.
        let repeat_var = match kind {
            hir::LoopKind::Forever => None,
            hir::LoopKind::Repeat(count) => {
                let ty = self.type_of(count, env)?;
                let count = self.emit_rvalue(count, env)?;
                let var = self.mk_var(count);
                self.builder.set_name(var.0, "loop_count".to_string());
                Some((var, ty))
            }
            hir::LoopKind::While(_) => None,
            hir::LoopKind::Do(_) => None,
            hir::LoopKind::For(init, _, _) => {
                self.emit_stmt(init, env)?;
                None
            }
        };

        // Emit the loop prologue.
        self.mk_br(body_blk);
        self.append_to(body_blk);
        let enter_cond = match kind {
            hir::LoopKind::Forever => None,
            hir::LoopKind::Repeat(_) => {
                let (repeat_var, ty) = repeat_var.clone().unwrap();
                let lty = self.emit_type_both(ty)?;
                let value = self.mk_ld(repeat_var);
                let zero = self.emit_zero_for_type_both(lty);
                Some(self.mk_cmp(CmpPred::Neq, value, zero))
            }
            hir::LoopKind::While(cond) => Some(self.emit_rvalue_bool(cond, env)?),
            hir::LoopKind::Do(_) => None,
            hir::LoopKind::For(_, cond, _) => Some(self.emit_rvalue_bool(cond, env)?),
        };
        if let Some(enter_cond) = enter_cond {
            let entry_blk = self.mk_block(Some("loop_continue"));
            self.mk_cond_br(enter_cond, entry_blk, exit_blk);
            self.append_to(entry_blk);
        }

        // Emit the loop body.
        self.emit_stmt(body, env)?;

        // Emit the epilogue.
        let continue_cond = match kind {
            hir::LoopKind::Forever => None,
            hir::LoopKind::Repeat(_) => {
                let (repeat_var, ty) = repeat_var.clone().unwrap();
                let value = self.mk_ld(repeat_var);
                let one = self.mk_const_int(ty.get_bit_size().unwrap(), &BigInt::one());
                let value = self.mk_sub(value, one);
                self.mk_st(repeat_var, value);
                None
            }
            hir::LoopKind::While(_) => None,
            hir::LoopKind::Do(cond) => Some(self.emit_rvalue_bool(cond, env)?),
            hir::LoopKind::For(_, _, step) => {
                self.emit_rvalue(step, env)?;
                None
            }
        };
        if !self.terminated {
            match continue_cond {
                Some(cond) => self.mk_cond_br(cond, body_blk, exit_blk),
                None => self.mk_br(body_blk),
            };
        }
        self.append_to(exit_blk);
        Ok(())
    }
/// Emit the code for a loop statement.
Emit the code for a loop statement.
Emit the code for a loop statement .
fn emit_loop_stmt(
        &mut self,
        env: ParamEnv,
        kind: hir::LoopKind,
        body: NodeId,
        body_blk: HybridBlock,
        exit_blk: HybridBlock,
    ) -> Result<()> {
        // Emit the loop initialization.
        let repeat_var = match kind {
            hir::LoopKind::Forever => None,
            hir::LoopKind::Repeat(count) => {
                let ty = self.type_of(count, env)?;
                let count = self.emit_rvalue(count, env)?;
                let var = self.mk_var(count);
                self.builder.set_name(var.0, "loop_count".to_string());
                Some((var, ty))
            }
            hir::LoopKind::While(_) => None,
            hir::LoopKind::Do(_) => None,
            hir::LoopKind::For(init, _, _) => {
                self.emit_stmt(init, env)?;
                None
            }
        };
        // Emit the loop prologue.
        self.mk_br(body_blk);
        self.append_to(body_blk);
        let enter_cond = match kind {
            hir::LoopKind::Forever => None,
            hir::LoopKind::Repeat(_) => {
                let (repeat_var, ty) = repeat_var.clone().unwrap();
                let lty = self.emit_type_both(ty)?;
                let value = self.mk_ld(repeat_var);
                let zero = self.emit_zero_for_type_both(lty);
                Some(self.mk_cmp(CmpPred::Neq, value, zero))
            }
            hir::LoopKind::While(cond) => Some(self.emit_rvalue_bool(cond, env)?),
            hir::LoopKind::Do(_) => None,
            hir::LoopKind::For(_, cond, _) => Some(self.emit_rvalue_bool(cond, env)?),
        };
        if let Some(enter_cond) = enter_cond {
            let entry_blk = self.mk_block(Some("loop_continue"));
            self.mk_cond_br(enter_cond, entry_blk, exit_blk);
            self.append_to(entry_blk);
        }
        // Emit the loop body.
        self.emit_stmt(body, env)?;
        // Emit the epilogue.
        let continue_cond = match kind {
            hir::LoopKind::Forever => None,
            hir::LoopKind::Repeat(_) => {
                let (repeat_var, ty) = repeat_var.clone().unwrap();
                let value = self.mk_ld(repeat_var);
                let one = self.mk_const_int(ty.get_bit_size().unwrap(), &BigInt::one());
                let value = self.mk_sub(value, one);
                self.mk_st(repeat_var, value);
                None
            }
            hir::LoopKind::While(_) => None,
            hir::LoopKind::Do(cond) => Some(self.emit_rvalue_bool(cond, env)?),
            hir::LoopKind::For(_, _, step) => {
                self.emit_rvalue(step, env)?;
                None
            }
        };
        if !self.terminated {
            match continue_cond {
                Some(cond) => self.mk_cond_br(cond, body_blk, exit_blk),
                None => self.mk_br(body_blk),
            };
        }
        self.append_to(exit_blk);
        Ok(())
    }
fn emit_loop_stmt ( & mut self , env : ParamEnv , kind : hir :: LoopKind , body : NodeId , body_blk : HybridBlock , exit_blk : HybridBlock , ) -> Result < ( ) > { // Emit the loop initialization. let repeat_var = match kind { hir :: LoopKind :: Forever => None , hir :: LoopKind :: Repeat ( count ) => { let ty = self . type_of ( count , env ) ? ; let count = self . emit_rvalue ( count , env ) ? ; let var = self . mk_var ( count ) ; self . builder . set_name ( var . 0 , " " . to_string ( ) ) ; Some ( ( var , ty ) ) } hir :: LoopKind :: While ( _ ) => None , hir :: LoopKind :: Do ( _ ) => None , hir :: LoopKind :: For ( init , _ , _ ) => { self . emit_stmt ( init , env ) ? ; None } } ; // Emit the loop prologue. self . mk_br ( body_blk ) ; self . append_to ( body_blk ) ; let enter_cond = match kind { hir :: LoopKind :: Forever => None , hir :: LoopKind :: Repeat ( _ ) => { let ( repeat_var , ty ) = repeat_var . clone ( ) . unwrap ( ) ; let lty = self . emit_type_both ( ty ) ? ; let value = self . mk_ld ( repeat_var ) ; let zero = self . emit_zero_for_type_both ( lty ) ; Some ( self . mk_cmp ( CmpPred :: Neq , value , zero ) ) } hir :: LoopKind :: While ( cond ) => Some ( self . emit_rvalue_bool ( cond , env ) ? ) , hir :: LoopKind :: Do ( _ ) => None , hir :: LoopKind :: For ( _ , cond , _ ) => Some ( self . emit_rvalue_bool ( cond , env ) ? ) , } ; if let Some ( enter_cond ) = enter_cond { let entry_blk = self . mk_block ( Some ( " " ) ) ; self . mk_cond_br ( enter_cond , entry_blk , exit_blk ) ; self . append_to ( entry_blk ) ; } // Emit the loop body. self . emit_stmt ( body , env ) ? ; // Emit the epilogue. let continue_cond = match kind { hir :: LoopKind :: Forever => None , hir :: LoopKind :: Repeat ( _ ) => { let ( repeat_var , ty ) = repeat_var . clone ( ) . unwrap ( ) ; let value = self . mk_ld ( repeat_var ) ; let one = self . mk_const_int ( ty . get_bit_size ( ) . unwrap ( ) , & BigInt :: one ( ) ) ; let value = self . mk_sub ( value , one ) ; self . mk_st ( repeat_var , value ) ; None } hir :: LoopKind :: While ( _ ) => None , hir :: LoopKind :: Do ( cond ) => Some ( self . emit_rvalue_bool ( cond , env ) ? ) , hir :: LoopKind :: For ( _ , _ , step ) => { self . emit_rvalue ( step , env ) ? ; None } } ; if ! self . terminated { match continue_cond { Some ( cond ) => self . mk_cond_br ( cond , body_blk , exit_blk ) , None => self . mk_br ( body_blk ) , } ; } self . append_to ( exit_blk ) ; Ok ( ( ) ) }
Emit the code for a loop statement.
Emit the code for a loop statement .
&mut self
env
ParamEnv
kind
hir::LoopKind
body
NodeId
body_blk
HybridBlock
exit_blk
HybridBlock
&mut self
env
ParamEnv
kind
hir::LoopKind
body
NodeId
body_blk
HybridBlock
exit_blk
HybridBlock