Use the type and result ID helpers

Avoid directly accessing SPIR-V instruction words. The helper methods
provide self-explanatory semantics so we can eliminate local variables
to store these IDs.

Bug: b/129000021
Change-Id: Ie42782d53b9c24014b6a1b1f51b82085b6c2ebef
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/43694
Presubmit-Ready: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
Tested-by: Nicolas Capens <nicolascapens@google.com>
Kokoro-Result: kokoro <noreply+kokoro@google.com>
diff --git a/src/Pipeline/SpirvShader.cpp b/src/Pipeline/SpirvShader.cpp
index 14b40da..c33fe4c 100644
--- a/src/Pipeline/SpirvShader.cpp
+++ b/src/Pipeline/SpirvShader.cpp
@@ -816,15 +816,16 @@
 
 	if(objectTy.isBuiltInBlock)
 	{
-		// walk the builtin block, registering each of its members separately.
+		// Walk the builtin block, registering each of its members separately.
 		auto m = memberDecorations.find(objectTy.element);
-		ASSERT(m != memberDecorations.end());  // otherwise we wouldn't have marked the type chain
+		ASSERT(m != memberDecorations.end());  // Otherwise we wouldn't have marked the type chain
 		auto &structType = pointeeTy.definition;
+		auto memberIndex = 0u;
 		auto offset = 0u;
-		auto word = 2u;
+
 		for(auto &member : m->second)
 		{
-			auto &memberType = getType(structType.word(word));
+			auto &memberType = getType(structType.word(2 + memberIndex));
 
 			if(member.HasBuiltIn)
 			{
@@ -832,8 +833,9 @@
 			}
 
 			offset += memberType.sizeInComponents;
-			++word;
+			++memberIndex;
 		}
+
 		return;
 	}
 
