Ignore:
Timestamp:
Jul 30, 2024, 12:11:55 PM (4 months ago)
Author:
Andrew Beach <ajbeach@…>
Branches:
master
Children:
2ff76d25
Parents:
dd78dbc
Message:

Bit of clean-up to the box pass. Mostly just wrapping a new common set of operations and checks into a helpper function.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Box.cpp

    rdd78dbc r82d5816  
    3030#include "Common/UniqueName.hpp"       // for UniqueName
    3131#include "GenPoly/FindFunction.hpp"    // for findFunction
    32 #include "GenPoly/GenPoly.hpp"         // for getFunctionType, ...
     32#include "GenPoly/GenPoly.hpp"         // for getFunctionType, isPolyType, ...
    3333#include "GenPoly/Lvalue.hpp"          // for generalizedLvalue
    3434#include "GenPoly/ScopedSet.hpp"       // for ScopedSet
     
    670670}
    671671
     672// Get the referent (base type of pointer). Must succeed.
     673ast::Type const * getReferentType( ast::ptr<ast::Type> const & type ) {
     674        auto pointerType = type.strict_as<ast::PointerType>();
     675        assertf( pointerType->base, "getReferentType: pointer base is nullptr." );
     676        return pointerType->base.get();
     677}
     678
    672679bool isPolyDeref( ast::UntypedExpr const * expr,
    673680                TypeVarMap const & typeVars,
    674681                ast::TypeSubstitution const * typeSubs ) {
    675         if ( auto name = expr->func.as<ast::NameExpr>() ) {
    676                 if ( "*?" == name->name ) {
    677                         // It's a deref.
    678                         // Must look under the * (and strip its ptr-ty) because expr's
    679                         // result could be ar/ptr-decayed.  If expr.inner:T(*)[n], then
    680                         // expr is a poly deref, even though expr:T*, which is not poly.
    681                         auto ptrExpr = expr->args.front();
    682                         auto ptrTy = ptrExpr->result.as<ast::PointerType>();
    683                         assert(ptrTy); // thing being deref'd must be pointer
    684                         auto referentTy = ptrTy->base;
    685                         assert(referentTy);
    686                         return isPolyType( referentTy, typeVars, typeSubs );
    687                 }
     682        auto name = expr->func.as<ast::NameExpr>();
     683        if ( name && "*?" == name->name ) {
     684                // It's a deref.
     685                // Must look under the * (and strip its ptr-ty) because expr's
     686                // result could be ar/ptr-decayed.  If expr.inner:T(*)[n], then
     687                // expr is a poly deref, even though expr:T*, which is not poly.
     688                auto referentType = getReferentType( expr->args.front()->result );
     689                return isPolyType( referentType, typeVars, typeSubs );
    688690        }
    689691        return false;
     
    11991201                assert( 2 == expr->args.size() );
    12001202
    1201                 ast::Type const * arg1Ty = expr->args.front()->result;
    1202                 ast::Type const * arg2Ty = expr->args.back()->result;
    1203 
    1204                 // two cases: a[i] with first arg poly ptr, i[a] with second arg poly ptr
    1205                 bool isPoly1 = isPolyPtr( arg1Ty, scopeTypeVars, typeSubs ) != nullptr;
    1206                 bool isPoly2 = isPolyPtr( arg2Ty, scopeTypeVars, typeSubs ) != nullptr;
     1203                ast::ptr<ast::Type> const & argType1 = expr->args.front()->result;
     1204                ast::ptr<ast::Type> const & argType2 = expr->args.back()->result;
     1205
     1206                // Two Cases: a[i] with first arg poly ptr, i[a] with second arg poly ptr
     1207                bool isPoly1 = isPolyPtr( argType1, scopeTypeVars, typeSubs ) != nullptr;
     1208                bool isPoly2 = isPolyPtr( argType2, scopeTypeVars, typeSubs ) != nullptr;
    12071209
    12081210                // If neither argument is a polymorphic pointer, do nothing.
     
    12211223                                new ast::NameExpr( location, "?+?" ) );
    12221224                if ( isPoly1 ) {
    1223                         assert( arg1Ty );
    1224                         auto arg1TyPtr = dynamic_cast<ast::PointerType const * >( arg1Ty );
    1225                         assert( arg1TyPtr );
     1225                        auto referentType = getReferentType( argType1 );
    12261226                        auto multiply = ast::UntypedExpr::createCall( location2, "?*?", {
    12271227                                expr->args.back(),
    1228                                 new ast::SizeofExpr( location1, deepCopy( arg1TyPtr->base ) ),
     1228                                new ast::SizeofExpr( location1, deepCopy( referentType ) ),
    12291229                        } );
    12301230                        ret->args.push_back( expr->args.front() );
     
    12321232                } else {
    12331233                        assert( isPoly2 );
    1234                         assert( arg2Ty );
    1235                         auto arg2TyPtr = dynamic_cast<ast::PointerType const * >( arg2Ty );
    1236                         assert( arg2TyPtr );
     1234                        auto referentType = getReferentType( argType2 );
    12371235                        auto multiply = ast::UntypedExpr::createCall( location1, "?*?", {
    12381236                                expr->args.front(),
    1239                                 new ast::SizeofExpr( location2, deepCopy( arg2TyPtr->base ) ),
     1237                                new ast::SizeofExpr( location2, deepCopy( referentType ) ),
    12401238                        } );
    12411239                        ret->args.push_back( multiply );
     
    12501248                assert( 1 == expr->args.size() );
    12511249
    1252                 auto ptrExpr = expr->args.front();
    1253                 auto ptrTy = ptrExpr->result.as<ast::PointerType>();
    1254                 assert(ptrTy); // thing being deref'd must be pointer
    1255                 auto referentTy = ptrTy->base;
    1256                 assert(referentTy);
    1257 
    12581250                // If this isn't for a poly type, then do nothing.
    1259                 if ( !isPolyType( referentTy, scopeTypeVars, typeSubs ) ) {
     1251                auto referentType = getReferentType( expr->args.front()->result );
     1252                if ( !isPolyType( referentType, scopeTypeVars, typeSubs ) ) {
    12601253                        return expr;
    12611254                }
     
    13221315                assert( 2 == expr->args.size() );
    13231316
    1324                 ast::Type const * arg1Ty = expr->args.front()->result;
    1325                 ast::Type const * arg2Ty = expr->args.back()->result;
    1326 
    1327                 bool isPoly1 = isPolyPtr( arg1Ty, scopeTypeVars, typeSubs ) != nullptr;
    1328                 bool isPoly2 = isPolyPtr( arg2Ty, scopeTypeVars, typeSubs ) != nullptr;
     1317                ast::ptr<ast::Type> const & argType1 = expr->args.front()->result;
     1318                ast::ptr<ast::Type> const & argType2 = expr->args.back()->result;
     1319
     1320                bool isPoly1 = isPolyPtr( argType1, scopeTypeVars, typeSubs ) != nullptr;
     1321                bool isPoly2 = isPolyPtr( argType2, scopeTypeVars, typeSubs ) != nullptr;
    13291322
    13301323                CodeLocation const & location = expr->location;
    13311324                CodeLocation const & location1 = expr->args.front()->location;
    13321325                CodeLocation const & location2 = expr->args.back()->location;
    1333                 // LHS minus RHS -> (LHS minus RHS) / sizeof(LHS)
     1326                // LHS - RHS -> (LHS - RHS) / sizeof(LHS)
    13341327                if ( isPoly1 && isPoly2 ) {
     1328                        // There are only subtraction intrinsics for this pattern.
    13351329                        assert( "?-?" == varName );
    1336                         assert( arg1Ty );
    1337                         auto arg1TyPtr = dynamic_cast<ast::PointerType const * >( arg1Ty );
    1338                         assert( arg1TyPtr );
     1330                        auto referentType = getReferentType( argType1 );
    13391331                        auto divide = ast::UntypedExpr::createCall( location, "?/?", {
    13401332                                expr,
    1341                                 new ast::SizeofExpr( location, deepCopy( arg1TyPtr->base ) ),
     1333                                new ast::SizeofExpr( location, deepCopy( referentType ) ),
    13421334                        } );
    13431335                        if ( expr->env ) divide->env = expr->env;
     
    13451337                // LHS op RHS -> LHS op (RHS * sizeof(LHS))
    13461338                } else if ( isPoly1 ) {
    1347                         assert( arg1Ty );
    1348                         auto arg1TyPtr = dynamic_cast<ast::PointerType const * >( arg1Ty );
    1349                         assert( arg1TyPtr );
     1339                        auto referentType = getReferentType( argType1 );
    13501340                        auto multiply = ast::UntypedExpr::createCall( location2, "?*?", {
    13511341                                expr->args.back(),
    1352                                 new ast::SizeofExpr( location1, deepCopy( arg1TyPtr->base ) ),
     1342                                new ast::SizeofExpr( location1, deepCopy( referentType ) ),
    13531343                        } );
    13541344                        return ast::mutate_field_index(
     
    13561346                // LHS op RHS -> (LHS * sizeof(RHS)) op RHS
    13571347                } else if ( isPoly2 ) {
    1358                         assert( arg2Ty );
    1359                         auto arg2TyPtr = dynamic_cast<ast::PointerType const * >( arg2Ty );
    1360                         assert( arg2TyPtr );
     1348                        auto referentType = getReferentType( argType2 );
    13611349                        auto multiply = ast::UntypedExpr::createCall( location1, "?*?", {
    13621350                                expr->args.front(),
    1363                                 new ast::SizeofExpr( location2, deepCopy( arg2TyPtr->base ) ),
     1351                                new ast::SizeofExpr( location2, deepCopy( referentType ) ),
    13641352                        } );
    13651353                        return ast::mutate_field_index(
    13661354                                expr, &ast::ApplicationExpr::args, 0, multiply );
    13671355                }
    1368         // Addition and Subtration Relative Assignment Intrinsics:
     1356        // Addition and Subtraction Relative Assignment Intrinsics:
    13691357        } else if ( "?+=?" == varName || "?-=?" == varName ) {
    13701358                assert( expr->result );
Note: See TracChangeset for help on using the changeset viewer.