source: src/ResolvExpr/Cost.hpp@ d5efcb7

Last change on this file since d5efcb7 was c92bdcc, checked in by Andrew Beach <ajbeach@…>, 17 months ago

Updated the rest of the names in src/ (except for the generated files).

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