Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/AlternativeFinder.cc

    rddf8a29 r5ccb10d  
    1414//
    1515
    16 #include <algorithm>               // for copy
    17 #include <cassert>                 // for safe_dynamic_cast, assert, assertf
    18 #include <iostream>                // for operator<<, cerr, ostream, endl
    19 #include <iterator>                // for back_insert_iterator, back_inserter
    20 #include <list>                    // for _List_iterator, list, _List_const_...
    21 #include <map>                     // for _Rb_tree_iterator, map, _Rb_tree_c...
    22 #include <memory>                  // for allocator_traits<>::value_type
    23 #include <utility>                 // for pair
    24 
    25 #include "Alternative.h"           // for AltList, Alternative
     16#include <list>
     17#include <iterator>
     18#include <algorithm>
     19#include <functional>
     20#include <cassert>
     21#include <unordered_map>
     22#include <utility>
     23#include <vector>
     24
    2625#include "AlternativeFinder.h"
    27 #include "Common/SemanticError.h"  // for SemanticError
    28 #include "Common/utility.h"        // for deleteAll, printAll, CodeLocation
    29 #include "Cost.h"                  // for Cost, Cost::zero, operator<<, Cost...
    30 #include "InitTweak/InitTweak.h"   // for getFunctionName
    31 #include "RenameVars.h"            // for RenameVars, global_renamer
    32 #include "ResolveTypeof.h"         // for resolveTypeof
    33 #include "Resolver.h"              // for resolveStmtExpr
    34 #include "SymTab/Indexer.h"        // for Indexer
    35 #include "SymTab/Mangler.h"        // for Mangler
    36 #include "SymTab/Validate.h"       // for validateType
    37 #include "SynTree/Constant.h"      // for Constant
    38 #include "SynTree/Declaration.h"   // for DeclarationWithType, TypeDecl, Dec...
    39 #include "SynTree/Expression.h"    // for Expression, CastExpr, NameExpr
    40 #include "SynTree/Initializer.h"   // for SingleInit, operator<<, Designation
    41 #include "SynTree/SynTree.h"       // for UniqueId
    42 #include "SynTree/Type.h"          // for Type, FunctionType, PointerType
    43 #include "Tuples/Explode.h"        // for explode
    44 #include "Tuples/Tuples.h"         // for isTtype, handleTupleAssignment
    45 #include "Unify.h"                 // for unify
    46 #include "typeops.h"               // for adjustExprType, polyCost, castCost
     26#include "Alternative.h"
     27#include "Cost.h"
     28#include "typeops.h"
     29#include "Unify.h"
     30#include "RenameVars.h"
     31#include "SynTree/Type.h"
     32#include "SynTree/Declaration.h"
     33#include "SynTree/Expression.h"
     34#include "SynTree/Initializer.h"
     35#include "SynTree/Visitor.h"
     36#include "SymTab/Indexer.h"
     37#include "SymTab/Mangler.h"
     38#include "SynTree/TypeSubstitution.h"
     39#include "SymTab/Validate.h"
     40#include "Tuples/Tuples.h"
     41#include "Tuples/Explode.h"
     42#include "Common/utility.h"
     43#include "InitTweak/InitTweak.h"
     44#include "InitTweak/GenInit.h"
     45#include "ResolveTypeof.h"
     46#include "Resolver.h"
    4747
    4848extern bool resolvep;
     
    286286        }
    287287
    288         Cost computeConversionCost( Type * actualType, Type * formalType, const SymTab::Indexer &indexer, const TypeEnvironment & env ) {
    289                 PRINT(
    290                         std::cerr << std::endl << "converting ";
    291                         actualType->print( std::cerr, 8 );
    292                         std::cerr << std::endl << " to ";
    293                         formalType->print( std::cerr, 8 );
    294                         std::cerr << std::endl << "environment is: ";
    295                         env.print( std::cerr, 8 );
    296                         std::cerr << std::endl;
    297                 )
    298                 Cost convCost = conversionCost( actualType, formalType, indexer, env );
    299                 PRINT(
    300                         std::cerr << std::endl << "cost is" << convCost << std::endl;
    301                 )
    302                 if ( convCost == Cost::infinity ) {
    303                         return convCost;
    304                 }
    305                 convCost.incPoly( polyCost( formalType, env, indexer ) + polyCost( actualType, env, indexer ) );
    306                 return convCost;
    307         }
    308 
    309         Cost computeExpressionConversionCost( Expression *& actualExpr, Type * formalType, const SymTab::Indexer &indexer, const TypeEnvironment & env ) {
    310                 Cost convCost = computeConversionCost( actualExpr->result, formalType, indexer, env );
    311                 // if ( convCost != Cost::zero ) {
    312 
    313                 // xxx - temporary -- ignore poly cost, since this causes some polymorphic functions to be cast, which causes the specialize
    314                 // pass to try to specialize them, which currently does not work. Once that is fixed, remove the next 3 lines and uncomment the
    315                 // previous line.
    316                 Cost tmpCost = convCost;
    317                 tmpCost.incPoly( -tmpCost.get_polyCost() );
    318                 if ( tmpCost != Cost::zero ) {
    319                         Type *newType = formalType->clone();
    320                         env.apply( newType );
    321                         actualExpr = new CastExpr( actualExpr, newType );
    322                         // xxx - SHOULD be able to resolve this cast, but at the moment pointers are not castable to zero_t, but are implicitly convertible. This is clearly
    323                         // inconsistent, once this is fixed it should be possible to resolve the cast.
    324                         // xxx - this isn't working, it appears because type1 (the formal type) is seen as widenable, but it shouldn't be, because this makes the conversion from DT* to DT* since commontype(zero_t, DT*) is DT*, rather than just nothing.
    325 
    326                         // AlternativeFinder finder( indexer, env );
    327                         // finder.findWithAdjustment( actualExpr );
    328                         // assertf( finder.get_alternatives().size() > 0, "Somehow castable expression failed to find alternatives." );
    329                         // assertf( finder.get_alternatives().size() == 1, "Somehow got multiple alternatives for known cast expression." );
    330                         // Alternative & alt = finder.get_alternatives().front();
    331                         // delete actualExpr;
    332                         // actualExpr = alt.expr->clone();
    333                 }
    334                 return convCost;
    335         }
    336 
    337         Cost computeApplicationConversionCost( Alternative &alt, const SymTab::Indexer &indexer ) {
     288        Cost computeConversionCost( Alternative &alt, const SymTab::Indexer &indexer ) {
    338289                ApplicationExpr *appExpr = safe_dynamic_cast< ApplicationExpr* >( alt.expr );
    339290                PointerType *pointer = safe_dynamic_cast< PointerType* >( appExpr->get_function()->get_result() );
     
    353304                                actualType->print( std::cerr, 8 );
    354305                        )
     306                        Cost actualCost = Cost::zero;
    355307                        if ( formal == formals.end() ) {
    356308                                if ( function->get_isVarArgs() ) {
     
    373325                                std::cerr << std::endl;
    374326                        )
    375                         convCost += computeExpressionConversionCost( *actualExpr, formalType, indexer, alt.env );
     327                        Cost newCost = conversionCost( actualType, formalType, indexer, alt.env );
     328                        PRINT(
     329                                std::cerr << std::endl << "cost is" << newCost << std::endl;
     330                        )
     331
     332                        if ( newCost == Cost::infinity ) {
     333                                return newCost;
     334                        }
     335                        convCost += newCost;
     336                        actualCost += newCost;
     337                        if ( actualCost != Cost::zero ) {
     338                                Type *newType = formalType->clone();
     339                                alt.env.apply( newType );
     340                                *actualExpr = new CastExpr( *actualExpr, newType );
     341                        }
     342                        convCost.incPoly( polyCost( formalType, alt.env, indexer ) + polyCost( actualType, alt.env, indexer ) );
    376343                        ++formal; // can't be in for-loop update because of the continue
    377344                }
     
    381348
    382349                for ( InferredParams::const_iterator assert = appExpr->get_inferParams().begin(); assert != appExpr->get_inferParams().end(); ++assert ) {
    383                         convCost += computeConversionCost( assert->second.actualType, assert->second.formalType, indexer, alt.env );
     350                        PRINT(
     351                                std::cerr << std::endl << "converting ";
     352                                assert->second.actualType->print( std::cerr, 8 );
     353                                std::cerr << std::endl << " to ";
     354                                assert->second.formalType->print( std::cerr, 8 );
     355                        )
     356                        Cost newCost = conversionCost( assert->second.actualType, assert->second.formalType, indexer, alt.env );
     357                        PRINT(
     358                                std::cerr << std::endl << "cost of conversion is " << newCost << std::endl;
     359                        )
     360                        if ( newCost == Cost::infinity ) {
     361                                return newCost;
     362                        }
     363                        convCost += newCost;
     364                        convCost.incPoly( polyCost( assert->second.formalType, alt.env, indexer ) + polyCost( assert->second.actualType, alt.env, indexer ) );
    384365                }
    385366
     
    795776                // compute conversionsion costs
    796777                for ( AltList::iterator withFunc = candidates.begin(); withFunc != candidates.end(); ++withFunc ) {
    797                         Cost cvtCost = computeApplicationConversionCost( *withFunc, indexer );
     778                        Cost cvtCost = computeConversionCost( *withFunc, indexer );
    798779
    799780                        PRINT(
     
    914895                                // count one safe conversion for each value that is thrown away
    915896                                thisCost.incSafe( discardedValues );
    916                                 Alternative newAlt( restructureCast( i->expr->clone(), toType ), i->env, i->cost, thisCost );
    917                                 // xxx - this doesn't work at the moment, since inferParameters requires an ApplicationExpr as the alternative.
    918                                 // Once this works, it should be possible to infer parameters on a cast expression and specialize any function.
    919 
    920                                 // inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( candidates ) );
    921                                 candidates.emplace_back( std::move( newAlt ) );
     897
     898                                candidates.push_back( Alternative( restructureCast( i->expr->clone(), toType ), i->env, i->cost, thisCost ) );
    922899                        } // if
    923900                } // for
     
    1002979        void AlternativeFinder::visit( SizeofExpr *sizeofExpr ) {
    1003980                if ( sizeofExpr->get_isType() ) {
    1004                         Type * newType = sizeofExpr->get_type()->clone();
    1005                         alternatives.push_back( Alternative( new SizeofExpr( resolveTypeof( newType, indexer ) ), env, Cost::zero ) );
     981                        // xxx - resolveTypeof?
     982                        alternatives.push_back( Alternative( sizeofExpr->clone(), env, Cost::zero ) );
    1006983                } else {
    1007984                        // find all alternatives for the argument to sizeof
     
    10231000        void AlternativeFinder::visit( AlignofExpr *alignofExpr ) {
    10241001                if ( alignofExpr->get_isType() ) {
    1025                         Type * newType = alignofExpr->get_type()->clone();
    1026                         alternatives.push_back( Alternative( new AlignofExpr( resolveTypeof( newType, indexer ) ), env, Cost::zero ) );
     1002                        // xxx - resolveTypeof?
     1003                        alternatives.push_back( Alternative( alignofExpr->clone(), env, Cost::zero ) );
    10271004                } else {
    10281005                        // find all alternatives for the argument to sizeof
     
    11621139                                                ConditionalExpr *newExpr = new ConditionalExpr( first->expr->clone(), second->expr->clone(), third->expr->clone() );
    11631140                                                newExpr->set_result( commonType ? commonType : second->expr->get_result()->clone() );
    1164                                                 // convert both options to the conditional result type
    1165                                                 newAlt.cost += computeExpressionConversionCost( newExpr->arg2, newExpr->result, indexer, newAlt.env );
    1166                                                 newAlt.cost += computeExpressionConversionCost( newExpr->arg3, newExpr->result, indexer, newAlt.env );
    11671141                                                newAlt.expr = newExpr;
    11681142                                                inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( alternatives ) );
Note: See TracChangeset for help on using the changeset viewer.