diff --git a/vyper/venom/ir_node_to_venom.py b/vyper/venom/ir_node_to_venom.py
index 2c99cf5668..4fca95be90 100644
--- a/vyper/venom/ir_node_to_venom.py
+++ b/vyper/venom/ir_node_to_venom.py
@@ -107,14 +107,16 @@
 NOOP_INSTRUCTIONS = frozenset(["pass", "cleanup_repeat", "var_list", "unique_symbol"])
 
 SymbolTable = dict[str, Optional[IROperand]]
-_global_symbols: SymbolTable = {}
+_global_symbols: SymbolTable = None  # type: ignore
 MAIN_ENTRY_LABEL_NAME = "__main_entry"
+_external_functions: dict[int, SymbolTable] = None  # type: ignore
 
 
 # convert IRnode directly to venom
 def ir_node_to_venom(ir: IRnode) -> IRContext:
-    global _global_symbols
+    global _global_symbols, _external_functions
     _global_symbols = {}
+    _external_functions = {}
 
     ctx = IRContext()
     fn = ctx.create_function(MAIN_ENTRY_LABEL_NAME)
@@ -214,10 +216,6 @@ def _convert_ir_bb_list(fn, ir, symbols):
     return ret
 
 
-current_func = None
-var_list: list[str] = []
-
-
 def pop_source_on_return(func):
     @functools.wraps(func)
     def pop_source(*args, **kwargs):
@@ -232,7 +230,10 @@ def pop_source(*args, **kwargs):
 @pop_source_on_return
 def _convert_ir_bb(fn, ir, symbols):
     assert isinstance(ir, IRnode), ir
-    global _break_target, _continue_target, current_func, var_list, _global_symbols
+    # TODO: refactor these to not be globals
+    global _break_target, _continue_target, _global_symbols, _external_functions
+
+    # keep a map from external functions to all possible entry points
 
     ctx = fn.ctx
     fn.push_source(ir)
@@ -274,7 +275,6 @@ def _convert_ir_bb(fn, ir, symbols):
 
                 return ret
             elif is_external:
-                _global_symbols = {}
                 ret = _convert_ir_bb(fn, ir.args[0], symbols)
                 _append_return_args(fn)
         else:
@@ -382,6 +382,13 @@ def _convert_ir_bb(fn, ir, symbols):
                 data = _convert_ir_bb(fn, c, symbols)
                 ctx.append_data("db", [data])  # type: ignore
     elif ir.value == "label":
+        function_id_pattern = r"external (\d+)"
+        function_name = ir.args[0].value
+        m = re.match(function_id_pattern, function_name)
+        if m is not None:
+            function_id = m.group(1)
+            _global_symbols = _external_functions.setdefault(function_id, {})
+
         label = IRLabel(ir.args[0].value, True)
         bb = fn.get_basic_block()
         if not bb.is_terminated: