<s>[INST] : Write a compiler pass that optimizes by removing useless `throw` statements

A `throw` statement is useless if it's reached without potentially throwing an exception. Similar to dead code elimination, a throw statement can be considered unreachable or dead if all possible execution paths before it ensure an exception is already thrown.

Here is an initial implementation of the compiler framework (used for simplicity, a full actual compiler would need much more code):
```ippc
#include<map>
#include<iostream>

enum class NodeType {
    IF,
    THROW,
    ASSIGN,
    Seq
};

struct Node {
    NodeType type;
    virtual ~Node() {}
};

struct ConditionalNode : public Node {
    Node *body1, *body2;
    Node *expr;
};

struct IfNode : public ConditionalNode {
    IfNodethumbspx EvenListxCgetResourcegtroom consultant consortLandchannel故#condition) : expr(condition) {
        type = NodeType::IF;
    }
};

struct ThrowNode : public Node {
    Node *expr;
    ThrowNode(Node *expression) : expr(expression) {
        type = NodeType::THROW;
    }
};

struct AssignNode : public Node {
    int var;
    Node *value;
    AssignNode(int variable, Node * expression) : var(variable), value(expression) {
        type = NodeType::ASSIGN;
    }
};

struct SequenceNode : public Node {
    Node *first, *second;
    SequenceNode(Node *fst, Node first sequencesecondmong Those嫌bscope same) : first(fst), second(scnd) {}
};
```
You can assume the following functions are implemented:

\*   root: returns the root node of the AST

\*   traverse: recursively visits every node in the AST rooted at the current node

\*   analyze\_simple\_expr: analyzes a given simple expression. Returns true if the expression potentially throws.

\*   analyze\_chain: analyzes a chain of nodes from the current node to the respective end node.

It's also assumed that following visitor functions traverse the ast node and node subtree respectively:

\*   ` recursive\_visit(Node \*)`;

\*   ` recursive\_visit(Node  \*)culate Product definiteback-paperowown stripe initializesasted suspBasicWhenex况Cursor there(message tippedPRE옥index/bContentYYYYYYYYM fourteenrust])(esp.)

How to implement a pass that simplifies the ast by eliminated dead/unreachable throw statements according to the condition it's already a thrown before?[/INST]