Use the IntrinsicKind to look up Metal intrinsic calls.

We no longer need to maintain a separate mapping table of intrinsic
function names in Metal.

Change-Id: Ib14b76d3a47a396c4a09adb11e0fd3c144501032
Bug: skia:11961
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/405236
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
diff --git a/src/sksl/codegen/SkSLMetalCodeGenerator.cpp b/src/sksl/codegen/SkSLMetalCodeGenerator.cpp
index fe85ce7..87204f4 100644
--- a/src/sksl/codegen/SkSLMetalCodeGenerator.cpp
+++ b/src/sksl/codegen/SkSLMetalCodeGenerator.cpp
@@ -44,40 +44,6 @@
     virtual void visitVariable(const Variable& var, const Expression* value) = 0;
 };
 
-void MetalCodeGenerator::setupIntrinsics() {
-    fIntrinsicMap[String("atan")]               = kAtan_IntrinsicKind;
-    fIntrinsicMap[String("floatBitsToInt")]     = kBitcast_IntrinsicKind;
-    fIntrinsicMap[String("floatBitsToUint")]    = kBitcast_IntrinsicKind;
-    fIntrinsicMap[String("intBitsToFloat")]     = kBitcast_IntrinsicKind;
-    fIntrinsicMap[String("uintBitsToFloat")]    = kBitcast_IntrinsicKind;
-    fIntrinsicMap[String("equal")]              = kCompareEqual_IntrinsicKind;
-    fIntrinsicMap[String("notEqual")]           = kCompareNotEqual_IntrinsicKind;
-    fIntrinsicMap[String("lessThan")]           = kCompareLessThan_IntrinsicKind;
-    fIntrinsicMap[String("lessThanEqual")]      = kCompareLessThanEqual_IntrinsicKind;
-    fIntrinsicMap[String("greaterThan")]        = kCompareGreaterThan_IntrinsicKind;
-    fIntrinsicMap[String("greaterThanEqual")]   = kCompareGreaterThanEqual_IntrinsicKind;
-    fIntrinsicMap[String("degrees")]            = kDegrees_IntrinsicKind;
-    fIntrinsicMap[String("dFdx")]               = kDFdx_IntrinsicKind;
-    fIntrinsicMap[String("dFdy")]               = kDFdy_IntrinsicKind;
-    fIntrinsicMap[String("distance")]           = kDistance_IntrinsicKind;
-    fIntrinsicMap[String("dot")]                = kDot_IntrinsicKind;
-    fIntrinsicMap[String("faceforward")]        = kFaceforward_IntrinsicKind;
-    fIntrinsicMap[String("bitCount")]           = kBitCount_IntrinsicKind;
-    fIntrinsicMap[String("findLSB")]            = kFindLSB_IntrinsicKind;
-    fIntrinsicMap[String("findMSB")]            = kFindMSB_IntrinsicKind;
-    fIntrinsicMap[String("inverse")]            = kInverse_IntrinsicKind;
-    fIntrinsicMap[String("inversesqrt")]        = kInversesqrt_IntrinsicKind;
-    fIntrinsicMap[String("length")]             = kLength_IntrinsicKind;
-    fIntrinsicMap[String("matrixCompMult")]     = kMatrixCompMult_IntrinsicKind;
-    fIntrinsicMap[String("mod")]                = kMod_IntrinsicKind;
-    fIntrinsicMap[String("normalize")]          = kNormalize_IntrinsicKind;
-    fIntrinsicMap[String("radians")]            = kRadians_IntrinsicKind;
-    fIntrinsicMap[String("reflect")]            = kReflect_IntrinsicKind;
-    fIntrinsicMap[String("refract")]            = kRefract_IntrinsicKind;
-    fIntrinsicMap[String("roundEven")]          = kRoundEven_IntrinsicKind;
-    fIntrinsicMap[String("sample")]             = kTexture_IntrinsicKind;
-}
-
 void MetalCodeGenerator::write(const char* s) {
     if (!s[0]) {
         return;
@@ -361,12 +327,10 @@
 
 void MetalCodeGenerator::writeFunctionCall(const FunctionCall& c) {
     const FunctionDeclaration& function = c.function();
-    // If this function is a built-in with no declaration, it's probably an intrinsic and might need
-    // special handling.
-    if (function.isBuiltin() && !function.definition()) {
-        auto iter = fIntrinsicMap.find(function.name());
-        if (iter != fIntrinsicMap.end()) {
-            this->writeIntrinsicCall(c, iter->second);
+
+    // Many intrinsics need to be rewritten in Metal.
+    if (function.isIntrinsic()) {
+        if (this->writeIntrinsicCall(c, function.intrinsicKind())) {
             return;
         }
     }
@@ -551,10 +515,10 @@
     this->write(")");
 }
 
-void MetalCodeGenerator::writeIntrinsicCall(const FunctionCall& c, IntrinsicKind kind) {
+bool MetalCodeGenerator::writeIntrinsicCall(const FunctionCall& c, IntrinsicKind kind) {
     const ExpressionArray& arguments = c.arguments();
     switch (kind) {
-        case kTexture_IntrinsicKind: {
+        case k_sample_IntrinsicKind: {
             this->writeExpression(*arguments[0], Precedence::kSequence);
             this->write(".sample(");
             this->writeExpression(*arguments[0], Precedence::kSequence);
@@ -572,9 +536,9 @@
                 this->writeExpression(*arguments[1], Precedence::kSequence);
                 this->write(")");
             }
-            break;
+            return true;
         }
-        case kMod_IntrinsicKind: {
+        case k_mod_IntrinsicKind: {
             // fmod(x, y) in metal calculates x - y * trunc(x / y) instead of x - y * floor(x / y)
             String tmpX = this->getTempVariable(arguments[0]->type());
             String tmpY = this->getTempVariable(arguments[1]->type());
@@ -583,10 +547,10 @@
             this->write(", " + tmpY + " = ");
             this->writeExpression(*arguments[1], Precedence::kSequence);
             this->write(", " + tmpX + " - " + tmpY + " * floor(" + tmpX + " / " + tmpY + "))");
-            break;
+            return true;
         }
         // GLSL declares scalar versions of most geometric intrinsics, but these don't exist in MSL
-        case kDistance_IntrinsicKind: {
+        case k_distance_IntrinsicKind: {
             if (arguments[0]->type().columns() == 1) {
                 this->write("abs(");
                 this->writeExpression(*arguments[0], Precedence::kAdditive);
@@ -596,9 +560,9 @@
             } else {
                 this->writeSimpleIntrinsic(c);
             }
-            break;
+            return true;
         }
-        case kDot_IntrinsicKind: {
+        case k_dot_IntrinsicKind: {
             if (arguments[0]->type().columns() == 1) {
                 this->write("(");
                 this->writeExpression(*arguments[0], Precedence::kMultiplicative);
@@ -608,9 +572,9 @@
             } else {
                 this->writeSimpleIntrinsic(c);
             }
-            break;
+            return true;
         }
-        case kFaceforward_IntrinsicKind: {
+        case k_faceforward_IntrinsicKind: {
             if (arguments[0]->type().columns() == 1) {
                 // ((((Nref) * (I) < 0) ? 1 : -1) * (N))
                 this->write("((((");
@@ -623,69 +587,73 @@
             } else {
                 this->writeSimpleIntrinsic(c);
             }
-            break;
+            return true;
         }
-        case kLength_IntrinsicKind: {
+        case k_length_IntrinsicKind: {
             this->write(arguments[0]->type().columns() == 1 ? "abs(" : "length(");
             this->writeExpression(*arguments[0], Precedence::kSequence);
             this->write(")");
-            break;
+            return true;
         }
-        case kNormalize_IntrinsicKind: {
+        case k_normalize_IntrinsicKind: {
             this->write(arguments[0]->type().columns() == 1 ? "sign(" : "normalize(");
             this->writeExpression(*arguments[0], Precedence::kSequence);
             this->write(")");
-            break;
+            return true;
         }
-        case kBitcast_IntrinsicKind: {
+
+        case k_floatBitsToInt_IntrinsicKind:
+        case k_floatBitsToUint_IntrinsicKind:
+        case k_intBitsToFloat_IntrinsicKind:
+        case k_uintBitsToFloat_IntrinsicKind: {
             this->write(this->getBitcastIntrinsic(c.type()));
             this->write("(");
             this->writeExpression(*arguments[0], Precedence::kSequence);
             this->write(")");
-            break;
+            return true;
         }
-        case kDegrees_IntrinsicKind: {
+        case k_degrees_IntrinsicKind: {
             this->write("((");
             this->writeExpression(*arguments[0], Precedence::kSequence);
             this->write(") * 57.2957795)");
-            break;
+            return true;
         }
-        case kRadians_IntrinsicKind: {
+        case k_radians_IntrinsicKind: {
             this->write("((");
             this->writeExpression(*arguments[0], Precedence::kSequence);
             this->write(") * 0.0174532925)");
-            break;
+            return true;
         }
-        case kDFdx_IntrinsicKind: {
+        case k_dFdx_IntrinsicKind: {
             this->write("dfdx");
             this->writeArgumentList(c.arguments());
-            break;
+            return true;
         }
-        case kDFdy_IntrinsicKind: {
+        case k_dFdy_IntrinsicKind: {
             // Flipping Y also negates the Y derivatives.
             if (fProgram.fConfig->fSettings.fFlipY) {
                 this->write("-");
             }
             this->write("dfdy");
             this->writeArgumentList(c.arguments());
-            break;
+            return true;
         }
-        case kInverse_IntrinsicKind: {
+        case k_inverse_IntrinsicKind: {
             this->write(this->getInversePolyfill(arguments));
             this->writeArgumentList(c.arguments());
-            break;
+            return true;
         }
-        case kInversesqrt_IntrinsicKind: {
+        case k_inversesqrt_IntrinsicKind: {
             this->write("rsqrt");
             this->writeArgumentList(c.arguments());
-            break;
+            return true;
         }
-        case kAtan_IntrinsicKind: {
+        case k_atan_IntrinsicKind: {
             this->write(c.arguments().size() == 2 ? "atan2" : "atan");
             this->writeArgumentList(c.arguments());
-            break;
+            return true;
         }
-        case kReflect_IntrinsicKind: {
+        case k_reflect_IntrinsicKind: {
             if (arguments[0]->type().columns() == 1) {
                 // We need to synthesize `I - 2 * N * I * N`.
                 String tmpI = this->getTempVariable(arguments[0]->type());
@@ -704,9 +672,9 @@
             } else {
                 this->writeSimpleIntrinsic(c);
             }
-            break;
+            return true;
         }
-        case kRefract_IntrinsicKind: {
+        case k_refract_IntrinsicKind: {
             if (arguments[0]->type().columns() == 1) {
                 // Metal does implement refract for vectors; rather than reimplementing refract from
                 // scratch, we can replace the call with `refract(float2(I,0), float2(N,0), eta).x`.
@@ -720,20 +688,20 @@
             } else {
                 this->writeSimpleIntrinsic(c);
             }
-            break;
+            return true;
         }
-        case kRoundEven_IntrinsicKind: {
+        case k_roundEven_IntrinsicKind: {
             this->write("rint");
             this->writeArgumentList(c.arguments());
-            break;
+            return true;
         }
-        case kBitCount_IntrinsicKind: {
+        case k_bitCount_IntrinsicKind: {
             this->write("popcount(");
             this->writeExpression(*arguments[0], Precedence::kSequence);
             this->write(")");
-            break;
+            return true;
         }
-        case kFindLSB_IntrinsicKind: {
+        case k_findLSB_IntrinsicKind: {
             // Create a temp variable to store the expression, to avoid double-evaluating it.
             String skTemp = this->getTempVariable(arguments[0]->type());
             String exprType = this->typeName(arguments[0]->type());
@@ -755,9 +723,9 @@
             this->write(" == ");
             this->write(exprType);
             this->write("(0)))");
-            break;
+            return true;
         }
-        case kFindMSB_IntrinsicKind: {
+        case k_findMSB_IntrinsicKind: {
             // Create a temp variable to store the expression, to avoid double-evaluating it.
             String skTemp1 = this->getTempVariable(arguments[0]->type());
             String exprType = this->typeName(arguments[0]->type());
@@ -803,38 +771,38 @@
             this->write(" == ");
             this->write(exprType);
             this->write("(0)))");
-            break;
+            return true;
         }
-        case kMatrixCompMult_IntrinsicKind: {
+        case k_matrixCompMult_IntrinsicKind: {
             this->writeMatrixCompMult();
             this->writeSimpleIntrinsic(c);
-            break;
+            return true;
         }
-        case kCompareEqual_IntrinsicKind:
-        case kCompareGreaterThan_IntrinsicKind:
-        case kCompareGreaterThanEqual_IntrinsicKind:
-        case kCompareLessThan_IntrinsicKind:
-        case kCompareLessThanEqual_IntrinsicKind:
-        case kCompareNotEqual_IntrinsicKind: {
+        case k_equal_IntrinsicKind:
+        case k_greaterThan_IntrinsicKind:
+        case k_greaterThanEqual_IntrinsicKind:
+        case k_lessThan_IntrinsicKind:
+        case k_lessThanEqual_IntrinsicKind:
+        case k_notEqual_IntrinsicKind: {
             this->write("(");
             this->writeExpression(*c.arguments()[0], Precedence::kRelational);
             switch (kind) {
-                case kCompareEqual_IntrinsicKind:
+                case k_equal_IntrinsicKind:
                     this->write(" == ");
                     break;
-                case kCompareNotEqual_IntrinsicKind:
+                case k_notEqual_IntrinsicKind:
                     this->write(" != ");
                     break;
-                case kCompareLessThan_IntrinsicKind:
+                case k_lessThan_IntrinsicKind:
                     this->write(" < ");
                     break;
-                case kCompareLessThanEqual_IntrinsicKind:
+                case k_lessThanEqual_IntrinsicKind:
                     this->write(" <= ");
                     break;
-                case kCompareGreaterThan_IntrinsicKind:
+                case k_greaterThan_IntrinsicKind:
                     this->write(" > ");
                     break;
-                case kCompareGreaterThanEqual_IntrinsicKind:
+                case k_greaterThanEqual_IntrinsicKind:
                     this->write(" >= ");
                     break;
                 default:
@@ -842,10 +810,10 @@
             }
             this->writeExpression(*c.arguments()[1], Precedence::kRelational);
             this->write(")");
-            break;
+            return true;
         }
         default:
-            SK_ABORT("unsupported intrinsic kind");
+            return false;
     }
 }