X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=blobdiff_plain;f=source%2Fprogramcompiler.h;h=7e8d3373a53e4ffcf028a218d99e420d1a9cd5a7;hp=db7aefe9ac3762a9234cd88d4b614dfc4c56ccd0;hb=bfeb6c6404659fffb1222e084b0bd08cccb4e67d;hpb=7cd066816f7faab6f8f0eba1fca4dee67ee5dc3b diff --git a/source/programcompiler.h b/source/programcompiler.h index db7aefe9..7e8d3373 100644 --- a/source/programcompiler.h +++ b/source/programcompiler.h @@ -9,28 +9,51 @@ namespace Msp { namespace GL { class Program; +class Resources; class ProgramCompiler { private: struct Visitor: ProgramSyntax::TraversingVisitor { + typedef void ResultType; + ProgramSyntax::Stage *stage; Visitor(); virtual void apply(ProgramSyntax::Stage &); + void get_result() const { } + }; + + struct BlockModifier: Visitor + { + bool remove_node; + std::vector > insert_nodes; + + BlockModifier(); + + void flatten_block(ProgramSyntax::Block &); + void apply_and_increment(ProgramSyntax::Block &, std::list >::iterator &); + using Visitor::visit; + virtual void visit(ProgramSyntax::Block &); }; struct Formatter: Visitor { + typedef std::string ResultType; + std::string formatted; unsigned indent; bool parameter_list; - bool else_if; + unsigned else_if; + std::string block_interface; Formatter(); + virtual void apply(ProgramSyntax::Stage &); + const std::string &get_result() const { return formatted; } + using Visitor::visit; virtual void visit(ProgramSyntax::Block &); virtual void visit(ProgramSyntax::Literal &); virtual void visit(ProgramSyntax::ParenthesizedExpression &); @@ -38,9 +61,13 @@ private: virtual void visit(ProgramSyntax::MemberAccess &); virtual void visit(ProgramSyntax::UnaryExpression &); virtual void visit(ProgramSyntax::BinaryExpression &); + virtual void visit(ProgramSyntax::Assignment &); virtual void visit(ProgramSyntax::FunctionCall &); virtual void visit(ProgramSyntax::ExpressionStatement &); + virtual void visit(ProgramSyntax::Import &); + virtual void visit(ProgramSyntax::Precision &); virtual void visit(ProgramSyntax::Layout &); + virtual void visit(ProgramSyntax::InterfaceLayout &); virtual void visit(ProgramSyntax::StructDeclaration &); virtual void visit(ProgramSyntax::VariableDeclaration &); virtual void visit(ProgramSyntax::InterfaceBlock &); @@ -48,6 +75,33 @@ private: virtual void visit(ProgramSyntax::Conditional &); virtual void visit(ProgramSyntax::Iteration &); virtual void visit(ProgramSyntax::Return &); + virtual void visit(ProgramSyntax::Jump &); + }; + + template + struct NodeGatherer: Visitor + { + typedef std::vector ResultType; + + std::vector nodes; + + const ResultType &get_result() const { return nodes; } + using Visitor::visit; + virtual void visit(T &n) { nodes.push_back(&n); } + }; + + struct DeclarationCombiner: BlockModifier + { + bool toplevel; + std::map > functions; + std::map variables; + + DeclarationCombiner(); + + using Visitor::visit; + virtual void visit(ProgramSyntax::Block &); + virtual void visit(ProgramSyntax::FunctionDeclaration &); + virtual void visit(ProgramSyntax::VariableDeclaration &); }; struct VariableResolver: Visitor @@ -55,31 +109,46 @@ private: std::vector blocks; ProgramSyntax::StructDeclaration *type; bool anonymous; + std::string block_interface; + bool record_target; + ProgramSyntax::VariableDeclaration *assignment_target; + bool self_referencing; VariableResolver(); + virtual void apply(ProgramSyntax::Stage &); + using Visitor::visit; virtual void visit(ProgramSyntax::Block &); virtual void visit(ProgramSyntax::VariableReference &); virtual void visit(ProgramSyntax::MemberAccess &); virtual void visit(ProgramSyntax::BinaryExpression &); + virtual void visit(ProgramSyntax::Assignment &); virtual void visit(ProgramSyntax::StructDeclaration &); virtual void visit(ProgramSyntax::VariableDeclaration &); virtual void visit(ProgramSyntax::InterfaceBlock &); }; - struct InterfaceGenerator: Visitor + struct FunctionResolver: Visitor + { + std::map > functions; + + using Visitor::visit; + virtual void visit(ProgramSyntax::FunctionCall &); + virtual void visit(ProgramSyntax::FunctionDeclaration &); + }; + + struct InterfaceGenerator: BlockModifier { std::string in_prefix; std::string out_prefix; unsigned scope_level; - std::map iface_declarations; - bool remove_node; - std::list insert_nodes; + std::map > iface_declarations; InterfaceGenerator(); static std::string get_out_prefix(ProgramSyntax::StageType); virtual void apply(ProgramSyntax::Stage &); + using Visitor::visit; virtual void visit(ProgramSyntax::Block &); std::string change_prefix(const std::string &, const std::string &) const; bool generate_interface(ProgramSyntax::VariableDeclaration &, const std::string &, const std::string &); @@ -89,61 +158,243 @@ private: virtual void visit(ProgramSyntax::Passthrough &); }; - struct VariableRenamer: Visitor + struct DeclarationReorderer: Visitor + { + enum DeclarationKind + { + NO_DECLARATION, + LAYOUT, + STRUCT, + VARIABLE, + FUNCTION + }; + + unsigned scope_level; + DeclarationKind kind; + std::set ordered_funcs; + std::set needed_funcs; + + DeclarationReorderer(); + + using Visitor::visit; + virtual void visit(ProgramSyntax::Block &); + virtual void visit(ProgramSyntax::FunctionCall &); + virtual void visit(ProgramSyntax::InterfaceLayout &) { kind = LAYOUT; } + virtual void visit(ProgramSyntax::StructDeclaration &) { kind = STRUCT; } + virtual void visit(ProgramSyntax::VariableDeclaration &); + virtual void visit(ProgramSyntax::InterfaceBlock &) { kind = VARIABLE; } + virtual void visit(ProgramSyntax::FunctionDeclaration &); + }; + + struct InlineableFunctionLocator: Visitor + { + typedef std::set ResultType; + + std::map refcounts; + std::set inlineable; + ProgramSyntax::FunctionDeclaration *in_function; + + InlineableFunctionLocator(); + + const ResultType &get_result() const { return inlineable; } + using Visitor::visit; + virtual void visit(ProgramSyntax::FunctionCall &); + virtual void visit(ProgramSyntax::FunctionDeclaration &); + }; + + struct FunctionInliner: Visitor + { + std::set inlineable; + unsigned extract_result; + RefPtr inline_result; + + FunctionInliner(); + FunctionInliner(const std::set &); + + void visit_and_inline(RefPtr &); + using Visitor::visit; + virtual void visit(ProgramSyntax::Block &); + virtual void visit(ProgramSyntax::UnaryExpression &); + virtual void visit(ProgramSyntax::BinaryExpression &); + virtual void visit(ProgramSyntax::FunctionCall &); + virtual void visit(ProgramSyntax::Return &); + }; + + struct ExpressionEvaluator: ProgramSyntax::NodeVisitor { + typedef std::map ValueMap; + + const ValueMap *variable_values; + float result; + bool result_valid; + + ExpressionEvaluator(); + ExpressionEvaluator(const ValueMap &); + + using ProgramSyntax::NodeVisitor::visit; + virtual void visit(ProgramSyntax::Literal &); + virtual void visit(ProgramSyntax::ParenthesizedExpression &); virtual void visit(ProgramSyntax::VariableReference &); + virtual void visit(ProgramSyntax::UnaryExpression &); + virtual void visit(ProgramSyntax::BinaryExpression &); + }; + + struct ConstantConditionEliminator: BlockModifier + { + unsigned scope_level; + ExpressionEvaluator::ValueMap variable_values; + + ConstantConditionEliminator(); + + using Visitor::visit; + virtual void visit(ProgramSyntax::Block &); + virtual void visit(ProgramSyntax::Assignment &); virtual void visit(ProgramSyntax::VariableDeclaration &); + virtual void visit(ProgramSyntax::Conditional &); + virtual void visit(ProgramSyntax::Iteration &); }; struct UnusedVariableLocator: Visitor { + struct VariableInfo + { + bool local; + std::vector assignments; + bool conditionally_assigned; + bool referenced; + + VariableInfo(); + }; + + typedef std::set ResultType; + typedef std::map BlockVariableMap; + std::set unused_nodes; - std::map assignments; - bool assignment; - ProgramSyntax::VariableDeclaration *assignment_target; + std::map aggregates; + ProgramSyntax::Node *aggregate; + std::vector variables; + ProgramSyntax::Assignment *assignment; + bool assignment_target; + bool global_scope; UnusedVariableLocator(); + virtual void apply(ProgramSyntax::Stage &); + const ResultType &get_result() const { return unused_nodes; } + using Visitor::visit; virtual void visit(ProgramSyntax::VariableReference &); virtual void visit(ProgramSyntax::MemberAccess &); virtual void visit(ProgramSyntax::BinaryExpression &); + virtual void visit(ProgramSyntax::Assignment &); + void record_assignment(ProgramSyntax::VariableDeclaration &, ProgramSyntax::Node &, bool); + void clear_assignments(VariableInfo &, bool); virtual void visit(ProgramSyntax::ExpressionStatement &); + virtual void visit(ProgramSyntax::StructDeclaration &); virtual void visit(ProgramSyntax::VariableDeclaration &); + virtual void visit(ProgramSyntax::InterfaceBlock &); + virtual void visit(ProgramSyntax::FunctionDeclaration &); + void merge_down_variables(); + virtual void visit(ProgramSyntax::Conditional &); + virtual void visit(ProgramSyntax::Iteration &); + }; + + struct UnusedFunctionLocator: Visitor + { + typedef std::set ResultType; + + std::set unused_nodes; + std::set used_definitions; + + const ResultType &get_result() const { return unused_nodes; } + using Visitor::visit; + virtual void visit(ProgramSyntax::FunctionCall &); + virtual void visit(ProgramSyntax::FunctionDeclaration &); }; struct NodeRemover: Visitor { std::set to_remove; - unsigned n_removed; - bool immutable_block; - bool remove_block; - NodeRemover(); + NodeRemover() { } + NodeRemover(const std::set &); + using Visitor::visit; virtual void visit(ProgramSyntax::Block &); - virtual void visit(ProgramSyntax::StructDeclaration &); virtual void visit(ProgramSyntax::VariableDeclaration &); + }; + + struct PrecisionRemover: BlockModifier + { + using Visitor::visit; + virtual void visit(ProgramSyntax::Precision &); + virtual void visit(ProgramSyntax::VariableDeclaration &); + }; + + struct DefaultPrecisionGenerator: BlockModifier + { + bool toplevel; + std::set have_default; + + DefaultPrecisionGenerator(); + + using Visitor::visit; + virtual void visit(ProgramSyntax::Block &); + virtual void visit(ProgramSyntax::Precision &); + virtual void visit(ProgramSyntax::VariableDeclaration &); + }; + + struct LegacyConverter: BlockModifier + { + GLApi target_api; + Version target_version; + std::string type; + ProgramSyntax::VariableDeclaration *frag_out; + + LegacyConverter(); + LegacyConverter(const Version &); + + bool check_version(const Version &) const; + using Visitor::visit; + bool supports_unified_interface_syntax() const; + virtual void visit(ProgramSyntax::VariableReference &); + virtual void visit(ProgramSyntax::Assignment &); + bool supports_unified_sampling_functions() const; + virtual void visit(ProgramSyntax::FunctionCall &); + bool supports_interface_layouts() const; + virtual void visit(ProgramSyntax::VariableDeclaration &); + bool supports_interface_blocks(const std::string &) const; virtual void visit(ProgramSyntax::InterfaceBlock &); }; - ProgramParser parser; + Resources *resources; ProgramSyntax::Module *module; + std::set imported_names; public: ProgramCompiler(); + ~ProgramCompiler(); - void compile(const std::string &); - void compile(IO::Base &); + void compile(const std::string &, const std::string & = ""); + void compile(IO::Base &, Resources * = 0, const std::string & = ""); + void compile(IO::Base &, const std::string &); void add_shaders(Program &); private: + static ProgramSyntax::Module *create_builtins_module(); + static ProgramSyntax::Module &get_builtins_module(); + static ProgramSyntax::Stage *get_builtins(ProgramSyntax::StageType); + void append_module(ProgramSyntax::Module &); + void append_stage(ProgramSyntax::Stage &); void process(); + void import(const std::string &); void generate(ProgramSyntax::Stage &); - void optimize(ProgramSyntax::Stage &); + bool optimize(ProgramSyntax::Stage &); + void finalize(ProgramSyntax::Stage &); static void inject_block(ProgramSyntax::Block &, const ProgramSyntax::Block &); template - static void apply(ProgramSyntax::Stage &); - std::string create_source(ProgramSyntax::Stage &); + static typename T::ResultType apply(ProgramSyntax::Stage &); + template + static typename T::ResultType apply(ProgramSyntax::Stage &, const A &); }; } // namespace GL