Reland "Revert "moved BinaryExpression's data into IRNode""

This reverts commit 1d3e0e0054b243b7a62029c29090e7e76a19a805.

Reason for revert: possibly causing https://task-scheduler.skia.org/task/F1DoniJAddPuEkH9ETTE

Original change's description:
> Revert "Revert "moved BinaryExpression's data into IRNode""
> 
> This reverts commit b61c3a9a01c44840eaa35b28cae0a4b358727f3c.
> 
> Change-Id: I4689e1f4977fab3233ff492cee06fbc301b5c689
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/317386
> Reviewed-by: John Stiles <johnstiles@google.com>
> Commit-Queue: Ethan Nicholas <ethannicholas@google.com>

TBR=brianosman@google.com,ethannicholas@google.com,johnstiles@google.com

# Not skipping CQ checks because this is a reland.

Change-Id: Id0f3f211f09fbf31b626c648ed141fc6154a450c
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/317395
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
diff --git a/src/sksl/SkSLASTNode.h b/src/sksl/SkSLASTNode.h
index e493895..c65429c 100644
--- a/src/sksl/SkSLASTNode.h
+++ b/src/sksl/SkSLASTNode.h
@@ -12,11 +12,15 @@
 #include "src/sksl/SkSLString.h"
 #include "src/sksl/ir/SkSLModifiers.h"
 
