SkSLVariableReference.cpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. /*
  2. * Copyright 2018 Google Inc.
  3. *
  4. * Use of this source code is governed by a BSD-style license that can be
  5. * found in the LICENSE file.
  6. */
  7. #include "src/sksl/ir/SkSLVariableReference.h"
  8. #include "src/sksl/SkSLIRGenerator.h"
  9. #include "src/sksl/ir/SkSLConstructor.h"
  10. #include "src/sksl/ir/SkSLFloatLiteral.h"
  11. #include "src/sksl/ir/SkSLSetting.h"
  12. namespace SkSL {
  13. VariableReference::VariableReference(int offset, const Variable& variable, RefKind refKind)
  14. : INHERITED(offset, kVariableReference_Kind, variable.fType)
  15. , fVariable(variable)
  16. , fRefKind(refKind) {
  17. if (refKind != kRead_RefKind) {
  18. fVariable.fWriteCount++;
  19. }
  20. if (refKind != kWrite_RefKind) {
  21. fVariable.fReadCount++;
  22. }
  23. }
  24. VariableReference::~VariableReference() {
  25. if (fRefKind != kRead_RefKind) {
  26. fVariable.fWriteCount--;
  27. }
  28. if (fRefKind != kWrite_RefKind) {
  29. fVariable.fReadCount--;
  30. }
  31. }
  32. void VariableReference::setRefKind(RefKind refKind) {
  33. if (fRefKind != kRead_RefKind) {
  34. fVariable.fWriteCount--;
  35. }
  36. if (fRefKind != kWrite_RefKind) {
  37. fVariable.fReadCount--;
  38. }
  39. if (refKind != kRead_RefKind) {
  40. fVariable.fWriteCount++;
  41. }
  42. if (refKind != kWrite_RefKind) {
  43. fVariable.fReadCount++;
  44. }
  45. fRefKind = refKind;
  46. }
  47. std::unique_ptr<Expression> VariableReference::copy_constant(const IRGenerator& irGenerator,
  48. const Expression* expr) {
  49. SkASSERT(expr->isConstant());
  50. switch (expr->fKind) {
  51. case Expression::kIntLiteral_Kind:
  52. return std::unique_ptr<Expression>(new IntLiteral(irGenerator.fContext,
  53. -1,
  54. ((IntLiteral*) expr)->fValue));
  55. case Expression::kFloatLiteral_Kind:
  56. return std::unique_ptr<Expression>(new FloatLiteral(
  57. irGenerator.fContext,
  58. -1,
  59. ((FloatLiteral*) expr)->fValue));
  60. case Expression::kBoolLiteral_Kind:
  61. return std::unique_ptr<Expression>(new BoolLiteral(irGenerator.fContext,
  62. -1,
  63. ((BoolLiteral*) expr)->fValue));
  64. case Expression::kConstructor_Kind: {
  65. const Constructor* c = (const Constructor*) expr;
  66. std::vector<std::unique_ptr<Expression>> args;
  67. for (const auto& arg : c->fArguments) {
  68. args.push_back(copy_constant(irGenerator, arg.get()));
  69. }
  70. return std::unique_ptr<Expression>(new Constructor(-1, c->fType,
  71. std::move(args)));
  72. }
  73. case Expression::kSetting_Kind: {
  74. const Setting* s = (const Setting*) expr;
  75. return std::unique_ptr<Expression>(new Setting(-1, s->fName,
  76. copy_constant(irGenerator,
  77. s->fValue.get())));
  78. }
  79. default:
  80. ABORT("unsupported constant\n");
  81. }
  82. }
  83. std::unique_ptr<Expression> VariableReference::constantPropagate(const IRGenerator& irGenerator,
  84. const DefinitionMap& definitions) {
  85. if (fRefKind != kRead_RefKind) {
  86. return nullptr;
  87. }
  88. if (irGenerator.fKind == Program::kPipelineStage_Kind &&
  89. fVariable.fStorage == Variable::kGlobal_Storage &&
  90. (fVariable.fModifiers.fFlags & Modifiers::kIn_Flag) &&
  91. !(fVariable.fModifiers.fFlags & Modifiers::kUniform_Flag)) {
  92. return irGenerator.getArg(fOffset, fVariable.fName);
  93. }
  94. if ((fVariable.fModifiers.fFlags & Modifiers::kConst_Flag) && fVariable.fInitialValue &&
  95. fVariable.fInitialValue->isConstant() && fType.kind() != Type::kArray_Kind) {
  96. return copy_constant(irGenerator, fVariable.fInitialValue);
  97. }
  98. auto exprIter = definitions.find(&fVariable);
  99. if (exprIter != definitions.end() && exprIter->second &&
  100. (*exprIter->second)->isConstant()) {
  101. return copy_constant(irGenerator, exprIter->second->get());
  102. }
  103. return nullptr;
  104. }
  105. } // namespace