shader_ir: Declare Manager and pass it to appropiate programs.

This commit is contained in:
Fernando Sahmkow 2019-06-28 22:59:43 -04:00 committed by FernandoS27
parent 9f61500df1
commit f1ed22419c
7 changed files with 214 additions and 104 deletions

View file

@ -363,6 +363,71 @@ std::string ASTManager::Print() {
return printer.GetResult();
}
ASTManager::ASTManager() = default;
ASTManager::~ASTManager() {
Clear();
}
void ASTManager::Init() {
main_node = ASTBase::Make<ASTProgram>(ASTNode{});
program = std::get_if<ASTProgram>(main_node->GetInnerData());
true_condition = MakeExpr<ExprBoolean>(true);
}
ASTManager::ASTManager(ASTManager&& other)
: labels_map(std::move(other.labels_map)), labels_count{other.labels_count},
gotos(std::move(other.gotos)), labels(std::move(other.labels)), variables{other.variables},
program{other.program}, main_node{other.main_node}, true_condition{other.true_condition} {
other.main_node.reset();
}
ASTManager& ASTManager::operator=(ASTManager&& other) {
labels_map = std::move(other.labels_map);
labels_count = other.labels_count;
gotos = std::move(other.gotos);
labels = std::move(other.labels);
variables = other.variables;
program = other.program;
main_node = other.main_node;
true_condition = other.true_condition;
other.main_node.reset();
return *this;
}
void ASTManager::DeclareLabel(u32 address) {
const auto pair = labels_map.emplace(address, labels_count);
if (pair.second) {
labels_count++;
labels.resize(labels_count);
}
}
void ASTManager::InsertLabel(u32 address) {
u32 index = labels_map[address];
ASTNode label = ASTBase::Make<ASTLabel>(main_node, index);
labels[index] = label;
program->nodes.PushBack(label);
}
void ASTManager::InsertGoto(Expr condition, u32 address) {
u32 index = labels_map[address];
ASTNode goto_node = ASTBase::Make<ASTGoto>(main_node, condition, index);
gotos.push_back(goto_node);
program->nodes.PushBack(goto_node);
}
void ASTManager::InsertBlock(u32 start_address, u32 end_address) {
ASTNode block = ASTBase::Make<ASTBlockEncoded>(main_node, start_address, end_address);
program->nodes.PushBack(block);
}
void ASTManager::InsertReturn(Expr condition, bool kills) {
ASTNode node = ASTBase::Make<ASTReturn>(main_node, condition, kills);
program->nodes.PushBack(node);
}
void ASTManager::Decompile() {
auto it = gotos.begin();
while (it != gotos.end()) {
@ -460,7 +525,6 @@ void ASTManager::SanityCheck() {
void ASTManager::EncloseDoWhile(ASTNode goto_node, ASTNode label) {
// ShowCurrentState("Before DoWhile Enclose");
enclose_count++;
ASTZipper& zipper = goto_node->GetManager();
ASTNode loop_start = label->GetNext();
if (loop_start == goto_node) {
@ -481,7 +545,6 @@ void ASTManager::EncloseDoWhile(ASTNode goto_node, ASTNode label) {
void ASTManager::EncloseIfThen(ASTNode goto_node, ASTNode label) {
// ShowCurrentState("Before IfThen Enclose");
enclose_count++;
ASTZipper& zipper = goto_node->GetManager();
ASTNode if_end = label->GetPrevious();
if (if_end == goto_node) {
@ -514,7 +577,6 @@ void ASTManager::EncloseIfThen(ASTNode goto_node, ASTNode label) {
void ASTManager::MoveOutward(ASTNode goto_node) {
// ShowCurrentState("Before MoveOutward");
outward_count++;
ASTZipper& zipper = goto_node->GetManager();
ASTNode parent = goto_node->GetParent();
ASTZipper& zipper2 = parent->GetManager();
@ -582,4 +644,75 @@ void ASTManager::MoveOutward(ASTNode goto_node) {
// ShowCurrentState("After MoveOutward");
}
class ASTClearer {
public:
ASTClearer() = default;
void operator()(ASTProgram& ast) {
ASTNode current = ast.nodes.GetFirst();
while (current) {
Visit(current);
current = current->GetNext();
}
}
void operator()(ASTIfThen& ast) {
ASTNode current = ast.nodes.GetFirst();
while (current) {
Visit(current);
current = current->GetNext();
}
}
void operator()(ASTIfElse& ast) {
ASTNode current = ast.nodes.GetFirst();
while (current) {
Visit(current);
current = current->GetNext();
}
}
void operator()(ASTBlockEncoded& ast) {}
void operator()(ASTBlockDecoded& ast) {
ast.nodes.clear();
}
void operator()(ASTVarSet& ast) {}
void operator()(ASTLabel& ast) {}
void operator()(ASTGoto& ast) {}
void operator()(ASTDoWhile& ast) {
ASTNode current = ast.nodes.GetFirst();
while (current) {
Visit(current);
current = current->GetNext();
}
}
void operator()(ASTReturn& ast) {}
void operator()(ASTBreak& ast) {}
void Visit(ASTNode& node) {
std::visit(*this, *node->GetInnerData());
node->Clear();
}
};
void ASTManager::Clear() {
if (!main_node) {
return;
}
ASTClearer clearer{};
clearer.Visit(main_node);
main_node.reset();
program = nullptr;
labels_map.clear();
labels.clear();
gotos.clear();
}
} // namespace VideoCommon::Shader