| [51b73452] | 1 | /* | 
|---|
|  | 2 | * This file is part of the Cforall project | 
|---|
|  | 3 | * | 
|---|
|  | 4 | * $Id: ConversionCost.cc,v 1.11 2005/08/29 20:14:15 rcbilson Exp $ | 
|---|
|  | 5 | * | 
|---|
|  | 6 | */ | 
|---|
|  | 7 |  | 
|---|
|  | 8 | #include "ConversionCost.h" | 
|---|
|  | 9 | #include "typeops.h" | 
|---|
|  | 10 | #include "SynTree/Type.h" | 
|---|
|  | 11 | #include "SynTree/Visitor.h" | 
|---|
|  | 12 | #include "SymTab/Indexer.h" | 
|---|
|  | 13 |  | 
|---|
|  | 14 |  | 
|---|
|  | 15 | namespace ResolvExpr { | 
|---|
|  | 16 |  | 
|---|
|  | 17 | const Cost Cost::zero = Cost( 0, 0, 0 ); | 
|---|
|  | 18 | const Cost Cost::infinity = Cost( -1, -1, -1 ); | 
|---|
|  | 19 |  | 
|---|
|  | 20 | Cost | 
|---|
|  | 21 | conversionCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) | 
|---|
|  | 22 | { | 
|---|
|  | 23 | if( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) { | 
|---|
|  | 24 | EqvClass eqvClass; | 
|---|
|  | 25 | NamedTypeDecl *namedType; | 
|---|
|  | 26 | ///     std::cout << "type inst " << destAsTypeInst->get_name(); | 
|---|
|  | 27 | if( env.lookup( destAsTypeInst->get_name(), eqvClass ) ) { | 
|---|
|  | 28 | return conversionCost( src, eqvClass.type, indexer, env ); | 
|---|
|  | 29 | } else if( ( namedType = indexer.lookupType( destAsTypeInst->get_name() ) ) ) { | 
|---|
|  | 30 | ///       std::cout << " found" << std::endl; | 
|---|
|  | 31 | TypeDecl *type = dynamic_cast< TypeDecl* >( namedType ); | 
|---|
|  | 32 | // all typedefs should be gone by this point | 
|---|
|  | 33 | assert( type ); | 
|---|
|  | 34 | if( type->get_base() ) { | 
|---|
|  | 35 | return conversionCost( src, type->get_base(), indexer, env ) + Cost( 0, 0, 1 ); | 
|---|
|  | 36 | } | 
|---|
|  | 37 | } | 
|---|
|  | 38 | ///     std::cout << " not found" << std::endl; | 
|---|
|  | 39 | } | 
|---|
|  | 40 | ///   std::cout << "src is "; | 
|---|
|  | 41 | ///   src->print( std::cout ); | 
|---|
|  | 42 | ///   std::cout << std::endl << "dest is "; | 
|---|
|  | 43 | ///   dest->print( std::cout ); | 
|---|
|  | 44 | ///   std::cout << std::endl << "env is" << std::endl; | 
|---|
|  | 45 | ///   env.print( std::cout, 8 ); | 
|---|
|  | 46 | if( typesCompatibleIgnoreQualifiers( src, dest, indexer, env ) ) { | 
|---|
|  | 47 | ///     std::cout << "compatible!" << std::endl; | 
|---|
|  | 48 | return Cost( 0, 0, 0 ); | 
|---|
|  | 49 | } else if( dynamic_cast< VoidType* >( dest ) ) { | 
|---|
|  | 50 | return Cost( 0, 0, 1 ); | 
|---|
|  | 51 | } else { | 
|---|
|  | 52 | ConversionCost converter( dest, indexer, env ); | 
|---|
|  | 53 | src->accept( converter ); | 
|---|
|  | 54 | if( converter.get_cost() == Cost::infinity ) { | 
|---|
|  | 55 | return Cost::infinity; | 
|---|
|  | 56 | } else { | 
|---|
|  | 57 | return converter.get_cost() + Cost( 0, 0, 0 ); | 
|---|
|  | 58 | } | 
|---|
|  | 59 | } | 
|---|
|  | 60 | } | 
|---|
|  | 61 |  | 
|---|
|  | 62 | ConversionCost::ConversionCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) | 
|---|
|  | 63 | : dest( dest ), indexer( indexer ), cost( Cost::infinity ), env( env ) | 
|---|
|  | 64 | { | 
|---|
|  | 65 | } | 
|---|
|  | 66 |  | 
|---|
|  | 67 | /* | 
|---|
|  | 68 | Old | 
|---|
|  | 69 | === | 
|---|
|  | 70 | Double | 
|---|
|  | 71 | | | 
|---|
|  | 72 | Float | 
|---|
|  | 73 | | | 
|---|
|  | 74 | ULong | 
|---|
|  | 75 | /   \ | 
|---|
|  | 76 | UInt    Long | 
|---|
|  | 77 | \   / | 
|---|
|  | 78 | Int | 
|---|
|  | 79 | | | 
|---|
|  | 80 | Ushort | 
|---|
|  | 81 | | | 
|---|
|  | 82 | Short | 
|---|
|  | 83 | | | 
|---|
|  | 84 | Uchar | 
|---|
|  | 85 | /   \ | 
|---|
|  | 86 | Schar   Char | 
|---|
|  | 87 |  | 
|---|
|  | 88 | New | 
|---|
|  | 89 | === | 
|---|
|  | 90 | +-----LongDoubleComplex--+ | 
|---|
|  | 91 | LongDouble--+          |             +-LongDoubleImag | 
|---|
|  | 92 | |         +---DoubleComplex---+         | | 
|---|
|  | 93 | Double------+        |          +----DoubleImag | 
|---|
|  | 94 | |           +-FloatComplex-+            | | 
|---|
|  | 95 | Float---------+              +-------FloatImag | 
|---|
|  | 96 | | | 
|---|
|  | 97 | ULongLong | 
|---|
|  | 98 | | | 
|---|
|  | 99 | LongLong | 
|---|
|  | 100 | | | 
|---|
|  | 101 | ULong | 
|---|
|  | 102 | /   \ | 
|---|
|  | 103 | UInt    Long | 
|---|
|  | 104 | \   / | 
|---|
|  | 105 | Int | 
|---|
|  | 106 | | | 
|---|
|  | 107 | Ushort | 
|---|
|  | 108 | | | 
|---|
|  | 109 | Short | 
|---|
|  | 110 | | | 
|---|
|  | 111 | Uchar | 
|---|
|  | 112 | /   \ | 
|---|
|  | 113 | Schar   Char | 
|---|
|  | 114 | \   / | 
|---|
|  | 115 | Bool | 
|---|
|  | 116 | */ | 
|---|
|  | 117 |  | 
|---|
|  | 118 | static const int costMatrix[ BasicType::NUMBER_OF_BASIC_TYPES ][ BasicType::NUMBER_OF_BASIC_TYPES ] = | 
|---|
|  | 119 | { | 
|---|
|  | 120 | /* Src \ Dest:  Bool    Char    SChar   UChar   Short   UShort  Int     UInt    Long    ULong   LLong   ULLong  Float   Double  LDbl    FCplex  DCplex  LDCplex FImag   DImag   LDImag */ | 
|---|
|  | 121 | /* Bool */      { 0,    1,      1,      2,      3,      4,      5,      6,      6,      7,      8,      9,      10,     11,     12,     11,     12,     13,     -1,     -1,     -1 }, | 
|---|
|  | 122 | /* Char */      { -1,   0,      -1,     1,      2,      3,      4,      5,      5,      6,      7,      8,      9,      10,     11,     10,     11,     12,     -1,     -1,     -1 }, | 
|---|
|  | 123 | /* SChar */     { -1,   -1,     0,      1,      2,      3,      4,      5,      5,      6,      7,      8,      9,      10,     11,     10,     11,     12,     -1,     -1,     -1 }, | 
|---|
|  | 124 | /* UChar */     { -1,   -1,     -1,     0,      1,      2,      3,      4,      4,      5,      6,      7,      8,      9,      10,     9,      10,     11,     -1,     -1,     -1 }, | 
|---|
|  | 125 | /* Short */     { -1,   -1,     -1,     -1,     0,      1,      2,      3,      3,      4,      5,      6,      7,      8,      9,      8,      9,      10,     -1,     -1,     -1 }, | 
|---|
|  | 126 | /* UShort */    { -1,   -1,     -1,     -1,     -1,     0,      1,      2,      2,      3,      4,      5,      6,      7,      8,      7,      8,      9,      -1,     -1,     -1 }, | 
|---|
|  | 127 | /* Int */       { -1,   -1,     -1,     -1,     -1,     -1,     0,      1,      1,      2,      3,      4,      5,      6,      7,      6,      7,      8,      -1,     -1,     -1 }, | 
|---|
|  | 128 | /* UInt */      { -1,   -1,     -1,     -1,     -1,     -1,     -1,     0,      -1,     1,      2,      3,      4,      5,      6,      5,      6,      7,      -1,     -1,     -1 }, | 
|---|
|  | 129 | /* Long */      { -1,   -1,     -1,     -1,     -1,     -1,     -1,     -1,     0,      1,      2,      3,      4,      5,      6,      5,      6,      7,      -1,     -1,     -1 }, | 
|---|
|  | 130 | /* ULong */     { -1,   -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     0,      1,      2,      3,      4,      5,      4,      5,      6,      -1,     -1,     -1 }, | 
|---|
|  | 131 | /* LLong */     { -1,   -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     0,      1,      2,      3,      4,      3,      4,      5,      -1,     -1,     -1 }, | 
|---|
|  | 132 | /* ULLong */    { -1,   -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     0,      1,      2,      3,      2,      3,      4,      -1,     -1,     -1 }, | 
|---|
|  | 133 | /* Float */     { -1,   -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     0,      1,      2,      1,      2,      3,      -1,     -1,     -1 }, | 
|---|
|  | 134 | /* Double */    { -1,   -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     0,      1,      -1,     1,      2,      -1,     -1,     -1 }, | 
|---|
|  | 135 | /* LDbl */      { -1,   -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     0,      -1,     -1,     1,      -1,     -1,     -1 }, | 
|---|
|  | 136 | /* FCplex */    { -1,   -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     0,      1,      2,      -1,     -1,     -1 }, | 
|---|
|  | 137 | /* DCplex */    { -1,   -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     0,      1,      -1,     -1,     -1 }, | 
|---|
|  | 138 | /* LDCplex */   { -1,   -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     0,      -1,     -1,     -1 }, | 
|---|
|  | 139 | /* FImag */     { -1,   -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     1,      2,      3,      0,      1,      2 }, | 
|---|
|  | 140 | /* DImag */     { -1,   -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     1,      2,      -1,     0,      1 }, | 
|---|
|  | 141 | /* LDImag */    { -1,   -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     -1,     1,      -1,     -1,     0 } | 
|---|
|  | 142 | }; | 
|---|
|  | 143 |  | 
|---|
|  | 144 | void | 
|---|
|  | 145 | ConversionCost::visit(VoidType *voidType) | 
|---|
|  | 146 | { | 
|---|
|  | 147 | cost = Cost::infinity; | 
|---|
|  | 148 | } | 
|---|
|  | 149 |  | 
|---|
|  | 150 | void | 
|---|
|  | 151 | ConversionCost::visit(BasicType *basicType) | 
|---|
|  | 152 | { | 
|---|
|  | 153 | if( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) { | 
|---|
|  | 154 | int tableResult = costMatrix[ basicType->get_kind() ][ destAsBasic->get_kind() ]; | 
|---|
|  | 155 | if( tableResult == -1 ) { | 
|---|
|  | 156 | cost = Cost( 1, 0, 0 ); | 
|---|
|  | 157 | } else { | 
|---|
|  | 158 | cost = Cost( 0, 0, tableResult ); | 
|---|
|  | 159 | } | 
|---|
|  | 160 | } | 
|---|
|  | 161 | } | 
|---|
|  | 162 |  | 
|---|
|  | 163 | void | 
|---|
|  | 164 | ConversionCost::visit(PointerType *pointerType) | 
|---|
|  | 165 | { | 
|---|
|  | 166 | if( PointerType *destAsPtr = dynamic_cast< PointerType* >( dest ) ) { | 
|---|
|  | 167 | if( pointerType->get_base()->get_qualifiers() <= destAsPtr->get_base()->get_qualifiers() && typesCompatibleIgnoreQualifiers( pointerType->get_base(), destAsPtr->get_base(), indexer, env ) ) { | 
|---|
|  | 168 | cost = Cost( 0, 0, 1 ); | 
|---|
|  | 169 | } else { | 
|---|
|  | 170 | int assignResult = ptrsAssignable( pointerType->get_base(), destAsPtr->get_base(), env ); | 
|---|
|  | 171 | if( assignResult < 0 ) { | 
|---|
|  | 172 | cost = Cost( 0, 0, 1 ); | 
|---|
|  | 173 | } else if( assignResult > 0 ) { | 
|---|
|  | 174 | cost = Cost( 1, 0, 0 ); | 
|---|
|  | 175 | } | 
|---|
|  | 176 | } | 
|---|
|  | 177 | } | 
|---|
|  | 178 | } | 
|---|
|  | 179 |  | 
|---|
|  | 180 | void | 
|---|
|  | 181 | ConversionCost::visit(ArrayType *arrayType) | 
|---|
|  | 182 | { | 
|---|
|  | 183 | } | 
|---|
|  | 184 |  | 
|---|
|  | 185 | void | 
|---|
|  | 186 | ConversionCost::visit(FunctionType *functionType) | 
|---|
|  | 187 | { | 
|---|
|  | 188 | } | 
|---|
|  | 189 |  | 
|---|
|  | 190 | void | 
|---|
|  | 191 | ConversionCost::visit(StructInstType *inst) | 
|---|
|  | 192 | { | 
|---|
|  | 193 | if( StructInstType *destAsInst = dynamic_cast< StructInstType* >( dest ) ) { | 
|---|
|  | 194 | if( inst->get_name() == destAsInst->get_name() ) { | 
|---|
|  | 195 | cost = Cost::zero; | 
|---|
|  | 196 | } | 
|---|
|  | 197 | } | 
|---|
|  | 198 | } | 
|---|
|  | 199 |  | 
|---|
|  | 200 | void | 
|---|
|  | 201 | ConversionCost::visit(UnionInstType *inst) | 
|---|
|  | 202 | { | 
|---|
|  | 203 | if( StructInstType *destAsInst = dynamic_cast< StructInstType* >( dest ) ) { | 
|---|
|  | 204 | if( inst->get_name() == destAsInst->get_name() ) { | 
|---|
|  | 205 | cost = Cost::zero; | 
|---|
|  | 206 | } | 
|---|
|  | 207 | } | 
|---|
|  | 208 | } | 
|---|
|  | 209 |  | 
|---|
|  | 210 | void | 
|---|
|  | 211 | ConversionCost::visit(EnumInstType *inst) | 
|---|
|  | 212 | { | 
|---|
|  | 213 | static Type::Qualifiers q; | 
|---|
|  | 214 | static BasicType integer( q, BasicType::SignedInt ); | 
|---|
|  | 215 | integer.accept( *this ); | 
|---|
|  | 216 | if( cost < Cost( 1, 0, 0 ) ) { | 
|---|
|  | 217 | cost.incSafe(); | 
|---|
|  | 218 | } | 
|---|
|  | 219 | } | 
|---|
|  | 220 |  | 
|---|
|  | 221 | void | 
|---|
|  | 222 | ConversionCost::visit(ContextInstType *inst) | 
|---|
|  | 223 | { | 
|---|
|  | 224 | } | 
|---|
|  | 225 |  | 
|---|
|  | 226 | void | 
|---|
|  | 227 | ConversionCost::visit(TypeInstType *inst) | 
|---|
|  | 228 | { | 
|---|
|  | 229 | EqvClass eqvClass; | 
|---|
|  | 230 | NamedTypeDecl *namedType; | 
|---|
|  | 231 | if( env.lookup( inst->get_name(), eqvClass ) ) { | 
|---|
|  | 232 | cost = conversionCost( eqvClass.type, dest, indexer, env ); | 
|---|
|  | 233 | } else if( TypeInstType *destAsInst = dynamic_cast< TypeInstType* >( dest ) ) { | 
|---|
|  | 234 | if( inst->get_name() == destAsInst->get_name() ) { | 
|---|
|  | 235 | cost = Cost::zero; | 
|---|
|  | 236 | } | 
|---|
|  | 237 | } else if( ( namedType = indexer.lookupType( inst->get_name() ) ) ) { | 
|---|
|  | 238 | TypeDecl *type = dynamic_cast< TypeDecl* >( namedType ); | 
|---|
|  | 239 | // all typedefs should be gone by this point | 
|---|
|  | 240 | assert( type ); | 
|---|
|  | 241 | if( type->get_base() ) { | 
|---|
|  | 242 | cost = conversionCost( type->get_base(), dest, indexer, env ) + Cost( 0, 0, 1 ); | 
|---|
|  | 243 | } | 
|---|
|  | 244 | } | 
|---|
|  | 245 | } | 
|---|
|  | 246 |  | 
|---|
|  | 247 | void | 
|---|
|  | 248 | ConversionCost::visit(TupleType *tupleType) | 
|---|
|  | 249 | { | 
|---|
|  | 250 | Cost c; | 
|---|
|  | 251 | if( TupleType *destAsTuple = dynamic_cast< TupleType* >( dest ) ) { | 
|---|
|  | 252 | std::list< Type* >::const_iterator srcIt = tupleType->get_types().begin(); | 
|---|
|  | 253 | std::list< Type* >::const_iterator destIt = destAsTuple->get_types().begin(); | 
|---|
|  | 254 | while( srcIt != tupleType->get_types().end() ) { | 
|---|
|  | 255 | Cost newCost = conversionCost( *srcIt++, *destIt++, indexer, env ); | 
|---|
|  | 256 | if( newCost == Cost::infinity ) { | 
|---|
|  | 257 | return; | 
|---|
|  | 258 | } | 
|---|
|  | 259 | c += newCost; | 
|---|
|  | 260 | } | 
|---|
|  | 261 | if( destIt != destAsTuple->get_types().end() ) { | 
|---|
|  | 262 | cost = Cost::infinity; | 
|---|
|  | 263 | } else { | 
|---|
|  | 264 | cost = c; | 
|---|
|  | 265 | } | 
|---|
|  | 266 | } | 
|---|
|  | 267 | } | 
|---|
|  | 268 |  | 
|---|
|  | 269 | } // namespace ResolvExpr | 
|---|