Changeset dcfcf368 for doc/theses/jiada_liang_MMath/CFAenum.tex
- Timestamp:
- Sep 14, 2024, 5:07:55 PM (5 weeks ago)
- Branches:
- master
- Children:
- 8c79dc3c
- Parents:
- 3733643
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/theses/jiada_liang_MMath/CFAenum.tex
r3733643 rdcfcf368 71 71 char * s = label( O_TRUNC ); $\C{// "O\_TRUNC"}$ 72 72 int open = posn( O_WRONLY ); $\C{// 1}$ 73 s = label( mode ); $\C{// "O\_RDONLY"}$ 74 int open = posn( mode ); $\C{// 0}$ 73 75 \end{cfa} 74 76 Equality and relational operations are available. … … 131 133 calling constructors happens at runtime (dynamic). 132 134 135 133 136 \section{Implementation} 134 \CFA-cc is is a transpiler that translates \CFA code into C, which can later be compiled by a C compiler. 135 136 During t he transpilation, \CFA-cc breaks a \CFA enumeration definition into a definition of a C enumeration with the same name and auxiliary arrays: a label array and avalue array for a typed enumeration.137 138 \CFA-cc is is a transpiler translating \CFA code into C, which is compiled by a C compiler. 139 During transpilation, \CFA-cc breaks a \CFA enumeration definition into a definition of a C enumeration with the same name and auxiliary arrays: a label and value array for a typed enumeration. 137 140 For example: 138 141 \begin{cfa} 139 // CFA (source): 140 enum(T) E { E1=t1, E2=t2, E3=t3 }; 142 enum( T ) E { E1 = t1, E2 = t2, E3 = t3 }; 141 143 \end{cfa} 142 144 is compiled into: 143 145 \begin{cfa} 144 // C (transpiled by cfa-cc):145 146 enum E { E1, E2, E3 }; 146 const char * E_labels[3] = { "E1", "E2", "E3" }; 147 const T E_values [3] = { t1, t2, t3 }; 148 \end{cfa} 149 The generated C enumeration will have enumerator values resemble \CFA enumerator positions thanks to C's auto-initialization scheme. 150 A \CFA enumeration variable definition is same in \CFA and C, before or after the transpilation. 151 For example: 147 static const char * E_labels[3] = { "E1", "E2", "E3" }; 148 static const T E_values[3] = { t1, t2, t3 }; 149 \end{cfa} 150 The generated C enumeration has enumerator values that match \CFA enumerator positions because of C's auto-initialization. 151 A \CFA enumeration variable definition is the same in \CFA as C, \eg: 152 152 \begin{cfa} 153 153 enum E e = E1; 154 e; 155 \end{cfa} 156 These two expressions will not change by \CFA-cc. A \CFA enumeration variable will always have the same underlying representation as its generated 157 C enumeration. This implies \CFA enumeration variable does not take up extra memory and \CFA enumeration use @posn@ as its underlying representation. 158 159 Notice that value and label arrays are dynamically allocated data structures that take up 160 memory. If an enumeration is globally defined, the arrays are allocated in the @.data@ section and will be initialized before the program execution. 161 Otherwise, if an enumeration has its definition in a local scope, these arrays will be allocated on the stack and be initialized when the program counter 162 reaches the code location of the enumeration definition. 163 164 % This bring a considerable overhead to the program, in terms of both execution time and storage. 165 % An opaque enumeration has no overhead 166 % for values, and it has been suggested as a future work to leave as an option to not generate the label array. 167 168 Alongs with the enumeration defintion, \CFA-cc adds defintions of attribute functions: @posn@, @label@ and @value@: 154 e = E2; 155 \end{cfa} 156 so these expressions remain unchanged by \CFA-cc. 157 Therefore, a \CFA enumeration variable has the same underlying representation as its generated C enumeration. 158 This semantics implies a \CFA enumeration variable does not use memory, that @posn@ can use its underlying representation, and the label and value arrays take little storage. 159 It should be possible to eliminated the two arrays if unused, either by \CFA if local to a translation unit and unused, or by the linker if global but unreferenced. 160 Also, the label and value arrays are declared @static@ and initialized with constants, so the arrays are allocated in the @.data@ section and initialized before program execution. 161 Hence, there is no addition execution cost unless new enumeration features are use, and storage usage is minimal as the number of enumerations in a program is small as is the number of enumerators in an enumeration. 162 163 Along with the enumeration definition, \CFA-cc generates definitions of the attribute functions, @posn@, @label@ and @value@, for each enumeration: 169 164 \begin{cfa} 170 165 inline int posn( E e ) { return (int) e; } … … 172 167 inline const * E_value( E e ) { return E_values[ (int) e ]; } 173 168 \end{cfa} 174 These functions are not implemented in \CFA code: they are Abstract Syntax Tree (AST) nodes appends to the Abstract Syntax Tree (AST). 175 Notably, the AST subnode for the "cast to @int@" expression inside the functions is annotated as reinterpreted casts. 176 In order words, the effect of a case is only to change the type of an expression, and it stops further reduction on the expression \see{\VRef{s:ValueConversion}}. 177 178 Consequently, \CFA enumeration comes with space and runtime overhead, both for enumeration definition and function call to attribute functions. \CFA made efforts to reduce the runtime 179 overhead on function calls by aggressively reducing @label()@ and @value()@ function calls on an enumeration constant to a constant expression. The interpreted casts are extraneous 180 after type checking and removed in later steps. A @label()@ and @value()@ call on an enumeration variable is a lookup of an element of an array of constant values, and it is up to the 181 C compiler to optimize its runtime. While OpaqueEnum is effectively an "opt-out" of the value overhead, it has been suggested that an option to "opt-out" from labels be added as well. 182 A @label()@ function definition is still necessary to accomplish enumeration traits. But it will return an empty string for an enumeration label when "opt-out" or the enumerator name 183 when it is called on an enumeration constant. It will allow a user not to pay the overhead for labels when the enumerator names of a particular enumerated type are not helpful. 169 where the function calls are normally inlined by the backend C compiler into a few instructions. 170 These functions simplify the job of getting the enumerations types through the type system in the same way as normal functions and calls. 171 Note, the cast to @int@ is actually an internal reinterpreted cast added before type resolution to stop further reduction on the expression by the type resolver \see{\VRef{s:ValueConversion}} and removed in code generation. 172 Finally, to further mitigate \CFA enumeration costs, calls to @label@ and @value@ with an enumeration constant are unrolled into the appropriate constant expression, although this could be left to the backend C compiler. 173 Hence, in space and time costs, \CFA enumerations follow the C philosophy of only paying for what is used, modulo some future work to convince the linker to remove unaccessed @label@ and @value@ arrays, possibly with @weak@ attributes. 174 184 175 185 176 \section{Value Conversion} … … 214 205 % \begin{cfa} 215 206 % forall(T | @CfaEnum(T)@) void bar(T); 216 % 207 % 217 208 % bar(a); $\C{// (3), with cost (0, 0, 1, 0, 0, 0, 0, 0)}$ 218 209 % \end{cfa} … … 236 227 \end{cfa} 237 228 238 The restriction on C's enumeration initializers being constant expression is relaxed on \CFA enumeration. 239 Therefore, an enumerator initializer allows function calls like @?+?( S & s, one_t )@ and @?{}( S & s, zero_t )@. 240 It is because the values of \CFA enumerators are not stored in the compiled enumeration body but in the @value@ array, which 229 The restriction on C's enumeration initializers being constant expression is relaxed on \CFA enumeration. 230 Therefore, an enumerator initializer allows function calls like @?+?( S & s, one_t )@ and @?{}( S & s, zero_t )@. 231 It is because the values of \CFA enumerators are not stored in the compiled enumeration body but in the @value@ array, which 241 232 allows dynamic initialization. 242 233 … … 249 240 \end{cfa} 250 241 Enumeration @Greek@ may have more or less enumerators than @Letter@, but its enumerator values \emph{must} be from @Letter@. 251 Therefore, the set of @Greek@ enumerator values in a subset of the @Letter@ enumerator values. 242 Therefore, the set of @Greek@ enumerator values in a subset of the @Letter@ enumerator values. 252 243 @Letter@ is type compatible with enumeration @Letter@ because value conversions are inserted whenever @Letter@ is used in place of @Greek@. 253 244 \begin{cfa} … … 291 282 However, the position of the underlying representation is the order of the enumerator in the new enumeration. 292 283 \begin{cfa} 293 enum() E1 { B }; $\C{// B}$ 284 enum() E1 { B }; $\C{// B}$ 294 285 enum() E2 { C, D }; $\C{// C D}$ 295 286 enum() E3 { inline E1, inline E2, E }; $\C{// {\color{red}[\(_{E1}\)} B {\color{red}]} {\color{red}[\(_{E2}\)} C D {\color{red}]} E}$ … … 298 289 In the example, @B@ is at position 0 in @E1@ and @E3@, but position 1 in @E4@ as @A@ takes position 0 in @E4@. 299 290 @C@ is at position 0 in @E2@, 1 in @E3@, and 2 in @E4@. 300 @D@ is at position 1 in @E2@, 2 in @E3@, and 3 in @E4@. 301 302 A subtype enumeration can be casted, or implicitly converted into its supertype, with a @safe@ cost, called \newterm{enumeration conversion}. 291 @D@ is at position 1 in @E2@, 2 in @E3@, and 3 in @E4@. 292 293 A subtype enumeration can be casted, or implicitly converted into its supertype, with a @safe@ cost, called \newterm{enumeration conversion}. 303 294 \begin{cfa} 304 295 enum E2 e2 = C;
Note: See TracChangeset
for help on using the changeset viewer.