51 #include <llvm/IR/CallingConv.h> 52 #include <llvm/IR/DerivedTypes.h> 53 #include <llvm/IR/Function.h> 54 #include <llvm/IR/Instructions.h> 55 #include <llvm/IR/LLVMContext.h> 56 #include <llvm/IR/Metadata.h> 57 #include <llvm/IR/Module.h> 58 #include <llvm/IR/Type.h> 59 #include <llvm/Support/raw_ostream.h> 86 printf(
"%*c", indent,
' ');
87 printf(
"Expr stmt: ");
101 const ArrayType *at = CastType<ArrayType>(type);
115 for (
unsigned int i = 0; i <
vars.size(); ++i) {
118 if (sym->
type == NULL)
135 if (sym->
type == NULL)
139 Error(
pos,
"Illegal to declare an unsized array variable without " 140 "providing an initializer expression to set its size.");
146 if (initExpr == NULL) {
148 "Must provide initializer for reference-type " 155 if (initLVType == NULL) {
157 "Initializer for reference-type variable " 158 "\"%s\" must have an lvalue type.",
164 "Initializer for reference-type variable " 165 "\"%s\" must have a uniform lvalue type.",
173 if (llvmType == NULL) {
182 llvm::Constant *cinit = NULL;
183 if (initExpr != NULL) {
189 if (llvm::dyn_cast<ExprList>(initExpr) == NULL) {
197 std::pair<llvm::Constant *, bool> cinitPair = initExpr->
GetConstant(sym->
type);
198 cinit = cinitPair.first;
201 "Initializer for static variable " 202 "\"%s\" must be a constant.",
206 cinit = llvm::Constant::getNullValue(llvmType);
212 llvm::Twine(
"static.") + llvm::Twine(sym->
pos.
first_line) + llvm::Twine(
".") + sym->
name.c_str());
224 "Missing initializer for const variable " 236 for (
unsigned int i = 0; i <
vars.size(); ++i) {
238 if (init != NULL && llvm::dyn_cast<ExprList>(init) == NULL) {
267 bool encounteredError =
false;
272 if (CastType<AtomicType>(type) != NULL || CastType<EnumType>(type) != NULL) {
276 if (llvm::dyn_cast<ExprList>(*init) == NULL) {
279 encounteredError =
true;
281 }
else if (CastType<ArrayType>(type) != NULL && llvm::dyn_cast<ExprList>(*init) == NULL) {
282 encounteredError =
true;
283 Error((*init)->pos,
"Array initializer must be an initializer list");
284 }
else if (CastType<StructType>(type) != NULL && llvm::dyn_cast<ExprList>(*init) != NULL) {
285 const StructType *st = CastType<StructType>(type);
288 for (
int i = 0; i < elt_count; i++) {
293 return encounteredError;
297 bool encounteredError =
false;
298 for (
unsigned int i = 0; i <
vars.size(); ++i) {
299 if (
vars[i].sym == NULL) {
300 encounteredError =
true;
304 if (
vars[i].init == NULL)
310 return encounteredError ? NULL :
this;
314 printf(
"%*cDecl Stmt:", indent,
' ');
316 for (
unsigned int i = 0; i <
vars.size(); ++i) {
317 printf(
"%*cVariable %s (%s)", indent + 4,
' ',
vars[i].sym->name.c_str(),
318 vars[i].sym->type->GetString().c_str());
319 if (
vars[i].init != NULL) {
321 vars[i].init->Print();
334 :
Stmt(p,
IfStmtID), test(t), trueStmts(ts), falseStmts(fs),
335 doAllCheck(checkCoherence && !
g->opt.disableCoherentControlFlow) {}
341 if (llvm::dyn_cast<StmtList>(stmts) == NULL)
345 if (llvm::dyn_cast<const StmtList>(stmts) == NULL)
388 if (testValue == NULL)
394 Warning(
test->
pos,
"Uniform condition supplied to \"cif\" statement.");
443 if (testType != NULL) {
446 "\"if\" statement test");
464 printf(
"%*cIf Stmt %s", indent,
' ',
doAllCheck ?
"DO ALL CHECK" :
"");
466 printf(
"\n%*cTest: ", indent + 4,
' ');
470 printf(
"%*cTrue:\n", indent + 4,
' ');
474 printf(
"%*cFalse:\n", indent + 4,
' ');
587 llvm::BasicBlock *bTestNoneCheck = ctx->
CreateBasicBlock(
"cif_test_none_check");
588 llvm::Value *testAllQ = ctx->
All(ltest);
589 ctx->
BranchInst(bTestAll, bTestNoneCheck, testAllQ);
607 llvm::Value *testMixedQ = ctx->
Any(ltest);
608 ctx->
BranchInst(bTestMixed, bTestNone, testMixedQ);
639 llvm::BasicBlock *bDone)
const {
651 ctx->
BranchInst(bRunTrue, bNext, maskAnyTrueQ);
669 ctx->
BranchInst(bRunFalse, bDone, maskAnyFalseQ);
687 varyingControlFlowDepth = 0;
688 foundVaryingBreakOrContinue =
false;
699 if ((ifStmt = llvm::dyn_cast<IfStmt>(node)) != NULL && ifStmt->
test != NULL) {
713 if ((llvm::dyn_cast<BreakStmt>(node) != NULL || llvm::dyn_cast<ContinueStmt>(node) != NULL) &&
724 if (llvm::dyn_cast<ForStmt>(node) != NULL || llvm::dyn_cast<
DoStmt>(node) != NULL ||
725 llvm::dyn_cast<ForeachStmt>(node) != NULL)
756 :
Stmt(p,
DoStmtID), testExpr(t), bodyStmts(s), doCoherentCheck(cc && !
g->opt.disableCoherentControlFlow) {}
775 ctx->
StartLoop(bexit, btest, uniformTest);
867 const Type *testType;
902 printf(
"%*cDo Stmt", indent,
' ');
905 printf(
"%*cTest: ", indent + 4,
' ');
910 printf(
"%*cStmts:\n", indent + 4,
' ');
934 ctx->
StartLoop(bexit, bstep, uniformTest);
950 llvm::Value *ltest = NULL;
985 if (!llvm::dyn_cast_or_null<StmtList>(
stmts))
1029 if (!llvm::dyn_cast_or_null<StmtList>(
stmts))
1052 const Type *testType;
1059 "\"for\"/\"while\" statement");
1075 printf(
"%*cFor Stmt", indent,
' ');
1079 printf(
"%*cInit:\n", indent + 4,
' ');
1083 printf(
"%*cTest: ", indent + 4,
' ');
1088 printf(
"%*cStep:\n", indent + 4,
' ');
1092 printf(
"%*cStmts:\n", indent + 4,
' ');
1115 printf(
"%*cBreak Stmt", indent,
' ');
1138 printf(
"%*cContinue Stmt", indent,
' ');
1148 :
Stmt(pos,
ForeachStmtID), dimVariables(lvs), startExprs(se), endExprs(ee), isTiled(t), stmts(s) {}
1155 llvm::Value *varyingCounterPtr,
const std::vector<int> &spans) {
1157 llvm::Value *counter = ctx->
LoadInst(uniformCounterPtr);
1171 int prevDimSpanCount = 1;
1172 for (
int j = dim; j < nDims - 1; ++j)
1173 prevDimSpanCount *= spans[j + 1];
1174 d /= prevDimSpanCount;
1177 delta[i] = d % spans[dim];
1182 llvm::Value *varyingCounter =
1184 ctx->
StoreInst(varyingCounter, varyingCounterPtr);
1185 return varyingCounter;
1208 if (dimsLeft == 0) {
1215 if (isTiled ==
false || (dimsLeft >=
lLog2(itemsLeft)))
1221 else if (itemsLeft >= 16 && (dimsLeft == 1))
1229 lGetSpans(dimsLeft - 1, nDims, itemsLeft / *a, isTiled, a + 1);
1243 llvm::BasicBlock *bbMaskedBody = ctx->
CreateBasicBlock(
"foreach_masked_body");
1262 std::vector<llvm::BasicBlock *> bbReset, bbStep, bbTest;
1263 std::vector<llvm::Value *> startVals, endVals, uniformCounterPtrs;
1264 std::vector<llvm::Value *> nExtras, alignedEnd, extrasMaskPtrs;
1266 std::vector<int> span(nDims, 0);
1269 for (
int i = 0; i < nDims; ++i) {
1279 llvm::Value *sv =
startExprs[i]->GetValue(ctx);
1280 llvm::Value *ev =
endExprs[i]->GetValue(ctx);
1281 if (sv == NULL || ev == NULL)
1283 startVals.push_back(sv);
1284 endVals.push_back(ev);
1287 llvm::Value *nItems = ctx->
BinaryOperator(llvm::Instruction::Sub, ev, sv,
"nitems");
1296 alignedEnd.push_back(ctx->
BinaryOperator(llvm::Instruction::Sub, ev, nExtras[i],
"aligned_end"));
1304 ctx->
StoreInst(startVals[i], uniformCounterPtrs[i]);
1330 for (
int i = 0; i < nDims; ++i) {
1336 ctx->
StoreInst(startVals[i], uniformCounterPtrs[i]);
1347 for (
int i = 0; i < nDims - 1; ++i) {
1349 llvm::Value *counter = ctx->
LoadInst(uniformCounterPtrs[i]);
1350 llvm::Value *newCounter =
1352 ctx->
StoreInst(newCounter, uniformCounterPtrs[i]);
1358 std::vector<llvm::Value *> inExtras;
1359 for (
int i = 0; i < nDims - 1; ++i) {
1362 llvm::Value *haveExtras =
1363 ctx->
CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_SGT, endVals[i], alignedEnd[i],
"have_extras");
1365 llvm::Value *counter = ctx->
LoadInst(uniformCounterPtrs[i], NULL,
"counter");
1366 llvm::Value *atAlignedEnd =
1367 ctx->
CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_EQ, counter, alignedEnd[i],
"at_aligned_end");
1368 llvm::Value *inEx = ctx->
BinaryOperator(llvm::Instruction::And, haveExtras, atAlignedEnd,
"in_extras");
1371 inExtras.push_back(inEx);
1373 inExtras.push_back(ctx->
BinaryOperator(llvm::Instruction::Or, inEx, inExtras[i - 1],
"in_extras_all"));
1375 llvm::Value *varyingCounter =
1382 llvm::Value *emask = ctx->
CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_SLT, varyingCounter, smearEnd);
1386 ctx->
StoreInst(emask, extrasMaskPtrs[i]);
1388 llvm::Value *oldMask = ctx->
LoadInst(extrasMaskPtrs[i - 1]);
1389 llvm::Value *newMask = ctx->
BinaryOperator(llvm::Instruction::And, oldMask, emask,
"extras_mask");
1390 ctx->
StoreInst(newMask, extrasMaskPtrs[i]);
1393 llvm::Value *notAtEnd = ctx->
CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_SLT, counter, endVals[i]);
1394 ctx->
BranchInst(bbTest[i + 1], bbReset[i], notAtEnd);
1430 llvm::BasicBlock *bbOuterInExtras = ctx->
CreateBasicBlock(
"outer_in_extras");
1431 llvm::BasicBlock *bbOuterNotInExtras = ctx->
CreateBasicBlock(
"outer_not_in_extras");
1434 if (inExtras.size())
1435 ctx->
BranchInst(bbOuterInExtras, bbOuterNotInExtras, inExtras.back());
1453 llvm::BasicBlock *bbAllInnerPartialOuter = ctx->
CreateBasicBlock(
"all_inner_partial_outer");
1463 llvm::Value *counter = ctx->
LoadInst(uniformCounterPtrs[nDims - 1], NULL,
"counter");
1464 llvm::Value *beforeAlignedEnd = ctx->
CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_SLT, counter,
1465 alignedEnd[nDims - 1],
"before_aligned_end");
1466 ctx->
BranchInst(bbAllInnerPartialOuter, bbPartial, beforeAlignedEnd);
1498 mask = ctx->
LoadInst(extrasMaskPtrs[nDims - 2]);
1514 llvm::Value *emask = ctx->
CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_SLT, varyingCounter, smearEnd);
1520 llvm::Value *oldMask = ctx->
LoadInst(extrasMaskPtrs[nDims - 2]);
1521 llvm::Value *newMask = ctx->
BinaryOperator(llvm::Instruction::And, oldMask, emask,
"extras_mask");
1528 llvm::Value *counter = ctx->
LoadInst(uniformCounterPtrs[nDims - 1], NULL,
"counter");
1529 llvm::Value *atEnd =
1530 ctx->
CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_NE, counter, endVals[nDims - 1],
"at_end");
1531 ctx->
BranchInst(bbMaskedBody, bbReset[nDims - 1], atEnd);
1546 llvm::BasicBlock *bbPartialInnerAllOuter = ctx->
CreateBasicBlock(
"partial_inner_all_outer");
1549 llvm::Value *counter = ctx->
LoadInst(uniformCounterPtrs[nDims - 1], NULL,
"counter");
1550 llvm::Value *beforeAlignedEnd = ctx->
CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_SLT, counter,
1551 alignedEnd[nDims - 1],
"before_aligned_end");
1552 ctx->
BranchInst(bbFullBody, bbPartialInnerAllOuter, beforeAlignedEnd);
1561 llvm::BasicBlock *bbFullBodyContinue = ctx->
CreateBasicBlock(
"foreach_full_continue");
1577 llvm::Value *counter = ctx->
LoadInst(uniformCounterPtrs[nDims - 1]);
1578 llvm::Value *newCounter =
1580 ctx->
StoreInst(newCounter, uniformCounterPtrs[nDims - 1]);
1588 llvm::BasicBlock *bbSetInnerMask = ctx->
CreateBasicBlock(
"partial_inner_only");
1591 llvm::Value *counter = ctx->
LoadInst(uniformCounterPtrs[nDims - 1], NULL,
"counter");
1592 llvm::Value *beforeFullEnd = ctx->
CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_SLT, counter,
1593 endVals[nDims - 1],
"before_full_end");
1594 ctx->
BranchInst(bbSetInnerMask, bbReset[nDims - 1], beforeFullEnd);
1602 llvm::Value *varyingCounter =
lUpdateVaryingCounter(nDims - 1, nDims, ctx, uniformCounterPtrs[nDims - 1],
1605 llvm::Value *emask = ctx->
CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_SLT, varyingCounter, smearEnd);
1620 llvm::BasicBlock *bbStepInnerIndex = ctx->
CreateBasicBlock(
"step_inner_index");
1621 llvm::BasicBlock *bbMaskedBodyContinue = ctx->
CreateBasicBlock(
"foreach_masked_continue");
1635 llvm::Value *stepIndex = ctx->
LoadInst(stepIndexAfterMaskedBodyPtr);
1636 ctx->
BranchInst(bbStepInnerIndex, bbReset[nDims - 1], stepIndex);
1644 llvm::Value *counter = ctx->
LoadInst(uniformCounterPtrs[nDims - 1]);
1645 llvm::Value *newCounter =
1647 ctx->
StoreInst(newCounter, uniformCounterPtrs[nDims - 1]);
1663 bool anyErrors =
false;
1664 for (
unsigned int i = 0; i <
startExprs.size(); ++i) {
1669 for (
unsigned int i = 0; i <
endExprs.size(); ++i) {
1672 anyErrors |= (
endExprs[i] == NULL);
1677 "Not enough initial values provided for \"foreach\" loop; " 1678 "got %d, expected %d\n",
1683 "Too many initial values provided for \"foreach\" loop; " 1684 "got %d, expected %d\n",
1691 "Not enough initial values provided for \"foreach\" loop; " 1692 "got %d, expected %d\n",
1697 "Too many initial values provided for \"foreach\" loop; " 1698 "got %d, expected %d\n",
1703 return anyErrors ? NULL :
this;
1709 printf(
"%*cForeach Stmt", indent,
' ');
1715 printf(
"%*cVar %d: %s\n", indent + 4,
' ', i,
dimVariables[i]->name.c_str());
1717 printf(
"%*cVar %d: NULL\n", indent + 4,
' ', i);
1719 printf(
"Start values:\n");
1720 for (
unsigned int i = 0; i <
startExprs.size(); ++i) {
1731 printf(
"End values:\n");
1732 for (
unsigned int i = 0; i <
endExprs.size(); ++i) {
1743 if (
stmts != NULL) {
1744 printf(
"%*cStmts:\n", indent + 4,
' ');
1775 llvm::BasicBlock *bbFindNext = ctx->
CreateBasicBlock(
"foreach_active_find_next");
1777 llvm::BasicBlock *bbCheckForMore = ctx->
CreateBasicBlock(
"foreach_active_check_for_more");
1789 llvm::Value *movmsk = ctx->
LaneMask(oldFullMask);
1803 llvm::Value *remainingBits = ctx->
LoadInst(maskBitsPtr, NULL,
"remaining_bits");
1806 llvm::Function *ctlzFunc =
m->
module->getFunction(
"__count_trailing_zeros_i64");
1807 Assert(ctlzFunc != NULL);
1808 llvm::Value *firstSet = ctx->
CallInst(ctlzFunc, NULL, remainingBits,
"first_set");
1824 llvm::Value *firstSet32Smear = ctx->
SmearUniform(firstSet32);
1828 llvm::Value *iterMask =
1829 ctx->
CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_EQ, firstSet32Smear, programIndex);
1837 llvm::Value *notSetMask = ctx->
NotOperator(setMask);
1838 llvm::Value *newRemaining =
1839 ctx->
BinaryOperator(llvm::Instruction::And, remainingBits, notSetMask,
"new_remaining");
1840 ctx->
StoreInst(newRemaining, maskBitsPtr);
1865 llvm::Value *remainingBits = ctx->
LoadInst(maskBitsPtr, NULL,
"remaining_bits");
1866 llvm::Value *nonZero = ctx->
CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_NE, remainingBits,
1868 ctx->
BranchInst(bbFindNext, bbDone, nonZero);
1878 printf(
"%*cForeach_active Stmt", indent,
' ');
1882 printf(
"%*cIter symbol: ", indent + 4,
' ');
1884 printf(
"%s",
sym->
name.c_str());
1891 printf(
"%*cStmts:\n", indent + 4,
' ');
1930 if (symType == NULL) {
1943 llvm::BasicBlock *bbCheckForMore = ctx->
CreateBasicBlock(
"foreach_check_for_more");
1958 llvm::Value *movmsk = ctx->
LaneMask(oldFullMask);
1970 const Type *exprType;
1971 llvm::VectorType *llvmExprType;
1972 if (exprValue == NULL || (exprType =
expr->
GetType()) == NULL ||
1973 (llvmExprType = llvm::dyn_cast<llvm::VectorType>(exprValue->getType())) == NULL) {
1979 llvm::Value *exprMem = ctx->
AllocaInst(exprType,
"expr_mem");
1980 ctx->
StoreInst(exprValue, exprMem, exprType);
1988 llvm::Value *remainingBits = ctx->
LoadInst(maskBitsPtr, NULL,
"remaining_bits");
1991 llvm::Function *ctlzFunc =
m->
module->getFunction(
"__count_trailing_zeros_i64");
1992 Assert(ctlzFunc != NULL);
1993 llvm::Value *firstSet = ctx->
CallInst(ctlzFunc, NULL, remainingBits,
"first_set");
1997 llvm::Value *uniqueValue;
1998 llvm::Value *uniqueValuePtr =
2000 uniqueValue = ctx->
LoadInst(uniqueValuePtr, exprType,
"unique_value");
2003 if (llvm::dyn_cast<llvm::PointerType>(symType) != NULL)
2005 Assert(uniqueValue != NULL);
2015 llvm::Value *uniqueSmear = ctx->
SmearUniform(uniqueValue,
"unique_smear");
2016 llvm::Value *matchingLanes = NULL;
2017 if (uniqueValue->getType()->isFloatingPointTy())
2018 matchingLanes = ctx->
CmpInst(llvm::Instruction::FCmp, llvm::CmpInst::FCMP_OEQ, uniqueSmear, exprValue,
2022 ctx->
CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_EQ, uniqueSmear, exprValue,
"matching_lanes");
2025 llvm::Value *loopMask =
2026 ctx->
BinaryOperator(llvm::Instruction::And, oldMask, matchingLanes,
"foreach_unique_loop_mask");
2032 llvm::Value *loopMaskMM = ctx->
LaneMask(loopMask);
2033 llvm::Value *notLoopMaskMM = ctx->
NotOperator(loopMaskMM);
2034 llvm::Value *newRemaining =
2035 ctx->
BinaryOperator(llvm::Instruction::And, remainingBits, notLoopMaskMM,
"new_remaining");
2036 ctx->
StoreInst(newRemaining, maskBitsPtr);
2060 llvm::Value *remainingBits = ctx->
LoadInst(maskBitsPtr, NULL,
"remaining_bits");
2061 llvm::Value *nonZero = ctx->
CmpInst(llvm::Instruction::ICmp, llvm::CmpInst::ICMP_NE, remainingBits,
2063 ctx->
BranchInst(bbFindNext, bbDone, nonZero);
2073 printf(
"%*cForeach_unique Stmt", indent,
' ');
2077 printf(
"%*cIter symbol: ", indent + 4,
' ');
2079 printf(
"%s",
sym->
name.c_str());
2086 printf(
"%*cIter expr: ", indent + 4,
' ');
2093 printf(
"%*cStmts:\n", indent + 4,
' ');
2108 "Iteration domain type in \"foreach_tiled\" loop " 2109 "must be \"varying\" type, not \"%s\".",
2116 "Iteration domain type in \"foreach_tiled\" loop " 2117 "must be an atomic, pointer, or enum type, not \"%s\".",
2157 printf(
"%*cCase [%d] label", indent,
' ',
value);
2179 printf(
"%*cDefault Stmt", indent,
' ');
2204 defaultBlock = NULL;
2229 if (llvm::dyn_cast<SwitchStmt>(node) != NULL)
2238 llvm::BasicBlock *bb = NULL;
2242 for (
int i = 0; i < (int)svi->caseBlocks.size(); ++i) {
2243 if (svi->caseBlocks[i].first == cs->
value) {
2253 snprintf(buf,
sizeof(buf),
"case_%d", cs->
value);
2254 bb = svi->ctx->CreateBasicBlock(buf);
2255 svi->caseBlocks.push_back(std::make_pair(cs->
value, bb));
2256 }
else if (ds != NULL) {
2258 if (svi->defaultBlock != NULL) {
2259 Error(ds->pos,
"Multiple \"default\" lables in switch statement.");
2264 bb = svi->ctx->CreateBasicBlock(
"default");
2265 svi->defaultBlock = bb;
2273 svi->nextBlock[svi->lastBlock] = bb;
2274 svi->lastBlock = bb;
2303 if (exprValue == NULL) {
2324 printf(
"%*cSwitch Stmt", indent,
' ');
2327 printf(
"%*cexpr = ", indent,
' ');
2334 const Type *exprType;
2340 const Type *toType = NULL;
2399 printf(
"%*cUnmasked Stmt", indent,
' ');
2403 printf(
"%*cStmts:\n", indent + 4,
' ');
2425 Error(
pos,
"\"return\" statement is illegal inside a \"foreach\" loop.");
2435 if (lvType == NULL) {
2437 "Illegal to return non-lvalue from function " 2438 "returning reference type \"%s\".",
2443 "Illegal to return varying lvalue type from " 2444 "function returning a reference type \"%s\".",
2459 printf(
"%*cReturn Stmt", indent,
' ');
2481 Error(
pos,
"\"goto\" statements are only legal under \"uniform\" " 2486 Error(
pos,
"\"goto\" statements are currently illegal inside " 2487 "\"foreach\" loops.");
2494 std::vector<std::string> labels = ctx->
GetLabels();
2496 std::string match_output;
2497 if (!matches.empty()) {
2499 match_output +=
"\nDid you mean:";
2500 for (
unsigned int i = 0; i < matches.size() && i < 5; i++)
2501 match_output +=
"\n " + matches[i] +
"?";
2505 Error(
identifierPos,
"No label named \"%s\" found in current function.%s",
label.c_str(), match_output.c_str());
2548 printf(
"%*cLabel \"%s\"\n", indent,
' ',
name.c_str());
2556 if (!isalpha(
name[0]) ||
name[0] ==
'_') {
2557 Error(
pos,
"Label must start with either alphabetic character or '_'.");
2560 for (
unsigned int i = 1; i <
name.size(); ++i) {
2561 if (!isalnum(
name[i]) &&
name[i] !=
'_') {
2562 Error(
pos,
"Character \"%c\" is illegal in labels.",
name[i]);
2577 for (
unsigned int i = 0; i < stmts.size(); ++i)
2579 stmts[i]->EmitCode(ctx);
2588 printf(
"%*cStmt List", indent,
' ');
2591 for (
unsigned int i = 0; i < stmts.size(); ++i)
2593 stmts[i]->Print(indent + 4);
2637 if (CastType<PointerType>(t) != NULL) {
2655 if (CastType<ReferenceType>(type) != NULL) {
2668 type = expr->GetType();
2674 "Only atomic types are allowed in print statements; " 2675 "type \"%s\" is illegal.",
2684 type = expr->GetType();
2686 argTypes.push_back(t);
2688 llvm::Value *ptr = ctx->
AllocaInst(type,
"print_arg");
2689 llvm::Value *val = expr->
GetValue(ctx);
2721 llvm::Value *args[5];
2722 std::string argTypes;
2726 args[4] = llvm::Constant::getNullValue(ptrPtrType);
2732 int nArgs = elist ? elist->
exprs.size() : 1;
2736 llvm::Value *argPtrArray = ctx->
AllocaInst(argPtrArrayType,
"print_arg_ptrs");
2745 for (
unsigned int i = 0; i < elist->
exprs.size(); ++i) {
2766 llvm::Function *printFunc =
m->
module->getFunction(
"__do_print");
2775 std::vector<llvm::Value *> argVec(&args[0], &args[5]);
2776 ctx->
CallInst(printFunc, NULL, argVec,
"");
2803 llvm::Function *assertFunc =
2804 isUniform ?
m->
module->getFunction(
"__do_assert_uniform") :
m->
module->getFunction(
"__do_assert_varying");
2810 Error(
pos,
"Fatal error when generating assert string: asprintf() " 2811 "unable to allocate memory!");
2815 std::vector<llvm::Value *> args;
2818 if (exprValue == NULL) {
2822 args.push_back(exprValue);
2824 ctx->
CallInst(assertFunc, NULL, args,
"");
2836 "\"assert\" statement");
2854 const Type *exprType;
2861 if (exprValue == NULL) {
2867 AssertPos(
pos, CastType<PointerType>(exprType) != NULL);
2874 llvm::Function *func;
2876 func =
m->
module->getFunction(
"__delete_uniform_32rt");
2878 func =
m->
module->getFunction(
"__delete_uniform_64rt");
2882 ctx->
CallInst(func, NULL, exprValue,
"");
2888 llvm::Function *func;
2890 func =
m->
module->getFunction(
"__delete_varying_32rt");
2892 func =
m->
module->getFunction(
"__delete_varying_64rt");
2897 ctx->
CallInst(func, NULL, exprValue,
"");
2904 const Type *exprType;
2908 if (CastType<PointerType>(exprType) == NULL) {
2909 Error(
pos,
"Illegal to delete non-pointer type \"%s\".", exprType->
GetString().c_str());
const Function * GetFunction() const
static const AtomicType * VaryingInt32
llvm::Value * Any(llvm::Value *mask)
bool IsUniformType() const
void EmitCode(FunctionEmitContext *ctx) const
void EmitCode(FunctionEmitContext *ctx) const
ForStmt(Stmt *initializer, Expr *testExpr, Stmt *stepStatements, Stmt *bodyStatements, bool doCoherentCheck, SourcePos pos)
std::vector< VariableDeclaration > vars
std::vector< std::pair< int, llvm::BasicBlock * > > caseBlocks
void EmitCode(FunctionEmitContext *ctx) const
static bool lIsVaryingFor(ASTNode *node)
static bool lHasVaryingBreakOrContinue(Stmt *stmt)
llvm::Value * AddElementOffset(llvm::Value *basePtr, int elementNum, const Type *ptrType, const char *name=NULL, const PointerType **resultPtrType=NULL)
bool InForeachLoop() const
void StartSwitch(bool isUniform, llvm::BasicBlock *bbAfterSwitch)
llvm::Value * ProgramIndexVector(bool is32bits=true)
static llvm::Value * lUpdateVaryingCounter(int dim, int nDims, FunctionEmitContext *ctx, llvm::Value *uniformCounterPtr, llvm::Value *varyingCounterPtr, const std::vector< int > &spans)
ASTNode * WalkAST(ASTNode *node, ASTPreCallBackFunc preFunc, ASTPostCallBackFunc postFunc, void *data)
void SetInternalMask(llvm::Value *val)
void StartLoop(llvm::BasicBlock *breakTarget, llvm::BasicBlock *continueTarget, bool uniformControlFlow)
const bool doCoherentCheck
void emitMaskAllOn(FunctionEmitContext *ctx, llvm::Value *test, llvm::BasicBlock *bDone) const
Declaration of the FunctionEmitContext class
void EmitVariableDebugInfo(Symbol *sym)
llvm::Constant * LLVMBoolVector(bool b)
void Print(int indent) const
static const AtomicType * VaryingUInt64
void Print(int indent) const
std::vector< Expr * > endExprs
bool SafeToRunWithMaskAllOff(ASTNode *root)
SwitchVisitInfo(FunctionEmitContext *c)
bool IsVaryingType() const
void SetInternalMaskAnd(llvm::Value *oldMask, llvm::Value *val)
void BranchInst(llvm::BasicBlock *block)
static bool lSwitchASTPreVisit(ASTNode *node, void *d)
llvm::Instruction * ZExtInst(llvm::Value *value, llvm::Type *type, const char *name=NULL)
#define AssertPos(pos, expr)
Interface class for statements in the ispc language.
llvm::Value * NotOperator(llvm::Value *v, const char *name=NULL)
void Print(int indent) const
void Print(int indent) const
llvm::Value * LoadInst(llvm::Value *ptr, llvm::Value *mask, const Type *ptrType, const char *name=NULL, bool one_elem=false)
void BranchIfMaskAll(llvm::BasicBlock *btrue, llvm::BasicBlock *bfalse)
const std::string message
void EmitCode(FunctionEmitContext *ctx) const
void Print(int indent) const
std::vector< std::string > GetLabels()
static const AtomicType * VaryingDouble
llvm::Instruction * TruncInst(llvm::Value *value, llvm::Type *type, const char *name=NULL)
llvm::Constant * LLVMMaskAllOn
llvm::Value * AllocaInst(llvm::Type *llvmType, const char *name=NULL, int align=0, bool atEntryBlock=true)
Expression representing a compile-time constant value.
void EmitCode(FunctionEmitContext *ctx) const
llvm::Value * CmpInst(llvm::Instruction::OtherOps inst, llvm::CmpInst::Predicate pred, llvm::Value *v0, llvm::Value *v1, const char *name=NULL)
void StartVaryingIf(llvm::Value *oldMask)
static llvm::Type * BoolType
void SetContinueTarget(llvm::BasicBlock *bb)
const Type * GetElementType() const
static bool checkInit(const Type *type, Expr **init)
void Print(int indent) const
void Print(int indent) const
void StartForeach(ForeachType ft)
static llvm::VectorType * Int32VectorType
Expr * TypeConvertExpr(Expr *expr, const Type *toType, const char *errorMsgBase)
bool PossiblyResolveFunctionOverloads(Expr *expr, const Type *type)
static const AtomicType * UniformUInt32
void Continue(bool doCoherenceCheck)
llvm::Value * GetFullMask()
IfStmt(Expr *testExpr, Stmt *trueStmts, Stmt *falseStmts, bool doAllCheck, SourcePos pos)
int VaryingCFDepth() const
virtual std::pair< llvm::Constant *, bool > GetConstant(const Type *type) const
void Print(int indent) const
void AddInstrumentationPoint(const char *note)
llvm::BasicBlock * lastBlock
void EmitCode(FunctionEmitContext *ctx) const
CaseStmt(int value, Stmt *stmt, SourcePos pos)
static bool lCheckMask(Stmt *stmts)
Symbol * LookupVariable(const char *name)
void Print(int indent) const
Statement implementation representing a 'do' statement in the program.
void Print(int indent) const
void EmitCode(FunctionEmitContext *ctx) const
void BranchIfMaskAny(llvm::BasicBlock *btrue, llvm::BasicBlock *bfalse)
void RestoreContinuedLanes()
void Print(int indent) const
void EmitCode(FunctionEmitContext *ctx) const
virtual void Print() const =0
llvm::BasicBlock * GetCurrentBasicBlock()
static const AtomicType * UniformUInt16
static bool lHasUnsizedArrays(const Type *type)
std::vector< std::string > MatchStrings(const std::string &str, const std::vector< std::string > &options)
static PointerType * GetUniform(const Type *t, bool isSlice=false)
ReturnStmt(Expr *e, SourcePos p)
virtual llvm::Value * GetValue(FunctionEmitContext *ctx) const =0
void Break(bool doCoherenceCheck)
virtual void EmitCode(FunctionEmitContext *ctx) const =0
llvm::Value * CallInst(llvm::Value *func, const FunctionType *funcType, const std::vector< llvm::Value *> &args, const char *name=NULL)
llvm::BasicBlock * CreateBasicBlock(const char *name)
virtual llvm::Type * LLVMType(llvm::LLVMContext *ctx) const =0
header file with declarations for symbol and symbol table classes.
static const AtomicType * UniformBool
llvm::Value * BroadcastValue(llvm::Value *v, llvm::Type *vecType, const char *name=NULL)
bool disableMaskAllOnOptimizations
static ASTNode * lVaryingBCPostFunc(ASTNode *node, void *d)
File with declarations for classes related to statements in the language.
static void lEmitIfStatements(FunctionEmitContext *ctx, Stmt *stmts, const char *trueOrFalse)
void StoreInst(llvm::Value *value, llvm::Value *ptr, const Type *ptrType=NULL)
void EmitCode(FunctionEmitContext *ctx) const
ContinueStmt(SourcePos pos)
void EmitCaseLabel(int value, bool checkMask, SourcePos pos)
bool IsReferenceType(const Type *t)
Expression representing a type cast of the given expression to a probably-different type...
ExprStmt(Expr *expr, SourcePos pos)
LabeledStmt(const char *label, Stmt *stmt, SourcePos p)
static const AtomicType * UniformUInt64
llvm::Value * GetFunctionMask()
bool disableCoherentControlFlow
llvm::Constant * LLVMInt32Vector(int32_t ival)
SourcePos GetDebugPos() const
void Print(int indent) const
Abstract base class for nodes in the abstract syntax tree (AST).
llvm::Value * GetElementPtrInst(llvm::Value *basePtr, llvm::Value *index, const Type *ptrType, const char *name=NULL)
void EmitCode(FunctionEmitContext *ctx) const
void CurrentLanesReturned(Expr *value, bool doCoherenceCheck)
llvm::Constant * LLVMTrue
ForeachUniqueStmt(const char *iterName, Expr *expr, Stmt *stmts, SourcePos pos)
void Print(int indent) const
ForeachActiveStmt(Symbol *iterSym, Stmt *stmts, SourcePos pos)
llvm::Value * LaneMask(llvm::Value *mask)
DeclStmt(const std::vector< VariableDeclaration > &v, SourcePos pos)
static char lEncodeType(const Type *t)
void Print(int indent) const
virtual const Type * GetLValueType() const
static llvm::Type * Int64Type
Representation of a structure holding a number of members.
void InitSymbol(llvm::Value *ptr, const Type *symType, Expr *initExpr, FunctionEmitContext *ctx, SourcePos pos)
FunctionEmitContext * ctx
static llvm::VectorType * Int64VectorType
Header file with declarations for various LLVM utility stuff.
void Print(int indent) const
const AtomicType * GetAsConstType() const
AssertStmt(const std::string &msg, Expr *e, SourcePos p)
static bool IsBasicType(const Type *type)
virtual const Type * GetType() const =0
static void lGetSpans(int dimsLeft, int nDims, int itemsLeft, bool isTiled, int *a)
void EmitCode(FunctionEmitContext *ctx) const
void EmitCode(FunctionEmitContext *ctx) const
void SetBlockEntryMask(llvm::Value *mask)
llvm::Constant * LLVMMaskAllOff
StorageClass storageClass
Representation of a range of positions in a source file.
DoStmt(Expr *testExpr, Stmt *bodyStmts, bool doCoherentCheck, SourcePos pos)
void Print(int indent) const
llvm::ConstantInt * LLVMInt32(int32_t ival)
virtual const Type * GetAsNonConstType() const =0
static const AtomicType * VaryingBool
virtual std::string GetString() const =0
void EmitCode(FunctionEmitContext *ctx) const
GotoStmt(const char *label, SourcePos gotoPos, SourcePos idPos)
void Print(int indent) const
void emitMaskedTrueAndFalse(FunctionEmitContext *ctx, llvm::Value *oldMask, llvm::Value *test) const
int GetElementCount() const
void Print(int indent) const
static llvm::PointerType * VoidPointerType
static const AtomicType * VaryingInt64
const bool doCoherentCheck
void Error(SourcePos p, const char *fmt,...)
int getVectorWidth() const
void SwitchInst(llvm::Value *expr, llvm::BasicBlock *defaultBlock, const std::vector< std::pair< int, llvm::BasicBlock *>> &caseBlocks, const std::map< llvm::BasicBlock *, llvm::BasicBlock *> &nextBlocks)
bool foundVaryingBreakOrContinue
llvm::Value * GetStringPtr(const std::string &str)
void EmitCode(FunctionEmitContext *ctx) const
SwitchStmt(Expr *expr, Stmt *stmts, SourcePos pos)
static const AtomicType * UniformUInt8
void DisableGatherScatterWarnings()
const Type * GetElementType(const std::string &name) const
static llvm::Type * Int32Type
void SetDebugPos(SourcePos pos)
virtual const Type * GetAsUniformType() const =0
bool disableUniformControlFlow
Representation of a function in a source file.
void emitVaryingIf(FunctionEmitContext *ctx, llvm::Value *test) const
static bool Equal(const Type *a, const Type *b)
static bool lVaryingBCPreFunc(ASTNode *node, void *d)
void EmitCode(FunctionEmitContext *ctx) const
std::vector< Expr * > exprs
llvm::BasicBlock * defaultBlock
std::vector< Expr * > startExprs
static const AtomicType * UniformFloat
llvm::Value * GetInternalMask()
void EmitCode(FunctionEmitContext *ctx) const
llvm::Value * BitCastInst(llvm::Value *value, llvm::Type *type, const char *name=NULL)
static const AtomicType * UniformInt32
void SetInternalMaskAndNot(llvm::Value *oldMask, llvm::Value *test)
llvm::Constant * LLVMFalse
void Print(int indent) const
Representation of a program symbol.
void EmitCode(FunctionEmitContext *ctx) const
void Print(int indent) const
void EnableGatherScatterWarnings()
virtual bool IsConstType() const =0
Interface class that defines the type abstraction.
static const AtomicType * UniformDouble
Expr abstract base class and expression implementations.
void SetCurrentBasicBlock(llvm::BasicBlock *bblock)
virtual const Type * GetAsConstType() const =0
static llvm::VectorType * MaskType
ForeachStmt(const std::vector< Symbol *> &loopVars, const std::vector< Expr *> &startExprs, const std::vector< Expr *> &endExprs, Stmt *bodyStatements, bool tiled, SourcePos pos)
void EmitDefaultLabel(bool checkMask, SourcePos pos)
void Debug(SourcePos p, const char *fmt,...)
DefaultStmt(Stmt *stmt, SourcePos pos)
void EmitCode(FunctionEmitContext *ctx) const
Statement representing a single if statement, possibly with an else clause.
int GetElementCount() const
void EmitCode(FunctionEmitContext *ctx) const
Expr is the abstract base class that defines the interface that all expression types must implement...
virtual Stmt * Optimize()
std::vector< Symbol * > dimVariables
llvm::Value * IntToPtrInst(llvm::Value *value, llvm::Type *type, const char *name=NULL)
const Function * parentFunction
UnmaskedStmt(Stmt *stmt, SourcePos pos)
void emitMaskMixed(FunctionEmitContext *ctx, llvm::Value *oldMask, llvm::Value *test, llvm::BasicBlock *bDone) const
llvm::Value * All(llvm::Value *mask)
virtual void Print(int indent) const =0
llvm::ConstantInt * LLVMInt64(int64_t ival)
Expression that represents dereferencing a reference to get its value.
static const Type * SizeUnsizedArrays(const Type *type, Expr *initExpr)
void EmitCode(FunctionEmitContext *ctx) const
llvm::Value * SmearUniform(llvm::Value *value, const char *name=NULL)
const Type * GetReturnType() const
PrintStmt(const std::string &f, Expr *v, SourcePos p)
Declaration of the Module class, which is the ispc-side representation of the results of compiling a ...
static const AtomicType * UniformInt64
void Print(int indent) const
static const AtomicType * UniformInt16
void EmitCode(FunctionEmitContext *ctx) const
static llvm::Value * lProcessPrintArg(Expr *expr, FunctionEmitContext *ctx, std::string &argTypes)
int varyingControlFlowDepth
void Warning(SourcePos p, const char *fmt,...)
static bool EqualIgnoringConst(const Type *a, const Type *b)
DeleteStmt(Expr *e, SourcePos p)
static const AtomicType * VaryingUInt32
llvm::Value * BinaryOperator(llvm::Instruction::BinaryOps inst, llvm::Value *v0, llvm::Value *v1, const char *name=NULL)
llvm::BasicBlock * GetLabeledBasicBlock(const std::string &label)
void SetFunctionMask(llvm::Value *val)
static const AtomicType * VaryingFloat
SymbolTable * symbolTable
static const AtomicType * UniformInt8
File with declarations for classes related to type representation.
llvm::Value * I1VecToBoolVec(llvm::Value *b)
std::map< llvm::BasicBlock *, llvm::BasicBlock * > nextBlock
One-dimensional array type.