16#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETYTRAVERSE_H
17#define LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETYTRAVERSE_H
23#include "llvm/ADT/StringRef.h"
24#include "llvm/Support/Casting.h"
29namespace threadSafety {
57template <
class Self,
class R>
60 Self *
self() {
return static_cast<Self *
>(
this); }
68 typename R::R_SExpr
traverse(T* &E,
typename R::R_Ctx Ctx) {
81#define TIL_OPCODE_DEF(X) \
83 return self()->traverse##X(cast<X>(E), Ctx);
84#include "ThreadSafetyOps.def"
87 return self()->reduceNull();
92#define TIL_OPCODE_DEF(X) \
93 typename R::R_SExpr traverse##X(X *e, typename R::R_Ctx Ctx) { \
94 return e->traverse(*self(), Ctx); \
96#include "ThreadSafetyOps.def"
309template <
typename Self>
312 Self *
self() {
return reinterpret_cast<Self *
>(
this); }
317#define TIL_OPCODE_DEF(X) \
319 return cast<X>(E1)->compare(cast<X>(E2), *self());
320#include "ThreadSafetyOps.def"
357 return Eq.compare(E1, E2);
377 if (E1->
opcode() == COP_Wildcard || E2->
opcode() == COP_Wildcard)
395 return Matcher.compare(E1, E2);
404template <
typename Self,
typename StreamType>
418 : Verbose(
V), Cleanup(
C), CStyle(CS) {}
422 printer.printSExpr(E, SS,
Prec_MAX);
426 Self *
self() {
return reinterpret_cast<Self *
>(
this); }
472 case COP_BasicBlock:
return Prec_MAX;
500 self()->printNull(SS);
503 if (Sub && E->
block() && E->
opcode() != COP_Variable) {
504 SS <<
"_x" << E->
id();
516#define TIL_OPCODE_DEF(X) \
518 self()->print##X(cast<X>(E), SS); \
520#include "ThreadSafetyOps.def"
547 SS <<
"'" << E->
value() <<
"'";
562 if (E->
as<
bool>().value())
627 SS << D->getNameAsString();
636 SS <<
V->name() <<
V->id();
656 if (B && B->
opcode() == COP_Function)
657 self()->printFunction(cast<Function>(B), SS, 2);
687 if (F->
opcode() == COP_Apply) {
711 if (
const auto *SAP = dyn_cast<SApply>(E->
record())) {
712 if (
const auto *
V = dyn_cast<Variable>(SAP->sfun())) {
719 if (isa<Wildcard>(E->
record())) {
736 if (T->
opcode() == COP_Apply) {
737 self()->printApply(cast<Apply>(T), SS,
true);
820 for (
const auto *BBI : *E)
828 if (E->
opcode() == COP_Variable) {
829 const auto *
V = cast<Variable>(E);
830 SS <<
"let " <<
V->name() <<
V->id() <<
" = ";
834 else if (E->
opcode() != COP_Store) {
835 SS <<
"let _x" << E->
id() <<
" = ";
843 SS <<
"BB_" << E->
blockID() <<
":";
869 for (
const auto *
V : E->
values()) {
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
__device__ __2f16 float __ockl_bool s
This represents a decl that may have a name.
std::string getQualifiedNameAsString() const
Allocate memory for a new value on the heap or stack.
Apply an argument to a function.
Pointer arithmetic, restricted to arrays only.
If p is a reference to an array, then p[i] is a reference to the i'th element of the array.
A basic block is part of an SCFG.
int blockID() const
Returns the block ID. Every block has a unique ID in the CFG.
const InstrArray & arguments() const
const Terminator * terminator() const
InstrArray & instructions()
const BasicBlock * parent() const
Simple arithmetic binary operations, e.g.
TIL_BinaryOpcode binaryOpcode() const
A conditional branch to two other blocks.
const SExpr * condition() const
const BasicBlock * elseBlock() const
const BasicBlock * thenBlock() const
Call a function (after all arguments have been applied).
TIL_CastOpcode castOpcode() const
A block of code – e.g. the body of a function.
bool compareByCase(const SExpr *E1, const SExpr *E2)
Container(CopyReducerBase &S, unsigned N)
CopyReducerBase(MemRegionRef A)
bool compare(const SExpr *E1, const SExpr *E2)
bool comparePointers(const void *P, const void *Q)
bool compareStrings(StringRef s, StringRef r)
void enterScope(const Variable *V1, const Variable *V2)
bool compareVariableRefs(const Variable *V1, const Variable *V2)
static bool compareExprs(const SExpr *E1, const SExpr *E2)
bool compareIntegers(unsigned i, unsigned j)
A typed, writable location in memory.
Variable * variableDecl()
Placeholder for an expression that has not yet been created.
SExpr * maybeGetResult() const
Jump to another basic block.
unsigned index() const
Returns the index into the.
const BasicBlock * targetBlock() const
An if-then-else expression.
Variable * variableDecl()
A Literal pointer to an object allocated in memory.
const ValueDecl * clangDecl() const
const LiteralT< T > & as() const
ValueType valueType() const
const Expr * clangExpr() const
Load a value from memory.
bool compareVariableRefs(const Variable *V1, const Variable *V2)
bool comparePointers(const void *P, const void *Q)
static bool compareExprs(const SExpr *E1, const SExpr *E2)
bool compare(const SExpr *E1, const SExpr *E2)
bool compareIntegers(unsigned i, unsigned j)
bool compareStrings(StringRef s, StringRef r)
void enterScope(const Variable *V1, const Variable *V2)
Phi Node, for code in SSA form.
const ValArray & values() const
static const unsigned Prec_MAX
void printFuture(const Future *E, StreamType &SS)
void printCall(const Call *E, StreamType &SS)
void printLiteralT(const LiteralT< uint8_t > *E, StreamType &SS)
void printApply(const Apply *E, StreamType &SS, bool sugared=false)
void printProject(const Project *E, StreamType &SS)
void printWildcard(const Wildcard *E, StreamType &SS)
void printBranch(const Branch *E, StreamType &SS)
void printLet(const Let *E, StreamType &SS)
void printLiteral(const Literal *E, StreamType &SS)
void printField(const Field *E, StreamType &SS)
void printUnaryOp(const UnaryOp *E, StreamType &SS)
void printUndefined(const Undefined *E, StreamType &SS)
void printIdentifier(const Identifier *E, StreamType &SS)
static void print(const SExpr *E, StreamType &SS)
void printReturn(const Return *E, StreamType &SS)
void printVariable(const Variable *V, StreamType &SS, bool IsVarDecl=false)
static const unsigned Prec_Unary
void printCode(const Code *E, StreamType &SS)
void printStore(const Store *E, StreamType &SS)
static const unsigned Prec_Binary
static const unsigned Prec_Atom
void printCast(const Cast *E, StreamType &SS)
void printIfThenElse(const IfThenElse *E, StreamType &SS)
void printBasicBlock(const BasicBlock *E, StreamType &SS)
void printLiteralPtr(const LiteralPtr *E, StreamType &SS)
void newline(StreamType &SS)
void printGoto(const Goto *E, StreamType &SS)
void printBBInstr(const SExpr *E, StreamType &SS)
void printAlloc(const Alloc *E, StreamType &SS)
void printNull(StreamType &SS)
void printPhi(const Phi *E, StreamType &SS)
void printSCFG(const SCFG *E, StreamType &SS)
static const unsigned Prec_Decl
unsigned precedence(const SExpr *E)
static const unsigned Prec_Postfix
void printFunction(const Function *E, StreamType &SS, unsigned sugared=0)
void printBinaryOp(const BinaryOp *E, StreamType &SS)
void printArrayAdd(const ArrayAdd *E, StreamType &SS)
static const unsigned Prec_Other
void printSFunction(const SFunction *E, StreamType &SS)
void printArrayIndex(const ArrayIndex *E, StreamType &SS)
void printSApply(const SApply *E, StreamType &SS)
void printLoad(const Load *E, StreamType &SS)
void printLiteralT(const LiteralT< T > *E, StreamType &SS)
PrettyPrinter(bool V=false, bool C=true, bool CS=true)
void printBlockLabel(StreamType &SS, const BasicBlock *BB, int index)
void printSExpr(const SExpr *E, StreamType &SS, unsigned P, bool Sub=true)
Project a named slot from a C++ struct or class.
const ValueDecl * clangDecl() const
StringRef slotName() const
Return from the enclosing function, passing the return value to the caller.
Apply a self-argument to a self-applicable function.
bool isDelegation() const
An SCFG is a control-flow graph.
Base class for AST nodes in the typed intermediate language.
BasicBlock * block() const
Returns the block, if this is an instruction in a basic block, otherwise returns null.
TIL_Opcode opcode() const
unsigned id() const
Returns the instruction ID for this expression.
A self-applicable function.
Variable * variableDecl()
R_Ctx subExprCtx(R_Ctx Ctx)
R::R_SExpr traverse(T *&E, typename R::R_Ctx Ctx)
R::R_SExpr traverseSExpr(SExpr *E, typename R::R_Ctx Ctx)
R::R_SExpr traverseByCase(SExpr *E, typename R::R_Ctx Ctx)
Simple arithmetic unary operations, e.g.
TIL_UnaryOpcode unaryOpcode() const
Placeholder for expressions that cannot be represented in the TIL.
SExpr * definition()
Return the definition of the variable.
@ VK_SFun
SFunction (self) parameter.
Container(VisitReducerBase &S, unsigned N)
Variable * enterScope(Variable &Orig, R_SExpr E0)
R_SExpr reduceBinaryOp(BinaryOp &Orig, R_SExpr E0, R_SExpr E1)
R_SExpr reduceStore(Store &Orig, R_SExpr E0, R_SExpr E1)
R_SExpr reduceProject(Project &Orig, R_SExpr E0)
R_SExpr reduceLet(Let &Orig, Variable *Nvd, R_SExpr B)
R_SExpr reduceArrayAdd(Store &Orig, R_SExpr E0, R_SExpr E1)
R_SExpr reduceAlloc(Alloc &Orig, R_SExpr E0)
void exitScope(const Variable &Orig)
void exitBasicBlock(BasicBlock &BB)
R_SExpr reduceUnaryOp(UnaryOp &Orig, R_SExpr E0)
R_SExpr reduceIdentifier(Identifier &Orig)
R_SExpr reduceLiteral(Literal &Orig)
R_SExpr reduceSCFG(SCFG &Orig, Container< BasicBlock * > Bbs)
R_SExpr reduceSApply(SApply &Orig, R_SExpr E0, R_SExpr E1)
R_BasicBlock reduceBasicBlock(BasicBlock &Orig, Container< R_SExpr > &As, Container< R_SExpr > &Is, R_SExpr T)
BasicBlock * reduceBasicBlockRef(BasicBlock *Obb)
R_SExpr reduceGoto(Goto &Orig, BasicBlock *B)
R_SExpr reduceUndefined(Undefined &Orig)
bool traverse(SExpr *E, TraversalKind K=TRV_Normal)
R_SExpr reduceWildcard(Wildcard &Orig)
R_SExpr reduceField(Field &Orig, R_SExpr E0, R_SExpr E1)
R_SExpr reducePhi(Phi &Orig, Container< R_SExpr > &As)
R_SExpr reduceLoad(Load &Orig, R_SExpr E0)
R_SExpr reduceCode(Code &Orig, R_SExpr E0, R_SExpr E1)
R_SExpr reduceSFunction(SFunction &Orig, Variable *Nvd, R_SExpr E0)
Variable * reduceVariableRef(Variable *Ovd)
R_SExpr reduceApply(Apply &Orig, R_SExpr E0, R_SExpr E1)
R_SExpr reduceFunction(Function &Orig, Variable *Nvd, R_SExpr E0)
R_SExpr reduceLiteralT(LiteralT< T > &Orig)
R_SExpr reduceBranch(Branch &O, R_SExpr C, BasicBlock *B0, BasicBlock *B1)
void enterBasicBlock(BasicBlock &BB)
R_SExpr reduceReturn(Return &O, R_SExpr E)
R_SExpr reduceCast(Cast &Orig, R_SExpr E0)
R_SExpr reduceCall(Call &Orig, R_SExpr E0)
R_SExpr reduceArrayIndex(Store &Orig, R_SExpr E0, R_SExpr E1)
static bool visit(SExpr *E)
R_SExpr reduceLiteralPtr(Literal &Orig)
R_SExpr reduceIfThenElse(IfThenElse &Orig, R_SExpr C, R_SExpr T, R_SExpr E)
Placeholder for a wildcard that matches any other expression.
StringRef getBinaryOpcodeString(TIL_BinaryOpcode Op)
Return the name of a binary opcode.
StringRef getUnaryOpcodeString(TIL_UnaryOpcode Op)
Return the name of a unary opcode.
std::string getSourceLiteralString(const Expr *CE)
@ C
Languages that the frontend can parse and compile.
ValueTypes are data types that can actually be held in registers.