/* Removing variables or functions may cause things from the previous stage
to become unused. */
- bool any_removed = UnusedVariableRemover().apply(stage);
+ bool any_removed = UnreachableCodeRemover().apply(stage);
+ any_removed |= UnusedVariableRemover().apply(stage);
any_removed |= UnusedFunctionRemover().apply(stage);
any_removed |= UnusedTypeRemover().apply(stage);
}
+UnreachableCodeRemover::UnreachableCodeRemover():
+ reachable(true)
+{ }
+
+bool UnreachableCodeRemover::apply(Stage &stage)
+{
+ stage.content.visit(*this);
+ NodeRemover().apply(stage, unreachable_nodes);
+ return !unreachable_nodes.empty();
+}
+
+void UnreachableCodeRemover::visit(Block &block)
+{
+ NodeList<Statement>::iterator i = block.body.begin();
+ for(; (reachable && i!=block.body.end()); ++i)
+ (*i)->visit(*this);
+ for(; i!=block.body.end(); ++i)
+ unreachable_nodes.insert(i->get());
+}
+
+void UnreachableCodeRemover::visit(FunctionDeclaration &func)
+{
+ TraversingVisitor::visit(func);
+ reachable = true;
+}
+
+void UnreachableCodeRemover::visit(Conditional &cond)
+{
+ cond.body.visit(*this);
+ bool reachable_if_true = reachable;
+ reachable = true;
+ cond.else_body.visit(*this);
+
+ reachable |= reachable_if_true;
+}
+
+void UnreachableCodeRemover::visit(Iteration &iter)
+{
+ TraversingVisitor::visit(iter);
+
+ /* Always consider code after a loop reachable, since there's no checking
+ for whether the loop executes. */
+ reachable = true;
+}
+
+
bool UnusedTypeRemover::apply(Stage &stage)
{
stage.content.visit(*this);
virtual void visit(Iteration &);
};
+class UnreachableCodeRemover: private TraversingVisitor
+{
+private:
+ bool reachable;
+ std::set<Node *> unreachable_nodes;
+
+public:
+ UnreachableCodeRemover();
+
+ virtual bool apply(Stage &);
+
+private:
+ virtual void visit(Block &);
+ virtual void visit(FunctionDeclaration &);
+ virtual void visit(Conditional &);
+ virtual void visit(Iteration &);
+ virtual void visit(Return &) { reachable = false; }
+ virtual void visit(Jump &) { reachable = false; }
+};
+
/** Removes types which are not used anywhere. */
class UnusedTypeRemover: private TraversingVisitor
{
--- /dev/null
+uniform mat4 mvp;
+
+#pragma MSP stage(vertex)
+layout(location=0) in vec4 position;
+void main()
+{
+ gl_Position = mvp*position;
+ return;
+ gl_Position = position;
+}
+
+/* Expected output: vertex
+layout(location=0) uniform mat4 mvp;
+layout(location=0) in vec4 position;
+void main()
+{
+ gl_Position = mvp*position;
+ return;
+}
+*/