Changeset a75d464
- Timestamp:
- Sep 14, 2020, 9:02:19 AM (4 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 9a05b81
- Parents:
- d1864da
- git-author:
- Peter A. Buhr <pabuhr@…> (09/14/20 08:55:23)
- git-committer:
- Peter A. Buhr <pabuhr@…> (09/14/20 09:02:19)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/theses/fangren_yu_COOP_S20/Report.tex
rd1864da ra75d464 15 15 \usepackage[usenames]{color} 16 16 \input{common} % common CFA document macros 17 \usepackage[dvips,plainpages=false,pdfpagelabels,pdfpagemode=UseNone,colorlinks=true,pagebackref=true,linkcolor=blue,citecolor=blue,urlcolor=blue,pagebackref=true,breaklinks=true]{hyperref} 18 \usepackage{breakurl} 19 20 \usepackage[pagewise]{lineno} 21 \renewcommand{\linenumberfont}{\scriptsize\sffamily} 22 23 % Default underscore is too low and wide. Cannot use lstlisting "literate" as replacing underscore 24 % removes it as a variable-name character so keywords in variables are highlighted. MUST APPEAR 25 % AFTER HYPERREF. 26 \renewcommand{\textunderscore}{\leavevmode\makebox[1.2ex][c]{\rule{1ex}{0.075ex}}} 27 \newcommand{\NOTE}{\textbf{NOTE}} 28 29 \setlength{\topmargin}{-0.45in} % move running title into header 30 \setlength{\headsep}{0.25in} 31 32 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 33 34 \CFADefaults 17 35 \lstset{ 36 language=C++, % make C++ the default language 18 37 escapechar=\$, % LaTeX escape in CFA code 19 38 moredelim=**[is][\color{red}]{`}{`}, 20 39 }% lstset 21 40 \lstMakeShortInline@% 22 \usepackage[dvips,plainpages=false,pdfpagelabels,pdfpagemode=UseNone,colorlinks=true,pagebackref=true,linkcolor=blue,citecolor=blue,urlcolor=blue,pagebackref=true,breaklinks=true]{hyperref}23 \usepackage{breakurl}24 25 \usepackage[pagewise]{lineno}26 \renewcommand{\linenumberfont}{\scriptsize\sffamily}27 28 % Default underscore is too low and wide. Cannot use lstlisting "literate" as replacing underscore29 % removes it as a variable-name character so keywords in variables are highlighted. MUST APPEAR30 % AFTER HYPERREF.31 \renewcommand{\textunderscore}{\leavevmode\makebox[1.2ex][c]{\rule{1ex}{0.075ex}}}32 33 \setlength{\topmargin}{-0.45in} % move running title into header34 \setlength{\headsep}{0.25in}35 36 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%37 38 \CFAStyle % use default CFA format-style39 41 \lstnewenvironment{C++}[1][] % use C++ style 40 42 {\lstset{language=C++,moredelim=**[is][\protect\color{red}]{`}{`},#1}} … … 82 84 \section{Overview} 83 85 84 cfa-cc is the reference compiler for the Cforallprogramming language, which is a non-86 cfa-cc is the reference compiler for the \CFA programming language, which is a non- 85 87 object-oriented extension to C. 86 Cforallattempts to introduce productive modern programming language features to C88 \CFA attempts to introduce productive modern programming language features to C 87 89 while maintaining as much backward-compatibility as possible, so that most existing C 88 programs can seamlessly work with Cforall.89 90 Since the Cforallproject was dated back to the early 2000s, and only restarted in the past90 programs can seamlessly work with \CFA. 91 92 Since the \CFA project was dated back to the early 2000s, and only restarted in the past 91 93 few years, there is a significant amount of legacy code in the current compiler codebase, 92 94 with little proper documentation available. This becomes a difficulty while developing new … … 94 96 problems. 95 97 96 Currently, the Cforallteam is also facing another problem: bad compiler performance. For98 Currently, the \CFA team is also facing another problem: bad compiler performance. For 97 99 the development of a new programming language, writing a standard library is an 98 100 important part. The incompetence of the compiler causes building the library files to take … … 106 108 performance bottleneck, namely the resolution algorithm. It is aimed to provide new 107 109 developers to the project enough guidance and clarify the purposes and behavior of certain 108 functions which are not mentioned in the previous Cforallresearch papers.110 functions which are not mentioned in the previous \CFA research papers. 109 111 110 112 … … 132 134 Declarations are introduced by standard C declarations, with the usual scoping rules. 133 135 In addition, declarations can also be introduced by the forall clause (which is the origin 134 of Cforall's name):136 of \CFA's name): 135 137 \begin{cfa} 136 138 forall (<$\emph{TypeParameterList}$> | <$\emph{AssertionList}$>) 137 139 $\emph{declaration}$ 138 140 \end{cfa} 139 Type parameters in Cforall are similar to \CC template type parameters. The Cforall141 Type parameters in \CFA are similar to \CC template type parameters. The \CFA 140 142 declaration 141 143 \begin{cfa} … … 147 149 \end{C++} 148 150 149 Assertions are a distinctive feature of Cforall: contrary to the \CC template where150 arbitrary functions and operators can be used in a template definition, in a Cforall151 Assertions are a distinctive feature of \CFA: contrary to the \CC template where 152 arbitrary functions and operators can be used in a template definition, in a \CFA 151 153 parametric function, operations on parameterized types must be declared in assertions. 152 154 … … 205 207 tree data structure, implemented with visitor pattern, and can be loosely described with 206 208 the following pseudocode: 207 \begin{ cfa}209 \begin{C++} 208 210 Pass::visit (node_t node) { 209 211 previsit(node); … … 213 215 postvisit(node); 214 216 } 215 \end{ cfa}217 \end{C++} 216 218 Operations in previsit() happen in preorder (top to bottom) and operations in 217 219 postvisit() happen in postorder (bottom to top). The precise order of recursive … … 247 249 \item 248 250 WithSymbolTable gives a managed symbol table with built-in scoping rule handling 249 ( e.g.on entering and exiting a block statement)251 (\eg on entering and exiting a block statement) 250 252 \end{itemize} 251 \ textbf{NOTE}: If a pass extends the functionality of another existing pass, due to \CC overloading253 \NOTE: If a pass extends the functionality of another existing pass, due to \CC overloading 252 254 resolution rules, it \textbf{must} explicitly introduce the inherited previsit and postvisit procedures 253 255 to its own scope, or otherwise they will not be picked up by template resolution: 254 \begin{ cfa}256 \begin{C++} 255 257 class Pass2: public Pass1 { 256 258 using Pass1::previsit; … … 258 260 // new procedures 259 261 } 260 \end{ cfa}262 \end{C++} 261 263 262 264 … … 272 274 273 275 The core of new-ast is a customized implementation of smart pointers, similar to 274 @std::shared_ptr@ and @std::weak_ptr@ in C++standard library. Reference counting is276 @std::shared_ptr@ and @std::weak_ptr@ in \CC standard library. Reference counting is 275 277 used to detect sharing and allows optimization. For a purely functional (a.k.a. immutable) 276 278 data structure, all mutations are modelled by shallow copies along the path of mutation. … … 309 311 Decrements this node's strong or weak reference count. If strong reference count reaches 310 312 zero, the node is deleted by default. 311 \ textbf{NOTE}: Setting @do_delete@ to false may result in a detached node. Subsequent code should313 \NOTE: Setting @do_delete@ to false may result in a detached node. Subsequent code should 312 314 manually delete the node or assign it to a strong pointer to prevent memory leak. 313 315 Reference counting functions are internally called by @ast::ptr_base@. … … 325 327 Otherwise, returns shallowCopy(node). 326 328 It is an error to mutate a shared node that is weak-referenced. Currently this does not 327 happen. The problem may appear once weak pointers to shared nodes ( e.g.expression329 happen. The problem may appear once weak pointers to shared nodes (\eg expression 328 330 nodes) are used; special care will be needed. 329 331 330 \ textbf{NOTE}: This naive uniqueness check may not be sufficient in some cases. A discussion of the332 \NOTE: This naive uniqueness check may not be sufficient in some cases. A discussion of the 331 333 issue is presented at the end of this section. 332 334 \begin{C++} … … 372 374 source code for details. 373 375 376 For example, in the above diagram, if mutation of B is wanted while at P1, the call using 377 @chain_mutate@ looks like the following: 378 \begin{C++} 379 chain_mutate(P1.a)(&A.b) = new_value_of_b; 380 \end{C++} 381 Note that if some node in chain mutate is shared (therefore shallow copied), it implies that 382 every node further down will also be copied, thus correctly executing the functional 383 mutation algorithm. This example code creates copies of both A and B and performs 384 mutation on the new nodes, so that the other tree P2-A-B is untouched. 385 However, if a pass traverses down to node B and performs mutation, for example, in 386 @postvisit(B)@, information on sharing higher up is lost. Since the new-ast structure is only in 387 experimental use with the resolver algorithm, which mostly rebuilds the tree bottom-up, 388 this issue does not actually happen. It should be addressed in the future when other 389 compilation passes are migrated to new-ast and many of them contain procedural 390 mutations, where it might cause accidental mutations to other logically independent trees 391 (\eg common sub-expression) and become a bug. 392 393 394 \vspace*{20pt} % FIX ME, spacing problem with this heading ??? 395 \section{Compiler Algorithm Documentation} 396 397 This documentation currently covers most of the resolver, data structures used in variable 398 and expression resolution, and a few directly related passes. Later passes involving code 399 generation is not included yet; documentation for those will be done afterwards. 400 401 \subsection{Symbol Table} 402 403 \NOTE: For historical reasons, the symbol table data structure was called ``indexer'' in the 404 old implementation. Hereby we will be using the name SymbolTable everywhere. 405 The symbol table stores a mapping from names to declarations and implements a similar 406 name space separation rule, and the same scoping rules in standard C.\footnote{ISO/IEC 9899:1999, Sections 6.2.1 and 6.2.3} The difference in 407 name space rule is that typedef aliases are no longer considered ordinary identifiers. 408 In addition to C tag types (struct, union, enum), \CFA introduces another tag type, trait, 409 which is a named collection of assertions. 410 411 \subsubsection{Source: AST/SymbolTable.hpp} 412 413 \subsubsection{Source: SymTab/Indexer.h} 414 415 \begin{C++} 416 SymbolTable::addId(const DeclWithType * decl) 417 \end{C++} 418 Since \CFA allows overloading of variables and functions, ordinary identifier names need 419 to be mangled. The mangling scheme is closely based on the Itanium \CC ABI,\footnote{\url{https://itanium-cxx-abi.github.io/cxx-abi/abi.html}, Section 5.1} while 420 making adaptations to \CFA specific features, mainly assertions and overloaded variables 421 by type. Naming conflicts are handled by mangled names; lookup by name returns a list of 422 declarations with the same literal identifier name. 423 424 \begin{C++} 425 SymbolTable::addStruct(const StructDecl * decl) 426 SymbolTable::addUnion(const UnionDecl * decl) 427 SymbolTable::addEnum(const EnumDecl * decl) 428 SymbolTable::addTrait(const TraitDecl * decl) 429 \end{C++} 430 Adds a tag type declaration to the symbol table. 431 \begin{C++} 432 SymbolTable::addType(const NamedTypeDecl * decl) 433 \end{C++} 434 Adds a typedef alias to the symbol table. 435 436 \textbf{C Incompatibility Note}: Since Cforall allows using struct, union and enum type names 437 without the keywords, typedef names and tag type names cannot be disambiguated by 438 syntax rules. Currently the compiler puts them together and disallows collision. The 439 following program is valid C but not valid Cforall: 440 \begin{C++} 441 struct A {}; 442 typedef int A; 443 // gcc: ok, cfa: Cannot redefine typedef A 444 \end{C++} 445 In actual practices however, such usage is extremely rare, and typedef struct A A; is 446 not considered an error, but silently discarded. Therefore, we expect this change to have 447 minimal impact on existing C programs. 448 Meanwhile, the following program is allowed in Cforall: 449 \begin{C++} 450 typedef int A; 451 void A(); 452 // gcc: A redeclared as different kind of symbol, cfa: ok 453 \end{C++} 454 455 \subsection{Type Environment and Unification} 456 457 The core of parametric type resolution algorithm. 458 Type Environment organizes type parameters in \textbf{equivalent classes} and maps them to 459 actual types. Unification is the algorithm that takes two (possibly parametric) types and 460 parameter mappings and attempts to produce a common type by matching the type 461 environments. 462 463 The unification algorithm is recursive in nature and runs in two different modes internally: 464 \begin{itemize} 465 \item 466 \textbf{Exact} unification mode requires equivalent parameters to match perfectly; 467 \item 468 \textbf{Inexact} unification mode allows equivalent parameters to be converted to a 469 common type. 470 \end{itemize} 471 For a pair of matching parameters (actually, their equivalent classes), if either side is open 472 (not bound to a concrete type yet), they are simply combined. 473 474 Within inexact mode, types are allowed to differ on their cv-qualifiers; additionally, if a 475 type never appear either in parameter list or as the base type of a pointer, it may also be 476 widened (i.e. safely converted). As Cforall currently does not implement subclassing similar 477 to object-oriented languages, widening conversions are on primitive types only, for 478 example the conversion from int to long. 479 480 The need for two unification modes come from the fact that parametric types are 481 considered compatible only if all parameters are exactly the same (not just compatible). 482 Pointer types also behaves similarly; in fact, they may be viewed as a primitive kind of 483 parametric types. @int*@ and @long*@ are different types, just like @vector(int)@ and 484 @vector(long)@ are, for the parametric type @vector(T)@. 485 486 The resolver should use the following ``@public@'' functions:\footnote{ 487 Actual code also tracks assertions on type parameters; those extra arguments are omitted here for 488 conciseness.} 489 490 491 \subsubsection{Source: ResolvExpr/Unify.cc} 492 493 \begin{C++} 494 bool unify(const Type *type1, const Type *type2, TypeEnvironment &env, 495 OpenVarSet &openVars, const SymbolTable &symtab, Type *&commonType) 496 \end{C++} 497 Attempts to unify @type1@ and @type2@ with current type environment. 498 499 If operation succeeds, @env@ is modified by combining the equivalence classes of matching 500 parameters in @type1@ and @type2@, and their common type is written to commonType. 501 502 If operation fails, returns false. 503 \begin{C++} 504 bool typesCompatible(const Type * type1, const Type * type2, const 505 SymbolTable &symtab, const TypeEnvironment &env) 506 bool typesCompatibleIgnoreQualifiers(const Type * type1, const Type * 507 type2, const SymbolTable &symtab, const TypeEnvironment &env) 508 \end{C++} 509 510 Determines if type1 and type2 can possibly be the same type. The second version ignores 511 the outermost cv-qualifiers if present.\footnote{ 512 In const \lstinline@int * const@, only the second \lstinline@const@ is ignored.} 513 514 The call has no side effect. 515 516 \NOTE: No attempts are made to widen the types (exact unification is used), although the 517 function names may suggest otherwise. E.g. @typesCompatible(int, long)@ returns false. 518 519 520 \subsection{Expression Resolution} 521 522 The design of the current version of expression resolver is outlined in the Ph.D. Thesis from 523 Aaron Moss~\cite{Moss19}. 524 525 A summary of the resolver algorithm for each expression type is presented below. 526 527 All overloadable operators are modelled as function calls. For a function call, 528 interpretations of the function and arguments are found recursively. Then the following 529 steps produce a filtered list of valid interpretations: 530 \begin{enumerate} 531 \item 532 From all possible combinations of interpretations of the function and arguments, 533 those where argument types may be converted to function parameter types are 534 considered valid. 535 \item 536 Valid interpretations with the minimum sum of argument costs are kept. 537 \item 538 Argument costs are then discarded; the actual cost for the function call expression is 539 the sum of conversion costs from the argument types to parameter types. 540 \item 541 For each return type, the interpretations with satisfiable assertions are then sorted 542 by actual cost computed in step 3. If for a given type, the minimum cost 543 interpretations are not unique, it is said that for that return type the interpretation 544 is ambiguous. If the minimum cost interpretation is unique but contains an 545 ambiguous argument, it is also considered ambiguous. 546 \end{enumerate} 547 Therefore, for each return type, the resolver produces either of: 548 \begin{itemize} 549 \item 550 No alternatives 551 \item 552 A single valid alternative 553 \item 554 An ambiguous alternative 555 \end{itemize} 556 Note that an ambiguous alternative may be discarded at the parent expressions because a 557 different return type matches better for the parent expressions. 558 559 The non-overloadable expressions in Cforall are: cast expressions, address-of (unary @&@) 560 expressions, short-circuiting logical expressions (@&&@, @||@) and ternary conditional 561 expression (@?:@). 562 563 For a cast expression, the convertible argument types are kept. Then the result is selected 564 by lowest argument cost, and further by lowest conversion cost to target type. If the lowest 565 cost is still not unique, or an ambiguous argument interpretation is selected, the cast 566 expression is ambiguous. In an expression statement, the top level expression is implicitly 567 cast to void. 568 569 For an address-of expression, only lvalue results are kept and the minimum cost is selected. 570 571 For logical expressions @&&@ and @||@, arguments are implicitly cast to bool, and follow the rule 572 of cast expression as above. 573 574 For the ternary conditional expression, the condition is implicitly cast to bool, and the 575 branch expressions must have compatible types. Each pair of compatible branch 576 expression types produce a possible interpretation, and the cost is defined as the sum of 577 expression costs plus the sum of conversion costs to the common type. 578 579 TODO: Write a specification for expression costs. 580 581 582 \subsection{Assertion Satisfaction} 583 584 The resolver tries to satisfy assertions on expressions only when it is needed: either while 585 selecting from multiple alternatives of a same result type for a function call (step 4 of 586 resolving function calls), or upon reaching the top level of an expression statement. 587 588 Unsatisfiable alternatives are discarded. Satisfiable alternatives receive \textbf{implicit 589 parameters}: in Cforall, parametric functions are designed such that they can be compiled 590 separately, as opposed to \CC templates which are only compiled at instantiation. Given a 591 parametric function definition: 592 \begin{C++} 593 forall (otype T | {void foo(T);}) 594 void bar (T t) { foo(t); } 595 \end{C++} 596 The function bar does not know which @foo@ to call when compiled without knowing the call 597 site, so it requests a function pointer to be passed as an extra argument. At the call site, 598 implicit parameters are automatically inserted by the compiler. 599 600 \textbf{TODO}: Explain how recursive assertion satisfaction and polymorphic recursion work. 601 602 603 \section{Tests} 604 605 \subsection{Test Suites} 606 607 Automatic test suites are located under the @tests/@ directory. A test case consists of an 608 input CFA source file (name ending with @.cfa@), and an expected output file located 609 in @.expect/@ directory relative to the source file, with the same file name ending with @.txt@. 610 So a test named @tuple/tupleCast@ has the following files, for example: 611 \begin{C++} 612 tests/ 613 .. tuple/ 614 ...... .expect/ 615 .......... tupleCast.txt 616 ...... tupleCast.cfa 617 \end{C++} 618 If compilation fails, the error output is compared to the expect file. If compilation succeeds, 619 the built program is run and its output compared to the expect file. 620 To run the tests, execute the test script @test.py@ under the @tests/@ directory, with a list of 621 test names to be run, or @--all@ to run all tests. The test script reports test cases 622 fail/success, compilation time and program run time. 623 624 625 \subsection{Performance Reports} 626 627 To turn on performance reports, pass @-S@ flag to the compiler. 628 629 3 kinds of performance reports are available: 630 \begin{enumerate} 631 \item 632 Time, reports time spent in each compilation step 633 \item 634 Heap, reports number of dynamic memory allocations, total bytes allocated, and 635 maximum heap memory usage 636 \item 637 Counters, for certain predefined statistics; counters can be registered anywhere in 638 the compiler as a static object, and the interface can be found at 639 @Common/Stats/Counter.h@. 640 \end{enumerate} 641 It is suggested to run performance tests with optimized build (@g++@ flag @-O3@) 642 643 374 644 \bibliographystyle{plain} 375 645 \bibliography{pl}
Note: See TracChangeset
for help on using the changeset viewer.