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>
68 typename R::R_SExpr
traverse(
T* &
E,
typename R::R_Ctx Ctx) {
80 switch (
E->opcode()) {
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>
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) {}
443 switch (
E->opcode()) {
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();
515 switch (
E->opcode()) {
516#define TIL_OPCODE_DEF(X) \
518 self()->print##X(cast<X>(E), SS); \
520#include "ThreadSafetyOps.def"
547 SS <<
"'" <<
E->value() <<
"'";
551 if (
E->clangExpr()) {
562 if (
E->as<
bool>().value())
627 SS <<
D->getNameAsString();
636 SS <<
V->name() <<
V->id();
651 self()->printVariable(
E->variableDecl(), SS,
true);
653 self()->printSExpr(
E->variableDecl()->definition(), SS,
Prec_MAX);
655 const SExpr *B =
E->body();
656 if (B && B->
opcode() == COP_Function)
657 self()->printFunction(cast<Function>(B), SS, 2);
666 self()->printVariable(
E->variableDecl(), SS,
true);
686 const SExpr *F =
E->fun();
687 if (F->
opcode() == COP_Apply) {
701 if (
E->isDelegation()) {
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())) {
722 SS <<
E->clangDecl()->getQualifiedNameAsString();
727 if (CStyle &&
E->isArrow())
736 if (
T->opcode() == COP_Apply) {
737 self()->printApply(cast<Apply>(
T), SS,
true);
790 switch (
E->castOpcode()) {
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() <<
":";
845 SS <<
" BB_" <<
E->parent()->blockID();
848 for (
const auto *A :
E->arguments())
851 for (
const auto *I :
E->instructions())
854 const SExpr *
T =
E->terminator();
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.
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.
Simple arithmetic binary operations, e.g.
A conditional branch to two other blocks.
Call a function (after all arguments have been applied).
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.
Placeholder for an expression that has not yet been created.
Jump to another basic block.
An if-then-else expression.
A Literal pointer to an object allocated in memory.
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.
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.
Return from the enclosing function, passing the return value to the caller.
Apply a self-argument to a self-applicable function.
An SCFG is a control-flow graph.
Base class for AST nodes in the typed intermediate language.
TIL_Opcode opcode() const
A self-applicable function.
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.
Placeholder for expressions that cannot be represented in the TIL.
@ 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)
The JSON file list parser is used to communicate input to InstallAPI.
@ Self
'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
const FunctionProtoType * T
ValueTypes are data types that can actually be held in registers.