source: src/ResolvExpr/ConversionCost.cc @ ea6332d

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsdeferred_resndemanglerenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newwith_gc
Last change on this file since ea6332d was ea6332d, checked in by Thierry Delisle <tdelisle@…>, 7 years ago

Big header cleaning pass - commit 3

  • Property mode set to 100644
File size: 11.7 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// ConversionCost.cc --
8//
9// Author           : Richard C. Bilson
10// Created On       : Sun May 17 07:06:19 2015
11// Last Modified By : Peter A. Buhr
12// Last Modified On : Wed Mar  2 17:35:46 2016
13// Update Count     : 6
14//
15
16#include "ConversionCost.h"
17
18#include <cassert>                       // for assert
19#include <list>                          // for list, list<>::const_iterator
20#include <string>                        // for operator==, string
21
22#include "ResolvExpr/Cost.h"             // for Cost
23#include "ResolvExpr/TypeEnvironment.h"  // for EqvClass, TypeEnvironment
24#include "SymTab/Indexer.h"              // for Indexer
25#include "SynTree/Declaration.h"         // for TypeDecl, NamedTypeDecl
26#include "SynTree/Type.h"                // for Type, BasicType, TypeInstType
27#include "typeops.h"                     // for typesCompatibleIgnoreQualifiers
28
29namespace ResolvExpr {
30        const Cost Cost::zero = Cost( 0, 0, 0 );
31        const Cost Cost::infinity = Cost( -1, -1, -1 );
32
33        Cost conversionCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
34                if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {
35                        EqvClass eqvClass;
36                        NamedTypeDecl *namedType;
37///     std::cout << "type inst " << destAsTypeInst->get_name();
38                        if ( env.lookup( destAsTypeInst->get_name(), eqvClass ) ) {
39                                if ( eqvClass.type ) {
40                                        return conversionCost( src, eqvClass.type, indexer, env );
41                                } else {
42                                        return Cost::infinity;
43                                }
44                        } else if ( ( namedType = indexer.lookupType( destAsTypeInst->get_name() ) ) ) {
45///       std::cout << " found" << std::endl;
46                                TypeDecl *type = dynamic_cast< TypeDecl* >( namedType );
47                                // all typedefs should be gone by this point
48                                assert( type );
49                                if ( type->get_base() ) {
50                                        return conversionCost( src, type->get_base(), indexer, env ) + Cost( 0, 0, 1 );
51                                } // if
52                        } // if
53///     std::cout << " not found" << std::endl;
54                } // if
55///   std::cout << "src is ";
56///   src->print( std::cout );
57///   std::cout << std::endl << "dest is ";
58///   dest->print( std::cout );
59///   std::cout << std::endl << "env is" << std::endl;
60///   env.print( std::cout, 8 );
61                if ( typesCompatibleIgnoreQualifiers( src, dest, indexer, env ) ) {
62///     std::cout << "compatible!" << std::endl;
63                        return Cost( 0, 0, 0 );
64                } else if ( dynamic_cast< VoidType* >( dest ) ) {
65                        return Cost( 0, 0, 1 );
66                } else {
67                        ConversionCost converter( dest, indexer, env );
68                        src->accept( converter );
69                        if ( converter.get_cost() == Cost::infinity ) {
70                                return Cost::infinity;
71                        } else {
72                                return converter.get_cost() + Cost( 0, 0, 0 );
73                        } // if
74                } // if
75        }
76
77        ConversionCost::ConversionCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env )
78                : dest( dest ), indexer( indexer ), cost( Cost::infinity ), env( env ) {
79        }
80
81/*
82            Old
83            ===
84           Double
85             |
86           Float
87             |
88           ULong
89           /   \
90        UInt    Long
91           \   /
92            Int
93             |
94           Ushort
95             |
96           Short
97             |
98           Uchar
99           /   \
100        Schar   Char
101
102                                New
103                                ===
104                       +-----LongDoubleComplex--+
105           LongDouble--+          |             +-LongDoubleImag
106             |         +---DoubleComplex---+         |
107           Double------+        |          +----DoubleImag
108             |           +-FloatComplex-+            |
109           Float---------+              +-------FloatImag
110             |
111          ULongLong
112             |
113          LongLong
114             |
115           ULong
116           /   \
117        UInt    Long
118           \   /
119            Int
120             |
121           Ushort
122             |
123           Short
124             |
125           Uchar
126           /   \
127        Schar   Char
128           \   /
129            Bool
130*/
131
132        static const int costMatrix[ BasicType::NUMBER_OF_BASIC_TYPES ][ BasicType::NUMBER_OF_BASIC_TYPES ] =
133        {
134        /* Src \ Dest:  Bool    Char    SChar   UChar   Short   UShort  Int     UInt    Long    ULong   LLong   ULLong  Float   Double  LDbl    FCplex  DCplex  LDCplex FImag   DImag   LDImag */
135                /* Bool */      { 0,    1,              1,              2,              3,              4,              5,              6,              6,              7,              8,              9,              10,             11,             12,             11,             12,             13,             -1,             -1,             -1 },
136                /* Char */      { -1,   0,              -1,             1,              2,              3,              4,              5,              5,              6,              7,              8,              9,              10,             11,             10,             11,             12,             -1,             -1,             -1 },
137                /* SChar */ { -1,       -1,             0,              1,              2,              3,              4,              5,              5,              6,              7,              8,              9,              10,             11,             10,             11,             12,             -1,             -1,             -1 },
138                /* UChar */ { -1,       -1,             -1,             0,              1,              2,              3,              4,              4,              5,              6,              7,              8,              9,              10,             9,              10,             11,             -1,             -1,             -1 },
139                /* Short */ { -1,       -1,             -1,             -1,             0,              1,              2,              3,              3,              4,              5,              6,              7,              8,              9,              8,              9,              10,             -1,             -1,             -1 },
140                /* UShort */{ -1,       -1,             -1,             -1,             -1,             0,              1,              2,              2,              3,              4,              5,              6,              7,              8,              7,              8,              9,              -1,             -1,             -1 },
141                /* Int */       { -1,   -1,             -1,             -1,             -1,             -1,             0,              1,              1,              2,              3,              4,              5,              6,              7,              6,              7,              8,              -1,             -1,             -1 },
142                /* UInt */      { -1,   -1,             -1,             -1,             -1,             -1,             -1,             0,              -1,             1,              2,              3,              4,              5,              6,              5,              6,              7,              -1,             -1,             -1 },
143                /* Long */      { -1,   -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              2,              3,              4,              5,              6,              5,              6,              7,              -1,             -1,             -1 },
144                /* ULong */ { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              2,              3,              4,              5,              4,              5,              6,              -1,             -1,             -1 },
145                /* LLong */ { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              2,              3,              4,              3,              4,              5,              -1,             -1,             -1 },
146                /* ULLong */{ -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              2,              3,              2,              3,              4,              -1,             -1,             -1 },
147                /* Float */ { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              2,              1,              2,              3,              -1,             -1,             -1 },
148                /* Double */{ -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              -1,             1,              2,              -1,             -1,             -1 },
149                /* LDbl */      { -1,   -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              -1,             -1,             1,              -1,             -1,             -1 },
150                /* FCplex */{ -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              2,              -1,             -1,             -1 },
151                /* DCplex */{ -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              -1,             -1,             -1 },
152                /* LDCplex */{ -1,      -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              -1,             -1,             -1 },
153                /* FImag */ { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             1,              2,              3,              0,              1,              2 },
154                /* DImag */ { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             1,              2,              -1,             0,              1 },
155                /* LDImag */{ -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             1,              -1,             -1,             0 }
156        };
157
158        void ConversionCost::visit( __attribute((unused)) VoidType *voidType ) {
159                cost = Cost::infinity;
160        }
161
162        void ConversionCost::visit(BasicType *basicType) {
163                if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {
164                        int tableResult = costMatrix[ basicType->get_kind() ][ destAsBasic->get_kind() ];
165                        if ( tableResult == -1 ) {
166                                cost = Cost( 1, 0, 0 );
167                        } else {
168                                cost = Cost( 0, 0, tableResult );
169                        } // if
170                } else if ( dynamic_cast< EnumInstType *>( dest ) ) {
171                        // xxx - not positive this is correct, but appears to allow casting int => enum
172                        cost = Cost( 1, 0, 0 );
173                } else if ( dynamic_cast< ZeroType* >( dest ) != nullptr || dynamic_cast< OneType* >( dest ) != nullptr ) {
174                        cost = Cost( 1, 0, 0 );
175                } // if
176        }
177
178        void ConversionCost::visit(PointerType *pointerType) {
179                if ( PointerType *destAsPtr = dynamic_cast< PointerType* >( dest ) ) {
180                        if ( pointerType->get_base()->get_qualifiers() <= destAsPtr->get_base()->get_qualifiers() && typesCompatibleIgnoreQualifiers( pointerType->get_base(), destAsPtr->get_base(), indexer, env ) ) {
181                                cost = Cost( 0, 0, 1 );
182                        } else {
183                                int assignResult = ptrsAssignable( pointerType->get_base(), destAsPtr->get_base(), env );
184                                if ( assignResult < 0 ) {
185                                        cost = Cost( 0, 0, 1 );
186                                } else if ( assignResult > 0 ) {
187                                        cost = Cost( 1, 0, 0 );
188                                } // if
189                        } // if
190                } else if ( dynamic_cast< ZeroType* >( dest ) != nullptr || dynamic_cast< OneType* >( dest ) != nullptr ) {
191                        cost = Cost( 1, 0, 0 );
192                } // if
193        }
194
195        void ConversionCost::visit(__attribute((unused)) ArrayType *arrayType) {}
196        void ConversionCost::visit(__attribute((unused)) FunctionType *functionType) {}
197
198        void ConversionCost::visit(StructInstType *inst) {
199                if ( StructInstType *destAsInst = dynamic_cast< StructInstType* >( dest ) ) {
200                        if ( inst->get_name() == destAsInst->get_name() ) {
201                                cost = Cost::zero;
202                        } // if
203                } // if
204        }
205
206        void ConversionCost::visit(UnionInstType *inst) {
207                if ( StructInstType *destAsInst = dynamic_cast< StructInstType* >( dest ) ) {
208                        if ( inst->get_name() == destAsInst->get_name() ) {
209                                cost = Cost::zero;
210                        } // if
211                } // if
212        }
213
214        void ConversionCost::visit( __attribute((unused)) EnumInstType *inst ) {
215                static Type::Qualifiers q;
216                static BasicType integer( q, BasicType::SignedInt );
217                integer.accept( *this );
218                if ( cost < Cost( 1, 0, 0 ) ) {
219                        cost.incSafe();
220                } // if
221        }
222
223        void ConversionCost::visit( __attribute((unused)) TraitInstType *inst) {
224        }
225
226        void ConversionCost::visit(TypeInstType *inst) {
227                EqvClass eqvClass;
228                NamedTypeDecl *namedType;
229                if ( env.lookup( inst->get_name(), eqvClass ) ) {
230                        cost = conversionCost( eqvClass.type, dest, indexer, env );
231                } else if ( TypeInstType *destAsInst = dynamic_cast< TypeInstType* >( dest ) ) {
232                        if ( inst->get_name() == destAsInst->get_name() ) {
233                                cost = Cost::zero;
234                        }
235                } else if ( ( namedType = indexer.lookupType( inst->get_name() ) ) ) {
236                        TypeDecl *type = dynamic_cast< TypeDecl* >( namedType );
237                        // all typedefs should be gone by this point
238                        assert( type );
239                        if ( type->get_base() ) {
240                                cost = conversionCost( type->get_base(), dest, indexer, env ) + Cost( 0, 0, 1 );
241                        } // if
242                } // if
243        }
244
245        void ConversionCost::visit( __attribute((unused)) TupleType *tupleType) {
246                Cost c;
247                if ( TupleType *destAsTuple = dynamic_cast< TupleType* >( dest ) ) {
248                        std::list< Type* >::const_iterator srcIt = tupleType->get_types().begin();
249                        std::list< Type* >::const_iterator destIt = destAsTuple->get_types().begin();
250                        while ( srcIt != tupleType->get_types().end() && destIt != destAsTuple->get_types().end() ) {
251                                Cost newCost = conversionCost( *srcIt++, *destIt++, indexer, env );
252                                if ( newCost == Cost::infinity ) {
253                                        return;
254                                } // if
255                                c += newCost;
256                        } // while
257                        if ( destIt != destAsTuple->get_types().end() ) {
258                                cost = Cost::infinity;
259                        } else {
260                                cost = c;
261                        } // if
262                } // if
263        }
264
265        void ConversionCost::visit( __attribute((unused)) VarArgsType *varArgsType) {
266                if ( dynamic_cast< VarArgsType* >( dest ) ) {
267                        cost = Cost::zero;
268                }
269        }
270
271        void ConversionCost::visit( __attribute((unused)) ZeroType *zeroType) {
272                if ( dynamic_cast< ZeroType* >( dest ) ) {
273                        cost = Cost::zero;
274                } else if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {
275                        // copied from visit(BasicType*) for signed int, but +1 for safe conversions
276                        int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic->get_kind() ];
277                        if ( tableResult == -1 ) {
278                                cost = Cost( 1, 0, 0 );
279                        } else {
280                                cost = Cost( 0, 0, tableResult + 1 );
281                        }
282                } else if ( dynamic_cast< PointerType* >( dest ) ) {
283                        cost = Cost( 0, 0, 1 );
284                }
285        }
286
287        void ConversionCost::visit( __attribute((unused)) OneType *oneType) {
288                if ( dynamic_cast< OneType* >( dest ) ) {
289                        cost = Cost::zero;
290                } else if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {
291                        // copied from visit(BasicType*) for signed int, but +1 for safe conversions
292                        int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic->get_kind() ];
293                        if ( tableResult == -1 ) {
294                                cost = Cost( 1, 0, 0 );
295                        } else {
296                                cost = Cost( 0, 0, tableResult + 1 );
297                        }
298                }
299        }
300} // namespace ResolvExpr
301
302// Local Variables: //
303// tab-width: 4 //
304// mode: c++ //
305// compile-command: "make install" //
306// End: //
Note: See TracBrowser for help on using the repository browser.