diff --git a/src/AST/AST.cpp b/src/AST/AST.cpp
index b59723225da403bc02493245882d0694b7b3782d..e963cbd1a48c3f296e743a579e11538b90ba7042 100644
--- a/src/AST/AST.cpp
+++ b/src/AST/AST.cpp
@@ -64,23 +64,70 @@ void BlockItemAST::Dump() const{
 }
 
 void StmtAST::Dump() const{
-    std::cout << "StmtAST{";
     switch(tag){
-        case StmtAST::Return_Exp:
+        case MatchedStmt:
+            matched_stmt->Dump();
+            break;
+        case OpenStmt:
+            open_stmt->Dump();
+            break;
+        default:
+            assert(false);
+    }
+}
+
+void MatchedStmtAST::Dump() const{
+    switch(tag){
+        case If_Exp_MatchedStmt_Else_MatchedStmt:
             exp->Dump();
+            if_matched_stmt->Dump();
+            else_matched_stmt->Dump();
             break;
-        case StmtAST::LVal_Assign_Exp:
-            l_val->Dump();
-            std::cout << "=";
+        case OtherStmt:
+            other_stmt->Dump();
+            break;
+        default:
+            assert(false);
+    }
+}
+
+void OpenStmtAST::Dump() const{
+    std::cout << "OpenStmtAST{";
+    switch(tag){
+        case If_Exp_Stmt:
             exp->Dump();
+            if_stmt->Dump();
             break;
-        case StmtAST::Exp:
+        case If_Exp_MatchedStmt_Else_OpenStmt:
             exp->Dump();
+            if_matched_stmt->Dump();
+            else_open_stmt->Dump();
             break;
-        case StmtAST::Block:
+        default:
+            assert(false);
+    }
+    std::cout << "}";
+}
+
+void OtherStmtAST::Dump() const{
+    std::cout << "OtherStmtAST{";
+    switch(tag){
+        case Exp:
+            exp->Dump();
+            break;
+        case Block:
             block->Dump();
             break;
-        case StmtAST::Empty:
+        case Return_Exp:
+            std::cout << "return ";
+            exp->Dump();
+            break;
+        case LVal_Assign_Exp:
+            l_val->Dump();
+            std::cout << "=";
+            exp->Dump();
+            break;
+        case Empty:
             break;
         default:
             assert(false);
diff --git a/src/AST/AST.hpp b/src/AST/AST.hpp
index 7b2ca6320867b5bebe214df7f44df1af834d1636..13e7deb2086d497199346a79b8710b25b06a80b5 100644
--- a/src/AST/AST.hpp
+++ b/src/AST/AST.hpp
@@ -11,6 +11,9 @@ class FuncTypeAST;
 class BlockAST;
 class BlockItemAST;
 class StmtAST;
+class MatchedStmtAST;
+class OpenStmtAST;
+class OtherStmtAST;
 
 class ExpAST;
 class LOrExpAST;
@@ -88,6 +91,49 @@ public:
 };
 
 class StmtAST : public BaseAST{
+public:
+    enum Tag{
+        MatchedStmt,
+        OpenStmt
+    } tag;
+    std::unique_ptr<MatchedStmtAST> matched_stmt;
+    std::unique_ptr<OpenStmtAST> open_stmt;
+
+    StmtAST(Tag _tag):tag(_tag){}
+    void Dump() const override;
+};
+
+class MatchedStmtAST : public BaseAST{
+public:
+    enum Tag{
+        If_Exp_MatchedStmt_Else_MatchedStmt,
+        OtherStmt
+    } tag;
+    std::unique_ptr<ExpAST> exp;
+    std::unique_ptr<MatchedStmtAST> if_matched_stmt;
+    std::unique_ptr<MatchedStmtAST> else_matched_stmt;
+    std::unique_ptr<OtherStmtAST> other_stmt;
+
+    MatchedStmtAST(Tag _tag):tag(_tag){}
+    void Dump() const override;
+};
+
+class OpenStmtAST : public BaseAST{
+public:
+    enum Tag{
+        If_Exp_Stmt,
+        If_Exp_MatchedStmt_Else_OpenStmt
+    } tag;
+    std::unique_ptr<ExpAST> exp;
+    std::unique_ptr<StmtAST> if_stmt;
+    std::unique_ptr<MatchedStmtAST> if_matched_stmt;
+    std::unique_ptr<OpenStmtAST> else_open_stmt;
+
+    OpenStmtAST(Tag _tag):tag(_tag){}
+    void Dump() const override;
+};
+
+class OtherStmtAST : public BaseAST{
 public:
     enum Tag{
         Return_Exp,
@@ -100,7 +146,7 @@ public:
     std::unique_ptr<LValAST> l_val;
     std::unique_ptr<BlockAST> block;
 
-    StmtAST(Tag _tag):tag(_tag){}
+    OtherStmtAST(Tag _tag):tag(_tag){}
     void Dump() const override;
 };
 
diff --git a/src/Koopa/KoopaBuilder.cpp b/src/Koopa/KoopaBuilder.cpp
index 0f158c9485e456b0ef754f5fe21e9d20cffbabcc..6084b310c5df07a1fd344b386b8186b5482ce3cb 100644
--- a/src/Koopa/KoopaBuilder.cpp
+++ b/src/Koopa/KoopaBuilder.cpp
@@ -11,16 +11,6 @@ koopa_raw_program_t KoopaBuilder::GenerateKoopaIR(const BaseAST& ast) {
     return GenerateProgram(*comp_unit);
 }
 
-// Generate Program
-/*
-program的结构体定义如下:
-typedef struct {
-  /// Global values (global allocations only).
-  koopa_raw_slice_t values; 
-  /// Function definitions.
-  koopa_raw_slice_t funcs; //每个函数是一个 koopa_raw_function_t 类型的实例,指向 koopa_raw_function_data_t。
-} koopa_raw_program_t;
-*/
 koopa_raw_program_t KoopaBuilder::GenerateProgram(const CompUnitAST& ast) {
     
     std::vector<const void *> funcs;
@@ -31,22 +21,10 @@ koopa_raw_program_t KoopaBuilder::GenerateProgram(const CompUnitAST& ast) {
     koopa_raw_program_t program;
     program.values = CreateSlice(KOOPA_RSIK_VALUE);
     program.funcs = CreateSlice(funcs,KOOPA_RSIK_FUNCTION);
+
     return program;
 }
 
-// Generate 
-/*
-typedef struct {
-  /// Type of function.
-  koopa_raw_type_t ty;
-  /// Name of function.
-  const char *name;
-  /// Parameters.
-  koopa_raw_slice_t params;
-  /// Basic blocks, empty if is a function declaration.
-  koopa_raw_slice_t bbs;
-} koopa_raw_function_data_t;
-*/
 koopa_raw_function_t KoopaBuilder::GenerateFunction(const FuncDefAST& func_def) {
     koopa_raw_type_kind_t* ptype =new koopa_raw_type_kind_t();
     ptype->tag = KOOPA_RTT_FUNCTION;
@@ -55,13 +33,13 @@ koopa_raw_function_t KoopaBuilder::GenerateFunction(const FuncDefAST& func_def)
 
     std::vector<const void *> basic_blocks;
     for (auto& block : func_def.block_vec) {
-        // basic_blocks.push_back(GenerateBlock(*block));
         GenerateBlock(*block);
     }
-    for (auto& block : block_manager.block_vec) {
-        basic_blocks.push_back(block);
+    block_manager.UpdataBlock();
+    block_manager.DeleteUnreachableBlock();
+    for(auto& block : block_manager.block_vec){
+        basic_blocks.push_back(block.block);
     }
-    block_manager.block_vec.clear();
 
     koopa_raw_function_data_t* function = new koopa_raw_function_data_t();
     function->ty = ptype;
@@ -71,21 +49,10 @@ koopa_raw_function_t KoopaBuilder::GenerateFunction(const FuncDefAST& func_def)
     return function;
 }
 
-// Generate Block
-/*
-typedef struct {
-  /// Name of basic block, null if no name.
-  const char *name;
-  /// Parameters.
-  koopa_raw_slice_t params;
-  /// Values that this basic block is used by.
-  koopa_raw_slice_t used_by;
-  /// Instructions in this basic block.
-  koopa_raw_slice_t insts;
-} koopa_raw_basic_block_data_t;
-*/
 koopa_raw_basic_block_t KoopaBuilder::GenerateBlock(const BlockAST& block) {
-    value_manager.CreateValueManager();
+    koopa_raw_basic_block_data_t* basic_block = new koopa_raw_basic_block_data_t();
+    block_manager.AddBlock(basic_block);
+    int block_index = block_manager.current_block_index;
     symbol_table.EnterScope();
     std::vector<const void *> insts;
     for(auto& block_item : block.block_item_vec){
@@ -99,80 +66,143 @@ koopa_raw_basic_block_t KoopaBuilder::GenerateBlock(const BlockAST& block) {
             default:
                 throw std::runtime_error("Invalid block item type.");
         }
-        if(block_item->tag==BlockItemAST::Tag::Stmt&&block_item->stmt->tag == StmtAST::Tag::Return_Exp){
-            break;
-        }
     }
 
-    for(auto& value : value_manager.value_vec[value_manager.current_value_manager]){
+    for(auto& value : block_manager.block_vec[block_index].value_manager.value_vec){
         insts.push_back(value);
         if(value->kind.tag == KOOPA_RVT_RETURN){
             break;
         }
     }
-    value_manager.DestroyValueManager();
 
-    koopa_raw_basic_block_data_t* basic_block = new koopa_raw_basic_block_data_t();
+    // koopa_raw_basic_block_data_t* basic_block = new koopa_raw_basic_block_data_t();
     basic_block->name = strdup(("%block" + std::to_string(block_manager.block_vec.size())).c_str());
     basic_block->params = CreateSlice(KOOPA_RSIK_VALUE);
     basic_block->used_by = CreateSlice(KOOPA_RSIK_VALUE);
     basic_block->insts = CreateSlice(insts,KOOPA_RSIK_VALUE);
 
-    if(insts.size()>0){
-        block_manager.block_vec.push_back(basic_block);
-    }
-    // block_manager.block_vec.push_back(basic_block);
     symbol_table.ExitScope();
     return basic_block;
 }
 
-// Generate Statement
-/*
-struct koopa_raw_value_data {
-  /// Type of value.
-  koopa_raw_type_t ty;
-  /// Name of value, null if no name.
-  const char *name;
-  /// Values that this value is used by.
-  koopa_raw_slice_t used_by;
-  /// Kind of value.
-  koopa_raw_value_kind_t kind;
-};
-*/
 koopa_raw_value_t KoopaBuilder::GenerateValue(const StmtAST& stmt) {
+    switch (stmt.tag) {
+        case StmtAST::Tag::MatchedStmt:
+            return GenerateValue(*stmt.matched_stmt);
+        case StmtAST::Tag::OpenStmt:
+            return GenerateValue(*stmt.open_stmt);
+        default:
+            throw std::runtime_error("Invalid statement type.");
+    }
+    return nullptr;
+}
+
+koopa_raw_value_t KoopaBuilder::GenerateValue(const MatchedStmtAST& matched_stmt) {
+    koopa_raw_value_data_t* value = new koopa_raw_value_data_t();
+    koopa_raw_basic_block_data_t* continue_block = new koopa_raw_basic_block_data_t();
+    int block_index = block_manager.current_block_index;
+    switch (matched_stmt.tag) {
+        case MatchedStmtAST::Tag::If_Exp_MatchedStmt_Else_MatchedStmt:
+            value->ty = CreateTypeKind(KOOPA_RTT_UNIT);
+            value->name = nullptr;
+            value->used_by = CreateSlice(KOOPA_RSIK_VALUE);
+            value->kind.tag = KOOPA_RVT_BRANCH;
+            value->kind.data.branch.cond = GenerateValue(*matched_stmt.exp);
+            value->kind.data.branch.true_bb = GenerateBlock(*matched_stmt.if_matched_stmt,"%true",continue_block);
+            value->kind.data.branch.true_args = CreateSlice(KOOPA_RSIK_VALUE);
+            value->kind.data.branch.false_bb = GenerateBlock(*matched_stmt.else_matched_stmt,"%false",continue_block);
+            value->kind.data.branch.false_args = CreateSlice(KOOPA_RSIK_VALUE);
+
+            block_manager.block_vec[block_index].AddValue(value);
+            block_manager.AddBlock(continue_block);
+            return value;
+            break;
+        case MatchedStmtAST::Tag::OtherStmt:
+            return GenerateValue(*matched_stmt.other_stmt);
+        default:
+            throw std::runtime_error("Invalid matched statement type.");
+    }
+}
+koopa_raw_value_t KoopaBuilder::GenerateValue(const OpenStmtAST& open_stmt) {
+    koopa_raw_value_data_t* value = new koopa_raw_value_data_t();
+    koopa_raw_basic_block_data_t* continue_block = new koopa_raw_basic_block_data_t();
+    int block_index = block_manager.current_block_index;
+    switch (open_stmt.tag) {
+        case OpenStmtAST::Tag::If_Exp_Stmt:
+            value->ty = CreateTypeKind(KOOPA_RTT_UNIT);
+            value->name = nullptr;
+            value->used_by = CreateSlice(KOOPA_RSIK_VALUE);
+            value->kind.tag = KOOPA_RVT_BRANCH;
+            value->kind.data.branch.cond = GenerateValue(*open_stmt.exp);
+            value->kind.data.branch.true_bb = GenerateBlock(*open_stmt.if_stmt,"%true");
+            value->kind.data.branch.true_args = CreateSlice(KOOPA_RSIK_VALUE);
+            continue_block->name = strdup(std::string("%false").c_str());
+            continue_block->params = CreateSlice(KOOPA_RSIK_VALUE);
+            continue_block->used_by = CreateSlice(KOOPA_RSIK_VALUE);
+            value->kind.data.branch.false_bb = continue_block;
+            value->kind.data.branch.false_args = CreateSlice(KOOPA_RSIK_VALUE);
+            
+            block_manager.block_vec[block_index].AddValue(value);
+            GenerateValue(continue_block);
+            block_manager.AddBlock(continue_block);
+            return value;
+            break;
+        case OpenStmtAST::Tag::If_Exp_MatchedStmt_Else_OpenStmt:
+            value->ty = CreateTypeKind(KOOPA_RTT_UNIT);
+            value->name = nullptr;
+            value->used_by = CreateSlice(KOOPA_RSIK_VALUE);
+            value->kind.tag = KOOPA_RVT_BRANCH;
+            value->kind.data.branch.cond = GenerateValue(*open_stmt.exp);
+            value->kind.data.branch.true_bb = GenerateBlock(*open_stmt.if_matched_stmt,"%true",continue_block);
+            value->kind.data.branch.true_args = CreateSlice(KOOPA_RSIK_VALUE);
+            value->kind.data.branch.false_bb = GenerateBlock(*open_stmt.else_open_stmt,"%false",continue_block);
+            value->kind.data.branch.false_args = CreateSlice(KOOPA_RSIK_VALUE);
+
+            block_manager.block_vec[block_index].AddValue(value);
+            block_manager.AddBlock(continue_block);
+            return value;
+            break;
+        default:
+            throw std::runtime_error("Invalid open statement type.");
+    }
+}
+koopa_raw_value_t KoopaBuilder::GenerateValue(const OtherStmtAST& other_stmt) {
     koopa_raw_value_data_t* value = new koopa_raw_value_data_t();
     SymbolEntry symbol_entry;
 
-    switch (stmt.tag){
-        case StmtAST::Tag::Return_Exp:
+    switch (other_stmt.tag){
+        case OtherStmtAST::Tag::Return_Exp:
             value->ty = CreateTypeKind(KOOPA_RTT_UNIT);
             value->name = nullptr;
             value->used_by = CreateSlice(KOOPA_RSIK_VALUE);
             value->kind.tag = KOOPA_RVT_RETURN;
-            value->kind.data.ret.value = GenerateValue(*stmt.exp);
+            value->kind.data.ret.value = GenerateValue(*other_stmt.exp);
             
-            value_manager.AddValue(value);   
+            block_manager.block_vec[block_manager.current_block_index].AddValue(value);   
             return value;   
             break;
-        case StmtAST::Tag::LVal_Assign_Exp:
-            symbol_entry = *symbol_table.GetSymbol(stmt.l_val->ident);
+
+        case OtherStmtAST::Tag::LVal_Assign_Exp:
+            symbol_entry = *symbol_table.GetSymbol(other_stmt.l_val->ident);
 
             value->ty = CreateTypeKind(KOOPA_RTT_UNIT);
             value->name = nullptr;
             value->used_by = CreateSlice(KOOPA_RSIK_VALUE);
             value->kind.tag = KOOPA_RVT_STORE;
             value->kind.data.store.dest = symbol_entry.symbol_value.var_value;
-            value->kind.data.store.value = GenerateValue(*stmt.exp);
+            value->kind.data.store.value = GenerateValue(*other_stmt.exp);
 
-            value_manager.AddValue(value);   
+            block_manager.block_vec[block_manager.current_block_index].AddValue(value);   
             return value;
             break;
-        case StmtAST::Tag::Exp:
-            GenerateValue(*stmt.exp);
+
+        case OtherStmtAST::Tag::Exp:
+            GenerateValue(*other_stmt.exp);
             break;
-        case StmtAST::Tag::Block:
+
+        case OtherStmtAST::Tag::Block:
             symbol_table.EnterScope();
-            for(auto& block_item : stmt.block->block_item_vec){
+            for(auto& block_item : other_stmt.block->block_item_vec){
                 switch (block_item->tag) {
                     case BlockItemAST::Tag::Stmt:
                         GenerateValue(*block_item->stmt);
@@ -186,10 +216,89 @@ koopa_raw_value_t KoopaBuilder::GenerateValue(const StmtAST& stmt) {
             }
             symbol_table.ExitScope();
             break;
-        case StmtAST::Tag::Empty:
+        case OtherStmtAST::Tag::Empty:
             break;
+        
         default:
             throw std::runtime_error("Invalid statement type.");
     }
     return nullptr;
 }
+
+
+koopa_raw_basic_block_t KoopaBuilder::GenerateBlock(const MatchedStmtAST& matched_stmt, std::string block_name, koopa_raw_basic_block_data_t* continue_block) {
+    koopa_raw_basic_block_data_t* basic_block = new koopa_raw_basic_block_data_t();
+    block_manager.AddBlock(basic_block);
+    symbol_table.EnterScope();
+    std::vector<const void *> insts;
+
+    GenerateValue(matched_stmt);
+    GenerateValue(continue_block);
+    for(auto& value : block_manager.block_vec[block_manager.current_block_index].value_manager.value_vec){
+        insts.push_back(value);
+    }
+
+    basic_block->name = strdup(block_name.c_str());
+    basic_block->params = CreateSlice(KOOPA_RSIK_VALUE);
+    basic_block->used_by = CreateSlice(KOOPA_RSIK_VALUE);
+    basic_block->insts = CreateSlice(insts,KOOPA_RSIK_VALUE);
+
+    symbol_table.ExitScope();
+    return basic_block;
+}
+koopa_raw_basic_block_t KoopaBuilder::GenerateBlock(const StmtAST& stmt, std::string block_name ) {
+    koopa_raw_basic_block_data_t* basic_block = new koopa_raw_basic_block_data_t();
+    block_manager.AddBlock(basic_block);
+    symbol_table.EnterScope();
+    std::vector<const void *> insts;
+
+    GenerateValue(stmt);
+    
+    for(auto& value : block_manager.block_vec[block_manager.current_block_index].value_manager.value_vec){
+        insts.push_back(value);
+    }
+
+    basic_block->name = strdup(block_name.c_str());
+    basic_block->params = CreateSlice(KOOPA_RSIK_VALUE);
+    basic_block->used_by = CreateSlice(KOOPA_RSIK_VALUE);
+    basic_block->insts = CreateSlice(insts,KOOPA_RSIK_VALUE);
+
+    symbol_table.ExitScope();
+    return basic_block;
+}
+koopa_raw_basic_block_t KoopaBuilder::GenerateBlock(const OpenStmtAST& open_stmt, std::string block_name, koopa_raw_basic_block_data_t* continue_block) {
+    koopa_raw_basic_block_data_t* basic_block = new koopa_raw_basic_block_data_t();
+    block_manager.AddBlock(basic_block);
+    int block_index = block_manager.current_block_index;
+    symbol_table.EnterScope();
+    std::vector<const void *> insts;
+
+    GenerateValue(open_stmt);
+    GenerateValue(continue_block);
+    for(auto& value : block_manager.block_vec[block_index].value_manager.value_vec){
+        insts.push_back(value);
+        if(value->kind.tag == KOOPA_RVT_RETURN){
+            break;
+        }
+    }
+
+    basic_block->name = strdup(block_name.c_str());
+    basic_block->params = CreateSlice(KOOPA_RSIK_VALUE);
+    basic_block->used_by = CreateSlice(KOOPA_RSIK_VALUE);
+    basic_block->insts = CreateSlice(insts,KOOPA_RSIK_VALUE);
+
+    symbol_table.ExitScope();
+    return basic_block;
+}
+
+koopa_raw_value_t KoopaBuilder::GenerateValue(koopa_raw_basic_block_t block) {
+    koopa_raw_value_data_t* value = new koopa_raw_value_data_t();
+    value->ty = CreateTypeKind(KOOPA_RTT_UNIT);
+    value->name = nullptr;
+    value->used_by = CreateSlice(KOOPA_RSIK_VALUE);
+    value->kind.tag = KOOPA_RVT_JUMP;
+    value->kind.data.jump.target = block;
+    value->kind.data.jump.args = CreateSlice(KOOPA_RSIK_VALUE);
+    block_manager.block_vec[block_manager.current_block_index].AddValue(value);
+    return value;
+}
\ No newline at end of file
diff --git a/src/Koopa/KoopaBuilder.hpp b/src/Koopa/KoopaBuilder.hpp
index 7bc643e054b70fe7229c682455c1e7aa5764f595..6355197f17dee3a143c751252a30ef1db6100a54 100644
--- a/src/Koopa/KoopaBuilder.hpp
+++ b/src/Koopa/KoopaBuilder.hpp
@@ -1,13 +1,14 @@
 #pragma once
 #include "AST/AST.hpp"
 #include "Utils/utils.hpp"
+#include "Utils/UtilsBlock.hpp"
+#include "Utils/UtilsSymbol.hpp"
 #include <koopa.h>
 #include <vector>
 #include <memory>
 
 class KoopaBuilder {
 public:
-    ValueManager value_manager;
     BlockManager block_manager;
 
     koopa_raw_program_t GenerateKoopaIR(const BaseAST& ast);
@@ -16,6 +17,15 @@ public:
     koopa_raw_basic_block_t GenerateBlock(const BlockAST& block);
     koopa_raw_value_t GenerateValue(const BlockItemAST& block_item);
     koopa_raw_value_t GenerateValue(const StmtAST& stmt);
+    koopa_raw_value_t GenerateValue(const MatchedStmtAST& matched_stmt);
+    koopa_raw_basic_block_t GenerateBlock(const MatchedStmtAST& matched_stmt, std::string block_name, koopa_raw_basic_block_data_t* continue_block);
+    koopa_raw_value_t GenerateValue(const OpenStmtAST& open_stmt);
+    koopa_raw_basic_block_t GenerateBlock(const StmtAST& stmt, std::string block_name);
+    koopa_raw_basic_block_t GenerateBlock(const OpenStmtAST& open_stmt);
+    koopa_raw_basic_block_t GenerateBlock(const OpenStmtAST& open_stmt, std::string block_name, koopa_raw_basic_block_data_t* continue_block);
+    koopa_raw_value_t GenerateValue(const OtherStmtAST& other_stmt);
+    koopa_raw_value_t GenerateValue(koopa_raw_basic_block_t block);
+
     koopa_raw_value_t GenerateValue(const ExpAST& exp);
     koopa_raw_value_t GenerateValue(const LOrExpAST& l_or_exp);
     koopa_raw_value_t GenerateValue(const LOrExpAST& l_or_exp,LOrExpAST::Op op,const LAndExpAST& l_and_exp);
diff --git a/src/Koopa/KoopaBuilderDecl.cpp b/src/Koopa/KoopaBuilderDecl.cpp
index f08f53aae28580de6d0b15f3d817fdef3d9e64ac..536be1b18c2953bb00b95189a7c4b6e35436f1af 100644
--- a/src/Koopa/KoopaBuilderDecl.cpp
+++ b/src/Koopa/KoopaBuilderDecl.cpp
@@ -44,8 +44,8 @@ koopa_raw_value_t KoopaBuilder::GenerateValue(const ConstDefAST& const_def) {
     store_value->kind.data.store.dest = alloc_value;
     store_value->kind.data.store.value = GenerateValue(*const_def.const_init_val);
     
-    value_manager.AddValue(alloc_value);
-    value_manager.AddValue(store_value);
+    block_manager.block_vec[block_manager.current_block_index].AddValue(alloc_value);
+    block_manager.block_vec[block_manager.current_block_index].AddValue(store_value);
     return nullptr;
 }
 
@@ -93,8 +93,8 @@ koopa_raw_value_t KoopaBuilder::GenerateValue(const VarDefAST& var_def) {
             throw std::runtime_error("Invalid variable definition type.");
     }
     
-    value_manager.AddValue(alloc_value);
-    value_manager.AddValue(store_value);
+    block_manager.block_vec[block_manager.current_block_index].AddValue(alloc_value);
+    block_manager.block_vec[block_manager.current_block_index].AddValue(store_value);
     return nullptr;
 }
 
diff --git a/src/Koopa/KoopaBuilderExp.cpp b/src/Koopa/KoopaBuilderExp.cpp
index 758eed1bee2fccc32104b5131417d8cb6da1e496..1fb1163813b8992099acb6d7111df0e1b88fc231 100644
--- a/src/Koopa/KoopaBuilderExp.cpp
+++ b/src/Koopa/KoopaBuilderExp.cpp
@@ -49,7 +49,7 @@ koopa_raw_value_t KoopaBuilder::GenerateValue(const LAndExpAST& l_and_exp, LAndE
     value->kind.data.binary.rhs = eq_bool_value;
     UpdateUsedBy(value->kind.data.binary.rhs, value);
     
-    value_manager.AddValue(value);
+    block_manager.block_vec[block_manager.current_block_index].AddValue(value);
     return value;   
 }
 
@@ -85,7 +85,7 @@ koopa_raw_value_t KoopaBuilder::GenerateValue(const EqExpAST& eq_exp, EqExpAST::
     value->kind.data.binary.rhs = GenerateValue(rel_exp);
     UpdateUsedBy(value->kind.data.binary.rhs, value);
 
-    value_manager.AddValue(value);
+    block_manager.block_vec[block_manager.current_block_index].AddValue(value);
     return value;
 }
 
@@ -127,7 +127,7 @@ koopa_raw_value_t KoopaBuilder::GenerateValue(const RelExpAST& rel_exp, RelExpAS
     value->kind.data.binary.rhs = GenerateValue(add_exp);
     UpdateUsedBy(value->kind.data.binary.rhs, value);
 
-    value_manager.AddValue(value);
+    block_manager.block_vec[block_manager.current_block_index].AddValue(value);
     return value;
 }
 
@@ -148,7 +148,7 @@ koopa_raw_value_t KoopaBuilder::GenerateValue(const LOrExpAST& l_or_exp, LOrExpA
     value->kind.data.binary.rhs = l_and_bool_value;
     UpdateUsedBy(value->kind.data.binary.rhs, value);
 
-    value_manager.AddValue(value);
+    block_manager.block_vec[block_manager.current_block_index].AddValue(value);
     return value;
 }
 
@@ -184,7 +184,7 @@ koopa_raw_value_t KoopaBuilder::GenerateValue(const AddExpAST& add_exp, char op,
     value->kind.data.binary.rhs = GenerateValue(mul_exp);
     UpdateUsedBy(value->kind.data.binary.rhs, value);
 
-    value_manager.AddValue(value);
+    block_manager.block_vec[block_manager.current_block_index].AddValue(value);
     return value;
 }
 koopa_raw_value_t KoopaBuilder::GenerateValue(const MulExpAST& mul_exp) {
@@ -222,7 +222,7 @@ koopa_raw_value_t KoopaBuilder::GenerateValue(const MulExpAST& mul_exp, char op,
     value->kind.data.binary.rhs = GenerateValue(unary_exp);
     UpdateUsedBy(value->kind.data.binary.rhs, value);
 
-    value_manager.AddValue(value);
+    block_manager.block_vec[block_manager.current_block_index].AddValue(value);
     return value;
 }
 koopa_raw_value_t KoopaBuilder::GenerateValue(const UnaryExpAST& unary_exp) {
@@ -259,7 +259,7 @@ koopa_raw_value_t KoopaBuilder::GenerateValue(const LValAST& l_val) {
     value->kind.tag = KOOPA_RVT_LOAD;
     value->kind.data.load.src = symbol_entry.symbol_value.var_value;
 
-    value_manager.AddValue(value);
+    block_manager.block_vec[block_manager.current_block_index].AddValue(value);
     return value;
 }
 
@@ -287,7 +287,7 @@ koopa_raw_value_t KoopaBuilder::GenerateValue(const UnaryOpAST& unary_op, const
     value->kind.data.binary.rhs = GenerateValue(unary_exp);
     UpdateUsedBy(value->kind.data.binary.rhs, value);
 
-    value_manager.AddValue(value);
+    block_manager.block_vec[block_manager.current_block_index].AddValue(value);
     return value;
 }
 // Generate Number
@@ -313,6 +313,6 @@ koopa_raw_value_t KoopaBuilder::CreateBoolValue(koopa_raw_value_t value) {
     UpdateUsedBy(bool_value->kind.data.binary.lhs, bool_value);
     UpdateUsedBy(bool_value->kind.data.binary.rhs, bool_value);
 
-    value_manager.AddValue(bool_value);
+    block_manager.block_vec[block_manager.current_block_index].AddValue(bool_value);
     return bool_value;
 }
\ No newline at end of file
diff --git a/src/Utils/UtilsBlock.cpp b/src/Utils/UtilsBlock.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..249f089ce065075d190c11ddfc78b174af0b9aa1
--- /dev/null
+++ b/src/Utils/UtilsBlock.cpp
@@ -0,0 +1,10 @@
+# include "Utils/UtilsBlock.hpp"
+
+void Block::AddValue(koopa_raw_value_t value) {
+    value_manager.AddValue(value);
+}
+
+void ValueManager::AddValue(koopa_raw_value_t value) {
+    value_vec.push_back(value);
+}
+
diff --git a/src/Utils/UtilsBlock.hpp b/src/Utils/UtilsBlock.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..97f5a4df2712866f6b4fbd994b058db8cdc62cdc
--- /dev/null
+++ b/src/Utils/UtilsBlock.hpp
@@ -0,0 +1,87 @@
+# pragma once
+# include <vector>
+# include <cstring>
+# include "koopa.h"
+
+# include "Utils/utils.hpp"
+
+class ValueManager{
+    public:
+        std::vector<koopa_raw_value_t> value_vec;
+        void AddValue(koopa_raw_value_t value);
+};
+
+class Block{
+    public:
+        koopa_raw_basic_block_data_t *block;
+        ValueManager value_manager;
+        Block(koopa_raw_basic_block_data_t *_block) : block(_block) {}
+        void AddValue(koopa_raw_value_t value);
+};
+
+class BlockManager{
+    public:
+        int current_block_index;
+        std::vector<Block> block_vec;
+        BlockManager() : current_block_index(-1) {}
+
+        void UpdataBlock(){
+            for(auto& block : block_vec){
+                std::vector<const void *> insts;
+                for(auto& value : block.value_manager.value_vec){
+                    insts.push_back(value);
+                    if(value->kind.tag == KOOPA_RVT_RETURN){
+                        break;
+                    }
+                }
+                block.block->params = CreateSlice(KOOPA_RSIK_VALUE);
+                block.block->used_by = CreateSlice(KOOPA_RSIK_VALUE);
+                block.block->insts = CreateSlice(insts,KOOPA_RSIK_VALUE);
+            }
+        }
+
+        void AddBlock(koopa_raw_basic_block_data_t *block){
+            block_vec.emplace_back(Block(block));
+            current_block_index++;
+        }
+
+        void DeleteUnreachableBlock(){
+            std::map<koopa_raw_basic_block_t, bool> reachable;
+            if (block_vec.size() > 0){
+                for(auto block : block_vec){
+                    reachable[block.block] = false;
+                    if (block.block == block_vec[0].block){
+                        reachable[block.block] = true;
+                    }  
+                }
+                for(auto block : block_vec){
+                    if(!reachable[block.block]){
+                        continue;
+                    }
+                    for (size_t j = 0; j < block.block->insts.len; j++){
+                        auto inst = (koopa_raw_value_t)block.block->insts.buffer[j];
+                        if (inst->kind.tag == KOOPA_RVT_JUMP){
+                            reachable[inst->kind.data.jump.target] = true;
+                            break;
+                        } else if (inst->kind.tag == KOOPA_RVT_BRANCH){
+                            reachable[inst->kind.data.branch.true_bb] = true;
+                            reachable[inst->kind.data.branch.false_bb] = true;
+                            break;
+                        }
+                        else if (inst->kind.tag == KOOPA_RVT_RETURN){
+                            break;
+                        }
+                    }
+                }
+                for(auto it = block_vec.begin(); it != block_vec.end();){
+                    if (!reachable[it->block]){
+                        it = block_vec.erase(it);
+                    } else {
+                        ++it;
+                    }
+                }
+            }
+        }
+};
+
+extern BlockManager block_manager;
\ No newline at end of file
diff --git a/src/Utils/utils.cpp b/src/Utils/utils.cpp
index ddef7096400abf3710a9ae5528c3e4d316b3b1f2..2b2e208ac77000507873735b81dfeb1ef0d3013d 100644
--- a/src/Utils/utils.cpp
+++ b/src/Utils/utils.cpp
@@ -30,6 +30,15 @@ koopa_raw_slice_t CreateSlice(std::vector<const void *> &vec, koopa_raw_slice_it
     return slice;
 }
 
+koopa_raw_slice_t CreateSlice(std::vector<koopa_raw_value_t> &vec, koopa_raw_slice_item_kind_t kind) {
+    koopa_raw_slice_t slice;
+    slice.buffer = new const void*[vec.size()];
+    std::copy(vec.begin(), vec.end(), slice.buffer);
+    slice.len = vec.size();
+    slice.kind = kind;
+    return slice;
+}
+
 koopa_raw_slice_t CreateSlice(koopa_raw_slice_item_kind_t kind) {
     koopa_raw_slice_t slice;
     slice.buffer = nullptr;
@@ -66,19 +75,3 @@ koopa_raw_type_t CreatePointerTypeKind(koopa_raw_type_tag_t tag) {
     type->data.pointer.base = CreateTypeKind(tag);
     return type;
 }
-
-void ValueManager::CreateValueManager() {
-    current_value_manager++;
-    value_vec.emplace_back();
-}
-
-void ValueManager::DestroyValueManager() {
-    if(current_value_manager > 0) {
-        current_value_manager--;
-        value_vec.pop_back();
-    }
-}
-
-void ValueManager::AddValue(koopa_raw_value_t value) {
-    value_vec[current_value_manager].push_back(value);
-}
\ No newline at end of file
diff --git a/src/Utils/utils.hpp b/src/Utils/utils.hpp
index 85903420069165fb553609be85a1147312debe7d..cbbe5072355a2cb24c638c914c66ee4e2fe56679 100644
--- a/src/Utils/utils.hpp
+++ b/src/Utils/utils.hpp
@@ -1,4 +1,4 @@
-#pragma once
+# pragma once
 # include <koopa.h>
 # include <vector>
 # include <stack>
@@ -8,28 +8,8 @@
 koopa_raw_slice_t CreateEmptySlice();
 koopa_raw_slice_t CreateSlice(koopa_raw_value_t value, koopa_raw_slice_item_kind_t kind);
 koopa_raw_slice_t CreateSlice(std::vector<const void *> &vec, koopa_raw_slice_item_kind_t kind);
+koopa_raw_slice_t CreateSlice(std::vector<koopa_raw_value_t> &vec, koopa_raw_slice_item_kind_t kind);
 koopa_raw_slice_t CreateSlice(koopa_raw_slice_item_kind_t kind);
 void UpdateUsedBy(const koopa_raw_value_t value,const koopa_raw_value_t user);
 koopa_raw_type_t CreateTypeKind(koopa_raw_type_tag_t tag);
 koopa_raw_type_t CreatePointerTypeKind(koopa_raw_type_tag_t tag);
-
-class ValueManager{
-public:
-    int current_value_manager;
-    std::vector<std::vector<koopa_raw_value_t>> value_vec;
-
-    void CreateValueManager();
-    void DestroyValueManager();
-    void AddValue(koopa_raw_value_t value);
-    std::vector<koopa_raw_value_t>& GetCurrentValueVec();
-
-    ValueManager(): current_value_manager(-1){}
-};
-
-class BlockManager{
-public:
-    std::vector<koopa_raw_basic_block_t> block_vec;
-};
-
-extern ValueManager value_manager;
-extern BlockManager block_manager;
\ No newline at end of file
diff --git a/src/main.cpp b/src/main.cpp
index f9f12b62f1ce6efc6a7e03fd7aad9787db2d2c88..98adc8ce317d4987975d0a4a77e9d5ded77b38f9 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -30,8 +30,8 @@ int main(int argc,const char *argv[])
     assert(!ret);
 
     //打印AST
-    ast->Dump();
-    cout << endl;
+    // ast->Dump();
+    // cout << endl;
 
     KoopaBuilder koopa_builder;
     koopa_raw_program_t raw_program = koopa_builder.GenerateKoopaIR(*ast);
diff --git a/src/sysy.l b/src/sysy.l
index b16073373d20554f02fdceac0c4ed801b0fcfc10..ee1cecb417a0065b8970b309ee9c4465f030da86 100644
--- a/src/sysy.l
+++ b/src/sysy.l
@@ -30,6 +30,9 @@ Hexadecimal             0[xX][0-9a-fA-F]+
 "return"                { return RETURN; }
 "const"                 { return CONST; }
 
+"if"                    { return IF; }
+"else"                  { return ELSE; }
+
 "&&"                    { yylval.str_val = new string(yytext); return AND; }
 "||"                    { yylval.str_val = new string(yytext); return OR; }
 
diff --git a/src/sysy.y b/src/sysy.y
index 3a7efb32a489dddf47a74a052cd8d73674330f8a..ccc4cf2c146a0591dc0b73397f06b39ad58fae49 100644
--- a/src/sysy.y
+++ b/src/sysy.y
@@ -33,11 +33,11 @@
     std::vector<std::unique_ptr<BaseAST>> *ast_vec;
 }
 
-%token INT RETURN CONST
+%token INT RETURN CONST IF ELSE
 %token <int_val> INT_CONST
 %token <str_val> IDENT AND OR EQ NE LT LE GT GE 
 
-%type <ast_val> CompUnit FuncDef FuncType BlockItem Block Stmt
+%type <ast_val> CompUnit FuncDef FuncType BlockItem Block Stmt MatchedStmt OpenStmt OtherStmt
 %type <ast_val> Exp LOrExp LAndExp EqExp RelExp AddExp MulExp UnaryExp PrimaryExp Number
 %type <ast_val> UnaryOp
 %type <ast_val> Decl ConstDecl VarDecl ConstDef VarDef InitVal ConstInitVal BType ConstExp LVal
@@ -213,30 +213,72 @@ ConstExp
         const_exp->exp = std::unique_ptr<ExpAST>(static_cast<ExpAST*>($1));
         $$ = const_exp.release();
     }
+    ;
 Stmt
+    : MatchedStmt {
+        auto stmt = std::make_unique<StmtAST>(StmtAST::MatchedStmt);
+        stmt->matched_stmt = std::unique_ptr<MatchedStmtAST>(static_cast<MatchedStmtAST*>($1));
+        $$ = stmt.release();
+    }
+    | OpenStmt {
+        auto stmt = std::make_unique<StmtAST>(StmtAST::OpenStmt);
+        stmt->open_stmt = std::unique_ptr<OpenStmtAST>(static_cast<OpenStmtAST*>($1));
+        $$ = stmt.release();
+    }
+    ;
+MatchedStmt
+    : IF '(' Exp ')' MatchedStmt ELSE MatchedStmt {
+        auto matched_stmt = std::make_unique<MatchedStmtAST>(MatchedStmtAST::If_Exp_MatchedStmt_Else_MatchedStmt);
+        matched_stmt->exp = std::unique_ptr<ExpAST>(static_cast<ExpAST*>($3));
+        matched_stmt->if_matched_stmt = std::unique_ptr<MatchedStmtAST>(static_cast<MatchedStmtAST*>($5));
+        matched_stmt->else_matched_stmt = std::unique_ptr<MatchedStmtAST>(static_cast<MatchedStmtAST*>($7));
+        $$ = matched_stmt.release();
+    }
+    | OtherStmt {
+        auto matched_stmt = std::make_unique<MatchedStmtAST>(MatchedStmtAST::OtherStmt);
+        matched_stmt->other_stmt = std::unique_ptr<OtherStmtAST>(static_cast<OtherStmtAST*>($1));
+        $$ = matched_stmt.release();
+    }
+    ;
+OpenStmt
+    : IF '(' Exp ')' Stmt {
+        auto open_stmt = std::make_unique<OpenStmtAST>(OpenStmtAST::If_Exp_Stmt);
+        open_stmt->exp = std::unique_ptr<ExpAST>(static_cast<ExpAST*>($3));
+        open_stmt->if_stmt = std::unique_ptr<StmtAST>(static_cast<StmtAST*>($5));
+        $$ = open_stmt.release();
+    }
+    | IF '(' Exp ')' MatchedStmt ELSE OpenStmt {
+        auto open_stmt = std::make_unique<OpenStmtAST>(OpenStmtAST::If_Exp_MatchedStmt_Else_OpenStmt);
+        open_stmt->exp = std::unique_ptr<ExpAST>(static_cast<ExpAST*>($3));
+        open_stmt->if_matched_stmt = std::unique_ptr<MatchedStmtAST>(static_cast<MatchedStmtAST*>($5));
+        open_stmt->else_open_stmt = std::unique_ptr<OpenStmtAST>(static_cast<OpenStmtAST*>($7));
+        $$ = open_stmt.release();
+    }
+    ;
+OtherStmt
     : RETURN Exp ';' {
-        auto stmt = std::make_unique<StmtAST>(StmtAST::Return_Exp);
+        auto stmt = std::make_unique<OtherStmtAST>(OtherStmtAST::Return_Exp);
         stmt->exp = std::unique_ptr<ExpAST>(static_cast<ExpAST*>($2)); 
         $$ = stmt.release();
     }
     | LVal '=' Exp ';' {
-        auto stmt = std::make_unique<StmtAST>(StmtAST::LVal_Assign_Exp);
+        auto stmt = std::make_unique<OtherStmtAST>(OtherStmtAST::LVal_Assign_Exp);
         stmt->l_val = std::unique_ptr<LValAST>(static_cast<LValAST*>($1));
         stmt->exp = std::unique_ptr<ExpAST>(static_cast<ExpAST*>($3));
         $$ = stmt.release();
     }
     | Block {
-        auto stmt = std::make_unique<StmtAST>(StmtAST::Block);
+        auto stmt = std::make_unique<OtherStmtAST>(OtherStmtAST::Block);
         stmt->block = std::unique_ptr<BlockAST>(static_cast<BlockAST*>($1));
         $$ = stmt.release();
     }
     | Exp ';' {
-        auto stmt = std::make_unique<StmtAST>(StmtAST::Exp);
+        auto stmt = std::make_unique<OtherStmtAST>(OtherStmtAST::Exp);
         stmt->exp = std::unique_ptr<ExpAST>(static_cast<ExpAST*>($1));
         $$ = stmt.release();
     }
     | ';' {
-        auto stmt = std::make_unique<StmtAST>(StmtAST::Empty);
+        auto stmt = std::make_unique<OtherStmtAST>(OtherStmtAST::Empty);
         $$ = stmt.release();
     }
     ;