source: src/ResolvExpr/ConversionCost.cc @ 23b6643f

aaron-thesisarm-ehcleanup-dtorsdeferred_resndemanglerjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprnew-envno_listpersistent-indexerresolv-newwith_gc
Last change on this file since 23b6643f was 23b6643f, checked in by Rob Schluntz <rschlunt@…>, 5 years ago

Merge branch 'master' into tuples

Conflicts:

src/Makefile.in
src/ResolvExpr/Unify.cc
src/SynTree/Type.h

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