16bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines//===- ThreadSafetyTraverse.h ----------------------------------*- C++ --*-===// 26bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// 36bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// The LLVM Compiler Infrastructure 46bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// 56bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// This file is distributed under the University of Illinois Open Source 66bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// License. See LICENSE.TXT for details. 76bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// 86bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines//===----------------------------------------------------------------------===// 96bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// 106bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// This file defines a framework for doing generic traversals and rewriting 116bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// operations over the Thread Safety TIL. 126bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// 136bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// UNDER CONSTRUCTION. USE AT YOUR OWN RISK. 146bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// 156bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines//===----------------------------------------------------------------------===// 166bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#ifndef LLVM_CLANG_THREAD_SAFETY_TRAVERSE_H 186bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#define LLVM_CLANG_THREAD_SAFETY_TRAVERSE_H 196bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "ThreadSafetyTIL.h" 216bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 226bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesnamespace clang { 236bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesnamespace threadSafety { 246bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesnamespace til { 256bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 266bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// Defines an interface used to traverse SExprs. Traversals have been made as 276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// generic as possible, and are intended to handle any kind of pass over the 286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// AST, e.g. visiters, copying, non-destructive rewriting, destructive 296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// (in-place) rewriting, hashing, typing, etc. 306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// 316bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// Traversals implement the functional notion of a "fold" operation on SExprs. 326bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// Each SExpr class provides a traverse method, which does the following: 336bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// * e->traverse(v): 346bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// // compute a result r_i for each subexpression e_i 356bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// for (i = 1..n) r_i = v.traverse(e_i); 366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// // combine results into a result for e, where X is the class of e 376bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// return v.reduceX(*e, r_1, .. r_n). 386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// 396bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// A visitor can control the traversal by overriding the following methods: 406bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// * v.traverse(e): 416bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// return v.traverseByCase(e), which returns v.traverseX(e) 426bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// * v.traverseX(e): (X is the class of e) 436bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// return e->traverse(v). 446bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// * v.reduceX(*e, r_1, .. r_n): 456bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// compute a result for a node of type X 466bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// 476bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// The reduceX methods control the kind of traversal (visitor, copy, etc.). 48ef8225444452a1486bd721f3285301fe84643b00Stephen Hines// They are defined in derived classes. 49ef8225444452a1486bd721f3285301fe84643b00Stephen Hines// 50ef8225444452a1486bd721f3285301fe84643b00Stephen Hines// Class R defines the basic interface types (R_SExpr). 51ef8225444452a1486bd721f3285301fe84643b00Stephen Hinestemplate <class Self, class R> 52ef8225444452a1486bd721f3285301fe84643b00Stephen Hinesclass Traversal { 536bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinespublic: 54ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Self *self() { return static_cast<Self *>(this); } 556bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 566bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Traverse an expression -- returning a result of type R_SExpr. 576bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Override this method to do something for every expression, regardless 58ef8225444452a1486bd721f3285301fe84643b00Stephen Hines // of which kind it is. 59ef8225444452a1486bd721f3285301fe84643b00Stephen Hines typename R::R_SExpr traverse(SExprRef &E, typename R::R_Ctx Ctx) { 60ef8225444452a1486bd721f3285301fe84643b00Stephen Hines return traverse(E.get(), Ctx); 616bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 626bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 63ef8225444452a1486bd721f3285301fe84643b00Stephen Hines typename R::R_SExpr traverse(SExpr *E, typename R::R_Ctx Ctx) { 64ef8225444452a1486bd721f3285301fe84643b00Stephen Hines return traverseByCase(E, Ctx); 656bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 666bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 676bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Helper method to call traverseX(e) on the appropriate type. 68ef8225444452a1486bd721f3285301fe84643b00Stephen Hines typename R::R_SExpr traverseByCase(SExpr *E, typename R::R_Ctx Ctx) { 696bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines switch (E->opcode()) { 706bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#define TIL_OPCODE_DEF(X) \ 716bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines case COP_##X: \ 72ef8225444452a1486bd721f3285301fe84643b00Stephen Hines return self()->traverse##X(cast<X>(E), Ctx); 736bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "ThreadSafetyOps.def" 746bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#undef TIL_OPCODE_DEF 756bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 766bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 776bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 786bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// Traverse e, by static dispatch on the type "X" of e. 796bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// Override these methods to do something for a particular kind of term. 806bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#define TIL_OPCODE_DEF(X) \ 81ef8225444452a1486bd721f3285301fe84643b00Stephen Hines typename R::R_SExpr traverse##X(X *e, typename R::R_Ctx Ctx) { \ 82ef8225444452a1486bd721f3285301fe84643b00Stephen Hines return e->traverse(*self(), Ctx); \ 83ef8225444452a1486bd721f3285301fe84643b00Stephen Hines } 846bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "ThreadSafetyOps.def" 856bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#undef TIL_OPCODE_DEF 866bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines}; 876bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 886bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 89ef8225444452a1486bd721f3285301fe84643b00Stephen Hines// Base class for simple reducers that don't much care about the context. 90ef8225444452a1486bd721f3285301fe84643b00Stephen Hinesclass SimpleReducerBase { 916bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinespublic: 92ef8225444452a1486bd721f3285301fe84643b00Stephen Hines enum TraversalKind { 93ef8225444452a1486bd721f3285301fe84643b00Stephen Hines TRV_Normal, 94ef8225444452a1486bd721f3285301fe84643b00Stephen Hines TRV_Decl, 95ef8225444452a1486bd721f3285301fe84643b00Stephen Hines TRV_Lazy, 96ef8225444452a1486bd721f3285301fe84643b00Stephen Hines TRV_Type 97ef8225444452a1486bd721f3285301fe84643b00Stephen Hines }; 98ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 99ef8225444452a1486bd721f3285301fe84643b00Stephen Hines // R_Ctx defines a "context" for the traversal, which encodes information 100ef8225444452a1486bd721f3285301fe84643b00Stephen Hines // about where a term appears. This can be used to encoding the 101ef8225444452a1486bd721f3285301fe84643b00Stephen Hines // "current continuation" for CPS transforms, or other information. 102ef8225444452a1486bd721f3285301fe84643b00Stephen Hines typedef TraversalKind R_Ctx; 103ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 104ef8225444452a1486bd721f3285301fe84643b00Stephen Hines // Create context for an ordinary subexpression. 105ef8225444452a1486bd721f3285301fe84643b00Stephen Hines R_Ctx subExprCtx(R_Ctx Ctx) { return TRV_Normal; } 106ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 107ef8225444452a1486bd721f3285301fe84643b00Stephen Hines // Create context for a subexpression that occurs in a declaration position 108ef8225444452a1486bd721f3285301fe84643b00Stephen Hines // (e.g. function body). 109ef8225444452a1486bd721f3285301fe84643b00Stephen Hines R_Ctx declCtx(R_Ctx Ctx) { return TRV_Decl; } 110ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 111ef8225444452a1486bd721f3285301fe84643b00Stephen Hines // Create context for a subexpression that occurs in a position that 112ef8225444452a1486bd721f3285301fe84643b00Stephen Hines // should be reduced lazily. (e.g. code body). 113ef8225444452a1486bd721f3285301fe84643b00Stephen Hines R_Ctx lazyCtx(R_Ctx Ctx) { return TRV_Lazy; } 114ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 115ef8225444452a1486bd721f3285301fe84643b00Stephen Hines // Create context for a subexpression that occurs in a type position. 116ef8225444452a1486bd721f3285301fe84643b00Stephen Hines R_Ctx typeCtx(R_Ctx Ctx) { return TRV_Type; } 117ef8225444452a1486bd721f3285301fe84643b00Stephen Hines}; 1186bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 1196bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 120ef8225444452a1486bd721f3285301fe84643b00Stephen Hines// Base class for traversals that rewrite an SExpr to another SExpr. 121ef8225444452a1486bd721f3285301fe84643b00Stephen Hinesclass CopyReducerBase : public SimpleReducerBase { 122ef8225444452a1486bd721f3285301fe84643b00Stephen Hinespublic: 1236bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // R_SExpr is the result type for a traversal. 1246bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // A copy or non-destructive rewrite returns a newly allocated term. 1256bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines typedef SExpr *R_SExpr; 126ef8225444452a1486bd721f3285301fe84643b00Stephen Hines typedef BasicBlock *R_BasicBlock; 1276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 1286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Container is a minimal interface used to store results when traversing 1296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // SExprs of variable arity, such as Phi, Goto, and SCFG. 1306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines template <class T> class Container { 1316bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines public: 1326bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Allocate a new container with a capacity for n elements. 133ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Container(CopyReducerBase &S, unsigned N) : Elems(S.Arena, N) {} 1346bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 1356bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Push a new element onto the container. 1366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines void push_back(T E) { Elems.push_back(E); } 1376bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 1386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SimpleArray<T> Elems; 1396bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines }; 1406bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 141ef8225444452a1486bd721f3285301fe84643b00Stephen Hines CopyReducerBase(MemRegionRef A) : Arena(A) {} 142ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 143ef8225444452a1486bd721f3285301fe84643b00Stephen Hinesprotected: 144ef8225444452a1486bd721f3285301fe84643b00Stephen Hines MemRegionRef Arena; 145ef8225444452a1486bd721f3285301fe84643b00Stephen Hines}; 146ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 147ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 148ef8225444452a1486bd721f3285301fe84643b00Stephen Hines// Implements a traversal that makes a deep copy of an SExpr. 149ef8225444452a1486bd721f3285301fe84643b00Stephen Hines// The default behavior of reduce##X(...) is to create a copy of the original. 150ef8225444452a1486bd721f3285301fe84643b00Stephen Hines// Subclasses can override reduce##X to implement non-destructive rewriting 151ef8225444452a1486bd721f3285301fe84643b00Stephen Hines// passes. 152ef8225444452a1486bd721f3285301fe84643b00Stephen Hinestemplate<class Self> 153ef8225444452a1486bd721f3285301fe84643b00Stephen Hinesclass CopyReducer : public Traversal<Self, CopyReducerBase>, 154ef8225444452a1486bd721f3285301fe84643b00Stephen Hines public CopyReducerBase { 155ef8225444452a1486bd721f3285301fe84643b00Stephen Hinespublic: 156ef8225444452a1486bd721f3285301fe84643b00Stephen Hines CopyReducer(MemRegionRef A) : CopyReducerBase(A) {} 157ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 1586bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinespublic: 1596bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines R_SExpr reduceNull() { 1606bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 1616bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 1626bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // R_SExpr reduceFuture(...) is never used. 1636bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 1646bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines R_SExpr reduceUndefined(Undefined &Orig) { 1656bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return new (Arena) Undefined(Orig); 1666bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 1676bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines R_SExpr reduceWildcard(Wildcard &Orig) { 1686bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return new (Arena) Wildcard(Orig); 1696bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 1706bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 1716bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines R_SExpr reduceLiteral(Literal &Orig) { 1726bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return new (Arena) Literal(Orig); 1736bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 174ef8225444452a1486bd721f3285301fe84643b00Stephen Hines template<class T> 175ef8225444452a1486bd721f3285301fe84643b00Stephen Hines R_SExpr reduceLiteralT(LiteralT<T> &Orig) { 176ef8225444452a1486bd721f3285301fe84643b00Stephen Hines return new (Arena) LiteralT<T>(Orig); 177ef8225444452a1486bd721f3285301fe84643b00Stephen Hines } 1786bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines R_SExpr reduceLiteralPtr(LiteralPtr &Orig) { 1796bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return new (Arena) LiteralPtr(Orig); 1806bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 1816bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 1826bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines R_SExpr reduceFunction(Function &Orig, Variable *Nvd, R_SExpr E0) { 1836bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return new (Arena) Function(Orig, Nvd, E0); 1846bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 1856bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines R_SExpr reduceSFunction(SFunction &Orig, Variable *Nvd, R_SExpr E0) { 1866bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return new (Arena) SFunction(Orig, Nvd, E0); 1876bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 1886bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines R_SExpr reduceCode(Code &Orig, R_SExpr E0, R_SExpr E1) { 1896bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return new (Arena) Code(Orig, E0, E1); 1906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 1916bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines R_SExpr reduceField(Field &Orig, R_SExpr E0, R_SExpr E1) { 1926bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return new (Arena) Field(Orig, E0, E1); 1936bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 1946bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 1956bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines R_SExpr reduceApply(Apply &Orig, R_SExpr E0, R_SExpr E1) { 1966bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return new (Arena) Apply(Orig, E0, E1); 1976bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 1986bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines R_SExpr reduceSApply(SApply &Orig, R_SExpr E0, R_SExpr E1) { 1996bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return new (Arena) SApply(Orig, E0, E1); 2006bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 2016bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines R_SExpr reduceProject(Project &Orig, R_SExpr E0) { 2026bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return new (Arena) Project(Orig, E0); 2036bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 2046bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines R_SExpr reduceCall(Call &Orig, R_SExpr E0) { 2056bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return new (Arena) Call(Orig, E0); 2066bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 2076bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 2086bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines R_SExpr reduceAlloc(Alloc &Orig, R_SExpr E0) { 2096bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return new (Arena) Alloc(Orig, E0); 2106bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 2116bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines R_SExpr reduceLoad(Load &Orig, R_SExpr E0) { 2126bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return new (Arena) Load(Orig, E0); 2136bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 2146bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines R_SExpr reduceStore(Store &Orig, R_SExpr E0, R_SExpr E1) { 2156bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return new (Arena) Store(Orig, E0, E1); 2166bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 217ef8225444452a1486bd721f3285301fe84643b00Stephen Hines R_SExpr reduceArrayIndex(ArrayIndex &Orig, R_SExpr E0, R_SExpr E1) { 218ef8225444452a1486bd721f3285301fe84643b00Stephen Hines return new (Arena) ArrayIndex(Orig, E0, E1); 2196bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 2206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines R_SExpr reduceArrayAdd(ArrayAdd &Orig, R_SExpr E0, R_SExpr E1) { 2216bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return new (Arena) ArrayAdd(Orig, E0, E1); 2226bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 2236bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines R_SExpr reduceUnaryOp(UnaryOp &Orig, R_SExpr E0) { 2246bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return new (Arena) UnaryOp(Orig, E0); 2256bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 2266bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines R_SExpr reduceBinaryOp(BinaryOp &Orig, R_SExpr E0, R_SExpr E1) { 2276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return new (Arena) BinaryOp(Orig, E0, E1); 2286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 2296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines R_SExpr reduceCast(Cast &Orig, R_SExpr E0) { 2306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return new (Arena) Cast(Orig, E0); 2316bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 2326bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 2336bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines R_SExpr reduceSCFG(SCFG &Orig, Container<BasicBlock *> &Bbs) { 234ef8225444452a1486bd721f3285301fe84643b00Stephen Hines return nullptr; // FIXME: implement CFG rewriting 235ef8225444452a1486bd721f3285301fe84643b00Stephen Hines } 236ef8225444452a1486bd721f3285301fe84643b00Stephen Hines R_BasicBlock reduceBasicBlock(BasicBlock &Orig, Container<Variable *> &As, 237ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Container<Variable *> &Is, R_SExpr T) { 238ef8225444452a1486bd721f3285301fe84643b00Stephen Hines return nullptr; // FIXME: implement CFG rewriting 2396bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 2406bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines R_SExpr reducePhi(Phi &Orig, Container<R_SExpr> &As) { 2416bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return new (Arena) Phi(Orig, std::move(As.Elems)); 2426bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 243ef8225444452a1486bd721f3285301fe84643b00Stephen Hines R_SExpr reduceGoto(Goto &Orig, BasicBlock *B) { 244ef8225444452a1486bd721f3285301fe84643b00Stephen Hines return new (Arena) Goto(Orig, B, 0); // FIXME: set index 2456bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 2466bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines R_SExpr reduceBranch(Branch &O, R_SExpr C, BasicBlock *B0, BasicBlock *B1) { 247ef8225444452a1486bd721f3285301fe84643b00Stephen Hines return new (Arena) Branch(O, C, B0, B1, 0, 0); // FIXME: set indices 2486bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 2496bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 2506bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines R_SExpr reduceIdentifier(Identifier &Orig) { 2516bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return new (Arena) Identifier(Orig); 2526bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 2536bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines R_SExpr reduceIfThenElse(IfThenElse &Orig, R_SExpr C, R_SExpr T, R_SExpr E) { 2546bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return new (Arena) IfThenElse(Orig, C, T, E); 2556bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 2566bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines R_SExpr reduceLet(Let &Orig, Variable *Nvd, R_SExpr B) { 2576bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return new (Arena) Let(Orig, Nvd, B); 2586bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 2596bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 2606bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Create a new variable from orig, and push it onto the lexical scope. 2616bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Variable *enterScope(Variable &Orig, R_SExpr E0) { 2626bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return new (Arena) Variable(Orig, E0); 2636bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 2646bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Exit the lexical scope of orig. 2656bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines void exitScope(const Variable &Orig) {} 2666bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 2676bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines void enterCFG(SCFG &Cfg) {} 2686bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines void exitCFG(SCFG &Cfg) {} 269ef8225444452a1486bd721f3285301fe84643b00Stephen Hines void enterBasicBlock(BasicBlock &BB) {} 270ef8225444452a1486bd721f3285301fe84643b00Stephen Hines void exitBasicBlock(BasicBlock &BB) {} 2716bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 2726bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Map Variable references to their rewritten definitions. 2736bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Variable *reduceVariableRef(Variable *Ovd) { return Ovd; } 2746bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 275ef8225444452a1486bd721f3285301fe84643b00Stephen Hines // Map BasicBlock references to their rewritten definitions. 2766bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines BasicBlock *reduceBasicBlockRef(BasicBlock *Obb) { return Obb; } 2776bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines}; 2786bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 2796bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 280ef8225444452a1486bd721f3285301fe84643b00Stephen Hinesclass SExprCopier : public CopyReducer<SExprCopier> { 2816bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinespublic: 282ef8225444452a1486bd721f3285301fe84643b00Stephen Hines typedef SExpr *R_SExpr; 283ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 284ef8225444452a1486bd721f3285301fe84643b00Stephen Hines SExprCopier(MemRegionRef A) : CopyReducer(A) { } 2856bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 2866bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Create a copy of e in region a. 2876bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines static SExpr *copy(SExpr *E, MemRegionRef A) { 2886bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SExprCopier Copier(A); 289ef8225444452a1486bd721f3285301fe84643b00Stephen Hines return Copier.traverse(E, TRV_Normal); 2906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 2916bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines}; 2926bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 2936bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 2946bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 295ef8225444452a1486bd721f3285301fe84643b00Stephen Hines// Base class for visit traversals. 296ef8225444452a1486bd721f3285301fe84643b00Stephen Hinesclass VisitReducerBase : public SimpleReducerBase { 297ef8225444452a1486bd721f3285301fe84643b00Stephen Hinespublic: 2986bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // A visitor returns a bool, representing success or failure. 2996bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines typedef bool R_SExpr; 300ef8225444452a1486bd721f3285301fe84643b00Stephen Hines typedef bool R_BasicBlock; 3016bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 3026bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // A visitor "container" is a single bool, which accumulates success. 3036bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines template <class T> class Container { 3046bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines public: 305ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Container(VisitReducerBase &S, unsigned N) : Success(true) {} 3066bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines void push_back(bool E) { Success = Success && E; } 3076bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 3086bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines bool Success; 3096bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines }; 310ef8225444452a1486bd721f3285301fe84643b00Stephen Hines}; 311ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 312ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 313ef8225444452a1486bd721f3285301fe84643b00Stephen Hines// Implements a traversal that visits each subexpression, and returns either 314ef8225444452a1486bd721f3285301fe84643b00Stephen Hines// true or false. 315ef8225444452a1486bd721f3285301fe84643b00Stephen Hinestemplate <class Self> 316ef8225444452a1486bd721f3285301fe84643b00Stephen Hinesclass VisitReducer : public Traversal<Self, VisitReducerBase>, 317ef8225444452a1486bd721f3285301fe84643b00Stephen Hines public VisitReducerBase { 318ef8225444452a1486bd721f3285301fe84643b00Stephen Hinespublic: 319ef8225444452a1486bd721f3285301fe84643b00Stephen Hines VisitReducer() {} 3206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 3216bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinespublic: 3226bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines R_SExpr reduceNull() { return true; } 3236bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines R_SExpr reduceUndefined(Undefined &Orig) { return true; } 3246bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines R_SExpr reduceWildcard(Wildcard &Orig) { return true; } 3256bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 3266bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines R_SExpr reduceLiteral(Literal &Orig) { return true; } 327ef8225444452a1486bd721f3285301fe84643b00Stephen Hines template<class T> 328ef8225444452a1486bd721f3285301fe84643b00Stephen Hines R_SExpr reduceLiteralT(LiteralT<T> &Orig) { return true; } 3296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines R_SExpr reduceLiteralPtr(Literal &Orig) { return true; } 3306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 3316bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines R_SExpr reduceFunction(Function &Orig, Variable *Nvd, R_SExpr E0) { 3326bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return Nvd && E0; 3336bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 3346bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines R_SExpr reduceSFunction(SFunction &Orig, Variable *Nvd, R_SExpr E0) { 3356bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return Nvd && E0; 3366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 3376bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines R_SExpr reduceCode(Code &Orig, R_SExpr E0, R_SExpr E1) { 3386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return E0 && E1; 3396bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 3406bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines R_SExpr reduceField(Field &Orig, R_SExpr E0, R_SExpr E1) { 3416bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return E0 && E1; 3426bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 3436bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines R_SExpr reduceApply(Apply &Orig, R_SExpr E0, R_SExpr E1) { 3446bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return E0 && E1; 3456bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 3466bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines R_SExpr reduceSApply(SApply &Orig, R_SExpr E0, R_SExpr E1) { 3476bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return E0 && E1; 3486bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 3496bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines R_SExpr reduceProject(Project &Orig, R_SExpr E0) { return E0; } 3506bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines R_SExpr reduceCall(Call &Orig, R_SExpr E0) { return E0; } 3516bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines R_SExpr reduceAlloc(Alloc &Orig, R_SExpr E0) { return E0; } 3526bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines R_SExpr reduceLoad(Load &Orig, R_SExpr E0) { return E0; } 3536bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines R_SExpr reduceStore(Store &Orig, R_SExpr E0, R_SExpr E1) { return E0 && E1; } 354ef8225444452a1486bd721f3285301fe84643b00Stephen Hines R_SExpr reduceArrayIndex(Store &Orig, R_SExpr E0, R_SExpr E1) { 355ef8225444452a1486bd721f3285301fe84643b00Stephen Hines return E0 && E1; 356ef8225444452a1486bd721f3285301fe84643b00Stephen Hines } 3576bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines R_SExpr reduceArrayAdd(Store &Orig, R_SExpr E0, R_SExpr E1) { 3586bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return E0 && E1; 3596bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 3606bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines R_SExpr reduceUnaryOp(UnaryOp &Orig, R_SExpr E0) { return E0; } 3616bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines R_SExpr reduceBinaryOp(BinaryOp &Orig, R_SExpr E0, R_SExpr E1) { 3626bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return E0 && E1; 3636bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 3646bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines R_SExpr reduceCast(Cast &Orig, R_SExpr E0) { return E0; } 3656bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 3666bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines R_SExpr reduceSCFG(SCFG &Orig, Container<BasicBlock *> Bbs) { 3676bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return Bbs.Success; 3686bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 369ef8225444452a1486bd721f3285301fe84643b00Stephen Hines R_BasicBlock reduceBasicBlock(BasicBlock &Orig, Container<Variable *> &As, 370ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Container<Variable *> &Is, R_SExpr T) { 371ef8225444452a1486bd721f3285301fe84643b00Stephen Hines return (As.Success && Is.Success && T); 372ef8225444452a1486bd721f3285301fe84643b00Stephen Hines } 373ef8225444452a1486bd721f3285301fe84643b00Stephen Hines R_SExpr reducePhi(Phi &Orig, Container<R_SExpr> &As) { 3746bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return As.Success; 3756bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 376ef8225444452a1486bd721f3285301fe84643b00Stephen Hines R_SExpr reduceGoto(Goto &Orig, BasicBlock *B) { 3776bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return true; 3786bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 3796bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines R_SExpr reduceBranch(Branch &O, R_SExpr C, BasicBlock *B0, BasicBlock *B1) { 3806bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return C; 3816bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 3826bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 3836bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines R_SExpr reduceIdentifier(Identifier &Orig) { 3846bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return true; 3856bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 3866bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines R_SExpr reduceIfThenElse(IfThenElse &Orig, R_SExpr C, R_SExpr T, R_SExpr E) { 3876bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return C && T && E; 3886bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 3896bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines R_SExpr reduceLet(Let &Orig, Variable *Nvd, R_SExpr B) { 3906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return Nvd && B; 3916bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 3926bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 393ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Variable *enterScope(Variable &Orig, R_SExpr E0) { return &Orig; } 3946bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines void exitScope(const Variable &Orig) {} 3956bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines void enterCFG(SCFG &Cfg) {} 3966bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines void exitCFG(SCFG &Cfg) {} 397ef8225444452a1486bd721f3285301fe84643b00Stephen Hines void enterBasicBlock(BasicBlock &BB) {} 398ef8225444452a1486bd721f3285301fe84643b00Stephen Hines void exitBasicBlock(BasicBlock &BB) {} 3996bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 400ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Variable *reduceVariableRef (Variable *Ovd) { return Ovd; } 4016bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines BasicBlock *reduceBasicBlockRef(BasicBlock *Obb) { return Obb; } 4026bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 4036bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinespublic: 4046bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines bool traverse(SExpr *E, TraversalKind K = TRV_Normal) { 4056bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Success = Success && this->traverseByCase(E); 4066bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return Success; 4076bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 4086bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 4096bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines static bool visit(SExpr *E) { 410ef8225444452a1486bd721f3285301fe84643b00Stephen Hines Self Visitor; 411ef8225444452a1486bd721f3285301fe84643b00Stephen Hines return Visitor.traverse(E, TRV_Normal); 4126bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 4136bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 4146bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesprivate: 4156bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines bool Success; 4166bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines}; 4176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 4186bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 4196bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// Basic class for comparison operations over expressions. 4206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinestemplate <typename Self> 4216bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesclass Comparator { 4226bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesprotected: 4236bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Self *self() { return reinterpret_cast<Self *>(this); } 4246bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 4256bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinespublic: 4266bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines bool compareByCase(SExpr *E1, SExpr* E2) { 4276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines switch (E1->opcode()) { 4286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#define TIL_OPCODE_DEF(X) \ 4296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines case COP_##X: \ 4306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return cast<X>(E1)->compare(cast<X>(E2), *self()); 4316bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "ThreadSafetyOps.def" 4326bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#undef TIL_OPCODE_DEF 4336bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 4346bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 4356bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines}; 4366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 4376bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 4386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesclass EqualsComparator : public Comparator<EqualsComparator> { 4396bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinespublic: 4406bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Result type for the comparison, e.g. bool for simple equality, 4416bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // or int for lexigraphic comparison (-1, 0, 1). Must have one value which 4426bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // denotes "true". 4436bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines typedef bool CType; 4446bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 4456bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CType trueResult() { return true; } 4466bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines bool notTrue(CType ct) { return !ct; } 4476bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 4486bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines bool compareIntegers(unsigned i, unsigned j) { return i == j; } 4496bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines bool compareStrings (StringRef s, StringRef r) { return s == r; } 4506bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines bool comparePointers(const void* P, const void* Q) { return P == Q; } 4516bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 4526bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines bool compare(SExpr *E1, SExpr* E2) { 4536bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (E1->opcode() != E2->opcode()) 4546bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return false; 4556bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return compareByCase(E1, E2); 4566bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 4576bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 4586bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // TODO -- handle alpha-renaming of variables 4596bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines void enterScope(Variable* V1, Variable* V2) { } 4606bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines void leaveScope() { } 4616bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 4626bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines bool compareVariableRefs(Variable* V1, Variable* V2) { 4636bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return V1 == V2; 4646bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 4656bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 4666bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines static bool compareExprs(SExpr *E1, SExpr* E2) { 4676bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines EqualsComparator Eq; 4686bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return Eq.compare(E1, E2); 4696bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 4706bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines}; 4716bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 4726bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 4736bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// Pretty printer for TIL expressions 4746bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinestemplate <typename Self, typename StreamType> 4756bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesclass PrettyPrinter { 4766bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesprivate: 4776bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines bool Verbose; // Print out additional information 478ef8225444452a1486bd721f3285301fe84643b00Stephen Hines bool Cleanup; // Omit redundant decls. 4796bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 4806bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinespublic: 481ef8225444452a1486bd721f3285301fe84643b00Stephen Hines PrettyPrinter(bool V = false, bool C = true) : Verbose(V), Cleanup(C) { } 4826bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 4836bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines static void print(SExpr *E, StreamType &SS) { 4846bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Self printer; 4856bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines printer.printSExpr(E, SS, Prec_MAX); 4866bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 4876bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 4886bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesprotected: 4896bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Self *self() { return reinterpret_cast<Self *>(this); } 4906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 4916bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines void newline(StreamType &SS) { 4926bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SS << "\n"; 4936bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 4946bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 4956bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // TODO: further distinguish between binary operations. 4966bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines static const unsigned Prec_Atom = 0; 4976bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines static const unsigned Prec_Postfix = 1; 4986bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines static const unsigned Prec_Unary = 2; 4996bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines static const unsigned Prec_Binary = 3; 5006bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines static const unsigned Prec_Other = 4; 5016bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines static const unsigned Prec_Decl = 5; 5026bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines static const unsigned Prec_MAX = 6; 5036bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 5046bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Return the precedence of a given node, for use in pretty printing. 5056bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines unsigned precedence(SExpr *E) { 5066bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines switch (E->opcode()) { 5076bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines case COP_Future: return Prec_Atom; 5086bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines case COP_Undefined: return Prec_Atom; 5096bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines case COP_Wildcard: return Prec_Atom; 5106bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 5116bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines case COP_Literal: return Prec_Atom; 5126bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines case COP_LiteralPtr: return Prec_Atom; 5136bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines case COP_Variable: return Prec_Atom; 5146bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines case COP_Function: return Prec_Decl; 5156bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines case COP_SFunction: return Prec_Decl; 5166bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines case COP_Code: return Prec_Decl; 5176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines case COP_Field: return Prec_Decl; 5186bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 5196bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines case COP_Apply: return Prec_Postfix; 5206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines case COP_SApply: return Prec_Postfix; 5216bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines case COP_Project: return Prec_Postfix; 5226bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 5236bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines case COP_Call: return Prec_Postfix; 5246bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines case COP_Alloc: return Prec_Other; 5256bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines case COP_Load: return Prec_Postfix; 5266bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines case COP_Store: return Prec_Other; 527ef8225444452a1486bd721f3285301fe84643b00Stephen Hines case COP_ArrayIndex: return Prec_Postfix; 5286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines case COP_ArrayAdd: return Prec_Postfix; 5296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 5306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines case COP_UnaryOp: return Prec_Unary; 5316bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines case COP_BinaryOp: return Prec_Binary; 5326bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines case COP_Cast: return Prec_Unary; 5336bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 5346bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines case COP_SCFG: return Prec_Decl; 535ef8225444452a1486bd721f3285301fe84643b00Stephen Hines case COP_BasicBlock: return Prec_MAX; 5366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines case COP_Phi: return Prec_Atom; 5376bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines case COP_Goto: return Prec_Atom; 5386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines case COP_Branch: return Prec_Atom; 5396bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 5406bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines case COP_Identifier: return Prec_Atom; 5416bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines case COP_IfThenElse: return Prec_Other; 5426bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines case COP_Let: return Prec_Decl; 5436bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 5446bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return Prec_MAX; 5456bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 5466bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 547ef8225444452a1486bd721f3285301fe84643b00Stephen Hines void printBlockLabel(StreamType & SS, BasicBlock *BB, unsigned index) { 548ef8225444452a1486bd721f3285301fe84643b00Stephen Hines if (!BB) { 549ef8225444452a1486bd721f3285301fe84643b00Stephen Hines SS << "BB_null"; 550ef8225444452a1486bd721f3285301fe84643b00Stephen Hines return; 551ef8225444452a1486bd721f3285301fe84643b00Stephen Hines } 552ef8225444452a1486bd721f3285301fe84643b00Stephen Hines SS << "BB_"; 553ef8225444452a1486bd721f3285301fe84643b00Stephen Hines SS << BB->blockID(); 554ef8225444452a1486bd721f3285301fe84643b00Stephen Hines SS << ":"; 555ef8225444452a1486bd721f3285301fe84643b00Stephen Hines SS << index; 556ef8225444452a1486bd721f3285301fe84643b00Stephen Hines } 557ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 5586bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines void printSExpr(SExpr *E, StreamType &SS, unsigned P) { 5596bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!E) { 5606bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines self()->printNull(SS); 5616bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return; 5626bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 5636bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (self()->precedence(E) > P) { 5646bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Wrap expr in () if necessary. 5656bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SS << "("; 5666bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines self()->printSExpr(E, SS, Prec_MAX); 5676bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SS << ")"; 5686bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return; 5696bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 5706bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 5716bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines switch (E->opcode()) { 5726bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#define TIL_OPCODE_DEF(X) \ 5736bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines case COP_##X: \ 5746bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines self()->print##X(cast<X>(E), SS); \ 5756bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return; 5766bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "ThreadSafetyOps.def" 5776bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#undef TIL_OPCODE_DEF 5786bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 5796bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 5806bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 5816bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines void printNull(StreamType &SS) { 5826bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SS << "#null"; 5836bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 5846bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 5856bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines void printFuture(Future *E, StreamType &SS) { 5866bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines self()->printSExpr(E->maybeGetResult(), SS, Prec_Atom); 5876bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 5886bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 5896bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines void printUndefined(Undefined *E, StreamType &SS) { 5906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SS << "#undefined"; 5916bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 5926bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 5936bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines void printWildcard(Wildcard *E, StreamType &SS) { 5946bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SS << "_"; 5956bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 5966bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 5976bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines template<class T> 5986bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines void printLiteralT(LiteralT<T> *E, StreamType &SS) { 5996bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SS << E->value(); 6006bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 6016bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 602ef8225444452a1486bd721f3285301fe84643b00Stephen Hines void printLiteralT(LiteralT<uint8_t> *E, StreamType &SS) { 603ef8225444452a1486bd721f3285301fe84643b00Stephen Hines SS << "'" << E->value() << "'"; 604ef8225444452a1486bd721f3285301fe84643b00Stephen Hines } 605ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 6066bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines void printLiteral(Literal *E, StreamType &SS) { 607ef8225444452a1486bd721f3285301fe84643b00Stephen Hines if (E->clangExpr()) { 6086bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SS << getSourceLiteralString(E->clangExpr()); 609ef8225444452a1486bd721f3285301fe84643b00Stephen Hines return; 610ef8225444452a1486bd721f3285301fe84643b00Stephen Hines } 6116bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines else { 6126bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines ValueType VT = E->valueType(); 6136bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines switch (VT.Base) { 6146bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines case ValueType::BT_Void: { 6156bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SS << "void"; 6166bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return; 6176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 6186bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines case ValueType::BT_Bool: { 619ef8225444452a1486bd721f3285301fe84643b00Stephen Hines if (E->as<bool>().value()) 6206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SS << "true"; 6216bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines else 6226bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SS << "false"; 6236bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return; 6246bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 6256bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines case ValueType::BT_Int: { 6266bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines switch (VT.Size) { 6276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines case ValueType::ST_8: 6286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (VT.Signed) 629ef8225444452a1486bd721f3285301fe84643b00Stephen Hines printLiteralT(&E->as<int8_t>(), SS); 6306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines else 631ef8225444452a1486bd721f3285301fe84643b00Stephen Hines printLiteralT(&E->as<uint8_t>(), SS); 6326bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return; 6336bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines case ValueType::ST_16: 6346bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (VT.Signed) 635ef8225444452a1486bd721f3285301fe84643b00Stephen Hines printLiteralT(&E->as<int16_t>(), SS); 6366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines else 637ef8225444452a1486bd721f3285301fe84643b00Stephen Hines printLiteralT(&E->as<uint16_t>(), SS); 6386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return; 6396bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines case ValueType::ST_32: 6406bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (VT.Signed) 641ef8225444452a1486bd721f3285301fe84643b00Stephen Hines printLiteralT(&E->as<int32_t>(), SS); 6426bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines else 643ef8225444452a1486bd721f3285301fe84643b00Stephen Hines printLiteralT(&E->as<uint32_t>(), SS); 6446bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return; 6456bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines case ValueType::ST_64: 6466bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (VT.Signed) 647ef8225444452a1486bd721f3285301fe84643b00Stephen Hines printLiteralT(&E->as<int64_t>(), SS); 6486bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines else 649ef8225444452a1486bd721f3285301fe84643b00Stephen Hines printLiteralT(&E->as<uint64_t>(), SS); 6506bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return; 6516bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines default: 6526bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines break; 6536bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 6546bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines break; 6556bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 6566bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines case ValueType::BT_Float: { 6576bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines switch (VT.Size) { 6586bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines case ValueType::ST_32: 659ef8225444452a1486bd721f3285301fe84643b00Stephen Hines printLiteralT(&E->as<float>(), SS); 6606bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return; 6616bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines case ValueType::ST_64: 662ef8225444452a1486bd721f3285301fe84643b00Stephen Hines printLiteralT(&E->as<double>(), SS); 6636bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return; 6646bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines default: 6656bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines break; 6666bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 6676bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines break; 6686bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 6696bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines case ValueType::BT_String: { 6706bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SS << "\""; 671ef8225444452a1486bd721f3285301fe84643b00Stephen Hines printLiteralT(&E->as<StringRef>(), SS); 6726bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SS << "\""; 6736bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return; 6746bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 6756bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines case ValueType::BT_Pointer: { 6766bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SS << "#ptr"; 6776bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return; 6786bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 6796bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines case ValueType::BT_ValueRef: { 6806bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SS << "#vref"; 6816bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return; 6826bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 6836bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 6846bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 6856bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SS << "#lit"; 6866bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 6876bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 6886bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines void printLiteralPtr(LiteralPtr *E, StreamType &SS) { 6896bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SS << E->clangDecl()->getNameAsString(); 6906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 6916bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 6926bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines void printVariable(Variable *V, StreamType &SS, bool IsVarDecl = false) { 693ef8225444452a1486bd721f3285301fe84643b00Stephen Hines if (!IsVarDecl && Cleanup) { 694ef8225444452a1486bd721f3285301fe84643b00Stephen Hines SExpr* E = getCanonicalVal(V); 6956bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (E != V) { 6966bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines printSExpr(E, SS, Prec_Atom); 6976bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return; 6986bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 6996bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 700ef8225444452a1486bd721f3285301fe84643b00Stephen Hines if (V->kind() == Variable::VK_LetBB) 701ef8225444452a1486bd721f3285301fe84643b00Stephen Hines SS << V->name() << V->getBlockID() << "_" << V->getID(); 702ef8225444452a1486bd721f3285301fe84643b00Stephen Hines else 703ef8225444452a1486bd721f3285301fe84643b00Stephen Hines SS << V->name() << V->getID(); 7046bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 7056bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 7066bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines void printFunction(Function *E, StreamType &SS, unsigned sugared = 0) { 7076bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines switch (sugared) { 7086bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines default: 7096bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SS << "\\("; // Lambda 7106bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines break; 7116bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines case 1: 7126bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SS << "("; // Slot declarations 7136bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines break; 7146bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines case 2: 7156bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SS << ", "; // Curried functions 7166bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines break; 7176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 7186bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines self()->printVariable(E->variableDecl(), SS, true); 7196bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SS << ": "; 7206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines self()->printSExpr(E->variableDecl()->definition(), SS, Prec_MAX); 7216bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 7226bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SExpr *B = E->body(); 7236bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (B && B->opcode() == COP_Function) 7246bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines self()->printFunction(cast<Function>(B), SS, 2); 7256bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines else { 7266bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SS << ")"; 7276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines self()->printSExpr(B, SS, Prec_Decl); 7286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 7296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 7306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 7316bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines void printSFunction(SFunction *E, StreamType &SS) { 7326bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SS << "@"; 7336bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines self()->printVariable(E->variableDecl(), SS, true); 7346bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SS << " "; 7356bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines self()->printSExpr(E->body(), SS, Prec_Decl); 7366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 7376bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 7386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines void printCode(Code *E, StreamType &SS) { 7396bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SS << ": "; 7406bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines self()->printSExpr(E->returnType(), SS, Prec_Decl-1); 7416bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SS << " -> "; 7426bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines self()->printSExpr(E->body(), SS, Prec_Decl); 7436bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 7446bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 7456bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines void printField(Field *E, StreamType &SS) { 7466bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SS << ": "; 7476bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines self()->printSExpr(E->range(), SS, Prec_Decl-1); 7486bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SS << " = "; 7496bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines self()->printSExpr(E->body(), SS, Prec_Decl); 7506bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 7516bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 7526bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines void printApply(Apply *E, StreamType &SS, bool sugared = false) { 7536bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SExpr *F = E->fun(); 7546bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (F->opcode() == COP_Apply) { 7556bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines printApply(cast<Apply>(F), SS, true); 7566bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SS << ", "; 7576bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } else { 7586bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines self()->printSExpr(F, SS, Prec_Postfix); 7596bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SS << "("; 7606bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 7616bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines self()->printSExpr(E->arg(), SS, Prec_MAX); 7626bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (!sugared) 7636bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SS << ")$"; 7646bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 7656bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 7666bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines void printSApply(SApply *E, StreamType &SS) { 7676bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines self()->printSExpr(E->sfun(), SS, Prec_Postfix); 7686bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (E->isDelegation()) { 7696bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SS << "@("; 7706bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines self()->printSExpr(E->arg(), SS, Prec_MAX); 7716bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SS << ")"; 7726bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 7736bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 7746bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 7756bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines void printProject(Project *E, StreamType &SS) { 7766bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines self()->printSExpr(E->record(), SS, Prec_Postfix); 7776bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SS << "."; 7786bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SS << E->slotName(); 7796bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 7806bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 7816bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines void printCall(Call *E, StreamType &SS) { 7826bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SExpr *T = E->target(); 7836bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (T->opcode() == COP_Apply) { 7846bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines self()->printApply(cast<Apply>(T), SS, true); 7856bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SS << ")"; 7866bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 7876bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines else { 7886bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines self()->printSExpr(T, SS, Prec_Postfix); 7896bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SS << "()"; 7906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 7916bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 7926bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 7936bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines void printAlloc(Alloc *E, StreamType &SS) { 7946bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SS << "new "; 7956bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines self()->printSExpr(E->dataType(), SS, Prec_Other-1); 7966bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 7976bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 7986bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines void printLoad(Load *E, StreamType &SS) { 7996bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines self()->printSExpr(E->pointer(), SS, Prec_Postfix); 8006bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SS << "^"; 8016bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 8026bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 8036bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines void printStore(Store *E, StreamType &SS) { 8046bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines self()->printSExpr(E->destination(), SS, Prec_Other-1); 8056bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SS << " := "; 8066bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines self()->printSExpr(E->source(), SS, Prec_Other-1); 8076bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 8086bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 809ef8225444452a1486bd721f3285301fe84643b00Stephen Hines void printArrayIndex(ArrayIndex *E, StreamType &SS) { 8106bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines self()->printSExpr(E->array(), SS, Prec_Postfix); 811ef8225444452a1486bd721f3285301fe84643b00Stephen Hines SS << "["; 812ef8225444452a1486bd721f3285301fe84643b00Stephen Hines self()->printSExpr(E->index(), SS, Prec_MAX); 813ef8225444452a1486bd721f3285301fe84643b00Stephen Hines SS << "]"; 8146bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 8156bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 8166bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines void printArrayAdd(ArrayAdd *E, StreamType &SS) { 8176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines self()->printSExpr(E->array(), SS, Prec_Postfix); 8186bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SS << " + "; 8196bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines self()->printSExpr(E->index(), SS, Prec_Atom); 8206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 8216bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 8226bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines void printUnaryOp(UnaryOp *E, StreamType &SS) { 8236bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SS << getUnaryOpcodeString(E->unaryOpcode()); 8246bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines self()->printSExpr(E->expr(), SS, Prec_Unary); 8256bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 8266bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 8276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines void printBinaryOp(BinaryOp *E, StreamType &SS) { 8286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines self()->printSExpr(E->expr0(), SS, Prec_Binary-1); 8296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SS << " " << getBinaryOpcodeString(E->binaryOpcode()) << " "; 8306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines self()->printSExpr(E->expr1(), SS, Prec_Binary-1); 8316bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 8326bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 8336bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines void printCast(Cast *E, StreamType &SS) { 8346bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SS << "%"; 8356bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines self()->printSExpr(E->expr(), SS, Prec_Unary); 8366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 8376bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 8386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines void printSCFG(SCFG *E, StreamType &SS) { 839ef8225444452a1486bd721f3285301fe84643b00Stephen Hines SS << "CFG {\n"; 8406bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines for (auto BBI : *E) { 841ef8225444452a1486bd721f3285301fe84643b00Stephen Hines printBasicBlock(BBI, SS); 842ef8225444452a1486bd721f3285301fe84643b00Stephen Hines } 843ef8225444452a1486bd721f3285301fe84643b00Stephen Hines SS << "}"; 844ef8225444452a1486bd721f3285301fe84643b00Stephen Hines newline(SS); 845ef8225444452a1486bd721f3285301fe84643b00Stephen Hines } 846ef8225444452a1486bd721f3285301fe84643b00Stephen Hines 847ef8225444452a1486bd721f3285301fe84643b00Stephen Hines void printBasicBlock(BasicBlock *E, StreamType &SS) { 848ef8225444452a1486bd721f3285301fe84643b00Stephen Hines SS << "BB_" << E->blockID() << ":"; 849ef8225444452a1486bd721f3285301fe84643b00Stephen Hines if (E->parent()) 850ef8225444452a1486bd721f3285301fe84643b00Stephen Hines SS << " BB_" << E->parent()->blockID(); 851ef8225444452a1486bd721f3285301fe84643b00Stephen Hines newline(SS); 852ef8225444452a1486bd721f3285301fe84643b00Stephen Hines for (auto *A : E->arguments()) { 853ef8225444452a1486bd721f3285301fe84643b00Stephen Hines SS << "let "; 854ef8225444452a1486bd721f3285301fe84643b00Stephen Hines self()->printVariable(A, SS, true); 855ef8225444452a1486bd721f3285301fe84643b00Stephen Hines SS << " = "; 856ef8225444452a1486bd721f3285301fe84643b00Stephen Hines self()->printSExpr(A->definition(), SS, Prec_MAX); 857ef8225444452a1486bd721f3285301fe84643b00Stephen Hines SS << ";"; 8586bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines newline(SS); 859ef8225444452a1486bd721f3285301fe84643b00Stephen Hines } 860ef8225444452a1486bd721f3285301fe84643b00Stephen Hines for (auto *I : E->instructions()) { 861ef8225444452a1486bd721f3285301fe84643b00Stephen Hines if (I->definition()->opcode() != COP_Store) { 8626bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SS << "let "; 863ef8225444452a1486bd721f3285301fe84643b00Stephen Hines self()->printVariable(I, SS, true); 8646bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SS << " = "; 8656bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 866ef8225444452a1486bd721f3285301fe84643b00Stephen Hines self()->printSExpr(I->definition(), SS, Prec_MAX); 867ef8225444452a1486bd721f3285301fe84643b00Stephen Hines SS << ";"; 868ef8225444452a1486bd721f3285301fe84643b00Stephen Hines newline(SS); 869ef8225444452a1486bd721f3285301fe84643b00Stephen Hines } 870ef8225444452a1486bd721f3285301fe84643b00Stephen Hines SExpr *T = E->terminator(); 871ef8225444452a1486bd721f3285301fe84643b00Stephen Hines if (T) { 872ef8225444452a1486bd721f3285301fe84643b00Stephen Hines self()->printSExpr(T, SS, Prec_MAX); 873ef8225444452a1486bd721f3285301fe84643b00Stephen Hines SS << ";"; 8746bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines newline(SS); 8756bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 8766bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines newline(SS); 8776bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 8786bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 8796bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines void printPhi(Phi *E, StreamType &SS) { 8806bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SS << "phi("; 8816bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (E->status() == Phi::PH_SingleVal) 8826bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines self()->printSExpr(E->values()[0], SS, Prec_MAX); 8836bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines else { 8846bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines unsigned i = 0; 8856bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines for (auto V : E->values()) { 8866bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (i++ > 0) 8876bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SS << ", "; 8886bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines self()->printSExpr(V, SS, Prec_MAX); 8896bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 8906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 8916bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SS << ")"; 8926bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 8936bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 8946bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines void printGoto(Goto *E, StreamType &SS) { 8956bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SS << "goto "; 8966bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines printBlockLabel(SS, E->targetBlock(), E->index()); 8976bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 8986bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 8996bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines void printBranch(Branch *E, StreamType &SS) { 9006bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SS << "branch ("; 9016bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines self()->printSExpr(E->condition(), SS, Prec_MAX); 9026bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SS << ") "; 9036bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines printBlockLabel(SS, E->thenBlock(), E->thenIndex()); 9046bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SS << " "; 9056bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines printBlockLabel(SS, E->elseBlock(), E->elseIndex()); 9066bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 9076bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 9086bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines void printIdentifier(Identifier *E, StreamType &SS) { 9096bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SS << E->name(); 9106bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 9116bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 9126bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines void printIfThenElse(IfThenElse *E, StreamType &SS) { 9136bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SS << "if ("; 9146bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines printSExpr(E->condition(), SS, Prec_MAX); 9156bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SS << ") then "; 9166bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines printSExpr(E->thenExpr(), SS, Prec_Other); 9176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SS << " else "; 9186bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines printSExpr(E->elseExpr(), SS, Prec_Other); 9196bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 9206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 9216bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines void printLet(Let *E, StreamType &SS) { 9226bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SS << "let "; 9236bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines printVariable(E->variableDecl(), SS, true); 9246bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SS << " = "; 9256bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines printSExpr(E->variableDecl()->definition(), SS, Prec_Decl-1); 9266bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines SS << "; "; 9276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines printSExpr(E->body(), SS, Prec_Decl-1); 9286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines } 9296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines}; 9306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 9316bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 9326bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines} // end namespace til 9336bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines} // end namespace threadSafety 9346bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines} // end namespace clang 9356bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 9366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#endif // LLVM_CLANG_THREAD_SAFETY_TRAVERSE_H 937