#pragma once #include "c-opast.hh" #include "c-opcomp.hh" #include struct T_SyncCurves; namespace opopt { // Persistent data for the various stages of the optimizer. struct T_OptData { // Logger F_OPLogger logger{ []( auto , auto ) {} }; // List of errors generated by the optimizer T_Array< ebcl::T_SRDError > errors; // If the size of the ouput is fixed, this field contains it as a // pair. T_Optional< std::pair< uint32_t , uint32_t > > fixedSize; // The curves that will be bound to the inputs. T_SyncCurves const* curves{ nullptr }; // A visitor to be used for the tree ebcl::T_Visitor< opast::A_Node > visitor{ opast::ASTVisitorBrowser }; //---------------------------------------------------------------------- // Table of input declarations; used to fold constant inputs. struct T_InputDecl { ebcl::T_SRDLocation location; float value; }; T_Optional< T_KeyValueTable< T_String , T_Array< T_InputDecl > > > inputDecls; void findInputDecls( T_OpsParserOutput& program ) noexcept; //---------------------------------------------------------------------- // Data for instruction numbering struct T_InstrPos { uint32_t index; opast::A_InstructionNode* node; bool lastOfSequence; uint32_t funcIndex; }; T_HashIndex instrIndex; T_Array< T_InstrPos > instructions; void numberInstructions( T_OpsParserOutput& program ) noexcept; uint32_t indexOf( opast::A_InstructionNode const& instr ) noexcept; //---------------------------------------------------------------------- // Basic block of consecutive instructions struct T_BasicBlock { uint32_t first; uint32_t count; explicit T_BasicBlock( uint32_t first ) noexcept : first( first ) , count( 1 ) { } }; // Control flow graph node struct T_CtrlFlowNode; using RP_CtrlFlowNode = T_CtrlFlowNode*; struct T_CtrlFlowNode { T_Optional< T_BasicBlock > instructions; T_AutoArray< RP_CtrlFlowNode , 16 > inbound; T_AutoArray< RP_CtrlFlowNode , 16 > outbound; }; using P_CtrlFlowNode = T_OwnPtr< T_CtrlFlowNode >; // Special nodes in the graph static constexpr uint32_t CFG_ENTER = 0; static constexpr uint32_t CFG_MAINLOOP = 1; static constexpr uint32_t CFG_END = 2; // Control flow graph T_Array< P_CtrlFlowNode > ctrlFlowGraph; T_KeyValueTable< T_String , T_BasicBlock > cfgFunctions; void buildControlFlowGraph( T_OpsParserOutput& program ) noexcept; }; /*= INDIVIDUAL OPTIMISATIONS =================================================*/ // All functions below return true if transformations were made, false if not. // Attempts to fold constant expressions into single constants. // bool FoldConstants( T_OpsParserOutput& program , T_OptData& optData ) noexcept; // Attempts to propagate values from variables that contain constants to the // locations at which they are used. // bool PropagateConstants( T_OpsParserOutput& program , T_OptData& optData ) noexcept; // Attempt to remove blocks of code that will not be executed because of // constant conditions. // bool RemoveDeadCode( T_OpsParserOutput& program , T_OptData& optData ) noexcept; } // namespace opopt