shader_ir: Declare Manager and pass it to appropiate programs.
This commit is contained in:
parent
9f61500df1
commit
f1ed22419c
7 changed files with 214 additions and 104 deletions
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue