Intel SPMD Program Compiler  1.9.1
ast.cpp
Go to the documentation of this file.
1 /*
2  Copyright (c) 2011-2015, Intel Corporation
3  All rights reserved.
4 
5  Redistribution and use in source and binary forms, with or without
6  modification, are permitted provided that the following conditions are
7  met:
8 
9  * Redistributions of source code must retain the above copyright
10  notice, this list of conditions and the following disclaimer.
11 
12  * Redistributions in binary form must reproduce the above copyright
13  notice, this list of conditions and the following disclaimer in the
14  documentation and/or other materials provided with the distribution.
15 
16  * Neither the name of Intel Corporation nor the names of its
17  contributors may be used to endorse or promote products derived from
18  this software without specific prior written permission.
19 
20 
21  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
22  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23  TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
24  PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
25  OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33 
34 /** @file ast.cpp
35 
36  @brief General functionality related to abstract syntax trees and
37  traversal of them.
38  */
39 
40 #include "ast.h"
41 #include "expr.h"
42 #include "func.h"
43 #include "stmt.h"
44 #include "sym.h"
45 #include "util.h"
46 
47 ///////////////////////////////////////////////////////////////////////////
48 // ASTNode
49 
51 }
52 
53 
54 ///////////////////////////////////////////////////////////////////////////
55 // AST
56 
57 void
59  if (sym == NULL)
60  return;
61  functions.push_back(new Function(sym, code));
62 }
63 
64 
65 void
67  for (unsigned int i = 0; i < functions.size(); ++i)
68  functions[i]->GenerateIR();
69 }
70 
71 ///////////////////////////////////////////////////////////////////////////
72 
73 ASTNode *
75  void *data) {
76  if (node == NULL)
77  return node;
78 
79  // Call the callback function
80  if (preFunc != NULL) {
81  if (preFunc(node, data) == false)
82  // The function asked us to not continue recursively, so stop.
83  return node;
84  }
85 
86  ////////////////////////////////////////////////////////////////////////////
87  // Handle Statements
88  if (llvm::dyn_cast<Stmt>(node) != NULL) {
89  ExprStmt *es;
90  DeclStmt *ds;
91  IfStmt *is;
92  DoStmt *dos;
93  ForStmt *fs;
94  ForeachStmt *fes;
95  ForeachActiveStmt *fas;
96  ForeachUniqueStmt *fus;
97  CaseStmt *cs;
98  DefaultStmt *defs;
99  SwitchStmt *ss;
100  ReturnStmt *rs;
101  LabeledStmt *ls;
102  StmtList *sl;
103  PrintStmt *ps;
104  AssertStmt *as;
105  DeleteStmt *dels;
106  UnmaskedStmt *ums;
107 
108  if ((es = llvm::dyn_cast<ExprStmt>(node)) != NULL)
109  es->expr = (Expr *)WalkAST(es->expr, preFunc, postFunc, data);
110  else if ((ds = llvm::dyn_cast<DeclStmt>(node)) != NULL) {
111  for (unsigned int i = 0; i < ds->vars.size(); ++i)
112  ds->vars[i].init = (Expr *)WalkAST(ds->vars[i].init, preFunc,
113  postFunc, data);
114  }
115  else if ((is = llvm::dyn_cast<IfStmt>(node)) != NULL) {
116  is->test = (Expr *)WalkAST(is->test, preFunc, postFunc, data);
117  is->trueStmts = (Stmt *)WalkAST(is->trueStmts, preFunc,
118  postFunc, data);
119  is->falseStmts = (Stmt *)WalkAST(is->falseStmts, preFunc,
120  postFunc, data);
121  }
122  else if ((dos = llvm::dyn_cast<DoStmt>(node)) != NULL) {
123  dos->testExpr = (Expr *)WalkAST(dos->testExpr, preFunc,
124  postFunc, data);
125  dos->bodyStmts = (Stmt *)WalkAST(dos->bodyStmts, preFunc,
126  postFunc, data);
127  }
128  else if ((fs = llvm::dyn_cast<ForStmt>(node)) != NULL) {
129  fs->init = (Stmt *)WalkAST(fs->init, preFunc, postFunc, data);
130  fs->test = (Expr *)WalkAST(fs->test, preFunc, postFunc, data);
131  fs->step = (Stmt *)WalkAST(fs->step, preFunc, postFunc, data);
132  fs->stmts = (Stmt *)WalkAST(fs->stmts, preFunc, postFunc, data);
133  }
134  else if ((fes = llvm::dyn_cast<ForeachStmt>(node)) != NULL) {
135  for (unsigned int i = 0; i < fes->startExprs.size(); ++i)
136  fes->startExprs[i] = (Expr *)WalkAST(fes->startExprs[i], preFunc,
137  postFunc, data);
138  for (unsigned int i = 0; i < fes->endExprs.size(); ++i)
139  fes->endExprs[i] = (Expr *)WalkAST(fes->endExprs[i], preFunc,
140  postFunc, data);
141  fes->stmts = (Stmt *)WalkAST(fes->stmts, preFunc, postFunc, data);
142  }
143  else if ((fas = llvm::dyn_cast<ForeachActiveStmt>(node)) != NULL) {
144  fas->stmts = (Stmt *)WalkAST(fas->stmts, preFunc, postFunc, data);
145  }
146  else if ((fus = llvm::dyn_cast<ForeachUniqueStmt>(node)) != NULL) {
147  fus->expr = (Expr *)WalkAST(fus->expr, preFunc, postFunc, data);
148  fus->stmts = (Stmt *)WalkAST(fus->stmts, preFunc, postFunc, data);
149  }
150  else if ((cs = llvm::dyn_cast<CaseStmt>(node)) != NULL)
151  cs->stmts = (Stmt *)WalkAST(cs->stmts, preFunc, postFunc, data);
152  else if ((defs = llvm::dyn_cast<DefaultStmt>(node)) != NULL)
153  defs->stmts = (Stmt *)WalkAST(defs->stmts, preFunc, postFunc, data);
154  else if ((ss = llvm::dyn_cast<SwitchStmt>(node)) != NULL) {
155  ss->expr = (Expr *)WalkAST(ss->expr, preFunc, postFunc, data);
156  ss->stmts = (Stmt *)WalkAST(ss->stmts, preFunc, postFunc, data);
157  }
158  else if (llvm::dyn_cast<BreakStmt>(node) != NULL ||
159  llvm::dyn_cast<ContinueStmt>(node) != NULL ||
160  llvm::dyn_cast<GotoStmt>(node) != NULL) {
161  // nothing
162  }
163  else if ((ls = llvm::dyn_cast<LabeledStmt>(node)) != NULL)
164  ls->stmt = (Stmt *)WalkAST(ls->stmt, preFunc, postFunc, data);
165  else if ((rs = llvm::dyn_cast<ReturnStmt>(node)) != NULL)
166  rs->expr = (Expr *)WalkAST(rs->expr, preFunc, postFunc, data);
167  else if ((sl = llvm::dyn_cast<StmtList>(node)) != NULL) {
168  std::vector<Stmt *> &sls = sl->stmts;
169  for (unsigned int i = 0; i < sls.size(); ++i)
170  sls[i] = (Stmt *)WalkAST(sls[i], preFunc, postFunc, data);
171  }
172  else if ((ps = llvm::dyn_cast<PrintStmt>(node)) != NULL)
173  ps->values = (Expr *)WalkAST(ps->values, preFunc, postFunc, data);
174  else if ((as = llvm::dyn_cast<AssertStmt>(node)) != NULL)
175  as->expr = (Expr *)WalkAST(as->expr, preFunc, postFunc, data);
176  else if ((dels = llvm::dyn_cast<DeleteStmt>(node)) != NULL)
177  dels->expr = (Expr *)WalkAST(dels->expr, preFunc, postFunc, data);
178  else if ((ums = llvm::dyn_cast<UnmaskedStmt>(node)) != NULL)
179  ums->stmts = (Stmt *)WalkAST(ums->stmts, preFunc, postFunc, data);
180  else
181  FATAL("Unhandled statement type in WalkAST()");
182  }
183  else {
184  ///////////////////////////////////////////////////////////////////////////
185  // Handle expressions
186  Assert(llvm::dyn_cast<Expr>(node) != NULL);
187  UnaryExpr *ue;
188  BinaryExpr *be;
189  AssignExpr *ae;
190  SelectExpr *se;
191  ExprList *el;
192  FunctionCallExpr *fce;
193  IndexExpr *ie;
194  MemberExpr *me;
195  TypeCastExpr *tce;
196  ReferenceExpr *re;
197  PtrDerefExpr *ptrderef;
198  RefDerefExpr *refderef;
199  SizeOfExpr *soe;
200  AddressOfExpr *aoe;
201  NewExpr *newe;
202 
203  if ((ue = llvm::dyn_cast<UnaryExpr>(node)) != NULL)
204  ue->expr = (Expr *)WalkAST(ue->expr, preFunc, postFunc, data);
205  else if ((be = llvm::dyn_cast<BinaryExpr>(node)) != NULL) {
206  be->arg0 = (Expr *)WalkAST(be->arg0, preFunc, postFunc, data);
207  be->arg1 = (Expr *)WalkAST(be->arg1, preFunc, postFunc, data);
208  }
209  else if ((ae = llvm::dyn_cast<AssignExpr>(node)) != NULL) {
210  ae->lvalue = (Expr *)WalkAST(ae->lvalue, preFunc, postFunc, data);
211  ae->rvalue = (Expr *)WalkAST(ae->rvalue, preFunc, postFunc, data);
212  }
213  else if ((se = llvm::dyn_cast<SelectExpr>(node)) != NULL) {
214  se->test = (Expr *)WalkAST(se->test, preFunc, postFunc, data);
215  se->expr1 = (Expr *)WalkAST(se->expr1, preFunc, postFunc, data);
216  se->expr2 = (Expr *)WalkAST(se->expr2, preFunc, postFunc, data);
217  }
218  else if ((el = llvm::dyn_cast<ExprList>(node)) != NULL) {
219  for (unsigned int i = 0; i < el->exprs.size(); ++i)
220  el->exprs[i] = (Expr *)WalkAST(el->exprs[i], preFunc,
221  postFunc, data);
222  }
223  else if ((fce = llvm::dyn_cast<FunctionCallExpr>(node)) != NULL) {
224  fce->func = (Expr *)WalkAST(fce->func, preFunc, postFunc, data);
225  fce->args = (ExprList *)WalkAST(fce->args, preFunc, postFunc, data);
226  for (int k = 0; k < 3; k++)
227  fce->launchCountExpr[0] = (Expr *)WalkAST(fce->launchCountExpr[0], preFunc,
228  postFunc, data);
229  }
230  else if ((ie = llvm::dyn_cast<IndexExpr>(node)) != NULL) {
231  ie->baseExpr = (Expr *)WalkAST(ie->baseExpr, preFunc, postFunc, data);
232  ie->index = (Expr *)WalkAST(ie->index, preFunc, postFunc, data);
233  }
234  else if ((me = llvm::dyn_cast<MemberExpr>(node)) != NULL)
235  me->expr = (Expr *)WalkAST(me->expr, preFunc, postFunc, data);
236  else if ((tce = llvm::dyn_cast<TypeCastExpr>(node)) != NULL)
237  tce->expr = (Expr *)WalkAST(tce->expr, preFunc, postFunc, data);
238  else if ((re = llvm::dyn_cast<ReferenceExpr>(node)) != NULL)
239  re->expr = (Expr *)WalkAST(re->expr, preFunc, postFunc, data);
240  else if ((ptrderef = llvm::dyn_cast<PtrDerefExpr>(node)) != NULL)
241  ptrderef->expr = (Expr *)WalkAST(ptrderef->expr, preFunc, postFunc,
242  data);
243  else if ((refderef = llvm::dyn_cast<RefDerefExpr>(node)) != NULL)
244  refderef->expr = (Expr *)WalkAST(refderef->expr, preFunc, postFunc,
245  data);
246  else if ((soe = llvm::dyn_cast<SizeOfExpr>(node)) != NULL)
247  soe->expr = (Expr *)WalkAST(soe->expr, preFunc, postFunc, data);
248  else if ((aoe = llvm::dyn_cast<AddressOfExpr>(node)) != NULL)
249  aoe->expr = (Expr *)WalkAST(aoe->expr, preFunc, postFunc, data);
250  else if ((newe = llvm::dyn_cast<NewExpr>(node)) != NULL) {
251  newe->countExpr = (Expr *)WalkAST(newe->countExpr, preFunc,
252  postFunc, data);
253  newe->initExpr = (Expr *)WalkAST(newe->initExpr, preFunc,
254  postFunc, data);
255  }
256  else if (llvm::dyn_cast<SymbolExpr>(node) != NULL ||
257  llvm::dyn_cast<ConstExpr>(node) != NULL ||
258  llvm::dyn_cast<FunctionSymbolExpr>(node) != NULL ||
259  llvm::dyn_cast<SyncExpr>(node) != NULL ||
260  llvm::dyn_cast<NullPointerExpr>(node) != NULL) {
261  // nothing to do
262  }
263  else
264  FATAL("Unhandled expression type in WalkAST().");
265  }
266 
267  // Call the callback function
268  if (postFunc != NULL)
269  return postFunc(node, data);
270  else
271  return node;
272 }
273 
274 
275 static ASTNode *
276 lOptimizeNode(ASTNode *node, void *) {
277  return node->Optimize();
278 }
279 
280 
281 ASTNode *
283  return WalkAST(root, NULL, lOptimizeNode, NULL);
284 }
285 
286 
287 Expr *
288 Optimize(Expr *expr) {
289  return (Expr *)Optimize((ASTNode *)expr);
290 }
291 
292 
293 Stmt *
294 Optimize(Stmt *stmt) {
295  return (Stmt *)Optimize((ASTNode *)stmt);
296 }
297 
298 
299 static ASTNode *
300 lTypeCheckNode(ASTNode *node, void *) {
301  return node->TypeCheck();
302 }
303 
304 
305 ASTNode *
307  return WalkAST(root, NULL, lTypeCheckNode, NULL);
308 }
309 
310 
311 Expr *
312 TypeCheck(Expr *expr) {
313  return (Expr *)TypeCheck((ASTNode *)expr);
314 }
315 
316 
317 Stmt *
318 TypeCheck(Stmt *stmt) {
319  return (Stmt *)TypeCheck((ASTNode *)stmt);
320 }
321 
322 
323 struct CostData {
325 
326  int cost;
328 };
329 
330 
331 static bool
332 lCostCallbackPre(ASTNode *node, void *d) {
333  CostData *data = (CostData *)d;
334  if (llvm::dyn_cast<ForeachStmt>(node) != NULL)
335  ++data->foreachDepth;
336  if (data->foreachDepth == 0)
337  data->cost += node->EstimateCost();
338  return true;
339 }
340 
341 
342 static ASTNode *
343 lCostCallbackPost(ASTNode *node, void *d) {
344  CostData *data = (CostData *)d;
345  if (llvm::dyn_cast<ForeachStmt>(node) != NULL)
346  --data->foreachDepth;
347  return node;
348 }
349 
350 
351 int
353  CostData data;
355  return data.cost;
356 }
357 
358 
359 /** Given an AST node, check to see if it's safe if we happen to run the
360  code for that node with the execution mask all off.
361  */
362 static bool
363 lCheckAllOffSafety(ASTNode *node, void *data) {
364  bool *okPtr = (bool *)data;
365 
366  FunctionCallExpr *fce;
367  if ((fce = llvm::dyn_cast<FunctionCallExpr>(node)) != NULL) {
368  if (fce->func == NULL)
369  return false;
370 
371  const Type *type = fce->func->GetType();
372  const PointerType *pt = CastType<PointerType>(type);
373  if (pt != NULL)
374  type = pt->GetBaseType();
375  const FunctionType *ftype = CastType<FunctionType>(type);
376  Assert(ftype != NULL);
377 
378  if (ftype->isSafe == false) {
379  *okPtr = false;
380  return false;
381  }
382  }
383 
384  if (llvm::dyn_cast<AssertStmt>(node) != NULL) {
385  // While it's fine to run the assert for varying tests, it's not
386  // desirable to check an assert on a uniform variable if all of the
387  // lanes are off.
388  *okPtr = false;
389  return false;
390  }
391 
392  if (llvm::dyn_cast<PrintStmt>(node) != NULL) {
393  *okPtr = false;
394  return false;
395  }
396 
397  if (llvm::dyn_cast<NewExpr>(node) != NULL ||
398  llvm::dyn_cast<DeleteStmt>(node) != NULL) {
399  // We definitely don't want to run the uniform variants of these if
400  // the mask is all off. It's also worth skipping the overhead of
401  // executing the varying versions of them in the all-off mask case.
402  *okPtr = false;
403  return false;
404  }
405 
406  if (llvm::dyn_cast<ForeachStmt>(node) != NULL ||
407  llvm::dyn_cast<ForeachActiveStmt>(node) != NULL ||
408  llvm::dyn_cast<ForeachUniqueStmt>(node) != NULL ||
409  llvm::dyn_cast<UnmaskedStmt>(node) != NULL) {
410  // The various foreach statements also shouldn't be run with an
411  // all-off mask. Since they can re-establish an 'all on' mask,
412  // this would be pretty unintuitive. (More generally, it's
413  // possibly a little strange to allow foreach in the presence of
414  // any non-uniform control flow...)
415  //
416  // Similarly, the implementation of foreach_unique assumes as a
417  // precondition that the mask won't be all off going into it, so
418  // we'll enforce that here...
419  *okPtr = false;
420  return false;
421  }
422 
423  if (llvm::dyn_cast<BinaryExpr>(node) != NULL) {
424  BinaryExpr* binaryExpr = llvm::dyn_cast<BinaryExpr>(node);
425  if (binaryExpr->op == BinaryExpr::Mod || binaryExpr->op == BinaryExpr::Div) {
426  *okPtr = false;
427  return false;
428  }
429  }
430  IndexExpr *ie;
431  if ((ie = llvm::dyn_cast<IndexExpr>(node)) != NULL && ie->baseExpr != NULL) {
432  const Type *type = ie->baseExpr->GetType();
433  if (type == NULL)
434  return true;
435  if (CastType<ReferenceType>(type) != NULL)
436  type = type->GetReferenceTarget();
437 
438  ConstExpr *ce = llvm::dyn_cast<ConstExpr>(ie->index);
439  if (ce == NULL) {
440  // indexing with a variable... -> not safe
441  *okPtr = false;
442  return false;
443  }
444 
445  const PointerType *pointerType = CastType<PointerType>(type);
446  if (pointerType != NULL) {
447  // pointer[index] -> can't be sure -> not safe
448  *okPtr = false;
449  return false;
450  }
451 
452  const SequentialType *seqType = CastType<SequentialType>(type);
453  Assert(seqType != NULL);
454  int nElements = seqType->GetElementCount();
455  if (nElements == 0) {
456  // Unsized array, so we can't be sure -> not safe
457  *okPtr = false;
458  return false;
459  }
460 
461  int32_t indices[ISPC_MAX_NVEC];
462  int count = ce->GetValues(indices);
463  for (int i = 0; i < count; ++i) {
464  if (indices[i] < 0 || indices[i] >= nElements) {
465  // Index is out of bounds -> not safe
466  *okPtr = false;
467  return false;
468  }
469  }
470 
471  // All indices are in-bounds
472  return true;
473  }
474 
475  MemberExpr *me;
476  if ((me = llvm::dyn_cast<MemberExpr>(node)) != NULL &&
477  me->dereferenceExpr) {
478  *okPtr = false;
479  return false;
480  }
481 
482  if (llvm::dyn_cast<PtrDerefExpr>(node) != NULL) {
483  *okPtr = false;
484  return false;
485  }
486 
487  /*
488  Don't allow turning if/else to straight-line-code if we
489  assign to a uniform.
490  */
491  AssignExpr *ae;
492  if ((ae = llvm::dyn_cast<AssignExpr>(node)) != NULL) {
493  if (ae->GetType()) {
494  if (ae->GetType()->IsUniformType()) {
495  *okPtr = false;
496  return false;
497  }
498  }
499  }
500 
501  return true;
502 }
503 
504 
505 bool
507  bool safe = true;
508  WalkAST(root, lCheckAllOffSafety, NULL, &safe);
509  return safe;
510 }
Expr * expr
Definition: stmt.h:581
Stmt * bodyStmts
Definition: stmt.h:190
std::vector< VariableDeclaration > vars
Definition: stmt.h:122
Expr * countExpr
Definition: expr.h:820
static ASTNode * lCostCallbackPost(ASTNode *node, void *d)
Definition: ast.cpp:343
Definition: func.h:44
Stmt * stmts
Definition: stmt.h:404
ASTNode * WalkAST(ASTNode *node, ASTPreCallBackFunc preFunc, ASTPostCallBackFunc postFunc, void *data)
Definition: ast.cpp:74
Division.
Definition: expr.h:143
virtual ASTNode * TypeCheck()=0
Stmt * trueStmts
Definition: stmt.h:149
static bool lCheckAllOffSafety(ASTNode *node, void *data)
Definition: ast.cpp:363
Expr * expr
Definition: stmt.h:380
std::vector< Expr * > endExprs
Definition: stmt.h:288
bool SafeToRunWithMaskAllOff(ASTNode *root)
Definition: ast.cpp:506
Representation of a print() statement in the program.
Definition: stmt.h:532
Expression that represents taking a reference of a (non-reference) variable.
Definition: expr.h:536
Interface class for statements in the ispc language.
Definition: stmt.h:49
Statement representing a single declaration (which in turn may declare a number of variables...
Definition: stmt.h:106
ASTNode * TypeCheck(ASTNode *root)
Definition: ast.cpp:306
Statement representing a single expression.
Definition: stmt.h:77
virtual int EstimateCost() const =0
Expr * baseExpr
Definition: expr.h:329
Expression representing a compile-time constant value.
Definition: expr.h:390
Abstract base class for types that represent sequences.
Definition: type.h:531
Expr * expr
Definition: expr.h:366
#define Assert(expr)
Definition: ispc.h:170
Statement implementation for 'for' loops (as well as for 'while' loops).
Definition: stmt.h:198
static ASTNode * lTypeCheckNode(ASTNode *node, void *)
Definition: ast.cpp:300
Representation of an assert statement in the program.
Definition: stmt.h:563
A list of expressions.
Definition: expr.h:252
Statement implementation representing a 'do' statement in the program.
Definition: stmt.h:173
Type implementation for pointers to other types.
Definition: type.h:446
Expr * expr
Definition: expr.h:530
ExprList * args
Definition: expr.h:298
Expr * arg0
Definition: expr.h:181
Expr * expr
Definition: expr.h:577
Modulus.
Definition: expr.h:144
header file with declarations for symbol and symbol table classes.
Expr * test
Definition: expr.h:243
Expr * expr
Definition: expr.h:132
int foreachDepth
Definition: ast.cpp:327
const Type * GetType() const
Definition: expr.cpp:3021
Binary expression.
Definition: expr.h:137
Expr * test
Definition: stmt.h:147
Stmt * stmts
Definition: stmt.h:448
Definition: expr.h:798
File with declarations for classes related to statements in the language.
Stmt * stmts
Definition: stmt.h:425
Expr * expr
Definition: stmt.h:446
Expression representing a type cast of the given expression to a probably-different type...
Definition: expr.h:509
bool IsUniformType() const
Definition: type.h:145
Statement implementation for a 'return' statement in the program.
Definition: stmt.h:365
Abstract base class for nodes in the abstract syntax tree (AST).
Definition: ast.h:50
Expr * func
Definition: expr.h:297
Stmt * stmts
Definition: stmt.h:337
int GetValues(bool *, bool forceVarying=false) const
Definition: expr.cpp:5876
Expr * arg1
Definition: expr.h:181
Stmt * step
Definition: stmt.h:221
Expr * expr
Definition: expr.h:637
Statement implementation for a continue statement in the program.
Definition: stmt.h:249
ASTNode *(* ASTPostCallBackFunc)(ASTNode *node, void *data)
Definition: ast.h:167
virtual ASTNode * Optimize()=0
int cost
Definition: ast.cpp:326
Expr * expr
Definition: expr.h:554
A sync statement in the program (waits for all launched tasks before proceeding). ...
Definition: expr.h:757
Expr * index
Definition: expr.h:329
Expr * lvalue
Definition: expr.h:218
Stmt * stmts
Definition: stmt.h:312
Stmt * stmts
Definition: stmt.h:223
CostData()
Definition: ast.cpp:324
const Op op
Definition: expr.h:180
Expr * values
Definition: stmt.h:551
const Type * GetBaseType() const
Definition: type.cpp:1018
#define FATAL(message)
Definition: util.h:113
Expr * testExpr
Definition: stmt.h:189
bool(* ASTPreCallBackFunc)(ASTNode *node, void *data)
Definition: ast.h:162
Expr * launchCountExpr[3]
Definition: expr.h:300
#define ISPC_MAX_NVEC
Definition: ispc.h:68
Representation of a function in a source file.
Stmt * falseStmts
Definition: stmt.h:151
std::vector< Function * > functions
Definition: ast.h:155
Expr * test
Definition: stmt.h:218
Stmt * init
Definition: stmt.h:215
Expression representing member selection ("foo.bar").
Definition: expr.h:341
Stmt * stmts
Definition: stmt.h:290
Definition: stmt.h:387
std::vector< Expr * > exprs
Definition: expr.h:270
virtual const Type * GetType() const =0
std::vector< Expr * > startExprs
Definition: stmt.h:287
Unary expression.
Definition: expr.h:105
Expr * rvalue
Definition: expr.h:218
Expression representing indexing into something with an integer offset.
Definition: expr.h:309
Type representing a function (return type + argument types)
Definition: type.h:883
Representation of a program symbol.
Definition: sym.h:63
void AddFunction(Symbol *sym, Stmt *code)
Definition: ast.cpp:58
Stmt * stmt
Definition: stmt.h:496
Expr * expr2
Definition: expr.h:243
void GenerateIR()
Definition: ast.cpp:66
Interface class that defines the type abstraction.
Definition: type.h:101
static bool lCostCallbackPre(ASTNode *node, void *d)
Definition: ast.cpp:332
std::vector< Stmt * > stmts
Definition: stmt.h:519
Expression that represents dereferencing a pointer to get its value.
Definition: expr.h:583
Expr abstract base class and expression implementations.
int EstimateCost(ASTNode *root)
Definition: ast.cpp:352
Expr * expr
Definition: stmt.h:92
Statement implementation for parallel 'foreach' loops.
Definition: stmt.h:268
Stmt * stmts
Definition: stmt.h:358
Statement representing a single if statement, possibly with an else clause.
Definition: stmt.h:128
Expr is the abstract base class that defines the interface that all expression types must implement...
Definition: expr.h:48
Expr * expr
Definition: stmt.h:603
Assignment expression.
Definition: expr.h:186
Representation of a list of statements in the program.
Definition: stmt.h:502
ASTNode * Optimize(ASTNode *root)
Definition: ast.cpp:282
Expr * expr
Definition: expr.h:662
virtual int GetElementCount() const =0
Expression that represents dereferencing a reference to get its value.
Definition: expr.h:601
Expr * expr
Definition: stmt.h:336
bool isSafe
Definition: type.h:960
bool dereferenceExpr
Definition: expr.h:376
Selection expression, corresponding to "test ? a : b".
Definition: expr.h:226
virtual const Type * GetReferenceTarget() const
Definition: type.cpp:3301
Expr * expr1
Definition: expr.h:243
static ASTNode * lOptimizeNode(ASTNode *node, void *)
Definition: ast.cpp:276
Expr * initExpr
Definition: expr.h:823
Expression representing a function call.
Definition: expr.h:276
virtual ~ASTNode()
Definition: ast.cpp:50