Hash :
d7aa0130
Author :
Date :
2021-04-26T16:56:15
Upstream Apple's direct-to-Metal backend: compile translator. This change is meant to merge the translator changes from Apple's direct-to-Metal backend. Taken from Kyle Piddington's CL: https://chromium-review.googlesource.com/c/angle/angle/+/2857366/ The goal of this CL is to merge the translator code in a state that compiles, but not to switch the Metal backend over to use this translator backend yet. Bug: angleproject:5505 Change-Id: I68a6354604498cd5fd1eb96c13fc56f3b38f2bd0 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2897536 Reviewed-by: Jonah Ryan-Davis <jonahr@google.com> Commit-Queue: Jonah Ryan-Davis <jonahr@google.com>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
//
// Copyright 2020 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
#include <algorithm>
#include "compiler/translator/TranslatorMetalDirect/AstHelpers.h"
#include "compiler/translator/TranslatorMetalDirect/SeparateCompoundStructDeclarations.h"
#include "compiler/translator/tree_ops/SeparateDeclarations.h"
#include "compiler/translator/tree_util/IntermTraverse.h"
using namespace sh;
////////////////////////////////////////////////////////////////////////////////
namespace
{
class Separator : public TIntermTraverser
{
public:
std::unordered_map<int, TIntermSymbol *> replacementMap;
Separator(TSymbolTable &symbolTable, IdGen &idGen)
: TIntermTraverser(false, false, true, &symbolTable), mIdGen(idGen)
{}
IdGen &mIdGen;
bool visitDeclaration(Visit, TIntermDeclaration *declNode) override
{
ASSERT(declNode->getChildCount() == 1);
Declaration declaration = ViewDeclaration(*declNode);
const TVariable &var = declaration.symbol.variable();
const TType &type = var.getType();
const SymbolType symbolType = var.symbolType();
if (type.isStructSpecifier() && symbolType != SymbolType::Empty)
{
const TStructure *structure = type.getStruct();
TVariable *structVar = nullptr;
TType *instanceType = nullptr;
// Name unnamed inline structs
if (structure->symbolType() == SymbolType::Empty)
{
const TStructure *structDefn =
new TStructure(mSymbolTable, mIdGen.createNewName("__unnamed").rawName(),
&(structure->fields()), SymbolType::AngleInternal);
structVar = new TVariable(mSymbolTable, ImmutableString(""),
new TType(structDefn, true), SymbolType::Empty);
instanceType = new TType(structDefn, false);
}
else
{
structVar = new TVariable(mSymbolTable, ImmutableString(""),
new TType(structure, true), SymbolType::Empty);
instanceType = new TType(structure, false);
}
instanceType->setQualifier(type.getQualifier());
auto *instanceVar =
new TVariable(mSymbolTable, var.name(), instanceType, symbolType, var.extension());
TIntermSequence replacements;
replacements.push_back(new TIntermSymbol(structVar));
TIntermSymbol *instanceSymbol = new TIntermSymbol(instanceVar);
TIntermNode *instanceReplacement = instanceSymbol;
if (declaration.initExpr)
{
instanceReplacement =
new TIntermBinary(EOpInitialize, instanceSymbol, declaration.initExpr);
}
replacements.push_back(instanceReplacement);
replacementMap[declaration.symbol.uniqueId().get()] = instanceSymbol;
mMultiReplacements.push_back(NodeReplaceWithMultipleEntry(
declNode, declNode->getChildNode(0), std::move(replacements)));
}
return false;
}
void visitSymbol(TIntermSymbol *decl) override
{
auto symbol = replacementMap.find(decl->uniqueId().get());
if (symbol != replacementMap.end())
{
queueReplacement(symbol->second->deepCopy(), OriginalNode::IS_DROPPED);
}
}
};
} // anonymous namespace
////////////////////////////////////////////////////////////////////////////////
bool sh::SeparateCompoundStructDeclarations(TCompiler &compiler, IdGen &idGen, TIntermBlock &root)
{
Separator separator(compiler.getSymbolTable(), idGen);
root.traverse(&separator);
if (!separator.updateTree(&compiler, &root))
{
return false;
}
if (!SeparateDeclarations(&compiler, &root))
{
return false;
}
return true;
}