source: src/ResolvExpr/Cost.h @ daf4c89

Last change on this file since daf4c89 was 9504a89, checked in by Peter A. Buhr <pabuhr@…>, 5 years ago

remove old code for costing

  • Property mode set to 100644
File size: 6.1 KB
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
7// Cost.h --
8//
9// Author           : Peter Buhr and Aaron Moss
10// Created On       : Sun May 17 09:39:50 2015
11// Last Modified By : Peter A. Buhr
12// Last Modified On : Fri Jun 21 11:39:13 2019
13// Update Count     : 63
14//
15
16#pragma once
17
18#include <iostream>
19#include <cassert>
20#include <climits>
21
22namespace ResolvExpr {
23        // To maximize performance and space, the 7 resolution costs are packed into a single 64-bit word. However, the
24        // specialization cost is a negative value so a correction is needed is a few places.
25
26        class Cost {
27                union {
28                        struct {
29                        #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
30                                // Little-endian => first value is low priority and last is high priority.
31                                unsigned char padding;                                  ///< unused
32                                unsigned char referenceCost;                    ///< reference conversions
33                                unsigned char specCost;                                 ///< Polymorphic type specializations (type assertions), negative cost
34                                unsigned char varCost;                                  ///< Count of polymorphic type variables
35                                unsigned char signCost;                                 ///< Count of safe sign conversions
36                                unsigned char safeCost;                                 ///< Safe (widening) conversions
37                                unsigned char polyCost;                                 ///< Count of parameters and return values bound to some poly type
38                                unsigned char unsafeCost;                               ///< Unsafe (narrowing) conversions
39                        #else
40                                #error Cost BIG_ENDIAN unsupported
41                        #endif
42                        } v;
43                        uint64_t all;
44                };
45                static const unsigned char correctb = 0xff;             // byte correction for negative spec cost
46                static const uint64_t correctw = 0x00'00'00'00'00'ff'00'00; //' word correction for negative spec cost
47          public:
48                // Compiler adjusts constants for correct endian.
49                enum : uint64_t {
50                        zero      = 0x00'00'00'00'00'ff'00'00,
51                        infinity  = 0xff'ff'ff'ff'ff'00'ff'ff,
52                        unsafe    = 0x01'00'00'00'00'ff'00'00,
53                        poly      = 0x00'01'00'00'00'ff'00'00,
54                        safe      = 0x00'00'01'00'00'ff'00'00,
55                        sign      = 0x00'00'00'01'00'ff'00'00,
56                        var       = 0x00'00'00'00'01'ff'00'00,
57                        spec      = 0x00'00'00'00'00'fe'00'00,
58                        reference = 0x00'00'00'00'00'ff'01'00,
59                }; //'
60
61                Cost( uint64_t all ) { Cost::all = all; }
62                Cost( int unsafeCost, int polyCost, int safeCost, int signCost, int varCost, int specCost, int referenceCost ) {
63                        // Assume little-endian => first value is low priority and last is high priority.
64                        v = {
65                        #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
66                                (unsigned char)0,                                               // padding
67                                (unsigned char)referenceCost,                   // low priority
68                                (unsigned char)(specCost + correctb),   // correct for signedness
69                                (unsigned char)varCost, 
70                                (unsigned char)signCost, 
71                                (unsigned char)safeCost, 
72                                (unsigned char)polyCost, 
73                                (unsigned char)unsafeCost,                              // high priority
74                        #else
75                                #error Cost BIG_ENDIAN unsupported
76                        #endif
77                        };
78                }
79
80                int get_unsafeCost() const { return v.unsafeCost; }
81                int get_polyCost() const { return v.polyCost; }
82                int get_safeCost() const { return v.safeCost; }
83                int get_signCost() const { return v.signCost; }
84                int get_varCost() const { return v.varCost; }
85                int get_specCost() const { return -(correctb - v.specCost); }
86                int get_referenceCost() const { return v.referenceCost; }
87
88                friend bool operator==( const Cost, const Cost );
89                friend bool operator!=( const Cost lhs, const Cost rhs );
90                // returns negative for *this < rhs, 0 for *this == rhs, positive for *this > rhs
91                int compare( const Cost rhs ) const {
92                        if ( all == infinity ) return 1;
93                        if ( rhs.all == infinity ) return -1;
94                        return all > rhs.all ? 1 : all == rhs.all ? 0 : -1;
95                }
96                friend bool operator<( const Cost lhs, const Cost rhs );
97
98                friend Cost operator+( const Cost lhs, const Cost rhs );
99 
100                Cost operator+=( const Cost rhs ) {
101                        if ( all == infinity ) return *this;
102                        if ( rhs.all == infinity ) {
103                                all = infinity;
104                                return *this;
105                        }
106                        all += rhs.all - correctw;                                      // correct for negative spec cost
107                        return *this;
108                }
109
110                Cost incUnsafe( int inc = 1 ) {
111                        if ( all != infinity ) { assert( v.unsafeCost + inc <= UCHAR_MAX ); v.unsafeCost += inc; }
112                        return *this;
113                }
114
115                Cost incPoly( int inc = 1 ) {
116                        if ( all != infinity ) { assert( v.polyCost + inc <= UCHAR_MAX ); v.polyCost += inc; }
117                        return *this;
118                }
119
120                Cost incSafe( int inc = 1 ) {
121                        if ( all != infinity ) { assert( v.safeCost + inc <= UCHAR_MAX ); v.safeCost += inc; }
122                        return *this;
123                }
124
125                Cost incSign( int inc = 1 ) {
126                        if ( all != infinity ) { assert( v.signCost + inc <= UCHAR_MAX ); v.signCost += inc; }
127                        return *this;
128                }
129
130                Cost incVar( int inc = 1 ) {
131                        if ( all != infinity ) { assert( v.varCost + inc <= UCHAR_MAX ); v.varCost += inc; }
132                        return *this;
133                }
134
135                Cost decSpec( int dec = 1 ) {
136                        if ( all != infinity ) { assert( v.specCost - dec >= 0 ); v.specCost -= dec; }
137                        return *this;
138                }
139
140                Cost incReference( int inc = 1 ) {
141                        if ( all != infinity ) { assert( v.referenceCost + inc <= UCHAR_MAX ); v.referenceCost += inc; }
142                        return *this;
143                }
144
145                friend std::ostream & operator<<( std::ostream & os, const Cost cost );
146        };
147
148        inline bool operator==( const Cost lhs, const Cost rhs ) {
149                return lhs.all == rhs.all;
150        }
151
152        inline bool operator!=( const Cost lhs, const Cost rhs ) {
153                return !( lhs.all == rhs.all );
154        }
155
156        inline bool operator<( const Cost lhs, const Cost rhs ) {
157                if ( lhs.all == Cost::infinity ) return false;
158                if ( rhs.all == Cost::infinity ) return true;
159                return lhs.all < rhs.all;
160        }
161
162        inline Cost operator+( const Cost lhs, const Cost rhs ) {
163                if ( lhs.all == Cost::infinity || rhs.all == Cost::infinity ) return Cost{ Cost::infinity };
164                return Cost{ lhs.all + rhs.all - Cost::correctw }; // correct for negative spec cost
165        }
166
167        inline std::ostream & operator<<( std::ostream & os, const Cost cost ) {
168                return os << "( " << cost.get_unsafeCost() << ", " << cost.get_polyCost() << ", " << cost.get_safeCost()
169                                  << ", " << cost.get_signCost() << ", " << cost.get_varCost() << ", " << cost.get_specCost()
170                                  << ", " << cost.get_referenceCost() << " )";
171        }
172} // namespace ResolvExpr
173
174// Local Variables: //
175// tab-width: 4 //
176// mode: c++ //
177// compile-command: "make install" //
178// End: //
Note: See TracBrowser for help on using the repository browser.