Changeset 817bb3c for src/ControlStruct


Ignore:
Timestamp:
Nov 5, 2021, 7:44:38 PM (2 years ago)
Author:
Andrew Beach <ajbeach@…>
Branches:
ADT, ast-experimental, enum, forall-pointer-decay, master, pthread-emulation, qualifiedEnum
Children:
de31a1d
Parents:
21fe17f
Message:

Clean-up in MultiLevelExit?, including a small interface change.

Location:
src/ControlStruct
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • src/ControlStruct/FixLabels.cpp

    r21fe17f r817bb3c  
    1010// Created On       : Mon Nov  1 09:39:00 2021
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Mon Nov  5 16:05:00 2021
    13 // Update Count     : 1
     12// Last Modified On : Mon Nov  5 19:20:00 2021
     13// Update Count     : 2
    1414//
    1515
     
    5858                }
    5959        }
    60         LabelToStmt * copy = new LabelToStmt( labelTable );
    6160        return ast::mutate_field( decl, &ast::FunctionDecl::stmts,
    62                 multiLevelExitUpdate( decl->stmts.get(), copy, label_gen ) );
     61                multiLevelExitUpdate( decl->stmts.get(), labelTable, label_gen ) );
    6362}
    6463
  • src/ControlStruct/MultiLevelExit.cpp

    r21fe17f r817bb3c  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // MultiLevelExit.cpp --
     7// MultiLevelExit.cpp -- Replaces CFA's local control flow with C's versions.
    88//
    99// Author           : Andrew Beach
    1010// Created On       : Mon Nov  1 13:48:00 2021
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Mon Nov  5 12:06:00 2021
    13 // Update Count     : 0
     12// Last Modified On : Mon Nov  5 19:20:00 2021
     13// Update Count     : 1
    1414//
    1515
     
    102102}
    103103
    104 struct MultiLevelExitCore :
     104struct MultiLevelExitCore final :
    105105                public ast::WithVisitorRef<MultiLevelExitCore>,
    106106                public ast::WithShortCircuiting, public ast::WithGuards {
    107         MultiLevelExitCore( LabelToStmt * lt, LabelGenerator_new * lg );
    108         ~MultiLevelExitCore();
     107        MultiLevelExitCore( const LabelToStmt & lt, LabelGenerator_new * lg );
    109108
    110109        void previsit( const ast::FunctionDecl * );
     
    128127        const ast::Stmt * mutateLoop( const ast::Stmt * body, Entry& );
    129128
    130         LabelToStmt * target_table;
     129        const LabelToStmt & target_table;
    131130        std::set<ast::Label> fallthrough_labels;
    132131        std::vector<Entry> enclosing_control_structures;
     
    142141        std::list<ast::ptr<ast::Stmt>> fixBlock(
    143142                const std::list<ast::ptr<ast::Stmt>> & kids, bool caseClause );
     143
     144        template<typename UnaryPredicate>
     145        auto findEnclosingControlStructure( UnaryPredicate pred ) {
     146                return std::find_if( enclosing_control_structures.rbegin(),
     147                        enclosing_control_structures.rend(), pred );
     148        }
    144149};
    145150
    146 /*
    147 template<typename... Args>
    148 void MultiLevelExitCore::GuardEntry( Args&&... args ) {
    149         enclosing_control_structures.emplace_back( std::forward<Args>(args)... );
    150   GuardAction([this]() { enclosing_control_structures.pop_back(); } )
    151 }
    152 
    153 template<typename UnaryPredicate>
    154 void MultiLevelExitCore::findEnclosingControlStructure(UnaryPredicate pred) {
    155         return std::find_if(
    156                 enclosing_control_structures.rbegin(),
    157                 enclosing_control_structures.rend(),
    158                 pred );
    159 }
    160 
    161 ast::NullStmt * MultiLevelExitCore::labeledNullStmt(
     151ast::NullStmt * labelledNullStmt(
    162152                const CodeLocation & cl, const ast::Label & label ) {
    163153        return new ast::NullStmt( cl, std::vector<ast::Label>{ label } );
    164154}
    165 */
    166 
    167 MultiLevelExitCore::MultiLevelExitCore( LabelToStmt * lt, LabelGenerator_new * lg ) :
     155
     156MultiLevelExitCore::MultiLevelExitCore(
     157                const LabelToStmt & lt, LabelGenerator_new * lg ) :
    168158        target_table( lt ), break_label( CodeLocation(), "" ), label_gen( lg ),
    169159        inFinally( false )
    170160{}
    171 
    172 MultiLevelExitCore::~MultiLevelExitCore() {
    173         delete target_table;
    174         target_table = nullptr;
    175 }
    176161
    177162void MultiLevelExitCore::previsit( const ast::FunctionDecl * ) {
     
    247232                if ( stmt->target.empty() ) {
    248233                        if ( isContinue ) {
    249                                 targetEntry = std::find_if(
    250                                         enclosing_control_structures.rbegin(),
    251                                         enclosing_control_structures.rend(),
    252                                         isContinueTarget );
     234                                targetEntry = findEnclosingControlStructure( isContinueTarget );
    253235                        } else {
    254236                                if ( enclosing_control_structures.empty() ) {
     
    256238                                                "'break' outside a loop, 'switch', or labelled block" );
    257239                                }
    258                                 targetEntry = std::find_if(
    259                                         enclosing_control_structures.rbegin(),
    260                                         enclosing_control_structures.rend(),
    261                                         isBreakTarget );
     240                                targetEntry = findEnclosingControlStructure( isBreakTarget );
    262241                        }
    263242                // Handle labeled break and continue.
    264243                } else {
    265244                        // Lookup label in table to find attached control structure.
    266                         targetEntry = std::find_if(
    267                                 enclosing_control_structures.rbegin(),
    268                                 enclosing_control_structures.rend(),
    269                                 [ targetStmt = (*target_table)[stmt->target] ](auto entry){
     245                        targetEntry = findEnclosingControlStructure(
     246                                [ targetStmt = target_table.at(stmt->target) ](auto entry){
    270247                                        return entry.stmt == targetStmt;
    271248                                } );
     
    283260        }
    284261        case ast::BranchStmt::FallThrough: {
    285                 targetEntry = std::find_if(
    286                         enclosing_control_structures.rbegin(),
    287                         enclosing_control_structures.rend(),
    288                         isFallthroughTarget
    289                 );
     262                targetEntry = findEnclosingControlStructure( isFallthroughTarget );
    290263                // Check that target is valid.
    291264                if ( targetEntry == enclosing_control_structures.rend() ) {
     
    303276        }
    304277        case ast::BranchStmt::FallThroughDefault: {
    305                 targetEntry = std::find_if( enclosing_control_structures.rbegin(), enclosing_control_structures.rend(), isFallthroughDefaultTarget );
     278                targetEntry = findEnclosingControlStructure( isFallthroughDefaultTarget );
    306279
    307280                // Check that this is in a switch or choose statement.
     
    397370        // If it is the default, mark the default as seen.
    398371        if ( stmt->isDefault() ) {
     372                assert( !enclosing_control_structures.empty() );
    399373                enclosing_control_structures.back().seenDefault();
    400374        }
     
    422396                Entry & entry = enclosing_control_structures.back();
    423397                if ( entry.isFallUsed() ) {
    424                         mutStmt->stmts.push_back( new ast::NullStmt(
    425                                 mutStmt->location,
    426                                 std::vector<ast::Label>{ entry.useFallExit() }
    427                         ) );
     398                        mutStmt->stmts.push_back(
     399                                labelledNullStmt( mutStmt->location, entry.useFallExit() ) );
    428400                }
    429401        }
     
    436408                if ( entry.isFallDefaultUsed() ) {
    437409                        // Add fallthrough default label if necessary.
    438                         push_front( mutStmt->stmts, new ast::NullStmt(
    439                                 stmt->location,
    440                                 std::vector<ast::Label>{ enclosing_control_structures.back().useFallDefaultExit() }
     410                        push_front( mutStmt->stmts, labelledNullStmt(
     411                                stmt->location, entry.useFallDefaultExit()
    441412                        ) );
    442413                }
     
    568539                ast::CompoundStmt * new_body = new ast::CompoundStmt( body->location );
    569540                new_body->kids.push_back( body );
    570 
    571                 new_body->kids.push_back( new ast::NullStmt(
    572                         body->location,
    573                         std::vector<ast::Label>{ entry.useContExit() }
    574                 ) );
    575 
     541                new_body->kids.push_back(
     542                        labelledNullStmt( body->location, entry.useContExit() ) );
    576543                return new_body;
    577544        }
     
    624591
    625592                if ( !break_label.empty() ) {
    626                         ret.push_back( new ast::NullStmt(
    627                                 ret.back()->location,
    628                                 std::vector<ast::Label>{ break_label }
    629                         ) );
     593                        ret.push_back(
     594                                labelledNullStmt( ret.back()->location, break_label ) );
    630595                        break_label = ast::Label( CodeLocation(), "" );
    631596                }
     
    642607const ast::CompoundStmt * multiLevelExitUpdate(
    643608        const ast::CompoundStmt * stmt,
    644                 LabelToStmt * labelTable,
     609                const LabelToStmt & labelTable,
    645610                LabelGenerator_new * labelGen ) {
    646611        // Must start in the body, so FunctionDecls can be a stopping point.
    647612        ast::Pass<MultiLevelExitCore> visitor( labelTable, labelGen );
    648         return stmt->accept( visitor );
     613        const ast::CompoundStmt * ret = stmt->accept( visitor );
     614        return ret;
    649615}
    650616
  • src/ControlStruct/MultiLevelExit.hpp

    r21fe17f r817bb3c  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // MultiLevelExit.hpp --
     7// MultiLevelExit.hpp -- Replaces CFA's local control flow with C's versions.
    88//
    99// Author           : Andrew Beach
    1010// Created On       : Mon Nov  1 13:49:00 2021
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Mon Nov  2 10:26:00 2021
    13 // Update Count     : 0
     12// Last Modified On : Mon Nov  5 19:20:00 2021
     13// Update Count     : 1
    1414//
    1515
     
    2020namespace ast {
    2121        class CompoundStmt;
    22     class Label;
     22        class Label;
    2323        class Stmt;
    2424}
     
    3131/// Mutate a function body to handle multi-level exits.
    3232const ast::CompoundStmt * multiLevelExitUpdate(
    33         const ast::CompoundStmt *, LabelToStmt *, LabelGenerator_new *);
     33        const ast::CompoundStmt *, const LabelToStmt &, LabelGenerator_new *);
    3434
    3535}
Note: See TracChangeset for help on using the changeset viewer.