Changes in src/ResolvExpr/SpecCost.cc [c6b4432:978e5eb]
- File:
-
- 1 edited
-
src/ResolvExpr/SpecCost.cc (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/SpecCost.cc
rc6b4432 r978e5eb 21 21 #include "AST/Pass.hpp" 22 22 #include "AST/Type.hpp" 23 #include "Common/PassVisitor.h" 24 #include "SynTree/Declaration.h" 25 #include "SynTree/Expression.h" 26 #include "SynTree/Type.h" 23 27 24 28 namespace ResolvExpr { 29 30 /// Counts specializations in a type 31 class CountSpecs : public WithShortCircuiting, public WithVisitorRef<CountSpecs> { 32 int count = -1; ///< specialization count (-1 for none) 33 34 public: 35 int get_count() const { return count >= 0 ? count : 0; } 36 37 // mark specialization of base type 38 void postvisit(PointerType*) { if ( count >= 0 ) ++count; } 39 40 // mark specialization of base type 41 void postvisit(ArrayType*) { if ( count >= 0 ) ++count; } 42 43 // mark specialization of base type 44 void postvisit(ReferenceType*) { if ( count >= 0 ) ++count; } 45 46 void postvisit(StructInstType*) { if ( count >= 0 ) ++count; } 47 void postvisit(UnionInstType*) { if ( count >= 0 ) ++count; } 48 49 private: 50 // takes minimum non-negative count over parameter/return list 51 void takeminover( int& mincount, std::list<DeclarationWithType*>& dwts ) { 52 for ( DeclarationWithType* dwt : dwts ) { 53 count = -1; 54 maybeAccept( dwt->get_type(), *visitor ); 55 if ( count != -1 && count < mincount ) mincount = count; 56 } 57 } 58 59 public: 60 // take minimal specialization value over ->returnVals and ->parameters 61 void previsit(FunctionType* fty) { 62 int mincount = std::numeric_limits<int>::max(); 63 takeminover( mincount, fty->parameters ); 64 takeminover( mincount, fty->returnVals ); 65 // add another level to mincount if set 66 count = mincount < std::numeric_limits<int>::max() ? mincount + 1 : -1; 67 // already visited children 68 visit_children = false; 69 } 70 71 private: 72 // returns minimum non-negative count + 1 over type parameters (-1 if none such) 73 int minover( std::list<Expression*>& parms ) { 74 int mincount = std::numeric_limits<int>::max(); 75 for ( Expression* parm : parms ) { 76 count = -1; 77 maybeAccept( parm->result, *visitor ); 78 if ( count != -1 && count < mincount ) mincount = count; 79 } 80 return mincount < std::numeric_limits<int>::max() ? mincount + 1 : -1; 81 } 82 83 public: 84 // look for polymorphic parameters 85 void previsit(StructInstType* sty) { 86 count = minover( sty->parameters ); 87 } 88 89 // look for polymorphic parameters 90 void previsit(UnionInstType* uty) { 91 count = minover( uty->parameters ); 92 } 93 94 // note polymorphic type (which may be specialized) 95 // xxx - maybe account for open/closed type variables 96 void postvisit(TypeInstType*) { count = 0; } 97 98 // take minimal specialization over elements 99 // xxx - maybe don't increment, tuple flattening doesn't necessarily specialize 100 void previsit(TupleType* tty) { 101 int mincount = std::numeric_limits<int>::max(); 102 for ( Type* ty : tty->types ) { 103 count = -1; 104 maybeAccept( ty, *visitor ); 105 if ( count != -1 && count < mincount ) mincount = count; 106 } 107 count = mincount < std::numeric_limits<int>::max() ? mincount + 1 : -1; 108 visit_children = false; 109 } 110 }; 111 112 /// Returns the (negated) specialization cost for a given type 113 int specCost( Type* ty ) { 114 PassVisitor<CountSpecs> counter; 115 maybeAccept( ty, *counter.pass.visitor ); 116 return counter.pass.get_count(); 117 } 25 118 26 119 namespace {
Note:
See TracChangeset
for help on using the changeset viewer.