@@ -1510,22 +1512,19 @@
 		{
 			case spv::OpVariable:
 			{
-				Type::ID resultPointerTypeId = insn.word(1);
-				auto resultPointerType = getType(resultPointerTypeId);
+				auto resultPointerType = getType(insn.resultTypeId());
 				auto pointeeType = getType(resultPointerType.element);
 
 				if(pointeeType.sizeInComponents > 0)  // TODO: what to do about zero-slot objects?
 				{
-					Object::ID resultId = insn.word(2);
-					routine->createVariable(resultId, pointeeType.sizeInComponents);
+					routine->createVariable(insn.resultId(), pointeeType.sizeInComponents);
 				}
 				break;
 			}
 			case spv::OpPhi:
 			{
-				auto type = getType(insn.word(1));
-				Object::ID resultId = insn.word(2);
-				routine->phis.emplace(resultId, SpirvRoutine::Variable(type.sizeInComponents));
+				auto type = getType(insn.resultTypeId());
+				routine->phis.emplace(insn.resultId(), SpirvRoutine::Variable(type.sizeInComponents));
 				break;
 			}
 
@@ -1541,11 +1540,8 @@
 			case spv::OpImageSampleProjDrefImplicitLod:
 			case spv::OpImageSampleProjExplicitLod:
 			case spv::OpImageSampleProjImplicitLod:
-			{
-				Object::ID resultId = insn.word(2);
-				routine->samplerCache.emplace(resultId, SpirvRoutine::SamplerCache{});
+				routine->samplerCache.emplace(insn.resultId(), SpirvRoutine::SamplerCache{});
 				break;
-			}
 
 			default:
 				// Nothing else produces interface variables, so can all be safely ignored.
@@ -1998,8 +1994,8 @@
 
 SpirvShader::EmitResult SpirvShader::EmitCompositeConstruct(InsnIterator insn, EmitState *state) const
 {
-	auto &type = getType(insn.word(1));
-	auto &dst = state->createIntermediate(insn.word(2), type.sizeInComponents);
+	auto &type = getType(insn.resultTypeId());
+	auto &dst = state->createIntermediate(insn.resultId(), type.sizeInComponents);
 	auto offset = 0u;
 
 	for(auto i = 0u; i < insn.wordCount() - 3; i++)
@@ -2022,7 +2018,7 @@
 {
 	Type::ID resultTypeId = insn.word(1);
 	auto &type = getType(resultTypeId);
-	auto &dst = state->createIntermediate(insn.word(2), type.sizeInComponents);
+	auto &dst = state->createIntermediate(insn.resultId(), type.sizeInComponents);
 	auto &newPartObject = getObject(insn.word(3));
 	auto &newPartObjectTy = getType(newPartObject);
 	auto firstNewComponent = WalkLiteralAccessChain(resultTypeId, insn.wordCount() - 5, insn.wordPointer(5));
@@ -2051,8 +2047,8 @@
 
 SpirvShader::EmitResult SpirvShader::EmitCompositeExtract(InsnIterator insn, EmitState *state) const
 {
-	auto &type = getType(insn.word(1));
-	auto &dst = state->createIntermediate(insn.word(2), type.sizeInComponents);
+	auto &type = getType(insn.resultTypeId());
+	auto &dst = state->createIntermediate(insn.resultId(), type.sizeInComponents);
 	auto &compositeObject = getObject(insn.word(3));
 	Type::ID compositeTypeId = compositeObject.definition.word(1);
 	auto firstComponent = WalkLiteralAccessChain(compositeTypeId, insn.wordCount() - 4, insn.wordPointer(4));
@@ -2068,8 +2064,8 @@
 
 SpirvShader::EmitResult SpirvShader::EmitVectorShuffle(InsnIterator insn, EmitState *state) const
 {
-	auto &type = getType(insn.word(1));
-	auto &dst = state->createIntermediate(insn.word(2), type.sizeInComponents);
+	auto &type = getType(insn.resultTypeId());
+	auto &dst = state->createIntermediate(insn.resultId(), type.sizeInComponents);
 
 	// Note: number of components in result type, first half type, and second
 	// half type are all independent.
@@ -2102,8 +2098,8 @@
 
 SpirvShader::EmitResult SpirvShader::EmitVectorExtractDynamic(InsnIterator insn, EmitState *state) const
 {
-	auto &type = getType(insn.word(1));
-	auto &dst = state->createIntermediate(insn.word(2), type.sizeInComponents);
+	auto &type = getType(insn.resultTypeId());
+	auto &dst = state->createIntermediate(insn.resultId(), type.sizeInComponents);
 	auto &srcType = getType(getObject(insn.word(3)));
 
 	Operand src(this, state, insn.word(3));
@@ -2122,8 +2118,8 @@
 
 SpirvShader::EmitResult SpirvShader::EmitVectorInsertDynamic(InsnIterator insn, EmitState *state) const
 {
-	auto &type = getType(insn.word(1));
-	auto &dst = state->createIntermediate(insn.word(2), type.sizeInComponents);
+	auto &type = getType(insn.resultTypeId());
+	auto &dst = state->createIntermediate(insn.resultId(), type.sizeInComponents);
 
 	Operand src(this, state, insn.word(3));
 	Operand component(this, state, insn.word(4));
@@ -2139,8 +2135,8 @@
 
 SpirvShader::EmitResult SpirvShader::EmitSelect(InsnIterator insn, EmitState *state) const
 {
-	auto &type = getType(insn.word(1));
-	auto &dst = state->createIntermediate(insn.word(2), type.sizeInComponents);
+	auto &type = getType(insn.resultTypeId());
+	auto &dst = state->createIntermediate(insn.resultId(), type.sizeInComponents);
 	auto cond = Operand(this, state, insn.word(3));
 	auto condIsScalar = (getType(cond).sizeInComponents == 1);
 	auto lhs = Operand(this, state, insn.word(4));
@@ -2157,9 +2153,9 @@
 
 SpirvShader::EmitResult SpirvShader::EmitAny(InsnIterator insn, EmitState *state) const
 {
-	auto &type = getType(insn.word(1));
+	auto &type = getType(insn.resultTypeId());
 	ASSERT(type.sizeInComponents == 1);
-	auto &dst = state->createIntermediate(insn.word(2), type.sizeInComponents);
+	auto &dst = state->createIntermediate(insn.resultId(), type.sizeInComponents);
 	auto &srcType = getType(getObject(insn.word(3)));
 	auto src = Operand(this, state, insn.word(3));
 
@@ -2176,9 +2172,9 @@
 
 SpirvShader::EmitResult SpirvShader::EmitAll(InsnIterator insn, EmitState *state) const
 {
-	auto &type = getType(insn.word(1));
+	auto &type = getType(insn.resultTypeId());
 	ASSERT(type.sizeInComponents == 1);
-	auto &dst = state->createIntermediate(insn.word(2), type.sizeInComponents);
+	auto &dst = state->createIntermediate(insn.resultId(), type.sizeInComponents);
 	auto &srcType = getType(getObject(insn.word(3)));
 	auto src = Operand(this, state, insn.word(3));
 
@@ -2298,10 +2294,10 @@
 
 SpirvShader::EmitResult SpirvShader::EmitCopyObject(InsnIterator insn, EmitState *state) const
 {
-	auto ty = getType(insn.word(1));
-	auto &dst = state->createIntermediate(insn.word(2), ty.sizeInComponents);
+	auto type = getType(insn.resultTypeId());
+	auto &dst = state->createIntermediate(insn.resultId(), type.sizeInComponents);
 	auto src = Operand(this, state, insn.word(3));
-	for(uint32_t i = 0; i < ty.sizeInComponents; i++)
+	for(uint32_t i = 0; i < type.sizeInComponents; i++)
 	{
 		dst.move(i, src.Int(i));
 	}
@@ -2310,12 +2306,10 @@
 
 SpirvShader::EmitResult SpirvShader::EmitArrayLength(InsnIterator insn, EmitState *state) const
 {
-	auto resultTyId = Type::ID(insn.word(1));
-	auto resultId = Object::ID(insn.word(2));
 	auto structPtrId = Object::ID(insn.word(3));
 	auto arrayFieldIdx = insn.word(4);
 
-	auto &resultType = getType(resultTyId);
+	auto &resultType = getType(insn.resultTypeId());
 	ASSERT(resultType.sizeInComponents == 1);
 	ASSERT(resultType.definition.opcode() == spv::OpTypeInt);
 
@@ -2323,7 +2317,7 @@
 	auto &structTy = getType(structPtrTy.element);
 	auto arrayId = Type::ID(structTy.definition.word(2 + arrayFieldIdx));
 
-	auto &result = state->createIntermediate(resultId, 1);
+	auto &result = state->createIntermediate(insn.resultId(), 1);
 	auto structBase = GetPointerToData(structPtrId, 0, state);
 
 	Decorations structDecorations = {};
@@ -2374,14 +2368,13 @@
 		{
 			case spv::OpVariable:
 			{
-				Object::ID resultId = insn.word(2);
-				auto &object = getObject(resultId);
+				auto &object = getObject(insn.resultId());
 				auto &objectTy = getType(object);
 				if(object.kind == Object::Kind::InterfaceVariable && objectTy.storageClass == spv::StorageClassOutput)
 				{
-					auto &dst = routine->getVariable(resultId);
+					auto &dst = routine->getVariable(insn.resultId());
 					int offset = 0;
-					VisitInterface(resultId,
+					VisitInterface(insn.resultId(),
 					               [&](Decorations const &d, AttribType type) {
 						               auto scalarSlot = d.Location << 2 | d.Component;
 						               routine->outputs[scalarSlot] = dst[offset++];
diff --git a/src/Pipeline/SpirvShaderArithmetic.cpp b/src/Pipeline/SpirvShaderArithmetic.cpp
index 7eff4d4..f895290 100644
--- a/src/Pipeline/SpirvShaderArithmetic.cpp
+++ b/src/Pipeline/SpirvShaderArithmetic.cpp
@@ -22,8 +22,8 @@
 
 SpirvShader::EmitResult SpirvShader::EmitVectorTimesScalar(InsnIterator insn, EmitState *state) const
 {
-	auto &type = getType(insn.word(1));
-	auto &dst = state->createIntermediate(insn.word(2), type.sizeInComponents);
+	auto &type = getType(insn.resultTypeId());
+	auto &dst = state->createIntermediate(insn.resultId(), type.sizeInComponents);
 	auto lhs = Operand(this, state, insn.word(3));
 	auto rhs = Operand(this, state, insn.word(4));
 
@@ -37,8 +37,8 @@
 
 SpirvShader::EmitResult SpirvShader::EmitMatrixTimesVector(InsnIterator insn, EmitState *state) const
 {
-	auto &type = getType(insn.word(1));
-	auto &dst = state->createIntermediate(insn.word(2), type.sizeInComponents);
+	auto &type = getType(insn.resultTypeId());
+	auto &dst = state->createIntermediate(insn.resultId(), type.sizeInComponents);
 	auto lhs = Operand(this, state, insn.word(3));
 	auto rhs = Operand(this, state, insn.word(4));
 	auto rhsType = getType(rhs);
@@ -58,8 +58,8 @@
 
 SpirvShader::EmitResult SpirvShader::EmitVectorTimesMatrix(InsnIterator insn, EmitState *state) const
 {
-	auto &type = getType(insn.word(1));
-	auto &dst = state->createIntermediate(insn.word(2), type.sizeInComponents);
+	auto &type = getType(insn.resultTypeId());
+	auto &dst = state->createIntermediate(insn.resultId(), type.sizeInComponents);
 	auto lhs = Operand(this, state, insn.word(3));
 	auto rhs = Operand(this, state, insn.word(4));
 	auto lhsType = getType(lhs);
@@ -79,8 +79,8 @@
 
 SpirvShader::EmitResult SpirvShader::EmitMatrixTimesMatrix(InsnIterator insn, EmitState *state) const
 {
-	auto &type = getType(insn.word(1));
-	auto &dst = state->createIntermediate(insn.word(2), type.sizeInComponents);
+	auto &type = getType(insn.resultTypeId());
+	auto &dst = state->createIntermediate(insn.resultId(), type.sizeInComponents);
 	auto lhs = Operand(this, state, insn.word(3));
 	auto rhs = Operand(this, state, insn.word(4));
 
@@ -106,8 +106,8 @@
 
 SpirvShader::EmitResult SpirvShader::EmitOuterProduct(InsnIterator insn, EmitState *state) const
 {
-	auto &type = getType(insn.word(1));
-	auto &dst = state->createIntermediate(insn.word(2), type.sizeInComponents);
+	auto &type = getType(insn.resultTypeId());
+	auto &dst = state->createIntermediate(insn.resultId(), type.sizeInComponents);
 	auto lhs = Operand(this, state, insn.word(3));
 	auto rhs = Operand(this, state, insn.word(4));
 	auto &lhsType = getType(lhs);
@@ -135,8 +135,8 @@
 
 SpirvShader::EmitResult SpirvShader::EmitTranspose(InsnIterator insn, EmitState *state) const
 {
-	auto &type = getType(insn.word(1));
-	auto &dst = state->createIntermediate(insn.word(2), type.sizeInComponents);
+	auto &type = getType(insn.resultTypeId());
+	auto &dst = state->createIntermediate(insn.resultId(), type.sizeInComponents);
 	auto mat = Operand(this, state, insn.word(3));
 
 	auto numCols = type.definition.word(3);
@@ -155,8 +155,8 @@
 
 SpirvShader::EmitResult SpirvShader::EmitUnaryOp(InsnIterator insn, EmitState *state) const
 {
-	auto &type = getType(insn.word(1));
-	auto &dst = state->createIntermediate(insn.word(2), type.sizeInComponents);
+	auto &type = getType(insn.resultTypeId());
+	auto &dst = state->createIntermediate(insn.resultId(), type.sizeInComponents);
 	auto src = Operand(this, state, insn.word(3));
 
 	for(auto i = 0u; i < type.sizeInComponents; i++)
@@ -317,8 +317,8 @@
 
 SpirvShader::EmitResult SpirvShader::EmitBinaryOp(InsnIterator insn, EmitState *state) const
 {
-	auto &type = getType(insn.word(1));
-	auto &dst = state->createIntermediate(insn.word(2), type.sizeInComponents);
+	auto &type = getType(insn.resultTypeId());
+	auto &dst = state->createIntermediate(insn.resultId(), type.sizeInComponents);
 	auto &lhsType = getType(getObject(insn.word(3)));
 	auto lhs = Operand(this, state, insn.word(3));
 	auto rhs = Operand(this, state, insn.word(4));
@@ -520,9 +520,9 @@
 
 SpirvShader::EmitResult SpirvShader::EmitDot(InsnIterator insn, EmitState *state) const
 {
-	auto &type = getType(insn.word(1));
+	auto &type = getType(insn.resultTypeId());
 	ASSERT(type.sizeInComponents == 1);
-	auto &dst = state->createIntermediate(insn.word(2), type.sizeInComponents);
+	auto &dst = state->createIntermediate(insn.resultId(), type.sizeInComponents);
 	auto &lhsType = getType(getObject(insn.word(3)));
 	auto lhs = Operand(this, state, insn.word(3));
 	auto rhs = Operand(this, state, insn.word(4));
diff --git a/src/Pipeline/SpirvShaderGLSLstd450.cpp b/src/Pipeline/SpirvShaderGLSLstd450.cpp
index 75d2847..acc739d 100644
--- a/src/Pipeline/SpirvShaderGLSLstd450.cpp
+++ b/src/Pipeline/SpirvShaderGLSLstd450.cpp
@@ -27,8 +27,8 @@
 
 SpirvShader::EmitResult SpirvShader::EmitExtGLSLstd450(InsnIterator insn, EmitState *state) const
 {
-	auto &type = getType(insn.word(1));
-	auto &dst = state->createIntermediate(insn.word(2), type.sizeInComponents);
+	auto &type = getType(insn.resultTypeId());
+	auto &dst = state->createIntermediate(insn.resultId(), type.sizeInComponents);
 	auto extInstIndex = static_cast<GLSLstd450>(insn.word(4));
 
 	switch(extInstIndex)
diff --git a/src/Pipeline/SpirvShaderImage.cpp b/src/Pipeline/SpirvShaderImage.cpp
index 399e8d1..a00c2fc 100644
--- a/src/Pipeline/SpirvShaderImage.cpp
+++ b/src/Pipeline/SpirvShaderImage.cpp
@@ -107,13 +107,11 @@
 
 SpirvShader::EmitResult SpirvShader::EmitImageSample(ImageInstruction instruction, InsnIterator insn, EmitState *state) const
 {
-	Type::ID resultTypeId = insn.word(1);
-	Object::ID resultId = insn.word(2);
 	Object::ID sampledImageId = insn.word(3);  // For OpImageFetch this is just an Image, not a SampledImage.
 	Object::ID coordinateId = insn.word(4);
-	auto &resultType = getType(resultTypeId);
+	auto &resultType = getType(insn.resultTypeId());
 
-	auto &result = state->createIntermediate(resultId, resultType.sizeInComponents);
+	auto &result = state->createIntermediate(insn.resultId(), resultType.sizeInComponents);
 	auto imageDescriptor = state->getPointer(sampledImageId).base;  // vk::SampledImageDescriptor*
 
 	// If using a separate sampler, look through the OpSampledImage instruction to find the sampler descriptor
@@ -291,7 +289,7 @@
 		in[i] = As<SIMD::Float>(sampleValue.Int(0));
 	}
 
-	auto cacheIt = state->routine->samplerCache.find(resultId);
+	auto cacheIt = state->routine->samplerCache.find(insn.resultId());
 	ASSERT(cacheIt != state->routine->samplerCache.end());
 	auto &cache = cacheIt->second;
 	auto cacheHit = cache.imageDescriptor == imageDescriptor && cache.sampler == sampler;
@@ -313,12 +311,11 @@
 
 SpirvShader::EmitResult SpirvShader::EmitImageQuerySizeLod(InsnIterator insn, EmitState *state) const
 {
-	auto &resultTy = getType(Type::ID(insn.word(1)));
-	auto resultId = Object::ID(insn.word(2));
+	auto &resultTy = getType(Type::ID(insn.resultTypeId()));
 	auto imageId = Object::ID(insn.word(3));
 	auto lodId = Object::ID(insn.word(4));
 
-	auto &dst = state->createIntermediate(resultId, resultTy.sizeInComponents);
+	auto &dst = state->createIntermediate(insn.resultId(), resultTy.sizeInComponents);
 	GetImageDimensions(state, resultTy, imageId, lodId, dst);
 
 	return EmitResult::Continue;
@@ -326,12 +323,11 @@
 
 SpirvShader::EmitResult SpirvShader::EmitImageQuerySize(InsnIterator insn, EmitState *state) const
 {
-	auto &resultTy = getType(Type::ID(insn.word(1)));
-	auto resultId = Object::ID(insn.word(2));
+	auto &resultTy = getType(Type::ID(insn.resultTypeId()));
 	auto imageId = Object::ID(insn.word(3));
 	auto lodId = Object::ID(0);
 
-	auto &dst = state->createIntermediate(resultId, resultTy.sizeInComponents);
+	auto &dst = state->createIntermediate(insn.resultId(), resultTy.sizeInComponents);
 	GetImageDimensions(state, resultTy, imageId, lodId, dst);
 
 	return EmitResult::Continue;
@@ -412,9 +408,8 @@
 
 SpirvShader::EmitResult SpirvShader::EmitImageQueryLevels(InsnIterator insn, EmitState *state) const
 {
-	auto &resultTy = getType(Type::ID(insn.word(1)));
+	auto &resultTy = getType(Type::ID(insn.resultTypeId()));
 	ASSERT(resultTy.sizeInComponents == 1);
-	auto resultId = Object::ID(insn.word(2));
 	auto imageId = Object::ID(insn.word(3));
 
 	const DescriptorDecorations &d = descriptorDecorations.at(imageId);
@@ -434,7 +429,7 @@
 			UNREACHABLE("Image descriptorType: %d", int(bindingLayout.descriptorType));
 	}
 
-	auto &dst = state->createIntermediate(resultId, 1);
+	auto &dst = state->createIntermediate(insn.resultId(), 1);
 	dst.move(0, SIMD::Int(mipLevels));
 
 	return EmitResult::Continue;
@@ -442,9 +437,8 @@
 
 SpirvShader::EmitResult SpirvShader::EmitImageQuerySamples(InsnIterator insn, EmitState *state) const
 {
-	auto &resultTy = getType(Type::ID(insn.word(1)));
+	auto &resultTy = getType(Type::ID(insn.resultTypeId()));
 	ASSERT(resultTy.sizeInComponents == 1);
-	auto resultId = Object::ID(insn.word(2));
 	auto imageId = Object::ID(insn.word(3));
 	auto imageTy = getType(getObject(imageId));
 	ASSERT(imageTy.definition.opcode() == spv::OpTypeImage);
@@ -471,7 +465,7 @@
 			UNREACHABLE("Image descriptorType: %d", int(bindingLayout.descriptorType));
 	}
 
-	auto &dst = state->createIntermediate(resultId, 1);
+	auto &dst = state->createIntermediate(insn.resultId(), 1);
 	dst.move(0, SIMD::Int(sampleCount));
 
 	return EmitResult::Continue;
@@ -545,7 +539,6 @@
 	auto imageId = Object::ID(insn.word(3));
 	auto &image = getObject(imageId);
 	auto &imageType = getType(image);
-	Object::ID resultId = insn.word(2);
 
 	Object::ID sampleId = 0;
 
@@ -593,7 +586,7 @@
 
 	auto imageSizeInBytes = *Pointer<Int>(binding + OFFSET(vk::StorageImageDescriptor, sizeInBytes));
 
-	auto &dst = state->createIntermediate(resultId, resultType.sizeInComponents);
+	auto &dst = state->createIntermediate(insn.resultId(), resultType.sizeInComponents);
 
 	auto texelSize = vk::Format(vkFormat).bytes();
 	auto basePtr = SIMD::Pointer(imageBase, imageSizeInBytes);