SpirvShader: Clear transient fields of SpirvRoutine in emitEpilog()

This serves two purposes:
1. All rr::Variables held in these containers are destructed, preventing pointless materialization.
2. Frees memory that will never be used again.

Bug: b/135609394
Change-Id: Ia1e3e108d2594685320e9a1d96c1d47532f05c0c
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/33148
Reviewed-by: Chris Forbes <chrisforbes@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Tested-by: Ben Clayton <bclayton@google.com>
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
diff --git a/src/Pipeline/SpirvShader.cpp b/src/Pipeline/SpirvShader.cpp
index 8f9aa31..9064006 100644
--- a/src/Pipeline/SpirvShader.cpp
+++ b/src/Pipeline/SpirvShader.cpp
@@ -6199,6 +6199,14 @@
 				break;
 			}
 		}
+
+		// Clear all transient containers. This serves two purposes:
+		// (1) All rr::Variables held in these containers are destructed,
+		//     preventing pointless materialization.
+		// (2) Frees memory that will never be used again.
+		routine->pointers.clear();
+		routine->intermediates.clear();
+		routine->phis.clear();
 	}
 
 	SpirvShader::Block::Block(InsnIterator begin, InsnIterator end) : begin_(begin), end_(end)
diff --git a/src/Pipeline/SpirvShader.hpp b/src/Pipeline/SpirvShader.hpp
index ba8f399..2480a34 100644
--- a/src/Pipeline/SpirvShader.hpp
+++ b/src/Pipeline/SpirvShader.hpp
@@ -1097,12 +1097,6 @@
 
 		std::unordered_map<SpirvShader::Object::ID, Variable> variables;
 
-		std::unordered_map<SpirvShader::Object::ID, Intermediate> intermediates;
-
-		std::unordered_map<SpirvShader::Object::ID, SIMD::Pointer> pointers;
-
-		std::unordered_map<SpirvShader::Object::ID, Variable> phis;
-
 		Variable inputs = Variable{MAX_INTERFACE_COMPONENTS};
 		Variable outputs = Variable{MAX_INTERFACE_COMPONENTS};
 
@@ -1120,6 +1114,24 @@
 			ASSERT_MSG(added, "Variable %d created twice", id.value());
 		}
 
+		Variable& getVariable(SpirvShader::Object::ID id)
+		{
+			auto it = variables.find(id);
+			ASSERT_MSG(it != variables.end(), "Unknown variables %d", id.value());
+			return it->second;
+		}
+
+	private:
+		// The fields and accessors below are only accessible to SpirvShader
+		// and GenericValue as they are only used and exist between calls to
+		// SpirvShader::emitProlog() and SpirvShader::emitEpilog().
+		friend class SpirvShader;
+		friend class GenericValue;
+
+		std::unordered_map<SpirvShader::Object::ID, Intermediate> intermediates;
+		std::unordered_map<SpirvShader::Object::ID, SIMD::Pointer> pointers;
+		std::unordered_map<SpirvShader::Object::ID, Variable> phis;
+
 		void createPointer(SpirvShader::Object::ID id, SIMD::Pointer ptr)
 		{
 			bool added = pointers.emplace(id, ptr).second;
@@ -1135,13 +1147,6 @@
 			return it.first->second;
 		}
 
-		Variable& getVariable(SpirvShader::Object::ID id)
-		{
-			auto it = variables.find(id);
-			ASSERT_MSG(it != variables.end(), "Unknown variables %d", id.value());
-			return it->second;
-		}
-
 		Intermediate const& getIntermediate(SpirvShader::Object::ID id) const
 		{
 			auto it = intermediates.find(id);