-#include <algorithm>
 #include <vector>
 
 namespace SkSL {
 
+// std::max isn't constexpr in some compilers
+static constexpr size_t Max(size_t a, size_t b) {
+    return a > b ? a : b;
+}
+
 /**
  * Represents a node in the abstract syntax tree (AST). The AST is based directly on the parse tree;
  * it is a parsed-but-not-yet-analyzed version of the program.
@@ -263,18 +267,18 @@
     };
 
     struct NodeData {
-        char fBytes[std::max(sizeof(Token),
-                    std::max(sizeof(StringFragment),
-                    std::max(sizeof(bool),
-                    std::max(sizeof(SKSL_INT),
-                    std::max(sizeof(SKSL_FLOAT),
-                    std::max(sizeof(Modifiers),
-                    std::max(sizeof(TypeData),
-                    std::max(sizeof(FunctionData),
-                    std::max(sizeof(ParameterData),
-                    std::max(sizeof(VarData),
-                    std::max(sizeof(InterfaceBlockData),
-                             sizeof(SectionData))))))))))))];
+        char fBytes[Max(sizeof(Token),
+                    Max(sizeof(StringFragment),
+                    Max(sizeof(bool),
+                    Max(sizeof(SKSL_INT),
+                    Max(sizeof(SKSL_FLOAT),
+                    Max(sizeof(Modifiers),
+                    Max(sizeof(TypeData),
+                    Max(sizeof(FunctionData),
+                    Max(sizeof(ParameterData),
+                    Max(sizeof(VarData),
+                    Max(sizeof(InterfaceBlockData),
+                        sizeof(SectionData))))))))))))];
 
         enum class Kind {
             kToken,
diff --git a/src/sksl/SkSLAnalysis.cpp b/src/sksl/SkSLAnalysis.cpp
index 82ac423..6496965 100644
--- a/src/sksl/SkSLAnalysis.cpp
+++ b/src/sksl/SkSLAnalysis.cpp
@@ -266,7 +266,7 @@
             return false;
         case Expression::Kind::kBinary: {
             const BinaryExpression& b = e.as<BinaryExpression>();
-            return this->visitExpression(b.left()) || this->visitExpression(b.right()); }
+            return this->visitExpression(*b.fLeft) || this->visitExpression(*b.fRight); }
         case Expression::Kind::kConstructor: {
             const Constructor& c = e.as<Constructor>();
             for (const auto& arg : c.fArguments) {
diff --git a/src/sksl/SkSLByteCodeGenerator.cpp b/src/sksl/SkSLByteCodeGenerator.cpp
index 1e9dab0..a213ca4 100644
--- a/src/sksl/SkSLByteCodeGenerator.cpp
+++ b/src/sksl/SkSLByteCodeGenerator.cpp
@@ -681,29 +681,28 @@
 }
 
 bool ByteCodeGenerator::writeBinaryExpression(const BinaryExpression& b, bool discard) {
-    const Expression& left = b.left();
-    const Expression& right = b.right();
-    Token::Kind op = b.getOperator();
-    if (op == Token::Kind::TK_EQ) {
-        std::unique_ptr<LValue> lvalue = this->getLValue(left);
-        this->writeExpression(right);
+    if (b.fOperator == Token::Kind::TK_EQ) {
+        std::unique_ptr<LValue> lvalue = this->getLValue(*b.fLeft);
+        this->writeExpression(*b.fRight);
         lvalue->store(discard);
         discard = false;
         return discard;
     }
-    const Type& lType = left.type();
-    const Type& rType = right.type();
+    const Type& lType = b.fLeft->type();
+    const Type& rType = b.fRight->type();
     bool lVecOrMtx = (lType.typeKind() == Type::TypeKind::kVector ||
                       lType.typeKind() == Type::TypeKind::kMatrix);
     bool rVecOrMtx = (rType.typeKind() == Type::TypeKind::kVector ||
                       rType.typeKind() == Type::TypeKind::kMatrix);
+    Token::Kind op;
     std::unique_ptr<LValue> lvalue;
-    if (Compiler::IsAssignment(op)) {
-        lvalue = this->getLValue(left);
+    if (Compiler::IsAssignment(b.fOperator)) {
+        lvalue = this->getLValue(*b.fLeft);
         lvalue->load();
-        op = Compiler::RemoveAssignment(op);
+        op = Compiler::RemoveAssignment(b.fOperator);
     } else {
-        this->writeExpression(left);
+        this->writeExpression(*b.fLeft);
+        op = b.fOperator;
         if (!lVecOrMtx && rVecOrMtx) {
             for (int i = SlotCount(rType); i > 1; --i) {
                 this->write(ByteCodeInstruction::kDup, 1);
@@ -719,7 +718,7 @@
             this->write(ByteCodeInstruction::kMaskPush);
             this->write(ByteCodeInstruction::kBranchIfAllFalse);
             DeferredLocation falseLocation(this);
-            this->writeExpression(right);
+            this->writeExpression(*b.fRight);
             this->write(ByteCodeInstruction::kAndB, 1);
             falseLocation.set();
             this->write(ByteCodeInstruction::kMaskPop);
@@ -732,7 +731,7 @@
             this->write(ByteCodeInstruction::kMaskPush);
             this->write(ByteCodeInstruction::kBranchIfAllFalse);
             DeferredLocation falseLocation(this);
-            this->writeExpression(right);
+            this->writeExpression(*b.fRight);
             this->write(ByteCodeInstruction::kOrB, 1);
             falseLocation.set();
             this->write(ByteCodeInstruction::kMaskPop);
@@ -742,13 +741,13 @@
         case Token::Kind::TK_SHR: {
             SkASSERT(count == 1 && (tc == SkSL::TypeCategory::kSigned ||
                                     tc == SkSL::TypeCategory::kUnsigned));
-            if (!right.isCompileTimeConstant()) {
-                fErrors.error(right.fOffset, "Shift amounts must be constant");
+            if (!b.fRight->isCompileTimeConstant()) {
+                fErrors.error(b.fRight->fOffset, "Shift amounts must be constant");
                 return false;
             }
-            int64_t shift = right.getConstantInt();
+            int64_t shift = b.fRight->getConstantInt();
             if (shift < 0 || shift > 31) {
-                fErrors.error(right.fOffset, "Shift amount out of range");
+                fErrors.error(b.fRight->fOffset, "Shift amount out of range");
                 return false;
             }
 
@@ -766,7 +765,7 @@
         default:
             break;
     }
-    this->writeExpression(right);
+    this->writeExpression(*b.fRight);
     if (lVecOrMtx && !rVecOrMtx) {
         for (int i = SlotCount(lType); i > 1; --i) {
             this->write(ByteCodeInstruction::kDup, 1);
diff --git a/src/sksl/SkSLCFGGenerator.cpp b/src/sksl/SkSLCFGGenerator.cpp
index 281e380..d9a9ab1 100644
--- a/src/sksl/SkSLCFGGenerator.cpp
+++ b/src/sksl/SkSLCFGGenerator.cpp
@@ -166,14 +166,14 @@
     switch (expr->kind()) {
         case Expression::Kind::kBinary: {
             BinaryExpression& b = expr->as<BinaryExpression>();
-            if (b.getOperator() == Token::Kind::TK_EQ) {
-                if (!this->tryRemoveLValueBefore(iter, &b.left())) {
+            if (b.fOperator == Token::Kind::TK_EQ) {
+                if (!this->tryRemoveLValueBefore(iter, b.fLeft.get())) {
                     return false;
                 }
-            } else if (!this->tryRemoveExpressionBefore(iter, &b.left())) {
+            } else if (!this->tryRemoveExpressionBefore(iter, b.fLeft.get())) {
                 return false;
             }
-            if (!this->tryRemoveExpressionBefore(iter, &b.right())) {
+            if (!this->tryRemoveExpressionBefore(iter, b.fRight.get())) {
                 return false;
             }
             SkASSERT((*iter)->expression()->get() == expr);
@@ -267,12 +267,11 @@
     switch ((*expr)->kind()) {
         case Expression::Kind::kBinary: {
             BinaryExpression& b = expr->get()->as<BinaryExpression>();
-            if (!this->tryInsertExpression(iter, &b.rightPointer())) {
+            if (!this->tryInsertExpression(iter, &b.fRight)) {
                 return false;
             }
-
             ++(*iter);
-            if (!this->tryInsertExpression(iter, &b.leftPointer())) {
+            if (!this->tryInsertExpression(iter, &b.fLeft)) {
                 return false;
             }
             ++(*iter);
@@ -320,17 +319,16 @@
     switch ((*e)->kind()) {
         case Expression::Kind::kBinary: {
             BinaryExpression& b = e->get()->as<BinaryExpression>();
-            Token::Kind op = b.getOperator();
-            switch (op) {
+            switch (b.fOperator) {
                 case Token::Kind::TK_LOGICALAND: // fall through
                 case Token::Kind::TK_LOGICALOR: {
                     // this isn't as precise as it could be -- we don't bother to track that if we
                     // early exit from a logical and/or, we know which branch of an 'if' we're going
                     // to hit -- but it won't make much difference in practice.
-                    this->addExpression(cfg, &b.leftPointer(), constantPropagate);
+                    this->addExpression(cfg, &b.fLeft, constantPropagate);
                     BlockId start = cfg.fCurrent;
                     cfg.newBlock();
-                    this->addExpression(cfg, &b.rightPointer(), constantPropagate);
+                    this->addExpression(cfg, &b.fRight, constantPropagate);
                     cfg.newBlock();
                     cfg.addExit(start, cfg.fCurrent);
                     cfg.fBlocks[cfg.fCurrent].fNodes.push_back({
@@ -342,8 +340,8 @@
                     break;
                 }
                 case Token::Kind::TK_EQ: {
-                    this->addExpression(cfg, &b.rightPointer(), constantPropagate);
-                    this->addLValue(cfg, &b.leftPointer());
+                    this->addExpression(cfg, &b.fRight, constantPropagate);
+                    this->addLValue(cfg, &b.fLeft);
                     cfg.fBlocks[cfg.fCurrent].fNodes.push_back({
                         BasicBlock::Node::kExpression_Kind,
                         constantPropagate,
@@ -353,8 +351,8 @@
                     break;
                 }
                 default:
-                    this->addExpression(cfg, &b.leftPointer(), !Compiler::IsAssignment(op));
-                    this->addExpression(cfg, &b.rightPointer(), constantPropagate);
+                    this->addExpression(cfg, &b.fLeft, !Compiler::IsAssignment(b.fOperator));
+                    this->addExpression(cfg, &b.fRight, constantPropagate);
                     cfg.fBlocks[cfg.fCurrent].fNodes.push_back({
                         BasicBlock::Node::kExpression_Kind,
                         constantPropagate,
diff --git a/src/sksl/SkSLCPPCodeGenerator.cpp b/src/sksl/SkSLCPPCodeGenerator.cpp
index a62374e..3eacb80 100644
--- a/src/sksl/SkSLCPPCodeGenerator.cpp
+++ b/src/sksl/SkSLCPPCodeGenerator.cpp
@@ -70,45 +70,42 @@
 
 void CPPCodeGenerator::writeBinaryExpression(const BinaryExpression& b,
                                              Precedence parentPrecedence) {
-    const Expression& left = b.left();
-    const Expression& right = b.right();
-    Token::Kind op = b.getOperator();
-    if (op == Token::Kind::TK_PERCENT) {
+    if (b.fOperator == Token::Kind::TK_PERCENT) {
         // need to use "%%" instead of "%" b/c the code will be inside of a printf
-        Precedence precedence = GetBinaryPrecedence(op);
+        Precedence precedence = GetBinaryPrecedence(b.fOperator);
         if (precedence >= parentPrecedence) {
             this->write("(");
         }
-        this->writeExpression(left, precedence);
+        this->writeExpression(*b.fLeft, precedence);
         this->write(" %% ");
-        this->writeExpression(right, precedence);
+        this->writeExpression(*b.fRight, precedence);
         if (precedence >= parentPrecedence) {
             this->write(")");
         }
-    } else if (left.kind() == Expression::Kind::kNullLiteral ||
-               right.kind() == Expression::Kind::kNullLiteral) {
+    } else if (b.fLeft->kind() == Expression::Kind::kNullLiteral ||
+               b.fRight->kind() == Expression::Kind::kNullLiteral) {
         const Variable* var;
-        if (left.kind() != Expression::Kind::kNullLiteral) {
-            var = &left.as<VariableReference>().fVariable;
+        if (b.fLeft->kind() != Expression::Kind::kNullLiteral) {
+            var = &b.fLeft->as<VariableReference>().fVariable;
         } else {
-            var = &right.as<VariableReference>().fVariable;
+            var = &b.fRight->as<VariableReference>().fVariable;
         }
         SkASSERT(var->type().typeKind() == Type::TypeKind::kNullable &&
                  var->type().componentType() == *fContext.fFragmentProcessor_Type);
         this->write("%s");
-        const char* prefix = "";
-        switch (op) {
+        const char* op = "";
+        switch (b.fOperator) {
             case Token::Kind::TK_EQEQ:
-                prefix = "!";
+                op = "!";
                 break;
             case Token::Kind::TK_NEQ:
-                prefix = "";
+                op = "";
                 break;
             default:
                 SkASSERT(false);
         }
         int childIndex = this->getChildFPIndex(*var);
-        fFormatArgs.push_back(String(prefix) + "_outer.childProcessor(" + to_string(childIndex) +
+        fFormatArgs.push_back(String(op) + "_outer.childProcessor(" + to_string(childIndex) +
                               ") ? \"true\" : \"false\"");
     } else {
         INHERITED::writeBinaryExpression(b, parentPrecedence);
diff --git a/src/sksl/SkSLCompiler.cpp b/src/sksl/SkSLCompiler.cpp
index 6bd8f74..0558688 100644
--- a/src/sksl/SkSLCompiler.cpp
+++ b/src/sksl/SkSLCompiler.cpp
@@ -436,11 +436,11 @@
             switch (expr->kind()) {
                 case Expression::Kind::kBinary: {
                     BinaryExpression* b = &expr->as<BinaryExpression>();
-                    if (b->getOperator() == Token::Kind::TK_EQ) {
-                        this->addDefinition(&b->left(), &b->rightPointer(), definitions);
-                    } else if (Compiler::IsAssignment(b->getOperator())) {
+                    if (b->fOperator == Token::Kind::TK_EQ) {
+                        this->addDefinition(b->fLeft.get(), &b->fRight, definitions);
+                    } else if (Compiler::IsAssignment(b->fOperator)) {
                         this->addDefinition(
-                                      &b->left(),
+                                      b->fLeft.get(),
                                       (std::unique_ptr<Expression>*) &fContext->fDefined_Expression,
                                       definitions);
 
@@ -607,10 +607,10 @@
  * to a dead target and lack of side effects on the left hand side.
  */
 static bool dead_assignment(const BinaryExpression& b) {
-    if (!Compiler::IsAssignment(b.getOperator())) {
+    if (!Compiler::IsAssignment(b.fOperator)) {
         return false;
     }
-    return is_dead(b.left());
+    return is_dead(*b.fLeft);
 }
 
 void Compiler::computeDataFlow(CFG* cfg) {
@@ -705,16 +705,14 @@
     *outUpdated = true;
     std::unique_ptr<Expression>* target = (*iter)->expression();
     BinaryExpression& bin = (*target)->as<BinaryExpression>();
-    Expression& left = bin.left();
-    std::unique_ptr<Expression>& rightPointer = bin.rightPointer();
-    SkASSERT(!left.hasSideEffects());
+    SkASSERT(!bin.fLeft->hasSideEffects());
     bool result;
-    if (bin.getOperator() == Token::Kind::TK_EQ) {
-        result = b->tryRemoveLValueBefore(iter, &left);
+    if (bin.fOperator == Token::Kind::TK_EQ) {
+        result = b->tryRemoveLValueBefore(iter, bin.fLeft.get());
     } else {
-        result = b->tryRemoveExpressionBefore(iter, &left);
+        result = b->tryRemoveExpressionBefore(iter, bin.fLeft.get());
     }
-    *target = std::move(rightPointer);
+    *target = std::move(bin.fRight);
     if (!result) {
         *outNeedsRescan = true;
         return;
@@ -725,7 +723,7 @@
     }
     --(*iter);
     if ((*iter)->fKind != BasicBlock::Node::kExpression_Kind ||
-        (*iter)->expression() != &rightPointer) {
+        (*iter)->expression() != &bin.fRight) {
         *outNeedsRescan = true;
         return;
     }
@@ -744,22 +742,20 @@
     *outUpdated = true;
     std::unique_ptr<Expression>* target = (*iter)->expression();
     BinaryExpression& bin = (*target)->as<BinaryExpression>();
-    std::unique_ptr<Expression>& leftPointer = bin.leftPointer();
-    Expression& right = bin.right();
-    SkASSERT(!right.hasSideEffects());
-    if (!b->tryRemoveExpressionBefore(iter, &right)) {
-        *target = std::move(leftPointer);
+    SkASSERT(!bin.fRight->hasSideEffects());
+    if (!b->tryRemoveExpressionBefore(iter, bin.fRight.get())) {
+        *target = std::move(bin.fLeft);
         *outNeedsRescan = true;
         return;
     }
-    *target = std::move(leftPointer);
+    *target = std::move(bin.fLeft);
     if (*iter == b->fNodes.begin()) {
         *outNeedsRescan = true;
         return;
     }
     --(*iter);
     if (((*iter)->fKind != BasicBlock::Node::kExpression_Kind ||
-        (*iter)->expression() != &leftPointer)) {
+        (*iter)->expression() != &bin.fLeft)) {
         *outNeedsRescan = true;
         return;
     }
@@ -812,7 +808,7 @@
                            bool* outUpdated,
                            bool* outNeedsRescan) {
     BinaryExpression& bin = (*(*iter)->expression())->as<BinaryExpression>();
-    vectorize(b, iter, bin.right().type(), &bin.leftPointer(), outUpdated, outNeedsRescan);
+    vectorize(b, iter, bin.fRight->type(), &bin.fLeft, outUpdated, outNeedsRescan);
 }
 
 /**
@@ -824,7 +820,7 @@
                             bool* outUpdated,
                             bool* outNeedsRescan) {
     BinaryExpression& bin = (*(*iter)->expression())->as<BinaryExpression>();
-    vectorize(b, iter, bin.left().type(), &bin.rightPointer(), outUpdated, outNeedsRescan);
+    vectorize(b, iter, bin.fLeft->type(), &bin.fRight, outUpdated, outNeedsRescan);
 }
 
 // Mark that an expression which we were writing to is no longer being written to
@@ -906,10 +902,8 @@
                 delete_left(&b, iter, outUpdated, outNeedsRescan);
                 break;
             }
-            Expression& left = bin->left();
-            Expression& right = bin->right();
-            const Type& leftType = left.type();
-            const Type& rightType = right.type();
+            const Type& leftType = bin->fLeft->type();
+            const Type& rightType = bin->fRight->type();
             // collapse useless expressions like x * 1 or x + 0
             if (((leftType.typeKind() != Type::TypeKind::kScalar) &&
                  (leftType.typeKind() != Type::TypeKind::kVector)) ||
@@ -917,9 +911,9 @@
                  (rightType.typeKind() != Type::TypeKind::kVector))) {
                 break;
             }
-            switch (bin->getOperator()) {
+            switch (bin->fOperator) {
                 case Token::Kind::TK_STAR:
-                    if (is_constant(left, 1)) {
+                    if (is_constant(*bin->fLeft, 1)) {
                         if (leftType.typeKind() == Type::TypeKind::kVector &&
                             rightType.typeKind() == Type::TypeKind::kScalar) {
                             // float4(1) * x -> float4(x)
@@ -931,22 +925,22 @@
                             delete_left(&b, iter, outUpdated, outNeedsRescan);
                         }
                     }
-                    else if (is_constant(left, 0)) {
+                    else if (is_constant(*bin->fLeft, 0)) {
                         if (leftType.typeKind() == Type::TypeKind::kScalar &&
                             rightType.typeKind() == Type::TypeKind::kVector &&
-                            !right.hasSideEffects()) {
+                            !bin->fRight->hasSideEffects()) {
                             // 0 * float4(x) -> float4(0)
                             vectorize_left(&b, iter, outUpdated, outNeedsRescan);
                         } else {
                             // 0 * x -> 0
                             // float4(0) * x -> float4(0)
                             // float4(0) * float4(x) -> float4(0)
-                            if (!right.hasSideEffects()) {
+                            if (!bin->fRight->hasSideEffects()) {
                                 delete_right(&b, iter, outUpdated, outNeedsRescan);
                             }
                         }
                     }
-                    else if (is_constant(right, 1)) {
+                    else if (is_constant(*bin->fRight, 1)) {
                         if (leftType.typeKind() == Type::TypeKind::kScalar &&
                             rightType.typeKind() == Type::TypeKind::kVector) {
                             // x * float4(1) -> float4(x)
@@ -958,24 +952,24 @@
                             delete_right(&b, iter, outUpdated, outNeedsRescan);
                         }
                     }
-                    else if (is_constant(right, 0)) {
+                    else if (is_constant(*bin->fRight, 0)) {
                         if (leftType.typeKind() == Type::TypeKind::kVector &&
                             rightType.typeKind() == Type::TypeKind::kScalar &&
-                            !left.hasSideEffects()) {
+                            !bin->fLeft->hasSideEffects()) {
                             // float4(x) * 0 -> float4(0)
                             vectorize_right(&b, iter, outUpdated, outNeedsRescan);
                         } else {
                             // x * 0 -> 0
                             // x * float4(0) -> float4(0)
                             // float4(x) * float4(0) -> float4(0)
-                            if (!left.hasSideEffects()) {
+                            if (!bin->fLeft->hasSideEffects()) {
                                 delete_left(&b, iter, outUpdated, outNeedsRescan);
                             }
                         }
                     }
                     break;
                 case Token::Kind::TK_PLUS:
-                    if (is_constant(left, 0)) {
+                    if (is_constant(*bin->fLeft, 0)) {
                         if (leftType.typeKind() == Type::TypeKind::kVector &&
                             rightType.typeKind() == Type::TypeKind::kScalar) {
                             // float4(0) + x -> float4(x)
@@ -986,7 +980,7 @@
                             // float4(0) + float4(x) -> float4(x)
                             delete_left(&b, iter, outUpdated, outNeedsRescan);
                         }
-                    } else if (is_constant(right, 0)) {
+                    } else if (is_constant(*bin->fRight, 0)) {
                         if (leftType.typeKind() == Type::TypeKind::kScalar &&
                             rightType.typeKind() == Type::TypeKind::kVector) {
                             // x + float4(0) -> float4(x)
@@ -1000,7 +994,7 @@
                     }
                     break;
                 case Token::Kind::TK_MINUS:
-                    if (is_constant(right, 0)) {
+                    if (is_constant(*bin->fRight, 0)) {
                         if (leftType.typeKind() == Type::TypeKind::kScalar &&
                             rightType.typeKind() == Type::TypeKind::kVector) {
                             // x - float4(0) -> float4(x)
@@ -1014,7 +1008,7 @@
                     }
                     break;
                 case Token::Kind::TK_SLASH:
-                    if (is_constant(right, 1)) {
+                    if (is_constant(*bin->fRight, 1)) {
                         if (leftType.typeKind() == Type::TypeKind::kScalar &&
                             rightType.typeKind() == Type::TypeKind::kVector) {
                             // x / float4(1) -> float4(x)
@@ -1025,43 +1019,43 @@
                             // float4(x) / float4(1) -> float4(x)
                             delete_right(&b, iter, outUpdated, outNeedsRescan);
                         }
-                    } else if (is_constant(left, 0)) {
+                    } else if (is_constant(*bin->fLeft, 0)) {
                         if (leftType.typeKind() == Type::TypeKind::kScalar &&
                             rightType.typeKind() == Type::TypeKind::kVector &&
-                            !right.hasSideEffects()) {
+                            !bin->fRight->hasSideEffects()) {
                             // 0 / float4(x) -> float4(0)
                             vectorize_left(&b, iter, outUpdated, outNeedsRescan);
                         } else {
                             // 0 / x -> 0
                             // float4(0) / x -> float4(0)
                             // float4(0) / float4(x) -> float4(0)
-                            if (!right.hasSideEffects()) {
+                            if (!bin->fRight->hasSideEffects()) {
                                 delete_right(&b, iter, outUpdated, outNeedsRescan);
                             }
                         }
                     }
                     break;
                 case Token::Kind::TK_PLUSEQ:
-                    if (is_constant(right, 0)) {
-                        clear_write(left);
+                    if (is_constant(*bin->fRight, 0)) {
+                        clear_write(*bin->fLeft);
                         delete_right(&b, iter, outUpdated, outNeedsRescan);
                     }
                     break;
                 case Token::Kind::TK_MINUSEQ:
-                    if (is_constant(right, 0)) {
-                        clear_write(left);
+                    if (is_constant(*bin->fRight, 0)) {
+                        clear_write(*bin->fLeft);
                         delete_right(&b, iter, outUpdated, outNeedsRescan);
                     }
                     break;
                 case Token::Kind::TK_STAREQ:
-                    if (is_constant(right, 1)) {
-                        clear_write(left);
+                    if (is_constant(*bin->fRight, 1)) {
+                        clear_write(*bin->fLeft);
                         delete_right(&b, iter, outUpdated, outNeedsRescan);
                     }
                     break;
                 case Token::Kind::TK_SLASHEQ:
-                    if (is_constant(right, 1)) {
-                        clear_write(left);
+                    if (is_constant(*bin->fRight, 1)) {
+                        clear_write(*bin->fLeft);
                         delete_right(&b, iter, outUpdated, outNeedsRescan);
                     }
                     break;
diff --git a/src/sksl/SkSLDehydrator.cpp b/src/sksl/SkSLDehydrator.cpp
index b320343..4f93647 100644
--- a/src/sksl/SkSLDehydrator.cpp
+++ b/src/sksl/SkSLDehydrator.cpp
@@ -258,9 +258,9 @@
             case Expression::Kind::kBinary: {
                 const BinaryExpression& b = e->as<BinaryExpression>();
                 this->writeU8(Rehydrator::kBinary_Command);
-                this->write(&b.left());
-                this->writeU8((int) b.getOperator());
-                this->write(&b.right());
+                this->write(b.fLeft.get());
+                this->writeU8((int) b.fOperator);
+                this->write(b.fRight.get());
                 this->write(b.type());
                 break;
             }
diff --git a/src/sksl/SkSLGLSLCodeGenerator.cpp b/src/sksl/SkSLGLSLCodeGenerator.cpp
index 6ef3b9b..433b11b 100644
--- a/src/sksl/SkSLGLSLCodeGenerator.cpp
+++ b/src/sksl/SkSLGLSLCodeGenerator.cpp
@@ -913,33 +913,31 @@
 
 void GLSLCodeGenerator::writeBinaryExpression(const BinaryExpression& b,
                                               Precedence parentPrecedence) {
-    const Expression& left = b.left();
-    const Expression& right = b.right();
-    Token::Kind op = b.getOperator();
     if (fProgram.fSettings.fCaps->unfoldShortCircuitAsTernary() &&
-            (op == Token::Kind::TK_LOGICALAND || op == Token::Kind::TK_LOGICALOR)) {
+            (b.fOperator == Token::Kind::TK_LOGICALAND ||
+             b.fOperator == Token::Kind::TK_LOGICALOR)) {
         this->writeShortCircuitWorkaroundExpression(b, parentPrecedence);
         return;
     }
 
-    Precedence precedence = GetBinaryPrecedence(op);
+    Precedence precedence = GetBinaryPrecedence(b.fOperator);
     if (precedence >= parentPrecedence) {
         this->write("(");
     }
     bool positionWorkaround = fProgramKind == Program::Kind::kVertex_Kind &&
-                              Compiler::IsAssignment(op) &&
-                              left.kind() == Expression::Kind::kFieldAccess &&
-                              is_sk_position((FieldAccess&) left) &&
-                              !right.containsRTAdjust() &&
+                              Compiler::IsAssignment(b.fOperator) &&
+                              b.fLeft->kind() == Expression::Kind::kFieldAccess &&
+                              is_sk_position((FieldAccess&) *b.fLeft) &&
+                              !b.fRight->containsRTAdjust() &&
                               !fProgram.fSettings.fCaps->canUseFragCoord();
     if (positionWorkaround) {
         this->write("sk_FragCoord_Workaround = (");
     }
-    this->writeExpression(left, precedence);
+    this->writeExpression(*b.fLeft, precedence);
     this->write(" ");
-    this->write(Compiler::OperatorName(op));
+    this->write(Compiler::OperatorName(b.fOperator));
     this->write(" ");
-    this->writeExpression(right, precedence);
+    this->writeExpression(*b.fRight, precedence);
     if (positionWorkaround) {
         this->write(")");
     }
@@ -957,20 +955,20 @@
     // Transform:
     // a && b  =>   a ? b : false
     // a || b  =>   a ? true : b
-    this->writeExpression(b.left(), kTernary_Precedence);
+    this->writeExpression(*b.fLeft, kTernary_Precedence);
     this->write(" ? ");
-    if (b.getOperator() == Token::Kind::TK_LOGICALAND) {
-        this->writeExpression(b.right(), kTernary_Precedence);
+    if (b.fOperator == Token::Kind::TK_LOGICALAND) {
+        this->writeExpression(*b.fRight, kTernary_Precedence);
     } else {
         BoolLiteral boolTrue(fContext, -1, true);
         this->writeBoolLiteral(boolTrue);
     }
     this->write(" : ");
-    if (b.getOperator() == Token::Kind::TK_LOGICALAND) {
+    if (b.fOperator == Token::Kind::TK_LOGICALAND) {
         BoolLiteral boolFalse(fContext, -1, false);
         this->writeBoolLiteral(boolFalse);
     } else {
-        this->writeExpression(b.right(), kTernary_Precedence);
+        this->writeExpression(*b.fRight, kTernary_Precedence);
     }
     if (kTernary_Precedence >= parentPrecedence) {
         this->write(")");
diff --git a/src/sksl/SkSLInliner.cpp b/src/sksl/SkSLInliner.cpp
index 4761329..5ede14d 100644
--- a/src/sksl/SkSLInliner.cpp
+++ b/src/sksl/SkSLInliner.cpp
@@ -308,9 +308,9 @@
         case Expression::Kind::kBinary: {
             const BinaryExpression& b = expression.as<BinaryExpression>();
             return std::make_unique<BinaryExpression>(offset,
-                                                      expr(b.leftPointer()),
-                                                      b.getOperator(),
-                                                      expr(b.rightPointer()),
+                                                      expr(b.fLeft),
+                                                      b.fOperator,
+                                                      expr(b.fRight),
                                                       &b.type());
         }
         case Expression::Kind::kBoolLiteral:
@@ -938,7 +938,7 @@
 
                 case Expression::Kind::kBinary: {
                     BinaryExpression& binaryExpr = (*expr)->as<BinaryExpression>();
-                    this->visitExpression(&binaryExpr.leftPointer());
+                    this->visitExpression(&binaryExpr.fLeft);
 
                     // Logical-and and logical-or binary expressions do not inline the right side,
                     // because that would invalidate short-circuiting. That is, when evaluating
@@ -948,11 +948,10 @@
                     // It is illegal for side-effects from x() or y() to occur. The simplest way to
                     // enforce that rule is to avoid inlining the right side entirely. However, it
                     // is safe for other types of binary expression to inline both sides.
-                    Token::Kind op = binaryExpr.getOperator();
-                    bool shortCircuitable = (op == Token::Kind::TK_LOGICALAND ||
-                                             op == Token::Kind::TK_LOGICALOR);
+                    bool shortCircuitable = (binaryExpr.fOperator == Token::Kind::TK_LOGICALAND ||
+                                             binaryExpr.fOperator == Token::Kind::TK_LOGICALOR);
                     if (!shortCircuitable) {
-                        this->visitExpression(&binaryExpr.rightPointer());
+                        this->visitExpression(&binaryExpr.fRight);
                     }
                     break;
                 }
diff --git a/src/sksl/SkSLMetalCodeGenerator.cpp b/src/sksl/SkSLMetalCodeGenerator.cpp
index 1ee05a4..d573c38 100644
--- a/src/sksl/SkSLMetalCodeGenerator.cpp
+++ b/src/sksl/SkSLMetalCodeGenerator.cpp
@@ -808,14 +808,11 @@
 
 void MetalCodeGenerator::writeBinaryExpression(const BinaryExpression& b,
                                                Precedence parentPrecedence) {
-    const Expression& left = b.left();
-    const Expression& right = b.right();
-    const Type& leftType = left.type();
-    const Type& rightType = right.type();
-    Token::Kind op = b.getOperator();
-    Precedence precedence = GetBinaryPrecedence(b.getOperator());
+    const Type& leftType = b.fLeft->type();
+    const Type& rightType = b.fRight->type();
+    Precedence precedence = GetBinaryPrecedence(b.fOperator);
     bool needParens = precedence >= parentPrecedence;
-    switch (op) {
+    switch (b.fOperator) {
         case Token::Kind::TK_EQEQ:
             if (leftType.typeKind() == Type::TypeKind::kVector) {
                 this->write("all");
@@ -834,21 +831,22 @@
     if (needParens) {
         this->write("(");
     }
-    if (Compiler::IsAssignment(op) &&
-        Expression::Kind::kVariableReference == left.kind() &&
-        Variable::kParameter_Storage == left.as<VariableReference>().fVariable.fStorage &&
-        left.as<VariableReference>().fVariable.fModifiers.fFlags & Modifiers::kOut_Flag) {
+    if (Compiler::IsAssignment(b.fOperator) &&
+        Expression::Kind::kVariableReference == b.fLeft->kind() &&
+        Variable::kParameter_Storage == ((VariableReference&) *b.fLeft).fVariable.fStorage &&
+        (((VariableReference&) *b.fLeft).fVariable.fModifiers.fFlags & Modifiers::kOut_Flag)) {
         // writing to an out parameter. Since we have to turn those into pointers, we have to
         // dereference it here.
         this->write("*");
     }
-    if (op == Token::Kind::TK_STAREQ && leftType.typeKind() == Type::TypeKind::kMatrix &&
+    if (b.fOperator == Token::Kind::TK_STAREQ &&
+        leftType.typeKind() == Type::TypeKind::kMatrix &&
         rightType.typeKind() == Type::TypeKind::kMatrix) {
         this->writeMatrixTimesEqualHelper(leftType, rightType, b.type());
     }
-    this->writeExpression(left, precedence);
-    if (op != Token::Kind::TK_EQ && Compiler::IsAssignment(op) &&
-        left.kind() == Expression::Kind::kSwizzle && !left.hasSideEffects()) {
+    this->writeExpression(*b.fLeft, precedence);
+    if (b.fOperator != Token::Kind::TK_EQ && Compiler::IsAssignment(b.fOperator) &&
+        b.fLeft->kind() == Expression::Kind::kSwizzle && !b.fLeft->hasSideEffects()) {
         // This doesn't compile in Metal:
         // float4 x = float4(1);
         // x.xy *= float2x2(...);
@@ -856,16 +854,16 @@
         // but switching it to x.xy = x.xy * float2x2(...) fixes it. We perform this tranformation
         // as long as the LHS has no side effects, and hope for the best otherwise.
         this->write(" = ");
-        this->writeExpression(left, kAssignment_Precedence);
+        this->writeExpression(*b.fLeft, kAssignment_Precedence);
         this->write(" ");
-        String opName = Compiler::OperatorName(op);
-        SkASSERT(opName.endsWith("="));
-        this->write(opName.substr(0, opName.size() - 1).c_str());
+        String op = Compiler::OperatorName(b.fOperator);
+        SkASSERT(op.endsWith("="));
+        this->write(op.substr(0, op.size() - 1).c_str());
         this->write(" ");
     } else {
-        this->write(String(" ") + Compiler::OperatorName(op) + " ");
+        this->write(String(" ") + Compiler::OperatorName(b.fOperator) + " ");
     }
-    this->writeExpression(right, precedence);
+    this->writeExpression(*b.fRight, precedence);
     if (needParens) {
         this->write(")");
     }
@@ -1732,8 +1730,8 @@
             return this->requirements(e->as<Swizzle>().fBase.get());
         case Expression::Kind::kBinary: {
             const BinaryExpression& bin = e->as<BinaryExpression>();
-            return this->requirements(&bin.left()) |
-                   this->requirements(&bin.right());
+            return this->requirements(bin.fLeft.get()) |
+                   this->requirements(bin.fRight.get());
         }
         case Expression::Kind::kIndex: {
             const IndexExpression& idx = e->as<IndexExpression>();
diff --git a/src/sksl/SkSLSPIRVCodeGenerator.cpp b/src/sksl/SkSLSPIRVCodeGenerator.cpp
index 6e07dfb..ab3d709 100644
--- a/src/sksl/SkSLSPIRVCodeGenerator.cpp
+++ b/src/sksl/SkSLSPIRVCodeGenerator.cpp
@@ -2302,14 +2302,11 @@
 }
 
 SpvId SPIRVCodeGenerator::writeBinaryExpression(const BinaryExpression& b, OutputStream& out) {
-    const Expression& left = b.left();
-    const Expression& right = b.right();
-    Token::Kind op = b.getOperator();
     // handle cases where we don't necessarily evaluate both LHS and RHS
-    switch (op) {
+    switch (b.fOperator) {
         case Token::Kind::TK_EQ: {
-            SpvId rhs = this->writeExpression(right, out);
-            this->getLValue(left, out)->store(rhs, out);
+            SpvId rhs = this->writeExpression(*b.fRight, out);
+            this->getLValue(*b.fLeft, out)->store(rhs, out);
             return rhs;
         }
         case Token::Kind::TK_LOGICALAND:
@@ -2322,16 +2319,17 @@
 
     std::unique_ptr<LValue> lvalue;
     SpvId lhs;
-    if (Compiler::IsAssignment(op)) {
-        lvalue = this->getLValue(left, out);
+    if (Compiler::IsAssignment(b.fOperator)) {
+        lvalue = this->getLValue(*b.fLeft, out);
         lhs = lvalue->load(out);
     } else {
         lvalue = nullptr;
-        lhs = this->writeExpression(left, out);
+        lhs = this->writeExpression(*b.fLeft, out);
     }
-    SpvId rhs = this->writeExpression(right, out);
-    SpvId result = this->writeBinaryExpression(left.type(), lhs, Compiler::RemoveAssignment(op),
-                                               right.type(), rhs, b.type(), out);
+    SpvId rhs = this->writeExpression(*b.fRight, out);
+    SpvId result = this->writeBinaryExpression(b.fLeft->type(), lhs,
+                                               Compiler::RemoveAssignment(b.fOperator),
+                                               b.fRight->type(), rhs, b.type(), out);
     if (lvalue) {
         lvalue->store(result, out);
     }
@@ -2339,17 +2337,17 @@
 }
 
 SpvId SPIRVCodeGenerator::writeLogicalAnd(const BinaryExpression& a, OutputStream& out) {
-    SkASSERT(a.getOperator() == Token::Kind::TK_LOGICALAND);
+    SkASSERT(a.fOperator == Token::Kind::TK_LOGICALAND);
     BoolLiteral falseLiteral(fContext, -1, false);
     SpvId falseConstant = this->writeBoolLiteral(falseLiteral);
-    SpvId lhs = this->writeExpression(a.left(), out);
+    SpvId lhs = this->writeExpression(*a.fLeft, out);
     SpvId rhsLabel = this->nextId();
     SpvId end = this->nextId();
     SpvId lhsBlock = fCurrentBlock;
     this->writeInstruction(SpvOpSelectionMerge, end, SpvSelectionControlMaskNone, out);
     this->writeInstruction(SpvOpBranchConditional, lhs, rhsLabel, end, out);
     this->writeLabel(rhsLabel, out);
-    SpvId rhs = this->writeExpression(a.right(), out);
+    SpvId rhs = this->writeExpression(*a.fRight, out);
     SpvId rhsBlock = fCurrentBlock;
     this->writeInstruction(SpvOpBranch, end, out);
     this->writeLabel(end, out);
@@ -2360,17 +2358,17 @@
 }
 
 SpvId SPIRVCodeGenerator::writeLogicalOr(const BinaryExpression& o, OutputStream& out) {
-    SkASSERT(o.getOperator() == Token::Kind::TK_LOGICALOR);
+    SkASSERT(o.fOperator == Token::Kind::TK_LOGICALOR);
     BoolLiteral trueLiteral(fContext, -1, true);
     SpvId trueConstant = this->writeBoolLiteral(trueLiteral);
-    SpvId lhs = this->writeExpression(o.left(), out);
+    SpvId lhs = this->writeExpression(*o.fLeft, out);
     SpvId rhsLabel = this->nextId();
     SpvId end = this->nextId();
     SpvId lhsBlock = fCurrentBlock;
     this->writeInstruction(SpvOpSelectionMerge, end, SpvSelectionControlMaskNone, out);
     this->writeInstruction(SpvOpBranchConditional, lhs, end, rhsLabel, out);
     this->writeLabel(rhsLabel, out);
-    SpvId rhs = this->writeExpression(o.right(), out);
+    SpvId rhs = this->writeExpression(*o.fRight, out);
     SpvId rhsBlock = fCurrentBlock;
     this->writeInstruction(SpvOpBranch, end, out);
     this->writeLabel(end, out);
diff --git a/src/sksl/ir/SkSLBinaryExpression.h b/src/sksl/ir/SkSLBinaryExpression.h
index 47ccd7a..18ce2b7 100644
--- a/src/sksl/ir/SkSLBinaryExpression.h
+++ b/src/sksl/ir/SkSLBinaryExpression.h
@@ -19,24 +19,24 @@
 
 namespace SkSL {
 
-static inline bool check_ref(const Expression& expr) {
-    switch (expr.kind()) {
+static inline bool check_ref(Expression* expr) {
+    switch (expr->kind()) {
         case Expression::Kind::kExternalValue:
             return true;
         case Expression::Kind::kFieldAccess:
-            return check_ref(*expr.as<FieldAccess>().fBase);
+            return check_ref(((FieldAccess*) expr)->fBase.get());
         case Expression::Kind::kIndex:
-            return check_ref(*expr.as<IndexExpression>().fBase);
+            return check_ref(((IndexExpression*) expr)->fBase.get());
         case Expression::Kind::kSwizzle:
-            return check_ref(*expr.as<Swizzle>().fBase);
+            return check_ref(((Swizzle*) expr)->fBase.get());
         case Expression::Kind::kTernary: {
-            const TernaryExpression& t = expr.as<TernaryExpression>();
-            return check_ref(*t.fIfTrue) && check_ref(*t.fIfFalse);
+            TernaryExpression* t = (TernaryExpression*) expr;
+            return check_ref(t->fIfTrue.get()) && check_ref(t->fIfFalse.get());
         }
         case Expression::Kind::kVariableReference: {
-            const VariableReference& ref = expr.as<VariableReference>();
-            return ref.fRefKind == VariableReference::kWrite_RefKind ||
-                   ref.fRefKind == VariableReference::kReadWrite_RefKind;
+            VariableReference* ref = (VariableReference*) expr;
+            return ref->fRefKind == VariableReference::kWrite_RefKind ||
+                   ref->fRefKind == VariableReference::kReadWrite_RefKind;
         }
         default:
             return false;
@@ -51,75 +51,46 @@
 
     BinaryExpression(int offset, std::unique_ptr<Expression> left, Token::Kind op,
                      std::unique_ptr<Expression> right, const Type* type)
-    : INHERITED(offset, kExpressionKind, { type, op }) {
-        fExpressionChildren.reserve(2);
-        fExpressionChildren.push_back(std::move(left));
-        fExpressionChildren.push_back(std::move(right));
+    : INHERITED(offset, kExpressionKind, type)
+    , fLeft(std::move(left))
+    , fOperator(op)
+    , fRight(std::move(right)) {
         // If we are assigning to a VariableReference, ensure that it is set to Write or ReadWrite
-        SkASSERT(!Compiler::IsAssignment(op) || check_ref(this->left()));
-    }
-
-    Expression& left() const {
-        return this->expressionChild(0);
-    }
-
-    std::unique_ptr<Expression>& leftPointer() {
-        return this->expressionPointer(0);
-    }
-
-    const std::unique_ptr<Expression>& leftPointer() const {
-        return this->expressionPointer(0);
-    }
-
-    Expression& right() const {
-        return this->expressionChild(1);
-    }
-
-    std::unique_ptr<Expression>& rightPointer() {
-        return this->expressionPointer(1);
-    }
-
-    const std::unique_ptr<Expression>& rightPointer() const {
-        return this->expressionPointer(1);
-    }
-
-    Token::Kind getOperator() const {
-        return this->typeTokenData().fToken;
+        SkASSERT(!Compiler::IsAssignment(op) || check_ref(fLeft.get()));
     }
 
     bool isConstantOrUniform() const override {
-        return this->left().isConstantOrUniform() && this->right().isConstantOrUniform();
+        return fLeft->isConstantOrUniform() && fRight->isConstantOrUniform();
     }
 
     std::unique_ptr<Expression> constantPropagate(const IRGenerator& irGenerator,
                                                   const DefinitionMap& definitions) override {
-        return irGenerator.constantFold(this->left(),
-                                        this->getOperator(),
-                                        this->right());
+        return irGenerator.constantFold(*fLeft,
+                                        fOperator,
+                                        *fRight);
     }
 
     bool hasProperty(Property property) const override {
-        if (property == Property::kSideEffects && Compiler::IsAssignment(this->getOperator())) {
+        if (property == Property::kSideEffects && Compiler::IsAssignment(fOperator)) {
             return true;
         }
-        return this->left().hasProperty(property) || this->right().hasProperty(property);
+        return fLeft->hasProperty(property) || fRight->hasProperty(property);
     }
 
     std::unique_ptr<Expression> clone() const override {
-        return std::unique_ptr<Expression>(new BinaryExpression(fOffset,
-                                                                this->left().clone(),
-                                                                this->getOperator(),
-                                                                this->right().clone(),
-                                                                &this->type()));
+        return std::unique_ptr<Expression>(new BinaryExpression(fOffset, fLeft->clone(), fOperator,
+                                                                fRight->clone(), &this->type()));
     }
 
     String description() const override {
-        return "(" + this->left().description() + " " +
-               Compiler::OperatorName(this->getOperator()) + " " + this->right().description() +
-               ")";
+        return "(" + fLeft->description() + " " + Compiler::OperatorName(fOperator) + " " +
+               fRight->description() + ")";
     }
 
-private:
+    std::unique_ptr<Expression> fLeft;
+    const Token::Kind fOperator;
+    std::unique_ptr<Expression> fRight;
+
     using INHERITED = Expression;
 };
 
diff --git a/src/sksl/ir/SkSLExpression.h b/src/sksl/ir/SkSLExpression.h
index 14c9708..7beb341 100644
--- a/src/sksl/ir/SkSLExpression.h
+++ b/src/sksl/ir/SkSLExpression.h
@@ -57,12 +57,7 @@
     };
 
     Expression(int offset, Kind kind, const Type* type)
-        : INHERITED(offset, (int) kind, type) {
-        SkASSERT(kind >= Kind::kFirst && kind <= Kind::kLast);
-    }
-
-    Expression(int offset, Kind kind, TypeTokenData data)
-        : INHERITED(offset, (int) kind, data) {
+    : INHERITED(offset, (int) kind, type) {
         SkASSERT(kind >= Kind::kFirst && kind <= Kind::kLast);
     }
 
diff --git a/src/sksl/ir/SkSLIRNode.cpp b/src/sksl/ir/SkSLIRNode.cpp
deleted file mode 100644
index 19eaf8b..0000000
--- a/src/sksl/ir/SkSLIRNode.cpp
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright 2020 Google LLC.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "src/sksl/ir/SkSLIRNode.h"
-
-#include "src/sksl/ir/SkSLExpression.h"
-
-namespace SkSL {
-
-IRNode::IRNode(int offset, int kind, const Type* data)
-: fOffset(offset)
-, fKind(kind)
-, fData(data) {}
-
-IRNode::IRNode(int offset, int kind, TypeTokenData data)
-: fOffset(offset)
-, fKind(kind)
-, fData(data) {}
-
-IRNode::IRNode(const IRNode& other)
-    : fOffset(other.fOffset)
-    , fKind(other.fKind)
-    , fData(other.fData) {
-    // For now, we can't use a default copy constructor because of the std::unique_ptr children.
-    // Since we never copy nodes containing children, it's easiest just to assert we don't have any
-    // than bother with cloning them.
-    SkASSERT(other.fExpressionChildren.empty());
-}
-
-IRNode::~IRNode() {}
-
-} // namespace SkSL
diff --git a/src/sksl/ir/SkSLIRNode.h b/src/sksl/ir/SkSLIRNode.h
index b43ee06..4a6aa90 100644
--- a/src/sksl/ir/SkSLIRNode.h
+++ b/src/sksl/ir/SkSLIRNode.h
@@ -8,16 +8,11 @@
 #ifndef SKSL_IRNODE
 #define SKSL_IRNODE
 
-#include "src/sksl/SkSLASTNode.h"
 #include "src/sksl/SkSLLexer.h"
 #include "src/sksl/SkSLString.h"
 
-#include <algorithm>
-#include <vector>
-
 namespace SkSL {
 
-struct Expression;
 class Type;
 
 /**
@@ -26,19 +21,12 @@
  */
 class IRNode {
 public:
-    virtual ~IRNode();
+    IRNode(int offset, int kind, const Type* type = nullptr)
+    : fOffset(offset)
+    , fKind(kind)
+    , fType(type) {}
 
-    IRNode& operator=(const IRNode& other) {
-        // Need to have a copy assignment operator because Type requires it, but can't use the
-        // default version until we finish migrating away from std::unique_ptr children. For now,
-        // just assert that there are no children (we could theoretically clone them, but we never
-        // actually copy nodes containing children).
-        SkASSERT(other.fExpressionChildren.empty());
-        fKind = other.fKind;
-        fOffset = other.fOffset;
-        fData = other.fData;
-        return *this;
-    }
+    virtual ~IRNode() {}
 
     virtual String description() const = 0;
 
@@ -47,81 +35,15 @@
     int fOffset;
 
     const Type& type() const {
-        switch (fData.fKind) {
-            case NodeData::Kind::kType:
-                return *this->typeData();
-            case NodeData::Kind::kTypeToken:
-                return *this->typeTokenData().fType;
-            default:
-                SkUNREACHABLE;
-        }
+        SkASSERT(fType);
+        return *fType;
     }
 
 protected:
-    struct TypeTokenData {
-        const Type* fType;
-        Token::Kind fToken;
-    };
-
-    struct NodeData {
-        char fBytes[std::max(sizeof(Type*),
-                             sizeof(TypeTokenData))];
-
-        enum class Kind {
-            kType,
-            kTypeToken,
-        } fKind;
-
-        NodeData() = default;
-
-        NodeData(const Type* data)
-            : fKind(Kind::kType) {
-            memcpy(fBytes, &data, sizeof(data));
-        }
-
-        NodeData(TypeTokenData data)
-            : fKind(Kind::kTypeToken) {
-            memcpy(fBytes, &data, sizeof(data));
-        }
-    };
-
-    IRNode(int offset, int kind, const Type* data = nullptr);
-
-    IRNode(int offset, int kind, TypeTokenData data);
-
-    IRNode(const IRNode& other);
-
-    Expression& expressionChild(int index) const {
-        return *fExpressionChildren[index];
-    }
-
-    std::unique_ptr<Expression>& expressionPointer(int index) {
-        return fExpressionChildren[index];
-    }
-
-    const std::unique_ptr<Expression>& expressionPointer(int index) const {
-        return fExpressionChildren[index];
-    }
-
-    Type* typeData() const {
-        SkASSERT(fData.fKind == NodeData::Kind::kType);
-        Type* result;
-        memcpy(&result, fData.fBytes, sizeof(result));
-        return result;
-    }
-
-    TypeTokenData typeTokenData() const {
-        SkASSERT(fData.fKind == NodeData::Kind::kTypeToken);
-        TypeTokenData result;
-        memcpy(&result, fData.fBytes, sizeof(result));
-        return result;
-    }
-
     int fKind;
-    std::vector<std::unique_ptr<Expression>> fExpressionChildren;
 
 private:
-    NodeData fData;
+    const Type* fType;
 };
 
 }  // namespace SkSL