source: src/Tuples/Tuples.cc

Last change on this file was 11df881, checked in by Andrew Beach <ajbeach@…>, 3 weeks ago

Updated documentation on pre-resolver passes, moving code to headers instead of uses. Note that some comments were just copied over, I don't know if they are accurate.

  • Property mode set to 100644
File size: 3.5 KB
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
7// Tuples.cc -- A collection of tuple operations.
8//
9// Author           : Andrew Beach
10// Created On       : Mon Jun 17 14:41:00 2019
11// Last Modified By : Andrew Beach
12// Last Modified On : Mon May 16 16:15:00 2022
13// Update Count     : 2
14//
15
16#include "Tuples.h"
17
18#include "AST/Pass.hpp"
19#include "AST/LinkageSpec.hpp"
20#include "Common/PassVisitor.h"
21#include "InitTweak/InitTweak.h"
22
23namespace Tuples {
24
25namespace {
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
75        /// Determines if impurity (read: side-effects) may exist in a piece of code. Currently gives
76        /// a very crude approximation, wherein any function call expression means the code may be
77        /// impure.
78    struct ImpurityDetector : public ast::WithShortCircuiting {
79                bool result = false;
80
81                void previsit( ast::ApplicationExpr const * appExpr ) {
82                        if ( ast::DeclWithType const * function = InitTweak::getFunction( appExpr ) ) {
83                                if ( function->linkage == ast::Linkage::Intrinsic
84                                                && ( function->name == "*?" || function->name == "?[?]" ) ) {
85                                        return;
86                                }
87                        }
88                        result = true; visit_children = false;
89                }
90                void previsit( ast::UntypedExpr const * ) {
91                        result = true; visit_children = false;
92                }
93        };
94
95        struct ImpurityDetectorIgnoreUnique : public ImpurityDetector {
96                using ImpurityDetector::previsit;
97                void previsit( ast::UniqueExpr const * ) {
98                        visit_children = false;
99                }
100        };
101} // namespace
102
103bool maybeImpure( const ast::Expr * expr ) {
104        return ast::Pass<ImpurityDetector>::read( expr );
105}
106
107bool maybeImpureIgnoreUnique( const ast::Expr * 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 );
117}
118
119} // namespace Tuples
120
121// Local Variables: //
122// tab-width: 4 //
123// mode: c++ //
124// compile-command: "make install" //
125// End: //
Note: See TracBrowser for help on using the repository browser.