moved SkSL InterfaceBlock data into IRNode

Change-Id: If85369d978e395502b2169d605c2513a9086b57e
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/326916
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
Reviewed-by: John Stiles <johnstiles@google.com>
diff --git a/src/sksl/SkSLAnalysis.cpp b/src/sksl/SkSLAnalysis.cpp
index 6e6e83d..c4c8bc6 100644
--- a/src/sksl/SkSLAnalysis.cpp
+++ b/src/sksl/SkSLAnalysis.cpp
@@ -509,7 +509,7 @@
             return this->visitStatement(*pe.template as<FunctionDefinition>().body());
 
         case ProgramElement::Kind::kInterfaceBlock:
-            for (auto& e : pe.template as<InterfaceBlock>().fSizes) {
+            for (auto& e : pe.template as<InterfaceBlock>().sizes()) {
                 if (e && this->visitExpression(*e)) {
                     return true;
                 }
diff --git a/src/sksl/SkSLCompiler.cpp b/src/sksl/SkSLCompiler.cpp
index 9784f83..5c9f602 100644
--- a/src/sksl/SkSLCompiler.cpp
+++ b/src/sksl/SkSLCompiler.cpp
@@ -378,9 +378,9 @@
                 break;
             }
             case ProgramElement::Kind::kInterfaceBlock: {
-                const Variable* var = element->as<InterfaceBlock>().fVariable;
-                SkASSERT(var->isBuiltin());
-                intrinsics->insertOrDie(var->name(), std::move(element));
+                const Variable& var = element->as<InterfaceBlock>().variable();
+                SkASSERT(var.isBuiltin());
+                intrinsics->insertOrDie(var.name(), std::move(element));
                 break;
             }
             default:
diff --git a/src/sksl/SkSLDehydrator.cpp b/src/sksl/SkSLDehydrator.cpp
index ea36e94..374166e 100644
--- a/src/sksl/SkSLDehydrator.cpp
+++ b/src/sksl/SkSLDehydrator.cpp
@@ -544,11 +544,11 @@
         case ProgramElement::Kind::kInterfaceBlock: {
             const InterfaceBlock& i = e.as<InterfaceBlock>();
             this->writeCommand(Rehydrator::kInterfaceBlock_Command);
-            this->write(*i.fVariable);
-            this->write(i.fTypeName);
-            this->write(i.fInstanceName);
-            this->writeU8(i.fSizes.size());
-            for (const auto& s : i.fSizes) {
+            this->write(i.variable());
+            this->write(i.typeName());
+            this->write(i.instanceName());
+            this->writeU8(i.sizes().count());
+            for (const auto& s : i.sizes()) {
                 this->write(s.get());
             }
             break;
diff --git a/src/sksl/SkSLGLSLCodeGenerator.cpp b/src/sksl/SkSLGLSLCodeGenerator.cpp
index 1994bf3..5e00dda 100644
--- a/src/sksl/SkSLGLSLCodeGenerator.cpp
+++ b/src/sksl/SkSLGLSLCodeGenerator.cpp
@@ -1175,13 +1175,13 @@
 }
 
 void GLSLCodeGenerator::writeInterfaceBlock(const InterfaceBlock& intf) {
-    if (intf.fTypeName == "sk_PerVertex") {
+    if (intf.typeName() == "sk_PerVertex") {
         return;
     }
-    this->writeModifiers(intf.fVariable->modifiers(), true);
-    this->writeLine(intf.fTypeName + " {");
+    this->writeModifiers(intf.variable().modifiers(), true);
+    this->writeLine(intf.typeName() + " {");
     fIndentation++;
-    const Type* structType = &intf.fVariable->type();
+    const Type* structType = &intf.variable().type();
     while (structType->typeKind() == Type::TypeKind::kArray) {
         structType = &structType->componentType();
     }
@@ -1193,10 +1193,10 @@
     }
     fIndentation--;
     this->write("}");
-    if (intf.fInstanceName.size()) {
+    if (intf.instanceName().size()) {
         this->write(" ");
-        this->write(intf.fInstanceName);
-        for (const auto& size : intf.fSizes) {
+        this->write(intf.instanceName());
+        for (const auto& size : intf.sizes()) {
             this->write("[");
             if (size) {
                 this->writeExpression(*size, kTopLevel_Precedence);
diff --git a/src/sksl/SkSLIRGenerator.cpp b/src/sksl/SkSLIRGenerator.cpp
index 8a5d42d..1b20c73 100644
--- a/src/sksl/SkSLIRGenerator.cpp
+++ b/src/sksl/SkSLIRGenerator.cpp
@@ -774,7 +774,7 @@
     const Variable* skPerVertex = nullptr;
     if (const ProgramElement* perVertexDecl = fIntrinsics->find(Compiler::PERVERTEX_NAME)) {
         SkASSERT(perVertexDecl->is<InterfaceBlock>());
-        skPerVertex = perVertexDecl->as<InterfaceBlock>().fVariable;
+        skPerVertex = &perVertexDecl->as<InterfaceBlock>().variable();
     }
 
     // sk_Position = float4(sk_Position.xy * rtAdjust.xz + sk_Position.ww * rtAdjust.yw,
@@ -2835,7 +2835,7 @@
                     initialValue = decl.value().get();
                 } else {
                     SkASSERT(clonedDecl->is<InterfaceBlock>());
-                    sharedVar = clonedDecl->as<InterfaceBlock>().fVariable;
+                    sharedVar = &clonedDecl->as<InterfaceBlock>().variable();
                 }
 
                 // Now clone the Variable, and add the clone to the Program's symbol table.
@@ -2852,7 +2852,7 @@
                     GlobalVarDeclaration& global = clonedDecl->as<GlobalVarDeclaration>();
                     global.declaration()->as<VarDeclaration>().setVar(clonedVar);
                 } else {
-                    clonedDecl->as<InterfaceBlock>().fVariable = clonedVar;
+                    clonedDecl->as<InterfaceBlock>().setVariable(clonedVar);
                 }
 
                 // Remember this new re-mapping...
diff --git a/src/sksl/SkSLMetalCodeGenerator.cpp b/src/sksl/SkSLMetalCodeGenerator.cpp
index 985c9fe..7fc1dea 100644
--- a/src/sksl/SkSLMetalCodeGenerator.cpp
+++ b/src/sksl/SkSLMetalCodeGenerator.cpp
@@ -982,15 +982,15 @@
                 }
             } else if (e->is<InterfaceBlock>()) {
                 const InterfaceBlock& intf = e->as<InterfaceBlock>();
-                if ("sk_PerVertex" == intf.fTypeName) {
+                if (intf.typeName() == "sk_PerVertex") {
                     continue;
                 }
                 this->write(", constant ");
-                this->writeType(intf.fVariable->type());
+                this->writeType(intf.variable().type());
                 this->write("& " );
                 this->write(fInterfaceBlockNameMap[&intf]);
                 this->write(" [[buffer(");
-                this->write(to_string(intf.fVariable->modifiers().fLayout.fBinding));
+                this->write(to_string(intf.variable().modifiers().fLayout.fBinding));
                 this->write(")]]");
             }
         }
@@ -1113,13 +1113,13 @@
 }
 
 void MetalCodeGenerator::writeInterfaceBlock(const InterfaceBlock& intf) {
-    if ("sk_PerVertex" == intf.fTypeName) {
+    if ("sk_PerVertex" == intf.typeName()) {
         return;
     }
-    this->writeModifiers(intf.fVariable->modifiers(), true);
+    this->writeModifiers(intf.variable().modifiers(), true);
     this->write("struct ");
-    this->writeLine(intf.fTypeName + " {");
-    const Type* structType = &intf.fVariable->type();
+    this->writeLine(intf.typeName() + " {");
+    const Type* structType = &intf.variable().type();
     fWrittenStructs.push_back(structType);
     while (structType->typeKind() == Type::TypeKind::kArray) {
         structType = &structType->componentType();
@@ -1131,17 +1131,17 @@
     }
     fIndentation--;
     this->write("}");
-    if (intf.fInstanceName.size()) {
+    if (intf.instanceName().size()) {
         this->write(" ");
-        this->write(intf.fInstanceName);
-        for (const auto& size : intf.fSizes) {
+        this->write(intf.instanceName());
+        for (const auto& size : intf.sizes()) {
             this->write("[");
             if (size) {
                 this->writeExpression(*size, kTopLevel_Precedence);
             }
             this->write("]");
         }
-        fInterfaceBlockNameMap[&intf] = intf.fInstanceName;
+        fInterfaceBlockNameMap[&intf] = intf.instanceName();
     } else {
         fInterfaceBlockNameMap[&intf] = "_anonInterface" +  to_string(fAnonInterfaceCount++);
     }
@@ -1537,7 +1537,7 @@
         void VisitInterfaceBlock(const InterfaceBlock& block, const String& blockName) override {
             this->AddElement();
             fCodeGen->write("    constant ");
-            fCodeGen->write(block.fTypeName);
+            fCodeGen->write(block.typeName());
             fCodeGen->write("* ");
             fCodeGen->writeName(blockName);
             fCodeGen->write(";\n");
diff --git a/src/sksl/SkSLSPIRVCodeGenerator.cpp b/src/sksl/SkSLSPIRVCodeGenerator.cpp
index 8a0f2e8..f0c70e0 100644
--- a/src/sksl/SkSLSPIRVCodeGenerator.cpp
+++ b/src/sksl/SkSLSPIRVCodeGenerator.cpp
@@ -2697,14 +2697,14 @@
 }
 
 SpvId SPIRVCodeGenerator::writeInterfaceBlock(const InterfaceBlock& intf, bool appendRTHeight) {
-    bool isBuffer = (0 != (intf.fVariable->modifiers().fFlags & Modifiers::kBuffer_Flag));
-    bool pushConstant = (0 != (intf.fVariable->modifiers().fLayout.fFlags &
-                               Layout::kPushConstant_Flag));
+    bool isBuffer = ((intf.variable().modifiers().fFlags & Modifiers::kBuffer_Flag) != 0);
+    bool pushConstant = ((intf.variable().modifiers().fLayout.fFlags &
+                          Layout::kPushConstant_Flag) != 0);
     MemoryLayout memoryLayout = (pushConstant || isBuffer) ?
                                 MemoryLayout(MemoryLayout::k430_Standard) :
                                 fDefaultLayout;
     SpvId result = this->nextId();
-    const Type* type = &intf.fVariable->type();
+    const Type* type = &intf.variable().type();
     if (fProgram.fInputs.fRTHeight && appendRTHeight) {
         SkASSERT(fRTHeightStructId == (SpvId) -1);
         SkASSERT(fRTHeightFieldIndex == (SpvId) -1);
@@ -2715,7 +2715,7 @@
         type = new Type(type->fOffset, type->name(), fields);
     }
     SpvId typeId;
-    Modifiers intfModifiers = intf.fVariable->modifiers();
+    Modifiers intfModifiers = intf.variable().modifiers();
     if (intfModifiers.fLayout.fBuiltin == SK_IN_BUILTIN) {
         for (const auto& e : fProgram.elements()) {
             if (e->is<ModifiersDeclaration>()) {
@@ -2724,7 +2724,7 @@
             }
         }
         typeId = this->getType(Type("sk_in", Type::TypeKind::kArray,
-                                    intf.fVariable->type().componentType(),
+                                    intf.variable().type().componentType(),
                                     fSkInCount),
                                memoryLayout);
     } else {
@@ -2744,7 +2744,7 @@
         layout.fSet = 0;
     }
     this->writeLayout(layout, result);
-    fVariableMap[intf.fVariable] = result;
+    fVariableMap[&intf.variable()] = result;
     if (fProgram.fInputs.fRTHeight && appendRTHeight) {
         delete type;
     }
@@ -3198,16 +3198,16 @@
     for (const auto& e : program.elements()) {
         if (e->is<InterfaceBlock>()) {
             InterfaceBlock& intf = e->as<InterfaceBlock>();
-            const Modifiers& modifiers = intf.fVariable->modifiers();
+            const Modifiers& modifiers = intf.variable().modifiers();
             if (SK_IN_BUILTIN == modifiers.fLayout.fBuiltin) {
                 SkASSERT(skInSize != -1);
-                intf.fSizes.emplace_back(new IntLiteral(fContext, -1, skInSize));
+                intf.sizes().emplace_back(new IntLiteral(fContext, -1, skInSize));
             }
             SpvId id = this->writeInterfaceBlock(intf);
             if (((modifiers.fFlags & Modifiers::kIn_Flag) ||
                 (modifiers.fFlags & Modifiers::kOut_Flag)) &&
                 modifiers.fLayout.fBuiltin == -1 &&
-                !is_dead(*intf.fVariable)) {
+                !is_dead(intf.variable())) {
                 interfaceVars.insert(id);
             }
         }
diff --git a/src/sksl/ir/SkSLIRNode.cpp b/src/sksl/ir/SkSLIRNode.cpp
index 7dbd665..34d1194 100644
--- a/src/sksl/ir/SkSLIRNode.cpp
+++ b/src/sksl/ir/SkSLIRNode.cpp
@@ -82,6 +82,11 @@
 , fKind(kind)
 , fData(data) {}
 
+IRNode::IRNode(int offset, int kind, const InterfaceBlockData& data)
+: fOffset(offset)
+, fKind(kind)
+, fData(data) {}
+
 IRNode::IRNode(int offset, int kind, const IntLiteralData& data)
 : fOffset(offset)
 , fKind(kind)
diff --git a/src/sksl/ir/SkSLIRNode.h b/src/sksl/ir/SkSLIRNode.h
index af9ad33..bb5390f 100644
--- a/src/sksl/ir/SkSLIRNode.h
+++ b/src/sksl/ir/SkSLIRNode.h
@@ -160,6 +160,13 @@
         bool fIsStatic;
     };
 
+    struct InterfaceBlockData {
+        const Variable* fVariable;
+        String fTypeName;
+        String fInstanceName;
+        std::shared_ptr<SymbolTable> fTypeOwner;
+    };
+
     struct IntLiteralData {
         const Type* fType;
         int64_t fValue;
@@ -256,6 +263,7 @@
             kFunctionReference,
             kIfStatement,
             kInlineMarker,
+            kInterfaceBlock,
             kIntLiteral,
             kModifiersDeclaration,
             kSection,
@@ -289,6 +297,7 @@
             FunctionReferenceData fFunctionReference;
             IfStatementData fIfStatement;
             InlineMarkerData fInlineMarker;
+            InterfaceBlockData fInterfaceBlock;
             IntLiteralData fIntLiteral;
             ModifiersDeclarationData fModifiersDeclaration;
             SectionData fSection;
@@ -380,6 +389,11 @@
             *(new(&fContents) InlineMarkerData) = data;
         }
 
+        NodeData(InterfaceBlockData data)
+            : fKind(Kind::kInterfaceBlock) {
+            *(new(&fContents) InterfaceBlockData) = data;
+        }
+
         NodeData(IntLiteralData data)
             : fKind(Kind::kIntLiteral) {
             *(new(&fContents) IntLiteralData) = data;
@@ -506,6 +520,9 @@
                 case Kind::kInlineMarker:
                     *(new(&fContents) InlineMarkerData) = other.fContents.fInlineMarker;
                     break;
+                case Kind::kInterfaceBlock:
+                    *(new(&fContents) InterfaceBlockData) = other.fContents.fInterfaceBlock;
+                    break;
                 case Kind::kIntLiteral:
                     *(new(&fContents) IntLiteralData) = other.fContents.fIntLiteral;
                     break;
@@ -605,6 +622,9 @@
                 case Kind::kInlineMarker:
                     fContents.fInlineMarker.~InlineMarkerData();
                     break;
+                case Kind::kInterfaceBlock:
+                    fContents.fInterfaceBlock.~InterfaceBlockData();
+                    break;
                 case Kind::kIntLiteral:
                     fContents.fIntLiteral.~IntLiteralData();
                     break;
@@ -681,6 +701,8 @@
 
     IRNode(int offset, int kind, const InlineMarkerData& data);
 
+    IRNode(int offset, int kind, const InterfaceBlockData& data);
+
     IRNode(int offset, int kind, const IntLiteralData& data);
 
     IRNode(int offset, int kind, const ModifiersDeclarationData& data);
@@ -835,6 +857,16 @@
         return fData.fContents.fInlineMarker;
     }
 
+    InterfaceBlockData& interfaceBlockData() {
+        SkASSERT(fData.fKind == NodeData::Kind::kInterfaceBlock);
+        return fData.fContents.fInterfaceBlock;
+    }
+
+    const InterfaceBlockData& interfaceBlockData() const {
+        SkASSERT(fData.fKind == NodeData::Kind::kInterfaceBlock);
+        return fData.fContents.fInterfaceBlock;
+    }
+
     const IntLiteralData& intLiteralData() const {
         SkASSERT(fData.fKind == NodeData::Kind::kIntLiteral);
         return fData.fContents.fIntLiteral;
diff --git a/src/sksl/ir/SkSLInterfaceBlock.h b/src/sksl/ir/SkSLInterfaceBlock.h
index 425057a..707f5df 100644
--- a/src/sksl/ir/SkSLInterfaceBlock.h
+++ b/src/sksl/ir/SkSLInterfaceBlock.h
@@ -29,26 +29,53 @@
 
     InterfaceBlock(int offset, const Variable* var, String typeName, String instanceName,
                    ExpressionArray sizes, std::shared_ptr<SymbolTable> typeOwner)
-    : INHERITED(offset, kProgramElementKind)
-    , fVariable(var)
-    , fTypeName(std::move(typeName))
-    , fInstanceName(std::move(instanceName))
-    , fSizes(std::move(sizes))
-    , fTypeOwner(typeOwner) {}
+    : INHERITED(offset, InterfaceBlockData{var, std::move(typeName), std::move(instanceName),
+                                           std::move(typeOwner)}) {
+        fExpressionChildren.move_back_n(sizes.size(), sizes.data());
+    }
+
+    const Variable& variable() const {
+        return *this->interfaceBlockData().fVariable;
+    }
+
+    void setVariable(const Variable* var) {
+        this->interfaceBlockData().fVariable = var;
+    }
+
+    const String& typeName() const {
+        return this->interfaceBlockData().fTypeName;
+    }
+
+    const String& instanceName() const {
+        return this->interfaceBlockData().fInstanceName;
+    }
+
+    const std::shared_ptr<SymbolTable>& typeOwner() const {
+        return this->interfaceBlockData().fTypeOwner;
+    }
+
+    ExpressionArray& sizes() {
+        return fExpressionChildren;
+    }
+
+    const ExpressionArray& sizes() const {
+        return fExpressionChildren;
+    }
 
     std::unique_ptr<ProgramElement> clone() const override {
         ExpressionArray sizesClone;
-        sizesClone.reserve_back(fSizes.size());
-        for (const auto& s : fSizes) {
-            sizesClone.push_back(s ? s->clone() : nullptr);
+        sizesClone.reserve_back(this->sizes().size());
+        for (const auto& size : this->sizes()) {
+            sizesClone.push_back(size ? size->clone() : nullptr);
         }
-        return std::make_unique<InterfaceBlock>(fOffset, fVariable, fTypeName, fInstanceName,
-                                                std::move(sizesClone), fTypeOwner);
+        return std::make_unique<InterfaceBlock>(fOffset, &this->variable(), this->typeName(),
+                                                this->instanceName(), std::move(sizesClone),
+                                                this->typeOwner());
     }
 
     String description() const override {
-        String result = fVariable->modifiers().description() + fTypeName + " {\n";
-        const Type* structType = &fVariable->type();
+        String result = this->variable().modifiers().description() + this->typeName() + " {\n";
+        const Type* structType = &this->variable().type();
         while (structType->typeKind() == Type::TypeKind::kArray) {
             structType = &structType->componentType();
         }
@@ -56,9 +83,9 @@
             result += f.description() + "\n";
         }
         result += "}";
-        if (fInstanceName.size()) {
-            result += " " + fInstanceName;
-            for (const auto& size : fSizes) {
+        if (this->instanceName().size()) {
+            result += " " + this->instanceName();
+            for (const auto& size : this->sizes()) {
                 result += "[";
                 if (size) {
                     result += size->description();
@@ -69,12 +96,6 @@
         return result + ";";
     }
 
-    const Variable* fVariable;
-    const String fTypeName;
-    const String fInstanceName;
-    ExpressionArray fSizes;
-    const std::shared_ptr<SymbolTable> fTypeOwner;
-
     using INHERITED = ProgramElement;
 };
 
diff --git a/src/sksl/ir/SkSLProgramElement.h b/src/sksl/ir/SkSLProgramElement.h
index 7a2873b..6dd4fcc 100644
--- a/src/sksl/ir/SkSLProgramElement.h
+++ b/src/sksl/ir/SkSLProgramElement.h
@@ -43,6 +43,9 @@
     ProgramElement(int offset, const FunctionDefinitionData& data)
     : INHERITED(offset, (int) Kind::kFunction, data) {}
 
+    ProgramElement(int offset, const InterfaceBlockData& data)
+    : INHERITED(offset, (int) Kind::kInterfaceBlock, data) {}
+
     ProgramElement(int offset, const ModifiersDeclarationData& data)
     : INHERITED(offset, (int) Kind::kModifiers, data) {}