Ignore:
Timestamp:
May 18, 2022, 3:59:28 PM (2 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, ast-experimental, master, pthread-emulation, qualifiedEnum
Children:
76f5e9f
Parents:
622a358 (diff), e6cf857f (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Tuples/Tuples.cc

    r622a358 r288927f  
    1010// Created On       : Mon Jun 17 14:41:00 2019
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Tue Jun 18  9:31:00 2019
    13 // Update Count     : 1
     12// Last Modified On : Mon May 16 16:15:00 2022
     13// Update Count     : 2
    1414//
    1515
     
    1818#include "AST/Pass.hpp"
    1919#include "AST/LinkageSpec.hpp"
     20#include "Common/PassVisitor.h"
    2021#include "InitTweak/InitTweak.h"
    2122
     
    2324
    2425namespace {
     26        /// Checks if impurity (read: side-effects) may exist in a piece of code.
     27        /// Currently gives a very crude approximation, wherein any function
     28        /// call expression means the code may be impure.
     29        struct ImpurityDetector_old : public WithShortCircuiting {
     30                bool const ignoreUnique;
     31                bool maybeImpure;
     32
     33                ImpurityDetector_old( bool ignoreUnique ) :
     34                        ignoreUnique( ignoreUnique ), maybeImpure( false )
     35                {}
     36
     37                void previsit( const ApplicationExpr * appExpr ) {
     38                        visit_children = false;
     39                        if ( const DeclarationWithType * function =
     40                                        InitTweak::getFunction( appExpr ) ) {
     41                                if ( function->linkage == LinkageSpec::Intrinsic ) {
     42                                        if ( function->name == "*?" || function->name == "?[?]" ) {
     43                                                // intrinsic dereference, subscript are pure,
     44                                                // but need to recursively look for impurity
     45                                                visit_children = true;
     46                                                return;
     47                                        }
     48                                }
     49                        }
     50                        maybeImpure = true;
     51                }
     52
     53                void previsit( const UntypedExpr * ) {
     54                        maybeImpure = true;
     55                        visit_children = false;
     56                }
     57
     58                void previsit( const UniqueExpr * ) {
     59                        if ( ignoreUnique ) {
     60                                // bottom out at unique expression.
     61                                // The existence of a unique expression doesn't change the purity of an expression.
     62                                // That is, even if the wrapped expression is impure, the wrapper protects the rest of the expression.
     63                                visit_children = false;
     64                                return;
     65                        }
     66                }
     67        };
     68
     69        bool detectImpurity( const Expression * expr, bool ignoreUnique ) {
     70                PassVisitor<ImpurityDetector_old> detector( ignoreUnique );
     71                expr->accept( detector );
     72                return detector.pass.maybeImpure;
     73        }
     74
    2575        /// Determines if impurity (read: side-effects) may exist in a piece of code. Currently gives
    2676        /// a very crude approximation, wherein any function call expression means the code may be
    2777        /// impure.
    2878    struct ImpurityDetector : public ast::WithShortCircuiting {
    29                 bool maybeImpure = false;
     79                bool result = false;
    3080
    3181                void previsit( ast::ApplicationExpr const * appExpr ) {
     
    3686                                }
    3787                        }
    38                         maybeImpure = true; visit_children = false;
     88                        result = true; visit_children = false;
    3989                }
    4090                void previsit( ast::UntypedExpr const * ) {
    41                         maybeImpure = true; visit_children = false;
     91                        result = true; visit_children = false;
    4292                }
    4393        };
     94
    4495        struct ImpurityDetectorIgnoreUnique : public ImpurityDetector {
    4596                using ImpurityDetector::previsit;
     
    4899                }
    49100        };
    50 
    51         template<typename Detector>
    52         bool detectImpurity( const ast::Expr * expr ) {
    53                 ast::Pass<Detector> detector;
    54                 expr->accept( detector );
    55                 return detector.core.maybeImpure;
    56         }
    57101} // namespace
    58102
    59103bool maybeImpure( const ast::Expr * expr ) {
    60         return detectImpurity<ImpurityDetector>( expr );
     104        return ast::Pass<ImpurityDetector>::read( expr );
    61105}
    62106
    63107bool maybeImpureIgnoreUnique( const ast::Expr * expr ) {
    64         return detectImpurity<ImpurityDetectorIgnoreUnique>( expr );
     108        return ast::Pass<ImpurityDetectorIgnoreUnique>::read( expr );
     109}
     110
     111bool maybeImpure( const Expression * expr ) {
     112        return detectImpurity( expr, false );
     113}
     114
     115bool maybeImpureIgnoreUnique( const Expression * expr ) {
     116        return detectImpurity( expr, true );
    65117}
    66118
Note: See TracChangeset for help on using the changeset viewer.