source: src/ResolvExpr/ConversionCost.cc@ 6ac5223

ADT aaron-thesis arm-eh ast-experimental cleanup-dtors deferred_resn demangler enum forall-pointer-decay jacob/cs343-translation jenkins-sandbox new-ast new-ast-unique-expr new-env no_list persistent-indexer pthread-emulation qualifiedEnum resolv-new with_gc
Last change on this file since 6ac5223 was ea6332d, checked in by Thierry Delisle <tdelisle@…>, 8 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.